blob: 2be752746e92c6518d351aaded6e0d9d1e006c0a [file] [log] [blame]
[email protected]c0dd24c2012-08-30 23:25:271// Copyright 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]cc3cfaa2013-03-18 09:05:525#include "cc/layers/texture_layer.h"
[email protected]c0dd24c2012-08-30 23:25:276
[email protected]b04264f92013-09-13 23:37:297#include <algorithm>
[email protected]de44a152013-01-08 15:28:468#include <string>
9
[email protected]b04264f92013-09-13 23:37:2910#include "base/bind.h"
[email protected]de44a152013-01-08 15:28:4611#include "base/callback.h"
[email protected]9794fb32013-08-29 09:49:5912#include "base/synchronization/waitable_event.h"
[email protected]74b43cc2013-08-30 06:29:2713#include "base/threading/thread.h"
14#include "base/time/time.h"
[email protected]b04264f92013-09-13 23:37:2915#include "cc/layers/solid_color_layer.h"
[email protected]97d519fb2013-03-29 02:27:5416#include "cc/layers/texture_layer_client.h"
[email protected]cc3cfaa2013-03-18 09:05:5217#include "cc/layers/texture_layer_impl.h"
[email protected]b04264f92013-09-13 23:37:2918#include "cc/output/compositor_frame_ack.h"
19#include "cc/output/context_provider.h"
[email protected]e00bab022013-08-19 00:42:4520#include "cc/resources/returned_resource.h"
[email protected]586d51ed2012-12-07 20:31:4521#include "cc/test/fake_impl_proxy.h"
[email protected]101441ce2012-10-16 01:45:0322#include "cc/test/fake_layer_tree_host_client.h"
[email protected]586d51ed2012-12-07 20:31:4523#include "cc/test/fake_layer_tree_host_impl.h"
[email protected]199b715e2013-08-13 05:18:3424#include "cc/test/fake_output_surface.h"
[email protected]06d68d02013-04-19 18:46:2125#include "cc/test/layer_test_common.h"
[email protected]e216fef02013-03-20 22:56:1026#include "cc/test/layer_tree_test.h"
[email protected]c2610b9f2013-10-31 06:54:5927#include "cc/test/test_web_graphics_context_3d.h"
[email protected]9794fb32013-08-29 09:49:5928#include "cc/trees/blocking_task_runner.h"
[email protected]556fd292013-03-18 08:03:0429#include "cc/trees/layer_tree_host.h"
30#include "cc/trees/layer_tree_impl.h"
31#include "cc/trees/single_thread_proxy.h"
[email protected]0bf5a202013-07-10 14:50:5432#include "gpu/GLES2/gl2extchromium.h"
[email protected]7f0c53db2012-10-02 00:23:1833#include "testing/gmock/include/gmock/gmock.h"
34#include "testing/gtest/include/gtest/gtest.h"
[email protected]c0dd24c2012-08-30 23:25:2735
[email protected]c0dd24c2012-08-30 23:25:2736using ::testing::Mock;
37using ::testing::_;
38using ::testing::AtLeast;
39using ::testing::AnyNumber;
[email protected]d72d9e02014-04-03 18:40:0940using ::testing::InvokeWithoutArgs;
[email protected]c0dd24c2012-08-30 23:25:2741
[email protected]ba565742012-11-10 09:29:4842namespace cc {
[email protected]c0dd24c2012-08-30 23:25:2743namespace {
44
[email protected]e0a4d732014-02-15 00:23:2645gpu::Mailbox MailboxFromChar(char value) {
[email protected]df41e252014-02-03 23:39:5046 gpu::Mailbox mailbox;
[email protected]e0a4d732014-02-15 00:23:2647 memset(mailbox.name, value, sizeof(mailbox.name));
[email protected]df41e252014-02-03 23:39:5048 return mailbox;
49}
50
[email protected]408b5e22013-03-19 09:48:0951class MockLayerTreeHost : public LayerTreeHost {
[email protected]28571b042013-03-14 07:59:1552 public:
[email protected]943528e2013-11-07 05:01:3253 explicit MockLayerTreeHost(FakeLayerTreeHostClient* client)
[email protected]a7f35682013-10-22 23:05:5754 : LayerTreeHost(client, NULL, LayerTreeSettings()) {
[email protected]943528e2013-11-07 05:01:3255 InitializeSingleThreaded(client);
[email protected]28571b042013-03-14 07:59:1556 }
[email protected]c0dd24c2012-08-30 23:25:2757
[email protected]28571b042013-03-14 07:59:1558 MOCK_METHOD0(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]d72d9e02014-04-03 18:40:0964class FakeTextureLayerClient : public TextureLayerClient {
65 public:
[email protected]17e08432014-04-10 00:41:1166 FakeTextureLayerClient() : mailbox_changed_(true) {}
[email protected]d72d9e02014-04-03 18:40:0967
68 virtual bool PrepareTextureMailbox(
69 TextureMailbox* mailbox,
70 scoped_ptr<SingleReleaseCallback>* release_callback,
71 bool use_shared_memory) OVERRIDE {
72 if (!mailbox_changed_)
73 return false;
74
75 *mailbox = mailbox_;
76 *release_callback = release_callback_.Pass();
77 mailbox_changed_ = false;
78 return true;
79 }
80
[email protected]d72d9e02014-04-03 18:40:0981 void set_mailbox(const TextureMailbox& mailbox,
82 scoped_ptr<SingleReleaseCallback> release_callback) {
83 mailbox_ = mailbox;
84 release_callback_ = release_callback.Pass();
85 mailbox_changed_ = true;
86 }
87
88 private:
[email protected]d72d9e02014-04-03 18:40:0989 TextureMailbox mailbox_;
90 scoped_ptr<SingleReleaseCallback> release_callback_;
91 bool mailbox_changed_;
92 DISALLOW_COPY_AND_ASSIGN(FakeTextureLayerClient);
93};
94
95class MockMailboxCallback {
96 public:
97 MOCK_METHOD3(Release,
98 void(const gpu::Mailbox& mailbox,
99 uint32 sync_point,
100 bool lost_resource));
101 MOCK_METHOD3(Release2,
102 void(base::SharedMemory* shared_memory,
103 uint32 sync_point,
104 bool lost_resource));
105};
106
107struct CommonMailboxObjects {
108 CommonMailboxObjects()
109 : mailbox_name1_(MailboxFromChar('1')),
110 mailbox_name2_(MailboxFromChar('2')),
111 sync_point1_(1),
112 sync_point2_(2),
113 shared_memory_(new base::SharedMemory) {
114 release_mailbox1_ = base::Bind(&MockMailboxCallback::Release,
115 base::Unretained(&mock_callback_),
116 mailbox_name1_);
117 release_mailbox2_ = base::Bind(&MockMailboxCallback::Release,
118 base::Unretained(&mock_callback_),
119 mailbox_name2_);
120 const uint32 arbitrary_target1 = GL_TEXTURE_2D;
121 const uint32 arbitrary_target2 = GL_TEXTURE_EXTERNAL_OES;
122 mailbox1_ = TextureMailbox(mailbox_name1_, arbitrary_target1, sync_point1_);
123 mailbox2_ = TextureMailbox(mailbox_name2_, arbitrary_target2, sync_point2_);
124 gfx::Size size(128, 128);
125 EXPECT_TRUE(shared_memory_->CreateAndMapAnonymous(4 * size.GetArea()));
126 release_mailbox3_ = base::Bind(&MockMailboxCallback::Release2,
127 base::Unretained(&mock_callback_),
128 shared_memory_.get());
129 mailbox3_ = TextureMailbox(shared_memory_.get(), size);
130 }
131
132 gpu::Mailbox mailbox_name1_;
133 gpu::Mailbox mailbox_name2_;
134 MockMailboxCallback mock_callback_;
135 ReleaseCallback release_mailbox1_;
136 ReleaseCallback release_mailbox2_;
137 ReleaseCallback release_mailbox3_;
138 TextureMailbox mailbox1_;
139 TextureMailbox mailbox2_;
140 TextureMailbox mailbox3_;
141 uint32 sync_point1_;
142 uint32 sync_point2_;
143 scoped_ptr<base::SharedMemory> shared_memory_;
144};
145
[email protected]31d4df82013-07-18 10:17:22146class TextureLayerTest : public testing::Test {
147 public:
148 TextureLayerTest()
149 : fake_client_(
[email protected]4e2eb352014-03-20 17:25:45150 FakeLayerTreeHostClient(FakeLayerTreeHostClient::DIRECT_3D)),
151 host_impl_(&proxy_, &shared_bitmap_manager_) {}
[email protected]31d4df82013-07-18 10:17:22152
153 protected:
154 virtual void SetUp() {
155 layer_tree_host_.reset(new MockLayerTreeHost(&fake_client_));
[email protected]d72d9e02014-04-03 18:40:09156 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
157 layer_tree_host_->SetViewportSize(gfx::Size(10, 10));
158 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
[email protected]31d4df82013-07-18 10:17:22159 }
160
161 virtual void TearDown() {
162 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
[email protected]31d4df82013-07-18 10:17:22163 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
164
165 layer_tree_host_->SetRootLayer(NULL);
166 layer_tree_host_.reset();
167 }
168
169 scoped_ptr<MockLayerTreeHost> layer_tree_host_;
170 FakeImplProxy proxy_;
171 FakeLayerTreeHostClient fake_client_;
[email protected]4e2eb352014-03-20 17:25:45172 TestSharedBitmapManager shared_bitmap_manager_;
[email protected]31d4df82013-07-18 10:17:22173 FakeLayerTreeHostImpl host_impl_;
174};
175
[email protected]31d4df82013-07-18 10:17:22176TEST_F(TextureLayerTest, CheckPropertyChangeCausesCorrectBehavior) {
[email protected]17e08432014-04-10 00:41:11177 scoped_refptr<TextureLayer> test_layer = TextureLayer::CreateForMailbox(NULL);
[email protected]80d42bd2013-08-30 19:13:45178 EXPECT_SET_NEEDS_COMMIT(1, layer_tree_host_->SetRootLayer(test_layer));
[email protected]31d4df82013-07-18 10:17:22179
180 // Test properties that should call SetNeedsCommit. All properties need to
181 // be set to new values in order for SetNeedsCommit to be called.
182 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetFlipped(false));
183 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetUV(
184 gfx::PointF(0.25f, 0.25f), gfx::PointF(0.75f, 0.75f)));
185 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetVertexOpacity(
186 0.5f, 0.5f, 0.5f, 0.5f));
187 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetPremultipliedAlpha(false));
188 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetBlendBackgroundColor(true));
[email protected]31d4df82013-07-18 10:17:22189}
190
[email protected]1c10e232013-07-31 12:35:43191TEST_F(TextureLayerTest, VisibleContentOpaqueRegion) {
192 const gfx::Size layer_bounds(100, 100);
193 const gfx::Rect layer_rect(layer_bounds);
194 const Region layer_region(layer_rect);
195
[email protected]17e08432014-04-10 00:41:11196 scoped_refptr<TextureLayer> layer = TextureLayer::CreateForMailbox(NULL);
[email protected]1c10e232013-07-31 12:35:43197 layer->SetBounds(layer_bounds);
198 layer->draw_properties().visible_content_rect = layer_rect;
199 layer->SetBlendBackgroundColor(true);
200
201 // Verify initial conditions.
202 EXPECT_FALSE(layer->contents_opaque());
203 EXPECT_EQ(0u, layer->background_color());
204 EXPECT_EQ(Region().ToString(),
205 layer->VisibleContentOpaqueRegion().ToString());
206
207 // Opaque background.
208 layer->SetBackgroundColor(SK_ColorWHITE);
209 EXPECT_EQ(layer_region.ToString(),
210 layer->VisibleContentOpaqueRegion().ToString());
211
212 // Transparent background.
213 layer->SetBackgroundColor(SkColorSetARGB(100, 255, 255, 255));
214 EXPECT_EQ(Region().ToString(),
215 layer->VisibleContentOpaqueRegion().ToString());
216}
217
[email protected]31d4df82013-07-18 10:17:22218TEST_F(TextureLayerTest, RateLimiter) {
219 FakeTextureLayerClient client;
220 scoped_refptr<TextureLayer> test_layer = TextureLayer::CreateForMailbox(
221 &client);
222 test_layer->SetIsDrawable(true);
223 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
224 layer_tree_host_->SetRootLayer(test_layer);
225
226 // Don't rate limit until we invalidate.
[email protected]aeeb3372013-11-05 14:05:54227 EXPECT_CALL(*layer_tree_host_, StartRateLimiter()).Times(0);
[email protected]31d4df82013-07-18 10:17:22228 test_layer->SetRateLimitContext(true);
229 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
230
231 // Do rate limit after we invalidate.
[email protected]aeeb3372013-11-05 14:05:54232 EXPECT_CALL(*layer_tree_host_, StartRateLimiter());
[email protected]31d4df82013-07-18 10:17:22233 test_layer->SetNeedsDisplay();
234 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
235
236 // Stop rate limiter when we don't want it any more.
[email protected]aeeb3372013-11-05 14:05:54237 EXPECT_CALL(*layer_tree_host_, StopRateLimiter());
[email protected]31d4df82013-07-18 10:17:22238 test_layer->SetRateLimitContext(false);
239 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
240
241 // Or we clear the client.
242 test_layer->SetRateLimitContext(true);
[email protected]aeeb3372013-11-05 14:05:54243 EXPECT_CALL(*layer_tree_host_, StopRateLimiter());
[email protected]31d4df82013-07-18 10:17:22244 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
245 test_layer->ClearClient();
246 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
247
248 // Reset to a layer with a client, that started the rate limiter.
249 test_layer = TextureLayer::CreateForMailbox(
250 &client);
251 test_layer->SetIsDrawable(true);
252 test_layer->SetRateLimitContext(true);
253 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
254 layer_tree_host_->SetRootLayer(test_layer);
[email protected]aeeb3372013-11-05 14:05:54255 EXPECT_CALL(*layer_tree_host_, StartRateLimiter()).Times(0);
[email protected]31d4df82013-07-18 10:17:22256 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
[email protected]aeeb3372013-11-05 14:05:54257 EXPECT_CALL(*layer_tree_host_, StartRateLimiter());
[email protected]31d4df82013-07-18 10:17:22258 test_layer->SetNeedsDisplay();
259 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
260
261 // Stop rate limiter when we're removed from the tree.
[email protected]aeeb3372013-11-05 14:05:54262 EXPECT_CALL(*layer_tree_host_, StopRateLimiter());
[email protected]d72d9e02014-04-03 18:40:09263 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1);
[email protected]31d4df82013-07-18 10:17:22264 layer_tree_host_->SetRootLayer(NULL);
265 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
266}
267
[email protected]df41e252014-02-03 23:39:50268class TestMailboxHolder : public TextureLayer::TextureMailboxHolder {
[email protected]9794fb32013-08-29 09:49:59269 public:
[email protected]df41e252014-02-03 23:39:50270 using TextureLayer::TextureMailboxHolder::Create;
[email protected]9794fb32013-08-29 09:49:59271
272 protected:
273 virtual ~TestMailboxHolder() {}
274};
275
[email protected]de44a152013-01-08 15:28:46276class TextureLayerWithMailboxTest : public TextureLayerTest {
[email protected]28571b042013-03-14 07:59:15277 protected:
278 virtual void TearDown() {
279 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
280 EXPECT_CALL(test_data_.mock_callback_,
281 Release(test_data_.mailbox_name1_,
[email protected]7ba3ca72013-04-11 06:37:25282 test_data_.sync_point1_,
283 false)).Times(1);
[email protected]28571b042013-03-14 07:59:15284 TextureLayerTest::TearDown();
285 }
[email protected]de44a152013-01-08 15:28:46286
[email protected]28571b042013-03-14 07:59:15287 CommonMailboxObjects test_data_;
[email protected]de44a152013-01-08 15:28:46288};
289
[email protected]28571b042013-03-14 07:59:15290TEST_F(TextureLayerWithMailboxTest, ReplaceMailboxOnMainThreadBeforeCommit) {
[email protected]e8e4ae232013-04-12 00:26:01291 scoped_refptr<TextureLayer> test_layer = TextureLayer::CreateForMailbox(NULL);
[email protected]22898ed2013-06-01 04:52:30292 ASSERT_TRUE(test_layer.get());
[email protected]de44a152013-01-08 15:28:46293
[email protected]28571b042013-03-14 07:59:15294 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
295 layer_tree_host_->SetRootLayer(test_layer);
296 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
[email protected]de44a152013-01-08 15:28:46297
[email protected]28571b042013-03-14 07:59:15298 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
[email protected]9260757f2013-09-17 01:24:16299 test_layer->SetTextureMailbox(
300 test_data_.mailbox1_,
301 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
[email protected]28571b042013-03-14 07:59:15302 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
[email protected]de44a152013-01-08 15:28:46303
[email protected]28571b042013-03-14 07:59:15304 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
305 EXPECT_CALL(test_data_.mock_callback_,
[email protected]7ba3ca72013-04-11 06:37:25306 Release(test_data_.mailbox_name1_,
307 test_data_.sync_point1_,
308 false))
[email protected]28571b042013-03-14 07:59:15309 .Times(1);
[email protected]9260757f2013-09-17 01:24:16310 test_layer->SetTextureMailbox(
311 test_data_.mailbox2_,
312 SingleReleaseCallback::Create(test_data_.release_mailbox2_));
[email protected]28571b042013-03-14 07:59:15313 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
314 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]de44a152013-01-08 15:28:46315
[email protected]28571b042013-03-14 07:59:15316 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
317 EXPECT_CALL(test_data_.mock_callback_,
[email protected]7ba3ca72013-04-11 06:37:25318 Release(test_data_.mailbox_name2_,
319 test_data_.sync_point2_,
320 false))
[email protected]28571b042013-03-14 07:59:15321 .Times(1);
[email protected]9260757f2013-09-17 01:24:16322 test_layer->SetTextureMailbox(TextureMailbox(),
323 scoped_ptr<SingleReleaseCallback>());
[email protected]28571b042013-03-14 07:59:15324 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
325 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]de44a152013-01-08 15:28:46326
[email protected]80d42bd2013-08-30 19:13:45327 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
[email protected]9260757f2013-09-17 01:24:16328 test_layer->SetTextureMailbox(
329 test_data_.mailbox3_,
330 SingleReleaseCallback::Create(test_data_.release_mailbox3_));
[email protected]42f40a52013-06-08 04:38:51331 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
332 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
333
[email protected]42f40a52013-06-08 04:38:51334 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
335 EXPECT_CALL(test_data_.mock_callback_,
336 Release2(test_data_.shared_memory_.get(),
337 0, false))
338 .Times(1);
[email protected]9260757f2013-09-17 01:24:16339 test_layer->SetTextureMailbox(TextureMailbox(),
340 scoped_ptr<SingleReleaseCallback>());
[email protected]42f40a52013-06-08 04:38:51341 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
342 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
343
[email protected]28571b042013-03-14 07:59:15344 // Test destructor.
345 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
[email protected]9260757f2013-09-17 01:24:16346 test_layer->SetTextureMailbox(
347 test_data_.mailbox1_,
348 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
[email protected]de44a152013-01-08 15:28:46349}
350
[email protected]f9e8f452014-03-07 22:09:40351TEST_F(TextureLayerTest, SetTextureMailboxWithoutReleaseCallback) {
352 scoped_refptr<TextureLayer> test_layer = TextureLayer::CreateForMailbox(NULL);
353 ASSERT_TRUE(test_layer.get());
354
355 // These use the same gpu::Mailbox, but different sync points.
356 TextureMailbox mailbox1(MailboxFromChar('a'), GL_TEXTURE_2D, 1);
357 TextureMailbox mailbox2(MailboxFromChar('a'), GL_TEXTURE_2D, 2);
358
[email protected]f9e8f452014-03-07 22:09:40359 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
360 layer_tree_host_->SetRootLayer(test_layer);
361 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
362
363 // Set the mailbox the first time. It should cause a commit.
[email protected]f9e8f452014-03-07 22:09:40364 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
365 test_layer->SetTextureMailboxWithoutReleaseCallback(mailbox1);
366 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
367
368 // Set the mailbox again with a new sync point, as the backing texture has
369 // been updated. It should cause a new commit.
[email protected]f9e8f452014-03-07 22:09:40370 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
371 test_layer->SetTextureMailboxWithoutReleaseCallback(mailbox2);
372 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
373}
374
[email protected]9794fb32013-08-29 09:49:59375class TextureLayerMailboxHolderTest : public TextureLayerTest {
376 public:
377 TextureLayerMailboxHolderTest()
378 : main_thread_("MAIN") {
379 main_thread_.Start();
380 }
381
382 void Wait(const base::Thread& thread) {
383 bool manual_reset = false;
384 bool initially_signaled = false;
385 base::WaitableEvent event(manual_reset, initially_signaled);
386 thread.message_loop()->PostTask(
387 FROM_HERE,
388 base::Bind(&base::WaitableEvent::Signal, base::Unretained(&event)));
389 event.Wait();
390 }
391
392 void CreateMainRef() {
393 main_ref_ = TestMailboxHolder::Create(
[email protected]9260757f2013-09-17 01:24:16394 test_data_.mailbox1_,
395 SingleReleaseCallback::Create(test_data_.release_mailbox1_)).Pass();
[email protected]9794fb32013-08-29 09:49:59396 }
397
398 void ReleaseMainRef() {
399 main_ref_.reset();
400 }
401
[email protected]9260757f2013-09-17 01:24:16402 void CreateImplRef(scoped_ptr<SingleReleaseCallback>* impl_ref) {
[email protected]9794fb32013-08-29 09:49:59403 *impl_ref = main_ref_->holder()->GetCallbackForImplThread();
404 }
405
406 void CapturePostTasksAndWait(base::WaitableEvent* begin_capture,
407 base::WaitableEvent* wait_for_capture,
408 base::WaitableEvent* stop_capture) {
409 begin_capture->Wait();
410 BlockingTaskRunner::CapturePostTasks capture;
411 wait_for_capture->Signal();
412 stop_capture->Wait();
413 }
414
415 protected:
416 scoped_ptr<TestMailboxHolder::MainThreadReference>
417 main_ref_;
418 base::Thread main_thread_;
419 CommonMailboxObjects test_data_;
420};
421
422TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_BothReleaseThenMain) {
423 scoped_refptr<TextureLayer> test_layer = TextureLayer::CreateForMailbox(NULL);
424 ASSERT_TRUE(test_layer.get());
425
426 main_thread_.message_loop()->PostTask(
427 FROM_HERE,
428 base::Bind(&TextureLayerMailboxHolderTest::CreateMainRef,
429 base::Unretained(this)));
430
431 Wait(main_thread_);
432
433 // The texture layer is attached to compositor1, and passes a reference to its
434 // impl tree.
[email protected]9260757f2013-09-17 01:24:16435 scoped_ptr<SingleReleaseCallback> compositor1;
[email protected]9794fb32013-08-29 09:49:59436 main_thread_.message_loop()->PostTask(
437 FROM_HERE,
438 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
439 base::Unretained(this),
440 &compositor1));
441
442 // Then the texture layer is removed and attached to compositor2, and passes a
443 // reference to its impl tree.
[email protected]9260757f2013-09-17 01:24:16444 scoped_ptr<SingleReleaseCallback> compositor2;
[email protected]9794fb32013-08-29 09:49:59445 main_thread_.message_loop()->PostTask(
446 FROM_HERE,
447 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
448 base::Unretained(this),
449 &compositor2));
450
451 Wait(main_thread_);
452 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
453
454 // The compositors both destroy their impl trees before the main thread layer
455 // is destroyed.
[email protected]9260757f2013-09-17 01:24:16456 compositor1->Run(100, false);
457 compositor2->Run(200, false);
[email protected]9794fb32013-08-29 09:49:59458
459 Wait(main_thread_);
460
461 EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0);
462 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
463
464 // The main thread ref is the last one, so the mailbox is released back to the
465 // embedder, with the last sync point provided by the impl trees.
466 EXPECT_CALL(test_data_.mock_callback_,
467 Release(test_data_.mailbox_name1_, 200, false)).Times(1);
468
469 main_thread_.message_loop()->PostTask(
470 FROM_HERE,
471 base::Bind(&TextureLayerMailboxHolderTest::ReleaseMainRef,
472 base::Unretained(this)));
473 Wait(main_thread_);
474 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
475}
476
477TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_MainReleaseBetween) {
478 scoped_refptr<TextureLayer> test_layer = TextureLayer::CreateForMailbox(NULL);
479 ASSERT_TRUE(test_layer.get());
480
481 main_thread_.message_loop()->PostTask(
482 FROM_HERE,
483 base::Bind(&TextureLayerMailboxHolderTest::CreateMainRef,
484 base::Unretained(this)));
485
486 Wait(main_thread_);
487
488 // The texture layer is attached to compositor1, and passes a reference to its
489 // impl tree.
[email protected]9260757f2013-09-17 01:24:16490 scoped_ptr<SingleReleaseCallback> compositor1;
[email protected]9794fb32013-08-29 09:49:59491 main_thread_.message_loop()->PostTask(
492 FROM_HERE,
493 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
494 base::Unretained(this),
495 &compositor1));
496
497 // Then the texture layer is removed and attached to compositor2, and passes a
498 // reference to its impl tree.
[email protected]9260757f2013-09-17 01:24:16499 scoped_ptr<SingleReleaseCallback> compositor2;
[email protected]9794fb32013-08-29 09:49:59500 main_thread_.message_loop()->PostTask(
501 FROM_HERE,
502 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
503 base::Unretained(this),
504 &compositor2));
505
506 Wait(main_thread_);
507 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
508
509 // One compositor destroys their impl tree.
[email protected]9260757f2013-09-17 01:24:16510 compositor1->Run(100, false);
[email protected]9794fb32013-08-29 09:49:59511
512 // Then the main thread reference is destroyed.
513 main_thread_.message_loop()->PostTask(
514 FROM_HERE,
515 base::Bind(&TextureLayerMailboxHolderTest::ReleaseMainRef,
516 base::Unretained(this)));
517
518 Wait(main_thread_);
519
520 EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0);
521 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
522
523 // The second impl reference is destroyed last, causing the mailbox to be
524 // released back to the embedder with the last sync point from the impl tree.
525 EXPECT_CALL(test_data_.mock_callback_,
526 Release(test_data_.mailbox_name1_, 200, true)).Times(1);
527
[email protected]9260757f2013-09-17 01:24:16528 compositor2->Run(200, true);
[email protected]9794fb32013-08-29 09:49:59529 Wait(main_thread_);
530 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
531}
532
533TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_MainReleasedFirst) {
534 scoped_refptr<TextureLayer> test_layer = TextureLayer::CreateForMailbox(NULL);
535 ASSERT_TRUE(test_layer.get());
536
537 main_thread_.message_loop()->PostTask(
538 FROM_HERE,
539 base::Bind(&TextureLayerMailboxHolderTest::CreateMainRef,
540 base::Unretained(this)));
541
542 Wait(main_thread_);
543
544 // The texture layer is attached to compositor1, and passes a reference to its
545 // impl tree.
[email protected]9260757f2013-09-17 01:24:16546 scoped_ptr<SingleReleaseCallback> compositor1;
[email protected]9794fb32013-08-29 09:49:59547 main_thread_.message_loop()->PostTask(
548 FROM_HERE,
549 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
550 base::Unretained(this),
551 &compositor1));
552
553 // Then the texture layer is removed and attached to compositor2, and passes a
554 // reference to its impl tree.
[email protected]9260757f2013-09-17 01:24:16555 scoped_ptr<SingleReleaseCallback> compositor2;
[email protected]9794fb32013-08-29 09:49:59556 main_thread_.message_loop()->PostTask(
557 FROM_HERE,
558 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
559 base::Unretained(this),
560 &compositor2));
561
562 Wait(main_thread_);
563 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
564
565 // The main thread reference is destroyed first.
566 main_thread_.message_loop()->PostTask(
567 FROM_HERE,
568 base::Bind(&TextureLayerMailboxHolderTest::ReleaseMainRef,
569 base::Unretained(this)));
570
571 // One compositor destroys their impl tree.
[email protected]9260757f2013-09-17 01:24:16572 compositor2->Run(200, false);
[email protected]9794fb32013-08-29 09:49:59573
574 Wait(main_thread_);
575
576 EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0);
577 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
578
579 // The second impl reference is destroyed last, causing the mailbox to be
580 // released back to the embedder with the last sync point from the impl tree.
581 EXPECT_CALL(test_data_.mock_callback_,
582 Release(test_data_.mailbox_name1_, 100, true)).Times(1);
583
[email protected]9260757f2013-09-17 01:24:16584 compositor1->Run(100, true);
[email protected]9794fb32013-08-29 09:49:59585 Wait(main_thread_);
586 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
587}
588
589TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_SecondImplRefShortcut) {
590 scoped_refptr<TextureLayer> test_layer = TextureLayer::CreateForMailbox(NULL);
591 ASSERT_TRUE(test_layer.get());
592
593 main_thread_.message_loop()->PostTask(
594 FROM_HERE,
595 base::Bind(&TextureLayerMailboxHolderTest::CreateMainRef,
596 base::Unretained(this)));
597
598 Wait(main_thread_);
599
600 // The texture layer is attached to compositor1, and passes a reference to its
601 // impl tree.
[email protected]9260757f2013-09-17 01:24:16602 scoped_ptr<SingleReleaseCallback> compositor1;
[email protected]9794fb32013-08-29 09:49:59603 main_thread_.message_loop()->PostTask(
604 FROM_HERE,
605 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
606 base::Unretained(this),
607 &compositor1));
608
609 // Then the texture layer is removed and attached to compositor2, and passes a
610 // reference to its impl tree.
[email protected]9260757f2013-09-17 01:24:16611 scoped_ptr<SingleReleaseCallback> compositor2;
[email protected]9794fb32013-08-29 09:49:59612 main_thread_.message_loop()->PostTask(
613 FROM_HERE,
614 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
615 base::Unretained(this),
616 &compositor2));
617
618 Wait(main_thread_);
619 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
620
621 // The main thread reference is destroyed first.
622 main_thread_.message_loop()->PostTask(
623 FROM_HERE,
624 base::Bind(&TextureLayerMailboxHolderTest::ReleaseMainRef,
625 base::Unretained(this)));
626
627 EXPECT_CALL(test_data_.mock_callback_,
628 Release(test_data_.mailbox_name1_, 200, true)).Times(1);
629
630 bool manual_reset = false;
631 bool initially_signaled = false;
632 base::WaitableEvent begin_capture(manual_reset, initially_signaled);
633 base::WaitableEvent wait_for_capture(manual_reset, initially_signaled);
634 base::WaitableEvent stop_capture(manual_reset, initially_signaled);
635
636 // Post a task to start capturing tasks on the main thread. This will block
637 // the main thread until we signal the |stop_capture| event.
638 main_thread_.message_loop()->PostTask(
639 FROM_HERE,
640 base::Bind(&TextureLayerMailboxHolderTest::CapturePostTasksAndWait,
641 base::Unretained(this),
642 &begin_capture,
643 &wait_for_capture,
644 &stop_capture));
645
646 // Before the main thread capturing starts, one compositor destroys their
647 // impl reference. Since capturing did not start, this gets post-tasked to
648 // the main thread.
[email protected]9260757f2013-09-17 01:24:16649 compositor1->Run(100, false);
[email protected]9794fb32013-08-29 09:49:59650
651 // Start capturing on the main thread.
652 begin_capture.Signal();
653 wait_for_capture.Wait();
654
655 // Meanwhile, the second compositor released its impl reference, but this task
656 // gets shortcutted directly to the main thread. This means the reference is
657 // released before compositor1, whose reference will be released later when
658 // the post-task is serviced. But since it was destroyed _on the impl thread_
659 // last, its sync point values should be used.
[email protected]9260757f2013-09-17 01:24:16660 compositor2->Run(200, true);
[email protected]9794fb32013-08-29 09:49:59661
662 stop_capture.Signal();
663 Wait(main_thread_);
664
665 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
666}
667
[email protected]e216fef02013-03-20 22:56:10668class TextureLayerImplWithMailboxThreadedCallback : public LayerTreeTest {
[email protected]28571b042013-03-14 07:59:15669 public:
670 TextureLayerImplWithMailboxThreadedCallback()
671 : callback_count_(0),
672 commit_count_(0) {}
673
674 // Make sure callback is received on main and doesn't block the impl thread.
[email protected]df41e252014-02-03 23:39:50675 void ReleaseCallback(uint32 sync_point, bool lost_resource) {
[email protected]9794fb32013-08-29 09:49:59676 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]7ba3ca72013-04-11 06:37:25677 EXPECT_FALSE(lost_resource);
[email protected]28571b042013-03-14 07:59:15678 ++callback_count_;
679 }
680
681 void SetMailbox(char mailbox_char) {
[email protected]9794fb32013-08-29 09:49:59682 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]9260757f2013-09-17 01:24:16683 scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create(
[email protected]28571b042013-03-14 07:59:15684 base::Bind(
685 &TextureLayerImplWithMailboxThreadedCallback::ReleaseCallback,
686 base::Unretained(this)));
[email protected]df41e252014-02-03 23:39:50687 layer_->SetTextureMailbox(
[email protected]e0a4d732014-02-15 00:23:26688 TextureMailbox(MailboxFromChar(mailbox_char), GL_TEXTURE_2D, 0),
[email protected]df41e252014-02-03 23:39:50689 callback.Pass());
[email protected]28571b042013-03-14 07:59:15690 }
691
[email protected]e216fef02013-03-20 22:56:10692 virtual void BeginTest() OVERRIDE {
[email protected]9794fb32013-08-29 09:49:59693 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
694
[email protected]28571b042013-03-14 07:59:15695 gfx::Size bounds(100, 100);
696 root_ = Layer::Create();
[email protected]28571b042013-03-14 07:59:15697 root_->SetBounds(bounds);
698
[email protected]e8e4ae232013-04-12 00:26:01699 layer_ = TextureLayer::CreateForMailbox(NULL);
[email protected]28571b042013-03-14 07:59:15700 layer_->SetIsDrawable(true);
[email protected]28571b042013-03-14 07:59:15701 layer_->SetBounds(bounds);
702
703 root_->AddChild(layer_);
[email protected]e216fef02013-03-20 22:56:10704 layer_tree_host()->SetRootLayer(root_);
[email protected]18ce59702013-04-09 04:58:40705 layer_tree_host()->SetViewportSize(bounds);
[email protected]28571b042013-03-14 07:59:15706 SetMailbox('1');
707 EXPECT_EQ(0, callback_count_);
708
709 // Case #1: change mailbox before the commit. The old mailbox should be
710 // released immediately.
711 SetMailbox('2');
712 EXPECT_EQ(1, callback_count_);
[email protected]e216fef02013-03-20 22:56:10713 PostSetNeedsCommitToMainThread();
[email protected]28571b042013-03-14 07:59:15714 }
715
[email protected]e216fef02013-03-20 22:56:10716 virtual void DidCommit() OVERRIDE {
[email protected]28571b042013-03-14 07:59:15717 ++commit_count_;
718 switch (commit_count_) {
719 case 1:
720 // Case #2: change mailbox after the commit (and draw), where the
721 // layer draws. The old mailbox should be released during the next
722 // commit.
723 SetMailbox('3');
724 EXPECT_EQ(1, callback_count_);
725 break;
726 case 2:
[email protected]28571b042013-03-14 07:59:15727 EXPECT_EQ(2, callback_count_);
728 // Case #3: change mailbox when the layer doesn't draw. The old
729 // mailbox should be released during the next commit.
730 layer_->SetBounds(gfx::Size());
731 SetMailbox('4');
732 break;
[email protected]9794fb32013-08-29 09:49:59733 case 3:
[email protected]28571b042013-03-14 07:59:15734 EXPECT_EQ(3, callback_count_);
735 // Case #4: release mailbox that was committed but never drawn. The
736 // old mailbox should be released during the next commit.
[email protected]9260757f2013-09-17 01:24:16737 layer_->SetTextureMailbox(TextureMailbox(),
738 scoped_ptr<SingleReleaseCallback>());
[email protected]28571b042013-03-14 07:59:15739 break;
[email protected]9794fb32013-08-29 09:49:59740 case 4:
741 if (layer_tree_host()->settings().impl_side_painting) {
742 // With impl painting, the texture mailbox will still be on the impl
743 // thread when the commit finishes, because the layer is not drawble
744 // when it has no texture mailbox, and thus does not block the commit
745 // on activation. So, we wait for activation.
746 // TODO(danakj): fix this. crbug.com/277953
747 layer_tree_host()->SetNeedsCommit();
748 break;
749 } else {
750 ++commit_count_;
751 }
752 case 5:
[email protected]28571b042013-03-14 07:59:15753 EXPECT_EQ(4, callback_count_);
[email protected]7096acc2013-06-18 21:12:43754 // Restore a mailbox for the next step.
755 SetMailbox('5');
756 break;
[email protected]9794fb32013-08-29 09:49:59757 case 6:
[email protected]7096acc2013-06-18 21:12:43758 // Case #5: remove layer from tree. Callback should *not* be called, the
759 // mailbox is returned to the main thread.
760 EXPECT_EQ(4, callback_count_);
761 layer_->RemoveFromParent();
762 break;
[email protected]9794fb32013-08-29 09:49:59763 case 7:
764 if (layer_tree_host()->settings().impl_side_painting) {
765 // With impl painting, the texture mailbox will still be on the impl
766 // thread when the commit finishes, because the layer is not around to
767 // block the commit on activation anymore. So, we wait for activation.
768 // TODO(danakj): fix this. crbug.com/277953
769 layer_tree_host()->SetNeedsCommit();
770 break;
771 } else {
772 ++commit_count_;
773 }
774 case 8:
[email protected]7096acc2013-06-18 21:12:43775 EXPECT_EQ(4, callback_count_);
776 // Resetting the mailbox will call the callback now.
[email protected]9260757f2013-09-17 01:24:16777 layer_->SetTextureMailbox(TextureMailbox(),
778 scoped_ptr<SingleReleaseCallback>());
[email protected]7096acc2013-06-18 21:12:43779 EXPECT_EQ(5, callback_count_);
[email protected]e216fef02013-03-20 22:56:10780 EndTest();
[email protected]28571b042013-03-14 07:59:15781 break;
782 default:
783 NOTREACHED();
784 break;
[email protected]de44a152013-01-08 15:28:46785 }
[email protected]28571b042013-03-14 07:59:15786 }
[email protected]de44a152013-01-08 15:28:46787
[email protected]e216fef02013-03-20 22:56:10788 virtual void AfterTest() OVERRIDE {}
[email protected]de44a152013-01-08 15:28:46789
[email protected]28571b042013-03-14 07:59:15790 private:
[email protected]9794fb32013-08-29 09:49:59791 base::ThreadChecker main_thread_;
[email protected]28571b042013-03-14 07:59:15792 int callback_count_;
793 int commit_count_;
794 scoped_refptr<Layer> root_;
795 scoped_refptr<TextureLayer> layer_;
[email protected]de44a152013-01-08 15:28:46796};
797
[email protected]4145d172013-05-10 16:54:36798SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
799 TextureLayerImplWithMailboxThreadedCallback);
[email protected]de44a152013-01-08 15:28:46800
[email protected]74b43cc2013-08-30 06:29:27801
[email protected]74b43cc2013-08-30 06:29:27802class TextureLayerMailboxIsActivatedDuringCommit : public LayerTreeTest {
803 protected:
[email protected]98ea818e2014-01-24 10:22:08804 TextureLayerMailboxIsActivatedDuringCommit() : activate_count_(0) {}
[email protected]74b43cc2013-08-30 06:29:27805
[email protected]df41e252014-02-03 23:39:50806 static void ReleaseCallback(uint32 sync_point, bool lost_resource) {}
[email protected]74b43cc2013-08-30 06:29:27807
808 void SetMailbox(char mailbox_char) {
[email protected]9260757f2013-09-17 01:24:16809 scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create(
[email protected]74b43cc2013-08-30 06:29:27810 base::Bind(
811 &TextureLayerMailboxIsActivatedDuringCommit::ReleaseCallback));
[email protected]df41e252014-02-03 23:39:50812 layer_->SetTextureMailbox(
[email protected]e0a4d732014-02-15 00:23:26813 TextureMailbox(MailboxFromChar(mailbox_char), GL_TEXTURE_2D, 0),
[email protected]df41e252014-02-03 23:39:50814 callback.Pass());
[email protected]74b43cc2013-08-30 06:29:27815 }
816
817 virtual void BeginTest() OVERRIDE {
[email protected]74b43cc2013-08-30 06:29:27818 gfx::Size bounds(100, 100);
819 root_ = Layer::Create();
[email protected]74b43cc2013-08-30 06:29:27820 root_->SetBounds(bounds);
821
822 layer_ = TextureLayer::CreateForMailbox(NULL);
823 layer_->SetIsDrawable(true);
[email protected]74b43cc2013-08-30 06:29:27824 layer_->SetBounds(bounds);
825
826 root_->AddChild(layer_);
827 layer_tree_host()->SetRootLayer(root_);
828 layer_tree_host()->SetViewportSize(bounds);
829 SetMailbox('1');
830
831 PostSetNeedsCommitToMainThread();
832 }
833
834 virtual void WillActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
[email protected]74b43cc2013-08-30 06:29:27835 ++activate_count_;
836 }
837
[email protected]98ea818e2014-01-24 10:22:08838 virtual void DidCommit() OVERRIDE {
839 switch (layer_tree_host()->source_frame_number()) {
[email protected]74b43cc2013-08-30 06:29:27840 case 1:
841 // The first mailbox has been activated. Set a new mailbox, and
842 // expect the next commit to finish *after* it is activated.
843 SetMailbox('2');
[email protected]74b43cc2013-08-30 06:29:27844 break;
845 case 2:
846 // The second mailbox has been activated. Remove the layer from
847 // the tree to cause another commit/activation. The commit should
848 // finish *after* the layer is removed from the active tree.
849 layer_->RemoveFromParent();
[email protected]74b43cc2013-08-30 06:29:27850 break;
851 case 3:
852 EndTest();
853 break;
854 }
855 }
856
[email protected]98ea818e2014-01-24 10:22:08857 virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
858 switch (host_impl->active_tree()->source_frame_number()) {
[email protected]b6061062014-06-27 19:20:08859 case 0: {
860 // The activate for the 1st mailbox should have happened before now.
861 EXPECT_EQ(1, activate_count_);
862 break;
863 }
864 case 1: {
[email protected]74b43cc2013-08-30 06:29:27865 // The activate for the 2nd mailbox should have happened before now.
[email protected]74b43cc2013-08-30 06:29:27866 EXPECT_EQ(2, activate_count_);
867 break;
868 }
[email protected]b6061062014-06-27 19:20:08869 case 2: {
[email protected]74b43cc2013-08-30 06:29:27870 // The activate to remove the layer should have happened before now.
[email protected]74b43cc2013-08-30 06:29:27871 EXPECT_EQ(3, activate_count_);
872 break;
873 }
[email protected]b6061062014-06-27 19:20:08874 case 3: {
875 NOTREACHED();
876 break;
877 }
[email protected]74b43cc2013-08-30 06:29:27878 }
879 }
880
881
882 virtual void AfterTest() OVERRIDE {}
883
[email protected]74b43cc2013-08-30 06:29:27884 int activate_count_;
885 scoped_refptr<Layer> root_;
886 scoped_refptr<TextureLayer> layer_;
887};
888
889SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
890 TextureLayerMailboxIsActivatedDuringCommit);
891
[email protected]de44a152013-01-08 15:28:46892class TextureLayerImplWithMailboxTest : public TextureLayerTest {
[email protected]28571b042013-03-14 07:59:15893 protected:
[email protected]408b5e22013-03-19 09:48:09894 TextureLayerImplWithMailboxTest()
895 : fake_client_(
896 FakeLayerTreeHostClient(FakeLayerTreeHostClient::DIRECT_3D)) {}
897
[email protected]28571b042013-03-14 07:59:15898 virtual void SetUp() {
899 TextureLayerTest::SetUp();
[email protected]408b5e22013-03-19 09:48:09900 layer_tree_host_.reset(new MockLayerTreeHost(&fake_client_));
[email protected]a6366932014-02-05 20:12:47901 EXPECT_TRUE(host_impl_.InitializeRenderer(
902 FakeOutputSurface::Create3d().PassAs<OutputSurface>()));
[email protected]28571b042013-03-14 07:59:15903 }
[email protected]de44a152013-01-08 15:28:46904
[email protected]0ec335c42013-07-04 06:17:08905 bool WillDraw(TextureLayerImpl* layer, DrawMode mode) {
906 bool will_draw = layer->WillDraw(
907 mode, host_impl_.active_tree()->resource_provider());
908 if (will_draw)
909 layer->DidDraw(host_impl_.active_tree()->resource_provider());
910 return will_draw;
911 }
912
[email protected]28571b042013-03-14 07:59:15913 CommonMailboxObjects test_data_;
[email protected]408b5e22013-03-19 09:48:09914 FakeLayerTreeHostClient fake_client_;
[email protected]de44a152013-01-08 15:28:46915};
916
[email protected]ffbb2212013-06-02 23:47:59917// Test conditions for results of TextureLayerImpl::WillDraw under
918// different configurations of different mailbox, texture_id, and draw_mode.
919TEST_F(TextureLayerImplWithMailboxTest, TestWillDraw) {
[email protected]0ec335c42013-07-04 06:17:08920 EXPECT_CALL(test_data_.mock_callback_,
921 Release(test_data_.mailbox_name1_,
922 test_data_.sync_point1_,
923 false))
924 .Times(AnyNumber());
925 EXPECT_CALL(test_data_.mock_callback_,
926 Release2(test_data_.shared_memory_.get(), 0, false))
927 .Times(AnyNumber());
[email protected]ffbb2212013-06-02 23:47:59928 // Hardware mode.
929 {
930 scoped_ptr<TextureLayerImpl> impl_layer =
[email protected]17e08432014-04-10 00:41:11931 TextureLayerImpl::Create(host_impl_.active_tree(), 1);
[email protected]9260757f2013-09-17 01:24:16932 impl_layer->SetTextureMailbox(
933 test_data_.mailbox1_,
934 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
[email protected]0ec335c42013-07-04 06:17:08935 EXPECT_TRUE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE));
[email protected]ffbb2212013-06-02 23:47:59936 }
937
938 {
939 scoped_ptr<TextureLayerImpl> impl_layer =
[email protected]17e08432014-04-10 00:41:11940 TextureLayerImpl::Create(host_impl_.active_tree(), 1);
[email protected]9260757f2013-09-17 01:24:16941 impl_layer->SetTextureMailbox(TextureMailbox(),
942 scoped_ptr<SingleReleaseCallback>());
[email protected]0ec335c42013-07-04 06:17:08943 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE));
944 }
945
946 {
947 // Software resource.
948 scoped_ptr<TextureLayerImpl> impl_layer =
[email protected]17e08432014-04-10 00:41:11949 TextureLayerImpl::Create(host_impl_.active_tree(), 1);
[email protected]9260757f2013-09-17 01:24:16950 impl_layer->SetTextureMailbox(
951 test_data_.mailbox3_,
952 SingleReleaseCallback::Create(test_data_.release_mailbox3_));
[email protected]3e44d7a2013-07-30 00:03:10953 EXPECT_TRUE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE));
[email protected]ffbb2212013-06-02 23:47:59954 }
955
[email protected]0ec335c42013-07-04 06:17:08956 // Software mode.
957 {
958 scoped_ptr<TextureLayerImpl> impl_layer =
[email protected]17e08432014-04-10 00:41:11959 TextureLayerImpl::Create(host_impl_.active_tree(), 1);
[email protected]9260757f2013-09-17 01:24:16960 impl_layer->SetTextureMailbox(
961 test_data_.mailbox1_,
962 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
[email protected]0ec335c42013-07-04 06:17:08963 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE));
964 }
965
966 {
967 scoped_ptr<TextureLayerImpl> impl_layer =
[email protected]17e08432014-04-10 00:41:11968 TextureLayerImpl::Create(host_impl_.active_tree(), 1);
[email protected]9260757f2013-09-17 01:24:16969 impl_layer->SetTextureMailbox(TextureMailbox(),
970 scoped_ptr<SingleReleaseCallback>());
[email protected]0ec335c42013-07-04 06:17:08971 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE));
972 }
973
974 {
975 // Software resource.
976 scoped_ptr<TextureLayerImpl> impl_layer =
[email protected]17e08432014-04-10 00:41:11977 TextureLayerImpl::Create(host_impl_.active_tree(), 1);
[email protected]9260757f2013-09-17 01:24:16978 impl_layer->SetTextureMailbox(
979 test_data_.mailbox3_,
980 SingleReleaseCallback::Create(test_data_.release_mailbox3_));
[email protected]0ec335c42013-07-04 06:17:08981 EXPECT_TRUE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE));
982 }
983
[email protected]ffbb2212013-06-02 23:47:59984 // Resourceless software mode.
985 {
986 scoped_ptr<TextureLayerImpl> impl_layer =
[email protected]17e08432014-04-10 00:41:11987 TextureLayerImpl::Create(host_impl_.active_tree(), 1);
[email protected]9260757f2013-09-17 01:24:16988 impl_layer->SetTextureMailbox(
989 test_data_.mailbox1_,
990 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
[email protected]0ec335c42013-07-04 06:17:08991 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_RESOURCELESS_SOFTWARE));
[email protected]ffbb2212013-06-02 23:47:59992 }
[email protected]ffbb2212013-06-02 23:47:59993}
994
[email protected]28571b042013-03-14 07:59:15995TEST_F(TextureLayerImplWithMailboxTest, TestImplLayerCallbacks) {
996 host_impl_.CreatePendingTree();
997 scoped_ptr<TextureLayerImpl> pending_layer;
[email protected]17e08432014-04-10 00:41:11998 pending_layer = TextureLayerImpl::Create(host_impl_.pending_tree(), 1);
[email protected]28571b042013-03-14 07:59:15999 ASSERT_TRUE(pending_layer);
[email protected]de44a152013-01-08 15:28:461000
[email protected]ed511b8d2013-03-25 03:29:291001 scoped_ptr<LayerImpl> active_layer(
[email protected]28571b042013-03-14 07:59:151002 pending_layer->CreateLayerImpl(host_impl_.active_tree()));
[email protected]ed511b8d2013-03-25 03:29:291003 ASSERT_TRUE(active_layer);
[email protected]de44a152013-01-08 15:28:461004
[email protected]9260757f2013-09-17 01:24:161005 pending_layer->SetTextureMailbox(
1006 test_data_.mailbox1_,
1007 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
[email protected]421e84f2013-02-22 03:27:151008
[email protected]28571b042013-03-14 07:59:151009 // Test multiple commits without an activation.
1010 EXPECT_CALL(test_data_.mock_callback_,
[email protected]7ba3ca72013-04-11 06:37:251011 Release(test_data_.mailbox_name1_,
1012 test_data_.sync_point1_,
1013 false))
[email protected]28571b042013-03-14 07:59:151014 .Times(1);
[email protected]9260757f2013-09-17 01:24:161015 pending_layer->SetTextureMailbox(
1016 test_data_.mailbox2_,
1017 SingleReleaseCallback::Create(test_data_.release_mailbox2_));
[email protected]28571b042013-03-14 07:59:151018 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]421e84f2013-02-22 03:27:151019
[email protected]28571b042013-03-14 07:59:151020 // Test callback after activation.
[email protected]ed511b8d2013-03-25 03:29:291021 pending_layer->PushPropertiesTo(active_layer.get());
1022 active_layer->DidBecomeActive();
[email protected]421e84f2013-02-22 03:27:151023
[email protected]7ba3ca72013-04-11 06:37:251024 EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0);
[email protected]9260757f2013-09-17 01:24:161025 pending_layer->SetTextureMailbox(
1026 test_data_.mailbox1_,
1027 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
[email protected]28571b042013-03-14 07:59:151028 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]421e84f2013-02-22 03:27:151029
[email protected]7ba3ca72013-04-11 06:37:251030 EXPECT_CALL(test_data_.mock_callback_,
1031 Release(test_data_.mailbox_name2_, _, false))
[email protected]28571b042013-03-14 07:59:151032 .Times(1);
[email protected]ed511b8d2013-03-25 03:29:291033 pending_layer->PushPropertiesTo(active_layer.get());
1034 active_layer->DidBecomeActive();
[email protected]28571b042013-03-14 07:59:151035 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]de44a152013-01-08 15:28:461036
[email protected]28571b042013-03-14 07:59:151037 // Test resetting the mailbox.
[email protected]7ba3ca72013-04-11 06:37:251038 EXPECT_CALL(test_data_.mock_callback_,
1039 Release(test_data_.mailbox_name1_, _, false))
[email protected]28571b042013-03-14 07:59:151040 .Times(1);
[email protected]9260757f2013-09-17 01:24:161041 pending_layer->SetTextureMailbox(TextureMailbox(),
1042 scoped_ptr<SingleReleaseCallback>());
[email protected]ed511b8d2013-03-25 03:29:291043 pending_layer->PushPropertiesTo(active_layer.get());
1044 active_layer->DidBecomeActive();
[email protected]28571b042013-03-14 07:59:151045 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]de44a152013-01-08 15:28:461046
[email protected]28571b042013-03-14 07:59:151047 // Test destructor.
1048 EXPECT_CALL(test_data_.mock_callback_,
[email protected]7ba3ca72013-04-11 06:37:251049 Release(test_data_.mailbox_name1_,
1050 test_data_.sync_point1_,
1051 false))
[email protected]28571b042013-03-14 07:59:151052 .Times(1);
[email protected]9260757f2013-09-17 01:24:161053 pending_layer->SetTextureMailbox(
1054 test_data_.mailbox1_,
1055 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
[email protected]de44a152013-01-08 15:28:461056}
1057
[email protected]28571b042013-03-14 07:59:151058TEST_F(TextureLayerImplWithMailboxTest,
1059 TestDestructorCallbackOnCreatedResource) {
1060 scoped_ptr<TextureLayerImpl> impl_layer;
[email protected]17e08432014-04-10 00:41:111061 impl_layer = TextureLayerImpl::Create(host_impl_.active_tree(), 1);
[email protected]28571b042013-03-14 07:59:151062 ASSERT_TRUE(impl_layer);
[email protected]de44a152013-01-08 15:28:461063
[email protected]7ba3ca72013-04-11 06:37:251064 EXPECT_CALL(test_data_.mock_callback_,
1065 Release(test_data_.mailbox_name1_, _, false))
[email protected]28571b042013-03-14 07:59:151066 .Times(1);
[email protected]9260757f2013-09-17 01:24:161067 impl_layer->SetTextureMailbox(
1068 test_data_.mailbox1_,
1069 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
[email protected]ffbb2212013-06-02 23:47:591070 impl_layer->DidBecomeActive();
1071 EXPECT_TRUE(impl_layer->WillDraw(
1072 DRAW_MODE_HARDWARE, host_impl_.active_tree()->resource_provider()));
[email protected]28571b042013-03-14 07:59:151073 impl_layer->DidDraw(host_impl_.active_tree()->resource_provider());
[email protected]9260757f2013-09-17 01:24:161074 impl_layer->SetTextureMailbox(TextureMailbox(),
1075 scoped_ptr<SingleReleaseCallback>());
[email protected]de44a152013-01-08 15:28:461076}
1077
[email protected]28571b042013-03-14 07:59:151078TEST_F(TextureLayerImplWithMailboxTest, TestCallbackOnInUseResource) {
1079 ResourceProvider* provider = host_impl_.active_tree()->resource_provider();
1080 ResourceProvider::ResourceId id =
[email protected]9260757f2013-09-17 01:24:161081 provider->CreateResourceFromTextureMailbox(
1082 test_data_.mailbox1_,
1083 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
[email protected]28571b042013-03-14 07:59:151084 provider->AllocateForTesting(id);
[email protected]de44a152013-01-08 15:28:461085
[email protected]28571b042013-03-14 07:59:151086 // Transfer some resources to the parent.
1087 ResourceProvider::ResourceIdArray resource_ids_to_transfer;
1088 resource_ids_to_transfer.push_back(id);
1089 TransferableResourceArray list;
1090 provider->PrepareSendToParent(resource_ids_to_transfer, &list);
1091 EXPECT_TRUE(provider->InUseByConsumer(id));
[email protected]7ba3ca72013-04-11 06:37:251092 EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0);
[email protected]28571b042013-03-14 07:59:151093 provider->DeleteResource(id);
1094 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]7ba3ca72013-04-11 06:37:251095 EXPECT_CALL(test_data_.mock_callback_,
1096 Release(test_data_.mailbox_name1_, _, false))
[email protected]28571b042013-03-14 07:59:151097 .Times(1);
[email protected]e00bab022013-08-19 00:42:451098 ReturnedResourceArray returned;
1099 TransferableResource::ReturnResources(list, &returned);
1100 provider->ReceiveReturnsFromParent(returned);
[email protected]de44a152013-01-08 15:28:461101}
1102
[email protected]4bad8b62013-10-24 01:27:291103// Checks that TextureLayer::Update does not cause an extra commit when setting
1104// the texture mailbox.
1105class TextureLayerNoExtraCommitForMailboxTest
1106 : public LayerTreeTest,
1107 public TextureLayerClient {
1108 public:
[email protected]4bad8b62013-10-24 01:27:291109 // TextureLayerClient implementation.
[email protected]4bad8b62013-10-24 01:27:291110 virtual bool PrepareTextureMailbox(
[email protected]df41e252014-02-03 23:39:501111 TextureMailbox* texture_mailbox,
[email protected]4bad8b62013-10-24 01:27:291112 scoped_ptr<SingleReleaseCallback>* release_callback,
1113 bool use_shared_memory) OVERRIDE {
[email protected]cce34bd2013-12-02 23:24:451114 if (layer_tree_host()->source_frame_number() == 1) {
[email protected]9f35bd22014-06-03 15:25:461115 // Once this has been committed, the mailbox will be released.
[email protected]df41e252014-02-03 23:39:501116 *texture_mailbox = TextureMailbox();
[email protected]cce34bd2013-12-02 23:24:451117 return true;
1118 }
[email protected]4bad8b62013-10-24 01:27:291119
[email protected]e0a4d732014-02-15 00:23:261120 *texture_mailbox = TextureMailbox(MailboxFromChar('1'), GL_TEXTURE_2D, 0);
[email protected]4bad8b62013-10-24 01:27:291121 *release_callback = SingleReleaseCallback::Create(
1122 base::Bind(&TextureLayerNoExtraCommitForMailboxTest::MailboxReleased,
1123 base::Unretained(this)));
[email protected]4bad8b62013-10-24 01:27:291124 return true;
1125 }
1126
[email protected]df41e252014-02-03 23:39:501127 void MailboxReleased(uint32 sync_point, bool lost_resource) {
[email protected]9f35bd22014-06-03 15:25:461128 // Source frame number during callback is the same as the source frame
1129 // on which it was released.
1130 EXPECT_EQ(1, layer_tree_host()->source_frame_number());
[email protected]cce34bd2013-12-02 23:24:451131 EndTest();
[email protected]4bad8b62013-10-24 01:27:291132 }
1133
1134 virtual void SetupTree() OVERRIDE {
1135 scoped_refptr<Layer> root = Layer::Create();
1136 root->SetBounds(gfx::Size(10, 10));
[email protected]4bad8b62013-10-24 01:27:291137 root->SetIsDrawable(true);
1138
[email protected]4bad8b62013-10-24 01:27:291139 texture_layer_ = TextureLayer::CreateForMailbox(this);
1140 texture_layer_->SetBounds(gfx::Size(10, 10));
[email protected]4bad8b62013-10-24 01:27:291141 texture_layer_->SetIsDrawable(true);
[email protected]0d7fb302014-01-23 21:30:471142 root->AddChild(texture_layer_);
[email protected]4bad8b62013-10-24 01:27:291143
1144 layer_tree_host()->SetRootLayer(root);
1145 LayerTreeTest::SetupTree();
1146 }
1147
1148 virtual void BeginTest() OVERRIDE {
1149 PostSetNeedsCommitToMainThread();
1150 }
1151
[email protected]cce34bd2013-12-02 23:24:451152 virtual void DidCommitAndDrawFrame() OVERRIDE {
[email protected]4bad8b62013-10-24 01:27:291153 switch (layer_tree_host()->source_frame_number()) {
1154 case 1:
[email protected]cce34bd2013-12-02 23:24:451155 EXPECT_FALSE(proxy()->CommitPendingForTesting());
1156 // Invalidate the texture layer to clear the mailbox before
1157 // ending the test.
1158 texture_layer_->SetNeedsDisplay();
1159 break;
1160 case 2:
[email protected]4bad8b62013-10-24 01:27:291161 break;
1162 default:
1163 NOTREACHED();
1164 break;
1165 }
1166 }
1167
[email protected]cce34bd2013-12-02 23:24:451168 virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl,
1169 bool result) OVERRIDE {
1170 ASSERT_TRUE(result);
1171 DelegatedFrameData* delegated_frame_data =
1172 output_surface()->last_sent_frame().delegated_frame_data.get();
1173 if (!delegated_frame_data)
1174 return;
1175
1176 // Return all resources immediately.
1177 TransferableResourceArray resources_to_return =
1178 output_surface()->resources_held_by_parent();
1179
1180 CompositorFrameAck ack;
1181 for (size_t i = 0; i < resources_to_return.size(); ++i)
1182 output_surface()->ReturnResource(resources_to_return[i].id, &ack);
1183 host_impl->ReclaimResources(&ack);
[email protected]cce34bd2013-12-02 23:24:451184 }
1185
[email protected]4bad8b62013-10-24 01:27:291186 virtual void AfterTest() OVERRIDE {}
1187
1188 private:
[email protected]4bad8b62013-10-24 01:27:291189 scoped_refptr<TextureLayer> texture_layer_;
[email protected]4bad8b62013-10-24 01:27:291190};
1191
[email protected]cce34bd2013-12-02 23:24:451192SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerNoExtraCommitForMailboxTest);
[email protected]4bad8b62013-10-24 01:27:291193
[email protected]b04264f92013-09-13 23:37:291194// Checks that changing a mailbox in the client for a TextureLayer that's
1195// invisible correctly works and uses the new mailbox as soon as the layer
1196// becomes visible (and returns the old one).
1197class TextureLayerChangeInvisibleMailboxTest
1198 : public LayerTreeTest,
1199 public TextureLayerClient {
1200 public:
1201 TextureLayerChangeInvisibleMailboxTest()
1202 : mailbox_changed_(true),
1203 mailbox_returned_(0),
1204 prepare_called_(0),
1205 commit_count_(0) {
1206 mailbox_ = MakeMailbox('1');
1207 }
1208
1209 // TextureLayerClient implementation.
[email protected]b04264f92013-09-13 23:37:291210 virtual bool PrepareTextureMailbox(
[email protected]e51444a2013-12-10 23:05:011211 TextureMailbox* mailbox,
[email protected]9260757f2013-09-17 01:24:161212 scoped_ptr<SingleReleaseCallback>* release_callback,
1213 bool use_shared_memory) OVERRIDE {
[email protected]b04264f92013-09-13 23:37:291214 ++prepare_called_;
1215 if (!mailbox_changed_)
1216 return false;
1217 *mailbox = mailbox_;
[email protected]9260757f2013-09-17 01:24:161218 *release_callback = SingleReleaseCallback::Create(
1219 base::Bind(&TextureLayerChangeInvisibleMailboxTest::MailboxReleased,
1220 base::Unretained(this)));
[email protected]b04264f92013-09-13 23:37:291221 return true;
1222 }
1223
1224 TextureMailbox MakeMailbox(char name) {
[email protected]e0a4d732014-02-15 00:23:261225 return TextureMailbox(MailboxFromChar(name), GL_TEXTURE_2D, 0);
[email protected]b04264f92013-09-13 23:37:291226 }
1227
[email protected]df41e252014-02-03 23:39:501228 void MailboxReleased(uint32 sync_point, bool lost_resource) {
[email protected]b04264f92013-09-13 23:37:291229 ++mailbox_returned_;
1230 }
1231
1232 virtual void SetupTree() OVERRIDE {
1233 scoped_refptr<Layer> root = Layer::Create();
1234 root->SetBounds(gfx::Size(10, 10));
[email protected]b04264f92013-09-13 23:37:291235 root->SetIsDrawable(true);
1236
1237 solid_layer_ = SolidColorLayer::Create();
1238 solid_layer_->SetBounds(gfx::Size(10, 10));
1239 solid_layer_->SetIsDrawable(true);
1240 solid_layer_->SetBackgroundColor(SK_ColorWHITE);
1241 root->AddChild(solid_layer_);
1242
1243 parent_layer_ = Layer::Create();
1244 parent_layer_->SetBounds(gfx::Size(10, 10));
1245 parent_layer_->SetIsDrawable(true);
1246 root->AddChild(parent_layer_);
1247
1248 texture_layer_ = TextureLayer::CreateForMailbox(this);
1249 texture_layer_->SetBounds(gfx::Size(10, 10));
[email protected]b04264f92013-09-13 23:37:291250 texture_layer_->SetIsDrawable(true);
1251 parent_layer_->AddChild(texture_layer_);
1252
1253 layer_tree_host()->SetRootLayer(root);
1254 LayerTreeTest::SetupTree();
1255 }
1256
1257 virtual void BeginTest() OVERRIDE {
1258 PostSetNeedsCommitToMainThread();
1259 }
1260
1261 virtual void DidCommitAndDrawFrame() OVERRIDE {
1262 ++commit_count_;
1263 switch (commit_count_) {
1264 case 1:
1265 // We should have updated the layer, committing the texture.
1266 EXPECT_EQ(1, prepare_called_);
1267 // Make layer invisible.
1268 parent_layer_->SetOpacity(0.f);
1269 break;
1270 case 2:
1271 // Layer shouldn't have been updated.
1272 EXPECT_EQ(1, prepare_called_);
1273 // Change the texture.
1274 mailbox_ = MakeMailbox('2');
1275 mailbox_changed_ = true;
1276 texture_layer_->SetNeedsDisplay();
1277 // Force a change to make sure we draw a frame.
1278 solid_layer_->SetBackgroundColor(SK_ColorGRAY);
1279 break;
1280 case 3:
1281 // Layer shouldn't have been updated.
1282 EXPECT_EQ(1, prepare_called_);
1283 // So the old mailbox isn't returned yet.
1284 EXPECT_EQ(0, mailbox_returned_);
1285 // Make layer visible again.
1286 parent_layer_->SetOpacity(1.f);
1287 break;
1288 case 4:
1289 // Layer should have been updated.
1290 EXPECT_EQ(2, prepare_called_);
1291 // So the old mailbox should have been returned already.
1292 EXPECT_EQ(1, mailbox_returned_);
1293 texture_layer_->ClearClient();
1294 break;
1295 case 5:
1296 EXPECT_EQ(2, mailbox_returned_);
1297 EndTest();
1298 break;
1299 default:
1300 NOTREACHED();
1301 break;
1302 }
1303 }
1304
1305 virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl,
1306 bool result) OVERRIDE {
1307 ASSERT_TRUE(result);
1308 DelegatedFrameData* delegated_frame_data =
1309 output_surface()->last_sent_frame().delegated_frame_data.get();
1310 if (!delegated_frame_data)
1311 return;
1312
1313 // Return all resources immediately.
1314 TransferableResourceArray resources_to_return =
1315 output_surface()->resources_held_by_parent();
1316
1317 CompositorFrameAck ack;
1318 for (size_t i = 0; i < resources_to_return.size(); ++i)
1319 output_surface()->ReturnResource(resources_to_return[i].id, &ack);
[email protected]a7335e0b2013-09-18 09:34:511320 host_impl->ReclaimResources(&ack);
[email protected]b04264f92013-09-13 23:37:291321 }
1322
1323 virtual void AfterTest() OVERRIDE {}
1324
1325 private:
1326 scoped_refptr<SolidColorLayer> solid_layer_;
1327 scoped_refptr<Layer> parent_layer_;
1328 scoped_refptr<TextureLayer> texture_layer_;
1329
1330 // Used on the main thread.
1331 bool mailbox_changed_;
1332 TextureMailbox mailbox_;
1333 int mailbox_returned_;
1334 int prepare_called_;
1335 int commit_count_;
1336};
1337
1338SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerChangeInvisibleMailboxTest);
1339
[email protected]0d7fb302014-01-23 21:30:471340// Test that TextureLayerImpl::ReleaseResources can be called which releases
1341// the mailbox back to TextureLayerClient.
1342class TextureLayerReleaseResourcesBase
1343 : public LayerTreeTest,
1344 public TextureLayerClient {
1345 public:
1346 // TextureLayerClient implementation.
[email protected]0d7fb302014-01-23 21:30:471347 virtual bool PrepareTextureMailbox(
1348 TextureMailbox* mailbox,
1349 scoped_ptr<SingleReleaseCallback>* release_callback,
1350 bool use_shared_memory) OVERRIDE {
[email protected]e0a4d732014-02-15 00:23:261351 *mailbox = TextureMailbox(MailboxFromChar('1'), GL_TEXTURE_2D, 0);
[email protected]0d7fb302014-01-23 21:30:471352 *release_callback = SingleReleaseCallback::Create(
1353 base::Bind(&TextureLayerReleaseResourcesBase::MailboxReleased,
1354 base::Unretained(this)));
1355 return true;
1356 }
1357
1358 void MailboxReleased(unsigned sync_point, bool lost_resource) {
1359 mailbox_released_ = true;
1360 }
1361
1362 virtual void SetupTree() OVERRIDE {
1363 LayerTreeTest::SetupTree();
1364
1365 scoped_refptr<TextureLayer> texture_layer =
1366 TextureLayer::CreateForMailbox(this);
1367 texture_layer->SetBounds(gfx::Size(10, 10));
[email protected]0d7fb302014-01-23 21:30:471368 texture_layer->SetIsDrawable(true);
1369
1370 layer_tree_host()->root_layer()->AddChild(texture_layer);
1371 }
1372
1373 virtual void BeginTest() OVERRIDE {
1374 mailbox_released_ = false;
1375 PostSetNeedsCommitToMainThread();
1376 }
1377
1378 virtual void DidCommitAndDrawFrame() OVERRIDE {
1379 EndTest();
1380 }
1381
1382 virtual void AfterTest() OVERRIDE {
1383 EXPECT_TRUE(mailbox_released_);
1384 }
1385
1386 private:
1387 bool mailbox_released_;
1388};
1389
1390class TextureLayerReleaseResourcesAfterCommit
1391 : public TextureLayerReleaseResourcesBase {
1392 public:
1393 virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
1394 LayerTreeImpl* tree = NULL;
1395 if (host_impl->settings().impl_side_painting)
1396 tree = host_impl->pending_tree();
1397 else
1398 tree = host_impl->active_tree();
1399 tree->root_layer()->children()[0]->ReleaseResources();
1400 }
1401};
1402
1403SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerReleaseResourcesAfterCommit);
1404
1405class TextureLayerReleaseResourcesAfterActivate
1406 : public TextureLayerReleaseResourcesBase {
1407 public:
1408 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
1409 host_impl->active_tree()->root_layer()->children()[0]->ReleaseResources();
1410 }
1411};
1412
1413SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerReleaseResourcesAfterActivate);
1414
[email protected]9c2bd822013-07-26 12:30:171415class TextureLayerWithMailboxMainThreadDeleted : public LayerTreeTest {
1416 public:
[email protected]df41e252014-02-03 23:39:501417 void ReleaseCallback(uint32 sync_point, bool lost_resource) {
[email protected]9794fb32013-08-29 09:49:591418 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]9c2bd822013-07-26 12:30:171419 EXPECT_FALSE(lost_resource);
1420 ++callback_count_;
1421 EndTest();
1422 }
1423
1424 void SetMailbox(char mailbox_char) {
[email protected]9794fb32013-08-29 09:49:591425 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]9260757f2013-09-17 01:24:161426 scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create(
[email protected]9c2bd822013-07-26 12:30:171427 base::Bind(
1428 &TextureLayerWithMailboxMainThreadDeleted::ReleaseCallback,
1429 base::Unretained(this)));
[email protected]df41e252014-02-03 23:39:501430 layer_->SetTextureMailbox(
[email protected]e0a4d732014-02-15 00:23:261431 TextureMailbox(MailboxFromChar(mailbox_char), GL_TEXTURE_2D, 0),
[email protected]df41e252014-02-03 23:39:501432 callback.Pass());
[email protected]9c2bd822013-07-26 12:30:171433 }
1434
1435 virtual void SetupTree() OVERRIDE {
1436 gfx::Size bounds(100, 100);
1437 root_ = Layer::Create();
[email protected]9c2bd822013-07-26 12:30:171438 root_->SetBounds(bounds);
1439
1440 layer_ = TextureLayer::CreateForMailbox(NULL);
1441 layer_->SetIsDrawable(true);
[email protected]9c2bd822013-07-26 12:30:171442 layer_->SetBounds(bounds);
1443
1444 root_->AddChild(layer_);
1445 layer_tree_host()->SetRootLayer(root_);
1446 layer_tree_host()->SetViewportSize(bounds);
1447 }
1448
1449 virtual void BeginTest() OVERRIDE {
[email protected]9794fb32013-08-29 09:49:591450 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
1451
[email protected]9c2bd822013-07-26 12:30:171452 callback_count_ = 0;
1453
1454 // Set the mailbox on the main thread.
1455 SetMailbox('1');
1456 EXPECT_EQ(0, callback_count_);
1457
1458 PostSetNeedsCommitToMainThread();
1459 }
1460
1461 virtual void DidCommitAndDrawFrame() OVERRIDE {
1462 switch (layer_tree_host()->source_frame_number()) {
1463 case 1:
1464 // Delete the TextureLayer on the main thread while the mailbox is in
1465 // the impl tree.
1466 layer_->RemoveFromParent();
1467 layer_ = NULL;
1468 break;
1469 }
1470 }
1471
1472 virtual void AfterTest() OVERRIDE {
1473 EXPECT_EQ(1, callback_count_);
1474 }
1475
1476 private:
[email protected]9794fb32013-08-29 09:49:591477 base::ThreadChecker main_thread_;
[email protected]9c2bd822013-07-26 12:30:171478 int callback_count_;
1479 scoped_refptr<Layer> root_;
1480 scoped_refptr<TextureLayer> layer_;
1481};
1482
1483SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
1484 TextureLayerWithMailboxMainThreadDeleted);
1485
1486class TextureLayerWithMailboxImplThreadDeleted : public LayerTreeTest {
1487 public:
[email protected]df41e252014-02-03 23:39:501488 void ReleaseCallback(uint32 sync_point, bool lost_resource) {
[email protected]9794fb32013-08-29 09:49:591489 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]9c2bd822013-07-26 12:30:171490 EXPECT_FALSE(lost_resource);
1491 ++callback_count_;
1492 EndTest();
1493 }
1494
1495 void SetMailbox(char mailbox_char) {
[email protected]9794fb32013-08-29 09:49:591496 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]9260757f2013-09-17 01:24:161497 scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create(
[email protected]9c2bd822013-07-26 12:30:171498 base::Bind(
1499 &TextureLayerWithMailboxImplThreadDeleted::ReleaseCallback,
1500 base::Unretained(this)));
[email protected]df41e252014-02-03 23:39:501501 layer_->SetTextureMailbox(
[email protected]e0a4d732014-02-15 00:23:261502 TextureMailbox(MailboxFromChar(mailbox_char), GL_TEXTURE_2D, 0),
[email protected]df41e252014-02-03 23:39:501503 callback.Pass());
[email protected]9c2bd822013-07-26 12:30:171504 }
1505
1506 virtual void SetupTree() OVERRIDE {
1507 gfx::Size bounds(100, 100);
1508 root_ = Layer::Create();
[email protected]9c2bd822013-07-26 12:30:171509 root_->SetBounds(bounds);
1510
1511 layer_ = TextureLayer::CreateForMailbox(NULL);
1512 layer_->SetIsDrawable(true);
[email protected]9c2bd822013-07-26 12:30:171513 layer_->SetBounds(bounds);
1514
1515 root_->AddChild(layer_);
1516 layer_tree_host()->SetRootLayer(root_);
1517 layer_tree_host()->SetViewportSize(bounds);
1518 }
1519
1520 virtual void BeginTest() OVERRIDE {
[email protected]9794fb32013-08-29 09:49:591521 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
1522
[email protected]9c2bd822013-07-26 12:30:171523 callback_count_ = 0;
1524
1525 // Set the mailbox on the main thread.
1526 SetMailbox('1');
1527 EXPECT_EQ(0, callback_count_);
1528
1529 PostSetNeedsCommitToMainThread();
1530 }
1531
1532 virtual void DidCommitAndDrawFrame() OVERRIDE {
1533 switch (layer_tree_host()->source_frame_number()) {
1534 case 1:
1535 // Remove the TextureLayer on the main thread while the mailbox is in
1536 // the impl tree, but don't delete the TextureLayer until after the impl
1537 // tree side is deleted.
1538 layer_->RemoveFromParent();
1539 break;
1540 case 2:
1541 layer_ = NULL;
1542 break;
1543 }
1544 }
1545
1546 virtual void AfterTest() OVERRIDE {
1547 EXPECT_EQ(1, callback_count_);
1548 }
1549
1550 private:
[email protected]9794fb32013-08-29 09:49:591551 base::ThreadChecker main_thread_;
[email protected]9c2bd822013-07-26 12:30:171552 int callback_count_;
1553 scoped_refptr<Layer> root_;
1554 scoped_refptr<TextureLayer> layer_;
1555};
1556
1557SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
1558 TextureLayerWithMailboxImplThreadDeleted);
1559
[email protected]ba565742012-11-10 09:29:481560} // namespace
1561} // namespace cc