1 // Copyright 2011 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.
5 #include "cc/trees/tree_synchronizer.h"
11 #include "base/format_macros.h"
12 #include "base/strings/stringprintf.h"
13 #include "cc/animation/layer_animation_controller.h"
14 #include "cc/layers/layer.h"
15 #include "cc/layers/layer_impl.h"
16 #include "cc/test/animation_test_common.h"
17 #include "cc/test/fake_impl_proxy.h"
18 #include "cc/test/fake_layer_tree_host.h"
19 #include "cc/test/fake_rendering_stats_instrumentation.h"
20 #include "cc/test/test_shared_bitmap_manager.h"
21 #include "cc/test/test_task_graph_runner.h"
22 #include "cc/trees/proxy.h"
23 #include "cc/trees/single_thread_proxy.h"
24 #include "testing/gtest/include/gtest/gtest.h"
29 class MockLayerImpl
: public LayerImpl
{
31 static scoped_ptr
<MockLayerImpl
> Create(LayerTreeImpl
* tree_impl
,
33 return make_scoped_ptr(new MockLayerImpl(tree_impl
, layer_id
));
35 ~MockLayerImpl() override
{
36 if (layer_impl_destruction_list_
)
37 layer_impl_destruction_list_
->push_back(id());
40 void SetLayerImplDestructionList(std::vector
<int>* list
) {
41 layer_impl_destruction_list_
= list
;
45 MockLayerImpl(LayerTreeImpl
* tree_impl
, int layer_id
)
46 : LayerImpl(tree_impl
, layer_id
),
47 layer_impl_destruction_list_(NULL
) {}
49 std::vector
<int>* layer_impl_destruction_list_
;
52 class MockLayer
: public Layer
{
54 static scoped_refptr
<MockLayer
> Create(
55 const LayerSettings
& settings
,
56 std::vector
<int>* layer_impl_destruction_list
) {
57 return make_scoped_refptr(
58 new MockLayer(settings
, layer_impl_destruction_list
));
61 scoped_ptr
<LayerImpl
> CreateLayerImpl(LayerTreeImpl
* tree_impl
) override
{
62 return MockLayerImpl::Create(tree_impl
, layer_id_
);
65 void PushPropertiesTo(LayerImpl
* layer_impl
) override
{
66 Layer::PushPropertiesTo(layer_impl
);
68 MockLayerImpl
* mock_layer_impl
= static_cast<MockLayerImpl
*>(layer_impl
);
69 mock_layer_impl
->SetLayerImplDestructionList(layer_impl_destruction_list_
);
73 explicit MockLayer(const LayerSettings
& settings
,
74 std::vector
<int>* layer_impl_destruction_list
)
76 layer_impl_destruction_list_(layer_impl_destruction_list
) {}
77 ~MockLayer() override
{}
79 std::vector
<int>* layer_impl_destruction_list_
;
82 class FakeLayerAnimationController
: public LayerAnimationController
{
84 static scoped_refptr
<LayerAnimationController
> Create() {
85 return static_cast<LayerAnimationController
*>(
86 new FakeLayerAnimationController
);
89 bool SynchronizedAnimations() const { return synchronized_animations_
; }
92 FakeLayerAnimationController()
93 : LayerAnimationController(1),
94 synchronized_animations_(false) {}
96 ~FakeLayerAnimationController() override
{}
98 void PushAnimationUpdatesTo(
99 LayerAnimationController
* controller_impl
) override
{
100 LayerAnimationController::PushAnimationUpdatesTo(controller_impl
);
101 synchronized_animations_
= true;
104 bool synchronized_animations_
;
107 void ExpectTreesAreIdentical(Layer
* layer
,
108 LayerImpl
* layer_impl
,
109 LayerTreeImpl
* tree_impl
) {
111 ASSERT_TRUE(layer_impl
);
113 EXPECT_EQ(layer
->id(), layer_impl
->id());
114 EXPECT_EQ(layer_impl
->layer_tree_impl(), tree_impl
);
116 EXPECT_EQ(layer
->non_fast_scrollable_region(),
117 layer_impl
->non_fast_scrollable_region());
119 ASSERT_EQ(!!layer
->mask_layer(), !!layer_impl
->mask_layer());
120 if (layer
->mask_layer()) {
121 SCOPED_TRACE("mask_layer");
122 ExpectTreesAreIdentical(
123 layer
->mask_layer(), layer_impl
->mask_layer(), tree_impl
);
126 ASSERT_EQ(!!layer
->replica_layer(), !!layer_impl
->replica_layer());
127 if (layer
->replica_layer()) {
128 SCOPED_TRACE("replica_layer");
129 ExpectTreesAreIdentical(
130 layer
->replica_layer(), layer_impl
->replica_layer(), tree_impl
);
133 const LayerList
& layer_children
= layer
->children();
134 const OwnedLayerImplList
& layer_impl_children
= layer_impl
->children();
136 ASSERT_EQ(layer_children
.size(), layer_impl_children
.size());
138 const std::set
<Layer
*>* layer_scroll_children
= layer
->scroll_children();
139 const std::set
<LayerImpl
*>* layer_impl_scroll_children
=
140 layer_impl
->scroll_children();
142 ASSERT_EQ(!!layer_scroll_children
, !!layer_impl_scroll_children
);
144 if (layer_scroll_children
) {
146 layer_scroll_children
->size(),
147 layer_impl_scroll_children
->size());
150 const Layer
* layer_scroll_parent
= layer
->scroll_parent();
151 const LayerImpl
* layer_impl_scroll_parent
= layer_impl
->scroll_parent();
153 ASSERT_EQ(!!layer_scroll_parent
, !!layer_impl_scroll_parent
);
155 if (layer_scroll_parent
) {
156 ASSERT_EQ(layer_scroll_parent
->id(), layer_impl_scroll_parent
->id());
157 ASSERT_TRUE(layer_scroll_parent
->scroll_children()->find(layer
) !=
158 layer_scroll_parent
->scroll_children()->end());
159 ASSERT_TRUE(layer_impl_scroll_parent
->scroll_children()->find(layer_impl
) !=
160 layer_impl_scroll_parent
->scroll_children()->end());
163 const std::set
<Layer
*>* layer_clip_children
= layer
->clip_children();
164 const std::set
<LayerImpl
*>* layer_impl_clip_children
=
165 layer_impl
->clip_children();
167 ASSERT_EQ(!!layer_clip_children
, !!layer_impl_clip_children
);
169 if (layer_clip_children
)
170 ASSERT_EQ(layer_clip_children
->size(), layer_impl_clip_children
->size());
172 const Layer
* layer_clip_parent
= layer
->clip_parent();
173 const LayerImpl
* layer_impl_clip_parent
= layer_impl
->clip_parent();
175 ASSERT_EQ(!!layer_clip_parent
, !!layer_impl_clip_parent
);
177 if (layer_clip_parent
) {
178 const std::set
<LayerImpl
*>* clip_children_impl
=
179 layer_impl_clip_parent
->clip_children();
180 const std::set
<Layer
*>* clip_children
=
181 layer_clip_parent
->clip_children();
182 ASSERT_EQ(layer_clip_parent
->id(), layer_impl_clip_parent
->id());
183 ASSERT_TRUE(clip_children
->find(layer
) != clip_children
->end());
184 ASSERT_TRUE(clip_children_impl
->find(layer_impl
) !=
185 clip_children_impl
->end());
188 for (size_t i
= 0; i
< layer_children
.size(); ++i
) {
189 SCOPED_TRACE(base::StringPrintf("child layer %" PRIuS
, i
).c_str());
190 ExpectTreesAreIdentical(
191 layer_children
[i
].get(), layer_impl_children
[i
], tree_impl
);
195 class TreeSynchronizerTest
: public testing::Test
{
197 TreeSynchronizerTest()
198 : client_(FakeLayerTreeHostClient::DIRECT_3D
),
199 host_(FakeLayerTreeHost::Create(&client_
, &task_graph_runner_
)) {}
202 FakeLayerTreeHostClient client_
;
203 TestTaskGraphRunner task_graph_runner_
;
204 scoped_ptr
<FakeLayerTreeHost
> host_
;
205 LayerSettings layer_settings_
;
208 // Attempts to synchronizes a null tree. This should not crash, and should
209 // return a null tree.
210 TEST_F(TreeSynchronizerTest
, SyncNullTree
) {
211 scoped_ptr
<LayerImpl
> layer_impl_tree_root
=
212 TreeSynchronizer::SynchronizeTrees(
213 static_cast<Layer
*>(NULL
), nullptr, host_
->active_tree());
215 EXPECT_TRUE(!layer_impl_tree_root
.get());
218 // Constructs a very simple tree and synchronizes it without trying to reuse any
219 // preexisting layers.
220 TEST_F(TreeSynchronizerTest
, SyncSimpleTreeFromEmpty
) {
221 scoped_refptr
<Layer
> layer_tree_root
= Layer::Create(layer_settings_
);
222 layer_tree_root
->AddChild(Layer::Create(layer_settings_
));
223 layer_tree_root
->AddChild(Layer::Create(layer_settings_
));
225 host_
->SetRootLayer(layer_tree_root
);
227 scoped_ptr
<LayerImpl
> layer_impl_tree_root
=
228 TreeSynchronizer::SynchronizeTrees(
229 layer_tree_root
.get(), nullptr, host_
->active_tree());
231 ExpectTreesAreIdentical(layer_tree_root
.get(),
232 layer_impl_tree_root
.get(),
233 host_
->active_tree());
236 // Constructs a very simple tree and synchronizes it attempting to reuse some
238 TEST_F(TreeSynchronizerTest
, SyncSimpleTreeReusingLayers
) {
239 std::vector
<int> layer_impl_destruction_list
;
241 scoped_refptr
<Layer
> layer_tree_root
=
242 MockLayer::Create(layer_settings_
, &layer_impl_destruction_list
);
243 layer_tree_root
->AddChild(
244 MockLayer::Create(layer_settings_
, &layer_impl_destruction_list
));
245 layer_tree_root
->AddChild(
246 MockLayer::Create(layer_settings_
, &layer_impl_destruction_list
));
248 host_
->SetRootLayer(layer_tree_root
);
250 scoped_ptr
<LayerImpl
> layer_impl_tree_root
=
251 TreeSynchronizer::SynchronizeTrees(
252 layer_tree_root
.get(), nullptr, host_
->active_tree());
253 ExpectTreesAreIdentical(layer_tree_root
.get(),
254 layer_impl_tree_root
.get(),
255 host_
->active_tree());
257 // We have to push properties to pick up the destruction list pointer.
258 TreeSynchronizer::PushProperties(layer_tree_root
.get(),
259 layer_impl_tree_root
.get());
261 // Add a new layer to the Layer side
262 layer_tree_root
->children()[0]->AddChild(
263 MockLayer::Create(layer_settings_
, &layer_impl_destruction_list
));
265 layer_tree_root
->children()[1]->RemoveFromParent();
266 int second_layer_impl_id
= layer_impl_tree_root
->children()[1]->id();
268 // Synchronize again. After the sync the trees should be equivalent and we
269 // should have created and destroyed one LayerImpl.
270 layer_impl_tree_root
=
271 TreeSynchronizer::SynchronizeTrees(layer_tree_root
.get(),
272 layer_impl_tree_root
.Pass(),
273 host_
->active_tree());
274 ExpectTreesAreIdentical(layer_tree_root
.get(),
275 layer_impl_tree_root
.get(),
276 host_
->active_tree());
278 ASSERT_EQ(1u, layer_impl_destruction_list
.size());
279 EXPECT_EQ(second_layer_impl_id
, layer_impl_destruction_list
[0]);
282 // Constructs a very simple tree and checks that a stacking-order change is
284 TEST_F(TreeSynchronizerTest
, SyncSimpleTreeAndTrackStackingOrderChange
) {
285 std::vector
<int> layer_impl_destruction_list
;
287 // Set up the tree and sync once. child2 needs to be synced here, too, even
288 // though we remove it to set up the intended scenario.
289 scoped_refptr
<Layer
> layer_tree_root
=
290 MockLayer::Create(layer_settings_
, &layer_impl_destruction_list
);
291 scoped_refptr
<Layer
> child2
=
292 MockLayer::Create(layer_settings_
, &layer_impl_destruction_list
);
293 layer_tree_root
->AddChild(
294 MockLayer::Create(layer_settings_
, &layer_impl_destruction_list
));
295 layer_tree_root
->AddChild(child2
);
297 host_
->SetRootLayer(layer_tree_root
);
299 scoped_ptr
<LayerImpl
> layer_impl_tree_root
=
300 TreeSynchronizer::SynchronizeTrees(
301 layer_tree_root
.get(), nullptr, host_
->active_tree());
302 ExpectTreesAreIdentical(layer_tree_root
.get(),
303 layer_impl_tree_root
.get(),
304 host_
->active_tree());
306 // We have to push properties to pick up the destruction list pointer.
307 TreeSynchronizer::PushProperties(layer_tree_root
.get(),
308 layer_impl_tree_root
.get());
310 layer_impl_tree_root
->ResetAllChangeTrackingForSubtree();
312 // re-insert the layer and sync again.
313 child2
->RemoveFromParent();
314 layer_tree_root
->AddChild(child2
);
315 layer_impl_tree_root
=
316 TreeSynchronizer::SynchronizeTrees(layer_tree_root
.get(),
317 layer_impl_tree_root
.Pass(),
318 host_
->active_tree());
319 ExpectTreesAreIdentical(layer_tree_root
.get(),
320 layer_impl_tree_root
.get(),
321 host_
->active_tree());
323 TreeSynchronizer::PushProperties(layer_tree_root
.get(),
324 layer_impl_tree_root
.get());
326 // Check that the impl thread properly tracked the change.
327 EXPECT_FALSE(layer_impl_tree_root
->LayerPropertyChanged());
328 EXPECT_FALSE(layer_impl_tree_root
->children()[0]->LayerPropertyChanged());
329 EXPECT_TRUE(layer_impl_tree_root
->children()[1]->LayerPropertyChanged());
332 TEST_F(TreeSynchronizerTest
, SyncSimpleTreeAndProperties
) {
333 scoped_refptr
<Layer
> layer_tree_root
= Layer::Create(layer_settings_
);
334 layer_tree_root
->AddChild(Layer::Create(layer_settings_
));
335 layer_tree_root
->AddChild(Layer::Create(layer_settings_
));
337 host_
->SetRootLayer(layer_tree_root
);
339 // Pick some random properties to set. The values are not important, we're
340 // just testing that at least some properties are making it through.
341 gfx::PointF root_position
= gfx::PointF(2.3f
, 7.4f
);
342 layer_tree_root
->SetPosition(root_position
);
344 float first_child_opacity
= 0.25f
;
345 layer_tree_root
->children()[0]->SetOpacity(first_child_opacity
);
347 gfx::Size second_child_bounds
= gfx::Size(25, 53);
348 layer_tree_root
->children()[1]->SetBounds(second_child_bounds
);
349 layer_tree_root
->children()[1]->SavePaintProperties();
351 scoped_ptr
<LayerImpl
> layer_impl_tree_root
=
352 TreeSynchronizer::SynchronizeTrees(
353 layer_tree_root
.get(), nullptr, host_
->active_tree());
354 ExpectTreesAreIdentical(layer_tree_root
.get(),
355 layer_impl_tree_root
.get(),
356 host_
->active_tree());
358 TreeSynchronizer::PushProperties(layer_tree_root
.get(),
359 layer_impl_tree_root
.get());
361 // Check that the property values we set on the Layer tree are reflected in
362 // the LayerImpl tree.
363 gfx::PointF root_layer_impl_position
= layer_impl_tree_root
->position();
364 EXPECT_EQ(root_position
.x(), root_layer_impl_position
.x());
365 EXPECT_EQ(root_position
.y(), root_layer_impl_position
.y());
367 EXPECT_EQ(first_child_opacity
,
368 layer_impl_tree_root
->children()[0]->opacity());
370 gfx::Size second_layer_impl_child_bounds
=
371 layer_impl_tree_root
->children()[1]->bounds();
372 EXPECT_EQ(second_child_bounds
.width(),
373 second_layer_impl_child_bounds
.width());
374 EXPECT_EQ(second_child_bounds
.height(),
375 second_layer_impl_child_bounds
.height());
378 TEST_F(TreeSynchronizerTest
, ReuseLayerImplsAfterStructuralChange
) {
379 std::vector
<int> layer_impl_destruction_list
;
381 // Set up a tree with this sort of structure:
382 // root --- A --- B ---+--- C
385 scoped_refptr
<Layer
> layer_tree_root
=
386 MockLayer::Create(layer_settings_
, &layer_impl_destruction_list
);
387 layer_tree_root
->AddChild(
388 MockLayer::Create(layer_settings_
, &layer_impl_destruction_list
));
390 scoped_refptr
<Layer
> layer_a
= layer_tree_root
->children()[0].get();
392 MockLayer::Create(layer_settings_
, &layer_impl_destruction_list
));
394 scoped_refptr
<Layer
> layer_b
= layer_a
->children()[0].get();
396 MockLayer::Create(layer_settings_
, &layer_impl_destruction_list
));
398 scoped_refptr
<Layer
> layer_c
= layer_b
->children()[0].get();
400 MockLayer::Create(layer_settings_
, &layer_impl_destruction_list
));
401 scoped_refptr
<Layer
> layer_d
= layer_b
->children()[1].get();
403 host_
->SetRootLayer(layer_tree_root
);
405 scoped_ptr
<LayerImpl
> layer_impl_tree_root
=
406 TreeSynchronizer::SynchronizeTrees(
407 layer_tree_root
.get(), nullptr, host_
->active_tree());
408 ExpectTreesAreIdentical(layer_tree_root
.get(),
409 layer_impl_tree_root
.get(),
410 host_
->active_tree());
412 // We have to push properties to pick up the destruction list pointer.
413 TreeSynchronizer::PushProperties(layer_tree_root
.get(),
414 layer_impl_tree_root
.get());
416 // Now restructure the tree to look like this:
417 // root --- D ---+--- A
420 layer_tree_root
->RemoveAllChildren();
421 layer_d
->RemoveAllChildren();
422 layer_tree_root
->AddChild(layer_d
);
423 layer_a
->RemoveAllChildren();
424 layer_d
->AddChild(layer_a
);
425 layer_c
->RemoveAllChildren();
426 layer_d
->AddChild(layer_c
);
427 layer_b
->RemoveAllChildren();
428 layer_c
->AddChild(layer_b
);
430 // After another synchronize our trees should match and we should not have
431 // destroyed any LayerImpls
432 layer_impl_tree_root
=
433 TreeSynchronizer::SynchronizeTrees(layer_tree_root
.get(),
434 layer_impl_tree_root
.Pass(),
435 host_
->active_tree());
436 ExpectTreesAreIdentical(layer_tree_root
.get(),
437 layer_impl_tree_root
.get(),
438 host_
->active_tree());
440 EXPECT_EQ(0u, layer_impl_destruction_list
.size());
443 // Constructs a very simple tree, synchronizes it, then synchronizes to a
444 // totally new tree. All layers from the old tree should be deleted.
445 TEST_F(TreeSynchronizerTest
, SyncSimpleTreeThenDestroy
) {
446 std::vector
<int> layer_impl_destruction_list
;
448 scoped_refptr
<Layer
> old_layer_tree_root
=
449 MockLayer::Create(layer_settings_
, &layer_impl_destruction_list
);
450 old_layer_tree_root
->AddChild(
451 MockLayer::Create(layer_settings_
, &layer_impl_destruction_list
));
452 old_layer_tree_root
->AddChild(
453 MockLayer::Create(layer_settings_
, &layer_impl_destruction_list
));
455 host_
->SetRootLayer(old_layer_tree_root
);
457 int old_tree_root_layer_id
= old_layer_tree_root
->id();
458 int old_tree_first_child_layer_id
= old_layer_tree_root
->children()[0]->id();
459 int old_tree_second_child_layer_id
= old_layer_tree_root
->children()[1]->id();
461 scoped_ptr
<LayerImpl
> layer_impl_tree_root
=
462 TreeSynchronizer::SynchronizeTrees(
463 old_layer_tree_root
.get(), nullptr, host_
->active_tree());
464 ExpectTreesAreIdentical(old_layer_tree_root
.get(),
465 layer_impl_tree_root
.get(),
466 host_
->active_tree());
468 // We have to push properties to pick up the destruction list pointer.
469 TreeSynchronizer::PushProperties(old_layer_tree_root
.get(),
470 layer_impl_tree_root
.get());
472 // Remove all children on the Layer side.
473 old_layer_tree_root
->RemoveAllChildren();
475 // Synchronize again. After the sync all LayerImpls from the old tree should
477 scoped_refptr
<Layer
> new_layer_tree_root
= Layer::Create(layer_settings_
);
478 host_
->SetRootLayer(new_layer_tree_root
);
479 layer_impl_tree_root
=
480 TreeSynchronizer::SynchronizeTrees(new_layer_tree_root
.get(),
481 layer_impl_tree_root
.Pass(),
482 host_
->active_tree());
483 ExpectTreesAreIdentical(new_layer_tree_root
.get(),
484 layer_impl_tree_root
.get(),
485 host_
->active_tree());
487 ASSERT_EQ(3u, layer_impl_destruction_list
.size());
489 EXPECT_TRUE(std::find(layer_impl_destruction_list
.begin(),
490 layer_impl_destruction_list
.end(),
491 old_tree_root_layer_id
) !=
492 layer_impl_destruction_list
.end());
493 EXPECT_TRUE(std::find(layer_impl_destruction_list
.begin(),
494 layer_impl_destruction_list
.end(),
495 old_tree_first_child_layer_id
) !=
496 layer_impl_destruction_list
.end());
497 EXPECT_TRUE(std::find(layer_impl_destruction_list
.begin(),
498 layer_impl_destruction_list
.end(),
499 old_tree_second_child_layer_id
) !=
500 layer_impl_destruction_list
.end());
503 // Constructs+syncs a tree with mask, replica, and replica mask layers.
504 TEST_F(TreeSynchronizerTest
, SyncMaskReplicaAndReplicaMaskLayers
) {
505 scoped_refptr
<Layer
> layer_tree_root
= Layer::Create(layer_settings_
);
506 layer_tree_root
->AddChild(Layer::Create(layer_settings_
));
507 layer_tree_root
->AddChild(Layer::Create(layer_settings_
));
508 layer_tree_root
->AddChild(Layer::Create(layer_settings_
));
510 // First child gets a mask layer.
511 scoped_refptr
<Layer
> mask_layer
= Layer::Create(layer_settings_
);
512 layer_tree_root
->children()[0]->SetMaskLayer(mask_layer
.get());
514 // Second child gets a replica layer.
515 scoped_refptr
<Layer
> replica_layer
= Layer::Create(layer_settings_
);
516 layer_tree_root
->children()[1]->SetReplicaLayer(replica_layer
.get());
518 // Third child gets a replica layer with a mask layer.
519 scoped_refptr
<Layer
> replica_layer_with_mask
= Layer::Create(layer_settings_
);
520 scoped_refptr
<Layer
> replica_mask_layer
= Layer::Create(layer_settings_
);
521 replica_layer_with_mask
->SetMaskLayer(replica_mask_layer
.get());
522 layer_tree_root
->children()[2]->
523 SetReplicaLayer(replica_layer_with_mask
.get());
525 host_
->SetRootLayer(layer_tree_root
);
527 scoped_ptr
<LayerImpl
> layer_impl_tree_root
=
528 TreeSynchronizer::SynchronizeTrees(
529 layer_tree_root
.get(), nullptr, host_
->active_tree());
531 ExpectTreesAreIdentical(layer_tree_root
.get(),
532 layer_impl_tree_root
.get(),
533 host_
->active_tree());
535 // Remove the mask layer.
536 layer_tree_root
->children()[0]->SetMaskLayer(NULL
);
537 layer_impl_tree_root
=
538 TreeSynchronizer::SynchronizeTrees(layer_tree_root
.get(),
539 layer_impl_tree_root
.Pass(),
540 host_
->active_tree());
541 ExpectTreesAreIdentical(layer_tree_root
.get(),
542 layer_impl_tree_root
.get(),
543 host_
->active_tree());
545 // Remove the replica layer.
546 layer_tree_root
->children()[1]->SetReplicaLayer(NULL
);
547 layer_impl_tree_root
=
548 TreeSynchronizer::SynchronizeTrees(layer_tree_root
.get(),
549 layer_impl_tree_root
.Pass(),
550 host_
->active_tree());
551 ExpectTreesAreIdentical(layer_tree_root
.get(),
552 layer_impl_tree_root
.get(),
553 host_
->active_tree());
555 // Remove the replica mask.
556 replica_layer_with_mask
->SetMaskLayer(NULL
);
557 layer_impl_tree_root
=
558 TreeSynchronizer::SynchronizeTrees(layer_tree_root
.get(),
559 layer_impl_tree_root
.Pass(),
560 host_
->active_tree());
561 ExpectTreesAreIdentical(layer_tree_root
.get(),
562 layer_impl_tree_root
.get(),
563 host_
->active_tree());
566 TEST_F(TreeSynchronizerTest
, SynchronizeAnimations
) {
567 LayerTreeSettings settings
;
569 DebugScopedSetImplThread
impl(&proxy
);
570 FakeRenderingStatsInstrumentation stats_instrumentation
;
571 TestSharedBitmapManager shared_bitmap_manager
;
572 TestTaskGraphRunner task_graph_runner
;
573 scoped_ptr
<LayerTreeHostImpl
> host_impl
= LayerTreeHostImpl::Create(
574 settings
, nullptr, &proxy
, &stats_instrumentation
, &shared_bitmap_manager
,
575 nullptr, &task_graph_runner
, 0);
577 scoped_refptr
<Layer
> layer_tree_root
= Layer::Create(layer_settings_
);
578 host_
->SetRootLayer(layer_tree_root
);
580 layer_tree_root
->SetLayerAnimationControllerForTest(
581 FakeLayerAnimationController::Create());
583 EXPECT_FALSE(static_cast<FakeLayerAnimationController
*>(
584 layer_tree_root
->layer_animation_controller())->SynchronizedAnimations());
586 scoped_ptr
<LayerImpl
> layer_impl_tree_root
=
587 TreeSynchronizer::SynchronizeTrees(
588 layer_tree_root
.get(), nullptr, host_
->active_tree());
589 TreeSynchronizer::PushProperties(layer_tree_root
.get(),
590 layer_impl_tree_root
.get());
591 layer_impl_tree_root
=
592 TreeSynchronizer::SynchronizeTrees(layer_tree_root
.get(),
593 layer_impl_tree_root
.Pass(),
594 host_
->active_tree());
596 EXPECT_TRUE(static_cast<FakeLayerAnimationController
*>(
597 layer_tree_root
->layer_animation_controller())->SynchronizedAnimations());
600 TEST_F(TreeSynchronizerTest
, SynchronizeScrollParent
) {
601 LayerTreeSettings settings
;
603 DebugScopedSetImplThread
impl(&proxy
);
604 FakeRenderingStatsInstrumentation stats_instrumentation
;
605 TestSharedBitmapManager shared_bitmap_manager
;
606 TestTaskGraphRunner task_graph_runner
;
607 scoped_ptr
<LayerTreeHostImpl
> host_impl
= LayerTreeHostImpl::Create(
608 settings
, nullptr, &proxy
, &stats_instrumentation
, &shared_bitmap_manager
,
609 nullptr, &task_graph_runner
, 0);
611 scoped_refptr
<Layer
> layer_tree_root
= Layer::Create(layer_settings_
);
612 scoped_refptr
<Layer
> scroll_parent
= Layer::Create(layer_settings_
);
613 layer_tree_root
->AddChild(scroll_parent
);
614 layer_tree_root
->AddChild(Layer::Create(layer_settings_
));
615 layer_tree_root
->AddChild(Layer::Create(layer_settings_
));
617 host_
->SetRootLayer(layer_tree_root
);
619 // First child is the second and third child's scroll parent.
620 layer_tree_root
->children()[1]->SetScrollParent(scroll_parent
.get());
621 layer_tree_root
->children()[2]->SetScrollParent(scroll_parent
.get());
623 scoped_ptr
<LayerImpl
> layer_impl_tree_root
=
624 TreeSynchronizer::SynchronizeTrees(
625 layer_tree_root
.get(), nullptr, host_impl
->active_tree());
626 TreeSynchronizer::PushProperties(layer_tree_root
.get(),
627 layer_impl_tree_root
.get());
629 SCOPED_TRACE("case one");
630 ExpectTreesAreIdentical(layer_tree_root
.get(),
631 layer_impl_tree_root
.get(),
632 host_impl
->active_tree());
635 // Remove the first scroll child.
636 layer_tree_root
->children()[1]->RemoveFromParent();
637 layer_impl_tree_root
=
638 TreeSynchronizer::SynchronizeTrees(layer_tree_root
.get(),
639 layer_impl_tree_root
.Pass(),
640 host_impl
->active_tree());
641 TreeSynchronizer::PushProperties(layer_tree_root
.get(),
642 layer_impl_tree_root
.get());
644 SCOPED_TRACE("case two");
645 ExpectTreesAreIdentical(layer_tree_root
.get(),
646 layer_impl_tree_root
.get(),
647 host_impl
->active_tree());
650 // Add an additional scroll layer.
651 scoped_refptr
<Layer
> additional_scroll_child
= Layer::Create(layer_settings_
);
652 layer_tree_root
->AddChild(additional_scroll_child
);
653 additional_scroll_child
->SetScrollParent(scroll_parent
.get());
654 layer_impl_tree_root
=
655 TreeSynchronizer::SynchronizeTrees(layer_tree_root
.get(),
656 layer_impl_tree_root
.Pass(),
657 host_impl
->active_tree());
658 TreeSynchronizer::PushProperties(layer_tree_root
.get(),
659 layer_impl_tree_root
.get());
661 SCOPED_TRACE("case three");
662 ExpectTreesAreIdentical(layer_tree_root
.get(),
663 layer_impl_tree_root
.get(),
664 host_impl
->active_tree());
668 TEST_F(TreeSynchronizerTest
, SynchronizeClipParent
) {
669 LayerTreeSettings settings
;
671 DebugScopedSetImplThread
impl(&proxy
);
672 FakeRenderingStatsInstrumentation stats_instrumentation
;
673 TestSharedBitmapManager shared_bitmap_manager
;
674 TestTaskGraphRunner task_graph_runner
;
675 scoped_ptr
<LayerTreeHostImpl
> host_impl
= LayerTreeHostImpl::Create(
676 settings
, nullptr, &proxy
, &stats_instrumentation
, &shared_bitmap_manager
,
677 nullptr, &task_graph_runner
, 0);
679 scoped_refptr
<Layer
> layer_tree_root
= Layer::Create(layer_settings_
);
680 scoped_refptr
<Layer
> clip_parent
= Layer::Create(layer_settings_
);
681 scoped_refptr
<Layer
> intervening
= Layer::Create(layer_settings_
);
682 scoped_refptr
<Layer
> clip_child1
= Layer::Create(layer_settings_
);
683 scoped_refptr
<Layer
> clip_child2
= Layer::Create(layer_settings_
);
684 layer_tree_root
->AddChild(clip_parent
);
685 clip_parent
->AddChild(intervening
);
686 intervening
->AddChild(clip_child1
);
687 intervening
->AddChild(clip_child2
);
689 host_
->SetRootLayer(layer_tree_root
);
691 // First child is the second and third child's scroll parent.
692 clip_child1
->SetClipParent(clip_parent
.get());
693 clip_child2
->SetClipParent(clip_parent
.get());
695 scoped_ptr
<LayerImpl
> layer_impl_tree_root
=
696 TreeSynchronizer::SynchronizeTrees(
697 layer_tree_root
.get(), nullptr, host_impl
->active_tree());
698 TreeSynchronizer::PushProperties(layer_tree_root
.get(),
699 layer_impl_tree_root
.get());
700 ExpectTreesAreIdentical(layer_tree_root
.get(),
701 layer_impl_tree_root
.get(),
702 host_impl
->active_tree());
704 // Remove the first clip child.
705 clip_child1
->RemoveFromParent();
708 layer_impl_tree_root
=
709 TreeSynchronizer::SynchronizeTrees(layer_tree_root
.get(),
710 layer_impl_tree_root
.Pass(),
711 host_impl
->active_tree());
712 TreeSynchronizer::PushProperties(layer_tree_root
.get(),
713 layer_impl_tree_root
.get());
714 ExpectTreesAreIdentical(layer_tree_root
.get(),
715 layer_impl_tree_root
.get(),
716 host_impl
->active_tree());
718 // Add an additional clip child.
719 scoped_refptr
<Layer
> additional_clip_child
= Layer::Create(layer_settings_
);
720 intervening
->AddChild(additional_clip_child
);
721 additional_clip_child
->SetClipParent(clip_parent
.get());
722 layer_impl_tree_root
=
723 TreeSynchronizer::SynchronizeTrees(layer_tree_root
.get(),
724 layer_impl_tree_root
.Pass(),
725 host_impl
->active_tree());
726 TreeSynchronizer::PushProperties(layer_tree_root
.get(),
727 layer_impl_tree_root
.get());
728 ExpectTreesAreIdentical(layer_tree_root
.get(),
729 layer_impl_tree_root
.get(),
730 host_impl
->active_tree());
732 // Remove the nearest clipping ancestor.
733 clip_parent
->RemoveFromParent();
735 layer_impl_tree_root
=
736 TreeSynchronizer::SynchronizeTrees(layer_tree_root
.get(),
737 layer_impl_tree_root
.Pass(),
738 host_impl
->active_tree());
739 TreeSynchronizer::PushProperties(layer_tree_root
.get(),
740 layer_impl_tree_root
.get());
741 ExpectTreesAreIdentical(layer_tree_root
.get(),
742 layer_impl_tree_root
.get(),
743 host_impl
->active_tree());
745 // The clip children should have been unhooked.
746 EXPECT_EQ(2u, intervening
->children().size());
747 EXPECT_FALSE(clip_child2
->clip_parent());
748 EXPECT_FALSE(additional_clip_child
->clip_parent());