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/trees/proxy.h"
22 #include "cc/trees/single_thread_proxy.h"
23 #include "testing/gtest/include/gtest/gtest.h"
28 class MockLayerImpl
: public LayerImpl
{
30 static scoped_ptr
<MockLayerImpl
> Create(LayerTreeImpl
* tree_impl
,
32 return make_scoped_ptr(new MockLayerImpl(tree_impl
, layer_id
));
34 ~MockLayerImpl() override
{
35 if (layer_impl_destruction_list_
)
36 layer_impl_destruction_list_
->push_back(id());
39 void SetLayerImplDestructionList(std::vector
<int>* list
) {
40 layer_impl_destruction_list_
= list
;
44 MockLayerImpl(LayerTreeImpl
* tree_impl
, int layer_id
)
45 : LayerImpl(tree_impl
, layer_id
),
46 layer_impl_destruction_list_(NULL
) {}
48 std::vector
<int>* layer_impl_destruction_list_
;
51 class MockLayer
: public Layer
{
53 static scoped_refptr
<MockLayer
> Create(
54 std::vector
<int>* layer_impl_destruction_list
) {
55 return make_scoped_refptr(new MockLayer(layer_impl_destruction_list
));
58 scoped_ptr
<LayerImpl
> CreateLayerImpl(LayerTreeImpl
* tree_impl
) override
{
59 return MockLayerImpl::Create(tree_impl
, layer_id_
);
62 void PushPropertiesTo(LayerImpl
* layer_impl
) override
{
63 Layer::PushPropertiesTo(layer_impl
);
65 MockLayerImpl
* mock_layer_impl
= static_cast<MockLayerImpl
*>(layer_impl
);
66 mock_layer_impl
->SetLayerImplDestructionList(layer_impl_destruction_list_
);
70 explicit MockLayer(std::vector
<int>* layer_impl_destruction_list
)
71 : Layer(), layer_impl_destruction_list_(layer_impl_destruction_list
) {}
72 ~MockLayer() override
{}
74 std::vector
<int>* layer_impl_destruction_list_
;
77 class FakeLayerAnimationController
: public LayerAnimationController
{
79 static scoped_refptr
<LayerAnimationController
> Create() {
80 return static_cast<LayerAnimationController
*>(
81 new FakeLayerAnimationController
);
84 bool SynchronizedAnimations() const { return synchronized_animations_
; }
87 FakeLayerAnimationController()
88 : LayerAnimationController(1),
89 synchronized_animations_(false) {}
91 ~FakeLayerAnimationController() override
{}
93 void PushAnimationUpdatesTo(
94 LayerAnimationController
* controller_impl
) override
{
95 LayerAnimationController::PushAnimationUpdatesTo(controller_impl
);
96 synchronized_animations_
= true;
99 bool synchronized_animations_
;
102 void ExpectTreesAreIdentical(Layer
* layer
,
103 LayerImpl
* layer_impl
,
104 LayerTreeImpl
* tree_impl
) {
106 ASSERT_TRUE(layer_impl
);
108 EXPECT_EQ(layer
->id(), layer_impl
->id());
109 EXPECT_EQ(layer_impl
->layer_tree_impl(), tree_impl
);
111 EXPECT_EQ(layer
->non_fast_scrollable_region(),
112 layer_impl
->non_fast_scrollable_region());
114 ASSERT_EQ(!!layer
->mask_layer(), !!layer_impl
->mask_layer());
115 if (layer
->mask_layer()) {
116 SCOPED_TRACE("mask_layer");
117 ExpectTreesAreIdentical(
118 layer
->mask_layer(), layer_impl
->mask_layer(), tree_impl
);
121 ASSERT_EQ(!!layer
->replica_layer(), !!layer_impl
->replica_layer());
122 if (layer
->replica_layer()) {
123 SCOPED_TRACE("replica_layer");
124 ExpectTreesAreIdentical(
125 layer
->replica_layer(), layer_impl
->replica_layer(), tree_impl
);
128 const LayerList
& layer_children
= layer
->children();
129 const OwnedLayerImplList
& layer_impl_children
= layer_impl
->children();
131 ASSERT_EQ(layer_children
.size(), layer_impl_children
.size());
133 const std::set
<Layer
*>* layer_scroll_children
= layer
->scroll_children();
134 const std::set
<LayerImpl
*>* layer_impl_scroll_children
=
135 layer_impl
->scroll_children();
137 ASSERT_EQ(!!layer_scroll_children
, !!layer_impl_scroll_children
);
139 if (layer_scroll_children
) {
141 layer_scroll_children
->size(),
142 layer_impl_scroll_children
->size());
145 const Layer
* layer_scroll_parent
= layer
->scroll_parent();
146 const LayerImpl
* layer_impl_scroll_parent
= layer_impl
->scroll_parent();
148 ASSERT_EQ(!!layer_scroll_parent
, !!layer_impl_scroll_parent
);
150 if (layer_scroll_parent
) {
151 ASSERT_EQ(layer_scroll_parent
->id(), layer_impl_scroll_parent
->id());
152 ASSERT_TRUE(layer_scroll_parent
->scroll_children()->find(layer
) !=
153 layer_scroll_parent
->scroll_children()->end());
154 ASSERT_TRUE(layer_impl_scroll_parent
->scroll_children()->find(layer_impl
) !=
155 layer_impl_scroll_parent
->scroll_children()->end());
158 const std::set
<Layer
*>* layer_clip_children
= layer
->clip_children();
159 const std::set
<LayerImpl
*>* layer_impl_clip_children
=
160 layer_impl
->clip_children();
162 ASSERT_EQ(!!layer_clip_children
, !!layer_impl_clip_children
);
164 if (layer_clip_children
)
165 ASSERT_EQ(layer_clip_children
->size(), layer_impl_clip_children
->size());
167 const Layer
* layer_clip_parent
= layer
->clip_parent();
168 const LayerImpl
* layer_impl_clip_parent
= layer_impl
->clip_parent();
170 ASSERT_EQ(!!layer_clip_parent
, !!layer_impl_clip_parent
);
172 if (layer_clip_parent
) {
173 const std::set
<LayerImpl
*>* clip_children_impl
=
174 layer_impl_clip_parent
->clip_children();
175 const std::set
<Layer
*>* clip_children
=
176 layer_clip_parent
->clip_children();
177 ASSERT_EQ(layer_clip_parent
->id(), layer_impl_clip_parent
->id());
178 ASSERT_TRUE(clip_children
->find(layer
) != clip_children
->end());
179 ASSERT_TRUE(clip_children_impl
->find(layer_impl
) !=
180 clip_children_impl
->end());
183 for (size_t i
= 0; i
< layer_children
.size(); ++i
) {
184 SCOPED_TRACE(base::StringPrintf("child layer %" PRIuS
, i
).c_str());
185 ExpectTreesAreIdentical(
186 layer_children
[i
].get(), layer_impl_children
[i
], tree_impl
);
190 class TreeSynchronizerTest
: public testing::Test
{
192 TreeSynchronizerTest()
193 : client_(FakeLayerTreeHostClient::DIRECT_3D
),
194 host_(FakeLayerTreeHost::Create(&client_
)) {}
197 FakeLayerTreeHostClient client_
;
198 scoped_ptr
<FakeLayerTreeHost
> host_
;
201 // Attempts to synchronizes a null tree. This should not crash, and should
202 // return a null tree.
203 TEST_F(TreeSynchronizerTest
, SyncNullTree
) {
204 scoped_ptr
<LayerImpl
> layer_impl_tree_root
=
205 TreeSynchronizer::SynchronizeTrees(
206 static_cast<Layer
*>(NULL
), nullptr, host_
->active_tree());
208 EXPECT_TRUE(!layer_impl_tree_root
.get());
211 // Constructs a very simple tree and synchronizes it without trying to reuse any
212 // preexisting layers.
213 TEST_F(TreeSynchronizerTest
, SyncSimpleTreeFromEmpty
) {
214 scoped_refptr
<Layer
> layer_tree_root
= Layer::Create();
215 layer_tree_root
->AddChild(Layer::Create());
216 layer_tree_root
->AddChild(Layer::Create());
218 host_
->SetRootLayer(layer_tree_root
);
220 scoped_ptr
<LayerImpl
> layer_impl_tree_root
=
221 TreeSynchronizer::SynchronizeTrees(
222 layer_tree_root
.get(), nullptr, host_
->active_tree());
224 ExpectTreesAreIdentical(layer_tree_root
.get(),
225 layer_impl_tree_root
.get(),
226 host_
->active_tree());
229 // Constructs a very simple tree and synchronizes it attempting to reuse some
231 TEST_F(TreeSynchronizerTest
, SyncSimpleTreeReusingLayers
) {
232 std::vector
<int> layer_impl_destruction_list
;
234 scoped_refptr
<Layer
> layer_tree_root
=
235 MockLayer::Create(&layer_impl_destruction_list
);
236 layer_tree_root
->AddChild(MockLayer::Create(&layer_impl_destruction_list
));
237 layer_tree_root
->AddChild(MockLayer::Create(&layer_impl_destruction_list
));
239 host_
->SetRootLayer(layer_tree_root
);
241 scoped_ptr
<LayerImpl
> layer_impl_tree_root
=
242 TreeSynchronizer::SynchronizeTrees(
243 layer_tree_root
.get(), nullptr, host_
->active_tree());
244 ExpectTreesAreIdentical(layer_tree_root
.get(),
245 layer_impl_tree_root
.get(),
246 host_
->active_tree());
248 // We have to push properties to pick up the destruction list pointer.
249 TreeSynchronizer::PushProperties(layer_tree_root
.get(),
250 layer_impl_tree_root
.get());
252 // Add a new layer to the Layer side
253 layer_tree_root
->children()[0]->
254 AddChild(MockLayer::Create(&layer_impl_destruction_list
));
256 layer_tree_root
->children()[1]->RemoveFromParent();
257 int second_layer_impl_id
= layer_impl_tree_root
->children()[1]->id();
259 // Synchronize again. After the sync the trees should be equivalent and we
260 // should have created and destroyed one LayerImpl.
261 layer_impl_tree_root
=
262 TreeSynchronizer::SynchronizeTrees(layer_tree_root
.get(),
263 layer_impl_tree_root
.Pass(),
264 host_
->active_tree());
265 ExpectTreesAreIdentical(layer_tree_root
.get(),
266 layer_impl_tree_root
.get(),
267 host_
->active_tree());
269 ASSERT_EQ(1u, layer_impl_destruction_list
.size());
270 EXPECT_EQ(second_layer_impl_id
, layer_impl_destruction_list
[0]);
273 // Constructs a very simple tree and checks that a stacking-order change is
275 TEST_F(TreeSynchronizerTest
, SyncSimpleTreeAndTrackStackingOrderChange
) {
276 std::vector
<int> layer_impl_destruction_list
;
278 // Set up the tree and sync once. child2 needs to be synced here, too, even
279 // though we remove it to set up the intended scenario.
280 scoped_refptr
<Layer
> layer_tree_root
=
281 MockLayer::Create(&layer_impl_destruction_list
);
282 scoped_refptr
<Layer
> child2
= MockLayer::Create(&layer_impl_destruction_list
);
283 layer_tree_root
->AddChild(MockLayer::Create(&layer_impl_destruction_list
));
284 layer_tree_root
->AddChild(child2
);
286 host_
->SetRootLayer(layer_tree_root
);
288 scoped_ptr
<LayerImpl
> layer_impl_tree_root
=
289 TreeSynchronizer::SynchronizeTrees(
290 layer_tree_root
.get(), nullptr, host_
->active_tree());
291 ExpectTreesAreIdentical(layer_tree_root
.get(),
292 layer_impl_tree_root
.get(),
293 host_
->active_tree());
295 // We have to push properties to pick up the destruction list pointer.
296 TreeSynchronizer::PushProperties(layer_tree_root
.get(),
297 layer_impl_tree_root
.get());
299 layer_impl_tree_root
->ResetAllChangeTrackingForSubtree();
301 // re-insert the layer and sync again.
302 child2
->RemoveFromParent();
303 layer_tree_root
->AddChild(child2
);
304 layer_impl_tree_root
=
305 TreeSynchronizer::SynchronizeTrees(layer_tree_root
.get(),
306 layer_impl_tree_root
.Pass(),
307 host_
->active_tree());
308 ExpectTreesAreIdentical(layer_tree_root
.get(),
309 layer_impl_tree_root
.get(),
310 host_
->active_tree());
312 TreeSynchronizer::PushProperties(layer_tree_root
.get(),
313 layer_impl_tree_root
.get());
315 // Check that the impl thread properly tracked the change.
316 EXPECT_FALSE(layer_impl_tree_root
->LayerPropertyChanged());
317 EXPECT_FALSE(layer_impl_tree_root
->children()[0]->LayerPropertyChanged());
318 EXPECT_TRUE(layer_impl_tree_root
->children()[1]->LayerPropertyChanged());
321 TEST_F(TreeSynchronizerTest
, SyncSimpleTreeAndProperties
) {
322 scoped_refptr
<Layer
> layer_tree_root
= Layer::Create();
323 layer_tree_root
->AddChild(Layer::Create());
324 layer_tree_root
->AddChild(Layer::Create());
326 host_
->SetRootLayer(layer_tree_root
);
328 // Pick some random properties to set. The values are not important, we're
329 // just testing that at least some properties are making it through.
330 gfx::PointF root_position
= gfx::PointF(2.3f
, 7.4f
);
331 layer_tree_root
->SetPosition(root_position
);
333 float first_child_opacity
= 0.25f
;
334 layer_tree_root
->children()[0]->SetOpacity(first_child_opacity
);
336 gfx::Size second_child_bounds
= gfx::Size(25, 53);
337 layer_tree_root
->children()[1]->SetBounds(second_child_bounds
);
338 layer_tree_root
->children()[1]->SavePaintProperties();
340 scoped_ptr
<LayerImpl
> layer_impl_tree_root
=
341 TreeSynchronizer::SynchronizeTrees(
342 layer_tree_root
.get(), nullptr, host_
->active_tree());
343 ExpectTreesAreIdentical(layer_tree_root
.get(),
344 layer_impl_tree_root
.get(),
345 host_
->active_tree());
347 TreeSynchronizer::PushProperties(layer_tree_root
.get(),
348 layer_impl_tree_root
.get());
350 // Check that the property values we set on the Layer tree are reflected in
351 // the LayerImpl tree.
352 gfx::PointF root_layer_impl_position
= layer_impl_tree_root
->position();
353 EXPECT_EQ(root_position
.x(), root_layer_impl_position
.x());
354 EXPECT_EQ(root_position
.y(), root_layer_impl_position
.y());
356 EXPECT_EQ(first_child_opacity
,
357 layer_impl_tree_root
->children()[0]->opacity());
359 gfx::Size second_layer_impl_child_bounds
=
360 layer_impl_tree_root
->children()[1]->bounds();
361 EXPECT_EQ(second_child_bounds
.width(),
362 second_layer_impl_child_bounds
.width());
363 EXPECT_EQ(second_child_bounds
.height(),
364 second_layer_impl_child_bounds
.height());
367 TEST_F(TreeSynchronizerTest
, ReuseLayerImplsAfterStructuralChange
) {
368 std::vector
<int> layer_impl_destruction_list
;
370 // Set up a tree with this sort of structure:
371 // root --- A --- B ---+--- C
374 scoped_refptr
<Layer
> layer_tree_root
=
375 MockLayer::Create(&layer_impl_destruction_list
);
376 layer_tree_root
->AddChild(MockLayer::Create(&layer_impl_destruction_list
));
378 scoped_refptr
<Layer
> layer_a
= layer_tree_root
->children()[0].get();
379 layer_a
->AddChild(MockLayer::Create(&layer_impl_destruction_list
));
381 scoped_refptr
<Layer
> layer_b
= layer_a
->children()[0].get();
382 layer_b
->AddChild(MockLayer::Create(&layer_impl_destruction_list
));
384 scoped_refptr
<Layer
> layer_c
= layer_b
->children()[0].get();
385 layer_b
->AddChild(MockLayer::Create(&layer_impl_destruction_list
));
386 scoped_refptr
<Layer
> layer_d
= layer_b
->children()[1].get();
388 host_
->SetRootLayer(layer_tree_root
);
390 scoped_ptr
<LayerImpl
> layer_impl_tree_root
=
391 TreeSynchronizer::SynchronizeTrees(
392 layer_tree_root
.get(), nullptr, host_
->active_tree());
393 ExpectTreesAreIdentical(layer_tree_root
.get(),
394 layer_impl_tree_root
.get(),
395 host_
->active_tree());
397 // We have to push properties to pick up the destruction list pointer.
398 TreeSynchronizer::PushProperties(layer_tree_root
.get(),
399 layer_impl_tree_root
.get());
401 // Now restructure the tree to look like this:
402 // root --- D ---+--- A
405 layer_tree_root
->RemoveAllChildren();
406 layer_d
->RemoveAllChildren();
407 layer_tree_root
->AddChild(layer_d
);
408 layer_a
->RemoveAllChildren();
409 layer_d
->AddChild(layer_a
);
410 layer_c
->RemoveAllChildren();
411 layer_d
->AddChild(layer_c
);
412 layer_b
->RemoveAllChildren();
413 layer_c
->AddChild(layer_b
);
415 // After another synchronize our trees should match and we should not have
416 // destroyed any LayerImpls
417 layer_impl_tree_root
=
418 TreeSynchronizer::SynchronizeTrees(layer_tree_root
.get(),
419 layer_impl_tree_root
.Pass(),
420 host_
->active_tree());
421 ExpectTreesAreIdentical(layer_tree_root
.get(),
422 layer_impl_tree_root
.get(),
423 host_
->active_tree());
425 EXPECT_EQ(0u, layer_impl_destruction_list
.size());
428 // Constructs a very simple tree, synchronizes it, then synchronizes to a
429 // totally new tree. All layers from the old tree should be deleted.
430 TEST_F(TreeSynchronizerTest
, SyncSimpleTreeThenDestroy
) {
431 std::vector
<int> layer_impl_destruction_list
;
433 scoped_refptr
<Layer
> old_layer_tree_root
=
434 MockLayer::Create(&layer_impl_destruction_list
);
435 old_layer_tree_root
->AddChild(
436 MockLayer::Create(&layer_impl_destruction_list
));
437 old_layer_tree_root
->AddChild(
438 MockLayer::Create(&layer_impl_destruction_list
));
440 host_
->SetRootLayer(old_layer_tree_root
);
442 int old_tree_root_layer_id
= old_layer_tree_root
->id();
443 int old_tree_first_child_layer_id
= old_layer_tree_root
->children()[0]->id();
444 int old_tree_second_child_layer_id
= old_layer_tree_root
->children()[1]->id();
446 scoped_ptr
<LayerImpl
> layer_impl_tree_root
=
447 TreeSynchronizer::SynchronizeTrees(
448 old_layer_tree_root
.get(), nullptr, host_
->active_tree());
449 ExpectTreesAreIdentical(old_layer_tree_root
.get(),
450 layer_impl_tree_root
.get(),
451 host_
->active_tree());
453 // We have to push properties to pick up the destruction list pointer.
454 TreeSynchronizer::PushProperties(old_layer_tree_root
.get(),
455 layer_impl_tree_root
.get());
457 // Remove all children on the Layer side.
458 old_layer_tree_root
->RemoveAllChildren();
460 // Synchronize again. After the sync all LayerImpls from the old tree should
462 scoped_refptr
<Layer
> new_layer_tree_root
= Layer::Create();
463 host_
->SetRootLayer(new_layer_tree_root
);
464 layer_impl_tree_root
=
465 TreeSynchronizer::SynchronizeTrees(new_layer_tree_root
.get(),
466 layer_impl_tree_root
.Pass(),
467 host_
->active_tree());
468 ExpectTreesAreIdentical(new_layer_tree_root
.get(),
469 layer_impl_tree_root
.get(),
470 host_
->active_tree());
472 ASSERT_EQ(3u, layer_impl_destruction_list
.size());
474 EXPECT_TRUE(std::find(layer_impl_destruction_list
.begin(),
475 layer_impl_destruction_list
.end(),
476 old_tree_root_layer_id
) !=
477 layer_impl_destruction_list
.end());
478 EXPECT_TRUE(std::find(layer_impl_destruction_list
.begin(),
479 layer_impl_destruction_list
.end(),
480 old_tree_first_child_layer_id
) !=
481 layer_impl_destruction_list
.end());
482 EXPECT_TRUE(std::find(layer_impl_destruction_list
.begin(),
483 layer_impl_destruction_list
.end(),
484 old_tree_second_child_layer_id
) !=
485 layer_impl_destruction_list
.end());
488 // Constructs+syncs a tree with mask, replica, and replica mask layers.
489 TEST_F(TreeSynchronizerTest
, SyncMaskReplicaAndReplicaMaskLayers
) {
490 scoped_refptr
<Layer
> layer_tree_root
= Layer::Create();
491 layer_tree_root
->AddChild(Layer::Create());
492 layer_tree_root
->AddChild(Layer::Create());
493 layer_tree_root
->AddChild(Layer::Create());
495 // First child gets a mask layer.
496 scoped_refptr
<Layer
> mask_layer
= Layer::Create();
497 layer_tree_root
->children()[0]->SetMaskLayer(mask_layer
.get());
499 // Second child gets a replica layer.
500 scoped_refptr
<Layer
> replica_layer
= Layer::Create();
501 layer_tree_root
->children()[1]->SetReplicaLayer(replica_layer
.get());
503 // Third child gets a replica layer with a mask layer.
504 scoped_refptr
<Layer
> replica_layer_with_mask
= Layer::Create();
505 scoped_refptr
<Layer
> replica_mask_layer
= Layer::Create();
506 replica_layer_with_mask
->SetMaskLayer(replica_mask_layer
.get());
507 layer_tree_root
->children()[2]->
508 SetReplicaLayer(replica_layer_with_mask
.get());
510 host_
->SetRootLayer(layer_tree_root
);
512 scoped_ptr
<LayerImpl
> layer_impl_tree_root
=
513 TreeSynchronizer::SynchronizeTrees(
514 layer_tree_root
.get(), nullptr, host_
->active_tree());
516 ExpectTreesAreIdentical(layer_tree_root
.get(),
517 layer_impl_tree_root
.get(),
518 host_
->active_tree());
520 // Remove the mask layer.
521 layer_tree_root
->children()[0]->SetMaskLayer(NULL
);
522 layer_impl_tree_root
=
523 TreeSynchronizer::SynchronizeTrees(layer_tree_root
.get(),
524 layer_impl_tree_root
.Pass(),
525 host_
->active_tree());
526 ExpectTreesAreIdentical(layer_tree_root
.get(),
527 layer_impl_tree_root
.get(),
528 host_
->active_tree());
530 // Remove the replica layer.
531 layer_tree_root
->children()[1]->SetReplicaLayer(NULL
);
532 layer_impl_tree_root
=
533 TreeSynchronizer::SynchronizeTrees(layer_tree_root
.get(),
534 layer_impl_tree_root
.Pass(),
535 host_
->active_tree());
536 ExpectTreesAreIdentical(layer_tree_root
.get(),
537 layer_impl_tree_root
.get(),
538 host_
->active_tree());
540 // Remove the replica mask.
541 replica_layer_with_mask
->SetMaskLayer(NULL
);
542 layer_impl_tree_root
=
543 TreeSynchronizer::SynchronizeTrees(layer_tree_root
.get(),
544 layer_impl_tree_root
.Pass(),
545 host_
->active_tree());
546 ExpectTreesAreIdentical(layer_tree_root
.get(),
547 layer_impl_tree_root
.get(),
548 host_
->active_tree());
551 TEST_F(TreeSynchronizerTest
, SynchronizeAnimations
) {
552 LayerTreeSettings settings
;
554 DebugScopedSetImplThread
impl(&proxy
);
555 FakeRenderingStatsInstrumentation stats_instrumentation
;
556 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
557 new TestSharedBitmapManager());
558 scoped_ptr
<LayerTreeHostImpl
> host_impl
=
559 LayerTreeHostImpl::Create(settings
, NULL
, &proxy
, &stats_instrumentation
,
560 shared_bitmap_manager
.get(), NULL
, NULL
, 0);
562 scoped_refptr
<Layer
> layer_tree_root
= Layer::Create();
563 host_
->SetRootLayer(layer_tree_root
);
565 layer_tree_root
->SetLayerAnimationControllerForTest(
566 FakeLayerAnimationController::Create());
568 EXPECT_FALSE(static_cast<FakeLayerAnimationController
*>(
569 layer_tree_root
->layer_animation_controller())->SynchronizedAnimations());
571 scoped_ptr
<LayerImpl
> layer_impl_tree_root
=
572 TreeSynchronizer::SynchronizeTrees(
573 layer_tree_root
.get(), nullptr, host_
->active_tree());
574 TreeSynchronizer::PushProperties(layer_tree_root
.get(),
575 layer_impl_tree_root
.get());
576 layer_impl_tree_root
=
577 TreeSynchronizer::SynchronizeTrees(layer_tree_root
.get(),
578 layer_impl_tree_root
.Pass(),
579 host_
->active_tree());
581 EXPECT_TRUE(static_cast<FakeLayerAnimationController
*>(
582 layer_tree_root
->layer_animation_controller())->SynchronizedAnimations());
585 TEST_F(TreeSynchronizerTest
, SynchronizeScrollParent
) {
586 LayerTreeSettings settings
;
588 DebugScopedSetImplThread
impl(&proxy
);
589 FakeRenderingStatsInstrumentation stats_instrumentation
;
590 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
591 new TestSharedBitmapManager());
592 scoped_ptr
<LayerTreeHostImpl
> host_impl
=
593 LayerTreeHostImpl::Create(settings
, NULL
, &proxy
, &stats_instrumentation
,
594 shared_bitmap_manager
.get(), NULL
, NULL
, 0);
596 scoped_refptr
<Layer
> layer_tree_root
= Layer::Create();
597 scoped_refptr
<Layer
> scroll_parent
= Layer::Create();
598 layer_tree_root
->AddChild(scroll_parent
);
599 layer_tree_root
->AddChild(Layer::Create());
600 layer_tree_root
->AddChild(Layer::Create());
602 host_
->SetRootLayer(layer_tree_root
);
604 // First child is the second and third child's scroll parent.
605 layer_tree_root
->children()[1]->SetScrollParent(scroll_parent
.get());
606 layer_tree_root
->children()[2]->SetScrollParent(scroll_parent
.get());
608 scoped_ptr
<LayerImpl
> layer_impl_tree_root
=
609 TreeSynchronizer::SynchronizeTrees(
610 layer_tree_root
.get(), nullptr, host_impl
->active_tree());
611 TreeSynchronizer::PushProperties(layer_tree_root
.get(),
612 layer_impl_tree_root
.get());
614 SCOPED_TRACE("case one");
615 ExpectTreesAreIdentical(layer_tree_root
.get(),
616 layer_impl_tree_root
.get(),
617 host_impl
->active_tree());
620 // Remove the first scroll child.
621 layer_tree_root
->children()[1]->RemoveFromParent();
622 layer_impl_tree_root
=
623 TreeSynchronizer::SynchronizeTrees(layer_tree_root
.get(),
624 layer_impl_tree_root
.Pass(),
625 host_impl
->active_tree());
626 TreeSynchronizer::PushProperties(layer_tree_root
.get(),
627 layer_impl_tree_root
.get());
629 SCOPED_TRACE("case two");
630 ExpectTreesAreIdentical(layer_tree_root
.get(),
631 layer_impl_tree_root
.get(),
632 host_impl
->active_tree());
635 // Add an additional scroll layer.
636 scoped_refptr
<Layer
> additional_scroll_child
= Layer::Create();
637 layer_tree_root
->AddChild(additional_scroll_child
);
638 additional_scroll_child
->SetScrollParent(scroll_parent
.get());
639 layer_impl_tree_root
=
640 TreeSynchronizer::SynchronizeTrees(layer_tree_root
.get(),
641 layer_impl_tree_root
.Pass(),
642 host_impl
->active_tree());
643 TreeSynchronizer::PushProperties(layer_tree_root
.get(),
644 layer_impl_tree_root
.get());
646 SCOPED_TRACE("case three");
647 ExpectTreesAreIdentical(layer_tree_root
.get(),
648 layer_impl_tree_root
.get(),
649 host_impl
->active_tree());
653 TEST_F(TreeSynchronizerTest
, SynchronizeClipParent
) {
654 LayerTreeSettings settings
;
656 DebugScopedSetImplThread
impl(&proxy
);
657 FakeRenderingStatsInstrumentation stats_instrumentation
;
658 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
659 new TestSharedBitmapManager());
660 scoped_ptr
<LayerTreeHostImpl
> host_impl
=
661 LayerTreeHostImpl::Create(settings
, NULL
, &proxy
, &stats_instrumentation
,
662 shared_bitmap_manager
.get(), NULL
, NULL
, 0);
664 scoped_refptr
<Layer
> layer_tree_root
= Layer::Create();
665 scoped_refptr
<Layer
> clip_parent
= Layer::Create();
666 scoped_refptr
<Layer
> intervening
= Layer::Create();
667 scoped_refptr
<Layer
> clip_child1
= Layer::Create();
668 scoped_refptr
<Layer
> clip_child2
= Layer::Create();
669 layer_tree_root
->AddChild(clip_parent
);
670 clip_parent
->AddChild(intervening
);
671 intervening
->AddChild(clip_child1
);
672 intervening
->AddChild(clip_child2
);
674 host_
->SetRootLayer(layer_tree_root
);
676 // First child is the second and third child's scroll parent.
677 clip_child1
->SetClipParent(clip_parent
.get());
678 clip_child2
->SetClipParent(clip_parent
.get());
680 scoped_ptr
<LayerImpl
> layer_impl_tree_root
=
681 TreeSynchronizer::SynchronizeTrees(
682 layer_tree_root
.get(), nullptr, host_impl
->active_tree());
683 TreeSynchronizer::PushProperties(layer_tree_root
.get(),
684 layer_impl_tree_root
.get());
685 ExpectTreesAreIdentical(layer_tree_root
.get(),
686 layer_impl_tree_root
.get(),
687 host_impl
->active_tree());
689 // Remove the first clip child.
690 clip_child1
->RemoveFromParent();
693 layer_impl_tree_root
=
694 TreeSynchronizer::SynchronizeTrees(layer_tree_root
.get(),
695 layer_impl_tree_root
.Pass(),
696 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 // Add an additional clip child.
704 scoped_refptr
<Layer
> additional_clip_child
= Layer::Create();
705 intervening
->AddChild(additional_clip_child
);
706 additional_clip_child
->SetClipParent(clip_parent
.get());
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 // Remove the nearest clipping ancestor.
718 clip_parent
->RemoveFromParent();
720 layer_impl_tree_root
=
721 TreeSynchronizer::SynchronizeTrees(layer_tree_root
.get(),
722 layer_impl_tree_root
.Pass(),
723 host_impl
->active_tree());
724 TreeSynchronizer::PushProperties(layer_tree_root
.get(),
725 layer_impl_tree_root
.get());
726 ExpectTreesAreIdentical(layer_tree_root
.get(),
727 layer_impl_tree_root
.get(),
728 host_impl
->active_tree());
730 // The clip children should have been unhooked.
731 EXPECT_EQ(2u, intervening
->children().size());
732 EXPECT_FALSE(clip_child2
->clip_parent());
733 EXPECT_FALSE(additional_clip_child
->clip_parent());