// Copyright 2014 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/layer_tree_impl.h"

#include "cc/layers/heads_up_display_layer_impl.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/trees/clip_node.h"
#include "cc/trees/draw_property_utils.h"
#include "cc/trees/layer_tree_host_common.h"
#include "cc/trees/layer_tree_host_impl.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace cc {
namespace {

class LayerTreeImplTestSettings : public LayerTreeSettings {
 public:
  LayerTreeImplTestSettings() {
    layer_transforms_should_scale_layer_contents = true;
  }
};

class LayerTreeImplTest : public testing::Test {
 public:
  LayerTreeImplTest(
      const LayerTreeSettings& settings = LayerTreeImplTestSettings())
      : impl_test_(settings) {}

  FakeLayerTreeHostImpl& host_impl() const { return *impl_test_.host_impl(); }

  LayerImpl* root_layer() { return impl_test_.root_layer_for_testing(); }

  const RenderSurfaceList& GetRenderSurfaceList() const {
    return host_impl().active_tree()->GetRenderSurfaceList();
  }

  void ExecuteCalculateDrawProperties(LayerImpl* root_layer) {
    // We are probably not testing what is intended if the root_layer bounds are
    // empty.
    DCHECK(!root_layer->bounds().IsEmpty());

    render_surface_list_impl_.clear();
    LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
        root_layer, root_layer->bounds(), &render_surface_list_impl_);
    inputs.can_adjust_raster_scales = true;
    LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs);
  }

  int HitTestSimpleTree(int root_id,
                        int left_child_id,
                        int right_child_id,
                        int root_sorting_context,
                        int left_child_sorting_context,
                        int right_child_sorting_context,
                        float root_depth,
                        float left_child_depth,
                        float right_child_depth) {
    host_impl().active_tree()->SetRootLayerForTesting(nullptr);

    std::unique_ptr<LayerImpl> root =
        LayerImpl::Create(host_impl().active_tree(), root_id);
    std::unique_ptr<LayerImpl> left_child =
        LayerImpl::Create(host_impl().active_tree(), left_child_id);
    std::unique_ptr<LayerImpl> right_child =
        LayerImpl::Create(host_impl().active_tree(), right_child_id);

    gfx::Size bounds(100, 100);
    {
      gfx::Transform translate_z;
      translate_z.Translate3d(0, 0, root_depth);
      root->test_properties()->transform = translate_z;
      root->test_properties()->sorting_context_id = root_sorting_context;
      root->SetBounds(bounds);
      root->SetDrawsContent(true);
    }
    {
      gfx::Transform translate_z;
      translate_z.Translate3d(0, 0, left_child_depth);
      left_child->test_properties()->transform = translate_z;
      left_child->test_properties()->sorting_context_id =
          left_child_sorting_context;
      left_child->SetBounds(bounds);
      left_child->SetDrawsContent(true);
      left_child->test_properties()->should_flatten_transform = false;
    }
    {
      gfx::Transform translate_z;
      translate_z.Translate3d(0, 0, right_child_depth);
      right_child->test_properties()->transform = translate_z;
      right_child->test_properties()->sorting_context_id =
          right_child_sorting_context;
      right_child->SetBounds(bounds);
      right_child->SetDrawsContent(true);
    }

    root->test_properties()->AddChild(std::move(left_child));
    root->test_properties()->AddChild(std::move(right_child));

    host_impl().active_tree()->SetDeviceViewportSize(root->bounds());
    host_impl().active_tree()->SetRootLayerForTesting(std::move(root));
    host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree();
    CHECK_EQ(1u, GetRenderSurfaceList().size());

    gfx::PointF test_point = gfx::PointF(1.f, 1.f);
    LayerImpl* result_layer =
        host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);

    CHECK(result_layer);
    return result_layer->id();
  }

 private:
  LayerTestCommon::LayerImplTest impl_test_;
  RenderSurfaceList render_surface_list_impl_;
};

TEST_F(LayerTreeImplTest, HitTestingForSingleLayer) {
  gfx::Size bounds(100, 100);
  LayerImpl* root = root_layer();
  root->SetBounds(bounds);
  root->SetDrawsContent(true);

  host_impl().active_tree()->SetDeviceViewportSize(root->bounds());
  host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree();

  // Sanity check the scenario we just created.
  ASSERT_EQ(1u, GetRenderSurfaceList().size());
  ASSERT_EQ(1, GetRenderSurface(root_layer())->num_contributors());

  // Hit testing for a point outside the layer should return a null pointer.
  gfx::PointF test_point(101.f, 101.f);
  LayerImpl* result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
  EXPECT_FALSE(result_layer);

  test_point = gfx::PointF(-1.f, -1.f);
  result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
  EXPECT_FALSE(result_layer);

  // Hit testing for a point inside should return the root layer.
  test_point = gfx::PointF(1.f, 1.f);
  result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
  ASSERT_TRUE(result_layer);
  EXPECT_EQ(root->id(), result_layer->id());

  test_point = gfx::PointF(99.f, 99.f);
  result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
  ASSERT_TRUE(result_layer);
  EXPECT_EQ(root->id(), result_layer->id());
}

TEST_F(LayerTreeImplTest, UpdateViewportAndHitTest) {
  // Ensures that the viewport rect is correctly updated by the clip tree.
  gfx::Size bounds(100, 100);
  LayerImpl* root = root_layer();
  root->SetBounds(bounds);
  root->SetDrawsContent(true);

  host_impl().active_tree()->SetDeviceViewportSize(root->bounds());
  host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree();
  EXPECT_EQ(
      gfx::RectF(gfx::SizeF(bounds)),
      host_impl().active_tree()->property_trees()->clip_tree.ViewportClip());
  EXPECT_EQ(gfx::Rect(bounds), root->visible_layer_rect());

  gfx::Size new_bounds(50, 50);
  host_impl().active_tree()->SetDeviceViewportSize(new_bounds);
  gfx::PointF test_point(51.f, 51.f);
  host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
  EXPECT_EQ(
      gfx::RectF(gfx::SizeF(new_bounds)),
      host_impl().active_tree()->property_trees()->clip_tree.ViewportClip());
  EXPECT_EQ(gfx::Rect(new_bounds), root->visible_layer_rect());
}

TEST_F(LayerTreeImplTest, HitTestingForSingleLayerAndHud) {
  LayerImpl* root = root_layer();
  root->SetBounds(gfx::Size(100, 100));
  root->SetDrawsContent(true);

  // Create hud and add it as a child of root.
  std::unique_ptr<HeadsUpDisplayLayerImpl> hud =
      HeadsUpDisplayLayerImpl::Create(host_impl().active_tree(), 11111);
  hud->SetBounds(gfx::Size(200, 200));
  hud->SetDrawsContent(true);

  host_impl().active_tree()->SetDeviceViewportSize(hud->bounds());
  host_impl().active_tree()->set_hud_layer(hud.get());
  root->test_properties()->AddChild(std::move(hud));
  host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree();

  // Sanity check the scenario we just created.
  ASSERT_EQ(1u, GetRenderSurfaceList().size());
  ASSERT_EQ(2, GetRenderSurface(root_layer())->num_contributors());

  // Hit testing for a point inside HUD, but outside root should return null
  gfx::PointF test_point(101.f, 101.f);
  LayerImpl* result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
  EXPECT_FALSE(result_layer);

  test_point = gfx::PointF(-1.f, -1.f);
  result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
  EXPECT_FALSE(result_layer);

  // Hit testing for a point inside should return the root layer, never the HUD
  // layer.
  test_point = gfx::PointF(1.f, 1.f);
  result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
  ASSERT_TRUE(result_layer);
  EXPECT_EQ(root->id(), result_layer->id());

  test_point = gfx::PointF(99.f, 99.f);
  result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
  ASSERT_TRUE(result_layer);
  EXPECT_EQ(root->id(), result_layer->id());
}

TEST_F(LayerTreeImplTest, HitTestingForUninvertibleTransform) {
  gfx::Transform uninvertible_transform;
  uninvertible_transform.matrix().set(0, 0, 0.0);
  uninvertible_transform.matrix().set(1, 1, 0.0);
  uninvertible_transform.matrix().set(2, 2, 0.0);
  uninvertible_transform.matrix().set(3, 3, 0.0);
  ASSERT_FALSE(uninvertible_transform.IsInvertible());

  LayerImpl* root = root_layer();
  root->test_properties()->transform = uninvertible_transform;
  root->SetBounds(gfx::Size(100, 100));
  root->SetDrawsContent(true);

  host_impl().active_tree()->SetDeviceViewportSize(root->bounds());
  host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree();
  // Sanity check the scenario we just created.
  ASSERT_EQ(1u, GetRenderSurfaceList().size());
  ASSERT_EQ(1, GetRenderSurface(root_layer())->num_contributors());
  ASSERT_FALSE(root_layer()->ScreenSpaceTransform().IsInvertible());

  // Hit testing any point should not hit the layer. If the invertible matrix is
  // accidentally ignored and treated like an identity, then the hit testing
  // will incorrectly hit the layer when it shouldn't.
  gfx::PointF test_point(1.f, 1.f);
  LayerImpl* result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
  EXPECT_FALSE(result_layer);

  test_point = gfx::PointF(10.f, 10.f);
  result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
  EXPECT_FALSE(result_layer);

  test_point = gfx::PointF(10.f, 30.f);
  result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
  EXPECT_FALSE(result_layer);

  test_point = gfx::PointF(50.f, 50.f);
  result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
  EXPECT_FALSE(result_layer);

  test_point = gfx::PointF(67.f, 48.f);
  result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
  EXPECT_FALSE(result_layer);

  test_point = gfx::PointF(99.f, 99.f);
  result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
  EXPECT_FALSE(result_layer);

  test_point = gfx::PointF(-1.f, -1.f);
  result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
  EXPECT_FALSE(result_layer);
}

TEST_F(LayerTreeImplTest, HitTestingForSinglePositionedLayer) {
  // This layer is positioned, and hit testing should correctly know where the
  // layer is located.
  {
    std::unique_ptr<LayerImpl> test_layer =
        LayerImpl::Create(host_impl().active_tree(), 12345);
    test_layer->test_properties()->position = gfx::PointF(50.f, 50.f);
    test_layer->SetBounds(gfx::Size(100, 100));
    test_layer->SetDrawsContent(true);
    root_layer()->test_properties()->AddChild(std::move(test_layer));
  }

  LayerImpl* test_layer = root_layer()->test_properties()->children[0];
  host_impl().active_tree()->SetDeviceViewportSize(test_layer->bounds());
  host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree();

  // Sanity check the scenario we just created.
  ASSERT_EQ(1u, GetRenderSurfaceList().size());
  ASSERT_EQ(1, GetRenderSurface(test_layer)->num_contributors());

  // Hit testing for a point outside the layer should return a null pointer.
  gfx::PointF test_point(49.f, 49.f);
  LayerImpl* result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
  EXPECT_FALSE(result_layer);

  // Even though the layer exists at (101, 101), it should not be visible there
  // since the root render surface would clamp it.
  test_point = gfx::PointF(101.f, 101.f);
  result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
  EXPECT_FALSE(result_layer);

  // Hit testing for a point inside should return the root layer.
  test_point = gfx::PointF(51.f, 51.f);
  result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
  ASSERT_TRUE(result_layer);
  EXPECT_EQ(test_layer->id(), result_layer->id());

  test_point = gfx::PointF(99.f, 99.f);
  result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
  ASSERT_TRUE(result_layer);
  EXPECT_EQ(test_layer->id(), result_layer->id());
}

TEST_F(LayerTreeImplTest, HitTestingForSingleRotatedLayer) {
  gfx::Transform rotation45_degrees_about_center;
  rotation45_degrees_about_center.Translate(50.0, 50.0);
  rotation45_degrees_about_center.RotateAboutZAxis(45.0);
  rotation45_degrees_about_center.Translate(-50.0, -50.0);

  LayerImpl* root = root_layer();
  root->test_properties()->transform = rotation45_degrees_about_center;
  root->SetBounds(gfx::Size(100, 100));
  root->SetDrawsContent(true);

  host_impl().active_tree()->SetDeviceViewportSize(root->bounds());
  host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree();

  // Sanity check the scenario we just created.
  ASSERT_EQ(1u, GetRenderSurfaceList().size());
  ASSERT_EQ(1, GetRenderSurface(root_layer())->num_contributors());

  // Hit testing for points outside the layer.
  // These corners would have been inside the un-transformed layer, but they
  // should not hit the correctly transformed layer.
  gfx::PointF test_point(99.f, 99.f);
  LayerImpl* result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
  EXPECT_FALSE(result_layer);

  test_point = gfx::PointF(1.f, 1.f);
  result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
  EXPECT_FALSE(result_layer);

  // Hit testing for a point inside should return the root layer.
  test_point = gfx::PointF(1.f, 50.f);
  result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
  ASSERT_TRUE(result_layer);
  EXPECT_EQ(root->id(), result_layer->id());

  // Hit testing the corners that would overlap the unclipped layer, but are
  // outside the clipped region.
  test_point = gfx::PointF(50.f, -1.f);
  result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
  ASSERT_FALSE(result_layer);

  test_point = gfx::PointF(-1.f, 50.f);
  result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
  ASSERT_FALSE(result_layer);
}

TEST_F(LayerTreeImplTest, HitTestingClipNodeDifferentTransformAndTargetIds) {
  // Tests hit testing on a layer whose clip node has different transform and
  // target id.
  LayerImpl* root = root_layer();
  root->SetBounds(gfx::Size(500, 500));

  gfx::Transform translation;
  translation.Translate(100, 100);
  std::unique_ptr<LayerImpl> render_surface =
      LayerImpl::Create(host_impl().active_tree(), 2);
  render_surface->test_properties()->transform = translation;
  render_surface->SetBounds(gfx::Size(100, 100));
  render_surface->test_properties()->force_render_surface = true;

  gfx::Transform scale_matrix;
  scale_matrix.Scale(2, 2);
  std::unique_ptr<LayerImpl> scale =
      LayerImpl::Create(host_impl().active_tree(), 3);
  scale->test_properties()->transform = scale_matrix;
  scale->SetBounds(gfx::Size(50, 50));

  std::unique_ptr<LayerImpl> clip =
      LayerImpl::Create(host_impl().active_tree(), 4);
  clip->SetBounds(gfx::Size(25, 25));
  clip->SetMasksToBounds(true);

  std::unique_ptr<LayerImpl> test =
      LayerImpl::Create(host_impl().active_tree(), 5);
  test->SetBounds(gfx::Size(100, 100));
  test->SetDrawsContent(true);

  clip->test_properties()->AddChild(std::move(test));
  scale->test_properties()->AddChild(std::move(clip));
  render_surface->test_properties()->AddChild(std::move(scale));
  root->test_properties()->AddChild(std::move(render_surface));

  host_impl().active_tree()->SetDeviceViewportSize(root->bounds());
  host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree();

  gfx::PointF test_point(160.f, 160.f);
  LayerImpl* result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
  EXPECT_FALSE(result_layer);

  test_point = gfx::PointF(140.f, 140.f);
  result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
  ASSERT_TRUE(result_layer);
  EXPECT_EQ(5, result_layer->id());
}

TEST_F(LayerTreeImplTest, HitTestingSiblings) {
  // This tests hit testing when the test point hits only one of the siblings.
  LayerImpl* root = root_layer();
  root->SetBounds(gfx::Size(100, 100));

  std::unique_ptr<LayerImpl> child1 =
      LayerImpl::Create(host_impl().active_tree(), 2);
  child1->SetBounds(gfx::Size(25, 25));
  child1->SetMasksToBounds(true);
  child1->SetDrawsContent(true);

  std::unique_ptr<LayerImpl> child2 =
      LayerImpl::Create(host_impl().active_tree(), 3);
  child2->SetBounds(gfx::Size(75, 75));
  child2->SetMasksToBounds(true);
  child2->SetDrawsContent(true);

  root->test_properties()->AddChild(std::move(child1));
  root->test_properties()->AddChild(std::move(child2));

  host_impl().active_tree()->SetDeviceViewportSize(root->bounds());
  host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree();

  gfx::PointF test_point(50.f, 50.f);
  LayerImpl* result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
  ASSERT_TRUE(result_layer);
  EXPECT_EQ(3, result_layer->id());
}

TEST_F(LayerTreeImplTest, HitTestingForSinglePerspectiveLayer) {
  // perspective_projection_about_center * translation_by_z is designed so that
  // the 100 x 100 layer becomes 50 x 50, and remains centered at (50, 50).
  gfx::Transform perspective_projection_about_center;
  perspective_projection_about_center.Translate(50.0, 50.0);
  perspective_projection_about_center.ApplyPerspectiveDepth(1.0);
  perspective_projection_about_center.Translate(-50.0, -50.0);
  gfx::Transform translation_by_z;
  translation_by_z.Translate3d(0.0, 0.0, -1.0);

  LayerImpl* root = root_layer();
  root->test_properties()->transform =
      (perspective_projection_about_center * translation_by_z);
  root->SetBounds(gfx::Size(100, 100));
  root->SetDrawsContent(true);

  host_impl().active_tree()->SetDeviceViewportSize(root->bounds());
  host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree();

  // Sanity check the scenario we just created.
  ASSERT_EQ(1u, GetRenderSurfaceList().size());
  ASSERT_EQ(1, GetRenderSurface(root_layer())->num_contributors());

  // Hit testing for points outside the layer.
  // These corners would have been inside the un-transformed layer, but they
  // should not hit the correctly transformed layer.
  gfx::PointF test_point(24.f, 24.f);
  LayerImpl* result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
  EXPECT_FALSE(result_layer);

  test_point = gfx::PointF(76.f, 76.f);
  result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
  EXPECT_FALSE(result_layer);

  // Hit testing for a point inside should return the root layer.
  test_point = gfx::PointF(26.f, 26.f);
  result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
  ASSERT_TRUE(result_layer);
  EXPECT_EQ(root->id(), result_layer->id());

  test_point = gfx::PointF(74.f, 74.f);
  result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
  ASSERT_TRUE(result_layer);
  EXPECT_EQ(root->id(), result_layer->id());
}

TEST_F(LayerTreeImplTest, HitTestingForSimpleClippedLayer) {
  // Test that hit-testing will only work for the visible portion of a layer,
  // and not the entire layer bounds. Here we just test the simple axis-aligned
  // case.
  LayerImpl* root = root_layer();
  root->SetBounds(gfx::Size(100, 100));
  {
    std::unique_ptr<LayerImpl> clipping_layer =
        LayerImpl::Create(host_impl().active_tree(), 123);
    // this layer is positioned, and hit testing should correctly know where the
    // layer is located.
    clipping_layer->test_properties()->position = gfx::PointF(25.f, 25.f);
    clipping_layer->SetBounds(gfx::Size(50, 50));
    clipping_layer->SetMasksToBounds(true);

    std::unique_ptr<LayerImpl> child =
        LayerImpl::Create(host_impl().active_tree(), 456);
    child->test_properties()->position = gfx::PointF(-50.f, -50.f);
    child->SetBounds(gfx::Size(300, 300));
    child->SetDrawsContent(true);
    clipping_layer->test_properties()->AddChild(std::move(child));
    root->test_properties()->AddChild(std::move(clipping_layer));
  }

  host_impl().active_tree()->SetDeviceViewportSize(root->bounds());
  host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree();

  // Sanity check the scenario we just created.
  ASSERT_EQ(1u, GetRenderSurfaceList().size());
  ASSERT_EQ(1, GetRenderSurface(root_layer())->num_contributors());
  LayerImpl* child_layer = host_impl().active_tree()->LayerById(456);
  EXPECT_TRUE(child_layer->contributes_to_drawn_render_surface());

  // Hit testing for a point outside the layer should return a null pointer.
  // Despite the child layer being very large, it should be clipped to the root
  // layer's bounds.
  gfx::PointF test_point(24.f, 24.f);
  LayerImpl* result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
  EXPECT_FALSE(result_layer);

  // Even though the layer exists at (101, 101), it should not be visible there
  // since the clipping_layer would clamp it.
  test_point = gfx::PointF(76.f, 76.f);
  result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
  EXPECT_FALSE(result_layer);

  // Hit testing for a point inside should return the child layer.
  test_point = gfx::PointF(26.f, 26.f);
  result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
  ASSERT_TRUE(result_layer);
  EXPECT_EQ(456, result_layer->id());

  test_point = gfx::PointF(74.f, 74.f);
  result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
  ASSERT_TRUE(result_layer);
  EXPECT_EQ(456, result_layer->id());
}

TEST_F(LayerTreeImplTest, HitTestingForMultiClippedRotatedLayer) {
  // This test checks whether hit testing correctly avoids hit testing with
  // multiple ancestors that clip in non axis-aligned ways. To pass this test,
  // the hit testing algorithm needs to recognize that multiple parent layers
  // may clip the layer, and should not actually hit those clipped areas.
  //
  // The child and grand_child layers are both initialized to clip the
  // rotated_leaf. The child layer is rotated about the top-left corner, so that
  // the root + child clips combined create a triangle. The rotated_leaf will
  // only be visible where it overlaps this triangle.
  //
  LayerImpl* root = root_layer();

  root->SetBounds(gfx::Size(100, 100));
  root->SetMasksToBounds(true);
  // Visible rects computed by combinig clips in target space and root space
  // don't match because of rotation transforms. So, we skip
  // verify_visible_rect_calculations.
  {
    std::unique_ptr<LayerImpl> child =
        LayerImpl::Create(host_impl().active_tree(), 456);
    std::unique_ptr<LayerImpl> grand_child =
        LayerImpl::Create(host_impl().active_tree(), 789);
    std::unique_ptr<LayerImpl> rotated_leaf =
        LayerImpl::Create(host_impl().active_tree(), 2468);

    child->test_properties()->position = gfx::PointF(10.f, 10.f);
    child->SetBounds(gfx::Size(80, 80));
    child->SetMasksToBounds(true);

    gfx::Transform rotation45_degrees_about_corner;
    rotation45_degrees_about_corner.RotateAboutZAxis(45.0);

    // This is positioned with respect to its parent which is already at
    // position (10, 10).
    // The size is to ensure it covers at least sqrt(2) * 100.
    grand_child->SetBounds(gfx::Size(200, 200));
    grand_child->test_properties()->transform = rotation45_degrees_about_corner;
    grand_child->SetMasksToBounds(true);

    // Rotates about the center of the layer
    gfx::Transform rotated_leaf_transform;
    rotated_leaf_transform.Translate(
        -10.0, -10.0);  // cancel out the grand_parent's position
    rotated_leaf_transform.RotateAboutZAxis(
        -45.0);  // cancel out the corner 45-degree rotation of the parent.
    rotated_leaf_transform.Translate(50.0, 50.0);
    rotated_leaf_transform.RotateAboutZAxis(45.0);
    rotated_leaf_transform.Translate(-50.0, -50.0);
    rotated_leaf->SetBounds(gfx::Size(100, 100));
    rotated_leaf->test_properties()->transform = rotated_leaf_transform;
    rotated_leaf->SetDrawsContent(true);

    grand_child->test_properties()->AddChild(std::move(rotated_leaf));
    child->test_properties()->AddChild(std::move(grand_child));
    root->test_properties()->AddChild(std::move(child));

    ExecuteCalculateDrawProperties(root);
  }

  host_impl().active_tree()->SetDeviceViewportSize(root->bounds());
  host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree();
  // (11, 89) is close to the the bottom left corner within the clip, but it is
  // not inside the layer.
  gfx::PointF test_point(11.f, 89.f);
  LayerImpl* result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
  EXPECT_FALSE(result_layer);

  // Closer inwards from the bottom left will overlap the layer.
  test_point = gfx::PointF(25.f, 75.f);
  result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
  ASSERT_TRUE(result_layer);
  EXPECT_EQ(2468, result_layer->id());

  // (4, 50) is inside the unclipped layer, but that corner of the layer should
  // be clipped away by the grandparent and should not get hit. If hit testing
  // blindly uses visible content rect without considering how parent may clip
  // the layer, then hit testing would accidentally think that the point
  // successfully hits the layer.
  test_point = gfx::PointF(4.f, 50.f);
  result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
  EXPECT_FALSE(result_layer);

  // (11, 50) is inside the layer and within the clipped area.
  test_point = gfx::PointF(11.f, 50.f);
  result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
  ASSERT_TRUE(result_layer);
  EXPECT_EQ(2468, result_layer->id());

  // Around the middle, just to the right and up, would have hit the layer
  // except that that area should be clipped away by the parent.
  test_point = gfx::PointF(51.f, 49.f);
  result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
  EXPECT_FALSE(result_layer);

  // Around the middle, just to the left and down, should successfully hit the
  // layer.
  test_point = gfx::PointF(49.f, 51.f);
  result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
  ASSERT_TRUE(result_layer);
  EXPECT_EQ(2468, result_layer->id());
}

TEST_F(LayerTreeImplTest, HitTestingForNonClippingIntermediateLayer) {
  // This test checks that hit testing code does not accidentally clip to layer
  // bounds for a layer that actually does not clip.

  LayerImpl* root = root_layer();
  root->SetBounds(gfx::Size(100, 100));
  {
    std::unique_ptr<LayerImpl> intermediate_layer =
        LayerImpl::Create(host_impl().active_tree(), 123);
    // this layer is positioned, and hit testing should correctly know where the
    // layer is located.
    intermediate_layer->test_properties()->position = gfx::PointF(10.f, 10.f);
    intermediate_layer->SetBounds(gfx::Size(50, 50));
    // Sanity check the intermediate layer should not clip.
    ASSERT_FALSE(intermediate_layer->masks_to_bounds());
    ASSERT_FALSE(intermediate_layer->test_properties()->mask_layer);

    // The child of the intermediate_layer is translated so that it does not
    // overlap intermediate_layer at all.  If child is incorrectly clipped, we
    // would not be able to hit it successfully.
    std::unique_ptr<LayerImpl> child =
        LayerImpl::Create(host_impl().active_tree(), 456);
    child->test_properties()->position =
        gfx::PointF(60.f, 60.f);  // 70, 70 in screen spae
    child->SetBounds(gfx::Size(20, 20));
    child->SetDrawsContent(true);
    intermediate_layer->test_properties()->AddChild(std::move(child));
    root->test_properties()->AddChild(std::move(intermediate_layer));
  }

  host_impl().active_tree()->SetDeviceViewportSize(root->bounds());
  host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree();

  // Sanity check the scenario we just created.
  ASSERT_EQ(1u, GetRenderSurfaceList().size());
  ASSERT_EQ(1, GetRenderSurface(root_layer())->num_contributors());
  LayerImpl* child_layer = host_impl().active_tree()->LayerById(456);
  EXPECT_TRUE(child_layer->contributes_to_drawn_render_surface());

  // Hit testing for a point outside the layer should return a null pointer.
  gfx::PointF test_point(69.f, 69.f);
  LayerImpl* result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
  EXPECT_FALSE(result_layer);

  test_point = gfx::PointF(91.f, 91.f);
  result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
  EXPECT_FALSE(result_layer);

  // Hit testing for a point inside should return the child layer.
  test_point = gfx::PointF(71.f, 71.f);
  result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
  ASSERT_TRUE(result_layer);
  EXPECT_EQ(456, result_layer->id());

  test_point = gfx::PointF(89.f, 89.f);
  result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
  ASSERT_TRUE(result_layer);
  EXPECT_EQ(456, result_layer->id());
}

TEST_F(LayerTreeImplTest, HitTestingForMultipleLayers) {
  LayerImpl* root = root_layer();
  root->SetBounds(gfx::Size(100, 100));
  root->SetDrawsContent(true);
  {
    // child 1 and child2 are initialized to overlap between x=50 and x=60.
    // grand_child is set to overlap both child1 and child2 between y=50 and
    // y=60.  The expected stacking order is: (front) child2, (second)
    // grand_child, (third) child1, and (back) the root layer behind all other
    // layers.

    std::unique_ptr<LayerImpl> child1 =
        LayerImpl::Create(host_impl().active_tree(), 2);
    std::unique_ptr<LayerImpl> child2 =
        LayerImpl::Create(host_impl().active_tree(), 3);
    std::unique_ptr<LayerImpl> grand_child1 =
        LayerImpl::Create(host_impl().active_tree(), 4);

    child1->test_properties()->position = gfx::PointF(10.f, 10.f);
    child1->SetBounds(gfx::Size(50, 50));
    child1->SetDrawsContent(true);

    child2->test_properties()->position = gfx::PointF(50.f, 10.f);
    child2->SetBounds(gfx::Size(50, 50));
    child2->SetDrawsContent(true);

    // Remember that grand_child is positioned with respect to its parent (i.e.
    // child1).  In screen space, the intended position is (10, 50), with size
    // 100 x 50.
    grand_child1->test_properties()->position = gfx::PointF(0.f, 40.f);
    grand_child1->SetBounds(gfx::Size(100, 50));
    grand_child1->SetDrawsContent(true);

    child1->test_properties()->AddChild(std::move(grand_child1));
    root->test_properties()->AddChild(std::move(child1));
    root->test_properties()->AddChild(std::move(child2));

    ExecuteCalculateDrawProperties(root);
  }

  LayerImpl* child1 = root->test_properties()->children[0];
  LayerImpl* child2 = root->test_properties()->children[1];
  LayerImpl* grand_child1 = child1->test_properties()->children[0];

  host_impl().active_tree()->SetDeviceViewportSize(root->bounds());
  host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree();

  // Sanity check the scenario we just created.
  ASSERT_TRUE(child1);
  ASSERT_TRUE(child2);
  ASSERT_TRUE(grand_child1);
  ASSERT_EQ(1u, GetRenderSurfaceList().size());

  RenderSurfaceImpl* root_render_surface = GetRenderSurface(root);
  ASSERT_EQ(4, root_render_surface->num_contributors());
  EXPECT_TRUE(root_layer()->contributes_to_drawn_render_surface());
  EXPECT_TRUE(child1->contributes_to_drawn_render_surface());
  EXPECT_TRUE(child2->contributes_to_drawn_render_surface());
  EXPECT_TRUE(grand_child1->contributes_to_drawn_render_surface());

  // Nothing overlaps the root at (1, 1), so hit testing there should find
  // the root layer.
  gfx::PointF test_point = gfx::PointF(1.f, 1.f);
  LayerImpl* result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
  ASSERT_TRUE(result_layer);
  EXPECT_EQ(1, result_layer->id());

  // At (15, 15), child1 and root are the only layers. child1 is expected to be
  // on top.
  test_point = gfx::PointF(15.f, 15.f);
  result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
  ASSERT_TRUE(result_layer);
  EXPECT_EQ(2, result_layer->id());

  // At (51, 20), child1 and child2 overlap. child2 is expected to be on top.
  test_point = gfx::PointF(51.f, 20.f);
  result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
  ASSERT_TRUE(result_layer);
  EXPECT_EQ(3, result_layer->id());

  // At (80, 51), child2 and grand_child1 overlap. child2 is expected to be on
  // top.
  test_point = gfx::PointF(80.f, 51.f);
  result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
  ASSERT_TRUE(result_layer);
  EXPECT_EQ(3, result_layer->id());

  // At (51, 51), all layers overlap each other. child2 is expected to be on top
  // of all other layers.
  test_point = gfx::PointF(51.f, 51.f);
  result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
  ASSERT_TRUE(result_layer);
  EXPECT_EQ(3, result_layer->id());

  // At (20, 51), child1 and grand_child1 overlap. grand_child1 is expected to
  // be on top.
  test_point = gfx::PointF(20.f, 51.f);
  result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
  ASSERT_TRUE(result_layer);
  EXPECT_EQ(4, result_layer->id());
}

TEST_F(LayerTreeImplTest, HitTestingSameSortingContextTied) {
  int hit_layer_id = HitTestSimpleTree(/* ids */ 1, 2, 3,
                                       /* sorting_contexts */ 10, 10, 10,
                                       /* depths */ 0, 0, 0);
  // 3 is the last in tree order, and so should be on top.
  EXPECT_EQ(3, hit_layer_id);
}

TEST_F(LayerTreeImplTest, HitTestingSameSortingContextChildWins) {
  int hit_layer_id = HitTestSimpleTree(/* ids */ 1, 2, 3,
                                       /* sorting_contexts */ 10, 10, 10,
                                       /* depths */ 0, 1, 0);
  EXPECT_EQ(2, hit_layer_id);
}

TEST_F(LayerTreeImplTest, HitTestingWithoutSortingContext) {
  int hit_layer_id = HitTestSimpleTree(/* ids */ 1, 2, 3,
                                       /* sorting_contexts */ 0, 0, 0,
                                       /* depths */ 0, 1, 0);
  EXPECT_EQ(3, hit_layer_id);
}

TEST_F(LayerTreeImplTest, HitTestingDistinctSortingContext) {
  int hit_layer_id = HitTestSimpleTree(/* ids */ 1, 2, 3,
                                       /* sorting_contexts */ 10, 11, 12,
                                       /* depths */ 0, 1, 0);
  EXPECT_EQ(3, hit_layer_id);
}

TEST_F(LayerTreeImplTest, HitTestingSameSortingContextParentWins) {
  int hit_layer_id = HitTestSimpleTree(/* ids */ 1, 2, 3,
                                       /* sorting_contexts */ 10, 10, 10,
                                       /* depths */ 0, -1, -1);
  EXPECT_EQ(1, hit_layer_id);
}

TEST_F(LayerTreeImplTest, HitTestingForMultipleLayersAtVaryingDepths) {
  LayerImpl* root = root_layer();
  root->SetBounds(gfx::Size(100, 100));
  root->SetDrawsContent(true);
  root->test_properties()->should_flatten_transform = false;
  root->test_properties()->sorting_context_id = 1;
  {
    // child 1 and child2 are initialized to overlap between x=50 and x=60.
    // grand_child is set to overlap both child1 and child2 between y=50 and
    // y=60.  The expected stacking order is: (front) child2, (second)
    // grand_child, (third) child1, and (back) the root layer behind all other
    // layers.

    std::unique_ptr<LayerImpl> child1 =
        LayerImpl::Create(host_impl().active_tree(), 2);
    std::unique_ptr<LayerImpl> child2 =
        LayerImpl::Create(host_impl().active_tree(), 3);
    std::unique_ptr<LayerImpl> grand_child1 =
        LayerImpl::Create(host_impl().active_tree(), 4);

    child1->test_properties()->position = gfx::PointF(10.f, 10.f);
    child1->SetBounds(gfx::Size(50, 50));
    child1->SetDrawsContent(true);
    child1->test_properties()->should_flatten_transform = false;
    child1->test_properties()->sorting_context_id = 1;

    child2->test_properties()->position = gfx::PointF(50.f, 10.f);
    child2->SetBounds(gfx::Size(50, 50));
    gfx::Transform translate_z;
    translate_z.Translate3d(0, 0, 10.f);
    child2->test_properties()->transform = translate_z;
    child2->SetDrawsContent(true);
    child2->test_properties()->should_flatten_transform = false;
    child2->test_properties()->sorting_context_id = 1;

    // Remember that grand_child is positioned with respect to its parent (i.e.
    // child1).  In screen space, the intended position is (10, 50), with size
    // 100 x 50.
    grand_child1->test_properties()->position = gfx::PointF(0.f, 40.f);
    grand_child1->SetBounds(gfx::Size(100, 50));
    grand_child1->SetDrawsContent(true);
    grand_child1->test_properties()->should_flatten_transform = false;

    child1->test_properties()->AddChild(std::move(grand_child1));
    root->test_properties()->AddChild(std::move(child1));
    root->test_properties()->AddChild(std::move(child2));
  }

  LayerImpl* child1 = root->test_properties()->children[0];
  LayerImpl* child2 = root->test_properties()->children[1];
  LayerImpl* grand_child1 = child1->test_properties()->children[0];

  host_impl().active_tree()->SetDeviceViewportSize(root->bounds());
  host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree();

  // Sanity check the scenario we just created.
  ASSERT_TRUE(child1);
  ASSERT_TRUE(child2);
  ASSERT_TRUE(grand_child1);
  ASSERT_EQ(1u, GetRenderSurfaceList().size());

  // Nothing overlaps the root_layer at (1, 1), so hit testing there should find
  // the root layer.
  gfx::PointF test_point = gfx::PointF(1.f, 1.f);
  LayerImpl* result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
  ASSERT_TRUE(result_layer);
  EXPECT_EQ(1, result_layer->id());

  // At (15, 15), child1 and root are the only layers. child1 is expected to be
  // on top.
  test_point = gfx::PointF(15.f, 15.f);
  result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
  ASSERT_TRUE(result_layer);
  EXPECT_EQ(2, result_layer->id());

  // At (51, 20), child1 and child2 overlap. child2 is expected to be on top,
  // as it was transformed to the foreground.
  test_point = gfx::PointF(51.f, 20.f);
  result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
  ASSERT_TRUE(result_layer);
  EXPECT_EQ(3, result_layer->id());

  // At (80, 51), child2 and grand_child1 overlap. child2 is expected to
  // be on top, as it was transformed to the foreground.
  test_point = gfx::PointF(80.f, 51.f);
  result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
  ASSERT_TRUE(result_layer);
  EXPECT_EQ(3, result_layer->id());

  // At (51, 51), child1, child2 and grand_child1 overlap. child2 is expected to
  // be on top, as it was transformed to the foreground.
  test_point = gfx::PointF(51.f, 51.f);
  result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
  ASSERT_TRUE(result_layer);
  EXPECT_EQ(3, result_layer->id());

  // At (20, 51), child1 and grand_child1 overlap. grand_child1 is expected to
  // be on top, as it descends from child1.
  test_point = gfx::PointF(20.f, 51.f);
  result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
  ASSERT_TRUE(result_layer);
  EXPECT_EQ(4, result_layer->id());
}

TEST_F(LayerTreeImplTest, HitTestingRespectsClipParents) {
  LayerImpl* root = root_layer();
  root->SetBounds(gfx::Size(100, 100));
  root->SetDrawsContent(true);
  {
    std::unique_ptr<LayerImpl> child =
        LayerImpl::Create(host_impl().active_tree(), 2);
    std::unique_ptr<LayerImpl> grand_child =
        LayerImpl::Create(host_impl().active_tree(), 4);

    child->test_properties()->position = gfx::PointF(10.f, 10.f);
    child->SetBounds(gfx::Size(1, 1));
    child->SetDrawsContent(true);
    child->SetMasksToBounds(true);

    grand_child->test_properties()->position = gfx::PointF(0.f, 40.f);
    grand_child->SetBounds(gfx::Size(100, 50));
    grand_child->SetDrawsContent(true);
    grand_child->test_properties()->force_render_surface = true;

    // This should let |grand_child| "escape" |child|'s clip.
    grand_child->test_properties()->clip_parent = root;
    std::unique_ptr<std::set<LayerImpl*>> clip_children(
        new std::set<LayerImpl*>);
    clip_children->insert(grand_child.get());
    root->test_properties()->clip_children = std::move(clip_children);

    child->test_properties()->AddChild(std::move(grand_child));
    root->test_properties()->AddChild(std::move(child));
  }

  host_impl().active_tree()->SetDeviceViewportSize(root->bounds());
  host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree();

  gfx::PointF test_point(12.f, 52.f);
  LayerImpl* result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
  ASSERT_TRUE(result_layer);
  EXPECT_EQ(4, result_layer->id());
}

TEST_F(LayerTreeImplTest, HitTestingRespectsScrollParents) {
  LayerImpl* root = root_layer();
  root->SetBounds(gfx::Size(100, 100));
  root->SetDrawsContent(true);
  {
    std::unique_ptr<LayerImpl> child =
        LayerImpl::Create(host_impl().active_tree(), 2);
    std::unique_ptr<LayerImpl> scroll_child =
        LayerImpl::Create(host_impl().active_tree(), 3);
    std::unique_ptr<LayerImpl> grand_child =
        LayerImpl::Create(host_impl().active_tree(), 4);

    child->test_properties()->position = gfx::PointF(10.f, 10.f);
    child->SetBounds(gfx::Size(1, 1));
    child->SetDrawsContent(true);
    child->SetMasksToBounds(true);

    scroll_child->SetBounds(gfx::Size(200, 200));
    scroll_child->SetDrawsContent(true);

    // This should cause scroll child and its descendants to be affected by
    // |child|'s clip.
    scroll_child->test_properties()->scroll_parent = child.get();

    grand_child->SetBounds(gfx::Size(200, 200));
    grand_child->SetDrawsContent(true);
    grand_child->test_properties()->force_render_surface = true;

    scroll_child->test_properties()->AddChild(std::move(grand_child));
    root->test_properties()->AddChild(std::move(scroll_child));
    root->test_properties()->AddChild(std::move(child));
  }

  host_impl().active_tree()->SetDeviceViewportSize(root->bounds());
  host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree();

  gfx::PointF test_point(12.f, 52.f);
  LayerImpl* result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
  // The |test_point| should have been clipped away by |child|, the scroll
  // parent, so the only thing that should be hit is |root|.
  ASSERT_TRUE(result_layer);
  ASSERT_EQ(1, result_layer->id());
}
TEST_F(LayerTreeImplTest, HitTestingForMultipleLayerLists) {
  //
  // The geometry is set up similarly to the previous case, but
  // all layers are forced to be render surfaces now.
  //
  LayerImpl* root = root_layer();
  root->SetBounds(gfx::Size(100, 100));
  root->SetDrawsContent(true);
  {
    // child 1 and child2 are initialized to overlap between x=50 and x=60.
    // grand_child is set to overlap both child1 and child2 between y=50 and
    // y=60.  The expected stacking order is: (front) child2, (second)
    // grand_child, (third) child1, and (back) the root layer behind all other
    // layers.

    std::unique_ptr<LayerImpl> child1 =
        LayerImpl::Create(host_impl().active_tree(), 2);
    std::unique_ptr<LayerImpl> child2 =
        LayerImpl::Create(host_impl().active_tree(), 3);
    std::unique_ptr<LayerImpl> grand_child1 =
        LayerImpl::Create(host_impl().active_tree(), 4);

    child1->test_properties()->position = gfx::PointF(10.f, 10.f);
    child1->SetBounds(gfx::Size(50, 50));
    child1->SetDrawsContent(true);
    child1->test_properties()->force_render_surface = true;

    child2->test_properties()->position = gfx::PointF(50.f, 10.f);
    child2->SetBounds(gfx::Size(50, 50));
    child2->SetDrawsContent(true);
    child2->test_properties()->force_render_surface = true;

    // Remember that grand_child is positioned with respect to its parent (i.e.
    // child1).  In screen space, the intended position is (10, 50), with size
    // 100 x 50.
    grand_child1->test_properties()->position = gfx::PointF(0.f, 40.f);
    grand_child1->SetBounds(gfx::Size(100, 50));
    grand_child1->SetDrawsContent(true);
    grand_child1->test_properties()->force_render_surface = true;

    child1->test_properties()->AddChild(std::move(grand_child1));
    root->test_properties()->AddChild(std::move(child1));
    root->test_properties()->AddChild(std::move(child2));

    ExecuteCalculateDrawProperties(root);
  }

  LayerImpl* child1 = root->test_properties()->children[0];
  LayerImpl* child2 = root->test_properties()->children[1];
  LayerImpl* grand_child1 = child1->test_properties()->children[0];

  host_impl().active_tree()->SetDeviceViewportSize(root->bounds());
  host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree();

  // Sanity check the scenario we just created.
  ASSERT_TRUE(child1);
  ASSERT_TRUE(child2);
  ASSERT_TRUE(grand_child1);
  ASSERT_TRUE(GetRenderSurface(child1));
  ASSERT_TRUE(GetRenderSurface(child2));
  ASSERT_TRUE(GetRenderSurface(grand_child1));
  ASSERT_EQ(4u, GetRenderSurfaceList().size());
  // The root surface has the root layer, and child1's and child2's render
  // surfaces.
  ASSERT_EQ(3, GetRenderSurface(root)->num_contributors());
  // The child1 surface has the child1 layer and grand_child1's render surface.
  ASSERT_EQ(2, GetRenderSurface(child1)->num_contributors());
  ASSERT_EQ(1, GetRenderSurface(child2)->num_contributors());
  ASSERT_EQ(1, GetRenderSurface(grand_child1)->num_contributors());
  EXPECT_TRUE(root_layer()->contributes_to_drawn_render_surface());
  EXPECT_TRUE(child1->contributes_to_drawn_render_surface());
  EXPECT_TRUE(grand_child1->contributes_to_drawn_render_surface());
  EXPECT_TRUE(child2->contributes_to_drawn_render_surface());

  // Nothing overlaps the root at (1, 1), so hit testing there should find
  // the root layer.
  gfx::PointF test_point(1.f, 1.f);
  LayerImpl* result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
  ASSERT_TRUE(result_layer);
  EXPECT_EQ(1, result_layer->id());

  // At (15, 15), child1 and root are the only layers. child1 is expected to be
  // on top.
  test_point = gfx::PointF(15.f, 15.f);
  result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
  ASSERT_TRUE(result_layer);
  EXPECT_EQ(2, result_layer->id());

  // At (51, 20), child1 and child2 overlap. child2 is expected to be on top.
  test_point = gfx::PointF(51.f, 20.f);
  result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
  ASSERT_TRUE(result_layer);
  EXPECT_EQ(3, result_layer->id());

  // At (80, 51), child2 and grand_child1 overlap. child2 is expected to be on
  // top.
  test_point = gfx::PointF(80.f, 51.f);
  result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
  ASSERT_TRUE(result_layer);
  EXPECT_EQ(3, result_layer->id());

  // At (51, 51), all layers overlap each other. child2 is expected to be on top
  // of all other layers.
  test_point = gfx::PointF(51.f, 51.f);
  result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
  ASSERT_TRUE(result_layer);
  EXPECT_EQ(3, result_layer->id());

  // At (20, 51), child1 and grand_child1 overlap. grand_child1 is expected to
  // be on top.
  test_point = gfx::PointF(20.f, 51.f);
  result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
  ASSERT_TRUE(result_layer);
  EXPECT_EQ(4, result_layer->id());
}

TEST_F(LayerTreeImplTest, HitCheckingTouchHandlerRegionsForSingleLayer) {
  TouchActionRegion touch_action_region;
  touch_action_region.Union(kTouchActionNone, gfx::Rect(10, 10, 50, 50));

  LayerImpl* root = root_layer();
  root->SetBounds(gfx::Size(100, 100));
  root->SetDrawsContent(true);

  host_impl().active_tree()->SetDeviceViewportSize(root->bounds());
  host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree();

  // Sanity check the scenario we just created.
  ASSERT_EQ(1u, GetRenderSurfaceList().size());
  ASSERT_EQ(1, GetRenderSurface(root)->num_contributors());

  // Hit checking for any point should return a null pointer for a layer without
  // any touch event handler regions.
  gfx::PointF test_point(11.f, 11.f);
  LayerImpl* result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
          test_point);
  EXPECT_FALSE(result_layer);

  root->SetTouchActionRegion(touch_action_region);
  // Hit checking for a point outside the layer should return a null pointer.
  test_point = gfx::PointF(101.f, 101.f);
  result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
          test_point);
  EXPECT_FALSE(result_layer);

  test_point = gfx::PointF(-1.f, -1.f);
  result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
          test_point);
  EXPECT_FALSE(result_layer);

  // Hit checking for a point inside the layer, but outside the touch handler
  // region should return a null pointer.
  test_point = gfx::PointF(1.f, 1.f);
  result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
          test_point);
  EXPECT_FALSE(result_layer);

  test_point = gfx::PointF(99.f, 99.f);
  result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
          test_point);
  EXPECT_FALSE(result_layer);

  // Hit checking for a point inside the touch event handler region should
  // return the root layer.
  test_point = gfx::PointF(11.f, 11.f);
  result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
          test_point);
  ASSERT_TRUE(result_layer);
  EXPECT_EQ(root->id(), result_layer->id());

  test_point = gfx::PointF(59.f, 59.f);
  result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
          test_point);
  ASSERT_TRUE(result_layer);
  EXPECT_EQ(root->id(), result_layer->id());
}

TEST_F(LayerTreeImplTest,
       HitCheckingTouchHandlerRegionsForUninvertibleTransform) {
  gfx::Transform uninvertible_transform;
  uninvertible_transform.matrix().set(0, 0, 0.0);
  uninvertible_transform.matrix().set(1, 1, 0.0);
  uninvertible_transform.matrix().set(2, 2, 0.0);
  uninvertible_transform.matrix().set(3, 3, 0.0);
  ASSERT_FALSE(uninvertible_transform.IsInvertible());

  TouchActionRegion touch_action_region;
  touch_action_region.Union(kTouchActionNone, gfx::Rect(10, 10, 50, 50));

  LayerImpl* root = root_layer();
  root->test_properties()->transform = uninvertible_transform;
  root->SetBounds(gfx::Size(100, 100));
  root->SetDrawsContent(true);
  root->SetTouchActionRegion(touch_action_region);

  host_impl().active_tree()->SetDeviceViewportSize(root->bounds());
  host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree();

  // Sanity check the scenario we just created.
  ASSERT_EQ(1u, GetRenderSurfaceList().size());
  ASSERT_EQ(1, GetRenderSurface(root)->num_contributors());
  ASSERT_FALSE(root->ScreenSpaceTransform().IsInvertible());

  // Hit checking any point should not hit the touch handler region on the
  // layer. If the invertible matrix is accidentally ignored and treated like an
  // identity, then the hit testing will incorrectly hit the layer when it
  // shouldn't.
  gfx::PointF test_point(1.f, 1.f);
  LayerImpl* result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
          test_point);
  EXPECT_FALSE(result_layer);

  test_point = gfx::PointF(10.f, 10.f);
  result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
          test_point);
  EXPECT_FALSE(result_layer);

  test_point = gfx::PointF(10.f, 30.f);
  result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
          test_point);
  EXPECT_FALSE(result_layer);

  test_point = gfx::PointF(50.f, 50.f);
  result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
          test_point);
  EXPECT_FALSE(result_layer);

  test_point = gfx::PointF(67.f, 48.f);
  result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
          test_point);
  EXPECT_FALSE(result_layer);

  test_point = gfx::PointF(99.f, 99.f);
  result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
          test_point);
  EXPECT_FALSE(result_layer);

  test_point = gfx::PointF(-1.f, -1.f);
  result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
          test_point);
  EXPECT_FALSE(result_layer);
}

TEST_F(LayerTreeImplTest,
       HitCheckingTouchHandlerRegionsForSinglePositionedLayer) {
  TouchActionRegion touch_action_region;
  touch_action_region.Union(kTouchActionNone, gfx::Rect(10, 10, 50, 50));

  // This layer is positioned, and hit testing should correctly know where the
  // layer is located.
  {
    std::unique_ptr<LayerImpl> test_layer =
        LayerImpl::Create(host_impl().active_tree(), 12345);
    test_layer->test_properties()->position = gfx::PointF(50.f, 50.f);
    test_layer->SetBounds(gfx::Size(100, 100));
    test_layer->SetDrawsContent(true);
    test_layer->SetTouchActionRegion(touch_action_region);
    root_layer()->test_properties()->AddChild(std::move(test_layer));
  }

  LayerImpl* test_layer = root_layer()->test_properties()->children[0];
  host_impl().active_tree()->SetDeviceViewportSize(test_layer->bounds());
  host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree();

  // Sanity check the scenario we just created.
  ASSERT_EQ(1u, GetRenderSurfaceList().size());
  ASSERT_EQ(1, GetRenderSurface(test_layer)->num_contributors());

  // Hit checking for a point outside the layer should return a null pointer.
  gfx::PointF test_point(49.f, 49.f);
  LayerImpl* result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
          test_point);
  EXPECT_FALSE(result_layer);

  // Even though the layer has a touch handler region containing (101, 101), it
  // should not be visible there since the root render surface would clamp it.
  test_point = gfx::PointF(101.f, 101.f);
  result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
          test_point);
  EXPECT_FALSE(result_layer);

  // Hit checking for a point inside the layer, but outside the touch handler
  // region should return a null pointer.
  test_point = gfx::PointF(51.f, 51.f);
  result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
          test_point);
  EXPECT_FALSE(result_layer);

  // Hit checking for a point inside the touch event handler region should
  // return the test layer.
  test_point = gfx::PointF(61.f, 61.f);
  result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
          test_point);
  ASSERT_TRUE(result_layer);
  EXPECT_EQ(test_layer->id(), result_layer->id());

  test_point = gfx::PointF(99.f, 99.f);
  result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
          test_point);
  ASSERT_TRUE(result_layer);
  EXPECT_EQ(test_layer->id(), result_layer->id());
}

TEST_F(LayerTreeImplTest,
       HitCheckingTouchHandlerRegionsForSingleLayerWithDeviceScale) {
  // The layer's device_scale_factor and page_scale_factor should scale the
  // content rect and we should be able to hit the touch handler region by
  // scaling the points accordingly.

  // Set the bounds of the root layer big enough to fit the child when scaled.
  LayerImpl* root = root_layer();
  root->SetBounds(gfx::Size(100, 100));
  {
    TouchActionRegion touch_action_region;
    touch_action_region.Union(kTouchActionNone, gfx::Rect(10, 10, 30, 30));
    std::unique_ptr<LayerImpl> test_layer =
        LayerImpl::Create(host_impl().active_tree(), 12345);
    test_layer->test_properties()->position = gfx::PointF(25.f, 25.f);
    test_layer->SetBounds(gfx::Size(50, 50));
    test_layer->SetDrawsContent(true);
    test_layer->SetTouchActionRegion(touch_action_region);
    root->test_properties()->AddChild(std::move(test_layer));
  }

  float device_scale_factor = 3.f;
  float page_scale_factor = 5.f;
  float max_page_scale_factor = 10.f;
  gfx::Size scaled_bounds_for_root = gfx::ScaleToCeiledSize(
      root->bounds(), device_scale_factor * page_scale_factor);
  host_impl().active_tree()->SetDeviceViewportSize(scaled_bounds_for_root);

  host_impl().active_tree()->SetDeviceScaleFactor(device_scale_factor);
  LayerTreeImpl::ViewportLayerIds viewport_ids;
  viewport_ids.page_scale = 1;
  viewport_ids.inner_viewport_scroll = 1;
  host_impl().active_tree()->SetViewportLayersFromIds(viewport_ids);
  host_impl().active_tree()->BuildLayerListAndPropertyTreesForTesting();
  host_impl().active_tree()->PushPageScaleFromMainThread(
      page_scale_factor, page_scale_factor, max_page_scale_factor);
  host_impl().active_tree()->SetPageScaleOnActiveTree(page_scale_factor);
  host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree();

  // Sanity check the scenario we just created.
  // The visible content rect for test_layer is actually 100x100, even though
  // its layout size is 50x50, positioned at 25x25.
  LayerImpl* test_layer = root->test_properties()->children[0];
  ASSERT_EQ(1u, GetRenderSurfaceList().size());
  ASSERT_EQ(1, GetRenderSurface(root)->num_contributors());

  // Check whether the child layer fits into the root after scaled.
  EXPECT_EQ(gfx::Rect(test_layer->bounds()), test_layer->visible_layer_rect());

  // Hit checking for a point outside the layer should return a null pointer
  // (the root layer does not have a touch event handler, so it will not be
  // tested either).
  gfx::PointF test_point(76.f, 76.f);
  test_point =
      gfx::ScalePoint(test_point, device_scale_factor * page_scale_factor);
  LayerImpl* result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
          test_point);
  EXPECT_FALSE(result_layer);

  // Hit checking for a point inside the layer, but outside the touch handler
  // region should return a null pointer.
  test_point = gfx::PointF(26.f, 26.f);
  test_point =
      gfx::ScalePoint(test_point, device_scale_factor * page_scale_factor);
  result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
          test_point);
  EXPECT_FALSE(result_layer);

  test_point = gfx::PointF(34.f, 34.f);
  test_point =
      gfx::ScalePoint(test_point, device_scale_factor * page_scale_factor);
  result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
          test_point);
  EXPECT_FALSE(result_layer);

  test_point = gfx::PointF(65.f, 65.f);
  test_point =
      gfx::ScalePoint(test_point, device_scale_factor * page_scale_factor);
  result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
          test_point);
  EXPECT_FALSE(result_layer);

  test_point = gfx::PointF(74.f, 74.f);
  test_point =
      gfx::ScalePoint(test_point, device_scale_factor * page_scale_factor);
  result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
          test_point);
  EXPECT_FALSE(result_layer);

  // Hit checking for a point inside the touch event handler region should
  // return the root layer.
  test_point = gfx::PointF(35.f, 35.f);
  test_point =
      gfx::ScalePoint(test_point, device_scale_factor * page_scale_factor);
  result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
          test_point);
  ASSERT_TRUE(result_layer);
  EXPECT_EQ(12345, result_layer->id());

  test_point = gfx::PointF(64.f, 64.f);
  test_point =
      gfx::ScalePoint(test_point, device_scale_factor * page_scale_factor);
  result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
          test_point);
  ASSERT_TRUE(result_layer);
  EXPECT_EQ(12345, result_layer->id());

  // Check update of page scale factor on the active tree when page scale layer
  // is also the root layer.
  page_scale_factor *= 1.5f;
  host_impl().active_tree()->SetPageScaleOnActiveTree(page_scale_factor);
  EXPECT_EQ(root, host_impl().active_tree()->PageScaleLayer());

  test_point = gfx::PointF(35.f, 35.f);
  test_point =
      gfx::ScalePoint(test_point, device_scale_factor * page_scale_factor);
  result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
          test_point);
  ASSERT_TRUE(result_layer);
  EXPECT_EQ(12345, result_layer->id());

  test_point = gfx::PointF(64.f, 64.f);
  test_point =
      gfx::ScalePoint(test_point, device_scale_factor * page_scale_factor);
  result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
          test_point);
  ASSERT_TRUE(result_layer);
  EXPECT_EQ(12345, result_layer->id());
}

TEST_F(LayerTreeImplTest, HitCheckingTouchHandlerRegionsForSimpleClippedLayer) {
  // Test that hit-checking will only work for the visible portion of a layer,
  // and not the entire layer bounds. Here we just test the simple axis-aligned
  // case.
  LayerImpl* root = root_layer();
  root->SetBounds(gfx::Size(100, 100));
  {
    std::unique_ptr<LayerImpl> clipping_layer =
        LayerImpl::Create(host_impl().active_tree(), 123);
    // this layer is positioned, and hit testing should correctly know where the
    // layer is located.
    clipping_layer->test_properties()->position = gfx::PointF(25.f, 25.f);
    clipping_layer->SetBounds(gfx::Size(50, 50));
    clipping_layer->SetMasksToBounds(true);

    TouchActionRegion touch_action_region;
    touch_action_region.Union(kTouchActionNone, gfx::Rect(10, 10, 50, 50));

    std::unique_ptr<LayerImpl> child =
        LayerImpl::Create(host_impl().active_tree(), 456);
    child->test_properties()->position = gfx::PointF(-50.f, -50.f);
    child->SetBounds(gfx::Size(300, 300));
    child->SetDrawsContent(true);
    child->SetTouchActionRegion(touch_action_region);
    clipping_layer->test_properties()->AddChild(std::move(child));
    root->test_properties()->AddChild(std::move(clipping_layer));
  }

  host_impl().active_tree()->SetDeviceViewportSize(root->bounds());
  host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree();

  // Sanity check the scenario we just created.
  ASSERT_EQ(1u, GetRenderSurfaceList().size());
  ASSERT_EQ(1, GetRenderSurface(root)->num_contributors());
  LayerImpl* child_layer = host_impl().active_tree()->LayerById(456);
  EXPECT_TRUE(child_layer->contributes_to_drawn_render_surface());

  // Hit checking for a point outside the layer should return a null pointer.
  // Despite the child layer being very large, it should be clipped to the root
  // layer's bounds.
  gfx::PointF test_point(24.f, 24.f);
  LayerImpl* result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
          test_point);
  EXPECT_FALSE(result_layer);

  // Hit checking for a point inside the layer, but outside the touch handler
  // region should return a null pointer.
  test_point = gfx::PointF(35.f, 35.f);
  result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
          test_point);
  EXPECT_FALSE(result_layer);

  test_point = gfx::PointF(74.f, 74.f);
  result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
          test_point);
  EXPECT_FALSE(result_layer);

  // Hit checking for a point inside the touch event handler region should
  // return the root layer.
  test_point = gfx::PointF(25.f, 25.f);
  result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
          test_point);
  ASSERT_TRUE(result_layer);
  EXPECT_EQ(456, result_layer->id());

  test_point = gfx::PointF(34.f, 34.f);
  result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
          test_point);
  ASSERT_TRUE(result_layer);
  EXPECT_EQ(456, result_layer->id());
}

TEST_F(LayerTreeImplTest,
       HitCheckingTouchHandlerRegionsForClippedLayerWithDeviceScale) {
  // The layer's device_scale_factor and page_scale_factor should scale the
  // content rect and we should be able to hit the touch handler region by
  // scaling the points accordingly.

  // Set the bounds of the root layer big enough to fit the child when scaled.
  LayerImpl* root = root_layer();
  root->SetBounds(gfx::Size(100, 100));
  std::unique_ptr<LayerImpl> surface =
      LayerImpl::Create(host_impl().active_tree(), 2);
  surface->SetBounds(gfx::Size(100, 100));
  surface->test_properties()->force_render_surface = true;
  {
    std::unique_ptr<LayerImpl> clipping_layer =
        LayerImpl::Create(host_impl().active_tree(), 123);
    // This layer is positioned, and hit testing should correctly know where the
    // layer is located.
    clipping_layer->test_properties()->position = gfx::PointF(25.f, 20.f);
    clipping_layer->SetBounds(gfx::Size(50, 50));
    clipping_layer->SetMasksToBounds(true);

    TouchActionRegion touch_action_region;
    touch_action_region.Union(kTouchActionNone, gfx::Rect(0, 0, 300, 300));

    std::unique_ptr<LayerImpl> child =
        LayerImpl::Create(host_impl().active_tree(), 456);
    child->test_properties()->position = gfx::PointF(-50.f, -50.f);
    child->SetBounds(gfx::Size(300, 300));
    child->SetDrawsContent(true);
    child->SetTouchActionRegion(touch_action_region);
    clipping_layer->test_properties()->AddChild(std::move(child));
    surface->test_properties()->AddChild(std::move(clipping_layer));
    root->test_properties()->AddChild(std::move(surface));
  }

  float device_scale_factor = 3.f;
  float page_scale_factor = 1.f;
  float max_page_scale_factor = 1.f;
  gfx::Size scaled_bounds_for_root = gfx::ScaleToCeiledSize(
      root->bounds(), device_scale_factor * page_scale_factor);
  host_impl().active_tree()->SetDeviceViewportSize(scaled_bounds_for_root);

  host_impl().active_tree()->SetDeviceScaleFactor(device_scale_factor);
  LayerTreeImpl::ViewportLayerIds viewport_ids;
  viewport_ids.page_scale = 1;
  viewport_ids.inner_viewport_scroll = 1;
  host_impl().active_tree()->SetViewportLayersFromIds(viewport_ids);
  host_impl().active_tree()->BuildLayerListAndPropertyTreesForTesting();
  host_impl().active_tree()->PushPageScaleFromMainThread(
      page_scale_factor, page_scale_factor, max_page_scale_factor);
  host_impl().active_tree()->SetPageScaleOnActiveTree(page_scale_factor);
  host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree();

  // Sanity check the scenario we just created.
  ASSERT_EQ(2u, GetRenderSurfaceList().size());

  // Hit checking for a point outside the layer should return a null pointer.
  // Despite the child layer being very large, it should be clipped to the root
  // layer's bounds.
  gfx::PointF test_point(24.f, 24.f);
  test_point =
      gfx::ScalePoint(test_point, device_scale_factor * page_scale_factor);
  LayerImpl* result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
          test_point);
  EXPECT_FALSE(result_layer);

  // Hit checking for a point inside the touch event handler region should
  // return the child layer.
  test_point = gfx::PointF(25.f, 25.f);
  test_point =
      gfx::ScalePoint(test_point, device_scale_factor * page_scale_factor);
  result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
          test_point);
  ASSERT_TRUE(result_layer);
  EXPECT_EQ(456, result_layer->id());
}

TEST_F(LayerTreeImplTest, HitCheckingTouchHandlerOverlappingRegions) {
  LayerImpl* root = root_layer();
  root->SetBounds(gfx::Size(100, 100));
  {
    std::unique_ptr<LayerImpl> touch_layer =
        LayerImpl::Create(host_impl().active_tree(), 123);
    // this layer is positioned, and hit testing should correctly know where the
    // layer is located.
    touch_layer->SetBounds(gfx::Size(50, 50));
    touch_layer->SetDrawsContent(true);
    TouchActionRegion touch_action_region;
    touch_action_region.Union(kTouchActionNone, gfx::Rect(0, 0, 50, 50));
    touch_layer->SetTouchActionRegion(touch_action_region);
    root->test_properties()->AddChild(std::move(touch_layer));
  }

  {
    std::unique_ptr<LayerImpl> notouch_layer =
        LayerImpl::Create(host_impl().active_tree(), 1234);
    // this layer is positioned, and hit testing should correctly know where the
    // layer is located.
    notouch_layer->test_properties()->position = gfx::PointF(0, 25);
    notouch_layer->SetBounds(gfx::Size(50, 50));
    notouch_layer->SetDrawsContent(true);
    root->test_properties()->AddChild(std::move(notouch_layer));
  }

  host_impl().active_tree()->SetDeviceViewportSize(root->bounds());
  host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree();

  // Sanity check the scenario we just created.
  ASSERT_EQ(1u, GetRenderSurfaceList().size());
  ASSERT_EQ(2, GetRenderSurface(root)->num_contributors());
  LayerImpl* touch_layer = host_impl().active_tree()->LayerById(123);
  LayerImpl* notouch_layer = host_impl().active_tree()->LayerById(1234);
  EXPECT_TRUE(touch_layer->contributes_to_drawn_render_surface());
  EXPECT_TRUE(notouch_layer->contributes_to_drawn_render_surface());

  gfx::PointF test_point(35.f, 35.f);
  LayerImpl* result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
          test_point);

  // We should have passed through the no-touch layer and found the layer
  // behind it.
  EXPECT_TRUE(result_layer);

  host_impl().active_tree()->LayerById(1234)->SetContentsOpaque(true);
  result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
          test_point);

  // Even with an opaque layer in the middle, we should still find the layer
  // with
  // the touch handler behind it (since we can't assume that opaque layers are
  // opaque to hit testing).
  EXPECT_TRUE(result_layer);

  test_point = gfx::PointF(35.f, 15.f);
  result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
          test_point);
  ASSERT_TRUE(result_layer);
  EXPECT_EQ(123, result_layer->id());

  test_point = gfx::PointF(35.f, 65.f);
  result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
          test_point);
  EXPECT_FALSE(result_layer);
}

TEST_F(LayerTreeImplTest, HitTestingTouchHandlerRegionsForLayerThatIsNotDrawn) {
  LayerImpl* root = root_layer();
  root->SetBounds(gfx::Size(100, 100));
  root->SetDrawsContent(true);
  {
    TouchActionRegion touch_action_region;
    touch_action_region.Union(kTouchActionNone, gfx::Rect(10, 10, 30, 30));
    std::unique_ptr<LayerImpl> test_layer =
        LayerImpl::Create(host_impl().active_tree(), 12345);
    test_layer->SetBounds(gfx::Size(50, 50));
    test_layer->SetDrawsContent(false);
    test_layer->SetTouchActionRegion(touch_action_region);
    root->test_properties()->AddChild(std::move(test_layer));
  }
  host_impl().active_tree()->SetDeviceViewportSize(root->bounds());
  host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree();

  LayerImpl* test_layer = root->test_properties()->children[0];
  // As test_layer doesn't draw content, it shouldn't contribute content to the
  // root surface.
  ASSERT_EQ(1u, GetRenderSurfaceList().size());
  EXPECT_FALSE(test_layer->contributes_to_drawn_render_surface());

  // Hit testing for a point outside the test layer should return null pointer.
  // We also implicitly check that the updated screen space transform of a layer
  // that is not in drawn render surface layer list (test_layer) is used during
  // hit testing (becuase the point is inside test_layer with respect to the old
  // screen space transform).
  gfx::PointF test_point(24.f, 24.f);
  test_layer->test_properties()->position = gfx::PointF(25.f, 25.f);
  gfx::Transform expected_screen_space_transform;
  expected_screen_space_transform.Translate(25.f, 25.f);

  host_impl().active_tree()->property_trees()->needs_rebuild = true;
  host_impl().active_tree()->BuildLayerListAndPropertyTreesForTesting();
  LayerImpl* result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
          test_point);
  EXPECT_FALSE(result_layer);
  EXPECT_FALSE(test_layer->contributes_to_drawn_render_surface());
  EXPECT_TRANSFORMATION_MATRIX_EQ(
      expected_screen_space_transform,
      draw_property_utils::ScreenSpaceTransform(
          test_layer,
          host_impl().active_tree()->property_trees()->transform_tree));

  // We change the position of the test layer such that the test point is now
  // inside the test_layer.
  test_layer = root->test_properties()->children[0];
  test_layer->test_properties()->position = gfx::PointF(10.f, 10.f);
  test_layer->NoteLayerPropertyChanged();
  expected_screen_space_transform.MakeIdentity();
  expected_screen_space_transform.Translate(10.f, 10.f);

  host_impl().active_tree()->property_trees()->needs_rebuild = true;
  host_impl().active_tree()->BuildLayerListAndPropertyTreesForTesting();
  result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
          test_point);
  ASSERT_TRUE(result_layer);
  ASSERT_EQ(test_layer, result_layer);
  EXPECT_FALSE(result_layer->contributes_to_drawn_render_surface());
  EXPECT_TRANSFORMATION_MATRIX_EQ(
      expected_screen_space_transform,
      draw_property_utils::ScreenSpaceTransform(
          test_layer,
          host_impl().active_tree()->property_trees()->transform_tree));
}

TEST_F(LayerTreeImplTest, SelectionBoundsForSingleLayer) {
  LayerImpl* root = root_layer();
  root->SetBounds(gfx::Size(100, 100));
  root->SetDrawsContent(true);

  host_impl().active_tree()->SetDeviceViewportSize(root->bounds());
  host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree();

  // Sanity check the scenario we just created.
  ASSERT_EQ(1u, GetRenderSurfaceList().size());
  ASSERT_EQ(1, GetRenderSurface(root)->num_contributors());

  LayerSelection input;

  input.start.type = gfx::SelectionBound::LEFT;
  input.start.edge_top = gfx::Point(10, 10);
  input.start.edge_bottom = gfx::Point(10, 20);
  input.start.layer_id = root->id();

  input.end.type = gfx::SelectionBound::RIGHT;
  input.end.edge_top = gfx::Point(50, 10);
  input.end.edge_bottom = gfx::Point(50, 30);
  input.end.layer_id = root->id();

  viz::Selection<gfx::SelectionBound> output;

  // Empty input bounds should produce empty output bounds.
  host_impl().active_tree()->GetViewportSelection(&output);
  EXPECT_EQ(gfx::SelectionBound(), output.start);
  EXPECT_EQ(gfx::SelectionBound(), output.end);

  // Selection bounds should produce distinct left and right bounds.
  host_impl().active_tree()->RegisterSelection(input);
  host_impl().active_tree()->GetViewportSelection(&output);
  EXPECT_EQ(input.start.type, output.start.type());
  EXPECT_EQ(gfx::PointF(input.start.edge_bottom), output.start.edge_bottom());
  EXPECT_EQ(gfx::PointF(input.start.edge_top), output.start.edge_top());
  EXPECT_TRUE(output.start.visible());
  EXPECT_EQ(input.end.type, output.end.type());
  EXPECT_EQ(gfx::PointF(input.end.edge_bottom), output.end.edge_bottom());
  EXPECT_EQ(gfx::PointF(input.end.edge_top), output.end.edge_top());
  EXPECT_TRUE(output.end.visible());

  // Insertion bounds should produce identical left and right bounds.
  LayerSelection insertion_input;
  insertion_input.start.type = gfx::SelectionBound::CENTER;
  insertion_input.start.edge_top = gfx::Point(15, 10);
  insertion_input.start.edge_bottom = gfx::Point(15, 30);
  insertion_input.start.layer_id = root->id();
  insertion_input.end = insertion_input.start;
  host_impl().active_tree()->RegisterSelection(insertion_input);
  host_impl().active_tree()->GetViewportSelection(&output);
  EXPECT_EQ(insertion_input.start.type, output.start.type());
  EXPECT_EQ(gfx::PointF(insertion_input.start.edge_bottom),
            output.start.edge_bottom());
  EXPECT_EQ(gfx::PointF(insertion_input.start.edge_top),
            output.start.edge_top());
  EXPECT_TRUE(output.start.visible());
  EXPECT_EQ(output.start, output.end);
}

TEST_F(LayerTreeImplTest, SelectionBoundsForPartialOccludedLayers) {
  LayerImpl* root = root_layer();
  root->SetDrawsContent(true);
  root->SetBounds(gfx::Size(100, 100));

  int clip_layer_id = 1234;
  int clipped_layer_id = 123;

  gfx::Vector2dF clipping_offset(10, 10);
  {
    std::unique_ptr<LayerImpl> clipping_layer =
        LayerImpl::Create(host_impl().active_tree(), clip_layer_id);
    // The clipping layer should occlude the right selection bound.
    clipping_layer->test_properties()->position =
        gfx::PointF() + clipping_offset;
    clipping_layer->SetBounds(gfx::Size(50, 50));
    clipping_layer->SetMasksToBounds(true);

    std::unique_ptr<LayerImpl> clipped_layer =
        LayerImpl::Create(host_impl().active_tree(), clipped_layer_id);
    clipped_layer->SetBounds(gfx::Size(100, 100));
    clipped_layer->SetDrawsContent(true);
    clipping_layer->test_properties()->AddChild(std::move(clipped_layer));
    root->test_properties()->AddChild(std::move(clipping_layer));
  }

  host_impl().active_tree()->SetDeviceViewportSize(root->bounds());
  host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree();

  // Sanity check the scenario we just created.
  ASSERT_EQ(1u, GetRenderSurfaceList().size());

  LayerSelection input;
  input.start.type = gfx::SelectionBound::LEFT;
  input.start.edge_top = gfx::Point(25, 10);
  input.start.edge_bottom = gfx::Point(25, 30);
  input.start.layer_id = clipped_layer_id;

  input.end.type = gfx::SelectionBound::RIGHT;
  input.end.edge_top = gfx::Point(75, 10);
  input.end.edge_bottom = gfx::Point(75, 30);
  input.end.layer_id = clipped_layer_id;
  host_impl().active_tree()->RegisterSelection(input);

  // The left bound should be occluded by the clip layer.
  viz::Selection<gfx::SelectionBound> output;
  host_impl().active_tree()->GetViewportSelection(&output);
  EXPECT_EQ(input.start.type, output.start.type());
  auto expected_output_start_top = gfx::PointF(input.start.edge_top);
  auto expected_output_edge_botom = gfx::PointF(input.start.edge_bottom);
  expected_output_start_top.Offset(clipping_offset.x(), clipping_offset.y());
  expected_output_edge_botom.Offset(clipping_offset.x(), clipping_offset.y());
  EXPECT_EQ(expected_output_start_top, output.start.edge_top());
  EXPECT_EQ(expected_output_edge_botom, output.start.edge_bottom());
  EXPECT_TRUE(output.start.visible());
  EXPECT_EQ(input.end.type, output.end.type());
  auto expected_output_end_top = gfx::PointF(input.end.edge_top);
  auto expected_output_end_bottom = gfx::PointF(input.end.edge_bottom);
  expected_output_end_bottom.Offset(clipping_offset.x(), clipping_offset.y());
  expected_output_end_top.Offset(clipping_offset.x(), clipping_offset.y());
  EXPECT_EQ(expected_output_end_top, output.end.edge_top());
  EXPECT_EQ(expected_output_end_bottom, output.end.edge_bottom());
  EXPECT_FALSE(output.end.visible());

  // Handles outside the viewport bounds should be marked invisible.
  input.start.edge_top = gfx::Point(-25, 0);
  input.start.edge_bottom = gfx::Point(-25, 20);
  host_impl().active_tree()->RegisterSelection(input);
  host_impl().active_tree()->GetViewportSelection(&output);
  EXPECT_FALSE(output.start.visible());

  input.start.edge_top = gfx::Point(0, -25);
  input.start.edge_bottom = gfx::Point(0, -5);
  host_impl().active_tree()->RegisterSelection(input);
  host_impl().active_tree()->GetViewportSelection(&output);
  EXPECT_FALSE(output.start.visible());

  // If the handle bottom is partially visible, the handle is marked visible.
  input.start.edge_top = gfx::Point(0, -20);
  input.start.edge_bottom = gfx::Point(0, 1);
  host_impl().active_tree()->RegisterSelection(input);
  host_impl().active_tree()->GetViewportSelection(&output);
  EXPECT_TRUE(output.start.visible());
}

TEST_F(LayerTreeImplTest, SelectionBoundsForScaledLayers) {
  LayerImpl* root = root_layer();
  root->SetDrawsContent(true);
  root->SetBounds(gfx::Size(100, 100));

  int root_layer_id = root->id();
  int sub_layer_id = 2;

  gfx::Vector2dF sub_layer_offset(10, 0);
  {
    std::unique_ptr<LayerImpl> sub_layer =
        LayerImpl::Create(host_impl().active_tree(), sub_layer_id);
    sub_layer->test_properties()->position = gfx::PointF() + sub_layer_offset;
    sub_layer->SetBounds(gfx::Size(50, 50));
    sub_layer->SetDrawsContent(true);
    root->test_properties()->AddChild(std::move(sub_layer));
  }

  host_impl().active_tree()->BuildPropertyTreesForTesting();

  float device_scale_factor = 3.f;
  float page_scale_factor = 5.f;
  gfx::Size scaled_bounds_for_root = gfx::ScaleToCeiledSize(
      root->bounds(), device_scale_factor * page_scale_factor);
  host_impl().active_tree()->SetDeviceViewportSize(scaled_bounds_for_root);

  LayerTreeImpl::ViewportLayerIds viewport_ids;
  viewport_ids.page_scale = root->id();
  host_impl().active_tree()->SetViewportLayersFromIds(viewport_ids);
  host_impl().active_tree()->SetDeviceScaleFactor(device_scale_factor);
  host_impl().active_tree()->SetPageScaleOnActiveTree(page_scale_factor);

  host_impl().active_tree()->PushPageScaleFromMainThread(
      page_scale_factor, page_scale_factor, page_scale_factor);
  host_impl().active_tree()->SetPageScaleOnActiveTree(page_scale_factor);
  host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree();

  // Sanity check the scenario we just created.
  ASSERT_EQ(1u, GetRenderSurfaceList().size());

  LayerSelection input;
  input.start.type = gfx::SelectionBound::LEFT;
  input.start.edge_top = gfx::Point(10, 10);
  input.start.edge_bottom = gfx::Point(10, 30);
  input.start.layer_id = root_layer_id;

  input.end.type = gfx::SelectionBound::RIGHT;
  input.end.edge_top = gfx::Point(0, 0);
  input.end.edge_bottom = gfx::Point(0, 20);
  input.end.layer_id = sub_layer_id;
  host_impl().active_tree()->RegisterSelection(input);

  // The viewport bounds should be properly scaled by the page scale, but should
  // remain in DIP coordinates.
  viz::Selection<gfx::SelectionBound> output;
  host_impl().active_tree()->GetViewportSelection(&output);
  EXPECT_EQ(input.start.type, output.start.type());
  auto expected_output_start_top = gfx::PointF(input.start.edge_top);
  auto expected_output_edge_bottom = gfx::PointF(input.start.edge_bottom);
  expected_output_start_top.Scale(page_scale_factor);
  expected_output_edge_bottom.Scale(page_scale_factor);
  EXPECT_EQ(expected_output_start_top, output.start.edge_top());
  EXPECT_EQ(expected_output_edge_bottom, output.start.edge_bottom());
  EXPECT_TRUE(output.start.visible());
  EXPECT_EQ(input.end.type, output.end.type());

  auto expected_output_end_top = gfx::PointF(input.end.edge_top);
  auto expected_output_end_bottom = gfx::PointF(input.end.edge_bottom);
  expected_output_end_top.Offset(sub_layer_offset.x(), sub_layer_offset.y());
  expected_output_end_bottom.Offset(sub_layer_offset.x(), sub_layer_offset.y());
  expected_output_end_top.Scale(page_scale_factor);
  expected_output_end_bottom.Scale(page_scale_factor);
  EXPECT_EQ(expected_output_end_top, output.end.edge_top());
  EXPECT_EQ(expected_output_end_bottom, output.end.edge_bottom());
  EXPECT_TRUE(output.end.visible());
}

TEST_F(LayerTreeImplTest, SelectionBoundsForDSFEnabled) {
  LayerImpl* root = root_layer();
  root->SetDrawsContent(true);
  root->SetBounds(gfx::Size(100, 100));
  host_impl().active_tree()->SetDeviceViewportSize(root->bounds());

  int root_layer_id = root->id();
  int sub_layer_id = 2;

  gfx::Vector2dF sub_layer_offset(10, 0);
  {
    std::unique_ptr<LayerImpl> sub_layer =
        LayerImpl::Create(host_impl().active_tree(), sub_layer_id);
    sub_layer->test_properties()->position = gfx::PointF() + sub_layer_offset;
    sub_layer->SetBounds(gfx::Size(50, 50));
    sub_layer->SetDrawsContent(true);
    root->test_properties()->AddChild(std::move(sub_layer));
  }

  host_impl().active_tree()->BuildPropertyTreesForTesting();

  float device_scale_factor = 3.f;
  float painted_device_scale_factor = 5.f;

  LayerTreeImpl::ViewportLayerIds viewport_ids;
  viewport_ids.page_scale = root->id();
  host_impl().active_tree()->SetViewportLayersFromIds(viewport_ids);
  host_impl().active_tree()->SetDeviceScaleFactor(device_scale_factor);
  host_impl().active_tree()->set_painted_device_scale_factor(
      painted_device_scale_factor);

  LayerSelection input;
  input.start.type = gfx::SelectionBound::LEFT;
  input.start.edge_top = gfx::Point(10, 10);
  input.start.edge_bottom = gfx::Point(10, 30);
  input.start.layer_id = root_layer_id;

  input.end.type = gfx::SelectionBound::RIGHT;
  input.end.edge_top = gfx::Point(0, 0);
  input.end.edge_bottom = gfx::Point(0, 20);
  input.end.layer_id = sub_layer_id;
  host_impl().active_tree()->RegisterSelection(input);

  // The viewport bounds should be properly scaled by the page scale, but should
  // remain in DIP coordinates.
  viz::Selection<gfx::SelectionBound> output;
  host_impl().active_tree()->GetViewportSelection(&output);
  EXPECT_EQ(input.start.type, output.start.type());
  auto expected_output_start_top = gfx::PointF(input.start.edge_top);
  auto expected_output_edge_bottom = gfx::PointF(input.start.edge_bottom);
  expected_output_start_top.Scale(
      1.f / (device_scale_factor * painted_device_scale_factor));
  expected_output_edge_bottom.Scale(
      1.f / (device_scale_factor * painted_device_scale_factor));
  EXPECT_EQ(expected_output_start_top, output.start.edge_top());
  EXPECT_EQ(expected_output_edge_bottom, output.start.edge_bottom());
  EXPECT_TRUE(output.start.visible());
  EXPECT_EQ(input.end.type, output.end.type());

  auto expected_output_end_top = gfx::PointF(input.end.edge_top);
  auto expected_output_end_bottom = gfx::PointF(input.end.edge_bottom);
  expected_output_end_top.Offset(sub_layer_offset.x(), sub_layer_offset.y());
  expected_output_end_bottom.Offset(sub_layer_offset.x(), sub_layer_offset.y());
  expected_output_end_top.Scale(
      1.f / (device_scale_factor * painted_device_scale_factor));
  expected_output_end_bottom.Scale(
      1.f / (device_scale_factor * painted_device_scale_factor));
  EXPECT_EQ(expected_output_end_top, output.end.edge_top());
  EXPECT_EQ(expected_output_end_bottom, output.end.edge_bottom());
  EXPECT_TRUE(output.end.visible());
}

TEST_F(LayerTreeImplTest, SelectionBoundsWithLargeTransforms) {
  LayerImpl* root = root_layer();
  root->SetBounds(gfx::Size(100, 100));

  int child_id = 2;
  int grand_child_id = 3;

  gfx::Transform large_transform;
  large_transform.Scale(SkDoubleToMScalar(1e37), SkDoubleToMScalar(1e37));
  large_transform.RotateAboutYAxis(30);

  {
    std::unique_ptr<LayerImpl> child =
        LayerImpl::Create(host_impl().active_tree(), child_id);
    child->test_properties()->transform = large_transform;
    child->SetBounds(gfx::Size(100, 100));

    std::unique_ptr<LayerImpl> grand_child =
        LayerImpl::Create(host_impl().active_tree(), grand_child_id);
    grand_child->test_properties()->transform = large_transform;
    grand_child->SetBounds(gfx::Size(100, 100));
    grand_child->SetDrawsContent(true);

    child->test_properties()->AddChild(std::move(grand_child));
    root->test_properties()->AddChild(std::move(child));
  }

  host_impl().active_tree()->SetDeviceViewportSize(root->bounds());
  host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree();

  LayerSelection input;

  input.start.type = gfx::SelectionBound::LEFT;
  input.start.edge_top = gfx::Point(10, 10);
  input.start.edge_bottom = gfx::Point(10, 20);
  input.start.layer_id = grand_child_id;

  input.end.type = gfx::SelectionBound::RIGHT;
  input.end.edge_top = gfx::Point(50, 10);
  input.end.edge_bottom = gfx::Point(50, 30);
  input.end.layer_id = grand_child_id;

  host_impl().active_tree()->RegisterSelection(input);

  viz::Selection<gfx::SelectionBound> output;
  host_impl().active_tree()->GetViewportSelection(&output);

  // edge_bottom and edge_top aren't allowed to have NaNs, so the selection
  // should be empty.
  EXPECT_EQ(gfx::SelectionBound(), output.start);
  EXPECT_EQ(gfx::SelectionBound(), output.end);
}

TEST_F(LayerTreeImplTest, NumLayersTestOne) {
  // Root is created by the test harness.
  EXPECT_EQ(1u, host_impl().active_tree()->NumLayers());
  EXPECT_TRUE(root_layer());
  // Create another layer, should increment.
  auto layer = LayerImpl::Create(host_impl().active_tree(), 2);
  EXPECT_EQ(2u, host_impl().active_tree()->NumLayers());
}

TEST_F(LayerTreeImplTest, NumLayersSmallTree) {
  EXPECT_EQ(1u, host_impl().active_tree()->NumLayers());
  LayerImpl* root = root_layer();
  root->test_properties()->AddChild(
      LayerImpl::Create(host_impl().active_tree(), 2));
  root->test_properties()->AddChild(
      LayerImpl::Create(host_impl().active_tree(), 3));
  root->test_properties()->children[1]->test_properties()->AddChild(
      LayerImpl::Create(host_impl().active_tree(), 4));
  EXPECT_EQ(4u, host_impl().active_tree()->NumLayers());
}

TEST_F(LayerTreeImplTest, DeviceScaleFactorNeedsDrawPropertiesUpdate) {
  host_impl().active_tree()->BuildPropertyTreesForTesting();
  host_impl().active_tree()->SetDeviceScaleFactor(1.f);
  host_impl().active_tree()->UpdateDrawProperties();
  EXPECT_FALSE(host_impl().active_tree()->needs_update_draw_properties());
  host_impl().active_tree()->SetDeviceScaleFactor(2.f);
  EXPECT_TRUE(host_impl().active_tree()->needs_update_draw_properties());
}

TEST_F(LayerTreeImplTest, RasterColorSpaceDoesNotNeedDrawPropertiesUpdate) {
  host_impl().active_tree()->BuildPropertyTreesForTesting();
  host_impl().active_tree()->SetRasterColorSpace(
      1, gfx::ColorSpace::CreateXYZD50());
  host_impl().active_tree()->UpdateDrawProperties();
  EXPECT_FALSE(host_impl().active_tree()->needs_update_draw_properties());
  host_impl().active_tree()->SetRasterColorSpace(1,
                                                 gfx::ColorSpace::CreateSRGB());
  EXPECT_FALSE(host_impl().active_tree()->needs_update_draw_properties());
}

TEST_F(LayerTreeImplTest, HitTestingCorrectLayerWheelListener) {
  host_impl().active_tree()->set_event_listener_properties(
      EventListenerClass::kMouseWheel, EventListenerProperties::kBlocking);

  LayerImpl* root = root_layer();
  std::unique_ptr<LayerImpl> left_child =
      LayerImpl::Create(host_impl().active_tree(), 2);
  std::unique_ptr<LayerImpl> right_child =
      LayerImpl::Create(host_impl().active_tree(), 3);

  {
    gfx::Transform translate_z;
    translate_z.Translate3d(0, 0, 10);
    root->test_properties()->transform = translate_z;
    root->SetBounds(gfx::Size(100, 100));
    root->SetDrawsContent(true);
  }
  {
    gfx::Transform translate_z;
    translate_z.Translate3d(0, 0, 10);
    left_child->test_properties()->transform = translate_z;
    left_child->SetBounds(gfx::Size(100, 100));
    left_child->SetDrawsContent(true);
  }
  {
    gfx::Transform translate_z;
    translate_z.Translate3d(0, 0, 10);
    right_child->test_properties()->transform = translate_z;
    right_child->SetBounds(gfx::Size(100, 100));
  }

  root->test_properties()->AddChild(std::move(left_child));
  root->test_properties()->AddChild(std::move(right_child));

  host_impl().active_tree()->SetDeviceViewportSize(root->bounds());
  host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree();
  CHECK_EQ(1u, GetRenderSurfaceList().size());

  gfx::PointF test_point = gfx::PointF(1.f, 1.f);
  LayerImpl* result_layer =
      host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);

  CHECK(result_layer);
  EXPECT_EQ(2, result_layer->id());
}

// When using layer lists, we may not have layers for the outer viewport. This
// test verifies that scroll size can be calculated using property tree nodes.
TEST_F(LayerTreeImplTest, ScrollSizeWithoutLayers) {
  const gfx::Size inner_viewport_size(1000, 1000);
  const gfx::Size outer_viewport_size(1000, 1000);
  const gfx::Size scroll_layer_size(2000, 2000);

  auto* tree_impl = host_impl().active_tree();
  LayerTestCommon::SetupBrowserControlsAndScrollLayerWithVirtualViewport(
      &host_impl(), tree_impl, 50, inner_viewport_size, outer_viewport_size,
      scroll_layer_size);

  // With viewport layers the scrollable size should be correct.
  EXPECT_EQ(gfx::SizeF(scroll_layer_size), tree_impl->ScrollableSize());

  // The scrollable size should be correct without non-outer viewport layers.
  LayerTreeImpl::ViewportLayerIds updated_viewport_ids;
  updated_viewport_ids.outer_viewport_scroll =
      tree_impl->OuterViewportScrollLayer()->id();
  tree_impl->SetViewportLayersFromIds(updated_viewport_ids);
  EXPECT_EQ(gfx::SizeF(scroll_layer_size), tree_impl->ScrollableSize());
}

namespace {

class StubSwapPromise : public SwapPromise,
                        public base::SupportsWeakPtr<StubSwapPromise> {
 public:
  StubSwapPromise() = default;
  ~StubSwapPromise() override = default;

  void DidActivate() override {}
  void WillSwap(viz::CompositorFrameMetadata* metadata) override {}
  void DidSwap() override {}
  void DidNotSwap(DidNotSwapReason reason) override {}

  void OnCommit() override {}
  int64_t TraceId() const override { return 0; }
};

}  // namespace

TEST_F(LayerTreeImplTest, StubSwapPromisesAreDroppedWhenSwapFails) {
  const size_t promises_count = 2;

  std::vector<base::WeakPtr<StubSwapPromise>> weak_swap_promises;
  std::vector<std::unique_ptr<StubSwapPromise>> swap_promises_to_pass;
  for (size_t i = 0; i < promises_count; ++i) {
    swap_promises_to_pass.push_back(std::make_unique<StubSwapPromise>());
  }

  for (auto& promise : swap_promises_to_pass) {
    weak_swap_promises.push_back(promise->AsWeakPtr());
    host_impl().active_tree()->QueueSwapPromise(std::move(promise));
  }
  std::vector<std::unique_ptr<SwapPromise>> promises;
  host_impl().active_tree()->PassSwapPromises(std::move(promises));

  ASSERT_EQ(promises_count, weak_swap_promises.size());
  for (size_t i = 0; i < weak_swap_promises.size(); ++i) {
    EXPECT_FALSE(weak_swap_promises[i]) << "While checking case #" << i;
  }

  // Finally, check that the promises do not survive
  // |LayerTreeImpl::BreakSwapPromises|.
  {
    std::unique_ptr<StubSwapPromise> promise(new StubSwapPromise());
    auto weak_promise = promise->AsWeakPtr();
    host_impl().active_tree()->QueueSwapPromise(std::move(promise));
    host_impl().active_tree()->BreakSwapPromises(
        SwapPromise::DidNotSwapReason::SWAP_FAILS);
    EXPECT_FALSE(weak_promise);
  }
}

namespace {
class CommitToPendingTreeLayerTreeImplTestSettings : public LayerTreeSettings {
 public:
  CommitToPendingTreeLayerTreeImplTestSettings() {
    commit_to_active_tree = false;
  }
};

class CommitToPendingTreeLayerTreeImplTest : public LayerTreeImplTest {
 public:
  CommitToPendingTreeLayerTreeImplTest()
      : LayerTreeImplTest(CommitToPendingTreeLayerTreeImplTestSettings()) {}
};
}  // namespace

TEST_F(CommitToPendingTreeLayerTreeImplTest,
       ElementIdToAnimationMapsTrackOnlyOnSyncTree) {
  ASSERT_FALSE(host_impl().CommitToActiveTree());

  // When we have a pending tree (e.g. commit_to_active_tree is false), the
  // various ElementId to animation maps should not track anything for the
  // active tree (as they are only used on the sync tree).
  LayerTreeImpl* active_tree = host_impl().active_tree();
  active_tree->BuildPropertyTreesForTesting();
  LayerImpl* active_root = active_tree->root_layer_for_testing();

  auto& active_opacity_map =
      active_tree->element_id_to_opacity_animations_for_testing();
  ASSERT_EQ(active_opacity_map.size(), 0u);
  active_tree->SetOpacityMutated(active_root->element_id(), 0.5f);
  EXPECT_EQ(active_opacity_map.size(), 0u);

  auto& active_transform_map =
      active_tree->element_id_to_transform_animations_for_testing();
  ASSERT_EQ(active_transform_map.size(), 0u);
  active_tree->SetTransformMutated(active_root->element_id(), gfx::Transform());
  EXPECT_EQ(active_transform_map.size(), 0u);

  auto& active_filter_map =
      active_tree->element_id_to_filter_animations_for_testing();
  ASSERT_EQ(active_filter_map.size(), 0u);
  active_tree->SetFilterMutated(active_root->element_id(), FilterOperations());
  EXPECT_EQ(active_filter_map.size(), 0u);

  // The pending/recycle tree however should track them. Here we need two nodes
  // (the root and a child) as we will be adding entries for both the pending
  // and recycle tree cases.
  host_impl().CreatePendingTree();
  LayerTreeImpl* pending_tree = host_impl().pending_tree();
  std::unique_ptr<LayerImpl> pending_root_ptr =
      LayerImpl::Create(pending_tree, 2);
  LayerImpl* pending_root = pending_root_ptr.get();
  pending_tree->SetRootLayerForTesting(std::move(pending_root_ptr));

  std::unique_ptr<LayerImpl> child_ptr =
      LayerImpl::Create(host_impl().pending_tree(), 3);
  // The easiest way to force the child to have a TransformNode is to make it
  // fixed position. Similarly a non-one opacity forces an EffectNode.
  child_ptr->test_properties()->position_constraint.set_is_fixed_position(true);
  child_ptr->test_properties()->opacity = 0.9f;
  LayerImpl* child = child_ptr.get();
  pending_root->test_properties()->AddChild(std::move(child_ptr));
  pending_tree->BuildPropertyTreesForTesting();

  auto& pending_opacity_map =
      pending_tree->element_id_to_opacity_animations_for_testing();
  ASSERT_EQ(pending_opacity_map.size(), 0u);
  pending_tree->SetOpacityMutated(pending_root->element_id(), 0.5f);
  EXPECT_EQ(pending_opacity_map.size(), 1u);

  auto& pending_transform_map =
      pending_tree->element_id_to_transform_animations_for_testing();
  ASSERT_EQ(pending_transform_map.size(), 0u);
  pending_tree->SetTransformMutated(pending_root->element_id(),
                                    gfx::Transform());
  EXPECT_EQ(pending_transform_map.size(), 1u);

  auto& pending_filter_map =
      pending_tree->element_id_to_filter_animations_for_testing();
  ASSERT_EQ(pending_filter_map.size(), 0u);
  pending_tree->SetFilterMutated(pending_root->element_id(),
                                 FilterOperations());
  EXPECT_EQ(pending_filter_map.size(), 1u);

  // Finally, check the recycle tree - this should still track them.
  host_impl().ActivateSyncTree();
  LayerTreeImpl* recycle_tree = host_impl().recycle_tree();
  ASSERT_TRUE(recycle_tree);

  auto& recycle_opacity_map =
      recycle_tree->element_id_to_opacity_animations_for_testing();
  ASSERT_EQ(recycle_opacity_map.size(), 1u);
  recycle_tree->SetOpacityMutated(child->element_id(), 0.5f);
  EXPECT_EQ(recycle_opacity_map.size(), 2u);

  auto& recycle_transform_map =
      recycle_tree->element_id_to_transform_animations_for_testing();
  ASSERT_EQ(recycle_transform_map.size(), 1u);
  recycle_tree->SetTransformMutated(child->element_id(), gfx::Transform());
  EXPECT_EQ(recycle_transform_map.size(), 2u);

  auto& recycle_filter_map =
      recycle_tree->element_id_to_filter_animations_for_testing();
  ASSERT_EQ(recycle_filter_map.size(), 1u);
  recycle_tree->SetFilterMutated(child->element_id(), FilterOperations());
  EXPECT_EQ(recycle_filter_map.size(), 2u);
}

TEST_F(LayerTreeImplTest, ElementIdToAnimationMapsTrackOnlyOnSyncTree) {
  ASSERT_TRUE(host_impl().CommitToActiveTree());

  // When we are commiting directly to the active tree, the various ElementId to
  // animation maps should track on the active tree (as it is the sync tree, and
  // they are used on the sync tree).
  LayerTreeImpl* active_tree = host_impl().active_tree();
  active_tree->BuildPropertyTreesForTesting();
  LayerImpl* root = active_tree->root_layer_for_testing();

  auto& opacity_map =
      active_tree->element_id_to_opacity_animations_for_testing();
  ASSERT_EQ(opacity_map.size(), 0u);
  active_tree->SetOpacityMutated(root->element_id(), 0.5f);
  EXPECT_EQ(opacity_map.size(), 1u);

  auto& transform_map =
      active_tree->element_id_to_transform_animations_for_testing();
  ASSERT_EQ(transform_map.size(), 0u);
  active_tree->SetTransformMutated(root->element_id(), gfx::Transform());
  EXPECT_EQ(transform_map.size(), 1u);

  auto& filter_map = active_tree->element_id_to_filter_animations_for_testing();
  ASSERT_EQ(filter_map.size(), 0u);
  active_tree->SetFilterMutated(root->element_id(), FilterOperations());
  EXPECT_EQ(filter_map.size(), 1u);
}

}  // namespace
}  // namespace cc
