blob: 2db505d9ee27129eef9363ff716fbb0a5fb2460e [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;
40
[email protected]ba565742012-11-10 09:29:4841namespace cc {
[email protected]c0dd24c2012-08-30 23:25:2742namespace {
43
[email protected]408b5e22013-03-19 09:48:0944class MockLayerTreeHost : public LayerTreeHost {
[email protected]28571b042013-03-14 07:59:1545 public:
[email protected]943528e2013-11-07 05:01:3246 explicit MockLayerTreeHost(FakeLayerTreeHostClient* client)
[email protected]a7f35682013-10-22 23:05:5747 : LayerTreeHost(client, NULL, LayerTreeSettings()) {
[email protected]943528e2013-11-07 05:01:3248 InitializeSingleThreaded(client);
[email protected]28571b042013-03-14 07:59:1549 }
[email protected]c0dd24c2012-08-30 23:25:2750
[email protected]28571b042013-03-14 07:59:1551 MOCK_METHOD0(AcquireLayerTextures, void());
52 MOCK_METHOD0(SetNeedsCommit, void());
[email protected]3519b872013-07-30 07:17:5053 MOCK_METHOD0(SetNeedsUpdateLayers, void());
[email protected]aeeb3372013-11-05 14:05:5454 MOCK_METHOD0(StartRateLimiter, void());
55 MOCK_METHOD0(StopRateLimiter, void());
[email protected]c0dd24c2012-08-30 23:25:2756};
57
[email protected]31d4df82013-07-18 10:17:2258class TextureLayerTest : public testing::Test {
59 public:
60 TextureLayerTest()
61 : fake_client_(
62 FakeLayerTreeHostClient(FakeLayerTreeHostClient::DIRECT_3D)),
63 host_impl_(&proxy_) {}
64
65 protected:
66 virtual void SetUp() {
67 layer_tree_host_.reset(new MockLayerTreeHost(&fake_client_));
68 }
69
70 virtual void TearDown() {
71 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
72 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(AnyNumber());
73 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
74
75 layer_tree_host_->SetRootLayer(NULL);
76 layer_tree_host_.reset();
77 }
78
79 scoped_ptr<MockLayerTreeHost> layer_tree_host_;
80 FakeImplProxy proxy_;
81 FakeLayerTreeHostClient fake_client_;
82 FakeLayerTreeHostImpl host_impl_;
83};
84
85TEST_F(TextureLayerTest, SyncImplWhenChangingTextureId) {
86 scoped_refptr<TextureLayer> test_layer = TextureLayer::Create(NULL);
87 ASSERT_TRUE(test_layer.get());
88
89 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(AnyNumber());
90 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
91 layer_tree_host_->SetRootLayer(test_layer);
92 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
93 EXPECT_EQ(test_layer->layer_tree_host(), layer_tree_host_.get());
94
95 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
96 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
97 test_layer->SetTextureId(1);
98 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
99
100 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(AtLeast(1));
101 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
102 test_layer->SetTextureId(2);
103 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
104
105 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(AtLeast(1));
106 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
107 test_layer->SetTextureId(0);
108 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
109}
110
111TEST_F(TextureLayerTest, SyncImplWhenDrawing) {
112 gfx::RectF dirty_rect(0.f, 0.f, 1.f, 1.f);
113
114 scoped_refptr<TextureLayer> test_layer = TextureLayer::Create(NULL);
115 ASSERT_TRUE(test_layer.get());
116 scoped_ptr<TextureLayerImpl> impl_layer;
117 impl_layer = TextureLayerImpl::Create(host_impl_.active_tree(), 1, false);
118 ASSERT_TRUE(impl_layer);
119
120 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(AnyNumber());
121 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
122 layer_tree_host_->SetRootLayer(test_layer);
123 test_layer->SetTextureId(1);
124 test_layer->SetIsDrawable(true);
125 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
126 EXPECT_EQ(test_layer->layer_tree_host(), layer_tree_host_.get());
127
128 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(1);
129 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(0);
130 test_layer->WillModifyTexture();
131 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
132
133 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
[email protected]3519b872013-07-30 07:17:50134 EXPECT_CALL(*layer_tree_host_, SetNeedsUpdateLayers()).Times(1);
[email protected]31d4df82013-07-18 10:17:22135 test_layer->SetNeedsDisplayRect(dirty_rect);
136 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
137
138 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
139 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1);
140 test_layer->PushPropertiesTo(impl_layer.get()); // fake commit
141 test_layer->SetIsDrawable(false);
142 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
143
144 // Verify that non-drawable layers don't signal the compositor,
145 // except for the first draw after last commit, which must acquire
146 // the texture.
147 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(1);
148 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(0);
149 test_layer->WillModifyTexture();
150 test_layer->SetNeedsDisplayRect(dirty_rect);
151 test_layer->PushPropertiesTo(impl_layer.get()); // fake commit
152 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
153
154 // Second draw with layer in non-drawable state: no texture
155 // acquisition.
156 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
157 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(0);
158 test_layer->WillModifyTexture();
159 test_layer->SetNeedsDisplayRect(dirty_rect);
160 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
161}
162
163TEST_F(TextureLayerTest, SyncImplWhenRemovingFromTree) {
164 scoped_refptr<Layer> root_layer = Layer::Create();
165 ASSERT_TRUE(root_layer.get());
166 scoped_refptr<Layer> child_layer = Layer::Create();
167 ASSERT_TRUE(child_layer.get());
168 root_layer->AddChild(child_layer);
169 scoped_refptr<TextureLayer> test_layer = TextureLayer::Create(NULL);
170 ASSERT_TRUE(test_layer.get());
171 test_layer->SetTextureId(0);
172 child_layer->AddChild(test_layer);
173
174 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(AnyNumber());
175 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
176 layer_tree_host_->SetRootLayer(root_layer);
177 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
178
179 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
180 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
181 test_layer->RemoveFromParent();
182 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
183
184 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
185 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
186 child_layer->AddChild(test_layer);
187 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
188
189 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
190 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
191 test_layer->SetTextureId(1);
192 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
193
194 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(AtLeast(1));
195 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
196 test_layer->RemoveFromParent();
197 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
198}
199
200TEST_F(TextureLayerTest, CheckPropertyChangeCausesCorrectBehavior) {
201 scoped_refptr<TextureLayer> test_layer = TextureLayer::Create(NULL);
[email protected]80d42bd2013-08-30 19:13:45202 EXPECT_SET_NEEDS_COMMIT(1, layer_tree_host_->SetRootLayer(test_layer));
[email protected]31d4df82013-07-18 10:17:22203
204 // Test properties that should call SetNeedsCommit. All properties need to
205 // be set to new values in order for SetNeedsCommit to be called.
206 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetFlipped(false));
207 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetUV(
208 gfx::PointF(0.25f, 0.25f), gfx::PointF(0.75f, 0.75f)));
209 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetVertexOpacity(
210 0.5f, 0.5f, 0.5f, 0.5f));
211 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetPremultipliedAlpha(false));
212 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetBlendBackgroundColor(true));
213 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetTextureId(1));
214
215 // Calling SetTextureId can call AcquireLayerTextures.
216 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(AnyNumber());
217}
218
[email protected]1c10e232013-07-31 12:35:43219TEST_F(TextureLayerTest, VisibleContentOpaqueRegion) {
220 const gfx::Size layer_bounds(100, 100);
221 const gfx::Rect layer_rect(layer_bounds);
222 const Region layer_region(layer_rect);
223
224 scoped_refptr<TextureLayer> layer = TextureLayer::Create(NULL);
225 layer->SetBounds(layer_bounds);
226 layer->draw_properties().visible_content_rect = layer_rect;
227 layer->SetBlendBackgroundColor(true);
228
229 // Verify initial conditions.
230 EXPECT_FALSE(layer->contents_opaque());
231 EXPECT_EQ(0u, layer->background_color());
232 EXPECT_EQ(Region().ToString(),
233 layer->VisibleContentOpaqueRegion().ToString());
234
235 // Opaque background.
236 layer->SetBackgroundColor(SK_ColorWHITE);
237 EXPECT_EQ(layer_region.ToString(),
238 layer->VisibleContentOpaqueRegion().ToString());
239
240 // Transparent background.
241 layer->SetBackgroundColor(SkColorSetARGB(100, 255, 255, 255));
242 EXPECT_EQ(Region().ToString(),
243 layer->VisibleContentOpaqueRegion().ToString());
244}
245
[email protected]2f529812013-07-12 01:58:39246class FakeTextureLayerClient : public TextureLayerClient {
247 public:
[email protected]f5931d42013-11-06 19:44:57248 FakeTextureLayerClient() {}
[email protected]2f529812013-07-12 01:58:39249
250 virtual unsigned PrepareTexture() OVERRIDE {
[email protected]31d4df82013-07-18 10:17:22251 return 0;
[email protected]2f529812013-07-12 01:58:39252 }
253
[email protected]9260757f2013-09-17 01:24:16254 virtual bool PrepareTextureMailbox(
255 TextureMailbox* mailbox,
256 scoped_ptr<SingleReleaseCallback>* release_callback,
257 bool use_shared_memory) OVERRIDE {
[email protected]31d4df82013-07-18 10:17:22258 *mailbox = TextureMailbox();
[email protected]9260757f2013-09-17 01:24:16259 *release_callback = scoped_ptr<SingleReleaseCallback>();
[email protected]2f529812013-07-12 01:58:39260 return true;
261 }
262
263 private:
[email protected]2f529812013-07-12 01:58:39264 DISALLOW_COPY_AND_ASSIGN(FakeTextureLayerClient);
265};
266
[email protected]31d4df82013-07-18 10:17:22267TEST_F(TextureLayerTest, RateLimiter) {
268 FakeTextureLayerClient client;
269 scoped_refptr<TextureLayer> test_layer = TextureLayer::CreateForMailbox(
270 &client);
271 test_layer->SetIsDrawable(true);
272 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
273 layer_tree_host_->SetRootLayer(test_layer);
274
275 // Don't rate limit until we invalidate.
[email protected]aeeb3372013-11-05 14:05:54276 EXPECT_CALL(*layer_tree_host_, StartRateLimiter()).Times(0);
[email protected]31d4df82013-07-18 10:17:22277 test_layer->SetRateLimitContext(true);
278 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
279
280 // Do rate limit after we invalidate.
[email protected]aeeb3372013-11-05 14:05:54281 EXPECT_CALL(*layer_tree_host_, StartRateLimiter());
[email protected]31d4df82013-07-18 10:17:22282 test_layer->SetNeedsDisplay();
283 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
284
285 // Stop rate limiter when we don't want it any more.
[email protected]aeeb3372013-11-05 14:05:54286 EXPECT_CALL(*layer_tree_host_, StopRateLimiter());
[email protected]31d4df82013-07-18 10:17:22287 test_layer->SetRateLimitContext(false);
288 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
289
290 // Or we clear the client.
291 test_layer->SetRateLimitContext(true);
[email protected]aeeb3372013-11-05 14:05:54292 EXPECT_CALL(*layer_tree_host_, StopRateLimiter());
[email protected]31d4df82013-07-18 10:17:22293 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
294 test_layer->ClearClient();
295 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
296
297 // Reset to a layer with a client, that started the rate limiter.
298 test_layer = TextureLayer::CreateForMailbox(
299 &client);
300 test_layer->SetIsDrawable(true);
301 test_layer->SetRateLimitContext(true);
302 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
303 layer_tree_host_->SetRootLayer(test_layer);
[email protected]aeeb3372013-11-05 14:05:54304 EXPECT_CALL(*layer_tree_host_, StartRateLimiter()).Times(0);
[email protected]31d4df82013-07-18 10:17:22305 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
[email protected]aeeb3372013-11-05 14:05:54306 EXPECT_CALL(*layer_tree_host_, StartRateLimiter());
[email protected]31d4df82013-07-18 10:17:22307 test_layer->SetNeedsDisplay();
308 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
309
310 // Stop rate limiter when we're removed from the tree.
[email protected]aeeb3372013-11-05 14:05:54311 EXPECT_CALL(*layer_tree_host_, StopRateLimiter());
[email protected]31d4df82013-07-18 10:17:22312 layer_tree_host_->SetRootLayer(NULL);
313 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
314}
315
[email protected]de44a152013-01-08 15:28:46316class MockMailboxCallback {
[email protected]28571b042013-03-14 07:59:15317 public:
[email protected]7ba3ca72013-04-11 06:37:25318 MOCK_METHOD3(Release, void(const std::string& mailbox,
319 unsigned sync_point,
320 bool lost_resource));
[email protected]42f40a52013-06-08 04:38:51321 MOCK_METHOD3(Release2, void(base::SharedMemory* shared_memory,
322 unsigned sync_point,
323 bool lost_resource));
[email protected]de44a152013-01-08 15:28:46324};
325
326struct CommonMailboxObjects {
[email protected]28571b042013-03-14 07:59:15327 CommonMailboxObjects()
328 : mailbox_name1_(64, '1'),
329 mailbox_name2_(64, '2'),
330 sync_point1_(1),
[email protected]42f40a52013-06-08 04:38:51331 sync_point2_(2),
332 shared_memory_(new base::SharedMemory) {
[email protected]28571b042013-03-14 07:59:15333 release_mailbox1_ = base::Bind(&MockMailboxCallback::Release,
334 base::Unretained(&mock_callback_),
335 mailbox_name1_);
336 release_mailbox2_ = base::Bind(&MockMailboxCallback::Release,
337 base::Unretained(&mock_callback_),
338 mailbox_name2_);
339 gpu::Mailbox m1;
340 m1.SetName(reinterpret_cast<const int8*>(mailbox_name1_.data()));
[email protected]9260757f2013-09-17 01:24:16341 mailbox1_ = TextureMailbox(m1, sync_point1_);
[email protected]28571b042013-03-14 07:59:15342 gpu::Mailbox m2;
343 m2.SetName(reinterpret_cast<const int8*>(mailbox_name2_.data()));
[email protected]9260757f2013-09-17 01:24:16344 mailbox2_ = TextureMailbox(m2, sync_point2_);
[email protected]42f40a52013-06-08 04:38:51345
346 gfx::Size size(128, 128);
347 EXPECT_TRUE(shared_memory_->CreateAndMapAnonymous(4 * size.GetArea()));
348 release_mailbox3_ = base::Bind(&MockMailboxCallback::Release2,
349 base::Unretained(&mock_callback_),
350 shared_memory_.get());
[email protected]9260757f2013-09-17 01:24:16351 mailbox3_ = TextureMailbox(shared_memory_.get(), size);
[email protected]28571b042013-03-14 07:59:15352 }
[email protected]de44a152013-01-08 15:28:46353
[email protected]28571b042013-03-14 07:59:15354 std::string mailbox_name1_;
355 std::string mailbox_name2_;
356 MockMailboxCallback mock_callback_;
[email protected]9260757f2013-09-17 01:24:16357 ReleaseCallback release_mailbox1_;
358 ReleaseCallback release_mailbox2_;
359 ReleaseCallback release_mailbox3_;
[email protected]28571b042013-03-14 07:59:15360 TextureMailbox mailbox1_;
361 TextureMailbox mailbox2_;
[email protected]42f40a52013-06-08 04:38:51362 TextureMailbox mailbox3_;
[email protected]28571b042013-03-14 07:59:15363 unsigned sync_point1_;
364 unsigned sync_point2_;
[email protected]42f40a52013-06-08 04:38:51365 scoped_ptr<base::SharedMemory> shared_memory_;
[email protected]de44a152013-01-08 15:28:46366};
367
[email protected]9794fb32013-08-29 09:49:59368class TestMailboxHolder : public TextureLayer::MailboxHolder {
369 public:
370 using TextureLayer::MailboxHolder::Create;
371
372 protected:
373 virtual ~TestMailboxHolder() {}
374};
375
[email protected]de44a152013-01-08 15:28:46376class TextureLayerWithMailboxTest : public TextureLayerTest {
[email protected]28571b042013-03-14 07:59:15377 protected:
378 virtual void TearDown() {
379 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
380 EXPECT_CALL(test_data_.mock_callback_,
381 Release(test_data_.mailbox_name1_,
[email protected]7ba3ca72013-04-11 06:37:25382 test_data_.sync_point1_,
383 false)).Times(1);
[email protected]28571b042013-03-14 07:59:15384 TextureLayerTest::TearDown();
385 }
[email protected]de44a152013-01-08 15:28:46386
[email protected]28571b042013-03-14 07:59:15387 CommonMailboxObjects test_data_;
[email protected]de44a152013-01-08 15:28:46388};
389
[email protected]28571b042013-03-14 07:59:15390TEST_F(TextureLayerWithMailboxTest, ReplaceMailboxOnMainThreadBeforeCommit) {
[email protected]e8e4ae232013-04-12 00:26:01391 scoped_refptr<TextureLayer> test_layer = TextureLayer::CreateForMailbox(NULL);
[email protected]22898ed2013-06-01 04:52:30392 ASSERT_TRUE(test_layer.get());
[email protected]de44a152013-01-08 15:28:46393
[email protected]28571b042013-03-14 07:59:15394 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
395 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
396 layer_tree_host_->SetRootLayer(test_layer);
397 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
[email protected]de44a152013-01-08 15:28:46398
[email protected]28571b042013-03-14 07:59:15399 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
400 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
[email protected]9260757f2013-09-17 01:24:16401 test_layer->SetTextureMailbox(
402 test_data_.mailbox1_,
403 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
[email protected]28571b042013-03-14 07:59:15404 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
[email protected]de44a152013-01-08 15:28:46405
[email protected]28571b042013-03-14 07:59:15406 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
407 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
408 EXPECT_CALL(test_data_.mock_callback_,
[email protected]7ba3ca72013-04-11 06:37:25409 Release(test_data_.mailbox_name1_,
410 test_data_.sync_point1_,
411 false))
[email protected]28571b042013-03-14 07:59:15412 .Times(1);
[email protected]9260757f2013-09-17 01:24:16413 test_layer->SetTextureMailbox(
414 test_data_.mailbox2_,
415 SingleReleaseCallback::Create(test_data_.release_mailbox2_));
[email protected]28571b042013-03-14 07:59:15416 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
417 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]de44a152013-01-08 15:28:46418
[email protected]28571b042013-03-14 07:59:15419 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
420 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
421 EXPECT_CALL(test_data_.mock_callback_,
[email protected]7ba3ca72013-04-11 06:37:25422 Release(test_data_.mailbox_name2_,
423 test_data_.sync_point2_,
424 false))
[email protected]28571b042013-03-14 07:59:15425 .Times(1);
[email protected]9260757f2013-09-17 01:24:16426 test_layer->SetTextureMailbox(TextureMailbox(),
427 scoped_ptr<SingleReleaseCallback>());
[email protected]28571b042013-03-14 07:59:15428 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
429 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]de44a152013-01-08 15:28:46430
[email protected]80d42bd2013-08-30 19:13:45431 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
432 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
[email protected]9260757f2013-09-17 01:24:16433 test_layer->SetTextureMailbox(
434 test_data_.mailbox3_,
435 SingleReleaseCallback::Create(test_data_.release_mailbox3_));
[email protected]42f40a52013-06-08 04:38:51436 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
437 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
438
439 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
440 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
441 EXPECT_CALL(test_data_.mock_callback_,
442 Release2(test_data_.shared_memory_.get(),
443 0, false))
444 .Times(1);
[email protected]9260757f2013-09-17 01:24:16445 test_layer->SetTextureMailbox(TextureMailbox(),
446 scoped_ptr<SingleReleaseCallback>());
[email protected]42f40a52013-06-08 04:38:51447 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
448 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
449
[email protected]28571b042013-03-14 07:59:15450 // Test destructor.
451 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
[email protected]9260757f2013-09-17 01:24:16452 test_layer->SetTextureMailbox(
453 test_data_.mailbox1_,
454 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
[email protected]de44a152013-01-08 15:28:46455}
456
[email protected]9794fb32013-08-29 09:49:59457class TextureLayerMailboxHolderTest : public TextureLayerTest {
458 public:
459 TextureLayerMailboxHolderTest()
460 : main_thread_("MAIN") {
461 main_thread_.Start();
462 }
463
464 void Wait(const base::Thread& thread) {
465 bool manual_reset = false;
466 bool initially_signaled = false;
467 base::WaitableEvent event(manual_reset, initially_signaled);
468 thread.message_loop()->PostTask(
469 FROM_HERE,
470 base::Bind(&base::WaitableEvent::Signal, base::Unretained(&event)));
471 event.Wait();
472 }
473
474 void CreateMainRef() {
475 main_ref_ = TestMailboxHolder::Create(
[email protected]9260757f2013-09-17 01:24:16476 test_data_.mailbox1_,
477 SingleReleaseCallback::Create(test_data_.release_mailbox1_)).Pass();
[email protected]9794fb32013-08-29 09:49:59478 }
479
480 void ReleaseMainRef() {
481 main_ref_.reset();
482 }
483
[email protected]9260757f2013-09-17 01:24:16484 void CreateImplRef(scoped_ptr<SingleReleaseCallback>* impl_ref) {
[email protected]9794fb32013-08-29 09:49:59485 *impl_ref = main_ref_->holder()->GetCallbackForImplThread();
486 }
487
488 void CapturePostTasksAndWait(base::WaitableEvent* begin_capture,
489 base::WaitableEvent* wait_for_capture,
490 base::WaitableEvent* stop_capture) {
491 begin_capture->Wait();
492 BlockingTaskRunner::CapturePostTasks capture;
493 wait_for_capture->Signal();
494 stop_capture->Wait();
495 }
496
497 protected:
498 scoped_ptr<TestMailboxHolder::MainThreadReference>
499 main_ref_;
500 base::Thread main_thread_;
501 CommonMailboxObjects test_data_;
502};
503
504TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_BothReleaseThenMain) {
505 scoped_refptr<TextureLayer> test_layer = TextureLayer::CreateForMailbox(NULL);
506 ASSERT_TRUE(test_layer.get());
507
508 main_thread_.message_loop()->PostTask(
509 FROM_HERE,
510 base::Bind(&TextureLayerMailboxHolderTest::CreateMainRef,
511 base::Unretained(this)));
512
513 Wait(main_thread_);
514
515 // The texture layer is attached to compositor1, and passes a reference to its
516 // impl tree.
[email protected]9260757f2013-09-17 01:24:16517 scoped_ptr<SingleReleaseCallback> compositor1;
[email protected]9794fb32013-08-29 09:49:59518 main_thread_.message_loop()->PostTask(
519 FROM_HERE,
520 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
521 base::Unretained(this),
522 &compositor1));
523
524 // Then the texture layer is removed and attached to compositor2, and passes a
525 // reference to its impl tree.
[email protected]9260757f2013-09-17 01:24:16526 scoped_ptr<SingleReleaseCallback> compositor2;
[email protected]9794fb32013-08-29 09:49:59527 main_thread_.message_loop()->PostTask(
528 FROM_HERE,
529 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
530 base::Unretained(this),
531 &compositor2));
532
533 Wait(main_thread_);
534 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
535
536 // The compositors both destroy their impl trees before the main thread layer
537 // is destroyed.
[email protected]9260757f2013-09-17 01:24:16538 compositor1->Run(100, false);
539 compositor2->Run(200, false);
[email protected]9794fb32013-08-29 09:49:59540
541 Wait(main_thread_);
542
543 EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0);
544 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
545
546 // The main thread ref is the last one, so the mailbox is released back to the
547 // embedder, with the last sync point provided by the impl trees.
548 EXPECT_CALL(test_data_.mock_callback_,
549 Release(test_data_.mailbox_name1_, 200, false)).Times(1);
550
551 main_thread_.message_loop()->PostTask(
552 FROM_HERE,
553 base::Bind(&TextureLayerMailboxHolderTest::ReleaseMainRef,
554 base::Unretained(this)));
555 Wait(main_thread_);
556 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
557}
558
559TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_MainReleaseBetween) {
560 scoped_refptr<TextureLayer> test_layer = TextureLayer::CreateForMailbox(NULL);
561 ASSERT_TRUE(test_layer.get());
562
563 main_thread_.message_loop()->PostTask(
564 FROM_HERE,
565 base::Bind(&TextureLayerMailboxHolderTest::CreateMainRef,
566 base::Unretained(this)));
567
568 Wait(main_thread_);
569
570 // The texture layer is attached to compositor1, and passes a reference to its
571 // impl tree.
[email protected]9260757f2013-09-17 01:24:16572 scoped_ptr<SingleReleaseCallback> compositor1;
[email protected]9794fb32013-08-29 09:49:59573 main_thread_.message_loop()->PostTask(
574 FROM_HERE,
575 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
576 base::Unretained(this),
577 &compositor1));
578
579 // Then the texture layer is removed and attached to compositor2, and passes a
580 // reference to its impl tree.
[email protected]9260757f2013-09-17 01:24:16581 scoped_ptr<SingleReleaseCallback> compositor2;
[email protected]9794fb32013-08-29 09:49:59582 main_thread_.message_loop()->PostTask(
583 FROM_HERE,
584 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
585 base::Unretained(this),
586 &compositor2));
587
588 Wait(main_thread_);
589 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
590
591 // One compositor destroys their impl tree.
[email protected]9260757f2013-09-17 01:24:16592 compositor1->Run(100, false);
[email protected]9794fb32013-08-29 09:49:59593
594 // Then the main thread reference is destroyed.
595 main_thread_.message_loop()->PostTask(
596 FROM_HERE,
597 base::Bind(&TextureLayerMailboxHolderTest::ReleaseMainRef,
598 base::Unretained(this)));
599
600 Wait(main_thread_);
601
602 EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0);
603 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
604
605 // The second impl reference is destroyed last, causing the mailbox to be
606 // released back to the embedder with the last sync point from the impl tree.
607 EXPECT_CALL(test_data_.mock_callback_,
608 Release(test_data_.mailbox_name1_, 200, true)).Times(1);
609
[email protected]9260757f2013-09-17 01:24:16610 compositor2->Run(200, true);
[email protected]9794fb32013-08-29 09:49:59611 Wait(main_thread_);
612 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
613}
614
615TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_MainReleasedFirst) {
616 scoped_refptr<TextureLayer> test_layer = TextureLayer::CreateForMailbox(NULL);
617 ASSERT_TRUE(test_layer.get());
618
619 main_thread_.message_loop()->PostTask(
620 FROM_HERE,
621 base::Bind(&TextureLayerMailboxHolderTest::CreateMainRef,
622 base::Unretained(this)));
623
624 Wait(main_thread_);
625
626 // The texture layer is attached to compositor1, and passes a reference to its
627 // impl tree.
[email protected]9260757f2013-09-17 01:24:16628 scoped_ptr<SingleReleaseCallback> compositor1;
[email protected]9794fb32013-08-29 09:49:59629 main_thread_.message_loop()->PostTask(
630 FROM_HERE,
631 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
632 base::Unretained(this),
633 &compositor1));
634
635 // Then the texture layer is removed and attached to compositor2, and passes a
636 // reference to its impl tree.
[email protected]9260757f2013-09-17 01:24:16637 scoped_ptr<SingleReleaseCallback> compositor2;
[email protected]9794fb32013-08-29 09:49:59638 main_thread_.message_loop()->PostTask(
639 FROM_HERE,
640 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
641 base::Unretained(this),
642 &compositor2));
643
644 Wait(main_thread_);
645 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
646
647 // The main thread reference is destroyed first.
648 main_thread_.message_loop()->PostTask(
649 FROM_HERE,
650 base::Bind(&TextureLayerMailboxHolderTest::ReleaseMainRef,
651 base::Unretained(this)));
652
653 // One compositor destroys their impl tree.
[email protected]9260757f2013-09-17 01:24:16654 compositor2->Run(200, false);
[email protected]9794fb32013-08-29 09:49:59655
656 Wait(main_thread_);
657
658 EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0);
659 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
660
661 // The second impl reference is destroyed last, causing the mailbox to be
662 // released back to the embedder with the last sync point from the impl tree.
663 EXPECT_CALL(test_data_.mock_callback_,
664 Release(test_data_.mailbox_name1_, 100, true)).Times(1);
665
[email protected]9260757f2013-09-17 01:24:16666 compositor1->Run(100, true);
[email protected]9794fb32013-08-29 09:49:59667 Wait(main_thread_);
668 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
669}
670
671TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_SecondImplRefShortcut) {
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 // The main thread reference is destroyed first.
704 main_thread_.message_loop()->PostTask(
705 FROM_HERE,
706 base::Bind(&TextureLayerMailboxHolderTest::ReleaseMainRef,
707 base::Unretained(this)));
708
709 EXPECT_CALL(test_data_.mock_callback_,
710 Release(test_data_.mailbox_name1_, 200, true)).Times(1);
711
712 bool manual_reset = false;
713 bool initially_signaled = false;
714 base::WaitableEvent begin_capture(manual_reset, initially_signaled);
715 base::WaitableEvent wait_for_capture(manual_reset, initially_signaled);
716 base::WaitableEvent stop_capture(manual_reset, initially_signaled);
717
718 // Post a task to start capturing tasks on the main thread. This will block
719 // the main thread until we signal the |stop_capture| event.
720 main_thread_.message_loop()->PostTask(
721 FROM_HERE,
722 base::Bind(&TextureLayerMailboxHolderTest::CapturePostTasksAndWait,
723 base::Unretained(this),
724 &begin_capture,
725 &wait_for_capture,
726 &stop_capture));
727
728 // Before the main thread capturing starts, one compositor destroys their
729 // impl reference. Since capturing did not start, this gets post-tasked to
730 // the main thread.
[email protected]9260757f2013-09-17 01:24:16731 compositor1->Run(100, false);
[email protected]9794fb32013-08-29 09:49:59732
733 // Start capturing on the main thread.
734 begin_capture.Signal();
735 wait_for_capture.Wait();
736
737 // Meanwhile, the second compositor released its impl reference, but this task
738 // gets shortcutted directly to the main thread. This means the reference is
739 // released before compositor1, whose reference will be released later when
740 // the post-task is serviced. But since it was destroyed _on the impl thread_
741 // last, its sync point values should be used.
[email protected]9260757f2013-09-17 01:24:16742 compositor2->Run(200, true);
[email protected]9794fb32013-08-29 09:49:59743
744 stop_capture.Signal();
745 Wait(main_thread_);
746
747 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
748}
749
[email protected]e216fef02013-03-20 22:56:10750class TextureLayerImplWithMailboxThreadedCallback : public LayerTreeTest {
[email protected]28571b042013-03-14 07:59:15751 public:
752 TextureLayerImplWithMailboxThreadedCallback()
753 : callback_count_(0),
754 commit_count_(0) {}
755
756 // Make sure callback is received on main and doesn't block the impl thread.
[email protected]7ba3ca72013-04-11 06:37:25757 void ReleaseCallback(unsigned sync_point, bool lost_resource) {
[email protected]9794fb32013-08-29 09:49:59758 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]7ba3ca72013-04-11 06:37:25759 EXPECT_FALSE(lost_resource);
[email protected]28571b042013-03-14 07:59:15760 ++callback_count_;
761 }
762
763 void SetMailbox(char mailbox_char) {
[email protected]9794fb32013-08-29 09:49:59764 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]9260757f2013-09-17 01:24:16765 TextureMailbox mailbox(std::string(64, mailbox_char));
766 scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create(
[email protected]28571b042013-03-14 07:59:15767 base::Bind(
768 &TextureLayerImplWithMailboxThreadedCallback::ReleaseCallback,
769 base::Unretained(this)));
[email protected]9260757f2013-09-17 01:24:16770 layer_->SetTextureMailbox(mailbox, callback.Pass());
[email protected]28571b042013-03-14 07:59:15771 }
772
[email protected]e216fef02013-03-20 22:56:10773 virtual void BeginTest() OVERRIDE {
[email protected]9794fb32013-08-29 09:49:59774 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
775
[email protected]28571b042013-03-14 07:59:15776 gfx::Size bounds(100, 100);
777 root_ = Layer::Create();
778 root_->SetAnchorPoint(gfx::PointF());
779 root_->SetBounds(bounds);
780
[email protected]e8e4ae232013-04-12 00:26:01781 layer_ = TextureLayer::CreateForMailbox(NULL);
[email protected]28571b042013-03-14 07:59:15782 layer_->SetIsDrawable(true);
783 layer_->SetAnchorPoint(gfx::PointF());
784 layer_->SetBounds(bounds);
785
786 root_->AddChild(layer_);
[email protected]e216fef02013-03-20 22:56:10787 layer_tree_host()->SetRootLayer(root_);
[email protected]18ce59702013-04-09 04:58:40788 layer_tree_host()->SetViewportSize(bounds);
[email protected]28571b042013-03-14 07:59:15789 SetMailbox('1');
790 EXPECT_EQ(0, callback_count_);
791
792 // Case #1: change mailbox before the commit. The old mailbox should be
793 // released immediately.
794 SetMailbox('2');
795 EXPECT_EQ(1, callback_count_);
[email protected]e216fef02013-03-20 22:56:10796 PostSetNeedsCommitToMainThread();
[email protected]28571b042013-03-14 07:59:15797 }
798
[email protected]e216fef02013-03-20 22:56:10799 virtual void DidCommit() OVERRIDE {
[email protected]28571b042013-03-14 07:59:15800 ++commit_count_;
801 switch (commit_count_) {
802 case 1:
803 // Case #2: change mailbox after the commit (and draw), where the
804 // layer draws. The old mailbox should be released during the next
805 // commit.
806 SetMailbox('3');
807 EXPECT_EQ(1, callback_count_);
808 break;
809 case 2:
[email protected]28571b042013-03-14 07:59:15810 EXPECT_EQ(2, callback_count_);
811 // Case #3: change mailbox when the layer doesn't draw. The old
812 // mailbox should be released during the next commit.
813 layer_->SetBounds(gfx::Size());
814 SetMailbox('4');
815 break;
[email protected]9794fb32013-08-29 09:49:59816 case 3:
[email protected]28571b042013-03-14 07:59:15817 EXPECT_EQ(3, callback_count_);
818 // Case #4: release mailbox that was committed but never drawn. The
819 // old mailbox should be released during the next commit.
[email protected]9260757f2013-09-17 01:24:16820 layer_->SetTextureMailbox(TextureMailbox(),
821 scoped_ptr<SingleReleaseCallback>());
[email protected]28571b042013-03-14 07:59:15822 break;
[email protected]9794fb32013-08-29 09:49:59823 case 4:
824 if (layer_tree_host()->settings().impl_side_painting) {
825 // With impl painting, the texture mailbox will still be on the impl
826 // thread when the commit finishes, because the layer is not drawble
827 // when it has no texture mailbox, and thus does not block the commit
828 // on activation. So, we wait for activation.
829 // TODO(danakj): fix this. crbug.com/277953
830 layer_tree_host()->SetNeedsCommit();
831 break;
832 } else {
833 ++commit_count_;
834 }
835 case 5:
[email protected]28571b042013-03-14 07:59:15836 EXPECT_EQ(4, callback_count_);
[email protected]7096acc2013-06-18 21:12:43837 // Restore a mailbox for the next step.
838 SetMailbox('5');
839 break;
[email protected]9794fb32013-08-29 09:49:59840 case 6:
[email protected]7096acc2013-06-18 21:12:43841 // Case #5: remove layer from tree. Callback should *not* be called, the
842 // mailbox is returned to the main thread.
843 EXPECT_EQ(4, callback_count_);
844 layer_->RemoveFromParent();
845 break;
[email protected]9794fb32013-08-29 09:49:59846 case 7:
847 if (layer_tree_host()->settings().impl_side_painting) {
848 // With impl painting, the texture mailbox will still be on the impl
849 // thread when the commit finishes, because the layer is not around to
850 // block the commit on activation anymore. So, we wait for activation.
851 // TODO(danakj): fix this. crbug.com/277953
852 layer_tree_host()->SetNeedsCommit();
853 break;
854 } else {
855 ++commit_count_;
856 }
857 case 8:
[email protected]7096acc2013-06-18 21:12:43858 EXPECT_EQ(4, callback_count_);
859 // Resetting the mailbox will call the callback now.
[email protected]9260757f2013-09-17 01:24:16860 layer_->SetTextureMailbox(TextureMailbox(),
861 scoped_ptr<SingleReleaseCallback>());
[email protected]7096acc2013-06-18 21:12:43862 EXPECT_EQ(5, callback_count_);
[email protected]e216fef02013-03-20 22:56:10863 EndTest();
[email protected]28571b042013-03-14 07:59:15864 break;
865 default:
866 NOTREACHED();
867 break;
[email protected]de44a152013-01-08 15:28:46868 }
[email protected]28571b042013-03-14 07:59:15869 }
[email protected]de44a152013-01-08 15:28:46870
[email protected]e216fef02013-03-20 22:56:10871 virtual void AfterTest() OVERRIDE {}
[email protected]de44a152013-01-08 15:28:46872
[email protected]28571b042013-03-14 07:59:15873 private:
[email protected]9794fb32013-08-29 09:49:59874 base::ThreadChecker main_thread_;
[email protected]28571b042013-03-14 07:59:15875 int callback_count_;
876 int commit_count_;
877 scoped_refptr<Layer> root_;
878 scoped_refptr<TextureLayer> layer_;
[email protected]de44a152013-01-08 15:28:46879};
880
[email protected]4145d172013-05-10 16:54:36881SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
882 TextureLayerImplWithMailboxThreadedCallback);
[email protected]de44a152013-01-08 15:28:46883
[email protected]74b43cc2013-08-30 06:29:27884
885class TextureLayerNoMailboxIsActivatedDuringCommit : public LayerTreeTest,
886 public TextureLayerClient {
887 protected:
888 TextureLayerNoMailboxIsActivatedDuringCommit()
889 : wait_thread_("WAIT"),
[email protected]f10dc472013-09-27 03:31:59890 wait_event_(false, false),
[email protected]f5931d42013-11-06 19:44:57891 texture_(0u) {
[email protected]74b43cc2013-08-30 06:29:27892 wait_thread_.Start();
893 }
894
895 virtual void BeginTest() OVERRIDE {
896 activate_count_ = 0;
897
898 gfx::Size bounds(100, 100);
899 root_ = Layer::Create();
900 root_->SetAnchorPoint(gfx::PointF());
901 root_->SetBounds(bounds);
902
903 layer_ = TextureLayer::Create(this);
904 layer_->SetIsDrawable(true);
905 layer_->SetAnchorPoint(gfx::PointF());
906 layer_->SetBounds(bounds);
907
908 root_->AddChild(layer_);
909 layer_tree_host()->SetRootLayer(root_);
910 layer_tree_host()->SetViewportSize(bounds);
911
912 PostSetNeedsCommitToMainThread();
913 }
914
[email protected]f5931d42013-11-06 19:44:57915 virtual scoped_ptr<OutputSurface> CreateOutputSurface(bool fallback)
916 OVERRIDE {
917 scoped_refptr<TestContextProvider> provider = TestContextProvider::Create();
918 texture_ = provider->UnboundTestContext3d()->createExternalTexture();
919 return FakeOutputSurface::Create3d(provider).PassAs<OutputSurface>();
920 }
921
[email protected]74b43cc2013-08-30 06:29:27922 // TextureLayerClient implementation.
923 virtual unsigned PrepareTexture() OVERRIDE {
[email protected]f5931d42013-11-06 19:44:57924 return texture_;
[email protected]74b43cc2013-08-30 06:29:27925 }
[email protected]9260757f2013-09-17 01:24:16926 virtual bool PrepareTextureMailbox(
927 TextureMailbox* mailbox,
928 scoped_ptr<SingleReleaseCallback>* release_callback,
929 bool use_shared_memory) OVERRIDE {
[email protected]74b43cc2013-08-30 06:29:27930 return false;
931 }
932
933 virtual void WillActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
934 // Slow down activation so the main thread DidCommit() will run if
935 // not blocked.
936 wait_thread_.message_loop()->PostDelayedTask(
937 FROM_HERE,
938 base::Bind(&base::WaitableEvent::Signal,
939 base::Unretained(&wait_event_)),
940 base::TimeDelta::FromMilliseconds(10));
941 wait_event_.Wait();
942
943 base::AutoLock lock(activate_lock_);
944 ++activate_count_;
945 }
946
947 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
948 // The main thread is awake now, and will run DidCommit() immediately.
949 // Run DidActivate() afterwards by posting it now.
950 proxy()->MainThreadTaskRunner()->PostTask(
951 FROM_HERE,
952 base::Bind(&TextureLayerNoMailboxIsActivatedDuringCommit::DidActivate,
953 base::Unretained(this)));
954 }
955
956 void DidActivate() {
957 base::AutoLock lock(activate_lock_);
958 switch (activate_count_) {
959 case 1:
960 // The first texture has been activated. Invalidate the layer so it
961 // grabs a new texture id from the client.
962 layer_->SetNeedsDisplay();
963 // So this commit number should complete after the second activate.
964 EXPECT_EQ(1, layer_tree_host()->source_frame_number());
965 break;
966 case 2:
967 // The second mailbox has been activated. Remove the layer from
968 // the tree to cause another commit/activation. The commit should
969 // finish *after* the layer is removed from the active tree.
970 layer_->RemoveFromParent();
971 // So this commit number should complete after the third activate.
972 EXPECT_EQ(2, layer_tree_host()->source_frame_number());
973 break;
974 case 3:
975 EndTest();
976 break;
977 }
978 }
979
980 virtual void DidCommit() OVERRIDE {
981 switch (layer_tree_host()->source_frame_number()) {
982 case 2: {
983 // The activate for the 2nd texture should have happened before now.
984 base::AutoLock lock(activate_lock_);
985 EXPECT_EQ(2, activate_count_);
986 break;
987 }
988 case 3: {
989 // The activate to remove the layer should have happened before now.
990 base::AutoLock lock(activate_lock_);
991 EXPECT_EQ(3, activate_count_);
992 break;
993 }
994 }
995 }
996
997
998 virtual void AfterTest() OVERRIDE {}
999
1000 base::Thread wait_thread_;
1001 base::WaitableEvent wait_event_;
1002 base::Lock activate_lock_;
[email protected]f5931d42013-11-06 19:44:571003 unsigned texture_;
[email protected]74b43cc2013-08-30 06:29:271004 int activate_count_;
[email protected]74b43cc2013-08-30 06:29:271005 scoped_refptr<Layer> root_;
1006 scoped_refptr<TextureLayer> layer_;
1007};
1008
1009SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
1010 TextureLayerNoMailboxIsActivatedDuringCommit);
1011
1012class TextureLayerMailboxIsActivatedDuringCommit : public LayerTreeTest {
1013 protected:
1014 TextureLayerMailboxIsActivatedDuringCommit()
1015 : wait_thread_("WAIT"),
1016 wait_event_(false, false) {
1017 wait_thread_.Start();
1018 }
1019
1020 static void ReleaseCallback(unsigned sync_point, bool lost_resource) {}
1021
1022 void SetMailbox(char mailbox_char) {
[email protected]9260757f2013-09-17 01:24:161023 TextureMailbox mailbox(std::string(64, mailbox_char));
1024 scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create(
[email protected]74b43cc2013-08-30 06:29:271025 base::Bind(
1026 &TextureLayerMailboxIsActivatedDuringCommit::ReleaseCallback));
[email protected]9260757f2013-09-17 01:24:161027 layer_->SetTextureMailbox(mailbox, callback.Pass());
[email protected]74b43cc2013-08-30 06:29:271028 }
1029
1030 virtual void BeginTest() OVERRIDE {
1031 activate_count_ = 0;
1032
1033 gfx::Size bounds(100, 100);
1034 root_ = Layer::Create();
1035 root_->SetAnchorPoint(gfx::PointF());
1036 root_->SetBounds(bounds);
1037
1038 layer_ = TextureLayer::CreateForMailbox(NULL);
1039 layer_->SetIsDrawable(true);
1040 layer_->SetAnchorPoint(gfx::PointF());
1041 layer_->SetBounds(bounds);
1042
1043 root_->AddChild(layer_);
1044 layer_tree_host()->SetRootLayer(root_);
1045 layer_tree_host()->SetViewportSize(bounds);
1046 SetMailbox('1');
1047
1048 PostSetNeedsCommitToMainThread();
1049 }
1050
1051 virtual void WillActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1052 // Slow down activation so the main thread DidCommit() will run if
1053 // not blocked.
1054 wait_thread_.message_loop()->PostDelayedTask(
1055 FROM_HERE,
1056 base::Bind(&base::WaitableEvent::Signal,
1057 base::Unretained(&wait_event_)),
1058 base::TimeDelta::FromMilliseconds(10));
1059 wait_event_.Wait();
1060
1061 base::AutoLock lock(activate_lock_);
1062 ++activate_count_;
1063 }
1064
1065 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1066 // The main thread is awake now, and will run DidCommit() immediately.
1067 // Run DidActivate() afterwards by posting it now.
1068 proxy()->MainThreadTaskRunner()->PostTask(
1069 FROM_HERE,
1070 base::Bind(&TextureLayerMailboxIsActivatedDuringCommit::DidActivate,
1071 base::Unretained(this)));
1072 }
1073
1074 void DidActivate() {
1075 base::AutoLock lock(activate_lock_);
1076 switch (activate_count_) {
1077 case 1:
1078 // The first mailbox has been activated. Set a new mailbox, and
1079 // expect the next commit to finish *after* it is activated.
1080 SetMailbox('2');
1081 // So this commit number should complete after the second activate.
1082 EXPECT_EQ(1, layer_tree_host()->source_frame_number());
1083 break;
1084 case 2:
1085 // The second mailbox has been activated. Remove the layer from
1086 // the tree to cause another commit/activation. The commit should
1087 // finish *after* the layer is removed from the active tree.
1088 layer_->RemoveFromParent();
1089 // So this commit number should complete after the third activate.
1090 EXPECT_EQ(2, layer_tree_host()->source_frame_number());
1091 break;
1092 case 3:
1093 EndTest();
1094 break;
1095 }
1096 }
1097
1098 virtual void DidCommit() OVERRIDE {
1099 switch (layer_tree_host()->source_frame_number()) {
1100 case 2: {
1101 // The activate for the 2nd mailbox should have happened before now.
1102 base::AutoLock lock(activate_lock_);
1103 EXPECT_EQ(2, activate_count_);
1104 break;
1105 }
1106 case 3: {
1107 // The activate to remove the layer should have happened before now.
1108 base::AutoLock lock(activate_lock_);
1109 EXPECT_EQ(3, activate_count_);
1110 break;
1111 }
1112 }
1113 }
1114
1115
1116 virtual void AfterTest() OVERRIDE {}
1117
1118 base::Thread wait_thread_;
1119 base::WaitableEvent wait_event_;
1120 base::Lock activate_lock_;
1121 int activate_count_;
1122 scoped_refptr<Layer> root_;
1123 scoped_refptr<TextureLayer> layer_;
1124};
1125
1126SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
1127 TextureLayerMailboxIsActivatedDuringCommit);
1128
[email protected]de44a152013-01-08 15:28:461129class TextureLayerImplWithMailboxTest : public TextureLayerTest {
[email protected]28571b042013-03-14 07:59:151130 protected:
[email protected]408b5e22013-03-19 09:48:091131 TextureLayerImplWithMailboxTest()
1132 : fake_client_(
1133 FakeLayerTreeHostClient(FakeLayerTreeHostClient::DIRECT_3D)) {}
1134
[email protected]28571b042013-03-14 07:59:151135 virtual void SetUp() {
1136 TextureLayerTest::SetUp();
[email protected]408b5e22013-03-19 09:48:091137 layer_tree_host_.reset(new MockLayerTreeHost(&fake_client_));
[email protected]f74945f2013-03-21 17:08:361138 EXPECT_TRUE(host_impl_.InitializeRenderer(CreateFakeOutputSurface()));
[email protected]28571b042013-03-14 07:59:151139 }
[email protected]de44a152013-01-08 15:28:461140
[email protected]0ec335c42013-07-04 06:17:081141 bool WillDraw(TextureLayerImpl* layer, DrawMode mode) {
1142 bool will_draw = layer->WillDraw(
1143 mode, host_impl_.active_tree()->resource_provider());
1144 if (will_draw)
1145 layer->DidDraw(host_impl_.active_tree()->resource_provider());
1146 return will_draw;
1147 }
1148
[email protected]28571b042013-03-14 07:59:151149 CommonMailboxObjects test_data_;
[email protected]408b5e22013-03-19 09:48:091150 FakeLayerTreeHostClient fake_client_;
[email protected]de44a152013-01-08 15:28:461151};
1152
[email protected]ffbb2212013-06-02 23:47:591153// Test conditions for results of TextureLayerImpl::WillDraw under
1154// different configurations of different mailbox, texture_id, and draw_mode.
1155TEST_F(TextureLayerImplWithMailboxTest, TestWillDraw) {
[email protected]0ec335c42013-07-04 06:17:081156 EXPECT_CALL(test_data_.mock_callback_,
1157 Release(test_data_.mailbox_name1_,
1158 test_data_.sync_point1_,
1159 false))
1160 .Times(AnyNumber());
1161 EXPECT_CALL(test_data_.mock_callback_,
1162 Release2(test_data_.shared_memory_.get(), 0, false))
1163 .Times(AnyNumber());
[email protected]ffbb2212013-06-02 23:47:591164 // Hardware mode.
1165 {
1166 scoped_ptr<TextureLayerImpl> impl_layer =
1167 TextureLayerImpl::Create(host_impl_.active_tree(), 1, true);
[email protected]afc4f262013-10-05 01:14:101168 impl_layer->SetDrawsContent(true);
[email protected]9260757f2013-09-17 01:24:161169 impl_layer->SetTextureMailbox(
1170 test_data_.mailbox1_,
1171 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
[email protected]0ec335c42013-07-04 06:17:081172 EXPECT_TRUE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE));
[email protected]ffbb2212013-06-02 23:47:591173 }
1174
1175 {
1176 scoped_ptr<TextureLayerImpl> impl_layer =
1177 TextureLayerImpl::Create(host_impl_.active_tree(), 1, true);
[email protected]afc4f262013-10-05 01:14:101178 impl_layer->SetDrawsContent(true);
[email protected]9260757f2013-09-17 01:24:161179 impl_layer->SetTextureMailbox(TextureMailbox(),
1180 scoped_ptr<SingleReleaseCallback>());
[email protected]0ec335c42013-07-04 06:17:081181 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE));
1182 }
1183
1184 {
1185 // Software resource.
1186 scoped_ptr<TextureLayerImpl> impl_layer =
1187 TextureLayerImpl::Create(host_impl_.active_tree(), 1, true);
[email protected]afc4f262013-10-05 01:14:101188 impl_layer->SetDrawsContent(true);
[email protected]9260757f2013-09-17 01:24:161189 impl_layer->SetTextureMailbox(
1190 test_data_.mailbox3_,
1191 SingleReleaseCallback::Create(test_data_.release_mailbox3_));
[email protected]3e44d7a2013-07-30 00:03:101192 EXPECT_TRUE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE));
[email protected]ffbb2212013-06-02 23:47:591193 }
1194
1195 {
1196 scoped_ptr<TextureLayerImpl> impl_layer =
1197 TextureLayerImpl::Create(host_impl_.active_tree(), 1, false);
[email protected]afc4f262013-10-05 01:14:101198 impl_layer->SetDrawsContent(true);
[email protected]0634cdd42013-08-16 00:46:091199 ContextProvider* context_provider =
1200 host_impl_.output_surface()->context_provider();
[email protected]1dff7962014-01-10 12:05:031201 GLuint texture = 0;
1202 context_provider->ContextGL()->GenTextures(1, &texture);
[email protected]ffbb2212013-06-02 23:47:591203 impl_layer->set_texture_id(texture);
[email protected]0ec335c42013-07-04 06:17:081204 EXPECT_TRUE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE));
[email protected]ffbb2212013-06-02 23:47:591205 }
1206
1207 {
1208 scoped_ptr<TextureLayerImpl> impl_layer =
1209 TextureLayerImpl::Create(host_impl_.active_tree(), 1, false);
[email protected]afc4f262013-10-05 01:14:101210 impl_layer->SetDrawsContent(true);
[email protected]ffbb2212013-06-02 23:47:591211 impl_layer->set_texture_id(0);
[email protected]0ec335c42013-07-04 06:17:081212 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE));
1213 }
1214
1215 // Software mode.
1216 {
1217 scoped_ptr<TextureLayerImpl> impl_layer =
1218 TextureLayerImpl::Create(host_impl_.active_tree(), 1, true);
[email protected]afc4f262013-10-05 01:14:101219 impl_layer->SetDrawsContent(true);
[email protected]9260757f2013-09-17 01:24:161220 impl_layer->SetTextureMailbox(
1221 test_data_.mailbox1_,
1222 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
[email protected]0ec335c42013-07-04 06:17:081223 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE));
1224 }
1225
1226 {
1227 scoped_ptr<TextureLayerImpl> impl_layer =
1228 TextureLayerImpl::Create(host_impl_.active_tree(), 1, true);
[email protected]afc4f262013-10-05 01:14:101229 impl_layer->SetDrawsContent(true);
[email protected]9260757f2013-09-17 01:24:161230 impl_layer->SetTextureMailbox(TextureMailbox(),
1231 scoped_ptr<SingleReleaseCallback>());
[email protected]0ec335c42013-07-04 06:17:081232 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE));
1233 }
1234
1235 {
1236 // Software resource.
1237 scoped_ptr<TextureLayerImpl> impl_layer =
1238 TextureLayerImpl::Create(host_impl_.active_tree(), 1, true);
[email protected]afc4f262013-10-05 01:14:101239 impl_layer->SetDrawsContent(true);
[email protected]9260757f2013-09-17 01:24:161240 impl_layer->SetTextureMailbox(
1241 test_data_.mailbox3_,
1242 SingleReleaseCallback::Create(test_data_.release_mailbox3_));
[email protected]0ec335c42013-07-04 06:17:081243 EXPECT_TRUE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE));
1244 }
1245
1246 {
1247 scoped_ptr<TextureLayerImpl> impl_layer =
1248 TextureLayerImpl::Create(host_impl_.active_tree(), 1, false);
[email protected]afc4f262013-10-05 01:14:101249 impl_layer->SetDrawsContent(true);
[email protected]0634cdd42013-08-16 00:46:091250 ContextProvider* context_provider =
1251 host_impl_.output_surface()->context_provider();
[email protected]1dff7962014-01-10 12:05:031252 GLuint texture = 0;
1253 context_provider->ContextGL()->GenTextures(1, &texture);
[email protected]0ec335c42013-07-04 06:17:081254 impl_layer->set_texture_id(texture);
1255 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE));
1256 }
1257
1258 {
1259 scoped_ptr<TextureLayerImpl> impl_layer =
1260 TextureLayerImpl::Create(host_impl_.active_tree(), 1, false);
[email protected]afc4f262013-10-05 01:14:101261 impl_layer->SetDrawsContent(true);
[email protected]0ec335c42013-07-04 06:17:081262 impl_layer->set_texture_id(0);
1263 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE));
[email protected]ffbb2212013-06-02 23:47:591264 }
1265
1266 // Resourceless software mode.
1267 {
1268 scoped_ptr<TextureLayerImpl> impl_layer =
1269 TextureLayerImpl::Create(host_impl_.active_tree(), 1, true);
[email protected]afc4f262013-10-05 01:14:101270 impl_layer->SetDrawsContent(true);
[email protected]9260757f2013-09-17 01:24:161271 impl_layer->SetTextureMailbox(
1272 test_data_.mailbox1_,
1273 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
[email protected]0ec335c42013-07-04 06:17:081274 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_RESOURCELESS_SOFTWARE));
[email protected]ffbb2212013-06-02 23:47:591275 }
1276
1277 {
1278 scoped_ptr<TextureLayerImpl> impl_layer =
1279 TextureLayerImpl::Create(host_impl_.active_tree(), 1, false);
[email protected]afc4f262013-10-05 01:14:101280 impl_layer->SetDrawsContent(true);
[email protected]0634cdd42013-08-16 00:46:091281 ContextProvider* context_provider =
1282 host_impl_.output_surface()->context_provider();
[email protected]1dff7962014-01-10 12:05:031283 GLuint texture = 0;
1284 context_provider->ContextGL()->GenTextures(1, &texture);
[email protected]ffbb2212013-06-02 23:47:591285 impl_layer->set_texture_id(texture);
[email protected]0ec335c42013-07-04 06:17:081286 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_RESOURCELESS_SOFTWARE));
[email protected]ffbb2212013-06-02 23:47:591287 }
1288}
1289
[email protected]28571b042013-03-14 07:59:151290TEST_F(TextureLayerImplWithMailboxTest, TestImplLayerCallbacks) {
1291 host_impl_.CreatePendingTree();
1292 scoped_ptr<TextureLayerImpl> pending_layer;
1293 pending_layer = TextureLayerImpl::Create(host_impl_.pending_tree(), 1, true);
1294 ASSERT_TRUE(pending_layer);
[email protected]de44a152013-01-08 15:28:461295
[email protected]ed511b8d2013-03-25 03:29:291296 scoped_ptr<LayerImpl> active_layer(
[email protected]28571b042013-03-14 07:59:151297 pending_layer->CreateLayerImpl(host_impl_.active_tree()));
[email protected]ed511b8d2013-03-25 03:29:291298 ASSERT_TRUE(active_layer);
[email protected]de44a152013-01-08 15:28:461299
[email protected]9260757f2013-09-17 01:24:161300 pending_layer->SetTextureMailbox(
1301 test_data_.mailbox1_,
1302 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
[email protected]421e84f2013-02-22 03:27:151303
[email protected]28571b042013-03-14 07:59:151304 // Test multiple commits without an activation.
1305 EXPECT_CALL(test_data_.mock_callback_,
[email protected]7ba3ca72013-04-11 06:37:251306 Release(test_data_.mailbox_name1_,
1307 test_data_.sync_point1_,
1308 false))
[email protected]28571b042013-03-14 07:59:151309 .Times(1);
[email protected]9260757f2013-09-17 01:24:161310 pending_layer->SetTextureMailbox(
1311 test_data_.mailbox2_,
1312 SingleReleaseCallback::Create(test_data_.release_mailbox2_));
[email protected]28571b042013-03-14 07:59:151313 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]421e84f2013-02-22 03:27:151314
[email protected]28571b042013-03-14 07:59:151315 // Test callback after activation.
[email protected]ed511b8d2013-03-25 03:29:291316 pending_layer->PushPropertiesTo(active_layer.get());
1317 active_layer->DidBecomeActive();
[email protected]421e84f2013-02-22 03:27:151318
[email protected]7ba3ca72013-04-11 06:37:251319 EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0);
[email protected]9260757f2013-09-17 01:24:161320 pending_layer->SetTextureMailbox(
1321 test_data_.mailbox1_,
1322 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
[email protected]28571b042013-03-14 07:59:151323 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]421e84f2013-02-22 03:27:151324
[email protected]7ba3ca72013-04-11 06:37:251325 EXPECT_CALL(test_data_.mock_callback_,
1326 Release(test_data_.mailbox_name2_, _, false))
[email protected]28571b042013-03-14 07:59:151327 .Times(1);
[email protected]ed511b8d2013-03-25 03:29:291328 pending_layer->PushPropertiesTo(active_layer.get());
1329 active_layer->DidBecomeActive();
[email protected]28571b042013-03-14 07:59:151330 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]de44a152013-01-08 15:28:461331
[email protected]28571b042013-03-14 07:59:151332 // Test resetting the mailbox.
[email protected]7ba3ca72013-04-11 06:37:251333 EXPECT_CALL(test_data_.mock_callback_,
1334 Release(test_data_.mailbox_name1_, _, false))
[email protected]28571b042013-03-14 07:59:151335 .Times(1);
[email protected]9260757f2013-09-17 01:24:161336 pending_layer->SetTextureMailbox(TextureMailbox(),
1337 scoped_ptr<SingleReleaseCallback>());
[email protected]ed511b8d2013-03-25 03:29:291338 pending_layer->PushPropertiesTo(active_layer.get());
1339 active_layer->DidBecomeActive();
[email protected]28571b042013-03-14 07:59:151340 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]de44a152013-01-08 15:28:461341
[email protected]28571b042013-03-14 07:59:151342 // Test destructor.
1343 EXPECT_CALL(test_data_.mock_callback_,
[email protected]7ba3ca72013-04-11 06:37:251344 Release(test_data_.mailbox_name1_,
1345 test_data_.sync_point1_,
1346 false))
[email protected]28571b042013-03-14 07:59:151347 .Times(1);
[email protected]9260757f2013-09-17 01:24:161348 pending_layer->SetTextureMailbox(
1349 test_data_.mailbox1_,
1350 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
[email protected]de44a152013-01-08 15:28:461351}
1352
[email protected]28571b042013-03-14 07:59:151353TEST_F(TextureLayerImplWithMailboxTest,
1354 TestDestructorCallbackOnCreatedResource) {
1355 scoped_ptr<TextureLayerImpl> impl_layer;
1356 impl_layer = TextureLayerImpl::Create(host_impl_.active_tree(), 1, true);
1357 ASSERT_TRUE(impl_layer);
[email protected]de44a152013-01-08 15:28:461358
[email protected]7ba3ca72013-04-11 06:37:251359 EXPECT_CALL(test_data_.mock_callback_,
1360 Release(test_data_.mailbox_name1_, _, false))
[email protected]28571b042013-03-14 07:59:151361 .Times(1);
[email protected]9260757f2013-09-17 01:24:161362 impl_layer->SetTextureMailbox(
1363 test_data_.mailbox1_,
1364 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
[email protected]afc4f262013-10-05 01:14:101365 impl_layer->SetDrawsContent(true);
[email protected]ffbb2212013-06-02 23:47:591366 impl_layer->DidBecomeActive();
1367 EXPECT_TRUE(impl_layer->WillDraw(
1368 DRAW_MODE_HARDWARE, host_impl_.active_tree()->resource_provider()));
[email protected]28571b042013-03-14 07:59:151369 impl_layer->DidDraw(host_impl_.active_tree()->resource_provider());
[email protected]9260757f2013-09-17 01:24:161370 impl_layer->SetTextureMailbox(TextureMailbox(),
1371 scoped_ptr<SingleReleaseCallback>());
[email protected]de44a152013-01-08 15:28:461372}
1373
[email protected]28571b042013-03-14 07:59:151374TEST_F(TextureLayerImplWithMailboxTest, TestCallbackOnInUseResource) {
1375 ResourceProvider* provider = host_impl_.active_tree()->resource_provider();
1376 ResourceProvider::ResourceId id =
[email protected]9260757f2013-09-17 01:24:161377 provider->CreateResourceFromTextureMailbox(
1378 test_data_.mailbox1_,
1379 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
[email protected]28571b042013-03-14 07:59:151380 provider->AllocateForTesting(id);
[email protected]de44a152013-01-08 15:28:461381
[email protected]28571b042013-03-14 07:59:151382 // Transfer some resources to the parent.
1383 ResourceProvider::ResourceIdArray resource_ids_to_transfer;
1384 resource_ids_to_transfer.push_back(id);
1385 TransferableResourceArray list;
1386 provider->PrepareSendToParent(resource_ids_to_transfer, &list);
1387 EXPECT_TRUE(provider->InUseByConsumer(id));
[email protected]7ba3ca72013-04-11 06:37:251388 EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0);
[email protected]28571b042013-03-14 07:59:151389 provider->DeleteResource(id);
1390 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]7ba3ca72013-04-11 06:37:251391 EXPECT_CALL(test_data_.mock_callback_,
1392 Release(test_data_.mailbox_name1_, _, false))
[email protected]28571b042013-03-14 07:59:151393 .Times(1);
[email protected]e00bab022013-08-19 00:42:451394 ReturnedResourceArray returned;
1395 TransferableResource::ReturnResources(list, &returned);
1396 provider->ReceiveReturnsFromParent(returned);
[email protected]de44a152013-01-08 15:28:461397}
1398
[email protected]97d519fb2013-03-29 02:27:541399// Check that ClearClient correctly clears the state so that the impl side
1400// doesn't try to use a texture that could have been destroyed.
[email protected]7ba3ca72013-04-11 06:37:251401class TextureLayerClientTest
1402 : public LayerTreeTest,
1403 public TextureLayerClient {
[email protected]97d519fb2013-03-29 02:27:541404 public:
1405 TextureLayerClientTest()
[email protected]f5931d42013-11-06 19:44:571406 : texture_(0),
[email protected]97d519fb2013-03-29 02:27:541407 commit_count_(0),
1408 expected_used_textures_on_draw_(0),
1409 expected_used_textures_on_commit_(0) {}
1410
[email protected]ebc0e1df2013-08-01 02:46:221411 virtual scoped_ptr<OutputSurface> CreateOutputSurface(bool fallback)
1412 OVERRIDE {
[email protected]f5931d42013-11-06 19:44:571413 scoped_refptr<TestContextProvider> provider = TestContextProvider::Create();
1414 texture_ = provider->UnboundTestContext3d()->createExternalTexture();
1415 return FakeOutputSurface::Create3d(provider).PassAs<OutputSurface>();
[email protected]97d519fb2013-03-29 02:27:541416 }
1417
[email protected]f5931d42013-11-06 19:44:571418 virtual unsigned PrepareTexture() OVERRIDE { return texture_; }
[email protected]97d519fb2013-03-29 02:27:541419
[email protected]2541d1a2013-07-10 07:33:271420 virtual bool PrepareTextureMailbox(
[email protected]9260757f2013-09-17 01:24:161421 TextureMailbox* mailbox,
1422 scoped_ptr<SingleReleaseCallback>* release_callback,
1423 bool use_shared_memory) OVERRIDE {
[email protected]e8e4ae232013-04-12 00:26:011424 return false;
1425 }
1426
[email protected]97d519fb2013-03-29 02:27:541427 virtual void SetupTree() OVERRIDE {
1428 scoped_refptr<Layer> root = Layer::Create();
1429 root->SetBounds(gfx::Size(10, 10));
1430 root->SetAnchorPoint(gfx::PointF());
1431 root->SetIsDrawable(true);
1432
1433 texture_layer_ = TextureLayer::Create(this);
1434 texture_layer_->SetBounds(gfx::Size(10, 10));
1435 texture_layer_->SetAnchorPoint(gfx::PointF());
1436 texture_layer_->SetIsDrawable(true);
1437 root->AddChild(texture_layer_);
1438
1439 layer_tree_host()->SetRootLayer(root);
1440 LayerTreeTest::SetupTree();
1441 {
1442 base::AutoLock lock(lock_);
1443 expected_used_textures_on_commit_ = 1;
1444 }
1445 }
1446
1447 virtual void BeginTest() OVERRIDE {
1448 PostSetNeedsCommitToMainThread();
1449 }
1450
1451 virtual void DidCommitAndDrawFrame() OVERRIDE {
1452 ++commit_count_;
1453 switch (commit_count_) {
1454 case 1:
1455 texture_layer_->ClearClient();
1456 texture_layer_->SetNeedsDisplay();
1457 {
1458 base::AutoLock lock(lock_);
1459 expected_used_textures_on_commit_ = 0;
1460 }
[email protected]97d519fb2013-03-29 02:27:541461 break;
1462 case 2:
1463 EndTest();
1464 break;
1465 default:
1466 NOTREACHED();
1467 break;
1468 }
1469 }
1470
1471 virtual void BeginCommitOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
1472 base::AutoLock lock(lock_);
1473 expected_used_textures_on_draw_ = expected_used_textures_on_commit_;
1474 }
1475
1476 virtual bool PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
1477 LayerTreeHostImpl::FrameData* frame_data,
1478 bool result) OVERRIDE {
[email protected]f5931d42013-11-06 19:44:571479 ContextForImplThread(host_impl)->ResetUsedTextures();
[email protected]97d519fb2013-03-29 02:27:541480 return true;
1481 }
1482
1483 virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl,
1484 bool result) OVERRIDE {
1485 ASSERT_TRUE(result);
[email protected]f5931d42013-11-06 19:44:571486 EXPECT_EQ(expected_used_textures_on_draw_,
1487 ContextForImplThread(host_impl)->NumUsedTextures());
[email protected]97d519fb2013-03-29 02:27:541488 }
1489
1490 virtual void AfterTest() OVERRIDE {}
1491
1492 private:
[email protected]f5931d42013-11-06 19:44:571493 TestWebGraphicsContext3D* ContextForImplThread(LayerTreeHostImpl* host_impl) {
[email protected]1dff7962014-01-10 12:05:031494 return static_cast<TestContextProvider*>(
1495 host_impl->output_surface()->context_provider().get())->TestContext3d();
[email protected]f5931d42013-11-06 19:44:571496 }
1497
[email protected]97d519fb2013-03-29 02:27:541498 scoped_refptr<TextureLayer> texture_layer_;
[email protected]97d519fb2013-03-29 02:27:541499 unsigned texture_;
1500 int commit_count_;
1501
1502 // Used only on thread.
1503 unsigned expected_used_textures_on_draw_;
1504
1505 // Used on either thread, protected by lock_.
1506 base::Lock lock_;
1507 unsigned expected_used_textures_on_commit_;
1508};
1509
[email protected]4145d172013-05-10 16:54:361510// The TextureLayerClient does not use mailboxes, so can't use a delegating
1511// renderer.
1512SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(TextureLayerClientTest);
[email protected]97d519fb2013-03-29 02:27:541513
[email protected]b04264f92013-09-13 23:37:291514
1515// Checks that changing a texture in the client for a TextureLayer that's
1516// invisible correctly works without drawing a deleted texture. See
1517// crbug.com/266628
1518class TextureLayerChangeInvisibleTest
1519 : public LayerTreeTest,
1520 public TextureLayerClient {
1521 public:
1522 TextureLayerChangeInvisibleTest()
[email protected]f5931d42013-11-06 19:44:571523 : texture_(0u),
[email protected]b04264f92013-09-13 23:37:291524 prepare_called_(0),
1525 commit_count_(0),
1526 expected_texture_on_draw_(0) {}
1527
[email protected]f5931d42013-11-06 19:44:571528 virtual scoped_ptr<OutputSurface> CreateOutputSurface(bool fallback)
1529 OVERRIDE {
1530 scoped_refptr<TestContextProvider> provider = TestContextProvider::Create();
1531 texture_ = provider->UnboundTestContext3d()->createExternalTexture();
1532 return FakeOutputSurface::Create3d(provider).PassAs<OutputSurface>();
1533 }
1534
[email protected]b04264f92013-09-13 23:37:291535 // TextureLayerClient implementation.
1536 virtual unsigned PrepareTexture() OVERRIDE {
1537 ++prepare_called_;
1538 return texture_;
1539 }
[email protected]b04264f92013-09-13 23:37:291540 virtual bool PrepareTextureMailbox(
[email protected]e51444a2013-12-10 23:05:011541 TextureMailbox* mailbox,
[email protected]9260757f2013-09-17 01:24:161542 scoped_ptr<SingleReleaseCallback>* release_callback,
1543 bool use_shared_memory) OVERRIDE {
[email protected]b04264f92013-09-13 23:37:291544 return false;
1545 }
1546
1547 virtual void SetupTree() OVERRIDE {
1548 scoped_refptr<Layer> root = Layer::Create();
1549 root->SetBounds(gfx::Size(10, 10));
1550 root->SetAnchorPoint(gfx::PointF());
1551 root->SetIsDrawable(true);
1552
1553 solid_layer_ = SolidColorLayer::Create();
1554 solid_layer_->SetBounds(gfx::Size(10, 10));
1555 solid_layer_->SetIsDrawable(true);
1556 solid_layer_->SetBackgroundColor(SK_ColorWHITE);
1557 root->AddChild(solid_layer_);
1558
1559 parent_layer_ = Layer::Create();
1560 parent_layer_->SetBounds(gfx::Size(10, 10));
1561 parent_layer_->SetIsDrawable(true);
1562 root->AddChild(parent_layer_);
1563
1564 texture_layer_ = TextureLayer::Create(this);
1565 texture_layer_->SetBounds(gfx::Size(10, 10));
1566 texture_layer_->SetAnchorPoint(gfx::PointF());
1567 texture_layer_->SetIsDrawable(true);
1568 parent_layer_->AddChild(texture_layer_);
1569
1570 layer_tree_host()->SetRootLayer(root);
1571 LayerTreeTest::SetupTree();
1572 }
1573
1574 virtual void BeginTest() OVERRIDE {
1575 PostSetNeedsCommitToMainThread();
1576 }
1577
1578 virtual void DidCommitAndDrawFrame() OVERRIDE {
1579 ++commit_count_;
1580 switch (commit_count_) {
1581 case 1:
1582 // We should have updated the layer, committing the texture.
1583 EXPECT_EQ(1, prepare_called_);
1584 // Make layer invisible.
1585 parent_layer_->SetOpacity(0.f);
1586 break;
1587 case 2: {
1588 // Layer shouldn't have been updated.
1589 EXPECT_EQ(1, prepare_called_);
[email protected]b04264f92013-09-13 23:37:291590 texture_layer_->SetNeedsDisplay();
1591 // Force a change to make sure we draw a frame.
1592 solid_layer_->SetBackgroundColor(SK_ColorGRAY);
1593 break;
1594 }
1595 case 3:
1596 EXPECT_EQ(1, prepare_called_);
[email protected]b04264f92013-09-13 23:37:291597 // Make layer visible again.
1598 parent_layer_->SetOpacity(1.f);
1599 break;
1600 case 4: {
1601 // Layer should have been updated.
1602 EXPECT_EQ(2, prepare_called_);
1603 texture_layer_->ClearClient();
[email protected]b04264f92013-09-13 23:37:291604 texture_ = 0;
1605 break;
1606 }
1607 case 5:
1608 EndTest();
1609 break;
1610 default:
1611 NOTREACHED();
1612 break;
1613 }
1614 }
1615
1616 virtual void BeginCommitOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
1617 ASSERT_TRUE(proxy()->IsMainThreadBlocked());
1618 // This is the only texture that can be drawn this frame.
1619 expected_texture_on_draw_ = texture_;
1620 }
1621
1622 virtual bool PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
1623 LayerTreeHostImpl::FrameData* frame_data,
1624 bool result) OVERRIDE {
1625 ContextForImplThread(host_impl)->ResetUsedTextures();
1626 return true;
1627 }
1628
1629 virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl,
1630 bool result) OVERRIDE {
1631 ASSERT_TRUE(result);
1632 TestWebGraphicsContext3D* context = ContextForImplThread(host_impl);
1633 int used_textures = context->NumUsedTextures();
1634 switch (host_impl->active_tree()->source_frame_number()) {
1635 case 0:
1636 EXPECT_EQ(1, used_textures);
1637 EXPECT_TRUE(context->UsedTexture(expected_texture_on_draw_));
1638 break;
1639 case 1:
1640 case 2:
1641 EXPECT_EQ(0, used_textures);
1642 break;
1643 case 3:
1644 EXPECT_EQ(1, used_textures);
1645 EXPECT_TRUE(context->UsedTexture(expected_texture_on_draw_));
1646 break;
1647 default:
1648 break;
1649 }
1650 }
1651
1652 virtual void AfterTest() OVERRIDE {}
1653
1654 private:
1655 TestWebGraphicsContext3D* ContextForImplThread(LayerTreeHostImpl* host_impl) {
[email protected]1dff7962014-01-10 12:05:031656 return static_cast<TestContextProvider*>(
1657 host_impl->output_surface()->context_provider().get())->TestContext3d();
[email protected]b04264f92013-09-13 23:37:291658 }
1659
1660 scoped_refptr<SolidColorLayer> solid_layer_;
1661 scoped_refptr<Layer> parent_layer_;
1662 scoped_refptr<TextureLayer> texture_layer_;
[email protected]b04264f92013-09-13 23:37:291663
1664 // Used on the main thread, and on the impl thread while the main thread is
1665 // blocked.
1666 unsigned texture_;
1667
1668 // Used on the main thread.
[email protected]b04264f92013-09-13 23:37:291669 int prepare_called_;
1670 int commit_count_;
1671
1672 // Used on the compositor thread.
1673 unsigned expected_texture_on_draw_;
1674};
1675
1676// The TextureLayerChangeInvisibleTest does not use mailboxes, so can't use a
1677// delegating renderer.
1678SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(TextureLayerChangeInvisibleTest);
1679
[email protected]4bad8b62013-10-24 01:27:291680// Checks that TextureLayer::Update does not cause an extra commit when setting
1681// the texture mailbox.
1682class TextureLayerNoExtraCommitForMailboxTest
1683 : public LayerTreeTest,
1684 public TextureLayerClient {
1685 public:
[email protected]4bad8b62013-10-24 01:27:291686 // TextureLayerClient implementation.
1687 virtual unsigned PrepareTexture() OVERRIDE {
1688 NOTREACHED();
1689 return 0;
1690 }
[email protected]4bad8b62013-10-24 01:27:291691 virtual bool PrepareTextureMailbox(
[email protected]cce34bd2013-12-02 23:24:451692 TextureMailbox* mailbox,
[email protected]4bad8b62013-10-24 01:27:291693 scoped_ptr<SingleReleaseCallback>* release_callback,
1694 bool use_shared_memory) OVERRIDE {
[email protected]cce34bd2013-12-02 23:24:451695 if (layer_tree_host()->source_frame_number() == 1) {
1696 *mailbox = TextureMailbox();
1697 return true;
1698 }
[email protected]4bad8b62013-10-24 01:27:291699
[email protected]cce34bd2013-12-02 23:24:451700 *mailbox = TextureMailbox(std::string(64, '1'));
[email protected]4bad8b62013-10-24 01:27:291701 *release_callback = SingleReleaseCallback::Create(
1702 base::Bind(&TextureLayerNoExtraCommitForMailboxTest::MailboxReleased,
1703 base::Unretained(this)));
[email protected]4bad8b62013-10-24 01:27:291704 return true;
1705 }
1706
[email protected]4bad8b62013-10-24 01:27:291707 void MailboxReleased(unsigned sync_point, bool lost_resource) {
[email protected]cce34bd2013-12-02 23:24:451708 EXPECT_EQ(2, layer_tree_host()->source_frame_number());
1709 EndTest();
[email protected]4bad8b62013-10-24 01:27:291710 }
1711
1712 virtual void SetupTree() OVERRIDE {
1713 scoped_refptr<Layer> root = Layer::Create();
1714 root->SetBounds(gfx::Size(10, 10));
1715 root->SetAnchorPoint(gfx::PointF());
1716 root->SetIsDrawable(true);
1717
1718 solid_layer_ = SolidColorLayer::Create();
1719 solid_layer_->SetBounds(gfx::Size(10, 10));
1720 solid_layer_->SetIsDrawable(true);
1721 solid_layer_->SetBackgroundColor(SK_ColorWHITE);
1722 root->AddChild(solid_layer_);
1723
1724 parent_layer_ = Layer::Create();
1725 parent_layer_->SetBounds(gfx::Size(10, 10));
1726 parent_layer_->SetIsDrawable(true);
1727 root->AddChild(parent_layer_);
1728
1729 texture_layer_ = TextureLayer::CreateForMailbox(this);
1730 texture_layer_->SetBounds(gfx::Size(10, 10));
1731 texture_layer_->SetAnchorPoint(gfx::PointF());
1732 texture_layer_->SetIsDrawable(true);
1733 parent_layer_->AddChild(texture_layer_);
1734
1735 layer_tree_host()->SetRootLayer(root);
1736 LayerTreeTest::SetupTree();
1737 }
1738
1739 virtual void BeginTest() OVERRIDE {
1740 PostSetNeedsCommitToMainThread();
1741 }
1742
[email protected]cce34bd2013-12-02 23:24:451743 virtual void DidCommitAndDrawFrame() OVERRIDE {
[email protected]4bad8b62013-10-24 01:27:291744 switch (layer_tree_host()->source_frame_number()) {
1745 case 1:
[email protected]cce34bd2013-12-02 23:24:451746 EXPECT_FALSE(proxy()->CommitPendingForTesting());
1747 // Invalidate the texture layer to clear the mailbox before
1748 // ending the test.
1749 texture_layer_->SetNeedsDisplay();
1750 break;
1751 case 2:
[email protected]4bad8b62013-10-24 01:27:291752 break;
1753 default:
1754 NOTREACHED();
1755 break;
1756 }
1757 }
1758
[email protected]cce34bd2013-12-02 23:24:451759 virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl,
1760 bool result) OVERRIDE {
1761 ASSERT_TRUE(result);
1762 DelegatedFrameData* delegated_frame_data =
1763 output_surface()->last_sent_frame().delegated_frame_data.get();
1764 if (!delegated_frame_data)
1765 return;
1766
1767 // Return all resources immediately.
1768 TransferableResourceArray resources_to_return =
1769 output_surface()->resources_held_by_parent();
1770
1771 CompositorFrameAck ack;
1772 for (size_t i = 0; i < resources_to_return.size(); ++i)
1773 output_surface()->ReturnResource(resources_to_return[i].id, &ack);
1774 host_impl->ReclaimResources(&ack);
1775 host_impl->OnSwapBuffersComplete();
1776 }
1777
[email protected]4bad8b62013-10-24 01:27:291778 virtual void AfterTest() OVERRIDE {}
1779
1780 private:
1781 scoped_refptr<SolidColorLayer> solid_layer_;
1782 scoped_refptr<Layer> parent_layer_;
1783 scoped_refptr<TextureLayer> texture_layer_;
[email protected]4bad8b62013-10-24 01:27:291784};
1785
[email protected]cce34bd2013-12-02 23:24:451786SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerNoExtraCommitForMailboxTest);
[email protected]4bad8b62013-10-24 01:27:291787
[email protected]b04264f92013-09-13 23:37:291788// Checks that changing a mailbox in the client for a TextureLayer that's
1789// invisible correctly works and uses the new mailbox as soon as the layer
1790// becomes visible (and returns the old one).
1791class TextureLayerChangeInvisibleMailboxTest
1792 : public LayerTreeTest,
1793 public TextureLayerClient {
1794 public:
1795 TextureLayerChangeInvisibleMailboxTest()
1796 : mailbox_changed_(true),
1797 mailbox_returned_(0),
1798 prepare_called_(0),
1799 commit_count_(0) {
1800 mailbox_ = MakeMailbox('1');
1801 }
1802
1803 // TextureLayerClient implementation.
1804 virtual unsigned PrepareTexture() OVERRIDE {
1805 NOTREACHED();
1806 return 0;
1807 }
1808
[email protected]b04264f92013-09-13 23:37:291809 virtual bool PrepareTextureMailbox(
[email protected]e51444a2013-12-10 23:05:011810 TextureMailbox* mailbox,
[email protected]9260757f2013-09-17 01:24:161811 scoped_ptr<SingleReleaseCallback>* release_callback,
1812 bool use_shared_memory) OVERRIDE {
[email protected]b04264f92013-09-13 23:37:291813 ++prepare_called_;
1814 if (!mailbox_changed_)
1815 return false;
1816 *mailbox = mailbox_;
[email protected]9260757f2013-09-17 01:24:161817 *release_callback = SingleReleaseCallback::Create(
1818 base::Bind(&TextureLayerChangeInvisibleMailboxTest::MailboxReleased,
1819 base::Unretained(this)));
[email protected]b04264f92013-09-13 23:37:291820 return true;
1821 }
1822
1823 TextureMailbox MakeMailbox(char name) {
[email protected]9260757f2013-09-17 01:24:161824 return TextureMailbox(std::string(64, name));
[email protected]b04264f92013-09-13 23:37:291825 }
1826
1827 void MailboxReleased(unsigned sync_point, bool lost_resource) {
1828 ++mailbox_returned_;
1829 }
1830
1831 virtual void SetupTree() OVERRIDE {
1832 scoped_refptr<Layer> root = Layer::Create();
1833 root->SetBounds(gfx::Size(10, 10));
1834 root->SetAnchorPoint(gfx::PointF());
1835 root->SetIsDrawable(true);
1836
1837 solid_layer_ = SolidColorLayer::Create();
1838 solid_layer_->SetBounds(gfx::Size(10, 10));
1839 solid_layer_->SetIsDrawable(true);
1840 solid_layer_->SetBackgroundColor(SK_ColorWHITE);
1841 root->AddChild(solid_layer_);
1842
1843 parent_layer_ = Layer::Create();
1844 parent_layer_->SetBounds(gfx::Size(10, 10));
1845 parent_layer_->SetIsDrawable(true);
1846 root->AddChild(parent_layer_);
1847
1848 texture_layer_ = TextureLayer::CreateForMailbox(this);
1849 texture_layer_->SetBounds(gfx::Size(10, 10));
1850 texture_layer_->SetAnchorPoint(gfx::PointF());
1851 texture_layer_->SetIsDrawable(true);
1852 parent_layer_->AddChild(texture_layer_);
1853
1854 layer_tree_host()->SetRootLayer(root);
1855 LayerTreeTest::SetupTree();
1856 }
1857
1858 virtual void BeginTest() OVERRIDE {
1859 PostSetNeedsCommitToMainThread();
1860 }
1861
1862 virtual void DidCommitAndDrawFrame() OVERRIDE {
1863 ++commit_count_;
1864 switch (commit_count_) {
1865 case 1:
1866 // We should have updated the layer, committing the texture.
1867 EXPECT_EQ(1, prepare_called_);
1868 // Make layer invisible.
1869 parent_layer_->SetOpacity(0.f);
1870 break;
1871 case 2:
1872 // Layer shouldn't have been updated.
1873 EXPECT_EQ(1, prepare_called_);
1874 // Change the texture.
1875 mailbox_ = MakeMailbox('2');
1876 mailbox_changed_ = true;
1877 texture_layer_->SetNeedsDisplay();
1878 // Force a change to make sure we draw a frame.
1879 solid_layer_->SetBackgroundColor(SK_ColorGRAY);
1880 break;
1881 case 3:
1882 // Layer shouldn't have been updated.
1883 EXPECT_EQ(1, prepare_called_);
1884 // So the old mailbox isn't returned yet.
1885 EXPECT_EQ(0, mailbox_returned_);
1886 // Make layer visible again.
1887 parent_layer_->SetOpacity(1.f);
1888 break;
1889 case 4:
1890 // Layer should have been updated.
1891 EXPECT_EQ(2, prepare_called_);
1892 // So the old mailbox should have been returned already.
1893 EXPECT_EQ(1, mailbox_returned_);
1894 texture_layer_->ClearClient();
1895 break;
1896 case 5:
1897 EXPECT_EQ(2, mailbox_returned_);
1898 EndTest();
1899 break;
1900 default:
1901 NOTREACHED();
1902 break;
1903 }
1904 }
1905
1906 virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl,
1907 bool result) OVERRIDE {
1908 ASSERT_TRUE(result);
1909 DelegatedFrameData* delegated_frame_data =
1910 output_surface()->last_sent_frame().delegated_frame_data.get();
1911 if (!delegated_frame_data)
1912 return;
1913
1914 // Return all resources immediately.
1915 TransferableResourceArray resources_to_return =
1916 output_surface()->resources_held_by_parent();
1917
1918 CompositorFrameAck ack;
1919 for (size_t i = 0; i < resources_to_return.size(); ++i)
1920 output_surface()->ReturnResource(resources_to_return[i].id, &ack);
[email protected]a7335e0b2013-09-18 09:34:511921 host_impl->ReclaimResources(&ack);
1922 host_impl->OnSwapBuffersComplete();
[email protected]b04264f92013-09-13 23:37:291923 }
1924
1925 virtual void AfterTest() OVERRIDE {}
1926
1927 private:
1928 scoped_refptr<SolidColorLayer> solid_layer_;
1929 scoped_refptr<Layer> parent_layer_;
1930 scoped_refptr<TextureLayer> texture_layer_;
1931
1932 // Used on the main thread.
1933 bool mailbox_changed_;
1934 TextureMailbox mailbox_;
1935 int mailbox_returned_;
1936 int prepare_called_;
1937 int commit_count_;
1938};
1939
1940SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerChangeInvisibleMailboxTest);
1941
[email protected]0bf5a202013-07-10 14:50:541942// Test recovering from a lost context.
1943class TextureLayerLostContextTest
1944 : public LayerTreeTest,
1945 public TextureLayerClient {
1946 public:
1947 TextureLayerLostContextTest()
[email protected]f5931d42013-11-06 19:44:571948 : context_lost_(false),
[email protected]0bf5a202013-07-10 14:50:541949 draw_count_(0) {}
1950
[email protected]ebc0e1df2013-08-01 02:46:221951 virtual scoped_ptr<OutputSurface> CreateOutputSurface(bool fallback)
1952 OVERRIDE {
[email protected]3f6a906c2013-07-17 01:03:261953 return CreateFakeOutputSurface();
[email protected]0bf5a202013-07-10 14:50:541954 }
1955
[email protected]171cbb32013-07-11 03:51:191956 virtual unsigned PrepareTexture() OVERRIDE {
[email protected]f5931d42013-11-06 19:44:571957 if (draw_count_ == 0)
1958 context_lost_ = true;
1959 if (context_lost_)
1960 return 0u;
1961 return 1u;
[email protected]0bf5a202013-07-10 14:50:541962 }
1963
1964 virtual bool PrepareTextureMailbox(
[email protected]9260757f2013-09-17 01:24:161965 TextureMailbox* mailbox,
1966 scoped_ptr<SingleReleaseCallback>* release_callback,
1967 bool use_shared_memory) OVERRIDE {
[email protected]0bf5a202013-07-10 14:50:541968 return false;
1969 }
1970
1971 virtual void SetupTree() OVERRIDE {
1972 scoped_refptr<Layer> root = Layer::Create();
1973 root->SetBounds(gfx::Size(10, 10));
1974 root->SetIsDrawable(true);
1975
1976 texture_layer_ = TextureLayer::Create(this);
1977 texture_layer_->SetBounds(gfx::Size(10, 10));
1978 texture_layer_->SetIsDrawable(true);
1979 root->AddChild(texture_layer_);
1980
1981 layer_tree_host()->SetRootLayer(root);
1982 LayerTreeTest::SetupTree();
1983 }
1984
1985 virtual void BeginTest() OVERRIDE {
1986 PostSetNeedsCommitToMainThread();
1987 }
1988
1989 virtual bool PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
1990 LayerTreeHostImpl::FrameData* frame_data,
1991 bool result) OVERRIDE {
1992 LayerImpl* root = host_impl->RootLayer();
1993 TextureLayerImpl* texture_layer =
1994 static_cast<TextureLayerImpl*>(root->children()[0]);
1995 if (++draw_count_ == 1)
1996 EXPECT_EQ(0u, texture_layer->texture_id());
1997 else
[email protected]f5931d42013-11-06 19:44:571998 EXPECT_EQ(1u, texture_layer->texture_id());
[email protected]0bf5a202013-07-10 14:50:541999 return true;
2000 }
2001
2002 virtual void DidCommitAndDrawFrame() OVERRIDE {
2003 EndTest();
2004 }
2005
2006 virtual void AfterTest() OVERRIDE {}
2007
2008 private:
2009 scoped_refptr<TextureLayer> texture_layer_;
[email protected]f5931d42013-11-06 19:44:572010 bool context_lost_;
[email protected]0bf5a202013-07-10 14:50:542011 int draw_count_;
2012};
2013
2014SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(TextureLayerLostContextTest);
2015
[email protected]9c2bd822013-07-26 12:30:172016class TextureLayerWithMailboxMainThreadDeleted : public LayerTreeTest {
2017 public:
2018 void ReleaseCallback(unsigned sync_point, bool lost_resource) {
[email protected]9794fb32013-08-29 09:49:592019 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]9c2bd822013-07-26 12:30:172020 EXPECT_FALSE(lost_resource);
2021 ++callback_count_;
2022 EndTest();
2023 }
2024
2025 void SetMailbox(char mailbox_char) {
[email protected]9794fb32013-08-29 09:49:592026 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]9260757f2013-09-17 01:24:162027 TextureMailbox mailbox(std::string(64, mailbox_char));
2028 scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create(
[email protected]9c2bd822013-07-26 12:30:172029 base::Bind(
2030 &TextureLayerWithMailboxMainThreadDeleted::ReleaseCallback,
2031 base::Unretained(this)));
[email protected]9260757f2013-09-17 01:24:162032 layer_->SetTextureMailbox(mailbox, callback.Pass());
[email protected]9c2bd822013-07-26 12:30:172033 }
2034
2035 virtual void SetupTree() OVERRIDE {
2036 gfx::Size bounds(100, 100);
2037 root_ = Layer::Create();
2038 root_->SetAnchorPoint(gfx::PointF());
2039 root_->SetBounds(bounds);
2040
2041 layer_ = TextureLayer::CreateForMailbox(NULL);
2042 layer_->SetIsDrawable(true);
2043 layer_->SetAnchorPoint(gfx::PointF());
2044 layer_->SetBounds(bounds);
2045
2046 root_->AddChild(layer_);
2047 layer_tree_host()->SetRootLayer(root_);
2048 layer_tree_host()->SetViewportSize(bounds);
2049 }
2050
2051 virtual void BeginTest() OVERRIDE {
[email protected]9794fb32013-08-29 09:49:592052 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
2053
[email protected]9c2bd822013-07-26 12:30:172054 callback_count_ = 0;
2055
2056 // Set the mailbox on the main thread.
2057 SetMailbox('1');
2058 EXPECT_EQ(0, callback_count_);
2059
2060 PostSetNeedsCommitToMainThread();
2061 }
2062
2063 virtual void DidCommitAndDrawFrame() OVERRIDE {
2064 switch (layer_tree_host()->source_frame_number()) {
2065 case 1:
2066 // Delete the TextureLayer on the main thread while the mailbox is in
2067 // the impl tree.
2068 layer_->RemoveFromParent();
2069 layer_ = NULL;
2070 break;
2071 }
2072 }
2073
2074 virtual void AfterTest() OVERRIDE {
2075 EXPECT_EQ(1, callback_count_);
2076 }
2077
2078 private:
[email protected]9794fb32013-08-29 09:49:592079 base::ThreadChecker main_thread_;
[email protected]9c2bd822013-07-26 12:30:172080 int callback_count_;
2081 scoped_refptr<Layer> root_;
2082 scoped_refptr<TextureLayer> layer_;
2083};
2084
2085SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
2086 TextureLayerWithMailboxMainThreadDeleted);
2087
2088class TextureLayerWithMailboxImplThreadDeleted : public LayerTreeTest {
2089 public:
2090 void ReleaseCallback(unsigned sync_point, bool lost_resource) {
[email protected]9794fb32013-08-29 09:49:592091 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]9c2bd822013-07-26 12:30:172092 EXPECT_FALSE(lost_resource);
2093 ++callback_count_;
2094 EndTest();
2095 }
2096
2097 void SetMailbox(char mailbox_char) {
[email protected]9794fb32013-08-29 09:49:592098 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]9260757f2013-09-17 01:24:162099 TextureMailbox mailbox(std::string(64, mailbox_char));
2100 scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create(
[email protected]9c2bd822013-07-26 12:30:172101 base::Bind(
2102 &TextureLayerWithMailboxImplThreadDeleted::ReleaseCallback,
2103 base::Unretained(this)));
[email protected]9260757f2013-09-17 01:24:162104 layer_->SetTextureMailbox(mailbox, callback.Pass());
[email protected]9c2bd822013-07-26 12:30:172105 }
2106
2107 virtual void SetupTree() OVERRIDE {
2108 gfx::Size bounds(100, 100);
2109 root_ = Layer::Create();
2110 root_->SetAnchorPoint(gfx::PointF());
2111 root_->SetBounds(bounds);
2112
2113 layer_ = TextureLayer::CreateForMailbox(NULL);
2114 layer_->SetIsDrawable(true);
2115 layer_->SetAnchorPoint(gfx::PointF());
2116 layer_->SetBounds(bounds);
2117
2118 root_->AddChild(layer_);
2119 layer_tree_host()->SetRootLayer(root_);
2120 layer_tree_host()->SetViewportSize(bounds);
2121 }
2122
2123 virtual void BeginTest() OVERRIDE {
[email protected]9794fb32013-08-29 09:49:592124 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
2125
[email protected]9c2bd822013-07-26 12:30:172126 callback_count_ = 0;
2127
2128 // Set the mailbox on the main thread.
2129 SetMailbox('1');
2130 EXPECT_EQ(0, callback_count_);
2131
2132 PostSetNeedsCommitToMainThread();
2133 }
2134
2135 virtual void DidCommitAndDrawFrame() OVERRIDE {
2136 switch (layer_tree_host()->source_frame_number()) {
2137 case 1:
2138 // Remove the TextureLayer on the main thread while the mailbox is in
2139 // the impl tree, but don't delete the TextureLayer until after the impl
2140 // tree side is deleted.
2141 layer_->RemoveFromParent();
2142 break;
2143 case 2:
2144 layer_ = NULL;
2145 break;
2146 }
2147 }
2148
2149 virtual void AfterTest() OVERRIDE {
2150 EXPECT_EQ(1, callback_count_);
2151 }
2152
2153 private:
[email protected]9794fb32013-08-29 09:49:592154 base::ThreadChecker main_thread_;
[email protected]9c2bd822013-07-26 12:30:172155 int callback_count_;
2156 scoped_refptr<Layer> root_;
2157 scoped_refptr<TextureLayer> layer_;
2158};
2159
2160SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
2161 TextureLayerWithMailboxImplThreadDeleted);
2162
[email protected]ba565742012-11-10 09:29:482163} // namespace
2164} // namespace cc