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"
10 #include "base/bind.h"
11 #include "base/callback.h"
12 #include "base/synchronization/waitable_event.h"
13 #include "base/threading/thread.h"
14 #include "base/time/time.h"
15 #include "cc/layers/solid_color_layer.h"
16 #include "cc/layers/texture_layer_client.h"
17 #include "cc/layers/texture_layer_impl.h"
18 #include "cc/output/compositor_frame_ack.h"
19 #include "cc/output/context_provider.h"
20 #include "cc/resources/returned_resource.h"
21 #include "cc/test/fake_impl_proxy.h"
22 #include "cc/test/fake_layer_tree_host_client.h"
23 #include "cc/test/fake_layer_tree_host_impl.h"
24 #include "cc/test/fake_output_surface.h"
25 #include "cc/test/layer_test_common.h"
26 #include "cc/test/layer_tree_test.h"
27 #include "cc/test/test_web_graphics_context_3d.h"
28 #include "cc/trees/blocking_task_runner.h"
29 #include "cc/trees/layer_tree_host.h"
30 #include "cc/trees/layer_tree_impl.h"
31 #include "cc/trees/single_thread_proxy.h"
32 #include "gpu/GLES2/gl2extchromium.h"
33 #include "testing/gmock/include/gmock/gmock.h"
34 #include "testing/gtest/include/gtest/gtest.h"
36 using ::testing::Mock
;
38 using ::testing::AtLeast
;
39 using ::testing::AnyNumber
;
44 gpu::Mailbox
MailboxFromChar(char value
) {
46 memset(mailbox
.name
, value
, sizeof(mailbox
.name
));
50 class MockLayerTreeHost
: public LayerTreeHost
{
52 explicit MockLayerTreeHost(FakeLayerTreeHostClient
* client
)
53 : LayerTreeHost(client
, NULL
, LayerTreeSettings()) {
54 InitializeSingleThreaded(client
);
57 MOCK_METHOD0(AcquireLayerTextures
, void());
58 MOCK_METHOD0(SetNeedsCommit
, void());
59 MOCK_METHOD0(SetNeedsUpdateLayers
, void());
60 MOCK_METHOD0(StartRateLimiter
, void());
61 MOCK_METHOD0(StopRateLimiter
, void());
64 class TextureLayerTest
: public testing::Test
{
68 FakeLayerTreeHostClient(FakeLayerTreeHostClient::DIRECT_3D
)),
69 host_impl_(&proxy_
) {}
72 virtual void SetUp() {
73 layer_tree_host_
.reset(new MockLayerTreeHost(&fake_client_
));
76 virtual void TearDown() {
77 Mock::VerifyAndClearExpectations(layer_tree_host_
.get());
78 EXPECT_CALL(*layer_tree_host_
, AcquireLayerTextures()).Times(AnyNumber());
79 EXPECT_CALL(*layer_tree_host_
, SetNeedsCommit()).Times(AnyNumber());
81 layer_tree_host_
->SetRootLayer(NULL
);
82 layer_tree_host_
.reset();
85 scoped_ptr
<MockLayerTreeHost
> layer_tree_host_
;
87 FakeLayerTreeHostClient fake_client_
;
88 FakeLayerTreeHostImpl host_impl_
;
91 TEST_F(TextureLayerTest
, SyncImplWhenChangingTextureId
) {
92 scoped_refptr
<TextureLayer
> test_layer
= TextureLayer::Create(NULL
);
93 ASSERT_TRUE(test_layer
.get());
95 EXPECT_CALL(*layer_tree_host_
, AcquireLayerTextures()).Times(AnyNumber());
96 EXPECT_CALL(*layer_tree_host_
, SetNeedsCommit()).Times(AnyNumber());
97 layer_tree_host_
->SetRootLayer(test_layer
);
98 Mock::VerifyAndClearExpectations(layer_tree_host_
.get());
99 EXPECT_EQ(test_layer
->layer_tree_host(), layer_tree_host_
.get());
101 EXPECT_CALL(*layer_tree_host_
, AcquireLayerTextures()).Times(0);
102 EXPECT_CALL(*layer_tree_host_
, SetNeedsCommit()).Times(AtLeast(1));
103 test_layer
->SetTextureId(1);
104 Mock::VerifyAndClearExpectations(layer_tree_host_
.get());
106 EXPECT_CALL(*layer_tree_host_
, AcquireLayerTextures()).Times(AtLeast(1));
107 EXPECT_CALL(*layer_tree_host_
, SetNeedsCommit()).Times(AtLeast(1));
108 test_layer
->SetTextureId(2);
109 Mock::VerifyAndClearExpectations(layer_tree_host_
.get());
111 EXPECT_CALL(*layer_tree_host_
, AcquireLayerTextures()).Times(AtLeast(1));
112 EXPECT_CALL(*layer_tree_host_
, SetNeedsCommit()).Times(AtLeast(1));
113 test_layer
->SetTextureId(0);
114 Mock::VerifyAndClearExpectations(layer_tree_host_
.get());
117 TEST_F(TextureLayerTest
, SyncImplWhenDrawing
) {
118 gfx::RectF
dirty_rect(0.f
, 0.f
, 1.f
, 1.f
);
120 scoped_refptr
<TextureLayer
> test_layer
= TextureLayer::Create(NULL
);
121 ASSERT_TRUE(test_layer
.get());
122 scoped_ptr
<TextureLayerImpl
> impl_layer
;
123 impl_layer
= TextureLayerImpl::Create(host_impl_
.active_tree(), 1, false);
124 ASSERT_TRUE(impl_layer
);
126 EXPECT_CALL(*layer_tree_host_
, AcquireLayerTextures()).Times(AnyNumber());
127 EXPECT_CALL(*layer_tree_host_
, SetNeedsCommit()).Times(AnyNumber());
128 layer_tree_host_
->SetRootLayer(test_layer
);
129 test_layer
->SetTextureId(1);
130 test_layer
->SetIsDrawable(true);
131 Mock::VerifyAndClearExpectations(layer_tree_host_
.get());
132 EXPECT_EQ(test_layer
->layer_tree_host(), layer_tree_host_
.get());
134 EXPECT_CALL(*layer_tree_host_
, AcquireLayerTextures()).Times(1);
135 EXPECT_CALL(*layer_tree_host_
, SetNeedsCommit()).Times(0);
136 test_layer
->WillModifyTexture();
137 Mock::VerifyAndClearExpectations(layer_tree_host_
.get());
139 EXPECT_CALL(*layer_tree_host_
, AcquireLayerTextures()).Times(0);
140 EXPECT_CALL(*layer_tree_host_
, SetNeedsUpdateLayers()).Times(1);
141 test_layer
->SetNeedsDisplayRect(dirty_rect
);
142 Mock::VerifyAndClearExpectations(layer_tree_host_
.get());
144 EXPECT_CALL(*layer_tree_host_
, AcquireLayerTextures()).Times(0);
145 EXPECT_CALL(*layer_tree_host_
, SetNeedsCommit()).Times(1);
146 test_layer
->PushPropertiesTo(impl_layer
.get()); // fake commit
147 test_layer
->SetIsDrawable(false);
148 Mock::VerifyAndClearExpectations(layer_tree_host_
.get());
150 // Verify that non-drawable layers don't signal the compositor,
151 // except for the first draw after last commit, which must acquire
153 EXPECT_CALL(*layer_tree_host_
, AcquireLayerTextures()).Times(1);
154 EXPECT_CALL(*layer_tree_host_
, SetNeedsCommit()).Times(0);
155 test_layer
->WillModifyTexture();
156 test_layer
->SetNeedsDisplayRect(dirty_rect
);
157 test_layer
->PushPropertiesTo(impl_layer
.get()); // fake commit
158 Mock::VerifyAndClearExpectations(layer_tree_host_
.get());
160 // Second draw with layer in non-drawable state: no texture
162 EXPECT_CALL(*layer_tree_host_
, AcquireLayerTextures()).Times(0);
163 EXPECT_CALL(*layer_tree_host_
, SetNeedsCommit()).Times(0);
164 test_layer
->WillModifyTexture();
165 test_layer
->SetNeedsDisplayRect(dirty_rect
);
166 Mock::VerifyAndClearExpectations(layer_tree_host_
.get());
169 TEST_F(TextureLayerTest
, SyncImplWhenRemovingFromTree
) {
170 scoped_refptr
<Layer
> root_layer
= Layer::Create();
171 ASSERT_TRUE(root_layer
.get());
172 scoped_refptr
<Layer
> child_layer
= Layer::Create();
173 ASSERT_TRUE(child_layer
.get());
174 root_layer
->AddChild(child_layer
);
175 scoped_refptr
<TextureLayer
> test_layer
= TextureLayer::Create(NULL
);
176 ASSERT_TRUE(test_layer
.get());
177 test_layer
->SetTextureId(0);
178 child_layer
->AddChild(test_layer
);
180 EXPECT_CALL(*layer_tree_host_
, AcquireLayerTextures()).Times(AnyNumber());
181 EXPECT_CALL(*layer_tree_host_
, SetNeedsCommit()).Times(AnyNumber());
182 layer_tree_host_
->SetRootLayer(root_layer
);
183 Mock::VerifyAndClearExpectations(layer_tree_host_
.get());
185 EXPECT_CALL(*layer_tree_host_
, AcquireLayerTextures()).Times(0);
186 EXPECT_CALL(*layer_tree_host_
, SetNeedsCommit()).Times(AtLeast(1));
187 test_layer
->RemoveFromParent();
188 Mock::VerifyAndClearExpectations(layer_tree_host_
.get());
190 EXPECT_CALL(*layer_tree_host_
, AcquireLayerTextures()).Times(0);
191 EXPECT_CALL(*layer_tree_host_
, SetNeedsCommit()).Times(AtLeast(1));
192 child_layer
->AddChild(test_layer
);
193 Mock::VerifyAndClearExpectations(layer_tree_host_
.get());
195 EXPECT_CALL(*layer_tree_host_
, AcquireLayerTextures()).Times(0);
196 EXPECT_CALL(*layer_tree_host_
, SetNeedsCommit()).Times(AtLeast(1));
197 test_layer
->SetTextureId(1);
198 Mock::VerifyAndClearExpectations(layer_tree_host_
.get());
200 EXPECT_CALL(*layer_tree_host_
, AcquireLayerTextures()).Times(AtLeast(1));
201 EXPECT_CALL(*layer_tree_host_
, SetNeedsCommit()).Times(AtLeast(1));
202 test_layer
->RemoveFromParent();
203 Mock::VerifyAndClearExpectations(layer_tree_host_
.get());
206 TEST_F(TextureLayerTest
, CheckPropertyChangeCausesCorrectBehavior
) {
207 scoped_refptr
<TextureLayer
> test_layer
= TextureLayer::Create(NULL
);
208 EXPECT_SET_NEEDS_COMMIT(1, layer_tree_host_
->SetRootLayer(test_layer
));
210 // Test properties that should call SetNeedsCommit. All properties need to
211 // be set to new values in order for SetNeedsCommit to be called.
212 EXPECT_SET_NEEDS_COMMIT(1, test_layer
->SetFlipped(false));
213 EXPECT_SET_NEEDS_COMMIT(1, test_layer
->SetUV(
214 gfx::PointF(0.25f
, 0.25f
), gfx::PointF(0.75f
, 0.75f
)));
215 EXPECT_SET_NEEDS_COMMIT(1, test_layer
->SetVertexOpacity(
216 0.5f
, 0.5f
, 0.5f
, 0.5f
));
217 EXPECT_SET_NEEDS_COMMIT(1, test_layer
->SetPremultipliedAlpha(false));
218 EXPECT_SET_NEEDS_COMMIT(1, test_layer
->SetBlendBackgroundColor(true));
219 EXPECT_SET_NEEDS_COMMIT(1, test_layer
->SetTextureId(1));
221 // Calling SetTextureId can call AcquireLayerTextures.
222 EXPECT_CALL(*layer_tree_host_
, AcquireLayerTextures()).Times(AnyNumber());
225 TEST_F(TextureLayerTest
, VisibleContentOpaqueRegion
) {
226 const gfx::Size
layer_bounds(100, 100);
227 const gfx::Rect
layer_rect(layer_bounds
);
228 const Region
layer_region(layer_rect
);
230 scoped_refptr
<TextureLayer
> layer
= TextureLayer::Create(NULL
);
231 layer
->SetBounds(layer_bounds
);
232 layer
->draw_properties().visible_content_rect
= layer_rect
;
233 layer
->SetBlendBackgroundColor(true);
235 // Verify initial conditions.
236 EXPECT_FALSE(layer
->contents_opaque());
237 EXPECT_EQ(0u, layer
->background_color());
238 EXPECT_EQ(Region().ToString(),
239 layer
->VisibleContentOpaqueRegion().ToString());
241 // Opaque background.
242 layer
->SetBackgroundColor(SK_ColorWHITE
);
243 EXPECT_EQ(layer_region
.ToString(),
244 layer
->VisibleContentOpaqueRegion().ToString());
246 // Transparent background.
247 layer
->SetBackgroundColor(SkColorSetARGB(100, 255, 255, 255));
248 EXPECT_EQ(Region().ToString(),
249 layer
->VisibleContentOpaqueRegion().ToString());
252 class FakeTextureLayerClient
: public TextureLayerClient
{
254 FakeTextureLayerClient() {}
256 virtual unsigned PrepareTexture() OVERRIDE
{
260 virtual bool PrepareTextureMailbox(
261 TextureMailbox
* mailbox
,
262 scoped_ptr
<SingleReleaseCallback
>* release_callback
,
263 bool use_shared_memory
) OVERRIDE
{
264 *mailbox
= TextureMailbox();
265 *release_callback
= scoped_ptr
<SingleReleaseCallback
>();
270 DISALLOW_COPY_AND_ASSIGN(FakeTextureLayerClient
);
273 TEST_F(TextureLayerTest
, RateLimiter
) {
274 FakeTextureLayerClient client
;
275 scoped_refptr
<TextureLayer
> test_layer
= TextureLayer::CreateForMailbox(
277 test_layer
->SetIsDrawable(true);
278 EXPECT_CALL(*layer_tree_host_
, SetNeedsCommit()).Times(AnyNumber());
279 layer_tree_host_
->SetRootLayer(test_layer
);
281 // Don't rate limit until we invalidate.
282 EXPECT_CALL(*layer_tree_host_
, StartRateLimiter()).Times(0);
283 test_layer
->SetRateLimitContext(true);
284 Mock::VerifyAndClearExpectations(layer_tree_host_
.get());
286 // Do rate limit after we invalidate.
287 EXPECT_CALL(*layer_tree_host_
, StartRateLimiter());
288 test_layer
->SetNeedsDisplay();
289 Mock::VerifyAndClearExpectations(layer_tree_host_
.get());
291 // Stop rate limiter when we don't want it any more.
292 EXPECT_CALL(*layer_tree_host_
, StopRateLimiter());
293 test_layer
->SetRateLimitContext(false);
294 Mock::VerifyAndClearExpectations(layer_tree_host_
.get());
296 // Or we clear the client.
297 test_layer
->SetRateLimitContext(true);
298 EXPECT_CALL(*layer_tree_host_
, StopRateLimiter());
299 EXPECT_CALL(*layer_tree_host_
, SetNeedsCommit()).Times(AnyNumber());
300 test_layer
->ClearClient();
301 Mock::VerifyAndClearExpectations(layer_tree_host_
.get());
303 // Reset to a layer with a client, that started the rate limiter.
304 test_layer
= TextureLayer::CreateForMailbox(
306 test_layer
->SetIsDrawable(true);
307 test_layer
->SetRateLimitContext(true);
308 EXPECT_CALL(*layer_tree_host_
, SetNeedsCommit()).Times(AnyNumber());
309 layer_tree_host_
->SetRootLayer(test_layer
);
310 EXPECT_CALL(*layer_tree_host_
, StartRateLimiter()).Times(0);
311 Mock::VerifyAndClearExpectations(layer_tree_host_
.get());
312 EXPECT_CALL(*layer_tree_host_
, StartRateLimiter());
313 test_layer
->SetNeedsDisplay();
314 Mock::VerifyAndClearExpectations(layer_tree_host_
.get());
316 // Stop rate limiter when we're removed from the tree.
317 EXPECT_CALL(*layer_tree_host_
, StopRateLimiter());
318 layer_tree_host_
->SetRootLayer(NULL
);
319 Mock::VerifyAndClearExpectations(layer_tree_host_
.get());
322 class MockMailboxCallback
{
324 MOCK_METHOD3(Release
,
325 void(const gpu::Mailbox
& mailbox
,
327 bool lost_resource
));
328 MOCK_METHOD3(Release2
,
329 void(base::SharedMemory
* shared_memory
,
331 bool lost_resource
));
334 struct CommonMailboxObjects
{
335 CommonMailboxObjects()
336 : mailbox_name1_(MailboxFromChar('1')),
337 mailbox_name2_(MailboxFromChar('2')),
340 shared_memory_(new base::SharedMemory
) {
341 release_mailbox1_
= base::Bind(&MockMailboxCallback::Release
,
342 base::Unretained(&mock_callback_
),
344 release_mailbox2_
= base::Bind(&MockMailboxCallback::Release
,
345 base::Unretained(&mock_callback_
),
347 const uint32 arbitrary_target1
= 1;
348 const uint32 arbitrary_target2
= 2;
349 mailbox1_
= TextureMailbox(mailbox_name1_
, arbitrary_target1
, sync_point1_
);
350 mailbox2_
= TextureMailbox(mailbox_name2_
, arbitrary_target2
, sync_point2_
);
351 gfx::Size
size(128, 128);
352 EXPECT_TRUE(shared_memory_
->CreateAndMapAnonymous(4 * size
.GetArea()));
353 release_mailbox3_
= base::Bind(&MockMailboxCallback::Release2
,
354 base::Unretained(&mock_callback_
),
355 shared_memory_
.get());
356 mailbox3_
= TextureMailbox(shared_memory_
.get(), size
);
359 gpu::Mailbox mailbox_name1_
;
360 gpu::Mailbox mailbox_name2_
;
361 MockMailboxCallback mock_callback_
;
362 ReleaseCallback release_mailbox1_
;
363 ReleaseCallback release_mailbox2_
;
364 ReleaseCallback release_mailbox3_
;
365 TextureMailbox mailbox1_
;
366 TextureMailbox mailbox2_
;
367 TextureMailbox mailbox3_
;
370 scoped_ptr
<base::SharedMemory
> shared_memory_
;
373 class TestMailboxHolder
: public TextureLayer::TextureMailboxHolder
{
375 using TextureLayer::TextureMailboxHolder::Create
;
378 virtual ~TestMailboxHolder() {}
381 class TextureLayerWithMailboxTest
: public TextureLayerTest
{
383 virtual void TearDown() {
384 Mock::VerifyAndClearExpectations(&test_data_
.mock_callback_
);
385 EXPECT_CALL(test_data_
.mock_callback_
,
386 Release(test_data_
.mailbox_name1_
,
387 test_data_
.sync_point1_
,
389 TextureLayerTest::TearDown();
392 CommonMailboxObjects test_data_
;
395 TEST_F(TextureLayerWithMailboxTest
, ReplaceMailboxOnMainThreadBeforeCommit
) {
396 scoped_refptr
<TextureLayer
> test_layer
= TextureLayer::CreateForMailbox(NULL
);
397 ASSERT_TRUE(test_layer
.get());
399 EXPECT_CALL(*layer_tree_host_
, AcquireLayerTextures()).Times(0);
400 EXPECT_CALL(*layer_tree_host_
, SetNeedsCommit()).Times(AnyNumber());
401 layer_tree_host_
->SetRootLayer(test_layer
);
402 Mock::VerifyAndClearExpectations(layer_tree_host_
.get());
404 EXPECT_CALL(*layer_tree_host_
, AcquireLayerTextures()).Times(0);
405 EXPECT_CALL(*layer_tree_host_
, SetNeedsCommit()).Times(AtLeast(1));
406 test_layer
->SetTextureMailbox(
407 test_data_
.mailbox1_
,
408 SingleReleaseCallback::Create(test_data_
.release_mailbox1_
));
409 Mock::VerifyAndClearExpectations(layer_tree_host_
.get());
411 EXPECT_CALL(*layer_tree_host_
, AcquireLayerTextures()).Times(0);
412 EXPECT_CALL(*layer_tree_host_
, SetNeedsCommit()).Times(AtLeast(1));
413 EXPECT_CALL(test_data_
.mock_callback_
,
414 Release(test_data_
.mailbox_name1_
,
415 test_data_
.sync_point1_
,
418 test_layer
->SetTextureMailbox(
419 test_data_
.mailbox2_
,
420 SingleReleaseCallback::Create(test_data_
.release_mailbox2_
));
421 Mock::VerifyAndClearExpectations(layer_tree_host_
.get());
422 Mock::VerifyAndClearExpectations(&test_data_
.mock_callback_
);
424 EXPECT_CALL(*layer_tree_host_
, AcquireLayerTextures()).Times(0);
425 EXPECT_CALL(*layer_tree_host_
, SetNeedsCommit()).Times(AtLeast(1));
426 EXPECT_CALL(test_data_
.mock_callback_
,
427 Release(test_data_
.mailbox_name2_
,
428 test_data_
.sync_point2_
,
431 test_layer
->SetTextureMailbox(TextureMailbox(),
432 scoped_ptr
<SingleReleaseCallback
>());
433 Mock::VerifyAndClearExpectations(layer_tree_host_
.get());
434 Mock::VerifyAndClearExpectations(&test_data_
.mock_callback_
);
436 EXPECT_CALL(*layer_tree_host_
, AcquireLayerTextures()).Times(0);
437 EXPECT_CALL(*layer_tree_host_
, SetNeedsCommit()).Times(AtLeast(1));
438 test_layer
->SetTextureMailbox(
439 test_data_
.mailbox3_
,
440 SingleReleaseCallback::Create(test_data_
.release_mailbox3_
));
441 Mock::VerifyAndClearExpectations(layer_tree_host_
.get());
442 Mock::VerifyAndClearExpectations(&test_data_
.mock_callback_
);
444 EXPECT_CALL(*layer_tree_host_
, AcquireLayerTextures()).Times(0);
445 EXPECT_CALL(*layer_tree_host_
, SetNeedsCommit()).Times(AtLeast(1));
446 EXPECT_CALL(test_data_
.mock_callback_
,
447 Release2(test_data_
.shared_memory_
.get(),
450 test_layer
->SetTextureMailbox(TextureMailbox(),
451 scoped_ptr
<SingleReleaseCallback
>());
452 Mock::VerifyAndClearExpectations(layer_tree_host_
.get());
453 Mock::VerifyAndClearExpectations(&test_data_
.mock_callback_
);
456 EXPECT_CALL(*layer_tree_host_
, SetNeedsCommit()).Times(AtLeast(1));
457 test_layer
->SetTextureMailbox(
458 test_data_
.mailbox1_
,
459 SingleReleaseCallback::Create(test_data_
.release_mailbox1_
));
462 class TextureLayerMailboxHolderTest
: public TextureLayerTest
{
464 TextureLayerMailboxHolderTest()
465 : main_thread_("MAIN") {
466 main_thread_
.Start();
469 void Wait(const base::Thread
& thread
) {
470 bool manual_reset
= false;
471 bool initially_signaled
= false;
472 base::WaitableEvent
event(manual_reset
, initially_signaled
);
473 thread
.message_loop()->PostTask(
475 base::Bind(&base::WaitableEvent::Signal
, base::Unretained(&event
)));
479 void CreateMainRef() {
480 main_ref_
= TestMailboxHolder::Create(
481 test_data_
.mailbox1_
,
482 SingleReleaseCallback::Create(test_data_
.release_mailbox1_
)).Pass();
485 void ReleaseMainRef() {
489 void CreateImplRef(scoped_ptr
<SingleReleaseCallback
>* impl_ref
) {
490 *impl_ref
= main_ref_
->holder()->GetCallbackForImplThread();
493 void CapturePostTasksAndWait(base::WaitableEvent
* begin_capture
,
494 base::WaitableEvent
* wait_for_capture
,
495 base::WaitableEvent
* stop_capture
) {
496 begin_capture
->Wait();
497 BlockingTaskRunner::CapturePostTasks capture
;
498 wait_for_capture
->Signal();
499 stop_capture
->Wait();
503 scoped_ptr
<TestMailboxHolder::MainThreadReference
>
505 base::Thread main_thread_
;
506 CommonMailboxObjects test_data_
;
509 TEST_F(TextureLayerMailboxHolderTest
, TwoCompositors_BothReleaseThenMain
) {
510 scoped_refptr
<TextureLayer
> test_layer
= TextureLayer::CreateForMailbox(NULL
);
511 ASSERT_TRUE(test_layer
.get());
513 main_thread_
.message_loop()->PostTask(
515 base::Bind(&TextureLayerMailboxHolderTest::CreateMainRef
,
516 base::Unretained(this)));
520 // The texture layer is attached to compositor1, and passes a reference to its
522 scoped_ptr
<SingleReleaseCallback
> compositor1
;
523 main_thread_
.message_loop()->PostTask(
525 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef
,
526 base::Unretained(this),
529 // Then the texture layer is removed and attached to compositor2, and passes a
530 // reference to its impl tree.
531 scoped_ptr
<SingleReleaseCallback
> compositor2
;
532 main_thread_
.message_loop()->PostTask(
534 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef
,
535 base::Unretained(this),
539 Mock::VerifyAndClearExpectations(&test_data_
.mock_callback_
);
541 // The compositors both destroy their impl trees before the main thread layer
543 compositor1
->Run(100, false);
544 compositor2
->Run(200, false);
548 EXPECT_CALL(test_data_
.mock_callback_
, Release(_
, _
, _
)).Times(0);
549 Mock::VerifyAndClearExpectations(&test_data_
.mock_callback_
);
551 // The main thread ref is the last one, so the mailbox is released back to the
552 // embedder, with the last sync point provided by the impl trees.
553 EXPECT_CALL(test_data_
.mock_callback_
,
554 Release(test_data_
.mailbox_name1_
, 200, false)).Times(1);
556 main_thread_
.message_loop()->PostTask(
558 base::Bind(&TextureLayerMailboxHolderTest::ReleaseMainRef
,
559 base::Unretained(this)));
561 Mock::VerifyAndClearExpectations(&test_data_
.mock_callback_
);
564 TEST_F(TextureLayerMailboxHolderTest
, TwoCompositors_MainReleaseBetween
) {
565 scoped_refptr
<TextureLayer
> test_layer
= TextureLayer::CreateForMailbox(NULL
);
566 ASSERT_TRUE(test_layer
.get());
568 main_thread_
.message_loop()->PostTask(
570 base::Bind(&TextureLayerMailboxHolderTest::CreateMainRef
,
571 base::Unretained(this)));
575 // The texture layer is attached to compositor1, and passes a reference to its
577 scoped_ptr
<SingleReleaseCallback
> compositor1
;
578 main_thread_
.message_loop()->PostTask(
580 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef
,
581 base::Unretained(this),
584 // Then the texture layer is removed and attached to compositor2, and passes a
585 // reference to its impl tree.
586 scoped_ptr
<SingleReleaseCallback
> compositor2
;
587 main_thread_
.message_loop()->PostTask(
589 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef
,
590 base::Unretained(this),
594 Mock::VerifyAndClearExpectations(&test_data_
.mock_callback_
);
596 // One compositor destroys their impl tree.
597 compositor1
->Run(100, false);
599 // Then the main thread reference is destroyed.
600 main_thread_
.message_loop()->PostTask(
602 base::Bind(&TextureLayerMailboxHolderTest::ReleaseMainRef
,
603 base::Unretained(this)));
607 EXPECT_CALL(test_data_
.mock_callback_
, Release(_
, _
, _
)).Times(0);
608 Mock::VerifyAndClearExpectations(&test_data_
.mock_callback_
);
610 // The second impl reference is destroyed last, causing the mailbox to be
611 // released back to the embedder with the last sync point from the impl tree.
612 EXPECT_CALL(test_data_
.mock_callback_
,
613 Release(test_data_
.mailbox_name1_
, 200, true)).Times(1);
615 compositor2
->Run(200, true);
617 Mock::VerifyAndClearExpectations(&test_data_
.mock_callback_
);
620 TEST_F(TextureLayerMailboxHolderTest
, TwoCompositors_MainReleasedFirst
) {
621 scoped_refptr
<TextureLayer
> test_layer
= TextureLayer::CreateForMailbox(NULL
);
622 ASSERT_TRUE(test_layer
.get());
624 main_thread_
.message_loop()->PostTask(
626 base::Bind(&TextureLayerMailboxHolderTest::CreateMainRef
,
627 base::Unretained(this)));
631 // The texture layer is attached to compositor1, and passes a reference to its
633 scoped_ptr
<SingleReleaseCallback
> compositor1
;
634 main_thread_
.message_loop()->PostTask(
636 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef
,
637 base::Unretained(this),
640 // Then the texture layer is removed and attached to compositor2, and passes a
641 // reference to its impl tree.
642 scoped_ptr
<SingleReleaseCallback
> compositor2
;
643 main_thread_
.message_loop()->PostTask(
645 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef
,
646 base::Unretained(this),
650 Mock::VerifyAndClearExpectations(&test_data_
.mock_callback_
);
652 // The main thread reference is destroyed first.
653 main_thread_
.message_loop()->PostTask(
655 base::Bind(&TextureLayerMailboxHolderTest::ReleaseMainRef
,
656 base::Unretained(this)));
658 // One compositor destroys their impl tree.
659 compositor2
->Run(200, false);
663 EXPECT_CALL(test_data_
.mock_callback_
, Release(_
, _
, _
)).Times(0);
664 Mock::VerifyAndClearExpectations(&test_data_
.mock_callback_
);
666 // The second impl reference is destroyed last, causing the mailbox to be
667 // released back to the embedder with the last sync point from the impl tree.
668 EXPECT_CALL(test_data_
.mock_callback_
,
669 Release(test_data_
.mailbox_name1_
, 100, true)).Times(1);
671 compositor1
->Run(100, true);
673 Mock::VerifyAndClearExpectations(&test_data_
.mock_callback_
);
676 TEST_F(TextureLayerMailboxHolderTest
, TwoCompositors_SecondImplRefShortcut
) {
677 scoped_refptr
<TextureLayer
> test_layer
= TextureLayer::CreateForMailbox(NULL
);
678 ASSERT_TRUE(test_layer
.get());
680 main_thread_
.message_loop()->PostTask(
682 base::Bind(&TextureLayerMailboxHolderTest::CreateMainRef
,
683 base::Unretained(this)));
687 // The texture layer is attached to compositor1, and passes a reference to its
689 scoped_ptr
<SingleReleaseCallback
> compositor1
;
690 main_thread_
.message_loop()->PostTask(
692 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef
,
693 base::Unretained(this),
696 // Then the texture layer is removed and attached to compositor2, and passes a
697 // reference to its impl tree.
698 scoped_ptr
<SingleReleaseCallback
> compositor2
;
699 main_thread_
.message_loop()->PostTask(
701 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef
,
702 base::Unretained(this),
706 Mock::VerifyAndClearExpectations(&test_data_
.mock_callback_
);
708 // The main thread reference is destroyed first.
709 main_thread_
.message_loop()->PostTask(
711 base::Bind(&TextureLayerMailboxHolderTest::ReleaseMainRef
,
712 base::Unretained(this)));
714 EXPECT_CALL(test_data_
.mock_callback_
,
715 Release(test_data_
.mailbox_name1_
, 200, true)).Times(1);
717 bool manual_reset
= false;
718 bool initially_signaled
= false;
719 base::WaitableEvent
begin_capture(manual_reset
, initially_signaled
);
720 base::WaitableEvent
wait_for_capture(manual_reset
, initially_signaled
);
721 base::WaitableEvent
stop_capture(manual_reset
, initially_signaled
);
723 // Post a task to start capturing tasks on the main thread. This will block
724 // the main thread until we signal the |stop_capture| event.
725 main_thread_
.message_loop()->PostTask(
727 base::Bind(&TextureLayerMailboxHolderTest::CapturePostTasksAndWait
,
728 base::Unretained(this),
733 // Before the main thread capturing starts, one compositor destroys their
734 // impl reference. Since capturing did not start, this gets post-tasked to
736 compositor1
->Run(100, false);
738 // Start capturing on the main thread.
739 begin_capture
.Signal();
740 wait_for_capture
.Wait();
742 // Meanwhile, the second compositor released its impl reference, but this task
743 // gets shortcutted directly to the main thread. This means the reference is
744 // released before compositor1, whose reference will be released later when
745 // the post-task is serviced. But since it was destroyed _on the impl thread_
746 // last, its sync point values should be used.
747 compositor2
->Run(200, true);
749 stop_capture
.Signal();
752 Mock::VerifyAndClearExpectations(&test_data_
.mock_callback_
);
755 class TextureLayerImplWithMailboxThreadedCallback
: public LayerTreeTest
{
757 TextureLayerImplWithMailboxThreadedCallback()
758 : callback_count_(0),
761 // Make sure callback is received on main and doesn't block the impl thread.
762 void ReleaseCallback(uint32 sync_point
, bool lost_resource
) {
763 EXPECT_EQ(true, main_thread_
.CalledOnValidThread());
764 EXPECT_FALSE(lost_resource
);
768 void SetMailbox(char mailbox_char
) {
769 EXPECT_EQ(true, main_thread_
.CalledOnValidThread());
770 scoped_ptr
<SingleReleaseCallback
> callback
= SingleReleaseCallback::Create(
772 &TextureLayerImplWithMailboxThreadedCallback::ReleaseCallback
,
773 base::Unretained(this)));
774 layer_
->SetTextureMailbox(
775 TextureMailbox(MailboxFromChar(mailbox_char
), GL_TEXTURE_2D
, 0),
779 virtual void BeginTest() OVERRIDE
{
780 EXPECT_EQ(true, main_thread_
.CalledOnValidThread());
782 gfx::Size
bounds(100, 100);
783 root_
= Layer::Create();
784 root_
->SetAnchorPoint(gfx::PointF());
785 root_
->SetBounds(bounds
);
787 layer_
= TextureLayer::CreateForMailbox(NULL
);
788 layer_
->SetIsDrawable(true);
789 layer_
->SetAnchorPoint(gfx::PointF());
790 layer_
->SetBounds(bounds
);
792 root_
->AddChild(layer_
);
793 layer_tree_host()->SetRootLayer(root_
);
794 layer_tree_host()->SetViewportSize(bounds
);
796 EXPECT_EQ(0, callback_count_
);
798 // Case #1: change mailbox before the commit. The old mailbox should be
799 // released immediately.
801 EXPECT_EQ(1, callback_count_
);
802 PostSetNeedsCommitToMainThread();
805 virtual void DidCommit() OVERRIDE
{
807 switch (commit_count_
) {
809 // Case #2: change mailbox after the commit (and draw), where the
810 // layer draws. The old mailbox should be released during the next
813 EXPECT_EQ(1, callback_count_
);
816 EXPECT_EQ(2, callback_count_
);
817 // Case #3: change mailbox when the layer doesn't draw. The old
818 // mailbox should be released during the next commit.
819 layer_
->SetBounds(gfx::Size());
823 EXPECT_EQ(3, callback_count_
);
824 // Case #4: release mailbox that was committed but never drawn. The
825 // old mailbox should be released during the next commit.
826 layer_
->SetTextureMailbox(TextureMailbox(),
827 scoped_ptr
<SingleReleaseCallback
>());
830 if (layer_tree_host()->settings().impl_side_painting
) {
831 // With impl painting, the texture mailbox will still be on the impl
832 // thread when the commit finishes, because the layer is not drawble
833 // when it has no texture mailbox, and thus does not block the commit
834 // on activation. So, we wait for activation.
835 // TODO(danakj): fix this. crbug.com/277953
836 layer_tree_host()->SetNeedsCommit();
842 EXPECT_EQ(4, callback_count_
);
843 // Restore a mailbox for the next step.
847 // Case #5: remove layer from tree. Callback should *not* be called, the
848 // mailbox is returned to the main thread.
849 EXPECT_EQ(4, callback_count_
);
850 layer_
->RemoveFromParent();
853 if (layer_tree_host()->settings().impl_side_painting
) {
854 // With impl painting, the texture mailbox will still be on the impl
855 // thread when the commit finishes, because the layer is not around to
856 // block the commit on activation anymore. So, we wait for activation.
857 // TODO(danakj): fix this. crbug.com/277953
858 layer_tree_host()->SetNeedsCommit();
864 EXPECT_EQ(4, callback_count_
);
865 // Resetting the mailbox will call the callback now.
866 layer_
->SetTextureMailbox(TextureMailbox(),
867 scoped_ptr
<SingleReleaseCallback
>());
868 EXPECT_EQ(5, callback_count_
);
877 virtual void AfterTest() OVERRIDE
{}
880 base::ThreadChecker main_thread_
;
883 scoped_refptr
<Layer
> root_
;
884 scoped_refptr
<TextureLayer
> layer_
;
887 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
888 TextureLayerImplWithMailboxThreadedCallback
);
891 class TextureLayerNoMailboxIsActivatedDuringCommit
: public LayerTreeTest
,
892 public TextureLayerClient
{
894 TextureLayerNoMailboxIsActivatedDuringCommit()
895 : texture_(0u), activate_count_(0) {}
897 virtual void BeginTest() OVERRIDE
{
898 gfx::Size
bounds(100, 100);
899 root_
= Layer::Create();
900 root_
->SetAnchorPoint(gfx::PointF());
901 root_
->SetBounds(bounds
);
903 layer_
= TextureLayer::Create(this);
904 layer_
->SetIsDrawable(true);
905 layer_
->SetAnchorPoint(gfx::PointF());
906 layer_
->SetBounds(bounds
);
908 root_
->AddChild(layer_
);
909 layer_tree_host()->SetRootLayer(root_
);
910 layer_tree_host()->SetViewportSize(bounds
);
912 PostSetNeedsCommitToMainThread();
915 virtual scoped_ptr
<FakeOutputSurface
> CreateFakeOutputSurface(bool fallback
)
917 scoped_refptr
<TestContextProvider
> provider
= TestContextProvider::Create();
918 texture_
= provider
->UnboundTestContext3d()->createExternalTexture();
919 return FakeOutputSurface::Create3d(provider
);
922 // TextureLayerClient implementation.
923 virtual unsigned PrepareTexture() OVERRIDE
{
926 virtual bool PrepareTextureMailbox(
927 TextureMailbox
* mailbox
,
928 scoped_ptr
<SingleReleaseCallback
>* release_callback
,
929 bool use_shared_memory
) OVERRIDE
{
933 virtual void WillActivateTreeOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
937 virtual void DidCommit() OVERRIDE
{
938 switch (layer_tree_host()->source_frame_number()) {
940 // The first texture has been activated. Invalidate the layer so it
941 // grabs a new texture id from the client.
942 layer_
->SetNeedsDisplay();
945 // The second mailbox has been activated. Remove the layer from
946 // the tree to cause another commit/activation. The commit should
947 // finish *after* the layer is removed from the active tree.
948 layer_
->RemoveFromParent();
956 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* host_impl
) OVERRIDE
{
957 switch (host_impl
->active_tree()->source_frame_number()) {
959 // The activate for the 2nd texture should have happened before now.
960 EXPECT_EQ(2, activate_count_
);
964 // The activate to remove the layer should have happened before now.
965 EXPECT_EQ(3, activate_count_
);
971 virtual void AfterTest() OVERRIDE
{}
975 scoped_refptr
<Layer
> root_
;
976 scoped_refptr
<TextureLayer
> layer_
;
979 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
980 TextureLayerNoMailboxIsActivatedDuringCommit
);
982 class TextureLayerMailboxIsActivatedDuringCommit
: public LayerTreeTest
{
984 TextureLayerMailboxIsActivatedDuringCommit() : activate_count_(0) {}
986 static void ReleaseCallback(uint32 sync_point
, bool lost_resource
) {}
988 void SetMailbox(char mailbox_char
) {
989 scoped_ptr
<SingleReleaseCallback
> callback
= SingleReleaseCallback::Create(
991 &TextureLayerMailboxIsActivatedDuringCommit::ReleaseCallback
));
992 layer_
->SetTextureMailbox(
993 TextureMailbox(MailboxFromChar(mailbox_char
), GL_TEXTURE_2D
, 0),
997 virtual void BeginTest() OVERRIDE
{
998 gfx::Size
bounds(100, 100);
999 root_
= Layer::Create();
1000 root_
->SetAnchorPoint(gfx::PointF());
1001 root_
->SetBounds(bounds
);
1003 layer_
= TextureLayer::CreateForMailbox(NULL
);
1004 layer_
->SetIsDrawable(true);
1005 layer_
->SetAnchorPoint(gfx::PointF());
1006 layer_
->SetBounds(bounds
);
1008 root_
->AddChild(layer_
);
1009 layer_tree_host()->SetRootLayer(root_
);
1010 layer_tree_host()->SetViewportSize(bounds
);
1013 PostSetNeedsCommitToMainThread();
1016 virtual void WillActivateTreeOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
1020 virtual void DidCommit() OVERRIDE
{
1021 switch (layer_tree_host()->source_frame_number()) {
1023 // The first mailbox has been activated. Set a new mailbox, and
1024 // expect the next commit to finish *after* it is activated.
1028 // The second mailbox has been activated. Remove the layer from
1029 // the tree to cause another commit/activation. The commit should
1030 // finish *after* the layer is removed from the active tree.
1031 layer_
->RemoveFromParent();
1039 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* host_impl
) OVERRIDE
{
1040 switch (host_impl
->active_tree()->source_frame_number()) {
1042 // The activate for the 2nd mailbox should have happened before now.
1043 EXPECT_EQ(2, activate_count_
);
1047 // The activate to remove the layer should have happened before now.
1048 EXPECT_EQ(3, activate_count_
);
1055 virtual void AfterTest() OVERRIDE
{}
1057 int activate_count_
;
1058 scoped_refptr
<Layer
> root_
;
1059 scoped_refptr
<TextureLayer
> layer_
;
1062 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
1063 TextureLayerMailboxIsActivatedDuringCommit
);
1065 class TextureLayerImplWithMailboxTest
: public TextureLayerTest
{
1067 TextureLayerImplWithMailboxTest()
1069 FakeLayerTreeHostClient(FakeLayerTreeHostClient::DIRECT_3D
)) {}
1071 virtual void SetUp() {
1072 TextureLayerTest::SetUp();
1073 layer_tree_host_
.reset(new MockLayerTreeHost(&fake_client_
));
1074 EXPECT_TRUE(host_impl_
.InitializeRenderer(
1075 FakeOutputSurface::Create3d().PassAs
<OutputSurface
>()));
1078 bool WillDraw(TextureLayerImpl
* layer
, DrawMode mode
) {
1079 bool will_draw
= layer
->WillDraw(
1080 mode
, host_impl_
.active_tree()->resource_provider());
1082 layer
->DidDraw(host_impl_
.active_tree()->resource_provider());
1086 CommonMailboxObjects test_data_
;
1087 FakeLayerTreeHostClient fake_client_
;
1090 // Test conditions for results of TextureLayerImpl::WillDraw under
1091 // different configurations of different mailbox, texture_id, and draw_mode.
1092 TEST_F(TextureLayerImplWithMailboxTest
, TestWillDraw
) {
1093 EXPECT_CALL(test_data_
.mock_callback_
,
1094 Release(test_data_
.mailbox_name1_
,
1095 test_data_
.sync_point1_
,
1097 .Times(AnyNumber());
1098 EXPECT_CALL(test_data_
.mock_callback_
,
1099 Release2(test_data_
.shared_memory_
.get(), 0, false))
1100 .Times(AnyNumber());
1103 scoped_ptr
<TextureLayerImpl
> impl_layer
=
1104 TextureLayerImpl::Create(host_impl_
.active_tree(), 1, true);
1105 impl_layer
->SetDrawsContent(true);
1106 impl_layer
->SetTextureMailbox(
1107 test_data_
.mailbox1_
,
1108 SingleReleaseCallback::Create(test_data_
.release_mailbox1_
));
1109 EXPECT_TRUE(WillDraw(impl_layer
.get(), DRAW_MODE_HARDWARE
));
1113 scoped_ptr
<TextureLayerImpl
> impl_layer
=
1114 TextureLayerImpl::Create(host_impl_
.active_tree(), 1, true);
1115 impl_layer
->SetDrawsContent(true);
1116 impl_layer
->SetTextureMailbox(TextureMailbox(),
1117 scoped_ptr
<SingleReleaseCallback
>());
1118 EXPECT_FALSE(WillDraw(impl_layer
.get(), DRAW_MODE_HARDWARE
));
1122 // Software resource.
1123 scoped_ptr
<TextureLayerImpl
> impl_layer
=
1124 TextureLayerImpl::Create(host_impl_
.active_tree(), 1, true);
1125 impl_layer
->SetDrawsContent(true);
1126 impl_layer
->SetTextureMailbox(
1127 test_data_
.mailbox3_
,
1128 SingleReleaseCallback::Create(test_data_
.release_mailbox3_
));
1129 EXPECT_TRUE(WillDraw(impl_layer
.get(), DRAW_MODE_HARDWARE
));
1133 scoped_ptr
<TextureLayerImpl
> impl_layer
=
1134 TextureLayerImpl::Create(host_impl_
.active_tree(), 1, false);
1135 impl_layer
->SetDrawsContent(true);
1136 ContextProvider
* context_provider
=
1137 host_impl_
.output_surface()->context_provider();
1139 context_provider
->ContextGL()->GenTextures(1, &texture
);
1140 impl_layer
->SetTextureId(texture
);
1141 EXPECT_TRUE(WillDraw(impl_layer
.get(), DRAW_MODE_HARDWARE
));
1145 scoped_ptr
<TextureLayerImpl
> impl_layer
=
1146 TextureLayerImpl::Create(host_impl_
.active_tree(), 1, false);
1147 impl_layer
->SetDrawsContent(true);
1148 impl_layer
->SetTextureId(0);
1149 EXPECT_FALSE(WillDraw(impl_layer
.get(), DRAW_MODE_HARDWARE
));
1154 scoped_ptr
<TextureLayerImpl
> impl_layer
=
1155 TextureLayerImpl::Create(host_impl_
.active_tree(), 1, true);
1156 impl_layer
->SetDrawsContent(true);
1157 impl_layer
->SetTextureMailbox(
1158 test_data_
.mailbox1_
,
1159 SingleReleaseCallback::Create(test_data_
.release_mailbox1_
));
1160 EXPECT_FALSE(WillDraw(impl_layer
.get(), DRAW_MODE_SOFTWARE
));
1164 scoped_ptr
<TextureLayerImpl
> impl_layer
=
1165 TextureLayerImpl::Create(host_impl_
.active_tree(), 1, true);
1166 impl_layer
->SetDrawsContent(true);
1167 impl_layer
->SetTextureMailbox(TextureMailbox(),
1168 scoped_ptr
<SingleReleaseCallback
>());
1169 EXPECT_FALSE(WillDraw(impl_layer
.get(), DRAW_MODE_SOFTWARE
));
1173 // Software resource.
1174 scoped_ptr
<TextureLayerImpl
> impl_layer
=
1175 TextureLayerImpl::Create(host_impl_
.active_tree(), 1, true);
1176 impl_layer
->SetDrawsContent(true);
1177 impl_layer
->SetTextureMailbox(
1178 test_data_
.mailbox3_
,
1179 SingleReleaseCallback::Create(test_data_
.release_mailbox3_
));
1180 EXPECT_TRUE(WillDraw(impl_layer
.get(), DRAW_MODE_SOFTWARE
));
1184 scoped_ptr
<TextureLayerImpl
> impl_layer
=
1185 TextureLayerImpl::Create(host_impl_
.active_tree(), 1, false);
1186 impl_layer
->SetDrawsContent(true);
1187 ContextProvider
* context_provider
=
1188 host_impl_
.output_surface()->context_provider();
1190 context_provider
->ContextGL()->GenTextures(1, &texture
);
1191 impl_layer
->SetTextureId(texture
);
1192 EXPECT_FALSE(WillDraw(impl_layer
.get(), DRAW_MODE_SOFTWARE
));
1196 scoped_ptr
<TextureLayerImpl
> impl_layer
=
1197 TextureLayerImpl::Create(host_impl_
.active_tree(), 1, false);
1198 impl_layer
->SetDrawsContent(true);
1199 impl_layer
->SetTextureId(0);
1200 EXPECT_FALSE(WillDraw(impl_layer
.get(), DRAW_MODE_SOFTWARE
));
1203 // Resourceless software mode.
1205 scoped_ptr
<TextureLayerImpl
> impl_layer
=
1206 TextureLayerImpl::Create(host_impl_
.active_tree(), 1, true);
1207 impl_layer
->SetDrawsContent(true);
1208 impl_layer
->SetTextureMailbox(
1209 test_data_
.mailbox1_
,
1210 SingleReleaseCallback::Create(test_data_
.release_mailbox1_
));
1211 EXPECT_FALSE(WillDraw(impl_layer
.get(), DRAW_MODE_RESOURCELESS_SOFTWARE
));
1215 scoped_ptr
<TextureLayerImpl
> impl_layer
=
1216 TextureLayerImpl::Create(host_impl_
.active_tree(), 1, false);
1217 impl_layer
->SetDrawsContent(true);
1218 ContextProvider
* context_provider
=
1219 host_impl_
.output_surface()->context_provider();
1221 context_provider
->ContextGL()->GenTextures(1, &texture
);
1222 impl_layer
->SetTextureId(texture
);
1223 EXPECT_FALSE(WillDraw(impl_layer
.get(), DRAW_MODE_RESOURCELESS_SOFTWARE
));
1227 TEST_F(TextureLayerImplWithMailboxTest
, TestImplLayerCallbacks
) {
1228 host_impl_
.CreatePendingTree();
1229 scoped_ptr
<TextureLayerImpl
> pending_layer
;
1230 pending_layer
= TextureLayerImpl::Create(host_impl_
.pending_tree(), 1, true);
1231 ASSERT_TRUE(pending_layer
);
1233 scoped_ptr
<LayerImpl
> active_layer(
1234 pending_layer
->CreateLayerImpl(host_impl_
.active_tree()));
1235 ASSERT_TRUE(active_layer
);
1237 pending_layer
->SetTextureMailbox(
1238 test_data_
.mailbox1_
,
1239 SingleReleaseCallback::Create(test_data_
.release_mailbox1_
));
1241 // Test multiple commits without an activation.
1242 EXPECT_CALL(test_data_
.mock_callback_
,
1243 Release(test_data_
.mailbox_name1_
,
1244 test_data_
.sync_point1_
,
1247 pending_layer
->SetTextureMailbox(
1248 test_data_
.mailbox2_
,
1249 SingleReleaseCallback::Create(test_data_
.release_mailbox2_
));
1250 Mock::VerifyAndClearExpectations(&test_data_
.mock_callback_
);
1252 // Test callback after activation.
1253 pending_layer
->PushPropertiesTo(active_layer
.get());
1254 active_layer
->DidBecomeActive();
1256 EXPECT_CALL(test_data_
.mock_callback_
, Release(_
, _
, _
)).Times(0);
1257 pending_layer
->SetTextureMailbox(
1258 test_data_
.mailbox1_
,
1259 SingleReleaseCallback::Create(test_data_
.release_mailbox1_
));
1260 Mock::VerifyAndClearExpectations(&test_data_
.mock_callback_
);
1262 EXPECT_CALL(test_data_
.mock_callback_
,
1263 Release(test_data_
.mailbox_name2_
, _
, false))
1265 pending_layer
->PushPropertiesTo(active_layer
.get());
1266 active_layer
->DidBecomeActive();
1267 Mock::VerifyAndClearExpectations(&test_data_
.mock_callback_
);
1269 // Test resetting the mailbox.
1270 EXPECT_CALL(test_data_
.mock_callback_
,
1271 Release(test_data_
.mailbox_name1_
, _
, false))
1273 pending_layer
->SetTextureMailbox(TextureMailbox(),
1274 scoped_ptr
<SingleReleaseCallback
>());
1275 pending_layer
->PushPropertiesTo(active_layer
.get());
1276 active_layer
->DidBecomeActive();
1277 Mock::VerifyAndClearExpectations(&test_data_
.mock_callback_
);
1280 EXPECT_CALL(test_data_
.mock_callback_
,
1281 Release(test_data_
.mailbox_name1_
,
1282 test_data_
.sync_point1_
,
1285 pending_layer
->SetTextureMailbox(
1286 test_data_
.mailbox1_
,
1287 SingleReleaseCallback::Create(test_data_
.release_mailbox1_
));
1290 TEST_F(TextureLayerImplWithMailboxTest
,
1291 TestDestructorCallbackOnCreatedResource
) {
1292 scoped_ptr
<TextureLayerImpl
> impl_layer
;
1293 impl_layer
= TextureLayerImpl::Create(host_impl_
.active_tree(), 1, true);
1294 ASSERT_TRUE(impl_layer
);
1296 EXPECT_CALL(test_data_
.mock_callback_
,
1297 Release(test_data_
.mailbox_name1_
, _
, false))
1299 impl_layer
->SetTextureMailbox(
1300 test_data_
.mailbox1_
,
1301 SingleReleaseCallback::Create(test_data_
.release_mailbox1_
));
1302 impl_layer
->SetDrawsContent(true);
1303 impl_layer
->DidBecomeActive();
1304 EXPECT_TRUE(impl_layer
->WillDraw(
1305 DRAW_MODE_HARDWARE
, host_impl_
.active_tree()->resource_provider()));
1306 impl_layer
->DidDraw(host_impl_
.active_tree()->resource_provider());
1307 impl_layer
->SetTextureMailbox(TextureMailbox(),
1308 scoped_ptr
<SingleReleaseCallback
>());
1311 TEST_F(TextureLayerImplWithMailboxTest
, TestCallbackOnInUseResource
) {
1312 ResourceProvider
* provider
= host_impl_
.active_tree()->resource_provider();
1313 ResourceProvider::ResourceId id
=
1314 provider
->CreateResourceFromTextureMailbox(
1315 test_data_
.mailbox1_
,
1316 SingleReleaseCallback::Create(test_data_
.release_mailbox1_
));
1317 provider
->AllocateForTesting(id
);
1319 // Transfer some resources to the parent.
1320 ResourceProvider::ResourceIdArray resource_ids_to_transfer
;
1321 resource_ids_to_transfer
.push_back(id
);
1322 TransferableResourceArray list
;
1323 provider
->PrepareSendToParent(resource_ids_to_transfer
, &list
);
1324 EXPECT_TRUE(provider
->InUseByConsumer(id
));
1325 EXPECT_CALL(test_data_
.mock_callback_
, Release(_
, _
, _
)).Times(0);
1326 provider
->DeleteResource(id
);
1327 Mock::VerifyAndClearExpectations(&test_data_
.mock_callback_
);
1328 EXPECT_CALL(test_data_
.mock_callback_
,
1329 Release(test_data_
.mailbox_name1_
, _
, false))
1331 ReturnedResourceArray returned
;
1332 TransferableResource::ReturnResources(list
, &returned
);
1333 provider
->ReceiveReturnsFromParent(returned
);
1336 // Check that ClearClient correctly clears the state so that the impl side
1337 // doesn't try to use a texture that could have been destroyed.
1338 class TextureLayerClientTest
1339 : public LayerTreeTest
,
1340 public TextureLayerClient
{
1342 TextureLayerClientTest()
1345 expected_used_textures_on_draw_(0),
1346 expected_used_textures_on_commit_(0) {}
1348 virtual scoped_ptr
<FakeOutputSurface
> CreateFakeOutputSurface(bool fallback
)
1350 scoped_refptr
<TestContextProvider
> provider
= TestContextProvider::Create();
1351 texture_
= provider
->UnboundTestContext3d()->createExternalTexture();
1352 return FakeOutputSurface::Create3d(provider
);
1355 virtual unsigned PrepareTexture() OVERRIDE
{ return texture_
; }
1357 virtual bool PrepareTextureMailbox(
1358 TextureMailbox
* mailbox
,
1359 scoped_ptr
<SingleReleaseCallback
>* release_callback
,
1360 bool use_shared_memory
) OVERRIDE
{
1364 virtual void SetupTree() OVERRIDE
{
1365 scoped_refptr
<Layer
> root
= Layer::Create();
1366 root
->SetBounds(gfx::Size(10, 10));
1367 root
->SetAnchorPoint(gfx::PointF());
1368 root
->SetIsDrawable(true);
1370 texture_layer_
= TextureLayer::Create(this);
1371 texture_layer_
->SetBounds(gfx::Size(10, 10));
1372 texture_layer_
->SetAnchorPoint(gfx::PointF());
1373 texture_layer_
->SetIsDrawable(true);
1374 root
->AddChild(texture_layer_
);
1376 layer_tree_host()->SetRootLayer(root
);
1377 LayerTreeTest::SetupTree();
1379 base::AutoLock
lock(lock_
);
1380 expected_used_textures_on_commit_
= 1;
1384 virtual void BeginTest() OVERRIDE
{
1385 PostSetNeedsCommitToMainThread();
1388 virtual void DidCommitAndDrawFrame() OVERRIDE
{
1390 switch (commit_count_
) {
1392 texture_layer_
->ClearClient();
1393 texture_layer_
->SetNeedsDisplay();
1395 base::AutoLock
lock(lock_
);
1396 expected_used_textures_on_commit_
= 0;
1408 virtual void BeginCommitOnThread(LayerTreeHostImpl
* host_impl
) OVERRIDE
{
1409 base::AutoLock
lock(lock_
);
1410 expected_used_textures_on_draw_
= expected_used_textures_on_commit_
;
1413 virtual DrawSwapReadbackResult::DrawResult
PrepareToDrawOnThread(
1414 LayerTreeHostImpl
* host_impl
,
1415 LayerTreeHostImpl::FrameData
* frame_data
,
1416 DrawSwapReadbackResult::DrawResult draw_result
) OVERRIDE
{
1417 ContextForImplThread(host_impl
)->ResetUsedTextures();
1418 return DrawSwapReadbackResult::DRAW_SUCCESS
;
1421 virtual void SwapBuffersOnThread(LayerTreeHostImpl
* host_impl
,
1422 bool result
) OVERRIDE
{
1423 ASSERT_TRUE(result
);
1424 EXPECT_EQ(expected_used_textures_on_draw_
,
1425 ContextForImplThread(host_impl
)->NumUsedTextures());
1428 virtual void AfterTest() OVERRIDE
{}
1431 TestWebGraphicsContext3D
* ContextForImplThread(LayerTreeHostImpl
* host_impl
) {
1432 return static_cast<TestContextProvider
*>(
1433 host_impl
->output_surface()->context_provider().get())->TestContext3d();
1436 scoped_refptr
<TextureLayer
> texture_layer_
;
1440 // Used only on thread.
1441 unsigned expected_used_textures_on_draw_
;
1443 // Used on either thread, protected by lock_.
1445 unsigned expected_used_textures_on_commit_
;
1448 // The TextureLayerClient does not use mailboxes, so can't use a delegating
1450 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(TextureLayerClientTest
);
1453 // Checks that changing a texture in the client for a TextureLayer that's
1454 // invisible correctly works without drawing a deleted texture. See
1456 class TextureLayerChangeInvisibleTest
1457 : public LayerTreeTest
,
1458 public TextureLayerClient
{
1460 TextureLayerChangeInvisibleTest()
1464 expected_texture_on_draw_(0) {}
1466 virtual scoped_ptr
<FakeOutputSurface
> CreateFakeOutputSurface(bool fallback
)
1468 scoped_refptr
<TestContextProvider
> provider
= TestContextProvider::Create();
1469 texture_
= provider
->UnboundTestContext3d()->createExternalTexture();
1470 return FakeOutputSurface::Create3d(provider
);
1473 // TextureLayerClient implementation.
1474 virtual unsigned PrepareTexture() OVERRIDE
{
1478 virtual bool PrepareTextureMailbox(
1479 TextureMailbox
* mailbox
,
1480 scoped_ptr
<SingleReleaseCallback
>* release_callback
,
1481 bool use_shared_memory
) OVERRIDE
{
1485 virtual void SetupTree() OVERRIDE
{
1486 scoped_refptr
<Layer
> root
= Layer::Create();
1487 root
->SetBounds(gfx::Size(10, 10));
1488 root
->SetAnchorPoint(gfx::PointF());
1489 root
->SetIsDrawable(true);
1491 solid_layer_
= SolidColorLayer::Create();
1492 solid_layer_
->SetBounds(gfx::Size(10, 10));
1493 solid_layer_
->SetIsDrawable(true);
1494 solid_layer_
->SetBackgroundColor(SK_ColorWHITE
);
1495 root
->AddChild(solid_layer_
);
1497 parent_layer_
= Layer::Create();
1498 parent_layer_
->SetBounds(gfx::Size(10, 10));
1499 parent_layer_
->SetIsDrawable(true);
1500 root
->AddChild(parent_layer_
);
1502 texture_layer_
= TextureLayer::Create(this);
1503 texture_layer_
->SetBounds(gfx::Size(10, 10));
1504 texture_layer_
->SetAnchorPoint(gfx::PointF());
1505 texture_layer_
->SetIsDrawable(true);
1506 parent_layer_
->AddChild(texture_layer_
);
1508 layer_tree_host()->SetRootLayer(root
);
1509 LayerTreeTest::SetupTree();
1512 virtual void BeginTest() OVERRIDE
{
1513 PostSetNeedsCommitToMainThread();
1516 virtual void DidCommitAndDrawFrame() OVERRIDE
{
1518 switch (commit_count_
) {
1520 // We should have updated the layer, committing the texture.
1521 EXPECT_EQ(1, prepare_called_
);
1522 // Make layer invisible.
1523 parent_layer_
->SetOpacity(0.f
);
1526 // Layer shouldn't have been updated.
1527 EXPECT_EQ(1, prepare_called_
);
1528 texture_layer_
->SetNeedsDisplay();
1529 // Force a change to make sure we draw a frame.
1530 solid_layer_
->SetBackgroundColor(SK_ColorGRAY
);
1534 EXPECT_EQ(1, prepare_called_
);
1535 // Make layer visible again.
1536 parent_layer_
->SetOpacity(1.f
);
1539 // Layer should have been updated.
1540 EXPECT_EQ(2, prepare_called_
);
1541 texture_layer_
->ClearClient();
1554 virtual void BeginCommitOnThread(LayerTreeHostImpl
* host_impl
) OVERRIDE
{
1555 ASSERT_TRUE(proxy()->IsMainThreadBlocked());
1556 // This is the only texture that can be drawn this frame.
1557 expected_texture_on_draw_
= texture_
;
1560 virtual DrawSwapReadbackResult::DrawResult
PrepareToDrawOnThread(
1561 LayerTreeHostImpl
* host_impl
,
1562 LayerTreeHostImpl::FrameData
* frame_data
,
1563 DrawSwapReadbackResult::DrawResult draw_result
) OVERRIDE
{
1564 ContextForImplThread(host_impl
)->ResetUsedTextures();
1565 return DrawSwapReadbackResult::DRAW_SUCCESS
;
1568 virtual void SwapBuffersOnThread(LayerTreeHostImpl
* host_impl
,
1569 bool result
) OVERRIDE
{
1570 ASSERT_TRUE(result
);
1571 TestWebGraphicsContext3D
* context
= ContextForImplThread(host_impl
);
1572 int used_textures
= context
->NumUsedTextures();
1573 switch (host_impl
->active_tree()->source_frame_number()) {
1575 EXPECT_EQ(1, used_textures
);
1576 EXPECT_TRUE(context
->UsedTexture(expected_texture_on_draw_
));
1580 EXPECT_EQ(0, used_textures
);
1583 EXPECT_EQ(1, used_textures
);
1584 EXPECT_TRUE(context
->UsedTexture(expected_texture_on_draw_
));
1591 virtual void AfterTest() OVERRIDE
{}
1594 TestWebGraphicsContext3D
* ContextForImplThread(LayerTreeHostImpl
* host_impl
) {
1595 return static_cast<TestContextProvider
*>(
1596 host_impl
->output_surface()->context_provider().get())->TestContext3d();
1599 scoped_refptr
<SolidColorLayer
> solid_layer_
;
1600 scoped_refptr
<Layer
> parent_layer_
;
1601 scoped_refptr
<TextureLayer
> texture_layer_
;
1603 // Used on the main thread, and on the impl thread while the main thread is
1607 // Used on the main thread.
1608 int prepare_called_
;
1611 // Used on the compositor thread.
1612 unsigned expected_texture_on_draw_
;
1615 // The TextureLayerChangeInvisibleTest does not use mailboxes, so can't use a
1616 // delegating renderer.
1617 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(TextureLayerChangeInvisibleTest
);
1619 // Checks that TextureLayer::Update does not cause an extra commit when setting
1620 // the texture mailbox.
1621 class TextureLayerNoExtraCommitForMailboxTest
1622 : public LayerTreeTest
,
1623 public TextureLayerClient
{
1625 // TextureLayerClient implementation.
1626 virtual unsigned PrepareTexture() OVERRIDE
{
1630 virtual bool PrepareTextureMailbox(
1631 TextureMailbox
* texture_mailbox
,
1632 scoped_ptr
<SingleReleaseCallback
>* release_callback
,
1633 bool use_shared_memory
) OVERRIDE
{
1634 if (layer_tree_host()->source_frame_number() == 1) {
1635 *texture_mailbox
= TextureMailbox();
1639 *texture_mailbox
= TextureMailbox(MailboxFromChar('1'), GL_TEXTURE_2D
, 0);
1640 *release_callback
= SingleReleaseCallback::Create(
1641 base::Bind(&TextureLayerNoExtraCommitForMailboxTest::MailboxReleased
,
1642 base::Unretained(this)));
1646 void MailboxReleased(uint32 sync_point
, bool lost_resource
) {
1647 EXPECT_EQ(2, layer_tree_host()->source_frame_number());
1651 virtual void SetupTree() OVERRIDE
{
1652 scoped_refptr
<Layer
> root
= Layer::Create();
1653 root
->SetBounds(gfx::Size(10, 10));
1654 root
->SetAnchorPoint(gfx::PointF());
1655 root
->SetIsDrawable(true);
1657 texture_layer_
= TextureLayer::CreateForMailbox(this);
1658 texture_layer_
->SetBounds(gfx::Size(10, 10));
1659 texture_layer_
->SetAnchorPoint(gfx::PointF());
1660 texture_layer_
->SetIsDrawable(true);
1661 root
->AddChild(texture_layer_
);
1663 layer_tree_host()->SetRootLayer(root
);
1664 LayerTreeTest::SetupTree();
1667 virtual void BeginTest() OVERRIDE
{
1668 PostSetNeedsCommitToMainThread();
1671 virtual void DidCommitAndDrawFrame() OVERRIDE
{
1672 switch (layer_tree_host()->source_frame_number()) {
1674 EXPECT_FALSE(proxy()->CommitPendingForTesting());
1675 // Invalidate the texture layer to clear the mailbox before
1677 texture_layer_
->SetNeedsDisplay();
1687 virtual void SwapBuffersOnThread(LayerTreeHostImpl
* host_impl
,
1688 bool result
) OVERRIDE
{
1689 ASSERT_TRUE(result
);
1690 DelegatedFrameData
* delegated_frame_data
=
1691 output_surface()->last_sent_frame().delegated_frame_data
.get();
1692 if (!delegated_frame_data
)
1695 // Return all resources immediately.
1696 TransferableResourceArray resources_to_return
=
1697 output_surface()->resources_held_by_parent();
1699 CompositorFrameAck ack
;
1700 for (size_t i
= 0; i
< resources_to_return
.size(); ++i
)
1701 output_surface()->ReturnResource(resources_to_return
[i
].id
, &ack
);
1702 host_impl
->ReclaimResources(&ack
);
1703 host_impl
->OnSwapBuffersComplete();
1706 virtual void AfterTest() OVERRIDE
{}
1709 scoped_refptr
<TextureLayer
> texture_layer_
;
1712 SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerNoExtraCommitForMailboxTest
);
1714 // Checks that changing a mailbox in the client for a TextureLayer that's
1715 // invisible correctly works and uses the new mailbox as soon as the layer
1716 // becomes visible (and returns the old one).
1717 class TextureLayerChangeInvisibleMailboxTest
1718 : public LayerTreeTest
,
1719 public TextureLayerClient
{
1721 TextureLayerChangeInvisibleMailboxTest()
1722 : mailbox_changed_(true),
1723 mailbox_returned_(0),
1726 mailbox_
= MakeMailbox('1');
1729 // TextureLayerClient implementation.
1730 virtual unsigned PrepareTexture() OVERRIDE
{
1735 virtual bool PrepareTextureMailbox(
1736 TextureMailbox
* mailbox
,
1737 scoped_ptr
<SingleReleaseCallback
>* release_callback
,
1738 bool use_shared_memory
) OVERRIDE
{
1740 if (!mailbox_changed_
)
1742 *mailbox
= mailbox_
;
1743 *release_callback
= SingleReleaseCallback::Create(
1744 base::Bind(&TextureLayerChangeInvisibleMailboxTest::MailboxReleased
,
1745 base::Unretained(this)));
1749 TextureMailbox
MakeMailbox(char name
) {
1750 return TextureMailbox(MailboxFromChar(name
), GL_TEXTURE_2D
, 0);
1753 void MailboxReleased(uint32 sync_point
, bool lost_resource
) {
1754 ++mailbox_returned_
;
1757 virtual void SetupTree() OVERRIDE
{
1758 scoped_refptr
<Layer
> root
= Layer::Create();
1759 root
->SetBounds(gfx::Size(10, 10));
1760 root
->SetAnchorPoint(gfx::PointF());
1761 root
->SetIsDrawable(true);
1763 solid_layer_
= SolidColorLayer::Create();
1764 solid_layer_
->SetBounds(gfx::Size(10, 10));
1765 solid_layer_
->SetIsDrawable(true);
1766 solid_layer_
->SetBackgroundColor(SK_ColorWHITE
);
1767 root
->AddChild(solid_layer_
);
1769 parent_layer_
= Layer::Create();
1770 parent_layer_
->SetBounds(gfx::Size(10, 10));
1771 parent_layer_
->SetIsDrawable(true);
1772 root
->AddChild(parent_layer_
);
1774 texture_layer_
= TextureLayer::CreateForMailbox(this);
1775 texture_layer_
->SetBounds(gfx::Size(10, 10));
1776 texture_layer_
->SetAnchorPoint(gfx::PointF());
1777 texture_layer_
->SetIsDrawable(true);
1778 parent_layer_
->AddChild(texture_layer_
);
1780 layer_tree_host()->SetRootLayer(root
);
1781 LayerTreeTest::SetupTree();
1784 virtual void BeginTest() OVERRIDE
{
1785 PostSetNeedsCommitToMainThread();
1788 virtual void DidCommitAndDrawFrame() OVERRIDE
{
1790 switch (commit_count_
) {
1792 // We should have updated the layer, committing the texture.
1793 EXPECT_EQ(1, prepare_called_
);
1794 // Make layer invisible.
1795 parent_layer_
->SetOpacity(0.f
);
1798 // Layer shouldn't have been updated.
1799 EXPECT_EQ(1, prepare_called_
);
1800 // Change the texture.
1801 mailbox_
= MakeMailbox('2');
1802 mailbox_changed_
= true;
1803 texture_layer_
->SetNeedsDisplay();
1804 // Force a change to make sure we draw a frame.
1805 solid_layer_
->SetBackgroundColor(SK_ColorGRAY
);
1808 // Layer shouldn't have been updated.
1809 EXPECT_EQ(1, prepare_called_
);
1810 // So the old mailbox isn't returned yet.
1811 EXPECT_EQ(0, mailbox_returned_
);
1812 // Make layer visible again.
1813 parent_layer_
->SetOpacity(1.f
);
1816 // Layer should have been updated.
1817 EXPECT_EQ(2, prepare_called_
);
1818 // So the old mailbox should have been returned already.
1819 EXPECT_EQ(1, mailbox_returned_
);
1820 texture_layer_
->ClearClient();
1823 EXPECT_EQ(2, mailbox_returned_
);
1832 virtual void SwapBuffersOnThread(LayerTreeHostImpl
* host_impl
,
1833 bool result
) OVERRIDE
{
1834 ASSERT_TRUE(result
);
1835 DelegatedFrameData
* delegated_frame_data
=
1836 output_surface()->last_sent_frame().delegated_frame_data
.get();
1837 if (!delegated_frame_data
)
1840 // Return all resources immediately.
1841 TransferableResourceArray resources_to_return
=
1842 output_surface()->resources_held_by_parent();
1844 CompositorFrameAck ack
;
1845 for (size_t i
= 0; i
< resources_to_return
.size(); ++i
)
1846 output_surface()->ReturnResource(resources_to_return
[i
].id
, &ack
);
1847 host_impl
->ReclaimResources(&ack
);
1848 host_impl
->OnSwapBuffersComplete();
1851 virtual void AfterTest() OVERRIDE
{}
1854 scoped_refptr
<SolidColorLayer
> solid_layer_
;
1855 scoped_refptr
<Layer
> parent_layer_
;
1856 scoped_refptr
<TextureLayer
> texture_layer_
;
1858 // Used on the main thread.
1859 bool mailbox_changed_
;
1860 TextureMailbox mailbox_
;
1861 int mailbox_returned_
;
1862 int prepare_called_
;
1866 SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerChangeInvisibleMailboxTest
);
1868 // Test that TextureLayerImpl::ReleaseResources can be called which releases
1869 // the mailbox back to TextureLayerClient.
1870 class TextureLayerReleaseResourcesBase
1871 : public LayerTreeTest
,
1872 public TextureLayerClient
{
1874 // TextureLayerClient implementation.
1875 virtual unsigned PrepareTexture() OVERRIDE
{
1879 virtual bool PrepareTextureMailbox(
1880 TextureMailbox
* mailbox
,
1881 scoped_ptr
<SingleReleaseCallback
>* release_callback
,
1882 bool use_shared_memory
) OVERRIDE
{
1883 *mailbox
= TextureMailbox(MailboxFromChar('1'), GL_TEXTURE_2D
, 0);
1884 *release_callback
= SingleReleaseCallback::Create(
1885 base::Bind(&TextureLayerReleaseResourcesBase::MailboxReleased
,
1886 base::Unretained(this)));
1890 void MailboxReleased(unsigned sync_point
, bool lost_resource
) {
1891 mailbox_released_
= true;
1894 virtual void SetupTree() OVERRIDE
{
1895 LayerTreeTest::SetupTree();
1897 scoped_refptr
<TextureLayer
> texture_layer
=
1898 TextureLayer::CreateForMailbox(this);
1899 texture_layer
->SetBounds(gfx::Size(10, 10));
1900 texture_layer
->SetAnchorPoint(gfx::PointF());
1901 texture_layer
->SetIsDrawable(true);
1903 layer_tree_host()->root_layer()->AddChild(texture_layer
);
1906 virtual void BeginTest() OVERRIDE
{
1907 mailbox_released_
= false;
1908 PostSetNeedsCommitToMainThread();
1911 virtual void DidCommitAndDrawFrame() OVERRIDE
{
1915 virtual void AfterTest() OVERRIDE
{
1916 EXPECT_TRUE(mailbox_released_
);
1920 bool mailbox_released_
;
1923 class TextureLayerReleaseResourcesAfterCommit
1924 : public TextureLayerReleaseResourcesBase
{
1926 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* host_impl
) OVERRIDE
{
1927 LayerTreeImpl
* tree
= NULL
;
1928 if (host_impl
->settings().impl_side_painting
)
1929 tree
= host_impl
->pending_tree();
1931 tree
= host_impl
->active_tree();
1932 tree
->root_layer()->children()[0]->ReleaseResources();
1936 SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerReleaseResourcesAfterCommit
);
1938 class TextureLayerReleaseResourcesAfterActivate
1939 : public TextureLayerReleaseResourcesBase
{
1941 virtual void DidActivateTreeOnThread(LayerTreeHostImpl
* host_impl
) OVERRIDE
{
1942 host_impl
->active_tree()->root_layer()->children()[0]->ReleaseResources();
1946 SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerReleaseResourcesAfterActivate
);
1948 // Test recovering from a lost context.
1949 class TextureLayerLostContextTest
1950 : public LayerTreeTest
,
1951 public TextureLayerClient
{
1953 TextureLayerLostContextTest()
1954 : context_lost_(false),
1957 virtual scoped_ptr
<FakeOutputSurface
> CreateFakeOutputSurface(bool fallback
)
1959 return FakeOutputSurface::Create3d();
1962 virtual unsigned PrepareTexture() OVERRIDE
{
1963 if (draw_count_
== 0)
1964 context_lost_
= true;
1970 virtual bool PrepareTextureMailbox(
1971 TextureMailbox
* mailbox
,
1972 scoped_ptr
<SingleReleaseCallback
>* release_callback
,
1973 bool use_shared_memory
) OVERRIDE
{
1977 virtual void SetupTree() OVERRIDE
{
1978 scoped_refptr
<Layer
> root
= Layer::Create();
1979 root
->SetBounds(gfx::Size(10, 10));
1980 root
->SetIsDrawable(true);
1982 texture_layer_
= TextureLayer::Create(this);
1983 texture_layer_
->SetBounds(gfx::Size(10, 10));
1984 texture_layer_
->SetIsDrawable(true);
1985 root
->AddChild(texture_layer_
);
1987 layer_tree_host()->SetRootLayer(root
);
1988 LayerTreeTest::SetupTree();
1991 virtual void BeginTest() OVERRIDE
{
1992 PostSetNeedsCommitToMainThread();
1995 virtual DrawSwapReadbackResult::DrawResult
PrepareToDrawOnThread(
1996 LayerTreeHostImpl
* host_impl
,
1997 LayerTreeHostImpl::FrameData
* frame_data
,
1998 DrawSwapReadbackResult::DrawResult draw_result
) OVERRIDE
{
1999 LayerImpl
* root
= host_impl
->RootLayer();
2000 TextureLayerImpl
* texture_layer
=
2001 static_cast<TextureLayerImpl
*>(root
->children()[0]);
2002 if (++draw_count_
== 1)
2003 EXPECT_EQ(0u, texture_layer
->texture_id());
2005 EXPECT_EQ(1u, texture_layer
->texture_id());
2006 return DrawSwapReadbackResult::DRAW_SUCCESS
;
2009 virtual void DidCommitAndDrawFrame() OVERRIDE
{
2013 virtual void AfterTest() OVERRIDE
{}
2016 scoped_refptr
<TextureLayer
> texture_layer_
;
2021 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(TextureLayerLostContextTest
);
2023 class TextureLayerWithMailboxMainThreadDeleted
: public LayerTreeTest
{
2025 void ReleaseCallback(uint32 sync_point
, bool lost_resource
) {
2026 EXPECT_EQ(true, main_thread_
.CalledOnValidThread());
2027 EXPECT_FALSE(lost_resource
);
2032 void SetMailbox(char mailbox_char
) {
2033 EXPECT_EQ(true, main_thread_
.CalledOnValidThread());
2034 scoped_ptr
<SingleReleaseCallback
> callback
= SingleReleaseCallback::Create(
2036 &TextureLayerWithMailboxMainThreadDeleted::ReleaseCallback
,
2037 base::Unretained(this)));
2038 layer_
->SetTextureMailbox(
2039 TextureMailbox(MailboxFromChar(mailbox_char
), GL_TEXTURE_2D
, 0),
2043 virtual void SetupTree() OVERRIDE
{
2044 gfx::Size
bounds(100, 100);
2045 root_
= Layer::Create();
2046 root_
->SetAnchorPoint(gfx::PointF());
2047 root_
->SetBounds(bounds
);
2049 layer_
= TextureLayer::CreateForMailbox(NULL
);
2050 layer_
->SetIsDrawable(true);
2051 layer_
->SetAnchorPoint(gfx::PointF());
2052 layer_
->SetBounds(bounds
);
2054 root_
->AddChild(layer_
);
2055 layer_tree_host()->SetRootLayer(root_
);
2056 layer_tree_host()->SetViewportSize(bounds
);
2059 virtual void BeginTest() OVERRIDE
{
2060 EXPECT_EQ(true, main_thread_
.CalledOnValidThread());
2062 callback_count_
= 0;
2064 // Set the mailbox on the main thread.
2066 EXPECT_EQ(0, callback_count_
);
2068 PostSetNeedsCommitToMainThread();
2071 virtual void DidCommitAndDrawFrame() OVERRIDE
{
2072 switch (layer_tree_host()->source_frame_number()) {
2074 // Delete the TextureLayer on the main thread while the mailbox is in
2076 layer_
->RemoveFromParent();
2082 virtual void AfterTest() OVERRIDE
{
2083 EXPECT_EQ(1, callback_count_
);
2087 base::ThreadChecker main_thread_
;
2088 int callback_count_
;
2089 scoped_refptr
<Layer
> root_
;
2090 scoped_refptr
<TextureLayer
> layer_
;
2093 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
2094 TextureLayerWithMailboxMainThreadDeleted
);
2096 class TextureLayerWithMailboxImplThreadDeleted
: public LayerTreeTest
{
2098 void ReleaseCallback(uint32 sync_point
, bool lost_resource
) {
2099 EXPECT_EQ(true, main_thread_
.CalledOnValidThread());
2100 EXPECT_FALSE(lost_resource
);
2105 void SetMailbox(char mailbox_char
) {
2106 EXPECT_EQ(true, main_thread_
.CalledOnValidThread());
2107 scoped_ptr
<SingleReleaseCallback
> callback
= SingleReleaseCallback::Create(
2109 &TextureLayerWithMailboxImplThreadDeleted::ReleaseCallback
,
2110 base::Unretained(this)));
2111 layer_
->SetTextureMailbox(
2112 TextureMailbox(MailboxFromChar(mailbox_char
), GL_TEXTURE_2D
, 0),
2116 virtual void SetupTree() OVERRIDE
{
2117 gfx::Size
bounds(100, 100);
2118 root_
= Layer::Create();
2119 root_
->SetAnchorPoint(gfx::PointF());
2120 root_
->SetBounds(bounds
);
2122 layer_
= TextureLayer::CreateForMailbox(NULL
);
2123 layer_
->SetIsDrawable(true);
2124 layer_
->SetAnchorPoint(gfx::PointF());
2125 layer_
->SetBounds(bounds
);
2127 root_
->AddChild(layer_
);
2128 layer_tree_host()->SetRootLayer(root_
);
2129 layer_tree_host()->SetViewportSize(bounds
);
2132 virtual void BeginTest() OVERRIDE
{
2133 EXPECT_EQ(true, main_thread_
.CalledOnValidThread());
2135 callback_count_
= 0;
2137 // Set the mailbox on the main thread.
2139 EXPECT_EQ(0, callback_count_
);
2141 PostSetNeedsCommitToMainThread();
2144 virtual void DidCommitAndDrawFrame() OVERRIDE
{
2145 switch (layer_tree_host()->source_frame_number()) {
2147 // Remove the TextureLayer on the main thread while the mailbox is in
2148 // the impl tree, but don't delete the TextureLayer until after the impl
2149 // tree side is deleted.
2150 layer_
->RemoveFromParent();
2158 virtual void AfterTest() OVERRIDE
{
2159 EXPECT_EQ(1, callback_count_
);
2163 base::ThreadChecker main_thread_
;
2164 int callback_count_
;
2165 scoped_refptr
<Layer
> root_
;
2166 scoped_refptr
<TextureLayer
> layer_
;
2169 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
2170 TextureLayerWithMailboxImplThreadDeleted
);