12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright 2012 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/resources/resource_provider.h"
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <algorithm>
80f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include <map>
923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include <set>
10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/bind.h"
127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/containers/hash_tables.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/logging.h"
147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/memory/ref_counted.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/base/scoped_ptr_deque.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/output/output_surface.h"
173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "cc/resources/returned_resource.h"
181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "cc/resources/shared_bitmap_manager.h"
19d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "cc/resources/single_release_callback.h"
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/test/fake_output_surface.h"
217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "cc/test/fake_output_surface_client.h"
2223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "cc/test/test_shared_bitmap_manager.h"
230f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "cc/test/test_texture.h"
240f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "cc/test/test_web_graphics_context_3d.h"
251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "cc/trees/blocking_task_runner.h"
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "gpu/GLES2/gl2extchromium.h"
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "testing/gmock/include/gmock/gmock.h"
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "third_party/khronos/GLES2/gl2.h"
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "third_party/khronos/GLES2/gl2ext.h"
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/rect.h"
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using testing::Mock;
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using testing::NiceMock;
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using testing::Return;
3690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)using testing::SetArgPointee;
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using testing::StrictMock;
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using testing::_;
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace cc {
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccistatic void EmptyReleaseCallback(uint32 sync_point,
441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                 bool lost_resource,
451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                 BlockingTaskRunner* main_thread_task_runner) {
461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccistatic void ReleaseCallback(
491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    uint32* release_sync_point,
501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    bool* release_lost_resource,
511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    BlockingTaskRunner** release_main_thread_task_runner,
521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    uint32 sync_point,
531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    bool lost_resource,
541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    BlockingTaskRunner* main_thread_task_runner) {
551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  *release_sync_point = sync_point;
561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  *release_lost_resource = lost_resource;
571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  *release_main_thread_task_runner = main_thread_task_runner;
581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccistatic void SharedMemoryReleaseCallback(
611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    scoped_ptr<base::SharedMemory> memory,
621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    uint32 sync_point,
631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    bool lost_resource,
641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    BlockingTaskRunner* main_thread_task_runner) {
651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)static void ReleaseSharedMemoryCallback(
681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    scoped_ptr<base::SharedMemory> shared_memory,
691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    bool* release_called,
705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    uint32* release_sync_point,
711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    bool* lost_resource_result,
725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    uint32 sync_point,
731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    bool lost_resource,
741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    BlockingTaskRunner* main_thread_task_runner) {
751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  *release_called = true;
761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  *release_sync_point = sync_point;
771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  *lost_resource_result = lost_resource;
781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)static scoped_ptr<base::SharedMemory> CreateAndFillSharedMemory(
815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const gfx::Size& size,
821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    uint32_t value) {
831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  scoped_ptr<base::SharedMemory> shared_memory(new base::SharedMemory);
841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  CHECK(shared_memory->CreateAndMapAnonymous(4 * size.GetArea()));
851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  uint32_t* pixels = reinterpret_cast<uint32_t*>(shared_memory->memory());
861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  CHECK(pixels);
871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  std::fill_n(pixels, size.GetArea(), value);
881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  return shared_memory.Pass();
891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
91d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)class TextureStateTrackingContext : public TestWebGraphicsContext3D {
92d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) public:
93a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  MOCK_METHOD2(bindTexture, void(GLenum target, GLuint texture));
94a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  MOCK_METHOD3(texParameteri, void(GLenum target, GLenum pname, GLint param));
955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  MOCK_METHOD1(waitSyncPoint, void(GLuint sync_point));
965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  MOCK_METHOD0(insertSyncPoint, GLuint(void));
97a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  MOCK_METHOD2(produceTextureCHROMIUM,
98a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)               void(GLenum target, const GLbyte* mailbox));
99a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  MOCK_METHOD2(consumeTextureCHROMIUM,
100a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)               void(GLenum target, const GLbyte* mailbox));
101d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
1024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Force all textures to be consecutive numbers starting at "1",
1034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // so we easily can test for them.
104a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual GLuint NextTextureId() OVERRIDE {
1054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    base::AutoLock lock(namespace_->lock);
1064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return namespace_->next_texture_id++;
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
108a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual void RetireTextureId(GLuint) OVERRIDE {}
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Shared data between multiple ResourceProviderContext. This contains mailbox
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// contents as well as information about sync points.
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class ContextSharedData {
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static scoped_ptr<ContextSharedData> Create() {
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return make_scoped_ptr(new ContextSharedData());
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  uint32 InsertSyncPoint() { return next_sync_point_++; }
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
121a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void GenMailbox(GLbyte* mailbox) {
1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    memset(mailbox, 0, GL_MAILBOX_SIZE_CHROMIUM);
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    memcpy(mailbox, &next_mailbox_, sizeof(next_mailbox_));
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ++next_mailbox_;
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
127a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void ProduceTexture(const GLbyte* mailbox_name,
1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                      uint32 sync_point,
1294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                      scoped_refptr<TestTexture> texture) {
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    unsigned mailbox = 0;
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    memcpy(&mailbox, mailbox_name, sizeof(mailbox));
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_TRUE(mailbox && mailbox < next_mailbox_);
1337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    textures_[mailbox] = texture;
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_LT(sync_point_for_mailbox_[mailbox], sync_point);
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    sync_point_for_mailbox_[mailbox] = sync_point;
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
138a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  scoped_refptr<TestTexture> ConsumeTexture(const GLbyte* mailbox_name,
1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                            uint32 sync_point) {
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    unsigned mailbox = 0;
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    memcpy(&mailbox, mailbox_name, sizeof(mailbox));
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK(mailbox && mailbox < next_mailbox_);
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // If the latest sync point the context has waited on is before the sync
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // point for when the mailbox was set, pretend we never saw that
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // ProduceTexture.
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (sync_point_for_mailbox_[mailbox] > sync_point) {
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      NOTREACHED();
1494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      return scoped_refptr<TestTexture>();
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
1517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return textures_[mailbox];
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ContextSharedData() : next_sync_point_(1), next_mailbox_(1) {}
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  uint32 next_sync_point_;
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  unsigned next_mailbox_;
1594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  typedef base::hash_map<unsigned, scoped_refptr<TestTexture> > TextureMap;
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TextureMap textures_;
1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::hash_map<unsigned, uint32> sync_point_for_mailbox_;
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class ResourceProviderContext : public TestWebGraphicsContext3D {
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static scoped_ptr<ResourceProviderContext> Create(
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ContextSharedData* shared_data) {
1688bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return make_scoped_ptr(new ResourceProviderContext(shared_data));
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual GLuint insertSyncPoint() OVERRIDE {
1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    uint32 sync_point = shared_data_->InsertSyncPoint();
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Commit the produceTextureCHROMIUM calls at this point, so that
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // they're associated with the sync point.
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (PendingProduceTextureList::iterator it =
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)             pending_produce_textures_.begin();
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         it != pending_produce_textures_.end();
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         ++it) {
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      shared_data_->ProduceTexture(
1807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          (*it)->mailbox, sync_point, (*it)->texture);
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    pending_produce_textures_.clear();
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return sync_point;
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void waitSyncPoint(GLuint sync_point) OVERRIDE {
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    last_waited_sync_point_ = std::max(sync_point, last_waited_sync_point_);
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  unsigned last_waited_sync_point() const { return last_waited_sync_point_; }
1915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
192a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual void texStorage2DEXT(GLenum target,
193a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                               GLint levels,
194a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                               GLuint internalformat,
195a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                               GLint width,
196a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                               GLint height) OVERRIDE {
1974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    CheckTextureIsBound(target);
198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ASSERT_EQ(static_cast<unsigned>(GL_TEXTURE_2D), target);
199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ASSERT_EQ(1, levels);
200a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLenum format = GL_RGBA;
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    switch (internalformat) {
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case GL_RGBA8_OES:
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        break;
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case GL_BGRA8_EXT:
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        format = GL_BGRA_EXT;
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        break;
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      default:
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        NOTREACHED();
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    AllocateTexture(gfx::Size(width, height), format);
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
213a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual void texImage2D(GLenum target,
214a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                          GLint level,
215a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                          GLenum internalformat,
216a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                          GLsizei width,
217a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                          GLsizei height,
218a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                          GLint border,
219a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                          GLenum format,
220a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                          GLenum type,
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          const void* pixels) OVERRIDE {
2224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    CheckTextureIsBound(target);
223c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ASSERT_EQ(static_cast<unsigned>(GL_TEXTURE_2D), target);
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_FALSE(level);
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_EQ(internalformat, format);
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_FALSE(border);
227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ASSERT_EQ(static_cast<unsigned>(GL_UNSIGNED_BYTE), type);
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    AllocateTexture(gfx::Size(width, height), format);
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (pixels)
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      SetPixels(0, 0, width, height, pixels);
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
233a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual void texSubImage2D(GLenum target,
234a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                             GLint level,
235a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                             GLint xoffset,
236a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                             GLint yoffset,
237a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                             GLsizei width,
238a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                             GLsizei height,
239a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                             GLenum format,
240a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                             GLenum type,
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             const void* pixels) OVERRIDE {
2424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    CheckTextureIsBound(target);
243c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ASSERT_EQ(static_cast<unsigned>(GL_TEXTURE_2D), target);
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_FALSE(level);
245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ASSERT_EQ(static_cast<unsigned>(GL_UNSIGNED_BYTE), type);
2461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    {
2471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      base::AutoLock lock_for_texture_access(namespace_->lock);
2481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      ASSERT_EQ(GLDataFormat(BoundTexture(target)->format), format);
2491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    }
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_TRUE(pixels);
2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SetPixels(xoffset, yoffset, width, height, pixels);
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
254a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual void genMailboxCHROMIUM(GLbyte* mailbox) OVERRIDE {
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return shared_data_->GenMailbox(mailbox);
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
258a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual void produceTextureCHROMIUM(GLenum target,
259a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                      const GLbyte* mailbox) OVERRIDE {
2604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    CheckTextureIsBound(target);
2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Delay moving the texture into the mailbox until the next
2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // InsertSyncPoint, so that it is not visible to other contexts that
2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // haven't waited on that sync point.
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<PendingProduceTexture> pending(new PendingProduceTexture);
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    memcpy(pending->mailbox, mailbox, sizeof(pending->mailbox));
2671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    base::AutoLock lock_for_texture_access(namespace_->lock);
2684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    pending->texture = BoundTexture(target);
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    pending_produce_textures_.push_back(pending.Pass());
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
272a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual void consumeTextureCHROMIUM(GLenum target,
273a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                      const GLbyte* mailbox) OVERRIDE {
2744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    CheckTextureIsBound(target);
2751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    base::AutoLock lock_for_texture_access(namespace_->lock);
2764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    scoped_refptr<TestTexture> texture =
2774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        shared_data_->ConsumeTexture(mailbox, last_waited_sync_point_);
2784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    namespace_->textures.Replace(BoundTextureId(target), texture);
2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void GetPixels(const gfx::Size& size,
2825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                 ResourceFormat format,
2835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                 uint8_t* pixels) {
2844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    CheckTextureIsBound(GL_TEXTURE_2D);
2851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    base::AutoLock lock_for_texture_access(namespace_->lock);
2864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    scoped_refptr<TestTexture> texture = BoundTexture(GL_TEXTURE_2D);
2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_EQ(texture->size, size);
2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_EQ(texture->format, format);
2894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    memcpy(pixels, texture->data.get(), TextureSizeBytes(size, format));
2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected:
2938bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  explicit ResourceProviderContext(ContextSharedData* shared_data)
2948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      : shared_data_(shared_data),
2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        last_waited_sync_point_(0) {}
2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
2985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void AllocateTexture(const gfx::Size& size, GLenum format) {
2994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    CheckTextureIsBound(GL_TEXTURE_2D);
300d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    ResourceFormat texture_format = RGBA_8888;
301d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    switch (format) {
302d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      case GL_RGBA:
303d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        texture_format = RGBA_8888;
304d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        break;
305d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      case GL_BGRA_EXT:
306d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        texture_format = BGRA_8888;
307d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        break;
308d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    }
3091e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    base::AutoLock lock_for_texture_access(namespace_->lock);
3104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    BoundTexture(GL_TEXTURE_2D)->Reallocate(size, texture_format);
3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void SetPixels(int xoffset,
3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 int yoffset,
3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 int width,
3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 int height,
3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 const void* pixels) {
3184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    CheckTextureIsBound(GL_TEXTURE_2D);
3191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    base::AutoLock lock_for_texture_access(namespace_->lock);
3204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    scoped_refptr<TestTexture> texture = BoundTexture(GL_TEXTURE_2D);
3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_TRUE(texture->data.get());
3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_TRUE(xoffset >= 0 && xoffset + width <= texture->size.width());
3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_TRUE(yoffset >= 0 && yoffset + height <= texture->size.height());
3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_TRUE(pixels);
3254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    size_t in_pitch = TextureSizeBytes(gfx::Size(width, 1), texture->format);
3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    size_t out_pitch =
3274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        TextureSizeBytes(gfx::Size(texture->size.width(), 1), texture->format);
3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    uint8_t* dest = texture->data.get() + yoffset * out_pitch +
3294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                    TextureSizeBytes(gfx::Size(xoffset, 1), texture->format);
3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const uint8_t* src = static_cast<const uint8_t*>(pixels);
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (int i = 0; i < height; ++i) {
3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      memcpy(dest, src, in_pitch);
3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      dest += out_pitch;
3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      src += in_pitch;
3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  struct PendingProduceTexture {
3395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    GLbyte mailbox[GL_MAILBOX_SIZE_CHROMIUM];
3404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    scoped_refptr<TestTexture> texture;
3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  typedef ScopedPtrDeque<PendingProduceTexture> PendingProduceTextureList;
3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ContextSharedData* shared_data_;
3445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  GLuint last_waited_sync_point_;
3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PendingProduceTextureList pending_produce_textures_;
3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid GetResourcePixels(ResourceProvider* resource_provider,
3497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                       ResourceProviderContext* context,
3507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                       ResourceProvider::ResourceId id,
3515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                       const gfx::Size& size,
352d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                       ResourceFormat format,
3537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                       uint8_t* pixels) {
35403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  resource_provider->WaitSyncPointIfNeeded(id);
3557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  switch (resource_provider->default_resource_type()) {
3567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    case ResourceProvider::GLTexture: {
3577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      ResourceProvider::ScopedReadLockGL lock_gl(resource_provider, id);
3587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      ASSERT_NE(0U, lock_gl.texture_id());
3597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      context->bindTexture(GL_TEXTURE_2D, lock_gl.texture_id());
3607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      context->GetPixels(size, format, pixels);
3617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      break;
3627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    }
3637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    case ResourceProvider::Bitmap: {
3647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      ResourceProvider::ScopedReadLockSoftware lock_software(resource_provider,
3657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                                             id);
3667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      memcpy(pixels,
3677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch             lock_software.sk_bitmap()->getPixels(),
3687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch             lock_software.sk_bitmap()->getSize());
3697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      break;
3707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    }
3717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    case ResourceProvider::InvalidType:
3727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      NOTREACHED();
3737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      break;
3747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
3757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
3767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
377c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class ResourceProviderTest
378c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : public testing::TestWithParam<ResourceProvider::ResourceType> {
3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ResourceProviderTest()
3813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      : shared_data_(ContextSharedData::Create()),
3821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        context3d_(NULL),
3831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        child_context_(NULL),
3841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        main_thread_task_runner_(BlockingTaskRunner::Create(NULL)) {
3857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    switch (GetParam()) {
3863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      case ResourceProvider::GLTexture: {
3873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        scoped_ptr<ResourceProviderContext> context3d(
3883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            ResourceProviderContext::Create(shared_data_.get()));
3893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        context3d_ = context3d.get();
3903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
3913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        scoped_refptr<TestContextProvider> context_provider =
3923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            TestContextProvider::Create(
3933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                context3d.PassAs<TestWebGraphicsContext3D>());
3943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
3953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        output_surface_ = FakeOutputSurface::Create3d(context_provider);
3961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
3971e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        scoped_ptr<ResourceProviderContext> child_context_owned =
3981e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)            ResourceProviderContext::Create(shared_data_.get());
3991e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        child_context_ = child_context_owned.get();
4001e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        child_output_surface_ = FakeOutputSurface::Create3d(
4011e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)            child_context_owned.PassAs<TestWebGraphicsContext3D>());
4027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        break;
4033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      }
4047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      case ResourceProvider::Bitmap:
4057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        output_surface_ = FakeOutputSurface::CreateSoftware(
4067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            make_scoped_ptr(new SoftwareOutputDevice));
4071e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        child_output_surface_ = FakeOutputSurface::CreateSoftware(
4081e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)            make_scoped_ptr(new SoftwareOutputDevice));
4097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        break;
4107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      case ResourceProvider::InvalidType:
4117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        NOTREACHED();
4127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        break;
4137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    }
4143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    CHECK(output_surface_->BindToClient(&output_surface_client_));
4151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    CHECK(child_output_surface_->BindToClient(&child_output_surface_client_));
4161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
4171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    shared_bitmap_manager_.reset(new TestSharedBitmapManager());
4181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
4191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    resource_provider_ =
4201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        ResourceProvider::Create(output_surface_.get(),
4211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                 shared_bitmap_manager_.get(),
4221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                 main_thread_task_runner_.get(),
4231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                 0,
4241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                 false,
4251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                 1,
4261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                 false);
4271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    child_resource_provider_ =
4281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        ResourceProvider::Create(child_output_surface_.get(),
4291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                 shared_bitmap_manager_.get(),
4301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                 main_thread_task_runner_.get(),
4311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                 0,
4321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                 false,
4331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                 1,
4341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                 false);
4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
43768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  static void CollectResources(ReturnedResourceArray* array,
4381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               const ReturnedResourceArray& returned,
4391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               BlockingTaskRunner* main_thread_task_runner) {
44068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    array->insert(array->end(), returned.begin(), returned.end());
44168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
44268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
44368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  static ReturnCallback GetReturnCallback(ReturnedResourceArray* array) {
44468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    return base::Bind(&ResourceProviderTest::CollectResources, array);
44568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
44668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
447d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  static void SetResourceFilter(ResourceProvider* resource_provider,
44868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                ResourceProvider::ResourceId id,
449a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                GLenum filter) {
4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ResourceProvider::ScopedSamplerGL sampler(
4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        resource_provider, id, GL_TEXTURE_2D, filter);
4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ResourceProviderContext* context() { return context3d_; }
4553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
4565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ResourceProvider::ResourceId CreateChildMailbox(uint32* release_sync_point,
4571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                                  bool* lost_resource,
4581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                                  bool* release_called,
4595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                                  uint32* sync_point) {
4601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    if (GetParam() == ResourceProvider::GLTexture) {
4611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      unsigned texture = child_context_->createTexture();
4621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      gpu::Mailbox gpu_mailbox;
4631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      child_context_->bindTexture(GL_TEXTURE_2D, texture);
4641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      child_context_->genMailboxCHROMIUM(gpu_mailbox.name);
4651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      child_context_->produceTextureCHROMIUM(GL_TEXTURE_2D, gpu_mailbox.name);
4661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      *sync_point = child_context_->insertSyncPoint();
4671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      EXPECT_LT(0u, *sync_point);
4681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
4691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      scoped_ptr<base::SharedMemory> shared_memory;
4701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      scoped_ptr<SingleReleaseCallbackImpl> callback =
4711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          SingleReleaseCallbackImpl::Create(
4721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci              base::Bind(ReleaseSharedMemoryCallback,
4731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                         base::Passed(&shared_memory),
4741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                         release_called,
4751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                         release_sync_point,
4761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                         lost_resource));
4771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      return child_resource_provider_->CreateResourceFromTextureMailbox(
4785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          TextureMailbox(gpu_mailbox, GL_TEXTURE_2D, *sync_point),
4795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          callback.Pass());
4801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    } else {
4811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      gfx::Size size(64, 64);
4821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      scoped_ptr<base::SharedMemory> shared_memory(
4831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          CreateAndFillSharedMemory(size, 0));
4841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
4851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      base::SharedMemory* shared_memory_ptr = shared_memory.get();
4861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      scoped_ptr<SingleReleaseCallbackImpl> callback =
4871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          SingleReleaseCallbackImpl::Create(
4881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci              base::Bind(ReleaseSharedMemoryCallback,
4891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                         base::Passed(&shared_memory),
4901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                         release_called,
4911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                         release_sync_point,
4921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                         lost_resource));
4931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      return child_resource_provider_->CreateResourceFromTextureMailbox(
4941e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          TextureMailbox(shared_memory_ptr, size), callback.Pass());
4951e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    }
4961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
4971e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected:
4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<ContextSharedData> shared_data_;
5003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ResourceProviderContext* context3d_;
5011e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ResourceProviderContext* child_context_;
5023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  FakeOutputSurfaceClient output_surface_client_;
5031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  FakeOutputSurfaceClient child_output_surface_client_;
5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<OutputSurface> output_surface_;
5051e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  scoped_ptr<OutputSurface> child_output_surface_;
5061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<BlockingTaskRunner> main_thread_task_runner_;
5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<ResourceProvider> resource_provider_;
5081e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  scoped_ptr<ResourceProvider> child_resource_provider_;
5091e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  scoped_ptr<TestSharedBitmapManager> shared_bitmap_manager_;
5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid CheckCreateResource(ResourceProvider::ResourceType expected_default_type,
5137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                         ResourceProvider* resource_provider,
5147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                         ResourceProviderContext* context) {
5157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DCHECK_EQ(expected_default_type, resource_provider->default_resource_type());
5167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Size size(1, 1);
518d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  ResourceFormat format = RGBA_8888;
5194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  size_t pixel_size = TextureSizeBytes(size, format);
5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(4U, pixel_size);
5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  ResourceProvider::ResourceId id = resource_provider->CreateResource(
52303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureHintImmutable, format);
5247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_EQ(1, static_cast<int>(resource_provider->num_resources()));
5257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (expected_default_type == ResourceProvider::GLTexture)
5264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    EXPECT_EQ(0u, context->NumTextures());
5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  uint8_t data[4] = { 1, 2, 3, 4 };
5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect rect(size);
5307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  resource_provider->SetPixels(id, data, rect, rect, gfx::Vector2d());
5317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (expected_default_type == ResourceProvider::GLTexture)
5324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    EXPECT_EQ(1u, context->NumTextures());
5332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  uint8_t result[4] = { 0 };
5357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  GetResourcePixels(resource_provider, context, id, size, format, result);
5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, memcmp(data, result, pixel_size));
5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  resource_provider->DeleteResource(id);
5397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_EQ(0, static_cast<int>(resource_provider->num_resources()));
5407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (expected_default_type == ResourceProvider::GLTexture)
5414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    EXPECT_EQ(0u, context->NumTextures());
5427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
5437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
5447dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochTEST_P(ResourceProviderTest, Basic) {
5457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  CheckCreateResource(GetParam(), resource_provider_.get(), context());
5462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_P(ResourceProviderTest, Upload) {
5492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Size size(2, 2);
550d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  ResourceFormat format = RGBA_8888;
5514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  size_t pixel_size = TextureSizeBytes(size, format);
5522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(16U, pixel_size);
5532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ResourceProvider::ResourceId id = resource_provider_->CreateResource(
55503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureHintImmutable, format);
5562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  uint8_t image[16] = { 0 };
5582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect image_rect(size);
5592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_provider_->SetPixels(
5602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      id, image, image_rect, image_rect, gfx::Vector2d());
5612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (uint8_t i = 0; i < pixel_size; ++i)
5632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    image[i] = i;
5642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  uint8_t result[16] = { 0 };
5662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
5672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gfx::Rect source_rect(0, 0, 1, 1);
5682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gfx::Vector2d dest_offset(0, 0);
5692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    resource_provider_->SetPixels(
5702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        id, image, image_rect, source_rect, dest_offset);
5712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    uint8_t expected[16] = { 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
5737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    GetResourcePixels(
5747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        resource_provider_.get(), context(), id, size, format, result);
5752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(0, memcmp(expected, result, pixel_size));
5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
5782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gfx::Rect source_rect(0, 0, 1, 1);
5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gfx::Vector2d dest_offset(1, 1);
5802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    resource_provider_->SetPixels(
5812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        id, image, image_rect, source_rect, dest_offset);
5822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    uint8_t expected[16] = { 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3 };
5847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    GetResourcePixels(
5857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        resource_provider_.get(), context(), id, size, format, result);
5862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(0, memcmp(expected, result, pixel_size));
5872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
5892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gfx::Rect source_rect(1, 0, 1, 1);
5902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gfx::Vector2d dest_offset(0, 1);
5912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    resource_provider_->SetPixels(
5922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        id, image, image_rect, source_rect, dest_offset);
5932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    uint8_t expected[16] = { 0, 1, 2, 3, 0, 0, 0, 0, 4, 5, 6, 7, 0, 1, 2, 3 };
5957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    GetResourcePixels(
5967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        resource_provider_.get(), context(), id, size, format, result);
5972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(0, memcmp(expected, result, pixel_size));
5982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
6002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gfx::Rect offset_image_rect(gfx::Point(100, 100), size);
6012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gfx::Rect source_rect(100, 100, 1, 1);
6022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gfx::Vector2d dest_offset(1, 0);
6032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    resource_provider_->SetPixels(
6042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        id, image, offset_image_rect, source_rect, dest_offset);
6052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    uint8_t expected[16] = { 0, 1, 2, 3, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3 };
6077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    GetResourcePixels(
6087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        resource_provider_.get(), context(), id, size, format, result);
6092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(0, memcmp(expected, result, pixel_size));
6102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_provider_->DeleteResource(id);
6132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)TEST_P(ResourceProviderTest, TransferGLResources) {
6162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (GetParam() != ResourceProvider::GLTexture)
6172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
6182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Size size(1, 1);
619d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  ResourceFormat format = RGBA_8888;
6204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  size_t pixel_size = TextureSizeBytes(size, format);
6212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(4U, pixel_size);
6222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ResourceProvider::ResourceId id1 = child_resource_provider_->CreateResource(
62403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureHintImmutable, format);
6252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  uint8_t data1[4] = { 1, 2, 3, 4 };
6262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect rect(size);
6271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  child_resource_provider_->SetPixels(id1, data1, rect, rect, gfx::Vector2d());
6282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ResourceProvider::ResourceId id2 = child_resource_provider_->CreateResource(
63003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureHintImmutable, format);
6312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  uint8_t data2[4] = { 5, 5, 5, 5 };
6321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  child_resource_provider_->SetPixels(id2, data2, rect, rect, gfx::Vector2d());
6332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ResourceProvider::ResourceId id3 = child_resource_provider_->CreateResource(
63503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureHintImmutable, format);
6361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  child_resource_provider_->AcquireImage(id3);
6371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  int stride;
6381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  child_resource_provider_->MapImage(id3, &stride);
6391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  child_resource_provider_->UnmapImage(id3);
6405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
641a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLuint external_texture_id = child_context_->createExternalTexture();
6421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  child_context_->bindTexture(GL_TEXTURE_EXTERNAL_OES, external_texture_id);
6434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
64468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  gpu::Mailbox external_mailbox;
6451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  child_context_->genMailboxCHROMIUM(external_mailbox.name);
6461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  child_context_->produceTextureCHROMIUM(GL_TEXTURE_EXTERNAL_OES,
6471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                         external_mailbox.name);
6485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const GLuint external_sync_point = child_context_->insertSyncPoint();
6495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ResourceProvider::ResourceId id4 =
6501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      child_resource_provider_->CreateResourceFromTextureMailbox(
65168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          TextureMailbox(
65268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)              external_mailbox, GL_TEXTURE_EXTERNAL_OES, external_sync_point),
6531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          SingleReleaseCallbackImpl::Create(base::Bind(&EmptyReleaseCallback)));
65468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
65568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  ReturnedResourceArray returned_to_child;
65668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  int child_id =
65768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      resource_provider_->CreateChild(GetReturnCallback(&returned_to_child));
6582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
6592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Transfer some resources to the parent.
6602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ResourceProvider::ResourceIdArray resource_ids_to_transfer;
6612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    resource_ids_to_transfer.push_back(id1);
6622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    resource_ids_to_transfer.push_back(id2);
66368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    resource_ids_to_transfer.push_back(id3);
6645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    resource_ids_to_transfer.push_back(id4);
6652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TransferableResourceArray list;
6661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
6671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                                  &list);
6685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ASSERT_EQ(4u, list.size());
6695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_NE(0u, list[0].mailbox_holder.sync_point);
6705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_NE(0u, list[1].mailbox_holder.sync_point);
6715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_EQ(list[0].mailbox_holder.sync_point,
6725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              list[1].mailbox_holder.sync_point);
6735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_NE(0u, list[2].mailbox_holder.sync_point);
6745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_EQ(list[0].mailbox_holder.sync_point,
6755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              list[2].mailbox_holder.sync_point);
6765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_EQ(external_sync_point, list[3].mailbox_holder.sync_point);
6775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_2D),
6785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              list[0].mailbox_holder.texture_target);
6795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_2D),
6805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              list[1].mailbox_holder.texture_target);
6815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_2D),
6825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              list[2].mailbox_holder.texture_target);
6835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_EXTERNAL_OES),
6845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              list[3].mailbox_holder.texture_target);
6851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id1));
6861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id2));
6871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id3));
6885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id4));
6892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    resource_provider_->ReceiveFromChild(child_id, list);
6905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_NE(list[0].mailbox_holder.sync_point,
6915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              context3d_->last_waited_sync_point());
6925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    {
69303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      resource_provider_->WaitSyncPointIfNeeded(list[0].id);
6945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ResourceProvider::ScopedReadLockGL lock(resource_provider_.get(),
6955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                              list[0].id);
6965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
6975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_EQ(list[0].mailbox_holder.sync_point,
6985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              context3d_->last_waited_sync_point());
69968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    resource_provider_->DeclareUsedResourcesFromChild(child_id,
70068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                                      resource_ids_to_transfer);
7012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
7022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(4u, resource_provider_->num_resources());
7042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ResourceProvider::ResourceIdMap resource_map =
7052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      resource_provider_->GetChildToParentMap(child_id);
7062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ResourceProvider::ResourceId mapped_id1 = resource_map[id1];
7072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ResourceProvider::ResourceId mapped_id2 = resource_map[id2];
70868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  ResourceProvider::ResourceId mapped_id3 = resource_map[id3];
7095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ResourceProvider::ResourceId mapped_id4 = resource_map[id4];
7102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NE(0u, mapped_id1);
7112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NE(0u, mapped_id2);
71268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_NE(0u, mapped_id3);
7135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_NE(0u, mapped_id4);
7142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(resource_provider_->InUseByConsumer(id1));
7152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(resource_provider_->InUseByConsumer(id2));
71668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_FALSE(resource_provider_->InUseByConsumer(id3));
7175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(resource_provider_->InUseByConsumer(id4));
7182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  uint8_t result[4] = { 0 };
7207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  GetResourcePixels(
7217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      resource_provider_.get(), context(), mapped_id1, size, format, result);
7222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, memcmp(data1, result, pixel_size));
7232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  GetResourcePixels(
7257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      resource_provider_.get(), context(), mapped_id2, size, format, result);
7262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, memcmp(data2, result, pixel_size));
72768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
7282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
7292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Check that transfering again the same resource from the child to the
7303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    // parent works.
7312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ResourceProvider::ResourceIdArray resource_ids_to_transfer;
7322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    resource_ids_to_transfer.push_back(id1);
7335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    resource_ids_to_transfer.push_back(id2);
7345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    resource_ids_to_transfer.push_back(id3);
7352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TransferableResourceArray list;
7361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
7371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                                  &list);
7385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_EQ(3u, list.size());
7393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    EXPECT_EQ(id1, list[0].id);
7405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_EQ(id2, list[1].id);
7415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_EQ(id3, list[2].id);
7425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_2D),
7435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              list[0].mailbox_holder.texture_target);
7445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_2D),
7455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              list[1].mailbox_holder.texture_target);
7465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_2D),
7475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              list[2].mailbox_holder.texture_target);
7483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ReturnedResourceArray returned;
7493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    TransferableResource::ReturnResources(list, &returned);
7501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    child_resource_provider_->ReceiveReturnsFromParent(returned);
7515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // ids were exported twice, we returned them only once, they should still
7525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // be in-use.
7531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id1));
7545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id2));
7555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id3));
7562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
7572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
75868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    EXPECT_EQ(0u, returned_to_child.size());
75968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
76068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    // Transfer resources back from the parent to the child. Set no resources as
76168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    // being in use.
76268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    ResourceProvider::ResourceIdArray no_resources;
76368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    resource_provider_->DeclareUsedResourcesFromChild(child_id, no_resources);
76468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
7655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ASSERT_EQ(4u, returned_to_child.size());
76668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    EXPECT_NE(0u, returned_to_child[0].sync_point);
76768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    EXPECT_NE(0u, returned_to_child[1].sync_point);
76868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    EXPECT_NE(0u, returned_to_child[2].sync_point);
7695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_NE(0u, returned_to_child[3].sync_point);
77068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    EXPECT_FALSE(returned_to_child[0].lost);
77168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    EXPECT_FALSE(returned_to_child[1].lost);
77268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    EXPECT_FALSE(returned_to_child[2].lost);
7735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_FALSE(returned_to_child[3].lost);
7741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    child_resource_provider_->ReceiveReturnsFromParent(returned_to_child);
77568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    returned_to_child.clear();
7762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
7771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_FALSE(child_resource_provider_->InUseByConsumer(id1));
7781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_FALSE(child_resource_provider_->InUseByConsumer(id2));
7791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_FALSE(child_resource_provider_->InUseByConsumer(id3));
7805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(child_resource_provider_->InUseByConsumer(id4));
7812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
78303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    child_resource_provider_->WaitSyncPointIfNeeded(id1);
7841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    ResourceProvider::ScopedReadLockGL lock(child_resource_provider_.get(),
7851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                            id1);
7862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_NE(0U, lock.texture_id());
7871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    child_context_->bindTexture(GL_TEXTURE_2D, lock.texture_id());
7881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    child_context_->GetPixels(size, format, result);
7892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(0, memcmp(data1, result, pixel_size));
7902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
7912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
79203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    child_resource_provider_->WaitSyncPointIfNeeded(id2);
7931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    ResourceProvider::ScopedReadLockGL lock(child_resource_provider_.get(),
7941e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                            id2);
7952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_NE(0U, lock.texture_id());
7961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    child_context_->bindTexture(GL_TEXTURE_2D, lock.texture_id());
7971e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    child_context_->GetPixels(size, format, result);
7982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(0, memcmp(data2, result, pixel_size));
7992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
8002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
80103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    child_resource_provider_->WaitSyncPointIfNeeded(id3);
8025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ResourceProvider::ScopedReadLockGL lock(child_resource_provider_.get(),
8035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                            id3);
8045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ASSERT_NE(0U, lock.texture_id());
8055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    child_context_->bindTexture(GL_TEXTURE_2D, lock.texture_id());
8065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
8075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  {
8082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Transfer resources to the parent again.
8092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ResourceProvider::ResourceIdArray resource_ids_to_transfer;
8102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    resource_ids_to_transfer.push_back(id1);
8112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    resource_ids_to_transfer.push_back(id2);
81268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    resource_ids_to_transfer.push_back(id3);
8135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    resource_ids_to_transfer.push_back(id4);
8142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TransferableResourceArray list;
8151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
8161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                                  &list);
8175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ASSERT_EQ(4u, list.size());
81868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    EXPECT_EQ(id1, list[0].id);
81968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    EXPECT_EQ(id2, list[1].id);
82068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    EXPECT_EQ(id3, list[2].id);
8215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_EQ(id4, list[3].id);
8225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_NE(0u, list[0].mailbox_holder.sync_point);
8235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_NE(0u, list[1].mailbox_holder.sync_point);
8245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_NE(0u, list[2].mailbox_holder.sync_point);
8255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_NE(0u, list[3].mailbox_holder.sync_point);
8265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_2D),
8275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              list[0].mailbox_holder.texture_target);
8285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_2D),
8295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              list[1].mailbox_holder.texture_target);
8305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_2D),
8315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              list[2].mailbox_holder.texture_target);
8325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_EXTERNAL_OES),
8335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              list[3].mailbox_holder.texture_target);
8341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id1));
8351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id2));
8361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id3));
8375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id4));
8382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    resource_provider_->ReceiveFromChild(child_id, list);
83968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    resource_provider_->DeclareUsedResourcesFromChild(child_id,
84068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                                      resource_ids_to_transfer);
8412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
8422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
84368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_EQ(0u, returned_to_child.size());
84468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
8455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(4u, resource_provider_->num_resources());
8462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_provider_->DestroyChild(child_id);
8472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0u, resource_provider_->num_resources());
84868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
8495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(4u, returned_to_child.size());
85068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_NE(0u, returned_to_child[0].sync_point);
85168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_NE(0u, returned_to_child[1].sync_point);
85268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_NE(0u, returned_to_child[2].sync_point);
8535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_NE(0u, returned_to_child[3].sync_point);
85468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_FALSE(returned_to_child[0].lost);
85568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_FALSE(returned_to_child[1].lost);
85668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_FALSE(returned_to_child[2].lost);
8575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(returned_to_child[3].lost);
85868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
85968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
860effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochTEST_P(ResourceProviderTest, ReadLockCountStopsReturnToChildOrDelete) {
861effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  if (GetParam() != ResourceProvider::GLTexture)
862effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    return;
863effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  gfx::Size size(1, 1);
864effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  ResourceFormat format = RGBA_8888;
865effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
866effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  ResourceProvider::ResourceId id1 = child_resource_provider_->CreateResource(
86703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureHintImmutable, format);
868effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  uint8_t data1[4] = {1, 2, 3, 4};
869effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  gfx::Rect rect(size);
870effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  child_resource_provider_->SetPixels(id1, data1, rect, rect, gfx::Vector2d());
871effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
872effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  ReturnedResourceArray returned_to_child;
873effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  int child_id =
874effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      resource_provider_->CreateChild(GetReturnCallback(&returned_to_child));
875effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  {
876effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    // Transfer some resources to the parent.
877effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    ResourceProvider::ResourceIdArray resource_ids_to_transfer;
878effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    resource_ids_to_transfer.push_back(id1);
879effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    TransferableResourceArray list;
880effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
881effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                                                  &list);
882effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    ASSERT_EQ(1u, list.size());
883effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id1));
884effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
885effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    resource_provider_->ReceiveFromChild(child_id, list);
886effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
88703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    resource_provider_->WaitSyncPointIfNeeded(list[0].id);
888effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    ResourceProvider::ScopedReadLockGL lock(resource_provider_.get(),
889effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                                            list[0].id);
890effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
891effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    resource_provider_->DeclareUsedResourcesFromChild(
892effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        child_id, ResourceProvider::ResourceIdArray());
893effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    EXPECT_EQ(0u, returned_to_child.size());
894effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
895effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
896effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_EQ(1u, returned_to_child.size());
897effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  child_resource_provider_->ReceiveReturnsFromParent(returned_to_child);
898effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
899effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  {
90003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    child_resource_provider_->WaitSyncPointIfNeeded(id1);
901effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    ResourceProvider::ScopedReadLockGL lock(child_resource_provider_.get(),
902effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                                            id1);
903effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    child_resource_provider_->DeleteResource(id1);
904effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    EXPECT_EQ(1u, child_resource_provider_->num_resources());
905effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id1));
906effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
907effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
908effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_EQ(0u, child_resource_provider_->num_resources());
909effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  resource_provider_->DestroyChild(child_id);
910effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
911effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
9125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)TEST_P(ResourceProviderTest, AllowOverlayTransfersToParent) {
9135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Overlays only supported on the GL path.
9145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (GetParam() != ResourceProvider::GLTexture)
9155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return;
9165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
9175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  uint32 sync_point = 0;
9185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  TextureMailbox mailbox(gpu::Mailbox::Generate(), GL_TEXTURE_2D, sync_point);
9195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  mailbox.set_allow_overlay(true);
9201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<SingleReleaseCallbackImpl> release_callback =
9211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      SingleReleaseCallbackImpl::Create(base::Bind(&EmptyReleaseCallback));
9225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ResourceProvider::ResourceId id1 =
9235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      child_resource_provider_->CreateResourceFromTextureMailbox(
9245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          mailbox, release_callback.Pass());
9255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
9265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  TextureMailbox mailbox2(gpu::Mailbox::Generate(), GL_TEXTURE_2D, sync_point);
9275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  mailbox2.set_allow_overlay(false);
9281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<SingleReleaseCallbackImpl> release_callback2 =
9291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      SingleReleaseCallbackImpl::Create(base::Bind(&EmptyReleaseCallback));
9305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ResourceProvider::ResourceId id2 =
9315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      child_resource_provider_->CreateResourceFromTextureMailbox(
9325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          mailbox2, release_callback2.Pass());
9335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
9345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ReturnedResourceArray returned_to_child;
9355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  int child_id =
9365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      resource_provider_->CreateChild(GetReturnCallback(&returned_to_child));
9375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
9385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Transfer some resources to the parent.
9395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ResourceProvider::ResourceIdArray resource_ids_to_transfer;
9405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  resource_ids_to_transfer.push_back(id1);
9415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  resource_ids_to_transfer.push_back(id2);
9425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  TransferableResourceArray list;
9435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
9445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                                &list);
9455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ASSERT_EQ(2u, list.size());
9465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  resource_provider_->ReceiveFromChild(child_id, list);
9475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_TRUE(resource_provider_->AllowOverlay(list[0].id));
9485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_FALSE(resource_provider_->AllowOverlay(list[1].id));
9495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
9505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  resource_provider_->DeclareUsedResourcesFromChild(
9515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      child_id, ResourceProvider::ResourceIdArray());
9525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
9535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_EQ(2u, returned_to_child.size());
9545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  child_resource_provider_->ReceiveReturnsFromParent(returned_to_child);
9555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
9565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  child_resource_provider_->DeleteResource(id1);
9575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  child_resource_provider_->DeleteResource(id2);
9585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_EQ(0u, child_resource_provider_->num_resources());
9595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
9605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  resource_provider_->DestroyChild(child_id);
9615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
9625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
9631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)TEST_P(ResourceProviderTest, TransferSoftwareResources) {
9641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (GetParam() != ResourceProvider::Bitmap)
9651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    return;
9661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
9671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  gfx::Size size(1, 1);
9681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ResourceFormat format = RGBA_8888;
9691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  size_t pixel_size = TextureSizeBytes(size, format);
9701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ASSERT_EQ(4U, pixel_size);
9711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
9721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ResourceProvider::ResourceId id1 = child_resource_provider_->CreateResource(
97303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureHintImmutable, format);
9741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  uint8_t data1[4] = { 1, 2, 3, 4 };
9751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  gfx::Rect rect(size);
9761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  child_resource_provider_->SetPixels(id1, data1, rect, rect, gfx::Vector2d());
9771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
9781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ResourceProvider::ResourceId id2 = child_resource_provider_->CreateResource(
97903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureHintImmutable, format);
9801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  uint8_t data2[4] = { 5, 5, 5, 5 };
9811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  child_resource_provider_->SetPixels(id2, data2, rect, rect, gfx::Vector2d());
9821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
9831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  scoped_ptr<base::SharedMemory> shared_memory(new base::SharedMemory());
9841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  shared_memory->CreateAndMapAnonymous(1);
9851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  base::SharedMemory* shared_memory_ptr = shared_memory.get();
9861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ResourceProvider::ResourceId id3 =
9871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      child_resource_provider_->CreateResourceFromTextureMailbox(
9881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          TextureMailbox(shared_memory_ptr, gfx::Size(1, 1)),
9891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          SingleReleaseCallbackImpl::Create(base::Bind(
9901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)              &SharedMemoryReleaseCallback, base::Passed(&shared_memory))));
9911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
9921e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ReturnedResourceArray returned_to_child;
9931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  int child_id =
9941e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      resource_provider_->CreateChild(GetReturnCallback(&returned_to_child));
9951e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  {
9961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // Transfer some resources to the parent.
9971e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    ResourceProvider::ResourceIdArray resource_ids_to_transfer;
9981e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    resource_ids_to_transfer.push_back(id1);
9991e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    resource_ids_to_transfer.push_back(id2);
10001e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    resource_ids_to_transfer.push_back(id3);
10011e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    TransferableResourceArray list;
10021e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
10031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                                  &list);
10041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    ASSERT_EQ(3u, list.size());
10055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_EQ(0u, list[0].mailbox_holder.sync_point);
10065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_EQ(0u, list[1].mailbox_holder.sync_point);
10075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_EQ(0u, list[2].mailbox_holder.sync_point);
10081e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id1));
10091e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id2));
10101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id3));
10111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    resource_provider_->ReceiveFromChild(child_id, list);
10121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    resource_provider_->DeclareUsedResourcesFromChild(child_id,
10131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                                      resource_ids_to_transfer);
10141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
10151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
10161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(3u, resource_provider_->num_resources());
10171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ResourceProvider::ResourceIdMap resource_map =
10181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      resource_provider_->GetChildToParentMap(child_id);
10191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ResourceProvider::ResourceId mapped_id1 = resource_map[id1];
10201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ResourceProvider::ResourceId mapped_id2 = resource_map[id2];
10211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ResourceProvider::ResourceId mapped_id3 = resource_map[id3];
10221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_NE(0u, mapped_id1);
10231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_NE(0u, mapped_id2);
10241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_NE(0u, mapped_id3);
10251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_FALSE(resource_provider_->InUseByConsumer(id1));
10261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_FALSE(resource_provider_->InUseByConsumer(id2));
10271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_FALSE(resource_provider_->InUseByConsumer(id3));
10281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
10291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  uint8_t result[4] = { 0 };
10301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  GetResourcePixels(
10311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      resource_provider_.get(), context(), mapped_id1, size, format, result);
10321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_EQ(0, memcmp(data1, result, pixel_size));
10331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
10341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  GetResourcePixels(
10351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      resource_provider_.get(), context(), mapped_id2, size, format, result);
10361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_EQ(0, memcmp(data2, result, pixel_size));
10371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
10381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  {
10391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // Check that transfering again the same resource from the child to the
10401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // parent works.
10411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    ResourceProvider::ResourceIdArray resource_ids_to_transfer;
10421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    resource_ids_to_transfer.push_back(id1);
10435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    resource_ids_to_transfer.push_back(id2);
10441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    TransferableResourceArray list;
10451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
10461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                                  &list);
10471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_EQ(2u, list.size());
10481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    EXPECT_EQ(id1, list[0].id);
10495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_EQ(id2, list[1].id);
10501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    ReturnedResourceArray returned;
10511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    TransferableResource::ReturnResources(list, &returned);
10521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    child_resource_provider_->ReceiveReturnsFromParent(returned);
10535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // ids were exported twice, we returned them only once, they should still
10545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // be in-use.
10551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id1));
10565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id2));
10571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
10581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  {
10591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    EXPECT_EQ(0u, returned_to_child.size());
10601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
10611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // Transfer resources back from the parent to the child. Set no resources as
10621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // being in use.
10631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    ResourceProvider::ResourceIdArray no_resources;
10641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    resource_provider_->DeclareUsedResourcesFromChild(child_id, no_resources);
10651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
10661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    ASSERT_EQ(3u, returned_to_child.size());
10671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    EXPECT_EQ(0u, returned_to_child[0].sync_point);
10681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    EXPECT_EQ(0u, returned_to_child[1].sync_point);
10691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    EXPECT_EQ(0u, returned_to_child[2].sync_point);
107023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    std::set<ResourceProvider::ResourceId> expected_ids;
107123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    expected_ids.insert(id1);
107223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    expected_ids.insert(id2);
107323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    expected_ids.insert(id3);
107423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    std::set<ResourceProvider::ResourceId> returned_ids;
10751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    for (unsigned i = 0; i < 3; i++)
107623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      returned_ids.insert(returned_to_child[i].id);
107723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    EXPECT_EQ(expected_ids, returned_ids);
10781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    EXPECT_FALSE(returned_to_child[0].lost);
10791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    EXPECT_FALSE(returned_to_child[1].lost);
10801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    EXPECT_FALSE(returned_to_child[2].lost);
10811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    child_resource_provider_->ReceiveReturnsFromParent(returned_to_child);
10821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    returned_to_child.clear();
10831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
10841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_FALSE(child_resource_provider_->InUseByConsumer(id1));
10851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_FALSE(child_resource_provider_->InUseByConsumer(id2));
10861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_FALSE(child_resource_provider_->InUseByConsumer(id3));
10871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
10881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  {
10891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    ResourceProvider::ScopedReadLockSoftware lock(
10901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        child_resource_provider_.get(), id1);
10911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    const SkBitmap* sk_bitmap = lock.sk_bitmap();
10921e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    EXPECT_EQ(sk_bitmap->width(), size.width());
10931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    EXPECT_EQ(sk_bitmap->height(), size.height());
10941e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    EXPECT_EQ(0, memcmp(data1, sk_bitmap->getPixels(), pixel_size));
10951e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
10961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  {
10971e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    ResourceProvider::ScopedReadLockSoftware lock(
10981e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        child_resource_provider_.get(), id2);
10991e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    const SkBitmap* sk_bitmap = lock.sk_bitmap();
11001e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    EXPECT_EQ(sk_bitmap->width(), size.width());
11011e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    EXPECT_EQ(sk_bitmap->height(), size.height());
11021e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    EXPECT_EQ(0, memcmp(data2, sk_bitmap->getPixels(), pixel_size));
11031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
11041e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  {
11051e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // Transfer resources to the parent again.
11061e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    ResourceProvider::ResourceIdArray resource_ids_to_transfer;
11071e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    resource_ids_to_transfer.push_back(id1);
11081e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    resource_ids_to_transfer.push_back(id2);
11091e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    resource_ids_to_transfer.push_back(id3);
11101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    TransferableResourceArray list;
11111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
11121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                                  &list);
11131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    ASSERT_EQ(3u, list.size());
11141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    EXPECT_EQ(id1, list[0].id);
11151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    EXPECT_EQ(id2, list[1].id);
11161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    EXPECT_EQ(id3, list[2].id);
11171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id1));
11181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id2));
11191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id3));
11201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    resource_provider_->ReceiveFromChild(child_id, list);
11211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    resource_provider_->DeclareUsedResourcesFromChild(child_id,
11221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                                      resource_ids_to_transfer);
11231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
11241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
11251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_EQ(0u, returned_to_child.size());
11261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
11271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(3u, resource_provider_->num_resources());
11281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  resource_provider_->DestroyChild(child_id);
11291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_EQ(0u, resource_provider_->num_resources());
11301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
11311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_EQ(3u, returned_to_child.size());
11321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_EQ(0u, returned_to_child[0].sync_point);
11331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_EQ(0u, returned_to_child[1].sync_point);
11341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_EQ(0u, returned_to_child[2].sync_point);
113523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  std::set<ResourceProvider::ResourceId> expected_ids;
113623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  expected_ids.insert(id1);
113723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  expected_ids.insert(id2);
113823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  expected_ids.insert(id3);
113923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  std::set<ResourceProvider::ResourceId> returned_ids;
11401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  for (unsigned i = 0; i < 3; i++)
114123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    returned_ids.insert(returned_to_child[i].id);
114223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  EXPECT_EQ(expected_ids, returned_ids);
11431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_FALSE(returned_to_child[0].lost);
11441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_FALSE(returned_to_child[1].lost);
11451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_FALSE(returned_to_child[2].lost);
11461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
11471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
11481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)TEST_P(ResourceProviderTest, TransferGLToSoftware) {
11491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (GetParam() != ResourceProvider::Bitmap)
115068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    return;
115168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
115268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  scoped_ptr<ResourceProviderContext> child_context_owned(
115368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      ResourceProviderContext::Create(shared_data_.get()));
115468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
115568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  FakeOutputSurfaceClient child_output_surface_client;
115668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  scoped_ptr<OutputSurface> child_output_surface(FakeOutputSurface::Create3d(
115768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      child_context_owned.PassAs<TestWebGraphicsContext3D>()));
115868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  CHECK(child_output_surface->BindToClient(&child_output_surface_client));
115968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
11601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<ResourceProvider> child_resource_provider(
11611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      ResourceProvider::Create(child_output_surface.get(),
11621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               shared_bitmap_manager_.get(),
11631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               NULL,
11641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               0,
11651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               false,
11661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               1,
11671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               false));
116868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
116968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  gfx::Size size(1, 1);
117068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  ResourceFormat format = RGBA_8888;
11714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  size_t pixel_size = TextureSizeBytes(size, format);
117268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  ASSERT_EQ(4U, pixel_size);
117368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
117468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  ResourceProvider::ResourceId id1 = child_resource_provider->CreateResource(
117503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureHintImmutable, format);
11761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  uint8_t data1[4] = { 1, 2, 3, 4 };
117768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  gfx::Rect rect(size);
117868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  child_resource_provider->SetPixels(id1, data1, rect, rect, gfx::Vector2d());
117968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
11801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ReturnedResourceArray returned_to_child;
11811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  int child_id =
11821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      resource_provider_->CreateChild(GetReturnCallback(&returned_to_child));
11831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  {
11841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    ResourceProvider::ResourceIdArray resource_ids_to_transfer;
11851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    resource_ids_to_transfer.push_back(id1);
11861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    TransferableResourceArray list;
11871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    child_resource_provider->PrepareSendToParent(resource_ids_to_transfer,
11881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                                 &list);
11891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    ASSERT_EQ(1u, list.size());
11905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_NE(0u, list[0].mailbox_holder.sync_point);
11915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_2D),
11925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              list[0].mailbox_holder.texture_target);
11931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    EXPECT_TRUE(child_resource_provider->InUseByConsumer(id1));
11941e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    resource_provider_->ReceiveFromChild(child_id, list);
11951e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
11961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
11971e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_EQ(0u, resource_provider_->num_resources());
11981e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ASSERT_EQ(1u, returned_to_child.size());
11991e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_EQ(returned_to_child[0].id, id1);
12001e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ResourceProvider::ResourceIdMap resource_map =
12011e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      resource_provider_->GetChildToParentMap(child_id);
12021e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ResourceProvider::ResourceId mapped_id1 = resource_map[id1];
12031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_EQ(0u, mapped_id1);
12041e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
12051e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  resource_provider_->DestroyChild(child_id);
12061e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_EQ(0u, resource_provider_->num_resources());
12071e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
12081e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ASSERT_EQ(1u, returned_to_child.size());
12091e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_FALSE(returned_to_child[0].lost);
12101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
12111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
12121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)TEST_P(ResourceProviderTest, TransferInvalidSoftware) {
12131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (GetParam() != ResourceProvider::Bitmap)
12141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    return;
12151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
12161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  gfx::Size size(1, 1);
12171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ResourceFormat format = RGBA_8888;
12181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  size_t pixel_size = TextureSizeBytes(size, format);
12191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ASSERT_EQ(4U, pixel_size);
12201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
12211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ResourceProvider::ResourceId id1 = child_resource_provider_->CreateResource(
122203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureHintImmutable, format);
12231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  uint8_t data1[4] = { 1, 2, 3, 4 };
12241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  gfx::Rect rect(size);
12251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  child_resource_provider_->SetPixels(id1, data1, rect, rect, gfx::Vector2d());
12261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
12271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ReturnedResourceArray returned_to_child;
12281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  int child_id =
12291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      resource_provider_->CreateChild(GetReturnCallback(&returned_to_child));
12301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  {
12311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    ResourceProvider::ResourceIdArray resource_ids_to_transfer;
12321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    resource_ids_to_transfer.push_back(id1);
12331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    TransferableResourceArray list;
12341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
12351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                                  &list);
12361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    ASSERT_EQ(1u, list.size());
12371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // Make invalid.
12385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    list[0].mailbox_holder.mailbox.name[1] = 5;
12391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id1));
12401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    resource_provider_->ReceiveFromChild(child_id, list);
12411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
12421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
12435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(1u, resource_provider_->num_resources());
12445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(0u, returned_to_child.size());
12455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
12461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ResourceProvider::ResourceIdMap resource_map =
12471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      resource_provider_->GetChildToParentMap(child_id);
12481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ResourceProvider::ResourceId mapped_id1 = resource_map[id1];
12495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_NE(0u, mapped_id1);
12505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  {
12515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ResourceProvider::ScopedReadLockSoftware lock(resource_provider_.get(),
12525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                                  mapped_id1);
12535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_FALSE(lock.valid());
12545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
12551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
12561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  resource_provider_->DestroyChild(child_id);
12571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_EQ(0u, resource_provider_->num_resources());
12581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
12591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ASSERT_EQ(1u, returned_to_child.size());
12601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_FALSE(returned_to_child[0].lost);
12611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
12621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
12631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)TEST_P(ResourceProviderTest, DeleteExportedResources) {
12641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  gfx::Size size(1, 1);
12651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ResourceFormat format = RGBA_8888;
12661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  size_t pixel_size = TextureSizeBytes(size, format);
12671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ASSERT_EQ(4U, pixel_size);
12681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
12691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ResourceProvider::ResourceId id1 = child_resource_provider_->CreateResource(
127003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureHintImmutable, format);
12711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  uint8_t data1[4] = { 1, 2, 3, 4 };
12721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  gfx::Rect rect(size);
12731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  child_resource_provider_->SetPixels(id1, data1, rect, rect, gfx::Vector2d());
12741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
12751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ResourceProvider::ResourceId id2 = child_resource_provider_->CreateResource(
127603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureHintImmutable, format);
127768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  uint8_t data2[4] = {5, 5, 5, 5};
12781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  child_resource_provider_->SetPixels(id2, data2, rect, rect, gfx::Vector2d());
127968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
128068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  ReturnedResourceArray returned_to_child;
128168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  int child_id =
128268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      resource_provider_->CreateChild(GetReturnCallback(&returned_to_child));
128368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  {
128468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    // Transfer some resources to the parent.
128568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    ResourceProvider::ResourceIdArray resource_ids_to_transfer;
128668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    resource_ids_to_transfer.push_back(id1);
128768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    resource_ids_to_transfer.push_back(id2);
128868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    TransferableResourceArray list;
12891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
12901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                                  &list);
129168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    ASSERT_EQ(2u, list.size());
12921e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    if (GetParam() == ResourceProvider::GLTexture) {
12935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      EXPECT_NE(0u, list[0].mailbox_holder.sync_point);
12945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      EXPECT_NE(0u, list[1].mailbox_holder.sync_point);
12951e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    }
12961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id1));
12971e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id2));
129868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    resource_provider_->ReceiveFromChild(child_id, list);
129968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    resource_provider_->DeclareUsedResourcesFromChild(child_id,
130068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                                      resource_ids_to_transfer);
130168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
130268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
130368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_EQ(2u, resource_provider_->num_resources());
130468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  ResourceProvider::ResourceIdMap resource_map =
130568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      resource_provider_->GetChildToParentMap(child_id);
130668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  ResourceProvider::ResourceId mapped_id1 = resource_map[id1];
130768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  ResourceProvider::ResourceId mapped_id2 = resource_map[id2];
130868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_NE(0u, mapped_id1);
130968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_NE(0u, mapped_id2);
131068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_FALSE(resource_provider_->InUseByConsumer(id1));
131168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_FALSE(resource_provider_->InUseByConsumer(id2));
131268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
131368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  {
131468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    // The parent transfers the resources to the grandparent.
131568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    ResourceProvider::ResourceIdArray resource_ids_to_transfer;
131668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    resource_ids_to_transfer.push_back(mapped_id1);
131768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    resource_ids_to_transfer.push_back(mapped_id2);
131868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    TransferableResourceArray list;
131968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    resource_provider_->PrepareSendToParent(resource_ids_to_transfer, &list);
132068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
132168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    ASSERT_EQ(2u, list.size());
13221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    if (GetParam() == ResourceProvider::GLTexture) {
13235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      EXPECT_NE(0u, list[0].mailbox_holder.sync_point);
13245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      EXPECT_NE(0u, list[1].mailbox_holder.sync_point);
13251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    }
132668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    EXPECT_TRUE(resource_provider_->InUseByConsumer(id1));
132768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    EXPECT_TRUE(resource_provider_->InUseByConsumer(id2));
132868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
132968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    // Release the resource in the parent. Set no resources as being in use. The
133068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    // resources are exported so that can't be transferred back yet.
133168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    ResourceProvider::ResourceIdArray no_resources;
133268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    resource_provider_->DeclareUsedResourcesFromChild(child_id, no_resources);
133368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
133468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    EXPECT_EQ(0u, returned_to_child.size());
133568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    EXPECT_EQ(2u, resource_provider_->num_resources());
133668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
133768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    // Return the resources from the grandparent to the parent. They should be
133868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    // returned to the child then.
133968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    EXPECT_EQ(2u, list.size());
134068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    EXPECT_EQ(mapped_id1, list[0].id);
134168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    EXPECT_EQ(mapped_id2, list[1].id);
134268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    ReturnedResourceArray returned;
134368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    TransferableResource::ReturnResources(list, &returned);
134468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    resource_provider_->ReceiveReturnsFromParent(returned);
134568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
134668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    EXPECT_EQ(0u, resource_provider_->num_resources());
134768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    ASSERT_EQ(2u, returned_to_child.size());
13481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    if (GetParam() == ResourceProvider::GLTexture) {
13491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      EXPECT_NE(0u, returned_to_child[0].sync_point);
13501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      EXPECT_NE(0u, returned_to_child[1].sync_point);
13511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    }
135268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    EXPECT_FALSE(returned_to_child[0].lost);
135368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    EXPECT_FALSE(returned_to_child[1].lost);
135468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
135568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
135668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
135768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)TEST_P(ResourceProviderTest, DestroyChildWithExportedResources) {
135868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  gfx::Size size(1, 1);
135968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  ResourceFormat format = RGBA_8888;
13604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  size_t pixel_size = TextureSizeBytes(size, format);
136168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  ASSERT_EQ(4U, pixel_size);
136268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
13631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ResourceProvider::ResourceId id1 = child_resource_provider_->CreateResource(
136403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureHintImmutable, format);
136568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  uint8_t data1[4] = {1, 2, 3, 4};
136668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  gfx::Rect rect(size);
13671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  child_resource_provider_->SetPixels(id1, data1, rect, rect, gfx::Vector2d());
136868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
13691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ResourceProvider::ResourceId id2 = child_resource_provider_->CreateResource(
137003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureHintImmutable, format);
137168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  uint8_t data2[4] = {5, 5, 5, 5};
13721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  child_resource_provider_->SetPixels(id2, data2, rect, rect, gfx::Vector2d());
137368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
137468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  ReturnedResourceArray returned_to_child;
137568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  int child_id =
137668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      resource_provider_->CreateChild(GetReturnCallback(&returned_to_child));
137768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  {
137868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    // Transfer some resources to the parent.
137968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    ResourceProvider::ResourceIdArray resource_ids_to_transfer;
138068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    resource_ids_to_transfer.push_back(id1);
138168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    resource_ids_to_transfer.push_back(id2);
138268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    TransferableResourceArray list;
13831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
13841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                                  &list);
138568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    ASSERT_EQ(2u, list.size());
13861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    if (GetParam() == ResourceProvider::GLTexture) {
13875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      EXPECT_NE(0u, list[0].mailbox_holder.sync_point);
13885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      EXPECT_NE(0u, list[1].mailbox_holder.sync_point);
13891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    }
13901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id1));
13911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id2));
139268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    resource_provider_->ReceiveFromChild(child_id, list);
139368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    resource_provider_->DeclareUsedResourcesFromChild(child_id,
139468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                                      resource_ids_to_transfer);
139568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
139668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
139768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_EQ(2u, resource_provider_->num_resources());
139868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  ResourceProvider::ResourceIdMap resource_map =
139968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      resource_provider_->GetChildToParentMap(child_id);
140068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  ResourceProvider::ResourceId mapped_id1 = resource_map[id1];
140168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  ResourceProvider::ResourceId mapped_id2 = resource_map[id2];
140268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_NE(0u, mapped_id1);
140368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_NE(0u, mapped_id2);
140468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_FALSE(resource_provider_->InUseByConsumer(id1));
140568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_FALSE(resource_provider_->InUseByConsumer(id2));
140668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
140768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  {
140868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    // The parent transfers the resources to the grandparent.
140968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    ResourceProvider::ResourceIdArray resource_ids_to_transfer;
141068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    resource_ids_to_transfer.push_back(mapped_id1);
141168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    resource_ids_to_transfer.push_back(mapped_id2);
141268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    TransferableResourceArray list;
141368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    resource_provider_->PrepareSendToParent(resource_ids_to_transfer, &list);
141468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
141568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    ASSERT_EQ(2u, list.size());
14161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    if (GetParam() == ResourceProvider::GLTexture) {
14175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      EXPECT_NE(0u, list[0].mailbox_holder.sync_point);
14185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      EXPECT_NE(0u, list[1].mailbox_holder.sync_point);
14191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    }
142068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    EXPECT_TRUE(resource_provider_->InUseByConsumer(id1));
142168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    EXPECT_TRUE(resource_provider_->InUseByConsumer(id2));
142268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
142368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    // Release the resource in the parent. Set no resources as being in use. The
142468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    // resources are exported so that can't be transferred back yet.
142568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    ResourceProvider::ResourceIdArray no_resources;
142668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    resource_provider_->DeclareUsedResourcesFromChild(child_id, no_resources);
142768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
1428f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // Destroy the child, the resources should not be returned yet.
142968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    EXPECT_EQ(0u, returned_to_child.size());
143068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    EXPECT_EQ(2u, resource_provider_->num_resources());
143168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
143268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    resource_provider_->DestroyChild(child_id);
143368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
1434f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_EQ(2u, resource_provider_->num_resources());
1435f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    ASSERT_EQ(0u, returned_to_child.size());
143668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
1437f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // Return a resource from the grandparent, it should be returned at this
1438f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // point.
143968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    EXPECT_EQ(2u, list.size());
144068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    EXPECT_EQ(mapped_id1, list[0].id);
144168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    EXPECT_EQ(mapped_id2, list[1].id);
1442f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    TransferableResourceArray return_list;
1443f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return_list.push_back(list[1]);
1444f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    list.pop_back();
144568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    ReturnedResourceArray returned;
1446f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    TransferableResource::ReturnResources(return_list, &returned);
144768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    resource_provider_->ReceiveReturnsFromParent(returned);
144868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
1449f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_EQ(1u, resource_provider_->num_resources());
1450f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    ASSERT_EQ(1u, returned_to_child.size());
1451f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (GetParam() == ResourceProvider::GLTexture) {
1452f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      EXPECT_NE(0u, returned_to_child[0].sync_point);
1453f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
1454f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_FALSE(returned_to_child[0].lost);
1455f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    returned_to_child.clear();
1456f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1457f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // Destroy the parent resource provider. The resource that's left should be
1458f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // lost at this point, and returned.
1459f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    resource_provider_.reset();
1460f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    ASSERT_EQ(1u, returned_to_child.size());
1461f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (GetParam() == ResourceProvider::GLTexture) {
1462f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      EXPECT_NE(0u, returned_to_child[0].sync_point);
1463f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
1464f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_TRUE(returned_to_child[0].lost);
146568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
14662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
14672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_P(ResourceProviderTest, DeleteTransferredResources) {
14692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Size size(1, 1);
1470d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  ResourceFormat format = RGBA_8888;
14714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  size_t pixel_size = TextureSizeBytes(size, format);
14722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(4U, pixel_size);
14732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ResourceProvider::ResourceId id = child_resource_provider_->CreateResource(
147503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureHintImmutable, format);
14762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  uint8_t data[4] = { 1, 2, 3, 4 };
14772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect rect(size);
14781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  child_resource_provider_->SetPixels(id, data, rect, rect, gfx::Vector2d());
14792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
148068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  ReturnedResourceArray returned_to_child;
148168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  int child_id =
148268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      resource_provider_->CreateChild(GetReturnCallback(&returned_to_child));
14832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
14842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Transfer some resource to the parent.
14852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ResourceProvider::ResourceIdArray resource_ids_to_transfer;
14862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    resource_ids_to_transfer.push_back(id);
14872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TransferableResourceArray list;
14881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
14891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                                  &list);
14902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_EQ(1u, list.size());
14911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    if (GetParam() == ResourceProvider::GLTexture)
14925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      EXPECT_NE(0u, list[0].mailbox_holder.sync_point);
14931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id));
14942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    resource_provider_->ReceiveFromChild(child_id, list);
149568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    resource_provider_->DeclareUsedResourcesFromChild(child_id,
149668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                                      resource_ids_to_transfer);
14972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
14982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Delete textures in the child, while they are transfered.
15001e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  child_resource_provider_->DeleteResource(id);
15011e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_EQ(1u, child_resource_provider_->num_resources());
15022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
150368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    EXPECT_EQ(0u, returned_to_child.size());
150468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
150568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    // Transfer resources back from the parent to the child. Set no resources as
150668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    // being in use.
150768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    ResourceProvider::ResourceIdArray no_resources;
150868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    resource_provider_->DeclareUsedResourcesFromChild(child_id, no_resources);
150968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
151068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    ASSERT_EQ(1u, returned_to_child.size());
15111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    if (GetParam() == ResourceProvider::GLTexture)
15121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      EXPECT_NE(0u, returned_to_child[0].sync_point);
15131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    child_resource_provider_->ReceiveReturnsFromParent(returned_to_child);
15142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
15151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_EQ(0u, child_resource_provider_->num_resources());
15162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
15172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1518a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_P(ResourceProviderTest, UnuseTransferredResources) {
1519a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  gfx::Size size(1, 1);
1520a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ResourceFormat format = RGBA_8888;
1521a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  size_t pixel_size = TextureSizeBytes(size, format);
1522a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_EQ(4U, pixel_size);
1523a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1524a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ResourceProvider::ResourceId id = child_resource_provider_->CreateResource(
152503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureHintImmutable, format);
1526a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  uint8_t data[4] = {1, 2, 3, 4};
1527a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  gfx::Rect rect(size);
1528a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  child_resource_provider_->SetPixels(id, data, rect, rect, gfx::Vector2d());
1529a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1530a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ReturnedResourceArray returned_to_child;
1531a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  int child_id =
1532a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      resource_provider_->CreateChild(GetReturnCallback(&returned_to_child));
1533a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  const ResourceProvider::ResourceIdMap& map =
1534a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      resource_provider_->GetChildToParentMap(child_id);
1535a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  {
1536a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // Transfer some resource to the parent.
1537a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ResourceProvider::ResourceIdArray resource_ids_to_transfer;
1538a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    resource_ids_to_transfer.push_back(id);
1539a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    TransferableResourceArray list;
1540a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
1541a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                                  &list);
1542a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id));
1543a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    resource_provider_->ReceiveFromChild(child_id, list);
1544a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    resource_provider_->DeclareUsedResourcesFromChild(child_id,
1545a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                                      resource_ids_to_transfer);
1546a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
1547a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  TransferableResourceArray sent_to_top_level;
1548a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  {
1549a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // Parent transfers to top-level.
1550a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ASSERT_TRUE(map.find(id) != map.end());
1551a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ResourceProvider::ResourceId parent_id = map.find(id)->second;
1552a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ResourceProvider::ResourceIdArray resource_ids_to_transfer;
1553a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    resource_ids_to_transfer.push_back(parent_id);
1554a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
1555a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                            &sent_to_top_level);
1556a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_TRUE(resource_provider_->InUseByConsumer(parent_id));
1557a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
1558a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  {
1559a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // Stop using resource.
1560a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ResourceProvider::ResourceIdArray empty;
1561a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    resource_provider_->DeclareUsedResourcesFromChild(child_id, empty);
1562a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // Resource is not yet returned to the child, since it's in use by the
1563a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // top-level.
1564a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_TRUE(returned_to_child.empty());
1565a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
1566a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  {
1567a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // Send the resource to the parent again.
1568a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ResourceProvider::ResourceIdArray resource_ids_to_transfer;
1569a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    resource_ids_to_transfer.push_back(id);
1570a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    TransferableResourceArray list;
1571a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
1572a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                                  &list);
1573a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id));
1574a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    resource_provider_->ReceiveFromChild(child_id, list);
1575a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    resource_provider_->DeclareUsedResourcesFromChild(child_id,
1576a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                                      resource_ids_to_transfer);
1577a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
1578a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  {
1579a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // Receive returns back from top-level.
1580a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ReturnedResourceArray returned;
1581a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    TransferableResource::ReturnResources(sent_to_top_level, &returned);
1582a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    resource_provider_->ReceiveReturnsFromParent(returned);
1583a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // Resource is still not yet returned to the child, since it's declared used
1584a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // in the parent.
1585a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_TRUE(returned_to_child.empty());
1586a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ASSERT_TRUE(map.find(id) != map.end());
1587a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ResourceProvider::ResourceId parent_id = map.find(id)->second;
1588a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_FALSE(resource_provider_->InUseByConsumer(parent_id));
1589a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
1590a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  {
1591a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    sent_to_top_level.clear();
1592a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // Parent transfers again to top-level.
1593a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ASSERT_TRUE(map.find(id) != map.end());
1594a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ResourceProvider::ResourceId parent_id = map.find(id)->second;
1595a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ResourceProvider::ResourceIdArray resource_ids_to_transfer;
1596a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    resource_ids_to_transfer.push_back(parent_id);
1597a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
1598a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                            &sent_to_top_level);
1599a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_TRUE(resource_provider_->InUseByConsumer(parent_id));
1600a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
1601a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  {
1602a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // Receive returns back from top-level.
1603a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ReturnedResourceArray returned;
1604a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    TransferableResource::ReturnResources(sent_to_top_level, &returned);
1605a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    resource_provider_->ReceiveReturnsFromParent(returned);
1606a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // Resource is still not yet returned to the child, since it's still
1607a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // declared used in the parent.
1608a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_TRUE(returned_to_child.empty());
1609a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ASSERT_TRUE(map.find(id) != map.end());
1610a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ResourceProvider::ResourceId parent_id = map.find(id)->second;
1611a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_FALSE(resource_provider_->InUseByConsumer(parent_id));
1612a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
1613a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  {
1614a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // Stop using resource.
1615a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ResourceProvider::ResourceIdArray empty;
1616a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    resource_provider_->DeclareUsedResourcesFromChild(child_id, empty);
1617a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // Resource should have been returned to the child, since it's no longer in
1618a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // use by the top-level.
1619a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ASSERT_EQ(1u, returned_to_child.size());
1620a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_EQ(id, returned_to_child[0].id);
1621a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_EQ(2, returned_to_child[0].count);
1622a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    child_resource_provider_->ReceiveReturnsFromParent(returned_to_child);
1623a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    returned_to_child.clear();
1624a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_FALSE(child_resource_provider_->InUseByConsumer(id));
1625a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
1626a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
1627a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1628d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)class ResourceProviderTestTextureFilters : public ResourceProviderTest {
1629d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) public:
1630d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  static void RunTest(GLenum child_filter, GLenum parent_filter) {
1631d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    scoped_ptr<TextureStateTrackingContext> child_context_owned(
1632d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        new TextureStateTrackingContext);
1633d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    TextureStateTrackingContext* child_context = child_context_owned.get();
16342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1635d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    FakeOutputSurfaceClient child_output_surface_client;
1636d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    scoped_ptr<OutputSurface> child_output_surface(FakeOutputSurface::Create3d(
1637d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        child_context_owned.PassAs<TestWebGraphicsContext3D>()));
1638d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    CHECK(child_output_surface->BindToClient(&child_output_surface_client));
163923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
164023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        new TestSharedBitmapManager());
16413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1642d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    scoped_ptr<ResourceProvider> child_resource_provider(
16430f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        ResourceProvider::Create(child_output_surface.get(),
164423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)                                 shared_bitmap_manager.get(),
16451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                 NULL,
16460f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                                 0,
16470f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                                 false,
1648010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                                 1,
1649010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                                 false));
16503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1651d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    scoped_ptr<TextureStateTrackingContext> parent_context_owned(
1652d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        new TextureStateTrackingContext);
1653d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    TextureStateTrackingContext* parent_context = parent_context_owned.get();
16542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1655d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    FakeOutputSurfaceClient parent_output_surface_client;
1656d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    scoped_ptr<OutputSurface> parent_output_surface(FakeOutputSurface::Create3d(
1657d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        parent_context_owned.PassAs<TestWebGraphicsContext3D>()));
1658d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    CHECK(parent_output_surface->BindToClient(&parent_output_surface_client));
16592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1660d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    scoped_ptr<ResourceProvider> parent_resource_provider(
16610f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        ResourceProvider::Create(parent_output_surface.get(),
166223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)                                 shared_bitmap_manager.get(),
16631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                 NULL,
16640f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                                 0,
16650f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                                 false,
1666010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                                 1,
1667010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                                 false));
16682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1669d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    gfx::Size size(1, 1);
1670d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    ResourceFormat format = RGBA_8888;
16714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    int child_texture_id = 1;
16724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    int parent_texture_id = 2;
1673d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
16744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    size_t pixel_size = TextureSizeBytes(size, format);
1675d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    ASSERT_EQ(4U, pixel_size);
1676d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
1677d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    ResourceProvider::ResourceId id = child_resource_provider->CreateResource(
167803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureHintImmutable, format);
1679d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
1680d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    // The new texture is created with GL_LINEAR.
16814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    EXPECT_CALL(*child_context, bindTexture(GL_TEXTURE_2D, child_texture_id))
1682d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        .Times(2);  // Once to create and once to allocate.
1683d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    EXPECT_CALL(*child_context,
1684d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
1685d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    EXPECT_CALL(*child_context,
1686d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
1687d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    EXPECT_CALL(
1688d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        *child_context,
1689d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
1690d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    EXPECT_CALL(
1691d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        *child_context,
1692d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
1693d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    EXPECT_CALL(*child_context,
1694d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                texParameteri(GL_TEXTURE_2D,
1695d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                              GL_TEXTURE_POOL_CHROMIUM,
1696d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                              GL_TEXTURE_POOL_UNMANAGED_CHROMIUM));
1697d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    child_resource_provider->AllocateForTesting(id);
1698d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    Mock::VerifyAndClearExpectations(child_context);
1699d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
1700d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    uint8_t data[4] = { 1, 2, 3, 4 };
1701d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    gfx::Rect rect(size);
1702d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
17034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    EXPECT_CALL(*child_context, bindTexture(GL_TEXTURE_2D, child_texture_id));
1704d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    child_resource_provider->SetPixels(id, data, rect, rect, gfx::Vector2d());
1705d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    Mock::VerifyAndClearExpectations(child_context);
1706d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
1707d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    // The texture is set to |child_filter| in the child.
17084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    EXPECT_CALL(*child_context, bindTexture(GL_TEXTURE_2D, child_texture_id));
1709d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    if (child_filter != GL_LINEAR) {
1710d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      EXPECT_CALL(
1711d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)          *child_context,
1712d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)          texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, child_filter));
1713d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      EXPECT_CALL(
1714d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)          *child_context,
1715d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)          texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, child_filter));
1716d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    }
1717d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    SetResourceFilter(child_resource_provider.get(), id, child_filter);
1718d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    Mock::VerifyAndClearExpectations(child_context);
1719d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
172068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    ReturnedResourceArray returned_to_child;
172168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    int child_id = parent_resource_provider->CreateChild(
172268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        GetReturnCallback(&returned_to_child));
1723d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    {
1724d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      // Transfer some resource to the parent.
1725d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      ResourceProvider::ResourceIdArray resource_ids_to_transfer;
1726d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      resource_ids_to_transfer.push_back(id);
1727d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      TransferableResourceArray list;
1728d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
17294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      EXPECT_CALL(*child_context, bindTexture(GL_TEXTURE_2D, child_texture_id));
1730d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      EXPECT_CALL(*child_context,
1731d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                  produceTextureCHROMIUM(GL_TEXTURE_2D, _));
1732d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      EXPECT_CALL(*child_context, insertSyncPoint());
1733d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      child_resource_provider->PrepareSendToParent(resource_ids_to_transfer,
1734d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                                   &list);
1735d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      Mock::VerifyAndClearExpectations(child_context);
1736d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
1737d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      ASSERT_EQ(1u, list.size());
1738d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      EXPECT_EQ(static_cast<unsigned>(child_filter), list[0].filter);
1739d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
1740d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      EXPECT_CALL(*parent_context,
17414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                  bindTexture(GL_TEXTURE_2D, parent_texture_id));
17424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      EXPECT_CALL(*parent_context, consumeTextureCHROMIUM(GL_TEXTURE_2D, _));
1743d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      parent_resource_provider->ReceiveFromChild(child_id, list);
17445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      {
174503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        parent_resource_provider->WaitSyncPointIfNeeded(list[0].id);
17465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        ResourceProvider::ScopedReadLockGL lock(parent_resource_provider.get(),
17475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                                list[0].id);
17485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      }
1749d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      Mock::VerifyAndClearExpectations(parent_context);
175068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
175168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      parent_resource_provider->DeclareUsedResourcesFromChild(
175268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          child_id, resource_ids_to_transfer);
175368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      Mock::VerifyAndClearExpectations(parent_context);
1754d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    }
1755d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    ResourceProvider::ResourceIdMap resource_map =
1756d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        parent_resource_provider->GetChildToParentMap(child_id);
1757d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    ResourceProvider::ResourceId mapped_id = resource_map[id];
1758d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    EXPECT_NE(0u, mapped_id);
1759d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
1760d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    // The texture is set to |parent_filter| in the parent.
17614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    EXPECT_CALL(*parent_context, bindTexture(GL_TEXTURE_2D, parent_texture_id));
1762d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    EXPECT_CALL(
1763d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        *parent_context,
1764d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, parent_filter));
1765d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    EXPECT_CALL(
1766d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        *parent_context,
1767d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, parent_filter));
1768d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    SetResourceFilter(parent_resource_provider.get(), mapped_id, parent_filter);
1769d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    Mock::VerifyAndClearExpectations(parent_context);
1770d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
1771d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    // The texture should be reset to |child_filter| in the parent when it is
1772d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    // returned, since that is how it was received.
17734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    EXPECT_CALL(*parent_context, bindTexture(GL_TEXTURE_2D, parent_texture_id));
1774d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    EXPECT_CALL(
1775d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        *parent_context,
1776d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, child_filter));
1777d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    EXPECT_CALL(
1778d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        *parent_context,
1779d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, child_filter));
1780d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
1781d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    {
178268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      EXPECT_EQ(0u, returned_to_child.size());
1783d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
178468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      // Transfer resources back from the parent to the child. Set no resources
178568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      // as being in use.
178668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      ResourceProvider::ResourceIdArray no_resources;
1787d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      EXPECT_CALL(*parent_context, insertSyncPoint());
178868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      parent_resource_provider->DeclareUsedResourcesFromChild(child_id,
178968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                                              no_resources);
179068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      Mock::VerifyAndClearExpectations(parent_context);
1791d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
179268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      ASSERT_EQ(1u, returned_to_child.size());
179368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      child_resource_provider->ReceiveReturnsFromParent(returned_to_child);
1794d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    }
1795d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
1796d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    // The child remembers the texture filter is set to |child_filter|.
17974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    EXPECT_CALL(*child_context, bindTexture(GL_TEXTURE_2D, child_texture_id));
1798d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    SetResourceFilter(child_resource_provider.get(), id, child_filter);
1799d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    Mock::VerifyAndClearExpectations(child_context);
18002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1801d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)};
1802d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
1803d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)TEST_P(ResourceProviderTest, TextureFilters_ChildNearestParentLinear) {
1804d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (GetParam() != ResourceProvider::GLTexture)
1805d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    return;
1806d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  ResourceProviderTestTextureFilters::RunTest(GL_NEAREST, GL_LINEAR);
1807d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
1808d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
1809d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)TEST_P(ResourceProviderTest, TextureFilters_ChildLinearParentNearest) {
1810d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (GetParam() != ResourceProvider::GLTexture)
1811d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    return;
1812d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  ResourceProviderTestTextureFilters::RunTest(GL_LINEAR, GL_NEAREST);
18132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
18142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_P(ResourceProviderTest, TransferMailboxResources) {
18161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // Other mailbox transfers tested elsewhere.
18172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (GetParam() != ResourceProvider::GLTexture)
18182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
18192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  unsigned texture = context()->createTexture();
18202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  context()->bindTexture(GL_TEXTURE_2D, texture);
18212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  uint8_t data[4] = { 1, 2, 3, 4 };
18222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  context()->texImage2D(
18232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &data);
18242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gpu::Mailbox mailbox;
18252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  context()->genMailboxCHROMIUM(mailbox.name);
18262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  context()->produceTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name);
18275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  uint32 sync_point = context()->insertSyncPoint();
18282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // All the logic below assumes that the sync points are all positive.
18302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_LT(0u, sync_point);
18312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  uint32 release_sync_point = 0;
1833c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool lost_resource = false;
18341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  BlockingTaskRunner* main_thread_task_runner = NULL;
18351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ReleaseCallbackImpl callback = base::Bind(ReleaseCallback,
18361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                            &release_sync_point,
18371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                            &lost_resource,
18381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                            &main_thread_task_runner);
18392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ResourceProvider::ResourceId resource =
18402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      resource_provider_->CreateResourceFromTextureMailbox(
18415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          TextureMailbox(mailbox, GL_TEXTURE_2D, sync_point),
18421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          SingleReleaseCallbackImpl::Create(callback));
18434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(1u, context()->NumTextures());
18442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0u, release_sync_point);
18452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
18462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Transfer the resource, expect the sync points to be consistent.
18472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ResourceProvider::ResourceIdArray resource_ids_to_transfer;
18482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    resource_ids_to_transfer.push_back(resource);
18492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TransferableResourceArray list;
18502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    resource_provider_->PrepareSendToParent(resource_ids_to_transfer, &list);
18512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_EQ(1u, list.size());
18525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_LE(sync_point, list[0].mailbox_holder.sync_point);
1853c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(0,
18545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              memcmp(mailbox.name,
18555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                     list[0].mailbox_holder.mailbox.name,
18565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                     sizeof(mailbox.name)));
18572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(0u, release_sync_point);
18582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    context()->waitSyncPoint(list[0].mailbox_holder.sync_point);
18602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    unsigned other_texture = context()->createTexture();
18612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    context()->bindTexture(GL_TEXTURE_2D, other_texture);
18622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    context()->consumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name);
18632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    uint8_t test_data[4] = { 0 };
1864d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    context()->GetPixels(
1865d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        gfx::Size(1, 1), RGBA_8888, test_data);
1866c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(0, memcmp(data, test_data, sizeof(data)));
18672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    context()->produceTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name);
18682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    context()->deleteTexture(other_texture);
18695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    list[0].mailbox_holder.sync_point = context()->insertSyncPoint();
18705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_LT(0u, list[0].mailbox_holder.sync_point);
18712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Receive the resource, then delete it, expect the sync points to be
18732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // consistent.
18743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ReturnedResourceArray returned;
18753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    TransferableResource::ReturnResources(list, &returned);
18763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    resource_provider_->ReceiveReturnsFromParent(returned);
18774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    EXPECT_EQ(1u, context()->NumTextures());
18782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(0u, release_sync_point);
18792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    resource_provider_->DeleteResource(resource);
18815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_LE(list[0].mailbox_holder.sync_point, release_sync_point);
1882c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_FALSE(lost_resource);
18831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_EQ(main_thread_task_runner_.get(), main_thread_task_runner);
18842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
18852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We're going to do the same thing as above, but testing the case where we
18872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // delete the resource before we receive it back.
18882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  sync_point = release_sync_point;
18892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_LT(0u, sync_point);
18902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  release_sync_point = 0;
18912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource = resource_provider_->CreateResourceFromTextureMailbox(
18925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      TextureMailbox(mailbox, GL_TEXTURE_2D, sync_point),
18931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      SingleReleaseCallbackImpl::Create(callback));
18944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(1u, context()->NumTextures());
18952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0u, release_sync_point);
18962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
18972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Transfer the resource, expect the sync points to be consistent.
18982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ResourceProvider::ResourceIdArray resource_ids_to_transfer;
18992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    resource_ids_to_transfer.push_back(resource);
19002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TransferableResourceArray list;
19012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    resource_provider_->PrepareSendToParent(resource_ids_to_transfer, &list);
19022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_EQ(1u, list.size());
19035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_LE(sync_point, list[0].mailbox_holder.sync_point);
1904c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(0,
19055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              memcmp(mailbox.name,
19065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                     list[0].mailbox_holder.mailbox.name,
19075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                     sizeof(mailbox.name)));
19082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(0u, release_sync_point);
19092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
19105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    context()->waitSyncPoint(list[0].mailbox_holder.sync_point);
19112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    unsigned other_texture = context()->createTexture();
19122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    context()->bindTexture(GL_TEXTURE_2D, other_texture);
19132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    context()->consumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name);
19142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    uint8_t test_data[4] = { 0 };
1915d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    context()->GetPixels(
1916d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        gfx::Size(1, 1), RGBA_8888, test_data);
1917c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(0, memcmp(data, test_data, sizeof(data)));
19182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    context()->produceTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name);
19192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    context()->deleteTexture(other_texture);
19205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    list[0].mailbox_holder.sync_point = context()->insertSyncPoint();
19215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_LT(0u, list[0].mailbox_holder.sync_point);
19222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
19232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Delete the resource, which shouldn't do anything.
19242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    resource_provider_->DeleteResource(resource);
19254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    EXPECT_EQ(1u, context()->NumTextures());
19262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(0u, release_sync_point);
19272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
19282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Then receive the resource which should release the mailbox, expect the
19292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // sync points to be consistent.
19303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ReturnedResourceArray returned;
19313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    TransferableResource::ReturnResources(list, &returned);
19323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    resource_provider_->ReceiveReturnsFromParent(returned);
19335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_LE(list[0].mailbox_holder.sync_point, release_sync_point);
1934c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_FALSE(lost_resource);
19351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_EQ(main_thread_task_runner_.get(), main_thread_task_runner);
19362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
19372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
19382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  context()->waitSyncPoint(release_sync_point);
19392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  context()->bindTexture(GL_TEXTURE_2D, texture);
19402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  context()->consumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name);
19412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  context()->deleteTexture(texture);
19422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
19432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
194468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)TEST_P(ResourceProviderTest, LostResourceInParent) {
194568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  gfx::Size size(1, 1);
194668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  ResourceFormat format = RGBA_8888;
194768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  ResourceProvider::ResourceId resource =
19481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      child_resource_provider_->CreateResource(
194903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)          size,
195003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)          GL_CLAMP_TO_EDGE,
195103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)          ResourceProvider::TextureHintImmutable,
195203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)          format);
19531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  child_resource_provider_->AllocateForTesting(resource);
19541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // Expect a GL resource to be lost.
19551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  bool should_lose_resource = GetParam() == ResourceProvider::GLTexture;
195668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
195768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  ReturnedResourceArray returned_to_child;
195868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  int child_id =
195968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      resource_provider_->CreateChild(GetReturnCallback(&returned_to_child));
196068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  {
196168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    // Transfer the resource to the parent.
196268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    ResourceProvider::ResourceIdArray resource_ids_to_transfer;
196368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    resource_ids_to_transfer.push_back(resource);
196468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    TransferableResourceArray list;
19651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
19661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                                  &list);
196768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    EXPECT_EQ(1u, list.size());
196868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
196968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    resource_provider_->ReceiveFromChild(child_id, list);
197068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    resource_provider_->DeclareUsedResourcesFromChild(child_id,
197168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                                      resource_ids_to_transfer);
197268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
197368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
197468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // Lose the output surface in the parent.
197568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  resource_provider_->DidLoseOutputSurface();
197668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
197768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  {
197868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    EXPECT_EQ(0u, returned_to_child.size());
197968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
198068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    // Transfer resources back from the parent to the child. Set no resources as
198168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    // being in use.
198268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    ResourceProvider::ResourceIdArray no_resources;
198368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    resource_provider_->DeclareUsedResourcesFromChild(child_id, no_resources);
198468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
19851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // Expect a GL resource to be lost.
198668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    ASSERT_EQ(1u, returned_to_child.size());
19871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    EXPECT_EQ(should_lose_resource, returned_to_child[0].lost);
19881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    child_resource_provider_->ReceiveReturnsFromParent(returned_to_child);
198968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    returned_to_child.clear();
199068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
199168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
19921e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // A GL resource should be lost.
19931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_EQ(should_lose_resource, child_resource_provider_->IsLost(resource));
199468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
199568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // Lost resources stay in use in the parent forever.
19961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_EQ(should_lose_resource,
19971e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)            child_resource_provider_->InUseByConsumer(resource));
199868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
199968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
200068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)TEST_P(ResourceProviderTest, LostResourceInGrandParent) {
200168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  gfx::Size size(1, 1);
200268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  ResourceFormat format = RGBA_8888;
200368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  ResourceProvider::ResourceId resource =
20041e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      child_resource_provider_->CreateResource(
200503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)          size,
200603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)          GL_CLAMP_TO_EDGE,
200703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)          ResourceProvider::TextureHintImmutable,
200803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)          format);
20091e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  child_resource_provider_->AllocateForTesting(resource);
201068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
201168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  ReturnedResourceArray returned_to_child;
201268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  int child_id =
201368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      resource_provider_->CreateChild(GetReturnCallback(&returned_to_child));
201468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  {
201568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    // Transfer the resource to the parent.
201668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    ResourceProvider::ResourceIdArray resource_ids_to_transfer;
201768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    resource_ids_to_transfer.push_back(resource);
201868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    TransferableResourceArray list;
20191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
20201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                                  &list);
202168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    EXPECT_EQ(1u, list.size());
202268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
202368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    resource_provider_->ReceiveFromChild(child_id, list);
202468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    resource_provider_->DeclareUsedResourcesFromChild(child_id,
202568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                                      resource_ids_to_transfer);
202668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
202768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
202868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  {
202968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    ResourceProvider::ResourceIdMap resource_map =
203068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        resource_provider_->GetChildToParentMap(child_id);
203168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    ResourceProvider::ResourceId parent_resource = resource_map[resource];
203268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    EXPECT_NE(0u, parent_resource);
203368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
203468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    // Transfer to a grandparent.
203568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    ResourceProvider::ResourceIdArray resource_ids_to_transfer;
203668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    resource_ids_to_transfer.push_back(parent_resource);
203768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    TransferableResourceArray list;
203868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    resource_provider_->PrepareSendToParent(resource_ids_to_transfer, &list);
203968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
204068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    // Receive back a lost resource from the grandparent.
204168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    EXPECT_EQ(1u, list.size());
204268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    EXPECT_EQ(parent_resource, list[0].id);
204368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    ReturnedResourceArray returned;
204468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    TransferableResource::ReturnResources(list, &returned);
204568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    EXPECT_EQ(1u, returned.size());
204668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    EXPECT_EQ(parent_resource, returned[0].id);
204768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    returned[0].lost = true;
204868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    resource_provider_->ReceiveReturnsFromParent(returned);
204968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
205068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    // The resource should be lost.
205168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    EXPECT_TRUE(resource_provider_->IsLost(parent_resource));
205268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
205368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    // Lost resources stay in use in the parent forever.
205468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    EXPECT_TRUE(resource_provider_->InUseByConsumer(parent_resource));
205568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
205668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
205768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  {
205868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    EXPECT_EQ(0u, returned_to_child.size());
205968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
206068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    // Transfer resources back from the parent to the child. Set no resources as
206168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    // being in use.
206268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    ResourceProvider::ResourceIdArray no_resources;
206368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    resource_provider_->DeclareUsedResourcesFromChild(child_id, no_resources);
206468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
206568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    // Expect the resource to be lost.
206668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    ASSERT_EQ(1u, returned_to_child.size());
206768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    EXPECT_TRUE(returned_to_child[0].lost);
20681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    child_resource_provider_->ReceiveReturnsFromParent(returned_to_child);
206968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    returned_to_child.clear();
207068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
207168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
207268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // The resource should be lost.
20731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_TRUE(child_resource_provider_->IsLost(resource));
207468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
207568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // Lost resources stay in use in the parent forever.
20761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_TRUE(child_resource_provider_->InUseByConsumer(resource));
207768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
207868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
207968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)TEST_P(ResourceProviderTest, LostMailboxInParent) {
20805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  uint32 release_sync_point = 0;
208168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  bool lost_resource = false;
20821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  bool release_called = false;
20835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  uint32 sync_point = 0;
20841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ResourceProvider::ResourceId resource = CreateChildMailbox(
20851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      &release_sync_point, &lost_resource, &release_called, &sync_point);
208668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
208768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  ReturnedResourceArray returned_to_child;
208868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  int child_id =
208968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      resource_provider_->CreateChild(GetReturnCallback(&returned_to_child));
209068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  {
209168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    // Transfer the resource to the parent.
209268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    ResourceProvider::ResourceIdArray resource_ids_to_transfer;
209368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    resource_ids_to_transfer.push_back(resource);
209468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    TransferableResourceArray list;
20951e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
20961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                                  &list);
209768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    EXPECT_EQ(1u, list.size());
209868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
209968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    resource_provider_->ReceiveFromChild(child_id, list);
210068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    resource_provider_->DeclareUsedResourcesFromChild(child_id,
210168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                                      resource_ids_to_transfer);
210268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
210368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
210468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // Lose the output surface in the parent.
210568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  resource_provider_->DidLoseOutputSurface();
210668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
210768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  {
210868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    EXPECT_EQ(0u, returned_to_child.size());
210968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
211068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    // Transfer resources back from the parent to the child. Set no resources as
211168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    // being in use.
211268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    ResourceProvider::ResourceIdArray no_resources;
211368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    resource_provider_->DeclareUsedResourcesFromChild(child_id, no_resources);
211468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
211568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    ASSERT_EQ(1u, returned_to_child.size());
21161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // Losing an output surface only loses hardware resources.
21171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    EXPECT_EQ(returned_to_child[0].lost,
21181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)              GetParam() == ResourceProvider::GLTexture);
21191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    child_resource_provider_->ReceiveReturnsFromParent(returned_to_child);
212068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    returned_to_child.clear();
212168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
212268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
21231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // Delete the resource in the child. Expect the resource to be lost if it's
21241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // a GL texture.
21251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  child_resource_provider_->DeleteResource(resource);
21261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_EQ(lost_resource, GetParam() == ResourceProvider::GLTexture);
212768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
212868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
212968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)TEST_P(ResourceProviderTest, LostMailboxInGrandParent) {
21305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  uint32 release_sync_point = 0;
213168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  bool lost_resource = false;
21321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  bool release_called = false;
21335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  uint32 sync_point = 0;
21341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ResourceProvider::ResourceId resource = CreateChildMailbox(
21351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      &release_sync_point, &lost_resource, &release_called, &sync_point);
213668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
213768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  ReturnedResourceArray returned_to_child;
213868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  int child_id =
213968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      resource_provider_->CreateChild(GetReturnCallback(&returned_to_child));
214068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  {
214168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    // Transfer the resource to the parent.
214268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    ResourceProvider::ResourceIdArray resource_ids_to_transfer;
214368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    resource_ids_to_transfer.push_back(resource);
214468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    TransferableResourceArray list;
21451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
21461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                                  &list);
214768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    EXPECT_EQ(1u, list.size());
214868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
214968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    resource_provider_->ReceiveFromChild(child_id, list);
215068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    resource_provider_->DeclareUsedResourcesFromChild(child_id,
215168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                                      resource_ids_to_transfer);
215268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
215368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
215468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  {
215568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    ResourceProvider::ResourceIdMap resource_map =
215668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        resource_provider_->GetChildToParentMap(child_id);
215768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    ResourceProvider::ResourceId parent_resource = resource_map[resource];
215868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    EXPECT_NE(0u, parent_resource);
215968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
216068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    // Transfer to a grandparent.
216168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    ResourceProvider::ResourceIdArray resource_ids_to_transfer;
216268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    resource_ids_to_transfer.push_back(parent_resource);
216368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    TransferableResourceArray list;
216468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    resource_provider_->PrepareSendToParent(resource_ids_to_transfer, &list);
216568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
216668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    // Receive back a lost resource from the grandparent.
216768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    EXPECT_EQ(1u, list.size());
216868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    EXPECT_EQ(parent_resource, list[0].id);
216968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    ReturnedResourceArray returned;
217068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    TransferableResource::ReturnResources(list, &returned);
217168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    EXPECT_EQ(1u, returned.size());
217268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    EXPECT_EQ(parent_resource, returned[0].id);
217368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    returned[0].lost = true;
217468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    resource_provider_->ReceiveReturnsFromParent(returned);
217568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
217668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
217768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  {
217868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    EXPECT_EQ(0u, returned_to_child.size());
217968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
218068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    // Transfer resources back from the parent to the child. Set no resources as
218168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    // being in use.
218268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    ResourceProvider::ResourceIdArray no_resources;
218368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    resource_provider_->DeclareUsedResourcesFromChild(child_id, no_resources);
218468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
218568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    // Expect the resource to be lost.
218668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    ASSERT_EQ(1u, returned_to_child.size());
218768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    EXPECT_TRUE(returned_to_child[0].lost);
21881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    child_resource_provider_->ReceiveReturnsFromParent(returned_to_child);
218968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    returned_to_child.clear();
219068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
219168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
219268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // Delete the resource in the child. Expect the resource to be lost.
21931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  child_resource_provider_->DeleteResource(resource);
219468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_TRUE(lost_resource);
219568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
219668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
2197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_P(ResourceProviderTest, Shutdown) {
21985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  uint32 release_sync_point = 0;
2199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool lost_resource = false;
22001e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  bool release_called = false;
22015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  uint32 sync_point = 0;
22021e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  CreateChildMailbox(
22031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      &release_sync_point, &lost_resource, &release_called, &sync_point);
2204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0u, release_sync_point);
2206c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(lost_resource);
2207c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
22081e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  child_resource_provider_.reset();
2209868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
22101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (GetParam() == ResourceProvider::GLTexture) {
22111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    EXPECT_LE(sync_point, release_sync_point);
22121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
2213868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(release_called);
22141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_FALSE(lost_resource);
2215868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
2216868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2217c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_P(ResourceProviderTest, ShutdownWithExportedResource) {
22185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  uint32 release_sync_point = 0;
2219c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool lost_resource = false;
22201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  bool release_called = false;
22215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  uint32 sync_point = 0;
22221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ResourceProvider::ResourceId resource = CreateChildMailbox(
22231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      &release_sync_point, &lost_resource, &release_called, &sync_point);
2224c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2225c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Transfer the resource, so we can't release it properly on shutdown.
2226c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ResourceProvider::ResourceIdArray resource_ids_to_transfer;
2227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  resource_ids_to_transfer.push_back(resource);
2228c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TransferableResourceArray list;
22291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
22301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                                &list);
2231c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0u, release_sync_point);
2233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(lost_resource);
2234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
22351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  child_resource_provider_.reset();
2236c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2237c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Since the resource is in the parent, the child considers it lost.
2238c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0u, release_sync_point);
2239c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(lost_resource);
2240c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
2241c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2242c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_P(ResourceProviderTest, LostContext) {
2243c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // TextureMailbox callbacks only exist for GL textures for now.
2244c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (GetParam() != ResourceProvider::GLTexture)
2245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
2246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  unsigned texture = context()->createTexture();
2247c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  context()->bindTexture(GL_TEXTURE_2D, texture);
2248c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  gpu::Mailbox mailbox;
2249c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  context()->genMailboxCHROMIUM(mailbox.name);
2250c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  context()->produceTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name);
22515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  uint32 sync_point = context()->insertSyncPoint();
2252c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2253c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_LT(0u, sync_point);
2254c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
22555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  uint32 release_sync_point = 0;
2256c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool lost_resource = false;
22571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  BlockingTaskRunner* main_thread_task_runner = NULL;
22581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<SingleReleaseCallbackImpl> callback =
22591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      SingleReleaseCallbackImpl::Create(base::Bind(ReleaseCallback,
22601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                                   &release_sync_point,
22611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                                   &lost_resource,
22621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                                   &main_thread_task_runner));
2263c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  resource_provider_->CreateResourceFromTextureMailbox(
22645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      TextureMailbox(mailbox, GL_TEXTURE_2D, sync_point), callback.Pass());
2265c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2266c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0u, release_sync_point);
2267c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(lost_resource);
22681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(NULL, main_thread_task_runner);
2269c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2270c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  resource_provider_->DidLoseOutputSurface();
2271c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  resource_provider_.reset();
2272c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2273c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_LE(sync_point, release_sync_point);
2274c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(lost_resource);
22751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(main_thread_task_runner_.get(), main_thread_task_runner);
2276c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
2277c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
22782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_P(ResourceProviderTest, ScopedSampler) {
22792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Sampling is only supported for GL textures.
22802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (GetParam() != ResourceProvider::GLTexture)
22812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
22822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
22833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<TextureStateTrackingContext> context_owned(
22843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      new TextureStateTrackingContext);
22853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  TextureStateTrackingContext* context = context_owned.get();
22863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
22873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  FakeOutputSurfaceClient output_surface_client;
22883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
22893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      context_owned.PassAs<TestWebGraphicsContext3D>()));
22903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  CHECK(output_surface->BindToClient(&output_surface_client));
22913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
22921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<ResourceProvider> resource_provider(
22931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      ResourceProvider::Create(output_surface.get(),
22941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               shared_bitmap_manager_.get(),
22951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               NULL,
22961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               0,
22971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               false,
22981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               1,
22991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               false));
23002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
23012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Size size(1, 1);
2302d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  ResourceFormat format = RGBA_8888;
23032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int texture_id = 1;
23042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2305d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  ResourceProvider::ResourceId id = resource_provider->CreateResource(
230603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureHintImmutable, format);
2307d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
23082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Check that the texture gets created with the right sampler settings.
23092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id))
23102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      .Times(2);  // Once to create and once to allocate.
23112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*context,
23122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
23132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*context,
23142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
23152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(
23162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      *context,
23172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
23182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(
23192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      *context,
23202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
23212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*context,
23222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              texParameteri(GL_TEXTURE_2D,
23232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            GL_TEXTURE_POOL_CHROMIUM,
23242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            GL_TEXTURE_POOL_UNMANAGED_CHROMIUM));
2325d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
23262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_provider->AllocateForTesting(id);
2327d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  Mock::VerifyAndClearExpectations(context);
23282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
23292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Creating a sampler with the default filter should not change any texture
23302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // parameters.
23312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
23322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id));
23332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ResourceProvider::ScopedSamplerGL sampler(
23342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        resource_provider.get(), id, GL_TEXTURE_2D, GL_LINEAR);
2335d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    Mock::VerifyAndClearExpectations(context);
23362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
23372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
23382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Using a different filter should be reflected in the texture parameters.
23392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
23402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id));
23412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_CALL(
23422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        *context,
23432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST));
23442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_CALL(
23452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        *context,
23462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
23472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ResourceProvider::ScopedSamplerGL sampler(
23482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        resource_provider.get(), id, GL_TEXTURE_2D, GL_NEAREST);
2349d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    Mock::VerifyAndClearExpectations(context);
23502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
23512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
23522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Test resetting to the default filter.
23532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
23542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id));
23552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_CALL(*context,
23562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
23572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_CALL(*context,
23582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
23592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ResourceProvider::ScopedSamplerGL sampler(
23602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        resource_provider.get(), id, GL_TEXTURE_2D, GL_LINEAR);
2361d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    Mock::VerifyAndClearExpectations(context);
23622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
23632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
23642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
23652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_P(ResourceProviderTest, ManagedResource) {
23662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Sampling is only supported for GL textures.
23672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (GetParam() != ResourceProvider::GLTexture)
23682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
23692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
23703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<TextureStateTrackingContext> context_owned(
23713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      new TextureStateTrackingContext);
23723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  TextureStateTrackingContext* context = context_owned.get();
23733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
23743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  FakeOutputSurfaceClient output_surface_client;
23753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
23763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      context_owned.PassAs<TestWebGraphicsContext3D>()));
23773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  CHECK(output_surface->BindToClient(&output_surface_client));
23783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
23791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<ResourceProvider> resource_provider(
23801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      ResourceProvider::Create(output_surface.get(),
23811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               shared_bitmap_manager_.get(),
23821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               NULL,
23831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               0,
23841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               false,
23851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               1,
23861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               false));
23872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
23882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Size size(1, 1);
2389d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  ResourceFormat format = RGBA_8888;
23902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int texture_id = 1;
23912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
23922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Check that the texture gets created with the right sampler settings.
2393868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ResourceProvider::ResourceId id = resource_provider->CreateManagedResource(
2394f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      size,
2395f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      GL_TEXTURE_2D,
2396f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      GL_CLAMP_TO_EDGE,
239703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      ResourceProvider::TextureHintImmutable,
2398f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      format);
23992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id));
24002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*context,
24012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
24022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*context,
24032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
24042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(
24052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      *context,
24062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
24072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(
24082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      *context,
24092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
24102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*context,
24112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              texParameteri(GL_TEXTURE_2D,
24122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            GL_TEXTURE_POOL_CHROMIUM,
24132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            GL_TEXTURE_POOL_MANAGED_CHROMIUM));
2414868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  resource_provider->CreateForTesting(id);
2415c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_NE(0u, id);
24162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
24172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Mock::VerifyAndClearExpectations(context);
24182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
24192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
242058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)TEST_P(ResourceProviderTest, TextureWrapMode) {
242158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Sampling is only supported for GL textures.
242258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (GetParam() != ResourceProvider::GLTexture)
242358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return;
242458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
242558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  scoped_ptr<TextureStateTrackingContext> context_owned(
242658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      new TextureStateTrackingContext);
242758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  TextureStateTrackingContext* context = context_owned.get();
242858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
242958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  FakeOutputSurfaceClient output_surface_client;
243058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
243158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      context_owned.PassAs<TestWebGraphicsContext3D>()));
243258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  CHECK(output_surface->BindToClient(&output_surface_client));
243358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
24341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<ResourceProvider> resource_provider(
24351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      ResourceProvider::Create(output_surface.get(),
24361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               shared_bitmap_manager_.get(),
24371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               NULL,
24381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               0,
24391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               false,
24401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               1,
24411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               false));
244258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
244358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  gfx::Size size(1, 1);
2444d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  ResourceFormat format = RGBA_8888;
244558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  GLenum texture_pool = GL_TEXTURE_POOL_UNMANAGED_CHROMIUM;
244658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
24474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  for (int texture_id = 1; texture_id <= 2; ++texture_id) {
24484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    GLint wrap_mode = texture_id == 1 ? GL_CLAMP_TO_EDGE : GL_REPEAT;
244958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // Check that the texture gets created with the right sampler settings.
245003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    ResourceProvider::ResourceId id = resource_provider->CreateGLTexture(
245103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        size,
245203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        GL_TEXTURE_2D,
245303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        texture_pool,
245403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        wrap_mode,
245503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        ResourceProvider::TextureHintImmutable,
245603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        format);
245703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id));
245803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    EXPECT_CALL(*context,
245903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
246003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    EXPECT_CALL(*context,
246103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
246203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    EXPECT_CALL(*context,
246303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap_mode));
246403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    EXPECT_CALL(*context,
246503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap_mode));
246603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    EXPECT_CALL(*context,
246703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                texParameteri(GL_TEXTURE_2D,
246803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                              GL_TEXTURE_POOL_CHROMIUM,
246903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                              GL_TEXTURE_POOL_UNMANAGED_CHROMIUM));
247003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    resource_provider->CreateForTesting(id);
247103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    EXPECT_NE(0u, id);
247203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
247303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    Mock::VerifyAndClearExpectations(context);
247403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
247503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
247603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
247703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)TEST_P(ResourceProviderTest, TextureHint) {
247803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Sampling is only supported for GL textures.
247903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (GetParam() != ResourceProvider::GLTexture)
248003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    return;
248103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
248203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  scoped_ptr<TextureStateTrackingContext> context_owned(
248303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      new TextureStateTrackingContext);
248403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  TextureStateTrackingContext* context = context_owned.get();
248503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  context->set_support_texture_storage(true);
248603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  context->set_support_texture_usage(true);
248703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
248803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  FakeOutputSurfaceClient output_surface_client;
248903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
249003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      context_owned.PassAs<TestWebGraphicsContext3D>()));
249103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  CHECK(output_surface->BindToClient(&output_surface_client));
249203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
24931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<ResourceProvider> resource_provider(
24941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      ResourceProvider::Create(output_surface.get(),
24951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               shared_bitmap_manager_.get(),
24961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               NULL,
24971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               0,
24981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               false,
24991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               1,
25001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               false));
250103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
250203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  gfx::Size size(1, 1);
250303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  ResourceFormat format = RGBA_8888;
250403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  GLenum texture_pool = GL_TEXTURE_POOL_UNMANAGED_CHROMIUM;
250503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
250603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  const ResourceProvider::TextureHint hints[4] = {
250703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      ResourceProvider::TextureHintDefault,
250803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      ResourceProvider::TextureHintImmutable,
250903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      ResourceProvider::TextureHintFramebuffer,
251003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      ResourceProvider::TextureHintImmutableFramebuffer,
251103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  };
251203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  for (GLuint texture_id = 1; texture_id <= arraysize(hints); ++texture_id) {
251303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    // Check that the texture gets created with the right sampler settings.
2514d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    ResourceProvider::ResourceId id =
2515d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        resource_provider->CreateGLTexture(size,
2516f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                           GL_TEXTURE_2D,
2517d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                           texture_pool,
251803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                           GL_CLAMP_TO_EDGE,
251903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                           hints[texture_id - 1],
2520d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                           format);
252158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id));
252258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    EXPECT_CALL(*context,
252358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
252458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    EXPECT_CALL(*context,
252558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
252658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    EXPECT_CALL(
252758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        *context,
252803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
252958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    EXPECT_CALL(
253058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        *context,
253103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
253258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    EXPECT_CALL(*context,
253358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                texParameteri(GL_TEXTURE_2D,
253458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                              GL_TEXTURE_POOL_CHROMIUM,
253558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                              GL_TEXTURE_POOL_UNMANAGED_CHROMIUM));
253603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    // Check only TextureHintFramebuffer set GL_TEXTURE_USAGE_ANGLE.
253703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    bool is_framebuffer_hint =
253803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        hints[texture_id - 1] & ResourceProvider::TextureHintFramebuffer;
253903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    EXPECT_CALL(*context,
254003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                texParameteri(GL_TEXTURE_2D,
254103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                              GL_TEXTURE_USAGE_ANGLE,
254203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                              GL_FRAMEBUFFER_ATTACHMENT_ANGLE))
254303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        .Times(is_framebuffer_hint ? 1 : 0);
254458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    resource_provider->CreateForTesting(id);
254558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    EXPECT_NE(0u, id);
254658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
254758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    Mock::VerifyAndClearExpectations(context);
254858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
254958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
255058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
2551868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)TEST_P(ResourceProviderTest, TextureMailbox_SharedMemory) {
2552868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (GetParam() != ResourceProvider::Bitmap)
2553868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return;
2554868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2555868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  gfx::Size size(64, 64);
2556868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const uint32_t kBadBeef = 0xbadbeef;
2557868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  scoped_ptr<base::SharedMemory> shared_memory(
2558868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      CreateAndFillSharedMemory(size, kBadBeef));
2559868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
25603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  FakeOutputSurfaceClient output_surface_client;
2561868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  scoped_ptr<OutputSurface> output_surface(
2562868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      FakeOutputSurface::CreateSoftware(make_scoped_ptr(
2563868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          new SoftwareOutputDevice)));
25643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  CHECK(output_surface->BindToClient(&output_surface_client));
25653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
25661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<ResourceProvider> resource_provider(
25671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      ResourceProvider::Create(output_surface.get(),
25681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               shared_bitmap_manager_.get(),
25691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               main_thread_task_runner_.get(),
25701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               0,
25711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               false,
25721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               1,
25731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               false));
2574868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
25751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  uint32 release_sync_point = 0;
25761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  bool lost_resource = false;
25771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  BlockingTaskRunner* main_thread_task_runner = NULL;
25781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<SingleReleaseCallbackImpl> callback =
25791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      SingleReleaseCallbackImpl::Create(base::Bind(&ReleaseCallback,
25801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                                   &release_sync_point,
25811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                                   &lost_resource,
25821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                                   &main_thread_task_runner));
2583d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  TextureMailbox mailbox(shared_memory.get(), size);
2584868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2585868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ResourceProvider::ResourceId id =
2586d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      resource_provider->CreateResourceFromTextureMailbox(
2587d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)          mailbox, callback.Pass());
2588868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_NE(0u, id);
2589868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2590868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  {
2591868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    ResourceProvider::ScopedReadLockSoftware lock(resource_provider.get(), id);
2592868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const SkBitmap* sk_bitmap = lock.sk_bitmap();
2593868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    EXPECT_EQ(sk_bitmap->width(), size.width());
2594868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    EXPECT_EQ(sk_bitmap->height(), size.height());
2595868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    EXPECT_EQ(*sk_bitmap->getAddr32(16, 16), kBadBeef);
2596868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
25971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
25981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  resource_provider->DeleteResource(id);
25991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(0u, release_sync_point);
26001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_FALSE(lost_resource);
26011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(main_thread_task_runner_.get(), main_thread_task_runner);
2602868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
2603868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2604c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_P(ResourceProviderTest, TextureMailbox_GLTexture2D) {
2605c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Mailboxing is only supported for GL textures.
2606c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (GetParam() != ResourceProvider::GLTexture)
2607c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
2608c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
26093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<TextureStateTrackingContext> context_owned(
26103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      new TextureStateTrackingContext);
26113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  TextureStateTrackingContext* context = context_owned.get();
26123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
26133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  FakeOutputSurfaceClient output_surface_client;
26143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
26153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      context_owned.PassAs<TestWebGraphicsContext3D>()));
26163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  CHECK(output_surface->BindToClient(&output_surface_client));
26173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
26181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<ResourceProvider> resource_provider(
26191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      ResourceProvider::Create(output_surface.get(),
26201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               shared_bitmap_manager_.get(),
26211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               main_thread_task_runner_.get(),
26221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               0,
26231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               false,
26241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               1,
26251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               false));
2626c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2627c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  unsigned texture_id = 1;
26285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  uint32 sync_point = 30;
2629c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  unsigned target = GL_TEXTURE_2D;
2630c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2631c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*context, bindTexture(_, _)).Times(0);
2632c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*context, waitSyncPoint(_)).Times(0);
2633c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*context, insertSyncPoint()).Times(0);
2634c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*context, produceTextureCHROMIUM(_, _)).Times(0);
2635c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*context, consumeTextureCHROMIUM(_, _)).Times(0);
2636c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2637c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  gpu::Mailbox gpu_mailbox;
2638c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  memcpy(gpu_mailbox.name, "Hello world", strlen("Hello world") + 1);
26391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  uint32 release_sync_point = 0;
26401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  bool lost_resource = false;
26411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  BlockingTaskRunner* main_thread_task_runner = NULL;
26421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<SingleReleaseCallbackImpl> callback =
26431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      SingleReleaseCallbackImpl::Create(base::Bind(&ReleaseCallback,
26441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                                   &release_sync_point,
26451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                                   &lost_resource,
26461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                                   &main_thread_task_runner));
2647c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
26485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  TextureMailbox mailbox(gpu_mailbox, target, sync_point);
2649c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2650c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ResourceProvider::ResourceId id =
2651d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      resource_provider->CreateResourceFromTextureMailbox(
2652d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)          mailbox, callback.Pass());
2653c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_NE(0u, id);
2654c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2655c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  Mock::VerifyAndClearExpectations(context);
2656c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2657c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  {
265803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    // Mailbox sync point WaitSyncPoint before using the texture.
265903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    EXPECT_CALL(*context, waitSyncPoint(sync_point));
266003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    resource_provider->WaitSyncPointIfNeeded(id);
266103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    Mock::VerifyAndClearExpectations(context);
266203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
2663c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Using the texture does a consume of the mailbox.
2664c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_CALL(*context, bindTexture(target, texture_id));
2665c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_CALL(*context, consumeTextureCHROMIUM(target, _));
2666c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2667c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_CALL(*context, insertSyncPoint()).Times(0);
2668c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_CALL(*context, produceTextureCHROMIUM(_, _)).Times(0);
2669c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2670c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ResourceProvider::ScopedReadLockGL lock(resource_provider.get(), id);
2671c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    Mock::VerifyAndClearExpectations(context);
2672c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
26737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // When done with it, a sync point should be inserted, but no produce is
26747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // necessary.
26757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    EXPECT_CALL(*context, bindTexture(_, _)).Times(0);
2676c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_CALL(*context, insertSyncPoint());
26777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    EXPECT_CALL(*context, produceTextureCHROMIUM(_, _)).Times(0);
2678c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2679c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_CALL(*context, waitSyncPoint(_)).Times(0);
2680c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_CALL(*context, consumeTextureCHROMIUM(_, _)).Times(0);
2681c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
26821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
26831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  resource_provider->DeleteResource(id);
26841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(0u, release_sync_point);
26851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_FALSE(lost_resource);
26861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(main_thread_task_runner_.get(), main_thread_task_runner);
2687c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
2688c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2689c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_P(ResourceProviderTest, TextureMailbox_GLTextureExternalOES) {
2690c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Mailboxing is only supported for GL textures.
2691c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (GetParam() != ResourceProvider::GLTexture)
2692c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
2693c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
26943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<TextureStateTrackingContext> context_owned(
26953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      new TextureStateTrackingContext);
26963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  TextureStateTrackingContext* context = context_owned.get();
26973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
26983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  FakeOutputSurfaceClient output_surface_client;
26993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
27003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      context_owned.PassAs<TestWebGraphicsContext3D>()));
27013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  CHECK(output_surface->BindToClient(&output_surface_client));
27023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
27031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<ResourceProvider> resource_provider(
27041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      ResourceProvider::Create(output_surface.get(),
27051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               shared_bitmap_manager_.get(),
27061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               NULL,
27071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               0,
27081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               false,
27091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               1,
27101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               false));
2711c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2712c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  unsigned texture_id = 1;
27135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  uint32 sync_point = 30;
2714c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  unsigned target = GL_TEXTURE_EXTERNAL_OES;
2715c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2716c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*context, bindTexture(_, _)).Times(0);
2717c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*context, waitSyncPoint(_)).Times(0);
2718c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*context, insertSyncPoint()).Times(0);
2719c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*context, produceTextureCHROMIUM(_, _)).Times(0);
2720c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*context, consumeTextureCHROMIUM(_, _)).Times(0);
2721c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2722c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  gpu::Mailbox gpu_mailbox;
2723c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  memcpy(gpu_mailbox.name, "Hello world", strlen("Hello world") + 1);
27241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<SingleReleaseCallbackImpl> callback =
27251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      SingleReleaseCallbackImpl::Create(base::Bind(&EmptyReleaseCallback));
2726c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2727d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  TextureMailbox mailbox(gpu_mailbox, target, sync_point);
2728c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2729c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ResourceProvider::ResourceId id =
2730d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      resource_provider->CreateResourceFromTextureMailbox(
2731d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)          mailbox, callback.Pass());
2732c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_NE(0u, id);
2733c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2734c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  Mock::VerifyAndClearExpectations(context);
2735c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2736c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  {
273703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    // Mailbox sync point WaitSyncPoint before using the texture.
273803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    EXPECT_CALL(*context, waitSyncPoint(sync_point));
273903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    resource_provider->WaitSyncPointIfNeeded(id);
274003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    Mock::VerifyAndClearExpectations(context);
274103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
2742c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Using the texture does a consume of the mailbox.
2743c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_CALL(*context, bindTexture(target, texture_id));
2744c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_CALL(*context, consumeTextureCHROMIUM(target, _));
2745c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2746c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_CALL(*context, insertSyncPoint()).Times(0);
2747c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_CALL(*context, produceTextureCHROMIUM(_, _)).Times(0);
2748c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2749c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ResourceProvider::ScopedReadLockGL lock(resource_provider.get(), id);
2750c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    Mock::VerifyAndClearExpectations(context);
2751c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
27527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // When done with it, a sync point should be inserted, but no produce is
27537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // necessary.
27547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    EXPECT_CALL(*context, bindTexture(_, _)).Times(0);
2755c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_CALL(*context, insertSyncPoint());
27567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    EXPECT_CALL(*context, produceTextureCHROMIUM(_, _)).Times(0);
2757c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2758c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_CALL(*context, waitSyncPoint(_)).Times(0);
2759c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_CALL(*context, consumeTextureCHROMIUM(_, _)).Times(0);
2760c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
2761c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
2762c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
276303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)TEST_P(ResourceProviderTest,
276403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)       TextureMailbox_WaitSyncPointIfNeeded_WithSyncPoint) {
276503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Mailboxing is only supported for GL textures.
276603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (GetParam() != ResourceProvider::GLTexture)
276703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    return;
276803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
276903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  scoped_ptr<TextureStateTrackingContext> context_owned(
277003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      new TextureStateTrackingContext);
277103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  TextureStateTrackingContext* context = context_owned.get();
277203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
277303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  FakeOutputSurfaceClient output_surface_client;
277403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
277503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      context_owned.PassAs<TestWebGraphicsContext3D>()));
277603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  CHECK(output_surface->BindToClient(&output_surface_client));
277703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
27781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<ResourceProvider> resource_provider(
27791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      ResourceProvider::Create(output_surface.get(),
27801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               shared_bitmap_manager_.get(),
27811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               NULL,
27821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               0,
27831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               false,
27841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               1,
27851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               false));
278603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
278703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  uint32 sync_point = 30;
278803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  unsigned target = GL_TEXTURE_2D;
278903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
279003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  EXPECT_CALL(*context, bindTexture(_, _)).Times(0);
279103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  EXPECT_CALL(*context, waitSyncPoint(_)).Times(0);
279203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  EXPECT_CALL(*context, insertSyncPoint()).Times(0);
279303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  EXPECT_CALL(*context, produceTextureCHROMIUM(_, _)).Times(0);
279403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  EXPECT_CALL(*context, consumeTextureCHROMIUM(_, _)).Times(0);
279503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
279603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  gpu::Mailbox gpu_mailbox;
279703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  memcpy(gpu_mailbox.name, "Hello world", strlen("Hello world") + 1);
27981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<SingleReleaseCallbackImpl> callback =
27991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      SingleReleaseCallbackImpl::Create(base::Bind(&EmptyReleaseCallback));
280003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
280103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  TextureMailbox mailbox(gpu_mailbox, target, sync_point);
280203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
280303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  ResourceProvider::ResourceId id =
280403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      resource_provider->CreateResourceFromTextureMailbox(mailbox,
280503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                                          callback.Pass());
280603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  EXPECT_NE(0u, id);
280703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
280803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  Mock::VerifyAndClearExpectations(context);
280903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
281003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  {
281103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    // First call to WaitSyncPointIfNeeded should call waitSyncPoint.
281203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    EXPECT_CALL(*context, waitSyncPoint(sync_point));
281303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    resource_provider->WaitSyncPointIfNeeded(id);
281403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    Mock::VerifyAndClearExpectations(context);
281503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
281603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    // Subsequent calls to WaitSyncPointIfNeeded shouldn't call waitSyncPoint.
281703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    EXPECT_CALL(*context, waitSyncPoint(_)).Times(0);
281803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    resource_provider->WaitSyncPointIfNeeded(id);
281903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    Mock::VerifyAndClearExpectations(context);
282003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
282103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
282203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
282303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)TEST_P(ResourceProviderTest, TextureMailbox_WaitSyncPointIfNeeded_NoSyncPoint) {
282403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Mailboxing is only supported for GL textures.
282503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (GetParam() != ResourceProvider::GLTexture)
282603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    return;
282703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
282803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  scoped_ptr<TextureStateTrackingContext> context_owned(
282903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      new TextureStateTrackingContext);
283003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  TextureStateTrackingContext* context = context_owned.get();
283103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
283203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  FakeOutputSurfaceClient output_surface_client;
283303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
283403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      context_owned.PassAs<TestWebGraphicsContext3D>()));
283503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  CHECK(output_surface->BindToClient(&output_surface_client));
283603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
28371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<ResourceProvider> resource_provider(
28381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      ResourceProvider::Create(output_surface.get(),
28391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               shared_bitmap_manager_.get(),
28401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               NULL,
28411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               0,
28421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               false,
28431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               1,
28441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               false));
284503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
284603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  uint32 sync_point = 0;
284703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  unsigned target = GL_TEXTURE_2D;
284803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
284903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  EXPECT_CALL(*context, bindTexture(_, _)).Times(0);
285003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  EXPECT_CALL(*context, waitSyncPoint(_)).Times(0);
285103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  EXPECT_CALL(*context, insertSyncPoint()).Times(0);
285203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  EXPECT_CALL(*context, produceTextureCHROMIUM(_, _)).Times(0);
285303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  EXPECT_CALL(*context, consumeTextureCHROMIUM(_, _)).Times(0);
285403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
285503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  gpu::Mailbox gpu_mailbox;
285603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  memcpy(gpu_mailbox.name, "Hello world", strlen("Hello world") + 1);
28571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<SingleReleaseCallbackImpl> callback =
28581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      SingleReleaseCallbackImpl::Create(base::Bind(&EmptyReleaseCallback));
285903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
286003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  TextureMailbox mailbox(gpu_mailbox, target, sync_point);
286103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
286203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  ResourceProvider::ResourceId id =
286303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      resource_provider->CreateResourceFromTextureMailbox(mailbox,
286403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                                          callback.Pass());
286503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  EXPECT_NE(0u, id);
286603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
286703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  Mock::VerifyAndClearExpectations(context);
286803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
286903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  {
287003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    // WaitSyncPointIfNeeded with sync_point == 0 shouldn't call waitSyncPoint.
287103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    EXPECT_CALL(*context, waitSyncPoint(_)).Times(0);
287203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    resource_provider->WaitSyncPointIfNeeded(id);
287303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    Mock::VerifyAndClearExpectations(context);
287403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
287503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
287603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
28772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class AllocationTrackingContext3D : public TestWebGraphicsContext3D {
28782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
2879a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  MOCK_METHOD0(NextTextureId, GLuint());
2880a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  MOCK_METHOD1(RetireTextureId, void(GLuint id));
2881a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  MOCK_METHOD2(bindTexture, void(GLenum target, GLuint texture));
2882f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  MOCK_METHOD5(texStorage2DEXT,
2883a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)               void(GLenum target,
2884a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                    GLint levels,
2885a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                    GLuint internalformat,
2886a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                    GLint width,
2887a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                    GLint height));
28882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MOCK_METHOD9(texImage2D,
2889a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)               void(GLenum target,
2890a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                    GLint level,
2891a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                    GLenum internalformat,
2892a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                    GLsizei width,
2893a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                    GLsizei height,
2894a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                    GLint border,
2895a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                    GLenum format,
2896a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                    GLenum type,
28972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    const void* pixels));
28982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MOCK_METHOD9(texSubImage2D,
2899a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)               void(GLenum target,
2900a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                    GLint level,
2901a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                    GLint xoffset,
2902a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                    GLint yoffset,
2903a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                    GLsizei width,
2904a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                    GLsizei height,
2905a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                    GLenum format,
2906a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                    GLenum type,
29072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    const void* pixels));
29082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MOCK_METHOD9(asyncTexImage2DCHROMIUM,
2909a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)               void(GLenum target,
2910a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                    GLint level,
2911a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                    GLenum internalformat,
2912a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                    GLsizei width,
2913a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                    GLsizei height,
2914a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                    GLint border,
2915a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                    GLenum format,
2916a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                    GLenum type,
29172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    const void* pixels));
29182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MOCK_METHOD9(asyncTexSubImage2DCHROMIUM,
2919a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)               void(GLenum target,
2920a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                    GLint level,
2921a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                    GLint xoffset,
2922a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                    GLint yoffset,
2923a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                    GLsizei width,
2924a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                    GLsizei height,
2925a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                    GLenum format,
2926a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                    GLenum type,
29272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    const void* pixels));
29281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  MOCK_METHOD8(compressedTexImage2D,
2929a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)               void(GLenum target,
2930a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                    GLint level,
2931a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                    GLenum internalformat,
2932a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                    GLsizei width,
2933a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                    GLsizei height,
2934a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                    GLint border,
2935a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                    GLsizei image_size,
29361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                    const void* data));
2937a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  MOCK_METHOD1(waitAsyncTexImage2DCHROMIUM, void(GLenum));
2938010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  MOCK_METHOD4(createImageCHROMIUM, GLuint(GLsizei, GLsizei, GLenum, GLenum));
2939a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  MOCK_METHOD1(destroyImageCHROMIUM, void(GLuint));
2940010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  MOCK_METHOD1(mapImageCHROMIUM, void*(GLuint));
2941a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  MOCK_METHOD3(getImageParameterivCHROMIUM, void(GLuint, GLenum, GLint*));
2942a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  MOCK_METHOD1(unmapImageCHROMIUM, void(GLuint));
2943a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  MOCK_METHOD2(bindTexImage2DCHROMIUM, void(GLenum, GLint));
2944a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  MOCK_METHOD2(releaseTexImage2DCHROMIUM, void(GLenum, GLint));
2945f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
2946f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // We're mocking bindTexture, so we override
2947f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // TestWebGraphicsContext3D::texParameteri to avoid assertions related to the
2948f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // currently bound texture.
2949a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual void texParameteri(GLenum target, GLenum pname, GLint param) {}
29502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
29512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
29522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_P(ResourceProviderTest, TextureAllocation) {
29532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Only for GL textures.
29542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (GetParam() != ResourceProvider::GLTexture)
29552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
29563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<AllocationTrackingContext3D> context_owned(
29573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      new StrictMock<AllocationTrackingContext3D>);
29583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  AllocationTrackingContext3D* context = context_owned.get();
29593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
29603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  FakeOutputSurfaceClient output_surface_client;
29613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
29623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      context_owned.PassAs<TestWebGraphicsContext3D>()));
29633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  CHECK(output_surface->BindToClient(&output_surface_client));
29643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
29651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<ResourceProvider> resource_provider(
29661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      ResourceProvider::Create(output_surface.get(),
29671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               shared_bitmap_manager_.get(),
29681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               NULL,
29691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               0,
29701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               false,
29711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               1,
29721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               false));
29732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
29742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Size size(2, 2);
29752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Vector2d offset(0, 0);
29762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect rect(0, 0, 2, 2);
2977d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  ResourceFormat format = RGBA_8888;
29782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ResourceProvider::ResourceId id = 0;
29792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  uint8_t pixels[16] = { 0 };
29802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int texture_id = 123;
29812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
29822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Lazy allocation. Don't allocate when creating the resource.
29832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  id = resource_provider->CreateResource(
298403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureHintImmutable, format);
2985868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
29860f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_CALL(*context, NextTextureId()).WillOnce(Return(texture_id));
2987868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id)).Times(1);
2988868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  resource_provider->CreateForTesting(id);
2989868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
29900f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_CALL(*context, RetireTextureId(texture_id)).Times(1);
29912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_provider->DeleteResource(id);
2992868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
29932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Mock::VerifyAndClearExpectations(context);
29942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
29952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Do allocate when we set the pixels.
2996868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  id = resource_provider->CreateResource(
299703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureHintImmutable, format);
2998868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
29990f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_CALL(*context, NextTextureId()).WillOnce(Return(texture_id));
30002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id)).Times(3);
30012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*context, texImage2D(_, _, _, 2, 2, _, _, _, _)).Times(1);
30022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*context, texSubImage2D(_, _, _, _, 2, 2, _, _, _)).Times(1);
30032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_provider->SetPixels(id, pixels, rect, rect, offset);
3004868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
30050f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_CALL(*context, RetireTextureId(texture_id)).Times(1);
30062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_provider->DeleteResource(id);
3007868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
30082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Mock::VerifyAndClearExpectations(context);
30092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3010eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Same for async version.
3011868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  id = resource_provider->CreateResource(
301203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureHintImmutable, format);
30131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  resource_provider->AcquirePixelBuffer(id);
3014868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
30150f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_CALL(*context, NextTextureId()).WillOnce(Return(texture_id));
3016eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id)).Times(2);
3017eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_CALL(*context, asyncTexImage2DCHROMIUM(_, _, _, 2, 2, _, _, _, _))
3018eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      .Times(1);
3019eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  resource_provider->BeginSetPixels(id);
3020eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ASSERT_TRUE(resource_provider->DidSetPixelsComplete(id));
3021868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
30221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  resource_provider->ReleasePixelBuffer(id);
3023868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
30240f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_CALL(*context, RetireTextureId(texture_id)).Times(1);
30252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_provider->DeleteResource(id);
3026868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
30272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Mock::VerifyAndClearExpectations(context);
3028eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
3029eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
303003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)TEST_P(ResourceProviderTest, TextureAllocationHint) {
3031f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Only for GL textures.
3032f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (GetParam() != ResourceProvider::GLTexture)
3033f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return;
3034f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<AllocationTrackingContext3D> context_owned(
3035f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      new StrictMock<AllocationTrackingContext3D>);
3036f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  AllocationTrackingContext3D* context = context_owned.get();
3037f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  context->set_support_texture_storage(true);
303803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  context->set_support_texture_usage(true);
3039f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
3040f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  FakeOutputSurfaceClient output_surface_client;
3041f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
3042f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      context_owned.PassAs<TestWebGraphicsContext3D>()));
3043f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  CHECK(output_surface->BindToClient(&output_surface_client));
3044f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
30451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<ResourceProvider> resource_provider(
30461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      ResourceProvider::Create(output_surface.get(),
30471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               shared_bitmap_manager_.get(),
30481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               NULL,
30491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               0,
30501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               false,
30511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               1,
30521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               false));
3053f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
3054f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  gfx::Size size(2, 2);
3055f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
30561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const ResourceFormat formats[2] = {RGBA_8888, BGRA_8888};
305703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  const ResourceProvider::TextureHint hints[4] = {
305803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      ResourceProvider::TextureHintDefault,
305903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      ResourceProvider::TextureHintImmutable,
306003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      ResourceProvider::TextureHintFramebuffer,
306103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      ResourceProvider::TextureHintImmutableFramebuffer,
306203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  };
30631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  for (size_t i = 0; i < arraysize(formats); ++i) {
30641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    for (GLuint texture_id = 1; texture_id <= arraysize(hints); ++texture_id) {
30651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      // Lazy allocation. Don't allocate when creating the resource.
30661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      ResourceProvider::ResourceId id = resource_provider->CreateResource(
30671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          size, GL_CLAMP_TO_EDGE, hints[texture_id - 1], formats[i]);
30681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
30691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      EXPECT_CALL(*context, NextTextureId()).WillOnce(Return(texture_id));
30701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id)).Times(2);
30711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      bool is_immutable_hint =
30721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          hints[texture_id - 1] & ResourceProvider::TextureHintImmutable;
30731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      bool support_immutable_texture =
30741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          is_immutable_hint && formats[i] == RGBA_8888;
30751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      EXPECT_CALL(*context, texStorage2DEXT(_, _, _, 2, 2))
30761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          .Times(support_immutable_texture ? 1 : 0);
30771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      EXPECT_CALL(*context, texImage2D(_, _, _, 2, 2, _, _, _, _))
30781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          .Times(support_immutable_texture ? 0 : 1);
30791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      resource_provider->AllocateForTesting(id);
30801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
30811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      EXPECT_CALL(*context, RetireTextureId(texture_id)).Times(1);
30821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      resource_provider->DeleteResource(id);
30831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
30841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      Mock::VerifyAndClearExpectations(context);
30851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    }
30861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
30871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
3088f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
30891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_P(ResourceProviderTest, TextureAllocationHint_BGRA) {
30901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Only for GL textures.
30911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (GetParam() != ResourceProvider::GLTexture)
30921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
30931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<AllocationTrackingContext3D> context_owned(
30941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new StrictMock<AllocationTrackingContext3D>);
30951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  AllocationTrackingContext3D* context = context_owned.get();
30961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  context->set_support_texture_format_bgra8888(true);
30971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  context->set_support_texture_storage(true);
30981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  context->set_support_texture_usage(true);
3099f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
31001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  FakeOutputSurfaceClient output_surface_client;
31011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
31021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      context_owned.PassAs<TestWebGraphicsContext3D>()));
31031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  CHECK(output_surface->BindToClient(&output_surface_client));
31041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
31051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<ResourceProvider> resource_provider(
31061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      ResourceProvider::Create(output_surface.get(),
31071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               shared_bitmap_manager_.get(),
31081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               NULL,
31091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               0,
31101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               false,
31111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               1,
31121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               false));
31131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
31141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  gfx::Size size(2, 2);
31151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const ResourceFormat formats[2] = {RGBA_8888, BGRA_8888};
31161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
31171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const ResourceProvider::TextureHint hints[4] = {
31181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      ResourceProvider::TextureHintDefault,
31191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      ResourceProvider::TextureHintImmutable,
31201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      ResourceProvider::TextureHintFramebuffer,
31211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      ResourceProvider::TextureHintImmutableFramebuffer,
31221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  };
31231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  for (size_t i = 0; i < arraysize(formats); ++i) {
31241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    for (GLuint texture_id = 1; texture_id <= arraysize(hints); ++texture_id) {
31251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      // Lazy allocation. Don't allocate when creating the resource.
31261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      ResourceProvider::ResourceId id = resource_provider->CreateResource(
31271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          size, GL_CLAMP_TO_EDGE, hints[texture_id - 1], formats[i]);
31281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
31291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      EXPECT_CALL(*context, NextTextureId()).WillOnce(Return(texture_id));
31301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id)).Times(2);
31311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      bool is_immutable_hint =
31321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          hints[texture_id - 1] & ResourceProvider::TextureHintImmutable;
31331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      EXPECT_CALL(*context, texStorage2DEXT(_, _, _, 2, 2))
31341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          .Times(is_immutable_hint ? 1 : 0);
31351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      EXPECT_CALL(*context, texImage2D(_, _, _, 2, 2, _, _, _, _))
31361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          .Times(is_immutable_hint ? 0 : 1);
31371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      resource_provider->AllocateForTesting(id);
31381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
31391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      EXPECT_CALL(*context, RetireTextureId(texture_id)).Times(1);
31401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      resource_provider->DeleteResource(id);
31411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
31421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      Mock::VerifyAndClearExpectations(context);
31431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    }
314403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
3145f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
3146f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
3147eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(ResourceProviderTest, PixelBuffer_GLTexture) {
3148eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (GetParam() != ResourceProvider::GLTexture)
3149eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return;
31503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<AllocationTrackingContext3D> context_owned(
31513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      new StrictMock<AllocationTrackingContext3D>);
31523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  AllocationTrackingContext3D* context = context_owned.get();
31533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
31543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  FakeOutputSurfaceClient output_surface_client;
31553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
31563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      context_owned.PassAs<TestWebGraphicsContext3D>()));
31573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  CHECK(output_surface->BindToClient(&output_surface_client));
3158eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
3159eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  gfx::Size size(2, 2);
3160d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  ResourceFormat format = RGBA_8888;
3161eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ResourceProvider::ResourceId id = 0;
3162eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  int texture_id = 123;
3163eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
31641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<ResourceProvider> resource_provider(
31651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      ResourceProvider::Create(output_surface.get(),
31661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               shared_bitmap_manager_.get(),
31671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               NULL,
31681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               0,
31691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               false,
31701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               1,
31711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               false));
31722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3173868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  id = resource_provider->CreateResource(
317403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureHintImmutable, format);
31751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  resource_provider->AcquirePixelBuffer(id);
3176868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
31770f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_CALL(*context, NextTextureId()).WillOnce(Return(texture_id));
31782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id)).Times(2);
31792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*context, asyncTexImage2DCHROMIUM(_, _, _, 2, 2, _, _, _, _))
31802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      .Times(1);
31812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_provider->BeginSetPixels(id);
3182eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
3183eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_TRUE(resource_provider->DidSetPixelsComplete(id));
3184868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
31851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  resource_provider->ReleasePixelBuffer(id);
3186868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
31870f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_CALL(*context, RetireTextureId(texture_id)).Times(1);
31882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_provider->DeleteResource(id);
3189868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
31902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Mock::VerifyAndClearExpectations(context);
31912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
31922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
31932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_P(ResourceProviderTest, ForcingAsyncUploadToComplete) {
31942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Only for GL textures.
31952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (GetParam() != ResourceProvider::GLTexture)
31962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
31973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<AllocationTrackingContext3D> context_owned(
31983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      new StrictMock<AllocationTrackingContext3D>);
31993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  AllocationTrackingContext3D* context = context_owned.get();
32003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
32013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  FakeOutputSurfaceClient output_surface_client;
32023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
32033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      context_owned.PassAs<TestWebGraphicsContext3D>()));
32043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  CHECK(output_surface->BindToClient(&output_surface_client));
32052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
32062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Size size(2, 2);
3207d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  ResourceFormat format = RGBA_8888;
32082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ResourceProvider::ResourceId id = 0;
32092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int texture_id = 123;
32102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
32111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<ResourceProvider> resource_provider(
32121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      ResourceProvider::Create(output_surface.get(),
32131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               shared_bitmap_manager_.get(),
32141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               NULL,
32151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               0,
32161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               false,
32171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               1,
32181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               false));
32192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3220868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  id = resource_provider->CreateResource(
322103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureHintImmutable, format);
32221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  resource_provider->AcquirePixelBuffer(id);
3223868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
32240f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_CALL(*context, NextTextureId()).WillOnce(Return(texture_id));
3225868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id)).Times(2);
32262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*context, asyncTexImage2DCHROMIUM(_, _, _, 2, 2, _, _, _, _))
32272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      .Times(1);
3228868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  resource_provider->BeginSetPixels(id);
3229868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3230868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id)).Times(1);
32312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*context, waitAsyncTexImage2DCHROMIUM(GL_TEXTURE_2D)).Times(1);
32322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, 0)).Times(1);
32332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_provider->ForceSetPixelsToComplete(id);
3234868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
32351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  resource_provider->ReleasePixelBuffer(id);
3236868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
32370f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_CALL(*context, RetireTextureId(texture_id)).Times(1);
3238868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  resource_provider->DeleteResource(id);
3239868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
32402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Mock::VerifyAndClearExpectations(context);
32412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
32422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3243c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_P(ResourceProviderTest, PixelBufferLostContext) {
32443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<AllocationTrackingContext3D> context_owned(
32453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      new NiceMock<AllocationTrackingContext3D>);
32463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  AllocationTrackingContext3D* context = context_owned.get();
32473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
32483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  FakeOutputSurfaceClient output_surface_client;
32493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
32503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      context_owned.PassAs<TestWebGraphicsContext3D>()));
32513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  CHECK(output_surface->BindToClient(&output_surface_client));
3252c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3253c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  gfx::Size size(2, 2);
3254d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  ResourceFormat format = RGBA_8888;
3255c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ResourceProvider::ResourceId id = 0;
3256c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int texture_id = 123;
3257c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
32581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<ResourceProvider> resource_provider(
32591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      ResourceProvider::Create(output_surface.get(),
32601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               shared_bitmap_manager_.get(),
32611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               NULL,
32621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               0,
32631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               false,
32641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               1,
32651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               false));
3266c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
32670f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_CALL(*context, NextTextureId()).WillRepeatedly(Return(texture_id));
3268c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3269c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  id = resource_provider->CreateResource(
327003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureHintImmutable, format);
3271c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  context->loseContextCHROMIUM(GL_GUILTY_CONTEXT_RESET_ARB,
3272c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                               GL_INNOCENT_CONTEXT_RESET_ARB);
32735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
32741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  resource_provider->AcquirePixelBuffer(id);
32751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  int stride;
32761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  void* buffer = resource_provider->MapPixelBuffer(id, &stride);
32771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_FALSE(buffer);
32781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  resource_provider->UnmapPixelBuffer(id);
3279c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  Mock::VerifyAndClearExpectations(context);
3280c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
3281c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3282eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(ResourceProviderTest, Image_GLTexture) {
328390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Only for GL textures.
328490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (GetParam() != ResourceProvider::GLTexture)
328590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return;
32863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<AllocationTrackingContext3D> context_owned(
32873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      new StrictMock<AllocationTrackingContext3D>);
32883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  AllocationTrackingContext3D* context = context_owned.get();
32893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
32903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  FakeOutputSurfaceClient output_surface_client;
32913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
32923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      context_owned.PassAs<TestWebGraphicsContext3D>()));
32933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  CHECK(output_surface->BindToClient(&output_surface_client));
329490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
329590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  const int kWidth = 2;
329690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  const int kHeight = 2;
329790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  gfx::Size size(kWidth, kHeight);
3298d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  ResourceFormat format = RGBA_8888;
329990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  ResourceProvider::ResourceId id = 0;
330090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  const unsigned kTextureId = 123u;
330190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  const unsigned kImageId = 234u;
330290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
33031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<ResourceProvider> resource_provider(
33041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      ResourceProvider::Create(output_surface.get(),
33051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               shared_bitmap_manager_.get(),
33061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               NULL,
33071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               0,
33081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               false,
33091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               1,
33101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               false));
331190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
331290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  id = resource_provider->CreateResource(
331303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureHintImmutable, format);
331490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
33155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const int kStride = 4;
331690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  void* dummy_mapped_buffer_address = NULL;
3317010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  EXPECT_CALL(
3318010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      *context,
3319010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      createImageCHROMIUM(kWidth, kHeight, GL_RGBA8_OES, GL_IMAGE_MAP_CHROMIUM))
33205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      .WillOnce(Return(kImageId))
332190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      .RetiresOnSaturation();
33221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  resource_provider->AcquireImage(id);
33231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
332490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_CALL(*context, getImageParameterivCHROMIUM(kImageId,
332590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                                    GL_IMAGE_ROWBYTES_CHROMIUM,
332690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                                    _))
332790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      .WillOnce(SetArgPointee<2>(kStride))
332890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      .RetiresOnSaturation();
3329010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  EXPECT_CALL(*context, mapImageCHROMIUM(kImageId))
33305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      .WillOnce(Return(dummy_mapped_buffer_address))
33315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      .RetiresOnSaturation();
33321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  int stride;
33331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  resource_provider->MapImage(id, &stride);
333490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
333590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_CALL(*context, unmapImageCHROMIUM(kImageId))
333690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      .Times(1)
333790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      .RetiresOnSaturation();
33381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  resource_provider->UnmapImage(id);
333990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
33400f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_CALL(*context, NextTextureId())
3341a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      .WillOnce(Return(kTextureId))
3342a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      .RetiresOnSaturation();
3343a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Once in CreateTextureId and once in BindForSampling
3344a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, kTextureId)).Times(2)
3345a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      .RetiresOnSaturation();
3346a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_CALL(*context, bindTexImage2DCHROMIUM(GL_TEXTURE_2D, kImageId))
3347a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      .Times(1)
3348a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      .RetiresOnSaturation();
33498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  {
33508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    ResourceProvider::ScopedSamplerGL lock_gl(
33518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        resource_provider.get(), id, GL_TEXTURE_2D, GL_LINEAR);
33528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    EXPECT_EQ(kTextureId, lock_gl.texture_id());
33538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
33548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
33555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_CALL(
33565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      *context,
33575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      getImageParameterivCHROMIUM(kImageId, GL_IMAGE_ROWBYTES_CHROMIUM, _))
33585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      .WillOnce(SetArgPointee<2>(kStride))
33595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      .RetiresOnSaturation();
3360010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  EXPECT_CALL(*context, mapImageCHROMIUM(kImageId))
33618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      .WillOnce(Return(dummy_mapped_buffer_address))
33628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      .RetiresOnSaturation();
33631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  resource_provider->MapImage(id, &stride);
33648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
33658bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  EXPECT_CALL(*context, unmapImageCHROMIUM(kImageId))
33668bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      .Times(1)
33678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      .RetiresOnSaturation();
33681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  resource_provider->UnmapImage(id);
33698bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
33708bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, kTextureId)).Times(1)
33718bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      .RetiresOnSaturation();
3372a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_CALL(*context, releaseTexImage2DCHROMIUM(GL_TEXTURE_2D, kImageId))
337390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      .Times(1)
337490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      .RetiresOnSaturation();
33758bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  EXPECT_CALL(*context, bindTexImage2DCHROMIUM(GL_TEXTURE_2D, kImageId))
33768bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      .Times(1)
33778bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      .RetiresOnSaturation();
33780f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_CALL(*context, RetireTextureId(kTextureId))
337990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      .Times(1)
338090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      .RetiresOnSaturation();
3381a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  {
3382a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    ResourceProvider::ScopedSamplerGL lock_gl(
3383a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        resource_provider.get(), id, GL_TEXTURE_2D, GL_LINEAR);
3384a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    EXPECT_EQ(kTextureId, lock_gl.texture_id());
3385a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
3386a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
3387a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_CALL(*context, destroyImageCHROMIUM(kImageId))
3388a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      .Times(1)
3389a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      .RetiresOnSaturation();
339090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
339190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
3392a02191e04bc25c4935f804f2c080ae28663d096dBen MurdochTEST_P(ResourceProviderTest, CopyResource_GLTexture) {
3393a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  if (GetParam() != ResourceProvider::GLTexture)
3394a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    return;
3395a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  scoped_ptr<AllocationTrackingContext3D> context_owned(
3396a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      new StrictMock<AllocationTrackingContext3D>);
3397a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  AllocationTrackingContext3D* context = context_owned.get();
33980529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  context_owned->set_support_sync_query(true);
3399a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
3400a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  FakeOutputSurfaceClient output_surface_client;
3401a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
3402a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      context_owned.PassAs<TestWebGraphicsContext3D>()));
3403a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  ASSERT_TRUE(output_surface->BindToClient(&output_surface_client));
3404a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
3405a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  const int kWidth = 2;
3406a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  const int kHeight = 2;
3407a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  gfx::Size size(kWidth, kHeight);
3408a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  ResourceFormat format = RGBA_8888;
3409a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  ResourceProvider::ResourceId source_id = 0;
3410a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  ResourceProvider::ResourceId dest_id = 0;
3411a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  const unsigned kSourceTextureId = 123u;
3412a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  const unsigned kDestTextureId = 321u;
3413a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  const unsigned kImageId = 234u;
3414a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
34151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<ResourceProvider> resource_provider(
34161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      ResourceProvider::Create(output_surface.get(),
34171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               shared_bitmap_manager_.get(),
34181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               NULL,
34191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               0,
34201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               false,
34211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               1,
34221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               false));
3423a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
3424a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  source_id = resource_provider->CreateResource(
342503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureHintImmutable, format);
3426a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
3427a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  const int kStride = 4;
3428a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  void* dummy_mapped_buffer_address = NULL;
3429010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  EXPECT_CALL(
3430010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      *context,
3431010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      createImageCHROMIUM(kWidth, kHeight, GL_RGBA8_OES, GL_IMAGE_MAP_CHROMIUM))
3432a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      .WillOnce(Return(kImageId))
3433a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      .RetiresOnSaturation();
3434a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  EXPECT_CALL(
3435a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      *context,
3436a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      getImageParameterivCHROMIUM(kImageId, GL_IMAGE_ROWBYTES_CHROMIUM, _))
3437a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      .WillOnce(SetArgPointee<2>(kStride))
3438a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      .RetiresOnSaturation();
3439010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  EXPECT_CALL(*context, mapImageCHROMIUM(kImageId))
3440a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      .WillOnce(Return(dummy_mapped_buffer_address))
3441a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      .RetiresOnSaturation();
34421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  resource_provider->AcquireImage(source_id);
34431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  int stride;
34441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  resource_provider->MapImage(source_id, &stride);
3445a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  EXPECT_CALL(*context, unmapImageCHROMIUM(kImageId))
3446a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      .Times(1)
3447a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      .RetiresOnSaturation();
34481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  resource_provider->UnmapImage(source_id);
3449a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  Mock::VerifyAndClearExpectations(context);
3450a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
3451a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  dest_id = resource_provider->CreateResource(
345203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureHintImmutable, format);
3453a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
3454a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  EXPECT_CALL(*context, NextTextureId())
3455a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      .WillOnce(Return(kDestTextureId))
3456a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      .RetiresOnSaturation();
3457a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, kDestTextureId))
3458a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      .Times(1)
3459a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      .RetiresOnSaturation();
3460a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  EXPECT_CALL(*context, NextTextureId())
3461a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      .WillOnce(Return(kSourceTextureId))
3462a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      .RetiresOnSaturation();
3463a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, kSourceTextureId))
3464a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      .Times(2)
3465a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      .RetiresOnSaturation();
3466a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  EXPECT_CALL(*context, bindTexImage2DCHROMIUM(GL_TEXTURE_2D, kImageId))
3467a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      .Times(1)
3468a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      .RetiresOnSaturation();
3469a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  resource_provider->CopyResource(source_id, dest_id);
3470a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  Mock::VerifyAndClearExpectations(context);
3471a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
3472a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  EXPECT_CALL(*context, destroyImageCHROMIUM(kImageId))
3473a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      .Times(1)
3474a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      .RetiresOnSaturation();
3475a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  EXPECT_CALL(*context, RetireTextureId(kSourceTextureId))
3476a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      .Times(1)
3477a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      .RetiresOnSaturation();
3478a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  EXPECT_CALL(*context, RetireTextureId(kDestTextureId))
3479a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      .Times(1)
3480a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      .RetiresOnSaturation();
3481a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  resource_provider->DeleteResource(source_id);
3482a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  resource_provider->DeleteResource(dest_id);
3483a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch}
3484a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
3485ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid InitializeGLAndCheck(ContextSharedData* shared_data,
3486ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                          ResourceProvider* resource_provider,
34877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                          FakeOutputSurface* output_surface) {
34883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<ResourceProviderContext> context_owned =
3489ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      ResourceProviderContext::Create(shared_data);
34903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ResourceProviderContext* context = context_owned.get();
34913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
34923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_refptr<TestContextProvider> context_provider =
34933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      TestContextProvider::Create(
34943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)          context_owned.PassAs<TestWebGraphicsContext3D>());
34955c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  output_surface->InitializeAndSetContext3d(context_provider);
34960529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  resource_provider->InitializeGL();
34973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
34983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  CheckCreateResource(ResourceProvider::GLTexture, resource_provider, context);
34997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
35007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
35017dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochTEST(ResourceProviderTest, BasicInitializeGLSoftware) {
3502ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  scoped_ptr<ContextSharedData> shared_data = ContextSharedData::Create();
3503cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  bool delegated_rendering = false;
35047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  scoped_ptr<FakeOutputSurface> output_surface(
35057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      FakeOutputSurface::CreateDeferredGL(
3506cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          scoped_ptr<SoftwareOutputDevice>(new SoftwareOutputDevice),
3507cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          delegated_rendering));
3508cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FakeOutputSurfaceClient client(output_surface.get());
35097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_TRUE(output_surface->BindToClient(&client));
351023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
351123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      new TestSharedBitmapManager());
35121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<ResourceProvider> resource_provider(
35131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      ResourceProvider::Create(output_surface.get(),
35141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               shared_bitmap_manager.get(),
35151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               NULL,
35161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               0,
35171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               false,
35181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               1,
35191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               false));
35207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
35217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  CheckCreateResource(ResourceProvider::Bitmap, resource_provider.get(), NULL);
35227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
3523ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  InitializeGLAndCheck(shared_data.get(),
3524ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                       resource_provider.get(),
3525ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                       output_surface.get());
35267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
35277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  resource_provider->InitializeSoftware();
35283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  output_surface->ReleaseGL();
35297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  CheckCreateResource(ResourceProvider::Bitmap, resource_provider.get(), NULL);
35307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
3531ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  InitializeGLAndCheck(shared_data.get(),
3532ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                       resource_provider.get(),
3533ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                       output_surface.get());
35347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
35357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
35361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)TEST_P(ResourceProviderTest, CompressedTextureETC1Allocate) {
35371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (GetParam() != ResourceProvider::GLTexture)
35381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    return;
35391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
35401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  scoped_ptr<AllocationTrackingContext3D> context_owned(
35411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      new AllocationTrackingContext3D);
35421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  AllocationTrackingContext3D* context = context_owned.get();
35431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  context_owned->set_support_compressed_texture_etc1(true);
35441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
35451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  FakeOutputSurfaceClient output_surface_client;
35461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
35471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      context_owned.PassAs<TestWebGraphicsContext3D>()));
35481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  CHECK(output_surface->BindToClient(&output_surface_client));
35491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
35501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  gfx::Size size(4, 4);
35510f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  scoped_ptr<ResourceProvider> resource_provider(
35520f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      ResourceProvider::Create(output_surface.get(),
35530f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                               shared_bitmap_manager_.get(),
35541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               NULL,
35550f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                               0,
35560f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                               false,
3557010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                               1,
3558010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                               false));
35591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  int texture_id = 123;
35601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
35611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ResourceProvider::ResourceId id = resource_provider->CreateResource(
356203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureHintImmutable, ETC1);
35631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_NE(0u, id);
35640f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_CALL(*context, NextTextureId()).WillOnce(Return(texture_id));
35651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id)).Times(2);
35661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  resource_provider->AllocateForTesting(id);
35671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
35680f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_CALL(*context, RetireTextureId(texture_id)).Times(1);
35691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  resource_provider->DeleteResource(id);
35701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
35711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
35721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)TEST_P(ResourceProviderTest, CompressedTextureETC1SetPixels) {
35731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (GetParam() != ResourceProvider::GLTexture)
35741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    return;
35751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
35761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  scoped_ptr<AllocationTrackingContext3D> context_owned(
35771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      new AllocationTrackingContext3D);
35781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  AllocationTrackingContext3D* context = context_owned.get();
35791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  context_owned->set_support_compressed_texture_etc1(true);
35801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
35811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  FakeOutputSurfaceClient output_surface_client;
35821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
35831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      context_owned.PassAs<TestWebGraphicsContext3D>()));
35841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  CHECK(output_surface->BindToClient(&output_surface_client));
35851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
35861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  gfx::Size size(4, 4);
35870f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  scoped_ptr<ResourceProvider> resource_provider(
35880f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      ResourceProvider::Create(output_surface.get(),
35890f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                               shared_bitmap_manager_.get(),
35901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               NULL,
35910f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                               0,
35920f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                               false,
3593010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                               1,
3594010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                               false));
35951e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  int texture_id = 123;
35961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  uint8_t pixels[8];
35971e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
35981e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ResourceProvider::ResourceId id = resource_provider->CreateResource(
359903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureHintImmutable, ETC1);
36001e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_NE(0u, id);
36010f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_CALL(*context, NextTextureId()).WillOnce(Return(texture_id));
36021e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id)).Times(3);
36031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_CALL(*context,
36041e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)              compressedTexImage2D(
36051e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                  _, 0, _, size.width(), size.height(), _, _, _)).Times(1);
36061e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  resource_provider->SetPixels(
36071e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      id, pixels, gfx::Rect(size), gfx::Rect(size), gfx::Vector2d(0, 0));
36081e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
36090f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_CALL(*context, RetireTextureId(texture_id)).Times(1);
36101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  resource_provider->DeleteResource(id);
36111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
36121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
36132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)INSTANTIATE_TEST_CASE_P(
36142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ResourceProviderTests,
36152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ResourceProviderTest,
36162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ::testing::Values(ResourceProvider::GLTexture, ResourceProvider::Bitmap));
36172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
36180f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)class TextureIdAllocationTrackingContext : public TestWebGraphicsContext3D {
36190f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) public:
3620a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual GLuint NextTextureId() OVERRIDE {
36210f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    base::AutoLock lock(namespace_->lock);
36220f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    return namespace_->next_texture_id++;
36230f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
3624a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual void RetireTextureId(GLuint) OVERRIDE {}
3625a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLuint PeekTextureId() {
36260f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    base::AutoLock lock(namespace_->lock);
36270f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    return namespace_->next_texture_id;
36280f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
36290f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)};
36300f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
36310f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)TEST(ResourceProviderTest, TextureAllocationChunkSize) {
36320f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  scoped_ptr<TextureIdAllocationTrackingContext> context_owned(
36330f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      new TextureIdAllocationTrackingContext);
36340f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  TextureIdAllocationTrackingContext* context = context_owned.get();
36350f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
36360f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  FakeOutputSurfaceClient output_surface_client;
36370f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
36380f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      context_owned.PassAs<TestWebGraphicsContext3D>()));
36390f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  CHECK(output_surface->BindToClient(&output_surface_client));
364023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
364123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      new TestSharedBitmapManager());
36420f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
36430f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  gfx::Size size(1, 1);
36440f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  ResourceFormat format = RGBA_8888;
36450f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
36460f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  {
36470f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    size_t kTextureAllocationChunkSize = 1;
36480f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    scoped_ptr<ResourceProvider> resource_provider(
36490f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        ResourceProvider::Create(output_surface.get(),
365023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)                                 shared_bitmap_manager.get(),
36511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                 NULL,
36520f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                                 0,
36530f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                                 false,
3654010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                                 kTextureAllocationChunkSize,
3655010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                                 false));
36560f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
36570f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    ResourceProvider::ResourceId id = resource_provider->CreateResource(
365803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureHintImmutable, format);
36590f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    resource_provider->AllocateForTesting(id);
36600f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    Mock::VerifyAndClearExpectations(context);
36610f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
36620f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    DCHECK_EQ(2u, context->PeekTextureId());
36630f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    resource_provider->DeleteResource(id);
36640f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
36650f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
36660f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  {
36670f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    size_t kTextureAllocationChunkSize = 8;
36680f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    scoped_ptr<ResourceProvider> resource_provider(
36690f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        ResourceProvider::Create(output_surface.get(),
367023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)                                 shared_bitmap_manager.get(),
36711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                 NULL,
36720f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                                 0,
36730f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                                 false,
3674010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                                 kTextureAllocationChunkSize,
3675010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                                 false));
36760f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
36770f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    ResourceProvider::ResourceId id = resource_provider->CreateResource(
367803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureHintImmutable, format);
36790f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    resource_provider->AllocateForTesting(id);
36800f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    Mock::VerifyAndClearExpectations(context);
36810f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
36820f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    DCHECK_EQ(10u, context->PeekTextureId());
36830f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    resource_provider->DeleteResource(id);
36840f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
36850f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}
36860f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
36872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
36882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace cc
3689