// 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 <map>
#include <set>

#include "base/bind.h"
#include "base/containers/hash_tables.h"
#include "base/logging.h"
#include "base/memory/ref_counted.h"
#include "cc/base/blocking_task_runner.h"
#include "cc/base/scoped_ptr_deque.h"
#include "cc/output/output_surface.h"
#include "cc/resources/returned_resource.h"
#include "cc/resources/shared_bitmap_manager.h"
#include "cc/resources/single_release_callback.h"
#include "cc/test/fake_output_surface.h"
#include "cc/test/fake_output_surface_client.h"
#include "cc/test/test_gpu_memory_buffer_manager.h"
#include "cc/test/test_shared_bitmap_manager.h"
#include "cc/test/test_texture.h"
#include "cc/test/test_web_graphics_context_3d.h"
#include "gpu/GLES2/gl2extchromium.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/khronos/GLES2/gl2.h"
#include "third_party/khronos/GLES2/gl2ext.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/gpu_memory_buffer.h"

using testing::Mock;
using testing::NiceMock;
using testing::Return;
using testing::SetArgPointee;
using testing::StrictMock;
using testing::_;

namespace cc {
namespace {

static void EmptyReleaseCallback(uint32 sync_point,
                                 bool lost_resource,
                                 BlockingTaskRunner* main_thread_task_runner) {
}

static void ReleaseCallback(
    uint32* release_sync_point,
    bool* release_lost_resource,
    BlockingTaskRunner** release_main_thread_task_runner,
    uint32 sync_point,
    bool lost_resource,
    BlockingTaskRunner* main_thread_task_runner) {
  *release_sync_point = sync_point;
  *release_lost_resource = lost_resource;
  *release_main_thread_task_runner = main_thread_task_runner;
}

static void SharedBitmapReleaseCallback(
    scoped_ptr<SharedBitmap> bitmap,
    uint32 sync_point,
    bool lost_resource,
    BlockingTaskRunner* main_thread_task_runner) {
}

static void ReleaseSharedBitmapCallback(
    scoped_ptr<SharedBitmap> shared_bitmap,
    bool* release_called,
    uint32* release_sync_point,
    bool* lost_resource_result,
    uint32 sync_point,
    bool lost_resource,
    BlockingTaskRunner* main_thread_task_runner) {
  *release_called = true;
  *release_sync_point = sync_point;
  *lost_resource_result = lost_resource;
}

static scoped_ptr<SharedBitmap> CreateAndFillSharedBitmap(
    SharedBitmapManager* manager,
    const gfx::Size& size,
    uint32_t value) {
  scoped_ptr<SharedBitmap> shared_bitmap = manager->AllocateSharedBitmap(size);
  CHECK(shared_bitmap);
  uint32_t* pixels = reinterpret_cast<uint32_t*>(shared_bitmap->pixels());
  CHECK(pixels);
  std::fill_n(pixels, size.GetArea(), value);
  return shared_bitmap.Pass();
}

class TextureStateTrackingContext : public TestWebGraphicsContext3D {
 public:
  MOCK_METHOD2(bindTexture, void(GLenum target, GLuint texture));
  MOCK_METHOD3(texParameteri, void(GLenum target, GLenum pname, GLint param));
  MOCK_METHOD1(waitSyncPoint, void(GLuint sync_point));
  MOCK_METHOD0(insertSyncPoint, GLuint(void));
  MOCK_METHOD3(produceTextureDirectCHROMIUM,
               void(GLuint texture, GLenum target, const GLbyte* mailbox));
  MOCK_METHOD2(createAndConsumeTextureCHROMIUM,
               unsigned(GLenum target, const GLbyte* mailbox));

  // Force all textures to be consecutive numbers starting at "1",
  // so we easily can test for them.
  GLuint NextTextureId() override {
    base::AutoLock lock(namespace_->lock);
    return namespace_->next_texture_id++;
  }
  void RetireTextureId(GLuint) override {}
};

// Shared data between multiple ResourceProviderContext. This contains mailbox
// contents as well as information about sync points.
class ContextSharedData {
 public:
  static scoped_ptr<ContextSharedData> Create() {
    return make_scoped_ptr(new ContextSharedData());
  }

  uint32 InsertSyncPoint() { return next_sync_point_++; }

  void GenMailbox(GLbyte* mailbox) {
    memset(mailbox, 0, GL_MAILBOX_SIZE_CHROMIUM);
    memcpy(mailbox, &next_mailbox_, sizeof(next_mailbox_));
    ++next_mailbox_;
  }

  void ProduceTexture(const GLbyte* mailbox_name,
                      uint32 sync_point,
                      scoped_refptr<TestTexture> texture) {
    unsigned mailbox = 0;
    memcpy(&mailbox, mailbox_name, sizeof(mailbox));
    ASSERT_TRUE(mailbox && mailbox < next_mailbox_);
    textures_[mailbox] = texture;
    ASSERT_LT(sync_point_for_mailbox_[mailbox], sync_point);
    sync_point_for_mailbox_[mailbox] = sync_point;
  }

  scoped_refptr<TestTexture> ConsumeTexture(const GLbyte* mailbox_name,
                                            uint32 sync_point) {
    unsigned mailbox = 0;
    memcpy(&mailbox, mailbox_name, sizeof(mailbox));
    DCHECK(mailbox && mailbox < next_mailbox_);

    // If the latest sync point the context has waited on is before the sync
    // point for when the mailbox was set, pretend we never saw that
    // ProduceTexture.
    if (sync_point_for_mailbox_[mailbox] > sync_point) {
      NOTREACHED();
      return scoped_refptr<TestTexture>();
    }
    return textures_[mailbox];
  }

 private:
  ContextSharedData() : next_sync_point_(1), next_mailbox_(1) {}

  uint32 next_sync_point_;
  unsigned next_mailbox_;
  typedef base::hash_map<unsigned, scoped_refptr<TestTexture>> TextureMap;
  TextureMap textures_;
  base::hash_map<unsigned, uint32> sync_point_for_mailbox_;
};

class ResourceProviderContext : public TestWebGraphicsContext3D {
 public:
  static scoped_ptr<ResourceProviderContext> Create(
      ContextSharedData* shared_data) {
    return make_scoped_ptr(new ResourceProviderContext(shared_data));
  }

  GLuint insertSyncPoint() override {
    uint32 sync_point = shared_data_->InsertSyncPoint();
    // Commit the produceTextureCHROMIUM calls at this point, so that
    // they're associated with the sync point.
    for (PendingProduceTextureList::iterator it =
             pending_produce_textures_.begin();
         it != pending_produce_textures_.end();
         ++it) {
      shared_data_->ProduceTexture(
          (*it)->mailbox, sync_point, (*it)->texture);
    }
    pending_produce_textures_.clear();
    return sync_point;
  }

  void waitSyncPoint(GLuint sync_point) override {
    last_waited_sync_point_ = std::max(sync_point, last_waited_sync_point_);
  }

  unsigned last_waited_sync_point() const { return last_waited_sync_point_; }

  void texStorage2DEXT(GLenum target,
                       GLint levels,
                       GLuint internalformat,
                       GLint width,
                       GLint height) override {
    CheckTextureIsBound(target);
    ASSERT_EQ(static_cast<unsigned>(GL_TEXTURE_2D), target);
    ASSERT_EQ(1, levels);
    GLenum format = GL_RGBA;
    switch (internalformat) {
      case GL_RGBA8_OES:
        break;
      case GL_BGRA8_EXT:
        format = GL_BGRA_EXT;
        break;
      default:
        NOTREACHED();
    }
    AllocateTexture(gfx::Size(width, height), format);
  }

  void texImage2D(GLenum target,
                  GLint level,
                  GLenum internalformat,
                  GLsizei width,
                  GLsizei height,
                  GLint border,
                  GLenum format,
                  GLenum type,
                  const void* pixels) override {
    CheckTextureIsBound(target);
    ASSERT_EQ(static_cast<unsigned>(GL_TEXTURE_2D), target);
    ASSERT_FALSE(level);
    ASSERT_EQ(internalformat, format);
    ASSERT_FALSE(border);
    ASSERT_EQ(static_cast<unsigned>(GL_UNSIGNED_BYTE), type);
    AllocateTexture(gfx::Size(width, height), format);
    if (pixels)
      SetPixels(0, 0, width, height, pixels);
  }

  void texSubImage2D(GLenum target,
                     GLint level,
                     GLint xoffset,
                     GLint yoffset,
                     GLsizei width,
                     GLsizei height,
                     GLenum format,
                     GLenum type,
                     const void* pixels) override {
    CheckTextureIsBound(target);
    ASSERT_EQ(static_cast<unsigned>(GL_TEXTURE_2D), target);
    ASSERT_FALSE(level);
    ASSERT_EQ(static_cast<unsigned>(GL_UNSIGNED_BYTE), type);
    {
      base::AutoLock lock_for_texture_access(namespace_->lock);
      ASSERT_EQ(GLDataFormat(BoundTexture(target)->format), format);
    }
    ASSERT_TRUE(pixels);
    SetPixels(xoffset, yoffset, width, height, pixels);
  }

  void genMailboxCHROMIUM(GLbyte* mailbox) override {
    return shared_data_->GenMailbox(mailbox);
  }

  void produceTextureDirectCHROMIUM(GLuint texture,
                                    GLenum target,
                                    const GLbyte* mailbox) override {
    // Delay moving the texture into the mailbox until the next
    // InsertSyncPoint, so that it is not visible to other contexts that
    // haven't waited on that sync point.
    scoped_ptr<PendingProduceTexture> pending(new PendingProduceTexture);
    memcpy(pending->mailbox, mailbox, sizeof(pending->mailbox));
    base::AutoLock lock_for_texture_access(namespace_->lock);
    pending->texture = UnboundTexture(texture);
    pending_produce_textures_.push_back(pending.Pass());
  }

  GLuint createAndConsumeTextureCHROMIUM(GLenum target,
                                         const GLbyte* mailbox) override {
    GLuint texture_id = createTexture();
    base::AutoLock lock_for_texture_access(namespace_->lock);
    scoped_refptr<TestTexture> texture =
        shared_data_->ConsumeTexture(mailbox, last_waited_sync_point_);
    namespace_->textures.Replace(texture_id, texture);
    return texture_id;
  }

  void GetPixels(const gfx::Size& size,
                 ResourceFormat format,
                 uint8_t* pixels) {
    CheckTextureIsBound(GL_TEXTURE_2D);
    base::AutoLock lock_for_texture_access(namespace_->lock);
    scoped_refptr<TestTexture> texture = BoundTexture(GL_TEXTURE_2D);
    ASSERT_EQ(texture->size, size);
    ASSERT_EQ(texture->format, format);
    memcpy(pixels, texture->data.get(), TextureSizeBytes(size, format));
  }

 protected:
  explicit ResourceProviderContext(ContextSharedData* shared_data)
      : shared_data_(shared_data),
        last_waited_sync_point_(0) {}

 private:
  void AllocateTexture(const gfx::Size& size, GLenum format) {
    CheckTextureIsBound(GL_TEXTURE_2D);
    ResourceFormat texture_format = RGBA_8888;
    switch (format) {
      case GL_RGBA:
        texture_format = RGBA_8888;
        break;
      case GL_BGRA_EXT:
        texture_format = BGRA_8888;
        break;
    }
    base::AutoLock lock_for_texture_access(namespace_->lock);
    BoundTexture(GL_TEXTURE_2D)->Reallocate(size, texture_format);
  }

  void SetPixels(int xoffset,
                 int yoffset,
                 int width,
                 int height,
                 const void* pixels) {
    CheckTextureIsBound(GL_TEXTURE_2D);
    base::AutoLock lock_for_texture_access(namespace_->lock);
    scoped_refptr<TestTexture> texture = BoundTexture(GL_TEXTURE_2D);
    ASSERT_TRUE(texture->data.get());
    ASSERT_TRUE(xoffset >= 0 && xoffset + width <= texture->size.width());
    ASSERT_TRUE(yoffset >= 0 && yoffset + height <= texture->size.height());
    ASSERT_TRUE(pixels);
    size_t in_pitch = TextureSizeBytes(gfx::Size(width, 1), texture->format);
    size_t out_pitch =
        TextureSizeBytes(gfx::Size(texture->size.width(), 1), texture->format);
    uint8_t* dest = texture->data.get() + yoffset * out_pitch +
                    TextureSizeBytes(gfx::Size(xoffset, 1), texture->format);
    const uint8_t* src = static_cast<const uint8_t*>(pixels);
    for (int i = 0; i < height; ++i) {
      memcpy(dest, src, in_pitch);
      dest += out_pitch;
      src += in_pitch;
    }
  }

  struct PendingProduceTexture {
    GLbyte mailbox[GL_MAILBOX_SIZE_CHROMIUM];
    scoped_refptr<TestTexture> texture;
  };
  typedef ScopedPtrDeque<PendingProduceTexture> PendingProduceTextureList;
  ContextSharedData* shared_data_;
  GLuint last_waited_sync_point_;
  PendingProduceTextureList pending_produce_textures_;
};

void GetResourcePixels(ResourceProvider* resource_provider,
                       ResourceProviderContext* context,
                       ResourceProvider::ResourceId id,
                       const gfx::Size& size,
                       ResourceFormat format,
                       uint8_t* pixels) {
  resource_provider->WaitSyncPointIfNeeded(id);
  switch (resource_provider->default_resource_type()) {
    case ResourceProvider::RESOURCE_TYPE_GL_TEXTURE: {
      ResourceProvider::ScopedReadLockGL lock_gl(resource_provider, id);
      ASSERT_NE(0U, lock_gl.texture_id());
      context->bindTexture(GL_TEXTURE_2D, lock_gl.texture_id());
      context->GetPixels(size, format, pixels);
      break;
    }
    case ResourceProvider::RESOURCE_TYPE_BITMAP: {
      ResourceProvider::ScopedReadLockSoftware lock_software(resource_provider,
                                                             id);
      memcpy(pixels,
             lock_software.sk_bitmap()->getPixels(),
             lock_software.sk_bitmap()->getSize());
      break;
    }
    case ResourceProvider::RESOURCE_TYPE_INVALID:
      NOTREACHED();
      break;
  }
}

class ResourceProviderTest
    : public testing::TestWithParam<ResourceProvider::ResourceType> {
 public:
  ResourceProviderTest()
      : shared_data_(ContextSharedData::Create()),
        context3d_(NULL),
        child_context_(NULL),
        main_thread_task_runner_(BlockingTaskRunner::Create(NULL)) {
    switch (GetParam()) {
      case ResourceProvider::RESOURCE_TYPE_GL_TEXTURE: {
        scoped_ptr<ResourceProviderContext> context3d(
            ResourceProviderContext::Create(shared_data_.get()));
        context3d_ = context3d.get();

        scoped_refptr<TestContextProvider> context_provider =
            TestContextProvider::Create(context3d.Pass());

        output_surface_ = FakeOutputSurface::Create3d(context_provider);

        scoped_ptr<ResourceProviderContext> child_context_owned =
            ResourceProviderContext::Create(shared_data_.get());
        child_context_ = child_context_owned.get();
        child_output_surface_ =
            FakeOutputSurface::Create3d(child_context_owned.Pass());
        break;
      }
      case ResourceProvider::RESOURCE_TYPE_BITMAP:
        output_surface_ = FakeOutputSurface::CreateSoftware(
            make_scoped_ptr(new SoftwareOutputDevice));
        child_output_surface_ = FakeOutputSurface::CreateSoftware(
            make_scoped_ptr(new SoftwareOutputDevice));
        break;
      case ResourceProvider::RESOURCE_TYPE_INVALID:
        NOTREACHED();
        break;
    }
    CHECK(output_surface_->BindToClient(&output_surface_client_));
    CHECK(child_output_surface_->BindToClient(&child_output_surface_client_));

    shared_bitmap_manager_.reset(new TestSharedBitmapManager);
    gpu_memory_buffer_manager_.reset(new TestGpuMemoryBufferManager);

    resource_provider_ =
        ResourceProvider::Create(output_surface_.get(),
                                 shared_bitmap_manager_.get(),
                                 gpu_memory_buffer_manager_.get(),
                                 main_thread_task_runner_.get(),
                                 0,
                                 false,
                                 1);
    child_resource_provider_ =
        ResourceProvider::Create(child_output_surface_.get(),
                                 shared_bitmap_manager_.get(),
                                 gpu_memory_buffer_manager_.get(),
                                 main_thread_task_runner_.get(),
                                 0,
                                 false,
                                 1);
  }

  static void CollectResources(ReturnedResourceArray* array,
                               const ReturnedResourceArray& returned,
                               BlockingTaskRunner* main_thread_task_runner) {
    array->insert(array->end(), returned.begin(), returned.end());
  }

  static ReturnCallback GetReturnCallback(ReturnedResourceArray* array) {
    return base::Bind(&ResourceProviderTest::CollectResources, array);
  }

  static void SetResourceFilter(ResourceProvider* resource_provider,
                                ResourceProvider::ResourceId id,
                                GLenum filter) {
    ResourceProvider::ScopedSamplerGL sampler(
        resource_provider, id, GL_TEXTURE_2D, filter);
  }

  ResourceProviderContext* context() { return context3d_; }

  ResourceProvider::ResourceId CreateChildMailbox(uint32* release_sync_point,
                                                  bool* lost_resource,
                                                  bool* release_called,
                                                  uint32* sync_point) {
    if (GetParam() == ResourceProvider::RESOURCE_TYPE_GL_TEXTURE) {
      unsigned texture = child_context_->createTexture();
      gpu::Mailbox gpu_mailbox;
      child_context_->genMailboxCHROMIUM(gpu_mailbox.name);
      child_context_->produceTextureDirectCHROMIUM(texture, GL_TEXTURE_2D,
                                                   gpu_mailbox.name);
      *sync_point = child_context_->insertSyncPoint();
      EXPECT_LT(0u, *sync_point);

      scoped_ptr<SharedBitmap> shared_bitmap;
      scoped_ptr<SingleReleaseCallbackImpl> callback =
          SingleReleaseCallbackImpl::Create(base::Bind(
              ReleaseSharedBitmapCallback, base::Passed(&shared_bitmap),
              release_called, release_sync_point, lost_resource));
      return child_resource_provider_->CreateResourceFromTextureMailbox(
          TextureMailbox(gpu_mailbox, GL_TEXTURE_2D, *sync_point),
          callback.Pass());
    } else {
      gfx::Size size(64, 64);
      scoped_ptr<SharedBitmap> shared_bitmap(
          CreateAndFillSharedBitmap(shared_bitmap_manager_.get(), size, 0));

      SharedBitmap* shared_bitmap_ptr = shared_bitmap.get();
      scoped_ptr<SingleReleaseCallbackImpl> callback =
          SingleReleaseCallbackImpl::Create(base::Bind(
              ReleaseSharedBitmapCallback, base::Passed(&shared_bitmap),
              release_called, release_sync_point, lost_resource));
      return child_resource_provider_->CreateResourceFromTextureMailbox(
          TextureMailbox(shared_bitmap_ptr, size), callback.Pass());
    }
  }

 protected:
  scoped_ptr<ContextSharedData> shared_data_;
  ResourceProviderContext* context3d_;
  ResourceProviderContext* child_context_;
  FakeOutputSurfaceClient output_surface_client_;
  FakeOutputSurfaceClient child_output_surface_client_;
  scoped_ptr<OutputSurface> output_surface_;
  scoped_ptr<OutputSurface> child_output_surface_;
  scoped_ptr<BlockingTaskRunner> main_thread_task_runner_;
  scoped_ptr<ResourceProvider> resource_provider_;
  scoped_ptr<ResourceProvider> child_resource_provider_;
  scoped_ptr<TestSharedBitmapManager> shared_bitmap_manager_;
  scoped_ptr<TestGpuMemoryBufferManager> gpu_memory_buffer_manager_;
};

void CheckCreateResource(ResourceProvider::ResourceType expected_default_type,
                         ResourceProvider* resource_provider,
                         ResourceProviderContext* context) {
  DCHECK_EQ(expected_default_type, resource_provider->default_resource_type());

  gfx::Size size(1, 1);
  ResourceFormat format = RGBA_8888;
  size_t pixel_size = TextureSizeBytes(size, format);
  ASSERT_EQ(4U, pixel_size);

  ResourceProvider::ResourceId id = resource_provider->CreateResource(
      size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);
  EXPECT_EQ(1, static_cast<int>(resource_provider->num_resources()));
  if (expected_default_type == ResourceProvider::RESOURCE_TYPE_GL_TEXTURE)
    EXPECT_EQ(0u, context->NumTextures());

  uint8_t data[4] = { 1, 2, 3, 4 };
  resource_provider->CopyToResource(id, data, size);
  if (expected_default_type == ResourceProvider::RESOURCE_TYPE_GL_TEXTURE)
    EXPECT_EQ(1u, context->NumTextures());

  uint8_t result[4] = { 0 };
  GetResourcePixels(resource_provider, context, id, size, format, result);
  EXPECT_EQ(0, memcmp(data, result, pixel_size));

  resource_provider->DeleteResource(id);
  EXPECT_EQ(0, static_cast<int>(resource_provider->num_resources()));
  if (expected_default_type == ResourceProvider::RESOURCE_TYPE_GL_TEXTURE)
    EXPECT_EQ(0u, context->NumTextures());
}

TEST_P(ResourceProviderTest, Basic) {
  CheckCreateResource(GetParam(), resource_provider_.get(), context());
}

TEST_P(ResourceProviderTest, Upload) {
  gfx::Size size(2, 2);
  ResourceFormat format = RGBA_8888;
  size_t pixel_size = TextureSizeBytes(size, format);
  ASSERT_EQ(16U, pixel_size);

  ResourceProvider::ResourceId id = resource_provider_->CreateResource(
      size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);

  uint8_t image[16] = { 0 };
  gfx::Rect image_rect(size);
  resource_provider_->SetPixels(
      id, image, image_rect, image_rect, gfx::Vector2d());

  for (uint8_t i = 0; i < pixel_size; ++i)
    image[i] = i;

  uint8_t result[16] = { 0 };
  {
    gfx::Rect source_rect(0, 0, 1, 1);
    gfx::Vector2d dest_offset(0, 0);
    resource_provider_->SetPixels(
        id, image, image_rect, source_rect, dest_offset);

    uint8_t expected[16] = { 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
    GetResourcePixels(
        resource_provider_.get(), context(), id, size, format, result);
    EXPECT_EQ(0, memcmp(expected, result, pixel_size));
  }
  {
    gfx::Rect source_rect(0, 0, 1, 1);
    gfx::Vector2d dest_offset(1, 1);
    resource_provider_->SetPixels(
        id, image, image_rect, source_rect, dest_offset);

    uint8_t expected[16] = { 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3 };
    GetResourcePixels(
        resource_provider_.get(), context(), id, size, format, result);
    EXPECT_EQ(0, memcmp(expected, result, pixel_size));
  }
  {
    gfx::Rect source_rect(1, 0, 1, 1);
    gfx::Vector2d dest_offset(0, 1);
    resource_provider_->SetPixels(
        id, image, image_rect, source_rect, dest_offset);

    uint8_t expected[16] = { 0, 1, 2, 3, 0, 0, 0, 0, 4, 5, 6, 7, 0, 1, 2, 3 };
    GetResourcePixels(
        resource_provider_.get(), context(), id, size, format, result);
    EXPECT_EQ(0, memcmp(expected, result, pixel_size));
  }
  {
    gfx::Rect offset_image_rect(gfx::Point(100, 100), size);
    gfx::Rect source_rect(100, 100, 1, 1);
    gfx::Vector2d dest_offset(1, 0);
    resource_provider_->SetPixels(
        id, image, offset_image_rect, source_rect, dest_offset);

    uint8_t expected[16] = { 0, 1, 2, 3, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3 };
    GetResourcePixels(
        resource_provider_.get(), context(), id, size, format, result);
    EXPECT_EQ(0, memcmp(expected, result, pixel_size));
  }

  resource_provider_->DeleteResource(id);
}

TEST_P(ResourceProviderTest, SimpleUpload) {
  gfx::Size size(2, 2);
  ResourceFormat format = RGBA_8888;
  size_t pixel_size = TextureSizeBytes(size, format);
  ASSERT_EQ(16U, pixel_size);

  ResourceProvider::ResourceId id = resource_provider_->CreateResource(
      size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);

  uint8_t image[16] = {0};
  resource_provider_->CopyToResource(id, image, size);
  {
    uint8_t result[16] = {0};
    uint8_t expected[16] = {0};
    GetResourcePixels(resource_provider_.get(), context(), id, size, format,
                      result);
    EXPECT_EQ(0, memcmp(expected, result, pixel_size));
  }

  for (uint8_t i = 0; i < pixel_size; ++i)
    image[i] = i;
  resource_provider_->CopyToResource(id, image, size);
  {
    uint8_t result[16] = {0};
    uint8_t expected[16] = {
        0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
    GetResourcePixels(resource_provider_.get(), context(), id, size, format,
                      result);
    EXPECT_EQ(0, memcmp(expected, result, pixel_size));
  }
}

TEST_P(ResourceProviderTest, TransferGLResources) {
  if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE)
    return;
  gfx::Size size(1, 1);
  ResourceFormat format = RGBA_8888;
  size_t pixel_size = TextureSizeBytes(size, format);
  ASSERT_EQ(4U, pixel_size);

  ResourceProvider::ResourceId id1 = child_resource_provider_->CreateResource(
      size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);
  uint8_t data1[4] = { 1, 2, 3, 4 };
  child_resource_provider_->CopyToResource(id1, data1, size);

  ResourceProvider::ResourceId id2 = child_resource_provider_->CreateResource(
      size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);
  uint8_t data2[4] = { 5, 5, 5, 5 };
  child_resource_provider_->CopyToResource(id2, data2, size);

  ResourceProvider::ResourceId id3 = child_resource_provider_->CreateResource(
      size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);
  {
    ResourceProvider::ScopedWriteLockGpuMemoryBuffer lock(
        child_resource_provider_.get(), id3);
    EXPECT_TRUE(!!lock.GetGpuMemoryBuffer());
  }

  GLuint external_texture_id = child_context_->createExternalTexture();

  gpu::Mailbox external_mailbox;
  child_context_->genMailboxCHROMIUM(external_mailbox.name);
  child_context_->produceTextureDirectCHROMIUM(
      external_texture_id, GL_TEXTURE_EXTERNAL_OES, external_mailbox.name);
  const GLuint external_sync_point = child_context_->insertSyncPoint();
  ResourceProvider::ResourceId id4 =
      child_resource_provider_->CreateResourceFromTextureMailbox(
          TextureMailbox(
              external_mailbox, GL_TEXTURE_EXTERNAL_OES, external_sync_point),
          SingleReleaseCallbackImpl::Create(base::Bind(&EmptyReleaseCallback)));

  ReturnedResourceArray returned_to_child;
  int child_id =
      resource_provider_->CreateChild(GetReturnCallback(&returned_to_child));
  {
    // Transfer some resources to the parent.
    ResourceProvider::ResourceIdArray resource_ids_to_transfer;
    resource_ids_to_transfer.push_back(id1);
    resource_ids_to_transfer.push_back(id2);
    resource_ids_to_transfer.push_back(id3);
    resource_ids_to_transfer.push_back(id4);
    TransferableResourceArray list;
    child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
                                                  &list);
    ASSERT_EQ(4u, list.size());
    EXPECT_NE(0u, list[0].mailbox_holder.sync_point);
    EXPECT_NE(0u, list[1].mailbox_holder.sync_point);
    EXPECT_EQ(list[0].mailbox_holder.sync_point,
              list[1].mailbox_holder.sync_point);
    EXPECT_NE(0u, list[2].mailbox_holder.sync_point);
    EXPECT_EQ(list[0].mailbox_holder.sync_point,
              list[2].mailbox_holder.sync_point);
    EXPECT_EQ(external_sync_point, list[3].mailbox_holder.sync_point);
    EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_2D),
              list[0].mailbox_holder.texture_target);
    EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_2D),
              list[1].mailbox_holder.texture_target);
    EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_2D),
              list[2].mailbox_holder.texture_target);
    EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_EXTERNAL_OES),
              list[3].mailbox_holder.texture_target);
    EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id1));
    EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id2));
    EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id3));
    EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id4));
    resource_provider_->ReceiveFromChild(child_id, list);
    EXPECT_NE(list[0].mailbox_holder.sync_point,
              context3d_->last_waited_sync_point());
    {
      resource_provider_->WaitSyncPointIfNeeded(list[0].id);
      ResourceProvider::ScopedReadLockGL lock(resource_provider_.get(),
                                              list[0].id);
    }
    EXPECT_EQ(list[0].mailbox_holder.sync_point,
              context3d_->last_waited_sync_point());
    resource_provider_->DeclareUsedResourcesFromChild(child_id,
                                                      resource_ids_to_transfer);
  }

  EXPECT_EQ(4u, resource_provider_->num_resources());
  ResourceProvider::ResourceIdMap resource_map =
      resource_provider_->GetChildToParentMap(child_id);
  ResourceProvider::ResourceId mapped_id1 = resource_map[id1];
  ResourceProvider::ResourceId mapped_id2 = resource_map[id2];
  ResourceProvider::ResourceId mapped_id3 = resource_map[id3];
  ResourceProvider::ResourceId mapped_id4 = resource_map[id4];
  EXPECT_NE(0u, mapped_id1);
  EXPECT_NE(0u, mapped_id2);
  EXPECT_NE(0u, mapped_id3);
  EXPECT_NE(0u, mapped_id4);
  EXPECT_FALSE(resource_provider_->InUseByConsumer(id1));
  EXPECT_FALSE(resource_provider_->InUseByConsumer(id2));
  EXPECT_FALSE(resource_provider_->InUseByConsumer(id3));
  EXPECT_FALSE(resource_provider_->InUseByConsumer(id4));

  uint8_t result[4] = { 0 };
  GetResourcePixels(
      resource_provider_.get(), context(), mapped_id1, size, format, result);
  EXPECT_EQ(0, memcmp(data1, result, pixel_size));

  GetResourcePixels(
      resource_provider_.get(), context(), mapped_id2, size, format, result);
  EXPECT_EQ(0, memcmp(data2, result, pixel_size));

  {
    // Check that transfering again the same resource from the child to the
    // parent works.
    ResourceProvider::ResourceIdArray resource_ids_to_transfer;
    resource_ids_to_transfer.push_back(id1);
    resource_ids_to_transfer.push_back(id2);
    resource_ids_to_transfer.push_back(id3);
    TransferableResourceArray list;
    child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
                                                  &list);
    EXPECT_EQ(3u, list.size());
    EXPECT_EQ(id1, list[0].id);
    EXPECT_EQ(id2, list[1].id);
    EXPECT_EQ(id3, list[2].id);
    EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_2D),
              list[0].mailbox_holder.texture_target);
    EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_2D),
              list[1].mailbox_holder.texture_target);
    EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_2D),
              list[2].mailbox_holder.texture_target);
    ReturnedResourceArray returned;
    TransferableResource::ReturnResources(list, &returned);
    child_resource_provider_->ReceiveReturnsFromParent(returned);
    // ids were exported twice, we returned them only once, they should still
    // be in-use.
    EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id1));
    EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id2));
    EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id3));
  }
  {
    EXPECT_EQ(0u, returned_to_child.size());

    // Transfer resources back from the parent to the child. Set no resources as
    // being in use.
    ResourceProvider::ResourceIdArray no_resources;
    resource_provider_->DeclareUsedResourcesFromChild(child_id, no_resources);

    ASSERT_EQ(4u, returned_to_child.size());
    EXPECT_NE(0u, returned_to_child[0].sync_point);
    EXPECT_NE(0u, returned_to_child[1].sync_point);
    EXPECT_NE(0u, returned_to_child[2].sync_point);
    EXPECT_NE(0u, returned_to_child[3].sync_point);
    EXPECT_FALSE(returned_to_child[0].lost);
    EXPECT_FALSE(returned_to_child[1].lost);
    EXPECT_FALSE(returned_to_child[2].lost);
    EXPECT_FALSE(returned_to_child[3].lost);
    child_resource_provider_->ReceiveReturnsFromParent(returned_to_child);
    returned_to_child.clear();
  }
  EXPECT_FALSE(child_resource_provider_->InUseByConsumer(id1));
  EXPECT_FALSE(child_resource_provider_->InUseByConsumer(id2));
  EXPECT_FALSE(child_resource_provider_->InUseByConsumer(id3));
  EXPECT_FALSE(child_resource_provider_->InUseByConsumer(id4));

  {
    child_resource_provider_->WaitSyncPointIfNeeded(id1);
    ResourceProvider::ScopedReadLockGL lock(child_resource_provider_.get(),
                                            id1);
    ASSERT_NE(0U, lock.texture_id());
    child_context_->bindTexture(GL_TEXTURE_2D, lock.texture_id());
    child_context_->GetPixels(size, format, result);
    EXPECT_EQ(0, memcmp(data1, result, pixel_size));
  }
  {
    child_resource_provider_->WaitSyncPointIfNeeded(id2);
    ResourceProvider::ScopedReadLockGL lock(child_resource_provider_.get(),
                                            id2);
    ASSERT_NE(0U, lock.texture_id());
    child_context_->bindTexture(GL_TEXTURE_2D, lock.texture_id());
    child_context_->GetPixels(size, format, result);
    EXPECT_EQ(0, memcmp(data2, result, pixel_size));
  }
  {
    child_resource_provider_->WaitSyncPointIfNeeded(id3);
    ResourceProvider::ScopedReadLockGL lock(child_resource_provider_.get(),
                                            id3);
    ASSERT_NE(0U, lock.texture_id());
    child_context_->bindTexture(GL_TEXTURE_2D, lock.texture_id());
  }
  {
    // Transfer resources to the parent again.
    ResourceProvider::ResourceIdArray resource_ids_to_transfer;
    resource_ids_to_transfer.push_back(id1);
    resource_ids_to_transfer.push_back(id2);
    resource_ids_to_transfer.push_back(id3);
    resource_ids_to_transfer.push_back(id4);
    TransferableResourceArray list;
    child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
                                                  &list);
    ASSERT_EQ(4u, list.size());
    EXPECT_EQ(id1, list[0].id);
    EXPECT_EQ(id2, list[1].id);
    EXPECT_EQ(id3, list[2].id);
    EXPECT_EQ(id4, list[3].id);
    EXPECT_NE(0u, list[0].mailbox_holder.sync_point);
    EXPECT_NE(0u, list[1].mailbox_holder.sync_point);
    EXPECT_NE(0u, list[2].mailbox_holder.sync_point);
    EXPECT_NE(0u, list[3].mailbox_holder.sync_point);
    EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_2D),
              list[0].mailbox_holder.texture_target);
    EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_2D),
              list[1].mailbox_holder.texture_target);
    EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_2D),
              list[2].mailbox_holder.texture_target);
    EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_EXTERNAL_OES),
              list[3].mailbox_holder.texture_target);
    EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id1));
    EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id2));
    EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id3));
    EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id4));
    resource_provider_->ReceiveFromChild(child_id, list);
    resource_provider_->DeclareUsedResourcesFromChild(child_id,
                                                      resource_ids_to_transfer);
  }

  EXPECT_EQ(0u, returned_to_child.size());

  EXPECT_EQ(4u, resource_provider_->num_resources());
  resource_provider_->DestroyChild(child_id);
  EXPECT_EQ(0u, resource_provider_->num_resources());

  ASSERT_EQ(4u, returned_to_child.size());
  EXPECT_NE(0u, returned_to_child[0].sync_point);
  EXPECT_NE(0u, returned_to_child[1].sync_point);
  EXPECT_NE(0u, returned_to_child[2].sync_point);
  EXPECT_NE(0u, returned_to_child[3].sync_point);
  EXPECT_FALSE(returned_to_child[0].lost);
  EXPECT_FALSE(returned_to_child[1].lost);
  EXPECT_FALSE(returned_to_child[2].lost);
  EXPECT_FALSE(returned_to_child[3].lost);
}

TEST_P(ResourceProviderTest, ReadLockCountStopsReturnToChildOrDelete) {
  if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE)
    return;
  gfx::Size size(1, 1);
  ResourceFormat format = RGBA_8888;

  ResourceProvider::ResourceId id1 = child_resource_provider_->CreateResource(
      size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);
  uint8_t data1[4] = {1, 2, 3, 4};
  child_resource_provider_->CopyToResource(id1, data1, size);

  ReturnedResourceArray returned_to_child;
  int child_id =
      resource_provider_->CreateChild(GetReturnCallback(&returned_to_child));
  {
    // Transfer some resources to the parent.
    ResourceProvider::ResourceIdArray resource_ids_to_transfer;
    resource_ids_to_transfer.push_back(id1);
    TransferableResourceArray list;
    child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
                                                  &list);
    ASSERT_EQ(1u, list.size());
    EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id1));

    resource_provider_->ReceiveFromChild(child_id, list);

    resource_provider_->WaitSyncPointIfNeeded(list[0].id);
    ResourceProvider::ScopedReadLockGL lock(resource_provider_.get(),
                                            list[0].id);

    resource_provider_->DeclareUsedResourcesFromChild(
        child_id, ResourceProvider::ResourceIdArray());
    EXPECT_EQ(0u, returned_to_child.size());
  }

  EXPECT_EQ(1u, returned_to_child.size());
  child_resource_provider_->ReceiveReturnsFromParent(returned_to_child);

  {
    child_resource_provider_->WaitSyncPointIfNeeded(id1);
    ResourceProvider::ScopedReadLockGL lock(child_resource_provider_.get(),
                                            id1);
    child_resource_provider_->DeleteResource(id1);
    EXPECT_EQ(1u, child_resource_provider_->num_resources());
    EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id1));
  }

  EXPECT_EQ(0u, child_resource_provider_->num_resources());
  resource_provider_->DestroyChild(child_id);
}

TEST_P(ResourceProviderTest, AllowOverlayTransfersToParent) {
  // Overlays only supported on the GL path.
  if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE)
    return;

  uint32 sync_point = 0;
  TextureMailbox mailbox(gpu::Mailbox::Generate(), GL_TEXTURE_2D, sync_point);
  mailbox.set_allow_overlay(true);
  scoped_ptr<SingleReleaseCallbackImpl> release_callback =
      SingleReleaseCallbackImpl::Create(base::Bind(&EmptyReleaseCallback));
  ResourceProvider::ResourceId id1 =
      child_resource_provider_->CreateResourceFromTextureMailbox(
          mailbox, release_callback.Pass());

  TextureMailbox mailbox2(gpu::Mailbox::Generate(), GL_TEXTURE_2D, sync_point);
  mailbox2.set_allow_overlay(false);
  scoped_ptr<SingleReleaseCallbackImpl> release_callback2 =
      SingleReleaseCallbackImpl::Create(base::Bind(&EmptyReleaseCallback));
  ResourceProvider::ResourceId id2 =
      child_resource_provider_->CreateResourceFromTextureMailbox(
          mailbox2, release_callback2.Pass());

  ReturnedResourceArray returned_to_child;
  int child_id =
      resource_provider_->CreateChild(GetReturnCallback(&returned_to_child));

  // Transfer some resources to the parent.
  ResourceProvider::ResourceIdArray resource_ids_to_transfer;
  resource_ids_to_transfer.push_back(id1);
  resource_ids_to_transfer.push_back(id2);
  TransferableResourceArray list;
  child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
                                                &list);
  ASSERT_EQ(2u, list.size());
  resource_provider_->ReceiveFromChild(child_id, list);
  EXPECT_TRUE(resource_provider_->AllowOverlay(list[0].id));
  EXPECT_FALSE(resource_provider_->AllowOverlay(list[1].id));

  resource_provider_->DeclareUsedResourcesFromChild(
      child_id, ResourceProvider::ResourceIdArray());

  EXPECT_EQ(2u, returned_to_child.size());
  child_resource_provider_->ReceiveReturnsFromParent(returned_to_child);

  child_resource_provider_->DeleteResource(id1);
  child_resource_provider_->DeleteResource(id2);
  EXPECT_EQ(0u, child_resource_provider_->num_resources());

  resource_provider_->DestroyChild(child_id);
}

TEST_P(ResourceProviderTest, TransferSoftwareResources) {
  if (GetParam() != ResourceProvider::RESOURCE_TYPE_BITMAP)
    return;

  gfx::Size size(1, 1);
  ResourceFormat format = RGBA_8888;
  size_t pixel_size = TextureSizeBytes(size, format);
  ASSERT_EQ(4U, pixel_size);

  ResourceProvider::ResourceId id1 = child_resource_provider_->CreateResource(
      size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);
  uint8_t data1[4] = { 1, 2, 3, 4 };
  child_resource_provider_->CopyToResource(id1, data1, size);

  ResourceProvider::ResourceId id2 = child_resource_provider_->CreateResource(
      size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);
  uint8_t data2[4] = { 5, 5, 5, 5 };
  child_resource_provider_->CopyToResource(id2, data2, size);

  scoped_ptr<SharedBitmap> shared_bitmap(CreateAndFillSharedBitmap(
      shared_bitmap_manager_.get(), gfx::Size(1, 1), 0));
  SharedBitmap* shared_bitmap_ptr = shared_bitmap.get();
  ResourceProvider::ResourceId id3 =
      child_resource_provider_->CreateResourceFromTextureMailbox(
          TextureMailbox(shared_bitmap_ptr, gfx::Size(1, 1)),
          SingleReleaseCallbackImpl::Create(base::Bind(
              &SharedBitmapReleaseCallback, base::Passed(&shared_bitmap))));

  ReturnedResourceArray returned_to_child;
  int child_id =
      resource_provider_->CreateChild(GetReturnCallback(&returned_to_child));
  {
    // Transfer some resources to the parent.
    ResourceProvider::ResourceIdArray resource_ids_to_transfer;
    resource_ids_to_transfer.push_back(id1);
    resource_ids_to_transfer.push_back(id2);
    resource_ids_to_transfer.push_back(id3);
    TransferableResourceArray list;
    child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
                                                  &list);
    ASSERT_EQ(3u, list.size());
    EXPECT_EQ(0u, list[0].mailbox_holder.sync_point);
    EXPECT_EQ(0u, list[1].mailbox_holder.sync_point);
    EXPECT_EQ(0u, list[2].mailbox_holder.sync_point);
    EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id1));
    EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id2));
    EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id3));
    resource_provider_->ReceiveFromChild(child_id, list);
    resource_provider_->DeclareUsedResourcesFromChild(child_id,
                                                      resource_ids_to_transfer);
  }

  EXPECT_EQ(3u, resource_provider_->num_resources());
  ResourceProvider::ResourceIdMap resource_map =
      resource_provider_->GetChildToParentMap(child_id);
  ResourceProvider::ResourceId mapped_id1 = resource_map[id1];
  ResourceProvider::ResourceId mapped_id2 = resource_map[id2];
  ResourceProvider::ResourceId mapped_id3 = resource_map[id3];
  EXPECT_NE(0u, mapped_id1);
  EXPECT_NE(0u, mapped_id2);
  EXPECT_NE(0u, mapped_id3);
  EXPECT_FALSE(resource_provider_->InUseByConsumer(id1));
  EXPECT_FALSE(resource_provider_->InUseByConsumer(id2));
  EXPECT_FALSE(resource_provider_->InUseByConsumer(id3));

  uint8_t result[4] = { 0 };
  GetResourcePixels(
      resource_provider_.get(), context(), mapped_id1, size, format, result);
  EXPECT_EQ(0, memcmp(data1, result, pixel_size));

  GetResourcePixels(
      resource_provider_.get(), context(), mapped_id2, size, format, result);
  EXPECT_EQ(0, memcmp(data2, result, pixel_size));

  {
    // Check that transfering again the same resource from the child to the
    // parent works.
    ResourceProvider::ResourceIdArray resource_ids_to_transfer;
    resource_ids_to_transfer.push_back(id1);
    resource_ids_to_transfer.push_back(id2);
    TransferableResourceArray list;
    child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
                                                  &list);
    EXPECT_EQ(2u, list.size());
    EXPECT_EQ(id1, list[0].id);
    EXPECT_EQ(id2, list[1].id);
    ReturnedResourceArray returned;
    TransferableResource::ReturnResources(list, &returned);
    child_resource_provider_->ReceiveReturnsFromParent(returned);
    // ids were exported twice, we returned them only once, they should still
    // be in-use.
    EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id1));
    EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id2));
  }
  {
    EXPECT_EQ(0u, returned_to_child.size());

    // Transfer resources back from the parent to the child. Set no resources as
    // being in use.
    ResourceProvider::ResourceIdArray no_resources;
    resource_provider_->DeclareUsedResourcesFromChild(child_id, no_resources);

    ASSERT_EQ(3u, returned_to_child.size());
    EXPECT_EQ(0u, returned_to_child[0].sync_point);
    EXPECT_EQ(0u, returned_to_child[1].sync_point);
    EXPECT_EQ(0u, returned_to_child[2].sync_point);
    std::set<ResourceProvider::ResourceId> expected_ids;
    expected_ids.insert(id1);
    expected_ids.insert(id2);
    expected_ids.insert(id3);
    std::set<ResourceProvider::ResourceId> returned_ids;
    for (unsigned i = 0; i < 3; i++)
      returned_ids.insert(returned_to_child[i].id);
    EXPECT_EQ(expected_ids, returned_ids);
    EXPECT_FALSE(returned_to_child[0].lost);
    EXPECT_FALSE(returned_to_child[1].lost);
    EXPECT_FALSE(returned_to_child[2].lost);
    child_resource_provider_->ReceiveReturnsFromParent(returned_to_child);
    returned_to_child.clear();
  }
  EXPECT_FALSE(child_resource_provider_->InUseByConsumer(id1));
  EXPECT_FALSE(child_resource_provider_->InUseByConsumer(id2));
  EXPECT_FALSE(child_resource_provider_->InUseByConsumer(id3));

  {
    ResourceProvider::ScopedReadLockSoftware lock(
        child_resource_provider_.get(), id1);
    const SkBitmap* sk_bitmap = lock.sk_bitmap();
    EXPECT_EQ(sk_bitmap->width(), size.width());
    EXPECT_EQ(sk_bitmap->height(), size.height());
    EXPECT_EQ(0, memcmp(data1, sk_bitmap->getPixels(), pixel_size));
  }
  {
    ResourceProvider::ScopedReadLockSoftware lock(
        child_resource_provider_.get(), id2);
    const SkBitmap* sk_bitmap = lock.sk_bitmap();
    EXPECT_EQ(sk_bitmap->width(), size.width());
    EXPECT_EQ(sk_bitmap->height(), size.height());
    EXPECT_EQ(0, memcmp(data2, sk_bitmap->getPixels(), pixel_size));
  }
  {
    // Transfer resources to the parent again.
    ResourceProvider::ResourceIdArray resource_ids_to_transfer;
    resource_ids_to_transfer.push_back(id1);
    resource_ids_to_transfer.push_back(id2);
    resource_ids_to_transfer.push_back(id3);
    TransferableResourceArray list;
    child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
                                                  &list);
    ASSERT_EQ(3u, list.size());
    EXPECT_EQ(id1, list[0].id);
    EXPECT_EQ(id2, list[1].id);
    EXPECT_EQ(id3, list[2].id);
    EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id1));
    EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id2));
    EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id3));
    resource_provider_->ReceiveFromChild(child_id, list);
    resource_provider_->DeclareUsedResourcesFromChild(child_id,
                                                      resource_ids_to_transfer);
  }

  EXPECT_EQ(0u, returned_to_child.size());

  EXPECT_EQ(3u, resource_provider_->num_resources());
  resource_provider_->DestroyChild(child_id);
  EXPECT_EQ(0u, resource_provider_->num_resources());

  ASSERT_EQ(3u, returned_to_child.size());
  EXPECT_EQ(0u, returned_to_child[0].sync_point);
  EXPECT_EQ(0u, returned_to_child[1].sync_point);
  EXPECT_EQ(0u, returned_to_child[2].sync_point);
  std::set<ResourceProvider::ResourceId> expected_ids;
  expected_ids.insert(id1);
  expected_ids.insert(id2);
  expected_ids.insert(id3);
  std::set<ResourceProvider::ResourceId> returned_ids;
  for (unsigned i = 0; i < 3; i++)
    returned_ids.insert(returned_to_child[i].id);
  EXPECT_EQ(expected_ids, returned_ids);
  EXPECT_FALSE(returned_to_child[0].lost);
  EXPECT_FALSE(returned_to_child[1].lost);
  EXPECT_FALSE(returned_to_child[2].lost);
}

TEST_P(ResourceProviderTest, TransferGLToSoftware) {
  if (GetParam() != ResourceProvider::RESOURCE_TYPE_BITMAP)
    return;

  scoped_ptr<ResourceProviderContext> child_context_owned(
      ResourceProviderContext::Create(shared_data_.get()));

  FakeOutputSurfaceClient child_output_surface_client;
  scoped_ptr<OutputSurface> child_output_surface(
      FakeOutputSurface::Create3d(child_context_owned.Pass()));
  CHECK(child_output_surface->BindToClient(&child_output_surface_client));

  scoped_ptr<ResourceProvider> child_resource_provider(
      ResourceProvider::Create(child_output_surface.get(),
                               shared_bitmap_manager_.get(),
                               gpu_memory_buffer_manager_.get(),
                               NULL,
                               0,
                               false,
                               1));

  gfx::Size size(1, 1);
  ResourceFormat format = RGBA_8888;
  size_t pixel_size = TextureSizeBytes(size, format);
  ASSERT_EQ(4U, pixel_size);

  ResourceProvider::ResourceId id1 = child_resource_provider->CreateResource(
      size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);
  uint8_t data1[4] = { 1, 2, 3, 4 };
  child_resource_provider->CopyToResource(id1, data1, size);

  ReturnedResourceArray returned_to_child;
  int child_id =
      resource_provider_->CreateChild(GetReturnCallback(&returned_to_child));
  {
    ResourceProvider::ResourceIdArray resource_ids_to_transfer;
    resource_ids_to_transfer.push_back(id1);
    TransferableResourceArray list;
    child_resource_provider->PrepareSendToParent(resource_ids_to_transfer,
                                                 &list);
    ASSERT_EQ(1u, list.size());
    EXPECT_NE(0u, list[0].mailbox_holder.sync_point);
    EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_2D),
              list[0].mailbox_holder.texture_target);
    EXPECT_TRUE(child_resource_provider->InUseByConsumer(id1));
    resource_provider_->ReceiveFromChild(child_id, list);
  }

  EXPECT_EQ(0u, resource_provider_->num_resources());
  ASSERT_EQ(1u, returned_to_child.size());
  EXPECT_EQ(returned_to_child[0].id, id1);
  ResourceProvider::ResourceIdMap resource_map =
      resource_provider_->GetChildToParentMap(child_id);
  ResourceProvider::ResourceId mapped_id1 = resource_map[id1];
  EXPECT_EQ(0u, mapped_id1);

  resource_provider_->DestroyChild(child_id);
  EXPECT_EQ(0u, resource_provider_->num_resources());

  ASSERT_EQ(1u, returned_to_child.size());
  EXPECT_FALSE(returned_to_child[0].lost);
}

TEST_P(ResourceProviderTest, TransferInvalidSoftware) {
  if (GetParam() != ResourceProvider::RESOURCE_TYPE_BITMAP)
    return;

  gfx::Size size(1, 1);
  ResourceFormat format = RGBA_8888;
  size_t pixel_size = TextureSizeBytes(size, format);
  ASSERT_EQ(4U, pixel_size);

  ResourceProvider::ResourceId id1 = child_resource_provider_->CreateResource(
      size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);
  uint8_t data1[4] = { 1, 2, 3, 4 };
  child_resource_provider_->CopyToResource(id1, data1, size);

  ReturnedResourceArray returned_to_child;
  int child_id =
      resource_provider_->CreateChild(GetReturnCallback(&returned_to_child));
  {
    ResourceProvider::ResourceIdArray resource_ids_to_transfer;
    resource_ids_to_transfer.push_back(id1);
    TransferableResourceArray list;
    child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
                                                  &list);
    ASSERT_EQ(1u, list.size());
    // Make invalid.
    list[0].mailbox_holder.mailbox.name[1] = 5;
    EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id1));
    resource_provider_->ReceiveFromChild(child_id, list);
  }

  EXPECT_EQ(1u, resource_provider_->num_resources());
  EXPECT_EQ(0u, returned_to_child.size());

  ResourceProvider::ResourceIdMap resource_map =
      resource_provider_->GetChildToParentMap(child_id);
  ResourceProvider::ResourceId mapped_id1 = resource_map[id1];
  EXPECT_NE(0u, mapped_id1);
  {
    ResourceProvider::ScopedReadLockSoftware lock(resource_provider_.get(),
                                                  mapped_id1);
    EXPECT_FALSE(lock.valid());
  }

  resource_provider_->DestroyChild(child_id);
  EXPECT_EQ(0u, resource_provider_->num_resources());

  ASSERT_EQ(1u, returned_to_child.size());
  EXPECT_FALSE(returned_to_child[0].lost);
}

TEST_P(ResourceProviderTest, DeleteExportedResources) {
  gfx::Size size(1, 1);
  ResourceFormat format = RGBA_8888;
  size_t pixel_size = TextureSizeBytes(size, format);
  ASSERT_EQ(4U, pixel_size);

  ResourceProvider::ResourceId id1 = child_resource_provider_->CreateResource(
      size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);
  uint8_t data1[4] = { 1, 2, 3, 4 };
  child_resource_provider_->CopyToResource(id1, data1, size);

  ResourceProvider::ResourceId id2 = child_resource_provider_->CreateResource(
      size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);
  uint8_t data2[4] = {5, 5, 5, 5};
  child_resource_provider_->CopyToResource(id2, data2, size);

  ReturnedResourceArray returned_to_child;
  int child_id =
      resource_provider_->CreateChild(GetReturnCallback(&returned_to_child));
  {
    // Transfer some resources to the parent.
    ResourceProvider::ResourceIdArray resource_ids_to_transfer;
    resource_ids_to_transfer.push_back(id1);
    resource_ids_to_transfer.push_back(id2);
    TransferableResourceArray list;
    child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
                                                  &list);
    ASSERT_EQ(2u, list.size());
    if (GetParam() == ResourceProvider::RESOURCE_TYPE_GL_TEXTURE) {
      EXPECT_NE(0u, list[0].mailbox_holder.sync_point);
      EXPECT_NE(0u, list[1].mailbox_holder.sync_point);
    }
    EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id1));
    EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id2));
    resource_provider_->ReceiveFromChild(child_id, list);
    resource_provider_->DeclareUsedResourcesFromChild(child_id,
                                                      resource_ids_to_transfer);
  }

  EXPECT_EQ(2u, resource_provider_->num_resources());
  ResourceProvider::ResourceIdMap resource_map =
      resource_provider_->GetChildToParentMap(child_id);
  ResourceProvider::ResourceId mapped_id1 = resource_map[id1];
  ResourceProvider::ResourceId mapped_id2 = resource_map[id2];
  EXPECT_NE(0u, mapped_id1);
  EXPECT_NE(0u, mapped_id2);
  EXPECT_FALSE(resource_provider_->InUseByConsumer(id1));
  EXPECT_FALSE(resource_provider_->InUseByConsumer(id2));

  {
    // The parent transfers the resources to the grandparent.
    ResourceProvider::ResourceIdArray resource_ids_to_transfer;
    resource_ids_to_transfer.push_back(mapped_id1);
    resource_ids_to_transfer.push_back(mapped_id2);
    TransferableResourceArray list;
    resource_provider_->PrepareSendToParent(resource_ids_to_transfer, &list);

    ASSERT_EQ(2u, list.size());
    if (GetParam() == ResourceProvider::RESOURCE_TYPE_GL_TEXTURE) {
      EXPECT_NE(0u, list[0].mailbox_holder.sync_point);
      EXPECT_NE(0u, list[1].mailbox_holder.sync_point);
    }
    EXPECT_TRUE(resource_provider_->InUseByConsumer(id1));
    EXPECT_TRUE(resource_provider_->InUseByConsumer(id2));

    // Release the resource in the parent. Set no resources as being in use. The
    // resources are exported so that can't be transferred back yet.
    ResourceProvider::ResourceIdArray no_resources;
    resource_provider_->DeclareUsedResourcesFromChild(child_id, no_resources);

    EXPECT_EQ(0u, returned_to_child.size());
    EXPECT_EQ(2u, resource_provider_->num_resources());

    // Return the resources from the grandparent to the parent. They should be
    // returned to the child then.
    EXPECT_EQ(2u, list.size());
    EXPECT_EQ(mapped_id1, list[0].id);
    EXPECT_EQ(mapped_id2, list[1].id);
    ReturnedResourceArray returned;
    TransferableResource::ReturnResources(list, &returned);
    resource_provider_->ReceiveReturnsFromParent(returned);

    EXPECT_EQ(0u, resource_provider_->num_resources());
    ASSERT_EQ(2u, returned_to_child.size());
    if (GetParam() == ResourceProvider::RESOURCE_TYPE_GL_TEXTURE) {
      EXPECT_NE(0u, returned_to_child[0].sync_point);
      EXPECT_NE(0u, returned_to_child[1].sync_point);
    }
    EXPECT_FALSE(returned_to_child[0].lost);
    EXPECT_FALSE(returned_to_child[1].lost);
  }
}

TEST_P(ResourceProviderTest, DestroyChildWithExportedResources) {
  gfx::Size size(1, 1);
  ResourceFormat format = RGBA_8888;
  size_t pixel_size = TextureSizeBytes(size, format);
  ASSERT_EQ(4U, pixel_size);

  ResourceProvider::ResourceId id1 = child_resource_provider_->CreateResource(
      size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);
  uint8_t data1[4] = {1, 2, 3, 4};
  child_resource_provider_->CopyToResource(id1, data1, size);

  ResourceProvider::ResourceId id2 = child_resource_provider_->CreateResource(
      size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);
  uint8_t data2[4] = {5, 5, 5, 5};
  child_resource_provider_->CopyToResource(id2, data2, size);

  ReturnedResourceArray returned_to_child;
  int child_id =
      resource_provider_->CreateChild(GetReturnCallback(&returned_to_child));
  {
    // Transfer some resources to the parent.
    ResourceProvider::ResourceIdArray resource_ids_to_transfer;
    resource_ids_to_transfer.push_back(id1);
    resource_ids_to_transfer.push_back(id2);
    TransferableResourceArray list;
    child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
                                                  &list);
    ASSERT_EQ(2u, list.size());
    if (GetParam() == ResourceProvider::RESOURCE_TYPE_GL_TEXTURE) {
      EXPECT_NE(0u, list[0].mailbox_holder.sync_point);
      EXPECT_NE(0u, list[1].mailbox_holder.sync_point);
    }
    EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id1));
    EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id2));
    resource_provider_->ReceiveFromChild(child_id, list);
    resource_provider_->DeclareUsedResourcesFromChild(child_id,
                                                      resource_ids_to_transfer);
  }

  EXPECT_EQ(2u, resource_provider_->num_resources());
  ResourceProvider::ResourceIdMap resource_map =
      resource_provider_->GetChildToParentMap(child_id);
  ResourceProvider::ResourceId mapped_id1 = resource_map[id1];
  ResourceProvider::ResourceId mapped_id2 = resource_map[id2];
  EXPECT_NE(0u, mapped_id1);
  EXPECT_NE(0u, mapped_id2);
  EXPECT_FALSE(resource_provider_->InUseByConsumer(id1));
  EXPECT_FALSE(resource_provider_->InUseByConsumer(id2));

  {
    // The parent transfers the resources to the grandparent.
    ResourceProvider::ResourceIdArray resource_ids_to_transfer;
    resource_ids_to_transfer.push_back(mapped_id1);
    resource_ids_to_transfer.push_back(mapped_id2);
    TransferableResourceArray list;
    resource_provider_->PrepareSendToParent(resource_ids_to_transfer, &list);

    ASSERT_EQ(2u, list.size());
    if (GetParam() == ResourceProvider::RESOURCE_TYPE_GL_TEXTURE) {
      EXPECT_NE(0u, list[0].mailbox_holder.sync_point);
      EXPECT_NE(0u, list[1].mailbox_holder.sync_point);
    }
    EXPECT_TRUE(resource_provider_->InUseByConsumer(id1));
    EXPECT_TRUE(resource_provider_->InUseByConsumer(id2));

    // Release the resource in the parent. Set no resources as being in use. The
    // resources are exported so that can't be transferred back yet.
    ResourceProvider::ResourceIdArray no_resources;
    resource_provider_->DeclareUsedResourcesFromChild(child_id, no_resources);

    // Destroy the child, the resources should not be returned yet.
    EXPECT_EQ(0u, returned_to_child.size());
    EXPECT_EQ(2u, resource_provider_->num_resources());

    resource_provider_->DestroyChild(child_id);

    EXPECT_EQ(2u, resource_provider_->num_resources());
    ASSERT_EQ(0u, returned_to_child.size());

    // Return a resource from the grandparent, it should be returned at this
    // point.
    EXPECT_EQ(2u, list.size());
    EXPECT_EQ(mapped_id1, list[0].id);
    EXPECT_EQ(mapped_id2, list[1].id);
    TransferableResourceArray return_list;
    return_list.push_back(list[1]);
    list.pop_back();
    ReturnedResourceArray returned;
    TransferableResource::ReturnResources(return_list, &returned);
    resource_provider_->ReceiveReturnsFromParent(returned);

    EXPECT_EQ(1u, resource_provider_->num_resources());
    ASSERT_EQ(1u, returned_to_child.size());
    if (GetParam() == ResourceProvider::RESOURCE_TYPE_GL_TEXTURE) {
      EXPECT_NE(0u, returned_to_child[0].sync_point);
    }
    EXPECT_FALSE(returned_to_child[0].lost);
    returned_to_child.clear();

    // Destroy the parent resource provider. The resource that's left should be
    // lost at this point, and returned.
    resource_provider_ = nullptr;
    ASSERT_EQ(1u, returned_to_child.size());
    if (GetParam() == ResourceProvider::RESOURCE_TYPE_GL_TEXTURE) {
      EXPECT_NE(0u, returned_to_child[0].sync_point);
    }
    EXPECT_TRUE(returned_to_child[0].lost);
  }
}

TEST_P(ResourceProviderTest, DeleteTransferredResources) {
  gfx::Size size(1, 1);
  ResourceFormat format = RGBA_8888;
  size_t pixel_size = TextureSizeBytes(size, format);
  ASSERT_EQ(4U, pixel_size);

  ResourceProvider::ResourceId id = child_resource_provider_->CreateResource(
      size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);
  uint8_t data[4] = { 1, 2, 3, 4 };
  child_resource_provider_->CopyToResource(id, data, size);

  ReturnedResourceArray returned_to_child;
  int child_id =
      resource_provider_->CreateChild(GetReturnCallback(&returned_to_child));
  {
    // Transfer some resource to the parent.
    ResourceProvider::ResourceIdArray resource_ids_to_transfer;
    resource_ids_to_transfer.push_back(id);
    TransferableResourceArray list;
    child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
                                                  &list);
    ASSERT_EQ(1u, list.size());
    if (GetParam() == ResourceProvider::RESOURCE_TYPE_GL_TEXTURE)
      EXPECT_NE(0u, list[0].mailbox_holder.sync_point);
    EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id));
    resource_provider_->ReceiveFromChild(child_id, list);
    resource_provider_->DeclareUsedResourcesFromChild(child_id,
                                                      resource_ids_to_transfer);
  }

  // Delete textures in the child, while they are transfered.
  child_resource_provider_->DeleteResource(id);
  EXPECT_EQ(1u, child_resource_provider_->num_resources());
  {
    EXPECT_EQ(0u, returned_to_child.size());

    // Transfer resources back from the parent to the child. Set no resources as
    // being in use.
    ResourceProvider::ResourceIdArray no_resources;
    resource_provider_->DeclareUsedResourcesFromChild(child_id, no_resources);

    ASSERT_EQ(1u, returned_to_child.size());
    if (GetParam() == ResourceProvider::RESOURCE_TYPE_GL_TEXTURE)
      EXPECT_NE(0u, returned_to_child[0].sync_point);
    child_resource_provider_->ReceiveReturnsFromParent(returned_to_child);
  }
  EXPECT_EQ(0u, child_resource_provider_->num_resources());
}

TEST_P(ResourceProviderTest, UnuseTransferredResources) {
  gfx::Size size(1, 1);
  ResourceFormat format = RGBA_8888;
  size_t pixel_size = TextureSizeBytes(size, format);
  ASSERT_EQ(4U, pixel_size);

  ResourceProvider::ResourceId id = child_resource_provider_->CreateResource(
      size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);
  uint8_t data[4] = {1, 2, 3, 4};
  child_resource_provider_->CopyToResource(id, data, size);

  ReturnedResourceArray returned_to_child;
  int child_id =
      resource_provider_->CreateChild(GetReturnCallback(&returned_to_child));
  const ResourceProvider::ResourceIdMap& map =
      resource_provider_->GetChildToParentMap(child_id);
  {
    // Transfer some resource to the parent.
    ResourceProvider::ResourceIdArray resource_ids_to_transfer;
    resource_ids_to_transfer.push_back(id);
    TransferableResourceArray list;
    child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
                                                  &list);
    EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id));
    resource_provider_->ReceiveFromChild(child_id, list);
    resource_provider_->DeclareUsedResourcesFromChild(child_id,
                                                      resource_ids_to_transfer);
  }
  TransferableResourceArray sent_to_top_level;
  {
    // Parent transfers to top-level.
    ASSERT_TRUE(map.find(id) != map.end());
    ResourceProvider::ResourceId parent_id = map.find(id)->second;
    ResourceProvider::ResourceIdArray resource_ids_to_transfer;
    resource_ids_to_transfer.push_back(parent_id);
    resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
                                            &sent_to_top_level);
    EXPECT_TRUE(resource_provider_->InUseByConsumer(parent_id));
  }
  {
    // Stop using resource.
    ResourceProvider::ResourceIdArray empty;
    resource_provider_->DeclareUsedResourcesFromChild(child_id, empty);
    // Resource is not yet returned to the child, since it's in use by the
    // top-level.
    EXPECT_TRUE(returned_to_child.empty());
  }
  {
    // Send the resource to the parent again.
    ResourceProvider::ResourceIdArray resource_ids_to_transfer;
    resource_ids_to_transfer.push_back(id);
    TransferableResourceArray list;
    child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
                                                  &list);
    EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id));
    resource_provider_->ReceiveFromChild(child_id, list);
    resource_provider_->DeclareUsedResourcesFromChild(child_id,
                                                      resource_ids_to_transfer);
  }
  {
    // Receive returns back from top-level.
    ReturnedResourceArray returned;
    TransferableResource::ReturnResources(sent_to_top_level, &returned);
    resource_provider_->ReceiveReturnsFromParent(returned);
    // Resource is still not yet returned to the child, since it's declared used
    // in the parent.
    EXPECT_TRUE(returned_to_child.empty());
    ASSERT_TRUE(map.find(id) != map.end());
    ResourceProvider::ResourceId parent_id = map.find(id)->second;
    EXPECT_FALSE(resource_provider_->InUseByConsumer(parent_id));
  }
  {
    sent_to_top_level.clear();
    // Parent transfers again to top-level.
    ASSERT_TRUE(map.find(id) != map.end());
    ResourceProvider::ResourceId parent_id = map.find(id)->second;
    ResourceProvider::ResourceIdArray resource_ids_to_transfer;
    resource_ids_to_transfer.push_back(parent_id);
    resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
                                            &sent_to_top_level);
    EXPECT_TRUE(resource_provider_->InUseByConsumer(parent_id));
  }
  {
    // Receive returns back from top-level.
    ReturnedResourceArray returned;
    TransferableResource::ReturnResources(sent_to_top_level, &returned);
    resource_provider_->ReceiveReturnsFromParent(returned);
    // Resource is still not yet returned to the child, since it's still
    // declared used in the parent.
    EXPECT_TRUE(returned_to_child.empty());
    ASSERT_TRUE(map.find(id) != map.end());
    ResourceProvider::ResourceId parent_id = map.find(id)->second;
    EXPECT_FALSE(resource_provider_->InUseByConsumer(parent_id));
  }
  {
    // Stop using resource.
    ResourceProvider::ResourceIdArray empty;
    resource_provider_->DeclareUsedResourcesFromChild(child_id, empty);
    // Resource should have been returned to the child, since it's no longer in
    // use by the top-level.
    ASSERT_EQ(1u, returned_to_child.size());
    EXPECT_EQ(id, returned_to_child[0].id);
    EXPECT_EQ(2, returned_to_child[0].count);
    child_resource_provider_->ReceiveReturnsFromParent(returned_to_child);
    returned_to_child.clear();
    EXPECT_FALSE(child_resource_provider_->InUseByConsumer(id));
  }
}

class ResourceProviderTestTextureFilters : public ResourceProviderTest {
 public:
  static void RunTest(GLenum child_filter, GLenum parent_filter) {
    scoped_ptr<TextureStateTrackingContext> child_context_owned(
        new TextureStateTrackingContext);
    TextureStateTrackingContext* child_context = child_context_owned.get();

    FakeOutputSurfaceClient child_output_surface_client;
    scoped_ptr<OutputSurface> child_output_surface(
        FakeOutputSurface::Create3d(child_context_owned.Pass()));
    CHECK(child_output_surface->BindToClient(&child_output_surface_client));
    scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
        new TestSharedBitmapManager());

    scoped_ptr<ResourceProvider> child_resource_provider(
        ResourceProvider::Create(child_output_surface.get(),
                                 shared_bitmap_manager.get(),
                                 NULL,
                                 NULL,
                                 0,
                                 false,
                                 1));

    scoped_ptr<TextureStateTrackingContext> parent_context_owned(
        new TextureStateTrackingContext);
    TextureStateTrackingContext* parent_context = parent_context_owned.get();

    FakeOutputSurfaceClient parent_output_surface_client;
    scoped_ptr<OutputSurface> parent_output_surface(
        FakeOutputSurface::Create3d(parent_context_owned.Pass()));
    CHECK(parent_output_surface->BindToClient(&parent_output_surface_client));

    scoped_ptr<ResourceProvider> parent_resource_provider(
        ResourceProvider::Create(parent_output_surface.get(),
                                 shared_bitmap_manager.get(),
                                 NULL,
                                 NULL,
                                 0,
                                 false,
                                 1));

    gfx::Size size(1, 1);
    ResourceFormat format = RGBA_8888;
    int child_texture_id = 1;
    int parent_texture_id = 2;

    size_t pixel_size = TextureSizeBytes(size, format);
    ASSERT_EQ(4U, pixel_size);

    ResourceProvider::ResourceId id = child_resource_provider->CreateResource(
        size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE,
        format);

    // The new texture is created with GL_LINEAR.
    EXPECT_CALL(*child_context, bindTexture(GL_TEXTURE_2D, child_texture_id))
        .Times(2);  // Once to create and once to allocate.
    EXPECT_CALL(*child_context,
                texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
    EXPECT_CALL(*child_context,
                texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
    EXPECT_CALL(
        *child_context,
        texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
    EXPECT_CALL(
        *child_context,
        texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
    EXPECT_CALL(*child_context,
                texParameteri(GL_TEXTURE_2D,
                              GL_TEXTURE_POOL_CHROMIUM,
                              GL_TEXTURE_POOL_UNMANAGED_CHROMIUM));
    child_resource_provider->AllocateForTesting(id);
    Mock::VerifyAndClearExpectations(child_context);

    uint8_t data[4] = { 1, 2, 3, 4 };

    EXPECT_CALL(*child_context, bindTexture(GL_TEXTURE_2D, child_texture_id));
    child_resource_provider->CopyToResource(id, data, size);
    Mock::VerifyAndClearExpectations(child_context);

    // The texture is set to |child_filter| in the child.
    EXPECT_CALL(*child_context, bindTexture(GL_TEXTURE_2D, child_texture_id));
    if (child_filter != GL_LINEAR) {
      EXPECT_CALL(
          *child_context,
          texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, child_filter));
      EXPECT_CALL(
          *child_context,
          texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, child_filter));
    }
    SetResourceFilter(child_resource_provider.get(), id, child_filter);
    Mock::VerifyAndClearExpectations(child_context);

    ReturnedResourceArray returned_to_child;
    int child_id = parent_resource_provider->CreateChild(
        GetReturnCallback(&returned_to_child));
    {
      // Transfer some resource to the parent.
      ResourceProvider::ResourceIdArray resource_ids_to_transfer;
      resource_ids_to_transfer.push_back(id);
      TransferableResourceArray list;

      EXPECT_CALL(*child_context,
                  produceTextureDirectCHROMIUM(_, GL_TEXTURE_2D, _));
      EXPECT_CALL(*child_context, insertSyncPoint());
      child_resource_provider->PrepareSendToParent(resource_ids_to_transfer,
                                                   &list);
      Mock::VerifyAndClearExpectations(child_context);

      ASSERT_EQ(1u, list.size());
      EXPECT_EQ(static_cast<unsigned>(child_filter), list[0].filter);

      EXPECT_CALL(*parent_context,
                  createAndConsumeTextureCHROMIUM(GL_TEXTURE_2D, _))
          .WillOnce(Return(parent_texture_id));

      parent_resource_provider->ReceiveFromChild(child_id, list);
      {
        parent_resource_provider->WaitSyncPointIfNeeded(list[0].id);
        ResourceProvider::ScopedReadLockGL lock(parent_resource_provider.get(),
                                                list[0].id);
      }
      Mock::VerifyAndClearExpectations(parent_context);

      parent_resource_provider->DeclareUsedResourcesFromChild(
          child_id, resource_ids_to_transfer);
      Mock::VerifyAndClearExpectations(parent_context);
    }
    ResourceProvider::ResourceIdMap resource_map =
        parent_resource_provider->GetChildToParentMap(child_id);
    ResourceProvider::ResourceId mapped_id = resource_map[id];
    EXPECT_NE(0u, mapped_id);

    // The texture is set to |parent_filter| in the parent.
    EXPECT_CALL(*parent_context, bindTexture(GL_TEXTURE_2D, parent_texture_id));
    EXPECT_CALL(
        *parent_context,
        texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, parent_filter));
    EXPECT_CALL(
        *parent_context,
        texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, parent_filter));
    SetResourceFilter(parent_resource_provider.get(), mapped_id, parent_filter);
    Mock::VerifyAndClearExpectations(parent_context);

    // The texture should be reset to |child_filter| in the parent when it is
    // returned, since that is how it was received.
    EXPECT_CALL(*parent_context, bindTexture(GL_TEXTURE_2D, parent_texture_id));
    EXPECT_CALL(
        *parent_context,
        texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, child_filter));
    EXPECT_CALL(
        *parent_context,
        texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, child_filter));

    {
      EXPECT_EQ(0u, returned_to_child.size());

      // Transfer resources back from the parent to the child. Set no resources
      // as being in use.
      ResourceProvider::ResourceIdArray no_resources;
      EXPECT_CALL(*parent_context, insertSyncPoint());
      parent_resource_provider->DeclareUsedResourcesFromChild(child_id,
                                                              no_resources);
      Mock::VerifyAndClearExpectations(parent_context);

      ASSERT_EQ(1u, returned_to_child.size());
      child_resource_provider->ReceiveReturnsFromParent(returned_to_child);
    }

    // The child remembers the texture filter is set to |child_filter|.
    EXPECT_CALL(*child_context, bindTexture(GL_TEXTURE_2D, child_texture_id));
    SetResourceFilter(child_resource_provider.get(), id, child_filter);
    Mock::VerifyAndClearExpectations(child_context);
  }
};

TEST_P(ResourceProviderTest, TextureFilters_ChildNearestParentLinear) {
  if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE)
    return;
  ResourceProviderTestTextureFilters::RunTest(GL_NEAREST, GL_LINEAR);
}

TEST_P(ResourceProviderTest, TextureFilters_ChildLinearParentNearest) {
  if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE)
    return;
  ResourceProviderTestTextureFilters::RunTest(GL_LINEAR, GL_NEAREST);
}

TEST_P(ResourceProviderTest, TransferMailboxResources) {
  // Other mailbox transfers tested elsewhere.
  if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE)
    return;
  unsigned texture = context()->createTexture();
  context()->bindTexture(GL_TEXTURE_2D, texture);
  uint8_t data[4] = { 1, 2, 3, 4 };
  context()->texImage2D(
      GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &data);
  gpu::Mailbox mailbox;
  context()->genMailboxCHROMIUM(mailbox.name);
  context()->produceTextureDirectCHROMIUM(texture, GL_TEXTURE_2D, mailbox.name);
  uint32 sync_point = context()->insertSyncPoint();

  // All the logic below assumes that the sync points are all positive.
  EXPECT_LT(0u, sync_point);

  uint32 release_sync_point = 0;
  bool lost_resource = false;
  BlockingTaskRunner* main_thread_task_runner = NULL;
  ReleaseCallbackImpl callback = base::Bind(ReleaseCallback,
                                            &release_sync_point,
                                            &lost_resource,
                                            &main_thread_task_runner);
  ResourceProvider::ResourceId resource =
      resource_provider_->CreateResourceFromTextureMailbox(
          TextureMailbox(mailbox, GL_TEXTURE_2D, sync_point),
          SingleReleaseCallbackImpl::Create(callback));
  EXPECT_EQ(1u, context()->NumTextures());
  EXPECT_EQ(0u, release_sync_point);
  {
    // Transfer the resource, expect the sync points to be consistent.
    ResourceProvider::ResourceIdArray resource_ids_to_transfer;
    resource_ids_to_transfer.push_back(resource);
    TransferableResourceArray list;
    resource_provider_->PrepareSendToParent(resource_ids_to_transfer, &list);
    ASSERT_EQ(1u, list.size());
    EXPECT_LE(sync_point, list[0].mailbox_holder.sync_point);
    EXPECT_EQ(0,
              memcmp(mailbox.name,
                     list[0].mailbox_holder.mailbox.name,
                     sizeof(mailbox.name)));
    EXPECT_EQ(0u, release_sync_point);

    context()->waitSyncPoint(list[0].mailbox_holder.sync_point);
    unsigned other_texture =
        context()->createAndConsumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name);
    uint8_t test_data[4] = { 0 };
    context()->GetPixels(
        gfx::Size(1, 1), RGBA_8888, test_data);
    EXPECT_EQ(0, memcmp(data, test_data, sizeof(data)));

    context()->produceTextureDirectCHROMIUM(other_texture, GL_TEXTURE_2D,
                                            mailbox.name);
    context()->deleteTexture(other_texture);
    list[0].mailbox_holder.sync_point = context()->insertSyncPoint();
    EXPECT_LT(0u, list[0].mailbox_holder.sync_point);

    // Receive the resource, then delete it, expect the sync points to be
    // consistent.
    ReturnedResourceArray returned;
    TransferableResource::ReturnResources(list, &returned);
    resource_provider_->ReceiveReturnsFromParent(returned);
    EXPECT_EQ(1u, context()->NumTextures());
    EXPECT_EQ(0u, release_sync_point);

    resource_provider_->DeleteResource(resource);
    EXPECT_LE(list[0].mailbox_holder.sync_point, release_sync_point);
    EXPECT_FALSE(lost_resource);
    EXPECT_EQ(main_thread_task_runner_.get(), main_thread_task_runner);
  }

  // We're going to do the same thing as above, but testing the case where we
  // delete the resource before we receive it back.
  sync_point = release_sync_point;
  EXPECT_LT(0u, sync_point);
  release_sync_point = 0;
  resource = resource_provider_->CreateResourceFromTextureMailbox(
      TextureMailbox(mailbox, GL_TEXTURE_2D, sync_point),
      SingleReleaseCallbackImpl::Create(callback));
  EXPECT_EQ(1u, context()->NumTextures());
  EXPECT_EQ(0u, release_sync_point);
  {
    // Transfer the resource, expect the sync points to be consistent.
    ResourceProvider::ResourceIdArray resource_ids_to_transfer;
    resource_ids_to_transfer.push_back(resource);
    TransferableResourceArray list;
    resource_provider_->PrepareSendToParent(resource_ids_to_transfer, &list);
    ASSERT_EQ(1u, list.size());
    EXPECT_LE(sync_point, list[0].mailbox_holder.sync_point);
    EXPECT_EQ(0,
              memcmp(mailbox.name,
                     list[0].mailbox_holder.mailbox.name,
                     sizeof(mailbox.name)));
    EXPECT_EQ(0u, release_sync_point);

    context()->waitSyncPoint(list[0].mailbox_holder.sync_point);
    unsigned other_texture =
        context()->createAndConsumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name);
    uint8_t test_data[4] = { 0 };
    context()->GetPixels(
        gfx::Size(1, 1), RGBA_8888, test_data);
    EXPECT_EQ(0, memcmp(data, test_data, sizeof(data)));

    context()->produceTextureDirectCHROMIUM(other_texture, GL_TEXTURE_2D,
                                            mailbox.name);
    context()->deleteTexture(other_texture);
    list[0].mailbox_holder.sync_point = context()->insertSyncPoint();
    EXPECT_LT(0u, list[0].mailbox_holder.sync_point);

    // Delete the resource, which shouldn't do anything.
    resource_provider_->DeleteResource(resource);
    EXPECT_EQ(1u, context()->NumTextures());
    EXPECT_EQ(0u, release_sync_point);

    // Then receive the resource which should release the mailbox, expect the
    // sync points to be consistent.
    ReturnedResourceArray returned;
    TransferableResource::ReturnResources(list, &returned);
    resource_provider_->ReceiveReturnsFromParent(returned);
    EXPECT_LE(list[0].mailbox_holder.sync_point, release_sync_point);
    EXPECT_FALSE(lost_resource);
    EXPECT_EQ(main_thread_task_runner_.get(), main_thread_task_runner);
  }

  context()->waitSyncPoint(release_sync_point);
  texture =
      context()->createAndConsumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name);
  context()->deleteTexture(texture);
}

TEST_P(ResourceProviderTest, LostResourceInParent) {
  gfx::Size size(1, 1);
  ResourceFormat format = RGBA_8888;
  ResourceProvider::ResourceId resource =
      child_resource_provider_->CreateResource(
          size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE,
          format);
  child_resource_provider_->AllocateForTesting(resource);
  // Expect a GL resource to be lost.
  bool should_lose_resource =
      GetParam() == ResourceProvider::RESOURCE_TYPE_GL_TEXTURE;

  ReturnedResourceArray returned_to_child;
  int child_id =
      resource_provider_->CreateChild(GetReturnCallback(&returned_to_child));
  {
    // Transfer the resource to the parent.
    ResourceProvider::ResourceIdArray resource_ids_to_transfer;
    resource_ids_to_transfer.push_back(resource);
    TransferableResourceArray list;
    child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
                                                  &list);
    EXPECT_EQ(1u, list.size());

    resource_provider_->ReceiveFromChild(child_id, list);
    resource_provider_->DeclareUsedResourcesFromChild(child_id,
                                                      resource_ids_to_transfer);
  }

  // Lose the output surface in the parent.
  resource_provider_->DidLoseOutputSurface();

  {
    EXPECT_EQ(0u, returned_to_child.size());

    // Transfer resources back from the parent to the child. Set no resources as
    // being in use.
    ResourceProvider::ResourceIdArray no_resources;
    resource_provider_->DeclareUsedResourcesFromChild(child_id, no_resources);

    // Expect a GL resource to be lost.
    ASSERT_EQ(1u, returned_to_child.size());
    EXPECT_EQ(should_lose_resource, returned_to_child[0].lost);
    child_resource_provider_->ReceiveReturnsFromParent(returned_to_child);
    returned_to_child.clear();
  }

  // A GL resource should be lost.
  EXPECT_EQ(should_lose_resource, child_resource_provider_->IsLost(resource));

  // Lost resources stay in use in the parent forever.
  EXPECT_EQ(should_lose_resource,
            child_resource_provider_->InUseByConsumer(resource));
}

TEST_P(ResourceProviderTest, LostResourceInGrandParent) {
  gfx::Size size(1, 1);
  ResourceFormat format = RGBA_8888;
  ResourceProvider::ResourceId resource =
      child_resource_provider_->CreateResource(
          size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE,
          format);
  child_resource_provider_->AllocateForTesting(resource);

  ReturnedResourceArray returned_to_child;
  int child_id =
      resource_provider_->CreateChild(GetReturnCallback(&returned_to_child));
  {
    // Transfer the resource to the parent.
    ResourceProvider::ResourceIdArray resource_ids_to_transfer;
    resource_ids_to_transfer.push_back(resource);
    TransferableResourceArray list;
    child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
                                                  &list);
    EXPECT_EQ(1u, list.size());

    resource_provider_->ReceiveFromChild(child_id, list);
    resource_provider_->DeclareUsedResourcesFromChild(child_id,
                                                      resource_ids_to_transfer);
  }

  {
    ResourceProvider::ResourceIdMap resource_map =
        resource_provider_->GetChildToParentMap(child_id);
    ResourceProvider::ResourceId parent_resource = resource_map[resource];
    EXPECT_NE(0u, parent_resource);

    // Transfer to a grandparent.
    ResourceProvider::ResourceIdArray resource_ids_to_transfer;
    resource_ids_to_transfer.push_back(parent_resource);
    TransferableResourceArray list;
    resource_provider_->PrepareSendToParent(resource_ids_to_transfer, &list);

    // Receive back a lost resource from the grandparent.
    EXPECT_EQ(1u, list.size());
    EXPECT_EQ(parent_resource, list[0].id);
    ReturnedResourceArray returned;
    TransferableResource::ReturnResources(list, &returned);
    EXPECT_EQ(1u, returned.size());
    EXPECT_EQ(parent_resource, returned[0].id);
    returned[0].lost = true;
    resource_provider_->ReceiveReturnsFromParent(returned);

    // The resource should be lost.
    EXPECT_TRUE(resource_provider_->IsLost(parent_resource));

    // Lost resources stay in use in the parent forever.
    EXPECT_TRUE(resource_provider_->InUseByConsumer(parent_resource));
  }

  {
    EXPECT_EQ(0u, returned_to_child.size());

    // Transfer resources back from the parent to the child. Set no resources as
    // being in use.
    ResourceProvider::ResourceIdArray no_resources;
    resource_provider_->DeclareUsedResourcesFromChild(child_id, no_resources);

    // Expect the resource to be lost.
    ASSERT_EQ(1u, returned_to_child.size());
    EXPECT_TRUE(returned_to_child[0].lost);
    child_resource_provider_->ReceiveReturnsFromParent(returned_to_child);
    returned_to_child.clear();
  }

  // The resource should be lost.
  EXPECT_TRUE(child_resource_provider_->IsLost(resource));

  // Lost resources stay in use in the parent forever.
  EXPECT_TRUE(child_resource_provider_->InUseByConsumer(resource));
}

TEST_P(ResourceProviderTest, LostMailboxInParent) {
  uint32 release_sync_point = 0;
  bool lost_resource = false;
  bool release_called = false;
  uint32 sync_point = 0;
  ResourceProvider::ResourceId resource = CreateChildMailbox(
      &release_sync_point, &lost_resource, &release_called, &sync_point);

  ReturnedResourceArray returned_to_child;
  int child_id =
      resource_provider_->CreateChild(GetReturnCallback(&returned_to_child));
  {
    // Transfer the resource to the parent.
    ResourceProvider::ResourceIdArray resource_ids_to_transfer;
    resource_ids_to_transfer.push_back(resource);
    TransferableResourceArray list;
    child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
                                                  &list);
    EXPECT_EQ(1u, list.size());

    resource_provider_->ReceiveFromChild(child_id, list);
    resource_provider_->DeclareUsedResourcesFromChild(child_id,
                                                      resource_ids_to_transfer);
  }

  // Lose the output surface in the parent.
  resource_provider_->DidLoseOutputSurface();

  {
    EXPECT_EQ(0u, returned_to_child.size());

    // Transfer resources back from the parent to the child. Set no resources as
    // being in use.
    ResourceProvider::ResourceIdArray no_resources;
    resource_provider_->DeclareUsedResourcesFromChild(child_id, no_resources);

    ASSERT_EQ(1u, returned_to_child.size());
    // Losing an output surface only loses hardware resources.
    EXPECT_EQ(returned_to_child[0].lost,
              GetParam() == ResourceProvider::RESOURCE_TYPE_GL_TEXTURE);
    child_resource_provider_->ReceiveReturnsFromParent(returned_to_child);
    returned_to_child.clear();
  }

  // Delete the resource in the child. Expect the resource to be lost if it's
  // a GL texture.
  child_resource_provider_->DeleteResource(resource);
  EXPECT_EQ(lost_resource,
            GetParam() == ResourceProvider::RESOURCE_TYPE_GL_TEXTURE);
}

TEST_P(ResourceProviderTest, LostMailboxInGrandParent) {
  uint32 release_sync_point = 0;
  bool lost_resource = false;
  bool release_called = false;
  uint32 sync_point = 0;
  ResourceProvider::ResourceId resource = CreateChildMailbox(
      &release_sync_point, &lost_resource, &release_called, &sync_point);

  ReturnedResourceArray returned_to_child;
  int child_id =
      resource_provider_->CreateChild(GetReturnCallback(&returned_to_child));
  {
    // Transfer the resource to the parent.
    ResourceProvider::ResourceIdArray resource_ids_to_transfer;
    resource_ids_to_transfer.push_back(resource);
    TransferableResourceArray list;
    child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
                                                  &list);
    EXPECT_EQ(1u, list.size());

    resource_provider_->ReceiveFromChild(child_id, list);
    resource_provider_->DeclareUsedResourcesFromChild(child_id,
                                                      resource_ids_to_transfer);
  }

  {
    ResourceProvider::ResourceIdMap resource_map =
        resource_provider_->GetChildToParentMap(child_id);
    ResourceProvider::ResourceId parent_resource = resource_map[resource];
    EXPECT_NE(0u, parent_resource);

    // Transfer to a grandparent.
    ResourceProvider::ResourceIdArray resource_ids_to_transfer;
    resource_ids_to_transfer.push_back(parent_resource);
    TransferableResourceArray list;
    resource_provider_->PrepareSendToParent(resource_ids_to_transfer, &list);

    // Receive back a lost resource from the grandparent.
    EXPECT_EQ(1u, list.size());
    EXPECT_EQ(parent_resource, list[0].id);
    ReturnedResourceArray returned;
    TransferableResource::ReturnResources(list, &returned);
    EXPECT_EQ(1u, returned.size());
    EXPECT_EQ(parent_resource, returned[0].id);
    returned[0].lost = true;
    resource_provider_->ReceiveReturnsFromParent(returned);
  }

  {
    EXPECT_EQ(0u, returned_to_child.size());

    // Transfer resources back from the parent to the child. Set no resources as
    // being in use.
    ResourceProvider::ResourceIdArray no_resources;
    resource_provider_->DeclareUsedResourcesFromChild(child_id, no_resources);

    // Expect the resource to be lost.
    ASSERT_EQ(1u, returned_to_child.size());
    EXPECT_TRUE(returned_to_child[0].lost);
    child_resource_provider_->ReceiveReturnsFromParent(returned_to_child);
    returned_to_child.clear();
  }

  // Delete the resource in the child. Expect the resource to be lost.
  child_resource_provider_->DeleteResource(resource);
  EXPECT_TRUE(lost_resource);
}

TEST_P(ResourceProviderTest, Shutdown) {
  uint32 release_sync_point = 0;
  bool lost_resource = false;
  bool release_called = false;
  uint32 sync_point = 0;
  CreateChildMailbox(
      &release_sync_point, &lost_resource, &release_called, &sync_point);

  EXPECT_EQ(0u, release_sync_point);
  EXPECT_FALSE(lost_resource);

  child_resource_provider_ = nullptr;

  if (GetParam() == ResourceProvider::RESOURCE_TYPE_GL_TEXTURE) {
    EXPECT_LE(sync_point, release_sync_point);
  }
  EXPECT_TRUE(release_called);
  EXPECT_FALSE(lost_resource);
}

TEST_P(ResourceProviderTest, ShutdownWithExportedResource) {
  uint32 release_sync_point = 0;
  bool lost_resource = false;
  bool release_called = false;
  uint32 sync_point = 0;
  ResourceProvider::ResourceId resource = CreateChildMailbox(
      &release_sync_point, &lost_resource, &release_called, &sync_point);

  // Transfer the resource, so we can't release it properly on shutdown.
  ResourceProvider::ResourceIdArray resource_ids_to_transfer;
  resource_ids_to_transfer.push_back(resource);
  TransferableResourceArray list;
  child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
                                                &list);

  EXPECT_EQ(0u, release_sync_point);
  EXPECT_FALSE(lost_resource);

  child_resource_provider_ = nullptr;

  // Since the resource is in the parent, the child considers it lost.
  EXPECT_EQ(0u, release_sync_point);
  EXPECT_TRUE(lost_resource);
}

TEST_P(ResourceProviderTest, LostContext) {
  // TextureMailbox callbacks only exist for GL textures for now.
  if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE)
    return;
  unsigned texture = context()->createTexture();
  context()->bindTexture(GL_TEXTURE_2D, texture);
  gpu::Mailbox mailbox;
  context()->genMailboxCHROMIUM(mailbox.name);
  context()->produceTextureDirectCHROMIUM(texture, GL_TEXTURE_2D, mailbox.name);
  uint32 sync_point = context()->insertSyncPoint();

  EXPECT_LT(0u, sync_point);

  uint32 release_sync_point = 0;
  bool lost_resource = false;
  BlockingTaskRunner* main_thread_task_runner = NULL;
  scoped_ptr<SingleReleaseCallbackImpl> callback =
      SingleReleaseCallbackImpl::Create(base::Bind(ReleaseCallback,
                                                   &release_sync_point,
                                                   &lost_resource,
                                                   &main_thread_task_runner));
  resource_provider_->CreateResourceFromTextureMailbox(
      TextureMailbox(mailbox, GL_TEXTURE_2D, sync_point), callback.Pass());

  EXPECT_EQ(0u, release_sync_point);
  EXPECT_FALSE(lost_resource);
  EXPECT_EQ(NULL, main_thread_task_runner);

  resource_provider_->DidLoseOutputSurface();
  resource_provider_ = nullptr;

  EXPECT_LE(sync_point, release_sync_point);
  EXPECT_TRUE(lost_resource);
  EXPECT_EQ(main_thread_task_runner_.get(), main_thread_task_runner);
}

TEST_P(ResourceProviderTest, ScopedSampler) {
  // Sampling is only supported for GL textures.
  if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE)
    return;

  scoped_ptr<TextureStateTrackingContext> context_owned(
      new TextureStateTrackingContext);
  TextureStateTrackingContext* context = context_owned.get();

  FakeOutputSurfaceClient output_surface_client;
  scoped_ptr<OutputSurface> output_surface(
      FakeOutputSurface::Create3d(context_owned.Pass()));
  CHECK(output_surface->BindToClient(&output_surface_client));

  scoped_ptr<ResourceProvider> resource_provider(
      ResourceProvider::Create(output_surface.get(),
                               shared_bitmap_manager_.get(),
                               gpu_memory_buffer_manager_.get(),
                               NULL,
                               0,
                               false,
                               1));

  gfx::Size size(1, 1);
  ResourceFormat format = RGBA_8888;
  int texture_id = 1;

  ResourceProvider::ResourceId id = resource_provider->CreateResource(
      size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);

  // Check that the texture gets created with the right sampler settings.
  EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id))
      .Times(2);  // Once to create and once to allocate.
  EXPECT_CALL(*context,
              texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
  EXPECT_CALL(*context,
              texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
  EXPECT_CALL(
      *context,
      texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
  EXPECT_CALL(
      *context,
      texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
  EXPECT_CALL(*context,
              texParameteri(GL_TEXTURE_2D,
                            GL_TEXTURE_POOL_CHROMIUM,
                            GL_TEXTURE_POOL_UNMANAGED_CHROMIUM));

  resource_provider->AllocateForTesting(id);
  Mock::VerifyAndClearExpectations(context);

  // Creating a sampler with the default filter should not change any texture
  // parameters.
  {
    EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id));
    ResourceProvider::ScopedSamplerGL sampler(
        resource_provider.get(), id, GL_TEXTURE_2D, GL_LINEAR);
    Mock::VerifyAndClearExpectations(context);
  }

  // Using a different filter should be reflected in the texture parameters.
  {
    EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id));
    EXPECT_CALL(
        *context,
        texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST));
    EXPECT_CALL(
        *context,
        texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
    ResourceProvider::ScopedSamplerGL sampler(
        resource_provider.get(), id, GL_TEXTURE_2D, GL_NEAREST);
    Mock::VerifyAndClearExpectations(context);
  }

  // Test resetting to the default filter.
  {
    EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id));
    EXPECT_CALL(*context,
                texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
    EXPECT_CALL(*context,
                texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
    ResourceProvider::ScopedSamplerGL sampler(
        resource_provider.get(), id, GL_TEXTURE_2D, GL_LINEAR);
    Mock::VerifyAndClearExpectations(context);
  }
}

TEST_P(ResourceProviderTest, ManagedResource) {
  // Sampling is only supported for GL textures.
  if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE)
    return;

  scoped_ptr<TextureStateTrackingContext> context_owned(
      new TextureStateTrackingContext);
  TextureStateTrackingContext* context = context_owned.get();

  FakeOutputSurfaceClient output_surface_client;
  scoped_ptr<OutputSurface> output_surface(
      FakeOutputSurface::Create3d(context_owned.Pass()));
  CHECK(output_surface->BindToClient(&output_surface_client));

  scoped_ptr<ResourceProvider> resource_provider(
      ResourceProvider::Create(output_surface.get(),
                               shared_bitmap_manager_.get(),
                               gpu_memory_buffer_manager_.get(),
                               NULL,
                               0,
                               false,
                               1));

  gfx::Size size(1, 1);
  ResourceFormat format = RGBA_8888;
  int texture_id = 1;

  // Check that the texture gets created with the right sampler settings.
  ResourceProvider::ResourceId id = resource_provider->CreateManagedResource(
      size, GL_TEXTURE_2D, GL_CLAMP_TO_EDGE,
      ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);
  EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id));
  EXPECT_CALL(*context,
              texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
  EXPECT_CALL(*context,
              texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
  EXPECT_CALL(
      *context,
      texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
  EXPECT_CALL(
      *context,
      texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
  EXPECT_CALL(*context,
              texParameteri(GL_TEXTURE_2D,
                            GL_TEXTURE_POOL_CHROMIUM,
                            GL_TEXTURE_POOL_MANAGED_CHROMIUM));
  resource_provider->CreateForTesting(id);
  EXPECT_NE(0u, id);

  Mock::VerifyAndClearExpectations(context);
}

TEST_P(ResourceProviderTest, TextureWrapMode) {
  // Sampling is only supported for GL textures.
  if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE)
    return;

  scoped_ptr<TextureStateTrackingContext> context_owned(
      new TextureStateTrackingContext);
  TextureStateTrackingContext* context = context_owned.get();

  FakeOutputSurfaceClient output_surface_client;
  scoped_ptr<OutputSurface> output_surface(
      FakeOutputSurface::Create3d(context_owned.Pass()));
  CHECK(output_surface->BindToClient(&output_surface_client));

  scoped_ptr<ResourceProvider> resource_provider(
      ResourceProvider::Create(output_surface.get(),
                               shared_bitmap_manager_.get(),
                               gpu_memory_buffer_manager_.get(),
                               NULL,
                               0,
                               false,
                               1));

  gfx::Size size(1, 1);
  ResourceFormat format = RGBA_8888;
  GLenum texture_pool = GL_TEXTURE_POOL_UNMANAGED_CHROMIUM;

  for (int texture_id = 1; texture_id <= 2; ++texture_id) {
    GLint wrap_mode = texture_id == 1 ? GL_CLAMP_TO_EDGE : GL_REPEAT;
    // Check that the texture gets created with the right sampler settings.
    ResourceProvider::ResourceId id = resource_provider->CreateGLTexture(
        size, GL_TEXTURE_2D, texture_pool, wrap_mode,
        ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);
    EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id));
    EXPECT_CALL(*context,
                texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
    EXPECT_CALL(*context,
                texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
    EXPECT_CALL(*context,
                texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap_mode));
    EXPECT_CALL(*context,
                texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap_mode));
    EXPECT_CALL(*context,
                texParameteri(GL_TEXTURE_2D,
                              GL_TEXTURE_POOL_CHROMIUM,
                              GL_TEXTURE_POOL_UNMANAGED_CHROMIUM));
    resource_provider->CreateForTesting(id);
    EXPECT_NE(0u, id);

    Mock::VerifyAndClearExpectations(context);
  }
}

TEST_P(ResourceProviderTest, TextureHint) {
  // Sampling is only supported for GL textures.
  if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE)
    return;

  scoped_ptr<TextureStateTrackingContext> context_owned(
      new TextureStateTrackingContext);
  TextureStateTrackingContext* context = context_owned.get();
  context->set_support_texture_storage(true);
  context->set_support_texture_usage(true);

  FakeOutputSurfaceClient output_surface_client;
  scoped_ptr<OutputSurface> output_surface(
      FakeOutputSurface::Create3d(context_owned.Pass()));
  CHECK(output_surface->BindToClient(&output_surface_client));

  scoped_ptr<ResourceProvider> resource_provider(
      ResourceProvider::Create(output_surface.get(),
                               shared_bitmap_manager_.get(),
                               gpu_memory_buffer_manager_.get(),
                               NULL,
                               0,
                               false,
                               1));

  gfx::Size size(1, 1);
  ResourceFormat format = RGBA_8888;
  GLenum texture_pool = GL_TEXTURE_POOL_UNMANAGED_CHROMIUM;

  const ResourceProvider::TextureHint hints[4] = {
      ResourceProvider::TEXTURE_HINT_DEFAULT,
      ResourceProvider::TEXTURE_HINT_IMMUTABLE,
      ResourceProvider::TEXTURE_HINT_FRAMEBUFFER,
      ResourceProvider::TEXTURE_HINT_IMMUTABLE_FRAMEBUFFER,
  };
  for (GLuint texture_id = 1; texture_id <= arraysize(hints); ++texture_id) {
    // Check that the texture gets created with the right sampler settings.
    ResourceProvider::ResourceId id =
        resource_provider->CreateGLTexture(size,
                                           GL_TEXTURE_2D,
                                           texture_pool,
                                           GL_CLAMP_TO_EDGE,
                                           hints[texture_id - 1],
                                           format);
    EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id));
    EXPECT_CALL(*context,
                texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
    EXPECT_CALL(*context,
                texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
    EXPECT_CALL(
        *context,
        texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
    EXPECT_CALL(
        *context,
        texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
    EXPECT_CALL(*context,
                texParameteri(GL_TEXTURE_2D,
                              GL_TEXTURE_POOL_CHROMIUM,
                              GL_TEXTURE_POOL_UNMANAGED_CHROMIUM));
    // Check only TEXTURE_HINT_FRAMEBUFFER set GL_TEXTURE_USAGE_ANGLE.
    bool is_framebuffer_hint =
        hints[texture_id - 1] & ResourceProvider::TEXTURE_HINT_FRAMEBUFFER;
    EXPECT_CALL(*context,
                texParameteri(GL_TEXTURE_2D,
                              GL_TEXTURE_USAGE_ANGLE,
                              GL_FRAMEBUFFER_ATTACHMENT_ANGLE))
        .Times(is_framebuffer_hint ? 1 : 0);
    resource_provider->CreateForTesting(id);
    EXPECT_NE(0u, id);

    Mock::VerifyAndClearExpectations(context);
  }
}

TEST_P(ResourceProviderTest, TextureMailbox_SharedMemory) {
  if (GetParam() != ResourceProvider::RESOURCE_TYPE_BITMAP)
    return;

  gfx::Size size(64, 64);
  const uint32_t kBadBeef = 0xbadbeef;
  scoped_ptr<SharedBitmap> shared_bitmap(
      CreateAndFillSharedBitmap(shared_bitmap_manager_.get(), size, kBadBeef));

  FakeOutputSurfaceClient output_surface_client;
  scoped_ptr<OutputSurface> output_surface(
      FakeOutputSurface::CreateSoftware(make_scoped_ptr(
          new SoftwareOutputDevice)));
  CHECK(output_surface->BindToClient(&output_surface_client));

  scoped_ptr<ResourceProvider> resource_provider(
      ResourceProvider::Create(output_surface.get(),
                               shared_bitmap_manager_.get(),
                               gpu_memory_buffer_manager_.get(),
                               main_thread_task_runner_.get(),
                               0,
                               false,
                               1));

  uint32 release_sync_point = 0;
  bool lost_resource = false;
  BlockingTaskRunner* main_thread_task_runner = NULL;
  scoped_ptr<SingleReleaseCallbackImpl> callback =
      SingleReleaseCallbackImpl::Create(base::Bind(&ReleaseCallback,
                                                   &release_sync_point,
                                                   &lost_resource,
                                                   &main_thread_task_runner));
  TextureMailbox mailbox(shared_bitmap.get(), size);

  ResourceProvider::ResourceId id =
      resource_provider->CreateResourceFromTextureMailbox(
          mailbox, callback.Pass());
  EXPECT_NE(0u, id);

  {
    ResourceProvider::ScopedReadLockSoftware lock(resource_provider.get(), id);
    const SkBitmap* sk_bitmap = lock.sk_bitmap();
    EXPECT_EQ(sk_bitmap->width(), size.width());
    EXPECT_EQ(sk_bitmap->height(), size.height());
    EXPECT_EQ(*sk_bitmap->getAddr32(16, 16), kBadBeef);
  }

  resource_provider->DeleteResource(id);
  EXPECT_EQ(0u, release_sync_point);
  EXPECT_FALSE(lost_resource);
  EXPECT_EQ(main_thread_task_runner_.get(), main_thread_task_runner);
}

class ResourceProviderTestTextureMailboxGLFilters
    : public ResourceProviderTest {
 public:
  static void RunTest(TestSharedBitmapManager* shared_bitmap_manager,
                      TestGpuMemoryBufferManager* gpu_memory_buffer_manager,
                      BlockingTaskRunner* main_thread_task_runner,
                      bool mailbox_nearest_neighbor,
                      GLenum sampler_filter) {
    scoped_ptr<TextureStateTrackingContext> context_owned(
        new TextureStateTrackingContext);
    TextureStateTrackingContext* context = context_owned.get();

    FakeOutputSurfaceClient output_surface_client;
    scoped_ptr<OutputSurface> output_surface(
        FakeOutputSurface::Create3d(context_owned.Pass()));
    CHECK(output_surface->BindToClient(&output_surface_client));

    scoped_ptr<ResourceProvider> resource_provider(
        ResourceProvider::Create(output_surface.get(),
                                 shared_bitmap_manager,
                                 gpu_memory_buffer_manager,
                                 main_thread_task_runner,
                                 0,
                                 false,
                                 1));

    unsigned texture_id = 1;
    uint32 sync_point = 30;
    unsigned target = GL_TEXTURE_2D;

    EXPECT_CALL(*context, bindTexture(_, _)).Times(0);
    EXPECT_CALL(*context, waitSyncPoint(_)).Times(0);
    EXPECT_CALL(*context, insertSyncPoint()).Times(0);
    EXPECT_CALL(*context, produceTextureDirectCHROMIUM(_, _, _)).Times(0);
    EXPECT_CALL(*context, createAndConsumeTextureCHROMIUM(_, _)).Times(0);

    gpu::Mailbox gpu_mailbox;
    memcpy(gpu_mailbox.name, "Hello world", strlen("Hello world") + 1);
    uint32 release_sync_point = 0;
    bool lost_resource = false;
    BlockingTaskRunner* mailbox_task_runner = NULL;
    scoped_ptr<SingleReleaseCallbackImpl> callback =
        SingleReleaseCallbackImpl::Create(base::Bind(&ReleaseCallback,
                                                     &release_sync_point,
                                                     &lost_resource,
                                                     &mailbox_task_runner));

    TextureMailbox mailbox(gpu_mailbox, target, sync_point);
    mailbox.set_nearest_neighbor(mailbox_nearest_neighbor);

    ResourceProvider::ResourceId id =
        resource_provider->CreateResourceFromTextureMailbox(mailbox,
                                                            callback.Pass());
    EXPECT_NE(0u, id);

    Mock::VerifyAndClearExpectations(context);

    {
      // Mailbox sync point WaitSyncPoint before using the texture.
      EXPECT_CALL(*context, waitSyncPoint(sync_point));
      resource_provider->WaitSyncPointIfNeeded(id);
      Mock::VerifyAndClearExpectations(context);

      EXPECT_CALL(*context, createAndConsumeTextureCHROMIUM(target, _))
          .WillOnce(Return(texture_id));
      EXPECT_CALL(*context, bindTexture(target, texture_id));

      EXPECT_CALL(*context, insertSyncPoint()).Times(0);
      EXPECT_CALL(*context, produceTextureDirectCHROMIUM(_, _, _)).Times(0);

      // The sampler will reset these if |mailbox_nearest_neighbor| does not
      // match |sampler_filter|.
      if (mailbox_nearest_neighbor != (sampler_filter == GL_NEAREST)) {
        EXPECT_CALL(*context, texParameteri(
            GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, sampler_filter));
        EXPECT_CALL(*context, texParameteri(
            GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, sampler_filter));
      }

      ResourceProvider::ScopedSamplerGL lock(
          resource_provider.get(), id, sampler_filter);
      Mock::VerifyAndClearExpectations(context);

      // When done with it, a sync point should be inserted, but no produce is
      // necessary.
      EXPECT_CALL(*context, bindTexture(_, _)).Times(0);
      EXPECT_CALL(*context, insertSyncPoint());
      EXPECT_CALL(*context, produceTextureDirectCHROMIUM(_, _, _)).Times(0);

      EXPECT_CALL(*context, waitSyncPoint(_)).Times(0);
      EXPECT_CALL(*context, createAndConsumeTextureCHROMIUM(_, _)).Times(0);
    }

    resource_provider->DeleteResource(id);
    EXPECT_EQ(0u, release_sync_point);
    EXPECT_FALSE(lost_resource);
    EXPECT_EQ(main_thread_task_runner, mailbox_task_runner);
  }
};

TEST_P(ResourceProviderTest, TextureMailbox_GLTexture2D_LinearToLinear) {
  // Mailboxing is only supported for GL textures.
  if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE)
    return;

  ResourceProviderTestTextureMailboxGLFilters::RunTest(
      shared_bitmap_manager_.get(),
      gpu_memory_buffer_manager_.get(),
      main_thread_task_runner_.get(),
      false,
      GL_LINEAR);
}

TEST_P(ResourceProviderTest, TextureMailbox_GLTexture2D_NearestToNearest) {
  // Mailboxing is only supported for GL textures.
  if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE)
    return;

  ResourceProviderTestTextureMailboxGLFilters::RunTest(
      shared_bitmap_manager_.get(),
      gpu_memory_buffer_manager_.get(),
      main_thread_task_runner_.get(),
      true,
      GL_NEAREST);
}

TEST_P(ResourceProviderTest, TextureMailbox_GLTexture2D_NearestToLinear) {
  // Mailboxing is only supported for GL textures.
  if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE)
    return;

  ResourceProviderTestTextureMailboxGLFilters::RunTest(
      shared_bitmap_manager_.get(),
      gpu_memory_buffer_manager_.get(),
      main_thread_task_runner_.get(),
      true,
      GL_LINEAR);
}

TEST_P(ResourceProviderTest, TextureMailbox_GLTexture2D_LinearToNearest) {
  // Mailboxing is only supported for GL textures.
  if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE)
    return;

  ResourceProviderTestTextureMailboxGLFilters::RunTest(
      shared_bitmap_manager_.get(),
      gpu_memory_buffer_manager_.get(),
      main_thread_task_runner_.get(),
      false,
      GL_NEAREST);
}

TEST_P(ResourceProviderTest, TextureMailbox_GLTextureExternalOES) {
  // Mailboxing is only supported for GL textures.
  if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE)
    return;

  scoped_ptr<TextureStateTrackingContext> context_owned(
      new TextureStateTrackingContext);
  TextureStateTrackingContext* context = context_owned.get();

  FakeOutputSurfaceClient output_surface_client;
  scoped_ptr<OutputSurface> output_surface(
      FakeOutputSurface::Create3d(context_owned.Pass()));
  CHECK(output_surface->BindToClient(&output_surface_client));

  scoped_ptr<ResourceProvider> resource_provider(
      ResourceProvider::Create(output_surface.get(),
                               shared_bitmap_manager_.get(),
                               gpu_memory_buffer_manager_.get(),
                               NULL,
                               0,
                               false,
                               1));

  uint32 sync_point = 30;
  unsigned target = GL_TEXTURE_EXTERNAL_OES;

  EXPECT_CALL(*context, bindTexture(_, _)).Times(0);
  EXPECT_CALL(*context, waitSyncPoint(_)).Times(0);
  EXPECT_CALL(*context, insertSyncPoint()).Times(0);
  EXPECT_CALL(*context, produceTextureDirectCHROMIUM(_, _, _)).Times(0);
  EXPECT_CALL(*context, createAndConsumeTextureCHROMIUM(_, _)).Times(0);

  gpu::Mailbox gpu_mailbox;
  memcpy(gpu_mailbox.name, "Hello world", strlen("Hello world") + 1);
  scoped_ptr<SingleReleaseCallbackImpl> callback =
      SingleReleaseCallbackImpl::Create(base::Bind(&EmptyReleaseCallback));

  TextureMailbox mailbox(gpu_mailbox, target, sync_point);

  ResourceProvider::ResourceId id =
      resource_provider->CreateResourceFromTextureMailbox(
          mailbox, callback.Pass());
  EXPECT_NE(0u, id);

  Mock::VerifyAndClearExpectations(context);

  {
    // Mailbox sync point WaitSyncPoint before using the texture.
    EXPECT_CALL(*context, waitSyncPoint(sync_point));
    resource_provider->WaitSyncPointIfNeeded(id);
    Mock::VerifyAndClearExpectations(context);

    unsigned texture_id = 1;

    EXPECT_CALL(*context, createAndConsumeTextureCHROMIUM(target, _))
        .WillOnce(Return(texture_id));

    EXPECT_CALL(*context, insertSyncPoint()).Times(0);
    EXPECT_CALL(*context, produceTextureDirectCHROMIUM(_, _, _)).Times(0);

    ResourceProvider::ScopedReadLockGL lock(resource_provider.get(), id);
    Mock::VerifyAndClearExpectations(context);

    // When done with it, a sync point should be inserted, but no produce is
    // necessary.
    EXPECT_CALL(*context, bindTexture(_, _)).Times(0);
    EXPECT_CALL(*context, insertSyncPoint());
    EXPECT_CALL(*context, produceTextureDirectCHROMIUM(_, _, _)).Times(0);

    EXPECT_CALL(*context, waitSyncPoint(_)).Times(0);
    EXPECT_CALL(*context, createAndConsumeTextureCHROMIUM(_, _)).Times(0);
  }
}

TEST_P(ResourceProviderTest,
       TextureMailbox_WaitSyncPointIfNeeded_WithSyncPoint) {
  // Mailboxing is only supported for GL textures.
  if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE)
    return;

  scoped_ptr<TextureStateTrackingContext> context_owned(
      new TextureStateTrackingContext);
  TextureStateTrackingContext* context = context_owned.get();

  FakeOutputSurfaceClient output_surface_client;
  scoped_ptr<OutputSurface> output_surface(
      FakeOutputSurface::Create3d(context_owned.Pass()));
  CHECK(output_surface->BindToClient(&output_surface_client));

  scoped_ptr<ResourceProvider> resource_provider(
      ResourceProvider::Create(output_surface.get(),
                               shared_bitmap_manager_.get(),
                               gpu_memory_buffer_manager_.get(),
                               NULL,
                               0,
                               false,
                               1));

  uint32 sync_point = 30;
  unsigned target = GL_TEXTURE_2D;

  EXPECT_CALL(*context, bindTexture(_, _)).Times(0);
  EXPECT_CALL(*context, waitSyncPoint(_)).Times(0);
  EXPECT_CALL(*context, insertSyncPoint()).Times(0);
  EXPECT_CALL(*context, produceTextureDirectCHROMIUM(_, _, _)).Times(0);
  EXPECT_CALL(*context, createAndConsumeTextureCHROMIUM(_, _)).Times(0);

  gpu::Mailbox gpu_mailbox;
  memcpy(gpu_mailbox.name, "Hello world", strlen("Hello world") + 1);
  scoped_ptr<SingleReleaseCallbackImpl> callback =
      SingleReleaseCallbackImpl::Create(base::Bind(&EmptyReleaseCallback));

  TextureMailbox mailbox(gpu_mailbox, target, sync_point);

  ResourceProvider::ResourceId id =
      resource_provider->CreateResourceFromTextureMailbox(mailbox,
                                                          callback.Pass());
  EXPECT_NE(0u, id);

  Mock::VerifyAndClearExpectations(context);

  {
    // First call to WaitSyncPointIfNeeded should call waitSyncPoint.
    EXPECT_CALL(*context, waitSyncPoint(sync_point));
    resource_provider->WaitSyncPointIfNeeded(id);
    Mock::VerifyAndClearExpectations(context);

    // Subsequent calls to WaitSyncPointIfNeeded shouldn't call waitSyncPoint.
    EXPECT_CALL(*context, waitSyncPoint(_)).Times(0);
    resource_provider->WaitSyncPointIfNeeded(id);
    Mock::VerifyAndClearExpectations(context);
  }
}

TEST_P(ResourceProviderTest, TextureMailbox_WaitSyncPointIfNeeded_NoSyncPoint) {
  // Mailboxing is only supported for GL textures.
  if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE)
    return;

  scoped_ptr<TextureStateTrackingContext> context_owned(
      new TextureStateTrackingContext);
  TextureStateTrackingContext* context = context_owned.get();

  FakeOutputSurfaceClient output_surface_client;
  scoped_ptr<OutputSurface> output_surface(
      FakeOutputSurface::Create3d(context_owned.Pass()));
  CHECK(output_surface->BindToClient(&output_surface_client));

  scoped_ptr<ResourceProvider> resource_provider(
      ResourceProvider::Create(output_surface.get(),
                               shared_bitmap_manager_.get(),
                               gpu_memory_buffer_manager_.get(),
                               NULL,
                               0,
                               false,
                               1));

  uint32 sync_point = 0;
  unsigned target = GL_TEXTURE_2D;

  EXPECT_CALL(*context, bindTexture(_, _)).Times(0);
  EXPECT_CALL(*context, waitSyncPoint(_)).Times(0);
  EXPECT_CALL(*context, insertSyncPoint()).Times(0);
  EXPECT_CALL(*context, produceTextureDirectCHROMIUM(_, _, _)).Times(0);
  EXPECT_CALL(*context, createAndConsumeTextureCHROMIUM(_, _)).Times(0);

  gpu::Mailbox gpu_mailbox;
  memcpy(gpu_mailbox.name, "Hello world", strlen("Hello world") + 1);
  scoped_ptr<SingleReleaseCallbackImpl> callback =
      SingleReleaseCallbackImpl::Create(base::Bind(&EmptyReleaseCallback));

  TextureMailbox mailbox(gpu_mailbox, target, sync_point);

  ResourceProvider::ResourceId id =
      resource_provider->CreateResourceFromTextureMailbox(mailbox,
                                                          callback.Pass());
  EXPECT_NE(0u, id);

  Mock::VerifyAndClearExpectations(context);

  {
    // WaitSyncPointIfNeeded with sync_point == 0 shouldn't call waitSyncPoint.
    EXPECT_CALL(*context, waitSyncPoint(_)).Times(0);
    resource_provider->WaitSyncPointIfNeeded(id);
    Mock::VerifyAndClearExpectations(context);
  }
}

class AllocationTrackingContext3D : public TestWebGraphicsContext3D {
 public:
  MOCK_METHOD0(NextTextureId, GLuint());
  MOCK_METHOD1(RetireTextureId, void(GLuint id));
  MOCK_METHOD2(bindTexture, void(GLenum target, GLuint texture));
  MOCK_METHOD5(texStorage2DEXT,
               void(GLenum target,
                    GLint levels,
                    GLuint internalformat,
                    GLint width,
                    GLint height));
  MOCK_METHOD9(texImage2D,
               void(GLenum target,
                    GLint level,
                    GLenum internalformat,
                    GLsizei width,
                    GLsizei height,
                    GLint border,
                    GLenum format,
                    GLenum type,
                    const void* pixels));
  MOCK_METHOD9(texSubImage2D,
               void(GLenum target,
                    GLint level,
                    GLint xoffset,
                    GLint yoffset,
                    GLsizei width,
                    GLsizei height,
                    GLenum format,
                    GLenum type,
                    const void* pixels));
  MOCK_METHOD9(asyncTexImage2DCHROMIUM,
               void(GLenum target,
                    GLint level,
                    GLenum internalformat,
                    GLsizei width,
                    GLsizei height,
                    GLint border,
                    GLenum format,
                    GLenum type,
                    const void* pixels));
  MOCK_METHOD9(asyncTexSubImage2DCHROMIUM,
               void(GLenum target,
                    GLint level,
                    GLint xoffset,
                    GLint yoffset,
                    GLsizei width,
                    GLsizei height,
                    GLenum format,
                    GLenum type,
                    const void* pixels));
  MOCK_METHOD8(compressedTexImage2D,
               void(GLenum target,
                    GLint level,
                    GLenum internalformat,
                    GLsizei width,
                    GLsizei height,
                    GLint border,
                    GLsizei image_size,
                    const void* data));
  MOCK_METHOD1(waitAsyncTexImage2DCHROMIUM, void(GLenum));
  MOCK_METHOD4(createImageCHROMIUM,
               GLuint(ClientBuffer, GLsizei, GLsizei, GLenum));
  MOCK_METHOD1(destroyImageCHROMIUM, void(GLuint));
  MOCK_METHOD2(bindTexImage2DCHROMIUM, void(GLenum, GLint));
  MOCK_METHOD2(releaseTexImage2DCHROMIUM, void(GLenum, GLint));

  // We're mocking bindTexture, so we override
  // TestWebGraphicsContext3D::texParameteri to avoid assertions related to the
  // currently bound texture.
  virtual void texParameteri(GLenum target, GLenum pname, GLint param) {}
};

TEST_P(ResourceProviderTest, TextureAllocation) {
  // Only for GL textures.
  if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE)
    return;
  scoped_ptr<AllocationTrackingContext3D> context_owned(
      new StrictMock<AllocationTrackingContext3D>);
  AllocationTrackingContext3D* context = context_owned.get();

  FakeOutputSurfaceClient output_surface_client;
  scoped_ptr<OutputSurface> output_surface(
      FakeOutputSurface::Create3d(context_owned.Pass()));
  CHECK(output_surface->BindToClient(&output_surface_client));

  scoped_ptr<ResourceProvider> resource_provider(
      ResourceProvider::Create(output_surface.get(),
                               shared_bitmap_manager_.get(),
                               gpu_memory_buffer_manager_.get(),
                               NULL,
                               0,
                               false,
                               1));

  gfx::Size size(2, 2);
  gfx::Vector2d offset(0, 0);
  ResourceFormat format = RGBA_8888;
  ResourceProvider::ResourceId id = 0;
  uint8_t pixels[16] = { 0 };
  int texture_id = 123;

  // Lazy allocation. Don't allocate when creating the resource.
  id = resource_provider->CreateResource(
      size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);

  EXPECT_CALL(*context, NextTextureId()).WillOnce(Return(texture_id));
  EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id)).Times(1);
  resource_provider->CreateForTesting(id);

  EXPECT_CALL(*context, RetireTextureId(texture_id)).Times(1);
  resource_provider->DeleteResource(id);

  Mock::VerifyAndClearExpectations(context);

  // Do allocate when we set the pixels.
  id = resource_provider->CreateResource(
      size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);

  EXPECT_CALL(*context, NextTextureId()).WillOnce(Return(texture_id));
  EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id)).Times(3);
  EXPECT_CALL(*context, texImage2D(_, _, _, 2, 2, _, _, _, _)).Times(1);
  EXPECT_CALL(*context, texSubImage2D(_, _, _, _, 2, 2, _, _, _)).Times(1);
  resource_provider->CopyToResource(id, pixels, size);

  EXPECT_CALL(*context, RetireTextureId(texture_id)).Times(1);
  resource_provider->DeleteResource(id);

  Mock::VerifyAndClearExpectations(context);

  // Same for async version.
  id = resource_provider->CreateResource(
      size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);
  resource_provider->AcquirePixelBuffer(id);

  EXPECT_CALL(*context, NextTextureId()).WillOnce(Return(texture_id));
  EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id)).Times(2);
  EXPECT_CALL(*context, asyncTexImage2DCHROMIUM(_, _, _, 2, 2, _, _, _, _))
      .Times(1);
  resource_provider->BeginSetPixels(id);
  ASSERT_TRUE(resource_provider->DidSetPixelsComplete(id));

  resource_provider->ReleasePixelBuffer(id);

  EXPECT_CALL(*context, RetireTextureId(texture_id)).Times(1);
  resource_provider->DeleteResource(id);

  Mock::VerifyAndClearExpectations(context);
}

TEST_P(ResourceProviderTest, TextureAllocationHint) {
  // Only for GL textures.
  if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE)
    return;
  scoped_ptr<AllocationTrackingContext3D> context_owned(
      new StrictMock<AllocationTrackingContext3D>);
  AllocationTrackingContext3D* context = context_owned.get();
  context->set_support_texture_storage(true);
  context->set_support_texture_usage(true);

  FakeOutputSurfaceClient output_surface_client;
  scoped_ptr<OutputSurface> output_surface(
      FakeOutputSurface::Create3d(context_owned.Pass()));
  CHECK(output_surface->BindToClient(&output_surface_client));

  scoped_ptr<ResourceProvider> resource_provider(
      ResourceProvider::Create(output_surface.get(),
                               shared_bitmap_manager_.get(),
                               gpu_memory_buffer_manager_.get(),
                               NULL,
                               0,
                               false,
                               1));

  gfx::Size size(2, 2);

  const ResourceFormat formats[2] = {RGBA_8888, BGRA_8888};
  const ResourceProvider::TextureHint hints[4] = {
      ResourceProvider::TEXTURE_HINT_DEFAULT,
      ResourceProvider::TEXTURE_HINT_IMMUTABLE,
      ResourceProvider::TEXTURE_HINT_FRAMEBUFFER,
      ResourceProvider::TEXTURE_HINT_IMMUTABLE_FRAMEBUFFER,
  };
  for (size_t i = 0; i < arraysize(formats); ++i) {
    for (GLuint texture_id = 1; texture_id <= arraysize(hints); ++texture_id) {
      // Lazy allocation. Don't allocate when creating the resource.
      ResourceProvider::ResourceId id = resource_provider->CreateResource(
          size, GL_CLAMP_TO_EDGE, hints[texture_id - 1], formats[i]);

      EXPECT_CALL(*context, NextTextureId()).WillOnce(Return(texture_id));
      EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id)).Times(2);
      bool is_immutable_hint =
          hints[texture_id - 1] & ResourceProvider::TEXTURE_HINT_IMMUTABLE;
      bool support_immutable_texture =
          is_immutable_hint && formats[i] == RGBA_8888;
      EXPECT_CALL(*context, texStorage2DEXT(_, _, _, 2, 2))
          .Times(support_immutable_texture ? 1 : 0);
      EXPECT_CALL(*context, texImage2D(_, _, _, 2, 2, _, _, _, _))
          .Times(support_immutable_texture ? 0 : 1);
      resource_provider->AllocateForTesting(id);

      EXPECT_CALL(*context, RetireTextureId(texture_id)).Times(1);
      resource_provider->DeleteResource(id);

      Mock::VerifyAndClearExpectations(context);
    }
  }
}

TEST_P(ResourceProviderTest, TextureAllocationHint_BGRA) {
  // Only for GL textures.
  if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE)
    return;
  scoped_ptr<AllocationTrackingContext3D> context_owned(
      new StrictMock<AllocationTrackingContext3D>);
  AllocationTrackingContext3D* context = context_owned.get();
  context->set_support_texture_format_bgra8888(true);
  context->set_support_texture_storage(true);
  context->set_support_texture_usage(true);

  FakeOutputSurfaceClient output_surface_client;
  scoped_ptr<OutputSurface> output_surface(
      FakeOutputSurface::Create3d(context_owned.Pass()));
  CHECK(output_surface->BindToClient(&output_surface_client));

  scoped_ptr<ResourceProvider> resource_provider(
      ResourceProvider::Create(output_surface.get(),
                               shared_bitmap_manager_.get(),
                               gpu_memory_buffer_manager_.get(),
                               NULL,
                               0,
                               false,
                               1));

  gfx::Size size(2, 2);
  const ResourceFormat formats[2] = {RGBA_8888, BGRA_8888};

  const ResourceProvider::TextureHint hints[4] = {
      ResourceProvider::TEXTURE_HINT_DEFAULT,
      ResourceProvider::TEXTURE_HINT_IMMUTABLE,
      ResourceProvider::TEXTURE_HINT_FRAMEBUFFER,
      ResourceProvider::TEXTURE_HINT_IMMUTABLE_FRAMEBUFFER,
  };
  for (size_t i = 0; i < arraysize(formats); ++i) {
    for (GLuint texture_id = 1; texture_id <= arraysize(hints); ++texture_id) {
      // Lazy allocation. Don't allocate when creating the resource.
      ResourceProvider::ResourceId id = resource_provider->CreateResource(
          size, GL_CLAMP_TO_EDGE, hints[texture_id - 1], formats[i]);

      EXPECT_CALL(*context, NextTextureId()).WillOnce(Return(texture_id));
      EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id)).Times(2);
      bool is_immutable_hint =
          hints[texture_id - 1] & ResourceProvider::TEXTURE_HINT_IMMUTABLE;
      EXPECT_CALL(*context, texStorage2DEXT(_, _, _, 2, 2))
          .Times(is_immutable_hint ? 1 : 0);
      EXPECT_CALL(*context, texImage2D(_, _, _, 2, 2, _, _, _, _))
          .Times(is_immutable_hint ? 0 : 1);
      resource_provider->AllocateForTesting(id);

      EXPECT_CALL(*context, RetireTextureId(texture_id)).Times(1);
      resource_provider->DeleteResource(id);

      Mock::VerifyAndClearExpectations(context);
    }
  }
}

TEST_P(ResourceProviderTest, PixelBuffer_GLTexture) {
  if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE)
    return;
  scoped_ptr<AllocationTrackingContext3D> context_owned(
      new StrictMock<AllocationTrackingContext3D>);
  AllocationTrackingContext3D* context = context_owned.get();

  FakeOutputSurfaceClient output_surface_client;
  scoped_ptr<OutputSurface> output_surface(
      FakeOutputSurface::Create3d(context_owned.Pass()));
  CHECK(output_surface->BindToClient(&output_surface_client));

  gfx::Size size(2, 2);
  ResourceFormat format = RGBA_8888;
  ResourceProvider::ResourceId id = 0;
  int texture_id = 123;

  scoped_ptr<ResourceProvider> resource_provider(
      ResourceProvider::Create(output_surface.get(),
                               shared_bitmap_manager_.get(),
                               gpu_memory_buffer_manager_.get(),
                               NULL,
                               0,
                               false,
                               1));

  id = resource_provider->CreateResource(
      size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);
  resource_provider->AcquirePixelBuffer(id);

  EXPECT_CALL(*context, NextTextureId()).WillOnce(Return(texture_id));
  EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id)).Times(2);
  EXPECT_CALL(*context, asyncTexImage2DCHROMIUM(_, _, _, 2, 2, _, _, _, _))
      .Times(1);
  resource_provider->BeginSetPixels(id);

  EXPECT_TRUE(resource_provider->DidSetPixelsComplete(id));

  resource_provider->ReleasePixelBuffer(id);

  EXPECT_CALL(*context, RetireTextureId(texture_id)).Times(1);
  resource_provider->DeleteResource(id);

  Mock::VerifyAndClearExpectations(context);
}

TEST_P(ResourceProviderTest, ForcingAsyncUploadToComplete) {
  // Only for GL textures.
  if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE)
    return;
  scoped_ptr<AllocationTrackingContext3D> context_owned(
      new StrictMock<AllocationTrackingContext3D>);
  AllocationTrackingContext3D* context = context_owned.get();

  FakeOutputSurfaceClient output_surface_client;
  scoped_ptr<OutputSurface> output_surface(
      FakeOutputSurface::Create3d(context_owned.Pass()));
  CHECK(output_surface->BindToClient(&output_surface_client));

  gfx::Size size(2, 2);
  ResourceFormat format = RGBA_8888;
  ResourceProvider::ResourceId id = 0;
  int texture_id = 123;

  scoped_ptr<ResourceProvider> resource_provider(
      ResourceProvider::Create(output_surface.get(),
                               shared_bitmap_manager_.get(),
                               gpu_memory_buffer_manager_.get(),
                               NULL,
                               0,
                               false,
                               1));

  id = resource_provider->CreateResource(
      size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);
  resource_provider->AcquirePixelBuffer(id);

  EXPECT_CALL(*context, NextTextureId()).WillOnce(Return(texture_id));
  EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id)).Times(2);
  EXPECT_CALL(*context, asyncTexImage2DCHROMIUM(_, _, _, 2, 2, _, _, _, _))
      .Times(1);
  resource_provider->BeginSetPixels(id);

  EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id)).Times(1);
  EXPECT_CALL(*context, waitAsyncTexImage2DCHROMIUM(GL_TEXTURE_2D)).Times(1);
  EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, 0)).Times(1);
  resource_provider->ForceSetPixelsToComplete(id);

  resource_provider->ReleasePixelBuffer(id);

  EXPECT_CALL(*context, RetireTextureId(texture_id)).Times(1);
  resource_provider->DeleteResource(id);

  Mock::VerifyAndClearExpectations(context);
}

TEST_P(ResourceProviderTest, PixelBufferLostContext) {
  scoped_ptr<AllocationTrackingContext3D> context_owned(
      new NiceMock<AllocationTrackingContext3D>);
  AllocationTrackingContext3D* context = context_owned.get();

  FakeOutputSurfaceClient output_surface_client;
  scoped_ptr<OutputSurface> output_surface(
      FakeOutputSurface::Create3d(context_owned.Pass()));
  CHECK(output_surface->BindToClient(&output_surface_client));

  gfx::Size size(2, 2);
  ResourceFormat format = RGBA_8888;
  ResourceProvider::ResourceId id = 0;
  int texture_id = 123;

  scoped_ptr<ResourceProvider> resource_provider(
      ResourceProvider::Create(output_surface.get(),
                               shared_bitmap_manager_.get(),
                               gpu_memory_buffer_manager_.get(),
                               NULL,
                               0,
                               false,
                               1));

  EXPECT_CALL(*context, NextTextureId()).WillRepeatedly(Return(texture_id));

  id = resource_provider->CreateResource(
      size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);
  context->loseContextCHROMIUM(GL_GUILTY_CONTEXT_RESET_ARB,
                               GL_INNOCENT_CONTEXT_RESET_ARB);

  resource_provider->AcquirePixelBuffer(id);
  int stride;
  void* buffer = resource_provider->MapPixelBuffer(id, &stride);
  EXPECT_FALSE(buffer);
  resource_provider->UnmapPixelBuffer(id);
  Mock::VerifyAndClearExpectations(context);
}

TEST_P(ResourceProviderTest, Image_GLTexture) {
  // Only for GL textures.
  if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE)
    return;
  scoped_ptr<AllocationTrackingContext3D> context_owned(
      new StrictMock<AllocationTrackingContext3D>);
  AllocationTrackingContext3D* context = context_owned.get();

  FakeOutputSurfaceClient output_surface_client;
  scoped_ptr<OutputSurface> output_surface(
      FakeOutputSurface::Create3d(context_owned.Pass()));
  CHECK(output_surface->BindToClient(&output_surface_client));

  const int kWidth = 2;
  const int kHeight = 2;
  gfx::Size size(kWidth, kHeight);
  ResourceFormat format = RGBA_8888;
  ResourceProvider::ResourceId id = 0;
  const unsigned kTextureId = 123u;
  const unsigned kImageId = 234u;

  scoped_ptr<ResourceProvider> resource_provider(
      ResourceProvider::Create(output_surface.get(),
                               shared_bitmap_manager_.get(),
                               gpu_memory_buffer_manager_.get(),
                               NULL,
                               0,
                               false,
                               1));

  id = resource_provider->CreateResource(
      size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);

  EXPECT_CALL(*context, createImageCHROMIUM(_, kWidth, kHeight, GL_RGBA))
      .WillOnce(Return(kImageId))
      .RetiresOnSaturation();
  {
    ResourceProvider::ScopedWriteLockGpuMemoryBuffer lock(
        resource_provider.get(), id);
    EXPECT_TRUE(!!lock.GetGpuMemoryBuffer());
  }

  EXPECT_CALL(*context, NextTextureId())
      .WillOnce(Return(kTextureId))
      .RetiresOnSaturation();
  // Once in CreateTextureId and once in BindForSampling
  EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, kTextureId)).Times(2)
      .RetiresOnSaturation();
  EXPECT_CALL(*context, bindTexImage2DCHROMIUM(GL_TEXTURE_2D, kImageId))
      .Times(1)
      .RetiresOnSaturation();
  {
    ResourceProvider::ScopedSamplerGL lock_gl(
        resource_provider.get(), id, GL_TEXTURE_2D, GL_LINEAR);
    EXPECT_EQ(kTextureId, lock_gl.texture_id());
  }

  {
    ResourceProvider::ScopedWriteLockGpuMemoryBuffer lock(
        resource_provider.get(), id);
    EXPECT_TRUE(!!lock.GetGpuMemoryBuffer());
  }

  EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, kTextureId)).Times(1)
      .RetiresOnSaturation();
  EXPECT_CALL(*context, releaseTexImage2DCHROMIUM(GL_TEXTURE_2D, kImageId))
      .Times(1)
      .RetiresOnSaturation();
  EXPECT_CALL(*context, bindTexImage2DCHROMIUM(GL_TEXTURE_2D, kImageId))
      .Times(1)
      .RetiresOnSaturation();
  EXPECT_CALL(*context, RetireTextureId(kTextureId))
      .Times(1)
      .RetiresOnSaturation();
  {
    ResourceProvider::ScopedSamplerGL lock_gl(
        resource_provider.get(), id, GL_TEXTURE_2D, GL_LINEAR);
    EXPECT_EQ(kTextureId, lock_gl.texture_id());
  }

  EXPECT_CALL(*context, destroyImageCHROMIUM(kImageId))
      .Times(1)
      .RetiresOnSaturation();
}

TEST_P(ResourceProviderTest, CopyResource_GLTexture) {
  if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE)
    return;
  scoped_ptr<AllocationTrackingContext3D> context_owned(
      new StrictMock<AllocationTrackingContext3D>);
  AllocationTrackingContext3D* context = context_owned.get();
  context_owned->set_support_sync_query(true);

  FakeOutputSurfaceClient output_surface_client;
  scoped_ptr<OutputSurface> output_surface(
      FakeOutputSurface::Create3d(context_owned.Pass()));
  ASSERT_TRUE(output_surface->BindToClient(&output_surface_client));

  const int kWidth = 2;
  const int kHeight = 2;
  gfx::Size size(kWidth, kHeight);
  ResourceFormat format = RGBA_8888;
  ResourceProvider::ResourceId source_id = 0;
  ResourceProvider::ResourceId dest_id = 0;
  const unsigned kSourceTextureId = 123u;
  const unsigned kDestTextureId = 321u;
  const unsigned kImageId = 234u;

  scoped_ptr<ResourceProvider> resource_provider(
      ResourceProvider::Create(output_surface.get(),
                               shared_bitmap_manager_.get(),
                               gpu_memory_buffer_manager_.get(),
                               NULL,
                               0,
                               false,
                               1));

  source_id = resource_provider->CreateResource(
      size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);

  EXPECT_CALL(*context, createImageCHROMIUM(_, kWidth, kHeight, GL_RGBA))
      .WillOnce(Return(kImageId))
      .RetiresOnSaturation();
  {
    ResourceProvider::ScopedWriteLockGpuMemoryBuffer lock(
        resource_provider.get(), source_id);
    EXPECT_TRUE(!!lock.GetGpuMemoryBuffer());
  }
  Mock::VerifyAndClearExpectations(context);

  dest_id = resource_provider->CreateResource(
      size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);

  EXPECT_CALL(*context, NextTextureId())
      .WillOnce(Return(kDestTextureId))
      .RetiresOnSaturation();
  EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, kDestTextureId))
      .Times(2)
      .RetiresOnSaturation();
  EXPECT_CALL(*context, texImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA,
                                   GL_UNSIGNED_BYTE, nullptr))
      .Times(1)
      .RetiresOnSaturation();
  EXPECT_CALL(*context, NextTextureId())
      .WillOnce(Return(kSourceTextureId))
      .RetiresOnSaturation();
  EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, kSourceTextureId))
      .Times(2)
      .RetiresOnSaturation();
  EXPECT_CALL(*context, bindTexImage2DCHROMIUM(GL_TEXTURE_2D, kImageId))
      .Times(1)
      .RetiresOnSaturation();
  resource_provider->CopyResource(source_id, dest_id);
  Mock::VerifyAndClearExpectations(context);

  EXPECT_CALL(*context, destroyImageCHROMIUM(kImageId))
      .Times(1)
      .RetiresOnSaturation();
  EXPECT_CALL(*context, RetireTextureId(kSourceTextureId))
      .Times(1)
      .RetiresOnSaturation();
  EXPECT_CALL(*context, RetireTextureId(kDestTextureId))
      .Times(1)
      .RetiresOnSaturation();
  resource_provider->DeleteResource(source_id);
  resource_provider->DeleteResource(dest_id);
}

void InitializeGLAndCheck(ContextSharedData* shared_data,
                          ResourceProvider* resource_provider,
                          FakeOutputSurface* output_surface) {
  scoped_ptr<ResourceProviderContext> context_owned =
      ResourceProviderContext::Create(shared_data);
  ResourceProviderContext* context = context_owned.get();

  scoped_refptr<TestContextProvider> context_provider =
      TestContextProvider::Create(context_owned.Pass());
  output_surface->InitializeAndSetContext3d(context_provider, nullptr);
  resource_provider->InitializeGL();

  CheckCreateResource(ResourceProvider::RESOURCE_TYPE_GL_TEXTURE,
                      resource_provider, context);
}

TEST(ResourceProviderTest, BasicInitializeGLSoftware) {
  scoped_ptr<ContextSharedData> shared_data = ContextSharedData::Create();
  bool delegated_rendering = false;
  scoped_ptr<FakeOutputSurface> output_surface(
      FakeOutputSurface::CreateDeferredGL(
          scoped_ptr<SoftwareOutputDevice>(new SoftwareOutputDevice),
          delegated_rendering));
  FakeOutputSurfaceClient client(output_surface.get());
  EXPECT_TRUE(output_surface->BindToClient(&client));
  scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
      new TestSharedBitmapManager());
  scoped_ptr<ResourceProvider> resource_provider(
      ResourceProvider::Create(output_surface.get(),
                               shared_bitmap_manager.get(),
                               NULL,
                               NULL,
                               0,
                               false,
                               1));

  CheckCreateResource(ResourceProvider::RESOURCE_TYPE_BITMAP,
                      resource_provider.get(), NULL);

  InitializeGLAndCheck(shared_data.get(),
                       resource_provider.get(),
                       output_surface.get());

  resource_provider->InitializeSoftware();
  output_surface->ReleaseGL();
  CheckCreateResource(ResourceProvider::RESOURCE_TYPE_BITMAP,
                      resource_provider.get(), NULL);

  InitializeGLAndCheck(shared_data.get(),
                       resource_provider.get(),
                       output_surface.get());
}

TEST_P(ResourceProviderTest, CompressedTextureETC1Allocate) {
  if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE)
    return;

  scoped_ptr<AllocationTrackingContext3D> context_owned(
      new AllocationTrackingContext3D);
  AllocationTrackingContext3D* context = context_owned.get();
  context_owned->set_support_compressed_texture_etc1(true);

  FakeOutputSurfaceClient output_surface_client;
  scoped_ptr<OutputSurface> output_surface(
      FakeOutputSurface::Create3d(context_owned.Pass()));
  CHECK(output_surface->BindToClient(&output_surface_client));

  gfx::Size size(4, 4);
  scoped_ptr<ResourceProvider> resource_provider(
      ResourceProvider::Create(output_surface.get(),
                               shared_bitmap_manager_.get(),
                               gpu_memory_buffer_manager_.get(),
                               NULL,
                               0,
                               false,
                               1));
  int texture_id = 123;

  ResourceProvider::ResourceId id = resource_provider->CreateResource(
      size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, ETC1);
  EXPECT_NE(0u, id);
  EXPECT_CALL(*context, NextTextureId()).WillOnce(Return(texture_id));
  EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id)).Times(2);
  resource_provider->AllocateForTesting(id);

  EXPECT_CALL(*context, RetireTextureId(texture_id)).Times(1);
  resource_provider->DeleteResource(id);
}

TEST_P(ResourceProviderTest, CompressedTextureETC1Upload) {
  if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE)
    return;

  scoped_ptr<AllocationTrackingContext3D> context_owned(
      new AllocationTrackingContext3D);
  AllocationTrackingContext3D* context = context_owned.get();
  context_owned->set_support_compressed_texture_etc1(true);

  FakeOutputSurfaceClient output_surface_client;
  scoped_ptr<OutputSurface> output_surface(
      FakeOutputSurface::Create3d(context_owned.Pass()));
  CHECK(output_surface->BindToClient(&output_surface_client));

  gfx::Size size(4, 4);
  scoped_ptr<ResourceProvider> resource_provider(
      ResourceProvider::Create(output_surface.get(),
                               shared_bitmap_manager_.get(),
                               gpu_memory_buffer_manager_.get(),
                               NULL,
                               0,
                               false,
                               1));
  int texture_id = 123;
  uint8_t pixels[8];

  ResourceProvider::ResourceId id = resource_provider->CreateResource(
      size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, ETC1);
  EXPECT_NE(0u, id);
  EXPECT_CALL(*context, NextTextureId()).WillOnce(Return(texture_id));
  EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id)).Times(3);
  EXPECT_CALL(*context,
              compressedTexImage2D(
                  _, 0, _, size.width(), size.height(), _, _, _)).Times(1);
  resource_provider->CopyToResource(id, pixels, size);

  EXPECT_CALL(*context, RetireTextureId(texture_id)).Times(1);
  resource_provider->DeleteResource(id);
}

INSTANTIATE_TEST_CASE_P(
    ResourceProviderTests,
    ResourceProviderTest,
    ::testing::Values(ResourceProvider::RESOURCE_TYPE_GL_TEXTURE,
                      ResourceProvider::RESOURCE_TYPE_BITMAP));

class TextureIdAllocationTrackingContext : public TestWebGraphicsContext3D {
 public:
  GLuint NextTextureId() override {
    base::AutoLock lock(namespace_->lock);
    return namespace_->next_texture_id++;
  }
  void RetireTextureId(GLuint) override {}
  GLuint PeekTextureId() {
    base::AutoLock lock(namespace_->lock);
    return namespace_->next_texture_id;
  }
};

TEST(ResourceProviderTest, TextureAllocationChunkSize) {
  scoped_ptr<TextureIdAllocationTrackingContext> context_owned(
      new TextureIdAllocationTrackingContext);
  TextureIdAllocationTrackingContext* context = context_owned.get();

  FakeOutputSurfaceClient output_surface_client;
  scoped_ptr<OutputSurface> output_surface(
      FakeOutputSurface::Create3d(context_owned.Pass()));
  CHECK(output_surface->BindToClient(&output_surface_client));
  scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
      new TestSharedBitmapManager());

  gfx::Size size(1, 1);
  ResourceFormat format = RGBA_8888;

  {
    size_t kTextureAllocationChunkSize = 1;
    scoped_ptr<ResourceProvider> resource_provider(
        ResourceProvider::Create(output_surface.get(),
                                 shared_bitmap_manager.get(),
                                 NULL,
                                 NULL,
                                 0,
                                 false,
                                 kTextureAllocationChunkSize));

    ResourceProvider::ResourceId id = resource_provider->CreateResource(
        size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE,
        format);
    resource_provider->AllocateForTesting(id);
    Mock::VerifyAndClearExpectations(context);

    DCHECK_EQ(2u, context->PeekTextureId());
    resource_provider->DeleteResource(id);
  }

  {
    size_t kTextureAllocationChunkSize = 8;
    scoped_ptr<ResourceProvider> resource_provider(
        ResourceProvider::Create(output_surface.get(),
                                 shared_bitmap_manager.get(),
                                 NULL,
                                 NULL,
                                 0,
                                 false,
                                 kTextureAllocationChunkSize));

    ResourceProvider::ResourceId id = resource_provider->CreateResource(
        size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE,
        format);
    resource_provider->AllocateForTesting(id);
    Mock::VerifyAndClearExpectations(context);

    DCHECK_EQ(10u, context->PeekTextureId());
    resource_provider->DeleteResource(id);
  }
}

}  // namespace
}  // namespace cc
