1 // 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
5 #include <stdint.h>
6
7 #include <iostream>
8 #include <set>
9 #include <vector>
10
11 #include "base/location.h"
12 #include "base/run_loop.h"
13 #include "base/single_thread_task_runner.h"
14 #include "base/threading/thread_task_runner_handle.h"
15 #include "base/time/time.h"
16 #include "cc/animation/animation_host.h"
17 #include "cc/layers/solid_color_layer.h"
18 #include "cc/layers/surface_layer.h"
19 #include "cc/layers/surface_layer_impl.h"
20 #include "cc/test/fake_impl_task_runner_provider.h"
21 #include "cc/test/fake_layer_tree_host.h"
22 #include "cc/test/fake_layer_tree_host_client.h"
23 #include "cc/test/fake_layer_tree_host_impl.h"
24 #include "cc/test/layer_tree_test.h"
25 #include "cc/test/test_task_graph_runner.h"
26 #include "cc/trees/layer_tree_host.h"
27 #include "components/viz/common/quads/compositor_frame.h"
28 #include "components/viz/common/surfaces/surface_info.h"
29 #include "testing/gmock/include/gmock/gmock.h"
30 #include "testing/gtest/include/gtest/gtest.h"
31
32 namespace cc {
33 namespace {
34
35 using testing::_;
36 using testing::Eq;
37 using testing::ElementsAre;
38 using testing::SizeIs;
39
40 constexpr viz::FrameSinkId kArbitraryFrameSinkId(1, 1);
41
42 class SurfaceLayerTest : public testing::Test {
43 public:
SurfaceLayerTest()44 SurfaceLayerTest()
45 : host_impl_(&task_runner_provider_, &task_graph_runner_) {}
46
47 // Synchronizes |layer_tree_host_| and |host_impl_| and pushes surface ids.
SynchronizeTrees()48 void SynchronizeTrees() {
49 TreeSynchronizer::PushLayerProperties(layer_tree_host_.get(),
50 host_impl_.pending_tree());
51 layer_tree_host_->PushSurfaceRangesTo(host_impl_.pending_tree());
52 }
53
54 protected:
SetUp()55 void SetUp() override {
56 animation_host_ = AnimationHost::CreateForTesting(ThreadInstance::MAIN);
57 layer_tree_host_ = FakeLayerTreeHost::Create(
58 &fake_client_, &task_graph_runner_, animation_host_.get());
59 layer_tree_host_->SetViewportRectAndScale(gfx::Rect(10, 10), 1.f,
60 viz::LocalSurfaceId());
61 host_impl_.CreatePendingTree();
62 }
63
TearDown()64 void TearDown() override {
65 if (layer_tree_host_) {
66 layer_tree_host_->SetRootLayer(nullptr);
67 layer_tree_host_ = nullptr;
68 }
69 }
70
71 FakeLayerTreeHostClient fake_client_;
72 FakeImplTaskRunnerProvider task_runner_provider_;
73 TestTaskGraphRunner task_graph_runner_;
74 std::unique_ptr<AnimationHost> animation_host_;
75 std::unique_ptr<FakeLayerTreeHost> layer_tree_host_;
76 FakeLayerTreeHostImpl host_impl_;
77 };
78
79 // This test verifies that if UseExistingDeadline() is used on a new
80 // SurfaceLayer then the deadline will be 0 frames.
TEST_F(SurfaceLayerTest,UseExistingDeadlineForNewSurfaceLayer)81 TEST_F(SurfaceLayerTest, UseExistingDeadlineForNewSurfaceLayer) {
82 scoped_refptr<SurfaceLayer> layer = SurfaceLayer::Create();
83 layer_tree_host_->SetRootLayer(layer);
84 viz::SurfaceId primary_id(
85 kArbitraryFrameSinkId,
86 viz::LocalSurfaceId(1, base::UnguessableToken::Create()));
87 layer->SetSurfaceId(primary_id, DeadlinePolicy::UseExistingDeadline());
88 EXPECT_EQ(0u, layer->deadline_in_frames());
89 }
90
91 // This test verifies that if UseInfiniteDeadline() is used on a new
92 // SurfaceLayer then the deadline will be max number of frames.
TEST_F(SurfaceLayerTest,UseInfiniteDeadlineForNewSurfaceLayer)93 TEST_F(SurfaceLayerTest, UseInfiniteDeadlineForNewSurfaceLayer) {
94 scoped_refptr<SurfaceLayer> layer = SurfaceLayer::Create();
95 layer_tree_host_->SetRootLayer(layer);
96 viz::SurfaceId primary_id(
97 kArbitraryFrameSinkId,
98 viz::LocalSurfaceId(1, base::UnguessableToken::Create()));
99 layer->SetSurfaceId(primary_id, DeadlinePolicy::UseInfiniteDeadline());
100 EXPECT_EQ(std::numeric_limits<uint32_t>::max(), layer->deadline_in_frames());
101 }
102
103 // This test verifies that if an invalid primary surface ID is set then the
104 // deadline will be reset to 0 frames.
TEST_F(SurfaceLayerTest,ResetDeadlineOnInvalidSurfaceId)105 TEST_F(SurfaceLayerTest, ResetDeadlineOnInvalidSurfaceId) {
106 scoped_refptr<SurfaceLayer> layer = SurfaceLayer::Create();
107 layer_tree_host_->SetRootLayer(layer);
108 viz::SurfaceId primary_id(
109 kArbitraryFrameSinkId,
110 viz::LocalSurfaceId(1, base::UnguessableToken::Create()));
111 layer->SetSurfaceId(primary_id, DeadlinePolicy::UseSpecifiedDeadline(3u));
112 EXPECT_EQ(3u, layer->deadline_in_frames());
113
114 // Reset the surface layer to an invalid SurfaceId. Verify that the deadline
115 // is reset.
116 layer->SetSurfaceId(viz::SurfaceId(),
117 DeadlinePolicy::UseSpecifiedDeadline(3u));
118 EXPECT_EQ(0u, layer->deadline_in_frames());
119 }
120
121 // This test verifies that SurfaceLayer properties are pushed across to
122 // SurfaceLayerImpl.
TEST_F(SurfaceLayerTest,PushProperties)123 TEST_F(SurfaceLayerTest, PushProperties) {
124 scoped_refptr<SurfaceLayer> layer = SurfaceLayer::Create();
125 layer_tree_host_->SetRootLayer(layer);
126 viz::SurfaceId primary_id(
127 kArbitraryFrameSinkId,
128 viz::LocalSurfaceId(1, base::UnguessableToken::Create()));
129 layer->SetSurfaceId(primary_id, DeadlinePolicy::UseSpecifiedDeadline(1u));
130 layer->SetSurfaceId(primary_id, DeadlinePolicy::UseSpecifiedDeadline(2u));
131 layer->SetSurfaceId(primary_id, DeadlinePolicy::UseExistingDeadline());
132 layer->SetOldestAcceptableFallback(primary_id);
133 layer->SetBackgroundColor(SK_ColorBLUE);
134 layer->SetStretchContentToFillBounds(true);
135
136 EXPECT_TRUE(layer_tree_host_->needs_surface_ranges_sync());
137 EXPECT_EQ(layer_tree_host_->SurfaceRanges().size(), 1u);
138
139 // Verify that pending tree has no surface ids already.
140 EXPECT_FALSE(host_impl_.pending_tree()->needs_surface_ranges_sync());
141 EXPECT_EQ(host_impl_.pending_tree()->SurfaceRanges().size(), 0u);
142
143 std::unique_ptr<SurfaceLayerImpl> layer_impl =
144 SurfaceLayerImpl::Create(host_impl_.pending_tree(), layer->id());
145 SynchronizeTrees();
146
147 // Verify that pending tree received the surface id and also has
148 // needs_surface_ranges_sync set to true as it needs to sync with active tree.
149 EXPECT_TRUE(host_impl_.pending_tree()->needs_surface_ranges_sync());
150 EXPECT_EQ(host_impl_.pending_tree()->SurfaceRanges().size(), 1u);
151
152 // Verify we have reset the state on layer tree host.
153 EXPECT_FALSE(layer_tree_host_->needs_surface_ranges_sync());
154
155 // Verify that the primary and fallback SurfaceIds are pushed through.
156 EXPECT_EQ(primary_id, layer_impl->range().end());
157 EXPECT_EQ(primary_id, layer_impl->range().start());
158 EXPECT_EQ(SK_ColorBLUE, layer_impl->background_color());
159 EXPECT_TRUE(layer_impl->stretch_content_to_fill_bounds());
160 EXPECT_EQ(2u, layer_impl->deadline_in_frames());
161
162 viz::SurfaceId fallback_id(
163 kArbitraryFrameSinkId,
164 viz::LocalSurfaceId(2, base::UnguessableToken::Create()));
165 layer->SetOldestAcceptableFallback(fallback_id);
166 layer->SetSurfaceId(fallback_id, DeadlinePolicy::UseExistingDeadline());
167 layer->SetBackgroundColor(SK_ColorGREEN);
168 layer->SetStretchContentToFillBounds(false);
169
170 // Verify that fallback surface id is not recorded on the layer tree host as
171 // surface synchronization is not enabled.
172 EXPECT_TRUE(layer_tree_host_->needs_surface_ranges_sync());
173 EXPECT_EQ(layer_tree_host_->SurfaceRanges().size(), 1u);
174
175 SynchronizeTrees();
176
177 EXPECT_EQ(host_impl_.pending_tree()->SurfaceRanges().size(), 1u);
178
179 // Verify that the primary viz::SurfaceId stays the same and the new
180 // fallback viz::SurfaceId is pushed through.
181 EXPECT_EQ(fallback_id, layer_impl->range().end());
182 EXPECT_EQ(fallback_id, layer_impl->range().start());
183 EXPECT_EQ(SK_ColorGREEN, layer_impl->background_color());
184 // The deadline resets back to 0 (no deadline) after the first commit.
185 EXPECT_EQ(0u, layer_impl->deadline_in_frames());
186 EXPECT_FALSE(layer_impl->stretch_content_to_fill_bounds());
187 }
188
189 // This test verifies the list of surface ids is correct when there are cloned
190 // surface layers. This emulates the flow of maximize and minimize animations on
191 // Chrome OS.
TEST_F(SurfaceLayerTest,CheckSurfaceReferencesForClonedLayer)192 TEST_F(SurfaceLayerTest, CheckSurfaceReferencesForClonedLayer) {
193 const viz::SurfaceId old_surface_id(
194 kArbitraryFrameSinkId,
195 viz::LocalSurfaceId(1, base::UnguessableToken::Create()));
196
197 // This layer will always contain the old surface id and will be deleted when
198 // animation is done.
199 scoped_refptr<SurfaceLayer> layer1 = SurfaceLayer::Create();
200 layer1->SetLayerTreeHost(layer_tree_host_.get());
201 layer1->SetSurfaceId(old_surface_id, DeadlinePolicy::UseDefaultDeadline());
202 layer1->SetOldestAcceptableFallback(old_surface_id);
203
204 // This layer will eventually be switched be switched to show the new surface
205 // id and will be retained when animation is done.
206 scoped_refptr<SurfaceLayer> layer2 = SurfaceLayer::Create();
207 layer2->SetLayerTreeHost(layer_tree_host_.get());
208 layer2->SetSurfaceId(old_surface_id, DeadlinePolicy::UseDefaultDeadline());
209 layer2->SetOldestAcceptableFallback(old_surface_id);
210
211 std::unique_ptr<SurfaceLayerImpl> layer_impl1 =
212 SurfaceLayerImpl::Create(host_impl_.pending_tree(), layer1->id());
213 std::unique_ptr<SurfaceLayerImpl> layer_impl2 =
214 SurfaceLayerImpl::Create(host_impl_.pending_tree(), layer2->id());
215
216 SynchronizeTrees();
217
218 // Verify that only |old_surface_id| is going to be referenced.
219 EXPECT_THAT(layer_tree_host_->SurfaceRanges(),
220 ElementsAre(viz::SurfaceRange(old_surface_id)));
221 EXPECT_THAT(host_impl_.pending_tree()->SurfaceRanges(),
222 ElementsAre(viz::SurfaceRange(old_surface_id)));
223
224 const viz::SurfaceId new_surface_id(
225 kArbitraryFrameSinkId,
226 viz::LocalSurfaceId(2, base::UnguessableToken::Create()));
227
228 // Switch the new layer to use |new_surface_id|.
229 layer2->SetSurfaceId(new_surface_id, DeadlinePolicy::UseDefaultDeadline());
230 layer2->SetOldestAcceptableFallback(new_surface_id);
231
232 SynchronizeTrees();
233
234 // Verify that both surface ids are going to be referenced.
235 EXPECT_THAT(layer_tree_host_->SurfaceRanges(),
236 ElementsAre(viz::SurfaceRange(old_surface_id),
237 viz::SurfaceRange(new_surface_id)));
238 EXPECT_THAT(host_impl_.pending_tree()->SurfaceRanges(),
239 ElementsAre(viz::SurfaceRange(old_surface_id),
240 viz::SurfaceRange(new_surface_id)));
241
242 // Unparent the old layer like it's being destroyed at the end of animation.
243 layer1->SetLayerTreeHost(nullptr);
244
245 SynchronizeTrees();
246
247 // Verify that only |new_surface_id| is going to be referenced.
248 EXPECT_THAT(layer_tree_host_->SurfaceRanges(),
249 ElementsAre(viz::SurfaceRange(new_surface_id)));
250 EXPECT_THAT(host_impl_.pending_tree()->SurfaceRanges(),
251 ElementsAre(viz::SurfaceRange(new_surface_id)));
252
253 // Cleanup for destruction.
254 layer2->SetLayerTreeHost(nullptr);
255 }
256
257 // This test verifies LayerTreeHost::needs_surface_ranges_sync() is correct when
258 // there are cloned surface layers.
TEST_F(SurfaceLayerTest,CheckNeedsSurfaceIdsSyncForClonedLayers)259 TEST_F(SurfaceLayerTest, CheckNeedsSurfaceIdsSyncForClonedLayers) {
260 const viz::SurfaceId surface_id(
261 kArbitraryFrameSinkId,
262 viz::LocalSurfaceId(1, base::UnguessableToken::Create()));
263
264 scoped_refptr<SurfaceLayer> layer1 = SurfaceLayer::Create();
265 layer1->SetLayerTreeHost(layer_tree_host_.get());
266 layer1->SetSurfaceId(surface_id, DeadlinePolicy::UseDefaultDeadline());
267 layer1->SetOldestAcceptableFallback(surface_id);
268
269 // Verify the surface id is in SurfaceLayerIds() and
270 // needs_surface_ranges_sync() is true.
271 EXPECT_TRUE(layer_tree_host_->needs_surface_ranges_sync());
272 EXPECT_THAT(layer_tree_host_->SurfaceRanges(), SizeIs(1));
273
274 std::unique_ptr<SurfaceLayerImpl> layer_impl1 =
275 SurfaceLayerImpl::Create(host_impl_.pending_tree(), layer1->id());
276 SynchronizeTrees();
277
278 // After syncchronizing trees verify needs_surface_ranges_sync() is false.
279 EXPECT_FALSE(layer_tree_host_->needs_surface_ranges_sync());
280
281 // Create the second layer that is a clone of the first.
282 scoped_refptr<SurfaceLayer> layer2 = SurfaceLayer::Create();
283 layer2->SetLayerTreeHost(layer_tree_host_.get());
284 layer2->SetSurfaceId(surface_id, DeadlinePolicy::UseDefaultDeadline());
285 layer2->SetOldestAcceptableFallback(surface_id);
286
287 // Verify that after creating the second layer with the same surface id that
288 // needs_surface_ranges_sync() is still false.
289 EXPECT_TRUE(layer_tree_host_->needs_surface_ranges_sync());
290 EXPECT_THAT(layer_tree_host_->SurfaceRanges(), SizeIs(1));
291
292 std::unique_ptr<SurfaceLayerImpl> layer_impl2 =
293 SurfaceLayerImpl::Create(host_impl_.pending_tree(), layer2->id());
294 SynchronizeTrees();
295
296 // Verify needs_surface_ranges_sync() is still false after synchronizing
297 // trees.
298 EXPECT_FALSE(layer_tree_host_->needs_surface_ranges_sync());
299
300 // Destroy one of the layers, leaving one layer with the surface id.
301 layer1->SetLayerTreeHost(nullptr);
302
303 // Verify needs_surface_ranges_sync() is still false.
304 EXPECT_FALSE(layer_tree_host_->needs_surface_ranges_sync());
305
306 // Destroy the last layer, this should change the set of layer surface ids.
307 layer2->SetLayerTreeHost(nullptr);
308
309 // Verify SurfaceLayerIds() is empty and needs_surface_ranges_sync() is true.
310 EXPECT_TRUE(layer_tree_host_->needs_surface_ranges_sync());
311 EXPECT_THAT(layer_tree_host_->SurfaceRanges(), SizeIs(0));
312 }
313
314 } // namespace
315 } // namespace cc
316