- add sources.
[platform/framework/web/crosswalk.git] / src / cc / trees / tree_synchronizer_unittest.cc
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.
4
5 #include "cc/trees/tree_synchronizer.h"
6
7 #include <algorithm>
8 #include <set>
9 #include <vector>
10
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"
20
21 namespace cc {
22 namespace {
23
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));
29   }
30   virtual ~MockLayerImpl() {
31     if (layer_impl_destruction_list_)
32       layer_impl_destruction_list_->push_back(id());
33   }
34
35   void SetLayerImplDestructionList(std::vector<int>* list) {
36     layer_impl_destruction_list_ = list;
37   }
38
39  private:
40   MockLayerImpl(LayerTreeImpl* tree_impl, int layer_id)
41       : LayerImpl(tree_impl, layer_id),
42         layer_impl_destruction_list_(NULL) {}
43
44   std::vector<int>* layer_impl_destruction_list_;
45 };
46
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));
52   }
53
54   virtual scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl)
55       OVERRIDE {
56     return MockLayerImpl::Create(tree_impl, layer_id_).PassAs<LayerImpl>();
57   }
58
59   virtual void PushPropertiesTo(LayerImpl* layer_impl) OVERRIDE {
60     Layer::PushPropertiesTo(layer_impl);
61
62     MockLayerImpl* mock_layer_impl = static_cast<MockLayerImpl*>(layer_impl);
63     mock_layer_impl->SetLayerImplDestructionList(layer_impl_destruction_list_);
64   }
65
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() {}
70
71   std::vector<int>* layer_impl_destruction_list_;
72 };
73
74 class FakeLayerAnimationController : public LayerAnimationController {
75  public:
76   static scoped_refptr<LayerAnimationController> Create() {
77     return static_cast<LayerAnimationController*>(
78         new FakeLayerAnimationController);
79   }
80
81   bool SynchronizedAnimations() const { return synchronized_animations_; }
82
83  private:
84   FakeLayerAnimationController()
85       : LayerAnimationController(1),
86         synchronized_animations_(false) {}
87
88   virtual ~FakeLayerAnimationController() {}
89
90   virtual void PushAnimationUpdatesTo(LayerAnimationController* controller_impl)
91       OVERRIDE {
92     LayerAnimationController::PushAnimationUpdatesTo(controller_impl);
93     synchronized_animations_ = true;
94   }
95
96   bool synchronized_animations_;
97 };
98
99 void ExpectTreesAreIdentical(Layer* layer,
100                              LayerImpl* layer_impl,
101                              LayerTreeImpl* tree_impl) {
102   ASSERT_TRUE(layer);
103   ASSERT_TRUE(layer_impl);
104
105   EXPECT_EQ(layer->id(), layer_impl->id());
106   EXPECT_EQ(layer_impl->layer_tree_impl(), tree_impl);
107
108   EXPECT_EQ(layer->non_fast_scrollable_region(),
109             layer_impl->non_fast_scrollable_region());
110
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);
115   }
116
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);
121   }
122
123   const LayerList& layer_children = layer->children();
124   const OwnedLayerImplList& layer_impl_children = layer_impl->children();
125
126   ASSERT_EQ(layer_children.size(), layer_impl_children.size());
127
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();
131
132   ASSERT_EQ(!!layer_scroll_children, !!layer_impl_scroll_children);
133
134   if (layer_scroll_children) {
135     ASSERT_EQ(
136         layer_scroll_children->size(),
137         layer_impl_scroll_children->size());
138   }
139
140   const Layer* layer_scroll_parent = layer->scroll_parent();
141   const LayerImpl* layer_impl_scroll_parent = layer_impl->scroll_parent();
142
143   ASSERT_EQ(!!layer_scroll_parent, !!layer_impl_scroll_parent);
144
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());
151   }
152
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();
156
157   ASSERT_EQ(!!layer_clip_children, !!layer_impl_clip_children);
158
159   if (layer_clip_children)
160     ASSERT_EQ(layer_clip_children->size(), layer_impl_clip_children->size());
161
162   const Layer* layer_clip_parent = layer->clip_parent();
163   const LayerImpl* layer_impl_clip_parent = layer_impl->clip_parent();
164
165   ASSERT_EQ(!!layer_clip_parent, !!layer_impl_clip_parent);
166
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());
176   }
177
178   for (size_t i = 0; i < layer_children.size(); ++i) {
179     ExpectTreesAreIdentical(
180         layer_children[i].get(), layer_impl_children[i], tree_impl);
181   }
182 }
183
184 class TreeSynchronizerTest : public testing::Test {
185  public:
186   TreeSynchronizerTest() : host_(FakeLayerTreeHost::Create()) {}
187
188  protected:
189   scoped_ptr<FakeLayerTreeHost> host_;
190 };
191
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());
199
200   EXPECT_TRUE(!layer_impl_tree_root.get());
201 }
202
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());
209
210   host_->SetRootLayer(layer_tree_root);
211
212   scoped_ptr<LayerImpl> layer_impl_tree_root =
213       TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
214                                          scoped_ptr<LayerImpl>(),
215                                          host_->active_tree());
216
217   ExpectTreesAreIdentical(layer_tree_root.get(),
218                           layer_impl_tree_root.get(),
219                           host_->active_tree());
220 }
221
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;
226
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));
231
232   host_->SetRootLayer(layer_tree_root);
233
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());
241
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());
245
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();
252
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());
262
263   ASSERT_EQ(1u, layer_impl_destruction_list.size());
264   EXPECT_EQ(second_layer_impl_id, layer_impl_destruction_list[0]);
265 }
266
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;
271
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);
279
280   host_->SetRootLayer(layer_tree_root);
281
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());
289
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());
293
294   layer_impl_tree_root->ResetAllChangeTrackingForSubtree();
295
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());
306
307   TreeSynchronizer::PushProperties(layer_tree_root.get(),
308                                    layer_impl_tree_root.get());
309
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());
314 }
315
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());
320
321   host_->SetRootLayer(layer_tree_root);
322
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);
327
328   float first_child_opacity = 0.25f;
329   layer_tree_root->children()[0]->SetOpacity(first_child_opacity);
330
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();
334
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());
342
343   TreeSynchronizer::PushProperties(layer_tree_root.get(),
344                                    layer_impl_tree_root.get());
345
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());
351
352   EXPECT_EQ(first_child_opacity,
353             layer_impl_tree_root->children()[0]->opacity());
354
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());
361 }
362
363 TEST_F(TreeSynchronizerTest, ReuseLayerImplsAfterStructuralChange) {
364   std::vector<int> layer_impl_destruction_list;
365
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));
373
374   scoped_refptr<Layer> layer_a = layer_tree_root->children()[0].get();
375   layer_a->AddChild(MockLayer::Create(&layer_impl_destruction_list));
376
377   scoped_refptr<Layer> layer_b = layer_a->children()[0].get();
378   layer_b->AddChild(MockLayer::Create(&layer_impl_destruction_list));
379
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();
383
384   host_->SetRootLayer(layer_tree_root);
385
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());
393
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());
397
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);
411
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());
421
422   EXPECT_EQ(0u, layer_impl_destruction_list.size());
423 }
424
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;
429
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));
436
437   host_->SetRootLayer(old_layer_tree_root);
438
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();
442
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());
450
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());
454
455   // Remove all children on the Layer side.
456   old_layer_tree_root->RemoveAllChildren();
457
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());
469
470   ASSERT_EQ(3u, layer_impl_destruction_list.size());
471
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());
484 }
485
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());
492
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());
496
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());
500
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());
507
508   host_->SetRootLayer(layer_tree_root);
509
510   scoped_ptr<LayerImpl> layer_impl_tree_root =
511       TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
512                                          scoped_ptr<LayerImpl>(),
513                                          host_->active_tree());
514
515   ExpectTreesAreIdentical(layer_tree_root.get(),
516                           layer_impl_tree_root.get(),
517                           host_->active_tree());
518
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());
528
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());
538
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());
548 }
549
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);
557
558   scoped_refptr<Layer> layer_tree_root = Layer::Create();
559   host_->SetRootLayer(layer_tree_root);
560
561   layer_tree_root->SetLayerAnimationControllerForTest(
562       FakeLayerAnimationController::Create());
563
564   EXPECT_FALSE(static_cast<FakeLayerAnimationController*>(
565       layer_tree_root->layer_animation_controller())->SynchronizedAnimations());
566
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());
577
578   EXPECT_TRUE(static_cast<FakeLayerAnimationController*>(
579       layer_tree_root->layer_animation_controller())->SynchronizedAnimations());
580 }
581
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);
589
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());
595
596   host_->SetRootLayer(layer_tree_root);
597
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);
601
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());
611
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());
623
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());
637
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());
650
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());
655 }
656
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);
664
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);
674
675   host_->SetRootLayer(layer_tree_root);
676
677   // First child is the second and third child's scroll parent.
678   clip_child1->SetClipParent(clip_parent);
679   clip_child2->SetClipParent(clip_parent);
680
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());
690
691   // Remove the first clip child.
692   clip_child1->RemoveFromParent();
693   clip_child1 = NULL;
694
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());
704
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());
718
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());
731
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());
736 }
737
738 }  // namespace
739 }  // namespace cc