blob: 3bd90ec5782195eeb21c197ace139f70057bdb83 [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"
skyostil0fd1dad2015-04-13 20:11:4812#include "base/location.h"
13#include "base/single_thread_task_runner.h"
[email protected]9794fb32013-08-29 09:49:5914#include "base/synchronization/waitable_event.h"
skyostil0fd1dad2015-04-13 20:11:4815#include "base/thread_task_runner_handle.h"
[email protected]74b43cc2013-08-30 06:29:2716#include "base/threading/thread.h"
17#include "base/time/time.h"
[email protected]b04264f92013-09-13 23:37:2918#include "cc/layers/solid_color_layer.h"
[email protected]97d519fb2013-03-29 02:27:5419#include "cc/layers/texture_layer_client.h"
[email protected]cc3cfaa2013-03-18 09:05:5220#include "cc/layers/texture_layer_impl.h"
[email protected]b04264f92013-09-13 23:37:2921#include "cc/output/compositor_frame_ack.h"
22#include "cc/output/context_provider.h"
[email protected]e00bab022013-08-19 00:42:4523#include "cc/resources/returned_resource.h"
[email protected]586d51ed2012-12-07 20:31:4524#include "cc/test/fake_impl_proxy.h"
[email protected]101441ce2012-10-16 01:45:0325#include "cc/test/fake_layer_tree_host_client.h"
[email protected]586d51ed2012-12-07 20:31:4526#include "cc/test/fake_layer_tree_host_impl.h"
[email protected]199b715e2013-08-13 05:18:3427#include "cc/test/fake_output_surface.h"
[email protected]06d68d02013-04-19 18:46:2128#include "cc/test/layer_test_common.h"
[email protected]e216fef02013-03-20 22:56:1029#include "cc/test/layer_tree_test.h"
reveman34b7a1522015-03-23 20:27:4730#include "cc/test/test_task_graph_runner.h"
[email protected]c2610b9f2013-10-31 06:54:5931#include "cc/test/test_web_graphics_context_3d.h"
[email protected]9794fb32013-08-29 09:49:5932#include "cc/trees/blocking_task_runner.h"
[email protected]556fd292013-03-18 08:03:0433#include "cc/trees/layer_tree_host.h"
34#include "cc/trees/layer_tree_impl.h"
35#include "cc/trees/single_thread_proxy.h"
[email protected]0bf5a202013-07-10 14:50:5436#include "gpu/GLES2/gl2extchromium.h"
[email protected]7f0c53db2012-10-02 00:23:1837#include "testing/gmock/include/gmock/gmock.h"
38#include "testing/gtest/include/gtest/gtest.h"
[email protected]c0dd24c2012-08-30 23:25:2739
[email protected]c0dd24c2012-08-30 23:25:2740using ::testing::Mock;
41using ::testing::_;
42using ::testing::AtLeast;
43using ::testing::AnyNumber;
[email protected]d72d9e02014-04-03 18:40:0944using ::testing::InvokeWithoutArgs;
[email protected]c0dd24c2012-08-30 23:25:2745
[email protected]ba565742012-11-10 09:29:4846namespace cc {
[email protected]c0dd24c2012-08-30 23:25:2747namespace {
48
[email protected]e0a4d732014-02-15 00:23:2649gpu::Mailbox MailboxFromChar(char value) {
[email protected]df41e252014-02-03 23:39:5050 gpu::Mailbox mailbox;
[email protected]e0a4d732014-02-15 00:23:2651 memset(mailbox.name, value, sizeof(mailbox.name));
[email protected]df41e252014-02-03 23:39:5052 return mailbox;
53}
54
[email protected]408b5e22013-03-19 09:48:0955class MockLayerTreeHost : public LayerTreeHost {
[email protected]28571b042013-03-14 07:59:1556 public:
[email protected]943528e2013-11-07 05:01:3257 explicit MockLayerTreeHost(FakeLayerTreeHostClient* client)
reveman34b7a1522015-03-23 20:27:4758 : LayerTreeHost(client, nullptr, nullptr, nullptr, LayerTreeSettings()) {
skyostil0fd1dad2015-04-13 20:11:4859 InitializeSingleThreaded(client, base::ThreadTaskRunnerHandle::Get(),
simonhonga7e3ac42014-11-11 20:50:2260 nullptr);
[email protected]28571b042013-03-14 07:59:1561 }
[email protected]c0dd24c2012-08-30 23:25:2762
[email protected]28571b042013-03-14 07:59:1563 MOCK_METHOD0(SetNeedsCommit, void());
[email protected]3519b872013-07-30 07:17:5064 MOCK_METHOD0(SetNeedsUpdateLayers, void());
[email protected]aeeb3372013-11-05 14:05:5465 MOCK_METHOD0(StartRateLimiter, void());
66 MOCK_METHOD0(StopRateLimiter, void());
[email protected]c0dd24c2012-08-30 23:25:2767};
68
[email protected]d72d9e02014-04-03 18:40:0969class FakeTextureLayerClient : public TextureLayerClient {
70 public:
[email protected]17e08432014-04-10 00:41:1171 FakeTextureLayerClient() : mailbox_changed_(true) {}
[email protected]d72d9e02014-04-03 18:40:0972
dcheng716bedf2014-10-21 09:51:0873 bool PrepareTextureMailbox(
[email protected]d72d9e02014-04-03 18:40:0974 TextureMailbox* mailbox,
75 scoped_ptr<SingleReleaseCallback>* release_callback,
mostynbf68776d82014-10-06 18:07:3776 bool use_shared_memory) override {
[email protected]d72d9e02014-04-03 18:40:0977 if (!mailbox_changed_)
78 return false;
79
80 *mailbox = mailbox_;
81 *release_callback = release_callback_.Pass();
82 mailbox_changed_ = false;
83 return true;
84 }
85
[email protected]d72d9e02014-04-03 18:40:0986 void set_mailbox(const TextureMailbox& mailbox,
87 scoped_ptr<SingleReleaseCallback> release_callback) {
88 mailbox_ = mailbox;
89 release_callback_ = release_callback.Pass();
90 mailbox_changed_ = true;
91 }
92
93 private:
[email protected]d72d9e02014-04-03 18:40:0994 TextureMailbox mailbox_;
95 scoped_ptr<SingleReleaseCallback> release_callback_;
96 bool mailbox_changed_;
97 DISALLOW_COPY_AND_ASSIGN(FakeTextureLayerClient);
98};
99
100class MockMailboxCallback {
101 public:
102 MOCK_METHOD3(Release,
103 void(const gpu::Mailbox& mailbox,
104 uint32 sync_point,
105 bool lost_resource));
106 MOCK_METHOD3(Release2,
jbauman9015c8b2014-12-11 00:49:37107 void(SharedBitmap* shared_bitmap,
[email protected]d72d9e02014-04-03 18:40:09108 uint32 sync_point,
109 bool lost_resource));
skyostil3976a3f2014-09-04 22:07:23110 MOCK_METHOD4(ReleaseImpl,
111 void(const gpu::Mailbox& mailbox,
112 uint32 sync_point,
113 bool lost_resource,
114 BlockingTaskRunner* main_thread_task_runner));
115 MOCK_METHOD4(ReleaseImpl2,
jbauman9015c8b2014-12-11 00:49:37116 void(SharedBitmap* shared_bitmap,
skyostil3976a3f2014-09-04 22:07:23117 uint32 sync_point,
118 bool lost_resource,
119 BlockingTaskRunner* main_thread_task_runner));
[email protected]d72d9e02014-04-03 18:40:09120};
121
122struct CommonMailboxObjects {
jbauman9015c8b2014-12-11 00:49:37123 explicit CommonMailboxObjects(SharedBitmapManager* manager)
[email protected]d72d9e02014-04-03 18:40:09124 : mailbox_name1_(MailboxFromChar('1')),
125 mailbox_name2_(MailboxFromChar('2')),
126 sync_point1_(1),
jbauman9015c8b2014-12-11 00:49:37127 sync_point2_(2) {
[email protected]d72d9e02014-04-03 18:40:09128 release_mailbox1_ = base::Bind(&MockMailboxCallback::Release,
129 base::Unretained(&mock_callback_),
130 mailbox_name1_);
131 release_mailbox2_ = base::Bind(&MockMailboxCallback::Release,
132 base::Unretained(&mock_callback_),
133 mailbox_name2_);
skyostil3976a3f2014-09-04 22:07:23134 release_mailbox1_impl_ = base::Bind(&MockMailboxCallback::ReleaseImpl,
135 base::Unretained(&mock_callback_),
136 mailbox_name1_);
137 release_mailbox2_impl_ = base::Bind(&MockMailboxCallback::ReleaseImpl,
138 base::Unretained(&mock_callback_),
139 mailbox_name2_);
[email protected]d72d9e02014-04-03 18:40:09140 const uint32 arbitrary_target1 = GL_TEXTURE_2D;
141 const uint32 arbitrary_target2 = GL_TEXTURE_EXTERNAL_OES;
142 mailbox1_ = TextureMailbox(mailbox_name1_, arbitrary_target1, sync_point1_);
143 mailbox2_ = TextureMailbox(mailbox_name2_, arbitrary_target2, sync_point2_);
144 gfx::Size size(128, 128);
jbauman9015c8b2014-12-11 00:49:37145 shared_bitmap_ = manager->AllocateSharedBitmap(size);
146 DCHECK(shared_bitmap_);
147 release_mailbox3_ =
148 base::Bind(&MockMailboxCallback::Release2,
149 base::Unretained(&mock_callback_), shared_bitmap_.get());
150 release_mailbox3_impl_ =
151 base::Bind(&MockMailboxCallback::ReleaseImpl2,
152 base::Unretained(&mock_callback_), shared_bitmap_.get());
153 mailbox3_ = TextureMailbox(shared_bitmap_.get(), size);
[email protected]d72d9e02014-04-03 18:40:09154 }
155
156 gpu::Mailbox mailbox_name1_;
157 gpu::Mailbox mailbox_name2_;
158 MockMailboxCallback mock_callback_;
159 ReleaseCallback release_mailbox1_;
160 ReleaseCallback release_mailbox2_;
161 ReleaseCallback release_mailbox3_;
skyostil3976a3f2014-09-04 22:07:23162 ReleaseCallbackImpl release_mailbox1_impl_;
163 ReleaseCallbackImpl release_mailbox2_impl_;
164 ReleaseCallbackImpl release_mailbox3_impl_;
[email protected]d72d9e02014-04-03 18:40:09165 TextureMailbox mailbox1_;
166 TextureMailbox mailbox2_;
167 TextureMailbox mailbox3_;
168 uint32 sync_point1_;
169 uint32 sync_point2_;
jbauman9015c8b2014-12-11 00:49:37170 scoped_ptr<SharedBitmap> shared_bitmap_;
[email protected]d72d9e02014-04-03 18:40:09171};
172
[email protected]31d4df82013-07-18 10:17:22173class TextureLayerTest : public testing::Test {
174 public:
175 TextureLayerTest()
176 : fake_client_(
[email protected]4e2eb352014-03-20 17:25:45177 FakeLayerTreeHostClient(FakeLayerTreeHostClient::DIRECT_3D)),
reveman34b7a1522015-03-23 20:27:47178 host_impl_(&proxy_, &shared_bitmap_manager_, &task_graph_runner_),
jbauman9015c8b2014-12-11 00:49:37179 test_data_(&shared_bitmap_manager_) {}
[email protected]31d4df82013-07-18 10:17:22180
181 protected:
dcheng93a52eb2014-12-23 02:14:23182 void SetUp() override {
[email protected]31d4df82013-07-18 10:17:22183 layer_tree_host_.reset(new MockLayerTreeHost(&fake_client_));
[email protected]d72d9e02014-04-03 18:40:09184 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
185 layer_tree_host_->SetViewportSize(gfx::Size(10, 10));
186 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
[email protected]31d4df82013-07-18 10:17:22187 }
188
dcheng93a52eb2014-12-23 02:14:23189 void TearDown() override {
[email protected]31d4df82013-07-18 10:17:22190 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
[email protected]31d4df82013-07-18 10:17:22191 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
192
kulkarni.a4015690f12014-10-10 13:50:06193 layer_tree_host_->SetRootLayer(nullptr);
danakjf446a072014-09-27 21:55:48194 layer_tree_host_ = nullptr;
[email protected]31d4df82013-07-18 10:17:22195 }
196
197 scoped_ptr<MockLayerTreeHost> layer_tree_host_;
198 FakeImplProxy proxy_;
199 FakeLayerTreeHostClient fake_client_;
[email protected]4e2eb352014-03-20 17:25:45200 TestSharedBitmapManager shared_bitmap_manager_;
reveman34b7a1522015-03-23 20:27:47201 TestTaskGraphRunner task_graph_runner_;
[email protected]31d4df82013-07-18 10:17:22202 FakeLayerTreeHostImpl host_impl_;
jbauman9015c8b2014-12-11 00:49:37203 CommonMailboxObjects test_data_;
[email protected]31d4df82013-07-18 10:17:22204};
205
[email protected]31d4df82013-07-18 10:17:22206TEST_F(TextureLayerTest, CheckPropertyChangeCausesCorrectBehavior) {
kulkarni.a4015690f12014-10-10 13:50:06207 scoped_refptr<TextureLayer> test_layer =
208 TextureLayer::CreateForMailbox(nullptr);
[email protected]80d42bd2013-08-30 19:13:45209 EXPECT_SET_NEEDS_COMMIT(1, layer_tree_host_->SetRootLayer(test_layer));
[email protected]31d4df82013-07-18 10:17:22210
211 // Test properties that should call SetNeedsCommit. All properties need to
212 // be set to new values in order for SetNeedsCommit to be called.
213 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetFlipped(false));
jackhou10c9af42014-12-04 05:24:44214 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetNearestNeighbor(true));
[email protected]31d4df82013-07-18 10:17:22215 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetUV(
216 gfx::PointF(0.25f, 0.25f), gfx::PointF(0.75f, 0.75f)));
217 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetVertexOpacity(
218 0.5f, 0.5f, 0.5f, 0.5f));
219 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetPremultipliedAlpha(false));
220 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetBlendBackgroundColor(true));
[email protected]31d4df82013-07-18 10:17:22221}
222
[email protected]1c10e232013-07-31 12:35:43223TEST_F(TextureLayerTest, VisibleContentOpaqueRegion) {
224 const gfx::Size layer_bounds(100, 100);
225 const gfx::Rect layer_rect(layer_bounds);
226 const Region layer_region(layer_rect);
227
kulkarni.a4015690f12014-10-10 13:50:06228 scoped_refptr<TextureLayer> layer = TextureLayer::CreateForMailbox(nullptr);
[email protected]1c10e232013-07-31 12:35:43229 layer->SetBounds(layer_bounds);
230 layer->draw_properties().visible_content_rect = layer_rect;
231 layer->SetBlendBackgroundColor(true);
232
233 // Verify initial conditions.
234 EXPECT_FALSE(layer->contents_opaque());
235 EXPECT_EQ(0u, layer->background_color());
236 EXPECT_EQ(Region().ToString(),
237 layer->VisibleContentOpaqueRegion().ToString());
238
239 // Opaque background.
240 layer->SetBackgroundColor(SK_ColorWHITE);
241 EXPECT_EQ(layer_region.ToString(),
242 layer->VisibleContentOpaqueRegion().ToString());
243
244 // Transparent background.
245 layer->SetBackgroundColor(SkColorSetARGB(100, 255, 255, 255));
246 EXPECT_EQ(Region().ToString(),
247 layer->VisibleContentOpaqueRegion().ToString());
248}
249
[email protected]31d4df82013-07-18 10:17:22250TEST_F(TextureLayerTest, RateLimiter) {
251 FakeTextureLayerClient client;
252 scoped_refptr<TextureLayer> test_layer = TextureLayer::CreateForMailbox(
253 &client);
254 test_layer->SetIsDrawable(true);
255 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
256 layer_tree_host_->SetRootLayer(test_layer);
257
258 // Don't rate limit until we invalidate.
[email protected]aeeb3372013-11-05 14:05:54259 EXPECT_CALL(*layer_tree_host_, StartRateLimiter()).Times(0);
[email protected]31d4df82013-07-18 10:17:22260 test_layer->SetRateLimitContext(true);
261 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
262
263 // Do rate limit after we invalidate.
[email protected]aeeb3372013-11-05 14:05:54264 EXPECT_CALL(*layer_tree_host_, StartRateLimiter());
[email protected]31d4df82013-07-18 10:17:22265 test_layer->SetNeedsDisplay();
266 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
267
268 // Stop rate limiter when we don't want it any more.
[email protected]aeeb3372013-11-05 14:05:54269 EXPECT_CALL(*layer_tree_host_, StopRateLimiter());
[email protected]31d4df82013-07-18 10:17:22270 test_layer->SetRateLimitContext(false);
271 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
272
273 // Or we clear the client.
274 test_layer->SetRateLimitContext(true);
[email protected]aeeb3372013-11-05 14:05:54275 EXPECT_CALL(*layer_tree_host_, StopRateLimiter());
[email protected]31d4df82013-07-18 10:17:22276 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
277 test_layer->ClearClient();
278 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
279
280 // Reset to a layer with a client, that started the rate limiter.
281 test_layer = TextureLayer::CreateForMailbox(
282 &client);
283 test_layer->SetIsDrawable(true);
284 test_layer->SetRateLimitContext(true);
285 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
286 layer_tree_host_->SetRootLayer(test_layer);
[email protected]aeeb3372013-11-05 14:05:54287 EXPECT_CALL(*layer_tree_host_, StartRateLimiter()).Times(0);
[email protected]31d4df82013-07-18 10:17:22288 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
[email protected]aeeb3372013-11-05 14:05:54289 EXPECT_CALL(*layer_tree_host_, StartRateLimiter());
[email protected]31d4df82013-07-18 10:17:22290 test_layer->SetNeedsDisplay();
291 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
292
293 // Stop rate limiter when we're removed from the tree.
[email protected]aeeb3372013-11-05 14:05:54294 EXPECT_CALL(*layer_tree_host_, StopRateLimiter());
[email protected]d72d9e02014-04-03 18:40:09295 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1);
kulkarni.a4015690f12014-10-10 13:50:06296 layer_tree_host_->SetRootLayer(nullptr);
[email protected]31d4df82013-07-18 10:17:22297 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
298}
299
[email protected]df41e252014-02-03 23:39:50300class TestMailboxHolder : public TextureLayer::TextureMailboxHolder {
[email protected]9794fb32013-08-29 09:49:59301 public:
[email protected]df41e252014-02-03 23:39:50302 using TextureLayer::TextureMailboxHolder::Create;
[email protected]9794fb32013-08-29 09:49:59303
304 protected:
dcheng716bedf2014-10-21 09:51:08305 ~TestMailboxHolder() override {}
[email protected]9794fb32013-08-29 09:49:59306};
307
[email protected]de44a152013-01-08 15:28:46308class TextureLayerWithMailboxTest : public TextureLayerTest {
[email protected]28571b042013-03-14 07:59:15309 protected:
dcheng93a52eb2014-12-23 02:14:23310 void TearDown() override {
[email protected]28571b042013-03-14 07:59:15311 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
312 EXPECT_CALL(test_data_.mock_callback_,
313 Release(test_data_.mailbox_name1_,
[email protected]7ba3ca72013-04-11 06:37:25314 test_data_.sync_point1_,
315 false)).Times(1);
[email protected]28571b042013-03-14 07:59:15316 TextureLayerTest::TearDown();
317 }
[email protected]de44a152013-01-08 15:28:46318};
319
[email protected]28571b042013-03-14 07:59:15320TEST_F(TextureLayerWithMailboxTest, ReplaceMailboxOnMainThreadBeforeCommit) {
kulkarni.a4015690f12014-10-10 13:50:06321 scoped_refptr<TextureLayer> test_layer =
322 TextureLayer::CreateForMailbox(nullptr);
[email protected]22898ed2013-06-01 04:52:30323 ASSERT_TRUE(test_layer.get());
[email protected]de44a152013-01-08 15:28:46324
[email protected]28571b042013-03-14 07:59:15325 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
326 layer_tree_host_->SetRootLayer(test_layer);
327 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
[email protected]de44a152013-01-08 15:28:46328
[email protected]28571b042013-03-14 07:59:15329 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
[email protected]9260757f2013-09-17 01:24:16330 test_layer->SetTextureMailbox(
331 test_data_.mailbox1_,
332 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
[email protected]28571b042013-03-14 07:59:15333 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
[email protected]de44a152013-01-08 15:28:46334
[email protected]28571b042013-03-14 07:59:15335 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
336 EXPECT_CALL(test_data_.mock_callback_,
[email protected]7ba3ca72013-04-11 06:37:25337 Release(test_data_.mailbox_name1_,
338 test_data_.sync_point1_,
339 false))
[email protected]28571b042013-03-14 07:59:15340 .Times(1);
[email protected]9260757f2013-09-17 01:24:16341 test_layer->SetTextureMailbox(
342 test_data_.mailbox2_,
343 SingleReleaseCallback::Create(test_data_.release_mailbox2_));
[email protected]28571b042013-03-14 07:59:15344 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
345 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]de44a152013-01-08 15:28:46346
[email protected]28571b042013-03-14 07:59:15347 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
348 EXPECT_CALL(test_data_.mock_callback_,
[email protected]7ba3ca72013-04-11 06:37:25349 Release(test_data_.mailbox_name2_,
350 test_data_.sync_point2_,
351 false))
[email protected]28571b042013-03-14 07:59:15352 .Times(1);
danakj968153f32014-10-15 22:52:16353 test_layer->SetTextureMailbox(TextureMailbox(), nullptr);
[email protected]28571b042013-03-14 07:59:15354 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
355 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]de44a152013-01-08 15:28:46356
[email protected]80d42bd2013-08-30 19:13:45357 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
[email protected]9260757f2013-09-17 01:24:16358 test_layer->SetTextureMailbox(
359 test_data_.mailbox3_,
360 SingleReleaseCallback::Create(test_data_.release_mailbox3_));
[email protected]42f40a52013-06-08 04:38:51361 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
362 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
363
[email protected]42f40a52013-06-08 04:38:51364 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
365 EXPECT_CALL(test_data_.mock_callback_,
jbauman9015c8b2014-12-11 00:49:37366 Release2(test_data_.shared_bitmap_.get(), 0, false)).Times(1);
danakj968153f32014-10-15 22:52:16367 test_layer->SetTextureMailbox(TextureMailbox(), nullptr);
[email protected]42f40a52013-06-08 04:38:51368 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
369 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
370
[email protected]28571b042013-03-14 07:59:15371 // Test destructor.
372 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
[email protected]9260757f2013-09-17 01:24:16373 test_layer->SetTextureMailbox(
374 test_data_.mailbox1_,
375 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
[email protected]de44a152013-01-08 15:28:46376}
377
[email protected]f9e8f452014-03-07 22:09:40378TEST_F(TextureLayerTest, SetTextureMailboxWithoutReleaseCallback) {
kulkarni.a4015690f12014-10-10 13:50:06379 scoped_refptr<TextureLayer> test_layer =
380 TextureLayer::CreateForMailbox(nullptr);
[email protected]f9e8f452014-03-07 22:09:40381 ASSERT_TRUE(test_layer.get());
382
383 // These use the same gpu::Mailbox, but different sync points.
384 TextureMailbox mailbox1(MailboxFromChar('a'), GL_TEXTURE_2D, 1);
385 TextureMailbox mailbox2(MailboxFromChar('a'), GL_TEXTURE_2D, 2);
386
[email protected]f9e8f452014-03-07 22:09:40387 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
388 layer_tree_host_->SetRootLayer(test_layer);
389 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
390
391 // Set the mailbox the first time. It should cause a commit.
[email protected]f9e8f452014-03-07 22:09:40392 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
393 test_layer->SetTextureMailboxWithoutReleaseCallback(mailbox1);
394 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
395
396 // Set the mailbox again with a new sync point, as the backing texture has
397 // been updated. It should cause a new commit.
[email protected]f9e8f452014-03-07 22:09:40398 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
399 test_layer->SetTextureMailboxWithoutReleaseCallback(mailbox2);
400 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
401}
402
[email protected]9794fb32013-08-29 09:49:59403class TextureLayerMailboxHolderTest : public TextureLayerTest {
404 public:
405 TextureLayerMailboxHolderTest()
406 : main_thread_("MAIN") {
407 main_thread_.Start();
skyostil0fd1dad2015-04-13 20:11:48408 main_thread_.message_loop()->task_runner()->PostTask(
409 FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::InitializeOnMain,
410 base::Unretained(this)));
skyostil3976a3f2014-09-04 22:07:23411 Wait(main_thread_);
[email protected]9794fb32013-08-29 09:49:59412 }
413
414 void Wait(const base::Thread& thread) {
415 bool manual_reset = false;
416 bool initially_signaled = false;
417 base::WaitableEvent event(manual_reset, initially_signaled);
skyostil0fd1dad2015-04-13 20:11:48418 thread.message_loop()->task_runner()->PostTask(
[email protected]9794fb32013-08-29 09:49:59419 FROM_HERE,
420 base::Bind(&base::WaitableEvent::Signal, base::Unretained(&event)));
421 event.Wait();
422 }
423
424 void CreateMainRef() {
425 main_ref_ = TestMailboxHolder::Create(
[email protected]9260757f2013-09-17 01:24:16426 test_data_.mailbox1_,
427 SingleReleaseCallback::Create(test_data_.release_mailbox1_)).Pass();
[email protected]9794fb32013-08-29 09:49:59428 }
429
danakjf446a072014-09-27 21:55:48430 void ReleaseMainRef() { main_ref_ = nullptr; }
[email protected]9794fb32013-08-29 09:49:59431
skyostil3976a3f2014-09-04 22:07:23432 void CreateImplRef(scoped_ptr<SingleReleaseCallbackImpl>* impl_ref) {
[email protected]9794fb32013-08-29 09:49:59433 *impl_ref = main_ref_->holder()->GetCallbackForImplThread();
434 }
435
436 void CapturePostTasksAndWait(base::WaitableEvent* begin_capture,
437 base::WaitableEvent* wait_for_capture,
438 base::WaitableEvent* stop_capture) {
439 begin_capture->Wait();
skyostil3976a3f2014-09-04 22:07:23440 BlockingTaskRunner::CapturePostTasks capture(
441 main_thread_task_runner_.get());
[email protected]9794fb32013-08-29 09:49:59442 wait_for_capture->Signal();
443 stop_capture->Wait();
444 }
445
446 protected:
skyostil3976a3f2014-09-04 22:07:23447 void InitializeOnMain() {
448 main_thread_task_runner_ =
skyostil0fd1dad2015-04-13 20:11:48449 BlockingTaskRunner::Create(main_thread_.task_runner());
skyostil3976a3f2014-09-04 22:07:23450 }
451
[email protected]9794fb32013-08-29 09:49:59452 scoped_ptr<TestMailboxHolder::MainThreadReference>
453 main_ref_;
454 base::Thread main_thread_;
skyostil3976a3f2014-09-04 22:07:23455 scoped_ptr<BlockingTaskRunner> main_thread_task_runner_;
[email protected]9794fb32013-08-29 09:49:59456};
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
skyostil0fd1dad2015-04-13 20:11:48463 main_thread_.message_loop()->task_runner()->PostTask(
464 FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::CreateMainRef,
465 base::Unretained(this)));
[email protected]9794fb32013-08-29 09:49:59466
467 Wait(main_thread_);
468
469 // The texture layer is attached to compositor1, and passes a reference to its
470 // impl tree.
skyostil3976a3f2014-09-04 22:07:23471 scoped_ptr<SingleReleaseCallbackImpl> compositor1;
skyostil0fd1dad2015-04-13 20:11:48472 main_thread_.message_loop()->task_runner()->PostTask(
473 FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
474 base::Unretained(this), &compositor1));
[email protected]9794fb32013-08-29 09:49:59475
476 // Then the texture layer is removed and attached to compositor2, and passes a
477 // reference to its impl tree.
skyostil3976a3f2014-09-04 22:07:23478 scoped_ptr<SingleReleaseCallbackImpl> compositor2;
skyostil0fd1dad2015-04-13 20:11:48479 main_thread_.message_loop()->task_runner()->PostTask(
480 FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
481 base::Unretained(this), &compositor2));
[email protected]9794fb32013-08-29 09:49:59482
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
skyostil0fd1dad2015-04-13 20:11:48501 main_thread_.message_loop()->task_runner()->PostTask(
502 FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::ReleaseMainRef,
503 base::Unretained(this)));
[email protected]9794fb32013-08-29 09:49:59504 Wait(main_thread_);
505 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
506}
507
508TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_MainReleaseBetween) {
kulkarni.a4015690f12014-10-10 13:50:06509 scoped_refptr<TextureLayer> test_layer =
510 TextureLayer::CreateForMailbox(nullptr);
[email protected]9794fb32013-08-29 09:49:59511 ASSERT_TRUE(test_layer.get());
512
skyostil0fd1dad2015-04-13 20:11:48513 main_thread_.message_loop()->task_runner()->PostTask(
514 FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::CreateMainRef,
515 base::Unretained(this)));
[email protected]9794fb32013-08-29 09:49:59516
517 Wait(main_thread_);
518
519 // The texture layer is attached to compositor1, and passes a reference to its
520 // impl tree.
skyostil3976a3f2014-09-04 22:07:23521 scoped_ptr<SingleReleaseCallbackImpl> compositor1;
skyostil0fd1dad2015-04-13 20:11:48522 main_thread_.message_loop()->task_runner()->PostTask(
523 FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
524 base::Unretained(this), &compositor1));
[email protected]9794fb32013-08-29 09:49:59525
526 // Then the texture layer is removed and attached to compositor2, and passes a
527 // reference to its impl tree.
skyostil3976a3f2014-09-04 22:07:23528 scoped_ptr<SingleReleaseCallbackImpl> compositor2;
skyostil0fd1dad2015-04-13 20:11:48529 main_thread_.message_loop()->task_runner()->PostTask(
530 FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
531 base::Unretained(this), &compositor2));
[email protected]9794fb32013-08-29 09:49:59532
533 Wait(main_thread_);
534 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
535
536 // One compositor destroys their impl tree.
skyostil3976a3f2014-09-04 22:07:23537 compositor1->Run(100, false, main_thread_task_runner_.get());
[email protected]9794fb32013-08-29 09:49:59538
539 // Then the main thread reference is destroyed.
skyostil0fd1dad2015-04-13 20:11:48540 main_thread_.message_loop()->task_runner()->PostTask(
541 FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::ReleaseMainRef,
542 base::Unretained(this)));
[email protected]9794fb32013-08-29 09:49:59543
544 Wait(main_thread_);
545
546 EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0);
547 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
548
549 // The second impl reference is destroyed last, causing the mailbox to be
550 // released back to the embedder with the last sync point from the impl tree.
551 EXPECT_CALL(test_data_.mock_callback_,
552 Release(test_data_.mailbox_name1_, 200, true)).Times(1);
553
skyostil3976a3f2014-09-04 22:07:23554 compositor2->Run(200, true, main_thread_task_runner_.get());
[email protected]9794fb32013-08-29 09:49:59555 Wait(main_thread_);
556 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
557}
558
559TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_MainReleasedFirst) {
kulkarni.a4015690f12014-10-10 13:50:06560 scoped_refptr<TextureLayer> test_layer =
561 TextureLayer::CreateForMailbox(nullptr);
[email protected]9794fb32013-08-29 09:49:59562 ASSERT_TRUE(test_layer.get());
563
skyostil0fd1dad2015-04-13 20:11:48564 main_thread_.message_loop()->task_runner()->PostTask(
565 FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::CreateMainRef,
566 base::Unretained(this)));
[email protected]9794fb32013-08-29 09:49:59567
568 Wait(main_thread_);
569
570 // The texture layer is attached to compositor1, and passes a reference to its
571 // impl tree.
skyostil3976a3f2014-09-04 22:07:23572 scoped_ptr<SingleReleaseCallbackImpl> compositor1;
skyostil0fd1dad2015-04-13 20:11:48573 main_thread_.message_loop()->task_runner()->PostTask(
574 FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
575 base::Unretained(this), &compositor1));
[email protected]9794fb32013-08-29 09:49:59576
577 // Then the texture layer is removed and attached to compositor2, and passes a
578 // reference to its impl tree.
skyostil3976a3f2014-09-04 22:07:23579 scoped_ptr<SingleReleaseCallbackImpl> compositor2;
skyostil0fd1dad2015-04-13 20:11:48580 main_thread_.message_loop()->task_runner()->PostTask(
581 FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
582 base::Unretained(this), &compositor2));
[email protected]9794fb32013-08-29 09:49:59583
584 Wait(main_thread_);
585 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
586
587 // The main thread reference is destroyed first.
skyostil0fd1dad2015-04-13 20:11:48588 main_thread_.message_loop()->task_runner()->PostTask(
589 FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::ReleaseMainRef,
590 base::Unretained(this)));
[email protected]9794fb32013-08-29 09:49:59591
592 // One compositor destroys their impl tree.
skyostil3976a3f2014-09-04 22:07:23593 compositor2->Run(200, false, main_thread_task_runner_.get());
[email protected]9794fb32013-08-29 09:49:59594
595 Wait(main_thread_);
596
597 EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0);
598 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
599
600 // The second impl reference is destroyed last, causing the mailbox to be
601 // released back to the embedder with the last sync point from the impl tree.
602 EXPECT_CALL(test_data_.mock_callback_,
603 Release(test_data_.mailbox_name1_, 100, true)).Times(1);
604
skyostil3976a3f2014-09-04 22:07:23605 compositor1->Run(100, true, main_thread_task_runner_.get());
[email protected]9794fb32013-08-29 09:49:59606 Wait(main_thread_);
607 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
608}
609
610TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_SecondImplRefShortcut) {
kulkarni.a4015690f12014-10-10 13:50:06611 scoped_refptr<TextureLayer> test_layer =
612 TextureLayer::CreateForMailbox(nullptr);
[email protected]9794fb32013-08-29 09:49:59613 ASSERT_TRUE(test_layer.get());
614
skyostil0fd1dad2015-04-13 20:11:48615 main_thread_.message_loop()->task_runner()->PostTask(
616 FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::CreateMainRef,
617 base::Unretained(this)));
[email protected]9794fb32013-08-29 09:49:59618
619 Wait(main_thread_);
620
621 // The texture layer is attached to compositor1, and passes a reference to its
622 // impl tree.
skyostil3976a3f2014-09-04 22:07:23623 scoped_ptr<SingleReleaseCallbackImpl> compositor1;
skyostil0fd1dad2015-04-13 20:11:48624 main_thread_.message_loop()->task_runner()->PostTask(
625 FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
626 base::Unretained(this), &compositor1));
[email protected]9794fb32013-08-29 09:49:59627
628 // Then the texture layer is removed and attached to compositor2, and passes a
629 // reference to its impl tree.
skyostil3976a3f2014-09-04 22:07:23630 scoped_ptr<SingleReleaseCallbackImpl> compositor2;
skyostil0fd1dad2015-04-13 20:11:48631 main_thread_.message_loop()->task_runner()->PostTask(
632 FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
633 base::Unretained(this), &compositor2));
[email protected]9794fb32013-08-29 09:49:59634
635 Wait(main_thread_);
636 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
637
638 // The main thread reference is destroyed first.
skyostil0fd1dad2015-04-13 20:11:48639 main_thread_.message_loop()->task_runner()->PostTask(
640 FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::ReleaseMainRef,
641 base::Unretained(this)));
[email protected]9794fb32013-08-29 09:49:59642
643 EXPECT_CALL(test_data_.mock_callback_,
644 Release(test_data_.mailbox_name1_, 200, true)).Times(1);
645
646 bool manual_reset = false;
647 bool initially_signaled = false;
648 base::WaitableEvent begin_capture(manual_reset, initially_signaled);
649 base::WaitableEvent wait_for_capture(manual_reset, initially_signaled);
650 base::WaitableEvent stop_capture(manual_reset, initially_signaled);
651
652 // Post a task to start capturing tasks on the main thread. This will block
653 // the main thread until we signal the |stop_capture| event.
skyostil0fd1dad2015-04-13 20:11:48654 main_thread_.message_loop()->task_runner()->PostTask(
[email protected]9794fb32013-08-29 09:49:59655 FROM_HERE,
656 base::Bind(&TextureLayerMailboxHolderTest::CapturePostTasksAndWait,
skyostil0fd1dad2015-04-13 20:11:48657 base::Unretained(this), &begin_capture, &wait_for_capture,
[email protected]9794fb32013-08-29 09:49:59658 &stop_capture));
659
660 // Before the main thread capturing starts, one compositor destroys their
661 // impl reference. Since capturing did not start, this gets post-tasked to
662 // the main thread.
skyostil3976a3f2014-09-04 22:07:23663 compositor1->Run(100, false, main_thread_task_runner_.get());
[email protected]9794fb32013-08-29 09:49:59664
665 // Start capturing on the main thread.
666 begin_capture.Signal();
667 wait_for_capture.Wait();
668
669 // Meanwhile, the second compositor released its impl reference, but this task
670 // gets shortcutted directly to the main thread. This means the reference is
671 // released before compositor1, whose reference will be released later when
672 // the post-task is serviced. But since it was destroyed _on the impl thread_
673 // last, its sync point values should be used.
skyostil3976a3f2014-09-04 22:07:23674 compositor2->Run(200, true, main_thread_task_runner_.get());
[email protected]9794fb32013-08-29 09:49:59675
676 stop_capture.Signal();
677 Wait(main_thread_);
678
679 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
680}
681
[email protected]e216fef02013-03-20 22:56:10682class TextureLayerImplWithMailboxThreadedCallback : public LayerTreeTest {
[email protected]28571b042013-03-14 07:59:15683 public:
684 TextureLayerImplWithMailboxThreadedCallback()
685 : callback_count_(0),
686 commit_count_(0) {}
687
688 // Make sure callback is received on main and doesn't block the impl thread.
[email protected]df41e252014-02-03 23:39:50689 void ReleaseCallback(uint32 sync_point, bool lost_resource) {
[email protected]9794fb32013-08-29 09:49:59690 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]7ba3ca72013-04-11 06:37:25691 EXPECT_FALSE(lost_resource);
[email protected]28571b042013-03-14 07:59:15692 ++callback_count_;
693 }
694
695 void SetMailbox(char mailbox_char) {
[email protected]9794fb32013-08-29 09:49:59696 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]9260757f2013-09-17 01:24:16697 scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create(
[email protected]28571b042013-03-14 07:59:15698 base::Bind(
699 &TextureLayerImplWithMailboxThreadedCallback::ReleaseCallback,
700 base::Unretained(this)));
[email protected]df41e252014-02-03 23:39:50701 layer_->SetTextureMailbox(
[email protected]e0a4d732014-02-15 00:23:26702 TextureMailbox(MailboxFromChar(mailbox_char), GL_TEXTURE_2D, 0),
[email protected]df41e252014-02-03 23:39:50703 callback.Pass());
[email protected]28571b042013-03-14 07:59:15704 }
705
dcheng716bedf2014-10-21 09:51:08706 void BeginTest() override {
[email protected]9794fb32013-08-29 09:49:59707 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
708
[email protected]28571b042013-03-14 07:59:15709 gfx::Size bounds(100, 100);
710 root_ = Layer::Create();
[email protected]28571b042013-03-14 07:59:15711 root_->SetBounds(bounds);
712
kulkarni.a4015690f12014-10-10 13:50:06713 layer_ = TextureLayer::CreateForMailbox(nullptr);
[email protected]28571b042013-03-14 07:59:15714 layer_->SetIsDrawable(true);
[email protected]28571b042013-03-14 07:59:15715 layer_->SetBounds(bounds);
716
717 root_->AddChild(layer_);
[email protected]e216fef02013-03-20 22:56:10718 layer_tree_host()->SetRootLayer(root_);
[email protected]18ce59702013-04-09 04:58:40719 layer_tree_host()->SetViewportSize(bounds);
[email protected]28571b042013-03-14 07:59:15720 SetMailbox('1');
721 EXPECT_EQ(0, callback_count_);
722
723 // Case #1: change mailbox before the commit. The old mailbox should be
724 // released immediately.
725 SetMailbox('2');
726 EXPECT_EQ(1, callback_count_);
[email protected]e216fef02013-03-20 22:56:10727 PostSetNeedsCommitToMainThread();
[email protected]28571b042013-03-14 07:59:15728 }
729
dcheng716bedf2014-10-21 09:51:08730 void DidCommit() override {
[email protected]28571b042013-03-14 07:59:15731 ++commit_count_;
732 switch (commit_count_) {
733 case 1:
734 // Case #2: change mailbox after the commit (and draw), where the
735 // layer draws. The old mailbox should be released during the next
736 // commit.
737 SetMailbox('3');
738 EXPECT_EQ(1, callback_count_);
739 break;
740 case 2:
[email protected]28571b042013-03-14 07:59:15741 EXPECT_EQ(2, callback_count_);
742 // Case #3: change mailbox when the layer doesn't draw. The old
743 // mailbox should be released during the next commit.
744 layer_->SetBounds(gfx::Size());
745 SetMailbox('4');
746 break;
[email protected]9794fb32013-08-29 09:49:59747 case 3:
[email protected]28571b042013-03-14 07:59:15748 EXPECT_EQ(3, callback_count_);
749 // Case #4: release mailbox that was committed but never drawn. The
750 // old mailbox should be released during the next commit.
danakj968153f32014-10-15 22:52:16751 layer_->SetTextureMailbox(TextureMailbox(), nullptr);
[email protected]28571b042013-03-14 07:59:15752 break;
[email protected]9794fb32013-08-29 09:49:59753 case 4:
754 if (layer_tree_host()->settings().impl_side_painting) {
755 // With impl painting, the texture mailbox will still be on the impl
756 // thread when the commit finishes, because the layer is not drawble
757 // when it has no texture mailbox, and thus does not block the commit
758 // on activation. So, we wait for activation.
759 // TODO(danakj): fix this. crbug.com/277953
760 layer_tree_host()->SetNeedsCommit();
761 break;
762 } else {
763 ++commit_count_;
764 }
765 case 5:
[email protected]28571b042013-03-14 07:59:15766 EXPECT_EQ(4, callback_count_);
[email protected]7096acc2013-06-18 21:12:43767 // Restore a mailbox for the next step.
768 SetMailbox('5');
769 break;
[email protected]9794fb32013-08-29 09:49:59770 case 6:
[email protected]7096acc2013-06-18 21:12:43771 // Case #5: remove layer from tree. Callback should *not* be called, the
772 // mailbox is returned to the main thread.
773 EXPECT_EQ(4, callback_count_);
774 layer_->RemoveFromParent();
775 break;
[email protected]9794fb32013-08-29 09:49:59776 case 7:
777 if (layer_tree_host()->settings().impl_side_painting) {
778 // With impl painting, the texture mailbox will still be on the impl
779 // thread when the commit finishes, because the layer is not around to
780 // block the commit on activation anymore. So, we wait for activation.
781 // TODO(danakj): fix this. crbug.com/277953
782 layer_tree_host()->SetNeedsCommit();
783 break;
784 } else {
785 ++commit_count_;
786 }
787 case 8:
[email protected]7096acc2013-06-18 21:12:43788 EXPECT_EQ(4, callback_count_);
789 // Resetting the mailbox will call the callback now.
danakj968153f32014-10-15 22:52:16790 layer_->SetTextureMailbox(TextureMailbox(), nullptr);
[email protected]7096acc2013-06-18 21:12:43791 EXPECT_EQ(5, callback_count_);
[email protected]e216fef02013-03-20 22:56:10792 EndTest();
[email protected]28571b042013-03-14 07:59:15793 break;
794 default:
795 NOTREACHED();
796 break;
[email protected]de44a152013-01-08 15:28:46797 }
[email protected]28571b042013-03-14 07:59:15798 }
[email protected]de44a152013-01-08 15:28:46799
dcheng716bedf2014-10-21 09:51:08800 void AfterTest() override {}
[email protected]de44a152013-01-08 15:28:46801
[email protected]28571b042013-03-14 07:59:15802 private:
[email protected]9794fb32013-08-29 09:49:59803 base::ThreadChecker main_thread_;
[email protected]28571b042013-03-14 07:59:15804 int callback_count_;
805 int commit_count_;
806 scoped_refptr<Layer> root_;
807 scoped_refptr<TextureLayer> layer_;
[email protected]de44a152013-01-08 15:28:46808};
809
[email protected]4145d172013-05-10 16:54:36810SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
811 TextureLayerImplWithMailboxThreadedCallback);
[email protected]de44a152013-01-08 15:28:46812
[email protected]74b43cc2013-08-30 06:29:27813
[email protected]74b43cc2013-08-30 06:29:27814class TextureLayerMailboxIsActivatedDuringCommit : public LayerTreeTest {
815 protected:
[email protected]98ea818e2014-01-24 10:22:08816 TextureLayerMailboxIsActivatedDuringCommit() : activate_count_(0) {}
[email protected]74b43cc2013-08-30 06:29:27817
[email protected]df41e252014-02-03 23:39:50818 static void ReleaseCallback(uint32 sync_point, bool lost_resource) {}
[email protected]74b43cc2013-08-30 06:29:27819
820 void SetMailbox(char mailbox_char) {
[email protected]9260757f2013-09-17 01:24:16821 scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create(
[email protected]74b43cc2013-08-30 06:29:27822 base::Bind(
823 &TextureLayerMailboxIsActivatedDuringCommit::ReleaseCallback));
[email protected]df41e252014-02-03 23:39:50824 layer_->SetTextureMailbox(
[email protected]e0a4d732014-02-15 00:23:26825 TextureMailbox(MailboxFromChar(mailbox_char), GL_TEXTURE_2D, 0),
[email protected]df41e252014-02-03 23:39:50826 callback.Pass());
[email protected]74b43cc2013-08-30 06:29:27827 }
828
dcheng716bedf2014-10-21 09:51:08829 void BeginTest() override {
[email protected]74b43cc2013-08-30 06:29:27830 gfx::Size bounds(100, 100);
831 root_ = Layer::Create();
[email protected]74b43cc2013-08-30 06:29:27832 root_->SetBounds(bounds);
833
kulkarni.a4015690f12014-10-10 13:50:06834 layer_ = TextureLayer::CreateForMailbox(nullptr);
[email protected]74b43cc2013-08-30 06:29:27835 layer_->SetIsDrawable(true);
[email protected]74b43cc2013-08-30 06:29:27836 layer_->SetBounds(bounds);
837
838 root_->AddChild(layer_);
839 layer_tree_host()->SetRootLayer(root_);
840 layer_tree_host()->SetViewportSize(bounds);
841 SetMailbox('1');
842
843 PostSetNeedsCommitToMainThread();
844 }
845
dcheng716bedf2014-10-21 09:51:08846 void WillActivateTreeOnThread(LayerTreeHostImpl* impl) override {
[email protected]74b43cc2013-08-30 06:29:27847 ++activate_count_;
848 }
849
dcheng716bedf2014-10-21 09:51:08850 void DidCommit() override {
[email protected]98ea818e2014-01-24 10:22:08851 switch (layer_tree_host()->source_frame_number()) {
[email protected]74b43cc2013-08-30 06:29:27852 case 1:
853 // The first mailbox has been activated. Set a new mailbox, and
854 // expect the next commit to finish *after* it is activated.
855 SetMailbox('2');
[email protected]74b43cc2013-08-30 06:29:27856 break;
857 case 2:
858 // The second mailbox has been activated. Remove the layer from
859 // the tree to cause another commit/activation. The commit should
860 // finish *after* the layer is removed from the active tree.
861 layer_->RemoveFromParent();
[email protected]74b43cc2013-08-30 06:29:27862 break;
863 case 3:
864 EndTest();
865 break;
866 }
867 }
868
dcheng716bedf2014-10-21 09:51:08869 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
[email protected]98ea818e2014-01-24 10:22:08870 switch (host_impl->active_tree()->source_frame_number()) {
[email protected]b6061062014-06-27 19:20:08871 case 0: {
872 // The activate for the 1st mailbox should have happened before now.
873 EXPECT_EQ(1, activate_count_);
874 break;
875 }
876 case 1: {
[email protected]74b43cc2013-08-30 06:29:27877 // The activate for the 2nd mailbox should have happened before now.
[email protected]74b43cc2013-08-30 06:29:27878 EXPECT_EQ(2, activate_count_);
879 break;
880 }
[email protected]b6061062014-06-27 19:20:08881 case 2: {
[email protected]74b43cc2013-08-30 06:29:27882 // The activate to remove the layer should have happened before now.
[email protected]74b43cc2013-08-30 06:29:27883 EXPECT_EQ(3, activate_count_);
884 break;
885 }
[email protected]b6061062014-06-27 19:20:08886 case 3: {
887 NOTREACHED();
888 break;
889 }
[email protected]74b43cc2013-08-30 06:29:27890 }
891 }
892
dcheng716bedf2014-10-21 09:51:08893 void AfterTest() override {}
[email protected]74b43cc2013-08-30 06:29:27894
[email protected]74b43cc2013-08-30 06:29:27895 int activate_count_;
896 scoped_refptr<Layer> root_;
897 scoped_refptr<TextureLayer> layer_;
898};
899
900SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
901 TextureLayerMailboxIsActivatedDuringCommit);
902
[email protected]de44a152013-01-08 15:28:46903class TextureLayerImplWithMailboxTest : public TextureLayerTest {
[email protected]28571b042013-03-14 07:59:15904 protected:
[email protected]408b5e22013-03-19 09:48:09905 TextureLayerImplWithMailboxTest()
906 : fake_client_(
907 FakeLayerTreeHostClient(FakeLayerTreeHostClient::DIRECT_3D)) {}
908
dcheng93a52eb2014-12-23 02:14:23909 void SetUp() override {
[email protected]28571b042013-03-14 07:59:15910 TextureLayerTest::SetUp();
[email protected]408b5e22013-03-19 09:48:09911 layer_tree_host_.reset(new MockLayerTreeHost(&fake_client_));
danakjf446a072014-09-27 21:55:48912 EXPECT_TRUE(host_impl_.InitializeRenderer(FakeOutputSurface::Create3d()));
[email protected]28571b042013-03-14 07:59:15913 }
[email protected]de44a152013-01-08 15:28:46914
[email protected]0ec335c42013-07-04 06:17:08915 bool WillDraw(TextureLayerImpl* layer, DrawMode mode) {
916 bool will_draw = layer->WillDraw(
917 mode, host_impl_.active_tree()->resource_provider());
918 if (will_draw)
919 layer->DidDraw(host_impl_.active_tree()->resource_provider());
920 return will_draw;
921 }
922
[email protected]408b5e22013-03-19 09:48:09923 FakeLayerTreeHostClient fake_client_;
[email protected]de44a152013-01-08 15:28:46924};
925
[email protected]ffbb2212013-06-02 23:47:59926// Test conditions for results of TextureLayerImpl::WillDraw under
927// different configurations of different mailbox, texture_id, and draw_mode.
928TEST_F(TextureLayerImplWithMailboxTest, TestWillDraw) {
skyostil3976a3f2014-09-04 22:07:23929 EXPECT_CALL(
930 test_data_.mock_callback_,
931 ReleaseImpl(test_data_.mailbox_name1_, test_data_.sync_point1_, false, _))
[email protected]0ec335c42013-07-04 06:17:08932 .Times(AnyNumber());
933 EXPECT_CALL(test_data_.mock_callback_,
jbauman9015c8b2014-12-11 00:49:37934 ReleaseImpl2(test_data_.shared_bitmap_.get(), 0, false, _))
[email protected]0ec335c42013-07-04 06:17:08935 .Times(AnyNumber());
[email protected]ffbb2212013-06-02 23:47:59936 // Hardware mode.
937 {
938 scoped_ptr<TextureLayerImpl> impl_layer =
[email protected]17e08432014-04-10 00:41:11939 TextureLayerImpl::Create(host_impl_.active_tree(), 1);
[email protected]9260757f2013-09-17 01:24:16940 impl_layer->SetTextureMailbox(
941 test_data_.mailbox1_,
skyostil3976a3f2014-09-04 22:07:23942 SingleReleaseCallbackImpl::Create(test_data_.release_mailbox1_impl_));
[email protected]0ec335c42013-07-04 06:17:08943 EXPECT_TRUE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE));
[email protected]ffbb2212013-06-02 23:47:59944 }
945
946 {
947 scoped_ptr<TextureLayerImpl> impl_layer =
[email protected]17e08432014-04-10 00:41:11948 TextureLayerImpl::Create(host_impl_.active_tree(), 1);
danakj968153f32014-10-15 22:52:16949 impl_layer->SetTextureMailbox(TextureMailbox(), nullptr);
[email protected]0ec335c42013-07-04 06:17:08950 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE));
951 }
952
953 {
954 // Software resource.
955 scoped_ptr<TextureLayerImpl> impl_layer =
[email protected]17e08432014-04-10 00:41:11956 TextureLayerImpl::Create(host_impl_.active_tree(), 1);
[email protected]9260757f2013-09-17 01:24:16957 impl_layer->SetTextureMailbox(
958 test_data_.mailbox3_,
skyostil3976a3f2014-09-04 22:07:23959 SingleReleaseCallbackImpl::Create(test_data_.release_mailbox3_impl_));
[email protected]3e44d7a2013-07-30 00:03:10960 EXPECT_TRUE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE));
[email protected]ffbb2212013-06-02 23:47:59961 }
962
[email protected]0ec335c42013-07-04 06:17:08963 // Software 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_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE));
971 }
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_SOFTWARE));
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]0ec335c42013-07-04 06:17:08987 EXPECT_TRUE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE));
988 }
989
[email protected]ffbb2212013-06-02 23:47:59990 // Resourceless 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_RESOURCELESS_SOFTWARE));
[email protected]ffbb2212013-06-02 23:47:59998 }
[email protected]ffbb2212013-06-02 23:47:59999}
1000
[email protected]28571b042013-03-14 07:59:151001TEST_F(TextureLayerImplWithMailboxTest, TestImplLayerCallbacks) {
1002 host_impl_.CreatePendingTree();
1003 scoped_ptr<TextureLayerImpl> pending_layer;
[email protected]17e08432014-04-10 00:41:111004 pending_layer = TextureLayerImpl::Create(host_impl_.pending_tree(), 1);
[email protected]28571b042013-03-14 07:59:151005 ASSERT_TRUE(pending_layer);
[email protected]de44a152013-01-08 15:28:461006
[email protected]ed511b8d2013-03-25 03:29:291007 scoped_ptr<LayerImpl> active_layer(
[email protected]28571b042013-03-14 07:59:151008 pending_layer->CreateLayerImpl(host_impl_.active_tree()));
[email protected]ed511b8d2013-03-25 03:29:291009 ASSERT_TRUE(active_layer);
[email protected]de44a152013-01-08 15:28:461010
[email protected]9260757f2013-09-17 01:24:161011 pending_layer->SetTextureMailbox(
1012 test_data_.mailbox1_,
skyostil3976a3f2014-09-04 22:07:231013 SingleReleaseCallbackImpl::Create(test_data_.release_mailbox1_impl_));
[email protected]421e84f2013-02-22 03:27:151014
[email protected]28571b042013-03-14 07:59:151015 // Test multiple commits without an activation.
skyostil3976a3f2014-09-04 22:07:231016 EXPECT_CALL(
1017 test_data_.mock_callback_,
1018 ReleaseImpl(test_data_.mailbox_name1_, test_data_.sync_point1_, false, _))
[email protected]28571b042013-03-14 07:59:151019 .Times(1);
[email protected]9260757f2013-09-17 01:24:161020 pending_layer->SetTextureMailbox(
1021 test_data_.mailbox2_,
skyostil3976a3f2014-09-04 22:07:231022 SingleReleaseCallbackImpl::Create(test_data_.release_mailbox2_impl_));
[email protected]28571b042013-03-14 07:59:151023 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]421e84f2013-02-22 03:27:151024
[email protected]28571b042013-03-14 07:59:151025 // Test callback after activation.
[email protected]ed511b8d2013-03-25 03:29:291026 pending_layer->PushPropertiesTo(active_layer.get());
1027 active_layer->DidBecomeActive();
[email protected]421e84f2013-02-22 03:27:151028
skyostil3976a3f2014-09-04 22:07:231029 EXPECT_CALL(test_data_.mock_callback_, ReleaseImpl(_, _, _, _)).Times(0);
[email protected]9260757f2013-09-17 01:24:161030 pending_layer->SetTextureMailbox(
1031 test_data_.mailbox1_,
skyostil3976a3f2014-09-04 22:07:231032 SingleReleaseCallbackImpl::Create(test_data_.release_mailbox1_impl_));
[email protected]28571b042013-03-14 07:59:151033 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]421e84f2013-02-22 03:27:151034
[email protected]7ba3ca72013-04-11 06:37:251035 EXPECT_CALL(test_data_.mock_callback_,
skyostil3976a3f2014-09-04 22:07:231036 ReleaseImpl(test_data_.mailbox_name2_, _, false, _)).Times(1);
[email protected]ed511b8d2013-03-25 03:29:291037 pending_layer->PushPropertiesTo(active_layer.get());
1038 active_layer->DidBecomeActive();
[email protected]28571b042013-03-14 07:59:151039 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]de44a152013-01-08 15:28:461040
[email protected]28571b042013-03-14 07:59:151041 // Test resetting the mailbox.
[email protected]7ba3ca72013-04-11 06:37:251042 EXPECT_CALL(test_data_.mock_callback_,
skyostil3976a3f2014-09-04 22:07:231043 ReleaseImpl(test_data_.mailbox_name1_, _, false, _)).Times(1);
danakj968153f32014-10-15 22:52:161044 pending_layer->SetTextureMailbox(TextureMailbox(), nullptr);
[email protected]ed511b8d2013-03-25 03:29:291045 pending_layer->PushPropertiesTo(active_layer.get());
1046 active_layer->DidBecomeActive();
[email protected]28571b042013-03-14 07:59:151047 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]de44a152013-01-08 15:28:461048
[email protected]28571b042013-03-14 07:59:151049 // Test destructor.
skyostil3976a3f2014-09-04 22:07:231050 EXPECT_CALL(
1051 test_data_.mock_callback_,
1052 ReleaseImpl(test_data_.mailbox_name1_, test_data_.sync_point1_, false, _))
[email protected]28571b042013-03-14 07:59:151053 .Times(1);
[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]de44a152013-01-08 15:28:461057}
1058
[email protected]28571b042013-03-14 07:59:151059TEST_F(TextureLayerImplWithMailboxTest,
1060 TestDestructorCallbackOnCreatedResource) {
1061 scoped_ptr<TextureLayerImpl> impl_layer;
[email protected]17e08432014-04-10 00:41:111062 impl_layer = TextureLayerImpl::Create(host_impl_.active_tree(), 1);
[email protected]28571b042013-03-14 07:59:151063 ASSERT_TRUE(impl_layer);
[email protected]de44a152013-01-08 15:28:461064
[email protected]7ba3ca72013-04-11 06:37:251065 EXPECT_CALL(test_data_.mock_callback_,
skyostil3976a3f2014-09-04 22:07:231066 ReleaseImpl(test_data_.mailbox_name1_, _, false, _)).Times(1);
[email protected]9260757f2013-09-17 01:24:161067 impl_layer->SetTextureMailbox(
1068 test_data_.mailbox1_,
skyostil3976a3f2014-09-04 22:07:231069 SingleReleaseCallbackImpl::Create(test_data_.release_mailbox1_impl_));
[email protected]ffbb2212013-06-02 23:47:591070 impl_layer->DidBecomeActive();
1071 EXPECT_TRUE(impl_layer->WillDraw(
1072 DRAW_MODE_HARDWARE, host_impl_.active_tree()->resource_provider()));
[email protected]28571b042013-03-14 07:59:151073 impl_layer->DidDraw(host_impl_.active_tree()->resource_provider());
danakj968153f32014-10-15 22:52:161074 impl_layer->SetTextureMailbox(TextureMailbox(), nullptr);
[email protected]de44a152013-01-08 15:28:461075}
1076
[email protected]28571b042013-03-14 07:59:151077TEST_F(TextureLayerImplWithMailboxTest, TestCallbackOnInUseResource) {
1078 ResourceProvider* provider = host_impl_.active_tree()->resource_provider();
skyostil3976a3f2014-09-04 22:07:231079 ResourceProvider::ResourceId id = provider->CreateResourceFromTextureMailbox(
1080 test_data_.mailbox1_,
1081 SingleReleaseCallbackImpl::Create(test_data_.release_mailbox1_impl_));
[email protected]28571b042013-03-14 07:59:151082 provider->AllocateForTesting(id);
[email protected]de44a152013-01-08 15:28:461083
[email protected]28571b042013-03-14 07:59:151084 // Transfer some resources to the parent.
1085 ResourceProvider::ResourceIdArray resource_ids_to_transfer;
1086 resource_ids_to_transfer.push_back(id);
1087 TransferableResourceArray list;
1088 provider->PrepareSendToParent(resource_ids_to_transfer, &list);
1089 EXPECT_TRUE(provider->InUseByConsumer(id));
skyostil3976a3f2014-09-04 22:07:231090 EXPECT_CALL(test_data_.mock_callback_, ReleaseImpl(_, _, _, _)).Times(0);
[email protected]28571b042013-03-14 07:59:151091 provider->DeleteResource(id);
1092 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]7ba3ca72013-04-11 06:37:251093 EXPECT_CALL(test_data_.mock_callback_,
skyostil3976a3f2014-09-04 22:07:231094 ReleaseImpl(test_data_.mailbox_name1_, _, false, _)).Times(1);
[email protected]e00bab022013-08-19 00:42:451095 ReturnedResourceArray returned;
1096 TransferableResource::ReturnResources(list, &returned);
1097 provider->ReceiveReturnsFromParent(returned);
[email protected]de44a152013-01-08 15:28:461098}
1099
[email protected]4bad8b62013-10-24 01:27:291100// Checks that TextureLayer::Update does not cause an extra commit when setting
1101// the texture mailbox.
1102class TextureLayerNoExtraCommitForMailboxTest
1103 : public LayerTreeTest,
1104 public TextureLayerClient {
1105 public:
[email protected]4bad8b62013-10-24 01:27:291106 // TextureLayerClient implementation.
dcheng716bedf2014-10-21 09:51:081107 bool PrepareTextureMailbox(
[email protected]df41e252014-02-03 23:39:501108 TextureMailbox* texture_mailbox,
[email protected]4bad8b62013-10-24 01:27:291109 scoped_ptr<SingleReleaseCallback>* release_callback,
mostynbf68776d82014-10-06 18:07:371110 bool use_shared_memory) override {
[email protected]cce34bd2013-12-02 23:24:451111 if (layer_tree_host()->source_frame_number() == 1) {
[email protected]9f35bd22014-06-03 15:25:461112 // Once this has been committed, the mailbox will be released.
[email protected]df41e252014-02-03 23:39:501113 *texture_mailbox = TextureMailbox();
[email protected]cce34bd2013-12-02 23:24:451114 return true;
1115 }
[email protected]4bad8b62013-10-24 01:27:291116
[email protected]e0a4d732014-02-15 00:23:261117 *texture_mailbox = TextureMailbox(MailboxFromChar('1'), GL_TEXTURE_2D, 0);
[email protected]4bad8b62013-10-24 01:27:291118 *release_callback = SingleReleaseCallback::Create(
1119 base::Bind(&TextureLayerNoExtraCommitForMailboxTest::MailboxReleased,
1120 base::Unretained(this)));
[email protected]4bad8b62013-10-24 01:27:291121 return true;
1122 }
1123
[email protected]df41e252014-02-03 23:39:501124 void MailboxReleased(uint32 sync_point, bool lost_resource) {
[email protected]9f35bd22014-06-03 15:25:461125 // Source frame number during callback is the same as the source frame
1126 // on which it was released.
1127 EXPECT_EQ(1, layer_tree_host()->source_frame_number());
[email protected]cce34bd2013-12-02 23:24:451128 EndTest();
[email protected]4bad8b62013-10-24 01:27:291129 }
1130
dcheng716bedf2014-10-21 09:51:081131 void SetupTree() override {
[email protected]4bad8b62013-10-24 01:27:291132 scoped_refptr<Layer> root = Layer::Create();
1133 root->SetBounds(gfx::Size(10, 10));
[email protected]4bad8b62013-10-24 01:27:291134 root->SetIsDrawable(true);
1135
[email protected]4bad8b62013-10-24 01:27:291136 texture_layer_ = TextureLayer::CreateForMailbox(this);
1137 texture_layer_->SetBounds(gfx::Size(10, 10));
[email protected]4bad8b62013-10-24 01:27:291138 texture_layer_->SetIsDrawable(true);
[email protected]0d7fb302014-01-23 21:30:471139 root->AddChild(texture_layer_);
[email protected]4bad8b62013-10-24 01:27:291140
1141 layer_tree_host()->SetRootLayer(root);
1142 LayerTreeTest::SetupTree();
1143 }
1144
dcheng716bedf2014-10-21 09:51:081145 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
[email protected]4bad8b62013-10-24 01:27:291146
dcheng716bedf2014-10-21 09:51:081147 void DidCommitAndDrawFrame() override {
[email protected]4bad8b62013-10-24 01:27:291148 switch (layer_tree_host()->source_frame_number()) {
1149 case 1:
[email protected]4ea293f72014-08-13 03:03:171150 EXPECT_FALSE(proxy()->MainFrameWillHappenForTesting());
[email protected]cce34bd2013-12-02 23:24:451151 // Invalidate the texture layer to clear the mailbox before
1152 // ending the test.
1153 texture_layer_->SetNeedsDisplay();
1154 break;
1155 case 2:
[email protected]4bad8b62013-10-24 01:27:291156 break;
1157 default:
1158 NOTREACHED();
1159 break;
1160 }
1161 }
1162
dcheng716bedf2014-10-21 09:51:081163 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override {
[email protected]cce34bd2013-12-02 23:24:451164 ASSERT_TRUE(result);
1165 DelegatedFrameData* delegated_frame_data =
1166 output_surface()->last_sent_frame().delegated_frame_data.get();
1167 if (!delegated_frame_data)
1168 return;
1169
1170 // Return all resources immediately.
1171 TransferableResourceArray resources_to_return =
1172 output_surface()->resources_held_by_parent();
1173
1174 CompositorFrameAck ack;
1175 for (size_t i = 0; i < resources_to_return.size(); ++i)
1176 output_surface()->ReturnResource(resources_to_return[i].id, &ack);
1177 host_impl->ReclaimResources(&ack);
[email protected]cce34bd2013-12-02 23:24:451178 }
1179
dcheng716bedf2014-10-21 09:51:081180 void AfterTest() override {}
[email protected]4bad8b62013-10-24 01:27:291181
1182 private:
[email protected]4bad8b62013-10-24 01:27:291183 scoped_refptr<TextureLayer> texture_layer_;
[email protected]4bad8b62013-10-24 01:27:291184};
1185
[email protected]cce34bd2013-12-02 23:24:451186SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerNoExtraCommitForMailboxTest);
[email protected]4bad8b62013-10-24 01:27:291187
[email protected]b04264f92013-09-13 23:37:291188// Checks that changing a mailbox in the client for a TextureLayer that's
1189// invisible correctly works and uses the new mailbox as soon as the layer
1190// becomes visible (and returns the old one).
1191class TextureLayerChangeInvisibleMailboxTest
1192 : public LayerTreeTest,
1193 public TextureLayerClient {
1194 public:
1195 TextureLayerChangeInvisibleMailboxTest()
1196 : mailbox_changed_(true),
1197 mailbox_returned_(0),
1198 prepare_called_(0),
1199 commit_count_(0) {
1200 mailbox_ = MakeMailbox('1');
1201 }
1202
1203 // TextureLayerClient implementation.
dcheng716bedf2014-10-21 09:51:081204 bool PrepareTextureMailbox(
[email protected]e51444a2013-12-10 23:05:011205 TextureMailbox* mailbox,
[email protected]9260757f2013-09-17 01:24:161206 scoped_ptr<SingleReleaseCallback>* release_callback,
mostynbf68776d82014-10-06 18:07:371207 bool use_shared_memory) override {
[email protected]b04264f92013-09-13 23:37:291208 ++prepare_called_;
1209 if (!mailbox_changed_)
1210 return false;
1211 *mailbox = mailbox_;
[email protected]9260757f2013-09-17 01:24:161212 *release_callback = SingleReleaseCallback::Create(
1213 base::Bind(&TextureLayerChangeInvisibleMailboxTest::MailboxReleased,
1214 base::Unretained(this)));
[email protected]b04264f92013-09-13 23:37:291215 return true;
1216 }
1217
1218 TextureMailbox MakeMailbox(char name) {
[email protected]e0a4d732014-02-15 00:23:261219 return TextureMailbox(MailboxFromChar(name), GL_TEXTURE_2D, 0);
[email protected]b04264f92013-09-13 23:37:291220 }
1221
[email protected]df41e252014-02-03 23:39:501222 void MailboxReleased(uint32 sync_point, bool lost_resource) {
[email protected]b04264f92013-09-13 23:37:291223 ++mailbox_returned_;
1224 }
1225
dcheng716bedf2014-10-21 09:51:081226 void SetupTree() override {
[email protected]b04264f92013-09-13 23:37:291227 scoped_refptr<Layer> root = Layer::Create();
1228 root->SetBounds(gfx::Size(10, 10));
[email protected]b04264f92013-09-13 23:37:291229 root->SetIsDrawable(true);
1230
1231 solid_layer_ = SolidColorLayer::Create();
1232 solid_layer_->SetBounds(gfx::Size(10, 10));
1233 solid_layer_->SetIsDrawable(true);
1234 solid_layer_->SetBackgroundColor(SK_ColorWHITE);
1235 root->AddChild(solid_layer_);
1236
1237 parent_layer_ = Layer::Create();
1238 parent_layer_->SetBounds(gfx::Size(10, 10));
1239 parent_layer_->SetIsDrawable(true);
1240 root->AddChild(parent_layer_);
1241
1242 texture_layer_ = TextureLayer::CreateForMailbox(this);
1243 texture_layer_->SetBounds(gfx::Size(10, 10));
[email protected]b04264f92013-09-13 23:37:291244 texture_layer_->SetIsDrawable(true);
1245 parent_layer_->AddChild(texture_layer_);
1246
1247 layer_tree_host()->SetRootLayer(root);
1248 LayerTreeTest::SetupTree();
1249 }
1250
dcheng716bedf2014-10-21 09:51:081251 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
[email protected]b04264f92013-09-13 23:37:291252
dcheng716bedf2014-10-21 09:51:081253 void DidCommitAndDrawFrame() override {
[email protected]b04264f92013-09-13 23:37:291254 ++commit_count_;
1255 switch (commit_count_) {
1256 case 1:
1257 // We should have updated the layer, committing the texture.
1258 EXPECT_EQ(1, prepare_called_);
1259 // Make layer invisible.
1260 parent_layer_->SetOpacity(0.f);
1261 break;
1262 case 2:
1263 // Layer shouldn't have been updated.
1264 EXPECT_EQ(1, prepare_called_);
1265 // Change the texture.
1266 mailbox_ = MakeMailbox('2');
1267 mailbox_changed_ = true;
1268 texture_layer_->SetNeedsDisplay();
1269 // Force a change to make sure we draw a frame.
1270 solid_layer_->SetBackgroundColor(SK_ColorGRAY);
1271 break;
1272 case 3:
1273 // Layer shouldn't have been updated.
1274 EXPECT_EQ(1, prepare_called_);
1275 // So the old mailbox isn't returned yet.
1276 EXPECT_EQ(0, mailbox_returned_);
1277 // Make layer visible again.
1278 parent_layer_->SetOpacity(1.f);
1279 break;
1280 case 4:
1281 // Layer should have been updated.
1282 EXPECT_EQ(2, prepare_called_);
1283 // So the old mailbox should have been returned already.
1284 EXPECT_EQ(1, mailbox_returned_);
1285 texture_layer_->ClearClient();
1286 break;
1287 case 5:
1288 EXPECT_EQ(2, mailbox_returned_);
1289 EndTest();
1290 break;
1291 default:
1292 NOTREACHED();
1293 break;
1294 }
1295 }
1296
dcheng716bedf2014-10-21 09:51:081297 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override {
[email protected]b04264f92013-09-13 23:37:291298 ASSERT_TRUE(result);
1299 DelegatedFrameData* delegated_frame_data =
1300 output_surface()->last_sent_frame().delegated_frame_data.get();
1301 if (!delegated_frame_data)
1302 return;
1303
1304 // Return all resources immediately.
1305 TransferableResourceArray resources_to_return =
1306 output_surface()->resources_held_by_parent();
1307
1308 CompositorFrameAck ack;
1309 for (size_t i = 0; i < resources_to_return.size(); ++i)
1310 output_surface()->ReturnResource(resources_to_return[i].id, &ack);
[email protected]a7335e0b2013-09-18 09:34:511311 host_impl->ReclaimResources(&ack);
[email protected]b04264f92013-09-13 23:37:291312 }
1313
dcheng716bedf2014-10-21 09:51:081314 void AfterTest() override {}
[email protected]b04264f92013-09-13 23:37:291315
1316 private:
1317 scoped_refptr<SolidColorLayer> solid_layer_;
1318 scoped_refptr<Layer> parent_layer_;
1319 scoped_refptr<TextureLayer> texture_layer_;
1320
1321 // Used on the main thread.
1322 bool mailbox_changed_;
1323 TextureMailbox mailbox_;
1324 int mailbox_returned_;
1325 int prepare_called_;
1326 int commit_count_;
1327};
1328
1329SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerChangeInvisibleMailboxTest);
1330
[email protected]0d7fb302014-01-23 21:30:471331// Test that TextureLayerImpl::ReleaseResources can be called which releases
1332// the mailbox back to TextureLayerClient.
1333class TextureLayerReleaseResourcesBase
1334 : public LayerTreeTest,
1335 public TextureLayerClient {
1336 public:
1337 // TextureLayerClient implementation.
dcheng716bedf2014-10-21 09:51:081338 bool PrepareTextureMailbox(
[email protected]0d7fb302014-01-23 21:30:471339 TextureMailbox* mailbox,
1340 scoped_ptr<SingleReleaseCallback>* release_callback,
mostynbf68776d82014-10-06 18:07:371341 bool use_shared_memory) override {
[email protected]e0a4d732014-02-15 00:23:261342 *mailbox = TextureMailbox(MailboxFromChar('1'), GL_TEXTURE_2D, 0);
[email protected]0d7fb302014-01-23 21:30:471343 *release_callback = SingleReleaseCallback::Create(
1344 base::Bind(&TextureLayerReleaseResourcesBase::MailboxReleased,
1345 base::Unretained(this)));
1346 return true;
1347 }
1348
1349 void MailboxReleased(unsigned sync_point, bool lost_resource) {
1350 mailbox_released_ = true;
1351 }
1352
dcheng716bedf2014-10-21 09:51:081353 void SetupTree() override {
[email protected]0d7fb302014-01-23 21:30:471354 LayerTreeTest::SetupTree();
1355
1356 scoped_refptr<TextureLayer> texture_layer =
1357 TextureLayer::CreateForMailbox(this);
1358 texture_layer->SetBounds(gfx::Size(10, 10));
[email protected]0d7fb302014-01-23 21:30:471359 texture_layer->SetIsDrawable(true);
1360
1361 layer_tree_host()->root_layer()->AddChild(texture_layer);
1362 }
1363
dcheng716bedf2014-10-21 09:51:081364 void BeginTest() override {
[email protected]0d7fb302014-01-23 21:30:471365 mailbox_released_ = false;
1366 PostSetNeedsCommitToMainThread();
1367 }
1368
dcheng716bedf2014-10-21 09:51:081369 void DidCommitAndDrawFrame() override { EndTest(); }
[email protected]0d7fb302014-01-23 21:30:471370
dcheng716bedf2014-10-21 09:51:081371 void AfterTest() override { EXPECT_TRUE(mailbox_released_); }
[email protected]0d7fb302014-01-23 21:30:471372
1373 private:
1374 bool mailbox_released_;
1375};
1376
1377class TextureLayerReleaseResourcesAfterCommit
1378 : public TextureLayerReleaseResourcesBase {
1379 public:
dcheng716bedf2014-10-21 09:51:081380 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
kulkarni.a4015690f12014-10-10 13:50:061381 LayerTreeImpl* tree = nullptr;
danakj009cdfdf2015-02-17 22:35:141382 tree = host_impl->sync_tree();
[email protected]0d7fb302014-01-23 21:30:471383 tree->root_layer()->children()[0]->ReleaseResources();
1384 }
1385};
1386
1387SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerReleaseResourcesAfterCommit);
1388
1389class TextureLayerReleaseResourcesAfterActivate
1390 : public TextureLayerReleaseResourcesBase {
1391 public:
dcheng716bedf2014-10-21 09:51:081392 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
[email protected]0d7fb302014-01-23 21:30:471393 host_impl->active_tree()->root_layer()->children()[0]->ReleaseResources();
1394 }
1395};
1396
1397SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerReleaseResourcesAfterActivate);
1398
[email protected]9c2bd822013-07-26 12:30:171399class TextureLayerWithMailboxMainThreadDeleted : public LayerTreeTest {
1400 public:
[email protected]df41e252014-02-03 23:39:501401 void ReleaseCallback(uint32 sync_point, bool lost_resource) {
[email protected]9794fb32013-08-29 09:49:591402 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]9c2bd822013-07-26 12:30:171403 EXPECT_FALSE(lost_resource);
1404 ++callback_count_;
1405 EndTest();
1406 }
1407
1408 void SetMailbox(char mailbox_char) {
[email protected]9794fb32013-08-29 09:49:591409 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]9260757f2013-09-17 01:24:161410 scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create(
[email protected]9c2bd822013-07-26 12:30:171411 base::Bind(
1412 &TextureLayerWithMailboxMainThreadDeleted::ReleaseCallback,
1413 base::Unretained(this)));
[email protected]df41e252014-02-03 23:39:501414 layer_->SetTextureMailbox(
[email protected]e0a4d732014-02-15 00:23:261415 TextureMailbox(MailboxFromChar(mailbox_char), GL_TEXTURE_2D, 0),
[email protected]df41e252014-02-03 23:39:501416 callback.Pass());
[email protected]9c2bd822013-07-26 12:30:171417 }
1418
dcheng716bedf2014-10-21 09:51:081419 void SetupTree() override {
[email protected]9c2bd822013-07-26 12:30:171420 gfx::Size bounds(100, 100);
1421 root_ = Layer::Create();
[email protected]9c2bd822013-07-26 12:30:171422 root_->SetBounds(bounds);
1423
kulkarni.a4015690f12014-10-10 13:50:061424 layer_ = TextureLayer::CreateForMailbox(nullptr);
[email protected]9c2bd822013-07-26 12:30:171425 layer_->SetIsDrawable(true);
[email protected]9c2bd822013-07-26 12:30:171426 layer_->SetBounds(bounds);
1427
1428 root_->AddChild(layer_);
1429 layer_tree_host()->SetRootLayer(root_);
1430 layer_tree_host()->SetViewportSize(bounds);
1431 }
1432
dcheng716bedf2014-10-21 09:51:081433 void BeginTest() override {
[email protected]9794fb32013-08-29 09:49:591434 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
1435
[email protected]9c2bd822013-07-26 12:30:171436 callback_count_ = 0;
1437
1438 // Set the mailbox on the main thread.
1439 SetMailbox('1');
1440 EXPECT_EQ(0, callback_count_);
1441
1442 PostSetNeedsCommitToMainThread();
1443 }
1444
dcheng716bedf2014-10-21 09:51:081445 void DidCommitAndDrawFrame() override {
[email protected]9c2bd822013-07-26 12:30:171446 switch (layer_tree_host()->source_frame_number()) {
1447 case 1:
1448 // Delete the TextureLayer on the main thread while the mailbox is in
1449 // the impl tree.
1450 layer_->RemoveFromParent();
kulkarni.a4015690f12014-10-10 13:50:061451 layer_ = nullptr;
[email protected]9c2bd822013-07-26 12:30:171452 break;
1453 }
1454 }
1455
dcheng716bedf2014-10-21 09:51:081456 void AfterTest() override { EXPECT_EQ(1, callback_count_); }
[email protected]9c2bd822013-07-26 12:30:171457
1458 private:
[email protected]9794fb32013-08-29 09:49:591459 base::ThreadChecker main_thread_;
[email protected]9c2bd822013-07-26 12:30:171460 int callback_count_;
1461 scoped_refptr<Layer> root_;
1462 scoped_refptr<TextureLayer> layer_;
1463};
1464
1465SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
1466 TextureLayerWithMailboxMainThreadDeleted);
1467
1468class TextureLayerWithMailboxImplThreadDeleted : public LayerTreeTest {
1469 public:
[email protected]df41e252014-02-03 23:39:501470 void ReleaseCallback(uint32 sync_point, bool lost_resource) {
[email protected]9794fb32013-08-29 09:49:591471 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]9c2bd822013-07-26 12:30:171472 EXPECT_FALSE(lost_resource);
1473 ++callback_count_;
1474 EndTest();
1475 }
1476
1477 void SetMailbox(char mailbox_char) {
[email protected]9794fb32013-08-29 09:49:591478 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]9260757f2013-09-17 01:24:161479 scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create(
[email protected]9c2bd822013-07-26 12:30:171480 base::Bind(
1481 &TextureLayerWithMailboxImplThreadDeleted::ReleaseCallback,
1482 base::Unretained(this)));
[email protected]df41e252014-02-03 23:39:501483 layer_->SetTextureMailbox(
[email protected]e0a4d732014-02-15 00:23:261484 TextureMailbox(MailboxFromChar(mailbox_char), GL_TEXTURE_2D, 0),
[email protected]df41e252014-02-03 23:39:501485 callback.Pass());
[email protected]9c2bd822013-07-26 12:30:171486 }
1487
dcheng716bedf2014-10-21 09:51:081488 void SetupTree() override {
[email protected]9c2bd822013-07-26 12:30:171489 gfx::Size bounds(100, 100);
1490 root_ = Layer::Create();
[email protected]9c2bd822013-07-26 12:30:171491 root_->SetBounds(bounds);
1492
kulkarni.a4015690f12014-10-10 13:50:061493 layer_ = TextureLayer::CreateForMailbox(nullptr);
[email protected]9c2bd822013-07-26 12:30:171494 layer_->SetIsDrawable(true);
[email protected]9c2bd822013-07-26 12:30:171495 layer_->SetBounds(bounds);
1496
1497 root_->AddChild(layer_);
1498 layer_tree_host()->SetRootLayer(root_);
1499 layer_tree_host()->SetViewportSize(bounds);
1500 }
1501
dcheng716bedf2014-10-21 09:51:081502 void BeginTest() override {
[email protected]9794fb32013-08-29 09:49:591503 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
1504
[email protected]9c2bd822013-07-26 12:30:171505 callback_count_ = 0;
1506
1507 // Set the mailbox on the main thread.
1508 SetMailbox('1');
1509 EXPECT_EQ(0, callback_count_);
1510
1511 PostSetNeedsCommitToMainThread();
1512 }
1513
dcheng716bedf2014-10-21 09:51:081514 void DidCommitAndDrawFrame() override {
[email protected]9c2bd822013-07-26 12:30:171515 switch (layer_tree_host()->source_frame_number()) {
1516 case 1:
1517 // Remove the TextureLayer on the main thread while the mailbox is in
1518 // the impl tree, but don't delete the TextureLayer until after the impl
1519 // tree side is deleted.
1520 layer_->RemoveFromParent();
1521 break;
1522 case 2:
kulkarni.a4015690f12014-10-10 13:50:061523 layer_ = nullptr;
[email protected]9c2bd822013-07-26 12:30:171524 break;
1525 }
1526 }
1527
dcheng716bedf2014-10-21 09:51:081528 void AfterTest() override { EXPECT_EQ(1, callback_count_); }
[email protected]9c2bd822013-07-26 12:30:171529
1530 private:
[email protected]9794fb32013-08-29 09:49:591531 base::ThreadChecker main_thread_;
[email protected]9c2bd822013-07-26 12:30:171532 int callback_count_;
1533 scoped_refptr<Layer> root_;
1534 scoped_refptr<TextureLayer> layer_;
1535};
1536
1537SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
1538 TextureLayerWithMailboxImplThreadDeleted);
1539
[email protected]ba565742012-11-10 09:29:481540} // namespace
1541} // namespace cc