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 virtual ~MockLayerImpl() {
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 virtual scoped_ptr
<LayerImpl
> CreateLayerImpl(LayerTreeImpl
* tree_impl
)
59 return MockLayerImpl::Create(tree_impl
, layer_id_
).PassAs
<LayerImpl
>();
62 virtual 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 virtual ~MockLayer() {}
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 virtual ~FakeLayerAnimationController() {}
93 virtual void PushAnimationUpdatesTo(LayerAnimationController
* controller_impl
)
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(static_cast<Layer
*>(NULL
),
206 scoped_ptr
<LayerImpl
>(),
207 host_
->active_tree());
209 EXPECT_TRUE(!layer_impl_tree_root
.get());
212 // Constructs a very simple tree and synchronizes it without trying to reuse any
213 // preexisting layers.
214 TEST_F(TreeSynchronizerTest
, SyncSimpleTreeFromEmpty
) {
215 scoped_refptr
<Layer
> layer_tree_root
= Layer::Create();
216 layer_tree_root
->AddChild(Layer::Create());
217 layer_tree_root
->AddChild(Layer::Create());
219 host_
->SetRootLayer(layer_tree_root
);
221 scoped_ptr
<LayerImpl
> layer_impl_tree_root
=
222 TreeSynchronizer::SynchronizeTrees(layer_tree_root
.get(),
223 scoped_ptr
<LayerImpl
>(),
224 host_
->active_tree());
226 ExpectTreesAreIdentical(layer_tree_root
.get(),
227 layer_impl_tree_root
.get(),
228 host_
->active_tree());
231 // Constructs a very simple tree and synchronizes it attempting to reuse some
233 TEST_F(TreeSynchronizerTest
, SyncSimpleTreeReusingLayers
) {
234 std::vector
<int> layer_impl_destruction_list
;
236 scoped_refptr
<Layer
> layer_tree_root
=
237 MockLayer::Create(&layer_impl_destruction_list
);
238 layer_tree_root
->AddChild(MockLayer::Create(&layer_impl_destruction_list
));
239 layer_tree_root
->AddChild(MockLayer::Create(&layer_impl_destruction_list
));
241 host_
->SetRootLayer(layer_tree_root
);
243 scoped_ptr
<LayerImpl
> layer_impl_tree_root
=
244 TreeSynchronizer::SynchronizeTrees(layer_tree_root
.get(),
245 scoped_ptr
<LayerImpl
>(),
246 host_
->active_tree());
247 ExpectTreesAreIdentical(layer_tree_root
.get(),
248 layer_impl_tree_root
.get(),
249 host_
->active_tree());
251 // We have to push properties to pick up the destruction list pointer.
252 TreeSynchronizer::PushProperties(layer_tree_root
.get(),
253 layer_impl_tree_root
.get());
255 // Add a new layer to the Layer side
256 layer_tree_root
->children()[0]->
257 AddChild(MockLayer::Create(&layer_impl_destruction_list
));
259 layer_tree_root
->children()[1]->RemoveFromParent();
260 int second_layer_impl_id
= layer_impl_tree_root
->children()[1]->id();
262 // Synchronize again. After the sync the trees should be equivalent and we
263 // should have created and destroyed one LayerImpl.
264 layer_impl_tree_root
=
265 TreeSynchronizer::SynchronizeTrees(layer_tree_root
.get(),
266 layer_impl_tree_root
.Pass(),
267 host_
->active_tree());
268 ExpectTreesAreIdentical(layer_tree_root
.get(),
269 layer_impl_tree_root
.get(),
270 host_
->active_tree());
272 ASSERT_EQ(1u, layer_impl_destruction_list
.size());
273 EXPECT_EQ(second_layer_impl_id
, layer_impl_destruction_list
[0]);
276 // Constructs a very simple tree and checks that a stacking-order change is
278 TEST_F(TreeSynchronizerTest
, SyncSimpleTreeAndTrackStackingOrderChange
) {
279 std::vector
<int> layer_impl_destruction_list
;
281 // Set up the tree and sync once. child2 needs to be synced here, too, even
282 // though we remove it to set up the intended scenario.
283 scoped_refptr
<Layer
> layer_tree_root
=
284 MockLayer::Create(&layer_impl_destruction_list
);
285 scoped_refptr
<Layer
> child2
= MockLayer::Create(&layer_impl_destruction_list
);
286 layer_tree_root
->AddChild(MockLayer::Create(&layer_impl_destruction_list
));
287 layer_tree_root
->AddChild(child2
);
289 host_
->SetRootLayer(layer_tree_root
);
291 scoped_ptr
<LayerImpl
> layer_impl_tree_root
=
292 TreeSynchronizer::SynchronizeTrees(layer_tree_root
.get(),
293 scoped_ptr
<LayerImpl
>(),
294 host_
->active_tree());
295 ExpectTreesAreIdentical(layer_tree_root
.get(),
296 layer_impl_tree_root
.get(),
297 host_
->active_tree());
299 // We have to push properties to pick up the destruction list pointer.
300 TreeSynchronizer::PushProperties(layer_tree_root
.get(),
301 layer_impl_tree_root
.get());
303 layer_impl_tree_root
->ResetAllChangeTrackingForSubtree();
305 // re-insert the layer and sync again.
306 child2
->RemoveFromParent();
307 layer_tree_root
->AddChild(child2
);
308 layer_impl_tree_root
=
309 TreeSynchronizer::SynchronizeTrees(layer_tree_root
.get(),
310 layer_impl_tree_root
.Pass(),
311 host_
->active_tree());
312 ExpectTreesAreIdentical(layer_tree_root
.get(),
313 layer_impl_tree_root
.get(),
314 host_
->active_tree());
316 TreeSynchronizer::PushProperties(layer_tree_root
.get(),
317 layer_impl_tree_root
.get());
319 // Check that the impl thread properly tracked the change.
320 EXPECT_FALSE(layer_impl_tree_root
->LayerPropertyChanged());
321 EXPECT_FALSE(layer_impl_tree_root
->children()[0]->LayerPropertyChanged());
322 EXPECT_TRUE(layer_impl_tree_root
->children()[1]->LayerPropertyChanged());
325 TEST_F(TreeSynchronizerTest
, SyncSimpleTreeAndProperties
) {
326 scoped_refptr
<Layer
> layer_tree_root
= Layer::Create();
327 layer_tree_root
->AddChild(Layer::Create());
328 layer_tree_root
->AddChild(Layer::Create());
330 host_
->SetRootLayer(layer_tree_root
);
332 // Pick some random properties to set. The values are not important, we're
333 // just testing that at least some properties are making it through.
334 gfx::PointF root_position
= gfx::PointF(2.3f
, 7.4f
);
335 layer_tree_root
->SetPosition(root_position
);
337 float first_child_opacity
= 0.25f
;
338 layer_tree_root
->children()[0]->SetOpacity(first_child_opacity
);
340 gfx::Size second_child_bounds
= gfx::Size(25, 53);
341 layer_tree_root
->children()[1]->SetBounds(second_child_bounds
);
342 layer_tree_root
->children()[1]->SavePaintProperties();
344 scoped_ptr
<LayerImpl
> layer_impl_tree_root
=
345 TreeSynchronizer::SynchronizeTrees(layer_tree_root
.get(),
346 scoped_ptr
<LayerImpl
>(),
347 host_
->active_tree());
348 ExpectTreesAreIdentical(layer_tree_root
.get(),
349 layer_impl_tree_root
.get(),
350 host_
->active_tree());
352 TreeSynchronizer::PushProperties(layer_tree_root
.get(),
353 layer_impl_tree_root
.get());
355 // Check that the property values we set on the Layer tree are reflected in
356 // the LayerImpl tree.
357 gfx::PointF root_layer_impl_position
= layer_impl_tree_root
->position();
358 EXPECT_EQ(root_position
.x(), root_layer_impl_position
.x());
359 EXPECT_EQ(root_position
.y(), root_layer_impl_position
.y());
361 EXPECT_EQ(first_child_opacity
,
362 layer_impl_tree_root
->children()[0]->opacity());
364 gfx::Size second_layer_impl_child_bounds
=
365 layer_impl_tree_root
->children()[1]->bounds();
366 EXPECT_EQ(second_child_bounds
.width(),
367 second_layer_impl_child_bounds
.width());
368 EXPECT_EQ(second_child_bounds
.height(),
369 second_layer_impl_child_bounds
.height());
372 TEST_F(TreeSynchronizerTest
, ReuseLayerImplsAfterStructuralChange
) {
373 std::vector
<int> layer_impl_destruction_list
;
375 // Set up a tree with this sort of structure:
376 // root --- A --- B ---+--- C
379 scoped_refptr
<Layer
> layer_tree_root
=
380 MockLayer::Create(&layer_impl_destruction_list
);
381 layer_tree_root
->AddChild(MockLayer::Create(&layer_impl_destruction_list
));
383 scoped_refptr
<Layer
> layer_a
= layer_tree_root
->children()[0].get();
384 layer_a
->AddChild(MockLayer::Create(&layer_impl_destruction_list
));
386 scoped_refptr
<Layer
> layer_b
= layer_a
->children()[0].get();
387 layer_b
->AddChild(MockLayer::Create(&layer_impl_destruction_list
));
389 scoped_refptr
<Layer
> layer_c
= layer_b
->children()[0].get();
390 layer_b
->AddChild(MockLayer::Create(&layer_impl_destruction_list
));
391 scoped_refptr
<Layer
> layer_d
= layer_b
->children()[1].get();
393 host_
->SetRootLayer(layer_tree_root
);
395 scoped_ptr
<LayerImpl
> layer_impl_tree_root
=
396 TreeSynchronizer::SynchronizeTrees(layer_tree_root
.get(),
397 scoped_ptr
<LayerImpl
>(),
398 host_
->active_tree());
399 ExpectTreesAreIdentical(layer_tree_root
.get(),
400 layer_impl_tree_root
.get(),
401 host_
->active_tree());
403 // We have to push properties to pick up the destruction list pointer.
404 TreeSynchronizer::PushProperties(layer_tree_root
.get(),
405 layer_impl_tree_root
.get());
407 // Now restructure the tree to look like this:
408 // root --- D ---+--- A
411 layer_tree_root
->RemoveAllChildren();
412 layer_d
->RemoveAllChildren();
413 layer_tree_root
->AddChild(layer_d
);
414 layer_a
->RemoveAllChildren();
415 layer_d
->AddChild(layer_a
);
416 layer_c
->RemoveAllChildren();
417 layer_d
->AddChild(layer_c
);
418 layer_b
->RemoveAllChildren();
419 layer_c
->AddChild(layer_b
);
421 // After another synchronize our trees should match and we should not have
422 // destroyed any LayerImpls
423 layer_impl_tree_root
=
424 TreeSynchronizer::SynchronizeTrees(layer_tree_root
.get(),
425 layer_impl_tree_root
.Pass(),
426 host_
->active_tree());
427 ExpectTreesAreIdentical(layer_tree_root
.get(),
428 layer_impl_tree_root
.get(),
429 host_
->active_tree());
431 EXPECT_EQ(0u, layer_impl_destruction_list
.size());
434 // Constructs a very simple tree, synchronizes it, then synchronizes to a
435 // totally new tree. All layers from the old tree should be deleted.
436 TEST_F(TreeSynchronizerTest
, SyncSimpleTreeThenDestroy
) {
437 std::vector
<int> layer_impl_destruction_list
;
439 scoped_refptr
<Layer
> old_layer_tree_root
=
440 MockLayer::Create(&layer_impl_destruction_list
);
441 old_layer_tree_root
->AddChild(
442 MockLayer::Create(&layer_impl_destruction_list
));
443 old_layer_tree_root
->AddChild(
444 MockLayer::Create(&layer_impl_destruction_list
));
446 host_
->SetRootLayer(old_layer_tree_root
);
448 int old_tree_root_layer_id
= old_layer_tree_root
->id();
449 int old_tree_first_child_layer_id
= old_layer_tree_root
->children()[0]->id();
450 int old_tree_second_child_layer_id
= old_layer_tree_root
->children()[1]->id();
452 scoped_ptr
<LayerImpl
> layer_impl_tree_root
=
453 TreeSynchronizer::SynchronizeTrees(old_layer_tree_root
.get(),
454 scoped_ptr
<LayerImpl
>(),
455 host_
->active_tree());
456 ExpectTreesAreIdentical(old_layer_tree_root
.get(),
457 layer_impl_tree_root
.get(),
458 host_
->active_tree());
460 // We have to push properties to pick up the destruction list pointer.
461 TreeSynchronizer::PushProperties(old_layer_tree_root
.get(),
462 layer_impl_tree_root
.get());
464 // Remove all children on the Layer side.
465 old_layer_tree_root
->RemoveAllChildren();
467 // Synchronize again. After the sync all LayerImpls from the old tree should
469 scoped_refptr
<Layer
> new_layer_tree_root
= Layer::Create();
470 host_
->SetRootLayer(new_layer_tree_root
);
471 layer_impl_tree_root
=
472 TreeSynchronizer::SynchronizeTrees(new_layer_tree_root
.get(),
473 layer_impl_tree_root
.Pass(),
474 host_
->active_tree());
475 ExpectTreesAreIdentical(new_layer_tree_root
.get(),
476 layer_impl_tree_root
.get(),
477 host_
->active_tree());
479 ASSERT_EQ(3u, layer_impl_destruction_list
.size());
481 EXPECT_TRUE(std::find(layer_impl_destruction_list
.begin(),
482 layer_impl_destruction_list
.end(),
483 old_tree_root_layer_id
) !=
484 layer_impl_destruction_list
.end());
485 EXPECT_TRUE(std::find(layer_impl_destruction_list
.begin(),
486 layer_impl_destruction_list
.end(),
487 old_tree_first_child_layer_id
) !=
488 layer_impl_destruction_list
.end());
489 EXPECT_TRUE(std::find(layer_impl_destruction_list
.begin(),
490 layer_impl_destruction_list
.end(),
491 old_tree_second_child_layer_id
) !=
492 layer_impl_destruction_list
.end());
495 // Constructs+syncs a tree with mask, replica, and replica mask layers.
496 TEST_F(TreeSynchronizerTest
, SyncMaskReplicaAndReplicaMaskLayers
) {
497 scoped_refptr
<Layer
> layer_tree_root
= Layer::Create();
498 layer_tree_root
->AddChild(Layer::Create());
499 layer_tree_root
->AddChild(Layer::Create());
500 layer_tree_root
->AddChild(Layer::Create());
502 // First child gets a mask layer.
503 scoped_refptr
<Layer
> mask_layer
= Layer::Create();
504 layer_tree_root
->children()[0]->SetMaskLayer(mask_layer
.get());
506 // Second child gets a replica layer.
507 scoped_refptr
<Layer
> replica_layer
= Layer::Create();
508 layer_tree_root
->children()[1]->SetReplicaLayer(replica_layer
.get());
510 // Third child gets a replica layer with a mask layer.
511 scoped_refptr
<Layer
> replica_layer_with_mask
= Layer::Create();
512 scoped_refptr
<Layer
> replica_mask_layer
= Layer::Create();
513 replica_layer_with_mask
->SetMaskLayer(replica_mask_layer
.get());
514 layer_tree_root
->children()[2]->
515 SetReplicaLayer(replica_layer_with_mask
.get());
517 host_
->SetRootLayer(layer_tree_root
);
519 scoped_ptr
<LayerImpl
> layer_impl_tree_root
=
520 TreeSynchronizer::SynchronizeTrees(layer_tree_root
.get(),
521 scoped_ptr
<LayerImpl
>(),
522 host_
->active_tree());
524 ExpectTreesAreIdentical(layer_tree_root
.get(),
525 layer_impl_tree_root
.get(),
526 host_
->active_tree());
528 // Remove the mask layer.
529 layer_tree_root
->children()[0]->SetMaskLayer(NULL
);
530 layer_impl_tree_root
=
531 TreeSynchronizer::SynchronizeTrees(layer_tree_root
.get(),
532 layer_impl_tree_root
.Pass(),
533 host_
->active_tree());
534 ExpectTreesAreIdentical(layer_tree_root
.get(),
535 layer_impl_tree_root
.get(),
536 host_
->active_tree());
538 // Remove the replica layer.
539 layer_tree_root
->children()[1]->SetReplicaLayer(NULL
);
540 layer_impl_tree_root
=
541 TreeSynchronizer::SynchronizeTrees(layer_tree_root
.get(),
542 layer_impl_tree_root
.Pass(),
543 host_
->active_tree());
544 ExpectTreesAreIdentical(layer_tree_root
.get(),
545 layer_impl_tree_root
.get(),
546 host_
->active_tree());
548 // Remove the replica mask.
549 replica_layer_with_mask
->SetMaskLayer(NULL
);
550 layer_impl_tree_root
=
551 TreeSynchronizer::SynchronizeTrees(layer_tree_root
.get(),
552 layer_impl_tree_root
.Pass(),
553 host_
->active_tree());
554 ExpectTreesAreIdentical(layer_tree_root
.get(),
555 layer_impl_tree_root
.get(),
556 host_
->active_tree());
559 TEST_F(TreeSynchronizerTest
, SynchronizeAnimations
) {
560 LayerTreeSettings settings
;
562 DebugScopedSetImplThread
impl(&proxy
);
563 FakeRenderingStatsInstrumentation stats_instrumentation
;
564 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
565 new TestSharedBitmapManager());
566 scoped_ptr
<LayerTreeHostImpl
> host_impl
=
567 LayerTreeHostImpl::Create(settings
,
570 &stats_instrumentation
,
571 shared_bitmap_manager
.get(),
574 scoped_refptr
<Layer
> layer_tree_root
= Layer::Create();
575 host_
->SetRootLayer(layer_tree_root
);
577 layer_tree_root
->SetLayerAnimationControllerForTest(
578 FakeLayerAnimationController::Create());
580 EXPECT_FALSE(static_cast<FakeLayerAnimationController
*>(
581 layer_tree_root
->layer_animation_controller())->SynchronizedAnimations());
583 scoped_ptr
<LayerImpl
> layer_impl_tree_root
=
584 TreeSynchronizer::SynchronizeTrees(layer_tree_root
.get(),
585 scoped_ptr
<LayerImpl
>(),
586 host_
->active_tree());
587 TreeSynchronizer::PushProperties(layer_tree_root
.get(),
588 layer_impl_tree_root
.get());
589 layer_impl_tree_root
=
590 TreeSynchronizer::SynchronizeTrees(layer_tree_root
.get(),
591 layer_impl_tree_root
.Pass(),
592 host_
->active_tree());
594 EXPECT_TRUE(static_cast<FakeLayerAnimationController
*>(
595 layer_tree_root
->layer_animation_controller())->SynchronizedAnimations());
598 TEST_F(TreeSynchronizerTest
, SynchronizeScrollParent
) {
599 LayerTreeSettings settings
;
601 DebugScopedSetImplThread
impl(&proxy
);
602 FakeRenderingStatsInstrumentation stats_instrumentation
;
603 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
604 new TestSharedBitmapManager());
605 scoped_ptr
<LayerTreeHostImpl
> host_impl
=
606 LayerTreeHostImpl::Create(settings
,
609 &stats_instrumentation
,
610 shared_bitmap_manager
.get(),
613 scoped_refptr
<Layer
> layer_tree_root
= Layer::Create();
614 scoped_refptr
<Layer
> scroll_parent
= Layer::Create();
615 layer_tree_root
->AddChild(scroll_parent
);
616 layer_tree_root
->AddChild(Layer::Create());
617 layer_tree_root
->AddChild(Layer::Create());
619 host_
->SetRootLayer(layer_tree_root
);
621 // First child is the second and third child's scroll parent.
622 layer_tree_root
->children()[1]->SetScrollParent(scroll_parent
.get());
623 layer_tree_root
->children()[2]->SetScrollParent(scroll_parent
.get());
625 scoped_ptr
<LayerImpl
> layer_impl_tree_root
=
626 TreeSynchronizer::SynchronizeTrees(layer_tree_root
.get(),
627 scoped_ptr
<LayerImpl
>(),
628 host_impl
->active_tree());
629 TreeSynchronizer::PushProperties(layer_tree_root
.get(),
630 layer_impl_tree_root
.get());
632 SCOPED_TRACE("case one");
633 ExpectTreesAreIdentical(layer_tree_root
.get(),
634 layer_impl_tree_root
.get(),
635 host_impl
->active_tree());
638 // Remove the first scroll child.
639 layer_tree_root
->children()[1]->RemoveFromParent();
640 layer_impl_tree_root
=
641 TreeSynchronizer::SynchronizeTrees(layer_tree_root
.get(),
642 layer_impl_tree_root
.Pass(),
643 host_impl
->active_tree());
644 TreeSynchronizer::PushProperties(layer_tree_root
.get(),
645 layer_impl_tree_root
.get());
647 SCOPED_TRACE("case two");
648 ExpectTreesAreIdentical(layer_tree_root
.get(),
649 layer_impl_tree_root
.get(),
650 host_impl
->active_tree());
653 // Add an additional scroll layer.
654 scoped_refptr
<Layer
> additional_scroll_child
= Layer::Create();
655 layer_tree_root
->AddChild(additional_scroll_child
);
656 additional_scroll_child
->SetScrollParent(scroll_parent
.get());
657 layer_impl_tree_root
=
658 TreeSynchronizer::SynchronizeTrees(layer_tree_root
.get(),
659 layer_impl_tree_root
.Pass(),
660 host_impl
->active_tree());
661 TreeSynchronizer::PushProperties(layer_tree_root
.get(),
662 layer_impl_tree_root
.get());
664 SCOPED_TRACE("case three");
665 ExpectTreesAreIdentical(layer_tree_root
.get(),
666 layer_impl_tree_root
.get(),
667 host_impl
->active_tree());
671 TEST_F(TreeSynchronizerTest
, SynchronizeClipParent
) {
672 LayerTreeSettings settings
;
674 DebugScopedSetImplThread
impl(&proxy
);
675 FakeRenderingStatsInstrumentation stats_instrumentation
;
676 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
677 new TestSharedBitmapManager());
678 scoped_ptr
<LayerTreeHostImpl
> host_impl
=
679 LayerTreeHostImpl::Create(settings
,
682 &stats_instrumentation
,
683 shared_bitmap_manager
.get(),
686 scoped_refptr
<Layer
> layer_tree_root
= Layer::Create();
687 scoped_refptr
<Layer
> clip_parent
= Layer::Create();
688 scoped_refptr
<Layer
> intervening
= Layer::Create();
689 scoped_refptr
<Layer
> clip_child1
= Layer::Create();
690 scoped_refptr
<Layer
> clip_child2
= Layer::Create();
691 layer_tree_root
->AddChild(clip_parent
);
692 clip_parent
->AddChild(intervening
);
693 intervening
->AddChild(clip_child1
);
694 intervening
->AddChild(clip_child2
);
696 host_
->SetRootLayer(layer_tree_root
);
698 // First child is the second and third child's scroll parent.
699 clip_child1
->SetClipParent(clip_parent
.get());
700 clip_child2
->SetClipParent(clip_parent
.get());
702 scoped_ptr
<LayerImpl
> layer_impl_tree_root
=
703 TreeSynchronizer::SynchronizeTrees(layer_tree_root
.get(),
704 scoped_ptr
<LayerImpl
>(),
705 host_impl
->active_tree());
706 TreeSynchronizer::PushProperties(layer_tree_root
.get(),
707 layer_impl_tree_root
.get());
708 ExpectTreesAreIdentical(layer_tree_root
.get(),
709 layer_impl_tree_root
.get(),
710 host_impl
->active_tree());
712 // Remove the first clip child.
713 clip_child1
->RemoveFromParent();
716 layer_impl_tree_root
=
717 TreeSynchronizer::SynchronizeTrees(layer_tree_root
.get(),
718 layer_impl_tree_root
.Pass(),
719 host_impl
->active_tree());
720 TreeSynchronizer::PushProperties(layer_tree_root
.get(),
721 layer_impl_tree_root
.get());
722 ExpectTreesAreIdentical(layer_tree_root
.get(),
723 layer_impl_tree_root
.get(),
724 host_impl
->active_tree());
726 // Add an additional clip child.
727 scoped_refptr
<Layer
> additional_clip_child
= Layer::Create();
728 intervening
->AddChild(additional_clip_child
);
729 additional_clip_child
->SetClipParent(clip_parent
.get());
730 layer_impl_tree_root
=
731 TreeSynchronizer::SynchronizeTrees(layer_tree_root
.get(),
732 layer_impl_tree_root
.Pass(),
733 host_impl
->active_tree());
734 TreeSynchronizer::PushProperties(layer_tree_root
.get(),
735 layer_impl_tree_root
.get());
736 ExpectTreesAreIdentical(layer_tree_root
.get(),
737 layer_impl_tree_root
.get(),
738 host_impl
->active_tree());
740 // Remove the nearest clipping ancestor.
741 clip_parent
->RemoveFromParent();
743 layer_impl_tree_root
=
744 TreeSynchronizer::SynchronizeTrees(layer_tree_root
.get(),
745 layer_impl_tree_root
.Pass(),
746 host_impl
->active_tree());
747 TreeSynchronizer::PushProperties(layer_tree_root
.get(),
748 layer_impl_tree_root
.get());
749 ExpectTreesAreIdentical(layer_tree_root
.get(),
750 layer_impl_tree_root
.get(),
751 host_impl
->active_tree());
753 // The clip children should have been unhooked.
754 EXPECT_EQ(2u, intervening
->children().size());
755 EXPECT_FALSE(clip_child2
->clip_parent());
756 EXPECT_FALSE(additional_clip_child
->clip_parent());