blob: 88ff0409615523770fd3c0d49ae6b1b513de8f4b [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]e0a4d732014-02-15 00:23:2644gpu::Mailbox MailboxFromChar(char value) {
[email protected]df41e252014-02-03 23:39:5045 gpu::Mailbox mailbox;
[email protected]e0a4d732014-02-15 00:23:2646 memset(mailbox.name, value, sizeof(mailbox.name));
[email protected]df41e252014-02-03 23:39:5047 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,
[email protected]e0a4d732014-02-15 00:23:26325 void(const gpu::Mailbox& mailbox,
[email protected]df41e252014-02-03 23:39:50326 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()
[email protected]e0a4d732014-02-15 00:23:26336 : mailbox_name1_(MailboxFromChar('1')),
337 mailbox_name2_(MailboxFromChar('2')),
[email protected]28571b042013-03-14 07:59:15338 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;
[email protected]e0a4d732014-02-15 00:23:26349 mailbox1_ = TextureMailbox(mailbox_name1_, arbitrary_target1, sync_point1_);
350 mailbox2_ = TextureMailbox(mailbox_name2_, arbitrary_target2, sync_point2_);
[email protected]42f40a52013-06-08 04:38:51351 gfx::Size size(128, 128);
352 EXPECT_TRUE(shared_memory_->CreateAndMapAnonymous(4 * size.GetArea()));
353 release_mailbox3_ = base::Bind(&MockMailboxCallback::Release2,
354 base::Unretained(&mock_callback_),
355 shared_memory_.get());
[email protected]9260757f2013-09-17 01:24:16356 mailbox3_ = TextureMailbox(shared_memory_.get(), size);
[email protected]28571b042013-03-14 07:59:15357 }
[email protected]de44a152013-01-08 15:28:46358
[email protected]e0a4d732014-02-15 00:23:26359 gpu::Mailbox mailbox_name1_;
360 gpu::Mailbox mailbox_name2_;
[email protected]28571b042013-03-14 07:59:15361 MockMailboxCallback mock_callback_;
[email protected]9260757f2013-09-17 01:24:16362 ReleaseCallback release_mailbox1_;
363 ReleaseCallback release_mailbox2_;
364 ReleaseCallback release_mailbox3_;
[email protected]28571b042013-03-14 07:59:15365 TextureMailbox mailbox1_;
366 TextureMailbox mailbox2_;
[email protected]42f40a52013-06-08 04:38:51367 TextureMailbox mailbox3_;
[email protected]df41e252014-02-03 23:39:50368 uint32 sync_point1_;
369 uint32 sync_point2_;
[email protected]42f40a52013-06-08 04:38:51370 scoped_ptr<base::SharedMemory> shared_memory_;
[email protected]de44a152013-01-08 15:28:46371};
372
[email protected]df41e252014-02-03 23:39:50373class TestMailboxHolder : public TextureLayer::TextureMailboxHolder {
[email protected]9794fb32013-08-29 09:49:59374 public:
[email protected]df41e252014-02-03 23:39:50375 using TextureLayer::TextureMailboxHolder::Create;
[email protected]9794fb32013-08-29 09:49:59376
377 protected:
378 virtual ~TestMailboxHolder() {}
379};
380
[email protected]de44a152013-01-08 15:28:46381class TextureLayerWithMailboxTest : public TextureLayerTest {
[email protected]28571b042013-03-14 07:59:15382 protected:
383 virtual void TearDown() {
384 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
385 EXPECT_CALL(test_data_.mock_callback_,
386 Release(test_data_.mailbox_name1_,
[email protected]7ba3ca72013-04-11 06:37:25387 test_data_.sync_point1_,
388 false)).Times(1);
[email protected]28571b042013-03-14 07:59:15389 TextureLayerTest::TearDown();
390 }
[email protected]de44a152013-01-08 15:28:46391
[email protected]28571b042013-03-14 07:59:15392 CommonMailboxObjects test_data_;
[email protected]de44a152013-01-08 15:28:46393};
394
[email protected]28571b042013-03-14 07:59:15395TEST_F(TextureLayerWithMailboxTest, ReplaceMailboxOnMainThreadBeforeCommit) {
[email protected]e8e4ae232013-04-12 00:26:01396 scoped_refptr<TextureLayer> test_layer = TextureLayer::CreateForMailbox(NULL);
[email protected]22898ed2013-06-01 04:52:30397 ASSERT_TRUE(test_layer.get());
[email protected]de44a152013-01-08 15:28:46398
[email protected]28571b042013-03-14 07:59:15399 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
400 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
401 layer_tree_host_->SetRootLayer(test_layer);
402 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
[email protected]de44a152013-01-08 15:28:46403
[email protected]28571b042013-03-14 07:59:15404 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
405 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
[email protected]9260757f2013-09-17 01:24:16406 test_layer->SetTextureMailbox(
407 test_data_.mailbox1_,
408 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
[email protected]28571b042013-03-14 07:59:15409 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
[email protected]de44a152013-01-08 15:28:46410
[email protected]28571b042013-03-14 07:59:15411 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
412 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
413 EXPECT_CALL(test_data_.mock_callback_,
[email protected]7ba3ca72013-04-11 06:37:25414 Release(test_data_.mailbox_name1_,
415 test_data_.sync_point1_,
416 false))
[email protected]28571b042013-03-14 07:59:15417 .Times(1);
[email protected]9260757f2013-09-17 01:24:16418 test_layer->SetTextureMailbox(
419 test_data_.mailbox2_,
420 SingleReleaseCallback::Create(test_data_.release_mailbox2_));
[email protected]28571b042013-03-14 07:59:15421 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
422 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]de44a152013-01-08 15:28:46423
[email protected]28571b042013-03-14 07:59:15424 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
425 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
426 EXPECT_CALL(test_data_.mock_callback_,
[email protected]7ba3ca72013-04-11 06:37:25427 Release(test_data_.mailbox_name2_,
428 test_data_.sync_point2_,
429 false))
[email protected]28571b042013-03-14 07:59:15430 .Times(1);
[email protected]9260757f2013-09-17 01:24:16431 test_layer->SetTextureMailbox(TextureMailbox(),
432 scoped_ptr<SingleReleaseCallback>());
[email protected]28571b042013-03-14 07:59:15433 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
434 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]de44a152013-01-08 15:28:46435
[email protected]80d42bd2013-08-30 19:13:45436 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
437 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
[email protected]9260757f2013-09-17 01:24:16438 test_layer->SetTextureMailbox(
439 test_data_.mailbox3_,
440 SingleReleaseCallback::Create(test_data_.release_mailbox3_));
[email protected]42f40a52013-06-08 04:38:51441 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
442 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
443
444 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
445 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
446 EXPECT_CALL(test_data_.mock_callback_,
447 Release2(test_data_.shared_memory_.get(),
448 0, false))
449 .Times(1);
[email protected]9260757f2013-09-17 01:24:16450 test_layer->SetTextureMailbox(TextureMailbox(),
451 scoped_ptr<SingleReleaseCallback>());
[email protected]42f40a52013-06-08 04:38:51452 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
453 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
454
[email protected]28571b042013-03-14 07:59:15455 // Test destructor.
456 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
[email protected]9260757f2013-09-17 01:24:16457 test_layer->SetTextureMailbox(
458 test_data_.mailbox1_,
459 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
[email protected]de44a152013-01-08 15:28:46460}
461
[email protected]9794fb32013-08-29 09:49:59462class TextureLayerMailboxHolderTest : public TextureLayerTest {
463 public:
464 TextureLayerMailboxHolderTest()
465 : main_thread_("MAIN") {
466 main_thread_.Start();
467 }
468
469 void Wait(const base::Thread& thread) {
470 bool manual_reset = false;
471 bool initially_signaled = false;
472 base::WaitableEvent event(manual_reset, initially_signaled);
473 thread.message_loop()->PostTask(
474 FROM_HERE,
475 base::Bind(&base::WaitableEvent::Signal, base::Unretained(&event)));
476 event.Wait();
477 }
478
479 void CreateMainRef() {
480 main_ref_ = TestMailboxHolder::Create(
[email protected]9260757f2013-09-17 01:24:16481 test_data_.mailbox1_,
482 SingleReleaseCallback::Create(test_data_.release_mailbox1_)).Pass();
[email protected]9794fb32013-08-29 09:49:59483 }
484
485 void ReleaseMainRef() {
486 main_ref_.reset();
487 }
488
[email protected]9260757f2013-09-17 01:24:16489 void CreateImplRef(scoped_ptr<SingleReleaseCallback>* impl_ref) {
[email protected]9794fb32013-08-29 09:49:59490 *impl_ref = main_ref_->holder()->GetCallbackForImplThread();
491 }
492
493 void CapturePostTasksAndWait(base::WaitableEvent* begin_capture,
494 base::WaitableEvent* wait_for_capture,
495 base::WaitableEvent* stop_capture) {
496 begin_capture->Wait();
497 BlockingTaskRunner::CapturePostTasks capture;
498 wait_for_capture->Signal();
499 stop_capture->Wait();
500 }
501
502 protected:
503 scoped_ptr<TestMailboxHolder::MainThreadReference>
504 main_ref_;
505 base::Thread main_thread_;
506 CommonMailboxObjects test_data_;
507};
508
509TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_BothReleaseThenMain) {
510 scoped_refptr<TextureLayer> test_layer = TextureLayer::CreateForMailbox(NULL);
511 ASSERT_TRUE(test_layer.get());
512
513 main_thread_.message_loop()->PostTask(
514 FROM_HERE,
515 base::Bind(&TextureLayerMailboxHolderTest::CreateMainRef,
516 base::Unretained(this)));
517
518 Wait(main_thread_);
519
520 // The texture layer is attached to compositor1, and passes a reference to its
521 // impl tree.
[email protected]9260757f2013-09-17 01:24:16522 scoped_ptr<SingleReleaseCallback> compositor1;
[email protected]9794fb32013-08-29 09:49:59523 main_thread_.message_loop()->PostTask(
524 FROM_HERE,
525 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
526 base::Unretained(this),
527 &compositor1));
528
529 // Then the texture layer is removed and attached to compositor2, and passes a
530 // reference to its impl tree.
[email protected]9260757f2013-09-17 01:24:16531 scoped_ptr<SingleReleaseCallback> compositor2;
[email protected]9794fb32013-08-29 09:49:59532 main_thread_.message_loop()->PostTask(
533 FROM_HERE,
534 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
535 base::Unretained(this),
536 &compositor2));
537
538 Wait(main_thread_);
539 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
540
541 // The compositors both destroy their impl trees before the main thread layer
542 // is destroyed.
[email protected]9260757f2013-09-17 01:24:16543 compositor1->Run(100, false);
544 compositor2->Run(200, false);
[email protected]9794fb32013-08-29 09:49:59545
546 Wait(main_thread_);
547
548 EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0);
549 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
550
551 // The main thread ref is the last one, so the mailbox is released back to the
552 // embedder, with the last sync point provided by the impl trees.
553 EXPECT_CALL(test_data_.mock_callback_,
554 Release(test_data_.mailbox_name1_, 200, false)).Times(1);
555
556 main_thread_.message_loop()->PostTask(
557 FROM_HERE,
558 base::Bind(&TextureLayerMailboxHolderTest::ReleaseMainRef,
559 base::Unretained(this)));
560 Wait(main_thread_);
561 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
562}
563
564TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_MainReleaseBetween) {
565 scoped_refptr<TextureLayer> test_layer = TextureLayer::CreateForMailbox(NULL);
566 ASSERT_TRUE(test_layer.get());
567
568 main_thread_.message_loop()->PostTask(
569 FROM_HERE,
570 base::Bind(&TextureLayerMailboxHolderTest::CreateMainRef,
571 base::Unretained(this)));
572
573 Wait(main_thread_);
574
575 // The texture layer is attached to compositor1, and passes a reference to its
576 // impl tree.
[email protected]9260757f2013-09-17 01:24:16577 scoped_ptr<SingleReleaseCallback> compositor1;
[email protected]9794fb32013-08-29 09:49:59578 main_thread_.message_loop()->PostTask(
579 FROM_HERE,
580 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
581 base::Unretained(this),
582 &compositor1));
583
584 // Then the texture layer is removed and attached to compositor2, and passes a
585 // reference to its impl tree.
[email protected]9260757f2013-09-17 01:24:16586 scoped_ptr<SingleReleaseCallback> compositor2;
[email protected]9794fb32013-08-29 09:49:59587 main_thread_.message_loop()->PostTask(
588 FROM_HERE,
589 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
590 base::Unretained(this),
591 &compositor2));
592
593 Wait(main_thread_);
594 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
595
596 // One compositor destroys their impl tree.
[email protected]9260757f2013-09-17 01:24:16597 compositor1->Run(100, false);
[email protected]9794fb32013-08-29 09:49:59598
599 // Then the main thread reference is destroyed.
600 main_thread_.message_loop()->PostTask(
601 FROM_HERE,
602 base::Bind(&TextureLayerMailboxHolderTest::ReleaseMainRef,
603 base::Unretained(this)));
604
605 Wait(main_thread_);
606
607 EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0);
608 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
609
610 // The second impl reference is destroyed last, causing the mailbox to be
611 // released back to the embedder with the last sync point from the impl tree.
612 EXPECT_CALL(test_data_.mock_callback_,
613 Release(test_data_.mailbox_name1_, 200, true)).Times(1);
614
[email protected]9260757f2013-09-17 01:24:16615 compositor2->Run(200, true);
[email protected]9794fb32013-08-29 09:49:59616 Wait(main_thread_);
617 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
618}
619
620TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_MainReleasedFirst) {
621 scoped_refptr<TextureLayer> test_layer = TextureLayer::CreateForMailbox(NULL);
622 ASSERT_TRUE(test_layer.get());
623
624 main_thread_.message_loop()->PostTask(
625 FROM_HERE,
626 base::Bind(&TextureLayerMailboxHolderTest::CreateMainRef,
627 base::Unretained(this)));
628
629 Wait(main_thread_);
630
631 // The texture layer is attached to compositor1, and passes a reference to its
632 // impl tree.
[email protected]9260757f2013-09-17 01:24:16633 scoped_ptr<SingleReleaseCallback> compositor1;
[email protected]9794fb32013-08-29 09:49:59634 main_thread_.message_loop()->PostTask(
635 FROM_HERE,
636 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
637 base::Unretained(this),
638 &compositor1));
639
640 // Then the texture layer is removed and attached to compositor2, and passes a
641 // reference to its impl tree.
[email protected]9260757f2013-09-17 01:24:16642 scoped_ptr<SingleReleaseCallback> compositor2;
[email protected]9794fb32013-08-29 09:49:59643 main_thread_.message_loop()->PostTask(
644 FROM_HERE,
645 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
646 base::Unretained(this),
647 &compositor2));
648
649 Wait(main_thread_);
650 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
651
652 // The main thread reference is destroyed first.
653 main_thread_.message_loop()->PostTask(
654 FROM_HERE,
655 base::Bind(&TextureLayerMailboxHolderTest::ReleaseMainRef,
656 base::Unretained(this)));
657
658 // One compositor destroys their impl tree.
[email protected]9260757f2013-09-17 01:24:16659 compositor2->Run(200, false);
[email protected]9794fb32013-08-29 09:49:59660
661 Wait(main_thread_);
662
663 EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0);
664 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
665
666 // The second impl reference is destroyed last, causing the mailbox to be
667 // released back to the embedder with the last sync point from the impl tree.
668 EXPECT_CALL(test_data_.mock_callback_,
669 Release(test_data_.mailbox_name1_, 100, true)).Times(1);
670
[email protected]9260757f2013-09-17 01:24:16671 compositor1->Run(100, true);
[email protected]9794fb32013-08-29 09:49:59672 Wait(main_thread_);
673 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
674}
675
676TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_SecondImplRefShortcut) {
677 scoped_refptr<TextureLayer> test_layer = TextureLayer::CreateForMailbox(NULL);
678 ASSERT_TRUE(test_layer.get());
679
680 main_thread_.message_loop()->PostTask(
681 FROM_HERE,
682 base::Bind(&TextureLayerMailboxHolderTest::CreateMainRef,
683 base::Unretained(this)));
684
685 Wait(main_thread_);
686
687 // The texture layer is attached to compositor1, and passes a reference to its
688 // impl tree.
[email protected]9260757f2013-09-17 01:24:16689 scoped_ptr<SingleReleaseCallback> compositor1;
[email protected]9794fb32013-08-29 09:49:59690 main_thread_.message_loop()->PostTask(
691 FROM_HERE,
692 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
693 base::Unretained(this),
694 &compositor1));
695
696 // Then the texture layer is removed and attached to compositor2, and passes a
697 // reference to its impl tree.
[email protected]9260757f2013-09-17 01:24:16698 scoped_ptr<SingleReleaseCallback> compositor2;
[email protected]9794fb32013-08-29 09:49:59699 main_thread_.message_loop()->PostTask(
700 FROM_HERE,
701 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
702 base::Unretained(this),
703 &compositor2));
704
705 Wait(main_thread_);
706 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
707
708 // The main thread reference is destroyed first.
709 main_thread_.message_loop()->PostTask(
710 FROM_HERE,
711 base::Bind(&TextureLayerMailboxHolderTest::ReleaseMainRef,
712 base::Unretained(this)));
713
714 EXPECT_CALL(test_data_.mock_callback_,
715 Release(test_data_.mailbox_name1_, 200, true)).Times(1);
716
717 bool manual_reset = false;
718 bool initially_signaled = false;
719 base::WaitableEvent begin_capture(manual_reset, initially_signaled);
720 base::WaitableEvent wait_for_capture(manual_reset, initially_signaled);
721 base::WaitableEvent stop_capture(manual_reset, initially_signaled);
722
723 // Post a task to start capturing tasks on the main thread. This will block
724 // the main thread until we signal the |stop_capture| event.
725 main_thread_.message_loop()->PostTask(
726 FROM_HERE,
727 base::Bind(&TextureLayerMailboxHolderTest::CapturePostTasksAndWait,
728 base::Unretained(this),
729 &begin_capture,
730 &wait_for_capture,
731 &stop_capture));
732
733 // Before the main thread capturing starts, one compositor destroys their
734 // impl reference. Since capturing did not start, this gets post-tasked to
735 // the main thread.
[email protected]9260757f2013-09-17 01:24:16736 compositor1->Run(100, false);
[email protected]9794fb32013-08-29 09:49:59737
738 // Start capturing on the main thread.
739 begin_capture.Signal();
740 wait_for_capture.Wait();
741
742 // Meanwhile, the second compositor released its impl reference, but this task
743 // gets shortcutted directly to the main thread. This means the reference is
744 // released before compositor1, whose reference will be released later when
745 // the post-task is serviced. But since it was destroyed _on the impl thread_
746 // last, its sync point values should be used.
[email protected]9260757f2013-09-17 01:24:16747 compositor2->Run(200, true);
[email protected]9794fb32013-08-29 09:49:59748
749 stop_capture.Signal();
750 Wait(main_thread_);
751
752 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
753}
754
[email protected]e216fef02013-03-20 22:56:10755class TextureLayerImplWithMailboxThreadedCallback : public LayerTreeTest {
[email protected]28571b042013-03-14 07:59:15756 public:
757 TextureLayerImplWithMailboxThreadedCallback()
758 : callback_count_(0),
759 commit_count_(0) {}
760
761 // Make sure callback is received on main and doesn't block the impl thread.
[email protected]df41e252014-02-03 23:39:50762 void ReleaseCallback(uint32 sync_point, bool lost_resource) {
[email protected]9794fb32013-08-29 09:49:59763 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]7ba3ca72013-04-11 06:37:25764 EXPECT_FALSE(lost_resource);
[email protected]28571b042013-03-14 07:59:15765 ++callback_count_;
766 }
767
768 void SetMailbox(char mailbox_char) {
[email protected]9794fb32013-08-29 09:49:59769 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]9260757f2013-09-17 01:24:16770 scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create(
[email protected]28571b042013-03-14 07:59:15771 base::Bind(
772 &TextureLayerImplWithMailboxThreadedCallback::ReleaseCallback,
773 base::Unretained(this)));
[email protected]df41e252014-02-03 23:39:50774 layer_->SetTextureMailbox(
[email protected]e0a4d732014-02-15 00:23:26775 TextureMailbox(MailboxFromChar(mailbox_char), GL_TEXTURE_2D, 0),
[email protected]df41e252014-02-03 23:39:50776 callback.Pass());
[email protected]28571b042013-03-14 07:59:15777 }
778
[email protected]e216fef02013-03-20 22:56:10779 virtual void BeginTest() OVERRIDE {
[email protected]9794fb32013-08-29 09:49:59780 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
781
[email protected]28571b042013-03-14 07:59:15782 gfx::Size bounds(100, 100);
783 root_ = Layer::Create();
784 root_->SetAnchorPoint(gfx::PointF());
785 root_->SetBounds(bounds);
786
[email protected]e8e4ae232013-04-12 00:26:01787 layer_ = TextureLayer::CreateForMailbox(NULL);
[email protected]28571b042013-03-14 07:59:15788 layer_->SetIsDrawable(true);
789 layer_->SetAnchorPoint(gfx::PointF());
790 layer_->SetBounds(bounds);
791
792 root_->AddChild(layer_);
[email protected]e216fef02013-03-20 22:56:10793 layer_tree_host()->SetRootLayer(root_);
[email protected]18ce59702013-04-09 04:58:40794 layer_tree_host()->SetViewportSize(bounds);
[email protected]28571b042013-03-14 07:59:15795 SetMailbox('1');
796 EXPECT_EQ(0, callback_count_);
797
798 // Case #1: change mailbox before the commit. The old mailbox should be
799 // released immediately.
800 SetMailbox('2');
801 EXPECT_EQ(1, callback_count_);
[email protected]e216fef02013-03-20 22:56:10802 PostSetNeedsCommitToMainThread();
[email protected]28571b042013-03-14 07:59:15803 }
804
[email protected]e216fef02013-03-20 22:56:10805 virtual void DidCommit() OVERRIDE {
[email protected]28571b042013-03-14 07:59:15806 ++commit_count_;
807 switch (commit_count_) {
808 case 1:
809 // Case #2: change mailbox after the commit (and draw), where the
810 // layer draws. The old mailbox should be released during the next
811 // commit.
812 SetMailbox('3');
813 EXPECT_EQ(1, callback_count_);
814 break;
815 case 2:
[email protected]28571b042013-03-14 07:59:15816 EXPECT_EQ(2, callback_count_);
817 // Case #3: change mailbox when the layer doesn't draw. The old
818 // mailbox should be released during the next commit.
819 layer_->SetBounds(gfx::Size());
820 SetMailbox('4');
821 break;
[email protected]9794fb32013-08-29 09:49:59822 case 3:
[email protected]28571b042013-03-14 07:59:15823 EXPECT_EQ(3, callback_count_);
824 // Case #4: release mailbox that was committed but never drawn. The
825 // old mailbox should be released during the next commit.
[email protected]9260757f2013-09-17 01:24:16826 layer_->SetTextureMailbox(TextureMailbox(),
827 scoped_ptr<SingleReleaseCallback>());
[email protected]28571b042013-03-14 07:59:15828 break;
[email protected]9794fb32013-08-29 09:49:59829 case 4:
830 if (layer_tree_host()->settings().impl_side_painting) {
831 // With impl painting, the texture mailbox will still be on the impl
832 // thread when the commit finishes, because the layer is not drawble
833 // when it has no texture mailbox, and thus does not block the commit
834 // on activation. So, we wait for activation.
835 // TODO(danakj): fix this. crbug.com/277953
836 layer_tree_host()->SetNeedsCommit();
837 break;
838 } else {
839 ++commit_count_;
840 }
841 case 5:
[email protected]28571b042013-03-14 07:59:15842 EXPECT_EQ(4, callback_count_);
[email protected]7096acc2013-06-18 21:12:43843 // Restore a mailbox for the next step.
844 SetMailbox('5');
845 break;
[email protected]9794fb32013-08-29 09:49:59846 case 6:
[email protected]7096acc2013-06-18 21:12:43847 // Case #5: remove layer from tree. Callback should *not* be called, the
848 // mailbox is returned to the main thread.
849 EXPECT_EQ(4, callback_count_);
850 layer_->RemoveFromParent();
851 break;
[email protected]9794fb32013-08-29 09:49:59852 case 7:
853 if (layer_tree_host()->settings().impl_side_painting) {
854 // With impl painting, the texture mailbox will still be on the impl
855 // thread when the commit finishes, because the layer is not around to
856 // block the commit on activation anymore. So, we wait for activation.
857 // TODO(danakj): fix this. crbug.com/277953
858 layer_tree_host()->SetNeedsCommit();
859 break;
860 } else {
861 ++commit_count_;
862 }
863 case 8:
[email protected]7096acc2013-06-18 21:12:43864 EXPECT_EQ(4, callback_count_);
865 // Resetting the mailbox will call the callback now.
[email protected]9260757f2013-09-17 01:24:16866 layer_->SetTextureMailbox(TextureMailbox(),
867 scoped_ptr<SingleReleaseCallback>());
[email protected]7096acc2013-06-18 21:12:43868 EXPECT_EQ(5, callback_count_);
[email protected]e216fef02013-03-20 22:56:10869 EndTest();
[email protected]28571b042013-03-14 07:59:15870 break;
871 default:
872 NOTREACHED();
873 break;
[email protected]de44a152013-01-08 15:28:46874 }
[email protected]28571b042013-03-14 07:59:15875 }
[email protected]de44a152013-01-08 15:28:46876
[email protected]e216fef02013-03-20 22:56:10877 virtual void AfterTest() OVERRIDE {}
[email protected]de44a152013-01-08 15:28:46878
[email protected]28571b042013-03-14 07:59:15879 private:
[email protected]9794fb32013-08-29 09:49:59880 base::ThreadChecker main_thread_;
[email protected]28571b042013-03-14 07:59:15881 int callback_count_;
882 int commit_count_;
883 scoped_refptr<Layer> root_;
884 scoped_refptr<TextureLayer> layer_;
[email protected]de44a152013-01-08 15:28:46885};
886
[email protected]4145d172013-05-10 16:54:36887SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
888 TextureLayerImplWithMailboxThreadedCallback);
[email protected]de44a152013-01-08 15:28:46889
[email protected]74b43cc2013-08-30 06:29:27890
891class TextureLayerNoMailboxIsActivatedDuringCommit : public LayerTreeTest,
892 public TextureLayerClient {
893 protected:
894 TextureLayerNoMailboxIsActivatedDuringCommit()
[email protected]98ea818e2014-01-24 10:22:08895 : texture_(0u), activate_count_(0) {}
[email protected]74b43cc2013-08-30 06:29:27896
897 virtual void BeginTest() OVERRIDE {
[email protected]74b43cc2013-08-30 06:29:27898 gfx::Size bounds(100, 100);
899 root_ = Layer::Create();
900 root_->SetAnchorPoint(gfx::PointF());
901 root_->SetBounds(bounds);
902
903 layer_ = TextureLayer::Create(this);
904 layer_->SetIsDrawable(true);
905 layer_->SetAnchorPoint(gfx::PointF());
906 layer_->SetBounds(bounds);
907
908 root_->AddChild(layer_);
909 layer_tree_host()->SetRootLayer(root_);
910 layer_tree_host()->SetViewportSize(bounds);
911
912 PostSetNeedsCommitToMainThread();
913 }
914
[email protected]a6366932014-02-05 20:12:47915 virtual scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface(bool fallback)
[email protected]f5931d42013-11-06 19:44:57916 OVERRIDE {
917 scoped_refptr<TestContextProvider> provider = TestContextProvider::Create();
918 texture_ = provider->UnboundTestContext3d()->createExternalTexture();
[email protected]a6366932014-02-05 20:12:47919 return FakeOutputSurface::Create3d(provider);
[email protected]f5931d42013-11-06 19:44:57920 }
921
[email protected]74b43cc2013-08-30 06:29:27922 // TextureLayerClient implementation.
923 virtual unsigned PrepareTexture() OVERRIDE {
[email protected]f5931d42013-11-06 19:44:57924 return texture_;
[email protected]74b43cc2013-08-30 06:29:27925 }
[email protected]9260757f2013-09-17 01:24:16926 virtual bool PrepareTextureMailbox(
927 TextureMailbox* mailbox,
928 scoped_ptr<SingleReleaseCallback>* release_callback,
929 bool use_shared_memory) OVERRIDE {
[email protected]74b43cc2013-08-30 06:29:27930 return false;
931 }
932
933 virtual void WillActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
[email protected]74b43cc2013-08-30 06:29:27934 ++activate_count_;
935 }
936
[email protected]98ea818e2014-01-24 10:22:08937 virtual void DidCommit() OVERRIDE {
938 switch (layer_tree_host()->source_frame_number()) {
[email protected]74b43cc2013-08-30 06:29:27939 case 1:
940 // The first texture has been activated. Invalidate the layer so it
941 // grabs a new texture id from the client.
942 layer_->SetNeedsDisplay();
[email protected]74b43cc2013-08-30 06:29:27943 break;
944 case 2:
945 // The second mailbox has been activated. Remove the layer from
946 // the tree to cause another commit/activation. The commit should
947 // finish *after* the layer is removed from the active tree.
948 layer_->RemoveFromParent();
[email protected]74b43cc2013-08-30 06:29:27949 break;
950 case 3:
951 EndTest();
952 break;
953 }
954 }
955
[email protected]98ea818e2014-01-24 10:22:08956 virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
957 switch (host_impl->active_tree()->source_frame_number()) {
[email protected]74b43cc2013-08-30 06:29:27958 case 2: {
959 // The activate for the 2nd texture should have happened before now.
[email protected]74b43cc2013-08-30 06:29:27960 EXPECT_EQ(2, activate_count_);
961 break;
962 }
963 case 3: {
964 // The activate to remove the layer should have happened before now.
[email protected]74b43cc2013-08-30 06:29:27965 EXPECT_EQ(3, activate_count_);
966 break;
967 }
968 }
969 }
970
[email protected]74b43cc2013-08-30 06:29:27971 virtual void AfterTest() OVERRIDE {}
972
[email protected]f5931d42013-11-06 19:44:57973 unsigned texture_;
[email protected]74b43cc2013-08-30 06:29:27974 int activate_count_;
[email protected]74b43cc2013-08-30 06:29:27975 scoped_refptr<Layer> root_;
976 scoped_refptr<TextureLayer> layer_;
977};
978
979SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
980 TextureLayerNoMailboxIsActivatedDuringCommit);
981
982class TextureLayerMailboxIsActivatedDuringCommit : public LayerTreeTest {
983 protected:
[email protected]98ea818e2014-01-24 10:22:08984 TextureLayerMailboxIsActivatedDuringCommit() : activate_count_(0) {}
[email protected]74b43cc2013-08-30 06:29:27985
[email protected]df41e252014-02-03 23:39:50986 static void ReleaseCallback(uint32 sync_point, bool lost_resource) {}
[email protected]74b43cc2013-08-30 06:29:27987
988 void SetMailbox(char mailbox_char) {
[email protected]9260757f2013-09-17 01:24:16989 scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create(
[email protected]74b43cc2013-08-30 06:29:27990 base::Bind(
991 &TextureLayerMailboxIsActivatedDuringCommit::ReleaseCallback));
[email protected]df41e252014-02-03 23:39:50992 layer_->SetTextureMailbox(
[email protected]e0a4d732014-02-15 00:23:26993 TextureMailbox(MailboxFromChar(mailbox_char), GL_TEXTURE_2D, 0),
[email protected]df41e252014-02-03 23:39:50994 callback.Pass());
[email protected]74b43cc2013-08-30 06:29:27995 }
996
997 virtual void BeginTest() OVERRIDE {
[email protected]74b43cc2013-08-30 06:29:27998 gfx::Size bounds(100, 100);
999 root_ = Layer::Create();
1000 root_->SetAnchorPoint(gfx::PointF());
1001 root_->SetBounds(bounds);
1002
1003 layer_ = TextureLayer::CreateForMailbox(NULL);
1004 layer_->SetIsDrawable(true);
1005 layer_->SetAnchorPoint(gfx::PointF());
1006 layer_->SetBounds(bounds);
1007
1008 root_->AddChild(layer_);
1009 layer_tree_host()->SetRootLayer(root_);
1010 layer_tree_host()->SetViewportSize(bounds);
1011 SetMailbox('1');
1012
1013 PostSetNeedsCommitToMainThread();
1014 }
1015
1016 virtual void WillActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
[email protected]74b43cc2013-08-30 06:29:271017 ++activate_count_;
1018 }
1019
[email protected]98ea818e2014-01-24 10:22:081020 virtual void DidCommit() OVERRIDE {
1021 switch (layer_tree_host()->source_frame_number()) {
[email protected]74b43cc2013-08-30 06:29:271022 case 1:
1023 // The first mailbox has been activated. Set a new mailbox, and
1024 // expect the next commit to finish *after* it is activated.
1025 SetMailbox('2');
[email protected]74b43cc2013-08-30 06:29:271026 break;
1027 case 2:
1028 // The second mailbox has been activated. Remove the layer from
1029 // the tree to cause another commit/activation. The commit should
1030 // finish *after* the layer is removed from the active tree.
1031 layer_->RemoveFromParent();
[email protected]74b43cc2013-08-30 06:29:271032 break;
1033 case 3:
1034 EndTest();
1035 break;
1036 }
1037 }
1038
[email protected]98ea818e2014-01-24 10:22:081039 virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
1040 switch (host_impl->active_tree()->source_frame_number()) {
[email protected]74b43cc2013-08-30 06:29:271041 case 2: {
1042 // The activate for the 2nd mailbox should have happened before now.
[email protected]74b43cc2013-08-30 06:29:271043 EXPECT_EQ(2, activate_count_);
1044 break;
1045 }
1046 case 3: {
1047 // The activate to remove the layer should have happened before now.
[email protected]74b43cc2013-08-30 06:29:271048 EXPECT_EQ(3, activate_count_);
1049 break;
1050 }
1051 }
1052 }
1053
1054
1055 virtual void AfterTest() OVERRIDE {}
1056
[email protected]74b43cc2013-08-30 06:29:271057 int activate_count_;
1058 scoped_refptr<Layer> root_;
1059 scoped_refptr<TextureLayer> layer_;
1060};
1061
1062SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
1063 TextureLayerMailboxIsActivatedDuringCommit);
1064
[email protected]de44a152013-01-08 15:28:461065class TextureLayerImplWithMailboxTest : public TextureLayerTest {
[email protected]28571b042013-03-14 07:59:151066 protected:
[email protected]408b5e22013-03-19 09:48:091067 TextureLayerImplWithMailboxTest()
1068 : fake_client_(
1069 FakeLayerTreeHostClient(FakeLayerTreeHostClient::DIRECT_3D)) {}
1070
[email protected]28571b042013-03-14 07:59:151071 virtual void SetUp() {
1072 TextureLayerTest::SetUp();
[email protected]408b5e22013-03-19 09:48:091073 layer_tree_host_.reset(new MockLayerTreeHost(&fake_client_));
[email protected]a6366932014-02-05 20:12:471074 EXPECT_TRUE(host_impl_.InitializeRenderer(
1075 FakeOutputSurface::Create3d().PassAs<OutputSurface>()));
[email protected]28571b042013-03-14 07:59:151076 }
[email protected]de44a152013-01-08 15:28:461077
[email protected]0ec335c42013-07-04 06:17:081078 bool WillDraw(TextureLayerImpl* layer, DrawMode mode) {
1079 bool will_draw = layer->WillDraw(
1080 mode, host_impl_.active_tree()->resource_provider());
1081 if (will_draw)
1082 layer->DidDraw(host_impl_.active_tree()->resource_provider());
1083 return will_draw;
1084 }
1085
[email protected]28571b042013-03-14 07:59:151086 CommonMailboxObjects test_data_;
[email protected]408b5e22013-03-19 09:48:091087 FakeLayerTreeHostClient fake_client_;
[email protected]de44a152013-01-08 15:28:461088};
1089
[email protected]ffbb2212013-06-02 23:47:591090// Test conditions for results of TextureLayerImpl::WillDraw under
1091// different configurations of different mailbox, texture_id, and draw_mode.
1092TEST_F(TextureLayerImplWithMailboxTest, TestWillDraw) {
[email protected]0ec335c42013-07-04 06:17:081093 EXPECT_CALL(test_data_.mock_callback_,
1094 Release(test_data_.mailbox_name1_,
1095 test_data_.sync_point1_,
1096 false))
1097 .Times(AnyNumber());
1098 EXPECT_CALL(test_data_.mock_callback_,
1099 Release2(test_data_.shared_memory_.get(), 0, false))
1100 .Times(AnyNumber());
[email protected]ffbb2212013-06-02 23:47:591101 // Hardware mode.
1102 {
1103 scoped_ptr<TextureLayerImpl> impl_layer =
1104 TextureLayerImpl::Create(host_impl_.active_tree(), 1, true);
[email protected]afc4f262013-10-05 01:14:101105 impl_layer->SetDrawsContent(true);
[email protected]9260757f2013-09-17 01:24:161106 impl_layer->SetTextureMailbox(
1107 test_data_.mailbox1_,
1108 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
[email protected]0ec335c42013-07-04 06:17:081109 EXPECT_TRUE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE));
[email protected]ffbb2212013-06-02 23:47:591110 }
1111
1112 {
1113 scoped_ptr<TextureLayerImpl> impl_layer =
1114 TextureLayerImpl::Create(host_impl_.active_tree(), 1, true);
[email protected]afc4f262013-10-05 01:14:101115 impl_layer->SetDrawsContent(true);
[email protected]9260757f2013-09-17 01:24:161116 impl_layer->SetTextureMailbox(TextureMailbox(),
1117 scoped_ptr<SingleReleaseCallback>());
[email protected]0ec335c42013-07-04 06:17:081118 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE));
1119 }
1120
1121 {
1122 // Software resource.
1123 scoped_ptr<TextureLayerImpl> impl_layer =
1124 TextureLayerImpl::Create(host_impl_.active_tree(), 1, true);
[email protected]afc4f262013-10-05 01:14:101125 impl_layer->SetDrawsContent(true);
[email protected]9260757f2013-09-17 01:24:161126 impl_layer->SetTextureMailbox(
1127 test_data_.mailbox3_,
1128 SingleReleaseCallback::Create(test_data_.release_mailbox3_));
[email protected]3e44d7a2013-07-30 00:03:101129 EXPECT_TRUE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE));
[email protected]ffbb2212013-06-02 23:47:591130 }
1131
1132 {
1133 scoped_ptr<TextureLayerImpl> impl_layer =
1134 TextureLayerImpl::Create(host_impl_.active_tree(), 1, false);
[email protected]afc4f262013-10-05 01:14:101135 impl_layer->SetDrawsContent(true);
[email protected]0634cdd42013-08-16 00:46:091136 ContextProvider* context_provider =
1137 host_impl_.output_surface()->context_provider();
[email protected]1dff7962014-01-10 12:05:031138 GLuint texture = 0;
1139 context_provider->ContextGL()->GenTextures(1, &texture);
[email protected]ad0250b2014-01-18 03:24:341140 impl_layer->SetTextureId(texture);
[email protected]0ec335c42013-07-04 06:17:081141 EXPECT_TRUE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE));
[email protected]ffbb2212013-06-02 23:47:591142 }
1143
1144 {
1145 scoped_ptr<TextureLayerImpl> impl_layer =
1146 TextureLayerImpl::Create(host_impl_.active_tree(), 1, false);
[email protected]afc4f262013-10-05 01:14:101147 impl_layer->SetDrawsContent(true);
[email protected]ad0250b2014-01-18 03:24:341148 impl_layer->SetTextureId(0);
[email protected]0ec335c42013-07-04 06:17:081149 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE));
1150 }
1151
1152 // Software mode.
1153 {
1154 scoped_ptr<TextureLayerImpl> impl_layer =
1155 TextureLayerImpl::Create(host_impl_.active_tree(), 1, true);
[email protected]afc4f262013-10-05 01:14:101156 impl_layer->SetDrawsContent(true);
[email protected]9260757f2013-09-17 01:24:161157 impl_layer->SetTextureMailbox(
1158 test_data_.mailbox1_,
1159 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
[email protected]0ec335c42013-07-04 06:17:081160 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE));
1161 }
1162
1163 {
1164 scoped_ptr<TextureLayerImpl> impl_layer =
1165 TextureLayerImpl::Create(host_impl_.active_tree(), 1, true);
[email protected]afc4f262013-10-05 01:14:101166 impl_layer->SetDrawsContent(true);
[email protected]9260757f2013-09-17 01:24:161167 impl_layer->SetTextureMailbox(TextureMailbox(),
1168 scoped_ptr<SingleReleaseCallback>());
[email protected]0ec335c42013-07-04 06:17:081169 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE));
1170 }
1171
1172 {
1173 // Software resource.
1174 scoped_ptr<TextureLayerImpl> impl_layer =
1175 TextureLayerImpl::Create(host_impl_.active_tree(), 1, true);
[email protected]afc4f262013-10-05 01:14:101176 impl_layer->SetDrawsContent(true);
[email protected]9260757f2013-09-17 01:24:161177 impl_layer->SetTextureMailbox(
1178 test_data_.mailbox3_,
1179 SingleReleaseCallback::Create(test_data_.release_mailbox3_));
[email protected]0ec335c42013-07-04 06:17:081180 EXPECT_TRUE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE));
1181 }
1182
1183 {
1184 scoped_ptr<TextureLayerImpl> impl_layer =
1185 TextureLayerImpl::Create(host_impl_.active_tree(), 1, false);
[email protected]afc4f262013-10-05 01:14:101186 impl_layer->SetDrawsContent(true);
[email protected]0634cdd42013-08-16 00:46:091187 ContextProvider* context_provider =
1188 host_impl_.output_surface()->context_provider();
[email protected]1dff7962014-01-10 12:05:031189 GLuint texture = 0;
1190 context_provider->ContextGL()->GenTextures(1, &texture);
[email protected]ad0250b2014-01-18 03:24:341191 impl_layer->SetTextureId(texture);
[email protected]0ec335c42013-07-04 06:17:081192 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE));
1193 }
1194
1195 {
1196 scoped_ptr<TextureLayerImpl> impl_layer =
1197 TextureLayerImpl::Create(host_impl_.active_tree(), 1, false);
[email protected]afc4f262013-10-05 01:14:101198 impl_layer->SetDrawsContent(true);
[email protected]ad0250b2014-01-18 03:24:341199 impl_layer->SetTextureId(0);
[email protected]0ec335c42013-07-04 06:17:081200 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE));
[email protected]ffbb2212013-06-02 23:47:591201 }
1202
1203 // Resourceless software mode.
1204 {
1205 scoped_ptr<TextureLayerImpl> impl_layer =
1206 TextureLayerImpl::Create(host_impl_.active_tree(), 1, true);
[email protected]afc4f262013-10-05 01:14:101207 impl_layer->SetDrawsContent(true);
[email protected]9260757f2013-09-17 01:24:161208 impl_layer->SetTextureMailbox(
1209 test_data_.mailbox1_,
1210 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
[email protected]0ec335c42013-07-04 06:17:081211 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_RESOURCELESS_SOFTWARE));
[email protected]ffbb2212013-06-02 23:47:591212 }
1213
1214 {
1215 scoped_ptr<TextureLayerImpl> impl_layer =
1216 TextureLayerImpl::Create(host_impl_.active_tree(), 1, false);
[email protected]afc4f262013-10-05 01:14:101217 impl_layer->SetDrawsContent(true);
[email protected]0634cdd42013-08-16 00:46:091218 ContextProvider* context_provider =
1219 host_impl_.output_surface()->context_provider();
[email protected]1dff7962014-01-10 12:05:031220 GLuint texture = 0;
1221 context_provider->ContextGL()->GenTextures(1, &texture);
[email protected]ad0250b2014-01-18 03:24:341222 impl_layer->SetTextureId(texture);
[email protected]0ec335c42013-07-04 06:17:081223 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_RESOURCELESS_SOFTWARE));
[email protected]ffbb2212013-06-02 23:47:591224 }
1225}
1226
[email protected]28571b042013-03-14 07:59:151227TEST_F(TextureLayerImplWithMailboxTest, TestImplLayerCallbacks) {
1228 host_impl_.CreatePendingTree();
1229 scoped_ptr<TextureLayerImpl> pending_layer;
1230 pending_layer = TextureLayerImpl::Create(host_impl_.pending_tree(), 1, true);
1231 ASSERT_TRUE(pending_layer);
[email protected]de44a152013-01-08 15:28:461232
[email protected]ed511b8d2013-03-25 03:29:291233 scoped_ptr<LayerImpl> active_layer(
[email protected]28571b042013-03-14 07:59:151234 pending_layer->CreateLayerImpl(host_impl_.active_tree()));
[email protected]ed511b8d2013-03-25 03:29:291235 ASSERT_TRUE(active_layer);
[email protected]de44a152013-01-08 15:28:461236
[email protected]9260757f2013-09-17 01:24:161237 pending_layer->SetTextureMailbox(
1238 test_data_.mailbox1_,
1239 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
[email protected]421e84f2013-02-22 03:27:151240
[email protected]28571b042013-03-14 07:59:151241 // Test multiple commits without an activation.
1242 EXPECT_CALL(test_data_.mock_callback_,
[email protected]7ba3ca72013-04-11 06:37:251243 Release(test_data_.mailbox_name1_,
1244 test_data_.sync_point1_,
1245 false))
[email protected]28571b042013-03-14 07:59:151246 .Times(1);
[email protected]9260757f2013-09-17 01:24:161247 pending_layer->SetTextureMailbox(
1248 test_data_.mailbox2_,
1249 SingleReleaseCallback::Create(test_data_.release_mailbox2_));
[email protected]28571b042013-03-14 07:59:151250 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]421e84f2013-02-22 03:27:151251
[email protected]28571b042013-03-14 07:59:151252 // Test callback after activation.
[email protected]ed511b8d2013-03-25 03:29:291253 pending_layer->PushPropertiesTo(active_layer.get());
1254 active_layer->DidBecomeActive();
[email protected]421e84f2013-02-22 03:27:151255
[email protected]7ba3ca72013-04-11 06:37:251256 EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0);
[email protected]9260757f2013-09-17 01:24:161257 pending_layer->SetTextureMailbox(
1258 test_data_.mailbox1_,
1259 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
[email protected]28571b042013-03-14 07:59:151260 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]421e84f2013-02-22 03:27:151261
[email protected]7ba3ca72013-04-11 06:37:251262 EXPECT_CALL(test_data_.mock_callback_,
1263 Release(test_data_.mailbox_name2_, _, false))
[email protected]28571b042013-03-14 07:59:151264 .Times(1);
[email protected]ed511b8d2013-03-25 03:29:291265 pending_layer->PushPropertiesTo(active_layer.get());
1266 active_layer->DidBecomeActive();
[email protected]28571b042013-03-14 07:59:151267 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]de44a152013-01-08 15:28:461268
[email protected]28571b042013-03-14 07:59:151269 // Test resetting the mailbox.
[email protected]7ba3ca72013-04-11 06:37:251270 EXPECT_CALL(test_data_.mock_callback_,
1271 Release(test_data_.mailbox_name1_, _, false))
[email protected]28571b042013-03-14 07:59:151272 .Times(1);
[email protected]9260757f2013-09-17 01:24:161273 pending_layer->SetTextureMailbox(TextureMailbox(),
1274 scoped_ptr<SingleReleaseCallback>());
[email protected]ed511b8d2013-03-25 03:29:291275 pending_layer->PushPropertiesTo(active_layer.get());
1276 active_layer->DidBecomeActive();
[email protected]28571b042013-03-14 07:59:151277 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]de44a152013-01-08 15:28:461278
[email protected]28571b042013-03-14 07:59:151279 // Test destructor.
1280 EXPECT_CALL(test_data_.mock_callback_,
[email protected]7ba3ca72013-04-11 06:37:251281 Release(test_data_.mailbox_name1_,
1282 test_data_.sync_point1_,
1283 false))
[email protected]28571b042013-03-14 07:59:151284 .Times(1);
[email protected]9260757f2013-09-17 01:24:161285 pending_layer->SetTextureMailbox(
1286 test_data_.mailbox1_,
1287 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
[email protected]de44a152013-01-08 15:28:461288}
1289
[email protected]28571b042013-03-14 07:59:151290TEST_F(TextureLayerImplWithMailboxTest,
1291 TestDestructorCallbackOnCreatedResource) {
1292 scoped_ptr<TextureLayerImpl> impl_layer;
1293 impl_layer = TextureLayerImpl::Create(host_impl_.active_tree(), 1, true);
1294 ASSERT_TRUE(impl_layer);
[email protected]de44a152013-01-08 15:28:461295
[email protected]7ba3ca72013-04-11 06:37:251296 EXPECT_CALL(test_data_.mock_callback_,
1297 Release(test_data_.mailbox_name1_, _, false))
[email protected]28571b042013-03-14 07:59:151298 .Times(1);
[email protected]9260757f2013-09-17 01:24:161299 impl_layer->SetTextureMailbox(
1300 test_data_.mailbox1_,
1301 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
[email protected]afc4f262013-10-05 01:14:101302 impl_layer->SetDrawsContent(true);
[email protected]ffbb2212013-06-02 23:47:591303 impl_layer->DidBecomeActive();
1304 EXPECT_TRUE(impl_layer->WillDraw(
1305 DRAW_MODE_HARDWARE, host_impl_.active_tree()->resource_provider()));
[email protected]28571b042013-03-14 07:59:151306 impl_layer->DidDraw(host_impl_.active_tree()->resource_provider());
[email protected]9260757f2013-09-17 01:24:161307 impl_layer->SetTextureMailbox(TextureMailbox(),
1308 scoped_ptr<SingleReleaseCallback>());
[email protected]de44a152013-01-08 15:28:461309}
1310
[email protected]28571b042013-03-14 07:59:151311TEST_F(TextureLayerImplWithMailboxTest, TestCallbackOnInUseResource) {
1312 ResourceProvider* provider = host_impl_.active_tree()->resource_provider();
1313 ResourceProvider::ResourceId id =
[email protected]9260757f2013-09-17 01:24:161314 provider->CreateResourceFromTextureMailbox(
1315 test_data_.mailbox1_,
1316 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
[email protected]28571b042013-03-14 07:59:151317 provider->AllocateForTesting(id);
[email protected]de44a152013-01-08 15:28:461318
[email protected]28571b042013-03-14 07:59:151319 // Transfer some resources to the parent.
1320 ResourceProvider::ResourceIdArray resource_ids_to_transfer;
1321 resource_ids_to_transfer.push_back(id);
1322 TransferableResourceArray list;
1323 provider->PrepareSendToParent(resource_ids_to_transfer, &list);
1324 EXPECT_TRUE(provider->InUseByConsumer(id));
[email protected]7ba3ca72013-04-11 06:37:251325 EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0);
[email protected]28571b042013-03-14 07:59:151326 provider->DeleteResource(id);
1327 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]7ba3ca72013-04-11 06:37:251328 EXPECT_CALL(test_data_.mock_callback_,
1329 Release(test_data_.mailbox_name1_, _, false))
[email protected]28571b042013-03-14 07:59:151330 .Times(1);
[email protected]e00bab022013-08-19 00:42:451331 ReturnedResourceArray returned;
1332 TransferableResource::ReturnResources(list, &returned);
1333 provider->ReceiveReturnsFromParent(returned);
[email protected]de44a152013-01-08 15:28:461334}
1335
[email protected]97d519fb2013-03-29 02:27:541336// Check that ClearClient correctly clears the state so that the impl side
1337// doesn't try to use a texture that could have been destroyed.
[email protected]7ba3ca72013-04-11 06:37:251338class TextureLayerClientTest
1339 : public LayerTreeTest,
1340 public TextureLayerClient {
[email protected]97d519fb2013-03-29 02:27:541341 public:
1342 TextureLayerClientTest()
[email protected]f5931d42013-11-06 19:44:571343 : texture_(0),
[email protected]97d519fb2013-03-29 02:27:541344 commit_count_(0),
1345 expected_used_textures_on_draw_(0),
1346 expected_used_textures_on_commit_(0) {}
1347
[email protected]a6366932014-02-05 20:12:471348 virtual scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface(bool fallback)
[email protected]ebc0e1df2013-08-01 02:46:221349 OVERRIDE {
[email protected]f5931d42013-11-06 19:44:571350 scoped_refptr<TestContextProvider> provider = TestContextProvider::Create();
1351 texture_ = provider->UnboundTestContext3d()->createExternalTexture();
[email protected]a6366932014-02-05 20:12:471352 return FakeOutputSurface::Create3d(provider);
[email protected]97d519fb2013-03-29 02:27:541353 }
1354
[email protected]f5931d42013-11-06 19:44:571355 virtual unsigned PrepareTexture() OVERRIDE { return texture_; }
[email protected]97d519fb2013-03-29 02:27:541356
[email protected]2541d1a2013-07-10 07:33:271357 virtual bool PrepareTextureMailbox(
[email protected]9260757f2013-09-17 01:24:161358 TextureMailbox* mailbox,
1359 scoped_ptr<SingleReleaseCallback>* release_callback,
1360 bool use_shared_memory) OVERRIDE {
[email protected]e8e4ae232013-04-12 00:26:011361 return false;
1362 }
1363
[email protected]97d519fb2013-03-29 02:27:541364 virtual void SetupTree() OVERRIDE {
1365 scoped_refptr<Layer> root = Layer::Create();
1366 root->SetBounds(gfx::Size(10, 10));
1367 root->SetAnchorPoint(gfx::PointF());
1368 root->SetIsDrawable(true);
1369
1370 texture_layer_ = TextureLayer::Create(this);
1371 texture_layer_->SetBounds(gfx::Size(10, 10));
1372 texture_layer_->SetAnchorPoint(gfx::PointF());
1373 texture_layer_->SetIsDrawable(true);
1374 root->AddChild(texture_layer_);
1375
1376 layer_tree_host()->SetRootLayer(root);
1377 LayerTreeTest::SetupTree();
1378 {
1379 base::AutoLock lock(lock_);
1380 expected_used_textures_on_commit_ = 1;
1381 }
1382 }
1383
1384 virtual void BeginTest() OVERRIDE {
1385 PostSetNeedsCommitToMainThread();
1386 }
1387
1388 virtual void DidCommitAndDrawFrame() OVERRIDE {
1389 ++commit_count_;
1390 switch (commit_count_) {
1391 case 1:
1392 texture_layer_->ClearClient();
1393 texture_layer_->SetNeedsDisplay();
1394 {
1395 base::AutoLock lock(lock_);
1396 expected_used_textures_on_commit_ = 0;
1397 }
[email protected]97d519fb2013-03-29 02:27:541398 break;
1399 case 2:
1400 EndTest();
1401 break;
1402 default:
1403 NOTREACHED();
1404 break;
1405 }
1406 }
1407
1408 virtual void BeginCommitOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
1409 base::AutoLock lock(lock_);
1410 expected_used_textures_on_draw_ = expected_used_textures_on_commit_;
1411 }
1412
[email protected]7ddfe7e82014-01-30 07:22:111413 virtual DrawSwapReadbackResult::DrawResult PrepareToDrawOnThread(
1414 LayerTreeHostImpl* host_impl,
1415 LayerTreeHostImpl::FrameData* frame_data,
1416 DrawSwapReadbackResult::DrawResult draw_result) OVERRIDE {
[email protected]f5931d42013-11-06 19:44:571417 ContextForImplThread(host_impl)->ResetUsedTextures();
[email protected]7ddfe7e82014-01-30 07:22:111418 return DrawSwapReadbackResult::DRAW_SUCCESS;
[email protected]97d519fb2013-03-29 02:27:541419 }
1420
1421 virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl,
1422 bool result) OVERRIDE {
1423 ASSERT_TRUE(result);
[email protected]f5931d42013-11-06 19:44:571424 EXPECT_EQ(expected_used_textures_on_draw_,
1425 ContextForImplThread(host_impl)->NumUsedTextures());
[email protected]97d519fb2013-03-29 02:27:541426 }
1427
1428 virtual void AfterTest() OVERRIDE {}
1429
1430 private:
[email protected]f5931d42013-11-06 19:44:571431 TestWebGraphicsContext3D* ContextForImplThread(LayerTreeHostImpl* host_impl) {
[email protected]1dff7962014-01-10 12:05:031432 return static_cast<TestContextProvider*>(
1433 host_impl->output_surface()->context_provider().get())->TestContext3d();
[email protected]f5931d42013-11-06 19:44:571434 }
1435
[email protected]97d519fb2013-03-29 02:27:541436 scoped_refptr<TextureLayer> texture_layer_;
[email protected]97d519fb2013-03-29 02:27:541437 unsigned texture_;
1438 int commit_count_;
1439
1440 // Used only on thread.
1441 unsigned expected_used_textures_on_draw_;
1442
1443 // Used on either thread, protected by lock_.
1444 base::Lock lock_;
1445 unsigned expected_used_textures_on_commit_;
1446};
1447
[email protected]4145d172013-05-10 16:54:361448// The TextureLayerClient does not use mailboxes, so can't use a delegating
1449// renderer.
1450SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(TextureLayerClientTest);
[email protected]97d519fb2013-03-29 02:27:541451
[email protected]b04264f92013-09-13 23:37:291452
1453// Checks that changing a texture in the client for a TextureLayer that's
1454// invisible correctly works without drawing a deleted texture. See
1455// crbug.com/266628
1456class TextureLayerChangeInvisibleTest
1457 : public LayerTreeTest,
1458 public TextureLayerClient {
1459 public:
1460 TextureLayerChangeInvisibleTest()
[email protected]f5931d42013-11-06 19:44:571461 : texture_(0u),
[email protected]b04264f92013-09-13 23:37:291462 prepare_called_(0),
1463 commit_count_(0),
1464 expected_texture_on_draw_(0) {}
1465
[email protected]a6366932014-02-05 20:12:471466 virtual scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface(bool fallback)
[email protected]f5931d42013-11-06 19:44:571467 OVERRIDE {
1468 scoped_refptr<TestContextProvider> provider = TestContextProvider::Create();
1469 texture_ = provider->UnboundTestContext3d()->createExternalTexture();
[email protected]a6366932014-02-05 20:12:471470 return FakeOutputSurface::Create3d(provider);
[email protected]f5931d42013-11-06 19:44:571471 }
1472
[email protected]b04264f92013-09-13 23:37:291473 // TextureLayerClient implementation.
1474 virtual unsigned PrepareTexture() OVERRIDE {
1475 ++prepare_called_;
1476 return texture_;
1477 }
[email protected]b04264f92013-09-13 23:37:291478 virtual bool PrepareTextureMailbox(
[email protected]e51444a2013-12-10 23:05:011479 TextureMailbox* mailbox,
[email protected]9260757f2013-09-17 01:24:161480 scoped_ptr<SingleReleaseCallback>* release_callback,
1481 bool use_shared_memory) OVERRIDE {
[email protected]b04264f92013-09-13 23:37:291482 return false;
1483 }
1484
1485 virtual void SetupTree() OVERRIDE {
1486 scoped_refptr<Layer> root = Layer::Create();
1487 root->SetBounds(gfx::Size(10, 10));
1488 root->SetAnchorPoint(gfx::PointF());
1489 root->SetIsDrawable(true);
1490
1491 solid_layer_ = SolidColorLayer::Create();
1492 solid_layer_->SetBounds(gfx::Size(10, 10));
1493 solid_layer_->SetIsDrawable(true);
1494 solid_layer_->SetBackgroundColor(SK_ColorWHITE);
1495 root->AddChild(solid_layer_);
1496
1497 parent_layer_ = Layer::Create();
1498 parent_layer_->SetBounds(gfx::Size(10, 10));
1499 parent_layer_->SetIsDrawable(true);
1500 root->AddChild(parent_layer_);
1501
1502 texture_layer_ = TextureLayer::Create(this);
1503 texture_layer_->SetBounds(gfx::Size(10, 10));
1504 texture_layer_->SetAnchorPoint(gfx::PointF());
1505 texture_layer_->SetIsDrawable(true);
1506 parent_layer_->AddChild(texture_layer_);
1507
1508 layer_tree_host()->SetRootLayer(root);
1509 LayerTreeTest::SetupTree();
1510 }
1511
1512 virtual void BeginTest() OVERRIDE {
1513 PostSetNeedsCommitToMainThread();
1514 }
1515
1516 virtual void DidCommitAndDrawFrame() OVERRIDE {
1517 ++commit_count_;
1518 switch (commit_count_) {
1519 case 1:
1520 // We should have updated the layer, committing the texture.
1521 EXPECT_EQ(1, prepare_called_);
1522 // Make layer invisible.
1523 parent_layer_->SetOpacity(0.f);
1524 break;
1525 case 2: {
1526 // Layer shouldn't have been updated.
1527 EXPECT_EQ(1, prepare_called_);
[email protected]b04264f92013-09-13 23:37:291528 texture_layer_->SetNeedsDisplay();
1529 // Force a change to make sure we draw a frame.
1530 solid_layer_->SetBackgroundColor(SK_ColorGRAY);
1531 break;
1532 }
1533 case 3:
1534 EXPECT_EQ(1, prepare_called_);
[email protected]b04264f92013-09-13 23:37:291535 // Make layer visible again.
1536 parent_layer_->SetOpacity(1.f);
1537 break;
1538 case 4: {
1539 // Layer should have been updated.
1540 EXPECT_EQ(2, prepare_called_);
1541 texture_layer_->ClearClient();
[email protected]b04264f92013-09-13 23:37:291542 texture_ = 0;
1543 break;
1544 }
1545 case 5:
1546 EndTest();
1547 break;
1548 default:
1549 NOTREACHED();
1550 break;
1551 }
1552 }
1553
1554 virtual void BeginCommitOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
1555 ASSERT_TRUE(proxy()->IsMainThreadBlocked());
1556 // This is the only texture that can be drawn this frame.
1557 expected_texture_on_draw_ = texture_;
1558 }
1559
[email protected]7ddfe7e82014-01-30 07:22:111560 virtual DrawSwapReadbackResult::DrawResult PrepareToDrawOnThread(
1561 LayerTreeHostImpl* host_impl,
1562 LayerTreeHostImpl::FrameData* frame_data,
1563 DrawSwapReadbackResult::DrawResult draw_result) OVERRIDE {
[email protected]b04264f92013-09-13 23:37:291564 ContextForImplThread(host_impl)->ResetUsedTextures();
[email protected]7ddfe7e82014-01-30 07:22:111565 return DrawSwapReadbackResult::DRAW_SUCCESS;
[email protected]b04264f92013-09-13 23:37:291566 }
1567
1568 virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl,
1569 bool result) OVERRIDE {
1570 ASSERT_TRUE(result);
1571 TestWebGraphicsContext3D* context = ContextForImplThread(host_impl);
1572 int used_textures = context->NumUsedTextures();
1573 switch (host_impl->active_tree()->source_frame_number()) {
1574 case 0:
1575 EXPECT_EQ(1, used_textures);
1576 EXPECT_TRUE(context->UsedTexture(expected_texture_on_draw_));
1577 break;
1578 case 1:
1579 case 2:
1580 EXPECT_EQ(0, used_textures);
1581 break;
1582 case 3:
1583 EXPECT_EQ(1, used_textures);
1584 EXPECT_TRUE(context->UsedTexture(expected_texture_on_draw_));
1585 break;
1586 default:
1587 break;
1588 }
1589 }
1590
1591 virtual void AfterTest() OVERRIDE {}
1592
1593 private:
1594 TestWebGraphicsContext3D* ContextForImplThread(LayerTreeHostImpl* host_impl) {
[email protected]1dff7962014-01-10 12:05:031595 return static_cast<TestContextProvider*>(
1596 host_impl->output_surface()->context_provider().get())->TestContext3d();
[email protected]b04264f92013-09-13 23:37:291597 }
1598
1599 scoped_refptr<SolidColorLayer> solid_layer_;
1600 scoped_refptr<Layer> parent_layer_;
1601 scoped_refptr<TextureLayer> texture_layer_;
[email protected]b04264f92013-09-13 23:37:291602
1603 // Used on the main thread, and on the impl thread while the main thread is
1604 // blocked.
1605 unsigned texture_;
1606
1607 // Used on the main thread.
[email protected]b04264f92013-09-13 23:37:291608 int prepare_called_;
1609 int commit_count_;
1610
1611 // Used on the compositor thread.
1612 unsigned expected_texture_on_draw_;
1613};
1614
1615// The TextureLayerChangeInvisibleTest does not use mailboxes, so can't use a
1616// delegating renderer.
1617SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(TextureLayerChangeInvisibleTest);
1618
[email protected]4bad8b62013-10-24 01:27:291619// Checks that TextureLayer::Update does not cause an extra commit when setting
1620// the texture mailbox.
1621class TextureLayerNoExtraCommitForMailboxTest
1622 : public LayerTreeTest,
1623 public TextureLayerClient {
1624 public:
[email protected]4bad8b62013-10-24 01:27:291625 // TextureLayerClient implementation.
1626 virtual unsigned PrepareTexture() OVERRIDE {
1627 NOTREACHED();
1628 return 0;
1629 }
[email protected]4bad8b62013-10-24 01:27:291630 virtual bool PrepareTextureMailbox(
[email protected]df41e252014-02-03 23:39:501631 TextureMailbox* texture_mailbox,
[email protected]4bad8b62013-10-24 01:27:291632 scoped_ptr<SingleReleaseCallback>* release_callback,
1633 bool use_shared_memory) OVERRIDE {
[email protected]cce34bd2013-12-02 23:24:451634 if (layer_tree_host()->source_frame_number() == 1) {
[email protected]df41e252014-02-03 23:39:501635 *texture_mailbox = TextureMailbox();
[email protected]cce34bd2013-12-02 23:24:451636 return true;
1637 }
[email protected]4bad8b62013-10-24 01:27:291638
[email protected]e0a4d732014-02-15 00:23:261639 *texture_mailbox = TextureMailbox(MailboxFromChar('1'), GL_TEXTURE_2D, 0);
[email protected]4bad8b62013-10-24 01:27:291640 *release_callback = SingleReleaseCallback::Create(
1641 base::Bind(&TextureLayerNoExtraCommitForMailboxTest::MailboxReleased,
1642 base::Unretained(this)));
[email protected]4bad8b62013-10-24 01:27:291643 return true;
1644 }
1645
[email protected]df41e252014-02-03 23:39:501646 void MailboxReleased(uint32 sync_point, bool lost_resource) {
[email protected]cce34bd2013-12-02 23:24:451647 EXPECT_EQ(2, layer_tree_host()->source_frame_number());
1648 EndTest();
[email protected]4bad8b62013-10-24 01:27:291649 }
1650
1651 virtual void SetupTree() OVERRIDE {
1652 scoped_refptr<Layer> root = Layer::Create();
1653 root->SetBounds(gfx::Size(10, 10));
1654 root->SetAnchorPoint(gfx::PointF());
1655 root->SetIsDrawable(true);
1656
[email protected]4bad8b62013-10-24 01:27:291657 texture_layer_ = TextureLayer::CreateForMailbox(this);
1658 texture_layer_->SetBounds(gfx::Size(10, 10));
1659 texture_layer_->SetAnchorPoint(gfx::PointF());
1660 texture_layer_->SetIsDrawable(true);
[email protected]0d7fb302014-01-23 21:30:471661 root->AddChild(texture_layer_);
[email protected]4bad8b62013-10-24 01:27:291662
1663 layer_tree_host()->SetRootLayer(root);
1664 LayerTreeTest::SetupTree();
1665 }
1666
1667 virtual void BeginTest() OVERRIDE {
1668 PostSetNeedsCommitToMainThread();
1669 }
1670
[email protected]cce34bd2013-12-02 23:24:451671 virtual void DidCommitAndDrawFrame() OVERRIDE {
[email protected]4bad8b62013-10-24 01:27:291672 switch (layer_tree_host()->source_frame_number()) {
1673 case 1:
[email protected]cce34bd2013-12-02 23:24:451674 EXPECT_FALSE(proxy()->CommitPendingForTesting());
1675 // Invalidate the texture layer to clear the mailbox before
1676 // ending the test.
1677 texture_layer_->SetNeedsDisplay();
1678 break;
1679 case 2:
[email protected]4bad8b62013-10-24 01:27:291680 break;
1681 default:
1682 NOTREACHED();
1683 break;
1684 }
1685 }
1686
[email protected]cce34bd2013-12-02 23:24:451687 virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl,
1688 bool result) OVERRIDE {
1689 ASSERT_TRUE(result);
1690 DelegatedFrameData* delegated_frame_data =
1691 output_surface()->last_sent_frame().delegated_frame_data.get();
1692 if (!delegated_frame_data)
1693 return;
1694
1695 // Return all resources immediately.
1696 TransferableResourceArray resources_to_return =
1697 output_surface()->resources_held_by_parent();
1698
1699 CompositorFrameAck ack;
1700 for (size_t i = 0; i < resources_to_return.size(); ++i)
1701 output_surface()->ReturnResource(resources_to_return[i].id, &ack);
1702 host_impl->ReclaimResources(&ack);
1703 host_impl->OnSwapBuffersComplete();
1704 }
1705
[email protected]4bad8b62013-10-24 01:27:291706 virtual void AfterTest() OVERRIDE {}
1707
1708 private:
[email protected]4bad8b62013-10-24 01:27:291709 scoped_refptr<TextureLayer> texture_layer_;
[email protected]4bad8b62013-10-24 01:27:291710};
1711
[email protected]cce34bd2013-12-02 23:24:451712SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerNoExtraCommitForMailboxTest);
[email protected]4bad8b62013-10-24 01:27:291713
[email protected]b04264f92013-09-13 23:37:291714// Checks that changing a mailbox in the client for a TextureLayer that's
1715// invisible correctly works and uses the new mailbox as soon as the layer
1716// becomes visible (and returns the old one).
1717class TextureLayerChangeInvisibleMailboxTest
1718 : public LayerTreeTest,
1719 public TextureLayerClient {
1720 public:
1721 TextureLayerChangeInvisibleMailboxTest()
1722 : mailbox_changed_(true),
1723 mailbox_returned_(0),
1724 prepare_called_(0),
1725 commit_count_(0) {
1726 mailbox_ = MakeMailbox('1');
1727 }
1728
1729 // TextureLayerClient implementation.
1730 virtual unsigned PrepareTexture() OVERRIDE {
1731 NOTREACHED();
1732 return 0;
1733 }
1734
[email protected]b04264f92013-09-13 23:37:291735 virtual bool PrepareTextureMailbox(
[email protected]e51444a2013-12-10 23:05:011736 TextureMailbox* mailbox,
[email protected]9260757f2013-09-17 01:24:161737 scoped_ptr<SingleReleaseCallback>* release_callback,
1738 bool use_shared_memory) OVERRIDE {
[email protected]b04264f92013-09-13 23:37:291739 ++prepare_called_;
1740 if (!mailbox_changed_)
1741 return false;
1742 *mailbox = mailbox_;
[email protected]9260757f2013-09-17 01:24:161743 *release_callback = SingleReleaseCallback::Create(
1744 base::Bind(&TextureLayerChangeInvisibleMailboxTest::MailboxReleased,
1745 base::Unretained(this)));
[email protected]b04264f92013-09-13 23:37:291746 return true;
1747 }
1748
1749 TextureMailbox MakeMailbox(char name) {
[email protected]e0a4d732014-02-15 00:23:261750 return TextureMailbox(MailboxFromChar(name), GL_TEXTURE_2D, 0);
[email protected]b04264f92013-09-13 23:37:291751 }
1752
[email protected]df41e252014-02-03 23:39:501753 void MailboxReleased(uint32 sync_point, bool lost_resource) {
[email protected]b04264f92013-09-13 23:37:291754 ++mailbox_returned_;
1755 }
1756
1757 virtual void SetupTree() OVERRIDE {
1758 scoped_refptr<Layer> root = Layer::Create();
1759 root->SetBounds(gfx::Size(10, 10));
1760 root->SetAnchorPoint(gfx::PointF());
1761 root->SetIsDrawable(true);
1762
1763 solid_layer_ = SolidColorLayer::Create();
1764 solid_layer_->SetBounds(gfx::Size(10, 10));
1765 solid_layer_->SetIsDrawable(true);
1766 solid_layer_->SetBackgroundColor(SK_ColorWHITE);
1767 root->AddChild(solid_layer_);
1768
1769 parent_layer_ = Layer::Create();
1770 parent_layer_->SetBounds(gfx::Size(10, 10));
1771 parent_layer_->SetIsDrawable(true);
1772 root->AddChild(parent_layer_);
1773
1774 texture_layer_ = TextureLayer::CreateForMailbox(this);
1775 texture_layer_->SetBounds(gfx::Size(10, 10));
1776 texture_layer_->SetAnchorPoint(gfx::PointF());
1777 texture_layer_->SetIsDrawable(true);
1778 parent_layer_->AddChild(texture_layer_);
1779
1780 layer_tree_host()->SetRootLayer(root);
1781 LayerTreeTest::SetupTree();
1782 }
1783
1784 virtual void BeginTest() OVERRIDE {
1785 PostSetNeedsCommitToMainThread();
1786 }
1787
1788 virtual void DidCommitAndDrawFrame() OVERRIDE {
1789 ++commit_count_;
1790 switch (commit_count_) {
1791 case 1:
1792 // We should have updated the layer, committing the texture.
1793 EXPECT_EQ(1, prepare_called_);
1794 // Make layer invisible.
1795 parent_layer_->SetOpacity(0.f);
1796 break;
1797 case 2:
1798 // Layer shouldn't have been updated.
1799 EXPECT_EQ(1, prepare_called_);
1800 // Change the texture.
1801 mailbox_ = MakeMailbox('2');
1802 mailbox_changed_ = true;
1803 texture_layer_->SetNeedsDisplay();
1804 // Force a change to make sure we draw a frame.
1805 solid_layer_->SetBackgroundColor(SK_ColorGRAY);
1806 break;
1807 case 3:
1808 // Layer shouldn't have been updated.
1809 EXPECT_EQ(1, prepare_called_);
1810 // So the old mailbox isn't returned yet.
1811 EXPECT_EQ(0, mailbox_returned_);
1812 // Make layer visible again.
1813 parent_layer_->SetOpacity(1.f);
1814 break;
1815 case 4:
1816 // Layer should have been updated.
1817 EXPECT_EQ(2, prepare_called_);
1818 // So the old mailbox should have been returned already.
1819 EXPECT_EQ(1, mailbox_returned_);
1820 texture_layer_->ClearClient();
1821 break;
1822 case 5:
1823 EXPECT_EQ(2, mailbox_returned_);
1824 EndTest();
1825 break;
1826 default:
1827 NOTREACHED();
1828 break;
1829 }
1830 }
1831
1832 virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl,
1833 bool result) OVERRIDE {
1834 ASSERT_TRUE(result);
1835 DelegatedFrameData* delegated_frame_data =
1836 output_surface()->last_sent_frame().delegated_frame_data.get();
1837 if (!delegated_frame_data)
1838 return;
1839
1840 // Return all resources immediately.
1841 TransferableResourceArray resources_to_return =
1842 output_surface()->resources_held_by_parent();
1843
1844 CompositorFrameAck ack;
1845 for (size_t i = 0; i < resources_to_return.size(); ++i)
1846 output_surface()->ReturnResource(resources_to_return[i].id, &ack);
[email protected]a7335e0b2013-09-18 09:34:511847 host_impl->ReclaimResources(&ack);
1848 host_impl->OnSwapBuffersComplete();
[email protected]b04264f92013-09-13 23:37:291849 }
1850
1851 virtual void AfterTest() OVERRIDE {}
1852
1853 private:
1854 scoped_refptr<SolidColorLayer> solid_layer_;
1855 scoped_refptr<Layer> parent_layer_;
1856 scoped_refptr<TextureLayer> texture_layer_;
1857
1858 // Used on the main thread.
1859 bool mailbox_changed_;
1860 TextureMailbox mailbox_;
1861 int mailbox_returned_;
1862 int prepare_called_;
1863 int commit_count_;
1864};
1865
1866SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerChangeInvisibleMailboxTest);
1867
[email protected]0d7fb302014-01-23 21:30:471868// Test that TextureLayerImpl::ReleaseResources can be called which releases
1869// the mailbox back to TextureLayerClient.
1870class TextureLayerReleaseResourcesBase
1871 : public LayerTreeTest,
1872 public TextureLayerClient {
1873 public:
1874 // TextureLayerClient implementation.
1875 virtual unsigned PrepareTexture() OVERRIDE {
1876 NOTREACHED();
1877 return 0;
1878 }
1879 virtual bool PrepareTextureMailbox(
1880 TextureMailbox* mailbox,
1881 scoped_ptr<SingleReleaseCallback>* release_callback,
1882 bool use_shared_memory) OVERRIDE {
[email protected]e0a4d732014-02-15 00:23:261883 *mailbox = TextureMailbox(MailboxFromChar('1'), GL_TEXTURE_2D, 0);
[email protected]0d7fb302014-01-23 21:30:471884 *release_callback = SingleReleaseCallback::Create(
1885 base::Bind(&TextureLayerReleaseResourcesBase::MailboxReleased,
1886 base::Unretained(this)));
1887 return true;
1888 }
1889
1890 void MailboxReleased(unsigned sync_point, bool lost_resource) {
1891 mailbox_released_ = true;
1892 }
1893
1894 virtual void SetupTree() OVERRIDE {
1895 LayerTreeTest::SetupTree();
1896
1897 scoped_refptr<TextureLayer> texture_layer =
1898 TextureLayer::CreateForMailbox(this);
1899 texture_layer->SetBounds(gfx::Size(10, 10));
1900 texture_layer->SetAnchorPoint(gfx::PointF());
1901 texture_layer->SetIsDrawable(true);
1902
1903 layer_tree_host()->root_layer()->AddChild(texture_layer);
1904 }
1905
1906 virtual void BeginTest() OVERRIDE {
1907 mailbox_released_ = false;
1908 PostSetNeedsCommitToMainThread();
1909 }
1910
1911 virtual void DidCommitAndDrawFrame() OVERRIDE {
1912 EndTest();
1913 }
1914
1915 virtual void AfterTest() OVERRIDE {
1916 EXPECT_TRUE(mailbox_released_);
1917 }
1918
1919 private:
1920 bool mailbox_released_;
1921};
1922
1923class TextureLayerReleaseResourcesAfterCommit
1924 : public TextureLayerReleaseResourcesBase {
1925 public:
1926 virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
1927 LayerTreeImpl* tree = NULL;
1928 if (host_impl->settings().impl_side_painting)
1929 tree = host_impl->pending_tree();
1930 else
1931 tree = host_impl->active_tree();
1932 tree->root_layer()->children()[0]->ReleaseResources();
1933 }
1934};
1935
1936SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerReleaseResourcesAfterCommit);
1937
1938class TextureLayerReleaseResourcesAfterActivate
1939 : public TextureLayerReleaseResourcesBase {
1940 public:
1941 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
1942 host_impl->active_tree()->root_layer()->children()[0]->ReleaseResources();
1943 }
1944};
1945
1946SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerReleaseResourcesAfterActivate);
1947
[email protected]0bf5a202013-07-10 14:50:541948// Test recovering from a lost context.
1949class TextureLayerLostContextTest
1950 : public LayerTreeTest,
1951 public TextureLayerClient {
1952 public:
1953 TextureLayerLostContextTest()
[email protected]f5931d42013-11-06 19:44:571954 : context_lost_(false),
[email protected]0bf5a202013-07-10 14:50:541955 draw_count_(0) {}
1956
[email protected]a6366932014-02-05 20:12:471957 virtual scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface(bool fallback)
[email protected]ebc0e1df2013-08-01 02:46:221958 OVERRIDE {
[email protected]a6366932014-02-05 20:12:471959 return FakeOutputSurface::Create3d();
[email protected]0bf5a202013-07-10 14:50:541960 }
1961
[email protected]171cbb32013-07-11 03:51:191962 virtual unsigned PrepareTexture() OVERRIDE {
[email protected]f5931d42013-11-06 19:44:571963 if (draw_count_ == 0)
1964 context_lost_ = true;
1965 if (context_lost_)
1966 return 0u;
1967 return 1u;
[email protected]0bf5a202013-07-10 14:50:541968 }
1969
1970 virtual bool PrepareTextureMailbox(
[email protected]9260757f2013-09-17 01:24:161971 TextureMailbox* mailbox,
1972 scoped_ptr<SingleReleaseCallback>* release_callback,
1973 bool use_shared_memory) OVERRIDE {
[email protected]0bf5a202013-07-10 14:50:541974 return false;
1975 }
1976
1977 virtual void SetupTree() OVERRIDE {
1978 scoped_refptr<Layer> root = Layer::Create();
1979 root->SetBounds(gfx::Size(10, 10));
1980 root->SetIsDrawable(true);
1981
1982 texture_layer_ = TextureLayer::Create(this);
1983 texture_layer_->SetBounds(gfx::Size(10, 10));
1984 texture_layer_->SetIsDrawable(true);
1985 root->AddChild(texture_layer_);
1986
1987 layer_tree_host()->SetRootLayer(root);
1988 LayerTreeTest::SetupTree();
1989 }
1990
1991 virtual void BeginTest() OVERRIDE {
1992 PostSetNeedsCommitToMainThread();
1993 }
1994
[email protected]7ddfe7e82014-01-30 07:22:111995 virtual DrawSwapReadbackResult::DrawResult PrepareToDrawOnThread(
1996 LayerTreeHostImpl* host_impl,
1997 LayerTreeHostImpl::FrameData* frame_data,
1998 DrawSwapReadbackResult::DrawResult draw_result) OVERRIDE {
[email protected]0bf5a202013-07-10 14:50:541999 LayerImpl* root = host_impl->RootLayer();
2000 TextureLayerImpl* texture_layer =
2001 static_cast<TextureLayerImpl*>(root->children()[0]);
2002 if (++draw_count_ == 1)
2003 EXPECT_EQ(0u, texture_layer->texture_id());
2004 else
[email protected]f5931d42013-11-06 19:44:572005 EXPECT_EQ(1u, texture_layer->texture_id());
[email protected]7ddfe7e82014-01-30 07:22:112006 return DrawSwapReadbackResult::DRAW_SUCCESS;
[email protected]0bf5a202013-07-10 14:50:542007 }
2008
2009 virtual void DidCommitAndDrawFrame() OVERRIDE {
2010 EndTest();
2011 }
2012
2013 virtual void AfterTest() OVERRIDE {}
2014
2015 private:
2016 scoped_refptr<TextureLayer> texture_layer_;
[email protected]f5931d42013-11-06 19:44:572017 bool context_lost_;
[email protected]0bf5a202013-07-10 14:50:542018 int draw_count_;
2019};
2020
2021SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(TextureLayerLostContextTest);
2022
[email protected]9c2bd822013-07-26 12:30:172023class TextureLayerWithMailboxMainThreadDeleted : public LayerTreeTest {
2024 public:
[email protected]df41e252014-02-03 23:39:502025 void ReleaseCallback(uint32 sync_point, bool lost_resource) {
[email protected]9794fb32013-08-29 09:49:592026 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]9c2bd822013-07-26 12:30:172027 EXPECT_FALSE(lost_resource);
2028 ++callback_count_;
2029 EndTest();
2030 }
2031
2032 void SetMailbox(char mailbox_char) {
[email protected]9794fb32013-08-29 09:49:592033 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]9260757f2013-09-17 01:24:162034 scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create(
[email protected]9c2bd822013-07-26 12:30:172035 base::Bind(
2036 &TextureLayerWithMailboxMainThreadDeleted::ReleaseCallback,
2037 base::Unretained(this)));
[email protected]df41e252014-02-03 23:39:502038 layer_->SetTextureMailbox(
[email protected]e0a4d732014-02-15 00:23:262039 TextureMailbox(MailboxFromChar(mailbox_char), GL_TEXTURE_2D, 0),
[email protected]df41e252014-02-03 23:39:502040 callback.Pass());
[email protected]9c2bd822013-07-26 12:30:172041 }
2042
2043 virtual void SetupTree() OVERRIDE {
2044 gfx::Size bounds(100, 100);
2045 root_ = Layer::Create();
2046 root_->SetAnchorPoint(gfx::PointF());
2047 root_->SetBounds(bounds);
2048
2049 layer_ = TextureLayer::CreateForMailbox(NULL);
2050 layer_->SetIsDrawable(true);
2051 layer_->SetAnchorPoint(gfx::PointF());
2052 layer_->SetBounds(bounds);
2053
2054 root_->AddChild(layer_);
2055 layer_tree_host()->SetRootLayer(root_);
2056 layer_tree_host()->SetViewportSize(bounds);
2057 }
2058
2059 virtual void BeginTest() OVERRIDE {
[email protected]9794fb32013-08-29 09:49:592060 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
2061
[email protected]9c2bd822013-07-26 12:30:172062 callback_count_ = 0;
2063
2064 // Set the mailbox on the main thread.
2065 SetMailbox('1');
2066 EXPECT_EQ(0, callback_count_);
2067
2068 PostSetNeedsCommitToMainThread();
2069 }
2070
2071 virtual void DidCommitAndDrawFrame() OVERRIDE {
2072 switch (layer_tree_host()->source_frame_number()) {
2073 case 1:
2074 // Delete the TextureLayer on the main thread while the mailbox is in
2075 // the impl tree.
2076 layer_->RemoveFromParent();
2077 layer_ = NULL;
2078 break;
2079 }
2080 }
2081
2082 virtual void AfterTest() OVERRIDE {
2083 EXPECT_EQ(1, callback_count_);
2084 }
2085
2086 private:
[email protected]9794fb32013-08-29 09:49:592087 base::ThreadChecker main_thread_;
[email protected]9c2bd822013-07-26 12:30:172088 int callback_count_;
2089 scoped_refptr<Layer> root_;
2090 scoped_refptr<TextureLayer> layer_;
2091};
2092
2093SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
2094 TextureLayerWithMailboxMainThreadDeleted);
2095
2096class TextureLayerWithMailboxImplThreadDeleted : public LayerTreeTest {
2097 public:
[email protected]df41e252014-02-03 23:39:502098 void ReleaseCallback(uint32 sync_point, bool lost_resource) {
[email protected]9794fb32013-08-29 09:49:592099 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]9c2bd822013-07-26 12:30:172100 EXPECT_FALSE(lost_resource);
2101 ++callback_count_;
2102 EndTest();
2103 }
2104
2105 void SetMailbox(char mailbox_char) {
[email protected]9794fb32013-08-29 09:49:592106 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]9260757f2013-09-17 01:24:162107 scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create(
[email protected]9c2bd822013-07-26 12:30:172108 base::Bind(
2109 &TextureLayerWithMailboxImplThreadDeleted::ReleaseCallback,
2110 base::Unretained(this)));
[email protected]df41e252014-02-03 23:39:502111 layer_->SetTextureMailbox(
[email protected]e0a4d732014-02-15 00:23:262112 TextureMailbox(MailboxFromChar(mailbox_char), GL_TEXTURE_2D, 0),
[email protected]df41e252014-02-03 23:39:502113 callback.Pass());
[email protected]9c2bd822013-07-26 12:30:172114 }
2115
2116 virtual void SetupTree() OVERRIDE {
2117 gfx::Size bounds(100, 100);
2118 root_ = Layer::Create();
2119 root_->SetAnchorPoint(gfx::PointF());
2120 root_->SetBounds(bounds);
2121
2122 layer_ = TextureLayer::CreateForMailbox(NULL);
2123 layer_->SetIsDrawable(true);
2124 layer_->SetAnchorPoint(gfx::PointF());
2125 layer_->SetBounds(bounds);
2126
2127 root_->AddChild(layer_);
2128 layer_tree_host()->SetRootLayer(root_);
2129 layer_tree_host()->SetViewportSize(bounds);
2130 }
2131
2132 virtual void BeginTest() OVERRIDE {
[email protected]9794fb32013-08-29 09:49:592133 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
2134
[email protected]9c2bd822013-07-26 12:30:172135 callback_count_ = 0;
2136
2137 // Set the mailbox on the main thread.
2138 SetMailbox('1');
2139 EXPECT_EQ(0, callback_count_);
2140
2141 PostSetNeedsCommitToMainThread();
2142 }
2143
2144 virtual void DidCommitAndDrawFrame() OVERRIDE {
2145 switch (layer_tree_host()->source_frame_number()) {
2146 case 1:
2147 // Remove the TextureLayer on the main thread while the mailbox is in
2148 // the impl tree, but don't delete the TextureLayer until after the impl
2149 // tree side is deleted.
2150 layer_->RemoveFromParent();
2151 break;
2152 case 2:
2153 layer_ = NULL;
2154 break;
2155 }
2156 }
2157
2158 virtual void AfterTest() OVERRIDE {
2159 EXPECT_EQ(1, callback_count_);
2160 }
2161
2162 private:
[email protected]9794fb32013-08-29 09:49:592163 base::ThreadChecker main_thread_;
[email protected]9c2bd822013-07-26 12:30:172164 int callback_count_;
2165 scoped_refptr<Layer> root_;
2166 scoped_refptr<TextureLayer> layer_;
2167};
2168
2169SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
2170 TextureLayerWithMailboxImplThreadDeleted);
2171
[email protected]ba565742012-11-10 09:29:482172} // namespace
2173} // namespace cc