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 "cc/animation/layer_animation_controller.h"
12 #include "cc/layers/layer.h"
13 #include "cc/layers/layer_impl.h"
14 #include "cc/test/animation_test_common.h"
15 #include "cc/test/fake_impl_proxy.h"
16 #include "cc/test/fake_layer_tree_host.h"
17 #include "cc/trees/proxy.h"
18 #include "cc/trees/single_thread_proxy.h"
19 #include "testing/gtest/include/gtest/gtest.h"
24 class MockLayerImpl
: public LayerImpl
{
26 static scoped_ptr
<MockLayerImpl
> Create(LayerTreeImpl
* tree_impl
,
28 return make_scoped_ptr(new MockLayerImpl(tree_impl
, layer_id
));
30 virtual ~MockLayerImpl() {
31 if (layer_impl_destruction_list_
)
32 layer_impl_destruction_list_
->push_back(id());
35 void SetLayerImplDestructionList(std::vector
<int>* list
) {
36 layer_impl_destruction_list_
= list
;
40 MockLayerImpl(LayerTreeImpl
* tree_impl
, int layer_id
)
41 : LayerImpl(tree_impl
, layer_id
),
42 layer_impl_destruction_list_(NULL
) {}
44 std::vector
<int>* layer_impl_destruction_list_
;
47 class MockLayer
: public Layer
{
49 static scoped_refptr
<MockLayer
> Create(
50 std::vector
<int>* layer_impl_destruction_list
) {
51 return make_scoped_refptr(new MockLayer(layer_impl_destruction_list
));
54 virtual scoped_ptr
<LayerImpl
> CreateLayerImpl(LayerTreeImpl
* tree_impl
)
56 return MockLayerImpl::Create(tree_impl
, layer_id_
).PassAs
<LayerImpl
>();
59 virtual void PushPropertiesTo(LayerImpl
* layer_impl
) OVERRIDE
{
60 Layer::PushPropertiesTo(layer_impl
);
62 MockLayerImpl
* mock_layer_impl
= static_cast<MockLayerImpl
*>(layer_impl
);
63 mock_layer_impl
->SetLayerImplDestructionList(layer_impl_destruction_list_
);
67 explicit MockLayer(std::vector
<int>* layer_impl_destruction_list
)
68 : Layer(), layer_impl_destruction_list_(layer_impl_destruction_list
) {}
69 virtual ~MockLayer() {}
71 std::vector
<int>* layer_impl_destruction_list_
;
74 class FakeLayerAnimationController
: public LayerAnimationController
{
76 static scoped_refptr
<LayerAnimationController
> Create() {
77 return static_cast<LayerAnimationController
*>(
78 new FakeLayerAnimationController
);
81 bool SynchronizedAnimations() const { return synchronized_animations_
; }
84 FakeLayerAnimationController()
85 : LayerAnimationController(1),
86 synchronized_animations_(false) {}
88 virtual ~FakeLayerAnimationController() {}
90 virtual void PushAnimationUpdatesTo(LayerAnimationController
* controller_impl
)
92 LayerAnimationController::PushAnimationUpdatesTo(controller_impl
);
93 synchronized_animations_
= true;
96 bool synchronized_animations_
;
99 void ExpectTreesAreIdentical(Layer
* layer
,
100 LayerImpl
* layer_impl
,
101 LayerTreeImpl
* tree_impl
) {
103 ASSERT_TRUE(layer_impl
);
105 EXPECT_EQ(layer
->id(), layer_impl
->id());
106 EXPECT_EQ(layer_impl
->layer_tree_impl(), tree_impl
);
108 EXPECT_EQ(layer
->non_fast_scrollable_region(),
109 layer_impl
->non_fast_scrollable_region());
111 ASSERT_EQ(!!layer
->mask_layer(), !!layer_impl
->mask_layer());
112 if (layer
->mask_layer()) {
113 ExpectTreesAreIdentical(
114 layer
->mask_layer(), layer_impl
->mask_layer(), tree_impl
);
117 ASSERT_EQ(!!layer
->replica_layer(), !!layer_impl
->replica_layer());
118 if (layer
->replica_layer()) {
119 ExpectTreesAreIdentical(
120 layer
->replica_layer(), layer_impl
->replica_layer(), tree_impl
);
123 const LayerList
& layer_children
= layer
->children();
124 const OwnedLayerImplList
& layer_impl_children
= layer_impl
->children();
126 ASSERT_EQ(layer_children
.size(), layer_impl_children
.size());
128 const std::set
<Layer
*>* layer_scroll_children
= layer
->scroll_children();
129 const std::set
<LayerImpl
*>* layer_impl_scroll_children
=
130 layer_impl
->scroll_children();
132 ASSERT_EQ(!!layer_scroll_children
, !!layer_impl_scroll_children
);
134 if (layer_scroll_children
) {
136 layer_scroll_children
->size(),
137 layer_impl_scroll_children
->size());
140 const Layer
* layer_scroll_parent
= layer
->scroll_parent();
141 const LayerImpl
* layer_impl_scroll_parent
= layer_impl
->scroll_parent();
143 ASSERT_EQ(!!layer_scroll_parent
, !!layer_impl_scroll_parent
);
145 if (layer_scroll_parent
) {
146 ASSERT_EQ(layer_scroll_parent
->id(), layer_impl_scroll_parent
->id());
147 ASSERT_TRUE(layer_scroll_parent
->scroll_children()->find(layer
) !=
148 layer_scroll_parent
->scroll_children()->end());
149 ASSERT_TRUE(layer_impl_scroll_parent
->scroll_children()->find(layer_impl
) !=
150 layer_impl_scroll_parent
->scroll_children()->end());
153 const std::set
<Layer
*>* layer_clip_children
= layer
->clip_children();
154 const std::set
<LayerImpl
*>* layer_impl_clip_children
=
155 layer_impl
->clip_children();
157 ASSERT_EQ(!!layer_clip_children
, !!layer_impl_clip_children
);
159 if (layer_clip_children
)
160 ASSERT_EQ(layer_clip_children
->size(), layer_impl_clip_children
->size());
162 const Layer
* layer_clip_parent
= layer
->clip_parent();
163 const LayerImpl
* layer_impl_clip_parent
= layer_impl
->clip_parent();
165 ASSERT_EQ(!!layer_clip_parent
, !!layer_impl_clip_parent
);
167 if (layer_clip_parent
) {
168 const std::set
<LayerImpl
*>* clip_children_impl
=
169 layer_impl_clip_parent
->clip_children();
170 const std::set
<Layer
*>* clip_children
=
171 layer_clip_parent
->clip_children();
172 ASSERT_EQ(layer_clip_parent
->id(), layer_impl_clip_parent
->id());
173 ASSERT_TRUE(clip_children
->find(layer
) != clip_children
->end());
174 ASSERT_TRUE(clip_children_impl
->find(layer_impl
) !=
175 clip_children_impl
->end());
178 for (size_t i
= 0; i
< layer_children
.size(); ++i
) {
179 ExpectTreesAreIdentical(
180 layer_children
[i
].get(), layer_impl_children
[i
], tree_impl
);
184 class TreeSynchronizerTest
: public testing::Test
{
186 TreeSynchronizerTest() : host_(FakeLayerTreeHost::Create()) {}
189 scoped_ptr
<FakeLayerTreeHost
> host_
;
192 // Attempts to synchronizes a null tree. This should not crash, and should
193 // return a null tree.
194 TEST_F(TreeSynchronizerTest
, SyncNullTree
) {
195 scoped_ptr
<LayerImpl
> layer_impl_tree_root
=
196 TreeSynchronizer::SynchronizeTrees(static_cast<Layer
*>(NULL
),
197 scoped_ptr
<LayerImpl
>(),
198 host_
->active_tree());
200 EXPECT_TRUE(!layer_impl_tree_root
.get());
203 // Constructs a very simple tree and synchronizes it without trying to reuse any
204 // preexisting layers.
205 TEST_F(TreeSynchronizerTest
, SyncSimpleTreeFromEmpty
) {
206 scoped_refptr
<Layer
> layer_tree_root
= Layer::Create();
207 layer_tree_root
->AddChild(Layer::Create());
208 layer_tree_root
->AddChild(Layer::Create());
210 host_
->SetRootLayer(layer_tree_root
);
212 scoped_ptr
<LayerImpl
> layer_impl_tree_root
=
213 TreeSynchronizer::SynchronizeTrees(layer_tree_root
.get(),
214 scoped_ptr
<LayerImpl
>(),
215 host_
->active_tree());
217 ExpectTreesAreIdentical(layer_tree_root
.get(),
218 layer_impl_tree_root
.get(),
219 host_
->active_tree());
222 // Constructs a very simple tree and synchronizes it attempting to reuse some
224 TEST_F(TreeSynchronizerTest
, SyncSimpleTreeReusingLayers
) {
225 std::vector
<int> layer_impl_destruction_list
;
227 scoped_refptr
<Layer
> layer_tree_root
=
228 MockLayer::Create(&layer_impl_destruction_list
);
229 layer_tree_root
->AddChild(MockLayer::Create(&layer_impl_destruction_list
));
230 layer_tree_root
->AddChild(MockLayer::Create(&layer_impl_destruction_list
));
232 host_
->SetRootLayer(layer_tree_root
);
234 scoped_ptr
<LayerImpl
> layer_impl_tree_root
=
235 TreeSynchronizer::SynchronizeTrees(layer_tree_root
.get(),
236 scoped_ptr
<LayerImpl
>(),
237 host_
->active_tree());
238 ExpectTreesAreIdentical(layer_tree_root
.get(),
239 layer_impl_tree_root
.get(),
240 host_
->active_tree());
242 // We have to push properties to pick up the destruction list pointer.
243 TreeSynchronizer::PushProperties(layer_tree_root
.get(),
244 layer_impl_tree_root
.get());
246 // Add a new layer to the Layer side
247 layer_tree_root
->children()[0]->
248 AddChild(MockLayer::Create(&layer_impl_destruction_list
));
250 layer_tree_root
->children()[1]->RemoveFromParent();
251 int second_layer_impl_id
= layer_impl_tree_root
->children()[1]->id();
253 // Synchronize again. After the sync the trees should be equivalent and we
254 // should have created and destroyed one LayerImpl.
255 layer_impl_tree_root
=
256 TreeSynchronizer::SynchronizeTrees(layer_tree_root
.get(),
257 layer_impl_tree_root
.Pass(),
258 host_
->active_tree());
259 ExpectTreesAreIdentical(layer_tree_root
.get(),
260 layer_impl_tree_root
.get(),
261 host_
->active_tree());
263 ASSERT_EQ(1u, layer_impl_destruction_list
.size());
264 EXPECT_EQ(second_layer_impl_id
, layer_impl_destruction_list
[0]);
267 // Constructs a very simple tree and checks that a stacking-order change is
269 TEST_F(TreeSynchronizerTest
, SyncSimpleTreeAndTrackStackingOrderChange
) {
270 std::vector
<int> layer_impl_destruction_list
;
272 // Set up the tree and sync once. child2 needs to be synced here, too, even
273 // though we remove it to set up the intended scenario.
274 scoped_refptr
<Layer
> layer_tree_root
=
275 MockLayer::Create(&layer_impl_destruction_list
);
276 scoped_refptr
<Layer
> child2
= MockLayer::Create(&layer_impl_destruction_list
);
277 layer_tree_root
->AddChild(MockLayer::Create(&layer_impl_destruction_list
));
278 layer_tree_root
->AddChild(child2
);
280 host_
->SetRootLayer(layer_tree_root
);
282 scoped_ptr
<LayerImpl
> layer_impl_tree_root
=
283 TreeSynchronizer::SynchronizeTrees(layer_tree_root
.get(),
284 scoped_ptr
<LayerImpl
>(),
285 host_
->active_tree());
286 ExpectTreesAreIdentical(layer_tree_root
.get(),
287 layer_impl_tree_root
.get(),
288 host_
->active_tree());
290 // We have to push properties to pick up the destruction list pointer.
291 TreeSynchronizer::PushProperties(layer_tree_root
.get(),
292 layer_impl_tree_root
.get());
294 layer_impl_tree_root
->ResetAllChangeTrackingForSubtree();
296 // re-insert the layer and sync again.
297 child2
->RemoveFromParent();
298 layer_tree_root
->AddChild(child2
);
299 layer_impl_tree_root
=
300 TreeSynchronizer::SynchronizeTrees(layer_tree_root
.get(),
301 layer_impl_tree_root
.Pass(),
302 host_
->active_tree());
303 ExpectTreesAreIdentical(layer_tree_root
.get(),
304 layer_impl_tree_root
.get(),
305 host_
->active_tree());
307 TreeSynchronizer::PushProperties(layer_tree_root
.get(),
308 layer_impl_tree_root
.get());
310 // Check that the impl thread properly tracked the change.
311 EXPECT_FALSE(layer_impl_tree_root
->LayerPropertyChanged());
312 EXPECT_FALSE(layer_impl_tree_root
->children()[0]->LayerPropertyChanged());
313 EXPECT_TRUE(layer_impl_tree_root
->children()[1]->LayerPropertyChanged());
316 TEST_F(TreeSynchronizerTest
, SyncSimpleTreeAndProperties
) {
317 scoped_refptr
<Layer
> layer_tree_root
= Layer::Create();
318 layer_tree_root
->AddChild(Layer::Create());
319 layer_tree_root
->AddChild(Layer::Create());
321 host_
->SetRootLayer(layer_tree_root
);
323 // Pick some random properties to set. The values are not important, we're
324 // just testing that at least some properties are making it through.
325 gfx::PointF root_position
= gfx::PointF(2.3f
, 7.4f
);
326 layer_tree_root
->SetPosition(root_position
);
328 float first_child_opacity
= 0.25f
;
329 layer_tree_root
->children()[0]->SetOpacity(first_child_opacity
);
331 gfx::Size second_child_bounds
= gfx::Size(25, 53);
332 layer_tree_root
->children()[1]->SetBounds(second_child_bounds
);
333 layer_tree_root
->children()[1]->SavePaintProperties();
335 scoped_ptr
<LayerImpl
> layer_impl_tree_root
=
336 TreeSynchronizer::SynchronizeTrees(layer_tree_root
.get(),
337 scoped_ptr
<LayerImpl
>(),
338 host_
->active_tree());
339 ExpectTreesAreIdentical(layer_tree_root
.get(),
340 layer_impl_tree_root
.get(),
341 host_
->active_tree());
343 TreeSynchronizer::PushProperties(layer_tree_root
.get(),
344 layer_impl_tree_root
.get());
346 // Check that the property values we set on the Layer tree are reflected in
347 // the LayerImpl tree.
348 gfx::PointF root_layer_impl_position
= layer_impl_tree_root
->position();
349 EXPECT_EQ(root_position
.x(), root_layer_impl_position
.x());
350 EXPECT_EQ(root_position
.y(), root_layer_impl_position
.y());
352 EXPECT_EQ(first_child_opacity
,
353 layer_impl_tree_root
->children()[0]->opacity());
355 gfx::Size second_layer_impl_child_bounds
=
356 layer_impl_tree_root
->children()[1]->bounds();
357 EXPECT_EQ(second_child_bounds
.width(),
358 second_layer_impl_child_bounds
.width());
359 EXPECT_EQ(second_child_bounds
.height(),
360 second_layer_impl_child_bounds
.height());
363 TEST_F(TreeSynchronizerTest
, ReuseLayerImplsAfterStructuralChange
) {
364 std::vector
<int> layer_impl_destruction_list
;
366 // Set up a tree with this sort of structure:
367 // root --- A --- B ---+--- C
370 scoped_refptr
<Layer
> layer_tree_root
=
371 MockLayer::Create(&layer_impl_destruction_list
);
372 layer_tree_root
->AddChild(MockLayer::Create(&layer_impl_destruction_list
));
374 scoped_refptr
<Layer
> layer_a
= layer_tree_root
->children()[0].get();
375 layer_a
->AddChild(MockLayer::Create(&layer_impl_destruction_list
));
377 scoped_refptr
<Layer
> layer_b
= layer_a
->children()[0].get();
378 layer_b
->AddChild(MockLayer::Create(&layer_impl_destruction_list
));
380 scoped_refptr
<Layer
> layer_c
= layer_b
->children()[0].get();
381 layer_b
->AddChild(MockLayer::Create(&layer_impl_destruction_list
));
382 scoped_refptr
<Layer
> layer_d
= layer_b
->children()[1].get();
384 host_
->SetRootLayer(layer_tree_root
);
386 scoped_ptr
<LayerImpl
> layer_impl_tree_root
=
387 TreeSynchronizer::SynchronizeTrees(layer_tree_root
.get(),
388 scoped_ptr
<LayerImpl
>(),
389 host_
->active_tree());
390 ExpectTreesAreIdentical(layer_tree_root
.get(),
391 layer_impl_tree_root
.get(),
392 host_
->active_tree());
394 // We have to push properties to pick up the destruction list pointer.
395 TreeSynchronizer::PushProperties(layer_tree_root
.get(),
396 layer_impl_tree_root
.get());
398 // Now restructure the tree to look like this:
399 // root --- D ---+--- A
402 layer_tree_root
->RemoveAllChildren();
403 layer_d
->RemoveAllChildren();
404 layer_tree_root
->AddChild(layer_d
);
405 layer_a
->RemoveAllChildren();
406 layer_d
->AddChild(layer_a
);
407 layer_c
->RemoveAllChildren();
408 layer_d
->AddChild(layer_c
);
409 layer_b
->RemoveAllChildren();
410 layer_c
->AddChild(layer_b
);
412 // After another synchronize our trees should match and we should not have
413 // destroyed any LayerImpls
414 layer_impl_tree_root
=
415 TreeSynchronizer::SynchronizeTrees(layer_tree_root
.get(),
416 layer_impl_tree_root
.Pass(),
417 host_
->active_tree());
418 ExpectTreesAreIdentical(layer_tree_root
.get(),
419 layer_impl_tree_root
.get(),
420 host_
->active_tree());
422 EXPECT_EQ(0u, layer_impl_destruction_list
.size());
425 // Constructs a very simple tree, synchronizes it, then synchronizes to a
426 // totally new tree. All layers from the old tree should be deleted.
427 TEST_F(TreeSynchronizerTest
, SyncSimpleTreeThenDestroy
) {
428 std::vector
<int> layer_impl_destruction_list
;
430 scoped_refptr
<Layer
> old_layer_tree_root
=
431 MockLayer::Create(&layer_impl_destruction_list
);
432 old_layer_tree_root
->AddChild(
433 MockLayer::Create(&layer_impl_destruction_list
));
434 old_layer_tree_root
->AddChild(
435 MockLayer::Create(&layer_impl_destruction_list
));
437 host_
->SetRootLayer(old_layer_tree_root
);
439 int old_tree_root_layer_id
= old_layer_tree_root
->id();
440 int old_tree_first_child_layer_id
= old_layer_tree_root
->children()[0]->id();
441 int old_tree_second_child_layer_id
= old_layer_tree_root
->children()[1]->id();
443 scoped_ptr
<LayerImpl
> layer_impl_tree_root
=
444 TreeSynchronizer::SynchronizeTrees(old_layer_tree_root
.get(),
445 scoped_ptr
<LayerImpl
>(),
446 host_
->active_tree());
447 ExpectTreesAreIdentical(old_layer_tree_root
.get(),
448 layer_impl_tree_root
.get(),
449 host_
->active_tree());
451 // We have to push properties to pick up the destruction list pointer.
452 TreeSynchronizer::PushProperties(old_layer_tree_root
.get(),
453 layer_impl_tree_root
.get());
455 // Remove all children on the Layer side.
456 old_layer_tree_root
->RemoveAllChildren();
458 // Synchronize again. After the sync all LayerImpls from the old tree should
460 scoped_refptr
<Layer
> new_layer_tree_root
= Layer::Create();
461 host_
->SetRootLayer(new_layer_tree_root
);
462 layer_impl_tree_root
=
463 TreeSynchronizer::SynchronizeTrees(new_layer_tree_root
.get(),
464 layer_impl_tree_root
.Pass(),
465 host_
->active_tree());
466 ExpectTreesAreIdentical(new_layer_tree_root
.get(),
467 layer_impl_tree_root
.get(),
468 host_
->active_tree());
470 ASSERT_EQ(3u, layer_impl_destruction_list
.size());
472 EXPECT_TRUE(std::find(layer_impl_destruction_list
.begin(),
473 layer_impl_destruction_list
.end(),
474 old_tree_root_layer_id
) !=
475 layer_impl_destruction_list
.end());
476 EXPECT_TRUE(std::find(layer_impl_destruction_list
.begin(),
477 layer_impl_destruction_list
.end(),
478 old_tree_first_child_layer_id
) !=
479 layer_impl_destruction_list
.end());
480 EXPECT_TRUE(std::find(layer_impl_destruction_list
.begin(),
481 layer_impl_destruction_list
.end(),
482 old_tree_second_child_layer_id
) !=
483 layer_impl_destruction_list
.end());
486 // Constructs+syncs a tree with mask, replica, and replica mask layers.
487 TEST_F(TreeSynchronizerTest
, SyncMaskReplicaAndReplicaMaskLayers
) {
488 scoped_refptr
<Layer
> layer_tree_root
= Layer::Create();
489 layer_tree_root
->AddChild(Layer::Create());
490 layer_tree_root
->AddChild(Layer::Create());
491 layer_tree_root
->AddChild(Layer::Create());
493 // First child gets a mask layer.
494 scoped_refptr
<Layer
> mask_layer
= Layer::Create();
495 layer_tree_root
->children()[0]->SetMaskLayer(mask_layer
.get());
497 // Second child gets a replica layer.
498 scoped_refptr
<Layer
> replica_layer
= Layer::Create();
499 layer_tree_root
->children()[1]->SetReplicaLayer(replica_layer
.get());
501 // Third child gets a replica layer with a mask layer.
502 scoped_refptr
<Layer
> replica_layer_with_mask
= Layer::Create();
503 scoped_refptr
<Layer
> replica_mask_layer
= Layer::Create();
504 replica_layer_with_mask
->SetMaskLayer(replica_mask_layer
.get());
505 layer_tree_root
->children()[2]->
506 SetReplicaLayer(replica_layer_with_mask
.get());
508 host_
->SetRootLayer(layer_tree_root
);
510 scoped_ptr
<LayerImpl
> layer_impl_tree_root
=
511 TreeSynchronizer::SynchronizeTrees(layer_tree_root
.get(),
512 scoped_ptr
<LayerImpl
>(),
513 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
<LayerTreeHostImpl
> host_impl
= LayerTreeHostImpl::Create(
556 settings
, NULL
, &proxy
, &stats_instrumentation
, NULL
, 0);
558 scoped_refptr
<Layer
> layer_tree_root
= Layer::Create();
559 host_
->SetRootLayer(layer_tree_root
);
561 layer_tree_root
->SetLayerAnimationControllerForTest(
562 FakeLayerAnimationController::Create());
564 EXPECT_FALSE(static_cast<FakeLayerAnimationController
*>(
565 layer_tree_root
->layer_animation_controller())->SynchronizedAnimations());
567 scoped_ptr
<LayerImpl
> layer_impl_tree_root
=
568 TreeSynchronizer::SynchronizeTrees(layer_tree_root
.get(),
569 scoped_ptr
<LayerImpl
>(),
570 host_
->active_tree());
571 TreeSynchronizer::PushProperties(layer_tree_root
.get(),
572 layer_impl_tree_root
.get());
573 layer_impl_tree_root
=
574 TreeSynchronizer::SynchronizeTrees(layer_tree_root
.get(),
575 layer_impl_tree_root
.Pass(),
576 host_
->active_tree());
578 EXPECT_TRUE(static_cast<FakeLayerAnimationController
*>(
579 layer_tree_root
->layer_animation_controller())->SynchronizedAnimations());
582 TEST_F(TreeSynchronizerTest
, SynchronizeScrollParent
) {
583 LayerTreeSettings settings
;
585 DebugScopedSetImplThread
impl(&proxy
);
586 FakeRenderingStatsInstrumentation stats_instrumentation
;
587 scoped_ptr
<LayerTreeHostImpl
> host_impl
= LayerTreeHostImpl::Create(
588 settings
, NULL
, &proxy
, &stats_instrumentation
, NULL
, 0);
590 scoped_refptr
<Layer
> layer_tree_root
= Layer::Create();
591 scoped_refptr
<Layer
> scroll_parent
= Layer::Create();
592 layer_tree_root
->AddChild(scroll_parent
);
593 layer_tree_root
->AddChild(Layer::Create());
594 layer_tree_root
->AddChild(Layer::Create());
596 host_
->SetRootLayer(layer_tree_root
);
598 // First child is the second and third child's scroll parent.
599 layer_tree_root
->children()[1]->SetScrollParent(scroll_parent
);
600 layer_tree_root
->children()[2]->SetScrollParent(scroll_parent
);
602 scoped_ptr
<LayerImpl
> layer_impl_tree_root
=
603 TreeSynchronizer::SynchronizeTrees(layer_tree_root
.get(),
604 scoped_ptr
<LayerImpl
>(),
605 host_impl
->active_tree());
606 TreeSynchronizer::PushProperties(layer_tree_root
.get(),
607 layer_impl_tree_root
.get());
608 ExpectTreesAreIdentical(layer_tree_root
.get(),
609 layer_impl_tree_root
.get(),
610 host_impl
->active_tree());
612 // Remove the first scroll child.
613 layer_tree_root
->children()[1]->RemoveFromParent();
614 layer_impl_tree_root
=
615 TreeSynchronizer::SynchronizeTrees(layer_tree_root
.get(),
616 layer_impl_tree_root
.Pass(),
617 host_impl
->active_tree());
618 TreeSynchronizer::PushProperties(layer_tree_root
.get(),
619 layer_impl_tree_root
.get());
620 ExpectTreesAreIdentical(layer_tree_root
.get(),
621 layer_impl_tree_root
.get(),
622 host_impl
->active_tree());
624 // Add an additional scroll layer.
625 scoped_refptr
<Layer
> additional_scroll_child
= Layer::Create();
626 layer_tree_root
->AddChild(additional_scroll_child
);
627 additional_scroll_child
->SetScrollParent(scroll_parent
);
628 layer_impl_tree_root
=
629 TreeSynchronizer::SynchronizeTrees(layer_tree_root
.get(),
630 layer_impl_tree_root
.Pass(),
631 host_impl
->active_tree());
632 TreeSynchronizer::PushProperties(layer_tree_root
.get(),
633 layer_impl_tree_root
.get());
634 ExpectTreesAreIdentical(layer_tree_root
.get(),
635 layer_impl_tree_root
.get(),
636 host_impl
->active_tree());
638 // Remove the scroll parent.
639 scroll_parent
->RemoveFromParent();
640 scroll_parent
= NULL
;
641 layer_impl_tree_root
=
642 TreeSynchronizer::SynchronizeTrees(layer_tree_root
.get(),
643 layer_impl_tree_root
.Pass(),
644 host_impl
->active_tree());
645 TreeSynchronizer::PushProperties(layer_tree_root
.get(),
646 layer_impl_tree_root
.get());
647 ExpectTreesAreIdentical(layer_tree_root
.get(),
648 layer_impl_tree_root
.get(),
649 host_impl
->active_tree());
651 // The scroll children should have been unhooked.
652 EXPECT_EQ(2u, layer_tree_root
->children().size());
653 EXPECT_FALSE(layer_tree_root
->children()[0]->scroll_parent());
654 EXPECT_FALSE(layer_tree_root
->children()[1]->scroll_parent());
657 TEST_F(TreeSynchronizerTest
, SynchronizeClipParent
) {
658 LayerTreeSettings settings
;
660 DebugScopedSetImplThread
impl(&proxy
);
661 FakeRenderingStatsInstrumentation stats_instrumentation
;
662 scoped_ptr
<LayerTreeHostImpl
> host_impl
= LayerTreeHostImpl::Create(
663 settings
, NULL
, &proxy
, &stats_instrumentation
, NULL
, 0);
665 scoped_refptr
<Layer
> layer_tree_root
= Layer::Create();
666 scoped_refptr
<Layer
> clip_parent
= Layer::Create();
667 scoped_refptr
<Layer
> intervening
= Layer::Create();
668 scoped_refptr
<Layer
> clip_child1
= Layer::Create();
669 scoped_refptr
<Layer
> clip_child2
= Layer::Create();
670 layer_tree_root
->AddChild(clip_parent
);
671 clip_parent
->AddChild(intervening
);
672 intervening
->AddChild(clip_child1
);
673 intervening
->AddChild(clip_child2
);
675 host_
->SetRootLayer(layer_tree_root
);
677 // First child is the second and third child's scroll parent.
678 clip_child1
->SetClipParent(clip_parent
);
679 clip_child2
->SetClipParent(clip_parent
);
681 scoped_ptr
<LayerImpl
> layer_impl_tree_root
=
682 TreeSynchronizer::SynchronizeTrees(layer_tree_root
.get(),
683 scoped_ptr
<LayerImpl
>(),
684 host_impl
->active_tree());
685 TreeSynchronizer::PushProperties(layer_tree_root
.get(),
686 layer_impl_tree_root
.get());
687 ExpectTreesAreIdentical(layer_tree_root
.get(),
688 layer_impl_tree_root
.get(),
689 host_impl
->active_tree());
691 // Remove the first clip child.
692 clip_child1
->RemoveFromParent();
695 layer_impl_tree_root
=
696 TreeSynchronizer::SynchronizeTrees(layer_tree_root
.get(),
697 layer_impl_tree_root
.Pass(),
698 host_impl
->active_tree());
699 TreeSynchronizer::PushProperties(layer_tree_root
.get(),
700 layer_impl_tree_root
.get());
701 ExpectTreesAreIdentical(layer_tree_root
.get(),
702 layer_impl_tree_root
.get(),
703 host_impl
->active_tree());
705 // Add an additional clip child.
706 scoped_refptr
<Layer
> additional_clip_child
= Layer::Create();
707 intervening
->AddChild(additional_clip_child
);
708 additional_clip_child
->SetClipParent(clip_parent
);
709 layer_impl_tree_root
=
710 TreeSynchronizer::SynchronizeTrees(layer_tree_root
.get(),
711 layer_impl_tree_root
.Pass(),
712 host_impl
->active_tree());
713 TreeSynchronizer::PushProperties(layer_tree_root
.get(),
714 layer_impl_tree_root
.get());
715 ExpectTreesAreIdentical(layer_tree_root
.get(),
716 layer_impl_tree_root
.get(),
717 host_impl
->active_tree());
719 // Remove the nearest clipping ancestor.
720 clip_parent
->RemoveFromParent();
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 // The clip children should have been unhooked.
733 EXPECT_EQ(2u, intervening
->children().size());
734 EXPECT_FALSE(clip_child2
->clip_parent());
735 EXPECT_FALSE(additional_clip_child
->clip_parent());