blob: 73c6f7325ca87d278b1c03423138f6ddc4a4fa26 [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]f9e8f452014-03-07 22:09:40462TEST_F(TextureLayerTest, SetTextureMailboxWithoutReleaseCallback) {
463 scoped_refptr<TextureLayer> test_layer = TextureLayer::CreateForMailbox(NULL);
464 ASSERT_TRUE(test_layer.get());
465
466 // These use the same gpu::Mailbox, but different sync points.
467 TextureMailbox mailbox1(MailboxFromChar('a'), GL_TEXTURE_2D, 1);
468 TextureMailbox mailbox2(MailboxFromChar('a'), GL_TEXTURE_2D, 2);
469
470 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
471 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
472 layer_tree_host_->SetRootLayer(test_layer);
473 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
474
475 // Set the mailbox the first time. It should cause a commit.
476 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
477 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
478 test_layer->SetTextureMailboxWithoutReleaseCallback(mailbox1);
479 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
480
481 // Set the mailbox again with a new sync point, as the backing texture has
482 // been updated. It should cause a new commit.
483 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
484 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
485 test_layer->SetTextureMailboxWithoutReleaseCallback(mailbox2);
486 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
487}
488
[email protected]9794fb32013-08-29 09:49:59489class TextureLayerMailboxHolderTest : public TextureLayerTest {
490 public:
491 TextureLayerMailboxHolderTest()
492 : main_thread_("MAIN") {
493 main_thread_.Start();
494 }
495
496 void Wait(const base::Thread& thread) {
497 bool manual_reset = false;
498 bool initially_signaled = false;
499 base::WaitableEvent event(manual_reset, initially_signaled);
500 thread.message_loop()->PostTask(
501 FROM_HERE,
502 base::Bind(&base::WaitableEvent::Signal, base::Unretained(&event)));
503 event.Wait();
504 }
505
506 void CreateMainRef() {
507 main_ref_ = TestMailboxHolder::Create(
[email protected]9260757f2013-09-17 01:24:16508 test_data_.mailbox1_,
509 SingleReleaseCallback::Create(test_data_.release_mailbox1_)).Pass();
[email protected]9794fb32013-08-29 09:49:59510 }
511
512 void ReleaseMainRef() {
513 main_ref_.reset();
514 }
515
[email protected]9260757f2013-09-17 01:24:16516 void CreateImplRef(scoped_ptr<SingleReleaseCallback>* impl_ref) {
[email protected]9794fb32013-08-29 09:49:59517 *impl_ref = main_ref_->holder()->GetCallbackForImplThread();
518 }
519
520 void CapturePostTasksAndWait(base::WaitableEvent* begin_capture,
521 base::WaitableEvent* wait_for_capture,
522 base::WaitableEvent* stop_capture) {
523 begin_capture->Wait();
524 BlockingTaskRunner::CapturePostTasks capture;
525 wait_for_capture->Signal();
526 stop_capture->Wait();
527 }
528
529 protected:
530 scoped_ptr<TestMailboxHolder::MainThreadReference>
531 main_ref_;
532 base::Thread main_thread_;
533 CommonMailboxObjects test_data_;
534};
535
536TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_BothReleaseThenMain) {
537 scoped_refptr<TextureLayer> test_layer = TextureLayer::CreateForMailbox(NULL);
538 ASSERT_TRUE(test_layer.get());
539
540 main_thread_.message_loop()->PostTask(
541 FROM_HERE,
542 base::Bind(&TextureLayerMailboxHolderTest::CreateMainRef,
543 base::Unretained(this)));
544
545 Wait(main_thread_);
546
547 // The texture layer is attached to compositor1, and passes a reference to its
548 // impl tree.
[email protected]9260757f2013-09-17 01:24:16549 scoped_ptr<SingleReleaseCallback> compositor1;
[email protected]9794fb32013-08-29 09:49:59550 main_thread_.message_loop()->PostTask(
551 FROM_HERE,
552 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
553 base::Unretained(this),
554 &compositor1));
555
556 // Then the texture layer is removed and attached to compositor2, and passes a
557 // reference to its impl tree.
[email protected]9260757f2013-09-17 01:24:16558 scoped_ptr<SingleReleaseCallback> compositor2;
[email protected]9794fb32013-08-29 09:49:59559 main_thread_.message_loop()->PostTask(
560 FROM_HERE,
561 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
562 base::Unretained(this),
563 &compositor2));
564
565 Wait(main_thread_);
566 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
567
568 // The compositors both destroy their impl trees before the main thread layer
569 // is destroyed.
[email protected]9260757f2013-09-17 01:24:16570 compositor1->Run(100, false);
571 compositor2->Run(200, false);
[email protected]9794fb32013-08-29 09:49:59572
573 Wait(main_thread_);
574
575 EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0);
576 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
577
578 // The main thread ref is the last one, so the mailbox is released back to the
579 // embedder, with the last sync point provided by the impl trees.
580 EXPECT_CALL(test_data_.mock_callback_,
581 Release(test_data_.mailbox_name1_, 200, false)).Times(1);
582
583 main_thread_.message_loop()->PostTask(
584 FROM_HERE,
585 base::Bind(&TextureLayerMailboxHolderTest::ReleaseMainRef,
586 base::Unretained(this)));
587 Wait(main_thread_);
588 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
589}
590
591TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_MainReleaseBetween) {
592 scoped_refptr<TextureLayer> test_layer = TextureLayer::CreateForMailbox(NULL);
593 ASSERT_TRUE(test_layer.get());
594
595 main_thread_.message_loop()->PostTask(
596 FROM_HERE,
597 base::Bind(&TextureLayerMailboxHolderTest::CreateMainRef,
598 base::Unretained(this)));
599
600 Wait(main_thread_);
601
602 // The texture layer is attached to compositor1, and passes a reference to its
603 // impl tree.
[email protected]9260757f2013-09-17 01:24:16604 scoped_ptr<SingleReleaseCallback> compositor1;
[email protected]9794fb32013-08-29 09:49:59605 main_thread_.message_loop()->PostTask(
606 FROM_HERE,
607 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
608 base::Unretained(this),
609 &compositor1));
610
611 // Then the texture layer is removed and attached to compositor2, and passes a
612 // reference to its impl tree.
[email protected]9260757f2013-09-17 01:24:16613 scoped_ptr<SingleReleaseCallback> compositor2;
[email protected]9794fb32013-08-29 09:49:59614 main_thread_.message_loop()->PostTask(
615 FROM_HERE,
616 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
617 base::Unretained(this),
618 &compositor2));
619
620 Wait(main_thread_);
621 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
622
623 // One compositor destroys their impl tree.
[email protected]9260757f2013-09-17 01:24:16624 compositor1->Run(100, false);
[email protected]9794fb32013-08-29 09:49:59625
626 // Then the main thread reference is destroyed.
627 main_thread_.message_loop()->PostTask(
628 FROM_HERE,
629 base::Bind(&TextureLayerMailboxHolderTest::ReleaseMainRef,
630 base::Unretained(this)));
631
632 Wait(main_thread_);
633
634 EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0);
635 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
636
637 // The second impl reference is destroyed last, causing the mailbox to be
638 // released back to the embedder with the last sync point from the impl tree.
639 EXPECT_CALL(test_data_.mock_callback_,
640 Release(test_data_.mailbox_name1_, 200, true)).Times(1);
641
[email protected]9260757f2013-09-17 01:24:16642 compositor2->Run(200, true);
[email protected]9794fb32013-08-29 09:49:59643 Wait(main_thread_);
644 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
645}
646
647TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_MainReleasedFirst) {
648 scoped_refptr<TextureLayer> test_layer = TextureLayer::CreateForMailbox(NULL);
649 ASSERT_TRUE(test_layer.get());
650
651 main_thread_.message_loop()->PostTask(
652 FROM_HERE,
653 base::Bind(&TextureLayerMailboxHolderTest::CreateMainRef,
654 base::Unretained(this)));
655
656 Wait(main_thread_);
657
658 // The texture layer is attached to compositor1, and passes a reference to its
659 // impl tree.
[email protected]9260757f2013-09-17 01:24:16660 scoped_ptr<SingleReleaseCallback> compositor1;
[email protected]9794fb32013-08-29 09:49:59661 main_thread_.message_loop()->PostTask(
662 FROM_HERE,
663 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
664 base::Unretained(this),
665 &compositor1));
666
667 // Then the texture layer is removed and attached to compositor2, and passes a
668 // reference to its impl tree.
[email protected]9260757f2013-09-17 01:24:16669 scoped_ptr<SingleReleaseCallback> compositor2;
[email protected]9794fb32013-08-29 09:49:59670 main_thread_.message_loop()->PostTask(
671 FROM_HERE,
672 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
673 base::Unretained(this),
674 &compositor2));
675
676 Wait(main_thread_);
677 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
678
679 // The main thread reference is destroyed first.
680 main_thread_.message_loop()->PostTask(
681 FROM_HERE,
682 base::Bind(&TextureLayerMailboxHolderTest::ReleaseMainRef,
683 base::Unretained(this)));
684
685 // One compositor destroys their impl tree.
[email protected]9260757f2013-09-17 01:24:16686 compositor2->Run(200, false);
[email protected]9794fb32013-08-29 09:49:59687
688 Wait(main_thread_);
689
690 EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0);
691 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
692
693 // The second impl reference is destroyed last, causing the mailbox to be
694 // released back to the embedder with the last sync point from the impl tree.
695 EXPECT_CALL(test_data_.mock_callback_,
696 Release(test_data_.mailbox_name1_, 100, true)).Times(1);
697
[email protected]9260757f2013-09-17 01:24:16698 compositor1->Run(100, true);
[email protected]9794fb32013-08-29 09:49:59699 Wait(main_thread_);
700 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
701}
702
703TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_SecondImplRefShortcut) {
704 scoped_refptr<TextureLayer> test_layer = TextureLayer::CreateForMailbox(NULL);
705 ASSERT_TRUE(test_layer.get());
706
707 main_thread_.message_loop()->PostTask(
708 FROM_HERE,
709 base::Bind(&TextureLayerMailboxHolderTest::CreateMainRef,
710 base::Unretained(this)));
711
712 Wait(main_thread_);
713
714 // The texture layer is attached to compositor1, and passes a reference to its
715 // impl tree.
[email protected]9260757f2013-09-17 01:24:16716 scoped_ptr<SingleReleaseCallback> compositor1;
[email protected]9794fb32013-08-29 09:49:59717 main_thread_.message_loop()->PostTask(
718 FROM_HERE,
719 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
720 base::Unretained(this),
721 &compositor1));
722
723 // Then the texture layer is removed and attached to compositor2, and passes a
724 // reference to its impl tree.
[email protected]9260757f2013-09-17 01:24:16725 scoped_ptr<SingleReleaseCallback> compositor2;
[email protected]9794fb32013-08-29 09:49:59726 main_thread_.message_loop()->PostTask(
727 FROM_HERE,
728 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
729 base::Unretained(this),
730 &compositor2));
731
732 Wait(main_thread_);
733 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
734
735 // The main thread reference is destroyed first.
736 main_thread_.message_loop()->PostTask(
737 FROM_HERE,
738 base::Bind(&TextureLayerMailboxHolderTest::ReleaseMainRef,
739 base::Unretained(this)));
740
741 EXPECT_CALL(test_data_.mock_callback_,
742 Release(test_data_.mailbox_name1_, 200, true)).Times(1);
743
744 bool manual_reset = false;
745 bool initially_signaled = false;
746 base::WaitableEvent begin_capture(manual_reset, initially_signaled);
747 base::WaitableEvent wait_for_capture(manual_reset, initially_signaled);
748 base::WaitableEvent stop_capture(manual_reset, initially_signaled);
749
750 // Post a task to start capturing tasks on the main thread. This will block
751 // the main thread until we signal the |stop_capture| event.
752 main_thread_.message_loop()->PostTask(
753 FROM_HERE,
754 base::Bind(&TextureLayerMailboxHolderTest::CapturePostTasksAndWait,
755 base::Unretained(this),
756 &begin_capture,
757 &wait_for_capture,
758 &stop_capture));
759
760 // Before the main thread capturing starts, one compositor destroys their
761 // impl reference. Since capturing did not start, this gets post-tasked to
762 // the main thread.
[email protected]9260757f2013-09-17 01:24:16763 compositor1->Run(100, false);
[email protected]9794fb32013-08-29 09:49:59764
765 // Start capturing on the main thread.
766 begin_capture.Signal();
767 wait_for_capture.Wait();
768
769 // Meanwhile, the second compositor released its impl reference, but this task
770 // gets shortcutted directly to the main thread. This means the reference is
771 // released before compositor1, whose reference will be released later when
772 // the post-task is serviced. But since it was destroyed _on the impl thread_
773 // last, its sync point values should be used.
[email protected]9260757f2013-09-17 01:24:16774 compositor2->Run(200, true);
[email protected]9794fb32013-08-29 09:49:59775
776 stop_capture.Signal();
777 Wait(main_thread_);
778
779 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
780}
781
[email protected]e216fef02013-03-20 22:56:10782class TextureLayerImplWithMailboxThreadedCallback : public LayerTreeTest {
[email protected]28571b042013-03-14 07:59:15783 public:
784 TextureLayerImplWithMailboxThreadedCallback()
785 : callback_count_(0),
786 commit_count_(0) {}
787
788 // Make sure callback is received on main and doesn't block the impl thread.
[email protected]df41e252014-02-03 23:39:50789 void ReleaseCallback(uint32 sync_point, bool lost_resource) {
[email protected]9794fb32013-08-29 09:49:59790 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]7ba3ca72013-04-11 06:37:25791 EXPECT_FALSE(lost_resource);
[email protected]28571b042013-03-14 07:59:15792 ++callback_count_;
793 }
794
795 void SetMailbox(char mailbox_char) {
[email protected]9794fb32013-08-29 09:49:59796 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]9260757f2013-09-17 01:24:16797 scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create(
[email protected]28571b042013-03-14 07:59:15798 base::Bind(
799 &TextureLayerImplWithMailboxThreadedCallback::ReleaseCallback,
800 base::Unretained(this)));
[email protected]df41e252014-02-03 23:39:50801 layer_->SetTextureMailbox(
[email protected]e0a4d732014-02-15 00:23:26802 TextureMailbox(MailboxFromChar(mailbox_char), GL_TEXTURE_2D, 0),
[email protected]df41e252014-02-03 23:39:50803 callback.Pass());
[email protected]28571b042013-03-14 07:59:15804 }
805
[email protected]e216fef02013-03-20 22:56:10806 virtual void BeginTest() OVERRIDE {
[email protected]9794fb32013-08-29 09:49:59807 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
808
[email protected]28571b042013-03-14 07:59:15809 gfx::Size bounds(100, 100);
810 root_ = Layer::Create();
811 root_->SetAnchorPoint(gfx::PointF());
812 root_->SetBounds(bounds);
813
[email protected]e8e4ae232013-04-12 00:26:01814 layer_ = TextureLayer::CreateForMailbox(NULL);
[email protected]28571b042013-03-14 07:59:15815 layer_->SetIsDrawable(true);
816 layer_->SetAnchorPoint(gfx::PointF());
817 layer_->SetBounds(bounds);
818
819 root_->AddChild(layer_);
[email protected]e216fef02013-03-20 22:56:10820 layer_tree_host()->SetRootLayer(root_);
[email protected]18ce59702013-04-09 04:58:40821 layer_tree_host()->SetViewportSize(bounds);
[email protected]28571b042013-03-14 07:59:15822 SetMailbox('1');
823 EXPECT_EQ(0, callback_count_);
824
825 // Case #1: change mailbox before the commit. The old mailbox should be
826 // released immediately.
827 SetMailbox('2');
828 EXPECT_EQ(1, callback_count_);
[email protected]e216fef02013-03-20 22:56:10829 PostSetNeedsCommitToMainThread();
[email protected]28571b042013-03-14 07:59:15830 }
831
[email protected]e216fef02013-03-20 22:56:10832 virtual void DidCommit() OVERRIDE {
[email protected]28571b042013-03-14 07:59:15833 ++commit_count_;
834 switch (commit_count_) {
835 case 1:
836 // Case #2: change mailbox after the commit (and draw), where the
837 // layer draws. The old mailbox should be released during the next
838 // commit.
839 SetMailbox('3');
840 EXPECT_EQ(1, callback_count_);
841 break;
842 case 2:
[email protected]28571b042013-03-14 07:59:15843 EXPECT_EQ(2, callback_count_);
844 // Case #3: change mailbox when the layer doesn't draw. The old
845 // mailbox should be released during the next commit.
846 layer_->SetBounds(gfx::Size());
847 SetMailbox('4');
848 break;
[email protected]9794fb32013-08-29 09:49:59849 case 3:
[email protected]28571b042013-03-14 07:59:15850 EXPECT_EQ(3, callback_count_);
851 // Case #4: release mailbox that was committed but never drawn. The
852 // old mailbox should be released during the next commit.
[email protected]9260757f2013-09-17 01:24:16853 layer_->SetTextureMailbox(TextureMailbox(),
854 scoped_ptr<SingleReleaseCallback>());
[email protected]28571b042013-03-14 07:59:15855 break;
[email protected]9794fb32013-08-29 09:49:59856 case 4:
857 if (layer_tree_host()->settings().impl_side_painting) {
858 // With impl painting, the texture mailbox will still be on the impl
859 // thread when the commit finishes, because the layer is not drawble
860 // when it has no texture mailbox, and thus does not block the commit
861 // on activation. So, we wait for activation.
862 // TODO(danakj): fix this. crbug.com/277953
863 layer_tree_host()->SetNeedsCommit();
864 break;
865 } else {
866 ++commit_count_;
867 }
868 case 5:
[email protected]28571b042013-03-14 07:59:15869 EXPECT_EQ(4, callback_count_);
[email protected]7096acc2013-06-18 21:12:43870 // Restore a mailbox for the next step.
871 SetMailbox('5');
872 break;
[email protected]9794fb32013-08-29 09:49:59873 case 6:
[email protected]7096acc2013-06-18 21:12:43874 // Case #5: remove layer from tree. Callback should *not* be called, the
875 // mailbox is returned to the main thread.
876 EXPECT_EQ(4, callback_count_);
877 layer_->RemoveFromParent();
878 break;
[email protected]9794fb32013-08-29 09:49:59879 case 7:
880 if (layer_tree_host()->settings().impl_side_painting) {
881 // With impl painting, the texture mailbox will still be on the impl
882 // thread when the commit finishes, because the layer is not around to
883 // block the commit on activation anymore. So, we wait for activation.
884 // TODO(danakj): fix this. crbug.com/277953
885 layer_tree_host()->SetNeedsCommit();
886 break;
887 } else {
888 ++commit_count_;
889 }
890 case 8:
[email protected]7096acc2013-06-18 21:12:43891 EXPECT_EQ(4, callback_count_);
892 // Resetting the mailbox will call the callback now.
[email protected]9260757f2013-09-17 01:24:16893 layer_->SetTextureMailbox(TextureMailbox(),
894 scoped_ptr<SingleReleaseCallback>());
[email protected]7096acc2013-06-18 21:12:43895 EXPECT_EQ(5, callback_count_);
[email protected]e216fef02013-03-20 22:56:10896 EndTest();
[email protected]28571b042013-03-14 07:59:15897 break;
898 default:
899 NOTREACHED();
900 break;
[email protected]de44a152013-01-08 15:28:46901 }
[email protected]28571b042013-03-14 07:59:15902 }
[email protected]de44a152013-01-08 15:28:46903
[email protected]e216fef02013-03-20 22:56:10904 virtual void AfterTest() OVERRIDE {}
[email protected]de44a152013-01-08 15:28:46905
[email protected]28571b042013-03-14 07:59:15906 private:
[email protected]9794fb32013-08-29 09:49:59907 base::ThreadChecker main_thread_;
[email protected]28571b042013-03-14 07:59:15908 int callback_count_;
909 int commit_count_;
910 scoped_refptr<Layer> root_;
911 scoped_refptr<TextureLayer> layer_;
[email protected]de44a152013-01-08 15:28:46912};
913
[email protected]4145d172013-05-10 16:54:36914SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
915 TextureLayerImplWithMailboxThreadedCallback);
[email protected]de44a152013-01-08 15:28:46916
[email protected]74b43cc2013-08-30 06:29:27917
918class TextureLayerNoMailboxIsActivatedDuringCommit : public LayerTreeTest,
919 public TextureLayerClient {
920 protected:
921 TextureLayerNoMailboxIsActivatedDuringCommit()
[email protected]98ea818e2014-01-24 10:22:08922 : texture_(0u), activate_count_(0) {}
[email protected]74b43cc2013-08-30 06:29:27923
924 virtual void BeginTest() OVERRIDE {
[email protected]74b43cc2013-08-30 06:29:27925 gfx::Size bounds(100, 100);
926 root_ = Layer::Create();
927 root_->SetAnchorPoint(gfx::PointF());
928 root_->SetBounds(bounds);
929
930 layer_ = TextureLayer::Create(this);
931 layer_->SetIsDrawable(true);
932 layer_->SetAnchorPoint(gfx::PointF());
933 layer_->SetBounds(bounds);
934
935 root_->AddChild(layer_);
936 layer_tree_host()->SetRootLayer(root_);
937 layer_tree_host()->SetViewportSize(bounds);
938
939 PostSetNeedsCommitToMainThread();
940 }
941
[email protected]a6366932014-02-05 20:12:47942 virtual scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface(bool fallback)
[email protected]f5931d42013-11-06 19:44:57943 OVERRIDE {
944 scoped_refptr<TestContextProvider> provider = TestContextProvider::Create();
945 texture_ = provider->UnboundTestContext3d()->createExternalTexture();
[email protected]a6366932014-02-05 20:12:47946 return FakeOutputSurface::Create3d(provider);
[email protected]f5931d42013-11-06 19:44:57947 }
948
[email protected]74b43cc2013-08-30 06:29:27949 // TextureLayerClient implementation.
950 virtual unsigned PrepareTexture() OVERRIDE {
[email protected]f5931d42013-11-06 19:44:57951 return texture_;
[email protected]74b43cc2013-08-30 06:29:27952 }
[email protected]9260757f2013-09-17 01:24:16953 virtual bool PrepareTextureMailbox(
954 TextureMailbox* mailbox,
955 scoped_ptr<SingleReleaseCallback>* release_callback,
956 bool use_shared_memory) OVERRIDE {
[email protected]74b43cc2013-08-30 06:29:27957 return false;
958 }
959
960 virtual void WillActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
[email protected]74b43cc2013-08-30 06:29:27961 ++activate_count_;
962 }
963
[email protected]98ea818e2014-01-24 10:22:08964 virtual void DidCommit() OVERRIDE {
965 switch (layer_tree_host()->source_frame_number()) {
[email protected]74b43cc2013-08-30 06:29:27966 case 1:
967 // The first texture has been activated. Invalidate the layer so it
968 // grabs a new texture id from the client.
969 layer_->SetNeedsDisplay();
[email protected]74b43cc2013-08-30 06:29:27970 break;
971 case 2:
972 // The second mailbox has been activated. Remove the layer from
973 // the tree to cause another commit/activation. The commit should
974 // finish *after* the layer is removed from the active tree.
975 layer_->RemoveFromParent();
[email protected]74b43cc2013-08-30 06:29:27976 break;
977 case 3:
978 EndTest();
979 break;
980 }
981 }
982
[email protected]98ea818e2014-01-24 10:22:08983 virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
984 switch (host_impl->active_tree()->source_frame_number()) {
[email protected]74b43cc2013-08-30 06:29:27985 case 2: {
986 // The activate for the 2nd texture should have happened before now.
[email protected]74b43cc2013-08-30 06:29:27987 EXPECT_EQ(2, activate_count_);
988 break;
989 }
990 case 3: {
991 // The activate to remove the layer should have happened before now.
[email protected]74b43cc2013-08-30 06:29:27992 EXPECT_EQ(3, activate_count_);
993 break;
994 }
995 }
996 }
997
[email protected]74b43cc2013-08-30 06:29:27998 virtual void AfterTest() OVERRIDE {}
999
[email protected]f5931d42013-11-06 19:44:571000 unsigned texture_;
[email protected]74b43cc2013-08-30 06:29:271001 int activate_count_;
[email protected]74b43cc2013-08-30 06:29:271002 scoped_refptr<Layer> root_;
1003 scoped_refptr<TextureLayer> layer_;
1004};
1005
1006SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
1007 TextureLayerNoMailboxIsActivatedDuringCommit);
1008
1009class TextureLayerMailboxIsActivatedDuringCommit : public LayerTreeTest {
1010 protected:
[email protected]98ea818e2014-01-24 10:22:081011 TextureLayerMailboxIsActivatedDuringCommit() : activate_count_(0) {}
[email protected]74b43cc2013-08-30 06:29:271012
[email protected]df41e252014-02-03 23:39:501013 static void ReleaseCallback(uint32 sync_point, bool lost_resource) {}
[email protected]74b43cc2013-08-30 06:29:271014
1015 void SetMailbox(char mailbox_char) {
[email protected]9260757f2013-09-17 01:24:161016 scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create(
[email protected]74b43cc2013-08-30 06:29:271017 base::Bind(
1018 &TextureLayerMailboxIsActivatedDuringCommit::ReleaseCallback));
[email protected]df41e252014-02-03 23:39:501019 layer_->SetTextureMailbox(
[email protected]e0a4d732014-02-15 00:23:261020 TextureMailbox(MailboxFromChar(mailbox_char), GL_TEXTURE_2D, 0),
[email protected]df41e252014-02-03 23:39:501021 callback.Pass());
[email protected]74b43cc2013-08-30 06:29:271022 }
1023
1024 virtual void BeginTest() OVERRIDE {
[email protected]74b43cc2013-08-30 06:29:271025 gfx::Size bounds(100, 100);
1026 root_ = Layer::Create();
1027 root_->SetAnchorPoint(gfx::PointF());
1028 root_->SetBounds(bounds);
1029
1030 layer_ = TextureLayer::CreateForMailbox(NULL);
1031 layer_->SetIsDrawable(true);
1032 layer_->SetAnchorPoint(gfx::PointF());
1033 layer_->SetBounds(bounds);
1034
1035 root_->AddChild(layer_);
1036 layer_tree_host()->SetRootLayer(root_);
1037 layer_tree_host()->SetViewportSize(bounds);
1038 SetMailbox('1');
1039
1040 PostSetNeedsCommitToMainThread();
1041 }
1042
1043 virtual void WillActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
[email protected]74b43cc2013-08-30 06:29:271044 ++activate_count_;
1045 }
1046
[email protected]98ea818e2014-01-24 10:22:081047 virtual void DidCommit() OVERRIDE {
1048 switch (layer_tree_host()->source_frame_number()) {
[email protected]74b43cc2013-08-30 06:29:271049 case 1:
1050 // The first mailbox has been activated. Set a new mailbox, and
1051 // expect the next commit to finish *after* it is activated.
1052 SetMailbox('2');
[email protected]74b43cc2013-08-30 06:29:271053 break;
1054 case 2:
1055 // The second mailbox has been activated. Remove the layer from
1056 // the tree to cause another commit/activation. The commit should
1057 // finish *after* the layer is removed from the active tree.
1058 layer_->RemoveFromParent();
[email protected]74b43cc2013-08-30 06:29:271059 break;
1060 case 3:
1061 EndTest();
1062 break;
1063 }
1064 }
1065
[email protected]98ea818e2014-01-24 10:22:081066 virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
1067 switch (host_impl->active_tree()->source_frame_number()) {
[email protected]74b43cc2013-08-30 06:29:271068 case 2: {
1069 // The activate for the 2nd mailbox should have happened before now.
[email protected]74b43cc2013-08-30 06:29:271070 EXPECT_EQ(2, activate_count_);
1071 break;
1072 }
1073 case 3: {
1074 // The activate to remove the layer should have happened before now.
[email protected]74b43cc2013-08-30 06:29:271075 EXPECT_EQ(3, activate_count_);
1076 break;
1077 }
1078 }
1079 }
1080
1081
1082 virtual void AfterTest() OVERRIDE {}
1083
[email protected]74b43cc2013-08-30 06:29:271084 int activate_count_;
1085 scoped_refptr<Layer> root_;
1086 scoped_refptr<TextureLayer> layer_;
1087};
1088
1089SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
1090 TextureLayerMailboxIsActivatedDuringCommit);
1091
[email protected]de44a152013-01-08 15:28:461092class TextureLayerImplWithMailboxTest : public TextureLayerTest {
[email protected]28571b042013-03-14 07:59:151093 protected:
[email protected]408b5e22013-03-19 09:48:091094 TextureLayerImplWithMailboxTest()
1095 : fake_client_(
1096 FakeLayerTreeHostClient(FakeLayerTreeHostClient::DIRECT_3D)) {}
1097
[email protected]28571b042013-03-14 07:59:151098 virtual void SetUp() {
1099 TextureLayerTest::SetUp();
[email protected]408b5e22013-03-19 09:48:091100 layer_tree_host_.reset(new MockLayerTreeHost(&fake_client_));
[email protected]a6366932014-02-05 20:12:471101 EXPECT_TRUE(host_impl_.InitializeRenderer(
1102 FakeOutputSurface::Create3d().PassAs<OutputSurface>()));
[email protected]28571b042013-03-14 07:59:151103 }
[email protected]de44a152013-01-08 15:28:461104
[email protected]0ec335c42013-07-04 06:17:081105 bool WillDraw(TextureLayerImpl* layer, DrawMode mode) {
1106 bool will_draw = layer->WillDraw(
1107 mode, host_impl_.active_tree()->resource_provider());
1108 if (will_draw)
1109 layer->DidDraw(host_impl_.active_tree()->resource_provider());
1110 return will_draw;
1111 }
1112
[email protected]28571b042013-03-14 07:59:151113 CommonMailboxObjects test_data_;
[email protected]408b5e22013-03-19 09:48:091114 FakeLayerTreeHostClient fake_client_;
[email protected]de44a152013-01-08 15:28:461115};
1116
[email protected]ffbb2212013-06-02 23:47:591117// Test conditions for results of TextureLayerImpl::WillDraw under
1118// different configurations of different mailbox, texture_id, and draw_mode.
1119TEST_F(TextureLayerImplWithMailboxTest, TestWillDraw) {
[email protected]0ec335c42013-07-04 06:17:081120 EXPECT_CALL(test_data_.mock_callback_,
1121 Release(test_data_.mailbox_name1_,
1122 test_data_.sync_point1_,
1123 false))
1124 .Times(AnyNumber());
1125 EXPECT_CALL(test_data_.mock_callback_,
1126 Release2(test_data_.shared_memory_.get(), 0, false))
1127 .Times(AnyNumber());
[email protected]ffbb2212013-06-02 23:47:591128 // Hardware mode.
1129 {
1130 scoped_ptr<TextureLayerImpl> impl_layer =
1131 TextureLayerImpl::Create(host_impl_.active_tree(), 1, true);
[email protected]afc4f262013-10-05 01:14:101132 impl_layer->SetDrawsContent(true);
[email protected]9260757f2013-09-17 01:24:161133 impl_layer->SetTextureMailbox(
1134 test_data_.mailbox1_,
1135 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
[email protected]0ec335c42013-07-04 06:17:081136 EXPECT_TRUE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE));
[email protected]ffbb2212013-06-02 23:47:591137 }
1138
1139 {
1140 scoped_ptr<TextureLayerImpl> impl_layer =
1141 TextureLayerImpl::Create(host_impl_.active_tree(), 1, true);
[email protected]afc4f262013-10-05 01:14:101142 impl_layer->SetDrawsContent(true);
[email protected]9260757f2013-09-17 01:24:161143 impl_layer->SetTextureMailbox(TextureMailbox(),
1144 scoped_ptr<SingleReleaseCallback>());
[email protected]0ec335c42013-07-04 06:17:081145 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE));
1146 }
1147
1148 {
1149 // Software resource.
1150 scoped_ptr<TextureLayerImpl> impl_layer =
1151 TextureLayerImpl::Create(host_impl_.active_tree(), 1, true);
[email protected]afc4f262013-10-05 01:14:101152 impl_layer->SetDrawsContent(true);
[email protected]9260757f2013-09-17 01:24:161153 impl_layer->SetTextureMailbox(
1154 test_data_.mailbox3_,
1155 SingleReleaseCallback::Create(test_data_.release_mailbox3_));
[email protected]3e44d7a2013-07-30 00:03:101156 EXPECT_TRUE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE));
[email protected]ffbb2212013-06-02 23:47:591157 }
1158
1159 {
1160 scoped_ptr<TextureLayerImpl> impl_layer =
1161 TextureLayerImpl::Create(host_impl_.active_tree(), 1, false);
[email protected]afc4f262013-10-05 01:14:101162 impl_layer->SetDrawsContent(true);
[email protected]0634cdd42013-08-16 00:46:091163 ContextProvider* context_provider =
1164 host_impl_.output_surface()->context_provider();
[email protected]1dff7962014-01-10 12:05:031165 GLuint texture = 0;
1166 context_provider->ContextGL()->GenTextures(1, &texture);
[email protected]ad0250b2014-01-18 03:24:341167 impl_layer->SetTextureId(texture);
[email protected]0ec335c42013-07-04 06:17:081168 EXPECT_TRUE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE));
[email protected]ffbb2212013-06-02 23:47:591169 }
1170
1171 {
1172 scoped_ptr<TextureLayerImpl> impl_layer =
1173 TextureLayerImpl::Create(host_impl_.active_tree(), 1, false);
[email protected]afc4f262013-10-05 01:14:101174 impl_layer->SetDrawsContent(true);
[email protected]ad0250b2014-01-18 03:24:341175 impl_layer->SetTextureId(0);
[email protected]0ec335c42013-07-04 06:17:081176 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE));
1177 }
1178
1179 // Software mode.
1180 {
1181 scoped_ptr<TextureLayerImpl> impl_layer =
1182 TextureLayerImpl::Create(host_impl_.active_tree(), 1, true);
[email protected]afc4f262013-10-05 01:14:101183 impl_layer->SetDrawsContent(true);
[email protected]9260757f2013-09-17 01:24:161184 impl_layer->SetTextureMailbox(
1185 test_data_.mailbox1_,
1186 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
[email protected]0ec335c42013-07-04 06:17:081187 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE));
1188 }
1189
1190 {
1191 scoped_ptr<TextureLayerImpl> impl_layer =
1192 TextureLayerImpl::Create(host_impl_.active_tree(), 1, true);
[email protected]afc4f262013-10-05 01:14:101193 impl_layer->SetDrawsContent(true);
[email protected]9260757f2013-09-17 01:24:161194 impl_layer->SetTextureMailbox(TextureMailbox(),
1195 scoped_ptr<SingleReleaseCallback>());
[email protected]0ec335c42013-07-04 06:17:081196 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE));
1197 }
1198
1199 {
1200 // Software resource.
1201 scoped_ptr<TextureLayerImpl> impl_layer =
1202 TextureLayerImpl::Create(host_impl_.active_tree(), 1, true);
[email protected]afc4f262013-10-05 01:14:101203 impl_layer->SetDrawsContent(true);
[email protected]9260757f2013-09-17 01:24:161204 impl_layer->SetTextureMailbox(
1205 test_data_.mailbox3_,
1206 SingleReleaseCallback::Create(test_data_.release_mailbox3_));
[email protected]0ec335c42013-07-04 06:17:081207 EXPECT_TRUE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE));
1208 }
1209
1210 {
1211 scoped_ptr<TextureLayerImpl> impl_layer =
1212 TextureLayerImpl::Create(host_impl_.active_tree(), 1, false);
[email protected]afc4f262013-10-05 01:14:101213 impl_layer->SetDrawsContent(true);
[email protected]0634cdd42013-08-16 00:46:091214 ContextProvider* context_provider =
1215 host_impl_.output_surface()->context_provider();
[email protected]1dff7962014-01-10 12:05:031216 GLuint texture = 0;
1217 context_provider->ContextGL()->GenTextures(1, &texture);
[email protected]ad0250b2014-01-18 03:24:341218 impl_layer->SetTextureId(texture);
[email protected]0ec335c42013-07-04 06:17:081219 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE));
1220 }
1221
1222 {
1223 scoped_ptr<TextureLayerImpl> impl_layer =
1224 TextureLayerImpl::Create(host_impl_.active_tree(), 1, false);
[email protected]afc4f262013-10-05 01:14:101225 impl_layer->SetDrawsContent(true);
[email protected]ad0250b2014-01-18 03:24:341226 impl_layer->SetTextureId(0);
[email protected]0ec335c42013-07-04 06:17:081227 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE));
[email protected]ffbb2212013-06-02 23:47:591228 }
1229
1230 // Resourceless software mode.
1231 {
1232 scoped_ptr<TextureLayerImpl> impl_layer =
1233 TextureLayerImpl::Create(host_impl_.active_tree(), 1, true);
[email protected]afc4f262013-10-05 01:14:101234 impl_layer->SetDrawsContent(true);
[email protected]9260757f2013-09-17 01:24:161235 impl_layer->SetTextureMailbox(
1236 test_data_.mailbox1_,
1237 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
[email protected]0ec335c42013-07-04 06:17:081238 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_RESOURCELESS_SOFTWARE));
[email protected]ffbb2212013-06-02 23:47:591239 }
1240
1241 {
1242 scoped_ptr<TextureLayerImpl> impl_layer =
1243 TextureLayerImpl::Create(host_impl_.active_tree(), 1, false);
[email protected]afc4f262013-10-05 01:14:101244 impl_layer->SetDrawsContent(true);
[email protected]0634cdd42013-08-16 00:46:091245 ContextProvider* context_provider =
1246 host_impl_.output_surface()->context_provider();
[email protected]1dff7962014-01-10 12:05:031247 GLuint texture = 0;
1248 context_provider->ContextGL()->GenTextures(1, &texture);
[email protected]ad0250b2014-01-18 03:24:341249 impl_layer->SetTextureId(texture);
[email protected]0ec335c42013-07-04 06:17:081250 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_RESOURCELESS_SOFTWARE));
[email protected]ffbb2212013-06-02 23:47:591251 }
1252}
1253
[email protected]28571b042013-03-14 07:59:151254TEST_F(TextureLayerImplWithMailboxTest, TestImplLayerCallbacks) {
1255 host_impl_.CreatePendingTree();
1256 scoped_ptr<TextureLayerImpl> pending_layer;
1257 pending_layer = TextureLayerImpl::Create(host_impl_.pending_tree(), 1, true);
1258 ASSERT_TRUE(pending_layer);
[email protected]de44a152013-01-08 15:28:461259
[email protected]ed511b8d2013-03-25 03:29:291260 scoped_ptr<LayerImpl> active_layer(
[email protected]28571b042013-03-14 07:59:151261 pending_layer->CreateLayerImpl(host_impl_.active_tree()));
[email protected]ed511b8d2013-03-25 03:29:291262 ASSERT_TRUE(active_layer);
[email protected]de44a152013-01-08 15:28:461263
[email protected]9260757f2013-09-17 01:24:161264 pending_layer->SetTextureMailbox(
1265 test_data_.mailbox1_,
1266 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
[email protected]421e84f2013-02-22 03:27:151267
[email protected]28571b042013-03-14 07:59:151268 // Test multiple commits without an activation.
1269 EXPECT_CALL(test_data_.mock_callback_,
[email protected]7ba3ca72013-04-11 06:37:251270 Release(test_data_.mailbox_name1_,
1271 test_data_.sync_point1_,
1272 false))
[email protected]28571b042013-03-14 07:59:151273 .Times(1);
[email protected]9260757f2013-09-17 01:24:161274 pending_layer->SetTextureMailbox(
1275 test_data_.mailbox2_,
1276 SingleReleaseCallback::Create(test_data_.release_mailbox2_));
[email protected]28571b042013-03-14 07:59:151277 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]421e84f2013-02-22 03:27:151278
[email protected]28571b042013-03-14 07:59:151279 // Test callback after activation.
[email protected]ed511b8d2013-03-25 03:29:291280 pending_layer->PushPropertiesTo(active_layer.get());
1281 active_layer->DidBecomeActive();
[email protected]421e84f2013-02-22 03:27:151282
[email protected]7ba3ca72013-04-11 06:37:251283 EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0);
[email protected]9260757f2013-09-17 01:24:161284 pending_layer->SetTextureMailbox(
1285 test_data_.mailbox1_,
1286 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
[email protected]28571b042013-03-14 07:59:151287 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]421e84f2013-02-22 03:27:151288
[email protected]7ba3ca72013-04-11 06:37:251289 EXPECT_CALL(test_data_.mock_callback_,
1290 Release(test_data_.mailbox_name2_, _, false))
[email protected]28571b042013-03-14 07:59:151291 .Times(1);
[email protected]ed511b8d2013-03-25 03:29:291292 pending_layer->PushPropertiesTo(active_layer.get());
1293 active_layer->DidBecomeActive();
[email protected]28571b042013-03-14 07:59:151294 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]de44a152013-01-08 15:28:461295
[email protected]28571b042013-03-14 07:59:151296 // Test resetting the mailbox.
[email protected]7ba3ca72013-04-11 06:37:251297 EXPECT_CALL(test_data_.mock_callback_,
1298 Release(test_data_.mailbox_name1_, _, false))
[email protected]28571b042013-03-14 07:59:151299 .Times(1);
[email protected]9260757f2013-09-17 01:24:161300 pending_layer->SetTextureMailbox(TextureMailbox(),
1301 scoped_ptr<SingleReleaseCallback>());
[email protected]ed511b8d2013-03-25 03:29:291302 pending_layer->PushPropertiesTo(active_layer.get());
1303 active_layer->DidBecomeActive();
[email protected]28571b042013-03-14 07:59:151304 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]de44a152013-01-08 15:28:461305
[email protected]28571b042013-03-14 07:59:151306 // Test destructor.
1307 EXPECT_CALL(test_data_.mock_callback_,
[email protected]7ba3ca72013-04-11 06:37:251308 Release(test_data_.mailbox_name1_,
1309 test_data_.sync_point1_,
1310 false))
[email protected]28571b042013-03-14 07:59:151311 .Times(1);
[email protected]9260757f2013-09-17 01:24:161312 pending_layer->SetTextureMailbox(
1313 test_data_.mailbox1_,
1314 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
[email protected]de44a152013-01-08 15:28:461315}
1316
[email protected]28571b042013-03-14 07:59:151317TEST_F(TextureLayerImplWithMailboxTest,
1318 TestDestructorCallbackOnCreatedResource) {
1319 scoped_ptr<TextureLayerImpl> impl_layer;
1320 impl_layer = TextureLayerImpl::Create(host_impl_.active_tree(), 1, true);
1321 ASSERT_TRUE(impl_layer);
[email protected]de44a152013-01-08 15:28:461322
[email protected]7ba3ca72013-04-11 06:37:251323 EXPECT_CALL(test_data_.mock_callback_,
1324 Release(test_data_.mailbox_name1_, _, false))
[email protected]28571b042013-03-14 07:59:151325 .Times(1);
[email protected]9260757f2013-09-17 01:24:161326 impl_layer->SetTextureMailbox(
1327 test_data_.mailbox1_,
1328 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
[email protected]afc4f262013-10-05 01:14:101329 impl_layer->SetDrawsContent(true);
[email protected]ffbb2212013-06-02 23:47:591330 impl_layer->DidBecomeActive();
1331 EXPECT_TRUE(impl_layer->WillDraw(
1332 DRAW_MODE_HARDWARE, host_impl_.active_tree()->resource_provider()));
[email protected]28571b042013-03-14 07:59:151333 impl_layer->DidDraw(host_impl_.active_tree()->resource_provider());
[email protected]9260757f2013-09-17 01:24:161334 impl_layer->SetTextureMailbox(TextureMailbox(),
1335 scoped_ptr<SingleReleaseCallback>());
[email protected]de44a152013-01-08 15:28:461336}
1337
[email protected]28571b042013-03-14 07:59:151338TEST_F(TextureLayerImplWithMailboxTest, TestCallbackOnInUseResource) {
1339 ResourceProvider* provider = host_impl_.active_tree()->resource_provider();
1340 ResourceProvider::ResourceId id =
[email protected]9260757f2013-09-17 01:24:161341 provider->CreateResourceFromTextureMailbox(
1342 test_data_.mailbox1_,
1343 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
[email protected]28571b042013-03-14 07:59:151344 provider->AllocateForTesting(id);
[email protected]de44a152013-01-08 15:28:461345
[email protected]28571b042013-03-14 07:59:151346 // Transfer some resources to the parent.
1347 ResourceProvider::ResourceIdArray resource_ids_to_transfer;
1348 resource_ids_to_transfer.push_back(id);
1349 TransferableResourceArray list;
1350 provider->PrepareSendToParent(resource_ids_to_transfer, &list);
1351 EXPECT_TRUE(provider->InUseByConsumer(id));
[email protected]7ba3ca72013-04-11 06:37:251352 EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0);
[email protected]28571b042013-03-14 07:59:151353 provider->DeleteResource(id);
1354 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]7ba3ca72013-04-11 06:37:251355 EXPECT_CALL(test_data_.mock_callback_,
1356 Release(test_data_.mailbox_name1_, _, false))
[email protected]28571b042013-03-14 07:59:151357 .Times(1);
[email protected]e00bab022013-08-19 00:42:451358 ReturnedResourceArray returned;
1359 TransferableResource::ReturnResources(list, &returned);
1360 provider->ReceiveReturnsFromParent(returned);
[email protected]de44a152013-01-08 15:28:461361}
1362
[email protected]97d519fb2013-03-29 02:27:541363// Check that ClearClient correctly clears the state so that the impl side
1364// doesn't try to use a texture that could have been destroyed.
[email protected]7ba3ca72013-04-11 06:37:251365class TextureLayerClientTest
1366 : public LayerTreeTest,
1367 public TextureLayerClient {
[email protected]97d519fb2013-03-29 02:27:541368 public:
1369 TextureLayerClientTest()
[email protected]f5931d42013-11-06 19:44:571370 : texture_(0),
[email protected]97d519fb2013-03-29 02:27:541371 commit_count_(0),
1372 expected_used_textures_on_draw_(0),
1373 expected_used_textures_on_commit_(0) {}
1374
[email protected]a6366932014-02-05 20:12:471375 virtual scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface(bool fallback)
[email protected]ebc0e1df2013-08-01 02:46:221376 OVERRIDE {
[email protected]f5931d42013-11-06 19:44:571377 scoped_refptr<TestContextProvider> provider = TestContextProvider::Create();
1378 texture_ = provider->UnboundTestContext3d()->createExternalTexture();
[email protected]a6366932014-02-05 20:12:471379 return FakeOutputSurface::Create3d(provider);
[email protected]97d519fb2013-03-29 02:27:541380 }
1381
[email protected]f5931d42013-11-06 19:44:571382 virtual unsigned PrepareTexture() OVERRIDE { return texture_; }
[email protected]97d519fb2013-03-29 02:27:541383
[email protected]2541d1a2013-07-10 07:33:271384 virtual bool PrepareTextureMailbox(
[email protected]9260757f2013-09-17 01:24:161385 TextureMailbox* mailbox,
1386 scoped_ptr<SingleReleaseCallback>* release_callback,
1387 bool use_shared_memory) OVERRIDE {
[email protected]e8e4ae232013-04-12 00:26:011388 return false;
1389 }
1390
[email protected]97d519fb2013-03-29 02:27:541391 virtual void SetupTree() OVERRIDE {
1392 scoped_refptr<Layer> root = Layer::Create();
1393 root->SetBounds(gfx::Size(10, 10));
1394 root->SetAnchorPoint(gfx::PointF());
1395 root->SetIsDrawable(true);
1396
1397 texture_layer_ = TextureLayer::Create(this);
1398 texture_layer_->SetBounds(gfx::Size(10, 10));
1399 texture_layer_->SetAnchorPoint(gfx::PointF());
1400 texture_layer_->SetIsDrawable(true);
1401 root->AddChild(texture_layer_);
1402
1403 layer_tree_host()->SetRootLayer(root);
1404 LayerTreeTest::SetupTree();
1405 {
1406 base::AutoLock lock(lock_);
1407 expected_used_textures_on_commit_ = 1;
1408 }
1409 }
1410
1411 virtual void BeginTest() OVERRIDE {
1412 PostSetNeedsCommitToMainThread();
1413 }
1414
1415 virtual void DidCommitAndDrawFrame() OVERRIDE {
1416 ++commit_count_;
1417 switch (commit_count_) {
1418 case 1:
1419 texture_layer_->ClearClient();
1420 texture_layer_->SetNeedsDisplay();
1421 {
1422 base::AutoLock lock(lock_);
1423 expected_used_textures_on_commit_ = 0;
1424 }
[email protected]97d519fb2013-03-29 02:27:541425 break;
1426 case 2:
1427 EndTest();
1428 break;
1429 default:
1430 NOTREACHED();
1431 break;
1432 }
1433 }
1434
1435 virtual void BeginCommitOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
1436 base::AutoLock lock(lock_);
1437 expected_used_textures_on_draw_ = expected_used_textures_on_commit_;
1438 }
1439
[email protected]7ddfe7e82014-01-30 07:22:111440 virtual DrawSwapReadbackResult::DrawResult PrepareToDrawOnThread(
1441 LayerTreeHostImpl* host_impl,
1442 LayerTreeHostImpl::FrameData* frame_data,
1443 DrawSwapReadbackResult::DrawResult draw_result) OVERRIDE {
[email protected]f5931d42013-11-06 19:44:571444 ContextForImplThread(host_impl)->ResetUsedTextures();
[email protected]7ddfe7e82014-01-30 07:22:111445 return DrawSwapReadbackResult::DRAW_SUCCESS;
[email protected]97d519fb2013-03-29 02:27:541446 }
1447
1448 virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl,
1449 bool result) OVERRIDE {
1450 ASSERT_TRUE(result);
[email protected]f5931d42013-11-06 19:44:571451 EXPECT_EQ(expected_used_textures_on_draw_,
1452 ContextForImplThread(host_impl)->NumUsedTextures());
[email protected]97d519fb2013-03-29 02:27:541453 }
1454
1455 virtual void AfterTest() OVERRIDE {}
1456
1457 private:
[email protected]f5931d42013-11-06 19:44:571458 TestWebGraphicsContext3D* ContextForImplThread(LayerTreeHostImpl* host_impl) {
[email protected]1dff7962014-01-10 12:05:031459 return static_cast<TestContextProvider*>(
1460 host_impl->output_surface()->context_provider().get())->TestContext3d();
[email protected]f5931d42013-11-06 19:44:571461 }
1462
[email protected]97d519fb2013-03-29 02:27:541463 scoped_refptr<TextureLayer> texture_layer_;
[email protected]97d519fb2013-03-29 02:27:541464 unsigned texture_;
1465 int commit_count_;
1466
1467 // Used only on thread.
1468 unsigned expected_used_textures_on_draw_;
1469
1470 // Used on either thread, protected by lock_.
1471 base::Lock lock_;
1472 unsigned expected_used_textures_on_commit_;
1473};
1474
[email protected]4145d172013-05-10 16:54:361475// The TextureLayerClient does not use mailboxes, so can't use a delegating
1476// renderer.
1477SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(TextureLayerClientTest);
[email protected]97d519fb2013-03-29 02:27:541478
[email protected]b04264f92013-09-13 23:37:291479
1480// Checks that changing a texture in the client for a TextureLayer that's
1481// invisible correctly works without drawing a deleted texture. See
1482// crbug.com/266628
1483class TextureLayerChangeInvisibleTest
1484 : public LayerTreeTest,
1485 public TextureLayerClient {
1486 public:
1487 TextureLayerChangeInvisibleTest()
[email protected]f5931d42013-11-06 19:44:571488 : texture_(0u),
[email protected]b04264f92013-09-13 23:37:291489 prepare_called_(0),
1490 commit_count_(0),
1491 expected_texture_on_draw_(0) {}
1492
[email protected]a6366932014-02-05 20:12:471493 virtual scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface(bool fallback)
[email protected]f5931d42013-11-06 19:44:571494 OVERRIDE {
1495 scoped_refptr<TestContextProvider> provider = TestContextProvider::Create();
1496 texture_ = provider->UnboundTestContext3d()->createExternalTexture();
[email protected]a6366932014-02-05 20:12:471497 return FakeOutputSurface::Create3d(provider);
[email protected]f5931d42013-11-06 19:44:571498 }
1499
[email protected]b04264f92013-09-13 23:37:291500 // TextureLayerClient implementation.
1501 virtual unsigned PrepareTexture() OVERRIDE {
1502 ++prepare_called_;
1503 return texture_;
1504 }
[email protected]b04264f92013-09-13 23:37:291505 virtual bool PrepareTextureMailbox(
[email protected]e51444a2013-12-10 23:05:011506 TextureMailbox* mailbox,
[email protected]9260757f2013-09-17 01:24:161507 scoped_ptr<SingleReleaseCallback>* release_callback,
1508 bool use_shared_memory) OVERRIDE {
[email protected]b04264f92013-09-13 23:37:291509 return false;
1510 }
1511
1512 virtual void SetupTree() OVERRIDE {
1513 scoped_refptr<Layer> root = Layer::Create();
1514 root->SetBounds(gfx::Size(10, 10));
1515 root->SetAnchorPoint(gfx::PointF());
1516 root->SetIsDrawable(true);
1517
1518 solid_layer_ = SolidColorLayer::Create();
1519 solid_layer_->SetBounds(gfx::Size(10, 10));
1520 solid_layer_->SetIsDrawable(true);
1521 solid_layer_->SetBackgroundColor(SK_ColorWHITE);
1522 root->AddChild(solid_layer_);
1523
1524 parent_layer_ = Layer::Create();
1525 parent_layer_->SetBounds(gfx::Size(10, 10));
1526 parent_layer_->SetIsDrawable(true);
1527 root->AddChild(parent_layer_);
1528
1529 texture_layer_ = TextureLayer::Create(this);
1530 texture_layer_->SetBounds(gfx::Size(10, 10));
1531 texture_layer_->SetAnchorPoint(gfx::PointF());
1532 texture_layer_->SetIsDrawable(true);
1533 parent_layer_->AddChild(texture_layer_);
1534
1535 layer_tree_host()->SetRootLayer(root);
1536 LayerTreeTest::SetupTree();
1537 }
1538
1539 virtual void BeginTest() OVERRIDE {
1540 PostSetNeedsCommitToMainThread();
1541 }
1542
1543 virtual void DidCommitAndDrawFrame() OVERRIDE {
1544 ++commit_count_;
1545 switch (commit_count_) {
1546 case 1:
1547 // We should have updated the layer, committing the texture.
1548 EXPECT_EQ(1, prepare_called_);
1549 // Make layer invisible.
1550 parent_layer_->SetOpacity(0.f);
1551 break;
1552 case 2: {
1553 // Layer shouldn't have been updated.
1554 EXPECT_EQ(1, prepare_called_);
[email protected]b04264f92013-09-13 23:37:291555 texture_layer_->SetNeedsDisplay();
1556 // Force a change to make sure we draw a frame.
1557 solid_layer_->SetBackgroundColor(SK_ColorGRAY);
1558 break;
1559 }
1560 case 3:
1561 EXPECT_EQ(1, prepare_called_);
[email protected]b04264f92013-09-13 23:37:291562 // Make layer visible again.
1563 parent_layer_->SetOpacity(1.f);
1564 break;
1565 case 4: {
1566 // Layer should have been updated.
1567 EXPECT_EQ(2, prepare_called_);
1568 texture_layer_->ClearClient();
[email protected]b04264f92013-09-13 23:37:291569 texture_ = 0;
1570 break;
1571 }
1572 case 5:
1573 EndTest();
1574 break;
1575 default:
1576 NOTREACHED();
1577 break;
1578 }
1579 }
1580
1581 virtual void BeginCommitOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
1582 ASSERT_TRUE(proxy()->IsMainThreadBlocked());
1583 // This is the only texture that can be drawn this frame.
1584 expected_texture_on_draw_ = texture_;
1585 }
1586
[email protected]7ddfe7e82014-01-30 07:22:111587 virtual DrawSwapReadbackResult::DrawResult PrepareToDrawOnThread(
1588 LayerTreeHostImpl* host_impl,
1589 LayerTreeHostImpl::FrameData* frame_data,
1590 DrawSwapReadbackResult::DrawResult draw_result) OVERRIDE {
[email protected]b04264f92013-09-13 23:37:291591 ContextForImplThread(host_impl)->ResetUsedTextures();
[email protected]7ddfe7e82014-01-30 07:22:111592 return DrawSwapReadbackResult::DRAW_SUCCESS;
[email protected]b04264f92013-09-13 23:37:291593 }
1594
1595 virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl,
1596 bool result) OVERRIDE {
1597 ASSERT_TRUE(result);
1598 TestWebGraphicsContext3D* context = ContextForImplThread(host_impl);
1599 int used_textures = context->NumUsedTextures();
1600 switch (host_impl->active_tree()->source_frame_number()) {
1601 case 0:
1602 EXPECT_EQ(1, used_textures);
1603 EXPECT_TRUE(context->UsedTexture(expected_texture_on_draw_));
1604 break;
1605 case 1:
1606 case 2:
1607 EXPECT_EQ(0, used_textures);
1608 break;
1609 case 3:
1610 EXPECT_EQ(1, used_textures);
1611 EXPECT_TRUE(context->UsedTexture(expected_texture_on_draw_));
1612 break;
1613 default:
1614 break;
1615 }
1616 }
1617
1618 virtual void AfterTest() OVERRIDE {}
1619
1620 private:
1621 TestWebGraphicsContext3D* ContextForImplThread(LayerTreeHostImpl* host_impl) {
[email protected]1dff7962014-01-10 12:05:031622 return static_cast<TestContextProvider*>(
1623 host_impl->output_surface()->context_provider().get())->TestContext3d();
[email protected]b04264f92013-09-13 23:37:291624 }
1625
1626 scoped_refptr<SolidColorLayer> solid_layer_;
1627 scoped_refptr<Layer> parent_layer_;
1628 scoped_refptr<TextureLayer> texture_layer_;
[email protected]b04264f92013-09-13 23:37:291629
1630 // Used on the main thread, and on the impl thread while the main thread is
1631 // blocked.
1632 unsigned texture_;
1633
1634 // Used on the main thread.
[email protected]b04264f92013-09-13 23:37:291635 int prepare_called_;
1636 int commit_count_;
1637
1638 // Used on the compositor thread.
1639 unsigned expected_texture_on_draw_;
1640};
1641
1642// The TextureLayerChangeInvisibleTest does not use mailboxes, so can't use a
1643// delegating renderer.
1644SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(TextureLayerChangeInvisibleTest);
1645
[email protected]4bad8b62013-10-24 01:27:291646// Checks that TextureLayer::Update does not cause an extra commit when setting
1647// the texture mailbox.
1648class TextureLayerNoExtraCommitForMailboxTest
1649 : public LayerTreeTest,
1650 public TextureLayerClient {
1651 public:
[email protected]4bad8b62013-10-24 01:27:291652 // TextureLayerClient implementation.
1653 virtual unsigned PrepareTexture() OVERRIDE {
1654 NOTREACHED();
1655 return 0;
1656 }
[email protected]4bad8b62013-10-24 01:27:291657 virtual bool PrepareTextureMailbox(
[email protected]df41e252014-02-03 23:39:501658 TextureMailbox* texture_mailbox,
[email protected]4bad8b62013-10-24 01:27:291659 scoped_ptr<SingleReleaseCallback>* release_callback,
1660 bool use_shared_memory) OVERRIDE {
[email protected]cce34bd2013-12-02 23:24:451661 if (layer_tree_host()->source_frame_number() == 1) {
[email protected]df41e252014-02-03 23:39:501662 *texture_mailbox = TextureMailbox();
[email protected]cce34bd2013-12-02 23:24:451663 return true;
1664 }
[email protected]4bad8b62013-10-24 01:27:291665
[email protected]e0a4d732014-02-15 00:23:261666 *texture_mailbox = TextureMailbox(MailboxFromChar('1'), GL_TEXTURE_2D, 0);
[email protected]4bad8b62013-10-24 01:27:291667 *release_callback = SingleReleaseCallback::Create(
1668 base::Bind(&TextureLayerNoExtraCommitForMailboxTest::MailboxReleased,
1669 base::Unretained(this)));
[email protected]4bad8b62013-10-24 01:27:291670 return true;
1671 }
1672
[email protected]df41e252014-02-03 23:39:501673 void MailboxReleased(uint32 sync_point, bool lost_resource) {
[email protected]cce34bd2013-12-02 23:24:451674 EXPECT_EQ(2, layer_tree_host()->source_frame_number());
1675 EndTest();
[email protected]4bad8b62013-10-24 01:27:291676 }
1677
1678 virtual void SetupTree() OVERRIDE {
1679 scoped_refptr<Layer> root = Layer::Create();
1680 root->SetBounds(gfx::Size(10, 10));
1681 root->SetAnchorPoint(gfx::PointF());
1682 root->SetIsDrawable(true);
1683
[email protected]4bad8b62013-10-24 01:27:291684 texture_layer_ = TextureLayer::CreateForMailbox(this);
1685 texture_layer_->SetBounds(gfx::Size(10, 10));
1686 texture_layer_->SetAnchorPoint(gfx::PointF());
1687 texture_layer_->SetIsDrawable(true);
[email protected]0d7fb302014-01-23 21:30:471688 root->AddChild(texture_layer_);
[email protected]4bad8b62013-10-24 01:27:291689
1690 layer_tree_host()->SetRootLayer(root);
1691 LayerTreeTest::SetupTree();
1692 }
1693
1694 virtual void BeginTest() OVERRIDE {
1695 PostSetNeedsCommitToMainThread();
1696 }
1697
[email protected]cce34bd2013-12-02 23:24:451698 virtual void DidCommitAndDrawFrame() OVERRIDE {
[email protected]4bad8b62013-10-24 01:27:291699 switch (layer_tree_host()->source_frame_number()) {
1700 case 1:
[email protected]cce34bd2013-12-02 23:24:451701 EXPECT_FALSE(proxy()->CommitPendingForTesting());
1702 // Invalidate the texture layer to clear the mailbox before
1703 // ending the test.
1704 texture_layer_->SetNeedsDisplay();
1705 break;
1706 case 2:
[email protected]4bad8b62013-10-24 01:27:291707 break;
1708 default:
1709 NOTREACHED();
1710 break;
1711 }
1712 }
1713
[email protected]cce34bd2013-12-02 23:24:451714 virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl,
1715 bool result) OVERRIDE {
1716 ASSERT_TRUE(result);
1717 DelegatedFrameData* delegated_frame_data =
1718 output_surface()->last_sent_frame().delegated_frame_data.get();
1719 if (!delegated_frame_data)
1720 return;
1721
1722 // Return all resources immediately.
1723 TransferableResourceArray resources_to_return =
1724 output_surface()->resources_held_by_parent();
1725
1726 CompositorFrameAck ack;
1727 for (size_t i = 0; i < resources_to_return.size(); ++i)
1728 output_surface()->ReturnResource(resources_to_return[i].id, &ack);
1729 host_impl->ReclaimResources(&ack);
1730 host_impl->OnSwapBuffersComplete();
1731 }
1732
[email protected]4bad8b62013-10-24 01:27:291733 virtual void AfterTest() OVERRIDE {}
1734
1735 private:
[email protected]4bad8b62013-10-24 01:27:291736 scoped_refptr<TextureLayer> texture_layer_;
[email protected]4bad8b62013-10-24 01:27:291737};
1738
[email protected]cce34bd2013-12-02 23:24:451739SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerNoExtraCommitForMailboxTest);
[email protected]4bad8b62013-10-24 01:27:291740
[email protected]b04264f92013-09-13 23:37:291741// Checks that changing a mailbox in the client for a TextureLayer that's
1742// invisible correctly works and uses the new mailbox as soon as the layer
1743// becomes visible (and returns the old one).
1744class TextureLayerChangeInvisibleMailboxTest
1745 : public LayerTreeTest,
1746 public TextureLayerClient {
1747 public:
1748 TextureLayerChangeInvisibleMailboxTest()
1749 : mailbox_changed_(true),
1750 mailbox_returned_(0),
1751 prepare_called_(0),
1752 commit_count_(0) {
1753 mailbox_ = MakeMailbox('1');
1754 }
1755
1756 // TextureLayerClient implementation.
1757 virtual unsigned PrepareTexture() OVERRIDE {
1758 NOTREACHED();
1759 return 0;
1760 }
1761
[email protected]b04264f92013-09-13 23:37:291762 virtual bool PrepareTextureMailbox(
[email protected]e51444a2013-12-10 23:05:011763 TextureMailbox* mailbox,
[email protected]9260757f2013-09-17 01:24:161764 scoped_ptr<SingleReleaseCallback>* release_callback,
1765 bool use_shared_memory) OVERRIDE {
[email protected]b04264f92013-09-13 23:37:291766 ++prepare_called_;
1767 if (!mailbox_changed_)
1768 return false;
1769 *mailbox = mailbox_;
[email protected]9260757f2013-09-17 01:24:161770 *release_callback = SingleReleaseCallback::Create(
1771 base::Bind(&TextureLayerChangeInvisibleMailboxTest::MailboxReleased,
1772 base::Unretained(this)));
[email protected]b04264f92013-09-13 23:37:291773 return true;
1774 }
1775
1776 TextureMailbox MakeMailbox(char name) {
[email protected]e0a4d732014-02-15 00:23:261777 return TextureMailbox(MailboxFromChar(name), GL_TEXTURE_2D, 0);
[email protected]b04264f92013-09-13 23:37:291778 }
1779
[email protected]df41e252014-02-03 23:39:501780 void MailboxReleased(uint32 sync_point, bool lost_resource) {
[email protected]b04264f92013-09-13 23:37:291781 ++mailbox_returned_;
1782 }
1783
1784 virtual void SetupTree() OVERRIDE {
1785 scoped_refptr<Layer> root = Layer::Create();
1786 root->SetBounds(gfx::Size(10, 10));
1787 root->SetAnchorPoint(gfx::PointF());
1788 root->SetIsDrawable(true);
1789
1790 solid_layer_ = SolidColorLayer::Create();
1791 solid_layer_->SetBounds(gfx::Size(10, 10));
1792 solid_layer_->SetIsDrawable(true);
1793 solid_layer_->SetBackgroundColor(SK_ColorWHITE);
1794 root->AddChild(solid_layer_);
1795
1796 parent_layer_ = Layer::Create();
1797 parent_layer_->SetBounds(gfx::Size(10, 10));
1798 parent_layer_->SetIsDrawable(true);
1799 root->AddChild(parent_layer_);
1800
1801 texture_layer_ = TextureLayer::CreateForMailbox(this);
1802 texture_layer_->SetBounds(gfx::Size(10, 10));
1803 texture_layer_->SetAnchorPoint(gfx::PointF());
1804 texture_layer_->SetIsDrawable(true);
1805 parent_layer_->AddChild(texture_layer_);
1806
1807 layer_tree_host()->SetRootLayer(root);
1808 LayerTreeTest::SetupTree();
1809 }
1810
1811 virtual void BeginTest() OVERRIDE {
1812 PostSetNeedsCommitToMainThread();
1813 }
1814
1815 virtual void DidCommitAndDrawFrame() OVERRIDE {
1816 ++commit_count_;
1817 switch (commit_count_) {
1818 case 1:
1819 // We should have updated the layer, committing the texture.
1820 EXPECT_EQ(1, prepare_called_);
1821 // Make layer invisible.
1822 parent_layer_->SetOpacity(0.f);
1823 break;
1824 case 2:
1825 // Layer shouldn't have been updated.
1826 EXPECT_EQ(1, prepare_called_);
1827 // Change the texture.
1828 mailbox_ = MakeMailbox('2');
1829 mailbox_changed_ = true;
1830 texture_layer_->SetNeedsDisplay();
1831 // Force a change to make sure we draw a frame.
1832 solid_layer_->SetBackgroundColor(SK_ColorGRAY);
1833 break;
1834 case 3:
1835 // Layer shouldn't have been updated.
1836 EXPECT_EQ(1, prepare_called_);
1837 // So the old mailbox isn't returned yet.
1838 EXPECT_EQ(0, mailbox_returned_);
1839 // Make layer visible again.
1840 parent_layer_->SetOpacity(1.f);
1841 break;
1842 case 4:
1843 // Layer should have been updated.
1844 EXPECT_EQ(2, prepare_called_);
1845 // So the old mailbox should have been returned already.
1846 EXPECT_EQ(1, mailbox_returned_);
1847 texture_layer_->ClearClient();
1848 break;
1849 case 5:
1850 EXPECT_EQ(2, mailbox_returned_);
1851 EndTest();
1852 break;
1853 default:
1854 NOTREACHED();
1855 break;
1856 }
1857 }
1858
1859 virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl,
1860 bool result) OVERRIDE {
1861 ASSERT_TRUE(result);
1862 DelegatedFrameData* delegated_frame_data =
1863 output_surface()->last_sent_frame().delegated_frame_data.get();
1864 if (!delegated_frame_data)
1865 return;
1866
1867 // Return all resources immediately.
1868 TransferableResourceArray resources_to_return =
1869 output_surface()->resources_held_by_parent();
1870
1871 CompositorFrameAck ack;
1872 for (size_t i = 0; i < resources_to_return.size(); ++i)
1873 output_surface()->ReturnResource(resources_to_return[i].id, &ack);
[email protected]a7335e0b2013-09-18 09:34:511874 host_impl->ReclaimResources(&ack);
1875 host_impl->OnSwapBuffersComplete();
[email protected]b04264f92013-09-13 23:37:291876 }
1877
1878 virtual void AfterTest() OVERRIDE {}
1879
1880 private:
1881 scoped_refptr<SolidColorLayer> solid_layer_;
1882 scoped_refptr<Layer> parent_layer_;
1883 scoped_refptr<TextureLayer> texture_layer_;
1884
1885 // Used on the main thread.
1886 bool mailbox_changed_;
1887 TextureMailbox mailbox_;
1888 int mailbox_returned_;
1889 int prepare_called_;
1890 int commit_count_;
1891};
1892
1893SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerChangeInvisibleMailboxTest);
1894
[email protected]0d7fb302014-01-23 21:30:471895// Test that TextureLayerImpl::ReleaseResources can be called which releases
1896// the mailbox back to TextureLayerClient.
1897class TextureLayerReleaseResourcesBase
1898 : public LayerTreeTest,
1899 public TextureLayerClient {
1900 public:
1901 // TextureLayerClient implementation.
1902 virtual unsigned PrepareTexture() OVERRIDE {
1903 NOTREACHED();
1904 return 0;
1905 }
1906 virtual bool PrepareTextureMailbox(
1907 TextureMailbox* mailbox,
1908 scoped_ptr<SingleReleaseCallback>* release_callback,
1909 bool use_shared_memory) OVERRIDE {
[email protected]e0a4d732014-02-15 00:23:261910 *mailbox = TextureMailbox(MailboxFromChar('1'), GL_TEXTURE_2D, 0);
[email protected]0d7fb302014-01-23 21:30:471911 *release_callback = SingleReleaseCallback::Create(
1912 base::Bind(&TextureLayerReleaseResourcesBase::MailboxReleased,
1913 base::Unretained(this)));
1914 return true;
1915 }
1916
1917 void MailboxReleased(unsigned sync_point, bool lost_resource) {
1918 mailbox_released_ = true;
1919 }
1920
1921 virtual void SetupTree() OVERRIDE {
1922 LayerTreeTest::SetupTree();
1923
1924 scoped_refptr<TextureLayer> texture_layer =
1925 TextureLayer::CreateForMailbox(this);
1926 texture_layer->SetBounds(gfx::Size(10, 10));
1927 texture_layer->SetAnchorPoint(gfx::PointF());
1928 texture_layer->SetIsDrawable(true);
1929
1930 layer_tree_host()->root_layer()->AddChild(texture_layer);
1931 }
1932
1933 virtual void BeginTest() OVERRIDE {
1934 mailbox_released_ = false;
1935 PostSetNeedsCommitToMainThread();
1936 }
1937
1938 virtual void DidCommitAndDrawFrame() OVERRIDE {
1939 EndTest();
1940 }
1941
1942 virtual void AfterTest() OVERRIDE {
1943 EXPECT_TRUE(mailbox_released_);
1944 }
1945
1946 private:
1947 bool mailbox_released_;
1948};
1949
1950class TextureLayerReleaseResourcesAfterCommit
1951 : public TextureLayerReleaseResourcesBase {
1952 public:
1953 virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
1954 LayerTreeImpl* tree = NULL;
1955 if (host_impl->settings().impl_side_painting)
1956 tree = host_impl->pending_tree();
1957 else
1958 tree = host_impl->active_tree();
1959 tree->root_layer()->children()[0]->ReleaseResources();
1960 }
1961};
1962
1963SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerReleaseResourcesAfterCommit);
1964
1965class TextureLayerReleaseResourcesAfterActivate
1966 : public TextureLayerReleaseResourcesBase {
1967 public:
1968 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
1969 host_impl->active_tree()->root_layer()->children()[0]->ReleaseResources();
1970 }
1971};
1972
1973SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerReleaseResourcesAfterActivate);
1974
[email protected]0bf5a202013-07-10 14:50:541975// Test recovering from a lost context.
1976class TextureLayerLostContextTest
1977 : public LayerTreeTest,
1978 public TextureLayerClient {
1979 public:
1980 TextureLayerLostContextTest()
[email protected]f5931d42013-11-06 19:44:571981 : context_lost_(false),
[email protected]0bf5a202013-07-10 14:50:541982 draw_count_(0) {}
1983
[email protected]a6366932014-02-05 20:12:471984 virtual scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface(bool fallback)
[email protected]ebc0e1df2013-08-01 02:46:221985 OVERRIDE {
[email protected]a6366932014-02-05 20:12:471986 return FakeOutputSurface::Create3d();
[email protected]0bf5a202013-07-10 14:50:541987 }
1988
[email protected]171cbb32013-07-11 03:51:191989 virtual unsigned PrepareTexture() OVERRIDE {
[email protected]f5931d42013-11-06 19:44:571990 if (draw_count_ == 0)
1991 context_lost_ = true;
1992 if (context_lost_)
1993 return 0u;
1994 return 1u;
[email protected]0bf5a202013-07-10 14:50:541995 }
1996
1997 virtual bool PrepareTextureMailbox(
[email protected]9260757f2013-09-17 01:24:161998 TextureMailbox* mailbox,
1999 scoped_ptr<SingleReleaseCallback>* release_callback,
2000 bool use_shared_memory) OVERRIDE {
[email protected]0bf5a202013-07-10 14:50:542001 return false;
2002 }
2003
2004 virtual void SetupTree() OVERRIDE {
2005 scoped_refptr<Layer> root = Layer::Create();
2006 root->SetBounds(gfx::Size(10, 10));
2007 root->SetIsDrawable(true);
2008
2009 texture_layer_ = TextureLayer::Create(this);
2010 texture_layer_->SetBounds(gfx::Size(10, 10));
2011 texture_layer_->SetIsDrawable(true);
2012 root->AddChild(texture_layer_);
2013
2014 layer_tree_host()->SetRootLayer(root);
2015 LayerTreeTest::SetupTree();
2016 }
2017
2018 virtual void BeginTest() OVERRIDE {
2019 PostSetNeedsCommitToMainThread();
2020 }
2021
[email protected]7ddfe7e82014-01-30 07:22:112022 virtual DrawSwapReadbackResult::DrawResult PrepareToDrawOnThread(
2023 LayerTreeHostImpl* host_impl,
2024 LayerTreeHostImpl::FrameData* frame_data,
2025 DrawSwapReadbackResult::DrawResult draw_result) OVERRIDE {
[email protected]0bf5a202013-07-10 14:50:542026 LayerImpl* root = host_impl->RootLayer();
2027 TextureLayerImpl* texture_layer =
2028 static_cast<TextureLayerImpl*>(root->children()[0]);
2029 if (++draw_count_ == 1)
2030 EXPECT_EQ(0u, texture_layer->texture_id());
2031 else
[email protected]f5931d42013-11-06 19:44:572032 EXPECT_EQ(1u, texture_layer->texture_id());
[email protected]7ddfe7e82014-01-30 07:22:112033 return DrawSwapReadbackResult::DRAW_SUCCESS;
[email protected]0bf5a202013-07-10 14:50:542034 }
2035
2036 virtual void DidCommitAndDrawFrame() OVERRIDE {
2037 EndTest();
2038 }
2039
2040 virtual void AfterTest() OVERRIDE {}
2041
2042 private:
2043 scoped_refptr<TextureLayer> texture_layer_;
[email protected]f5931d42013-11-06 19:44:572044 bool context_lost_;
[email protected]0bf5a202013-07-10 14:50:542045 int draw_count_;
2046};
2047
2048SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(TextureLayerLostContextTest);
2049
[email protected]9c2bd822013-07-26 12:30:172050class TextureLayerWithMailboxMainThreadDeleted : public LayerTreeTest {
2051 public:
[email protected]df41e252014-02-03 23:39:502052 void ReleaseCallback(uint32 sync_point, bool lost_resource) {
[email protected]9794fb32013-08-29 09:49:592053 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]9c2bd822013-07-26 12:30:172054 EXPECT_FALSE(lost_resource);
2055 ++callback_count_;
2056 EndTest();
2057 }
2058
2059 void SetMailbox(char mailbox_char) {
[email protected]9794fb32013-08-29 09:49:592060 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]9260757f2013-09-17 01:24:162061 scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create(
[email protected]9c2bd822013-07-26 12:30:172062 base::Bind(
2063 &TextureLayerWithMailboxMainThreadDeleted::ReleaseCallback,
2064 base::Unretained(this)));
[email protected]df41e252014-02-03 23:39:502065 layer_->SetTextureMailbox(
[email protected]e0a4d732014-02-15 00:23:262066 TextureMailbox(MailboxFromChar(mailbox_char), GL_TEXTURE_2D, 0),
[email protected]df41e252014-02-03 23:39:502067 callback.Pass());
[email protected]9c2bd822013-07-26 12:30:172068 }
2069
2070 virtual void SetupTree() OVERRIDE {
2071 gfx::Size bounds(100, 100);
2072 root_ = Layer::Create();
2073 root_->SetAnchorPoint(gfx::PointF());
2074 root_->SetBounds(bounds);
2075
2076 layer_ = TextureLayer::CreateForMailbox(NULL);
2077 layer_->SetIsDrawable(true);
2078 layer_->SetAnchorPoint(gfx::PointF());
2079 layer_->SetBounds(bounds);
2080
2081 root_->AddChild(layer_);
2082 layer_tree_host()->SetRootLayer(root_);
2083 layer_tree_host()->SetViewportSize(bounds);
2084 }
2085
2086 virtual void BeginTest() OVERRIDE {
[email protected]9794fb32013-08-29 09:49:592087 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
2088
[email protected]9c2bd822013-07-26 12:30:172089 callback_count_ = 0;
2090
2091 // Set the mailbox on the main thread.
2092 SetMailbox('1');
2093 EXPECT_EQ(0, callback_count_);
2094
2095 PostSetNeedsCommitToMainThread();
2096 }
2097
2098 virtual void DidCommitAndDrawFrame() OVERRIDE {
2099 switch (layer_tree_host()->source_frame_number()) {
2100 case 1:
2101 // Delete the TextureLayer on the main thread while the mailbox is in
2102 // the impl tree.
2103 layer_->RemoveFromParent();
2104 layer_ = NULL;
2105 break;
2106 }
2107 }
2108
2109 virtual void AfterTest() OVERRIDE {
2110 EXPECT_EQ(1, callback_count_);
2111 }
2112
2113 private:
[email protected]9794fb32013-08-29 09:49:592114 base::ThreadChecker main_thread_;
[email protected]9c2bd822013-07-26 12:30:172115 int callback_count_;
2116 scoped_refptr<Layer> root_;
2117 scoped_refptr<TextureLayer> layer_;
2118};
2119
2120SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
2121 TextureLayerWithMailboxMainThreadDeleted);
2122
2123class TextureLayerWithMailboxImplThreadDeleted : public LayerTreeTest {
2124 public:
[email protected]df41e252014-02-03 23:39:502125 void ReleaseCallback(uint32 sync_point, bool lost_resource) {
[email protected]9794fb32013-08-29 09:49:592126 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]9c2bd822013-07-26 12:30:172127 EXPECT_FALSE(lost_resource);
2128 ++callback_count_;
2129 EndTest();
2130 }
2131
2132 void SetMailbox(char mailbox_char) {
[email protected]9794fb32013-08-29 09:49:592133 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]9260757f2013-09-17 01:24:162134 scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create(
[email protected]9c2bd822013-07-26 12:30:172135 base::Bind(
2136 &TextureLayerWithMailboxImplThreadDeleted::ReleaseCallback,
2137 base::Unretained(this)));
[email protected]df41e252014-02-03 23:39:502138 layer_->SetTextureMailbox(
[email protected]e0a4d732014-02-15 00:23:262139 TextureMailbox(MailboxFromChar(mailbox_char), GL_TEXTURE_2D, 0),
[email protected]df41e252014-02-03 23:39:502140 callback.Pass());
[email protected]9c2bd822013-07-26 12:30:172141 }
2142
2143 virtual void SetupTree() OVERRIDE {
2144 gfx::Size bounds(100, 100);
2145 root_ = Layer::Create();
2146 root_->SetAnchorPoint(gfx::PointF());
2147 root_->SetBounds(bounds);
2148
2149 layer_ = TextureLayer::CreateForMailbox(NULL);
2150 layer_->SetIsDrawable(true);
2151 layer_->SetAnchorPoint(gfx::PointF());
2152 layer_->SetBounds(bounds);
2153
2154 root_->AddChild(layer_);
2155 layer_tree_host()->SetRootLayer(root_);
2156 layer_tree_host()->SetViewportSize(bounds);
2157 }
2158
2159 virtual void BeginTest() OVERRIDE {
[email protected]9794fb32013-08-29 09:49:592160 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
2161
[email protected]9c2bd822013-07-26 12:30:172162 callback_count_ = 0;
2163
2164 // Set the mailbox on the main thread.
2165 SetMailbox('1');
2166 EXPECT_EQ(0, callback_count_);
2167
2168 PostSetNeedsCommitToMainThread();
2169 }
2170
2171 virtual void DidCommitAndDrawFrame() OVERRIDE {
2172 switch (layer_tree_host()->source_frame_number()) {
2173 case 1:
2174 // Remove the TextureLayer on the main thread while the mailbox is in
2175 // the impl tree, but don't delete the TextureLayer until after the impl
2176 // tree side is deleted.
2177 layer_->RemoveFromParent();
2178 break;
2179 case 2:
2180 layer_ = NULL;
2181 break;
2182 }
2183 }
2184
2185 virtual void AfterTest() OVERRIDE {
2186 EXPECT_EQ(1, callback_count_);
2187 }
2188
2189 private:
[email protected]9794fb32013-08-29 09:49:592190 base::ThreadChecker main_thread_;
[email protected]9c2bd822013-07-26 12:30:172191 int callback_count_;
2192 scoped_refptr<Layer> root_;
2193 scoped_refptr<TextureLayer> layer_;
2194};
2195
2196SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
2197 TextureLayerWithMailboxImplThreadDeleted);
2198
[email protected]ba565742012-11-10 09:29:482199} // namespace
2200} // namespace cc