blob: cfbe8133fbf51cd445a1397fd2dde1b0a19434a8 [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]df41e252014-02-03 23:39:5044gpu::Mailbox MailboxFromString(const std::string& string) {
45 gpu::Mailbox mailbox;
46 mailbox.SetName(reinterpret_cast<const int8*>(string.data()));
47 return mailbox;
48}
49
[email protected]408b5e22013-03-19 09:48:0950class MockLayerTreeHost : public LayerTreeHost {
[email protected]28571b042013-03-14 07:59:1551 public:
[email protected]943528e2013-11-07 05:01:3252 explicit MockLayerTreeHost(FakeLayerTreeHostClient* client)
[email protected]a7f35682013-10-22 23:05:5753 : LayerTreeHost(client, NULL, LayerTreeSettings()) {
[email protected]943528e2013-11-07 05:01:3254 InitializeSingleThreaded(client);
[email protected]28571b042013-03-14 07:59:1555 }
[email protected]c0dd24c2012-08-30 23:25:2756
[email protected]28571b042013-03-14 07:59:1557 MOCK_METHOD0(AcquireLayerTextures, void());
58 MOCK_METHOD0(SetNeedsCommit, void());
[email protected]3519b872013-07-30 07:17:5059 MOCK_METHOD0(SetNeedsUpdateLayers, void());
[email protected]aeeb3372013-11-05 14:05:5460 MOCK_METHOD0(StartRateLimiter, void());
61 MOCK_METHOD0(StopRateLimiter, void());
[email protected]c0dd24c2012-08-30 23:25:2762};
63
[email protected]31d4df82013-07-18 10:17:2264class TextureLayerTest : public testing::Test {
65 public:
66 TextureLayerTest()
67 : fake_client_(
68 FakeLayerTreeHostClient(FakeLayerTreeHostClient::DIRECT_3D)),
69 host_impl_(&proxy_) {}
70
71 protected:
72 virtual void SetUp() {
73 layer_tree_host_.reset(new MockLayerTreeHost(&fake_client_));
74 }
75
76 virtual void TearDown() {
77 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
78 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(AnyNumber());
79 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
80
81 layer_tree_host_->SetRootLayer(NULL);
82 layer_tree_host_.reset();
83 }
84
85 scoped_ptr<MockLayerTreeHost> layer_tree_host_;
86 FakeImplProxy proxy_;
87 FakeLayerTreeHostClient fake_client_;
88 FakeLayerTreeHostImpl host_impl_;
89};
90
91TEST_F(TextureLayerTest, SyncImplWhenChangingTextureId) {
92 scoped_refptr<TextureLayer> test_layer = TextureLayer::Create(NULL);
93 ASSERT_TRUE(test_layer.get());
94
95 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(AnyNumber());
96 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
97 layer_tree_host_->SetRootLayer(test_layer);
98 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
99 EXPECT_EQ(test_layer->layer_tree_host(), layer_tree_host_.get());
100
101 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
102 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
103 test_layer->SetTextureId(1);
104 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
105
106 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(AtLeast(1));
107 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
108 test_layer->SetTextureId(2);
109 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
110
111 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(AtLeast(1));
112 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
113 test_layer->SetTextureId(0);
114 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
115}
116
117TEST_F(TextureLayerTest, SyncImplWhenDrawing) {
118 gfx::RectF dirty_rect(0.f, 0.f, 1.f, 1.f);
119
120 scoped_refptr<TextureLayer> test_layer = TextureLayer::Create(NULL);
121 ASSERT_TRUE(test_layer.get());
122 scoped_ptr<TextureLayerImpl> impl_layer;
123 impl_layer = TextureLayerImpl::Create(host_impl_.active_tree(), 1, false);
124 ASSERT_TRUE(impl_layer);
125
126 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(AnyNumber());
127 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
128 layer_tree_host_->SetRootLayer(test_layer);
129 test_layer->SetTextureId(1);
130 test_layer->SetIsDrawable(true);
131 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
132 EXPECT_EQ(test_layer->layer_tree_host(), layer_tree_host_.get());
133
134 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(1);
135 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(0);
136 test_layer->WillModifyTexture();
137 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
138
139 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
[email protected]3519b872013-07-30 07:17:50140 EXPECT_CALL(*layer_tree_host_, SetNeedsUpdateLayers()).Times(1);
[email protected]31d4df82013-07-18 10:17:22141 test_layer->SetNeedsDisplayRect(dirty_rect);
142 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
143
144 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
145 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1);
146 test_layer->PushPropertiesTo(impl_layer.get()); // fake commit
147 test_layer->SetIsDrawable(false);
148 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
149
150 // Verify that non-drawable layers don't signal the compositor,
151 // except for the first draw after last commit, which must acquire
152 // the texture.
153 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(1);
154 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(0);
155 test_layer->WillModifyTexture();
156 test_layer->SetNeedsDisplayRect(dirty_rect);
157 test_layer->PushPropertiesTo(impl_layer.get()); // fake commit
158 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
159
160 // Second draw with layer in non-drawable state: no texture
161 // acquisition.
162 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
163 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(0);
164 test_layer->WillModifyTexture();
165 test_layer->SetNeedsDisplayRect(dirty_rect);
166 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
167}
168
169TEST_F(TextureLayerTest, SyncImplWhenRemovingFromTree) {
170 scoped_refptr<Layer> root_layer = Layer::Create();
171 ASSERT_TRUE(root_layer.get());
172 scoped_refptr<Layer> child_layer = Layer::Create();
173 ASSERT_TRUE(child_layer.get());
174 root_layer->AddChild(child_layer);
175 scoped_refptr<TextureLayer> test_layer = TextureLayer::Create(NULL);
176 ASSERT_TRUE(test_layer.get());
177 test_layer->SetTextureId(0);
178 child_layer->AddChild(test_layer);
179
180 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(AnyNumber());
181 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
182 layer_tree_host_->SetRootLayer(root_layer);
183 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
184
185 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
186 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
187 test_layer->RemoveFromParent();
188 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
189
190 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
191 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
192 child_layer->AddChild(test_layer);
193 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
194
195 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
196 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
197 test_layer->SetTextureId(1);
198 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
199
200 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(AtLeast(1));
201 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
202 test_layer->RemoveFromParent();
203 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
204}
205
206TEST_F(TextureLayerTest, CheckPropertyChangeCausesCorrectBehavior) {
207 scoped_refptr<TextureLayer> test_layer = TextureLayer::Create(NULL);
[email protected]80d42bd2013-08-30 19:13:45208 EXPECT_SET_NEEDS_COMMIT(1, layer_tree_host_->SetRootLayer(test_layer));
[email protected]31d4df82013-07-18 10:17:22209
210 // Test properties that should call SetNeedsCommit. All properties need to
211 // be set to new values in order for SetNeedsCommit to be called.
212 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetFlipped(false));
213 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetUV(
214 gfx::PointF(0.25f, 0.25f), gfx::PointF(0.75f, 0.75f)));
215 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetVertexOpacity(
216 0.5f, 0.5f, 0.5f, 0.5f));
217 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetPremultipliedAlpha(false));
218 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetBlendBackgroundColor(true));
219 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetTextureId(1));
220
221 // Calling SetTextureId can call AcquireLayerTextures.
222 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(AnyNumber());
223}
224
[email protected]1c10e232013-07-31 12:35:43225TEST_F(TextureLayerTest, VisibleContentOpaqueRegion) {
226 const gfx::Size layer_bounds(100, 100);
227 const gfx::Rect layer_rect(layer_bounds);
228 const Region layer_region(layer_rect);
229
230 scoped_refptr<TextureLayer> layer = TextureLayer::Create(NULL);
231 layer->SetBounds(layer_bounds);
232 layer->draw_properties().visible_content_rect = layer_rect;
233 layer->SetBlendBackgroundColor(true);
234
235 // Verify initial conditions.
236 EXPECT_FALSE(layer->contents_opaque());
237 EXPECT_EQ(0u, layer->background_color());
238 EXPECT_EQ(Region().ToString(),
239 layer->VisibleContentOpaqueRegion().ToString());
240
241 // Opaque background.
242 layer->SetBackgroundColor(SK_ColorWHITE);
243 EXPECT_EQ(layer_region.ToString(),
244 layer->VisibleContentOpaqueRegion().ToString());
245
246 // Transparent background.
247 layer->SetBackgroundColor(SkColorSetARGB(100, 255, 255, 255));
248 EXPECT_EQ(Region().ToString(),
249 layer->VisibleContentOpaqueRegion().ToString());
250}
251
[email protected]2f529812013-07-12 01:58:39252class FakeTextureLayerClient : public TextureLayerClient {
253 public:
[email protected]f5931d42013-11-06 19:44:57254 FakeTextureLayerClient() {}
[email protected]2f529812013-07-12 01:58:39255
256 virtual unsigned PrepareTexture() OVERRIDE {
[email protected]31d4df82013-07-18 10:17:22257 return 0;
[email protected]2f529812013-07-12 01:58:39258 }
259
[email protected]9260757f2013-09-17 01:24:16260 virtual bool PrepareTextureMailbox(
261 TextureMailbox* mailbox,
262 scoped_ptr<SingleReleaseCallback>* release_callback,
263 bool use_shared_memory) OVERRIDE {
[email protected]31d4df82013-07-18 10:17:22264 *mailbox = TextureMailbox();
[email protected]9260757f2013-09-17 01:24:16265 *release_callback = scoped_ptr<SingleReleaseCallback>();
[email protected]2f529812013-07-12 01:58:39266 return true;
267 }
268
269 private:
[email protected]2f529812013-07-12 01:58:39270 DISALLOW_COPY_AND_ASSIGN(FakeTextureLayerClient);
271};
272
[email protected]31d4df82013-07-18 10:17:22273TEST_F(TextureLayerTest, RateLimiter) {
274 FakeTextureLayerClient client;
275 scoped_refptr<TextureLayer> test_layer = TextureLayer::CreateForMailbox(
276 &client);
277 test_layer->SetIsDrawable(true);
278 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
279 layer_tree_host_->SetRootLayer(test_layer);
280
281 // Don't rate limit until we invalidate.
[email protected]aeeb3372013-11-05 14:05:54282 EXPECT_CALL(*layer_tree_host_, StartRateLimiter()).Times(0);
[email protected]31d4df82013-07-18 10:17:22283 test_layer->SetRateLimitContext(true);
284 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
285
286 // Do rate limit after we invalidate.
[email protected]aeeb3372013-11-05 14:05:54287 EXPECT_CALL(*layer_tree_host_, StartRateLimiter());
[email protected]31d4df82013-07-18 10:17:22288 test_layer->SetNeedsDisplay();
289 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
290
291 // Stop rate limiter when we don't want it any more.
[email protected]aeeb3372013-11-05 14:05:54292 EXPECT_CALL(*layer_tree_host_, StopRateLimiter());
[email protected]31d4df82013-07-18 10:17:22293 test_layer->SetRateLimitContext(false);
294 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
295
296 // Or we clear the client.
297 test_layer->SetRateLimitContext(true);
[email protected]aeeb3372013-11-05 14:05:54298 EXPECT_CALL(*layer_tree_host_, StopRateLimiter());
[email protected]31d4df82013-07-18 10:17:22299 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
300 test_layer->ClearClient();
301 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
302
303 // Reset to a layer with a client, that started the rate limiter.
304 test_layer = TextureLayer::CreateForMailbox(
305 &client);
306 test_layer->SetIsDrawable(true);
307 test_layer->SetRateLimitContext(true);
308 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
309 layer_tree_host_->SetRootLayer(test_layer);
[email protected]aeeb3372013-11-05 14:05:54310 EXPECT_CALL(*layer_tree_host_, StartRateLimiter()).Times(0);
[email protected]31d4df82013-07-18 10:17:22311 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
[email protected]aeeb3372013-11-05 14:05:54312 EXPECT_CALL(*layer_tree_host_, StartRateLimiter());
[email protected]31d4df82013-07-18 10:17:22313 test_layer->SetNeedsDisplay();
314 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
315
316 // Stop rate limiter when we're removed from the tree.
[email protected]aeeb3372013-11-05 14:05:54317 EXPECT_CALL(*layer_tree_host_, StopRateLimiter());
[email protected]31d4df82013-07-18 10:17:22318 layer_tree_host_->SetRootLayer(NULL);
319 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
320}
321
[email protected]de44a152013-01-08 15:28:46322class MockMailboxCallback {
[email protected]28571b042013-03-14 07:59:15323 public:
[email protected]df41e252014-02-03 23:39:50324 MOCK_METHOD3(Release,
325 void(const std::string& mailbox,
326 uint32 sync_point,
327 bool lost_resource));
328 MOCK_METHOD3(Release2,
329 void(base::SharedMemory* shared_memory,
330 uint32 sync_point,
331 bool lost_resource));
[email protected]de44a152013-01-08 15:28:46332};
333
334struct CommonMailboxObjects {
[email protected]28571b042013-03-14 07:59:15335 CommonMailboxObjects()
336 : mailbox_name1_(64, '1'),
337 mailbox_name2_(64, '2'),
338 sync_point1_(1),
[email protected]42f40a52013-06-08 04:38:51339 sync_point2_(2),
340 shared_memory_(new base::SharedMemory) {
[email protected]28571b042013-03-14 07:59:15341 release_mailbox1_ = base::Bind(&MockMailboxCallback::Release,
342 base::Unretained(&mock_callback_),
343 mailbox_name1_);
344 release_mailbox2_ = base::Bind(&MockMailboxCallback::Release,
345 base::Unretained(&mock_callback_),
346 mailbox_name2_);
[email protected]df41e252014-02-03 23:39:50347 const uint32 arbitrary_target1 = 1;
348 const uint32 arbitrary_target2 = 2;
349 mailbox1_ = TextureMailbox(
350 MailboxFromString(mailbox_name1_), arbitrary_target1, sync_point1_);
351 mailbox2_ = TextureMailbox(
352 MailboxFromString(mailbox_name2_), arbitrary_target2, sync_point2_);
[email protected]42f40a52013-06-08 04:38:51353 gfx::Size size(128, 128);
354 EXPECT_TRUE(shared_memory_->CreateAndMapAnonymous(4 * size.GetArea()));
355 release_mailbox3_ = base::Bind(&MockMailboxCallback::Release2,
356 base::Unretained(&mock_callback_),
357 shared_memory_.get());
[email protected]9260757f2013-09-17 01:24:16358 mailbox3_ = TextureMailbox(shared_memory_.get(), size);
[email protected]28571b042013-03-14 07:59:15359 }
[email protected]de44a152013-01-08 15:28:46360
[email protected]28571b042013-03-14 07:59:15361 std::string mailbox_name1_;
362 std::string mailbox_name2_;
363 MockMailboxCallback mock_callback_;
[email protected]9260757f2013-09-17 01:24:16364 ReleaseCallback release_mailbox1_;
365 ReleaseCallback release_mailbox2_;
366 ReleaseCallback release_mailbox3_;
[email protected]28571b042013-03-14 07:59:15367 TextureMailbox mailbox1_;
368 TextureMailbox mailbox2_;
[email protected]42f40a52013-06-08 04:38:51369 TextureMailbox mailbox3_;
[email protected]df41e252014-02-03 23:39:50370 uint32 sync_point1_;
371 uint32 sync_point2_;
[email protected]42f40a52013-06-08 04:38:51372 scoped_ptr<base::SharedMemory> shared_memory_;
[email protected]de44a152013-01-08 15:28:46373};
374
[email protected]df41e252014-02-03 23:39:50375class TestMailboxHolder : public TextureLayer::TextureMailboxHolder {
[email protected]9794fb32013-08-29 09:49:59376 public:
[email protected]df41e252014-02-03 23:39:50377 using TextureLayer::TextureMailboxHolder::Create;
[email protected]9794fb32013-08-29 09:49:59378
379 protected:
380 virtual ~TestMailboxHolder() {}
381};
382
[email protected]de44a152013-01-08 15:28:46383class TextureLayerWithMailboxTest : public TextureLayerTest {
[email protected]28571b042013-03-14 07:59:15384 protected:
385 virtual void TearDown() {
386 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
387 EXPECT_CALL(test_data_.mock_callback_,
388 Release(test_data_.mailbox_name1_,
[email protected]7ba3ca72013-04-11 06:37:25389 test_data_.sync_point1_,
390 false)).Times(1);
[email protected]28571b042013-03-14 07:59:15391 TextureLayerTest::TearDown();
392 }
[email protected]de44a152013-01-08 15:28:46393
[email protected]28571b042013-03-14 07:59:15394 CommonMailboxObjects test_data_;
[email protected]de44a152013-01-08 15:28:46395};
396
[email protected]28571b042013-03-14 07:59:15397TEST_F(TextureLayerWithMailboxTest, ReplaceMailboxOnMainThreadBeforeCommit) {
[email protected]e8e4ae232013-04-12 00:26:01398 scoped_refptr<TextureLayer> test_layer = TextureLayer::CreateForMailbox(NULL);
[email protected]22898ed2013-06-01 04:52:30399 ASSERT_TRUE(test_layer.get());
[email protected]de44a152013-01-08 15:28:46400
[email protected]28571b042013-03-14 07:59:15401 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
402 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
403 layer_tree_host_->SetRootLayer(test_layer);
404 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));
[email protected]9260757f2013-09-17 01:24:16408 test_layer->SetTextureMailbox(
409 test_data_.mailbox1_,
410 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
[email protected]28571b042013-03-14 07:59:15411 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
[email protected]de44a152013-01-08 15:28:46412
[email protected]28571b042013-03-14 07:59:15413 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
414 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
415 EXPECT_CALL(test_data_.mock_callback_,
[email protected]7ba3ca72013-04-11 06:37:25416 Release(test_data_.mailbox_name1_,
417 test_data_.sync_point1_,
418 false))
[email protected]28571b042013-03-14 07:59:15419 .Times(1);
[email protected]9260757f2013-09-17 01:24:16420 test_layer->SetTextureMailbox(
421 test_data_.mailbox2_,
422 SingleReleaseCallback::Create(test_data_.release_mailbox2_));
[email protected]28571b042013-03-14 07:59:15423 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
424 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]de44a152013-01-08 15:28:46425
[email protected]28571b042013-03-14 07:59:15426 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
427 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
428 EXPECT_CALL(test_data_.mock_callback_,
[email protected]7ba3ca72013-04-11 06:37:25429 Release(test_data_.mailbox_name2_,
430 test_data_.sync_point2_,
431 false))
[email protected]28571b042013-03-14 07:59:15432 .Times(1);
[email protected]9260757f2013-09-17 01:24:16433 test_layer->SetTextureMailbox(TextureMailbox(),
434 scoped_ptr<SingleReleaseCallback>());
[email protected]28571b042013-03-14 07:59:15435 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
436 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]de44a152013-01-08 15:28:46437
[email protected]80d42bd2013-08-30 19:13:45438 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
439 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
[email protected]9260757f2013-09-17 01:24:16440 test_layer->SetTextureMailbox(
441 test_data_.mailbox3_,
442 SingleReleaseCallback::Create(test_data_.release_mailbox3_));
[email protected]42f40a52013-06-08 04:38:51443 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
444 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
445
446 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
447 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
448 EXPECT_CALL(test_data_.mock_callback_,
449 Release2(test_data_.shared_memory_.get(),
450 0, false))
451 .Times(1);
[email protected]9260757f2013-09-17 01:24:16452 test_layer->SetTextureMailbox(TextureMailbox(),
453 scoped_ptr<SingleReleaseCallback>());
[email protected]42f40a52013-06-08 04:38:51454 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
455 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
456
[email protected]28571b042013-03-14 07:59:15457 // Test destructor.
458 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
[email protected]9260757f2013-09-17 01:24:16459 test_layer->SetTextureMailbox(
460 test_data_.mailbox1_,
461 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
[email protected]de44a152013-01-08 15:28:46462}
463
[email protected]9794fb32013-08-29 09:49:59464class TextureLayerMailboxHolderTest : public TextureLayerTest {
465 public:
466 TextureLayerMailboxHolderTest()
467 : main_thread_("MAIN") {
468 main_thread_.Start();
469 }
470
471 void Wait(const base::Thread& thread) {
472 bool manual_reset = false;
473 bool initially_signaled = false;
474 base::WaitableEvent event(manual_reset, initially_signaled);
475 thread.message_loop()->PostTask(
476 FROM_HERE,
477 base::Bind(&base::WaitableEvent::Signal, base::Unretained(&event)));
478 event.Wait();
479 }
480
481 void CreateMainRef() {
482 main_ref_ = TestMailboxHolder::Create(
[email protected]9260757f2013-09-17 01:24:16483 test_data_.mailbox1_,
484 SingleReleaseCallback::Create(test_data_.release_mailbox1_)).Pass();
[email protected]9794fb32013-08-29 09:49:59485 }
486
487 void ReleaseMainRef() {
488 main_ref_.reset();
489 }
490
[email protected]9260757f2013-09-17 01:24:16491 void CreateImplRef(scoped_ptr<SingleReleaseCallback>* impl_ref) {
[email protected]9794fb32013-08-29 09:49:59492 *impl_ref = main_ref_->holder()->GetCallbackForImplThread();
493 }
494
495 void CapturePostTasksAndWait(base::WaitableEvent* begin_capture,
496 base::WaitableEvent* wait_for_capture,
497 base::WaitableEvent* stop_capture) {
498 begin_capture->Wait();
499 BlockingTaskRunner::CapturePostTasks capture;
500 wait_for_capture->Signal();
501 stop_capture->Wait();
502 }
503
504 protected:
505 scoped_ptr<TestMailboxHolder::MainThreadReference>
506 main_ref_;
507 base::Thread main_thread_;
508 CommonMailboxObjects test_data_;
509};
510
511TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_BothReleaseThenMain) {
512 scoped_refptr<TextureLayer> test_layer = TextureLayer::CreateForMailbox(NULL);
513 ASSERT_TRUE(test_layer.get());
514
515 main_thread_.message_loop()->PostTask(
516 FROM_HERE,
517 base::Bind(&TextureLayerMailboxHolderTest::CreateMainRef,
518 base::Unretained(this)));
519
520 Wait(main_thread_);
521
522 // The texture layer is attached to compositor1, and passes a reference to its
523 // impl tree.
[email protected]9260757f2013-09-17 01:24:16524 scoped_ptr<SingleReleaseCallback> compositor1;
[email protected]9794fb32013-08-29 09:49:59525 main_thread_.message_loop()->PostTask(
526 FROM_HERE,
527 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
528 base::Unretained(this),
529 &compositor1));
530
531 // Then the texture layer is removed and attached to compositor2, and passes a
532 // reference to its impl tree.
[email protected]9260757f2013-09-17 01:24:16533 scoped_ptr<SingleReleaseCallback> compositor2;
[email protected]9794fb32013-08-29 09:49:59534 main_thread_.message_loop()->PostTask(
535 FROM_HERE,
536 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
537 base::Unretained(this),
538 &compositor2));
539
540 Wait(main_thread_);
541 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
542
543 // The compositors both destroy their impl trees before the main thread layer
544 // is destroyed.
[email protected]9260757f2013-09-17 01:24:16545 compositor1->Run(100, false);
546 compositor2->Run(200, false);
[email protected]9794fb32013-08-29 09:49:59547
548 Wait(main_thread_);
549
550 EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0);
551 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
552
553 // The main thread ref is the last one, so the mailbox is released back to the
554 // embedder, with the last sync point provided by the impl trees.
555 EXPECT_CALL(test_data_.mock_callback_,
556 Release(test_data_.mailbox_name1_, 200, false)).Times(1);
557
558 main_thread_.message_loop()->PostTask(
559 FROM_HERE,
560 base::Bind(&TextureLayerMailboxHolderTest::ReleaseMainRef,
561 base::Unretained(this)));
562 Wait(main_thread_);
563 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
564}
565
566TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_MainReleaseBetween) {
567 scoped_refptr<TextureLayer> test_layer = TextureLayer::CreateForMailbox(NULL);
568 ASSERT_TRUE(test_layer.get());
569
570 main_thread_.message_loop()->PostTask(
571 FROM_HERE,
572 base::Bind(&TextureLayerMailboxHolderTest::CreateMainRef,
573 base::Unretained(this)));
574
575 Wait(main_thread_);
576
577 // The texture layer is attached to compositor1, and passes a reference to its
578 // impl tree.
[email protected]9260757f2013-09-17 01:24:16579 scoped_ptr<SingleReleaseCallback> compositor1;
[email protected]9794fb32013-08-29 09:49:59580 main_thread_.message_loop()->PostTask(
581 FROM_HERE,
582 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
583 base::Unretained(this),
584 &compositor1));
585
586 // Then the texture layer is removed and attached to compositor2, and passes a
587 // reference to its impl tree.
[email protected]9260757f2013-09-17 01:24:16588 scoped_ptr<SingleReleaseCallback> compositor2;
[email protected]9794fb32013-08-29 09:49:59589 main_thread_.message_loop()->PostTask(
590 FROM_HERE,
591 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
592 base::Unretained(this),
593 &compositor2));
594
595 Wait(main_thread_);
596 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
597
598 // One compositor destroys their impl tree.
[email protected]9260757f2013-09-17 01:24:16599 compositor1->Run(100, false);
[email protected]9794fb32013-08-29 09:49:59600
601 // Then the main thread reference is destroyed.
602 main_thread_.message_loop()->PostTask(
603 FROM_HERE,
604 base::Bind(&TextureLayerMailboxHolderTest::ReleaseMainRef,
605 base::Unretained(this)));
606
607 Wait(main_thread_);
608
609 EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0);
610 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
611
612 // The second impl reference is destroyed last, causing the mailbox to be
613 // released back to the embedder with the last sync point from the impl tree.
614 EXPECT_CALL(test_data_.mock_callback_,
615 Release(test_data_.mailbox_name1_, 200, true)).Times(1);
616
[email protected]9260757f2013-09-17 01:24:16617 compositor2->Run(200, true);
[email protected]9794fb32013-08-29 09:49:59618 Wait(main_thread_);
619 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
620}
621
622TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_MainReleasedFirst) {
623 scoped_refptr<TextureLayer> test_layer = TextureLayer::CreateForMailbox(NULL);
624 ASSERT_TRUE(test_layer.get());
625
626 main_thread_.message_loop()->PostTask(
627 FROM_HERE,
628 base::Bind(&TextureLayerMailboxHolderTest::CreateMainRef,
629 base::Unretained(this)));
630
631 Wait(main_thread_);
632
633 // The texture layer is attached to compositor1, and passes a reference to its
634 // impl tree.
[email protected]9260757f2013-09-17 01:24:16635 scoped_ptr<SingleReleaseCallback> compositor1;
[email protected]9794fb32013-08-29 09:49:59636 main_thread_.message_loop()->PostTask(
637 FROM_HERE,
638 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
639 base::Unretained(this),
640 &compositor1));
641
642 // Then the texture layer is removed and attached to compositor2, and passes a
643 // reference to its impl tree.
[email protected]9260757f2013-09-17 01:24:16644 scoped_ptr<SingleReleaseCallback> compositor2;
[email protected]9794fb32013-08-29 09:49:59645 main_thread_.message_loop()->PostTask(
646 FROM_HERE,
647 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
648 base::Unretained(this),
649 &compositor2));
650
651 Wait(main_thread_);
652 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
653
654 // The main thread reference is destroyed first.
655 main_thread_.message_loop()->PostTask(
656 FROM_HERE,
657 base::Bind(&TextureLayerMailboxHolderTest::ReleaseMainRef,
658 base::Unretained(this)));
659
660 // One compositor destroys their impl tree.
[email protected]9260757f2013-09-17 01:24:16661 compositor2->Run(200, false);
[email protected]9794fb32013-08-29 09:49:59662
663 Wait(main_thread_);
664
665 EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0);
666 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
667
668 // The second impl reference is destroyed last, causing the mailbox to be
669 // released back to the embedder with the last sync point from the impl tree.
670 EXPECT_CALL(test_data_.mock_callback_,
671 Release(test_data_.mailbox_name1_, 100, true)).Times(1);
672
[email protected]9260757f2013-09-17 01:24:16673 compositor1->Run(100, true);
[email protected]9794fb32013-08-29 09:49:59674 Wait(main_thread_);
675 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
676}
677
678TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_SecondImplRefShortcut) {
679 scoped_refptr<TextureLayer> test_layer = TextureLayer::CreateForMailbox(NULL);
680 ASSERT_TRUE(test_layer.get());
681
682 main_thread_.message_loop()->PostTask(
683 FROM_HERE,
684 base::Bind(&TextureLayerMailboxHolderTest::CreateMainRef,
685 base::Unretained(this)));
686
687 Wait(main_thread_);
688
689 // The texture layer is attached to compositor1, and passes a reference to its
690 // impl tree.
[email protected]9260757f2013-09-17 01:24:16691 scoped_ptr<SingleReleaseCallback> compositor1;
[email protected]9794fb32013-08-29 09:49:59692 main_thread_.message_loop()->PostTask(
693 FROM_HERE,
694 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
695 base::Unretained(this),
696 &compositor1));
697
698 // Then the texture layer is removed and attached to compositor2, and passes a
699 // reference to its impl tree.
[email protected]9260757f2013-09-17 01:24:16700 scoped_ptr<SingleReleaseCallback> compositor2;
[email protected]9794fb32013-08-29 09:49:59701 main_thread_.message_loop()->PostTask(
702 FROM_HERE,
703 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
704 base::Unretained(this),
705 &compositor2));
706
707 Wait(main_thread_);
708 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
709
710 // The main thread reference is destroyed first.
711 main_thread_.message_loop()->PostTask(
712 FROM_HERE,
713 base::Bind(&TextureLayerMailboxHolderTest::ReleaseMainRef,
714 base::Unretained(this)));
715
716 EXPECT_CALL(test_data_.mock_callback_,
717 Release(test_data_.mailbox_name1_, 200, true)).Times(1);
718
719 bool manual_reset = false;
720 bool initially_signaled = false;
721 base::WaitableEvent begin_capture(manual_reset, initially_signaled);
722 base::WaitableEvent wait_for_capture(manual_reset, initially_signaled);
723 base::WaitableEvent stop_capture(manual_reset, initially_signaled);
724
725 // Post a task to start capturing tasks on the main thread. This will block
726 // the main thread until we signal the |stop_capture| event.
727 main_thread_.message_loop()->PostTask(
728 FROM_HERE,
729 base::Bind(&TextureLayerMailboxHolderTest::CapturePostTasksAndWait,
730 base::Unretained(this),
731 &begin_capture,
732 &wait_for_capture,
733 &stop_capture));
734
735 // Before the main thread capturing starts, one compositor destroys their
736 // impl reference. Since capturing did not start, this gets post-tasked to
737 // the main thread.
[email protected]9260757f2013-09-17 01:24:16738 compositor1->Run(100, false);
[email protected]9794fb32013-08-29 09:49:59739
740 // Start capturing on the main thread.
741 begin_capture.Signal();
742 wait_for_capture.Wait();
743
744 // Meanwhile, the second compositor released its impl reference, but this task
745 // gets shortcutted directly to the main thread. This means the reference is
746 // released before compositor1, whose reference will be released later when
747 // the post-task is serviced. But since it was destroyed _on the impl thread_
748 // last, its sync point values should be used.
[email protected]9260757f2013-09-17 01:24:16749 compositor2->Run(200, true);
[email protected]9794fb32013-08-29 09:49:59750
751 stop_capture.Signal();
752 Wait(main_thread_);
753
754 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
755}
756
[email protected]e216fef02013-03-20 22:56:10757class TextureLayerImplWithMailboxThreadedCallback : public LayerTreeTest {
[email protected]28571b042013-03-14 07:59:15758 public:
759 TextureLayerImplWithMailboxThreadedCallback()
760 : callback_count_(0),
761 commit_count_(0) {}
762
763 // Make sure callback is received on main and doesn't block the impl thread.
[email protected]df41e252014-02-03 23:39:50764 void ReleaseCallback(uint32 sync_point, bool lost_resource) {
[email protected]9794fb32013-08-29 09:49:59765 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]7ba3ca72013-04-11 06:37:25766 EXPECT_FALSE(lost_resource);
[email protected]28571b042013-03-14 07:59:15767 ++callback_count_;
768 }
769
770 void SetMailbox(char mailbox_char) {
[email protected]9794fb32013-08-29 09:49:59771 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]9260757f2013-09-17 01:24:16772 scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create(
[email protected]28571b042013-03-14 07:59:15773 base::Bind(
774 &TextureLayerImplWithMailboxThreadedCallback::ReleaseCallback,
775 base::Unretained(this)));
[email protected]df41e252014-02-03 23:39:50776 layer_->SetTextureMailbox(
777 TextureMailbox(
778 MailboxFromString(std::string(64, mailbox_char)), GL_TEXTURE_2D, 0),
779 callback.Pass());
[email protected]28571b042013-03-14 07:59:15780 }
781
[email protected]e216fef02013-03-20 22:56:10782 virtual void BeginTest() OVERRIDE {
[email protected]9794fb32013-08-29 09:49:59783 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
784
[email protected]28571b042013-03-14 07:59:15785 gfx::Size bounds(100, 100);
786 root_ = Layer::Create();
787 root_->SetAnchorPoint(gfx::PointF());
788 root_->SetBounds(bounds);
789
[email protected]e8e4ae232013-04-12 00:26:01790 layer_ = TextureLayer::CreateForMailbox(NULL);
[email protected]28571b042013-03-14 07:59:15791 layer_->SetIsDrawable(true);
792 layer_->SetAnchorPoint(gfx::PointF());
793 layer_->SetBounds(bounds);
794
795 root_->AddChild(layer_);
[email protected]e216fef02013-03-20 22:56:10796 layer_tree_host()->SetRootLayer(root_);
[email protected]18ce59702013-04-09 04:58:40797 layer_tree_host()->SetViewportSize(bounds);
[email protected]28571b042013-03-14 07:59:15798 SetMailbox('1');
799 EXPECT_EQ(0, callback_count_);
800
801 // Case #1: change mailbox before the commit. The old mailbox should be
802 // released immediately.
803 SetMailbox('2');
804 EXPECT_EQ(1, callback_count_);
[email protected]e216fef02013-03-20 22:56:10805 PostSetNeedsCommitToMainThread();
[email protected]28571b042013-03-14 07:59:15806 }
807
[email protected]e216fef02013-03-20 22:56:10808 virtual void DidCommit() OVERRIDE {
[email protected]28571b042013-03-14 07:59:15809 ++commit_count_;
810 switch (commit_count_) {
811 case 1:
812 // Case #2: change mailbox after the commit (and draw), where the
813 // layer draws. The old mailbox should be released during the next
814 // commit.
815 SetMailbox('3');
816 EXPECT_EQ(1, callback_count_);
817 break;
818 case 2:
[email protected]28571b042013-03-14 07:59:15819 EXPECT_EQ(2, callback_count_);
820 // Case #3: change mailbox when the layer doesn't draw. The old
821 // mailbox should be released during the next commit.
822 layer_->SetBounds(gfx::Size());
823 SetMailbox('4');
824 break;
[email protected]9794fb32013-08-29 09:49:59825 case 3:
[email protected]28571b042013-03-14 07:59:15826 EXPECT_EQ(3, callback_count_);
827 // Case #4: release mailbox that was committed but never drawn. The
828 // old mailbox should be released during the next commit.
[email protected]9260757f2013-09-17 01:24:16829 layer_->SetTextureMailbox(TextureMailbox(),
830 scoped_ptr<SingleReleaseCallback>());
[email protected]28571b042013-03-14 07:59:15831 break;
[email protected]9794fb32013-08-29 09:49:59832 case 4:
833 if (layer_tree_host()->settings().impl_side_painting) {
834 // With impl painting, the texture mailbox will still be on the impl
835 // thread when the commit finishes, because the layer is not drawble
836 // when it has no texture mailbox, and thus does not block the commit
837 // on activation. So, we wait for activation.
838 // TODO(danakj): fix this. crbug.com/277953
839 layer_tree_host()->SetNeedsCommit();
840 break;
841 } else {
842 ++commit_count_;
843 }
844 case 5:
[email protected]28571b042013-03-14 07:59:15845 EXPECT_EQ(4, callback_count_);
[email protected]7096acc2013-06-18 21:12:43846 // Restore a mailbox for the next step.
847 SetMailbox('5');
848 break;
[email protected]9794fb32013-08-29 09:49:59849 case 6:
[email protected]7096acc2013-06-18 21:12:43850 // Case #5: remove layer from tree. Callback should *not* be called, the
851 // mailbox is returned to the main thread.
852 EXPECT_EQ(4, callback_count_);
853 layer_->RemoveFromParent();
854 break;
[email protected]9794fb32013-08-29 09:49:59855 case 7:
856 if (layer_tree_host()->settings().impl_side_painting) {
857 // With impl painting, the texture mailbox will still be on the impl
858 // thread when the commit finishes, because the layer is not around to
859 // block the commit on activation anymore. So, we wait for activation.
860 // TODO(danakj): fix this. crbug.com/277953
861 layer_tree_host()->SetNeedsCommit();
862 break;
863 } else {
864 ++commit_count_;
865 }
866 case 8:
[email protected]7096acc2013-06-18 21:12:43867 EXPECT_EQ(4, callback_count_);
868 // Resetting the mailbox will call the callback now.
[email protected]9260757f2013-09-17 01:24:16869 layer_->SetTextureMailbox(TextureMailbox(),
870 scoped_ptr<SingleReleaseCallback>());
[email protected]7096acc2013-06-18 21:12:43871 EXPECT_EQ(5, callback_count_);
[email protected]e216fef02013-03-20 22:56:10872 EndTest();
[email protected]28571b042013-03-14 07:59:15873 break;
874 default:
875 NOTREACHED();
876 break;
[email protected]de44a152013-01-08 15:28:46877 }
[email protected]28571b042013-03-14 07:59:15878 }
[email protected]de44a152013-01-08 15:28:46879
[email protected]e216fef02013-03-20 22:56:10880 virtual void AfterTest() OVERRIDE {}
[email protected]de44a152013-01-08 15:28:46881
[email protected]28571b042013-03-14 07:59:15882 private:
[email protected]9794fb32013-08-29 09:49:59883 base::ThreadChecker main_thread_;
[email protected]28571b042013-03-14 07:59:15884 int callback_count_;
885 int commit_count_;
886 scoped_refptr<Layer> root_;
887 scoped_refptr<TextureLayer> layer_;
[email protected]de44a152013-01-08 15:28:46888};
889
[email protected]4145d172013-05-10 16:54:36890SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
891 TextureLayerImplWithMailboxThreadedCallback);
[email protected]de44a152013-01-08 15:28:46892
[email protected]74b43cc2013-08-30 06:29:27893
894class TextureLayerNoMailboxIsActivatedDuringCommit : public LayerTreeTest,
895 public TextureLayerClient {
896 protected:
897 TextureLayerNoMailboxIsActivatedDuringCommit()
[email protected]98ea818e2014-01-24 10:22:08898 : texture_(0u), activate_count_(0) {}
[email protected]74b43cc2013-08-30 06:29:27899
900 virtual void BeginTest() OVERRIDE {
[email protected]74b43cc2013-08-30 06:29:27901 gfx::Size bounds(100, 100);
902 root_ = Layer::Create();
903 root_->SetAnchorPoint(gfx::PointF());
904 root_->SetBounds(bounds);
905
906 layer_ = TextureLayer::Create(this);
907 layer_->SetIsDrawable(true);
908 layer_->SetAnchorPoint(gfx::PointF());
909 layer_->SetBounds(bounds);
910
911 root_->AddChild(layer_);
912 layer_tree_host()->SetRootLayer(root_);
913 layer_tree_host()->SetViewportSize(bounds);
914
915 PostSetNeedsCommitToMainThread();
916 }
917
[email protected]a6366932014-02-05 20:12:47918 virtual scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface(bool fallback)
[email protected]f5931d42013-11-06 19:44:57919 OVERRIDE {
920 scoped_refptr<TestContextProvider> provider = TestContextProvider::Create();
921 texture_ = provider->UnboundTestContext3d()->createExternalTexture();
[email protected]a6366932014-02-05 20:12:47922 return FakeOutputSurface::Create3d(provider);
[email protected]f5931d42013-11-06 19:44:57923 }
924
[email protected]74b43cc2013-08-30 06:29:27925 // TextureLayerClient implementation.
926 virtual unsigned PrepareTexture() OVERRIDE {
[email protected]f5931d42013-11-06 19:44:57927 return texture_;
[email protected]74b43cc2013-08-30 06:29:27928 }
[email protected]9260757f2013-09-17 01:24:16929 virtual bool PrepareTextureMailbox(
930 TextureMailbox* mailbox,
931 scoped_ptr<SingleReleaseCallback>* release_callback,
932 bool use_shared_memory) OVERRIDE {
[email protected]74b43cc2013-08-30 06:29:27933 return false;
934 }
935
936 virtual void WillActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
[email protected]74b43cc2013-08-30 06:29:27937 ++activate_count_;
938 }
939
[email protected]98ea818e2014-01-24 10:22:08940 virtual void DidCommit() OVERRIDE {
941 switch (layer_tree_host()->source_frame_number()) {
[email protected]74b43cc2013-08-30 06:29:27942 case 1:
943 // The first texture has been activated. Invalidate the layer so it
944 // grabs a new texture id from the client.
945 layer_->SetNeedsDisplay();
[email protected]74b43cc2013-08-30 06:29:27946 break;
947 case 2:
948 // The second mailbox has been activated. Remove the layer from
949 // the tree to cause another commit/activation. The commit should
950 // finish *after* the layer is removed from the active tree.
951 layer_->RemoveFromParent();
[email protected]74b43cc2013-08-30 06:29:27952 break;
953 case 3:
954 EndTest();
955 break;
956 }
957 }
958
[email protected]98ea818e2014-01-24 10:22:08959 virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
960 switch (host_impl->active_tree()->source_frame_number()) {
[email protected]74b43cc2013-08-30 06:29:27961 case 2: {
962 // The activate for the 2nd texture should have happened before now.
[email protected]74b43cc2013-08-30 06:29:27963 EXPECT_EQ(2, activate_count_);
964 break;
965 }
966 case 3: {
967 // The activate to remove the layer should have happened before now.
[email protected]74b43cc2013-08-30 06:29:27968 EXPECT_EQ(3, activate_count_);
969 break;
970 }
971 }
972 }
973
[email protected]74b43cc2013-08-30 06:29:27974 virtual void AfterTest() OVERRIDE {}
975
[email protected]f5931d42013-11-06 19:44:57976 unsigned texture_;
[email protected]74b43cc2013-08-30 06:29:27977 int activate_count_;
[email protected]74b43cc2013-08-30 06:29:27978 scoped_refptr<Layer> root_;
979 scoped_refptr<TextureLayer> layer_;
980};
981
982SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
983 TextureLayerNoMailboxIsActivatedDuringCommit);
984
985class TextureLayerMailboxIsActivatedDuringCommit : public LayerTreeTest {
986 protected:
[email protected]98ea818e2014-01-24 10:22:08987 TextureLayerMailboxIsActivatedDuringCommit() : activate_count_(0) {}
[email protected]74b43cc2013-08-30 06:29:27988
[email protected]df41e252014-02-03 23:39:50989 static void ReleaseCallback(uint32 sync_point, bool lost_resource) {}
[email protected]74b43cc2013-08-30 06:29:27990
991 void SetMailbox(char mailbox_char) {
[email protected]9260757f2013-09-17 01:24:16992 scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create(
[email protected]74b43cc2013-08-30 06:29:27993 base::Bind(
994 &TextureLayerMailboxIsActivatedDuringCommit::ReleaseCallback));
[email protected]df41e252014-02-03 23:39:50995 layer_->SetTextureMailbox(
996 TextureMailbox(
997 MailboxFromString(std::string(64, mailbox_char)), GL_TEXTURE_2D, 0),
998 callback.Pass());
[email protected]74b43cc2013-08-30 06:29:27999 }
1000
1001 virtual void BeginTest() OVERRIDE {
[email protected]74b43cc2013-08-30 06:29:271002 gfx::Size bounds(100, 100);
1003 root_ = Layer::Create();
1004 root_->SetAnchorPoint(gfx::PointF());
1005 root_->SetBounds(bounds);
1006
1007 layer_ = TextureLayer::CreateForMailbox(NULL);
1008 layer_->SetIsDrawable(true);
1009 layer_->SetAnchorPoint(gfx::PointF());
1010 layer_->SetBounds(bounds);
1011
1012 root_->AddChild(layer_);
1013 layer_tree_host()->SetRootLayer(root_);
1014 layer_tree_host()->SetViewportSize(bounds);
1015 SetMailbox('1');
1016
1017 PostSetNeedsCommitToMainThread();
1018 }
1019
1020 virtual void WillActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
[email protected]74b43cc2013-08-30 06:29:271021 ++activate_count_;
1022 }
1023
[email protected]98ea818e2014-01-24 10:22:081024 virtual void DidCommit() OVERRIDE {
1025 switch (layer_tree_host()->source_frame_number()) {
[email protected]74b43cc2013-08-30 06:29:271026 case 1:
1027 // The first mailbox has been activated. Set a new mailbox, and
1028 // expect the next commit to finish *after* it is activated.
1029 SetMailbox('2');
[email protected]74b43cc2013-08-30 06:29:271030 break;
1031 case 2:
1032 // The second mailbox has been activated. Remove the layer from
1033 // the tree to cause another commit/activation. The commit should
1034 // finish *after* the layer is removed from the active tree.
1035 layer_->RemoveFromParent();
[email protected]74b43cc2013-08-30 06:29:271036 break;
1037 case 3:
1038 EndTest();
1039 break;
1040 }
1041 }
1042
[email protected]98ea818e2014-01-24 10:22:081043 virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
1044 switch (host_impl->active_tree()->source_frame_number()) {
[email protected]74b43cc2013-08-30 06:29:271045 case 2: {
1046 // The activate for the 2nd mailbox should have happened before now.
[email protected]74b43cc2013-08-30 06:29:271047 EXPECT_EQ(2, activate_count_);
1048 break;
1049 }
1050 case 3: {
1051 // The activate to remove the layer should have happened before now.
[email protected]74b43cc2013-08-30 06:29:271052 EXPECT_EQ(3, activate_count_);
1053 break;
1054 }
1055 }
1056 }
1057
1058
1059 virtual void AfterTest() OVERRIDE {}
1060
[email protected]74b43cc2013-08-30 06:29:271061 int activate_count_;
1062 scoped_refptr<Layer> root_;
1063 scoped_refptr<TextureLayer> layer_;
1064};
1065
1066SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
1067 TextureLayerMailboxIsActivatedDuringCommit);
1068
[email protected]de44a152013-01-08 15:28:461069class TextureLayerImplWithMailboxTest : public TextureLayerTest {
[email protected]28571b042013-03-14 07:59:151070 protected:
[email protected]408b5e22013-03-19 09:48:091071 TextureLayerImplWithMailboxTest()
1072 : fake_client_(
1073 FakeLayerTreeHostClient(FakeLayerTreeHostClient::DIRECT_3D)) {}
1074
[email protected]28571b042013-03-14 07:59:151075 virtual void SetUp() {
1076 TextureLayerTest::SetUp();
[email protected]408b5e22013-03-19 09:48:091077 layer_tree_host_.reset(new MockLayerTreeHost(&fake_client_));
[email protected]a6366932014-02-05 20:12:471078 EXPECT_TRUE(host_impl_.InitializeRenderer(
1079 FakeOutputSurface::Create3d().PassAs<OutputSurface>()));
[email protected]28571b042013-03-14 07:59:151080 }
[email protected]de44a152013-01-08 15:28:461081
[email protected]0ec335c42013-07-04 06:17:081082 bool WillDraw(TextureLayerImpl* layer, DrawMode mode) {
1083 bool will_draw = layer->WillDraw(
1084 mode, host_impl_.active_tree()->resource_provider());
1085 if (will_draw)
1086 layer->DidDraw(host_impl_.active_tree()->resource_provider());
1087 return will_draw;
1088 }
1089
[email protected]28571b042013-03-14 07:59:151090 CommonMailboxObjects test_data_;
[email protected]408b5e22013-03-19 09:48:091091 FakeLayerTreeHostClient fake_client_;
[email protected]de44a152013-01-08 15:28:461092};
1093
[email protected]ffbb2212013-06-02 23:47:591094// Test conditions for results of TextureLayerImpl::WillDraw under
1095// different configurations of different mailbox, texture_id, and draw_mode.
1096TEST_F(TextureLayerImplWithMailboxTest, TestWillDraw) {
[email protected]0ec335c42013-07-04 06:17:081097 EXPECT_CALL(test_data_.mock_callback_,
1098 Release(test_data_.mailbox_name1_,
1099 test_data_.sync_point1_,
1100 false))
1101 .Times(AnyNumber());
1102 EXPECT_CALL(test_data_.mock_callback_,
1103 Release2(test_data_.shared_memory_.get(), 0, false))
1104 .Times(AnyNumber());
[email protected]ffbb2212013-06-02 23:47:591105 // Hardware mode.
1106 {
1107 scoped_ptr<TextureLayerImpl> impl_layer =
1108 TextureLayerImpl::Create(host_impl_.active_tree(), 1, true);
[email protected]afc4f262013-10-05 01:14:101109 impl_layer->SetDrawsContent(true);
[email protected]9260757f2013-09-17 01:24:161110 impl_layer->SetTextureMailbox(
1111 test_data_.mailbox1_,
1112 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
[email protected]0ec335c42013-07-04 06:17:081113 EXPECT_TRUE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE));
[email protected]ffbb2212013-06-02 23:47:591114 }
1115
1116 {
1117 scoped_ptr<TextureLayerImpl> impl_layer =
1118 TextureLayerImpl::Create(host_impl_.active_tree(), 1, true);
[email protected]afc4f262013-10-05 01:14:101119 impl_layer->SetDrawsContent(true);
[email protected]9260757f2013-09-17 01:24:161120 impl_layer->SetTextureMailbox(TextureMailbox(),
1121 scoped_ptr<SingleReleaseCallback>());
[email protected]0ec335c42013-07-04 06:17:081122 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE));
1123 }
1124
1125 {
1126 // Software resource.
1127 scoped_ptr<TextureLayerImpl> impl_layer =
1128 TextureLayerImpl::Create(host_impl_.active_tree(), 1, true);
[email protected]afc4f262013-10-05 01:14:101129 impl_layer->SetDrawsContent(true);
[email protected]9260757f2013-09-17 01:24:161130 impl_layer->SetTextureMailbox(
1131 test_data_.mailbox3_,
1132 SingleReleaseCallback::Create(test_data_.release_mailbox3_));
[email protected]3e44d7a2013-07-30 00:03:101133 EXPECT_TRUE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE));
[email protected]ffbb2212013-06-02 23:47:591134 }
1135
1136 {
1137 scoped_ptr<TextureLayerImpl> impl_layer =
1138 TextureLayerImpl::Create(host_impl_.active_tree(), 1, false);
[email protected]afc4f262013-10-05 01:14:101139 impl_layer->SetDrawsContent(true);
[email protected]0634cdd42013-08-16 00:46:091140 ContextProvider* context_provider =
1141 host_impl_.output_surface()->context_provider();
[email protected]1dff7962014-01-10 12:05:031142 GLuint texture = 0;
1143 context_provider->ContextGL()->GenTextures(1, &texture);
[email protected]ad0250b2014-01-18 03:24:341144 impl_layer->SetTextureId(texture);
[email protected]0ec335c42013-07-04 06:17:081145 EXPECT_TRUE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE));
[email protected]ffbb2212013-06-02 23:47:591146 }
1147
1148 {
1149 scoped_ptr<TextureLayerImpl> impl_layer =
1150 TextureLayerImpl::Create(host_impl_.active_tree(), 1, false);
[email protected]afc4f262013-10-05 01:14:101151 impl_layer->SetDrawsContent(true);
[email protected]ad0250b2014-01-18 03:24:341152 impl_layer->SetTextureId(0);
[email protected]0ec335c42013-07-04 06:17:081153 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE));
1154 }
1155
1156 // Software mode.
1157 {
1158 scoped_ptr<TextureLayerImpl> impl_layer =
1159 TextureLayerImpl::Create(host_impl_.active_tree(), 1, true);
[email protected]afc4f262013-10-05 01:14:101160 impl_layer->SetDrawsContent(true);
[email protected]9260757f2013-09-17 01:24:161161 impl_layer->SetTextureMailbox(
1162 test_data_.mailbox1_,
1163 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
[email protected]0ec335c42013-07-04 06:17:081164 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE));
1165 }
1166
1167 {
1168 scoped_ptr<TextureLayerImpl> impl_layer =
1169 TextureLayerImpl::Create(host_impl_.active_tree(), 1, true);
[email protected]afc4f262013-10-05 01:14:101170 impl_layer->SetDrawsContent(true);
[email protected]9260757f2013-09-17 01:24:161171 impl_layer->SetTextureMailbox(TextureMailbox(),
1172 scoped_ptr<SingleReleaseCallback>());
[email protected]0ec335c42013-07-04 06:17:081173 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE));
1174 }
1175
1176 {
1177 // Software resource.
1178 scoped_ptr<TextureLayerImpl> impl_layer =
1179 TextureLayerImpl::Create(host_impl_.active_tree(), 1, true);
[email protected]afc4f262013-10-05 01:14:101180 impl_layer->SetDrawsContent(true);
[email protected]9260757f2013-09-17 01:24:161181 impl_layer->SetTextureMailbox(
1182 test_data_.mailbox3_,
1183 SingleReleaseCallback::Create(test_data_.release_mailbox3_));
[email protected]0ec335c42013-07-04 06:17:081184 EXPECT_TRUE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE));
1185 }
1186
1187 {
1188 scoped_ptr<TextureLayerImpl> impl_layer =
1189 TextureLayerImpl::Create(host_impl_.active_tree(), 1, false);
[email protected]afc4f262013-10-05 01:14:101190 impl_layer->SetDrawsContent(true);
[email protected]0634cdd42013-08-16 00:46:091191 ContextProvider* context_provider =
1192 host_impl_.output_surface()->context_provider();
[email protected]1dff7962014-01-10 12:05:031193 GLuint texture = 0;
1194 context_provider->ContextGL()->GenTextures(1, &texture);
[email protected]ad0250b2014-01-18 03:24:341195 impl_layer->SetTextureId(texture);
[email protected]0ec335c42013-07-04 06:17:081196 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE));
1197 }
1198
1199 {
1200 scoped_ptr<TextureLayerImpl> impl_layer =
1201 TextureLayerImpl::Create(host_impl_.active_tree(), 1, false);
[email protected]afc4f262013-10-05 01:14:101202 impl_layer->SetDrawsContent(true);
[email protected]ad0250b2014-01-18 03:24:341203 impl_layer->SetTextureId(0);
[email protected]0ec335c42013-07-04 06:17:081204 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE));
[email protected]ffbb2212013-06-02 23:47:591205 }
1206
1207 // Resourceless software mode.
1208 {
1209 scoped_ptr<TextureLayerImpl> impl_layer =
1210 TextureLayerImpl::Create(host_impl_.active_tree(), 1, true);
[email protected]afc4f262013-10-05 01:14:101211 impl_layer->SetDrawsContent(true);
[email protected]9260757f2013-09-17 01:24:161212 impl_layer->SetTextureMailbox(
1213 test_data_.mailbox1_,
1214 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
[email protected]0ec335c42013-07-04 06:17:081215 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_RESOURCELESS_SOFTWARE));
[email protected]ffbb2212013-06-02 23:47:591216 }
1217
1218 {
1219 scoped_ptr<TextureLayerImpl> impl_layer =
1220 TextureLayerImpl::Create(host_impl_.active_tree(), 1, false);
[email protected]afc4f262013-10-05 01:14:101221 impl_layer->SetDrawsContent(true);
[email protected]0634cdd42013-08-16 00:46:091222 ContextProvider* context_provider =
1223 host_impl_.output_surface()->context_provider();
[email protected]1dff7962014-01-10 12:05:031224 GLuint texture = 0;
1225 context_provider->ContextGL()->GenTextures(1, &texture);
[email protected]ad0250b2014-01-18 03:24:341226 impl_layer->SetTextureId(texture);
[email protected]0ec335c42013-07-04 06:17:081227 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_RESOURCELESS_SOFTWARE));
[email protected]ffbb2212013-06-02 23:47:591228 }
1229}
1230
[email protected]28571b042013-03-14 07:59:151231TEST_F(TextureLayerImplWithMailboxTest, TestImplLayerCallbacks) {
1232 host_impl_.CreatePendingTree();
1233 scoped_ptr<TextureLayerImpl> pending_layer;
1234 pending_layer = TextureLayerImpl::Create(host_impl_.pending_tree(), 1, true);
1235 ASSERT_TRUE(pending_layer);
[email protected]de44a152013-01-08 15:28:461236
[email protected]ed511b8d2013-03-25 03:29:291237 scoped_ptr<LayerImpl> active_layer(
[email protected]28571b042013-03-14 07:59:151238 pending_layer->CreateLayerImpl(host_impl_.active_tree()));
[email protected]ed511b8d2013-03-25 03:29:291239 ASSERT_TRUE(active_layer);
[email protected]de44a152013-01-08 15:28:461240
[email protected]9260757f2013-09-17 01:24:161241 pending_layer->SetTextureMailbox(
1242 test_data_.mailbox1_,
1243 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
[email protected]421e84f2013-02-22 03:27:151244
[email protected]28571b042013-03-14 07:59:151245 // Test multiple commits without an activation.
1246 EXPECT_CALL(test_data_.mock_callback_,
[email protected]7ba3ca72013-04-11 06:37:251247 Release(test_data_.mailbox_name1_,
1248 test_data_.sync_point1_,
1249 false))
[email protected]28571b042013-03-14 07:59:151250 .Times(1);
[email protected]9260757f2013-09-17 01:24:161251 pending_layer->SetTextureMailbox(
1252 test_data_.mailbox2_,
1253 SingleReleaseCallback::Create(test_data_.release_mailbox2_));
[email protected]28571b042013-03-14 07:59:151254 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]421e84f2013-02-22 03:27:151255
[email protected]28571b042013-03-14 07:59:151256 // Test callback after activation.
[email protected]ed511b8d2013-03-25 03:29:291257 pending_layer->PushPropertiesTo(active_layer.get());
1258 active_layer->DidBecomeActive();
[email protected]421e84f2013-02-22 03:27:151259
[email protected]7ba3ca72013-04-11 06:37:251260 EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0);
[email protected]9260757f2013-09-17 01:24:161261 pending_layer->SetTextureMailbox(
1262 test_data_.mailbox1_,
1263 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
[email protected]28571b042013-03-14 07:59:151264 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]421e84f2013-02-22 03:27:151265
[email protected]7ba3ca72013-04-11 06:37:251266 EXPECT_CALL(test_data_.mock_callback_,
1267 Release(test_data_.mailbox_name2_, _, false))
[email protected]28571b042013-03-14 07:59:151268 .Times(1);
[email protected]ed511b8d2013-03-25 03:29:291269 pending_layer->PushPropertiesTo(active_layer.get());
1270 active_layer->DidBecomeActive();
[email protected]28571b042013-03-14 07:59:151271 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]de44a152013-01-08 15:28:461272
[email protected]28571b042013-03-14 07:59:151273 // Test resetting the mailbox.
[email protected]7ba3ca72013-04-11 06:37:251274 EXPECT_CALL(test_data_.mock_callback_,
1275 Release(test_data_.mailbox_name1_, _, false))
[email protected]28571b042013-03-14 07:59:151276 .Times(1);
[email protected]9260757f2013-09-17 01:24:161277 pending_layer->SetTextureMailbox(TextureMailbox(),
1278 scoped_ptr<SingleReleaseCallback>());
[email protected]ed511b8d2013-03-25 03:29:291279 pending_layer->PushPropertiesTo(active_layer.get());
1280 active_layer->DidBecomeActive();
[email protected]28571b042013-03-14 07:59:151281 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]de44a152013-01-08 15:28:461282
[email protected]28571b042013-03-14 07:59:151283 // Test destructor.
1284 EXPECT_CALL(test_data_.mock_callback_,
[email protected]7ba3ca72013-04-11 06:37:251285 Release(test_data_.mailbox_name1_,
1286 test_data_.sync_point1_,
1287 false))
[email protected]28571b042013-03-14 07:59:151288 .Times(1);
[email protected]9260757f2013-09-17 01:24:161289 pending_layer->SetTextureMailbox(
1290 test_data_.mailbox1_,
1291 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
[email protected]de44a152013-01-08 15:28:461292}
1293
[email protected]28571b042013-03-14 07:59:151294TEST_F(TextureLayerImplWithMailboxTest,
1295 TestDestructorCallbackOnCreatedResource) {
1296 scoped_ptr<TextureLayerImpl> impl_layer;
1297 impl_layer = TextureLayerImpl::Create(host_impl_.active_tree(), 1, true);
1298 ASSERT_TRUE(impl_layer);
[email protected]de44a152013-01-08 15:28:461299
[email protected]7ba3ca72013-04-11 06:37:251300 EXPECT_CALL(test_data_.mock_callback_,
1301 Release(test_data_.mailbox_name1_, _, false))
[email protected]28571b042013-03-14 07:59:151302 .Times(1);
[email protected]9260757f2013-09-17 01:24:161303 impl_layer->SetTextureMailbox(
1304 test_data_.mailbox1_,
1305 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
[email protected]afc4f262013-10-05 01:14:101306 impl_layer->SetDrawsContent(true);
[email protected]ffbb2212013-06-02 23:47:591307 impl_layer->DidBecomeActive();
1308 EXPECT_TRUE(impl_layer->WillDraw(
1309 DRAW_MODE_HARDWARE, host_impl_.active_tree()->resource_provider()));
[email protected]28571b042013-03-14 07:59:151310 impl_layer->DidDraw(host_impl_.active_tree()->resource_provider());
[email protected]9260757f2013-09-17 01:24:161311 impl_layer->SetTextureMailbox(TextureMailbox(),
1312 scoped_ptr<SingleReleaseCallback>());
[email protected]de44a152013-01-08 15:28:461313}
1314
[email protected]28571b042013-03-14 07:59:151315TEST_F(TextureLayerImplWithMailboxTest, TestCallbackOnInUseResource) {
1316 ResourceProvider* provider = host_impl_.active_tree()->resource_provider();
1317 ResourceProvider::ResourceId id =
[email protected]9260757f2013-09-17 01:24:161318 provider->CreateResourceFromTextureMailbox(
1319 test_data_.mailbox1_,
1320 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
[email protected]28571b042013-03-14 07:59:151321 provider->AllocateForTesting(id);
[email protected]de44a152013-01-08 15:28:461322
[email protected]28571b042013-03-14 07:59:151323 // Transfer some resources to the parent.
1324 ResourceProvider::ResourceIdArray resource_ids_to_transfer;
1325 resource_ids_to_transfer.push_back(id);
1326 TransferableResourceArray list;
1327 provider->PrepareSendToParent(resource_ids_to_transfer, &list);
1328 EXPECT_TRUE(provider->InUseByConsumer(id));
[email protected]7ba3ca72013-04-11 06:37:251329 EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0);
[email protected]28571b042013-03-14 07:59:151330 provider->DeleteResource(id);
1331 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]7ba3ca72013-04-11 06:37:251332 EXPECT_CALL(test_data_.mock_callback_,
1333 Release(test_data_.mailbox_name1_, _, false))
[email protected]28571b042013-03-14 07:59:151334 .Times(1);
[email protected]e00bab022013-08-19 00:42:451335 ReturnedResourceArray returned;
1336 TransferableResource::ReturnResources(list, &returned);
1337 provider->ReceiveReturnsFromParent(returned);
[email protected]de44a152013-01-08 15:28:461338}
1339
[email protected]97d519fb2013-03-29 02:27:541340// Check that ClearClient correctly clears the state so that the impl side
1341// doesn't try to use a texture that could have been destroyed.
[email protected]7ba3ca72013-04-11 06:37:251342class TextureLayerClientTest
1343 : public LayerTreeTest,
1344 public TextureLayerClient {
[email protected]97d519fb2013-03-29 02:27:541345 public:
1346 TextureLayerClientTest()
[email protected]f5931d42013-11-06 19:44:571347 : texture_(0),
[email protected]97d519fb2013-03-29 02:27:541348 commit_count_(0),
1349 expected_used_textures_on_draw_(0),
1350 expected_used_textures_on_commit_(0) {}
1351
[email protected]a6366932014-02-05 20:12:471352 virtual scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface(bool fallback)
[email protected]ebc0e1df2013-08-01 02:46:221353 OVERRIDE {
[email protected]f5931d42013-11-06 19:44:571354 scoped_refptr<TestContextProvider> provider = TestContextProvider::Create();
1355 texture_ = provider->UnboundTestContext3d()->createExternalTexture();
[email protected]a6366932014-02-05 20:12:471356 return FakeOutputSurface::Create3d(provider);
[email protected]97d519fb2013-03-29 02:27:541357 }
1358
[email protected]f5931d42013-11-06 19:44:571359 virtual unsigned PrepareTexture() OVERRIDE { return texture_; }
[email protected]97d519fb2013-03-29 02:27:541360
[email protected]2541d1a2013-07-10 07:33:271361 virtual bool PrepareTextureMailbox(
[email protected]9260757f2013-09-17 01:24:161362 TextureMailbox* mailbox,
1363 scoped_ptr<SingleReleaseCallback>* release_callback,
1364 bool use_shared_memory) OVERRIDE {
[email protected]e8e4ae232013-04-12 00:26:011365 return false;
1366 }
1367
[email protected]97d519fb2013-03-29 02:27:541368 virtual void SetupTree() OVERRIDE {
1369 scoped_refptr<Layer> root = Layer::Create();
1370 root->SetBounds(gfx::Size(10, 10));
1371 root->SetAnchorPoint(gfx::PointF());
1372 root->SetIsDrawable(true);
1373
1374 texture_layer_ = TextureLayer::Create(this);
1375 texture_layer_->SetBounds(gfx::Size(10, 10));
1376 texture_layer_->SetAnchorPoint(gfx::PointF());
1377 texture_layer_->SetIsDrawable(true);
1378 root->AddChild(texture_layer_);
1379
1380 layer_tree_host()->SetRootLayer(root);
1381 LayerTreeTest::SetupTree();
1382 {
1383 base::AutoLock lock(lock_);
1384 expected_used_textures_on_commit_ = 1;
1385 }
1386 }
1387
1388 virtual void BeginTest() OVERRIDE {
1389 PostSetNeedsCommitToMainThread();
1390 }
1391
1392 virtual void DidCommitAndDrawFrame() OVERRIDE {
1393 ++commit_count_;
1394 switch (commit_count_) {
1395 case 1:
1396 texture_layer_->ClearClient();
1397 texture_layer_->SetNeedsDisplay();
1398 {
1399 base::AutoLock lock(lock_);
1400 expected_used_textures_on_commit_ = 0;
1401 }
[email protected]97d519fb2013-03-29 02:27:541402 break;
1403 case 2:
1404 EndTest();
1405 break;
1406 default:
1407 NOTREACHED();
1408 break;
1409 }
1410 }
1411
1412 virtual void BeginCommitOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
1413 base::AutoLock lock(lock_);
1414 expected_used_textures_on_draw_ = expected_used_textures_on_commit_;
1415 }
1416
[email protected]7ddfe7e82014-01-30 07:22:111417 virtual DrawSwapReadbackResult::DrawResult PrepareToDrawOnThread(
1418 LayerTreeHostImpl* host_impl,
1419 LayerTreeHostImpl::FrameData* frame_data,
1420 DrawSwapReadbackResult::DrawResult draw_result) OVERRIDE {
[email protected]f5931d42013-11-06 19:44:571421 ContextForImplThread(host_impl)->ResetUsedTextures();
[email protected]7ddfe7e82014-01-30 07:22:111422 return DrawSwapReadbackResult::DRAW_SUCCESS;
[email protected]97d519fb2013-03-29 02:27:541423 }
1424
1425 virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl,
1426 bool result) OVERRIDE {
1427 ASSERT_TRUE(result);
[email protected]f5931d42013-11-06 19:44:571428 EXPECT_EQ(expected_used_textures_on_draw_,
1429 ContextForImplThread(host_impl)->NumUsedTextures());
[email protected]97d519fb2013-03-29 02:27:541430 }
1431
1432 virtual void AfterTest() OVERRIDE {}
1433
1434 private:
[email protected]f5931d42013-11-06 19:44:571435 TestWebGraphicsContext3D* ContextForImplThread(LayerTreeHostImpl* host_impl) {
[email protected]1dff7962014-01-10 12:05:031436 return static_cast<TestContextProvider*>(
1437 host_impl->output_surface()->context_provider().get())->TestContext3d();
[email protected]f5931d42013-11-06 19:44:571438 }
1439
[email protected]97d519fb2013-03-29 02:27:541440 scoped_refptr<TextureLayer> texture_layer_;
[email protected]97d519fb2013-03-29 02:27:541441 unsigned texture_;
1442 int commit_count_;
1443
1444 // Used only on thread.
1445 unsigned expected_used_textures_on_draw_;
1446
1447 // Used on either thread, protected by lock_.
1448 base::Lock lock_;
1449 unsigned expected_used_textures_on_commit_;
1450};
1451
[email protected]4145d172013-05-10 16:54:361452// The TextureLayerClient does not use mailboxes, so can't use a delegating
1453// renderer.
1454SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(TextureLayerClientTest);
[email protected]97d519fb2013-03-29 02:27:541455
[email protected]b04264f92013-09-13 23:37:291456
1457// Checks that changing a texture in the client for a TextureLayer that's
1458// invisible correctly works without drawing a deleted texture. See
1459// crbug.com/266628
1460class TextureLayerChangeInvisibleTest
1461 : public LayerTreeTest,
1462 public TextureLayerClient {
1463 public:
1464 TextureLayerChangeInvisibleTest()
[email protected]f5931d42013-11-06 19:44:571465 : texture_(0u),
[email protected]b04264f92013-09-13 23:37:291466 prepare_called_(0),
1467 commit_count_(0),
1468 expected_texture_on_draw_(0) {}
1469
[email protected]a6366932014-02-05 20:12:471470 virtual scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface(bool fallback)
[email protected]f5931d42013-11-06 19:44:571471 OVERRIDE {
1472 scoped_refptr<TestContextProvider> provider = TestContextProvider::Create();
1473 texture_ = provider->UnboundTestContext3d()->createExternalTexture();
[email protected]a6366932014-02-05 20:12:471474 return FakeOutputSurface::Create3d(provider);
[email protected]f5931d42013-11-06 19:44:571475 }
1476
[email protected]b04264f92013-09-13 23:37:291477 // TextureLayerClient implementation.
1478 virtual unsigned PrepareTexture() OVERRIDE {
1479 ++prepare_called_;
1480 return texture_;
1481 }
[email protected]b04264f92013-09-13 23:37:291482 virtual bool PrepareTextureMailbox(
[email protected]e51444a2013-12-10 23:05:011483 TextureMailbox* mailbox,
[email protected]9260757f2013-09-17 01:24:161484 scoped_ptr<SingleReleaseCallback>* release_callback,
1485 bool use_shared_memory) OVERRIDE {
[email protected]b04264f92013-09-13 23:37:291486 return false;
1487 }
1488
1489 virtual void SetupTree() OVERRIDE {
1490 scoped_refptr<Layer> root = Layer::Create();
1491 root->SetBounds(gfx::Size(10, 10));
1492 root->SetAnchorPoint(gfx::PointF());
1493 root->SetIsDrawable(true);
1494
1495 solid_layer_ = SolidColorLayer::Create();
1496 solid_layer_->SetBounds(gfx::Size(10, 10));
1497 solid_layer_->SetIsDrawable(true);
1498 solid_layer_->SetBackgroundColor(SK_ColorWHITE);
1499 root->AddChild(solid_layer_);
1500
1501 parent_layer_ = Layer::Create();
1502 parent_layer_->SetBounds(gfx::Size(10, 10));
1503 parent_layer_->SetIsDrawable(true);
1504 root->AddChild(parent_layer_);
1505
1506 texture_layer_ = TextureLayer::Create(this);
1507 texture_layer_->SetBounds(gfx::Size(10, 10));
1508 texture_layer_->SetAnchorPoint(gfx::PointF());
1509 texture_layer_->SetIsDrawable(true);
1510 parent_layer_->AddChild(texture_layer_);
1511
1512 layer_tree_host()->SetRootLayer(root);
1513 LayerTreeTest::SetupTree();
1514 }
1515
1516 virtual void BeginTest() OVERRIDE {
1517 PostSetNeedsCommitToMainThread();
1518 }
1519
1520 virtual void DidCommitAndDrawFrame() OVERRIDE {
1521 ++commit_count_;
1522 switch (commit_count_) {
1523 case 1:
1524 // We should have updated the layer, committing the texture.
1525 EXPECT_EQ(1, prepare_called_);
1526 // Make layer invisible.
1527 parent_layer_->SetOpacity(0.f);
1528 break;
1529 case 2: {
1530 // Layer shouldn't have been updated.
1531 EXPECT_EQ(1, prepare_called_);
[email protected]b04264f92013-09-13 23:37:291532 texture_layer_->SetNeedsDisplay();
1533 // Force a change to make sure we draw a frame.
1534 solid_layer_->SetBackgroundColor(SK_ColorGRAY);
1535 break;
1536 }
1537 case 3:
1538 EXPECT_EQ(1, prepare_called_);
[email protected]b04264f92013-09-13 23:37:291539 // Make layer visible again.
1540 parent_layer_->SetOpacity(1.f);
1541 break;
1542 case 4: {
1543 // Layer should have been updated.
1544 EXPECT_EQ(2, prepare_called_);
1545 texture_layer_->ClearClient();
[email protected]b04264f92013-09-13 23:37:291546 texture_ = 0;
1547 break;
1548 }
1549 case 5:
1550 EndTest();
1551 break;
1552 default:
1553 NOTREACHED();
1554 break;
1555 }
1556 }
1557
1558 virtual void BeginCommitOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
1559 ASSERT_TRUE(proxy()->IsMainThreadBlocked());
1560 // This is the only texture that can be drawn this frame.
1561 expected_texture_on_draw_ = texture_;
1562 }
1563
[email protected]7ddfe7e82014-01-30 07:22:111564 virtual DrawSwapReadbackResult::DrawResult PrepareToDrawOnThread(
1565 LayerTreeHostImpl* host_impl,
1566 LayerTreeHostImpl::FrameData* frame_data,
1567 DrawSwapReadbackResult::DrawResult draw_result) OVERRIDE {
[email protected]b04264f92013-09-13 23:37:291568 ContextForImplThread(host_impl)->ResetUsedTextures();
[email protected]7ddfe7e82014-01-30 07:22:111569 return DrawSwapReadbackResult::DRAW_SUCCESS;
[email protected]b04264f92013-09-13 23:37:291570 }
1571
1572 virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl,
1573 bool result) OVERRIDE {
1574 ASSERT_TRUE(result);
1575 TestWebGraphicsContext3D* context = ContextForImplThread(host_impl);
1576 int used_textures = context->NumUsedTextures();
1577 switch (host_impl->active_tree()->source_frame_number()) {
1578 case 0:
1579 EXPECT_EQ(1, used_textures);
1580 EXPECT_TRUE(context->UsedTexture(expected_texture_on_draw_));
1581 break;
1582 case 1:
1583 case 2:
1584 EXPECT_EQ(0, used_textures);
1585 break;
1586 case 3:
1587 EXPECT_EQ(1, used_textures);
1588 EXPECT_TRUE(context->UsedTexture(expected_texture_on_draw_));
1589 break;
1590 default:
1591 break;
1592 }
1593 }
1594
1595 virtual void AfterTest() OVERRIDE {}
1596
1597 private:
1598 TestWebGraphicsContext3D* ContextForImplThread(LayerTreeHostImpl* host_impl) {
[email protected]1dff7962014-01-10 12:05:031599 return static_cast<TestContextProvider*>(
1600 host_impl->output_surface()->context_provider().get())->TestContext3d();
[email protected]b04264f92013-09-13 23:37:291601 }
1602
1603 scoped_refptr<SolidColorLayer> solid_layer_;
1604 scoped_refptr<Layer> parent_layer_;
1605 scoped_refptr<TextureLayer> texture_layer_;
[email protected]b04264f92013-09-13 23:37:291606
1607 // Used on the main thread, and on the impl thread while the main thread is
1608 // blocked.
1609 unsigned texture_;
1610
1611 // Used on the main thread.
[email protected]b04264f92013-09-13 23:37:291612 int prepare_called_;
1613 int commit_count_;
1614
1615 // Used on the compositor thread.
1616 unsigned expected_texture_on_draw_;
1617};
1618
1619// The TextureLayerChangeInvisibleTest does not use mailboxes, so can't use a
1620// delegating renderer.
1621SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(TextureLayerChangeInvisibleTest);
1622
[email protected]4bad8b62013-10-24 01:27:291623// Checks that TextureLayer::Update does not cause an extra commit when setting
1624// the texture mailbox.
1625class TextureLayerNoExtraCommitForMailboxTest
1626 : public LayerTreeTest,
1627 public TextureLayerClient {
1628 public:
[email protected]4bad8b62013-10-24 01:27:291629 // TextureLayerClient implementation.
1630 virtual unsigned PrepareTexture() OVERRIDE {
1631 NOTREACHED();
1632 return 0;
1633 }
[email protected]4bad8b62013-10-24 01:27:291634 virtual bool PrepareTextureMailbox(
[email protected]df41e252014-02-03 23:39:501635 TextureMailbox* texture_mailbox,
[email protected]4bad8b62013-10-24 01:27:291636 scoped_ptr<SingleReleaseCallback>* release_callback,
1637 bool use_shared_memory) OVERRIDE {
[email protected]cce34bd2013-12-02 23:24:451638 if (layer_tree_host()->source_frame_number() == 1) {
[email protected]df41e252014-02-03 23:39:501639 *texture_mailbox = TextureMailbox();
[email protected]cce34bd2013-12-02 23:24:451640 return true;
1641 }
[email protected]4bad8b62013-10-24 01:27:291642
[email protected]df41e252014-02-03 23:39:501643 *texture_mailbox = TextureMailbox(
1644 MailboxFromString(std::string(64, '1')), GL_TEXTURE_2D, 0);
[email protected]4bad8b62013-10-24 01:27:291645 *release_callback = SingleReleaseCallback::Create(
1646 base::Bind(&TextureLayerNoExtraCommitForMailboxTest::MailboxReleased,
1647 base::Unretained(this)));
[email protected]4bad8b62013-10-24 01:27:291648 return true;
1649 }
1650
[email protected]df41e252014-02-03 23:39:501651 void MailboxReleased(uint32 sync_point, bool lost_resource) {
[email protected]cce34bd2013-12-02 23:24:451652 EXPECT_EQ(2, layer_tree_host()->source_frame_number());
1653 EndTest();
[email protected]4bad8b62013-10-24 01:27:291654 }
1655
1656 virtual void SetupTree() OVERRIDE {
1657 scoped_refptr<Layer> root = Layer::Create();
1658 root->SetBounds(gfx::Size(10, 10));
1659 root->SetAnchorPoint(gfx::PointF());
1660 root->SetIsDrawable(true);
1661
[email protected]4bad8b62013-10-24 01:27:291662 texture_layer_ = TextureLayer::CreateForMailbox(this);
1663 texture_layer_->SetBounds(gfx::Size(10, 10));
1664 texture_layer_->SetAnchorPoint(gfx::PointF());
1665 texture_layer_->SetIsDrawable(true);
[email protected]0d7fb302014-01-23 21:30:471666 root->AddChild(texture_layer_);
[email protected]4bad8b62013-10-24 01:27:291667
1668 layer_tree_host()->SetRootLayer(root);
1669 LayerTreeTest::SetupTree();
1670 }
1671
1672 virtual void BeginTest() OVERRIDE {
1673 PostSetNeedsCommitToMainThread();
1674 }
1675
[email protected]cce34bd2013-12-02 23:24:451676 virtual void DidCommitAndDrawFrame() OVERRIDE {
[email protected]4bad8b62013-10-24 01:27:291677 switch (layer_tree_host()->source_frame_number()) {
1678 case 1:
[email protected]cce34bd2013-12-02 23:24:451679 EXPECT_FALSE(proxy()->CommitPendingForTesting());
1680 // Invalidate the texture layer to clear the mailbox before
1681 // ending the test.
1682 texture_layer_->SetNeedsDisplay();
1683 break;
1684 case 2:
[email protected]4bad8b62013-10-24 01:27:291685 break;
1686 default:
1687 NOTREACHED();
1688 break;
1689 }
1690 }
1691
[email protected]cce34bd2013-12-02 23:24:451692 virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl,
1693 bool result) OVERRIDE {
1694 ASSERT_TRUE(result);
1695 DelegatedFrameData* delegated_frame_data =
1696 output_surface()->last_sent_frame().delegated_frame_data.get();
1697 if (!delegated_frame_data)
1698 return;
1699
1700 // Return all resources immediately.
1701 TransferableResourceArray resources_to_return =
1702 output_surface()->resources_held_by_parent();
1703
1704 CompositorFrameAck ack;
1705 for (size_t i = 0; i < resources_to_return.size(); ++i)
1706 output_surface()->ReturnResource(resources_to_return[i].id, &ack);
1707 host_impl->ReclaimResources(&ack);
1708 host_impl->OnSwapBuffersComplete();
1709 }
1710
[email protected]4bad8b62013-10-24 01:27:291711 virtual void AfterTest() OVERRIDE {}
1712
1713 private:
[email protected]4bad8b62013-10-24 01:27:291714 scoped_refptr<TextureLayer> texture_layer_;
[email protected]4bad8b62013-10-24 01:27:291715};
1716
[email protected]cce34bd2013-12-02 23:24:451717SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerNoExtraCommitForMailboxTest);
[email protected]4bad8b62013-10-24 01:27:291718
[email protected]b04264f92013-09-13 23:37:291719// Checks that changing a mailbox in the client for a TextureLayer that's
1720// invisible correctly works and uses the new mailbox as soon as the layer
1721// becomes visible (and returns the old one).
1722class TextureLayerChangeInvisibleMailboxTest
1723 : public LayerTreeTest,
1724 public TextureLayerClient {
1725 public:
1726 TextureLayerChangeInvisibleMailboxTest()
1727 : mailbox_changed_(true),
1728 mailbox_returned_(0),
1729 prepare_called_(0),
1730 commit_count_(0) {
1731 mailbox_ = MakeMailbox('1');
1732 }
1733
1734 // TextureLayerClient implementation.
1735 virtual unsigned PrepareTexture() OVERRIDE {
1736 NOTREACHED();
1737 return 0;
1738 }
1739
[email protected]b04264f92013-09-13 23:37:291740 virtual bool PrepareTextureMailbox(
[email protected]e51444a2013-12-10 23:05:011741 TextureMailbox* mailbox,
[email protected]9260757f2013-09-17 01:24:161742 scoped_ptr<SingleReleaseCallback>* release_callback,
1743 bool use_shared_memory) OVERRIDE {
[email protected]b04264f92013-09-13 23:37:291744 ++prepare_called_;
1745 if (!mailbox_changed_)
1746 return false;
1747 *mailbox = mailbox_;
[email protected]9260757f2013-09-17 01:24:161748 *release_callback = SingleReleaseCallback::Create(
1749 base::Bind(&TextureLayerChangeInvisibleMailboxTest::MailboxReleased,
1750 base::Unretained(this)));
[email protected]b04264f92013-09-13 23:37:291751 return true;
1752 }
1753
1754 TextureMailbox MakeMailbox(char name) {
[email protected]df41e252014-02-03 23:39:501755 return TextureMailbox(
1756 MailboxFromString(std::string(64, name)), GL_TEXTURE_2D, 0);
[email protected]b04264f92013-09-13 23:37:291757 }
1758
[email protected]df41e252014-02-03 23:39:501759 void MailboxReleased(uint32 sync_point, bool lost_resource) {
[email protected]b04264f92013-09-13 23:37:291760 ++mailbox_returned_;
1761 }
1762
1763 virtual void SetupTree() OVERRIDE {
1764 scoped_refptr<Layer> root = Layer::Create();
1765 root->SetBounds(gfx::Size(10, 10));
1766 root->SetAnchorPoint(gfx::PointF());
1767 root->SetIsDrawable(true);
1768
1769 solid_layer_ = SolidColorLayer::Create();
1770 solid_layer_->SetBounds(gfx::Size(10, 10));
1771 solid_layer_->SetIsDrawable(true);
1772 solid_layer_->SetBackgroundColor(SK_ColorWHITE);
1773 root->AddChild(solid_layer_);
1774
1775 parent_layer_ = Layer::Create();
1776 parent_layer_->SetBounds(gfx::Size(10, 10));
1777 parent_layer_->SetIsDrawable(true);
1778 root->AddChild(parent_layer_);
1779
1780 texture_layer_ = TextureLayer::CreateForMailbox(this);
1781 texture_layer_->SetBounds(gfx::Size(10, 10));
1782 texture_layer_->SetAnchorPoint(gfx::PointF());
1783 texture_layer_->SetIsDrawable(true);
1784 parent_layer_->AddChild(texture_layer_);
1785
1786 layer_tree_host()->SetRootLayer(root);
1787 LayerTreeTest::SetupTree();
1788 }
1789
1790 virtual void BeginTest() OVERRIDE {
1791 PostSetNeedsCommitToMainThread();
1792 }
1793
1794 virtual void DidCommitAndDrawFrame() OVERRIDE {
1795 ++commit_count_;
1796 switch (commit_count_) {
1797 case 1:
1798 // We should have updated the layer, committing the texture.
1799 EXPECT_EQ(1, prepare_called_);
1800 // Make layer invisible.
1801 parent_layer_->SetOpacity(0.f);
1802 break;
1803 case 2:
1804 // Layer shouldn't have been updated.
1805 EXPECT_EQ(1, prepare_called_);
1806 // Change the texture.
1807 mailbox_ = MakeMailbox('2');
1808 mailbox_changed_ = true;
1809 texture_layer_->SetNeedsDisplay();
1810 // Force a change to make sure we draw a frame.
1811 solid_layer_->SetBackgroundColor(SK_ColorGRAY);
1812 break;
1813 case 3:
1814 // Layer shouldn't have been updated.
1815 EXPECT_EQ(1, prepare_called_);
1816 // So the old mailbox isn't returned yet.
1817 EXPECT_EQ(0, mailbox_returned_);
1818 // Make layer visible again.
1819 parent_layer_->SetOpacity(1.f);
1820 break;
1821 case 4:
1822 // Layer should have been updated.
1823 EXPECT_EQ(2, prepare_called_);
1824 // So the old mailbox should have been returned already.
1825 EXPECT_EQ(1, mailbox_returned_);
1826 texture_layer_->ClearClient();
1827 break;
1828 case 5:
1829 EXPECT_EQ(2, mailbox_returned_);
1830 EndTest();
1831 break;
1832 default:
1833 NOTREACHED();
1834 break;
1835 }
1836 }
1837
1838 virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl,
1839 bool result) OVERRIDE {
1840 ASSERT_TRUE(result);
1841 DelegatedFrameData* delegated_frame_data =
1842 output_surface()->last_sent_frame().delegated_frame_data.get();
1843 if (!delegated_frame_data)
1844 return;
1845
1846 // Return all resources immediately.
1847 TransferableResourceArray resources_to_return =
1848 output_surface()->resources_held_by_parent();
1849
1850 CompositorFrameAck ack;
1851 for (size_t i = 0; i < resources_to_return.size(); ++i)
1852 output_surface()->ReturnResource(resources_to_return[i].id, &ack);
[email protected]a7335e0b2013-09-18 09:34:511853 host_impl->ReclaimResources(&ack);
1854 host_impl->OnSwapBuffersComplete();
[email protected]b04264f92013-09-13 23:37:291855 }
1856
1857 virtual void AfterTest() OVERRIDE {}
1858
1859 private:
1860 scoped_refptr<SolidColorLayer> solid_layer_;
1861 scoped_refptr<Layer> parent_layer_;
1862 scoped_refptr<TextureLayer> texture_layer_;
1863
1864 // Used on the main thread.
1865 bool mailbox_changed_;
1866 TextureMailbox mailbox_;
1867 int mailbox_returned_;
1868 int prepare_called_;
1869 int commit_count_;
1870};
1871
1872SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerChangeInvisibleMailboxTest);
1873
[email protected]0d7fb302014-01-23 21:30:471874// Test that TextureLayerImpl::ReleaseResources can be called which releases
1875// the mailbox back to TextureLayerClient.
1876class TextureLayerReleaseResourcesBase
1877 : public LayerTreeTest,
1878 public TextureLayerClient {
1879 public:
1880 // TextureLayerClient implementation.
1881 virtual unsigned PrepareTexture() OVERRIDE {
1882 NOTREACHED();
1883 return 0;
1884 }
1885 virtual bool PrepareTextureMailbox(
1886 TextureMailbox* mailbox,
1887 scoped_ptr<SingleReleaseCallback>* release_callback,
1888 bool use_shared_memory) OVERRIDE {
[email protected]df41e252014-02-03 23:39:501889 *mailbox = TextureMailbox(
1890 MailboxFromString(std::string(64, '1')), GL_TEXTURE_2D, 0);
[email protected]0d7fb302014-01-23 21:30:471891 *release_callback = SingleReleaseCallback::Create(
1892 base::Bind(&TextureLayerReleaseResourcesBase::MailboxReleased,
1893 base::Unretained(this)));
1894 return true;
1895 }
1896
1897 void MailboxReleased(unsigned sync_point, bool lost_resource) {
1898 mailbox_released_ = true;
1899 }
1900
1901 virtual void SetupTree() OVERRIDE {
1902 LayerTreeTest::SetupTree();
1903
1904 scoped_refptr<TextureLayer> texture_layer =
1905 TextureLayer::CreateForMailbox(this);
1906 texture_layer->SetBounds(gfx::Size(10, 10));
1907 texture_layer->SetAnchorPoint(gfx::PointF());
1908 texture_layer->SetIsDrawable(true);
1909
1910 layer_tree_host()->root_layer()->AddChild(texture_layer);
1911 }
1912
1913 virtual void BeginTest() OVERRIDE {
1914 mailbox_released_ = false;
1915 PostSetNeedsCommitToMainThread();
1916 }
1917
1918 virtual void DidCommitAndDrawFrame() OVERRIDE {
1919 EndTest();
1920 }
1921
1922 virtual void AfterTest() OVERRIDE {
1923 EXPECT_TRUE(mailbox_released_);
1924 }
1925
1926 private:
1927 bool mailbox_released_;
1928};
1929
1930class TextureLayerReleaseResourcesAfterCommit
1931 : public TextureLayerReleaseResourcesBase {
1932 public:
1933 virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
1934 LayerTreeImpl* tree = NULL;
1935 if (host_impl->settings().impl_side_painting)
1936 tree = host_impl->pending_tree();
1937 else
1938 tree = host_impl->active_tree();
1939 tree->root_layer()->children()[0]->ReleaseResources();
1940 }
1941};
1942
1943SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerReleaseResourcesAfterCommit);
1944
1945class TextureLayerReleaseResourcesAfterActivate
1946 : public TextureLayerReleaseResourcesBase {
1947 public:
1948 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
1949 host_impl->active_tree()->root_layer()->children()[0]->ReleaseResources();
1950 }
1951};
1952
1953SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerReleaseResourcesAfterActivate);
1954
[email protected]0bf5a202013-07-10 14:50:541955// Test recovering from a lost context.
1956class TextureLayerLostContextTest
1957 : public LayerTreeTest,
1958 public TextureLayerClient {
1959 public:
1960 TextureLayerLostContextTest()
[email protected]f5931d42013-11-06 19:44:571961 : context_lost_(false),
[email protected]0bf5a202013-07-10 14:50:541962 draw_count_(0) {}
1963
[email protected]a6366932014-02-05 20:12:471964 virtual scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface(bool fallback)
[email protected]ebc0e1df2013-08-01 02:46:221965 OVERRIDE {
[email protected]a6366932014-02-05 20:12:471966 return FakeOutputSurface::Create3d();
[email protected]0bf5a202013-07-10 14:50:541967 }
1968
[email protected]171cbb32013-07-11 03:51:191969 virtual unsigned PrepareTexture() OVERRIDE {
[email protected]f5931d42013-11-06 19:44:571970 if (draw_count_ == 0)
1971 context_lost_ = true;
1972 if (context_lost_)
1973 return 0u;
1974 return 1u;
[email protected]0bf5a202013-07-10 14:50:541975 }
1976
1977 virtual bool PrepareTextureMailbox(
[email protected]9260757f2013-09-17 01:24:161978 TextureMailbox* mailbox,
1979 scoped_ptr<SingleReleaseCallback>* release_callback,
1980 bool use_shared_memory) OVERRIDE {
[email protected]0bf5a202013-07-10 14:50:541981 return false;
1982 }
1983
1984 virtual void SetupTree() OVERRIDE {
1985 scoped_refptr<Layer> root = Layer::Create();
1986 root->SetBounds(gfx::Size(10, 10));
1987 root->SetIsDrawable(true);
1988
1989 texture_layer_ = TextureLayer::Create(this);
1990 texture_layer_->SetBounds(gfx::Size(10, 10));
1991 texture_layer_->SetIsDrawable(true);
1992 root->AddChild(texture_layer_);
1993
1994 layer_tree_host()->SetRootLayer(root);
1995 LayerTreeTest::SetupTree();
1996 }
1997
1998 virtual void BeginTest() OVERRIDE {
1999 PostSetNeedsCommitToMainThread();
2000 }
2001
[email protected]7ddfe7e82014-01-30 07:22:112002 virtual DrawSwapReadbackResult::DrawResult PrepareToDrawOnThread(
2003 LayerTreeHostImpl* host_impl,
2004 LayerTreeHostImpl::FrameData* frame_data,
2005 DrawSwapReadbackResult::DrawResult draw_result) OVERRIDE {
[email protected]0bf5a202013-07-10 14:50:542006 LayerImpl* root = host_impl->RootLayer();
2007 TextureLayerImpl* texture_layer =
2008 static_cast<TextureLayerImpl*>(root->children()[0]);
2009 if (++draw_count_ == 1)
2010 EXPECT_EQ(0u, texture_layer->texture_id());
2011 else
[email protected]f5931d42013-11-06 19:44:572012 EXPECT_EQ(1u, texture_layer->texture_id());
[email protected]7ddfe7e82014-01-30 07:22:112013 return DrawSwapReadbackResult::DRAW_SUCCESS;
[email protected]0bf5a202013-07-10 14:50:542014 }
2015
2016 virtual void DidCommitAndDrawFrame() OVERRIDE {
2017 EndTest();
2018 }
2019
2020 virtual void AfterTest() OVERRIDE {}
2021
2022 private:
2023 scoped_refptr<TextureLayer> texture_layer_;
[email protected]f5931d42013-11-06 19:44:572024 bool context_lost_;
[email protected]0bf5a202013-07-10 14:50:542025 int draw_count_;
2026};
2027
2028SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(TextureLayerLostContextTest);
2029
[email protected]9c2bd822013-07-26 12:30:172030class TextureLayerWithMailboxMainThreadDeleted : public LayerTreeTest {
2031 public:
[email protected]df41e252014-02-03 23:39:502032 void ReleaseCallback(uint32 sync_point, bool lost_resource) {
[email protected]9794fb32013-08-29 09:49:592033 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]9c2bd822013-07-26 12:30:172034 EXPECT_FALSE(lost_resource);
2035 ++callback_count_;
2036 EndTest();
2037 }
2038
2039 void SetMailbox(char mailbox_char) {
[email protected]9794fb32013-08-29 09:49:592040 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]9260757f2013-09-17 01:24:162041 scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create(
[email protected]9c2bd822013-07-26 12:30:172042 base::Bind(
2043 &TextureLayerWithMailboxMainThreadDeleted::ReleaseCallback,
2044 base::Unretained(this)));
[email protected]df41e252014-02-03 23:39:502045 layer_->SetTextureMailbox(
2046 TextureMailbox(
2047 MailboxFromString(std::string(64, mailbox_char)), GL_TEXTURE_2D, 0),
2048 callback.Pass());
[email protected]9c2bd822013-07-26 12:30:172049 }
2050
2051 virtual void SetupTree() OVERRIDE {
2052 gfx::Size bounds(100, 100);
2053 root_ = Layer::Create();
2054 root_->SetAnchorPoint(gfx::PointF());
2055 root_->SetBounds(bounds);
2056
2057 layer_ = TextureLayer::CreateForMailbox(NULL);
2058 layer_->SetIsDrawable(true);
2059 layer_->SetAnchorPoint(gfx::PointF());
2060 layer_->SetBounds(bounds);
2061
2062 root_->AddChild(layer_);
2063 layer_tree_host()->SetRootLayer(root_);
2064 layer_tree_host()->SetViewportSize(bounds);
2065 }
2066
2067 virtual void BeginTest() OVERRIDE {
[email protected]9794fb32013-08-29 09:49:592068 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
2069
[email protected]9c2bd822013-07-26 12:30:172070 callback_count_ = 0;
2071
2072 // Set the mailbox on the main thread.
2073 SetMailbox('1');
2074 EXPECT_EQ(0, callback_count_);
2075
2076 PostSetNeedsCommitToMainThread();
2077 }
2078
2079 virtual void DidCommitAndDrawFrame() OVERRIDE {
2080 switch (layer_tree_host()->source_frame_number()) {
2081 case 1:
2082 // Delete the TextureLayer on the main thread while the mailbox is in
2083 // the impl tree.
2084 layer_->RemoveFromParent();
2085 layer_ = NULL;
2086 break;
2087 }
2088 }
2089
2090 virtual void AfterTest() OVERRIDE {
2091 EXPECT_EQ(1, callback_count_);
2092 }
2093
2094 private:
[email protected]9794fb32013-08-29 09:49:592095 base::ThreadChecker main_thread_;
[email protected]9c2bd822013-07-26 12:30:172096 int callback_count_;
2097 scoped_refptr<Layer> root_;
2098 scoped_refptr<TextureLayer> layer_;
2099};
2100
2101SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
2102 TextureLayerWithMailboxMainThreadDeleted);
2103
2104class TextureLayerWithMailboxImplThreadDeleted : public LayerTreeTest {
2105 public:
[email protected]df41e252014-02-03 23:39:502106 void ReleaseCallback(uint32 sync_point, bool lost_resource) {
[email protected]9794fb32013-08-29 09:49:592107 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]9c2bd822013-07-26 12:30:172108 EXPECT_FALSE(lost_resource);
2109 ++callback_count_;
2110 EndTest();
2111 }
2112
2113 void SetMailbox(char mailbox_char) {
[email protected]9794fb32013-08-29 09:49:592114 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]9260757f2013-09-17 01:24:162115 scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create(
[email protected]9c2bd822013-07-26 12:30:172116 base::Bind(
2117 &TextureLayerWithMailboxImplThreadDeleted::ReleaseCallback,
2118 base::Unretained(this)));
[email protected]df41e252014-02-03 23:39:502119 layer_->SetTextureMailbox(
2120 TextureMailbox(
2121 MailboxFromString(std::string(64, mailbox_char)), GL_TEXTURE_2D, 0),
2122 callback.Pass());
[email protected]9c2bd822013-07-26 12:30:172123 }
2124
2125 virtual void SetupTree() OVERRIDE {
2126 gfx::Size bounds(100, 100);
2127 root_ = Layer::Create();
2128 root_->SetAnchorPoint(gfx::PointF());
2129 root_->SetBounds(bounds);
2130
2131 layer_ = TextureLayer::CreateForMailbox(NULL);
2132 layer_->SetIsDrawable(true);
2133 layer_->SetAnchorPoint(gfx::PointF());
2134 layer_->SetBounds(bounds);
2135
2136 root_->AddChild(layer_);
2137 layer_tree_host()->SetRootLayer(root_);
2138 layer_tree_host()->SetViewportSize(bounds);
2139 }
2140
2141 virtual void BeginTest() OVERRIDE {
[email protected]9794fb32013-08-29 09:49:592142 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
2143
[email protected]9c2bd822013-07-26 12:30:172144 callback_count_ = 0;
2145
2146 // Set the mailbox on the main thread.
2147 SetMailbox('1');
2148 EXPECT_EQ(0, callback_count_);
2149
2150 PostSetNeedsCommitToMainThread();
2151 }
2152
2153 virtual void DidCommitAndDrawFrame() OVERRIDE {
2154 switch (layer_tree_host()->source_frame_number()) {
2155 case 1:
2156 // Remove the TextureLayer on the main thread while the mailbox is in
2157 // the impl tree, but don't delete the TextureLayer until after the impl
2158 // tree side is deleted.
2159 layer_->RemoveFromParent();
2160 break;
2161 case 2:
2162 layer_ = NULL;
2163 break;
2164 }
2165 }
2166
2167 virtual void AfterTest() OVERRIDE {
2168 EXPECT_EQ(1, callback_count_);
2169 }
2170
2171 private:
[email protected]9794fb32013-08-29 09:49:592172 base::ThreadChecker main_thread_;
[email protected]9c2bd822013-07-26 12:30:172173 int callback_count_;
2174 scoped_refptr<Layer> root_;
2175 scoped_refptr<TextureLayer> layer_;
2176};
2177
2178SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
2179 TextureLayerWithMailboxImplThreadDeleted);
2180
[email protected]ba565742012-11-10 09:29:482181} // namespace
2182} // namespace cc