blob: f2ee2695d69e4da1dc3d818da55689992f2d8119 [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)
reveman22dd9292014-10-13 20:52:0554 : LayerTreeHost(client, nullptr, nullptr, LayerTreeSettings()) {
simonhonga7e3ac42014-11-11 20:50:2255 InitializeSingleThreaded(client,
56 base::MessageLoopProxy::current(),
57 nullptr);
[email protected]28571b042013-03-14 07:59:1558 }
[email protected]c0dd24c2012-08-30 23:25:2759
[email protected]28571b042013-03-14 07:59:1560 MOCK_METHOD0(SetNeedsCommit, void());
[email protected]3519b872013-07-30 07:17:5061 MOCK_METHOD0(SetNeedsUpdateLayers, void());
[email protected]aeeb3372013-11-05 14:05:5462 MOCK_METHOD0(StartRateLimiter, void());
63 MOCK_METHOD0(StopRateLimiter, void());
[email protected]c0dd24c2012-08-30 23:25:2764};
65
[email protected]d72d9e02014-04-03 18:40:0966class FakeTextureLayerClient : public TextureLayerClient {
67 public:
[email protected]17e08432014-04-10 00:41:1168 FakeTextureLayerClient() : mailbox_changed_(true) {}
[email protected]d72d9e02014-04-03 18:40:0969
dcheng716bedf2014-10-21 09:51:0870 bool PrepareTextureMailbox(
[email protected]d72d9e02014-04-03 18:40:0971 TextureMailbox* mailbox,
72 scoped_ptr<SingleReleaseCallback>* release_callback,
mostynbf68776d82014-10-06 18:07:3773 bool use_shared_memory) override {
[email protected]d72d9e02014-04-03 18:40:0974 if (!mailbox_changed_)
75 return false;
76
77 *mailbox = mailbox_;
78 *release_callback = release_callback_.Pass();
79 mailbox_changed_ = false;
80 return true;
81 }
82
[email protected]d72d9e02014-04-03 18:40:0983 void set_mailbox(const TextureMailbox& mailbox,
84 scoped_ptr<SingleReleaseCallback> release_callback) {
85 mailbox_ = mailbox;
86 release_callback_ = release_callback.Pass();
87 mailbox_changed_ = true;
88 }
89
90 private:
[email protected]d72d9e02014-04-03 18:40:0991 TextureMailbox mailbox_;
92 scoped_ptr<SingleReleaseCallback> release_callback_;
93 bool mailbox_changed_;
94 DISALLOW_COPY_AND_ASSIGN(FakeTextureLayerClient);
95};
96
97class MockMailboxCallback {
98 public:
99 MOCK_METHOD3(Release,
100 void(const gpu::Mailbox& mailbox,
101 uint32 sync_point,
102 bool lost_resource));
103 MOCK_METHOD3(Release2,
104 void(base::SharedMemory* shared_memory,
105 uint32 sync_point,
106 bool lost_resource));
skyostil3976a3f2014-09-04 22:07:23107 MOCK_METHOD4(ReleaseImpl,
108 void(const gpu::Mailbox& mailbox,
109 uint32 sync_point,
110 bool lost_resource,
111 BlockingTaskRunner* main_thread_task_runner));
112 MOCK_METHOD4(ReleaseImpl2,
113 void(base::SharedMemory* shared_memory,
114 uint32 sync_point,
115 bool lost_resource,
116 BlockingTaskRunner* main_thread_task_runner));
[email protected]d72d9e02014-04-03 18:40:09117};
118
119struct CommonMailboxObjects {
120 CommonMailboxObjects()
121 : mailbox_name1_(MailboxFromChar('1')),
122 mailbox_name2_(MailboxFromChar('2')),
123 sync_point1_(1),
124 sync_point2_(2),
125 shared_memory_(new base::SharedMemory) {
126 release_mailbox1_ = base::Bind(&MockMailboxCallback::Release,
127 base::Unretained(&mock_callback_),
128 mailbox_name1_);
129 release_mailbox2_ = base::Bind(&MockMailboxCallback::Release,
130 base::Unretained(&mock_callback_),
131 mailbox_name2_);
skyostil3976a3f2014-09-04 22:07:23132 release_mailbox1_impl_ = base::Bind(&MockMailboxCallback::ReleaseImpl,
133 base::Unretained(&mock_callback_),
134 mailbox_name1_);
135 release_mailbox2_impl_ = base::Bind(&MockMailboxCallback::ReleaseImpl,
136 base::Unretained(&mock_callback_),
137 mailbox_name2_);
[email protected]d72d9e02014-04-03 18:40:09138 const uint32 arbitrary_target1 = GL_TEXTURE_2D;
139 const uint32 arbitrary_target2 = GL_TEXTURE_EXTERNAL_OES;
140 mailbox1_ = TextureMailbox(mailbox_name1_, arbitrary_target1, sync_point1_);
141 mailbox2_ = TextureMailbox(mailbox_name2_, arbitrary_target2, sync_point2_);
142 gfx::Size size(128, 128);
143 EXPECT_TRUE(shared_memory_->CreateAndMapAnonymous(4 * size.GetArea()));
144 release_mailbox3_ = base::Bind(&MockMailboxCallback::Release2,
145 base::Unretained(&mock_callback_),
146 shared_memory_.get());
skyostil3976a3f2014-09-04 22:07:23147 release_mailbox3_impl_ = base::Bind(&MockMailboxCallback::ReleaseImpl2,
148 base::Unretained(&mock_callback_),
149 shared_memory_.get());
[email protected]d72d9e02014-04-03 18:40:09150 mailbox3_ = TextureMailbox(shared_memory_.get(), size);
151 }
152
153 gpu::Mailbox mailbox_name1_;
154 gpu::Mailbox mailbox_name2_;
155 MockMailboxCallback mock_callback_;
156 ReleaseCallback release_mailbox1_;
157 ReleaseCallback release_mailbox2_;
158 ReleaseCallback release_mailbox3_;
skyostil3976a3f2014-09-04 22:07:23159 ReleaseCallbackImpl release_mailbox1_impl_;
160 ReleaseCallbackImpl release_mailbox2_impl_;
161 ReleaseCallbackImpl release_mailbox3_impl_;
[email protected]d72d9e02014-04-03 18:40:09162 TextureMailbox mailbox1_;
163 TextureMailbox mailbox2_;
164 TextureMailbox mailbox3_;
165 uint32 sync_point1_;
166 uint32 sync_point2_;
167 scoped_ptr<base::SharedMemory> shared_memory_;
168};
169
[email protected]31d4df82013-07-18 10:17:22170class TextureLayerTest : public testing::Test {
171 public:
172 TextureLayerTest()
173 : fake_client_(
[email protected]4e2eb352014-03-20 17:25:45174 FakeLayerTreeHostClient(FakeLayerTreeHostClient::DIRECT_3D)),
175 host_impl_(&proxy_, &shared_bitmap_manager_) {}
[email protected]31d4df82013-07-18 10:17:22176
177 protected:
178 virtual void SetUp() {
179 layer_tree_host_.reset(new MockLayerTreeHost(&fake_client_));
[email protected]d72d9e02014-04-03 18:40:09180 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
181 layer_tree_host_->SetViewportSize(gfx::Size(10, 10));
182 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
[email protected]31d4df82013-07-18 10:17:22183 }
184
185 virtual void TearDown() {
186 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
[email protected]31d4df82013-07-18 10:17:22187 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
188
kulkarni.a4015690f12014-10-10 13:50:06189 layer_tree_host_->SetRootLayer(nullptr);
danakjf446a072014-09-27 21:55:48190 layer_tree_host_ = nullptr;
[email protected]31d4df82013-07-18 10:17:22191 }
192
193 scoped_ptr<MockLayerTreeHost> layer_tree_host_;
194 FakeImplProxy proxy_;
195 FakeLayerTreeHostClient fake_client_;
[email protected]4e2eb352014-03-20 17:25:45196 TestSharedBitmapManager shared_bitmap_manager_;
[email protected]31d4df82013-07-18 10:17:22197 FakeLayerTreeHostImpl host_impl_;
198};
199
[email protected]31d4df82013-07-18 10:17:22200TEST_F(TextureLayerTest, CheckPropertyChangeCausesCorrectBehavior) {
kulkarni.a4015690f12014-10-10 13:50:06201 scoped_refptr<TextureLayer> test_layer =
202 TextureLayer::CreateForMailbox(nullptr);
[email protected]80d42bd2013-08-30 19:13:45203 EXPECT_SET_NEEDS_COMMIT(1, layer_tree_host_->SetRootLayer(test_layer));
[email protected]31d4df82013-07-18 10:17:22204
205 // Test properties that should call SetNeedsCommit. All properties need to
206 // be set to new values in order for SetNeedsCommit to be called.
207 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetFlipped(false));
208 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetUV(
209 gfx::PointF(0.25f, 0.25f), gfx::PointF(0.75f, 0.75f)));
210 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetVertexOpacity(
211 0.5f, 0.5f, 0.5f, 0.5f));
212 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetPremultipliedAlpha(false));
213 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetBlendBackgroundColor(true));
[email protected]31d4df82013-07-18 10:17:22214}
215
[email protected]1c10e232013-07-31 12:35:43216TEST_F(TextureLayerTest, VisibleContentOpaqueRegion) {
217 const gfx::Size layer_bounds(100, 100);
218 const gfx::Rect layer_rect(layer_bounds);
219 const Region layer_region(layer_rect);
220
kulkarni.a4015690f12014-10-10 13:50:06221 scoped_refptr<TextureLayer> layer = TextureLayer::CreateForMailbox(nullptr);
[email protected]1c10e232013-07-31 12:35:43222 layer->SetBounds(layer_bounds);
223 layer->draw_properties().visible_content_rect = layer_rect;
224 layer->SetBlendBackgroundColor(true);
225
226 // Verify initial conditions.
227 EXPECT_FALSE(layer->contents_opaque());
228 EXPECT_EQ(0u, layer->background_color());
229 EXPECT_EQ(Region().ToString(),
230 layer->VisibleContentOpaqueRegion().ToString());
231
232 // Opaque background.
233 layer->SetBackgroundColor(SK_ColorWHITE);
234 EXPECT_EQ(layer_region.ToString(),
235 layer->VisibleContentOpaqueRegion().ToString());
236
237 // Transparent background.
238 layer->SetBackgroundColor(SkColorSetARGB(100, 255, 255, 255));
239 EXPECT_EQ(Region().ToString(),
240 layer->VisibleContentOpaqueRegion().ToString());
241}
242
[email protected]31d4df82013-07-18 10:17:22243TEST_F(TextureLayerTest, RateLimiter) {
244 FakeTextureLayerClient client;
245 scoped_refptr<TextureLayer> test_layer = TextureLayer::CreateForMailbox(
246 &client);
247 test_layer->SetIsDrawable(true);
248 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
249 layer_tree_host_->SetRootLayer(test_layer);
250
251 // Don't rate limit until we invalidate.
[email protected]aeeb3372013-11-05 14:05:54252 EXPECT_CALL(*layer_tree_host_, StartRateLimiter()).Times(0);
[email protected]31d4df82013-07-18 10:17:22253 test_layer->SetRateLimitContext(true);
254 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
255
256 // Do rate limit after we invalidate.
[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 don't want it any more.
[email protected]aeeb3372013-11-05 14:05:54262 EXPECT_CALL(*layer_tree_host_, StopRateLimiter());
[email protected]31d4df82013-07-18 10:17:22263 test_layer->SetRateLimitContext(false);
264 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
265
266 // Or we clear the client.
267 test_layer->SetRateLimitContext(true);
[email protected]aeeb3372013-11-05 14:05:54268 EXPECT_CALL(*layer_tree_host_, StopRateLimiter());
[email protected]31d4df82013-07-18 10:17:22269 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
270 test_layer->ClearClient();
271 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
272
273 // Reset to a layer with a client, that started the rate limiter.
274 test_layer = TextureLayer::CreateForMailbox(
275 &client);
276 test_layer->SetIsDrawable(true);
277 test_layer->SetRateLimitContext(true);
278 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
279 layer_tree_host_->SetRootLayer(test_layer);
[email protected]aeeb3372013-11-05 14:05:54280 EXPECT_CALL(*layer_tree_host_, StartRateLimiter()).Times(0);
[email protected]31d4df82013-07-18 10:17:22281 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
[email protected]aeeb3372013-11-05 14:05:54282 EXPECT_CALL(*layer_tree_host_, StartRateLimiter());
[email protected]31d4df82013-07-18 10:17:22283 test_layer->SetNeedsDisplay();
284 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
285
286 // Stop rate limiter when we're removed from the tree.
[email protected]aeeb3372013-11-05 14:05:54287 EXPECT_CALL(*layer_tree_host_, StopRateLimiter());
[email protected]d72d9e02014-04-03 18:40:09288 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1);
kulkarni.a4015690f12014-10-10 13:50:06289 layer_tree_host_->SetRootLayer(nullptr);
[email protected]31d4df82013-07-18 10:17:22290 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
291}
292
[email protected]df41e252014-02-03 23:39:50293class TestMailboxHolder : public TextureLayer::TextureMailboxHolder {
[email protected]9794fb32013-08-29 09:49:59294 public:
[email protected]df41e252014-02-03 23:39:50295 using TextureLayer::TextureMailboxHolder::Create;
[email protected]9794fb32013-08-29 09:49:59296
297 protected:
dcheng716bedf2014-10-21 09:51:08298 ~TestMailboxHolder() override {}
[email protected]9794fb32013-08-29 09:49:59299};
300
[email protected]de44a152013-01-08 15:28:46301class TextureLayerWithMailboxTest : public TextureLayerTest {
[email protected]28571b042013-03-14 07:59:15302 protected:
303 virtual void TearDown() {
304 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
305 EXPECT_CALL(test_data_.mock_callback_,
306 Release(test_data_.mailbox_name1_,
[email protected]7ba3ca72013-04-11 06:37:25307 test_data_.sync_point1_,
308 false)).Times(1);
[email protected]28571b042013-03-14 07:59:15309 TextureLayerTest::TearDown();
310 }
[email protected]de44a152013-01-08 15:28:46311
[email protected]28571b042013-03-14 07:59:15312 CommonMailboxObjects test_data_;
[email protected]de44a152013-01-08 15:28:46313};
314
[email protected]28571b042013-03-14 07:59:15315TEST_F(TextureLayerWithMailboxTest, ReplaceMailboxOnMainThreadBeforeCommit) {
kulkarni.a4015690f12014-10-10 13:50:06316 scoped_refptr<TextureLayer> test_layer =
317 TextureLayer::CreateForMailbox(nullptr);
[email protected]22898ed2013-06-01 04:52:30318 ASSERT_TRUE(test_layer.get());
[email protected]de44a152013-01-08 15:28:46319
[email protected]28571b042013-03-14 07:59:15320 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
321 layer_tree_host_->SetRootLayer(test_layer);
322 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
[email protected]de44a152013-01-08 15:28:46323
[email protected]28571b042013-03-14 07:59:15324 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
[email protected]9260757f2013-09-17 01:24:16325 test_layer->SetTextureMailbox(
326 test_data_.mailbox1_,
327 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
[email protected]28571b042013-03-14 07:59:15328 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
[email protected]de44a152013-01-08 15:28:46329
[email protected]28571b042013-03-14 07:59:15330 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
331 EXPECT_CALL(test_data_.mock_callback_,
[email protected]7ba3ca72013-04-11 06:37:25332 Release(test_data_.mailbox_name1_,
333 test_data_.sync_point1_,
334 false))
[email protected]28571b042013-03-14 07:59:15335 .Times(1);
[email protected]9260757f2013-09-17 01:24:16336 test_layer->SetTextureMailbox(
337 test_data_.mailbox2_,
338 SingleReleaseCallback::Create(test_data_.release_mailbox2_));
[email protected]28571b042013-03-14 07:59:15339 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
340 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]de44a152013-01-08 15:28:46341
[email protected]28571b042013-03-14 07:59:15342 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
343 EXPECT_CALL(test_data_.mock_callback_,
[email protected]7ba3ca72013-04-11 06:37:25344 Release(test_data_.mailbox_name2_,
345 test_data_.sync_point2_,
346 false))
[email protected]28571b042013-03-14 07:59:15347 .Times(1);
danakj968153f32014-10-15 22:52:16348 test_layer->SetTextureMailbox(TextureMailbox(), nullptr);
[email protected]28571b042013-03-14 07:59:15349 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
350 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]de44a152013-01-08 15:28:46351
[email protected]80d42bd2013-08-30 19:13:45352 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
[email protected]9260757f2013-09-17 01:24:16353 test_layer->SetTextureMailbox(
354 test_data_.mailbox3_,
355 SingleReleaseCallback::Create(test_data_.release_mailbox3_));
[email protected]42f40a52013-06-08 04:38:51356 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
357 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
358
[email protected]42f40a52013-06-08 04:38:51359 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
360 EXPECT_CALL(test_data_.mock_callback_,
361 Release2(test_data_.shared_memory_.get(),
362 0, false))
363 .Times(1);
danakj968153f32014-10-15 22:52:16364 test_layer->SetTextureMailbox(TextureMailbox(), nullptr);
[email protected]42f40a52013-06-08 04:38:51365 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
366 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
367
[email protected]28571b042013-03-14 07:59:15368 // Test destructor.
369 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
[email protected]9260757f2013-09-17 01:24:16370 test_layer->SetTextureMailbox(
371 test_data_.mailbox1_,
372 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
[email protected]de44a152013-01-08 15:28:46373}
374
[email protected]f9e8f452014-03-07 22:09:40375TEST_F(TextureLayerTest, SetTextureMailboxWithoutReleaseCallback) {
kulkarni.a4015690f12014-10-10 13:50:06376 scoped_refptr<TextureLayer> test_layer =
377 TextureLayer::CreateForMailbox(nullptr);
[email protected]f9e8f452014-03-07 22:09:40378 ASSERT_TRUE(test_layer.get());
379
380 // These use the same gpu::Mailbox, but different sync points.
381 TextureMailbox mailbox1(MailboxFromChar('a'), GL_TEXTURE_2D, 1);
382 TextureMailbox mailbox2(MailboxFromChar('a'), GL_TEXTURE_2D, 2);
383
[email protected]f9e8f452014-03-07 22:09:40384 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
385 layer_tree_host_->SetRootLayer(test_layer);
386 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
387
388 // Set the mailbox the first time. It should cause a commit.
[email protected]f9e8f452014-03-07 22:09:40389 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
390 test_layer->SetTextureMailboxWithoutReleaseCallback(mailbox1);
391 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
392
393 // Set the mailbox again with a new sync point, as the backing texture has
394 // been updated. It should cause a new commit.
[email protected]f9e8f452014-03-07 22:09:40395 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
396 test_layer->SetTextureMailboxWithoutReleaseCallback(mailbox2);
397 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
398}
399
[email protected]9794fb32013-08-29 09:49:59400class TextureLayerMailboxHolderTest : public TextureLayerTest {
401 public:
402 TextureLayerMailboxHolderTest()
403 : main_thread_("MAIN") {
404 main_thread_.Start();
skyostil3976a3f2014-09-04 22:07:23405 main_thread_.message_loop()->PostTask(
406 FROM_HERE,
407 base::Bind(&TextureLayerMailboxHolderTest::InitializeOnMain,
408 base::Unretained(this)));
409 Wait(main_thread_);
[email protected]9794fb32013-08-29 09:49:59410 }
411
412 void Wait(const base::Thread& thread) {
413 bool manual_reset = false;
414 bool initially_signaled = false;
415 base::WaitableEvent event(manual_reset, initially_signaled);
416 thread.message_loop()->PostTask(
417 FROM_HERE,
418 base::Bind(&base::WaitableEvent::Signal, base::Unretained(&event)));
419 event.Wait();
420 }
421
422 void CreateMainRef() {
423 main_ref_ = TestMailboxHolder::Create(
[email protected]9260757f2013-09-17 01:24:16424 test_data_.mailbox1_,
425 SingleReleaseCallback::Create(test_data_.release_mailbox1_)).Pass();
[email protected]9794fb32013-08-29 09:49:59426 }
427
danakjf446a072014-09-27 21:55:48428 void ReleaseMainRef() { main_ref_ = nullptr; }
[email protected]9794fb32013-08-29 09:49:59429
skyostil3976a3f2014-09-04 22:07:23430 void CreateImplRef(scoped_ptr<SingleReleaseCallbackImpl>* impl_ref) {
[email protected]9794fb32013-08-29 09:49:59431 *impl_ref = main_ref_->holder()->GetCallbackForImplThread();
432 }
433
434 void CapturePostTasksAndWait(base::WaitableEvent* begin_capture,
435 base::WaitableEvent* wait_for_capture,
436 base::WaitableEvent* stop_capture) {
437 begin_capture->Wait();
skyostil3976a3f2014-09-04 22:07:23438 BlockingTaskRunner::CapturePostTasks capture(
439 main_thread_task_runner_.get());
[email protected]9794fb32013-08-29 09:49:59440 wait_for_capture->Signal();
441 stop_capture->Wait();
442 }
443
444 protected:
skyostil3976a3f2014-09-04 22:07:23445 void InitializeOnMain() {
446 main_thread_task_runner_ =
447 BlockingTaskRunner::Create(main_thread_.message_loop_proxy());
448 }
449
[email protected]9794fb32013-08-29 09:49:59450 scoped_ptr<TestMailboxHolder::MainThreadReference>
451 main_ref_;
452 base::Thread main_thread_;
skyostil3976a3f2014-09-04 22:07:23453 scoped_ptr<BlockingTaskRunner> main_thread_task_runner_;
[email protected]9794fb32013-08-29 09:49:59454 CommonMailboxObjects test_data_;
455};
456
457TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_BothReleaseThenMain) {
kulkarni.a4015690f12014-10-10 13:50:06458 scoped_refptr<TextureLayer> test_layer =
459 TextureLayer::CreateForMailbox(nullptr);
[email protected]9794fb32013-08-29 09:49:59460 ASSERT_TRUE(test_layer.get());
461
462 main_thread_.message_loop()->PostTask(
463 FROM_HERE,
464 base::Bind(&TextureLayerMailboxHolderTest::CreateMainRef,
465 base::Unretained(this)));
466
467 Wait(main_thread_);
468
469 // The texture layer is attached to compositor1, and passes a reference to its
470 // impl tree.
skyostil3976a3f2014-09-04 22:07:23471 scoped_ptr<SingleReleaseCallbackImpl> compositor1;
[email protected]9794fb32013-08-29 09:49:59472 main_thread_.message_loop()->PostTask(
473 FROM_HERE,
474 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
475 base::Unretained(this),
476 &compositor1));
477
478 // Then the texture layer is removed and attached to compositor2, and passes a
479 // reference to its impl tree.
skyostil3976a3f2014-09-04 22:07:23480 scoped_ptr<SingleReleaseCallbackImpl> compositor2;
[email protected]9794fb32013-08-29 09:49:59481 main_thread_.message_loop()->PostTask(
482 FROM_HERE,
483 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
484 base::Unretained(this),
485 &compositor2));
486
487 Wait(main_thread_);
488 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
489
490 // The compositors both destroy their impl trees before the main thread layer
491 // is destroyed.
skyostil3976a3f2014-09-04 22:07:23492 compositor1->Run(100, false, main_thread_task_runner_.get());
493 compositor2->Run(200, false, main_thread_task_runner_.get());
[email protected]9794fb32013-08-29 09:49:59494
495 Wait(main_thread_);
496
497 EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0);
498 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
499
500 // The main thread ref is the last one, so the mailbox is released back to the
501 // embedder, with the last sync point provided by the impl trees.
502 EXPECT_CALL(test_data_.mock_callback_,
503 Release(test_data_.mailbox_name1_, 200, false)).Times(1);
504
505 main_thread_.message_loop()->PostTask(
506 FROM_HERE,
507 base::Bind(&TextureLayerMailboxHolderTest::ReleaseMainRef,
508 base::Unretained(this)));
509 Wait(main_thread_);
510 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
511}
512
513TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_MainReleaseBetween) {
kulkarni.a4015690f12014-10-10 13:50:06514 scoped_refptr<TextureLayer> test_layer =
515 TextureLayer::CreateForMailbox(nullptr);
[email protected]9794fb32013-08-29 09:49:59516 ASSERT_TRUE(test_layer.get());
517
518 main_thread_.message_loop()->PostTask(
519 FROM_HERE,
520 base::Bind(&TextureLayerMailboxHolderTest::CreateMainRef,
521 base::Unretained(this)));
522
523 Wait(main_thread_);
524
525 // The texture layer is attached to compositor1, and passes a reference to its
526 // impl tree.
skyostil3976a3f2014-09-04 22:07:23527 scoped_ptr<SingleReleaseCallbackImpl> compositor1;
[email protected]9794fb32013-08-29 09:49:59528 main_thread_.message_loop()->PostTask(
529 FROM_HERE,
530 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
531 base::Unretained(this),
532 &compositor1));
533
534 // Then the texture layer is removed and attached to compositor2, and passes a
535 // reference to its impl tree.
skyostil3976a3f2014-09-04 22:07:23536 scoped_ptr<SingleReleaseCallbackImpl> compositor2;
[email protected]9794fb32013-08-29 09:49:59537 main_thread_.message_loop()->PostTask(
538 FROM_HERE,
539 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
540 base::Unretained(this),
541 &compositor2));
542
543 Wait(main_thread_);
544 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
545
546 // One compositor destroys their impl tree.
skyostil3976a3f2014-09-04 22:07:23547 compositor1->Run(100, false, main_thread_task_runner_.get());
[email protected]9794fb32013-08-29 09:49:59548
549 // Then the main thread reference is destroyed.
550 main_thread_.message_loop()->PostTask(
551 FROM_HERE,
552 base::Bind(&TextureLayerMailboxHolderTest::ReleaseMainRef,
553 base::Unretained(this)));
554
555 Wait(main_thread_);
556
557 EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0);
558 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
559
560 // The second impl reference is destroyed last, causing the mailbox to be
561 // released back to the embedder with the last sync point from the impl tree.
562 EXPECT_CALL(test_data_.mock_callback_,
563 Release(test_data_.mailbox_name1_, 200, true)).Times(1);
564
skyostil3976a3f2014-09-04 22:07:23565 compositor2->Run(200, true, main_thread_task_runner_.get());
[email protected]9794fb32013-08-29 09:49:59566 Wait(main_thread_);
567 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
568}
569
570TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_MainReleasedFirst) {
kulkarni.a4015690f12014-10-10 13:50:06571 scoped_refptr<TextureLayer> test_layer =
572 TextureLayer::CreateForMailbox(nullptr);
[email protected]9794fb32013-08-29 09:49:59573 ASSERT_TRUE(test_layer.get());
574
575 main_thread_.message_loop()->PostTask(
576 FROM_HERE,
577 base::Bind(&TextureLayerMailboxHolderTest::CreateMainRef,
578 base::Unretained(this)));
579
580 Wait(main_thread_);
581
582 // The texture layer is attached to compositor1, and passes a reference to its
583 // impl tree.
skyostil3976a3f2014-09-04 22:07:23584 scoped_ptr<SingleReleaseCallbackImpl> compositor1;
[email protected]9794fb32013-08-29 09:49:59585 main_thread_.message_loop()->PostTask(
586 FROM_HERE,
587 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
588 base::Unretained(this),
589 &compositor1));
590
591 // Then the texture layer is removed and attached to compositor2, and passes a
592 // reference to its impl tree.
skyostil3976a3f2014-09-04 22:07:23593 scoped_ptr<SingleReleaseCallbackImpl> compositor2;
[email protected]9794fb32013-08-29 09:49:59594 main_thread_.message_loop()->PostTask(
595 FROM_HERE,
596 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
597 base::Unretained(this),
598 &compositor2));
599
600 Wait(main_thread_);
601 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
602
603 // The main thread reference is destroyed first.
604 main_thread_.message_loop()->PostTask(
605 FROM_HERE,
606 base::Bind(&TextureLayerMailboxHolderTest::ReleaseMainRef,
607 base::Unretained(this)));
608
609 // One compositor destroys their impl tree.
skyostil3976a3f2014-09-04 22:07:23610 compositor2->Run(200, false, main_thread_task_runner_.get());
[email protected]9794fb32013-08-29 09:49:59611
612 Wait(main_thread_);
613
614 EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0);
615 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
616
617 // The second impl reference is destroyed last, causing the mailbox to be
618 // released back to the embedder with the last sync point from the impl tree.
619 EXPECT_CALL(test_data_.mock_callback_,
620 Release(test_data_.mailbox_name1_, 100, true)).Times(1);
621
skyostil3976a3f2014-09-04 22:07:23622 compositor1->Run(100, true, main_thread_task_runner_.get());
[email protected]9794fb32013-08-29 09:49:59623 Wait(main_thread_);
624 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
625}
626
627TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_SecondImplRefShortcut) {
kulkarni.a4015690f12014-10-10 13:50:06628 scoped_refptr<TextureLayer> test_layer =
629 TextureLayer::CreateForMailbox(nullptr);
[email protected]9794fb32013-08-29 09:49:59630 ASSERT_TRUE(test_layer.get());
631
632 main_thread_.message_loop()->PostTask(
633 FROM_HERE,
634 base::Bind(&TextureLayerMailboxHolderTest::CreateMainRef,
635 base::Unretained(this)));
636
637 Wait(main_thread_);
638
639 // The texture layer is attached to compositor1, and passes a reference to its
640 // impl tree.
skyostil3976a3f2014-09-04 22:07:23641 scoped_ptr<SingleReleaseCallbackImpl> compositor1;
[email protected]9794fb32013-08-29 09:49:59642 main_thread_.message_loop()->PostTask(
643 FROM_HERE,
644 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
645 base::Unretained(this),
646 &compositor1));
647
648 // Then the texture layer is removed and attached to compositor2, and passes a
649 // reference to its impl tree.
skyostil3976a3f2014-09-04 22:07:23650 scoped_ptr<SingleReleaseCallbackImpl> compositor2;
[email protected]9794fb32013-08-29 09:49:59651 main_thread_.message_loop()->PostTask(
652 FROM_HERE,
653 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
654 base::Unretained(this),
655 &compositor2));
656
657 Wait(main_thread_);
658 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
659
660 // The main thread reference is destroyed first.
661 main_thread_.message_loop()->PostTask(
662 FROM_HERE,
663 base::Bind(&TextureLayerMailboxHolderTest::ReleaseMainRef,
664 base::Unretained(this)));
665
666 EXPECT_CALL(test_data_.mock_callback_,
667 Release(test_data_.mailbox_name1_, 200, true)).Times(1);
668
669 bool manual_reset = false;
670 bool initially_signaled = false;
671 base::WaitableEvent begin_capture(manual_reset, initially_signaled);
672 base::WaitableEvent wait_for_capture(manual_reset, initially_signaled);
673 base::WaitableEvent stop_capture(manual_reset, initially_signaled);
674
675 // Post a task to start capturing tasks on the main thread. This will block
676 // the main thread until we signal the |stop_capture| event.
677 main_thread_.message_loop()->PostTask(
678 FROM_HERE,
679 base::Bind(&TextureLayerMailboxHolderTest::CapturePostTasksAndWait,
680 base::Unretained(this),
681 &begin_capture,
682 &wait_for_capture,
683 &stop_capture));
684
685 // Before the main thread capturing starts, one compositor destroys their
686 // impl reference. Since capturing did not start, this gets post-tasked to
687 // the main thread.
skyostil3976a3f2014-09-04 22:07:23688 compositor1->Run(100, false, main_thread_task_runner_.get());
[email protected]9794fb32013-08-29 09:49:59689
690 // Start capturing on the main thread.
691 begin_capture.Signal();
692 wait_for_capture.Wait();
693
694 // Meanwhile, the second compositor released its impl reference, but this task
695 // gets shortcutted directly to the main thread. This means the reference is
696 // released before compositor1, whose reference will be released later when
697 // the post-task is serviced. But since it was destroyed _on the impl thread_
698 // last, its sync point values should be used.
skyostil3976a3f2014-09-04 22:07:23699 compositor2->Run(200, true, main_thread_task_runner_.get());
[email protected]9794fb32013-08-29 09:49:59700
701 stop_capture.Signal();
702 Wait(main_thread_);
703
704 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
705}
706
[email protected]e216fef02013-03-20 22:56:10707class TextureLayerImplWithMailboxThreadedCallback : public LayerTreeTest {
[email protected]28571b042013-03-14 07:59:15708 public:
709 TextureLayerImplWithMailboxThreadedCallback()
710 : callback_count_(0),
711 commit_count_(0) {}
712
713 // Make sure callback is received on main and doesn't block the impl thread.
[email protected]df41e252014-02-03 23:39:50714 void ReleaseCallback(uint32 sync_point, bool lost_resource) {
[email protected]9794fb32013-08-29 09:49:59715 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]7ba3ca72013-04-11 06:37:25716 EXPECT_FALSE(lost_resource);
[email protected]28571b042013-03-14 07:59:15717 ++callback_count_;
718 }
719
720 void SetMailbox(char mailbox_char) {
[email protected]9794fb32013-08-29 09:49:59721 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]9260757f2013-09-17 01:24:16722 scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create(
[email protected]28571b042013-03-14 07:59:15723 base::Bind(
724 &TextureLayerImplWithMailboxThreadedCallback::ReleaseCallback,
725 base::Unretained(this)));
[email protected]df41e252014-02-03 23:39:50726 layer_->SetTextureMailbox(
[email protected]e0a4d732014-02-15 00:23:26727 TextureMailbox(MailboxFromChar(mailbox_char), GL_TEXTURE_2D, 0),
[email protected]df41e252014-02-03 23:39:50728 callback.Pass());
[email protected]28571b042013-03-14 07:59:15729 }
730
dcheng716bedf2014-10-21 09:51:08731 void BeginTest() override {
[email protected]9794fb32013-08-29 09:49:59732 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
733
[email protected]28571b042013-03-14 07:59:15734 gfx::Size bounds(100, 100);
735 root_ = Layer::Create();
[email protected]28571b042013-03-14 07:59:15736 root_->SetBounds(bounds);
737
kulkarni.a4015690f12014-10-10 13:50:06738 layer_ = TextureLayer::CreateForMailbox(nullptr);
[email protected]28571b042013-03-14 07:59:15739 layer_->SetIsDrawable(true);
[email protected]28571b042013-03-14 07:59:15740 layer_->SetBounds(bounds);
741
742 root_->AddChild(layer_);
[email protected]e216fef02013-03-20 22:56:10743 layer_tree_host()->SetRootLayer(root_);
[email protected]18ce59702013-04-09 04:58:40744 layer_tree_host()->SetViewportSize(bounds);
[email protected]28571b042013-03-14 07:59:15745 SetMailbox('1');
746 EXPECT_EQ(0, callback_count_);
747
748 // Case #1: change mailbox before the commit. The old mailbox should be
749 // released immediately.
750 SetMailbox('2');
751 EXPECT_EQ(1, callback_count_);
[email protected]e216fef02013-03-20 22:56:10752 PostSetNeedsCommitToMainThread();
[email protected]28571b042013-03-14 07:59:15753 }
754
dcheng716bedf2014-10-21 09:51:08755 void DidCommit() override {
[email protected]28571b042013-03-14 07:59:15756 ++commit_count_;
757 switch (commit_count_) {
758 case 1:
759 // Case #2: change mailbox after the commit (and draw), where the
760 // layer draws. The old mailbox should be released during the next
761 // commit.
762 SetMailbox('3');
763 EXPECT_EQ(1, callback_count_);
764 break;
765 case 2:
[email protected]28571b042013-03-14 07:59:15766 EXPECT_EQ(2, callback_count_);
767 // Case #3: change mailbox when the layer doesn't draw. The old
768 // mailbox should be released during the next commit.
769 layer_->SetBounds(gfx::Size());
770 SetMailbox('4');
771 break;
[email protected]9794fb32013-08-29 09:49:59772 case 3:
[email protected]28571b042013-03-14 07:59:15773 EXPECT_EQ(3, callback_count_);
774 // Case #4: release mailbox that was committed but never drawn. The
775 // old mailbox should be released during the next commit.
danakj968153f32014-10-15 22:52:16776 layer_->SetTextureMailbox(TextureMailbox(), nullptr);
[email protected]28571b042013-03-14 07:59:15777 break;
[email protected]9794fb32013-08-29 09:49:59778 case 4:
779 if (layer_tree_host()->settings().impl_side_painting) {
780 // With impl painting, the texture mailbox will still be on the impl
781 // thread when the commit finishes, because the layer is not drawble
782 // when it has no texture mailbox, and thus does not block the commit
783 // on activation. So, we wait for activation.
784 // TODO(danakj): fix this. crbug.com/277953
785 layer_tree_host()->SetNeedsCommit();
786 break;
787 } else {
788 ++commit_count_;
789 }
790 case 5:
[email protected]28571b042013-03-14 07:59:15791 EXPECT_EQ(4, callback_count_);
[email protected]7096acc2013-06-18 21:12:43792 // Restore a mailbox for the next step.
793 SetMailbox('5');
794 break;
[email protected]9794fb32013-08-29 09:49:59795 case 6:
[email protected]7096acc2013-06-18 21:12:43796 // Case #5: remove layer from tree. Callback should *not* be called, the
797 // mailbox is returned to the main thread.
798 EXPECT_EQ(4, callback_count_);
799 layer_->RemoveFromParent();
800 break;
[email protected]9794fb32013-08-29 09:49:59801 case 7:
802 if (layer_tree_host()->settings().impl_side_painting) {
803 // With impl painting, the texture mailbox will still be on the impl
804 // thread when the commit finishes, because the layer is not around to
805 // block the commit on activation anymore. So, we wait for activation.
806 // TODO(danakj): fix this. crbug.com/277953
807 layer_tree_host()->SetNeedsCommit();
808 break;
809 } else {
810 ++commit_count_;
811 }
812 case 8:
[email protected]7096acc2013-06-18 21:12:43813 EXPECT_EQ(4, callback_count_);
814 // Resetting the mailbox will call the callback now.
danakj968153f32014-10-15 22:52:16815 layer_->SetTextureMailbox(TextureMailbox(), nullptr);
[email protected]7096acc2013-06-18 21:12:43816 EXPECT_EQ(5, callback_count_);
[email protected]e216fef02013-03-20 22:56:10817 EndTest();
[email protected]28571b042013-03-14 07:59:15818 break;
819 default:
820 NOTREACHED();
821 break;
[email protected]de44a152013-01-08 15:28:46822 }
[email protected]28571b042013-03-14 07:59:15823 }
[email protected]de44a152013-01-08 15:28:46824
dcheng716bedf2014-10-21 09:51:08825 void AfterTest() override {}
[email protected]de44a152013-01-08 15:28:46826
[email protected]28571b042013-03-14 07:59:15827 private:
[email protected]9794fb32013-08-29 09:49:59828 base::ThreadChecker main_thread_;
[email protected]28571b042013-03-14 07:59:15829 int callback_count_;
830 int commit_count_;
831 scoped_refptr<Layer> root_;
832 scoped_refptr<TextureLayer> layer_;
[email protected]de44a152013-01-08 15:28:46833};
834
[email protected]4145d172013-05-10 16:54:36835SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
836 TextureLayerImplWithMailboxThreadedCallback);
[email protected]de44a152013-01-08 15:28:46837
[email protected]74b43cc2013-08-30 06:29:27838
[email protected]74b43cc2013-08-30 06:29:27839class TextureLayerMailboxIsActivatedDuringCommit : public LayerTreeTest {
840 protected:
[email protected]98ea818e2014-01-24 10:22:08841 TextureLayerMailboxIsActivatedDuringCommit() : activate_count_(0) {}
[email protected]74b43cc2013-08-30 06:29:27842
[email protected]df41e252014-02-03 23:39:50843 static void ReleaseCallback(uint32 sync_point, bool lost_resource) {}
[email protected]74b43cc2013-08-30 06:29:27844
845 void SetMailbox(char mailbox_char) {
[email protected]9260757f2013-09-17 01:24:16846 scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create(
[email protected]74b43cc2013-08-30 06:29:27847 base::Bind(
848 &TextureLayerMailboxIsActivatedDuringCommit::ReleaseCallback));
[email protected]df41e252014-02-03 23:39:50849 layer_->SetTextureMailbox(
[email protected]e0a4d732014-02-15 00:23:26850 TextureMailbox(MailboxFromChar(mailbox_char), GL_TEXTURE_2D, 0),
[email protected]df41e252014-02-03 23:39:50851 callback.Pass());
[email protected]74b43cc2013-08-30 06:29:27852 }
853
dcheng716bedf2014-10-21 09:51:08854 void BeginTest() override {
[email protected]74b43cc2013-08-30 06:29:27855 gfx::Size bounds(100, 100);
856 root_ = Layer::Create();
[email protected]74b43cc2013-08-30 06:29:27857 root_->SetBounds(bounds);
858
kulkarni.a4015690f12014-10-10 13:50:06859 layer_ = TextureLayer::CreateForMailbox(nullptr);
[email protected]74b43cc2013-08-30 06:29:27860 layer_->SetIsDrawable(true);
[email protected]74b43cc2013-08-30 06:29:27861 layer_->SetBounds(bounds);
862
863 root_->AddChild(layer_);
864 layer_tree_host()->SetRootLayer(root_);
865 layer_tree_host()->SetViewportSize(bounds);
866 SetMailbox('1');
867
868 PostSetNeedsCommitToMainThread();
869 }
870
dcheng716bedf2014-10-21 09:51:08871 void WillActivateTreeOnThread(LayerTreeHostImpl* impl) override {
[email protected]74b43cc2013-08-30 06:29:27872 ++activate_count_;
873 }
874
dcheng716bedf2014-10-21 09:51:08875 void DidCommit() override {
[email protected]98ea818e2014-01-24 10:22:08876 switch (layer_tree_host()->source_frame_number()) {
[email protected]74b43cc2013-08-30 06:29:27877 case 1:
878 // The first mailbox has been activated. Set a new mailbox, and
879 // expect the next commit to finish *after* it is activated.
880 SetMailbox('2');
[email protected]74b43cc2013-08-30 06:29:27881 break;
882 case 2:
883 // The second mailbox has been activated. Remove the layer from
884 // the tree to cause another commit/activation. The commit should
885 // finish *after* the layer is removed from the active tree.
886 layer_->RemoveFromParent();
[email protected]74b43cc2013-08-30 06:29:27887 break;
888 case 3:
889 EndTest();
890 break;
891 }
892 }
893
dcheng716bedf2014-10-21 09:51:08894 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
[email protected]98ea818e2014-01-24 10:22:08895 switch (host_impl->active_tree()->source_frame_number()) {
[email protected]b6061062014-06-27 19:20:08896 case 0: {
897 // The activate for the 1st mailbox should have happened before now.
898 EXPECT_EQ(1, activate_count_);
899 break;
900 }
901 case 1: {
[email protected]74b43cc2013-08-30 06:29:27902 // The activate for the 2nd mailbox should have happened before now.
[email protected]74b43cc2013-08-30 06:29:27903 EXPECT_EQ(2, activate_count_);
904 break;
905 }
[email protected]b6061062014-06-27 19:20:08906 case 2: {
[email protected]74b43cc2013-08-30 06:29:27907 // The activate to remove the layer should have happened before now.
[email protected]74b43cc2013-08-30 06:29:27908 EXPECT_EQ(3, activate_count_);
909 break;
910 }
[email protected]b6061062014-06-27 19:20:08911 case 3: {
912 NOTREACHED();
913 break;
914 }
[email protected]74b43cc2013-08-30 06:29:27915 }
916 }
917
dcheng716bedf2014-10-21 09:51:08918 void AfterTest() override {}
[email protected]74b43cc2013-08-30 06:29:27919
[email protected]74b43cc2013-08-30 06:29:27920 int activate_count_;
921 scoped_refptr<Layer> root_;
922 scoped_refptr<TextureLayer> layer_;
923};
924
925SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
926 TextureLayerMailboxIsActivatedDuringCommit);
927
[email protected]de44a152013-01-08 15:28:46928class TextureLayerImplWithMailboxTest : public TextureLayerTest {
[email protected]28571b042013-03-14 07:59:15929 protected:
[email protected]408b5e22013-03-19 09:48:09930 TextureLayerImplWithMailboxTest()
931 : fake_client_(
932 FakeLayerTreeHostClient(FakeLayerTreeHostClient::DIRECT_3D)) {}
933
[email protected]28571b042013-03-14 07:59:15934 virtual void SetUp() {
935 TextureLayerTest::SetUp();
[email protected]408b5e22013-03-19 09:48:09936 layer_tree_host_.reset(new MockLayerTreeHost(&fake_client_));
danakjf446a072014-09-27 21:55:48937 EXPECT_TRUE(host_impl_.InitializeRenderer(FakeOutputSurface::Create3d()));
[email protected]28571b042013-03-14 07:59:15938 }
[email protected]de44a152013-01-08 15:28:46939
[email protected]0ec335c42013-07-04 06:17:08940 bool WillDraw(TextureLayerImpl* layer, DrawMode mode) {
941 bool will_draw = layer->WillDraw(
942 mode, host_impl_.active_tree()->resource_provider());
943 if (will_draw)
944 layer->DidDraw(host_impl_.active_tree()->resource_provider());
945 return will_draw;
946 }
947
[email protected]28571b042013-03-14 07:59:15948 CommonMailboxObjects test_data_;
[email protected]408b5e22013-03-19 09:48:09949 FakeLayerTreeHostClient fake_client_;
[email protected]de44a152013-01-08 15:28:46950};
951
[email protected]ffbb2212013-06-02 23:47:59952// Test conditions for results of TextureLayerImpl::WillDraw under
953// different configurations of different mailbox, texture_id, and draw_mode.
954TEST_F(TextureLayerImplWithMailboxTest, TestWillDraw) {
skyostil3976a3f2014-09-04 22:07:23955 EXPECT_CALL(
956 test_data_.mock_callback_,
957 ReleaseImpl(test_data_.mailbox_name1_, test_data_.sync_point1_, false, _))
[email protected]0ec335c42013-07-04 06:17:08958 .Times(AnyNumber());
959 EXPECT_CALL(test_data_.mock_callback_,
skyostil3976a3f2014-09-04 22:07:23960 ReleaseImpl2(test_data_.shared_memory_.get(), 0, false, _))
[email protected]0ec335c42013-07-04 06:17:08961 .Times(AnyNumber());
[email protected]ffbb2212013-06-02 23:47:59962 // Hardware mode.
963 {
964 scoped_ptr<TextureLayerImpl> impl_layer =
[email protected]17e08432014-04-10 00:41:11965 TextureLayerImpl::Create(host_impl_.active_tree(), 1);
[email protected]9260757f2013-09-17 01:24:16966 impl_layer->SetTextureMailbox(
967 test_data_.mailbox1_,
skyostil3976a3f2014-09-04 22:07:23968 SingleReleaseCallbackImpl::Create(test_data_.release_mailbox1_impl_));
[email protected]0ec335c42013-07-04 06:17:08969 EXPECT_TRUE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE));
[email protected]ffbb2212013-06-02 23:47:59970 }
971
972 {
973 scoped_ptr<TextureLayerImpl> impl_layer =
[email protected]17e08432014-04-10 00:41:11974 TextureLayerImpl::Create(host_impl_.active_tree(), 1);
danakj968153f32014-10-15 22:52:16975 impl_layer->SetTextureMailbox(TextureMailbox(), nullptr);
[email protected]0ec335c42013-07-04 06:17:08976 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE));
977 }
978
979 {
980 // Software resource.
981 scoped_ptr<TextureLayerImpl> impl_layer =
[email protected]17e08432014-04-10 00:41:11982 TextureLayerImpl::Create(host_impl_.active_tree(), 1);
[email protected]9260757f2013-09-17 01:24:16983 impl_layer->SetTextureMailbox(
984 test_data_.mailbox3_,
skyostil3976a3f2014-09-04 22:07:23985 SingleReleaseCallbackImpl::Create(test_data_.release_mailbox3_impl_));
[email protected]3e44d7a2013-07-30 00:03:10986 EXPECT_TRUE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE));
[email protected]ffbb2212013-06-02 23:47:59987 }
988
[email protected]0ec335c42013-07-04 06:17:08989 // Software mode.
990 {
991 scoped_ptr<TextureLayerImpl> impl_layer =
[email protected]17e08432014-04-10 00:41:11992 TextureLayerImpl::Create(host_impl_.active_tree(), 1);
[email protected]9260757f2013-09-17 01:24:16993 impl_layer->SetTextureMailbox(
994 test_data_.mailbox1_,
skyostil3976a3f2014-09-04 22:07:23995 SingleReleaseCallbackImpl::Create(test_data_.release_mailbox1_impl_));
[email protected]0ec335c42013-07-04 06:17:08996 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE));
997 }
998
999 {
1000 scoped_ptr<TextureLayerImpl> impl_layer =
[email protected]17e08432014-04-10 00:41:111001 TextureLayerImpl::Create(host_impl_.active_tree(), 1);
danakj968153f32014-10-15 22:52:161002 impl_layer->SetTextureMailbox(TextureMailbox(), nullptr);
[email protected]0ec335c42013-07-04 06:17:081003 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE));
1004 }
1005
1006 {
1007 // Software resource.
1008 scoped_ptr<TextureLayerImpl> impl_layer =
[email protected]17e08432014-04-10 00:41:111009 TextureLayerImpl::Create(host_impl_.active_tree(), 1);
[email protected]9260757f2013-09-17 01:24:161010 impl_layer->SetTextureMailbox(
1011 test_data_.mailbox3_,
skyostil3976a3f2014-09-04 22:07:231012 SingleReleaseCallbackImpl::Create(test_data_.release_mailbox3_impl_));
[email protected]0ec335c42013-07-04 06:17:081013 EXPECT_TRUE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE));
1014 }
1015
[email protected]ffbb2212013-06-02 23:47:591016 // Resourceless software mode.
1017 {
1018 scoped_ptr<TextureLayerImpl> impl_layer =
[email protected]17e08432014-04-10 00:41:111019 TextureLayerImpl::Create(host_impl_.active_tree(), 1);
[email protected]9260757f2013-09-17 01:24:161020 impl_layer->SetTextureMailbox(
1021 test_data_.mailbox1_,
skyostil3976a3f2014-09-04 22:07:231022 SingleReleaseCallbackImpl::Create(test_data_.release_mailbox1_impl_));
[email protected]0ec335c42013-07-04 06:17:081023 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_RESOURCELESS_SOFTWARE));
[email protected]ffbb2212013-06-02 23:47:591024 }
[email protected]ffbb2212013-06-02 23:47:591025}
1026
[email protected]28571b042013-03-14 07:59:151027TEST_F(TextureLayerImplWithMailboxTest, TestImplLayerCallbacks) {
1028 host_impl_.CreatePendingTree();
1029 scoped_ptr<TextureLayerImpl> pending_layer;
[email protected]17e08432014-04-10 00:41:111030 pending_layer = TextureLayerImpl::Create(host_impl_.pending_tree(), 1);
[email protected]28571b042013-03-14 07:59:151031 ASSERT_TRUE(pending_layer);
[email protected]de44a152013-01-08 15:28:461032
[email protected]ed511b8d2013-03-25 03:29:291033 scoped_ptr<LayerImpl> active_layer(
[email protected]28571b042013-03-14 07:59:151034 pending_layer->CreateLayerImpl(host_impl_.active_tree()));
[email protected]ed511b8d2013-03-25 03:29:291035 ASSERT_TRUE(active_layer);
[email protected]de44a152013-01-08 15:28:461036
[email protected]9260757f2013-09-17 01:24:161037 pending_layer->SetTextureMailbox(
1038 test_data_.mailbox1_,
skyostil3976a3f2014-09-04 22:07:231039 SingleReleaseCallbackImpl::Create(test_data_.release_mailbox1_impl_));
[email protected]421e84f2013-02-22 03:27:151040
[email protected]28571b042013-03-14 07:59:151041 // Test multiple commits without an activation.
skyostil3976a3f2014-09-04 22:07:231042 EXPECT_CALL(
1043 test_data_.mock_callback_,
1044 ReleaseImpl(test_data_.mailbox_name1_, test_data_.sync_point1_, false, _))
[email protected]28571b042013-03-14 07:59:151045 .Times(1);
[email protected]9260757f2013-09-17 01:24:161046 pending_layer->SetTextureMailbox(
1047 test_data_.mailbox2_,
skyostil3976a3f2014-09-04 22:07:231048 SingleReleaseCallbackImpl::Create(test_data_.release_mailbox2_impl_));
[email protected]28571b042013-03-14 07:59:151049 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]421e84f2013-02-22 03:27:151050
[email protected]28571b042013-03-14 07:59:151051 // Test callback after activation.
[email protected]ed511b8d2013-03-25 03:29:291052 pending_layer->PushPropertiesTo(active_layer.get());
1053 active_layer->DidBecomeActive();
[email protected]421e84f2013-02-22 03:27:151054
skyostil3976a3f2014-09-04 22:07:231055 EXPECT_CALL(test_data_.mock_callback_, ReleaseImpl(_, _, _, _)).Times(0);
[email protected]9260757f2013-09-17 01:24:161056 pending_layer->SetTextureMailbox(
1057 test_data_.mailbox1_,
skyostil3976a3f2014-09-04 22:07:231058 SingleReleaseCallbackImpl::Create(test_data_.release_mailbox1_impl_));
[email protected]28571b042013-03-14 07:59:151059 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]421e84f2013-02-22 03:27:151060
[email protected]7ba3ca72013-04-11 06:37:251061 EXPECT_CALL(test_data_.mock_callback_,
skyostil3976a3f2014-09-04 22:07:231062 ReleaseImpl(test_data_.mailbox_name2_, _, false, _)).Times(1);
[email protected]ed511b8d2013-03-25 03:29:291063 pending_layer->PushPropertiesTo(active_layer.get());
1064 active_layer->DidBecomeActive();
[email protected]28571b042013-03-14 07:59:151065 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]de44a152013-01-08 15:28:461066
[email protected]28571b042013-03-14 07:59:151067 // Test resetting the mailbox.
[email protected]7ba3ca72013-04-11 06:37:251068 EXPECT_CALL(test_data_.mock_callback_,
skyostil3976a3f2014-09-04 22:07:231069 ReleaseImpl(test_data_.mailbox_name1_, _, false, _)).Times(1);
danakj968153f32014-10-15 22:52:161070 pending_layer->SetTextureMailbox(TextureMailbox(), nullptr);
[email protected]ed511b8d2013-03-25 03:29:291071 pending_layer->PushPropertiesTo(active_layer.get());
1072 active_layer->DidBecomeActive();
[email protected]28571b042013-03-14 07:59:151073 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]de44a152013-01-08 15:28:461074
[email protected]28571b042013-03-14 07:59:151075 // Test destructor.
skyostil3976a3f2014-09-04 22:07:231076 EXPECT_CALL(
1077 test_data_.mock_callback_,
1078 ReleaseImpl(test_data_.mailbox_name1_, test_data_.sync_point1_, false, _))
[email protected]28571b042013-03-14 07:59:151079 .Times(1);
[email protected]9260757f2013-09-17 01:24:161080 pending_layer->SetTextureMailbox(
1081 test_data_.mailbox1_,
skyostil3976a3f2014-09-04 22:07:231082 SingleReleaseCallbackImpl::Create(test_data_.release_mailbox1_impl_));
[email protected]de44a152013-01-08 15:28:461083}
1084
[email protected]28571b042013-03-14 07:59:151085TEST_F(TextureLayerImplWithMailboxTest,
1086 TestDestructorCallbackOnCreatedResource) {
1087 scoped_ptr<TextureLayerImpl> impl_layer;
[email protected]17e08432014-04-10 00:41:111088 impl_layer = TextureLayerImpl::Create(host_impl_.active_tree(), 1);
[email protected]28571b042013-03-14 07:59:151089 ASSERT_TRUE(impl_layer);
[email protected]de44a152013-01-08 15:28:461090
[email protected]7ba3ca72013-04-11 06:37:251091 EXPECT_CALL(test_data_.mock_callback_,
skyostil3976a3f2014-09-04 22:07:231092 ReleaseImpl(test_data_.mailbox_name1_, _, false, _)).Times(1);
[email protected]9260757f2013-09-17 01:24:161093 impl_layer->SetTextureMailbox(
1094 test_data_.mailbox1_,
skyostil3976a3f2014-09-04 22:07:231095 SingleReleaseCallbackImpl::Create(test_data_.release_mailbox1_impl_));
[email protected]ffbb2212013-06-02 23:47:591096 impl_layer->DidBecomeActive();
1097 EXPECT_TRUE(impl_layer->WillDraw(
1098 DRAW_MODE_HARDWARE, host_impl_.active_tree()->resource_provider()));
[email protected]28571b042013-03-14 07:59:151099 impl_layer->DidDraw(host_impl_.active_tree()->resource_provider());
danakj968153f32014-10-15 22:52:161100 impl_layer->SetTextureMailbox(TextureMailbox(), nullptr);
[email protected]de44a152013-01-08 15:28:461101}
1102
[email protected]28571b042013-03-14 07:59:151103TEST_F(TextureLayerImplWithMailboxTest, TestCallbackOnInUseResource) {
1104 ResourceProvider* provider = host_impl_.active_tree()->resource_provider();
skyostil3976a3f2014-09-04 22:07:231105 ResourceProvider::ResourceId id = provider->CreateResourceFromTextureMailbox(
1106 test_data_.mailbox1_,
1107 SingleReleaseCallbackImpl::Create(test_data_.release_mailbox1_impl_));
[email protected]28571b042013-03-14 07:59:151108 provider->AllocateForTesting(id);
[email protected]de44a152013-01-08 15:28:461109
[email protected]28571b042013-03-14 07:59:151110 // Transfer some resources to the parent.
1111 ResourceProvider::ResourceIdArray resource_ids_to_transfer;
1112 resource_ids_to_transfer.push_back(id);
1113 TransferableResourceArray list;
1114 provider->PrepareSendToParent(resource_ids_to_transfer, &list);
1115 EXPECT_TRUE(provider->InUseByConsumer(id));
skyostil3976a3f2014-09-04 22:07:231116 EXPECT_CALL(test_data_.mock_callback_, ReleaseImpl(_, _, _, _)).Times(0);
[email protected]28571b042013-03-14 07:59:151117 provider->DeleteResource(id);
1118 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]7ba3ca72013-04-11 06:37:251119 EXPECT_CALL(test_data_.mock_callback_,
skyostil3976a3f2014-09-04 22:07:231120 ReleaseImpl(test_data_.mailbox_name1_, _, false, _)).Times(1);
[email protected]e00bab022013-08-19 00:42:451121 ReturnedResourceArray returned;
1122 TransferableResource::ReturnResources(list, &returned);
1123 provider->ReceiveReturnsFromParent(returned);
[email protected]de44a152013-01-08 15:28:461124}
1125
[email protected]4bad8b62013-10-24 01:27:291126// Checks that TextureLayer::Update does not cause an extra commit when setting
1127// the texture mailbox.
1128class TextureLayerNoExtraCommitForMailboxTest
1129 : public LayerTreeTest,
1130 public TextureLayerClient {
1131 public:
[email protected]4bad8b62013-10-24 01:27:291132 // TextureLayerClient implementation.
dcheng716bedf2014-10-21 09:51:081133 bool PrepareTextureMailbox(
[email protected]df41e252014-02-03 23:39:501134 TextureMailbox* texture_mailbox,
[email protected]4bad8b62013-10-24 01:27:291135 scoped_ptr<SingleReleaseCallback>* release_callback,
mostynbf68776d82014-10-06 18:07:371136 bool use_shared_memory) override {
[email protected]cce34bd2013-12-02 23:24:451137 if (layer_tree_host()->source_frame_number() == 1) {
[email protected]9f35bd22014-06-03 15:25:461138 // Once this has been committed, the mailbox will be released.
[email protected]df41e252014-02-03 23:39:501139 *texture_mailbox = TextureMailbox();
[email protected]cce34bd2013-12-02 23:24:451140 return true;
1141 }
[email protected]4bad8b62013-10-24 01:27:291142
[email protected]e0a4d732014-02-15 00:23:261143 *texture_mailbox = TextureMailbox(MailboxFromChar('1'), GL_TEXTURE_2D, 0);
[email protected]4bad8b62013-10-24 01:27:291144 *release_callback = SingleReleaseCallback::Create(
1145 base::Bind(&TextureLayerNoExtraCommitForMailboxTest::MailboxReleased,
1146 base::Unretained(this)));
[email protected]4bad8b62013-10-24 01:27:291147 return true;
1148 }
1149
[email protected]df41e252014-02-03 23:39:501150 void MailboxReleased(uint32 sync_point, bool lost_resource) {
[email protected]9f35bd22014-06-03 15:25:461151 // Source frame number during callback is the same as the source frame
1152 // on which it was released.
1153 EXPECT_EQ(1, layer_tree_host()->source_frame_number());
[email protected]cce34bd2013-12-02 23:24:451154 EndTest();
[email protected]4bad8b62013-10-24 01:27:291155 }
1156
dcheng716bedf2014-10-21 09:51:081157 void SetupTree() override {
[email protected]4bad8b62013-10-24 01:27:291158 scoped_refptr<Layer> root = Layer::Create();
1159 root->SetBounds(gfx::Size(10, 10));
[email protected]4bad8b62013-10-24 01:27:291160 root->SetIsDrawable(true);
1161
[email protected]4bad8b62013-10-24 01:27:291162 texture_layer_ = TextureLayer::CreateForMailbox(this);
1163 texture_layer_->SetBounds(gfx::Size(10, 10));
[email protected]4bad8b62013-10-24 01:27:291164 texture_layer_->SetIsDrawable(true);
[email protected]0d7fb302014-01-23 21:30:471165 root->AddChild(texture_layer_);
[email protected]4bad8b62013-10-24 01:27:291166
1167 layer_tree_host()->SetRootLayer(root);
1168 LayerTreeTest::SetupTree();
1169 }
1170
dcheng716bedf2014-10-21 09:51:081171 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
[email protected]4bad8b62013-10-24 01:27:291172
dcheng716bedf2014-10-21 09:51:081173 void DidCommitAndDrawFrame() override {
[email protected]4bad8b62013-10-24 01:27:291174 switch (layer_tree_host()->source_frame_number()) {
1175 case 1:
[email protected]4ea293f72014-08-13 03:03:171176 EXPECT_FALSE(proxy()->MainFrameWillHappenForTesting());
[email protected]cce34bd2013-12-02 23:24:451177 // Invalidate the texture layer to clear the mailbox before
1178 // ending the test.
1179 texture_layer_->SetNeedsDisplay();
1180 break;
1181 case 2:
[email protected]4bad8b62013-10-24 01:27:291182 break;
1183 default:
1184 NOTREACHED();
1185 break;
1186 }
1187 }
1188
dcheng716bedf2014-10-21 09:51:081189 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override {
[email protected]cce34bd2013-12-02 23:24:451190 ASSERT_TRUE(result);
1191 DelegatedFrameData* delegated_frame_data =
1192 output_surface()->last_sent_frame().delegated_frame_data.get();
1193 if (!delegated_frame_data)
1194 return;
1195
1196 // Return all resources immediately.
1197 TransferableResourceArray resources_to_return =
1198 output_surface()->resources_held_by_parent();
1199
1200 CompositorFrameAck ack;
1201 for (size_t i = 0; i < resources_to_return.size(); ++i)
1202 output_surface()->ReturnResource(resources_to_return[i].id, &ack);
1203 host_impl->ReclaimResources(&ack);
[email protected]cce34bd2013-12-02 23:24:451204 }
1205
dcheng716bedf2014-10-21 09:51:081206 void AfterTest() override {}
[email protected]4bad8b62013-10-24 01:27:291207
1208 private:
[email protected]4bad8b62013-10-24 01:27:291209 scoped_refptr<TextureLayer> texture_layer_;
[email protected]4bad8b62013-10-24 01:27:291210};
1211
[email protected]cce34bd2013-12-02 23:24:451212SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerNoExtraCommitForMailboxTest);
[email protected]4bad8b62013-10-24 01:27:291213
[email protected]b04264f92013-09-13 23:37:291214// Checks that changing a mailbox in the client for a TextureLayer that's
1215// invisible correctly works and uses the new mailbox as soon as the layer
1216// becomes visible (and returns the old one).
1217class TextureLayerChangeInvisibleMailboxTest
1218 : public LayerTreeTest,
1219 public TextureLayerClient {
1220 public:
1221 TextureLayerChangeInvisibleMailboxTest()
1222 : mailbox_changed_(true),
1223 mailbox_returned_(0),
1224 prepare_called_(0),
1225 commit_count_(0) {
1226 mailbox_ = MakeMailbox('1');
1227 }
1228
1229 // TextureLayerClient implementation.
dcheng716bedf2014-10-21 09:51:081230 bool PrepareTextureMailbox(
[email protected]e51444a2013-12-10 23:05:011231 TextureMailbox* mailbox,
[email protected]9260757f2013-09-17 01:24:161232 scoped_ptr<SingleReleaseCallback>* release_callback,
mostynbf68776d82014-10-06 18:07:371233 bool use_shared_memory) override {
[email protected]b04264f92013-09-13 23:37:291234 ++prepare_called_;
1235 if (!mailbox_changed_)
1236 return false;
1237 *mailbox = mailbox_;
[email protected]9260757f2013-09-17 01:24:161238 *release_callback = SingleReleaseCallback::Create(
1239 base::Bind(&TextureLayerChangeInvisibleMailboxTest::MailboxReleased,
1240 base::Unretained(this)));
[email protected]b04264f92013-09-13 23:37:291241 return true;
1242 }
1243
1244 TextureMailbox MakeMailbox(char name) {
[email protected]e0a4d732014-02-15 00:23:261245 return TextureMailbox(MailboxFromChar(name), GL_TEXTURE_2D, 0);
[email protected]b04264f92013-09-13 23:37:291246 }
1247
[email protected]df41e252014-02-03 23:39:501248 void MailboxReleased(uint32 sync_point, bool lost_resource) {
[email protected]b04264f92013-09-13 23:37:291249 ++mailbox_returned_;
1250 }
1251
dcheng716bedf2014-10-21 09:51:081252 void SetupTree() override {
[email protected]b04264f92013-09-13 23:37:291253 scoped_refptr<Layer> root = Layer::Create();
1254 root->SetBounds(gfx::Size(10, 10));
[email protected]b04264f92013-09-13 23:37:291255 root->SetIsDrawable(true);
1256
1257 solid_layer_ = SolidColorLayer::Create();
1258 solid_layer_->SetBounds(gfx::Size(10, 10));
1259 solid_layer_->SetIsDrawable(true);
1260 solid_layer_->SetBackgroundColor(SK_ColorWHITE);
1261 root->AddChild(solid_layer_);
1262
1263 parent_layer_ = Layer::Create();
1264 parent_layer_->SetBounds(gfx::Size(10, 10));
1265 parent_layer_->SetIsDrawable(true);
1266 root->AddChild(parent_layer_);
1267
1268 texture_layer_ = TextureLayer::CreateForMailbox(this);
1269 texture_layer_->SetBounds(gfx::Size(10, 10));
[email protected]b04264f92013-09-13 23:37:291270 texture_layer_->SetIsDrawable(true);
1271 parent_layer_->AddChild(texture_layer_);
1272
1273 layer_tree_host()->SetRootLayer(root);
1274 LayerTreeTest::SetupTree();
1275 }
1276
dcheng716bedf2014-10-21 09:51:081277 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
[email protected]b04264f92013-09-13 23:37:291278
dcheng716bedf2014-10-21 09:51:081279 void DidCommitAndDrawFrame() override {
[email protected]b04264f92013-09-13 23:37:291280 ++commit_count_;
1281 switch (commit_count_) {
1282 case 1:
1283 // We should have updated the layer, committing the texture.
1284 EXPECT_EQ(1, prepare_called_);
1285 // Make layer invisible.
1286 parent_layer_->SetOpacity(0.f);
1287 break;
1288 case 2:
1289 // Layer shouldn't have been updated.
1290 EXPECT_EQ(1, prepare_called_);
1291 // Change the texture.
1292 mailbox_ = MakeMailbox('2');
1293 mailbox_changed_ = true;
1294 texture_layer_->SetNeedsDisplay();
1295 // Force a change to make sure we draw a frame.
1296 solid_layer_->SetBackgroundColor(SK_ColorGRAY);
1297 break;
1298 case 3:
1299 // Layer shouldn't have been updated.
1300 EXPECT_EQ(1, prepare_called_);
1301 // So the old mailbox isn't returned yet.
1302 EXPECT_EQ(0, mailbox_returned_);
1303 // Make layer visible again.
1304 parent_layer_->SetOpacity(1.f);
1305 break;
1306 case 4:
1307 // Layer should have been updated.
1308 EXPECT_EQ(2, prepare_called_);
1309 // So the old mailbox should have been returned already.
1310 EXPECT_EQ(1, mailbox_returned_);
1311 texture_layer_->ClearClient();
1312 break;
1313 case 5:
1314 EXPECT_EQ(2, mailbox_returned_);
1315 EndTest();
1316 break;
1317 default:
1318 NOTREACHED();
1319 break;
1320 }
1321 }
1322
dcheng716bedf2014-10-21 09:51:081323 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override {
[email protected]b04264f92013-09-13 23:37:291324 ASSERT_TRUE(result);
1325 DelegatedFrameData* delegated_frame_data =
1326 output_surface()->last_sent_frame().delegated_frame_data.get();
1327 if (!delegated_frame_data)
1328 return;
1329
1330 // Return all resources immediately.
1331 TransferableResourceArray resources_to_return =
1332 output_surface()->resources_held_by_parent();
1333
1334 CompositorFrameAck ack;
1335 for (size_t i = 0; i < resources_to_return.size(); ++i)
1336 output_surface()->ReturnResource(resources_to_return[i].id, &ack);
[email protected]a7335e0b2013-09-18 09:34:511337 host_impl->ReclaimResources(&ack);
[email protected]b04264f92013-09-13 23:37:291338 }
1339
dcheng716bedf2014-10-21 09:51:081340 void AfterTest() override {}
[email protected]b04264f92013-09-13 23:37:291341
1342 private:
1343 scoped_refptr<SolidColorLayer> solid_layer_;
1344 scoped_refptr<Layer> parent_layer_;
1345 scoped_refptr<TextureLayer> texture_layer_;
1346
1347 // Used on the main thread.
1348 bool mailbox_changed_;
1349 TextureMailbox mailbox_;
1350 int mailbox_returned_;
1351 int prepare_called_;
1352 int commit_count_;
1353};
1354
1355SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerChangeInvisibleMailboxTest);
1356
[email protected]0d7fb302014-01-23 21:30:471357// Test that TextureLayerImpl::ReleaseResources can be called which releases
1358// the mailbox back to TextureLayerClient.
1359class TextureLayerReleaseResourcesBase
1360 : public LayerTreeTest,
1361 public TextureLayerClient {
1362 public:
1363 // TextureLayerClient implementation.
dcheng716bedf2014-10-21 09:51:081364 bool PrepareTextureMailbox(
[email protected]0d7fb302014-01-23 21:30:471365 TextureMailbox* mailbox,
1366 scoped_ptr<SingleReleaseCallback>* release_callback,
mostynbf68776d82014-10-06 18:07:371367 bool use_shared_memory) override {
[email protected]e0a4d732014-02-15 00:23:261368 *mailbox = TextureMailbox(MailboxFromChar('1'), GL_TEXTURE_2D, 0);
[email protected]0d7fb302014-01-23 21:30:471369 *release_callback = SingleReleaseCallback::Create(
1370 base::Bind(&TextureLayerReleaseResourcesBase::MailboxReleased,
1371 base::Unretained(this)));
1372 return true;
1373 }
1374
1375 void MailboxReleased(unsigned sync_point, bool lost_resource) {
1376 mailbox_released_ = true;
1377 }
1378
dcheng716bedf2014-10-21 09:51:081379 void SetupTree() override {
[email protected]0d7fb302014-01-23 21:30:471380 LayerTreeTest::SetupTree();
1381
1382 scoped_refptr<TextureLayer> texture_layer =
1383 TextureLayer::CreateForMailbox(this);
1384 texture_layer->SetBounds(gfx::Size(10, 10));
[email protected]0d7fb302014-01-23 21:30:471385 texture_layer->SetIsDrawable(true);
1386
1387 layer_tree_host()->root_layer()->AddChild(texture_layer);
1388 }
1389
dcheng716bedf2014-10-21 09:51:081390 void BeginTest() override {
[email protected]0d7fb302014-01-23 21:30:471391 mailbox_released_ = false;
1392 PostSetNeedsCommitToMainThread();
1393 }
1394
dcheng716bedf2014-10-21 09:51:081395 void DidCommitAndDrawFrame() override { EndTest(); }
[email protected]0d7fb302014-01-23 21:30:471396
dcheng716bedf2014-10-21 09:51:081397 void AfterTest() override { EXPECT_TRUE(mailbox_released_); }
[email protected]0d7fb302014-01-23 21:30:471398
1399 private:
1400 bool mailbox_released_;
1401};
1402
1403class TextureLayerReleaseResourcesAfterCommit
1404 : public TextureLayerReleaseResourcesBase {
1405 public:
dcheng716bedf2014-10-21 09:51:081406 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
kulkarni.a4015690f12014-10-10 13:50:061407 LayerTreeImpl* tree = nullptr;
[email protected]0d7fb302014-01-23 21:30:471408 if (host_impl->settings().impl_side_painting)
1409 tree = host_impl->pending_tree();
1410 else
1411 tree = host_impl->active_tree();
1412 tree->root_layer()->children()[0]->ReleaseResources();
1413 }
1414};
1415
1416SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerReleaseResourcesAfterCommit);
1417
1418class TextureLayerReleaseResourcesAfterActivate
1419 : public TextureLayerReleaseResourcesBase {
1420 public:
dcheng716bedf2014-10-21 09:51:081421 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
[email protected]0d7fb302014-01-23 21:30:471422 host_impl->active_tree()->root_layer()->children()[0]->ReleaseResources();
1423 }
1424};
1425
1426SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerReleaseResourcesAfterActivate);
1427
[email protected]9c2bd822013-07-26 12:30:171428class TextureLayerWithMailboxMainThreadDeleted : public LayerTreeTest {
1429 public:
[email protected]df41e252014-02-03 23:39:501430 void ReleaseCallback(uint32 sync_point, bool lost_resource) {
[email protected]9794fb32013-08-29 09:49:591431 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]9c2bd822013-07-26 12:30:171432 EXPECT_FALSE(lost_resource);
1433 ++callback_count_;
1434 EndTest();
1435 }
1436
1437 void SetMailbox(char mailbox_char) {
[email protected]9794fb32013-08-29 09:49:591438 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]9260757f2013-09-17 01:24:161439 scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create(
[email protected]9c2bd822013-07-26 12:30:171440 base::Bind(
1441 &TextureLayerWithMailboxMainThreadDeleted::ReleaseCallback,
1442 base::Unretained(this)));
[email protected]df41e252014-02-03 23:39:501443 layer_->SetTextureMailbox(
[email protected]e0a4d732014-02-15 00:23:261444 TextureMailbox(MailboxFromChar(mailbox_char), GL_TEXTURE_2D, 0),
[email protected]df41e252014-02-03 23:39:501445 callback.Pass());
[email protected]9c2bd822013-07-26 12:30:171446 }
1447
dcheng716bedf2014-10-21 09:51:081448 void SetupTree() override {
[email protected]9c2bd822013-07-26 12:30:171449 gfx::Size bounds(100, 100);
1450 root_ = Layer::Create();
[email protected]9c2bd822013-07-26 12:30:171451 root_->SetBounds(bounds);
1452
kulkarni.a4015690f12014-10-10 13:50:061453 layer_ = TextureLayer::CreateForMailbox(nullptr);
[email protected]9c2bd822013-07-26 12:30:171454 layer_->SetIsDrawable(true);
[email protected]9c2bd822013-07-26 12:30:171455 layer_->SetBounds(bounds);
1456
1457 root_->AddChild(layer_);
1458 layer_tree_host()->SetRootLayer(root_);
1459 layer_tree_host()->SetViewportSize(bounds);
1460 }
1461
dcheng716bedf2014-10-21 09:51:081462 void BeginTest() override {
[email protected]9794fb32013-08-29 09:49:591463 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
1464
[email protected]9c2bd822013-07-26 12:30:171465 callback_count_ = 0;
1466
1467 // Set the mailbox on the main thread.
1468 SetMailbox('1');
1469 EXPECT_EQ(0, callback_count_);
1470
1471 PostSetNeedsCommitToMainThread();
1472 }
1473
dcheng716bedf2014-10-21 09:51:081474 void DidCommitAndDrawFrame() override {
[email protected]9c2bd822013-07-26 12:30:171475 switch (layer_tree_host()->source_frame_number()) {
1476 case 1:
1477 // Delete the TextureLayer on the main thread while the mailbox is in
1478 // the impl tree.
1479 layer_->RemoveFromParent();
kulkarni.a4015690f12014-10-10 13:50:061480 layer_ = nullptr;
[email protected]9c2bd822013-07-26 12:30:171481 break;
1482 }
1483 }
1484
dcheng716bedf2014-10-21 09:51:081485 void AfterTest() override { EXPECT_EQ(1, callback_count_); }
[email protected]9c2bd822013-07-26 12:30:171486
1487 private:
[email protected]9794fb32013-08-29 09:49:591488 base::ThreadChecker main_thread_;
[email protected]9c2bd822013-07-26 12:30:171489 int callback_count_;
1490 scoped_refptr<Layer> root_;
1491 scoped_refptr<TextureLayer> layer_;
1492};
1493
1494SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
1495 TextureLayerWithMailboxMainThreadDeleted);
1496
1497class TextureLayerWithMailboxImplThreadDeleted : public LayerTreeTest {
1498 public:
[email protected]df41e252014-02-03 23:39:501499 void ReleaseCallback(uint32 sync_point, bool lost_resource) {
[email protected]9794fb32013-08-29 09:49:591500 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]9c2bd822013-07-26 12:30:171501 EXPECT_FALSE(lost_resource);
1502 ++callback_count_;
1503 EndTest();
1504 }
1505
1506 void SetMailbox(char mailbox_char) {
[email protected]9794fb32013-08-29 09:49:591507 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]9260757f2013-09-17 01:24:161508 scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create(
[email protected]9c2bd822013-07-26 12:30:171509 base::Bind(
1510 &TextureLayerWithMailboxImplThreadDeleted::ReleaseCallback,
1511 base::Unretained(this)));
[email protected]df41e252014-02-03 23:39:501512 layer_->SetTextureMailbox(
[email protected]e0a4d732014-02-15 00:23:261513 TextureMailbox(MailboxFromChar(mailbox_char), GL_TEXTURE_2D, 0),
[email protected]df41e252014-02-03 23:39:501514 callback.Pass());
[email protected]9c2bd822013-07-26 12:30:171515 }
1516
dcheng716bedf2014-10-21 09:51:081517 void SetupTree() override {
[email protected]9c2bd822013-07-26 12:30:171518 gfx::Size bounds(100, 100);
1519 root_ = Layer::Create();
[email protected]9c2bd822013-07-26 12:30:171520 root_->SetBounds(bounds);
1521
kulkarni.a4015690f12014-10-10 13:50:061522 layer_ = TextureLayer::CreateForMailbox(nullptr);
[email protected]9c2bd822013-07-26 12:30:171523 layer_->SetIsDrawable(true);
[email protected]9c2bd822013-07-26 12:30:171524 layer_->SetBounds(bounds);
1525
1526 root_->AddChild(layer_);
1527 layer_tree_host()->SetRootLayer(root_);
1528 layer_tree_host()->SetViewportSize(bounds);
1529 }
1530
dcheng716bedf2014-10-21 09:51:081531 void BeginTest() override {
[email protected]9794fb32013-08-29 09:49:591532 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
1533
[email protected]9c2bd822013-07-26 12:30:171534 callback_count_ = 0;
1535
1536 // Set the mailbox on the main thread.
1537 SetMailbox('1');
1538 EXPECT_EQ(0, callback_count_);
1539
1540 PostSetNeedsCommitToMainThread();
1541 }
1542
dcheng716bedf2014-10-21 09:51:081543 void DidCommitAndDrawFrame() override {
[email protected]9c2bd822013-07-26 12:30:171544 switch (layer_tree_host()->source_frame_number()) {
1545 case 1:
1546 // Remove the TextureLayer on the main thread while the mailbox is in
1547 // the impl tree, but don't delete the TextureLayer until after the impl
1548 // tree side is deleted.
1549 layer_->RemoveFromParent();
1550 break;
1551 case 2:
kulkarni.a4015690f12014-10-10 13:50:061552 layer_ = nullptr;
[email protected]9c2bd822013-07-26 12:30:171553 break;
1554 }
1555 }
1556
dcheng716bedf2014-10-21 09:51:081557 void AfterTest() override { EXPECT_EQ(1, callback_count_); }
[email protected]9c2bd822013-07-26 12:30:171558
1559 private:
[email protected]9794fb32013-08-29 09:49:591560 base::ThreadChecker main_thread_;
[email protected]9c2bd822013-07-26 12:30:171561 int callback_count_;
1562 scoped_refptr<Layer> root_;
1563 scoped_refptr<TextureLayer> layer_;
1564};
1565
1566SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
1567 TextureLayerWithMailboxImplThreadDeleted);
1568
[email protected]ba565742012-11-10 09:29:481569} // namespace
1570} // namespace cc