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