// 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/layers/layer.h"

#include <stddef.h>

#include "base/bind.h"
#include "base/stl_util.h"
#include "base/threading/thread_task_runner_handle.h"
#include "cc/animation/animation_host.h"
#include "cc/animation/animation_id_provider.h"
#include "cc/animation/keyframed_animation_curve.h"
#include "cc/base/math_util.h"
#include "cc/input/main_thread_scrolling_reason.h"
#include "cc/layers/layer_impl.h"
#include "cc/layers/picture_layer.h"
#include "cc/layers/solid_color_scrollbar_layer.h"
#include "cc/test/animation_test_common.h"
#include "cc/test/fake_content_layer_client.h"
#include "cc/test/fake_impl_task_runner_provider.h"
#include "cc/test/fake_layer_tree_host.h"
#include "cc/test/fake_layer_tree_host_client.h"
#include "cc/test/fake_layer_tree_host_impl.h"
#include "cc/test/geometry_test_utils.h"
#include "cc/test/layer_test_common.h"
#include "cc/test/stub_layer_tree_host_single_thread_client.h"
#include "cc/test/test_task_graph_runner.h"
#include "cc/trees/layer_tree_host.h"
#include "cc/trees/single_thread_proxy.h"
#include "cc/trees/transform_node.h"
#include "components/viz/common/frame_sinks/copy_output_request.h"
#include "components/viz/common/frame_sinks/copy_output_result.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/core/SkColor.h"
#include "ui/gfx/geometry/point3_f.h"
#include "ui/gfx/geometry/point_f.h"
#include "ui/gfx/geometry/scroll_offset.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/geometry/vector2d_f.h"
#include "ui/gfx/transform.h"

using ::testing::AnyNumber;
using ::testing::AtLeast;
using ::testing::Mock;
using ::testing::StrictMock;
using ::testing::_;

#define EXPECT_SET_NEEDS_FULL_TREE_SYNC(expect, code_to_test)               \
  do {                                                                      \
    EXPECT_CALL(*layer_tree_host_, SetNeedsFullTreeSync()).Times((expect)); \
    code_to_test;                                                           \
    Mock::VerifyAndClearExpectations(layer_tree_host_.get());               \
  } while (false)

#define EXECUTE_AND_VERIFY_SUBTREE_CHANGED(code_to_test)                       \
  code_to_test;                                                                \
  root->layer_tree_host()->BuildPropertyTreesForTesting();                     \
  EXPECT_TRUE(root->subtree_property_changed());                               \
  EXPECT_TRUE(base::ContainsKey(                                               \
      root->layer_tree_host()->LayersThatShouldPushProperties(), root.get())); \
  EXPECT_TRUE(child->subtree_property_changed());                              \
  EXPECT_TRUE(base::ContainsKey(                                               \
      child->layer_tree_host()->LayersThatShouldPushProperties(),              \
      child.get()));                                                           \
  EXPECT_TRUE(grand_child->subtree_property_changed());                        \
  EXPECT_TRUE(base::ContainsKey(                                               \
      grand_child->layer_tree_host()->LayersThatShouldPushProperties(),        \
      grand_child.get()));

#define EXECUTE_AND_VERIFY_SUBTREE_NOT_CHANGED(code_to_test)                   \
  code_to_test;                                                                \
  root->layer_tree_host()->BuildPropertyTreesForTesting();                     \
  EXPECT_FALSE(root->subtree_property_changed());                              \
  EXPECT_FALSE(base::ContainsKey(                                              \
      root->layer_tree_host()->LayersThatShouldPushProperties(), root.get())); \
  EXPECT_FALSE(child->subtree_property_changed());                             \
  EXPECT_FALSE(base::ContainsKey(                                              \
      child->layer_tree_host()->LayersThatShouldPushProperties(),              \
      child.get()));                                                           \
  EXPECT_FALSE(grand_child->subtree_property_changed());                       \
  EXPECT_FALSE(base::ContainsKey(                                              \
      grand_child->layer_tree_host()->LayersThatShouldPushProperties(),        \
      grand_child.get()));

#define EXECUTE_AND_VERIFY_SUBTREE_CHANGES_RESET(code_to_test) \
  code_to_test;                                                \
  EXPECT_FALSE(root->subtree_property_changed());              \
  EXPECT_FALSE(child->subtree_property_changed());             \
  EXPECT_FALSE(grand_child->subtree_property_changed());

namespace cc {

namespace {

static auto kArbitrarySourceId1 =
    base::UnguessableToken::Deserialize(0xdead, 0xbeef);
static auto kArbitrarySourceId2 =
    base::UnguessableToken::Deserialize(0xdead, 0xbee0);

class MockLayerTreeHost : public LayerTreeHost {
 public:
  MockLayerTreeHost(LayerTreeHostSingleThreadClient* single_thread_client,
                    LayerTreeHost::InitParams params)
      : LayerTreeHost(std::move(params), CompositorMode::SINGLE_THREADED) {
    InitializeSingleThreaded(single_thread_client,
                             base::ThreadTaskRunnerHandle::Get());
  }

  MOCK_METHOD0(SetNeedsCommit, void());
  MOCK_METHOD0(SetNeedsUpdateLayers, void());
  MOCK_METHOD0(SetNeedsFullTreeSync, void());
};

bool LayerNeedsDisplay(Layer* layer) {
  return !layer->update_rect().IsEmpty();
}

class LayerTest : public testing::Test {
 public:
  LayerTest()
      : host_impl_(LayerTreeSettings(),
                   &task_runner_provider_,
                   &task_graph_runner_) {
    timeline_impl_ =
        AnimationTimeline::Create(AnimationIdProvider::NextTimelineId());
    timeline_impl_->set_is_impl_only(true);
    host_impl_.animation_host()->AddAnimationTimeline(timeline_impl_);
  }

  const LayerTreeSettings& settings() { return settings_; }
  scoped_refptr<AnimationTimeline> timeline_impl() { return timeline_impl_; }

 protected:
  void SetUp() override {
    animation_host_ = AnimationHost::CreateForTesting(ThreadInstance::MAIN);

    LayerTreeHost::InitParams params;
    params.client = &fake_client_;
    params.settings = &settings_;
    params.task_graph_runner = &task_graph_runner_;
    params.mutator_host = animation_host_.get();

    layer_tree_host_.reset(new StrictMock<MockLayerTreeHost>(
        &single_thread_client_, std::move(params)));
  }

  void TearDown() override {
    Mock::VerifyAndClearExpectations(layer_tree_host_.get());
    EXPECT_CALL(*layer_tree_host_, SetNeedsFullTreeSync()).Times(AnyNumber());
    parent_ = nullptr;
    child1_ = nullptr;
    child2_ = nullptr;
    child3_ = nullptr;
    grand_child1_ = nullptr;
    grand_child2_ = nullptr;
    grand_child3_ = nullptr;

    layer_tree_host_->SetRootLayer(nullptr);
    animation_host_->SetMutatorHostClient(nullptr);
    layer_tree_host_ = nullptr;
    animation_host_ = nullptr;
  }

  void SimulateCommitForLayer(Layer* layer) {
    layer->PushPropertiesTo(
        layer->CreateLayerImpl(host_impl_.active_tree()).get());
  }

  void VerifyTestTreeInitialState() const {
    ASSERT_EQ(3U, parent_->children().size());
    EXPECT_EQ(child1_, parent_->children()[0]);
    EXPECT_EQ(child2_, parent_->children()[1]);
    EXPECT_EQ(child3_, parent_->children()[2]);
    EXPECT_EQ(parent_.get(), child1_->parent());
    EXPECT_EQ(parent_.get(), child2_->parent());
    EXPECT_EQ(parent_.get(), child3_->parent());

    ASSERT_EQ(2U, child1_->children().size());
    EXPECT_EQ(grand_child1_, child1_->children()[0]);
    EXPECT_EQ(grand_child2_, child1_->children()[1]);
    EXPECT_EQ(child1_.get(), grand_child1_->parent());
    EXPECT_EQ(child1_.get(), grand_child2_->parent());

    ASSERT_EQ(1U, child2_->children().size());
    EXPECT_EQ(grand_child3_, child2_->children()[0]);
    EXPECT_EQ(child2_.get(), grand_child3_->parent());

    ASSERT_EQ(0U, child3_->children().size());
  }

  void CreateSimpleTestTree() {
    parent_ = Layer::Create();
    child1_ = Layer::Create();
    child2_ = Layer::Create();
    child3_ = Layer::Create();
    grand_child1_ = Layer::Create();
    grand_child2_ = Layer::Create();
    grand_child3_ = Layer::Create();

    EXPECT_CALL(*layer_tree_host_, SetNeedsFullTreeSync()).Times(AnyNumber());
    layer_tree_host_->SetRootLayer(parent_);

    parent_->AddChild(child1_);
    parent_->AddChild(child2_);
    parent_->AddChild(child3_);
    child1_->AddChild(grand_child1_);
    child1_->AddChild(grand_child2_);
    child2_->AddChild(grand_child3_);

    Mock::VerifyAndClearExpectations(layer_tree_host_.get());

    VerifyTestTreeInitialState();
  }

  FakeImplTaskRunnerProvider task_runner_provider_;
  TestTaskGraphRunner task_graph_runner_;
  FakeLayerTreeHostImpl host_impl_;

  StubLayerTreeHostSingleThreadClient single_thread_client_;
  FakeLayerTreeHostClient fake_client_;
  std::unique_ptr<StrictMock<MockLayerTreeHost>> layer_tree_host_;
  std::unique_ptr<AnimationHost> animation_host_;
  scoped_refptr<Layer> parent_;
  scoped_refptr<Layer> child1_;
  scoped_refptr<Layer> child2_;
  scoped_refptr<Layer> child3_;
  scoped_refptr<Layer> grand_child1_;
  scoped_refptr<Layer> grand_child2_;
  scoped_refptr<Layer> grand_child3_;

  scoped_refptr<AnimationTimeline> timeline_impl_;

  LayerTreeSettings settings_;
};

TEST_F(LayerTest, BasicCreateAndDestroy) {
  scoped_refptr<Layer> test_layer = Layer::Create();
  ASSERT_TRUE(test_layer.get());

  EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(0);
  test_layer->SetLayerTreeHost(layer_tree_host_.get());
  Mock::VerifyAndClearExpectations(layer_tree_host_.get());

  EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(0);
  test_layer->SetLayerTreeHost(nullptr);
}

TEST_F(LayerTest, LayerPropertyChangedForSubtree) {
  EXPECT_CALL(*layer_tree_host_, SetNeedsFullTreeSync()).Times(AtLeast(1));
  scoped_refptr<Layer> root = Layer::Create();
  scoped_refptr<Layer> child = Layer::Create();
  scoped_refptr<Layer> child2 = Layer::Create();
  scoped_refptr<Layer> grand_child = Layer::Create();
  FakeContentLayerClient client;
  scoped_refptr<PictureLayer> mask_layer1 = PictureLayer::Create(&client);

  layer_tree_host_->SetRootLayer(root);
  root->AddChild(child);
  root->AddChild(child2);
  child->AddChild(grand_child);
  EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
  child->SetForceRenderSurfaceForTesting(true);
  EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
  child2->SetScrollParent(grand_child.get());

  // Resizing without a mask layer or masks_to_bounds, should only require a
  // regular commit. Note that a layer and its mask should match sizes, but
  // the mask isn't in the tree yet, so won't need its own commit.
  gfx::Size arbitrary_size = gfx::Size(1, 2);
  EXPECT_SET_NEEDS_COMMIT(1, root->SetBounds(arbitrary_size));
  EXPECT_SET_NEEDS_COMMIT(0, mask_layer1->SetBounds(arbitrary_size));
  EXPECT_CALL(*layer_tree_host_, SetNeedsFullTreeSync()).Times(1);
  EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetMaskLayer(mask_layer1.get()));

  // Set up the impl layers after the full tree is constructed, including the
  // mask layer.
  SkBlendMode arbitrary_blend_mode = SkBlendMode::kMultiply;
  std::unique_ptr<LayerImpl> root_impl =
      LayerImpl::Create(host_impl_.active_tree(), root->id());
  std::unique_ptr<LayerImpl> child_impl =
      LayerImpl::Create(host_impl_.active_tree(), child->id());
  std::unique_ptr<LayerImpl> child2_impl =
      LayerImpl::Create(host_impl_.active_tree(), child2->id());
  std::unique_ptr<LayerImpl> grand_child_impl =
      LayerImpl::Create(host_impl_.active_tree(), grand_child->id());
  std::unique_ptr<LayerImpl> mask_layer1_impl =
      mask_layer1->CreateLayerImpl(host_impl_.active_tree());

  EXECUTE_AND_VERIFY_SUBTREE_CHANGES_RESET(
      root->PushPropertiesTo(root_impl.get());
      child->PushPropertiesTo(child_impl.get());
      child2->PushPropertiesTo(child2_impl.get());
      grand_child->PushPropertiesTo(grand_child_impl.get());
      mask_layer1->PushPropertiesTo(mask_layer1_impl.get()););

  // Once there is a mask layer, resizes require subtree properties to update.
  arbitrary_size = gfx::Size(11, 22);
  EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(2);
  EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetBounds(arbitrary_size));
  EXECUTE_AND_VERIFY_SUBTREE_CHANGED(mask_layer1->SetBounds(arbitrary_size));

  EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1);
  EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetMasksToBounds(true));
  EXECUTE_AND_VERIFY_SUBTREE_CHANGES_RESET(
      root->PushPropertiesTo(root_impl.get());
      child->PushPropertiesTo(child_impl.get());
      child2->PushPropertiesTo(child2_impl.get());
      grand_child->PushPropertiesTo(grand_child_impl.get()));

  EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1);
  EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetContentsOpaque(true));
  EXECUTE_AND_VERIFY_SUBTREE_CHANGES_RESET(
      root->PushPropertiesTo(root_impl.get());
      child->PushPropertiesTo(child_impl.get());
      child2->PushPropertiesTo(child2_impl.get());
      grand_child->PushPropertiesTo(grand_child_impl.get()));

  EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1);
  EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetShouldFlattenTransform(false));
  EXECUTE_AND_VERIFY_SUBTREE_CHANGES_RESET(
      root->PushPropertiesTo(root_impl.get());
      child->PushPropertiesTo(child_impl.get());
      child2->PushPropertiesTo(child2_impl.get());
      grand_child->PushPropertiesTo(grand_child_impl.get()));

  EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1);
  EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->Set3dSortingContextId(1));
  EXECUTE_AND_VERIFY_SUBTREE_CHANGES_RESET(
      root->PushPropertiesTo(root_impl.get());
      child->PushPropertiesTo(child_impl.get());
      child2->PushPropertiesTo(child2_impl.get());
      grand_child->PushPropertiesTo(grand_child_impl.get()));

  EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1);
  EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetTrilinearFiltering(true));
  EXECUTE_AND_VERIFY_SUBTREE_CHANGES_RESET(
      root->PushPropertiesTo(root_impl.get());
      child->PushPropertiesTo(child_impl.get());
      child2->PushPropertiesTo(child2_impl.get());
      grand_child->PushPropertiesTo(grand_child_impl.get()));

  EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1);
  EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetTrilinearFiltering(false));
  EXECUTE_AND_VERIFY_SUBTREE_CHANGES_RESET(
      root->PushPropertiesTo(root_impl.get());
      child->PushPropertiesTo(child_impl.get());
      child2->PushPropertiesTo(child2_impl.get());
      grand_child->PushPropertiesTo(grand_child_impl.get()));

  EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1);
  const std::array<uint32_t, 4> radii{1, 2, 3, 4};
  EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetRoundedCorner(radii));
  EXECUTE_AND_VERIFY_SUBTREE_CHANGES_RESET(
      root->PushPropertiesTo(root_impl.get());
      child->PushPropertiesTo(child_impl.get());
      child2->PushPropertiesTo(child2_impl.get());
      grand_child->PushPropertiesTo(grand_child_impl.get()));

  EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1);
  EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetIsFastRoundedCorner(true));
  EXECUTE_AND_VERIFY_SUBTREE_CHANGES_RESET(
      root->PushPropertiesTo(root_impl.get());
      child->PushPropertiesTo(child_impl.get());
      child2->PushPropertiesTo(child2_impl.get());
      grand_child->PushPropertiesTo(grand_child_impl.get()));

  EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1);
  EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetRoundedCorner({0, 0, 0, 0}));
  EXECUTE_AND_VERIFY_SUBTREE_CHANGES_RESET(
      root->PushPropertiesTo(root_impl.get());
      child->PushPropertiesTo(child_impl.get());
      child2->PushPropertiesTo(child2_impl.get());
      grand_child->PushPropertiesTo(grand_child_impl.get()));

  EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1);
  EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetDoubleSided(false));
  EXECUTE_AND_VERIFY_SUBTREE_CHANGES_RESET(
      root->PushPropertiesTo(root_impl.get());
      child->PushPropertiesTo(child_impl.get());
      child2->PushPropertiesTo(child2_impl.get());
      grand_child->PushPropertiesTo(grand_child_impl.get()));

  EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1);
  EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetHideLayerAndSubtree(true));
  EXECUTE_AND_VERIFY_SUBTREE_CHANGES_RESET(
      root->PushPropertiesTo(root_impl.get());
      child->PushPropertiesTo(child_impl.get());
      child2->PushPropertiesTo(child2_impl.get());
      grand_child->PushPropertiesTo(grand_child_impl.get()));

  EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1);
  EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetBlendMode(arbitrary_blend_mode));
  EXECUTE_AND_VERIFY_SUBTREE_CHANGES_RESET(
      root->PushPropertiesTo(root_impl.get());
      child->PushPropertiesTo(child_impl.get());
      child2->PushPropertiesTo(child2_impl.get());
      grand_child->PushPropertiesTo(grand_child_impl.get()));

  // Should be a different size than previous call, to ensure it marks tree
  // changed.
  arbitrary_size = gfx::Size(111, 222);
  EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(2);
  EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetBounds(arbitrary_size));
  EXECUTE_AND_VERIFY_SUBTREE_CHANGED(mask_layer1->SetBounds(arbitrary_size));
  EXECUTE_AND_VERIFY_SUBTREE_CHANGES_RESET(
      root->PushPropertiesTo(root_impl.get());
      child->PushPropertiesTo(child_impl.get());
      child2->PushPropertiesTo(child2_impl.get());
      grand_child->PushPropertiesTo(grand_child_impl.get()));

  FilterOperations arbitrary_filters;
  arbitrary_filters.Append(FilterOperation::CreateOpacityFilter(0.5f));
  EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1);
  EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetFilters(arbitrary_filters));
  EXECUTE_AND_VERIFY_SUBTREE_CHANGES_RESET(
      root->PushPropertiesTo(root_impl.get());
      child->PushPropertiesTo(child_impl.get());
      child2->PushPropertiesTo(child2_impl.get());
      grand_child->PushPropertiesTo(grand_child_impl.get()));

  EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1);
  EXECUTE_AND_VERIFY_SUBTREE_CHANGED(
      root->SetBackdropFilters(arbitrary_filters));
  EXECUTE_AND_VERIFY_SUBTREE_CHANGES_RESET(
      root->PushPropertiesTo(root_impl.get());
      child->PushPropertiesTo(child_impl.get());
      child2->PushPropertiesTo(child2_impl.get());
      grand_child->PushPropertiesTo(grand_child_impl.get()));

  gfx::PointF arbitrary_point_f = gfx::PointF(0.125f, 0.25f);
  EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1);
  root->SetPosition(arbitrary_point_f);
  TransformNode* node = layer_tree_host_->property_trees()->transform_tree.Node(
      root->transform_tree_index());
  EXPECT_TRUE(node->transform_changed);
  EXECUTE_AND_VERIFY_SUBTREE_CHANGES_RESET(
      root->PushPropertiesTo(root_impl.get());
      child->PushPropertiesTo(child_impl.get());
      child2->PushPropertiesTo(child2_impl.get());
      grand_child->PushPropertiesTo(grand_child_impl.get());
      layer_tree_host_->property_trees()->ResetAllChangeTracking());
  EXPECT_FALSE(node->transform_changed);

  EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1);
  child->SetPosition(arbitrary_point_f);
  node = layer_tree_host_->property_trees()->transform_tree.Node(
      child->transform_tree_index());
  EXPECT_TRUE(node->transform_changed);
  // child2 is not in the subtree of child, but its scroll parent is. So, its
  // to_screen will be effected by change in position of child2.
  layer_tree_host_->property_trees()->transform_tree.UpdateTransforms(
      child2->transform_tree_index());
  node = layer_tree_host_->property_trees()->transform_tree.Node(
      child2->transform_tree_index());
  EXPECT_TRUE(node->transform_changed);
  EXECUTE_AND_VERIFY_SUBTREE_CHANGES_RESET(
      child->PushPropertiesTo(child_impl.get());
      grand_child->PushPropertiesTo(grand_child_impl.get());
      layer_tree_host_->property_trees()->ResetAllChangeTracking());
  node = layer_tree_host_->property_trees()->transform_tree.Node(
      child->transform_tree_index());
  EXPECT_FALSE(node->transform_changed);

  gfx::Point3F arbitrary_point_3f = gfx::Point3F(0.125f, 0.25f, 0.f);
  EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1);
  root->SetTransformOrigin(arbitrary_point_3f);
  node = layer_tree_host_->property_trees()->transform_tree.Node(
      root->transform_tree_index());
  EXPECT_TRUE(node->transform_changed);
  EXECUTE_AND_VERIFY_SUBTREE_CHANGES_RESET(
      root->PushPropertiesTo(root_impl.get());
      child->PushPropertiesTo(child_impl.get());
      child2->PushPropertiesTo(child2_impl.get());
      grand_child->PushPropertiesTo(grand_child_impl.get());
      layer_tree_host_->property_trees()->ResetAllChangeTracking());

  gfx::Transform arbitrary_transform;
  arbitrary_transform.Scale3d(0.1f, 0.2f, 0.3f);
  EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1);
  root->SetTransform(arbitrary_transform);
  node = layer_tree_host_->property_trees()->transform_tree.Node(
      root->transform_tree_index());
  EXPECT_TRUE(node->transform_changed);
}

TEST_F(LayerTest, AddAndRemoveChild) {
  scoped_refptr<Layer> parent = Layer::Create();
  scoped_refptr<Layer> child = Layer::Create();

  // Upon creation, layers should not have children or parent.
  ASSERT_EQ(0U, parent->children().size());
  EXPECT_FALSE(child->parent());

  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, layer_tree_host_->SetRootLayer(parent));
  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, parent->AddChild(child));

  ASSERT_EQ(1U, parent->children().size());
  EXPECT_EQ(child.get(), parent->children()[0]);
  EXPECT_EQ(parent.get(), child->parent());
  EXPECT_EQ(parent.get(), child->RootLayer());

  EXPECT_SET_NEEDS_FULL_TREE_SYNC(AtLeast(1), child->RemoveFromParent());
}

TEST_F(LayerTest, AddSameChildTwice) {
  EXPECT_CALL(*layer_tree_host_, SetNeedsFullTreeSync()).Times(AtLeast(1));

  scoped_refptr<Layer> parent = Layer::Create();
  scoped_refptr<Layer> child = Layer::Create();

  layer_tree_host_->SetRootLayer(parent);

  ASSERT_EQ(0u, parent->children().size());

  parent->AddChild(child);
  ASSERT_EQ(1u, parent->children().size());
  EXPECT_EQ(parent.get(), child->parent());

  parent->AddChild(child);
  ASSERT_EQ(1u, parent->children().size());
  EXPECT_EQ(parent.get(), child->parent());
}

TEST_F(LayerTest, ReorderChildren) {
  EXPECT_CALL(*layer_tree_host_, SetNeedsFullTreeSync()).Times(AtLeast(1));

  scoped_refptr<Layer> parent = Layer::Create();
  scoped_refptr<Layer> child1 = Layer::Create();
  scoped_refptr<Layer> child2 = Layer::Create();
  scoped_refptr<Layer> child3 = Layer::Create();

  layer_tree_host_->SetRootLayer(parent);

  parent->AddChild(child1);
  parent->AddChild(child2);
  parent->AddChild(child3);
  EXPECT_EQ(child1, parent->children()[0]);
  EXPECT_EQ(child2, parent->children()[1]);
  EXPECT_EQ(child3, parent->children()[2]);

  layer_tree_host_->ClearLayersThatShouldPushProperties();

  LayerList new_children_order;
  new_children_order.emplace_back(child3);
  new_children_order.emplace_back(child1);
  new_children_order.emplace_back(child2);
  parent->ReorderChildren(&new_children_order);
  EXPECT_EQ(child3, parent->children()[0]);
  EXPECT_EQ(child1, parent->children()[1]);
  EXPECT_EQ(child2, parent->children()[2]);

  for (const auto& child : parent->children()) {
    EXPECT_FALSE(base::ContainsKey(
        layer_tree_host_->LayersThatShouldPushProperties(), child.get()));
    EXPECT_TRUE(child->subtree_property_changed());
  }
}

TEST_F(LayerTest, InsertChild) {
  scoped_refptr<Layer> parent = Layer::Create();
  scoped_refptr<Layer> child1 = Layer::Create();
  scoped_refptr<Layer> child2 = Layer::Create();
  scoped_refptr<Layer> child3 = Layer::Create();
  scoped_refptr<Layer> child4 = Layer::Create();

  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, layer_tree_host_->SetRootLayer(parent));

  ASSERT_EQ(0U, parent->children().size());

  // Case 1: inserting to empty list.
  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, parent->InsertChild(child3, 0));
  ASSERT_EQ(1U, parent->children().size());
  EXPECT_EQ(child3, parent->children()[0]);
  EXPECT_EQ(parent.get(), child3->parent());

  // Case 2: inserting to beginning of list
  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, parent->InsertChild(child1, 0));
  ASSERT_EQ(2U, parent->children().size());
  EXPECT_EQ(child1, parent->children()[0]);
  EXPECT_EQ(child3, parent->children()[1]);
  EXPECT_EQ(parent.get(), child1->parent());

  // Case 3: inserting to middle of list
  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, parent->InsertChild(child2, 1));
  ASSERT_EQ(3U, parent->children().size());
  EXPECT_EQ(child1, parent->children()[0]);
  EXPECT_EQ(child2, parent->children()[1]);
  EXPECT_EQ(child3, parent->children()[2]);
  EXPECT_EQ(parent.get(), child2->parent());

  // Case 4: inserting to end of list
  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, parent->InsertChild(child4, 3));

  ASSERT_EQ(4U, parent->children().size());
  EXPECT_EQ(child1, parent->children()[0]);
  EXPECT_EQ(child2, parent->children()[1]);
  EXPECT_EQ(child3, parent->children()[2]);
  EXPECT_EQ(child4, parent->children()[3]);
  EXPECT_EQ(parent.get(), child4->parent());

  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, layer_tree_host_->SetRootLayer(nullptr));
}

TEST_F(LayerTest, InsertChildPastEndOfList) {
  scoped_refptr<Layer> parent = Layer::Create();
  scoped_refptr<Layer> child1 = Layer::Create();
  scoped_refptr<Layer> child2 = Layer::Create();

  ASSERT_EQ(0U, parent->children().size());

  // insert to an out-of-bounds index
  parent->InsertChild(child1, 53);

  ASSERT_EQ(1U, parent->children().size());
  EXPECT_EQ(child1, parent->children()[0]);

  // insert another child to out-of-bounds, when list is not already empty.
  parent->InsertChild(child2, 2459);

  ASSERT_EQ(2U, parent->children().size());
  EXPECT_EQ(child1, parent->children()[0]);
  EXPECT_EQ(child2, parent->children()[1]);
}

TEST_F(LayerTest, InsertSameChildTwice) {
  scoped_refptr<Layer> parent = Layer::Create();
  scoped_refptr<Layer> child1 = Layer::Create();
  scoped_refptr<Layer> child2 = Layer::Create();

  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, layer_tree_host_->SetRootLayer(parent));

  ASSERT_EQ(0U, parent->children().size());

  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, parent->InsertChild(child1, 0));
  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, parent->InsertChild(child2, 1));

  ASSERT_EQ(2U, parent->children().size());
  EXPECT_EQ(child1, parent->children()[0]);
  EXPECT_EQ(child2, parent->children()[1]);

  // Inserting the same child again should cause the child to be removed and
  // re-inserted at the new location.
  EXPECT_SET_NEEDS_FULL_TREE_SYNC(AtLeast(1), parent->InsertChild(child1, 1));

  // child1 should now be at the end of the list.
  ASSERT_EQ(2U, parent->children().size());
  EXPECT_EQ(child2, parent->children()[0]);
  EXPECT_EQ(child1, parent->children()[1]);

  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, layer_tree_host_->SetRootLayer(nullptr));
}

TEST_F(LayerTest, ReplaceChildWithNewChild) {
  CreateSimpleTestTree();
  scoped_refptr<Layer> child4 = Layer::Create();

  EXPECT_FALSE(child4->parent());

  EXPECT_SET_NEEDS_FULL_TREE_SYNC(
      AtLeast(1), parent_->ReplaceChild(child2_.get(), child4));
  EXPECT_FALSE(LayerNeedsDisplay(parent_.get()));
  EXPECT_FALSE(LayerNeedsDisplay(child1_.get()));
  EXPECT_FALSE(LayerNeedsDisplay(child2_.get()));
  EXPECT_FALSE(LayerNeedsDisplay(child3_.get()));
  EXPECT_FALSE(LayerNeedsDisplay(child4.get()));

  ASSERT_EQ(static_cast<size_t>(3), parent_->children().size());
  EXPECT_EQ(child1_, parent_->children()[0]);
  EXPECT_EQ(child4, parent_->children()[1]);
  EXPECT_EQ(child3_, parent_->children()[2]);
  EXPECT_EQ(parent_.get(), child4->parent());

  EXPECT_FALSE(child2_->parent());
}

TEST_F(LayerTest, ReplaceChildWithNewChildThatHasOtherParent) {
  CreateSimpleTestTree();

  // create another simple tree with test_layer and child4.
  scoped_refptr<Layer> test_layer = Layer::Create();
  scoped_refptr<Layer> child4 = Layer::Create();
  test_layer->AddChild(child4);
  ASSERT_EQ(1U, test_layer->children().size());
  EXPECT_EQ(child4, test_layer->children()[0]);
  EXPECT_EQ(test_layer.get(), child4->parent());

  EXPECT_SET_NEEDS_FULL_TREE_SYNC(
      AtLeast(1), parent_->ReplaceChild(child2_.get(), child4));

  ASSERT_EQ(3U, parent_->children().size());
  EXPECT_EQ(child1_, parent_->children()[0]);
  EXPECT_EQ(child4, parent_->children()[1]);
  EXPECT_EQ(child3_, parent_->children()[2]);
  EXPECT_EQ(parent_.get(), child4->parent());

  // test_layer should no longer have child4,
  // and child2 should no longer have a parent.
  ASSERT_EQ(0U, test_layer->children().size());
  EXPECT_FALSE(child2_->parent());
}

TEST_F(LayerTest, DeleteRemovedScrollParent) {
  scoped_refptr<Layer> parent = Layer::Create();
  scoped_refptr<Layer> child1 = Layer::Create();
  scoped_refptr<Layer> child2 = Layer::Create();

  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, layer_tree_host_->SetRootLayer(parent));

  ASSERT_EQ(0U, parent->children().size());

  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, parent->InsertChild(child1, 0));
  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, parent->InsertChild(child2, 1));

  ASSERT_EQ(2U, parent->children().size());
  EXPECT_EQ(child1, parent->children()[0]);
  EXPECT_EQ(child2, parent->children()[1]);

  EXPECT_SET_NEEDS_COMMIT(1, child1->SetScrollParent(child2.get()));

  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, child2->RemoveFromParent());

  SimulateCommitForLayer(child1.get());

  EXPECT_SET_NEEDS_COMMIT(1, child1->SetScrollParent(nullptr));
  EXPECT_TRUE(base::ContainsKey(
      layer_tree_host_->LayersThatShouldPushProperties(), child1.get()));

  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, layer_tree_host_->SetRootLayer(nullptr));
}

TEST_F(LayerTest, DeleteRemovedScrollChild) {
  scoped_refptr<Layer> parent = Layer::Create();
  scoped_refptr<Layer> child1 = Layer::Create();
  scoped_refptr<Layer> child2 = Layer::Create();

  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, layer_tree_host_->SetRootLayer(parent));

  ASSERT_EQ(0U, parent->children().size());

  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, parent->InsertChild(child1, 0));
  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, parent->InsertChild(child2, 1));

  ASSERT_EQ(2U, parent->children().size());
  EXPECT_EQ(child1, parent->children()[0]);
  EXPECT_EQ(child2, parent->children()[1]);

  EXPECT_SET_NEEDS_COMMIT(1, child1->SetScrollParent(child2.get()));

  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, child1->RemoveFromParent());
  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, layer_tree_host_->SetRootLayer(nullptr));
}

TEST_F(LayerTest, ReplaceChildWithSameChild) {
  CreateSimpleTestTree();

  // SetNeedsFullTreeSync / SetNeedsCommit should not be called because its the
  // same child.
  EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(0);
  EXPECT_CALL(*layer_tree_host_, SetNeedsFullTreeSync()).Times(0);
  parent_->ReplaceChild(child2_.get(), child2_);

  VerifyTestTreeInitialState();
}

TEST_F(LayerTest, RemoveAllChildren) {
  CreateSimpleTestTree();

  EXPECT_SET_NEEDS_FULL_TREE_SYNC(AtLeast(3), parent_->RemoveAllChildren());

  ASSERT_EQ(0U, parent_->children().size());
  EXPECT_FALSE(child1_->parent());
  EXPECT_FALSE(child2_->parent());
  EXPECT_FALSE(child3_->parent());
}

TEST_F(LayerTest, HasAncestor) {
  scoped_refptr<Layer> parent = Layer::Create();
  EXPECT_FALSE(parent->HasAncestor(parent.get()));

  scoped_refptr<Layer> child = Layer::Create();
  parent->AddChild(child);

  EXPECT_FALSE(child->HasAncestor(child.get()));
  EXPECT_TRUE(child->HasAncestor(parent.get()));
  EXPECT_FALSE(parent->HasAncestor(child.get()));

  scoped_refptr<Layer> child_child = Layer::Create();
  child->AddChild(child_child);

  EXPECT_FALSE(child_child->HasAncestor(child_child.get()));
  EXPECT_TRUE(child_child->HasAncestor(parent.get()));
  EXPECT_TRUE(child_child->HasAncestor(child.get()));
  EXPECT_FALSE(parent->HasAncestor(child.get()));
  EXPECT_FALSE(parent->HasAncestor(child_child.get()));
}

TEST_F(LayerTest, GetRootLayerAfterTreeManipulations) {
  CreateSimpleTestTree();

  // For this test we don't care about SetNeedsFullTreeSync calls.
  EXPECT_CALL(*layer_tree_host_, SetNeedsFullTreeSync()).Times(AnyNumber());

  scoped_refptr<Layer> child4 = Layer::Create();

  EXPECT_EQ(parent_.get(), parent_->RootLayer());
  EXPECT_EQ(parent_.get(), child1_->RootLayer());
  EXPECT_EQ(parent_.get(), child2_->RootLayer());
  EXPECT_EQ(parent_.get(), child3_->RootLayer());
  EXPECT_EQ(child4.get(),   child4->RootLayer());
  EXPECT_EQ(parent_.get(), grand_child1_->RootLayer());
  EXPECT_EQ(parent_.get(), grand_child2_->RootLayer());
  EXPECT_EQ(parent_.get(), grand_child3_->RootLayer());

  child1_->RemoveFromParent();

  // |child1| and its children, grand_child1 and grand_child2 are now on a
  // separate subtree.
  EXPECT_EQ(parent_.get(), parent_->RootLayer());
  EXPECT_EQ(child1_.get(), child1_->RootLayer());
  EXPECT_EQ(parent_.get(), child2_->RootLayer());
  EXPECT_EQ(parent_.get(), child3_->RootLayer());
  EXPECT_EQ(child4.get(), child4->RootLayer());
  EXPECT_EQ(child1_.get(), grand_child1_->RootLayer());
  EXPECT_EQ(child1_.get(), grand_child2_->RootLayer());
  EXPECT_EQ(parent_.get(), grand_child3_->RootLayer());

  grand_child3_->AddChild(child4);

  EXPECT_EQ(parent_.get(), parent_->RootLayer());
  EXPECT_EQ(child1_.get(), child1_->RootLayer());
  EXPECT_EQ(parent_.get(), child2_->RootLayer());
  EXPECT_EQ(parent_.get(), child3_->RootLayer());
  EXPECT_EQ(parent_.get(), child4->RootLayer());
  EXPECT_EQ(child1_.get(), grand_child1_->RootLayer());
  EXPECT_EQ(child1_.get(), grand_child2_->RootLayer());
  EXPECT_EQ(parent_.get(), grand_child3_->RootLayer());

  child2_->ReplaceChild(grand_child3_.get(), child1_);

  // |grand_child3| gets orphaned and the child1 subtree gets planted back into
  // the tree under child2.
  EXPECT_EQ(parent_.get(), parent_->RootLayer());
  EXPECT_EQ(parent_.get(), child1_->RootLayer());
  EXPECT_EQ(parent_.get(), child2_->RootLayer());
  EXPECT_EQ(parent_.get(), child3_->RootLayer());
  EXPECT_EQ(grand_child3_.get(), child4->RootLayer());
  EXPECT_EQ(parent_.get(), grand_child1_->RootLayer());
  EXPECT_EQ(parent_.get(), grand_child2_->RootLayer());
  EXPECT_EQ(grand_child3_.get(), grand_child3_->RootLayer());
}

TEST_F(LayerTest, CheckSetNeedsDisplayCausesCorrectBehavior) {
  // The semantics for SetNeedsDisplay which are tested here:
  //   1. sets NeedsDisplay flag appropriately.
  //   2. indirectly calls SetNeedsUpdate, exactly once for each call to
  //      SetNeedsDisplay.

  scoped_refptr<Layer> test_layer = Layer::Create();
  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1,
                                  layer_tree_host_->SetRootLayer(test_layer));
  EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetIsDrawable(true));

  gfx::Size test_bounds = gfx::Size(501, 508);

  gfx::Rect dirty_rect = gfx::Rect(10, 15, 1, 2);
  gfx::Rect out_of_bounds_dirty_rect = gfx::Rect(400, 405, 500, 502);

  // Before anything, test_layer should not be dirty.
  EXPECT_FALSE(LayerNeedsDisplay(test_layer.get()));

  // This is just initialization, but SetNeedsCommit behavior is verified anyway
  // to avoid warnings.
  EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetBounds(test_bounds));
  EXPECT_FALSE(LayerNeedsDisplay(test_layer.get()));

  // The real test begins here.
  SimulateCommitForLayer(test_layer.get());
  EXPECT_FALSE(LayerNeedsDisplay(test_layer.get()));

  // Case 1: Layer should accept dirty rects that go beyond its bounds.
  EXPECT_FALSE(LayerNeedsDisplay(test_layer.get()));
  EXPECT_SET_NEEDS_UPDATE(
      1, test_layer->SetNeedsDisplayRect(out_of_bounds_dirty_rect));
  EXPECT_TRUE(LayerNeedsDisplay(test_layer.get()));
  SimulateCommitForLayer(test_layer.get());

  // Case 2: SetNeedsDisplay() without the dirty rect arg.
  EXPECT_FALSE(LayerNeedsDisplay(test_layer.get()));
  EXPECT_SET_NEEDS_UPDATE(1, test_layer->SetNeedsDisplay());
  EXPECT_TRUE(LayerNeedsDisplay(test_layer.get()));
  SimulateCommitForLayer(test_layer.get());

  // Case 3: SetNeedsDisplay() with an empty rect.
  EXPECT_FALSE(LayerNeedsDisplay(test_layer.get()));
  EXPECT_SET_NEEDS_COMMIT(0, test_layer->SetNeedsDisplayRect(gfx::Rect()));
  EXPECT_FALSE(LayerNeedsDisplay(test_layer.get()));
  SimulateCommitForLayer(test_layer.get());

  // Case 4: SetNeedsDisplay() with a non-drawable layer
  EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetIsDrawable(false));
  SimulateCommitForLayer(test_layer.get());
  EXPECT_FALSE(LayerNeedsDisplay(test_layer.get()));
  EXPECT_SET_NEEDS_UPDATE(0, test_layer->SetNeedsDisplayRect(dirty_rect));
  EXPECT_TRUE(LayerNeedsDisplay(test_layer.get()));
}

TEST_F(LayerTest, TestSettingMainThreadScrollingReason) {
  scoped_refptr<Layer> test_layer = Layer::Create();
  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1,
                                  layer_tree_host_->SetRootLayer(test_layer));
  EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetIsDrawable(true));

  // sanity check of initial test condition
  EXPECT_FALSE(LayerNeedsDisplay(test_layer.get()));

  uint32_t reasons = 0, reasons_to_clear = 0, reasons_after_clearing = 0;
  reasons |= MainThreadScrollingReason::kThreadedScrollingDisabled;
  reasons |= MainThreadScrollingReason::kHandlingScrollFromMainThread;
  reasons |= MainThreadScrollingReason::kScrollbarScrolling;

  reasons_to_clear |= MainThreadScrollingReason::kHandlingScrollFromMainThread;

  reasons_after_clearing |=
      MainThreadScrollingReason::kThreadedScrollingDisabled;
  reasons_after_clearing |= MainThreadScrollingReason::kScrollbarScrolling;

  // Check that the reasons are added correctly.
  EXPECT_SET_NEEDS_COMMIT(
      1, test_layer->AddMainThreadScrollingReasons(
             MainThreadScrollingReason::kThreadedScrollingDisabled));
  EXPECT_SET_NEEDS_COMMIT(
      1, test_layer->AddMainThreadScrollingReasons(
             MainThreadScrollingReason::kHandlingScrollFromMainThread));
  EXPECT_SET_NEEDS_COMMIT(1,
                          test_layer->AddMainThreadScrollingReasons(
                              MainThreadScrollingReason::kScrollbarScrolling));
  EXPECT_EQ(reasons, test_layer->GetMainThreadScrollingReasons());

  // Check that the reasons can be selectively cleared.
  EXPECT_SET_NEEDS_COMMIT(
      1, test_layer->ClearMainThreadScrollingReasons(reasons_to_clear));
  EXPECT_EQ(reasons_after_clearing,
            test_layer->GetMainThreadScrollingReasons());

  // Check that clearing non-set reasons doesn't set needs commit.
  reasons_to_clear = 0;
  reasons_to_clear |= MainThreadScrollingReason::kFrameOverlay;
  EXPECT_SET_NEEDS_COMMIT(
      0, test_layer->ClearMainThreadScrollingReasons(reasons_to_clear));
  EXPECT_EQ(reasons_after_clearing,
            test_layer->GetMainThreadScrollingReasons());

  // Check that adding an existing condition doesn't set needs commit.
  EXPECT_SET_NEEDS_COMMIT(
      0, test_layer->AddMainThreadScrollingReasons(
             MainThreadScrollingReason::kThreadedScrollingDisabled));
}

TEST_F(LayerTest, CheckPropertyChangeCausesCorrectBehavior) {
  scoped_refptr<Layer> test_layer = Layer::Create();
  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1,
                                  layer_tree_host_->SetRootLayer(test_layer));
  EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetIsDrawable(true));

  FakeContentLayerClient client;
  scoped_refptr<PictureLayer> mask_layer1 = PictureLayer::Create(&client);

  // sanity check of initial test condition
  EXPECT_FALSE(LayerNeedsDisplay(test_layer.get()));

  // Next, test properties that should call SetNeedsCommit (but not
  // SetNeedsDisplay). All properties need to be set to new values in order for
  // SetNeedsCommit to be called.
  EXPECT_SET_NEEDS_COMMIT(
      1, test_layer->SetTransformOrigin(gfx::Point3F(1.23f, 4.56f, 0.f)));
  EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetBackgroundColor(SK_ColorLTGRAY));
  EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetMasksToBounds(true));
  EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetRoundedCorner({1, 2, 3, 4}));
  EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetIsFastRoundedCorner(true));
  EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetOpacity(0.5f));
  EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetBlendMode(SkBlendMode::kHue));
  EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetIsRootForIsolatedGroup(true));
  EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetContentsOpaque(true));
  EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetPosition(gfx::PointF(4.f, 9.f)));
  // We can use any layer pointer here since we aren't syncing for real.
  EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetScrollable(gfx::Size(1, 1)));
  EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetUserScrollable(true, false));
  EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetScrollOffset(
      gfx::ScrollOffset(10, 10)));
  EXPECT_SET_NEEDS_COMMIT(
      1, test_layer->AddMainThreadScrollingReasons(
             MainThreadScrollingReason::kThreadedScrollingDisabled));
  EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetNonFastScrollableRegion(
      Region(gfx::Rect(1, 1, 2, 2))));
  EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetTransform(
      gfx::Transform(0.0, 0.0, 0.0, 0.0, 0.0, 0.0)));
  EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetDoubleSided(false));
  TouchActionRegion touch_action_region;
  touch_action_region.Union(kTouchActionNone, gfx::Rect(10, 10));
  EXPECT_SET_NEEDS_COMMIT(
      1, test_layer->SetTouchActionRegion(std::move(touch_action_region)));
  EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetForceRenderSurfaceForTesting(true));
  EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetHideLayerAndSubtree(true));
  EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetElementId(ElementId(2)));

  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1,
                                  test_layer->SetMaskLayer(mask_layer1.get()));

  // The above tests should not have caused a change to the needs_display flag.
  EXPECT_FALSE(LayerNeedsDisplay(test_layer.get()));

  // As layers are removed from the tree, they will cause a tree sync.
  EXPECT_CALL(*layer_tree_host_, SetNeedsFullTreeSync()).Times((AnyNumber()));
}

TEST_F(LayerTest, PushPropertiesAccumulatesUpdateRect) {
  scoped_refptr<Layer> test_layer = Layer::Create();
  std::unique_ptr<LayerImpl> impl_layer =
      LayerImpl::Create(host_impl_.active_tree(), 1);

  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1,
                                  layer_tree_host_->SetRootLayer(test_layer));

  host_impl_.active_tree()->SetRootLayerForTesting(std::move(impl_layer));
  host_impl_.active_tree()->BuildLayerListForTesting();
  LayerImpl* impl_layer_ptr = host_impl_.active_tree()->LayerById(1);
  test_layer->SetNeedsDisplayRect(gfx::Rect(5, 5));
  test_layer->PushPropertiesTo(impl_layer_ptr);
  EXPECT_FLOAT_RECT_EQ(gfx::RectF(0.f, 0.f, 5.f, 5.f),
                       impl_layer_ptr->update_rect());

  // The LayerImpl's update_rect() should be accumulated here, since we did not
  // do anything to clear it.
  test_layer->SetNeedsDisplayRect(gfx::Rect(10, 10, 5, 5));
  test_layer->PushPropertiesTo(impl_layer_ptr);
  EXPECT_FLOAT_RECT_EQ(gfx::RectF(0.f, 0.f, 15.f, 15.f),
                       impl_layer_ptr->update_rect());

  // If we do clear the LayerImpl side, then the next update_rect() should be
  // fresh without accumulation.
  host_impl_.active_tree()->ResetAllChangeTracking();
  test_layer->SetNeedsDisplayRect(gfx::Rect(10, 10, 5, 5));
  test_layer->PushPropertiesTo(impl_layer_ptr);
  EXPECT_FLOAT_RECT_EQ(gfx::RectF(10.f, 10.f, 5.f, 5.f),
                       impl_layer_ptr->update_rect());
}

TEST_F(LayerTest, PushPropertiesCausesLayerPropertyChangedForTransform) {
  scoped_refptr<Layer> test_layer = Layer::Create();
  std::unique_ptr<LayerImpl> impl_layer =
      LayerImpl::Create(host_impl_.active_tree(), 1);

  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1,
                                  layer_tree_host_->SetRootLayer(test_layer));

  gfx::Transform transform;
  transform.Rotate(45.0);
  EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetTransform(transform));

  EXPECT_FALSE(impl_layer->LayerPropertyChanged());

  test_layer->PushPropertiesTo(impl_layer.get());

  EXPECT_TRUE(impl_layer->LayerPropertyChanged());
  EXPECT_FALSE(impl_layer->LayerPropertyChangedFromPropertyTrees());
  EXPECT_TRUE(impl_layer->LayerPropertyChangedNotFromPropertyTrees());
}

TEST_F(LayerTest, PushPropertiesCausesLayerPropertyChangedForRoundCorner) {
  scoped_refptr<Layer> test_layer = Layer::Create();
  test_layer->SetMasksToBounds(true);
  std::unique_ptr<LayerImpl> impl_layer =
      LayerImpl::Create(host_impl_.active_tree(), 1);

  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1,
                                  layer_tree_host_->SetRootLayer(test_layer));

  EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetRoundedCorner({1, 2, 3, 4}));

  EXPECT_FALSE(impl_layer->LayerPropertyChanged());

  test_layer->PushPropertiesTo(impl_layer.get());

  EXPECT_TRUE(impl_layer->LayerPropertyChanged());
  EXPECT_FALSE(impl_layer->LayerPropertyChangedFromPropertyTrees());
  EXPECT_TRUE(impl_layer->LayerPropertyChangedNotFromPropertyTrees());
}

TEST_F(LayerTest, PushPropertiesCausesLayerPropertyChangedForOpacity) {
  scoped_refptr<Layer> test_layer = Layer::Create();
  std::unique_ptr<LayerImpl> impl_layer =
      LayerImpl::Create(host_impl_.active_tree(), 1);

  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1,
                                  layer_tree_host_->SetRootLayer(test_layer));

  EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetOpacity(0.5f));

  EXPECT_FALSE(impl_layer->LayerPropertyChanged());

  test_layer->PushPropertiesTo(impl_layer.get());

  EXPECT_TRUE(impl_layer->LayerPropertyChanged());
  EXPECT_FALSE(impl_layer->LayerPropertyChangedFromPropertyTrees());
  EXPECT_TRUE(impl_layer->LayerPropertyChangedNotFromPropertyTrees());
}

TEST_F(LayerTest, MaskHasParent) {
  scoped_refptr<Layer> parent = Layer::Create();
  scoped_refptr<Layer> child = Layer::Create();
  FakeContentLayerClient client;
  scoped_refptr<PictureLayer> mask = PictureLayer::Create(&client);
  scoped_refptr<PictureLayer> mask_replacement = PictureLayer::Create(&client);

  parent->AddChild(child);
  child->SetMaskLayer(mask.get());

  EXPECT_EQ(parent.get(), child->parent());
  EXPECT_EQ(child.get(), mask->parent());

  child->SetMaskLayer(mask_replacement.get());
  EXPECT_EQ(nullptr, mask->parent());
  EXPECT_EQ(child.get(), mask_replacement->parent());
}

class LayerTreeHostFactory {
 public:
  std::unique_ptr<LayerTreeHost> Create(MutatorHost* mutator_host) {
    return Create(LayerTreeSettings(), mutator_host);
  }

  std::unique_ptr<LayerTreeHost> Create(LayerTreeSettings settings,
                                        MutatorHost* mutator_host) {
    LayerTreeHost::InitParams params;
    params.client = &client_;
    params.task_graph_runner = &task_graph_runner_;
    params.settings = &settings;
    params.main_task_runner = base::ThreadTaskRunnerHandle::Get();
    params.mutator_host = mutator_host;

    return LayerTreeHost::CreateSingleThreaded(&single_thread_client_,
                                               std::move(params));
  }

 private:
  FakeLayerTreeHostClient client_;
  StubLayerTreeHostSingleThreadClient single_thread_client_;
  TestTaskGraphRunner task_graph_runner_;
};

void AssertLayerTreeHostMatchesForSubtree(Layer* layer, LayerTreeHost* host) {
  EXPECT_EQ(host, layer->layer_tree_host());

  for (size_t i = 0; i < layer->children().size(); ++i)
    AssertLayerTreeHostMatchesForSubtree(layer->children()[i].get(), host);

  if (layer->mask_layer())
    AssertLayerTreeHostMatchesForSubtree(layer->mask_layer(), host);
}

class LayerLayerTreeHostTest : public testing::Test {};

TEST_F(LayerLayerTreeHostTest, EnteringTree) {
  scoped_refptr<Layer> parent = Layer::Create();
  scoped_refptr<Layer> child = Layer::Create();
  FakeContentLayerClient client;
  scoped_refptr<PictureLayer> mask = PictureLayer::Create(&client);

  // Set up a detached tree of layers. The host pointer should be nil for these
  // layers.
  parent->AddChild(child);
  child->SetMaskLayer(mask.get());

  AssertLayerTreeHostMatchesForSubtree(parent.get(), nullptr);

  LayerTreeHostFactory factory;

  auto animation_host = AnimationHost::CreateForTesting(ThreadInstance::MAIN);
  std::unique_ptr<LayerTreeHost> layer_tree_host =
      factory.Create(animation_host.get());
  // Setting the root layer should set the host pointer for all layers in the
  // tree.
  layer_tree_host->SetRootLayer(parent.get());

  AssertLayerTreeHostMatchesForSubtree(parent.get(), layer_tree_host.get());

  // Clearing the root layer should also clear out the host pointers for all
  // layers in the tree.
  layer_tree_host->SetRootLayer(nullptr);

  AssertLayerTreeHostMatchesForSubtree(parent.get(), nullptr);
}

TEST_F(LayerLayerTreeHostTest, AddingLayerSubtree) {
  scoped_refptr<Layer> parent = Layer::Create();
  LayerTreeHostFactory factory;

  auto animation_host = AnimationHost::CreateForTesting(ThreadInstance::MAIN);
  std::unique_ptr<LayerTreeHost> layer_tree_host =
      factory.Create(animation_host.get());

  layer_tree_host->SetRootLayer(parent.get());

  EXPECT_EQ(parent->layer_tree_host(), layer_tree_host.get());

  // Adding a subtree to a layer already associated with a host should set the
  // host pointer on all layers in that subtree.
  scoped_refptr<Layer> child = Layer::Create();
  scoped_refptr<Layer> grand_child = Layer::Create();
  child->AddChild(grand_child);

  // Masks should pick up the new host too.
  FakeContentLayerClient client;
  scoped_refptr<PictureLayer> child_mask = PictureLayer::Create(&client);
  child->SetMaskLayer(child_mask.get());

  parent->AddChild(child);
  AssertLayerTreeHostMatchesForSubtree(parent.get(), layer_tree_host.get());

  layer_tree_host->SetRootLayer(nullptr);
}

TEST_F(LayerLayerTreeHostTest, ChangeHost) {
  scoped_refptr<Layer> parent = Layer::Create();
  scoped_refptr<Layer> child = Layer::Create();
  FakeContentLayerClient client;
  scoped_refptr<PictureLayer> mask = PictureLayer::Create(&client);

  // Same setup as the previous test.
  parent->AddChild(child);
  child->SetMaskLayer(mask.get());

  LayerTreeHostFactory factory;
  auto animation_host1 = AnimationHost::CreateForTesting(ThreadInstance::MAIN);
  std::unique_ptr<LayerTreeHost> first_layer_tree_host =
      factory.Create(animation_host1.get());
  first_layer_tree_host->SetRootLayer(parent.get());

  AssertLayerTreeHostMatchesForSubtree(parent.get(),
                                       first_layer_tree_host.get());

  // Now re-root the tree to a new host (simulating what we do on a context lost
  // event). This should update the host pointers for all layers in the tree.
  auto animation_host2 = AnimationHost::CreateForTesting(ThreadInstance::MAIN);
  std::unique_ptr<LayerTreeHost> second_layer_tree_host =
      factory.Create(animation_host2.get());
  second_layer_tree_host->SetRootLayer(parent.get());

  AssertLayerTreeHostMatchesForSubtree(parent.get(),
                                       second_layer_tree_host.get());

  second_layer_tree_host->SetRootLayer(nullptr);
}

TEST_F(LayerLayerTreeHostTest, ChangeHostInSubtree) {
  scoped_refptr<Layer> first_parent = Layer::Create();
  scoped_refptr<Layer> first_child = Layer::Create();
  scoped_refptr<Layer> second_parent = Layer::Create();
  scoped_refptr<Layer> second_child = Layer::Create();
  scoped_refptr<Layer> second_grand_child = Layer::Create();

  // First put all children under the first parent and set the first host.
  first_parent->AddChild(first_child);
  second_child->AddChild(second_grand_child);
  first_parent->AddChild(second_child);

  LayerTreeHostFactory factory;
  auto animation_host1 = AnimationHost::CreateForTesting(ThreadInstance::MAIN);
  std::unique_ptr<LayerTreeHost> first_layer_tree_host =
      factory.Create(animation_host1.get());
  first_layer_tree_host->SetRootLayer(first_parent.get());

  AssertLayerTreeHostMatchesForSubtree(first_parent.get(),
                                       first_layer_tree_host.get());

  // Now reparent the subtree starting at second_child to a layer in a different
  // tree.
  auto animation_host2 = AnimationHost::CreateForTesting(ThreadInstance::MAIN);
  std::unique_ptr<LayerTreeHost> second_layer_tree_host =
      factory.Create(animation_host2.get());
  second_layer_tree_host->SetRootLayer(second_parent.get());

  second_parent->AddChild(second_child);

  // The moved layer and its children should point to the new host.
  EXPECT_EQ(second_layer_tree_host.get(), second_child->layer_tree_host());
  EXPECT_EQ(second_layer_tree_host.get(),
            second_grand_child->layer_tree_host());

  // Test over, cleanup time.
  first_layer_tree_host->SetRootLayer(nullptr);
  second_layer_tree_host->SetRootLayer(nullptr);
}

TEST_F(LayerLayerTreeHostTest, ReplaceMaskLayer) {
  FakeContentLayerClient client;

  scoped_refptr<Layer> parent = Layer::Create();
  scoped_refptr<PictureLayer> mask = PictureLayer::Create(&client);
  scoped_refptr<Layer> mask_child = Layer::Create();
  scoped_refptr<PictureLayer> mask_replacement = PictureLayer::Create(&client);

  parent->SetMaskLayer(mask.get());
  mask->AddChild(mask_child);

  LayerTreeHostFactory factory;
  auto animation_host = AnimationHost::CreateForTesting(ThreadInstance::MAIN);
  std::unique_ptr<LayerTreeHost> layer_tree_host =
      factory.Create(animation_host.get());
  layer_tree_host->SetRootLayer(parent.get());

  AssertLayerTreeHostMatchesForSubtree(parent.get(), layer_tree_host.get());

  // Replacing the mask should clear out the old mask's subtree's host pointers.
  parent->SetMaskLayer(mask_replacement.get());
  EXPECT_EQ(nullptr, mask->layer_tree_host());
  EXPECT_EQ(nullptr, mask_child->layer_tree_host());

  // Test over, cleanup time.
  layer_tree_host->SetRootLayer(nullptr);
}

TEST_F(LayerLayerTreeHostTest, DestroyHostWithNonNullRootLayer) {
  scoped_refptr<Layer> root = Layer::Create();
  scoped_refptr<Layer> child = Layer::Create();
  root->AddChild(child);
  LayerTreeHostFactory factory;
  auto animation_host = AnimationHost::CreateForTesting(ThreadInstance::MAIN);
  std::unique_ptr<LayerTreeHost> layer_tree_host =
      factory.Create(animation_host.get());
  layer_tree_host->SetRootLayer(root);
}

TEST_F(LayerTest, SafeOpaqueBackgroundColor) {
  LayerTreeHostFactory factory;
  auto animation_host = AnimationHost::CreateForTesting(ThreadInstance::MAIN);
  std::unique_ptr<LayerTreeHost> layer_tree_host =
      factory.Create(animation_host.get());

  scoped_refptr<Layer> layer = Layer::Create();
  layer_tree_host->SetRootLayer(layer);

  for (int contents_opaque = 0; contents_opaque < 2; ++contents_opaque) {
    for (int layer_opaque = 0; layer_opaque < 2; ++layer_opaque) {
      for (int host_opaque = 0; host_opaque < 2; ++host_opaque) {
        layer->SetContentsOpaque(!!contents_opaque);
        layer->SetBackgroundColor(layer_opaque ? SK_ColorRED
                                               : SK_ColorTRANSPARENT);
        layer_tree_host->set_background_color(
            host_opaque ? SK_ColorRED : SK_ColorTRANSPARENT);

        layer_tree_host->property_trees()->needs_rebuild = true;
        layer_tree_host->BuildPropertyTreesForTesting();
        SkColor safe_color = layer->SafeOpaqueBackgroundColor();
        if (contents_opaque) {
          EXPECT_EQ(SkColorGetA(safe_color), 255u)
              << "Flags: " << contents_opaque << ", " << layer_opaque << ", "
              << host_opaque << "\n";
        } else {
          EXPECT_NE(SkColorGetA(safe_color), 255u)
              << "Flags: " << contents_opaque << ", " << layer_opaque << ", "
              << host_opaque << "\n";
        }
      }
    }
  }
}

class DrawsContentChangeLayer : public Layer {
 public:
  static scoped_refptr<DrawsContentChangeLayer> Create() {
    return base::WrapRefCounted(new DrawsContentChangeLayer());
  }

  void SetLayerTreeHost(LayerTreeHost* host) override {
    Layer::SetLayerTreeHost(host);
    SetFakeDrawsContent(!fake_draws_content_);
  }

  bool HasDrawableContent() const override {
    return fake_draws_content_ && Layer::HasDrawableContent();
  }

  void SetFakeDrawsContent(bool fake_draws_content) {
    fake_draws_content_ = fake_draws_content;
    UpdateDrawsContent(HasDrawableContent());
  }

 private:
  DrawsContentChangeLayer() : fake_draws_content_(false) {}
  ~DrawsContentChangeLayer() override = default;

  bool fake_draws_content_;
};

TEST_F(LayerTest, DrawsContentChangedInSetLayerTreeHost) {
  scoped_refptr<Layer> root_layer = Layer::Create();
  scoped_refptr<DrawsContentChangeLayer> becomes_not_draws_content =
      DrawsContentChangeLayer::Create();
  scoped_refptr<DrawsContentChangeLayer> becomes_draws_content =
      DrawsContentChangeLayer::Create();
  root_layer->SetIsDrawable(true);
  becomes_not_draws_content->SetIsDrawable(true);
  becomes_not_draws_content->SetFakeDrawsContent(true);
  EXPECT_EQ(0, root_layer->NumDescendantsThatDrawContent());
  root_layer->AddChild(becomes_not_draws_content);
  EXPECT_EQ(0, root_layer->NumDescendantsThatDrawContent());

  becomes_draws_content->SetIsDrawable(true);
  root_layer->AddChild(becomes_draws_content);
  EXPECT_EQ(1, root_layer->NumDescendantsThatDrawContent());
}

TEST_F(LayerTest, PushUpdatesShouldHitTest) {
  scoped_refptr<Layer> root_layer = Layer::Create();
  std::unique_ptr<LayerImpl> impl_layer =
      LayerImpl::Create(host_impl_.active_tree(), 1);
  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1,
                                  layer_tree_host_->SetRootLayer(root_layer));
  EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(5);

  // A layer that draws content should be hit testable.
  root_layer->SetIsDrawable(true);
  root_layer->SetHitTestable(true);
  root_layer->PushPropertiesTo(impl_layer.get());
  EXPECT_TRUE(impl_layer->DrawsContent());
  EXPECT_TRUE(impl_layer->HitTestable());

  // A layer that does not draw content and does not hit test without drawing
  // content should not be hit testable.
  root_layer->SetIsDrawable(false);
  root_layer->SetHitTestable(false);
  root_layer->PushPropertiesTo(impl_layer.get());
  EXPECT_FALSE(impl_layer->DrawsContent());
  EXPECT_FALSE(impl_layer->HitTestable());

  // |SetHitTestableWithoutDrawsContent| should cause a layer to become hit
  // testable even though it does not draw content.
  root_layer->SetHitTestable(true);
  root_layer->PushPropertiesTo(impl_layer.get());
  EXPECT_FALSE(impl_layer->DrawsContent());
  EXPECT_TRUE(impl_layer->HitTestable());
}

void ReceiveCopyOutputResult(int* result_count,
                             std::unique_ptr<viz::CopyOutputResult> result) {
  ++(*result_count);
}

TEST_F(LayerTest, DedupesCopyOutputRequestsBySource) {
  scoped_refptr<Layer> layer = Layer::Create();
  int result_count = 0;

  // Create identical requests without the source being set, and expect the
  // layer does not abort either one.
  std::unique_ptr<viz::CopyOutputRequest> request =
      std::make_unique<viz::CopyOutputRequest>(
          viz::CopyOutputRequest::ResultFormat::RGBA_BITMAP,
          base::BindOnce(&ReceiveCopyOutputResult, &result_count));
  layer->RequestCopyOfOutput(std::move(request));
  EXPECT_EQ(0, result_count);
  request = std::make_unique<viz::CopyOutputRequest>(
      viz::CopyOutputRequest::ResultFormat::RGBA_BITMAP,
      base::BindOnce(&ReceiveCopyOutputResult, &result_count));
  layer->RequestCopyOfOutput(std::move(request));
  EXPECT_EQ(0, result_count);

  // When the layer is destroyed, expect both requests to be aborted.
  layer = nullptr;
  EXPECT_EQ(2, result_count);

  layer = Layer::Create();
  result_count = 0;

  // Create identical requests, but this time the source is being set.  Expect
  // the first request using |kArbitrarySourceId1| aborts immediately when
  // the second request using |kArbitrarySourceId1| is made.
  int did_receive_first_result_from_this_source = 0;
  request = std::make_unique<viz::CopyOutputRequest>(
      viz::CopyOutputRequest::ResultFormat::RGBA_BITMAP,
      base::BindOnce(&ReceiveCopyOutputResult,
                     &did_receive_first_result_from_this_source));
  request->set_source(kArbitrarySourceId1);
  layer->RequestCopyOfOutput(std::move(request));
  EXPECT_EQ(0, did_receive_first_result_from_this_source);
  // Make a request from a different source.
  int did_receive_result_from_different_source = 0;
  request = std::make_unique<viz::CopyOutputRequest>(
      viz::CopyOutputRequest::ResultFormat::RGBA_BITMAP,
      base::BindOnce(&ReceiveCopyOutputResult,
                     &did_receive_result_from_different_source));
  request->set_source(kArbitrarySourceId2);
  layer->RequestCopyOfOutput(std::move(request));
  EXPECT_EQ(0, did_receive_result_from_different_source);
  // Make a request without specifying the source.
  int did_receive_result_from_anonymous_source = 0;
  request = std::make_unique<viz::CopyOutputRequest>(
      viz::CopyOutputRequest::ResultFormat::RGBA_BITMAP,
      base::BindOnce(&ReceiveCopyOutputResult,
                     &did_receive_result_from_anonymous_source));
  layer->RequestCopyOfOutput(std::move(request));
  EXPECT_EQ(0, did_receive_result_from_anonymous_source);
  // Make the second request from |kArbitrarySourceId1|.
  int did_receive_second_result_from_this_source = 0;
  request = std::make_unique<viz::CopyOutputRequest>(
      viz::CopyOutputRequest::ResultFormat::RGBA_BITMAP,
      base::BindOnce(&ReceiveCopyOutputResult,
                     &did_receive_second_result_from_this_source));
  request->set_source(kArbitrarySourceId1);
  layer->RequestCopyOfOutput(
      std::move(request));  // First request to be aborted.
  EXPECT_EQ(1, did_receive_first_result_from_this_source);
  EXPECT_EQ(0, did_receive_result_from_different_source);
  EXPECT_EQ(0, did_receive_result_from_anonymous_source);
  EXPECT_EQ(0, did_receive_second_result_from_this_source);

  // When the layer is destroyed, the other three requests should be aborted.
  layer = nullptr;
  EXPECT_EQ(1, did_receive_first_result_from_this_source);
  EXPECT_EQ(1, did_receive_result_from_different_source);
  EXPECT_EQ(1, did_receive_result_from_anonymous_source);
  EXPECT_EQ(1, did_receive_second_result_from_this_source);
}

TEST_F(LayerTest, AnimationSchedulesLayerUpdate) {
  // TODO(weiliangc): This is really a LayerTreeHost unittest by this point,
  // though currently there is no good place for this unittest to go. Move to
  // LayerTreeHost unittest when there is a good setup.
  scoped_refptr<Layer> layer = Layer::Create();
  layer->SetElementId(ElementId(2));
  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, layer_tree_host_->SetRootLayer(layer));
  auto element_id = layer->element_id();

  EXPECT_CALL(*layer_tree_host_, SetNeedsUpdateLayers()).Times(1);
  layer_tree_host_->SetElementOpacityMutated(element_id,
                                             ElementListType::ACTIVE, 0.5f);
  Mock::VerifyAndClearExpectations(layer_tree_host_.get());

  EXPECT_CALL(*layer_tree_host_, SetNeedsUpdateLayers()).Times(1);
  gfx::Transform transform;
  transform.Rotate(45.0);
  layer_tree_host_->SetElementTransformMutated(
      element_id, ElementListType::ACTIVE, transform);
  Mock::VerifyAndClearExpectations(layer_tree_host_.get());

  // Scroll offset animation should not schedule a layer update since it is
  // handled similarly to normal compositor scroll updates.
  EXPECT_CALL(*layer_tree_host_, SetNeedsUpdateLayers()).Times(0);
  layer_tree_host_->SetElementScrollOffsetMutated(
      element_id, ElementListType::ACTIVE, gfx::ScrollOffset(10, 10));
  Mock::VerifyAndClearExpectations(layer_tree_host_.get());
}

TEST_F(LayerTest, ElementIdIsPushed) {
  scoped_refptr<Layer> test_layer = Layer::Create();
  std::unique_ptr<LayerImpl> impl_layer =
      LayerImpl::Create(host_impl_.active_tree(), 1);

  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1,
                                  layer_tree_host_->SetRootLayer(test_layer));

  EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1);

  test_layer->SetElementId(ElementId(2));

  EXPECT_FALSE(impl_layer->element_id());

  test_layer->PushPropertiesTo(impl_layer.get());

  EXPECT_EQ(ElementId(2), impl_layer->element_id());
}

TEST_F(LayerTest, SetLayerTreeHostNotUsingLayerListsManagesElementId) {
  scoped_refptr<Layer> test_layer = Layer::Create();
  ElementId element_id = ElementId(2);
  test_layer->SetElementId(element_id);

  // Expect additional call due to has-animation check.
  EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(2);
  scoped_refptr<AnimationTimeline> timeline =
      AnimationTimeline::Create(AnimationIdProvider::NextTimelineId());
  animation_host_->AddAnimationTimeline(timeline);

  AddOpacityTransitionToElementWithAnimation(element_id, timeline, 10.0, 1.f,
                                             0.f, false);
  EXPECT_TRUE(animation_host_->IsElementAnimating(element_id));

  EXPECT_EQ(nullptr, layer_tree_host_->LayerByElementId(element_id));
  test_layer->SetLayerTreeHost(layer_tree_host_.get());
  // Layer should now be registered by element id.
  EXPECT_EQ(test_layer, layer_tree_host_->LayerByElementId(element_id));

  test_layer->SetLayerTreeHost(nullptr);
  // Layer should have been un-registered.
  EXPECT_EQ(nullptr, layer_tree_host_->LayerByElementId(element_id));
}

TEST_F(LayerTest, SetElementIdNotUsingLayerLists) {
  scoped_refptr<Layer> test_layer = Layer::Create();
  test_layer->SetLayerTreeHost(layer_tree_host_.get());

  EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(2);
  ElementId element_id = ElementId(2);
  EXPECT_EQ(nullptr, layer_tree_host_->LayerByElementId(element_id));

  test_layer->SetElementId(element_id);
  // Layer should now be registered by element id.
  EXPECT_EQ(test_layer, layer_tree_host_->LayerByElementId(element_id));

  ElementId other_element_id = ElementId(3);
  test_layer->SetElementId(other_element_id);
  // The layer should have been unregistered from the original element
  // id and registered with the new one.
  EXPECT_EQ(nullptr, layer_tree_host_->LayerByElementId(element_id));
  EXPECT_EQ(test_layer, layer_tree_host_->LayerByElementId(other_element_id));

  test_layer->SetLayerTreeHost(nullptr);
}

class LayerTestWithLayerLists : public LayerTest {
 protected:
  void SetUp() override {
    settings_.use_layer_lists = true;
    LayerTest::SetUp();
  }
};

TEST_F(LayerTestWithLayerLists, LayerTreeHostRegistersScrollingElementId) {
  scoped_refptr<Layer> normal_layer = Layer::Create();
  scoped_refptr<Layer> scrolling_layer = Layer::Create();
  scrolling_layer->SetScrollable(gfx::Size(1000, 1000));
  ElementId normal_element_id = ElementId(2);
  ElementId scrolling_element_id = ElementId(3);
  normal_layer->SetElementId(normal_element_id);
  scrolling_layer->SetElementId(scrolling_element_id);

  EXPECT_EQ(nullptr, layer_tree_host_->LayerByElementId(normal_element_id));
  EXPECT_EQ(nullptr, layer_tree_host_->LayerByElementId(scrolling_element_id));
  normal_layer->SetLayerTreeHost(layer_tree_host_.get());
  scrolling_layer->SetLayerTreeHost(layer_tree_host_.get());
  EXPECT_EQ(nullptr, layer_tree_host_->LayerByElementId(normal_element_id));
  EXPECT_EQ(scrolling_layer,
            layer_tree_host_->LayerByElementId(scrolling_element_id));

  normal_layer->SetLayerTreeHost(nullptr);
  scrolling_layer->SetLayerTreeHost(nullptr);
  EXPECT_EQ(nullptr, layer_tree_host_->LayerByElementId(scrolling_element_id));
}

TEST_F(LayerTestWithLayerLists, ChangingScrollableElementIdRegistersElement) {
  scoped_refptr<Layer> test_layer = Layer::Create();
  test_layer->SetScrollable(gfx::Size(1000, 1000));
  EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1);
  test_layer->SetLayerTreeHost(layer_tree_host_.get());

  ElementId element_id = ElementId(2);
  EXPECT_EQ(nullptr, layer_tree_host_->LayerByElementId(element_id));

  // Setting the element id should register the layer.
  test_layer->SetElementId(element_id);
  EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1);
  EXPECT_EQ(test_layer, layer_tree_host_->LayerByElementId(element_id));

  // Unsetting the element id should unregister the layer.
  test_layer->SetElementId(ElementId());
  EXPECT_EQ(nullptr, layer_tree_host_->LayerByElementId(element_id));

  test_layer->SetLayerTreeHost(nullptr);
  EXPECT_EQ(nullptr, layer_tree_host_->LayerByElementId(element_id));
}

TEST_F(LayerTestWithLayerLists, ChangingScrollableRegistersElement) {
  scoped_refptr<Layer> test_layer = Layer::Create();
  EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1);
  test_layer->SetLayerTreeHost(layer_tree_host_.get());

  ElementId element_id = ElementId(2);
  EXPECT_EQ(nullptr, layer_tree_host_->LayerByElementId(element_id));

  // Setting the element id commits the element id but should not register
  // the layer.
  test_layer->SetElementId(element_id);
  EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1);
  EXPECT_EQ(nullptr, layer_tree_host_->LayerByElementId(element_id));

  // Making the layer scrollable should register it.
  test_layer->SetScrollable(gfx::Size(1000, 1000));
  EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1);
  EXPECT_EQ(test_layer, layer_tree_host_->LayerByElementId(element_id));

  // Unsetting the element id should unregister the layer.
  test_layer->SetElementId(ElementId());
  EXPECT_EQ(nullptr, layer_tree_host_->LayerByElementId(element_id));

  test_layer->SetLayerTreeHost(nullptr);
  EXPECT_EQ(nullptr, layer_tree_host_->LayerByElementId(element_id));
}

TEST_F(LayerTestWithLayerLists, SetElementIdUsingLayerLists) {
  scoped_refptr<Layer> test_layer = Layer::Create();
  ElementId element_id = ElementId(2);
  test_layer->SetElementId(element_id);

  EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(0);
  EXPECT_EQ(nullptr, layer_tree_host_->LayerByElementId(element_id));
}

}  // namespace
}  // namespace cc
