Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(597)

Side by Side Diff: cc/blimp/compositor_state_deserializer_unittest.cc

Issue 2375363002: cc/blimp: Set up the framework for state serialization. (Closed)
Patch Set: test update Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « cc/blimp/compositor_state_deserializer_client.h ('k') | cc/blimp/layer_factory.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2016 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 "compositor_state_deserializer.h"
6
7 #include "base/run_loop.h"
8 #include "cc/animation/animation_host.h"
9 #include "cc/blimp/compositor_proto_state.h"
10 #include "cc/blimp/compositor_state_deserializer_client.h"
11 #include "cc/blimp/layer_tree_host_remote.h"
12 #include "cc/proto/compositor_message.pb.h"
13 #include "cc/test/fake_layer_tree_host.h"
14 #include "cc/test/fake_layer_tree_host_client.h"
15 #include "cc/test/fake_remote_compositor_bridge.h"
16 #include "cc/test/remote_client_layer_factory.h"
17 #include "cc/test/stub_layer_tree_host_client.h"
18 #include "cc/test/test_task_graph_runner.h"
19 #include "cc/trees/layer_tree_host_common.h"
20 #include "testing/gtest/include/gtest/gtest.h"
21
22 namespace cc {
23 namespace {
24
25 #define EXPECT_LAYERS_EQ(engine_layer_id, client_layer) \
26 EXPECT_EQ( \
27 compositor_state_deserializer_->GetLayerForEngineId(engine_layer_id), \
28 client_layer);
29
30 class RemoteCompositorBridgeForTest : public FakeRemoteCompositorBridge {
31 public:
32 using ProtoFrameCallback = base::Callback<void(
33 std::unique_ptr<CompositorProtoState> compositor_proto_state)>;
34
35 RemoteCompositorBridgeForTest(
36 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
37 ProtoFrameCallback proto_frame_callback)
38 : FakeRemoteCompositorBridge(main_task_runner),
39 proto_frame_callback_(proto_frame_callback) {}
40
41 ~RemoteCompositorBridgeForTest() override = default;
42
43 void ProcessCompositorStateUpdate(
44 std::unique_ptr<CompositorProtoState> compositor_proto_state) override {
45 proto_frame_callback_.Run(std::move(compositor_proto_state));
46 }
47
48 private:
49 ProtoFrameCallback proto_frame_callback_;
50 };
51
52 class CompositorStateDeserializerTest
53 : public testing::Test,
54 public CompositorStateDeserializerClient {
55 public:
56 void SetUp() override {
57 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner =
58 base::ThreadTaskRunnerHandle::Get();
59
60 // Engine side setup.
61 LayerTreeHostRemote::InitParams params;
62 params.client = &layer_tree_host_client_remote_;
63 params.main_task_runner = main_task_runner;
64 params.animation_host = AnimationHost::CreateMainInstance();
65 params.remote_compositor_bridge =
66 base::MakeUnique<RemoteCompositorBridgeForTest>(
67 main_task_runner,
68 base::Bind(
69 &CompositorStateDeserializerTest::ProcessCompositorStateUpdate,
70 base::Unretained(this)));
71 LayerTreeSettings settings;
72 params.settings = &settings;
73
74 layer_tree_host_remote_ = base::MakeUnique<LayerTreeHostRemote>(&params);
75
76 // Client side setup.
77 layer_tree_host_in_process_ = FakeLayerTreeHost::Create(
78 &layer_tree_host_client_client_, &task_graph_runner_);
79 compositor_state_deserializer_ =
80 base::MakeUnique<CompositorStateDeserializer>(
81 layer_tree_host_in_process_.get(),
82 base::Bind(&CompositorStateDeserializerTest::LayerScrolled,
83 base::Unretained(this)),
84 this);
85 }
86
87 void TearDown() override {
88 layer_tree_host_remote_ = nullptr;
89 compositor_state_deserializer_ = nullptr;
90 layer_tree_host_in_process_ = nullptr;
91 }
92
93 void ProcessCompositorStateUpdate(
94 std::unique_ptr<CompositorProtoState> compositor_proto_state) {
95 // Immediately deserialize the state update.
96 compositor_state_deserializer_->DeserializeCompositorUpdate(
97 compositor_proto_state->compositor_message->layer_tree_host());
98 }
99
100 // CompositorStateDeserializer implementation.
101 bool ShouldRetainClientScroll(int engine_layer_id,
102 const gfx::ScrollOffset& new_offset) override {
103 return should_retain_client_scroll_;
104 }
105 bool ShouldRetainClientPageScale(float new_page_scale) override {
106 return should_retain_client_scale_;
107 }
108
109 void LayerScrolled(int engine_layer_id) {}
110
111 void VerifyTreesAreIdentical() {
112 LayerTree* engine_layer_tree = layer_tree_host_remote_->GetLayerTree();
113 LayerTree* client_layer_tree = layer_tree_host_in_process_->GetLayerTree();
114
115 if (engine_layer_tree->root_layer()) {
116 LayerTreeHostCommon::CallFunctionForEveryLayer(
117 engine_layer_tree, [this](Layer* engine_layer) {
118 VerifyLayersAreIdentical(
119 engine_layer,
120 compositor_state_deserializer_->GetLayerForEngineId(
121 engine_layer->id()));
122 });
123 } else {
124 EXPECT_EQ(layer_tree_host_in_process_->GetLayerTree()->root_layer(),
125 nullptr);
126 }
127
128 // Viewport layers.
129 // Overscroll Elasticty Layer.
130 Layer* client_overscroll_elasticity_layer =
131 client_layer_tree->overscroll_elasticity_layer();
132 if (engine_layer_tree->overscroll_elasticity_layer()) {
133 int engine_overscroll_elasticity_layer_id =
134 engine_layer_tree->overscroll_elasticity_layer()->id();
135
136 EXPECT_LAYERS_EQ(engine_overscroll_elasticity_layer_id,
137 client_overscroll_elasticity_layer);
138 } else {
139 EXPECT_EQ(client_overscroll_elasticity_layer, nullptr);
140 }
141
142 // PageScale Layer.
143 Layer* client_page_scale_layer = client_layer_tree->page_scale_layer();
144 if (engine_layer_tree->page_scale_layer()) {
145 int engine_page_scale_layer_id =
146 engine_layer_tree->page_scale_layer()->id();
147
148 EXPECT_LAYERS_EQ(engine_page_scale_layer_id, client_page_scale_layer);
149 } else {
150 EXPECT_EQ(client_page_scale_layer, nullptr);
151 }
152
153 // InnerViewportScroll Layer.
154 Layer* client_inner_viewport_layer =
155 client_layer_tree->inner_viewport_scroll_layer();
156 if (engine_layer_tree->inner_viewport_scroll_layer()) {
157 int engine_inner_viewport_layer_id =
158 engine_layer_tree->inner_viewport_scroll_layer()->id();
159
160 EXPECT_LAYERS_EQ(engine_inner_viewport_layer_id,
161 client_inner_viewport_layer);
162 } else {
163 EXPECT_EQ(client_inner_viewport_layer, nullptr);
164 }
165
166 // OuterViewportScroll Layer.
167 Layer* client_outer_viewport_layer =
168 client_layer_tree->outer_viewport_scroll_layer();
169 if (engine_layer_tree->outer_viewport_scroll_layer()) {
170 int engine_outer_viewport_layer_id =
171 engine_layer_tree->outer_viewport_scroll_layer()->id();
172
173 EXPECT_LAYERS_EQ(engine_outer_viewport_layer_id,
174 client_outer_viewport_layer);
175 } else {
176 EXPECT_EQ(client_outer_viewport_layer, nullptr);
177 }
178 }
179
180 void VerifyLayersAreIdentical(Layer* engine_layer, Layer* client_layer) {
181 ASSERT_NE(client_layer, nullptr);
182
183 LayerTree* client_layer_tree = layer_tree_host_in_process_->GetLayerTree();
184 EXPECT_EQ(client_layer_tree, client_layer->GetLayerTree());
185
186 // Parent.
187 if (engine_layer->parent()) {
188 int engine_parent_id = engine_layer->parent()->id();
189 EXPECT_LAYERS_EQ(engine_parent_id, client_layer->parent());
190 } else {
191 EXPECT_EQ(client_layer->parent(), nullptr);
192 }
193
194 // Mask Layers.
195 if (engine_layer->mask_layer()) {
196 int engine_mask_layer_id = engine_layer->mask_layer()->id();
197 EXPECT_LAYERS_EQ(engine_mask_layer_id, client_layer->mask_layer());
198 } else {
199 EXPECT_EQ(client_layer->mask_layer(), nullptr);
200 }
201
202 // Scroll parent.
203 if (engine_layer->scroll_parent()) {
204 int engine_scroll_parent_id = engine_layer->scroll_parent()->id();
205 EXPECT_LAYERS_EQ(engine_scroll_parent_id, client_layer->scroll_parent());
206 } else {
207 EXPECT_EQ(client_layer->scroll_parent(), nullptr);
208 }
209
210 // Clip parent.
211 if (engine_layer->clip_parent()) {
212 int engine_clip_parent_id = engine_layer->clip_parent()->id();
213 EXPECT_LAYERS_EQ(engine_clip_parent_id, client_layer->clip_parent());
214 } else {
215 EXPECT_EQ(client_layer->clip_parent(), nullptr);
216 }
217
218 // Scroll-clip layer.
219 if (engine_layer->scroll_clip_layer()) {
220 int scroll_clip_id = engine_layer->scroll_clip_layer()->id();
221 EXPECT_LAYERS_EQ(scroll_clip_id, client_layer->scroll_clip_layer());
222 } else {
223 EXPECT_EQ(client_layer->scroll_clip_layer(), nullptr);
224 }
225 }
226
227 // Engine setup.
228 std::unique_ptr<LayerTreeHostRemote> layer_tree_host_remote_;
229 StubLayerTreeHostClient layer_tree_host_client_remote_;
230
231 // Client setup.
232 std::unique_ptr<FakeLayerTreeHost> layer_tree_host_in_process_;
233 std::unique_ptr<CompositorStateDeserializer> compositor_state_deserializer_;
234 FakeLayerTreeHostClient layer_tree_host_client_client_;
235 TestTaskGraphRunner task_graph_runner_;
236
237 bool should_retain_client_scroll_ = false;
238 bool should_retain_client_scale_ = false;
239 };
240
241 TEST_F(CompositorStateDeserializerTest, BasicSync) {
242 // Set up a tree with a single node.
243 scoped_refptr<Layer> root_layer = Layer::Create();
244 layer_tree_host_remote_->GetLayerTree()->SetRootLayer(root_layer);
245
246 // Synchronize State and verify.
247 base::RunLoop().RunUntilIdle();
248 VerifyTreesAreIdentical();
249
250 // Swap the root layer.
251 scoped_refptr<Layer> new_root_layer = Layer::Create();
252 new_root_layer->AddChild(Layer::Create());
253 new_root_layer->AddChild(Layer::Create());
254 layer_tree_host_remote_->GetLayerTree()->SetRootLayer(new_root_layer);
255
256 // Synchronize State and verify.
257 base::RunLoop().RunUntilIdle();
258 VerifyTreesAreIdentical();
259 // Verify that we are no longer tracking the destroyed layer on the client.
260 EXPECT_EQ(
261 compositor_state_deserializer_->GetLayerForEngineId(root_layer->id()),
262 nullptr);
263
264 // Remove the root layer to change to a null tree.
265 layer_tree_host_remote_->GetLayerTree()->SetRootLayer(nullptr);
266
267 // Synchronize State and verify.
268 base::RunLoop().RunUntilIdle();
269 VerifyTreesAreIdentical();
270 }
271
272 TEST_F(CompositorStateDeserializerTest, ViewportLayers) {
273 scoped_refptr<Layer> root_layer = Layer::Create();
274 layer_tree_host_remote_->GetLayerTree()->SetRootLayer(root_layer);
275
276 scoped_refptr<Layer> overscroll_elasticity_layer = Layer::Create();
277 scoped_refptr<Layer> inner_viewport_scroll_layer = Layer::Create();
278 scoped_refptr<Layer> outer_viewport_scroll_layer = Layer::Create();
279 scoped_refptr<Layer> page_scale_layer = Layer::Create();
280 layer_tree_host_remote_->GetLayerTree()->RegisterViewportLayers(
281 overscroll_elasticity_layer, page_scale_layer,
282 inner_viewport_scroll_layer, outer_viewport_scroll_layer);
283
284 root_layer->AddChild(overscroll_elasticity_layer);
285 overscroll_elasticity_layer->AddChild(page_scale_layer);
286 page_scale_layer->AddChild(inner_viewport_scroll_layer);
287 inner_viewport_scroll_layer->AddChild(outer_viewport_scroll_layer);
288
289 // Synchronize State and verify.
290 base::RunLoop().RunUntilIdle();
291 VerifyTreesAreIdentical();
292 }
293
294 TEST_F(CompositorStateDeserializerTest, ScrollClipAndMaskLayers) {
295 /* root -- A---C---D
296 / | \
297 / | E(MaskLayer)
298 / ------B */
299 scoped_refptr<Layer> root_layer = Layer::Create();
300 layer_tree_host_remote_->GetLayerTree()->SetRootLayer(root_layer);
301
302 scoped_refptr<Layer> layer_a = Layer::Create();
303 scoped_refptr<Layer> layer_b = Layer::Create();
304 scoped_refptr<Layer> layer_c = Layer::Create();
305 scoped_refptr<Layer> layer_d = Layer::Create();
306 scoped_refptr<Layer> layer_e = Layer::Create();
307
308 root_layer->AddChild(layer_a);
309 root_layer->AddChild(layer_b);
310 layer_a->AddChild(layer_c);
311 layer_c->AddChild(layer_d);
312
313 layer_a->SetMaskLayer(layer_e.get());
314 layer_c->SetScrollParent(layer_b.get());
315 layer_c->SetScrollClipLayerId(root_layer->id());
316 layer_d->SetClipParent(layer_a.get());
317
318 // Synchronize State and verify.
319 base::RunLoop().RunUntilIdle();
320 VerifyTreesAreIdentical();
321 }
322
323 TEST_F(CompositorStateDeserializerTest, ReconcileScrollAndScale) {
324 scoped_refptr<Layer> root_layer = Layer::Create();
325 layer_tree_host_remote_->GetLayerTree()->SetRootLayer(root_layer);
326
327 // Set scroll offset.
328 scoped_refptr<Layer> scroll_layer = Layer::Create();
329 root_layer->AddChild(scroll_layer);
330 gfx::ScrollOffset engine_offset(4, 3);
331 scroll_layer->SetScrollOffset(engine_offset);
332
333 // Set page scale.
334 float engine_page_scale = 0.5f;
335 layer_tree_host_remote_->GetLayerTree()->SetPageScaleFactorAndLimits(
336 engine_page_scale, 1.0, 1.0);
337
338 // Synchronize State and verify that the engine values are used.
339 base::RunLoop().RunUntilIdle();
340 VerifyTreesAreIdentical();
341
342 EXPECT_EQ(engine_page_scale,
343 layer_tree_host_in_process_->GetLayerTree()->page_scale_factor());
344 EXPECT_EQ(engine_offset, compositor_state_deserializer_
345 ->GetLayerForEngineId(scroll_layer->id())
346 ->scroll_offset());
347
348 // Now reset the scroll offset and page scale and force-retain the client
349 // values.
350 gfx::ScrollOffset new_engine_offset(2, 2);
351 scroll_layer->SetScrollOffset(new_engine_offset);
352 float new_engine_page_scale = 0.8f;
353 layer_tree_host_remote_->GetLayerTree()->SetPageScaleFactorAndLimits(
354 new_engine_page_scale, 1.0, 1.0);
355 should_retain_client_scroll_ = true;
356 should_retain_client_scale_ = true;
357
358 // Synchronize State and verify that the client values are retained.
359 base::RunLoop().RunUntilIdle();
360 VerifyTreesAreIdentical();
361
362 EXPECT_EQ(engine_page_scale,
363 layer_tree_host_in_process_->GetLayerTree()->page_scale_factor());
364 EXPECT_EQ(engine_offset, compositor_state_deserializer_
365 ->GetLayerForEngineId(scroll_layer->id())
366 ->scroll_offset());
367 }
368
369 TEST_F(CompositorStateDeserializerTest, PropertyTreesAreIdentical) {
370 // Override the LayerFactory. This is necessary to ensure the layer ids
371 // tracked in PropertyTrees on the engine and client are identical.
372 compositor_state_deserializer_->SetLayerFactoryForTesting(
373 base::MakeUnique<RemoteClientLayerFactory>());
374
375 scoped_refptr<Layer> root_layer = Layer::Create();
376 root_layer->SetBounds(gfx::Size(10, 10));
377 layer_tree_host_remote_->GetLayerTree()->SetRootLayer(root_layer);
378
379 scoped_refptr<Layer> child1 = Layer::Create();
380 root_layer->AddChild(child1);
381 gfx::Transform transform;
382 transform.Translate(gfx::Vector2dF(5, 4));
383 child1->SetTransform(transform);
384 child1->SetMasksToBounds(true);
385
386 scoped_refptr<Layer> child2 = Layer::Create();
387 root_layer->AddChild(child2);
388 child2->SetBounds(gfx::Size(5, 5));
389 child2->SetScrollOffset(gfx::ScrollOffset(3, 4));
390 child2->SetScrollParent(child1.get());
391 child2->SetUserScrollable(true, true);
392
393 scoped_refptr<Layer> grandchild11 = Layer::Create();
394 child1->AddChild(grandchild11);
395 grandchild11->SetClipParent(root_layer.get());
396
397 scoped_refptr<Layer> grandchild21 = Layer::Create();
398 child2->AddChild(grandchild21);
399 grandchild21->SetScrollClipLayerId(child1->id());
400 grandchild21->SetOpacity(0.5);
401
402 // Synchronize State and verify.
403 base::RunLoop().RunUntilIdle();
404 VerifyTreesAreIdentical();
405 EXPECT_EQ(root_layer->id(), layer_tree_host_in_process_->root_layer()->id());
406
407 // Sanity test to ensure that the PropertyTrees generated from the Layers on
408 // the client and engine are identical.
409 layer_tree_host_remote_->GetLayerTree()->BuildPropertyTreesForTesting();
410 PropertyTrees* engine_property_trees =
411 layer_tree_host_remote_->GetLayerTree()->property_trees();
412
413 layer_tree_host_in_process_->BuildPropertyTreesForTesting();
414 PropertyTrees* client_property_trees =
415 layer_tree_host_in_process_->property_trees();
416
417 EXPECT_EQ(*engine_property_trees, *client_property_trees);
418 }
419
420 } // namespace
421 } // namespace cc
OLDNEW
« no previous file with comments | « cc/blimp/compositor_state_deserializer_client.h ('k') | cc/blimp/layer_factory.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698