blob: 4e2f67577adf3d17bfe663e265e8ed8fc5147c6e [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));
jackhou10c9af42014-12-04 05:24:44208 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetNearestNeighbor(true));
[email protected]31d4df82013-07-18 10:17:22209 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetUV(
210 gfx::PointF(0.25f, 0.25f), gfx::PointF(0.75f, 0.75f)));
211 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetVertexOpacity(
212 0.5f, 0.5f, 0.5f, 0.5f));
213 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetPremultipliedAlpha(false));
214 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetBlendBackgroundColor(true));
[email protected]31d4df82013-07-18 10:17:22215}
216
[email protected]1c10e232013-07-31 12:35:43217TEST_F(TextureLayerTest, VisibleContentOpaqueRegion) {
218 const gfx::Size layer_bounds(100, 100);
219 const gfx::Rect layer_rect(layer_bounds);
220 const Region layer_region(layer_rect);
221
kulkarni.a4015690f12014-10-10 13:50:06222 scoped_refptr<TextureLayer> layer = TextureLayer::CreateForMailbox(nullptr);
[email protected]1c10e232013-07-31 12:35:43223 layer->SetBounds(layer_bounds);
224 layer->draw_properties().visible_content_rect = layer_rect;
225 layer->SetBlendBackgroundColor(true);
226
227 // Verify initial conditions.
228 EXPECT_FALSE(layer->contents_opaque());
229 EXPECT_EQ(0u, layer->background_color());
230 EXPECT_EQ(Region().ToString(),
231 layer->VisibleContentOpaqueRegion().ToString());
232
233 // Opaque background.
234 layer->SetBackgroundColor(SK_ColorWHITE);
235 EXPECT_EQ(layer_region.ToString(),
236 layer->VisibleContentOpaqueRegion().ToString());
237
238 // Transparent background.
239 layer->SetBackgroundColor(SkColorSetARGB(100, 255, 255, 255));
240 EXPECT_EQ(Region().ToString(),
241 layer->VisibleContentOpaqueRegion().ToString());
242}
243
[email protected]31d4df82013-07-18 10:17:22244TEST_F(TextureLayerTest, RateLimiter) {
245 FakeTextureLayerClient client;
246 scoped_refptr<TextureLayer> test_layer = TextureLayer::CreateForMailbox(
247 &client);
248 test_layer->SetIsDrawable(true);
249 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
250 layer_tree_host_->SetRootLayer(test_layer);
251
252 // Don't rate limit until we invalidate.
[email protected]aeeb3372013-11-05 14:05:54253 EXPECT_CALL(*layer_tree_host_, StartRateLimiter()).Times(0);
[email protected]31d4df82013-07-18 10:17:22254 test_layer->SetRateLimitContext(true);
255 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
256
257 // Do rate limit after we invalidate.
[email protected]aeeb3372013-11-05 14:05:54258 EXPECT_CALL(*layer_tree_host_, StartRateLimiter());
[email protected]31d4df82013-07-18 10:17:22259 test_layer->SetNeedsDisplay();
260 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
261
262 // Stop rate limiter when we don't want it any more.
[email protected]aeeb3372013-11-05 14:05:54263 EXPECT_CALL(*layer_tree_host_, StopRateLimiter());
[email protected]31d4df82013-07-18 10:17:22264 test_layer->SetRateLimitContext(false);
265 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
266
267 // Or we clear the client.
268 test_layer->SetRateLimitContext(true);
[email protected]aeeb3372013-11-05 14:05:54269 EXPECT_CALL(*layer_tree_host_, StopRateLimiter());
[email protected]31d4df82013-07-18 10:17:22270 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
271 test_layer->ClearClient();
272 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
273
274 // Reset to a layer with a client, that started the rate limiter.
275 test_layer = TextureLayer::CreateForMailbox(
276 &client);
277 test_layer->SetIsDrawable(true);
278 test_layer->SetRateLimitContext(true);
279 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
280 layer_tree_host_->SetRootLayer(test_layer);
[email protected]aeeb3372013-11-05 14:05:54281 EXPECT_CALL(*layer_tree_host_, StartRateLimiter()).Times(0);
[email protected]31d4df82013-07-18 10:17:22282 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
[email protected]aeeb3372013-11-05 14:05:54283 EXPECT_CALL(*layer_tree_host_, StartRateLimiter());
[email protected]31d4df82013-07-18 10:17:22284 test_layer->SetNeedsDisplay();
285 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
286
287 // Stop rate limiter when we're removed from the tree.
[email protected]aeeb3372013-11-05 14:05:54288 EXPECT_CALL(*layer_tree_host_, StopRateLimiter());
[email protected]d72d9e02014-04-03 18:40:09289 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1);
kulkarni.a4015690f12014-10-10 13:50:06290 layer_tree_host_->SetRootLayer(nullptr);
[email protected]31d4df82013-07-18 10:17:22291 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
292}
293
[email protected]df41e252014-02-03 23:39:50294class TestMailboxHolder : public TextureLayer::TextureMailboxHolder {
[email protected]9794fb32013-08-29 09:49:59295 public:
[email protected]df41e252014-02-03 23:39:50296 using TextureLayer::TextureMailboxHolder::Create;
[email protected]9794fb32013-08-29 09:49:59297
298 protected:
dcheng716bedf2014-10-21 09:51:08299 ~TestMailboxHolder() override {}
[email protected]9794fb32013-08-29 09:49:59300};
301
[email protected]de44a152013-01-08 15:28:46302class TextureLayerWithMailboxTest : public TextureLayerTest {
[email protected]28571b042013-03-14 07:59:15303 protected:
304 virtual void TearDown() {
305 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
306 EXPECT_CALL(test_data_.mock_callback_,
307 Release(test_data_.mailbox_name1_,
[email protected]7ba3ca72013-04-11 06:37:25308 test_data_.sync_point1_,
309 false)).Times(1);
[email protected]28571b042013-03-14 07:59:15310 TextureLayerTest::TearDown();
311 }
[email protected]de44a152013-01-08 15:28:46312
[email protected]28571b042013-03-14 07:59:15313 CommonMailboxObjects test_data_;
[email protected]de44a152013-01-08 15:28:46314};
315
[email protected]28571b042013-03-14 07:59:15316TEST_F(TextureLayerWithMailboxTest, ReplaceMailboxOnMainThreadBeforeCommit) {
kulkarni.a4015690f12014-10-10 13:50:06317 scoped_refptr<TextureLayer> test_layer =
318 TextureLayer::CreateForMailbox(nullptr);
[email protected]22898ed2013-06-01 04:52:30319 ASSERT_TRUE(test_layer.get());
[email protected]de44a152013-01-08 15:28:46320
[email protected]28571b042013-03-14 07:59:15321 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
322 layer_tree_host_->SetRootLayer(test_layer);
323 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
[email protected]de44a152013-01-08 15:28:46324
[email protected]28571b042013-03-14 07:59:15325 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
[email protected]9260757f2013-09-17 01:24:16326 test_layer->SetTextureMailbox(
327 test_data_.mailbox1_,
328 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
[email protected]28571b042013-03-14 07:59:15329 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
[email protected]de44a152013-01-08 15:28:46330
[email protected]28571b042013-03-14 07:59:15331 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
332 EXPECT_CALL(test_data_.mock_callback_,
[email protected]7ba3ca72013-04-11 06:37:25333 Release(test_data_.mailbox_name1_,
334 test_data_.sync_point1_,
335 false))
[email protected]28571b042013-03-14 07:59:15336 .Times(1);
[email protected]9260757f2013-09-17 01:24:16337 test_layer->SetTextureMailbox(
338 test_data_.mailbox2_,
339 SingleReleaseCallback::Create(test_data_.release_mailbox2_));
[email protected]28571b042013-03-14 07:59:15340 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
341 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]de44a152013-01-08 15:28:46342
[email protected]28571b042013-03-14 07:59:15343 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
344 EXPECT_CALL(test_data_.mock_callback_,
[email protected]7ba3ca72013-04-11 06:37:25345 Release(test_data_.mailbox_name2_,
346 test_data_.sync_point2_,
347 false))
[email protected]28571b042013-03-14 07:59:15348 .Times(1);
danakj968153f32014-10-15 22:52:16349 test_layer->SetTextureMailbox(TextureMailbox(), nullptr);
[email protected]28571b042013-03-14 07:59:15350 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
351 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]de44a152013-01-08 15:28:46352
[email protected]80d42bd2013-08-30 19:13:45353 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
[email protected]9260757f2013-09-17 01:24:16354 test_layer->SetTextureMailbox(
355 test_data_.mailbox3_,
356 SingleReleaseCallback::Create(test_data_.release_mailbox3_));
[email protected]42f40a52013-06-08 04:38:51357 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
358 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
359
[email protected]42f40a52013-06-08 04:38:51360 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
361 EXPECT_CALL(test_data_.mock_callback_,
362 Release2(test_data_.shared_memory_.get(),
363 0, false))
364 .Times(1);
danakj968153f32014-10-15 22:52:16365 test_layer->SetTextureMailbox(TextureMailbox(), nullptr);
[email protected]42f40a52013-06-08 04:38:51366 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
367 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
368
[email protected]28571b042013-03-14 07:59:15369 // Test destructor.
370 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
[email protected]9260757f2013-09-17 01:24:16371 test_layer->SetTextureMailbox(
372 test_data_.mailbox1_,
373 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
[email protected]de44a152013-01-08 15:28:46374}
375
[email protected]f9e8f452014-03-07 22:09:40376TEST_F(TextureLayerTest, SetTextureMailboxWithoutReleaseCallback) {
kulkarni.a4015690f12014-10-10 13:50:06377 scoped_refptr<TextureLayer> test_layer =
378 TextureLayer::CreateForMailbox(nullptr);
[email protected]f9e8f452014-03-07 22:09:40379 ASSERT_TRUE(test_layer.get());
380
381 // These use the same gpu::Mailbox, but different sync points.
382 TextureMailbox mailbox1(MailboxFromChar('a'), GL_TEXTURE_2D, 1);
383 TextureMailbox mailbox2(MailboxFromChar('a'), GL_TEXTURE_2D, 2);
384
[email protected]f9e8f452014-03-07 22:09:40385 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
386 layer_tree_host_->SetRootLayer(test_layer);
387 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
388
389 // Set the mailbox the first time. It should cause a commit.
[email protected]f9e8f452014-03-07 22:09:40390 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
391 test_layer->SetTextureMailboxWithoutReleaseCallback(mailbox1);
392 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
393
394 // Set the mailbox again with a new sync point, as the backing texture has
395 // been updated. It should cause a new commit.
[email protected]f9e8f452014-03-07 22:09:40396 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
397 test_layer->SetTextureMailboxWithoutReleaseCallback(mailbox2);
398 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
399}
400
[email protected]9794fb32013-08-29 09:49:59401class TextureLayerMailboxHolderTest : public TextureLayerTest {
402 public:
403 TextureLayerMailboxHolderTest()
404 : main_thread_("MAIN") {
405 main_thread_.Start();
skyostil3976a3f2014-09-04 22:07:23406 main_thread_.message_loop()->PostTask(
407 FROM_HERE,
408 base::Bind(&TextureLayerMailboxHolderTest::InitializeOnMain,
409 base::Unretained(this)));
410 Wait(main_thread_);
[email protected]9794fb32013-08-29 09:49:59411 }
412
413 void Wait(const base::Thread& thread) {
414 bool manual_reset = false;
415 bool initially_signaled = false;
416 base::WaitableEvent event(manual_reset, initially_signaled);
417 thread.message_loop()->PostTask(
418 FROM_HERE,
419 base::Bind(&base::WaitableEvent::Signal, base::Unretained(&event)));
420 event.Wait();
421 }
422
423 void CreateMainRef() {
424 main_ref_ = TestMailboxHolder::Create(
[email protected]9260757f2013-09-17 01:24:16425 test_data_.mailbox1_,
426 SingleReleaseCallback::Create(test_data_.release_mailbox1_)).Pass();
[email protected]9794fb32013-08-29 09:49:59427 }
428
danakjf446a072014-09-27 21:55:48429 void ReleaseMainRef() { main_ref_ = nullptr; }
[email protected]9794fb32013-08-29 09:49:59430
skyostil3976a3f2014-09-04 22:07:23431 void CreateImplRef(scoped_ptr<SingleReleaseCallbackImpl>* impl_ref) {
[email protected]9794fb32013-08-29 09:49:59432 *impl_ref = main_ref_->holder()->GetCallbackForImplThread();
433 }
434
435 void CapturePostTasksAndWait(base::WaitableEvent* begin_capture,
436 base::WaitableEvent* wait_for_capture,
437 base::WaitableEvent* stop_capture) {
438 begin_capture->Wait();
skyostil3976a3f2014-09-04 22:07:23439 BlockingTaskRunner::CapturePostTasks capture(
440 main_thread_task_runner_.get());
[email protected]9794fb32013-08-29 09:49:59441 wait_for_capture->Signal();
442 stop_capture->Wait();
443 }
444
445 protected:
skyostil3976a3f2014-09-04 22:07:23446 void InitializeOnMain() {
447 main_thread_task_runner_ =
448 BlockingTaskRunner::Create(main_thread_.message_loop_proxy());
449 }
450
[email protected]9794fb32013-08-29 09:49:59451 scoped_ptr<TestMailboxHolder::MainThreadReference>
452 main_ref_;
453 base::Thread main_thread_;
skyostil3976a3f2014-09-04 22:07:23454 scoped_ptr<BlockingTaskRunner> main_thread_task_runner_;
[email protected]9794fb32013-08-29 09:49:59455 CommonMailboxObjects test_data_;
456};
457
458TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_BothReleaseThenMain) {
kulkarni.a4015690f12014-10-10 13:50:06459 scoped_refptr<TextureLayer> test_layer =
460 TextureLayer::CreateForMailbox(nullptr);
[email protected]9794fb32013-08-29 09:49:59461 ASSERT_TRUE(test_layer.get());
462
463 main_thread_.message_loop()->PostTask(
464 FROM_HERE,
465 base::Bind(&TextureLayerMailboxHolderTest::CreateMainRef,
466 base::Unretained(this)));
467
468 Wait(main_thread_);
469
470 // The texture layer is attached to compositor1, and passes a reference to its
471 // impl tree.
skyostil3976a3f2014-09-04 22:07:23472 scoped_ptr<SingleReleaseCallbackImpl> compositor1;
[email protected]9794fb32013-08-29 09:49:59473 main_thread_.message_loop()->PostTask(
474 FROM_HERE,
475 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
476 base::Unretained(this),
477 &compositor1));
478
479 // Then the texture layer is removed and attached to compositor2, and passes a
480 // reference to its impl tree.
skyostil3976a3f2014-09-04 22:07:23481 scoped_ptr<SingleReleaseCallbackImpl> compositor2;
[email protected]9794fb32013-08-29 09:49:59482 main_thread_.message_loop()->PostTask(
483 FROM_HERE,
484 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
485 base::Unretained(this),
486 &compositor2));
487
488 Wait(main_thread_);
489 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
490
491 // The compositors both destroy their impl trees before the main thread layer
492 // is destroyed.
skyostil3976a3f2014-09-04 22:07:23493 compositor1->Run(100, false, main_thread_task_runner_.get());
494 compositor2->Run(200, false, main_thread_task_runner_.get());
[email protected]9794fb32013-08-29 09:49:59495
496 Wait(main_thread_);
497
498 EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0);
499 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
500
501 // The main thread ref is the last one, so the mailbox is released back to the
502 // embedder, with the last sync point provided by the impl trees.
503 EXPECT_CALL(test_data_.mock_callback_,
504 Release(test_data_.mailbox_name1_, 200, false)).Times(1);
505
506 main_thread_.message_loop()->PostTask(
507 FROM_HERE,
508 base::Bind(&TextureLayerMailboxHolderTest::ReleaseMainRef,
509 base::Unretained(this)));
510 Wait(main_thread_);
511 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
512}
513
514TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_MainReleaseBetween) {
kulkarni.a4015690f12014-10-10 13:50:06515 scoped_refptr<TextureLayer> test_layer =
516 TextureLayer::CreateForMailbox(nullptr);
[email protected]9794fb32013-08-29 09:49:59517 ASSERT_TRUE(test_layer.get());
518
519 main_thread_.message_loop()->PostTask(
520 FROM_HERE,
521 base::Bind(&TextureLayerMailboxHolderTest::CreateMainRef,
522 base::Unretained(this)));
523
524 Wait(main_thread_);
525
526 // The texture layer is attached to compositor1, and passes a reference to its
527 // impl tree.
skyostil3976a3f2014-09-04 22:07:23528 scoped_ptr<SingleReleaseCallbackImpl> compositor1;
[email protected]9794fb32013-08-29 09:49:59529 main_thread_.message_loop()->PostTask(
530 FROM_HERE,
531 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
532 base::Unretained(this),
533 &compositor1));
534
535 // Then the texture layer is removed and attached to compositor2, and passes a
536 // reference to its impl tree.
skyostil3976a3f2014-09-04 22:07:23537 scoped_ptr<SingleReleaseCallbackImpl> compositor2;
[email protected]9794fb32013-08-29 09:49:59538 main_thread_.message_loop()->PostTask(
539 FROM_HERE,
540 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
541 base::Unretained(this),
542 &compositor2));
543
544 Wait(main_thread_);
545 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
546
547 // One compositor destroys their impl tree.
skyostil3976a3f2014-09-04 22:07:23548 compositor1->Run(100, false, main_thread_task_runner_.get());
[email protected]9794fb32013-08-29 09:49:59549
550 // Then the main thread reference is destroyed.
551 main_thread_.message_loop()->PostTask(
552 FROM_HERE,
553 base::Bind(&TextureLayerMailboxHolderTest::ReleaseMainRef,
554 base::Unretained(this)));
555
556 Wait(main_thread_);
557
558 EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0);
559 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
560
561 // The second impl reference is destroyed last, causing the mailbox to be
562 // released back to the embedder with the last sync point from the impl tree.
563 EXPECT_CALL(test_data_.mock_callback_,
564 Release(test_data_.mailbox_name1_, 200, true)).Times(1);
565
skyostil3976a3f2014-09-04 22:07:23566 compositor2->Run(200, true, main_thread_task_runner_.get());
[email protected]9794fb32013-08-29 09:49:59567 Wait(main_thread_);
568 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
569}
570
571TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_MainReleasedFirst) {
kulkarni.a4015690f12014-10-10 13:50:06572 scoped_refptr<TextureLayer> test_layer =
573 TextureLayer::CreateForMailbox(nullptr);
[email protected]9794fb32013-08-29 09:49:59574 ASSERT_TRUE(test_layer.get());
575
576 main_thread_.message_loop()->PostTask(
577 FROM_HERE,
578 base::Bind(&TextureLayerMailboxHolderTest::CreateMainRef,
579 base::Unretained(this)));
580
581 Wait(main_thread_);
582
583 // The texture layer is attached to compositor1, and passes a reference to its
584 // impl tree.
skyostil3976a3f2014-09-04 22:07:23585 scoped_ptr<SingleReleaseCallbackImpl> compositor1;
[email protected]9794fb32013-08-29 09:49:59586 main_thread_.message_loop()->PostTask(
587 FROM_HERE,
588 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
589 base::Unretained(this),
590 &compositor1));
591
592 // Then the texture layer is removed and attached to compositor2, and passes a
593 // reference to its impl tree.
skyostil3976a3f2014-09-04 22:07:23594 scoped_ptr<SingleReleaseCallbackImpl> compositor2;
[email protected]9794fb32013-08-29 09:49:59595 main_thread_.message_loop()->PostTask(
596 FROM_HERE,
597 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
598 base::Unretained(this),
599 &compositor2));
600
601 Wait(main_thread_);
602 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
603
604 // The main thread reference is destroyed first.
605 main_thread_.message_loop()->PostTask(
606 FROM_HERE,
607 base::Bind(&TextureLayerMailboxHolderTest::ReleaseMainRef,
608 base::Unretained(this)));
609
610 // One compositor destroys their impl tree.
skyostil3976a3f2014-09-04 22:07:23611 compositor2->Run(200, false, main_thread_task_runner_.get());
[email protected]9794fb32013-08-29 09:49:59612
613 Wait(main_thread_);
614
615 EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0);
616 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
617
618 // The second impl reference is destroyed last, causing the mailbox to be
619 // released back to the embedder with the last sync point from the impl tree.
620 EXPECT_CALL(test_data_.mock_callback_,
621 Release(test_data_.mailbox_name1_, 100, true)).Times(1);
622
skyostil3976a3f2014-09-04 22:07:23623 compositor1->Run(100, true, main_thread_task_runner_.get());
[email protected]9794fb32013-08-29 09:49:59624 Wait(main_thread_);
625 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
626}
627
628TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_SecondImplRefShortcut) {
kulkarni.a4015690f12014-10-10 13:50:06629 scoped_refptr<TextureLayer> test_layer =
630 TextureLayer::CreateForMailbox(nullptr);
[email protected]9794fb32013-08-29 09:49:59631 ASSERT_TRUE(test_layer.get());
632
633 main_thread_.message_loop()->PostTask(
634 FROM_HERE,
635 base::Bind(&TextureLayerMailboxHolderTest::CreateMainRef,
636 base::Unretained(this)));
637
638 Wait(main_thread_);
639
640 // The texture layer is attached to compositor1, and passes a reference to its
641 // impl tree.
skyostil3976a3f2014-09-04 22:07:23642 scoped_ptr<SingleReleaseCallbackImpl> compositor1;
[email protected]9794fb32013-08-29 09:49:59643 main_thread_.message_loop()->PostTask(
644 FROM_HERE,
645 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
646 base::Unretained(this),
647 &compositor1));
648
649 // Then the texture layer is removed and attached to compositor2, and passes a
650 // reference to its impl tree.
skyostil3976a3f2014-09-04 22:07:23651 scoped_ptr<SingleReleaseCallbackImpl> compositor2;
[email protected]9794fb32013-08-29 09:49:59652 main_thread_.message_loop()->PostTask(
653 FROM_HERE,
654 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
655 base::Unretained(this),
656 &compositor2));
657
658 Wait(main_thread_);
659 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
660
661 // The main thread reference is destroyed first.
662 main_thread_.message_loop()->PostTask(
663 FROM_HERE,
664 base::Bind(&TextureLayerMailboxHolderTest::ReleaseMainRef,
665 base::Unretained(this)));
666
667 EXPECT_CALL(test_data_.mock_callback_,
668 Release(test_data_.mailbox_name1_, 200, true)).Times(1);
669
670 bool manual_reset = false;
671 bool initially_signaled = false;
672 base::WaitableEvent begin_capture(manual_reset, initially_signaled);
673 base::WaitableEvent wait_for_capture(manual_reset, initially_signaled);
674 base::WaitableEvent stop_capture(manual_reset, initially_signaled);
675
676 // Post a task to start capturing tasks on the main thread. This will block
677 // the main thread until we signal the |stop_capture| event.
678 main_thread_.message_loop()->PostTask(
679 FROM_HERE,
680 base::Bind(&TextureLayerMailboxHolderTest::CapturePostTasksAndWait,
681 base::Unretained(this),
682 &begin_capture,
683 &wait_for_capture,
684 &stop_capture));
685
686 // Before the main thread capturing starts, one compositor destroys their
687 // impl reference. Since capturing did not start, this gets post-tasked to
688 // the main thread.
skyostil3976a3f2014-09-04 22:07:23689 compositor1->Run(100, false, main_thread_task_runner_.get());
[email protected]9794fb32013-08-29 09:49:59690
691 // Start capturing on the main thread.
692 begin_capture.Signal();
693 wait_for_capture.Wait();
694
695 // Meanwhile, the second compositor released its impl reference, but this task
696 // gets shortcutted directly to the main thread. This means the reference is
697 // released before compositor1, whose reference will be released later when
698 // the post-task is serviced. But since it was destroyed _on the impl thread_
699 // last, its sync point values should be used.
skyostil3976a3f2014-09-04 22:07:23700 compositor2->Run(200, true, main_thread_task_runner_.get());
[email protected]9794fb32013-08-29 09:49:59701
702 stop_capture.Signal();
703 Wait(main_thread_);
704
705 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
706}
707
[email protected]e216fef02013-03-20 22:56:10708class TextureLayerImplWithMailboxThreadedCallback : public LayerTreeTest {
[email protected]28571b042013-03-14 07:59:15709 public:
710 TextureLayerImplWithMailboxThreadedCallback()
711 : callback_count_(0),
712 commit_count_(0) {}
713
714 // Make sure callback is received on main and doesn't block the impl thread.
[email protected]df41e252014-02-03 23:39:50715 void ReleaseCallback(uint32 sync_point, bool lost_resource) {
[email protected]9794fb32013-08-29 09:49:59716 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]7ba3ca72013-04-11 06:37:25717 EXPECT_FALSE(lost_resource);
[email protected]28571b042013-03-14 07:59:15718 ++callback_count_;
719 }
720
721 void SetMailbox(char mailbox_char) {
[email protected]9794fb32013-08-29 09:49:59722 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]9260757f2013-09-17 01:24:16723 scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create(
[email protected]28571b042013-03-14 07:59:15724 base::Bind(
725 &TextureLayerImplWithMailboxThreadedCallback::ReleaseCallback,
726 base::Unretained(this)));
[email protected]df41e252014-02-03 23:39:50727 layer_->SetTextureMailbox(
[email protected]e0a4d732014-02-15 00:23:26728 TextureMailbox(MailboxFromChar(mailbox_char), GL_TEXTURE_2D, 0),
[email protected]df41e252014-02-03 23:39:50729 callback.Pass());
[email protected]28571b042013-03-14 07:59:15730 }
731
dcheng716bedf2014-10-21 09:51:08732 void BeginTest() override {
[email protected]9794fb32013-08-29 09:49:59733 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
734
[email protected]28571b042013-03-14 07:59:15735 gfx::Size bounds(100, 100);
736 root_ = Layer::Create();
[email protected]28571b042013-03-14 07:59:15737 root_->SetBounds(bounds);
738
kulkarni.a4015690f12014-10-10 13:50:06739 layer_ = TextureLayer::CreateForMailbox(nullptr);
[email protected]28571b042013-03-14 07:59:15740 layer_->SetIsDrawable(true);
[email protected]28571b042013-03-14 07:59:15741 layer_->SetBounds(bounds);
742
743 root_->AddChild(layer_);
[email protected]e216fef02013-03-20 22:56:10744 layer_tree_host()->SetRootLayer(root_);
[email protected]18ce59702013-04-09 04:58:40745 layer_tree_host()->SetViewportSize(bounds);
[email protected]28571b042013-03-14 07:59:15746 SetMailbox('1');
747 EXPECT_EQ(0, callback_count_);
748
749 // Case #1: change mailbox before the commit. The old mailbox should be
750 // released immediately.
751 SetMailbox('2');
752 EXPECT_EQ(1, callback_count_);
[email protected]e216fef02013-03-20 22:56:10753 PostSetNeedsCommitToMainThread();
[email protected]28571b042013-03-14 07:59:15754 }
755
dcheng716bedf2014-10-21 09:51:08756 void DidCommit() override {
[email protected]28571b042013-03-14 07:59:15757 ++commit_count_;
758 switch (commit_count_) {
759 case 1:
760 // Case #2: change mailbox after the commit (and draw), where the
761 // layer draws. The old mailbox should be released during the next
762 // commit.
763 SetMailbox('3');
764 EXPECT_EQ(1, callback_count_);
765 break;
766 case 2:
[email protected]28571b042013-03-14 07:59:15767 EXPECT_EQ(2, callback_count_);
768 // Case #3: change mailbox when the layer doesn't draw. The old
769 // mailbox should be released during the next commit.
770 layer_->SetBounds(gfx::Size());
771 SetMailbox('4');
772 break;
[email protected]9794fb32013-08-29 09:49:59773 case 3:
[email protected]28571b042013-03-14 07:59:15774 EXPECT_EQ(3, callback_count_);
775 // Case #4: release mailbox that was committed but never drawn. The
776 // old mailbox should be released during the next commit.
danakj968153f32014-10-15 22:52:16777 layer_->SetTextureMailbox(TextureMailbox(), nullptr);
[email protected]28571b042013-03-14 07:59:15778 break;
[email protected]9794fb32013-08-29 09:49:59779 case 4:
780 if (layer_tree_host()->settings().impl_side_painting) {
781 // With impl painting, the texture mailbox will still be on the impl
782 // thread when the commit finishes, because the layer is not drawble
783 // when it has no texture mailbox, and thus does not block the commit
784 // on activation. So, we wait for activation.
785 // TODO(danakj): fix this. crbug.com/277953
786 layer_tree_host()->SetNeedsCommit();
787 break;
788 } else {
789 ++commit_count_;
790 }
791 case 5:
[email protected]28571b042013-03-14 07:59:15792 EXPECT_EQ(4, callback_count_);
[email protected]7096acc2013-06-18 21:12:43793 // Restore a mailbox for the next step.
794 SetMailbox('5');
795 break;
[email protected]9794fb32013-08-29 09:49:59796 case 6:
[email protected]7096acc2013-06-18 21:12:43797 // Case #5: remove layer from tree. Callback should *not* be called, the
798 // mailbox is returned to the main thread.
799 EXPECT_EQ(4, callback_count_);
800 layer_->RemoveFromParent();
801 break;
[email protected]9794fb32013-08-29 09:49:59802 case 7:
803 if (layer_tree_host()->settings().impl_side_painting) {
804 // With impl painting, the texture mailbox will still be on the impl
805 // thread when the commit finishes, because the layer is not around to
806 // block the commit on activation anymore. So, we wait for activation.
807 // TODO(danakj): fix this. crbug.com/277953
808 layer_tree_host()->SetNeedsCommit();
809 break;
810 } else {
811 ++commit_count_;
812 }
813 case 8:
[email protected]7096acc2013-06-18 21:12:43814 EXPECT_EQ(4, callback_count_);
815 // Resetting the mailbox will call the callback now.
danakj968153f32014-10-15 22:52:16816 layer_->SetTextureMailbox(TextureMailbox(), nullptr);
[email protected]7096acc2013-06-18 21:12:43817 EXPECT_EQ(5, callback_count_);
[email protected]e216fef02013-03-20 22:56:10818 EndTest();
[email protected]28571b042013-03-14 07:59:15819 break;
820 default:
821 NOTREACHED();
822 break;
[email protected]de44a152013-01-08 15:28:46823 }
[email protected]28571b042013-03-14 07:59:15824 }
[email protected]de44a152013-01-08 15:28:46825
dcheng716bedf2014-10-21 09:51:08826 void AfterTest() override {}
[email protected]de44a152013-01-08 15:28:46827
[email protected]28571b042013-03-14 07:59:15828 private:
[email protected]9794fb32013-08-29 09:49:59829 base::ThreadChecker main_thread_;
[email protected]28571b042013-03-14 07:59:15830 int callback_count_;
831 int commit_count_;
832 scoped_refptr<Layer> root_;
833 scoped_refptr<TextureLayer> layer_;
[email protected]de44a152013-01-08 15:28:46834};
835
[email protected]4145d172013-05-10 16:54:36836SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
837 TextureLayerImplWithMailboxThreadedCallback);
[email protected]de44a152013-01-08 15:28:46838
[email protected]74b43cc2013-08-30 06:29:27839
[email protected]74b43cc2013-08-30 06:29:27840class TextureLayerMailboxIsActivatedDuringCommit : public LayerTreeTest {
841 protected:
[email protected]98ea818e2014-01-24 10:22:08842 TextureLayerMailboxIsActivatedDuringCommit() : activate_count_(0) {}
[email protected]74b43cc2013-08-30 06:29:27843
[email protected]df41e252014-02-03 23:39:50844 static void ReleaseCallback(uint32 sync_point, bool lost_resource) {}
[email protected]74b43cc2013-08-30 06:29:27845
846 void SetMailbox(char mailbox_char) {
[email protected]9260757f2013-09-17 01:24:16847 scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create(
[email protected]74b43cc2013-08-30 06:29:27848 base::Bind(
849 &TextureLayerMailboxIsActivatedDuringCommit::ReleaseCallback));
[email protected]df41e252014-02-03 23:39:50850 layer_->SetTextureMailbox(
[email protected]e0a4d732014-02-15 00:23:26851 TextureMailbox(MailboxFromChar(mailbox_char), GL_TEXTURE_2D, 0),
[email protected]df41e252014-02-03 23:39:50852 callback.Pass());
[email protected]74b43cc2013-08-30 06:29:27853 }
854
dcheng716bedf2014-10-21 09:51:08855 void BeginTest() override {
[email protected]74b43cc2013-08-30 06:29:27856 gfx::Size bounds(100, 100);
857 root_ = Layer::Create();
[email protected]74b43cc2013-08-30 06:29:27858 root_->SetBounds(bounds);
859
kulkarni.a4015690f12014-10-10 13:50:06860 layer_ = TextureLayer::CreateForMailbox(nullptr);
[email protected]74b43cc2013-08-30 06:29:27861 layer_->SetIsDrawable(true);
[email protected]74b43cc2013-08-30 06:29:27862 layer_->SetBounds(bounds);
863
864 root_->AddChild(layer_);
865 layer_tree_host()->SetRootLayer(root_);
866 layer_tree_host()->SetViewportSize(bounds);
867 SetMailbox('1');
868
869 PostSetNeedsCommitToMainThread();
870 }
871
dcheng716bedf2014-10-21 09:51:08872 void WillActivateTreeOnThread(LayerTreeHostImpl* impl) override {
[email protected]74b43cc2013-08-30 06:29:27873 ++activate_count_;
874 }
875
dcheng716bedf2014-10-21 09:51:08876 void DidCommit() override {
[email protected]98ea818e2014-01-24 10:22:08877 switch (layer_tree_host()->source_frame_number()) {
[email protected]74b43cc2013-08-30 06:29:27878 case 1:
879 // The first mailbox has been activated. Set a new mailbox, and
880 // expect the next commit to finish *after* it is activated.
881 SetMailbox('2');
[email protected]74b43cc2013-08-30 06:29:27882 break;
883 case 2:
884 // The second mailbox has been activated. Remove the layer from
885 // the tree to cause another commit/activation. The commit should
886 // finish *after* the layer is removed from the active tree.
887 layer_->RemoveFromParent();
[email protected]74b43cc2013-08-30 06:29:27888 break;
889 case 3:
890 EndTest();
891 break;
892 }
893 }
894
dcheng716bedf2014-10-21 09:51:08895 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
[email protected]98ea818e2014-01-24 10:22:08896 switch (host_impl->active_tree()->source_frame_number()) {
[email protected]b6061062014-06-27 19:20:08897 case 0: {
898 // The activate for the 1st mailbox should have happened before now.
899 EXPECT_EQ(1, activate_count_);
900 break;
901 }
902 case 1: {
[email protected]74b43cc2013-08-30 06:29:27903 // The activate for the 2nd mailbox should have happened before now.
[email protected]74b43cc2013-08-30 06:29:27904 EXPECT_EQ(2, activate_count_);
905 break;
906 }
[email protected]b6061062014-06-27 19:20:08907 case 2: {
[email protected]74b43cc2013-08-30 06:29:27908 // The activate to remove the layer should have happened before now.
[email protected]74b43cc2013-08-30 06:29:27909 EXPECT_EQ(3, activate_count_);
910 break;
911 }
[email protected]b6061062014-06-27 19:20:08912 case 3: {
913 NOTREACHED();
914 break;
915 }
[email protected]74b43cc2013-08-30 06:29:27916 }
917 }
918
dcheng716bedf2014-10-21 09:51:08919 void AfterTest() override {}
[email protected]74b43cc2013-08-30 06:29:27920
[email protected]74b43cc2013-08-30 06:29:27921 int activate_count_;
922 scoped_refptr<Layer> root_;
923 scoped_refptr<TextureLayer> layer_;
924};
925
926SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
927 TextureLayerMailboxIsActivatedDuringCommit);
928
[email protected]de44a152013-01-08 15:28:46929class TextureLayerImplWithMailboxTest : public TextureLayerTest {
[email protected]28571b042013-03-14 07:59:15930 protected:
[email protected]408b5e22013-03-19 09:48:09931 TextureLayerImplWithMailboxTest()
932 : fake_client_(
933 FakeLayerTreeHostClient(FakeLayerTreeHostClient::DIRECT_3D)) {}
934
[email protected]28571b042013-03-14 07:59:15935 virtual void SetUp() {
936 TextureLayerTest::SetUp();
[email protected]408b5e22013-03-19 09:48:09937 layer_tree_host_.reset(new MockLayerTreeHost(&fake_client_));
danakjf446a072014-09-27 21:55:48938 EXPECT_TRUE(host_impl_.InitializeRenderer(FakeOutputSurface::Create3d()));
[email protected]28571b042013-03-14 07:59:15939 }
[email protected]de44a152013-01-08 15:28:46940
[email protected]0ec335c42013-07-04 06:17:08941 bool WillDraw(TextureLayerImpl* layer, DrawMode mode) {
942 bool will_draw = layer->WillDraw(
943 mode, host_impl_.active_tree()->resource_provider());
944 if (will_draw)
945 layer->DidDraw(host_impl_.active_tree()->resource_provider());
946 return will_draw;
947 }
948
[email protected]28571b042013-03-14 07:59:15949 CommonMailboxObjects test_data_;
[email protected]408b5e22013-03-19 09:48:09950 FakeLayerTreeHostClient fake_client_;
[email protected]de44a152013-01-08 15:28:46951};
952
[email protected]ffbb2212013-06-02 23:47:59953// Test conditions for results of TextureLayerImpl::WillDraw under
954// different configurations of different mailbox, texture_id, and draw_mode.
955TEST_F(TextureLayerImplWithMailboxTest, TestWillDraw) {
skyostil3976a3f2014-09-04 22:07:23956 EXPECT_CALL(
957 test_data_.mock_callback_,
958 ReleaseImpl(test_data_.mailbox_name1_, test_data_.sync_point1_, false, _))
[email protected]0ec335c42013-07-04 06:17:08959 .Times(AnyNumber());
960 EXPECT_CALL(test_data_.mock_callback_,
skyostil3976a3f2014-09-04 22:07:23961 ReleaseImpl2(test_data_.shared_memory_.get(), 0, false, _))
[email protected]0ec335c42013-07-04 06:17:08962 .Times(AnyNumber());
[email protected]ffbb2212013-06-02 23:47:59963 // Hardware mode.
964 {
965 scoped_ptr<TextureLayerImpl> impl_layer =
[email protected]17e08432014-04-10 00:41:11966 TextureLayerImpl::Create(host_impl_.active_tree(), 1);
[email protected]9260757f2013-09-17 01:24:16967 impl_layer->SetTextureMailbox(
968 test_data_.mailbox1_,
skyostil3976a3f2014-09-04 22:07:23969 SingleReleaseCallbackImpl::Create(test_data_.release_mailbox1_impl_));
[email protected]0ec335c42013-07-04 06:17:08970 EXPECT_TRUE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE));
[email protected]ffbb2212013-06-02 23:47:59971 }
972
973 {
974 scoped_ptr<TextureLayerImpl> impl_layer =
[email protected]17e08432014-04-10 00:41:11975 TextureLayerImpl::Create(host_impl_.active_tree(), 1);
danakj968153f32014-10-15 22:52:16976 impl_layer->SetTextureMailbox(TextureMailbox(), nullptr);
[email protected]0ec335c42013-07-04 06:17:08977 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE));
978 }
979
980 {
981 // Software resource.
982 scoped_ptr<TextureLayerImpl> impl_layer =
[email protected]17e08432014-04-10 00:41:11983 TextureLayerImpl::Create(host_impl_.active_tree(), 1);
[email protected]9260757f2013-09-17 01:24:16984 impl_layer->SetTextureMailbox(
985 test_data_.mailbox3_,
skyostil3976a3f2014-09-04 22:07:23986 SingleReleaseCallbackImpl::Create(test_data_.release_mailbox3_impl_));
[email protected]3e44d7a2013-07-30 00:03:10987 EXPECT_TRUE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE));
[email protected]ffbb2212013-06-02 23:47:59988 }
989
[email protected]0ec335c42013-07-04 06:17:08990 // Software mode.
991 {
992 scoped_ptr<TextureLayerImpl> impl_layer =
[email protected]17e08432014-04-10 00:41:11993 TextureLayerImpl::Create(host_impl_.active_tree(), 1);
[email protected]9260757f2013-09-17 01:24:16994 impl_layer->SetTextureMailbox(
995 test_data_.mailbox1_,
skyostil3976a3f2014-09-04 22:07:23996 SingleReleaseCallbackImpl::Create(test_data_.release_mailbox1_impl_));
[email protected]0ec335c42013-07-04 06:17:08997 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE));
998 }
999
1000 {
1001 scoped_ptr<TextureLayerImpl> impl_layer =
[email protected]17e08432014-04-10 00:41:111002 TextureLayerImpl::Create(host_impl_.active_tree(), 1);
danakj968153f32014-10-15 22:52:161003 impl_layer->SetTextureMailbox(TextureMailbox(), nullptr);
[email protected]0ec335c42013-07-04 06:17:081004 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE));
1005 }
1006
1007 {
1008 // Software resource.
1009 scoped_ptr<TextureLayerImpl> impl_layer =
[email protected]17e08432014-04-10 00:41:111010 TextureLayerImpl::Create(host_impl_.active_tree(), 1);
[email protected]9260757f2013-09-17 01:24:161011 impl_layer->SetTextureMailbox(
1012 test_data_.mailbox3_,
skyostil3976a3f2014-09-04 22:07:231013 SingleReleaseCallbackImpl::Create(test_data_.release_mailbox3_impl_));
[email protected]0ec335c42013-07-04 06:17:081014 EXPECT_TRUE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE));
1015 }
1016
[email protected]ffbb2212013-06-02 23:47:591017 // Resourceless software mode.
1018 {
1019 scoped_ptr<TextureLayerImpl> impl_layer =
[email protected]17e08432014-04-10 00:41:111020 TextureLayerImpl::Create(host_impl_.active_tree(), 1);
[email protected]9260757f2013-09-17 01:24:161021 impl_layer->SetTextureMailbox(
1022 test_data_.mailbox1_,
skyostil3976a3f2014-09-04 22:07:231023 SingleReleaseCallbackImpl::Create(test_data_.release_mailbox1_impl_));
[email protected]0ec335c42013-07-04 06:17:081024 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_RESOURCELESS_SOFTWARE));
[email protected]ffbb2212013-06-02 23:47:591025 }
[email protected]ffbb2212013-06-02 23:47:591026}
1027
[email protected]28571b042013-03-14 07:59:151028TEST_F(TextureLayerImplWithMailboxTest, TestImplLayerCallbacks) {
1029 host_impl_.CreatePendingTree();
1030 scoped_ptr<TextureLayerImpl> pending_layer;
[email protected]17e08432014-04-10 00:41:111031 pending_layer = TextureLayerImpl::Create(host_impl_.pending_tree(), 1);
[email protected]28571b042013-03-14 07:59:151032 ASSERT_TRUE(pending_layer);
[email protected]de44a152013-01-08 15:28:461033
[email protected]ed511b8d2013-03-25 03:29:291034 scoped_ptr<LayerImpl> active_layer(
[email protected]28571b042013-03-14 07:59:151035 pending_layer->CreateLayerImpl(host_impl_.active_tree()));
[email protected]ed511b8d2013-03-25 03:29:291036 ASSERT_TRUE(active_layer);
[email protected]de44a152013-01-08 15:28:461037
[email protected]9260757f2013-09-17 01:24:161038 pending_layer->SetTextureMailbox(
1039 test_data_.mailbox1_,
skyostil3976a3f2014-09-04 22:07:231040 SingleReleaseCallbackImpl::Create(test_data_.release_mailbox1_impl_));
[email protected]421e84f2013-02-22 03:27:151041
[email protected]28571b042013-03-14 07:59:151042 // Test multiple commits without an activation.
skyostil3976a3f2014-09-04 22:07:231043 EXPECT_CALL(
1044 test_data_.mock_callback_,
1045 ReleaseImpl(test_data_.mailbox_name1_, test_data_.sync_point1_, false, _))
[email protected]28571b042013-03-14 07:59:151046 .Times(1);
[email protected]9260757f2013-09-17 01:24:161047 pending_layer->SetTextureMailbox(
1048 test_data_.mailbox2_,
skyostil3976a3f2014-09-04 22:07:231049 SingleReleaseCallbackImpl::Create(test_data_.release_mailbox2_impl_));
[email protected]28571b042013-03-14 07:59:151050 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]421e84f2013-02-22 03:27:151051
[email protected]28571b042013-03-14 07:59:151052 // Test callback after activation.
[email protected]ed511b8d2013-03-25 03:29:291053 pending_layer->PushPropertiesTo(active_layer.get());
1054 active_layer->DidBecomeActive();
[email protected]421e84f2013-02-22 03:27:151055
skyostil3976a3f2014-09-04 22:07:231056 EXPECT_CALL(test_data_.mock_callback_, ReleaseImpl(_, _, _, _)).Times(0);
[email protected]9260757f2013-09-17 01:24:161057 pending_layer->SetTextureMailbox(
1058 test_data_.mailbox1_,
skyostil3976a3f2014-09-04 22:07:231059 SingleReleaseCallbackImpl::Create(test_data_.release_mailbox1_impl_));
[email protected]28571b042013-03-14 07:59:151060 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]421e84f2013-02-22 03:27:151061
[email protected]7ba3ca72013-04-11 06:37:251062 EXPECT_CALL(test_data_.mock_callback_,
skyostil3976a3f2014-09-04 22:07:231063 ReleaseImpl(test_data_.mailbox_name2_, _, false, _)).Times(1);
[email protected]ed511b8d2013-03-25 03:29:291064 pending_layer->PushPropertiesTo(active_layer.get());
1065 active_layer->DidBecomeActive();
[email protected]28571b042013-03-14 07:59:151066 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]de44a152013-01-08 15:28:461067
[email protected]28571b042013-03-14 07:59:151068 // Test resetting the mailbox.
[email protected]7ba3ca72013-04-11 06:37:251069 EXPECT_CALL(test_data_.mock_callback_,
skyostil3976a3f2014-09-04 22:07:231070 ReleaseImpl(test_data_.mailbox_name1_, _, false, _)).Times(1);
danakj968153f32014-10-15 22:52:161071 pending_layer->SetTextureMailbox(TextureMailbox(), nullptr);
[email protected]ed511b8d2013-03-25 03:29:291072 pending_layer->PushPropertiesTo(active_layer.get());
1073 active_layer->DidBecomeActive();
[email protected]28571b042013-03-14 07:59:151074 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]de44a152013-01-08 15:28:461075
[email protected]28571b042013-03-14 07:59:151076 // Test destructor.
skyostil3976a3f2014-09-04 22:07:231077 EXPECT_CALL(
1078 test_data_.mock_callback_,
1079 ReleaseImpl(test_data_.mailbox_name1_, test_data_.sync_point1_, false, _))
[email protected]28571b042013-03-14 07:59:151080 .Times(1);
[email protected]9260757f2013-09-17 01:24:161081 pending_layer->SetTextureMailbox(
1082 test_data_.mailbox1_,
skyostil3976a3f2014-09-04 22:07:231083 SingleReleaseCallbackImpl::Create(test_data_.release_mailbox1_impl_));
[email protected]de44a152013-01-08 15:28:461084}
1085
[email protected]28571b042013-03-14 07:59:151086TEST_F(TextureLayerImplWithMailboxTest,
1087 TestDestructorCallbackOnCreatedResource) {
1088 scoped_ptr<TextureLayerImpl> impl_layer;
[email protected]17e08432014-04-10 00:41:111089 impl_layer = TextureLayerImpl::Create(host_impl_.active_tree(), 1);
[email protected]28571b042013-03-14 07:59:151090 ASSERT_TRUE(impl_layer);
[email protected]de44a152013-01-08 15:28:461091
[email protected]7ba3ca72013-04-11 06:37:251092 EXPECT_CALL(test_data_.mock_callback_,
skyostil3976a3f2014-09-04 22:07:231093 ReleaseImpl(test_data_.mailbox_name1_, _, false, _)).Times(1);
[email protected]9260757f2013-09-17 01:24:161094 impl_layer->SetTextureMailbox(
1095 test_data_.mailbox1_,
skyostil3976a3f2014-09-04 22:07:231096 SingleReleaseCallbackImpl::Create(test_data_.release_mailbox1_impl_));
[email protected]ffbb2212013-06-02 23:47:591097 impl_layer->DidBecomeActive();
1098 EXPECT_TRUE(impl_layer->WillDraw(
1099 DRAW_MODE_HARDWARE, host_impl_.active_tree()->resource_provider()));
[email protected]28571b042013-03-14 07:59:151100 impl_layer->DidDraw(host_impl_.active_tree()->resource_provider());
danakj968153f32014-10-15 22:52:161101 impl_layer->SetTextureMailbox(TextureMailbox(), nullptr);
[email protected]de44a152013-01-08 15:28:461102}
1103
[email protected]28571b042013-03-14 07:59:151104TEST_F(TextureLayerImplWithMailboxTest, TestCallbackOnInUseResource) {
1105 ResourceProvider* provider = host_impl_.active_tree()->resource_provider();
skyostil3976a3f2014-09-04 22:07:231106 ResourceProvider::ResourceId id = provider->CreateResourceFromTextureMailbox(
1107 test_data_.mailbox1_,
1108 SingleReleaseCallbackImpl::Create(test_data_.release_mailbox1_impl_));
[email protected]28571b042013-03-14 07:59:151109 provider->AllocateForTesting(id);
[email protected]de44a152013-01-08 15:28:461110
[email protected]28571b042013-03-14 07:59:151111 // Transfer some resources to the parent.
1112 ResourceProvider::ResourceIdArray resource_ids_to_transfer;
1113 resource_ids_to_transfer.push_back(id);
1114 TransferableResourceArray list;
1115 provider->PrepareSendToParent(resource_ids_to_transfer, &list);
1116 EXPECT_TRUE(provider->InUseByConsumer(id));
skyostil3976a3f2014-09-04 22:07:231117 EXPECT_CALL(test_data_.mock_callback_, ReleaseImpl(_, _, _, _)).Times(0);
[email protected]28571b042013-03-14 07:59:151118 provider->DeleteResource(id);
1119 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]7ba3ca72013-04-11 06:37:251120 EXPECT_CALL(test_data_.mock_callback_,
skyostil3976a3f2014-09-04 22:07:231121 ReleaseImpl(test_data_.mailbox_name1_, _, false, _)).Times(1);
[email protected]e00bab022013-08-19 00:42:451122 ReturnedResourceArray returned;
1123 TransferableResource::ReturnResources(list, &returned);
1124 provider->ReceiveReturnsFromParent(returned);
[email protected]de44a152013-01-08 15:28:461125}
1126
[email protected]4bad8b62013-10-24 01:27:291127// Checks that TextureLayer::Update does not cause an extra commit when setting
1128// the texture mailbox.
1129class TextureLayerNoExtraCommitForMailboxTest
1130 : public LayerTreeTest,
1131 public TextureLayerClient {
1132 public:
[email protected]4bad8b62013-10-24 01:27:291133 // TextureLayerClient implementation.
dcheng716bedf2014-10-21 09:51:081134 bool PrepareTextureMailbox(
[email protected]df41e252014-02-03 23:39:501135 TextureMailbox* texture_mailbox,
[email protected]4bad8b62013-10-24 01:27:291136 scoped_ptr<SingleReleaseCallback>* release_callback,
mostynbf68776d82014-10-06 18:07:371137 bool use_shared_memory) override {
[email protected]cce34bd2013-12-02 23:24:451138 if (layer_tree_host()->source_frame_number() == 1) {
[email protected]9f35bd22014-06-03 15:25:461139 // Once this has been committed, the mailbox will be released.
[email protected]df41e252014-02-03 23:39:501140 *texture_mailbox = TextureMailbox();
[email protected]cce34bd2013-12-02 23:24:451141 return true;
1142 }
[email protected]4bad8b62013-10-24 01:27:291143
[email protected]e0a4d732014-02-15 00:23:261144 *texture_mailbox = TextureMailbox(MailboxFromChar('1'), GL_TEXTURE_2D, 0);
[email protected]4bad8b62013-10-24 01:27:291145 *release_callback = SingleReleaseCallback::Create(
1146 base::Bind(&TextureLayerNoExtraCommitForMailboxTest::MailboxReleased,
1147 base::Unretained(this)));
[email protected]4bad8b62013-10-24 01:27:291148 return true;
1149 }
1150
[email protected]df41e252014-02-03 23:39:501151 void MailboxReleased(uint32 sync_point, bool lost_resource) {
[email protected]9f35bd22014-06-03 15:25:461152 // Source frame number during callback is the same as the source frame
1153 // on which it was released.
1154 EXPECT_EQ(1, layer_tree_host()->source_frame_number());
[email protected]cce34bd2013-12-02 23:24:451155 EndTest();
[email protected]4bad8b62013-10-24 01:27:291156 }
1157
dcheng716bedf2014-10-21 09:51:081158 void SetupTree() override {
[email protected]4bad8b62013-10-24 01:27:291159 scoped_refptr<Layer> root = Layer::Create();
1160 root->SetBounds(gfx::Size(10, 10));
[email protected]4bad8b62013-10-24 01:27:291161 root->SetIsDrawable(true);
1162
[email protected]4bad8b62013-10-24 01:27:291163 texture_layer_ = TextureLayer::CreateForMailbox(this);
1164 texture_layer_->SetBounds(gfx::Size(10, 10));
[email protected]4bad8b62013-10-24 01:27:291165 texture_layer_->SetIsDrawable(true);
[email protected]0d7fb302014-01-23 21:30:471166 root->AddChild(texture_layer_);
[email protected]4bad8b62013-10-24 01:27:291167
1168 layer_tree_host()->SetRootLayer(root);
1169 LayerTreeTest::SetupTree();
1170 }
1171
dcheng716bedf2014-10-21 09:51:081172 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
[email protected]4bad8b62013-10-24 01:27:291173
dcheng716bedf2014-10-21 09:51:081174 void DidCommitAndDrawFrame() override {
[email protected]4bad8b62013-10-24 01:27:291175 switch (layer_tree_host()->source_frame_number()) {
1176 case 1:
[email protected]4ea293f72014-08-13 03:03:171177 EXPECT_FALSE(proxy()->MainFrameWillHappenForTesting());
[email protected]cce34bd2013-12-02 23:24:451178 // Invalidate the texture layer to clear the mailbox before
1179 // ending the test.
1180 texture_layer_->SetNeedsDisplay();
1181 break;
1182 case 2:
[email protected]4bad8b62013-10-24 01:27:291183 break;
1184 default:
1185 NOTREACHED();
1186 break;
1187 }
1188 }
1189
dcheng716bedf2014-10-21 09:51:081190 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override {
[email protected]cce34bd2013-12-02 23:24:451191 ASSERT_TRUE(result);
1192 DelegatedFrameData* delegated_frame_data =
1193 output_surface()->last_sent_frame().delegated_frame_data.get();
1194 if (!delegated_frame_data)
1195 return;
1196
1197 // Return all resources immediately.
1198 TransferableResourceArray resources_to_return =
1199 output_surface()->resources_held_by_parent();
1200
1201 CompositorFrameAck ack;
1202 for (size_t i = 0; i < resources_to_return.size(); ++i)
1203 output_surface()->ReturnResource(resources_to_return[i].id, &ack);
1204 host_impl->ReclaimResources(&ack);
[email protected]cce34bd2013-12-02 23:24:451205 }
1206
dcheng716bedf2014-10-21 09:51:081207 void AfterTest() override {}
[email protected]4bad8b62013-10-24 01:27:291208
1209 private:
[email protected]4bad8b62013-10-24 01:27:291210 scoped_refptr<TextureLayer> texture_layer_;
[email protected]4bad8b62013-10-24 01:27:291211};
1212
[email protected]cce34bd2013-12-02 23:24:451213SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerNoExtraCommitForMailboxTest);
[email protected]4bad8b62013-10-24 01:27:291214
[email protected]b04264f92013-09-13 23:37:291215// Checks that changing a mailbox in the client for a TextureLayer that's
1216// invisible correctly works and uses the new mailbox as soon as the layer
1217// becomes visible (and returns the old one).
1218class TextureLayerChangeInvisibleMailboxTest
1219 : public LayerTreeTest,
1220 public TextureLayerClient {
1221 public:
1222 TextureLayerChangeInvisibleMailboxTest()
1223 : mailbox_changed_(true),
1224 mailbox_returned_(0),
1225 prepare_called_(0),
1226 commit_count_(0) {
1227 mailbox_ = MakeMailbox('1');
1228 }
1229
1230 // TextureLayerClient implementation.
dcheng716bedf2014-10-21 09:51:081231 bool PrepareTextureMailbox(
[email protected]e51444a2013-12-10 23:05:011232 TextureMailbox* mailbox,
[email protected]9260757f2013-09-17 01:24:161233 scoped_ptr<SingleReleaseCallback>* release_callback,
mostynbf68776d82014-10-06 18:07:371234 bool use_shared_memory) override {
[email protected]b04264f92013-09-13 23:37:291235 ++prepare_called_;
1236 if (!mailbox_changed_)
1237 return false;
1238 *mailbox = mailbox_;
[email protected]9260757f2013-09-17 01:24:161239 *release_callback = SingleReleaseCallback::Create(
1240 base::Bind(&TextureLayerChangeInvisibleMailboxTest::MailboxReleased,
1241 base::Unretained(this)));
[email protected]b04264f92013-09-13 23:37:291242 return true;
1243 }
1244
1245 TextureMailbox MakeMailbox(char name) {
[email protected]e0a4d732014-02-15 00:23:261246 return TextureMailbox(MailboxFromChar(name), GL_TEXTURE_2D, 0);
[email protected]b04264f92013-09-13 23:37:291247 }
1248
[email protected]df41e252014-02-03 23:39:501249 void MailboxReleased(uint32 sync_point, bool lost_resource) {
[email protected]b04264f92013-09-13 23:37:291250 ++mailbox_returned_;
1251 }
1252
dcheng716bedf2014-10-21 09:51:081253 void SetupTree() override {
[email protected]b04264f92013-09-13 23:37:291254 scoped_refptr<Layer> root = Layer::Create();
1255 root->SetBounds(gfx::Size(10, 10));
[email protected]b04264f92013-09-13 23:37:291256 root->SetIsDrawable(true);
1257
1258 solid_layer_ = SolidColorLayer::Create();
1259 solid_layer_->SetBounds(gfx::Size(10, 10));
1260 solid_layer_->SetIsDrawable(true);
1261 solid_layer_->SetBackgroundColor(SK_ColorWHITE);
1262 root->AddChild(solid_layer_);
1263
1264 parent_layer_ = Layer::Create();
1265 parent_layer_->SetBounds(gfx::Size(10, 10));
1266 parent_layer_->SetIsDrawable(true);
1267 root->AddChild(parent_layer_);
1268
1269 texture_layer_ = TextureLayer::CreateForMailbox(this);
1270 texture_layer_->SetBounds(gfx::Size(10, 10));
[email protected]b04264f92013-09-13 23:37:291271 texture_layer_->SetIsDrawable(true);
1272 parent_layer_->AddChild(texture_layer_);
1273
1274 layer_tree_host()->SetRootLayer(root);
1275 LayerTreeTest::SetupTree();
1276 }
1277
dcheng716bedf2014-10-21 09:51:081278 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
[email protected]b04264f92013-09-13 23:37:291279
dcheng716bedf2014-10-21 09:51:081280 void DidCommitAndDrawFrame() override {
[email protected]b04264f92013-09-13 23:37:291281 ++commit_count_;
1282 switch (commit_count_) {
1283 case 1:
1284 // We should have updated the layer, committing the texture.
1285 EXPECT_EQ(1, prepare_called_);
1286 // Make layer invisible.
1287 parent_layer_->SetOpacity(0.f);
1288 break;
1289 case 2:
1290 // Layer shouldn't have been updated.
1291 EXPECT_EQ(1, prepare_called_);
1292 // Change the texture.
1293 mailbox_ = MakeMailbox('2');
1294 mailbox_changed_ = true;
1295 texture_layer_->SetNeedsDisplay();
1296 // Force a change to make sure we draw a frame.
1297 solid_layer_->SetBackgroundColor(SK_ColorGRAY);
1298 break;
1299 case 3:
1300 // Layer shouldn't have been updated.
1301 EXPECT_EQ(1, prepare_called_);
1302 // So the old mailbox isn't returned yet.
1303 EXPECT_EQ(0, mailbox_returned_);
1304 // Make layer visible again.
1305 parent_layer_->SetOpacity(1.f);
1306 break;
1307 case 4:
1308 // Layer should have been updated.
1309 EXPECT_EQ(2, prepare_called_);
1310 // So the old mailbox should have been returned already.
1311 EXPECT_EQ(1, mailbox_returned_);
1312 texture_layer_->ClearClient();
1313 break;
1314 case 5:
1315 EXPECT_EQ(2, mailbox_returned_);
1316 EndTest();
1317 break;
1318 default:
1319 NOTREACHED();
1320 break;
1321 }
1322 }
1323
dcheng716bedf2014-10-21 09:51:081324 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override {
[email protected]b04264f92013-09-13 23:37:291325 ASSERT_TRUE(result);
1326 DelegatedFrameData* delegated_frame_data =
1327 output_surface()->last_sent_frame().delegated_frame_data.get();
1328 if (!delegated_frame_data)
1329 return;
1330
1331 // Return all resources immediately.
1332 TransferableResourceArray resources_to_return =
1333 output_surface()->resources_held_by_parent();
1334
1335 CompositorFrameAck ack;
1336 for (size_t i = 0; i < resources_to_return.size(); ++i)
1337 output_surface()->ReturnResource(resources_to_return[i].id, &ack);
[email protected]a7335e0b2013-09-18 09:34:511338 host_impl->ReclaimResources(&ack);
[email protected]b04264f92013-09-13 23:37:291339 }
1340
dcheng716bedf2014-10-21 09:51:081341 void AfterTest() override {}
[email protected]b04264f92013-09-13 23:37:291342
1343 private:
1344 scoped_refptr<SolidColorLayer> solid_layer_;
1345 scoped_refptr<Layer> parent_layer_;
1346 scoped_refptr<TextureLayer> texture_layer_;
1347
1348 // Used on the main thread.
1349 bool mailbox_changed_;
1350 TextureMailbox mailbox_;
1351 int mailbox_returned_;
1352 int prepare_called_;
1353 int commit_count_;
1354};
1355
1356SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerChangeInvisibleMailboxTest);
1357
[email protected]0d7fb302014-01-23 21:30:471358// Test that TextureLayerImpl::ReleaseResources can be called which releases
1359// the mailbox back to TextureLayerClient.
1360class TextureLayerReleaseResourcesBase
1361 : public LayerTreeTest,
1362 public TextureLayerClient {
1363 public:
1364 // TextureLayerClient implementation.
dcheng716bedf2014-10-21 09:51:081365 bool PrepareTextureMailbox(
[email protected]0d7fb302014-01-23 21:30:471366 TextureMailbox* mailbox,
1367 scoped_ptr<SingleReleaseCallback>* release_callback,
mostynbf68776d82014-10-06 18:07:371368 bool use_shared_memory) override {
[email protected]e0a4d732014-02-15 00:23:261369 *mailbox = TextureMailbox(MailboxFromChar('1'), GL_TEXTURE_2D, 0);
[email protected]0d7fb302014-01-23 21:30:471370 *release_callback = SingleReleaseCallback::Create(
1371 base::Bind(&TextureLayerReleaseResourcesBase::MailboxReleased,
1372 base::Unretained(this)));
1373 return true;
1374 }
1375
1376 void MailboxReleased(unsigned sync_point, bool lost_resource) {
1377 mailbox_released_ = true;
1378 }
1379
dcheng716bedf2014-10-21 09:51:081380 void SetupTree() override {
[email protected]0d7fb302014-01-23 21:30:471381 LayerTreeTest::SetupTree();
1382
1383 scoped_refptr<TextureLayer> texture_layer =
1384 TextureLayer::CreateForMailbox(this);
1385 texture_layer->SetBounds(gfx::Size(10, 10));
[email protected]0d7fb302014-01-23 21:30:471386 texture_layer->SetIsDrawable(true);
1387
1388 layer_tree_host()->root_layer()->AddChild(texture_layer);
1389 }
1390
dcheng716bedf2014-10-21 09:51:081391 void BeginTest() override {
[email protected]0d7fb302014-01-23 21:30:471392 mailbox_released_ = false;
1393 PostSetNeedsCommitToMainThread();
1394 }
1395
dcheng716bedf2014-10-21 09:51:081396 void DidCommitAndDrawFrame() override { EndTest(); }
[email protected]0d7fb302014-01-23 21:30:471397
dcheng716bedf2014-10-21 09:51:081398 void AfterTest() override { EXPECT_TRUE(mailbox_released_); }
[email protected]0d7fb302014-01-23 21:30:471399
1400 private:
1401 bool mailbox_released_;
1402};
1403
1404class TextureLayerReleaseResourcesAfterCommit
1405 : public TextureLayerReleaseResourcesBase {
1406 public:
dcheng716bedf2014-10-21 09:51:081407 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
kulkarni.a4015690f12014-10-10 13:50:061408 LayerTreeImpl* tree = nullptr;
[email protected]0d7fb302014-01-23 21:30:471409 if (host_impl->settings().impl_side_painting)
1410 tree = host_impl->pending_tree();
1411 else
1412 tree = host_impl->active_tree();
1413 tree->root_layer()->children()[0]->ReleaseResources();
1414 }
1415};
1416
1417SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerReleaseResourcesAfterCommit);
1418
1419class TextureLayerReleaseResourcesAfterActivate
1420 : public TextureLayerReleaseResourcesBase {
1421 public:
dcheng716bedf2014-10-21 09:51:081422 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
[email protected]0d7fb302014-01-23 21:30:471423 host_impl->active_tree()->root_layer()->children()[0]->ReleaseResources();
1424 }
1425};
1426
1427SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerReleaseResourcesAfterActivate);
1428
[email protected]9c2bd822013-07-26 12:30:171429class TextureLayerWithMailboxMainThreadDeleted : public LayerTreeTest {
1430 public:
[email protected]df41e252014-02-03 23:39:501431 void ReleaseCallback(uint32 sync_point, bool lost_resource) {
[email protected]9794fb32013-08-29 09:49:591432 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]9c2bd822013-07-26 12:30:171433 EXPECT_FALSE(lost_resource);
1434 ++callback_count_;
1435 EndTest();
1436 }
1437
1438 void SetMailbox(char mailbox_char) {
[email protected]9794fb32013-08-29 09:49:591439 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]9260757f2013-09-17 01:24:161440 scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create(
[email protected]9c2bd822013-07-26 12:30:171441 base::Bind(
1442 &TextureLayerWithMailboxMainThreadDeleted::ReleaseCallback,
1443 base::Unretained(this)));
[email protected]df41e252014-02-03 23:39:501444 layer_->SetTextureMailbox(
[email protected]e0a4d732014-02-15 00:23:261445 TextureMailbox(MailboxFromChar(mailbox_char), GL_TEXTURE_2D, 0),
[email protected]df41e252014-02-03 23:39:501446 callback.Pass());
[email protected]9c2bd822013-07-26 12:30:171447 }
1448
dcheng716bedf2014-10-21 09:51:081449 void SetupTree() override {
[email protected]9c2bd822013-07-26 12:30:171450 gfx::Size bounds(100, 100);
1451 root_ = Layer::Create();
[email protected]9c2bd822013-07-26 12:30:171452 root_->SetBounds(bounds);
1453
kulkarni.a4015690f12014-10-10 13:50:061454 layer_ = TextureLayer::CreateForMailbox(nullptr);
[email protected]9c2bd822013-07-26 12:30:171455 layer_->SetIsDrawable(true);
[email protected]9c2bd822013-07-26 12:30:171456 layer_->SetBounds(bounds);
1457
1458 root_->AddChild(layer_);
1459 layer_tree_host()->SetRootLayer(root_);
1460 layer_tree_host()->SetViewportSize(bounds);
1461 }
1462
dcheng716bedf2014-10-21 09:51:081463 void BeginTest() override {
[email protected]9794fb32013-08-29 09:49:591464 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
1465
[email protected]9c2bd822013-07-26 12:30:171466 callback_count_ = 0;
1467
1468 // Set the mailbox on the main thread.
1469 SetMailbox('1');
1470 EXPECT_EQ(0, callback_count_);
1471
1472 PostSetNeedsCommitToMainThread();
1473 }
1474
dcheng716bedf2014-10-21 09:51:081475 void DidCommitAndDrawFrame() override {
[email protected]9c2bd822013-07-26 12:30:171476 switch (layer_tree_host()->source_frame_number()) {
1477 case 1:
1478 // Delete the TextureLayer on the main thread while the mailbox is in
1479 // the impl tree.
1480 layer_->RemoveFromParent();
kulkarni.a4015690f12014-10-10 13:50:061481 layer_ = nullptr;
[email protected]9c2bd822013-07-26 12:30:171482 break;
1483 }
1484 }
1485
dcheng716bedf2014-10-21 09:51:081486 void AfterTest() override { EXPECT_EQ(1, callback_count_); }
[email protected]9c2bd822013-07-26 12:30:171487
1488 private:
[email protected]9794fb32013-08-29 09:49:591489 base::ThreadChecker main_thread_;
[email protected]9c2bd822013-07-26 12:30:171490 int callback_count_;
1491 scoped_refptr<Layer> root_;
1492 scoped_refptr<TextureLayer> layer_;
1493};
1494
1495SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
1496 TextureLayerWithMailboxMainThreadDeleted);
1497
1498class TextureLayerWithMailboxImplThreadDeleted : public LayerTreeTest {
1499 public:
[email protected]df41e252014-02-03 23:39:501500 void ReleaseCallback(uint32 sync_point, bool lost_resource) {
[email protected]9794fb32013-08-29 09:49:591501 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]9c2bd822013-07-26 12:30:171502 EXPECT_FALSE(lost_resource);
1503 ++callback_count_;
1504 EndTest();
1505 }
1506
1507 void SetMailbox(char mailbox_char) {
[email protected]9794fb32013-08-29 09:49:591508 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]9260757f2013-09-17 01:24:161509 scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create(
[email protected]9c2bd822013-07-26 12:30:171510 base::Bind(
1511 &TextureLayerWithMailboxImplThreadDeleted::ReleaseCallback,
1512 base::Unretained(this)));
[email protected]df41e252014-02-03 23:39:501513 layer_->SetTextureMailbox(
[email protected]e0a4d732014-02-15 00:23:261514 TextureMailbox(MailboxFromChar(mailbox_char), GL_TEXTURE_2D, 0),
[email protected]df41e252014-02-03 23:39:501515 callback.Pass());
[email protected]9c2bd822013-07-26 12:30:171516 }
1517
dcheng716bedf2014-10-21 09:51:081518 void SetupTree() override {
[email protected]9c2bd822013-07-26 12:30:171519 gfx::Size bounds(100, 100);
1520 root_ = Layer::Create();
[email protected]9c2bd822013-07-26 12:30:171521 root_->SetBounds(bounds);
1522
kulkarni.a4015690f12014-10-10 13:50:061523 layer_ = TextureLayer::CreateForMailbox(nullptr);
[email protected]9c2bd822013-07-26 12:30:171524 layer_->SetIsDrawable(true);
[email protected]9c2bd822013-07-26 12:30:171525 layer_->SetBounds(bounds);
1526
1527 root_->AddChild(layer_);
1528 layer_tree_host()->SetRootLayer(root_);
1529 layer_tree_host()->SetViewportSize(bounds);
1530 }
1531
dcheng716bedf2014-10-21 09:51:081532 void BeginTest() override {
[email protected]9794fb32013-08-29 09:49:591533 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
1534
[email protected]9c2bd822013-07-26 12:30:171535 callback_count_ = 0;
1536
1537 // Set the mailbox on the main thread.
1538 SetMailbox('1');
1539 EXPECT_EQ(0, callback_count_);
1540
1541 PostSetNeedsCommitToMainThread();
1542 }
1543
dcheng716bedf2014-10-21 09:51:081544 void DidCommitAndDrawFrame() override {
[email protected]9c2bd822013-07-26 12:30:171545 switch (layer_tree_host()->source_frame_number()) {
1546 case 1:
1547 // Remove the TextureLayer on the main thread while the mailbox is in
1548 // the impl tree, but don't delete the TextureLayer until after the impl
1549 // tree side is deleted.
1550 layer_->RemoveFromParent();
1551 break;
1552 case 2:
kulkarni.a4015690f12014-10-10 13:50:061553 layer_ = nullptr;
[email protected]9c2bd822013-07-26 12:30:171554 break;
1555 }
1556 }
1557
dcheng716bedf2014-10-21 09:51:081558 void AfterTest() override { EXPECT_EQ(1, callback_count_); }
[email protected]9c2bd822013-07-26 12:30:171559
1560 private:
[email protected]9794fb32013-08-29 09:49:591561 base::ThreadChecker main_thread_;
[email protected]9c2bd822013-07-26 12:30:171562 int callback_count_;
1563 scoped_refptr<Layer> root_;
1564 scoped_refptr<TextureLayer> layer_;
1565};
1566
1567SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
1568 TextureLayerWithMailboxImplThreadDeleted);
1569
[email protected]ba565742012-11-10 09:29:481570} // namespace
1571} // namespace cc