blob: 8846152f67aaf521187df8a82cd0a322d646e582 [file] [log] [blame]
[email protected]c0dd24c2012-08-30 23:25:271// Copyright 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]cc3cfaa2013-03-18 09:05:525#include "cc/layers/texture_layer.h"
[email protected]c0dd24c2012-08-30 23:25:276
[email protected]b04264f92013-09-13 23:37:297#include <algorithm>
[email protected]de44a152013-01-08 15:28:468#include <string>
9
[email protected]b04264f92013-09-13 23:37:2910#include "base/bind.h"
[email protected]de44a152013-01-08 15:28:4611#include "base/callback.h"
[email protected]9794fb32013-08-29 09:49:5912#include "base/synchronization/waitable_event.h"
[email protected]74b43cc2013-08-30 06:29:2713#include "base/threading/thread.h"
14#include "base/time/time.h"
[email protected]b04264f92013-09-13 23:37:2915#include "cc/layers/solid_color_layer.h"
[email protected]97d519fb2013-03-29 02:27:5416#include "cc/layers/texture_layer_client.h"
[email protected]cc3cfaa2013-03-18 09:05:5217#include "cc/layers/texture_layer_impl.h"
[email protected]b04264f92013-09-13 23:37:2918#include "cc/output/compositor_frame_ack.h"
19#include "cc/output/context_provider.h"
[email protected]e00bab022013-08-19 00:42:4520#include "cc/resources/returned_resource.h"
[email protected]586d51ed2012-12-07 20:31:4521#include "cc/test/fake_impl_proxy.h"
[email protected]101441ce2012-10-16 01:45:0322#include "cc/test/fake_layer_tree_host_client.h"
[email protected]586d51ed2012-12-07 20:31:4523#include "cc/test/fake_layer_tree_host_impl.h"
[email protected]199b715e2013-08-13 05:18:3424#include "cc/test/fake_output_surface.h"
[email protected]06d68d02013-04-19 18:46:2125#include "cc/test/layer_test_common.h"
[email protected]e216fef02013-03-20 22:56:1026#include "cc/test/layer_tree_test.h"
[email protected]c2610b9f2013-10-31 06:54:5927#include "cc/test/test_web_graphics_context_3d.h"
[email protected]9794fb32013-08-29 09:49:5928#include "cc/trees/blocking_task_runner.h"
[email protected]556fd292013-03-18 08:03:0429#include "cc/trees/layer_tree_host.h"
30#include "cc/trees/layer_tree_impl.h"
31#include "cc/trees/single_thread_proxy.h"
[email protected]0bf5a202013-07-10 14:50:5432#include "gpu/GLES2/gl2extchromium.h"
[email protected]7f0c53db2012-10-02 00:23:1833#include "testing/gmock/include/gmock/gmock.h"
34#include "testing/gtest/include/gtest/gtest.h"
[email protected]c0dd24c2012-08-30 23:25:2735
[email protected]c0dd24c2012-08-30 23:25:2736using ::testing::Mock;
37using ::testing::_;
38using ::testing::AtLeast;
39using ::testing::AnyNumber;
[email protected]d72d9e02014-04-03 18:40:0940using ::testing::InvokeWithoutArgs;
[email protected]c0dd24c2012-08-30 23:25:2741
[email protected]ba565742012-11-10 09:29:4842namespace cc {
[email protected]c0dd24c2012-08-30 23:25:2743namespace {
44
[email protected]e0a4d732014-02-15 00:23:2645gpu::Mailbox MailboxFromChar(char value) {
[email protected]df41e252014-02-03 23:39:5046 gpu::Mailbox mailbox;
[email protected]e0a4d732014-02-15 00:23:2647 memset(mailbox.name, value, sizeof(mailbox.name));
[email protected]df41e252014-02-03 23:39:5048 return mailbox;
49}
50
[email protected]408b5e22013-03-19 09:48:0951class MockLayerTreeHost : public LayerTreeHost {
[email protected]28571b042013-03-14 07:59:1552 public:
[email protected]943528e2013-11-07 05:01:3253 explicit MockLayerTreeHost(FakeLayerTreeHostClient* client)
[email protected]a7f35682013-10-22 23:05:5754 : LayerTreeHost(client, NULL, LayerTreeSettings()) {
[email protected]27e6a212014-07-18 15:51:2755 InitializeSingleThreaded(client, base::MessageLoopProxy::current());
[email protected]28571b042013-03-14 07:59:1556 }
[email protected]c0dd24c2012-08-30 23:25:2757
[email protected]28571b042013-03-14 07:59:1558 MOCK_METHOD0(SetNeedsCommit, void());
[email protected]3519b872013-07-30 07:17:5059 MOCK_METHOD0(SetNeedsUpdateLayers, void());
[email protected]aeeb3372013-11-05 14:05:5460 MOCK_METHOD0(StartRateLimiter, void());
61 MOCK_METHOD0(StopRateLimiter, void());
[email protected]c0dd24c2012-08-30 23:25:2762};
63
[email protected]d72d9e02014-04-03 18:40:0964class FakeTextureLayerClient : public TextureLayerClient {
65 public:
[email protected]17e08432014-04-10 00:41:1166 FakeTextureLayerClient() : mailbox_changed_(true) {}
[email protected]d72d9e02014-04-03 18:40:0967
68 virtual bool PrepareTextureMailbox(
69 TextureMailbox* mailbox,
70 scoped_ptr<SingleReleaseCallback>* release_callback,
mostynbf68776d82014-10-06 18:07:3771 bool use_shared_memory) override {
[email protected]d72d9e02014-04-03 18:40:0972 if (!mailbox_changed_)
73 return false;
74
75 *mailbox = mailbox_;
76 *release_callback = release_callback_.Pass();
77 mailbox_changed_ = false;
78 return true;
79 }
80
[email protected]d72d9e02014-04-03 18:40:0981 void set_mailbox(const TextureMailbox& mailbox,
82 scoped_ptr<SingleReleaseCallback> release_callback) {
83 mailbox_ = mailbox;
84 release_callback_ = release_callback.Pass();
85 mailbox_changed_ = true;
86 }
87
88 private:
[email protected]d72d9e02014-04-03 18:40:0989 TextureMailbox mailbox_;
90 scoped_ptr<SingleReleaseCallback> release_callback_;
91 bool mailbox_changed_;
92 DISALLOW_COPY_AND_ASSIGN(FakeTextureLayerClient);
93};
94
95class MockMailboxCallback {
96 public:
97 MOCK_METHOD3(Release,
98 void(const gpu::Mailbox& mailbox,
99 uint32 sync_point,
100 bool lost_resource));
101 MOCK_METHOD3(Release2,
102 void(base::SharedMemory* shared_memory,
103 uint32 sync_point,
104 bool lost_resource));
skyostil3976a3f2014-09-04 22:07:23105 MOCK_METHOD4(ReleaseImpl,
106 void(const gpu::Mailbox& mailbox,
107 uint32 sync_point,
108 bool lost_resource,
109 BlockingTaskRunner* main_thread_task_runner));
110 MOCK_METHOD4(ReleaseImpl2,
111 void(base::SharedMemory* shared_memory,
112 uint32 sync_point,
113 bool lost_resource,
114 BlockingTaskRunner* main_thread_task_runner));
[email protected]d72d9e02014-04-03 18:40:09115};
116
117struct CommonMailboxObjects {
118 CommonMailboxObjects()
119 : mailbox_name1_(MailboxFromChar('1')),
120 mailbox_name2_(MailboxFromChar('2')),
121 sync_point1_(1),
122 sync_point2_(2),
123 shared_memory_(new base::SharedMemory) {
124 release_mailbox1_ = base::Bind(&MockMailboxCallback::Release,
125 base::Unretained(&mock_callback_),
126 mailbox_name1_);
127 release_mailbox2_ = base::Bind(&MockMailboxCallback::Release,
128 base::Unretained(&mock_callback_),
129 mailbox_name2_);
skyostil3976a3f2014-09-04 22:07:23130 release_mailbox1_impl_ = base::Bind(&MockMailboxCallback::ReleaseImpl,
131 base::Unretained(&mock_callback_),
132 mailbox_name1_);
133 release_mailbox2_impl_ = base::Bind(&MockMailboxCallback::ReleaseImpl,
134 base::Unretained(&mock_callback_),
135 mailbox_name2_);
[email protected]d72d9e02014-04-03 18:40:09136 const uint32 arbitrary_target1 = GL_TEXTURE_2D;
137 const uint32 arbitrary_target2 = GL_TEXTURE_EXTERNAL_OES;
138 mailbox1_ = TextureMailbox(mailbox_name1_, arbitrary_target1, sync_point1_);
139 mailbox2_ = TextureMailbox(mailbox_name2_, arbitrary_target2, sync_point2_);
140 gfx::Size size(128, 128);
141 EXPECT_TRUE(shared_memory_->CreateAndMapAnonymous(4 * size.GetArea()));
142 release_mailbox3_ = base::Bind(&MockMailboxCallback::Release2,
143 base::Unretained(&mock_callback_),
144 shared_memory_.get());
skyostil3976a3f2014-09-04 22:07:23145 release_mailbox3_impl_ = base::Bind(&MockMailboxCallback::ReleaseImpl2,
146 base::Unretained(&mock_callback_),
147 shared_memory_.get());
[email protected]d72d9e02014-04-03 18:40:09148 mailbox3_ = TextureMailbox(shared_memory_.get(), size);
149 }
150
151 gpu::Mailbox mailbox_name1_;
152 gpu::Mailbox mailbox_name2_;
153 MockMailboxCallback mock_callback_;
154 ReleaseCallback release_mailbox1_;
155 ReleaseCallback release_mailbox2_;
156 ReleaseCallback release_mailbox3_;
skyostil3976a3f2014-09-04 22:07:23157 ReleaseCallbackImpl release_mailbox1_impl_;
158 ReleaseCallbackImpl release_mailbox2_impl_;
159 ReleaseCallbackImpl release_mailbox3_impl_;
[email protected]d72d9e02014-04-03 18:40:09160 TextureMailbox mailbox1_;
161 TextureMailbox mailbox2_;
162 TextureMailbox mailbox3_;
163 uint32 sync_point1_;
164 uint32 sync_point2_;
165 scoped_ptr<base::SharedMemory> shared_memory_;
166};
167
[email protected]31d4df82013-07-18 10:17:22168class TextureLayerTest : public testing::Test {
169 public:
170 TextureLayerTest()
171 : fake_client_(
[email protected]4e2eb352014-03-20 17:25:45172 FakeLayerTreeHostClient(FakeLayerTreeHostClient::DIRECT_3D)),
173 host_impl_(&proxy_, &shared_bitmap_manager_) {}
[email protected]31d4df82013-07-18 10:17:22174
175 protected:
176 virtual void SetUp() {
177 layer_tree_host_.reset(new MockLayerTreeHost(&fake_client_));
[email protected]d72d9e02014-04-03 18:40:09178 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
179 layer_tree_host_->SetViewportSize(gfx::Size(10, 10));
180 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
[email protected]31d4df82013-07-18 10:17:22181 }
182
183 virtual void TearDown() {
184 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
[email protected]31d4df82013-07-18 10:17:22185 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
186
187 layer_tree_host_->SetRootLayer(NULL);
danakjf446a072014-09-27 21:55:48188 layer_tree_host_ = nullptr;
[email protected]31d4df82013-07-18 10:17:22189 }
190
191 scoped_ptr<MockLayerTreeHost> layer_tree_host_;
192 FakeImplProxy proxy_;
193 FakeLayerTreeHostClient fake_client_;
[email protected]4e2eb352014-03-20 17:25:45194 TestSharedBitmapManager shared_bitmap_manager_;
[email protected]31d4df82013-07-18 10:17:22195 FakeLayerTreeHostImpl host_impl_;
196};
197
[email protected]31d4df82013-07-18 10:17:22198TEST_F(TextureLayerTest, CheckPropertyChangeCausesCorrectBehavior) {
[email protected]17e08432014-04-10 00:41:11199 scoped_refptr<TextureLayer> test_layer = TextureLayer::CreateForMailbox(NULL);
[email protected]80d42bd2013-08-30 19:13:45200 EXPECT_SET_NEEDS_COMMIT(1, layer_tree_host_->SetRootLayer(test_layer));
[email protected]31d4df82013-07-18 10:17:22201
202 // Test properties that should call SetNeedsCommit. All properties need to
203 // be set to new values in order for SetNeedsCommit to be called.
204 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetFlipped(false));
205 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetUV(
206 gfx::PointF(0.25f, 0.25f), gfx::PointF(0.75f, 0.75f)));
207 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetVertexOpacity(
208 0.5f, 0.5f, 0.5f, 0.5f));
209 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetPremultipliedAlpha(false));
210 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetBlendBackgroundColor(true));
[email protected]31d4df82013-07-18 10:17:22211}
212
[email protected]1c10e232013-07-31 12:35:43213TEST_F(TextureLayerTest, VisibleContentOpaqueRegion) {
214 const gfx::Size layer_bounds(100, 100);
215 const gfx::Rect layer_rect(layer_bounds);
216 const Region layer_region(layer_rect);
217
[email protected]17e08432014-04-10 00:41:11218 scoped_refptr<TextureLayer> layer = TextureLayer::CreateForMailbox(NULL);
[email protected]1c10e232013-07-31 12:35:43219 layer->SetBounds(layer_bounds);
220 layer->draw_properties().visible_content_rect = layer_rect;
221 layer->SetBlendBackgroundColor(true);
222
223 // Verify initial conditions.
224 EXPECT_FALSE(layer->contents_opaque());
225 EXPECT_EQ(0u, layer->background_color());
226 EXPECT_EQ(Region().ToString(),
227 layer->VisibleContentOpaqueRegion().ToString());
228
229 // Opaque background.
230 layer->SetBackgroundColor(SK_ColorWHITE);
231 EXPECT_EQ(layer_region.ToString(),
232 layer->VisibleContentOpaqueRegion().ToString());
233
234 // Transparent background.
235 layer->SetBackgroundColor(SkColorSetARGB(100, 255, 255, 255));
236 EXPECT_EQ(Region().ToString(),
237 layer->VisibleContentOpaqueRegion().ToString());
238}
239
[email protected]31d4df82013-07-18 10:17:22240TEST_F(TextureLayerTest, RateLimiter) {
241 FakeTextureLayerClient client;
242 scoped_refptr<TextureLayer> test_layer = TextureLayer::CreateForMailbox(
243 &client);
244 test_layer->SetIsDrawable(true);
245 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
246 layer_tree_host_->SetRootLayer(test_layer);
247
248 // Don't rate limit until we invalidate.
[email protected]aeeb3372013-11-05 14:05:54249 EXPECT_CALL(*layer_tree_host_, StartRateLimiter()).Times(0);
[email protected]31d4df82013-07-18 10:17:22250 test_layer->SetRateLimitContext(true);
251 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
252
253 // Do rate limit after we invalidate.
[email protected]aeeb3372013-11-05 14:05:54254 EXPECT_CALL(*layer_tree_host_, StartRateLimiter());
[email protected]31d4df82013-07-18 10:17:22255 test_layer->SetNeedsDisplay();
256 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
257
258 // Stop rate limiter when we don't want it any more.
[email protected]aeeb3372013-11-05 14:05:54259 EXPECT_CALL(*layer_tree_host_, StopRateLimiter());
[email protected]31d4df82013-07-18 10:17:22260 test_layer->SetRateLimitContext(false);
261 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
262
263 // Or we clear the client.
264 test_layer->SetRateLimitContext(true);
[email protected]aeeb3372013-11-05 14:05:54265 EXPECT_CALL(*layer_tree_host_, StopRateLimiter());
[email protected]31d4df82013-07-18 10:17:22266 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
267 test_layer->ClearClient();
268 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
269
270 // Reset to a layer with a client, that started the rate limiter.
271 test_layer = TextureLayer::CreateForMailbox(
272 &client);
273 test_layer->SetIsDrawable(true);
274 test_layer->SetRateLimitContext(true);
275 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
276 layer_tree_host_->SetRootLayer(test_layer);
[email protected]aeeb3372013-11-05 14:05:54277 EXPECT_CALL(*layer_tree_host_, StartRateLimiter()).Times(0);
[email protected]31d4df82013-07-18 10:17:22278 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
[email protected]aeeb3372013-11-05 14:05:54279 EXPECT_CALL(*layer_tree_host_, StartRateLimiter());
[email protected]31d4df82013-07-18 10:17:22280 test_layer->SetNeedsDisplay();
281 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
282
283 // Stop rate limiter when we're removed from the tree.
[email protected]aeeb3372013-11-05 14:05:54284 EXPECT_CALL(*layer_tree_host_, StopRateLimiter());
[email protected]d72d9e02014-04-03 18:40:09285 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1);
[email protected]31d4df82013-07-18 10:17:22286 layer_tree_host_->SetRootLayer(NULL);
287 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
288}
289
[email protected]df41e252014-02-03 23:39:50290class TestMailboxHolder : public TextureLayer::TextureMailboxHolder {
[email protected]9794fb32013-08-29 09:49:59291 public:
[email protected]df41e252014-02-03 23:39:50292 using TextureLayer::TextureMailboxHolder::Create;
[email protected]9794fb32013-08-29 09:49:59293
294 protected:
295 virtual ~TestMailboxHolder() {}
296};
297
[email protected]de44a152013-01-08 15:28:46298class TextureLayerWithMailboxTest : public TextureLayerTest {
[email protected]28571b042013-03-14 07:59:15299 protected:
300 virtual void TearDown() {
301 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
302 EXPECT_CALL(test_data_.mock_callback_,
303 Release(test_data_.mailbox_name1_,
[email protected]7ba3ca72013-04-11 06:37:25304 test_data_.sync_point1_,
305 false)).Times(1);
[email protected]28571b042013-03-14 07:59:15306 TextureLayerTest::TearDown();
307 }
[email protected]de44a152013-01-08 15:28:46308
[email protected]28571b042013-03-14 07:59:15309 CommonMailboxObjects test_data_;
[email protected]de44a152013-01-08 15:28:46310};
311
[email protected]28571b042013-03-14 07:59:15312TEST_F(TextureLayerWithMailboxTest, ReplaceMailboxOnMainThreadBeforeCommit) {
[email protected]e8e4ae232013-04-12 00:26:01313 scoped_refptr<TextureLayer> test_layer = TextureLayer::CreateForMailbox(NULL);
[email protected]22898ed2013-06-01 04:52:30314 ASSERT_TRUE(test_layer.get());
[email protected]de44a152013-01-08 15:28:46315
[email protected]28571b042013-03-14 07:59:15316 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
317 layer_tree_host_->SetRootLayer(test_layer);
318 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
[email protected]de44a152013-01-08 15:28:46319
[email protected]28571b042013-03-14 07:59:15320 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
[email protected]9260757f2013-09-17 01:24:16321 test_layer->SetTextureMailbox(
322 test_data_.mailbox1_,
323 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
[email protected]28571b042013-03-14 07:59:15324 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
[email protected]de44a152013-01-08 15:28:46325
[email protected]28571b042013-03-14 07:59:15326 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
327 EXPECT_CALL(test_data_.mock_callback_,
[email protected]7ba3ca72013-04-11 06:37:25328 Release(test_data_.mailbox_name1_,
329 test_data_.sync_point1_,
330 false))
[email protected]28571b042013-03-14 07:59:15331 .Times(1);
[email protected]9260757f2013-09-17 01:24:16332 test_layer->SetTextureMailbox(
333 test_data_.mailbox2_,
334 SingleReleaseCallback::Create(test_data_.release_mailbox2_));
[email protected]28571b042013-03-14 07:59:15335 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
336 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]de44a152013-01-08 15:28:46337
[email protected]28571b042013-03-14 07:59:15338 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
339 EXPECT_CALL(test_data_.mock_callback_,
[email protected]7ba3ca72013-04-11 06:37:25340 Release(test_data_.mailbox_name2_,
341 test_data_.sync_point2_,
342 false))
[email protected]28571b042013-03-14 07:59:15343 .Times(1);
[email protected]9260757f2013-09-17 01:24:16344 test_layer->SetTextureMailbox(TextureMailbox(),
345 scoped_ptr<SingleReleaseCallback>());
[email protected]28571b042013-03-14 07:59:15346 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
347 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]de44a152013-01-08 15:28:46348
[email protected]80d42bd2013-08-30 19:13:45349 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
[email protected]9260757f2013-09-17 01:24:16350 test_layer->SetTextureMailbox(
351 test_data_.mailbox3_,
352 SingleReleaseCallback::Create(test_data_.release_mailbox3_));
[email protected]42f40a52013-06-08 04:38:51353 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
354 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
355
[email protected]42f40a52013-06-08 04:38:51356 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
357 EXPECT_CALL(test_data_.mock_callback_,
358 Release2(test_data_.shared_memory_.get(),
359 0, false))
360 .Times(1);
[email protected]9260757f2013-09-17 01:24:16361 test_layer->SetTextureMailbox(TextureMailbox(),
362 scoped_ptr<SingleReleaseCallback>());
[email protected]42f40a52013-06-08 04:38:51363 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
364 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
365
[email protected]28571b042013-03-14 07:59:15366 // Test destructor.
367 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
[email protected]9260757f2013-09-17 01:24:16368 test_layer->SetTextureMailbox(
369 test_data_.mailbox1_,
370 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
[email protected]de44a152013-01-08 15:28:46371}
372
[email protected]f9e8f452014-03-07 22:09:40373TEST_F(TextureLayerTest, SetTextureMailboxWithoutReleaseCallback) {
374 scoped_refptr<TextureLayer> test_layer = TextureLayer::CreateForMailbox(NULL);
375 ASSERT_TRUE(test_layer.get());
376
377 // These use the same gpu::Mailbox, but different sync points.
378 TextureMailbox mailbox1(MailboxFromChar('a'), GL_TEXTURE_2D, 1);
379 TextureMailbox mailbox2(MailboxFromChar('a'), GL_TEXTURE_2D, 2);
380
[email protected]f9e8f452014-03-07 22:09:40381 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
382 layer_tree_host_->SetRootLayer(test_layer);
383 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
384
385 // Set the mailbox the first time. It should cause a commit.
[email protected]f9e8f452014-03-07 22:09:40386 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
387 test_layer->SetTextureMailboxWithoutReleaseCallback(mailbox1);
388 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
389
390 // Set the mailbox again with a new sync point, as the backing texture has
391 // been updated. It should cause a new commit.
[email protected]f9e8f452014-03-07 22:09:40392 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
393 test_layer->SetTextureMailboxWithoutReleaseCallback(mailbox2);
394 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
395}
396
[email protected]9794fb32013-08-29 09:49:59397class TextureLayerMailboxHolderTest : public TextureLayerTest {
398 public:
399 TextureLayerMailboxHolderTest()
400 : main_thread_("MAIN") {
401 main_thread_.Start();
skyostil3976a3f2014-09-04 22:07:23402 main_thread_.message_loop()->PostTask(
403 FROM_HERE,
404 base::Bind(&TextureLayerMailboxHolderTest::InitializeOnMain,
405 base::Unretained(this)));
406 Wait(main_thread_);
[email protected]9794fb32013-08-29 09:49:59407 }
408
409 void Wait(const base::Thread& thread) {
410 bool manual_reset = false;
411 bool initially_signaled = false;
412 base::WaitableEvent event(manual_reset, initially_signaled);
413 thread.message_loop()->PostTask(
414 FROM_HERE,
415 base::Bind(&base::WaitableEvent::Signal, base::Unretained(&event)));
416 event.Wait();
417 }
418
419 void CreateMainRef() {
420 main_ref_ = TestMailboxHolder::Create(
[email protected]9260757f2013-09-17 01:24:16421 test_data_.mailbox1_,
422 SingleReleaseCallback::Create(test_data_.release_mailbox1_)).Pass();
[email protected]9794fb32013-08-29 09:49:59423 }
424
danakjf446a072014-09-27 21:55:48425 void ReleaseMainRef() { main_ref_ = nullptr; }
[email protected]9794fb32013-08-29 09:49:59426
skyostil3976a3f2014-09-04 22:07:23427 void CreateImplRef(scoped_ptr<SingleReleaseCallbackImpl>* impl_ref) {
[email protected]9794fb32013-08-29 09:49:59428 *impl_ref = main_ref_->holder()->GetCallbackForImplThread();
429 }
430
431 void CapturePostTasksAndWait(base::WaitableEvent* begin_capture,
432 base::WaitableEvent* wait_for_capture,
433 base::WaitableEvent* stop_capture) {
434 begin_capture->Wait();
skyostil3976a3f2014-09-04 22:07:23435 BlockingTaskRunner::CapturePostTasks capture(
436 main_thread_task_runner_.get());
[email protected]9794fb32013-08-29 09:49:59437 wait_for_capture->Signal();
438 stop_capture->Wait();
439 }
440
441 protected:
skyostil3976a3f2014-09-04 22:07:23442 void InitializeOnMain() {
443 main_thread_task_runner_ =
444 BlockingTaskRunner::Create(main_thread_.message_loop_proxy());
445 }
446
[email protected]9794fb32013-08-29 09:49:59447 scoped_ptr<TestMailboxHolder::MainThreadReference>
448 main_ref_;
449 base::Thread main_thread_;
skyostil3976a3f2014-09-04 22:07:23450 scoped_ptr<BlockingTaskRunner> main_thread_task_runner_;
[email protected]9794fb32013-08-29 09:49:59451 CommonMailboxObjects test_data_;
452};
453
454TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_BothReleaseThenMain) {
455 scoped_refptr<TextureLayer> test_layer = TextureLayer::CreateForMailbox(NULL);
456 ASSERT_TRUE(test_layer.get());
457
458 main_thread_.message_loop()->PostTask(
459 FROM_HERE,
460 base::Bind(&TextureLayerMailboxHolderTest::CreateMainRef,
461 base::Unretained(this)));
462
463 Wait(main_thread_);
464
465 // The texture layer is attached to compositor1, and passes a reference to its
466 // impl tree.
skyostil3976a3f2014-09-04 22:07:23467 scoped_ptr<SingleReleaseCallbackImpl> compositor1;
[email protected]9794fb32013-08-29 09:49:59468 main_thread_.message_loop()->PostTask(
469 FROM_HERE,
470 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
471 base::Unretained(this),
472 &compositor1));
473
474 // Then the texture layer is removed and attached to compositor2, and passes a
475 // reference to its impl tree.
skyostil3976a3f2014-09-04 22:07:23476 scoped_ptr<SingleReleaseCallbackImpl> compositor2;
[email protected]9794fb32013-08-29 09:49:59477 main_thread_.message_loop()->PostTask(
478 FROM_HERE,
479 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
480 base::Unretained(this),
481 &compositor2));
482
483 Wait(main_thread_);
484 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
485
486 // The compositors both destroy their impl trees before the main thread layer
487 // is destroyed.
skyostil3976a3f2014-09-04 22:07:23488 compositor1->Run(100, false, main_thread_task_runner_.get());
489 compositor2->Run(200, false, main_thread_task_runner_.get());
[email protected]9794fb32013-08-29 09:49:59490
491 Wait(main_thread_);
492
493 EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0);
494 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
495
496 // The main thread ref is the last one, so the mailbox is released back to the
497 // embedder, with the last sync point provided by the impl trees.
498 EXPECT_CALL(test_data_.mock_callback_,
499 Release(test_data_.mailbox_name1_, 200, false)).Times(1);
500
501 main_thread_.message_loop()->PostTask(
502 FROM_HERE,
503 base::Bind(&TextureLayerMailboxHolderTest::ReleaseMainRef,
504 base::Unretained(this)));
505 Wait(main_thread_);
506 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
507}
508
509TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_MainReleaseBetween) {
510 scoped_refptr<TextureLayer> test_layer = TextureLayer::CreateForMailbox(NULL);
511 ASSERT_TRUE(test_layer.get());
512
513 main_thread_.message_loop()->PostTask(
514 FROM_HERE,
515 base::Bind(&TextureLayerMailboxHolderTest::CreateMainRef,
516 base::Unretained(this)));
517
518 Wait(main_thread_);
519
520 // The texture layer is attached to compositor1, and passes a reference to its
521 // impl tree.
skyostil3976a3f2014-09-04 22:07:23522 scoped_ptr<SingleReleaseCallbackImpl> compositor1;
[email protected]9794fb32013-08-29 09:49:59523 main_thread_.message_loop()->PostTask(
524 FROM_HERE,
525 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
526 base::Unretained(this),
527 &compositor1));
528
529 // Then the texture layer is removed and attached to compositor2, and passes a
530 // reference to its impl tree.
skyostil3976a3f2014-09-04 22:07:23531 scoped_ptr<SingleReleaseCallbackImpl> compositor2;
[email protected]9794fb32013-08-29 09:49:59532 main_thread_.message_loop()->PostTask(
533 FROM_HERE,
534 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
535 base::Unretained(this),
536 &compositor2));
537
538 Wait(main_thread_);
539 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
540
541 // One compositor destroys their impl tree.
skyostil3976a3f2014-09-04 22:07:23542 compositor1->Run(100, false, main_thread_task_runner_.get());
[email protected]9794fb32013-08-29 09:49:59543
544 // Then the main thread reference is destroyed.
545 main_thread_.message_loop()->PostTask(
546 FROM_HERE,
547 base::Bind(&TextureLayerMailboxHolderTest::ReleaseMainRef,
548 base::Unretained(this)));
549
550 Wait(main_thread_);
551
552 EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0);
553 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
554
555 // The second impl reference is destroyed last, causing the mailbox to be
556 // released back to the embedder with the last sync point from the impl tree.
557 EXPECT_CALL(test_data_.mock_callback_,
558 Release(test_data_.mailbox_name1_, 200, true)).Times(1);
559
skyostil3976a3f2014-09-04 22:07:23560 compositor2->Run(200, true, main_thread_task_runner_.get());
[email protected]9794fb32013-08-29 09:49:59561 Wait(main_thread_);
562 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
563}
564
565TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_MainReleasedFirst) {
566 scoped_refptr<TextureLayer> test_layer = TextureLayer::CreateForMailbox(NULL);
567 ASSERT_TRUE(test_layer.get());
568
569 main_thread_.message_loop()->PostTask(
570 FROM_HERE,
571 base::Bind(&TextureLayerMailboxHolderTest::CreateMainRef,
572 base::Unretained(this)));
573
574 Wait(main_thread_);
575
576 // The texture layer is attached to compositor1, and passes a reference to its
577 // impl tree.
skyostil3976a3f2014-09-04 22:07:23578 scoped_ptr<SingleReleaseCallbackImpl> compositor1;
[email protected]9794fb32013-08-29 09:49:59579 main_thread_.message_loop()->PostTask(
580 FROM_HERE,
581 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
582 base::Unretained(this),
583 &compositor1));
584
585 // Then the texture layer is removed and attached to compositor2, and passes a
586 // reference to its impl tree.
skyostil3976a3f2014-09-04 22:07:23587 scoped_ptr<SingleReleaseCallbackImpl> compositor2;
[email protected]9794fb32013-08-29 09:49:59588 main_thread_.message_loop()->PostTask(
589 FROM_HERE,
590 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
591 base::Unretained(this),
592 &compositor2));
593
594 Wait(main_thread_);
595 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
596
597 // The main thread reference is destroyed first.
598 main_thread_.message_loop()->PostTask(
599 FROM_HERE,
600 base::Bind(&TextureLayerMailboxHolderTest::ReleaseMainRef,
601 base::Unretained(this)));
602
603 // One compositor destroys their impl tree.
skyostil3976a3f2014-09-04 22:07:23604 compositor2->Run(200, false, main_thread_task_runner_.get());
[email protected]9794fb32013-08-29 09:49:59605
606 Wait(main_thread_);
607
608 EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0);
609 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
610
611 // The second impl reference is destroyed last, causing the mailbox to be
612 // released back to the embedder with the last sync point from the impl tree.
613 EXPECT_CALL(test_data_.mock_callback_,
614 Release(test_data_.mailbox_name1_, 100, true)).Times(1);
615
skyostil3976a3f2014-09-04 22:07:23616 compositor1->Run(100, true, main_thread_task_runner_.get());
[email protected]9794fb32013-08-29 09:49:59617 Wait(main_thread_);
618 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
619}
620
621TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_SecondImplRefShortcut) {
622 scoped_refptr<TextureLayer> test_layer = TextureLayer::CreateForMailbox(NULL);
623 ASSERT_TRUE(test_layer.get());
624
625 main_thread_.message_loop()->PostTask(
626 FROM_HERE,
627 base::Bind(&TextureLayerMailboxHolderTest::CreateMainRef,
628 base::Unretained(this)));
629
630 Wait(main_thread_);
631
632 // The texture layer is attached to compositor1, and passes a reference to its
633 // impl tree.
skyostil3976a3f2014-09-04 22:07:23634 scoped_ptr<SingleReleaseCallbackImpl> compositor1;
[email protected]9794fb32013-08-29 09:49:59635 main_thread_.message_loop()->PostTask(
636 FROM_HERE,
637 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
638 base::Unretained(this),
639 &compositor1));
640
641 // Then the texture layer is removed and attached to compositor2, and passes a
642 // reference to its impl tree.
skyostil3976a3f2014-09-04 22:07:23643 scoped_ptr<SingleReleaseCallbackImpl> compositor2;
[email protected]9794fb32013-08-29 09:49:59644 main_thread_.message_loop()->PostTask(
645 FROM_HERE,
646 base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
647 base::Unretained(this),
648 &compositor2));
649
650 Wait(main_thread_);
651 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
652
653 // The main thread reference is destroyed first.
654 main_thread_.message_loop()->PostTask(
655 FROM_HERE,
656 base::Bind(&TextureLayerMailboxHolderTest::ReleaseMainRef,
657 base::Unretained(this)));
658
659 EXPECT_CALL(test_data_.mock_callback_,
660 Release(test_data_.mailbox_name1_, 200, true)).Times(1);
661
662 bool manual_reset = false;
663 bool initially_signaled = false;
664 base::WaitableEvent begin_capture(manual_reset, initially_signaled);
665 base::WaitableEvent wait_for_capture(manual_reset, initially_signaled);
666 base::WaitableEvent stop_capture(manual_reset, initially_signaled);
667
668 // Post a task to start capturing tasks on the main thread. This will block
669 // the main thread until we signal the |stop_capture| event.
670 main_thread_.message_loop()->PostTask(
671 FROM_HERE,
672 base::Bind(&TextureLayerMailboxHolderTest::CapturePostTasksAndWait,
673 base::Unretained(this),
674 &begin_capture,
675 &wait_for_capture,
676 &stop_capture));
677
678 // Before the main thread capturing starts, one compositor destroys their
679 // impl reference. Since capturing did not start, this gets post-tasked to
680 // the main thread.
skyostil3976a3f2014-09-04 22:07:23681 compositor1->Run(100, false, main_thread_task_runner_.get());
[email protected]9794fb32013-08-29 09:49:59682
683 // Start capturing on the main thread.
684 begin_capture.Signal();
685 wait_for_capture.Wait();
686
687 // Meanwhile, the second compositor released its impl reference, but this task
688 // gets shortcutted directly to the main thread. This means the reference is
689 // released before compositor1, whose reference will be released later when
690 // the post-task is serviced. But since it was destroyed _on the impl thread_
691 // last, its sync point values should be used.
skyostil3976a3f2014-09-04 22:07:23692 compositor2->Run(200, true, main_thread_task_runner_.get());
[email protected]9794fb32013-08-29 09:49:59693
694 stop_capture.Signal();
695 Wait(main_thread_);
696
697 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
698}
699
[email protected]e216fef02013-03-20 22:56:10700class TextureLayerImplWithMailboxThreadedCallback : public LayerTreeTest {
[email protected]28571b042013-03-14 07:59:15701 public:
702 TextureLayerImplWithMailboxThreadedCallback()
703 : callback_count_(0),
704 commit_count_(0) {}
705
706 // Make sure callback is received on main and doesn't block the impl thread.
[email protected]df41e252014-02-03 23:39:50707 void ReleaseCallback(uint32 sync_point, bool lost_resource) {
[email protected]9794fb32013-08-29 09:49:59708 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]7ba3ca72013-04-11 06:37:25709 EXPECT_FALSE(lost_resource);
[email protected]28571b042013-03-14 07:59:15710 ++callback_count_;
711 }
712
713 void SetMailbox(char mailbox_char) {
[email protected]9794fb32013-08-29 09:49:59714 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]9260757f2013-09-17 01:24:16715 scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create(
[email protected]28571b042013-03-14 07:59:15716 base::Bind(
717 &TextureLayerImplWithMailboxThreadedCallback::ReleaseCallback,
718 base::Unretained(this)));
[email protected]df41e252014-02-03 23:39:50719 layer_->SetTextureMailbox(
[email protected]e0a4d732014-02-15 00:23:26720 TextureMailbox(MailboxFromChar(mailbox_char), GL_TEXTURE_2D, 0),
[email protected]df41e252014-02-03 23:39:50721 callback.Pass());
[email protected]28571b042013-03-14 07:59:15722 }
723
mostynbf68776d82014-10-06 18:07:37724 virtual void BeginTest() override {
[email protected]9794fb32013-08-29 09:49:59725 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
726
[email protected]28571b042013-03-14 07:59:15727 gfx::Size bounds(100, 100);
728 root_ = Layer::Create();
[email protected]28571b042013-03-14 07:59:15729 root_->SetBounds(bounds);
730
[email protected]e8e4ae232013-04-12 00:26:01731 layer_ = TextureLayer::CreateForMailbox(NULL);
[email protected]28571b042013-03-14 07:59:15732 layer_->SetIsDrawable(true);
[email protected]28571b042013-03-14 07:59:15733 layer_->SetBounds(bounds);
734
735 root_->AddChild(layer_);
[email protected]e216fef02013-03-20 22:56:10736 layer_tree_host()->SetRootLayer(root_);
[email protected]18ce59702013-04-09 04:58:40737 layer_tree_host()->SetViewportSize(bounds);
[email protected]28571b042013-03-14 07:59:15738 SetMailbox('1');
739 EXPECT_EQ(0, callback_count_);
740
741 // Case #1: change mailbox before the commit. The old mailbox should be
742 // released immediately.
743 SetMailbox('2');
744 EXPECT_EQ(1, callback_count_);
[email protected]e216fef02013-03-20 22:56:10745 PostSetNeedsCommitToMainThread();
[email protected]28571b042013-03-14 07:59:15746 }
747
mostynbf68776d82014-10-06 18:07:37748 virtual void DidCommit() override {
[email protected]28571b042013-03-14 07:59:15749 ++commit_count_;
750 switch (commit_count_) {
751 case 1:
752 // Case #2: change mailbox after the commit (and draw), where the
753 // layer draws. The old mailbox should be released during the next
754 // commit.
755 SetMailbox('3');
756 EXPECT_EQ(1, callback_count_);
757 break;
758 case 2:
[email protected]28571b042013-03-14 07:59:15759 EXPECT_EQ(2, callback_count_);
760 // Case #3: change mailbox when the layer doesn't draw. The old
761 // mailbox should be released during the next commit.
762 layer_->SetBounds(gfx::Size());
763 SetMailbox('4');
764 break;
[email protected]9794fb32013-08-29 09:49:59765 case 3:
[email protected]28571b042013-03-14 07:59:15766 EXPECT_EQ(3, callback_count_);
767 // Case #4: release mailbox that was committed but never drawn. The
768 // old mailbox should be released during the next commit.
[email protected]9260757f2013-09-17 01:24:16769 layer_->SetTextureMailbox(TextureMailbox(),
770 scoped_ptr<SingleReleaseCallback>());
[email protected]28571b042013-03-14 07:59:15771 break;
[email protected]9794fb32013-08-29 09:49:59772 case 4:
773 if (layer_tree_host()->settings().impl_side_painting) {
774 // With impl painting, the texture mailbox will still be on the impl
775 // thread when the commit finishes, because the layer is not drawble
776 // when it has no texture mailbox, and thus does not block the commit
777 // on activation. So, we wait for activation.
778 // TODO(danakj): fix this. crbug.com/277953
779 layer_tree_host()->SetNeedsCommit();
780 break;
781 } else {
782 ++commit_count_;
783 }
784 case 5:
[email protected]28571b042013-03-14 07:59:15785 EXPECT_EQ(4, callback_count_);
[email protected]7096acc2013-06-18 21:12:43786 // Restore a mailbox for the next step.
787 SetMailbox('5');
788 break;
[email protected]9794fb32013-08-29 09:49:59789 case 6:
[email protected]7096acc2013-06-18 21:12:43790 // Case #5: remove layer from tree. Callback should *not* be called, the
791 // mailbox is returned to the main thread.
792 EXPECT_EQ(4, callback_count_);
793 layer_->RemoveFromParent();
794 break;
[email protected]9794fb32013-08-29 09:49:59795 case 7:
796 if (layer_tree_host()->settings().impl_side_painting) {
797 // With impl painting, the texture mailbox will still be on the impl
798 // thread when the commit finishes, because the layer is not around to
799 // block the commit on activation anymore. So, we wait for activation.
800 // TODO(danakj): fix this. crbug.com/277953
801 layer_tree_host()->SetNeedsCommit();
802 break;
803 } else {
804 ++commit_count_;
805 }
806 case 8:
[email protected]7096acc2013-06-18 21:12:43807 EXPECT_EQ(4, callback_count_);
808 // Resetting the mailbox will call the callback now.
[email protected]9260757f2013-09-17 01:24:16809 layer_->SetTextureMailbox(TextureMailbox(),
810 scoped_ptr<SingleReleaseCallback>());
[email protected]7096acc2013-06-18 21:12:43811 EXPECT_EQ(5, callback_count_);
[email protected]e216fef02013-03-20 22:56:10812 EndTest();
[email protected]28571b042013-03-14 07:59:15813 break;
814 default:
815 NOTREACHED();
816 break;
[email protected]de44a152013-01-08 15:28:46817 }
[email protected]28571b042013-03-14 07:59:15818 }
[email protected]de44a152013-01-08 15:28:46819
mostynbf68776d82014-10-06 18:07:37820 virtual void AfterTest() override {}
[email protected]de44a152013-01-08 15:28:46821
[email protected]28571b042013-03-14 07:59:15822 private:
[email protected]9794fb32013-08-29 09:49:59823 base::ThreadChecker main_thread_;
[email protected]28571b042013-03-14 07:59:15824 int callback_count_;
825 int commit_count_;
826 scoped_refptr<Layer> root_;
827 scoped_refptr<TextureLayer> layer_;
[email protected]de44a152013-01-08 15:28:46828};
829
[email protected]4145d172013-05-10 16:54:36830SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
831 TextureLayerImplWithMailboxThreadedCallback);
[email protected]de44a152013-01-08 15:28:46832
[email protected]74b43cc2013-08-30 06:29:27833
[email protected]74b43cc2013-08-30 06:29:27834class TextureLayerMailboxIsActivatedDuringCommit : public LayerTreeTest {
835 protected:
[email protected]98ea818e2014-01-24 10:22:08836 TextureLayerMailboxIsActivatedDuringCommit() : activate_count_(0) {}
[email protected]74b43cc2013-08-30 06:29:27837
[email protected]df41e252014-02-03 23:39:50838 static void ReleaseCallback(uint32 sync_point, bool lost_resource) {}
[email protected]74b43cc2013-08-30 06:29:27839
840 void SetMailbox(char mailbox_char) {
[email protected]9260757f2013-09-17 01:24:16841 scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create(
[email protected]74b43cc2013-08-30 06:29:27842 base::Bind(
843 &TextureLayerMailboxIsActivatedDuringCommit::ReleaseCallback));
[email protected]df41e252014-02-03 23:39:50844 layer_->SetTextureMailbox(
[email protected]e0a4d732014-02-15 00:23:26845 TextureMailbox(MailboxFromChar(mailbox_char), GL_TEXTURE_2D, 0),
[email protected]df41e252014-02-03 23:39:50846 callback.Pass());
[email protected]74b43cc2013-08-30 06:29:27847 }
848
mostynbf68776d82014-10-06 18:07:37849 virtual void BeginTest() override {
[email protected]74b43cc2013-08-30 06:29:27850 gfx::Size bounds(100, 100);
851 root_ = Layer::Create();
[email protected]74b43cc2013-08-30 06:29:27852 root_->SetBounds(bounds);
853
854 layer_ = TextureLayer::CreateForMailbox(NULL);
855 layer_->SetIsDrawable(true);
[email protected]74b43cc2013-08-30 06:29:27856 layer_->SetBounds(bounds);
857
858 root_->AddChild(layer_);
859 layer_tree_host()->SetRootLayer(root_);
860 layer_tree_host()->SetViewportSize(bounds);
861 SetMailbox('1');
862
863 PostSetNeedsCommitToMainThread();
864 }
865
mostynbf68776d82014-10-06 18:07:37866 virtual void WillActivateTreeOnThread(LayerTreeHostImpl* impl) override {
[email protected]74b43cc2013-08-30 06:29:27867 ++activate_count_;
868 }
869
mostynbf68776d82014-10-06 18:07:37870 virtual void DidCommit() override {
[email protected]98ea818e2014-01-24 10:22:08871 switch (layer_tree_host()->source_frame_number()) {
[email protected]74b43cc2013-08-30 06:29:27872 case 1:
873 // The first mailbox has been activated. Set a new mailbox, and
874 // expect the next commit to finish *after* it is activated.
875 SetMailbox('2');
[email protected]74b43cc2013-08-30 06:29:27876 break;
877 case 2:
878 // The second mailbox has been activated. Remove the layer from
879 // the tree to cause another commit/activation. The commit should
880 // finish *after* the layer is removed from the active tree.
881 layer_->RemoveFromParent();
[email protected]74b43cc2013-08-30 06:29:27882 break;
883 case 3:
884 EndTest();
885 break;
886 }
887 }
888
mostynbf68776d82014-10-06 18:07:37889 virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
[email protected]98ea818e2014-01-24 10:22:08890 switch (host_impl->active_tree()->source_frame_number()) {
[email protected]b6061062014-06-27 19:20:08891 case 0: {
892 // The activate for the 1st mailbox should have happened before now.
893 EXPECT_EQ(1, activate_count_);
894 break;
895 }
896 case 1: {
[email protected]74b43cc2013-08-30 06:29:27897 // The activate for the 2nd mailbox should have happened before now.
[email protected]74b43cc2013-08-30 06:29:27898 EXPECT_EQ(2, activate_count_);
899 break;
900 }
[email protected]b6061062014-06-27 19:20:08901 case 2: {
[email protected]74b43cc2013-08-30 06:29:27902 // The activate to remove the layer should have happened before now.
[email protected]74b43cc2013-08-30 06:29:27903 EXPECT_EQ(3, activate_count_);
904 break;
905 }
[email protected]b6061062014-06-27 19:20:08906 case 3: {
907 NOTREACHED();
908 break;
909 }
[email protected]74b43cc2013-08-30 06:29:27910 }
911 }
912
913
mostynbf68776d82014-10-06 18:07:37914 virtual void AfterTest() override {}
[email protected]74b43cc2013-08-30 06:29:27915
[email protected]74b43cc2013-08-30 06:29:27916 int activate_count_;
917 scoped_refptr<Layer> root_;
918 scoped_refptr<TextureLayer> layer_;
919};
920
921SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
922 TextureLayerMailboxIsActivatedDuringCommit);
923
[email protected]de44a152013-01-08 15:28:46924class TextureLayerImplWithMailboxTest : public TextureLayerTest {
[email protected]28571b042013-03-14 07:59:15925 protected:
[email protected]408b5e22013-03-19 09:48:09926 TextureLayerImplWithMailboxTest()
927 : fake_client_(
928 FakeLayerTreeHostClient(FakeLayerTreeHostClient::DIRECT_3D)) {}
929
[email protected]28571b042013-03-14 07:59:15930 virtual void SetUp() {
931 TextureLayerTest::SetUp();
[email protected]408b5e22013-03-19 09:48:09932 layer_tree_host_.reset(new MockLayerTreeHost(&fake_client_));
danakjf446a072014-09-27 21:55:48933 EXPECT_TRUE(host_impl_.InitializeRenderer(FakeOutputSurface::Create3d()));
[email protected]28571b042013-03-14 07:59:15934 }
[email protected]de44a152013-01-08 15:28:46935
[email protected]0ec335c42013-07-04 06:17:08936 bool WillDraw(TextureLayerImpl* layer, DrawMode mode) {
937 bool will_draw = layer->WillDraw(
938 mode, host_impl_.active_tree()->resource_provider());
939 if (will_draw)
940 layer->DidDraw(host_impl_.active_tree()->resource_provider());
941 return will_draw;
942 }
943
[email protected]28571b042013-03-14 07:59:15944 CommonMailboxObjects test_data_;
[email protected]408b5e22013-03-19 09:48:09945 FakeLayerTreeHostClient fake_client_;
[email protected]de44a152013-01-08 15:28:46946};
947
[email protected]ffbb2212013-06-02 23:47:59948// Test conditions for results of TextureLayerImpl::WillDraw under
949// different configurations of different mailbox, texture_id, and draw_mode.
950TEST_F(TextureLayerImplWithMailboxTest, TestWillDraw) {
skyostil3976a3f2014-09-04 22:07:23951 EXPECT_CALL(
952 test_data_.mock_callback_,
953 ReleaseImpl(test_data_.mailbox_name1_, test_data_.sync_point1_, false, _))
[email protected]0ec335c42013-07-04 06:17:08954 .Times(AnyNumber());
955 EXPECT_CALL(test_data_.mock_callback_,
skyostil3976a3f2014-09-04 22:07:23956 ReleaseImpl2(test_data_.shared_memory_.get(), 0, false, _))
[email protected]0ec335c42013-07-04 06:17:08957 .Times(AnyNumber());
[email protected]ffbb2212013-06-02 23:47:59958 // Hardware mode.
959 {
960 scoped_ptr<TextureLayerImpl> impl_layer =
[email protected]17e08432014-04-10 00:41:11961 TextureLayerImpl::Create(host_impl_.active_tree(), 1);
[email protected]9260757f2013-09-17 01:24:16962 impl_layer->SetTextureMailbox(
963 test_data_.mailbox1_,
skyostil3976a3f2014-09-04 22:07:23964 SingleReleaseCallbackImpl::Create(test_data_.release_mailbox1_impl_));
[email protected]0ec335c42013-07-04 06:17:08965 EXPECT_TRUE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE));
[email protected]ffbb2212013-06-02 23:47:59966 }
967
968 {
969 scoped_ptr<TextureLayerImpl> impl_layer =
[email protected]17e08432014-04-10 00:41:11970 TextureLayerImpl::Create(host_impl_.active_tree(), 1);
[email protected]9260757f2013-09-17 01:24:16971 impl_layer->SetTextureMailbox(TextureMailbox(),
skyostil3976a3f2014-09-04 22:07:23972 scoped_ptr<SingleReleaseCallbackImpl>());
[email protected]0ec335c42013-07-04 06:17:08973 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE));
974 }
975
976 {
977 // Software resource.
978 scoped_ptr<TextureLayerImpl> impl_layer =
[email protected]17e08432014-04-10 00:41:11979 TextureLayerImpl::Create(host_impl_.active_tree(), 1);
[email protected]9260757f2013-09-17 01:24:16980 impl_layer->SetTextureMailbox(
981 test_data_.mailbox3_,
skyostil3976a3f2014-09-04 22:07:23982 SingleReleaseCallbackImpl::Create(test_data_.release_mailbox3_impl_));
[email protected]3e44d7a2013-07-30 00:03:10983 EXPECT_TRUE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE));
[email protected]ffbb2212013-06-02 23:47:59984 }
985
[email protected]0ec335c42013-07-04 06:17:08986 // Software mode.
987 {
988 scoped_ptr<TextureLayerImpl> impl_layer =
[email protected]17e08432014-04-10 00:41:11989 TextureLayerImpl::Create(host_impl_.active_tree(), 1);
[email protected]9260757f2013-09-17 01:24:16990 impl_layer->SetTextureMailbox(
991 test_data_.mailbox1_,
skyostil3976a3f2014-09-04 22:07:23992 SingleReleaseCallbackImpl::Create(test_data_.release_mailbox1_impl_));
[email protected]0ec335c42013-07-04 06:17:08993 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE));
994 }
995
996 {
997 scoped_ptr<TextureLayerImpl> impl_layer =
[email protected]17e08432014-04-10 00:41:11998 TextureLayerImpl::Create(host_impl_.active_tree(), 1);
[email protected]9260757f2013-09-17 01:24:16999 impl_layer->SetTextureMailbox(TextureMailbox(),
skyostil3976a3f2014-09-04 22:07:231000 scoped_ptr<SingleReleaseCallbackImpl>());
[email protected]0ec335c42013-07-04 06:17:081001 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE));
1002 }
1003
1004 {
1005 // Software resource.
1006 scoped_ptr<TextureLayerImpl> impl_layer =
[email protected]17e08432014-04-10 00:41:111007 TextureLayerImpl::Create(host_impl_.active_tree(), 1);
[email protected]9260757f2013-09-17 01:24:161008 impl_layer->SetTextureMailbox(
1009 test_data_.mailbox3_,
skyostil3976a3f2014-09-04 22:07:231010 SingleReleaseCallbackImpl::Create(test_data_.release_mailbox3_impl_));
[email protected]0ec335c42013-07-04 06:17:081011 EXPECT_TRUE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE));
1012 }
1013
[email protected]ffbb2212013-06-02 23:47:591014 // Resourceless software mode.
1015 {
1016 scoped_ptr<TextureLayerImpl> impl_layer =
[email protected]17e08432014-04-10 00:41:111017 TextureLayerImpl::Create(host_impl_.active_tree(), 1);
[email protected]9260757f2013-09-17 01:24:161018 impl_layer->SetTextureMailbox(
1019 test_data_.mailbox1_,
skyostil3976a3f2014-09-04 22:07:231020 SingleReleaseCallbackImpl::Create(test_data_.release_mailbox1_impl_));
[email protected]0ec335c42013-07-04 06:17:081021 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_RESOURCELESS_SOFTWARE));
[email protected]ffbb2212013-06-02 23:47:591022 }
[email protected]ffbb2212013-06-02 23:47:591023}
1024
[email protected]28571b042013-03-14 07:59:151025TEST_F(TextureLayerImplWithMailboxTest, TestImplLayerCallbacks) {
1026 host_impl_.CreatePendingTree();
1027 scoped_ptr<TextureLayerImpl> pending_layer;
[email protected]17e08432014-04-10 00:41:111028 pending_layer = TextureLayerImpl::Create(host_impl_.pending_tree(), 1);
[email protected]28571b042013-03-14 07:59:151029 ASSERT_TRUE(pending_layer);
[email protected]de44a152013-01-08 15:28:461030
[email protected]ed511b8d2013-03-25 03:29:291031 scoped_ptr<LayerImpl> active_layer(
[email protected]28571b042013-03-14 07:59:151032 pending_layer->CreateLayerImpl(host_impl_.active_tree()));
[email protected]ed511b8d2013-03-25 03:29:291033 ASSERT_TRUE(active_layer);
[email protected]de44a152013-01-08 15:28:461034
[email protected]9260757f2013-09-17 01:24:161035 pending_layer->SetTextureMailbox(
1036 test_data_.mailbox1_,
skyostil3976a3f2014-09-04 22:07:231037 SingleReleaseCallbackImpl::Create(test_data_.release_mailbox1_impl_));
[email protected]421e84f2013-02-22 03:27:151038
[email protected]28571b042013-03-14 07:59:151039 // Test multiple commits without an activation.
skyostil3976a3f2014-09-04 22:07:231040 EXPECT_CALL(
1041 test_data_.mock_callback_,
1042 ReleaseImpl(test_data_.mailbox_name1_, test_data_.sync_point1_, false, _))
[email protected]28571b042013-03-14 07:59:151043 .Times(1);
[email protected]9260757f2013-09-17 01:24:161044 pending_layer->SetTextureMailbox(
1045 test_data_.mailbox2_,
skyostil3976a3f2014-09-04 22:07:231046 SingleReleaseCallbackImpl::Create(test_data_.release_mailbox2_impl_));
[email protected]28571b042013-03-14 07:59:151047 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]421e84f2013-02-22 03:27:151048
[email protected]28571b042013-03-14 07:59:151049 // Test callback after activation.
[email protected]ed511b8d2013-03-25 03:29:291050 pending_layer->PushPropertiesTo(active_layer.get());
1051 active_layer->DidBecomeActive();
[email protected]421e84f2013-02-22 03:27:151052
skyostil3976a3f2014-09-04 22:07:231053 EXPECT_CALL(test_data_.mock_callback_, ReleaseImpl(_, _, _, _)).Times(0);
[email protected]9260757f2013-09-17 01:24:161054 pending_layer->SetTextureMailbox(
1055 test_data_.mailbox1_,
skyostil3976a3f2014-09-04 22:07:231056 SingleReleaseCallbackImpl::Create(test_data_.release_mailbox1_impl_));
[email protected]28571b042013-03-14 07:59:151057 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]421e84f2013-02-22 03:27:151058
[email protected]7ba3ca72013-04-11 06:37:251059 EXPECT_CALL(test_data_.mock_callback_,
skyostil3976a3f2014-09-04 22:07:231060 ReleaseImpl(test_data_.mailbox_name2_, _, false, _)).Times(1);
[email protected]ed511b8d2013-03-25 03:29:291061 pending_layer->PushPropertiesTo(active_layer.get());
1062 active_layer->DidBecomeActive();
[email protected]28571b042013-03-14 07:59:151063 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]de44a152013-01-08 15:28:461064
[email protected]28571b042013-03-14 07:59:151065 // Test resetting the mailbox.
[email protected]7ba3ca72013-04-11 06:37:251066 EXPECT_CALL(test_data_.mock_callback_,
skyostil3976a3f2014-09-04 22:07:231067 ReleaseImpl(test_data_.mailbox_name1_, _, false, _)).Times(1);
[email protected]9260757f2013-09-17 01:24:161068 pending_layer->SetTextureMailbox(TextureMailbox(),
skyostil3976a3f2014-09-04 22:07:231069 scoped_ptr<SingleReleaseCallbackImpl>());
[email protected]ed511b8d2013-03-25 03:29:291070 pending_layer->PushPropertiesTo(active_layer.get());
1071 active_layer->DidBecomeActive();
[email protected]28571b042013-03-14 07:59:151072 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]de44a152013-01-08 15:28:461073
[email protected]28571b042013-03-14 07:59:151074 // Test destructor.
skyostil3976a3f2014-09-04 22:07:231075 EXPECT_CALL(
1076 test_data_.mock_callback_,
1077 ReleaseImpl(test_data_.mailbox_name1_, test_data_.sync_point1_, false, _))
[email protected]28571b042013-03-14 07:59:151078 .Times(1);
[email protected]9260757f2013-09-17 01:24:161079 pending_layer->SetTextureMailbox(
1080 test_data_.mailbox1_,
skyostil3976a3f2014-09-04 22:07:231081 SingleReleaseCallbackImpl::Create(test_data_.release_mailbox1_impl_));
[email protected]de44a152013-01-08 15:28:461082}
1083
[email protected]28571b042013-03-14 07:59:151084TEST_F(TextureLayerImplWithMailboxTest,
1085 TestDestructorCallbackOnCreatedResource) {
1086 scoped_ptr<TextureLayerImpl> impl_layer;
[email protected]17e08432014-04-10 00:41:111087 impl_layer = TextureLayerImpl::Create(host_impl_.active_tree(), 1);
[email protected]28571b042013-03-14 07:59:151088 ASSERT_TRUE(impl_layer);
[email protected]de44a152013-01-08 15:28:461089
[email protected]7ba3ca72013-04-11 06:37:251090 EXPECT_CALL(test_data_.mock_callback_,
skyostil3976a3f2014-09-04 22:07:231091 ReleaseImpl(test_data_.mailbox_name1_, _, false, _)).Times(1);
[email protected]9260757f2013-09-17 01:24:161092 impl_layer->SetTextureMailbox(
1093 test_data_.mailbox1_,
skyostil3976a3f2014-09-04 22:07:231094 SingleReleaseCallbackImpl::Create(test_data_.release_mailbox1_impl_));
[email protected]ffbb2212013-06-02 23:47:591095 impl_layer->DidBecomeActive();
1096 EXPECT_TRUE(impl_layer->WillDraw(
1097 DRAW_MODE_HARDWARE, host_impl_.active_tree()->resource_provider()));
[email protected]28571b042013-03-14 07:59:151098 impl_layer->DidDraw(host_impl_.active_tree()->resource_provider());
[email protected]9260757f2013-09-17 01:24:161099 impl_layer->SetTextureMailbox(TextureMailbox(),
skyostil3976a3f2014-09-04 22:07:231100 scoped_ptr<SingleReleaseCallbackImpl>());
[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.
[email protected]4bad8b62013-10-24 01:27:291133 virtual 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
mostynbf68776d82014-10-06 18:07:371157 virtual 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
mostynbf68776d82014-10-06 18:07:371171 virtual void BeginTest() override {
[email protected]4bad8b62013-10-24 01:27:291172 PostSetNeedsCommitToMainThread();
1173 }
1174
mostynbf68776d82014-10-06 18:07:371175 virtual void DidCommitAndDrawFrame() override {
[email protected]4bad8b62013-10-24 01:27:291176 switch (layer_tree_host()->source_frame_number()) {
1177 case 1:
[email protected]4ea293f72014-08-13 03:03:171178 EXPECT_FALSE(proxy()->MainFrameWillHappenForTesting());
[email protected]cce34bd2013-12-02 23:24:451179 // Invalidate the texture layer to clear the mailbox before
1180 // ending the test.
1181 texture_layer_->SetNeedsDisplay();
1182 break;
1183 case 2:
[email protected]4bad8b62013-10-24 01:27:291184 break;
1185 default:
1186 NOTREACHED();
1187 break;
1188 }
1189 }
1190
[email protected]cce34bd2013-12-02 23:24:451191 virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl,
mostynbf68776d82014-10-06 18:07:371192 bool result) override {
[email protected]cce34bd2013-12-02 23:24:451193 ASSERT_TRUE(result);
1194 DelegatedFrameData* delegated_frame_data =
1195 output_surface()->last_sent_frame().delegated_frame_data.get();
1196 if (!delegated_frame_data)
1197 return;
1198
1199 // Return all resources immediately.
1200 TransferableResourceArray resources_to_return =
1201 output_surface()->resources_held_by_parent();
1202
1203 CompositorFrameAck ack;
1204 for (size_t i = 0; i < resources_to_return.size(); ++i)
1205 output_surface()->ReturnResource(resources_to_return[i].id, &ack);
1206 host_impl->ReclaimResources(&ack);
[email protected]cce34bd2013-12-02 23:24:451207 }
1208
mostynbf68776d82014-10-06 18:07:371209 virtual void AfterTest() override {}
[email protected]4bad8b62013-10-24 01:27:291210
1211 private:
[email protected]4bad8b62013-10-24 01:27:291212 scoped_refptr<TextureLayer> texture_layer_;
[email protected]4bad8b62013-10-24 01:27:291213};
1214
[email protected]cce34bd2013-12-02 23:24:451215SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerNoExtraCommitForMailboxTest);
[email protected]4bad8b62013-10-24 01:27:291216
[email protected]b04264f92013-09-13 23:37:291217// Checks that changing a mailbox in the client for a TextureLayer that's
1218// invisible correctly works and uses the new mailbox as soon as the layer
1219// becomes visible (and returns the old one).
1220class TextureLayerChangeInvisibleMailboxTest
1221 : public LayerTreeTest,
1222 public TextureLayerClient {
1223 public:
1224 TextureLayerChangeInvisibleMailboxTest()
1225 : mailbox_changed_(true),
1226 mailbox_returned_(0),
1227 prepare_called_(0),
1228 commit_count_(0) {
1229 mailbox_ = MakeMailbox('1');
1230 }
1231
1232 // TextureLayerClient implementation.
[email protected]b04264f92013-09-13 23:37:291233 virtual bool PrepareTextureMailbox(
[email protected]e51444a2013-12-10 23:05:011234 TextureMailbox* mailbox,
[email protected]9260757f2013-09-17 01:24:161235 scoped_ptr<SingleReleaseCallback>* release_callback,
mostynbf68776d82014-10-06 18:07:371236 bool use_shared_memory) override {
[email protected]b04264f92013-09-13 23:37:291237 ++prepare_called_;
1238 if (!mailbox_changed_)
1239 return false;
1240 *mailbox = mailbox_;
[email protected]9260757f2013-09-17 01:24:161241 *release_callback = SingleReleaseCallback::Create(
1242 base::Bind(&TextureLayerChangeInvisibleMailboxTest::MailboxReleased,
1243 base::Unretained(this)));
[email protected]b04264f92013-09-13 23:37:291244 return true;
1245 }
1246
1247 TextureMailbox MakeMailbox(char name) {
[email protected]e0a4d732014-02-15 00:23:261248 return TextureMailbox(MailboxFromChar(name), GL_TEXTURE_2D, 0);
[email protected]b04264f92013-09-13 23:37:291249 }
1250
[email protected]df41e252014-02-03 23:39:501251 void MailboxReleased(uint32 sync_point, bool lost_resource) {
[email protected]b04264f92013-09-13 23:37:291252 ++mailbox_returned_;
1253 }
1254
mostynbf68776d82014-10-06 18:07:371255 virtual void SetupTree() override {
[email protected]b04264f92013-09-13 23:37:291256 scoped_refptr<Layer> root = Layer::Create();
1257 root->SetBounds(gfx::Size(10, 10));
[email protected]b04264f92013-09-13 23:37:291258 root->SetIsDrawable(true);
1259
1260 solid_layer_ = SolidColorLayer::Create();
1261 solid_layer_->SetBounds(gfx::Size(10, 10));
1262 solid_layer_->SetIsDrawable(true);
1263 solid_layer_->SetBackgroundColor(SK_ColorWHITE);
1264 root->AddChild(solid_layer_);
1265
1266 parent_layer_ = Layer::Create();
1267 parent_layer_->SetBounds(gfx::Size(10, 10));
1268 parent_layer_->SetIsDrawable(true);
1269 root->AddChild(parent_layer_);
1270
1271 texture_layer_ = TextureLayer::CreateForMailbox(this);
1272 texture_layer_->SetBounds(gfx::Size(10, 10));
[email protected]b04264f92013-09-13 23:37:291273 texture_layer_->SetIsDrawable(true);
1274 parent_layer_->AddChild(texture_layer_);
1275
1276 layer_tree_host()->SetRootLayer(root);
1277 LayerTreeTest::SetupTree();
1278 }
1279
mostynbf68776d82014-10-06 18:07:371280 virtual void BeginTest() override {
[email protected]b04264f92013-09-13 23:37:291281 PostSetNeedsCommitToMainThread();
1282 }
1283
mostynbf68776d82014-10-06 18:07:371284 virtual void DidCommitAndDrawFrame() override {
[email protected]b04264f92013-09-13 23:37:291285 ++commit_count_;
1286 switch (commit_count_) {
1287 case 1:
1288 // We should have updated the layer, committing the texture.
1289 EXPECT_EQ(1, prepare_called_);
1290 // Make layer invisible.
1291 parent_layer_->SetOpacity(0.f);
1292 break;
1293 case 2:
1294 // Layer shouldn't have been updated.
1295 EXPECT_EQ(1, prepare_called_);
1296 // Change the texture.
1297 mailbox_ = MakeMailbox('2');
1298 mailbox_changed_ = true;
1299 texture_layer_->SetNeedsDisplay();
1300 // Force a change to make sure we draw a frame.
1301 solid_layer_->SetBackgroundColor(SK_ColorGRAY);
1302 break;
1303 case 3:
1304 // Layer shouldn't have been updated.
1305 EXPECT_EQ(1, prepare_called_);
1306 // So the old mailbox isn't returned yet.
1307 EXPECT_EQ(0, mailbox_returned_);
1308 // Make layer visible again.
1309 parent_layer_->SetOpacity(1.f);
1310 break;
1311 case 4:
1312 // Layer should have been updated.
1313 EXPECT_EQ(2, prepare_called_);
1314 // So the old mailbox should have been returned already.
1315 EXPECT_EQ(1, mailbox_returned_);
1316 texture_layer_->ClearClient();
1317 break;
1318 case 5:
1319 EXPECT_EQ(2, mailbox_returned_);
1320 EndTest();
1321 break;
1322 default:
1323 NOTREACHED();
1324 break;
1325 }
1326 }
1327
1328 virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl,
mostynbf68776d82014-10-06 18:07:371329 bool result) override {
[email protected]b04264f92013-09-13 23:37:291330 ASSERT_TRUE(result);
1331 DelegatedFrameData* delegated_frame_data =
1332 output_surface()->last_sent_frame().delegated_frame_data.get();
1333 if (!delegated_frame_data)
1334 return;
1335
1336 // Return all resources immediately.
1337 TransferableResourceArray resources_to_return =
1338 output_surface()->resources_held_by_parent();
1339
1340 CompositorFrameAck ack;
1341 for (size_t i = 0; i < resources_to_return.size(); ++i)
1342 output_surface()->ReturnResource(resources_to_return[i].id, &ack);
[email protected]a7335e0b2013-09-18 09:34:511343 host_impl->ReclaimResources(&ack);
[email protected]b04264f92013-09-13 23:37:291344 }
1345
mostynbf68776d82014-10-06 18:07:371346 virtual void AfterTest() override {}
[email protected]b04264f92013-09-13 23:37:291347
1348 private:
1349 scoped_refptr<SolidColorLayer> solid_layer_;
1350 scoped_refptr<Layer> parent_layer_;
1351 scoped_refptr<TextureLayer> texture_layer_;
1352
1353 // Used on the main thread.
1354 bool mailbox_changed_;
1355 TextureMailbox mailbox_;
1356 int mailbox_returned_;
1357 int prepare_called_;
1358 int commit_count_;
1359};
1360
1361SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerChangeInvisibleMailboxTest);
1362
[email protected]0d7fb302014-01-23 21:30:471363// Test that TextureLayerImpl::ReleaseResources can be called which releases
1364// the mailbox back to TextureLayerClient.
1365class TextureLayerReleaseResourcesBase
1366 : public LayerTreeTest,
1367 public TextureLayerClient {
1368 public:
1369 // TextureLayerClient implementation.
[email protected]0d7fb302014-01-23 21:30:471370 virtual bool PrepareTextureMailbox(
1371 TextureMailbox* mailbox,
1372 scoped_ptr<SingleReleaseCallback>* release_callback,
mostynbf68776d82014-10-06 18:07:371373 bool use_shared_memory) override {
[email protected]e0a4d732014-02-15 00:23:261374 *mailbox = TextureMailbox(MailboxFromChar('1'), GL_TEXTURE_2D, 0);
[email protected]0d7fb302014-01-23 21:30:471375 *release_callback = SingleReleaseCallback::Create(
1376 base::Bind(&TextureLayerReleaseResourcesBase::MailboxReleased,
1377 base::Unretained(this)));
1378 return true;
1379 }
1380
1381 void MailboxReleased(unsigned sync_point, bool lost_resource) {
1382 mailbox_released_ = true;
1383 }
1384
mostynbf68776d82014-10-06 18:07:371385 virtual void SetupTree() override {
[email protected]0d7fb302014-01-23 21:30:471386 LayerTreeTest::SetupTree();
1387
1388 scoped_refptr<TextureLayer> texture_layer =
1389 TextureLayer::CreateForMailbox(this);
1390 texture_layer->SetBounds(gfx::Size(10, 10));
[email protected]0d7fb302014-01-23 21:30:471391 texture_layer->SetIsDrawable(true);
1392
1393 layer_tree_host()->root_layer()->AddChild(texture_layer);
1394 }
1395
mostynbf68776d82014-10-06 18:07:371396 virtual void BeginTest() override {
[email protected]0d7fb302014-01-23 21:30:471397 mailbox_released_ = false;
1398 PostSetNeedsCommitToMainThread();
1399 }
1400
mostynbf68776d82014-10-06 18:07:371401 virtual void DidCommitAndDrawFrame() override {
[email protected]0d7fb302014-01-23 21:30:471402 EndTest();
1403 }
1404
mostynbf68776d82014-10-06 18:07:371405 virtual void AfterTest() override {
[email protected]0d7fb302014-01-23 21:30:471406 EXPECT_TRUE(mailbox_released_);
1407 }
1408
1409 private:
1410 bool mailbox_released_;
1411};
1412
1413class TextureLayerReleaseResourcesAfterCommit
1414 : public TextureLayerReleaseResourcesBase {
1415 public:
mostynbf68776d82014-10-06 18:07:371416 virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
[email protected]0d7fb302014-01-23 21:30:471417 LayerTreeImpl* tree = NULL;
1418 if (host_impl->settings().impl_side_painting)
1419 tree = host_impl->pending_tree();
1420 else
1421 tree = host_impl->active_tree();
1422 tree->root_layer()->children()[0]->ReleaseResources();
1423 }
1424};
1425
1426SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerReleaseResourcesAfterCommit);
1427
1428class TextureLayerReleaseResourcesAfterActivate
1429 : public TextureLayerReleaseResourcesBase {
1430 public:
mostynbf68776d82014-10-06 18:07:371431 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
[email protected]0d7fb302014-01-23 21:30:471432 host_impl->active_tree()->root_layer()->children()[0]->ReleaseResources();
1433 }
1434};
1435
1436SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerReleaseResourcesAfterActivate);
1437
[email protected]9c2bd822013-07-26 12:30:171438class TextureLayerWithMailboxMainThreadDeleted : public LayerTreeTest {
1439 public:
[email protected]df41e252014-02-03 23:39:501440 void ReleaseCallback(uint32 sync_point, bool lost_resource) {
[email protected]9794fb32013-08-29 09:49:591441 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]9c2bd822013-07-26 12:30:171442 EXPECT_FALSE(lost_resource);
1443 ++callback_count_;
1444 EndTest();
1445 }
1446
1447 void SetMailbox(char mailbox_char) {
[email protected]9794fb32013-08-29 09:49:591448 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]9260757f2013-09-17 01:24:161449 scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create(
[email protected]9c2bd822013-07-26 12:30:171450 base::Bind(
1451 &TextureLayerWithMailboxMainThreadDeleted::ReleaseCallback,
1452 base::Unretained(this)));
[email protected]df41e252014-02-03 23:39:501453 layer_->SetTextureMailbox(
[email protected]e0a4d732014-02-15 00:23:261454 TextureMailbox(MailboxFromChar(mailbox_char), GL_TEXTURE_2D, 0),
[email protected]df41e252014-02-03 23:39:501455 callback.Pass());
[email protected]9c2bd822013-07-26 12:30:171456 }
1457
mostynbf68776d82014-10-06 18:07:371458 virtual void SetupTree() override {
[email protected]9c2bd822013-07-26 12:30:171459 gfx::Size bounds(100, 100);
1460 root_ = Layer::Create();
[email protected]9c2bd822013-07-26 12:30:171461 root_->SetBounds(bounds);
1462
1463 layer_ = TextureLayer::CreateForMailbox(NULL);
1464 layer_->SetIsDrawable(true);
[email protected]9c2bd822013-07-26 12:30:171465 layer_->SetBounds(bounds);
1466
1467 root_->AddChild(layer_);
1468 layer_tree_host()->SetRootLayer(root_);
1469 layer_tree_host()->SetViewportSize(bounds);
1470 }
1471
mostynbf68776d82014-10-06 18:07:371472 virtual void BeginTest() override {
[email protected]9794fb32013-08-29 09:49:591473 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
1474
[email protected]9c2bd822013-07-26 12:30:171475 callback_count_ = 0;
1476
1477 // Set the mailbox on the main thread.
1478 SetMailbox('1');
1479 EXPECT_EQ(0, callback_count_);
1480
1481 PostSetNeedsCommitToMainThread();
1482 }
1483
mostynbf68776d82014-10-06 18:07:371484 virtual void DidCommitAndDrawFrame() override {
[email protected]9c2bd822013-07-26 12:30:171485 switch (layer_tree_host()->source_frame_number()) {
1486 case 1:
1487 // Delete the TextureLayer on the main thread while the mailbox is in
1488 // the impl tree.
1489 layer_->RemoveFromParent();
1490 layer_ = NULL;
1491 break;
1492 }
1493 }
1494
mostynbf68776d82014-10-06 18:07:371495 virtual void AfterTest() override {
[email protected]9c2bd822013-07-26 12:30:171496 EXPECT_EQ(1, callback_count_);
1497 }
1498
1499 private:
[email protected]9794fb32013-08-29 09:49:591500 base::ThreadChecker main_thread_;
[email protected]9c2bd822013-07-26 12:30:171501 int callback_count_;
1502 scoped_refptr<Layer> root_;
1503 scoped_refptr<TextureLayer> layer_;
1504};
1505
1506SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
1507 TextureLayerWithMailboxMainThreadDeleted);
1508
1509class TextureLayerWithMailboxImplThreadDeleted : public LayerTreeTest {
1510 public:
[email protected]df41e252014-02-03 23:39:501511 void ReleaseCallback(uint32 sync_point, bool lost_resource) {
[email protected]9794fb32013-08-29 09:49:591512 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]9c2bd822013-07-26 12:30:171513 EXPECT_FALSE(lost_resource);
1514 ++callback_count_;
1515 EndTest();
1516 }
1517
1518 void SetMailbox(char mailbox_char) {
[email protected]9794fb32013-08-29 09:49:591519 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]9260757f2013-09-17 01:24:161520 scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create(
[email protected]9c2bd822013-07-26 12:30:171521 base::Bind(
1522 &TextureLayerWithMailboxImplThreadDeleted::ReleaseCallback,
1523 base::Unretained(this)));
[email protected]df41e252014-02-03 23:39:501524 layer_->SetTextureMailbox(
[email protected]e0a4d732014-02-15 00:23:261525 TextureMailbox(MailboxFromChar(mailbox_char), GL_TEXTURE_2D, 0),
[email protected]df41e252014-02-03 23:39:501526 callback.Pass());
[email protected]9c2bd822013-07-26 12:30:171527 }
1528
mostynbf68776d82014-10-06 18:07:371529 virtual void SetupTree() override {
[email protected]9c2bd822013-07-26 12:30:171530 gfx::Size bounds(100, 100);
1531 root_ = Layer::Create();
[email protected]9c2bd822013-07-26 12:30:171532 root_->SetBounds(bounds);
1533
1534 layer_ = TextureLayer::CreateForMailbox(NULL);
1535 layer_->SetIsDrawable(true);
[email protected]9c2bd822013-07-26 12:30:171536 layer_->SetBounds(bounds);
1537
1538 root_->AddChild(layer_);
1539 layer_tree_host()->SetRootLayer(root_);
1540 layer_tree_host()->SetViewportSize(bounds);
1541 }
1542
mostynbf68776d82014-10-06 18:07:371543 virtual void BeginTest() override {
[email protected]9794fb32013-08-29 09:49:591544 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
1545
[email protected]9c2bd822013-07-26 12:30:171546 callback_count_ = 0;
1547
1548 // Set the mailbox on the main thread.
1549 SetMailbox('1');
1550 EXPECT_EQ(0, callback_count_);
1551
1552 PostSetNeedsCommitToMainThread();
1553 }
1554
mostynbf68776d82014-10-06 18:07:371555 virtual void DidCommitAndDrawFrame() override {
[email protected]9c2bd822013-07-26 12:30:171556 switch (layer_tree_host()->source_frame_number()) {
1557 case 1:
1558 // Remove the TextureLayer on the main thread while the mailbox is in
1559 // the impl tree, but don't delete the TextureLayer until after the impl
1560 // tree side is deleted.
1561 layer_->RemoveFromParent();
1562 break;
1563 case 2:
1564 layer_ = NULL;
1565 break;
1566 }
1567 }
1568
mostynbf68776d82014-10-06 18:07:371569 virtual void AfterTest() override {
[email protected]9c2bd822013-07-26 12:30:171570 EXPECT_EQ(1, callback_count_);
1571 }
1572
1573 private:
[email protected]9794fb32013-08-29 09:49:591574 base::ThreadChecker main_thread_;
[email protected]9c2bd822013-07-26 12:30:171575 int callback_count_;
1576 scoped_refptr<Layer> root_;
1577 scoped_refptr<TextureLayer> layer_;
1578};
1579
1580SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
1581 TextureLayerWithMailboxImplThreadDeleted);
1582
[email protected]ba565742012-11-10 09:29:481583} // namespace
1584} // namespace cc