blob: 55b4c738d22656ee99fdf9731f1040d14bd59391 [file] [log] [blame]
[email protected]c0dd24c2012-08-30 23:25:271// 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.
4
[email protected]cc3cfaa2013-03-18 09:05:525#include "cc/layers/texture_layer.h"
[email protected]c0dd24c2012-08-30 23:25:276
[email protected]de44a152013-01-08 15:28:467#include <string>
8
9#include "base/callback.h"
[email protected]681ccff2013-03-18 06:13:5210#include "cc/base/thread.h"
[email protected]97d519fb2013-03-29 02:27:5411#include "cc/layers/texture_layer_client.h"
[email protected]cc3cfaa2013-03-18 09:05:5212#include "cc/layers/texture_layer_impl.h"
[email protected]586d51ed2012-12-07 20:31:4513#include "cc/test/fake_impl_proxy.h"
[email protected]101441ce2012-10-16 01:45:0314#include "cc/test/fake_layer_tree_host_client.h"
[email protected]586d51ed2012-12-07 20:31:4515#include "cc/test/fake_layer_tree_host_impl.h"
[email protected]06d68d02013-04-19 18:46:2116#include "cc/test/layer_test_common.h"
[email protected]e216fef02013-03-20 22:56:1017#include "cc/test/layer_tree_test.h"
[email protected]556fd292013-03-18 08:03:0418#include "cc/trees/layer_tree_host.h"
19#include "cc/trees/layer_tree_impl.h"
20#include "cc/trees/single_thread_proxy.h"
[email protected]7f0c53db2012-10-02 00:23:1821#include "testing/gmock/include/gmock/gmock.h"
22#include "testing/gtest/include/gtest/gtest.h"
[email protected]c0dd24c2012-08-30 23:25:2723
[email protected]c0dd24c2012-08-30 23:25:2724using ::testing::Mock;
25using ::testing::_;
26using ::testing::AtLeast;
27using ::testing::AnyNumber;
28
[email protected]ba565742012-11-10 09:29:4829namespace cc {
[email protected]c0dd24c2012-08-30 23:25:2730namespace {
31
[email protected]408b5e22013-03-19 09:48:0932class MockLayerTreeHost : public LayerTreeHost {
[email protected]28571b042013-03-14 07:59:1533 public:
[email protected]bf691c22013-03-26 21:15:0634 explicit MockLayerTreeHost(LayerTreeHostClient* client)
[email protected]408b5e22013-03-19 09:48:0935 : LayerTreeHost(client, LayerTreeSettings()) {
[email protected]28571b042013-03-14 07:59:1536 Initialize(scoped_ptr<Thread>(NULL));
37 }
[email protected]c0dd24c2012-08-30 23:25:2738
[email protected]28571b042013-03-14 07:59:1539 MOCK_METHOD0(AcquireLayerTextures, void());
40 MOCK_METHOD0(SetNeedsCommit, void());
[email protected]c0dd24c2012-08-30 23:25:2741};
42
[email protected]96baf3e2012-10-22 23:09:5543class TextureLayerTest : public testing::Test {
[email protected]28571b042013-03-14 07:59:1544 public:
[email protected]408b5e22013-03-19 09:48:0945 TextureLayerTest()
46 : fake_client_(
47 FakeLayerTreeHostClient(FakeLayerTreeHostClient::DIRECT_3D)),
48 host_impl_(&proxy_) {}
[email protected]0f077a52012-09-08 01:45:2449
[email protected]28571b042013-03-14 07:59:1550 protected:
51 virtual void SetUp() {
[email protected]408b5e22013-03-19 09:48:0952 layer_tree_host_.reset(new MockLayerTreeHost(&fake_client_));
[email protected]28571b042013-03-14 07:59:1553 }
[email protected]c0dd24c2012-08-30 23:25:2754
[email protected]28571b042013-03-14 07:59:1555 virtual void TearDown() {
56 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
57 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(AnyNumber());
58 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
[email protected]c0dd24c2012-08-30 23:25:2759
[email protected]28571b042013-03-14 07:59:1560 layer_tree_host_->SetRootLayer(NULL);
61 layer_tree_host_.reset();
62 }
[email protected]c0dd24c2012-08-30 23:25:2763
[email protected]408b5e22013-03-19 09:48:0964 scoped_ptr<MockLayerTreeHost> layer_tree_host_;
[email protected]28571b042013-03-14 07:59:1565 FakeImplProxy proxy_;
[email protected]408b5e22013-03-19 09:48:0966 FakeLayerTreeHostClient fake_client_;
[email protected]28571b042013-03-14 07:59:1567 FakeLayerTreeHostImpl host_impl_;
[email protected]c0dd24c2012-08-30 23:25:2768};
69
[email protected]28571b042013-03-14 07:59:1570TEST_F(TextureLayerTest, SyncImplWhenChangingTextureId) {
71 scoped_refptr<TextureLayer> test_layer = TextureLayer::Create(NULL);
72 ASSERT_TRUE(test_layer);
[email protected]c0dd24c2012-08-30 23:25:2773
[email protected]28571b042013-03-14 07:59:1574 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(AnyNumber());
75 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
76 layer_tree_host_->SetRootLayer(test_layer);
77 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
78 EXPECT_EQ(test_layer->layer_tree_host(), layer_tree_host_.get());
[email protected]c0dd24c2012-08-30 23:25:2779
[email protected]28571b042013-03-14 07:59:1580 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
81 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
82 test_layer->SetTextureId(1);
83 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
[email protected]c0dd24c2012-08-30 23:25:2784
[email protected]28571b042013-03-14 07:59:1585 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(AtLeast(1));
86 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
87 test_layer->SetTextureId(2);
88 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
[email protected]c0dd24c2012-08-30 23:25:2789
[email protected]28571b042013-03-14 07:59:1590 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(AtLeast(1));
91 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
92 test_layer->SetTextureId(0);
93 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
[email protected]c0dd24c2012-08-30 23:25:2794}
95
[email protected]28571b042013-03-14 07:59:1596TEST_F(TextureLayerTest, SyncImplWhenDrawing) {
97 gfx::RectF dirty_rect(0.f, 0.f, 1.f, 1.f);
[email protected]031ccfff2012-10-26 00:57:3898
[email protected]28571b042013-03-14 07:59:1599 scoped_refptr<TextureLayer> test_layer = TextureLayer::Create(NULL);
100 ASSERT_TRUE(test_layer);
101 scoped_ptr<TextureLayerImpl> impl_layer;
102 impl_layer = TextureLayerImpl::Create(host_impl_.active_tree(), 1, false);
103 ASSERT_TRUE(impl_layer);
[email protected]031ccfff2012-10-26 00:57:38104
[email protected]28571b042013-03-14 07:59:15105 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(AnyNumber());
106 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
107 layer_tree_host_->SetRootLayer(test_layer);
108 test_layer->SetTextureId(1);
109 test_layer->SetIsDrawable(true);
110 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
111 EXPECT_EQ(test_layer->layer_tree_host(), layer_tree_host_.get());
[email protected]031ccfff2012-10-26 00:57:38112
[email protected]28571b042013-03-14 07:59:15113 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(1);
114 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(0);
115 test_layer->WillModifyTexture();
116 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
[email protected]031ccfff2012-10-26 00:57:38117
[email protected]28571b042013-03-14 07:59:15118 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
119 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1);
120 test_layer->SetNeedsDisplayRect(dirty_rect);
121 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
[email protected]031ccfff2012-10-26 00:57:38122
[email protected]28571b042013-03-14 07:59:15123 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
124 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1);
125 test_layer->PushPropertiesTo(impl_layer.get()); // fake commit
126 test_layer->SetIsDrawable(false);
127 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
[email protected]031ccfff2012-10-26 00:57:38128
[email protected]28571b042013-03-14 07:59:15129 // Verify that non-drawable layers don't signal the compositor,
130 // except for the first draw after last commit, which must acquire
131 // the texture.
132 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(1);
133 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(0);
134 test_layer->WillModifyTexture();
135 test_layer->SetNeedsDisplayRect(dirty_rect);
136 test_layer->PushPropertiesTo(impl_layer.get()); // fake commit
137 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
[email protected]031ccfff2012-10-26 00:57:38138
[email protected]28571b042013-03-14 07:59:15139 // Second draw with layer in non-drawable state: no texture
140 // acquisition.
141 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
142 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(0);
143 test_layer->WillModifyTexture();
144 test_layer->SetNeedsDisplayRect(dirty_rect);
145 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
[email protected]031ccfff2012-10-26 00:57:38146}
147
[email protected]28571b042013-03-14 07:59:15148TEST_F(TextureLayerTest, SyncImplWhenRemovingFromTree) {
149 scoped_refptr<Layer> root_layer = Layer::Create();
150 ASSERT_TRUE(root_layer);
151 scoped_refptr<Layer> child_layer = Layer::Create();
152 ASSERT_TRUE(child_layer);
153 root_layer->AddChild(child_layer);
154 scoped_refptr<TextureLayer> test_layer = TextureLayer::Create(NULL);
155 ASSERT_TRUE(test_layer);
156 test_layer->SetTextureId(0);
157 child_layer->AddChild(test_layer);
[email protected]c0dd24c2012-08-30 23:25:27158
[email protected]28571b042013-03-14 07:59:15159 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(AnyNumber());
160 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
161 layer_tree_host_->SetRootLayer(root_layer);
162 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
[email protected]c0dd24c2012-08-30 23:25:27163
[email protected]28571b042013-03-14 07:59:15164 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
165 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
166 test_layer->RemoveFromParent();
167 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
[email protected]c0dd24c2012-08-30 23:25:27168
[email protected]28571b042013-03-14 07:59:15169 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
170 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
171 child_layer->AddChild(test_layer);
172 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
[email protected]c0dd24c2012-08-30 23:25:27173
[email protected]28571b042013-03-14 07:59:15174 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
175 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
176 test_layer->SetTextureId(1);
177 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
[email protected]c0dd24c2012-08-30 23:25:27178
[email protected]28571b042013-03-14 07:59:15179 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(AtLeast(1));
180 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
181 test_layer->RemoveFromParent();
182 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
[email protected]c0dd24c2012-08-30 23:25:27183}
184
[email protected]06d68d02013-04-19 18:46:21185TEST_F(TextureLayerTest, CheckPropertyChangeCausesCorrectBehavior) {
186 scoped_refptr<TextureLayer> test_layer = TextureLayer::Create(NULL);
187 test_layer->SetLayerTreeHost(layer_tree_host_.get());
188
189 // Test properties that should call SetNeedsCommit. All properties need to
190 // be set to new values in order for SetNeedsCommit to be called.
191 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetFlipped(false));
192 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetUV(
193 gfx::PointF(0.25f, 0.25f), gfx::PointF(0.75f, 0.75f)));
194 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetVertexOpacity(
195 0.5f, 0.5f, 0.5f, 0.5f));
196 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetPremultipliedAlpha(false));
197 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetTextureId(1));
198
199 // Calling SetTextureId can call AcquireLayerTextures.
200 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(AnyNumber());
201}
202
[email protected]de44a152013-01-08 15:28:46203class MockMailboxCallback {
[email protected]28571b042013-03-14 07:59:15204 public:
[email protected]7ba3ca72013-04-11 06:37:25205 MOCK_METHOD3(Release, void(const std::string& mailbox,
206 unsigned sync_point,
207 bool lost_resource));
[email protected]de44a152013-01-08 15:28:46208};
209
210struct CommonMailboxObjects {
[email protected]28571b042013-03-14 07:59:15211 CommonMailboxObjects()
212 : mailbox_name1_(64, '1'),
213 mailbox_name2_(64, '2'),
214 sync_point1_(1),
215 sync_point2_(2) {
216 release_mailbox1_ = base::Bind(&MockMailboxCallback::Release,
217 base::Unretained(&mock_callback_),
218 mailbox_name1_);
219 release_mailbox2_ = base::Bind(&MockMailboxCallback::Release,
220 base::Unretained(&mock_callback_),
221 mailbox_name2_);
222 gpu::Mailbox m1;
223 m1.SetName(reinterpret_cast<const int8*>(mailbox_name1_.data()));
224 mailbox1_ = TextureMailbox(m1, release_mailbox1_, sync_point1_);
225 gpu::Mailbox m2;
226 m2.SetName(reinterpret_cast<const int8*>(mailbox_name2_.data()));
227 mailbox2_ = TextureMailbox(m2, release_mailbox2_, sync_point2_);
228 }
[email protected]de44a152013-01-08 15:28:46229
[email protected]28571b042013-03-14 07:59:15230 std::string mailbox_name1_;
231 std::string mailbox_name2_;
232 MockMailboxCallback mock_callback_;
233 TextureMailbox::ReleaseCallback release_mailbox1_;
234 TextureMailbox::ReleaseCallback release_mailbox2_;
235 TextureMailbox mailbox1_;
236 TextureMailbox mailbox2_;
237 unsigned sync_point1_;
238 unsigned sync_point2_;
[email protected]de44a152013-01-08 15:28:46239};
240
241class TextureLayerWithMailboxTest : public TextureLayerTest {
[email protected]28571b042013-03-14 07:59:15242 protected:
243 virtual void TearDown() {
244 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
245 EXPECT_CALL(test_data_.mock_callback_,
246 Release(test_data_.mailbox_name1_,
[email protected]7ba3ca72013-04-11 06:37:25247 test_data_.sync_point1_,
248 false)).Times(1);
[email protected]28571b042013-03-14 07:59:15249 TextureLayerTest::TearDown();
250 }
[email protected]de44a152013-01-08 15:28:46251
[email protected]28571b042013-03-14 07:59:15252 CommonMailboxObjects test_data_;
[email protected]de44a152013-01-08 15:28:46253};
254
[email protected]28571b042013-03-14 07:59:15255TEST_F(TextureLayerWithMailboxTest, ReplaceMailboxOnMainThreadBeforeCommit) {
[email protected]e8e4ae232013-04-12 00:26:01256 scoped_refptr<TextureLayer> test_layer = TextureLayer::CreateForMailbox(NULL);
[email protected]28571b042013-03-14 07:59:15257 ASSERT_TRUE(test_layer);
[email protected]de44a152013-01-08 15:28:46258
[email protected]28571b042013-03-14 07:59:15259 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
260 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
261 layer_tree_host_->SetRootLayer(test_layer);
262 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
[email protected]de44a152013-01-08 15:28:46263
[email protected]28571b042013-03-14 07:59:15264 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
265 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
266 test_layer->SetTextureMailbox(test_data_.mailbox1_);
267 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
[email protected]de44a152013-01-08 15:28:46268
[email protected]28571b042013-03-14 07:59:15269 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
270 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
271 EXPECT_CALL(test_data_.mock_callback_,
[email protected]7ba3ca72013-04-11 06:37:25272 Release(test_data_.mailbox_name1_,
273 test_data_.sync_point1_,
274 false))
[email protected]28571b042013-03-14 07:59:15275 .Times(1);
276 test_layer->SetTextureMailbox(test_data_.mailbox2_);
277 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
278 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]de44a152013-01-08 15:28:46279
[email protected]28571b042013-03-14 07:59:15280 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
281 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
282 EXPECT_CALL(test_data_.mock_callback_,
[email protected]7ba3ca72013-04-11 06:37:25283 Release(test_data_.mailbox_name2_,
284 test_data_.sync_point2_,
285 false))
[email protected]28571b042013-03-14 07:59:15286 .Times(1);
287 test_layer->SetTextureMailbox(TextureMailbox());
288 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
289 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]de44a152013-01-08 15:28:46290
[email protected]28571b042013-03-14 07:59:15291 // Test destructor.
292 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
293 test_layer->SetTextureMailbox(test_data_.mailbox1_);
[email protected]de44a152013-01-08 15:28:46294}
295
[email protected]e216fef02013-03-20 22:56:10296class TextureLayerImplWithMailboxThreadedCallback : public LayerTreeTest {
[email protected]28571b042013-03-14 07:59:15297 public:
298 TextureLayerImplWithMailboxThreadedCallback()
299 : callback_count_(0),
300 commit_count_(0) {}
301
302 // Make sure callback is received on main and doesn't block the impl thread.
[email protected]7ba3ca72013-04-11 06:37:25303 void ReleaseCallback(unsigned sync_point, bool lost_resource) {
[email protected]28571b042013-03-14 07:59:15304 EXPECT_EQ(true, proxy()->IsMainThread());
[email protected]7ba3ca72013-04-11 06:37:25305 EXPECT_FALSE(lost_resource);
[email protected]28571b042013-03-14 07:59:15306 ++callback_count_;
307 }
308
309 void SetMailbox(char mailbox_char) {
310 TextureMailbox mailbox(
311 std::string(64, mailbox_char),
312 base::Bind(
313 &TextureLayerImplWithMailboxThreadedCallback::ReleaseCallback,
314 base::Unretained(this)));
315 layer_->SetTextureMailbox(mailbox);
316 }
317
[email protected]e216fef02013-03-20 22:56:10318 virtual void BeginTest() OVERRIDE {
[email protected]28571b042013-03-14 07:59:15319 gfx::Size bounds(100, 100);
320 root_ = Layer::Create();
321 root_->SetAnchorPoint(gfx::PointF());
322 root_->SetBounds(bounds);
323
[email protected]e8e4ae232013-04-12 00:26:01324 layer_ = TextureLayer::CreateForMailbox(NULL);
[email protected]28571b042013-03-14 07:59:15325 layer_->SetIsDrawable(true);
326 layer_->SetAnchorPoint(gfx::PointF());
327 layer_->SetBounds(bounds);
328
329 root_->AddChild(layer_);
[email protected]e216fef02013-03-20 22:56:10330 layer_tree_host()->SetRootLayer(root_);
[email protected]18ce59702013-04-09 04:58:40331 layer_tree_host()->SetViewportSize(bounds);
[email protected]28571b042013-03-14 07:59:15332 SetMailbox('1');
333 EXPECT_EQ(0, callback_count_);
334
335 // Case #1: change mailbox before the commit. The old mailbox should be
336 // released immediately.
337 SetMailbox('2');
338 EXPECT_EQ(1, callback_count_);
[email protected]e216fef02013-03-20 22:56:10339 PostSetNeedsCommitToMainThread();
[email protected]28571b042013-03-14 07:59:15340 }
341
[email protected]e216fef02013-03-20 22:56:10342 virtual void DidCommit() OVERRIDE {
[email protected]28571b042013-03-14 07:59:15343 ++commit_count_;
344 switch (commit_count_) {
345 case 1:
346 // Case #2: change mailbox after the commit (and draw), where the
347 // layer draws. The old mailbox should be released during the next
348 // commit.
349 SetMailbox('3');
350 EXPECT_EQ(1, callback_count_);
351 break;
352 case 2:
353 // Old mailbox was released, task was posted, but won't execute
[email protected]ed511b8d2013-03-25 03:29:29354 // until this DidCommit returns.
[email protected]28571b042013-03-14 07:59:15355 // TODO(piman): fix this.
356 EXPECT_EQ(1, callback_count_);
[email protected]e216fef02013-03-20 22:56:10357 layer_tree_host()->SetNeedsCommit();
[email protected]28571b042013-03-14 07:59:15358 break;
359 case 3:
360 EXPECT_EQ(2, callback_count_);
361 // Case #3: change mailbox when the layer doesn't draw. The old
362 // mailbox should be released during the next commit.
363 layer_->SetBounds(gfx::Size());
364 SetMailbox('4');
365 break;
366 case 4:
367 // Old mailbox was released, task was posted, but won't execute
[email protected]ed511b8d2013-03-25 03:29:29368 // until this DidCommit returns.
[email protected]28571b042013-03-14 07:59:15369 // TODO(piman): fix this.
370 EXPECT_EQ(2, callback_count_);
[email protected]e216fef02013-03-20 22:56:10371 layer_tree_host()->SetNeedsCommit();
[email protected]28571b042013-03-14 07:59:15372 break;
373 case 5:
374 EXPECT_EQ(3, callback_count_);
375 // Case #4: release mailbox that was committed but never drawn. The
376 // old mailbox should be released during the next commit.
377 layer_->SetTextureMailbox(TextureMailbox());
378 break;
379 case 6:
380 // Old mailbox was released, task was posted, but won't execute
[email protected]ed511b8d2013-03-25 03:29:29381 // until this DidCommit returns.
[email protected]28571b042013-03-14 07:59:15382 // TODO(piman): fix this.
383 EXPECT_EQ(3, callback_count_);
[email protected]e216fef02013-03-20 22:56:10384 layer_tree_host()->SetNeedsCommit();
[email protected]28571b042013-03-14 07:59:15385 break;
386 case 7:
387 EXPECT_EQ(4, callback_count_);
[email protected]e216fef02013-03-20 22:56:10388 EndTest();
[email protected]28571b042013-03-14 07:59:15389 break;
390 default:
391 NOTREACHED();
392 break;
[email protected]de44a152013-01-08 15:28:46393 }
[email protected]28571b042013-03-14 07:59:15394 }
[email protected]de44a152013-01-08 15:28:46395
[email protected]e216fef02013-03-20 22:56:10396 virtual void AfterTest() OVERRIDE {}
[email protected]de44a152013-01-08 15:28:46397
[email protected]28571b042013-03-14 07:59:15398 private:
399 int callback_count_;
400 int commit_count_;
401 scoped_refptr<Layer> root_;
402 scoped_refptr<TextureLayer> layer_;
[email protected]de44a152013-01-08 15:28:46403};
404
405SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerImplWithMailboxThreadedCallback);
406
407class TextureLayerImplWithMailboxTest : public TextureLayerTest {
[email protected]28571b042013-03-14 07:59:15408 protected:
[email protected]408b5e22013-03-19 09:48:09409 TextureLayerImplWithMailboxTest()
410 : fake_client_(
411 FakeLayerTreeHostClient(FakeLayerTreeHostClient::DIRECT_3D)) {}
412
[email protected]28571b042013-03-14 07:59:15413 virtual void SetUp() {
414 TextureLayerTest::SetUp();
[email protected]408b5e22013-03-19 09:48:09415 layer_tree_host_.reset(new MockLayerTreeHost(&fake_client_));
[email protected]f74945f2013-03-21 17:08:36416 EXPECT_TRUE(host_impl_.InitializeRenderer(CreateFakeOutputSurface()));
[email protected]28571b042013-03-14 07:59:15417 }
[email protected]de44a152013-01-08 15:28:46418
[email protected]28571b042013-03-14 07:59:15419 CommonMailboxObjects test_data_;
[email protected]408b5e22013-03-19 09:48:09420 FakeLayerTreeHostClient fake_client_;
[email protected]de44a152013-01-08 15:28:46421};
422
[email protected]28571b042013-03-14 07:59:15423TEST_F(TextureLayerImplWithMailboxTest, TestImplLayerCallbacks) {
424 host_impl_.CreatePendingTree();
425 scoped_ptr<TextureLayerImpl> pending_layer;
426 pending_layer = TextureLayerImpl::Create(host_impl_.pending_tree(), 1, true);
427 ASSERT_TRUE(pending_layer);
[email protected]de44a152013-01-08 15:28:46428
[email protected]ed511b8d2013-03-25 03:29:29429 scoped_ptr<LayerImpl> active_layer(
[email protected]28571b042013-03-14 07:59:15430 pending_layer->CreateLayerImpl(host_impl_.active_tree()));
[email protected]ed511b8d2013-03-25 03:29:29431 ASSERT_TRUE(active_layer);
[email protected]de44a152013-01-08 15:28:46432
[email protected]1a37a0752013-03-17 21:25:49433 pending_layer->SetTextureMailbox(test_data_.mailbox1_);
[email protected]421e84f2013-02-22 03:27:15434
[email protected]28571b042013-03-14 07:59:15435 // Test multiple commits without an activation.
436 EXPECT_CALL(test_data_.mock_callback_,
[email protected]7ba3ca72013-04-11 06:37:25437 Release(test_data_.mailbox_name1_,
438 test_data_.sync_point1_,
439 false))
[email protected]28571b042013-03-14 07:59:15440 .Times(1);
[email protected]1a37a0752013-03-17 21:25:49441 pending_layer->SetTextureMailbox(test_data_.mailbox2_);
[email protected]28571b042013-03-14 07:59:15442 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]421e84f2013-02-22 03:27:15443
[email protected]28571b042013-03-14 07:59:15444 // Test callback after activation.
[email protected]ed511b8d2013-03-25 03:29:29445 pending_layer->PushPropertiesTo(active_layer.get());
446 active_layer->DidBecomeActive();
[email protected]421e84f2013-02-22 03:27:15447
[email protected]7ba3ca72013-04-11 06:37:25448 EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0);
[email protected]1a37a0752013-03-17 21:25:49449 pending_layer->SetTextureMailbox(test_data_.mailbox1_);
[email protected]28571b042013-03-14 07:59:15450 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]421e84f2013-02-22 03:27:15451
[email protected]7ba3ca72013-04-11 06:37:25452 EXPECT_CALL(test_data_.mock_callback_,
453 Release(test_data_.mailbox_name2_, _, false))
[email protected]28571b042013-03-14 07:59:15454 .Times(1);
[email protected]ed511b8d2013-03-25 03:29:29455 pending_layer->PushPropertiesTo(active_layer.get());
456 active_layer->DidBecomeActive();
[email protected]28571b042013-03-14 07:59:15457 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]de44a152013-01-08 15:28:46458
[email protected]28571b042013-03-14 07:59:15459 // Test resetting the mailbox.
[email protected]7ba3ca72013-04-11 06:37:25460 EXPECT_CALL(test_data_.mock_callback_,
461 Release(test_data_.mailbox_name1_, _, false))
[email protected]28571b042013-03-14 07:59:15462 .Times(1);
[email protected]1a37a0752013-03-17 21:25:49463 pending_layer->SetTextureMailbox(TextureMailbox());
[email protected]ed511b8d2013-03-25 03:29:29464 pending_layer->PushPropertiesTo(active_layer.get());
465 active_layer->DidBecomeActive();
[email protected]28571b042013-03-14 07:59:15466 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]de44a152013-01-08 15:28:46467
[email protected]28571b042013-03-14 07:59:15468 // Test destructor.
469 EXPECT_CALL(test_data_.mock_callback_,
[email protected]7ba3ca72013-04-11 06:37:25470 Release(test_data_.mailbox_name1_,
471 test_data_.sync_point1_,
472 false))
[email protected]28571b042013-03-14 07:59:15473 .Times(1);
[email protected]1a37a0752013-03-17 21:25:49474 pending_layer->SetTextureMailbox(test_data_.mailbox1_);
[email protected]de44a152013-01-08 15:28:46475}
476
[email protected]28571b042013-03-14 07:59:15477TEST_F(TextureLayerImplWithMailboxTest,
478 TestDestructorCallbackOnCreatedResource) {
479 scoped_ptr<TextureLayerImpl> impl_layer;
480 impl_layer = TextureLayerImpl::Create(host_impl_.active_tree(), 1, true);
481 ASSERT_TRUE(impl_layer);
[email protected]de44a152013-01-08 15:28:46482
[email protected]7ba3ca72013-04-11 06:37:25483 EXPECT_CALL(test_data_.mock_callback_,
484 Release(test_data_.mailbox_name1_, _, false))
[email protected]28571b042013-03-14 07:59:15485 .Times(1);
[email protected]1a37a0752013-03-17 21:25:49486 impl_layer->SetTextureMailbox(test_data_.mailbox1_);
[email protected]28571b042013-03-14 07:59:15487 impl_layer->WillDraw(host_impl_.active_tree()->resource_provider());
488 impl_layer->DidDraw(host_impl_.active_tree()->resource_provider());
[email protected]1a37a0752013-03-17 21:25:49489 impl_layer->SetTextureMailbox(TextureMailbox());
[email protected]de44a152013-01-08 15:28:46490}
491
[email protected]28571b042013-03-14 07:59:15492TEST_F(TextureLayerImplWithMailboxTest, TestCallbackOnInUseResource) {
493 ResourceProvider* provider = host_impl_.active_tree()->resource_provider();
494 ResourceProvider::ResourceId id =
495 provider->CreateResourceFromTextureMailbox(test_data_.mailbox1_);
496 provider->AllocateForTesting(id);
[email protected]de44a152013-01-08 15:28:46497
[email protected]28571b042013-03-14 07:59:15498 // Transfer some resources to the parent.
499 ResourceProvider::ResourceIdArray resource_ids_to_transfer;
500 resource_ids_to_transfer.push_back(id);
501 TransferableResourceArray list;
502 provider->PrepareSendToParent(resource_ids_to_transfer, &list);
503 EXPECT_TRUE(provider->InUseByConsumer(id));
[email protected]7ba3ca72013-04-11 06:37:25504 EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0);
[email protected]28571b042013-03-14 07:59:15505 provider->DeleteResource(id);
506 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]7ba3ca72013-04-11 06:37:25507 EXPECT_CALL(test_data_.mock_callback_,
508 Release(test_data_.mailbox_name1_, _, false))
[email protected]28571b042013-03-14 07:59:15509 .Times(1);
510 provider->ReceiveFromParent(list);
[email protected]de44a152013-01-08 15:28:46511}
512
[email protected]97d519fb2013-03-29 02:27:54513// Check that ClearClient correctly clears the state so that the impl side
514// doesn't try to use a texture that could have been destroyed.
[email protected]7ba3ca72013-04-11 06:37:25515class TextureLayerClientTest
516 : public LayerTreeTest,
517 public TextureLayerClient {
[email protected]97d519fb2013-03-29 02:27:54518 public:
519 TextureLayerClientTest()
520 : context_(NULL),
521 texture_(0),
522 commit_count_(0),
523 expected_used_textures_on_draw_(0),
524 expected_used_textures_on_commit_(0) {}
525
526 virtual scoped_ptr<OutputSurface> CreateOutputSurface() OVERRIDE {
527 scoped_ptr<TestWebGraphicsContext3D> context(
528 TestWebGraphicsContext3D::Create());
529 context_ = context.get();
530 texture_ = context->createTexture();
531 return FakeOutputSurface::Create3d(
532 context.PassAs<WebKit::WebGraphicsContext3D>()).PassAs<OutputSurface>();
533 }
534
[email protected]d5d9bc52013-04-01 23:16:39535 virtual unsigned PrepareTexture(ResourceUpdateQueue* queue) OVERRIDE {
[email protected]97d519fb2013-03-29 02:27:54536 return texture_;
537 }
538
[email protected]d5d9bc52013-04-01 23:16:39539 virtual WebKit::WebGraphicsContext3D* Context3d() OVERRIDE {
[email protected]97d519fb2013-03-29 02:27:54540 return context_;
541 }
542
[email protected]e8e4ae232013-04-12 00:26:01543 virtual bool PrepareTextureMailbox(cc::TextureMailbox* mailbox) OVERRIDE {
544 return false;
545 }
546
[email protected]97d519fb2013-03-29 02:27:54547 virtual void SetupTree() OVERRIDE {
548 scoped_refptr<Layer> root = Layer::Create();
549 root->SetBounds(gfx::Size(10, 10));
550 root->SetAnchorPoint(gfx::PointF());
551 root->SetIsDrawable(true);
552
553 texture_layer_ = TextureLayer::Create(this);
554 texture_layer_->SetBounds(gfx::Size(10, 10));
555 texture_layer_->SetAnchorPoint(gfx::PointF());
556 texture_layer_->SetIsDrawable(true);
557 root->AddChild(texture_layer_);
558
559 layer_tree_host()->SetRootLayer(root);
560 LayerTreeTest::SetupTree();
561 {
562 base::AutoLock lock(lock_);
563 expected_used_textures_on_commit_ = 1;
564 }
565 }
566
567 virtual void BeginTest() OVERRIDE {
568 PostSetNeedsCommitToMainThread();
569 }
570
571 virtual void DidCommitAndDrawFrame() OVERRIDE {
572 ++commit_count_;
573 switch (commit_count_) {
574 case 1:
575 texture_layer_->ClearClient();
576 texture_layer_->SetNeedsDisplay();
577 {
578 base::AutoLock lock(lock_);
579 expected_used_textures_on_commit_ = 0;
580 }
581 texture_ = 0;
582 break;
583 case 2:
584 EndTest();
585 break;
586 default:
587 NOTREACHED();
588 break;
589 }
590 }
591
592 virtual void BeginCommitOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
593 base::AutoLock lock(lock_);
594 expected_used_textures_on_draw_ = expected_used_textures_on_commit_;
595 }
596
597 virtual bool PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
598 LayerTreeHostImpl::FrameData* frame_data,
599 bool result) OVERRIDE {
600 context_->ResetUsedTextures();
601 return true;
602 }
603
604 virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl,
605 bool result) OVERRIDE {
606 ASSERT_TRUE(result);
607 EXPECT_EQ(expected_used_textures_on_draw_, context_->NumUsedTextures());
608 }
609
610 virtual void AfterTest() OVERRIDE {}
611
612 private:
613 scoped_refptr<TextureLayer> texture_layer_;
614 TestWebGraphicsContext3D* context_;
615 unsigned texture_;
616 int commit_count_;
617
618 // Used only on thread.
619 unsigned expected_used_textures_on_draw_;
620
621 // Used on either thread, protected by lock_.
622 base::Lock lock_;
623 unsigned expected_used_textures_on_commit_;
624};
625
626SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerClientTest);
627
[email protected]ba565742012-11-10 09:29:48628} // namespace
629} // namespace cc