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 class MockLayerTreeHost : public LayerTreeHost {
46 explicit MockLayerTreeHost(FakeLayerTreeHostClient* client)
47 : LayerTreeHost(client, NULL, LayerTreeSettings()) {
48 InitializeSingleThreaded(client);
51 MOCK_METHOD0(AcquireLayerTextures, void());
52 MOCK_METHOD0(SetNeedsCommit, void());
53 MOCK_METHOD0(SetNeedsUpdateLayers, void());
54 MOCK_METHOD0(StartRateLimiter, void());
55 MOCK_METHOD0(StopRateLimiter, void());
58 class TextureLayerTest : public testing::Test {
62 FakeLayerTreeHostClient(FakeLayerTreeHostClient::DIRECT_3D)),
63 host_impl_(&proxy_) {}
66 virtual void SetUp() {
67 layer_tree_host_.reset(new MockLayerTreeHost(&fake_client_));
70 virtual void TearDown() {
71 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
72 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(AnyNumber());
73 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
75 layer_tree_host_->SetRootLayer(NULL);
76 layer_tree_host_.reset();
79 scoped_ptr<MockLayerTreeHost> layer_tree_host_;
81 FakeLayerTreeHostClient fake_client_;
82 FakeLayerTreeHostImpl host_impl_;
85 TEST_F(TextureLayerTest, SyncImplWhenChangingTextureId) {
86 scoped_refptr<TextureLayer> test_layer = TextureLayer::Create(NULL);
87 ASSERT_TRUE(test_layer.get());
89 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(AnyNumber());
90 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
91 layer_tree_host_->SetRootLayer(test_layer);
92 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
93 EXPECT_EQ(test_layer->layer_tree_host(), layer_tree_host_.get());
95 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
96 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
97 test_layer->SetTextureId(1);
98 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
100 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(AtLeast(1));
101 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
102 test_layer->SetTextureId(2);
103 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
105 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(AtLeast(1));
106 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
107 test_layer->SetTextureId(0);
108 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
111 TEST_F(TextureLayerTest, SyncImplWhenDrawing) {
112 gfx::RectF dirty_rect(0.f, 0.f, 1.f, 1.f);
114 scoped_refptr<TextureLayer> test_layer = TextureLayer::Create(NULL);
115 ASSERT_TRUE(test_layer.get());
116 scoped_ptr<TextureLayerImpl> impl_layer;
117 impl_layer = TextureLayerImpl::Create(host_impl_.active_tree(), 1, false);
118 ASSERT_TRUE(impl_layer);
120 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(AnyNumber());
121 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
122 layer_tree_host_->SetRootLayer(test_layer);
123 test_layer->SetTextureId(1);
124 test_layer->SetIsDrawable(true);
125 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
126 EXPECT_EQ(test_layer->layer_tree_host(), layer_tree_host_.get());
128 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(1);
129 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(0);
130 test_layer->WillModifyTexture();
131 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
133 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
134 EXPECT_CALL(*layer_tree_host_, SetNeedsUpdateLayers()).Times(1);
135 test_layer->SetNeedsDisplayRect(dirty_rect);
136 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
138 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
139 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1);
140 test_layer->PushPropertiesTo(impl_layer.get()); // fake commit
141 test_layer->SetIsDrawable(false);
142 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
144 // Verify that non-drawable layers don't signal the compositor,
145 // except for the first draw after last commit, which must acquire
147 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(1);
148 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(0);
149 test_layer->WillModifyTexture();
150 test_layer->SetNeedsDisplayRect(dirty_rect);
151 test_layer->PushPropertiesTo(impl_layer.get()); // fake commit
152 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
154 // Second draw with layer in non-drawable state: no texture
156 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
157 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(0);
158 test_layer->WillModifyTexture();
159 test_layer->SetNeedsDisplayRect(dirty_rect);
160 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
163 TEST_F(TextureLayerTest, SyncImplWhenRemovingFromTree) {
164 scoped_refptr<Layer> root_layer = Layer::Create();
165 ASSERT_TRUE(root_layer.get());
166 scoped_refptr<Layer> child_layer = Layer::Create();
167 ASSERT_TRUE(child_layer.get());
168 root_layer->AddChild(child_layer);
169 scoped_refptr<TextureLayer> test_layer = TextureLayer::Create(NULL);
170 ASSERT_TRUE(test_layer.get());
171 test_layer->SetTextureId(0);
172 child_layer->AddChild(test_layer);
174 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(AnyNumber());
175 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
176 layer_tree_host_->SetRootLayer(root_layer);
177 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
179 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
180 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
181 test_layer->RemoveFromParent();
182 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
184 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
185 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
186 child_layer->AddChild(test_layer);
187 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
189 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
190 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
191 test_layer->SetTextureId(1);
192 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
194 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(AtLeast(1));
195 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
196 test_layer->RemoveFromParent();
197 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
200 TEST_F(TextureLayerTest, CheckPropertyChangeCausesCorrectBehavior) {
201 scoped_refptr<TextureLayer> test_layer = TextureLayer::Create(NULL);
202 EXPECT_SET_NEEDS_COMMIT(1, layer_tree_host_->SetRootLayer(test_layer));
204 // Test properties that should call SetNeedsCommit. All properties need to
205 // be set to new values in order for SetNeedsCommit to be called.
206 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetFlipped(false));
207 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetUV(
208 gfx::PointF(0.25f, 0.25f), gfx::PointF(0.75f, 0.75f)));
209 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetVertexOpacity(
210 0.5f, 0.5f, 0.5f, 0.5f));
211 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetPremultipliedAlpha(false));
212 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetBlendBackgroundColor(true));
213 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetTextureId(1));
215 // Calling SetTextureId can call AcquireLayerTextures.
216 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(AnyNumber());
219 TEST_F(TextureLayerTest, VisibleContentOpaqueRegion) {
220 const gfx::Size layer_bounds(100, 100);
221 const gfx::Rect layer_rect(layer_bounds);
222 const Region layer_region(layer_rect);
224 scoped_refptr<TextureLayer> layer = TextureLayer::Create(NULL);
225 layer->SetBounds(layer_bounds);
226 layer->draw_properties().visible_content_rect = layer_rect;
227 layer->SetBlendBackgroundColor(true);
229 // Verify initial conditions.
230 EXPECT_FALSE(layer->contents_opaque());
231 EXPECT_EQ(0u, layer->background_color());
232 EXPECT_EQ(Region().ToString(),
233 layer->VisibleContentOpaqueRegion().ToString());
235 // Opaque background.
236 layer->SetBackgroundColor(SK_ColorWHITE);
237 EXPECT_EQ(layer_region.ToString(),
238 layer->VisibleContentOpaqueRegion().ToString());
240 // Transparent background.
241 layer->SetBackgroundColor(SkColorSetARGB(100, 255, 255, 255));
242 EXPECT_EQ(Region().ToString(),
243 layer->VisibleContentOpaqueRegion().ToString());
246 class FakeTextureLayerClient : public TextureLayerClient {
248 FakeTextureLayerClient() {}
250 virtual unsigned PrepareTexture() OVERRIDE {
254 virtual bool PrepareTextureMailbox(
255 TextureMailbox* mailbox,
256 scoped_ptr<SingleReleaseCallback>* release_callback,
257 bool use_shared_memory) OVERRIDE {
258 *mailbox = TextureMailbox();
259 *release_callback = scoped_ptr<SingleReleaseCallback>();
264 DISALLOW_COPY_AND_ASSIGN(FakeTextureLayerClient);
267 TEST_F(TextureLayerTest, RateLimiter) {
268 FakeTextureLayerClient client;
269 scoped_refptr<TextureLayer> test_layer = TextureLayer::CreateForMailbox(
271 test_layer->SetIsDrawable(true);
272 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
273 layer_tree_host_->SetRootLayer(test_layer);
275 // Don't rate limit until we invalidate.
276 EXPECT_CALL(*layer_tree_host_, StartRateLimiter()).Times(0);
277 test_layer->SetRateLimitContext(true);
278 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
280 // Do rate limit after we invalidate.
281 EXPECT_CALL(*layer_tree_host_, StartRateLimiter());
282 test_layer->SetNeedsDisplay();
283 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
285 // Stop rate limiter when we don't want it any more.
286 EXPECT_CALL(*layer_tree_host_, StopRateLimiter());
287 test_layer->SetRateLimitContext(false);
288 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
290 // Or we clear the client.
291 test_layer->SetRateLimitContext(true);
292 EXPECT_CALL(*layer_tree_host_, StopRateLimiter());
293 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
294 test_layer->ClearClient();
295 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
297 // Reset to a layer with a client, that started the rate limiter.
298 test_layer = TextureLayer::CreateForMailbox(
300 test_layer->SetIsDrawable(true);
301 test_layer->SetRateLimitContext(true);
302 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
303 layer_tree_host_->SetRootLayer(test_layer);
304 EXPECT_CALL(*layer_tree_host_, StartRateLimiter()).Times(0);
305 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
306 EXPECT_CALL(*layer_tree_host_, StartRateLimiter());
307 test_layer->SetNeedsDisplay();
308 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
310 // Stop rate limiter when we're removed from the tree.
311 EXPECT_CALL(*layer_tree_host_, StopRateLimiter());
312 layer_tree_host_->SetRootLayer(NULL);
313 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
316 class MockMailboxCallback {
318 MOCK_METHOD3(Release, void(const std::string& mailbox,
320 bool lost_resource));
321 MOCK_METHOD3(Release2, void(base::SharedMemory* shared_memory,
323 bool lost_resource));
326 struct CommonMailboxObjects {
327 CommonMailboxObjects()
328 : mailbox_name1_(64, '1'),
329 mailbox_name2_(64, '2'),
332 shared_memory_(new base::SharedMemory) {
333 release_mailbox1_ = base::Bind(&MockMailboxCallback::Release,
334 base::Unretained(&mock_callback_),
336 release_mailbox2_ = base::Bind(&MockMailboxCallback::Release,
337 base::Unretained(&mock_callback_),
340 m1.SetName(reinterpret_cast<const int8*>(mailbox_name1_.data()));
341 mailbox1_ = TextureMailbox(m1, sync_point1_);
343 m2.SetName(reinterpret_cast<const int8*>(mailbox_name2_.data()));
344 mailbox2_ = TextureMailbox(m2, sync_point2_);
346 gfx::Size size(128, 128);
347 EXPECT_TRUE(shared_memory_->CreateAndMapAnonymous(4 * size.GetArea()));
348 release_mailbox3_ = base::Bind(&MockMailboxCallback::Release2,
349 base::Unretained(&mock_callback_),
350 shared_memory_.get());
351 mailbox3_ = TextureMailbox(shared_memory_.get(), size);
354 std::string mailbox_name1_;
355 std::string mailbox_name2_;
356 MockMailboxCallback mock_callback_;
357 ReleaseCallback release_mailbox1_;
358 ReleaseCallback release_mailbox2_;
359 ReleaseCallback release_mailbox3_;
360 TextureMailbox mailbox1_;
361 TextureMailbox mailbox2_;
362 TextureMailbox mailbox3_;
363 unsigned sync_point1_;
364 unsigned sync_point2_;
365 scoped_ptr<base::SharedMemory> shared_memory_;
368 class TestMailboxHolder : public TextureLayer::MailboxHolder {
370 using TextureLayer::MailboxHolder::Create;
373 virtual ~TestMailboxHolder() {}
376 class TextureLayerWithMailboxTest : public TextureLayerTest {
378 virtual void TearDown() {
379 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
380 EXPECT_CALL(test_data_.mock_callback_,
381 Release(test_data_.mailbox_name1_,
382 test_data_.sync_point1_,
384 TextureLayerTest::TearDown();
387 CommonMailboxObjects test_data_;
390 TEST_F(TextureLayerWithMailboxTest, ReplaceMailboxOnMainThreadBeforeCommit) {
391 scoped_refptr<TextureLayer> test_layer = TextureLayer::CreateForMailbox(NULL);
392 ASSERT_TRUE(test_layer.get());
394 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
395 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
396 layer_tree_host_->SetRootLayer(test_layer);
397 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
399 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
400 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
401 test_layer->SetTextureMailbox(
402 test_data_.mailbox1_,
403 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
404 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
406 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
407 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
408 EXPECT_CALL(test_data_.mock_callback_,
409 Release(test_data_.mailbox_name1_,
410 test_data_.sync_point1_,
413 test_layer->SetTextureMailbox(
414 test_data_.mailbox2_,
415 SingleReleaseCallback::Create(test_data_.release_mailbox2_));
416 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
417 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
419 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
420 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
421 EXPECT_CALL(test_data_.mock_callback_,
422 Release(test_data_.mailbox_name2_,
423 test_data_.sync_point2_,
426 test_layer->SetTextureMailbox(TextureMailbox(),
427 scoped_ptr<SingleReleaseCallback>());
428 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
429 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
431 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
432 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
433 test_layer->SetTextureMailbox(
434 test_data_.mailbox3_,
435 SingleReleaseCallback::Create(test_data_.release_mailbox3_));
436 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
437 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
439 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
440 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
441 EXPECT_CALL(test_data_.mock_callback_,
442 Release2(test_data_.shared_memory_.get(),
445 test_layer->SetTextureMailbox(TextureMailbox(),
446 scoped_ptr<SingleReleaseCallback>());
447 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
448 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
451 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
452 test_layer->SetTextureMailbox(
453 test_data_.mailbox1_,
454 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
457 class TextureLayerMailboxHolderTest : public TextureLayerTest {
459 TextureLayerMailboxHolderTest()
460 : main_thread_("MAIN") {
461 main_thread_.Start();
464 void Wait(const base::Thread& thread) {
465 bool manual_reset = false;
466 bool initially_signaled = false;
467 base::WaitableEvent event(manual_reset, initially_signaled);
468 thread.message_loop()->PostTask(
470 base::Bind(&base::WaitableEvent::Signal, base::Unretained(&event)));
474 void CreateMainRef() {
475 main_ref_ = TestMailboxHolder::Create(
476 test_data_.mailbox1_,
477 SingleReleaseCallback::Create(test_data_.release_mailbox1_)).Pass();
480 void ReleaseMainRef() {
484 void CreateImplRef(scoped_ptr<SingleReleaseCallback>* impl_ref) {
485 *impl_ref = main_ref_->holder()->GetCallbackForImplThread();
488 void CapturePostTasksAndWait(base::WaitableEvent* begin_capture,
489 base::WaitableEvent* wait_for_capture,
490 base::WaitableEvent* stop_capture) {
491 begin_capture->Wait();
492 BlockingTaskRunner::CapturePostTasks capture;
493 wait_for_capture->Signal();
494 stop_capture->Wait();
498 scoped_ptr<TestMailboxHolder::MainThreadReference>
500 base::Thread main_thread_;
501 CommonMailboxObjects test_data_;
504 TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_BothReleaseThenMain) {
505 scoped_refptr<TextureLayer> test_layer = TextureLayer::CreateForMailbox(NULL);
506 ASSERT_TRUE(test_layer.get());
508 main_thread_.message_loop()->PostTask(
510 base::Bind(&TextureLayerMailboxHolderTest::CreateMainRef,
511 base::Unretained(this)));
515 // The texture layer is attached to compositor1, and passes a reference to its
517 scoped_ptr<SingleReleaseCallback> compositor1;
518 main_thread_.message_loop()->PostTask(
520 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
521 base::Unretained(this),
524 // Then the texture layer is removed and attached to compositor2, and passes a
525 // reference to its impl tree.
526 scoped_ptr<SingleReleaseCallback> compositor2;
527 main_thread_.message_loop()->PostTask(
529 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
530 base::Unretained(this),
534 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
536 // The compositors both destroy their impl trees before the main thread layer
538 compositor1->Run(100, false);
539 compositor2->Run(200, false);
543 EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0);
544 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
546 // The main thread ref is the last one, so the mailbox is released back to the
547 // embedder, with the last sync point provided by the impl trees.
548 EXPECT_CALL(test_data_.mock_callback_,
549 Release(test_data_.mailbox_name1_, 200, false)).Times(1);
551 main_thread_.message_loop()->PostTask(
553 base::Bind(&TextureLayerMailboxHolderTest::ReleaseMainRef,
554 base::Unretained(this)));
556 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
559 TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_MainReleaseBetween) {
560 scoped_refptr<TextureLayer> test_layer = TextureLayer::CreateForMailbox(NULL);
561 ASSERT_TRUE(test_layer.get());
563 main_thread_.message_loop()->PostTask(
565 base::Bind(&TextureLayerMailboxHolderTest::CreateMainRef,
566 base::Unretained(this)));
570 // The texture layer is attached to compositor1, and passes a reference to its
572 scoped_ptr<SingleReleaseCallback> compositor1;
573 main_thread_.message_loop()->PostTask(
575 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
576 base::Unretained(this),
579 // Then the texture layer is removed and attached to compositor2, and passes a
580 // reference to its impl tree.
581 scoped_ptr<SingleReleaseCallback> compositor2;
582 main_thread_.message_loop()->PostTask(
584 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
585 base::Unretained(this),
589 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
591 // One compositor destroys their impl tree.
592 compositor1->Run(100, false);
594 // Then the main thread reference is destroyed.
595 main_thread_.message_loop()->PostTask(
597 base::Bind(&TextureLayerMailboxHolderTest::ReleaseMainRef,
598 base::Unretained(this)));
602 EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0);
603 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
605 // The second impl reference is destroyed last, causing the mailbox to be
606 // released back to the embedder with the last sync point from the impl tree.
607 EXPECT_CALL(test_data_.mock_callback_,
608 Release(test_data_.mailbox_name1_, 200, true)).Times(1);
610 compositor2->Run(200, true);
612 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
615 TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_MainReleasedFirst) {
616 scoped_refptr<TextureLayer> test_layer = TextureLayer::CreateForMailbox(NULL);
617 ASSERT_TRUE(test_layer.get());
619 main_thread_.message_loop()->PostTask(
621 base::Bind(&TextureLayerMailboxHolderTest::CreateMainRef,
622 base::Unretained(this)));
626 // The texture layer is attached to compositor1, and passes a reference to its
628 scoped_ptr<SingleReleaseCallback> compositor1;
629 main_thread_.message_loop()->PostTask(
631 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
632 base::Unretained(this),
635 // Then the texture layer is removed and attached to compositor2, and passes a
636 // reference to its impl tree.
637 scoped_ptr<SingleReleaseCallback> compositor2;
638 main_thread_.message_loop()->PostTask(
640 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
641 base::Unretained(this),
645 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
647 // The main thread reference is destroyed first.
648 main_thread_.message_loop()->PostTask(
650 base::Bind(&TextureLayerMailboxHolderTest::ReleaseMainRef,
651 base::Unretained(this)));
653 // One compositor destroys their impl tree.
654 compositor2->Run(200, false);
658 EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0);
659 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
661 // The second impl reference is destroyed last, causing the mailbox to be
662 // released back to the embedder with the last sync point from the impl tree.
663 EXPECT_CALL(test_data_.mock_callback_,
664 Release(test_data_.mailbox_name1_, 100, true)).Times(1);
666 compositor1->Run(100, true);
668 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
671 TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_SecondImplRefShortcut) {
672 scoped_refptr<TextureLayer> test_layer = TextureLayer::CreateForMailbox(NULL);
673 ASSERT_TRUE(test_layer.get());
675 main_thread_.message_loop()->PostTask(
677 base::Bind(&TextureLayerMailboxHolderTest::CreateMainRef,
678 base::Unretained(this)));
682 // The texture layer is attached to compositor1, and passes a reference to its
684 scoped_ptr<SingleReleaseCallback> compositor1;
685 main_thread_.message_loop()->PostTask(
687 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
688 base::Unretained(this),
691 // Then the texture layer is removed and attached to compositor2, and passes a
692 // reference to its impl tree.
693 scoped_ptr<SingleReleaseCallback> compositor2;
694 main_thread_.message_loop()->PostTask(
696 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
697 base::Unretained(this),
701 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
703 // The main thread reference is destroyed first.
704 main_thread_.message_loop()->PostTask(
706 base::Bind(&TextureLayerMailboxHolderTest::ReleaseMainRef,
707 base::Unretained(this)));
709 EXPECT_CALL(test_data_.mock_callback_,
710 Release(test_data_.mailbox_name1_, 200, true)).Times(1);
712 bool manual_reset = false;
713 bool initially_signaled = false;
714 base::WaitableEvent begin_capture(manual_reset, initially_signaled);
715 base::WaitableEvent wait_for_capture(manual_reset, initially_signaled);
716 base::WaitableEvent stop_capture(manual_reset, initially_signaled);
718 // Post a task to start capturing tasks on the main thread. This will block
719 // the main thread until we signal the |stop_capture| event.
720 main_thread_.message_loop()->PostTask(
722 base::Bind(&TextureLayerMailboxHolderTest::CapturePostTasksAndWait,
723 base::Unretained(this),
728 // Before the main thread capturing starts, one compositor destroys their
729 // impl reference. Since capturing did not start, this gets post-tasked to
731 compositor1->Run(100, false);
733 // Start capturing on the main thread.
734 begin_capture.Signal();
735 wait_for_capture.Wait();
737 // Meanwhile, the second compositor released its impl reference, but this task
738 // gets shortcutted directly to the main thread. This means the reference is
739 // released before compositor1, whose reference will be released later when
740 // the post-task is serviced. But since it was destroyed _on the impl thread_
741 // last, its sync point values should be used.
742 compositor2->Run(200, true);
744 stop_capture.Signal();
747 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
750 class TextureLayerImplWithMailboxThreadedCallback : public LayerTreeTest {
752 TextureLayerImplWithMailboxThreadedCallback()
753 : callback_count_(0),
756 // Make sure callback is received on main and doesn't block the impl thread.
757 void ReleaseCallback(unsigned sync_point, bool lost_resource) {
758 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
759 EXPECT_FALSE(lost_resource);
763 void SetMailbox(char mailbox_char) {
764 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
765 TextureMailbox mailbox(std::string(64, mailbox_char));
766 scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create(
768 &TextureLayerImplWithMailboxThreadedCallback::ReleaseCallback,
769 base::Unretained(this)));
770 layer_->SetTextureMailbox(mailbox, callback.Pass());
773 virtual void BeginTest() OVERRIDE {
774 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
776 gfx::Size bounds(100, 100);
777 root_ = Layer::Create();
778 root_->SetAnchorPoint(gfx::PointF());
779 root_->SetBounds(bounds);
781 layer_ = TextureLayer::CreateForMailbox(NULL);
782 layer_->SetIsDrawable(true);
783 layer_->SetAnchorPoint(gfx::PointF());
784 layer_->SetBounds(bounds);
786 root_->AddChild(layer_);
787 layer_tree_host()->SetRootLayer(root_);
788 layer_tree_host()->SetViewportSize(bounds);
790 EXPECT_EQ(0, callback_count_);
792 // Case #1: change mailbox before the commit. The old mailbox should be
793 // released immediately.
795 EXPECT_EQ(1, callback_count_);
796 PostSetNeedsCommitToMainThread();
799 virtual void DidCommit() OVERRIDE {
801 switch (commit_count_) {
803 // Case #2: change mailbox after the commit (and draw), where the
804 // layer draws. The old mailbox should be released during the next
807 EXPECT_EQ(1, callback_count_);
810 EXPECT_EQ(2, callback_count_);
811 // Case #3: change mailbox when the layer doesn't draw. The old
812 // mailbox should be released during the next commit.
813 layer_->SetBounds(gfx::Size());
817 EXPECT_EQ(3, callback_count_);
818 // Case #4: release mailbox that was committed but never drawn. The
819 // old mailbox should be released during the next commit.
820 layer_->SetTextureMailbox(TextureMailbox(),
821 scoped_ptr<SingleReleaseCallback>());
824 if (layer_tree_host()->settings().impl_side_painting) {
825 // With impl painting, the texture mailbox will still be on the impl
826 // thread when the commit finishes, because the layer is not drawble
827 // when it has no texture mailbox, and thus does not block the commit
828 // on activation. So, we wait for activation.
829 // TODO(danakj): fix this. crbug.com/277953
830 layer_tree_host()->SetNeedsCommit();
836 EXPECT_EQ(4, callback_count_);
837 // Restore a mailbox for the next step.
841 // Case #5: remove layer from tree. Callback should *not* be called, the
842 // mailbox is returned to the main thread.
843 EXPECT_EQ(4, callback_count_);
844 layer_->RemoveFromParent();
847 if (layer_tree_host()->settings().impl_side_painting) {
848 // With impl painting, the texture mailbox will still be on the impl
849 // thread when the commit finishes, because the layer is not around to
850 // block the commit on activation anymore. So, we wait for activation.
851 // TODO(danakj): fix this. crbug.com/277953
852 layer_tree_host()->SetNeedsCommit();
858 EXPECT_EQ(4, callback_count_);
859 // Resetting the mailbox will call the callback now.
860 layer_->SetTextureMailbox(TextureMailbox(),
861 scoped_ptr<SingleReleaseCallback>());
862 EXPECT_EQ(5, callback_count_);
871 virtual void AfterTest() OVERRIDE {}
874 base::ThreadChecker main_thread_;
877 scoped_refptr<Layer> root_;
878 scoped_refptr<TextureLayer> layer_;
881 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
882 TextureLayerImplWithMailboxThreadedCallback);
885 class TextureLayerNoMailboxIsActivatedDuringCommit : public LayerTreeTest,
886 public TextureLayerClient {
888 TextureLayerNoMailboxIsActivatedDuringCommit()
889 : texture_(0u), activate_count_(0) {}
891 virtual void BeginTest() OVERRIDE {
892 gfx::Size bounds(100, 100);
893 root_ = Layer::Create();
894 root_->SetAnchorPoint(gfx::PointF());
895 root_->SetBounds(bounds);
897 layer_ = TextureLayer::Create(this);
898 layer_->SetIsDrawable(true);
899 layer_->SetAnchorPoint(gfx::PointF());
900 layer_->SetBounds(bounds);
902 root_->AddChild(layer_);
903 layer_tree_host()->SetRootLayer(root_);
904 layer_tree_host()->SetViewportSize(bounds);
906 PostSetNeedsCommitToMainThread();
909 virtual scoped_ptr<OutputSurface> CreateOutputSurface(bool fallback)
911 scoped_refptr<TestContextProvider> provider = TestContextProvider::Create();
912 texture_ = provider->UnboundTestContext3d()->createExternalTexture();
913 return FakeOutputSurface::Create3d(provider).PassAs<OutputSurface>();
916 // TextureLayerClient implementation.
917 virtual unsigned PrepareTexture() OVERRIDE {
920 virtual bool PrepareTextureMailbox(
921 TextureMailbox* mailbox,
922 scoped_ptr<SingleReleaseCallback>* release_callback,
923 bool use_shared_memory) OVERRIDE {
927 virtual void WillActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
931 virtual void DidCommit() OVERRIDE {
932 switch (layer_tree_host()->source_frame_number()) {
934 // The first texture has been activated. Invalidate the layer so it
935 // grabs a new texture id from the client.
936 layer_->SetNeedsDisplay();
939 // The second mailbox has been activated. Remove the layer from
940 // the tree to cause another commit/activation. The commit should
941 // finish *after* the layer is removed from the active tree.
942 layer_->RemoveFromParent();
950 virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
951 switch (host_impl->active_tree()->source_frame_number()) {
953 // The activate for the 2nd texture should have happened before now.
954 EXPECT_EQ(2, activate_count_);
958 // The activate to remove the layer should have happened before now.
959 EXPECT_EQ(3, activate_count_);
965 virtual void AfterTest() OVERRIDE {}
969 scoped_refptr<Layer> root_;
970 scoped_refptr<TextureLayer> layer_;
973 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
974 TextureLayerNoMailboxIsActivatedDuringCommit);
976 class TextureLayerMailboxIsActivatedDuringCommit : public LayerTreeTest {
978 TextureLayerMailboxIsActivatedDuringCommit() : activate_count_(0) {}
980 static void ReleaseCallback(unsigned sync_point, bool lost_resource) {}
982 void SetMailbox(char mailbox_char) {
983 TextureMailbox mailbox(std::string(64, mailbox_char));
984 scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create(
986 &TextureLayerMailboxIsActivatedDuringCommit::ReleaseCallback));
987 layer_->SetTextureMailbox(mailbox, callback.Pass());
990 virtual void BeginTest() OVERRIDE {
991 gfx::Size bounds(100, 100);
992 root_ = Layer::Create();
993 root_->SetAnchorPoint(gfx::PointF());
994 root_->SetBounds(bounds);
996 layer_ = TextureLayer::CreateForMailbox(NULL);
997 layer_->SetIsDrawable(true);
998 layer_->SetAnchorPoint(gfx::PointF());
999 layer_->SetBounds(bounds);
1001 root_->AddChild(layer_);
1002 layer_tree_host()->SetRootLayer(root_);
1003 layer_tree_host()->SetViewportSize(bounds);
1006 PostSetNeedsCommitToMainThread();
1009 virtual void WillActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1013 virtual void DidCommit() OVERRIDE {
1014 switch (layer_tree_host()->source_frame_number()) {
1016 // The first mailbox has been activated. Set a new mailbox, and
1017 // expect the next commit to finish *after* it is activated.
1021 // The second mailbox has been activated. Remove the layer from
1022 // the tree to cause another commit/activation. The commit should
1023 // finish *after* the layer is removed from the active tree.
1024 layer_->RemoveFromParent();
1032 virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
1033 switch (host_impl->active_tree()->source_frame_number()) {
1035 // The activate for the 2nd mailbox should have happened before now.
1036 EXPECT_EQ(2, activate_count_);
1040 // The activate to remove the layer should have happened before now.
1041 EXPECT_EQ(3, activate_count_);
1048 virtual void AfterTest() OVERRIDE {}
1050 int activate_count_;
1051 scoped_refptr<Layer> root_;
1052 scoped_refptr<TextureLayer> layer_;
1055 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
1056 TextureLayerMailboxIsActivatedDuringCommit);
1058 class TextureLayerImplWithMailboxTest : public TextureLayerTest {
1060 TextureLayerImplWithMailboxTest()
1062 FakeLayerTreeHostClient(FakeLayerTreeHostClient::DIRECT_3D)) {}
1064 virtual void SetUp() {
1065 TextureLayerTest::SetUp();
1066 layer_tree_host_.reset(new MockLayerTreeHost(&fake_client_));
1067 EXPECT_TRUE(host_impl_.InitializeRenderer(CreateFakeOutputSurface()));
1070 bool WillDraw(TextureLayerImpl* layer, DrawMode mode) {
1071 bool will_draw = layer->WillDraw(
1072 mode, host_impl_.active_tree()->resource_provider());
1074 layer->DidDraw(host_impl_.active_tree()->resource_provider());
1078 CommonMailboxObjects test_data_;
1079 FakeLayerTreeHostClient fake_client_;
1082 // Test conditions for results of TextureLayerImpl::WillDraw under
1083 // different configurations of different mailbox, texture_id, and draw_mode.
1084 TEST_F(TextureLayerImplWithMailboxTest, TestWillDraw) {
1085 EXPECT_CALL(test_data_.mock_callback_,
1086 Release(test_data_.mailbox_name1_,
1087 test_data_.sync_point1_,
1089 .Times(AnyNumber());
1090 EXPECT_CALL(test_data_.mock_callback_,
1091 Release2(test_data_.shared_memory_.get(), 0, false))
1092 .Times(AnyNumber());
1095 scoped_ptr<TextureLayerImpl> impl_layer =
1096 TextureLayerImpl::Create(host_impl_.active_tree(), 1, true);
1097 impl_layer->SetDrawsContent(true);
1098 impl_layer->SetTextureMailbox(
1099 test_data_.mailbox1_,
1100 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
1101 EXPECT_TRUE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE));
1105 scoped_ptr<TextureLayerImpl> impl_layer =
1106 TextureLayerImpl::Create(host_impl_.active_tree(), 1, true);
1107 impl_layer->SetDrawsContent(true);
1108 impl_layer->SetTextureMailbox(TextureMailbox(),
1109 scoped_ptr<SingleReleaseCallback>());
1110 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE));
1114 // Software resource.
1115 scoped_ptr<TextureLayerImpl> impl_layer =
1116 TextureLayerImpl::Create(host_impl_.active_tree(), 1, true);
1117 impl_layer->SetDrawsContent(true);
1118 impl_layer->SetTextureMailbox(
1119 test_data_.mailbox3_,
1120 SingleReleaseCallback::Create(test_data_.release_mailbox3_));
1121 EXPECT_TRUE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE));
1125 scoped_ptr<TextureLayerImpl> impl_layer =
1126 TextureLayerImpl::Create(host_impl_.active_tree(), 1, false);
1127 impl_layer->SetDrawsContent(true);
1128 ContextProvider* context_provider =
1129 host_impl_.output_surface()->context_provider();
1131 context_provider->ContextGL()->GenTextures(1, &texture);
1132 impl_layer->SetTextureId(texture);
1133 EXPECT_TRUE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE));
1137 scoped_ptr<TextureLayerImpl> impl_layer =
1138 TextureLayerImpl::Create(host_impl_.active_tree(), 1, false);
1139 impl_layer->SetDrawsContent(true);
1140 impl_layer->SetTextureId(0);
1141 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE));
1146 scoped_ptr<TextureLayerImpl> impl_layer =
1147 TextureLayerImpl::Create(host_impl_.active_tree(), 1, true);
1148 impl_layer->SetDrawsContent(true);
1149 impl_layer->SetTextureMailbox(
1150 test_data_.mailbox1_,
1151 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
1152 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE));
1156 scoped_ptr<TextureLayerImpl> impl_layer =
1157 TextureLayerImpl::Create(host_impl_.active_tree(), 1, true);
1158 impl_layer->SetDrawsContent(true);
1159 impl_layer->SetTextureMailbox(TextureMailbox(),
1160 scoped_ptr<SingleReleaseCallback>());
1161 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE));
1165 // Software resource.
1166 scoped_ptr<TextureLayerImpl> impl_layer =
1167 TextureLayerImpl::Create(host_impl_.active_tree(), 1, true);
1168 impl_layer->SetDrawsContent(true);
1169 impl_layer->SetTextureMailbox(
1170 test_data_.mailbox3_,
1171 SingleReleaseCallback::Create(test_data_.release_mailbox3_));
1172 EXPECT_TRUE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE));
1176 scoped_ptr<TextureLayerImpl> impl_layer =
1177 TextureLayerImpl::Create(host_impl_.active_tree(), 1, false);
1178 impl_layer->SetDrawsContent(true);
1179 ContextProvider* context_provider =
1180 host_impl_.output_surface()->context_provider();
1182 context_provider->ContextGL()->GenTextures(1, &texture);
1183 impl_layer->SetTextureId(texture);
1184 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE));
1188 scoped_ptr<TextureLayerImpl> impl_layer =
1189 TextureLayerImpl::Create(host_impl_.active_tree(), 1, false);
1190 impl_layer->SetDrawsContent(true);
1191 impl_layer->SetTextureId(0);
1192 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE));
1195 // Resourceless software mode.
1197 scoped_ptr<TextureLayerImpl> impl_layer =
1198 TextureLayerImpl::Create(host_impl_.active_tree(), 1, true);
1199 impl_layer->SetDrawsContent(true);
1200 impl_layer->SetTextureMailbox(
1201 test_data_.mailbox1_,
1202 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
1203 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_RESOURCELESS_SOFTWARE));
1207 scoped_ptr<TextureLayerImpl> impl_layer =
1208 TextureLayerImpl::Create(host_impl_.active_tree(), 1, false);
1209 impl_layer->SetDrawsContent(true);
1210 ContextProvider* context_provider =
1211 host_impl_.output_surface()->context_provider();
1213 context_provider->ContextGL()->GenTextures(1, &texture);
1214 impl_layer->SetTextureId(texture);
1215 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_RESOURCELESS_SOFTWARE));
1219 TEST_F(TextureLayerImplWithMailboxTest, TestImplLayerCallbacks) {
1220 host_impl_.CreatePendingTree();
1221 scoped_ptr<TextureLayerImpl> pending_layer;
1222 pending_layer = TextureLayerImpl::Create(host_impl_.pending_tree(), 1, true);
1223 ASSERT_TRUE(pending_layer);
1225 scoped_ptr<LayerImpl> active_layer(
1226 pending_layer->CreateLayerImpl(host_impl_.active_tree()));
1227 ASSERT_TRUE(active_layer);
1229 pending_layer->SetTextureMailbox(
1230 test_data_.mailbox1_,
1231 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
1233 // Test multiple commits without an activation.
1234 EXPECT_CALL(test_data_.mock_callback_,
1235 Release(test_data_.mailbox_name1_,
1236 test_data_.sync_point1_,
1239 pending_layer->SetTextureMailbox(
1240 test_data_.mailbox2_,
1241 SingleReleaseCallback::Create(test_data_.release_mailbox2_));
1242 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
1244 // Test callback after activation.
1245 pending_layer->PushPropertiesTo(active_layer.get());
1246 active_layer->DidBecomeActive();
1248 EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0);
1249 pending_layer->SetTextureMailbox(
1250 test_data_.mailbox1_,
1251 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
1252 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
1254 EXPECT_CALL(test_data_.mock_callback_,
1255 Release(test_data_.mailbox_name2_, _, false))
1257 pending_layer->PushPropertiesTo(active_layer.get());
1258 active_layer->DidBecomeActive();
1259 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
1261 // Test resetting the mailbox.
1262 EXPECT_CALL(test_data_.mock_callback_,
1263 Release(test_data_.mailbox_name1_, _, false))
1265 pending_layer->SetTextureMailbox(TextureMailbox(),
1266 scoped_ptr<SingleReleaseCallback>());
1267 pending_layer->PushPropertiesTo(active_layer.get());
1268 active_layer->DidBecomeActive();
1269 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
1272 EXPECT_CALL(test_data_.mock_callback_,
1273 Release(test_data_.mailbox_name1_,
1274 test_data_.sync_point1_,
1277 pending_layer->SetTextureMailbox(
1278 test_data_.mailbox1_,
1279 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
1282 TEST_F(TextureLayerImplWithMailboxTest,
1283 TestDestructorCallbackOnCreatedResource) {
1284 scoped_ptr<TextureLayerImpl> impl_layer;
1285 impl_layer = TextureLayerImpl::Create(host_impl_.active_tree(), 1, true);
1286 ASSERT_TRUE(impl_layer);
1288 EXPECT_CALL(test_data_.mock_callback_,
1289 Release(test_data_.mailbox_name1_, _, false))
1291 impl_layer->SetTextureMailbox(
1292 test_data_.mailbox1_,
1293 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
1294 impl_layer->SetDrawsContent(true);
1295 impl_layer->DidBecomeActive();
1296 EXPECT_TRUE(impl_layer->WillDraw(
1297 DRAW_MODE_HARDWARE, host_impl_.active_tree()->resource_provider()));
1298 impl_layer->DidDraw(host_impl_.active_tree()->resource_provider());
1299 impl_layer->SetTextureMailbox(TextureMailbox(),
1300 scoped_ptr<SingleReleaseCallback>());
1303 TEST_F(TextureLayerImplWithMailboxTest, TestCallbackOnInUseResource) {
1304 ResourceProvider* provider = host_impl_.active_tree()->resource_provider();
1305 ResourceProvider::ResourceId id =
1306 provider->CreateResourceFromTextureMailbox(
1307 test_data_.mailbox1_,
1308 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
1309 provider->AllocateForTesting(id);
1311 // Transfer some resources to the parent.
1312 ResourceProvider::ResourceIdArray resource_ids_to_transfer;
1313 resource_ids_to_transfer.push_back(id);
1314 TransferableResourceArray list;
1315 provider->PrepareSendToParent(resource_ids_to_transfer, &list);
1316 EXPECT_TRUE(provider->InUseByConsumer(id));
1317 EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0);
1318 provider->DeleteResource(id);
1319 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
1320 EXPECT_CALL(test_data_.mock_callback_,
1321 Release(test_data_.mailbox_name1_, _, false))
1323 ReturnedResourceArray returned;
1324 TransferableResource::ReturnResources(list, &returned);
1325 provider->ReceiveReturnsFromParent(returned);
1328 // Check that ClearClient correctly clears the state so that the impl side
1329 // doesn't try to use a texture that could have been destroyed.
1330 class TextureLayerClientTest
1331 : public LayerTreeTest,
1332 public TextureLayerClient {
1334 TextureLayerClientTest()
1337 expected_used_textures_on_draw_(0),
1338 expected_used_textures_on_commit_(0) {}
1340 virtual scoped_ptr<OutputSurface> CreateOutputSurface(bool fallback)
1342 scoped_refptr<TestContextProvider> provider = TestContextProvider::Create();
1343 texture_ = provider->UnboundTestContext3d()->createExternalTexture();
1344 return FakeOutputSurface::Create3d(provider).PassAs<OutputSurface>();
1347 virtual unsigned PrepareTexture() OVERRIDE { return texture_; }
1349 virtual bool PrepareTextureMailbox(
1350 TextureMailbox* mailbox,
1351 scoped_ptr<SingleReleaseCallback>* release_callback,
1352 bool use_shared_memory) OVERRIDE {
1356 virtual void SetupTree() OVERRIDE {
1357 scoped_refptr<Layer> root = Layer::Create();
1358 root->SetBounds(gfx::Size(10, 10));
1359 root->SetAnchorPoint(gfx::PointF());
1360 root->SetIsDrawable(true);
1362 texture_layer_ = TextureLayer::Create(this);
1363 texture_layer_->SetBounds(gfx::Size(10, 10));
1364 texture_layer_->SetAnchorPoint(gfx::PointF());
1365 texture_layer_->SetIsDrawable(true);
1366 root->AddChild(texture_layer_);
1368 layer_tree_host()->SetRootLayer(root);
1369 LayerTreeTest::SetupTree();
1371 base::AutoLock lock(lock_);
1372 expected_used_textures_on_commit_ = 1;
1376 virtual void BeginTest() OVERRIDE {
1377 PostSetNeedsCommitToMainThread();
1380 virtual void DidCommitAndDrawFrame() OVERRIDE {
1382 switch (commit_count_) {
1384 texture_layer_->ClearClient();
1385 texture_layer_->SetNeedsDisplay();
1387 base::AutoLock lock(lock_);
1388 expected_used_textures_on_commit_ = 0;
1400 virtual void BeginCommitOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
1401 base::AutoLock lock(lock_);
1402 expected_used_textures_on_draw_ = expected_used_textures_on_commit_;
1405 virtual bool PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
1406 LayerTreeHostImpl::FrameData* frame_data,
1407 bool result) OVERRIDE {
1408 ContextForImplThread(host_impl)->ResetUsedTextures();
1412 virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl,
1413 bool result) OVERRIDE {
1414 ASSERT_TRUE(result);
1415 EXPECT_EQ(expected_used_textures_on_draw_,
1416 ContextForImplThread(host_impl)->NumUsedTextures());
1419 virtual void AfterTest() OVERRIDE {}
1422 TestWebGraphicsContext3D* ContextForImplThread(LayerTreeHostImpl* host_impl) {
1423 return static_cast<TestContextProvider*>(
1424 host_impl->output_surface()->context_provider().get())->TestContext3d();
1427 scoped_refptr<TextureLayer> texture_layer_;
1431 // Used only on thread.
1432 unsigned expected_used_textures_on_draw_;
1434 // Used on either thread, protected by lock_.
1436 unsigned expected_used_textures_on_commit_;
1439 // The TextureLayerClient does not use mailboxes, so can't use a delegating
1441 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(TextureLayerClientTest);
1444 // Checks that changing a texture in the client for a TextureLayer that's
1445 // invisible correctly works without drawing a deleted texture. See
1447 class TextureLayerChangeInvisibleTest
1448 : public LayerTreeTest,
1449 public TextureLayerClient {
1451 TextureLayerChangeInvisibleTest()
1455 expected_texture_on_draw_(0) {}
1457 virtual scoped_ptr<OutputSurface> CreateOutputSurface(bool fallback)
1459 scoped_refptr<TestContextProvider> provider = TestContextProvider::Create();
1460 texture_ = provider->UnboundTestContext3d()->createExternalTexture();
1461 return FakeOutputSurface::Create3d(provider).PassAs<OutputSurface>();
1464 // TextureLayerClient implementation.
1465 virtual unsigned PrepareTexture() OVERRIDE {
1469 virtual bool PrepareTextureMailbox(
1470 TextureMailbox* mailbox,
1471 scoped_ptr<SingleReleaseCallback>* release_callback,
1472 bool use_shared_memory) OVERRIDE {
1476 virtual void SetupTree() OVERRIDE {
1477 scoped_refptr<Layer> root = Layer::Create();
1478 root->SetBounds(gfx::Size(10, 10));
1479 root->SetAnchorPoint(gfx::PointF());
1480 root->SetIsDrawable(true);
1482 solid_layer_ = SolidColorLayer::Create();
1483 solid_layer_->SetBounds(gfx::Size(10, 10));
1484 solid_layer_->SetIsDrawable(true);
1485 solid_layer_->SetBackgroundColor(SK_ColorWHITE);
1486 root->AddChild(solid_layer_);
1488 parent_layer_ = Layer::Create();
1489 parent_layer_->SetBounds(gfx::Size(10, 10));
1490 parent_layer_->SetIsDrawable(true);
1491 root->AddChild(parent_layer_);
1493 texture_layer_ = TextureLayer::Create(this);
1494 texture_layer_->SetBounds(gfx::Size(10, 10));
1495 texture_layer_->SetAnchorPoint(gfx::PointF());
1496 texture_layer_->SetIsDrawable(true);
1497 parent_layer_->AddChild(texture_layer_);
1499 layer_tree_host()->SetRootLayer(root);
1500 LayerTreeTest::SetupTree();
1503 virtual void BeginTest() OVERRIDE {
1504 PostSetNeedsCommitToMainThread();
1507 virtual void DidCommitAndDrawFrame() OVERRIDE {
1509 switch (commit_count_) {
1511 // We should have updated the layer, committing the texture.
1512 EXPECT_EQ(1, prepare_called_);
1513 // Make layer invisible.
1514 parent_layer_->SetOpacity(0.f);
1517 // Layer shouldn't have been updated.
1518 EXPECT_EQ(1, prepare_called_);
1519 texture_layer_->SetNeedsDisplay();
1520 // Force a change to make sure we draw a frame.
1521 solid_layer_->SetBackgroundColor(SK_ColorGRAY);
1525 EXPECT_EQ(1, prepare_called_);
1526 // Make layer visible again.
1527 parent_layer_->SetOpacity(1.f);
1530 // Layer should have been updated.
1531 EXPECT_EQ(2, prepare_called_);
1532 texture_layer_->ClearClient();
1545 virtual void BeginCommitOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
1546 ASSERT_TRUE(proxy()->IsMainThreadBlocked());
1547 // This is the only texture that can be drawn this frame.
1548 expected_texture_on_draw_ = texture_;
1551 virtual bool PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
1552 LayerTreeHostImpl::FrameData* frame_data,
1553 bool result) OVERRIDE {
1554 ContextForImplThread(host_impl)->ResetUsedTextures();
1558 virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl,
1559 bool result) OVERRIDE {
1560 ASSERT_TRUE(result);
1561 TestWebGraphicsContext3D* context = ContextForImplThread(host_impl);
1562 int used_textures = context->NumUsedTextures();
1563 switch (host_impl->active_tree()->source_frame_number()) {
1565 EXPECT_EQ(1, used_textures);
1566 EXPECT_TRUE(context->UsedTexture(expected_texture_on_draw_));
1570 EXPECT_EQ(0, used_textures);
1573 EXPECT_EQ(1, used_textures);
1574 EXPECT_TRUE(context->UsedTexture(expected_texture_on_draw_));
1581 virtual void AfterTest() OVERRIDE {}
1584 TestWebGraphicsContext3D* ContextForImplThread(LayerTreeHostImpl* host_impl) {
1585 return static_cast<TestContextProvider*>(
1586 host_impl->output_surface()->context_provider().get())->TestContext3d();
1589 scoped_refptr<SolidColorLayer> solid_layer_;
1590 scoped_refptr<Layer> parent_layer_;
1591 scoped_refptr<TextureLayer> texture_layer_;
1593 // Used on the main thread, and on the impl thread while the main thread is
1597 // Used on the main thread.
1598 int prepare_called_;
1601 // Used on the compositor thread.
1602 unsigned expected_texture_on_draw_;
1605 // The TextureLayerChangeInvisibleTest does not use mailboxes, so can't use a
1606 // delegating renderer.
1607 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(TextureLayerChangeInvisibleTest);
1609 // Checks that TextureLayer::Update does not cause an extra commit when setting
1610 // the texture mailbox.
1611 class TextureLayerNoExtraCommitForMailboxTest
1612 : public LayerTreeTest,
1613 public TextureLayerClient {
1615 // TextureLayerClient implementation.
1616 virtual unsigned PrepareTexture() OVERRIDE {
1620 virtual bool PrepareTextureMailbox(
1621 TextureMailbox* mailbox,
1622 scoped_ptr<SingleReleaseCallback>* release_callback,
1623 bool use_shared_memory) OVERRIDE {
1624 if (layer_tree_host()->source_frame_number() == 1) {
1625 *mailbox = TextureMailbox();
1629 *mailbox = TextureMailbox(std::string(64, '1'));
1630 *release_callback = SingleReleaseCallback::Create(
1631 base::Bind(&TextureLayerNoExtraCommitForMailboxTest::MailboxReleased,
1632 base::Unretained(this)));
1636 void MailboxReleased(unsigned sync_point, bool lost_resource) {
1637 EXPECT_EQ(2, layer_tree_host()->source_frame_number());
1641 virtual void SetupTree() OVERRIDE {
1642 scoped_refptr<Layer> root = Layer::Create();
1643 root->SetBounds(gfx::Size(10, 10));
1644 root->SetAnchorPoint(gfx::PointF());
1645 root->SetIsDrawable(true);
1647 texture_layer_ = TextureLayer::CreateForMailbox(this);
1648 texture_layer_->SetBounds(gfx::Size(10, 10));
1649 texture_layer_->SetAnchorPoint(gfx::PointF());
1650 texture_layer_->SetIsDrawable(true);
1651 root->AddChild(texture_layer_);
1653 layer_tree_host()->SetRootLayer(root);
1654 LayerTreeTest::SetupTree();
1657 virtual void BeginTest() OVERRIDE {
1658 PostSetNeedsCommitToMainThread();
1661 virtual void DidCommitAndDrawFrame() OVERRIDE {
1662 switch (layer_tree_host()->source_frame_number()) {
1664 EXPECT_FALSE(proxy()->CommitPendingForTesting());
1665 // Invalidate the texture layer to clear the mailbox before
1667 texture_layer_->SetNeedsDisplay();
1677 virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl,
1678 bool result) OVERRIDE {
1679 ASSERT_TRUE(result);
1680 DelegatedFrameData* delegated_frame_data =
1681 output_surface()->last_sent_frame().delegated_frame_data.get();
1682 if (!delegated_frame_data)
1685 // Return all resources immediately.
1686 TransferableResourceArray resources_to_return =
1687 output_surface()->resources_held_by_parent();
1689 CompositorFrameAck ack;
1690 for (size_t i = 0; i < resources_to_return.size(); ++i)
1691 output_surface()->ReturnResource(resources_to_return[i].id, &ack);
1692 host_impl->ReclaimResources(&ack);
1693 host_impl->OnSwapBuffersComplete();
1696 virtual void AfterTest() OVERRIDE {}
1699 scoped_refptr<TextureLayer> texture_layer_;
1702 SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerNoExtraCommitForMailboxTest);
1704 // Checks that changing a mailbox in the client for a TextureLayer that's
1705 // invisible correctly works and uses the new mailbox as soon as the layer
1706 // becomes visible (and returns the old one).
1707 class TextureLayerChangeInvisibleMailboxTest
1708 : public LayerTreeTest,
1709 public TextureLayerClient {
1711 TextureLayerChangeInvisibleMailboxTest()
1712 : mailbox_changed_(true),
1713 mailbox_returned_(0),
1716 mailbox_ = MakeMailbox('1');
1719 // TextureLayerClient implementation.
1720 virtual unsigned PrepareTexture() OVERRIDE {
1725 virtual bool PrepareTextureMailbox(
1726 TextureMailbox* mailbox,
1727 scoped_ptr<SingleReleaseCallback>* release_callback,
1728 bool use_shared_memory) OVERRIDE {
1730 if (!mailbox_changed_)
1732 *mailbox = mailbox_;
1733 *release_callback = SingleReleaseCallback::Create(
1734 base::Bind(&TextureLayerChangeInvisibleMailboxTest::MailboxReleased,
1735 base::Unretained(this)));
1739 TextureMailbox MakeMailbox(char name) {
1740 return TextureMailbox(std::string(64, name));
1743 void MailboxReleased(unsigned sync_point, bool lost_resource) {
1744 ++mailbox_returned_;
1747 virtual void SetupTree() OVERRIDE {
1748 scoped_refptr<Layer> root = Layer::Create();
1749 root->SetBounds(gfx::Size(10, 10));
1750 root->SetAnchorPoint(gfx::PointF());
1751 root->SetIsDrawable(true);
1753 solid_layer_ = SolidColorLayer::Create();
1754 solid_layer_->SetBounds(gfx::Size(10, 10));
1755 solid_layer_->SetIsDrawable(true);
1756 solid_layer_->SetBackgroundColor(SK_ColorWHITE);
1757 root->AddChild(solid_layer_);
1759 parent_layer_ = Layer::Create();
1760 parent_layer_->SetBounds(gfx::Size(10, 10));
1761 parent_layer_->SetIsDrawable(true);
1762 root->AddChild(parent_layer_);
1764 texture_layer_ = TextureLayer::CreateForMailbox(this);
1765 texture_layer_->SetBounds(gfx::Size(10, 10));
1766 texture_layer_->SetAnchorPoint(gfx::PointF());
1767 texture_layer_->SetIsDrawable(true);
1768 parent_layer_->AddChild(texture_layer_);
1770 layer_tree_host()->SetRootLayer(root);
1771 LayerTreeTest::SetupTree();
1774 virtual void BeginTest() OVERRIDE {
1775 PostSetNeedsCommitToMainThread();
1778 virtual void DidCommitAndDrawFrame() OVERRIDE {
1780 switch (commit_count_) {
1782 // We should have updated the layer, committing the texture.
1783 EXPECT_EQ(1, prepare_called_);
1784 // Make layer invisible.
1785 parent_layer_->SetOpacity(0.f);
1788 // Layer shouldn't have been updated.
1789 EXPECT_EQ(1, prepare_called_);
1790 // Change the texture.
1791 mailbox_ = MakeMailbox('2');
1792 mailbox_changed_ = true;
1793 texture_layer_->SetNeedsDisplay();
1794 // Force a change to make sure we draw a frame.
1795 solid_layer_->SetBackgroundColor(SK_ColorGRAY);
1798 // Layer shouldn't have been updated.
1799 EXPECT_EQ(1, prepare_called_);
1800 // So the old mailbox isn't returned yet.
1801 EXPECT_EQ(0, mailbox_returned_);
1802 // Make layer visible again.
1803 parent_layer_->SetOpacity(1.f);
1806 // Layer should have been updated.
1807 EXPECT_EQ(2, prepare_called_);
1808 // So the old mailbox should have been returned already.
1809 EXPECT_EQ(1, mailbox_returned_);
1810 texture_layer_->ClearClient();
1813 EXPECT_EQ(2, mailbox_returned_);
1822 virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl,
1823 bool result) OVERRIDE {
1824 ASSERT_TRUE(result);
1825 DelegatedFrameData* delegated_frame_data =
1826 output_surface()->last_sent_frame().delegated_frame_data.get();
1827 if (!delegated_frame_data)
1830 // Return all resources immediately.
1831 TransferableResourceArray resources_to_return =
1832 output_surface()->resources_held_by_parent();
1834 CompositorFrameAck ack;
1835 for (size_t i = 0; i < resources_to_return.size(); ++i)
1836 output_surface()->ReturnResource(resources_to_return[i].id, &ack);
1837 host_impl->ReclaimResources(&ack);
1838 host_impl->OnSwapBuffersComplete();
1841 virtual void AfterTest() OVERRIDE {}
1844 scoped_refptr<SolidColorLayer> solid_layer_;
1845 scoped_refptr<Layer> parent_layer_;
1846 scoped_refptr<TextureLayer> texture_layer_;
1848 // Used on the main thread.
1849 bool mailbox_changed_;
1850 TextureMailbox mailbox_;
1851 int mailbox_returned_;
1852 int prepare_called_;
1856 SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerChangeInvisibleMailboxTest);
1858 // Test that TextureLayerImpl::ReleaseResources can be called which releases
1859 // the mailbox back to TextureLayerClient.
1860 class TextureLayerReleaseResourcesBase
1861 : public LayerTreeTest,
1862 public TextureLayerClient {
1864 // TextureLayerClient implementation.
1865 virtual unsigned PrepareTexture() OVERRIDE {
1869 virtual bool PrepareTextureMailbox(
1870 TextureMailbox* mailbox,
1871 scoped_ptr<SingleReleaseCallback>* release_callback,
1872 bool use_shared_memory) OVERRIDE {
1873 *mailbox = TextureMailbox(std::string(64, '1'));
1874 *release_callback = SingleReleaseCallback::Create(
1875 base::Bind(&TextureLayerReleaseResourcesBase::MailboxReleased,
1876 base::Unretained(this)));
1880 void MailboxReleased(unsigned sync_point, bool lost_resource) {
1881 mailbox_released_ = true;
1884 virtual void SetupTree() OVERRIDE {
1885 LayerTreeTest::SetupTree();
1887 scoped_refptr<TextureLayer> texture_layer =
1888 TextureLayer::CreateForMailbox(this);
1889 texture_layer->SetBounds(gfx::Size(10, 10));
1890 texture_layer->SetAnchorPoint(gfx::PointF());
1891 texture_layer->SetIsDrawable(true);
1893 layer_tree_host()->root_layer()->AddChild(texture_layer);
1896 virtual void BeginTest() OVERRIDE {
1897 mailbox_released_ = false;
1898 PostSetNeedsCommitToMainThread();
1901 virtual void DidCommitAndDrawFrame() OVERRIDE {
1905 virtual void AfterTest() OVERRIDE {
1906 EXPECT_TRUE(mailbox_released_);
1910 bool mailbox_released_;
1913 class TextureLayerReleaseResourcesAfterCommit
1914 : public TextureLayerReleaseResourcesBase {
1916 virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
1917 LayerTreeImpl* tree = NULL;
1918 if (host_impl->settings().impl_side_painting)
1919 tree = host_impl->pending_tree();
1921 tree = host_impl->active_tree();
1922 tree->root_layer()->children()[0]->ReleaseResources();
1926 SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerReleaseResourcesAfterCommit);
1928 class TextureLayerReleaseResourcesAfterActivate
1929 : public TextureLayerReleaseResourcesBase {
1931 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
1932 host_impl->active_tree()->root_layer()->children()[0]->ReleaseResources();
1936 SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerReleaseResourcesAfterActivate);
1938 // Test recovering from a lost context.
1939 class TextureLayerLostContextTest
1940 : public LayerTreeTest,
1941 public TextureLayerClient {
1943 TextureLayerLostContextTest()
1944 : context_lost_(false),
1947 virtual scoped_ptr<OutputSurface> CreateOutputSurface(bool fallback)
1949 return CreateFakeOutputSurface();
1952 virtual unsigned PrepareTexture() OVERRIDE {
1953 if (draw_count_ == 0)
1954 context_lost_ = true;
1960 virtual bool PrepareTextureMailbox(
1961 TextureMailbox* mailbox,
1962 scoped_ptr<SingleReleaseCallback>* release_callback,
1963 bool use_shared_memory) OVERRIDE {
1967 virtual void SetupTree() OVERRIDE {
1968 scoped_refptr<Layer> root = Layer::Create();
1969 root->SetBounds(gfx::Size(10, 10));
1970 root->SetIsDrawable(true);
1972 texture_layer_ = TextureLayer::Create(this);
1973 texture_layer_->SetBounds(gfx::Size(10, 10));
1974 texture_layer_->SetIsDrawable(true);
1975 root->AddChild(texture_layer_);
1977 layer_tree_host()->SetRootLayer(root);
1978 LayerTreeTest::SetupTree();
1981 virtual void BeginTest() OVERRIDE {
1982 PostSetNeedsCommitToMainThread();
1985 virtual bool PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
1986 LayerTreeHostImpl::FrameData* frame_data,
1987 bool result) OVERRIDE {
1988 LayerImpl* root = host_impl->RootLayer();
1989 TextureLayerImpl* texture_layer =
1990 static_cast<TextureLayerImpl*>(root->children()[0]);
1991 if (++draw_count_ == 1)
1992 EXPECT_EQ(0u, texture_layer->texture_id());
1994 EXPECT_EQ(1u, texture_layer->texture_id());
1998 virtual void DidCommitAndDrawFrame() OVERRIDE {
2002 virtual void AfterTest() OVERRIDE {}
2005 scoped_refptr<TextureLayer> texture_layer_;
2010 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(TextureLayerLostContextTest);
2012 class TextureLayerWithMailboxMainThreadDeleted : public LayerTreeTest {
2014 void ReleaseCallback(unsigned sync_point, bool lost_resource) {
2015 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
2016 EXPECT_FALSE(lost_resource);
2021 void SetMailbox(char mailbox_char) {
2022 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
2023 TextureMailbox mailbox(std::string(64, mailbox_char));
2024 scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create(
2026 &TextureLayerWithMailboxMainThreadDeleted::ReleaseCallback,
2027 base::Unretained(this)));
2028 layer_->SetTextureMailbox(mailbox, callback.Pass());
2031 virtual void SetupTree() OVERRIDE {
2032 gfx::Size bounds(100, 100);
2033 root_ = Layer::Create();
2034 root_->SetAnchorPoint(gfx::PointF());
2035 root_->SetBounds(bounds);
2037 layer_ = TextureLayer::CreateForMailbox(NULL);
2038 layer_->SetIsDrawable(true);
2039 layer_->SetAnchorPoint(gfx::PointF());
2040 layer_->SetBounds(bounds);
2042 root_->AddChild(layer_);
2043 layer_tree_host()->SetRootLayer(root_);
2044 layer_tree_host()->SetViewportSize(bounds);
2047 virtual void BeginTest() OVERRIDE {
2048 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
2050 callback_count_ = 0;
2052 // Set the mailbox on the main thread.
2054 EXPECT_EQ(0, callback_count_);
2056 PostSetNeedsCommitToMainThread();
2059 virtual void DidCommitAndDrawFrame() OVERRIDE {
2060 switch (layer_tree_host()->source_frame_number()) {
2062 // Delete the TextureLayer on the main thread while the mailbox is in
2064 layer_->RemoveFromParent();
2070 virtual void AfterTest() OVERRIDE {
2071 EXPECT_EQ(1, callback_count_);
2075 base::ThreadChecker main_thread_;
2076 int callback_count_;
2077 scoped_refptr<Layer> root_;
2078 scoped_refptr<TextureLayer> layer_;
2081 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
2082 TextureLayerWithMailboxMainThreadDeleted);
2084 class TextureLayerWithMailboxImplThreadDeleted : public LayerTreeTest {
2086 void ReleaseCallback(unsigned sync_point, bool lost_resource) {
2087 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
2088 EXPECT_FALSE(lost_resource);
2093 void SetMailbox(char mailbox_char) {
2094 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
2095 TextureMailbox mailbox(std::string(64, mailbox_char));
2096 scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create(
2098 &TextureLayerWithMailboxImplThreadDeleted::ReleaseCallback,
2099 base::Unretained(this)));
2100 layer_->SetTextureMailbox(mailbox, callback.Pass());
2103 virtual void SetupTree() OVERRIDE {
2104 gfx::Size bounds(100, 100);
2105 root_ = Layer::Create();
2106 root_->SetAnchorPoint(gfx::PointF());
2107 root_->SetBounds(bounds);
2109 layer_ = TextureLayer::CreateForMailbox(NULL);
2110 layer_->SetIsDrawable(true);
2111 layer_->SetAnchorPoint(gfx::PointF());
2112 layer_->SetBounds(bounds);
2114 root_->AddChild(layer_);
2115 layer_tree_host()->SetRootLayer(root_);
2116 layer_tree_host()->SetViewportSize(bounds);
2119 virtual void BeginTest() OVERRIDE {
2120 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
2122 callback_count_ = 0;
2124 // Set the mailbox on the main thread.
2126 EXPECT_EQ(0, callback_count_);
2128 PostSetNeedsCommitToMainThread();
2131 virtual void DidCommitAndDrawFrame() OVERRIDE {
2132 switch (layer_tree_host()->source_frame_number()) {
2134 // Remove the TextureLayer on the main thread while the mailbox is in
2135 // the impl tree, but don't delete the TextureLayer until after the impl
2136 // tree side is deleted.
2137 layer_->RemoveFromParent();
2145 virtual void AfterTest() OVERRIDE {
2146 EXPECT_EQ(1, callback_count_);
2150 base::ThreadChecker main_thread_;
2151 int callback_count_;
2152 scoped_refptr<Layer> root_;
2153 scoped_refptr<TextureLayer> layer_;
2156 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
2157 TextureLayerWithMailboxImplThreadDeleted);