[safe browsing] Push missing download BINHASH histograms.
[chromium-blink-merge.git] / cc / trees / tree_synchronizer_unittest.cc
blob827c3662f796dd98645a5bf893b8178e894423dd
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"
7 #include <algorithm>
8 #include <set>
9 #include <vector>
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"
21 namespace cc {
22 namespace {
24 class MockLayerImpl : public LayerImpl {
25 public:
26 static scoped_ptr<MockLayerImpl> Create(LayerTreeImpl* tree_impl,
27 int layer_id) {
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;
39 private:
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 {
48 public:
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)
55 OVERRIDE {
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_);
66 private:
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 {
75 public:
76 static scoped_refptr<LayerAnimationController> Create() {
77 return static_cast<LayerAnimationController*>(
78 new FakeLayerAnimationController);
81 bool SynchronizedAnimations() const { return synchronized_animations_; }
83 private:
84 FakeLayerAnimationController()
85 : LayerAnimationController(1),
86 synchronized_animations_(false) {}
88 virtual ~FakeLayerAnimationController() {}
90 virtual void PushAnimationUpdatesTo(LayerAnimationController* controller_impl)
91 OVERRIDE {
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) {
102 ASSERT_TRUE(layer);
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) {
135 ASSERT_EQ(
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 {
185 public:
186 TreeSynchronizerTest() : host_(FakeLayerTreeHost::Create()) {}
188 protected:
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
223 // layers
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));
249 // Remove one.
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
268 // tracked properly.
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
368 // |
369 // +--- D
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
400 // |
401 // +--- C --- B
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
459 // be deleted.
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;
552 FakeProxy proxy;
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;
584 FakeProxy proxy;
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;
659 FakeProxy proxy;
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();
693 clip_child1 = NULL;
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();
721 clip_parent = NULL;
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());
738 } // namespace
739 } // namespace cc