1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "cc/resources/resource_provider.h"
12 #include "base/bind.h"
13 #include "base/containers/hash_tables.h"
14 #include "base/logging.h"
15 #include "base/memory/ref_counted.h"
16 #include "cc/base/scoped_ptr_deque.h"
17 #include "cc/output/output_surface.h"
18 #include "cc/resources/returned_resource.h"
19 #include "cc/resources/shared_bitmap_manager.h"
20 #include "cc/resources/single_release_callback.h"
21 #include "cc/test/fake_output_surface.h"
22 #include "cc/test/fake_output_surface_client.h"
23 #include "cc/test/test_gpu_memory_buffer_manager.h"
24 #include "cc/test/test_shared_bitmap_manager.h"
25 #include "cc/test/test_texture.h"
26 #include "cc/test/test_web_graphics_context_3d.h"
27 #include "cc/trees/blocking_task_runner.h"
28 #include "gpu/GLES2/gl2extchromium.h"
29 #include "testing/gmock/include/gmock/gmock.h"
30 #include "testing/gtest/include/gtest/gtest.h"
31 #include "third_party/khronos/GLES2/gl2.h"
32 #include "third_party/khronos/GLES2/gl2ext.h"
33 #include "ui/gfx/geometry/rect.h"
34 #include "ui/gfx/gpu_memory_buffer.h"
37 using testing::NiceMock
;
38 using testing::Return
;
39 using testing::SetArgPointee
;
40 using testing::StrictMock
;
46 static void EmptyReleaseCallback(uint32 sync_point
,
48 BlockingTaskRunner
* main_thread_task_runner
) {
51 static void ReleaseCallback(
52 uint32
* release_sync_point
,
53 bool* release_lost_resource
,
54 BlockingTaskRunner
** release_main_thread_task_runner
,
57 BlockingTaskRunner
* main_thread_task_runner
) {
58 *release_sync_point
= sync_point
;
59 *release_lost_resource
= lost_resource
;
60 *release_main_thread_task_runner
= main_thread_task_runner
;
63 static void SharedBitmapReleaseCallback(
64 scoped_ptr
<SharedBitmap
> bitmap
,
67 BlockingTaskRunner
* main_thread_task_runner
) {
70 static void ReleaseSharedBitmapCallback(
71 scoped_ptr
<SharedBitmap
> shared_bitmap
,
73 uint32
* release_sync_point
,
74 bool* lost_resource_result
,
77 BlockingTaskRunner
* main_thread_task_runner
) {
78 *release_called
= true;
79 *release_sync_point
= sync_point
;
80 *lost_resource_result
= lost_resource
;
83 static scoped_ptr
<SharedBitmap
> CreateAndFillSharedBitmap(
84 SharedBitmapManager
* manager
,
85 const gfx::Size
& size
,
87 scoped_ptr
<SharedBitmap
> shared_bitmap
= manager
->AllocateSharedBitmap(size
);
89 uint32_t* pixels
= reinterpret_cast<uint32_t*>(shared_bitmap
->pixels());
91 std::fill_n(pixels
, size
.GetArea(), value
);
92 return shared_bitmap
.Pass();
95 class TextureStateTrackingContext
: public TestWebGraphicsContext3D
{
97 MOCK_METHOD2(bindTexture
, void(GLenum target
, GLuint texture
));
98 MOCK_METHOD3(texParameteri
, void(GLenum target
, GLenum pname
, GLint param
));
99 MOCK_METHOD1(waitSyncPoint
, void(GLuint sync_point
));
100 MOCK_METHOD0(insertSyncPoint
, GLuint(void));
101 MOCK_METHOD3(produceTextureDirectCHROMIUM
,
102 void(GLuint texture
, GLenum target
, const GLbyte
* mailbox
));
103 MOCK_METHOD2(createAndConsumeTextureCHROMIUM
,
104 unsigned(GLenum target
, const GLbyte
* mailbox
));
106 // Force all textures to be consecutive numbers starting at "1",
107 // so we easily can test for them.
108 GLuint
NextTextureId() override
{
109 base::AutoLock
lock(namespace_
->lock
);
110 return namespace_
->next_texture_id
++;
112 void RetireTextureId(GLuint
) override
{}
115 // Shared data between multiple ResourceProviderContext. This contains mailbox
116 // contents as well as information about sync points.
117 class ContextSharedData
{
119 static scoped_ptr
<ContextSharedData
> Create() {
120 return make_scoped_ptr(new ContextSharedData());
123 uint32
InsertSyncPoint() { return next_sync_point_
++; }
125 void GenMailbox(GLbyte
* mailbox
) {
126 memset(mailbox
, 0, GL_MAILBOX_SIZE_CHROMIUM
);
127 memcpy(mailbox
, &next_mailbox_
, sizeof(next_mailbox_
));
131 void ProduceTexture(const GLbyte
* mailbox_name
,
133 scoped_refptr
<TestTexture
> texture
) {
134 unsigned mailbox
= 0;
135 memcpy(&mailbox
, mailbox_name
, sizeof(mailbox
));
136 ASSERT_TRUE(mailbox
&& mailbox
< next_mailbox_
);
137 textures_
[mailbox
] = texture
;
138 ASSERT_LT(sync_point_for_mailbox_
[mailbox
], sync_point
);
139 sync_point_for_mailbox_
[mailbox
] = sync_point
;
142 scoped_refptr
<TestTexture
> ConsumeTexture(const GLbyte
* mailbox_name
,
144 unsigned mailbox
= 0;
145 memcpy(&mailbox
, mailbox_name
, sizeof(mailbox
));
146 DCHECK(mailbox
&& mailbox
< next_mailbox_
);
148 // If the latest sync point the context has waited on is before the sync
149 // point for when the mailbox was set, pretend we never saw that
151 if (sync_point_for_mailbox_
[mailbox
] > sync_point
) {
153 return scoped_refptr
<TestTexture
>();
155 return textures_
[mailbox
];
159 ContextSharedData() : next_sync_point_(1), next_mailbox_(1) {}
161 uint32 next_sync_point_
;
162 unsigned next_mailbox_
;
163 typedef base::hash_map
<unsigned, scoped_refptr
<TestTexture
>> TextureMap
;
164 TextureMap textures_
;
165 base::hash_map
<unsigned, uint32
> sync_point_for_mailbox_
;
168 class ResourceProviderContext
: public TestWebGraphicsContext3D
{
170 static scoped_ptr
<ResourceProviderContext
> Create(
171 ContextSharedData
* shared_data
) {
172 return make_scoped_ptr(new ResourceProviderContext(shared_data
));
175 GLuint
insertSyncPoint() override
{
176 uint32 sync_point
= shared_data_
->InsertSyncPoint();
177 // Commit the produceTextureCHROMIUM calls at this point, so that
178 // they're associated with the sync point.
179 for (PendingProduceTextureList::iterator it
=
180 pending_produce_textures_
.begin();
181 it
!= pending_produce_textures_
.end();
183 shared_data_
->ProduceTexture(
184 (*it
)->mailbox
, sync_point
, (*it
)->texture
);
186 pending_produce_textures_
.clear();
190 void waitSyncPoint(GLuint sync_point
) override
{
191 last_waited_sync_point_
= std::max(sync_point
, last_waited_sync_point_
);
194 unsigned last_waited_sync_point() const { return last_waited_sync_point_
; }
196 void texStorage2DEXT(GLenum target
,
198 GLuint internalformat
,
200 GLint height
) override
{
201 CheckTextureIsBound(target
);
202 ASSERT_EQ(static_cast<unsigned>(GL_TEXTURE_2D
), target
);
203 ASSERT_EQ(1, levels
);
204 GLenum format
= GL_RGBA
;
205 switch (internalformat
) {
209 format
= GL_BGRA_EXT
;
214 AllocateTexture(gfx::Size(width
, height
), format
);
217 void texImage2D(GLenum target
,
219 GLenum internalformat
,
225 const void* pixels
) override
{
226 CheckTextureIsBound(target
);
227 ASSERT_EQ(static_cast<unsigned>(GL_TEXTURE_2D
), target
);
229 ASSERT_EQ(internalformat
, format
);
230 ASSERT_FALSE(border
);
231 ASSERT_EQ(static_cast<unsigned>(GL_UNSIGNED_BYTE
), type
);
232 AllocateTexture(gfx::Size(width
, height
), format
);
234 SetPixels(0, 0, width
, height
, pixels
);
237 void texSubImage2D(GLenum target
,
245 const void* pixels
) override
{
246 CheckTextureIsBound(target
);
247 ASSERT_EQ(static_cast<unsigned>(GL_TEXTURE_2D
), target
);
249 ASSERT_EQ(static_cast<unsigned>(GL_UNSIGNED_BYTE
), type
);
251 base::AutoLock
lock_for_texture_access(namespace_
->lock
);
252 ASSERT_EQ(GLDataFormat(BoundTexture(target
)->format
), format
);
255 SetPixels(xoffset
, yoffset
, width
, height
, pixels
);
258 void genMailboxCHROMIUM(GLbyte
* mailbox
) override
{
259 return shared_data_
->GenMailbox(mailbox
);
262 void produceTextureDirectCHROMIUM(GLuint texture
,
264 const GLbyte
* mailbox
) override
{
265 // Delay moving the texture into the mailbox until the next
266 // InsertSyncPoint, so that it is not visible to other contexts that
267 // haven't waited on that sync point.
268 scoped_ptr
<PendingProduceTexture
> pending(new PendingProduceTexture
);
269 memcpy(pending
->mailbox
, mailbox
, sizeof(pending
->mailbox
));
270 base::AutoLock
lock_for_texture_access(namespace_
->lock
);
271 pending
->texture
= UnboundTexture(texture
);
272 pending_produce_textures_
.push_back(pending
.Pass());
275 GLuint
createAndConsumeTextureCHROMIUM(GLenum target
,
276 const GLbyte
* mailbox
) override
{
277 GLuint texture_id
= createTexture();
278 base::AutoLock
lock_for_texture_access(namespace_
->lock
);
279 scoped_refptr
<TestTexture
> texture
=
280 shared_data_
->ConsumeTexture(mailbox
, last_waited_sync_point_
);
281 namespace_
->textures
.Replace(texture_id
, texture
);
285 void GetPixels(const gfx::Size
& size
,
286 ResourceFormat format
,
288 CheckTextureIsBound(GL_TEXTURE_2D
);
289 base::AutoLock
lock_for_texture_access(namespace_
->lock
);
290 scoped_refptr
<TestTexture
> texture
= BoundTexture(GL_TEXTURE_2D
);
291 ASSERT_EQ(texture
->size
, size
);
292 ASSERT_EQ(texture
->format
, format
);
293 memcpy(pixels
, texture
->data
.get(), TextureSizeBytes(size
, format
));
297 explicit ResourceProviderContext(ContextSharedData
* shared_data
)
298 : shared_data_(shared_data
),
299 last_waited_sync_point_(0) {}
302 void AllocateTexture(const gfx::Size
& size
, GLenum format
) {
303 CheckTextureIsBound(GL_TEXTURE_2D
);
304 ResourceFormat texture_format
= RGBA_8888
;
307 texture_format
= RGBA_8888
;
310 texture_format
= BGRA_8888
;
313 base::AutoLock
lock_for_texture_access(namespace_
->lock
);
314 BoundTexture(GL_TEXTURE_2D
)->Reallocate(size
, texture_format
);
317 void SetPixels(int xoffset
,
321 const void* pixels
) {
322 CheckTextureIsBound(GL_TEXTURE_2D
);
323 base::AutoLock
lock_for_texture_access(namespace_
->lock
);
324 scoped_refptr
<TestTexture
> texture
= BoundTexture(GL_TEXTURE_2D
);
325 ASSERT_TRUE(texture
->data
.get());
326 ASSERT_TRUE(xoffset
>= 0 && xoffset
+ width
<= texture
->size
.width());
327 ASSERT_TRUE(yoffset
>= 0 && yoffset
+ height
<= texture
->size
.height());
329 size_t in_pitch
= TextureSizeBytes(gfx::Size(width
, 1), texture
->format
);
331 TextureSizeBytes(gfx::Size(texture
->size
.width(), 1), texture
->format
);
332 uint8_t* dest
= texture
->data
.get() + yoffset
* out_pitch
+
333 TextureSizeBytes(gfx::Size(xoffset
, 1), texture
->format
);
334 const uint8_t* src
= static_cast<const uint8_t*>(pixels
);
335 for (int i
= 0; i
< height
; ++i
) {
336 memcpy(dest
, src
, in_pitch
);
342 struct PendingProduceTexture
{
343 GLbyte mailbox
[GL_MAILBOX_SIZE_CHROMIUM
];
344 scoped_refptr
<TestTexture
> texture
;
346 typedef ScopedPtrDeque
<PendingProduceTexture
> PendingProduceTextureList
;
347 ContextSharedData
* shared_data_
;
348 GLuint last_waited_sync_point_
;
349 PendingProduceTextureList pending_produce_textures_
;
352 void GetResourcePixels(ResourceProvider
* resource_provider
,
353 ResourceProviderContext
* context
,
355 const gfx::Size
& size
,
356 ResourceFormat format
,
358 resource_provider
->WaitSyncPointIfNeeded(id
);
359 switch (resource_provider
->default_resource_type()) {
360 case ResourceProvider::RESOURCE_TYPE_GL_TEXTURE
: {
361 ResourceProvider::ScopedReadLockGL
lock_gl(resource_provider
, id
);
362 ASSERT_NE(0U, lock_gl
.texture_id());
363 context
->bindTexture(GL_TEXTURE_2D
, lock_gl
.texture_id());
364 context
->GetPixels(size
, format
, pixels
);
367 case ResourceProvider::RESOURCE_TYPE_BITMAP
: {
368 ResourceProvider::ScopedReadLockSoftware
lock_software(resource_provider
,
371 lock_software
.sk_bitmap()->getPixels(),
372 lock_software
.sk_bitmap()->getSize());
378 class ResourceProviderTest
379 : public testing::TestWithParam
<ResourceProvider::ResourceType
> {
381 explicit ResourceProviderTest(bool child_needs_sync_point
)
382 : shared_data_(ContextSharedData::Create()),
384 child_context_(NULL
),
385 main_thread_task_runner_(BlockingTaskRunner::Create(NULL
)) {
386 switch (GetParam()) {
387 case ResourceProvider::RESOURCE_TYPE_GL_TEXTURE
: {
388 scoped_ptr
<ResourceProviderContext
> context3d(
389 ResourceProviderContext::Create(shared_data_
.get()));
390 context3d_
= context3d
.get();
392 scoped_refptr
<TestContextProvider
> context_provider
=
393 TestContextProvider::Create(context3d
.Pass());
395 output_surface_
= FakeOutputSurface::Create3d(context_provider
);
397 scoped_ptr
<ResourceProviderContext
> child_context_owned
=
398 ResourceProviderContext::Create(shared_data_
.get());
399 child_context_
= child_context_owned
.get();
400 if (child_needs_sync_point
) {
401 child_output_surface_
=
402 FakeOutputSurface::Create3d(child_context_owned
.Pass());
404 child_output_surface_
= FakeOutputSurface::CreateNoRequireSyncPoint(
405 child_context_owned
.Pass());
409 case ResourceProvider::RESOURCE_TYPE_BITMAP
:
410 output_surface_
= FakeOutputSurface::CreateSoftware(
411 make_scoped_ptr(new SoftwareOutputDevice
));
412 child_output_surface_
= FakeOutputSurface::CreateSoftware(
413 make_scoped_ptr(new SoftwareOutputDevice
));
416 CHECK(output_surface_
->BindToClient(&output_surface_client_
));
417 CHECK(child_output_surface_
->BindToClient(&child_output_surface_client_
));
419 shared_bitmap_manager_
.reset(new TestSharedBitmapManager
);
420 gpu_memory_buffer_manager_
.reset(new TestGpuMemoryBufferManager
);
422 resource_provider_
= ResourceProvider::Create(
423 output_surface_
.get(), shared_bitmap_manager_
.get(),
424 gpu_memory_buffer_manager_
.get(), main_thread_task_runner_
.get(), 0,
425 false, 1, use_image_texture_targets_
);
426 child_resource_provider_
= ResourceProvider::Create(
427 child_output_surface_
.get(), shared_bitmap_manager_
.get(),
428 gpu_memory_buffer_manager_
.get(), main_thread_task_runner_
.get(), 0,
429 false, 1, use_image_texture_targets_
);
432 ResourceProviderTest() : ResourceProviderTest(true) {}
434 static void CollectResources(ReturnedResourceArray
* array
,
435 const ReturnedResourceArray
& returned
,
436 BlockingTaskRunner
* main_thread_task_runner
) {
437 array
->insert(array
->end(), returned
.begin(), returned
.end());
440 static ReturnCallback
GetReturnCallback(ReturnedResourceArray
* array
) {
441 return base::Bind(&ResourceProviderTest::CollectResources
, array
);
444 static void SetResourceFilter(ResourceProvider
* resource_provider
,
447 ResourceProvider::ScopedSamplerGL
sampler(
448 resource_provider
, id
, GL_TEXTURE_2D
, filter
);
451 ResourceProviderContext
* context() { return context3d_
; }
453 ResourceId
CreateChildMailbox(uint32
* release_sync_point
,
455 bool* release_called
,
456 uint32
* sync_point
) {
457 if (GetParam() == ResourceProvider::RESOURCE_TYPE_GL_TEXTURE
) {
458 unsigned texture
= child_context_
->createTexture();
459 gpu::Mailbox gpu_mailbox
;
460 child_context_
->genMailboxCHROMIUM(gpu_mailbox
.name
);
461 child_context_
->produceTextureDirectCHROMIUM(texture
, GL_TEXTURE_2D
,
463 *sync_point
= child_context_
->insertSyncPoint();
464 EXPECT_LT(0u, *sync_point
);
466 scoped_ptr
<SharedBitmap
> shared_bitmap
;
467 scoped_ptr
<SingleReleaseCallbackImpl
> callback
=
468 SingleReleaseCallbackImpl::Create(base::Bind(
469 ReleaseSharedBitmapCallback
, base::Passed(&shared_bitmap
),
470 release_called
, release_sync_point
, lost_resource
));
471 return child_resource_provider_
->CreateResourceFromTextureMailbox(
472 TextureMailbox(gpu_mailbox
, GL_TEXTURE_2D
, *sync_point
),
475 gfx::Size
size(64, 64);
476 scoped_ptr
<SharedBitmap
> shared_bitmap(
477 CreateAndFillSharedBitmap(shared_bitmap_manager_
.get(), size
, 0));
479 SharedBitmap
* shared_bitmap_ptr
= shared_bitmap
.get();
480 scoped_ptr
<SingleReleaseCallbackImpl
> callback
=
481 SingleReleaseCallbackImpl::Create(base::Bind(
482 ReleaseSharedBitmapCallback
, base::Passed(&shared_bitmap
),
483 release_called
, release_sync_point
, lost_resource
));
484 return child_resource_provider_
->CreateResourceFromTextureMailbox(
485 TextureMailbox(shared_bitmap_ptr
, size
), callback
.Pass());
490 static std::vector
<unsigned> use_image_texture_targets() {
491 return use_image_texture_targets_
;
495 static std::vector
<unsigned> use_image_texture_targets_
;
496 scoped_ptr
<ContextSharedData
> shared_data_
;
497 ResourceProviderContext
* context3d_
;
498 ResourceProviderContext
* child_context_
;
499 FakeOutputSurfaceClient output_surface_client_
;
500 FakeOutputSurfaceClient child_output_surface_client_
;
501 scoped_ptr
<OutputSurface
> output_surface_
;
502 scoped_ptr
<OutputSurface
> child_output_surface_
;
503 scoped_ptr
<BlockingTaskRunner
> main_thread_task_runner_
;
504 scoped_ptr
<ResourceProvider
> resource_provider_
;
505 scoped_ptr
<ResourceProvider
> child_resource_provider_
;
506 scoped_ptr
<TestSharedBitmapManager
> shared_bitmap_manager_
;
507 scoped_ptr
<TestGpuMemoryBufferManager
> gpu_memory_buffer_manager_
;
510 std::vector
<unsigned> ResourceProviderTest::use_image_texture_targets_
=
511 std::vector
<unsigned>(static_cast<size_t>(gfx::BufferFormat::LAST
) + 1,
514 void CheckCreateResource(ResourceProvider::ResourceType expected_default_type
,
515 ResourceProvider
* resource_provider
,
516 ResourceProviderContext
* context
) {
517 DCHECK_EQ(expected_default_type
, resource_provider
->default_resource_type());
519 gfx::Size
size(1, 1);
520 ResourceFormat format
= RGBA_8888
;
521 size_t pixel_size
= TextureSizeBytes(size
, format
);
522 ASSERT_EQ(4U, pixel_size
);
524 ResourceId id
= resource_provider
->CreateResource(
525 size
, GL_CLAMP_TO_EDGE
, ResourceProvider::TEXTURE_HINT_IMMUTABLE
, format
);
526 EXPECT_EQ(1, static_cast<int>(resource_provider
->num_resources()));
527 if (expected_default_type
== ResourceProvider::RESOURCE_TYPE_GL_TEXTURE
)
528 EXPECT_EQ(0u, context
->NumTextures());
530 uint8_t data
[4] = { 1, 2, 3, 4 };
531 resource_provider
->CopyToResource(id
, data
, size
);
532 if (expected_default_type
== ResourceProvider::RESOURCE_TYPE_GL_TEXTURE
)
533 EXPECT_EQ(1u, context
->NumTextures());
535 uint8_t result
[4] = { 0 };
536 GetResourcePixels(resource_provider
, context
, id
, size
, format
, result
);
537 EXPECT_EQ(0, memcmp(data
, result
, pixel_size
));
539 resource_provider
->DeleteResource(id
);
540 EXPECT_EQ(0, static_cast<int>(resource_provider
->num_resources()));
541 if (expected_default_type
== ResourceProvider::RESOURCE_TYPE_GL_TEXTURE
)
542 EXPECT_EQ(0u, context
->NumTextures());
545 TEST_P(ResourceProviderTest
, Basic
) {
546 CheckCreateResource(GetParam(), resource_provider_
.get(), context());
549 TEST_P(ResourceProviderTest
, SimpleUpload
) {
550 gfx::Size
size(2, 2);
551 ResourceFormat format
= RGBA_8888
;
552 size_t pixel_size
= TextureSizeBytes(size
, format
);
553 ASSERT_EQ(16U, pixel_size
);
555 ResourceId id
= resource_provider_
->CreateResource(
556 size
, GL_CLAMP_TO_EDGE
, ResourceProvider::TEXTURE_HINT_IMMUTABLE
, format
);
558 uint8_t image
[16] = {0};
559 resource_provider_
->CopyToResource(id
, image
, size
);
561 uint8_t result
[16] = {0};
562 uint8_t expected
[16] = {0};
563 GetResourcePixels(resource_provider_
.get(), context(), id
, size
, format
,
565 EXPECT_EQ(0, memcmp(expected
, result
, pixel_size
));
568 for (uint8_t i
= 0; i
< pixel_size
; ++i
)
570 resource_provider_
->CopyToResource(id
, image
, size
);
572 uint8_t result
[16] = {0};
573 uint8_t expected
[16] = {
574 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
575 GetResourcePixels(resource_provider_
.get(), context(), id
, size
, format
,
577 EXPECT_EQ(0, memcmp(expected
, result
, pixel_size
));
581 TEST_P(ResourceProviderTest
, TransferGLResources
) {
582 if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE
)
584 gfx::Size
size(1, 1);
585 ResourceFormat format
= RGBA_8888
;
586 size_t pixel_size
= TextureSizeBytes(size
, format
);
587 ASSERT_EQ(4U, pixel_size
);
589 ResourceId id1
= child_resource_provider_
->CreateResource(
590 size
, GL_CLAMP_TO_EDGE
, ResourceProvider::TEXTURE_HINT_IMMUTABLE
, format
);
591 uint8_t data1
[4] = { 1, 2, 3, 4 };
592 child_resource_provider_
->CopyToResource(id1
, data1
, size
);
594 ResourceId id2
= child_resource_provider_
->CreateResource(
595 size
, GL_CLAMP_TO_EDGE
, ResourceProvider::TEXTURE_HINT_IMMUTABLE
, format
);
596 uint8_t data2
[4] = { 5, 5, 5, 5 };
597 child_resource_provider_
->CopyToResource(id2
, data2
, size
);
599 ResourceId id3
= child_resource_provider_
->CreateResource(
600 size
, GL_CLAMP_TO_EDGE
, ResourceProvider::TEXTURE_HINT_IMMUTABLE
, format
);
602 ResourceProvider::ScopedWriteLockGpuMemoryBuffer
lock(
603 child_resource_provider_
.get(), id3
);
604 EXPECT_TRUE(lock
.GetGpuMemoryBuffer());
607 GLuint external_texture_id
= child_context_
->createExternalTexture();
609 gpu::Mailbox external_mailbox
;
610 child_context_
->genMailboxCHROMIUM(external_mailbox
.name
);
611 child_context_
->produceTextureDirectCHROMIUM(
612 external_texture_id
, GL_TEXTURE_EXTERNAL_OES
, external_mailbox
.name
);
613 const GLuint external_sync_point
= child_context_
->insertSyncPoint();
614 ResourceId id4
= child_resource_provider_
->CreateResourceFromTextureMailbox(
615 TextureMailbox(external_mailbox
, GL_TEXTURE_EXTERNAL_OES
,
616 external_sync_point
),
617 SingleReleaseCallbackImpl::Create(base::Bind(&EmptyReleaseCallback
)));
619 ReturnedResourceArray returned_to_child
;
621 resource_provider_
->CreateChild(GetReturnCallback(&returned_to_child
));
623 // Transfer some resources to the parent.
624 ResourceProvider::ResourceIdArray resource_ids_to_transfer
;
625 resource_ids_to_transfer
.push_back(id1
);
626 resource_ids_to_transfer
.push_back(id2
);
627 resource_ids_to_transfer
.push_back(id3
);
628 resource_ids_to_transfer
.push_back(id4
);
629 TransferableResourceArray list
;
630 child_resource_provider_
->PrepareSendToParent(resource_ids_to_transfer
,
632 ASSERT_EQ(4u, list
.size());
633 EXPECT_NE(0u, list
[0].mailbox_holder
.sync_point
);
634 EXPECT_NE(0u, list
[1].mailbox_holder
.sync_point
);
635 EXPECT_EQ(list
[0].mailbox_holder
.sync_point
,
636 list
[1].mailbox_holder
.sync_point
);
637 EXPECT_NE(0u, list
[2].mailbox_holder
.sync_point
);
638 EXPECT_EQ(list
[0].mailbox_holder
.sync_point
,
639 list
[2].mailbox_holder
.sync_point
);
640 EXPECT_EQ(external_sync_point
, list
[3].mailbox_holder
.sync_point
);
641 EXPECT_EQ(static_cast<GLenum
>(GL_TEXTURE_2D
),
642 list
[0].mailbox_holder
.texture_target
);
643 EXPECT_EQ(static_cast<GLenum
>(GL_TEXTURE_2D
),
644 list
[1].mailbox_holder
.texture_target
);
645 EXPECT_EQ(static_cast<GLenum
>(GL_TEXTURE_2D
),
646 list
[2].mailbox_holder
.texture_target
);
647 EXPECT_EQ(static_cast<GLenum
>(GL_TEXTURE_EXTERNAL_OES
),
648 list
[3].mailbox_holder
.texture_target
);
649 EXPECT_TRUE(child_resource_provider_
->InUseByConsumer(id1
));
650 EXPECT_TRUE(child_resource_provider_
->InUseByConsumer(id2
));
651 EXPECT_TRUE(child_resource_provider_
->InUseByConsumer(id3
));
652 EXPECT_TRUE(child_resource_provider_
->InUseByConsumer(id4
));
653 resource_provider_
->ReceiveFromChild(child_id
, list
);
654 EXPECT_NE(list
[0].mailbox_holder
.sync_point
,
655 context3d_
->last_waited_sync_point());
657 resource_provider_
->WaitSyncPointIfNeeded(list
[0].id
);
658 ResourceProvider::ScopedReadLockGL
lock(resource_provider_
.get(),
661 EXPECT_EQ(list
[0].mailbox_holder
.sync_point
,
662 context3d_
->last_waited_sync_point());
663 ResourceProvider::ResourceIdSet resource_ids_to_receive
;
664 resource_ids_to_receive
.insert(id1
);
665 resource_ids_to_receive
.insert(id2
);
666 resource_ids_to_receive
.insert(id3
);
667 resource_ids_to_receive
.insert(id4
);
668 resource_provider_
->DeclareUsedResourcesFromChild(child_id
,
669 resource_ids_to_receive
);
672 EXPECT_EQ(4u, resource_provider_
->num_resources());
673 ResourceProvider::ResourceIdMap resource_map
=
674 resource_provider_
->GetChildToParentMap(child_id
);
675 ResourceId mapped_id1
= resource_map
[id1
];
676 ResourceId mapped_id2
= resource_map
[id2
];
677 ResourceId mapped_id3
= resource_map
[id3
];
678 ResourceId mapped_id4
= resource_map
[id4
];
679 EXPECT_NE(0u, mapped_id1
);
680 EXPECT_NE(0u, mapped_id2
);
681 EXPECT_NE(0u, mapped_id3
);
682 EXPECT_NE(0u, mapped_id4
);
683 EXPECT_FALSE(resource_provider_
->InUseByConsumer(id1
));
684 EXPECT_FALSE(resource_provider_
->InUseByConsumer(id2
));
685 EXPECT_FALSE(resource_provider_
->InUseByConsumer(id3
));
686 EXPECT_FALSE(resource_provider_
->InUseByConsumer(id4
));
688 uint8_t result
[4] = { 0 };
690 resource_provider_
.get(), context(), mapped_id1
, size
, format
, result
);
691 EXPECT_EQ(0, memcmp(data1
, result
, pixel_size
));
694 resource_provider_
.get(), context(), mapped_id2
, size
, format
, result
);
695 EXPECT_EQ(0, memcmp(data2
, result
, pixel_size
));
698 // Check that transfering again the same resource from the child to the
700 ResourceProvider::ResourceIdArray resource_ids_to_transfer
;
701 resource_ids_to_transfer
.push_back(id1
);
702 resource_ids_to_transfer
.push_back(id2
);
703 resource_ids_to_transfer
.push_back(id3
);
704 TransferableResourceArray list
;
705 child_resource_provider_
->PrepareSendToParent(resource_ids_to_transfer
,
707 EXPECT_EQ(3u, list
.size());
708 EXPECT_EQ(id1
, list
[0].id
);
709 EXPECT_EQ(id2
, list
[1].id
);
710 EXPECT_EQ(id3
, list
[2].id
);
711 EXPECT_EQ(static_cast<GLenum
>(GL_TEXTURE_2D
),
712 list
[0].mailbox_holder
.texture_target
);
713 EXPECT_EQ(static_cast<GLenum
>(GL_TEXTURE_2D
),
714 list
[1].mailbox_holder
.texture_target
);
715 EXPECT_EQ(static_cast<GLenum
>(GL_TEXTURE_2D
),
716 list
[2].mailbox_holder
.texture_target
);
717 ReturnedResourceArray returned
;
718 TransferableResource::ReturnResources(list
, &returned
);
719 child_resource_provider_
->ReceiveReturnsFromParent(returned
);
720 // ids were exported twice, we returned them only once, they should still
722 EXPECT_TRUE(child_resource_provider_
->InUseByConsumer(id1
));
723 EXPECT_TRUE(child_resource_provider_
->InUseByConsumer(id2
));
724 EXPECT_TRUE(child_resource_provider_
->InUseByConsumer(id3
));
727 EXPECT_EQ(0u, returned_to_child
.size());
729 // Transfer resources back from the parent to the child. Set no resources as
731 ResourceProvider::ResourceIdSet no_resources
;
732 resource_provider_
->DeclareUsedResourcesFromChild(child_id
, no_resources
);
734 ASSERT_EQ(4u, returned_to_child
.size());
735 EXPECT_NE(0u, returned_to_child
[0].sync_point
);
736 EXPECT_NE(0u, returned_to_child
[1].sync_point
);
737 EXPECT_NE(0u, returned_to_child
[2].sync_point
);
738 EXPECT_NE(0u, returned_to_child
[3].sync_point
);
739 EXPECT_FALSE(returned_to_child
[0].lost
);
740 EXPECT_FALSE(returned_to_child
[1].lost
);
741 EXPECT_FALSE(returned_to_child
[2].lost
);
742 EXPECT_FALSE(returned_to_child
[3].lost
);
743 child_resource_provider_
->ReceiveReturnsFromParent(returned_to_child
);
744 returned_to_child
.clear();
746 EXPECT_FALSE(child_resource_provider_
->InUseByConsumer(id1
));
747 EXPECT_FALSE(child_resource_provider_
->InUseByConsumer(id2
));
748 EXPECT_FALSE(child_resource_provider_
->InUseByConsumer(id3
));
749 EXPECT_FALSE(child_resource_provider_
->InUseByConsumer(id4
));
752 child_resource_provider_
->WaitSyncPointIfNeeded(id1
);
753 ResourceProvider::ScopedReadLockGL
lock(child_resource_provider_
.get(),
755 ASSERT_NE(0U, lock
.texture_id());
756 child_context_
->bindTexture(GL_TEXTURE_2D
, lock
.texture_id());
757 child_context_
->GetPixels(size
, format
, result
);
758 EXPECT_EQ(0, memcmp(data1
, result
, pixel_size
));
761 child_resource_provider_
->WaitSyncPointIfNeeded(id2
);
762 ResourceProvider::ScopedReadLockGL
lock(child_resource_provider_
.get(),
764 ASSERT_NE(0U, lock
.texture_id());
765 child_context_
->bindTexture(GL_TEXTURE_2D
, lock
.texture_id());
766 child_context_
->GetPixels(size
, format
, result
);
767 EXPECT_EQ(0, memcmp(data2
, result
, pixel_size
));
770 child_resource_provider_
->WaitSyncPointIfNeeded(id3
);
771 ResourceProvider::ScopedReadLockGL
lock(child_resource_provider_
.get(),
773 ASSERT_NE(0U, lock
.texture_id());
774 child_context_
->bindTexture(GL_TEXTURE_2D
, lock
.texture_id());
777 // Transfer resources to the parent again.
778 ResourceProvider::ResourceIdArray resource_ids_to_transfer
;
779 resource_ids_to_transfer
.push_back(id1
);
780 resource_ids_to_transfer
.push_back(id2
);
781 resource_ids_to_transfer
.push_back(id3
);
782 resource_ids_to_transfer
.push_back(id4
);
783 TransferableResourceArray list
;
784 child_resource_provider_
->PrepareSendToParent(resource_ids_to_transfer
,
786 ASSERT_EQ(4u, list
.size());
787 EXPECT_EQ(id1
, list
[0].id
);
788 EXPECT_EQ(id2
, list
[1].id
);
789 EXPECT_EQ(id3
, list
[2].id
);
790 EXPECT_EQ(id4
, list
[3].id
);
791 EXPECT_NE(0u, list
[0].mailbox_holder
.sync_point
);
792 EXPECT_NE(0u, list
[1].mailbox_holder
.sync_point
);
793 EXPECT_NE(0u, list
[2].mailbox_holder
.sync_point
);
794 EXPECT_NE(0u, list
[3].mailbox_holder
.sync_point
);
795 EXPECT_EQ(static_cast<GLenum
>(GL_TEXTURE_2D
),
796 list
[0].mailbox_holder
.texture_target
);
797 EXPECT_EQ(static_cast<GLenum
>(GL_TEXTURE_2D
),
798 list
[1].mailbox_holder
.texture_target
);
799 EXPECT_EQ(static_cast<GLenum
>(GL_TEXTURE_2D
),
800 list
[2].mailbox_holder
.texture_target
);
801 EXPECT_EQ(static_cast<GLenum
>(GL_TEXTURE_EXTERNAL_OES
),
802 list
[3].mailbox_holder
.texture_target
);
803 EXPECT_TRUE(child_resource_provider_
->InUseByConsumer(id1
));
804 EXPECT_TRUE(child_resource_provider_
->InUseByConsumer(id2
));
805 EXPECT_TRUE(child_resource_provider_
->InUseByConsumer(id3
));
806 EXPECT_TRUE(child_resource_provider_
->InUseByConsumer(id4
));
807 resource_provider_
->ReceiveFromChild(child_id
, list
);
808 ResourceProvider::ResourceIdSet resource_ids_to_receive
;
809 resource_ids_to_receive
.insert(id1
);
810 resource_ids_to_receive
.insert(id2
);
811 resource_ids_to_receive
.insert(id3
);
812 resource_ids_to_receive
.insert(id4
);
813 resource_provider_
->DeclareUsedResourcesFromChild(child_id
,
814 resource_ids_to_receive
);
817 EXPECT_EQ(0u, returned_to_child
.size());
819 EXPECT_EQ(4u, resource_provider_
->num_resources());
820 resource_provider_
->DestroyChild(child_id
);
821 EXPECT_EQ(0u, resource_provider_
->num_resources());
823 ASSERT_EQ(4u, returned_to_child
.size());
824 EXPECT_NE(0u, returned_to_child
[0].sync_point
);
825 EXPECT_NE(0u, returned_to_child
[1].sync_point
);
826 EXPECT_NE(0u, returned_to_child
[2].sync_point
);
827 EXPECT_NE(0u, returned_to_child
[3].sync_point
);
828 EXPECT_FALSE(returned_to_child
[0].lost
);
829 EXPECT_FALSE(returned_to_child
[1].lost
);
830 EXPECT_FALSE(returned_to_child
[2].lost
);
831 EXPECT_FALSE(returned_to_child
[3].lost
);
834 class ResourceProviderTestNoSyncPoint
: public ResourceProviderTest
{
836 ResourceProviderTestNoSyncPoint() : ResourceProviderTest(false) {
837 EXPECT_EQ(ResourceProvider::RESOURCE_TYPE_GL_TEXTURE
, GetParam());
841 TEST_P(ResourceProviderTestNoSyncPoint
, TransferGLResources
) {
842 gfx::Size
size(1, 1);
843 ResourceFormat format
= RGBA_8888
;
844 size_t pixel_size
= TextureSizeBytes(size
, format
);
845 ASSERT_EQ(4U, pixel_size
);
847 ResourceId id1
= child_resource_provider_
->CreateResource(
848 size
, GL_CLAMP_TO_EDGE
, ResourceProvider::TEXTURE_HINT_IMMUTABLE
, format
);
849 uint8_t data1
[4] = {1, 2, 3, 4};
850 child_resource_provider_
->CopyToResource(id1
, data1
, size
);
852 ResourceId id2
= child_resource_provider_
->CreateResource(
853 size
, GL_CLAMP_TO_EDGE
, ResourceProvider::TEXTURE_HINT_IMMUTABLE
, format
);
855 // Ensure locking the memory buffer doesn't create an unnecessary sync
857 ResourceProvider::ScopedWriteLockGpuMemoryBuffer
lock(
858 child_resource_provider_
.get(), id2
);
859 EXPECT_TRUE(lock
.GetGpuMemoryBuffer());
862 GLuint external_texture_id
= child_context_
->createExternalTexture();
864 // A sync point is specified directly and should be used.
865 gpu::Mailbox external_mailbox
;
866 child_context_
->genMailboxCHROMIUM(external_mailbox
.name
);
867 child_context_
->produceTextureDirectCHROMIUM(
868 external_texture_id
, GL_TEXTURE_EXTERNAL_OES
, external_mailbox
.name
);
869 const GLuint external_sync_point
= child_context_
->insertSyncPoint();
870 ResourceId id3
= child_resource_provider_
->CreateResourceFromTextureMailbox(
871 TextureMailbox(external_mailbox
, GL_TEXTURE_EXTERNAL_OES
,
872 external_sync_point
),
873 SingleReleaseCallbackImpl::Create(base::Bind(&EmptyReleaseCallback
)));
875 ReturnedResourceArray returned_to_child
;
877 resource_provider_
->CreateChild(GetReturnCallback(&returned_to_child
));
878 resource_provider_
->SetChildNeedsSyncPoints(child_id
, false);
880 // Transfer some resources to the parent.
881 ResourceProvider::ResourceIdArray resource_ids_to_transfer
;
882 resource_ids_to_transfer
.push_back(id1
);
883 resource_ids_to_transfer
.push_back(id2
);
884 resource_ids_to_transfer
.push_back(id3
);
885 TransferableResourceArray list
;
886 child_resource_provider_
->PrepareSendToParent(resource_ids_to_transfer
,
888 ASSERT_EQ(3u, list
.size());
889 // Standard resources shouldn't require creating and sending a sync point.
890 EXPECT_EQ(0u, list
[0].mailbox_holder
.sync_point
);
891 EXPECT_EQ(0u, list
[1].mailbox_holder
.sync_point
);
892 // A given sync point should be passed through.
893 EXPECT_EQ(external_sync_point
, list
[2].mailbox_holder
.sync_point
);
894 resource_provider_
->ReceiveFromChild(child_id
, list
);
896 ResourceProvider::ResourceIdSet resource_ids_to_receive
;
897 resource_ids_to_receive
.insert(id1
);
898 resource_ids_to_receive
.insert(id2
);
899 resource_ids_to_receive
.insert(id3
);
900 resource_provider_
->DeclareUsedResourcesFromChild(child_id
,
901 resource_ids_to_receive
);
905 EXPECT_EQ(0u, returned_to_child
.size());
907 // Transfer resources back from the parent to the child. Set no resources as
909 ResourceProvider::ResourceIdSet no_resources
;
910 resource_provider_
->DeclareUsedResourcesFromChild(child_id
, no_resources
);
912 ASSERT_EQ(3u, returned_to_child
.size());
913 std::map
<ResourceId
, unsigned int> returned_sync_points
;
914 for (const auto& returned
: returned_to_child
)
915 returned_sync_points
[returned
.id
] = returned
.sync_point
;
917 EXPECT_TRUE(returned_sync_points
.find(id1
) != returned_sync_points
.end());
918 // No new sync point should be created transferring back.
919 EXPECT_TRUE(returned_sync_points
.find(id1
) != returned_sync_points
.end());
920 EXPECT_EQ(0u, returned_sync_points
[id1
]);
921 EXPECT_TRUE(returned_sync_points
.find(id2
) != returned_sync_points
.end());
922 EXPECT_EQ(0u, returned_sync_points
[id2
]);
923 // Original sync point given should be returned.
924 EXPECT_TRUE(returned_sync_points
.find(id3
) != returned_sync_points
.end());
925 EXPECT_EQ(external_sync_point
, returned_sync_points
[id3
]);
926 EXPECT_FALSE(returned_to_child
[0].lost
);
927 EXPECT_FALSE(returned_to_child
[1].lost
);
928 EXPECT_FALSE(returned_to_child
[2].lost
);
929 child_resource_provider_
->ReceiveReturnsFromParent(returned_to_child
);
930 returned_to_child
.clear();
933 resource_provider_
->DestroyChild(child_id
);
936 INSTANTIATE_TEST_CASE_P(
937 ResourceProviderTests
,
938 ResourceProviderTestNoSyncPoint
,
939 ::testing::Values(ResourceProvider::RESOURCE_TYPE_GL_TEXTURE
));
941 TEST_P(ResourceProviderTest
, ReadLockCountStopsReturnToChildOrDelete
) {
942 if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE
)
944 gfx::Size
size(1, 1);
945 ResourceFormat format
= RGBA_8888
;
947 ResourceId id1
= child_resource_provider_
->CreateResource(
948 size
, GL_CLAMP_TO_EDGE
, ResourceProvider::TEXTURE_HINT_IMMUTABLE
, format
);
949 uint8_t data1
[4] = {1, 2, 3, 4};
950 child_resource_provider_
->CopyToResource(id1
, data1
, size
);
952 ReturnedResourceArray returned_to_child
;
954 resource_provider_
->CreateChild(GetReturnCallback(&returned_to_child
));
956 // Transfer some resources to the parent.
957 ResourceProvider::ResourceIdArray resource_ids_to_transfer
;
958 resource_ids_to_transfer
.push_back(id1
);
959 TransferableResourceArray list
;
960 child_resource_provider_
->PrepareSendToParent(resource_ids_to_transfer
,
962 ASSERT_EQ(1u, list
.size());
963 EXPECT_TRUE(child_resource_provider_
->InUseByConsumer(id1
));
965 resource_provider_
->ReceiveFromChild(child_id
, list
);
967 resource_provider_
->WaitSyncPointIfNeeded(list
[0].id
);
968 ResourceProvider::ScopedReadLockGL
lock(resource_provider_
.get(),
971 resource_provider_
->DeclareUsedResourcesFromChild(
972 child_id
, ResourceProvider::ResourceIdSet());
973 EXPECT_EQ(0u, returned_to_child
.size());
976 EXPECT_EQ(1u, returned_to_child
.size());
977 child_resource_provider_
->ReceiveReturnsFromParent(returned_to_child
);
980 child_resource_provider_
->WaitSyncPointIfNeeded(id1
);
981 ResourceProvider::ScopedReadLockGL
lock(child_resource_provider_
.get(),
983 child_resource_provider_
->DeleteResource(id1
);
984 EXPECT_EQ(1u, child_resource_provider_
->num_resources());
985 EXPECT_TRUE(child_resource_provider_
->InUseByConsumer(id1
));
988 EXPECT_EQ(0u, child_resource_provider_
->num_resources());
989 resource_provider_
->DestroyChild(child_id
);
992 class TestFence
: public ResourceProvider::Fence
{
996 void Set() override
{}
997 bool HasPassed() override
{ return passed
; }
998 void Wait() override
{}
1000 bool passed
= false;
1003 ~TestFence() override
{}
1006 TEST_P(ResourceProviderTest
, ReadLockFenceStopsReturnToChildOrDelete
) {
1007 if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE
)
1009 gfx::Size
size(1, 1);
1010 ResourceFormat format
= RGBA_8888
;
1012 ResourceId id1
= child_resource_provider_
->CreateResource(
1013 size
, GL_CLAMP_TO_EDGE
, ResourceProvider::TEXTURE_HINT_IMMUTABLE
, format
);
1014 uint8_t data1
[4] = {1, 2, 3, 4};
1015 child_resource_provider_
->CopyToResource(id1
, data1
, size
);
1016 child_resource_provider_
->EnableReadLockFencesForTesting(id1
);
1017 ReturnedResourceArray returned_to_child
;
1019 resource_provider_
->CreateChild(GetReturnCallback(&returned_to_child
));
1021 // Transfer some resources to the parent.
1022 ResourceProvider::ResourceIdArray resource_ids_to_transfer
;
1023 resource_ids_to_transfer
.push_back(id1
);
1024 TransferableResourceArray list
;
1025 child_resource_provider_
->PrepareSendToParent(resource_ids_to_transfer
,
1027 ASSERT_EQ(1u, list
.size());
1028 EXPECT_TRUE(child_resource_provider_
->InUseByConsumer(id1
));
1029 EXPECT_TRUE(list
[0].read_lock_fences_enabled
);
1031 resource_provider_
->ReceiveFromChild(child_id
, list
);
1033 scoped_refptr
<TestFence
> fence(new TestFence
);
1034 resource_provider_
->SetReadLockFence(fence
.get());
1036 unsigned parent_id
= list
.front().id
;
1037 resource_provider_
->WaitSyncPointIfNeeded(parent_id
);
1038 ResourceProvider::ScopedReadLockGL
lock(resource_provider_
.get(),
1041 resource_provider_
->DeclareUsedResourcesFromChild(
1042 child_id
, ResourceProvider::ResourceIdSet());
1043 EXPECT_EQ(0u, returned_to_child
.size());
1045 resource_provider_
->DeclareUsedResourcesFromChild(
1046 child_id
, ResourceProvider::ResourceIdSet());
1047 EXPECT_EQ(0u, returned_to_child
.size());
1048 fence
->passed
= true;
1050 resource_provider_
->DeclareUsedResourcesFromChild(
1051 child_id
, ResourceProvider::ResourceIdSet());
1052 EXPECT_EQ(1u, returned_to_child
.size());
1054 child_resource_provider_
->ReceiveReturnsFromParent(returned_to_child
);
1055 child_resource_provider_
->DeleteResource(id1
);
1056 EXPECT_EQ(0u, child_resource_provider_
->num_resources());
1059 TEST_P(ResourceProviderTest
, ReadLockFenceDestroyChild
) {
1060 if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE
)
1062 gfx::Size
size(1, 1);
1063 ResourceFormat format
= RGBA_8888
;
1065 ResourceId id1
= child_resource_provider_
->CreateResource(
1066 size
, GL_CLAMP_TO_EDGE
, ResourceProvider::TEXTURE_HINT_IMMUTABLE
, format
);
1067 uint8_t data
[4] = {1, 2, 3, 4};
1068 child_resource_provider_
->CopyToResource(id1
, data
, size
);
1069 child_resource_provider_
->EnableReadLockFencesForTesting(id1
);
1071 ResourceId id2
= child_resource_provider_
->CreateResource(
1072 size
, GL_CLAMP_TO_EDGE
, ResourceProvider::TEXTURE_HINT_IMMUTABLE
, format
);
1073 child_resource_provider_
->CopyToResource(id2
, data
, size
);
1075 ReturnedResourceArray returned_to_child
;
1077 resource_provider_
->CreateChild(GetReturnCallback(&returned_to_child
));
1079 // Transfer resources to the parent.
1080 ResourceProvider::ResourceIdArray resource_ids_to_transfer
;
1081 resource_ids_to_transfer
.push_back(id1
);
1082 resource_ids_to_transfer
.push_back(id2
);
1083 TransferableResourceArray list
;
1084 child_resource_provider_
->PrepareSendToParent(resource_ids_to_transfer
,
1086 ASSERT_EQ(2u, list
.size());
1087 EXPECT_TRUE(child_resource_provider_
->InUseByConsumer(id1
));
1088 EXPECT_TRUE(child_resource_provider_
->InUseByConsumer(id2
));
1090 resource_provider_
->ReceiveFromChild(child_id
, list
);
1092 scoped_refptr
<TestFence
> fence(new TestFence
);
1093 resource_provider_
->SetReadLockFence(fence
.get());
1095 for (size_t i
= 0; i
< list
.size(); i
++) {
1096 unsigned parent_id
= list
[i
].id
;
1097 resource_provider_
->WaitSyncPointIfNeeded(parent_id
);
1098 ResourceProvider::ScopedReadLockGL
lock(resource_provider_
.get(),
1102 EXPECT_EQ(0u, returned_to_child
.size());
1104 EXPECT_EQ(2u, resource_provider_
->num_resources());
1106 resource_provider_
->DestroyChild(child_id
);
1108 EXPECT_EQ(0u, resource_provider_
->num_resources());
1109 EXPECT_EQ(2u, returned_to_child
.size());
1111 // id1 should be lost and id2 should not.
1112 EXPECT_EQ(returned_to_child
[0].lost
, returned_to_child
[0].id
== id1
);
1113 EXPECT_EQ(returned_to_child
[1].lost
, returned_to_child
[1].id
== id1
);
1115 child_resource_provider_
->ReceiveReturnsFromParent(returned_to_child
);
1116 child_resource_provider_
->DeleteResource(id1
);
1117 child_resource_provider_
->DeleteResource(id2
);
1118 EXPECT_EQ(0u, child_resource_provider_
->num_resources());
1121 TEST_P(ResourceProviderTest
, ReadLockFenceContextLost
) {
1122 if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE
)
1124 gfx::Size
size(1, 1);
1125 ResourceFormat format
= RGBA_8888
;
1127 ResourceId id1
= child_resource_provider_
->CreateResource(
1128 size
, GL_CLAMP_TO_EDGE
, ResourceProvider::TEXTURE_HINT_IMMUTABLE
, format
);
1129 uint8_t data
[4] = {1, 2, 3, 4};
1130 child_resource_provider_
->CopyToResource(id1
, data
, size
);
1131 child_resource_provider_
->EnableReadLockFencesForTesting(id1
);
1133 ResourceId id2
= child_resource_provider_
->CreateResource(
1134 size
, GL_CLAMP_TO_EDGE
, ResourceProvider::TEXTURE_HINT_IMMUTABLE
, format
);
1135 child_resource_provider_
->CopyToResource(id2
, data
, size
);
1137 ReturnedResourceArray returned_to_child
;
1139 resource_provider_
->CreateChild(GetReturnCallback(&returned_to_child
));
1141 // Transfer resources to the parent.
1142 ResourceProvider::ResourceIdArray resource_ids_to_transfer
;
1143 resource_ids_to_transfer
.push_back(id1
);
1144 resource_ids_to_transfer
.push_back(id2
);
1145 TransferableResourceArray list
;
1146 child_resource_provider_
->PrepareSendToParent(resource_ids_to_transfer
,
1148 ASSERT_EQ(2u, list
.size());
1149 EXPECT_TRUE(child_resource_provider_
->InUseByConsumer(id1
));
1150 EXPECT_TRUE(child_resource_provider_
->InUseByConsumer(id2
));
1152 resource_provider_
->ReceiveFromChild(child_id
, list
);
1154 scoped_refptr
<TestFence
> fence(new TestFence
);
1155 resource_provider_
->SetReadLockFence(fence
.get());
1157 for (size_t i
= 0; i
< list
.size(); i
++) {
1158 unsigned parent_id
= list
[i
].id
;
1159 resource_provider_
->WaitSyncPointIfNeeded(parent_id
);
1160 ResourceProvider::ScopedReadLockGL
lock(resource_provider_
.get(),
1164 EXPECT_EQ(0u, returned_to_child
.size());
1166 EXPECT_EQ(2u, resource_provider_
->num_resources());
1167 resource_provider_
->DidLoseOutputSurface();
1168 resource_provider_
= nullptr;
1170 EXPECT_EQ(2u, returned_to_child
.size());
1172 EXPECT_TRUE(returned_to_child
[0].lost
);
1173 EXPECT_TRUE(returned_to_child
[1].lost
);
1176 TEST_P(ResourceProviderTest
, TransferSoftwareResources
) {
1177 if (GetParam() != ResourceProvider::RESOURCE_TYPE_BITMAP
)
1180 gfx::Size
size(1, 1);
1181 ResourceFormat format
= RGBA_8888
;
1182 size_t pixel_size
= TextureSizeBytes(size
, format
);
1183 ASSERT_EQ(4U, pixel_size
);
1185 ResourceId id1
= child_resource_provider_
->CreateResource(
1186 size
, GL_CLAMP_TO_EDGE
, ResourceProvider::TEXTURE_HINT_IMMUTABLE
, format
);
1187 uint8_t data1
[4] = { 1, 2, 3, 4 };
1188 child_resource_provider_
->CopyToResource(id1
, data1
, size
);
1190 ResourceId id2
= child_resource_provider_
->CreateResource(
1191 size
, GL_CLAMP_TO_EDGE
, ResourceProvider::TEXTURE_HINT_IMMUTABLE
, format
);
1192 uint8_t data2
[4] = { 5, 5, 5, 5 };
1193 child_resource_provider_
->CopyToResource(id2
, data2
, size
);
1195 scoped_ptr
<SharedBitmap
> shared_bitmap(CreateAndFillSharedBitmap(
1196 shared_bitmap_manager_
.get(), gfx::Size(1, 1), 0));
1197 SharedBitmap
* shared_bitmap_ptr
= shared_bitmap
.get();
1198 ResourceId id3
= child_resource_provider_
->CreateResourceFromTextureMailbox(
1199 TextureMailbox(shared_bitmap_ptr
, gfx::Size(1, 1)),
1200 SingleReleaseCallbackImpl::Create(base::Bind(
1201 &SharedBitmapReleaseCallback
, base::Passed(&shared_bitmap
))));
1203 ReturnedResourceArray returned_to_child
;
1205 resource_provider_
->CreateChild(GetReturnCallback(&returned_to_child
));
1207 // Transfer some resources to the parent.
1208 ResourceProvider::ResourceIdArray resource_ids_to_transfer
;
1209 resource_ids_to_transfer
.push_back(id1
);
1210 resource_ids_to_transfer
.push_back(id2
);
1211 resource_ids_to_transfer
.push_back(id3
);
1212 TransferableResourceArray list
;
1213 child_resource_provider_
->PrepareSendToParent(resource_ids_to_transfer
,
1215 ASSERT_EQ(3u, list
.size());
1216 EXPECT_EQ(0u, list
[0].mailbox_holder
.sync_point
);
1217 EXPECT_EQ(0u, list
[1].mailbox_holder
.sync_point
);
1218 EXPECT_EQ(0u, list
[2].mailbox_holder
.sync_point
);
1219 EXPECT_TRUE(child_resource_provider_
->InUseByConsumer(id1
));
1220 EXPECT_TRUE(child_resource_provider_
->InUseByConsumer(id2
));
1221 EXPECT_TRUE(child_resource_provider_
->InUseByConsumer(id3
));
1222 resource_provider_
->ReceiveFromChild(child_id
, list
);
1223 ResourceProvider::ResourceIdSet resource_ids_to_receive
;
1224 resource_ids_to_receive
.insert(id1
);
1225 resource_ids_to_receive
.insert(id2
);
1226 resource_ids_to_receive
.insert(id3
);
1227 resource_provider_
->DeclareUsedResourcesFromChild(child_id
,
1228 resource_ids_to_receive
);
1231 EXPECT_EQ(3u, resource_provider_
->num_resources());
1232 ResourceProvider::ResourceIdMap resource_map
=
1233 resource_provider_
->GetChildToParentMap(child_id
);
1234 ResourceId mapped_id1
= resource_map
[id1
];
1235 ResourceId mapped_id2
= resource_map
[id2
];
1236 ResourceId mapped_id3
= resource_map
[id3
];
1237 EXPECT_NE(0u, mapped_id1
);
1238 EXPECT_NE(0u, mapped_id2
);
1239 EXPECT_NE(0u, mapped_id3
);
1240 EXPECT_FALSE(resource_provider_
->InUseByConsumer(id1
));
1241 EXPECT_FALSE(resource_provider_
->InUseByConsumer(id2
));
1242 EXPECT_FALSE(resource_provider_
->InUseByConsumer(id3
));
1244 uint8_t result
[4] = { 0 };
1246 resource_provider_
.get(), context(), mapped_id1
, size
, format
, result
);
1247 EXPECT_EQ(0, memcmp(data1
, result
, pixel_size
));
1250 resource_provider_
.get(), context(), mapped_id2
, size
, format
, result
);
1251 EXPECT_EQ(0, memcmp(data2
, result
, pixel_size
));
1254 // Check that transfering again the same resource from the child to the
1256 ResourceProvider::ResourceIdArray resource_ids_to_transfer
;
1257 resource_ids_to_transfer
.push_back(id1
);
1258 resource_ids_to_transfer
.push_back(id2
);
1259 TransferableResourceArray list
;
1260 child_resource_provider_
->PrepareSendToParent(resource_ids_to_transfer
,
1262 EXPECT_EQ(2u, list
.size());
1263 EXPECT_EQ(id1
, list
[0].id
);
1264 EXPECT_EQ(id2
, list
[1].id
);
1265 ReturnedResourceArray returned
;
1266 TransferableResource::ReturnResources(list
, &returned
);
1267 child_resource_provider_
->ReceiveReturnsFromParent(returned
);
1268 // ids were exported twice, we returned them only once, they should still
1270 EXPECT_TRUE(child_resource_provider_
->InUseByConsumer(id1
));
1271 EXPECT_TRUE(child_resource_provider_
->InUseByConsumer(id2
));
1274 EXPECT_EQ(0u, returned_to_child
.size());
1276 // Transfer resources back from the parent to the child. Set no resources as
1278 ResourceProvider::ResourceIdSet no_resources
;
1279 resource_provider_
->DeclareUsedResourcesFromChild(child_id
, no_resources
);
1281 ASSERT_EQ(3u, returned_to_child
.size());
1282 EXPECT_EQ(0u, returned_to_child
[0].sync_point
);
1283 EXPECT_EQ(0u, returned_to_child
[1].sync_point
);
1284 EXPECT_EQ(0u, returned_to_child
[2].sync_point
);
1285 std::set
<ResourceId
> expected_ids
;
1286 expected_ids
.insert(id1
);
1287 expected_ids
.insert(id2
);
1288 expected_ids
.insert(id3
);
1289 std::set
<ResourceId
> returned_ids
;
1290 for (unsigned i
= 0; i
< 3; i
++)
1291 returned_ids
.insert(returned_to_child
[i
].id
);
1292 EXPECT_EQ(expected_ids
, returned_ids
);
1293 EXPECT_FALSE(returned_to_child
[0].lost
);
1294 EXPECT_FALSE(returned_to_child
[1].lost
);
1295 EXPECT_FALSE(returned_to_child
[2].lost
);
1296 child_resource_provider_
->ReceiveReturnsFromParent(returned_to_child
);
1297 returned_to_child
.clear();
1299 EXPECT_FALSE(child_resource_provider_
->InUseByConsumer(id1
));
1300 EXPECT_FALSE(child_resource_provider_
->InUseByConsumer(id2
));
1301 EXPECT_FALSE(child_resource_provider_
->InUseByConsumer(id3
));
1304 ResourceProvider::ScopedReadLockSoftware
lock(
1305 child_resource_provider_
.get(), id1
);
1306 const SkBitmap
* sk_bitmap
= lock
.sk_bitmap();
1307 EXPECT_EQ(sk_bitmap
->width(), size
.width());
1308 EXPECT_EQ(sk_bitmap
->height(), size
.height());
1309 EXPECT_EQ(0, memcmp(data1
, sk_bitmap
->getPixels(), pixel_size
));
1312 ResourceProvider::ScopedReadLockSoftware
lock(
1313 child_resource_provider_
.get(), id2
);
1314 const SkBitmap
* sk_bitmap
= lock
.sk_bitmap();
1315 EXPECT_EQ(sk_bitmap
->width(), size
.width());
1316 EXPECT_EQ(sk_bitmap
->height(), size
.height());
1317 EXPECT_EQ(0, memcmp(data2
, sk_bitmap
->getPixels(), pixel_size
));
1320 // Transfer resources to the parent again.
1321 ResourceProvider::ResourceIdArray resource_ids_to_transfer
;
1322 resource_ids_to_transfer
.push_back(id1
);
1323 resource_ids_to_transfer
.push_back(id2
);
1324 resource_ids_to_transfer
.push_back(id3
);
1325 TransferableResourceArray list
;
1326 child_resource_provider_
->PrepareSendToParent(resource_ids_to_transfer
,
1328 ASSERT_EQ(3u, list
.size());
1329 EXPECT_EQ(id1
, list
[0].id
);
1330 EXPECT_EQ(id2
, list
[1].id
);
1331 EXPECT_EQ(id3
, list
[2].id
);
1332 EXPECT_TRUE(child_resource_provider_
->InUseByConsumer(id1
));
1333 EXPECT_TRUE(child_resource_provider_
->InUseByConsumer(id2
));
1334 EXPECT_TRUE(child_resource_provider_
->InUseByConsumer(id3
));
1335 resource_provider_
->ReceiveFromChild(child_id
, list
);
1336 ResourceProvider::ResourceIdSet resource_ids_to_receive
;
1337 resource_ids_to_receive
.insert(id1
);
1338 resource_ids_to_receive
.insert(id2
);
1339 resource_ids_to_receive
.insert(id3
);
1340 resource_provider_
->DeclareUsedResourcesFromChild(child_id
,
1341 resource_ids_to_receive
);
1344 EXPECT_EQ(0u, returned_to_child
.size());
1346 EXPECT_EQ(3u, resource_provider_
->num_resources());
1347 resource_provider_
->DestroyChild(child_id
);
1348 EXPECT_EQ(0u, resource_provider_
->num_resources());
1350 ASSERT_EQ(3u, returned_to_child
.size());
1351 EXPECT_EQ(0u, returned_to_child
[0].sync_point
);
1352 EXPECT_EQ(0u, returned_to_child
[1].sync_point
);
1353 EXPECT_EQ(0u, returned_to_child
[2].sync_point
);
1354 std::set
<ResourceId
> expected_ids
;
1355 expected_ids
.insert(id1
);
1356 expected_ids
.insert(id2
);
1357 expected_ids
.insert(id3
);
1358 std::set
<ResourceId
> returned_ids
;
1359 for (unsigned i
= 0; i
< 3; i
++)
1360 returned_ids
.insert(returned_to_child
[i
].id
);
1361 EXPECT_EQ(expected_ids
, returned_ids
);
1362 EXPECT_FALSE(returned_to_child
[0].lost
);
1363 EXPECT_FALSE(returned_to_child
[1].lost
);
1364 EXPECT_FALSE(returned_to_child
[2].lost
);
1367 TEST_P(ResourceProviderTest
, TransferGLToSoftware
) {
1368 if (GetParam() != ResourceProvider::RESOURCE_TYPE_BITMAP
)
1371 scoped_ptr
<ResourceProviderContext
> child_context_owned(
1372 ResourceProviderContext::Create(shared_data_
.get()));
1374 FakeOutputSurfaceClient child_output_surface_client
;
1375 scoped_ptr
<OutputSurface
> child_output_surface(
1376 FakeOutputSurface::Create3d(child_context_owned
.Pass()));
1377 CHECK(child_output_surface
->BindToClient(&child_output_surface_client
));
1379 scoped_ptr
<ResourceProvider
> child_resource_provider(ResourceProvider::Create(
1380 child_output_surface
.get(), shared_bitmap_manager_
.get(),
1381 gpu_memory_buffer_manager_
.get(), NULL
, 0, false, 1,
1382 use_image_texture_targets_
));
1384 gfx::Size
size(1, 1);
1385 ResourceFormat format
= RGBA_8888
;
1386 size_t pixel_size
= TextureSizeBytes(size
, format
);
1387 ASSERT_EQ(4U, pixel_size
);
1389 ResourceId id1
= child_resource_provider
->CreateResource(
1390 size
, GL_CLAMP_TO_EDGE
, ResourceProvider::TEXTURE_HINT_IMMUTABLE
, format
);
1391 uint8_t data1
[4] = { 1, 2, 3, 4 };
1392 child_resource_provider
->CopyToResource(id1
, data1
, size
);
1394 ReturnedResourceArray returned_to_child
;
1396 resource_provider_
->CreateChild(GetReturnCallback(&returned_to_child
));
1398 ResourceProvider::ResourceIdArray resource_ids_to_transfer
;
1399 resource_ids_to_transfer
.push_back(id1
);
1400 TransferableResourceArray list
;
1401 child_resource_provider
->PrepareSendToParent(resource_ids_to_transfer
,
1403 ASSERT_EQ(1u, list
.size());
1404 EXPECT_NE(0u, list
[0].mailbox_holder
.sync_point
);
1405 EXPECT_EQ(static_cast<GLenum
>(GL_TEXTURE_2D
),
1406 list
[0].mailbox_holder
.texture_target
);
1407 EXPECT_TRUE(child_resource_provider
->InUseByConsumer(id1
));
1408 resource_provider_
->ReceiveFromChild(child_id
, list
);
1411 EXPECT_EQ(0u, resource_provider_
->num_resources());
1412 ASSERT_EQ(1u, returned_to_child
.size());
1413 EXPECT_EQ(returned_to_child
[0].id
, id1
);
1414 ResourceProvider::ResourceIdMap resource_map
=
1415 resource_provider_
->GetChildToParentMap(child_id
);
1416 ResourceId mapped_id1
= resource_map
[id1
];
1417 EXPECT_EQ(0u, mapped_id1
);
1419 resource_provider_
->DestroyChild(child_id
);
1420 EXPECT_EQ(0u, resource_provider_
->num_resources());
1422 ASSERT_EQ(1u, returned_to_child
.size());
1423 EXPECT_FALSE(returned_to_child
[0].lost
);
1426 TEST_P(ResourceProviderTest
, TransferInvalidSoftware
) {
1427 if (GetParam() != ResourceProvider::RESOURCE_TYPE_BITMAP
)
1430 gfx::Size
size(1, 1);
1431 ResourceFormat format
= RGBA_8888
;
1432 size_t pixel_size
= TextureSizeBytes(size
, format
);
1433 ASSERT_EQ(4U, pixel_size
);
1435 ResourceId id1
= child_resource_provider_
->CreateResource(
1436 size
, GL_CLAMP_TO_EDGE
, ResourceProvider::TEXTURE_HINT_IMMUTABLE
, format
);
1437 uint8_t data1
[4] = { 1, 2, 3, 4 };
1438 child_resource_provider_
->CopyToResource(id1
, data1
, size
);
1440 ReturnedResourceArray returned_to_child
;
1442 resource_provider_
->CreateChild(GetReturnCallback(&returned_to_child
));
1444 ResourceProvider::ResourceIdArray resource_ids_to_transfer
;
1445 resource_ids_to_transfer
.push_back(id1
);
1446 TransferableResourceArray list
;
1447 child_resource_provider_
->PrepareSendToParent(resource_ids_to_transfer
,
1449 ASSERT_EQ(1u, list
.size());
1451 list
[0].mailbox_holder
.mailbox
.name
[1] = 5;
1452 EXPECT_TRUE(child_resource_provider_
->InUseByConsumer(id1
));
1453 resource_provider_
->ReceiveFromChild(child_id
, list
);
1456 EXPECT_EQ(1u, resource_provider_
->num_resources());
1457 EXPECT_EQ(0u, returned_to_child
.size());
1459 ResourceProvider::ResourceIdMap resource_map
=
1460 resource_provider_
->GetChildToParentMap(child_id
);
1461 ResourceId mapped_id1
= resource_map
[id1
];
1462 EXPECT_NE(0u, mapped_id1
);
1464 ResourceProvider::ScopedReadLockSoftware
lock(resource_provider_
.get(),
1466 EXPECT_FALSE(lock
.valid());
1469 resource_provider_
->DestroyChild(child_id
);
1470 EXPECT_EQ(0u, resource_provider_
->num_resources());
1472 ASSERT_EQ(1u, returned_to_child
.size());
1473 EXPECT_FALSE(returned_to_child
[0].lost
);
1476 TEST_P(ResourceProviderTest
, DeleteExportedResources
) {
1477 gfx::Size
size(1, 1);
1478 ResourceFormat format
= RGBA_8888
;
1479 size_t pixel_size
= TextureSizeBytes(size
, format
);
1480 ASSERT_EQ(4U, pixel_size
);
1482 ResourceId id1
= child_resource_provider_
->CreateResource(
1483 size
, GL_CLAMP_TO_EDGE
, ResourceProvider::TEXTURE_HINT_IMMUTABLE
, format
);
1484 uint8_t data1
[4] = { 1, 2, 3, 4 };
1485 child_resource_provider_
->CopyToResource(id1
, data1
, size
);
1487 ResourceId id2
= child_resource_provider_
->CreateResource(
1488 size
, GL_CLAMP_TO_EDGE
, ResourceProvider::TEXTURE_HINT_IMMUTABLE
, format
);
1489 uint8_t data2
[4] = {5, 5, 5, 5};
1490 child_resource_provider_
->CopyToResource(id2
, data2
, size
);
1492 ReturnedResourceArray returned_to_child
;
1494 resource_provider_
->CreateChild(GetReturnCallback(&returned_to_child
));
1496 // Transfer some resources to the parent.
1497 ResourceProvider::ResourceIdArray resource_ids_to_transfer
;
1498 resource_ids_to_transfer
.push_back(id1
);
1499 resource_ids_to_transfer
.push_back(id2
);
1500 TransferableResourceArray list
;
1501 child_resource_provider_
->PrepareSendToParent(resource_ids_to_transfer
,
1503 ASSERT_EQ(2u, list
.size());
1504 if (GetParam() == ResourceProvider::RESOURCE_TYPE_GL_TEXTURE
) {
1505 EXPECT_NE(0u, list
[0].mailbox_holder
.sync_point
);
1506 EXPECT_NE(0u, list
[1].mailbox_holder
.sync_point
);
1508 EXPECT_TRUE(child_resource_provider_
->InUseByConsumer(id1
));
1509 EXPECT_TRUE(child_resource_provider_
->InUseByConsumer(id2
));
1510 resource_provider_
->ReceiveFromChild(child_id
, list
);
1511 ResourceProvider::ResourceIdSet resource_ids_to_receive
;
1512 resource_ids_to_receive
.insert(id1
);
1513 resource_ids_to_receive
.insert(id2
);
1514 resource_provider_
->DeclareUsedResourcesFromChild(child_id
,
1515 resource_ids_to_receive
);
1518 EXPECT_EQ(2u, resource_provider_
->num_resources());
1519 ResourceProvider::ResourceIdMap resource_map
=
1520 resource_provider_
->GetChildToParentMap(child_id
);
1521 ResourceId mapped_id1
= resource_map
[id1
];
1522 ResourceId mapped_id2
= resource_map
[id2
];
1523 EXPECT_NE(0u, mapped_id1
);
1524 EXPECT_NE(0u, mapped_id2
);
1525 EXPECT_FALSE(resource_provider_
->InUseByConsumer(id1
));
1526 EXPECT_FALSE(resource_provider_
->InUseByConsumer(id2
));
1529 // The parent transfers the resources to the grandparent.
1530 ResourceProvider::ResourceIdArray resource_ids_to_transfer
;
1531 resource_ids_to_transfer
.push_back(mapped_id1
);
1532 resource_ids_to_transfer
.push_back(mapped_id2
);
1533 TransferableResourceArray list
;
1534 resource_provider_
->PrepareSendToParent(resource_ids_to_transfer
, &list
);
1536 ASSERT_EQ(2u, list
.size());
1537 if (GetParam() == ResourceProvider::RESOURCE_TYPE_GL_TEXTURE
) {
1538 EXPECT_NE(0u, list
[0].mailbox_holder
.sync_point
);
1539 EXPECT_NE(0u, list
[1].mailbox_holder
.sync_point
);
1541 EXPECT_TRUE(resource_provider_
->InUseByConsumer(id1
));
1542 EXPECT_TRUE(resource_provider_
->InUseByConsumer(id2
));
1544 // Release the resource in the parent. Set no resources as being in use. The
1545 // resources are exported so that can't be transferred back yet.
1546 ResourceProvider::ResourceIdSet no_resources
;
1547 resource_provider_
->DeclareUsedResourcesFromChild(child_id
, no_resources
);
1549 EXPECT_EQ(0u, returned_to_child
.size());
1550 EXPECT_EQ(2u, resource_provider_
->num_resources());
1552 // Return the resources from the grandparent to the parent. They should be
1553 // returned to the child then.
1554 EXPECT_EQ(2u, list
.size());
1555 EXPECT_EQ(mapped_id1
, list
[0].id
);
1556 EXPECT_EQ(mapped_id2
, list
[1].id
);
1557 ReturnedResourceArray returned
;
1558 TransferableResource::ReturnResources(list
, &returned
);
1559 resource_provider_
->ReceiveReturnsFromParent(returned
);
1561 EXPECT_EQ(0u, resource_provider_
->num_resources());
1562 ASSERT_EQ(2u, returned_to_child
.size());
1563 if (GetParam() == ResourceProvider::RESOURCE_TYPE_GL_TEXTURE
) {
1564 EXPECT_NE(0u, returned_to_child
[0].sync_point
);
1565 EXPECT_NE(0u, returned_to_child
[1].sync_point
);
1567 EXPECT_FALSE(returned_to_child
[0].lost
);
1568 EXPECT_FALSE(returned_to_child
[1].lost
);
1572 TEST_P(ResourceProviderTest
, DestroyChildWithExportedResources
) {
1573 gfx::Size
size(1, 1);
1574 ResourceFormat format
= RGBA_8888
;
1575 size_t pixel_size
= TextureSizeBytes(size
, format
);
1576 ASSERT_EQ(4U, pixel_size
);
1578 ResourceId id1
= child_resource_provider_
->CreateResource(
1579 size
, GL_CLAMP_TO_EDGE
, ResourceProvider::TEXTURE_HINT_IMMUTABLE
, format
);
1580 uint8_t data1
[4] = {1, 2, 3, 4};
1581 child_resource_provider_
->CopyToResource(id1
, data1
, size
);
1583 ResourceId id2
= child_resource_provider_
->CreateResource(
1584 size
, GL_CLAMP_TO_EDGE
, ResourceProvider::TEXTURE_HINT_IMMUTABLE
, format
);
1585 uint8_t data2
[4] = {5, 5, 5, 5};
1586 child_resource_provider_
->CopyToResource(id2
, data2
, size
);
1588 ReturnedResourceArray returned_to_child
;
1590 resource_provider_
->CreateChild(GetReturnCallback(&returned_to_child
));
1592 // Transfer some resources to the parent.
1593 ResourceProvider::ResourceIdArray resource_ids_to_transfer
;
1594 resource_ids_to_transfer
.push_back(id1
);
1595 resource_ids_to_transfer
.push_back(id2
);
1596 TransferableResourceArray list
;
1597 child_resource_provider_
->PrepareSendToParent(resource_ids_to_transfer
,
1599 ASSERT_EQ(2u, list
.size());
1600 if (GetParam() == ResourceProvider::RESOURCE_TYPE_GL_TEXTURE
) {
1601 EXPECT_NE(0u, list
[0].mailbox_holder
.sync_point
);
1602 EXPECT_NE(0u, list
[1].mailbox_holder
.sync_point
);
1604 EXPECT_TRUE(child_resource_provider_
->InUseByConsumer(id1
));
1605 EXPECT_TRUE(child_resource_provider_
->InUseByConsumer(id2
));
1606 resource_provider_
->ReceiveFromChild(child_id
, list
);
1607 ResourceProvider::ResourceIdSet resource_ids_to_receive
;
1608 resource_ids_to_receive
.insert(id1
);
1609 resource_ids_to_receive
.insert(id2
);
1610 resource_provider_
->DeclareUsedResourcesFromChild(child_id
,
1611 resource_ids_to_receive
);
1614 EXPECT_EQ(2u, resource_provider_
->num_resources());
1615 ResourceProvider::ResourceIdMap resource_map
=
1616 resource_provider_
->GetChildToParentMap(child_id
);
1617 ResourceId mapped_id1
= resource_map
[id1
];
1618 ResourceId mapped_id2
= resource_map
[id2
];
1619 EXPECT_NE(0u, mapped_id1
);
1620 EXPECT_NE(0u, mapped_id2
);
1621 EXPECT_FALSE(resource_provider_
->InUseByConsumer(id1
));
1622 EXPECT_FALSE(resource_provider_
->InUseByConsumer(id2
));
1625 // The parent transfers the resources to the grandparent.
1626 ResourceProvider::ResourceIdArray resource_ids_to_transfer
;
1627 resource_ids_to_transfer
.push_back(mapped_id1
);
1628 resource_ids_to_transfer
.push_back(mapped_id2
);
1629 TransferableResourceArray list
;
1630 resource_provider_
->PrepareSendToParent(resource_ids_to_transfer
, &list
);
1632 ASSERT_EQ(2u, list
.size());
1633 if (GetParam() == ResourceProvider::RESOURCE_TYPE_GL_TEXTURE
) {
1634 EXPECT_NE(0u, list
[0].mailbox_holder
.sync_point
);
1635 EXPECT_NE(0u, list
[1].mailbox_holder
.sync_point
);
1637 EXPECT_TRUE(resource_provider_
->InUseByConsumer(id1
));
1638 EXPECT_TRUE(resource_provider_
->InUseByConsumer(id2
));
1640 // Release the resource in the parent. Set no resources as being in use. The
1641 // resources are exported so that can't be transferred back yet.
1642 ResourceProvider::ResourceIdSet no_resources
;
1643 resource_provider_
->DeclareUsedResourcesFromChild(child_id
, no_resources
);
1645 // Destroy the child, the resources should not be returned yet.
1646 EXPECT_EQ(0u, returned_to_child
.size());
1647 EXPECT_EQ(2u, resource_provider_
->num_resources());
1649 resource_provider_
->DestroyChild(child_id
);
1651 EXPECT_EQ(2u, resource_provider_
->num_resources());
1652 ASSERT_EQ(0u, returned_to_child
.size());
1654 // Return a resource from the grandparent, it should be returned at this
1656 EXPECT_EQ(2u, list
.size());
1657 EXPECT_EQ(mapped_id1
, list
[0].id
);
1658 EXPECT_EQ(mapped_id2
, list
[1].id
);
1659 TransferableResourceArray return_list
;
1660 return_list
.push_back(list
[1]);
1662 ReturnedResourceArray returned
;
1663 TransferableResource::ReturnResources(return_list
, &returned
);
1664 resource_provider_
->ReceiveReturnsFromParent(returned
);
1666 EXPECT_EQ(1u, resource_provider_
->num_resources());
1667 ASSERT_EQ(1u, returned_to_child
.size());
1668 if (GetParam() == ResourceProvider::RESOURCE_TYPE_GL_TEXTURE
) {
1669 EXPECT_NE(0u, returned_to_child
[0].sync_point
);
1671 EXPECT_FALSE(returned_to_child
[0].lost
);
1672 returned_to_child
.clear();
1674 // Destroy the parent resource provider. The resource that's left should be
1675 // lost at this point, and returned.
1676 resource_provider_
= nullptr;
1677 ASSERT_EQ(1u, returned_to_child
.size());
1678 if (GetParam() == ResourceProvider::RESOURCE_TYPE_GL_TEXTURE
) {
1679 EXPECT_NE(0u, returned_to_child
[0].sync_point
);
1681 EXPECT_TRUE(returned_to_child
[0].lost
);
1685 TEST_P(ResourceProviderTest
, DeleteTransferredResources
) {
1686 gfx::Size
size(1, 1);
1687 ResourceFormat format
= RGBA_8888
;
1688 size_t pixel_size
= TextureSizeBytes(size
, format
);
1689 ASSERT_EQ(4U, pixel_size
);
1691 ResourceId id
= child_resource_provider_
->CreateResource(
1692 size
, GL_CLAMP_TO_EDGE
, ResourceProvider::TEXTURE_HINT_IMMUTABLE
, format
);
1693 uint8_t data
[4] = { 1, 2, 3, 4 };
1694 child_resource_provider_
->CopyToResource(id
, data
, size
);
1696 ReturnedResourceArray returned_to_child
;
1698 resource_provider_
->CreateChild(GetReturnCallback(&returned_to_child
));
1700 // Transfer some resource to the parent.
1701 ResourceProvider::ResourceIdArray resource_ids_to_transfer
;
1702 resource_ids_to_transfer
.push_back(id
);
1703 TransferableResourceArray list
;
1704 child_resource_provider_
->PrepareSendToParent(resource_ids_to_transfer
,
1706 ASSERT_EQ(1u, list
.size());
1707 if (GetParam() == ResourceProvider::RESOURCE_TYPE_GL_TEXTURE
)
1708 EXPECT_NE(0u, list
[0].mailbox_holder
.sync_point
);
1709 EXPECT_TRUE(child_resource_provider_
->InUseByConsumer(id
));
1710 resource_provider_
->ReceiveFromChild(child_id
, list
);
1711 ResourceProvider::ResourceIdSet resource_ids_to_receive
;
1712 resource_ids_to_receive
.insert(id
);
1713 resource_provider_
->DeclareUsedResourcesFromChild(child_id
,
1714 resource_ids_to_receive
);
1717 // Delete textures in the child, while they are transfered.
1718 child_resource_provider_
->DeleteResource(id
);
1719 EXPECT_EQ(1u, child_resource_provider_
->num_resources());
1721 EXPECT_EQ(0u, returned_to_child
.size());
1723 // Transfer resources back from the parent to the child. Set no resources as
1725 ResourceProvider::ResourceIdSet no_resources
;
1726 resource_provider_
->DeclareUsedResourcesFromChild(child_id
, no_resources
);
1728 ASSERT_EQ(1u, returned_to_child
.size());
1729 if (GetParam() == ResourceProvider::RESOURCE_TYPE_GL_TEXTURE
)
1730 EXPECT_NE(0u, returned_to_child
[0].sync_point
);
1731 child_resource_provider_
->ReceiveReturnsFromParent(returned_to_child
);
1733 EXPECT_EQ(0u, child_resource_provider_
->num_resources());
1736 TEST_P(ResourceProviderTest
, UnuseTransferredResources
) {
1737 gfx::Size
size(1, 1);
1738 ResourceFormat format
= RGBA_8888
;
1739 size_t pixel_size
= TextureSizeBytes(size
, format
);
1740 ASSERT_EQ(4U, pixel_size
);
1742 ResourceId id
= child_resource_provider_
->CreateResource(
1743 size
, GL_CLAMP_TO_EDGE
, ResourceProvider::TEXTURE_HINT_IMMUTABLE
, format
);
1744 uint8_t data
[4] = {1, 2, 3, 4};
1745 child_resource_provider_
->CopyToResource(id
, data
, size
);
1747 ReturnedResourceArray returned_to_child
;
1749 resource_provider_
->CreateChild(GetReturnCallback(&returned_to_child
));
1750 const ResourceProvider::ResourceIdMap
& map
=
1751 resource_provider_
->GetChildToParentMap(child_id
);
1753 // Transfer some resource to the parent.
1754 ResourceProvider::ResourceIdArray resource_ids_to_transfer
;
1755 resource_ids_to_transfer
.push_back(id
);
1756 TransferableResourceArray list
;
1757 child_resource_provider_
->PrepareSendToParent(resource_ids_to_transfer
,
1759 EXPECT_TRUE(child_resource_provider_
->InUseByConsumer(id
));
1760 resource_provider_
->ReceiveFromChild(child_id
, list
);
1761 ResourceProvider::ResourceIdSet resource_ids_to_receive
;
1762 resource_ids_to_receive
.insert(id
);
1763 resource_provider_
->DeclareUsedResourcesFromChild(child_id
,
1764 resource_ids_to_receive
);
1766 TransferableResourceArray sent_to_top_level
;
1768 // Parent transfers to top-level.
1769 ASSERT_TRUE(map
.find(id
) != map
.end());
1770 ResourceId parent_id
= map
.find(id
)->second
;
1771 ResourceProvider::ResourceIdArray resource_ids_to_transfer
;
1772 resource_ids_to_transfer
.push_back(parent_id
);
1773 resource_provider_
->PrepareSendToParent(resource_ids_to_transfer
,
1774 &sent_to_top_level
);
1775 EXPECT_TRUE(resource_provider_
->InUseByConsumer(parent_id
));
1778 // Stop using resource.
1779 ResourceProvider::ResourceIdSet empty
;
1780 resource_provider_
->DeclareUsedResourcesFromChild(child_id
, empty
);
1781 // Resource is not yet returned to the child, since it's in use by the
1783 EXPECT_TRUE(returned_to_child
.empty());
1786 // Send the resource to the parent again.
1787 ResourceProvider::ResourceIdArray resource_ids_to_transfer
;
1788 resource_ids_to_transfer
.push_back(id
);
1789 TransferableResourceArray list
;
1790 child_resource_provider_
->PrepareSendToParent(resource_ids_to_transfer
,
1792 EXPECT_TRUE(child_resource_provider_
->InUseByConsumer(id
));
1793 resource_provider_
->ReceiveFromChild(child_id
, list
);
1794 ResourceProvider::ResourceIdSet resource_ids_to_receive
;
1795 resource_ids_to_receive
.insert(id
);
1796 resource_provider_
->DeclareUsedResourcesFromChild(child_id
,
1797 resource_ids_to_receive
);
1800 // Receive returns back from top-level.
1801 ReturnedResourceArray returned
;
1802 TransferableResource::ReturnResources(sent_to_top_level
, &returned
);
1803 resource_provider_
->ReceiveReturnsFromParent(returned
);
1804 // Resource is still not yet returned to the child, since it's declared used
1806 EXPECT_TRUE(returned_to_child
.empty());
1807 ASSERT_TRUE(map
.find(id
) != map
.end());
1808 ResourceId parent_id
= map
.find(id
)->second
;
1809 EXPECT_FALSE(resource_provider_
->InUseByConsumer(parent_id
));
1812 sent_to_top_level
.clear();
1813 // Parent transfers again to top-level.
1814 ASSERT_TRUE(map
.find(id
) != map
.end());
1815 ResourceId parent_id
= map
.find(id
)->second
;
1816 ResourceProvider::ResourceIdArray resource_ids_to_transfer
;
1817 resource_ids_to_transfer
.push_back(parent_id
);
1818 resource_provider_
->PrepareSendToParent(resource_ids_to_transfer
,
1819 &sent_to_top_level
);
1820 EXPECT_TRUE(resource_provider_
->InUseByConsumer(parent_id
));
1823 // Receive returns back from top-level.
1824 ReturnedResourceArray returned
;
1825 TransferableResource::ReturnResources(sent_to_top_level
, &returned
);
1826 resource_provider_
->ReceiveReturnsFromParent(returned
);
1827 // Resource is still not yet returned to the child, since it's still
1828 // declared used in the parent.
1829 EXPECT_TRUE(returned_to_child
.empty());
1830 ASSERT_TRUE(map
.find(id
) != map
.end());
1831 ResourceId parent_id
= map
.find(id
)->second
;
1832 EXPECT_FALSE(resource_provider_
->InUseByConsumer(parent_id
));
1835 // Stop using resource.
1836 ResourceProvider::ResourceIdSet empty
;
1837 resource_provider_
->DeclareUsedResourcesFromChild(child_id
, empty
);
1838 // Resource should have been returned to the child, since it's no longer in
1839 // use by the top-level.
1840 ASSERT_EQ(1u, returned_to_child
.size());
1841 EXPECT_EQ(id
, returned_to_child
[0].id
);
1842 EXPECT_EQ(2, returned_to_child
[0].count
);
1843 child_resource_provider_
->ReceiveReturnsFromParent(returned_to_child
);
1844 returned_to_child
.clear();
1845 EXPECT_FALSE(child_resource_provider_
->InUseByConsumer(id
));
1849 class ResourceProviderTestTextureFilters
: public ResourceProviderTest
{
1851 static void RunTest(GLenum child_filter
, GLenum parent_filter
) {
1852 scoped_ptr
<TextureStateTrackingContext
> child_context_owned(
1853 new TextureStateTrackingContext
);
1854 TextureStateTrackingContext
* child_context
= child_context_owned
.get();
1856 FakeOutputSurfaceClient child_output_surface_client
;
1857 scoped_ptr
<OutputSurface
> child_output_surface(
1858 FakeOutputSurface::Create3d(child_context_owned
.Pass()));
1859 CHECK(child_output_surface
->BindToClient(&child_output_surface_client
));
1860 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
1861 new TestSharedBitmapManager());
1863 scoped_ptr
<ResourceProvider
> child_resource_provider(
1864 ResourceProvider::Create(child_output_surface
.get(),
1865 shared_bitmap_manager
.get(), NULL
, NULL
, 0,
1866 false, 1, use_image_texture_targets_
));
1868 scoped_ptr
<TextureStateTrackingContext
> parent_context_owned(
1869 new TextureStateTrackingContext
);
1870 TextureStateTrackingContext
* parent_context
= parent_context_owned
.get();
1872 FakeOutputSurfaceClient parent_output_surface_client
;
1873 scoped_ptr
<OutputSurface
> parent_output_surface(
1874 FakeOutputSurface::Create3d(parent_context_owned
.Pass()));
1875 CHECK(parent_output_surface
->BindToClient(&parent_output_surface_client
));
1877 scoped_ptr
<ResourceProvider
> parent_resource_provider(
1878 ResourceProvider::Create(parent_output_surface
.get(),
1879 shared_bitmap_manager
.get(), NULL
, NULL
, 0,
1880 false, 1, use_image_texture_targets_
));
1882 gfx::Size
size(1, 1);
1883 ResourceFormat format
= RGBA_8888
;
1884 int child_texture_id
= 1;
1885 int parent_texture_id
= 2;
1887 size_t pixel_size
= TextureSizeBytes(size
, format
);
1888 ASSERT_EQ(4U, pixel_size
);
1890 ResourceId id
= child_resource_provider
->CreateResource(
1891 size
, GL_CLAMP_TO_EDGE
, ResourceProvider::TEXTURE_HINT_IMMUTABLE
,
1894 // The new texture is created with GL_LINEAR.
1895 EXPECT_CALL(*child_context
, bindTexture(GL_TEXTURE_2D
, child_texture_id
))
1896 .Times(2); // Once to create and once to allocate.
1897 EXPECT_CALL(*child_context
,
1898 texParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_LINEAR
));
1899 EXPECT_CALL(*child_context
,
1900 texParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_LINEAR
));
1903 texParameteri(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_S
, GL_CLAMP_TO_EDGE
));
1906 texParameteri(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_T
, GL_CLAMP_TO_EDGE
));
1907 EXPECT_CALL(*child_context
,
1908 texParameteri(GL_TEXTURE_2D
,
1909 GL_TEXTURE_POOL_CHROMIUM
,
1910 GL_TEXTURE_POOL_UNMANAGED_CHROMIUM
));
1911 child_resource_provider
->AllocateForTesting(id
);
1912 Mock::VerifyAndClearExpectations(child_context
);
1914 uint8_t data
[4] = { 1, 2, 3, 4 };
1916 EXPECT_CALL(*child_context
, bindTexture(GL_TEXTURE_2D
, child_texture_id
));
1917 child_resource_provider
->CopyToResource(id
, data
, size
);
1918 Mock::VerifyAndClearExpectations(child_context
);
1920 // The texture is set to |child_filter| in the child.
1921 EXPECT_CALL(*child_context
, bindTexture(GL_TEXTURE_2D
, child_texture_id
));
1922 if (child_filter
!= GL_LINEAR
) {
1925 texParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, child_filter
));
1928 texParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, child_filter
));
1930 SetResourceFilter(child_resource_provider
.get(), id
, child_filter
);
1931 Mock::VerifyAndClearExpectations(child_context
);
1933 ReturnedResourceArray returned_to_child
;
1934 int child_id
= parent_resource_provider
->CreateChild(
1935 GetReturnCallback(&returned_to_child
));
1937 // Transfer some resource to the parent.
1938 ResourceProvider::ResourceIdArray resource_ids_to_transfer
;
1939 resource_ids_to_transfer
.push_back(id
);
1940 TransferableResourceArray list
;
1942 EXPECT_CALL(*child_context
,
1943 produceTextureDirectCHROMIUM(_
, GL_TEXTURE_2D
, _
));
1944 EXPECT_CALL(*child_context
, insertSyncPoint());
1945 child_resource_provider
->PrepareSendToParent(resource_ids_to_transfer
,
1947 Mock::VerifyAndClearExpectations(child_context
);
1949 ASSERT_EQ(1u, list
.size());
1950 EXPECT_EQ(static_cast<unsigned>(child_filter
), list
[0].filter
);
1952 EXPECT_CALL(*parent_context
,
1953 createAndConsumeTextureCHROMIUM(GL_TEXTURE_2D
, _
))
1954 .WillOnce(Return(parent_texture_id
));
1956 parent_resource_provider
->ReceiveFromChild(child_id
, list
);
1958 parent_resource_provider
->WaitSyncPointIfNeeded(list
[0].id
);
1959 ResourceProvider::ScopedReadLockGL
lock(parent_resource_provider
.get(),
1962 Mock::VerifyAndClearExpectations(parent_context
);
1964 ResourceProvider::ResourceIdSet resource_ids_to_receive
;
1965 resource_ids_to_receive
.insert(id
);
1966 parent_resource_provider
->DeclareUsedResourcesFromChild(
1967 child_id
, resource_ids_to_receive
);
1968 Mock::VerifyAndClearExpectations(parent_context
);
1970 ResourceProvider::ResourceIdMap resource_map
=
1971 parent_resource_provider
->GetChildToParentMap(child_id
);
1972 ResourceId mapped_id
= resource_map
[id
];
1973 EXPECT_NE(0u, mapped_id
);
1975 // The texture is set to |parent_filter| in the parent.
1976 EXPECT_CALL(*parent_context
, bindTexture(GL_TEXTURE_2D
, parent_texture_id
));
1979 texParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, parent_filter
));
1982 texParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, parent_filter
));
1983 SetResourceFilter(parent_resource_provider
.get(), mapped_id
, parent_filter
);
1984 Mock::VerifyAndClearExpectations(parent_context
);
1986 // The texture should be reset to |child_filter| in the parent when it is
1987 // returned, since that is how it was received.
1988 EXPECT_CALL(*parent_context
, bindTexture(GL_TEXTURE_2D
, parent_texture_id
));
1991 texParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, child_filter
));
1994 texParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, child_filter
));
1997 EXPECT_EQ(0u, returned_to_child
.size());
1999 // Transfer resources back from the parent to the child. Set no resources
2001 ResourceProvider::ResourceIdSet no_resources
;
2002 EXPECT_CALL(*parent_context
, insertSyncPoint());
2003 parent_resource_provider
->DeclareUsedResourcesFromChild(child_id
,
2005 Mock::VerifyAndClearExpectations(parent_context
);
2007 ASSERT_EQ(1u, returned_to_child
.size());
2008 child_resource_provider
->ReceiveReturnsFromParent(returned_to_child
);
2011 // The child remembers the texture filter is set to |child_filter|.
2012 EXPECT_CALL(*child_context
, bindTexture(GL_TEXTURE_2D
, child_texture_id
));
2013 SetResourceFilter(child_resource_provider
.get(), id
, child_filter
);
2014 Mock::VerifyAndClearExpectations(child_context
);
2018 TEST_P(ResourceProviderTest
, TextureFilters_ChildNearestParentLinear
) {
2019 if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE
)
2021 ResourceProviderTestTextureFilters::RunTest(GL_NEAREST
, GL_LINEAR
);
2024 TEST_P(ResourceProviderTest
, TextureFilters_ChildLinearParentNearest
) {
2025 if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE
)
2027 ResourceProviderTestTextureFilters::RunTest(GL_LINEAR
, GL_NEAREST
);
2030 TEST_P(ResourceProviderTest
, TransferMailboxResources
) {
2031 // Other mailbox transfers tested elsewhere.
2032 if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE
)
2034 unsigned texture
= context()->createTexture();
2035 context()->bindTexture(GL_TEXTURE_2D
, texture
);
2036 uint8_t data
[4] = { 1, 2, 3, 4 };
2037 context()->texImage2D(
2038 GL_TEXTURE_2D
, 0, GL_RGBA
, 1, 1, 0, GL_RGBA
, GL_UNSIGNED_BYTE
, &data
);
2039 gpu::Mailbox mailbox
;
2040 context()->genMailboxCHROMIUM(mailbox
.name
);
2041 context()->produceTextureDirectCHROMIUM(texture
, GL_TEXTURE_2D
, mailbox
.name
);
2042 uint32 sync_point
= context()->insertSyncPoint();
2044 // All the logic below assumes that the sync points are all positive.
2045 EXPECT_LT(0u, sync_point
);
2047 uint32 release_sync_point
= 0;
2048 bool lost_resource
= false;
2049 BlockingTaskRunner
* main_thread_task_runner
= NULL
;
2050 ReleaseCallbackImpl callback
= base::Bind(ReleaseCallback
,
2051 &release_sync_point
,
2053 &main_thread_task_runner
);
2054 ResourceId resource
= resource_provider_
->CreateResourceFromTextureMailbox(
2055 TextureMailbox(mailbox
, GL_TEXTURE_2D
, sync_point
),
2056 SingleReleaseCallbackImpl::Create(callback
));
2057 EXPECT_EQ(1u, context()->NumTextures());
2058 EXPECT_EQ(0u, release_sync_point
);
2060 // Transfer the resource, expect the sync points to be consistent.
2061 ResourceProvider::ResourceIdArray resource_ids_to_transfer
;
2062 resource_ids_to_transfer
.push_back(resource
);
2063 TransferableResourceArray list
;
2064 resource_provider_
->PrepareSendToParent(resource_ids_to_transfer
, &list
);
2065 ASSERT_EQ(1u, list
.size());
2066 EXPECT_LE(sync_point
, list
[0].mailbox_holder
.sync_point
);
2068 memcmp(mailbox
.name
,
2069 list
[0].mailbox_holder
.mailbox
.name
,
2070 sizeof(mailbox
.name
)));
2071 EXPECT_EQ(0u, release_sync_point
);
2073 context()->waitSyncPoint(list
[0].mailbox_holder
.sync_point
);
2074 unsigned other_texture
=
2075 context()->createAndConsumeTextureCHROMIUM(GL_TEXTURE_2D
, mailbox
.name
);
2076 uint8_t test_data
[4] = { 0 };
2077 context()->GetPixels(
2078 gfx::Size(1, 1), RGBA_8888
, test_data
);
2079 EXPECT_EQ(0, memcmp(data
, test_data
, sizeof(data
)));
2081 context()->produceTextureDirectCHROMIUM(other_texture
, GL_TEXTURE_2D
,
2083 context()->deleteTexture(other_texture
);
2084 list
[0].mailbox_holder
.sync_point
= context()->insertSyncPoint();
2085 EXPECT_LT(0u, list
[0].mailbox_holder
.sync_point
);
2087 // Receive the resource, then delete it, expect the sync points to be
2089 ReturnedResourceArray returned
;
2090 TransferableResource::ReturnResources(list
, &returned
);
2091 resource_provider_
->ReceiveReturnsFromParent(returned
);
2092 EXPECT_EQ(1u, context()->NumTextures());
2093 EXPECT_EQ(0u, release_sync_point
);
2095 resource_provider_
->DeleteResource(resource
);
2096 EXPECT_LE(list
[0].mailbox_holder
.sync_point
, release_sync_point
);
2097 EXPECT_FALSE(lost_resource
);
2098 EXPECT_EQ(main_thread_task_runner_
.get(), main_thread_task_runner
);
2101 // We're going to do the same thing as above, but testing the case where we
2102 // delete the resource before we receive it back.
2103 sync_point
= release_sync_point
;
2104 EXPECT_LT(0u, sync_point
);
2105 release_sync_point
= 0;
2106 resource
= resource_provider_
->CreateResourceFromTextureMailbox(
2107 TextureMailbox(mailbox
, GL_TEXTURE_2D
, sync_point
),
2108 SingleReleaseCallbackImpl::Create(callback
));
2109 EXPECT_EQ(1u, context()->NumTextures());
2110 EXPECT_EQ(0u, release_sync_point
);
2112 // Transfer the resource, expect the sync points to be consistent.
2113 ResourceProvider::ResourceIdArray resource_ids_to_transfer
;
2114 resource_ids_to_transfer
.push_back(resource
);
2115 TransferableResourceArray list
;
2116 resource_provider_
->PrepareSendToParent(resource_ids_to_transfer
, &list
);
2117 ASSERT_EQ(1u, list
.size());
2118 EXPECT_LE(sync_point
, list
[0].mailbox_holder
.sync_point
);
2120 memcmp(mailbox
.name
,
2121 list
[0].mailbox_holder
.mailbox
.name
,
2122 sizeof(mailbox
.name
)));
2123 EXPECT_EQ(0u, release_sync_point
);
2125 context()->waitSyncPoint(list
[0].mailbox_holder
.sync_point
);
2126 unsigned other_texture
=
2127 context()->createAndConsumeTextureCHROMIUM(GL_TEXTURE_2D
, mailbox
.name
);
2128 uint8_t test_data
[4] = { 0 };
2129 context()->GetPixels(
2130 gfx::Size(1, 1), RGBA_8888
, test_data
);
2131 EXPECT_EQ(0, memcmp(data
, test_data
, sizeof(data
)));
2133 context()->produceTextureDirectCHROMIUM(other_texture
, GL_TEXTURE_2D
,
2135 context()->deleteTexture(other_texture
);
2136 list
[0].mailbox_holder
.sync_point
= context()->insertSyncPoint();
2137 EXPECT_LT(0u, list
[0].mailbox_holder
.sync_point
);
2139 // Delete the resource, which shouldn't do anything.
2140 resource_provider_
->DeleteResource(resource
);
2141 EXPECT_EQ(1u, context()->NumTextures());
2142 EXPECT_EQ(0u, release_sync_point
);
2144 // Then receive the resource which should release the mailbox, expect the
2145 // sync points to be consistent.
2146 ReturnedResourceArray returned
;
2147 TransferableResource::ReturnResources(list
, &returned
);
2148 resource_provider_
->ReceiveReturnsFromParent(returned
);
2149 EXPECT_LE(list
[0].mailbox_holder
.sync_point
, release_sync_point
);
2150 EXPECT_FALSE(lost_resource
);
2151 EXPECT_EQ(main_thread_task_runner_
.get(), main_thread_task_runner
);
2154 context()->waitSyncPoint(release_sync_point
);
2156 context()->createAndConsumeTextureCHROMIUM(GL_TEXTURE_2D
, mailbox
.name
);
2157 context()->deleteTexture(texture
);
2160 TEST_P(ResourceProviderTest
, LostResourceInParent
) {
2161 gfx::Size
size(1, 1);
2162 ResourceFormat format
= RGBA_8888
;
2163 ResourceId resource
= child_resource_provider_
->CreateResource(
2164 size
, GL_CLAMP_TO_EDGE
, ResourceProvider::TEXTURE_HINT_IMMUTABLE
, format
);
2165 child_resource_provider_
->AllocateForTesting(resource
);
2166 // Expect a GL resource to be lost.
2167 bool should_lose_resource
=
2168 GetParam() == ResourceProvider::RESOURCE_TYPE_GL_TEXTURE
;
2170 ReturnedResourceArray returned_to_child
;
2172 resource_provider_
->CreateChild(GetReturnCallback(&returned_to_child
));
2174 // Transfer the resource to the parent.
2175 ResourceProvider::ResourceIdArray resource_ids_to_transfer
;
2176 resource_ids_to_transfer
.push_back(resource
);
2177 TransferableResourceArray list
;
2178 child_resource_provider_
->PrepareSendToParent(resource_ids_to_transfer
,
2180 EXPECT_EQ(1u, list
.size());
2182 resource_provider_
->ReceiveFromChild(child_id
, list
);
2183 ResourceProvider::ResourceIdSet resource_ids_to_receive
;
2184 resource_ids_to_receive
.insert(resource
);
2185 resource_provider_
->DeclareUsedResourcesFromChild(child_id
,
2186 resource_ids_to_receive
);
2189 // Lose the output surface in the parent.
2190 resource_provider_
->DidLoseOutputSurface();
2193 EXPECT_EQ(0u, returned_to_child
.size());
2195 // Transfer resources back from the parent to the child. Set no resources as
2197 ResourceProvider::ResourceIdSet no_resources
;
2198 resource_provider_
->DeclareUsedResourcesFromChild(child_id
, no_resources
);
2200 // Expect a GL resource to be lost.
2201 ASSERT_EQ(1u, returned_to_child
.size());
2202 EXPECT_EQ(should_lose_resource
, returned_to_child
[0].lost
);
2203 child_resource_provider_
->ReceiveReturnsFromParent(returned_to_child
);
2204 returned_to_child
.clear();
2207 // A GL resource should be lost.
2208 EXPECT_EQ(should_lose_resource
, child_resource_provider_
->IsLost(resource
));
2210 // Lost resources stay in use in the parent forever.
2211 EXPECT_EQ(should_lose_resource
,
2212 child_resource_provider_
->InUseByConsumer(resource
));
2215 TEST_P(ResourceProviderTest
, LostResourceInGrandParent
) {
2216 gfx::Size
size(1, 1);
2217 ResourceFormat format
= RGBA_8888
;
2218 ResourceId resource
= child_resource_provider_
->CreateResource(
2219 size
, GL_CLAMP_TO_EDGE
, ResourceProvider::TEXTURE_HINT_IMMUTABLE
, format
);
2220 child_resource_provider_
->AllocateForTesting(resource
);
2222 ReturnedResourceArray returned_to_child
;
2224 resource_provider_
->CreateChild(GetReturnCallback(&returned_to_child
));
2226 // Transfer the resource to the parent.
2227 ResourceProvider::ResourceIdArray resource_ids_to_transfer
;
2228 resource_ids_to_transfer
.push_back(resource
);
2229 TransferableResourceArray list
;
2230 child_resource_provider_
->PrepareSendToParent(resource_ids_to_transfer
,
2232 EXPECT_EQ(1u, list
.size());
2234 resource_provider_
->ReceiveFromChild(child_id
, list
);
2235 ResourceProvider::ResourceIdSet resource_ids_to_receive
;
2236 resource_ids_to_receive
.insert(resource
);
2237 resource_provider_
->DeclareUsedResourcesFromChild(child_id
,
2238 resource_ids_to_receive
);
2242 ResourceProvider::ResourceIdMap resource_map
=
2243 resource_provider_
->GetChildToParentMap(child_id
);
2244 ResourceId parent_resource
= resource_map
[resource
];
2245 EXPECT_NE(0u, parent_resource
);
2247 // Transfer to a grandparent.
2248 ResourceProvider::ResourceIdArray resource_ids_to_transfer
;
2249 resource_ids_to_transfer
.push_back(parent_resource
);
2250 TransferableResourceArray list
;
2251 resource_provider_
->PrepareSendToParent(resource_ids_to_transfer
, &list
);
2253 // Receive back a lost resource from the grandparent.
2254 EXPECT_EQ(1u, list
.size());
2255 EXPECT_EQ(parent_resource
, list
[0].id
);
2256 ReturnedResourceArray returned
;
2257 TransferableResource::ReturnResources(list
, &returned
);
2258 EXPECT_EQ(1u, returned
.size());
2259 EXPECT_EQ(parent_resource
, returned
[0].id
);
2260 returned
[0].lost
= true;
2261 resource_provider_
->ReceiveReturnsFromParent(returned
);
2263 // The resource should be lost.
2264 EXPECT_TRUE(resource_provider_
->IsLost(parent_resource
));
2266 // Lost resources stay in use in the parent forever.
2267 EXPECT_TRUE(resource_provider_
->InUseByConsumer(parent_resource
));
2271 EXPECT_EQ(0u, returned_to_child
.size());
2273 // Transfer resources back from the parent to the child. Set no resources as
2275 ResourceProvider::ResourceIdSet no_resources
;
2276 resource_provider_
->DeclareUsedResourcesFromChild(child_id
, no_resources
);
2278 // Expect the resource to be lost.
2279 ASSERT_EQ(1u, returned_to_child
.size());
2280 EXPECT_TRUE(returned_to_child
[0].lost
);
2281 child_resource_provider_
->ReceiveReturnsFromParent(returned_to_child
);
2282 returned_to_child
.clear();
2285 // The resource should be lost.
2286 EXPECT_TRUE(child_resource_provider_
->IsLost(resource
));
2288 // Lost resources stay in use in the parent forever.
2289 EXPECT_TRUE(child_resource_provider_
->InUseByConsumer(resource
));
2292 TEST_P(ResourceProviderTest
, LostMailboxInParent
) {
2293 uint32 release_sync_point
= 0;
2294 bool lost_resource
= false;
2295 bool release_called
= false;
2296 uint32 sync_point
= 0;
2297 ResourceId resource
= CreateChildMailbox(&release_sync_point
, &lost_resource
,
2298 &release_called
, &sync_point
);
2300 ReturnedResourceArray returned_to_child
;
2302 resource_provider_
->CreateChild(GetReturnCallback(&returned_to_child
));
2304 // Transfer the resource to the parent.
2305 ResourceProvider::ResourceIdArray resource_ids_to_transfer
;
2306 resource_ids_to_transfer
.push_back(resource
);
2307 TransferableResourceArray list
;
2308 child_resource_provider_
->PrepareSendToParent(resource_ids_to_transfer
,
2310 EXPECT_EQ(1u, list
.size());
2312 resource_provider_
->ReceiveFromChild(child_id
, list
);
2313 ResourceProvider::ResourceIdSet resource_ids_to_receive
;
2314 resource_ids_to_receive
.insert(resource
);
2315 resource_provider_
->DeclareUsedResourcesFromChild(child_id
,
2316 resource_ids_to_receive
);
2319 // Lose the output surface in the parent.
2320 resource_provider_
->DidLoseOutputSurface();
2323 EXPECT_EQ(0u, returned_to_child
.size());
2325 // Transfer resources back from the parent to the child. Set no resources as
2327 ResourceProvider::ResourceIdSet no_resources
;
2328 resource_provider_
->DeclareUsedResourcesFromChild(child_id
, no_resources
);
2330 ASSERT_EQ(1u, returned_to_child
.size());
2331 // Losing an output surface only loses hardware resources.
2332 EXPECT_EQ(returned_to_child
[0].lost
,
2333 GetParam() == ResourceProvider::RESOURCE_TYPE_GL_TEXTURE
);
2334 child_resource_provider_
->ReceiveReturnsFromParent(returned_to_child
);
2335 returned_to_child
.clear();
2338 // Delete the resource in the child. Expect the resource to be lost if it's
2340 child_resource_provider_
->DeleteResource(resource
);
2341 EXPECT_EQ(lost_resource
,
2342 GetParam() == ResourceProvider::RESOURCE_TYPE_GL_TEXTURE
);
2345 TEST_P(ResourceProviderTest
, LostMailboxInGrandParent
) {
2346 uint32 release_sync_point
= 0;
2347 bool lost_resource
= false;
2348 bool release_called
= false;
2349 uint32 sync_point
= 0;
2350 ResourceId resource
= CreateChildMailbox(&release_sync_point
, &lost_resource
,
2351 &release_called
, &sync_point
);
2353 ReturnedResourceArray returned_to_child
;
2355 resource_provider_
->CreateChild(GetReturnCallback(&returned_to_child
));
2357 // Transfer the resource to the parent.
2358 ResourceProvider::ResourceIdArray resource_ids_to_transfer
;
2359 resource_ids_to_transfer
.push_back(resource
);
2360 TransferableResourceArray list
;
2361 child_resource_provider_
->PrepareSendToParent(resource_ids_to_transfer
,
2363 EXPECT_EQ(1u, list
.size());
2365 resource_provider_
->ReceiveFromChild(child_id
, list
);
2366 ResourceProvider::ResourceIdSet resource_ids_to_receive
;
2367 resource_ids_to_receive
.insert(resource
);
2368 resource_provider_
->DeclareUsedResourcesFromChild(child_id
,
2369 resource_ids_to_receive
);
2373 ResourceProvider::ResourceIdMap resource_map
=
2374 resource_provider_
->GetChildToParentMap(child_id
);
2375 ResourceId parent_resource
= resource_map
[resource
];
2376 EXPECT_NE(0u, parent_resource
);
2378 // Transfer to a grandparent.
2379 ResourceProvider::ResourceIdArray resource_ids_to_transfer
;
2380 resource_ids_to_transfer
.push_back(parent_resource
);
2381 TransferableResourceArray list
;
2382 resource_provider_
->PrepareSendToParent(resource_ids_to_transfer
, &list
);
2384 // Receive back a lost resource from the grandparent.
2385 EXPECT_EQ(1u, list
.size());
2386 EXPECT_EQ(parent_resource
, list
[0].id
);
2387 ReturnedResourceArray returned
;
2388 TransferableResource::ReturnResources(list
, &returned
);
2389 EXPECT_EQ(1u, returned
.size());
2390 EXPECT_EQ(parent_resource
, returned
[0].id
);
2391 returned
[0].lost
= true;
2392 resource_provider_
->ReceiveReturnsFromParent(returned
);
2396 EXPECT_EQ(0u, returned_to_child
.size());
2398 // Transfer resources back from the parent to the child. Set no resources as
2400 ResourceProvider::ResourceIdSet no_resources
;
2401 resource_provider_
->DeclareUsedResourcesFromChild(child_id
, no_resources
);
2403 // Expect the resource to be lost.
2404 ASSERT_EQ(1u, returned_to_child
.size());
2405 EXPECT_TRUE(returned_to_child
[0].lost
);
2406 child_resource_provider_
->ReceiveReturnsFromParent(returned_to_child
);
2407 returned_to_child
.clear();
2410 // Delete the resource in the child. Expect the resource to be lost.
2411 child_resource_provider_
->DeleteResource(resource
);
2412 EXPECT_TRUE(lost_resource
);
2415 TEST_P(ResourceProviderTest
, Shutdown
) {
2416 uint32 release_sync_point
= 0;
2417 bool lost_resource
= false;
2418 bool release_called
= false;
2419 uint32 sync_point
= 0;
2421 &release_sync_point
, &lost_resource
, &release_called
, &sync_point
);
2423 EXPECT_EQ(0u, release_sync_point
);
2424 EXPECT_FALSE(lost_resource
);
2426 child_resource_provider_
= nullptr;
2428 if (GetParam() == ResourceProvider::RESOURCE_TYPE_GL_TEXTURE
) {
2429 EXPECT_LE(sync_point
, release_sync_point
);
2431 EXPECT_TRUE(release_called
);
2432 EXPECT_FALSE(lost_resource
);
2435 TEST_P(ResourceProviderTest
, ShutdownWithExportedResource
) {
2436 uint32 release_sync_point
= 0;
2437 bool lost_resource
= false;
2438 bool release_called
= false;
2439 uint32 sync_point
= 0;
2440 ResourceId resource
= CreateChildMailbox(&release_sync_point
, &lost_resource
,
2441 &release_called
, &sync_point
);
2443 // Transfer the resource, so we can't release it properly on shutdown.
2444 ResourceProvider::ResourceIdArray resource_ids_to_transfer
;
2445 resource_ids_to_transfer
.push_back(resource
);
2446 TransferableResourceArray list
;
2447 child_resource_provider_
->PrepareSendToParent(resource_ids_to_transfer
,
2450 EXPECT_EQ(0u, release_sync_point
);
2451 EXPECT_FALSE(lost_resource
);
2453 child_resource_provider_
= nullptr;
2455 // Since the resource is in the parent, the child considers it lost.
2456 EXPECT_EQ(0u, release_sync_point
);
2457 EXPECT_TRUE(lost_resource
);
2460 TEST_P(ResourceProviderTest
, LostContext
) {
2461 // TextureMailbox callbacks only exist for GL textures for now.
2462 if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE
)
2464 unsigned texture
= context()->createTexture();
2465 context()->bindTexture(GL_TEXTURE_2D
, texture
);
2466 gpu::Mailbox mailbox
;
2467 context()->genMailboxCHROMIUM(mailbox
.name
);
2468 context()->produceTextureDirectCHROMIUM(texture
, GL_TEXTURE_2D
, mailbox
.name
);
2469 uint32 sync_point
= context()->insertSyncPoint();
2471 EXPECT_LT(0u, sync_point
);
2473 uint32 release_sync_point
= 0;
2474 bool lost_resource
= false;
2475 BlockingTaskRunner
* main_thread_task_runner
= NULL
;
2476 scoped_ptr
<SingleReleaseCallbackImpl
> callback
=
2477 SingleReleaseCallbackImpl::Create(base::Bind(ReleaseCallback
,
2478 &release_sync_point
,
2480 &main_thread_task_runner
));
2481 resource_provider_
->CreateResourceFromTextureMailbox(
2482 TextureMailbox(mailbox
, GL_TEXTURE_2D
, sync_point
), callback
.Pass());
2484 EXPECT_EQ(0u, release_sync_point
);
2485 EXPECT_FALSE(lost_resource
);
2486 EXPECT_EQ(NULL
, main_thread_task_runner
);
2488 resource_provider_
->DidLoseOutputSurface();
2489 resource_provider_
= nullptr;
2491 EXPECT_LE(sync_point
, release_sync_point
);
2492 EXPECT_TRUE(lost_resource
);
2493 EXPECT_EQ(main_thread_task_runner_
.get(), main_thread_task_runner
);
2496 TEST_P(ResourceProviderTest
, ScopedSampler
) {
2497 // Sampling is only supported for GL textures.
2498 if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE
)
2501 scoped_ptr
<TextureStateTrackingContext
> context_owned(
2502 new TextureStateTrackingContext
);
2503 TextureStateTrackingContext
* context
= context_owned
.get();
2505 FakeOutputSurfaceClient output_surface_client
;
2506 scoped_ptr
<OutputSurface
> output_surface(
2507 FakeOutputSurface::Create3d(context_owned
.Pass()));
2508 CHECK(output_surface
->BindToClient(&output_surface_client
));
2510 scoped_ptr
<ResourceProvider
> resource_provider(ResourceProvider::Create(
2511 output_surface
.get(), shared_bitmap_manager_
.get(),
2512 gpu_memory_buffer_manager_
.get(), NULL
, 0, false, 1,
2513 use_image_texture_targets_
));
2515 gfx::Size
size(1, 1);
2516 ResourceFormat format
= RGBA_8888
;
2519 ResourceId id
= resource_provider
->CreateResource(
2520 size
, GL_CLAMP_TO_EDGE
, ResourceProvider::TEXTURE_HINT_IMMUTABLE
, format
);
2522 // Check that the texture gets created with the right sampler settings.
2523 EXPECT_CALL(*context
, bindTexture(GL_TEXTURE_2D
, texture_id
))
2524 .Times(2); // Once to create and once to allocate.
2525 EXPECT_CALL(*context
,
2526 texParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_LINEAR
));
2527 EXPECT_CALL(*context
,
2528 texParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_LINEAR
));
2531 texParameteri(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_S
, GL_CLAMP_TO_EDGE
));
2534 texParameteri(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_T
, GL_CLAMP_TO_EDGE
));
2535 EXPECT_CALL(*context
,
2536 texParameteri(GL_TEXTURE_2D
,
2537 GL_TEXTURE_POOL_CHROMIUM
,
2538 GL_TEXTURE_POOL_UNMANAGED_CHROMIUM
));
2540 resource_provider
->AllocateForTesting(id
);
2541 Mock::VerifyAndClearExpectations(context
);
2543 // Creating a sampler with the default filter should not change any texture
2546 EXPECT_CALL(*context
, bindTexture(GL_TEXTURE_2D
, texture_id
));
2547 ResourceProvider::ScopedSamplerGL
sampler(
2548 resource_provider
.get(), id
, GL_TEXTURE_2D
, GL_LINEAR
);
2549 Mock::VerifyAndClearExpectations(context
);
2552 // Using a different filter should be reflected in the texture parameters.
2554 EXPECT_CALL(*context
, bindTexture(GL_TEXTURE_2D
, texture_id
));
2557 texParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_NEAREST
));
2560 texParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_NEAREST
));
2561 ResourceProvider::ScopedSamplerGL
sampler(
2562 resource_provider
.get(), id
, GL_TEXTURE_2D
, GL_NEAREST
);
2563 Mock::VerifyAndClearExpectations(context
);
2566 // Test resetting to the default filter.
2568 EXPECT_CALL(*context
, bindTexture(GL_TEXTURE_2D
, texture_id
));
2569 EXPECT_CALL(*context
,
2570 texParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_LINEAR
));
2571 EXPECT_CALL(*context
,
2572 texParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_LINEAR
));
2573 ResourceProvider::ScopedSamplerGL
sampler(
2574 resource_provider
.get(), id
, GL_TEXTURE_2D
, GL_LINEAR
);
2575 Mock::VerifyAndClearExpectations(context
);
2579 TEST_P(ResourceProviderTest
, ManagedResource
) {
2580 // Sampling is only supported for GL textures.
2581 if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE
)
2584 scoped_ptr
<TextureStateTrackingContext
> context_owned(
2585 new TextureStateTrackingContext
);
2586 TextureStateTrackingContext
* context
= context_owned
.get();
2588 FakeOutputSurfaceClient output_surface_client
;
2589 scoped_ptr
<OutputSurface
> output_surface(
2590 FakeOutputSurface::Create3d(context_owned
.Pass()));
2591 CHECK(output_surface
->BindToClient(&output_surface_client
));
2593 scoped_ptr
<ResourceProvider
> resource_provider(ResourceProvider::Create(
2594 output_surface
.get(), shared_bitmap_manager_
.get(),
2595 gpu_memory_buffer_manager_
.get(), NULL
, 0, false, 1,
2596 use_image_texture_targets_
));
2598 gfx::Size
size(1, 1);
2599 ResourceFormat format
= RGBA_8888
;
2602 // Check that the texture gets created with the right sampler settings.
2603 ResourceId id
= resource_provider
->CreateManagedResource(
2604 size
, GL_TEXTURE_2D
, GL_CLAMP_TO_EDGE
,
2605 ResourceProvider::TEXTURE_HINT_IMMUTABLE
, format
);
2606 EXPECT_CALL(*context
, bindTexture(GL_TEXTURE_2D
, texture_id
));
2607 EXPECT_CALL(*context
,
2608 texParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_LINEAR
));
2609 EXPECT_CALL(*context
,
2610 texParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_LINEAR
));
2613 texParameteri(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_S
, GL_CLAMP_TO_EDGE
));
2616 texParameteri(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_T
, GL_CLAMP_TO_EDGE
));
2617 EXPECT_CALL(*context
,
2618 texParameteri(GL_TEXTURE_2D
,
2619 GL_TEXTURE_POOL_CHROMIUM
,
2620 GL_TEXTURE_POOL_MANAGED_CHROMIUM
));
2621 resource_provider
->CreateForTesting(id
);
2624 Mock::VerifyAndClearExpectations(context
);
2627 TEST_P(ResourceProviderTest
, TextureWrapMode
) {
2628 // Sampling is only supported for GL textures.
2629 if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE
)
2632 scoped_ptr
<TextureStateTrackingContext
> context_owned(
2633 new TextureStateTrackingContext
);
2634 TextureStateTrackingContext
* context
= context_owned
.get();
2636 FakeOutputSurfaceClient output_surface_client
;
2637 scoped_ptr
<OutputSurface
> output_surface(
2638 FakeOutputSurface::Create3d(context_owned
.Pass()));
2639 CHECK(output_surface
->BindToClient(&output_surface_client
));
2641 scoped_ptr
<ResourceProvider
> resource_provider(ResourceProvider::Create(
2642 output_surface
.get(), shared_bitmap_manager_
.get(),
2643 gpu_memory_buffer_manager_
.get(), NULL
, 0, false, 1,
2644 use_image_texture_targets_
));
2646 gfx::Size
size(1, 1);
2647 ResourceFormat format
= RGBA_8888
;
2648 GLenum texture_pool
= GL_TEXTURE_POOL_UNMANAGED_CHROMIUM
;
2650 for (int texture_id
= 1; texture_id
<= 2; ++texture_id
) {
2651 GLint wrap_mode
= texture_id
== 1 ? GL_CLAMP_TO_EDGE
: GL_REPEAT
;
2652 // Check that the texture gets created with the right sampler settings.
2653 ResourceId id
= resource_provider
->CreateGLTexture(
2654 size
, GL_TEXTURE_2D
, texture_pool
, wrap_mode
,
2655 ResourceProvider::TEXTURE_HINT_IMMUTABLE
, format
);
2656 EXPECT_CALL(*context
, bindTexture(GL_TEXTURE_2D
, texture_id
));
2657 EXPECT_CALL(*context
,
2658 texParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_LINEAR
));
2659 EXPECT_CALL(*context
,
2660 texParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_LINEAR
));
2661 EXPECT_CALL(*context
,
2662 texParameteri(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_S
, wrap_mode
));
2663 EXPECT_CALL(*context
,
2664 texParameteri(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_T
, wrap_mode
));
2665 EXPECT_CALL(*context
,
2666 texParameteri(GL_TEXTURE_2D
,
2667 GL_TEXTURE_POOL_CHROMIUM
,
2668 GL_TEXTURE_POOL_UNMANAGED_CHROMIUM
));
2669 resource_provider
->CreateForTesting(id
);
2672 Mock::VerifyAndClearExpectations(context
);
2676 TEST_P(ResourceProviderTest
, TextureHint
) {
2677 // Sampling is only supported for GL textures.
2678 if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE
)
2681 scoped_ptr
<TextureStateTrackingContext
> context_owned(
2682 new TextureStateTrackingContext
);
2683 TextureStateTrackingContext
* context
= context_owned
.get();
2684 context
->set_support_texture_storage(true);
2685 context
->set_support_texture_usage(true);
2687 FakeOutputSurfaceClient output_surface_client
;
2688 scoped_ptr
<OutputSurface
> output_surface(
2689 FakeOutputSurface::Create3d(context_owned
.Pass()));
2690 CHECK(output_surface
->BindToClient(&output_surface_client
));
2692 scoped_ptr
<ResourceProvider
> resource_provider(ResourceProvider::Create(
2693 output_surface
.get(), shared_bitmap_manager_
.get(),
2694 gpu_memory_buffer_manager_
.get(), NULL
, 0, false, 1,
2695 use_image_texture_targets_
));
2697 gfx::Size
size(1, 1);
2698 ResourceFormat format
= RGBA_8888
;
2699 GLenum texture_pool
= GL_TEXTURE_POOL_UNMANAGED_CHROMIUM
;
2701 const ResourceProvider::TextureHint hints
[4] = {
2702 ResourceProvider::TEXTURE_HINT_DEFAULT
,
2703 ResourceProvider::TEXTURE_HINT_IMMUTABLE
,
2704 ResourceProvider::TEXTURE_HINT_FRAMEBUFFER
,
2705 ResourceProvider::TEXTURE_HINT_IMMUTABLE_FRAMEBUFFER
,
2707 for (GLuint texture_id
= 1; texture_id
<= arraysize(hints
); ++texture_id
) {
2708 // Check that the texture gets created with the right sampler settings.
2709 ResourceId id
= resource_provider
->CreateGLTexture(
2710 size
, GL_TEXTURE_2D
, texture_pool
, GL_CLAMP_TO_EDGE
,
2711 hints
[texture_id
- 1], format
);
2712 EXPECT_CALL(*context
, bindTexture(GL_TEXTURE_2D
, texture_id
));
2713 EXPECT_CALL(*context
,
2714 texParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_LINEAR
));
2715 EXPECT_CALL(*context
,
2716 texParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_LINEAR
));
2719 texParameteri(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_S
, GL_CLAMP_TO_EDGE
));
2722 texParameteri(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_T
, GL_CLAMP_TO_EDGE
));
2723 EXPECT_CALL(*context
,
2724 texParameteri(GL_TEXTURE_2D
,
2725 GL_TEXTURE_POOL_CHROMIUM
,
2726 GL_TEXTURE_POOL_UNMANAGED_CHROMIUM
));
2727 // Check only TEXTURE_HINT_FRAMEBUFFER set GL_TEXTURE_USAGE_ANGLE.
2728 bool is_framebuffer_hint
=
2729 hints
[texture_id
- 1] & ResourceProvider::TEXTURE_HINT_FRAMEBUFFER
;
2730 EXPECT_CALL(*context
,
2731 texParameteri(GL_TEXTURE_2D
,
2732 GL_TEXTURE_USAGE_ANGLE
,
2733 GL_FRAMEBUFFER_ATTACHMENT_ANGLE
))
2734 .Times(is_framebuffer_hint
? 1 : 0);
2735 resource_provider
->CreateForTesting(id
);
2738 Mock::VerifyAndClearExpectations(context
);
2742 TEST_P(ResourceProviderTest
, TextureMailbox_SharedMemory
) {
2743 if (GetParam() != ResourceProvider::RESOURCE_TYPE_BITMAP
)
2746 gfx::Size
size(64, 64);
2747 const uint32_t kBadBeef
= 0xbadbeef;
2748 scoped_ptr
<SharedBitmap
> shared_bitmap(
2749 CreateAndFillSharedBitmap(shared_bitmap_manager_
.get(), size
, kBadBeef
));
2751 FakeOutputSurfaceClient output_surface_client
;
2752 scoped_ptr
<OutputSurface
> output_surface(
2753 FakeOutputSurface::CreateSoftware(make_scoped_ptr(
2754 new SoftwareOutputDevice
)));
2755 CHECK(output_surface
->BindToClient(&output_surface_client
));
2757 scoped_ptr
<ResourceProvider
> resource_provider(ResourceProvider::Create(
2758 output_surface
.get(), shared_bitmap_manager_
.get(),
2759 gpu_memory_buffer_manager_
.get(), main_thread_task_runner_
.get(), 0,
2760 false, 1, use_image_texture_targets_
));
2762 uint32 release_sync_point
= 0;
2763 bool lost_resource
= false;
2764 BlockingTaskRunner
* main_thread_task_runner
= NULL
;
2765 scoped_ptr
<SingleReleaseCallbackImpl
> callback
=
2766 SingleReleaseCallbackImpl::Create(base::Bind(&ReleaseCallback
,
2767 &release_sync_point
,
2769 &main_thread_task_runner
));
2770 TextureMailbox
mailbox(shared_bitmap
.get(), size
);
2772 ResourceId id
= resource_provider
->CreateResourceFromTextureMailbox(
2773 mailbox
, callback
.Pass());
2777 ResourceProvider::ScopedReadLockSoftware
lock(resource_provider
.get(), id
);
2778 const SkBitmap
* sk_bitmap
= lock
.sk_bitmap();
2779 EXPECT_EQ(sk_bitmap
->width(), size
.width());
2780 EXPECT_EQ(sk_bitmap
->height(), size
.height());
2781 EXPECT_EQ(*sk_bitmap
->getAddr32(16, 16), kBadBeef
);
2784 resource_provider
->DeleteResource(id
);
2785 EXPECT_EQ(0u, release_sync_point
);
2786 EXPECT_FALSE(lost_resource
);
2787 EXPECT_EQ(main_thread_task_runner_
.get(), main_thread_task_runner
);
2790 class ResourceProviderTestTextureMailboxGLFilters
2791 : public ResourceProviderTest
{
2793 static void RunTest(TestSharedBitmapManager
* shared_bitmap_manager
,
2794 TestGpuMemoryBufferManager
* gpu_memory_buffer_manager
,
2795 BlockingTaskRunner
* main_thread_task_runner
,
2796 bool mailbox_nearest_neighbor
,
2797 GLenum sampler_filter
) {
2798 scoped_ptr
<TextureStateTrackingContext
> context_owned(
2799 new TextureStateTrackingContext
);
2800 TextureStateTrackingContext
* context
= context_owned
.get();
2802 FakeOutputSurfaceClient output_surface_client
;
2803 scoped_ptr
<OutputSurface
> output_surface(
2804 FakeOutputSurface::Create3d(context_owned
.Pass()));
2805 CHECK(output_surface
->BindToClient(&output_surface_client
));
2807 scoped_ptr
<ResourceProvider
> resource_provider(ResourceProvider::Create(
2808 output_surface
.get(), shared_bitmap_manager
, gpu_memory_buffer_manager
,
2809 main_thread_task_runner
, 0, false, 1, use_image_texture_targets_
));
2811 unsigned texture_id
= 1;
2812 uint32 sync_point
= 30;
2813 unsigned target
= GL_TEXTURE_2D
;
2815 EXPECT_CALL(*context
, bindTexture(_
, _
)).Times(0);
2816 EXPECT_CALL(*context
, waitSyncPoint(_
)).Times(0);
2817 EXPECT_CALL(*context
, insertSyncPoint()).Times(0);
2818 EXPECT_CALL(*context
, produceTextureDirectCHROMIUM(_
, _
, _
)).Times(0);
2819 EXPECT_CALL(*context
, createAndConsumeTextureCHROMIUM(_
, _
)).Times(0);
2821 gpu::Mailbox gpu_mailbox
;
2822 memcpy(gpu_mailbox
.name
, "Hello world", strlen("Hello world") + 1);
2823 uint32 release_sync_point
= 0;
2824 bool lost_resource
= false;
2825 BlockingTaskRunner
* mailbox_task_runner
= NULL
;
2826 scoped_ptr
<SingleReleaseCallbackImpl
> callback
=
2827 SingleReleaseCallbackImpl::Create(base::Bind(&ReleaseCallback
,
2828 &release_sync_point
,
2830 &mailbox_task_runner
));
2832 TextureMailbox
mailbox(gpu_mailbox
, target
, sync_point
);
2833 mailbox
.set_nearest_neighbor(mailbox_nearest_neighbor
);
2835 ResourceId id
= resource_provider
->CreateResourceFromTextureMailbox(
2836 mailbox
, callback
.Pass());
2839 Mock::VerifyAndClearExpectations(context
);
2842 // Mailbox sync point WaitSyncPoint before using the texture.
2843 EXPECT_CALL(*context
, waitSyncPoint(sync_point
));
2844 resource_provider
->WaitSyncPointIfNeeded(id
);
2845 Mock::VerifyAndClearExpectations(context
);
2847 EXPECT_CALL(*context
, createAndConsumeTextureCHROMIUM(target
, _
))
2848 .WillOnce(Return(texture_id
));
2849 EXPECT_CALL(*context
, bindTexture(target
, texture_id
));
2851 EXPECT_CALL(*context
, insertSyncPoint()).Times(0);
2852 EXPECT_CALL(*context
, produceTextureDirectCHROMIUM(_
, _
, _
)).Times(0);
2854 // The sampler will reset these if |mailbox_nearest_neighbor| does not
2855 // match |sampler_filter|.
2856 if (mailbox_nearest_neighbor
!= (sampler_filter
== GL_NEAREST
)) {
2857 EXPECT_CALL(*context
, texParameteri(
2858 GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, sampler_filter
));
2859 EXPECT_CALL(*context
, texParameteri(
2860 GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, sampler_filter
));
2863 ResourceProvider::ScopedSamplerGL
lock(
2864 resource_provider
.get(), id
, sampler_filter
);
2865 Mock::VerifyAndClearExpectations(context
);
2867 // When done with it, a sync point should be inserted, but no produce is
2869 EXPECT_CALL(*context
, bindTexture(_
, _
)).Times(0);
2870 EXPECT_CALL(*context
, insertSyncPoint());
2871 EXPECT_CALL(*context
, produceTextureDirectCHROMIUM(_
, _
, _
)).Times(0);
2873 EXPECT_CALL(*context
, waitSyncPoint(_
)).Times(0);
2874 EXPECT_CALL(*context
, createAndConsumeTextureCHROMIUM(_
, _
)).Times(0);
2877 resource_provider
->DeleteResource(id
);
2878 EXPECT_EQ(0u, release_sync_point
);
2879 EXPECT_FALSE(lost_resource
);
2880 EXPECT_EQ(main_thread_task_runner
, mailbox_task_runner
);
2884 TEST_P(ResourceProviderTest
, TextureMailbox_GLTexture2D_LinearToLinear
) {
2885 // Mailboxing is only supported for GL textures.
2886 if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE
)
2889 ResourceProviderTestTextureMailboxGLFilters::RunTest(
2890 shared_bitmap_manager_
.get(),
2891 gpu_memory_buffer_manager_
.get(),
2892 main_thread_task_runner_
.get(),
2897 TEST_P(ResourceProviderTest
, TextureMailbox_GLTexture2D_NearestToNearest
) {
2898 // Mailboxing is only supported for GL textures.
2899 if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE
)
2902 ResourceProviderTestTextureMailboxGLFilters::RunTest(
2903 shared_bitmap_manager_
.get(),
2904 gpu_memory_buffer_manager_
.get(),
2905 main_thread_task_runner_
.get(),
2910 TEST_P(ResourceProviderTest
, TextureMailbox_GLTexture2D_NearestToLinear
) {
2911 // Mailboxing is only supported for GL textures.
2912 if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE
)
2915 ResourceProviderTestTextureMailboxGLFilters::RunTest(
2916 shared_bitmap_manager_
.get(),
2917 gpu_memory_buffer_manager_
.get(),
2918 main_thread_task_runner_
.get(),
2923 TEST_P(ResourceProviderTest
, TextureMailbox_GLTexture2D_LinearToNearest
) {
2924 // Mailboxing is only supported for GL textures.
2925 if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE
)
2928 ResourceProviderTestTextureMailboxGLFilters::RunTest(
2929 shared_bitmap_manager_
.get(),
2930 gpu_memory_buffer_manager_
.get(),
2931 main_thread_task_runner_
.get(),
2936 TEST_P(ResourceProviderTest
, TextureMailbox_GLTextureExternalOES
) {
2937 // Mailboxing is only supported for GL textures.
2938 if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE
)
2941 scoped_ptr
<TextureStateTrackingContext
> context_owned(
2942 new TextureStateTrackingContext
);
2943 TextureStateTrackingContext
* context
= context_owned
.get();
2945 FakeOutputSurfaceClient output_surface_client
;
2946 scoped_ptr
<OutputSurface
> output_surface(
2947 FakeOutputSurface::Create3d(context_owned
.Pass()));
2948 CHECK(output_surface
->BindToClient(&output_surface_client
));
2950 scoped_ptr
<ResourceProvider
> resource_provider(ResourceProvider::Create(
2951 output_surface
.get(), shared_bitmap_manager_
.get(),
2952 gpu_memory_buffer_manager_
.get(), NULL
, 0, false, 1,
2953 use_image_texture_targets_
));
2955 uint32 sync_point
= 30;
2956 unsigned target
= GL_TEXTURE_EXTERNAL_OES
;
2958 EXPECT_CALL(*context
, bindTexture(_
, _
)).Times(0);
2959 EXPECT_CALL(*context
, waitSyncPoint(_
)).Times(0);
2960 EXPECT_CALL(*context
, insertSyncPoint()).Times(0);
2961 EXPECT_CALL(*context
, produceTextureDirectCHROMIUM(_
, _
, _
)).Times(0);
2962 EXPECT_CALL(*context
, createAndConsumeTextureCHROMIUM(_
, _
)).Times(0);
2964 gpu::Mailbox gpu_mailbox
;
2965 memcpy(gpu_mailbox
.name
, "Hello world", strlen("Hello world") + 1);
2966 scoped_ptr
<SingleReleaseCallbackImpl
> callback
=
2967 SingleReleaseCallbackImpl::Create(base::Bind(&EmptyReleaseCallback
));
2969 TextureMailbox
mailbox(gpu_mailbox
, target
, sync_point
);
2971 ResourceId id
= resource_provider
->CreateResourceFromTextureMailbox(
2972 mailbox
, callback
.Pass());
2975 Mock::VerifyAndClearExpectations(context
);
2978 // Mailbox sync point WaitSyncPoint before using the texture.
2979 EXPECT_CALL(*context
, waitSyncPoint(sync_point
));
2980 resource_provider
->WaitSyncPointIfNeeded(id
);
2981 Mock::VerifyAndClearExpectations(context
);
2983 unsigned texture_id
= 1;
2985 EXPECT_CALL(*context
, createAndConsumeTextureCHROMIUM(target
, _
))
2986 .WillOnce(Return(texture_id
));
2988 EXPECT_CALL(*context
, insertSyncPoint()).Times(0);
2989 EXPECT_CALL(*context
, produceTextureDirectCHROMIUM(_
, _
, _
)).Times(0);
2991 ResourceProvider::ScopedReadLockGL
lock(resource_provider
.get(), id
);
2992 Mock::VerifyAndClearExpectations(context
);
2994 // When done with it, a sync point should be inserted, but no produce is
2996 EXPECT_CALL(*context
, bindTexture(_
, _
)).Times(0);
2997 EXPECT_CALL(*context
, insertSyncPoint());
2998 EXPECT_CALL(*context
, produceTextureDirectCHROMIUM(_
, _
, _
)).Times(0);
3000 EXPECT_CALL(*context
, waitSyncPoint(_
)).Times(0);
3001 EXPECT_CALL(*context
, createAndConsumeTextureCHROMIUM(_
, _
)).Times(0);
3005 TEST_P(ResourceProviderTest
,
3006 TextureMailbox_WaitSyncPointIfNeeded_WithSyncPoint
) {
3007 // Mailboxing is only supported for GL textures.
3008 if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE
)
3011 scoped_ptr
<TextureStateTrackingContext
> context_owned(
3012 new TextureStateTrackingContext
);
3013 TextureStateTrackingContext
* context
= context_owned
.get();
3015 FakeOutputSurfaceClient output_surface_client
;
3016 scoped_ptr
<OutputSurface
> output_surface(
3017 FakeOutputSurface::Create3d(context_owned
.Pass()));
3018 CHECK(output_surface
->BindToClient(&output_surface_client
));
3020 scoped_ptr
<ResourceProvider
> resource_provider(ResourceProvider::Create(
3021 output_surface
.get(), shared_bitmap_manager_
.get(),
3022 gpu_memory_buffer_manager_
.get(), NULL
, 0, false, 1,
3023 use_image_texture_targets_
));
3025 uint32 sync_point
= 30;
3026 unsigned target
= GL_TEXTURE_2D
;
3028 EXPECT_CALL(*context
, bindTexture(_
, _
)).Times(0);
3029 EXPECT_CALL(*context
, waitSyncPoint(_
)).Times(0);
3030 EXPECT_CALL(*context
, insertSyncPoint()).Times(0);
3031 EXPECT_CALL(*context
, produceTextureDirectCHROMIUM(_
, _
, _
)).Times(0);
3032 EXPECT_CALL(*context
, createAndConsumeTextureCHROMIUM(_
, _
)).Times(0);
3034 gpu::Mailbox gpu_mailbox
;
3035 memcpy(gpu_mailbox
.name
, "Hello world", strlen("Hello world") + 1);
3036 scoped_ptr
<SingleReleaseCallbackImpl
> callback
=
3037 SingleReleaseCallbackImpl::Create(base::Bind(&EmptyReleaseCallback
));
3039 TextureMailbox
mailbox(gpu_mailbox
, target
, sync_point
);
3041 ResourceId id
= resource_provider
->CreateResourceFromTextureMailbox(
3042 mailbox
, callback
.Pass());
3045 Mock::VerifyAndClearExpectations(context
);
3048 // First call to WaitSyncPointIfNeeded should call waitSyncPoint.
3049 EXPECT_CALL(*context
, waitSyncPoint(sync_point
));
3050 resource_provider
->WaitSyncPointIfNeeded(id
);
3051 Mock::VerifyAndClearExpectations(context
);
3053 // Subsequent calls to WaitSyncPointIfNeeded shouldn't call waitSyncPoint.
3054 EXPECT_CALL(*context
, waitSyncPoint(_
)).Times(0);
3055 resource_provider
->WaitSyncPointIfNeeded(id
);
3056 Mock::VerifyAndClearExpectations(context
);
3060 TEST_P(ResourceProviderTest
, TextureMailbox_WaitSyncPointIfNeeded_NoSyncPoint
) {
3061 // Mailboxing is only supported for GL textures.
3062 if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE
)
3065 scoped_ptr
<TextureStateTrackingContext
> context_owned(
3066 new TextureStateTrackingContext
);
3067 TextureStateTrackingContext
* context
= context_owned
.get();
3069 FakeOutputSurfaceClient output_surface_client
;
3070 scoped_ptr
<OutputSurface
> output_surface(
3071 FakeOutputSurface::Create3d(context_owned
.Pass()));
3072 CHECK(output_surface
->BindToClient(&output_surface_client
));
3074 scoped_ptr
<ResourceProvider
> resource_provider(ResourceProvider::Create(
3075 output_surface
.get(), shared_bitmap_manager_
.get(),
3076 gpu_memory_buffer_manager_
.get(), NULL
, 0, false, 1,
3077 use_image_texture_targets_
));
3079 uint32 sync_point
= 0;
3080 unsigned target
= GL_TEXTURE_2D
;
3082 EXPECT_CALL(*context
, bindTexture(_
, _
)).Times(0);
3083 EXPECT_CALL(*context
, waitSyncPoint(_
)).Times(0);
3084 EXPECT_CALL(*context
, insertSyncPoint()).Times(0);
3085 EXPECT_CALL(*context
, produceTextureDirectCHROMIUM(_
, _
, _
)).Times(0);
3086 EXPECT_CALL(*context
, createAndConsumeTextureCHROMIUM(_
, _
)).Times(0);
3088 gpu::Mailbox gpu_mailbox
;
3089 memcpy(gpu_mailbox
.name
, "Hello world", strlen("Hello world") + 1);
3090 scoped_ptr
<SingleReleaseCallbackImpl
> callback
=
3091 SingleReleaseCallbackImpl::Create(base::Bind(&EmptyReleaseCallback
));
3093 TextureMailbox
mailbox(gpu_mailbox
, target
, sync_point
);
3095 ResourceId id
= resource_provider
->CreateResourceFromTextureMailbox(
3096 mailbox
, callback
.Pass());
3099 Mock::VerifyAndClearExpectations(context
);
3102 // WaitSyncPointIfNeeded with sync_point == 0 shouldn't call waitSyncPoint.
3103 EXPECT_CALL(*context
, waitSyncPoint(_
)).Times(0);
3104 resource_provider
->WaitSyncPointIfNeeded(id
);
3105 Mock::VerifyAndClearExpectations(context
);
3109 class AllocationTrackingContext3D
: public TestWebGraphicsContext3D
{
3111 MOCK_METHOD0(NextTextureId
, GLuint());
3112 MOCK_METHOD1(RetireTextureId
, void(GLuint id
));
3113 MOCK_METHOD2(bindTexture
, void(GLenum target
, GLuint texture
));
3114 MOCK_METHOD5(texStorage2DEXT
,
3117 GLuint internalformat
,
3120 MOCK_METHOD9(texImage2D
,
3123 GLenum internalformat
,
3129 const void* pixels
));
3130 MOCK_METHOD9(texSubImage2D
,
3139 const void* pixels
));
3140 MOCK_METHOD9(asyncTexImage2DCHROMIUM
,
3143 GLenum internalformat
,
3149 const void* pixels
));
3150 MOCK_METHOD9(asyncTexSubImage2DCHROMIUM
,
3159 const void* pixels
));
3160 MOCK_METHOD8(compressedTexImage2D
,
3163 GLenum internalformat
,
3169 MOCK_METHOD1(waitAsyncTexImage2DCHROMIUM
, void(GLenum
));
3170 MOCK_METHOD4(createImageCHROMIUM
,
3171 GLuint(ClientBuffer
, GLsizei
, GLsizei
, GLenum
));
3172 MOCK_METHOD1(destroyImageCHROMIUM
, void(GLuint
));
3173 MOCK_METHOD2(bindTexImage2DCHROMIUM
, void(GLenum
, GLint
));
3174 MOCK_METHOD2(releaseTexImage2DCHROMIUM
, void(GLenum
, GLint
));
3176 // We're mocking bindTexture, so we override
3177 // TestWebGraphicsContext3D::texParameteri to avoid assertions related to the
3178 // currently bound texture.
3179 virtual void texParameteri(GLenum target
, GLenum pname
, GLint param
) {}
3182 TEST_P(ResourceProviderTest
, TextureAllocation
) {
3183 // Only for GL textures.
3184 if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE
)
3186 scoped_ptr
<AllocationTrackingContext3D
> context_owned(
3187 new StrictMock
<AllocationTrackingContext3D
>);
3188 AllocationTrackingContext3D
* context
= context_owned
.get();
3190 FakeOutputSurfaceClient output_surface_client
;
3191 scoped_ptr
<OutputSurface
> output_surface(
3192 FakeOutputSurface::Create3d(context_owned
.Pass()));
3193 CHECK(output_surface
->BindToClient(&output_surface_client
));
3195 scoped_ptr
<ResourceProvider
> resource_provider(ResourceProvider::Create(
3196 output_surface
.get(), shared_bitmap_manager_
.get(),
3197 gpu_memory_buffer_manager_
.get(), NULL
, 0, false, 1,
3198 use_image_texture_targets_
));
3200 gfx::Size
size(2, 2);
3201 gfx::Vector2d
offset(0, 0);
3202 ResourceFormat format
= RGBA_8888
;
3204 uint8_t pixels
[16] = { 0 };
3205 int texture_id
= 123;
3207 // Lazy allocation. Don't allocate when creating the resource.
3208 id
= resource_provider
->CreateResource(
3209 size
, GL_CLAMP_TO_EDGE
, ResourceProvider::TEXTURE_HINT_IMMUTABLE
, format
);
3211 EXPECT_CALL(*context
, NextTextureId()).WillOnce(Return(texture_id
));
3212 EXPECT_CALL(*context
, bindTexture(GL_TEXTURE_2D
, texture_id
)).Times(1);
3213 resource_provider
->CreateForTesting(id
);
3215 EXPECT_CALL(*context
, RetireTextureId(texture_id
)).Times(1);
3216 resource_provider
->DeleteResource(id
);
3218 Mock::VerifyAndClearExpectations(context
);
3220 // Do allocate when we set the pixels.
3221 id
= resource_provider
->CreateResource(
3222 size
, GL_CLAMP_TO_EDGE
, ResourceProvider::TEXTURE_HINT_IMMUTABLE
, format
);
3224 EXPECT_CALL(*context
, NextTextureId()).WillOnce(Return(texture_id
));
3225 EXPECT_CALL(*context
, bindTexture(GL_TEXTURE_2D
, texture_id
)).Times(3);
3226 EXPECT_CALL(*context
, texImage2D(_
, _
, _
, 2, 2, _
, _
, _
, _
)).Times(1);
3227 EXPECT_CALL(*context
, texSubImage2D(_
, _
, _
, _
, 2, 2, _
, _
, _
)).Times(1);
3228 resource_provider
->CopyToResource(id
, pixels
, size
);
3230 EXPECT_CALL(*context
, RetireTextureId(texture_id
)).Times(1);
3231 resource_provider
->DeleteResource(id
);
3233 Mock::VerifyAndClearExpectations(context
);
3236 TEST_P(ResourceProviderTest
, TextureAllocationHint
) {
3237 // Only for GL textures.
3238 if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE
)
3240 scoped_ptr
<AllocationTrackingContext3D
> context_owned(
3241 new StrictMock
<AllocationTrackingContext3D
>);
3242 AllocationTrackingContext3D
* context
= context_owned
.get();
3243 context
->set_support_texture_storage(true);
3244 context
->set_support_texture_usage(true);
3246 FakeOutputSurfaceClient output_surface_client
;
3247 scoped_ptr
<OutputSurface
> output_surface(
3248 FakeOutputSurface::Create3d(context_owned
.Pass()));
3249 CHECK(output_surface
->BindToClient(&output_surface_client
));
3251 scoped_ptr
<ResourceProvider
> resource_provider(ResourceProvider::Create(
3252 output_surface
.get(), shared_bitmap_manager_
.get(),
3253 gpu_memory_buffer_manager_
.get(), NULL
, 0, false, 1,
3254 use_image_texture_targets_
));
3256 gfx::Size
size(2, 2);
3258 const ResourceFormat formats
[2] = {RGBA_8888
, BGRA_8888
};
3259 const ResourceProvider::TextureHint hints
[4] = {
3260 ResourceProvider::TEXTURE_HINT_DEFAULT
,
3261 ResourceProvider::TEXTURE_HINT_IMMUTABLE
,
3262 ResourceProvider::TEXTURE_HINT_FRAMEBUFFER
,
3263 ResourceProvider::TEXTURE_HINT_IMMUTABLE_FRAMEBUFFER
,
3265 for (size_t i
= 0; i
< arraysize(formats
); ++i
) {
3266 for (GLuint texture_id
= 1; texture_id
<= arraysize(hints
); ++texture_id
) {
3267 // Lazy allocation. Don't allocate when creating the resource.
3268 ResourceId id
= resource_provider
->CreateResource(
3269 size
, GL_CLAMP_TO_EDGE
, hints
[texture_id
- 1], formats
[i
]);
3271 EXPECT_CALL(*context
, NextTextureId()).WillOnce(Return(texture_id
));
3272 EXPECT_CALL(*context
, bindTexture(GL_TEXTURE_2D
, texture_id
)).Times(2);
3273 bool is_immutable_hint
=
3274 hints
[texture_id
- 1] & ResourceProvider::TEXTURE_HINT_IMMUTABLE
;
3275 bool support_immutable_texture
=
3276 is_immutable_hint
&& formats
[i
] == RGBA_8888
;
3277 EXPECT_CALL(*context
, texStorage2DEXT(_
, _
, _
, 2, 2))
3278 .Times(support_immutable_texture
? 1 : 0);
3279 EXPECT_CALL(*context
, texImage2D(_
, _
, _
, 2, 2, _
, _
, _
, _
))
3280 .Times(support_immutable_texture
? 0 : 1);
3281 resource_provider
->AllocateForTesting(id
);
3283 EXPECT_CALL(*context
, RetireTextureId(texture_id
)).Times(1);
3284 resource_provider
->DeleteResource(id
);
3286 Mock::VerifyAndClearExpectations(context
);
3291 TEST_P(ResourceProviderTest
, TextureAllocationHint_BGRA
) {
3292 // Only for GL textures.
3293 if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE
)
3295 scoped_ptr
<AllocationTrackingContext3D
> context_owned(
3296 new StrictMock
<AllocationTrackingContext3D
>);
3297 AllocationTrackingContext3D
* context
= context_owned
.get();
3298 context
->set_support_texture_format_bgra8888(true);
3299 context
->set_support_texture_storage(true);
3300 context
->set_support_texture_usage(true);
3302 FakeOutputSurfaceClient output_surface_client
;
3303 scoped_ptr
<OutputSurface
> output_surface(
3304 FakeOutputSurface::Create3d(context_owned
.Pass()));
3305 CHECK(output_surface
->BindToClient(&output_surface_client
));
3307 scoped_ptr
<ResourceProvider
> resource_provider(ResourceProvider::Create(
3308 output_surface
.get(), shared_bitmap_manager_
.get(),
3309 gpu_memory_buffer_manager_
.get(), NULL
, 0, false, 1,
3310 use_image_texture_targets_
));
3312 gfx::Size
size(2, 2);
3313 const ResourceFormat formats
[2] = {RGBA_8888
, BGRA_8888
};
3315 const ResourceProvider::TextureHint hints
[4] = {
3316 ResourceProvider::TEXTURE_HINT_DEFAULT
,
3317 ResourceProvider::TEXTURE_HINT_IMMUTABLE
,
3318 ResourceProvider::TEXTURE_HINT_FRAMEBUFFER
,
3319 ResourceProvider::TEXTURE_HINT_IMMUTABLE_FRAMEBUFFER
,
3321 for (size_t i
= 0; i
< arraysize(formats
); ++i
) {
3322 for (GLuint texture_id
= 1; texture_id
<= arraysize(hints
); ++texture_id
) {
3323 // Lazy allocation. Don't allocate when creating the resource.
3324 ResourceId id
= resource_provider
->CreateResource(
3325 size
, GL_CLAMP_TO_EDGE
, hints
[texture_id
- 1], formats
[i
]);
3327 EXPECT_CALL(*context
, NextTextureId()).WillOnce(Return(texture_id
));
3328 EXPECT_CALL(*context
, bindTexture(GL_TEXTURE_2D
, texture_id
)).Times(2);
3329 bool is_immutable_hint
=
3330 hints
[texture_id
- 1] & ResourceProvider::TEXTURE_HINT_IMMUTABLE
;
3331 EXPECT_CALL(*context
, texStorage2DEXT(_
, _
, _
, 2, 2))
3332 .Times(is_immutable_hint
? 1 : 0);
3333 EXPECT_CALL(*context
, texImage2D(_
, _
, _
, 2, 2, _
, _
, _
, _
))
3334 .Times(is_immutable_hint
? 0 : 1);
3335 resource_provider
->AllocateForTesting(id
);
3337 EXPECT_CALL(*context
, RetireTextureId(texture_id
)).Times(1);
3338 resource_provider
->DeleteResource(id
);
3340 Mock::VerifyAndClearExpectations(context
);
3345 TEST_P(ResourceProviderTest
, Image_GLTexture
) {
3346 // Only for GL textures.
3347 if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE
)
3349 scoped_ptr
<AllocationTrackingContext3D
> context_owned(
3350 new StrictMock
<AllocationTrackingContext3D
>);
3351 AllocationTrackingContext3D
* context
= context_owned
.get();
3353 FakeOutputSurfaceClient output_surface_client
;
3354 scoped_ptr
<OutputSurface
> output_surface(
3355 FakeOutputSurface::Create3d(context_owned
.Pass()));
3356 CHECK(output_surface
->BindToClient(&output_surface_client
));
3358 const int kWidth
= 2;
3359 const int kHeight
= 2;
3360 gfx::Size
size(kWidth
, kHeight
);
3361 ResourceFormat format
= RGBA_8888
;
3363 const unsigned kTextureId
= 123u;
3364 const unsigned kImageId
= 234u;
3366 scoped_ptr
<ResourceProvider
> resource_provider(ResourceProvider::Create(
3367 output_surface
.get(), shared_bitmap_manager_
.get(),
3368 gpu_memory_buffer_manager_
.get(), NULL
, 0, false, 1,
3369 use_image_texture_targets_
));
3371 id
= resource_provider
->CreateResource(
3372 size
, GL_CLAMP_TO_EDGE
, ResourceProvider::TEXTURE_HINT_IMMUTABLE
, format
);
3374 EXPECT_CALL(*context
, NextTextureId())
3375 .WillOnce(Return(kTextureId
))
3376 .RetiresOnSaturation();
3377 EXPECT_CALL(*context
, bindTexture(GL_TEXTURE_2D
, kTextureId
))
3379 .RetiresOnSaturation();
3380 EXPECT_CALL(*context
, createImageCHROMIUM(_
, kWidth
, kHeight
, GL_RGBA
))
3381 .WillOnce(Return(kImageId
))
3382 .RetiresOnSaturation();
3384 ResourceProvider::ScopedWriteLockGpuMemoryBuffer
lock(
3385 resource_provider
.get(), id
);
3386 EXPECT_TRUE(lock
.GetGpuMemoryBuffer());
3389 EXPECT_CALL(*context
, bindTexture(GL_TEXTURE_2D
, kTextureId
))
3391 .RetiresOnSaturation();
3392 EXPECT_CALL(*context
, bindTexImage2DCHROMIUM(GL_TEXTURE_2D
, kImageId
))
3394 .RetiresOnSaturation();
3396 ResourceProvider::ScopedSamplerGL
lock_gl(
3397 resource_provider
.get(), id
, GL_TEXTURE_2D
, GL_LINEAR
);
3398 EXPECT_EQ(kTextureId
, lock_gl
.texture_id());
3402 ResourceProvider::ScopedWriteLockGpuMemoryBuffer
lock(
3403 resource_provider
.get(), id
);
3404 EXPECT_TRUE(lock
.GetGpuMemoryBuffer());
3407 EXPECT_CALL(*context
, bindTexture(GL_TEXTURE_2D
, kTextureId
)).Times(1)
3408 .RetiresOnSaturation();
3409 EXPECT_CALL(*context
, releaseTexImage2DCHROMIUM(GL_TEXTURE_2D
, kImageId
))
3411 .RetiresOnSaturation();
3412 EXPECT_CALL(*context
, bindTexImage2DCHROMIUM(GL_TEXTURE_2D
, kImageId
))
3414 .RetiresOnSaturation();
3415 EXPECT_CALL(*context
, RetireTextureId(kTextureId
))
3417 .RetiresOnSaturation();
3419 ResourceProvider::ScopedSamplerGL
lock_gl(
3420 resource_provider
.get(), id
, GL_TEXTURE_2D
, GL_LINEAR
);
3421 EXPECT_EQ(kTextureId
, lock_gl
.texture_id());
3424 EXPECT_CALL(*context
, destroyImageCHROMIUM(kImageId
))
3426 .RetiresOnSaturation();
3429 TEST_P(ResourceProviderTest
, CompressedTextureETC1Allocate
) {
3430 if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE
)
3433 scoped_ptr
<AllocationTrackingContext3D
> context_owned(
3434 new AllocationTrackingContext3D
);
3435 AllocationTrackingContext3D
* context
= context_owned
.get();
3436 context_owned
->set_support_compressed_texture_etc1(true);
3438 FakeOutputSurfaceClient output_surface_client
;
3439 scoped_ptr
<OutputSurface
> output_surface(
3440 FakeOutputSurface::Create3d(context_owned
.Pass()));
3441 CHECK(output_surface
->BindToClient(&output_surface_client
));
3443 gfx::Size
size(4, 4);
3444 scoped_ptr
<ResourceProvider
> resource_provider(ResourceProvider::Create(
3445 output_surface
.get(), shared_bitmap_manager_
.get(),
3446 gpu_memory_buffer_manager_
.get(), NULL
, 0, false, 1,
3447 use_image_texture_targets_
));
3448 int texture_id
= 123;
3450 ResourceId id
= resource_provider
->CreateResource(
3451 size
, GL_CLAMP_TO_EDGE
, ResourceProvider::TEXTURE_HINT_IMMUTABLE
, ETC1
);
3453 EXPECT_CALL(*context
, NextTextureId()).WillOnce(Return(texture_id
));
3454 EXPECT_CALL(*context
, bindTexture(GL_TEXTURE_2D
, texture_id
)).Times(2);
3455 resource_provider
->AllocateForTesting(id
);
3457 EXPECT_CALL(*context
, RetireTextureId(texture_id
)).Times(1);
3458 resource_provider
->DeleteResource(id
);
3461 TEST_P(ResourceProviderTest
, CompressedTextureETC1Upload
) {
3462 if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE
)
3465 scoped_ptr
<AllocationTrackingContext3D
> context_owned(
3466 new AllocationTrackingContext3D
);
3467 AllocationTrackingContext3D
* context
= context_owned
.get();
3468 context_owned
->set_support_compressed_texture_etc1(true);
3470 FakeOutputSurfaceClient output_surface_client
;
3471 scoped_ptr
<OutputSurface
> output_surface(
3472 FakeOutputSurface::Create3d(context_owned
.Pass()));
3473 CHECK(output_surface
->BindToClient(&output_surface_client
));
3475 gfx::Size
size(4, 4);
3476 scoped_ptr
<ResourceProvider
> resource_provider(ResourceProvider::Create(
3477 output_surface
.get(), shared_bitmap_manager_
.get(),
3478 gpu_memory_buffer_manager_
.get(), NULL
, 0, false, 1,
3479 use_image_texture_targets_
));
3480 int texture_id
= 123;
3483 ResourceId id
= resource_provider
->CreateResource(
3484 size
, GL_CLAMP_TO_EDGE
, ResourceProvider::TEXTURE_HINT_IMMUTABLE
, ETC1
);
3486 EXPECT_CALL(*context
, NextTextureId()).WillOnce(Return(texture_id
));
3487 EXPECT_CALL(*context
, bindTexture(GL_TEXTURE_2D
, texture_id
)).Times(3);
3488 EXPECT_CALL(*context
,
3489 compressedTexImage2D(
3490 _
, 0, _
, size
.width(), size
.height(), _
, _
, _
)).Times(1);
3491 resource_provider
->CopyToResource(id
, pixels
, size
);
3493 EXPECT_CALL(*context
, RetireTextureId(texture_id
)).Times(1);
3494 resource_provider
->DeleteResource(id
);
3497 INSTANTIATE_TEST_CASE_P(
3498 ResourceProviderTests
,
3499 ResourceProviderTest
,
3500 ::testing::Values(ResourceProvider::RESOURCE_TYPE_GL_TEXTURE
,
3501 ResourceProvider::RESOURCE_TYPE_BITMAP
));
3503 class TextureIdAllocationTrackingContext
: public TestWebGraphicsContext3D
{
3505 GLuint
NextTextureId() override
{
3506 base::AutoLock
lock(namespace_
->lock
);
3507 return namespace_
->next_texture_id
++;
3509 void RetireTextureId(GLuint
) override
{}
3510 GLuint
PeekTextureId() {
3511 base::AutoLock
lock(namespace_
->lock
);
3512 return namespace_
->next_texture_id
;
3516 TEST(ResourceProviderTest
, TextureAllocationChunkSize
) {
3517 scoped_ptr
<TextureIdAllocationTrackingContext
> context_owned(
3518 new TextureIdAllocationTrackingContext
);
3519 TextureIdAllocationTrackingContext
* context
= context_owned
.get();
3521 FakeOutputSurfaceClient output_surface_client
;
3522 scoped_ptr
<OutputSurface
> output_surface(
3523 FakeOutputSurface::Create3d(context_owned
.Pass()));
3524 CHECK(output_surface
->BindToClient(&output_surface_client
));
3525 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
3526 new TestSharedBitmapManager());
3528 gfx::Size
size(1, 1);
3529 ResourceFormat format
= RGBA_8888
;
3532 size_t kTextureAllocationChunkSize
= 1;
3533 scoped_ptr
<ResourceProvider
> resource_provider(ResourceProvider::Create(
3534 output_surface
.get(), shared_bitmap_manager
.get(), NULL
, NULL
, 0, false,
3535 kTextureAllocationChunkSize
,
3536 ResourceProviderTest::use_image_texture_targets()));
3538 ResourceId id
= resource_provider
->CreateResource(
3539 size
, GL_CLAMP_TO_EDGE
, ResourceProvider::TEXTURE_HINT_IMMUTABLE
,
3541 resource_provider
->AllocateForTesting(id
);
3542 Mock::VerifyAndClearExpectations(context
);
3544 DCHECK_EQ(2u, context
->PeekTextureId());
3545 resource_provider
->DeleteResource(id
);
3549 size_t kTextureAllocationChunkSize
= 8;
3550 scoped_ptr
<ResourceProvider
> resource_provider(ResourceProvider::Create(
3551 output_surface
.get(), shared_bitmap_manager
.get(), NULL
, NULL
, 0, false,
3552 kTextureAllocationChunkSize
,
3553 ResourceProviderTest::use_image_texture_targets()));
3555 ResourceId id
= resource_provider
->CreateResource(
3556 size
, GL_CLAMP_TO_EDGE
, ResourceProvider::TEXTURE_HINT_IMMUTABLE
,
3558 resource_provider
->AllocateForTesting(id
);
3559 Mock::VerifyAndClearExpectations(context
);
3561 DCHECK_EQ(10u, context
->PeekTextureId());
3562 resource_provider
->DeleteResource(id
);