blob: 729f4a1d6da47de120febf650e603b61779c92c4 [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]9794fb32013-08-29 09:49:5910#include "base/synchronization/waitable_event.h"
[email protected]95fc42142013-08-13 19:31:0511#include "cc/debug/test_web_graphics_context_3d.h"
[email protected]97d519fb2013-03-29 02:27:5412#include "cc/layers/texture_layer_client.h"
[email protected]cc3cfaa2013-03-18 09:05:5213#include "cc/layers/texture_layer_impl.h"
[email protected]e00bab022013-08-19 00:42:4514#include "cc/resources/returned_resource.h"
[email protected]586d51ed2012-12-07 20:31:4515#include "cc/test/fake_impl_proxy.h"
[email protected]101441ce2012-10-16 01:45:0316#include "cc/test/fake_layer_tree_host_client.h"
[email protected]586d51ed2012-12-07 20:31:4517#include "cc/test/fake_layer_tree_host_impl.h"
[email protected]199b715e2013-08-13 05:18:3418#include "cc/test/fake_output_surface.h"
[email protected]06d68d02013-04-19 18:46:2119#include "cc/test/layer_test_common.h"
[email protected]e216fef02013-03-20 22:56:1020#include "cc/test/layer_tree_test.h"
[email protected]9794fb32013-08-29 09:49:5921#include "cc/trees/blocking_task_runner.h"
[email protected]556fd292013-03-18 08:03:0422#include "cc/trees/layer_tree_host.h"
23#include "cc/trees/layer_tree_impl.h"
24#include "cc/trees/single_thread_proxy.h"
[email protected]0bf5a202013-07-10 14:50:5425#include "gpu/GLES2/gl2extchromium.h"
[email protected]7f0c53db2012-10-02 00:23:1826#include "testing/gmock/include/gmock/gmock.h"
27#include "testing/gtest/include/gtest/gtest.h"
[email protected]c0dd24c2012-08-30 23:25:2728
[email protected]c0dd24c2012-08-30 23:25:2729using ::testing::Mock;
30using ::testing::_;
31using ::testing::AtLeast;
32using ::testing::AnyNumber;
33
[email protected]ba565742012-11-10 09:29:4834namespace cc {
[email protected]c0dd24c2012-08-30 23:25:2735namespace {
36
[email protected]408b5e22013-03-19 09:48:0937class MockLayerTreeHost : public LayerTreeHost {
[email protected]28571b042013-03-14 07:59:1538 public:
[email protected]bf691c22013-03-26 21:15:0639 explicit MockLayerTreeHost(LayerTreeHostClient* client)
[email protected]408b5e22013-03-19 09:48:0940 : LayerTreeHost(client, LayerTreeSettings()) {
[email protected]810d40b72013-06-20 18:26:1541 Initialize(NULL);
[email protected]28571b042013-03-14 07:59:1542 }
[email protected]c0dd24c2012-08-30 23:25:2743
[email protected]28571b042013-03-14 07:59:1544 MOCK_METHOD0(AcquireLayerTextures, void());
45 MOCK_METHOD0(SetNeedsCommit, void());
[email protected]3519b872013-07-30 07:17:5046 MOCK_METHOD0(SetNeedsUpdateLayers, void());
[email protected]2f529812013-07-12 01:58:3947 MOCK_METHOD1(StartRateLimiter, void(WebKit::WebGraphicsContext3D* context));
48 MOCK_METHOD1(StopRateLimiter, void(WebKit::WebGraphicsContext3D* context));
[email protected]c0dd24c2012-08-30 23:25:2749};
50
[email protected]31d4df82013-07-18 10:17:2251class TextureLayerTest : public testing::Test {
52 public:
53 TextureLayerTest()
54 : fake_client_(
55 FakeLayerTreeHostClient(FakeLayerTreeHostClient::DIRECT_3D)),
56 host_impl_(&proxy_) {}
57
58 protected:
59 virtual void SetUp() {
60 layer_tree_host_.reset(new MockLayerTreeHost(&fake_client_));
61 }
62
63 virtual void TearDown() {
64 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
65 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(AnyNumber());
66 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
67
68 layer_tree_host_->SetRootLayer(NULL);
69 layer_tree_host_.reset();
70 }
71
72 scoped_ptr<MockLayerTreeHost> layer_tree_host_;
73 FakeImplProxy proxy_;
74 FakeLayerTreeHostClient fake_client_;
75 FakeLayerTreeHostImpl host_impl_;
76};
77
78TEST_F(TextureLayerTest, SyncImplWhenChangingTextureId) {
79 scoped_refptr<TextureLayer> test_layer = TextureLayer::Create(NULL);
80 ASSERT_TRUE(test_layer.get());
81
82 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(AnyNumber());
83 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
84 layer_tree_host_->SetRootLayer(test_layer);
85 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
86 EXPECT_EQ(test_layer->layer_tree_host(), layer_tree_host_.get());
87
88 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
89 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
90 test_layer->SetTextureId(1);
91 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
92
93 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(AtLeast(1));
94 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
95 test_layer->SetTextureId(2);
96 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
97
98 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(AtLeast(1));
99 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
100 test_layer->SetTextureId(0);
101 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
102}
103
104TEST_F(TextureLayerTest, SyncImplWhenDrawing) {
105 gfx::RectF dirty_rect(0.f, 0.f, 1.f, 1.f);
106
107 scoped_refptr<TextureLayer> test_layer = TextureLayer::Create(NULL);
108 ASSERT_TRUE(test_layer.get());
109 scoped_ptr<TextureLayerImpl> impl_layer;
110 impl_layer = TextureLayerImpl::Create(host_impl_.active_tree(), 1, false);
111 ASSERT_TRUE(impl_layer);
112
113 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(AnyNumber());
114 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
115 layer_tree_host_->SetRootLayer(test_layer);
116 test_layer->SetTextureId(1);
117 test_layer->SetIsDrawable(true);
118 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
119 EXPECT_EQ(test_layer->layer_tree_host(), layer_tree_host_.get());
120
121 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(1);
122 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(0);
123 test_layer->WillModifyTexture();
124 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
125
126 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
[email protected]3519b872013-07-30 07:17:50127 EXPECT_CALL(*layer_tree_host_, SetNeedsUpdateLayers()).Times(1);
[email protected]31d4df82013-07-18 10:17:22128 test_layer->SetNeedsDisplayRect(dirty_rect);
129 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
130
131 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
132 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1);
133 test_layer->PushPropertiesTo(impl_layer.get()); // fake commit
134 test_layer->SetIsDrawable(false);
135 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
136
137 // Verify that non-drawable layers don't signal the compositor,
138 // except for the first draw after last commit, which must acquire
139 // the texture.
140 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(1);
141 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(0);
142 test_layer->WillModifyTexture();
143 test_layer->SetNeedsDisplayRect(dirty_rect);
144 test_layer->PushPropertiesTo(impl_layer.get()); // fake commit
145 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
146
147 // Second draw with layer in non-drawable state: no texture
148 // acquisition.
149 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
150 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(0);
151 test_layer->WillModifyTexture();
152 test_layer->SetNeedsDisplayRect(dirty_rect);
153 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
154}
155
156TEST_F(TextureLayerTest, SyncImplWhenRemovingFromTree) {
157 scoped_refptr<Layer> root_layer = Layer::Create();
158 ASSERT_TRUE(root_layer.get());
159 scoped_refptr<Layer> child_layer = Layer::Create();
160 ASSERT_TRUE(child_layer.get());
161 root_layer->AddChild(child_layer);
162 scoped_refptr<TextureLayer> test_layer = TextureLayer::Create(NULL);
163 ASSERT_TRUE(test_layer.get());
164 test_layer->SetTextureId(0);
165 child_layer->AddChild(test_layer);
166
167 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(AnyNumber());
168 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
169 layer_tree_host_->SetRootLayer(root_layer);
170 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
171
172 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
173 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
174 test_layer->RemoveFromParent();
175 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
176
177 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
178 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
179 child_layer->AddChild(test_layer);
180 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
181
182 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
183 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
184 test_layer->SetTextureId(1);
185 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
186
187 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(AtLeast(1));
188 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
189 test_layer->RemoveFromParent();
190 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
191}
192
193TEST_F(TextureLayerTest, CheckPropertyChangeCausesCorrectBehavior) {
194 scoped_refptr<TextureLayer> test_layer = TextureLayer::Create(NULL);
195 layer_tree_host_->SetRootLayer(test_layer);
196
197 // Test properties that should call SetNeedsCommit. All properties need to
198 // be set to new values in order for SetNeedsCommit to be called.
199 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetFlipped(false));
200 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetUV(
201 gfx::PointF(0.25f, 0.25f), gfx::PointF(0.75f, 0.75f)));
202 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetVertexOpacity(
203 0.5f, 0.5f, 0.5f, 0.5f));
204 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetPremultipliedAlpha(false));
205 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetBlendBackgroundColor(true));
206 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetTextureId(1));
207
208 // Calling SetTextureId can call AcquireLayerTextures.
209 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(AnyNumber());
210}
211
[email protected]1c10e232013-07-31 12:35:43212TEST_F(TextureLayerTest, VisibleContentOpaqueRegion) {
213 const gfx::Size layer_bounds(100, 100);
214 const gfx::Rect layer_rect(layer_bounds);
215 const Region layer_region(layer_rect);
216
217 scoped_refptr<TextureLayer> layer = TextureLayer::Create(NULL);
218 layer->SetBounds(layer_bounds);
219 layer->draw_properties().visible_content_rect = layer_rect;
220 layer->SetBlendBackgroundColor(true);
221
222 // Verify initial conditions.
223 EXPECT_FALSE(layer->contents_opaque());
224 EXPECT_EQ(0u, layer->background_color());
225 EXPECT_EQ(Region().ToString(),
226 layer->VisibleContentOpaqueRegion().ToString());
227
228 // Opaque background.
229 layer->SetBackgroundColor(SK_ColorWHITE);
230 EXPECT_EQ(layer_region.ToString(),
231 layer->VisibleContentOpaqueRegion().ToString());
232
233 // Transparent background.
234 layer->SetBackgroundColor(SkColorSetARGB(100, 255, 255, 255));
235 EXPECT_EQ(Region().ToString(),
236 layer->VisibleContentOpaqueRegion().ToString());
237}
238
[email protected]2f529812013-07-12 01:58:39239class FakeTextureLayerClient : public TextureLayerClient {
240 public:
[email protected]31d4df82013-07-18 10:17:22241 FakeTextureLayerClient() : context_(TestWebGraphicsContext3D::Create()) {}
[email protected]2f529812013-07-12 01:58:39242
243 virtual unsigned PrepareTexture() OVERRIDE {
[email protected]31d4df82013-07-18 10:17:22244 return 0;
[email protected]2f529812013-07-12 01:58:39245 }
246
247 virtual WebKit::WebGraphicsContext3D* Context3d() OVERRIDE {
248 return context_.get();
249 }
250
251 virtual bool PrepareTextureMailbox(TextureMailbox* mailbox,
252 bool use_shared_memory) OVERRIDE {
[email protected]31d4df82013-07-18 10:17:22253 *mailbox = TextureMailbox();
[email protected]2f529812013-07-12 01:58:39254 return true;
255 }
256
257 private:
258 scoped_ptr<TestWebGraphicsContext3D> context_;
259 DISALLOW_COPY_AND_ASSIGN(FakeTextureLayerClient);
260};
261
[email protected]31d4df82013-07-18 10:17:22262TEST_F(TextureLayerTest, RateLimiter) {
263 FakeTextureLayerClient client;
264 scoped_refptr<TextureLayer> test_layer = TextureLayer::CreateForMailbox(
265 &client);
266 test_layer->SetIsDrawable(true);
267 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
268 layer_tree_host_->SetRootLayer(test_layer);
269
270 // Don't rate limit until we invalidate.
271 EXPECT_CALL(*layer_tree_host_, StartRateLimiter(_)).Times(0);
272 test_layer->SetRateLimitContext(true);
273 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
274
275 // Do rate limit after we invalidate.
276 EXPECT_CALL(*layer_tree_host_, StartRateLimiter(client.Context3d()));
277 test_layer->SetNeedsDisplay();
278 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
279
280 // Stop rate limiter when we don't want it any more.
281 EXPECT_CALL(*layer_tree_host_, StopRateLimiter(client.Context3d()));
282 test_layer->SetRateLimitContext(false);
283 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
284
285 // Or we clear the client.
286 test_layer->SetRateLimitContext(true);
287 EXPECT_CALL(*layer_tree_host_, StopRateLimiter(client.Context3d()));
288 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
289 test_layer->ClearClient();
290 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
291
292 // Reset to a layer with a client, that started the rate limiter.
293 test_layer = TextureLayer::CreateForMailbox(
294 &client);
295 test_layer->SetIsDrawable(true);
296 test_layer->SetRateLimitContext(true);
297 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
298 layer_tree_host_->SetRootLayer(test_layer);
299 EXPECT_CALL(*layer_tree_host_, StartRateLimiter(_)).Times(0);
300 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
301 EXPECT_CALL(*layer_tree_host_, StartRateLimiter(client.Context3d()));
302 test_layer->SetNeedsDisplay();
303 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
304
305 // Stop rate limiter when we're removed from the tree.
306 EXPECT_CALL(*layer_tree_host_, StopRateLimiter(client.Context3d()));
307 layer_tree_host_->SetRootLayer(NULL);
308 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
309}
310
[email protected]de44a152013-01-08 15:28:46311class MockMailboxCallback {
[email protected]28571b042013-03-14 07:59:15312 public:
[email protected]7ba3ca72013-04-11 06:37:25313 MOCK_METHOD3(Release, void(const std::string& mailbox,
314 unsigned sync_point,
315 bool lost_resource));
[email protected]42f40a52013-06-08 04:38:51316 MOCK_METHOD3(Release2, void(base::SharedMemory* shared_memory,
317 unsigned sync_point,
318 bool lost_resource));
[email protected]de44a152013-01-08 15:28:46319};
320
321struct CommonMailboxObjects {
[email protected]28571b042013-03-14 07:59:15322 CommonMailboxObjects()
323 : mailbox_name1_(64, '1'),
324 mailbox_name2_(64, '2'),
325 sync_point1_(1),
[email protected]42f40a52013-06-08 04:38:51326 sync_point2_(2),
327 shared_memory_(new base::SharedMemory) {
[email protected]28571b042013-03-14 07:59:15328 release_mailbox1_ = base::Bind(&MockMailboxCallback::Release,
329 base::Unretained(&mock_callback_),
330 mailbox_name1_);
331 release_mailbox2_ = base::Bind(&MockMailboxCallback::Release,
332 base::Unretained(&mock_callback_),
333 mailbox_name2_);
334 gpu::Mailbox m1;
335 m1.SetName(reinterpret_cast<const int8*>(mailbox_name1_.data()));
336 mailbox1_ = TextureMailbox(m1, release_mailbox1_, sync_point1_);
337 gpu::Mailbox m2;
338 m2.SetName(reinterpret_cast<const int8*>(mailbox_name2_.data()));
339 mailbox2_ = TextureMailbox(m2, release_mailbox2_, sync_point2_);
[email protected]42f40a52013-06-08 04:38:51340
341 gfx::Size size(128, 128);
342 EXPECT_TRUE(shared_memory_->CreateAndMapAnonymous(4 * size.GetArea()));
343 release_mailbox3_ = base::Bind(&MockMailboxCallback::Release2,
344 base::Unretained(&mock_callback_),
345 shared_memory_.get());
346 mailbox3_ = TextureMailbox(shared_memory_.get(), size, release_mailbox3_);
[email protected]28571b042013-03-14 07:59:15347 }
[email protected]de44a152013-01-08 15:28:46348
[email protected]28571b042013-03-14 07:59:15349 std::string mailbox_name1_;
350 std::string mailbox_name2_;
351 MockMailboxCallback mock_callback_;
352 TextureMailbox::ReleaseCallback release_mailbox1_;
353 TextureMailbox::ReleaseCallback release_mailbox2_;
[email protected]42f40a52013-06-08 04:38:51354 TextureMailbox::ReleaseCallback release_mailbox3_;
[email protected]28571b042013-03-14 07:59:15355 TextureMailbox mailbox1_;
356 TextureMailbox mailbox2_;
[email protected]42f40a52013-06-08 04:38:51357 TextureMailbox mailbox3_;
[email protected]28571b042013-03-14 07:59:15358 unsigned sync_point1_;
359 unsigned sync_point2_;
[email protected]42f40a52013-06-08 04:38:51360 scoped_ptr<base::SharedMemory> shared_memory_;
[email protected]de44a152013-01-08 15:28:46361};
362
[email protected]9794fb32013-08-29 09:49:59363class TestMailboxHolder : public TextureLayer::MailboxHolder {
364 public:
365 using TextureLayer::MailboxHolder::Create;
366
367 protected:
368 virtual ~TestMailboxHolder() {}
369};
370
[email protected]de44a152013-01-08 15:28:46371class TextureLayerWithMailboxTest : public TextureLayerTest {
[email protected]28571b042013-03-14 07:59:15372 protected:
373 virtual void TearDown() {
374 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
375 EXPECT_CALL(test_data_.mock_callback_,
376 Release(test_data_.mailbox_name1_,
[email protected]7ba3ca72013-04-11 06:37:25377 test_data_.sync_point1_,
378 false)).Times(1);
[email protected]28571b042013-03-14 07:59:15379 TextureLayerTest::TearDown();
380 }
[email protected]de44a152013-01-08 15:28:46381
[email protected]28571b042013-03-14 07:59:15382 CommonMailboxObjects test_data_;
[email protected]de44a152013-01-08 15:28:46383};
384
[email protected]28571b042013-03-14 07:59:15385TEST_F(TextureLayerWithMailboxTest, ReplaceMailboxOnMainThreadBeforeCommit) {
[email protected]e8e4ae232013-04-12 00:26:01386 scoped_refptr<TextureLayer> test_layer = TextureLayer::CreateForMailbox(NULL);
[email protected]22898ed2013-06-01 04:52:30387 ASSERT_TRUE(test_layer.get());
[email protected]de44a152013-01-08 15:28:46388
[email protected]28571b042013-03-14 07:59:15389 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
390 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
391 layer_tree_host_->SetRootLayer(test_layer);
392 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
[email protected]de44a152013-01-08 15:28:46393
[email protected]28571b042013-03-14 07:59:15394 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
395 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
396 test_layer->SetTextureMailbox(test_data_.mailbox1_);
397 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
[email protected]de44a152013-01-08 15:28:46398
[email protected]28571b042013-03-14 07:59:15399 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
400 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
401 EXPECT_CALL(test_data_.mock_callback_,
[email protected]7ba3ca72013-04-11 06:37:25402 Release(test_data_.mailbox_name1_,
403 test_data_.sync_point1_,
404 false))
[email protected]28571b042013-03-14 07:59:15405 .Times(1);
406 test_layer->SetTextureMailbox(test_data_.mailbox2_);
407 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
408 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]de44a152013-01-08 15:28:46409
[email protected]28571b042013-03-14 07:59:15410 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
411 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
412 EXPECT_CALL(test_data_.mock_callback_,
[email protected]7ba3ca72013-04-11 06:37:25413 Release(test_data_.mailbox_name2_,
414 test_data_.sync_point2_,
415 false))
[email protected]28571b042013-03-14 07:59:15416 .Times(1);
417 test_layer->SetTextureMailbox(TextureMailbox());
418 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
419 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]de44a152013-01-08 15:28:46420
[email protected]42f40a52013-06-08 04:38:51421 test_layer->SetTextureMailbox(test_data_.mailbox3_);
422 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
423 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
424
425 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
426 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
427 EXPECT_CALL(test_data_.mock_callback_,
428 Release2(test_data_.shared_memory_.get(),
429 0, false))
430 .Times(1);
431 test_layer->SetTextureMailbox(TextureMailbox());
432 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
433 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
434
[email protected]28571b042013-03-14 07:59:15435 // Test destructor.
436 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
437 test_layer->SetTextureMailbox(test_data_.mailbox1_);
[email protected]de44a152013-01-08 15:28:46438}
439
[email protected]9794fb32013-08-29 09:49:59440class TextureLayerMailboxHolderTest : public TextureLayerTest {
441 public:
442 TextureLayerMailboxHolderTest()
443 : main_thread_("MAIN") {
444 main_thread_.Start();
445 }
446
447 void Wait(const base::Thread& thread) {
448 bool manual_reset = false;
449 bool initially_signaled = false;
450 base::WaitableEvent event(manual_reset, initially_signaled);
451 thread.message_loop()->PostTask(
452 FROM_HERE,
453 base::Bind(&base::WaitableEvent::Signal, base::Unretained(&event)));
454 event.Wait();
455 }
456
457 void CreateMainRef() {
458 main_ref_ = TestMailboxHolder::Create(
459 test_data_.mailbox1_).Pass();
460 }
461
462 void ReleaseMainRef() {
463 main_ref_.reset();
464 }
465
466 void CreateImplRef(TextureMailbox::ReleaseCallback* impl_ref) {
467 *impl_ref = main_ref_->holder()->GetCallbackForImplThread();
468 }
469
470 void CapturePostTasksAndWait(base::WaitableEvent* begin_capture,
471 base::WaitableEvent* wait_for_capture,
472 base::WaitableEvent* stop_capture) {
473 begin_capture->Wait();
474 BlockingTaskRunner::CapturePostTasks capture;
475 wait_for_capture->Signal();
476 stop_capture->Wait();
477 }
478
479 protected:
480 scoped_ptr<TestMailboxHolder::MainThreadReference>
481 main_ref_;
482 base::Thread main_thread_;
483 CommonMailboxObjects test_data_;
484};
485
486TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_BothReleaseThenMain) {
487 scoped_refptr<TextureLayer> test_layer = TextureLayer::CreateForMailbox(NULL);
488 ASSERT_TRUE(test_layer.get());
489
490 main_thread_.message_loop()->PostTask(
491 FROM_HERE,
492 base::Bind(&TextureLayerMailboxHolderTest::CreateMainRef,
493 base::Unretained(this)));
494
495 Wait(main_thread_);
496
497 // The texture layer is attached to compositor1, and passes a reference to its
498 // impl tree.
499 TextureMailbox::ReleaseCallback compositor1;
500 main_thread_.message_loop()->PostTask(
501 FROM_HERE,
502 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
503 base::Unretained(this),
504 &compositor1));
505
506 // Then the texture layer is removed and attached to compositor2, and passes a
507 // reference to its impl tree.
508 TextureMailbox::ReleaseCallback compositor2;
509 main_thread_.message_loop()->PostTask(
510 FROM_HERE,
511 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
512 base::Unretained(this),
513 &compositor2));
514
515 Wait(main_thread_);
516 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
517
518 // The compositors both destroy their impl trees before the main thread layer
519 // is destroyed.
520 compositor1.Run(100, false);
521 compositor2.Run(200, false);
522
523 Wait(main_thread_);
524
525 EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0);
526 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
527
528 // The main thread ref is the last one, so the mailbox is released back to the
529 // embedder, with the last sync point provided by the impl trees.
530 EXPECT_CALL(test_data_.mock_callback_,
531 Release(test_data_.mailbox_name1_, 200, false)).Times(1);
532
533 main_thread_.message_loop()->PostTask(
534 FROM_HERE,
535 base::Bind(&TextureLayerMailboxHolderTest::ReleaseMainRef,
536 base::Unretained(this)));
537 Wait(main_thread_);
538 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
539}
540
541TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_MainReleaseBetween) {
542 scoped_refptr<TextureLayer> test_layer = TextureLayer::CreateForMailbox(NULL);
543 ASSERT_TRUE(test_layer.get());
544
545 main_thread_.message_loop()->PostTask(
546 FROM_HERE,
547 base::Bind(&TextureLayerMailboxHolderTest::CreateMainRef,
548 base::Unretained(this)));
549
550 Wait(main_thread_);
551
552 // The texture layer is attached to compositor1, and passes a reference to its
553 // impl tree.
554 TextureMailbox::ReleaseCallback compositor1;
555 main_thread_.message_loop()->PostTask(
556 FROM_HERE,
557 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
558 base::Unretained(this),
559 &compositor1));
560
561 // Then the texture layer is removed and attached to compositor2, and passes a
562 // reference to its impl tree.
563 TextureMailbox::ReleaseCallback compositor2;
564 main_thread_.message_loop()->PostTask(
565 FROM_HERE,
566 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
567 base::Unretained(this),
568 &compositor2));
569
570 Wait(main_thread_);
571 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
572
573 // One compositor destroys their impl tree.
574 compositor1.Run(100, false);
575
576 // Then the main thread reference is destroyed.
577 main_thread_.message_loop()->PostTask(
578 FROM_HERE,
579 base::Bind(&TextureLayerMailboxHolderTest::ReleaseMainRef,
580 base::Unretained(this)));
581
582 Wait(main_thread_);
583
584 EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0);
585 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
586
587 // The second impl reference is destroyed last, causing the mailbox to be
588 // released back to the embedder with the last sync point from the impl tree.
589 EXPECT_CALL(test_data_.mock_callback_,
590 Release(test_data_.mailbox_name1_, 200, true)).Times(1);
591
592 compositor2.Run(200, true);
593 Wait(main_thread_);
594 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
595}
596
597TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_MainReleasedFirst) {
598 scoped_refptr<TextureLayer> test_layer = TextureLayer::CreateForMailbox(NULL);
599 ASSERT_TRUE(test_layer.get());
600
601 main_thread_.message_loop()->PostTask(
602 FROM_HERE,
603 base::Bind(&TextureLayerMailboxHolderTest::CreateMainRef,
604 base::Unretained(this)));
605
606 Wait(main_thread_);
607
608 // The texture layer is attached to compositor1, and passes a reference to its
609 // impl tree.
610 TextureMailbox::ReleaseCallback compositor1;
611 main_thread_.message_loop()->PostTask(
612 FROM_HERE,
613 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
614 base::Unretained(this),
615 &compositor1));
616
617 // Then the texture layer is removed and attached to compositor2, and passes a
618 // reference to its impl tree.
619 TextureMailbox::ReleaseCallback compositor2;
620 main_thread_.message_loop()->PostTask(
621 FROM_HERE,
622 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
623 base::Unretained(this),
624 &compositor2));
625
626 Wait(main_thread_);
627 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
628
629 // The main thread reference is destroyed first.
630 main_thread_.message_loop()->PostTask(
631 FROM_HERE,
632 base::Bind(&TextureLayerMailboxHolderTest::ReleaseMainRef,
633 base::Unretained(this)));
634
635 // One compositor destroys their impl tree.
636 compositor2.Run(200, false);
637
638 Wait(main_thread_);
639
640 EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0);
641 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
642
643 // The second impl reference is destroyed last, causing the mailbox to be
644 // released back to the embedder with the last sync point from the impl tree.
645 EXPECT_CALL(test_data_.mock_callback_,
646 Release(test_data_.mailbox_name1_, 100, true)).Times(1);
647
648 compositor1.Run(100, true);
649 Wait(main_thread_);
650 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
651}
652
653TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_SecondImplRefShortcut) {
654 scoped_refptr<TextureLayer> test_layer = TextureLayer::CreateForMailbox(NULL);
655 ASSERT_TRUE(test_layer.get());
656
657 main_thread_.message_loop()->PostTask(
658 FROM_HERE,
659 base::Bind(&TextureLayerMailboxHolderTest::CreateMainRef,
660 base::Unretained(this)));
661
662 Wait(main_thread_);
663
664 // The texture layer is attached to compositor1, and passes a reference to its
665 // impl tree.
666 TextureMailbox::ReleaseCallback compositor1;
667 main_thread_.message_loop()->PostTask(
668 FROM_HERE,
669 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
670 base::Unretained(this),
671 &compositor1));
672
673 // Then the texture layer is removed and attached to compositor2, and passes a
674 // reference to its impl tree.
675 TextureMailbox::ReleaseCallback compositor2;
676 main_thread_.message_loop()->PostTask(
677 FROM_HERE,
678 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
679 base::Unretained(this),
680 &compositor2));
681
682 Wait(main_thread_);
683 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
684
685 // The main thread reference is destroyed first.
686 main_thread_.message_loop()->PostTask(
687 FROM_HERE,
688 base::Bind(&TextureLayerMailboxHolderTest::ReleaseMainRef,
689 base::Unretained(this)));
690
691 EXPECT_CALL(test_data_.mock_callback_,
692 Release(test_data_.mailbox_name1_, 200, true)).Times(1);
693
694 bool manual_reset = false;
695 bool initially_signaled = false;
696 base::WaitableEvent begin_capture(manual_reset, initially_signaled);
697 base::WaitableEvent wait_for_capture(manual_reset, initially_signaled);
698 base::WaitableEvent stop_capture(manual_reset, initially_signaled);
699
700 // Post a task to start capturing tasks on the main thread. This will block
701 // the main thread until we signal the |stop_capture| event.
702 main_thread_.message_loop()->PostTask(
703 FROM_HERE,
704 base::Bind(&TextureLayerMailboxHolderTest::CapturePostTasksAndWait,
705 base::Unretained(this),
706 &begin_capture,
707 &wait_for_capture,
708 &stop_capture));
709
710 // Before the main thread capturing starts, one compositor destroys their
711 // impl reference. Since capturing did not start, this gets post-tasked to
712 // the main thread.
713 compositor1.Run(100, false);
714
715 // Start capturing on the main thread.
716 begin_capture.Signal();
717 wait_for_capture.Wait();
718
719 // Meanwhile, the second compositor released its impl reference, but this task
720 // gets shortcutted directly to the main thread. This means the reference is
721 // released before compositor1, whose reference will be released later when
722 // the post-task is serviced. But since it was destroyed _on the impl thread_
723 // last, its sync point values should be used.
724 compositor2.Run(200, true);
725
726 stop_capture.Signal();
727 Wait(main_thread_);
728
729 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
730}
731
[email protected]e216fef02013-03-20 22:56:10732class TextureLayerImplWithMailboxThreadedCallback : public LayerTreeTest {
[email protected]28571b042013-03-14 07:59:15733 public:
734 TextureLayerImplWithMailboxThreadedCallback()
735 : callback_count_(0),
736 commit_count_(0) {}
737
738 // Make sure callback is received on main and doesn't block the impl thread.
[email protected]7ba3ca72013-04-11 06:37:25739 void ReleaseCallback(unsigned sync_point, bool lost_resource) {
[email protected]9794fb32013-08-29 09:49:59740 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]7ba3ca72013-04-11 06:37:25741 EXPECT_FALSE(lost_resource);
[email protected]28571b042013-03-14 07:59:15742 ++callback_count_;
743 }
744
745 void SetMailbox(char mailbox_char) {
[email protected]9794fb32013-08-29 09:49:59746 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]28571b042013-03-14 07:59:15747 TextureMailbox mailbox(
748 std::string(64, mailbox_char),
749 base::Bind(
750 &TextureLayerImplWithMailboxThreadedCallback::ReleaseCallback,
751 base::Unretained(this)));
752 layer_->SetTextureMailbox(mailbox);
753 }
754
[email protected]e216fef02013-03-20 22:56:10755 virtual void BeginTest() OVERRIDE {
[email protected]9794fb32013-08-29 09:49:59756 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
757
[email protected]28571b042013-03-14 07:59:15758 gfx::Size bounds(100, 100);
759 root_ = Layer::Create();
760 root_->SetAnchorPoint(gfx::PointF());
761 root_->SetBounds(bounds);
762
[email protected]e8e4ae232013-04-12 00:26:01763 layer_ = TextureLayer::CreateForMailbox(NULL);
[email protected]28571b042013-03-14 07:59:15764 layer_->SetIsDrawable(true);
765 layer_->SetAnchorPoint(gfx::PointF());
766 layer_->SetBounds(bounds);
767
768 root_->AddChild(layer_);
[email protected]e216fef02013-03-20 22:56:10769 layer_tree_host()->SetRootLayer(root_);
[email protected]18ce59702013-04-09 04:58:40770 layer_tree_host()->SetViewportSize(bounds);
[email protected]28571b042013-03-14 07:59:15771 SetMailbox('1');
772 EXPECT_EQ(0, callback_count_);
773
774 // Case #1: change mailbox before the commit. The old mailbox should be
775 // released immediately.
776 SetMailbox('2');
777 EXPECT_EQ(1, callback_count_);
[email protected]e216fef02013-03-20 22:56:10778 PostSetNeedsCommitToMainThread();
[email protected]28571b042013-03-14 07:59:15779 }
780
[email protected]e216fef02013-03-20 22:56:10781 virtual void DidCommit() OVERRIDE {
[email protected]28571b042013-03-14 07:59:15782 ++commit_count_;
783 switch (commit_count_) {
784 case 1:
785 // Case #2: change mailbox after the commit (and draw), where the
786 // layer draws. The old mailbox should be released during the next
787 // commit.
788 SetMailbox('3');
789 EXPECT_EQ(1, callback_count_);
790 break;
791 case 2:
[email protected]28571b042013-03-14 07:59:15792 EXPECT_EQ(2, callback_count_);
793 // Case #3: change mailbox when the layer doesn't draw. The old
794 // mailbox should be released during the next commit.
795 layer_->SetBounds(gfx::Size());
796 SetMailbox('4');
797 break;
[email protected]9794fb32013-08-29 09:49:59798 case 3:
[email protected]28571b042013-03-14 07:59:15799 EXPECT_EQ(3, callback_count_);
800 // Case #4: release mailbox that was committed but never drawn. The
801 // old mailbox should be released during the next commit.
802 layer_->SetTextureMailbox(TextureMailbox());
803 break;
[email protected]9794fb32013-08-29 09:49:59804 case 4:
805 if (layer_tree_host()->settings().impl_side_painting) {
806 // With impl painting, the texture mailbox will still be on the impl
807 // thread when the commit finishes, because the layer is not drawble
808 // when it has no texture mailbox, and thus does not block the commit
809 // on activation. So, we wait for activation.
810 // TODO(danakj): fix this. crbug.com/277953
811 layer_tree_host()->SetNeedsCommit();
812 break;
813 } else {
814 ++commit_count_;
815 }
816 case 5:
[email protected]28571b042013-03-14 07:59:15817 EXPECT_EQ(4, callback_count_);
[email protected]7096acc2013-06-18 21:12:43818 // Restore a mailbox for the next step.
819 SetMailbox('5');
820 break;
[email protected]9794fb32013-08-29 09:49:59821 case 6:
[email protected]7096acc2013-06-18 21:12:43822 // Case #5: remove layer from tree. Callback should *not* be called, the
823 // mailbox is returned to the main thread.
824 EXPECT_EQ(4, callback_count_);
825 layer_->RemoveFromParent();
826 break;
[email protected]9794fb32013-08-29 09:49:59827 case 7:
828 if (layer_tree_host()->settings().impl_side_painting) {
829 // With impl painting, the texture mailbox will still be on the impl
830 // thread when the commit finishes, because the layer is not around to
831 // block the commit on activation anymore. So, we wait for activation.
832 // TODO(danakj): fix this. crbug.com/277953
833 layer_tree_host()->SetNeedsCommit();
834 break;
835 } else {
836 ++commit_count_;
837 }
838 case 8:
[email protected]7096acc2013-06-18 21:12:43839 EXPECT_EQ(4, callback_count_);
840 // Resetting the mailbox will call the callback now.
841 layer_->SetTextureMailbox(TextureMailbox());
842 EXPECT_EQ(5, callback_count_);
[email protected]e216fef02013-03-20 22:56:10843 EndTest();
[email protected]28571b042013-03-14 07:59:15844 break;
845 default:
846 NOTREACHED();
847 break;
[email protected]de44a152013-01-08 15:28:46848 }
[email protected]28571b042013-03-14 07:59:15849 }
[email protected]de44a152013-01-08 15:28:46850
[email protected]e216fef02013-03-20 22:56:10851 virtual void AfterTest() OVERRIDE {}
[email protected]de44a152013-01-08 15:28:46852
[email protected]28571b042013-03-14 07:59:15853 private:
[email protected]9794fb32013-08-29 09:49:59854 base::ThreadChecker main_thread_;
[email protected]28571b042013-03-14 07:59:15855 int callback_count_;
856 int commit_count_;
857 scoped_refptr<Layer> root_;
858 scoped_refptr<TextureLayer> layer_;
[email protected]de44a152013-01-08 15:28:46859};
860
[email protected]4145d172013-05-10 16:54:36861SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
862 TextureLayerImplWithMailboxThreadedCallback);
[email protected]de44a152013-01-08 15:28:46863
864class TextureLayerImplWithMailboxTest : public TextureLayerTest {
[email protected]28571b042013-03-14 07:59:15865 protected:
[email protected]408b5e22013-03-19 09:48:09866 TextureLayerImplWithMailboxTest()
867 : fake_client_(
868 FakeLayerTreeHostClient(FakeLayerTreeHostClient::DIRECT_3D)) {}
869
[email protected]28571b042013-03-14 07:59:15870 virtual void SetUp() {
871 TextureLayerTest::SetUp();
[email protected]408b5e22013-03-19 09:48:09872 layer_tree_host_.reset(new MockLayerTreeHost(&fake_client_));
[email protected]f74945f2013-03-21 17:08:36873 EXPECT_TRUE(host_impl_.InitializeRenderer(CreateFakeOutputSurface()));
[email protected]28571b042013-03-14 07:59:15874 }
[email protected]de44a152013-01-08 15:28:46875
[email protected]0ec335c42013-07-04 06:17:08876 bool WillDraw(TextureLayerImpl* layer, DrawMode mode) {
877 bool will_draw = layer->WillDraw(
878 mode, host_impl_.active_tree()->resource_provider());
879 if (will_draw)
880 layer->DidDraw(host_impl_.active_tree()->resource_provider());
881 return will_draw;
882 }
883
[email protected]28571b042013-03-14 07:59:15884 CommonMailboxObjects test_data_;
[email protected]408b5e22013-03-19 09:48:09885 FakeLayerTreeHostClient fake_client_;
[email protected]de44a152013-01-08 15:28:46886};
887
[email protected]ffbb2212013-06-02 23:47:59888// Test conditions for results of TextureLayerImpl::WillDraw under
889// different configurations of different mailbox, texture_id, and draw_mode.
890TEST_F(TextureLayerImplWithMailboxTest, TestWillDraw) {
[email protected]0ec335c42013-07-04 06:17:08891 EXPECT_CALL(test_data_.mock_callback_,
892 Release(test_data_.mailbox_name1_,
893 test_data_.sync_point1_,
894 false))
895 .Times(AnyNumber());
896 EXPECT_CALL(test_data_.mock_callback_,
897 Release2(test_data_.shared_memory_.get(), 0, false))
898 .Times(AnyNumber());
[email protected]ffbb2212013-06-02 23:47:59899 // Hardware mode.
900 {
901 scoped_ptr<TextureLayerImpl> impl_layer =
902 TextureLayerImpl::Create(host_impl_.active_tree(), 1, true);
903 impl_layer->SetTextureMailbox(test_data_.mailbox1_);
[email protected]0ec335c42013-07-04 06:17:08904 EXPECT_TRUE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE));
[email protected]ffbb2212013-06-02 23:47:59905 }
906
907 {
908 scoped_ptr<TextureLayerImpl> impl_layer =
909 TextureLayerImpl::Create(host_impl_.active_tree(), 1, true);
[email protected]0ec335c42013-07-04 06:17:08910 impl_layer->SetTextureMailbox(TextureMailbox());
911 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE));
912 }
913
914 {
915 // Software resource.
916 scoped_ptr<TextureLayerImpl> impl_layer =
917 TextureLayerImpl::Create(host_impl_.active_tree(), 1, true);
918 impl_layer->SetTextureMailbox(test_data_.mailbox3_);
[email protected]3e44d7a2013-07-30 00:03:10919 EXPECT_TRUE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE));
[email protected]ffbb2212013-06-02 23:47:59920 }
921
922 {
923 scoped_ptr<TextureLayerImpl> impl_layer =
924 TextureLayerImpl::Create(host_impl_.active_tree(), 1, false);
[email protected]0634cdd42013-08-16 00:46:09925 ContextProvider* context_provider =
926 host_impl_.output_surface()->context_provider();
[email protected]ffbb2212013-06-02 23:47:59927 unsigned texture =
[email protected]0634cdd42013-08-16 00:46:09928 context_provider->Context3d()->createTexture();
[email protected]ffbb2212013-06-02 23:47:59929 impl_layer->set_texture_id(texture);
[email protected]0ec335c42013-07-04 06:17:08930 EXPECT_TRUE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE));
[email protected]ffbb2212013-06-02 23:47:59931 }
932
933 {
934 scoped_ptr<TextureLayerImpl> impl_layer =
935 TextureLayerImpl::Create(host_impl_.active_tree(), 1, false);
936 impl_layer->set_texture_id(0);
[email protected]0ec335c42013-07-04 06:17:08937 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE));
938 }
939
940 // Software mode.
941 {
942 scoped_ptr<TextureLayerImpl> impl_layer =
943 TextureLayerImpl::Create(host_impl_.active_tree(), 1, true);
944 impl_layer->SetTextureMailbox(test_data_.mailbox1_);
945 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE));
946 }
947
948 {
949 scoped_ptr<TextureLayerImpl> impl_layer =
950 TextureLayerImpl::Create(host_impl_.active_tree(), 1, true);
951 impl_layer->SetTextureMailbox(TextureMailbox());
952 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE));
953 }
954
955 {
956 // Software resource.
957 scoped_ptr<TextureLayerImpl> impl_layer =
958 TextureLayerImpl::Create(host_impl_.active_tree(), 1, true);
959 impl_layer->SetTextureMailbox(test_data_.mailbox3_);
960 EXPECT_TRUE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE));
961 }
962
963 {
964 scoped_ptr<TextureLayerImpl> impl_layer =
965 TextureLayerImpl::Create(host_impl_.active_tree(), 1, false);
[email protected]0634cdd42013-08-16 00:46:09966 ContextProvider* context_provider =
967 host_impl_.output_surface()->context_provider();
[email protected]0ec335c42013-07-04 06:17:08968 unsigned texture =
[email protected]0634cdd42013-08-16 00:46:09969 context_provider->Context3d()->createTexture();
[email protected]0ec335c42013-07-04 06:17:08970 impl_layer->set_texture_id(texture);
971 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE));
972 }
973
974 {
975 scoped_ptr<TextureLayerImpl> impl_layer =
976 TextureLayerImpl::Create(host_impl_.active_tree(), 1, false);
977 impl_layer->set_texture_id(0);
978 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE));
[email protected]ffbb2212013-06-02 23:47:59979 }
980
981 // Resourceless software mode.
982 {
983 scoped_ptr<TextureLayerImpl> impl_layer =
984 TextureLayerImpl::Create(host_impl_.active_tree(), 1, true);
985 impl_layer->SetTextureMailbox(test_data_.mailbox1_);
[email protected]0ec335c42013-07-04 06:17:08986 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_RESOURCELESS_SOFTWARE));
[email protected]ffbb2212013-06-02 23:47:59987 }
988
989 {
990 scoped_ptr<TextureLayerImpl> impl_layer =
991 TextureLayerImpl::Create(host_impl_.active_tree(), 1, false);
[email protected]0634cdd42013-08-16 00:46:09992 ContextProvider* context_provider =
993 host_impl_.output_surface()->context_provider();
[email protected]ffbb2212013-06-02 23:47:59994 unsigned texture =
[email protected]0634cdd42013-08-16 00:46:09995 context_provider->Context3d()->createTexture();
[email protected]ffbb2212013-06-02 23:47:59996 impl_layer->set_texture_id(texture);
[email protected]0ec335c42013-07-04 06:17:08997 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_RESOURCELESS_SOFTWARE));
[email protected]ffbb2212013-06-02 23:47:59998 }
999}
1000
[email protected]28571b042013-03-14 07:59:151001TEST_F(TextureLayerImplWithMailboxTest, TestImplLayerCallbacks) {
1002 host_impl_.CreatePendingTree();
1003 scoped_ptr<TextureLayerImpl> pending_layer;
1004 pending_layer = TextureLayerImpl::Create(host_impl_.pending_tree(), 1, true);
1005 ASSERT_TRUE(pending_layer);
[email protected]de44a152013-01-08 15:28:461006
[email protected]ed511b8d2013-03-25 03:29:291007 scoped_ptr<LayerImpl> active_layer(
[email protected]28571b042013-03-14 07:59:151008 pending_layer->CreateLayerImpl(host_impl_.active_tree()));
[email protected]ed511b8d2013-03-25 03:29:291009 ASSERT_TRUE(active_layer);
[email protected]de44a152013-01-08 15:28:461010
[email protected]1a37a0752013-03-17 21:25:491011 pending_layer->SetTextureMailbox(test_data_.mailbox1_);
[email protected]421e84f2013-02-22 03:27:151012
[email protected]28571b042013-03-14 07:59:151013 // Test multiple commits without an activation.
1014 EXPECT_CALL(test_data_.mock_callback_,
[email protected]7ba3ca72013-04-11 06:37:251015 Release(test_data_.mailbox_name1_,
1016 test_data_.sync_point1_,
1017 false))
[email protected]28571b042013-03-14 07:59:151018 .Times(1);
[email protected]1a37a0752013-03-17 21:25:491019 pending_layer->SetTextureMailbox(test_data_.mailbox2_);
[email protected]28571b042013-03-14 07:59:151020 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]421e84f2013-02-22 03:27:151021
[email protected]28571b042013-03-14 07:59:151022 // Test callback after activation.
[email protected]ed511b8d2013-03-25 03:29:291023 pending_layer->PushPropertiesTo(active_layer.get());
1024 active_layer->DidBecomeActive();
[email protected]421e84f2013-02-22 03:27:151025
[email protected]7ba3ca72013-04-11 06:37:251026 EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0);
[email protected]1a37a0752013-03-17 21:25:491027 pending_layer->SetTextureMailbox(test_data_.mailbox1_);
[email protected]28571b042013-03-14 07:59:151028 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]421e84f2013-02-22 03:27:151029
[email protected]7ba3ca72013-04-11 06:37:251030 EXPECT_CALL(test_data_.mock_callback_,
1031 Release(test_data_.mailbox_name2_, _, false))
[email protected]28571b042013-03-14 07:59:151032 .Times(1);
[email protected]ed511b8d2013-03-25 03:29:291033 pending_layer->PushPropertiesTo(active_layer.get());
1034 active_layer->DidBecomeActive();
[email protected]28571b042013-03-14 07:59:151035 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]de44a152013-01-08 15:28:461036
[email protected]28571b042013-03-14 07:59:151037 // Test resetting the mailbox.
[email protected]7ba3ca72013-04-11 06:37:251038 EXPECT_CALL(test_data_.mock_callback_,
1039 Release(test_data_.mailbox_name1_, _, false))
[email protected]28571b042013-03-14 07:59:151040 .Times(1);
[email protected]1a37a0752013-03-17 21:25:491041 pending_layer->SetTextureMailbox(TextureMailbox());
[email protected]ed511b8d2013-03-25 03:29:291042 pending_layer->PushPropertiesTo(active_layer.get());
1043 active_layer->DidBecomeActive();
[email protected]28571b042013-03-14 07:59:151044 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]de44a152013-01-08 15:28:461045
[email protected]28571b042013-03-14 07:59:151046 // Test destructor.
1047 EXPECT_CALL(test_data_.mock_callback_,
[email protected]7ba3ca72013-04-11 06:37:251048 Release(test_data_.mailbox_name1_,
1049 test_data_.sync_point1_,
1050 false))
[email protected]28571b042013-03-14 07:59:151051 .Times(1);
[email protected]1a37a0752013-03-17 21:25:491052 pending_layer->SetTextureMailbox(test_data_.mailbox1_);
[email protected]de44a152013-01-08 15:28:461053}
1054
[email protected]28571b042013-03-14 07:59:151055TEST_F(TextureLayerImplWithMailboxTest,
1056 TestDestructorCallbackOnCreatedResource) {
1057 scoped_ptr<TextureLayerImpl> impl_layer;
1058 impl_layer = TextureLayerImpl::Create(host_impl_.active_tree(), 1, true);
1059 ASSERT_TRUE(impl_layer);
[email protected]de44a152013-01-08 15:28:461060
[email protected]7ba3ca72013-04-11 06:37:251061 EXPECT_CALL(test_data_.mock_callback_,
1062 Release(test_data_.mailbox_name1_, _, false))
[email protected]28571b042013-03-14 07:59:151063 .Times(1);
[email protected]1a37a0752013-03-17 21:25:491064 impl_layer->SetTextureMailbox(test_data_.mailbox1_);
[email protected]ffbb2212013-06-02 23:47:591065 impl_layer->DidBecomeActive();
1066 EXPECT_TRUE(impl_layer->WillDraw(
1067 DRAW_MODE_HARDWARE, host_impl_.active_tree()->resource_provider()));
[email protected]28571b042013-03-14 07:59:151068 impl_layer->DidDraw(host_impl_.active_tree()->resource_provider());
[email protected]1a37a0752013-03-17 21:25:491069 impl_layer->SetTextureMailbox(TextureMailbox());
[email protected]de44a152013-01-08 15:28:461070}
1071
[email protected]28571b042013-03-14 07:59:151072TEST_F(TextureLayerImplWithMailboxTest, TestCallbackOnInUseResource) {
1073 ResourceProvider* provider = host_impl_.active_tree()->resource_provider();
1074 ResourceProvider::ResourceId id =
1075 provider->CreateResourceFromTextureMailbox(test_data_.mailbox1_);
1076 provider->AllocateForTesting(id);
[email protected]de44a152013-01-08 15:28:461077
[email protected]28571b042013-03-14 07:59:151078 // Transfer some resources to the parent.
1079 ResourceProvider::ResourceIdArray resource_ids_to_transfer;
1080 resource_ids_to_transfer.push_back(id);
1081 TransferableResourceArray list;
1082 provider->PrepareSendToParent(resource_ids_to_transfer, &list);
1083 EXPECT_TRUE(provider->InUseByConsumer(id));
[email protected]7ba3ca72013-04-11 06:37:251084 EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0);
[email protected]28571b042013-03-14 07:59:151085 provider->DeleteResource(id);
1086 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]7ba3ca72013-04-11 06:37:251087 EXPECT_CALL(test_data_.mock_callback_,
1088 Release(test_data_.mailbox_name1_, _, false))
[email protected]28571b042013-03-14 07:59:151089 .Times(1);
[email protected]e00bab022013-08-19 00:42:451090 ReturnedResourceArray returned;
1091 TransferableResource::ReturnResources(list, &returned);
1092 provider->ReceiveReturnsFromParent(returned);
[email protected]de44a152013-01-08 15:28:461093}
1094
[email protected]97d519fb2013-03-29 02:27:541095// Check that ClearClient correctly clears the state so that the impl side
1096// doesn't try to use a texture that could have been destroyed.
[email protected]7ba3ca72013-04-11 06:37:251097class TextureLayerClientTest
1098 : public LayerTreeTest,
1099 public TextureLayerClient {
[email protected]97d519fb2013-03-29 02:27:541100 public:
1101 TextureLayerClientTest()
1102 : context_(NULL),
1103 texture_(0),
1104 commit_count_(0),
1105 expected_used_textures_on_draw_(0),
1106 expected_used_textures_on_commit_(0) {}
1107
[email protected]ebc0e1df2013-08-01 02:46:221108 virtual scoped_ptr<OutputSurface> CreateOutputSurface(bool fallback)
1109 OVERRIDE {
[email protected]97d519fb2013-03-29 02:27:541110 scoped_ptr<TestWebGraphicsContext3D> context(
1111 TestWebGraphicsContext3D::Create());
1112 context_ = context.get();
1113 texture_ = context->createTexture();
[email protected]0634cdd42013-08-16 00:46:091114 return FakeOutputSurface::Create3d(context.Pass()).PassAs<OutputSurface>();
[email protected]97d519fb2013-03-29 02:27:541115 }
1116
[email protected]171cbb32013-07-11 03:51:191117 virtual unsigned PrepareTexture() OVERRIDE {
[email protected]97d519fb2013-03-29 02:27:541118 return texture_;
1119 }
1120
[email protected]d5d9bc52013-04-01 23:16:391121 virtual WebKit::WebGraphicsContext3D* Context3d() OVERRIDE {
[email protected]97d519fb2013-03-29 02:27:541122 return context_;
1123 }
1124
[email protected]2541d1a2013-07-10 07:33:271125 virtual bool PrepareTextureMailbox(
1126 cc::TextureMailbox* mailbox, bool use_shared_memory) OVERRIDE {
[email protected]e8e4ae232013-04-12 00:26:011127 return false;
1128 }
1129
[email protected]97d519fb2013-03-29 02:27:541130 virtual void SetupTree() OVERRIDE {
1131 scoped_refptr<Layer> root = Layer::Create();
1132 root->SetBounds(gfx::Size(10, 10));
1133 root->SetAnchorPoint(gfx::PointF());
1134 root->SetIsDrawable(true);
1135
1136 texture_layer_ = TextureLayer::Create(this);
1137 texture_layer_->SetBounds(gfx::Size(10, 10));
1138 texture_layer_->SetAnchorPoint(gfx::PointF());
1139 texture_layer_->SetIsDrawable(true);
1140 root->AddChild(texture_layer_);
1141
1142 layer_tree_host()->SetRootLayer(root);
1143 LayerTreeTest::SetupTree();
1144 {
1145 base::AutoLock lock(lock_);
1146 expected_used_textures_on_commit_ = 1;
1147 }
1148 }
1149
1150 virtual void BeginTest() OVERRIDE {
1151 PostSetNeedsCommitToMainThread();
1152 }
1153
1154 virtual void DidCommitAndDrawFrame() OVERRIDE {
1155 ++commit_count_;
1156 switch (commit_count_) {
1157 case 1:
1158 texture_layer_->ClearClient();
1159 texture_layer_->SetNeedsDisplay();
1160 {
1161 base::AutoLock lock(lock_);
1162 expected_used_textures_on_commit_ = 0;
1163 }
1164 texture_ = 0;
1165 break;
1166 case 2:
1167 EndTest();
1168 break;
1169 default:
1170 NOTREACHED();
1171 break;
1172 }
1173 }
1174
1175 virtual void BeginCommitOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
1176 base::AutoLock lock(lock_);
1177 expected_used_textures_on_draw_ = expected_used_textures_on_commit_;
1178 }
1179
1180 virtual bool PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
1181 LayerTreeHostImpl::FrameData* frame_data,
1182 bool result) OVERRIDE {
1183 context_->ResetUsedTextures();
1184 return true;
1185 }
1186
1187 virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl,
1188 bool result) OVERRIDE {
1189 ASSERT_TRUE(result);
1190 EXPECT_EQ(expected_used_textures_on_draw_, context_->NumUsedTextures());
1191 }
1192
1193 virtual void AfterTest() OVERRIDE {}
1194
1195 private:
1196 scoped_refptr<TextureLayer> texture_layer_;
1197 TestWebGraphicsContext3D* context_;
1198 unsigned texture_;
1199 int commit_count_;
1200
1201 // Used only on thread.
1202 unsigned expected_used_textures_on_draw_;
1203
1204 // Used on either thread, protected by lock_.
1205 base::Lock lock_;
1206 unsigned expected_used_textures_on_commit_;
1207};
1208
[email protected]4145d172013-05-10 16:54:361209// The TextureLayerClient does not use mailboxes, so can't use a delegating
1210// renderer.
1211SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(TextureLayerClientTest);
[email protected]97d519fb2013-03-29 02:27:541212
[email protected]0bf5a202013-07-10 14:50:541213// Test recovering from a lost context.
1214class TextureLayerLostContextTest
1215 : public LayerTreeTest,
1216 public TextureLayerClient {
1217 public:
1218 TextureLayerLostContextTest()
1219 : texture_(0),
1220 draw_count_(0) {}
1221
[email protected]ebc0e1df2013-08-01 02:46:221222 virtual scoped_ptr<OutputSurface> CreateOutputSurface(bool fallback)
1223 OVERRIDE {
[email protected]0bf5a202013-07-10 14:50:541224 texture_context_ = TestWebGraphicsContext3D::Create();
1225 texture_ = texture_context_->createTexture();
[email protected]3f6a906c2013-07-17 01:03:261226 return CreateFakeOutputSurface();
[email protected]0bf5a202013-07-10 14:50:541227 }
1228
[email protected]171cbb32013-07-11 03:51:191229 virtual unsigned PrepareTexture() OVERRIDE {
[email protected]0bf5a202013-07-10 14:50:541230 if (draw_count_ == 0) {
1231 texture_context_->loseContextCHROMIUM(GL_GUILTY_CONTEXT_RESET_ARB,
1232 GL_INNOCENT_CONTEXT_RESET_ARB);
1233 }
1234 return texture_;
1235 }
1236
1237 virtual WebKit::WebGraphicsContext3D* Context3d() OVERRIDE {
1238 return texture_context_.get();
1239 }
1240
1241 virtual bool PrepareTextureMailbox(
1242 cc::TextureMailbox* mailbox, bool use_shared_memory) OVERRIDE {
1243 return false;
1244 }
1245
1246 virtual void SetupTree() OVERRIDE {
1247 scoped_refptr<Layer> root = Layer::Create();
1248 root->SetBounds(gfx::Size(10, 10));
1249 root->SetIsDrawable(true);
1250
1251 texture_layer_ = TextureLayer::Create(this);
1252 texture_layer_->SetBounds(gfx::Size(10, 10));
1253 texture_layer_->SetIsDrawable(true);
1254 root->AddChild(texture_layer_);
1255
1256 layer_tree_host()->SetRootLayer(root);
1257 LayerTreeTest::SetupTree();
1258 }
1259
1260 virtual void BeginTest() OVERRIDE {
1261 PostSetNeedsCommitToMainThread();
1262 }
1263
1264 virtual bool PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
1265 LayerTreeHostImpl::FrameData* frame_data,
1266 bool result) OVERRIDE {
1267 LayerImpl* root = host_impl->RootLayer();
1268 TextureLayerImpl* texture_layer =
1269 static_cast<TextureLayerImpl*>(root->children()[0]);
1270 if (++draw_count_ == 1)
1271 EXPECT_EQ(0u, texture_layer->texture_id());
1272 else
1273 EXPECT_EQ(texture_, texture_layer->texture_id());
1274 return true;
1275 }
1276
1277 virtual void DidCommitAndDrawFrame() OVERRIDE {
1278 EndTest();
1279 }
1280
1281 virtual void AfterTest() OVERRIDE {}
1282
1283 private:
1284 scoped_refptr<TextureLayer> texture_layer_;
1285 scoped_ptr<TestWebGraphicsContext3D> texture_context_;
1286 unsigned texture_;
1287 int draw_count_;
1288};
1289
1290SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(TextureLayerLostContextTest);
1291
[email protected]9c2bd822013-07-26 12:30:171292class TextureLayerWithMailboxMainThreadDeleted : public LayerTreeTest {
1293 public:
1294 void ReleaseCallback(unsigned sync_point, bool lost_resource) {
[email protected]9794fb32013-08-29 09:49:591295 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]9c2bd822013-07-26 12:30:171296 EXPECT_FALSE(lost_resource);
1297 ++callback_count_;
1298 EndTest();
1299 }
1300
1301 void SetMailbox(char mailbox_char) {
[email protected]9794fb32013-08-29 09:49:591302 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]9c2bd822013-07-26 12:30:171303 TextureMailbox mailbox(
1304 std::string(64, mailbox_char),
1305 base::Bind(
1306 &TextureLayerWithMailboxMainThreadDeleted::ReleaseCallback,
1307 base::Unretained(this)));
1308 layer_->SetTextureMailbox(mailbox);
1309 }
1310
1311 virtual void SetupTree() OVERRIDE {
1312 gfx::Size bounds(100, 100);
1313 root_ = Layer::Create();
1314 root_->SetAnchorPoint(gfx::PointF());
1315 root_->SetBounds(bounds);
1316
1317 layer_ = TextureLayer::CreateForMailbox(NULL);
1318 layer_->SetIsDrawable(true);
1319 layer_->SetAnchorPoint(gfx::PointF());
1320 layer_->SetBounds(bounds);
1321
1322 root_->AddChild(layer_);
1323 layer_tree_host()->SetRootLayer(root_);
1324 layer_tree_host()->SetViewportSize(bounds);
1325 }
1326
1327 virtual void BeginTest() OVERRIDE {
[email protected]9794fb32013-08-29 09:49:591328 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
1329
[email protected]9c2bd822013-07-26 12:30:171330 callback_count_ = 0;
1331
1332 // Set the mailbox on the main thread.
1333 SetMailbox('1');
1334 EXPECT_EQ(0, callback_count_);
1335
1336 PostSetNeedsCommitToMainThread();
1337 }
1338
1339 virtual void DidCommitAndDrawFrame() OVERRIDE {
1340 switch (layer_tree_host()->source_frame_number()) {
1341 case 1:
1342 // Delete the TextureLayer on the main thread while the mailbox is in
1343 // the impl tree.
1344 layer_->RemoveFromParent();
1345 layer_ = NULL;
1346 break;
1347 }
1348 }
1349
1350 virtual void AfterTest() OVERRIDE {
1351 EXPECT_EQ(1, callback_count_);
1352 }
1353
1354 private:
[email protected]9794fb32013-08-29 09:49:591355 base::ThreadChecker main_thread_;
[email protected]9c2bd822013-07-26 12:30:171356 int callback_count_;
1357 scoped_refptr<Layer> root_;
1358 scoped_refptr<TextureLayer> layer_;
1359};
1360
1361SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
1362 TextureLayerWithMailboxMainThreadDeleted);
1363
1364class TextureLayerWithMailboxImplThreadDeleted : public LayerTreeTest {
1365 public:
1366 void ReleaseCallback(unsigned sync_point, bool lost_resource) {
[email protected]9794fb32013-08-29 09:49:591367 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]9c2bd822013-07-26 12:30:171368 EXPECT_FALSE(lost_resource);
1369 ++callback_count_;
1370 EndTest();
1371 }
1372
1373 void SetMailbox(char mailbox_char) {
[email protected]9794fb32013-08-29 09:49:591374 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]9c2bd822013-07-26 12:30:171375 TextureMailbox mailbox(
1376 std::string(64, mailbox_char),
1377 base::Bind(
1378 &TextureLayerWithMailboxImplThreadDeleted::ReleaseCallback,
1379 base::Unretained(this)));
1380 layer_->SetTextureMailbox(mailbox);
1381 }
1382
1383 virtual void SetupTree() OVERRIDE {
1384 gfx::Size bounds(100, 100);
1385 root_ = Layer::Create();
1386 root_->SetAnchorPoint(gfx::PointF());
1387 root_->SetBounds(bounds);
1388
1389 layer_ = TextureLayer::CreateForMailbox(NULL);
1390 layer_->SetIsDrawable(true);
1391 layer_->SetAnchorPoint(gfx::PointF());
1392 layer_->SetBounds(bounds);
1393
1394 root_->AddChild(layer_);
1395 layer_tree_host()->SetRootLayer(root_);
1396 layer_tree_host()->SetViewportSize(bounds);
1397 }
1398
1399 virtual void BeginTest() OVERRIDE {
[email protected]9794fb32013-08-29 09:49:591400 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
1401
[email protected]9c2bd822013-07-26 12:30:171402 callback_count_ = 0;
1403
1404 // Set the mailbox on the main thread.
1405 SetMailbox('1');
1406 EXPECT_EQ(0, callback_count_);
1407
1408 PostSetNeedsCommitToMainThread();
1409 }
1410
1411 virtual void DidCommitAndDrawFrame() OVERRIDE {
1412 switch (layer_tree_host()->source_frame_number()) {
1413 case 1:
1414 // Remove the TextureLayer on the main thread while the mailbox is in
1415 // the impl tree, but don't delete the TextureLayer until after the impl
1416 // tree side is deleted.
1417 layer_->RemoveFromParent();
1418 break;
1419 case 2:
1420 layer_ = NULL;
1421 break;
1422 }
1423 }
1424
1425 virtual void AfterTest() OVERRIDE {
1426 EXPECT_EQ(1, callback_count_);
1427 }
1428
1429 private:
[email protected]9794fb32013-08-29 09:49:591430 base::ThreadChecker main_thread_;
[email protected]9c2bd822013-07-26 12:30:171431 int callback_count_;
1432 scoped_refptr<Layer> root_;
1433 scoped_refptr<TextureLayer> layer_;
1434};
1435
1436SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
1437 TextureLayerWithMailboxImplThreadDeleted);
1438
[email protected]ba565742012-11-10 09:29:481439} // namespace
1440} // namespace cc