blob: 2bf6a3328657ab74b91c139a66cfe394ab2427b1 [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"
danakj60bc3bc2016-04-09 00:24:4817#include "base/memory/ptr_util.h"
skyostil0fd1dad2015-04-13 20:11:4818#include "base/single_thread_task_runner.h"
danakj3c3973b2015-08-25 21:50:1819#include "base/synchronization/lock.h"
[email protected]9794fb32013-08-29 09:49:5920#include "base/synchronization/waitable_event.h"
[email protected]74b43cc2013-08-30 06:29:2721#include "base/threading/thread.h"
gab39cb4ed72016-05-11 17:45:1922#include "base/threading/thread_task_runner_handle.h"
[email protected]74b43cc2013-08-30 06:29:2723#include "base/time/time.h"
[email protected]b04264f92013-09-13 23:37:2924#include "cc/layers/solid_color_layer.h"
[email protected]97d519fb2013-03-29 02:27:5425#include "cc/layers/texture_layer_client.h"
[email protected]cc3cfaa2013-03-18 09:05:5226#include "cc/layers/texture_layer_impl.h"
[email protected]b04264f92013-09-13 23:37:2927#include "cc/output/compositor_frame_ack.h"
28#include "cc/output/context_provider.h"
[email protected]e00bab022013-08-19 00:42:4529#include "cc/resources/returned_resource.h"
khushalsagarb64b360d2015-10-21 19:25:1630#include "cc/test/fake_impl_task_runner_provider.h"
[email protected]101441ce2012-10-16 01:45:0331#include "cc/test/fake_layer_tree_host_client.h"
[email protected]586d51ed2012-12-07 20:31:4532#include "cc/test/fake_layer_tree_host_impl.h"
[email protected]199b715e2013-08-13 05:18:3433#include "cc/test/fake_output_surface.h"
[email protected]06d68d02013-04-19 18:46:2134#include "cc/test/layer_test_common.h"
[email protected]e216fef02013-03-20 22:56:1035#include "cc/test/layer_tree_test.h"
reveman34b7a1522015-03-23 20:27:4736#include "cc/test/test_task_graph_runner.h"
[email protected]c2610b9f2013-10-31 06:54:5937#include "cc/test/test_web_graphics_context_3d.h"
[email protected]9794fb32013-08-29 09:49:5938#include "cc/trees/blocking_task_runner.h"
[email protected]556fd292013-03-18 08:03:0439#include "cc/trees/layer_tree_host.h"
40#include "cc/trees/layer_tree_impl.h"
41#include "cc/trees/single_thread_proxy.h"
[email protected]0bf5a202013-07-10 14:50:5442#include "gpu/GLES2/gl2extchromium.h"
[email protected]7f0c53db2012-10-02 00:23:1843#include "testing/gmock/include/gmock/gmock.h"
44#include "testing/gtest/include/gtest/gtest.h"
[email protected]c0dd24c2012-08-30 23:25:2745
[email protected]c0dd24c2012-08-30 23:25:2746using ::testing::Mock;
47using ::testing::_;
48using ::testing::AtLeast;
49using ::testing::AnyNumber;
[email protected]d72d9e02014-04-03 18:40:0950using ::testing::InvokeWithoutArgs;
[email protected]c0dd24c2012-08-30 23:25:2751
[email protected]ba565742012-11-10 09:29:4852namespace cc {
[email protected]c0dd24c2012-08-30 23:25:2753namespace {
54
[email protected]e0a4d732014-02-15 00:23:2655gpu::Mailbox MailboxFromChar(char value) {
[email protected]df41e252014-02-03 23:39:5056 gpu::Mailbox mailbox;
[email protected]e0a4d732014-02-15 00:23:2657 memset(mailbox.name, value, sizeof(mailbox.name));
[email protected]df41e252014-02-03 23:39:5058 return mailbox;
59}
60
dyen398dd0142016-01-21 22:05:5661gpu::SyncToken SyncTokenFromUInt(uint32_t value) {
lukasza2573ce7d2016-02-16 19:17:2262 return gpu::SyncToken(gpu::CommandBufferNamespace::GPU_IO, 0,
63 gpu::CommandBufferId::FromUnsafeValue(0x123), value);
dyen398dd0142016-01-21 22:05:5664}
65
[email protected]408b5e22013-03-19 09:48:0966class MockLayerTreeHost : public LayerTreeHost {
[email protected]28571b042013-03-14 07:59:1567 public:
danakj60bc3bc2016-04-09 00:24:4868 static std::unique_ptr<MockLayerTreeHost> Create(
danakjcf610582015-06-16 22:48:5669 FakeLayerTreeHostClient* client,
70 TaskGraphRunner* task_graph_runner) {
sadrul6780f3da2015-05-11 17:01:5271 LayerTreeHost::InitParams params;
72 params.client = client;
danakjcf610582015-06-16 22:48:5673 params.task_graph_runner = task_graph_runner;
sadrul6780f3da2015-05-11 17:01:5274 LayerTreeSettings settings;
75 params.settings = &settings;
danakj60bc3bc2016-04-09 00:24:4876 return base::WrapUnique(new MockLayerTreeHost(client, &params));
[email protected]28571b042013-03-14 07:59:1577 }
[email protected]c0dd24c2012-08-30 23:25:2778
[email protected]28571b042013-03-14 07:59:1579 MOCK_METHOD0(SetNeedsCommit, void());
[email protected]3519b872013-07-30 07:17:5080 MOCK_METHOD0(SetNeedsUpdateLayers, void());
[email protected]aeeb3372013-11-05 14:05:5481 MOCK_METHOD0(StartRateLimiter, void());
82 MOCK_METHOD0(StopRateLimiter, void());
sadrul6780f3da2015-05-11 17:01:5283
84 private:
85 MockLayerTreeHost(FakeLayerTreeHostClient* client,
86 LayerTreeHost::InitParams* params)
khushalsagare0a38d42016-01-29 01:15:0687 : LayerTreeHost(params, CompositorMode::SINGLE_THREADED) {
sadrul6780f3da2015-05-11 17:01:5288 InitializeSingleThreaded(client, base::ThreadTaskRunnerHandle::Get(),
89 nullptr);
90 }
[email protected]c0dd24c2012-08-30 23:25:2791};
92
[email protected]d72d9e02014-04-03 18:40:0993class FakeTextureLayerClient : public TextureLayerClient {
94 public:
[email protected]17e08432014-04-10 00:41:1195 FakeTextureLayerClient() : mailbox_changed_(true) {}
[email protected]d72d9e02014-04-03 18:40:0996
dcheng716bedf2014-10-21 09:51:0897 bool PrepareTextureMailbox(
[email protected]d72d9e02014-04-03 18:40:0998 TextureMailbox* mailbox,
danakj60bc3bc2016-04-09 00:24:4899 std::unique_ptr<SingleReleaseCallback>* release_callback,
mostynbf68776d82014-10-06 18:07:37100 bool use_shared_memory) override {
[email protected]d72d9e02014-04-03 18:40:09101 if (!mailbox_changed_)
102 return false;
103
104 *mailbox = mailbox_;
danakja04855a2015-11-18 20:39:10105 *release_callback = std::move(release_callback_);
[email protected]d72d9e02014-04-03 18:40:09106 mailbox_changed_ = false;
107 return true;
108 }
109
[email protected]d72d9e02014-04-03 18:40:09110 void set_mailbox(const TextureMailbox& mailbox,
danakj60bc3bc2016-04-09 00:24:48111 std::unique_ptr<SingleReleaseCallback> release_callback) {
[email protected]d72d9e02014-04-03 18:40:09112 mailbox_ = mailbox;
danakja04855a2015-11-18 20:39:10113 release_callback_ = std::move(release_callback);
[email protected]d72d9e02014-04-03 18:40:09114 mailbox_changed_ = true;
115 }
116
117 private:
[email protected]d72d9e02014-04-03 18:40:09118 TextureMailbox mailbox_;
danakj60bc3bc2016-04-09 00:24:48119 std::unique_ptr<SingleReleaseCallback> release_callback_;
[email protected]d72d9e02014-04-03 18:40:09120 bool mailbox_changed_;
121 DISALLOW_COPY_AND_ASSIGN(FakeTextureLayerClient);
122};
123
124class MockMailboxCallback {
125 public:
126 MOCK_METHOD3(Release,
127 void(const gpu::Mailbox& mailbox,
dyencc16ed4d2015-11-03 20:03:04128 const gpu::SyncToken& sync_token,
[email protected]d72d9e02014-04-03 18:40:09129 bool lost_resource));
130 MOCK_METHOD3(Release2,
jbauman9015c8b2014-12-11 00:49:37131 void(SharedBitmap* shared_bitmap,
dyencc16ed4d2015-11-03 20:03:04132 const gpu::SyncToken& sync_token,
[email protected]d72d9e02014-04-03 18:40:09133 bool lost_resource));
skyostil3976a3f2014-09-04 22:07:23134 MOCK_METHOD4(ReleaseImpl,
135 void(const gpu::Mailbox& mailbox,
dyencc16ed4d2015-11-03 20:03:04136 const gpu::SyncToken& sync_token,
skyostil3976a3f2014-09-04 22:07:23137 bool lost_resource,
138 BlockingTaskRunner* main_thread_task_runner));
139 MOCK_METHOD4(ReleaseImpl2,
jbauman9015c8b2014-12-11 00:49:37140 void(SharedBitmap* shared_bitmap,
dyencc16ed4d2015-11-03 20:03:04141 const gpu::SyncToken& sync_token,
skyostil3976a3f2014-09-04 22:07:23142 bool lost_resource,
143 BlockingTaskRunner* main_thread_task_runner));
[email protected]d72d9e02014-04-03 18:40:09144};
145
146struct CommonMailboxObjects {
jbauman9015c8b2014-12-11 00:49:37147 explicit CommonMailboxObjects(SharedBitmapManager* manager)
[email protected]d72d9e02014-04-03 18:40:09148 : mailbox_name1_(MailboxFromChar('1')),
149 mailbox_name2_(MailboxFromChar('2')),
lukasza2573ce7d2016-02-16 19:17:22150 sync_token1_(gpu::CommandBufferNamespace::GPU_IO,
151 123,
152 gpu::CommandBufferId::FromUnsafeValue(0x234),
153 1),
154 sync_token2_(gpu::CommandBufferNamespace::GPU_IO,
155 123,
156 gpu::CommandBufferId::FromUnsafeValue(0x234),
157 2) {
[email protected]d72d9e02014-04-03 18:40:09158 release_mailbox1_ = base::Bind(&MockMailboxCallback::Release,
159 base::Unretained(&mock_callback_),
160 mailbox_name1_);
161 release_mailbox2_ = base::Bind(&MockMailboxCallback::Release,
162 base::Unretained(&mock_callback_),
163 mailbox_name2_);
skyostil3976a3f2014-09-04 22:07:23164 release_mailbox1_impl_ = base::Bind(&MockMailboxCallback::ReleaseImpl,
165 base::Unretained(&mock_callback_),
166 mailbox_name1_);
167 release_mailbox2_impl_ = base::Bind(&MockMailboxCallback::ReleaseImpl,
168 base::Unretained(&mock_callback_),
169 mailbox_name2_);
avi02a4d172015-12-21 06:14:36170 const uint32_t arbitrary_target1 = GL_TEXTURE_2D;
171 const uint32_t arbitrary_target2 = GL_TEXTURE_EXTERNAL_OES;
dyencc16ed4d2015-11-03 20:03:04172 mailbox1_ = TextureMailbox(mailbox_name1_, sync_token1_, arbitrary_target1);
173 mailbox2_ = TextureMailbox(mailbox_name2_, sync_token2_, arbitrary_target2);
[email protected]d72d9e02014-04-03 18:40:09174 gfx::Size size(128, 128);
jbauman9015c8b2014-12-11 00:49:37175 shared_bitmap_ = manager->AllocateSharedBitmap(size);
176 DCHECK(shared_bitmap_);
177 release_mailbox3_ =
178 base::Bind(&MockMailboxCallback::Release2,
179 base::Unretained(&mock_callback_), shared_bitmap_.get());
180 release_mailbox3_impl_ =
181 base::Bind(&MockMailboxCallback::ReleaseImpl2,
182 base::Unretained(&mock_callback_), shared_bitmap_.get());
183 mailbox3_ = TextureMailbox(shared_bitmap_.get(), size);
[email protected]d72d9e02014-04-03 18:40:09184 }
185
186 gpu::Mailbox mailbox_name1_;
187 gpu::Mailbox mailbox_name2_;
188 MockMailboxCallback mock_callback_;
189 ReleaseCallback release_mailbox1_;
190 ReleaseCallback release_mailbox2_;
191 ReleaseCallback release_mailbox3_;
skyostil3976a3f2014-09-04 22:07:23192 ReleaseCallbackImpl release_mailbox1_impl_;
193 ReleaseCallbackImpl release_mailbox2_impl_;
194 ReleaseCallbackImpl release_mailbox3_impl_;
[email protected]d72d9e02014-04-03 18:40:09195 TextureMailbox mailbox1_;
196 TextureMailbox mailbox2_;
197 TextureMailbox mailbox3_;
dyencc16ed4d2015-11-03 20:03:04198 gpu::SyncToken sync_token1_;
199 gpu::SyncToken sync_token2_;
danakj60bc3bc2016-04-09 00:24:48200 std::unique_ptr<SharedBitmap> shared_bitmap_;
[email protected]d72d9e02014-04-03 18:40:09201};
202
[email protected]31d4df82013-07-18 10:17:22203class TextureLayerTest : public testing::Test {
204 public:
205 TextureLayerTest()
206 : fake_client_(
[email protected]4e2eb352014-03-20 17:25:45207 FakeLayerTreeHostClient(FakeLayerTreeHostClient::DIRECT_3D)),
revemand180dfc32015-09-24 00:19:43208 output_surface_(FakeOutputSurface::Create3d()),
khushalsagarb64b360d2015-10-21 19:25:16209 host_impl_(&task_runner_provider_,
210 &shared_bitmap_manager_,
211 &task_graph_runner_),
jbauman9015c8b2014-12-11 00:49:37212 test_data_(&shared_bitmap_manager_) {}
[email protected]31d4df82013-07-18 10:17:22213
214 protected:
dcheng93a52eb2014-12-23 02:14:23215 void SetUp() override {
danakjcf610582015-06-16 22:48:56216 layer_tree_host_ =
217 MockLayerTreeHost::Create(&fake_client_, &task_graph_runner_);
[email protected]d72d9e02014-04-03 18:40:09218 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
219 layer_tree_host_->SetViewportSize(gfx::Size(10, 10));
220 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
[email protected]31d4df82013-07-18 10:17:22221 }
222
dcheng93a52eb2014-12-23 02:14:23223 void TearDown() override {
[email protected]31d4df82013-07-18 10:17:22224 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
[email protected]31d4df82013-07-18 10:17:22225 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
226
kulkarni.a4015690f12014-10-10 13:50:06227 layer_tree_host_->SetRootLayer(nullptr);
danakjf446a072014-09-27 21:55:48228 layer_tree_host_ = nullptr;
[email protected]31d4df82013-07-18 10:17:22229 }
230
danakj60bc3bc2016-04-09 00:24:48231 std::unique_ptr<MockLayerTreeHost> layer_tree_host_;
khushalsagarb64b360d2015-10-21 19:25:16232 FakeImplTaskRunnerProvider task_runner_provider_;
[email protected]31d4df82013-07-18 10:17:22233 FakeLayerTreeHostClient fake_client_;
[email protected]4e2eb352014-03-20 17:25:45234 TestSharedBitmapManager shared_bitmap_manager_;
reveman34b7a1522015-03-23 20:27:47235 TestTaskGraphRunner task_graph_runner_;
danakj60bc3bc2016-04-09 00:24:48236 std::unique_ptr<OutputSurface> output_surface_;
[email protected]31d4df82013-07-18 10:17:22237 FakeLayerTreeHostImpl host_impl_;
jbauman9015c8b2014-12-11 00:49:37238 CommonMailboxObjects test_data_;
[email protected]31d4df82013-07-18 10:17:22239};
240
[email protected]31d4df82013-07-18 10:17:22241TEST_F(TextureLayerTest, CheckPropertyChangeCausesCorrectBehavior) {
kulkarni.a4015690f12014-10-10 13:50:06242 scoped_refptr<TextureLayer> test_layer =
loyso0940d412016-03-14 01:30:31243 TextureLayer::CreateForMailbox(nullptr);
[email protected]80d42bd2013-08-30 19:13:45244 EXPECT_SET_NEEDS_COMMIT(1, layer_tree_host_->SetRootLayer(test_layer));
[email protected]31d4df82013-07-18 10:17:22245
246 // Test properties that should call SetNeedsCommit. All properties need to
247 // be set to new values in order for SetNeedsCommit to be called.
248 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetFlipped(false));
jackhou10c9af42014-12-04 05:24:44249 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetNearestNeighbor(true));
[email protected]31d4df82013-07-18 10:17:22250 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetUV(
251 gfx::PointF(0.25f, 0.25f), gfx::PointF(0.75f, 0.75f)));
252 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetVertexOpacity(
253 0.5f, 0.5f, 0.5f, 0.5f));
254 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetPremultipliedAlpha(false));
255 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetBlendBackgroundColor(true));
[email protected]31d4df82013-07-18 10:17:22256}
257
[email protected]df41e252014-02-03 23:39:50258class TestMailboxHolder : public TextureLayer::TextureMailboxHolder {
[email protected]9794fb32013-08-29 09:49:59259 public:
[email protected]df41e252014-02-03 23:39:50260 using TextureLayer::TextureMailboxHolder::Create;
[email protected]9794fb32013-08-29 09:49:59261
262 protected:
dcheng716bedf2014-10-21 09:51:08263 ~TestMailboxHolder() override {}
[email protected]9794fb32013-08-29 09:49:59264};
265
[email protected]de44a152013-01-08 15:28:46266class TextureLayerWithMailboxTest : public TextureLayerTest {
[email protected]28571b042013-03-14 07:59:15267 protected:
dcheng93a52eb2014-12-23 02:14:23268 void TearDown() override {
[email protected]28571b042013-03-14 07:59:15269 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
dyencc16ed4d2015-11-03 20:03:04270 EXPECT_CALL(
271 test_data_.mock_callback_,
272 Release(test_data_.mailbox_name1_, test_data_.sync_token1_, false))
273 .Times(1);
[email protected]28571b042013-03-14 07:59:15274 TextureLayerTest::TearDown();
275 }
[email protected]de44a152013-01-08 15:28:46276};
277
[email protected]28571b042013-03-14 07:59:15278TEST_F(TextureLayerWithMailboxTest, ReplaceMailboxOnMainThreadBeforeCommit) {
kulkarni.a4015690f12014-10-10 13:50:06279 scoped_refptr<TextureLayer> test_layer =
loyso0940d412016-03-14 01:30:31280 TextureLayer::CreateForMailbox(nullptr);
[email protected]22898ed2013-06-01 04:52:30281 ASSERT_TRUE(test_layer.get());
[email protected]de44a152013-01-08 15:28:46282
[email protected]28571b042013-03-14 07:59:15283 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
284 layer_tree_host_->SetRootLayer(test_layer);
285 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
[email protected]de44a152013-01-08 15:28:46286
[email protected]28571b042013-03-14 07:59:15287 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
[email protected]9260757f2013-09-17 01:24:16288 test_layer->SetTextureMailbox(
289 test_data_.mailbox1_,
290 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
[email protected]28571b042013-03-14 07:59:15291 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
[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_name1_, test_data_.sync_token1_, false))
[email protected]28571b042013-03-14 07:59:15297 .Times(1);
[email protected]9260757f2013-09-17 01:24:16298 test_layer->SetTextureMailbox(
299 test_data_.mailbox2_,
300 SingleReleaseCallback::Create(test_data_.release_mailbox2_));
[email protected]28571b042013-03-14 07:59:15301 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
302 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]de44a152013-01-08 15:28:46303
[email protected]28571b042013-03-14 07:59:15304 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
dyencc16ed4d2015-11-03 20:03:04305 EXPECT_CALL(
306 test_data_.mock_callback_,
307 Release(test_data_.mailbox_name2_, test_data_.sync_token2_, false))
[email protected]28571b042013-03-14 07:59:15308 .Times(1);
danakj968153f32014-10-15 22:52:16309 test_layer->SetTextureMailbox(TextureMailbox(), nullptr);
[email protected]28571b042013-03-14 07:59:15310 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
311 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]de44a152013-01-08 15:28:46312
[email protected]80d42bd2013-08-30 19:13:45313 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
[email protected]9260757f2013-09-17 01:24:16314 test_layer->SetTextureMailbox(
315 test_data_.mailbox3_,
316 SingleReleaseCallback::Create(test_data_.release_mailbox3_));
[email protected]42f40a52013-06-08 04:38:51317 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
318 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
319
[email protected]42f40a52013-06-08 04:38:51320 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
321 EXPECT_CALL(test_data_.mock_callback_,
dyencc16ed4d2015-11-03 20:03:04322 Release2(test_data_.shared_bitmap_.get(), _, false))
323 .Times(1);
danakj968153f32014-10-15 22:52:16324 test_layer->SetTextureMailbox(TextureMailbox(), nullptr);
[email protected]42f40a52013-06-08 04:38:51325 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
326 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
327
[email protected]28571b042013-03-14 07:59:15328 // Test destructor.
329 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]de44a152013-01-08 15:28:46333}
334
[email protected]9794fb32013-08-29 09:49:59335class TextureLayerMailboxHolderTest : public TextureLayerTest {
336 public:
337 TextureLayerMailboxHolderTest()
338 : main_thread_("MAIN") {
339 main_thread_.Start();
skyostil0fd1dad2015-04-13 20:11:48340 main_thread_.message_loop()->task_runner()->PostTask(
341 FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::InitializeOnMain,
342 base::Unretained(this)));
skyostil3976a3f2014-09-04 22:07:23343 Wait(main_thread_);
[email protected]9794fb32013-08-29 09:49:59344 }
345
346 void Wait(const base::Thread& thread) {
347 bool manual_reset = false;
348 bool initially_signaled = false;
349 base::WaitableEvent event(manual_reset, initially_signaled);
skyostil0fd1dad2015-04-13 20:11:48350 thread.message_loop()->task_runner()->PostTask(
[email protected]9794fb32013-08-29 09:49:59351 FROM_HERE,
352 base::Bind(&base::WaitableEvent::Signal, base::Unretained(&event)));
353 event.Wait();
354 }
355
356 void CreateMainRef() {
357 main_ref_ = TestMailboxHolder::Create(
[email protected]9260757f2013-09-17 01:24:16358 test_data_.mailbox1_,
danakja5a05ba02015-11-20 20:14:21359 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
[email protected]9794fb32013-08-29 09:49:59360 }
361
danakjf446a072014-09-27 21:55:48362 void ReleaseMainRef() { main_ref_ = nullptr; }
[email protected]9794fb32013-08-29 09:49:59363
danakj60bc3bc2016-04-09 00:24:48364 void CreateImplRef(std::unique_ptr<SingleReleaseCallbackImpl>* impl_ref) {
[email protected]9794fb32013-08-29 09:49:59365 *impl_ref = main_ref_->holder()->GetCallbackForImplThread();
366 }
367
368 void CapturePostTasksAndWait(base::WaitableEvent* begin_capture,
369 base::WaitableEvent* wait_for_capture,
370 base::WaitableEvent* stop_capture) {
371 begin_capture->Wait();
skyostil3976a3f2014-09-04 22:07:23372 BlockingTaskRunner::CapturePostTasks capture(
373 main_thread_task_runner_.get());
[email protected]9794fb32013-08-29 09:49:59374 wait_for_capture->Signal();
375 stop_capture->Wait();
376 }
377
378 protected:
skyostil3976a3f2014-09-04 22:07:23379 void InitializeOnMain() {
380 main_thread_task_runner_ =
skyostil0fd1dad2015-04-13 20:11:48381 BlockingTaskRunner::Create(main_thread_.task_runner());
skyostil3976a3f2014-09-04 22:07:23382 }
383
danakj60bc3bc2016-04-09 00:24:48384 std::unique_ptr<TestMailboxHolder::MainThreadReference> main_ref_;
[email protected]9794fb32013-08-29 09:49:59385 base::Thread main_thread_;
danakj60bc3bc2016-04-09 00:24:48386 std::unique_ptr<BlockingTaskRunner> main_thread_task_runner_;
[email protected]9794fb32013-08-29 09:49:59387};
388
389TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_BothReleaseThenMain) {
kulkarni.a4015690f12014-10-10 13:50:06390 scoped_refptr<TextureLayer> test_layer =
loyso0940d412016-03-14 01:30:31391 TextureLayer::CreateForMailbox(nullptr);
[email protected]9794fb32013-08-29 09:49:59392 ASSERT_TRUE(test_layer.get());
393
skyostil0fd1dad2015-04-13 20:11:48394 main_thread_.message_loop()->task_runner()->PostTask(
395 FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::CreateMainRef,
396 base::Unretained(this)));
[email protected]9794fb32013-08-29 09:49:59397
398 Wait(main_thread_);
399
400 // The texture layer is attached to compositor1, and passes a reference to its
401 // impl tree.
danakj60bc3bc2016-04-09 00:24:48402 std::unique_ptr<SingleReleaseCallbackImpl> compositor1;
skyostil0fd1dad2015-04-13 20:11:48403 main_thread_.message_loop()->task_runner()->PostTask(
404 FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
405 base::Unretained(this), &compositor1));
[email protected]9794fb32013-08-29 09:49:59406
407 // Then the texture layer is removed and attached to compositor2, and passes a
408 // reference to its impl tree.
danakj60bc3bc2016-04-09 00:24:48409 std::unique_ptr<SingleReleaseCallbackImpl> compositor2;
skyostil0fd1dad2015-04-13 20:11:48410 main_thread_.message_loop()->task_runner()->PostTask(
411 FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
412 base::Unretained(this), &compositor2));
[email protected]9794fb32013-08-29 09:49:59413
414 Wait(main_thread_);
415 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
416
417 // The compositors both destroy their impl trees before the main thread layer
418 // is destroyed.
dyen398dd0142016-01-21 22:05:56419 compositor1->Run(SyncTokenFromUInt(100), false,
420 main_thread_task_runner_.get());
421 compositor2->Run(SyncTokenFromUInt(200), false,
422 main_thread_task_runner_.get());
[email protected]9794fb32013-08-29 09:49:59423
424 Wait(main_thread_);
425
426 EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0);
427 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
428
429 // The main thread ref is the last one, so the mailbox is released back to the
430 // embedder, with the last sync point provided by the impl trees.
431 EXPECT_CALL(test_data_.mock_callback_,
dyen398dd0142016-01-21 22:05:56432 Release(test_data_.mailbox_name1_, SyncTokenFromUInt(200), false))
dyencc16ed4d2015-11-03 20:03:04433 .Times(1);
[email protected]9794fb32013-08-29 09:49:59434
skyostil0fd1dad2015-04-13 20:11:48435 main_thread_.message_loop()->task_runner()->PostTask(
436 FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::ReleaseMainRef,
437 base::Unretained(this)));
[email protected]9794fb32013-08-29 09:49:59438 Wait(main_thread_);
439 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
440}
441
442TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_MainReleaseBetween) {
kulkarni.a4015690f12014-10-10 13:50:06443 scoped_refptr<TextureLayer> test_layer =
loyso0940d412016-03-14 01:30:31444 TextureLayer::CreateForMailbox(nullptr);
[email protected]9794fb32013-08-29 09:49:59445 ASSERT_TRUE(test_layer.get());
446
skyostil0fd1dad2015-04-13 20:11:48447 main_thread_.message_loop()->task_runner()->PostTask(
448 FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::CreateMainRef,
449 base::Unretained(this)));
[email protected]9794fb32013-08-29 09:49:59450
451 Wait(main_thread_);
452
453 // The texture layer is attached to compositor1, and passes a reference to its
454 // impl tree.
danakj60bc3bc2016-04-09 00:24:48455 std::unique_ptr<SingleReleaseCallbackImpl> compositor1;
skyostil0fd1dad2015-04-13 20:11:48456 main_thread_.message_loop()->task_runner()->PostTask(
457 FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
458 base::Unretained(this), &compositor1));
[email protected]9794fb32013-08-29 09:49:59459
460 // Then the texture layer is removed and attached to compositor2, and passes a
461 // reference to its impl tree.
danakj60bc3bc2016-04-09 00:24:48462 std::unique_ptr<SingleReleaseCallbackImpl> compositor2;
skyostil0fd1dad2015-04-13 20:11:48463 main_thread_.message_loop()->task_runner()->PostTask(
464 FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
465 base::Unretained(this), &compositor2));
[email protected]9794fb32013-08-29 09:49:59466
467 Wait(main_thread_);
468 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
469
470 // One compositor destroys their impl tree.
dyen398dd0142016-01-21 22:05:56471 compositor1->Run(SyncTokenFromUInt(100), false,
472 main_thread_task_runner_.get());
[email protected]9794fb32013-08-29 09:49:59473
474 // Then the main thread reference is destroyed.
skyostil0fd1dad2015-04-13 20:11:48475 main_thread_.message_loop()->task_runner()->PostTask(
476 FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::ReleaseMainRef,
477 base::Unretained(this)));
[email protected]9794fb32013-08-29 09:49:59478
479 Wait(main_thread_);
480
481 EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0);
482 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
483
484 // The second impl reference is destroyed last, causing the mailbox to be
485 // released back to the embedder with the last sync point from the impl tree.
486 EXPECT_CALL(test_data_.mock_callback_,
dyen398dd0142016-01-21 22:05:56487 Release(test_data_.mailbox_name1_, SyncTokenFromUInt(200), true))
dyencc16ed4d2015-11-03 20:03:04488 .Times(1);
[email protected]9794fb32013-08-29 09:49:59489
dyen398dd0142016-01-21 22:05:56490 compositor2->Run(SyncTokenFromUInt(200), true,
491 main_thread_task_runner_.get());
[email protected]9794fb32013-08-29 09:49:59492 Wait(main_thread_);
493 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
494}
495
496TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_MainReleasedFirst) {
kulkarni.a4015690f12014-10-10 13:50:06497 scoped_refptr<TextureLayer> test_layer =
loyso0940d412016-03-14 01:30:31498 TextureLayer::CreateForMailbox(nullptr);
[email protected]9794fb32013-08-29 09:49:59499 ASSERT_TRUE(test_layer.get());
500
skyostil0fd1dad2015-04-13 20:11:48501 main_thread_.message_loop()->task_runner()->PostTask(
502 FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::CreateMainRef,
503 base::Unretained(this)));
[email protected]9794fb32013-08-29 09:49:59504
505 Wait(main_thread_);
506
507 // The texture layer is attached to compositor1, and passes a reference to its
508 // impl tree.
danakj60bc3bc2016-04-09 00:24:48509 std::unique_ptr<SingleReleaseCallbackImpl> compositor1;
skyostil0fd1dad2015-04-13 20:11:48510 main_thread_.message_loop()->task_runner()->PostTask(
511 FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
512 base::Unretained(this), &compositor1));
[email protected]9794fb32013-08-29 09:49:59513
514 // Then the texture layer is removed and attached to compositor2, and passes a
515 // reference to its impl tree.
danakj60bc3bc2016-04-09 00:24:48516 std::unique_ptr<SingleReleaseCallbackImpl> compositor2;
skyostil0fd1dad2015-04-13 20:11:48517 main_thread_.message_loop()->task_runner()->PostTask(
518 FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
519 base::Unretained(this), &compositor2));
[email protected]9794fb32013-08-29 09:49:59520
521 Wait(main_thread_);
522 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
523
524 // The main thread reference is destroyed first.
skyostil0fd1dad2015-04-13 20:11:48525 main_thread_.message_loop()->task_runner()->PostTask(
526 FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::ReleaseMainRef,
527 base::Unretained(this)));
[email protected]9794fb32013-08-29 09:49:59528
529 // One compositor destroys their impl tree.
dyen398dd0142016-01-21 22:05:56530 compositor2->Run(SyncTokenFromUInt(200), false,
531 main_thread_task_runner_.get());
[email protected]9794fb32013-08-29 09:49:59532
533 Wait(main_thread_);
534
535 EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0);
536 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
537
538 // The second impl reference is destroyed last, causing the mailbox to be
539 // released back to the embedder with the last sync point from the impl tree.
540 EXPECT_CALL(test_data_.mock_callback_,
dyen398dd0142016-01-21 22:05:56541 Release(test_data_.mailbox_name1_, SyncTokenFromUInt(100), true))
dyencc16ed4d2015-11-03 20:03:04542 .Times(1);
[email protected]9794fb32013-08-29 09:49:59543
dyen398dd0142016-01-21 22:05:56544 compositor1->Run(SyncTokenFromUInt(100), true,
545 main_thread_task_runner_.get());
[email protected]9794fb32013-08-29 09:49:59546 Wait(main_thread_);
547 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
548}
549
550TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_SecondImplRefShortcut) {
kulkarni.a4015690f12014-10-10 13:50:06551 scoped_refptr<TextureLayer> test_layer =
loyso0940d412016-03-14 01:30:31552 TextureLayer::CreateForMailbox(nullptr);
[email protected]9794fb32013-08-29 09:49:59553 ASSERT_TRUE(test_layer.get());
554
skyostil0fd1dad2015-04-13 20:11:48555 main_thread_.message_loop()->task_runner()->PostTask(
556 FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::CreateMainRef,
557 base::Unretained(this)));
[email protected]9794fb32013-08-29 09:49:59558
559 Wait(main_thread_);
560
561 // The texture layer is attached to compositor1, and passes a reference to its
562 // impl tree.
danakj60bc3bc2016-04-09 00:24:48563 std::unique_ptr<SingleReleaseCallbackImpl> compositor1;
skyostil0fd1dad2015-04-13 20:11:48564 main_thread_.message_loop()->task_runner()->PostTask(
565 FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
566 base::Unretained(this), &compositor1));
[email protected]9794fb32013-08-29 09:49:59567
568 // Then the texture layer is removed and attached to compositor2, and passes a
569 // reference to its impl tree.
danakj60bc3bc2016-04-09 00:24:48570 std::unique_ptr<SingleReleaseCallbackImpl> compositor2;
skyostil0fd1dad2015-04-13 20:11:48571 main_thread_.message_loop()->task_runner()->PostTask(
572 FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
573 base::Unretained(this), &compositor2));
[email protected]9794fb32013-08-29 09:49:59574
575 Wait(main_thread_);
576 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
577
578 // The main thread reference is destroyed first.
skyostil0fd1dad2015-04-13 20:11:48579 main_thread_.message_loop()->task_runner()->PostTask(
580 FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::ReleaseMainRef,
581 base::Unretained(this)));
[email protected]9794fb32013-08-29 09:49:59582
583 EXPECT_CALL(test_data_.mock_callback_,
dyen398dd0142016-01-21 22:05:56584 Release(test_data_.mailbox_name1_, SyncTokenFromUInt(200), true))
dyencc16ed4d2015-11-03 20:03:04585 .Times(1);
[email protected]9794fb32013-08-29 09:49:59586
587 bool manual_reset = false;
588 bool initially_signaled = false;
589 base::WaitableEvent begin_capture(manual_reset, initially_signaled);
590 base::WaitableEvent wait_for_capture(manual_reset, initially_signaled);
591 base::WaitableEvent stop_capture(manual_reset, initially_signaled);
592
593 // Post a task to start capturing tasks on the main thread. This will block
594 // the main thread until we signal the |stop_capture| event.
skyostil0fd1dad2015-04-13 20:11:48595 main_thread_.message_loop()->task_runner()->PostTask(
[email protected]9794fb32013-08-29 09:49:59596 FROM_HERE,
597 base::Bind(&TextureLayerMailboxHolderTest::CapturePostTasksAndWait,
skyostil0fd1dad2015-04-13 20:11:48598 base::Unretained(this), &begin_capture, &wait_for_capture,
[email protected]9794fb32013-08-29 09:49:59599 &stop_capture));
600
601 // Before the main thread capturing starts, one compositor destroys their
602 // impl reference. Since capturing did not start, this gets post-tasked to
603 // the main thread.
dyen398dd0142016-01-21 22:05:56604 compositor1->Run(SyncTokenFromUInt(100), false,
605 main_thread_task_runner_.get());
[email protected]9794fb32013-08-29 09:49:59606
607 // Start capturing on the main thread.
608 begin_capture.Signal();
609 wait_for_capture.Wait();
610
611 // Meanwhile, the second compositor released its impl reference, but this task
612 // gets shortcutted directly to the main thread. This means the reference is
613 // released before compositor1, whose reference will be released later when
614 // the post-task is serviced. But since it was destroyed _on the impl thread_
615 // last, its sync point values should be used.
dyen398dd0142016-01-21 22:05:56616 compositor2->Run(SyncTokenFromUInt(200), true,
617 main_thread_task_runner_.get());
[email protected]9794fb32013-08-29 09:49:59618
619 stop_capture.Signal();
620 Wait(main_thread_);
621
622 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
623}
624
[email protected]e216fef02013-03-20 22:56:10625class TextureLayerImplWithMailboxThreadedCallback : public LayerTreeTest {
[email protected]28571b042013-03-14 07:59:15626 public:
627 TextureLayerImplWithMailboxThreadedCallback()
628 : callback_count_(0),
629 commit_count_(0) {}
630
631 // Make sure callback is received on main and doesn't block the impl thread.
dyencc16ed4d2015-11-03 20:03:04632 void ReleaseCallback(const gpu::SyncToken& sync_token, bool lost_resource) {
[email protected]9794fb32013-08-29 09:49:59633 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]7ba3ca72013-04-11 06:37:25634 EXPECT_FALSE(lost_resource);
[email protected]28571b042013-03-14 07:59:15635 ++callback_count_;
636 }
637
638 void SetMailbox(char mailbox_char) {
[email protected]9794fb32013-08-29 09:49:59639 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
danakj60bc3bc2016-04-09 00:24:48640 std::unique_ptr<SingleReleaseCallback> callback =
641 SingleReleaseCallback::Create(base::Bind(
[email protected]28571b042013-03-14 07:59:15642 &TextureLayerImplWithMailboxThreadedCallback::ReleaseCallback,
643 base::Unretained(this)));
dyene5db881b2016-03-01 19:47:03644 layer_->SetTextureMailbox(
645 TextureMailbox(MailboxFromChar(mailbox_char),
646 SyncTokenFromUInt(static_cast<uint32_t>(mailbox_char)),
647 GL_TEXTURE_2D),
648 std::move(callback));
[email protected]28571b042013-03-14 07:59:15649 }
650
dcheng716bedf2014-10-21 09:51:08651 void BeginTest() override {
[email protected]9794fb32013-08-29 09:49:59652 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
653
[email protected]28571b042013-03-14 07:59:15654 gfx::Size bounds(100, 100);
loyso0940d412016-03-14 01:30:31655 root_ = Layer::Create();
[email protected]28571b042013-03-14 07:59:15656 root_->SetBounds(bounds);
657
loyso0940d412016-03-14 01:30:31658 layer_ = TextureLayer::CreateForMailbox(nullptr);
[email protected]28571b042013-03-14 07:59:15659 layer_->SetIsDrawable(true);
[email protected]28571b042013-03-14 07:59:15660 layer_->SetBounds(bounds);
661
662 root_->AddChild(layer_);
[email protected]e216fef02013-03-20 22:56:10663 layer_tree_host()->SetRootLayer(root_);
[email protected]18ce59702013-04-09 04:58:40664 layer_tree_host()->SetViewportSize(bounds);
[email protected]28571b042013-03-14 07:59:15665 SetMailbox('1');
666 EXPECT_EQ(0, callback_count_);
667
668 // Case #1: change mailbox before the commit. The old mailbox should be
669 // released immediately.
670 SetMailbox('2');
671 EXPECT_EQ(1, callback_count_);
[email protected]e216fef02013-03-20 22:56:10672 PostSetNeedsCommitToMainThread();
[email protected]28571b042013-03-14 07:59:15673 }
674
dcheng716bedf2014-10-21 09:51:08675 void DidCommit() override {
[email protected]28571b042013-03-14 07:59:15676 ++commit_count_;
677 switch (commit_count_) {
678 case 1:
679 // Case #2: change mailbox after the commit (and draw), where the
680 // layer draws. The old mailbox should be released during the next
681 // commit.
682 SetMailbox('3');
683 EXPECT_EQ(1, callback_count_);
684 break;
685 case 2:
[email protected]28571b042013-03-14 07:59:15686 EXPECT_EQ(2, callback_count_);
687 // Case #3: change mailbox when the layer doesn't draw. The old
688 // mailbox should be released during the next commit.
689 layer_->SetBounds(gfx::Size());
690 SetMailbox('4');
691 break;
[email protected]9794fb32013-08-29 09:49:59692 case 3:
[email protected]28571b042013-03-14 07:59:15693 EXPECT_EQ(3, callback_count_);
694 // Case #4: release mailbox that was committed but never drawn. The
695 // old mailbox should be released during the next commit.
danakj968153f32014-10-15 22:52:16696 layer_->SetTextureMailbox(TextureMailbox(), nullptr);
[email protected]28571b042013-03-14 07:59:15697 break;
[email protected]9794fb32013-08-29 09:49:59698 case 4:
danakj431a1202015-06-17 19:09:33699 // With impl painting, the texture mailbox will still be on the impl
700 // thread when the commit finishes, because the layer is not drawble
701 // when it has no texture mailbox, and thus does not block the commit
702 // on activation. So, we wait for activation.
703 // TODO(danakj): fix this. crbug.com/277953
704 layer_tree_host()->SetNeedsCommit();
705 break;
[email protected]9794fb32013-08-29 09:49:59706 case 5:
[email protected]28571b042013-03-14 07:59:15707 EXPECT_EQ(4, callback_count_);
[email protected]7096acc2013-06-18 21:12:43708 // Restore a mailbox for the next step.
709 SetMailbox('5');
710 break;
[email protected]9794fb32013-08-29 09:49:59711 case 6:
[email protected]7096acc2013-06-18 21:12:43712 // Case #5: remove layer from tree. Callback should *not* be called, the
713 // mailbox is returned to the main thread.
714 EXPECT_EQ(4, callback_count_);
715 layer_->RemoveFromParent();
716 break;
[email protected]9794fb32013-08-29 09:49:59717 case 7:
danakj431a1202015-06-17 19:09:33718 // With impl painting, the texture mailbox will still be on the impl
719 // thread when the commit finishes, because the layer is not around to
720 // block the commit on activation anymore. So, we wait for activation.
721 // TODO(danakj): fix this. crbug.com/277953
722 layer_tree_host()->SetNeedsCommit();
723 break;
[email protected]9794fb32013-08-29 09:49:59724 case 8:
[email protected]7096acc2013-06-18 21:12:43725 EXPECT_EQ(4, callback_count_);
726 // Resetting the mailbox will call the callback now.
danakj968153f32014-10-15 22:52:16727 layer_->SetTextureMailbox(TextureMailbox(), nullptr);
[email protected]7096acc2013-06-18 21:12:43728 EXPECT_EQ(5, callback_count_);
[email protected]e216fef02013-03-20 22:56:10729 EndTest();
[email protected]28571b042013-03-14 07:59:15730 break;
731 default:
732 NOTREACHED();
733 break;
[email protected]de44a152013-01-08 15:28:46734 }
[email protected]28571b042013-03-14 07:59:15735 }
[email protected]de44a152013-01-08 15:28:46736
dcheng716bedf2014-10-21 09:51:08737 void AfterTest() override {}
[email protected]de44a152013-01-08 15:28:46738
[email protected]28571b042013-03-14 07:59:15739 private:
[email protected]9794fb32013-08-29 09:49:59740 base::ThreadChecker main_thread_;
[email protected]28571b042013-03-14 07:59:15741 int callback_count_;
742 int commit_count_;
743 scoped_refptr<Layer> root_;
744 scoped_refptr<TextureLayer> layer_;
[email protected]de44a152013-01-08 15:28:46745};
746
[email protected]4145d172013-05-10 16:54:36747SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
748 TextureLayerImplWithMailboxThreadedCallback);
[email protected]de44a152013-01-08 15:28:46749
[email protected]74b43cc2013-08-30 06:29:27750
[email protected]74b43cc2013-08-30 06:29:27751class TextureLayerMailboxIsActivatedDuringCommit : public LayerTreeTest {
752 protected:
[email protected]98ea818e2014-01-24 10:22:08753 TextureLayerMailboxIsActivatedDuringCommit() : activate_count_(0) {}
[email protected]74b43cc2013-08-30 06:29:27754
dyene5db881b2016-03-01 19:47:03755 static void ReleaseCallback(const gpu::SyncToken& original_sync_token,
756 const gpu::SyncToken& release_sync_token,
dyencc16ed4d2015-11-03 20:03:04757 bool lost_resource) {}
[email protected]74b43cc2013-08-30 06:29:27758
759 void SetMailbox(char mailbox_char) {
dyene5db881b2016-03-01 19:47:03760 const gpu::SyncToken sync_token =
761 SyncTokenFromUInt(static_cast<uint32_t>(mailbox_char));
danakj60bc3bc2016-04-09 00:24:48762 std::unique_ptr<SingleReleaseCallback> callback =
763 SingleReleaseCallback::Create(base::Bind(
764 &TextureLayerMailboxIsActivatedDuringCommit::ReleaseCallback,
765 sync_token));
dyencc16ed4d2015-11-03 20:03:04766 layer_->SetTextureMailbox(TextureMailbox(MailboxFromChar(mailbox_char),
dyene5db881b2016-03-01 19:47:03767 sync_token, GL_TEXTURE_2D),
danakja04855a2015-11-18 20:39:10768 std::move(callback));
[email protected]74b43cc2013-08-30 06:29:27769 }
770
dcheng716bedf2014-10-21 09:51:08771 void BeginTest() override {
[email protected]74b43cc2013-08-30 06:29:27772 gfx::Size bounds(100, 100);
loyso0940d412016-03-14 01:30:31773 root_ = Layer::Create();
[email protected]74b43cc2013-08-30 06:29:27774 root_->SetBounds(bounds);
775
loyso0940d412016-03-14 01:30:31776 layer_ = TextureLayer::CreateForMailbox(nullptr);
[email protected]74b43cc2013-08-30 06:29:27777 layer_->SetIsDrawable(true);
[email protected]74b43cc2013-08-30 06:29:27778 layer_->SetBounds(bounds);
779
780 root_->AddChild(layer_);
781 layer_tree_host()->SetRootLayer(root_);
782 layer_tree_host()->SetViewportSize(bounds);
783 SetMailbox('1');
784
785 PostSetNeedsCommitToMainThread();
786 }
787
dcheng716bedf2014-10-21 09:51:08788 void WillActivateTreeOnThread(LayerTreeHostImpl* impl) override {
danakj3c3973b2015-08-25 21:50:18789 base::AutoLock lock(activate_count_lock_);
[email protected]74b43cc2013-08-30 06:29:27790 ++activate_count_;
791 }
792
dcheng716bedf2014-10-21 09:51:08793 void DidCommit() override {
danakj3c3973b2015-08-25 21:50:18794 // The first frame doesn't cause anything to be returned so it does not
795 // need to wait for activation.
796 if (layer_tree_host()->source_frame_number() > 1) {
797 base::AutoLock lock(activate_count_lock_);
798 // The activate happened before commit is done on the main side.
799 EXPECT_EQ(activate_count_, layer_tree_host()->source_frame_number());
800 }
801
[email protected]98ea818e2014-01-24 10:22:08802 switch (layer_tree_host()->source_frame_number()) {
[email protected]74b43cc2013-08-30 06:29:27803 case 1:
804 // The first mailbox has been activated. Set a new mailbox, and
805 // expect the next commit to finish *after* it is activated.
806 SetMailbox('2');
[email protected]74b43cc2013-08-30 06:29:27807 break;
808 case 2:
809 // The second mailbox has been activated. Remove the layer from
810 // the tree to cause another commit/activation. The commit should
811 // finish *after* the layer is removed from the active tree.
812 layer_->RemoveFromParent();
[email protected]74b43cc2013-08-30 06:29:27813 break;
814 case 3:
815 EndTest();
816 break;
817 }
818 }
819
dcheng716bedf2014-10-21 09:51:08820 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
danakj3c3973b2015-08-25 21:50:18821 // The activate didn't happen before commit is done on the impl side (but it
822 // should happen before the main thread is done).
823 EXPECT_EQ(activate_count_, host_impl->sync_tree()->source_frame_number());
[email protected]74b43cc2013-08-30 06:29:27824 }
825
dcheng716bedf2014-10-21 09:51:08826 void AfterTest() override {}
[email protected]74b43cc2013-08-30 06:29:27827
danakj3c3973b2015-08-25 21:50:18828 base::Lock activate_count_lock_;
[email protected]74b43cc2013-08-30 06:29:27829 int activate_count_;
830 scoped_refptr<Layer> root_;
831 scoped_refptr<TextureLayer> layer_;
832};
833
834SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
835 TextureLayerMailboxIsActivatedDuringCommit);
836
[email protected]de44a152013-01-08 15:28:46837class TextureLayerImplWithMailboxTest : public TextureLayerTest {
[email protected]28571b042013-03-14 07:59:15838 protected:
[email protected]408b5e22013-03-19 09:48:09839 TextureLayerImplWithMailboxTest()
840 : fake_client_(
841 FakeLayerTreeHostClient(FakeLayerTreeHostClient::DIRECT_3D)) {}
842
dcheng93a52eb2014-12-23 02:14:23843 void SetUp() override {
[email protected]28571b042013-03-14 07:59:15844 TextureLayerTest::SetUp();
danakjcf610582015-06-16 22:48:56845 layer_tree_host_ =
846 MockLayerTreeHost::Create(&fake_client_, &task_graph_runner_);
sievers71c62dd52015-10-07 01:44:39847 host_impl_.SetVisible(true);
revemand180dfc32015-09-24 00:19:43848 EXPECT_TRUE(host_impl_.InitializeRenderer(output_surface_.get()));
[email protected]28571b042013-03-14 07:59:15849 }
[email protected]de44a152013-01-08 15:28:46850
[email protected]0ec335c42013-07-04 06:17:08851 bool WillDraw(TextureLayerImpl* layer, DrawMode mode) {
852 bool will_draw = layer->WillDraw(
853 mode, host_impl_.active_tree()->resource_provider());
854 if (will_draw)
855 layer->DidDraw(host_impl_.active_tree()->resource_provider());
856 return will_draw;
857 }
858
[email protected]408b5e22013-03-19 09:48:09859 FakeLayerTreeHostClient fake_client_;
[email protected]de44a152013-01-08 15:28:46860};
861
[email protected]ffbb2212013-06-02 23:47:59862// Test conditions for results of TextureLayerImpl::WillDraw under
863// different configurations of different mailbox, texture_id, and draw_mode.
864TEST_F(TextureLayerImplWithMailboxTest, TestWillDraw) {
skyostil3976a3f2014-09-04 22:07:23865 EXPECT_CALL(
866 test_data_.mock_callback_,
dyencc16ed4d2015-11-03 20:03:04867 ReleaseImpl(test_data_.mailbox_name1_, test_data_.sync_token1_, false, _))
[email protected]0ec335c42013-07-04 06:17:08868 .Times(AnyNumber());
dyencc16ed4d2015-11-03 20:03:04869 EXPECT_CALL(
870 test_data_.mock_callback_,
871 ReleaseImpl2(test_data_.shared_bitmap_.get(), gpu::SyncToken(), false, _))
[email protected]0ec335c42013-07-04 06:17:08872 .Times(AnyNumber());
[email protected]ffbb2212013-06-02 23:47:59873 // Hardware mode.
874 {
danakj60bc3bc2016-04-09 00:24:48875 std::unique_ptr<TextureLayerImpl> impl_layer =
[email protected]17e08432014-04-10 00:41:11876 TextureLayerImpl::Create(host_impl_.active_tree(), 1);
[email protected]9260757f2013-09-17 01:24:16877 impl_layer->SetTextureMailbox(
878 test_data_.mailbox1_,
skyostil3976a3f2014-09-04 22:07:23879 SingleReleaseCallbackImpl::Create(test_data_.release_mailbox1_impl_));
[email protected]0ec335c42013-07-04 06:17:08880 EXPECT_TRUE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE));
[email protected]ffbb2212013-06-02 23:47:59881 }
882
883 {
danakj60bc3bc2016-04-09 00:24:48884 std::unique_ptr<TextureLayerImpl> impl_layer =
[email protected]17e08432014-04-10 00:41:11885 TextureLayerImpl::Create(host_impl_.active_tree(), 1);
danakj968153f32014-10-15 22:52:16886 impl_layer->SetTextureMailbox(TextureMailbox(), nullptr);
[email protected]0ec335c42013-07-04 06:17:08887 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE));
888 }
889
890 {
891 // Software resource.
danakj60bc3bc2016-04-09 00:24:48892 std::unique_ptr<TextureLayerImpl> impl_layer =
[email protected]17e08432014-04-10 00:41:11893 TextureLayerImpl::Create(host_impl_.active_tree(), 1);
[email protected]9260757f2013-09-17 01:24:16894 impl_layer->SetTextureMailbox(
895 test_data_.mailbox3_,
skyostil3976a3f2014-09-04 22:07:23896 SingleReleaseCallbackImpl::Create(test_data_.release_mailbox3_impl_));
[email protected]3e44d7a2013-07-30 00:03:10897 EXPECT_TRUE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE));
[email protected]ffbb2212013-06-02 23:47:59898 }
899
[email protected]0ec335c42013-07-04 06:17:08900 // Software mode.
901 {
danakj60bc3bc2016-04-09 00:24:48902 std::unique_ptr<TextureLayerImpl> impl_layer =
[email protected]17e08432014-04-10 00:41:11903 TextureLayerImpl::Create(host_impl_.active_tree(), 1);
[email protected]9260757f2013-09-17 01:24:16904 impl_layer->SetTextureMailbox(
905 test_data_.mailbox1_,
skyostil3976a3f2014-09-04 22:07:23906 SingleReleaseCallbackImpl::Create(test_data_.release_mailbox1_impl_));
[email protected]0ec335c42013-07-04 06:17:08907 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE));
908 }
909
910 {
danakj60bc3bc2016-04-09 00:24:48911 std::unique_ptr<TextureLayerImpl> impl_layer =
[email protected]17e08432014-04-10 00:41:11912 TextureLayerImpl::Create(host_impl_.active_tree(), 1);
danakj968153f32014-10-15 22:52:16913 impl_layer->SetTextureMailbox(TextureMailbox(), nullptr);
[email protected]0ec335c42013-07-04 06:17:08914 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE));
915 }
916
917 {
918 // Software resource.
danakj60bc3bc2016-04-09 00:24:48919 std::unique_ptr<TextureLayerImpl> impl_layer =
[email protected]17e08432014-04-10 00:41:11920 TextureLayerImpl::Create(host_impl_.active_tree(), 1);
[email protected]9260757f2013-09-17 01:24:16921 impl_layer->SetTextureMailbox(
922 test_data_.mailbox3_,
skyostil3976a3f2014-09-04 22:07:23923 SingleReleaseCallbackImpl::Create(test_data_.release_mailbox3_impl_));
[email protected]0ec335c42013-07-04 06:17:08924 EXPECT_TRUE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE));
925 }
926
[email protected]ffbb2212013-06-02 23:47:59927 // Resourceless software mode.
928 {
danakj60bc3bc2016-04-09 00:24:48929 std::unique_ptr<TextureLayerImpl> impl_layer =
[email protected]17e08432014-04-10 00:41:11930 TextureLayerImpl::Create(host_impl_.active_tree(), 1);
[email protected]9260757f2013-09-17 01:24:16931 impl_layer->SetTextureMailbox(
932 test_data_.mailbox1_,
skyostil3976a3f2014-09-04 22:07:23933 SingleReleaseCallbackImpl::Create(test_data_.release_mailbox1_impl_));
[email protected]0ec335c42013-07-04 06:17:08934 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_RESOURCELESS_SOFTWARE));
[email protected]ffbb2212013-06-02 23:47:59935 }
[email protected]ffbb2212013-06-02 23:47:59936}
937
[email protected]28571b042013-03-14 07:59:15938TEST_F(TextureLayerImplWithMailboxTest, TestImplLayerCallbacks) {
939 host_impl_.CreatePendingTree();
danakj60bc3bc2016-04-09 00:24:48940 std::unique_ptr<TextureLayerImpl> pending_layer;
[email protected]17e08432014-04-10 00:41:11941 pending_layer = TextureLayerImpl::Create(host_impl_.pending_tree(), 1);
[email protected]28571b042013-03-14 07:59:15942 ASSERT_TRUE(pending_layer);
[email protected]de44a152013-01-08 15:28:46943
danakj60bc3bc2016-04-09 00:24:48944 std::unique_ptr<LayerImpl> active_layer(
[email protected]28571b042013-03-14 07:59:15945 pending_layer->CreateLayerImpl(host_impl_.active_tree()));
[email protected]ed511b8d2013-03-25 03:29:29946 ASSERT_TRUE(active_layer);
[email protected]de44a152013-01-08 15:28:46947
[email protected]9260757f2013-09-17 01:24:16948 pending_layer->SetTextureMailbox(
949 test_data_.mailbox1_,
skyostil3976a3f2014-09-04 22:07:23950 SingleReleaseCallbackImpl::Create(test_data_.release_mailbox1_impl_));
[email protected]421e84f2013-02-22 03:27:15951
[email protected]28571b042013-03-14 07:59:15952 // Test multiple commits without an activation.
skyostil3976a3f2014-09-04 22:07:23953 EXPECT_CALL(
954 test_data_.mock_callback_,
dyencc16ed4d2015-11-03 20:03:04955 ReleaseImpl(test_data_.mailbox_name1_, test_data_.sync_token1_, false, _))
[email protected]28571b042013-03-14 07:59:15956 .Times(1);
[email protected]9260757f2013-09-17 01:24:16957 pending_layer->SetTextureMailbox(
958 test_data_.mailbox2_,
skyostil3976a3f2014-09-04 22:07:23959 SingleReleaseCallbackImpl::Create(test_data_.release_mailbox2_impl_));
[email protected]28571b042013-03-14 07:59:15960 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]421e84f2013-02-22 03:27:15961
[email protected]28571b042013-03-14 07:59:15962 // Test callback after activation.
[email protected]ed511b8d2013-03-25 03:29:29963 pending_layer->PushPropertiesTo(active_layer.get());
964 active_layer->DidBecomeActive();
[email protected]421e84f2013-02-22 03:27:15965
skyostil3976a3f2014-09-04 22:07:23966 EXPECT_CALL(test_data_.mock_callback_, ReleaseImpl(_, _, _, _)).Times(0);
[email protected]9260757f2013-09-17 01:24:16967 pending_layer->SetTextureMailbox(
968 test_data_.mailbox1_,
skyostil3976a3f2014-09-04 22:07:23969 SingleReleaseCallbackImpl::Create(test_data_.release_mailbox1_impl_));
[email protected]28571b042013-03-14 07:59:15970 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]421e84f2013-02-22 03:27:15971
[email protected]7ba3ca72013-04-11 06:37:25972 EXPECT_CALL(test_data_.mock_callback_,
skyostil3976a3f2014-09-04 22:07:23973 ReleaseImpl(test_data_.mailbox_name2_, _, false, _)).Times(1);
[email protected]ed511b8d2013-03-25 03:29:29974 pending_layer->PushPropertiesTo(active_layer.get());
975 active_layer->DidBecomeActive();
[email protected]28571b042013-03-14 07:59:15976 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]de44a152013-01-08 15:28:46977
[email protected]28571b042013-03-14 07:59:15978 // Test resetting the mailbox.
[email protected]7ba3ca72013-04-11 06:37:25979 EXPECT_CALL(test_data_.mock_callback_,
skyostil3976a3f2014-09-04 22:07:23980 ReleaseImpl(test_data_.mailbox_name1_, _, false, _)).Times(1);
danakj968153f32014-10-15 22:52:16981 pending_layer->SetTextureMailbox(TextureMailbox(), nullptr);
[email protected]ed511b8d2013-03-25 03:29:29982 pending_layer->PushPropertiesTo(active_layer.get());
983 active_layer->DidBecomeActive();
[email protected]28571b042013-03-14 07:59:15984 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]de44a152013-01-08 15:28:46985
[email protected]28571b042013-03-14 07:59:15986 // Test destructor.
skyostil3976a3f2014-09-04 22:07:23987 EXPECT_CALL(
988 test_data_.mock_callback_,
dyencc16ed4d2015-11-03 20:03:04989 ReleaseImpl(test_data_.mailbox_name1_, test_data_.sync_token1_, false, _))
[email protected]28571b042013-03-14 07:59:15990 .Times(1);
[email protected]9260757f2013-09-17 01:24:16991 pending_layer->SetTextureMailbox(
992 test_data_.mailbox1_,
skyostil3976a3f2014-09-04 22:07:23993 SingleReleaseCallbackImpl::Create(test_data_.release_mailbox1_impl_));
[email protected]de44a152013-01-08 15:28:46994}
995
[email protected]28571b042013-03-14 07:59:15996TEST_F(TextureLayerImplWithMailboxTest,
997 TestDestructorCallbackOnCreatedResource) {
danakj60bc3bc2016-04-09 00:24:48998 std::unique_ptr<TextureLayerImpl> impl_layer;
[email protected]17e08432014-04-10 00:41:11999 impl_layer = TextureLayerImpl::Create(host_impl_.active_tree(), 1);
[email protected]28571b042013-03-14 07:59:151000 ASSERT_TRUE(impl_layer);
[email protected]de44a152013-01-08 15:28:461001
[email protected]7ba3ca72013-04-11 06:37:251002 EXPECT_CALL(test_data_.mock_callback_,
skyostil3976a3f2014-09-04 22:07:231003 ReleaseImpl(test_data_.mailbox_name1_, _, false, _)).Times(1);
[email protected]9260757f2013-09-17 01:24:161004 impl_layer->SetTextureMailbox(
1005 test_data_.mailbox1_,
skyostil3976a3f2014-09-04 22:07:231006 SingleReleaseCallbackImpl::Create(test_data_.release_mailbox1_impl_));
[email protected]ffbb2212013-06-02 23:47:591007 impl_layer->DidBecomeActive();
1008 EXPECT_TRUE(impl_layer->WillDraw(
1009 DRAW_MODE_HARDWARE, host_impl_.active_tree()->resource_provider()));
[email protected]28571b042013-03-14 07:59:151010 impl_layer->DidDraw(host_impl_.active_tree()->resource_provider());
danakj968153f32014-10-15 22:52:161011 impl_layer->SetTextureMailbox(TextureMailbox(), nullptr);
[email protected]de44a152013-01-08 15:28:461012}
1013
[email protected]28571b042013-03-14 07:59:151014TEST_F(TextureLayerImplWithMailboxTest, TestCallbackOnInUseResource) {
1015 ResourceProvider* provider = host_impl_.active_tree()->resource_provider();
jbaumanbbd425e2015-05-19 00:33:351016 ResourceId id = provider->CreateResourceFromTextureMailbox(
skyostil3976a3f2014-09-04 22:07:231017 test_data_.mailbox1_,
1018 SingleReleaseCallbackImpl::Create(test_data_.release_mailbox1_impl_));
[email protected]28571b042013-03-14 07:59:151019 provider->AllocateForTesting(id);
[email protected]de44a152013-01-08 15:28:461020
[email protected]28571b042013-03-14 07:59:151021 // Transfer some resources to the parent.
1022 ResourceProvider::ResourceIdArray resource_ids_to_transfer;
1023 resource_ids_to_transfer.push_back(id);
1024 TransferableResourceArray list;
1025 provider->PrepareSendToParent(resource_ids_to_transfer, &list);
1026 EXPECT_TRUE(provider->InUseByConsumer(id));
skyostil3976a3f2014-09-04 22:07:231027 EXPECT_CALL(test_data_.mock_callback_, ReleaseImpl(_, _, _, _)).Times(0);
[email protected]28571b042013-03-14 07:59:151028 provider->DeleteResource(id);
1029 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]7ba3ca72013-04-11 06:37:251030 EXPECT_CALL(test_data_.mock_callback_,
skyostil3976a3f2014-09-04 22:07:231031 ReleaseImpl(test_data_.mailbox_name1_, _, false, _)).Times(1);
[email protected]e00bab022013-08-19 00:42:451032 ReturnedResourceArray returned;
1033 TransferableResource::ReturnResources(list, &returned);
1034 provider->ReceiveReturnsFromParent(returned);
[email protected]de44a152013-01-08 15:28:461035}
1036
[email protected]4bad8b62013-10-24 01:27:291037// Checks that TextureLayer::Update does not cause an extra commit when setting
1038// the texture mailbox.
1039class TextureLayerNoExtraCommitForMailboxTest
1040 : public LayerTreeTest,
1041 public TextureLayerClient {
1042 public:
[email protected]4bad8b62013-10-24 01:27:291043 // TextureLayerClient implementation.
dcheng716bedf2014-10-21 09:51:081044 bool PrepareTextureMailbox(
[email protected]df41e252014-02-03 23:39:501045 TextureMailbox* texture_mailbox,
danakj60bc3bc2016-04-09 00:24:481046 std::unique_ptr<SingleReleaseCallback>* release_callback,
mostynbf68776d82014-10-06 18:07:371047 bool use_shared_memory) override {
[email protected]cce34bd2013-12-02 23:24:451048 if (layer_tree_host()->source_frame_number() == 1) {
[email protected]9f35bd22014-06-03 15:25:461049 // Once this has been committed, the mailbox will be released.
[email protected]df41e252014-02-03 23:39:501050 *texture_mailbox = TextureMailbox();
[email protected]cce34bd2013-12-02 23:24:451051 return true;
1052 }
[email protected]4bad8b62013-10-24 01:27:291053
dyene5db881b2016-03-01 19:47:031054 *texture_mailbox = TextureMailbox(MailboxFromChar('1'),
1055 SyncTokenFromUInt(0x123), GL_TEXTURE_2D);
[email protected]4bad8b62013-10-24 01:27:291056 *release_callback = SingleReleaseCallback::Create(
1057 base::Bind(&TextureLayerNoExtraCommitForMailboxTest::MailboxReleased,
1058 base::Unretained(this)));
[email protected]4bad8b62013-10-24 01:27:291059 return true;
1060 }
1061
dyencc16ed4d2015-11-03 20:03:041062 void MailboxReleased(const gpu::SyncToken& sync_token, bool lost_resource) {
[email protected]9f35bd22014-06-03 15:25:461063 // Source frame number during callback is the same as the source frame
1064 // on which it was released.
1065 EXPECT_EQ(1, layer_tree_host()->source_frame_number());
dyene5db881b2016-03-01 19:47:031066 EXPECT_TRUE(sync_token.HasData());
[email protected]cce34bd2013-12-02 23:24:451067 EndTest();
[email protected]4bad8b62013-10-24 01:27:291068 }
1069
dcheng716bedf2014-10-21 09:51:081070 void SetupTree() override {
loyso0940d412016-03-14 01:30:311071 scoped_refptr<Layer> root = Layer::Create();
[email protected]4bad8b62013-10-24 01:27:291072 root->SetBounds(gfx::Size(10, 10));
[email protected]4bad8b62013-10-24 01:27:291073 root->SetIsDrawable(true);
1074
loyso0940d412016-03-14 01:30:311075 texture_layer_ = TextureLayer::CreateForMailbox(this);
[email protected]4bad8b62013-10-24 01:27:291076 texture_layer_->SetBounds(gfx::Size(10, 10));
[email protected]4bad8b62013-10-24 01:27:291077 texture_layer_->SetIsDrawable(true);
[email protected]0d7fb302014-01-23 21:30:471078 root->AddChild(texture_layer_);
[email protected]4bad8b62013-10-24 01:27:291079
1080 layer_tree_host()->SetRootLayer(root);
1081 LayerTreeTest::SetupTree();
1082 }
1083
dcheng716bedf2014-10-21 09:51:081084 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
[email protected]4bad8b62013-10-24 01:27:291085
dcheng716bedf2014-10-21 09:51:081086 void DidCommitAndDrawFrame() override {
[email protected]4bad8b62013-10-24 01:27:291087 switch (layer_tree_host()->source_frame_number()) {
1088 case 1:
[email protected]4ea293f72014-08-13 03:03:171089 EXPECT_FALSE(proxy()->MainFrameWillHappenForTesting());
[email protected]cce34bd2013-12-02 23:24:451090 // Invalidate the texture layer to clear the mailbox before
1091 // ending the test.
1092 texture_layer_->SetNeedsDisplay();
1093 break;
1094 case 2:
[email protected]4bad8b62013-10-24 01:27:291095 break;
1096 default:
1097 NOTREACHED();
1098 break;
1099 }
1100 }
1101
dcheng716bedf2014-10-21 09:51:081102 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override {
[email protected]cce34bd2013-12-02 23:24:451103 ASSERT_TRUE(result);
1104 DelegatedFrameData* delegated_frame_data =
1105 output_surface()->last_sent_frame().delegated_frame_data.get();
1106 if (!delegated_frame_data)
1107 return;
1108
1109 // Return all resources immediately.
1110 TransferableResourceArray resources_to_return =
1111 output_surface()->resources_held_by_parent();
1112
1113 CompositorFrameAck ack;
1114 for (size_t i = 0; i < resources_to_return.size(); ++i)
1115 output_surface()->ReturnResource(resources_to_return[i].id, &ack);
1116 host_impl->ReclaimResources(&ack);
[email protected]cce34bd2013-12-02 23:24:451117 }
1118
dcheng716bedf2014-10-21 09:51:081119 void AfterTest() override {}
[email protected]4bad8b62013-10-24 01:27:291120
1121 private:
[email protected]4bad8b62013-10-24 01:27:291122 scoped_refptr<TextureLayer> texture_layer_;
[email protected]4bad8b62013-10-24 01:27:291123};
1124
[email protected]cce34bd2013-12-02 23:24:451125SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerNoExtraCommitForMailboxTest);
[email protected]4bad8b62013-10-24 01:27:291126
[email protected]b04264f92013-09-13 23:37:291127// Checks that changing a mailbox in the client for a TextureLayer that's
1128// invisible correctly works and uses the new mailbox as soon as the layer
1129// becomes visible (and returns the old one).
1130class TextureLayerChangeInvisibleMailboxTest
1131 : public LayerTreeTest,
1132 public TextureLayerClient {
1133 public:
1134 TextureLayerChangeInvisibleMailboxTest()
1135 : mailbox_changed_(true),
1136 mailbox_returned_(0),
1137 prepare_called_(0),
1138 commit_count_(0) {
1139 mailbox_ = MakeMailbox('1');
1140 }
1141
1142 // TextureLayerClient implementation.
dcheng716bedf2014-10-21 09:51:081143 bool PrepareTextureMailbox(
[email protected]e51444a2013-12-10 23:05:011144 TextureMailbox* mailbox,
danakj60bc3bc2016-04-09 00:24:481145 std::unique_ptr<SingleReleaseCallback>* release_callback,
mostynbf68776d82014-10-06 18:07:371146 bool use_shared_memory) override {
[email protected]b04264f92013-09-13 23:37:291147 ++prepare_called_;
1148 if (!mailbox_changed_)
1149 return false;
1150 *mailbox = mailbox_;
[email protected]9260757f2013-09-17 01:24:161151 *release_callback = SingleReleaseCallback::Create(
1152 base::Bind(&TextureLayerChangeInvisibleMailboxTest::MailboxReleased,
1153 base::Unretained(this)));
[email protected]b04264f92013-09-13 23:37:291154 return true;
1155 }
1156
1157 TextureMailbox MakeMailbox(char name) {
dyene5db881b2016-03-01 19:47:031158 return TextureMailbox(MailboxFromChar(name),
1159 SyncTokenFromUInt(static_cast<uint32_t>(name)),
dyencc16ed4d2015-11-03 20:03:041160 GL_TEXTURE_2D);
[email protected]b04264f92013-09-13 23:37:291161 }
1162
dyencc16ed4d2015-11-03 20:03:041163 void MailboxReleased(const gpu::SyncToken& sync_token, bool lost_resource) {
dyene5db881b2016-03-01 19:47:031164 EXPECT_TRUE(sync_token.HasData());
[email protected]b04264f92013-09-13 23:37:291165 ++mailbox_returned_;
1166 }
1167
dcheng716bedf2014-10-21 09:51:081168 void SetupTree() override {
loyso0940d412016-03-14 01:30:311169 scoped_refptr<Layer> root = Layer::Create();
[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
loyso0940d412016-03-14 01:30:311173 solid_layer_ = SolidColorLayer::Create();
[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
loyso0940d412016-03-14 01:30:311179 parent_layer_ = Layer::Create();
[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
loyso0940d412016-03-14 01:30:311184 texture_layer_ = TextureLayer::CreateForMailbox(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.
jaydasikacf223762016-05-16 23:02:091220 parent_layer_->SetOpacity(0.9f);
[email protected]b04264f92013-09-13 23:37:291221 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,
danakj60bc3bc2016-04-09 00:24:481282 std::unique_ptr<SingleReleaseCallback>* release_callback,
mostynbf68776d82014-10-06 18:07:371283 bool use_shared_memory) override {
dyene5db881b2016-03-01 19:47:031284 *mailbox = TextureMailbox(MailboxFromChar('1'), SyncTokenFromUInt(1),
1285 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 =
loyso0940d412016-03-14 01:30:311300 TextureLayer::CreateForMailbox(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);
jaydasikabd6f15a2016-04-21 19:45:371305 texture_layer_id_ = texture_layer->id();
[email protected]0d7fb302014-01-23 21:30:471306 }
1307
dcheng716bedf2014-10-21 09:51:081308 void BeginTest() override {
[email protected]0d7fb302014-01-23 21:30:471309 mailbox_released_ = false;
1310 PostSetNeedsCommitToMainThread();
1311 }
1312
dcheng716bedf2014-10-21 09:51:081313 void DidCommitAndDrawFrame() override { EndTest(); }
[email protected]0d7fb302014-01-23 21:30:471314
dcheng716bedf2014-10-21 09:51:081315 void AfterTest() override { EXPECT_TRUE(mailbox_released_); }
[email protected]0d7fb302014-01-23 21:30:471316
jaydasikabd6f15a2016-04-21 19:45:371317 protected:
1318 int texture_layer_id_;
1319
[email protected]0d7fb302014-01-23 21:30:471320 private:
1321 bool mailbox_released_;
1322};
1323
1324class TextureLayerReleaseResourcesAfterCommit
1325 : public TextureLayerReleaseResourcesBase {
1326 public:
dcheng716bedf2014-10-21 09:51:081327 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
kulkarni.a4015690f12014-10-10 13:50:061328 LayerTreeImpl* tree = nullptr;
danakj009cdfdf2015-02-17 22:35:141329 tree = host_impl->sync_tree();
jaydasikabd6f15a2016-04-21 19:45:371330 tree->LayerById(texture_layer_id_)->ReleaseResources();
[email protected]0d7fb302014-01-23 21:30:471331 }
1332};
1333
1334SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerReleaseResourcesAfterCommit);
1335
1336class TextureLayerReleaseResourcesAfterActivate
1337 : public TextureLayerReleaseResourcesBase {
1338 public:
dcheng716bedf2014-10-21 09:51:081339 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
jaydasikabd6f15a2016-04-21 19:45:371340 host_impl->active_tree()->LayerById(texture_layer_id_)->ReleaseResources();
[email protected]0d7fb302014-01-23 21:30:471341 }
1342};
1343
1344SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerReleaseResourcesAfterActivate);
1345
[email protected]9c2bd822013-07-26 12:30:171346class TextureLayerWithMailboxMainThreadDeleted : public LayerTreeTest {
1347 public:
dyencc16ed4d2015-11-03 20:03:041348 void ReleaseCallback(const gpu::SyncToken& sync_token, bool lost_resource) {
[email protected]9794fb32013-08-29 09:49:591349 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]9c2bd822013-07-26 12:30:171350 EXPECT_FALSE(lost_resource);
1351 ++callback_count_;
1352 EndTest();
1353 }
1354
1355 void SetMailbox(char mailbox_char) {
[email protected]9794fb32013-08-29 09:49:591356 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
danakj60bc3bc2016-04-09 00:24:481357 std::unique_ptr<SingleReleaseCallback> callback =
1358 SingleReleaseCallback::Create(base::Bind(
[email protected]9c2bd822013-07-26 12:30:171359 &TextureLayerWithMailboxMainThreadDeleted::ReleaseCallback,
1360 base::Unretained(this)));
dyene5db881b2016-03-01 19:47:031361 layer_->SetTextureMailbox(
1362 TextureMailbox(MailboxFromChar(mailbox_char),
1363 SyncTokenFromUInt(static_cast<uint32_t>(mailbox_char)),
1364 GL_TEXTURE_2D),
1365 std::move(callback));
[email protected]9c2bd822013-07-26 12:30:171366 }
1367
dcheng716bedf2014-10-21 09:51:081368 void SetupTree() override {
[email protected]9c2bd822013-07-26 12:30:171369 gfx::Size bounds(100, 100);
loyso0940d412016-03-14 01:30:311370 root_ = Layer::Create();
[email protected]9c2bd822013-07-26 12:30:171371 root_->SetBounds(bounds);
1372
loyso0940d412016-03-14 01:30:311373 layer_ = TextureLayer::CreateForMailbox(nullptr);
[email protected]9c2bd822013-07-26 12:30:171374 layer_->SetIsDrawable(true);
[email protected]9c2bd822013-07-26 12:30:171375 layer_->SetBounds(bounds);
1376
1377 root_->AddChild(layer_);
1378 layer_tree_host()->SetRootLayer(root_);
1379 layer_tree_host()->SetViewportSize(bounds);
1380 }
1381
dcheng716bedf2014-10-21 09:51:081382 void BeginTest() override {
[email protected]9794fb32013-08-29 09:49:591383 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
1384
[email protected]9c2bd822013-07-26 12:30:171385 callback_count_ = 0;
1386
1387 // Set the mailbox on the main thread.
1388 SetMailbox('1');
1389 EXPECT_EQ(0, callback_count_);
1390
1391 PostSetNeedsCommitToMainThread();
1392 }
1393
dcheng716bedf2014-10-21 09:51:081394 void DidCommitAndDrawFrame() override {
[email protected]9c2bd822013-07-26 12:30:171395 switch (layer_tree_host()->source_frame_number()) {
1396 case 1:
1397 // Delete the TextureLayer on the main thread while the mailbox is in
1398 // the impl tree.
1399 layer_->RemoveFromParent();
kulkarni.a4015690f12014-10-10 13:50:061400 layer_ = nullptr;
[email protected]9c2bd822013-07-26 12:30:171401 break;
1402 }
1403 }
1404
dcheng716bedf2014-10-21 09:51:081405 void AfterTest() override { EXPECT_EQ(1, callback_count_); }
[email protected]9c2bd822013-07-26 12:30:171406
1407 private:
[email protected]9794fb32013-08-29 09:49:591408 base::ThreadChecker main_thread_;
[email protected]9c2bd822013-07-26 12:30:171409 int callback_count_;
1410 scoped_refptr<Layer> root_;
1411 scoped_refptr<TextureLayer> layer_;
1412};
1413
1414SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
1415 TextureLayerWithMailboxMainThreadDeleted);
1416
1417class TextureLayerWithMailboxImplThreadDeleted : public LayerTreeTest {
1418 public:
dyencc16ed4d2015-11-03 20:03:041419 void ReleaseCallback(const gpu::SyncToken& sync_token, bool lost_resource) {
[email protected]9794fb32013-08-29 09:49:591420 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]9c2bd822013-07-26 12:30:171421 EXPECT_FALSE(lost_resource);
1422 ++callback_count_;
1423 EndTest();
1424 }
1425
1426 void SetMailbox(char mailbox_char) {
[email protected]9794fb32013-08-29 09:49:591427 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
danakj60bc3bc2016-04-09 00:24:481428 std::unique_ptr<SingleReleaseCallback> callback =
1429 SingleReleaseCallback::Create(base::Bind(
[email protected]9c2bd822013-07-26 12:30:171430 &TextureLayerWithMailboxImplThreadDeleted::ReleaseCallback,
1431 base::Unretained(this)));
dyene5db881b2016-03-01 19:47:031432 layer_->SetTextureMailbox(
1433 TextureMailbox(MailboxFromChar(mailbox_char),
1434 SyncTokenFromUInt(static_cast<uint32_t>(mailbox_char)),
1435 GL_TEXTURE_2D),
1436 std::move(callback));
[email protected]9c2bd822013-07-26 12:30:171437 }
1438
dcheng716bedf2014-10-21 09:51:081439 void SetupTree() override {
[email protected]9c2bd822013-07-26 12:30:171440 gfx::Size bounds(100, 100);
loyso0940d412016-03-14 01:30:311441 root_ = Layer::Create();
[email protected]9c2bd822013-07-26 12:30:171442 root_->SetBounds(bounds);
1443
loyso0940d412016-03-14 01:30:311444 layer_ = TextureLayer::CreateForMailbox(nullptr);
[email protected]9c2bd822013-07-26 12:30:171445 layer_->SetIsDrawable(true);
[email protected]9c2bd822013-07-26 12:30:171446 layer_->SetBounds(bounds);
1447
1448 root_->AddChild(layer_);
1449 layer_tree_host()->SetRootLayer(root_);
1450 layer_tree_host()->SetViewportSize(bounds);
1451 }
1452
dcheng716bedf2014-10-21 09:51:081453 void BeginTest() override {
[email protected]9794fb32013-08-29 09:49:591454 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
1455
[email protected]9c2bd822013-07-26 12:30:171456 callback_count_ = 0;
1457
1458 // Set the mailbox on the main thread.
1459 SetMailbox('1');
1460 EXPECT_EQ(0, callback_count_);
1461
1462 PostSetNeedsCommitToMainThread();
1463 }
1464
dcheng716bedf2014-10-21 09:51:081465 void DidCommitAndDrawFrame() override {
[email protected]9c2bd822013-07-26 12:30:171466 switch (layer_tree_host()->source_frame_number()) {
1467 case 1:
1468 // Remove the TextureLayer on the main thread while the mailbox is in
1469 // the impl tree, but don't delete the TextureLayer until after the impl
1470 // tree side is deleted.
1471 layer_->RemoveFromParent();
1472 break;
1473 case 2:
kulkarni.a4015690f12014-10-10 13:50:061474 layer_ = nullptr;
[email protected]9c2bd822013-07-26 12:30:171475 break;
1476 }
1477 }
1478
dcheng716bedf2014-10-21 09:51:081479 void AfterTest() override { EXPECT_EQ(1, callback_count_); }
[email protected]9c2bd822013-07-26 12:30:171480
1481 private:
[email protected]9794fb32013-08-29 09:49:591482 base::ThreadChecker main_thread_;
[email protected]9c2bd822013-07-26 12:30:171483 int callback_count_;
1484 scoped_refptr<Layer> root_;
1485 scoped_refptr<TextureLayer> layer_;
1486};
1487
1488SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
1489 TextureLayerWithMailboxImplThreadDeleted);
1490
[email protected]ba565742012-11-10 09:29:481491} // namespace
1492} // namespace cc