// Copyright 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "cc/resources/resource_provider.h"

#include <algorithm>
#include <limits>

#include "base/containers/hash_tables.h"
#include "base/debug/trace_event.h"
#include "base/metrics/histogram.h"
#include "base/stl_util.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "cc/base/util.h"
#include "cc/output/gl_renderer.h"  // For the GLC() macro.
#include "cc/resources/platform_color.h"
#include "cc/resources/returned_resource.h"
#include "cc/resources/shared_bitmap_manager.h"
#include "cc/resources/texture_uploader.h"
#include "cc/resources/transferable_resource.h"
#include "gpu/GLES2/gl2extchromium.h"
#include "gpu/command_buffer/client/gles2_interface.h"
#include "gpu/command_buffer/client/gpu_memory_buffer_manager.h"
#include "third_party/khronos/GLES2/gl2.h"
#include "third_party/khronos/GLES2/gl2ext.h"
#include "third_party/skia/include/core/SkSurface.h"
#include "third_party/skia/include/gpu/GrContext.h"
#include "ui/gfx/frame_time.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/vector2d.h"
#include "ui/gfx/gpu_memory_buffer.h"

using gpu::gles2::GLES2Interface;

namespace cc {

class IdAllocator {
 public:
  virtual ~IdAllocator() {}

  virtual GLuint NextId() = 0;

 protected:
  IdAllocator(GLES2Interface* gl, size_t id_allocation_chunk_size)
      : gl_(gl),
        id_allocation_chunk_size_(id_allocation_chunk_size),
        ids_(new GLuint[id_allocation_chunk_size]),
        next_id_index_(id_allocation_chunk_size) {
    DCHECK(id_allocation_chunk_size_);
  }

  GLES2Interface* gl_;
  const size_t id_allocation_chunk_size_;
  scoped_ptr<GLuint[]> ids_;
  size_t next_id_index_;
};

namespace {

// Measured in seconds.
const double kSoftwareUploadTickRate = 0.000250;
const double kTextureUploadTickRate = 0.004;

GLenum TextureToStorageFormat(ResourceFormat format) {
  GLenum storage_format = GL_RGBA8_OES;
  switch (format) {
    case RGBA_8888:
      break;
    case BGRA_8888:
      storage_format = GL_BGRA8_EXT;
      break;
    case RGBA_4444:
    case ALPHA_8:
    case LUMINANCE_8:
    case RGB_565:
    case ETC1:
      NOTREACHED();
      break;
  }

  return storage_format;
}

bool IsFormatSupportedForStorage(ResourceFormat format, bool use_bgra) {
  switch (format) {
    case RGBA_8888:
      return true;
    case BGRA_8888:
      return use_bgra;
    case RGBA_4444:
    case ALPHA_8:
    case LUMINANCE_8:
    case RGB_565:
    case ETC1:
      return false;
  }
  return false;
}

GrPixelConfig ToGrPixelConfig(ResourceFormat format) {
  switch (format) {
    case RGBA_8888:
      return kRGBA_8888_GrPixelConfig;
    case BGRA_8888:
      return kBGRA_8888_GrPixelConfig;
    case RGBA_4444:
      return kRGBA_4444_GrPixelConfig;
    default:
      break;
  }
  DCHECK(false) << "Unsupported resource format.";
  return kSkia8888_GrPixelConfig;
}

gfx::GpuMemoryBuffer::Format ToGpuMemoryBufferFormat(ResourceFormat format) {
  switch (format) {
    case RGBA_8888:
      return gfx::GpuMemoryBuffer::Format::RGBA_8888;
    case BGRA_8888:
      return gfx::GpuMemoryBuffer::Format::BGRA_8888;
    case RGBA_4444:
    case ALPHA_8:
    case LUMINANCE_8:
    case RGB_565:
    case ETC1:
      break;
  }
  NOTREACHED();
  return gfx::GpuMemoryBuffer::Format::RGBA_8888;
}

class ScopedSetActiveTexture {
 public:
  ScopedSetActiveTexture(GLES2Interface* gl, GLenum unit)
      : gl_(gl), unit_(unit) {
    DCHECK_EQ(GL_TEXTURE0, ResourceProvider::GetActiveTextureUnit(gl_));

    if (unit_ != GL_TEXTURE0)
      GLC(gl_, gl_->ActiveTexture(unit_));
  }

  ~ScopedSetActiveTexture() {
    // Active unit being GL_TEXTURE0 is effectively the ground state.
    if (unit_ != GL_TEXTURE0)
      GLC(gl_, gl_->ActiveTexture(GL_TEXTURE0));
  }

 private:
  GLES2Interface* gl_;
  GLenum unit_;
};

class TextureIdAllocator : public IdAllocator {
 public:
  TextureIdAllocator(GLES2Interface* gl,
                     size_t texture_id_allocation_chunk_size)
      : IdAllocator(gl, texture_id_allocation_chunk_size) {}
  ~TextureIdAllocator() override {
    gl_->DeleteTextures(id_allocation_chunk_size_ - next_id_index_,
                        ids_.get() + next_id_index_);
  }

  // Overridden from IdAllocator:
  GLuint NextId() override {
    if (next_id_index_ == id_allocation_chunk_size_) {
      gl_->GenTextures(id_allocation_chunk_size_, ids_.get());
      next_id_index_ = 0;
    }

    return ids_[next_id_index_++];
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(TextureIdAllocator);
};

class BufferIdAllocator : public IdAllocator {
 public:
  BufferIdAllocator(GLES2Interface* gl, size_t buffer_id_allocation_chunk_size)
      : IdAllocator(gl, buffer_id_allocation_chunk_size) {}
  ~BufferIdAllocator() override {
    gl_->DeleteBuffers(id_allocation_chunk_size_ - next_id_index_,
                       ids_.get() + next_id_index_);
  }

  // Overridden from IdAllocator:
  GLuint NextId() override {
    if (next_id_index_ == id_allocation_chunk_size_) {
      gl_->GenBuffers(id_allocation_chunk_size_, ids_.get());
      next_id_index_ = 0;
    }

    return ids_[next_id_index_++];
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(BufferIdAllocator);
};

// Query object based fence implementation used to detect completion of copy
// texture operations. Fence has passed when query result is available.
class CopyTextureFence : public ResourceProvider::Fence {
 public:
  CopyTextureFence(gpu::gles2::GLES2Interface* gl, unsigned query_id)
      : gl_(gl), query_id_(query_id) {}

  // Overridden from ResourceProvider::Fence:
  void Set() override {}
  bool HasPassed() override {
    unsigned available = 1;
    gl_->GetQueryObjectuivEXT(
        query_id_, GL_QUERY_RESULT_AVAILABLE_EXT, &available);
    if (!available)
      return false;

    ProcessResult();
    return true;
  }
  void Wait() override {
    // ProcessResult() will wait for result to become available.
    ProcessResult();
  }

 private:
  ~CopyTextureFence() override {}

  void ProcessResult() {
    unsigned time_elapsed_us = 0;
    gl_->GetQueryObjectuivEXT(query_id_, GL_QUERY_RESULT_EXT, &time_elapsed_us);
    UMA_HISTOGRAM_CUSTOM_COUNTS("Renderer4.CopyTextureLatency", time_elapsed_us,
                                0, 256000, 50);
  }

  gpu::gles2::GLES2Interface* gl_;
  unsigned query_id_;

  DISALLOW_COPY_AND_ASSIGN(CopyTextureFence);
};

}  // namespace

ResourceProvider::Resource::Resource()
    : child_id(0),
      gl_id(0),
      gl_pixel_buffer_id(0),
      gl_upload_query_id(0),
      gl_read_lock_query_id(0),
      pixels(NULL),
      lock_for_read_count(0),
      imported_count(0),
      exported_count(0),
      dirty_image(false),
      locked_for_write(false),
      lost(false),
      marked_for_deletion(false),
      pending_set_pixels(false),
      set_pixels_completion_forced(false),
      allocated(false),
      read_lock_fences_enabled(false),
      has_shared_bitmap_id(false),
      allow_overlay(false),
      read_lock_fence(NULL),
      size(),
      origin(Internal),
      target(0),
      original_filter(0),
      filter(0),
      image_id(0),
      bound_image_id(0),
      texture_pool(0),
      wrap_mode(0),
      hint(TextureHintImmutable),
      type(InvalidType),
      format(RGBA_8888),
      shared_bitmap(NULL),
      gpu_memory_buffer(NULL) {
}

ResourceProvider::Resource::~Resource() {}

ResourceProvider::Resource::Resource(GLuint texture_id,
                                     const gfx::Size& size,
                                     Origin origin,
                                     GLenum target,
                                     GLenum filter,
                                     GLenum texture_pool,
                                     GLint wrap_mode,
                                     TextureHint hint,
                                     ResourceFormat format)
    : child_id(0),
      gl_id(texture_id),
      gl_pixel_buffer_id(0),
      gl_upload_query_id(0),
      gl_read_lock_query_id(0),
      pixels(NULL),
      lock_for_read_count(0),
      imported_count(0),
      exported_count(0),
      dirty_image(false),
      locked_for_write(false),
      lost(false),
      marked_for_deletion(false),
      pending_set_pixels(false),
      set_pixels_completion_forced(false),
      allocated(false),
      read_lock_fences_enabled(false),
      has_shared_bitmap_id(false),
      allow_overlay(false),
      read_lock_fence(NULL),
      size(size),
      origin(origin),
      target(target),
      original_filter(filter),
      filter(filter),
      image_id(0),
      bound_image_id(0),
      texture_pool(texture_pool),
      wrap_mode(wrap_mode),
      hint(hint),
      type(GLTexture),
      format(format),
      shared_bitmap(NULL),
      gpu_memory_buffer(NULL) {
  DCHECK(wrap_mode == GL_CLAMP_TO_EDGE || wrap_mode == GL_REPEAT);
  DCHECK_EQ(origin == Internal, !!texture_pool);
}

ResourceProvider::Resource::Resource(uint8_t* pixels,
                                     SharedBitmap* bitmap,
                                     const gfx::Size& size,
                                     Origin origin,
                                     GLenum filter,
                                     GLint wrap_mode)
    : child_id(0),
      gl_id(0),
      gl_pixel_buffer_id(0),
      gl_upload_query_id(0),
      gl_read_lock_query_id(0),
      pixels(pixels),
      lock_for_read_count(0),
      imported_count(0),
      exported_count(0),
      dirty_image(false),
      locked_for_write(false),
      lost(false),
      marked_for_deletion(false),
      pending_set_pixels(false),
      set_pixels_completion_forced(false),
      allocated(false),
      read_lock_fences_enabled(false),
      has_shared_bitmap_id(!!bitmap),
      allow_overlay(false),
      read_lock_fence(NULL),
      size(size),
      origin(origin),
      target(0),
      original_filter(filter),
      filter(filter),
      image_id(0),
      bound_image_id(0),
      texture_pool(0),
      wrap_mode(wrap_mode),
      hint(TextureHintImmutable),
      type(Bitmap),
      format(RGBA_8888),
      shared_bitmap(bitmap),
      gpu_memory_buffer(NULL) {
  DCHECK(wrap_mode == GL_CLAMP_TO_EDGE || wrap_mode == GL_REPEAT);
  DCHECK(origin == Delegated || pixels);
  if (bitmap)
    shared_bitmap_id = bitmap->id();
}

ResourceProvider::Resource::Resource(const SharedBitmapId& bitmap_id,
                                     const gfx::Size& size,
                                     Origin origin,
                                     GLenum filter,
                                     GLint wrap_mode)
    : child_id(0),
      gl_id(0),
      gl_pixel_buffer_id(0),
      gl_upload_query_id(0),
      gl_read_lock_query_id(0),
      pixels(NULL),
      lock_for_read_count(0),
      imported_count(0),
      exported_count(0),
      dirty_image(false),
      locked_for_write(false),
      lost(false),
      marked_for_deletion(false),
      pending_set_pixels(false),
      set_pixels_completion_forced(false),
      allocated(false),
      read_lock_fences_enabled(false),
      has_shared_bitmap_id(true),
      allow_overlay(false),
      read_lock_fence(NULL),
      size(size),
      origin(origin),
      target(0),
      original_filter(filter),
      filter(filter),
      image_id(0),
      bound_image_id(0),
      texture_pool(0),
      wrap_mode(wrap_mode),
      hint(TextureHintImmutable),
      type(Bitmap),
      format(RGBA_8888),
      shared_bitmap_id(bitmap_id),
      shared_bitmap(NULL),
      gpu_memory_buffer(NULL) {
  DCHECK(wrap_mode == GL_CLAMP_TO_EDGE || wrap_mode == GL_REPEAT);
}

ResourceProvider::Child::Child() : marked_for_deletion(false) {}

ResourceProvider::Child::~Child() {}

scoped_ptr<ResourceProvider> ResourceProvider::Create(
    OutputSurface* output_surface,
    SharedBitmapManager* shared_bitmap_manager,
    gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
    BlockingTaskRunner* blocking_main_thread_task_runner,
    int highp_threshold_min,
    bool use_rgba_4444_texture_format,
    size_t id_allocation_chunk_size) {
  scoped_ptr<ResourceProvider> resource_provider(
      new ResourceProvider(output_surface,
                           shared_bitmap_manager,
                           gpu_memory_buffer_manager,
                           blocking_main_thread_task_runner,
                           highp_threshold_min,
                           use_rgba_4444_texture_format,
                           id_allocation_chunk_size));

  if (resource_provider->ContextGL())
    resource_provider->InitializeGL();
  else
    resource_provider->InitializeSoftware();

  DCHECK_NE(InvalidType, resource_provider->default_resource_type());
  return resource_provider.Pass();
}

ResourceProvider::~ResourceProvider() {
  while (!children_.empty())
    DestroyChildInternal(children_.begin(), ForShutdown);
  while (!resources_.empty())
    DeleteResourceInternal(resources_.begin(), ForShutdown);

  CleanUpGLIfNeeded();
}

bool ResourceProvider::InUseByConsumer(ResourceId id) {
  Resource* resource = GetResource(id);
  return resource->lock_for_read_count > 0 || resource->exported_count > 0 ||
         resource->lost;
}

bool ResourceProvider::IsLost(ResourceId id) {
  Resource* resource = GetResource(id);
  return resource->lost;
}

bool ResourceProvider::AllowOverlay(ResourceId id) {
  Resource* resource = GetResource(id);
  return resource->allow_overlay;
}

ResourceProvider::ResourceId ResourceProvider::CreateResource(
    const gfx::Size& size,
    GLint wrap_mode,
    TextureHint hint,
    ResourceFormat format) {
  DCHECK(!size.IsEmpty());
  switch (default_resource_type_) {
    case GLTexture:
      return CreateGLTexture(size,
                             GL_TEXTURE_2D,
                             GL_TEXTURE_POOL_UNMANAGED_CHROMIUM,
                             wrap_mode,
                             hint,
                             format);
    case Bitmap:
      DCHECK_EQ(RGBA_8888, format);
      return CreateBitmap(size, wrap_mode);
    case InvalidType:
      break;
  }

  LOG(FATAL) << "Invalid default resource type.";
  return 0;
}

ResourceProvider::ResourceId ResourceProvider::CreateManagedResource(
    const gfx::Size& size,
    GLenum target,
    GLint wrap_mode,
    TextureHint hint,
    ResourceFormat format) {
  DCHECK(!size.IsEmpty());
  switch (default_resource_type_) {
    case GLTexture:
      return CreateGLTexture(size,
                             target,
                             GL_TEXTURE_POOL_MANAGED_CHROMIUM,
                             wrap_mode,
                             hint,
                             format);
    case Bitmap:
      DCHECK_EQ(RGBA_8888, format);
      return CreateBitmap(size, wrap_mode);
    case InvalidType:
      break;
  }

  LOG(FATAL) << "Invalid default resource type.";
  return 0;
}

ResourceProvider::ResourceId ResourceProvider::CreateGLTexture(
    const gfx::Size& size,
    GLenum target,
    GLenum texture_pool,
    GLint wrap_mode,
    TextureHint hint,
    ResourceFormat format) {
  DCHECK_LE(size.width(), max_texture_size_);
  DCHECK_LE(size.height(), max_texture_size_);
  DCHECK(thread_checker_.CalledOnValidThread());

  ResourceId id = next_id_++;
  Resource resource(0,
                    size,
                    Resource::Internal,
                    target,
                    GL_LINEAR,
                    texture_pool,
                    wrap_mode,
                    hint,
                    format);
  resource.allocated = false;
  resources_[id] = resource;
  return id;
}

ResourceProvider::ResourceId ResourceProvider::CreateBitmap(
    const gfx::Size& size, GLint wrap_mode) {
  DCHECK(thread_checker_.CalledOnValidThread());

  scoped_ptr<SharedBitmap> bitmap;
  if (shared_bitmap_manager_)
    bitmap = shared_bitmap_manager_->AllocateSharedBitmap(size);

  uint8_t* pixels;
  if (bitmap) {
    pixels = bitmap->pixels();
  } else {
    size_t bytes = SharedBitmap::CheckedSizeInBytes(size);
    pixels = new uint8_t[bytes];
  }
  DCHECK(pixels);

  ResourceId id = next_id_++;
  Resource resource(
      pixels, bitmap.release(), size, Resource::Internal, GL_LINEAR, wrap_mode);
  resource.allocated = true;
  resources_[id] = resource;
  return id;
}

ResourceProvider::ResourceId ResourceProvider::CreateResourceFromIOSurface(
    const gfx::Size& size,
    unsigned io_surface_id) {
  DCHECK(thread_checker_.CalledOnValidThread());

  ResourceId id = next_id_++;
  Resource resource(0,
                    gfx::Size(),
                    Resource::Internal,
                    GL_TEXTURE_RECTANGLE_ARB,
                    GL_LINEAR,
                    GL_TEXTURE_POOL_UNMANAGED_CHROMIUM,
                    GL_CLAMP_TO_EDGE,
                    TextureHintImmutable,
                    RGBA_8888);
  LazyCreate(&resource);
  GLES2Interface* gl = ContextGL();
  DCHECK(gl);
  gl->BindTexture(GL_TEXTURE_RECTANGLE_ARB, resource.gl_id);
  gl->TexImageIOSurface2DCHROMIUM(
      GL_TEXTURE_RECTANGLE_ARB, size.width(), size.height(), io_surface_id, 0);
  resource.allocated = true;
  resources_[id] = resource;
  return id;
}

ResourceProvider::ResourceId ResourceProvider::CreateResourceFromTextureMailbox(
    const TextureMailbox& mailbox,
    scoped_ptr<SingleReleaseCallbackImpl> release_callback_impl) {
  DCHECK(thread_checker_.CalledOnValidThread());
  // Just store the information. Mailbox will be consumed in LockForRead().
  ResourceId id = next_id_++;
  DCHECK(mailbox.IsValid());
  Resource& resource = resources_[id];
  if (mailbox.IsTexture()) {
    resource = Resource(0,
                        gfx::Size(),
                        Resource::External,
                        mailbox.target(),
                        GL_LINEAR,
                        0,
                        GL_CLAMP_TO_EDGE,
                        TextureHintImmutable,
                        RGBA_8888);
  } else {
    DCHECK(mailbox.IsSharedMemory());
    base::SharedMemory* shared_memory = mailbox.shared_memory();
    DCHECK(shared_memory->memory());
    uint8_t* pixels = reinterpret_cast<uint8_t*>(shared_memory->memory());
    DCHECK(pixels);
    scoped_ptr<SharedBitmap> shared_bitmap;
    if (shared_bitmap_manager_) {
      shared_bitmap =
          shared_bitmap_manager_->GetBitmapForSharedMemory(shared_memory);
    }
    resource = Resource(pixels,
                        shared_bitmap.release(),
                        mailbox.shared_memory_size(),
                        Resource::External,
                        GL_LINEAR,
                        GL_CLAMP_TO_EDGE);
  }
  resource.allocated = true;
  resource.mailbox = mailbox;
  resource.release_callback_impl =
      base::Bind(&SingleReleaseCallbackImpl::Run,
                 base::Owned(release_callback_impl.release()));
  resource.allow_overlay = mailbox.allow_overlay();
  return id;
}

void ResourceProvider::DeleteResource(ResourceId id) {
  DCHECK(thread_checker_.CalledOnValidThread());
  ResourceMap::iterator it = resources_.find(id);
  CHECK(it != resources_.end());
  Resource* resource = &it->second;
  DCHECK(!resource->marked_for_deletion);
  DCHECK_EQ(resource->imported_count, 0);
  DCHECK(resource->pending_set_pixels || !resource->locked_for_write);

  if (resource->exported_count > 0 || resource->lock_for_read_count > 0) {
    resource->marked_for_deletion = true;
    return;
  } else {
    DeleteResourceInternal(it, Normal);
  }
}

void ResourceProvider::DeleteResourceInternal(ResourceMap::iterator it,
                                              DeleteStyle style) {
  TRACE_EVENT0("cc", "ResourceProvider::DeleteResourceInternal");
  Resource* resource = &it->second;
  bool lost_resource = resource->lost;

  DCHECK(resource->exported_count == 0 || style != Normal);
  if (style == ForShutdown && resource->exported_count > 0)
    lost_resource = true;

  if (resource->image_id) {
    DCHECK(resource->origin == Resource::Internal);
    GLES2Interface* gl = ContextGL();
    DCHECK(gl);
    GLC(gl, gl->DestroyImageCHROMIUM(resource->image_id));
  }
  if (resource->gl_upload_query_id) {
    DCHECK(resource->origin == Resource::Internal);
    GLES2Interface* gl = ContextGL();
    DCHECK(gl);
    GLC(gl, gl->DeleteQueriesEXT(1, &resource->gl_upload_query_id));
  }
  if (resource->gl_read_lock_query_id) {
    DCHECK(resource->origin == Resource::Internal);
    GLES2Interface* gl = ContextGL();
    DCHECK(gl);
    GLC(gl, gl->DeleteQueriesEXT(1, &resource->gl_read_lock_query_id));
  }
  if (resource->gl_pixel_buffer_id) {
    DCHECK(resource->origin == Resource::Internal);
    GLES2Interface* gl = ContextGL();
    DCHECK(gl);
    GLC(gl, gl->DeleteBuffers(1, &resource->gl_pixel_buffer_id));
  }
  if (resource->origin == Resource::External) {
    DCHECK(resource->mailbox.IsValid());
    GLuint sync_point = resource->mailbox.sync_point();
    if (resource->type == GLTexture) {
      DCHECK(resource->mailbox.IsTexture());
      lost_resource |= lost_output_surface_;
      GLES2Interface* gl = ContextGL();
      DCHECK(gl);
      if (resource->gl_id) {
        GLC(gl, gl->DeleteTextures(1, &resource->gl_id));
        resource->gl_id = 0;
        if (!lost_resource)
          sync_point = gl->InsertSyncPointCHROMIUM();
      }
    } else {
      DCHECK(resource->mailbox.IsSharedMemory());
      base::SharedMemory* shared_memory = resource->mailbox.shared_memory();
      if (resource->pixels && shared_memory) {
        DCHECK(shared_memory->memory() == resource->pixels);
        resource->pixels = NULL;
        delete resource->shared_bitmap;
        resource->shared_bitmap = NULL;
      }
    }
    resource->release_callback_impl.Run(
        sync_point, lost_resource, blocking_main_thread_task_runner_);
  }
  if (resource->gl_id) {
    GLES2Interface* gl = ContextGL();
    DCHECK(gl);
    GLC(gl, gl->DeleteTextures(1, &resource->gl_id));
    resource->gl_id = 0;
  }
  if (resource->shared_bitmap) {
    DCHECK(resource->origin != Resource::External);
    DCHECK_EQ(Bitmap, resource->type);
    delete resource->shared_bitmap;
    resource->pixels = NULL;
  }
  if (resource->pixels) {
    DCHECK(resource->origin == Resource::Internal);
    delete[] resource->pixels;
    resource->pixels = NULL;
  }
  if (resource->gpu_memory_buffer) {
    DCHECK(resource->origin == Resource::Internal);
    delete resource->gpu_memory_buffer;
    resource->gpu_memory_buffer = NULL;
  }
  resources_.erase(it);
}

ResourceProvider::ResourceType ResourceProvider::GetResourceType(
    ResourceId id) {
  return GetResource(id)->type;
}

void ResourceProvider::SetPixels(ResourceId id,
                                 const uint8_t* image,
                                 const gfx::Rect& image_rect,
                                 const gfx::Rect& source_rect,
                                 const gfx::Vector2d& dest_offset) {
  Resource* resource = GetResource(id);
  DCHECK(!resource->locked_for_write);
  DCHECK(!resource->lock_for_read_count);
  DCHECK(resource->origin == Resource::Internal);
  DCHECK_EQ(resource->exported_count, 0);
  DCHECK(ReadLockFenceHasPassed(resource));
  LazyAllocate(resource);

  if (resource->type == GLTexture) {
    DCHECK(resource->gl_id);
    DCHECK(!resource->pending_set_pixels);
    DCHECK_EQ(resource->target, static_cast<GLenum>(GL_TEXTURE_2D));
    GLES2Interface* gl = ContextGL();
    DCHECK(gl);
    DCHECK(texture_uploader_.get());
    gl->BindTexture(GL_TEXTURE_2D, resource->gl_id);
    texture_uploader_->Upload(image,
                              image_rect,
                              source_rect,
                              dest_offset,
                              resource->format,
                              resource->size);
  } else {
    DCHECK_EQ(Bitmap, resource->type);
    DCHECK(resource->allocated);
    DCHECK_EQ(RGBA_8888, resource->format);
    DCHECK(source_rect.x() >= image_rect.x());
    DCHECK(source_rect.y() >= image_rect.y());
    DCHECK(source_rect.right() <= image_rect.right());
    DCHECK(source_rect.bottom() <= image_rect.bottom());
    SkImageInfo source_info =
        SkImageInfo::MakeN32Premul(source_rect.width(), source_rect.height());
    size_t image_row_bytes = image_rect.width() * 4;
    gfx::Vector2d source_offset = source_rect.origin() - image_rect.origin();
    image += source_offset.y() * image_row_bytes + source_offset.x() * 4;

    ScopedWriteLockSoftware lock(this, id);
    SkCanvas* dest = lock.sk_canvas();
    dest->writePixels(
        source_info, image, image_row_bytes, dest_offset.x(), dest_offset.y());
  }
}

size_t ResourceProvider::NumBlockingUploads() {
  if (!texture_uploader_)
    return 0;

  return texture_uploader_->NumBlockingUploads();
}

void ResourceProvider::MarkPendingUploadsAsNonBlocking() {
  if (!texture_uploader_)
    return;

  texture_uploader_->MarkPendingUploadsAsNonBlocking();
}

size_t ResourceProvider::EstimatedUploadsPerTick() {
  if (!texture_uploader_)
    return 1u;

  double textures_per_second = texture_uploader_->EstimatedTexturesPerSecond();
  size_t textures_per_tick = floor(
      kTextureUploadTickRate * textures_per_second);
  return textures_per_tick ? textures_per_tick : 1u;
}

void ResourceProvider::FlushUploads() {
  if (!texture_uploader_)
    return;

  texture_uploader_->Flush();
}

void ResourceProvider::ReleaseCachedData() {
  if (!texture_uploader_)
    return;

  texture_uploader_->ReleaseCachedQueries();
}

base::TimeTicks ResourceProvider::EstimatedUploadCompletionTime(
    size_t uploads_per_tick) {
  if (lost_output_surface_)
    return base::TimeTicks();

  // Software resource uploads happen on impl thread, so don't bother batching
  // them up and trying to wait for them to complete.
  if (!texture_uploader_) {
    return gfx::FrameTime::Now() + base::TimeDelta::FromMicroseconds(
        base::Time::kMicrosecondsPerSecond * kSoftwareUploadTickRate);
  }

  base::TimeDelta upload_one_texture_time =
      base::TimeDelta::FromMicroseconds(
          base::Time::kMicrosecondsPerSecond * kTextureUploadTickRate) /
      uploads_per_tick;

  size_t total_uploads = NumBlockingUploads() + uploads_per_tick;
  return gfx::FrameTime::Now() + upload_one_texture_time * total_uploads;
}

ResourceProvider::Resource* ResourceProvider::GetResource(ResourceId id) {
  DCHECK(thread_checker_.CalledOnValidThread());
  ResourceMap::iterator it = resources_.find(id);
  CHECK(it != resources_.end());
  return &it->second;
}

const ResourceProvider::Resource* ResourceProvider::LockForRead(ResourceId id) {
  Resource* resource = GetResource(id);
  DCHECK(!resource->locked_for_write ||
         resource->set_pixels_completion_forced) <<
      "locked for write: " << resource->locked_for_write <<
      " pixels completion forced: " << resource->set_pixels_completion_forced;
  DCHECK_EQ(resource->exported_count, 0);
  // Uninitialized! Call SetPixels or LockForWrite first.
  DCHECK(resource->allocated);

  LazyCreate(resource);

  if (resource->type == GLTexture && !resource->gl_id) {
    DCHECK(resource->origin != Resource::Internal);
    DCHECK(resource->mailbox.IsTexture());

    // Mailbox sync_points must be processed by a call to
    // WaitSyncPointIfNeeded() prior to calling LockForRead().
    DCHECK(!resource->mailbox.sync_point());

    GLES2Interface* gl = ContextGL();
    DCHECK(gl);
    resource->gl_id = texture_id_allocator_->NextId();
    GLC(gl, gl->BindTexture(resource->target, resource->gl_id));
    GLC(gl,
        gl->ConsumeTextureCHROMIUM(resource->mailbox.target(),
                                   resource->mailbox.name()));
  }

  if (!resource->pixels && resource->has_shared_bitmap_id &&
      shared_bitmap_manager_) {
    scoped_ptr<SharedBitmap> bitmap =
        shared_bitmap_manager_->GetSharedBitmapFromId(
            resource->size, resource->shared_bitmap_id);
    if (bitmap) {
      resource->shared_bitmap = bitmap.release();
      resource->pixels = resource->shared_bitmap->pixels();
    }
  }

  resource->lock_for_read_count++;
  if (resource->read_lock_fences_enabled) {
    if (current_read_lock_fence_.get())
      current_read_lock_fence_->Set();
    resource->read_lock_fence = current_read_lock_fence_;
  }

  return resource;
}

void ResourceProvider::UnlockForRead(ResourceId id) {
  DCHECK(thread_checker_.CalledOnValidThread());
  ResourceMap::iterator it = resources_.find(id);
  CHECK(it != resources_.end());

  Resource* resource = &it->second;
  DCHECK_GT(resource->lock_for_read_count, 0);
  DCHECK_EQ(resource->exported_count, 0);
  resource->lock_for_read_count--;
  if (resource->marked_for_deletion && !resource->lock_for_read_count) {
    if (!resource->child_id) {
      // The resource belongs to this ResourceProvider, so it can be destroyed.
      DeleteResourceInternal(it, Normal);
    } else {
      ChildMap::iterator child_it = children_.find(resource->child_id);
      ResourceIdArray unused;
      unused.push_back(id);
      DeleteAndReturnUnusedResourcesToChild(child_it, Normal, unused);
    }
  }
}

ResourceProvider::Resource* ResourceProvider::LockForWrite(ResourceId id) {
  Resource* resource = GetResource(id);
  DCHECK(CanLockForWrite(id));

  resource->locked_for_write = true;
  return resource;
}

bool ResourceProvider::CanLockForWrite(ResourceId id) {
  Resource* resource = GetResource(id);
  return !resource->locked_for_write && !resource->lock_for_read_count &&
         !resource->exported_count && resource->origin == Resource::Internal &&
         !resource->lost && ReadLockFenceHasPassed(resource);
}

void ResourceProvider::UnlockForWrite(ResourceProvider::Resource* resource) {
  DCHECK(resource->locked_for_write);
  DCHECK_EQ(resource->exported_count, 0);
  DCHECK(resource->origin == Resource::Internal);
  resource->locked_for_write = false;
}

ResourceProvider::ScopedReadLockGL::ScopedReadLockGL(
    ResourceProvider* resource_provider,
    ResourceProvider::ResourceId resource_id)
    : resource_provider_(resource_provider),
      resource_id_(resource_id),
      texture_id_(resource_provider->LockForRead(resource_id)->gl_id) {
  DCHECK(texture_id_);
}

ResourceProvider::ScopedReadLockGL::~ScopedReadLockGL() {
  resource_provider_->UnlockForRead(resource_id_);
}

ResourceProvider::ScopedSamplerGL::ScopedSamplerGL(
    ResourceProvider* resource_provider,
    ResourceProvider::ResourceId resource_id,
    GLenum filter)
    : ScopedReadLockGL(resource_provider, resource_id),
      unit_(GL_TEXTURE0),
      target_(resource_provider->BindForSampling(resource_id, unit_, filter)) {
}

ResourceProvider::ScopedSamplerGL::ScopedSamplerGL(
    ResourceProvider* resource_provider,
    ResourceProvider::ResourceId resource_id,
    GLenum unit,
    GLenum filter)
    : ScopedReadLockGL(resource_provider, resource_id),
      unit_(unit),
      target_(resource_provider->BindForSampling(resource_id, unit_, filter)) {
}

ResourceProvider::ScopedSamplerGL::~ScopedSamplerGL() {
}

ResourceProvider::ScopedWriteLockGL::ScopedWriteLockGL(
    ResourceProvider* resource_provider,
    ResourceProvider::ResourceId resource_id)
    : resource_provider_(resource_provider),
      resource_(resource_provider->LockForWrite(resource_id)) {
  resource_provider_->LazyAllocate(resource_);
  texture_id_ = resource_->gl_id;
  DCHECK(texture_id_);
}

ResourceProvider::ScopedWriteLockGL::~ScopedWriteLockGL() {
  resource_provider_->UnlockForWrite(resource_);
}

void ResourceProvider::PopulateSkBitmapWithResource(
    SkBitmap* sk_bitmap, const Resource* resource) {
  DCHECK_EQ(RGBA_8888, resource->format);
  SkImageInfo info = SkImageInfo::MakeN32Premul(resource->size.width(),
                                                resource->size.height());
  sk_bitmap->installPixels(info, resource->pixels, info.minRowBytes());
}

ResourceProvider::ScopedReadLockSoftware::ScopedReadLockSoftware(
    ResourceProvider* resource_provider,
    ResourceProvider::ResourceId resource_id)
    : resource_provider_(resource_provider),
      resource_id_(resource_id) {
  const Resource* resource = resource_provider->LockForRead(resource_id);
  wrap_mode_ = resource->wrap_mode;
  ResourceProvider::PopulateSkBitmapWithResource(&sk_bitmap_, resource);
}

ResourceProvider::ScopedReadLockSoftware::~ScopedReadLockSoftware() {
  resource_provider_->UnlockForRead(resource_id_);
}

ResourceProvider::ScopedWriteLockSoftware::ScopedWriteLockSoftware(
    ResourceProvider* resource_provider,
    ResourceProvider::ResourceId resource_id)
    : resource_provider_(resource_provider),
      resource_(resource_provider->LockForWrite(resource_id)) {
  ResourceProvider::PopulateSkBitmapWithResource(&sk_bitmap_, resource_);
  DCHECK(valid());
  sk_canvas_.reset(new SkCanvas(sk_bitmap_));
}

ResourceProvider::ScopedWriteLockSoftware::~ScopedWriteLockSoftware() {
  DCHECK(thread_checker_.CalledOnValidThread());
  resource_provider_->UnlockForWrite(resource_);
}

ResourceProvider::ScopedWriteLockGpuMemoryBuffer::
    ScopedWriteLockGpuMemoryBuffer(ResourceProvider* resource_provider,
                                   ResourceProvider::ResourceId resource_id)
    : resource_provider_(resource_provider),
      resource_(resource_provider->LockForWrite(resource_id)),
      gpu_memory_buffer_manager_(resource_provider->gpu_memory_buffer_manager_),
      gpu_memory_buffer_(nullptr),
      size_(resource_->size),
      format_(resource_->format) {
  DCHECK_EQ(GLTexture, resource_->type);
  std::swap(gpu_memory_buffer_, resource_->gpu_memory_buffer);
}

ResourceProvider::ScopedWriteLockGpuMemoryBuffer::
    ~ScopedWriteLockGpuMemoryBuffer() {
  DCHECK(thread_checker_.CalledOnValidThread());
  resource_provider_->UnlockForWrite(resource_);
  if (!gpu_memory_buffer_)
    return;

  if (!resource_->image_id) {
    GLES2Interface* gl = resource_provider_->ContextGL();
    DCHECK(gl);

    resource_->image_id =
        gl->CreateImageCHROMIUM(gpu_memory_buffer_->AsClientBuffer(),
                                size_.width(),
                                size_.height(),
                                GL_RGBA);
  }

  std::swap(resource_->gpu_memory_buffer, gpu_memory_buffer_);
  resource_->allocated = true;
  resource_->dirty_image = true;

  // GpuMemoryBuffer provides direct access to the memory used by the GPU.
  // Read lock fences are required to ensure that we're not trying to map a
  // buffer that is currently in-use by the GPU.
  resource_->read_lock_fences_enabled = true;
}

gfx::GpuMemoryBuffer*
ResourceProvider::ScopedWriteLockGpuMemoryBuffer::GetGpuMemoryBuffer() {
  if (!gpu_memory_buffer_) {
    scoped_ptr<gfx::GpuMemoryBuffer> gpu_memory_buffer =
        gpu_memory_buffer_manager_->AllocateGpuMemoryBuffer(
            size_, ToGpuMemoryBufferFormat(format_), gfx::GpuMemoryBuffer::MAP);
    gpu_memory_buffer_ = gpu_memory_buffer.release();
  }

  return gpu_memory_buffer_;
}

ResourceProvider::ScopedWriteLockGr::ScopedWriteLockGr(
    ResourceProvider* resource_provider,
    ResourceProvider::ResourceId resource_id)
    : resource_provider_(resource_provider),
      resource_(resource_provider->LockForWrite(resource_id)) {
}

ResourceProvider::ScopedWriteLockGr::~ScopedWriteLockGr() {
  DCHECK(thread_checker_.CalledOnValidThread());
  resource_provider_->UnlockForWrite(resource_);
}

SkSurface* ResourceProvider::ScopedWriteLockGr::GetSkSurface(
    bool use_distance_field_text,
    bool can_use_lcd_text) {
  DCHECK(thread_checker_.CalledOnValidThread());
  DCHECK(resource_->locked_for_write);

  bool create_surface =
      !resource_->sk_surface.get() ||
      !SurfaceHasMatchingProperties(use_distance_field_text, can_use_lcd_text);
  if (create_surface) {
    class GrContext* gr_context = resource_provider_->GrContext();
    // TODO(alokp): Implement TestContextProvider::GrContext().
    if (!gr_context)
      return nullptr;

    resource_provider_->LazyAllocate(resource_);

    GrBackendTextureDesc desc;
    desc.fFlags = kRenderTarget_GrBackendTextureFlag;
    desc.fWidth = resource_->size.width();
    desc.fHeight = resource_->size.height();
    desc.fConfig = ToGrPixelConfig(resource_->format);
    desc.fOrigin = kTopLeft_GrSurfaceOrigin;
    desc.fTextureHandle = resource_->gl_id;
    skia::RefPtr<GrTexture> gr_texture =
        skia::AdoptRef(gr_context->wrapBackendTexture(desc));
    if (!gr_texture)
      return nullptr;
    uint32_t flags = use_distance_field_text
                         ? SkSurfaceProps::kUseDistanceFieldFonts_Flag
                         : 0;
    // Use unknown pixel geometry to disable LCD text.
    SkSurfaceProps surface_props(flags, kUnknown_SkPixelGeometry);
    if (can_use_lcd_text) {
      // LegacyFontHost will get LCD text and skia figures out what type to use.
      surface_props =
          SkSurfaceProps(flags, SkSurfaceProps::kLegacyFontHost_InitType);
    }
    resource_->sk_surface = skia::AdoptRef(SkSurface::NewRenderTargetDirect(
        gr_texture->asRenderTarget(), &surface_props));
  }
  return resource_->sk_surface.get();
}

bool ResourceProvider::ScopedWriteLockGr::SurfaceHasMatchingProperties(
    bool use_distance_field_text,
    bool can_use_lcd_text) const {
  const SkSurface* surface = resource_->sk_surface.get();
  bool surface_uses_distance_field_text =
      surface->props().isUseDistanceFieldFonts();
  bool surface_can_use_lcd_text =
      surface->props().pixelGeometry() != kUnknown_SkPixelGeometry;
  return use_distance_field_text == surface_uses_distance_field_text &&
         can_use_lcd_text == surface_can_use_lcd_text;
}

ResourceProvider::SynchronousFence::SynchronousFence(
    gpu::gles2::GLES2Interface* gl)
    : gl_(gl), has_synchronized_(true) {
}

ResourceProvider::SynchronousFence::~SynchronousFence() {
}

void ResourceProvider::SynchronousFence::Set() {
  has_synchronized_ = false;
}

bool ResourceProvider::SynchronousFence::HasPassed() {
  if (!has_synchronized_) {
    has_synchronized_ = true;
    Synchronize();
  }
  return true;
}

void ResourceProvider::SynchronousFence::Wait() {
  HasPassed();
}

void ResourceProvider::SynchronousFence::Synchronize() {
  TRACE_EVENT0("cc", "ResourceProvider::SynchronousFence::Synchronize");
  gl_->Finish();
}

ResourceProvider::ResourceProvider(
    OutputSurface* output_surface,
    SharedBitmapManager* shared_bitmap_manager,
    gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
    BlockingTaskRunner* blocking_main_thread_task_runner,
    int highp_threshold_min,
    bool use_rgba_4444_texture_format,
    size_t id_allocation_chunk_size)
    : output_surface_(output_surface),
      shared_bitmap_manager_(shared_bitmap_manager),
      gpu_memory_buffer_manager_(gpu_memory_buffer_manager),
      blocking_main_thread_task_runner_(blocking_main_thread_task_runner),
      lost_output_surface_(false),
      highp_threshold_min_(highp_threshold_min),
      next_id_(1),
      next_child_(1),
      default_resource_type_(InvalidType),
      use_texture_storage_ext_(false),
      use_texture_format_bgra_(false),
      use_texture_usage_hint_(false),
      use_compressed_texture_etc1_(false),
      max_texture_size_(0),
      best_texture_format_(RGBA_8888),
      use_rgba_4444_texture_format_(use_rgba_4444_texture_format),
      id_allocation_chunk_size_(id_allocation_chunk_size),
      use_sync_query_(false) {
  DCHECK(output_surface_->HasClient());
  DCHECK(id_allocation_chunk_size_);
}

void ResourceProvider::InitializeSoftware() {
  DCHECK(thread_checker_.CalledOnValidThread());
  DCHECK_NE(Bitmap, default_resource_type_);

  CleanUpGLIfNeeded();

  default_resource_type_ = Bitmap;
  // Pick an arbitrary limit here similar to what hardware might.
  max_texture_size_ = 16 * 1024;
  best_texture_format_ = RGBA_8888;
}

void ResourceProvider::InitializeGL() {
  DCHECK(thread_checker_.CalledOnValidThread());
  DCHECK(!texture_uploader_);
  DCHECK_NE(GLTexture, default_resource_type_);
  DCHECK(!texture_id_allocator_);
  DCHECK(!buffer_id_allocator_);

  default_resource_type_ = GLTexture;

  const ContextProvider::Capabilities& caps =
      output_surface_->context_provider()->ContextCapabilities();

  bool use_bgra = caps.gpu.texture_format_bgra8888;
  use_texture_storage_ext_ = caps.gpu.texture_storage;
  use_texture_format_bgra_ = caps.gpu.texture_format_bgra8888;
  use_texture_usage_hint_ = caps.gpu.texture_usage;
  use_compressed_texture_etc1_ = caps.gpu.texture_format_etc1;
  use_sync_query_ = caps.gpu.sync_query;

  GLES2Interface* gl = ContextGL();
  DCHECK(gl);

  texture_uploader_ = TextureUploader::Create(gl);
  max_texture_size_ = 0;  // Context expects cleared value.
  GLC(gl, gl->GetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size_));
  best_texture_format_ = PlatformColor::BestTextureFormat(use_bgra);

  texture_id_allocator_.reset(
      new TextureIdAllocator(gl, id_allocation_chunk_size_));
  buffer_id_allocator_.reset(
      new BufferIdAllocator(gl, id_allocation_chunk_size_));
}

void ResourceProvider::CleanUpGLIfNeeded() {
  GLES2Interface* gl = ContextGL();
  if (default_resource_type_ != GLTexture) {
    // We are not in GL mode, but double check before returning.
    DCHECK(!gl);
    DCHECK(!texture_uploader_);
    return;
  }

  DCHECK(gl);
#if DCHECK_IS_ON
  // Check that all GL resources has been deleted.
  for (ResourceMap::const_iterator itr = resources_.begin();
       itr != resources_.end();
       ++itr) {
    DCHECK_NE(GLTexture, itr->second.type);
  }
#endif  // DCHECK_IS_ON

  texture_uploader_ = nullptr;
  texture_id_allocator_ = nullptr;
  buffer_id_allocator_ = nullptr;
  gl->Finish();
}

int ResourceProvider::CreateChild(const ReturnCallback& return_callback) {
  DCHECK(thread_checker_.CalledOnValidThread());

  Child child_info;
  child_info.return_callback = return_callback;

  int child = next_child_++;
  children_[child] = child_info;
  return child;
}

void ResourceProvider::DestroyChild(int child_id) {
  ChildMap::iterator it = children_.find(child_id);
  DCHECK(it != children_.end());
  DestroyChildInternal(it, Normal);
}

void ResourceProvider::DestroyChildInternal(ChildMap::iterator it,
                                            DeleteStyle style) {
  DCHECK(thread_checker_.CalledOnValidThread());

  Child& child = it->second;
  DCHECK(style == ForShutdown || !child.marked_for_deletion);

  ResourceIdArray resources_for_child;

  for (ResourceIdMap::iterator child_it = child.child_to_parent_map.begin();
       child_it != child.child_to_parent_map.end();
       ++child_it) {
    ResourceId id = child_it->second;
    resources_for_child.push_back(id);
  }

  // If the child is going away, don't consider any resources in use.
  child.in_use_resources.clear();
  child.marked_for_deletion = true;

  DeleteAndReturnUnusedResourcesToChild(it, style, resources_for_child);
}

const ResourceProvider::ResourceIdMap& ResourceProvider::GetChildToParentMap(
    int child) const {
  DCHECK(thread_checker_.CalledOnValidThread());
  ChildMap::const_iterator it = children_.find(child);
  DCHECK(it != children_.end());
  DCHECK(!it->second.marked_for_deletion);
  return it->second.child_to_parent_map;
}

void ResourceProvider::PrepareSendToParent(const ResourceIdArray& resources,
                                           TransferableResourceArray* list) {
  DCHECK(thread_checker_.CalledOnValidThread());
  GLES2Interface* gl = ContextGL();
  bool need_sync_point = false;
  for (ResourceIdArray::const_iterator it = resources.begin();
       it != resources.end();
       ++it) {
    TransferableResource resource;
    TransferResource(gl, *it, &resource);
    if (!resource.mailbox_holder.sync_point && !resource.is_software)
      need_sync_point = true;
    ++resources_.find(*it)->second.exported_count;
    list->push_back(resource);
  }
  if (need_sync_point) {
    GLuint sync_point = gl->InsertSyncPointCHROMIUM();
    for (TransferableResourceArray::iterator it = list->begin();
         it != list->end();
         ++it) {
      if (!it->mailbox_holder.sync_point)
        it->mailbox_holder.sync_point = sync_point;
    }
  }
}

void ResourceProvider::ReceiveFromChild(
    int child, const TransferableResourceArray& resources) {
  DCHECK(thread_checker_.CalledOnValidThread());
  GLES2Interface* gl = ContextGL();
  Child& child_info = children_.find(child)->second;
  DCHECK(!child_info.marked_for_deletion);
  for (TransferableResourceArray::const_iterator it = resources.begin();
       it != resources.end();
       ++it) {
    ResourceIdMap::iterator resource_in_map_it =
        child_info.child_to_parent_map.find(it->id);
    if (resource_in_map_it != child_info.child_to_parent_map.end()) {
      Resource& resource = resources_[resource_in_map_it->second];
      resource.marked_for_deletion = false;
      resource.imported_count++;
      continue;
    }

    if ((!it->is_software && !gl) ||
        (it->is_software && !shared_bitmap_manager_)) {
      TRACE_EVENT0("cc", "ResourceProvider::ReceiveFromChild dropping invalid");
      ReturnedResourceArray to_return;
      to_return.push_back(it->ToReturnedResource());
      child_info.return_callback.Run(to_return,
                                     blocking_main_thread_task_runner_);
      continue;
    }

    ResourceId local_id = next_id_++;
    Resource& resource = resources_[local_id];
    if (it->is_software) {
      resource = Resource(it->mailbox_holder.mailbox,
                          it->size,
                          Resource::Delegated,
                          GL_LINEAR,
                          it->is_repeated ? GL_REPEAT : GL_CLAMP_TO_EDGE);
    } else {
      resource = Resource(0,
                          it->size,
                          Resource::Delegated,
                          it->mailbox_holder.texture_target,
                          it->filter,
                          0,
                          it->is_repeated ? GL_REPEAT : GL_CLAMP_TO_EDGE,
                          TextureHintImmutable,
                          it->format);
      resource.mailbox = TextureMailbox(it->mailbox_holder.mailbox,
                                        it->mailbox_holder.texture_target,
                                        it->mailbox_holder.sync_point);
    }
    resource.child_id = child;
    // Don't allocate a texture for a child.
    resource.allocated = true;
    resource.imported_count = 1;
    resource.allow_overlay = it->allow_overlay;
    child_info.parent_to_child_map[local_id] = it->id;
    child_info.child_to_parent_map[it->id] = local_id;
  }
}

void ResourceProvider::DeclareUsedResourcesFromChild(
    int child,
    const ResourceIdArray& resources_from_child) {
  DCHECK(thread_checker_.CalledOnValidThread());

  ChildMap::iterator child_it = children_.find(child);
  DCHECK(child_it != children_.end());
  Child& child_info = child_it->second;
  DCHECK(!child_info.marked_for_deletion);
  child_info.in_use_resources.clear();

  for (size_t i = 0; i < resources_from_child.size(); ++i) {
    ResourceIdMap::iterator it =
        child_info.child_to_parent_map.find(resources_from_child[i]);
    DCHECK(it != child_info.child_to_parent_map.end());

    ResourceId local_id = it->second;
    DCHECK(!resources_[local_id].marked_for_deletion);
    child_info.in_use_resources.insert(local_id);
  }

  ResourceIdArray unused;
  for (ResourceIdMap::iterator it = child_info.child_to_parent_map.begin();
       it != child_info.child_to_parent_map.end();
       ++it) {
    ResourceId local_id = it->second;
    bool resource_is_in_use = child_info.in_use_resources.count(local_id) > 0;
    if (!resource_is_in_use)
      unused.push_back(local_id);
  }
  DeleteAndReturnUnusedResourcesToChild(child_it, Normal, unused);
}

// static
bool ResourceProvider::CompareResourceMapIteratorsByChildId(
    const std::pair<ReturnedResource, ResourceMap::iterator>& a,
    const std::pair<ReturnedResource, ResourceMap::iterator>& b) {
  const ResourceMap::iterator& a_it = a.second;
  const ResourceMap::iterator& b_it = b.second;
  const Resource& a_resource = a_it->second;
  const Resource& b_resource = b_it->second;
  return a_resource.child_id < b_resource.child_id;
}

void ResourceProvider::ReceiveReturnsFromParent(
    const ReturnedResourceArray& resources) {
  DCHECK(thread_checker_.CalledOnValidThread());
  GLES2Interface* gl = ContextGL();

  int child_id = 0;
  ResourceIdArray resources_for_child;

  std::vector<std::pair<ReturnedResource, ResourceMap::iterator>>
      sorted_resources;

  for (ReturnedResourceArray::const_iterator it = resources.begin();
       it != resources.end();
       ++it) {
    ResourceId local_id = it->id;
    ResourceMap::iterator map_iterator = resources_.find(local_id);

    // Resource was already lost (e.g. it belonged to a child that was
    // destroyed).
    if (map_iterator == resources_.end())
      continue;

    sorted_resources.push_back(
        std::pair<ReturnedResource, ResourceMap::iterator>(*it, map_iterator));
  }

  std::sort(sorted_resources.begin(),
            sorted_resources.end(),
            CompareResourceMapIteratorsByChildId);

  ChildMap::iterator child_it = children_.end();
  for (size_t i = 0; i < sorted_resources.size(); ++i) {
    ReturnedResource& returned = sorted_resources[i].first;
    ResourceMap::iterator& map_iterator = sorted_resources[i].second;
    ResourceId local_id = map_iterator->first;
    Resource* resource = &map_iterator->second;

    CHECK_GE(resource->exported_count, returned.count);
    resource->exported_count -= returned.count;
    resource->lost |= returned.lost;
    if (resource->exported_count)
      continue;

    // Need to wait for the current read lock fence to pass before we can
    // recycle this resource.
    if (resource->read_lock_fences_enabled) {
      if (current_read_lock_fence_.get())
        current_read_lock_fence_->Set();
      resource->read_lock_fence = current_read_lock_fence_;
    }

    if (returned.sync_point) {
      DCHECK(!resource->has_shared_bitmap_id);
      if (resource->origin == Resource::Internal) {
        DCHECK(resource->gl_id);
        GLC(gl, gl->WaitSyncPointCHROMIUM(returned.sync_point));
      } else {
        DCHECK(!resource->gl_id);
        resource->mailbox.set_sync_point(returned.sync_point);
      }
    }

    if (!resource->marked_for_deletion)
      continue;

    if (!resource->child_id) {
      // The resource belongs to this ResourceProvider, so it can be destroyed.
      DeleteResourceInternal(map_iterator, Normal);
      continue;
    }

    DCHECK(resource->origin == Resource::Delegated);
    // Delete the resource and return it to the child it came from one.
    if (resource->child_id != child_id) {
      if (child_id) {
        DCHECK_NE(resources_for_child.size(), 0u);
        DCHECK(child_it != children_.end());
        DeleteAndReturnUnusedResourcesToChild(
            child_it, Normal, resources_for_child);
        resources_for_child.clear();
      }

      child_it = children_.find(resource->child_id);
      DCHECK(child_it != children_.end());
      child_id = resource->child_id;
    }
    resources_for_child.push_back(local_id);
  }

  if (child_id) {
    DCHECK_NE(resources_for_child.size(), 0u);
    DCHECK(child_it != children_.end());
    DeleteAndReturnUnusedResourcesToChild(
        child_it, Normal, resources_for_child);
  }
}

void ResourceProvider::TransferResource(GLES2Interface* gl,
                                        ResourceId id,
                                        TransferableResource* resource) {
  Resource* source = GetResource(id);
  DCHECK(!source->locked_for_write);
  DCHECK(!source->lock_for_read_count);
  DCHECK(source->origin != Resource::External || source->mailbox.IsValid());
  DCHECK(source->allocated);
  resource->id = id;
  resource->format = source->format;
  resource->mailbox_holder.texture_target = source->target;
  resource->filter = source->filter;
  resource->size = source->size;
  resource->is_repeated = (source->wrap_mode == GL_REPEAT);
  resource->allow_overlay = source->allow_overlay;

  if (source->type == Bitmap) {
    resource->mailbox_holder.mailbox = source->shared_bitmap_id;
    resource->is_software = true;
  } else if (!source->mailbox.IsValid()) {
    LazyCreate(source);
    DCHECK(source->gl_id);
    DCHECK(source->origin == Resource::Internal);
    GLC(gl,
        gl->BindTexture(resource->mailbox_holder.texture_target,
                        source->gl_id));
    if (source->image_id) {
      DCHECK(source->dirty_image);
      BindImageForSampling(source);
    }
    // This is a resource allocated by the compositor, we need to produce it.
    // Don't set a sync point, the caller will do it.
    GLC(gl, gl->GenMailboxCHROMIUM(resource->mailbox_holder.mailbox.name));
    GLC(gl,
        gl->ProduceTextureCHROMIUM(resource->mailbox_holder.texture_target,
                                   resource->mailbox_holder.mailbox.name));
    source->mailbox = TextureMailbox(resource->mailbox_holder);
  } else {
    DCHECK(source->mailbox.IsTexture());
    if (source->image_id && source->dirty_image) {
      DCHECK(source->gl_id);
      DCHECK(source->origin == Resource::Internal);
      GLC(gl,
          gl->BindTexture(resource->mailbox_holder.texture_target,
                          source->gl_id));
      BindImageForSampling(source);
    }
    // This is either an external resource, or a compositor resource that we
    // already exported. Make sure to forward the sync point that we were given.
    resource->mailbox_holder.mailbox = source->mailbox.mailbox();
    resource->mailbox_holder.texture_target = source->mailbox.target();
    resource->mailbox_holder.sync_point = source->mailbox.sync_point();
    source->mailbox.set_sync_point(0);
  }
}

void ResourceProvider::DeleteAndReturnUnusedResourcesToChild(
    ChildMap::iterator child_it,
    DeleteStyle style,
    const ResourceIdArray& unused) {
  DCHECK(thread_checker_.CalledOnValidThread());
  DCHECK(child_it != children_.end());
  Child* child_info = &child_it->second;

  if (unused.empty() && !child_info->marked_for_deletion)
    return;

  ReturnedResourceArray to_return;

  GLES2Interface* gl = ContextGL();
  bool need_sync_point = false;
  for (size_t i = 0; i < unused.size(); ++i) {
    ResourceId local_id = unused[i];

    ResourceMap::iterator it = resources_.find(local_id);
    CHECK(it != resources_.end());
    Resource& resource = it->second;

    DCHECK(!resource.locked_for_write);
    DCHECK_EQ(0u, child_info->in_use_resources.count(local_id));
    DCHECK(child_info->parent_to_child_map.count(local_id));

    ResourceId child_id = child_info->parent_to_child_map[local_id];
    DCHECK(child_info->child_to_parent_map.count(child_id));

    bool is_lost =
        resource.lost || (resource.type == GLTexture && lost_output_surface_);
    if (resource.exported_count > 0 || resource.lock_for_read_count > 0) {
      if (style != ForShutdown) {
        // Defer this until we receive the resource back from the parent or
        // the read lock is released.
        resource.marked_for_deletion = true;
        continue;
      }

      // We still have an exported_count, so we'll have to lose it.
      is_lost = true;
    }

    if (gl && resource.filter != resource.original_filter) {
      DCHECK(resource.target);
      DCHECK(resource.gl_id);

      GLC(gl, gl->BindTexture(resource.target, resource.gl_id));
      GLC(gl,
          gl->TexParameteri(resource.target,
                            GL_TEXTURE_MIN_FILTER,
                            resource.original_filter));
      GLC(gl,
          gl->TexParameteri(resource.target,
                            GL_TEXTURE_MAG_FILTER,
                            resource.original_filter));
    }

    ReturnedResource returned;
    returned.id = child_id;
    returned.sync_point = resource.mailbox.sync_point();
    if (!returned.sync_point && resource.type == GLTexture)
      need_sync_point = true;
    returned.count = resource.imported_count;
    returned.lost = is_lost;
    to_return.push_back(returned);

    child_info->parent_to_child_map.erase(local_id);
    child_info->child_to_parent_map.erase(child_id);
    resource.imported_count = 0;
    DeleteResourceInternal(it, style);
  }
  if (need_sync_point) {
    DCHECK(gl);
    GLuint sync_point = gl->InsertSyncPointCHROMIUM();
    for (size_t i = 0; i < to_return.size(); ++i) {
      if (!to_return[i].sync_point)
        to_return[i].sync_point = sync_point;
    }
  }

  if (!to_return.empty())
    child_info->return_callback.Run(to_return,
                                    blocking_main_thread_task_runner_);

  if (child_info->marked_for_deletion &&
      child_info->parent_to_child_map.empty()) {
    DCHECK(child_info->child_to_parent_map.empty());
    children_.erase(child_it);
  }
}

void ResourceProvider::AcquirePixelBuffer(ResourceId id) {
  TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
               "ResourceProvider::AcquirePixelBuffer");

  Resource* resource = GetResource(id);
  DCHECK(resource->origin == Resource::Internal);
  DCHECK_EQ(resource->exported_count, 0);
  DCHECK(!resource->image_id);
  DCHECK_NE(ETC1, resource->format);

  DCHECK_EQ(GLTexture, resource->type);
  GLES2Interface* gl = ContextGL();
  DCHECK(gl);
  if (!resource->gl_pixel_buffer_id)
    resource->gl_pixel_buffer_id = buffer_id_allocator_->NextId();
  gl->BindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM,
                 resource->gl_pixel_buffer_id);
  unsigned bytes_per_pixel = BitsPerPixel(resource->format) / 8;
  gl->BufferData(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM,
                 resource->size.height() *
                     RoundUp(bytes_per_pixel * resource->size.width(), 4u),
                 NULL,
                 GL_DYNAMIC_DRAW);
  gl->BindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, 0);
}

void ResourceProvider::ReleasePixelBuffer(ResourceId id) {
  TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
               "ResourceProvider::ReleasePixelBuffer");

  Resource* resource = GetResource(id);
  DCHECK(resource->origin == Resource::Internal);
  DCHECK_EQ(resource->exported_count, 0);
  DCHECK(!resource->image_id);

  // The pixel buffer can be released while there is a pending "set pixels"
  // if completion has been forced. Any shared memory associated with this
  // pixel buffer will not be freed until the waitAsyncTexImage2DCHROMIUM
  // command has been processed on the service side. It is also safe to
  // reuse any query id associated with this resource before they complete
  // as each new query has a unique submit count.
  if (resource->pending_set_pixels) {
    DCHECK(resource->set_pixels_completion_forced);
    resource->pending_set_pixels = false;
    resource->locked_for_write = false;
  }

  DCHECK_EQ(GLTexture, resource->type);
  if (!resource->gl_pixel_buffer_id)
    return;
  GLES2Interface* gl = ContextGL();
  DCHECK(gl);
  gl->BindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM,
                 resource->gl_pixel_buffer_id);
  gl->BufferData(
      GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, 0, NULL, GL_DYNAMIC_DRAW);
  gl->BindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, 0);
}

uint8_t* ResourceProvider::MapPixelBuffer(ResourceId id, int* stride) {
  TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
               "ResourceProvider::MapPixelBuffer");

  Resource* resource = GetResource(id);
  DCHECK(resource->origin == Resource::Internal);
  DCHECK_EQ(resource->exported_count, 0);
  DCHECK(!resource->image_id);

  *stride = 0;
  DCHECK_EQ(GLTexture, resource->type);
  GLES2Interface* gl = ContextGL();
  DCHECK(gl);
  DCHECK(resource->gl_pixel_buffer_id);
  gl->BindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM,
                 resource->gl_pixel_buffer_id);
  uint8_t* image = static_cast<uint8_t*>(gl->MapBufferCHROMIUM(
      GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, GL_WRITE_ONLY));
  gl->BindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, 0);
  // Buffer is required to be 4-byte aligned.
  CHECK(!(reinterpret_cast<intptr_t>(image) & 3));
  return image;
}

void ResourceProvider::UnmapPixelBuffer(ResourceId id) {
  TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
               "ResourceProvider::UnmapPixelBuffer");

  Resource* resource = GetResource(id);
  DCHECK(resource->origin == Resource::Internal);
  DCHECK_EQ(resource->exported_count, 0);
  DCHECK(!resource->image_id);

  DCHECK_EQ(GLTexture, resource->type);
  GLES2Interface* gl = ContextGL();
  DCHECK(gl);
  DCHECK(resource->gl_pixel_buffer_id);
  gl->BindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM,
                 resource->gl_pixel_buffer_id);
  gl->UnmapBufferCHROMIUM(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM);
  gl->BindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, 0);
}

GLenum ResourceProvider::BindForSampling(ResourceId resource_id,
                                         GLenum unit,
                                         GLenum filter) {
  DCHECK(thread_checker_.CalledOnValidThread());
  GLES2Interface* gl = ContextGL();
  ResourceMap::iterator it = resources_.find(resource_id);
  DCHECK(it != resources_.end());
  Resource* resource = &it->second;
  DCHECK(resource->lock_for_read_count);
  DCHECK(!resource->locked_for_write || resource->set_pixels_completion_forced);

  ScopedSetActiveTexture scoped_active_tex(gl, unit);
  GLenum target = resource->target;
  GLC(gl, gl->BindTexture(target, resource->gl_id));
  if (filter != resource->filter) {
    GLC(gl, gl->TexParameteri(target, GL_TEXTURE_MIN_FILTER, filter));
    GLC(gl, gl->TexParameteri(target, GL_TEXTURE_MAG_FILTER, filter));
    resource->filter = filter;
  }

  if (resource->image_id && resource->dirty_image)
    BindImageForSampling(resource);

  return target;
}

void ResourceProvider::BeginSetPixels(ResourceId id) {
  TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
               "ResourceProvider::BeginSetPixels");

  Resource* resource = GetResource(id);
  DCHECK(!resource->pending_set_pixels);

  LazyCreate(resource);
  DCHECK(resource->origin == Resource::Internal);
  DCHECK(resource->gl_id || resource->allocated);
  DCHECK(ReadLockFenceHasPassed(resource));
  DCHECK(!resource->image_id);

  bool allocate = !resource->allocated;
  resource->allocated = true;
  LockForWrite(id);

  DCHECK_EQ(GLTexture, resource->type);
  DCHECK(resource->gl_id);
  GLES2Interface* gl = ContextGL();
  DCHECK(gl);
  DCHECK(resource->gl_pixel_buffer_id);
  DCHECK_EQ(resource->target, static_cast<GLenum>(GL_TEXTURE_2D));
  gl->BindTexture(GL_TEXTURE_2D, resource->gl_id);
  gl->BindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM,
                 resource->gl_pixel_buffer_id);
  if (!resource->gl_upload_query_id)
    gl->GenQueriesEXT(1, &resource->gl_upload_query_id);
  gl->BeginQueryEXT(GL_ASYNC_PIXEL_UNPACK_COMPLETED_CHROMIUM,
                    resource->gl_upload_query_id);
  if (allocate) {
    gl->AsyncTexImage2DCHROMIUM(GL_TEXTURE_2D,
                                0, /* level */
                                GLInternalFormat(resource->format),
                                resource->size.width(),
                                resource->size.height(),
                                0, /* border */
                                GLDataFormat(resource->format),
                                GLDataType(resource->format),
                                NULL);
  } else {
    gl->AsyncTexSubImage2DCHROMIUM(GL_TEXTURE_2D,
                                   0, /* level */
                                   0, /* x */
                                   0, /* y */
                                   resource->size.width(),
                                   resource->size.height(),
                                   GLDataFormat(resource->format),
                                   GLDataType(resource->format),
                                   NULL);
  }
  gl->EndQueryEXT(GL_ASYNC_PIXEL_UNPACK_COMPLETED_CHROMIUM);
  gl->BindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, 0);

  resource->pending_set_pixels = true;
  resource->set_pixels_completion_forced = false;
}

void ResourceProvider::ForceSetPixelsToComplete(ResourceId id) {
  TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
               "ResourceProvider::ForceSetPixelsToComplete");

  Resource* resource = GetResource(id);

  DCHECK(resource->locked_for_write);
  DCHECK(resource->pending_set_pixels);
  DCHECK(!resource->set_pixels_completion_forced);

  if (resource->gl_id) {
    GLES2Interface* gl = ContextGL();
    GLC(gl, gl->BindTexture(GL_TEXTURE_2D, resource->gl_id));
    GLC(gl, gl->WaitAsyncTexImage2DCHROMIUM(GL_TEXTURE_2D));
    GLC(gl, gl->BindTexture(GL_TEXTURE_2D, 0));
  }

  resource->set_pixels_completion_forced = true;
}

bool ResourceProvider::DidSetPixelsComplete(ResourceId id) {
  TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
               "ResourceProvider::DidSetPixelsComplete");

  Resource* resource = GetResource(id);

  DCHECK(resource->locked_for_write);
  DCHECK(resource->pending_set_pixels);

  if (resource->gl_id) {
    GLES2Interface* gl = ContextGL();
    DCHECK(gl);
    DCHECK(resource->gl_upload_query_id);
    GLuint complete = 1;
    gl->GetQueryObjectuivEXT(
        resource->gl_upload_query_id, GL_QUERY_RESULT_AVAILABLE_EXT, &complete);
    if (!complete)
      return false;
  }

  resource->pending_set_pixels = false;
  UnlockForWrite(resource);

  // Async set pixels commands are not necessarily processed in-sequence with
  // drawing commands. Read lock fences are required to ensure that async
  // commands don't access the resource while used for drawing.
  resource->read_lock_fences_enabled = true;

  return true;
}

void ResourceProvider::CreateForTesting(ResourceId id) {
  LazyCreate(GetResource(id));
}

GLenum ResourceProvider::TargetForTesting(ResourceId id) {
  Resource* resource = GetResource(id);
  return resource->target;
}

void ResourceProvider::LazyCreate(Resource* resource) {
  if (resource->type != GLTexture || resource->origin != Resource::Internal)
    return;

  if (resource->gl_id)
    return;

  DCHECK(resource->texture_pool);
  DCHECK(resource->origin == Resource::Internal);
  DCHECK(!resource->mailbox.IsValid());
  resource->gl_id = texture_id_allocator_->NextId();

  GLES2Interface* gl = ContextGL();
  DCHECK(gl);

  // Create and set texture properties. Allocation is delayed until needed.
  GLC(gl, gl->BindTexture(resource->target, resource->gl_id));
  GLC(gl,
      gl->TexParameteri(
          resource->target, GL_TEXTURE_MIN_FILTER, resource->original_filter));
  GLC(gl,
      gl->TexParameteri(
          resource->target, GL_TEXTURE_MAG_FILTER, resource->original_filter));
  GLC(gl,
      gl->TexParameteri(
          resource->target, GL_TEXTURE_WRAP_S, resource->wrap_mode));
  GLC(gl,
      gl->TexParameteri(
          resource->target, GL_TEXTURE_WRAP_T, resource->wrap_mode));
  GLC(gl,
      gl->TexParameteri(
          resource->target, GL_TEXTURE_POOL_CHROMIUM, resource->texture_pool));
  if (use_texture_usage_hint_ && (resource->hint & TextureHintFramebuffer)) {
    GLC(gl,
        gl->TexParameteri(resource->target,
                          GL_TEXTURE_USAGE_ANGLE,
                          GL_FRAMEBUFFER_ATTACHMENT_ANGLE));
  }
}

void ResourceProvider::AllocateForTesting(ResourceId id) {
  LazyAllocate(GetResource(id));
}

void ResourceProvider::LazyAllocate(Resource* resource) {
  DCHECK(resource);
  if (resource->allocated)
    return;
  LazyCreate(resource);
  if (!resource->gl_id)
    return;
  resource->allocated = true;
  GLES2Interface* gl = ContextGL();
  gfx::Size& size = resource->size;
  DCHECK_EQ(resource->target, static_cast<GLenum>(GL_TEXTURE_2D));
  ResourceFormat format = resource->format;
  GLC(gl, gl->BindTexture(GL_TEXTURE_2D, resource->gl_id));
  if (use_texture_storage_ext_ &&
      IsFormatSupportedForStorage(format, use_texture_format_bgra_) &&
      (resource->hint & TextureHintImmutable)) {
    GLenum storage_format = TextureToStorageFormat(format);
    GLC(gl,
        gl->TexStorage2DEXT(
            GL_TEXTURE_2D, 1, storage_format, size.width(), size.height()));
  } else {
    // ETC1 does not support preallocation.
    if (format != ETC1) {
      GLC(gl,
          gl->TexImage2D(GL_TEXTURE_2D,
                         0,
                         GLInternalFormat(format),
                         size.width(),
                         size.height(),
                         0,
                         GLDataFormat(format),
                         GLDataType(format),
                         NULL));
    }
  }
}

void ResourceProvider::BindImageForSampling(Resource* resource) {
  GLES2Interface* gl = ContextGL();
  DCHECK(resource->gl_id);
  DCHECK(resource->image_id);

  // Release image currently bound to texture.
  if (resource->bound_image_id)
    gl->ReleaseTexImage2DCHROMIUM(resource->target, resource->bound_image_id);
  gl->BindTexImage2DCHROMIUM(resource->target, resource->image_id);
  resource->bound_image_id = resource->image_id;
  resource->dirty_image = false;
}

void ResourceProvider::CopyResource(ResourceId source_id, ResourceId dest_id) {
  TRACE_EVENT0("cc", "ResourceProvider::CopyResource");

  Resource* source_resource = GetResource(source_id);
  DCHECK(!source_resource->lock_for_read_count);
  DCHECK(source_resource->origin == Resource::Internal);
  DCHECK_EQ(source_resource->exported_count, 0);
  DCHECK_EQ(GLTexture, source_resource->type);
  DCHECK(source_resource->allocated);
  LazyCreate(source_resource);

  Resource* dest_resource = GetResource(dest_id);
  DCHECK(!dest_resource->locked_for_write);
  DCHECK(!dest_resource->lock_for_read_count);
  DCHECK(dest_resource->origin == Resource::Internal);
  DCHECK_EQ(dest_resource->exported_count, 0);
  DCHECK_EQ(GLTexture, dest_resource->type);
  LazyCreate(dest_resource);

  DCHECK_EQ(source_resource->type, dest_resource->type);
  DCHECK_EQ(source_resource->format, dest_resource->format);
  DCHECK(source_resource->size == dest_resource->size);

  GLES2Interface* gl = ContextGL();
  DCHECK(gl);
  if (source_resource->image_id && source_resource->dirty_image) {
    gl->BindTexture(source_resource->target, source_resource->gl_id);
    BindImageForSampling(source_resource);
  }
  if (use_sync_query_) {
    if (!source_resource->gl_read_lock_query_id)
      gl->GenQueriesEXT(1, &source_resource->gl_read_lock_query_id);
    gl->BeginQueryEXT(GL_COMMANDS_COMPLETED_CHROMIUM,
                      source_resource->gl_read_lock_query_id);
  }
  DCHECK(!dest_resource->image_id);
  dest_resource->allocated = true;
  gl->CopyTextureCHROMIUM(dest_resource->target,
                          source_resource->gl_id,
                          dest_resource->gl_id,
                          0,
                          GLInternalFormat(dest_resource->format),
                          GLDataType(dest_resource->format));
  if (source_resource->gl_read_lock_query_id) {
    // End query and create a read lock fence that will prevent access to
    // source resource until CopyTextureCHROMIUM command has completed.
    gl->EndQueryEXT(GL_COMMANDS_COMPLETED_CHROMIUM);
    source_resource->read_lock_fence = make_scoped_refptr(
        new CopyTextureFence(gl, source_resource->gl_read_lock_query_id));
  } else {
    // Create a SynchronousFence when CHROMIUM_sync_query extension is missing.
    // Try to use one synchronous fence for as many CopyResource operations as
    // possible as that reduce the number of times we have to synchronize with
    // the GL.
    if (!synchronous_fence_.get() || synchronous_fence_->has_synchronized())
      synchronous_fence_ = make_scoped_refptr(new SynchronousFence(gl));
    source_resource->read_lock_fence = synchronous_fence_;
    source_resource->read_lock_fence->Set();
  }
}

void ResourceProvider::WaitSyncPointIfNeeded(ResourceId id) {
  Resource* resource = GetResource(id);
  DCHECK_EQ(resource->exported_count, 0);
  DCHECK(resource->allocated);
  if (resource->type != GLTexture || resource->gl_id)
    return;
  if (!resource->mailbox.sync_point())
    return;
  DCHECK(resource->mailbox.IsValid());
  GLES2Interface* gl = ContextGL();
  DCHECK(gl);
  GLC(gl, gl->WaitSyncPointCHROMIUM(resource->mailbox.sync_point()));
  resource->mailbox.set_sync_point(0);
}

void ResourceProvider::WaitReadLockIfNeeded(ResourceId id) {
  Resource* resource = GetResource(id);
  DCHECK_EQ(resource->exported_count, 0);
  if (!resource->read_lock_fence.get())
    return;

  resource->read_lock_fence->Wait();
}

GLint ResourceProvider::GetActiveTextureUnit(GLES2Interface* gl) {
  GLint active_unit = 0;
  gl->GetIntegerv(GL_ACTIVE_TEXTURE, &active_unit);
  return active_unit;
}

GLES2Interface* ResourceProvider::ContextGL() const {
  ContextProvider* context_provider = output_surface_->context_provider();
  return context_provider ? context_provider->ContextGL() : NULL;
}

class GrContext* ResourceProvider::GrContext() const {
  ContextProvider* context_provider = output_surface_->context_provider();
  return context_provider ? context_provider->GrContext() : NULL;
}

}  // namespace cc
