// Copyright 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "cc/trees/tree_synchronizer.h"

#include <algorithm>
#include <set>
#include <vector>

#include "cc/animation/layer_animation_controller.h"
#include "cc/layers/layer.h"
#include "cc/layers/layer_impl.h"
#include "cc/test/animation_test_common.h"
#include "cc/test/fake_impl_proxy.h"
#include "cc/test/fake_layer_tree_host.h"
#include "cc/trees/proxy.h"
#include "cc/trees/single_thread_proxy.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace cc {
namespace {

class MockLayerImpl : public LayerImpl {
 public:
  static scoped_ptr<MockLayerImpl> Create(LayerTreeImpl* tree_impl,
                                          int layer_id) {
    return make_scoped_ptr(new MockLayerImpl(tree_impl, layer_id));
  }
  virtual ~MockLayerImpl() {
    if (layer_impl_destruction_list_)
      layer_impl_destruction_list_->push_back(id());
  }

  void SetLayerImplDestructionList(std::vector<int>* list) {
    layer_impl_destruction_list_ = list;
  }

 private:
  MockLayerImpl(LayerTreeImpl* tree_impl, int layer_id)
      : LayerImpl(tree_impl, layer_id),
        layer_impl_destruction_list_(NULL) {}

  std::vector<int>* layer_impl_destruction_list_;
};

class MockLayer : public Layer {
 public:
  static scoped_refptr<MockLayer> Create(
      std::vector<int>* layer_impl_destruction_list) {
    return make_scoped_refptr(new MockLayer(layer_impl_destruction_list));
  }

  virtual scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl)
      OVERRIDE {
    return MockLayerImpl::Create(tree_impl, layer_id_).PassAs<LayerImpl>();
  }

  virtual void PushPropertiesTo(LayerImpl* layer_impl) OVERRIDE {
    Layer::PushPropertiesTo(layer_impl);

    MockLayerImpl* mock_layer_impl = static_cast<MockLayerImpl*>(layer_impl);
    mock_layer_impl->SetLayerImplDestructionList(layer_impl_destruction_list_);
  }

 private:
  explicit MockLayer(std::vector<int>* layer_impl_destruction_list)
      : Layer(), layer_impl_destruction_list_(layer_impl_destruction_list) {}
  virtual ~MockLayer() {}

  std::vector<int>* layer_impl_destruction_list_;
};

class FakeLayerAnimationController : public LayerAnimationController {
 public:
  static scoped_refptr<LayerAnimationController> Create() {
    return static_cast<LayerAnimationController*>(
        new FakeLayerAnimationController);
  }

  bool SynchronizedAnimations() const { return synchronized_animations_; }

 private:
  FakeLayerAnimationController()
      : LayerAnimationController(1),
        synchronized_animations_(false) {}

  virtual ~FakeLayerAnimationController() {}

  virtual void PushAnimationUpdatesTo(LayerAnimationController* controller_impl)
      OVERRIDE {
    LayerAnimationController::PushAnimationUpdatesTo(controller_impl);
    synchronized_animations_ = true;
  }

  bool synchronized_animations_;
};

void ExpectTreesAreIdentical(Layer* layer,
                             LayerImpl* layer_impl,
                             LayerTreeImpl* tree_impl) {
  ASSERT_TRUE(layer);
  ASSERT_TRUE(layer_impl);

  EXPECT_EQ(layer->id(), layer_impl->id());
  EXPECT_EQ(layer_impl->layer_tree_impl(), tree_impl);

  EXPECT_EQ(layer->non_fast_scrollable_region(),
            layer_impl->non_fast_scrollable_region());

  ASSERT_EQ(!!layer->mask_layer(), !!layer_impl->mask_layer());
  if (layer->mask_layer()) {
    ExpectTreesAreIdentical(
        layer->mask_layer(), layer_impl->mask_layer(), tree_impl);
  }

  ASSERT_EQ(!!layer->replica_layer(), !!layer_impl->replica_layer());
  if (layer->replica_layer()) {
    ExpectTreesAreIdentical(
        layer->replica_layer(), layer_impl->replica_layer(), tree_impl);
  }

  const LayerList& layer_children = layer->children();
  const OwnedLayerImplList& layer_impl_children = layer_impl->children();

  ASSERT_EQ(layer_children.size(), layer_impl_children.size());

  const std::set<Layer*>* layer_scroll_children = layer->scroll_children();
  const std::set<LayerImpl*>* layer_impl_scroll_children =
      layer_impl->scroll_children();

  ASSERT_EQ(!!layer_scroll_children, !!layer_impl_scroll_children);

  if (layer_scroll_children) {
    ASSERT_EQ(
        layer_scroll_children->size(),
        layer_impl_scroll_children->size());
  }

  const Layer* layer_scroll_parent = layer->scroll_parent();
  const LayerImpl* layer_impl_scroll_parent = layer_impl->scroll_parent();

  ASSERT_EQ(!!layer_scroll_parent, !!layer_impl_scroll_parent);

  if (layer_scroll_parent) {
    ASSERT_EQ(layer_scroll_parent->id(), layer_impl_scroll_parent->id());
    ASSERT_TRUE(layer_scroll_parent->scroll_children()->find(layer) !=
        layer_scroll_parent->scroll_children()->end());
    ASSERT_TRUE(layer_impl_scroll_parent->scroll_children()->find(layer_impl) !=
        layer_impl_scroll_parent->scroll_children()->end());
  }

  const std::set<Layer*>* layer_clip_children = layer->clip_children();
  const std::set<LayerImpl*>* layer_impl_clip_children =
      layer_impl->clip_children();

  ASSERT_EQ(!!layer_clip_children, !!layer_impl_clip_children);

  if (layer_clip_children)
    ASSERT_EQ(layer_clip_children->size(), layer_impl_clip_children->size());

  const Layer* layer_clip_parent = layer->clip_parent();
  const LayerImpl* layer_impl_clip_parent = layer_impl->clip_parent();

  ASSERT_EQ(!!layer_clip_parent, !!layer_impl_clip_parent);

  if (layer_clip_parent) {
    const std::set<LayerImpl*>* clip_children_impl =
        layer_impl_clip_parent->clip_children();
    const std::set<Layer*>* clip_children =
        layer_clip_parent->clip_children();
    ASSERT_EQ(layer_clip_parent->id(), layer_impl_clip_parent->id());
    ASSERT_TRUE(clip_children->find(layer) != clip_children->end());
    ASSERT_TRUE(clip_children_impl->find(layer_impl) !=
                clip_children_impl->end());
  }

  for (size_t i = 0; i < layer_children.size(); ++i) {
    ExpectTreesAreIdentical(
        layer_children[i].get(), layer_impl_children[i], tree_impl);
  }
}

class TreeSynchronizerTest : public testing::Test {
 public:
  TreeSynchronizerTest() : host_(FakeLayerTreeHost::Create()) {}

 protected:
  scoped_ptr<FakeLayerTreeHost> host_;
};

// Attempts to synchronizes a null tree. This should not crash, and should
// return a null tree.
TEST_F(TreeSynchronizerTest, SyncNullTree) {
  scoped_ptr<LayerImpl> layer_impl_tree_root =
      TreeSynchronizer::SynchronizeTrees(static_cast<Layer*>(NULL),
                                         scoped_ptr<LayerImpl>(),
                                         host_->active_tree());

  EXPECT_TRUE(!layer_impl_tree_root.get());
}

// Constructs a very simple tree and synchronizes it without trying to reuse any
// preexisting layers.
TEST_F(TreeSynchronizerTest, SyncSimpleTreeFromEmpty) {
  scoped_refptr<Layer> layer_tree_root = Layer::Create();
  layer_tree_root->AddChild(Layer::Create());
  layer_tree_root->AddChild(Layer::Create());

  host_->SetRootLayer(layer_tree_root);

  scoped_ptr<LayerImpl> layer_impl_tree_root =
      TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
                                         scoped_ptr<LayerImpl>(),
                                         host_->active_tree());

  ExpectTreesAreIdentical(layer_tree_root.get(),
                          layer_impl_tree_root.get(),
                          host_->active_tree());
}

// Constructs a very simple tree and synchronizes it attempting to reuse some
// layers
TEST_F(TreeSynchronizerTest, SyncSimpleTreeReusingLayers) {
  std::vector<int> layer_impl_destruction_list;

  scoped_refptr<Layer> layer_tree_root =
      MockLayer::Create(&layer_impl_destruction_list);
  layer_tree_root->AddChild(MockLayer::Create(&layer_impl_destruction_list));
  layer_tree_root->AddChild(MockLayer::Create(&layer_impl_destruction_list));

  host_->SetRootLayer(layer_tree_root);

  scoped_ptr<LayerImpl> layer_impl_tree_root =
      TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
                                         scoped_ptr<LayerImpl>(),
                                         host_->active_tree());
  ExpectTreesAreIdentical(layer_tree_root.get(),
                          layer_impl_tree_root.get(),
                          host_->active_tree());

  // We have to push properties to pick up the destruction list pointer.
  TreeSynchronizer::PushProperties(layer_tree_root.get(),
                                   layer_impl_tree_root.get());

  // Add a new layer to the Layer side
  layer_tree_root->children()[0]->
      AddChild(MockLayer::Create(&layer_impl_destruction_list));
  // Remove one.
  layer_tree_root->children()[1]->RemoveFromParent();
  int second_layer_impl_id = layer_impl_tree_root->children()[1]->id();

  // Synchronize again. After the sync the trees should be equivalent and we
  // should have created and destroyed one LayerImpl.
  layer_impl_tree_root =
      TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
                                         layer_impl_tree_root.Pass(),
                                         host_->active_tree());
  ExpectTreesAreIdentical(layer_tree_root.get(),
                          layer_impl_tree_root.get(),
                          host_->active_tree());

  ASSERT_EQ(1u, layer_impl_destruction_list.size());
  EXPECT_EQ(second_layer_impl_id, layer_impl_destruction_list[0]);
}

// Constructs a very simple tree and checks that a stacking-order change is
// tracked properly.
TEST_F(TreeSynchronizerTest, SyncSimpleTreeAndTrackStackingOrderChange) {
  std::vector<int> layer_impl_destruction_list;

  // Set up the tree and sync once. child2 needs to be synced here, too, even
  // though we remove it to set up the intended scenario.
  scoped_refptr<Layer> layer_tree_root =
      MockLayer::Create(&layer_impl_destruction_list);
  scoped_refptr<Layer> child2 = MockLayer::Create(&layer_impl_destruction_list);
  layer_tree_root->AddChild(MockLayer::Create(&layer_impl_destruction_list));
  layer_tree_root->AddChild(child2);

  host_->SetRootLayer(layer_tree_root);

  scoped_ptr<LayerImpl> layer_impl_tree_root =
      TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
                                         scoped_ptr<LayerImpl>(),
                                         host_->active_tree());
  ExpectTreesAreIdentical(layer_tree_root.get(),
                          layer_impl_tree_root.get(),
                          host_->active_tree());

  // We have to push properties to pick up the destruction list pointer.
  TreeSynchronizer::PushProperties(layer_tree_root.get(),
                                   layer_impl_tree_root.get());

  layer_impl_tree_root->ResetAllChangeTrackingForSubtree();

  // re-insert the layer and sync again.
  child2->RemoveFromParent();
  layer_tree_root->AddChild(child2);
  layer_impl_tree_root =
      TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
                                         layer_impl_tree_root.Pass(),
                                         host_->active_tree());
  ExpectTreesAreIdentical(layer_tree_root.get(),
                          layer_impl_tree_root.get(),
                          host_->active_tree());

  TreeSynchronizer::PushProperties(layer_tree_root.get(),
                                   layer_impl_tree_root.get());

  // Check that the impl thread properly tracked the change.
  EXPECT_FALSE(layer_impl_tree_root->LayerPropertyChanged());
  EXPECT_FALSE(layer_impl_tree_root->children()[0]->LayerPropertyChanged());
  EXPECT_TRUE(layer_impl_tree_root->children()[1]->LayerPropertyChanged());
}

TEST_F(TreeSynchronizerTest, SyncSimpleTreeAndProperties) {
  scoped_refptr<Layer> layer_tree_root = Layer::Create();
  layer_tree_root->AddChild(Layer::Create());
  layer_tree_root->AddChild(Layer::Create());

  host_->SetRootLayer(layer_tree_root);

  // Pick some random properties to set. The values are not important, we're
  // just testing that at least some properties are making it through.
  gfx::PointF root_position = gfx::PointF(2.3f, 7.4f);
  layer_tree_root->SetPosition(root_position);

  float first_child_opacity = 0.25f;
  layer_tree_root->children()[0]->SetOpacity(first_child_opacity);

  gfx::Size second_child_bounds = gfx::Size(25, 53);
  layer_tree_root->children()[1]->SetBounds(second_child_bounds);
  layer_tree_root->children()[1]->SavePaintProperties();

  scoped_ptr<LayerImpl> layer_impl_tree_root =
      TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
                                         scoped_ptr<LayerImpl>(),
                                         host_->active_tree());
  ExpectTreesAreIdentical(layer_tree_root.get(),
                          layer_impl_tree_root.get(),
                          host_->active_tree());

  TreeSynchronizer::PushProperties(layer_tree_root.get(),
                                   layer_impl_tree_root.get());

  // Check that the property values we set on the Layer tree are reflected in
  // the LayerImpl tree.
  gfx::PointF root_layer_impl_position = layer_impl_tree_root->position();
  EXPECT_EQ(root_position.x(), root_layer_impl_position.x());
  EXPECT_EQ(root_position.y(), root_layer_impl_position.y());

  EXPECT_EQ(first_child_opacity,
            layer_impl_tree_root->children()[0]->opacity());

  gfx::Size second_layer_impl_child_bounds =
      layer_impl_tree_root->children()[1]->bounds();
  EXPECT_EQ(second_child_bounds.width(),
            second_layer_impl_child_bounds.width());
  EXPECT_EQ(second_child_bounds.height(),
            second_layer_impl_child_bounds.height());
}

TEST_F(TreeSynchronizerTest, ReuseLayerImplsAfterStructuralChange) {
  std::vector<int> layer_impl_destruction_list;

  // Set up a tree with this sort of structure:
  // root --- A --- B ---+--- C
  //                     |
  //                     +--- D
  scoped_refptr<Layer> layer_tree_root =
      MockLayer::Create(&layer_impl_destruction_list);
  layer_tree_root->AddChild(MockLayer::Create(&layer_impl_destruction_list));

  scoped_refptr<Layer> layer_a = layer_tree_root->children()[0].get();
  layer_a->AddChild(MockLayer::Create(&layer_impl_destruction_list));

  scoped_refptr<Layer> layer_b = layer_a->children()[0].get();
  layer_b->AddChild(MockLayer::Create(&layer_impl_destruction_list));

  scoped_refptr<Layer> layer_c = layer_b->children()[0].get();
  layer_b->AddChild(MockLayer::Create(&layer_impl_destruction_list));
  scoped_refptr<Layer> layer_d = layer_b->children()[1].get();

  host_->SetRootLayer(layer_tree_root);

  scoped_ptr<LayerImpl> layer_impl_tree_root =
      TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
                                         scoped_ptr<LayerImpl>(),
                                         host_->active_tree());
  ExpectTreesAreIdentical(layer_tree_root.get(),
                          layer_impl_tree_root.get(),
                          host_->active_tree());

  // We have to push properties to pick up the destruction list pointer.
  TreeSynchronizer::PushProperties(layer_tree_root.get(),
                                   layer_impl_tree_root.get());

  // Now restructure the tree to look like this:
  // root --- D ---+--- A
  //               |
  //               +--- C --- B
  layer_tree_root->RemoveAllChildren();
  layer_d->RemoveAllChildren();
  layer_tree_root->AddChild(layer_d);
  layer_a->RemoveAllChildren();
  layer_d->AddChild(layer_a);
  layer_c->RemoveAllChildren();
  layer_d->AddChild(layer_c);
  layer_b->RemoveAllChildren();
  layer_c->AddChild(layer_b);

  // After another synchronize our trees should match and we should not have
  // destroyed any LayerImpls
  layer_impl_tree_root =
      TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
                                         layer_impl_tree_root.Pass(),
                                         host_->active_tree());
  ExpectTreesAreIdentical(layer_tree_root.get(),
                          layer_impl_tree_root.get(),
                          host_->active_tree());

  EXPECT_EQ(0u, layer_impl_destruction_list.size());
}

// Constructs a very simple tree, synchronizes it, then synchronizes to a
// totally new tree. All layers from the old tree should be deleted.
TEST_F(TreeSynchronizerTest, SyncSimpleTreeThenDestroy) {
  std::vector<int> layer_impl_destruction_list;

  scoped_refptr<Layer> old_layer_tree_root =
      MockLayer::Create(&layer_impl_destruction_list);
  old_layer_tree_root->AddChild(
      MockLayer::Create(&layer_impl_destruction_list));
  old_layer_tree_root->AddChild(
      MockLayer::Create(&layer_impl_destruction_list));

  host_->SetRootLayer(old_layer_tree_root);

  int old_tree_root_layer_id = old_layer_tree_root->id();
  int old_tree_first_child_layer_id = old_layer_tree_root->children()[0]->id();
  int old_tree_second_child_layer_id = old_layer_tree_root->children()[1]->id();

  scoped_ptr<LayerImpl> layer_impl_tree_root =
      TreeSynchronizer::SynchronizeTrees(old_layer_tree_root.get(),
                                         scoped_ptr<LayerImpl>(),
                                         host_->active_tree());
  ExpectTreesAreIdentical(old_layer_tree_root.get(),
                          layer_impl_tree_root.get(),
                          host_->active_tree());

  // We have to push properties to pick up the destruction list pointer.
  TreeSynchronizer::PushProperties(old_layer_tree_root.get(),
                                   layer_impl_tree_root.get());

  // Remove all children on the Layer side.
  old_layer_tree_root->RemoveAllChildren();

  // Synchronize again. After the sync all LayerImpls from the old tree should
  // be deleted.
  scoped_refptr<Layer> new_layer_tree_root = Layer::Create();
  host_->SetRootLayer(new_layer_tree_root);
  layer_impl_tree_root =
      TreeSynchronizer::SynchronizeTrees(new_layer_tree_root.get(),
                                         layer_impl_tree_root.Pass(),
                                         host_->active_tree());
  ExpectTreesAreIdentical(new_layer_tree_root.get(),
                          layer_impl_tree_root.get(),
                          host_->active_tree());

  ASSERT_EQ(3u, layer_impl_destruction_list.size());

  EXPECT_TRUE(std::find(layer_impl_destruction_list.begin(),
                        layer_impl_destruction_list.end(),
                        old_tree_root_layer_id) !=
              layer_impl_destruction_list.end());
  EXPECT_TRUE(std::find(layer_impl_destruction_list.begin(),
                        layer_impl_destruction_list.end(),
                        old_tree_first_child_layer_id) !=
              layer_impl_destruction_list.end());
  EXPECT_TRUE(std::find(layer_impl_destruction_list.begin(),
                        layer_impl_destruction_list.end(),
                        old_tree_second_child_layer_id) !=
              layer_impl_destruction_list.end());
}

// Constructs+syncs a tree with mask, replica, and replica mask layers.
TEST_F(TreeSynchronizerTest, SyncMaskReplicaAndReplicaMaskLayers) {
  scoped_refptr<Layer> layer_tree_root = Layer::Create();
  layer_tree_root->AddChild(Layer::Create());
  layer_tree_root->AddChild(Layer::Create());
  layer_tree_root->AddChild(Layer::Create());

  // First child gets a mask layer.
  scoped_refptr<Layer> mask_layer = Layer::Create();
  layer_tree_root->children()[0]->SetMaskLayer(mask_layer.get());

  // Second child gets a replica layer.
  scoped_refptr<Layer> replica_layer = Layer::Create();
  layer_tree_root->children()[1]->SetReplicaLayer(replica_layer.get());

  // Third child gets a replica layer with a mask layer.
  scoped_refptr<Layer> replica_layer_with_mask = Layer::Create();
  scoped_refptr<Layer> replica_mask_layer = Layer::Create();
  replica_layer_with_mask->SetMaskLayer(replica_mask_layer.get());
  layer_tree_root->children()[2]->
      SetReplicaLayer(replica_layer_with_mask.get());

  host_->SetRootLayer(layer_tree_root);

  scoped_ptr<LayerImpl> layer_impl_tree_root =
      TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
                                         scoped_ptr<LayerImpl>(),
                                         host_->active_tree());

  ExpectTreesAreIdentical(layer_tree_root.get(),
                          layer_impl_tree_root.get(),
                          host_->active_tree());

  // Remove the mask layer.
  layer_tree_root->children()[0]->SetMaskLayer(NULL);
  layer_impl_tree_root =
      TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
                                         layer_impl_tree_root.Pass(),
                                         host_->active_tree());
  ExpectTreesAreIdentical(layer_tree_root.get(),
                          layer_impl_tree_root.get(),
                          host_->active_tree());

  // Remove the replica layer.
  layer_tree_root->children()[1]->SetReplicaLayer(NULL);
  layer_impl_tree_root =
      TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
                                         layer_impl_tree_root.Pass(),
                                         host_->active_tree());
  ExpectTreesAreIdentical(layer_tree_root.get(),
                          layer_impl_tree_root.get(),
                          host_->active_tree());

  // Remove the replica mask.
  replica_layer_with_mask->SetMaskLayer(NULL);
  layer_impl_tree_root =
      TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
                                         layer_impl_tree_root.Pass(),
                                         host_->active_tree());
  ExpectTreesAreIdentical(layer_tree_root.get(),
                          layer_impl_tree_root.get(),
                          host_->active_tree());
}

TEST_F(TreeSynchronizerTest, SynchronizeAnimations) {
  LayerTreeSettings settings;
  FakeProxy proxy;
  DebugScopedSetImplThread impl(&proxy);
  FakeRenderingStatsInstrumentation stats_instrumentation;
  scoped_ptr<LayerTreeHostImpl> host_impl =
      LayerTreeHostImpl::Create(settings,
                                NULL,
                                &proxy,
                                &stats_instrumentation);

  scoped_refptr<Layer> layer_tree_root = Layer::Create();
  host_->SetRootLayer(layer_tree_root);

  layer_tree_root->SetLayerAnimationControllerForTest(
      FakeLayerAnimationController::Create());

  EXPECT_FALSE(static_cast<FakeLayerAnimationController*>(
      layer_tree_root->layer_animation_controller())->SynchronizedAnimations());

  scoped_ptr<LayerImpl> layer_impl_tree_root =
      TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
                                         scoped_ptr<LayerImpl>(),
                                         host_->active_tree());
  TreeSynchronizer::PushProperties(layer_tree_root.get(),
                                   layer_impl_tree_root.get());
  layer_impl_tree_root =
      TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
                                         layer_impl_tree_root.Pass(),
                                         host_->active_tree());

  EXPECT_TRUE(static_cast<FakeLayerAnimationController*>(
      layer_tree_root->layer_animation_controller())->SynchronizedAnimations());
}

TEST_F(TreeSynchronizerTest, SynchronizeScrollParent) {
  LayerTreeSettings settings;
  FakeProxy proxy;
  DebugScopedSetImplThread impl(&proxy);
  FakeRenderingStatsInstrumentation stats_instrumentation;
  scoped_ptr<LayerTreeHostImpl> host_impl =
      LayerTreeHostImpl::Create(settings,
                                NULL,
                                &proxy,
                                &stats_instrumentation);

  scoped_refptr<Layer> layer_tree_root = Layer::Create();
  scoped_refptr<Layer> scroll_parent = Layer::Create();
  layer_tree_root->AddChild(scroll_parent);
  layer_tree_root->AddChild(Layer::Create());
  layer_tree_root->AddChild(Layer::Create());

  host_->SetRootLayer(layer_tree_root);

  // First child is the second and third child's scroll parent.
  layer_tree_root->children()[1]->SetScrollParent(scroll_parent);
  layer_tree_root->children()[2]->SetScrollParent(scroll_parent);

  scoped_ptr<LayerImpl> layer_impl_tree_root =
      TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
                                         scoped_ptr<LayerImpl>(),
                                         host_impl->active_tree());
  TreeSynchronizer::PushProperties(layer_tree_root.get(),
                                   layer_impl_tree_root.get());
  ExpectTreesAreIdentical(layer_tree_root.get(),
                          layer_impl_tree_root.get(),
                          host_impl->active_tree());

  // Remove the first scroll child.
  layer_tree_root->children()[1]->RemoveFromParent();
  layer_impl_tree_root =
      TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
                                         layer_impl_tree_root.Pass(),
                                         host_impl->active_tree());
  TreeSynchronizer::PushProperties(layer_tree_root.get(),
                                   layer_impl_tree_root.get());
  ExpectTreesAreIdentical(layer_tree_root.get(),
                          layer_impl_tree_root.get(),
                          host_impl->active_tree());

  // Add an additional scroll layer.
  scoped_refptr<Layer> additional_scroll_child = Layer::Create();
  layer_tree_root->AddChild(additional_scroll_child);
  additional_scroll_child->SetScrollParent(scroll_parent);
  layer_impl_tree_root =
      TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
                                         layer_impl_tree_root.Pass(),
                                         host_impl->active_tree());
  TreeSynchronizer::PushProperties(layer_tree_root.get(),
                                   layer_impl_tree_root.get());
  ExpectTreesAreIdentical(layer_tree_root.get(),
                          layer_impl_tree_root.get(),
                          host_impl->active_tree());

  // Remove the scroll parent.
  scroll_parent->RemoveFromParent();
  scroll_parent = NULL;
  layer_impl_tree_root =
      TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
                                         layer_impl_tree_root.Pass(),
                                         host_impl->active_tree());
  TreeSynchronizer::PushProperties(layer_tree_root.get(),
                                   layer_impl_tree_root.get());
  ExpectTreesAreIdentical(layer_tree_root.get(),
                          layer_impl_tree_root.get(),
                          host_impl->active_tree());

  // The scroll children should have been unhooked.
  EXPECT_EQ(2u, layer_tree_root->children().size());
  EXPECT_FALSE(layer_tree_root->children()[0]->scroll_parent());
  EXPECT_FALSE(layer_tree_root->children()[1]->scroll_parent());
}

TEST_F(TreeSynchronizerTest, SynchronizeClipParent) {
  LayerTreeSettings settings;
  FakeProxy proxy;
  DebugScopedSetImplThread impl(&proxy);
  FakeRenderingStatsInstrumentation stats_instrumentation;
  scoped_ptr<LayerTreeHostImpl> host_impl =
      LayerTreeHostImpl::Create(settings,
                                NULL,
                                &proxy,
                                &stats_instrumentation);

  scoped_refptr<Layer> layer_tree_root = Layer::Create();
  scoped_refptr<Layer> clip_parent = Layer::Create();
  scoped_refptr<Layer> intervening = Layer::Create();
  scoped_refptr<Layer> clip_child1 = Layer::Create();
  scoped_refptr<Layer> clip_child2 = Layer::Create();
  layer_tree_root->AddChild(clip_parent);
  clip_parent->AddChild(intervening);
  intervening->AddChild(clip_child1);
  intervening->AddChild(clip_child2);

  host_->SetRootLayer(layer_tree_root);

  // First child is the second and third child's scroll parent.
  clip_child1->SetClipParent(clip_parent);
  clip_child2->SetClipParent(clip_parent);

  scoped_ptr<LayerImpl> layer_impl_tree_root =
      TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
                                         scoped_ptr<LayerImpl>(),
                                         host_impl->active_tree());
  TreeSynchronizer::PushProperties(layer_tree_root.get(),
                                   layer_impl_tree_root.get());
  ExpectTreesAreIdentical(layer_tree_root.get(),
                          layer_impl_tree_root.get(),
                          host_impl->active_tree());

  // Remove the first clip child.
  clip_child1->RemoveFromParent();
  clip_child1 = NULL;

  layer_impl_tree_root =
      TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
                                         layer_impl_tree_root.Pass(),
                                         host_impl->active_tree());
  TreeSynchronizer::PushProperties(layer_tree_root.get(),
                                   layer_impl_tree_root.get());
  ExpectTreesAreIdentical(layer_tree_root.get(),
                          layer_impl_tree_root.get(),
                          host_impl->active_tree());

  // Add an additional clip child.
  scoped_refptr<Layer> additional_clip_child = Layer::Create();
  intervening->AddChild(additional_clip_child);
  additional_clip_child->SetClipParent(clip_parent);
  layer_impl_tree_root =
      TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
                                         layer_impl_tree_root.Pass(),
                                         host_impl->active_tree());
  TreeSynchronizer::PushProperties(layer_tree_root.get(),
                                   layer_impl_tree_root.get());
  ExpectTreesAreIdentical(layer_tree_root.get(),
                          layer_impl_tree_root.get(),
                          host_impl->active_tree());

  // Remove the nearest clipping ancestor.
  clip_parent->RemoveFromParent();
  clip_parent = NULL;
  layer_impl_tree_root =
      TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
                                         layer_impl_tree_root.Pass(),
                                         host_impl->active_tree());
  TreeSynchronizer::PushProperties(layer_tree_root.get(),
                                   layer_impl_tree_root.get());
  ExpectTreesAreIdentical(layer_tree_root.get(),
                          layer_impl_tree_root.get(),
                          host_impl->active_tree());

  // The clip children should have been unhooked.
  EXPECT_EQ(2u, intervening->children().size());
  EXPECT_FALSE(clip_child2->clip_parent());
  EXPECT_FALSE(additional_clip_child->clip_parent());
}

}  // namespace
}  // namespace cc
