blob: 998ee16bba962b1e936e57f94b27787574515497 [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"
Victor Miura29b7ea3d2017-12-19 20:23:5941#include "components/viz/common/gpu/raster_context_provider.h"
Fady Samuel4f7f0fb32017-07-28 15:33:3742#include "components/viz/common/resources/returned_resource.h"
danakj6b082cc2017-11-20 22:32:1243#include "components/viz/common/resources/transferable_resource.h"
danakjc391f332017-07-12 20:45:5244#include "components/viz/test/test_layer_tree_frame_sink.h"
[email protected]0bf5a202013-07-10 14:50:5445#include "gpu/GLES2/gl2extchromium.h"
[email protected]7f0c53db2012-10-02 00:23:1846#include "testing/gmock/include/gmock/gmock.h"
47#include "testing/gtest/include/gtest/gtest.h"
[email protected]c0dd24c2012-08-30 23:25:2748
[email protected]c0dd24c2012-08-30 23:25:2749using ::testing::Mock;
50using ::testing::_;
51using ::testing::AtLeast;
52using ::testing::AnyNumber;
[email protected]d72d9e02014-04-03 18:40:0953using ::testing::InvokeWithoutArgs;
[email protected]c0dd24c2012-08-30 23:25:2754
[email protected]ba565742012-11-10 09:29:4855namespace cc {
[email protected]c0dd24c2012-08-30 23:25:2756namespace {
57
[email protected]e0a4d732014-02-15 00:23:2658gpu::Mailbox MailboxFromChar(char value) {
[email protected]df41e252014-02-03 23:39:5059 gpu::Mailbox mailbox;
[email protected]e0a4d732014-02-15 00:23:2660 memset(mailbox.name, value, sizeof(mailbox.name));
[email protected]df41e252014-02-03 23:39:5061 return mailbox;
62}
63
dyen398dd0142016-01-21 22:05:5664gpu::SyncToken SyncTokenFromUInt(uint32_t value) {
lukasza2573ce7d2016-02-16 19:17:2265 return gpu::SyncToken(gpu::CommandBufferNamespace::GPU_IO, 0,
66 gpu::CommandBufferId::FromUnsafeValue(0x123), value);
dyen398dd0142016-01-21 22:05:5667}
68
khushalsagare0e4486e2017-01-25 03:15:0369class MockLayerTreeHost : public LayerTreeHost {
[email protected]28571b042013-03-14 07:59:1570 public:
danakj60bc3bc2016-04-09 00:24:4871 static std::unique_ptr<MockLayerTreeHost> Create(
danakjcf610582015-06-16 22:48:5672 FakeLayerTreeHostClient* client,
loyso2cb3f32f2016-11-08 07:08:3473 TaskGraphRunner* task_graph_runner,
74 MutatorHost* mutator_host) {
khushalsagare0e4486e2017-01-25 03:15:0375 LayerTreeHost::InitParams params;
sadrul6780f3da2015-05-11 17:01:5276 params.client = client;
danakjcf610582015-06-16 22:48:5677 params.task_graph_runner = task_graph_runner;
loyso2cb3f32f2016-11-08 07:08:3478 params.mutator_host = mutator_host;
sadrul6780f3da2015-05-11 17:01:5279 LayerTreeSettings settings;
80 params.settings = &settings;
danakjffc181a2016-07-22 22:48:4381 return base::WrapUnique(new MockLayerTreeHost(&params));
[email protected]28571b042013-03-14 07:59:1582 }
[email protected]c0dd24c2012-08-30 23:25:2783
[email protected]28571b042013-03-14 07:59:1584 MOCK_METHOD0(SetNeedsCommit, void());
[email protected]aeeb3372013-11-05 14:05:5485 MOCK_METHOD0(StartRateLimiter, void());
86 MOCK_METHOD0(StopRateLimiter, void());
sadrul6780f3da2015-05-11 17:01:5287
88 private:
khushalsagare0e4486e2017-01-25 03:15:0389 explicit MockLayerTreeHost(LayerTreeHost::InitParams* params)
90 : LayerTreeHost(params, CompositorMode::SINGLE_THREADED) {
danakjffc181a2016-07-22 22:48:4391 InitializeSingleThreaded(&single_thread_client_,
enne2b0ad682016-09-21 01:44:4792 base::ThreadTaskRunnerHandle::Get());
sadrul6780f3da2015-05-11 17:01:5293 }
danakjffc181a2016-07-22 22:48:4394
95 StubLayerTreeHostSingleThreadClient single_thread_client_;
[email protected]c0dd24c2012-08-30 23:25:2796};
97
danakj5df8257f2017-11-20 22:16:5898class MockReleaseCallback {
[email protected]d72d9e02014-04-03 18:40:0999 public:
100 MOCK_METHOD3(Release,
101 void(const gpu::Mailbox& mailbox,
dyencc16ed4d2015-11-03 20:03:04102 const gpu::SyncToken& sync_token,
[email protected]d72d9e02014-04-03 18:40:09103 bool lost_resource));
104 MOCK_METHOD3(Release2,
Fady Samuel4b5f9862017-07-11 05:27:20105 void(viz::SharedBitmap* shared_bitmap,
dyencc16ed4d2015-11-03 20:03:04106 const gpu::SyncToken& sync_token,
[email protected]d72d9e02014-04-03 18:40:09107 bool lost_resource));
108};
109
danakj5df8257f2017-11-20 22:16:58110struct CommonResourceObjects {
111 explicit CommonResourceObjects(viz::SharedBitmapManager* manager)
[email protected]d72d9e02014-04-03 18:40:09112 : mailbox_name1_(MailboxFromChar('1')),
113 mailbox_name2_(MailboxFromChar('2')),
lukasza2573ce7d2016-02-16 19:17:22114 sync_token1_(gpu::CommandBufferNamespace::GPU_IO,
115 123,
116 gpu::CommandBufferId::FromUnsafeValue(0x234),
117 1),
118 sync_token2_(gpu::CommandBufferNamespace::GPU_IO,
119 123,
120 gpu::CommandBufferId::FromUnsafeValue(0x234),
121 2) {
danakj5df8257f2017-11-20 22:16:58122 release_callback1_ =
123 base::Bind(&MockReleaseCallback::Release,
124 base::Unretained(&mock_callback_), mailbox_name1_);
125 release_callback2_ =
126 base::Bind(&MockReleaseCallback::Release,
127 base::Unretained(&mock_callback_), mailbox_name2_);
avi02a4d172015-12-21 06:14:36128 const uint32_t arbitrary_target1 = GL_TEXTURE_2D;
129 const uint32_t arbitrary_target2 = GL_TEXTURE_EXTERNAL_OES;
danakj5df8257f2017-11-20 22:16:58130 resource1_ = viz::TransferableResource::MakeGL(
131 mailbox_name1_, GL_LINEAR, arbitrary_target1, sync_token1_);
132 resource2_ = viz::TransferableResource::MakeGL(
133 mailbox_name2_, GL_LINEAR, arbitrary_target2, sync_token2_);
[email protected]d72d9e02014-04-03 18:40:09134 gfx::Size size(128, 128);
jbauman9015c8b2014-12-11 00:49:37135 shared_bitmap_ = manager->AllocateSharedBitmap(size);
136 DCHECK(shared_bitmap_);
danakj5df8257f2017-11-20 22:16:58137 release_callback3_ =
138 base::Bind(&MockReleaseCallback::Release2,
jbauman9015c8b2014-12-11 00:49:37139 base::Unretained(&mock_callback_), shared_bitmap_.get());
danakj5df8257f2017-11-20 22:16:58140 resource3_ = viz::TransferableResource::MakeSoftware(
141 shared_bitmap_->id(), shared_bitmap_->sequence_number(), size);
[email protected]d72d9e02014-04-03 18:40:09142 }
143
tzik736175f2017-11-15 13:39:24144 using RepeatingReleaseCallback =
145 base::RepeatingCallback<void(const gpu::SyncToken& sync_token,
146 bool is_lost)>;
147
[email protected]d72d9e02014-04-03 18:40:09148 gpu::Mailbox mailbox_name1_;
149 gpu::Mailbox mailbox_name2_;
danakj5df8257f2017-11-20 22:16:58150 MockReleaseCallback mock_callback_;
151 RepeatingReleaseCallback release_callback1_;
152 RepeatingReleaseCallback release_callback2_;
153 RepeatingReleaseCallback release_callback3_;
dyencc16ed4d2015-11-03 20:03:04154 gpu::SyncToken sync_token1_;
155 gpu::SyncToken sync_token2_;
Fady Samuel4b5f9862017-07-11 05:27:20156 std::unique_ptr<viz::SharedBitmap> shared_bitmap_;
danakj5df8257f2017-11-20 22:16:58157 viz::TransferableResource resource1_;
158 viz::TransferableResource resource2_;
159 viz::TransferableResource resource3_;
[email protected]d72d9e02014-04-03 18:40:09160};
161
[email protected]31d4df82013-07-18 10:17:22162class TextureLayerTest : public testing::Test {
163 public:
164 TextureLayerTest()
danakjc7afae52017-06-20 21:12:41165 : layer_tree_frame_sink_(FakeLayerTreeFrameSink::Create3d()),
166 host_impl_(&task_runner_provider_, &task_graph_runner_),
jbauman9015c8b2014-12-11 00:49:37167 test_data_(&shared_bitmap_manager_) {}
[email protected]31d4df82013-07-18 10:17:22168
169 protected:
dcheng93a52eb2014-12-23 02:14:23170 void SetUp() override {
loyso2cb3f32f2016-11-08 07:08:34171 animation_host_ = AnimationHost::CreateForTesting(ThreadInstance::MAIN);
172 layer_tree_host_ = MockLayerTreeHost::Create(
173 &fake_client_, &task_graph_runner_, animation_host_.get());
[email protected]d72d9e02014-04-03 18:40:09174 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
khushalsagarb69ba9452017-01-27 22:20:07175 layer_tree_host_->SetViewportSize(gfx::Size(10, 10));
[email protected]d72d9e02014-04-03 18:40:09176 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
[email protected]31d4df82013-07-18 10:17:22177 }
178
dcheng93a52eb2014-12-23 02:14:23179 void TearDown() override {
[email protected]31d4df82013-07-18 10:17:22180 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
[email protected]31d4df82013-07-18 10:17:22181 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
182
loyso2cb3f32f2016-11-08 07:08:34183 animation_host_->SetMutatorHostClient(nullptr);
khushalsagarb69ba9452017-01-27 22:20:07184 layer_tree_host_->SetRootLayer(nullptr);
danakjf446a072014-09-27 21:55:48185 layer_tree_host_ = nullptr;
loyso2cb3f32f2016-11-08 07:08:34186 animation_host_ = nullptr;
[email protected]31d4df82013-07-18 10:17:22187 }
188
danakj60bc3bc2016-04-09 00:24:48189 std::unique_ptr<MockLayerTreeHost> layer_tree_host_;
loyso2cb3f32f2016-11-08 07:08:34190 std::unique_ptr<AnimationHost> animation_host_;
khushalsagarb64b360d2015-10-21 19:25:16191 FakeImplTaskRunnerProvider task_runner_provider_;
[email protected]31d4df82013-07-18 10:17:22192 FakeLayerTreeHostClient fake_client_;
[email protected]4e2eb352014-03-20 17:25:45193 TestSharedBitmapManager shared_bitmap_manager_;
reveman34b7a1522015-03-23 20:27:47194 TestTaskGraphRunner task_graph_runner_;
danakjc7afae52017-06-20 21:12:41195 std::unique_ptr<LayerTreeFrameSink> layer_tree_frame_sink_;
[email protected]31d4df82013-07-18 10:17:22196 FakeLayerTreeHostImpl host_impl_;
danakj5df8257f2017-11-20 22:16:58197 CommonResourceObjects test_data_;
[email protected]31d4df82013-07-18 10:17:22198};
199
[email protected]31d4df82013-07-18 10:17:22200TEST_F(TextureLayerTest, CheckPropertyChangeCausesCorrectBehavior) {
kulkarni.a4015690f12014-10-10 13:50:06201 scoped_refptr<TextureLayer> test_layer =
loyso0940d412016-03-14 01:30:31202 TextureLayer::CreateForMailbox(nullptr);
khushalsagarb69ba9452017-01-27 22:20:07203 EXPECT_SET_NEEDS_COMMIT(1, layer_tree_host_->SetRootLayer(test_layer));
[email protected]31d4df82013-07-18 10:17:22204
205 // Test properties that should call SetNeedsCommit. All properties need to
206 // be set to new values in order for SetNeedsCommit to be called.
207 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetFlipped(false));
jackhou10c9af42014-12-04 05:24:44208 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetNearestNeighbor(true));
[email protected]31d4df82013-07-18 10:17:22209 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetUV(
210 gfx::PointF(0.25f, 0.25f), gfx::PointF(0.75f, 0.75f)));
211 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetVertexOpacity(
212 0.5f, 0.5f, 0.5f, 0.5f));
213 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetPremultipliedAlpha(false));
214 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetBlendBackgroundColor(true));
[email protected]31d4df82013-07-18 10:17:22215}
216
danakj7fb2f142017-11-21 01:36:15217class TestMailboxHolder : public TextureLayer::TransferableResourceHolder {
[email protected]9794fb32013-08-29 09:49:59218 public:
danakj7fb2f142017-11-21 01:36:15219 using TextureLayer::TransferableResourceHolder::Create;
[email protected]9794fb32013-08-29 09:49:59220
221 protected:
Chris Watkinsf6353292017-12-04 02:36:05222 ~TestMailboxHolder() override = default;
[email protected]9794fb32013-08-29 09:49:59223};
224
danakj5df8257f2017-11-20 22:16:58225class TextureLayerWithResourceTest : public TextureLayerTest {
[email protected]28571b042013-03-14 07:59:15226 protected:
dcheng93a52eb2014-12-23 02:14:23227 void TearDown() override {
[email protected]28571b042013-03-14 07:59:15228 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
dyencc16ed4d2015-11-03 20:03:04229 EXPECT_CALL(
230 test_data_.mock_callback_,
231 Release(test_data_.mailbox_name1_, test_data_.sync_token1_, false))
232 .Times(1);
[email protected]28571b042013-03-14 07:59:15233 TextureLayerTest::TearDown();
234 }
[email protected]de44a152013-01-08 15:28:46235};
236
danakj5df8257f2017-11-20 22:16:58237TEST_F(TextureLayerWithResourceTest, ReplaceMailboxOnMainThreadBeforeCommit) {
kulkarni.a4015690f12014-10-10 13:50:06238 scoped_refptr<TextureLayer> test_layer =
loyso0940d412016-03-14 01:30:31239 TextureLayer::CreateForMailbox(nullptr);
[email protected]22898ed2013-06-01 04:52:30240 ASSERT_TRUE(test_layer.get());
[email protected]de44a152013-01-08 15:28:46241
[email protected]28571b042013-03-14 07:59:15242 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
khushalsagarb69ba9452017-01-27 22:20:07243 layer_tree_host_->SetRootLayer(test_layer);
[email protected]28571b042013-03-14 07:59:15244 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
[email protected]de44a152013-01-08 15:28:46245
[email protected]28571b042013-03-14 07:59:15246 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
danakj5df8257f2017-11-20 22:16:58247 test_layer->SetTransferableResource(
248 test_data_.resource1_,
249 viz::SingleReleaseCallback::Create(test_data_.release_callback1_));
[email protected]28571b042013-03-14 07:59:15250 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
[email protected]de44a152013-01-08 15:28:46251
[email protected]28571b042013-03-14 07:59:15252 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
dyencc16ed4d2015-11-03 20:03:04253 EXPECT_CALL(
254 test_data_.mock_callback_,
255 Release(test_data_.mailbox_name1_, test_data_.sync_token1_, false))
[email protected]28571b042013-03-14 07:59:15256 .Times(1);
danakj5df8257f2017-11-20 22:16:58257 test_layer->SetTransferableResource(
258 test_data_.resource2_,
259 viz::SingleReleaseCallback::Create(test_data_.release_callback2_));
[email protected]28571b042013-03-14 07:59:15260 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
261 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]de44a152013-01-08 15:28:46262
[email protected]28571b042013-03-14 07:59:15263 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
dyencc16ed4d2015-11-03 20:03:04264 EXPECT_CALL(
265 test_data_.mock_callback_,
266 Release(test_data_.mailbox_name2_, test_data_.sync_token2_, false))
[email protected]28571b042013-03-14 07:59:15267 .Times(1);
danakj5df8257f2017-11-20 22:16:58268 test_layer->ClearTexture();
[email protected]28571b042013-03-14 07:59:15269 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
270 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]de44a152013-01-08 15:28:46271
[email protected]80d42bd2013-08-30 19:13:45272 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
danakj5df8257f2017-11-20 22:16:58273 test_layer->SetTransferableResource(
274 test_data_.resource3_,
275 viz::SingleReleaseCallback::Create(test_data_.release_callback3_));
[email protected]42f40a52013-06-08 04:38:51276 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
277 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
278
[email protected]42f40a52013-06-08 04:38:51279 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
280 EXPECT_CALL(test_data_.mock_callback_,
dyencc16ed4d2015-11-03 20:03:04281 Release2(test_data_.shared_bitmap_.get(), _, false))
282 .Times(1);
danakj5df8257f2017-11-20 22:16:58283 test_layer->ClearTexture();
[email protected]42f40a52013-06-08 04:38:51284 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
285 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
286
[email protected]28571b042013-03-14 07:59:15287 // Test destructor.
288 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
danakj5df8257f2017-11-20 22:16:58289 test_layer->SetTransferableResource(
290 test_data_.resource1_,
291 viz::SingleReleaseCallback::Create(test_data_.release_callback1_));
[email protected]de44a152013-01-08 15:28:46292}
293
[email protected]9794fb32013-08-29 09:49:59294class TextureLayerMailboxHolderTest : public TextureLayerTest {
295 public:
296 TextureLayerMailboxHolderTest()
297 : main_thread_("MAIN") {
298 main_thread_.Start();
299 }
300
301 void Wait(const base::Thread& thread) {
gabcca53112016-06-08 20:13:28302 base::WaitableEvent event(base::WaitableEvent::ResetPolicy::AUTOMATIC,
303 base::WaitableEvent::InitialState::NOT_SIGNALED);
fdoray70df5a92016-06-22 21:13:59304 thread.task_runner()->PostTask(
[email protected]9794fb32013-08-29 09:49:59305 FROM_HERE,
tzik4604bb52017-04-13 21:50:22306 base::BindOnce(&base::WaitableEvent::Signal, base::Unretained(&event)));
[email protected]9794fb32013-08-29 09:49:59307 event.Wait();
308 }
309
310 void CreateMainRef() {
311 main_ref_ = TestMailboxHolder::Create(
danakj5df8257f2017-11-20 22:16:58312 test_data_.resource1_,
313 viz::SingleReleaseCallback::Create(test_data_.release_callback1_));
[email protected]9794fb32013-08-29 09:49:59314 }
315
danakjf446a072014-09-27 21:55:48316 void ReleaseMainRef() { main_ref_ = nullptr; }
[email protected]9794fb32013-08-29 09:49:59317
danakjcde8e4c32017-09-25 18:33:47318 void CreateImplRef(
319 std::unique_ptr<viz::SingleReleaseCallback>* impl_ref,
320 scoped_refptr<base::SequencedTaskRunner> main_thread_task_runner) {
321 *impl_ref = main_ref_->holder()->GetCallbackForImplThread(
322 std::move(main_thread_task_runner));
[email protected]9794fb32013-08-29 09:49:59323 }
324
325 protected:
danakj60bc3bc2016-04-09 00:24:48326 std::unique_ptr<TestMailboxHolder::MainThreadReference> main_ref_;
[email protected]9794fb32013-08-29 09:49:59327 base::Thread main_thread_;
[email protected]9794fb32013-08-29 09:49:59328};
329
330TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_BothReleaseThenMain) {
kulkarni.a4015690f12014-10-10 13:50:06331 scoped_refptr<TextureLayer> test_layer =
loyso0940d412016-03-14 01:30:31332 TextureLayer::CreateForMailbox(nullptr);
[email protected]9794fb32013-08-29 09:49:59333 ASSERT_TRUE(test_layer.get());
334
fdoray70df5a92016-06-22 21:13:59335 main_thread_.task_runner()->PostTask(
tzik4604bb52017-04-13 21:50:22336 FROM_HERE, base::BindOnce(&TextureLayerMailboxHolderTest::CreateMainRef,
337 base::Unretained(this)));
[email protected]9794fb32013-08-29 09:49:59338
339 Wait(main_thread_);
340
341 // The texture layer is attached to compositor1, and passes a reference to its
342 // impl tree.
danakjcde8e4c32017-09-25 18:33:47343 std::unique_ptr<viz::SingleReleaseCallback> compositor1;
fdoray70df5a92016-06-22 21:13:59344 main_thread_.task_runner()->PostTask(
tzik4604bb52017-04-13 21:50:22345 FROM_HERE, base::BindOnce(&TextureLayerMailboxHolderTest::CreateImplRef,
danakjcde8e4c32017-09-25 18:33:47346 base::Unretained(this), &compositor1,
347 main_thread_.task_runner()));
[email protected]9794fb32013-08-29 09:49:59348
349 // Then the texture layer is removed and attached to compositor2, and passes a
350 // reference to its impl tree.
danakjcde8e4c32017-09-25 18:33:47351 std::unique_ptr<viz::SingleReleaseCallback> compositor2;
fdoray70df5a92016-06-22 21:13:59352 main_thread_.task_runner()->PostTask(
tzik4604bb52017-04-13 21:50:22353 FROM_HERE, base::BindOnce(&TextureLayerMailboxHolderTest::CreateImplRef,
danakjcde8e4c32017-09-25 18:33:47354 base::Unretained(this), &compositor2,
355 main_thread_.task_runner()));
[email protected]9794fb32013-08-29 09:49:59356
357 Wait(main_thread_);
358 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
359
360 // The compositors both destroy their impl trees before the main thread layer
361 // is destroyed.
danakjcde8e4c32017-09-25 18:33:47362 compositor1->Run(SyncTokenFromUInt(100), false);
363 compositor2->Run(SyncTokenFromUInt(200), false);
[email protected]9794fb32013-08-29 09:49:59364
365 Wait(main_thread_);
366
367 EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0);
368 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
369
danakj5df8257f2017-11-20 22:16:58370 // The main thread ref is the last one, so the resource is released back to
371 // the embedder, with the last sync point provided by the impl trees.
[email protected]9794fb32013-08-29 09:49:59372 EXPECT_CALL(test_data_.mock_callback_,
dyen398dd0142016-01-21 22:05:56373 Release(test_data_.mailbox_name1_, SyncTokenFromUInt(200), false))
dyencc16ed4d2015-11-03 20:03:04374 .Times(1);
[email protected]9794fb32013-08-29 09:49:59375
fdoray70df5a92016-06-22 21:13:59376 main_thread_.task_runner()->PostTask(
tzik4604bb52017-04-13 21:50:22377 FROM_HERE, base::BindOnce(&TextureLayerMailboxHolderTest::ReleaseMainRef,
378 base::Unretained(this)));
[email protected]9794fb32013-08-29 09:49:59379 Wait(main_thread_);
380 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
381}
382
383TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_MainReleaseBetween) {
kulkarni.a4015690f12014-10-10 13:50:06384 scoped_refptr<TextureLayer> test_layer =
loyso0940d412016-03-14 01:30:31385 TextureLayer::CreateForMailbox(nullptr);
[email protected]9794fb32013-08-29 09:49:59386 ASSERT_TRUE(test_layer.get());
387
fdoray70df5a92016-06-22 21:13:59388 main_thread_.task_runner()->PostTask(
tzik4604bb52017-04-13 21:50:22389 FROM_HERE, base::BindOnce(&TextureLayerMailboxHolderTest::CreateMainRef,
390 base::Unretained(this)));
[email protected]9794fb32013-08-29 09:49:59391
392 Wait(main_thread_);
393
394 // The texture layer is attached to compositor1, and passes a reference to its
395 // impl tree.
danakjcde8e4c32017-09-25 18:33:47396 std::unique_ptr<viz::SingleReleaseCallback> compositor1;
fdoray70df5a92016-06-22 21:13:59397 main_thread_.task_runner()->PostTask(
tzik4604bb52017-04-13 21:50:22398 FROM_HERE, base::BindOnce(&TextureLayerMailboxHolderTest::CreateImplRef,
danakjcde8e4c32017-09-25 18:33:47399 base::Unretained(this), &compositor1,
400 main_thread_.task_runner()));
[email protected]9794fb32013-08-29 09:49:59401
402 // Then the texture layer is removed and attached to compositor2, and passes a
403 // reference to its impl tree.
danakjcde8e4c32017-09-25 18:33:47404 std::unique_ptr<viz::SingleReleaseCallback> compositor2;
fdoray70df5a92016-06-22 21:13:59405 main_thread_.task_runner()->PostTask(
tzik4604bb52017-04-13 21:50:22406 FROM_HERE, base::BindOnce(&TextureLayerMailboxHolderTest::CreateImplRef,
danakjcde8e4c32017-09-25 18:33:47407 base::Unretained(this), &compositor2,
408 main_thread_.task_runner()));
[email protected]9794fb32013-08-29 09:49:59409
410 Wait(main_thread_);
411 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
412
413 // One compositor destroys their impl tree.
danakjcde8e4c32017-09-25 18:33:47414 compositor1->Run(SyncTokenFromUInt(100), false);
[email protected]9794fb32013-08-29 09:49:59415
416 // Then the main thread reference is destroyed.
fdoray70df5a92016-06-22 21:13:59417 main_thread_.task_runner()->PostTask(
tzik4604bb52017-04-13 21:50:22418 FROM_HERE, base::BindOnce(&TextureLayerMailboxHolderTest::ReleaseMainRef,
419 base::Unretained(this)));
[email protected]9794fb32013-08-29 09:49:59420
421 Wait(main_thread_);
422
423 EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0);
424 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
425
danakj5df8257f2017-11-20 22:16:58426 // The second impl reference is destroyed last, causing the resource to be
[email protected]9794fb32013-08-29 09:49:59427 // released back to the embedder with the last sync point from the impl tree.
428 EXPECT_CALL(test_data_.mock_callback_,
dyen398dd0142016-01-21 22:05:56429 Release(test_data_.mailbox_name1_, SyncTokenFromUInt(200), true))
dyencc16ed4d2015-11-03 20:03:04430 .Times(1);
[email protected]9794fb32013-08-29 09:49:59431
danakjcde8e4c32017-09-25 18:33:47432 compositor2->Run(SyncTokenFromUInt(200), true);
[email protected]9794fb32013-08-29 09:49:59433 Wait(main_thread_);
434 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
435}
436
437TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_MainReleasedFirst) {
kulkarni.a4015690f12014-10-10 13:50:06438 scoped_refptr<TextureLayer> test_layer =
loyso0940d412016-03-14 01:30:31439 TextureLayer::CreateForMailbox(nullptr);
[email protected]9794fb32013-08-29 09:49:59440 ASSERT_TRUE(test_layer.get());
441
fdoray70df5a92016-06-22 21:13:59442 main_thread_.task_runner()->PostTask(
tzik4604bb52017-04-13 21:50:22443 FROM_HERE, base::BindOnce(&TextureLayerMailboxHolderTest::CreateMainRef,
444 base::Unretained(this)));
[email protected]9794fb32013-08-29 09:49:59445
446 Wait(main_thread_);
447
448 // The texture layer is attached to compositor1, and passes a reference to its
449 // impl tree.
danakjcde8e4c32017-09-25 18:33:47450 std::unique_ptr<viz::SingleReleaseCallback> compositor1;
fdoray70df5a92016-06-22 21:13:59451 main_thread_.task_runner()->PostTask(
tzik4604bb52017-04-13 21:50:22452 FROM_HERE, base::BindOnce(&TextureLayerMailboxHolderTest::CreateImplRef,
danakjcde8e4c32017-09-25 18:33:47453 base::Unretained(this), &compositor1,
454 main_thread_.task_runner()));
[email protected]9794fb32013-08-29 09:49:59455
456 // Then the texture layer is removed and attached to compositor2, and passes a
457 // reference to its impl tree.
danakjcde8e4c32017-09-25 18:33:47458 std::unique_ptr<viz::SingleReleaseCallback> compositor2;
fdoray70df5a92016-06-22 21:13:59459 main_thread_.task_runner()->PostTask(
tzik4604bb52017-04-13 21:50:22460 FROM_HERE, base::BindOnce(&TextureLayerMailboxHolderTest::CreateImplRef,
danakjcde8e4c32017-09-25 18:33:47461 base::Unretained(this), &compositor2,
462 main_thread_.task_runner()));
[email protected]9794fb32013-08-29 09:49:59463
464 Wait(main_thread_);
465 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
466
467 // The main thread reference is destroyed first.
fdoray70df5a92016-06-22 21:13:59468 main_thread_.task_runner()->PostTask(
tzik4604bb52017-04-13 21:50:22469 FROM_HERE, base::BindOnce(&TextureLayerMailboxHolderTest::ReleaseMainRef,
470 base::Unretained(this)));
[email protected]9794fb32013-08-29 09:49:59471
472 // One compositor destroys their impl tree.
danakjcde8e4c32017-09-25 18:33:47473 compositor2->Run(SyncTokenFromUInt(200), false);
[email protected]9794fb32013-08-29 09:49:59474
475 Wait(main_thread_);
476
477 EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0);
478 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
479
danakj5df8257f2017-11-20 22:16:58480 // The second impl reference is destroyed last, causing the resource to be
[email protected]9794fb32013-08-29 09:49:59481 // released back to the embedder with the last sync point from the impl tree.
482 EXPECT_CALL(test_data_.mock_callback_,
dyen398dd0142016-01-21 22:05:56483 Release(test_data_.mailbox_name1_, SyncTokenFromUInt(100), true))
dyencc16ed4d2015-11-03 20:03:04484 .Times(1);
[email protected]9794fb32013-08-29 09:49:59485
danakjcde8e4c32017-09-25 18:33:47486 compositor1->Run(SyncTokenFromUInt(100), true);
[email protected]9794fb32013-08-29 09:49:59487 Wait(main_thread_);
488 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
489}
490
[email protected]e216fef02013-03-20 22:56:10491class TextureLayerImplWithMailboxThreadedCallback : public LayerTreeTest {
[email protected]28571b042013-03-14 07:59:15492 public:
danakjc391f332017-07-12 20:45:52493 std::unique_ptr<viz::TestLayerTreeFrameSink> CreateLayerTreeFrameSink(
Alex Zhangbcce8b132017-07-20 20:17:24494 const viz::RendererSettings& renderer_settings,
Alex Zhang903cb6a2017-06-12 20:31:37495 double refresh_rate,
Xu Xing32549162017-07-17 22:25:43496 scoped_refptr<viz::ContextProvider> compositor_context_provider,
Victor Miura29b7ea3d2017-12-19 20:23:59497 scoped_refptr<viz::RasterContextProvider> worker_context_provider)
498 override {
staraz88677422017-05-26 13:53:03499 constexpr bool disable_display_vsync = false;
danakj014316e2016-08-04 18:40:26500 bool synchronous_composite =
501 !HasImplThread() &&
khushalsagarcebe4942016-09-07 23:27:01502 !layer_tree_host()->GetSettings().single_thread_proxy_scheduler;
Jeremy Roman909d927b2017-08-27 18:34:09503 return std::make_unique<viz::TestLayerTreeFrameSink>(
danakj014316e2016-08-04 18:40:26504 compositor_context_provider, std::move(worker_context_provider),
staraz88677422017-05-26 13:53:03505 shared_bitmap_manager(), gpu_memory_buffer_manager(), renderer_settings,
Alex Zhang903cb6a2017-06-12 20:31:37506 ImplThreadTaskRunner(), synchronous_composite, disable_display_vsync,
507 refresh_rate);
danakj014316e2016-08-04 18:40:26508 }
[email protected]28571b042013-03-14 07:59:15509
ericrkad5923812017-01-25 23:26:12510 void AdvanceTestCase() {
511 ++test_case_;
512 switch (test_case_) {
513 case 1:
danakj5df8257f2017-11-20 22:16:58514 // Case #1: change resource before the commit. The old resource should
515 // be released immediately.
ericrkad5923812017-01-25 23:26:12516 SetMailbox('2');
517 EXPECT_EQ(1, callback_count_);
518 PostSetNeedsCommitToMainThread();
519
520 // Case 2 does not rely on callbacks to advance.
521 pending_callback_ = false;
522 break;
523 case 2:
danakj5df8257f2017-11-20 22:16:58524 // Case #2: change resource after the commit (and draw), where the
525 // layer draws. The old resource should be released during the next
ericrkad5923812017-01-25 23:26:12526 // commit.
527 SetMailbox('3');
528 EXPECT_EQ(1, callback_count_);
529
530 // Cases 3-5 rely on a callback to advance.
531 pending_callback_ = true;
532 break;
533 case 3:
534 EXPECT_EQ(2, callback_count_);
danakj5df8257f2017-11-20 22:16:58535 // Case #3: change resource when the layer doesn't draw. The old
536 // resource should be released during the next commit.
ericrkad5923812017-01-25 23:26:12537 layer_->SetBounds(gfx::Size());
538 SetMailbox('4');
539 break;
540 case 4:
541 EXPECT_EQ(3, callback_count_);
danakj5df8257f2017-11-20 22:16:58542 // Case #4: release resource that was committed but never drawn. The
543 // old resource should be released during the next commit.
544 layer_->ClearTexture();
ericrkad5923812017-01-25 23:26:12545 break;
546 case 5:
547 EXPECT_EQ(4, callback_count_);
danakj5df8257f2017-11-20 22:16:58548 // Restore a resource for the next step.
ericrkad5923812017-01-25 23:26:12549 SetMailbox('5');
550
551 // Cases 6 and 7 do not rely on callbacks to advance.
552 pending_callback_ = false;
553 break;
554 case 6:
555 // Case #5: remove layer from tree. Callback should *not* be called, the
danakj5df8257f2017-11-20 22:16:58556 // resource is returned to the main thread.
ericrkad5923812017-01-25 23:26:12557 EXPECT_EQ(4, callback_count_);
558 layer_->RemoveFromParent();
559 break;
560 case 7:
561 EXPECT_EQ(4, callback_count_);
danakj5df8257f2017-11-20 22:16:58562 // Resetting the resource will call the callback now, before another
danakjcde8e4c32017-09-25 18:33:47563 // commit is needed, as the ReleaseCallback is already in flight from
564 // RemoveFromParent().
danakj5df8257f2017-11-20 22:16:58565 layer_->ClearTexture();
danakjcde8e4c32017-09-25 18:33:47566 pending_callback_ = true;
567 frame_number_ = layer_tree_host()->SourceFrameNumber();
568 break;
569 case 8:
570 // A commit wasn't needed, the ReleaseCallback was already in flight.
571 EXPECT_EQ(frame_number_, layer_tree_host()->SourceFrameNumber());
ericrkad5923812017-01-25 23:26:12572 EXPECT_EQ(5, callback_count_);
573 EndTest();
574 break;
575 default:
576 NOTREACHED();
577 break;
578 }
579 }
580
[email protected]28571b042013-03-14 07:59:15581 // Make sure callback is received on main and doesn't block the impl thread.
danakj014316e2016-08-04 18:40:26582 void ReleaseCallback(char mailbox_char,
583 const gpu::SyncToken& sync_token,
584 bool lost_resource) {
[email protected]9794fb32013-08-29 09:49:59585 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]7ba3ca72013-04-11 06:37:25586 EXPECT_FALSE(lost_resource);
[email protected]28571b042013-03-14 07:59:15587 ++callback_count_;
ericrkad5923812017-01-25 23:26:12588
589 // If we are waiting on a callback, advance now.
590 if (pending_callback_)
591 AdvanceTestCase();
[email protected]28571b042013-03-14 07:59:15592 }
593
594 void SetMailbox(char mailbox_char) {
[email protected]9794fb32013-08-29 09:49:59595 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
Fady Samueldfecb7d2017-07-26 11:41:04596 std::unique_ptr<viz::SingleReleaseCallback> callback =
597 viz::SingleReleaseCallback::Create(base::Bind(
[email protected]28571b042013-03-14 07:59:15598 &TextureLayerImplWithMailboxThreadedCallback::ReleaseCallback,
danakj014316e2016-08-04 18:40:26599 base::Unretained(this), mailbox_char));
danakj5df8257f2017-11-20 22:16:58600
601 auto resource = viz::TransferableResource::MakeGL(
602 MailboxFromChar(mailbox_char), GL_LINEAR, GL_TEXTURE_2D,
603 SyncTokenFromUInt(static_cast<uint32_t>(mailbox_char)));
604 layer_->SetTransferableResource(resource, std::move(callback));
605 // Damage the layer so we send a new frame with the new resource to the
danakj014316e2016-08-04 18:40:26606 // Display compositor.
607 layer_->SetNeedsDisplay();
[email protected]28571b042013-03-14 07:59:15608 }
609
dcheng716bedf2014-10-21 09:51:08610 void BeginTest() override {
[email protected]9794fb32013-08-29 09:49:59611 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
612
[email protected]28571b042013-03-14 07:59:15613 gfx::Size bounds(100, 100);
loyso0940d412016-03-14 01:30:31614 root_ = Layer::Create();
[email protected]28571b042013-03-14 07:59:15615 root_->SetBounds(bounds);
616
loyso0940d412016-03-14 01:30:31617 layer_ = TextureLayer::CreateForMailbox(nullptr);
[email protected]28571b042013-03-14 07:59:15618 layer_->SetIsDrawable(true);
[email protected]28571b042013-03-14 07:59:15619 layer_->SetBounds(bounds);
620
621 root_->AddChild(layer_);
khushalsagarb69ba9452017-01-27 22:20:07622 layer_tree_host()->SetRootLayer(root_);
623 layer_tree_host()->SetViewportSize(bounds);
[email protected]28571b042013-03-14 07:59:15624 SetMailbox('1');
625 EXPECT_EQ(0, callback_count_);
626
ericrkad5923812017-01-25 23:26:12627 // Setup is complete - advance to test case 1.
628 AdvanceTestCase();
[email protected]28571b042013-03-14 07:59:15629 }
630
dcheng716bedf2014-10-21 09:51:08631 void DidCommit() override {
ericrkad5923812017-01-25 23:26:12632 // If we are not waiting on a callback, advance now.
633 if (!pending_callback_)
634 AdvanceTestCase();
[email protected]28571b042013-03-14 07:59:15635 }
[email protected]de44a152013-01-08 15:28:46636
dcheng716bedf2014-10-21 09:51:08637 void AfterTest() override {}
[email protected]de44a152013-01-08 15:28:46638
[email protected]28571b042013-03-14 07:59:15639 private:
[email protected]9794fb32013-08-29 09:49:59640 base::ThreadChecker main_thread_;
danakj014316e2016-08-04 18:40:26641 int callback_count_ = 0;
ericrkad5923812017-01-25 23:26:12642 int test_case_ = 0;
danakjcde8e4c32017-09-25 18:33:47643 int frame_number_ = 0;
ericrkad5923812017-01-25 23:26:12644 // Whether we are waiting on a callback to advance the test case.
645 bool pending_callback_ = false;
[email protected]28571b042013-03-14 07:59:15646 scoped_refptr<Layer> root_;
647 scoped_refptr<TextureLayer> layer_;
[email protected]de44a152013-01-08 15:28:46648};
649
danakj0943a112016-08-11 00:33:46650SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerImplWithMailboxThreadedCallback);
[email protected]74b43cc2013-08-30 06:29:27651
[email protected]74b43cc2013-08-30 06:29:27652class TextureLayerMailboxIsActivatedDuringCommit : public LayerTreeTest {
653 protected:
samans0834fe042017-03-03 17:03:22654 void ReleaseCallback(const gpu::SyncToken& original_sync_token,
655 const gpu::SyncToken& release_sync_token,
656 bool lost_resource) {
657 released_count_++;
658 switch (released_count_) {
659 case 1:
660 break;
661 case 2:
662 EXPECT_EQ(3, layer_tree_host()->SourceFrameNumber());
663 EndTest();
664 break;
665 default:
666 NOTREACHED();
667 }
668 }
[email protected]74b43cc2013-08-30 06:29:27669
670 void SetMailbox(char mailbox_char) {
dyene5db881b2016-03-01 19:47:03671 const gpu::SyncToken sync_token =
672 SyncTokenFromUInt(static_cast<uint32_t>(mailbox_char));
Fady Samueldfecb7d2017-07-26 11:41:04673 std::unique_ptr<viz::SingleReleaseCallback> callback =
674 viz::SingleReleaseCallback::Create(base::Bind(
danakj60bc3bc2016-04-09 00:24:48675 &TextureLayerMailboxIsActivatedDuringCommit::ReleaseCallback,
samans0834fe042017-03-03 17:03:22676 base::Unretained(this), sync_token));
danakj5df8257f2017-11-20 22:16:58677 auto resource = viz::TransferableResource::MakeGL(
678 MailboxFromChar(mailbox_char), GL_LINEAR, GL_TEXTURE_2D, sync_token);
679 layer_->SetTransferableResource(resource, std::move(callback));
[email protected]74b43cc2013-08-30 06:29:27680 }
681
dcheng716bedf2014-10-21 09:51:08682 void BeginTest() override {
[email protected]74b43cc2013-08-30 06:29:27683 gfx::Size bounds(100, 100);
loyso0940d412016-03-14 01:30:31684 root_ = Layer::Create();
[email protected]74b43cc2013-08-30 06:29:27685 root_->SetBounds(bounds);
686
loyso0940d412016-03-14 01:30:31687 layer_ = TextureLayer::CreateForMailbox(nullptr);
[email protected]74b43cc2013-08-30 06:29:27688 layer_->SetIsDrawable(true);
[email protected]74b43cc2013-08-30 06:29:27689 layer_->SetBounds(bounds);
690
691 root_->AddChild(layer_);
khushalsagarb69ba9452017-01-27 22:20:07692 layer_tree_host()->SetRootLayer(root_);
693 layer_tree_host()->SetViewportSize(bounds);
[email protected]74b43cc2013-08-30 06:29:27694 SetMailbox('1');
695
696 PostSetNeedsCommitToMainThread();
697 }
698
dcheng716bedf2014-10-21 09:51:08699 void WillActivateTreeOnThread(LayerTreeHostImpl* impl) override {
danakj3c3973b2015-08-25 21:50:18700 base::AutoLock lock(activate_count_lock_);
[email protected]74b43cc2013-08-30 06:29:27701 ++activate_count_;
702 }
703
dcheng716bedf2014-10-21 09:51:08704 void DidCommit() override {
danakj3c3973b2015-08-25 21:50:18705 // The first frame doesn't cause anything to be returned so it does not
706 // need to wait for activation.
khushalsagarcebe4942016-09-07 23:27:01707 if (layer_tree_host()->SourceFrameNumber() > 1) {
danakj3c3973b2015-08-25 21:50:18708 base::AutoLock lock(activate_count_lock_);
709 // The activate happened before commit is done on the main side.
khushalsagarcebe4942016-09-07 23:27:01710 EXPECT_EQ(activate_count_, layer_tree_host()->SourceFrameNumber());
danakj3c3973b2015-08-25 21:50:18711 }
712
khushalsagarcebe4942016-09-07 23:27:01713 switch (layer_tree_host()->SourceFrameNumber()) {
[email protected]74b43cc2013-08-30 06:29:27714 case 1:
715 // The first mailbox has been activated. Set a new mailbox, and
716 // expect the next commit to finish *after* it is activated.
717 SetMailbox('2');
[email protected]74b43cc2013-08-30 06:29:27718 break;
719 case 2:
720 // The second mailbox has been activated. Remove the layer from
721 // the tree to cause another commit/activation. The commit should
722 // finish *after* the layer is removed from the active tree.
723 layer_->RemoveFromParent();
[email protected]74b43cc2013-08-30 06:29:27724 break;
725 case 3:
samans0834fe042017-03-03 17:03:22726 // This ensures all texture mailboxes are released before the end of the
727 // test.
728 layer_->ClearClient();
[email protected]74b43cc2013-08-30 06:29:27729 break;
samans0834fe042017-03-03 17:03:22730 default:
731 NOTREACHED();
[email protected]74b43cc2013-08-30 06:29:27732 }
733 }
734
dcheng716bedf2014-10-21 09:51:08735 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
danakj3c3973b2015-08-25 21:50:18736 // The activate didn't happen before commit is done on the impl side (but it
737 // should happen before the main thread is done).
738 EXPECT_EQ(activate_count_, host_impl->sync_tree()->source_frame_number());
[email protected]74b43cc2013-08-30 06:29:27739 }
740
dcheng716bedf2014-10-21 09:51:08741 void AfterTest() override {}
[email protected]74b43cc2013-08-30 06:29:27742
danakj3c3973b2015-08-25 21:50:18743 base::Lock activate_count_lock_;
samans0834fe042017-03-03 17:03:22744 int activate_count_ = 0;
[email protected]74b43cc2013-08-30 06:29:27745 scoped_refptr<Layer> root_;
746 scoped_refptr<TextureLayer> layer_;
samans0834fe042017-03-03 17:03:22747 int released_count_ = 0;
[email protected]74b43cc2013-08-30 06:29:27748};
749
danakj0943a112016-08-11 00:33:46750SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerMailboxIsActivatedDuringCommit);
[email protected]74b43cc2013-08-30 06:29:27751
danakj5df8257f2017-11-20 22:16:58752class TextureLayerImplWithResourceTest : public TextureLayerTest {
[email protected]28571b042013-03-14 07:59:15753 protected:
dcheng93a52eb2014-12-23 02:14:23754 void SetUp() override {
[email protected]28571b042013-03-14 07:59:15755 TextureLayerTest::SetUp();
loyso2cb3f32f2016-11-08 07:08:34756 layer_tree_host_ = MockLayerTreeHost::Create(
757 &fake_client_, &task_graph_runner_, animation_host_.get());
sievers71c62dd52015-10-07 01:44:39758 host_impl_.SetVisible(true);
danakjc7afae52017-06-20 21:12:41759 EXPECT_TRUE(host_impl_.InitializeRenderer(layer_tree_frame_sink_.get()));
[email protected]28571b042013-03-14 07:59:15760 }
[email protected]de44a152013-01-08 15:28:46761
[email protected]0ec335c42013-07-04 06:17:08762 bool WillDraw(TextureLayerImpl* layer, DrawMode mode) {
763 bool will_draw = layer->WillDraw(
764 mode, host_impl_.active_tree()->resource_provider());
765 if (will_draw)
766 layer->DidDraw(host_impl_.active_tree()->resource_provider());
767 return will_draw;
768 }
769
[email protected]408b5e22013-03-19 09:48:09770 FakeLayerTreeHostClient fake_client_;
[email protected]de44a152013-01-08 15:28:46771};
772
[email protected]ffbb2212013-06-02 23:47:59773// Test conditions for results of TextureLayerImpl::WillDraw under
774// different configurations of different mailbox, texture_id, and draw_mode.
danakj5df8257f2017-11-20 22:16:58775TEST_F(TextureLayerImplWithResourceTest, TestWillDraw) {
776 EXPECT_CALL(test_data_.mock_callback_,
777 Release(test_data_.mailbox_name1_, gpu::SyncToken(), false))
[email protected]0ec335c42013-07-04 06:17:08778 .Times(AnyNumber());
dyencc16ed4d2015-11-03 20:03:04779 EXPECT_CALL(
780 test_data_.mock_callback_,
danakjcde8e4c32017-09-25 18:33:47781 Release2(test_data_.shared_bitmap_.get(), gpu::SyncToken(), false))
[email protected]0ec335c42013-07-04 06:17:08782 .Times(AnyNumber());
[email protected]ffbb2212013-06-02 23:47:59783 // Hardware mode.
784 {
danakj60bc3bc2016-04-09 00:24:48785 std::unique_ptr<TextureLayerImpl> impl_layer =
[email protected]17e08432014-04-10 00:41:11786 TextureLayerImpl::Create(host_impl_.active_tree(), 1);
danakj5df8257f2017-11-20 22:16:58787 impl_layer->SetTransferableResource(
788 test_data_.resource1_,
789 viz::SingleReleaseCallback::Create(test_data_.release_callback1_));
[email protected]0ec335c42013-07-04 06:17:08790 EXPECT_TRUE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE));
[email protected]ffbb2212013-06-02 23:47:59791 }
792
793 {
danakj60bc3bc2016-04-09 00:24:48794 std::unique_ptr<TextureLayerImpl> impl_layer =
[email protected]17e08432014-04-10 00:41:11795 TextureLayerImpl::Create(host_impl_.active_tree(), 1);
danakj5df8257f2017-11-20 22:16:58796 impl_layer->SetTransferableResource(viz::TransferableResource(), nullptr);
[email protected]0ec335c42013-07-04 06:17:08797 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE));
798 }
799
[email protected]0ec335c42013-07-04 06:17:08800 // Software mode.
801 {
danakj60bc3bc2016-04-09 00:24:48802 std::unique_ptr<TextureLayerImpl> impl_layer =
[email protected]17e08432014-04-10 00:41:11803 TextureLayerImpl::Create(host_impl_.active_tree(), 1);
danakj5df8257f2017-11-20 22:16:58804 impl_layer->SetTransferableResource(
805 test_data_.resource1_,
806 viz::SingleReleaseCallback::Create(test_data_.release_callback1_));
[email protected]0ec335c42013-07-04 06:17:08807 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE));
808 }
809
810 {
danakj60bc3bc2016-04-09 00:24:48811 std::unique_ptr<TextureLayerImpl> impl_layer =
[email protected]17e08432014-04-10 00:41:11812 TextureLayerImpl::Create(host_impl_.active_tree(), 1);
danakj5df8257f2017-11-20 22:16:58813 impl_layer->SetTransferableResource(viz::TransferableResource(), nullptr);
[email protected]0ec335c42013-07-04 06:17:08814 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE));
815 }
816
817 {
818 // Software resource.
danakj60bc3bc2016-04-09 00:24:48819 std::unique_ptr<TextureLayerImpl> impl_layer =
[email protected]17e08432014-04-10 00:41:11820 TextureLayerImpl::Create(host_impl_.active_tree(), 1);
danakj5df8257f2017-11-20 22:16:58821 impl_layer->SetTransferableResource(
822 test_data_.resource3_,
823 viz::SingleReleaseCallback::Create(test_data_.release_callback3_));
[email protected]0ec335c42013-07-04 06:17:08824 EXPECT_TRUE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE));
825 }
826
[email protected]ffbb2212013-06-02 23:47:59827 // Resourceless software mode.
828 {
danakj60bc3bc2016-04-09 00:24:48829 std::unique_ptr<TextureLayerImpl> impl_layer =
[email protected]17e08432014-04-10 00:41:11830 TextureLayerImpl::Create(host_impl_.active_tree(), 1);
danakj5df8257f2017-11-20 22:16:58831 impl_layer->SetTransferableResource(
832 test_data_.resource1_,
833 viz::SingleReleaseCallback::Create(test_data_.release_callback1_));
[email protected]0ec335c42013-07-04 06:17:08834 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_RESOURCELESS_SOFTWARE));
[email protected]ffbb2212013-06-02 23:47:59835 }
[email protected]ffbb2212013-06-02 23:47:59836}
837
danakj5df8257f2017-11-20 22:16:58838TEST_F(TextureLayerImplWithResourceTest, TestImplLayerCallbacks) {
[email protected]28571b042013-03-14 07:59:15839 host_impl_.CreatePendingTree();
danakj60bc3bc2016-04-09 00:24:48840 std::unique_ptr<TextureLayerImpl> pending_layer;
[email protected]17e08432014-04-10 00:41:11841 pending_layer = TextureLayerImpl::Create(host_impl_.pending_tree(), 1);
[email protected]28571b042013-03-14 07:59:15842 ASSERT_TRUE(pending_layer);
[email protected]de44a152013-01-08 15:28:46843
danakj60bc3bc2016-04-09 00:24:48844 std::unique_ptr<LayerImpl> active_layer(
[email protected]28571b042013-03-14 07:59:15845 pending_layer->CreateLayerImpl(host_impl_.active_tree()));
[email protected]ed511b8d2013-03-25 03:29:29846 ASSERT_TRUE(active_layer);
[email protected]de44a152013-01-08 15:28:46847
danakj5df8257f2017-11-20 22:16:58848 pending_layer->SetTransferableResource(
849 test_data_.resource1_,
850 viz::SingleReleaseCallback::Create(test_data_.release_callback1_));
[email protected]421e84f2013-02-22 03:27:15851
danakj5df8257f2017-11-20 22:16:58852 // Test multiple commits without an activation. The resource wasn't used so no
853 // sync token is returned.
854 EXPECT_CALL(test_data_.mock_callback_,
855 Release(test_data_.mailbox_name1_, gpu::SyncToken(), false))
[email protected]28571b042013-03-14 07:59:15856 .Times(1);
danakj5df8257f2017-11-20 22:16:58857 pending_layer->SetTransferableResource(
858 test_data_.resource2_,
859 viz::SingleReleaseCallback::Create(test_data_.release_callback2_));
[email protected]28571b042013-03-14 07:59:15860 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]421e84f2013-02-22 03:27:15861
[email protected]28571b042013-03-14 07:59:15862 // Test callback after activation.
[email protected]ed511b8d2013-03-25 03:29:29863 pending_layer->PushPropertiesTo(active_layer.get());
864 active_layer->DidBecomeActive();
[email protected]421e84f2013-02-22 03:27:15865
danakjcde8e4c32017-09-25 18:33:47866 EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0);
danakj5df8257f2017-11-20 22:16:58867 pending_layer->SetTransferableResource(
868 test_data_.resource1_,
869 viz::SingleReleaseCallback::Create(test_data_.release_callback1_));
[email protected]28571b042013-03-14 07:59:15870 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]421e84f2013-02-22 03:27:15871
[email protected]7ba3ca72013-04-11 06:37:25872 EXPECT_CALL(test_data_.mock_callback_,
danakjcde8e4c32017-09-25 18:33:47873 Release(test_data_.mailbox_name2_, _, false))
874 .Times(1);
[email protected]ed511b8d2013-03-25 03:29:29875 pending_layer->PushPropertiesTo(active_layer.get());
876 active_layer->DidBecomeActive();
[email protected]28571b042013-03-14 07:59:15877 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]de44a152013-01-08 15:28:46878
[email protected]28571b042013-03-14 07:59:15879 // Test resetting the mailbox.
[email protected]7ba3ca72013-04-11 06:37:25880 EXPECT_CALL(test_data_.mock_callback_,
danakjcde8e4c32017-09-25 18:33:47881 Release(test_data_.mailbox_name1_, _, false))
882 .Times(1);
danakj5df8257f2017-11-20 22:16:58883 pending_layer->SetTransferableResource(viz::TransferableResource(), nullptr);
[email protected]ed511b8d2013-03-25 03:29:29884 pending_layer->PushPropertiesTo(active_layer.get());
885 active_layer->DidBecomeActive();
[email protected]28571b042013-03-14 07:59:15886 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]de44a152013-01-08 15:28:46887
danakj5df8257f2017-11-20 22:16:58888 // Test destructor. The resource wasn't used so no sync token is returned.
889 EXPECT_CALL(test_data_.mock_callback_,
890 Release(test_data_.mailbox_name1_, gpu::SyncToken(), false))
[email protected]28571b042013-03-14 07:59:15891 .Times(1);
danakj5df8257f2017-11-20 22:16:58892 pending_layer->SetTransferableResource(
893 test_data_.resource1_,
894 viz::SingleReleaseCallback::Create(test_data_.release_callback1_));
[email protected]de44a152013-01-08 15:28:46895}
896
danakj5df8257f2017-11-20 22:16:58897TEST_F(TextureLayerImplWithResourceTest,
[email protected]28571b042013-03-14 07:59:15898 TestDestructorCallbackOnCreatedResource) {
danakj60bc3bc2016-04-09 00:24:48899 std::unique_ptr<TextureLayerImpl> impl_layer;
[email protected]17e08432014-04-10 00:41:11900 impl_layer = TextureLayerImpl::Create(host_impl_.active_tree(), 1);
[email protected]28571b042013-03-14 07:59:15901 ASSERT_TRUE(impl_layer);
[email protected]de44a152013-01-08 15:28:46902
[email protected]7ba3ca72013-04-11 06:37:25903 EXPECT_CALL(test_data_.mock_callback_,
danakjcde8e4c32017-09-25 18:33:47904 Release(test_data_.mailbox_name1_, _, false))
905 .Times(1);
danakj5df8257f2017-11-20 22:16:58906 impl_layer->SetTransferableResource(
907 test_data_.resource1_,
908 viz::SingleReleaseCallback::Create(test_data_.release_callback1_));
[email protected]ffbb2212013-06-02 23:47:59909 impl_layer->DidBecomeActive();
910 EXPECT_TRUE(impl_layer->WillDraw(
911 DRAW_MODE_HARDWARE, host_impl_.active_tree()->resource_provider()));
[email protected]28571b042013-03-14 07:59:15912 impl_layer->DidDraw(host_impl_.active_tree()->resource_provider());
danakj5df8257f2017-11-20 22:16:58913 impl_layer->SetTransferableResource(viz::TransferableResource(), nullptr);
[email protected]de44a152013-01-08 15:28:46914}
915
[email protected]4bad8b62013-10-24 01:27:29916// Checks that TextureLayer::Update does not cause an extra commit when setting
917// the texture mailbox.
918class TextureLayerNoExtraCommitForMailboxTest
919 : public LayerTreeTest,
920 public TextureLayerClient {
921 public:
[email protected]4bad8b62013-10-24 01:27:29922 // TextureLayerClient implementation.
danakj5df8257f2017-11-20 22:16:58923 bool PrepareTransferableResource(
924 viz::TransferableResource* resource,
Fady Samueldfecb7d2017-07-26 11:41:04925 std::unique_ptr<viz::SingleReleaseCallback>* release_callback) override {
khushalsagarcebe4942016-09-07 23:27:01926 if (layer_tree_host()->SourceFrameNumber() == 1) {
danakj5df8257f2017-11-20 22:16:58927 // Once this has been committed, the resource will be released.
928 *resource = viz::TransferableResource();
[email protected]cce34bd2013-12-02 23:24:45929 return true;
930 }
[email protected]4bad8b62013-10-24 01:27:29931
danakj5df8257f2017-11-20 22:16:58932 *resource = viz::TransferableResource::MakeGL(MailboxFromChar('1'),
933 GL_LINEAR, GL_TEXTURE_2D,
934 SyncTokenFromUInt(0x123));
Fady Samueldfecb7d2017-07-26 11:41:04935 *release_callback = viz::SingleReleaseCallback::Create(
danakj5df8257f2017-11-20 22:16:58936 base::Bind(&TextureLayerNoExtraCommitForMailboxTest::ResourceReleased,
[email protected]4bad8b62013-10-24 01:27:29937 base::Unretained(this)));
[email protected]4bad8b62013-10-24 01:27:29938 return true;
939 }
940
danakj5df8257f2017-11-20 22:16:58941 void ResourceReleased(const gpu::SyncToken& sync_token, bool lost_resource) {
dyene5db881b2016-03-01 19:47:03942 EXPECT_TRUE(sync_token.HasData());
[email protected]cce34bd2013-12-02 23:24:45943 EndTest();
[email protected]4bad8b62013-10-24 01:27:29944 }
945
dcheng716bedf2014-10-21 09:51:08946 void SetupTree() override {
loyso0940d412016-03-14 01:30:31947 scoped_refptr<Layer> root = Layer::Create();
[email protected]4bad8b62013-10-24 01:27:29948 root->SetBounds(gfx::Size(10, 10));
[email protected]4bad8b62013-10-24 01:27:29949 root->SetIsDrawable(true);
950
loyso0940d412016-03-14 01:30:31951 texture_layer_ = TextureLayer::CreateForMailbox(this);
[email protected]4bad8b62013-10-24 01:27:29952 texture_layer_->SetBounds(gfx::Size(10, 10));
[email protected]4bad8b62013-10-24 01:27:29953 texture_layer_->SetIsDrawable(true);
[email protected]0d7fb302014-01-23 21:30:47954 root->AddChild(texture_layer_);
[email protected]4bad8b62013-10-24 01:27:29955
khushalsagarb69ba9452017-01-27 22:20:07956 layer_tree_host()->SetRootLayer(root);
[email protected]4bad8b62013-10-24 01:27:29957 LayerTreeTest::SetupTree();
958 }
959
dcheng716bedf2014-10-21 09:51:08960 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
[email protected]4bad8b62013-10-24 01:27:29961
dcheng716bedf2014-10-21 09:51:08962 void DidCommitAndDrawFrame() override {
khushalsagarcebe4942016-09-07 23:27:01963 switch (layer_tree_host()->SourceFrameNumber()) {
[email protected]4bad8b62013-10-24 01:27:29964 case 1:
[email protected]4ea293f72014-08-13 03:03:17965 EXPECT_FALSE(proxy()->MainFrameWillHappenForTesting());
[email protected]cce34bd2013-12-02 23:24:45966 // Invalidate the texture layer to clear the mailbox before
967 // ending the test.
968 texture_layer_->SetNeedsDisplay();
969 break;
970 case 2:
[email protected]4bad8b62013-10-24 01:27:29971 break;
972 default:
973 NOTREACHED();
974 break;
975 }
976 }
977
dcheng716bedf2014-10-21 09:51:08978 void AfterTest() override {}
[email protected]4bad8b62013-10-24 01:27:29979
980 private:
[email protected]4bad8b62013-10-24 01:27:29981 scoped_refptr<TextureLayer> texture_layer_;
[email protected]4bad8b62013-10-24 01:27:29982};
983
[email protected]cce34bd2013-12-02 23:24:45984SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerNoExtraCommitForMailboxTest);
[email protected]4bad8b62013-10-24 01:27:29985
[email protected]b04264f92013-09-13 23:37:29986// Checks that changing a mailbox in the client for a TextureLayer that's
987// invisible correctly works and uses the new mailbox as soon as the layer
988// becomes visible (and returns the old one).
989class TextureLayerChangeInvisibleMailboxTest
990 : public LayerTreeTest,
991 public TextureLayerClient {
992 public:
993 TextureLayerChangeInvisibleMailboxTest()
danakj5df8257f2017-11-20 22:16:58994 : resource_changed_(true),
995 resource_(MakeResource('1')),
996 resource_returned_(0),
[email protected]b04264f92013-09-13 23:37:29997 prepare_called_(0),
danakj5df8257f2017-11-20 22:16:58998 commit_count_(0) {}
[email protected]b04264f92013-09-13 23:37:29999
1000 // TextureLayerClient implementation.
danakj5df8257f2017-11-20 22:16:581001 bool PrepareTransferableResource(
1002 viz::TransferableResource* resource,
Fady Samueldfecb7d2017-07-26 11:41:041003 std::unique_ptr<viz::SingleReleaseCallback>* release_callback) override {
[email protected]b04264f92013-09-13 23:37:291004 ++prepare_called_;
danakj5df8257f2017-11-20 22:16:581005 if (!resource_changed_)
[email protected]b04264f92013-09-13 23:37:291006 return false;
danakj5df8257f2017-11-20 22:16:581007 *resource = resource_;
Fady Samueldfecb7d2017-07-26 11:41:041008 *release_callback = viz::SingleReleaseCallback::Create(
danakj5df8257f2017-11-20 22:16:581009 base::Bind(&TextureLayerChangeInvisibleMailboxTest::ResourceReleased,
[email protected]9260757f2013-09-17 01:24:161010 base::Unretained(this)));
[email protected]b04264f92013-09-13 23:37:291011 return true;
1012 }
1013
danakj5df8257f2017-11-20 22:16:581014 viz::TransferableResource MakeResource(char name) {
1015 return viz::TransferableResource::MakeGL(
1016 MailboxFromChar(name), GL_LINEAR, GL_TEXTURE_2D,
1017 SyncTokenFromUInt(static_cast<uint32_t>(name)));
[email protected]b04264f92013-09-13 23:37:291018 }
1019
danakj5df8257f2017-11-20 22:16:581020 void ResourceReleased(const gpu::SyncToken& sync_token, bool lost_resource) {
dyene5db881b2016-03-01 19:47:031021 EXPECT_TRUE(sync_token.HasData());
danakj5df8257f2017-11-20 22:16:581022 ++resource_returned_;
[email protected]b04264f92013-09-13 23:37:291023 }
1024
dcheng716bedf2014-10-21 09:51:081025 void SetupTree() override {
loyso0940d412016-03-14 01:30:311026 scoped_refptr<Layer> root = Layer::Create();
[email protected]b04264f92013-09-13 23:37:291027 root->SetBounds(gfx::Size(10, 10));
[email protected]b04264f92013-09-13 23:37:291028 root->SetIsDrawable(true);
1029
loyso0940d412016-03-14 01:30:311030 solid_layer_ = SolidColorLayer::Create();
[email protected]b04264f92013-09-13 23:37:291031 solid_layer_->SetBounds(gfx::Size(10, 10));
1032 solid_layer_->SetIsDrawable(true);
1033 solid_layer_->SetBackgroundColor(SK_ColorWHITE);
1034 root->AddChild(solid_layer_);
1035
loyso0940d412016-03-14 01:30:311036 parent_layer_ = Layer::Create();
[email protected]b04264f92013-09-13 23:37:291037 parent_layer_->SetBounds(gfx::Size(10, 10));
1038 parent_layer_->SetIsDrawable(true);
1039 root->AddChild(parent_layer_);
1040
loyso0940d412016-03-14 01:30:311041 texture_layer_ = TextureLayer::CreateForMailbox(this);
[email protected]b04264f92013-09-13 23:37:291042 texture_layer_->SetBounds(gfx::Size(10, 10));
[email protected]b04264f92013-09-13 23:37:291043 texture_layer_->SetIsDrawable(true);
1044 parent_layer_->AddChild(texture_layer_);
1045
khushalsagarb69ba9452017-01-27 22:20:071046 layer_tree_host()->SetRootLayer(root);
[email protected]b04264f92013-09-13 23:37:291047 LayerTreeTest::SetupTree();
1048 }
1049
dcheng716bedf2014-10-21 09:51:081050 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
[email protected]b04264f92013-09-13 23:37:291051
samans44b6dfc2017-04-19 16:50:531052 void DidReceiveCompositorFrameAck() override {
[email protected]b04264f92013-09-13 23:37:291053 ++commit_count_;
1054 switch (commit_count_) {
1055 case 1:
1056 // We should have updated the layer, committing the texture.
1057 EXPECT_EQ(1, prepare_called_);
1058 // Make layer invisible.
1059 parent_layer_->SetOpacity(0.f);
1060 break;
1061 case 2:
1062 // Layer shouldn't have been updated.
1063 EXPECT_EQ(1, prepare_called_);
1064 // Change the texture.
danakj5df8257f2017-11-20 22:16:581065 resource_ = MakeResource('2');
1066 resource_changed_ = true;
[email protected]b04264f92013-09-13 23:37:291067 texture_layer_->SetNeedsDisplay();
1068 // Force a change to make sure we draw a frame.
1069 solid_layer_->SetBackgroundColor(SK_ColorGRAY);
1070 break;
1071 case 3:
1072 // Layer shouldn't have been updated.
1073 EXPECT_EQ(1, prepare_called_);
danakj5df8257f2017-11-20 22:16:581074 // So the old resource isn't returned yet.
1075 EXPECT_EQ(0, resource_returned_);
[email protected]b04264f92013-09-13 23:37:291076 // Make layer visible again.
jaydasikacf223762016-05-16 23:02:091077 parent_layer_->SetOpacity(0.9f);
[email protected]b04264f92013-09-13 23:37:291078 break;
1079 case 4:
1080 // Layer should have been updated.
1081 EXPECT_EQ(2, prepare_called_);
danakj5df8257f2017-11-20 22:16:581082 // So the old resource should have been returned already.
1083 EXPECT_EQ(1, resource_returned_);
[email protected]b04264f92013-09-13 23:37:291084 texture_layer_->ClearClient();
1085 break;
1086 case 5:
danakj5df8257f2017-11-20 22:16:581087 EXPECT_EQ(2, resource_returned_);
samans44b6dfc2017-04-19 16:50:531088 EndTest();
[email protected]b04264f92013-09-13 23:37:291089 break;
1090 default:
1091 NOTREACHED();
1092 break;
1093 }
1094 }
1095
dcheng716bedf2014-10-21 09:51:081096 void AfterTest() override {}
[email protected]b04264f92013-09-13 23:37:291097
1098 private:
1099 scoped_refptr<SolidColorLayer> solid_layer_;
1100 scoped_refptr<Layer> parent_layer_;
1101 scoped_refptr<TextureLayer> texture_layer_;
1102
1103 // Used on the main thread.
danakj5df8257f2017-11-20 22:16:581104 bool resource_changed_;
1105 viz::TransferableResource resource_;
1106 int resource_returned_;
[email protected]b04264f92013-09-13 23:37:291107 int prepare_called_;
1108 int commit_count_;
1109};
1110
samans44b6dfc2017-04-19 16:50:531111SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerChangeInvisibleMailboxTest);
[email protected]b04264f92013-09-13 23:37:291112
[email protected]0d7fb302014-01-23 21:30:471113// Test that TextureLayerImpl::ReleaseResources can be called which releases
danakj5df8257f2017-11-20 22:16:581114// the resource back to TextureLayerClient.
[email protected]0d7fb302014-01-23 21:30:471115class TextureLayerReleaseResourcesBase
1116 : public LayerTreeTest,
1117 public TextureLayerClient {
1118 public:
1119 // TextureLayerClient implementation.
danakj5df8257f2017-11-20 22:16:581120 bool PrepareTransferableResource(
1121 viz::TransferableResource* resource,
Fady Samueldfecb7d2017-07-26 11:41:041122 std::unique_ptr<viz::SingleReleaseCallback>* release_callback) override {
danakj5df8257f2017-11-20 22:16:581123 *resource = viz::TransferableResource::MakeGL(
1124 MailboxFromChar('1'), GL_LINEAR, GL_TEXTURE_2D, SyncTokenFromUInt(1));
Fady Samueldfecb7d2017-07-26 11:41:041125 *release_callback = viz::SingleReleaseCallback::Create(
danakj5df8257f2017-11-20 22:16:581126 base::Bind(&TextureLayerReleaseResourcesBase::ResourceReleased,
[email protected]0d7fb302014-01-23 21:30:471127 base::Unretained(this)));
1128 return true;
1129 }
1130
danakj5df8257f2017-11-20 22:16:581131 void ResourceReleased(const gpu::SyncToken& sync_token, bool lost_resource) {
1132 resource_released_ = true;
[email protected]0d7fb302014-01-23 21:30:471133 }
1134
dcheng716bedf2014-10-21 09:51:081135 void SetupTree() override {
[email protected]0d7fb302014-01-23 21:30:471136 LayerTreeTest::SetupTree();
1137
1138 scoped_refptr<TextureLayer> texture_layer =
loyso0940d412016-03-14 01:30:311139 TextureLayer::CreateForMailbox(this);
[email protected]0d7fb302014-01-23 21:30:471140 texture_layer->SetBounds(gfx::Size(10, 10));
[email protected]0d7fb302014-01-23 21:30:471141 texture_layer->SetIsDrawable(true);
1142
khushalsagarb69ba9452017-01-27 22:20:071143 layer_tree_host()->root_layer()->AddChild(texture_layer);
jaydasikabd6f15a2016-04-21 19:45:371144 texture_layer_id_ = texture_layer->id();
[email protected]0d7fb302014-01-23 21:30:471145 }
1146
dcheng716bedf2014-10-21 09:51:081147 void BeginTest() override {
danakj5df8257f2017-11-20 22:16:581148 resource_released_ = false;
[email protected]0d7fb302014-01-23 21:30:471149 PostSetNeedsCommitToMainThread();
1150 }
1151
dcheng716bedf2014-10-21 09:51:081152 void DidCommitAndDrawFrame() override { EndTest(); }
[email protected]0d7fb302014-01-23 21:30:471153
danakj5df8257f2017-11-20 22:16:581154 void AfterTest() override { EXPECT_TRUE(resource_released_); }
[email protected]0d7fb302014-01-23 21:30:471155
jaydasikabd6f15a2016-04-21 19:45:371156 protected:
1157 int texture_layer_id_;
1158
[email protected]0d7fb302014-01-23 21:30:471159 private:
danakj5df8257f2017-11-20 22:16:581160 bool resource_released_;
[email protected]0d7fb302014-01-23 21:30:471161};
1162
1163class TextureLayerReleaseResourcesAfterCommit
1164 : public TextureLayerReleaseResourcesBase {
1165 public:
dcheng716bedf2014-10-21 09:51:081166 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
kulkarni.a4015690f12014-10-10 13:50:061167 LayerTreeImpl* tree = nullptr;
danakj009cdfdf2015-02-17 22:35:141168 tree = host_impl->sync_tree();
jaydasikabd6f15a2016-04-21 19:45:371169 tree->LayerById(texture_layer_id_)->ReleaseResources();
[email protected]0d7fb302014-01-23 21:30:471170 }
1171};
1172
1173SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerReleaseResourcesAfterCommit);
1174
1175class TextureLayerReleaseResourcesAfterActivate
1176 : public TextureLayerReleaseResourcesBase {
1177 public:
dcheng716bedf2014-10-21 09:51:081178 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
jaydasikabd6f15a2016-04-21 19:45:371179 host_impl->active_tree()->LayerById(texture_layer_id_)->ReleaseResources();
[email protected]0d7fb302014-01-23 21:30:471180 }
1181};
1182
1183SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerReleaseResourcesAfterActivate);
1184
danakj5df8257f2017-11-20 22:16:581185class TextureLayerWithResourceMainThreadDeleted : public LayerTreeTest {
[email protected]9c2bd822013-07-26 12:30:171186 public:
dyencc16ed4d2015-11-03 20:03:041187 void ReleaseCallback(const gpu::SyncToken& sync_token, bool lost_resource) {
[email protected]9794fb32013-08-29 09:49:591188 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]9c2bd822013-07-26 12:30:171189 EXPECT_FALSE(lost_resource);
1190 ++callback_count_;
1191 EndTest();
1192 }
1193
1194 void SetMailbox(char mailbox_char) {
[email protected]9794fb32013-08-29 09:49:591195 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
Fady Samueldfecb7d2017-07-26 11:41:041196 std::unique_ptr<viz::SingleReleaseCallback> callback =
1197 viz::SingleReleaseCallback::Create(base::Bind(
danakj5df8257f2017-11-20 22:16:581198 &TextureLayerWithResourceMainThreadDeleted::ReleaseCallback,
[email protected]9c2bd822013-07-26 12:30:171199 base::Unretained(this)));
danakj5df8257f2017-11-20 22:16:581200 auto resource = viz::TransferableResource::MakeGL(
1201 MailboxFromChar(mailbox_char), GL_LINEAR, GL_TEXTURE_2D,
1202 SyncTokenFromUInt(static_cast<uint32_t>(mailbox_char)));
1203 layer_->SetTransferableResource(resource, std::move(callback));
[email protected]9c2bd822013-07-26 12:30:171204 }
1205
dcheng716bedf2014-10-21 09:51:081206 void SetupTree() override {
[email protected]9c2bd822013-07-26 12:30:171207 gfx::Size bounds(100, 100);
loyso0940d412016-03-14 01:30:311208 root_ = Layer::Create();
[email protected]9c2bd822013-07-26 12:30:171209 root_->SetBounds(bounds);
1210
loyso0940d412016-03-14 01:30:311211 layer_ = TextureLayer::CreateForMailbox(nullptr);
[email protected]9c2bd822013-07-26 12:30:171212 layer_->SetIsDrawable(true);
[email protected]9c2bd822013-07-26 12:30:171213 layer_->SetBounds(bounds);
1214
1215 root_->AddChild(layer_);
khushalsagarb69ba9452017-01-27 22:20:071216 layer_tree_host()->SetRootLayer(root_);
1217 layer_tree_host()->SetViewportSize(bounds);
[email protected]9c2bd822013-07-26 12:30:171218 }
1219
dcheng716bedf2014-10-21 09:51:081220 void BeginTest() override {
[email protected]9794fb32013-08-29 09:49:591221 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
1222
[email protected]9c2bd822013-07-26 12:30:171223 callback_count_ = 0;
1224
danakj5df8257f2017-11-20 22:16:581225 // Set the resource on the main thread.
[email protected]9c2bd822013-07-26 12:30:171226 SetMailbox('1');
1227 EXPECT_EQ(0, callback_count_);
1228
1229 PostSetNeedsCommitToMainThread();
1230 }
1231
dcheng716bedf2014-10-21 09:51:081232 void DidCommitAndDrawFrame() override {
khushalsagarcebe4942016-09-07 23:27:011233 switch (layer_tree_host()->SourceFrameNumber()) {
[email protected]9c2bd822013-07-26 12:30:171234 case 1:
danakj5df8257f2017-11-20 22:16:581235 // Delete the TextureLayer on the main thread while the resource is in
[email protected]9c2bd822013-07-26 12:30:171236 // the impl tree.
1237 layer_->RemoveFromParent();
kulkarni.a4015690f12014-10-10 13:50:061238 layer_ = nullptr;
[email protected]9c2bd822013-07-26 12:30:171239 break;
1240 }
1241 }
1242
dcheng716bedf2014-10-21 09:51:081243 void AfterTest() override { EXPECT_EQ(1, callback_count_); }
[email protected]9c2bd822013-07-26 12:30:171244
1245 private:
[email protected]9794fb32013-08-29 09:49:591246 base::ThreadChecker main_thread_;
[email protected]9c2bd822013-07-26 12:30:171247 int callback_count_;
1248 scoped_refptr<Layer> root_;
1249 scoped_refptr<TextureLayer> layer_;
1250};
1251
danakj5df8257f2017-11-20 22:16:581252SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerWithResourceMainThreadDeleted);
[email protected]9c2bd822013-07-26 12:30:171253
danakj5df8257f2017-11-20 22:16:581254class TextureLayerWithResourceImplThreadDeleted : public LayerTreeTest {
[email protected]9c2bd822013-07-26 12:30:171255 public:
dyencc16ed4d2015-11-03 20:03:041256 void ReleaseCallback(const gpu::SyncToken& sync_token, bool lost_resource) {
[email protected]9794fb32013-08-29 09:49:591257 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]9c2bd822013-07-26 12:30:171258 EXPECT_FALSE(lost_resource);
1259 ++callback_count_;
1260 EndTest();
1261 }
1262
1263 void SetMailbox(char mailbox_char) {
[email protected]9794fb32013-08-29 09:49:591264 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
Fady Samueldfecb7d2017-07-26 11:41:041265 std::unique_ptr<viz::SingleReleaseCallback> callback =
1266 viz::SingleReleaseCallback::Create(base::Bind(
danakj5df8257f2017-11-20 22:16:581267 &TextureLayerWithResourceImplThreadDeleted::ReleaseCallback,
[email protected]9c2bd822013-07-26 12:30:171268 base::Unretained(this)));
danakj5df8257f2017-11-20 22:16:581269 auto resource = viz::TransferableResource::MakeGL(
1270 MailboxFromChar(mailbox_char), GL_LINEAR, GL_TEXTURE_2D,
1271 SyncTokenFromUInt(static_cast<uint32_t>(mailbox_char)));
1272 layer_->SetTransferableResource(resource, std::move(callback));
[email protected]9c2bd822013-07-26 12:30:171273 }
1274
dcheng716bedf2014-10-21 09:51:081275 void SetupTree() override {
[email protected]9c2bd822013-07-26 12:30:171276 gfx::Size bounds(100, 100);
loyso0940d412016-03-14 01:30:311277 root_ = Layer::Create();
[email protected]9c2bd822013-07-26 12:30:171278 root_->SetBounds(bounds);
1279
loyso0940d412016-03-14 01:30:311280 layer_ = TextureLayer::CreateForMailbox(nullptr);
[email protected]9c2bd822013-07-26 12:30:171281 layer_->SetIsDrawable(true);
[email protected]9c2bd822013-07-26 12:30:171282 layer_->SetBounds(bounds);
1283
1284 root_->AddChild(layer_);
khushalsagarb69ba9452017-01-27 22:20:071285 layer_tree_host()->SetRootLayer(root_);
1286 layer_tree_host()->SetViewportSize(bounds);
[email protected]9c2bd822013-07-26 12:30:171287 }
1288
dcheng716bedf2014-10-21 09:51:081289 void BeginTest() override {
[email protected]9794fb32013-08-29 09:49:591290 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
1291
[email protected]9c2bd822013-07-26 12:30:171292 callback_count_ = 0;
1293
danakj5df8257f2017-11-20 22:16:581294 // Set the resource on the main thread.
[email protected]9c2bd822013-07-26 12:30:171295 SetMailbox('1');
1296 EXPECT_EQ(0, callback_count_);
1297
1298 PostSetNeedsCommitToMainThread();
1299 }
1300
dcheng716bedf2014-10-21 09:51:081301 void DidCommitAndDrawFrame() override {
khushalsagarcebe4942016-09-07 23:27:011302 switch (layer_tree_host()->SourceFrameNumber()) {
[email protected]9c2bd822013-07-26 12:30:171303 case 1:
danakj5df8257f2017-11-20 22:16:581304 // Remove the TextureLayer on the main thread while the resource is in
[email protected]9c2bd822013-07-26 12:30:171305 // the impl tree, but don't delete the TextureLayer until after the impl
1306 // tree side is deleted.
1307 layer_->RemoveFromParent();
1308 break;
1309 case 2:
kulkarni.a4015690f12014-10-10 13:50:061310 layer_ = nullptr;
[email protected]9c2bd822013-07-26 12:30:171311 break;
1312 }
1313 }
1314
dcheng716bedf2014-10-21 09:51:081315 void AfterTest() override { EXPECT_EQ(1, callback_count_); }
[email protected]9c2bd822013-07-26 12:30:171316
1317 private:
[email protected]9794fb32013-08-29 09:49:591318 base::ThreadChecker main_thread_;
[email protected]9c2bd822013-07-26 12:30:171319 int callback_count_;
1320 scoped_refptr<Layer> root_;
1321 scoped_refptr<TextureLayer> layer_;
1322};
1323
danakj5df8257f2017-11-20 22:16:581324SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerWithResourceImplThreadDeleted);
[email protected]9c2bd822013-07-26 12:30:171325
[email protected]ba565742012-11-10 09:29:481326} // namespace
1327} // namespace cc