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/test_shared_bitmap_manager.h"
20 #include "cc/trees/proxy.h"
21 #include "cc/trees/single_thread_proxy.h"
22 #include "testing/gtest/include/gtest/gtest.h"
27 class MockLayerImpl
: public LayerImpl
{
29 static scoped_ptr
<MockLayerImpl
> Create(LayerTreeImpl
* tree_impl
,
31 return make_scoped_ptr(new MockLayerImpl(tree_impl
, layer_id
));
33 ~MockLayerImpl() override
{
34 if (layer_impl_destruction_list_
)
35 layer_impl_destruction_list_
->push_back(id());
38 void SetLayerImplDestructionList(std::vector
<int>* list
) {
39 layer_impl_destruction_list_
= list
;
43 MockLayerImpl(LayerTreeImpl
* tree_impl
, int layer_id
)
44 : LayerImpl(tree_impl
, layer_id
),
45 layer_impl_destruction_list_(NULL
) {}
47 std::vector
<int>* layer_impl_destruction_list_
;
50 class MockLayer
: public Layer
{
52 static scoped_refptr
<MockLayer
> Create(
53 std::vector
<int>* layer_impl_destruction_list
) {
54 return make_scoped_refptr(new MockLayer(layer_impl_destruction_list
));
57 scoped_ptr
<LayerImpl
> CreateLayerImpl(LayerTreeImpl
* tree_impl
) override
{
58 return MockLayerImpl::Create(tree_impl
, layer_id_
);
61 void PushPropertiesTo(LayerImpl
* layer_impl
) override
{
62 Layer::PushPropertiesTo(layer_impl
);
64 MockLayerImpl
* mock_layer_impl
= static_cast<MockLayerImpl
*>(layer_impl
);
65 mock_layer_impl
->SetLayerImplDestructionList(layer_impl_destruction_list_
);
69 explicit MockLayer(std::vector
<int>* layer_impl_destruction_list
)
70 : Layer(), layer_impl_destruction_list_(layer_impl_destruction_list
) {}
71 ~MockLayer() override
{}
73 std::vector
<int>* layer_impl_destruction_list_
;
76 class FakeLayerAnimationController
: public LayerAnimationController
{
78 static scoped_refptr
<LayerAnimationController
> Create() {
79 return static_cast<LayerAnimationController
*>(
80 new FakeLayerAnimationController
);
83 bool SynchronizedAnimations() const { return synchronized_animations_
; }
86 FakeLayerAnimationController()
87 : LayerAnimationController(1),
88 synchronized_animations_(false) {}
90 ~FakeLayerAnimationController() override
{}
92 void PushAnimationUpdatesTo(
93 LayerAnimationController
* controller_impl
) override
{
94 LayerAnimationController::PushAnimationUpdatesTo(controller_impl
);
95 synchronized_animations_
= true;
98 bool synchronized_animations_
;
101 void ExpectTreesAreIdentical(Layer
* layer
,
102 LayerImpl
* layer_impl
,
103 LayerTreeImpl
* tree_impl
) {
105 ASSERT_TRUE(layer_impl
);
107 EXPECT_EQ(layer
->id(), layer_impl
->id());
108 EXPECT_EQ(layer_impl
->layer_tree_impl(), tree_impl
);
110 EXPECT_EQ(layer
->non_fast_scrollable_region(),
111 layer_impl
->non_fast_scrollable_region());
113 ASSERT_EQ(!!layer
->mask_layer(), !!layer_impl
->mask_layer());
114 if (layer
->mask_layer()) {
115 SCOPED_TRACE("mask_layer");
116 ExpectTreesAreIdentical(
117 layer
->mask_layer(), layer_impl
->mask_layer(), tree_impl
);
120 ASSERT_EQ(!!layer
->replica_layer(), !!layer_impl
->replica_layer());
121 if (layer
->replica_layer()) {
122 SCOPED_TRACE("replica_layer");
123 ExpectTreesAreIdentical(
124 layer
->replica_layer(), layer_impl
->replica_layer(), tree_impl
);
127 const LayerList
& layer_children
= layer
->children();
128 const OwnedLayerImplList
& layer_impl_children
= layer_impl
->children();
130 ASSERT_EQ(layer_children
.size(), layer_impl_children
.size());
132 const std::set
<Layer
*>* layer_scroll_children
= layer
->scroll_children();
133 const std::set
<LayerImpl
*>* layer_impl_scroll_children
=
134 layer_impl
->scroll_children();
136 ASSERT_EQ(!!layer_scroll_children
, !!layer_impl_scroll_children
);
138 if (layer_scroll_children
) {
140 layer_scroll_children
->size(),
141 layer_impl_scroll_children
->size());
144 const Layer
* layer_scroll_parent
= layer
->scroll_parent();
145 const LayerImpl
* layer_impl_scroll_parent
= layer_impl
->scroll_parent();
147 ASSERT_EQ(!!layer_scroll_parent
, !!layer_impl_scroll_parent
);
149 if (layer_scroll_parent
) {
150 ASSERT_EQ(layer_scroll_parent
->id(), layer_impl_scroll_parent
->id());
151 ASSERT_TRUE(layer_scroll_parent
->scroll_children()->find(layer
) !=
152 layer_scroll_parent
->scroll_children()->end());
153 ASSERT_TRUE(layer_impl_scroll_parent
->scroll_children()->find(layer_impl
) !=
154 layer_impl_scroll_parent
->scroll_children()->end());
157 const std::set
<Layer
*>* layer_clip_children
= layer
->clip_children();
158 const std::set
<LayerImpl
*>* layer_impl_clip_children
=
159 layer_impl
->clip_children();
161 ASSERT_EQ(!!layer_clip_children
, !!layer_impl_clip_children
);
163 if (layer_clip_children
)
164 ASSERT_EQ(layer_clip_children
->size(), layer_impl_clip_children
->size());
166 const Layer
* layer_clip_parent
= layer
->clip_parent();
167 const LayerImpl
* layer_impl_clip_parent
= layer_impl
->clip_parent();
169 ASSERT_EQ(!!layer_clip_parent
, !!layer_impl_clip_parent
);
171 if (layer_clip_parent
) {
172 const std::set
<LayerImpl
*>* clip_children_impl
=
173 layer_impl_clip_parent
->clip_children();
174 const std::set
<Layer
*>* clip_children
=
175 layer_clip_parent
->clip_children();
176 ASSERT_EQ(layer_clip_parent
->id(), layer_impl_clip_parent
->id());
177 ASSERT_TRUE(clip_children
->find(layer
) != clip_children
->end());
178 ASSERT_TRUE(clip_children_impl
->find(layer_impl
) !=
179 clip_children_impl
->end());
182 for (size_t i
= 0; i
< layer_children
.size(); ++i
) {
183 SCOPED_TRACE(base::StringPrintf("child layer %" PRIuS
, i
).c_str());
184 ExpectTreesAreIdentical(
185 layer_children
[i
].get(), layer_impl_children
[i
], tree_impl
);
189 class TreeSynchronizerTest
: public testing::Test
{
191 TreeSynchronizerTest()
192 : client_(FakeLayerTreeHostClient::DIRECT_3D
),
193 host_(FakeLayerTreeHost::Create(&client_
)) {}
196 FakeLayerTreeHostClient client_
;
197 scoped_ptr
<FakeLayerTreeHost
> host_
;
200 // Attempts to synchronizes a null tree. This should not crash, and should
201 // return a null tree.
202 TEST_F(TreeSynchronizerTest
, SyncNullTree
) {
203 scoped_ptr
<LayerImpl
> layer_impl_tree_root
=
204 TreeSynchronizer::SynchronizeTrees(
205 static_cast<Layer
*>(NULL
), nullptr, host_
->active_tree());
207 EXPECT_TRUE(!layer_impl_tree_root
.get());
210 // Constructs a very simple tree and synchronizes it without trying to reuse any
211 // preexisting layers.
212 TEST_F(TreeSynchronizerTest
, SyncSimpleTreeFromEmpty
) {
213 scoped_refptr
<Layer
> layer_tree_root
= Layer::Create();
214 layer_tree_root
->AddChild(Layer::Create());
215 layer_tree_root
->AddChild(Layer::Create());
217 host_
->SetRootLayer(layer_tree_root
);
219 scoped_ptr
<LayerImpl
> layer_impl_tree_root
=
220 TreeSynchronizer::SynchronizeTrees(
221 layer_tree_root
.get(), nullptr, host_
->active_tree());
223 ExpectTreesAreIdentical(layer_tree_root
.get(),
224 layer_impl_tree_root
.get(),
225 host_
->active_tree());
228 // Constructs a very simple tree and synchronizes it attempting to reuse some
230 TEST_F(TreeSynchronizerTest
, SyncSimpleTreeReusingLayers
) {
231 std::vector
<int> layer_impl_destruction_list
;
233 scoped_refptr
<Layer
> layer_tree_root
=
234 MockLayer::Create(&layer_impl_destruction_list
);
235 layer_tree_root
->AddChild(MockLayer::Create(&layer_impl_destruction_list
));
236 layer_tree_root
->AddChild(MockLayer::Create(&layer_impl_destruction_list
));
238 host_
->SetRootLayer(layer_tree_root
);
240 scoped_ptr
<LayerImpl
> layer_impl_tree_root
=
241 TreeSynchronizer::SynchronizeTrees(
242 layer_tree_root
.get(), nullptr, host_
->active_tree());
243 ExpectTreesAreIdentical(layer_tree_root
.get(),
244 layer_impl_tree_root
.get(),
245 host_
->active_tree());
247 // We have to push properties to pick up the destruction list pointer.
248 TreeSynchronizer::PushProperties(layer_tree_root
.get(),
249 layer_impl_tree_root
.get());
251 // Add a new layer to the Layer side
252 layer_tree_root
->children()[0]->
253 AddChild(MockLayer::Create(&layer_impl_destruction_list
));
255 layer_tree_root
->children()[1]->RemoveFromParent();
256 int second_layer_impl_id
= layer_impl_tree_root
->children()[1]->id();
258 // Synchronize again. After the sync the trees should be equivalent and we
259 // should have created and destroyed one LayerImpl.
260 layer_impl_tree_root
=
261 TreeSynchronizer::SynchronizeTrees(layer_tree_root
.get(),
262 layer_impl_tree_root
.Pass(),
263 host_
->active_tree());
264 ExpectTreesAreIdentical(layer_tree_root
.get(),
265 layer_impl_tree_root
.get(),
266 host_
->active_tree());
268 ASSERT_EQ(1u, layer_impl_destruction_list
.size());
269 EXPECT_EQ(second_layer_impl_id
, layer_impl_destruction_list
[0]);
272 // Constructs a very simple tree and checks that a stacking-order change is
274 TEST_F(TreeSynchronizerTest
, SyncSimpleTreeAndTrackStackingOrderChange
) {
275 std::vector
<int> layer_impl_destruction_list
;
277 // Set up the tree and sync once. child2 needs to be synced here, too, even
278 // though we remove it to set up the intended scenario.
279 scoped_refptr
<Layer
> layer_tree_root
=
280 MockLayer::Create(&layer_impl_destruction_list
);
281 scoped_refptr
<Layer
> child2
= MockLayer::Create(&layer_impl_destruction_list
);
282 layer_tree_root
->AddChild(MockLayer::Create(&layer_impl_destruction_list
));
283 layer_tree_root
->AddChild(child2
);
285 host_
->SetRootLayer(layer_tree_root
);
287 scoped_ptr
<LayerImpl
> layer_impl_tree_root
=
288 TreeSynchronizer::SynchronizeTrees(
289 layer_tree_root
.get(), nullptr, host_
->active_tree());
290 ExpectTreesAreIdentical(layer_tree_root
.get(),
291 layer_impl_tree_root
.get(),
292 host_
->active_tree());
294 // We have to push properties to pick up the destruction list pointer.
295 TreeSynchronizer::PushProperties(layer_tree_root
.get(),
296 layer_impl_tree_root
.get());
298 layer_impl_tree_root
->ResetAllChangeTrackingForSubtree();
300 // re-insert the layer and sync again.
301 child2
->RemoveFromParent();
302 layer_tree_root
->AddChild(child2
);
303 layer_impl_tree_root
=
304 TreeSynchronizer::SynchronizeTrees(layer_tree_root
.get(),
305 layer_impl_tree_root
.Pass(),
306 host_
->active_tree());
307 ExpectTreesAreIdentical(layer_tree_root
.get(),
308 layer_impl_tree_root
.get(),
309 host_
->active_tree());
311 TreeSynchronizer::PushProperties(layer_tree_root
.get(),
312 layer_impl_tree_root
.get());
314 // Check that the impl thread properly tracked the change.
315 EXPECT_FALSE(layer_impl_tree_root
->LayerPropertyChanged());
316 EXPECT_FALSE(layer_impl_tree_root
->children()[0]->LayerPropertyChanged());
317 EXPECT_TRUE(layer_impl_tree_root
->children()[1]->LayerPropertyChanged());
320 TEST_F(TreeSynchronizerTest
, SyncSimpleTreeAndProperties
) {
321 scoped_refptr
<Layer
> layer_tree_root
= Layer::Create();
322 layer_tree_root
->AddChild(Layer::Create());
323 layer_tree_root
->AddChild(Layer::Create());
325 host_
->SetRootLayer(layer_tree_root
);
327 // Pick some random properties to set. The values are not important, we're
328 // just testing that at least some properties are making it through.
329 gfx::PointF root_position
= gfx::PointF(2.3f
, 7.4f
);
330 layer_tree_root
->SetPosition(root_position
);
332 float first_child_opacity
= 0.25f
;
333 layer_tree_root
->children()[0]->SetOpacity(first_child_opacity
);
335 gfx::Size second_child_bounds
= gfx::Size(25, 53);
336 layer_tree_root
->children()[1]->SetBounds(second_child_bounds
);
337 layer_tree_root
->children()[1]->SavePaintProperties();
339 scoped_ptr
<LayerImpl
> layer_impl_tree_root
=
340 TreeSynchronizer::SynchronizeTrees(
341 layer_tree_root
.get(), nullptr, host_
->active_tree());
342 ExpectTreesAreIdentical(layer_tree_root
.get(),
343 layer_impl_tree_root
.get(),
344 host_
->active_tree());
346 TreeSynchronizer::PushProperties(layer_tree_root
.get(),
347 layer_impl_tree_root
.get());
349 // Check that the property values we set on the Layer tree are reflected in
350 // the LayerImpl tree.
351 gfx::PointF root_layer_impl_position
= layer_impl_tree_root
->position();
352 EXPECT_EQ(root_position
.x(), root_layer_impl_position
.x());
353 EXPECT_EQ(root_position
.y(), root_layer_impl_position
.y());
355 EXPECT_EQ(first_child_opacity
,
356 layer_impl_tree_root
->children()[0]->opacity());
358 gfx::Size second_layer_impl_child_bounds
=
359 layer_impl_tree_root
->children()[1]->bounds();
360 EXPECT_EQ(second_child_bounds
.width(),
361 second_layer_impl_child_bounds
.width());
362 EXPECT_EQ(second_child_bounds
.height(),
363 second_layer_impl_child_bounds
.height());
366 TEST_F(TreeSynchronizerTest
, ReuseLayerImplsAfterStructuralChange
) {
367 std::vector
<int> layer_impl_destruction_list
;
369 // Set up a tree with this sort of structure:
370 // root --- A --- B ---+--- C
373 scoped_refptr
<Layer
> layer_tree_root
=
374 MockLayer::Create(&layer_impl_destruction_list
);
375 layer_tree_root
->AddChild(MockLayer::Create(&layer_impl_destruction_list
));
377 scoped_refptr
<Layer
> layer_a
= layer_tree_root
->children()[0].get();
378 layer_a
->AddChild(MockLayer::Create(&layer_impl_destruction_list
));
380 scoped_refptr
<Layer
> layer_b
= layer_a
->children()[0].get();
381 layer_b
->AddChild(MockLayer::Create(&layer_impl_destruction_list
));
383 scoped_refptr
<Layer
> layer_c
= layer_b
->children()[0].get();
384 layer_b
->AddChild(MockLayer::Create(&layer_impl_destruction_list
));
385 scoped_refptr
<Layer
> layer_d
= layer_b
->children()[1].get();
387 host_
->SetRootLayer(layer_tree_root
);
389 scoped_ptr
<LayerImpl
> layer_impl_tree_root
=
390 TreeSynchronizer::SynchronizeTrees(
391 layer_tree_root
.get(), nullptr, host_
->active_tree());
392 ExpectTreesAreIdentical(layer_tree_root
.get(),
393 layer_impl_tree_root
.get(),
394 host_
->active_tree());
396 // We have to push properties to pick up the destruction list pointer.
397 TreeSynchronizer::PushProperties(layer_tree_root
.get(),
398 layer_impl_tree_root
.get());
400 // Now restructure the tree to look like this:
401 // root --- D ---+--- A
404 layer_tree_root
->RemoveAllChildren();
405 layer_d
->RemoveAllChildren();
406 layer_tree_root
->AddChild(layer_d
);
407 layer_a
->RemoveAllChildren();
408 layer_d
->AddChild(layer_a
);
409 layer_c
->RemoveAllChildren();
410 layer_d
->AddChild(layer_c
);
411 layer_b
->RemoveAllChildren();
412 layer_c
->AddChild(layer_b
);
414 // After another synchronize our trees should match and we should not have
415 // destroyed any LayerImpls
416 layer_impl_tree_root
=
417 TreeSynchronizer::SynchronizeTrees(layer_tree_root
.get(),
418 layer_impl_tree_root
.Pass(),
419 host_
->active_tree());
420 ExpectTreesAreIdentical(layer_tree_root
.get(),
421 layer_impl_tree_root
.get(),
422 host_
->active_tree());
424 EXPECT_EQ(0u, layer_impl_destruction_list
.size());
427 // Constructs a very simple tree, synchronizes it, then synchronizes to a
428 // totally new tree. All layers from the old tree should be deleted.
429 TEST_F(TreeSynchronizerTest
, SyncSimpleTreeThenDestroy
) {
430 std::vector
<int> layer_impl_destruction_list
;
432 scoped_refptr
<Layer
> old_layer_tree_root
=
433 MockLayer::Create(&layer_impl_destruction_list
);
434 old_layer_tree_root
->AddChild(
435 MockLayer::Create(&layer_impl_destruction_list
));
436 old_layer_tree_root
->AddChild(
437 MockLayer::Create(&layer_impl_destruction_list
));
439 host_
->SetRootLayer(old_layer_tree_root
);
441 int old_tree_root_layer_id
= old_layer_tree_root
->id();
442 int old_tree_first_child_layer_id
= old_layer_tree_root
->children()[0]->id();
443 int old_tree_second_child_layer_id
= old_layer_tree_root
->children()[1]->id();
445 scoped_ptr
<LayerImpl
> layer_impl_tree_root
=
446 TreeSynchronizer::SynchronizeTrees(
447 old_layer_tree_root
.get(), nullptr, host_
->active_tree());
448 ExpectTreesAreIdentical(old_layer_tree_root
.get(),
449 layer_impl_tree_root
.get(),
450 host_
->active_tree());
452 // We have to push properties to pick up the destruction list pointer.
453 TreeSynchronizer::PushProperties(old_layer_tree_root
.get(),
454 layer_impl_tree_root
.get());
456 // Remove all children on the Layer side.
457 old_layer_tree_root
->RemoveAllChildren();
459 // Synchronize again. After the sync all LayerImpls from the old tree should
461 scoped_refptr
<Layer
> new_layer_tree_root
= Layer::Create();
462 host_
->SetRootLayer(new_layer_tree_root
);
463 layer_impl_tree_root
=
464 TreeSynchronizer::SynchronizeTrees(new_layer_tree_root
.get(),
465 layer_impl_tree_root
.Pass(),
466 host_
->active_tree());
467 ExpectTreesAreIdentical(new_layer_tree_root
.get(),
468 layer_impl_tree_root
.get(),
469 host_
->active_tree());
471 ASSERT_EQ(3u, layer_impl_destruction_list
.size());
473 EXPECT_TRUE(std::find(layer_impl_destruction_list
.begin(),
474 layer_impl_destruction_list
.end(),
475 old_tree_root_layer_id
) !=
476 layer_impl_destruction_list
.end());
477 EXPECT_TRUE(std::find(layer_impl_destruction_list
.begin(),
478 layer_impl_destruction_list
.end(),
479 old_tree_first_child_layer_id
) !=
480 layer_impl_destruction_list
.end());
481 EXPECT_TRUE(std::find(layer_impl_destruction_list
.begin(),
482 layer_impl_destruction_list
.end(),
483 old_tree_second_child_layer_id
) !=
484 layer_impl_destruction_list
.end());
487 // Constructs+syncs a tree with mask, replica, and replica mask layers.
488 TEST_F(TreeSynchronizerTest
, SyncMaskReplicaAndReplicaMaskLayers
) {
489 scoped_refptr
<Layer
> layer_tree_root
= Layer::Create();
490 layer_tree_root
->AddChild(Layer::Create());
491 layer_tree_root
->AddChild(Layer::Create());
492 layer_tree_root
->AddChild(Layer::Create());
494 // First child gets a mask layer.
495 scoped_refptr
<Layer
> mask_layer
= Layer::Create();
496 layer_tree_root
->children()[0]->SetMaskLayer(mask_layer
.get());
498 // Second child gets a replica layer.
499 scoped_refptr
<Layer
> replica_layer
= Layer::Create();
500 layer_tree_root
->children()[1]->SetReplicaLayer(replica_layer
.get());
502 // Third child gets a replica layer with a mask layer.
503 scoped_refptr
<Layer
> replica_layer_with_mask
= Layer::Create();
504 scoped_refptr
<Layer
> replica_mask_layer
= Layer::Create();
505 replica_layer_with_mask
->SetMaskLayer(replica_mask_layer
.get());
506 layer_tree_root
->children()[2]->
507 SetReplicaLayer(replica_layer_with_mask
.get());
509 host_
->SetRootLayer(layer_tree_root
);
511 scoped_ptr
<LayerImpl
> layer_impl_tree_root
=
512 TreeSynchronizer::SynchronizeTrees(
513 layer_tree_root
.get(), nullptr, host_
->active_tree());
515 ExpectTreesAreIdentical(layer_tree_root
.get(),
516 layer_impl_tree_root
.get(),
517 host_
->active_tree());
519 // Remove the mask layer.
520 layer_tree_root
->children()[0]->SetMaskLayer(NULL
);
521 layer_impl_tree_root
=
522 TreeSynchronizer::SynchronizeTrees(layer_tree_root
.get(),
523 layer_impl_tree_root
.Pass(),
524 host_
->active_tree());
525 ExpectTreesAreIdentical(layer_tree_root
.get(),
526 layer_impl_tree_root
.get(),
527 host_
->active_tree());
529 // Remove the replica layer.
530 layer_tree_root
->children()[1]->SetReplicaLayer(NULL
);
531 layer_impl_tree_root
=
532 TreeSynchronizer::SynchronizeTrees(layer_tree_root
.get(),
533 layer_impl_tree_root
.Pass(),
534 host_
->active_tree());
535 ExpectTreesAreIdentical(layer_tree_root
.get(),
536 layer_impl_tree_root
.get(),
537 host_
->active_tree());
539 // Remove the replica mask.
540 replica_layer_with_mask
->SetMaskLayer(NULL
);
541 layer_impl_tree_root
=
542 TreeSynchronizer::SynchronizeTrees(layer_tree_root
.get(),
543 layer_impl_tree_root
.Pass(),
544 host_
->active_tree());
545 ExpectTreesAreIdentical(layer_tree_root
.get(),
546 layer_impl_tree_root
.get(),
547 host_
->active_tree());
550 TEST_F(TreeSynchronizerTest
, SynchronizeAnimations
) {
551 LayerTreeSettings settings
;
553 DebugScopedSetImplThread
impl(&proxy
);
554 FakeRenderingStatsInstrumentation stats_instrumentation
;
555 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
556 new TestSharedBitmapManager());
557 scoped_ptr
<LayerTreeHostImpl
> host_impl
=
558 LayerTreeHostImpl::Create(settings
,
561 &stats_instrumentation
,
562 shared_bitmap_manager
.get(),
566 scoped_refptr
<Layer
> layer_tree_root
= Layer::Create();
567 host_
->SetRootLayer(layer_tree_root
);
569 layer_tree_root
->SetLayerAnimationControllerForTest(
570 FakeLayerAnimationController::Create());
572 EXPECT_FALSE(static_cast<FakeLayerAnimationController
*>(
573 layer_tree_root
->layer_animation_controller())->SynchronizedAnimations());
575 scoped_ptr
<LayerImpl
> layer_impl_tree_root
=
576 TreeSynchronizer::SynchronizeTrees(
577 layer_tree_root
.get(), nullptr, host_
->active_tree());
578 TreeSynchronizer::PushProperties(layer_tree_root
.get(),
579 layer_impl_tree_root
.get());
580 layer_impl_tree_root
=
581 TreeSynchronizer::SynchronizeTrees(layer_tree_root
.get(),
582 layer_impl_tree_root
.Pass(),
583 host_
->active_tree());
585 EXPECT_TRUE(static_cast<FakeLayerAnimationController
*>(
586 layer_tree_root
->layer_animation_controller())->SynchronizedAnimations());
589 TEST_F(TreeSynchronizerTest
, SynchronizeScrollParent
) {
590 LayerTreeSettings settings
;
592 DebugScopedSetImplThread
impl(&proxy
);
593 FakeRenderingStatsInstrumentation stats_instrumentation
;
594 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
595 new TestSharedBitmapManager());
596 scoped_ptr
<LayerTreeHostImpl
> host_impl
=
597 LayerTreeHostImpl::Create(settings
,
600 &stats_instrumentation
,
601 shared_bitmap_manager
.get(),
605 scoped_refptr
<Layer
> layer_tree_root
= Layer::Create();
606 scoped_refptr
<Layer
> scroll_parent
= Layer::Create();
607 layer_tree_root
->AddChild(scroll_parent
);
608 layer_tree_root
->AddChild(Layer::Create());
609 layer_tree_root
->AddChild(Layer::Create());
611 host_
->SetRootLayer(layer_tree_root
);
613 // First child is the second and third child's scroll parent.
614 layer_tree_root
->children()[1]->SetScrollParent(scroll_parent
.get());
615 layer_tree_root
->children()[2]->SetScrollParent(scroll_parent
.get());
617 scoped_ptr
<LayerImpl
> layer_impl_tree_root
=
618 TreeSynchronizer::SynchronizeTrees(
619 layer_tree_root
.get(), nullptr, host_impl
->active_tree());
620 TreeSynchronizer::PushProperties(layer_tree_root
.get(),
621 layer_impl_tree_root
.get());
623 SCOPED_TRACE("case one");
624 ExpectTreesAreIdentical(layer_tree_root
.get(),
625 layer_impl_tree_root
.get(),
626 host_impl
->active_tree());
629 // Remove the first scroll child.
630 layer_tree_root
->children()[1]->RemoveFromParent();
631 layer_impl_tree_root
=
632 TreeSynchronizer::SynchronizeTrees(layer_tree_root
.get(),
633 layer_impl_tree_root
.Pass(),
634 host_impl
->active_tree());
635 TreeSynchronizer::PushProperties(layer_tree_root
.get(),
636 layer_impl_tree_root
.get());
638 SCOPED_TRACE("case two");
639 ExpectTreesAreIdentical(layer_tree_root
.get(),
640 layer_impl_tree_root
.get(),
641 host_impl
->active_tree());
644 // Add an additional scroll layer.
645 scoped_refptr
<Layer
> additional_scroll_child
= Layer::Create();
646 layer_tree_root
->AddChild(additional_scroll_child
);
647 additional_scroll_child
->SetScrollParent(scroll_parent
.get());
648 layer_impl_tree_root
=
649 TreeSynchronizer::SynchronizeTrees(layer_tree_root
.get(),
650 layer_impl_tree_root
.Pass(),
651 host_impl
->active_tree());
652 TreeSynchronizer::PushProperties(layer_tree_root
.get(),
653 layer_impl_tree_root
.get());
655 SCOPED_TRACE("case three");
656 ExpectTreesAreIdentical(layer_tree_root
.get(),
657 layer_impl_tree_root
.get(),
658 host_impl
->active_tree());
662 TEST_F(TreeSynchronizerTest
, SynchronizeClipParent
) {
663 LayerTreeSettings settings
;
665 DebugScopedSetImplThread
impl(&proxy
);
666 FakeRenderingStatsInstrumentation stats_instrumentation
;
667 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
668 new TestSharedBitmapManager());
669 scoped_ptr
<LayerTreeHostImpl
> host_impl
=
670 LayerTreeHostImpl::Create(settings
,
673 &stats_instrumentation
,
674 shared_bitmap_manager
.get(),
678 scoped_refptr
<Layer
> layer_tree_root
= Layer::Create();
679 scoped_refptr
<Layer
> clip_parent
= Layer::Create();
680 scoped_refptr
<Layer
> intervening
= Layer::Create();
681 scoped_refptr
<Layer
> clip_child1
= Layer::Create();
682 scoped_refptr
<Layer
> clip_child2
= Layer::Create();
683 layer_tree_root
->AddChild(clip_parent
);
684 clip_parent
->AddChild(intervening
);
685 intervening
->AddChild(clip_child1
);
686 intervening
->AddChild(clip_child2
);
688 host_
->SetRootLayer(layer_tree_root
);
690 // First child is the second and third child's scroll parent.
691 clip_child1
->SetClipParent(clip_parent
.get());
692 clip_child2
->SetClipParent(clip_parent
.get());
694 scoped_ptr
<LayerImpl
> layer_impl_tree_root
=
695 TreeSynchronizer::SynchronizeTrees(
696 layer_tree_root
.get(), nullptr, host_impl
->active_tree());
697 TreeSynchronizer::PushProperties(layer_tree_root
.get(),
698 layer_impl_tree_root
.get());
699 ExpectTreesAreIdentical(layer_tree_root
.get(),
700 layer_impl_tree_root
.get(),
701 host_impl
->active_tree());
703 // Remove the first clip child.
704 clip_child1
->RemoveFromParent();
707 layer_impl_tree_root
=
708 TreeSynchronizer::SynchronizeTrees(layer_tree_root
.get(),
709 layer_impl_tree_root
.Pass(),
710 host_impl
->active_tree());
711 TreeSynchronizer::PushProperties(layer_tree_root
.get(),
712 layer_impl_tree_root
.get());
713 ExpectTreesAreIdentical(layer_tree_root
.get(),
714 layer_impl_tree_root
.get(),
715 host_impl
->active_tree());
717 // Add an additional clip child.
718 scoped_refptr
<Layer
> additional_clip_child
= Layer::Create();
719 intervening
->AddChild(additional_clip_child
);
720 additional_clip_child
->SetClipParent(clip_parent
.get());
721 layer_impl_tree_root
=
722 TreeSynchronizer::SynchronizeTrees(layer_tree_root
.get(),
723 layer_impl_tree_root
.Pass(),
724 host_impl
->active_tree());
725 TreeSynchronizer::PushProperties(layer_tree_root
.get(),
726 layer_impl_tree_root
.get());
727 ExpectTreesAreIdentical(layer_tree_root
.get(),
728 layer_impl_tree_root
.get(),
729 host_impl
->active_tree());
731 // Remove the nearest clipping ancestor.
732 clip_parent
->RemoveFromParent();
734 layer_impl_tree_root
=
735 TreeSynchronizer::SynchronizeTrees(layer_tree_root
.get(),
736 layer_impl_tree_root
.Pass(),
737 host_impl
->active_tree());
738 TreeSynchronizer::PushProperties(layer_tree_root
.get(),
739 layer_impl_tree_root
.get());
740 ExpectTreesAreIdentical(layer_tree_root
.get(),
741 layer_impl_tree_root
.get(),
742 host_impl
->active_tree());
744 // The clip children should have been unhooked.
745 EXPECT_EQ(2u, intervening
->children().size());
746 EXPECT_FALSE(clip_child2
->clip_parent());
747 EXPECT_FALSE(additional_clip_child
->clip_parent());