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/layers/texture_layer.h"
9 #include "base/callback.h"
10 #include "cc/layers/texture_layer_client.h"
11 #include "cc/layers/texture_layer_impl.h"
12 #include "cc/test/fake_impl_proxy.h"
13 #include "cc/test/fake_layer_tree_host_client.h"
14 #include "cc/test/fake_layer_tree_host_impl.h"
15 #include "cc/test/layer_test_common.h"
16 #include "cc/test/layer_tree_test.h"
17 #include "cc/trees/layer_tree_host.h"
18 #include "cc/trees/layer_tree_impl.h"
19 #include "cc/trees/single_thread_proxy.h"
20 #include "testing/gmock/include/gmock/gmock.h"
21 #include "testing/gtest/include/gtest/gtest.h"
23 using ::testing::Mock
;
25 using ::testing::AtLeast
;
26 using ::testing::AnyNumber
;
31 class MockLayerTreeHost
: public LayerTreeHost
{
33 explicit MockLayerTreeHost(LayerTreeHostClient
* client
)
34 : LayerTreeHost(client
, LayerTreeSettings()) {
38 MOCK_METHOD0(AcquireLayerTextures
, void());
39 MOCK_METHOD0(SetNeedsCommit
, void());
42 class TextureLayerTest
: public testing::Test
{
46 FakeLayerTreeHostClient(FakeLayerTreeHostClient::DIRECT_3D
)),
47 host_impl_(&proxy_
) {}
50 virtual void SetUp() {
51 layer_tree_host_
.reset(new MockLayerTreeHost(&fake_client_
));
54 virtual void TearDown() {
55 Mock::VerifyAndClearExpectations(layer_tree_host_
.get());
56 EXPECT_CALL(*layer_tree_host_
, AcquireLayerTextures()).Times(AnyNumber());
57 EXPECT_CALL(*layer_tree_host_
, SetNeedsCommit()).Times(AnyNumber());
59 layer_tree_host_
->SetRootLayer(NULL
);
60 layer_tree_host_
.reset();
63 scoped_ptr
<MockLayerTreeHost
> layer_tree_host_
;
65 FakeLayerTreeHostClient fake_client_
;
66 FakeLayerTreeHostImpl host_impl_
;
69 TEST_F(TextureLayerTest
, SyncImplWhenChangingTextureId
) {
70 scoped_refptr
<TextureLayer
> test_layer
= TextureLayer::Create(NULL
);
71 ASSERT_TRUE(test_layer
.get());
73 EXPECT_CALL(*layer_tree_host_
, AcquireLayerTextures()).Times(AnyNumber());
74 EXPECT_CALL(*layer_tree_host_
, SetNeedsCommit()).Times(AnyNumber());
75 layer_tree_host_
->SetRootLayer(test_layer
);
76 Mock::VerifyAndClearExpectations(layer_tree_host_
.get());
77 EXPECT_EQ(test_layer
->layer_tree_host(), layer_tree_host_
.get());
79 EXPECT_CALL(*layer_tree_host_
, AcquireLayerTextures()).Times(0);
80 EXPECT_CALL(*layer_tree_host_
, SetNeedsCommit()).Times(AtLeast(1));
81 test_layer
->SetTextureId(1);
82 Mock::VerifyAndClearExpectations(layer_tree_host_
.get());
84 EXPECT_CALL(*layer_tree_host_
, AcquireLayerTextures()).Times(AtLeast(1));
85 EXPECT_CALL(*layer_tree_host_
, SetNeedsCommit()).Times(AtLeast(1));
86 test_layer
->SetTextureId(2);
87 Mock::VerifyAndClearExpectations(layer_tree_host_
.get());
89 EXPECT_CALL(*layer_tree_host_
, AcquireLayerTextures()).Times(AtLeast(1));
90 EXPECT_CALL(*layer_tree_host_
, SetNeedsCommit()).Times(AtLeast(1));
91 test_layer
->SetTextureId(0);
92 Mock::VerifyAndClearExpectations(layer_tree_host_
.get());
95 TEST_F(TextureLayerTest
, SyncImplWhenDrawing
) {
96 gfx::RectF
dirty_rect(0.f
, 0.f
, 1.f
, 1.f
);
98 scoped_refptr
<TextureLayer
> test_layer
= TextureLayer::Create(NULL
);
99 ASSERT_TRUE(test_layer
.get());
100 scoped_ptr
<TextureLayerImpl
> impl_layer
;
101 impl_layer
= TextureLayerImpl::Create(host_impl_
.active_tree(), 1, false);
102 ASSERT_TRUE(impl_layer
);
104 EXPECT_CALL(*layer_tree_host_
, AcquireLayerTextures()).Times(AnyNumber());
105 EXPECT_CALL(*layer_tree_host_
, SetNeedsCommit()).Times(AnyNumber());
106 layer_tree_host_
->SetRootLayer(test_layer
);
107 test_layer
->SetTextureId(1);
108 test_layer
->SetIsDrawable(true);
109 Mock::VerifyAndClearExpectations(layer_tree_host_
.get());
110 EXPECT_EQ(test_layer
->layer_tree_host(), layer_tree_host_
.get());
112 EXPECT_CALL(*layer_tree_host_
, AcquireLayerTextures()).Times(1);
113 EXPECT_CALL(*layer_tree_host_
, SetNeedsCommit()).Times(0);
114 test_layer
->WillModifyTexture();
115 Mock::VerifyAndClearExpectations(layer_tree_host_
.get());
117 EXPECT_CALL(*layer_tree_host_
, AcquireLayerTextures()).Times(0);
118 EXPECT_CALL(*layer_tree_host_
, SetNeedsCommit()).Times(1);
119 test_layer
->SetNeedsDisplayRect(dirty_rect
);
120 Mock::VerifyAndClearExpectations(layer_tree_host_
.get());
122 EXPECT_CALL(*layer_tree_host_
, AcquireLayerTextures()).Times(0);
123 EXPECT_CALL(*layer_tree_host_
, SetNeedsCommit()).Times(1);
124 test_layer
->PushPropertiesTo(impl_layer
.get()); // fake commit
125 test_layer
->SetIsDrawable(false);
126 Mock::VerifyAndClearExpectations(layer_tree_host_
.get());
128 // Verify that non-drawable layers don't signal the compositor,
129 // except for the first draw after last commit, which must acquire
131 EXPECT_CALL(*layer_tree_host_
, AcquireLayerTextures()).Times(1);
132 EXPECT_CALL(*layer_tree_host_
, SetNeedsCommit()).Times(0);
133 test_layer
->WillModifyTexture();
134 test_layer
->SetNeedsDisplayRect(dirty_rect
);
135 test_layer
->PushPropertiesTo(impl_layer
.get()); // fake commit
136 Mock::VerifyAndClearExpectations(layer_tree_host_
.get());
138 // Second draw with layer in non-drawable state: no texture
140 EXPECT_CALL(*layer_tree_host_
, AcquireLayerTextures()).Times(0);
141 EXPECT_CALL(*layer_tree_host_
, SetNeedsCommit()).Times(0);
142 test_layer
->WillModifyTexture();
143 test_layer
->SetNeedsDisplayRect(dirty_rect
);
144 Mock::VerifyAndClearExpectations(layer_tree_host_
.get());
147 TEST_F(TextureLayerTest
, SyncImplWhenRemovingFromTree
) {
148 scoped_refptr
<Layer
> root_layer
= Layer::Create();
149 ASSERT_TRUE(root_layer
.get());
150 scoped_refptr
<Layer
> child_layer
= Layer::Create();
151 ASSERT_TRUE(child_layer
.get());
152 root_layer
->AddChild(child_layer
);
153 scoped_refptr
<TextureLayer
> test_layer
= TextureLayer::Create(NULL
);
154 ASSERT_TRUE(test_layer
.get());
155 test_layer
->SetTextureId(0);
156 child_layer
->AddChild(test_layer
);
158 EXPECT_CALL(*layer_tree_host_
, AcquireLayerTextures()).Times(AnyNumber());
159 EXPECT_CALL(*layer_tree_host_
, SetNeedsCommit()).Times(AnyNumber());
160 layer_tree_host_
->SetRootLayer(root_layer
);
161 Mock::VerifyAndClearExpectations(layer_tree_host_
.get());
163 EXPECT_CALL(*layer_tree_host_
, AcquireLayerTextures()).Times(0);
164 EXPECT_CALL(*layer_tree_host_
, SetNeedsCommit()).Times(AtLeast(1));
165 test_layer
->RemoveFromParent();
166 Mock::VerifyAndClearExpectations(layer_tree_host_
.get());
168 EXPECT_CALL(*layer_tree_host_
, AcquireLayerTextures()).Times(0);
169 EXPECT_CALL(*layer_tree_host_
, SetNeedsCommit()).Times(AtLeast(1));
170 child_layer
->AddChild(test_layer
);
171 Mock::VerifyAndClearExpectations(layer_tree_host_
.get());
173 EXPECT_CALL(*layer_tree_host_
, AcquireLayerTextures()).Times(0);
174 EXPECT_CALL(*layer_tree_host_
, SetNeedsCommit()).Times(AtLeast(1));
175 test_layer
->SetTextureId(1);
176 Mock::VerifyAndClearExpectations(layer_tree_host_
.get());
178 EXPECT_CALL(*layer_tree_host_
, AcquireLayerTextures()).Times(AtLeast(1));
179 EXPECT_CALL(*layer_tree_host_
, SetNeedsCommit()).Times(AtLeast(1));
180 test_layer
->RemoveFromParent();
181 Mock::VerifyAndClearExpectations(layer_tree_host_
.get());
184 TEST_F(TextureLayerTest
, CheckPropertyChangeCausesCorrectBehavior
) {
185 scoped_refptr
<TextureLayer
> test_layer
= TextureLayer::Create(NULL
);
186 test_layer
->SetLayerTreeHost(layer_tree_host_
.get());
188 // Test properties that should call SetNeedsCommit. All properties need to
189 // be set to new values in order for SetNeedsCommit to be called.
190 EXPECT_SET_NEEDS_COMMIT(1, test_layer
->SetFlipped(false));
191 EXPECT_SET_NEEDS_COMMIT(1, test_layer
->SetUV(
192 gfx::PointF(0.25f
, 0.25f
), gfx::PointF(0.75f
, 0.75f
)));
193 EXPECT_SET_NEEDS_COMMIT(1, test_layer
->SetVertexOpacity(
194 0.5f
, 0.5f
, 0.5f
, 0.5f
));
195 EXPECT_SET_NEEDS_COMMIT(1, test_layer
->SetPremultipliedAlpha(false));
196 EXPECT_SET_NEEDS_COMMIT(1, test_layer
->SetTextureId(1));
198 // Calling SetTextureId can call AcquireLayerTextures.
199 EXPECT_CALL(*layer_tree_host_
, AcquireLayerTextures()).Times(AnyNumber());
202 class MockMailboxCallback
{
204 MOCK_METHOD3(Release
, void(const std::string
& mailbox
,
206 bool lost_resource
));
207 MOCK_METHOD3(Release2
, void(base::SharedMemory
* shared_memory
,
209 bool lost_resource
));
212 struct CommonMailboxObjects
{
213 CommonMailboxObjects()
214 : mailbox_name1_(64, '1'),
215 mailbox_name2_(64, '2'),
218 shared_memory_(new base::SharedMemory
) {
219 release_mailbox1_
= base::Bind(&MockMailboxCallback::Release
,
220 base::Unretained(&mock_callback_
),
222 release_mailbox2_
= base::Bind(&MockMailboxCallback::Release
,
223 base::Unretained(&mock_callback_
),
226 m1
.SetName(reinterpret_cast<const int8
*>(mailbox_name1_
.data()));
227 mailbox1_
= TextureMailbox(m1
, release_mailbox1_
, sync_point1_
);
229 m2
.SetName(reinterpret_cast<const int8
*>(mailbox_name2_
.data()));
230 mailbox2_
= TextureMailbox(m2
, release_mailbox2_
, sync_point2_
);
232 gfx::Size
size(128, 128);
233 EXPECT_TRUE(shared_memory_
->CreateAndMapAnonymous(4 * size
.GetArea()));
234 release_mailbox3_
= base::Bind(&MockMailboxCallback::Release2
,
235 base::Unretained(&mock_callback_
),
236 shared_memory_
.get());
237 mailbox3_
= TextureMailbox(shared_memory_
.get(), size
, release_mailbox3_
);
240 std::string mailbox_name1_
;
241 std::string mailbox_name2_
;
242 MockMailboxCallback mock_callback_
;
243 TextureMailbox::ReleaseCallback release_mailbox1_
;
244 TextureMailbox::ReleaseCallback release_mailbox2_
;
245 TextureMailbox::ReleaseCallback release_mailbox3_
;
246 TextureMailbox mailbox1_
;
247 TextureMailbox mailbox2_
;
248 TextureMailbox mailbox3_
;
249 unsigned sync_point1_
;
250 unsigned sync_point2_
;
251 scoped_ptr
<base::SharedMemory
> shared_memory_
;
254 class TextureLayerWithMailboxTest
: public TextureLayerTest
{
256 virtual void TearDown() {
257 Mock::VerifyAndClearExpectations(&test_data_
.mock_callback_
);
258 EXPECT_CALL(test_data_
.mock_callback_
,
259 Release(test_data_
.mailbox_name1_
,
260 test_data_
.sync_point1_
,
262 TextureLayerTest::TearDown();
265 CommonMailboxObjects test_data_
;
268 TEST_F(TextureLayerWithMailboxTest
, ReplaceMailboxOnMainThreadBeforeCommit
) {
269 scoped_refptr
<TextureLayer
> test_layer
= TextureLayer::CreateForMailbox(NULL
);
270 ASSERT_TRUE(test_layer
.get());
272 EXPECT_CALL(*layer_tree_host_
, AcquireLayerTextures()).Times(0);
273 EXPECT_CALL(*layer_tree_host_
, SetNeedsCommit()).Times(AnyNumber());
274 layer_tree_host_
->SetRootLayer(test_layer
);
275 Mock::VerifyAndClearExpectations(layer_tree_host_
.get());
277 EXPECT_CALL(*layer_tree_host_
, AcquireLayerTextures()).Times(0);
278 EXPECT_CALL(*layer_tree_host_
, SetNeedsCommit()).Times(AtLeast(1));
279 test_layer
->SetTextureMailbox(test_data_
.mailbox1_
);
280 Mock::VerifyAndClearExpectations(layer_tree_host_
.get());
282 EXPECT_CALL(*layer_tree_host_
, AcquireLayerTextures()).Times(0);
283 EXPECT_CALL(*layer_tree_host_
, SetNeedsCommit()).Times(AtLeast(1));
284 EXPECT_CALL(test_data_
.mock_callback_
,
285 Release(test_data_
.mailbox_name1_
,
286 test_data_
.sync_point1_
,
289 test_layer
->SetTextureMailbox(test_data_
.mailbox2_
);
290 Mock::VerifyAndClearExpectations(layer_tree_host_
.get());
291 Mock::VerifyAndClearExpectations(&test_data_
.mock_callback_
);
293 EXPECT_CALL(*layer_tree_host_
, AcquireLayerTextures()).Times(0);
294 EXPECT_CALL(*layer_tree_host_
, SetNeedsCommit()).Times(AtLeast(1));
295 EXPECT_CALL(test_data_
.mock_callback_
,
296 Release(test_data_
.mailbox_name2_
,
297 test_data_
.sync_point2_
,
300 test_layer
->SetTextureMailbox(TextureMailbox());
301 Mock::VerifyAndClearExpectations(layer_tree_host_
.get());
302 Mock::VerifyAndClearExpectations(&test_data_
.mock_callback_
);
304 test_layer
->SetTextureMailbox(test_data_
.mailbox3_
);
305 Mock::VerifyAndClearExpectations(layer_tree_host_
.get());
306 Mock::VerifyAndClearExpectations(&test_data_
.mock_callback_
);
308 EXPECT_CALL(*layer_tree_host_
, AcquireLayerTextures()).Times(0);
309 EXPECT_CALL(*layer_tree_host_
, SetNeedsCommit()).Times(AtLeast(1));
310 EXPECT_CALL(test_data_
.mock_callback_
,
311 Release2(test_data_
.shared_memory_
.get(),
314 test_layer
->SetTextureMailbox(TextureMailbox());
315 Mock::VerifyAndClearExpectations(layer_tree_host_
.get());
316 Mock::VerifyAndClearExpectations(&test_data_
.mock_callback_
);
319 EXPECT_CALL(*layer_tree_host_
, SetNeedsCommit()).Times(AtLeast(1));
320 test_layer
->SetTextureMailbox(test_data_
.mailbox1_
);
323 class TextureLayerImplWithMailboxThreadedCallback
: public LayerTreeTest
{
325 TextureLayerImplWithMailboxThreadedCallback()
326 : callback_count_(0),
329 // Make sure callback is received on main and doesn't block the impl thread.
330 void ReleaseCallback(unsigned sync_point
, bool lost_resource
) {
331 EXPECT_EQ(true, proxy()->IsMainThread());
332 EXPECT_FALSE(lost_resource
);
336 void SetMailbox(char mailbox_char
) {
337 TextureMailbox
mailbox(
338 std::string(64, mailbox_char
),
340 &TextureLayerImplWithMailboxThreadedCallback::ReleaseCallback
,
341 base::Unretained(this)));
342 layer_
->SetTextureMailbox(mailbox
);
345 virtual void BeginTest() OVERRIDE
{
346 gfx::Size
bounds(100, 100);
347 root_
= Layer::Create();
348 root_
->SetAnchorPoint(gfx::PointF());
349 root_
->SetBounds(bounds
);
351 layer_
= TextureLayer::CreateForMailbox(NULL
);
352 layer_
->SetIsDrawable(true);
353 layer_
->SetAnchorPoint(gfx::PointF());
354 layer_
->SetBounds(bounds
);
356 root_
->AddChild(layer_
);
357 layer_tree_host()->SetRootLayer(root_
);
358 layer_tree_host()->SetViewportSize(bounds
);
360 EXPECT_EQ(0, callback_count_
);
362 // Case #1: change mailbox before the commit. The old mailbox should be
363 // released immediately.
365 EXPECT_EQ(1, callback_count_
);
366 PostSetNeedsCommitToMainThread();
369 virtual void DidCommit() OVERRIDE
{
371 switch (commit_count_
) {
373 // Case #2: change mailbox after the commit (and draw), where the
374 // layer draws. The old mailbox should be released during the next
377 EXPECT_EQ(1, callback_count_
);
380 // Old mailbox was released, task was posted, but won't execute
381 // until this DidCommit returns.
382 // TODO(piman): fix this.
383 EXPECT_EQ(1, callback_count_
);
384 layer_tree_host()->SetNeedsCommit();
387 EXPECT_EQ(2, callback_count_
);
388 // Case #3: change mailbox when the layer doesn't draw. The old
389 // mailbox should be released during the next commit.
390 layer_
->SetBounds(gfx::Size());
394 // Old mailbox was released, task was posted, but won't execute
395 // until this DidCommit returns.
396 // TODO(piman): fix this.
397 EXPECT_EQ(2, callback_count_
);
398 layer_tree_host()->SetNeedsCommit();
401 EXPECT_EQ(3, callback_count_
);
402 // Case #4: release mailbox that was committed but never drawn. The
403 // old mailbox should be released during the next commit.
404 layer_
->SetTextureMailbox(TextureMailbox());
407 // Old mailbox was released, task was posted, but won't execute
408 // until this DidCommit returns.
409 // TODO(piman): fix this.
410 EXPECT_EQ(3, callback_count_
);
411 layer_tree_host()->SetNeedsCommit();
414 EXPECT_EQ(4, callback_count_
);
415 // Restore a mailbox for the next step.
419 // Case #5: remove layer from tree. Callback should *not* be called, the
420 // mailbox is returned to the main thread.
421 EXPECT_EQ(4, callback_count_
);
422 layer_
->RemoveFromParent();
425 // Mailbox was released to the main thread, task was posted, but won't
426 // execute until this DidCommit returns.
427 // TODO(piman): fix this.
428 EXPECT_EQ(4, callback_count_
);
429 layer_tree_host()->SetNeedsCommit();
432 EXPECT_EQ(4, callback_count_
);
433 // Resetting the mailbox will call the callback now.
434 layer_
->SetTextureMailbox(TextureMailbox());
435 EXPECT_EQ(5, callback_count_
);
444 virtual void AfterTest() OVERRIDE
{}
449 scoped_refptr
<Layer
> root_
;
450 scoped_refptr
<TextureLayer
> layer_
;
453 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
454 TextureLayerImplWithMailboxThreadedCallback
);
456 class TextureLayerImplWithMailboxTest
: public TextureLayerTest
{
458 TextureLayerImplWithMailboxTest()
460 FakeLayerTreeHostClient(FakeLayerTreeHostClient::DIRECT_3D
)) {}
462 virtual void SetUp() {
463 TextureLayerTest::SetUp();
464 layer_tree_host_
.reset(new MockLayerTreeHost(&fake_client_
));
465 EXPECT_TRUE(host_impl_
.InitializeRenderer(CreateFakeOutputSurface()));
468 CommonMailboxObjects test_data_
;
469 FakeLayerTreeHostClient fake_client_
;
472 // Test conditions for results of TextureLayerImpl::WillDraw under
473 // different configurations of different mailbox, texture_id, and draw_mode.
474 TEST_F(TextureLayerImplWithMailboxTest
, TestWillDraw
) {
477 scoped_ptr
<TextureLayerImpl
> impl_layer
=
478 TextureLayerImpl::Create(host_impl_
.active_tree(), 1, true);
479 impl_layer
->SetTextureMailbox(test_data_
.mailbox1_
);
480 impl_layer
->DidBecomeActive();
481 EXPECT_TRUE(impl_layer
->WillDraw(
482 DRAW_MODE_HARDWARE
, host_impl_
.active_tree()->resource_provider()));
483 impl_layer
->DidDraw(host_impl_
.active_tree()->resource_provider());
487 scoped_ptr
<TextureLayerImpl
> impl_layer
=
488 TextureLayerImpl::Create(host_impl_
.active_tree(), 1, true);
489 impl_layer
->SetTextureMailbox(test_data_
.mailbox1_
);
490 EXPECT_FALSE(impl_layer
->WillDraw(
491 DRAW_MODE_HARDWARE
, host_impl_
.active_tree()->resource_provider()));
495 scoped_ptr
<TextureLayerImpl
> impl_layer
=
496 TextureLayerImpl::Create(host_impl_
.active_tree(), 1, false);
498 host_impl_
.output_surface()->context3d()->createTexture();
499 impl_layer
->set_texture_id(texture
);
500 EXPECT_TRUE(impl_layer
->WillDraw(
501 DRAW_MODE_HARDWARE
, host_impl_
.active_tree()->resource_provider()));
502 impl_layer
->DidDraw(host_impl_
.active_tree()->resource_provider());
506 scoped_ptr
<TextureLayerImpl
> impl_layer
=
507 TextureLayerImpl::Create(host_impl_
.active_tree(), 1, false);
508 impl_layer
->set_texture_id(0);
509 EXPECT_FALSE(impl_layer
->WillDraw(
510 DRAW_MODE_HARDWARE
, host_impl_
.active_tree()->resource_provider()));
513 // Resourceless software mode.
515 scoped_ptr
<TextureLayerImpl
> impl_layer
=
516 TextureLayerImpl::Create(host_impl_
.active_tree(), 1, true);
517 impl_layer
->SetTextureMailbox(test_data_
.mailbox1_
);
518 impl_layer
->DidBecomeActive();
520 impl_layer
->WillDraw(DRAW_MODE_RESOURCELESS_SOFTWARE
,
521 host_impl_
.active_tree()->resource_provider()));
525 scoped_ptr
<TextureLayerImpl
> impl_layer
=
526 TextureLayerImpl::Create(host_impl_
.active_tree(), 1, false);
528 host_impl_
.output_surface()->context3d()->createTexture();
529 impl_layer
->set_texture_id(texture
);
531 impl_layer
->WillDraw(DRAW_MODE_RESOURCELESS_SOFTWARE
,
532 host_impl_
.active_tree()->resource_provider()));
536 TEST_F(TextureLayerImplWithMailboxTest
, TestImplLayerCallbacks
) {
537 host_impl_
.CreatePendingTree();
538 scoped_ptr
<TextureLayerImpl
> pending_layer
;
539 pending_layer
= TextureLayerImpl::Create(host_impl_
.pending_tree(), 1, true);
540 ASSERT_TRUE(pending_layer
);
542 scoped_ptr
<LayerImpl
> active_layer(
543 pending_layer
->CreateLayerImpl(host_impl_
.active_tree()));
544 ASSERT_TRUE(active_layer
);
546 pending_layer
->SetTextureMailbox(test_data_
.mailbox1_
);
548 // Test multiple commits without an activation.
549 EXPECT_CALL(test_data_
.mock_callback_
,
550 Release(test_data_
.mailbox_name1_
,
551 test_data_
.sync_point1_
,
554 pending_layer
->SetTextureMailbox(test_data_
.mailbox2_
);
555 Mock::VerifyAndClearExpectations(&test_data_
.mock_callback_
);
557 // Test callback after activation.
558 pending_layer
->PushPropertiesTo(active_layer
.get());
559 active_layer
->DidBecomeActive();
561 EXPECT_CALL(test_data_
.mock_callback_
, Release(_
, _
, _
)).Times(0);
562 pending_layer
->SetTextureMailbox(test_data_
.mailbox1_
);
563 Mock::VerifyAndClearExpectations(&test_data_
.mock_callback_
);
565 EXPECT_CALL(test_data_
.mock_callback_
,
566 Release(test_data_
.mailbox_name2_
, _
, false))
568 pending_layer
->PushPropertiesTo(active_layer
.get());
569 active_layer
->DidBecomeActive();
570 Mock::VerifyAndClearExpectations(&test_data_
.mock_callback_
);
572 // Test resetting the mailbox.
573 EXPECT_CALL(test_data_
.mock_callback_
,
574 Release(test_data_
.mailbox_name1_
, _
, false))
576 pending_layer
->SetTextureMailbox(TextureMailbox());
577 pending_layer
->PushPropertiesTo(active_layer
.get());
578 active_layer
->DidBecomeActive();
579 Mock::VerifyAndClearExpectations(&test_data_
.mock_callback_
);
582 EXPECT_CALL(test_data_
.mock_callback_
,
583 Release(test_data_
.mailbox_name1_
,
584 test_data_
.sync_point1_
,
587 pending_layer
->SetTextureMailbox(test_data_
.mailbox1_
);
590 TEST_F(TextureLayerImplWithMailboxTest
,
591 TestDestructorCallbackOnCreatedResource
) {
592 scoped_ptr
<TextureLayerImpl
> impl_layer
;
593 impl_layer
= TextureLayerImpl::Create(host_impl_
.active_tree(), 1, true);
594 ASSERT_TRUE(impl_layer
);
596 EXPECT_CALL(test_data_
.mock_callback_
,
597 Release(test_data_
.mailbox_name1_
, _
, false))
599 impl_layer
->SetTextureMailbox(test_data_
.mailbox1_
);
600 impl_layer
->DidBecomeActive();
601 EXPECT_TRUE(impl_layer
->WillDraw(
602 DRAW_MODE_HARDWARE
, host_impl_
.active_tree()->resource_provider()));
603 impl_layer
->DidDraw(host_impl_
.active_tree()->resource_provider());
604 impl_layer
->SetTextureMailbox(TextureMailbox());
607 TEST_F(TextureLayerImplWithMailboxTest
, TestCallbackOnInUseResource
) {
608 ResourceProvider
* provider
= host_impl_
.active_tree()->resource_provider();
609 ResourceProvider::ResourceId id
=
610 provider
->CreateResourceFromTextureMailbox(test_data_
.mailbox1_
);
611 provider
->AllocateForTesting(id
);
613 // Transfer some resources to the parent.
614 ResourceProvider::ResourceIdArray resource_ids_to_transfer
;
615 resource_ids_to_transfer
.push_back(id
);
616 TransferableResourceArray list
;
617 provider
->PrepareSendToParent(resource_ids_to_transfer
, &list
);
618 EXPECT_TRUE(provider
->InUseByConsumer(id
));
619 EXPECT_CALL(test_data_
.mock_callback_
, Release(_
, _
, _
)).Times(0);
620 provider
->DeleteResource(id
);
621 Mock::VerifyAndClearExpectations(&test_data_
.mock_callback_
);
622 EXPECT_CALL(test_data_
.mock_callback_
,
623 Release(test_data_
.mailbox_name1_
, _
, false))
625 provider
->ReceiveFromParent(list
);
628 // Check that ClearClient correctly clears the state so that the impl side
629 // doesn't try to use a texture that could have been destroyed.
630 class TextureLayerClientTest
631 : public LayerTreeTest
,
632 public TextureLayerClient
{
634 TextureLayerClientTest()
638 expected_used_textures_on_draw_(0),
639 expected_used_textures_on_commit_(0) {}
641 virtual scoped_ptr
<OutputSurface
> CreateOutputSurface() OVERRIDE
{
642 scoped_ptr
<TestWebGraphicsContext3D
> context(
643 TestWebGraphicsContext3D::Create());
644 context_
= context
.get();
645 texture_
= context
->createTexture();
646 return FakeOutputSurface::Create3d(
647 context
.PassAs
<WebKit::WebGraphicsContext3D
>()).PassAs
<OutputSurface
>();
650 virtual unsigned PrepareTexture(ResourceUpdateQueue
* queue
) OVERRIDE
{
654 virtual WebKit::WebGraphicsContext3D
* Context3d() OVERRIDE
{
658 virtual bool PrepareTextureMailbox(cc::TextureMailbox
* mailbox
) OVERRIDE
{
662 virtual void SetupTree() OVERRIDE
{
663 scoped_refptr
<Layer
> root
= Layer::Create();
664 root
->SetBounds(gfx::Size(10, 10));
665 root
->SetAnchorPoint(gfx::PointF());
666 root
->SetIsDrawable(true);
668 texture_layer_
= TextureLayer::Create(this);
669 texture_layer_
->SetBounds(gfx::Size(10, 10));
670 texture_layer_
->SetAnchorPoint(gfx::PointF());
671 texture_layer_
->SetIsDrawable(true);
672 root
->AddChild(texture_layer_
);
674 layer_tree_host()->SetRootLayer(root
);
675 LayerTreeTest::SetupTree();
677 base::AutoLock
lock(lock_
);
678 expected_used_textures_on_commit_
= 1;
682 virtual void BeginTest() OVERRIDE
{
683 PostSetNeedsCommitToMainThread();
686 virtual void DidCommitAndDrawFrame() OVERRIDE
{
688 switch (commit_count_
) {
690 texture_layer_
->ClearClient();
691 texture_layer_
->SetNeedsDisplay();
693 base::AutoLock
lock(lock_
);
694 expected_used_textures_on_commit_
= 0;
707 virtual void BeginCommitOnThread(LayerTreeHostImpl
* host_impl
) OVERRIDE
{
708 base::AutoLock
lock(lock_
);
709 expected_used_textures_on_draw_
= expected_used_textures_on_commit_
;
712 virtual bool PrepareToDrawOnThread(LayerTreeHostImpl
* host_impl
,
713 LayerTreeHostImpl::FrameData
* frame_data
,
714 bool result
) OVERRIDE
{
715 context_
->ResetUsedTextures();
719 virtual void SwapBuffersOnThread(LayerTreeHostImpl
* host_impl
,
720 bool result
) OVERRIDE
{
722 EXPECT_EQ(expected_used_textures_on_draw_
, context_
->NumUsedTextures());
725 virtual void AfterTest() OVERRIDE
{}
728 scoped_refptr
<TextureLayer
> texture_layer_
;
729 TestWebGraphicsContext3D
* context_
;
733 // Used only on thread.
734 unsigned expected_used_textures_on_draw_
;
736 // Used on either thread, protected by lock_.
738 unsigned expected_used_textures_on_commit_
;
741 // The TextureLayerClient does not use mailboxes, so can't use a delegating
743 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(TextureLayerClientTest
);