blob: 3171cc6eb891069a03cbccc147a113d7d3f43a33 [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);
[email protected]22898ed2013-06-01 04:52:3072 ASSERT_TRUE(test_layer.get());
[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);
[email protected]22898ed2013-06-01 04:52:30100 ASSERT_TRUE(test_layer.get());
[email protected]28571b042013-03-14 07:59:15101 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();
[email protected]22898ed2013-06-01 04:52:30150 ASSERT_TRUE(root_layer.get());
[email protected]28571b042013-03-14 07:59:15151 scoped_refptr<Layer> child_layer = Layer::Create();
[email protected]22898ed2013-06-01 04:52:30152 ASSERT_TRUE(child_layer.get());
[email protected]28571b042013-03-14 07:59:15153 root_layer->AddChild(child_layer);
154 scoped_refptr<TextureLayer> test_layer = TextureLayer::Create(NULL);
[email protected]22898ed2013-06-01 04:52:30155 ASSERT_TRUE(test_layer.get());
[email protected]28571b042013-03-14 07:59:15156 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]22898ed2013-06-01 04:52:30257 ASSERT_TRUE(test_layer.get());
[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
[email protected]4145d172013-05-10 16:54:36405SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
406 TextureLayerImplWithMailboxThreadedCallback);
[email protected]de44a152013-01-08 15:28:46407
408class TextureLayerImplWithMailboxTest : public TextureLayerTest {
[email protected]28571b042013-03-14 07:59:15409 protected:
[email protected]408b5e22013-03-19 09:48:09410 TextureLayerImplWithMailboxTest()
411 : fake_client_(
412 FakeLayerTreeHostClient(FakeLayerTreeHostClient::DIRECT_3D)) {}
413
[email protected]28571b042013-03-14 07:59:15414 virtual void SetUp() {
415 TextureLayerTest::SetUp();
[email protected]408b5e22013-03-19 09:48:09416 layer_tree_host_.reset(new MockLayerTreeHost(&fake_client_));
[email protected]f74945f2013-03-21 17:08:36417 EXPECT_TRUE(host_impl_.InitializeRenderer(CreateFakeOutputSurface()));
[email protected]28571b042013-03-14 07:59:15418 }
[email protected]de44a152013-01-08 15:28:46419
[email protected]28571b042013-03-14 07:59:15420 CommonMailboxObjects test_data_;
[email protected]408b5e22013-03-19 09:48:09421 FakeLayerTreeHostClient fake_client_;
[email protected]de44a152013-01-08 15:28:46422};
423
[email protected]28571b042013-03-14 07:59:15424TEST_F(TextureLayerImplWithMailboxTest, TestImplLayerCallbacks) {
425 host_impl_.CreatePendingTree();
426 scoped_ptr<TextureLayerImpl> pending_layer;
427 pending_layer = TextureLayerImpl::Create(host_impl_.pending_tree(), 1, true);
428 ASSERT_TRUE(pending_layer);
[email protected]de44a152013-01-08 15:28:46429
[email protected]ed511b8d2013-03-25 03:29:29430 scoped_ptr<LayerImpl> active_layer(
[email protected]28571b042013-03-14 07:59:15431 pending_layer->CreateLayerImpl(host_impl_.active_tree()));
[email protected]ed511b8d2013-03-25 03:29:29432 ASSERT_TRUE(active_layer);
[email protected]de44a152013-01-08 15:28:46433
[email protected]1a37a0752013-03-17 21:25:49434 pending_layer->SetTextureMailbox(test_data_.mailbox1_);
[email protected]421e84f2013-02-22 03:27:15435
[email protected]28571b042013-03-14 07:59:15436 // Test multiple commits without an activation.
437 EXPECT_CALL(test_data_.mock_callback_,
[email protected]7ba3ca72013-04-11 06:37:25438 Release(test_data_.mailbox_name1_,
439 test_data_.sync_point1_,
440 false))
[email protected]28571b042013-03-14 07:59:15441 .Times(1);
[email protected]1a37a0752013-03-17 21:25:49442 pending_layer->SetTextureMailbox(test_data_.mailbox2_);
[email protected]28571b042013-03-14 07:59:15443 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]421e84f2013-02-22 03:27:15444
[email protected]28571b042013-03-14 07:59:15445 // Test callback after activation.
[email protected]ed511b8d2013-03-25 03:29:29446 pending_layer->PushPropertiesTo(active_layer.get());
447 active_layer->DidBecomeActive();
[email protected]421e84f2013-02-22 03:27:15448
[email protected]7ba3ca72013-04-11 06:37:25449 EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0);
[email protected]1a37a0752013-03-17 21:25:49450 pending_layer->SetTextureMailbox(test_data_.mailbox1_);
[email protected]28571b042013-03-14 07:59:15451 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]421e84f2013-02-22 03:27:15452
[email protected]7ba3ca72013-04-11 06:37:25453 EXPECT_CALL(test_data_.mock_callback_,
454 Release(test_data_.mailbox_name2_, _, false))
[email protected]28571b042013-03-14 07:59:15455 .Times(1);
[email protected]ed511b8d2013-03-25 03:29:29456 pending_layer->PushPropertiesTo(active_layer.get());
457 active_layer->DidBecomeActive();
[email protected]28571b042013-03-14 07:59:15458 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]de44a152013-01-08 15:28:46459
[email protected]28571b042013-03-14 07:59:15460 // Test resetting the mailbox.
[email protected]7ba3ca72013-04-11 06:37:25461 EXPECT_CALL(test_data_.mock_callback_,
462 Release(test_data_.mailbox_name1_, _, false))
[email protected]28571b042013-03-14 07:59:15463 .Times(1);
[email protected]1a37a0752013-03-17 21:25:49464 pending_layer->SetTextureMailbox(TextureMailbox());
[email protected]ed511b8d2013-03-25 03:29:29465 pending_layer->PushPropertiesTo(active_layer.get());
466 active_layer->DidBecomeActive();
[email protected]28571b042013-03-14 07:59:15467 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]de44a152013-01-08 15:28:46468
[email protected]28571b042013-03-14 07:59:15469 // Test destructor.
470 EXPECT_CALL(test_data_.mock_callback_,
[email protected]7ba3ca72013-04-11 06:37:25471 Release(test_data_.mailbox_name1_,
472 test_data_.sync_point1_,
473 false))
[email protected]28571b042013-03-14 07:59:15474 .Times(1);
[email protected]1a37a0752013-03-17 21:25:49475 pending_layer->SetTextureMailbox(test_data_.mailbox1_);
[email protected]de44a152013-01-08 15:28:46476}
477
[email protected]28571b042013-03-14 07:59:15478TEST_F(TextureLayerImplWithMailboxTest,
479 TestDestructorCallbackOnCreatedResource) {
480 scoped_ptr<TextureLayerImpl> impl_layer;
481 impl_layer = TextureLayerImpl::Create(host_impl_.active_tree(), 1, true);
482 ASSERT_TRUE(impl_layer);
[email protected]de44a152013-01-08 15:28:46483
[email protected]7ba3ca72013-04-11 06:37:25484 EXPECT_CALL(test_data_.mock_callback_,
485 Release(test_data_.mailbox_name1_, _, false))
[email protected]28571b042013-03-14 07:59:15486 .Times(1);
[email protected]1a37a0752013-03-17 21:25:49487 impl_layer->SetTextureMailbox(test_data_.mailbox1_);
[email protected]28571b042013-03-14 07:59:15488 impl_layer->WillDraw(host_impl_.active_tree()->resource_provider());
489 impl_layer->DidDraw(host_impl_.active_tree()->resource_provider());
[email protected]1a37a0752013-03-17 21:25:49490 impl_layer->SetTextureMailbox(TextureMailbox());
[email protected]de44a152013-01-08 15:28:46491}
492
[email protected]28571b042013-03-14 07:59:15493TEST_F(TextureLayerImplWithMailboxTest, TestCallbackOnInUseResource) {
494 ResourceProvider* provider = host_impl_.active_tree()->resource_provider();
495 ResourceProvider::ResourceId id =
496 provider->CreateResourceFromTextureMailbox(test_data_.mailbox1_);
497 provider->AllocateForTesting(id);
[email protected]de44a152013-01-08 15:28:46498
[email protected]28571b042013-03-14 07:59:15499 // Transfer some resources to the parent.
500 ResourceProvider::ResourceIdArray resource_ids_to_transfer;
501 resource_ids_to_transfer.push_back(id);
502 TransferableResourceArray list;
503 provider->PrepareSendToParent(resource_ids_to_transfer, &list);
504 EXPECT_TRUE(provider->InUseByConsumer(id));
[email protected]7ba3ca72013-04-11 06:37:25505 EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0);
[email protected]28571b042013-03-14 07:59:15506 provider->DeleteResource(id);
507 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]7ba3ca72013-04-11 06:37:25508 EXPECT_CALL(test_data_.mock_callback_,
509 Release(test_data_.mailbox_name1_, _, false))
[email protected]28571b042013-03-14 07:59:15510 .Times(1);
511 provider->ReceiveFromParent(list);
[email protected]de44a152013-01-08 15:28:46512}
513
[email protected]97d519fb2013-03-29 02:27:54514// Check that ClearClient correctly clears the state so that the impl side
515// doesn't try to use a texture that could have been destroyed.
[email protected]7ba3ca72013-04-11 06:37:25516class TextureLayerClientTest
517 : public LayerTreeTest,
518 public TextureLayerClient {
[email protected]97d519fb2013-03-29 02:27:54519 public:
520 TextureLayerClientTest()
521 : context_(NULL),
522 texture_(0),
523 commit_count_(0),
524 expected_used_textures_on_draw_(0),
525 expected_used_textures_on_commit_(0) {}
526
527 virtual scoped_ptr<OutputSurface> CreateOutputSurface() OVERRIDE {
528 scoped_ptr<TestWebGraphicsContext3D> context(
529 TestWebGraphicsContext3D::Create());
530 context_ = context.get();
531 texture_ = context->createTexture();
532 return FakeOutputSurface::Create3d(
533 context.PassAs<WebKit::WebGraphicsContext3D>()).PassAs<OutputSurface>();
534 }
535
[email protected]d5d9bc52013-04-01 23:16:39536 virtual unsigned PrepareTexture(ResourceUpdateQueue* queue) OVERRIDE {
[email protected]97d519fb2013-03-29 02:27:54537 return texture_;
538 }
539
[email protected]d5d9bc52013-04-01 23:16:39540 virtual WebKit::WebGraphicsContext3D* Context3d() OVERRIDE {
[email protected]97d519fb2013-03-29 02:27:54541 return context_;
542 }
543
[email protected]e8e4ae232013-04-12 00:26:01544 virtual bool PrepareTextureMailbox(cc::TextureMailbox* mailbox) OVERRIDE {
545 return false;
546 }
547
[email protected]97d519fb2013-03-29 02:27:54548 virtual void SetupTree() OVERRIDE {
549 scoped_refptr<Layer> root = Layer::Create();
550 root->SetBounds(gfx::Size(10, 10));
551 root->SetAnchorPoint(gfx::PointF());
552 root->SetIsDrawable(true);
553
554 texture_layer_ = TextureLayer::Create(this);
555 texture_layer_->SetBounds(gfx::Size(10, 10));
556 texture_layer_->SetAnchorPoint(gfx::PointF());
557 texture_layer_->SetIsDrawable(true);
558 root->AddChild(texture_layer_);
559
560 layer_tree_host()->SetRootLayer(root);
561 LayerTreeTest::SetupTree();
562 {
563 base::AutoLock lock(lock_);
564 expected_used_textures_on_commit_ = 1;
565 }
566 }
567
568 virtual void BeginTest() OVERRIDE {
569 PostSetNeedsCommitToMainThread();
570 }
571
572 virtual void DidCommitAndDrawFrame() OVERRIDE {
573 ++commit_count_;
574 switch (commit_count_) {
575 case 1:
576 texture_layer_->ClearClient();
577 texture_layer_->SetNeedsDisplay();
578 {
579 base::AutoLock lock(lock_);
580 expected_used_textures_on_commit_ = 0;
581 }
582 texture_ = 0;
583 break;
584 case 2:
585 EndTest();
586 break;
587 default:
588 NOTREACHED();
589 break;
590 }
591 }
592
593 virtual void BeginCommitOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
594 base::AutoLock lock(lock_);
595 expected_used_textures_on_draw_ = expected_used_textures_on_commit_;
596 }
597
598 virtual bool PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
599 LayerTreeHostImpl::FrameData* frame_data,
600 bool result) OVERRIDE {
601 context_->ResetUsedTextures();
602 return true;
603 }
604
605 virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl,
606 bool result) OVERRIDE {
607 ASSERT_TRUE(result);
608 EXPECT_EQ(expected_used_textures_on_draw_, context_->NumUsedTextures());
609 }
610
611 virtual void AfterTest() OVERRIDE {}
612
613 private:
614 scoped_refptr<TextureLayer> texture_layer_;
615 TestWebGraphicsContext3D* context_;
616 unsigned texture_;
617 int commit_count_;
618
619 // Used only on thread.
620 unsigned expected_used_textures_on_draw_;
621
622 // Used on either thread, protected by lock_.
623 base::Lock lock_;
624 unsigned expected_used_textures_on_commit_;
625};
626
[email protected]4145d172013-05-10 16:54:36627// The TextureLayerClient does not use mailboxes, so can't use a delegating
628// renderer.
629SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(TextureLayerClientTest);
[email protected]97d519fb2013-03-29 02:27:54630
[email protected]ba565742012-11-10 09:29:48631} // namespace
632} // namespace cc