blob: e946142ffbef925cfb1e57b134b8dc149fea2ad5 [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"
loysoab32ee72016-06-08 03:33:1824#include "cc/animation/animation_host.h"
[email protected]b04264f92013-09-13 23:37:2925#include "cc/layers/solid_color_layer.h"
[email protected]97d519fb2013-03-29 02:27:5426#include "cc/layers/texture_layer_client.h"
[email protected]cc3cfaa2013-03-18 09:05:5227#include "cc/layers/texture_layer_impl.h"
khushalsagarb64b360d2015-10-21 19:25:1628#include "cc/test/fake_impl_task_runner_provider.h"
danakjc7afae52017-06-20 21:12:4129#include "cc/test/fake_layer_tree_frame_sink.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]06d68d02013-04-19 18:46:2132#include "cc/test/layer_test_common.h"
[email protected]e216fef02013-03-20 22:56:1033#include "cc/test/layer_tree_test.h"
danakjffc181a2016-07-22 22:48:4334#include "cc/test/stub_layer_tree_host_single_thread_client.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"
khushalsagare0e4486e2017-01-25 03:15:0337#include "cc/trees/layer_tree_host.h"
[email protected]556fd292013-03-18 08:03:0438#include "cc/trees/layer_tree_impl.h"
39#include "cc/trees/single_thread_proxy.h"
Xu Xing32549162017-07-17 22:25:4340#include "components/viz/common/gpu/context_provider.h"
Fady Samuel4f7f0fb32017-07-28 15:33:3741#include "components/viz/common/resources/returned_resource.h"
danakj6b082cc2017-11-20 22:32:1242#include "components/viz/common/resources/transferable_resource.h"
danakjc391f332017-07-12 20:45:5243#include "components/viz/test/test_layer_tree_frame_sink.h"
[email protected]0bf5a202013-07-10 14:50:5444#include "gpu/GLES2/gl2extchromium.h"
[email protected]7f0c53db2012-10-02 00:23:1845#include "testing/gmock/include/gmock/gmock.h"
46#include "testing/gtest/include/gtest/gtest.h"
[email protected]c0dd24c2012-08-30 23:25:2747
[email protected]c0dd24c2012-08-30 23:25:2748using ::testing::Mock;
49using ::testing::_;
50using ::testing::AtLeast;
51using ::testing::AnyNumber;
[email protected]d72d9e02014-04-03 18:40:0952using ::testing::InvokeWithoutArgs;
[email protected]c0dd24c2012-08-30 23:25:2753
[email protected]ba565742012-11-10 09:29:4854namespace cc {
[email protected]c0dd24c2012-08-30 23:25:2755namespace {
56
[email protected]e0a4d732014-02-15 00:23:2657gpu::Mailbox MailboxFromChar(char value) {
[email protected]df41e252014-02-03 23:39:5058 gpu::Mailbox mailbox;
[email protected]e0a4d732014-02-15 00:23:2659 memset(mailbox.name, value, sizeof(mailbox.name));
[email protected]df41e252014-02-03 23:39:5060 return mailbox;
61}
62
dyen398dd0142016-01-21 22:05:5663gpu::SyncToken SyncTokenFromUInt(uint32_t value) {
lukasza2573ce7d2016-02-16 19:17:2264 return gpu::SyncToken(gpu::CommandBufferNamespace::GPU_IO, 0,
65 gpu::CommandBufferId::FromUnsafeValue(0x123), value);
dyen398dd0142016-01-21 22:05:5666}
67
khushalsagare0e4486e2017-01-25 03:15:0368class MockLayerTreeHost : public LayerTreeHost {
[email protected]28571b042013-03-14 07:59:1569 public:
danakj60bc3bc2016-04-09 00:24:4870 static std::unique_ptr<MockLayerTreeHost> Create(
danakjcf610582015-06-16 22:48:5671 FakeLayerTreeHostClient* client,
loyso2cb3f32f2016-11-08 07:08:3472 TaskGraphRunner* task_graph_runner,
73 MutatorHost* mutator_host) {
khushalsagare0e4486e2017-01-25 03:15:0374 LayerTreeHost::InitParams params;
sadrul6780f3da2015-05-11 17:01:5275 params.client = client;
danakjcf610582015-06-16 22:48:5676 params.task_graph_runner = task_graph_runner;
loyso2cb3f32f2016-11-08 07:08:3477 params.mutator_host = mutator_host;
sadrul6780f3da2015-05-11 17:01:5278 LayerTreeSettings settings;
79 params.settings = &settings;
danakjffc181a2016-07-22 22:48:4380 return base::WrapUnique(new MockLayerTreeHost(&params));
[email protected]28571b042013-03-14 07:59:1581 }
[email protected]c0dd24c2012-08-30 23:25:2782
[email protected]28571b042013-03-14 07:59:1583 MOCK_METHOD0(SetNeedsCommit, void());
[email protected]aeeb3372013-11-05 14:05:5484 MOCK_METHOD0(StartRateLimiter, void());
85 MOCK_METHOD0(StopRateLimiter, void());
sadrul6780f3da2015-05-11 17:01:5286
87 private:
khushalsagare0e4486e2017-01-25 03:15:0388 explicit MockLayerTreeHost(LayerTreeHost::InitParams* params)
89 : LayerTreeHost(params, CompositorMode::SINGLE_THREADED) {
danakjffc181a2016-07-22 22:48:4390 InitializeSingleThreaded(&single_thread_client_,
enne2b0ad682016-09-21 01:44:4791 base::ThreadTaskRunnerHandle::Get());
sadrul6780f3da2015-05-11 17:01:5292 }
danakjffc181a2016-07-22 22:48:4393
94 StubLayerTreeHostSingleThreadClient single_thread_client_;
[email protected]c0dd24c2012-08-30 23:25:2795};
96
danakj5df8257f2017-11-20 22:16:5897class MockReleaseCallback {
[email protected]d72d9e02014-04-03 18:40:0998 public:
99 MOCK_METHOD3(Release,
100 void(const gpu::Mailbox& mailbox,
dyencc16ed4d2015-11-03 20:03:04101 const gpu::SyncToken& sync_token,
[email protected]d72d9e02014-04-03 18:40:09102 bool lost_resource));
103 MOCK_METHOD3(Release2,
Fady Samuel4b5f9862017-07-11 05:27:20104 void(viz::SharedBitmap* shared_bitmap,
dyencc16ed4d2015-11-03 20:03:04105 const gpu::SyncToken& sync_token,
[email protected]d72d9e02014-04-03 18:40:09106 bool lost_resource));
107};
108
danakj5df8257f2017-11-20 22:16:58109struct CommonResourceObjects {
110 explicit CommonResourceObjects(viz::SharedBitmapManager* manager)
[email protected]d72d9e02014-04-03 18:40:09111 : mailbox_name1_(MailboxFromChar('1')),
112 mailbox_name2_(MailboxFromChar('2')),
lukasza2573ce7d2016-02-16 19:17:22113 sync_token1_(gpu::CommandBufferNamespace::GPU_IO,
114 123,
115 gpu::CommandBufferId::FromUnsafeValue(0x234),
116 1),
117 sync_token2_(gpu::CommandBufferNamespace::GPU_IO,
118 123,
119 gpu::CommandBufferId::FromUnsafeValue(0x234),
120 2) {
danakj5df8257f2017-11-20 22:16:58121 release_callback1_ =
122 base::Bind(&MockReleaseCallback::Release,
123 base::Unretained(&mock_callback_), mailbox_name1_);
124 release_callback2_ =
125 base::Bind(&MockReleaseCallback::Release,
126 base::Unretained(&mock_callback_), mailbox_name2_);
avi02a4d172015-12-21 06:14:36127 const uint32_t arbitrary_target1 = GL_TEXTURE_2D;
128 const uint32_t arbitrary_target2 = GL_TEXTURE_EXTERNAL_OES;
danakj5df8257f2017-11-20 22:16:58129 resource1_ = viz::TransferableResource::MakeGL(
130 mailbox_name1_, GL_LINEAR, arbitrary_target1, sync_token1_);
131 resource2_ = viz::TransferableResource::MakeGL(
132 mailbox_name2_, GL_LINEAR, arbitrary_target2, sync_token2_);
[email protected]d72d9e02014-04-03 18:40:09133 gfx::Size size(128, 128);
jbauman9015c8b2014-12-11 00:49:37134 shared_bitmap_ = manager->AllocateSharedBitmap(size);
135 DCHECK(shared_bitmap_);
danakj5df8257f2017-11-20 22:16:58136 release_callback3_ =
137 base::Bind(&MockReleaseCallback::Release2,
jbauman9015c8b2014-12-11 00:49:37138 base::Unretained(&mock_callback_), shared_bitmap_.get());
danakj5df8257f2017-11-20 22:16:58139 resource3_ = viz::TransferableResource::MakeSoftware(
140 shared_bitmap_->id(), shared_bitmap_->sequence_number(), size);
[email protected]d72d9e02014-04-03 18:40:09141 }
142
tzik736175f2017-11-15 13:39:24143 using RepeatingReleaseCallback =
144 base::RepeatingCallback<void(const gpu::SyncToken& sync_token,
145 bool is_lost)>;
146
[email protected]d72d9e02014-04-03 18:40:09147 gpu::Mailbox mailbox_name1_;
148 gpu::Mailbox mailbox_name2_;
danakj5df8257f2017-11-20 22:16:58149 MockReleaseCallback mock_callback_;
150 RepeatingReleaseCallback release_callback1_;
151 RepeatingReleaseCallback release_callback2_;
152 RepeatingReleaseCallback release_callback3_;
dyencc16ed4d2015-11-03 20:03:04153 gpu::SyncToken sync_token1_;
154 gpu::SyncToken sync_token2_;
Fady Samuel4b5f9862017-07-11 05:27:20155 std::unique_ptr<viz::SharedBitmap> shared_bitmap_;
danakj5df8257f2017-11-20 22:16:58156 viz::TransferableResource resource1_;
157 viz::TransferableResource resource2_;
158 viz::TransferableResource resource3_;
[email protected]d72d9e02014-04-03 18:40:09159};
160
[email protected]31d4df82013-07-18 10:17:22161class TextureLayerTest : public testing::Test {
162 public:
163 TextureLayerTest()
danakjc7afae52017-06-20 21:12:41164 : layer_tree_frame_sink_(FakeLayerTreeFrameSink::Create3d()),
165 host_impl_(&task_runner_provider_, &task_graph_runner_),
jbauman9015c8b2014-12-11 00:49:37166 test_data_(&shared_bitmap_manager_) {}
[email protected]31d4df82013-07-18 10:17:22167
168 protected:
dcheng93a52eb2014-12-23 02:14:23169 void SetUp() override {
loyso2cb3f32f2016-11-08 07:08:34170 animation_host_ = AnimationHost::CreateForTesting(ThreadInstance::MAIN);
171 layer_tree_host_ = MockLayerTreeHost::Create(
172 &fake_client_, &task_graph_runner_, animation_host_.get());
[email protected]d72d9e02014-04-03 18:40:09173 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
khushalsagarb69ba9452017-01-27 22:20:07174 layer_tree_host_->SetViewportSize(gfx::Size(10, 10));
[email protected]d72d9e02014-04-03 18:40:09175 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
[email protected]31d4df82013-07-18 10:17:22176 }
177
dcheng93a52eb2014-12-23 02:14:23178 void TearDown() override {
[email protected]31d4df82013-07-18 10:17:22179 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
[email protected]31d4df82013-07-18 10:17:22180 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
181
loyso2cb3f32f2016-11-08 07:08:34182 animation_host_->SetMutatorHostClient(nullptr);
khushalsagarb69ba9452017-01-27 22:20:07183 layer_tree_host_->SetRootLayer(nullptr);
danakjf446a072014-09-27 21:55:48184 layer_tree_host_ = nullptr;
loyso2cb3f32f2016-11-08 07:08:34185 animation_host_ = nullptr;
[email protected]31d4df82013-07-18 10:17:22186 }
187
danakj60bc3bc2016-04-09 00:24:48188 std::unique_ptr<MockLayerTreeHost> layer_tree_host_;
loyso2cb3f32f2016-11-08 07:08:34189 std::unique_ptr<AnimationHost> animation_host_;
khushalsagarb64b360d2015-10-21 19:25:16190 FakeImplTaskRunnerProvider task_runner_provider_;
[email protected]31d4df82013-07-18 10:17:22191 FakeLayerTreeHostClient fake_client_;
[email protected]4e2eb352014-03-20 17:25:45192 TestSharedBitmapManager shared_bitmap_manager_;
reveman34b7a1522015-03-23 20:27:47193 TestTaskGraphRunner task_graph_runner_;
danakjc7afae52017-06-20 21:12:41194 std::unique_ptr<LayerTreeFrameSink> layer_tree_frame_sink_;
[email protected]31d4df82013-07-18 10:17:22195 FakeLayerTreeHostImpl host_impl_;
danakj5df8257f2017-11-20 22:16:58196 CommonResourceObjects test_data_;
[email protected]31d4df82013-07-18 10:17:22197};
198
[email protected]31d4df82013-07-18 10:17:22199TEST_F(TextureLayerTest, CheckPropertyChangeCausesCorrectBehavior) {
kulkarni.a4015690f12014-10-10 13:50:06200 scoped_refptr<TextureLayer> test_layer =
loyso0940d412016-03-14 01:30:31201 TextureLayer::CreateForMailbox(nullptr);
khushalsagarb69ba9452017-01-27 22:20:07202 EXPECT_SET_NEEDS_COMMIT(1, layer_tree_host_->SetRootLayer(test_layer));
[email protected]31d4df82013-07-18 10:17:22203
204 // Test properties that should call SetNeedsCommit. All properties need to
205 // be set to new values in order for SetNeedsCommit to be called.
206 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetFlipped(false));
jackhou10c9af42014-12-04 05:24:44207 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetNearestNeighbor(true));
[email protected]31d4df82013-07-18 10:17:22208 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetUV(
209 gfx::PointF(0.25f, 0.25f), gfx::PointF(0.75f, 0.75f)));
210 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetVertexOpacity(
211 0.5f, 0.5f, 0.5f, 0.5f));
212 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetPremultipliedAlpha(false));
213 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetBlendBackgroundColor(true));
[email protected]31d4df82013-07-18 10:17:22214}
215
danakj7fb2f142017-11-21 01:36:15216class TestMailboxHolder : public TextureLayer::TransferableResourceHolder {
[email protected]9794fb32013-08-29 09:49:59217 public:
danakj7fb2f142017-11-21 01:36:15218 using TextureLayer::TransferableResourceHolder::Create;
[email protected]9794fb32013-08-29 09:49:59219
220 protected:
Chris Watkinsf6353292017-12-04 02:36:05221 ~TestMailboxHolder() override = default;
[email protected]9794fb32013-08-29 09:49:59222};
223
danakj5df8257f2017-11-20 22:16:58224class TextureLayerWithResourceTest : public TextureLayerTest {
[email protected]28571b042013-03-14 07:59:15225 protected:
dcheng93a52eb2014-12-23 02:14:23226 void TearDown() override {
[email protected]28571b042013-03-14 07:59:15227 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
dyencc16ed4d2015-11-03 20:03:04228 EXPECT_CALL(
229 test_data_.mock_callback_,
230 Release(test_data_.mailbox_name1_, test_data_.sync_token1_, false))
231 .Times(1);
[email protected]28571b042013-03-14 07:59:15232 TextureLayerTest::TearDown();
233 }
[email protected]de44a152013-01-08 15:28:46234};
235
danakj5df8257f2017-11-20 22:16:58236TEST_F(TextureLayerWithResourceTest, ReplaceMailboxOnMainThreadBeforeCommit) {
kulkarni.a4015690f12014-10-10 13:50:06237 scoped_refptr<TextureLayer> test_layer =
loyso0940d412016-03-14 01:30:31238 TextureLayer::CreateForMailbox(nullptr);
[email protected]22898ed2013-06-01 04:52:30239 ASSERT_TRUE(test_layer.get());
[email protected]de44a152013-01-08 15:28:46240
[email protected]28571b042013-03-14 07:59:15241 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
khushalsagarb69ba9452017-01-27 22:20:07242 layer_tree_host_->SetRootLayer(test_layer);
[email protected]28571b042013-03-14 07:59:15243 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
[email protected]de44a152013-01-08 15:28:46244
[email protected]28571b042013-03-14 07:59:15245 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
danakj5df8257f2017-11-20 22:16:58246 test_layer->SetTransferableResource(
247 test_data_.resource1_,
248 viz::SingleReleaseCallback::Create(test_data_.release_callback1_));
[email protected]28571b042013-03-14 07:59:15249 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
[email protected]de44a152013-01-08 15:28:46250
[email protected]28571b042013-03-14 07:59:15251 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
dyencc16ed4d2015-11-03 20:03:04252 EXPECT_CALL(
253 test_data_.mock_callback_,
254 Release(test_data_.mailbox_name1_, test_data_.sync_token1_, false))
[email protected]28571b042013-03-14 07:59:15255 .Times(1);
danakj5df8257f2017-11-20 22:16:58256 test_layer->SetTransferableResource(
257 test_data_.resource2_,
258 viz::SingleReleaseCallback::Create(test_data_.release_callback2_));
[email protected]28571b042013-03-14 07:59:15259 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
260 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]de44a152013-01-08 15:28:46261
[email protected]28571b042013-03-14 07:59:15262 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
dyencc16ed4d2015-11-03 20:03:04263 EXPECT_CALL(
264 test_data_.mock_callback_,
265 Release(test_data_.mailbox_name2_, test_data_.sync_token2_, false))
[email protected]28571b042013-03-14 07:59:15266 .Times(1);
danakj5df8257f2017-11-20 22:16:58267 test_layer->ClearTexture();
[email protected]28571b042013-03-14 07:59:15268 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
269 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]de44a152013-01-08 15:28:46270
[email protected]80d42bd2013-08-30 19:13:45271 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
danakj5df8257f2017-11-20 22:16:58272 test_layer->SetTransferableResource(
273 test_data_.resource3_,
274 viz::SingleReleaseCallback::Create(test_data_.release_callback3_));
[email protected]42f40a52013-06-08 04:38:51275 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
276 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
277
[email protected]42f40a52013-06-08 04:38:51278 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
279 EXPECT_CALL(test_data_.mock_callback_,
dyencc16ed4d2015-11-03 20:03:04280 Release2(test_data_.shared_bitmap_.get(), _, false))
281 .Times(1);
danakj5df8257f2017-11-20 22:16:58282 test_layer->ClearTexture();
[email protected]42f40a52013-06-08 04:38:51283 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
284 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
285
[email protected]28571b042013-03-14 07:59:15286 // Test destructor.
287 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
danakj5df8257f2017-11-20 22:16:58288 test_layer->SetTransferableResource(
289 test_data_.resource1_,
290 viz::SingleReleaseCallback::Create(test_data_.release_callback1_));
[email protected]de44a152013-01-08 15:28:46291}
292
[email protected]9794fb32013-08-29 09:49:59293class TextureLayerMailboxHolderTest : public TextureLayerTest {
294 public:
295 TextureLayerMailboxHolderTest()
296 : main_thread_("MAIN") {
297 main_thread_.Start();
298 }
299
300 void Wait(const base::Thread& thread) {
gabcca53112016-06-08 20:13:28301 base::WaitableEvent event(base::WaitableEvent::ResetPolicy::AUTOMATIC,
302 base::WaitableEvent::InitialState::NOT_SIGNALED);
fdoray70df5a92016-06-22 21:13:59303 thread.task_runner()->PostTask(
[email protected]9794fb32013-08-29 09:49:59304 FROM_HERE,
tzik4604bb52017-04-13 21:50:22305 base::BindOnce(&base::WaitableEvent::Signal, base::Unretained(&event)));
[email protected]9794fb32013-08-29 09:49:59306 event.Wait();
307 }
308
309 void CreateMainRef() {
310 main_ref_ = TestMailboxHolder::Create(
danakj5df8257f2017-11-20 22:16:58311 test_data_.resource1_,
312 viz::SingleReleaseCallback::Create(test_data_.release_callback1_));
[email protected]9794fb32013-08-29 09:49:59313 }
314
danakjf446a072014-09-27 21:55:48315 void ReleaseMainRef() { main_ref_ = nullptr; }
[email protected]9794fb32013-08-29 09:49:59316
danakjcde8e4c32017-09-25 18:33:47317 void CreateImplRef(
318 std::unique_ptr<viz::SingleReleaseCallback>* impl_ref,
319 scoped_refptr<base::SequencedTaskRunner> main_thread_task_runner) {
320 *impl_ref = main_ref_->holder()->GetCallbackForImplThread(
321 std::move(main_thread_task_runner));
[email protected]9794fb32013-08-29 09:49:59322 }
323
324 protected:
danakj60bc3bc2016-04-09 00:24:48325 std::unique_ptr<TestMailboxHolder::MainThreadReference> main_ref_;
[email protected]9794fb32013-08-29 09:49:59326 base::Thread main_thread_;
[email protected]9794fb32013-08-29 09:49:59327};
328
329TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_BothReleaseThenMain) {
kulkarni.a4015690f12014-10-10 13:50:06330 scoped_refptr<TextureLayer> test_layer =
loyso0940d412016-03-14 01:30:31331 TextureLayer::CreateForMailbox(nullptr);
[email protected]9794fb32013-08-29 09:49:59332 ASSERT_TRUE(test_layer.get());
333
fdoray70df5a92016-06-22 21:13:59334 main_thread_.task_runner()->PostTask(
tzik4604bb52017-04-13 21:50:22335 FROM_HERE, base::BindOnce(&TextureLayerMailboxHolderTest::CreateMainRef,
336 base::Unretained(this)));
[email protected]9794fb32013-08-29 09:49:59337
338 Wait(main_thread_);
339
340 // The texture layer is attached to compositor1, and passes a reference to its
341 // impl tree.
danakjcde8e4c32017-09-25 18:33:47342 std::unique_ptr<viz::SingleReleaseCallback> compositor1;
fdoray70df5a92016-06-22 21:13:59343 main_thread_.task_runner()->PostTask(
tzik4604bb52017-04-13 21:50:22344 FROM_HERE, base::BindOnce(&TextureLayerMailboxHolderTest::CreateImplRef,
danakjcde8e4c32017-09-25 18:33:47345 base::Unretained(this), &compositor1,
346 main_thread_.task_runner()));
[email protected]9794fb32013-08-29 09:49:59347
348 // Then the texture layer is removed and attached to compositor2, and passes a
349 // reference to its impl tree.
danakjcde8e4c32017-09-25 18:33:47350 std::unique_ptr<viz::SingleReleaseCallback> compositor2;
fdoray70df5a92016-06-22 21:13:59351 main_thread_.task_runner()->PostTask(
tzik4604bb52017-04-13 21:50:22352 FROM_HERE, base::BindOnce(&TextureLayerMailboxHolderTest::CreateImplRef,
danakjcde8e4c32017-09-25 18:33:47353 base::Unretained(this), &compositor2,
354 main_thread_.task_runner()));
[email protected]9794fb32013-08-29 09:49:59355
356 Wait(main_thread_);
357 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
358
359 // The compositors both destroy their impl trees before the main thread layer
360 // is destroyed.
danakjcde8e4c32017-09-25 18:33:47361 compositor1->Run(SyncTokenFromUInt(100), false);
362 compositor2->Run(SyncTokenFromUInt(200), false);
[email protected]9794fb32013-08-29 09:49:59363
364 Wait(main_thread_);
365
366 EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0);
367 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
368
danakj5df8257f2017-11-20 22:16:58369 // The main thread ref is the last one, so the resource is released back to
370 // the embedder, with the last sync point provided by the impl trees.
[email protected]9794fb32013-08-29 09:49:59371 EXPECT_CALL(test_data_.mock_callback_,
dyen398dd0142016-01-21 22:05:56372 Release(test_data_.mailbox_name1_, SyncTokenFromUInt(200), false))
dyencc16ed4d2015-11-03 20:03:04373 .Times(1);
[email protected]9794fb32013-08-29 09:49:59374
fdoray70df5a92016-06-22 21:13:59375 main_thread_.task_runner()->PostTask(
tzik4604bb52017-04-13 21:50:22376 FROM_HERE, base::BindOnce(&TextureLayerMailboxHolderTest::ReleaseMainRef,
377 base::Unretained(this)));
[email protected]9794fb32013-08-29 09:49:59378 Wait(main_thread_);
379 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
380}
381
382TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_MainReleaseBetween) {
kulkarni.a4015690f12014-10-10 13:50:06383 scoped_refptr<TextureLayer> test_layer =
loyso0940d412016-03-14 01:30:31384 TextureLayer::CreateForMailbox(nullptr);
[email protected]9794fb32013-08-29 09:49:59385 ASSERT_TRUE(test_layer.get());
386
fdoray70df5a92016-06-22 21:13:59387 main_thread_.task_runner()->PostTask(
tzik4604bb52017-04-13 21:50:22388 FROM_HERE, base::BindOnce(&TextureLayerMailboxHolderTest::CreateMainRef,
389 base::Unretained(this)));
[email protected]9794fb32013-08-29 09:49:59390
391 Wait(main_thread_);
392
393 // The texture layer is attached to compositor1, and passes a reference to its
394 // impl tree.
danakjcde8e4c32017-09-25 18:33:47395 std::unique_ptr<viz::SingleReleaseCallback> compositor1;
fdoray70df5a92016-06-22 21:13:59396 main_thread_.task_runner()->PostTask(
tzik4604bb52017-04-13 21:50:22397 FROM_HERE, base::BindOnce(&TextureLayerMailboxHolderTest::CreateImplRef,
danakjcde8e4c32017-09-25 18:33:47398 base::Unretained(this), &compositor1,
399 main_thread_.task_runner()));
[email protected]9794fb32013-08-29 09:49:59400
401 // Then the texture layer is removed and attached to compositor2, and passes a
402 // reference to its impl tree.
danakjcde8e4c32017-09-25 18:33:47403 std::unique_ptr<viz::SingleReleaseCallback> compositor2;
fdoray70df5a92016-06-22 21:13:59404 main_thread_.task_runner()->PostTask(
tzik4604bb52017-04-13 21:50:22405 FROM_HERE, base::BindOnce(&TextureLayerMailboxHolderTest::CreateImplRef,
danakjcde8e4c32017-09-25 18:33:47406 base::Unretained(this), &compositor2,
407 main_thread_.task_runner()));
[email protected]9794fb32013-08-29 09:49:59408
409 Wait(main_thread_);
410 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
411
412 // One compositor destroys their impl tree.
danakjcde8e4c32017-09-25 18:33:47413 compositor1->Run(SyncTokenFromUInt(100), false);
[email protected]9794fb32013-08-29 09:49:59414
415 // Then the main thread reference is destroyed.
fdoray70df5a92016-06-22 21:13:59416 main_thread_.task_runner()->PostTask(
tzik4604bb52017-04-13 21:50:22417 FROM_HERE, base::BindOnce(&TextureLayerMailboxHolderTest::ReleaseMainRef,
418 base::Unretained(this)));
[email protected]9794fb32013-08-29 09:49:59419
420 Wait(main_thread_);
421
422 EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0);
423 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
424
danakj5df8257f2017-11-20 22:16:58425 // The second impl reference is destroyed last, causing the resource to be
[email protected]9794fb32013-08-29 09:49:59426 // released back to the embedder with the last sync point from the impl tree.
427 EXPECT_CALL(test_data_.mock_callback_,
dyen398dd0142016-01-21 22:05:56428 Release(test_data_.mailbox_name1_, SyncTokenFromUInt(200), true))
dyencc16ed4d2015-11-03 20:03:04429 .Times(1);
[email protected]9794fb32013-08-29 09:49:59430
danakjcde8e4c32017-09-25 18:33:47431 compositor2->Run(SyncTokenFromUInt(200), true);
[email protected]9794fb32013-08-29 09:49:59432 Wait(main_thread_);
433 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
434}
435
436TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_MainReleasedFirst) {
kulkarni.a4015690f12014-10-10 13:50:06437 scoped_refptr<TextureLayer> test_layer =
loyso0940d412016-03-14 01:30:31438 TextureLayer::CreateForMailbox(nullptr);
[email protected]9794fb32013-08-29 09:49:59439 ASSERT_TRUE(test_layer.get());
440
fdoray70df5a92016-06-22 21:13:59441 main_thread_.task_runner()->PostTask(
tzik4604bb52017-04-13 21:50:22442 FROM_HERE, base::BindOnce(&TextureLayerMailboxHolderTest::CreateMainRef,
443 base::Unretained(this)));
[email protected]9794fb32013-08-29 09:49:59444
445 Wait(main_thread_);
446
447 // The texture layer is attached to compositor1, and passes a reference to its
448 // impl tree.
danakjcde8e4c32017-09-25 18:33:47449 std::unique_ptr<viz::SingleReleaseCallback> compositor1;
fdoray70df5a92016-06-22 21:13:59450 main_thread_.task_runner()->PostTask(
tzik4604bb52017-04-13 21:50:22451 FROM_HERE, base::BindOnce(&TextureLayerMailboxHolderTest::CreateImplRef,
danakjcde8e4c32017-09-25 18:33:47452 base::Unretained(this), &compositor1,
453 main_thread_.task_runner()));
[email protected]9794fb32013-08-29 09:49:59454
455 // Then the texture layer is removed and attached to compositor2, and passes a
456 // reference to its impl tree.
danakjcde8e4c32017-09-25 18:33:47457 std::unique_ptr<viz::SingleReleaseCallback> compositor2;
fdoray70df5a92016-06-22 21:13:59458 main_thread_.task_runner()->PostTask(
tzik4604bb52017-04-13 21:50:22459 FROM_HERE, base::BindOnce(&TextureLayerMailboxHolderTest::CreateImplRef,
danakjcde8e4c32017-09-25 18:33:47460 base::Unretained(this), &compositor2,
461 main_thread_.task_runner()));
[email protected]9794fb32013-08-29 09:49:59462
463 Wait(main_thread_);
464 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
465
466 // The main thread reference is destroyed first.
fdoray70df5a92016-06-22 21:13:59467 main_thread_.task_runner()->PostTask(
tzik4604bb52017-04-13 21:50:22468 FROM_HERE, base::BindOnce(&TextureLayerMailboxHolderTest::ReleaseMainRef,
469 base::Unretained(this)));
[email protected]9794fb32013-08-29 09:49:59470
471 // One compositor destroys their impl tree.
danakjcde8e4c32017-09-25 18:33:47472 compositor2->Run(SyncTokenFromUInt(200), false);
[email protected]9794fb32013-08-29 09:49:59473
474 Wait(main_thread_);
475
476 EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0);
477 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
478
danakj5df8257f2017-11-20 22:16:58479 // The second impl reference is destroyed last, causing the resource to be
[email protected]9794fb32013-08-29 09:49:59480 // released back to the embedder with the last sync point from the impl tree.
481 EXPECT_CALL(test_data_.mock_callback_,
dyen398dd0142016-01-21 22:05:56482 Release(test_data_.mailbox_name1_, SyncTokenFromUInt(100), true))
dyencc16ed4d2015-11-03 20:03:04483 .Times(1);
[email protected]9794fb32013-08-29 09:49:59484
danakjcde8e4c32017-09-25 18:33:47485 compositor1->Run(SyncTokenFromUInt(100), true);
[email protected]9794fb32013-08-29 09:49:59486 Wait(main_thread_);
487 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
488}
489
[email protected]e216fef02013-03-20 22:56:10490class TextureLayerImplWithMailboxThreadedCallback : public LayerTreeTest {
[email protected]28571b042013-03-14 07:59:15491 public:
danakjc391f332017-07-12 20:45:52492 std::unique_ptr<viz::TestLayerTreeFrameSink> CreateLayerTreeFrameSink(
Alex Zhangbcce8b132017-07-20 20:17:24493 const viz::RendererSettings& renderer_settings,
Alex Zhang903cb6a2017-06-12 20:31:37494 double refresh_rate,
Xu Xing32549162017-07-17 22:25:43495 scoped_refptr<viz::ContextProvider> compositor_context_provider,
496 scoped_refptr<viz::ContextProvider> worker_context_provider) override {
staraz88677422017-05-26 13:53:03497 constexpr bool disable_display_vsync = false;
danakj014316e2016-08-04 18:40:26498 bool synchronous_composite =
499 !HasImplThread() &&
khushalsagarcebe4942016-09-07 23:27:01500 !layer_tree_host()->GetSettings().single_thread_proxy_scheduler;
Jeremy Roman909d927b2017-08-27 18:34:09501 return std::make_unique<viz::TestLayerTreeFrameSink>(
danakj014316e2016-08-04 18:40:26502 compositor_context_provider, std::move(worker_context_provider),
staraz88677422017-05-26 13:53:03503 shared_bitmap_manager(), gpu_memory_buffer_manager(), renderer_settings,
Alex Zhang903cb6a2017-06-12 20:31:37504 ImplThreadTaskRunner(), synchronous_composite, disable_display_vsync,
505 refresh_rate);
danakj014316e2016-08-04 18:40:26506 }
[email protected]28571b042013-03-14 07:59:15507
ericrkad5923812017-01-25 23:26:12508 void AdvanceTestCase() {
509 ++test_case_;
510 switch (test_case_) {
511 case 1:
danakj5df8257f2017-11-20 22:16:58512 // Case #1: change resource before the commit. The old resource should
513 // be released immediately.
ericrkad5923812017-01-25 23:26:12514 SetMailbox('2');
515 EXPECT_EQ(1, callback_count_);
516 PostSetNeedsCommitToMainThread();
517
518 // Case 2 does not rely on callbacks to advance.
519 pending_callback_ = false;
520 break;
521 case 2:
danakj5df8257f2017-11-20 22:16:58522 // Case #2: change resource after the commit (and draw), where the
523 // layer draws. The old resource should be released during the next
ericrkad5923812017-01-25 23:26:12524 // commit.
525 SetMailbox('3');
526 EXPECT_EQ(1, callback_count_);
527
528 // Cases 3-5 rely on a callback to advance.
529 pending_callback_ = true;
530 break;
531 case 3:
532 EXPECT_EQ(2, callback_count_);
danakj5df8257f2017-11-20 22:16:58533 // Case #3: change resource when the layer doesn't draw. The old
534 // resource should be released during the next commit.
ericrkad5923812017-01-25 23:26:12535 layer_->SetBounds(gfx::Size());
536 SetMailbox('4');
537 break;
538 case 4:
539 EXPECT_EQ(3, callback_count_);
danakj5df8257f2017-11-20 22:16:58540 // Case #4: release resource that was committed but never drawn. The
541 // old resource should be released during the next commit.
542 layer_->ClearTexture();
ericrkad5923812017-01-25 23:26:12543 break;
544 case 5:
545 EXPECT_EQ(4, callback_count_);
danakj5df8257f2017-11-20 22:16:58546 // Restore a resource for the next step.
ericrkad5923812017-01-25 23:26:12547 SetMailbox('5');
548
549 // Cases 6 and 7 do not rely on callbacks to advance.
550 pending_callback_ = false;
551 break;
552 case 6:
553 // Case #5: remove layer from tree. Callback should *not* be called, the
danakj5df8257f2017-11-20 22:16:58554 // resource is returned to the main thread.
ericrkad5923812017-01-25 23:26:12555 EXPECT_EQ(4, callback_count_);
556 layer_->RemoveFromParent();
557 break;
558 case 7:
559 EXPECT_EQ(4, callback_count_);
danakj5df8257f2017-11-20 22:16:58560 // Resetting the resource will call the callback now, before another
danakjcde8e4c32017-09-25 18:33:47561 // commit is needed, as the ReleaseCallback is already in flight from
562 // RemoveFromParent().
danakj5df8257f2017-11-20 22:16:58563 layer_->ClearTexture();
danakjcde8e4c32017-09-25 18:33:47564 pending_callback_ = true;
565 frame_number_ = layer_tree_host()->SourceFrameNumber();
566 break;
567 case 8:
568 // A commit wasn't needed, the ReleaseCallback was already in flight.
569 EXPECT_EQ(frame_number_, layer_tree_host()->SourceFrameNumber());
ericrkad5923812017-01-25 23:26:12570 EXPECT_EQ(5, callback_count_);
571 EndTest();
572 break;
573 default:
574 NOTREACHED();
575 break;
576 }
577 }
578
[email protected]28571b042013-03-14 07:59:15579 // Make sure callback is received on main and doesn't block the impl thread.
danakj014316e2016-08-04 18:40:26580 void ReleaseCallback(char mailbox_char,
581 const gpu::SyncToken& sync_token,
582 bool lost_resource) {
[email protected]9794fb32013-08-29 09:49:59583 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]7ba3ca72013-04-11 06:37:25584 EXPECT_FALSE(lost_resource);
[email protected]28571b042013-03-14 07:59:15585 ++callback_count_;
ericrkad5923812017-01-25 23:26:12586
587 // If we are waiting on a callback, advance now.
588 if (pending_callback_)
589 AdvanceTestCase();
[email protected]28571b042013-03-14 07:59:15590 }
591
592 void SetMailbox(char mailbox_char) {
[email protected]9794fb32013-08-29 09:49:59593 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
Fady Samueldfecb7d2017-07-26 11:41:04594 std::unique_ptr<viz::SingleReleaseCallback> callback =
595 viz::SingleReleaseCallback::Create(base::Bind(
[email protected]28571b042013-03-14 07:59:15596 &TextureLayerImplWithMailboxThreadedCallback::ReleaseCallback,
danakj014316e2016-08-04 18:40:26597 base::Unretained(this), mailbox_char));
danakj5df8257f2017-11-20 22:16:58598
599 auto resource = viz::TransferableResource::MakeGL(
600 MailboxFromChar(mailbox_char), GL_LINEAR, GL_TEXTURE_2D,
601 SyncTokenFromUInt(static_cast<uint32_t>(mailbox_char)));
602 layer_->SetTransferableResource(resource, std::move(callback));
603 // Damage the layer so we send a new frame with the new resource to the
danakj014316e2016-08-04 18:40:26604 // Display compositor.
605 layer_->SetNeedsDisplay();
[email protected]28571b042013-03-14 07:59:15606 }
607
dcheng716bedf2014-10-21 09:51:08608 void BeginTest() override {
[email protected]9794fb32013-08-29 09:49:59609 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
610
[email protected]28571b042013-03-14 07:59:15611 gfx::Size bounds(100, 100);
loyso0940d412016-03-14 01:30:31612 root_ = Layer::Create();
[email protected]28571b042013-03-14 07:59:15613 root_->SetBounds(bounds);
614
loyso0940d412016-03-14 01:30:31615 layer_ = TextureLayer::CreateForMailbox(nullptr);
[email protected]28571b042013-03-14 07:59:15616 layer_->SetIsDrawable(true);
[email protected]28571b042013-03-14 07:59:15617 layer_->SetBounds(bounds);
618
619 root_->AddChild(layer_);
khushalsagarb69ba9452017-01-27 22:20:07620 layer_tree_host()->SetRootLayer(root_);
621 layer_tree_host()->SetViewportSize(bounds);
[email protected]28571b042013-03-14 07:59:15622 SetMailbox('1');
623 EXPECT_EQ(0, callback_count_);
624
ericrkad5923812017-01-25 23:26:12625 // Setup is complete - advance to test case 1.
626 AdvanceTestCase();
[email protected]28571b042013-03-14 07:59:15627 }
628
dcheng716bedf2014-10-21 09:51:08629 void DidCommit() override {
ericrkad5923812017-01-25 23:26:12630 // If we are not waiting on a callback, advance now.
631 if (!pending_callback_)
632 AdvanceTestCase();
[email protected]28571b042013-03-14 07:59:15633 }
[email protected]de44a152013-01-08 15:28:46634
dcheng716bedf2014-10-21 09:51:08635 void AfterTest() override {}
[email protected]de44a152013-01-08 15:28:46636
[email protected]28571b042013-03-14 07:59:15637 private:
[email protected]9794fb32013-08-29 09:49:59638 base::ThreadChecker main_thread_;
danakj014316e2016-08-04 18:40:26639 int callback_count_ = 0;
ericrkad5923812017-01-25 23:26:12640 int test_case_ = 0;
danakjcde8e4c32017-09-25 18:33:47641 int frame_number_ = 0;
ericrkad5923812017-01-25 23:26:12642 // Whether we are waiting on a callback to advance the test case.
643 bool pending_callback_ = false;
[email protected]28571b042013-03-14 07:59:15644 scoped_refptr<Layer> root_;
645 scoped_refptr<TextureLayer> layer_;
[email protected]de44a152013-01-08 15:28:46646};
647
danakj0943a112016-08-11 00:33:46648SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerImplWithMailboxThreadedCallback);
[email protected]74b43cc2013-08-30 06:29:27649
[email protected]74b43cc2013-08-30 06:29:27650class TextureLayerMailboxIsActivatedDuringCommit : public LayerTreeTest {
651 protected:
samans0834fe042017-03-03 17:03:22652 void ReleaseCallback(const gpu::SyncToken& original_sync_token,
653 const gpu::SyncToken& release_sync_token,
654 bool lost_resource) {
655 released_count_++;
656 switch (released_count_) {
657 case 1:
658 break;
659 case 2:
660 EXPECT_EQ(3, layer_tree_host()->SourceFrameNumber());
661 EndTest();
662 break;
663 default:
664 NOTREACHED();
665 }
666 }
[email protected]74b43cc2013-08-30 06:29:27667
668 void SetMailbox(char mailbox_char) {
dyene5db881b2016-03-01 19:47:03669 const gpu::SyncToken sync_token =
670 SyncTokenFromUInt(static_cast<uint32_t>(mailbox_char));
Fady Samueldfecb7d2017-07-26 11:41:04671 std::unique_ptr<viz::SingleReleaseCallback> callback =
672 viz::SingleReleaseCallback::Create(base::Bind(
danakj60bc3bc2016-04-09 00:24:48673 &TextureLayerMailboxIsActivatedDuringCommit::ReleaseCallback,
samans0834fe042017-03-03 17:03:22674 base::Unretained(this), sync_token));
danakj5df8257f2017-11-20 22:16:58675 auto resource = viz::TransferableResource::MakeGL(
676 MailboxFromChar(mailbox_char), GL_LINEAR, GL_TEXTURE_2D, sync_token);
677 layer_->SetTransferableResource(resource, std::move(callback));
[email protected]74b43cc2013-08-30 06:29:27678 }
679
dcheng716bedf2014-10-21 09:51:08680 void BeginTest() override {
[email protected]74b43cc2013-08-30 06:29:27681 gfx::Size bounds(100, 100);
loyso0940d412016-03-14 01:30:31682 root_ = Layer::Create();
[email protected]74b43cc2013-08-30 06:29:27683 root_->SetBounds(bounds);
684
loyso0940d412016-03-14 01:30:31685 layer_ = TextureLayer::CreateForMailbox(nullptr);
[email protected]74b43cc2013-08-30 06:29:27686 layer_->SetIsDrawable(true);
[email protected]74b43cc2013-08-30 06:29:27687 layer_->SetBounds(bounds);
688
689 root_->AddChild(layer_);
khushalsagarb69ba9452017-01-27 22:20:07690 layer_tree_host()->SetRootLayer(root_);
691 layer_tree_host()->SetViewportSize(bounds);
[email protected]74b43cc2013-08-30 06:29:27692 SetMailbox('1');
693
694 PostSetNeedsCommitToMainThread();
695 }
696
dcheng716bedf2014-10-21 09:51:08697 void WillActivateTreeOnThread(LayerTreeHostImpl* impl) override {
danakj3c3973b2015-08-25 21:50:18698 base::AutoLock lock(activate_count_lock_);
[email protected]74b43cc2013-08-30 06:29:27699 ++activate_count_;
700 }
701
dcheng716bedf2014-10-21 09:51:08702 void DidCommit() override {
danakj3c3973b2015-08-25 21:50:18703 // The first frame doesn't cause anything to be returned so it does not
704 // need to wait for activation.
khushalsagarcebe4942016-09-07 23:27:01705 if (layer_tree_host()->SourceFrameNumber() > 1) {
danakj3c3973b2015-08-25 21:50:18706 base::AutoLock lock(activate_count_lock_);
707 // The activate happened before commit is done on the main side.
khushalsagarcebe4942016-09-07 23:27:01708 EXPECT_EQ(activate_count_, layer_tree_host()->SourceFrameNumber());
danakj3c3973b2015-08-25 21:50:18709 }
710
khushalsagarcebe4942016-09-07 23:27:01711 switch (layer_tree_host()->SourceFrameNumber()) {
[email protected]74b43cc2013-08-30 06:29:27712 case 1:
713 // The first mailbox has been activated. Set a new mailbox, and
714 // expect the next commit to finish *after* it is activated.
715 SetMailbox('2');
[email protected]74b43cc2013-08-30 06:29:27716 break;
717 case 2:
718 // The second mailbox has been activated. Remove the layer from
719 // the tree to cause another commit/activation. The commit should
720 // finish *after* the layer is removed from the active tree.
721 layer_->RemoveFromParent();
[email protected]74b43cc2013-08-30 06:29:27722 break;
723 case 3:
samans0834fe042017-03-03 17:03:22724 // This ensures all texture mailboxes are released before the end of the
725 // test.
726 layer_->ClearClient();
[email protected]74b43cc2013-08-30 06:29:27727 break;
samans0834fe042017-03-03 17:03:22728 default:
729 NOTREACHED();
[email protected]74b43cc2013-08-30 06:29:27730 }
731 }
732
dcheng716bedf2014-10-21 09:51:08733 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
danakj3c3973b2015-08-25 21:50:18734 // The activate didn't happen before commit is done on the impl side (but it
735 // should happen before the main thread is done).
736 EXPECT_EQ(activate_count_, host_impl->sync_tree()->source_frame_number());
[email protected]74b43cc2013-08-30 06:29:27737 }
738
dcheng716bedf2014-10-21 09:51:08739 void AfterTest() override {}
[email protected]74b43cc2013-08-30 06:29:27740
danakj3c3973b2015-08-25 21:50:18741 base::Lock activate_count_lock_;
samans0834fe042017-03-03 17:03:22742 int activate_count_ = 0;
[email protected]74b43cc2013-08-30 06:29:27743 scoped_refptr<Layer> root_;
744 scoped_refptr<TextureLayer> layer_;
samans0834fe042017-03-03 17:03:22745 int released_count_ = 0;
[email protected]74b43cc2013-08-30 06:29:27746};
747
danakj0943a112016-08-11 00:33:46748SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerMailboxIsActivatedDuringCommit);
[email protected]74b43cc2013-08-30 06:29:27749
danakj5df8257f2017-11-20 22:16:58750class TextureLayerImplWithResourceTest : public TextureLayerTest {
[email protected]28571b042013-03-14 07:59:15751 protected:
dcheng93a52eb2014-12-23 02:14:23752 void SetUp() override {
[email protected]28571b042013-03-14 07:59:15753 TextureLayerTest::SetUp();
loyso2cb3f32f2016-11-08 07:08:34754 layer_tree_host_ = MockLayerTreeHost::Create(
755 &fake_client_, &task_graph_runner_, animation_host_.get());
sievers71c62dd52015-10-07 01:44:39756 host_impl_.SetVisible(true);
danakjc7afae52017-06-20 21:12:41757 EXPECT_TRUE(host_impl_.InitializeRenderer(layer_tree_frame_sink_.get()));
[email protected]28571b042013-03-14 07:59:15758 }
[email protected]de44a152013-01-08 15:28:46759
[email protected]0ec335c42013-07-04 06:17:08760 bool WillDraw(TextureLayerImpl* layer, DrawMode mode) {
761 bool will_draw = layer->WillDraw(
762 mode, host_impl_.active_tree()->resource_provider());
763 if (will_draw)
764 layer->DidDraw(host_impl_.active_tree()->resource_provider());
765 return will_draw;
766 }
767
[email protected]408b5e22013-03-19 09:48:09768 FakeLayerTreeHostClient fake_client_;
[email protected]de44a152013-01-08 15:28:46769};
770
[email protected]ffbb2212013-06-02 23:47:59771// Test conditions for results of TextureLayerImpl::WillDraw under
772// different configurations of different mailbox, texture_id, and draw_mode.
danakj5df8257f2017-11-20 22:16:58773TEST_F(TextureLayerImplWithResourceTest, TestWillDraw) {
774 EXPECT_CALL(test_data_.mock_callback_,
775 Release(test_data_.mailbox_name1_, gpu::SyncToken(), false))
[email protected]0ec335c42013-07-04 06:17:08776 .Times(AnyNumber());
dyencc16ed4d2015-11-03 20:03:04777 EXPECT_CALL(
778 test_data_.mock_callback_,
danakjcde8e4c32017-09-25 18:33:47779 Release2(test_data_.shared_bitmap_.get(), gpu::SyncToken(), false))
[email protected]0ec335c42013-07-04 06:17:08780 .Times(AnyNumber());
[email protected]ffbb2212013-06-02 23:47:59781 // Hardware mode.
782 {
danakj60bc3bc2016-04-09 00:24:48783 std::unique_ptr<TextureLayerImpl> impl_layer =
[email protected]17e08432014-04-10 00:41:11784 TextureLayerImpl::Create(host_impl_.active_tree(), 1);
danakj5df8257f2017-11-20 22:16:58785 impl_layer->SetTransferableResource(
786 test_data_.resource1_,
787 viz::SingleReleaseCallback::Create(test_data_.release_callback1_));
[email protected]0ec335c42013-07-04 06:17:08788 EXPECT_TRUE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE));
[email protected]ffbb2212013-06-02 23:47:59789 }
790
791 {
danakj60bc3bc2016-04-09 00:24:48792 std::unique_ptr<TextureLayerImpl> impl_layer =
[email protected]17e08432014-04-10 00:41:11793 TextureLayerImpl::Create(host_impl_.active_tree(), 1);
danakj5df8257f2017-11-20 22:16:58794 impl_layer->SetTransferableResource(viz::TransferableResource(), nullptr);
[email protected]0ec335c42013-07-04 06:17:08795 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE));
796 }
797
[email protected]0ec335c42013-07-04 06:17:08798 // Software mode.
799 {
danakj60bc3bc2016-04-09 00:24:48800 std::unique_ptr<TextureLayerImpl> impl_layer =
[email protected]17e08432014-04-10 00:41:11801 TextureLayerImpl::Create(host_impl_.active_tree(), 1);
danakj5df8257f2017-11-20 22:16:58802 impl_layer->SetTransferableResource(
803 test_data_.resource1_,
804 viz::SingleReleaseCallback::Create(test_data_.release_callback1_));
[email protected]0ec335c42013-07-04 06:17:08805 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE));
806 }
807
808 {
danakj60bc3bc2016-04-09 00:24:48809 std::unique_ptr<TextureLayerImpl> impl_layer =
[email protected]17e08432014-04-10 00:41:11810 TextureLayerImpl::Create(host_impl_.active_tree(), 1);
danakj5df8257f2017-11-20 22:16:58811 impl_layer->SetTransferableResource(viz::TransferableResource(), nullptr);
[email protected]0ec335c42013-07-04 06:17:08812 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE));
813 }
814
815 {
816 // Software resource.
danakj60bc3bc2016-04-09 00:24:48817 std::unique_ptr<TextureLayerImpl> impl_layer =
[email protected]17e08432014-04-10 00:41:11818 TextureLayerImpl::Create(host_impl_.active_tree(), 1);
danakj5df8257f2017-11-20 22:16:58819 impl_layer->SetTransferableResource(
820 test_data_.resource3_,
821 viz::SingleReleaseCallback::Create(test_data_.release_callback3_));
[email protected]0ec335c42013-07-04 06:17:08822 EXPECT_TRUE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE));
823 }
824
[email protected]ffbb2212013-06-02 23:47:59825 // Resourceless software mode.
826 {
danakj60bc3bc2016-04-09 00:24:48827 std::unique_ptr<TextureLayerImpl> impl_layer =
[email protected]17e08432014-04-10 00:41:11828 TextureLayerImpl::Create(host_impl_.active_tree(), 1);
danakj5df8257f2017-11-20 22:16:58829 impl_layer->SetTransferableResource(
830 test_data_.resource1_,
831 viz::SingleReleaseCallback::Create(test_data_.release_callback1_));
[email protected]0ec335c42013-07-04 06:17:08832 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_RESOURCELESS_SOFTWARE));
[email protected]ffbb2212013-06-02 23:47:59833 }
[email protected]ffbb2212013-06-02 23:47:59834}
835
danakj5df8257f2017-11-20 22:16:58836TEST_F(TextureLayerImplWithResourceTest, TestImplLayerCallbacks) {
[email protected]28571b042013-03-14 07:59:15837 host_impl_.CreatePendingTree();
danakj60bc3bc2016-04-09 00:24:48838 std::unique_ptr<TextureLayerImpl> pending_layer;
[email protected]17e08432014-04-10 00:41:11839 pending_layer = TextureLayerImpl::Create(host_impl_.pending_tree(), 1);
[email protected]28571b042013-03-14 07:59:15840 ASSERT_TRUE(pending_layer);
[email protected]de44a152013-01-08 15:28:46841
danakj60bc3bc2016-04-09 00:24:48842 std::unique_ptr<LayerImpl> active_layer(
[email protected]28571b042013-03-14 07:59:15843 pending_layer->CreateLayerImpl(host_impl_.active_tree()));
[email protected]ed511b8d2013-03-25 03:29:29844 ASSERT_TRUE(active_layer);
[email protected]de44a152013-01-08 15:28:46845
danakj5df8257f2017-11-20 22:16:58846 pending_layer->SetTransferableResource(
847 test_data_.resource1_,
848 viz::SingleReleaseCallback::Create(test_data_.release_callback1_));
[email protected]421e84f2013-02-22 03:27:15849
danakj5df8257f2017-11-20 22:16:58850 // Test multiple commits without an activation. The resource wasn't used so no
851 // sync token is returned.
852 EXPECT_CALL(test_data_.mock_callback_,
853 Release(test_data_.mailbox_name1_, gpu::SyncToken(), false))
[email protected]28571b042013-03-14 07:59:15854 .Times(1);
danakj5df8257f2017-11-20 22:16:58855 pending_layer->SetTransferableResource(
856 test_data_.resource2_,
857 viz::SingleReleaseCallback::Create(test_data_.release_callback2_));
[email protected]28571b042013-03-14 07:59:15858 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]421e84f2013-02-22 03:27:15859
[email protected]28571b042013-03-14 07:59:15860 // Test callback after activation.
[email protected]ed511b8d2013-03-25 03:29:29861 pending_layer->PushPropertiesTo(active_layer.get());
862 active_layer->DidBecomeActive();
[email protected]421e84f2013-02-22 03:27:15863
danakjcde8e4c32017-09-25 18:33:47864 EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0);
danakj5df8257f2017-11-20 22:16:58865 pending_layer->SetTransferableResource(
866 test_data_.resource1_,
867 viz::SingleReleaseCallback::Create(test_data_.release_callback1_));
[email protected]28571b042013-03-14 07:59:15868 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]421e84f2013-02-22 03:27:15869
[email protected]7ba3ca72013-04-11 06:37:25870 EXPECT_CALL(test_data_.mock_callback_,
danakjcde8e4c32017-09-25 18:33:47871 Release(test_data_.mailbox_name2_, _, false))
872 .Times(1);
[email protected]ed511b8d2013-03-25 03:29:29873 pending_layer->PushPropertiesTo(active_layer.get());
874 active_layer->DidBecomeActive();
[email protected]28571b042013-03-14 07:59:15875 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]de44a152013-01-08 15:28:46876
[email protected]28571b042013-03-14 07:59:15877 // Test resetting the mailbox.
[email protected]7ba3ca72013-04-11 06:37:25878 EXPECT_CALL(test_data_.mock_callback_,
danakjcde8e4c32017-09-25 18:33:47879 Release(test_data_.mailbox_name1_, _, false))
880 .Times(1);
danakj5df8257f2017-11-20 22:16:58881 pending_layer->SetTransferableResource(viz::TransferableResource(), nullptr);
[email protected]ed511b8d2013-03-25 03:29:29882 pending_layer->PushPropertiesTo(active_layer.get());
883 active_layer->DidBecomeActive();
[email protected]28571b042013-03-14 07:59:15884 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]de44a152013-01-08 15:28:46885
danakj5df8257f2017-11-20 22:16:58886 // Test destructor. The resource wasn't used so no sync token is returned.
887 EXPECT_CALL(test_data_.mock_callback_,
888 Release(test_data_.mailbox_name1_, gpu::SyncToken(), false))
[email protected]28571b042013-03-14 07:59:15889 .Times(1);
danakj5df8257f2017-11-20 22:16:58890 pending_layer->SetTransferableResource(
891 test_data_.resource1_,
892 viz::SingleReleaseCallback::Create(test_data_.release_callback1_));
[email protected]de44a152013-01-08 15:28:46893}
894
danakj5df8257f2017-11-20 22:16:58895TEST_F(TextureLayerImplWithResourceTest,
[email protected]28571b042013-03-14 07:59:15896 TestDestructorCallbackOnCreatedResource) {
danakj60bc3bc2016-04-09 00:24:48897 std::unique_ptr<TextureLayerImpl> impl_layer;
[email protected]17e08432014-04-10 00:41:11898 impl_layer = TextureLayerImpl::Create(host_impl_.active_tree(), 1);
[email protected]28571b042013-03-14 07:59:15899 ASSERT_TRUE(impl_layer);
[email protected]de44a152013-01-08 15:28:46900
[email protected]7ba3ca72013-04-11 06:37:25901 EXPECT_CALL(test_data_.mock_callback_,
danakjcde8e4c32017-09-25 18:33:47902 Release(test_data_.mailbox_name1_, _, false))
903 .Times(1);
danakj5df8257f2017-11-20 22:16:58904 impl_layer->SetTransferableResource(
905 test_data_.resource1_,
906 viz::SingleReleaseCallback::Create(test_data_.release_callback1_));
[email protected]ffbb2212013-06-02 23:47:59907 impl_layer->DidBecomeActive();
908 EXPECT_TRUE(impl_layer->WillDraw(
909 DRAW_MODE_HARDWARE, host_impl_.active_tree()->resource_provider()));
[email protected]28571b042013-03-14 07:59:15910 impl_layer->DidDraw(host_impl_.active_tree()->resource_provider());
danakj5df8257f2017-11-20 22:16:58911 impl_layer->SetTransferableResource(viz::TransferableResource(), nullptr);
[email protected]de44a152013-01-08 15:28:46912}
913
[email protected]4bad8b62013-10-24 01:27:29914// Checks that TextureLayer::Update does not cause an extra commit when setting
915// the texture mailbox.
916class TextureLayerNoExtraCommitForMailboxTest
917 : public LayerTreeTest,
918 public TextureLayerClient {
919 public:
[email protected]4bad8b62013-10-24 01:27:29920 // TextureLayerClient implementation.
danakj5df8257f2017-11-20 22:16:58921 bool PrepareTransferableResource(
922 viz::TransferableResource* resource,
Fady Samueldfecb7d2017-07-26 11:41:04923 std::unique_ptr<viz::SingleReleaseCallback>* release_callback) override {
khushalsagarcebe4942016-09-07 23:27:01924 if (layer_tree_host()->SourceFrameNumber() == 1) {
danakj5df8257f2017-11-20 22:16:58925 // Once this has been committed, the resource will be released.
926 *resource = viz::TransferableResource();
[email protected]cce34bd2013-12-02 23:24:45927 return true;
928 }
[email protected]4bad8b62013-10-24 01:27:29929
danakj5df8257f2017-11-20 22:16:58930 *resource = viz::TransferableResource::MakeGL(MailboxFromChar('1'),
931 GL_LINEAR, GL_TEXTURE_2D,
932 SyncTokenFromUInt(0x123));
Fady Samueldfecb7d2017-07-26 11:41:04933 *release_callback = viz::SingleReleaseCallback::Create(
danakj5df8257f2017-11-20 22:16:58934 base::Bind(&TextureLayerNoExtraCommitForMailboxTest::ResourceReleased,
[email protected]4bad8b62013-10-24 01:27:29935 base::Unretained(this)));
[email protected]4bad8b62013-10-24 01:27:29936 return true;
937 }
938
danakj5df8257f2017-11-20 22:16:58939 void ResourceReleased(const gpu::SyncToken& sync_token, bool lost_resource) {
dyene5db881b2016-03-01 19:47:03940 EXPECT_TRUE(sync_token.HasData());
[email protected]cce34bd2013-12-02 23:24:45941 EndTest();
[email protected]4bad8b62013-10-24 01:27:29942 }
943
dcheng716bedf2014-10-21 09:51:08944 void SetupTree() override {
loyso0940d412016-03-14 01:30:31945 scoped_refptr<Layer> root = Layer::Create();
[email protected]4bad8b62013-10-24 01:27:29946 root->SetBounds(gfx::Size(10, 10));
[email protected]4bad8b62013-10-24 01:27:29947 root->SetIsDrawable(true);
948
loyso0940d412016-03-14 01:30:31949 texture_layer_ = TextureLayer::CreateForMailbox(this);
[email protected]4bad8b62013-10-24 01:27:29950 texture_layer_->SetBounds(gfx::Size(10, 10));
[email protected]4bad8b62013-10-24 01:27:29951 texture_layer_->SetIsDrawable(true);
[email protected]0d7fb302014-01-23 21:30:47952 root->AddChild(texture_layer_);
[email protected]4bad8b62013-10-24 01:27:29953
khushalsagarb69ba9452017-01-27 22:20:07954 layer_tree_host()->SetRootLayer(root);
[email protected]4bad8b62013-10-24 01:27:29955 LayerTreeTest::SetupTree();
956 }
957
dcheng716bedf2014-10-21 09:51:08958 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
[email protected]4bad8b62013-10-24 01:27:29959
dcheng716bedf2014-10-21 09:51:08960 void DidCommitAndDrawFrame() override {
khushalsagarcebe4942016-09-07 23:27:01961 switch (layer_tree_host()->SourceFrameNumber()) {
[email protected]4bad8b62013-10-24 01:27:29962 case 1:
[email protected]4ea293f72014-08-13 03:03:17963 EXPECT_FALSE(proxy()->MainFrameWillHappenForTesting());
[email protected]cce34bd2013-12-02 23:24:45964 // Invalidate the texture layer to clear the mailbox before
965 // ending the test.
966 texture_layer_->SetNeedsDisplay();
967 break;
968 case 2:
[email protected]4bad8b62013-10-24 01:27:29969 break;
970 default:
971 NOTREACHED();
972 break;
973 }
974 }
975
dcheng716bedf2014-10-21 09:51:08976 void AfterTest() override {}
[email protected]4bad8b62013-10-24 01:27:29977
978 private:
[email protected]4bad8b62013-10-24 01:27:29979 scoped_refptr<TextureLayer> texture_layer_;
[email protected]4bad8b62013-10-24 01:27:29980};
981
[email protected]cce34bd2013-12-02 23:24:45982SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerNoExtraCommitForMailboxTest);
[email protected]4bad8b62013-10-24 01:27:29983
[email protected]b04264f92013-09-13 23:37:29984// Checks that changing a mailbox in the client for a TextureLayer that's
985// invisible correctly works and uses the new mailbox as soon as the layer
986// becomes visible (and returns the old one).
987class TextureLayerChangeInvisibleMailboxTest
988 : public LayerTreeTest,
989 public TextureLayerClient {
990 public:
991 TextureLayerChangeInvisibleMailboxTest()
danakj5df8257f2017-11-20 22:16:58992 : resource_changed_(true),
993 resource_(MakeResource('1')),
994 resource_returned_(0),
[email protected]b04264f92013-09-13 23:37:29995 prepare_called_(0),
danakj5df8257f2017-11-20 22:16:58996 commit_count_(0) {}
[email protected]b04264f92013-09-13 23:37:29997
998 // TextureLayerClient implementation.
danakj5df8257f2017-11-20 22:16:58999 bool PrepareTransferableResource(
1000 viz::TransferableResource* resource,
Fady Samueldfecb7d2017-07-26 11:41:041001 std::unique_ptr<viz::SingleReleaseCallback>* release_callback) override {
[email protected]b04264f92013-09-13 23:37:291002 ++prepare_called_;
danakj5df8257f2017-11-20 22:16:581003 if (!resource_changed_)
[email protected]b04264f92013-09-13 23:37:291004 return false;
danakj5df8257f2017-11-20 22:16:581005 *resource = resource_;
Fady Samueldfecb7d2017-07-26 11:41:041006 *release_callback = viz::SingleReleaseCallback::Create(
danakj5df8257f2017-11-20 22:16:581007 base::Bind(&TextureLayerChangeInvisibleMailboxTest::ResourceReleased,
[email protected]9260757f2013-09-17 01:24:161008 base::Unretained(this)));
[email protected]b04264f92013-09-13 23:37:291009 return true;
1010 }
1011
danakj5df8257f2017-11-20 22:16:581012 viz::TransferableResource MakeResource(char name) {
1013 return viz::TransferableResource::MakeGL(
1014 MailboxFromChar(name), GL_LINEAR, GL_TEXTURE_2D,
1015 SyncTokenFromUInt(static_cast<uint32_t>(name)));
[email protected]b04264f92013-09-13 23:37:291016 }
1017
danakj5df8257f2017-11-20 22:16:581018 void ResourceReleased(const gpu::SyncToken& sync_token, bool lost_resource) {
dyene5db881b2016-03-01 19:47:031019 EXPECT_TRUE(sync_token.HasData());
danakj5df8257f2017-11-20 22:16:581020 ++resource_returned_;
[email protected]b04264f92013-09-13 23:37:291021 }
1022
dcheng716bedf2014-10-21 09:51:081023 void SetupTree() override {
loyso0940d412016-03-14 01:30:311024 scoped_refptr<Layer> root = Layer::Create();
[email protected]b04264f92013-09-13 23:37:291025 root->SetBounds(gfx::Size(10, 10));
[email protected]b04264f92013-09-13 23:37:291026 root->SetIsDrawable(true);
1027
loyso0940d412016-03-14 01:30:311028 solid_layer_ = SolidColorLayer::Create();
[email protected]b04264f92013-09-13 23:37:291029 solid_layer_->SetBounds(gfx::Size(10, 10));
1030 solid_layer_->SetIsDrawable(true);
1031 solid_layer_->SetBackgroundColor(SK_ColorWHITE);
1032 root->AddChild(solid_layer_);
1033
loyso0940d412016-03-14 01:30:311034 parent_layer_ = Layer::Create();
[email protected]b04264f92013-09-13 23:37:291035 parent_layer_->SetBounds(gfx::Size(10, 10));
1036 parent_layer_->SetIsDrawable(true);
1037 root->AddChild(parent_layer_);
1038
loyso0940d412016-03-14 01:30:311039 texture_layer_ = TextureLayer::CreateForMailbox(this);
[email protected]b04264f92013-09-13 23:37:291040 texture_layer_->SetBounds(gfx::Size(10, 10));
[email protected]b04264f92013-09-13 23:37:291041 texture_layer_->SetIsDrawable(true);
1042 parent_layer_->AddChild(texture_layer_);
1043
khushalsagarb69ba9452017-01-27 22:20:071044 layer_tree_host()->SetRootLayer(root);
[email protected]b04264f92013-09-13 23:37:291045 LayerTreeTest::SetupTree();
1046 }
1047
dcheng716bedf2014-10-21 09:51:081048 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
[email protected]b04264f92013-09-13 23:37:291049
samans44b6dfc2017-04-19 16:50:531050 void DidReceiveCompositorFrameAck() override {
[email protected]b04264f92013-09-13 23:37:291051 ++commit_count_;
1052 switch (commit_count_) {
1053 case 1:
1054 // We should have updated the layer, committing the texture.
1055 EXPECT_EQ(1, prepare_called_);
1056 // Make layer invisible.
1057 parent_layer_->SetOpacity(0.f);
1058 break;
1059 case 2:
1060 // Layer shouldn't have been updated.
1061 EXPECT_EQ(1, prepare_called_);
1062 // Change the texture.
danakj5df8257f2017-11-20 22:16:581063 resource_ = MakeResource('2');
1064 resource_changed_ = true;
[email protected]b04264f92013-09-13 23:37:291065 texture_layer_->SetNeedsDisplay();
1066 // Force a change to make sure we draw a frame.
1067 solid_layer_->SetBackgroundColor(SK_ColorGRAY);
1068 break;
1069 case 3:
1070 // Layer shouldn't have been updated.
1071 EXPECT_EQ(1, prepare_called_);
danakj5df8257f2017-11-20 22:16:581072 // So the old resource isn't returned yet.
1073 EXPECT_EQ(0, resource_returned_);
[email protected]b04264f92013-09-13 23:37:291074 // Make layer visible again.
jaydasikacf223762016-05-16 23:02:091075 parent_layer_->SetOpacity(0.9f);
[email protected]b04264f92013-09-13 23:37:291076 break;
1077 case 4:
1078 // Layer should have been updated.
1079 EXPECT_EQ(2, prepare_called_);
danakj5df8257f2017-11-20 22:16:581080 // So the old resource should have been returned already.
1081 EXPECT_EQ(1, resource_returned_);
[email protected]b04264f92013-09-13 23:37:291082 texture_layer_->ClearClient();
1083 break;
1084 case 5:
danakj5df8257f2017-11-20 22:16:581085 EXPECT_EQ(2, resource_returned_);
samans44b6dfc2017-04-19 16:50:531086 EndTest();
[email protected]b04264f92013-09-13 23:37:291087 break;
1088 default:
1089 NOTREACHED();
1090 break;
1091 }
1092 }
1093
dcheng716bedf2014-10-21 09:51:081094 void AfterTest() override {}
[email protected]b04264f92013-09-13 23:37:291095
1096 private:
1097 scoped_refptr<SolidColorLayer> solid_layer_;
1098 scoped_refptr<Layer> parent_layer_;
1099 scoped_refptr<TextureLayer> texture_layer_;
1100
1101 // Used on the main thread.
danakj5df8257f2017-11-20 22:16:581102 bool resource_changed_;
1103 viz::TransferableResource resource_;
1104 int resource_returned_;
[email protected]b04264f92013-09-13 23:37:291105 int prepare_called_;
1106 int commit_count_;
1107};
1108
samans44b6dfc2017-04-19 16:50:531109SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerChangeInvisibleMailboxTest);
[email protected]b04264f92013-09-13 23:37:291110
[email protected]0d7fb302014-01-23 21:30:471111// Test that TextureLayerImpl::ReleaseResources can be called which releases
danakj5df8257f2017-11-20 22:16:581112// the resource back to TextureLayerClient.
[email protected]0d7fb302014-01-23 21:30:471113class TextureLayerReleaseResourcesBase
1114 : public LayerTreeTest,
1115 public TextureLayerClient {
1116 public:
1117 // TextureLayerClient implementation.
danakj5df8257f2017-11-20 22:16:581118 bool PrepareTransferableResource(
1119 viz::TransferableResource* resource,
Fady Samueldfecb7d2017-07-26 11:41:041120 std::unique_ptr<viz::SingleReleaseCallback>* release_callback) override {
danakj5df8257f2017-11-20 22:16:581121 *resource = viz::TransferableResource::MakeGL(
1122 MailboxFromChar('1'), GL_LINEAR, GL_TEXTURE_2D, SyncTokenFromUInt(1));
Fady Samueldfecb7d2017-07-26 11:41:041123 *release_callback = viz::SingleReleaseCallback::Create(
danakj5df8257f2017-11-20 22:16:581124 base::Bind(&TextureLayerReleaseResourcesBase::ResourceReleased,
[email protected]0d7fb302014-01-23 21:30:471125 base::Unretained(this)));
1126 return true;
1127 }
1128
danakj5df8257f2017-11-20 22:16:581129 void ResourceReleased(const gpu::SyncToken& sync_token, bool lost_resource) {
1130 resource_released_ = true;
[email protected]0d7fb302014-01-23 21:30:471131 }
1132
dcheng716bedf2014-10-21 09:51:081133 void SetupTree() override {
[email protected]0d7fb302014-01-23 21:30:471134 LayerTreeTest::SetupTree();
1135
1136 scoped_refptr<TextureLayer> texture_layer =
loyso0940d412016-03-14 01:30:311137 TextureLayer::CreateForMailbox(this);
[email protected]0d7fb302014-01-23 21:30:471138 texture_layer->SetBounds(gfx::Size(10, 10));
[email protected]0d7fb302014-01-23 21:30:471139 texture_layer->SetIsDrawable(true);
1140
khushalsagarb69ba9452017-01-27 22:20:071141 layer_tree_host()->root_layer()->AddChild(texture_layer);
jaydasikabd6f15a2016-04-21 19:45:371142 texture_layer_id_ = texture_layer->id();
[email protected]0d7fb302014-01-23 21:30:471143 }
1144
dcheng716bedf2014-10-21 09:51:081145 void BeginTest() override {
danakj5df8257f2017-11-20 22:16:581146 resource_released_ = false;
[email protected]0d7fb302014-01-23 21:30:471147 PostSetNeedsCommitToMainThread();
1148 }
1149
dcheng716bedf2014-10-21 09:51:081150 void DidCommitAndDrawFrame() override { EndTest(); }
[email protected]0d7fb302014-01-23 21:30:471151
danakj5df8257f2017-11-20 22:16:581152 void AfterTest() override { EXPECT_TRUE(resource_released_); }
[email protected]0d7fb302014-01-23 21:30:471153
jaydasikabd6f15a2016-04-21 19:45:371154 protected:
1155 int texture_layer_id_;
1156
[email protected]0d7fb302014-01-23 21:30:471157 private:
danakj5df8257f2017-11-20 22:16:581158 bool resource_released_;
[email protected]0d7fb302014-01-23 21:30:471159};
1160
1161class TextureLayerReleaseResourcesAfterCommit
1162 : public TextureLayerReleaseResourcesBase {
1163 public:
dcheng716bedf2014-10-21 09:51:081164 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
kulkarni.a4015690f12014-10-10 13:50:061165 LayerTreeImpl* tree = nullptr;
danakj009cdfdf2015-02-17 22:35:141166 tree = host_impl->sync_tree();
jaydasikabd6f15a2016-04-21 19:45:371167 tree->LayerById(texture_layer_id_)->ReleaseResources();
[email protected]0d7fb302014-01-23 21:30:471168 }
1169};
1170
1171SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerReleaseResourcesAfterCommit);
1172
1173class TextureLayerReleaseResourcesAfterActivate
1174 : public TextureLayerReleaseResourcesBase {
1175 public:
dcheng716bedf2014-10-21 09:51:081176 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
jaydasikabd6f15a2016-04-21 19:45:371177 host_impl->active_tree()->LayerById(texture_layer_id_)->ReleaseResources();
[email protected]0d7fb302014-01-23 21:30:471178 }
1179};
1180
1181SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerReleaseResourcesAfterActivate);
1182
danakj5df8257f2017-11-20 22:16:581183class TextureLayerWithResourceMainThreadDeleted : public LayerTreeTest {
[email protected]9c2bd822013-07-26 12:30:171184 public:
dyencc16ed4d2015-11-03 20:03:041185 void ReleaseCallback(const gpu::SyncToken& sync_token, bool lost_resource) {
[email protected]9794fb32013-08-29 09:49:591186 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]9c2bd822013-07-26 12:30:171187 EXPECT_FALSE(lost_resource);
1188 ++callback_count_;
1189 EndTest();
1190 }
1191
1192 void SetMailbox(char mailbox_char) {
[email protected]9794fb32013-08-29 09:49:591193 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
Fady Samueldfecb7d2017-07-26 11:41:041194 std::unique_ptr<viz::SingleReleaseCallback> callback =
1195 viz::SingleReleaseCallback::Create(base::Bind(
danakj5df8257f2017-11-20 22:16:581196 &TextureLayerWithResourceMainThreadDeleted::ReleaseCallback,
[email protected]9c2bd822013-07-26 12:30:171197 base::Unretained(this)));
danakj5df8257f2017-11-20 22:16:581198 auto resource = viz::TransferableResource::MakeGL(
1199 MailboxFromChar(mailbox_char), GL_LINEAR, GL_TEXTURE_2D,
1200 SyncTokenFromUInt(static_cast<uint32_t>(mailbox_char)));
1201 layer_->SetTransferableResource(resource, std::move(callback));
[email protected]9c2bd822013-07-26 12:30:171202 }
1203
dcheng716bedf2014-10-21 09:51:081204 void SetupTree() override {
[email protected]9c2bd822013-07-26 12:30:171205 gfx::Size bounds(100, 100);
loyso0940d412016-03-14 01:30:311206 root_ = Layer::Create();
[email protected]9c2bd822013-07-26 12:30:171207 root_->SetBounds(bounds);
1208
loyso0940d412016-03-14 01:30:311209 layer_ = TextureLayer::CreateForMailbox(nullptr);
[email protected]9c2bd822013-07-26 12:30:171210 layer_->SetIsDrawable(true);
[email protected]9c2bd822013-07-26 12:30:171211 layer_->SetBounds(bounds);
1212
1213 root_->AddChild(layer_);
khushalsagarb69ba9452017-01-27 22:20:071214 layer_tree_host()->SetRootLayer(root_);
1215 layer_tree_host()->SetViewportSize(bounds);
[email protected]9c2bd822013-07-26 12:30:171216 }
1217
dcheng716bedf2014-10-21 09:51:081218 void BeginTest() override {
[email protected]9794fb32013-08-29 09:49:591219 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
1220
[email protected]9c2bd822013-07-26 12:30:171221 callback_count_ = 0;
1222
danakj5df8257f2017-11-20 22:16:581223 // Set the resource on the main thread.
[email protected]9c2bd822013-07-26 12:30:171224 SetMailbox('1');
1225 EXPECT_EQ(0, callback_count_);
1226
1227 PostSetNeedsCommitToMainThread();
1228 }
1229
dcheng716bedf2014-10-21 09:51:081230 void DidCommitAndDrawFrame() override {
khushalsagarcebe4942016-09-07 23:27:011231 switch (layer_tree_host()->SourceFrameNumber()) {
[email protected]9c2bd822013-07-26 12:30:171232 case 1:
danakj5df8257f2017-11-20 22:16:581233 // Delete the TextureLayer on the main thread while the resource is in
[email protected]9c2bd822013-07-26 12:30:171234 // the impl tree.
1235 layer_->RemoveFromParent();
kulkarni.a4015690f12014-10-10 13:50:061236 layer_ = nullptr;
[email protected]9c2bd822013-07-26 12:30:171237 break;
1238 }
1239 }
1240
dcheng716bedf2014-10-21 09:51:081241 void AfterTest() override { EXPECT_EQ(1, callback_count_); }
[email protected]9c2bd822013-07-26 12:30:171242
1243 private:
[email protected]9794fb32013-08-29 09:49:591244 base::ThreadChecker main_thread_;
[email protected]9c2bd822013-07-26 12:30:171245 int callback_count_;
1246 scoped_refptr<Layer> root_;
1247 scoped_refptr<TextureLayer> layer_;
1248};
1249
danakj5df8257f2017-11-20 22:16:581250SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerWithResourceMainThreadDeleted);
[email protected]9c2bd822013-07-26 12:30:171251
danakj5df8257f2017-11-20 22:16:581252class TextureLayerWithResourceImplThreadDeleted : public LayerTreeTest {
[email protected]9c2bd822013-07-26 12:30:171253 public:
dyencc16ed4d2015-11-03 20:03:041254 void ReleaseCallback(const gpu::SyncToken& sync_token, bool lost_resource) {
[email protected]9794fb32013-08-29 09:49:591255 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]9c2bd822013-07-26 12:30:171256 EXPECT_FALSE(lost_resource);
1257 ++callback_count_;
1258 EndTest();
1259 }
1260
1261 void SetMailbox(char mailbox_char) {
[email protected]9794fb32013-08-29 09:49:591262 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
Fady Samueldfecb7d2017-07-26 11:41:041263 std::unique_ptr<viz::SingleReleaseCallback> callback =
1264 viz::SingleReleaseCallback::Create(base::Bind(
danakj5df8257f2017-11-20 22:16:581265 &TextureLayerWithResourceImplThreadDeleted::ReleaseCallback,
[email protected]9c2bd822013-07-26 12:30:171266 base::Unretained(this)));
danakj5df8257f2017-11-20 22:16:581267 auto resource = viz::TransferableResource::MakeGL(
1268 MailboxFromChar(mailbox_char), GL_LINEAR, GL_TEXTURE_2D,
1269 SyncTokenFromUInt(static_cast<uint32_t>(mailbox_char)));
1270 layer_->SetTransferableResource(resource, std::move(callback));
[email protected]9c2bd822013-07-26 12:30:171271 }
1272
dcheng716bedf2014-10-21 09:51:081273 void SetupTree() override {
[email protected]9c2bd822013-07-26 12:30:171274 gfx::Size bounds(100, 100);
loyso0940d412016-03-14 01:30:311275 root_ = Layer::Create();
[email protected]9c2bd822013-07-26 12:30:171276 root_->SetBounds(bounds);
1277
loyso0940d412016-03-14 01:30:311278 layer_ = TextureLayer::CreateForMailbox(nullptr);
[email protected]9c2bd822013-07-26 12:30:171279 layer_->SetIsDrawable(true);
[email protected]9c2bd822013-07-26 12:30:171280 layer_->SetBounds(bounds);
1281
1282 root_->AddChild(layer_);
khushalsagarb69ba9452017-01-27 22:20:071283 layer_tree_host()->SetRootLayer(root_);
1284 layer_tree_host()->SetViewportSize(bounds);
[email protected]9c2bd822013-07-26 12:30:171285 }
1286
dcheng716bedf2014-10-21 09:51:081287 void BeginTest() override {
[email protected]9794fb32013-08-29 09:49:591288 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
1289
[email protected]9c2bd822013-07-26 12:30:171290 callback_count_ = 0;
1291
danakj5df8257f2017-11-20 22:16:581292 // Set the resource on the main thread.
[email protected]9c2bd822013-07-26 12:30:171293 SetMailbox('1');
1294 EXPECT_EQ(0, callback_count_);
1295
1296 PostSetNeedsCommitToMainThread();
1297 }
1298
dcheng716bedf2014-10-21 09:51:081299 void DidCommitAndDrawFrame() override {
khushalsagarcebe4942016-09-07 23:27:011300 switch (layer_tree_host()->SourceFrameNumber()) {
[email protected]9c2bd822013-07-26 12:30:171301 case 1:
danakj5df8257f2017-11-20 22:16:581302 // Remove the TextureLayer on the main thread while the resource is in
[email protected]9c2bd822013-07-26 12:30:171303 // the impl tree, but don't delete the TextureLayer until after the impl
1304 // tree side is deleted.
1305 layer_->RemoveFromParent();
1306 break;
1307 case 2:
kulkarni.a4015690f12014-10-10 13:50:061308 layer_ = nullptr;
[email protected]9c2bd822013-07-26 12:30:171309 break;
1310 }
1311 }
1312
dcheng716bedf2014-10-21 09:51:081313 void AfterTest() override { EXPECT_EQ(1, callback_count_); }
[email protected]9c2bd822013-07-26 12:30:171314
1315 private:
[email protected]9794fb32013-08-29 09:49:591316 base::ThreadChecker main_thread_;
[email protected]9c2bd822013-07-26 12:30:171317 int callback_count_;
1318 scoped_refptr<Layer> root_;
1319 scoped_refptr<TextureLayer> layer_;
1320};
1321
danakj5df8257f2017-11-20 22:16:581322SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerWithResourceImplThreadDeleted);
[email protected]9c2bd822013-07-26 12:30:171323
[email protected]ba565742012-11-10 09:29:481324} // namespace
1325} // namespace cc