• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/test_shared_bitmap_manager.h"
20 #include "cc/trees/proxy.h"
21 #include "cc/trees/single_thread_proxy.h"
22 #include "testing/gtest/include/gtest/gtest.h"
23 
24 namespace cc {
25 namespace {
26 
27 class MockLayerImpl : public LayerImpl {
28  public:
Create(LayerTreeImpl * tree_impl,int layer_id)29   static scoped_ptr<MockLayerImpl> Create(LayerTreeImpl* tree_impl,
30                                           int layer_id) {
31     return make_scoped_ptr(new MockLayerImpl(tree_impl, layer_id));
32   }
~MockLayerImpl()33   virtual ~MockLayerImpl() {
34     if (layer_impl_destruction_list_)
35       layer_impl_destruction_list_->push_back(id());
36   }
37 
SetLayerImplDestructionList(std::vector<int> * list)38   void SetLayerImplDestructionList(std::vector<int>* list) {
39     layer_impl_destruction_list_ = list;
40   }
41 
42  private:
MockLayerImpl(LayerTreeImpl * tree_impl,int layer_id)43   MockLayerImpl(LayerTreeImpl* tree_impl, int layer_id)
44       : LayerImpl(tree_impl, layer_id),
45         layer_impl_destruction_list_(NULL) {}
46 
47   std::vector<int>* layer_impl_destruction_list_;
48 };
49 
50 class MockLayer : public Layer {
51  public:
Create(std::vector<int> * layer_impl_destruction_list)52   static scoped_refptr<MockLayer> Create(
53       std::vector<int>* layer_impl_destruction_list) {
54     return make_scoped_refptr(new MockLayer(layer_impl_destruction_list));
55   }
56 
CreateLayerImpl(LayerTreeImpl * tree_impl)57   virtual scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl)
58       OVERRIDE {
59     return MockLayerImpl::Create(tree_impl, layer_id_).PassAs<LayerImpl>();
60   }
61 
PushPropertiesTo(LayerImpl * layer_impl)62   virtual 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:
MockLayer(std::vector<int> * layer_impl_destruction_list)70   explicit MockLayer(std::vector<int>* layer_impl_destruction_list)
71       : Layer(), layer_impl_destruction_list_(layer_impl_destruction_list) {}
~MockLayer()72   virtual ~MockLayer() {}
73 
74   std::vector<int>* layer_impl_destruction_list_;
75 };
76 
77 class FakeLayerAnimationController : public LayerAnimationController {
78  public:
Create()79   static scoped_refptr<LayerAnimationController> Create() {
80     return static_cast<LayerAnimationController*>(
81         new FakeLayerAnimationController);
82   }
83 
SynchronizedAnimations() const84   bool SynchronizedAnimations() const { return synchronized_animations_; }
85 
86  private:
FakeLayerAnimationController()87   FakeLayerAnimationController()
88       : LayerAnimationController(1),
89         synchronized_animations_(false) {}
90 
~FakeLayerAnimationController()91   virtual ~FakeLayerAnimationController() {}
92 
PushAnimationUpdatesTo(LayerAnimationController * controller_impl)93   virtual void PushAnimationUpdatesTo(LayerAnimationController* controller_impl)
94       OVERRIDE {
95     LayerAnimationController::PushAnimationUpdatesTo(controller_impl);
96     synchronized_animations_ = true;
97   }
98 
99   bool synchronized_animations_;
100 };
101 
ExpectTreesAreIdentical(Layer * layer,LayerImpl * layer_impl,LayerTreeImpl * tree_impl)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:
TreeSynchronizerTest()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.
TEST_F(TreeSynchronizerTest,SyncNullTree)203 TEST_F(TreeSynchronizerTest, SyncNullTree) {
204   scoped_ptr<LayerImpl> layer_impl_tree_root =
205       TreeSynchronizer::SynchronizeTrees(static_cast<Layer*>(NULL),
206                                          scoped_ptr<LayerImpl>(),
207                                          host_->active_tree());
208 
209   EXPECT_TRUE(!layer_impl_tree_root.get());
210 }
211 
212 // Constructs a very simple tree and synchronizes it without trying to reuse any
213 // preexisting layers.
TEST_F(TreeSynchronizerTest,SyncSimpleTreeFromEmpty)214 TEST_F(TreeSynchronizerTest, SyncSimpleTreeFromEmpty) {
215   scoped_refptr<Layer> layer_tree_root = Layer::Create();
216   layer_tree_root->AddChild(Layer::Create());
217   layer_tree_root->AddChild(Layer::Create());
218 
219   host_->SetRootLayer(layer_tree_root);
220 
221   scoped_ptr<LayerImpl> layer_impl_tree_root =
222       TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
223                                          scoped_ptr<LayerImpl>(),
224                                          host_->active_tree());
225 
226   ExpectTreesAreIdentical(layer_tree_root.get(),
227                           layer_impl_tree_root.get(),
228                           host_->active_tree());
229 }
230 
231 // Constructs a very simple tree and synchronizes it attempting to reuse some
232 // layers
TEST_F(TreeSynchronizerTest,SyncSimpleTreeReusingLayers)233 TEST_F(TreeSynchronizerTest, SyncSimpleTreeReusingLayers) {
234   std::vector<int> layer_impl_destruction_list;
235 
236   scoped_refptr<Layer> layer_tree_root =
237       MockLayer::Create(&layer_impl_destruction_list);
238   layer_tree_root->AddChild(MockLayer::Create(&layer_impl_destruction_list));
239   layer_tree_root->AddChild(MockLayer::Create(&layer_impl_destruction_list));
240 
241   host_->SetRootLayer(layer_tree_root);
242 
243   scoped_ptr<LayerImpl> layer_impl_tree_root =
244       TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
245                                          scoped_ptr<LayerImpl>(),
246                                          host_->active_tree());
247   ExpectTreesAreIdentical(layer_tree_root.get(),
248                           layer_impl_tree_root.get(),
249                           host_->active_tree());
250 
251   // We have to push properties to pick up the destruction list pointer.
252   TreeSynchronizer::PushProperties(layer_tree_root.get(),
253                                    layer_impl_tree_root.get());
254 
255   // Add a new layer to the Layer side
256   layer_tree_root->children()[0]->
257       AddChild(MockLayer::Create(&layer_impl_destruction_list));
258   // Remove one.
259   layer_tree_root->children()[1]->RemoveFromParent();
260   int second_layer_impl_id = layer_impl_tree_root->children()[1]->id();
261 
262   // Synchronize again. After the sync the trees should be equivalent and we
263   // should have created and destroyed one LayerImpl.
264   layer_impl_tree_root =
265       TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
266                                          layer_impl_tree_root.Pass(),
267                                          host_->active_tree());
268   ExpectTreesAreIdentical(layer_tree_root.get(),
269                           layer_impl_tree_root.get(),
270                           host_->active_tree());
271 
272   ASSERT_EQ(1u, layer_impl_destruction_list.size());
273   EXPECT_EQ(second_layer_impl_id, layer_impl_destruction_list[0]);
274 }
275 
276 // Constructs a very simple tree and checks that a stacking-order change is
277 // tracked properly.
TEST_F(TreeSynchronizerTest,SyncSimpleTreeAndTrackStackingOrderChange)278 TEST_F(TreeSynchronizerTest, SyncSimpleTreeAndTrackStackingOrderChange) {
279   std::vector<int> layer_impl_destruction_list;
280 
281   // Set up the tree and sync once. child2 needs to be synced here, too, even
282   // though we remove it to set up the intended scenario.
283   scoped_refptr<Layer> layer_tree_root =
284       MockLayer::Create(&layer_impl_destruction_list);
285   scoped_refptr<Layer> child2 = MockLayer::Create(&layer_impl_destruction_list);
286   layer_tree_root->AddChild(MockLayer::Create(&layer_impl_destruction_list));
287   layer_tree_root->AddChild(child2);
288 
289   host_->SetRootLayer(layer_tree_root);
290 
291   scoped_ptr<LayerImpl> layer_impl_tree_root =
292       TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
293                                          scoped_ptr<LayerImpl>(),
294                                          host_->active_tree());
295   ExpectTreesAreIdentical(layer_tree_root.get(),
296                           layer_impl_tree_root.get(),
297                           host_->active_tree());
298 
299   // We have to push properties to pick up the destruction list pointer.
300   TreeSynchronizer::PushProperties(layer_tree_root.get(),
301                                    layer_impl_tree_root.get());
302 
303   layer_impl_tree_root->ResetAllChangeTrackingForSubtree();
304 
305   // re-insert the layer and sync again.
306   child2->RemoveFromParent();
307   layer_tree_root->AddChild(child2);
308   layer_impl_tree_root =
309       TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
310                                          layer_impl_tree_root.Pass(),
311                                          host_->active_tree());
312   ExpectTreesAreIdentical(layer_tree_root.get(),
313                           layer_impl_tree_root.get(),
314                           host_->active_tree());
315 
316   TreeSynchronizer::PushProperties(layer_tree_root.get(),
317                                    layer_impl_tree_root.get());
318 
319   // Check that the impl thread properly tracked the change.
320   EXPECT_FALSE(layer_impl_tree_root->LayerPropertyChanged());
321   EXPECT_FALSE(layer_impl_tree_root->children()[0]->LayerPropertyChanged());
322   EXPECT_TRUE(layer_impl_tree_root->children()[1]->LayerPropertyChanged());
323 }
324 
TEST_F(TreeSynchronizerTest,SyncSimpleTreeAndProperties)325 TEST_F(TreeSynchronizerTest, SyncSimpleTreeAndProperties) {
326   scoped_refptr<Layer> layer_tree_root = Layer::Create();
327   layer_tree_root->AddChild(Layer::Create());
328   layer_tree_root->AddChild(Layer::Create());
329 
330   host_->SetRootLayer(layer_tree_root);
331 
332   // Pick some random properties to set. The values are not important, we're
333   // just testing that at least some properties are making it through.
334   gfx::PointF root_position = gfx::PointF(2.3f, 7.4f);
335   layer_tree_root->SetPosition(root_position);
336 
337   float first_child_opacity = 0.25f;
338   layer_tree_root->children()[0]->SetOpacity(first_child_opacity);
339 
340   gfx::Size second_child_bounds = gfx::Size(25, 53);
341   layer_tree_root->children()[1]->SetBounds(second_child_bounds);
342   layer_tree_root->children()[1]->SavePaintProperties();
343 
344   scoped_ptr<LayerImpl> layer_impl_tree_root =
345       TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
346                                          scoped_ptr<LayerImpl>(),
347                                          host_->active_tree());
348   ExpectTreesAreIdentical(layer_tree_root.get(),
349                           layer_impl_tree_root.get(),
350                           host_->active_tree());
351 
352   TreeSynchronizer::PushProperties(layer_tree_root.get(),
353                                    layer_impl_tree_root.get());
354 
355   // Check that the property values we set on the Layer tree are reflected in
356   // the LayerImpl tree.
357   gfx::PointF root_layer_impl_position = layer_impl_tree_root->position();
358   EXPECT_EQ(root_position.x(), root_layer_impl_position.x());
359   EXPECT_EQ(root_position.y(), root_layer_impl_position.y());
360 
361   EXPECT_EQ(first_child_opacity,
362             layer_impl_tree_root->children()[0]->opacity());
363 
364   gfx::Size second_layer_impl_child_bounds =
365       layer_impl_tree_root->children()[1]->bounds();
366   EXPECT_EQ(second_child_bounds.width(),
367             second_layer_impl_child_bounds.width());
368   EXPECT_EQ(second_child_bounds.height(),
369             second_layer_impl_child_bounds.height());
370 }
371 
TEST_F(TreeSynchronizerTest,ReuseLayerImplsAfterStructuralChange)372 TEST_F(TreeSynchronizerTest, ReuseLayerImplsAfterStructuralChange) {
373   std::vector<int> layer_impl_destruction_list;
374 
375   // Set up a tree with this sort of structure:
376   // root --- A --- B ---+--- C
377   //                     |
378   //                     +--- D
379   scoped_refptr<Layer> layer_tree_root =
380       MockLayer::Create(&layer_impl_destruction_list);
381   layer_tree_root->AddChild(MockLayer::Create(&layer_impl_destruction_list));
382 
383   scoped_refptr<Layer> layer_a = layer_tree_root->children()[0].get();
384   layer_a->AddChild(MockLayer::Create(&layer_impl_destruction_list));
385 
386   scoped_refptr<Layer> layer_b = layer_a->children()[0].get();
387   layer_b->AddChild(MockLayer::Create(&layer_impl_destruction_list));
388 
389   scoped_refptr<Layer> layer_c = layer_b->children()[0].get();
390   layer_b->AddChild(MockLayer::Create(&layer_impl_destruction_list));
391   scoped_refptr<Layer> layer_d = layer_b->children()[1].get();
392 
393   host_->SetRootLayer(layer_tree_root);
394 
395   scoped_ptr<LayerImpl> layer_impl_tree_root =
396       TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
397                                          scoped_ptr<LayerImpl>(),
398                                          host_->active_tree());
399   ExpectTreesAreIdentical(layer_tree_root.get(),
400                           layer_impl_tree_root.get(),
401                           host_->active_tree());
402 
403   // We have to push properties to pick up the destruction list pointer.
404   TreeSynchronizer::PushProperties(layer_tree_root.get(),
405                                    layer_impl_tree_root.get());
406 
407   // Now restructure the tree to look like this:
408   // root --- D ---+--- A
409   //               |
410   //               +--- C --- B
411   layer_tree_root->RemoveAllChildren();
412   layer_d->RemoveAllChildren();
413   layer_tree_root->AddChild(layer_d);
414   layer_a->RemoveAllChildren();
415   layer_d->AddChild(layer_a);
416   layer_c->RemoveAllChildren();
417   layer_d->AddChild(layer_c);
418   layer_b->RemoveAllChildren();
419   layer_c->AddChild(layer_b);
420 
421   // After another synchronize our trees should match and we should not have
422   // destroyed any LayerImpls
423   layer_impl_tree_root =
424       TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
425                                          layer_impl_tree_root.Pass(),
426                                          host_->active_tree());
427   ExpectTreesAreIdentical(layer_tree_root.get(),
428                           layer_impl_tree_root.get(),
429                           host_->active_tree());
430 
431   EXPECT_EQ(0u, layer_impl_destruction_list.size());
432 }
433 
434 // Constructs a very simple tree, synchronizes it, then synchronizes to a
435 // totally new tree. All layers from the old tree should be deleted.
TEST_F(TreeSynchronizerTest,SyncSimpleTreeThenDestroy)436 TEST_F(TreeSynchronizerTest, SyncSimpleTreeThenDestroy) {
437   std::vector<int> layer_impl_destruction_list;
438 
439   scoped_refptr<Layer> old_layer_tree_root =
440       MockLayer::Create(&layer_impl_destruction_list);
441   old_layer_tree_root->AddChild(
442       MockLayer::Create(&layer_impl_destruction_list));
443   old_layer_tree_root->AddChild(
444       MockLayer::Create(&layer_impl_destruction_list));
445 
446   host_->SetRootLayer(old_layer_tree_root);
447 
448   int old_tree_root_layer_id = old_layer_tree_root->id();
449   int old_tree_first_child_layer_id = old_layer_tree_root->children()[0]->id();
450   int old_tree_second_child_layer_id = old_layer_tree_root->children()[1]->id();
451 
452   scoped_ptr<LayerImpl> layer_impl_tree_root =
453       TreeSynchronizer::SynchronizeTrees(old_layer_tree_root.get(),
454                                          scoped_ptr<LayerImpl>(),
455                                          host_->active_tree());
456   ExpectTreesAreIdentical(old_layer_tree_root.get(),
457                           layer_impl_tree_root.get(),
458                           host_->active_tree());
459 
460   // We have to push properties to pick up the destruction list pointer.
461   TreeSynchronizer::PushProperties(old_layer_tree_root.get(),
462                                    layer_impl_tree_root.get());
463 
464   // Remove all children on the Layer side.
465   old_layer_tree_root->RemoveAllChildren();
466 
467   // Synchronize again. After the sync all LayerImpls from the old tree should
468   // be deleted.
469   scoped_refptr<Layer> new_layer_tree_root = Layer::Create();
470   host_->SetRootLayer(new_layer_tree_root);
471   layer_impl_tree_root =
472       TreeSynchronizer::SynchronizeTrees(new_layer_tree_root.get(),
473                                          layer_impl_tree_root.Pass(),
474                                          host_->active_tree());
475   ExpectTreesAreIdentical(new_layer_tree_root.get(),
476                           layer_impl_tree_root.get(),
477                           host_->active_tree());
478 
479   ASSERT_EQ(3u, layer_impl_destruction_list.size());
480 
481   EXPECT_TRUE(std::find(layer_impl_destruction_list.begin(),
482                         layer_impl_destruction_list.end(),
483                         old_tree_root_layer_id) !=
484               layer_impl_destruction_list.end());
485   EXPECT_TRUE(std::find(layer_impl_destruction_list.begin(),
486                         layer_impl_destruction_list.end(),
487                         old_tree_first_child_layer_id) !=
488               layer_impl_destruction_list.end());
489   EXPECT_TRUE(std::find(layer_impl_destruction_list.begin(),
490                         layer_impl_destruction_list.end(),
491                         old_tree_second_child_layer_id) !=
492               layer_impl_destruction_list.end());
493 }
494 
495 // Constructs+syncs a tree with mask, replica, and replica mask layers.
TEST_F(TreeSynchronizerTest,SyncMaskReplicaAndReplicaMaskLayers)496 TEST_F(TreeSynchronizerTest, SyncMaskReplicaAndReplicaMaskLayers) {
497   scoped_refptr<Layer> layer_tree_root = Layer::Create();
498   layer_tree_root->AddChild(Layer::Create());
499   layer_tree_root->AddChild(Layer::Create());
500   layer_tree_root->AddChild(Layer::Create());
501 
502   // First child gets a mask layer.
503   scoped_refptr<Layer> mask_layer = Layer::Create();
504   layer_tree_root->children()[0]->SetMaskLayer(mask_layer.get());
505 
506   // Second child gets a replica layer.
507   scoped_refptr<Layer> replica_layer = Layer::Create();
508   layer_tree_root->children()[1]->SetReplicaLayer(replica_layer.get());
509 
510   // Third child gets a replica layer with a mask layer.
511   scoped_refptr<Layer> replica_layer_with_mask = Layer::Create();
512   scoped_refptr<Layer> replica_mask_layer = Layer::Create();
513   replica_layer_with_mask->SetMaskLayer(replica_mask_layer.get());
514   layer_tree_root->children()[2]->
515       SetReplicaLayer(replica_layer_with_mask.get());
516 
517   host_->SetRootLayer(layer_tree_root);
518 
519   scoped_ptr<LayerImpl> layer_impl_tree_root =
520       TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
521                                          scoped_ptr<LayerImpl>(),
522                                          host_->active_tree());
523 
524   ExpectTreesAreIdentical(layer_tree_root.get(),
525                           layer_impl_tree_root.get(),
526                           host_->active_tree());
527 
528   // Remove the mask layer.
529   layer_tree_root->children()[0]->SetMaskLayer(NULL);
530   layer_impl_tree_root =
531       TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
532                                          layer_impl_tree_root.Pass(),
533                                          host_->active_tree());
534   ExpectTreesAreIdentical(layer_tree_root.get(),
535                           layer_impl_tree_root.get(),
536                           host_->active_tree());
537 
538   // Remove the replica layer.
539   layer_tree_root->children()[1]->SetReplicaLayer(NULL);
540   layer_impl_tree_root =
541       TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
542                                          layer_impl_tree_root.Pass(),
543                                          host_->active_tree());
544   ExpectTreesAreIdentical(layer_tree_root.get(),
545                           layer_impl_tree_root.get(),
546                           host_->active_tree());
547 
548   // Remove the replica mask.
549   replica_layer_with_mask->SetMaskLayer(NULL);
550   layer_impl_tree_root =
551       TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
552                                          layer_impl_tree_root.Pass(),
553                                          host_->active_tree());
554   ExpectTreesAreIdentical(layer_tree_root.get(),
555                           layer_impl_tree_root.get(),
556                           host_->active_tree());
557 }
558 
TEST_F(TreeSynchronizerTest,SynchronizeAnimations)559 TEST_F(TreeSynchronizerTest, SynchronizeAnimations) {
560   LayerTreeSettings settings;
561   FakeProxy proxy;
562   DebugScopedSetImplThread impl(&proxy);
563   FakeRenderingStatsInstrumentation stats_instrumentation;
564   scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
565       new TestSharedBitmapManager());
566   scoped_ptr<LayerTreeHostImpl> host_impl =
567       LayerTreeHostImpl::Create(settings,
568                                 NULL,
569                                 &proxy,
570                                 &stats_instrumentation,
571                                 shared_bitmap_manager.get(),
572                                 0);
573 
574   scoped_refptr<Layer> layer_tree_root = Layer::Create();
575   host_->SetRootLayer(layer_tree_root);
576 
577   layer_tree_root->SetLayerAnimationControllerForTest(
578       FakeLayerAnimationController::Create());
579 
580   EXPECT_FALSE(static_cast<FakeLayerAnimationController*>(
581       layer_tree_root->layer_animation_controller())->SynchronizedAnimations());
582 
583   scoped_ptr<LayerImpl> layer_impl_tree_root =
584       TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
585                                          scoped_ptr<LayerImpl>(),
586                                          host_->active_tree());
587   TreeSynchronizer::PushProperties(layer_tree_root.get(),
588                                    layer_impl_tree_root.get());
589   layer_impl_tree_root =
590       TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
591                                          layer_impl_tree_root.Pass(),
592                                          host_->active_tree());
593 
594   EXPECT_TRUE(static_cast<FakeLayerAnimationController*>(
595       layer_tree_root->layer_animation_controller())->SynchronizedAnimations());
596 }
597 
TEST_F(TreeSynchronizerTest,SynchronizeScrollParent)598 TEST_F(TreeSynchronizerTest, SynchronizeScrollParent) {
599   LayerTreeSettings settings;
600   FakeProxy proxy;
601   DebugScopedSetImplThread impl(&proxy);
602   FakeRenderingStatsInstrumentation stats_instrumentation;
603   scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
604       new TestSharedBitmapManager());
605   scoped_ptr<LayerTreeHostImpl> host_impl =
606       LayerTreeHostImpl::Create(settings,
607                                 NULL,
608                                 &proxy,
609                                 &stats_instrumentation,
610                                 shared_bitmap_manager.get(),
611                                 0);
612 
613   scoped_refptr<Layer> layer_tree_root = Layer::Create();
614   scoped_refptr<Layer> scroll_parent = Layer::Create();
615   layer_tree_root->AddChild(scroll_parent);
616   layer_tree_root->AddChild(Layer::Create());
617   layer_tree_root->AddChild(Layer::Create());
618 
619   host_->SetRootLayer(layer_tree_root);
620 
621   // First child is the second and third child's scroll parent.
622   layer_tree_root->children()[1]->SetScrollParent(scroll_parent.get());
623   layer_tree_root->children()[2]->SetScrollParent(scroll_parent.get());
624 
625   scoped_ptr<LayerImpl> layer_impl_tree_root =
626       TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
627                                          scoped_ptr<LayerImpl>(),
628                                          host_impl->active_tree());
629   TreeSynchronizer::PushProperties(layer_tree_root.get(),
630                                    layer_impl_tree_root.get());
631   {
632     SCOPED_TRACE("case one");
633     ExpectTreesAreIdentical(layer_tree_root.get(),
634                             layer_impl_tree_root.get(),
635                             host_impl->active_tree());
636   }
637 
638   // Remove the first scroll child.
639   layer_tree_root->children()[1]->RemoveFromParent();
640   layer_impl_tree_root =
641       TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
642                                          layer_impl_tree_root.Pass(),
643                                          host_impl->active_tree());
644   TreeSynchronizer::PushProperties(layer_tree_root.get(),
645                                    layer_impl_tree_root.get());
646   {
647     SCOPED_TRACE("case two");
648     ExpectTreesAreIdentical(layer_tree_root.get(),
649                             layer_impl_tree_root.get(),
650                             host_impl->active_tree());
651   }
652 
653   // Add an additional scroll layer.
654   scoped_refptr<Layer> additional_scroll_child = Layer::Create();
655   layer_tree_root->AddChild(additional_scroll_child);
656   additional_scroll_child->SetScrollParent(scroll_parent.get());
657   layer_impl_tree_root =
658       TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
659                                          layer_impl_tree_root.Pass(),
660                                          host_impl->active_tree());
661   TreeSynchronizer::PushProperties(layer_tree_root.get(),
662                                    layer_impl_tree_root.get());
663   {
664     SCOPED_TRACE("case three");
665     ExpectTreesAreIdentical(layer_tree_root.get(),
666                             layer_impl_tree_root.get(),
667                             host_impl->active_tree());
668   }
669 }
670 
TEST_F(TreeSynchronizerTest,SynchronizeClipParent)671 TEST_F(TreeSynchronizerTest, SynchronizeClipParent) {
672   LayerTreeSettings settings;
673   FakeProxy proxy;
674   DebugScopedSetImplThread impl(&proxy);
675   FakeRenderingStatsInstrumentation stats_instrumentation;
676   scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
677       new TestSharedBitmapManager());
678   scoped_ptr<LayerTreeHostImpl> host_impl =
679       LayerTreeHostImpl::Create(settings,
680                                 NULL,
681                                 &proxy,
682                                 &stats_instrumentation,
683                                 shared_bitmap_manager.get(),
684                                 0);
685 
686   scoped_refptr<Layer> layer_tree_root = Layer::Create();
687   scoped_refptr<Layer> clip_parent = Layer::Create();
688   scoped_refptr<Layer> intervening = Layer::Create();
689   scoped_refptr<Layer> clip_child1 = Layer::Create();
690   scoped_refptr<Layer> clip_child2 = Layer::Create();
691   layer_tree_root->AddChild(clip_parent);
692   clip_parent->AddChild(intervening);
693   intervening->AddChild(clip_child1);
694   intervening->AddChild(clip_child2);
695 
696   host_->SetRootLayer(layer_tree_root);
697 
698   // First child is the second and third child's scroll parent.
699   clip_child1->SetClipParent(clip_parent.get());
700   clip_child2->SetClipParent(clip_parent.get());
701 
702   scoped_ptr<LayerImpl> layer_impl_tree_root =
703       TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
704                                          scoped_ptr<LayerImpl>(),
705                                          host_impl->active_tree());
706   TreeSynchronizer::PushProperties(layer_tree_root.get(),
707                                    layer_impl_tree_root.get());
708   ExpectTreesAreIdentical(layer_tree_root.get(),
709                           layer_impl_tree_root.get(),
710                           host_impl->active_tree());
711 
712   // Remove the first clip child.
713   clip_child1->RemoveFromParent();
714   clip_child1 = NULL;
715 
716   layer_impl_tree_root =
717       TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
718                                          layer_impl_tree_root.Pass(),
719                                          host_impl->active_tree());
720   TreeSynchronizer::PushProperties(layer_tree_root.get(),
721                                    layer_impl_tree_root.get());
722   ExpectTreesAreIdentical(layer_tree_root.get(),
723                           layer_impl_tree_root.get(),
724                           host_impl->active_tree());
725 
726   // Add an additional clip child.
727   scoped_refptr<Layer> additional_clip_child = Layer::Create();
728   intervening->AddChild(additional_clip_child);
729   additional_clip_child->SetClipParent(clip_parent.get());
730   layer_impl_tree_root =
731       TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
732                                          layer_impl_tree_root.Pass(),
733                                          host_impl->active_tree());
734   TreeSynchronizer::PushProperties(layer_tree_root.get(),
735                                    layer_impl_tree_root.get());
736   ExpectTreesAreIdentical(layer_tree_root.get(),
737                           layer_impl_tree_root.get(),
738                           host_impl->active_tree());
739 
740   // Remove the nearest clipping ancestor.
741   clip_parent->RemoveFromParent();
742   clip_parent = NULL;
743   layer_impl_tree_root =
744       TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
745                                          layer_impl_tree_root.Pass(),
746                                          host_impl->active_tree());
747   TreeSynchronizer::PushProperties(layer_tree_root.get(),
748                                    layer_impl_tree_root.get());
749   ExpectTreesAreIdentical(layer_tree_root.get(),
750                           layer_impl_tree_root.get(),
751                           host_impl->active_tree());
752 
753   // The clip children should have been unhooked.
754   EXPECT_EQ(2u, intervening->children().size());
755   EXPECT_FALSE(clip_child2->clip_parent());
756   EXPECT_FALSE(additional_clip_child->clip_parent());
757 }
758 
759 }  // namespace
760 }  // namespace cc
761