blob: 31313afa3df22ddafae290373e91a627a2575611 [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
avi02a4d172015-12-21 06:14:367#include <stddef.h>
8#include <stdint.h>
9
[email protected]b04264f92013-09-13 23:37:2910#include <algorithm>
[email protected]de44a152013-01-08 15:28:4611#include <string>
12
[email protected]b04264f92013-09-13 23:37:2913#include "base/bind.h"
[email protected]de44a152013-01-08 15:28:4614#include "base/callback.h"
skyostil0fd1dad2015-04-13 20:11:4815#include "base/location.h"
avi02a4d172015-12-21 06:14:3616#include "base/macros.h"
skyostil0fd1dad2015-04-13 20:11:4817#include "base/single_thread_task_runner.h"
danakj3c3973b2015-08-25 21:50:1818#include "base/synchronization/lock.h"
[email protected]9794fb32013-08-29 09:49:5919#include "base/synchronization/waitable_event.h"
skyostil0fd1dad2015-04-13 20:11:4820#include "base/thread_task_runner_handle.h"
[email protected]74b43cc2013-08-30 06:29:2721#include "base/threading/thread.h"
22#include "base/time/time.h"
[email protected]b04264f92013-09-13 23:37:2923#include "cc/layers/solid_color_layer.h"
[email protected]97d519fb2013-03-29 02:27:5424#include "cc/layers/texture_layer_client.h"
[email protected]cc3cfaa2013-03-18 09:05:5225#include "cc/layers/texture_layer_impl.h"
[email protected]b04264f92013-09-13 23:37:2926#include "cc/output/compositor_frame_ack.h"
27#include "cc/output/context_provider.h"
[email protected]e00bab022013-08-19 00:42:4528#include "cc/resources/returned_resource.h"
khushalsagarb64b360d2015-10-21 19:25:1629#include "cc/test/fake_impl_task_runner_provider.h"
[email protected]101441ce2012-10-16 01:45:0330#include "cc/test/fake_layer_tree_host_client.h"
[email protected]586d51ed2012-12-07 20:31:4531#include "cc/test/fake_layer_tree_host_impl.h"
[email protected]199b715e2013-08-13 05:18:3432#include "cc/test/fake_output_surface.h"
[email protected]06d68d02013-04-19 18:46:2133#include "cc/test/layer_test_common.h"
[email protected]e216fef02013-03-20 22:56:1034#include "cc/test/layer_tree_test.h"
reveman34b7a1522015-03-23 20:27:4735#include "cc/test/test_task_graph_runner.h"
[email protected]c2610b9f2013-10-31 06:54:5936#include "cc/test/test_web_graphics_context_3d.h"
[email protected]9794fb32013-08-29 09:49:5937#include "cc/trees/blocking_task_runner.h"
[email protected]556fd292013-03-18 08:03:0438#include "cc/trees/layer_tree_host.h"
39#include "cc/trees/layer_tree_impl.h"
40#include "cc/trees/single_thread_proxy.h"
[email protected]0bf5a202013-07-10 14:50:5441#include "gpu/GLES2/gl2extchromium.h"
[email protected]7f0c53db2012-10-02 00:23:1842#include "testing/gmock/include/gmock/gmock.h"
43#include "testing/gtest/include/gtest/gtest.h"
[email protected]c0dd24c2012-08-30 23:25:2744
[email protected]c0dd24c2012-08-30 23:25:2745using ::testing::Mock;
46using ::testing::_;
47using ::testing::AtLeast;
48using ::testing::AnyNumber;
[email protected]d72d9e02014-04-03 18:40:0949using ::testing::InvokeWithoutArgs;
[email protected]c0dd24c2012-08-30 23:25:2750
[email protected]ba565742012-11-10 09:29:4851namespace cc {
[email protected]c0dd24c2012-08-30 23:25:2752namespace {
53
[email protected]e0a4d732014-02-15 00:23:2654gpu::Mailbox MailboxFromChar(char value) {
[email protected]df41e252014-02-03 23:39:5055 gpu::Mailbox mailbox;
[email protected]e0a4d732014-02-15 00:23:2656 memset(mailbox.name, value, sizeof(mailbox.name));
[email protected]df41e252014-02-03 23:39:5057 return mailbox;
58}
59
[email protected]408b5e22013-03-19 09:48:0960class MockLayerTreeHost : public LayerTreeHost {
[email protected]28571b042013-03-14 07:59:1561 public:
danakjcf610582015-06-16 22:48:5662 static scoped_ptr<MockLayerTreeHost> Create(
63 FakeLayerTreeHostClient* client,
64 TaskGraphRunner* task_graph_runner) {
sadrul6780f3da2015-05-11 17:01:5265 LayerTreeHost::InitParams params;
66 params.client = client;
danakjcf610582015-06-16 22:48:5667 params.task_graph_runner = task_graph_runner;
sadrul6780f3da2015-05-11 17:01:5268 LayerTreeSettings settings;
69 params.settings = &settings;
70 return make_scoped_ptr(new MockLayerTreeHost(client, &params));
[email protected]28571b042013-03-14 07:59:1571 }
[email protected]c0dd24c2012-08-30 23:25:2772
[email protected]28571b042013-03-14 07:59:1573 MOCK_METHOD0(SetNeedsCommit, void());
[email protected]3519b872013-07-30 07:17:5074 MOCK_METHOD0(SetNeedsUpdateLayers, void());
[email protected]aeeb3372013-11-05 14:05:5475 MOCK_METHOD0(StartRateLimiter, void());
76 MOCK_METHOD0(StopRateLimiter, void());
sadrul6780f3da2015-05-11 17:01:5277
78 private:
79 MockLayerTreeHost(FakeLayerTreeHostClient* client,
80 LayerTreeHost::InitParams* params)
khushalsagar19458bd2015-12-08 02:19:0181 : LayerTreeHost(params, CompositorMode::SingleThreaded) {
sadrul6780f3da2015-05-11 17:01:5282 InitializeSingleThreaded(client, base::ThreadTaskRunnerHandle::Get(),
83 nullptr);
84 }
[email protected]c0dd24c2012-08-30 23:25:2785};
86
[email protected]d72d9e02014-04-03 18:40:0987class FakeTextureLayerClient : public TextureLayerClient {
88 public:
[email protected]17e08432014-04-10 00:41:1189 FakeTextureLayerClient() : mailbox_changed_(true) {}
[email protected]d72d9e02014-04-03 18:40:0990
dcheng716bedf2014-10-21 09:51:0891 bool PrepareTextureMailbox(
[email protected]d72d9e02014-04-03 18:40:0992 TextureMailbox* mailbox,
93 scoped_ptr<SingleReleaseCallback>* release_callback,
mostynbf68776d82014-10-06 18:07:3794 bool use_shared_memory) override {
[email protected]d72d9e02014-04-03 18:40:0995 if (!mailbox_changed_)
96 return false;
97
98 *mailbox = mailbox_;
danakja04855a2015-11-18 20:39:1099 *release_callback = std::move(release_callback_);
[email protected]d72d9e02014-04-03 18:40:09100 mailbox_changed_ = false;
101 return true;
102 }
103
[email protected]d72d9e02014-04-03 18:40:09104 void set_mailbox(const TextureMailbox& mailbox,
105 scoped_ptr<SingleReleaseCallback> release_callback) {
106 mailbox_ = mailbox;
danakja04855a2015-11-18 20:39:10107 release_callback_ = std::move(release_callback);
[email protected]d72d9e02014-04-03 18:40:09108 mailbox_changed_ = true;
109 }
110
111 private:
[email protected]d72d9e02014-04-03 18:40:09112 TextureMailbox mailbox_;
113 scoped_ptr<SingleReleaseCallback> release_callback_;
114 bool mailbox_changed_;
115 DISALLOW_COPY_AND_ASSIGN(FakeTextureLayerClient);
116};
117
118class MockMailboxCallback {
119 public:
120 MOCK_METHOD3(Release,
121 void(const gpu::Mailbox& mailbox,
dyencc16ed4d2015-11-03 20:03:04122 const gpu::SyncToken& sync_token,
[email protected]d72d9e02014-04-03 18:40:09123 bool lost_resource));
124 MOCK_METHOD3(Release2,
jbauman9015c8b2014-12-11 00:49:37125 void(SharedBitmap* shared_bitmap,
dyencc16ed4d2015-11-03 20:03:04126 const gpu::SyncToken& sync_token,
[email protected]d72d9e02014-04-03 18:40:09127 bool lost_resource));
skyostil3976a3f2014-09-04 22:07:23128 MOCK_METHOD4(ReleaseImpl,
129 void(const gpu::Mailbox& mailbox,
dyencc16ed4d2015-11-03 20:03:04130 const gpu::SyncToken& sync_token,
skyostil3976a3f2014-09-04 22:07:23131 bool lost_resource,
132 BlockingTaskRunner* main_thread_task_runner));
133 MOCK_METHOD4(ReleaseImpl2,
jbauman9015c8b2014-12-11 00:49:37134 void(SharedBitmap* shared_bitmap,
dyencc16ed4d2015-11-03 20:03:04135 const gpu::SyncToken& sync_token,
skyostil3976a3f2014-09-04 22:07:23136 bool lost_resource,
137 BlockingTaskRunner* main_thread_task_runner));
[email protected]d72d9e02014-04-03 18:40:09138};
139
140struct CommonMailboxObjects {
jbauman9015c8b2014-12-11 00:49:37141 explicit CommonMailboxObjects(SharedBitmapManager* manager)
[email protected]d72d9e02014-04-03 18:40:09142 : mailbox_name1_(MailboxFromChar('1')),
143 mailbox_name2_(MailboxFromChar('2')),
dyencc16ed4d2015-11-03 20:03:04144 sync_token1_(1),
145 sync_token2_(2) {
[email protected]d72d9e02014-04-03 18:40:09146 release_mailbox1_ = base::Bind(&MockMailboxCallback::Release,
147 base::Unretained(&mock_callback_),
148 mailbox_name1_);
149 release_mailbox2_ = base::Bind(&MockMailboxCallback::Release,
150 base::Unretained(&mock_callback_),
151 mailbox_name2_);
skyostil3976a3f2014-09-04 22:07:23152 release_mailbox1_impl_ = base::Bind(&MockMailboxCallback::ReleaseImpl,
153 base::Unretained(&mock_callback_),
154 mailbox_name1_);
155 release_mailbox2_impl_ = base::Bind(&MockMailboxCallback::ReleaseImpl,
156 base::Unretained(&mock_callback_),
157 mailbox_name2_);
avi02a4d172015-12-21 06:14:36158 const uint32_t arbitrary_target1 = GL_TEXTURE_2D;
159 const uint32_t arbitrary_target2 = GL_TEXTURE_EXTERNAL_OES;
dyencc16ed4d2015-11-03 20:03:04160 mailbox1_ = TextureMailbox(mailbox_name1_, sync_token1_, arbitrary_target1);
161 mailbox2_ = TextureMailbox(mailbox_name2_, sync_token2_, arbitrary_target2);
[email protected]d72d9e02014-04-03 18:40:09162 gfx::Size size(128, 128);
jbauman9015c8b2014-12-11 00:49:37163 shared_bitmap_ = manager->AllocateSharedBitmap(size);
164 DCHECK(shared_bitmap_);
165 release_mailbox3_ =
166 base::Bind(&MockMailboxCallback::Release2,
167 base::Unretained(&mock_callback_), shared_bitmap_.get());
168 release_mailbox3_impl_ =
169 base::Bind(&MockMailboxCallback::ReleaseImpl2,
170 base::Unretained(&mock_callback_), shared_bitmap_.get());
171 mailbox3_ = TextureMailbox(shared_bitmap_.get(), size);
[email protected]d72d9e02014-04-03 18:40:09172 }
173
174 gpu::Mailbox mailbox_name1_;
175 gpu::Mailbox mailbox_name2_;
176 MockMailboxCallback mock_callback_;
177 ReleaseCallback release_mailbox1_;
178 ReleaseCallback release_mailbox2_;
179 ReleaseCallback release_mailbox3_;
skyostil3976a3f2014-09-04 22:07:23180 ReleaseCallbackImpl release_mailbox1_impl_;
181 ReleaseCallbackImpl release_mailbox2_impl_;
182 ReleaseCallbackImpl release_mailbox3_impl_;
[email protected]d72d9e02014-04-03 18:40:09183 TextureMailbox mailbox1_;
184 TextureMailbox mailbox2_;
185 TextureMailbox mailbox3_;
dyencc16ed4d2015-11-03 20:03:04186 gpu::SyncToken sync_token1_;
187 gpu::SyncToken sync_token2_;
jbauman9015c8b2014-12-11 00:49:37188 scoped_ptr<SharedBitmap> shared_bitmap_;
[email protected]d72d9e02014-04-03 18:40:09189};
190
[email protected]31d4df82013-07-18 10:17:22191class TextureLayerTest : public testing::Test {
192 public:
193 TextureLayerTest()
194 : fake_client_(
[email protected]4e2eb352014-03-20 17:25:45195 FakeLayerTreeHostClient(FakeLayerTreeHostClient::DIRECT_3D)),
revemand180dfc32015-09-24 00:19:43196 output_surface_(FakeOutputSurface::Create3d()),
khushalsagarb64b360d2015-10-21 19:25:16197 host_impl_(&task_runner_provider_,
198 &shared_bitmap_manager_,
199 &task_graph_runner_),
jbauman9015c8b2014-12-11 00:49:37200 test_data_(&shared_bitmap_manager_) {}
[email protected]31d4df82013-07-18 10:17:22201
202 protected:
dcheng93a52eb2014-12-23 02:14:23203 void SetUp() override {
danakjcf610582015-06-16 22:48:56204 layer_tree_host_ =
205 MockLayerTreeHost::Create(&fake_client_, &task_graph_runner_);
[email protected]d72d9e02014-04-03 18:40:09206 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
207 layer_tree_host_->SetViewportSize(gfx::Size(10, 10));
208 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
[email protected]31d4df82013-07-18 10:17:22209 }
210
dcheng93a52eb2014-12-23 02:14:23211 void TearDown() override {
[email protected]31d4df82013-07-18 10:17:22212 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
[email protected]31d4df82013-07-18 10:17:22213 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
214
kulkarni.a4015690f12014-10-10 13:50:06215 layer_tree_host_->SetRootLayer(nullptr);
danakjf446a072014-09-27 21:55:48216 layer_tree_host_ = nullptr;
[email protected]31d4df82013-07-18 10:17:22217 }
218
219 scoped_ptr<MockLayerTreeHost> layer_tree_host_;
khushalsagarb64b360d2015-10-21 19:25:16220 FakeImplTaskRunnerProvider task_runner_provider_;
[email protected]31d4df82013-07-18 10:17:22221 FakeLayerTreeHostClient fake_client_;
[email protected]4e2eb352014-03-20 17:25:45222 TestSharedBitmapManager shared_bitmap_manager_;
reveman34b7a1522015-03-23 20:27:47223 TestTaskGraphRunner task_graph_runner_;
revemand180dfc32015-09-24 00:19:43224 scoped_ptr<OutputSurface> output_surface_;
[email protected]31d4df82013-07-18 10:17:22225 FakeLayerTreeHostImpl host_impl_;
jbauman9015c8b2014-12-11 00:49:37226 CommonMailboxObjects test_data_;
loysoa6edaaff2015-05-25 03:26:44227 LayerSettings layer_settings_;
[email protected]31d4df82013-07-18 10:17:22228};
229
[email protected]31d4df82013-07-18 10:17:22230TEST_F(TextureLayerTest, CheckPropertyChangeCausesCorrectBehavior) {
kulkarni.a4015690f12014-10-10 13:50:06231 scoped_refptr<TextureLayer> test_layer =
loysoa6edaaff2015-05-25 03:26:44232 TextureLayer::CreateForMailbox(layer_settings_, nullptr);
[email protected]80d42bd2013-08-30 19:13:45233 EXPECT_SET_NEEDS_COMMIT(1, layer_tree_host_->SetRootLayer(test_layer));
[email protected]31d4df82013-07-18 10:17:22234
235 // Test properties that should call SetNeedsCommit. All properties need to
236 // be set to new values in order for SetNeedsCommit to be called.
237 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetFlipped(false));
jackhou10c9af42014-12-04 05:24:44238 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetNearestNeighbor(true));
[email protected]31d4df82013-07-18 10:17:22239 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetUV(
240 gfx::PointF(0.25f, 0.25f), gfx::PointF(0.75f, 0.75f)));
241 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetVertexOpacity(
242 0.5f, 0.5f, 0.5f, 0.5f));
243 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetPremultipliedAlpha(false));
244 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetBlendBackgroundColor(true));
[email protected]31d4df82013-07-18 10:17:22245}
246
[email protected]df41e252014-02-03 23:39:50247class TestMailboxHolder : public TextureLayer::TextureMailboxHolder {
[email protected]9794fb32013-08-29 09:49:59248 public:
[email protected]df41e252014-02-03 23:39:50249 using TextureLayer::TextureMailboxHolder::Create;
[email protected]9794fb32013-08-29 09:49:59250
251 protected:
dcheng716bedf2014-10-21 09:51:08252 ~TestMailboxHolder() override {}
[email protected]9794fb32013-08-29 09:49:59253};
254
[email protected]de44a152013-01-08 15:28:46255class TextureLayerWithMailboxTest : public TextureLayerTest {
[email protected]28571b042013-03-14 07:59:15256 protected:
dcheng93a52eb2014-12-23 02:14:23257 void TearDown() override {
[email protected]28571b042013-03-14 07:59:15258 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
dyencc16ed4d2015-11-03 20:03:04259 EXPECT_CALL(
260 test_data_.mock_callback_,
261 Release(test_data_.mailbox_name1_, test_data_.sync_token1_, false))
262 .Times(1);
[email protected]28571b042013-03-14 07:59:15263 TextureLayerTest::TearDown();
264 }
[email protected]de44a152013-01-08 15:28:46265};
266
[email protected]28571b042013-03-14 07:59:15267TEST_F(TextureLayerWithMailboxTest, ReplaceMailboxOnMainThreadBeforeCommit) {
kulkarni.a4015690f12014-10-10 13:50:06268 scoped_refptr<TextureLayer> test_layer =
loysoa6edaaff2015-05-25 03:26:44269 TextureLayer::CreateForMailbox(layer_settings_, nullptr);
[email protected]22898ed2013-06-01 04:52:30270 ASSERT_TRUE(test_layer.get());
[email protected]de44a152013-01-08 15:28:46271
[email protected]28571b042013-03-14 07:59:15272 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
273 layer_tree_host_->SetRootLayer(test_layer);
274 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
[email protected]de44a152013-01-08 15:28:46275
[email protected]28571b042013-03-14 07:59:15276 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
[email protected]9260757f2013-09-17 01:24:16277 test_layer->SetTextureMailbox(
278 test_data_.mailbox1_,
279 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
[email protected]28571b042013-03-14 07:59:15280 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
[email protected]de44a152013-01-08 15:28:46281
[email protected]28571b042013-03-14 07:59:15282 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
dyencc16ed4d2015-11-03 20:03:04283 EXPECT_CALL(
284 test_data_.mock_callback_,
285 Release(test_data_.mailbox_name1_, test_data_.sync_token1_, false))
[email protected]28571b042013-03-14 07:59:15286 .Times(1);
[email protected]9260757f2013-09-17 01:24:16287 test_layer->SetTextureMailbox(
288 test_data_.mailbox2_,
289 SingleReleaseCallback::Create(test_data_.release_mailbox2_));
[email protected]28571b042013-03-14 07:59:15290 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
291 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]de44a152013-01-08 15:28:46292
[email protected]28571b042013-03-14 07:59:15293 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
dyencc16ed4d2015-11-03 20:03:04294 EXPECT_CALL(
295 test_data_.mock_callback_,
296 Release(test_data_.mailbox_name2_, test_data_.sync_token2_, false))
[email protected]28571b042013-03-14 07:59:15297 .Times(1);
danakj968153f32014-10-15 22:52:16298 test_layer->SetTextureMailbox(TextureMailbox(), nullptr);
[email protected]28571b042013-03-14 07:59:15299 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
300 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]de44a152013-01-08 15:28:46301
[email protected]80d42bd2013-08-30 19:13:45302 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
[email protected]9260757f2013-09-17 01:24:16303 test_layer->SetTextureMailbox(
304 test_data_.mailbox3_,
305 SingleReleaseCallback::Create(test_data_.release_mailbox3_));
[email protected]42f40a52013-06-08 04:38:51306 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
307 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
308
[email protected]42f40a52013-06-08 04:38:51309 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
310 EXPECT_CALL(test_data_.mock_callback_,
dyencc16ed4d2015-11-03 20:03:04311 Release2(test_data_.shared_bitmap_.get(), _, false))
312 .Times(1);
danakj968153f32014-10-15 22:52:16313 test_layer->SetTextureMailbox(TextureMailbox(), nullptr);
[email protected]42f40a52013-06-08 04:38:51314 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
315 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
316
[email protected]28571b042013-03-14 07:59:15317 // Test destructor.
318 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
[email protected]9260757f2013-09-17 01:24:16319 test_layer->SetTextureMailbox(
320 test_data_.mailbox1_,
321 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
[email protected]de44a152013-01-08 15:28:46322}
323
[email protected]f9e8f452014-03-07 22:09:40324TEST_F(TextureLayerTest, SetTextureMailboxWithoutReleaseCallback) {
kulkarni.a4015690f12014-10-10 13:50:06325 scoped_refptr<TextureLayer> test_layer =
loysoa6edaaff2015-05-25 03:26:44326 TextureLayer::CreateForMailbox(layer_settings_, nullptr);
[email protected]f9e8f452014-03-07 22:09:40327 ASSERT_TRUE(test_layer.get());
328
329 // These use the same gpu::Mailbox, but different sync points.
dyencc16ed4d2015-11-03 20:03:04330 TextureMailbox mailbox1(MailboxFromChar('a'), gpu::SyncToken(1),
331 GL_TEXTURE_2D);
332 TextureMailbox mailbox2(MailboxFromChar('a'), gpu::SyncToken(2),
333 GL_TEXTURE_2D);
[email protected]f9e8f452014-03-07 22:09:40334
[email protected]f9e8f452014-03-07 22:09:40335 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
336 layer_tree_host_->SetRootLayer(test_layer);
337 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
338
339 // Set the mailbox the first time. It should cause a commit.
[email protected]f9e8f452014-03-07 22:09:40340 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
341 test_layer->SetTextureMailboxWithoutReleaseCallback(mailbox1);
342 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
343
344 // Set the mailbox again with a new sync point, as the backing texture has
345 // been updated. It should cause a new commit.
[email protected]f9e8f452014-03-07 22:09:40346 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
347 test_layer->SetTextureMailboxWithoutReleaseCallback(mailbox2);
348 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
349}
350
[email protected]9794fb32013-08-29 09:49:59351class TextureLayerMailboxHolderTest : public TextureLayerTest {
352 public:
353 TextureLayerMailboxHolderTest()
354 : main_thread_("MAIN") {
355 main_thread_.Start();
skyostil0fd1dad2015-04-13 20:11:48356 main_thread_.message_loop()->task_runner()->PostTask(
357 FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::InitializeOnMain,
358 base::Unretained(this)));
skyostil3976a3f2014-09-04 22:07:23359 Wait(main_thread_);
[email protected]9794fb32013-08-29 09:49:59360 }
361
362 void Wait(const base::Thread& thread) {
363 bool manual_reset = false;
364 bool initially_signaled = false;
365 base::WaitableEvent event(manual_reset, initially_signaled);
skyostil0fd1dad2015-04-13 20:11:48366 thread.message_loop()->task_runner()->PostTask(
[email protected]9794fb32013-08-29 09:49:59367 FROM_HERE,
368 base::Bind(&base::WaitableEvent::Signal, base::Unretained(&event)));
369 event.Wait();
370 }
371
372 void CreateMainRef() {
373 main_ref_ = TestMailboxHolder::Create(
[email protected]9260757f2013-09-17 01:24:16374 test_data_.mailbox1_,
danakja5a05ba02015-11-20 20:14:21375 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
[email protected]9794fb32013-08-29 09:49:59376 }
377
danakjf446a072014-09-27 21:55:48378 void ReleaseMainRef() { main_ref_ = nullptr; }
[email protected]9794fb32013-08-29 09:49:59379
skyostil3976a3f2014-09-04 22:07:23380 void CreateImplRef(scoped_ptr<SingleReleaseCallbackImpl>* impl_ref) {
[email protected]9794fb32013-08-29 09:49:59381 *impl_ref = main_ref_->holder()->GetCallbackForImplThread();
382 }
383
384 void CapturePostTasksAndWait(base::WaitableEvent* begin_capture,
385 base::WaitableEvent* wait_for_capture,
386 base::WaitableEvent* stop_capture) {
387 begin_capture->Wait();
skyostil3976a3f2014-09-04 22:07:23388 BlockingTaskRunner::CapturePostTasks capture(
389 main_thread_task_runner_.get());
[email protected]9794fb32013-08-29 09:49:59390 wait_for_capture->Signal();
391 stop_capture->Wait();
392 }
393
394 protected:
skyostil3976a3f2014-09-04 22:07:23395 void InitializeOnMain() {
396 main_thread_task_runner_ =
skyostil0fd1dad2015-04-13 20:11:48397 BlockingTaskRunner::Create(main_thread_.task_runner());
skyostil3976a3f2014-09-04 22:07:23398 }
399
[email protected]9794fb32013-08-29 09:49:59400 scoped_ptr<TestMailboxHolder::MainThreadReference>
401 main_ref_;
402 base::Thread main_thread_;
skyostil3976a3f2014-09-04 22:07:23403 scoped_ptr<BlockingTaskRunner> main_thread_task_runner_;
[email protected]9794fb32013-08-29 09:49:59404};
405
406TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_BothReleaseThenMain) {
kulkarni.a4015690f12014-10-10 13:50:06407 scoped_refptr<TextureLayer> test_layer =
loysoa6edaaff2015-05-25 03:26:44408 TextureLayer::CreateForMailbox(layer_settings_, nullptr);
[email protected]9794fb32013-08-29 09:49:59409 ASSERT_TRUE(test_layer.get());
410
skyostil0fd1dad2015-04-13 20:11:48411 main_thread_.message_loop()->task_runner()->PostTask(
412 FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::CreateMainRef,
413 base::Unretained(this)));
[email protected]9794fb32013-08-29 09:49:59414
415 Wait(main_thread_);
416
417 // The texture layer is attached to compositor1, and passes a reference to its
418 // impl tree.
skyostil3976a3f2014-09-04 22:07:23419 scoped_ptr<SingleReleaseCallbackImpl> compositor1;
skyostil0fd1dad2015-04-13 20:11:48420 main_thread_.message_loop()->task_runner()->PostTask(
421 FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
422 base::Unretained(this), &compositor1));
[email protected]9794fb32013-08-29 09:49:59423
424 // Then the texture layer is removed and attached to compositor2, and passes a
425 // reference to its impl tree.
skyostil3976a3f2014-09-04 22:07:23426 scoped_ptr<SingleReleaseCallbackImpl> compositor2;
skyostil0fd1dad2015-04-13 20:11:48427 main_thread_.message_loop()->task_runner()->PostTask(
428 FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
429 base::Unretained(this), &compositor2));
[email protected]9794fb32013-08-29 09:49:59430
431 Wait(main_thread_);
432 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
433
434 // The compositors both destroy their impl trees before the main thread layer
435 // is destroyed.
dyencc16ed4d2015-11-03 20:03:04436 compositor1->Run(gpu::SyncToken(100), false, main_thread_task_runner_.get());
437 compositor2->Run(gpu::SyncToken(200), false, main_thread_task_runner_.get());
[email protected]9794fb32013-08-29 09:49:59438
439 Wait(main_thread_);
440
441 EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0);
442 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
443
444 // The main thread ref is the last one, so the mailbox is released back to the
445 // embedder, with the last sync point provided by the impl trees.
446 EXPECT_CALL(test_data_.mock_callback_,
dyencc16ed4d2015-11-03 20:03:04447 Release(test_data_.mailbox_name1_, gpu::SyncToken(200), false))
448 .Times(1);
[email protected]9794fb32013-08-29 09:49:59449
skyostil0fd1dad2015-04-13 20:11:48450 main_thread_.message_loop()->task_runner()->PostTask(
451 FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::ReleaseMainRef,
452 base::Unretained(this)));
[email protected]9794fb32013-08-29 09:49:59453 Wait(main_thread_);
454 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
455}
456
457TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_MainReleaseBetween) {
kulkarni.a4015690f12014-10-10 13:50:06458 scoped_refptr<TextureLayer> test_layer =
loysoa6edaaff2015-05-25 03:26:44459 TextureLayer::CreateForMailbox(layer_settings_, nullptr);
[email protected]9794fb32013-08-29 09:49:59460 ASSERT_TRUE(test_layer.get());
461
skyostil0fd1dad2015-04-13 20:11:48462 main_thread_.message_loop()->task_runner()->PostTask(
463 FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::CreateMainRef,
464 base::Unretained(this)));
[email protected]9794fb32013-08-29 09:49:59465
466 Wait(main_thread_);
467
468 // The texture layer is attached to compositor1, and passes a reference to its
469 // impl tree.
skyostil3976a3f2014-09-04 22:07:23470 scoped_ptr<SingleReleaseCallbackImpl> compositor1;
skyostil0fd1dad2015-04-13 20:11:48471 main_thread_.message_loop()->task_runner()->PostTask(
472 FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
473 base::Unretained(this), &compositor1));
[email protected]9794fb32013-08-29 09:49:59474
475 // Then the texture layer is removed and attached to compositor2, and passes a
476 // reference to its impl tree.
skyostil3976a3f2014-09-04 22:07:23477 scoped_ptr<SingleReleaseCallbackImpl> compositor2;
skyostil0fd1dad2015-04-13 20:11:48478 main_thread_.message_loop()->task_runner()->PostTask(
479 FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
480 base::Unretained(this), &compositor2));
[email protected]9794fb32013-08-29 09:49:59481
482 Wait(main_thread_);
483 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
484
485 // One compositor destroys their impl tree.
dyencc16ed4d2015-11-03 20:03:04486 compositor1->Run(gpu::SyncToken(100), false, main_thread_task_runner_.get());
[email protected]9794fb32013-08-29 09:49:59487
488 // Then the main thread reference is destroyed.
skyostil0fd1dad2015-04-13 20:11:48489 main_thread_.message_loop()->task_runner()->PostTask(
490 FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::ReleaseMainRef,
491 base::Unretained(this)));
[email protected]9794fb32013-08-29 09:49:59492
493 Wait(main_thread_);
494
495 EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0);
496 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
497
498 // The second impl reference is destroyed last, causing the mailbox to be
499 // released back to the embedder with the last sync point from the impl tree.
500 EXPECT_CALL(test_data_.mock_callback_,
dyencc16ed4d2015-11-03 20:03:04501 Release(test_data_.mailbox_name1_, gpu::SyncToken(200), true))
502 .Times(1);
[email protected]9794fb32013-08-29 09:49:59503
dyencc16ed4d2015-11-03 20:03:04504 compositor2->Run(gpu::SyncToken(200), true, main_thread_task_runner_.get());
[email protected]9794fb32013-08-29 09:49:59505 Wait(main_thread_);
506 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
507}
508
509TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_MainReleasedFirst) {
kulkarni.a4015690f12014-10-10 13:50:06510 scoped_refptr<TextureLayer> test_layer =
loysoa6edaaff2015-05-25 03:26:44511 TextureLayer::CreateForMailbox(layer_settings_, nullptr);
[email protected]9794fb32013-08-29 09:49:59512 ASSERT_TRUE(test_layer.get());
513
skyostil0fd1dad2015-04-13 20:11:48514 main_thread_.message_loop()->task_runner()->PostTask(
515 FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::CreateMainRef,
516 base::Unretained(this)));
[email protected]9794fb32013-08-29 09:49:59517
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;
skyostil0fd1dad2015-04-13 20:11:48523 main_thread_.message_loop()->task_runner()->PostTask(
524 FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
525 base::Unretained(this), &compositor1));
[email protected]9794fb32013-08-29 09:49:59526
527 // Then the texture layer is removed and attached to compositor2, and passes a
528 // reference to its impl tree.
skyostil3976a3f2014-09-04 22:07:23529 scoped_ptr<SingleReleaseCallbackImpl> compositor2;
skyostil0fd1dad2015-04-13 20:11:48530 main_thread_.message_loop()->task_runner()->PostTask(
531 FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
532 base::Unretained(this), &compositor2));
[email protected]9794fb32013-08-29 09:49:59533
534 Wait(main_thread_);
535 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
536
537 // The main thread reference is destroyed first.
skyostil0fd1dad2015-04-13 20:11:48538 main_thread_.message_loop()->task_runner()->PostTask(
539 FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::ReleaseMainRef,
540 base::Unretained(this)));
[email protected]9794fb32013-08-29 09:49:59541
542 // One compositor destroys their impl tree.
dyencc16ed4d2015-11-03 20:03:04543 compositor2->Run(gpu::SyncToken(200), false, main_thread_task_runner_.get());
[email protected]9794fb32013-08-29 09:49:59544
545 Wait(main_thread_);
546
547 EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0);
548 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
549
550 // The second impl reference is destroyed last, causing the mailbox to be
551 // released back to the embedder with the last sync point from the impl tree.
552 EXPECT_CALL(test_data_.mock_callback_,
dyencc16ed4d2015-11-03 20:03:04553 Release(test_data_.mailbox_name1_, gpu::SyncToken(100), true))
554 .Times(1);
[email protected]9794fb32013-08-29 09:49:59555
dyencc16ed4d2015-11-03 20:03:04556 compositor1->Run(gpu::SyncToken(100), true, main_thread_task_runner_.get());
[email protected]9794fb32013-08-29 09:49:59557 Wait(main_thread_);
558 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
559}
560
561TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_SecondImplRefShortcut) {
kulkarni.a4015690f12014-10-10 13:50:06562 scoped_refptr<TextureLayer> test_layer =
loysoa6edaaff2015-05-25 03:26:44563 TextureLayer::CreateForMailbox(layer_settings_, nullptr);
[email protected]9794fb32013-08-29 09:49:59564 ASSERT_TRUE(test_layer.get());
565
skyostil0fd1dad2015-04-13 20:11:48566 main_thread_.message_loop()->task_runner()->PostTask(
567 FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::CreateMainRef,
568 base::Unretained(this)));
[email protected]9794fb32013-08-29 09:49:59569
570 Wait(main_thread_);
571
572 // The texture layer is attached to compositor1, and passes a reference to its
573 // impl tree.
skyostil3976a3f2014-09-04 22:07:23574 scoped_ptr<SingleReleaseCallbackImpl> compositor1;
skyostil0fd1dad2015-04-13 20:11:48575 main_thread_.message_loop()->task_runner()->PostTask(
576 FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
577 base::Unretained(this), &compositor1));
[email protected]9794fb32013-08-29 09:49:59578
579 // Then the texture layer is removed and attached to compositor2, and passes a
580 // reference to its impl tree.
skyostil3976a3f2014-09-04 22:07:23581 scoped_ptr<SingleReleaseCallbackImpl> compositor2;
skyostil0fd1dad2015-04-13 20:11:48582 main_thread_.message_loop()->task_runner()->PostTask(
583 FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
584 base::Unretained(this), &compositor2));
[email protected]9794fb32013-08-29 09:49:59585
586 Wait(main_thread_);
587 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
588
589 // The main thread reference is destroyed first.
skyostil0fd1dad2015-04-13 20:11:48590 main_thread_.message_loop()->task_runner()->PostTask(
591 FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::ReleaseMainRef,
592 base::Unretained(this)));
[email protected]9794fb32013-08-29 09:49:59593
594 EXPECT_CALL(test_data_.mock_callback_,
dyencc16ed4d2015-11-03 20:03:04595 Release(test_data_.mailbox_name1_, gpu::SyncToken(200), true))
596 .Times(1);
[email protected]9794fb32013-08-29 09:49:59597
598 bool manual_reset = false;
599 bool initially_signaled = false;
600 base::WaitableEvent begin_capture(manual_reset, initially_signaled);
601 base::WaitableEvent wait_for_capture(manual_reset, initially_signaled);
602 base::WaitableEvent stop_capture(manual_reset, initially_signaled);
603
604 // Post a task to start capturing tasks on the main thread. This will block
605 // the main thread until we signal the |stop_capture| event.
skyostil0fd1dad2015-04-13 20:11:48606 main_thread_.message_loop()->task_runner()->PostTask(
[email protected]9794fb32013-08-29 09:49:59607 FROM_HERE,
608 base::Bind(&TextureLayerMailboxHolderTest::CapturePostTasksAndWait,
skyostil0fd1dad2015-04-13 20:11:48609 base::Unretained(this), &begin_capture, &wait_for_capture,
[email protected]9794fb32013-08-29 09:49:59610 &stop_capture));
611
612 // Before the main thread capturing starts, one compositor destroys their
613 // impl reference. Since capturing did not start, this gets post-tasked to
614 // the main thread.
dyencc16ed4d2015-11-03 20:03:04615 compositor1->Run(gpu::SyncToken(100), false, main_thread_task_runner_.get());
[email protected]9794fb32013-08-29 09:49:59616
617 // Start capturing on the main thread.
618 begin_capture.Signal();
619 wait_for_capture.Wait();
620
621 // Meanwhile, the second compositor released its impl reference, but this task
622 // gets shortcutted directly to the main thread. This means the reference is
623 // released before compositor1, whose reference will be released later when
624 // the post-task is serviced. But since it was destroyed _on the impl thread_
625 // last, its sync point values should be used.
dyencc16ed4d2015-11-03 20:03:04626 compositor2->Run(gpu::SyncToken(200), true, main_thread_task_runner_.get());
[email protected]9794fb32013-08-29 09:49:59627
628 stop_capture.Signal();
629 Wait(main_thread_);
630
631 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
632}
633
[email protected]e216fef02013-03-20 22:56:10634class TextureLayerImplWithMailboxThreadedCallback : public LayerTreeTest {
[email protected]28571b042013-03-14 07:59:15635 public:
636 TextureLayerImplWithMailboxThreadedCallback()
637 : callback_count_(0),
638 commit_count_(0) {}
639
640 // Make sure callback is received on main and doesn't block the impl thread.
dyencc16ed4d2015-11-03 20:03:04641 void ReleaseCallback(const gpu::SyncToken& sync_token, bool lost_resource) {
[email protected]9794fb32013-08-29 09:49:59642 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]7ba3ca72013-04-11 06:37:25643 EXPECT_FALSE(lost_resource);
[email protected]28571b042013-03-14 07:59:15644 ++callback_count_;
645 }
646
647 void SetMailbox(char mailbox_char) {
[email protected]9794fb32013-08-29 09:49:59648 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]9260757f2013-09-17 01:24:16649 scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create(
[email protected]28571b042013-03-14 07:59:15650 base::Bind(
651 &TextureLayerImplWithMailboxThreadedCallback::ReleaseCallback,
652 base::Unretained(this)));
dyencc16ed4d2015-11-03 20:03:04653 layer_->SetTextureMailbox(TextureMailbox(MailboxFromChar(mailbox_char),
654 gpu::SyncToken(), GL_TEXTURE_2D),
danakja04855a2015-11-18 20:39:10655 std::move(callback));
[email protected]28571b042013-03-14 07:59:15656 }
657
dcheng716bedf2014-10-21 09:51:08658 void BeginTest() override {
[email protected]9794fb32013-08-29 09:49:59659 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
660
[email protected]28571b042013-03-14 07:59:15661 gfx::Size bounds(100, 100);
loysoa6edaaff2015-05-25 03:26:44662 root_ = Layer::Create(layer_settings());
[email protected]28571b042013-03-14 07:59:15663 root_->SetBounds(bounds);
664
loysoa6edaaff2015-05-25 03:26:44665 layer_ = TextureLayer::CreateForMailbox(layer_settings(), nullptr);
[email protected]28571b042013-03-14 07:59:15666 layer_->SetIsDrawable(true);
[email protected]28571b042013-03-14 07:59:15667 layer_->SetBounds(bounds);
668
669 root_->AddChild(layer_);
[email protected]e216fef02013-03-20 22:56:10670 layer_tree_host()->SetRootLayer(root_);
[email protected]18ce59702013-04-09 04:58:40671 layer_tree_host()->SetViewportSize(bounds);
[email protected]28571b042013-03-14 07:59:15672 SetMailbox('1');
673 EXPECT_EQ(0, callback_count_);
674
675 // Case #1: change mailbox before the commit. The old mailbox should be
676 // released immediately.
677 SetMailbox('2');
678 EXPECT_EQ(1, callback_count_);
[email protected]e216fef02013-03-20 22:56:10679 PostSetNeedsCommitToMainThread();
[email protected]28571b042013-03-14 07:59:15680 }
681
dcheng716bedf2014-10-21 09:51:08682 void DidCommit() override {
[email protected]28571b042013-03-14 07:59:15683 ++commit_count_;
684 switch (commit_count_) {
685 case 1:
686 // Case #2: change mailbox after the commit (and draw), where the
687 // layer draws. The old mailbox should be released during the next
688 // commit.
689 SetMailbox('3');
690 EXPECT_EQ(1, callback_count_);
691 break;
692 case 2:
[email protected]28571b042013-03-14 07:59:15693 EXPECT_EQ(2, callback_count_);
694 // Case #3: change mailbox when the layer doesn't draw. The old
695 // mailbox should be released during the next commit.
696 layer_->SetBounds(gfx::Size());
697 SetMailbox('4');
698 break;
[email protected]9794fb32013-08-29 09:49:59699 case 3:
[email protected]28571b042013-03-14 07:59:15700 EXPECT_EQ(3, callback_count_);
701 // Case #4: release mailbox that was committed but never drawn. The
702 // old mailbox should be released during the next commit.
danakj968153f32014-10-15 22:52:16703 layer_->SetTextureMailbox(TextureMailbox(), nullptr);
[email protected]28571b042013-03-14 07:59:15704 break;
[email protected]9794fb32013-08-29 09:49:59705 case 4:
danakj431a1202015-06-17 19:09:33706 // With impl painting, the texture mailbox will still be on the impl
707 // thread when the commit finishes, because the layer is not drawble
708 // when it has no texture mailbox, and thus does not block the commit
709 // on activation. So, we wait for activation.
710 // TODO(danakj): fix this. crbug.com/277953
711 layer_tree_host()->SetNeedsCommit();
712 break;
[email protected]9794fb32013-08-29 09:49:59713 case 5:
[email protected]28571b042013-03-14 07:59:15714 EXPECT_EQ(4, callback_count_);
[email protected]7096acc2013-06-18 21:12:43715 // Restore a mailbox for the next step.
716 SetMailbox('5');
717 break;
[email protected]9794fb32013-08-29 09:49:59718 case 6:
[email protected]7096acc2013-06-18 21:12:43719 // Case #5: remove layer from tree. Callback should *not* be called, the
720 // mailbox is returned to the main thread.
721 EXPECT_EQ(4, callback_count_);
722 layer_->RemoveFromParent();
723 break;
[email protected]9794fb32013-08-29 09:49:59724 case 7:
danakj431a1202015-06-17 19:09:33725 // With impl painting, the texture mailbox will still be on the impl
726 // thread when the commit finishes, because the layer is not around to
727 // block the commit on activation anymore. So, we wait for activation.
728 // TODO(danakj): fix this. crbug.com/277953
729 layer_tree_host()->SetNeedsCommit();
730 break;
[email protected]9794fb32013-08-29 09:49:59731 case 8:
[email protected]7096acc2013-06-18 21:12:43732 EXPECT_EQ(4, callback_count_);
733 // Resetting the mailbox will call the callback now.
danakj968153f32014-10-15 22:52:16734 layer_->SetTextureMailbox(TextureMailbox(), nullptr);
[email protected]7096acc2013-06-18 21:12:43735 EXPECT_EQ(5, callback_count_);
[email protected]e216fef02013-03-20 22:56:10736 EndTest();
[email protected]28571b042013-03-14 07:59:15737 break;
738 default:
739 NOTREACHED();
740 break;
[email protected]de44a152013-01-08 15:28:46741 }
[email protected]28571b042013-03-14 07:59:15742 }
[email protected]de44a152013-01-08 15:28:46743
dcheng716bedf2014-10-21 09:51:08744 void AfterTest() override {}
[email protected]de44a152013-01-08 15:28:46745
[email protected]28571b042013-03-14 07:59:15746 private:
[email protected]9794fb32013-08-29 09:49:59747 base::ThreadChecker main_thread_;
[email protected]28571b042013-03-14 07:59:15748 int callback_count_;
749 int commit_count_;
750 scoped_refptr<Layer> root_;
751 scoped_refptr<TextureLayer> layer_;
[email protected]de44a152013-01-08 15:28:46752};
753
[email protected]4145d172013-05-10 16:54:36754SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
755 TextureLayerImplWithMailboxThreadedCallback);
[email protected]de44a152013-01-08 15:28:46756
[email protected]74b43cc2013-08-30 06:29:27757
[email protected]74b43cc2013-08-30 06:29:27758class TextureLayerMailboxIsActivatedDuringCommit : public LayerTreeTest {
759 protected:
[email protected]98ea818e2014-01-24 10:22:08760 TextureLayerMailboxIsActivatedDuringCommit() : activate_count_(0) {}
[email protected]74b43cc2013-08-30 06:29:27761
dyencc16ed4d2015-11-03 20:03:04762 static void ReleaseCallback(const gpu::SyncToken& sync_token,
763 bool lost_resource) {}
[email protected]74b43cc2013-08-30 06:29:27764
765 void SetMailbox(char mailbox_char) {
[email protected]9260757f2013-09-17 01:24:16766 scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create(
[email protected]74b43cc2013-08-30 06:29:27767 base::Bind(
768 &TextureLayerMailboxIsActivatedDuringCommit::ReleaseCallback));
dyencc16ed4d2015-11-03 20:03:04769 layer_->SetTextureMailbox(TextureMailbox(MailboxFromChar(mailbox_char),
770 gpu::SyncToken(), GL_TEXTURE_2D),
danakja04855a2015-11-18 20:39:10771 std::move(callback));
[email protected]74b43cc2013-08-30 06:29:27772 }
773
dcheng716bedf2014-10-21 09:51:08774 void BeginTest() override {
[email protected]74b43cc2013-08-30 06:29:27775 gfx::Size bounds(100, 100);
loysoa6edaaff2015-05-25 03:26:44776 root_ = Layer::Create(layer_settings());
[email protected]74b43cc2013-08-30 06:29:27777 root_->SetBounds(bounds);
778
loysoa6edaaff2015-05-25 03:26:44779 layer_ = TextureLayer::CreateForMailbox(layer_settings(), nullptr);
[email protected]74b43cc2013-08-30 06:29:27780 layer_->SetIsDrawable(true);
[email protected]74b43cc2013-08-30 06:29:27781 layer_->SetBounds(bounds);
782
783 root_->AddChild(layer_);
784 layer_tree_host()->SetRootLayer(root_);
785 layer_tree_host()->SetViewportSize(bounds);
786 SetMailbox('1');
787
788 PostSetNeedsCommitToMainThread();
789 }
790
dcheng716bedf2014-10-21 09:51:08791 void WillActivateTreeOnThread(LayerTreeHostImpl* impl) override {
danakj3c3973b2015-08-25 21:50:18792 base::AutoLock lock(activate_count_lock_);
[email protected]74b43cc2013-08-30 06:29:27793 ++activate_count_;
794 }
795
dcheng716bedf2014-10-21 09:51:08796 void DidCommit() override {
danakj3c3973b2015-08-25 21:50:18797 // The first frame doesn't cause anything to be returned so it does not
798 // need to wait for activation.
799 if (layer_tree_host()->source_frame_number() > 1) {
800 base::AutoLock lock(activate_count_lock_);
801 // The activate happened before commit is done on the main side.
802 EXPECT_EQ(activate_count_, layer_tree_host()->source_frame_number());
803 }
804
[email protected]98ea818e2014-01-24 10:22:08805 switch (layer_tree_host()->source_frame_number()) {
[email protected]74b43cc2013-08-30 06:29:27806 case 1:
807 // The first mailbox has been activated. Set a new mailbox, and
808 // expect the next commit to finish *after* it is activated.
809 SetMailbox('2');
[email protected]74b43cc2013-08-30 06:29:27810 break;
811 case 2:
812 // The second mailbox has been activated. Remove the layer from
813 // the tree to cause another commit/activation. The commit should
814 // finish *after* the layer is removed from the active tree.
815 layer_->RemoveFromParent();
[email protected]74b43cc2013-08-30 06:29:27816 break;
817 case 3:
818 EndTest();
819 break;
820 }
821 }
822
dcheng716bedf2014-10-21 09:51:08823 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
danakj3c3973b2015-08-25 21:50:18824 // The activate didn't happen before commit is done on the impl side (but it
825 // should happen before the main thread is done).
826 EXPECT_EQ(activate_count_, host_impl->sync_tree()->source_frame_number());
[email protected]74b43cc2013-08-30 06:29:27827 }
828
dcheng716bedf2014-10-21 09:51:08829 void AfterTest() override {}
[email protected]74b43cc2013-08-30 06:29:27830
danakj3c3973b2015-08-25 21:50:18831 base::Lock activate_count_lock_;
[email protected]74b43cc2013-08-30 06:29:27832 int activate_count_;
833 scoped_refptr<Layer> root_;
834 scoped_refptr<TextureLayer> layer_;
835};
836
837SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
838 TextureLayerMailboxIsActivatedDuringCommit);
839
[email protected]de44a152013-01-08 15:28:46840class TextureLayerImplWithMailboxTest : public TextureLayerTest {
[email protected]28571b042013-03-14 07:59:15841 protected:
[email protected]408b5e22013-03-19 09:48:09842 TextureLayerImplWithMailboxTest()
843 : fake_client_(
844 FakeLayerTreeHostClient(FakeLayerTreeHostClient::DIRECT_3D)) {}
845
dcheng93a52eb2014-12-23 02:14:23846 void SetUp() override {
[email protected]28571b042013-03-14 07:59:15847 TextureLayerTest::SetUp();
danakjcf610582015-06-16 22:48:56848 layer_tree_host_ =
849 MockLayerTreeHost::Create(&fake_client_, &task_graph_runner_);
sievers71c62dd52015-10-07 01:44:39850 host_impl_.SetVisible(true);
revemand180dfc32015-09-24 00:19:43851 EXPECT_TRUE(host_impl_.InitializeRenderer(output_surface_.get()));
[email protected]28571b042013-03-14 07:59:15852 }
[email protected]de44a152013-01-08 15:28:46853
[email protected]0ec335c42013-07-04 06:17:08854 bool WillDraw(TextureLayerImpl* layer, DrawMode mode) {
855 bool will_draw = layer->WillDraw(
856 mode, host_impl_.active_tree()->resource_provider());
857 if (will_draw)
858 layer->DidDraw(host_impl_.active_tree()->resource_provider());
859 return will_draw;
860 }
861
[email protected]408b5e22013-03-19 09:48:09862 FakeLayerTreeHostClient fake_client_;
[email protected]de44a152013-01-08 15:28:46863};
864
[email protected]ffbb2212013-06-02 23:47:59865// Test conditions for results of TextureLayerImpl::WillDraw under
866// different configurations of different mailbox, texture_id, and draw_mode.
867TEST_F(TextureLayerImplWithMailboxTest, TestWillDraw) {
skyostil3976a3f2014-09-04 22:07:23868 EXPECT_CALL(
869 test_data_.mock_callback_,
dyencc16ed4d2015-11-03 20:03:04870 ReleaseImpl(test_data_.mailbox_name1_, test_data_.sync_token1_, false, _))
[email protected]0ec335c42013-07-04 06:17:08871 .Times(AnyNumber());
dyencc16ed4d2015-11-03 20:03:04872 EXPECT_CALL(
873 test_data_.mock_callback_,
874 ReleaseImpl2(test_data_.shared_bitmap_.get(), gpu::SyncToken(), false, _))
[email protected]0ec335c42013-07-04 06:17:08875 .Times(AnyNumber());
[email protected]ffbb2212013-06-02 23:47:59876 // Hardware mode.
877 {
878 scoped_ptr<TextureLayerImpl> impl_layer =
[email protected]17e08432014-04-10 00:41:11879 TextureLayerImpl::Create(host_impl_.active_tree(), 1);
[email protected]9260757f2013-09-17 01:24:16880 impl_layer->SetTextureMailbox(
881 test_data_.mailbox1_,
skyostil3976a3f2014-09-04 22:07:23882 SingleReleaseCallbackImpl::Create(test_data_.release_mailbox1_impl_));
[email protected]0ec335c42013-07-04 06:17:08883 EXPECT_TRUE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE));
[email protected]ffbb2212013-06-02 23:47:59884 }
885
886 {
887 scoped_ptr<TextureLayerImpl> impl_layer =
[email protected]17e08432014-04-10 00:41:11888 TextureLayerImpl::Create(host_impl_.active_tree(), 1);
danakj968153f32014-10-15 22:52:16889 impl_layer->SetTextureMailbox(TextureMailbox(), nullptr);
[email protected]0ec335c42013-07-04 06:17:08890 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE));
891 }
892
893 {
894 // Software resource.
895 scoped_ptr<TextureLayerImpl> impl_layer =
[email protected]17e08432014-04-10 00:41:11896 TextureLayerImpl::Create(host_impl_.active_tree(), 1);
[email protected]9260757f2013-09-17 01:24:16897 impl_layer->SetTextureMailbox(
898 test_data_.mailbox3_,
skyostil3976a3f2014-09-04 22:07:23899 SingleReleaseCallbackImpl::Create(test_data_.release_mailbox3_impl_));
[email protected]3e44d7a2013-07-30 00:03:10900 EXPECT_TRUE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE));
[email protected]ffbb2212013-06-02 23:47:59901 }
902
[email protected]0ec335c42013-07-04 06:17:08903 // Software mode.
904 {
905 scoped_ptr<TextureLayerImpl> impl_layer =
[email protected]17e08432014-04-10 00:41:11906 TextureLayerImpl::Create(host_impl_.active_tree(), 1);
[email protected]9260757f2013-09-17 01:24:16907 impl_layer->SetTextureMailbox(
908 test_data_.mailbox1_,
skyostil3976a3f2014-09-04 22:07:23909 SingleReleaseCallbackImpl::Create(test_data_.release_mailbox1_impl_));
[email protected]0ec335c42013-07-04 06:17:08910 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE));
911 }
912
913 {
914 scoped_ptr<TextureLayerImpl> impl_layer =
[email protected]17e08432014-04-10 00:41:11915 TextureLayerImpl::Create(host_impl_.active_tree(), 1);
danakj968153f32014-10-15 22:52:16916 impl_layer->SetTextureMailbox(TextureMailbox(), nullptr);
[email protected]0ec335c42013-07-04 06:17:08917 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE));
918 }
919
920 {
921 // Software resource.
922 scoped_ptr<TextureLayerImpl> impl_layer =
[email protected]17e08432014-04-10 00:41:11923 TextureLayerImpl::Create(host_impl_.active_tree(), 1);
[email protected]9260757f2013-09-17 01:24:16924 impl_layer->SetTextureMailbox(
925 test_data_.mailbox3_,
skyostil3976a3f2014-09-04 22:07:23926 SingleReleaseCallbackImpl::Create(test_data_.release_mailbox3_impl_));
[email protected]0ec335c42013-07-04 06:17:08927 EXPECT_TRUE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE));
928 }
929
[email protected]ffbb2212013-06-02 23:47:59930 // Resourceless software mode.
931 {
932 scoped_ptr<TextureLayerImpl> impl_layer =
[email protected]17e08432014-04-10 00:41:11933 TextureLayerImpl::Create(host_impl_.active_tree(), 1);
[email protected]9260757f2013-09-17 01:24:16934 impl_layer->SetTextureMailbox(
935 test_data_.mailbox1_,
skyostil3976a3f2014-09-04 22:07:23936 SingleReleaseCallbackImpl::Create(test_data_.release_mailbox1_impl_));
[email protected]0ec335c42013-07-04 06:17:08937 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_RESOURCELESS_SOFTWARE));
[email protected]ffbb2212013-06-02 23:47:59938 }
[email protected]ffbb2212013-06-02 23:47:59939}
940
[email protected]28571b042013-03-14 07:59:15941TEST_F(TextureLayerImplWithMailboxTest, TestImplLayerCallbacks) {
942 host_impl_.CreatePendingTree();
943 scoped_ptr<TextureLayerImpl> pending_layer;
[email protected]17e08432014-04-10 00:41:11944 pending_layer = TextureLayerImpl::Create(host_impl_.pending_tree(), 1);
[email protected]28571b042013-03-14 07:59:15945 ASSERT_TRUE(pending_layer);
[email protected]de44a152013-01-08 15:28:46946
[email protected]ed511b8d2013-03-25 03:29:29947 scoped_ptr<LayerImpl> active_layer(
[email protected]28571b042013-03-14 07:59:15948 pending_layer->CreateLayerImpl(host_impl_.active_tree()));
[email protected]ed511b8d2013-03-25 03:29:29949 ASSERT_TRUE(active_layer);
[email protected]de44a152013-01-08 15:28:46950
[email protected]9260757f2013-09-17 01:24:16951 pending_layer->SetTextureMailbox(
952 test_data_.mailbox1_,
skyostil3976a3f2014-09-04 22:07:23953 SingleReleaseCallbackImpl::Create(test_data_.release_mailbox1_impl_));
[email protected]421e84f2013-02-22 03:27:15954
[email protected]28571b042013-03-14 07:59:15955 // Test multiple commits without an activation.
skyostil3976a3f2014-09-04 22:07:23956 EXPECT_CALL(
957 test_data_.mock_callback_,
dyencc16ed4d2015-11-03 20:03:04958 ReleaseImpl(test_data_.mailbox_name1_, test_data_.sync_token1_, false, _))
[email protected]28571b042013-03-14 07:59:15959 .Times(1);
[email protected]9260757f2013-09-17 01:24:16960 pending_layer->SetTextureMailbox(
961 test_data_.mailbox2_,
skyostil3976a3f2014-09-04 22:07:23962 SingleReleaseCallbackImpl::Create(test_data_.release_mailbox2_impl_));
[email protected]28571b042013-03-14 07:59:15963 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]421e84f2013-02-22 03:27:15964
[email protected]28571b042013-03-14 07:59:15965 // Test callback after activation.
[email protected]ed511b8d2013-03-25 03:29:29966 pending_layer->PushPropertiesTo(active_layer.get());
967 active_layer->DidBecomeActive();
[email protected]421e84f2013-02-22 03:27:15968
skyostil3976a3f2014-09-04 22:07:23969 EXPECT_CALL(test_data_.mock_callback_, ReleaseImpl(_, _, _, _)).Times(0);
[email protected]9260757f2013-09-17 01:24:16970 pending_layer->SetTextureMailbox(
971 test_data_.mailbox1_,
skyostil3976a3f2014-09-04 22:07:23972 SingleReleaseCallbackImpl::Create(test_data_.release_mailbox1_impl_));
[email protected]28571b042013-03-14 07:59:15973 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]421e84f2013-02-22 03:27:15974
[email protected]7ba3ca72013-04-11 06:37:25975 EXPECT_CALL(test_data_.mock_callback_,
skyostil3976a3f2014-09-04 22:07:23976 ReleaseImpl(test_data_.mailbox_name2_, _, false, _)).Times(1);
[email protected]ed511b8d2013-03-25 03:29:29977 pending_layer->PushPropertiesTo(active_layer.get());
978 active_layer->DidBecomeActive();
[email protected]28571b042013-03-14 07:59:15979 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]de44a152013-01-08 15:28:46980
[email protected]28571b042013-03-14 07:59:15981 // Test resetting the mailbox.
[email protected]7ba3ca72013-04-11 06:37:25982 EXPECT_CALL(test_data_.mock_callback_,
skyostil3976a3f2014-09-04 22:07:23983 ReleaseImpl(test_data_.mailbox_name1_, _, false, _)).Times(1);
danakj968153f32014-10-15 22:52:16984 pending_layer->SetTextureMailbox(TextureMailbox(), nullptr);
[email protected]ed511b8d2013-03-25 03:29:29985 pending_layer->PushPropertiesTo(active_layer.get());
986 active_layer->DidBecomeActive();
[email protected]28571b042013-03-14 07:59:15987 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]de44a152013-01-08 15:28:46988
[email protected]28571b042013-03-14 07:59:15989 // Test destructor.
skyostil3976a3f2014-09-04 22:07:23990 EXPECT_CALL(
991 test_data_.mock_callback_,
dyencc16ed4d2015-11-03 20:03:04992 ReleaseImpl(test_data_.mailbox_name1_, test_data_.sync_token1_, false, _))
[email protected]28571b042013-03-14 07:59:15993 .Times(1);
[email protected]9260757f2013-09-17 01:24:16994 pending_layer->SetTextureMailbox(
995 test_data_.mailbox1_,
skyostil3976a3f2014-09-04 22:07:23996 SingleReleaseCallbackImpl::Create(test_data_.release_mailbox1_impl_));
[email protected]de44a152013-01-08 15:28:46997}
998
[email protected]28571b042013-03-14 07:59:15999TEST_F(TextureLayerImplWithMailboxTest,
1000 TestDestructorCallbackOnCreatedResource) {
1001 scoped_ptr<TextureLayerImpl> impl_layer;
[email protected]17e08432014-04-10 00:41:111002 impl_layer = TextureLayerImpl::Create(host_impl_.active_tree(), 1);
[email protected]28571b042013-03-14 07:59:151003 ASSERT_TRUE(impl_layer);
[email protected]de44a152013-01-08 15:28:461004
[email protected]7ba3ca72013-04-11 06:37:251005 EXPECT_CALL(test_data_.mock_callback_,
skyostil3976a3f2014-09-04 22:07:231006 ReleaseImpl(test_data_.mailbox_name1_, _, false, _)).Times(1);
[email protected]9260757f2013-09-17 01:24:161007 impl_layer->SetTextureMailbox(
1008 test_data_.mailbox1_,
skyostil3976a3f2014-09-04 22:07:231009 SingleReleaseCallbackImpl::Create(test_data_.release_mailbox1_impl_));
[email protected]ffbb2212013-06-02 23:47:591010 impl_layer->DidBecomeActive();
1011 EXPECT_TRUE(impl_layer->WillDraw(
1012 DRAW_MODE_HARDWARE, host_impl_.active_tree()->resource_provider()));
[email protected]28571b042013-03-14 07:59:151013 impl_layer->DidDraw(host_impl_.active_tree()->resource_provider());
danakj968153f32014-10-15 22:52:161014 impl_layer->SetTextureMailbox(TextureMailbox(), nullptr);
[email protected]de44a152013-01-08 15:28:461015}
1016
[email protected]28571b042013-03-14 07:59:151017TEST_F(TextureLayerImplWithMailboxTest, TestCallbackOnInUseResource) {
1018 ResourceProvider* provider = host_impl_.active_tree()->resource_provider();
jbaumanbbd425e2015-05-19 00:33:351019 ResourceId id = provider->CreateResourceFromTextureMailbox(
skyostil3976a3f2014-09-04 22:07:231020 test_data_.mailbox1_,
1021 SingleReleaseCallbackImpl::Create(test_data_.release_mailbox1_impl_));
[email protected]28571b042013-03-14 07:59:151022 provider->AllocateForTesting(id);
[email protected]de44a152013-01-08 15:28:461023
[email protected]28571b042013-03-14 07:59:151024 // Transfer some resources to the parent.
1025 ResourceProvider::ResourceIdArray resource_ids_to_transfer;
1026 resource_ids_to_transfer.push_back(id);
1027 TransferableResourceArray list;
1028 provider->PrepareSendToParent(resource_ids_to_transfer, &list);
1029 EXPECT_TRUE(provider->InUseByConsumer(id));
skyostil3976a3f2014-09-04 22:07:231030 EXPECT_CALL(test_data_.mock_callback_, ReleaseImpl(_, _, _, _)).Times(0);
[email protected]28571b042013-03-14 07:59:151031 provider->DeleteResource(id);
1032 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]7ba3ca72013-04-11 06:37:251033 EXPECT_CALL(test_data_.mock_callback_,
skyostil3976a3f2014-09-04 22:07:231034 ReleaseImpl(test_data_.mailbox_name1_, _, false, _)).Times(1);
[email protected]e00bab022013-08-19 00:42:451035 ReturnedResourceArray returned;
1036 TransferableResource::ReturnResources(list, &returned);
1037 provider->ReceiveReturnsFromParent(returned);
[email protected]de44a152013-01-08 15:28:461038}
1039
[email protected]4bad8b62013-10-24 01:27:291040// Checks that TextureLayer::Update does not cause an extra commit when setting
1041// the texture mailbox.
1042class TextureLayerNoExtraCommitForMailboxTest
1043 : public LayerTreeTest,
1044 public TextureLayerClient {
1045 public:
[email protected]4bad8b62013-10-24 01:27:291046 // TextureLayerClient implementation.
dcheng716bedf2014-10-21 09:51:081047 bool PrepareTextureMailbox(
[email protected]df41e252014-02-03 23:39:501048 TextureMailbox* texture_mailbox,
[email protected]4bad8b62013-10-24 01:27:291049 scoped_ptr<SingleReleaseCallback>* release_callback,
mostynbf68776d82014-10-06 18:07:371050 bool use_shared_memory) override {
[email protected]cce34bd2013-12-02 23:24:451051 if (layer_tree_host()->source_frame_number() == 1) {
[email protected]9f35bd22014-06-03 15:25:461052 // Once this has been committed, the mailbox will be released.
[email protected]df41e252014-02-03 23:39:501053 *texture_mailbox = TextureMailbox();
[email protected]cce34bd2013-12-02 23:24:451054 return true;
1055 }
[email protected]4bad8b62013-10-24 01:27:291056
dyencc16ed4d2015-11-03 20:03:041057 *texture_mailbox =
1058 TextureMailbox(MailboxFromChar('1'), gpu::SyncToken(), GL_TEXTURE_2D);
[email protected]4bad8b62013-10-24 01:27:291059 *release_callback = SingleReleaseCallback::Create(
1060 base::Bind(&TextureLayerNoExtraCommitForMailboxTest::MailboxReleased,
1061 base::Unretained(this)));
[email protected]4bad8b62013-10-24 01:27:291062 return true;
1063 }
1064
dyencc16ed4d2015-11-03 20:03:041065 void MailboxReleased(const gpu::SyncToken& sync_token, bool lost_resource) {
[email protected]9f35bd22014-06-03 15:25:461066 // Source frame number during callback is the same as the source frame
1067 // on which it was released.
1068 EXPECT_EQ(1, layer_tree_host()->source_frame_number());
[email protected]cce34bd2013-12-02 23:24:451069 EndTest();
[email protected]4bad8b62013-10-24 01:27:291070 }
1071
dcheng716bedf2014-10-21 09:51:081072 void SetupTree() override {
loysoa6edaaff2015-05-25 03:26:441073 scoped_refptr<Layer> root = Layer::Create(layer_settings());
[email protected]4bad8b62013-10-24 01:27:291074 root->SetBounds(gfx::Size(10, 10));
[email protected]4bad8b62013-10-24 01:27:291075 root->SetIsDrawable(true);
1076
loysoa6edaaff2015-05-25 03:26:441077 texture_layer_ = TextureLayer::CreateForMailbox(layer_settings(), this);
[email protected]4bad8b62013-10-24 01:27:291078 texture_layer_->SetBounds(gfx::Size(10, 10));
[email protected]4bad8b62013-10-24 01:27:291079 texture_layer_->SetIsDrawable(true);
[email protected]0d7fb302014-01-23 21:30:471080 root->AddChild(texture_layer_);
[email protected]4bad8b62013-10-24 01:27:291081
1082 layer_tree_host()->SetRootLayer(root);
1083 LayerTreeTest::SetupTree();
1084 }
1085
dcheng716bedf2014-10-21 09:51:081086 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
[email protected]4bad8b62013-10-24 01:27:291087
dcheng716bedf2014-10-21 09:51:081088 void DidCommitAndDrawFrame() override {
[email protected]4bad8b62013-10-24 01:27:291089 switch (layer_tree_host()->source_frame_number()) {
1090 case 1:
[email protected]4ea293f72014-08-13 03:03:171091 EXPECT_FALSE(proxy()->MainFrameWillHappenForTesting());
[email protected]cce34bd2013-12-02 23:24:451092 // Invalidate the texture layer to clear the mailbox before
1093 // ending the test.
1094 texture_layer_->SetNeedsDisplay();
1095 break;
1096 case 2:
[email protected]4bad8b62013-10-24 01:27:291097 break;
1098 default:
1099 NOTREACHED();
1100 break;
1101 }
1102 }
1103
dcheng716bedf2014-10-21 09:51:081104 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override {
[email protected]cce34bd2013-12-02 23:24:451105 ASSERT_TRUE(result);
1106 DelegatedFrameData* delegated_frame_data =
1107 output_surface()->last_sent_frame().delegated_frame_data.get();
1108 if (!delegated_frame_data)
1109 return;
1110
1111 // Return all resources immediately.
1112 TransferableResourceArray resources_to_return =
1113 output_surface()->resources_held_by_parent();
1114
1115 CompositorFrameAck ack;
1116 for (size_t i = 0; i < resources_to_return.size(); ++i)
1117 output_surface()->ReturnResource(resources_to_return[i].id, &ack);
1118 host_impl->ReclaimResources(&ack);
[email protected]cce34bd2013-12-02 23:24:451119 }
1120
dcheng716bedf2014-10-21 09:51:081121 void AfterTest() override {}
[email protected]4bad8b62013-10-24 01:27:291122
1123 private:
[email protected]4bad8b62013-10-24 01:27:291124 scoped_refptr<TextureLayer> texture_layer_;
[email protected]4bad8b62013-10-24 01:27:291125};
1126
[email protected]cce34bd2013-12-02 23:24:451127SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerNoExtraCommitForMailboxTest);
[email protected]4bad8b62013-10-24 01:27:291128
[email protected]b04264f92013-09-13 23:37:291129// Checks that changing a mailbox in the client for a TextureLayer that's
1130// invisible correctly works and uses the new mailbox as soon as the layer
1131// becomes visible (and returns the old one).
1132class TextureLayerChangeInvisibleMailboxTest
1133 : public LayerTreeTest,
1134 public TextureLayerClient {
1135 public:
1136 TextureLayerChangeInvisibleMailboxTest()
1137 : mailbox_changed_(true),
1138 mailbox_returned_(0),
1139 prepare_called_(0),
1140 commit_count_(0) {
1141 mailbox_ = MakeMailbox('1');
1142 }
1143
1144 // TextureLayerClient implementation.
dcheng716bedf2014-10-21 09:51:081145 bool PrepareTextureMailbox(
[email protected]e51444a2013-12-10 23:05:011146 TextureMailbox* mailbox,
[email protected]9260757f2013-09-17 01:24:161147 scoped_ptr<SingleReleaseCallback>* release_callback,
mostynbf68776d82014-10-06 18:07:371148 bool use_shared_memory) override {
[email protected]b04264f92013-09-13 23:37:291149 ++prepare_called_;
1150 if (!mailbox_changed_)
1151 return false;
1152 *mailbox = mailbox_;
[email protected]9260757f2013-09-17 01:24:161153 *release_callback = SingleReleaseCallback::Create(
1154 base::Bind(&TextureLayerChangeInvisibleMailboxTest::MailboxReleased,
1155 base::Unretained(this)));
[email protected]b04264f92013-09-13 23:37:291156 return true;
1157 }
1158
1159 TextureMailbox MakeMailbox(char name) {
dyencc16ed4d2015-11-03 20:03:041160 return TextureMailbox(MailboxFromChar(name), gpu::SyncToken(),
1161 GL_TEXTURE_2D);
[email protected]b04264f92013-09-13 23:37:291162 }
1163
dyencc16ed4d2015-11-03 20:03:041164 void MailboxReleased(const gpu::SyncToken& sync_token, bool lost_resource) {
[email protected]b04264f92013-09-13 23:37:291165 ++mailbox_returned_;
1166 }
1167
dcheng716bedf2014-10-21 09:51:081168 void SetupTree() override {
loysoa6edaaff2015-05-25 03:26:441169 scoped_refptr<Layer> root = Layer::Create(layer_settings());
[email protected]b04264f92013-09-13 23:37:291170 root->SetBounds(gfx::Size(10, 10));
[email protected]b04264f92013-09-13 23:37:291171 root->SetIsDrawable(true);
1172
loysoa6edaaff2015-05-25 03:26:441173 solid_layer_ = SolidColorLayer::Create(layer_settings());
[email protected]b04264f92013-09-13 23:37:291174 solid_layer_->SetBounds(gfx::Size(10, 10));
1175 solid_layer_->SetIsDrawable(true);
1176 solid_layer_->SetBackgroundColor(SK_ColorWHITE);
1177 root->AddChild(solid_layer_);
1178
loysoa6edaaff2015-05-25 03:26:441179 parent_layer_ = Layer::Create(layer_settings());
[email protected]b04264f92013-09-13 23:37:291180 parent_layer_->SetBounds(gfx::Size(10, 10));
1181 parent_layer_->SetIsDrawable(true);
1182 root->AddChild(parent_layer_);
1183
loysoa6edaaff2015-05-25 03:26:441184 texture_layer_ = TextureLayer::CreateForMailbox(layer_settings(), this);
[email protected]b04264f92013-09-13 23:37:291185 texture_layer_->SetBounds(gfx::Size(10, 10));
[email protected]b04264f92013-09-13 23:37:291186 texture_layer_->SetIsDrawable(true);
1187 parent_layer_->AddChild(texture_layer_);
1188
1189 layer_tree_host()->SetRootLayer(root);
1190 LayerTreeTest::SetupTree();
1191 }
1192
dcheng716bedf2014-10-21 09:51:081193 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
[email protected]b04264f92013-09-13 23:37:291194
dcheng716bedf2014-10-21 09:51:081195 void DidCommitAndDrawFrame() override {
[email protected]b04264f92013-09-13 23:37:291196 ++commit_count_;
1197 switch (commit_count_) {
1198 case 1:
1199 // We should have updated the layer, committing the texture.
1200 EXPECT_EQ(1, prepare_called_);
1201 // Make layer invisible.
1202 parent_layer_->SetOpacity(0.f);
1203 break;
1204 case 2:
1205 // Layer shouldn't have been updated.
1206 EXPECT_EQ(1, prepare_called_);
1207 // Change the texture.
1208 mailbox_ = MakeMailbox('2');
1209 mailbox_changed_ = true;
1210 texture_layer_->SetNeedsDisplay();
1211 // Force a change to make sure we draw a frame.
1212 solid_layer_->SetBackgroundColor(SK_ColorGRAY);
1213 break;
1214 case 3:
1215 // Layer shouldn't have been updated.
1216 EXPECT_EQ(1, prepare_called_);
1217 // So the old mailbox isn't returned yet.
1218 EXPECT_EQ(0, mailbox_returned_);
1219 // Make layer visible again.
1220 parent_layer_->SetOpacity(1.f);
1221 break;
1222 case 4:
1223 // Layer should have been updated.
1224 EXPECT_EQ(2, prepare_called_);
1225 // So the old mailbox should have been returned already.
1226 EXPECT_EQ(1, mailbox_returned_);
1227 texture_layer_->ClearClient();
1228 break;
1229 case 5:
1230 EXPECT_EQ(2, mailbox_returned_);
1231 EndTest();
1232 break;
1233 default:
1234 NOTREACHED();
1235 break;
1236 }
1237 }
1238
dcheng716bedf2014-10-21 09:51:081239 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override {
[email protected]b04264f92013-09-13 23:37:291240 ASSERT_TRUE(result);
1241 DelegatedFrameData* delegated_frame_data =
1242 output_surface()->last_sent_frame().delegated_frame_data.get();
1243 if (!delegated_frame_data)
1244 return;
1245
1246 // Return all resources immediately.
1247 TransferableResourceArray resources_to_return =
1248 output_surface()->resources_held_by_parent();
1249
1250 CompositorFrameAck ack;
1251 for (size_t i = 0; i < resources_to_return.size(); ++i)
1252 output_surface()->ReturnResource(resources_to_return[i].id, &ack);
[email protected]a7335e0b2013-09-18 09:34:511253 host_impl->ReclaimResources(&ack);
[email protected]b04264f92013-09-13 23:37:291254 }
1255
dcheng716bedf2014-10-21 09:51:081256 void AfterTest() override {}
[email protected]b04264f92013-09-13 23:37:291257
1258 private:
1259 scoped_refptr<SolidColorLayer> solid_layer_;
1260 scoped_refptr<Layer> parent_layer_;
1261 scoped_refptr<TextureLayer> texture_layer_;
1262
1263 // Used on the main thread.
1264 bool mailbox_changed_;
1265 TextureMailbox mailbox_;
1266 int mailbox_returned_;
1267 int prepare_called_;
1268 int commit_count_;
1269};
1270
1271SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerChangeInvisibleMailboxTest);
1272
[email protected]0d7fb302014-01-23 21:30:471273// Test that TextureLayerImpl::ReleaseResources can be called which releases
1274// the mailbox back to TextureLayerClient.
1275class TextureLayerReleaseResourcesBase
1276 : public LayerTreeTest,
1277 public TextureLayerClient {
1278 public:
1279 // TextureLayerClient implementation.
dcheng716bedf2014-10-21 09:51:081280 bool PrepareTextureMailbox(
[email protected]0d7fb302014-01-23 21:30:471281 TextureMailbox* mailbox,
1282 scoped_ptr<SingleReleaseCallback>* release_callback,
mostynbf68776d82014-10-06 18:07:371283 bool use_shared_memory) override {
dyencc16ed4d2015-11-03 20:03:041284 *mailbox =
1285 TextureMailbox(MailboxFromChar('1'), gpu::SyncToken(), GL_TEXTURE_2D);
[email protected]0d7fb302014-01-23 21:30:471286 *release_callback = SingleReleaseCallback::Create(
1287 base::Bind(&TextureLayerReleaseResourcesBase::MailboxReleased,
1288 base::Unretained(this)));
1289 return true;
1290 }
1291
dyencc16ed4d2015-11-03 20:03:041292 void MailboxReleased(const gpu::SyncToken& sync_token, bool lost_resource) {
[email protected]0d7fb302014-01-23 21:30:471293 mailbox_released_ = true;
1294 }
1295
dcheng716bedf2014-10-21 09:51:081296 void SetupTree() override {
[email protected]0d7fb302014-01-23 21:30:471297 LayerTreeTest::SetupTree();
1298
1299 scoped_refptr<TextureLayer> texture_layer =
loysoa6edaaff2015-05-25 03:26:441300 TextureLayer::CreateForMailbox(layer_settings(), this);
[email protected]0d7fb302014-01-23 21:30:471301 texture_layer->SetBounds(gfx::Size(10, 10));
[email protected]0d7fb302014-01-23 21:30:471302 texture_layer->SetIsDrawable(true);
1303
1304 layer_tree_host()->root_layer()->AddChild(texture_layer);
1305 }
1306
dcheng716bedf2014-10-21 09:51:081307 void BeginTest() override {
[email protected]0d7fb302014-01-23 21:30:471308 mailbox_released_ = false;
1309 PostSetNeedsCommitToMainThread();
1310 }
1311
dcheng716bedf2014-10-21 09:51:081312 void DidCommitAndDrawFrame() override { EndTest(); }
[email protected]0d7fb302014-01-23 21:30:471313
dcheng716bedf2014-10-21 09:51:081314 void AfterTest() override { EXPECT_TRUE(mailbox_released_); }
[email protected]0d7fb302014-01-23 21:30:471315
1316 private:
1317 bool mailbox_released_;
1318};
1319
1320class TextureLayerReleaseResourcesAfterCommit
1321 : public TextureLayerReleaseResourcesBase {
1322 public:
dcheng716bedf2014-10-21 09:51:081323 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
kulkarni.a4015690f12014-10-10 13:50:061324 LayerTreeImpl* tree = nullptr;
danakj009cdfdf2015-02-17 22:35:141325 tree = host_impl->sync_tree();
[email protected]0d7fb302014-01-23 21:30:471326 tree->root_layer()->children()[0]->ReleaseResources();
1327 }
1328};
1329
1330SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerReleaseResourcesAfterCommit);
1331
1332class TextureLayerReleaseResourcesAfterActivate
1333 : public TextureLayerReleaseResourcesBase {
1334 public:
dcheng716bedf2014-10-21 09:51:081335 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
[email protected]0d7fb302014-01-23 21:30:471336 host_impl->active_tree()->root_layer()->children()[0]->ReleaseResources();
1337 }
1338};
1339
1340SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerReleaseResourcesAfterActivate);
1341
[email protected]9c2bd822013-07-26 12:30:171342class TextureLayerWithMailboxMainThreadDeleted : public LayerTreeTest {
1343 public:
dyencc16ed4d2015-11-03 20:03:041344 void ReleaseCallback(const gpu::SyncToken& sync_token, bool lost_resource) {
[email protected]9794fb32013-08-29 09:49:591345 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]9c2bd822013-07-26 12:30:171346 EXPECT_FALSE(lost_resource);
1347 ++callback_count_;
1348 EndTest();
1349 }
1350
1351 void SetMailbox(char mailbox_char) {
[email protected]9794fb32013-08-29 09:49:591352 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]9260757f2013-09-17 01:24:161353 scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create(
[email protected]9c2bd822013-07-26 12:30:171354 base::Bind(
1355 &TextureLayerWithMailboxMainThreadDeleted::ReleaseCallback,
1356 base::Unretained(this)));
dyencc16ed4d2015-11-03 20:03:041357 layer_->SetTextureMailbox(TextureMailbox(MailboxFromChar(mailbox_char),
1358 gpu::SyncToken(), GL_TEXTURE_2D),
danakja04855a2015-11-18 20:39:101359 std::move(callback));
[email protected]9c2bd822013-07-26 12:30:171360 }
1361
dcheng716bedf2014-10-21 09:51:081362 void SetupTree() override {
[email protected]9c2bd822013-07-26 12:30:171363 gfx::Size bounds(100, 100);
loysoa6edaaff2015-05-25 03:26:441364 root_ = Layer::Create(layer_settings());
[email protected]9c2bd822013-07-26 12:30:171365 root_->SetBounds(bounds);
1366
loysoa6edaaff2015-05-25 03:26:441367 layer_ = TextureLayer::CreateForMailbox(layer_settings(), nullptr);
[email protected]9c2bd822013-07-26 12:30:171368 layer_->SetIsDrawable(true);
[email protected]9c2bd822013-07-26 12:30:171369 layer_->SetBounds(bounds);
1370
1371 root_->AddChild(layer_);
1372 layer_tree_host()->SetRootLayer(root_);
1373 layer_tree_host()->SetViewportSize(bounds);
1374 }
1375
dcheng716bedf2014-10-21 09:51:081376 void BeginTest() override {
[email protected]9794fb32013-08-29 09:49:591377 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
1378
[email protected]9c2bd822013-07-26 12:30:171379 callback_count_ = 0;
1380
1381 // Set the mailbox on the main thread.
1382 SetMailbox('1');
1383 EXPECT_EQ(0, callback_count_);
1384
1385 PostSetNeedsCommitToMainThread();
1386 }
1387
dcheng716bedf2014-10-21 09:51:081388 void DidCommitAndDrawFrame() override {
[email protected]9c2bd822013-07-26 12:30:171389 switch (layer_tree_host()->source_frame_number()) {
1390 case 1:
1391 // Delete the TextureLayer on the main thread while the mailbox is in
1392 // the impl tree.
1393 layer_->RemoveFromParent();
kulkarni.a4015690f12014-10-10 13:50:061394 layer_ = nullptr;
[email protected]9c2bd822013-07-26 12:30:171395 break;
1396 }
1397 }
1398
dcheng716bedf2014-10-21 09:51:081399 void AfterTest() override { EXPECT_EQ(1, callback_count_); }
[email protected]9c2bd822013-07-26 12:30:171400
1401 private:
[email protected]9794fb32013-08-29 09:49:591402 base::ThreadChecker main_thread_;
[email protected]9c2bd822013-07-26 12:30:171403 int callback_count_;
1404 scoped_refptr<Layer> root_;
1405 scoped_refptr<TextureLayer> layer_;
1406};
1407
1408SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
1409 TextureLayerWithMailboxMainThreadDeleted);
1410
1411class TextureLayerWithMailboxImplThreadDeleted : public LayerTreeTest {
1412 public:
dyencc16ed4d2015-11-03 20:03:041413 void ReleaseCallback(const gpu::SyncToken& sync_token, bool lost_resource) {
[email protected]9794fb32013-08-29 09:49:591414 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]9c2bd822013-07-26 12:30:171415 EXPECT_FALSE(lost_resource);
1416 ++callback_count_;
1417 EndTest();
1418 }
1419
1420 void SetMailbox(char mailbox_char) {
[email protected]9794fb32013-08-29 09:49:591421 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]9260757f2013-09-17 01:24:161422 scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create(
[email protected]9c2bd822013-07-26 12:30:171423 base::Bind(
1424 &TextureLayerWithMailboxImplThreadDeleted::ReleaseCallback,
1425 base::Unretained(this)));
dyencc16ed4d2015-11-03 20:03:041426 layer_->SetTextureMailbox(TextureMailbox(MailboxFromChar(mailbox_char),
1427 gpu::SyncToken(), GL_TEXTURE_2D),
danakja04855a2015-11-18 20:39:101428 std::move(callback));
[email protected]9c2bd822013-07-26 12:30:171429 }
1430
dcheng716bedf2014-10-21 09:51:081431 void SetupTree() override {
[email protected]9c2bd822013-07-26 12:30:171432 gfx::Size bounds(100, 100);
loysoa6edaaff2015-05-25 03:26:441433 root_ = Layer::Create(layer_settings());
[email protected]9c2bd822013-07-26 12:30:171434 root_->SetBounds(bounds);
1435
loysoa6edaaff2015-05-25 03:26:441436 layer_ = TextureLayer::CreateForMailbox(layer_settings(), nullptr);
[email protected]9c2bd822013-07-26 12:30:171437 layer_->SetIsDrawable(true);
[email protected]9c2bd822013-07-26 12:30:171438 layer_->SetBounds(bounds);
1439
1440 root_->AddChild(layer_);
1441 layer_tree_host()->SetRootLayer(root_);
1442 layer_tree_host()->SetViewportSize(bounds);
1443 }
1444
dcheng716bedf2014-10-21 09:51:081445 void BeginTest() override {
[email protected]9794fb32013-08-29 09:49:591446 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
1447
[email protected]9c2bd822013-07-26 12:30:171448 callback_count_ = 0;
1449
1450 // Set the mailbox on the main thread.
1451 SetMailbox('1');
1452 EXPECT_EQ(0, callback_count_);
1453
1454 PostSetNeedsCommitToMainThread();
1455 }
1456
dcheng716bedf2014-10-21 09:51:081457 void DidCommitAndDrawFrame() override {
[email protected]9c2bd822013-07-26 12:30:171458 switch (layer_tree_host()->source_frame_number()) {
1459 case 1:
1460 // Remove the TextureLayer on the main thread while the mailbox is in
1461 // the impl tree, but don't delete the TextureLayer until after the impl
1462 // tree side is deleted.
1463 layer_->RemoveFromParent();
1464 break;
1465 case 2:
kulkarni.a4015690f12014-10-10 13:50:061466 layer_ = nullptr;
[email protected]9c2bd822013-07-26 12:30:171467 break;
1468 }
1469 }
1470
dcheng716bedf2014-10-21 09:51:081471 void AfterTest() override { EXPECT_EQ(1, callback_count_); }
[email protected]9c2bd822013-07-26 12:30:171472
1473 private:
[email protected]9794fb32013-08-29 09:49:591474 base::ThreadChecker main_thread_;
[email protected]9c2bd822013-07-26 12:30:171475 int callback_count_;
1476 scoped_refptr<Layer> root_;
1477 scoped_refptr<TextureLayer> layer_;
1478};
1479
1480SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
1481 TextureLayerWithMailboxImplThreadDeleted);
1482
[email protected]ba565742012-11-10 09:29:481483} // namespace
1484} // namespace cc