Home | History | Annotate | Download | only in trees
      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, 0);
    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, 0);
    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, 0);
    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
    740