blob: e385f1b2ac5af86f760b2043087271e8f2a490f7 [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]b04264f92013-09-13 23:37:2915#include "cc/layers/solid_color_layer.h"
[email protected]97d519fb2013-03-29 02:27:5416#include "cc/layers/texture_layer_client.h"
[email protected]cc3cfaa2013-03-18 09:05:5217#include "cc/layers/texture_layer_impl.h"
[email protected]b04264f92013-09-13 23:37:2918#include "cc/output/compositor_frame_ack.h"
19#include "cc/output/context_provider.h"
[email protected]e00bab022013-08-19 00:42:4520#include "cc/resources/returned_resource.h"
[email protected]586d51ed2012-12-07 20:31:4521#include "cc/test/fake_impl_proxy.h"
[email protected]101441ce2012-10-16 01:45:0322#include "cc/test/fake_layer_tree_host_client.h"
[email protected]586d51ed2012-12-07 20:31:4523#include "cc/test/fake_layer_tree_host_impl.h"
[email protected]199b715e2013-08-13 05:18:3424#include "cc/test/fake_output_surface.h"
[email protected]06d68d02013-04-19 18:46:2125#include "cc/test/layer_test_common.h"
[email protected]e216fef02013-03-20 22:56:1026#include "cc/test/layer_tree_test.h"
[email protected]c2610b9f2013-10-31 06:54:5927#include "cc/test/test_web_graphics_context_3d.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;
[email protected]67dbcf202014-04-03 14:40:5740using ::testing::InvokeWithoutArgs;
[email protected]c0dd24c2012-08-30 23:25:2741
[email protected]ba565742012-11-10 09:29:4842namespace cc {
[email protected]c0dd24c2012-08-30 23:25:2743namespace {
44
[email protected]e0a4d732014-02-15 00:23:2645gpu::Mailbox MailboxFromChar(char value) {
[email protected]df41e252014-02-03 23:39:5046 gpu::Mailbox mailbox;
[email protected]e0a4d732014-02-15 00:23:2647 memset(mailbox.name, value, sizeof(mailbox.name));
[email protected]df41e252014-02-03 23:39:5048 return mailbox;
49}
50
[email protected]408b5e22013-03-19 09:48:0951class MockLayerTreeHost : public LayerTreeHost {
[email protected]28571b042013-03-14 07:59:1552 public:
[email protected]943528e2013-11-07 05:01:3253 explicit MockLayerTreeHost(FakeLayerTreeHostClient* client)
[email protected]a7f35682013-10-22 23:05:5754 : LayerTreeHost(client, NULL, LayerTreeSettings()) {
[email protected]943528e2013-11-07 05:01:3255 InitializeSingleThreaded(client);
[email protected]28571b042013-03-14 07:59:1556 }
[email protected]c0dd24c2012-08-30 23:25:2757
[email protected]28571b042013-03-14 07:59:1558 MOCK_METHOD0(AcquireLayerTextures, void());
59 MOCK_METHOD0(SetNeedsCommit, void());
[email protected]3519b872013-07-30 07:17:5060 MOCK_METHOD0(SetNeedsUpdateLayers, void());
[email protected]aeeb3372013-11-05 14:05:5461 MOCK_METHOD0(StartRateLimiter, void());
62 MOCK_METHOD0(StopRateLimiter, void());
[email protected]c0dd24c2012-08-30 23:25:2763};
64
[email protected]67dbcf202014-04-03 14:40:5765class FakeTextureLayerClient : public TextureLayerClient {
66 public:
67 FakeTextureLayerClient() : texture_(0), mailbox_changed_(true) {}
68
69 virtual unsigned PrepareTexture() OVERRIDE { return texture_; }
70
71 virtual bool PrepareTextureMailbox(
72 TextureMailbox* mailbox,
73 scoped_ptr<SingleReleaseCallback>* release_callback,
74 bool use_shared_memory) OVERRIDE {
75 if (!mailbox_changed_)
76 return false;
77
78 *mailbox = mailbox_;
79 *release_callback = release_callback_.Pass();
80 mailbox_changed_ = false;
81 return true;
82 }
83
84 void set_texture(unsigned texture) { texture_ = texture; }
85
86 void set_mailbox(const TextureMailbox& mailbox,
87 scoped_ptr<SingleReleaseCallback> release_callback) {
88 mailbox_ = mailbox;
89 release_callback_ = release_callback.Pass();
90 mailbox_changed_ = true;
91 }
92
93 private:
94 unsigned texture_;
95 TextureMailbox mailbox_;
96 scoped_ptr<SingleReleaseCallback> release_callback_;
97 bool mailbox_changed_;
98 DISALLOW_COPY_AND_ASSIGN(FakeTextureLayerClient);
99};
100
101class MockMailboxCallback {
102 public:
103 MOCK_METHOD3(Release,
104 void(const gpu::Mailbox& mailbox,
105 uint32 sync_point,
106 bool lost_resource));
107 MOCK_METHOD3(Release2,
108 void(base::SharedMemory* shared_memory,
109 uint32 sync_point,
110 bool lost_resource));
111};
112
113struct CommonMailboxObjects {
114 CommonMailboxObjects()
115 : mailbox_name1_(MailboxFromChar('1')),
116 mailbox_name2_(MailboxFromChar('2')),
117 sync_point1_(1),
118 sync_point2_(2),
119 shared_memory_(new base::SharedMemory) {
120 release_mailbox1_ = base::Bind(&MockMailboxCallback::Release,
121 base::Unretained(&mock_callback_),
122 mailbox_name1_);
123 release_mailbox2_ = base::Bind(&MockMailboxCallback::Release,
124 base::Unretained(&mock_callback_),
125 mailbox_name2_);
126 const uint32 arbitrary_target1 = GL_TEXTURE_2D;
127 const uint32 arbitrary_target2 = GL_TEXTURE_EXTERNAL_OES;
128 mailbox1_ = TextureMailbox(mailbox_name1_, arbitrary_target1, sync_point1_);
129 mailbox2_ = TextureMailbox(mailbox_name2_, arbitrary_target2, sync_point2_);
130 gfx::Size size(128, 128);
131 EXPECT_TRUE(shared_memory_->CreateAndMapAnonymous(4 * size.GetArea()));
132 release_mailbox3_ = base::Bind(&MockMailboxCallback::Release2,
133 base::Unretained(&mock_callback_),
134 shared_memory_.get());
135 mailbox3_ = TextureMailbox(shared_memory_.get(), size);
136 }
137
138 gpu::Mailbox mailbox_name1_;
139 gpu::Mailbox mailbox_name2_;
140 MockMailboxCallback mock_callback_;
141 ReleaseCallback release_mailbox1_;
142 ReleaseCallback release_mailbox2_;
143 ReleaseCallback release_mailbox3_;
144 TextureMailbox mailbox1_;
145 TextureMailbox mailbox2_;
146 TextureMailbox mailbox3_;
147 uint32 sync_point1_;
148 uint32 sync_point2_;
149 scoped_ptr<base::SharedMemory> shared_memory_;
150};
151
[email protected]31d4df82013-07-18 10:17:22152class TextureLayerTest : public testing::Test {
153 public:
154 TextureLayerTest()
155 : fake_client_(
[email protected]4e2eb352014-03-20 17:25:45156 FakeLayerTreeHostClient(FakeLayerTreeHostClient::DIRECT_3D)),
157 host_impl_(&proxy_, &shared_bitmap_manager_) {}
[email protected]31d4df82013-07-18 10:17:22158
159 protected:
160 virtual void SetUp() {
161 layer_tree_host_.reset(new MockLayerTreeHost(&fake_client_));
[email protected]67dbcf202014-04-03 14:40:57162 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
163 layer_tree_host_->SetViewportSize(gfx::Size(10, 10));
164 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
[email protected]31d4df82013-07-18 10:17:22165 }
166
167 virtual void TearDown() {
168 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
169 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(AnyNumber());
170 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
171
172 layer_tree_host_->SetRootLayer(NULL);
173 layer_tree_host_.reset();
174 }
175
176 scoped_ptr<MockLayerTreeHost> layer_tree_host_;
177 FakeImplProxy proxy_;
178 FakeLayerTreeHostClient fake_client_;
[email protected]4e2eb352014-03-20 17:25:45179 TestSharedBitmapManager shared_bitmap_manager_;
[email protected]31d4df82013-07-18 10:17:22180 FakeLayerTreeHostImpl host_impl_;
181};
182
[email protected]67dbcf202014-04-03 14:40:57183TEST_F(TextureLayerTest, SyncImplWhenClearingTexture) {
184 scoped_ptr<TestWebGraphicsContext3D> context(
185 TestWebGraphicsContext3D::Create());
186 FakeTextureLayerClient client;
187 scoped_refptr<TextureLayer> test_layer = TextureLayer::Create(&client);
[email protected]31d4df82013-07-18 10:17:22188 ASSERT_TRUE(test_layer.get());
[email protected]67dbcf202014-04-03 14:40:57189 test_layer->SetIsDrawable(true);
190 test_layer->SetBounds(gfx::Size(10, 10));
[email protected]31d4df82013-07-18 10:17:22191
[email protected]67dbcf202014-04-03 14:40:57192 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
[email protected]31d4df82013-07-18 10:17:22193 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
194 layer_tree_host_->SetRootLayer(test_layer);
195 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
196 EXPECT_EQ(test_layer->layer_tree_host(), layer_tree_host_.get());
197
[email protected]67dbcf202014-04-03 14:40:57198 // Clearing the texture before we gave one should not sync.
199 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
200 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(0);
201 test_layer->ClearTexture();
202 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
203
204 // Give a texture to the layer through the client.
205 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
206 EXPECT_CALL(*layer_tree_host_, SetNeedsUpdateLayers()).Times(AtLeast(1));
207 client.set_texture(context->createTexture());
208 test_layer->SetNeedsDisplay();
209 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
210 // Force a commit.
211 layer_tree_host_->Composite(base::TimeTicks());
212
213 // Clearing the texture should sync.
214 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(AtLeast(1));
215 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
216 test_layer->ClearTexture();
217 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
218
219 // But only once.
220 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
221 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(0);
222 test_layer->ClearTexture();
223 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
224
225 // Force a commit to give another texture.
226 EXPECT_CALL(*layer_tree_host_, SetNeedsUpdateLayers()).Times(AtLeast(1));
227 test_layer->SetNeedsDisplay();
228 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
229 layer_tree_host_->Composite(base::TimeTicks());
230
231 // Make undrawable and commit.
232 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
233 test_layer->SetIsDrawable(false);
234 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
235 layer_tree_host_->Composite(base::TimeTicks());
236
237 // Clearing textures should not sync.
[email protected]31d4df82013-07-18 10:17:22238 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
239 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
[email protected]67dbcf202014-04-03 14:40:57240 test_layer->ClearTexture();
[email protected]31d4df82013-07-18 10:17:22241 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
242}
243
[email protected]67dbcf202014-04-03 14:40:57244TEST_F(TextureLayerTest, SyncImplWhenClearingMailbox) {
245 CommonMailboxObjects mailboxes;
246 FakeTextureLayerClient client;
247 scoped_refptr<TextureLayer> test_layer =
248 TextureLayer::CreateForMailbox(&client);
[email protected]31d4df82013-07-18 10:17:22249 ASSERT_TRUE(test_layer.get());
[email protected]67dbcf202014-04-03 14:40:57250 test_layer->SetIsDrawable(true);
251 test_layer->SetBounds(gfx::Size(10, 10));
252 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
[email protected]31d4df82013-07-18 10:17:22253 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
254 layer_tree_host_->SetRootLayer(test_layer);
[email protected]31d4df82013-07-18 10:17:22255 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
256 EXPECT_EQ(test_layer->layer_tree_host(), layer_tree_host_.get());
257
[email protected]67dbcf202014-04-03 14:40:57258 // Clearing the mailbox before we gave one should not sync.
259 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
260 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
261 test_layer->ClearTexture();
[email protected]31d4df82013-07-18 10:17:22262 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
263
[email protected]67dbcf202014-04-03 14:40:57264 // Give a mailbox to the layer through the client.
[email protected]31d4df82013-07-18 10:17:22265 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
[email protected]67dbcf202014-04-03 14:40:57266 client.set_mailbox(
267 mailboxes.mailbox1_,
268 SingleReleaseCallback::Create(mailboxes.release_mailbox1_));
269 EXPECT_CALL(*layer_tree_host_, SetNeedsUpdateLayers()).Times(AtLeast(1));
270 test_layer->SetNeedsDisplay();
271 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
272 // Force a commit.
273 layer_tree_host_->Composite(base::TimeTicks());
274
275 // Clearing the mailbox should not sync.
276 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
277 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
278 test_layer->ClearTexture();
[email protected]31d4df82013-07-18 10:17:22279 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
280
[email protected]67dbcf202014-04-03 14:40:57281 // Commit will return mailbox1.
282 EXPECT_CALL(mailboxes.mock_callback_,
283 Release(mailboxes.mailbox_name1_, _, false));
284 layer_tree_host_->Composite(base::TimeTicks());
285 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
286
287 // Force a commit to give another mailbox.
[email protected]31d4df82013-07-18 10:17:22288 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
[email protected]67dbcf202014-04-03 14:40:57289 client.set_mailbox(
290 mailboxes.mailbox2_,
291 SingleReleaseCallback::Create(mailboxes.release_mailbox2_));
292 EXPECT_CALL(*layer_tree_host_, SetNeedsUpdateLayers()).Times(AtLeast(1));
293 test_layer->SetNeedsDisplay();
294 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
295 layer_tree_host_->Composite(base::TimeTicks());
296
297 // Make undrawable and commit.
298 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
[email protected]31d4df82013-07-18 10:17:22299 test_layer->SetIsDrawable(false);
[email protected]67dbcf202014-04-03 14:40:57300 layer_tree_host_->Composite(base::TimeTicks());
[email protected]31d4df82013-07-18 10:17:22301 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
302
[email protected]67dbcf202014-04-03 14:40:57303 // Clearing textures should not sync.
[email protected]31d4df82013-07-18 10:17:22304 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
[email protected]67dbcf202014-04-03 14:40:57305 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
306 test_layer->ClearTexture();
307 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
308
309 // Commit will return the mailbox.
310 EXPECT_CALL(mailboxes.mock_callback_,
311 Release(mailboxes.mailbox_name2_, _, false));
312 layer_tree_host_->Composite(base::TimeTicks());
[email protected]31d4df82013-07-18 10:17:22313 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
314}
315
316TEST_F(TextureLayerTest, SyncImplWhenRemovingFromTree) {
[email protected]67dbcf202014-04-03 14:40:57317 scoped_ptr<TestWebGraphicsContext3D> context(
318 TestWebGraphicsContext3D::Create());
[email protected]31d4df82013-07-18 10:17:22319 scoped_refptr<Layer> root_layer = Layer::Create();
320 ASSERT_TRUE(root_layer.get());
321 scoped_refptr<Layer> child_layer = Layer::Create();
322 ASSERT_TRUE(child_layer.get());
323 root_layer->AddChild(child_layer);
[email protected]67dbcf202014-04-03 14:40:57324 FakeTextureLayerClient client;
325 scoped_refptr<TextureLayer> test_layer = TextureLayer::Create(&client);
326 test_layer->SetIsDrawable(true);
327 test_layer->SetBounds(gfx::Size(10, 10));
[email protected]31d4df82013-07-18 10:17:22328 ASSERT_TRUE(test_layer.get());
[email protected]31d4df82013-07-18 10:17:22329 child_layer->AddChild(test_layer);
330
[email protected]67dbcf202014-04-03 14:40:57331 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
[email protected]31d4df82013-07-18 10:17:22332 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
333 layer_tree_host_->SetRootLayer(root_layer);
334 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
335
336 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
337 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
338 test_layer->RemoveFromParent();
339 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
340
341 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
342 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
343 child_layer->AddChild(test_layer);
344 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
345
[email protected]67dbcf202014-04-03 14:40:57346 // Give a texture to the layer through the client.
[email protected]31d4df82013-07-18 10:17:22347 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
[email protected]67dbcf202014-04-03 14:40:57348 EXPECT_CALL(*layer_tree_host_, SetNeedsUpdateLayers()).Times(AtLeast(1));
349 client.set_texture(context->createTexture());
350 test_layer->SetNeedsDisplay();
[email protected]31d4df82013-07-18 10:17:22351 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
[email protected]67dbcf202014-04-03 14:40:57352 // Force a commit.
353 layer_tree_host_->Composite(base::TimeTicks());
[email protected]31d4df82013-07-18 10:17:22354
355 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(AtLeast(1));
356 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
357 test_layer->RemoveFromParent();
358 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
359}
360
361TEST_F(TextureLayerTest, CheckPropertyChangeCausesCorrectBehavior) {
362 scoped_refptr<TextureLayer> test_layer = TextureLayer::Create(NULL);
[email protected]80d42bd2013-08-30 19:13:45363 EXPECT_SET_NEEDS_COMMIT(1, layer_tree_host_->SetRootLayer(test_layer));
[email protected]31d4df82013-07-18 10:17:22364
365 // Test properties that should call SetNeedsCommit. All properties need to
366 // be set to new values in order for SetNeedsCommit to be called.
367 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetFlipped(false));
368 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetUV(
369 gfx::PointF(0.25f, 0.25f), gfx::PointF(0.75f, 0.75f)));
370 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetVertexOpacity(
371 0.5f, 0.5f, 0.5f, 0.5f));
372 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetPremultipliedAlpha(false));
373 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetBlendBackgroundColor(true));
[email protected]31d4df82013-07-18 10:17:22374}
375
[email protected]1c10e232013-07-31 12:35:43376TEST_F(TextureLayerTest, VisibleContentOpaqueRegion) {
377 const gfx::Size layer_bounds(100, 100);
378 const gfx::Rect layer_rect(layer_bounds);
379 const Region layer_region(layer_rect);
380
381 scoped_refptr<TextureLayer> layer = TextureLayer::Create(NULL);
382 layer->SetBounds(layer_bounds);
383 layer->draw_properties().visible_content_rect = layer_rect;
384 layer->SetBlendBackgroundColor(true);
385
386 // Verify initial conditions.
387 EXPECT_FALSE(layer->contents_opaque());
388 EXPECT_EQ(0u, layer->background_color());
389 EXPECT_EQ(Region().ToString(),
390 layer->VisibleContentOpaqueRegion().ToString());
391
392 // Opaque background.
393 layer->SetBackgroundColor(SK_ColorWHITE);
394 EXPECT_EQ(layer_region.ToString(),
395 layer->VisibleContentOpaqueRegion().ToString());
396
397 // Transparent background.
398 layer->SetBackgroundColor(SkColorSetARGB(100, 255, 255, 255));
399 EXPECT_EQ(Region().ToString(),
400 layer->VisibleContentOpaqueRegion().ToString());
401}
402
[email protected]31d4df82013-07-18 10:17:22403TEST_F(TextureLayerTest, RateLimiter) {
404 FakeTextureLayerClient client;
405 scoped_refptr<TextureLayer> test_layer = TextureLayer::CreateForMailbox(
406 &client);
407 test_layer->SetIsDrawable(true);
408 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
409 layer_tree_host_->SetRootLayer(test_layer);
410
411 // Don't rate limit until we invalidate.
[email protected]aeeb3372013-11-05 14:05:54412 EXPECT_CALL(*layer_tree_host_, StartRateLimiter()).Times(0);
[email protected]31d4df82013-07-18 10:17:22413 test_layer->SetRateLimitContext(true);
414 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
415
416 // Do rate limit after we invalidate.
[email protected]aeeb3372013-11-05 14:05:54417 EXPECT_CALL(*layer_tree_host_, StartRateLimiter());
[email protected]31d4df82013-07-18 10:17:22418 test_layer->SetNeedsDisplay();
419 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
420
421 // Stop rate limiter when we don't want it any more.
[email protected]aeeb3372013-11-05 14:05:54422 EXPECT_CALL(*layer_tree_host_, StopRateLimiter());
[email protected]31d4df82013-07-18 10:17:22423 test_layer->SetRateLimitContext(false);
424 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
425
426 // Or we clear the client.
427 test_layer->SetRateLimitContext(true);
[email protected]aeeb3372013-11-05 14:05:54428 EXPECT_CALL(*layer_tree_host_, StopRateLimiter());
[email protected]31d4df82013-07-18 10:17:22429 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
430 test_layer->ClearClient();
431 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
432
433 // Reset to a layer with a client, that started the rate limiter.
434 test_layer = TextureLayer::CreateForMailbox(
435 &client);
436 test_layer->SetIsDrawable(true);
437 test_layer->SetRateLimitContext(true);
438 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
439 layer_tree_host_->SetRootLayer(test_layer);
[email protected]aeeb3372013-11-05 14:05:54440 EXPECT_CALL(*layer_tree_host_, StartRateLimiter()).Times(0);
[email protected]31d4df82013-07-18 10:17:22441 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
[email protected]aeeb3372013-11-05 14:05:54442 EXPECT_CALL(*layer_tree_host_, StartRateLimiter());
[email protected]31d4df82013-07-18 10:17:22443 test_layer->SetNeedsDisplay();
444 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
445
446 // Stop rate limiter when we're removed from the tree.
[email protected]aeeb3372013-11-05 14:05:54447 EXPECT_CALL(*layer_tree_host_, StopRateLimiter());
[email protected]67dbcf202014-04-03 14:40:57448 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1);
[email protected]31d4df82013-07-18 10:17:22449 layer_tree_host_->SetRootLayer(NULL);
450 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
451}
452
[email protected]df41e252014-02-03 23:39:50453class TestMailboxHolder : public TextureLayer::TextureMailboxHolder {
[email protected]9794fb32013-08-29 09:49:59454 public:
[email protected]df41e252014-02-03 23:39:50455 using TextureLayer::TextureMailboxHolder::Create;
[email protected]9794fb32013-08-29 09:49:59456
457 protected:
458 virtual ~TestMailboxHolder() {}
459};
460
[email protected]de44a152013-01-08 15:28:46461class TextureLayerWithMailboxTest : public TextureLayerTest {
[email protected]28571b042013-03-14 07:59:15462 protected:
463 virtual void TearDown() {
464 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
465 EXPECT_CALL(test_data_.mock_callback_,
466 Release(test_data_.mailbox_name1_,
[email protected]7ba3ca72013-04-11 06:37:25467 test_data_.sync_point1_,
468 false)).Times(1);
[email protected]28571b042013-03-14 07:59:15469 TextureLayerTest::TearDown();
470 }
[email protected]de44a152013-01-08 15:28:46471
[email protected]28571b042013-03-14 07:59:15472 CommonMailboxObjects test_data_;
[email protected]de44a152013-01-08 15:28:46473};
474
[email protected]28571b042013-03-14 07:59:15475TEST_F(TextureLayerWithMailboxTest, ReplaceMailboxOnMainThreadBeforeCommit) {
[email protected]e8e4ae232013-04-12 00:26:01476 scoped_refptr<TextureLayer> test_layer = TextureLayer::CreateForMailbox(NULL);
[email protected]22898ed2013-06-01 04:52:30477 ASSERT_TRUE(test_layer.get());
[email protected]de44a152013-01-08 15:28:46478
[email protected]28571b042013-03-14 07:59:15479 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
480 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
481 layer_tree_host_->SetRootLayer(test_layer);
482 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
[email protected]de44a152013-01-08 15:28:46483
[email protected]28571b042013-03-14 07:59:15484 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
485 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
[email protected]9260757f2013-09-17 01:24:16486 test_layer->SetTextureMailbox(
487 test_data_.mailbox1_,
488 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
[email protected]28571b042013-03-14 07:59:15489 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
[email protected]de44a152013-01-08 15:28:46490
[email protected]28571b042013-03-14 07:59:15491 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
492 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
493 EXPECT_CALL(test_data_.mock_callback_,
[email protected]7ba3ca72013-04-11 06:37:25494 Release(test_data_.mailbox_name1_,
495 test_data_.sync_point1_,
496 false))
[email protected]28571b042013-03-14 07:59:15497 .Times(1);
[email protected]9260757f2013-09-17 01:24:16498 test_layer->SetTextureMailbox(
499 test_data_.mailbox2_,
500 SingleReleaseCallback::Create(test_data_.release_mailbox2_));
[email protected]28571b042013-03-14 07:59:15501 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
502 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]de44a152013-01-08 15:28:46503
[email protected]28571b042013-03-14 07:59:15504 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
505 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
506 EXPECT_CALL(test_data_.mock_callback_,
[email protected]7ba3ca72013-04-11 06:37:25507 Release(test_data_.mailbox_name2_,
508 test_data_.sync_point2_,
509 false))
[email protected]28571b042013-03-14 07:59:15510 .Times(1);
[email protected]9260757f2013-09-17 01:24:16511 test_layer->SetTextureMailbox(TextureMailbox(),
512 scoped_ptr<SingleReleaseCallback>());
[email protected]28571b042013-03-14 07:59:15513 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
514 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]de44a152013-01-08 15:28:46515
[email protected]80d42bd2013-08-30 19:13:45516 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
517 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
[email protected]9260757f2013-09-17 01:24:16518 test_layer->SetTextureMailbox(
519 test_data_.mailbox3_,
520 SingleReleaseCallback::Create(test_data_.release_mailbox3_));
[email protected]42f40a52013-06-08 04:38:51521 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
522 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
523
524 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
525 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
526 EXPECT_CALL(test_data_.mock_callback_,
527 Release2(test_data_.shared_memory_.get(),
528 0, false))
529 .Times(1);
[email protected]9260757f2013-09-17 01:24:16530 test_layer->SetTextureMailbox(TextureMailbox(),
531 scoped_ptr<SingleReleaseCallback>());
[email protected]42f40a52013-06-08 04:38:51532 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
533 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
534
[email protected]28571b042013-03-14 07:59:15535 // Test destructor.
536 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
[email protected]9260757f2013-09-17 01:24:16537 test_layer->SetTextureMailbox(
538 test_data_.mailbox1_,
539 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
[email protected]de44a152013-01-08 15:28:46540}
541
[email protected]f9e8f452014-03-07 22:09:40542TEST_F(TextureLayerTest, SetTextureMailboxWithoutReleaseCallback) {
543 scoped_refptr<TextureLayer> test_layer = TextureLayer::CreateForMailbox(NULL);
544 ASSERT_TRUE(test_layer.get());
545
546 // These use the same gpu::Mailbox, but different sync points.
547 TextureMailbox mailbox1(MailboxFromChar('a'), GL_TEXTURE_2D, 1);
548 TextureMailbox mailbox2(MailboxFromChar('a'), GL_TEXTURE_2D, 2);
549
550 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
551 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
552 layer_tree_host_->SetRootLayer(test_layer);
553 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
554
555 // Set the mailbox the first time. It should cause a commit.
556 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
557 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
558 test_layer->SetTextureMailboxWithoutReleaseCallback(mailbox1);
559 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
560
561 // Set the mailbox again with a new sync point, as the backing texture has
562 // been updated. It should cause a new commit.
563 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
564 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
565 test_layer->SetTextureMailboxWithoutReleaseCallback(mailbox2);
566 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
567}
568
[email protected]9794fb32013-08-29 09:49:59569class TextureLayerMailboxHolderTest : public TextureLayerTest {
570 public:
571 TextureLayerMailboxHolderTest()
572 : main_thread_("MAIN") {
573 main_thread_.Start();
574 }
575
576 void Wait(const base::Thread& thread) {
577 bool manual_reset = false;
578 bool initially_signaled = false;
579 base::WaitableEvent event(manual_reset, initially_signaled);
580 thread.message_loop()->PostTask(
581 FROM_HERE,
582 base::Bind(&base::WaitableEvent::Signal, base::Unretained(&event)));
583 event.Wait();
584 }
585
586 void CreateMainRef() {
587 main_ref_ = TestMailboxHolder::Create(
[email protected]9260757f2013-09-17 01:24:16588 test_data_.mailbox1_,
589 SingleReleaseCallback::Create(test_data_.release_mailbox1_)).Pass();
[email protected]9794fb32013-08-29 09:49:59590 }
591
592 void ReleaseMainRef() {
593 main_ref_.reset();
594 }
595
[email protected]9260757f2013-09-17 01:24:16596 void CreateImplRef(scoped_ptr<SingleReleaseCallback>* impl_ref) {
[email protected]9794fb32013-08-29 09:49:59597 *impl_ref = main_ref_->holder()->GetCallbackForImplThread();
598 }
599
600 void CapturePostTasksAndWait(base::WaitableEvent* begin_capture,
601 base::WaitableEvent* wait_for_capture,
602 base::WaitableEvent* stop_capture) {
603 begin_capture->Wait();
604 BlockingTaskRunner::CapturePostTasks capture;
605 wait_for_capture->Signal();
606 stop_capture->Wait();
607 }
608
609 protected:
610 scoped_ptr<TestMailboxHolder::MainThreadReference>
611 main_ref_;
612 base::Thread main_thread_;
613 CommonMailboxObjects test_data_;
614};
615
616TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_BothReleaseThenMain) {
617 scoped_refptr<TextureLayer> test_layer = TextureLayer::CreateForMailbox(NULL);
618 ASSERT_TRUE(test_layer.get());
619
620 main_thread_.message_loop()->PostTask(
621 FROM_HERE,
622 base::Bind(&TextureLayerMailboxHolderTest::CreateMainRef,
623 base::Unretained(this)));
624
625 Wait(main_thread_);
626
627 // The texture layer is attached to compositor1, and passes a reference to its
628 // impl tree.
[email protected]9260757f2013-09-17 01:24:16629 scoped_ptr<SingleReleaseCallback> compositor1;
[email protected]9794fb32013-08-29 09:49:59630 main_thread_.message_loop()->PostTask(
631 FROM_HERE,
632 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
633 base::Unretained(this),
634 &compositor1));
635
636 // Then the texture layer is removed and attached to compositor2, and passes a
637 // reference to its impl tree.
[email protected]9260757f2013-09-17 01:24:16638 scoped_ptr<SingleReleaseCallback> compositor2;
[email protected]9794fb32013-08-29 09:49:59639 main_thread_.message_loop()->PostTask(
640 FROM_HERE,
641 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
642 base::Unretained(this),
643 &compositor2));
644
645 Wait(main_thread_);
646 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
647
648 // The compositors both destroy their impl trees before the main thread layer
649 // is destroyed.
[email protected]9260757f2013-09-17 01:24:16650 compositor1->Run(100, false);
651 compositor2->Run(200, false);
[email protected]9794fb32013-08-29 09:49:59652
653 Wait(main_thread_);
654
655 EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0);
656 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
657
658 // The main thread ref is the last one, so the mailbox is released back to the
659 // embedder, with the last sync point provided by the impl trees.
660 EXPECT_CALL(test_data_.mock_callback_,
661 Release(test_data_.mailbox_name1_, 200, false)).Times(1);
662
663 main_thread_.message_loop()->PostTask(
664 FROM_HERE,
665 base::Bind(&TextureLayerMailboxHolderTest::ReleaseMainRef,
666 base::Unretained(this)));
667 Wait(main_thread_);
668 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
669}
670
671TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_MainReleaseBetween) {
672 scoped_refptr<TextureLayer> test_layer = TextureLayer::CreateForMailbox(NULL);
673 ASSERT_TRUE(test_layer.get());
674
675 main_thread_.message_loop()->PostTask(
676 FROM_HERE,
677 base::Bind(&TextureLayerMailboxHolderTest::CreateMainRef,
678 base::Unretained(this)));
679
680 Wait(main_thread_);
681
682 // The texture layer is attached to compositor1, and passes a reference to its
683 // impl tree.
[email protected]9260757f2013-09-17 01:24:16684 scoped_ptr<SingleReleaseCallback> compositor1;
[email protected]9794fb32013-08-29 09:49:59685 main_thread_.message_loop()->PostTask(
686 FROM_HERE,
687 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
688 base::Unretained(this),
689 &compositor1));
690
691 // Then the texture layer is removed and attached to compositor2, and passes a
692 // reference to its impl tree.
[email protected]9260757f2013-09-17 01:24:16693 scoped_ptr<SingleReleaseCallback> compositor2;
[email protected]9794fb32013-08-29 09:49:59694 main_thread_.message_loop()->PostTask(
695 FROM_HERE,
696 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
697 base::Unretained(this),
698 &compositor2));
699
700 Wait(main_thread_);
701 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
702
703 // One compositor destroys their impl tree.
[email protected]9260757f2013-09-17 01:24:16704 compositor1->Run(100, false);
[email protected]9794fb32013-08-29 09:49:59705
706 // Then the main thread reference is destroyed.
707 main_thread_.message_loop()->PostTask(
708 FROM_HERE,
709 base::Bind(&TextureLayerMailboxHolderTest::ReleaseMainRef,
710 base::Unretained(this)));
711
712 Wait(main_thread_);
713
714 EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0);
715 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
716
717 // The second impl reference is destroyed last, causing the mailbox to be
718 // released back to the embedder with the last sync point from the impl tree.
719 EXPECT_CALL(test_data_.mock_callback_,
720 Release(test_data_.mailbox_name1_, 200, true)).Times(1);
721
[email protected]9260757f2013-09-17 01:24:16722 compositor2->Run(200, true);
[email protected]9794fb32013-08-29 09:49:59723 Wait(main_thread_);
724 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
725}
726
727TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_MainReleasedFirst) {
728 scoped_refptr<TextureLayer> test_layer = TextureLayer::CreateForMailbox(NULL);
729 ASSERT_TRUE(test_layer.get());
730
731 main_thread_.message_loop()->PostTask(
732 FROM_HERE,
733 base::Bind(&TextureLayerMailboxHolderTest::CreateMainRef,
734 base::Unretained(this)));
735
736 Wait(main_thread_);
737
738 // The texture layer is attached to compositor1, and passes a reference to its
739 // impl tree.
[email protected]9260757f2013-09-17 01:24:16740 scoped_ptr<SingleReleaseCallback> compositor1;
[email protected]9794fb32013-08-29 09:49:59741 main_thread_.message_loop()->PostTask(
742 FROM_HERE,
743 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
744 base::Unretained(this),
745 &compositor1));
746
747 // Then the texture layer is removed and attached to compositor2, and passes a
748 // reference to its impl tree.
[email protected]9260757f2013-09-17 01:24:16749 scoped_ptr<SingleReleaseCallback> compositor2;
[email protected]9794fb32013-08-29 09:49:59750 main_thread_.message_loop()->PostTask(
751 FROM_HERE,
752 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
753 base::Unretained(this),
754 &compositor2));
755
756 Wait(main_thread_);
757 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
758
759 // The main thread reference is destroyed first.
760 main_thread_.message_loop()->PostTask(
761 FROM_HERE,
762 base::Bind(&TextureLayerMailboxHolderTest::ReleaseMainRef,
763 base::Unretained(this)));
764
765 // One compositor destroys their impl tree.
[email protected]9260757f2013-09-17 01:24:16766 compositor2->Run(200, false);
[email protected]9794fb32013-08-29 09:49:59767
768 Wait(main_thread_);
769
770 EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0);
771 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
772
773 // The second impl reference is destroyed last, causing the mailbox to be
774 // released back to the embedder with the last sync point from the impl tree.
775 EXPECT_CALL(test_data_.mock_callback_,
776 Release(test_data_.mailbox_name1_, 100, true)).Times(1);
777
[email protected]9260757f2013-09-17 01:24:16778 compositor1->Run(100, true);
[email protected]9794fb32013-08-29 09:49:59779 Wait(main_thread_);
780 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
781}
782
783TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_SecondImplRefShortcut) {
784 scoped_refptr<TextureLayer> test_layer = TextureLayer::CreateForMailbox(NULL);
785 ASSERT_TRUE(test_layer.get());
786
787 main_thread_.message_loop()->PostTask(
788 FROM_HERE,
789 base::Bind(&TextureLayerMailboxHolderTest::CreateMainRef,
790 base::Unretained(this)));
791
792 Wait(main_thread_);
793
794 // The texture layer is attached to compositor1, and passes a reference to its
795 // impl tree.
[email protected]9260757f2013-09-17 01:24:16796 scoped_ptr<SingleReleaseCallback> compositor1;
[email protected]9794fb32013-08-29 09:49:59797 main_thread_.message_loop()->PostTask(
798 FROM_HERE,
799 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
800 base::Unretained(this),
801 &compositor1));
802
803 // Then the texture layer is removed and attached to compositor2, and passes a
804 // reference to its impl tree.
[email protected]9260757f2013-09-17 01:24:16805 scoped_ptr<SingleReleaseCallback> compositor2;
[email protected]9794fb32013-08-29 09:49:59806 main_thread_.message_loop()->PostTask(
807 FROM_HERE,
808 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
809 base::Unretained(this),
810 &compositor2));
811
812 Wait(main_thread_);
813 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
814
815 // The main thread reference is destroyed first.
816 main_thread_.message_loop()->PostTask(
817 FROM_HERE,
818 base::Bind(&TextureLayerMailboxHolderTest::ReleaseMainRef,
819 base::Unretained(this)));
820
821 EXPECT_CALL(test_data_.mock_callback_,
822 Release(test_data_.mailbox_name1_, 200, true)).Times(1);
823
824 bool manual_reset = false;
825 bool initially_signaled = false;
826 base::WaitableEvent begin_capture(manual_reset, initially_signaled);
827 base::WaitableEvent wait_for_capture(manual_reset, initially_signaled);
828 base::WaitableEvent stop_capture(manual_reset, initially_signaled);
829
830 // Post a task to start capturing tasks on the main thread. This will block
831 // the main thread until we signal the |stop_capture| event.
832 main_thread_.message_loop()->PostTask(
833 FROM_HERE,
834 base::Bind(&TextureLayerMailboxHolderTest::CapturePostTasksAndWait,
835 base::Unretained(this),
836 &begin_capture,
837 &wait_for_capture,
838 &stop_capture));
839
840 // Before the main thread capturing starts, one compositor destroys their
841 // impl reference. Since capturing did not start, this gets post-tasked to
842 // the main thread.
[email protected]9260757f2013-09-17 01:24:16843 compositor1->Run(100, false);
[email protected]9794fb32013-08-29 09:49:59844
845 // Start capturing on the main thread.
846 begin_capture.Signal();
847 wait_for_capture.Wait();
848
849 // Meanwhile, the second compositor released its impl reference, but this task
850 // gets shortcutted directly to the main thread. This means the reference is
851 // released before compositor1, whose reference will be released later when
852 // the post-task is serviced. But since it was destroyed _on the impl thread_
853 // last, its sync point values should be used.
[email protected]9260757f2013-09-17 01:24:16854 compositor2->Run(200, true);
[email protected]9794fb32013-08-29 09:49:59855
856 stop_capture.Signal();
857 Wait(main_thread_);
858
859 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
860}
861
[email protected]e216fef02013-03-20 22:56:10862class TextureLayerImplWithMailboxThreadedCallback : public LayerTreeTest {
[email protected]28571b042013-03-14 07:59:15863 public:
864 TextureLayerImplWithMailboxThreadedCallback()
865 : callback_count_(0),
866 commit_count_(0) {}
867
868 // Make sure callback is received on main and doesn't block the impl thread.
[email protected]df41e252014-02-03 23:39:50869 void ReleaseCallback(uint32 sync_point, bool lost_resource) {
[email protected]9794fb32013-08-29 09:49:59870 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]7ba3ca72013-04-11 06:37:25871 EXPECT_FALSE(lost_resource);
[email protected]28571b042013-03-14 07:59:15872 ++callback_count_;
873 }
874
875 void SetMailbox(char mailbox_char) {
[email protected]9794fb32013-08-29 09:49:59876 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]9260757f2013-09-17 01:24:16877 scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create(
[email protected]28571b042013-03-14 07:59:15878 base::Bind(
879 &TextureLayerImplWithMailboxThreadedCallback::ReleaseCallback,
880 base::Unretained(this)));
[email protected]df41e252014-02-03 23:39:50881 layer_->SetTextureMailbox(
[email protected]e0a4d732014-02-15 00:23:26882 TextureMailbox(MailboxFromChar(mailbox_char), GL_TEXTURE_2D, 0),
[email protected]df41e252014-02-03 23:39:50883 callback.Pass());
[email protected]28571b042013-03-14 07:59:15884 }
885
[email protected]e216fef02013-03-20 22:56:10886 virtual void BeginTest() OVERRIDE {
[email protected]9794fb32013-08-29 09:49:59887 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
888
[email protected]28571b042013-03-14 07:59:15889 gfx::Size bounds(100, 100);
890 root_ = Layer::Create();
891 root_->SetAnchorPoint(gfx::PointF());
892 root_->SetBounds(bounds);
893
[email protected]e8e4ae232013-04-12 00:26:01894 layer_ = TextureLayer::CreateForMailbox(NULL);
[email protected]28571b042013-03-14 07:59:15895 layer_->SetIsDrawable(true);
896 layer_->SetAnchorPoint(gfx::PointF());
897 layer_->SetBounds(bounds);
898
899 root_->AddChild(layer_);
[email protected]e216fef02013-03-20 22:56:10900 layer_tree_host()->SetRootLayer(root_);
[email protected]18ce59702013-04-09 04:58:40901 layer_tree_host()->SetViewportSize(bounds);
[email protected]28571b042013-03-14 07:59:15902 SetMailbox('1');
903 EXPECT_EQ(0, callback_count_);
904
905 // Case #1: change mailbox before the commit. The old mailbox should be
906 // released immediately.
907 SetMailbox('2');
908 EXPECT_EQ(1, callback_count_);
[email protected]e216fef02013-03-20 22:56:10909 PostSetNeedsCommitToMainThread();
[email protected]28571b042013-03-14 07:59:15910 }
911
[email protected]e216fef02013-03-20 22:56:10912 virtual void DidCommit() OVERRIDE {
[email protected]28571b042013-03-14 07:59:15913 ++commit_count_;
914 switch (commit_count_) {
915 case 1:
916 // Case #2: change mailbox after the commit (and draw), where the
917 // layer draws. The old mailbox should be released during the next
918 // commit.
919 SetMailbox('3');
920 EXPECT_EQ(1, callback_count_);
921 break;
922 case 2:
[email protected]28571b042013-03-14 07:59:15923 EXPECT_EQ(2, callback_count_);
924 // Case #3: change mailbox when the layer doesn't draw. The old
925 // mailbox should be released during the next commit.
926 layer_->SetBounds(gfx::Size());
927 SetMailbox('4');
928 break;
[email protected]9794fb32013-08-29 09:49:59929 case 3:
[email protected]28571b042013-03-14 07:59:15930 EXPECT_EQ(3, callback_count_);
931 // Case #4: release mailbox that was committed but never drawn. The
932 // old mailbox should be released during the next commit.
[email protected]9260757f2013-09-17 01:24:16933 layer_->SetTextureMailbox(TextureMailbox(),
934 scoped_ptr<SingleReleaseCallback>());
[email protected]28571b042013-03-14 07:59:15935 break;
[email protected]9794fb32013-08-29 09:49:59936 case 4:
937 if (layer_tree_host()->settings().impl_side_painting) {
938 // With impl painting, the texture mailbox will still be on the impl
939 // thread when the commit finishes, because the layer is not drawble
940 // when it has no texture mailbox, and thus does not block the commit
941 // on activation. So, we wait for activation.
942 // TODO(danakj): fix this. crbug.com/277953
943 layer_tree_host()->SetNeedsCommit();
944 break;
945 } else {
946 ++commit_count_;
947 }
948 case 5:
[email protected]28571b042013-03-14 07:59:15949 EXPECT_EQ(4, callback_count_);
[email protected]7096acc2013-06-18 21:12:43950 // Restore a mailbox for the next step.
951 SetMailbox('5');
952 break;
[email protected]9794fb32013-08-29 09:49:59953 case 6:
[email protected]7096acc2013-06-18 21:12:43954 // Case #5: remove layer from tree. Callback should *not* be called, the
955 // mailbox is returned to the main thread.
956 EXPECT_EQ(4, callback_count_);
957 layer_->RemoveFromParent();
958 break;
[email protected]9794fb32013-08-29 09:49:59959 case 7:
960 if (layer_tree_host()->settings().impl_side_painting) {
961 // With impl painting, the texture mailbox will still be on the impl
962 // thread when the commit finishes, because the layer is not around to
963 // block the commit on activation anymore. So, we wait for activation.
964 // TODO(danakj): fix this. crbug.com/277953
965 layer_tree_host()->SetNeedsCommit();
966 break;
967 } else {
968 ++commit_count_;
969 }
970 case 8:
[email protected]7096acc2013-06-18 21:12:43971 EXPECT_EQ(4, callback_count_);
972 // Resetting the mailbox will call the callback now.
[email protected]9260757f2013-09-17 01:24:16973 layer_->SetTextureMailbox(TextureMailbox(),
974 scoped_ptr<SingleReleaseCallback>());
[email protected]7096acc2013-06-18 21:12:43975 EXPECT_EQ(5, callback_count_);
[email protected]e216fef02013-03-20 22:56:10976 EndTest();
[email protected]28571b042013-03-14 07:59:15977 break;
978 default:
979 NOTREACHED();
980 break;
[email protected]de44a152013-01-08 15:28:46981 }
[email protected]28571b042013-03-14 07:59:15982 }
[email protected]de44a152013-01-08 15:28:46983
[email protected]e216fef02013-03-20 22:56:10984 virtual void AfterTest() OVERRIDE {}
[email protected]de44a152013-01-08 15:28:46985
[email protected]28571b042013-03-14 07:59:15986 private:
[email protected]9794fb32013-08-29 09:49:59987 base::ThreadChecker main_thread_;
[email protected]28571b042013-03-14 07:59:15988 int callback_count_;
989 int commit_count_;
990 scoped_refptr<Layer> root_;
991 scoped_refptr<TextureLayer> layer_;
[email protected]de44a152013-01-08 15:28:46992};
993
[email protected]4145d172013-05-10 16:54:36994SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
995 TextureLayerImplWithMailboxThreadedCallback);
[email protected]de44a152013-01-08 15:28:46996
[email protected]74b43cc2013-08-30 06:29:27997
998class TextureLayerNoMailboxIsActivatedDuringCommit : public LayerTreeTest,
999 public TextureLayerClient {
1000 protected:
1001 TextureLayerNoMailboxIsActivatedDuringCommit()
[email protected]98ea818e2014-01-24 10:22:081002 : texture_(0u), activate_count_(0) {}
[email protected]74b43cc2013-08-30 06:29:271003
1004 virtual void BeginTest() OVERRIDE {
[email protected]74b43cc2013-08-30 06:29:271005 gfx::Size bounds(100, 100);
1006 root_ = Layer::Create();
1007 root_->SetAnchorPoint(gfx::PointF());
1008 root_->SetBounds(bounds);
1009
1010 layer_ = TextureLayer::Create(this);
1011 layer_->SetIsDrawable(true);
1012 layer_->SetAnchorPoint(gfx::PointF());
1013 layer_->SetBounds(bounds);
1014
1015 root_->AddChild(layer_);
1016 layer_tree_host()->SetRootLayer(root_);
1017 layer_tree_host()->SetViewportSize(bounds);
1018
1019 PostSetNeedsCommitToMainThread();
1020 }
1021
[email protected]a6366932014-02-05 20:12:471022 virtual scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface(bool fallback)
[email protected]f5931d42013-11-06 19:44:571023 OVERRIDE {
1024 scoped_refptr<TestContextProvider> provider = TestContextProvider::Create();
1025 texture_ = provider->UnboundTestContext3d()->createExternalTexture();
[email protected]a6366932014-02-05 20:12:471026 return FakeOutputSurface::Create3d(provider);
[email protected]f5931d42013-11-06 19:44:571027 }
1028
[email protected]74b43cc2013-08-30 06:29:271029 // TextureLayerClient implementation.
1030 virtual unsigned PrepareTexture() OVERRIDE {
[email protected]f5931d42013-11-06 19:44:571031 return texture_;
[email protected]74b43cc2013-08-30 06:29:271032 }
[email protected]9260757f2013-09-17 01:24:161033 virtual bool PrepareTextureMailbox(
1034 TextureMailbox* mailbox,
1035 scoped_ptr<SingleReleaseCallback>* release_callback,
1036 bool use_shared_memory) OVERRIDE {
[email protected]74b43cc2013-08-30 06:29:271037 return false;
1038 }
1039
1040 virtual void WillActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
[email protected]74b43cc2013-08-30 06:29:271041 ++activate_count_;
1042 }
1043
[email protected]98ea818e2014-01-24 10:22:081044 virtual void DidCommit() OVERRIDE {
1045 switch (layer_tree_host()->source_frame_number()) {
[email protected]74b43cc2013-08-30 06:29:271046 case 1:
1047 // The first texture has been activated. Invalidate the layer so it
1048 // grabs a new texture id from the client.
1049 layer_->SetNeedsDisplay();
[email protected]74b43cc2013-08-30 06:29:271050 break;
1051 case 2:
1052 // The second mailbox has been activated. Remove the layer from
1053 // the tree to cause another commit/activation. The commit should
1054 // finish *after* the layer is removed from the active tree.
1055 layer_->RemoveFromParent();
[email protected]74b43cc2013-08-30 06:29:271056 break;
1057 case 3:
1058 EndTest();
1059 break;
1060 }
1061 }
1062
[email protected]98ea818e2014-01-24 10:22:081063 virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
1064 switch (host_impl->active_tree()->source_frame_number()) {
[email protected]74b43cc2013-08-30 06:29:271065 case 2: {
1066 // The activate for the 2nd texture should have happened before now.
[email protected]74b43cc2013-08-30 06:29:271067 EXPECT_EQ(2, activate_count_);
1068 break;
1069 }
1070 case 3: {
1071 // The activate to remove the layer should have happened before now.
[email protected]74b43cc2013-08-30 06:29:271072 EXPECT_EQ(3, activate_count_);
1073 break;
1074 }
1075 }
1076 }
1077
[email protected]74b43cc2013-08-30 06:29:271078 virtual void AfterTest() OVERRIDE {}
1079
[email protected]f5931d42013-11-06 19:44:571080 unsigned texture_;
[email protected]74b43cc2013-08-30 06:29:271081 int activate_count_;
[email protected]74b43cc2013-08-30 06:29:271082 scoped_refptr<Layer> root_;
1083 scoped_refptr<TextureLayer> layer_;
1084};
1085
1086SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
1087 TextureLayerNoMailboxIsActivatedDuringCommit);
1088
1089class TextureLayerMailboxIsActivatedDuringCommit : public LayerTreeTest {
1090 protected:
[email protected]98ea818e2014-01-24 10:22:081091 TextureLayerMailboxIsActivatedDuringCommit() : activate_count_(0) {}
[email protected]74b43cc2013-08-30 06:29:271092
[email protected]df41e252014-02-03 23:39:501093 static void ReleaseCallback(uint32 sync_point, bool lost_resource) {}
[email protected]74b43cc2013-08-30 06:29:271094
1095 void SetMailbox(char mailbox_char) {
[email protected]9260757f2013-09-17 01:24:161096 scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create(
[email protected]74b43cc2013-08-30 06:29:271097 base::Bind(
1098 &TextureLayerMailboxIsActivatedDuringCommit::ReleaseCallback));
[email protected]df41e252014-02-03 23:39:501099 layer_->SetTextureMailbox(
[email protected]e0a4d732014-02-15 00:23:261100 TextureMailbox(MailboxFromChar(mailbox_char), GL_TEXTURE_2D, 0),
[email protected]df41e252014-02-03 23:39:501101 callback.Pass());
[email protected]74b43cc2013-08-30 06:29:271102 }
1103
1104 virtual void BeginTest() OVERRIDE {
[email protected]74b43cc2013-08-30 06:29:271105 gfx::Size bounds(100, 100);
1106 root_ = Layer::Create();
1107 root_->SetAnchorPoint(gfx::PointF());
1108 root_->SetBounds(bounds);
1109
1110 layer_ = TextureLayer::CreateForMailbox(NULL);
1111 layer_->SetIsDrawable(true);
1112 layer_->SetAnchorPoint(gfx::PointF());
1113 layer_->SetBounds(bounds);
1114
1115 root_->AddChild(layer_);
1116 layer_tree_host()->SetRootLayer(root_);
1117 layer_tree_host()->SetViewportSize(bounds);
1118 SetMailbox('1');
1119
1120 PostSetNeedsCommitToMainThread();
1121 }
1122
1123 virtual void WillActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
[email protected]74b43cc2013-08-30 06:29:271124 ++activate_count_;
1125 }
1126
[email protected]98ea818e2014-01-24 10:22:081127 virtual void DidCommit() OVERRIDE {
1128 switch (layer_tree_host()->source_frame_number()) {
[email protected]74b43cc2013-08-30 06:29:271129 case 1:
1130 // The first mailbox has been activated. Set a new mailbox, and
1131 // expect the next commit to finish *after* it is activated.
1132 SetMailbox('2');
[email protected]74b43cc2013-08-30 06:29:271133 break;
1134 case 2:
1135 // The second mailbox has been activated. Remove the layer from
1136 // the tree to cause another commit/activation. The commit should
1137 // finish *after* the layer is removed from the active tree.
1138 layer_->RemoveFromParent();
[email protected]74b43cc2013-08-30 06:29:271139 break;
1140 case 3:
1141 EndTest();
1142 break;
1143 }
1144 }
1145
[email protected]98ea818e2014-01-24 10:22:081146 virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
1147 switch (host_impl->active_tree()->source_frame_number()) {
[email protected]74b43cc2013-08-30 06:29:271148 case 2: {
1149 // The activate for the 2nd mailbox should have happened before now.
[email protected]74b43cc2013-08-30 06:29:271150 EXPECT_EQ(2, activate_count_);
1151 break;
1152 }
1153 case 3: {
1154 // The activate to remove the layer should have happened before now.
[email protected]74b43cc2013-08-30 06:29:271155 EXPECT_EQ(3, activate_count_);
1156 break;
1157 }
1158 }
1159 }
1160
1161
1162 virtual void AfterTest() OVERRIDE {}
1163
[email protected]74b43cc2013-08-30 06:29:271164 int activate_count_;
1165 scoped_refptr<Layer> root_;
1166 scoped_refptr<TextureLayer> layer_;
1167};
1168
1169SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
1170 TextureLayerMailboxIsActivatedDuringCommit);
1171
[email protected]de44a152013-01-08 15:28:461172class TextureLayerImplWithMailboxTest : public TextureLayerTest {
[email protected]28571b042013-03-14 07:59:151173 protected:
[email protected]408b5e22013-03-19 09:48:091174 TextureLayerImplWithMailboxTest()
1175 : fake_client_(
1176 FakeLayerTreeHostClient(FakeLayerTreeHostClient::DIRECT_3D)) {}
1177
[email protected]28571b042013-03-14 07:59:151178 virtual void SetUp() {
1179 TextureLayerTest::SetUp();
[email protected]408b5e22013-03-19 09:48:091180 layer_tree_host_.reset(new MockLayerTreeHost(&fake_client_));
[email protected]a6366932014-02-05 20:12:471181 EXPECT_TRUE(host_impl_.InitializeRenderer(
1182 FakeOutputSurface::Create3d().PassAs<OutputSurface>()));
[email protected]28571b042013-03-14 07:59:151183 }
[email protected]de44a152013-01-08 15:28:461184
[email protected]0ec335c42013-07-04 06:17:081185 bool WillDraw(TextureLayerImpl* layer, DrawMode mode) {
1186 bool will_draw = layer->WillDraw(
1187 mode, host_impl_.active_tree()->resource_provider());
1188 if (will_draw)
1189 layer->DidDraw(host_impl_.active_tree()->resource_provider());
1190 return will_draw;
1191 }
1192
[email protected]28571b042013-03-14 07:59:151193 CommonMailboxObjects test_data_;
[email protected]408b5e22013-03-19 09:48:091194 FakeLayerTreeHostClient fake_client_;
[email protected]de44a152013-01-08 15:28:461195};
1196
[email protected]ffbb2212013-06-02 23:47:591197// Test conditions for results of TextureLayerImpl::WillDraw under
1198// different configurations of different mailbox, texture_id, and draw_mode.
1199TEST_F(TextureLayerImplWithMailboxTest, TestWillDraw) {
[email protected]0ec335c42013-07-04 06:17:081200 EXPECT_CALL(test_data_.mock_callback_,
1201 Release(test_data_.mailbox_name1_,
1202 test_data_.sync_point1_,
1203 false))
1204 .Times(AnyNumber());
1205 EXPECT_CALL(test_data_.mock_callback_,
1206 Release2(test_data_.shared_memory_.get(), 0, false))
1207 .Times(AnyNumber());
[email protected]ffbb2212013-06-02 23:47:591208 // Hardware mode.
1209 {
1210 scoped_ptr<TextureLayerImpl> impl_layer =
1211 TextureLayerImpl::Create(host_impl_.active_tree(), 1, true);
[email protected]afc4f262013-10-05 01:14:101212 impl_layer->SetDrawsContent(true);
[email protected]9260757f2013-09-17 01:24:161213 impl_layer->SetTextureMailbox(
1214 test_data_.mailbox1_,
1215 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
[email protected]0ec335c42013-07-04 06:17:081216 EXPECT_TRUE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE));
[email protected]ffbb2212013-06-02 23:47:591217 }
1218
1219 {
1220 scoped_ptr<TextureLayerImpl> impl_layer =
1221 TextureLayerImpl::Create(host_impl_.active_tree(), 1, true);
[email protected]afc4f262013-10-05 01:14:101222 impl_layer->SetDrawsContent(true);
[email protected]9260757f2013-09-17 01:24:161223 impl_layer->SetTextureMailbox(TextureMailbox(),
1224 scoped_ptr<SingleReleaseCallback>());
[email protected]0ec335c42013-07-04 06:17:081225 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE));
1226 }
1227
1228 {
1229 // Software resource.
1230 scoped_ptr<TextureLayerImpl> impl_layer =
1231 TextureLayerImpl::Create(host_impl_.active_tree(), 1, true);
[email protected]afc4f262013-10-05 01:14:101232 impl_layer->SetDrawsContent(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]3e44d7a2013-07-30 00:03:101236 EXPECT_TRUE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE));
[email protected]ffbb2212013-06-02 23:47:591237 }
1238
1239 {
1240 scoped_ptr<TextureLayerImpl> impl_layer =
1241 TextureLayerImpl::Create(host_impl_.active_tree(), 1, false);
[email protected]afc4f262013-10-05 01:14:101242 impl_layer->SetDrawsContent(true);
[email protected]0634cdd42013-08-16 00:46:091243 ContextProvider* context_provider =
1244 host_impl_.output_surface()->context_provider();
[email protected]1dff7962014-01-10 12:05:031245 GLuint texture = 0;
1246 context_provider->ContextGL()->GenTextures(1, &texture);
[email protected]ad0250b2014-01-18 03:24:341247 impl_layer->SetTextureId(texture);
[email protected]0ec335c42013-07-04 06:17:081248 EXPECT_TRUE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE));
[email protected]ffbb2212013-06-02 23:47:591249 }
1250
1251 {
1252 scoped_ptr<TextureLayerImpl> impl_layer =
1253 TextureLayerImpl::Create(host_impl_.active_tree(), 1, false);
[email protected]afc4f262013-10-05 01:14:101254 impl_layer->SetDrawsContent(true);
[email protected]ad0250b2014-01-18 03:24:341255 impl_layer->SetTextureId(0);
[email protected]0ec335c42013-07-04 06:17:081256 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE));
1257 }
1258
1259 // Software mode.
1260 {
1261 scoped_ptr<TextureLayerImpl> impl_layer =
1262 TextureLayerImpl::Create(host_impl_.active_tree(), 1, true);
[email protected]afc4f262013-10-05 01:14:101263 impl_layer->SetDrawsContent(true);
[email protected]9260757f2013-09-17 01:24:161264 impl_layer->SetTextureMailbox(
1265 test_data_.mailbox1_,
1266 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
[email protected]0ec335c42013-07-04 06:17:081267 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE));
1268 }
1269
1270 {
1271 scoped_ptr<TextureLayerImpl> impl_layer =
1272 TextureLayerImpl::Create(host_impl_.active_tree(), 1, true);
[email protected]afc4f262013-10-05 01:14:101273 impl_layer->SetDrawsContent(true);
[email protected]9260757f2013-09-17 01:24:161274 impl_layer->SetTextureMailbox(TextureMailbox(),
1275 scoped_ptr<SingleReleaseCallback>());
[email protected]0ec335c42013-07-04 06:17:081276 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE));
1277 }
1278
1279 {
1280 // Software resource.
1281 scoped_ptr<TextureLayerImpl> impl_layer =
1282 TextureLayerImpl::Create(host_impl_.active_tree(), 1, true);
[email protected]afc4f262013-10-05 01:14:101283 impl_layer->SetDrawsContent(true);
[email protected]9260757f2013-09-17 01:24:161284 impl_layer->SetTextureMailbox(
1285 test_data_.mailbox3_,
1286 SingleReleaseCallback::Create(test_data_.release_mailbox3_));
[email protected]0ec335c42013-07-04 06:17:081287 EXPECT_TRUE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE));
1288 }
1289
1290 {
1291 scoped_ptr<TextureLayerImpl> impl_layer =
1292 TextureLayerImpl::Create(host_impl_.active_tree(), 1, false);
[email protected]afc4f262013-10-05 01:14:101293 impl_layer->SetDrawsContent(true);
[email protected]0634cdd42013-08-16 00:46:091294 ContextProvider* context_provider =
1295 host_impl_.output_surface()->context_provider();
[email protected]1dff7962014-01-10 12:05:031296 GLuint texture = 0;
1297 context_provider->ContextGL()->GenTextures(1, &texture);
[email protected]ad0250b2014-01-18 03:24:341298 impl_layer->SetTextureId(texture);
[email protected]0ec335c42013-07-04 06:17:081299 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE));
1300 }
1301
1302 {
1303 scoped_ptr<TextureLayerImpl> impl_layer =
1304 TextureLayerImpl::Create(host_impl_.active_tree(), 1, false);
[email protected]afc4f262013-10-05 01:14:101305 impl_layer->SetDrawsContent(true);
[email protected]ad0250b2014-01-18 03:24:341306 impl_layer->SetTextureId(0);
[email protected]0ec335c42013-07-04 06:17:081307 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE));
[email protected]ffbb2212013-06-02 23:47:591308 }
1309
1310 // Resourceless software mode.
1311 {
1312 scoped_ptr<TextureLayerImpl> impl_layer =
1313 TextureLayerImpl::Create(host_impl_.active_tree(), 1, true);
[email protected]afc4f262013-10-05 01:14:101314 impl_layer->SetDrawsContent(true);
[email protected]9260757f2013-09-17 01:24:161315 impl_layer->SetTextureMailbox(
1316 test_data_.mailbox1_,
1317 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
[email protected]0ec335c42013-07-04 06:17:081318 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_RESOURCELESS_SOFTWARE));
[email protected]ffbb2212013-06-02 23:47:591319 }
1320
1321 {
1322 scoped_ptr<TextureLayerImpl> impl_layer =
1323 TextureLayerImpl::Create(host_impl_.active_tree(), 1, false);
[email protected]afc4f262013-10-05 01:14:101324 impl_layer->SetDrawsContent(true);
[email protected]0634cdd42013-08-16 00:46:091325 ContextProvider* context_provider =
1326 host_impl_.output_surface()->context_provider();
[email protected]1dff7962014-01-10 12:05:031327 GLuint texture = 0;
1328 context_provider->ContextGL()->GenTextures(1, &texture);
[email protected]ad0250b2014-01-18 03:24:341329 impl_layer->SetTextureId(texture);
[email protected]0ec335c42013-07-04 06:17:081330 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_RESOURCELESS_SOFTWARE));
[email protected]ffbb2212013-06-02 23:47:591331 }
1332}
1333
[email protected]28571b042013-03-14 07:59:151334TEST_F(TextureLayerImplWithMailboxTest, TestImplLayerCallbacks) {
1335 host_impl_.CreatePendingTree();
1336 scoped_ptr<TextureLayerImpl> pending_layer;
1337 pending_layer = TextureLayerImpl::Create(host_impl_.pending_tree(), 1, true);
1338 ASSERT_TRUE(pending_layer);
[email protected]de44a152013-01-08 15:28:461339
[email protected]ed511b8d2013-03-25 03:29:291340 scoped_ptr<LayerImpl> active_layer(
[email protected]28571b042013-03-14 07:59:151341 pending_layer->CreateLayerImpl(host_impl_.active_tree()));
[email protected]ed511b8d2013-03-25 03:29:291342 ASSERT_TRUE(active_layer);
[email protected]de44a152013-01-08 15:28:461343
[email protected]9260757f2013-09-17 01:24:161344 pending_layer->SetTextureMailbox(
1345 test_data_.mailbox1_,
1346 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
[email protected]421e84f2013-02-22 03:27:151347
[email protected]28571b042013-03-14 07:59:151348 // Test multiple commits without an activation.
1349 EXPECT_CALL(test_data_.mock_callback_,
[email protected]7ba3ca72013-04-11 06:37:251350 Release(test_data_.mailbox_name1_,
1351 test_data_.sync_point1_,
1352 false))
[email protected]28571b042013-03-14 07:59:151353 .Times(1);
[email protected]9260757f2013-09-17 01:24:161354 pending_layer->SetTextureMailbox(
1355 test_data_.mailbox2_,
1356 SingleReleaseCallback::Create(test_data_.release_mailbox2_));
[email protected]28571b042013-03-14 07:59:151357 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]421e84f2013-02-22 03:27:151358
[email protected]28571b042013-03-14 07:59:151359 // Test callback after activation.
[email protected]ed511b8d2013-03-25 03:29:291360 pending_layer->PushPropertiesTo(active_layer.get());
1361 active_layer->DidBecomeActive();
[email protected]421e84f2013-02-22 03:27:151362
[email protected]7ba3ca72013-04-11 06:37:251363 EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0);
[email protected]9260757f2013-09-17 01:24:161364 pending_layer->SetTextureMailbox(
1365 test_data_.mailbox1_,
1366 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
[email protected]28571b042013-03-14 07:59:151367 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]421e84f2013-02-22 03:27:151368
[email protected]7ba3ca72013-04-11 06:37:251369 EXPECT_CALL(test_data_.mock_callback_,
1370 Release(test_data_.mailbox_name2_, _, false))
[email protected]28571b042013-03-14 07:59:151371 .Times(1);
[email protected]ed511b8d2013-03-25 03:29:291372 pending_layer->PushPropertiesTo(active_layer.get());
1373 active_layer->DidBecomeActive();
[email protected]28571b042013-03-14 07:59:151374 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]de44a152013-01-08 15:28:461375
[email protected]28571b042013-03-14 07:59:151376 // Test resetting the mailbox.
[email protected]7ba3ca72013-04-11 06:37:251377 EXPECT_CALL(test_data_.mock_callback_,
1378 Release(test_data_.mailbox_name1_, _, false))
[email protected]28571b042013-03-14 07:59:151379 .Times(1);
[email protected]9260757f2013-09-17 01:24:161380 pending_layer->SetTextureMailbox(TextureMailbox(),
1381 scoped_ptr<SingleReleaseCallback>());
[email protected]ed511b8d2013-03-25 03:29:291382 pending_layer->PushPropertiesTo(active_layer.get());
1383 active_layer->DidBecomeActive();
[email protected]28571b042013-03-14 07:59:151384 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]de44a152013-01-08 15:28:461385
[email protected]28571b042013-03-14 07:59:151386 // Test destructor.
1387 EXPECT_CALL(test_data_.mock_callback_,
[email protected]7ba3ca72013-04-11 06:37:251388 Release(test_data_.mailbox_name1_,
1389 test_data_.sync_point1_,
1390 false))
[email protected]28571b042013-03-14 07:59:151391 .Times(1);
[email protected]9260757f2013-09-17 01:24:161392 pending_layer->SetTextureMailbox(
1393 test_data_.mailbox1_,
1394 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
[email protected]de44a152013-01-08 15:28:461395}
1396
[email protected]28571b042013-03-14 07:59:151397TEST_F(TextureLayerImplWithMailboxTest,
1398 TestDestructorCallbackOnCreatedResource) {
1399 scoped_ptr<TextureLayerImpl> impl_layer;
1400 impl_layer = TextureLayerImpl::Create(host_impl_.active_tree(), 1, true);
1401 ASSERT_TRUE(impl_layer);
[email protected]de44a152013-01-08 15:28:461402
[email protected]7ba3ca72013-04-11 06:37:251403 EXPECT_CALL(test_data_.mock_callback_,
1404 Release(test_data_.mailbox_name1_, _, false))
[email protected]28571b042013-03-14 07:59:151405 .Times(1);
[email protected]9260757f2013-09-17 01:24:161406 impl_layer->SetTextureMailbox(
1407 test_data_.mailbox1_,
1408 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
[email protected]afc4f262013-10-05 01:14:101409 impl_layer->SetDrawsContent(true);
[email protected]ffbb2212013-06-02 23:47:591410 impl_layer->DidBecomeActive();
1411 EXPECT_TRUE(impl_layer->WillDraw(
1412 DRAW_MODE_HARDWARE, host_impl_.active_tree()->resource_provider()));
[email protected]28571b042013-03-14 07:59:151413 impl_layer->DidDraw(host_impl_.active_tree()->resource_provider());
[email protected]9260757f2013-09-17 01:24:161414 impl_layer->SetTextureMailbox(TextureMailbox(),
1415 scoped_ptr<SingleReleaseCallback>());
[email protected]de44a152013-01-08 15:28:461416}
1417
[email protected]28571b042013-03-14 07:59:151418TEST_F(TextureLayerImplWithMailboxTest, TestCallbackOnInUseResource) {
1419 ResourceProvider* provider = host_impl_.active_tree()->resource_provider();
1420 ResourceProvider::ResourceId id =
[email protected]9260757f2013-09-17 01:24:161421 provider->CreateResourceFromTextureMailbox(
1422 test_data_.mailbox1_,
1423 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
[email protected]28571b042013-03-14 07:59:151424 provider->AllocateForTesting(id);
[email protected]de44a152013-01-08 15:28:461425
[email protected]28571b042013-03-14 07:59:151426 // Transfer some resources to the parent.
1427 ResourceProvider::ResourceIdArray resource_ids_to_transfer;
1428 resource_ids_to_transfer.push_back(id);
1429 TransferableResourceArray list;
1430 provider->PrepareSendToParent(resource_ids_to_transfer, &list);
1431 EXPECT_TRUE(provider->InUseByConsumer(id));
[email protected]7ba3ca72013-04-11 06:37:251432 EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0);
[email protected]28571b042013-03-14 07:59:151433 provider->DeleteResource(id);
1434 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]7ba3ca72013-04-11 06:37:251435 EXPECT_CALL(test_data_.mock_callback_,
1436 Release(test_data_.mailbox_name1_, _, false))
[email protected]28571b042013-03-14 07:59:151437 .Times(1);
[email protected]e00bab022013-08-19 00:42:451438 ReturnedResourceArray returned;
1439 TransferableResource::ReturnResources(list, &returned);
1440 provider->ReceiveReturnsFromParent(returned);
[email protected]de44a152013-01-08 15:28:461441}
1442
[email protected]97d519fb2013-03-29 02:27:541443// Check that ClearClient correctly clears the state so that the impl side
1444// doesn't try to use a texture that could have been destroyed.
[email protected]7ba3ca72013-04-11 06:37:251445class TextureLayerClientTest
1446 : public LayerTreeTest,
1447 public TextureLayerClient {
[email protected]97d519fb2013-03-29 02:27:541448 public:
1449 TextureLayerClientTest()
[email protected]f5931d42013-11-06 19:44:571450 : texture_(0),
[email protected]97d519fb2013-03-29 02:27:541451 commit_count_(0),
1452 expected_used_textures_on_draw_(0),
1453 expected_used_textures_on_commit_(0) {}
1454
[email protected]a6366932014-02-05 20:12:471455 virtual scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface(bool fallback)
[email protected]ebc0e1df2013-08-01 02:46:221456 OVERRIDE {
[email protected]f5931d42013-11-06 19:44:571457 scoped_refptr<TestContextProvider> provider = TestContextProvider::Create();
1458 texture_ = provider->UnboundTestContext3d()->createExternalTexture();
[email protected]a6366932014-02-05 20:12:471459 return FakeOutputSurface::Create3d(provider);
[email protected]97d519fb2013-03-29 02:27:541460 }
1461
[email protected]f5931d42013-11-06 19:44:571462 virtual unsigned PrepareTexture() OVERRIDE { return texture_; }
[email protected]97d519fb2013-03-29 02:27:541463
[email protected]2541d1a2013-07-10 07:33:271464 virtual bool PrepareTextureMailbox(
[email protected]9260757f2013-09-17 01:24:161465 TextureMailbox* mailbox,
1466 scoped_ptr<SingleReleaseCallback>* release_callback,
1467 bool use_shared_memory) OVERRIDE {
[email protected]e8e4ae232013-04-12 00:26:011468 return false;
1469 }
1470
[email protected]97d519fb2013-03-29 02:27:541471 virtual void SetupTree() OVERRIDE {
1472 scoped_refptr<Layer> root = Layer::Create();
1473 root->SetBounds(gfx::Size(10, 10));
1474 root->SetAnchorPoint(gfx::PointF());
1475 root->SetIsDrawable(true);
1476
1477 texture_layer_ = TextureLayer::Create(this);
1478 texture_layer_->SetBounds(gfx::Size(10, 10));
1479 texture_layer_->SetAnchorPoint(gfx::PointF());
1480 texture_layer_->SetIsDrawable(true);
1481 root->AddChild(texture_layer_);
1482
1483 layer_tree_host()->SetRootLayer(root);
1484 LayerTreeTest::SetupTree();
1485 {
1486 base::AutoLock lock(lock_);
1487 expected_used_textures_on_commit_ = 1;
1488 }
1489 }
1490
1491 virtual void BeginTest() OVERRIDE {
1492 PostSetNeedsCommitToMainThread();
1493 }
1494
1495 virtual void DidCommitAndDrawFrame() OVERRIDE {
1496 ++commit_count_;
1497 switch (commit_count_) {
1498 case 1:
1499 texture_layer_->ClearClient();
1500 texture_layer_->SetNeedsDisplay();
1501 {
1502 base::AutoLock lock(lock_);
1503 expected_used_textures_on_commit_ = 0;
1504 }
[email protected]97d519fb2013-03-29 02:27:541505 break;
1506 case 2:
1507 EndTest();
1508 break;
1509 default:
1510 NOTREACHED();
1511 break;
1512 }
1513 }
1514
1515 virtual void BeginCommitOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
1516 base::AutoLock lock(lock_);
1517 expected_used_textures_on_draw_ = expected_used_textures_on_commit_;
1518 }
1519
[email protected]7ddfe7e82014-01-30 07:22:111520 virtual DrawSwapReadbackResult::DrawResult PrepareToDrawOnThread(
1521 LayerTreeHostImpl* host_impl,
1522 LayerTreeHostImpl::FrameData* frame_data,
1523 DrawSwapReadbackResult::DrawResult draw_result) OVERRIDE {
[email protected]f5931d42013-11-06 19:44:571524 ContextForImplThread(host_impl)->ResetUsedTextures();
[email protected]7ddfe7e82014-01-30 07:22:111525 return DrawSwapReadbackResult::DRAW_SUCCESS;
[email protected]97d519fb2013-03-29 02:27:541526 }
1527
1528 virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl,
1529 bool result) OVERRIDE {
1530 ASSERT_TRUE(result);
[email protected]f5931d42013-11-06 19:44:571531 EXPECT_EQ(expected_used_textures_on_draw_,
1532 ContextForImplThread(host_impl)->NumUsedTextures());
[email protected]97d519fb2013-03-29 02:27:541533 }
1534
1535 virtual void AfterTest() OVERRIDE {}
1536
1537 private:
[email protected]f5931d42013-11-06 19:44:571538 TestWebGraphicsContext3D* ContextForImplThread(LayerTreeHostImpl* host_impl) {
[email protected]1dff7962014-01-10 12:05:031539 return static_cast<TestContextProvider*>(
1540 host_impl->output_surface()->context_provider().get())->TestContext3d();
[email protected]f5931d42013-11-06 19:44:571541 }
1542
[email protected]97d519fb2013-03-29 02:27:541543 scoped_refptr<TextureLayer> texture_layer_;
[email protected]97d519fb2013-03-29 02:27:541544 unsigned texture_;
1545 int commit_count_;
1546
1547 // Used only on thread.
1548 unsigned expected_used_textures_on_draw_;
1549
1550 // Used on either thread, protected by lock_.
1551 base::Lock lock_;
1552 unsigned expected_used_textures_on_commit_;
1553};
1554
[email protected]4145d172013-05-10 16:54:361555// The TextureLayerClient does not use mailboxes, so can't use a delegating
1556// renderer.
1557SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(TextureLayerClientTest);
[email protected]97d519fb2013-03-29 02:27:541558
[email protected]b04264f92013-09-13 23:37:291559
1560// Checks that changing a texture in the client for a TextureLayer that's
1561// invisible correctly works without drawing a deleted texture. See
1562// crbug.com/266628
1563class TextureLayerChangeInvisibleTest
1564 : public LayerTreeTest,
1565 public TextureLayerClient {
1566 public:
1567 TextureLayerChangeInvisibleTest()
[email protected]f5931d42013-11-06 19:44:571568 : texture_(0u),
[email protected]b04264f92013-09-13 23:37:291569 prepare_called_(0),
1570 commit_count_(0),
1571 expected_texture_on_draw_(0) {}
1572
[email protected]a6366932014-02-05 20:12:471573 virtual scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface(bool fallback)
[email protected]f5931d42013-11-06 19:44:571574 OVERRIDE {
1575 scoped_refptr<TestContextProvider> provider = TestContextProvider::Create();
1576 texture_ = provider->UnboundTestContext3d()->createExternalTexture();
[email protected]a6366932014-02-05 20:12:471577 return FakeOutputSurface::Create3d(provider);
[email protected]f5931d42013-11-06 19:44:571578 }
1579
[email protected]b04264f92013-09-13 23:37:291580 // TextureLayerClient implementation.
1581 virtual unsigned PrepareTexture() OVERRIDE {
1582 ++prepare_called_;
1583 return texture_;
1584 }
[email protected]b04264f92013-09-13 23:37:291585 virtual bool PrepareTextureMailbox(
[email protected]e51444a2013-12-10 23:05:011586 TextureMailbox* mailbox,
[email protected]9260757f2013-09-17 01:24:161587 scoped_ptr<SingleReleaseCallback>* release_callback,
1588 bool use_shared_memory) OVERRIDE {
[email protected]b04264f92013-09-13 23:37:291589 return false;
1590 }
1591
1592 virtual void SetupTree() OVERRIDE {
1593 scoped_refptr<Layer> root = Layer::Create();
1594 root->SetBounds(gfx::Size(10, 10));
1595 root->SetAnchorPoint(gfx::PointF());
1596 root->SetIsDrawable(true);
1597
1598 solid_layer_ = SolidColorLayer::Create();
1599 solid_layer_->SetBounds(gfx::Size(10, 10));
1600 solid_layer_->SetIsDrawable(true);
1601 solid_layer_->SetBackgroundColor(SK_ColorWHITE);
1602 root->AddChild(solid_layer_);
1603
1604 parent_layer_ = Layer::Create();
1605 parent_layer_->SetBounds(gfx::Size(10, 10));
1606 parent_layer_->SetIsDrawable(true);
1607 root->AddChild(parent_layer_);
1608
1609 texture_layer_ = TextureLayer::Create(this);
1610 texture_layer_->SetBounds(gfx::Size(10, 10));
1611 texture_layer_->SetAnchorPoint(gfx::PointF());
1612 texture_layer_->SetIsDrawable(true);
1613 parent_layer_->AddChild(texture_layer_);
1614
1615 layer_tree_host()->SetRootLayer(root);
1616 LayerTreeTest::SetupTree();
1617 }
1618
1619 virtual void BeginTest() OVERRIDE {
1620 PostSetNeedsCommitToMainThread();
1621 }
1622
1623 virtual void DidCommitAndDrawFrame() OVERRIDE {
1624 ++commit_count_;
1625 switch (commit_count_) {
1626 case 1:
1627 // We should have updated the layer, committing the texture.
1628 EXPECT_EQ(1, prepare_called_);
1629 // Make layer invisible.
1630 parent_layer_->SetOpacity(0.f);
1631 break;
1632 case 2: {
1633 // Layer shouldn't have been updated.
1634 EXPECT_EQ(1, prepare_called_);
[email protected]b04264f92013-09-13 23:37:291635 texture_layer_->SetNeedsDisplay();
1636 // Force a change to make sure we draw a frame.
1637 solid_layer_->SetBackgroundColor(SK_ColorGRAY);
1638 break;
1639 }
1640 case 3:
1641 EXPECT_EQ(1, prepare_called_);
[email protected]b04264f92013-09-13 23:37:291642 // Make layer visible again.
1643 parent_layer_->SetOpacity(1.f);
1644 break;
1645 case 4: {
1646 // Layer should have been updated.
1647 EXPECT_EQ(2, prepare_called_);
1648 texture_layer_->ClearClient();
[email protected]b04264f92013-09-13 23:37:291649 texture_ = 0;
1650 break;
1651 }
1652 case 5:
1653 EndTest();
1654 break;
1655 default:
1656 NOTREACHED();
1657 break;
1658 }
1659 }
1660
1661 virtual void BeginCommitOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
1662 ASSERT_TRUE(proxy()->IsMainThreadBlocked());
1663 // This is the only texture that can be drawn this frame.
1664 expected_texture_on_draw_ = texture_;
1665 }
1666
[email protected]7ddfe7e82014-01-30 07:22:111667 virtual DrawSwapReadbackResult::DrawResult PrepareToDrawOnThread(
1668 LayerTreeHostImpl* host_impl,
1669 LayerTreeHostImpl::FrameData* frame_data,
1670 DrawSwapReadbackResult::DrawResult draw_result) OVERRIDE {
[email protected]b04264f92013-09-13 23:37:291671 ContextForImplThread(host_impl)->ResetUsedTextures();
[email protected]7ddfe7e82014-01-30 07:22:111672 return DrawSwapReadbackResult::DRAW_SUCCESS;
[email protected]b04264f92013-09-13 23:37:291673 }
1674
1675 virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl,
1676 bool result) OVERRIDE {
1677 ASSERT_TRUE(result);
1678 TestWebGraphicsContext3D* context = ContextForImplThread(host_impl);
1679 int used_textures = context->NumUsedTextures();
1680 switch (host_impl->active_tree()->source_frame_number()) {
1681 case 0:
1682 EXPECT_EQ(1, used_textures);
1683 EXPECT_TRUE(context->UsedTexture(expected_texture_on_draw_));
1684 break;
1685 case 1:
1686 case 2:
1687 EXPECT_EQ(0, used_textures);
1688 break;
1689 case 3:
1690 EXPECT_EQ(1, used_textures);
1691 EXPECT_TRUE(context->UsedTexture(expected_texture_on_draw_));
1692 break;
1693 default:
1694 break;
1695 }
1696 }
1697
1698 virtual void AfterTest() OVERRIDE {}
1699
1700 private:
1701 TestWebGraphicsContext3D* ContextForImplThread(LayerTreeHostImpl* host_impl) {
[email protected]1dff7962014-01-10 12:05:031702 return static_cast<TestContextProvider*>(
1703 host_impl->output_surface()->context_provider().get())->TestContext3d();
[email protected]b04264f92013-09-13 23:37:291704 }
1705
1706 scoped_refptr<SolidColorLayer> solid_layer_;
1707 scoped_refptr<Layer> parent_layer_;
1708 scoped_refptr<TextureLayer> texture_layer_;
[email protected]b04264f92013-09-13 23:37:291709
1710 // Used on the main thread, and on the impl thread while the main thread is
1711 // blocked.
1712 unsigned texture_;
1713
1714 // Used on the main thread.
[email protected]b04264f92013-09-13 23:37:291715 int prepare_called_;
1716 int commit_count_;
1717
1718 // Used on the compositor thread.
1719 unsigned expected_texture_on_draw_;
1720};
1721
1722// The TextureLayerChangeInvisibleTest does not use mailboxes, so can't use a
1723// delegating renderer.
1724SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(TextureLayerChangeInvisibleTest);
1725
[email protected]4bad8b62013-10-24 01:27:291726// Checks that TextureLayer::Update does not cause an extra commit when setting
1727// the texture mailbox.
1728class TextureLayerNoExtraCommitForMailboxTest
1729 : public LayerTreeTest,
1730 public TextureLayerClient {
1731 public:
[email protected]4bad8b62013-10-24 01:27:291732 // TextureLayerClient implementation.
1733 virtual unsigned PrepareTexture() OVERRIDE {
1734 NOTREACHED();
1735 return 0;
1736 }
[email protected]4bad8b62013-10-24 01:27:291737 virtual bool PrepareTextureMailbox(
[email protected]df41e252014-02-03 23:39:501738 TextureMailbox* texture_mailbox,
[email protected]4bad8b62013-10-24 01:27:291739 scoped_ptr<SingleReleaseCallback>* release_callback,
1740 bool use_shared_memory) OVERRIDE {
[email protected]cce34bd2013-12-02 23:24:451741 if (layer_tree_host()->source_frame_number() == 1) {
[email protected]df41e252014-02-03 23:39:501742 *texture_mailbox = TextureMailbox();
[email protected]cce34bd2013-12-02 23:24:451743 return true;
1744 }
[email protected]4bad8b62013-10-24 01:27:291745
[email protected]e0a4d732014-02-15 00:23:261746 *texture_mailbox = TextureMailbox(MailboxFromChar('1'), GL_TEXTURE_2D, 0);
[email protected]4bad8b62013-10-24 01:27:291747 *release_callback = SingleReleaseCallback::Create(
1748 base::Bind(&TextureLayerNoExtraCommitForMailboxTest::MailboxReleased,
1749 base::Unretained(this)));
[email protected]4bad8b62013-10-24 01:27:291750 return true;
1751 }
1752
[email protected]df41e252014-02-03 23:39:501753 void MailboxReleased(uint32 sync_point, bool lost_resource) {
[email protected]cce34bd2013-12-02 23:24:451754 EXPECT_EQ(2, layer_tree_host()->source_frame_number());
1755 EndTest();
[email protected]4bad8b62013-10-24 01:27:291756 }
1757
1758 virtual void SetupTree() OVERRIDE {
1759 scoped_refptr<Layer> root = Layer::Create();
1760 root->SetBounds(gfx::Size(10, 10));
1761 root->SetAnchorPoint(gfx::PointF());
1762 root->SetIsDrawable(true);
1763
[email protected]4bad8b62013-10-24 01:27:291764 texture_layer_ = TextureLayer::CreateForMailbox(this);
1765 texture_layer_->SetBounds(gfx::Size(10, 10));
1766 texture_layer_->SetAnchorPoint(gfx::PointF());
1767 texture_layer_->SetIsDrawable(true);
[email protected]0d7fb302014-01-23 21:30:471768 root->AddChild(texture_layer_);
[email protected]4bad8b62013-10-24 01:27:291769
1770 layer_tree_host()->SetRootLayer(root);
1771 LayerTreeTest::SetupTree();
1772 }
1773
1774 virtual void BeginTest() OVERRIDE {
1775 PostSetNeedsCommitToMainThread();
1776 }
1777
[email protected]cce34bd2013-12-02 23:24:451778 virtual void DidCommitAndDrawFrame() OVERRIDE {
[email protected]4bad8b62013-10-24 01:27:291779 switch (layer_tree_host()->source_frame_number()) {
1780 case 1:
[email protected]cce34bd2013-12-02 23:24:451781 EXPECT_FALSE(proxy()->CommitPendingForTesting());
1782 // Invalidate the texture layer to clear the mailbox before
1783 // ending the test.
1784 texture_layer_->SetNeedsDisplay();
1785 break;
1786 case 2:
[email protected]4bad8b62013-10-24 01:27:291787 break;
1788 default:
1789 NOTREACHED();
1790 break;
1791 }
1792 }
1793
[email protected]cce34bd2013-12-02 23:24:451794 virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl,
1795 bool result) OVERRIDE {
1796 ASSERT_TRUE(result);
1797 DelegatedFrameData* delegated_frame_data =
1798 output_surface()->last_sent_frame().delegated_frame_data.get();
1799 if (!delegated_frame_data)
1800 return;
1801
1802 // Return all resources immediately.
1803 TransferableResourceArray resources_to_return =
1804 output_surface()->resources_held_by_parent();
1805
1806 CompositorFrameAck ack;
1807 for (size_t i = 0; i < resources_to_return.size(); ++i)
1808 output_surface()->ReturnResource(resources_to_return[i].id, &ack);
1809 host_impl->ReclaimResources(&ack);
1810 host_impl->OnSwapBuffersComplete();
1811 }
1812
[email protected]4bad8b62013-10-24 01:27:291813 virtual void AfterTest() OVERRIDE {}
1814
1815 private:
[email protected]4bad8b62013-10-24 01:27:291816 scoped_refptr<TextureLayer> texture_layer_;
[email protected]4bad8b62013-10-24 01:27:291817};
1818
[email protected]cce34bd2013-12-02 23:24:451819SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerNoExtraCommitForMailboxTest);
[email protected]4bad8b62013-10-24 01:27:291820
[email protected]b04264f92013-09-13 23:37:291821// Checks that changing a mailbox in the client for a TextureLayer that's
1822// invisible correctly works and uses the new mailbox as soon as the layer
1823// becomes visible (and returns the old one).
1824class TextureLayerChangeInvisibleMailboxTest
1825 : public LayerTreeTest,
1826 public TextureLayerClient {
1827 public:
1828 TextureLayerChangeInvisibleMailboxTest()
1829 : mailbox_changed_(true),
1830 mailbox_returned_(0),
1831 prepare_called_(0),
1832 commit_count_(0) {
1833 mailbox_ = MakeMailbox('1');
1834 }
1835
1836 // TextureLayerClient implementation.
1837 virtual unsigned PrepareTexture() OVERRIDE {
1838 NOTREACHED();
1839 return 0;
1840 }
1841
[email protected]b04264f92013-09-13 23:37:291842 virtual bool PrepareTextureMailbox(
[email protected]e51444a2013-12-10 23:05:011843 TextureMailbox* mailbox,
[email protected]9260757f2013-09-17 01:24:161844 scoped_ptr<SingleReleaseCallback>* release_callback,
1845 bool use_shared_memory) OVERRIDE {
[email protected]b04264f92013-09-13 23:37:291846 ++prepare_called_;
1847 if (!mailbox_changed_)
1848 return false;
1849 *mailbox = mailbox_;
[email protected]9260757f2013-09-17 01:24:161850 *release_callback = SingleReleaseCallback::Create(
1851 base::Bind(&TextureLayerChangeInvisibleMailboxTest::MailboxReleased,
1852 base::Unretained(this)));
[email protected]b04264f92013-09-13 23:37:291853 return true;
1854 }
1855
1856 TextureMailbox MakeMailbox(char name) {
[email protected]e0a4d732014-02-15 00:23:261857 return TextureMailbox(MailboxFromChar(name), GL_TEXTURE_2D, 0);
[email protected]b04264f92013-09-13 23:37:291858 }
1859
[email protected]df41e252014-02-03 23:39:501860 void MailboxReleased(uint32 sync_point, bool lost_resource) {
[email protected]b04264f92013-09-13 23:37:291861 ++mailbox_returned_;
1862 }
1863
1864 virtual void SetupTree() OVERRIDE {
1865 scoped_refptr<Layer> root = Layer::Create();
1866 root->SetBounds(gfx::Size(10, 10));
1867 root->SetAnchorPoint(gfx::PointF());
1868 root->SetIsDrawable(true);
1869
1870 solid_layer_ = SolidColorLayer::Create();
1871 solid_layer_->SetBounds(gfx::Size(10, 10));
1872 solid_layer_->SetIsDrawable(true);
1873 solid_layer_->SetBackgroundColor(SK_ColorWHITE);
1874 root->AddChild(solid_layer_);
1875
1876 parent_layer_ = Layer::Create();
1877 parent_layer_->SetBounds(gfx::Size(10, 10));
1878 parent_layer_->SetIsDrawable(true);
1879 root->AddChild(parent_layer_);
1880
1881 texture_layer_ = TextureLayer::CreateForMailbox(this);
1882 texture_layer_->SetBounds(gfx::Size(10, 10));
1883 texture_layer_->SetAnchorPoint(gfx::PointF());
1884 texture_layer_->SetIsDrawable(true);
1885 parent_layer_->AddChild(texture_layer_);
1886
1887 layer_tree_host()->SetRootLayer(root);
1888 LayerTreeTest::SetupTree();
1889 }
1890
1891 virtual void BeginTest() OVERRIDE {
1892 PostSetNeedsCommitToMainThread();
1893 }
1894
1895 virtual void DidCommitAndDrawFrame() OVERRIDE {
1896 ++commit_count_;
1897 switch (commit_count_) {
1898 case 1:
1899 // We should have updated the layer, committing the texture.
1900 EXPECT_EQ(1, prepare_called_);
1901 // Make layer invisible.
1902 parent_layer_->SetOpacity(0.f);
1903 break;
1904 case 2:
1905 // Layer shouldn't have been updated.
1906 EXPECT_EQ(1, prepare_called_);
1907 // Change the texture.
1908 mailbox_ = MakeMailbox('2');
1909 mailbox_changed_ = true;
1910 texture_layer_->SetNeedsDisplay();
1911 // Force a change to make sure we draw a frame.
1912 solid_layer_->SetBackgroundColor(SK_ColorGRAY);
1913 break;
1914 case 3:
1915 // Layer shouldn't have been updated.
1916 EXPECT_EQ(1, prepare_called_);
1917 // So the old mailbox isn't returned yet.
1918 EXPECT_EQ(0, mailbox_returned_);
1919 // Make layer visible again.
1920 parent_layer_->SetOpacity(1.f);
1921 break;
1922 case 4:
1923 // Layer should have been updated.
1924 EXPECT_EQ(2, prepare_called_);
1925 // So the old mailbox should have been returned already.
1926 EXPECT_EQ(1, mailbox_returned_);
1927 texture_layer_->ClearClient();
1928 break;
1929 case 5:
1930 EXPECT_EQ(2, mailbox_returned_);
1931 EndTest();
1932 break;
1933 default:
1934 NOTREACHED();
1935 break;
1936 }
1937 }
1938
1939 virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl,
1940 bool result) OVERRIDE {
1941 ASSERT_TRUE(result);
1942 DelegatedFrameData* delegated_frame_data =
1943 output_surface()->last_sent_frame().delegated_frame_data.get();
1944 if (!delegated_frame_data)
1945 return;
1946
1947 // Return all resources immediately.
1948 TransferableResourceArray resources_to_return =
1949 output_surface()->resources_held_by_parent();
1950
1951 CompositorFrameAck ack;
1952 for (size_t i = 0; i < resources_to_return.size(); ++i)
1953 output_surface()->ReturnResource(resources_to_return[i].id, &ack);
[email protected]a7335e0b2013-09-18 09:34:511954 host_impl->ReclaimResources(&ack);
1955 host_impl->OnSwapBuffersComplete();
[email protected]b04264f92013-09-13 23:37:291956 }
1957
1958 virtual void AfterTest() OVERRIDE {}
1959
1960 private:
1961 scoped_refptr<SolidColorLayer> solid_layer_;
1962 scoped_refptr<Layer> parent_layer_;
1963 scoped_refptr<TextureLayer> texture_layer_;
1964
1965 // Used on the main thread.
1966 bool mailbox_changed_;
1967 TextureMailbox mailbox_;
1968 int mailbox_returned_;
1969 int prepare_called_;
1970 int commit_count_;
1971};
1972
1973SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerChangeInvisibleMailboxTest);
1974
[email protected]0d7fb302014-01-23 21:30:471975// Test that TextureLayerImpl::ReleaseResources can be called which releases
1976// the mailbox back to TextureLayerClient.
1977class TextureLayerReleaseResourcesBase
1978 : public LayerTreeTest,
1979 public TextureLayerClient {
1980 public:
1981 // TextureLayerClient implementation.
1982 virtual unsigned PrepareTexture() OVERRIDE {
1983 NOTREACHED();
1984 return 0;
1985 }
1986 virtual bool PrepareTextureMailbox(
1987 TextureMailbox* mailbox,
1988 scoped_ptr<SingleReleaseCallback>* release_callback,
1989 bool use_shared_memory) OVERRIDE {
[email protected]e0a4d732014-02-15 00:23:261990 *mailbox = TextureMailbox(MailboxFromChar('1'), GL_TEXTURE_2D, 0);
[email protected]0d7fb302014-01-23 21:30:471991 *release_callback = SingleReleaseCallback::Create(
1992 base::Bind(&TextureLayerReleaseResourcesBase::MailboxReleased,
1993 base::Unretained(this)));
1994 return true;
1995 }
1996
1997 void MailboxReleased(unsigned sync_point, bool lost_resource) {
1998 mailbox_released_ = true;
1999 }
2000
2001 virtual void SetupTree() OVERRIDE {
2002 LayerTreeTest::SetupTree();
2003
2004 scoped_refptr<TextureLayer> texture_layer =
2005 TextureLayer::CreateForMailbox(this);
2006 texture_layer->SetBounds(gfx::Size(10, 10));
2007 texture_layer->SetAnchorPoint(gfx::PointF());
2008 texture_layer->SetIsDrawable(true);
2009
2010 layer_tree_host()->root_layer()->AddChild(texture_layer);
2011 }
2012
2013 virtual void BeginTest() OVERRIDE {
2014 mailbox_released_ = false;
2015 PostSetNeedsCommitToMainThread();
2016 }
2017
2018 virtual void DidCommitAndDrawFrame() OVERRIDE {
2019 EndTest();
2020 }
2021
2022 virtual void AfterTest() OVERRIDE {
2023 EXPECT_TRUE(mailbox_released_);
2024 }
2025
2026 private:
2027 bool mailbox_released_;
2028};
2029
2030class TextureLayerReleaseResourcesAfterCommit
2031 : public TextureLayerReleaseResourcesBase {
2032 public:
2033 virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
2034 LayerTreeImpl* tree = NULL;
2035 if (host_impl->settings().impl_side_painting)
2036 tree = host_impl->pending_tree();
2037 else
2038 tree = host_impl->active_tree();
2039 tree->root_layer()->children()[0]->ReleaseResources();
2040 }
2041};
2042
2043SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerReleaseResourcesAfterCommit);
2044
2045class TextureLayerReleaseResourcesAfterActivate
2046 : public TextureLayerReleaseResourcesBase {
2047 public:
2048 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
2049 host_impl->active_tree()->root_layer()->children()[0]->ReleaseResources();
2050 }
2051};
2052
2053SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerReleaseResourcesAfterActivate);
2054
[email protected]0bf5a202013-07-10 14:50:542055// Test recovering from a lost context.
2056class TextureLayerLostContextTest
2057 : public LayerTreeTest,
2058 public TextureLayerClient {
2059 public:
2060 TextureLayerLostContextTest()
[email protected]f5931d42013-11-06 19:44:572061 : context_lost_(false),
[email protected]0bf5a202013-07-10 14:50:542062 draw_count_(0) {}
2063
[email protected]a6366932014-02-05 20:12:472064 virtual scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface(bool fallback)
[email protected]ebc0e1df2013-08-01 02:46:222065 OVERRIDE {
[email protected]a6366932014-02-05 20:12:472066 return FakeOutputSurface::Create3d();
[email protected]0bf5a202013-07-10 14:50:542067 }
2068
[email protected]171cbb32013-07-11 03:51:192069 virtual unsigned PrepareTexture() OVERRIDE {
[email protected]f5931d42013-11-06 19:44:572070 if (draw_count_ == 0)
2071 context_lost_ = true;
2072 if (context_lost_)
2073 return 0u;
2074 return 1u;
[email protected]0bf5a202013-07-10 14:50:542075 }
2076
2077 virtual bool PrepareTextureMailbox(
[email protected]9260757f2013-09-17 01:24:162078 TextureMailbox* mailbox,
2079 scoped_ptr<SingleReleaseCallback>* release_callback,
2080 bool use_shared_memory) OVERRIDE {
[email protected]0bf5a202013-07-10 14:50:542081 return false;
2082 }
2083
2084 virtual void SetupTree() OVERRIDE {
2085 scoped_refptr<Layer> root = Layer::Create();
2086 root->SetBounds(gfx::Size(10, 10));
2087 root->SetIsDrawable(true);
2088
2089 texture_layer_ = TextureLayer::Create(this);
2090 texture_layer_->SetBounds(gfx::Size(10, 10));
2091 texture_layer_->SetIsDrawable(true);
2092 root->AddChild(texture_layer_);
2093
2094 layer_tree_host()->SetRootLayer(root);
2095 LayerTreeTest::SetupTree();
2096 }
2097
2098 virtual void BeginTest() OVERRIDE {
2099 PostSetNeedsCommitToMainThread();
2100 }
2101
[email protected]7ddfe7e82014-01-30 07:22:112102 virtual DrawSwapReadbackResult::DrawResult PrepareToDrawOnThread(
2103 LayerTreeHostImpl* host_impl,
2104 LayerTreeHostImpl::FrameData* frame_data,
2105 DrawSwapReadbackResult::DrawResult draw_result) OVERRIDE {
[email protected]0bf5a202013-07-10 14:50:542106 LayerImpl* root = host_impl->RootLayer();
2107 TextureLayerImpl* texture_layer =
2108 static_cast<TextureLayerImpl*>(root->children()[0]);
2109 if (++draw_count_ == 1)
2110 EXPECT_EQ(0u, texture_layer->texture_id());
2111 else
[email protected]f5931d42013-11-06 19:44:572112 EXPECT_EQ(1u, texture_layer->texture_id());
[email protected]7ddfe7e82014-01-30 07:22:112113 return DrawSwapReadbackResult::DRAW_SUCCESS;
[email protected]0bf5a202013-07-10 14:50:542114 }
2115
2116 virtual void DidCommitAndDrawFrame() OVERRIDE {
2117 EndTest();
2118 }
2119
2120 virtual void AfterTest() OVERRIDE {}
2121
2122 private:
2123 scoped_refptr<TextureLayer> texture_layer_;
[email protected]f5931d42013-11-06 19:44:572124 bool context_lost_;
[email protected]0bf5a202013-07-10 14:50:542125 int draw_count_;
2126};
2127
2128SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(TextureLayerLostContextTest);
2129
[email protected]9c2bd822013-07-26 12:30:172130class TextureLayerWithMailboxMainThreadDeleted : public LayerTreeTest {
2131 public:
[email protected]df41e252014-02-03 23:39:502132 void ReleaseCallback(uint32 sync_point, bool lost_resource) {
[email protected]9794fb32013-08-29 09:49:592133 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]9c2bd822013-07-26 12:30:172134 EXPECT_FALSE(lost_resource);
2135 ++callback_count_;
2136 EndTest();
2137 }
2138
2139 void SetMailbox(char mailbox_char) {
[email protected]9794fb32013-08-29 09:49:592140 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]9260757f2013-09-17 01:24:162141 scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create(
[email protected]9c2bd822013-07-26 12:30:172142 base::Bind(
2143 &TextureLayerWithMailboxMainThreadDeleted::ReleaseCallback,
2144 base::Unretained(this)));
[email protected]df41e252014-02-03 23:39:502145 layer_->SetTextureMailbox(
[email protected]e0a4d732014-02-15 00:23:262146 TextureMailbox(MailboxFromChar(mailbox_char), GL_TEXTURE_2D, 0),
[email protected]df41e252014-02-03 23:39:502147 callback.Pass());
[email protected]9c2bd822013-07-26 12:30:172148 }
2149
2150 virtual void SetupTree() OVERRIDE {
2151 gfx::Size bounds(100, 100);
2152 root_ = Layer::Create();
2153 root_->SetAnchorPoint(gfx::PointF());
2154 root_->SetBounds(bounds);
2155
2156 layer_ = TextureLayer::CreateForMailbox(NULL);
2157 layer_->SetIsDrawable(true);
2158 layer_->SetAnchorPoint(gfx::PointF());
2159 layer_->SetBounds(bounds);
2160
2161 root_->AddChild(layer_);
2162 layer_tree_host()->SetRootLayer(root_);
2163 layer_tree_host()->SetViewportSize(bounds);
2164 }
2165
2166 virtual void BeginTest() OVERRIDE {
[email protected]9794fb32013-08-29 09:49:592167 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
2168
[email protected]9c2bd822013-07-26 12:30:172169 callback_count_ = 0;
2170
2171 // Set the mailbox on the main thread.
2172 SetMailbox('1');
2173 EXPECT_EQ(0, callback_count_);
2174
2175 PostSetNeedsCommitToMainThread();
2176 }
2177
2178 virtual void DidCommitAndDrawFrame() OVERRIDE {
2179 switch (layer_tree_host()->source_frame_number()) {
2180 case 1:
2181 // Delete the TextureLayer on the main thread while the mailbox is in
2182 // the impl tree.
2183 layer_->RemoveFromParent();
2184 layer_ = NULL;
2185 break;
2186 }
2187 }
2188
2189 virtual void AfterTest() OVERRIDE {
2190 EXPECT_EQ(1, callback_count_);
2191 }
2192
2193 private:
[email protected]9794fb32013-08-29 09:49:592194 base::ThreadChecker main_thread_;
[email protected]9c2bd822013-07-26 12:30:172195 int callback_count_;
2196 scoped_refptr<Layer> root_;
2197 scoped_refptr<TextureLayer> layer_;
2198};
2199
2200SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
2201 TextureLayerWithMailboxMainThreadDeleted);
2202
2203class TextureLayerWithMailboxImplThreadDeleted : public LayerTreeTest {
2204 public:
[email protected]df41e252014-02-03 23:39:502205 void ReleaseCallback(uint32 sync_point, bool lost_resource) {
[email protected]9794fb32013-08-29 09:49:592206 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]9c2bd822013-07-26 12:30:172207 EXPECT_FALSE(lost_resource);
2208 ++callback_count_;
2209 EndTest();
2210 }
2211
2212 void SetMailbox(char mailbox_char) {
[email protected]9794fb32013-08-29 09:49:592213 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]9260757f2013-09-17 01:24:162214 scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create(
[email protected]9c2bd822013-07-26 12:30:172215 base::Bind(
2216 &TextureLayerWithMailboxImplThreadDeleted::ReleaseCallback,
2217 base::Unretained(this)));
[email protected]df41e252014-02-03 23:39:502218 layer_->SetTextureMailbox(
[email protected]e0a4d732014-02-15 00:23:262219 TextureMailbox(MailboxFromChar(mailbox_char), GL_TEXTURE_2D, 0),
[email protected]df41e252014-02-03 23:39:502220 callback.Pass());
[email protected]9c2bd822013-07-26 12:30:172221 }
2222
2223 virtual void SetupTree() OVERRIDE {
2224 gfx::Size bounds(100, 100);
2225 root_ = Layer::Create();
2226 root_->SetAnchorPoint(gfx::PointF());
2227 root_->SetBounds(bounds);
2228
2229 layer_ = TextureLayer::CreateForMailbox(NULL);
2230 layer_->SetIsDrawable(true);
2231 layer_->SetAnchorPoint(gfx::PointF());
2232 layer_->SetBounds(bounds);
2233
2234 root_->AddChild(layer_);
2235 layer_tree_host()->SetRootLayer(root_);
2236 layer_tree_host()->SetViewportSize(bounds);
2237 }
2238
2239 virtual void BeginTest() OVERRIDE {
[email protected]9794fb32013-08-29 09:49:592240 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
2241
[email protected]9c2bd822013-07-26 12:30:172242 callback_count_ = 0;
2243
2244 // Set the mailbox on the main thread.
2245 SetMailbox('1');
2246 EXPECT_EQ(0, callback_count_);
2247
2248 PostSetNeedsCommitToMainThread();
2249 }
2250
2251 virtual void DidCommitAndDrawFrame() OVERRIDE {
2252 switch (layer_tree_host()->source_frame_number()) {
2253 case 1:
2254 // Remove the TextureLayer on the main thread while the mailbox is in
2255 // the impl tree, but don't delete the TextureLayer until after the impl
2256 // tree side is deleted.
2257 layer_->RemoveFromParent();
2258 break;
2259 case 2:
2260 layer_ = NULL;
2261 break;
2262 }
2263 }
2264
2265 virtual void AfterTest() OVERRIDE {
2266 EXPECT_EQ(1, callback_count_);
2267 }
2268
2269 private:
[email protected]9794fb32013-08-29 09:49:592270 base::ThreadChecker main_thread_;
[email protected]9c2bd822013-07-26 12:30:172271 int callback_count_;
2272 scoped_refptr<Layer> root_;
2273 scoped_refptr<TextureLayer> layer_;
2274};
2275
2276SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
2277 TextureLayerWithMailboxImplThreadDeleted);
2278
[email protected]ba565742012-11-10 09:29:482279} // namespace
2280} // namespace cc