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 "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:
     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   }
     33   virtual ~MockLayerImpl() {
     34     if (layer_impl_destruction_list_)
     35       layer_impl_destruction_list_->push_back(id());
     36   }
     37 
     38   void SetLayerImplDestructionList(std::vector<int>* list) {
     39     layer_impl_destruction_list_ = list;
     40   }
     41 
     42  private:
     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:
     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 
     57   virtual scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl)
     58       OVERRIDE {
     59     return MockLayerImpl::Create(tree_impl, layer_id_).PassAs<LayerImpl>();
     60   }
     61 
     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:
     70   explicit MockLayer(std::vector<int>* layer_impl_destruction_list)
     71       : Layer(), layer_impl_destruction_list_(layer_impl_destruction_list) {}
     72   virtual ~MockLayer() {}
     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   virtual ~FakeLayerAnimationController() {}
     92 
     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 
    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(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.
    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
    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.
    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 
    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 
    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.
    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.
    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 
    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 
    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 
    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