// 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 "base/format_macros.h"
#include "base/strings/stringprintf.h"
#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/test/test_shared_bitmap_manager.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_);
  }

  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()) {
    SCOPED_TRACE("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()) {
    SCOPED_TRACE("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) {
    SCOPED_TRACE(base::StringPrintf("child layer %" PRIuS, i).c_str());
    ExpectTreesAreIdentical(
        layer_children[i].get(), layer_impl_children[i], tree_impl);
  }
}

class TreeSynchronizerTest : public testing::Test {
 public:
  TreeSynchronizerTest()
      : client_(FakeLayerTreeHostClient::DIRECT_3D),
        host_(FakeLayerTreeHost::Create(&client_)) {}

 protected:
  FakeLayerTreeHostClient client_;
  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<SharedBitmapManager> shared_bitmap_manager(
      new TestSharedBitmapManager());
  scoped_ptr<LayerTreeHostImpl> host_impl =
      LayerTreeHostImpl::Create(settings,
                                NULL,
                                &proxy,
                                &stats_instrumentation,
                                shared_bitmap_manager.get(),
                                0);

  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<SharedBitmapManager> shared_bitmap_manager(
      new TestSharedBitmapManager());
  scoped_ptr<LayerTreeHostImpl> host_impl =
      LayerTreeHostImpl::Create(settings,
                                NULL,
                                &proxy,
                                &stats_instrumentation,
                                shared_bitmap_manager.get(),
                                0);

  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.get());
  layer_tree_root->children()[2]->SetScrollParent(scroll_parent.get());

  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());
  {
    SCOPED_TRACE("case one");
    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());
  {
    SCOPED_TRACE("case two");
    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.get());
  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());
  {
    SCOPED_TRACE("case three");
    ExpectTreesAreIdentical(layer_tree_root.get(),
                            layer_impl_tree_root.get(),
                            host_impl->active_tree());
  }
}

TEST_F(TreeSynchronizerTest, SynchronizeClipParent) {
  LayerTreeSettings settings;
  FakeProxy proxy;
  DebugScopedSetImplThread impl(&proxy);
  FakeRenderingStatsInstrumentation stats_instrumentation;
  scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
      new TestSharedBitmapManager());
  scoped_ptr<LayerTreeHostImpl> host_impl =
      LayerTreeHostImpl::Create(settings,
                                NULL,
                                &proxy,
                                &stats_instrumentation,
                                shared_bitmap_manager.get(),
                                0);

  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.get());
  clip_child2->SetClipParent(clip_parent.get());

  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.get());
  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
