blob: 239c5b8fa22b19ef99669a3ae938380171db223a [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]b04264f92013-09-13 23:37:297#include <algorithm>
[email protected]de44a152013-01-08 15:28:468#include <string>
9
[email protected]b04264f92013-09-13 23:37:2910#include "base/bind.h"
[email protected]de44a152013-01-08 15:28:4611#include "base/callback.h"
[email protected]9794fb32013-08-29 09:49:5912#include "base/synchronization/waitable_event.h"
[email protected]74b43cc2013-08-30 06:29:2713#include "base/threading/thread.h"
14#include "base/time/time.h"
[email protected]95fc42142013-08-13 19:31:0515#include "cc/debug/test_web_graphics_context_3d.h"
[email protected]b04264f92013-09-13 23:37:2916#include "cc/layers/solid_color_layer.h"
[email protected]97d519fb2013-03-29 02:27:5417#include "cc/layers/texture_layer_client.h"
[email protected]cc3cfaa2013-03-18 09:05:5218#include "cc/layers/texture_layer_impl.h"
[email protected]b04264f92013-09-13 23:37:2919#include "cc/output/compositor_frame_ack.h"
20#include "cc/output/context_provider.h"
[email protected]e00bab022013-08-19 00:42:4521#include "cc/resources/returned_resource.h"
[email protected]586d51ed2012-12-07 20:31:4522#include "cc/test/fake_impl_proxy.h"
[email protected]101441ce2012-10-16 01:45:0323#include "cc/test/fake_layer_tree_host_client.h"
[email protected]586d51ed2012-12-07 20:31:4524#include "cc/test/fake_layer_tree_host_impl.h"
[email protected]199b715e2013-08-13 05:18:3425#include "cc/test/fake_output_surface.h"
[email protected]06d68d02013-04-19 18:46:2126#include "cc/test/layer_test_common.h"
[email protected]e216fef02013-03-20 22:56:1027#include "cc/test/layer_tree_test.h"
[email protected]9794fb32013-08-29 09:49:5928#include "cc/trees/blocking_task_runner.h"
[email protected]556fd292013-03-18 08:03:0429#include "cc/trees/layer_tree_host.h"
30#include "cc/trees/layer_tree_impl.h"
31#include "cc/trees/single_thread_proxy.h"
[email protected]0bf5a202013-07-10 14:50:5432#include "gpu/GLES2/gl2extchromium.h"
[email protected]7f0c53db2012-10-02 00:23:1833#include "testing/gmock/include/gmock/gmock.h"
34#include "testing/gtest/include/gtest/gtest.h"
[email protected]c0dd24c2012-08-30 23:25:2735
[email protected]c0dd24c2012-08-30 23:25:2736using ::testing::Mock;
37using ::testing::_;
38using ::testing::AtLeast;
39using ::testing::AnyNumber;
40
[email protected]ba565742012-11-10 09:29:4841namespace cc {
[email protected]c0dd24c2012-08-30 23:25:2742namespace {
43
[email protected]408b5e22013-03-19 09:48:0944class MockLayerTreeHost : public LayerTreeHost {
[email protected]28571b042013-03-14 07:59:1545 public:
[email protected]bf691c22013-03-26 21:15:0646 explicit MockLayerTreeHost(LayerTreeHostClient* client)
[email protected]408b5e22013-03-19 09:48:0947 : LayerTreeHost(client, LayerTreeSettings()) {
[email protected]810d40b72013-06-20 18:26:1548 Initialize(NULL);
[email protected]28571b042013-03-14 07:59:1549 }
[email protected]c0dd24c2012-08-30 23:25:2750
[email protected]28571b042013-03-14 07:59:1551 MOCK_METHOD0(AcquireLayerTextures, void());
52 MOCK_METHOD0(SetNeedsCommit, void());
[email protected]3519b872013-07-30 07:17:5053 MOCK_METHOD0(SetNeedsUpdateLayers, void());
[email protected]2f529812013-07-12 01:58:3954 MOCK_METHOD1(StartRateLimiter, void(WebKit::WebGraphicsContext3D* context));
55 MOCK_METHOD1(StopRateLimiter, void(WebKit::WebGraphicsContext3D* context));
[email protected]c0dd24c2012-08-30 23:25:2756};
57
[email protected]31d4df82013-07-18 10:17:2258class TextureLayerTest : public testing::Test {
59 public:
60 TextureLayerTest()
61 : fake_client_(
62 FakeLayerTreeHostClient(FakeLayerTreeHostClient::DIRECT_3D)),
63 host_impl_(&proxy_) {}
64
65 protected:
66 virtual void SetUp() {
67 layer_tree_host_.reset(new MockLayerTreeHost(&fake_client_));
68 }
69
70 virtual void TearDown() {
71 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
72 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(AnyNumber());
73 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
74
75 layer_tree_host_->SetRootLayer(NULL);
76 layer_tree_host_.reset();
77 }
78
79 scoped_ptr<MockLayerTreeHost> layer_tree_host_;
80 FakeImplProxy proxy_;
81 FakeLayerTreeHostClient fake_client_;
82 FakeLayerTreeHostImpl host_impl_;
83};
84
85TEST_F(TextureLayerTest, SyncImplWhenChangingTextureId) {
86 scoped_refptr<TextureLayer> test_layer = TextureLayer::Create(NULL);
87 ASSERT_TRUE(test_layer.get());
88
89 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(AnyNumber());
90 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
91 layer_tree_host_->SetRootLayer(test_layer);
92 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
93 EXPECT_EQ(test_layer->layer_tree_host(), layer_tree_host_.get());
94
95 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
96 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
97 test_layer->SetTextureId(1);
98 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
99
100 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(AtLeast(1));
101 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
102 test_layer->SetTextureId(2);
103 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
104
105 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(AtLeast(1));
106 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
107 test_layer->SetTextureId(0);
108 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
109}
110
111TEST_F(TextureLayerTest, SyncImplWhenDrawing) {
112 gfx::RectF dirty_rect(0.f, 0.f, 1.f, 1.f);
113
114 scoped_refptr<TextureLayer> test_layer = TextureLayer::Create(NULL);
115 ASSERT_TRUE(test_layer.get());
116 scoped_ptr<TextureLayerImpl> impl_layer;
117 impl_layer = TextureLayerImpl::Create(host_impl_.active_tree(), 1, false);
118 ASSERT_TRUE(impl_layer);
119
120 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(AnyNumber());
121 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
122 layer_tree_host_->SetRootLayer(test_layer);
123 test_layer->SetTextureId(1);
124 test_layer->SetIsDrawable(true);
125 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
126 EXPECT_EQ(test_layer->layer_tree_host(), layer_tree_host_.get());
127
128 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(1);
129 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(0);
130 test_layer->WillModifyTexture();
131 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
132
133 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
[email protected]3519b872013-07-30 07:17:50134 EXPECT_CALL(*layer_tree_host_, SetNeedsUpdateLayers()).Times(1);
[email protected]31d4df82013-07-18 10:17:22135 test_layer->SetNeedsDisplayRect(dirty_rect);
136 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
137
138 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
139 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1);
140 test_layer->PushPropertiesTo(impl_layer.get()); // fake commit
141 test_layer->SetIsDrawable(false);
142 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
143
144 // Verify that non-drawable layers don't signal the compositor,
145 // except for the first draw after last commit, which must acquire
146 // the texture.
147 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(1);
148 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(0);
149 test_layer->WillModifyTexture();
150 test_layer->SetNeedsDisplayRect(dirty_rect);
151 test_layer->PushPropertiesTo(impl_layer.get()); // fake commit
152 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
153
154 // Second draw with layer in non-drawable state: no texture
155 // acquisition.
156 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
157 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(0);
158 test_layer->WillModifyTexture();
159 test_layer->SetNeedsDisplayRect(dirty_rect);
160 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
161}
162
163TEST_F(TextureLayerTest, SyncImplWhenRemovingFromTree) {
164 scoped_refptr<Layer> root_layer = Layer::Create();
165 ASSERT_TRUE(root_layer.get());
166 scoped_refptr<Layer> child_layer = Layer::Create();
167 ASSERT_TRUE(child_layer.get());
168 root_layer->AddChild(child_layer);
169 scoped_refptr<TextureLayer> test_layer = TextureLayer::Create(NULL);
170 ASSERT_TRUE(test_layer.get());
171 test_layer->SetTextureId(0);
172 child_layer->AddChild(test_layer);
173
174 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(AnyNumber());
175 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
176 layer_tree_host_->SetRootLayer(root_layer);
177 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
178
179 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
180 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
181 test_layer->RemoveFromParent();
182 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
183
184 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
185 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
186 child_layer->AddChild(test_layer);
187 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
188
189 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
190 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
191 test_layer->SetTextureId(1);
192 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
193
194 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(AtLeast(1));
195 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
196 test_layer->RemoveFromParent();
197 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
198}
199
200TEST_F(TextureLayerTest, CheckPropertyChangeCausesCorrectBehavior) {
201 scoped_refptr<TextureLayer> test_layer = TextureLayer::Create(NULL);
[email protected]80d42bd2013-08-30 19:13:45202 EXPECT_SET_NEEDS_COMMIT(1, layer_tree_host_->SetRootLayer(test_layer));
[email protected]31d4df82013-07-18 10:17:22203
204 // Test properties that should call SetNeedsCommit. All properties need to
205 // be set to new values in order for SetNeedsCommit to be called.
206 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetFlipped(false));
207 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetUV(
208 gfx::PointF(0.25f, 0.25f), gfx::PointF(0.75f, 0.75f)));
209 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetVertexOpacity(
210 0.5f, 0.5f, 0.5f, 0.5f));
211 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetPremultipliedAlpha(false));
212 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetBlendBackgroundColor(true));
213 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetTextureId(1));
214
215 // Calling SetTextureId can call AcquireLayerTextures.
216 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(AnyNumber());
217}
218
[email protected]1c10e232013-07-31 12:35:43219TEST_F(TextureLayerTest, VisibleContentOpaqueRegion) {
220 const gfx::Size layer_bounds(100, 100);
221 const gfx::Rect layer_rect(layer_bounds);
222 const Region layer_region(layer_rect);
223
224 scoped_refptr<TextureLayer> layer = TextureLayer::Create(NULL);
225 layer->SetBounds(layer_bounds);
226 layer->draw_properties().visible_content_rect = layer_rect;
227 layer->SetBlendBackgroundColor(true);
228
229 // Verify initial conditions.
230 EXPECT_FALSE(layer->contents_opaque());
231 EXPECT_EQ(0u, layer->background_color());
232 EXPECT_EQ(Region().ToString(),
233 layer->VisibleContentOpaqueRegion().ToString());
234
235 // Opaque background.
236 layer->SetBackgroundColor(SK_ColorWHITE);
237 EXPECT_EQ(layer_region.ToString(),
238 layer->VisibleContentOpaqueRegion().ToString());
239
240 // Transparent background.
241 layer->SetBackgroundColor(SkColorSetARGB(100, 255, 255, 255));
242 EXPECT_EQ(Region().ToString(),
243 layer->VisibleContentOpaqueRegion().ToString());
244}
245
[email protected]2f529812013-07-12 01:58:39246class FakeTextureLayerClient : public TextureLayerClient {
247 public:
[email protected]31d4df82013-07-18 10:17:22248 FakeTextureLayerClient() : context_(TestWebGraphicsContext3D::Create()) {}
[email protected]2f529812013-07-12 01:58:39249
250 virtual unsigned PrepareTexture() OVERRIDE {
[email protected]31d4df82013-07-18 10:17:22251 return 0;
[email protected]2f529812013-07-12 01:58:39252 }
253
254 virtual WebKit::WebGraphicsContext3D* Context3d() OVERRIDE {
255 return context_.get();
256 }
257
[email protected]9260757f2013-09-17 01:24:16258 virtual bool PrepareTextureMailbox(
259 TextureMailbox* mailbox,
260 scoped_ptr<SingleReleaseCallback>* release_callback,
261 bool use_shared_memory) OVERRIDE {
[email protected]31d4df82013-07-18 10:17:22262 *mailbox = TextureMailbox();
[email protected]9260757f2013-09-17 01:24:16263 *release_callback = scoped_ptr<SingleReleaseCallback>();
[email protected]2f529812013-07-12 01:58:39264 return true;
265 }
266
267 private:
268 scoped_ptr<TestWebGraphicsContext3D> context_;
269 DISALLOW_COPY_AND_ASSIGN(FakeTextureLayerClient);
270};
271
[email protected]31d4df82013-07-18 10:17:22272TEST_F(TextureLayerTest, RateLimiter) {
273 FakeTextureLayerClient client;
274 scoped_refptr<TextureLayer> test_layer = TextureLayer::CreateForMailbox(
275 &client);
276 test_layer->SetIsDrawable(true);
277 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
278 layer_tree_host_->SetRootLayer(test_layer);
279
280 // Don't rate limit until we invalidate.
281 EXPECT_CALL(*layer_tree_host_, StartRateLimiter(_)).Times(0);
282 test_layer->SetRateLimitContext(true);
283 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
284
285 // Do rate limit after we invalidate.
286 EXPECT_CALL(*layer_tree_host_, StartRateLimiter(client.Context3d()));
287 test_layer->SetNeedsDisplay();
288 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
289
290 // Stop rate limiter when we don't want it any more.
291 EXPECT_CALL(*layer_tree_host_, StopRateLimiter(client.Context3d()));
292 test_layer->SetRateLimitContext(false);
293 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
294
295 // Or we clear the client.
296 test_layer->SetRateLimitContext(true);
297 EXPECT_CALL(*layer_tree_host_, StopRateLimiter(client.Context3d()));
298 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
299 test_layer->ClearClient();
300 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
301
302 // Reset to a layer with a client, that started the rate limiter.
303 test_layer = TextureLayer::CreateForMailbox(
304 &client);
305 test_layer->SetIsDrawable(true);
306 test_layer->SetRateLimitContext(true);
307 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
308 layer_tree_host_->SetRootLayer(test_layer);
309 EXPECT_CALL(*layer_tree_host_, StartRateLimiter(_)).Times(0);
310 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
311 EXPECT_CALL(*layer_tree_host_, StartRateLimiter(client.Context3d()));
312 test_layer->SetNeedsDisplay();
313 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
314
315 // Stop rate limiter when we're removed from the tree.
316 EXPECT_CALL(*layer_tree_host_, StopRateLimiter(client.Context3d()));
317 layer_tree_host_->SetRootLayer(NULL);
318 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
319}
320
[email protected]de44a152013-01-08 15:28:46321class MockMailboxCallback {
[email protected]28571b042013-03-14 07:59:15322 public:
[email protected]7ba3ca72013-04-11 06:37:25323 MOCK_METHOD3(Release, void(const std::string& mailbox,
324 unsigned sync_point,
325 bool lost_resource));
[email protected]42f40a52013-06-08 04:38:51326 MOCK_METHOD3(Release2, void(base::SharedMemory* shared_memory,
327 unsigned sync_point,
328 bool lost_resource));
[email protected]de44a152013-01-08 15:28:46329};
330
331struct CommonMailboxObjects {
[email protected]28571b042013-03-14 07:59:15332 CommonMailboxObjects()
333 : mailbox_name1_(64, '1'),
334 mailbox_name2_(64, '2'),
335 sync_point1_(1),
[email protected]42f40a52013-06-08 04:38:51336 sync_point2_(2),
337 shared_memory_(new base::SharedMemory) {
[email protected]28571b042013-03-14 07:59:15338 release_mailbox1_ = base::Bind(&MockMailboxCallback::Release,
339 base::Unretained(&mock_callback_),
340 mailbox_name1_);
341 release_mailbox2_ = base::Bind(&MockMailboxCallback::Release,
342 base::Unretained(&mock_callback_),
343 mailbox_name2_);
344 gpu::Mailbox m1;
345 m1.SetName(reinterpret_cast<const int8*>(mailbox_name1_.data()));
[email protected]9260757f2013-09-17 01:24:16346 mailbox1_ = TextureMailbox(m1, sync_point1_);
[email protected]28571b042013-03-14 07:59:15347 gpu::Mailbox m2;
348 m2.SetName(reinterpret_cast<const int8*>(mailbox_name2_.data()));
[email protected]9260757f2013-09-17 01:24:16349 mailbox2_ = TextureMailbox(m2, sync_point2_);
[email protected]42f40a52013-06-08 04:38:51350
351 gfx::Size size(128, 128);
352 EXPECT_TRUE(shared_memory_->CreateAndMapAnonymous(4 * size.GetArea()));
353 release_mailbox3_ = base::Bind(&MockMailboxCallback::Release2,
354 base::Unretained(&mock_callback_),
355 shared_memory_.get());
[email protected]9260757f2013-09-17 01:24:16356 mailbox3_ = TextureMailbox(shared_memory_.get(), size);
[email protected]28571b042013-03-14 07:59:15357 }
[email protected]de44a152013-01-08 15:28:46358
[email protected]28571b042013-03-14 07:59:15359 std::string mailbox_name1_;
360 std::string mailbox_name2_;
361 MockMailboxCallback mock_callback_;
[email protected]9260757f2013-09-17 01:24:16362 ReleaseCallback release_mailbox1_;
363 ReleaseCallback release_mailbox2_;
364 ReleaseCallback release_mailbox3_;
[email protected]28571b042013-03-14 07:59:15365 TextureMailbox mailbox1_;
366 TextureMailbox mailbox2_;
[email protected]42f40a52013-06-08 04:38:51367 TextureMailbox mailbox3_;
[email protected]28571b042013-03-14 07:59:15368 unsigned sync_point1_;
369 unsigned sync_point2_;
[email protected]42f40a52013-06-08 04:38:51370 scoped_ptr<base::SharedMemory> shared_memory_;
[email protected]de44a152013-01-08 15:28:46371};
372
[email protected]9794fb32013-08-29 09:49:59373class TestMailboxHolder : public TextureLayer::MailboxHolder {
374 public:
375 using TextureLayer::MailboxHolder::Create;
376
377 protected:
378 virtual ~TestMailboxHolder() {}
379};
380
[email protected]de44a152013-01-08 15:28:46381class TextureLayerWithMailboxTest : public TextureLayerTest {
[email protected]28571b042013-03-14 07:59:15382 protected:
383 virtual void TearDown() {
384 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
385 EXPECT_CALL(test_data_.mock_callback_,
386 Release(test_data_.mailbox_name1_,
[email protected]7ba3ca72013-04-11 06:37:25387 test_data_.sync_point1_,
388 false)).Times(1);
[email protected]28571b042013-03-14 07:59:15389 TextureLayerTest::TearDown();
390 }
[email protected]de44a152013-01-08 15:28:46391
[email protected]28571b042013-03-14 07:59:15392 CommonMailboxObjects test_data_;
[email protected]de44a152013-01-08 15:28:46393};
394
[email protected]28571b042013-03-14 07:59:15395TEST_F(TextureLayerWithMailboxTest, ReplaceMailboxOnMainThreadBeforeCommit) {
[email protected]e8e4ae232013-04-12 00:26:01396 scoped_refptr<TextureLayer> test_layer = TextureLayer::CreateForMailbox(NULL);
[email protected]22898ed2013-06-01 04:52:30397 ASSERT_TRUE(test_layer.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(AnyNumber());
401 layer_tree_host_->SetRootLayer(test_layer);
402 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
[email protected]de44a152013-01-08 15:28:46403
[email protected]28571b042013-03-14 07:59:15404 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
405 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
[email protected]9260757f2013-09-17 01:24:16406 test_layer->SetTextureMailbox(
407 test_data_.mailbox1_,
408 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
[email protected]28571b042013-03-14 07:59:15409 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
[email protected]de44a152013-01-08 15:28:46410
[email protected]28571b042013-03-14 07:59:15411 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
412 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
413 EXPECT_CALL(test_data_.mock_callback_,
[email protected]7ba3ca72013-04-11 06:37:25414 Release(test_data_.mailbox_name1_,
415 test_data_.sync_point1_,
416 false))
[email protected]28571b042013-03-14 07:59:15417 .Times(1);
[email protected]9260757f2013-09-17 01:24:16418 test_layer->SetTextureMailbox(
419 test_data_.mailbox2_,
420 SingleReleaseCallback::Create(test_data_.release_mailbox2_));
[email protected]28571b042013-03-14 07:59:15421 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
422 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]de44a152013-01-08 15:28:46423
[email protected]28571b042013-03-14 07:59:15424 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
425 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
426 EXPECT_CALL(test_data_.mock_callback_,
[email protected]7ba3ca72013-04-11 06:37:25427 Release(test_data_.mailbox_name2_,
428 test_data_.sync_point2_,
429 false))
[email protected]28571b042013-03-14 07:59:15430 .Times(1);
[email protected]9260757f2013-09-17 01:24:16431 test_layer->SetTextureMailbox(TextureMailbox(),
432 scoped_ptr<SingleReleaseCallback>());
[email protected]28571b042013-03-14 07:59:15433 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
434 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]de44a152013-01-08 15:28:46435
[email protected]80d42bd2013-08-30 19:13:45436 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
437 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
[email protected]9260757f2013-09-17 01:24:16438 test_layer->SetTextureMailbox(
439 test_data_.mailbox3_,
440 SingleReleaseCallback::Create(test_data_.release_mailbox3_));
[email protected]42f40a52013-06-08 04:38:51441 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
442 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
443
444 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
445 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
446 EXPECT_CALL(test_data_.mock_callback_,
447 Release2(test_data_.shared_memory_.get(),
448 0, false))
449 .Times(1);
[email protected]9260757f2013-09-17 01:24:16450 test_layer->SetTextureMailbox(TextureMailbox(),
451 scoped_ptr<SingleReleaseCallback>());
[email protected]42f40a52013-06-08 04:38:51452 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
453 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
454
[email protected]28571b042013-03-14 07:59:15455 // Test destructor.
456 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
[email protected]9260757f2013-09-17 01:24:16457 test_layer->SetTextureMailbox(
458 test_data_.mailbox1_,
459 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
[email protected]de44a152013-01-08 15:28:46460}
461
[email protected]9794fb32013-08-29 09:49:59462class TextureLayerMailboxHolderTest : public TextureLayerTest {
463 public:
464 TextureLayerMailboxHolderTest()
465 : main_thread_("MAIN") {
466 main_thread_.Start();
467 }
468
469 void Wait(const base::Thread& thread) {
470 bool manual_reset = false;
471 bool initially_signaled = false;
472 base::WaitableEvent event(manual_reset, initially_signaled);
473 thread.message_loop()->PostTask(
474 FROM_HERE,
475 base::Bind(&base::WaitableEvent::Signal, base::Unretained(&event)));
476 event.Wait();
477 }
478
479 void CreateMainRef() {
480 main_ref_ = TestMailboxHolder::Create(
[email protected]9260757f2013-09-17 01:24:16481 test_data_.mailbox1_,
482 SingleReleaseCallback::Create(test_data_.release_mailbox1_)).Pass();
[email protected]9794fb32013-08-29 09:49:59483 }
484
485 void ReleaseMainRef() {
486 main_ref_.reset();
487 }
488
[email protected]9260757f2013-09-17 01:24:16489 void CreateImplRef(scoped_ptr<SingleReleaseCallback>* impl_ref) {
[email protected]9794fb32013-08-29 09:49:59490 *impl_ref = main_ref_->holder()->GetCallbackForImplThread();
491 }
492
493 void CapturePostTasksAndWait(base::WaitableEvent* begin_capture,
494 base::WaitableEvent* wait_for_capture,
495 base::WaitableEvent* stop_capture) {
496 begin_capture->Wait();
497 BlockingTaskRunner::CapturePostTasks capture;
498 wait_for_capture->Signal();
499 stop_capture->Wait();
500 }
501
502 protected:
503 scoped_ptr<TestMailboxHolder::MainThreadReference>
504 main_ref_;
505 base::Thread main_thread_;
506 CommonMailboxObjects test_data_;
507};
508
509TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_BothReleaseThenMain) {
510 scoped_refptr<TextureLayer> test_layer = TextureLayer::CreateForMailbox(NULL);
511 ASSERT_TRUE(test_layer.get());
512
513 main_thread_.message_loop()->PostTask(
514 FROM_HERE,
515 base::Bind(&TextureLayerMailboxHolderTest::CreateMainRef,
516 base::Unretained(this)));
517
518 Wait(main_thread_);
519
520 // The texture layer is attached to compositor1, and passes a reference to its
521 // impl tree.
[email protected]9260757f2013-09-17 01:24:16522 scoped_ptr<SingleReleaseCallback> compositor1;
[email protected]9794fb32013-08-29 09:49:59523 main_thread_.message_loop()->PostTask(
524 FROM_HERE,
525 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
526 base::Unretained(this),
527 &compositor1));
528
529 // Then the texture layer is removed and attached to compositor2, and passes a
530 // reference to its impl tree.
[email protected]9260757f2013-09-17 01:24:16531 scoped_ptr<SingleReleaseCallback> compositor2;
[email protected]9794fb32013-08-29 09:49:59532 main_thread_.message_loop()->PostTask(
533 FROM_HERE,
534 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
535 base::Unretained(this),
536 &compositor2));
537
538 Wait(main_thread_);
539 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
540
541 // The compositors both destroy their impl trees before the main thread layer
542 // is destroyed.
[email protected]9260757f2013-09-17 01:24:16543 compositor1->Run(100, false);
544 compositor2->Run(200, false);
[email protected]9794fb32013-08-29 09:49:59545
546 Wait(main_thread_);
547
548 EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0);
549 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
550
551 // The main thread ref is the last one, so the mailbox is released back to the
552 // embedder, with the last sync point provided by the impl trees.
553 EXPECT_CALL(test_data_.mock_callback_,
554 Release(test_data_.mailbox_name1_, 200, false)).Times(1);
555
556 main_thread_.message_loop()->PostTask(
557 FROM_HERE,
558 base::Bind(&TextureLayerMailboxHolderTest::ReleaseMainRef,
559 base::Unretained(this)));
560 Wait(main_thread_);
561 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
562}
563
564TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_MainReleaseBetween) {
565 scoped_refptr<TextureLayer> test_layer = TextureLayer::CreateForMailbox(NULL);
566 ASSERT_TRUE(test_layer.get());
567
568 main_thread_.message_loop()->PostTask(
569 FROM_HERE,
570 base::Bind(&TextureLayerMailboxHolderTest::CreateMainRef,
571 base::Unretained(this)));
572
573 Wait(main_thread_);
574
575 // The texture layer is attached to compositor1, and passes a reference to its
576 // impl tree.
[email protected]9260757f2013-09-17 01:24:16577 scoped_ptr<SingleReleaseCallback> compositor1;
[email protected]9794fb32013-08-29 09:49:59578 main_thread_.message_loop()->PostTask(
579 FROM_HERE,
580 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
581 base::Unretained(this),
582 &compositor1));
583
584 // Then the texture layer is removed and attached to compositor2, and passes a
585 // reference to its impl tree.
[email protected]9260757f2013-09-17 01:24:16586 scoped_ptr<SingleReleaseCallback> compositor2;
[email protected]9794fb32013-08-29 09:49:59587 main_thread_.message_loop()->PostTask(
588 FROM_HERE,
589 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
590 base::Unretained(this),
591 &compositor2));
592
593 Wait(main_thread_);
594 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
595
596 // One compositor destroys their impl tree.
[email protected]9260757f2013-09-17 01:24:16597 compositor1->Run(100, false);
[email protected]9794fb32013-08-29 09:49:59598
599 // Then the main thread reference is destroyed.
600 main_thread_.message_loop()->PostTask(
601 FROM_HERE,
602 base::Bind(&TextureLayerMailboxHolderTest::ReleaseMainRef,
603 base::Unretained(this)));
604
605 Wait(main_thread_);
606
607 EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0);
608 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
609
610 // The second impl reference is destroyed last, causing the mailbox to be
611 // released back to the embedder with the last sync point from the impl tree.
612 EXPECT_CALL(test_data_.mock_callback_,
613 Release(test_data_.mailbox_name1_, 200, true)).Times(1);
614
[email protected]9260757f2013-09-17 01:24:16615 compositor2->Run(200, true);
[email protected]9794fb32013-08-29 09:49:59616 Wait(main_thread_);
617 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
618}
619
620TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_MainReleasedFirst) {
621 scoped_refptr<TextureLayer> test_layer = TextureLayer::CreateForMailbox(NULL);
622 ASSERT_TRUE(test_layer.get());
623
624 main_thread_.message_loop()->PostTask(
625 FROM_HERE,
626 base::Bind(&TextureLayerMailboxHolderTest::CreateMainRef,
627 base::Unretained(this)));
628
629 Wait(main_thread_);
630
631 // The texture layer is attached to compositor1, and passes a reference to its
632 // impl tree.
[email protected]9260757f2013-09-17 01:24:16633 scoped_ptr<SingleReleaseCallback> compositor1;
[email protected]9794fb32013-08-29 09:49:59634 main_thread_.message_loop()->PostTask(
635 FROM_HERE,
636 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
637 base::Unretained(this),
638 &compositor1));
639
640 // Then the texture layer is removed and attached to compositor2, and passes a
641 // reference to its impl tree.
[email protected]9260757f2013-09-17 01:24:16642 scoped_ptr<SingleReleaseCallback> compositor2;
[email protected]9794fb32013-08-29 09:49:59643 main_thread_.message_loop()->PostTask(
644 FROM_HERE,
645 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
646 base::Unretained(this),
647 &compositor2));
648
649 Wait(main_thread_);
650 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
651
652 // The main thread reference is destroyed first.
653 main_thread_.message_loop()->PostTask(
654 FROM_HERE,
655 base::Bind(&TextureLayerMailboxHolderTest::ReleaseMainRef,
656 base::Unretained(this)));
657
658 // One compositor destroys their impl tree.
[email protected]9260757f2013-09-17 01:24:16659 compositor2->Run(200, false);
[email protected]9794fb32013-08-29 09:49:59660
661 Wait(main_thread_);
662
663 EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0);
664 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
665
666 // The second impl reference is destroyed last, causing the mailbox to be
667 // released back to the embedder with the last sync point from the impl tree.
668 EXPECT_CALL(test_data_.mock_callback_,
669 Release(test_data_.mailbox_name1_, 100, true)).Times(1);
670
[email protected]9260757f2013-09-17 01:24:16671 compositor1->Run(100, true);
[email protected]9794fb32013-08-29 09:49:59672 Wait(main_thread_);
673 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
674}
675
676TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_SecondImplRefShortcut) {
677 scoped_refptr<TextureLayer> test_layer = TextureLayer::CreateForMailbox(NULL);
678 ASSERT_TRUE(test_layer.get());
679
680 main_thread_.message_loop()->PostTask(
681 FROM_HERE,
682 base::Bind(&TextureLayerMailboxHolderTest::CreateMainRef,
683 base::Unretained(this)));
684
685 Wait(main_thread_);
686
687 // The texture layer is attached to compositor1, and passes a reference to its
688 // impl tree.
[email protected]9260757f2013-09-17 01:24:16689 scoped_ptr<SingleReleaseCallback> compositor1;
[email protected]9794fb32013-08-29 09:49:59690 main_thread_.message_loop()->PostTask(
691 FROM_HERE,
692 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
693 base::Unretained(this),
694 &compositor1));
695
696 // Then the texture layer is removed and attached to compositor2, and passes a
697 // reference to its impl tree.
[email protected]9260757f2013-09-17 01:24:16698 scoped_ptr<SingleReleaseCallback> compositor2;
[email protected]9794fb32013-08-29 09:49:59699 main_thread_.message_loop()->PostTask(
700 FROM_HERE,
701 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
702 base::Unretained(this),
703 &compositor2));
704
705 Wait(main_thread_);
706 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
707
708 // The main thread reference is destroyed first.
709 main_thread_.message_loop()->PostTask(
710 FROM_HERE,
711 base::Bind(&TextureLayerMailboxHolderTest::ReleaseMainRef,
712 base::Unretained(this)));
713
714 EXPECT_CALL(test_data_.mock_callback_,
715 Release(test_data_.mailbox_name1_, 200, true)).Times(1);
716
717 bool manual_reset = false;
718 bool initially_signaled = false;
719 base::WaitableEvent begin_capture(manual_reset, initially_signaled);
720 base::WaitableEvent wait_for_capture(manual_reset, initially_signaled);
721 base::WaitableEvent stop_capture(manual_reset, initially_signaled);
722
723 // Post a task to start capturing tasks on the main thread. This will block
724 // the main thread until we signal the |stop_capture| event.
725 main_thread_.message_loop()->PostTask(
726 FROM_HERE,
727 base::Bind(&TextureLayerMailboxHolderTest::CapturePostTasksAndWait,
728 base::Unretained(this),
729 &begin_capture,
730 &wait_for_capture,
731 &stop_capture));
732
733 // Before the main thread capturing starts, one compositor destroys their
734 // impl reference. Since capturing did not start, this gets post-tasked to
735 // the main thread.
[email protected]9260757f2013-09-17 01:24:16736 compositor1->Run(100, false);
[email protected]9794fb32013-08-29 09:49:59737
738 // Start capturing on the main thread.
739 begin_capture.Signal();
740 wait_for_capture.Wait();
741
742 // Meanwhile, the second compositor released its impl reference, but this task
743 // gets shortcutted directly to the main thread. This means the reference is
744 // released before compositor1, whose reference will be released later when
745 // the post-task is serviced. But since it was destroyed _on the impl thread_
746 // last, its sync point values should be used.
[email protected]9260757f2013-09-17 01:24:16747 compositor2->Run(200, true);
[email protected]9794fb32013-08-29 09:49:59748
749 stop_capture.Signal();
750 Wait(main_thread_);
751
752 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
753}
754
[email protected]e216fef02013-03-20 22:56:10755class TextureLayerImplWithMailboxThreadedCallback : public LayerTreeTest {
[email protected]28571b042013-03-14 07:59:15756 public:
757 TextureLayerImplWithMailboxThreadedCallback()
758 : callback_count_(0),
759 commit_count_(0) {}
760
761 // Make sure callback is received on main and doesn't block the impl thread.
[email protected]7ba3ca72013-04-11 06:37:25762 void ReleaseCallback(unsigned sync_point, bool lost_resource) {
[email protected]9794fb32013-08-29 09:49:59763 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]7ba3ca72013-04-11 06:37:25764 EXPECT_FALSE(lost_resource);
[email protected]28571b042013-03-14 07:59:15765 ++callback_count_;
766 }
767
768 void SetMailbox(char mailbox_char) {
[email protected]9794fb32013-08-29 09:49:59769 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]9260757f2013-09-17 01:24:16770 TextureMailbox mailbox(std::string(64, mailbox_char));
771 scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create(
[email protected]28571b042013-03-14 07:59:15772 base::Bind(
773 &TextureLayerImplWithMailboxThreadedCallback::ReleaseCallback,
774 base::Unretained(this)));
[email protected]9260757f2013-09-17 01:24:16775 layer_->SetTextureMailbox(mailbox, callback.Pass());
[email protected]28571b042013-03-14 07:59:15776 }
777
[email protected]e216fef02013-03-20 22:56:10778 virtual void BeginTest() OVERRIDE {
[email protected]9794fb32013-08-29 09:49:59779 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
780
[email protected]28571b042013-03-14 07:59:15781 gfx::Size bounds(100, 100);
782 root_ = Layer::Create();
783 root_->SetAnchorPoint(gfx::PointF());
784 root_->SetBounds(bounds);
785
[email protected]e8e4ae232013-04-12 00:26:01786 layer_ = TextureLayer::CreateForMailbox(NULL);
[email protected]28571b042013-03-14 07:59:15787 layer_->SetIsDrawable(true);
788 layer_->SetAnchorPoint(gfx::PointF());
789 layer_->SetBounds(bounds);
790
791 root_->AddChild(layer_);
[email protected]e216fef02013-03-20 22:56:10792 layer_tree_host()->SetRootLayer(root_);
[email protected]18ce59702013-04-09 04:58:40793 layer_tree_host()->SetViewportSize(bounds);
[email protected]28571b042013-03-14 07:59:15794 SetMailbox('1');
795 EXPECT_EQ(0, callback_count_);
796
797 // Case #1: change mailbox before the commit. The old mailbox should be
798 // released immediately.
799 SetMailbox('2');
800 EXPECT_EQ(1, callback_count_);
[email protected]e216fef02013-03-20 22:56:10801 PostSetNeedsCommitToMainThread();
[email protected]28571b042013-03-14 07:59:15802 }
803
[email protected]e216fef02013-03-20 22:56:10804 virtual void DidCommit() OVERRIDE {
[email protected]28571b042013-03-14 07:59:15805 ++commit_count_;
806 switch (commit_count_) {
807 case 1:
808 // Case #2: change mailbox after the commit (and draw), where the
809 // layer draws. The old mailbox should be released during the next
810 // commit.
811 SetMailbox('3');
812 EXPECT_EQ(1, callback_count_);
813 break;
814 case 2:
[email protected]28571b042013-03-14 07:59:15815 EXPECT_EQ(2, callback_count_);
816 // Case #3: change mailbox when the layer doesn't draw. The old
817 // mailbox should be released during the next commit.
818 layer_->SetBounds(gfx::Size());
819 SetMailbox('4');
820 break;
[email protected]9794fb32013-08-29 09:49:59821 case 3:
[email protected]28571b042013-03-14 07:59:15822 EXPECT_EQ(3, callback_count_);
823 // Case #4: release mailbox that was committed but never drawn. The
824 // old mailbox should be released during the next commit.
[email protected]9260757f2013-09-17 01:24:16825 layer_->SetTextureMailbox(TextureMailbox(),
826 scoped_ptr<SingleReleaseCallback>());
[email protected]28571b042013-03-14 07:59:15827 break;
[email protected]9794fb32013-08-29 09:49:59828 case 4:
829 if (layer_tree_host()->settings().impl_side_painting) {
830 // With impl painting, the texture mailbox will still be on the impl
831 // thread when the commit finishes, because the layer is not drawble
832 // when it has no texture mailbox, and thus does not block the commit
833 // on activation. So, we wait for activation.
834 // TODO(danakj): fix this. crbug.com/277953
835 layer_tree_host()->SetNeedsCommit();
836 break;
837 } else {
838 ++commit_count_;
839 }
840 case 5:
[email protected]28571b042013-03-14 07:59:15841 EXPECT_EQ(4, callback_count_);
[email protected]7096acc2013-06-18 21:12:43842 // Restore a mailbox for the next step.
843 SetMailbox('5');
844 break;
[email protected]9794fb32013-08-29 09:49:59845 case 6:
[email protected]7096acc2013-06-18 21:12:43846 // Case #5: remove layer from tree. Callback should *not* be called, the
847 // mailbox is returned to the main thread.
848 EXPECT_EQ(4, callback_count_);
849 layer_->RemoveFromParent();
850 break;
[email protected]9794fb32013-08-29 09:49:59851 case 7:
852 if (layer_tree_host()->settings().impl_side_painting) {
853 // With impl painting, the texture mailbox will still be on the impl
854 // thread when the commit finishes, because the layer is not around to
855 // block the commit on activation anymore. So, we wait for activation.
856 // TODO(danakj): fix this. crbug.com/277953
857 layer_tree_host()->SetNeedsCommit();
858 break;
859 } else {
860 ++commit_count_;
861 }
862 case 8:
[email protected]7096acc2013-06-18 21:12:43863 EXPECT_EQ(4, callback_count_);
864 // Resetting the mailbox will call the callback now.
[email protected]9260757f2013-09-17 01:24:16865 layer_->SetTextureMailbox(TextureMailbox(),
866 scoped_ptr<SingleReleaseCallback>());
[email protected]7096acc2013-06-18 21:12:43867 EXPECT_EQ(5, callback_count_);
[email protected]e216fef02013-03-20 22:56:10868 EndTest();
[email protected]28571b042013-03-14 07:59:15869 break;
870 default:
871 NOTREACHED();
872 break;
[email protected]de44a152013-01-08 15:28:46873 }
[email protected]28571b042013-03-14 07:59:15874 }
[email protected]de44a152013-01-08 15:28:46875
[email protected]e216fef02013-03-20 22:56:10876 virtual void AfterTest() OVERRIDE {}
[email protected]de44a152013-01-08 15:28:46877
[email protected]28571b042013-03-14 07:59:15878 private:
[email protected]9794fb32013-08-29 09:49:59879 base::ThreadChecker main_thread_;
[email protected]28571b042013-03-14 07:59:15880 int callback_count_;
881 int commit_count_;
882 scoped_refptr<Layer> root_;
883 scoped_refptr<TextureLayer> layer_;
[email protected]de44a152013-01-08 15:28:46884};
885
[email protected]4145d172013-05-10 16:54:36886SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
887 TextureLayerImplWithMailboxThreadedCallback);
[email protected]de44a152013-01-08 15:28:46888
[email protected]74b43cc2013-08-30 06:29:27889
890class TextureLayerNoMailboxIsActivatedDuringCommit : public LayerTreeTest,
891 public TextureLayerClient {
892 protected:
893 TextureLayerNoMailboxIsActivatedDuringCommit()
894 : wait_thread_("WAIT"),
895 wait_event_(false, false) {
896 wait_thread_.Start();
897 }
898
899 virtual void BeginTest() OVERRIDE {
900 activate_count_ = 0;
901
902 gfx::Size bounds(100, 100);
903 root_ = Layer::Create();
904 root_->SetAnchorPoint(gfx::PointF());
905 root_->SetBounds(bounds);
906
907 layer_ = TextureLayer::Create(this);
908 layer_->SetIsDrawable(true);
909 layer_->SetAnchorPoint(gfx::PointF());
910 layer_->SetBounds(bounds);
911
912 root_->AddChild(layer_);
913 layer_tree_host()->SetRootLayer(root_);
914 layer_tree_host()->SetViewportSize(bounds);
915
916 PostSetNeedsCommitToMainThread();
917 }
918
919 // TextureLayerClient implementation.
920 virtual unsigned PrepareTexture() OVERRIDE {
921 return OffscreenContextProviderForMainThread()
922 ->Context3d()->createTexture();
923 }
924 virtual WebKit::WebGraphicsContext3D* Context3d() OVERRIDE {
925 return OffscreenContextProviderForMainThread()->Context3d();
926 }
[email protected]9260757f2013-09-17 01:24:16927 virtual bool PrepareTextureMailbox(
928 TextureMailbox* mailbox,
929 scoped_ptr<SingleReleaseCallback>* release_callback,
930 bool use_shared_memory) OVERRIDE {
[email protected]74b43cc2013-08-30 06:29:27931 return false;
932 }
933
934 virtual void WillActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
935 // Slow down activation so the main thread DidCommit() will run if
936 // not blocked.
937 wait_thread_.message_loop()->PostDelayedTask(
938 FROM_HERE,
939 base::Bind(&base::WaitableEvent::Signal,
940 base::Unretained(&wait_event_)),
941 base::TimeDelta::FromMilliseconds(10));
942 wait_event_.Wait();
943
944 base::AutoLock lock(activate_lock_);
945 ++activate_count_;
946 }
947
948 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
949 // The main thread is awake now, and will run DidCommit() immediately.
950 // Run DidActivate() afterwards by posting it now.
951 proxy()->MainThreadTaskRunner()->PostTask(
952 FROM_HERE,
953 base::Bind(&TextureLayerNoMailboxIsActivatedDuringCommit::DidActivate,
954 base::Unretained(this)));
955 }
956
957 void DidActivate() {
958 base::AutoLock lock(activate_lock_);
959 switch (activate_count_) {
960 case 1:
961 // The first texture has been activated. Invalidate the layer so it
962 // grabs a new texture id from the client.
963 layer_->SetNeedsDisplay();
964 // So this commit number should complete after the second activate.
965 EXPECT_EQ(1, layer_tree_host()->source_frame_number());
966 break;
967 case 2:
968 // The second mailbox has been activated. Remove the layer from
969 // the tree to cause another commit/activation. The commit should
970 // finish *after* the layer is removed from the active tree.
971 layer_->RemoveFromParent();
972 // So this commit number should complete after the third activate.
973 EXPECT_EQ(2, layer_tree_host()->source_frame_number());
974 break;
975 case 3:
976 EndTest();
977 break;
978 }
979 }
980
981 virtual void DidCommit() OVERRIDE {
982 switch (layer_tree_host()->source_frame_number()) {
983 case 2: {
984 // The activate for the 2nd texture should have happened before now.
985 base::AutoLock lock(activate_lock_);
986 EXPECT_EQ(2, activate_count_);
987 break;
988 }
989 case 3: {
990 // The activate to remove the layer should have happened before now.
991 base::AutoLock lock(activate_lock_);
992 EXPECT_EQ(3, activate_count_);
993 break;
994 }
995 }
996 }
997
998
999 virtual void AfterTest() OVERRIDE {}
1000
1001 base::Thread wait_thread_;
1002 base::WaitableEvent wait_event_;
1003 base::Lock activate_lock_;
1004 int activate_count_;
1005 int activate_commit_;
1006 scoped_refptr<Layer> root_;
1007 scoped_refptr<TextureLayer> layer_;
1008};
1009
1010SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
1011 TextureLayerNoMailboxIsActivatedDuringCommit);
1012
1013class TextureLayerMailboxIsActivatedDuringCommit : public LayerTreeTest {
1014 protected:
1015 TextureLayerMailboxIsActivatedDuringCommit()
1016 : wait_thread_("WAIT"),
1017 wait_event_(false, false) {
1018 wait_thread_.Start();
1019 }
1020
1021 static void ReleaseCallback(unsigned sync_point, bool lost_resource) {}
1022
1023 void SetMailbox(char mailbox_char) {
[email protected]9260757f2013-09-17 01:24:161024 TextureMailbox mailbox(std::string(64, mailbox_char));
1025 scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create(
[email protected]74b43cc2013-08-30 06:29:271026 base::Bind(
1027 &TextureLayerMailboxIsActivatedDuringCommit::ReleaseCallback));
[email protected]9260757f2013-09-17 01:24:161028 layer_->SetTextureMailbox(mailbox, callback.Pass());
[email protected]74b43cc2013-08-30 06:29:271029 }
1030
1031 virtual void BeginTest() OVERRIDE {
1032 activate_count_ = 0;
1033
1034 gfx::Size bounds(100, 100);
1035 root_ = Layer::Create();
1036 root_->SetAnchorPoint(gfx::PointF());
1037 root_->SetBounds(bounds);
1038
1039 layer_ = TextureLayer::CreateForMailbox(NULL);
1040 layer_->SetIsDrawable(true);
1041 layer_->SetAnchorPoint(gfx::PointF());
1042 layer_->SetBounds(bounds);
1043
1044 root_->AddChild(layer_);
1045 layer_tree_host()->SetRootLayer(root_);
1046 layer_tree_host()->SetViewportSize(bounds);
1047 SetMailbox('1');
1048
1049 PostSetNeedsCommitToMainThread();
1050 }
1051
1052 virtual void WillActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1053 // Slow down activation so the main thread DidCommit() will run if
1054 // not blocked.
1055 wait_thread_.message_loop()->PostDelayedTask(
1056 FROM_HERE,
1057 base::Bind(&base::WaitableEvent::Signal,
1058 base::Unretained(&wait_event_)),
1059 base::TimeDelta::FromMilliseconds(10));
1060 wait_event_.Wait();
1061
1062 base::AutoLock lock(activate_lock_);
1063 ++activate_count_;
1064 }
1065
1066 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1067 // The main thread is awake now, and will run DidCommit() immediately.
1068 // Run DidActivate() afterwards by posting it now.
1069 proxy()->MainThreadTaskRunner()->PostTask(
1070 FROM_HERE,
1071 base::Bind(&TextureLayerMailboxIsActivatedDuringCommit::DidActivate,
1072 base::Unretained(this)));
1073 }
1074
1075 void DidActivate() {
1076 base::AutoLock lock(activate_lock_);
1077 switch (activate_count_) {
1078 case 1:
1079 // The first mailbox has been activated. Set a new mailbox, and
1080 // expect the next commit to finish *after* it is activated.
1081 SetMailbox('2');
1082 // So this commit number should complete after the second activate.
1083 EXPECT_EQ(1, layer_tree_host()->source_frame_number());
1084 break;
1085 case 2:
1086 // The second mailbox has been activated. Remove the layer from
1087 // the tree to cause another commit/activation. The commit should
1088 // finish *after* the layer is removed from the active tree.
1089 layer_->RemoveFromParent();
1090 // So this commit number should complete after the third activate.
1091 EXPECT_EQ(2, layer_tree_host()->source_frame_number());
1092 break;
1093 case 3:
1094 EndTest();
1095 break;
1096 }
1097 }
1098
1099 virtual void DidCommit() OVERRIDE {
1100 switch (layer_tree_host()->source_frame_number()) {
1101 case 2: {
1102 // The activate for the 2nd mailbox should have happened before now.
1103 base::AutoLock lock(activate_lock_);
1104 EXPECT_EQ(2, activate_count_);
1105 break;
1106 }
1107 case 3: {
1108 // The activate to remove the layer should have happened before now.
1109 base::AutoLock lock(activate_lock_);
1110 EXPECT_EQ(3, activate_count_);
1111 break;
1112 }
1113 }
1114 }
1115
1116
1117 virtual void AfterTest() OVERRIDE {}
1118
1119 base::Thread wait_thread_;
1120 base::WaitableEvent wait_event_;
1121 base::Lock activate_lock_;
1122 int activate_count_;
1123 scoped_refptr<Layer> root_;
1124 scoped_refptr<TextureLayer> layer_;
1125};
1126
1127SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
1128 TextureLayerMailboxIsActivatedDuringCommit);
1129
[email protected]de44a152013-01-08 15:28:461130class TextureLayerImplWithMailboxTest : public TextureLayerTest {
[email protected]28571b042013-03-14 07:59:151131 protected:
[email protected]408b5e22013-03-19 09:48:091132 TextureLayerImplWithMailboxTest()
1133 : fake_client_(
1134 FakeLayerTreeHostClient(FakeLayerTreeHostClient::DIRECT_3D)) {}
1135
[email protected]28571b042013-03-14 07:59:151136 virtual void SetUp() {
1137 TextureLayerTest::SetUp();
[email protected]408b5e22013-03-19 09:48:091138 layer_tree_host_.reset(new MockLayerTreeHost(&fake_client_));
[email protected]f74945f2013-03-21 17:08:361139 EXPECT_TRUE(host_impl_.InitializeRenderer(CreateFakeOutputSurface()));
[email protected]28571b042013-03-14 07:59:151140 }
[email protected]de44a152013-01-08 15:28:461141
[email protected]0ec335c42013-07-04 06:17:081142 bool WillDraw(TextureLayerImpl* layer, DrawMode mode) {
1143 bool will_draw = layer->WillDraw(
1144 mode, host_impl_.active_tree()->resource_provider());
1145 if (will_draw)
1146 layer->DidDraw(host_impl_.active_tree()->resource_provider());
1147 return will_draw;
1148 }
1149
[email protected]28571b042013-03-14 07:59:151150 CommonMailboxObjects test_data_;
[email protected]408b5e22013-03-19 09:48:091151 FakeLayerTreeHostClient fake_client_;
[email protected]de44a152013-01-08 15:28:461152};
1153
[email protected]ffbb2212013-06-02 23:47:591154// Test conditions for results of TextureLayerImpl::WillDraw under
1155// different configurations of different mailbox, texture_id, and draw_mode.
1156TEST_F(TextureLayerImplWithMailboxTest, TestWillDraw) {
[email protected]0ec335c42013-07-04 06:17:081157 EXPECT_CALL(test_data_.mock_callback_,
1158 Release(test_data_.mailbox_name1_,
1159 test_data_.sync_point1_,
1160 false))
1161 .Times(AnyNumber());
1162 EXPECT_CALL(test_data_.mock_callback_,
1163 Release2(test_data_.shared_memory_.get(), 0, false))
1164 .Times(AnyNumber());
[email protected]ffbb2212013-06-02 23:47:591165 // Hardware mode.
1166 {
1167 scoped_ptr<TextureLayerImpl> impl_layer =
1168 TextureLayerImpl::Create(host_impl_.active_tree(), 1, true);
[email protected]9260757f2013-09-17 01:24:161169 impl_layer->SetTextureMailbox(
1170 test_data_.mailbox1_,
1171 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
[email protected]0ec335c42013-07-04 06:17:081172 EXPECT_TRUE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE));
[email protected]ffbb2212013-06-02 23:47:591173 }
1174
1175 {
1176 scoped_ptr<TextureLayerImpl> impl_layer =
1177 TextureLayerImpl::Create(host_impl_.active_tree(), 1, true);
[email protected]9260757f2013-09-17 01:24:161178 impl_layer->SetTextureMailbox(TextureMailbox(),
1179 scoped_ptr<SingleReleaseCallback>());
[email protected]0ec335c42013-07-04 06:17:081180 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE));
1181 }
1182
1183 {
1184 // Software resource.
1185 scoped_ptr<TextureLayerImpl> impl_layer =
1186 TextureLayerImpl::Create(host_impl_.active_tree(), 1, true);
[email protected]9260757f2013-09-17 01:24:161187 impl_layer->SetTextureMailbox(
1188 test_data_.mailbox3_,
1189 SingleReleaseCallback::Create(test_data_.release_mailbox3_));
[email protected]3e44d7a2013-07-30 00:03:101190 EXPECT_TRUE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE));
[email protected]ffbb2212013-06-02 23:47:591191 }
1192
1193 {
1194 scoped_ptr<TextureLayerImpl> impl_layer =
1195 TextureLayerImpl::Create(host_impl_.active_tree(), 1, false);
[email protected]0634cdd42013-08-16 00:46:091196 ContextProvider* context_provider =
1197 host_impl_.output_surface()->context_provider();
[email protected]ffbb2212013-06-02 23:47:591198 unsigned texture =
[email protected]0634cdd42013-08-16 00:46:091199 context_provider->Context3d()->createTexture();
[email protected]ffbb2212013-06-02 23:47:591200 impl_layer->set_texture_id(texture);
[email protected]0ec335c42013-07-04 06:17:081201 EXPECT_TRUE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE));
[email protected]ffbb2212013-06-02 23:47:591202 }
1203
1204 {
1205 scoped_ptr<TextureLayerImpl> impl_layer =
1206 TextureLayerImpl::Create(host_impl_.active_tree(), 1, false);
1207 impl_layer->set_texture_id(0);
[email protected]0ec335c42013-07-04 06:17:081208 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE));
1209 }
1210
1211 // Software mode.
1212 {
1213 scoped_ptr<TextureLayerImpl> impl_layer =
1214 TextureLayerImpl::Create(host_impl_.active_tree(), 1, true);
[email protected]9260757f2013-09-17 01:24:161215 impl_layer->SetTextureMailbox(
1216 test_data_.mailbox1_,
1217 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
[email protected]0ec335c42013-07-04 06:17:081218 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE));
1219 }
1220
1221 {
1222 scoped_ptr<TextureLayerImpl> impl_layer =
1223 TextureLayerImpl::Create(host_impl_.active_tree(), 1, true);
[email protected]9260757f2013-09-17 01:24:161224 impl_layer->SetTextureMailbox(TextureMailbox(),
1225 scoped_ptr<SingleReleaseCallback>());
[email protected]0ec335c42013-07-04 06:17:081226 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE));
1227 }
1228
1229 {
1230 // Software resource.
1231 scoped_ptr<TextureLayerImpl> impl_layer =
1232 TextureLayerImpl::Create(host_impl_.active_tree(), 1, true);
[email protected]9260757f2013-09-17 01:24:161233 impl_layer->SetTextureMailbox(
1234 test_data_.mailbox3_,
1235 SingleReleaseCallback::Create(test_data_.release_mailbox3_));
[email protected]0ec335c42013-07-04 06:17:081236 EXPECT_TRUE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE));
1237 }
1238
1239 {
1240 scoped_ptr<TextureLayerImpl> impl_layer =
1241 TextureLayerImpl::Create(host_impl_.active_tree(), 1, false);
[email protected]0634cdd42013-08-16 00:46:091242 ContextProvider* context_provider =
1243 host_impl_.output_surface()->context_provider();
[email protected]0ec335c42013-07-04 06:17:081244 unsigned texture =
[email protected]0634cdd42013-08-16 00:46:091245 context_provider->Context3d()->createTexture();
[email protected]0ec335c42013-07-04 06:17:081246 impl_layer->set_texture_id(texture);
1247 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE));
1248 }
1249
1250 {
1251 scoped_ptr<TextureLayerImpl> impl_layer =
1252 TextureLayerImpl::Create(host_impl_.active_tree(), 1, false);
1253 impl_layer->set_texture_id(0);
1254 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE));
[email protected]ffbb2212013-06-02 23:47:591255 }
1256
1257 // Resourceless software mode.
1258 {
1259 scoped_ptr<TextureLayerImpl> impl_layer =
1260 TextureLayerImpl::Create(host_impl_.active_tree(), 1, true);
[email protected]9260757f2013-09-17 01:24:161261 impl_layer->SetTextureMailbox(
1262 test_data_.mailbox1_,
1263 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
[email protected]0ec335c42013-07-04 06:17:081264 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_RESOURCELESS_SOFTWARE));
[email protected]ffbb2212013-06-02 23:47:591265 }
1266
1267 {
1268 scoped_ptr<TextureLayerImpl> impl_layer =
1269 TextureLayerImpl::Create(host_impl_.active_tree(), 1, false);
[email protected]0634cdd42013-08-16 00:46:091270 ContextProvider* context_provider =
1271 host_impl_.output_surface()->context_provider();
[email protected]ffbb2212013-06-02 23:47:591272 unsigned texture =
[email protected]0634cdd42013-08-16 00:46:091273 context_provider->Context3d()->createTexture();
[email protected]ffbb2212013-06-02 23:47:591274 impl_layer->set_texture_id(texture);
[email protected]0ec335c42013-07-04 06:17:081275 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_RESOURCELESS_SOFTWARE));
[email protected]ffbb2212013-06-02 23:47:591276 }
1277}
1278
[email protected]28571b042013-03-14 07:59:151279TEST_F(TextureLayerImplWithMailboxTest, TestImplLayerCallbacks) {
1280 host_impl_.CreatePendingTree();
1281 scoped_ptr<TextureLayerImpl> pending_layer;
1282 pending_layer = TextureLayerImpl::Create(host_impl_.pending_tree(), 1, true);
1283 ASSERT_TRUE(pending_layer);
[email protected]de44a152013-01-08 15:28:461284
[email protected]ed511b8d2013-03-25 03:29:291285 scoped_ptr<LayerImpl> active_layer(
[email protected]28571b042013-03-14 07:59:151286 pending_layer->CreateLayerImpl(host_impl_.active_tree()));
[email protected]ed511b8d2013-03-25 03:29:291287 ASSERT_TRUE(active_layer);
[email protected]de44a152013-01-08 15:28:461288
[email protected]9260757f2013-09-17 01:24:161289 pending_layer->SetTextureMailbox(
1290 test_data_.mailbox1_,
1291 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
[email protected]421e84f2013-02-22 03:27:151292
[email protected]28571b042013-03-14 07:59:151293 // Test multiple commits without an activation.
1294 EXPECT_CALL(test_data_.mock_callback_,
[email protected]7ba3ca72013-04-11 06:37:251295 Release(test_data_.mailbox_name1_,
1296 test_data_.sync_point1_,
1297 false))
[email protected]28571b042013-03-14 07:59:151298 .Times(1);
[email protected]9260757f2013-09-17 01:24:161299 pending_layer->SetTextureMailbox(
1300 test_data_.mailbox2_,
1301 SingleReleaseCallback::Create(test_data_.release_mailbox2_));
[email protected]28571b042013-03-14 07:59:151302 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]421e84f2013-02-22 03:27:151303
[email protected]28571b042013-03-14 07:59:151304 // Test callback after activation.
[email protected]ed511b8d2013-03-25 03:29:291305 pending_layer->PushPropertiesTo(active_layer.get());
1306 active_layer->DidBecomeActive();
[email protected]421e84f2013-02-22 03:27:151307
[email protected]7ba3ca72013-04-11 06:37:251308 EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0);
[email protected]9260757f2013-09-17 01:24:161309 pending_layer->SetTextureMailbox(
1310 test_data_.mailbox1_,
1311 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
[email protected]28571b042013-03-14 07:59:151312 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]421e84f2013-02-22 03:27:151313
[email protected]7ba3ca72013-04-11 06:37:251314 EXPECT_CALL(test_data_.mock_callback_,
1315 Release(test_data_.mailbox_name2_, _, false))
[email protected]28571b042013-03-14 07:59:151316 .Times(1);
[email protected]ed511b8d2013-03-25 03:29:291317 pending_layer->PushPropertiesTo(active_layer.get());
1318 active_layer->DidBecomeActive();
[email protected]28571b042013-03-14 07:59:151319 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]de44a152013-01-08 15:28:461320
[email protected]28571b042013-03-14 07:59:151321 // Test resetting the mailbox.
[email protected]7ba3ca72013-04-11 06:37:251322 EXPECT_CALL(test_data_.mock_callback_,
1323 Release(test_data_.mailbox_name1_, _, false))
[email protected]28571b042013-03-14 07:59:151324 .Times(1);
[email protected]9260757f2013-09-17 01:24:161325 pending_layer->SetTextureMailbox(TextureMailbox(),
1326 scoped_ptr<SingleReleaseCallback>());
[email protected]ed511b8d2013-03-25 03:29:291327 pending_layer->PushPropertiesTo(active_layer.get());
1328 active_layer->DidBecomeActive();
[email protected]28571b042013-03-14 07:59:151329 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]de44a152013-01-08 15:28:461330
[email protected]28571b042013-03-14 07:59:151331 // Test destructor.
1332 EXPECT_CALL(test_data_.mock_callback_,
[email protected]7ba3ca72013-04-11 06:37:251333 Release(test_data_.mailbox_name1_,
1334 test_data_.sync_point1_,
1335 false))
[email protected]28571b042013-03-14 07:59:151336 .Times(1);
[email protected]9260757f2013-09-17 01:24:161337 pending_layer->SetTextureMailbox(
1338 test_data_.mailbox1_,
1339 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
[email protected]de44a152013-01-08 15:28:461340}
1341
[email protected]28571b042013-03-14 07:59:151342TEST_F(TextureLayerImplWithMailboxTest,
1343 TestDestructorCallbackOnCreatedResource) {
1344 scoped_ptr<TextureLayerImpl> impl_layer;
1345 impl_layer = TextureLayerImpl::Create(host_impl_.active_tree(), 1, true);
1346 ASSERT_TRUE(impl_layer);
[email protected]de44a152013-01-08 15:28:461347
[email protected]7ba3ca72013-04-11 06:37:251348 EXPECT_CALL(test_data_.mock_callback_,
1349 Release(test_data_.mailbox_name1_, _, false))
[email protected]28571b042013-03-14 07:59:151350 .Times(1);
[email protected]9260757f2013-09-17 01:24:161351 impl_layer->SetTextureMailbox(
1352 test_data_.mailbox1_,
1353 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
[email protected]ffbb2212013-06-02 23:47:591354 impl_layer->DidBecomeActive();
1355 EXPECT_TRUE(impl_layer->WillDraw(
1356 DRAW_MODE_HARDWARE, host_impl_.active_tree()->resource_provider()));
[email protected]28571b042013-03-14 07:59:151357 impl_layer->DidDraw(host_impl_.active_tree()->resource_provider());
[email protected]9260757f2013-09-17 01:24:161358 impl_layer->SetTextureMailbox(TextureMailbox(),
1359 scoped_ptr<SingleReleaseCallback>());
[email protected]de44a152013-01-08 15:28:461360}
1361
[email protected]28571b042013-03-14 07:59:151362TEST_F(TextureLayerImplWithMailboxTest, TestCallbackOnInUseResource) {
1363 ResourceProvider* provider = host_impl_.active_tree()->resource_provider();
1364 ResourceProvider::ResourceId id =
[email protected]9260757f2013-09-17 01:24:161365 provider->CreateResourceFromTextureMailbox(
1366 test_data_.mailbox1_,
1367 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
[email protected]28571b042013-03-14 07:59:151368 provider->AllocateForTesting(id);
[email protected]de44a152013-01-08 15:28:461369
[email protected]28571b042013-03-14 07:59:151370 // Transfer some resources to the parent.
1371 ResourceProvider::ResourceIdArray resource_ids_to_transfer;
1372 resource_ids_to_transfer.push_back(id);
1373 TransferableResourceArray list;
1374 provider->PrepareSendToParent(resource_ids_to_transfer, &list);
1375 EXPECT_TRUE(provider->InUseByConsumer(id));
[email protected]7ba3ca72013-04-11 06:37:251376 EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0);
[email protected]28571b042013-03-14 07:59:151377 provider->DeleteResource(id);
1378 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]7ba3ca72013-04-11 06:37:251379 EXPECT_CALL(test_data_.mock_callback_,
1380 Release(test_data_.mailbox_name1_, _, false))
[email protected]28571b042013-03-14 07:59:151381 .Times(1);
[email protected]e00bab022013-08-19 00:42:451382 ReturnedResourceArray returned;
1383 TransferableResource::ReturnResources(list, &returned);
1384 provider->ReceiveReturnsFromParent(returned);
[email protected]de44a152013-01-08 15:28:461385}
1386
[email protected]97d519fb2013-03-29 02:27:541387// Check that ClearClient correctly clears the state so that the impl side
1388// doesn't try to use a texture that could have been destroyed.
[email protected]7ba3ca72013-04-11 06:37:251389class TextureLayerClientTest
1390 : public LayerTreeTest,
1391 public TextureLayerClient {
[email protected]97d519fb2013-03-29 02:27:541392 public:
1393 TextureLayerClientTest()
1394 : context_(NULL),
1395 texture_(0),
1396 commit_count_(0),
1397 expected_used_textures_on_draw_(0),
1398 expected_used_textures_on_commit_(0) {}
1399
[email protected]ebc0e1df2013-08-01 02:46:221400 virtual scoped_ptr<OutputSurface> CreateOutputSurface(bool fallback)
1401 OVERRIDE {
[email protected]97d519fb2013-03-29 02:27:541402 scoped_ptr<TestWebGraphicsContext3D> context(
1403 TestWebGraphicsContext3D::Create());
1404 context_ = context.get();
1405 texture_ = context->createTexture();
[email protected]0634cdd42013-08-16 00:46:091406 return FakeOutputSurface::Create3d(context.Pass()).PassAs<OutputSurface>();
[email protected]97d519fb2013-03-29 02:27:541407 }
1408
[email protected]171cbb32013-07-11 03:51:191409 virtual unsigned PrepareTexture() OVERRIDE {
[email protected]97d519fb2013-03-29 02:27:541410 return texture_;
1411 }
1412
[email protected]d5d9bc52013-04-01 23:16:391413 virtual WebKit::WebGraphicsContext3D* Context3d() OVERRIDE {
[email protected]97d519fb2013-03-29 02:27:541414 return context_;
1415 }
1416
[email protected]2541d1a2013-07-10 07:33:271417 virtual bool PrepareTextureMailbox(
[email protected]9260757f2013-09-17 01:24:161418 TextureMailbox* mailbox,
1419 scoped_ptr<SingleReleaseCallback>* release_callback,
1420 bool use_shared_memory) OVERRIDE {
[email protected]e8e4ae232013-04-12 00:26:011421 return false;
1422 }
1423
[email protected]97d519fb2013-03-29 02:27:541424 virtual void SetupTree() OVERRIDE {
1425 scoped_refptr<Layer> root = Layer::Create();
1426 root->SetBounds(gfx::Size(10, 10));
1427 root->SetAnchorPoint(gfx::PointF());
1428 root->SetIsDrawable(true);
1429
1430 texture_layer_ = TextureLayer::Create(this);
1431 texture_layer_->SetBounds(gfx::Size(10, 10));
1432 texture_layer_->SetAnchorPoint(gfx::PointF());
1433 texture_layer_->SetIsDrawable(true);
1434 root->AddChild(texture_layer_);
1435
1436 layer_tree_host()->SetRootLayer(root);
1437 LayerTreeTest::SetupTree();
1438 {
1439 base::AutoLock lock(lock_);
1440 expected_used_textures_on_commit_ = 1;
1441 }
1442 }
1443
1444 virtual void BeginTest() OVERRIDE {
1445 PostSetNeedsCommitToMainThread();
1446 }
1447
1448 virtual void DidCommitAndDrawFrame() OVERRIDE {
1449 ++commit_count_;
1450 switch (commit_count_) {
1451 case 1:
1452 texture_layer_->ClearClient();
1453 texture_layer_->SetNeedsDisplay();
1454 {
1455 base::AutoLock lock(lock_);
1456 expected_used_textures_on_commit_ = 0;
1457 }
1458 texture_ = 0;
1459 break;
1460 case 2:
1461 EndTest();
1462 break;
1463 default:
1464 NOTREACHED();
1465 break;
1466 }
1467 }
1468
1469 virtual void BeginCommitOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
1470 base::AutoLock lock(lock_);
1471 expected_used_textures_on_draw_ = expected_used_textures_on_commit_;
1472 }
1473
1474 virtual bool PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
1475 LayerTreeHostImpl::FrameData* frame_data,
1476 bool result) OVERRIDE {
1477 context_->ResetUsedTextures();
1478 return true;
1479 }
1480
1481 virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl,
1482 bool result) OVERRIDE {
1483 ASSERT_TRUE(result);
1484 EXPECT_EQ(expected_used_textures_on_draw_, context_->NumUsedTextures());
1485 }
1486
1487 virtual void AfterTest() OVERRIDE {}
1488
1489 private:
1490 scoped_refptr<TextureLayer> texture_layer_;
1491 TestWebGraphicsContext3D* context_;
1492 unsigned texture_;
1493 int commit_count_;
1494
1495 // Used only on thread.
1496 unsigned expected_used_textures_on_draw_;
1497
1498 // Used on either thread, protected by lock_.
1499 base::Lock lock_;
1500 unsigned expected_used_textures_on_commit_;
1501};
1502
[email protected]4145d172013-05-10 16:54:361503// The TextureLayerClient does not use mailboxes, so can't use a delegating
1504// renderer.
1505SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(TextureLayerClientTest);
[email protected]97d519fb2013-03-29 02:27:541506
[email protected]b04264f92013-09-13 23:37:291507
1508// Checks that changing a texture in the client for a TextureLayer that's
1509// invisible correctly works without drawing a deleted texture. See
1510// crbug.com/266628
1511class TextureLayerChangeInvisibleTest
1512 : public LayerTreeTest,
1513 public TextureLayerClient {
1514 public:
1515 TextureLayerChangeInvisibleTest()
1516 : client_context_(TestWebGraphicsContext3D::Create()),
1517 texture_(client_context_->createTexture()),
1518 texture_to_delete_on_next_commit_(0),
1519 prepare_called_(0),
1520 commit_count_(0),
1521 expected_texture_on_draw_(0) {}
1522
1523 // TextureLayerClient implementation.
1524 virtual unsigned PrepareTexture() OVERRIDE {
1525 ++prepare_called_;
1526 return texture_;
1527 }
1528
1529 // TextureLayerClient implementation.
1530 virtual WebKit::WebGraphicsContext3D* Context3d() OVERRIDE {
1531 return client_context_.get();
1532 }
1533
1534 // TextureLayerClient implementation.
1535 virtual bool PrepareTextureMailbox(
[email protected]9260757f2013-09-17 01:24:161536 cc::TextureMailbox* mailbox,
1537 scoped_ptr<SingleReleaseCallback>* release_callback,
1538 bool use_shared_memory) OVERRIDE {
[email protected]b04264f92013-09-13 23:37:291539 return false;
1540 }
1541
1542 virtual void SetupTree() OVERRIDE {
1543 scoped_refptr<Layer> root = Layer::Create();
1544 root->SetBounds(gfx::Size(10, 10));
1545 root->SetAnchorPoint(gfx::PointF());
1546 root->SetIsDrawable(true);
1547
1548 solid_layer_ = SolidColorLayer::Create();
1549 solid_layer_->SetBounds(gfx::Size(10, 10));
1550 solid_layer_->SetIsDrawable(true);
1551 solid_layer_->SetBackgroundColor(SK_ColorWHITE);
1552 root->AddChild(solid_layer_);
1553
1554 parent_layer_ = Layer::Create();
1555 parent_layer_->SetBounds(gfx::Size(10, 10));
1556 parent_layer_->SetIsDrawable(true);
1557 root->AddChild(parent_layer_);
1558
1559 texture_layer_ = TextureLayer::Create(this);
1560 texture_layer_->SetBounds(gfx::Size(10, 10));
1561 texture_layer_->SetAnchorPoint(gfx::PointF());
1562 texture_layer_->SetIsDrawable(true);
1563 parent_layer_->AddChild(texture_layer_);
1564
1565 layer_tree_host()->SetRootLayer(root);
1566 LayerTreeTest::SetupTree();
1567 }
1568
1569 virtual void BeginTest() OVERRIDE {
1570 PostSetNeedsCommitToMainThread();
1571 }
1572
1573 virtual void DidCommitAndDrawFrame() OVERRIDE {
1574 ++commit_count_;
1575 switch (commit_count_) {
1576 case 1:
1577 // We should have updated the layer, committing the texture.
1578 EXPECT_EQ(1, prepare_called_);
1579 // Make layer invisible.
1580 parent_layer_->SetOpacity(0.f);
1581 break;
1582 case 2: {
1583 // Layer shouldn't have been updated.
1584 EXPECT_EQ(1, prepare_called_);
1585 // Change the texture.
1586 texture_to_delete_on_next_commit_ = texture_;
1587 texture_ = client_context_->createTexture();
1588 texture_layer_->SetNeedsDisplay();
1589 // Force a change to make sure we draw a frame.
1590 solid_layer_->SetBackgroundColor(SK_ColorGRAY);
1591 break;
1592 }
1593 case 3:
1594 EXPECT_EQ(1, prepare_called_);
1595 client_context_->deleteTexture(texture_to_delete_on_next_commit_);
1596 texture_to_delete_on_next_commit_ = 0;
1597 // Make layer visible again.
1598 parent_layer_->SetOpacity(1.f);
1599 break;
1600 case 4: {
1601 // Layer should have been updated.
1602 EXPECT_EQ(2, prepare_called_);
1603 texture_layer_->ClearClient();
1604 client_context_->deleteTexture(texture_);
1605 texture_ = 0;
1606 break;
1607 }
1608 case 5:
1609 EndTest();
1610 break;
1611 default:
1612 NOTREACHED();
1613 break;
1614 }
1615 }
1616
1617 virtual void BeginCommitOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
1618 ASSERT_TRUE(proxy()->IsMainThreadBlocked());
1619 // This is the only texture that can be drawn this frame.
1620 expected_texture_on_draw_ = texture_;
1621 }
1622
1623 virtual bool PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
1624 LayerTreeHostImpl::FrameData* frame_data,
1625 bool result) OVERRIDE {
1626 ContextForImplThread(host_impl)->ResetUsedTextures();
1627 return true;
1628 }
1629
1630 virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl,
1631 bool result) OVERRIDE {
1632 ASSERT_TRUE(result);
1633 TestWebGraphicsContext3D* context = ContextForImplThread(host_impl);
1634 int used_textures = context->NumUsedTextures();
1635 switch (host_impl->active_tree()->source_frame_number()) {
1636 case 0:
1637 EXPECT_EQ(1, used_textures);
1638 EXPECT_TRUE(context->UsedTexture(expected_texture_on_draw_));
1639 break;
1640 case 1:
1641 case 2:
1642 EXPECT_EQ(0, used_textures);
1643 break;
1644 case 3:
1645 EXPECT_EQ(1, used_textures);
1646 EXPECT_TRUE(context->UsedTexture(expected_texture_on_draw_));
1647 break;
1648 default:
1649 break;
1650 }
1651 }
1652
1653 virtual void AfterTest() OVERRIDE {}
1654
1655 private:
1656 TestWebGraphicsContext3D* ContextForImplThread(LayerTreeHostImpl* host_impl) {
1657 return static_cast<TestWebGraphicsContext3D*>(
1658 host_impl->output_surface()->context_provider()->Context3d());
1659 }
1660
1661 scoped_refptr<SolidColorLayer> solid_layer_;
1662 scoped_refptr<Layer> parent_layer_;
1663 scoped_refptr<TextureLayer> texture_layer_;
1664 scoped_ptr<TestWebGraphicsContext3D> client_context_;
1665
1666 // Used on the main thread, and on the impl thread while the main thread is
1667 // blocked.
1668 unsigned texture_;
1669
1670 // Used on the main thread.
1671 unsigned texture_to_delete_on_next_commit_;
1672 int prepare_called_;
1673 int commit_count_;
1674
1675 // Used on the compositor thread.
1676 unsigned expected_texture_on_draw_;
1677};
1678
1679// The TextureLayerChangeInvisibleTest does not use mailboxes, so can't use a
1680// delegating renderer.
1681SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(TextureLayerChangeInvisibleTest);
1682
1683// Checks that changing a mailbox in the client for a TextureLayer that's
1684// invisible correctly works and uses the new mailbox as soon as the layer
1685// becomes visible (and returns the old one).
1686class TextureLayerChangeInvisibleMailboxTest
1687 : public LayerTreeTest,
1688 public TextureLayerClient {
1689 public:
1690 TextureLayerChangeInvisibleMailboxTest()
1691 : mailbox_changed_(true),
1692 mailbox_returned_(0),
1693 prepare_called_(0),
1694 commit_count_(0) {
1695 mailbox_ = MakeMailbox('1');
1696 }
1697
1698 // TextureLayerClient implementation.
1699 virtual unsigned PrepareTexture() OVERRIDE {
1700 NOTREACHED();
1701 return 0;
1702 }
1703
1704 // TextureLayerClient implementation.
1705 virtual WebKit::WebGraphicsContext3D* Context3d() OVERRIDE {
1706 NOTREACHED();
1707 return NULL;
1708 }
1709
1710 // TextureLayerClient implementation.
1711 virtual bool PrepareTextureMailbox(
[email protected]9260757f2013-09-17 01:24:161712 cc::TextureMailbox* mailbox,
1713 scoped_ptr<SingleReleaseCallback>* release_callback,
1714 bool use_shared_memory) OVERRIDE {
[email protected]b04264f92013-09-13 23:37:291715 ++prepare_called_;
1716 if (!mailbox_changed_)
1717 return false;
1718 *mailbox = mailbox_;
[email protected]9260757f2013-09-17 01:24:161719 *release_callback = SingleReleaseCallback::Create(
1720 base::Bind(&TextureLayerChangeInvisibleMailboxTest::MailboxReleased,
1721 base::Unretained(this)));
[email protected]b04264f92013-09-13 23:37:291722 return true;
1723 }
1724
1725 TextureMailbox MakeMailbox(char name) {
[email protected]9260757f2013-09-17 01:24:161726 return TextureMailbox(std::string(64, name));
[email protected]b04264f92013-09-13 23:37:291727 }
1728
1729 void MailboxReleased(unsigned sync_point, bool lost_resource) {
1730 ++mailbox_returned_;
1731 }
1732
1733 virtual void SetupTree() OVERRIDE {
1734 scoped_refptr<Layer> root = Layer::Create();
1735 root->SetBounds(gfx::Size(10, 10));
1736 root->SetAnchorPoint(gfx::PointF());
1737 root->SetIsDrawable(true);
1738
1739 solid_layer_ = SolidColorLayer::Create();
1740 solid_layer_->SetBounds(gfx::Size(10, 10));
1741 solid_layer_->SetIsDrawable(true);
1742 solid_layer_->SetBackgroundColor(SK_ColorWHITE);
1743 root->AddChild(solid_layer_);
1744
1745 parent_layer_ = Layer::Create();
1746 parent_layer_->SetBounds(gfx::Size(10, 10));
1747 parent_layer_->SetIsDrawable(true);
1748 root->AddChild(parent_layer_);
1749
1750 texture_layer_ = TextureLayer::CreateForMailbox(this);
1751 texture_layer_->SetBounds(gfx::Size(10, 10));
1752 texture_layer_->SetAnchorPoint(gfx::PointF());
1753 texture_layer_->SetIsDrawable(true);
1754 parent_layer_->AddChild(texture_layer_);
1755
1756 layer_tree_host()->SetRootLayer(root);
1757 LayerTreeTest::SetupTree();
1758 }
1759
1760 virtual void BeginTest() OVERRIDE {
1761 PostSetNeedsCommitToMainThread();
1762 }
1763
1764 virtual void DidCommitAndDrawFrame() OVERRIDE {
1765 ++commit_count_;
1766 switch (commit_count_) {
1767 case 1:
1768 // We should have updated the layer, committing the texture.
1769 EXPECT_EQ(1, prepare_called_);
1770 // Make layer invisible.
1771 parent_layer_->SetOpacity(0.f);
1772 break;
1773 case 2:
1774 // Layer shouldn't have been updated.
1775 EXPECT_EQ(1, prepare_called_);
1776 // Change the texture.
1777 mailbox_ = MakeMailbox('2');
1778 mailbox_changed_ = true;
1779 texture_layer_->SetNeedsDisplay();
1780 // Force a change to make sure we draw a frame.
1781 solid_layer_->SetBackgroundColor(SK_ColorGRAY);
1782 break;
1783 case 3:
1784 // Layer shouldn't have been updated.
1785 EXPECT_EQ(1, prepare_called_);
1786 // So the old mailbox isn't returned yet.
1787 EXPECT_EQ(0, mailbox_returned_);
1788 // Make layer visible again.
1789 parent_layer_->SetOpacity(1.f);
1790 break;
1791 case 4:
1792 // Layer should have been updated.
1793 EXPECT_EQ(2, prepare_called_);
1794 // So the old mailbox should have been returned already.
1795 EXPECT_EQ(1, mailbox_returned_);
1796 texture_layer_->ClearClient();
1797 break;
1798 case 5:
1799 EXPECT_EQ(2, mailbox_returned_);
1800 EndTest();
1801 break;
1802 default:
1803 NOTREACHED();
1804 break;
1805 }
1806 }
1807
1808 virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl,
1809 bool result) OVERRIDE {
1810 ASSERT_TRUE(result);
1811 DelegatedFrameData* delegated_frame_data =
1812 output_surface()->last_sent_frame().delegated_frame_data.get();
1813 if (!delegated_frame_data)
1814 return;
1815
1816 // Return all resources immediately.
1817 TransferableResourceArray resources_to_return =
1818 output_surface()->resources_held_by_parent();
1819
1820 CompositorFrameAck ack;
1821 for (size_t i = 0; i < resources_to_return.size(); ++i)
1822 output_surface()->ReturnResource(resources_to_return[i].id, &ack);
[email protected]a7335e0b2013-09-18 09:34:511823 host_impl->ReclaimResources(&ack);
1824 host_impl->OnSwapBuffersComplete();
[email protected]b04264f92013-09-13 23:37:291825 }
1826
1827 virtual void AfterTest() OVERRIDE {}
1828
1829 private:
1830 scoped_refptr<SolidColorLayer> solid_layer_;
1831 scoped_refptr<Layer> parent_layer_;
1832 scoped_refptr<TextureLayer> texture_layer_;
1833
1834 // Used on the main thread.
1835 bool mailbox_changed_;
1836 TextureMailbox mailbox_;
1837 int mailbox_returned_;
1838 int prepare_called_;
1839 int commit_count_;
1840};
1841
1842SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerChangeInvisibleMailboxTest);
1843
[email protected]0bf5a202013-07-10 14:50:541844// Test recovering from a lost context.
1845class TextureLayerLostContextTest
1846 : public LayerTreeTest,
1847 public TextureLayerClient {
1848 public:
1849 TextureLayerLostContextTest()
1850 : texture_(0),
1851 draw_count_(0) {}
1852
[email protected]ebc0e1df2013-08-01 02:46:221853 virtual scoped_ptr<OutputSurface> CreateOutputSurface(bool fallback)
1854 OVERRIDE {
[email protected]0bf5a202013-07-10 14:50:541855 texture_context_ = TestWebGraphicsContext3D::Create();
1856 texture_ = texture_context_->createTexture();
[email protected]3f6a906c2013-07-17 01:03:261857 return CreateFakeOutputSurface();
[email protected]0bf5a202013-07-10 14:50:541858 }
1859
[email protected]171cbb32013-07-11 03:51:191860 virtual unsigned PrepareTexture() OVERRIDE {
[email protected]0bf5a202013-07-10 14:50:541861 if (draw_count_ == 0) {
1862 texture_context_->loseContextCHROMIUM(GL_GUILTY_CONTEXT_RESET_ARB,
1863 GL_INNOCENT_CONTEXT_RESET_ARB);
1864 }
1865 return texture_;
1866 }
1867
1868 virtual WebKit::WebGraphicsContext3D* Context3d() OVERRIDE {
1869 return texture_context_.get();
1870 }
1871
1872 virtual bool PrepareTextureMailbox(
[email protected]9260757f2013-09-17 01:24:161873 TextureMailbox* mailbox,
1874 scoped_ptr<SingleReleaseCallback>* release_callback,
1875 bool use_shared_memory) OVERRIDE {
[email protected]0bf5a202013-07-10 14:50:541876 return false;
1877 }
1878
1879 virtual void SetupTree() OVERRIDE {
1880 scoped_refptr<Layer> root = Layer::Create();
1881 root->SetBounds(gfx::Size(10, 10));
1882 root->SetIsDrawable(true);
1883
1884 texture_layer_ = TextureLayer::Create(this);
1885 texture_layer_->SetBounds(gfx::Size(10, 10));
1886 texture_layer_->SetIsDrawable(true);
1887 root->AddChild(texture_layer_);
1888
1889 layer_tree_host()->SetRootLayer(root);
1890 LayerTreeTest::SetupTree();
1891 }
1892
1893 virtual void BeginTest() OVERRIDE {
1894 PostSetNeedsCommitToMainThread();
1895 }
1896
1897 virtual bool PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
1898 LayerTreeHostImpl::FrameData* frame_data,
1899 bool result) OVERRIDE {
1900 LayerImpl* root = host_impl->RootLayer();
1901 TextureLayerImpl* texture_layer =
1902 static_cast<TextureLayerImpl*>(root->children()[0]);
1903 if (++draw_count_ == 1)
1904 EXPECT_EQ(0u, texture_layer->texture_id());
1905 else
1906 EXPECT_EQ(texture_, texture_layer->texture_id());
1907 return true;
1908 }
1909
1910 virtual void DidCommitAndDrawFrame() OVERRIDE {
1911 EndTest();
1912 }
1913
1914 virtual void AfterTest() OVERRIDE {}
1915
1916 private:
1917 scoped_refptr<TextureLayer> texture_layer_;
1918 scoped_ptr<TestWebGraphicsContext3D> texture_context_;
1919 unsigned texture_;
1920 int draw_count_;
1921};
1922
1923SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(TextureLayerLostContextTest);
1924
[email protected]9c2bd822013-07-26 12:30:171925class TextureLayerWithMailboxMainThreadDeleted : public LayerTreeTest {
1926 public:
1927 void ReleaseCallback(unsigned sync_point, bool lost_resource) {
[email protected]9794fb32013-08-29 09:49:591928 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]9c2bd822013-07-26 12:30:171929 EXPECT_FALSE(lost_resource);
1930 ++callback_count_;
1931 EndTest();
1932 }
1933
1934 void SetMailbox(char mailbox_char) {
[email protected]9794fb32013-08-29 09:49:591935 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]9260757f2013-09-17 01:24:161936 TextureMailbox mailbox(std::string(64, mailbox_char));
1937 scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create(
[email protected]9c2bd822013-07-26 12:30:171938 base::Bind(
1939 &TextureLayerWithMailboxMainThreadDeleted::ReleaseCallback,
1940 base::Unretained(this)));
[email protected]9260757f2013-09-17 01:24:161941 layer_->SetTextureMailbox(mailbox, callback.Pass());
[email protected]9c2bd822013-07-26 12:30:171942 }
1943
1944 virtual void SetupTree() OVERRIDE {
1945 gfx::Size bounds(100, 100);
1946 root_ = Layer::Create();
1947 root_->SetAnchorPoint(gfx::PointF());
1948 root_->SetBounds(bounds);
1949
1950 layer_ = TextureLayer::CreateForMailbox(NULL);
1951 layer_->SetIsDrawable(true);
1952 layer_->SetAnchorPoint(gfx::PointF());
1953 layer_->SetBounds(bounds);
1954
1955 root_->AddChild(layer_);
1956 layer_tree_host()->SetRootLayer(root_);
1957 layer_tree_host()->SetViewportSize(bounds);
1958 }
1959
1960 virtual void BeginTest() OVERRIDE {
[email protected]9794fb32013-08-29 09:49:591961 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
1962
[email protected]9c2bd822013-07-26 12:30:171963 callback_count_ = 0;
1964
1965 // Set the mailbox on the main thread.
1966 SetMailbox('1');
1967 EXPECT_EQ(0, callback_count_);
1968
1969 PostSetNeedsCommitToMainThread();
1970 }
1971
1972 virtual void DidCommitAndDrawFrame() OVERRIDE {
1973 switch (layer_tree_host()->source_frame_number()) {
1974 case 1:
1975 // Delete the TextureLayer on the main thread while the mailbox is in
1976 // the impl tree.
1977 layer_->RemoveFromParent();
1978 layer_ = NULL;
1979 break;
1980 }
1981 }
1982
1983 virtual void AfterTest() OVERRIDE {
1984 EXPECT_EQ(1, callback_count_);
1985 }
1986
1987 private:
[email protected]9794fb32013-08-29 09:49:591988 base::ThreadChecker main_thread_;
[email protected]9c2bd822013-07-26 12:30:171989 int callback_count_;
1990 scoped_refptr<Layer> root_;
1991 scoped_refptr<TextureLayer> layer_;
1992};
1993
1994SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
1995 TextureLayerWithMailboxMainThreadDeleted);
1996
1997class TextureLayerWithMailboxImplThreadDeleted : public LayerTreeTest {
1998 public:
1999 void ReleaseCallback(unsigned sync_point, bool lost_resource) {
[email protected]9794fb32013-08-29 09:49:592000 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]9c2bd822013-07-26 12:30:172001 EXPECT_FALSE(lost_resource);
2002 ++callback_count_;
2003 EndTest();
2004 }
2005
2006 void SetMailbox(char mailbox_char) {
[email protected]9794fb32013-08-29 09:49:592007 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]9260757f2013-09-17 01:24:162008 TextureMailbox mailbox(std::string(64, mailbox_char));
2009 scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create(
[email protected]9c2bd822013-07-26 12:30:172010 base::Bind(
2011 &TextureLayerWithMailboxImplThreadDeleted::ReleaseCallback,
2012 base::Unretained(this)));
[email protected]9260757f2013-09-17 01:24:162013 layer_->SetTextureMailbox(mailbox, callback.Pass());
[email protected]9c2bd822013-07-26 12:30:172014 }
2015
2016 virtual void SetupTree() OVERRIDE {
2017 gfx::Size bounds(100, 100);
2018 root_ = Layer::Create();
2019 root_->SetAnchorPoint(gfx::PointF());
2020 root_->SetBounds(bounds);
2021
2022 layer_ = TextureLayer::CreateForMailbox(NULL);
2023 layer_->SetIsDrawable(true);
2024 layer_->SetAnchorPoint(gfx::PointF());
2025 layer_->SetBounds(bounds);
2026
2027 root_->AddChild(layer_);
2028 layer_tree_host()->SetRootLayer(root_);
2029 layer_tree_host()->SetViewportSize(bounds);
2030 }
2031
2032 virtual void BeginTest() OVERRIDE {
[email protected]9794fb32013-08-29 09:49:592033 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
2034
[email protected]9c2bd822013-07-26 12:30:172035 callback_count_ = 0;
2036
2037 // Set the mailbox on the main thread.
2038 SetMailbox('1');
2039 EXPECT_EQ(0, callback_count_);
2040
2041 PostSetNeedsCommitToMainThread();
2042 }
2043
2044 virtual void DidCommitAndDrawFrame() OVERRIDE {
2045 switch (layer_tree_host()->source_frame_number()) {
2046 case 1:
2047 // Remove the TextureLayer on the main thread while the mailbox is in
2048 // the impl tree, but don't delete the TextureLayer until after the impl
2049 // tree side is deleted.
2050 layer_->RemoveFromParent();
2051 break;
2052 case 2:
2053 layer_ = NULL;
2054 break;
2055 }
2056 }
2057
2058 virtual void AfterTest() OVERRIDE {
2059 EXPECT_EQ(1, callback_count_);
2060 }
2061
2062 private:
[email protected]9794fb32013-08-29 09:49:592063 base::ThreadChecker main_thread_;
[email protected]9c2bd822013-07-26 12:30:172064 int callback_count_;
2065 scoped_refptr<Layer> root_;
2066 scoped_refptr<TextureLayer> layer_;
2067};
2068
2069SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
2070 TextureLayerWithMailboxImplThreadDeleted);
2071
[email protected]ba565742012-11-10 09:29:482072} // namespace
2073} // namespace cc