blob: ff787087015ba488c3288a570db8d66c6a2f1bd8 [file] [log] [blame]
jbaumandbccae1ab2014-11-06 23:26:441// Copyright 2014 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
avi02a4d172015-12-21 06:14:365#include <stdint.h>
6
danakjaeb95062014-11-14 01:35:367#include <set>
8#include <vector>
9
skyostil0fd1dad2015-04-13 20:11:4810#include "base/location.h"
ksakamoto73809d9ee2016-12-16 08:02:5811#include "base/run_loop.h"
skyostil0fd1dad2015-04-13 20:11:4812#include "base/single_thread_task_runner.h"
gab39cb4ed72016-05-11 17:45:1913#include "base/threading/thread_task_runner_handle.h"
loyso2cb3f32f2016-11-08 07:08:3414#include "cc/animation/animation_host.h"
jbaumandbccae1ab2014-11-06 23:26:4415#include "cc/layers/solid_color_layer.h"
16#include "cc/layers/surface_layer.h"
fsamuel1d3252c2017-02-15 20:56:3717#include "cc/layers/surface_layer_impl.h"
kylechar5344b39e2016-10-06 23:51:1918#include "cc/output/compositor_frame.h"
samans72b2a282016-12-17 02:44:1519#include "cc/surfaces/sequence_surface_reference_factory.h"
20#include "cc/surfaces/surface_info.h"
khushalsagarb64b360d2015-10-21 19:25:1621#include "cc/test/fake_impl_task_runner_provider.h"
jbaumandbccae1ab2014-11-06 23:26:4422#include "cc/test/fake_layer_tree_host.h"
23#include "cc/test/fake_layer_tree_host_client.h"
24#include "cc/test/fake_layer_tree_host_impl.h"
25#include "cc/test/fake_output_surface.h"
26#include "cc/test/layer_tree_test.h"
danakjcf610582015-06-16 22:48:5627#include "cc/test/test_task_graph_runner.h"
jbaumandbccae1ab2014-11-06 23:26:4428#include "cc/trees/layer_tree_host.h"
29#include "testing/gmock/include/gmock/gmock.h"
30#include "testing/gtest/include/gtest/gtest.h"
31
32namespace cc {
33namespace {
34
fsamuele0f705b2016-10-01 14:07:1435static constexpr FrameSinkId kArbitraryFrameSinkId(1, 1);
fsamuel278664272016-07-13 04:06:5936
jbaumandbccae1ab2014-11-06 23:26:4437class SurfaceLayerTest : public testing::Test {
fsamuel1d3252c2017-02-15 20:56:3738 public:
39 SurfaceLayerTest()
40 : host_impl_(&task_runner_provider_, &task_graph_runner_) {}
41
jbaumandbccae1ab2014-11-06 23:26:4442 protected:
dcheng93a52eb2014-12-23 02:14:2343 void SetUp() override {
loyso2cb3f32f2016-11-08 07:08:3444 animation_host_ = AnimationHost::CreateForTesting(ThreadInstance::MAIN);
45 layer_tree_host_ = FakeLayerTreeHost::Create(
46 &fake_client_, &task_graph_runner_, animation_host_.get());
khushalsagarb69ba9452017-01-27 22:20:0747 layer_tree_host_->SetViewportSize(gfx::Size(10, 10));
fsamuel1d3252c2017-02-15 20:56:3748 host_impl_.CreatePendingTree();
jbaumandbccae1ab2014-11-06 23:26:4449 }
50
dcheng93a52eb2014-12-23 02:14:2351 void TearDown() override {
jbaumandbccae1ab2014-11-06 23:26:4452 if (layer_tree_host_) {
khushalsagarb69ba9452017-01-27 22:20:0753 layer_tree_host_->SetRootLayer(nullptr);
jbaumandbccae1ab2014-11-06 23:26:4454 layer_tree_host_ = nullptr;
55 }
56 }
57
jbaumandbccae1ab2014-11-06 23:26:4458 FakeLayerTreeHostClient fake_client_;
fsamuel1d3252c2017-02-15 20:56:3759 FakeImplTaskRunnerProvider task_runner_provider_;
danakjcf610582015-06-16 22:48:5660 TestTaskGraphRunner task_graph_runner_;
loyso2cb3f32f2016-11-08 07:08:3461 std::unique_ptr<AnimationHost> animation_host_;
danakj60bc3bc2016-04-09 00:24:4862 std::unique_ptr<FakeLayerTreeHost> layer_tree_host_;
fsamuel1d3252c2017-02-15 20:56:3763 FakeLayerTreeHostImpl host_impl_;
jbaumandbccae1ab2014-11-06 23:26:4464};
65
samans72b2a282016-12-17 02:44:1566class TestSurfaceReferenceFactory : public SequenceSurfaceReferenceFactory {
67 protected:
68 void SatisfySequence(const SurfaceSequence& seq) const override {
69 *out_seq_ = seq;
70 }
jbaumandbccae1ab2014-11-06 23:26:4471
samans72b2a282016-12-17 02:44:1572 void RequireSequence(const SurfaceId& id,
73 const SurfaceSequence& seq) const override {
74 *out_id_ = id;
75 out_set_->insert(seq);
76 }
77
78 public:
79 TestSurfaceReferenceFactory(SurfaceSequence* out_seq,
80 SurfaceId* out_id,
81 std::set<SurfaceSequence>* out_set)
82 : out_seq_(out_seq), out_id_(out_id), out_set_(out_set) {}
83
84 protected:
85 ~TestSurfaceReferenceFactory() override = default;
86
87 private:
88 SurfaceSequence* out_seq_;
89 SurfaceId* out_id_;
90 std::set<SurfaceSequence>* out_set_;
91
92 DISALLOW_COPY_AND_ASSIGN(TestSurfaceReferenceFactory);
93};
jbaumandbccae1ab2014-11-06 23:26:4494
95// Check that one surface can be referenced by multiple LayerTreeHosts, and
96// each will create its own SurfaceSequence that's satisfied on destruction.
97TEST_F(SurfaceLayerTest, MultipleFramesOneSurface) {
staraz7d7f6eb2016-11-11 00:19:1798 const base::UnguessableToken kArbitraryToken =
99 base::UnguessableToken::Create();
jbaumandbccae1ab2014-11-06 23:26:44100 SurfaceSequence blank_change; // Receives sequence if commit doesn't happen.
101
102 SurfaceId required_id;
103 std::set<SurfaceSequence> required_seq;
samans72b2a282016-12-17 02:44:15104 scoped_refptr<SurfaceReferenceFactory> ref_factory =
105 new TestSurfaceReferenceFactory(&blank_change, &required_id,
106 &required_seq);
107 auto layer = SurfaceLayer::Create(ref_factory);
108 SurfaceInfo info(
samans5258bfb2017-01-27 21:16:26109 SurfaceId(kArbitraryFrameSinkId, LocalSurfaceId(1, kArbitraryToken)), 1.f,
samans72b2a282016-12-17 02:44:15110 gfx::Size(1, 1));
fsamuel1d3252c2017-02-15 20:56:37111 layer->SetPrimarySurfaceInfo(info);
fsamuele0f705b2016-10-01 14:07:14112 layer_tree_host_->GetSurfaceSequenceGenerator()->set_frame_sink_id(
113 FrameSinkId(1, 1));
khushalsagarb69ba9452017-01-27 22:20:07114 layer_tree_host_->SetRootLayer(layer);
jbaumandbccae1ab2014-11-06 23:26:44115
loyso2cb3f32f2016-11-08 07:08:34116 auto animation_host2 = AnimationHost::CreateForTesting(ThreadInstance::MAIN);
danakj60bc3bc2016-04-09 00:24:48117 std::unique_ptr<FakeLayerTreeHost> layer_tree_host2 =
loyso2cb3f32f2016-11-08 07:08:34118 FakeLayerTreeHost::Create(&fake_client_, &task_graph_runner_,
119 animation_host2.get());
samans72b2a282016-12-17 02:44:15120 auto layer2 = SurfaceLayer::Create(std::move(ref_factory));
fsamuel1d3252c2017-02-15 20:56:37121 layer2->SetPrimarySurfaceInfo(info);
fsamuele0f705b2016-10-01 14:07:14122 layer_tree_host2->GetSurfaceSequenceGenerator()->set_frame_sink_id(
123 FrameSinkId(2, 2));
jbaumandbccae1ab2014-11-06 23:26:44124 layer_tree_host2->SetRootLayer(layer2);
125
126 // Layers haven't been removed, so no sequence should be satisfied.
starazf907282a2016-11-09 21:06:58127 EXPECT_FALSE(blank_change.is_valid());
jbaumandbccae1ab2014-11-06 23:26:44128
fsamuele0f705b2016-10-01 14:07:14129 SurfaceSequence expected1(FrameSinkId(1, 1), 1u);
130 SurfaceSequence expected2(FrameSinkId(2, 2), 1u);
jbaumandbccae1ab2014-11-06 23:26:44131
132 layer_tree_host2->SetRootLayer(nullptr);
133 layer_tree_host2.reset();
loyso2cb3f32f2016-11-08 07:08:34134 animation_host2 = nullptr;
jbaumandbccae1ab2014-11-06 23:26:44135
136 // Layer was removed so sequence from second LayerTreeHost should be
137 // satisfied.
ksakamoto73809d9ee2016-12-16 08:02:58138 base::RunLoop().RunUntilIdle();
jbaumandbccae1ab2014-11-06 23:26:44139 EXPECT_TRUE(blank_change == expected2);
140
141 // Set of sequences that need to be satisfied should include sequences from
142 // both trees.
staraz7d7f6eb2016-11-11 00:19:17143 EXPECT_TRUE(required_id == SurfaceId(kArbitraryFrameSinkId,
samans5258bfb2017-01-27 21:16:26144 LocalSurfaceId(1, kArbitraryToken)));
jbaumandbccae1ab2014-11-06 23:26:44145 EXPECT_EQ(2u, required_seq.size());
146 EXPECT_TRUE(required_seq.count(expected1));
147 EXPECT_TRUE(required_seq.count(expected2));
148
khushalsagarb69ba9452017-01-27 22:20:07149 layer_tree_host_->SetRootLayer(nullptr);
jbaumandbccae1ab2014-11-06 23:26:44150 layer_tree_host_.reset();
151
152 // Layer was removed so sequence from first LayerTreeHost should be
153 // satisfied.
ksakamoto73809d9ee2016-12-16 08:02:58154 base::RunLoop().RunUntilIdle();
jbaumandbccae1ab2014-11-06 23:26:44155 EXPECT_TRUE(blank_change == expected1);
156
157 // No more SurfaceSequences should have been generated that need to have be
158 // satisfied.
159 EXPECT_EQ(2u, required_seq.size());
160}
161
fsamuel1d3252c2017-02-15 20:56:37162// This test verifies that the primary and fallback SurfaceInfo are pushed
163// across from SurfaceLayer to SurfaceLayerImpl.
164TEST_F(SurfaceLayerTest, SurfaceInfoPushProperties) {
165 SurfaceSequence blank_change;
166 SurfaceId required_id;
167 std::set<SurfaceSequence> required_sequences;
168 scoped_refptr<SurfaceReferenceFactory> ref_factory =
169 new TestSurfaceReferenceFactory(&blank_change, &required_id,
170 &required_sequences);
171
172 scoped_refptr<SurfaceLayer> layer = SurfaceLayer::Create(ref_factory);
173 layer_tree_host_->SetRootLayer(layer);
174 SurfaceInfo primary_info(
175 SurfaceId(kArbitraryFrameSinkId,
176 LocalSurfaceId(1, base::UnguessableToken::Create())),
177 1.f, gfx::Size(1, 1));
178 layer->SetPrimarySurfaceInfo(primary_info);
179
180 std::unique_ptr<SurfaceLayerImpl> layer_impl =
181 SurfaceLayerImpl::Create(host_impl_.pending_tree(), layer->id());
182 layer->PushPropertiesTo(layer_impl.get());
183
184 // Verify tha the primary SurfaceInfo is pushed through and that there is
185 // no valid fallback SurfaceInfo.
186 EXPECT_EQ(primary_info, layer_impl->primary_surface_info());
187 EXPECT_EQ(SurfaceInfo(), layer_impl->fallback_surface_info());
188
189 SurfaceInfo fallback_info(
190 SurfaceId(kArbitraryFrameSinkId,
191 LocalSurfaceId(2, base::UnguessableToken::Create())),
192 2.f, gfx::Size(10, 10));
193 layer->SetFallbackSurfaceInfo(fallback_info);
194 layer->PushPropertiesTo(layer_impl.get());
195
196 // Verify that the primary SurfaceInfo stays the same and the new fallback
197 // SurfaceInfo is pushed through.
198 EXPECT_EQ(primary_info, layer_impl->primary_surface_info());
199 EXPECT_EQ(fallback_info, layer_impl->fallback_surface_info());
200}
201
jbaumandbccae1ab2014-11-06 23:26:44202// Check that SurfaceSequence is sent through swap promise.
203class SurfaceLayerSwapPromise : public LayerTreeTest {
204 public:
205 SurfaceLayerSwapPromise()
206 : commit_count_(0), sequence_was_satisfied_(false) {}
207
208 void BeginTest() override {
fsamuele0f705b2016-10-01 14:07:14209 layer_tree_host()->GetSurfaceSequenceGenerator()->set_frame_sink_id(
210 FrameSinkId(1, 1));
samans72b2a282016-12-17 02:44:15211 layer_ = SurfaceLayer::Create(new TestSurfaceReferenceFactory(
212 &satisfied_sequence_, &required_id_, &required_set_));
213 SurfaceInfo info(
samans5258bfb2017-01-27 21:16:26214 SurfaceId(kArbitraryFrameSinkId, LocalSurfaceId(1, kArbitraryToken)),
215 1.f, gfx::Size(1, 1));
fsamuel1d3252c2017-02-15 20:56:37216 layer_->SetPrimarySurfaceInfo(info);
jbaumandbccae1ab2014-11-06 23:26:44217
218 // Layer hasn't been added to tree so no SurfaceSequence generated yet.
219 EXPECT_EQ(0u, required_set_.size());
220
khushalsagarb69ba9452017-01-27 22:20:07221 layer_tree_host()->SetRootLayer(layer_);
jbaumandbccae1ab2014-11-06 23:26:44222
223 // Should have SurfaceSequence from first tree.
fsamuele0f705b2016-10-01 14:07:14224 SurfaceSequence expected(kArbitraryFrameSinkId, 1u);
staraz7d7f6eb2016-11-11 00:19:17225 EXPECT_TRUE(required_id_ == SurfaceId(kArbitraryFrameSinkId,
samans5258bfb2017-01-27 21:16:26226 LocalSurfaceId(1, kArbitraryToken)));
jbaumandbccae1ab2014-11-06 23:26:44227 EXPECT_EQ(1u, required_set_.size());
228 EXPECT_TRUE(required_set_.count(expected));
229
230 gfx::Size bounds(100, 100);
khushalsagarb69ba9452017-01-27 22:20:07231 layer_tree_host()->SetViewportSize(bounds);
tobiasjs2e02f73e2015-09-02 12:08:03232
loyso0940d412016-03-14 01:30:31233 blank_layer_ = SolidColorLayer::Create();
tobiasjs2e02f73e2015-09-02 12:08:03234 blank_layer_->SetIsDrawable(true);
235 blank_layer_->SetBounds(gfx::Size(10, 10));
236
jbaumandbccae1ab2014-11-06 23:26:44237 PostSetNeedsCommitToMainThread();
238 }
239
tobiasjs2e02f73e2015-09-02 12:08:03240 virtual void ChangeTree() = 0;
241
sohan.jyoti6e8cb7032015-01-08 20:01:27242 void DidCommitAndDrawFrame() override {
skyostil0fd1dad2015-04-13 20:11:48243 base::ThreadTaskRunnerHandle::Get()->PostTask(
jbaumandbccae1ab2014-11-06 23:26:44244 FROM_HERE, base::Bind(&SurfaceLayerSwapPromise::ChangeTree,
245 base::Unretained(this)));
246 }
247
tobiasjs2e02f73e2015-09-02 12:08:03248 protected:
249 int commit_count_;
250 bool sequence_was_satisfied_;
251 scoped_refptr<SurfaceLayer> layer_;
252 scoped_refptr<Layer> blank_layer_;
253 SurfaceSequence satisfied_sequence_;
254
255 SurfaceId required_id_;
256 std::set<SurfaceSequence> required_set_;
staraz7d7f6eb2016-11-11 00:19:17257 const base::UnguessableToken kArbitraryToken =
258 base::UnguessableToken::Create();
tobiasjs2e02f73e2015-09-02 12:08:03259};
260
261// Check that SurfaceSequence is sent through swap promise.
262class SurfaceLayerSwapPromiseWithDraw : public SurfaceLayerSwapPromise {
263 public:
tobiasjs2e02f73e2015-09-02 12:08:03264 void ChangeTree() override {
jbaumandbccae1ab2014-11-06 23:26:44265 ++commit_count_;
266 switch (commit_count_) {
267 case 1:
268 // Remove SurfaceLayer from tree to cause SwapPromise to be created.
khushalsagarb69ba9452017-01-27 22:20:07269 layer_tree_host()->SetRootLayer(blank_layer_);
jbaumandbccae1ab2014-11-06 23:26:44270 break;
271 case 2:
ksakamoto73809d9ee2016-12-16 08:02:58272 EndTest();
jbaumandbccae1ab2014-11-06 23:26:44273 break;
274 default:
275 NOTREACHED();
276 break;
277 }
278 }
279
jbaumandbccae1ab2014-11-06 23:26:44280 void AfterTest() override {
staraz7d7f6eb2016-11-11 00:19:17281 EXPECT_TRUE(required_id_ == SurfaceId(kArbitraryFrameSinkId,
samans5258bfb2017-01-27 21:16:26282 LocalSurfaceId(1, kArbitraryToken)));
jbaumandbccae1ab2014-11-06 23:26:44283 EXPECT_EQ(1u, required_set_.size());
ksakamoto73809d9ee2016-12-16 08:02:58284 EXPECT_TRUE(satisfied_sequence_ ==
285 SurfaceSequence(kArbitraryFrameSinkId, 1u));
jbaumandbccae1ab2014-11-06 23:26:44286 }
jbaumandbccae1ab2014-11-06 23:26:44287};
288
danakj6021ec32016-07-22 22:16:08289SINGLE_AND_MULTI_THREAD_TEST_F(SurfaceLayerSwapPromiseWithDraw);
tobiasjs2e02f73e2015-09-02 12:08:03290
291// Check that SurfaceSequence is sent through swap promise and resolved when
292// swap fails.
293class SurfaceLayerSwapPromiseWithoutDraw : public SurfaceLayerSwapPromise {
294 public:
295 SurfaceLayerSwapPromiseWithoutDraw() : SurfaceLayerSwapPromise() {}
296
297 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
298 LayerTreeHostImpl::FrameData* frame,
299 DrawResult draw_result) override {
300 return DRAW_ABORTED_MISSING_HIGH_RES_CONTENT;
301 }
302
303 void ChangeTree() override {
304 ++commit_count_;
305 switch (commit_count_) {
306 case 1:
307 // Remove SurfaceLayer from tree to cause SwapPromise to be created.
khushalsagarb69ba9452017-01-27 22:20:07308 layer_tree_host()->SetRootLayer(blank_layer_);
tobiasjs2e02f73e2015-09-02 12:08:03309 break;
310 case 2:
311 layer_tree_host()->SetNeedsCommit();
312 break;
313 default:
314 EndTest();
315 break;
316 }
317 }
318
319 void AfterTest() override {
staraz7d7f6eb2016-11-11 00:19:17320 EXPECT_TRUE(required_id_ == SurfaceId(kArbitraryFrameSinkId,
samans5258bfb2017-01-27 21:16:26321 LocalSurfaceId(1, kArbitraryToken)));
tobiasjs2e02f73e2015-09-02 12:08:03322 EXPECT_EQ(1u, required_set_.size());
fsamuele0f705b2016-10-01 14:07:14323 EXPECT_TRUE(satisfied_sequence_ ==
324 SurfaceSequence(kArbitraryFrameSinkId, 1u));
tobiasjs2e02f73e2015-09-02 12:08:03325 }
326};
327
328MULTI_THREAD_TEST_F(SurfaceLayerSwapPromiseWithoutDraw);
jbaumandbccae1ab2014-11-06 23:26:44329
330} // namespace
331} // namespace cc