Update To 11.40.268.0
[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 "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"
24
25 namespace cc {
26 namespace {
27
28 class MockLayerImpl : public LayerImpl {
29  public:
30   static scoped_ptr<MockLayerImpl> Create(LayerTreeImpl* tree_impl,
31                                           int layer_id) {
32     return make_scoped_ptr(new MockLayerImpl(tree_impl, layer_id));
33   }
34   ~MockLayerImpl() override {
35     if (layer_impl_destruction_list_)
36       layer_impl_destruction_list_->push_back(id());
37   }
38
39   void SetLayerImplDestructionList(std::vector<int>* list) {
40     layer_impl_destruction_list_ = list;
41   }
42
43  private:
44   MockLayerImpl(LayerTreeImpl* tree_impl, int layer_id)
45       : LayerImpl(tree_impl, layer_id),
46         layer_impl_destruction_list_(NULL) {}
47
48   std::vector<int>* layer_impl_destruction_list_;
49 };
50
51 class MockLayer : public Layer {
52  public:
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));
56   }
57
58   scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override {
59     return MockLayerImpl::Create(tree_impl, layer_id_);
60   }
61
62   void PushPropertiesTo(LayerImpl* layer_impl) override {
63     Layer::PushPropertiesTo(layer_impl);
64
65     MockLayerImpl* mock_layer_impl = static_cast<MockLayerImpl*>(layer_impl);
66     mock_layer_impl->SetLayerImplDestructionList(layer_impl_destruction_list_);
67   }
68
69  private:
70   explicit MockLayer(std::vector<int>* layer_impl_destruction_list)
71       : Layer(), layer_impl_destruction_list_(layer_impl_destruction_list) {}
72   ~MockLayer() override {}
73
74   std::vector<int>* layer_impl_destruction_list_;
75 };
76
77 class FakeLayerAnimationController : public LayerAnimationController {
78  public:
79   static scoped_refptr<LayerAnimationController> Create() {
80     return static_cast<LayerAnimationController*>(
81         new FakeLayerAnimationController);
82   }
83
84   bool SynchronizedAnimations() const { return synchronized_animations_; }
85
86  private:
87   FakeLayerAnimationController()
88       : LayerAnimationController(1),
89         synchronized_animations_(false) {}
90
91   ~FakeLayerAnimationController() override {}
92
93   void PushAnimationUpdatesTo(
94       LayerAnimationController* controller_impl) override {
95     LayerAnimationController::PushAnimationUpdatesTo(controller_impl);
96     synchronized_animations_ = true;
97   }
98
99   bool synchronized_animations_;
100 };
101
102 void ExpectTreesAreIdentical(Layer* layer,
103                              LayerImpl* layer_impl,
104                              LayerTreeImpl* tree_impl) {
105   ASSERT_TRUE(layer);
106   ASSERT_TRUE(layer_impl);
107
108   EXPECT_EQ(layer->id(), layer_impl->id());
109   EXPECT_EQ(layer_impl->layer_tree_impl(), tree_impl);
110
111   EXPECT_EQ(layer->non_fast_scrollable_region(),
112             layer_impl->non_fast_scrollable_region());
113
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);
119   }
120
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);
126   }
127
128   const LayerList& layer_children = layer->children();
129   const OwnedLayerImplList& layer_impl_children = layer_impl->children();
130
131   ASSERT_EQ(layer_children.size(), layer_impl_children.size());
132
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();
136
137   ASSERT_EQ(!!layer_scroll_children, !!layer_impl_scroll_children);
138
139   if (layer_scroll_children) {
140     ASSERT_EQ(
141         layer_scroll_children->size(),
142         layer_impl_scroll_children->size());
143   }
144
145   const Layer* layer_scroll_parent = layer->scroll_parent();
146   const LayerImpl* layer_impl_scroll_parent = layer_impl->scroll_parent();
147
148   ASSERT_EQ(!!layer_scroll_parent, !!layer_impl_scroll_parent);
149
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());
156   }
157
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();
161
162   ASSERT_EQ(!!layer_clip_children, !!layer_impl_clip_children);
163
164   if (layer_clip_children)
165     ASSERT_EQ(layer_clip_children->size(), layer_impl_clip_children->size());
166
167   const Layer* layer_clip_parent = layer->clip_parent();
168   const LayerImpl* layer_impl_clip_parent = layer_impl->clip_parent();
169
170   ASSERT_EQ(!!layer_clip_parent, !!layer_impl_clip_parent);
171
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());
181   }
182
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);
187   }
188 }
189
190 class TreeSynchronizerTest : public testing::Test {
191  public:
192   TreeSynchronizerTest()
193       : client_(FakeLayerTreeHostClient::DIRECT_3D),
194         host_(FakeLayerTreeHost::Create(&client_)) {}
195
196  protected:
197   FakeLayerTreeHostClient client_;
198   scoped_ptr<FakeLayerTreeHost> host_;
199 };
200
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());
207
208   EXPECT_TRUE(!layer_impl_tree_root.get());
209 }
210
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());
217
218   host_->SetRootLayer(layer_tree_root);
219
220   scoped_ptr<LayerImpl> layer_impl_tree_root =
221       TreeSynchronizer::SynchronizeTrees(
222           layer_tree_root.get(), nullptr, host_->active_tree());
223
224   ExpectTreesAreIdentical(layer_tree_root.get(),
225                           layer_impl_tree_root.get(),
226                           host_->active_tree());
227 }
228
229 // Constructs a very simple tree and synchronizes it attempting to reuse some
230 // layers
231 TEST_F(TreeSynchronizerTest, SyncSimpleTreeReusingLayers) {
232   std::vector<int> layer_impl_destruction_list;
233
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));
238
239   host_->SetRootLayer(layer_tree_root);
240
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());
247
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());
251
252   // Add a new layer to the Layer side
253   layer_tree_root->children()[0]->
254       AddChild(MockLayer::Create(&layer_impl_destruction_list));
255   // Remove one.
256   layer_tree_root->children()[1]->RemoveFromParent();
257   int second_layer_impl_id = layer_impl_tree_root->children()[1]->id();
258
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());
268
269   ASSERT_EQ(1u, layer_impl_destruction_list.size());
270   EXPECT_EQ(second_layer_impl_id, layer_impl_destruction_list[0]);
271 }
272
273 // Constructs a very simple tree and checks that a stacking-order change is
274 // tracked properly.
275 TEST_F(TreeSynchronizerTest, SyncSimpleTreeAndTrackStackingOrderChange) {
276   std::vector<int> layer_impl_destruction_list;
277
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);
285
286   host_->SetRootLayer(layer_tree_root);
287
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());
294
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());
298
299   layer_impl_tree_root->ResetAllChangeTrackingForSubtree();
300
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());
311
312   TreeSynchronizer::PushProperties(layer_tree_root.get(),
313                                    layer_impl_tree_root.get());
314
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());
319 }
320
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());
325
326   host_->SetRootLayer(layer_tree_root);
327
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);
332
333   float first_child_opacity = 0.25f;
334   layer_tree_root->children()[0]->SetOpacity(first_child_opacity);
335
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();
339
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());
346
347   TreeSynchronizer::PushProperties(layer_tree_root.get(),
348                                    layer_impl_tree_root.get());
349
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());
355
356   EXPECT_EQ(first_child_opacity,
357             layer_impl_tree_root->children()[0]->opacity());
358
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());
365 }
366
367 TEST_F(TreeSynchronizerTest, ReuseLayerImplsAfterStructuralChange) {
368   std::vector<int> layer_impl_destruction_list;
369
370   // Set up a tree with this sort of structure:
371   // root --- A --- B ---+--- C
372   //                     |
373   //                     +--- D
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));
377
378   scoped_refptr<Layer> layer_a = layer_tree_root->children()[0].get();
379   layer_a->AddChild(MockLayer::Create(&layer_impl_destruction_list));
380
381   scoped_refptr<Layer> layer_b = layer_a->children()[0].get();
382   layer_b->AddChild(MockLayer::Create(&layer_impl_destruction_list));
383
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();
387
388   host_->SetRootLayer(layer_tree_root);
389
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());
396
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());
400
401   // Now restructure the tree to look like this:
402   // root --- D ---+--- A
403   //               |
404   //               +--- C --- B
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);
414
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());
424
425   EXPECT_EQ(0u, layer_impl_destruction_list.size());
426 }
427
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;
432
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));
439
440   host_->SetRootLayer(old_layer_tree_root);
441
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();
445
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());
452
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());
456
457   // Remove all children on the Layer side.
458   old_layer_tree_root->RemoveAllChildren();
459
460   // Synchronize again. After the sync all LayerImpls from the old tree should
461   // be deleted.
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());
471
472   ASSERT_EQ(3u, layer_impl_destruction_list.size());
473
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());
486 }
487
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());
494
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());
498
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());
502
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());
509
510   host_->SetRootLayer(layer_tree_root);
511
512   scoped_ptr<LayerImpl> layer_impl_tree_root =
513       TreeSynchronizer::SynchronizeTrees(
514           layer_tree_root.get(), nullptr, host_->active_tree());
515
516   ExpectTreesAreIdentical(layer_tree_root.get(),
517                           layer_impl_tree_root.get(),
518                           host_->active_tree());
519
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());
529
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());
539
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());
549 }
550
551 TEST_F(TreeSynchronizerTest, SynchronizeAnimations) {
552   LayerTreeSettings settings;
553   FakeProxy proxy;
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,
560                                 NULL,
561                                 &proxy,
562                                 &stats_instrumentation,
563                                 shared_bitmap_manager.get(),
564                                 NULL,
565                                 0);
566
567   scoped_refptr<Layer> layer_tree_root = Layer::Create();
568   host_->SetRootLayer(layer_tree_root);
569
570   layer_tree_root->SetLayerAnimationControllerForTest(
571       FakeLayerAnimationController::Create());
572
573   EXPECT_FALSE(static_cast<FakeLayerAnimationController*>(
574       layer_tree_root->layer_animation_controller())->SynchronizedAnimations());
575
576   scoped_ptr<LayerImpl> layer_impl_tree_root =
577       TreeSynchronizer::SynchronizeTrees(
578           layer_tree_root.get(), nullptr, host_->active_tree());
579   TreeSynchronizer::PushProperties(layer_tree_root.get(),
580                                    layer_impl_tree_root.get());
581   layer_impl_tree_root =
582       TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
583                                          layer_impl_tree_root.Pass(),
584                                          host_->active_tree());
585
586   EXPECT_TRUE(static_cast<FakeLayerAnimationController*>(
587       layer_tree_root->layer_animation_controller())->SynchronizedAnimations());
588 }
589
590 TEST_F(TreeSynchronizerTest, SynchronizeScrollParent) {
591   LayerTreeSettings settings;
592   FakeProxy proxy;
593   DebugScopedSetImplThread impl(&proxy);
594   FakeRenderingStatsInstrumentation stats_instrumentation;
595   scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
596       new TestSharedBitmapManager());
597   scoped_ptr<LayerTreeHostImpl> host_impl =
598       LayerTreeHostImpl::Create(settings,
599                                 NULL,
600                                 &proxy,
601                                 &stats_instrumentation,
602                                 shared_bitmap_manager.get(),
603                                 NULL,
604                                 0);
605
606   scoped_refptr<Layer> layer_tree_root = Layer::Create();
607   scoped_refptr<Layer> scroll_parent = Layer::Create();
608   layer_tree_root->AddChild(scroll_parent);
609   layer_tree_root->AddChild(Layer::Create());
610   layer_tree_root->AddChild(Layer::Create());
611
612   host_->SetRootLayer(layer_tree_root);
613
614   // First child is the second and third child's scroll parent.
615   layer_tree_root->children()[1]->SetScrollParent(scroll_parent.get());
616   layer_tree_root->children()[2]->SetScrollParent(scroll_parent.get());
617
618   scoped_ptr<LayerImpl> layer_impl_tree_root =
619       TreeSynchronizer::SynchronizeTrees(
620           layer_tree_root.get(), nullptr, host_impl->active_tree());
621   TreeSynchronizer::PushProperties(layer_tree_root.get(),
622                                    layer_impl_tree_root.get());
623   {
624     SCOPED_TRACE("case one");
625     ExpectTreesAreIdentical(layer_tree_root.get(),
626                             layer_impl_tree_root.get(),
627                             host_impl->active_tree());
628   }
629
630   // Remove the first scroll child.
631   layer_tree_root->children()[1]->RemoveFromParent();
632   layer_impl_tree_root =
633       TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
634                                          layer_impl_tree_root.Pass(),
635                                          host_impl->active_tree());
636   TreeSynchronizer::PushProperties(layer_tree_root.get(),
637                                    layer_impl_tree_root.get());
638   {
639     SCOPED_TRACE("case two");
640     ExpectTreesAreIdentical(layer_tree_root.get(),
641                             layer_impl_tree_root.get(),
642                             host_impl->active_tree());
643   }
644
645   // Add an additional scroll layer.
646   scoped_refptr<Layer> additional_scroll_child = Layer::Create();
647   layer_tree_root->AddChild(additional_scroll_child);
648   additional_scroll_child->SetScrollParent(scroll_parent.get());
649   layer_impl_tree_root =
650       TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
651                                          layer_impl_tree_root.Pass(),
652                                          host_impl->active_tree());
653   TreeSynchronizer::PushProperties(layer_tree_root.get(),
654                                    layer_impl_tree_root.get());
655   {
656     SCOPED_TRACE("case three");
657     ExpectTreesAreIdentical(layer_tree_root.get(),
658                             layer_impl_tree_root.get(),
659                             host_impl->active_tree());
660   }
661 }
662
663 TEST_F(TreeSynchronizerTest, SynchronizeClipParent) {
664   LayerTreeSettings settings;
665   FakeProxy proxy;
666   DebugScopedSetImplThread impl(&proxy);
667   FakeRenderingStatsInstrumentation stats_instrumentation;
668   scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
669       new TestSharedBitmapManager());
670   scoped_ptr<LayerTreeHostImpl> host_impl =
671       LayerTreeHostImpl::Create(settings,
672                                 NULL,
673                                 &proxy,
674                                 &stats_instrumentation,
675                                 shared_bitmap_manager.get(),
676                                 NULL,
677                                 0);
678
679   scoped_refptr<Layer> layer_tree_root = Layer::Create();
680   scoped_refptr<Layer> clip_parent = Layer::Create();
681   scoped_refptr<Layer> intervening = Layer::Create();
682   scoped_refptr<Layer> clip_child1 = Layer::Create();
683   scoped_refptr<Layer> clip_child2 = Layer::Create();
684   layer_tree_root->AddChild(clip_parent);
685   clip_parent->AddChild(intervening);
686   intervening->AddChild(clip_child1);
687   intervening->AddChild(clip_child2);
688
689   host_->SetRootLayer(layer_tree_root);
690
691   // First child is the second and third child's scroll parent.
692   clip_child1->SetClipParent(clip_parent.get());
693   clip_child2->SetClipParent(clip_parent.get());
694
695   scoped_ptr<LayerImpl> layer_impl_tree_root =
696       TreeSynchronizer::SynchronizeTrees(
697           layer_tree_root.get(), nullptr, host_impl->active_tree());
698   TreeSynchronizer::PushProperties(layer_tree_root.get(),
699                                    layer_impl_tree_root.get());
700   ExpectTreesAreIdentical(layer_tree_root.get(),
701                           layer_impl_tree_root.get(),
702                           host_impl->active_tree());
703
704   // Remove the first clip child.
705   clip_child1->RemoveFromParent();
706   clip_child1 = NULL;
707
708   layer_impl_tree_root =
709       TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
710                                          layer_impl_tree_root.Pass(),
711                                          host_impl->active_tree());
712   TreeSynchronizer::PushProperties(layer_tree_root.get(),
713                                    layer_impl_tree_root.get());
714   ExpectTreesAreIdentical(layer_tree_root.get(),
715                           layer_impl_tree_root.get(),
716                           host_impl->active_tree());
717
718   // Add an additional clip child.
719   scoped_refptr<Layer> additional_clip_child = Layer::Create();
720   intervening->AddChild(additional_clip_child);
721   additional_clip_child->SetClipParent(clip_parent.get());
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   // Remove the nearest clipping ancestor.
733   clip_parent->RemoveFromParent();
734   clip_parent = NULL;
735   layer_impl_tree_root =
736       TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
737                                          layer_impl_tree_root.Pass(),
738                                          host_impl->active_tree());
739   TreeSynchronizer::PushProperties(layer_tree_root.get(),
740                                    layer_impl_tree_root.get());
741   ExpectTreesAreIdentical(layer_tree_root.get(),
742                           layer_impl_tree_root.get(),
743                           host_impl->active_tree());
744
745   // The clip children should have been unhooked.
746   EXPECT_EQ(2u, intervening->children().size());
747   EXPECT_FALSE(clip_child2->clip_parent());
748   EXPECT_FALSE(additional_clip_child->clip_parent());
749 }
750
751 }  // namespace
752 }  // namespace cc