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

#include <stddef.h>

#include <algorithm>
#include <memory>
#include <set>
#include <tuple>
#include <vector>

#include "base/memory/ptr_util.h"
#include "base/stl_util.h"
#include "cc/animation/animation_host.h"
#include "cc/animation/animation_id_provider.h"
#include "cc/animation/keyframed_animation_curve.h"
#include "cc/animation/single_keyframe_effect_animation.h"
#include "cc/animation/transform_operations.h"
#include "cc/base/math_util.h"
#include "cc/layers/content_layer_client.h"
#include "cc/layers/effect_tree_layer_list_iterator.h"
#include "cc/layers/layer.h"
#include "cc/layers/layer_impl.h"
#include "cc/layers/render_surface_impl.h"
#include "cc/test/animation_test_common.h"
#include "cc/test/fake_content_layer_client.h"
#include "cc/test/fake_picture_layer.h"
#include "cc/test/fake_picture_layer_impl.h"
#include "cc/test/geometry_test_utils.h"
#include "cc/test/layer_tree_impl_test_base.h"
#include "cc/trees/clip_node.h"
#include "cc/trees/draw_property_utils.h"
#include "cc/trees/effect_node.h"
#include "cc/trees/scroll_node.h"
#include "cc/trees/transform_node.h"
#include "components/viz/common/frame_sinks/copy_output_request.h"
#include "components/viz/common/frame_sinks/copy_output_result.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gfx/geometry/quad_f.h"
#include "ui/gfx/geometry/rect_conversions.h"
#include "ui/gfx/geometry/size_conversions.h"
#include "ui/gfx/geometry/vector2d_conversions.h"
#include "ui/gfx/transform.h"

namespace cc {
namespace {

bool LayerSubtreeHasCopyRequest(Layer* layer) {
  return GetEffectNode(layer)->subtree_has_copy_request;
}

class DrawPropertiesTestBase : public LayerTreeImplTestBase {
 public:
  DrawPropertiesTestBase() = default;
  explicit DrawPropertiesTestBase(const LayerTreeSettings& settings)
      : LayerTreeImplTestBase(settings) {}

  static void SetScrollOffsetDelta(LayerImpl* layer_impl,
                                   const gfx::Vector2dF& delta) {
    if (layer_impl->layer_tree_impl()
            ->property_trees()
            ->scroll_tree.SetScrollOffsetDeltaForTesting(
                layer_impl->element_id(), delta))
      layer_impl->layer_tree_impl()->DidUpdateScrollOffset(
          layer_impl->element_id());
  }

  static float GetMaximumAnimationScale(LayerImpl* layer_impl) {
    return layer_impl->layer_tree_impl()
        ->property_trees()
        ->GetAnimationScales(layer_impl->transform_tree_index(),
                             layer_impl->layer_tree_impl())
        .maximum_animation_scale;
  }

  static float GetStartingAnimationScale(LayerImpl* layer_impl) {
    return layer_impl->layer_tree_impl()
        ->property_trees()
        ->GetAnimationScales(layer_impl->transform_tree_index(),
                             layer_impl->layer_tree_impl())
        .starting_animation_scale;
  }

  void UpdateMainDrawProperties(float device_scale_factor = 1.0f) {
    SetDeviceScaleAndUpdateViewportRect(host(), device_scale_factor);
    UpdateDrawProperties(host(), &update_layer_list_);
  }

  LayerImpl* ImplOf(const scoped_refptr<Layer>& layer) {
    return layer ? host_impl()->active_tree()->LayerById(layer->id()) : nullptr;
  }
  LayerImpl* PendingImplOf(const scoped_refptr<Layer>& layer) {
    return layer ? host_impl()->pending_tree()->LayerById(layer->id())
                 : nullptr;
  }
  RenderSurfaceImpl* GetRenderSurfaceImpl(const scoped_refptr<Layer>& layer) {
    return GetRenderSurface(ImplOf(layer));
  }

  // Updates main thread draw properties, commits main thread tree to
  // impl-side pending tree, and updates pending tree draw properties.
  void Commit(float device_scale_factor = 1.0f) {
    UpdateMainDrawProperties(device_scale_factor);
    if (!host_impl()->pending_tree())
      host_impl()->CreatePendingTree();
    host()->CommitAndCreatePendingTree();
    // TODO(https://crbug.com/939968) This call should be handled by
    // FakeLayerTreeHost instead of manually pushing the properties from the
    // layer tree host to the pending tree.
    host()->PushLayerTreePropertiesTo(host_impl()->pending_tree());

    UpdateDrawProperties(host_impl()->pending_tree());
  }

  // Calls Commit(), then activates the pending tree, and updates active tree
  // draw properties.
  void CommitAndActivate(float device_scale_factor = 1.0f) {
    Commit(device_scale_factor);
    host_impl()->ActivateSyncTree();
    DCHECK_EQ(device_scale_factor,
              host_impl()->active_tree()->device_scale_factor());
    UpdateActiveTreeDrawProperties(device_scale_factor);
  }

  bool UpdateLayerListContains(int id) const {
    for (const auto& layer : update_layer_list_) {
      if (layer->id() == id)
        return true;
    }
    return false;
  }

  const LayerList& update_layer_list() const { return update_layer_list_; }

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

  void SetDeviceTransform(const gfx::Transform& device_transform) {
    host_impl()->OnDraw(device_transform, host_impl()->external_viewport(),
                        false, false);
  }

 private:
  LayerList update_layer_list_;
};

class DrawPropertiesTest : public DrawPropertiesTestBase,
                           public testing::Test {};

class DrawPropertiesTestWithLayerTree : public DrawPropertiesTestBase,
                                        public testing::Test {
 public:
  DrawPropertiesTestWithLayerTree()
      : DrawPropertiesTestBase(LayerTreeSettings()) {}
};

class DrawPropertiesDrawRectsTest : public DrawPropertiesTest {
 public:
  DrawPropertiesDrawRectsTest() : DrawPropertiesTest() {}

  void SetUp() override {
    LayerImpl* root = root_layer();
    root->SetDrawsContent(true);
    root->SetBounds(gfx::Size(500, 500));
  }

  LayerImpl* TestVisibleRectAndDrawableContentRect(
      const gfx::Rect& target_rect,
      const gfx::Transform& layer_transform,
      const gfx::Rect& layer_rect) {
    LayerImpl* root = root_layer();
    LayerImpl* target = AddLayer<LayerImpl>();
    LayerImpl* drawing_layer = AddLayer<LayerImpl>();

    target->SetDrawsContent(true);
    target->SetMasksToBounds(true);
    drawing_layer->SetDrawsContent(true);

    target->SetBounds(target_rect.size());
    drawing_layer->SetBounds(layer_rect.size());

    CopyProperties(root, target);
    CreateTransformNode(target).post_translation =
        gfx::PointF(target_rect.origin()).OffsetFromOrigin();
    CreateEffectNode(target).render_surface_reason = RenderSurfaceReason::kTest;
    CreateClipNode(target);
    CopyProperties(target, drawing_layer);
    auto& drawing_layer_transform_node = CreateTransformNode(drawing_layer);
    drawing_layer_transform_node.local = layer_transform;
    drawing_layer_transform_node.post_translation =
        gfx::PointF(layer_rect.origin()).OffsetFromOrigin();
    drawing_layer_transform_node.flattens_inherited_transform = false;

    UpdateActiveTreeDrawProperties();

    return drawing_layer;
  }
};

// Sanity check: For layers positioned at zero, with zero size,
// and with identity transforms, then the draw transform,
// screen space transform, and the hierarchy passed on to children
// layers should also be identity transforms.
TEST_F(DrawPropertiesTest, TransformsForNoOpLayer) {
  LayerImpl* parent = root_layer();
  LayerImpl* child = AddLayer<LayerImpl>();
  LayerImpl* grand_child = AddLayer<LayerImpl>();

  parent->SetBounds(gfx::Size(100, 100));

  CopyProperties(parent, child);
  CopyProperties(child, grand_child);

  UpdateActiveTreeDrawProperties();

  EXPECT_TRANSFORMATION_MATRIX_EQ(gfx::Transform(), child->DrawTransform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(gfx::Transform(),
                                  child->ScreenSpaceTransform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(gfx::Transform(),
                                  grand_child->DrawTransform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(gfx::Transform(),
                                  grand_child->ScreenSpaceTransform());
}

TEST_F(DrawPropertiesTest, TransformsForSingleLayer) {
  LayerImpl* root = root_layer();
  LayerImpl* layer = AddLayer<LayerImpl>();

  TransformTree& transform_tree =
      host_impl()->active_tree()->property_trees()->transform_tree;
  EffectTree& effect_tree =
      host_impl()->active_tree()->property_trees()->effect_tree;

  root->SetBounds(gfx::Size(1, 2));
  CopyProperties(root, layer);

  // Case 1: Setting the bounds of the layer should not affect either the draw
  // transform or the screenspace transform.
  layer->SetBounds(gfx::Size(10, 12));
  UpdateActiveTreeDrawProperties();
  EXPECT_TRANSFORMATION_MATRIX_EQ(
      gfx::Transform(),
      draw_property_utils::DrawTransform(layer, transform_tree, effect_tree));
  EXPECT_TRANSFORMATION_MATRIX_EQ(
      gfx::Transform(),
      draw_property_utils::ScreenSpaceTransform(layer, transform_tree));

  // Case 2: The anchor point by itself (without a layer transform) should have
  // no effect on the transforms.
  CreateTransformNode(layer).origin = gfx::Point3F(2.5f, 3.0f, 0.f);
  layer->SetBounds(gfx::Size(10, 12));
  UpdateActiveTreeDrawProperties();
  EXPECT_TRANSFORMATION_MATRIX_EQ(
      gfx::Transform(),
      draw_property_utils::DrawTransform(layer, transform_tree, effect_tree));
  EXPECT_TRANSFORMATION_MATRIX_EQ(
      gfx::Transform(),
      draw_property_utils::ScreenSpaceTransform(layer, transform_tree));

  // Case 3: A change in actual position affects both the draw transform and
  // screen space transform.
  gfx::Transform position_transform;
  position_transform.Translate(0.f, 1.2f);
  SetPostTranslation(layer, gfx::Vector2dF(0.f, 1.2f));
  UpdateActiveTreeDrawProperties();
  EXPECT_TRANSFORMATION_MATRIX_EQ(
      position_transform,
      draw_property_utils::DrawTransform(layer, transform_tree, effect_tree));
  EXPECT_TRANSFORMATION_MATRIX_EQ(
      position_transform,
      draw_property_utils::ScreenSpaceTransform(layer, transform_tree));

  // Case 4: In the correct sequence of transforms, the layer transform should
  // pre-multiply the translation-to-center. This is easily tested by using a
  // scale transform, because scale and translation are not commutative.
  gfx::Transform layer_transform;
  layer_transform.Scale3d(2.0, 2.0, 1.0);
  SetTransform(layer, layer_transform);
  SetTransformOrigin(layer, gfx::Point3F());
  SetPostTranslation(layer, gfx::Vector2dF());
  UpdateActiveTreeDrawProperties();
  EXPECT_TRANSFORMATION_MATRIX_EQ(
      layer_transform,
      draw_property_utils::DrawTransform(layer, transform_tree, effect_tree));
  EXPECT_TRANSFORMATION_MATRIX_EQ(
      layer_transform,
      draw_property_utils::ScreenSpaceTransform(layer, transform_tree));

  // Case 5: The layer transform should occur with respect to the anchor point.
  gfx::Transform translation_to_anchor;
  translation_to_anchor.Translate(5.0, 0.0);
  gfx::Transform expected_result =
      translation_to_anchor * layer_transform * Inverse(translation_to_anchor);
  SetTransformOrigin(layer, gfx::Point3F(5.f, 0.f, 0.f));
  UpdateActiveTreeDrawProperties();
  EXPECT_TRANSFORMATION_MATRIX_EQ(
      expected_result,
      draw_property_utils::DrawTransform(layer, transform_tree, effect_tree));
  EXPECT_TRANSFORMATION_MATRIX_EQ(
      expected_result,
      draw_property_utils::ScreenSpaceTransform(layer, transform_tree));

  // Case 6: Verify that position pre-multiplies the layer transform.  The
  // current implementation of CalculateDrawProperties does this implicitly, but
  // it is still worth testing to detect accidental regressions.
  expected_result = position_transform * translation_to_anchor *
                    layer_transform * Inverse(translation_to_anchor);
  SetPostTranslation(layer, gfx::Vector2dF(0.f, 1.2f));
  UpdateActiveTreeDrawProperties();
  EXPECT_TRANSFORMATION_MATRIX_EQ(
      expected_result,
      draw_property_utils::DrawTransform(layer, transform_tree, effect_tree));
  EXPECT_TRANSFORMATION_MATRIX_EQ(
      expected_result,
      draw_property_utils::ScreenSpaceTransform(layer, transform_tree));
}

TEST_F(DrawPropertiesTest, TransformsAboutScrollOffset) {
  const gfx::ScrollOffset kScrollOffset(50, 100);
  const gfx::Vector2dF kScrollDelta(2.34f, 5.67f);
  const gfx::Vector2d kMaxScrollOffset(200, 200);
  const gfx::PointF kScrollLayerPosition(-kScrollOffset.x(),
                                         -kScrollOffset.y());
  float page_scale = 0.888f;
  const float kDeviceScale = 1.666f;

  LayerImpl* sublayer = AddLayer<LayerImpl>();
  sublayer->SetDrawsContent(true);
  sublayer->SetBounds(gfx::Size(500, 500));

  LayerImpl* scroll_layer = AddLayer<LayerImpl>();
  scroll_layer->SetBounds(gfx::Size(10, 20));

  scroll_layer->SetElementId(LayerIdToElementIdForTesting(scroll_layer->id()));
  scroll_layer->SetScrollable(
      gfx::Size(scroll_layer->bounds().width() + kMaxScrollOffset.x(),
                scroll_layer->bounds().height() + kMaxScrollOffset.y()));

  LayerImpl* root = root_layer();
  root->SetBounds(gfx::Size(3, 4));
  SetupViewport(root, gfx::Size(3, 4), gfx::Size(500, 500));

  CopyProperties(OuterViewportScrollLayer(), scroll_layer);
  CreateTransformNode(scroll_layer);
  CreateScrollNode(scroll_layer);
  CopyProperties(scroll_layer, sublayer);

  auto& scroll_tree = GetPropertyTrees(scroll_layer)->scroll_tree;
  scroll_tree.UpdateScrollOffsetBaseForTesting(scroll_layer->element_id(),
                                               kScrollOffset);
  SetScrollOffsetDelta(scroll_layer, kScrollDelta);
  host_impl()->active_tree()->SetPageScaleOnActiveTree(page_scale);
  UpdateActiveTreeDrawProperties(kDeviceScale);

  gfx::Transform expected_transform;
  gfx::PointF sub_layer_screen_position = kScrollLayerPosition - kScrollDelta;
  expected_transform.Translate(
      std::round(sub_layer_screen_position.x() * page_scale * kDeviceScale),
      std::round(sub_layer_screen_position.y() * page_scale * kDeviceScale));
  expected_transform.Scale(page_scale * kDeviceScale,
                           page_scale * kDeviceScale);
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_transform,
                                  sublayer->DrawTransform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_transform,
                                  sublayer->ScreenSpaceTransform());

  gfx::Transform arbitrary_translate;
  const float kTranslateX = 10.6f;
  const float kTranslateY = 20.6f;
  arbitrary_translate.Translate(kTranslateX, kTranslateY);
  SetTransform(scroll_layer, arbitrary_translate);
  UpdateActiveTreeDrawProperties(kDeviceScale);
  expected_transform.MakeIdentity();
  expected_transform.Translate(
      std::round(kTranslateX * page_scale * kDeviceScale +
                 sub_layer_screen_position.x() * page_scale * kDeviceScale),
      std::round(kTranslateY * page_scale * kDeviceScale +
                 sub_layer_screen_position.y() * page_scale * kDeviceScale));
  expected_transform.Scale(page_scale * kDeviceScale,
                           page_scale * kDeviceScale);
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_transform,
                                  sublayer->DrawTransform());

  // Test that page scale is updated even when we don't rebuild property trees.
  page_scale = 1.888f;

  host_impl()->active_tree()->SetPageScaleOnActiveTree(page_scale);
  EXPECT_FALSE(host_impl()->active_tree()->property_trees()->needs_rebuild);
  UpdateActiveTreeDrawProperties(kDeviceScale);

  expected_transform.MakeIdentity();
  expected_transform.Translate(
      std::round(kTranslateX * page_scale * kDeviceScale +
                 sub_layer_screen_position.x() * page_scale * kDeviceScale),
      std::round(kTranslateY * page_scale * kDeviceScale +
                 sub_layer_screen_position.y() * page_scale * kDeviceScale));
  expected_transform.Scale(page_scale * kDeviceScale,
                           page_scale * kDeviceScale);
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_transform,
                                  sublayer->DrawTransform());
}

TEST_F(DrawPropertiesTest, TransformsForSimpleHierarchy) {
  LayerImpl* root = root_layer();
  LayerImpl* parent = AddLayer<LayerImpl>();
  LayerImpl* child = AddLayer<LayerImpl>();
  LayerImpl* grand_child = AddLayer<LayerImpl>();

  // One-time setup of root layer
  root->SetBounds(gfx::Size(1, 2));

  TransformTree& transform_tree =
      host_impl()->active_tree()->property_trees()->transform_tree;
  EffectTree& effect_tree =
      host_impl()->active_tree()->property_trees()->effect_tree;

  // Case 1: parent's anchor point should not affect child or grand_child.
  parent->SetBounds(gfx::Size(10, 12));
  child->SetBounds(gfx::Size(16, 18));
  grand_child->SetBounds(gfx::Size(76, 78));

  CopyProperties(root, parent);
  CreateTransformNode(parent).origin = gfx::Point3F(2.5f, 3.0f, 0.f);
  CopyProperties(parent, child);
  CopyProperties(child, grand_child);

  UpdateActiveTreeDrawProperties();

  EXPECT_TRANSFORMATION_MATRIX_EQ(
      gfx::Transform(),
      draw_property_utils::DrawTransform(child, transform_tree, effect_tree));
  EXPECT_TRANSFORMATION_MATRIX_EQ(
      gfx::Transform(),
      draw_property_utils::ScreenSpaceTransform(child, transform_tree));
  EXPECT_TRANSFORMATION_MATRIX_EQ(
      gfx::Transform(), draw_property_utils::DrawTransform(
                            grand_child, transform_tree, effect_tree));
  EXPECT_TRANSFORMATION_MATRIX_EQ(
      gfx::Transform(),
      draw_property_utils::ScreenSpaceTransform(grand_child, transform_tree));

  // Case 2: parent's position affects child and grand_child.
  gfx::Transform parent_position_transform;
  parent_position_transform.Translate(0.f, 1.2f);
  SetPostTranslation(parent, gfx::Vector2dF(0.f, 1.2f));
  UpdateActiveTreeDrawProperties();
  EXPECT_TRANSFORMATION_MATRIX_EQ(
      parent_position_transform,
      draw_property_utils::DrawTransform(child, transform_tree, effect_tree));
  EXPECT_TRANSFORMATION_MATRIX_EQ(
      parent_position_transform,
      draw_property_utils::ScreenSpaceTransform(child, transform_tree));
  EXPECT_TRANSFORMATION_MATRIX_EQ(
      parent_position_transform, draw_property_utils::DrawTransform(
                                     grand_child, transform_tree, effect_tree));
  EXPECT_TRANSFORMATION_MATRIX_EQ(
      parent_position_transform,
      draw_property_utils::ScreenSpaceTransform(grand_child, transform_tree));

  // Case 3: parent's local transform affects child and grandchild
  gfx::Transform parent_layer_transform;
  parent_layer_transform.Scale3d(2.0, 2.0, 1.0);
  gfx::Transform parent_translation_to_anchor;
  parent_translation_to_anchor.Translate(2.5, 3.0);
  gfx::Transform parent_composite_transform =
      parent_translation_to_anchor * parent_layer_transform *
      Inverse(parent_translation_to_anchor);
  SetTransform(parent, parent_layer_transform);
  SetPostTranslation(parent, gfx::Vector2dF());
  UpdateActiveTreeDrawProperties();
  EXPECT_TRANSFORMATION_MATRIX_EQ(
      parent_composite_transform,
      draw_property_utils::DrawTransform(child, transform_tree, effect_tree));
  EXPECT_TRANSFORMATION_MATRIX_EQ(
      parent_composite_transform,
      draw_property_utils::ScreenSpaceTransform(child, transform_tree));
  EXPECT_TRANSFORMATION_MATRIX_EQ(
      parent_composite_transform,
      draw_property_utils::DrawTransform(grand_child, transform_tree,
                                         effect_tree));
  EXPECT_TRANSFORMATION_MATRIX_EQ(
      parent_composite_transform,
      draw_property_utils::ScreenSpaceTransform(grand_child, transform_tree));
}

TEST_F(DrawPropertiesTest, TransformsForSingleRenderSurface) {
  LayerImpl* root = root_layer();
  LayerImpl* parent = AddLayer<LayerImpl>();
  LayerImpl* child = AddLayer<LayerImpl>();
  LayerImpl* grand_child = AddLayer<LayerImpl>();

  gfx::Transform parent_layer_transform;
  parent_layer_transform.Scale3d(1.f, 0.9f, 1.f);
  gfx::Transform parent_translation_to_anchor;
  parent_translation_to_anchor.Translate(25.0, 30.0);

  gfx::Transform parent_composite_transform =
      parent_translation_to_anchor * parent_layer_transform *
      Inverse(parent_translation_to_anchor);
  gfx::Vector2dF parent_composite_scale =
      MathUtil::ComputeTransform2dScaleComponents(parent_composite_transform,
                                                  1.f);
  gfx::Transform surface_sublayer_transform;
  surface_sublayer_transform.Scale(parent_composite_scale.x(),
                                   parent_composite_scale.y());
  gfx::Transform surface_sublayer_composite_transform =
      parent_composite_transform * Inverse(surface_sublayer_transform);

  root->SetBounds(gfx::Size(1, 2));
  parent->SetBounds(gfx::Size(100, 120));
  child->SetBounds(gfx::Size(16, 18));
  grand_child->SetBounds(gfx::Size(8, 10));
  grand_child->SetDrawsContent(true);

  CopyProperties(root, parent);
  auto& parent_transform_node = CreateTransformNode(parent);
  parent_transform_node.origin = gfx::Point3F(2.5f, 30.f, 0.f);
  parent_transform_node.local = parent_layer_transform;
  CopyProperties(parent, child);
  CreateEffectNode(child).render_surface_reason = RenderSurfaceReason::kTest;
  CopyProperties(child, grand_child);

  UpdateActiveTreeDrawProperties();

  // Render surface should have been created now.
  ASSERT_TRUE(GetRenderSurface(child));
  ASSERT_EQ(GetRenderSurface(child), child->render_target());

  // The child layer's draw transform should refer to its new render surface.
  // The screen-space transform, however, should still refer to the root.
  EXPECT_TRANSFORMATION_MATRIX_EQ(surface_sublayer_transform,
                                  child->DrawTransform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(parent_composite_transform,
                                  child->ScreenSpaceTransform());

  // Because the grand_child is the only drawable content, the child's render
  // surface will tighten its bounds to the grand_child.  The scale at which the
  // surface's subtree is drawn must be removed from the composite transform.
  EXPECT_TRANSFORMATION_MATRIX_EQ(surface_sublayer_composite_transform,
                                  child->render_target()->draw_transform());

  // The screen space is the same as the target since the child surface draws
  // into the root.
  EXPECT_TRANSFORMATION_MATRIX_EQ(
      surface_sublayer_composite_transform,
      child->render_target()->screen_space_transform());
}

TEST_F(DrawPropertiesTest, TransformsForRenderSurfaceHierarchy) {
  // This test creates a more complex tree and verifies it all at once. This
  // covers the following cases:
  //   - layers that are described w.r.t. a render surface: should have draw
  //   transforms described w.r.t. that surface
  //   - A render surface described w.r.t. an ancestor render surface: should
  //   have a draw transform described w.r.t. that ancestor surface
  //   - Sanity check on recursion: verify transforms of layers described w.r.t.
  //   a render surface that is described w.r.t. an ancestor render surface.
  //   - verifying that each layer has a reference to the correct render surface
  //   and render target values.

  LayerImpl* root = root_layer();
  LayerImpl* parent = AddLayer<LayerImpl>();
  parent->SetDrawsContent(true);
  LayerImpl* render_surface1 = AddLayer<LayerImpl>();
  render_surface1->SetDrawsContent(true);
  LayerImpl* render_surface2 = AddLayer<LayerImpl>();
  render_surface2->SetDrawsContent(true);
  LayerImpl* child_of_root = AddLayer<LayerImpl>();
  child_of_root->SetDrawsContent(true);
  LayerImpl* child_of_rs1 = AddLayer<LayerImpl>();
  child_of_rs1->SetDrawsContent(true);
  LayerImpl* child_of_rs2 = AddLayer<LayerImpl>();
  child_of_rs2->SetDrawsContent(true);
  LayerImpl* grand_child_of_root = AddLayer<LayerImpl>();
  grand_child_of_root->SetDrawsContent(true);
  LayerImpl* grand_child_of_rs1 = AddLayer<LayerImpl>();
  grand_child_of_rs1->SetDrawsContent(true);
  LayerImpl* grand_child_of_rs2 = AddLayer<LayerImpl>();
  grand_child_of_rs2->SetDrawsContent(true);

  // All layers in the tree are initialized with an anchor at .25 and a size of
  // (10,10).  Matrix "A" is the composite layer transform used in all layers.
  gfx::Transform translation_to_anchor;
  translation_to_anchor.Translate(2.5, 0.0);
  gfx::Transform layer_transform;
  layer_transform.Translate(1.0, 1.0);

  gfx::Transform A =
      translation_to_anchor * layer_transform * Inverse(translation_to_anchor);

  gfx::Vector2dF surface1_parent_transform_scale =
      MathUtil::ComputeTransform2dScaleComponents(A, 1.f);
  gfx::Transform surface1_sublayer_transform;
  surface1_sublayer_transform.Scale(surface1_parent_transform_scale.x(),
                                    surface1_parent_transform_scale.y());

  // SS1 = transform given to the subtree of render_surface1
  gfx::Transform SS1 = surface1_sublayer_transform;
  // S1 = transform to move from render_surface1 pixels to the layer space of
  // the owning layer
  gfx::Transform S1 = Inverse(surface1_sublayer_transform);

  gfx::Vector2dF surface2_parent_transform_scale =
      MathUtil::ComputeTransform2dScaleComponents(SS1 * A, 1.f);
  gfx::Transform surface2_sublayer_transform;
  surface2_sublayer_transform.Scale(surface2_parent_transform_scale.x(),
                                    surface2_parent_transform_scale.y());

  // SS2 = transform given to the subtree of render_surface2
  gfx::Transform SS2 = surface2_sublayer_transform;
  // S2 = transform to move from render_surface2 pixels to the layer space of
  // the owning layer
  gfx::Transform S2 = Inverse(surface2_sublayer_transform);

  root->SetBounds(gfx::Size(1, 2));
  parent->SetBounds(gfx::Size(10, 10));
  render_surface1->SetBounds(gfx::Size(10, 10));
  render_surface2->SetBounds(gfx::Size(10, 10));
  child_of_root->SetBounds(gfx::Size(10, 10));
  child_of_rs1->SetBounds(gfx::Size(10, 10));
  child_of_rs2->SetBounds(gfx::Size(10, 10));
  grand_child_of_root->SetBounds(gfx::Size(10, 10));
  grand_child_of_rs1->SetBounds(gfx::Size(10, 10));
  grand_child_of_rs2->SetBounds(gfx::Size(10, 10));

  CopyProperties(root, parent);
  auto& parent_transform_node = CreateTransformNode(parent);
  parent_transform_node.origin = gfx::Point3F(2.5f, 0.f, 0.f);
  parent_transform_node.local = layer_transform;
  CopyProperties(parent, child_of_root);
  auto& child_of_root_transform_node = CreateTransformNode(child_of_root);
  child_of_root_transform_node.origin = gfx::Point3F(2.5f, 0.f, 0.f);
  child_of_root_transform_node.local = layer_transform;
  CopyProperties(child_of_root, grand_child_of_root);
  auto& grand_child_of_root_transform_node =
      CreateTransformNode(grand_child_of_root);
  grand_child_of_root_transform_node.origin = gfx::Point3F(2.5f, 0.f, 0.f);
  grand_child_of_root_transform_node.local = layer_transform;
  CopyProperties(parent, render_surface1);
  auto& render_surface1_transform_node = CreateTransformNode(render_surface1);
  render_surface1_transform_node.origin = gfx::Point3F(2.5f, 0.f, 0.f);
  render_surface1_transform_node.local = layer_transform;
  auto& render_surface1_effect_node = CreateEffectNode(render_surface1);
  render_surface1_effect_node.render_surface_reason =
      RenderSurfaceReason::kTest;
  render_surface1_effect_node.opacity = 0.5f;
  CopyProperties(render_surface1, child_of_rs1);
  auto& child_of_rs1_transform_node = CreateTransformNode(child_of_rs1);
  child_of_rs1_transform_node.origin = gfx::Point3F(2.5f, 0.f, 0.f);
  child_of_rs1_transform_node.local = layer_transform;
  CopyProperties(child_of_rs1, grand_child_of_rs1);
  auto& grand_child_of_rs1_transform_node =
      CreateTransformNode(grand_child_of_rs1);
  grand_child_of_rs1_transform_node.origin = gfx::Point3F(2.5f, 0.f, 0.f);
  grand_child_of_rs1_transform_node.local = layer_transform;
  CopyProperties(render_surface1, render_surface2);
  auto& render_surface2_transform_node = CreateTransformNode(render_surface2);
  render_surface2_transform_node.origin = gfx::Point3F(2.5f, 0.f, 0.f);
  render_surface2_transform_node.local = layer_transform;
  auto& render_surface2_effect_node = CreateEffectNode(render_surface2);
  render_surface2_effect_node.render_surface_reason =
      RenderSurfaceReason::kTest;
  render_surface2_effect_node.opacity = 0.33f;
  CopyProperties(render_surface2, child_of_rs2);
  auto& child_of_rs2_transform_node = CreateTransformNode(child_of_rs2);
  child_of_rs2_transform_node.origin = gfx::Point3F(2.5f, 0.f, 0.f);
  child_of_rs2_transform_node.local = layer_transform;
  CopyProperties(child_of_rs2, grand_child_of_rs2);
  auto& grand_child_of_rs2_transform_node =
      CreateTransformNode(grand_child_of_rs2);
  grand_child_of_rs2_transform_node.origin = gfx::Point3F(2.5f, 0.f, 0.f);
  grand_child_of_rs2_transform_node.local = layer_transform;

  UpdateActiveTreeDrawProperties();

  // Only layers that are associated with render surfaces should have an actual
  // RenderSurface() value.
  ASSERT_TRUE(GetRenderSurface(root));
  ASSERT_EQ(GetRenderSurface(child_of_root), GetRenderSurface(root));
  ASSERT_EQ(GetRenderSurface(grand_child_of_root), GetRenderSurface(root));

  ASSERT_NE(GetRenderSurface(render_surface1), GetRenderSurface(root));
  ASSERT_EQ(GetRenderSurface(child_of_rs1), GetRenderSurface(render_surface1));
  ASSERT_EQ(GetRenderSurface(grand_child_of_rs1),
            GetRenderSurface(render_surface1));

  ASSERT_NE(GetRenderSurface(render_surface2), GetRenderSurface(root));
  ASSERT_NE(GetRenderSurface(render_surface2),
            GetRenderSurface(render_surface1));
  ASSERT_EQ(GetRenderSurface(child_of_rs2), GetRenderSurface(render_surface2));
  ASSERT_EQ(GetRenderSurface(grand_child_of_rs2),
            GetRenderSurface(render_surface2));

  // Verify all render target accessors
  EXPECT_EQ(GetRenderSurface(root), parent->render_target());
  EXPECT_EQ(GetRenderSurface(root), child_of_root->render_target());
  EXPECT_EQ(GetRenderSurface(root), grand_child_of_root->render_target());

  EXPECT_EQ(GetRenderSurface(render_surface1),
            render_surface1->render_target());
  EXPECT_EQ(GetRenderSurface(render_surface1), child_of_rs1->render_target());
  EXPECT_EQ(GetRenderSurface(render_surface1),
            grand_child_of_rs1->render_target());

  EXPECT_EQ(GetRenderSurface(render_surface2),
            render_surface2->render_target());
  EXPECT_EQ(GetRenderSurface(render_surface2), child_of_rs2->render_target());
  EXPECT_EQ(GetRenderSurface(render_surface2),
            grand_child_of_rs2->render_target());

  // Verify layer draw transforms note that draw transforms are described with
  // respect to the nearest ancestor render surface but screen space transforms
  // are described with respect to the root.
  EXPECT_TRANSFORMATION_MATRIX_EQ(A, parent->DrawTransform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(A * A, child_of_root->DrawTransform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(A * A * A,
                                  grand_child_of_root->DrawTransform());

  EXPECT_TRANSFORMATION_MATRIX_EQ(SS1, render_surface1->DrawTransform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(SS1 * A, child_of_rs1->DrawTransform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(SS1 * A * A,
                                  grand_child_of_rs1->DrawTransform());

  EXPECT_TRANSFORMATION_MATRIX_EQ(SS2, render_surface2->DrawTransform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(SS2 * A, child_of_rs2->DrawTransform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(SS2 * A * A,
                                  grand_child_of_rs2->DrawTransform());

  // Verify layer screen-space transforms
  //
  EXPECT_TRANSFORMATION_MATRIX_EQ(A, parent->ScreenSpaceTransform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(A * A, child_of_root->ScreenSpaceTransform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(A * A * A,
                                  grand_child_of_root->ScreenSpaceTransform());

  EXPECT_TRANSFORMATION_MATRIX_EQ(A * A,
                                  render_surface1->ScreenSpaceTransform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(A * A * A,
                                  child_of_rs1->ScreenSpaceTransform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(A * A * A * A,
                                  grand_child_of_rs1->ScreenSpaceTransform());

  EXPECT_TRANSFORMATION_MATRIX_EQ(A * A * A,
                                  render_surface2->ScreenSpaceTransform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(A * A * A * A,
                                  child_of_rs2->ScreenSpaceTransform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(A * A * A * A * A,
                                  grand_child_of_rs2->ScreenSpaceTransform());

  // Verify render surface transforms.
  //
  // Draw transform of render surface 1 is described with respect to root.
  EXPECT_TRANSFORMATION_MATRIX_EQ(
      A * A * S1, GetRenderSurface(render_surface1)->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(
      A * A * S1, GetRenderSurface(render_surface1)->screen_space_transform());
  // Draw transform of render surface 2 is described with respect to render
  // surface 1.
  EXPECT_TRANSFORMATION_MATRIX_EQ(
      SS1 * A * S2, GetRenderSurface(render_surface2)->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(
      A * A * A * S2,
      GetRenderSurface(render_surface2)->screen_space_transform());

  // Sanity check. If these fail there is probably a bug in the test itself.  It
  // is expected that we correctly set up transforms so that the y-component of
  // the screen-space transform encodes the "depth" of the layer in the tree.
  EXPECT_FLOAT_EQ(1.0, parent->ScreenSpaceTransform().matrix().get(1, 3));
  EXPECT_FLOAT_EQ(2.0,
                  child_of_root->ScreenSpaceTransform().matrix().get(1, 3));
  EXPECT_FLOAT_EQ(
      3.0, grand_child_of_root->ScreenSpaceTransform().matrix().get(1, 3));

  EXPECT_FLOAT_EQ(2.0,
                  render_surface1->ScreenSpaceTransform().matrix().get(1, 3));
  EXPECT_FLOAT_EQ(3.0, child_of_rs1->ScreenSpaceTransform().matrix().get(1, 3));
  EXPECT_FLOAT_EQ(
      4.0, grand_child_of_rs1->ScreenSpaceTransform().matrix().get(1, 3));

  EXPECT_FLOAT_EQ(3.0,
                  render_surface2->ScreenSpaceTransform().matrix().get(1, 3));
  EXPECT_FLOAT_EQ(4.0, child_of_rs2->ScreenSpaceTransform().matrix().get(1, 3));
  EXPECT_FLOAT_EQ(
      5.0, grand_child_of_rs2->ScreenSpaceTransform().matrix().get(1, 3));
}

TEST_F(DrawPropertiesTest, LayerFullyContainedWithinClipInTargetSpace) {
  LayerImpl* root = root_layer();
  LayerImpl* child = AddLayer<LayerImpl>();
  LayerImpl* grand_child = AddLayer<LayerImpl>();

  gfx::Transform child_transform;
  child_transform.Translate(50.0, 50.0);
  child_transform.RotateAboutZAxis(30.0);

  gfx::Transform grand_child_transform;
  grand_child_transform.RotateAboutYAxis(90.0);

  root->SetBounds(gfx::Size(200, 200));
  child->SetBounds(gfx::Size(10, 10));
  grand_child->SetBounds(gfx::Size(100, 100));
  grand_child->SetDrawsContent(true);

  CopyProperties(root, child);
  CreateTransformNode(child).local = child_transform;
  CopyProperties(child, grand_child);
  auto& grand_child_transform_node = CreateTransformNode(grand_child);
  grand_child_transform_node.flattens_inherited_transform = false;
  grand_child_transform_node.local = grand_child_transform;

  UpdateActiveTreeDrawProperties();

  // Mapping grand_child's bounds to screen space produces an empty rect, but
  // only because it is turned sideways.  The entire rect is contained inside
  // the clip, and is only empty so long as the numerical precision of the
  // transform is effectively perfect.  Currently we do the calculation the
  // other way around, and the Projection of the screen space clip into layer
  // space includes the entire bounds.
  EXPECT_EQ(gfx::Rect(grand_child->bounds()),
            grand_child->visible_layer_rect());
}

TEST_F(DrawPropertiesTest, TransformsForDegenerateIntermediateLayer) {
  // A layer that is empty in one axis, but not the other, was accidentally
  // skipping a necessary translation.  Without that translation, the coordinate
  // space of the layer's draw transform is incorrect.
  //
  // Normally this isn't a problem, because the layer wouldn't be drawn anyway,
  // but if that layer becomes a render surface, then its draw transform is
  // implicitly inherited by the rest of the subtree, which then is positioned
  // incorrectly as a result.

  LayerImpl* root = root_layer();
  LayerImpl* child = AddLayer<LayerImpl>();
  LayerImpl* grand_child = AddLayer<LayerImpl>();
  grand_child->SetDrawsContent(true);

  root->SetBounds(gfx::Size(100, 100));
  // The child height is zero, but has non-zero width that should be accounted
  // for while computing draw transforms.
  child->SetBounds(gfx::Size(10, 0));
  grand_child->SetBounds(gfx::Size(10, 10));

  CopyProperties(root, child);
  CreateEffectNode(child).render_surface_reason = RenderSurfaceReason::kTest;
  CopyProperties(child, grand_child);

  UpdateActiveTreeDrawProperties();

  ASSERT_TRUE(GetRenderSurface(child));
  // This is the real test, the rest are sanity checks.
  EXPECT_TRANSFORMATION_MATRIX_EQ(gfx::Transform(),
                                  GetRenderSurface(child)->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(gfx::Transform(), child->DrawTransform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(gfx::Transform(),
                                  grand_child->DrawTransform());
}

TEST_F(DrawPropertiesTest, RenderSurfaceWithSublayerScale) {
  LayerImpl* root = root_layer();
  LayerImpl* render_surface = AddLayer<LayerImpl>();
  LayerImpl* child = AddLayer<LayerImpl>();
  LayerImpl* grand_child = AddLayer<LayerImpl>();

  gfx::Transform translate;
  translate.Translate3d(5, 5, 5);

  root->SetBounds(gfx::Size(100, 100));
  render_surface->SetBounds(gfx::Size(100, 100));
  child->SetBounds(gfx::Size(100, 100));
  grand_child->SetBounds(gfx::Size(100, 100));
  grand_child->SetDrawsContent(true);

  CopyProperties(root, render_surface);
  CreateTransformNode(render_surface).local = translate;
  CreateEffectNode(render_surface).render_surface_reason =
      RenderSurfaceReason::kTest;
  CopyProperties(render_surface, child);
  CreateTransformNode(child).local = translate;
  CopyProperties(child, grand_child);
  CreateTransformNode(grand_child).local = translate;

  // render_surface will have a sublayer scale because of device scale factor.
  float device_scale_factor = 2.0f;
  UpdateActiveTreeDrawProperties(device_scale_factor);

  // Between grand_child and render_surface, we translate by (10, 10) and scale
  // by a factor of 2.
  gfx::Vector2dF expected_translation(20.0f, 20.0f);
  EXPECT_EQ(grand_child->DrawTransform().To2dTranslation(),
            expected_translation);
}

TEST_F(DrawPropertiesTest, TransformAboveRootLayer) {
  // Transformations applied at the root of the tree should be forwarded
  // to child layers instead of applied to the root RenderSurface.
  LayerImpl* root = root_layer();
  LayerImpl* child = AddLayer<LayerImpl>();

  root->SetDrawsContent(true);
  root->SetBounds(gfx::Size(100, 100));
  child->SetDrawsContent(true);
  child->SetBounds(gfx::Size(100, 100));
  child->SetMasksToBounds(true);

  CopyProperties(root, child);
  CreateClipNode(child);

  float device_scale_factor = 1.0f;
  gfx::Transform translate;
  translate.Translate(50, 50);
  {
    SetDeviceTransform(translate);
    UpdateActiveTreeDrawProperties(device_scale_factor);
    EXPECT_TRANSFORMATION_MATRIX_EQ(
        translate, root->draw_properties().target_space_transform);
    EXPECT_TRANSFORMATION_MATRIX_EQ(
        translate, child->draw_properties().target_space_transform);
    EXPECT_TRANSFORMATION_MATRIX_EQ(gfx::Transform(),
                                    GetRenderSurface(root)->draw_transform());
    EXPECT_TRANSFORMATION_MATRIX_EQ(translate, child->ScreenSpaceTransform());
    EXPECT_EQ(gfx::Rect(50, 50, 100, 100), child->clip_rect());
  }

  gfx::Transform scale;
  scale.Scale(2, 2);
  {
    SetDeviceTransform(scale);
    UpdateActiveTreeDrawProperties(device_scale_factor);
    EXPECT_TRANSFORMATION_MATRIX_EQ(
        scale, root->draw_properties().target_space_transform);
    EXPECT_TRANSFORMATION_MATRIX_EQ(
        scale, child->draw_properties().target_space_transform);
    EXPECT_TRANSFORMATION_MATRIX_EQ(gfx::Transform(),
                                    GetRenderSurface(root)->draw_transform());
    EXPECT_TRANSFORMATION_MATRIX_EQ(scale, child->ScreenSpaceTransform());
    EXPECT_EQ(gfx::Rect(0, 0, 200, 200), child->clip_rect());
  }

  gfx::Transform rotate;
  rotate.Rotate(2);
  {
    SetDeviceTransform(rotate);
    UpdateActiveTreeDrawProperties(device_scale_factor);
    EXPECT_TRANSFORMATION_MATRIX_EQ(
        rotate, root->draw_properties().target_space_transform);
    EXPECT_TRANSFORMATION_MATRIX_EQ(
        rotate, child->draw_properties().target_space_transform);
    EXPECT_TRANSFORMATION_MATRIX_EQ(gfx::Transform(),
                                    GetRenderSurface(root)->draw_transform());
    EXPECT_TRANSFORMATION_MATRIX_EQ(rotate, child->ScreenSpaceTransform());
    EXPECT_EQ(gfx::Rect(-4, 0, 104, 104), child->clip_rect());
  }

  gfx::Transform composite;
  composite.ConcatTransform(translate);
  composite.ConcatTransform(scale);
  composite.ConcatTransform(rotate);
  {
    SetDeviceTransform(composite);
    UpdateActiveTreeDrawProperties(device_scale_factor);
    EXPECT_TRANSFORMATION_MATRIX_EQ(
        composite, root->draw_properties().target_space_transform);
    EXPECT_TRANSFORMATION_MATRIX_EQ(
        composite, child->draw_properties().target_space_transform);
    EXPECT_TRANSFORMATION_MATRIX_EQ(gfx::Transform(),
                                    GetRenderSurface(root)->draw_transform());
    EXPECT_TRANSFORMATION_MATRIX_EQ(composite, child->ScreenSpaceTransform());
    EXPECT_EQ(gfx::Rect(89, 103, 208, 208), child->clip_rect());
  }

  // Verify it composes correctly with device scale.
  device_scale_factor = 1.5f;

  {
    SetDeviceTransform(translate);
    UpdateActiveTreeDrawProperties(device_scale_factor);
    gfx::Transform device_scaled_translate = translate;
    device_scaled_translate.Scale(device_scale_factor, device_scale_factor);
    EXPECT_TRANSFORMATION_MATRIX_EQ(
        device_scaled_translate,
        root->draw_properties().target_space_transform);
    EXPECT_TRANSFORMATION_MATRIX_EQ(
        device_scaled_translate,
        child->draw_properties().target_space_transform);
    EXPECT_TRANSFORMATION_MATRIX_EQ(gfx::Transform(),
                                    GetRenderSurface(root)->draw_transform());
    EXPECT_TRANSFORMATION_MATRIX_EQ(device_scaled_translate,
                                    child->ScreenSpaceTransform());
    EXPECT_EQ(gfx::Rect(50, 50, 150, 150), child->clip_rect());
  }
}

TEST_F(DrawPropertiesTest, DrawableContentRectForReferenceFilter) {
  LayerImpl* root = root_layer();
  LayerImpl* child = AddLayer<LayerImpl>();

  root->SetBounds(gfx::Size(100, 100));
  child->SetBounds(gfx::Size(25, 25));
  child->SetDrawsContent(true);
  FilterOperations filters;
  filters.Append(FilterOperation::CreateReferenceFilter(
      sk_make_sp<OffsetPaintFilter>(50, 50, nullptr)));

  CopyProperties(root, child);
  auto& child_effect_node = CreateEffectNode(child);
  child_effect_node.render_surface_reason = RenderSurfaceReason::kTest;
  child_effect_node.filters = filters;

  UpdateActiveTreeDrawProperties();

  // The render surface's size should be unaffected by the offset image filter;
  // it need only have a drawable content rect large enough to contain the
  // contents (at the new offset).
  ASSERT_TRUE(GetRenderSurface(child));
  EXPECT_EQ(gfx::RectF(50, 50, 25, 25),
            GetRenderSurface(child)->DrawableContentRect());
}

TEST_F(DrawPropertiesTest, DrawableContentRectForReferenceFilterHighDpi) {
  const float device_scale_factor = 2.0f;

  LayerImpl* root = root_layer();
  LayerImpl* child = AddLayer<LayerImpl>();

  root->SetBounds(gfx::Size(100, 100));
  child->SetBounds(gfx::Size(25, 25));
  child->SetDrawsContent(true);

  FilterOperations filters;
  filters.Append(FilterOperation::CreateReferenceFilter(
      sk_make_sp<OffsetPaintFilter>(50, 50, nullptr)));

  CopyProperties(root, child);
  auto& child_effect_node = CreateEffectNode(child);
  child_effect_node.render_surface_reason = RenderSurfaceReason::kTest;
  child_effect_node.filters = filters;

  UpdateActiveTreeDrawProperties(device_scale_factor);

  // The render surface's size should be unaffected by the offset image filter;
  // it need only have a drawable content rect large enough to contain the
  // contents (at the new offset). All coordinates should be scaled by 2,
  // corresponding to the device scale factor.
  ASSERT_TRUE(GetRenderSurface(child));
  EXPECT_EQ(gfx::RectF(100, 100, 50, 50),
            GetRenderSurface(child)->DrawableContentRect());
}

TEST_F(DrawPropertiesTest, RenderSurfaceForBlendMode) {
  LayerImpl* root = root_layer();
  LayerImpl* child = AddLayer<LayerImpl>();

  root->SetBounds(gfx::Size(10, 10));
  child->SetBounds(gfx::Size(10, 10));
  child->SetDrawsContent(true);

  CopyProperties(root, child);
  auto& child_effect_node = CreateEffectNode(child);
  child_effect_node.render_surface_reason = RenderSurfaceReason::kTest;
  child_effect_node.blend_mode = SkBlendMode::kMultiply;
  child_effect_node.opacity = 0.5f;

  UpdateActiveTreeDrawProperties();

  // Since the child layer has a blend mode other than normal, it should get
  // its own render surface.
  ASSERT_TRUE(GetRenderSurface(child));
  EXPECT_EQ(1.0f, child->draw_opacity());
  EXPECT_EQ(0.5f, GetRenderSurface(child)->draw_opacity());
  EXPECT_EQ(SkBlendMode::kMultiply, GetRenderSurface(child)->BlendMode());
}

TEST_F(DrawPropertiesTest, RenderSurfaceDrawOpacity) {
  LayerImpl* root = root_layer();
  LayerImpl* surface1 = AddLayer<LayerImpl>();
  LayerImpl* not_surface = AddLayer<LayerImpl>();
  LayerImpl* surface2 = AddLayer<LayerImpl>();

  root->SetBounds(gfx::Size(10, 10));
  surface1->SetBounds(gfx::Size(10, 10));
  surface1->SetDrawsContent(true);
  not_surface->SetBounds(gfx::Size(10, 10));
  surface2->SetBounds(gfx::Size(10, 10));
  surface2->SetDrawsContent(true);

  CopyProperties(root, surface1);
  auto& surface1_effect_node = CreateEffectNode(surface1);
  surface1_effect_node.render_surface_reason = RenderSurfaceReason::kTest;
  surface1_effect_node.opacity = 0.5f;
  CopyProperties(surface1, not_surface);
  CreateEffectNode(not_surface).opacity = 0.5f;
  CopyProperties(not_surface, surface2);
  auto& surface2_effect_node = CreateEffectNode(surface2);
  surface2_effect_node.render_surface_reason = RenderSurfaceReason::kTest;
  surface2_effect_node.opacity = 0.5f;

  UpdateActiveTreeDrawProperties();

  ASSERT_TRUE(GetRenderSurface(surface1));
  ASSERT_EQ(GetRenderSurface(not_surface), GetRenderSurface(surface1));
  ASSERT_TRUE(GetRenderSurface(surface2));
  EXPECT_EQ(0.5f, GetRenderSurface(surface1)->draw_opacity());
  // surface2's draw opacity should include the opacity of not-surface and
  // itself, but not the opacity of surface1.
  EXPECT_EQ(0.25f, GetRenderSurface(surface2)->draw_opacity());
}

TEST_F(DrawPropertiesTest, ClipRectCullsRenderSurfaces) {
  // The entire subtree of layers that are outside the clip rect should be
  // culled away, and should not affect the GetRenderSurfaceList.
  //
  // The test tree is set up as follows:
  //  - all layers except the leaf_nodes are forced to be a new render surface
  //  that have something to draw.
  //  - parent is a large container layer.
  //  - child has MasksToBounds=true to cause clipping.
  //  - grand_child is positioned outside of the child's bounds
  //  - great_grand_child is also kept outside child's bounds.
  //
  // In this configuration, grand_child and great_grand_child are completely
  // outside the clip rect, and they should never get scheduled on the list of
  // render surfaces.

  LayerImpl* root = root_layer();
  LayerImpl* child = AddLayer<LayerImpl>();
  LayerImpl* grand_child = AddLayer<LayerImpl>();
  LayerImpl* great_grand_child = AddLayer<LayerImpl>();

  // leaf_node1 ensures that root and child are kept on the
  // GetRenderSurfaceList, even though grand_child and great_grand_child should
  // be clipped.
  LayerImpl* leaf_node1 = AddLayer<LayerImpl>();
  LayerImpl* leaf_node2 = AddLayer<LayerImpl>();

  root->SetBounds(gfx::Size(500, 500));
  child->SetBounds(gfx::Size(20, 20));
  child->SetMasksToBounds(true);
  grand_child->SetBounds(gfx::Size(10, 10));
  great_grand_child->SetBounds(gfx::Size(10, 10));
  leaf_node1->SetBounds(gfx::Size(500, 500));
  leaf_node1->SetDrawsContent(true);
  leaf_node1->SetBounds(gfx::Size(20, 20));
  leaf_node2->SetDrawsContent(true);

  CopyProperties(root, child);
  CreateClipNode(child);
  CreateEffectNode(child).render_surface_reason = RenderSurfaceReason::kTest;
  CopyProperties(child, leaf_node1);
  CopyProperties(child, grand_child);
  grand_child->SetOffsetToTransformParent(gfx::Vector2dF(45.f, 45.f));
  CopyProperties(grand_child, great_grand_child);
  great_grand_child->SetOffsetToTransformParent(
      grand_child->offset_to_transform_parent());
  CopyProperties(great_grand_child, leaf_node2);
  leaf_node2->SetOffsetToTransformParent(
      great_grand_child->offset_to_transform_parent());

  UpdateActiveTreeDrawProperties();

  ASSERT_EQ(2U, GetRenderSurfaceList().size());
  EXPECT_EQ(static_cast<uint64_t>(root->id()),
            GetRenderSurfaceList().at(0)->id());
  EXPECT_EQ(static_cast<uint64_t>(child->id()),
            GetRenderSurfaceList().at(1)->id());
}

TEST_F(DrawPropertiesTest, ClipRectCullsSurfaceWithoutVisibleContent) {
  // When a render surface has a clip rect, it is used to clip the content rect
  // of the surface.

  // The test tree is set up as follows:
  //  - root is a container layer that masksToBounds=true to cause clipping.
  //  - child is a render surface, which has a clip rect set to the bounds of
  //  the root.
  //  - grand_child is a render surface, and the only visible content in child.
  //  It is positioned outside of the clip rect from root.

  // In this configuration, grand_child should be outside the clipped
  // content rect of the child, making grand_child not appear in the
  // GetRenderSurfaceList.

  LayerImpl* root = root_layer();
  LayerImpl* child = AddLayer<LayerImpl>();
  LayerImpl* grand_child = AddLayer<LayerImpl>();
  LayerImpl* leaf_node = AddLayer<LayerImpl>();

  root->SetMasksToBounds(true);
  root->SetBounds(gfx::Size(100, 100));
  child->SetBounds(gfx::Size(20, 20));
  grand_child->SetBounds(gfx::Size(10, 10));
  leaf_node->SetBounds(gfx::Size(10, 10));
  leaf_node->SetDrawsContent(true);

  CreateClipNode(root);
  CopyProperties(root, child);
  CreateEffectNode(child).render_surface_reason = RenderSurfaceReason::kTest;
  CopyProperties(child, grand_child);
  grand_child->SetOffsetToTransformParent(gfx::Vector2dF(200.f, 200.f));
  CreateEffectNode(grand_child).render_surface_reason =
      RenderSurfaceReason::kTest;
  CopyProperties(grand_child, leaf_node);
  leaf_node->SetOffsetToTransformParent(
      grand_child->offset_to_transform_parent());

  UpdateActiveTreeDrawProperties();

  // We should cull child and grand_child from the GetRenderSurfaceList.
  ASSERT_EQ(1U, GetRenderSurfaceList().size());
  EXPECT_EQ(static_cast<uint64_t>(root->id()),
            GetRenderSurfaceList().at(0)->id());
}

TEST_F(DrawPropertiesTest, IsClippedIsSetCorrectlyLayerImpl) {
  // Tests that LayerImpl's IsClipped() property is set to true when:
  //  - the layer clips its subtree, e.g. masks to bounds,
  //  - the layer is clipped by an ancestor that contributes to the same
  //    render target,
  //  - a surface is clipped by an ancestor that contributes to the same
  //    render target.
  //
  // In particular, for a layer that owns a render surface:
  //  - the render surface inherits any clip from ancestors, and does NOT
  //    pass that clipped status to the layer itself.
  //  - but if the layer itself masks to bounds, it is considered clipped
  //    and propagates the clip to the subtree.

  LayerImpl* root = root_layer();
  LayerImpl* parent = AddLayer<LayerImpl>();
  LayerImpl* child1 = AddLayer<LayerImpl>();
  LayerImpl* child2 = AddLayer<LayerImpl>();
  LayerImpl* grand_child = AddLayer<LayerImpl>();
  LayerImpl* leaf_node1 = AddLayer<LayerImpl>();
  LayerImpl* leaf_node2 = AddLayer<LayerImpl>();

  root->SetBounds(gfx::Size(100, 100));
  parent->SetBounds(gfx::Size(100, 100));
  parent->SetDrawsContent(true);
  child1->SetBounds(gfx::Size(100, 100));
  child1->SetDrawsContent(true);
  child2->SetBounds(gfx::Size(100, 100));
  child2->SetDrawsContent(true);
  grand_child->SetBounds(gfx::Size(100, 100));
  grand_child->SetDrawsContent(true);
  leaf_node1->SetBounds(gfx::Size(100, 100));
  leaf_node1->SetDrawsContent(true);
  leaf_node2->SetBounds(gfx::Size(100, 100));
  leaf_node2->SetDrawsContent(true);

  CopyProperties(root, parent);
  CopyProperties(parent, child1);
  CopyProperties(child1, grand_child);
  CopyProperties(grand_child, leaf_node1);
  CopyProperties(parent, child2);
  CreateTransformNode(child2);
  CreateEffectNode(child2).render_surface_reason = RenderSurfaceReason::kTest;
  CopyProperties(child2, leaf_node2);

  // Case 1: nothing is clipped except the root render surface.
  UpdateActiveTreeDrawProperties();

  ASSERT_TRUE(GetRenderSurface(root));
  ASSERT_TRUE(GetRenderSurface(child2));

  EXPECT_FALSE(root->is_clipped());
  EXPECT_TRUE(GetRenderSurface(root)->is_clipped());
  EXPECT_FALSE(parent->is_clipped());
  EXPECT_FALSE(child1->is_clipped());
  EXPECT_FALSE(child2->is_clipped());
  EXPECT_FALSE(GetRenderSurface(child2)->is_clipped());
  EXPECT_FALSE(grand_child->is_clipped());
  EXPECT_FALSE(leaf_node1->is_clipped());
  EXPECT_FALSE(leaf_node2->is_clipped());

  // Case 2: parent MasksToBounds, so the parent, child1, and child2's
  // surface are clipped. But layers that contribute to child2's surface are
  // not clipped explicitly because child2's surface already accounts for
  // that clip.
  parent->SetMasksToBounds(true);
  CreateClipNode(parent);
  child1->SetClipTreeIndex(parent->clip_tree_index());
  grand_child->SetClipTreeIndex(parent->clip_tree_index());
  leaf_node1->SetClipTreeIndex(parent->clip_tree_index());
  child2->SetClipTreeIndex(parent->clip_tree_index());
  GetEffectNode(child2)->clip_id = parent->clip_tree_index();
  leaf_node2->SetClipTreeIndex(parent->clip_tree_index());

  host_impl()->active_tree()->set_needs_update_draw_properties();
  UpdateActiveTreeDrawProperties();

  ASSERT_TRUE(GetRenderSurface(root));
  ASSERT_TRUE(GetRenderSurface(child2));

  EXPECT_FALSE(root->is_clipped());
  EXPECT_TRUE(GetRenderSurface(root)->is_clipped());
  EXPECT_TRUE(parent->is_clipped());
  EXPECT_TRUE(child1->is_clipped());
  EXPECT_FALSE(child2->is_clipped());
  EXPECT_TRUE(GetRenderSurface(child2)->is_clipped());
  EXPECT_TRUE(grand_child->is_clipped());
  EXPECT_TRUE(leaf_node1->is_clipped());
  EXPECT_FALSE(leaf_node2->is_clipped());

  parent->SetMasksToBounds(false);
  parent->SetClipTreeIndex(root->clip_tree_index());
  child1->SetClipTreeIndex(root->clip_tree_index());
  grand_child->SetClipTreeIndex(root->clip_tree_index());
  leaf_node1->SetClipTreeIndex(root->clip_tree_index());
  child2->SetClipTreeIndex(root->clip_tree_index());
  GetEffectNode(child2)->clip_id = root->clip_tree_index();
  leaf_node2->SetClipTreeIndex(root->clip_tree_index());

  // Case 3: child2 MasksToBounds. The layer and subtree are clipped, and
  // child2's render surface is not clipped.
  child2->SetMasksToBounds(true);
  CreateClipNode(child2);
  leaf_node2->SetClipTreeIndex(child2->clip_tree_index());

  host_impl()->active_tree()->set_needs_update_draw_properties();
  UpdateActiveTreeDrawProperties();

  ASSERT_TRUE(GetRenderSurface(root));
  ASSERT_TRUE(GetRenderSurface(child2));

  EXPECT_FALSE(root->is_clipped());
  EXPECT_TRUE(GetRenderSurface(root)->is_clipped());
  EXPECT_FALSE(parent->is_clipped());
  EXPECT_FALSE(child1->is_clipped());
  EXPECT_TRUE(child2->is_clipped());
  EXPECT_FALSE(GetRenderSurface(child2)->is_clipped());
  EXPECT_FALSE(grand_child->is_clipped());
  EXPECT_FALSE(leaf_node1->is_clipped());
  EXPECT_TRUE(leaf_node2->is_clipped());
}

TEST_F(DrawPropertiesTest, UpdateClipRectCorrectly) {
  // Tests that when as long as layer is clipped, it's clip rect is set to
  // correct value.
  LayerImpl* root = root_layer();
  LayerImpl* parent = AddLayer<LayerImpl>();
  LayerImpl* child = AddLayer<LayerImpl>();

  root->SetBounds(gfx::Size(100, 100));
  root->SetDrawsContent(true);
  parent->SetBounds(gfx::Size(100, 100));
  parent->SetDrawsContent(true);
  child->SetBounds(gfx::Size(100, 100));
  child->SetDrawsContent(true);
  child->SetMasksToBounds(true);

  CopyProperties(root, parent);
  CopyProperties(parent, child);
  CreateClipNode(child);

  UpdateActiveTreeDrawProperties();

  EXPECT_FALSE(root->is_clipped());
  EXPECT_FALSE(parent->is_clipped());
  EXPECT_TRUE(child->is_clipped());
  EXPECT_EQ(gfx::Rect(100, 100), child->clip_rect());

  parent->SetMasksToBounds(true);
  CreateClipNode(parent);
  GetClipNode(child)->parent_id = parent->clip_tree_index();
  child->SetOffsetToTransformParent(gfx::Vector2dF(100.f, 100.f));
  GetClipNode(child)->clip += gfx::Vector2dF(100.f, 100.f);

  host_impl()->active_tree()->set_needs_update_draw_properties();
  UpdateActiveTreeDrawProperties();

  EXPECT_FALSE(root->is_clipped());
  EXPECT_TRUE(parent->is_clipped());
  EXPECT_TRUE(child->is_clipped());
  EXPECT_EQ(gfx::Rect(), child->clip_rect());
}

TEST_F(DrawPropertiesTest, DrawableContentRectForLayers) {
  // Verify that layers get the appropriate DrawableContentRect when their
  // parent MasksToBounds is true.
  //
  //   grand_child1 - completely inside the region; DrawableContentRect should
  //   be the layer rect expressed in target space.
  //   grand_child2 - partially clipped but NOT MasksToBounds; the clip rect
  //   will be the intersection of layer bounds and the mask region.
  //   grand_child3 - partially clipped and MasksToBounds; the
  //   DrawableContentRect will still be the intersection of layer bounds and
  //   the mask region.
  //   grand_child4 - outside parent's clip rect; the DrawableContentRect should
  //   be empty.

  LayerImpl* parent = root_layer();
  LayerImpl* child = AddLayer<LayerImpl>();
  LayerImpl* grand_child1 = AddLayer<LayerImpl>();
  LayerImpl* grand_child2 = AddLayer<LayerImpl>();
  LayerImpl* grand_child3 = AddLayer<LayerImpl>();
  LayerImpl* grand_child4 = AddLayer<LayerImpl>();

  parent->SetBounds(gfx::Size(500, 500));
  child->SetMasksToBounds(true);
  child->SetBounds(gfx::Size(20, 20));
  grand_child1->SetBounds(gfx::Size(10, 10));
  grand_child1->SetDrawsContent(true);
  grand_child2->SetBounds(gfx::Size(10, 10));
  grand_child2->SetDrawsContent(true);
  grand_child3->SetBounds(gfx::Size(10, 10));
  grand_child3->SetMasksToBounds(true);
  grand_child3->SetDrawsContent(true);
  grand_child4->SetBounds(gfx::Size(10, 10));
  grand_child4->SetDrawsContent(true);

  CopyProperties(parent, child);
  CreateTransformNode(child);
  CreateEffectNode(child).render_surface_reason = RenderSurfaceReason::kTest;
  CreateClipNode(child);
  CopyProperties(child, grand_child1);
  grand_child1->SetOffsetToTransformParent(gfx::Vector2dF(5.f, 5.f));
  CopyProperties(child, grand_child2);
  grand_child2->SetOffsetToTransformParent(gfx::Vector2dF(15.f, 15.f));
  CopyProperties(child, grand_child3);
  grand_child3->SetOffsetToTransformParent(gfx::Vector2dF(15.f, 15.f));
  CreateClipNode(grand_child3);
  CopyProperties(child, grand_child4);
  grand_child4->SetOffsetToTransformParent(gfx::Vector2dF(45.f, 45.f));

  UpdateActiveTreeDrawProperties();

  EXPECT_EQ(gfx::Rect(5, 5, 10, 10), grand_child1->drawable_content_rect());
  EXPECT_EQ(gfx::Rect(15, 15, 5, 5), grand_child3->drawable_content_rect());
  EXPECT_EQ(gfx::Rect(15, 15, 5, 5), grand_child3->drawable_content_rect());
  EXPECT_TRUE(grand_child4->drawable_content_rect().IsEmpty());
}

TEST_F(DrawPropertiesTest, ClipRectIsPropagatedCorrectlyToSurfaces) {
  // Verify that render surfaces (and their layers) get the appropriate
  // clip rects when their parent MasksToBounds is true.
  //
  // Layers that own render surfaces (at least for now) do not inherit any
  // clipping; instead the surface will enforce the clip for the entire subtree.
  // They may still have a clip rect of their own layer bounds, however, if
  // MasksToBounds was true.
  LayerImpl* parent = root_layer();
  LayerImpl* child = AddLayer<LayerImpl>();
  LayerImpl* grand_child1 = AddLayer<LayerImpl>();
  LayerImpl* grand_child2 = AddLayer<LayerImpl>();
  LayerImpl* grand_child3 = AddLayer<LayerImpl>();
  LayerImpl* grand_child4 = AddLayer<LayerImpl>();
  // The leaf nodes ensure that these grand_children become render surfaces for
  // this test.
  LayerImpl* leaf_node1 = AddLayer<LayerImpl>();
  LayerImpl* leaf_node2 = AddLayer<LayerImpl>();
  LayerImpl* leaf_node3 = AddLayer<LayerImpl>();
  LayerImpl* leaf_node4 = AddLayer<LayerImpl>();

  parent->SetBounds(gfx::Size(500, 500));
  child->SetBounds(gfx::Size(20, 20));
  child->SetMasksToBounds(true);
  grand_child1->SetBounds(gfx::Size(10, 10));
  grand_child2->SetBounds(gfx::Size(10, 10));
  grand_child3->SetBounds(gfx::Size(10, 10));
  grand_child3->SetMasksToBounds(true);
  grand_child4->SetBounds(gfx::Size(10, 10));
  grand_child4->SetMasksToBounds(true);
  leaf_node1->SetBounds(gfx::Size(10, 10));
  leaf_node1->SetDrawsContent(true);
  leaf_node2->SetBounds(gfx::Size(10, 10));
  leaf_node2->SetDrawsContent(true);
  leaf_node3->SetBounds(gfx::Size(10, 10));
  leaf_node3->SetDrawsContent(true);
  leaf_node4->SetBounds(gfx::Size(10, 10));
  leaf_node4->SetDrawsContent(true);

  CopyProperties(parent, child);
  CreateEffectNode(child).render_surface_reason = RenderSurfaceReason::kTest;
  CreateClipNode(child);
  CopyProperties(child, grand_child1);
  CreateTransformNode(grand_child1).post_translation = gfx::Vector2dF(5.f, 5.f);
  CreateEffectNode(grand_child1).render_surface_reason =
      RenderSurfaceReason::kTest;
  CopyProperties(grand_child1, leaf_node1);
  CopyProperties(child, grand_child2);
  CreateTransformNode(grand_child2).post_translation =
      gfx::Vector2dF(15.f, 15.f);
  CreateEffectNode(grand_child2).render_surface_reason =
      RenderSurfaceReason::kTest;
  CopyProperties(grand_child2, leaf_node2);
  CopyProperties(child, grand_child3);
  CreateTransformNode(grand_child3).post_translation =
      gfx::Vector2dF(15.f, 15.f);
  CreateEffectNode(grand_child3).render_surface_reason =
      RenderSurfaceReason::kTest;
  CreateClipNode(grand_child3);
  CopyProperties(grand_child3, leaf_node3);
  CopyProperties(child, grand_child4);
  CreateTransformNode(grand_child4).post_translation =
      gfx::Vector2dF(45.f, 45.f);
  CreateEffectNode(grand_child4).render_surface_reason =
      RenderSurfaceReason::kTest;
  CreateClipNode(grand_child4);
  CopyProperties(grand_child4, leaf_node4);

  UpdateActiveTreeDrawProperties();

  ASSERT_TRUE(GetRenderSurface(grand_child1));
  ASSERT_TRUE(GetRenderSurface(grand_child2));
  ASSERT_TRUE(GetRenderSurface(grand_child3));

  // Surfaces are clipped by their parent, but un-affected by the owning layer's
  // MasksToBounds.
  EXPECT_EQ(gfx::Rect(0, 0, 20, 20),
            GetRenderSurface(grand_child1)->clip_rect());
  EXPECT_EQ(gfx::Rect(0, 0, 20, 20),
            GetRenderSurface(grand_child2)->clip_rect());
  EXPECT_EQ(gfx::Rect(0, 0, 20, 20),
            GetRenderSurface(grand_child3)->clip_rect());
}

TEST_F(DrawPropertiesTest, AnimationsForRenderSurfaceHierarchy) {
  LayerImpl* root = root_layer();
  LayerImpl* top = AddLayer<LayerImpl>();
  LayerImpl* render_surface1 = AddLayer<LayerImpl>();
  LayerImpl* child_of_rs1 = AddLayer<LayerImpl>();
  LayerImpl* grand_child_of_rs1 = AddLayer<LayerImpl>();
  LayerImpl* render_surface2 = AddLayer<LayerImpl>();
  LayerImpl* child_of_rs2 = AddLayer<LayerImpl>();
  LayerImpl* grand_child_of_rs2 = AddLayer<LayerImpl>();
  LayerImpl* child_of_top = AddLayer<LayerImpl>();
  LayerImpl* grand_child_of_top = AddLayer<LayerImpl>();
  SetElementIdsForTesting();

  top->SetDrawsContent(true);
  render_surface1->SetDrawsContent(true);
  child_of_rs1->SetDrawsContent(true);
  grand_child_of_rs1->SetDrawsContent(true);
  render_surface2->SetDrawsContent(true);
  child_of_rs2->SetDrawsContent(true);
  grand_child_of_rs2->SetDrawsContent(true);
  child_of_top->SetDrawsContent(true);
  grand_child_of_top->SetDrawsContent(true);

  gfx::Transform layer_transform;
  layer_transform.Translate(1.0, 1.0);

  root->SetBounds(gfx::Size(10, 10));
  top->SetBounds(gfx::Size(10, 10));
  render_surface1->SetBounds(gfx::Size(10, 10));
  render_surface2->SetBounds(gfx::Size(10, 10));
  child_of_top->SetBounds(gfx::Size(10, 10));
  child_of_rs1->SetBounds(gfx::Size(10, 10));
  child_of_rs2->SetBounds(gfx::Size(10, 10));
  grand_child_of_top->SetBounds(gfx::Size(10, 10));
  grand_child_of_rs1->SetBounds(gfx::Size(10, 10));
  grand_child_of_rs2->SetBounds(gfx::Size(10, 10));

  CopyProperties(root, top);
  CreateTransformNode(top).local = layer_transform;
  CopyProperties(top, render_surface1);
  auto& render_surface1_transform_node = CreateTransformNode(render_surface1);
  render_surface1_transform_node.origin = gfx::Point3F(0.25f, 0.f, 0.f);
  render_surface1_transform_node.post_translation = gfx::Vector2dF(2.5f, 0.f);
  render_surface1_transform_node.local = layer_transform;
  CreateEffectNode(render_surface1).render_surface_reason =
      RenderSurfaceReason::kTest;
  CopyProperties(render_surface1, child_of_rs1);
  auto& child_of_rs1_transform_node = CreateTransformNode(child_of_rs1);
  child_of_rs1_transform_node.origin = gfx::Point3F(0.25f, 0.f, 0.f);
  child_of_rs1_transform_node.post_translation = gfx::Vector2dF(2.5f, 0.f);
  child_of_rs1_transform_node.local = layer_transform;
  CopyProperties(child_of_rs1, grand_child_of_rs1);
  auto& grand_child_of_rs1_transform_node =
      CreateTransformNode(grand_child_of_rs1);
  grand_child_of_rs1_transform_node.origin = gfx::Point3F(0.25f, 0.f, 0.f);
  grand_child_of_rs1_transform_node.post_translation =
      gfx::Vector2dF(2.5f, 0.f);
  grand_child_of_rs1_transform_node.local = layer_transform;
  CopyProperties(render_surface1, render_surface2);
  auto& render_surface2_transform_node = CreateTransformNode(render_surface2);
  render_surface2_transform_node.origin = gfx::Point3F(0.25f, 0.f, 0.f);
  render_surface2_transform_node.post_translation = gfx::Vector2dF(2.5f, 0.f);
  render_surface2_transform_node.local = layer_transform;
  CreateEffectNode(render_surface2).render_surface_reason =
      RenderSurfaceReason::kTest;
  CopyProperties(render_surface2, child_of_rs2);
  auto& child_of_rs2_transform_node = CreateTransformNode(child_of_rs2);
  child_of_rs2_transform_node.origin = gfx::Point3F(0.25f, 0.f, 0.f);
  child_of_rs2_transform_node.post_translation = gfx::Vector2dF(2.5f, 0.f);
  child_of_rs2_transform_node.local = layer_transform;
  CopyProperties(child_of_rs2, grand_child_of_rs2);
  auto& grand_child_of_rs2_transform_node =
      CreateTransformNode(grand_child_of_rs2);
  grand_child_of_rs2_transform_node.origin = gfx::Point3F(0.25f, 0.f, 0.f);
  grand_child_of_rs2_transform_node.post_translation =
      gfx::Vector2dF(2.5f, 0.f);
  grand_child_of_rs2_transform_node.local = layer_transform;
  CopyProperties(top, child_of_top);
  auto& child_of_top_transform_node = CreateTransformNode(child_of_top);
  child_of_top_transform_node.origin = gfx::Point3F(0.25f, 0.f, 0.f);
  child_of_top_transform_node.post_translation = gfx::Vector2dF(2.5f, 0.f);
  child_of_top_transform_node.local = layer_transform;
  CopyProperties(child_of_top, grand_child_of_top);
  auto& grand_child_of_top_transform_node =
      CreateTransformNode(grand_child_of_top);
  grand_child_of_top_transform_node.origin = gfx::Point3F(0.25f, 0.f, 0.f);
  grand_child_of_top_transform_node.post_translation =
      gfx::Vector2dF(2.5f, 0.f);
  grand_child_of_top_transform_node.local = layer_transform;

  // Put an animated opacity on the render surface.
  AddOpacityTransitionToElementWithAnimation(
      render_surface1->element_id(), timeline_impl(), 10.0, 1.f, 0.f, false);

  // Also put an animated opacity on a layer without descendants.
  AddOpacityTransitionToElementWithAnimation(
      grand_child_of_top->element_id(), timeline_impl(), 10.0, 1.f, 0.f, false);

  // Put a transform animation on the render surface.
  AddAnimatedTransformToElementWithAnimation(render_surface2->element_id(),
                                             timeline_impl(), 10.0, 30, 0);

  // Also put transform animations on grand_child_of_top, and
  // grand_child_of_rs2
  AddAnimatedTransformToElementWithAnimation(grand_child_of_top->element_id(),
                                             timeline_impl(), 10.0, 30, 0);
  AddAnimatedTransformToElementWithAnimation(grand_child_of_rs2->element_id(),
                                             timeline_impl(), 10.0, 30, 0);

  UpdateActiveTreeDrawProperties();

  // Only layers that are associated with render surfaces should have an actual
  // RenderSurface() value.
  ASSERT_TRUE(GetRenderSurface(root));
  ASSERT_EQ(GetRenderSurface(top), GetRenderSurface(root));
  ASSERT_EQ(GetRenderSurface(child_of_top), GetRenderSurface(root));
  ASSERT_EQ(GetRenderSurface(grand_child_of_top), GetRenderSurface(root));

  ASSERT_NE(GetRenderSurface(render_surface1), GetRenderSurface(root));
  ASSERT_EQ(GetRenderSurface(child_of_rs1), GetRenderSurface(render_surface1));
  ASSERT_EQ(GetRenderSurface(grand_child_of_rs1),
            GetRenderSurface(render_surface1));

  ASSERT_NE(GetRenderSurface(render_surface2), GetRenderSurface(root));
  ASSERT_NE(GetRenderSurface(render_surface2),
            GetRenderSurface(render_surface1));
  ASSERT_EQ(GetRenderSurface(child_of_rs2), GetRenderSurface(render_surface2));
  ASSERT_EQ(GetRenderSurface(grand_child_of_rs2),
            GetRenderSurface(render_surface2));

  // Verify all render target accessors
  EXPECT_EQ(GetRenderSurface(root), root->render_target());
  EXPECT_EQ(GetRenderSurface(root), top->render_target());
  EXPECT_EQ(GetRenderSurface(root), child_of_top->render_target());
  EXPECT_EQ(GetRenderSurface(root), grand_child_of_top->render_target());

  EXPECT_EQ(GetRenderSurface(render_surface1),
            render_surface1->render_target());
  EXPECT_EQ(GetRenderSurface(render_surface1), child_of_rs1->render_target());
  EXPECT_EQ(GetRenderSurface(render_surface1),
            grand_child_of_rs1->render_target());

  EXPECT_EQ(GetRenderSurface(render_surface2),
            render_surface2->render_target());
  EXPECT_EQ(GetRenderSurface(render_surface2), child_of_rs2->render_target());
  EXPECT_EQ(GetRenderSurface(render_surface2),
            grand_child_of_rs2->render_target());

  // Verify screen_space_transform_is_animating values
  EXPECT_FALSE(root->screen_space_transform_is_animating());
  EXPECT_FALSE(child_of_top->screen_space_transform_is_animating());
  EXPECT_TRUE(grand_child_of_top->screen_space_transform_is_animating());
  EXPECT_FALSE(render_surface1->screen_space_transform_is_animating());
  EXPECT_FALSE(child_of_rs1->screen_space_transform_is_animating());
  EXPECT_FALSE(grand_child_of_rs1->screen_space_transform_is_animating());
  EXPECT_TRUE(render_surface2->screen_space_transform_is_animating());
  EXPECT_TRUE(child_of_rs2->screen_space_transform_is_animating());
  EXPECT_TRUE(grand_child_of_rs2->screen_space_transform_is_animating());

  // Sanity check. If these fail there is probably a bug in the test itself.
  // It is expected that we correctly set up transforms so that the y-component
  // of the screen-space transform encodes the "depth" of the layer in the tree.
  EXPECT_FLOAT_EQ(1.0, top->ScreenSpaceTransform().matrix().get(1, 3));
  EXPECT_FLOAT_EQ(2.0, child_of_top->ScreenSpaceTransform().matrix().get(1, 3));
  EXPECT_FLOAT_EQ(
      3.0, grand_child_of_top->ScreenSpaceTransform().matrix().get(1, 3));

  EXPECT_FLOAT_EQ(2.0,
                  render_surface1->ScreenSpaceTransform().matrix().get(1, 3));
  EXPECT_FLOAT_EQ(3.0, child_of_rs1->ScreenSpaceTransform().matrix().get(1, 3));
  EXPECT_FLOAT_EQ(
      4.0, grand_child_of_rs1->ScreenSpaceTransform().matrix().get(1, 3));

  EXPECT_FLOAT_EQ(3.0,
                  render_surface2->ScreenSpaceTransform().matrix().get(1, 3));
  EXPECT_FLOAT_EQ(4.0, child_of_rs2->ScreenSpaceTransform().matrix().get(1, 3));
  EXPECT_FLOAT_EQ(
      5.0, grand_child_of_rs2->ScreenSpaceTransform().matrix().get(1, 3));
}

TEST_F(DrawPropertiesTest, LargeTransforms) {
  LayerImpl* root = root_layer();
  LayerImpl* child = AddLayer<LayerImpl>();
  LayerImpl* grand_child = AddLayer<LayerImpl>();

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

  root->SetBounds(gfx::Size(10, 10));
  child->SetBounds(gfx::Size(10, 10));
  grand_child->SetBounds(gfx::Size(10, 10));
  grand_child->SetDrawsContent(true);

  CopyProperties(root, child);
  CreateTransformNode(child).local = large_transform;
  CopyProperties(child, grand_child);
  CreateTransformNode(grand_child).local = large_transform;

  UpdateActiveTreeDrawProperties();

  EXPECT_EQ(gfx::Rect(), grand_child->visible_layer_rect());
}

static bool TransformIsAnimating(LayerImpl* layer) {
  MutatorHost* host = layer->layer_tree_impl()->mutator_host();
  return host->IsAnimatingTransformProperty(
      layer->element_id(), layer->GetElementTypeForAnimation());
}

static bool HasPotentiallyRunningTransformAnimation(LayerImpl* layer) {
  MutatorHost* host = layer->layer_tree_impl()->mutator_host();
  return host->HasPotentiallyRunningTransformAnimation(
      layer->element_id(), layer->GetElementTypeForAnimation());
}

TEST_F(DrawPropertiesTest,
       ScreenSpaceTransformIsAnimatingWithDelayedAnimation) {
  LayerImpl* root = root_layer();
  LayerImpl* child = AddLayer<LayerImpl>();
  LayerImpl* grand_child = AddLayer<LayerImpl>();
  LayerImpl* great_grand_child = AddLayer<LayerImpl>();

  root->SetDrawsContent(true);
  child->SetDrawsContent(true);
  grand_child->SetDrawsContent(true);
  great_grand_child->SetDrawsContent(true);

  root->SetBounds(gfx::Size(10, 10));
  child->SetBounds(gfx::Size(10, 10));
  grand_child->SetBounds(gfx::Size(10, 10));
  great_grand_child->SetBounds(gfx::Size(10, 10));

  SetElementIdsForTesting();

  CopyProperties(root, child);
  CopyProperties(child, grand_child);
  CreateTransformNode(grand_child);  // for animation.
  CopyProperties(grand_child, great_grand_child);

  // Add a transform animation with a start delay to |grand_child|.
  std::unique_ptr<KeyframeModel> keyframe_model = KeyframeModel::Create(
      std::unique_ptr<AnimationCurve>(new FakeTransformTransition(1.0)), 0, 1,
      TargetProperty::TRANSFORM);
  keyframe_model->set_fill_mode(KeyframeModel::FillMode::NONE);
  keyframe_model->set_time_offset(base::TimeDelta::FromMilliseconds(-1000));
  AddKeyframeModelToElementWithAnimation(
      grand_child->element_id(), timeline_impl(), std::move(keyframe_model));

  UpdateActiveTreeDrawProperties();

  EXPECT_FALSE(root->screen_space_transform_is_animating());
  EXPECT_FALSE(child->screen_space_transform_is_animating());

  EXPECT_FALSE(TransformIsAnimating(grand_child));
  EXPECT_TRUE(HasPotentiallyRunningTransformAnimation(grand_child));
  EXPECT_TRUE(grand_child->screen_space_transform_is_animating());
  EXPECT_TRUE(great_grand_child->screen_space_transform_is_animating());
}

// Test visible layer rect and drawable content rect are calculated correctly
// for identity transforms.
TEST_F(DrawPropertiesDrawRectsTest, DrawRectsForIdentityTransform) {
  gfx::Rect target_surface_rect = gfx::Rect(0, 0, 100, 100);
  gfx::Transform layer_to_surface_transform;

  // Case 1: Layer is contained within the surface.
  gfx::Rect layer_content_rect = gfx::Rect(10, 10, 30, 30);
  gfx::Rect expected_visible_layer_rect = gfx::Rect(30, 30);
  gfx::Rect expected_drawable_content_rect = gfx::Rect(10, 10, 30, 30);
  LayerImpl* drawing_layer = TestVisibleRectAndDrawableContentRect(
      target_surface_rect, layer_to_surface_transform, layer_content_rect);
  EXPECT_EQ(expected_visible_layer_rect, drawing_layer->visible_layer_rect());
  EXPECT_EQ(expected_drawable_content_rect,
            drawing_layer->drawable_content_rect());

  // Case 2: Layer is outside the surface rect.
  layer_content_rect = gfx::Rect(120, 120, 30, 30);
  expected_visible_layer_rect = gfx::Rect();
  expected_drawable_content_rect = gfx::Rect();
  drawing_layer = TestVisibleRectAndDrawableContentRect(
      target_surface_rect, layer_to_surface_transform, layer_content_rect);
  EXPECT_EQ(expected_visible_layer_rect, drawing_layer->visible_layer_rect());
  EXPECT_EQ(expected_drawable_content_rect,
            drawing_layer->drawable_content_rect());

  // Case 3: Layer is partially overlapping the surface rect.
  layer_content_rect = gfx::Rect(80, 80, 30, 30);
  expected_visible_layer_rect = gfx::Rect(20, 20);
  expected_drawable_content_rect = gfx::Rect(80, 80, 20, 20);
  drawing_layer = TestVisibleRectAndDrawableContentRect(
      target_surface_rect, layer_to_surface_transform, layer_content_rect);
  EXPECT_EQ(expected_visible_layer_rect, drawing_layer->visible_layer_rect());
  EXPECT_EQ(expected_drawable_content_rect,
            drawing_layer->drawable_content_rect());
}

// Test visible layer rect and drawable content rect are calculated correctly
// for rotations about z-axis (i.e. 2D rotations).
TEST_F(DrawPropertiesDrawRectsTest, DrawRectsFor2DRotations) {
  gfx::Rect target_surface_rect = gfx::Rect(0, 0, 100, 100);
  gfx::Rect layer_content_rect = gfx::Rect(0, 0, 30, 30);
  gfx::Transform layer_to_surface_transform;

  // Case 1: Layer is contained within the surface.
  layer_to_surface_transform.MakeIdentity();
  layer_to_surface_transform.Translate(50.0, 50.0);
  layer_to_surface_transform.Rotate(45.0);
  gfx::Rect expected_visible_layer_rect = gfx::Rect(30, 30);
  gfx::Rect expected_drawable_content_rect = gfx::Rect(28, 50, 44, 43);
  LayerImpl* drawing_layer = TestVisibleRectAndDrawableContentRect(
      target_surface_rect, layer_to_surface_transform, layer_content_rect);
  EXPECT_EQ(expected_visible_layer_rect, drawing_layer->visible_layer_rect());
  EXPECT_EQ(expected_drawable_content_rect,
            drawing_layer->drawable_content_rect());

  // Case 2: Layer is outside the surface rect.
  layer_to_surface_transform.MakeIdentity();
  layer_to_surface_transform.Translate(-50.0, 0.0);
  layer_to_surface_transform.Rotate(45.0);
  expected_visible_layer_rect = gfx::Rect();
  expected_drawable_content_rect = gfx::Rect();
  drawing_layer = TestVisibleRectAndDrawableContentRect(
      target_surface_rect, layer_to_surface_transform, layer_content_rect);
  EXPECT_EQ(expected_visible_layer_rect, drawing_layer->visible_layer_rect());
  EXPECT_EQ(expected_drawable_content_rect,
            drawing_layer->drawable_content_rect());

  // Case 3: The layer is rotated about its top-left corner. In surface space,
  // the layer is oriented diagonally, with the left half outside of the render
  // surface. In this case, the g should still be the entire layer
  // (remember the g is computed in layer space); both the top-left
  // and bottom-right corners of the layer are still visible.
  layer_to_surface_transform.MakeIdentity();
  layer_to_surface_transform.Rotate(45.0);
  expected_visible_layer_rect = gfx::Rect(30, 30);
  expected_drawable_content_rect = gfx::Rect(22, 43);
  drawing_layer = TestVisibleRectAndDrawableContentRect(
      target_surface_rect, layer_to_surface_transform, layer_content_rect);
  EXPECT_EQ(expected_visible_layer_rect, drawing_layer->visible_layer_rect());
  EXPECT_EQ(expected_drawable_content_rect,
            drawing_layer->drawable_content_rect());

  // Case 4: The layer is rotated about its top-left corner, and translated
  // upwards. In surface space, the layer is oriented diagonally, with only the
  // top corner of the surface overlapping the layer. In layer space, the render
  // surface overlaps the right side of the layer. The g should be
  // the layer's right half.
  layer_to_surface_transform.MakeIdentity();
  layer_to_surface_transform.Translate(0.0, -sqrt(2.0) * 15.0);
  layer_to_surface_transform.Rotate(45.0);
  // Right half of layer bounds.
  expected_visible_layer_rect = gfx::Rect(15, 0, 15, 30);
  expected_drawable_content_rect = gfx::Rect(22, 22);
  drawing_layer = TestVisibleRectAndDrawableContentRect(
      target_surface_rect, layer_to_surface_transform, layer_content_rect);
  EXPECT_EQ(expected_visible_layer_rect, drawing_layer->visible_layer_rect());
  EXPECT_EQ(expected_drawable_content_rect,
            drawing_layer->drawable_content_rect());
}

// Test visible layer rect and drawable content rect are calculated correctly
// for 3d transforms.
TEST_F(DrawPropertiesDrawRectsTest, DrawRectsFor3dOrthographicTransform) {
  gfx::Rect target_surface_rect = gfx::Rect(0, 0, 100, 100);
  gfx::Rect layer_content_rect = gfx::Rect(0, 0, 100, 100);
  gfx::Transform layer_to_surface_transform;

  // Case 1: Orthographic projection of a layer rotated about y-axis by 45
  // degrees, should be fully contained in the render surface.
  // 100 is the un-rotated layer width; divided by sqrt(2) is the rotated width.
  layer_to_surface_transform.MakeIdentity();
  layer_to_surface_transform.RotateAboutYAxis(45.0);
  gfx::Rect expected_visible_layer_rect = gfx::Rect(100, 100);
  gfx::Rect expected_drawable_content_rect = gfx::Rect(71, 100);
  LayerImpl* drawing_layer = TestVisibleRectAndDrawableContentRect(
      target_surface_rect, layer_to_surface_transform, layer_content_rect);
  EXPECT_EQ(expected_visible_layer_rect, drawing_layer->visible_layer_rect());
  EXPECT_EQ(expected_drawable_content_rect,
            drawing_layer->drawable_content_rect());

  // Case 2: Orthographic projection of a layer rotated about y-axis by 45
  // degrees, but shifted to the side so only the right-half the layer would be
  // visible on the surface.
  // 50 is the un-rotated layer width; divided by sqrt(2) is the rotated width.
  SkMScalar half_width_of_rotated_layer =
      SkDoubleToMScalar((100.0 / sqrt(2.0)) * 0.5);
  layer_to_surface_transform.MakeIdentity();
  layer_to_surface_transform.Translate(-half_width_of_rotated_layer, 0.0);
  layer_to_surface_transform.RotateAboutYAxis(45.0);  // Rotates about the left
                                                      // edge of the layer.
  // Tight half of the layer.
  expected_visible_layer_rect = gfx::Rect(50, 0, 50, 100);
  expected_drawable_content_rect = gfx::Rect(36, 100);
  drawing_layer = TestVisibleRectAndDrawableContentRect(
      target_surface_rect, layer_to_surface_transform, layer_content_rect);
  EXPECT_EQ(expected_visible_layer_rect, drawing_layer->visible_layer_rect());
  EXPECT_EQ(expected_drawable_content_rect,
            drawing_layer->drawable_content_rect());
}

// Test visible layer rect and drawable content rect are calculated correctly
// when the layer has a perspective projection onto the target surface.
TEST_F(DrawPropertiesDrawRectsTest, DrawRectsFor3dPerspectiveTransform) {
  gfx::Rect target_surface_rect = gfx::Rect(0, 0, 100, 100);
  gfx::Rect layer_content_rect = gfx::Rect(-50, -50, 200, 200);
  gfx::Transform layer_to_surface_transform;

  // Case 1: Even though the layer is twice as large as the surface, due to
  // perspective foreshortening, the layer will fit fully in the surface when
  // its translated more than the perspective amount.
  layer_to_surface_transform.MakeIdentity();

  // The following sequence of transforms applies the perspective about the
  // center of the surface.
  layer_to_surface_transform.Translate(50.0, 50.0);
  layer_to_surface_transform.ApplyPerspectiveDepth(9.0);
  layer_to_surface_transform.Translate(-50.0, -50.0);

  // This translate places the layer in front of the surface's projection plane.
  layer_to_surface_transform.Translate3d(0.0, 0.0, -27.0);

  // Layer position is (-50, -50), visible rect in layer space is layer bounds
  // offset by layer position.
  gfx::Rect expected_visible_layer_rect = gfx::Rect(50, 50, 150, 150);
  gfx::Rect expected_drawable_content_rect = gfx::Rect(38, 38);
  LayerImpl* drawing_layer = TestVisibleRectAndDrawableContentRect(
      target_surface_rect, layer_to_surface_transform, layer_content_rect);
  EXPECT_EQ(expected_visible_layer_rect, drawing_layer->visible_layer_rect());
  EXPECT_EQ(expected_drawable_content_rect,
            drawing_layer->drawable_content_rect());

  // Case 2: same projection as before, except that the layer is also translated
  // to the side, so that only the right half of the layer should be visible.
  //
  // Explanation of expected result: The perspective ratio is (z distance
  // between layer and camera origin) / (z distance between projection plane and
  // camera origin) == ((-27 - 9) / 9) Then, by similar triangles, if we want to
  // move a layer by translating -25 units in projected surface units (so that
  // only half of it is visible), then we would need to translate by (-36 / 9) *
  // -25 == -100 in the layer's units.
  layer_to_surface_transform.Translate3d(-100.0, 0.0, 0.0);
  // Visible layer rect is moved by 100, and drawable content rect is in target
  // space and is moved by 25.
  expected_visible_layer_rect = gfx::Rect(150, 50, 50, 150);
  expected_drawable_content_rect = gfx::Rect(13, 38);
  drawing_layer = TestVisibleRectAndDrawableContentRect(
      target_surface_rect, layer_to_surface_transform, layer_content_rect);
  EXPECT_EQ(expected_visible_layer_rect, drawing_layer->visible_layer_rect());
  EXPECT_EQ(expected_drawable_content_rect,
            drawing_layer->drawable_content_rect());
}

// There is currently no explicit concept of an orthographic projection plane
// in our code (nor in the CSS spec to my knowledge). Therefore, layers that
// are technically behind the surface in an orthographic world should not be
// clipped when they are flattened to the surface.
TEST_F(DrawPropertiesDrawRectsTest,
       DrawRectsFor3dOrthographicIsNotClippedBehindSurface) {
  gfx::Rect target_surface_rect = gfx::Rect(0, 0, 100, 100);
  gfx::Rect layer_content_rect = gfx::Rect(0, 0, 100, 100);
  gfx::Transform layer_to_surface_transform;

  // This sequence of transforms effectively rotates the layer about the y-axis
  // at the center of the layer.
  layer_to_surface_transform.MakeIdentity();
  layer_to_surface_transform.Translate(50.0, 0.0);
  layer_to_surface_transform.RotateAboutYAxis(45.0);
  layer_to_surface_transform.Translate(-50.0, 0.0);

  // Layer is rotated about Y Axis, and its width is 100/sqrt(2) in surface
  // space.
  gfx::Rect expected_visible_layer_rect = gfx::Rect(100, 100);
  gfx::Rect expected_drawable_content_rect = gfx::Rect(14, 0, 72, 100);
  LayerImpl* drawing_layer = TestVisibleRectAndDrawableContentRect(
      target_surface_rect, layer_to_surface_transform, layer_content_rect);
  EXPECT_EQ(expected_visible_layer_rect, drawing_layer->visible_layer_rect());
  EXPECT_EQ(expected_drawable_content_rect,
            drawing_layer->drawable_content_rect());
}

// Test visible layer rect and drawable content rect are calculated correctly
// when projecting a surface onto a layer, but the layer is partially behind
// the camera (not just behind the projection plane). In this case, the
// cartesian coordinates may seem to be valid, but actually they are not. The
// visible rect needs to be properly clipped by the w = 0 plane in homogeneous
// coordinates before converting to cartesian coordinates. The drawable
// content rect would be entire surface rect because layer is rotated at the
// camera position.
TEST_F(DrawPropertiesDrawRectsTest, DrawRectsFor3dPerspectiveWhenClippedByW) {
  gfx::Rect target_surface_rect = gfx::Rect(0, 0, 200, 200);
  gfx::Rect layer_content_rect = gfx::Rect(0, 0, 20, 2);
  gfx::Transform layer_to_surface_transform;

  // The layer is positioned so that the right half of the layer should be in
  // front of the camera, while the other half is behind the surface's
  // projection plane. The following sequence of transforms applies the
  // perspective and rotation about the center of the layer.
  layer_to_surface_transform.MakeIdentity();
  layer_to_surface_transform.ApplyPerspectiveDepth(1.0);
  layer_to_surface_transform.Translate3d(10.0, 0.0, 1.0);
  layer_to_surface_transform.RotateAboutYAxis(-45.0);
  layer_to_surface_transform.Translate(-10, -1);

  // Sanity check that this transform does indeed cause w < 0 when applying the
  // transform, otherwise this code is not testing the intended scenario.
  bool clipped;
  MathUtil::MapQuad(layer_to_surface_transform,
                    gfx::QuadF(gfx::RectF(layer_content_rect)), &clipped);
  ASSERT_TRUE(clipped);

  gfx::Rect expected_visible_layer_rect = gfx::Rect(0, 1, 10, 1);
  gfx::Rect expected_drawable_content_rect = target_surface_rect;
  LayerImpl* drawing_layer = TestVisibleRectAndDrawableContentRect(
      target_surface_rect, layer_to_surface_transform, layer_content_rect);
  EXPECT_EQ(expected_visible_layer_rect, drawing_layer->visible_layer_rect());
  EXPECT_EQ(expected_drawable_content_rect,
            drawing_layer->drawable_content_rect());
}

static bool ProjectionClips(const gfx::Transform& map_transform,
                            const gfx::RectF& mapped_rect) {
  gfx::Transform inverse(Inverse(map_transform));
  bool clipped = false;
  if (!clipped)
    MathUtil::ProjectPoint(inverse, mapped_rect.top_right(), &clipped);
  if (!clipped)
    MathUtil::ProjectPoint(inverse, mapped_rect.origin(), &clipped);
  if (!clipped)
    MathUtil::ProjectPoint(inverse, mapped_rect.bottom_right(), &clipped);
  if (!clipped)
    MathUtil::ProjectPoint(inverse, mapped_rect.bottom_left(), &clipped);
  return clipped;
}

// To determine visible rect in layer space, there needs to be an
// un-projection from surface space to layer space. When the original
// transform was a perspective projection that was clipped, it returns a rect
// that encloses the clipped bounds.  Un-projecting this new rect may require
// clipping again.
TEST_F(DrawPropertiesDrawRectsTest, DrawRectsForPerspectiveUnprojection) {
  // This sequence of transforms causes one corner of the layer to protrude
  // across the w = 0 plane, and should be clipped.
  gfx::Rect target_surface_rect = gfx::Rect(0, 0, 150, 150);
  gfx::Rect layer_content_rect = gfx::Rect(0, 0, 20, 20);
  gfx::Transform layer_to_surface_transform;
  layer_to_surface_transform.MakeIdentity();
  layer_to_surface_transform.Translate(10, 10);
  layer_to_surface_transform.ApplyPerspectiveDepth(1.0);
  layer_to_surface_transform.Translate3d(0.0, 0.0, -5.0);
  layer_to_surface_transform.RotateAboutYAxis(45.0);
  layer_to_surface_transform.RotateAboutXAxis(80.0);
  layer_to_surface_transform.Translate(-10, -10);

  // Sanity check that un-projection does indeed cause w < 0, otherwise this
  // code is not testing the intended scenario.
  gfx::RectF clipped_rect = MathUtil::MapClippedRect(
      layer_to_surface_transform, gfx::RectF(layer_content_rect));
  ASSERT_TRUE(ProjectionClips(layer_to_surface_transform, clipped_rect));

  // Only the corner of the layer is not visible on the surface because of being
  // clipped. But, the net result of rounding visible region to an axis-aligned
  // rect is that the entire layer should still be considered visible.
  gfx::Rect expected_visible_layer_rect = layer_content_rect;
  gfx::Rect expected_drawable_content_rect = target_surface_rect;
  LayerImpl* drawing_layer = TestVisibleRectAndDrawableContentRect(
      target_surface_rect, layer_to_surface_transform, layer_content_rect);
  EXPECT_EQ(expected_visible_layer_rect, drawing_layer->visible_layer_rect());
  EXPECT_EQ(expected_drawable_content_rect,
            drawing_layer->drawable_content_rect());
}

TEST_F(DrawPropertiesTest, DrawableAndVisibleContentRectsForSimpleLayers) {
  LayerImpl* root = root_layer();
  LayerImpl* child1_layer = AddLayer<LayerImpl>();
  LayerImpl* child2_layer = AddLayer<LayerImpl>();
  LayerImpl* child3_layer = AddLayer<LayerImpl>();

  root->SetBounds(gfx::Size(100, 100));
  child1_layer->SetBounds(gfx::Size(50, 50));
  child1_layer->SetDrawsContent(true);
  child2_layer->SetBounds(gfx::Size(50, 50));
  child2_layer->SetDrawsContent(true);
  child3_layer->SetBounds(gfx::Size(50, 50));
  child3_layer->SetDrawsContent(true);

  CopyProperties(root, child1_layer);
  CopyProperties(root, child2_layer);
  child2_layer->SetOffsetToTransformParent(gfx::Vector2dF(75.f, 75.f));
  CopyProperties(root, child3_layer);
  child3_layer->SetOffsetToTransformParent(gfx::Vector2dF(125.f, 125.f));

  UpdateActiveTreeDrawProperties();

  EXPECT_EQ(gfx::RectF(100.f, 100.f),
            GetRenderSurface(root)->DrawableContentRect());

  // Layers that do not draw content should have empty visible_layer_rects.
  EXPECT_EQ(gfx::Rect(0, 0, 0, 0), root->visible_layer_rect());

  // layer visible_layer_rects are clipped by their target surface.
  EXPECT_EQ(gfx::Rect(0, 0, 50, 50), child1_layer->visible_layer_rect());
  EXPECT_EQ(gfx::Rect(0, 0, 25, 25), child2_layer->visible_layer_rect());
  EXPECT_TRUE(child3_layer->visible_layer_rect().IsEmpty());

  // layer drawable_content_rects are not clipped.
  EXPECT_EQ(gfx::Rect(0, 0, 50, 50), child1_layer->drawable_content_rect());
  EXPECT_EQ(gfx::Rect(75, 75, 50, 50), child2_layer->drawable_content_rect());
  EXPECT_EQ(gfx::Rect(125, 125, 50, 50), child3_layer->drawable_content_rect());
}

TEST_F(DrawPropertiesTest,
       DrawableAndVisibleContentRectsForLayersClippedByLayer) {
  LayerImpl* root = root_layer();
  LayerImpl* child = AddLayer<LayerImpl>();
  LayerImpl* grand_child1 = AddLayer<LayerImpl>();
  LayerImpl* grand_child2 = AddLayer<LayerImpl>();
  LayerImpl* grand_child3 = AddLayer<LayerImpl>();

  root->SetBounds(gfx::Size(100, 100));
  child->SetBounds(gfx::Size(100, 100));
  child->SetMasksToBounds(true);
  grand_child1->SetBounds(gfx::Size(50, 50));
  grand_child1->SetDrawsContent(true);
  grand_child2->SetBounds(gfx::Size(50, 50));
  grand_child2->SetDrawsContent(true);
  grand_child3->SetBounds(gfx::Size(50, 50));
  grand_child3->SetDrawsContent(true);

  CopyProperties(root, child);
  CreateClipNode(child);
  CopyProperties(child, grand_child1);
  grand_child1->SetOffsetToTransformParent(gfx::Vector2dF(5.f, 5.f));
  CopyProperties(child, grand_child2);
  grand_child2->SetOffsetToTransformParent(gfx::Vector2dF(75.f, 75.f));
  CopyProperties(child, grand_child3);
  grand_child3->SetOffsetToTransformParent(gfx::Vector2dF(125.f, 125.f));

  UpdateActiveTreeDrawProperties();

  EXPECT_EQ(gfx::RectF(100.f, 100.f),
            GetRenderSurface(root)->DrawableContentRect());

  // Layers that do not draw content should have empty visible content rects.
  EXPECT_EQ(gfx::Rect(0, 0, 0, 0), root->visible_layer_rect());
  EXPECT_EQ(gfx::Rect(0, 0, 0, 0), child->visible_layer_rect());

  // All grandchild visible content rects should be clipped by child.
  EXPECT_EQ(gfx::Rect(0, 0, 50, 50), grand_child1->visible_layer_rect());
  EXPECT_EQ(gfx::Rect(0, 0, 25, 25), grand_child2->visible_layer_rect());
  EXPECT_TRUE(grand_child3->visible_layer_rect().IsEmpty());

  // All grandchild DrawableContentRects should also be clipped by child.
  EXPECT_EQ(gfx::Rect(5, 5, 50, 50), grand_child1->drawable_content_rect());
  EXPECT_EQ(gfx::Rect(75, 75, 25, 25), grand_child2->drawable_content_rect());
  EXPECT_TRUE(grand_child3->drawable_content_rect().IsEmpty());
}

TEST_F(DrawPropertiesTest, VisibleContentRectWithClippingAndScaling) {
  LayerImpl* root = root_layer();
  LayerImpl* child = AddLayer<LayerImpl>();
  LayerImpl* grand_child = AddLayer<LayerImpl>();

  gfx::Transform child_scale_matrix;
  child_scale_matrix.Scale(0.25f, 0.25f);
  gfx::Transform grand_child_scale_matrix;
  grand_child_scale_matrix.Scale(0.246f, 0.246f);

  root->SetBounds(gfx::Size(100, 100));
  child->SetBounds(gfx::Size(10, 10));
  child->SetMasksToBounds(true);
  grand_child->SetBounds(gfx::Size(100, 100));
  grand_child->SetDrawsContent(true);

  CopyProperties(root, child);
  CreateTransformNode(child).local = child_scale_matrix;
  CreateClipNode(child);
  CopyProperties(child, grand_child);
  CreateTransformNode(grand_child).local = grand_child_scale_matrix;

  UpdateActiveTreeDrawProperties();

  // The visible rect is expanded to integer coordinates.
  EXPECT_EQ(gfx::Rect(41, 41), grand_child->visible_layer_rect());
}

TEST_F(DrawPropertiesTest, ClipRectWithClipParent) {
  LayerImpl* root = root_layer();
  LayerImpl* clip = AddLayer<LayerImpl>();
  LayerImpl* child1 = AddLayer<LayerImpl>();
  LayerImpl* child2 = AddLayer<LayerImpl>();

  root->SetBounds(gfx::Size(100, 100));
  CreateClipNode(root);

  clip->SetBounds(gfx::Size(10, 10));
  CopyProperties(root, clip);
  CreateClipNode(clip);

  child1->SetBounds(gfx::Size(20, 20));
  child1->SetDrawsContent(true);
  CopyProperties(clip, child1);
  child1->SetClipTreeIndex(root->clip_tree_index());

  child2->SetBounds(gfx::Size(20, 20));
  child2->SetDrawsContent(true);
  CopyProperties(clip, child2);

  UpdateActiveTreeDrawProperties();

  EXPECT_TRUE(child1->is_clipped());
  EXPECT_TRUE(child2->is_clipped());
  EXPECT_EQ(gfx::Rect(100, 100), child1->clip_rect());
  EXPECT_EQ(gfx::Rect(10, 10), child2->clip_rect());
}

TEST_F(DrawPropertiesTest, ClipRectWithClippedDescendantOfFilter) {
  LayerImpl* root = root_layer();
  LayerImpl* filter = AddLayer<LayerImpl>();
  LayerImpl* clip = AddLayer<LayerImpl>();
  LayerImpl* filter_grand_child = AddLayer<LayerImpl>();

  root->SetBounds(gfx::Size(100, 100));
  clip->SetBounds(gfx::Size(10, 10));
  clip->SetMasksToBounds(true);
  filter_grand_child->SetBounds(gfx::Size(20, 20));
  filter_grand_child->SetDrawsContent(true);

  CopyProperties(root, filter);
  CreateEffectNode(filter).render_surface_reason = RenderSurfaceReason::kTest;
  CopyProperties(filter, clip);
  CreateClipNode(clip);
  CopyProperties(clip, filter_grand_child);

  UpdateActiveTreeDrawProperties();
  EXPECT_TRUE(filter_grand_child->is_clipped());
  EXPECT_EQ(gfx::Rect(10, 10), filter_grand_child->clip_rect());

  FilterOperations blur_filter;
  blur_filter.Append(FilterOperation::CreateBlurFilter(4.0f));
  SetFilter(filter, blur_filter);

  UpdateActiveTreeDrawProperties();

  EXPECT_TRUE(filter_grand_child->is_clipped());
  EXPECT_EQ(gfx::Rect(10, 10), filter_grand_child->clip_rect());
}

TEST_F(DrawPropertiesTest,
       DrawableAndVisibleContentRectsForLayersInUnclippedRenderSurface) {
  LayerImpl* root = root_layer();
  LayerImpl* render_surface = AddLayer<LayerImpl>();
  LayerImpl* child1 = AddLayer<LayerImpl>();
  LayerImpl* child2 = AddLayer<LayerImpl>();
  LayerImpl* child3 = AddLayer<LayerImpl>();

  root->SetBounds(gfx::Size(100, 100));
  render_surface->SetBounds(gfx::Size(3, 4));
  child1->SetBounds(gfx::Size(50, 50));
  child1->SetDrawsContent(true);
  child2->SetBounds(gfx::Size(50, 50));
  child2->SetDrawsContent(true);
  child3->SetBounds(gfx::Size(50, 50));
  child3->SetDrawsContent(true);

  CopyProperties(root, render_surface);
  CreateEffectNode(render_surface).render_surface_reason =
      RenderSurfaceReason::kTest;
  CopyProperties(render_surface, child1);
  child1->SetOffsetToTransformParent(gfx::Vector2dF(5.f, 5.f));
  CopyProperties(render_surface, child2);
  child2->SetOffsetToTransformParent(gfx::Vector2dF(75.f, 75.f));
  CopyProperties(render_surface, child3);
  child3->SetOffsetToTransformParent(gfx::Vector2dF(125.f, 125.f));

  UpdateActiveTreeDrawProperties();

  ASSERT_TRUE(GetRenderSurface(render_surface));

  EXPECT_EQ(gfx::RectF(100.f, 100.f),
            GetRenderSurface(root)->DrawableContentRect());

  // Layers that do not draw content should have empty visible content rects.
  EXPECT_EQ(gfx::Rect(0, 0, 0, 0), root->visible_layer_rect());
  EXPECT_EQ(gfx::Rect(0, 0, 0, 0), render_surface->visible_layer_rect());

  // An unclipped surface grows its DrawableContentRect to include all drawable
  // regions of the subtree.
  EXPECT_EQ(gfx::RectF(5.f, 5.f, 170.f, 170.f),
            GetRenderSurface(render_surface)->DrawableContentRect());

  // All layers that draw content into the unclipped surface are also unclipped.
  // Only the viewport clip should apply
  EXPECT_EQ(gfx::Rect(0, 0, 50, 50), child1->visible_layer_rect());
  EXPECT_EQ(gfx::Rect(0, 0, 25, 25), child2->visible_layer_rect());
  EXPECT_EQ(gfx::Rect(0, 0, 0, 0), child3->visible_layer_rect());

  EXPECT_EQ(gfx::Rect(5, 5, 50, 50), child1->drawable_content_rect());
  EXPECT_EQ(gfx::Rect(75, 75, 50, 50), child2->drawable_content_rect());
  EXPECT_EQ(gfx::Rect(125, 125, 50, 50), child3->drawable_content_rect());
}

TEST_F(DrawPropertiesTest, VisibleContentRectsForClippedSurfaceWithEmptyClip) {
  LayerImpl* root = root_layer();
  LayerImpl* child1 = AddLayer<LayerImpl>();
  LayerImpl* child2 = AddLayer<LayerImpl>();
  LayerImpl* child3 = AddLayer<LayerImpl>();

  root->SetBounds(gfx::Size(100, 100));
  child1->SetBounds(gfx::Size(50, 50));
  child1->SetDrawsContent(true);
  child2->SetBounds(gfx::Size(50, 50));
  child2->SetDrawsContent(true);
  child3->SetBounds(gfx::Size(50, 50));
  child3->SetDrawsContent(true);

  CopyProperties(root, child1);
  child1->SetOffsetToTransformParent(gfx::Vector2dF(5.f, 5.f));
  CopyProperties(root, child2);
  child2->SetOffsetToTransformParent(gfx::Vector2dF(75.f, 75.f));
  CopyProperties(root, child3);
  child3->SetOffsetToTransformParent(gfx::Vector2dF(125.f, 125.f));

  // Now set the root render surface an empty clip.
  // Not using UpdateActiveTreeDrawProperties() because we want a special
  // device viewport rect.
  host_impl()->active_tree()->SetDeviceViewportRect(gfx::Rect());
  UpdateDrawProperties(host_impl()->active_tree());

  ASSERT_TRUE(GetRenderSurface(root));
  EXPECT_FALSE(root->is_clipped());

  gfx::Rect empty;
  EXPECT_EQ(empty, GetRenderSurface(root)->clip_rect());
  EXPECT_TRUE(GetRenderSurface(root)->is_clipped());

  // Visible content rect calculation will check if the target surface is
  // clipped or not. An empty clip rect does not indicate the render surface
  // is unclipped.
  EXPECT_EQ(empty, child1->visible_layer_rect());
  EXPECT_EQ(empty, child2->visible_layer_rect());
  EXPECT_EQ(empty, child3->visible_layer_rect());
}

TEST_F(DrawPropertiesTest,
       DrawableAndVisibleContentRectsForLayersWithUninvertibleTransform) {
  LayerImpl* root = root_layer();
  LayerImpl* child = AddLayer<LayerImpl>();

  root->SetBounds(gfx::Size(100, 100));
  child->SetBounds(gfx::Size(50, 50));
  child->SetDrawsContent(true);

  // Case 1: a truly degenerate matrix
  gfx::Transform uninvertible_matrix(0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
  ASSERT_FALSE(uninvertible_matrix.IsInvertible());

  CopyProperties(root, child);
  CreateTransformNode(child).local = uninvertible_matrix;

  UpdateActiveTreeDrawProperties();

  EXPECT_TRUE(child->visible_layer_rect().IsEmpty());
  EXPECT_TRUE(child->drawable_content_rect().IsEmpty());

  // Case 2: a matrix with flattened z, uninvertible and not visible according
  // to the CSS spec.
  uninvertible_matrix.MakeIdentity();
  uninvertible_matrix.matrix().set(2, 2, 0.0);
  ASSERT_FALSE(uninvertible_matrix.IsInvertible());

  SetTransform(child, uninvertible_matrix);
  UpdateActiveTreeDrawProperties();

  EXPECT_TRUE(child->visible_layer_rect().IsEmpty());
  EXPECT_TRUE(child->drawable_content_rect().IsEmpty());

  // Case 3: a matrix with flattened z, also uninvertible and not visible.
  uninvertible_matrix.MakeIdentity();
  uninvertible_matrix.Translate(500.0, 0.0);
  uninvertible_matrix.matrix().set(2, 2, 0.0);
  ASSERT_FALSE(uninvertible_matrix.IsInvertible());

  SetTransform(child, uninvertible_matrix);
  UpdateActiveTreeDrawProperties();

  EXPECT_TRUE(child->visible_layer_rect().IsEmpty());
  EXPECT_TRUE(child->drawable_content_rect().IsEmpty());
}

TEST_F(DrawPropertiesTest,
       VisibleContentRectForLayerWithUninvertibleDrawTransform) {
  LayerImpl* root = root_layer();
  LayerImpl* child = AddLayer<LayerImpl>();
  LayerImpl* grand_child = AddLayer<LayerImpl>();

  gfx::Transform perspective;
  perspective.ApplyPerspectiveDepth(SkDoubleToMScalar(1e-12));

  gfx::Transform rotation;
  rotation.RotateAboutYAxis(45.0);

  root->SetBounds(gfx::Size(100, 100));
  child->SetBounds(gfx::Size(100, 100));
  child->SetDrawsContent(true);
  grand_child->SetBounds(gfx::Size(100, 100));
  grand_child->SetDrawsContent(true);

  CopyProperties(root, child);
  auto& child_transform_node = CreateTransformNode(child);
  child_transform_node.flattens_inherited_transform = false;
  child_transform_node.post_translation = gfx::Vector2dF(10.f, 10.f);
  child_transform_node.sorting_context_id = 1;
  child_transform_node.local = perspective;
  CopyProperties(child, grand_child);
  auto& grand_child_transform_node = CreateTransformNode(grand_child);
  grand_child_transform_node.flattens_inherited_transform = false;
  grand_child_transform_node.sorting_context_id = 1;
  grand_child_transform_node.local = rotation;

  UpdateActiveTreeDrawProperties();

  // Though all layers have invertible transforms, matrix multiplication using
  // floating-point math makes the draw transform uninvertible.
  EXPECT_FALSE(GetTransformNode(grand_child)->ancestors_are_invertible);

  // CalcDrawProps skips a subtree when a layer's screen space transform is
  // uninvertible
  EXPECT_EQ(gfx::Rect(), grand_child->visible_layer_rect());
}

// Needs layer tree mode: mask layer.
TEST_F(DrawPropertiesTestWithLayerTree, OcclusionBySiblingOfTarget) {
  auto root = Layer::Create();
  auto child = Layer::Create();
  FakeContentLayerClient client;
  auto surface = PictureLayer::Create(&client);
  auto surface_child = PictureLayer::Create(&client);
  auto surface_sibling = PictureLayer::Create(&client);
  auto surface_child_mask = PictureLayer::Create(&client);

  surface->SetIsDrawable(true);
  surface_child->SetIsDrawable(true);
  surface_sibling->SetIsDrawable(true);
  surface_child_mask->SetIsDrawable(true);
  surface->SetContentsOpaque(true);
  surface_child->SetContentsOpaque(true);
  surface_sibling->SetContentsOpaque(true);
  surface_child_mask->SetContentsOpaque(true);

  gfx::Transform translate;
  translate.Translate(20.f, 20.f);

  root->SetBounds(gfx::Size(1000, 1000));
  child->SetBounds(gfx::Size(300, 300));
  surface->SetTransform(translate);
  surface->SetBounds(gfx::Size(300, 300));
  surface->SetForceRenderSurfaceForTesting(true);
  surface_child->SetBounds(gfx::Size(300, 300));
  surface_child->SetForceRenderSurfaceForTesting(true);
  surface_sibling->SetBounds(gfx::Size(200, 200));
  surface_child_mask->SetBounds(gfx::Size(300, 300));

  surface_child->SetMaskLayer(surface_child_mask);
  surface->AddChild(surface_child);
  child->AddChild(surface);
  child->AddChild(surface_sibling);
  root->AddChild(child);
  host()->SetRootLayer(root);

  CommitAndActivate();

  EXPECT_TRANSFORMATION_MATRIX_EQ(
      GetRenderSurfaceImpl(surface)->draw_transform(), translate);
  // surface_sibling draws into the root render surface and occludes
  // surface_child's contents.
  Occlusion actual_occlusion =
      GetRenderSurfaceImpl(surface_child)->occlusion_in_content_space();
  Occlusion expected_occlusion(translate, SimpleEnclosedRegion(),
                               SimpleEnclosedRegion(gfx::Rect(200, 200)));
  EXPECT_TRUE(expected_occlusion.IsEqual(actual_occlusion));

  // Mask layer's occlusion is different because we create transform and render
  // surface for it in layer tree mode.
  actual_occlusion =
      ImplOf(surface_child_mask)->draw_properties().occlusion_in_content_space;
  expected_occlusion = Occlusion(
      gfx::Transform(), SimpleEnclosedRegion(gfx::Rect(-20, -20, 200, 200)),
      SimpleEnclosedRegion());
  EXPECT_TRUE(expected_occlusion.IsEqual(actual_occlusion));
}

TEST_F(DrawPropertiesTest, OcclusionForLayerWithUninvertibleDrawTransform) {
  LayerImpl* root = root_layer();
  LayerImpl* child = AddLayer<LayerImpl>();
  LayerImpl* grand_child = AddLayer<LayerImpl>();
  LayerImpl* occluding_child = AddLayer<LayerImpl>();

  gfx::Transform perspective;
  perspective.ApplyPerspectiveDepth(SkDoubleToMScalar(1e-12));

  gfx::Transform rotation;
  rotation.RotateAboutYAxis(45.0);

  root->SetBounds(gfx::Size(1000, 1000));
  child->SetBounds(gfx::Size(300, 300));
  grand_child->SetBounds(gfx::Size(200, 200));
  occluding_child->SetBounds(gfx::Size(200, 200));

  child->SetDrawsContent(true);
  grand_child->SetDrawsContent(true);
  occluding_child->SetDrawsContent(true);
  occluding_child->SetContentsOpaque(true);

  CopyProperties(root, child);
  auto& child_transform_node = CreateTransformNode(child);
  child_transform_node.flattens_inherited_transform = false;
  child_transform_node.post_translation = gfx::Vector2dF(10.f, 10.f);
  child_transform_node.sorting_context_id = 1;
  child_transform_node.local = perspective;
  CopyProperties(child, grand_child);
  auto& grand_child_transform_node = CreateTransformNode(grand_child);
  grand_child_transform_node.flattens_inherited_transform = false;
  grand_child_transform_node.sorting_context_id = 1;
  grand_child_transform_node.local = rotation;
  CopyProperties(root, occluding_child);
  CreateTransformNode(occluding_child).flattens_inherited_transform = false;

  UpdateActiveTreeDrawProperties();

  // Though all layers have invertible transforms, matrix multiplication using
  // floating-point math makes the draw transform uninvertible.
  EXPECT_FALSE(GetTransformNode(grand_child)->ancestors_are_invertible);

  // Since |grand_child| has an uninvertible screen space transform, it is
  // skipped so
  // that we are not computing its occlusion_in_content_space.
  gfx::Rect layer_bounds = gfx::Rect();
  EXPECT_EQ(
      layer_bounds,
      grand_child->draw_properties()
          .occlusion_in_content_space.GetUnoccludedContentRect(layer_bounds));
}

TEST_F(DrawPropertiesTest,
       DrawableAndVisibleContentRectsForLayersInClippedRenderSurface) {
  LayerImpl* root = root_layer();
  LayerImpl* render_surface = AddLayer<LayerImpl>();
  LayerImpl* child1 = AddLayer<LayerImpl>();
  LayerImpl* child2 = AddLayer<LayerImpl>();
  LayerImpl* child3 = AddLayer<LayerImpl>();

  root->SetBounds(gfx::Size(100, 100));
  root->SetMasksToBounds(true);
  render_surface->SetBounds(gfx::Size(3, 4));
  child1->SetBounds(gfx::Size(50, 50));
  child1->SetDrawsContent(true);
  child2->SetBounds(gfx::Size(50, 50));
  child2->SetDrawsContent(true);
  child3->SetBounds(gfx::Size(50, 50));
  child3->SetDrawsContent(true);

  CreateClipNode(root);
  CopyProperties(root, render_surface);
  CreateEffectNode(render_surface).render_surface_reason =
      RenderSurfaceReason::kTest;
  CopyProperties(render_surface, child1);
  child1->SetOffsetToTransformParent(gfx::Vector2dF(5.f, 5.f));
  CopyProperties(render_surface, child2);
  child2->SetOffsetToTransformParent(gfx::Vector2dF(75.f, 75.f));
  CopyProperties(render_surface, child3);
  child3->SetOffsetToTransformParent(gfx::Vector2dF(125.f, 125.f));

  UpdateActiveTreeDrawProperties();

  ASSERT_TRUE(GetRenderSurface(render_surface));

  EXPECT_EQ(gfx::RectF(100.f, 100.f),
            GetRenderSurface(root)->DrawableContentRect());

  // Layers that do not draw content should have empty visible content rects.
  EXPECT_EQ(gfx::Rect(0, 0, 0, 0), root->visible_layer_rect());
  EXPECT_EQ(gfx::Rect(0, 0, 0, 0), render_surface->visible_layer_rect());

  // A clipped surface grows its DrawableContentRect to include all drawable
  // regions of the subtree, but also gets clamped by the ancestor's clip.
  EXPECT_EQ(gfx::RectF(5.f, 5.f, 95.f, 95.f),
            GetRenderSurface(render_surface)->DrawableContentRect());

  // All layers that draw content into the surface have their visible content
  // rect clipped by the surface clip rect.
  EXPECT_EQ(gfx::Rect(0, 0, 50, 50), child1->visible_layer_rect());
  EXPECT_EQ(gfx::Rect(0, 0, 25, 25), child2->visible_layer_rect());
  EXPECT_TRUE(child3->visible_layer_rect().IsEmpty());

  // But the DrawableContentRects are unclipped.
  EXPECT_EQ(gfx::Rect(5, 5, 50, 50), child1->drawable_content_rect());
  EXPECT_EQ(gfx::Rect(75, 75, 50, 50), child2->drawable_content_rect());
  EXPECT_EQ(gfx::Rect(125, 125, 50, 50), child3->drawable_content_rect());
}

// Check that clipping does not propagate down surfaces.
TEST_F(DrawPropertiesTest, DrawableAndVisibleContentRectsForSurfaceHierarchy) {
  LayerImpl* root = root_layer();
  LayerImpl* render_surface1 = AddLayer<LayerImpl>();
  LayerImpl* render_surface2 = AddLayer<LayerImpl>();
  LayerImpl* child1 = AddLayer<LayerImpl>();
  LayerImpl* child2 = AddLayer<LayerImpl>();
  LayerImpl* child3 = AddLayer<LayerImpl>();

  root->SetBounds(gfx::Size(100, 100));
  root->SetMasksToBounds(true);
  render_surface1->SetBounds(gfx::Size(3, 4));
  render_surface2->SetBounds(gfx::Size(7, 13));
  child1->SetBounds(gfx::Size(50, 50));
  child1->SetDrawsContent(true);
  child2->SetBounds(gfx::Size(50, 50));
  child2->SetDrawsContent(true);
  child3->SetBounds(gfx::Size(50, 50));
  child3->SetDrawsContent(true);

  CreateClipNode(root);
  CopyProperties(root, render_surface1);
  CreateEffectNode(render_surface1).render_surface_reason =
      RenderSurfaceReason::kTest;
  CopyProperties(render_surface1, render_surface2);
  CreateEffectNode(render_surface2).render_surface_reason =
      RenderSurfaceReason::kTest;
  CopyProperties(render_surface2, child1);
  child1->SetOffsetToTransformParent(gfx::Vector2dF(5.f, 5.f));
  CopyProperties(render_surface2, child2);
  child2->SetOffsetToTransformParent(gfx::Vector2dF(75.f, 75.f));
  CopyProperties(render_surface2, child3);
  child3->SetOffsetToTransformParent(gfx::Vector2dF(125.f, 125.f));

  UpdateActiveTreeDrawProperties();

  ASSERT_TRUE(GetRenderSurface(render_surface1));
  ASSERT_TRUE(GetRenderSurface(render_surface2));

  EXPECT_EQ(gfx::RectF(100.f, 100.f),
            GetRenderSurface(root)->DrawableContentRect());

  // Layers that do not draw content should have empty visible content rects.
  EXPECT_EQ(gfx::Rect(0, 0, 0, 0), root->visible_layer_rect());
  EXPECT_EQ(gfx::Rect(0, 0, 0, 0), render_surface1->visible_layer_rect());
  EXPECT_EQ(gfx::Rect(0, 0, 0, 0), render_surface2->visible_layer_rect());

  // A clipped surface grows its DrawableContentRect to include all drawable
  // regions of the subtree, but also gets clamped by the ancestor's clip.
  EXPECT_EQ(gfx::RectF(5.f, 5.f, 95.f, 95.f),
            GetRenderSurface(render_surface1)->DrawableContentRect());

  // render_surface1 lives in the "unclipped universe" of render_surface1, and
  // is only implicitly clipped by render_surface1's content rect. So,
  // render_surface2 grows to enclose all drawable content of its subtree.
  EXPECT_EQ(gfx::RectF(5.f, 5.f, 170.f, 170.f),
            GetRenderSurface(render_surface2)->DrawableContentRect());

  // All layers that draw content into render_surface2 think they are unclipped
  // by the surface. So, only the viewport clip applies.
  EXPECT_EQ(gfx::Rect(0, 0, 50, 50), child1->visible_layer_rect());
  EXPECT_EQ(gfx::Rect(0, 0, 25, 25), child2->visible_layer_rect());
  EXPECT_EQ(gfx::Rect(0, 0, 0, 0), child3->visible_layer_rect());

  // DrawableContentRects are also unclipped.
  EXPECT_EQ(gfx::Rect(5, 5, 50, 50), child1->drawable_content_rect());
  EXPECT_EQ(gfx::Rect(75, 75, 50, 50), child2->drawable_content_rect());
  EXPECT_EQ(gfx::Rect(125, 125, 50, 50), child3->drawable_content_rect());
}

TEST_F(DrawPropertiesTest,
       VisibleRectsForClippedDescendantsOfUnclippedSurfaces) {
  LayerImpl* root = root_layer();
  LayerImpl* render_surface1 = AddLayer<LayerImpl>();
  LayerImpl* child1 = AddLayer<LayerImpl>();
  LayerImpl* child2 = AddLayer<LayerImpl>();
  LayerImpl* render_surface2 = AddLayer<LayerImpl>();

  root->SetBounds(gfx::Size(100, 100));
  render_surface1->SetBounds(gfx::Size(100, 100));
  child1->SetBounds(gfx::Size(500, 500));
  child1->SetDrawsContent(true);
  child2->SetBounds(gfx::Size(700, 700));
  child2->SetDrawsContent(true);
  render_surface2->SetBounds(gfx::Size(1000, 1000));
  render_surface2->SetDrawsContent(true);

  child1->SetMasksToBounds(true);
  child2->SetMasksToBounds(true);

  CopyProperties(root, render_surface1);
  CreateEffectNode(render_surface1).render_surface_reason =
      RenderSurfaceReason::kTest;
  CopyProperties(render_surface1, child1);
  CreateClipNode(child1);
  CopyProperties(child1, child2);
  CreateClipNode(child2);
  CopyProperties(child2, render_surface2);
  CreateEffectNode(render_surface2).render_surface_reason =
      RenderSurfaceReason::kTest;

  UpdateActiveTreeDrawProperties();
  EXPECT_EQ(gfx::Rect(100, 100), child1->visible_layer_rect());
  EXPECT_EQ(gfx::Rect(100, 100), render_surface2->visible_layer_rect());
}

TEST_F(DrawPropertiesTest,
       VisibleRectsWhenClipChildIsBetweenTwoRenderSurfaces) {
  LayerImpl* root = root_layer();
  LayerImpl* clip_parent = AddLayer<LayerImpl>();
  LayerImpl* render_surface1 = AddLayer<LayerImpl>();
  LayerImpl* clip_child = AddLayer<LayerImpl>();
  LayerImpl* render_surface2 = AddLayer<LayerImpl>();

  root->SetBounds(gfx::Size(100, 100));

  clip_parent->SetBounds(gfx::Size(50, 50));
  CopyProperties(root, clip_parent);
  CreateClipNode(clip_parent);

  render_surface1->SetBounds(gfx::Size(20, 20));
  render_surface1->SetDrawsContent(true);
  CopyProperties(clip_parent, render_surface1);
  CreateEffectNode(render_surface1).render_surface_reason =
      RenderSurfaceReason::kTest;
  CreateClipNode(render_surface1);

  clip_child->SetBounds(gfx::Size(60, 60));
  clip_child->SetDrawsContent(true);
  CopyProperties(render_surface1, clip_child);
  clip_child->SetClipTreeIndex(clip_parent->clip_tree_index());

  render_surface2->SetBounds(gfx::Size(60, 60));
  render_surface2->SetDrawsContent(true);
  CopyProperties(clip_child, render_surface2);
  CreateEffectNode(render_surface2).render_surface_reason =
      RenderSurfaceReason::kTest;

  UpdateActiveTreeDrawProperties();
  EXPECT_EQ(gfx::Rect(20, 20), render_surface1->visible_layer_rect());
  EXPECT_EQ(gfx::Rect(50, 50), clip_child->visible_layer_rect());
  EXPECT_EQ(gfx::Rect(50, 50), render_surface2->visible_layer_rect());
}

TEST_F(DrawPropertiesTest, ClipRectOfSurfaceWhoseParentIsAClipChild) {
  LayerImpl* root = root_layer();
  LayerImpl* clip_parent = AddLayer<LayerImpl>();
  LayerImpl* clip_layer = AddLayer<LayerImpl>();
  LayerImpl* render_surface1 = AddLayer<LayerImpl>();
  LayerImpl* clip_child = AddLayer<LayerImpl>();
  LayerImpl* render_surface2 = AddLayer<LayerImpl>();

  root->SetBounds(gfx::Size(100, 100));

  clip_parent->SetBounds(gfx::Size(50, 50));
  clip_parent->SetOffsetToTransformParent(gfx::Vector2dF(2, 2));
  CopyProperties(root, clip_parent);
  CreateClipNode(clip_parent);

  clip_layer->SetBounds(gfx::Size(50, 50));
  clip_layer->SetOffsetToTransformParent(gfx::Vector2dF(2, 2));
  CopyProperties(clip_parent, clip_layer);
  CreateClipNode(clip_layer);

  render_surface1->SetBounds(gfx::Size(20, 20));
  render_surface1->SetDrawsContent(true);
  CopyProperties(clip_layer, render_surface1);
  CreateTransformNode(render_surface1).post_translation = gfx::Vector2dF(2, 2);
  CreateEffectNode(render_surface1).render_surface_reason =
      RenderSurfaceReason::kTest;
  CreateClipNode(render_surface1);

  clip_child->SetBounds(gfx::Size(60, 60));
  clip_child->SetDrawsContent(true);
  CopyProperties(render_surface1, clip_child);
  clip_child->SetClipTreeIndex(clip_parent->clip_tree_index());

  render_surface2->SetBounds(gfx::Size(60, 60));
  render_surface2->SetDrawsContent(true);
  CopyProperties(clip_child, render_surface2);
  CreateTransformNode(render_surface2);
  CreateEffectNode(render_surface2).render_surface_reason =
      RenderSurfaceReason::kTest;

  float device_scale_factor = 1.f;
  UpdateActiveTreeDrawProperties(device_scale_factor);
  EXPECT_EQ(gfx::Rect(50, 50), GetRenderSurface(render_surface2)->clip_rect());

  device_scale_factor = 2.f;
  UpdateActiveTreeDrawProperties(device_scale_factor);

  EXPECT_EQ(gfx::Rect(100, 100),
            GetRenderSurface(render_surface2)->clip_rect());
}

// Test that only drawn layers contribute to render surface content rect.
TEST_F(DrawPropertiesTest, RenderSurfaceContentRectWhenLayerNotDrawn) {
  LayerImpl* root = root_layer();
  LayerImpl* surface = AddLayer<LayerImpl>();
  LayerImpl* test_layer = AddLayer<LayerImpl>();

  root->SetBounds(gfx::Size(200, 200));
  surface->SetBounds(gfx::Size(100, 100));
  surface->SetDrawsContent(true);
  test_layer->SetBounds(gfx::Size(150, 150));

  CopyProperties(root, surface);
  CreateEffectNode(surface).render_surface_reason = RenderSurfaceReason::kTest;
  CopyProperties(surface, test_layer);

  UpdateActiveTreeDrawProperties();
  EXPECT_EQ(gfx::Rect(100, 100), GetRenderSurface(surface)->content_rect());

  test_layer->SetDrawsContent(true);
  UpdateActiveTreeDrawProperties();
  EXPECT_EQ(gfx::Rect(150, 150), GetRenderSurface(surface)->content_rect());
}

// Tests visible rects computation when we have unclipped_surface->
// surface_with_unclipped_descendants->clipped_surface, checks that the bounds
// of surface_with_unclipped_descendants doesn't propagate to the
// clipped_surface below it.
TEST_F(DrawPropertiesTest, VisibleRectsMultipleSurfaces) {
  LayerImpl* root = root_layer();
  LayerImpl* unclipped_surface = AddLayer<LayerImpl>();
  LayerImpl* clip_parent = AddLayer<LayerImpl>();
  LayerImpl* unclipped_desc_surface = AddLayer<LayerImpl>();
  LayerImpl* clip_child = AddLayer<LayerImpl>();
  LayerImpl* clipped_surface = AddLayer<LayerImpl>();

  root->SetBounds(gfx::Size(100, 100));
  unclipped_surface->SetBounds(gfx::Size(30, 30));
  unclipped_surface->SetDrawsContent(true);
  clip_parent->SetBounds(gfx::Size(50, 50));
  unclipped_desc_surface->SetBounds(gfx::Size(20, 20));
  unclipped_desc_surface->SetDrawsContent(true);
  clip_child->SetBounds(gfx::Size(60, 60));
  clip_child->SetClipTreeIndex(clip_parent->clip_tree_index());
  clipped_surface->SetBounds(gfx::Size(60, 60));
  clipped_surface->SetDrawsContent(true);

  CopyProperties(root, unclipped_surface);
  CreateEffectNode(unclipped_surface).render_surface_reason =
      RenderSurfaceReason::kTest;
  CopyProperties(unclipped_surface, clip_parent);
  CreateClipNode(clip_parent);
  CopyProperties(clip_parent, unclipped_desc_surface);
  CreateEffectNode(unclipped_desc_surface).render_surface_reason =
      RenderSurfaceReason::kTest;
  CopyProperties(unclipped_desc_surface, clip_child);
  CopyProperties(clip_child, clipped_surface);
  CreateEffectNode(clipped_surface).render_surface_reason =
      RenderSurfaceReason::kTest;

  UpdateActiveTreeDrawProperties();
  EXPECT_EQ(gfx::Rect(30, 30), unclipped_surface->visible_layer_rect());
  EXPECT_EQ(gfx::Rect(20, 20), unclipped_desc_surface->visible_layer_rect());
  EXPECT_EQ(gfx::Rect(50, 50), clipped_surface->visible_layer_rect());
}

// Tests visible rects computation when we have unclipped_surface->
// surface_with_unclipped_descendants->clipped_surface, checks that the bounds
// of root propagate to the clipped_surface.
TEST_F(DrawPropertiesTest, RootClipPropagationToClippedSurface) {
  LayerImpl* root = root_layer();
  LayerImpl* unclipped_surface = AddLayer<LayerImpl>();
  LayerImpl* clip_parent = AddLayer<LayerImpl>();
  LayerImpl* unclipped_desc_surface = AddLayer<LayerImpl>();
  LayerImpl* clip_child = AddLayer<LayerImpl>();
  LayerImpl* clipped_surface = AddLayer<LayerImpl>();

  root->SetBounds(gfx::Size(10, 10));
  unclipped_surface->SetBounds(gfx::Size(50, 50));
  unclipped_surface->SetDrawsContent(true);
  clip_parent->SetBounds(gfx::Size(50, 50));
  unclipped_desc_surface->SetBounds(gfx::Size(100, 100));
  unclipped_desc_surface->SetDrawsContent(true);
  clip_child->SetBounds(gfx::Size(100, 100));
  clipped_surface->SetBounds(gfx::Size(50, 50));
  clipped_surface->SetDrawsContent(true);

  CopyProperties(root, unclipped_surface);
  CreateEffectNode(unclipped_surface).render_surface_reason =
      RenderSurfaceReason::kTest;
  CopyProperties(unclipped_surface, clip_parent);
  CreateClipNode(clip_parent);
  CopyProperties(clip_parent, unclipped_desc_surface);
  CreateEffectNode(unclipped_desc_surface).render_surface_reason =
      RenderSurfaceReason::kTest;
  CreateClipNode(unclipped_desc_surface);
  CopyProperties(unclipped_desc_surface, clip_child);
  clip_child->SetClipTreeIndex(clip_parent->clip_tree_index());
  CopyProperties(clip_child, clipped_surface);
  CreateEffectNode(clipped_surface).render_surface_reason =
      RenderSurfaceReason::kTest;

  UpdateActiveTreeDrawProperties();
  EXPECT_EQ(gfx::Rect(10, 10), unclipped_surface->visible_layer_rect());
  EXPECT_EQ(gfx::Rect(10, 10), unclipped_desc_surface->visible_layer_rect());
  EXPECT_EQ(gfx::Rect(10, 10), clipped_surface->visible_layer_rect());
}

// Layers that have non-axis aligned bounds (due to transforms) have an
// expanded, axis-aligned DrawableContentRect and visible content rect.
TEST_F(DrawPropertiesTest,
       DrawableAndVisibleContentRectsWithTransformOnUnclippedSurface) {
  LayerImpl* root = root_layer();
  LayerImpl* render_surface = AddLayer<LayerImpl>();
  LayerImpl* child1 = AddLayer<LayerImpl>();

  gfx::Transform child_rotation;
  child_rotation.Rotate(45.0);

  root->SetBounds(gfx::Size(100, 100));
  render_surface->SetBounds(gfx::Size(3, 4));
  child1->SetBounds(gfx::Size(50, 50));
  child1->SetDrawsContent(true);

  CopyProperties(root, render_surface);
  CreateEffectNode(render_surface).render_surface_reason =
      RenderSurfaceReason::kTest;
  CopyProperties(render_surface, child1);
  auto& child1_transform_node = CreateTransformNode(child1);
  child1_transform_node.origin = gfx::Point3F(25.f, 25.f, 0.f);
  child1_transform_node.post_translation = gfx::Vector2dF(25.f, 25.f);
  child1_transform_node.local = child_rotation;

  UpdateActiveTreeDrawProperties();

  ASSERT_TRUE(GetRenderSurface(render_surface));

  EXPECT_EQ(gfx::RectF(100.f, 100.f),
            GetRenderSurface(root)->DrawableContentRect());

  // Layers that do not draw content should have empty visible content rects.
  EXPECT_EQ(gfx::Rect(0, 0, 0, 0), root->visible_layer_rect());
  EXPECT_EQ(gfx::Rect(0, 0, 0, 0), render_surface->visible_layer_rect());

  // The unclipped surface grows its DrawableContentRect to include all drawable
  // regions of the subtree.
  int diagonal_radius = ceil(sqrt(2.0) * 25.0);
  gfx::Rect expected_surface_drawable_content =
      gfx::Rect(50 - diagonal_radius, 50 - diagonal_radius, diagonal_radius * 2,
                diagonal_radius * 2);
  EXPECT_EQ(gfx::RectF(expected_surface_drawable_content),
            GetRenderSurface(render_surface)->DrawableContentRect());

  // All layers that draw content into the unclipped surface are also unclipped.
  EXPECT_EQ(gfx::Rect(0, 0, 50, 50), child1->visible_layer_rect());
  EXPECT_EQ(expected_surface_drawable_content, child1->drawable_content_rect());
}

// Layers that have non-axis aligned bounds (due to transforms) have an
// expanded, axis-aligned DrawableContentRect and visible content rect.
TEST_F(DrawPropertiesTest,
       DrawableAndVisibleContentRectsWithTransformOnClippedSurface) {
  LayerImpl* root = root_layer();
  LayerImpl* render_surface = AddLayer<LayerImpl>();
  LayerImpl* child1 = AddLayer<LayerImpl>();

  gfx::Transform child_rotation;
  child_rotation.Rotate(45.0);

  root->SetBounds(gfx::Size(50, 50));
  root->SetMasksToBounds(true);
  render_surface->SetBounds(gfx::Size(3, 4));
  child1->SetBounds(gfx::Size(50, 50));
  child1->SetDrawsContent(true);

  CreateClipNode(root);
  CopyProperties(root, render_surface);
  CreateEffectNode(render_surface).render_surface_reason =
      RenderSurfaceReason::kTest;
  CopyProperties(render_surface, child1);
  auto& child1_transform_node = CreateTransformNode(child1);
  child1_transform_node.origin = gfx::Point3F(25.f, 25.f, 0.f);
  child1_transform_node.post_translation = gfx::Vector2dF(25.f, 25.f);
  child1_transform_node.local = child_rotation;

  UpdateActiveTreeDrawProperties();

  ASSERT_TRUE(GetRenderSurface(render_surface));

  // The clipped surface clamps the DrawableContentRect that encloses the
  // rotated layer.
  int diagonal_radius = ceil(sqrt(2.0) * 25.0);
  gfx::Rect unclipped_surface_content =
      gfx::Rect(50 - diagonal_radius, 50 - diagonal_radius, diagonal_radius * 2,
                diagonal_radius * 2);
  gfx::RectF expected_surface_drawable_content(
      gfx::IntersectRects(unclipped_surface_content, gfx::Rect(50, 50)));
  EXPECT_EQ(expected_surface_drawable_content,
            GetRenderSurface(render_surface)->DrawableContentRect());

  // On the clipped surface, only a quarter  of the child1 is visible, but when
  // rotating it back to  child1's content space, the actual enclosing rect ends
  // up covering the full left half of child1.
  EXPECT_EQ(gfx::Rect(0, 0, 25, 50), child1->visible_layer_rect());

  // The child's DrawableContentRect is unclipped.
  EXPECT_EQ(unclipped_surface_content, child1->drawable_content_rect());
}

TEST_F(DrawPropertiesTest, DrawableAndVisibleContentRectsInHighDPI) {
  LayerImpl* root = root_layer();
  FakePictureLayerImpl* render_surface1 = AddLayer<FakePictureLayerImpl>();
  FakePictureLayerImpl* render_surface2 = AddLayer<FakePictureLayerImpl>();
  FakePictureLayerImpl* child1 = AddLayer<FakePictureLayerImpl>();
  FakePictureLayerImpl* child2 = AddLayer<FakePictureLayerImpl>();
  FakePictureLayerImpl* child3 = AddLayer<FakePictureLayerImpl>();

  root->SetBounds(gfx::Size(100, 100));
  root->SetMasksToBounds(true);
  render_surface1->SetBounds(gfx::Size(3, 4));
  render_surface1->SetDrawsContent(true);
  render_surface2->SetBounds(gfx::Size(7, 13));
  render_surface2->SetDrawsContent(true);
  child1->SetBounds(gfx::Size(50, 50));
  child1->SetDrawsContent(true);
  child2->SetBounds(gfx::Size(50, 50));
  child2->SetDrawsContent(true);
  child3->SetBounds(gfx::Size(50, 50));
  child3->SetDrawsContent(true);

  CreateClipNode(root);
  CopyProperties(root, render_surface1);
  CreateTransformNode(render_surface1).post_translation =
      gfx::Vector2dF(5.f, 5.f);
  CreateEffectNode(render_surface1).render_surface_reason =
      RenderSurfaceReason::kTest;
  CopyProperties(render_surface1, render_surface2);
  CreateTransformNode(render_surface2).post_translation =
      gfx::Vector2dF(5.f, 5.f);
  CreateEffectNode(render_surface2).render_surface_reason =
      RenderSurfaceReason::kTest;
  CopyProperties(render_surface2, child1);
  child1->SetOffsetToTransformParent(gfx::Vector2dF(5.f, 5.f));
  CopyProperties(render_surface2, child2);
  child2->SetOffsetToTransformParent(gfx::Vector2dF(75.f, 75.f));
  CopyProperties(render_surface2, child3);
  child3->SetOffsetToTransformParent(gfx::Vector2dF(125.f, 125.f));

  float device_scale_factor = 2.f;
  UpdateActiveTreeDrawProperties(device_scale_factor);

  ASSERT_TRUE(GetRenderSurface(render_surface1));
  ASSERT_TRUE(GetRenderSurface(render_surface2));

  // drawable_content_rects for all layers and surfaces are scaled by
  // device_scale_factor.
  EXPECT_EQ(gfx::RectF(200.f, 200.f),
            GetRenderSurface(root)->DrawableContentRect());
  EXPECT_EQ(gfx::RectF(10.f, 10.f, 190.f, 190.f),
            GetRenderSurface(render_surface1)->DrawableContentRect());

  // render_surface2 lives in the "unclipped universe" of render_surface1, and
  // is only implicitly clipped by render_surface1.
  EXPECT_EQ(gfx::RectF(10.f, 10.f, 350.f, 350.f),
            GetRenderSurface(render_surface2)->DrawableContentRect());

  EXPECT_EQ(gfx::Rect(10, 10, 100, 100), child1->drawable_content_rect());
  EXPECT_EQ(gfx::Rect(150, 150, 100, 100), child2->drawable_content_rect());
  EXPECT_EQ(gfx::Rect(250, 250, 100, 100), child3->drawable_content_rect());

  // The root layer does not actually draw content of its own.
  EXPECT_EQ(gfx::Rect(0, 0, 0, 0), root->visible_layer_rect());

  // All layer visible content rects are not expressed in content space of each
  // layer, so they are not scaled by the device_scale_factor.
  EXPECT_EQ(gfx::Rect(0, 0, 3, 4), render_surface1->visible_layer_rect());
  EXPECT_EQ(gfx::Rect(0, 0, 7, 13), render_surface2->visible_layer_rect());
  EXPECT_EQ(gfx::Rect(0, 0, 50, 50), child1->visible_layer_rect());
  EXPECT_EQ(gfx::Rect(0, 0, 15, 15), child2->visible_layer_rect());
  EXPECT_EQ(gfx::Rect(0, 0, 0, 0), child3->visible_layer_rect());
}

using DrawPropertiesScalingTest = DrawPropertiesTest;

// Verify draw and screen space transforms of layers not in a surface.
TEST_F(DrawPropertiesScalingTest, LayerTransformsInHighDPI) {
  LayerImpl* root = root_layer();
  root->SetBounds(gfx::Size(100, 100));
  root->SetDrawsContent(true);

  LayerImpl* child = AddLayer<LayerImpl>();
  child->SetBounds(gfx::Size(10, 10));
  child->SetDrawsContent(true);

  LayerImpl* child2 = AddLayer<LayerImpl>();
  child2->SetBounds(gfx::Size(5, 5));
  child2->SetDrawsContent(true);

  float device_scale_factor = 2.5f;

  CopyProperties(root, child);
  child->SetOffsetToTransformParent(gfx::Vector2dF(2.f, 2.f));
  CopyProperties(root, child2);
  child2->SetOffsetToTransformParent(gfx::Vector2dF(2.f, 2.f));

  UpdateActiveTreeDrawProperties(device_scale_factor);

  EXPECT_FLOAT_EQ(device_scale_factor, root->GetIdealContentsScale());
  EXPECT_FLOAT_EQ(device_scale_factor, child->GetIdealContentsScale());
  EXPECT_FLOAT_EQ(device_scale_factor, child2->GetIdealContentsScale());

  EXPECT_EQ(1u, GetRenderSurfaceList().size());

  // Verify root transforms
  gfx::Transform expected_root_transform;
  expected_root_transform.Scale(device_scale_factor, device_scale_factor);
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_root_transform,
                                  root->ScreenSpaceTransform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_root_transform,
                                  root->DrawTransform());

  // Verify results of transformed root rects
  gfx::RectF root_bounds(gfx::SizeF(root->bounds()));

  gfx::RectF root_draw_rect =
      MathUtil::MapClippedRect(root->DrawTransform(), root_bounds);
  gfx::RectF root_screen_space_rect =
      MathUtil::MapClippedRect(root->ScreenSpaceTransform(), root_bounds);

  gfx::RectF expected_root_draw_rect(gfx::SizeF(root->bounds()));
  expected_root_draw_rect.Scale(device_scale_factor);
  EXPECT_FLOAT_RECT_EQ(expected_root_draw_rect, root_draw_rect);
  EXPECT_FLOAT_RECT_EQ(expected_root_draw_rect, root_screen_space_rect);

  // Verify child and child2 transforms. They should match.
  gfx::Transform expected_child_transform;
  expected_child_transform.Scale(device_scale_factor, device_scale_factor);
  expected_child_transform.Translate(child->offset_to_transform_parent());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
                                  child->DrawTransform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
                                  child->ScreenSpaceTransform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
                                  child2->DrawTransform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
                                  child2->ScreenSpaceTransform());

  // Verify results of transformed child and child2 rects. They should
  // match.
  gfx::RectF child_bounds(gfx::SizeF(child->bounds()));

  gfx::RectF child_draw_rect =
      MathUtil::MapClippedRect(child->DrawTransform(), child_bounds);
  gfx::RectF child_screen_space_rect =
      MathUtil::MapClippedRect(child->ScreenSpaceTransform(), child_bounds);

  gfx::RectF child2_draw_rect =
      MathUtil::MapClippedRect(child2->DrawTransform(), child_bounds);
  gfx::RectF child2_screen_space_rect =
      MathUtil::MapClippedRect(child2->ScreenSpaceTransform(), child_bounds);

  gfx::RectF expected_child_draw_rect(
      gfx::PointAtOffsetFromOrigin(child->offset_to_transform_parent()),
      gfx::SizeF(child->bounds()));
  expected_child_draw_rect.Scale(device_scale_factor);
  EXPECT_FLOAT_RECT_EQ(expected_child_draw_rect, child_draw_rect);
  EXPECT_FLOAT_RECT_EQ(expected_child_draw_rect, child_screen_space_rect);
  EXPECT_FLOAT_RECT_EQ(expected_child_draw_rect, child2_draw_rect);
  EXPECT_FLOAT_RECT_EQ(expected_child_draw_rect, child2_screen_space_rect);
}

// Verify draw and screen space transforms of layers in a surface.
TEST_F(DrawPropertiesScalingTest, SurfaceLayerTransformsInHighDPI) {
  gfx::Transform perspective_matrix;
  perspective_matrix.ApplyPerspectiveDepth(2.0);
  gfx::Vector2dF perspective_surface_offset(2.f, 2.f);

  gfx::Transform scale_small_matrix;
  scale_small_matrix.Scale(SK_MScalar1 / 10.f, SK_MScalar1 / 12.f);

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

  LayerImpl* parent = AddLayer<LayerImpl>();
  parent->SetBounds(gfx::Size(100, 100));
  parent->SetDrawsContent(true);

  LayerImpl* perspective_surface = AddLayer<LayerImpl>();
  perspective_surface->SetBounds(gfx::Size(10, 10));
  perspective_surface->SetDrawsContent(true);

  LayerImpl* scale_surface = AddLayer<LayerImpl>();
  scale_surface->SetBounds(gfx::Size(10, 10));
  scale_surface->SetDrawsContent(true);

  CopyProperties(OuterViewportScrollLayer(), parent);
  CopyProperties(parent, perspective_surface);
  auto& perspective_surface_transform =
      CreateTransformNode(perspective_surface);
  perspective_surface_transform.local = perspective_matrix * scale_small_matrix;
  perspective_surface_transform.post_translation = perspective_surface_offset;
  CreateEffectNode(perspective_surface).render_surface_reason =
      RenderSurfaceReason::kTest;
  CopyProperties(parent, scale_surface);
  auto& scale_surface_transform = CreateTransformNode(scale_surface);
  scale_surface_transform.local = scale_small_matrix;
  scale_surface_transform.post_translation = gfx::Vector2dF(2.f, 2.f);
  CreateEffectNode(scale_surface).render_surface_reason =
      RenderSurfaceReason::kTest;

  float device_scale_factor = 2.5f;
  float page_scale_factor = 3.f;
  host_impl()->active_tree()->SetPageScaleOnActiveTree(page_scale_factor);

  UpdateActiveTreeDrawProperties(device_scale_factor);

  EXPECT_FLOAT_EQ(device_scale_factor * page_scale_factor,
                  parent->GetIdealContentsScale());
  EXPECT_FLOAT_EQ(device_scale_factor * page_scale_factor,
                  perspective_surface->GetIdealContentsScale());
  // Ideal scale is the max 2d scale component of the combined transform up to
  // the nearest render target. Here this includes the layer transform as well
  // as the device and page scale factors.
  gfx::Transform transform = scale_small_matrix;
  transform.Scale(device_scale_factor * page_scale_factor,
                  device_scale_factor * page_scale_factor);
  gfx::Vector2dF scales =
      MathUtil::ComputeTransform2dScaleComponents(transform, 0.f);
  float max_2d_scale = std::max(scales.x(), scales.y());
  EXPECT_FLOAT_EQ(max_2d_scale, scale_surface->GetIdealContentsScale());

  // The ideal scale will draw 1:1 with its render target space along
  // the larger-scale axis.
  gfx::Vector2dF target_space_transform_scales =
      MathUtil::ComputeTransform2dScaleComponents(
          scale_surface->draw_properties().target_space_transform, 0.f);
  EXPECT_FLOAT_EQ(max_2d_scale, std::max(target_space_transform_scales.x(),
                                         target_space_transform_scales.y()));

  EXPECT_EQ(3u, GetRenderSurfaceList().size());

  gfx::Transform expected_parent_draw_transform;
  expected_parent_draw_transform.Scale(device_scale_factor * page_scale_factor,
                                       device_scale_factor * page_scale_factor);
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_parent_draw_transform,
                                  parent->DrawTransform());

  // The scale for the perspective surface is not known, so it is rendered 1:1
  // with the screen, and then scaled during drawing.
  gfx::Transform expected_perspective_surface_draw_transform;
  expected_perspective_surface_draw_transform.Translate(
      device_scale_factor * page_scale_factor * perspective_surface_offset.x(),
      device_scale_factor * page_scale_factor * perspective_surface_offset.y());
  expected_perspective_surface_draw_transform.PreconcatTransform(
      perspective_matrix);
  expected_perspective_surface_draw_transform.PreconcatTransform(
      scale_small_matrix);
  gfx::Transform expected_perspective_surface_layer_draw_transform;
  expected_perspective_surface_layer_draw_transform.Scale(
      device_scale_factor * page_scale_factor,
      device_scale_factor * page_scale_factor);
  EXPECT_TRANSFORMATION_MATRIX_EQ(
      expected_perspective_surface_draw_transform,
      GetRenderSurface(perspective_surface)->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(
      expected_perspective_surface_layer_draw_transform,
      perspective_surface->DrawTransform());
}

TEST_F(DrawPropertiesScalingTest, SmallIdealScale) {
  gfx::Transform parent_scale_matrix;
  SkMScalar initial_parent_scale = 1.75;
  parent_scale_matrix.Scale(initial_parent_scale, initial_parent_scale);

  gfx::Transform child_scale_matrix;
  SkMScalar initial_child_scale = 0.25;
  child_scale_matrix.Scale(initial_child_scale, initial_child_scale);

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

  LayerImpl* page_scale = AddLayer<LayerImpl>();
  page_scale->SetBounds(gfx::Size(100, 100));

  LayerImpl* parent = AddLayer<LayerImpl>();
  parent->SetBounds(gfx::Size(100, 100));
  parent->SetDrawsContent(true);

  LayerImpl* child_scale = AddLayer<LayerImpl>();
  child_scale->SetBounds(gfx::Size(10, 10));
  child_scale->SetDrawsContent(true);

  float device_scale_factor = 2.5f;
  float page_scale_factor = 0.01f;

  CopyProperties(root, page_scale);
  CreateTransformNode(page_scale).in_subtree_of_page_scale_layer = true;
  CopyProperties(page_scale, parent);
  CreateTransformNode(parent).local = parent_scale_matrix;
  CopyProperties(parent, child_scale);
  CreateTransformNode(child_scale).local = child_scale_matrix;

  LayerTreeImpl::ViewportPropertyIds viewport_property_ids;
  viewport_property_ids.page_scale_transform =
      page_scale->transform_tree_index();
  host_impl()->active_tree()->SetViewportPropertyIds(viewport_property_ids);

  host_impl()->active_tree()->SetPageScaleOnActiveTree(page_scale_factor);
  UpdateActiveTreeDrawProperties(device_scale_factor);

  // The ideal scale is able to go below 1.
  float expected_ideal_scale =
      device_scale_factor * page_scale_factor * initial_parent_scale;
  EXPECT_LT(expected_ideal_scale, 1.f);
  EXPECT_FLOAT_EQ(expected_ideal_scale, parent->GetIdealContentsScale());

  expected_ideal_scale = device_scale_factor * page_scale_factor *
                         initial_parent_scale * initial_child_scale;
  EXPECT_LT(expected_ideal_scale, 1.f);
  EXPECT_FLOAT_EQ(expected_ideal_scale, child_scale->GetIdealContentsScale());
}

TEST_F(DrawPropertiesScalingTest, IdealScaleForAnimatingLayer) {
  gfx::Transform parent_scale_matrix;
  SkMScalar initial_parent_scale = 1.75;
  parent_scale_matrix.Scale(initial_parent_scale, initial_parent_scale);

  gfx::Transform child_scale_matrix;
  SkMScalar initial_child_scale = 1.25;
  child_scale_matrix.Scale(initial_child_scale, initial_child_scale);

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

  LayerImpl* parent = AddLayer<LayerImpl>();
  parent->SetBounds(gfx::Size(100, 100));
  parent->SetDrawsContent(true);

  LayerImpl* child_scale = AddLayer<LayerImpl>();
  child_scale->SetBounds(gfx::Size(10, 10));
  child_scale->SetDrawsContent(true);

  CopyProperties(root, parent);
  CreateTransformNode(parent).local = parent_scale_matrix;
  CopyProperties(parent, child_scale);
  CreateTransformNode(child_scale).local = child_scale_matrix;

  UpdateActiveTreeDrawProperties();

  EXPECT_FLOAT_EQ(initial_parent_scale, parent->GetIdealContentsScale());
  // Animating layers compute ideal scale in the same way as when
  // they are static.
  EXPECT_FLOAT_EQ(initial_child_scale * initial_parent_scale,
                  child_scale->GetIdealContentsScale());
}

TEST_F(DrawPropertiesTest, RenderSurfaceTransformsInHighDPI) {
  LayerImpl* parent = root_layer();
  parent->SetBounds(gfx::Size(30, 30));
  parent->SetDrawsContent(true);

  LayerImpl* child = AddLayer<LayerImpl>();
  child->SetBounds(gfx::Size(10, 10));
  child->SetDrawsContent(true);

  // This layer should end up in the same surface as child, with the same draw
  // and screen space transforms.
  LayerImpl* duplicate_child_non_owner = AddLayer<LayerImpl>();
  duplicate_child_non_owner->SetBounds(gfx::Size(10, 10));
  duplicate_child_non_owner->SetDrawsContent(true);

  float device_scale_factor = 1.5f;
  gfx::Vector2dF child_offset(2.f, 2.f);

  CopyProperties(parent, child);
  CreateTransformNode(child).post_translation = child_offset;
  CreateEffectNode(child).render_surface_reason = RenderSurfaceReason::kTest;
  CopyProperties(child, duplicate_child_non_owner);
  duplicate_child_non_owner->SetOffsetToTransformParent(
      child->offset_to_transform_parent());

  UpdateActiveTreeDrawProperties(device_scale_factor);

  // We should have two render surfaces. The root's render surface and child's
  // render surface (it needs one because of force_render_surface).
  EXPECT_EQ(2u, GetRenderSurfaceList().size());

  gfx::Transform expected_parent_transform;
  expected_parent_transform.Scale(device_scale_factor, device_scale_factor);
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_parent_transform,
                                  parent->ScreenSpaceTransform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_parent_transform,
                                  parent->DrawTransform());

  gfx::Transform expected_draw_transform;
  expected_draw_transform.Scale(device_scale_factor, device_scale_factor);
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_draw_transform,
                                  child->DrawTransform());

  gfx::Transform expected_screen_space_transform;
  expected_screen_space_transform.Scale(device_scale_factor,
                                        device_scale_factor);
  expected_screen_space_transform.Translate(child_offset);
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_screen_space_transform,
                                  child->ScreenSpaceTransform());

  gfx::Transform expected_duplicate_child_draw_transform =
      child->DrawTransform();
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_duplicate_child_draw_transform,
                                  duplicate_child_non_owner->DrawTransform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(
      child->ScreenSpaceTransform(),
      duplicate_child_non_owner->ScreenSpaceTransform());
  EXPECT_EQ(child->drawable_content_rect(),
            duplicate_child_non_owner->drawable_content_rect());
  EXPECT_EQ(child->bounds(), duplicate_child_non_owner->bounds());

  gfx::Transform expected_render_surface_draw_transform;
  expected_render_surface_draw_transform.Translate(
      device_scale_factor * child_offset.x(),
      device_scale_factor * child_offset.y());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_render_surface_draw_transform,
                                  GetRenderSurface(child)->draw_transform());

  gfx::Transform expected_surface_draw_transform;
  expected_surface_draw_transform.Translate(device_scale_factor * 2.f,
                                            device_scale_factor * 2.f);
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_surface_draw_transform,
                                  GetRenderSurface(child)->draw_transform());

  gfx::Transform expected_surface_screen_space_transform;
  expected_surface_screen_space_transform.Translate(device_scale_factor * 2.f,
                                                    device_scale_factor * 2.f);
  EXPECT_TRANSFORMATION_MATRIX_EQ(
      expected_surface_screen_space_transform,
      GetRenderSurface(child)->screen_space_transform());
}

TEST_F(DrawPropertiesTest,
       RenderSurfaceTransformsInHighDPIAccurateScaleZeroPosition) {
  LayerImpl* parent = root_layer();
  parent->SetBounds(gfx::Size(33, 31));
  parent->SetDrawsContent(true);

  LayerImpl* child = AddLayer<LayerImpl>();
  child->SetBounds(gfx::Size(13, 11));
  child->SetDrawsContent(true);

  float device_scale_factor = 1.7f;

  CopyProperties(parent, child);
  CreateEffectNode(child).render_surface_reason = RenderSurfaceReason::kTest;

  UpdateActiveTreeDrawProperties(device_scale_factor);

  // We should have two render surfaces. The root's render surface and child's
  // render surface (it needs one because of force_render_surface).
  EXPECT_EQ(2u, GetRenderSurfaceList().size());

  EXPECT_TRANSFORMATION_MATRIX_EQ(gfx::Transform(),
                                  GetRenderSurface(child)->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(gfx::Transform(),
                                  GetRenderSurface(child)->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(
      gfx::Transform(), GetRenderSurface(child)->screen_space_transform());
}

// Needs layer tree mode: mask layer. Not using impl-side PropertyTreeBuilder.
TEST_F(DrawPropertiesTestWithLayerTree, LayerSearch) {
  scoped_refptr<Layer> root = Layer::Create();
  scoped_refptr<Layer> child = Layer::Create();
  scoped_refptr<Layer> grand_child = Layer::Create();
  FakeContentLayerClient client;
  scoped_refptr<PictureLayer> mask_layer = PictureLayer::Create(&client);

  child->AddChild(grand_child.get());
  child->SetMaskLayer(mask_layer);
  root->AddChild(child.get());

  host()->SetRootLayer(root);

  int nonexistent_id = -1;
  EXPECT_EQ(root.get(), host()->LayerById(root->id()));
  EXPECT_EQ(child.get(), host()->LayerById(child->id()));
  EXPECT_EQ(grand_child.get(), host()->LayerById(grand_child->id()));
  EXPECT_EQ(mask_layer.get(), host()->LayerById(mask_layer->id()));
  EXPECT_FALSE(host()->LayerById(nonexistent_id));
}

TEST_F(DrawPropertiesTest, TransparentChildRenderSurfaceCreation) {
  LayerImpl* root = root_layer();
  LayerImpl* child = AddLayer<LayerImpl>();
  LayerImpl* grand_child = AddLayer<LayerImpl>();

  root->SetBounds(gfx::Size(100, 100));
  child->SetBounds(gfx::Size(10, 10));
  grand_child->SetBounds(gfx::Size(10, 10));
  grand_child->SetDrawsContent(true);

  CopyProperties(root, child);
  CreateEffectNode(child).opacity = 0.5f;
  CopyProperties(child, grand_child);

  UpdateActiveTreeDrawProperties();
  EXPECT_EQ(GetRenderSurface(child), GetRenderSurface(root));
}

TEST_F(DrawPropertiesTest, OpacityAnimatingOnPendingTree) {
  host_impl()->CreatePendingTree();
  LayerImpl* root = EnsureRootLayerInPendingTree();
  root->SetBounds(gfx::Size(100, 100));
  root->SetDrawsContent(true);

  auto* child = AddLayerInPendingTree<LayerImpl>();
  child->SetBounds(gfx::Size(50, 50));
  child->SetDrawsContent(true);

  host_impl()->pending_tree()->SetElementIdsForTesting();
  CopyProperties(root, child);
  CreateEffectNode(child).opacity = 0.0f;

  // Add opacity animation.
  AddOpacityTransitionToElementWithAnimation(
      child->element_id(), timeline_impl(), 10.0, 0.0f, 1.0f, false);

  UpdatePendingTreeDrawProperties();

  // We should have one render surface and two layers. The child
  // layer should be included even though it is transparent.
  ASSERT_EQ(1u, host_impl()->pending_tree()->GetRenderSurfaceList().size());
  ASSERT_EQ(2, GetRenderSurface(root)->num_contributors());

  // If the root itself is hidden, the child should not be drawn even if it has
  // an animating opacity.
  SetOpacity(root, 0.0f);
  UpdatePendingTreeDrawProperties();

  EXPECT_FALSE(GetEffectNode(child)->is_drawn);

  // A layer should be drawn and it should contribute to drawn surface when
  // it has animating opacity even if it has opacity 0.
  SetOpacity(root, 1.0f);
  SetOpacity(child, 0.0f);
  UpdatePendingTreeDrawProperties();

  EXPECT_TRUE(GetEffectNode(child)->is_drawn);
  EXPECT_TRUE(GetPropertyTrees(root)->effect_tree.ContributesToDrawnSurface(
      child->effect_tree_index()));

  // But if the opacity of the layer remains 0 after activation, it should not
  // be drawn.
  host_impl()->ActivateSyncTree();
  LayerTreeImpl* active_tree = host_impl()->active_tree();
  LayerImpl* active_child = active_tree->LayerById(child->id());

  EffectTree& active_effect_tree = active_tree->property_trees()->effect_tree;
  EXPECT_TRUE(active_effect_tree.needs_update());

  UpdateActiveTreeDrawProperties();

  EXPECT_FALSE(GetEffectNode(active_child)->is_drawn);
  EXPECT_FALSE(active_effect_tree.ContributesToDrawnSurface(
      active_child->effect_tree_index()));
}

using LCDTextTestParam = std::tuple<bool, bool>;
class LCDTextTest : public DrawPropertiesTestBase,
                    public testing::TestWithParam<LCDTextTestParam> {
 public:
  LCDTextTest() : DrawPropertiesTestBase(LCDTextTestLayerTreeSettings()) {}

 protected:
  LayerTreeSettings LCDTextTestLayerTreeSettings() {
    LayerListSettings settings;

    can_use_lcd_text_ = std::get<0>(GetParam());
    layers_always_allowed_lcd_text_ = std::get<1>(GetParam());
    settings.can_use_lcd_text = can_use_lcd_text_;
    settings.layers_always_allowed_lcd_text = layers_always_allowed_lcd_text_;
    return settings;
  }

  void SetUp() override {
    root_ = root_layer();
    child_ = AddLayer<LayerImpl>();
    grand_child_ = AddLayer<LayerImpl>();
    SetElementIdsForTesting();

    root_->SetContentsOpaque(true);
    child_->SetContentsOpaque(true);
    grand_child_->SetContentsOpaque(true);

    root_->SetDrawsContent(true);
    child_->SetDrawsContent(true);
    grand_child_->SetDrawsContent(true);

    root_->SetBounds(gfx::Size(1, 1));
    child_->SetBounds(gfx::Size(1, 1));
    grand_child_->SetBounds(gfx::Size(1, 1));

    CopyProperties(root_, child_);
    CreateTransformNode(child_);
    CreateEffectNode(child_).render_surface_reason = RenderSurfaceReason::kTest;
    CopyProperties(child_, grand_child_);
  }

  bool can_use_lcd_text_;
  bool layers_always_allowed_lcd_text_;

  LayerImpl* root_ = nullptr;
  LayerImpl* child_ = nullptr;
  LayerImpl* grand_child_ = nullptr;
};

TEST_P(LCDTextTest, CanUseLCDText) {
  bool expect_lcd_text = can_use_lcd_text_ || layers_always_allowed_lcd_text_;
  bool expect_not_lcd_text = layers_always_allowed_lcd_text_;

  // Case 1: Identity transform.
  UpdateActiveTreeDrawProperties();
  EXPECT_EQ(expect_lcd_text, root_->CanUseLCDText());
  EXPECT_EQ(expect_lcd_text, child_->CanUseLCDText());
  EXPECT_EQ(expect_lcd_text, grand_child_->CanUseLCDText());

  // Case 2: Integral translation.
  gfx::Transform integral_translation;
  integral_translation.Translate(1.0, 2.0);
  SetTransform(child_, integral_translation);

  UpdateActiveTreeDrawProperties();
  EXPECT_EQ(expect_lcd_text, root_->CanUseLCDText());
  EXPECT_EQ(expect_lcd_text, child_->CanUseLCDText());
  EXPECT_EQ(expect_lcd_text, grand_child_->CanUseLCDText());

  // Case 3: Non-integral translation.
  gfx::Transform non_integral_translation;
  non_integral_translation.Translate(1.5, 2.5);
  SetTransform(child_, non_integral_translation);
  UpdateActiveTreeDrawProperties();
  EXPECT_EQ(expect_lcd_text, root_->CanUseLCDText());
  EXPECT_EQ(expect_not_lcd_text, child_->CanUseLCDText());
  EXPECT_EQ(expect_not_lcd_text, grand_child_->CanUseLCDText());

  // Case 4: Rotation.
  gfx::Transform rotation;
  rotation.Rotate(10.0);
  SetTransform(child_, rotation);
  UpdateActiveTreeDrawProperties();
  EXPECT_EQ(expect_lcd_text, root_->CanUseLCDText());
  EXPECT_EQ(expect_not_lcd_text, child_->CanUseLCDText());
  EXPECT_EQ(expect_not_lcd_text, grand_child_->CanUseLCDText());

  // Case 5: Scale.
  gfx::Transform scale;
  scale.Scale(2.0, 2.0);
  SetTransform(child_, scale);
  UpdateActiveTreeDrawProperties();
  EXPECT_EQ(expect_lcd_text, root_->CanUseLCDText());
  EXPECT_EQ(expect_not_lcd_text, child_->CanUseLCDText());
  EXPECT_EQ(expect_not_lcd_text, grand_child_->CanUseLCDText());

  // Case 6: Skew.
  gfx::Transform skew;
  skew.Skew(10.0, 0.0);
  SetTransform(child_, skew);
  UpdateActiveTreeDrawProperties();
  EXPECT_EQ(expect_lcd_text, root_->CanUseLCDText());
  EXPECT_EQ(expect_not_lcd_text, child_->CanUseLCDText());
  EXPECT_EQ(expect_not_lcd_text, grand_child_->CanUseLCDText());

  // Case 7: Translucent.
  SetTransform(child_, gfx::Transform());
  SetOpacity(child_, 0.5f);
  UpdateActiveTreeDrawProperties();
  EXPECT_EQ(expect_lcd_text, root_->CanUseLCDText());
  EXPECT_EQ(expect_not_lcd_text, child_->CanUseLCDText());
  EXPECT_EQ(expect_not_lcd_text, grand_child_->CanUseLCDText());

  // Case 8: Sanity check: restore transform and opacity.
  SetTransform(child_, gfx::Transform());
  SetOpacity(child_, 1.f);
  UpdateActiveTreeDrawProperties();
  EXPECT_EQ(expect_lcd_text, root_->CanUseLCDText());
  EXPECT_EQ(expect_lcd_text, child_->CanUseLCDText());
  EXPECT_EQ(expect_lcd_text, grand_child_->CanUseLCDText());

  // Case 9: Non-opaque content.
  child_->SetContentsOpaque(false);
  UpdateActiveTreeDrawProperties();
  EXPECT_EQ(expect_lcd_text, root_->CanUseLCDText());
  EXPECT_EQ(expect_not_lcd_text, child_->CanUseLCDText());
  EXPECT_EQ(expect_lcd_text, grand_child_->CanUseLCDText());

  // Case 10: Sanity check: restore content opaqueness.
  child_->SetContentsOpaque(true);
  UpdateActiveTreeDrawProperties();
  EXPECT_EQ(expect_lcd_text, root_->CanUseLCDText());
  EXPECT_EQ(expect_lcd_text, child_->CanUseLCDText());
  EXPECT_EQ(expect_lcd_text, grand_child_->CanUseLCDText());

  // Case 11: will-change: transform
  child_->SetHasWillChangeTransformHint(true);
  UpdateActiveTreeDrawProperties();
  EXPECT_EQ(expect_lcd_text, root_->CanUseLCDText());
  EXPECT_EQ(expect_not_lcd_text, child_->CanUseLCDText());
  EXPECT_EQ(expect_lcd_text, grand_child_->CanUseLCDText());
}

TEST_P(LCDTextTest, CanUseLCDTextWithAnimation) {
  bool expect_lcd_text = can_use_lcd_text_ || layers_always_allowed_lcd_text_;
  bool expect_not_lcd_text = layers_always_allowed_lcd_text_;

  // Sanity check: Make sure can_use_lcd_text_ is set on each node.
  UpdateActiveTreeDrawProperties();
  EXPECT_EQ(expect_lcd_text, root_->CanUseLCDText());
  EXPECT_EQ(expect_lcd_text, child_->CanUseLCDText());
  EXPECT_EQ(expect_lcd_text, grand_child_->CanUseLCDText());

  // Add opacity animation.
  SetOpacity(child_, 0.9f);
  AddOpacityTransitionToElementWithAnimation(child_->element_id(), timeline(),
                                             10.0, 0.9f, 0.1f, false);
  UpdateActiveTreeDrawProperties();
  // Text LCD should be adjusted while animation is active.
  EXPECT_EQ(expect_lcd_text, root_->CanUseLCDText());
  EXPECT_EQ(expect_not_lcd_text, child_->CanUseLCDText());
  EXPECT_EQ(expect_not_lcd_text, grand_child_->CanUseLCDText());
}

TEST_P(LCDTextTest, CanUseLCDTextWithAnimationContentsOpaque) {
  bool expect_lcd_text = can_use_lcd_text_ || layers_always_allowed_lcd_text_;
  bool expect_not_lcd_text = layers_always_allowed_lcd_text_;

  // Sanity check: Make sure can_use_lcd_text_ is set on each node.
  UpdateActiveTreeDrawProperties();
  EXPECT_EQ(expect_lcd_text, root_->CanUseLCDText());
  EXPECT_EQ(expect_lcd_text, child_->CanUseLCDText());
  EXPECT_EQ(expect_lcd_text, grand_child_->CanUseLCDText());

  // Mark contents non-opaque within the first animation frame.
  child_->SetContentsOpaque(false);
  AddOpacityTransitionToElementWithAnimation(child_->element_id(), timeline(),
                                             10.0, 0.9f, 0.1f, false);
  UpdateActiveTreeDrawProperties();
  // LCD text should be disabled for non-opaque layers even during animations.
  EXPECT_EQ(expect_lcd_text, root_->CanUseLCDText());
  EXPECT_EQ(expect_not_lcd_text, child_->CanUseLCDText());
  EXPECT_EQ(expect_lcd_text, grand_child_->CanUseLCDText());
}

INSTANTIATE_TEST_SUITE_P(DrawPropertiesTest,
                         LCDTextTest,
                         testing::Combine(testing::Bool(), testing::Bool()));

// Needs layer tree mode: hide_layer_and_subtree.
TEST_F(DrawPropertiesTestWithLayerTree, SubtreeHidden_SingleLayerImpl) {
  auto root = Layer::Create();
  root->SetBounds(gfx::Size(50, 50));
  root->SetIsDrawable(true);

  auto child = Layer::Create();
  root->AddChild(child);
  child->SetBounds(gfx::Size(40, 40));
  child->SetIsDrawable(true);

  auto grand_child = Layer::Create();
  child->AddChild(grand_child);
  grand_child->SetBounds(gfx::Size(30, 30));
  grand_child->SetIsDrawable(true);
  grand_child->SetHideLayerAndSubtree(true);

  child->AddChild(grand_child);
  root->AddChild(child);
  host()->SetRootLayer(root);

  CommitAndActivate();

  // We should have one render surface and two layers. The grand child has
  // hidden itself.
  ASSERT_EQ(1u, GetRenderSurfaceList().size());
  ASSERT_EQ(2, GetRenderSurfaceImpl(root)->num_contributors());
  EXPECT_TRUE(ImplOf(root)->contributes_to_drawn_render_surface());
  EXPECT_TRUE(ImplOf(child)->contributes_to_drawn_render_surface());
  EXPECT_FALSE(ImplOf(grand_child)->contributes_to_drawn_render_surface());
}

// Needs layer tree mode: hide_layer_and_subtree.
TEST_F(DrawPropertiesTestWithLayerTree, SubtreeHidden_TwoLayersImpl) {
  auto root = Layer::Create();
  root->SetBounds(gfx::Size(50, 50));
  root->SetIsDrawable(true);

  auto child = Layer::Create();
  child->SetBounds(gfx::Size(40, 40));
  child->SetIsDrawable(true);
  child->SetHideLayerAndSubtree(true);

  auto grand_child = Layer::Create();
  grand_child->SetBounds(gfx::Size(30, 30));
  grand_child->SetIsDrawable(true);

  child->AddChild(grand_child);
  root->AddChild(child);
  host()->SetRootLayer(root);

  CommitAndActivate();

  // We should have one render surface and one layer. The child has
  // hidden itself and the grand child.
  ASSERT_EQ(1u, GetRenderSurfaceList().size());
  ASSERT_EQ(1, GetRenderSurfaceImpl(root)->num_contributors());
  EXPECT_TRUE(ImplOf(root)->contributes_to_drawn_render_surface());
  EXPECT_FALSE(ImplOf(child)->contributes_to_drawn_render_surface());
  EXPECT_FALSE(ImplOf(grand_child)->contributes_to_drawn_render_surface());
}

// Needs layer tree mode: mask layer, hide_layer_and_subtree and copy request.
TEST_F(DrawPropertiesTestWithLayerTree, SubtreeHiddenWithCopyRequest) {
  auto root = Layer::Create();
  root->SetBounds(gfx::Size(50, 50));
  root->SetIsDrawable(true);

  auto copy_grand_parent = Layer::Create();
  copy_grand_parent->SetBounds(gfx::Size(40, 40));
  copy_grand_parent->SetIsDrawable(true);

  auto copy_parent = Layer::Create();
  copy_parent->SetBounds(gfx::Size(30, 30));
  copy_parent->SetIsDrawable(true);
  copy_parent->SetForceRenderSurfaceForTesting(true);

  auto copy_layer = Layer::Create();
  copy_layer->SetBounds(gfx::Size(20, 20));
  copy_layer->SetIsDrawable(true);
  copy_layer->SetForceRenderSurfaceForTesting(true);

  auto copy_child = Layer::Create();
  copy_child->SetBounds(gfx::Size(20, 20));
  copy_child->SetIsDrawable(true);

  auto copy_grand_child = Layer::Create();
  copy_grand_child->SetBounds(gfx::Size(20, 20));
  copy_grand_child->SetIsDrawable(true);

  auto copy_grand_parent_sibling_before = Layer::Create();
  copy_grand_parent_sibling_before->SetBounds(gfx::Size(40, 40));
  copy_grand_parent_sibling_before->SetIsDrawable(true);

  auto copy_grand_parent_sibling_after = Layer::Create();
  copy_grand_parent_sibling_after->SetBounds(gfx::Size(40, 40));
  copy_grand_parent_sibling_after->SetIsDrawable(true);

  copy_child->AddChild(copy_grand_child);
  copy_layer->AddChild(copy_child);
  copy_parent->AddChild(copy_layer);
  copy_grand_parent->AddChild(copy_parent);
  root->AddChild(copy_grand_parent_sibling_before);
  root->AddChild(copy_grand_parent);
  root->AddChild(copy_grand_parent_sibling_after);
  host()->SetRootLayer(root);

  // Hide the copy_grand_parent and its subtree. But make a copy request in that
  // hidden subtree on copy_layer. Also hide the copy grand child and its
  // subtree.
  copy_grand_parent->SetHideLayerAndSubtree(true);
  copy_grand_parent_sibling_before->SetHideLayerAndSubtree(true);
  copy_grand_parent_sibling_after->SetHideLayerAndSubtree(true);
  copy_grand_child->SetHideLayerAndSubtree(true);

  copy_layer->RequestCopyOfOutput(
      viz::CopyOutputRequest::CreateStubForTesting());

  CommitAndActivate();

  EXPECT_TRUE(GetEffectNode(ImplOf(root))->subtree_has_copy_request);
  EXPECT_TRUE(
      GetEffectNode(ImplOf(copy_grand_parent))->subtree_has_copy_request);
  EXPECT_TRUE(GetEffectNode(ImplOf(copy_parent))->subtree_has_copy_request);
  EXPECT_TRUE(GetEffectNode(ImplOf(copy_layer))->subtree_has_copy_request);

  // We should have four render surfaces, one for the root, one for the grand
  // parent since it has opacity and two drawing descendants, one for the parent
  // since it owns a surface, and one for the copy_layer.
  ASSERT_EQ(4u, GetRenderSurfaceList().size());
  EXPECT_EQ(static_cast<uint64_t>(root->id()),
            GetRenderSurfaceList().at(0)->id());
  EXPECT_EQ(static_cast<uint64_t>(copy_grand_parent->id()),
            GetRenderSurfaceList().at(1)->id());
  EXPECT_EQ(static_cast<uint64_t>(copy_parent->id()),
            GetRenderSurfaceList().at(2)->id());
  EXPECT_EQ(static_cast<uint64_t>(copy_layer->id()),
            GetRenderSurfaceList().at(3)->id());

  // The root render surface should have 2 contributing layers.
  EXPECT_EQ(2, GetRenderSurfaceImpl(root)->num_contributors());
  EXPECT_TRUE(ImplOf(root)->contributes_to_drawn_render_surface());
  EXPECT_FALSE(
      ImplOf(copy_grand_parent)->contributes_to_drawn_render_surface());
  EXPECT_FALSE(ImplOf(copy_grand_parent_sibling_before)
                   ->contributes_to_drawn_render_surface());
  EXPECT_FALSE(ImplOf(copy_grand_parent_sibling_after)
                   ->contributes_to_drawn_render_surface());

  // Nothing actually draws into the copy parent, so only the copy_layer will
  // appear in its list, since it needs to be drawn for the copy request.
  ASSERT_EQ(1, GetRenderSurfaceImpl(copy_parent)->num_contributors());
  EXPECT_FALSE(ImplOf(copy_parent)->contributes_to_drawn_render_surface());

  // The copy layer's render surface should have 2 contributing layers.
  ASSERT_EQ(2, GetRenderSurfaceImpl(copy_layer)->num_contributors());
  EXPECT_TRUE(ImplOf(copy_layer)->contributes_to_drawn_render_surface());
  EXPECT_TRUE(ImplOf(copy_child)->contributes_to_drawn_render_surface());
  EXPECT_FALSE(ImplOf(copy_grand_child)->contributes_to_drawn_render_surface());

  // copy_grand_parent, copy_parent shouldn't be drawn because they are hidden,
  // but the copy_layer and copy_child should be drawn for the copy request.
  // copy grand child should not be drawn as its hidden even in the copy
  // request.
  EXPECT_FALSE(GetEffectNode(ImplOf(copy_grand_parent))->is_drawn);
  EXPECT_FALSE(GetEffectNode(ImplOf(copy_parent))->is_drawn);
  EXPECT_TRUE(GetEffectNode(ImplOf(copy_layer))->is_drawn);
  EXPECT_TRUE(GetEffectNode(ImplOf(copy_child))->is_drawn);
  EXPECT_FALSE(GetEffectNode(ImplOf(copy_grand_child))->is_drawn);

  // Though copy_layer is drawn, it shouldn't contribute to drawn surface as its
  // actually hidden.
  EXPECT_FALSE(
      GetRenderSurfaceImpl(copy_layer)->contributes_to_drawn_surface());
}

// Needs layer tree mode: copy request.
TEST_F(DrawPropertiesTestWithLayerTree, ClippedOutCopyRequest) {
  auto root = Layer::Create();
  root->SetBounds(gfx::Size(50, 50));
  root->SetIsDrawable(true);

  auto copy_parent = Layer::Create();
  copy_parent->SetIsDrawable(true);
  copy_parent->SetMasksToBounds(true);

  auto copy_layer = Layer::Create();
  copy_layer->SetBounds(gfx::Size(30, 30));
  copy_layer->SetIsDrawable(true);
  copy_layer->SetForceRenderSurfaceForTesting(true);

  auto copy_child = Layer::Create();
  copy_child->SetBounds(gfx::Size(20, 20));
  copy_child->SetIsDrawable(true);

  copy_layer->RequestCopyOfOutput(
      viz::CopyOutputRequest::CreateStubForTesting());

  copy_layer->AddChild(copy_child);
  copy_parent->AddChild(copy_layer);
  root->AddChild(copy_parent);

  host()->SetRootLayer(root);

  CommitAndActivate();

  // We should have two render surface, as the others are clipped out.
  ASSERT_EQ(2u, GetRenderSurfaceList().size());
  EXPECT_EQ(static_cast<uint64_t>(root->id()),
            GetRenderSurfaceList().at(0)->id());

  // The root render surface should have only 2 contributing layer, since the
  // other layers are clipped away.
  ASSERT_EQ(2, GetRenderSurfaceImpl(root)->num_contributors());
  EXPECT_TRUE(ImplOf(root)->contributes_to_drawn_render_surface());
}

// Needs layer tree mode: copy request.
TEST_F(DrawPropertiesTestWithLayerTree, SingularTransformAndCopyRequests) {
  auto root = Layer::Create();
  host()->SetRootLayer(root);
  root->SetBounds(gfx::Size(50, 50));
  root->SetIsDrawable(true);

  auto singular_transform_layer = Layer::Create();
  root->AddChild(singular_transform_layer);
  singular_transform_layer->SetBounds(gfx::Size(100, 100));
  singular_transform_layer->SetIsDrawable(true);
  gfx::Transform singular;
  singular.Scale3d(6.f, 6.f, 0.f);
  singular_transform_layer->SetTransform(singular);

  auto copy_layer = Layer::Create();
  singular_transform_layer->AddChild(copy_layer);
  copy_layer->SetBounds(gfx::Size(100, 100));
  copy_layer->SetIsDrawable(true);
  copy_layer->RequestCopyOfOutput(
      viz::CopyOutputRequest::CreateStubForTesting());

  auto copy_child = Layer::Create();
  copy_layer->AddChild(copy_child);
  copy_child->SetBounds(gfx::Size(100, 100));
  copy_child->SetIsDrawable(true);

  auto copy_grand_child = Layer::Create();
  copy_child->AddChild(copy_grand_child);
  copy_grand_child->SetBounds(gfx::Size(100, 100));
  copy_grand_child->SetIsDrawable(true);
  copy_grand_child->SetTransform(singular);

  ASSERT_TRUE(copy_layer->HasCopyRequest());
  CommitAndActivate();
  ASSERT_FALSE(copy_layer->HasCopyRequest());

  // A layer with singular transform should not contribute to drawn render
  // surface.
  EXPECT_FALSE(
      ImplOf(singular_transform_layer)->contributes_to_drawn_render_surface());
  // Even though copy_layer and copy_child have singular screen space transform,
  // they still contribute to drawn render surface as their transform to the
  // closest ancestor with copy request is not singular.
  EXPECT_TRUE(ImplOf(copy_layer)->contributes_to_drawn_render_surface());
  EXPECT_TRUE(ImplOf(copy_child)->contributes_to_drawn_render_surface());
  // copy_grand_child's transform to its closest ancestor with copy request is
  // also singular. So, it doesn't contribute to drawn render surface.
  EXPECT_FALSE(ImplOf(copy_grand_child)->contributes_to_drawn_render_surface());
}

// Needs layer tree mode: copy request.
TEST_F(DrawPropertiesTestWithLayerTree, VisibleRectInNonRootCopyRequest) {
  auto root = Layer::Create();
  host()->SetRootLayer(root);
  root->SetBounds(gfx::Size(50, 50));
  root->SetIsDrawable(true);
  root->SetMasksToBounds(true);

  auto copy_layer = Layer::Create();
  root->AddChild(copy_layer);
  copy_layer->SetBounds(gfx::Size(100, 100));
  copy_layer->SetIsDrawable(true);
  copy_layer->SetForceRenderSurfaceForTesting(true);

  auto copy_child = Layer::Create();
  copy_layer->AddChild(copy_child);
  copy_child->SetPosition(gfx::PointF(40.f, 40.f));
  copy_child->SetBounds(gfx::Size(20, 20));
  copy_child->SetIsDrawable(true);

  auto copy_clip = Layer::Create();
  copy_layer->AddChild(copy_clip);
  copy_clip->SetBounds(gfx::Size(55, 55));
  copy_clip->SetMasksToBounds(true);

  auto copy_clipped_child = Layer::Create();
  copy_clip->AddChild(copy_clipped_child);
  copy_clipped_child->SetPosition(gfx::PointF(40.f, 40.f));
  copy_clipped_child->SetBounds(gfx::Size(20, 20));
  copy_clipped_child->SetIsDrawable(true);

  auto copy_surface = Layer::Create();
  copy_clip->AddChild(copy_surface);
  copy_surface->SetPosition(gfx::PointF(45.f, 45.f));
  copy_surface->SetBounds(gfx::Size(20, 20));
  copy_surface->SetIsDrawable(true);
  copy_surface->SetForceRenderSurfaceForTesting(true);

  copy_layer->RequestCopyOfOutput(
      viz::CopyOutputRequest::CreateStubForTesting());
  ASSERT_TRUE(copy_layer->HasCopyRequest());
  CommitAndActivate();
  ASSERT_FALSE(copy_layer->HasCopyRequest());

  EXPECT_EQ(gfx::Rect(100, 100), ImplOf(copy_layer)->visible_layer_rect());
  EXPECT_EQ(gfx::Rect(20, 20), ImplOf(copy_child)->visible_layer_rect());
  EXPECT_EQ(gfx::Rect(15, 15),
            ImplOf(copy_clipped_child)->visible_layer_rect());
  EXPECT_EQ(gfx::Rect(10, 10), ImplOf(copy_surface)->visible_layer_rect());

  // Case 2: When the non root copy request layer is clipped.
  copy_layer->SetBounds(gfx::Size(50, 50));
  copy_layer->SetMasksToBounds(true);
  copy_layer->RequestCopyOfOutput(
      viz::CopyOutputRequest::CreateStubForTesting());
  ASSERT_TRUE(copy_layer->HasCopyRequest());
  CommitAndActivate();
  ASSERT_FALSE(copy_layer->HasCopyRequest());

  EXPECT_EQ(gfx::Rect(50, 50), ImplOf(copy_layer)->visible_layer_rect());
  EXPECT_EQ(gfx::Rect(10, 10), ImplOf(copy_child)->visible_layer_rect());
  EXPECT_EQ(gfx::Rect(10, 10),
            ImplOf(copy_clipped_child)->visible_layer_rect());
  EXPECT_EQ(gfx::Rect(5, 5), ImplOf(copy_surface)->visible_layer_rect());

  // Case 3: When there is device scale factor.
  SetDeviceScaleAndUpdateViewportRect(host(), 2.f);
  copy_layer->RequestCopyOfOutput(
      viz::CopyOutputRequest::CreateStubForTesting());

  ASSERT_TRUE(copy_layer->HasCopyRequest());
  CommitAndActivate();
  ASSERT_FALSE(copy_layer->HasCopyRequest());

  EXPECT_EQ(gfx::Rect(50, 50), ImplOf(copy_layer)->visible_layer_rect());
  EXPECT_EQ(gfx::Rect(10, 10), ImplOf(copy_child)->visible_layer_rect());
  EXPECT_EQ(gfx::Rect(10, 10),
            ImplOf(copy_clipped_child)->visible_layer_rect());
  EXPECT_EQ(gfx::Rect(5, 5), ImplOf(copy_surface)->visible_layer_rect());
}

TEST_F(DrawPropertiesTest, TransformedClipParent) {
  // Ensure that a transform between the layer and its render surface is not a
  // problem. Constructs the following layer tree.
  //
  // Virtual layer tree:
  //   root (a render surface)
  //     + render_surface
  //       + clip_parent (scaled)
  //         + intervening_clipping_layer
  //           + clip_child (clipped_by_clip_parent)
  //
  // The render surface should be resized correctly and the clip child should
  // inherit the right clip rect.
  LayerImpl* root = root_layer();
  root->SetBounds(gfx::Size(50, 50));

  LayerImpl* render_surface = AddLayer<LayerImpl>();
  render_surface->SetBounds(gfx::Size(10, 10));
  CopyProperties(root, render_surface);
  CreateEffectNode(render_surface).render_surface_reason =
      RenderSurfaceReason::kTest;

  LayerImpl* clip_parent = AddLayer<LayerImpl>();
  clip_parent->SetDrawsContent(true);
  clip_parent->SetBounds(gfx::Size(10, 10));
  CopyProperties(render_surface, clip_parent);
  auto& clip_parent_transform = CreateTransformNode(clip_parent);
  clip_parent_transform.local.Scale(2, 2);
  clip_parent_transform.post_translation = gfx::Vector2dF(1, 1);
  CreateClipNode(clip_parent);

  LayerImpl* intervening = AddLayer<LayerImpl>();
  intervening->SetDrawsContent(true);
  intervening->SetBounds(gfx::Size(5, 5));
  intervening->SetOffsetToTransformParent(gfx::Vector2dF(1, 1));
  CopyProperties(clip_parent, intervening);
  CreateClipNode(intervening);

  LayerImpl* clip_child = AddLayer<LayerImpl>();
  clip_child->SetDrawsContent(true);
  clip_child->SetBounds(gfx::Size(10, 10));
  clip_child->SetOffsetToTransformParent(gfx::Vector2dF(2, 2));
  CopyProperties(intervening, clip_child);
  clip_child->SetClipTreeIndex(clip_parent->clip_tree_index());

  UpdateActiveTreeDrawProperties();

  ASSERT_TRUE(GetRenderSurface(root));
  ASSERT_TRUE(GetRenderSurface(render_surface));

  // Ensure that we've inherited our clip parent's clip and weren't affected
  // by the intervening clip layer.
  ASSERT_EQ(gfx::Rect(1, 1, 20, 20), clip_parent->clip_rect());
  ASSERT_EQ(clip_parent->clip_rect(), clip_child->clip_rect());
  ASSERT_EQ(gfx::Rect(3, 3, 10, 10), intervening->clip_rect());

  // Ensure that the render surface reports a content rect that has been grown
  // to accomodate for the clip child.
  ASSERT_EQ(gfx::Rect(1, 1, 20, 20),
            GetRenderSurface(render_surface)->content_rect());

  // The above check implies the two below, but they nicely demonstrate that
  // we've grown, despite the intervening layer's clip.
  ASSERT_TRUE(clip_parent->clip_rect().Contains(
      GetRenderSurface(render_surface)->content_rect()));
  ASSERT_FALSE(intervening->clip_rect().Contains(
      GetRenderSurface(render_surface)->content_rect()));
}

TEST_F(DrawPropertiesTest, ClipParentWithInterveningRenderSurface) {
  // Ensure that intervening render surfaces are not a problem in the basic
  // case. In the following tree, both render surfaces should be resized to
  // accomodate for the clip child, despite an intervening clip.
  //
  // Virtual layer tree:
  //   root (a render surface)
  //    + clip_parent (clips)
  //      + render_surface1 (sets opacity)
  //        + intervening (clips)
  //          + render_surface2 (also sets opacity)
  //            + clip_child (clipped by clip_parent)
  //
  LayerImpl* root = root_layer();
  LayerImpl* clip_parent = AddLayer<LayerImpl>();
  LayerImpl* render_surface1 = AddLayer<LayerImpl>();
  LayerImpl* intervening = AddLayer<LayerImpl>();
  LayerImpl* render_surface2 = AddLayer<LayerImpl>();
  LayerImpl* clip_child = AddLayer<LayerImpl>();

  root->SetBounds(gfx::Size(50, 50));

  clip_parent->SetBounds(gfx::Size(40, 40));
  clip_parent->SetOffsetToTransformParent(gfx::Vector2dF(1, 1));
  CopyProperties(root, clip_parent);
  CreateClipNode(clip_parent);

  render_surface1->SetDrawsContent(true);
  render_surface1->SetBounds(gfx::Size(10, 10));
  CopyProperties(clip_parent, render_surface1);
  CreateTransformNode(render_surface1).post_translation = gfx::Vector2dF(1, 1);
  CreateEffectNode(render_surface1).render_surface_reason =
      RenderSurfaceReason::kTest;

  intervening->SetBounds(gfx::Size(5, 5));
  intervening->SetOffsetToTransformParent(gfx::Vector2dF(1, 1));
  CopyProperties(render_surface1, intervening);
  CreateClipNode(intervening);

  render_surface2->SetDrawsContent(true);
  render_surface2->SetBounds(gfx::Size(10, 10));
  CopyProperties(intervening, render_surface2);
  CreateTransformNode(render_surface2).post_translation = gfx::Vector2dF(1, 1);
  CreateEffectNode(render_surface2).render_surface_reason =
      RenderSurfaceReason::kTest;

  clip_child->SetBounds(gfx::Size(60, 60));
  clip_child->SetDrawsContent(true);
  clip_child->SetOffsetToTransformParent(gfx::Vector2dF(-10, -10));
  CopyProperties(render_surface2, clip_child);
  clip_child->SetClipTreeIndex(clip_parent->clip_tree_index());

  UpdateActiveTreeDrawProperties();

  EXPECT_TRUE(GetRenderSurface(root));
  EXPECT_TRUE(GetRenderSurface(render_surface1));
  EXPECT_TRUE(GetRenderSurface(render_surface2));

  // render_surface1 should apply the clip from clip_parent. Though there is a
  // clip child, render_surface1 can apply the clip as there are no clips
  // between the clip parent and render_surface1
  EXPECT_EQ(gfx::Rect(1, 1, 40, 40),
            GetRenderSurface(render_surface1)->clip_rect());
  EXPECT_TRUE(GetRenderSurface(render_surface1)->is_clipped());
  EXPECT_EQ(gfx::Rect(), render_surface1->clip_rect());
  EXPECT_FALSE(render_surface1->is_clipped());

  // render_surface2 could have expanded, as there is a clip between
  // clip_child's clip (clip_parent) and render_surface2's clip (intervening).
  // So, it should not be clipped (their bounds would no longer be reliable).
  // We should resort to layer clipping in this case.
  EXPECT_EQ(gfx::Rect(0, 0, 0, 0),
            GetRenderSurface(render_surface2)->clip_rect());
  EXPECT_FALSE(GetRenderSurface(render_surface2)->is_clipped());

  // This value is inherited from the clipping ancestor layer, 'intervening'.
  EXPECT_EQ(gfx::Rect(0, 0, 5, 5), render_surface2->clip_rect());
  EXPECT_TRUE(render_surface2->is_clipped());

  // The content rects of render_surface2 should have expanded to contain the
  // clip child.
  EXPECT_EQ(gfx::Rect(0, 0, 40, 40),
            GetRenderSurface(render_surface1)->content_rect());
  EXPECT_EQ(gfx::Rect(-10, -10, 60, 60),
            GetRenderSurface(render_surface2)->content_rect());

  // The clip child should have inherited the clip parent's clip (projected to
  // the right space, of course), but as render_surface1 already applies that
  // clip, clip_child need not apply it again.
  EXPECT_EQ(gfx::Rect(), clip_child->clip_rect());
  EXPECT_EQ(gfx::Rect(9, 9, 40, 40), clip_child->visible_layer_rect());
  EXPECT_FALSE(clip_child->is_clipped());
}

TEST_F(DrawPropertiesTest, ClipParentScrolledInterveningLayer) {
  // Ensure that intervening render surfaces are not a problem, even if there
  // is a scroll involved. Note, we do _not_ have to consider any other sort
  // of transform.
  //
  // Virtual layer tree:
  //   root (a render surface)
  //    + clip_parent (clips and transforms)
  //      + render_surface1 (has render surface)
  //        + intervening (clips AND scrolls)
  //          + render_surface2 (also has render surface)
  //            + clip_child (clipped by clip_parent)
  //
  LayerImpl* root = root_layer();
  LayerImpl* clip_parent = AddLayer<LayerImpl>();
  LayerImpl* render_surface1 = AddLayer<LayerImpl>();
  LayerImpl* intervening = AddLayer<LayerImpl>();
  LayerImpl* render_surface2 = AddLayer<LayerImpl>();
  LayerImpl* clip_child = AddLayer<LayerImpl>();

  root->SetBounds(gfx::Size(50, 50));

  clip_parent->SetBounds(gfx::Size(40, 40));
  CopyProperties(root, clip_parent);
  auto& clip_parent_transform = CreateTransformNode(clip_parent);
  clip_parent_transform.local.Translate(2, 2);
  clip_parent_transform.post_translation = gfx::Vector2dF(1, 1);
  CreateClipNode(clip_parent);

  render_surface1->SetDrawsContent(true);
  render_surface1->SetBounds(gfx::Size(10, 10));
  CopyProperties(clip_parent, render_surface1);
  CreateEffectNode(render_surface1).render_surface_reason =
      RenderSurfaceReason::kTest;

  intervening->SetBounds(gfx::Size(5, 5));
  intervening->SetScrollable(gfx::Size(1, 1));
  intervening->SetElementId(LayerIdToElementIdForTesting(intervening->id()));
  CopyProperties(render_surface1, intervening);
  CreateTransformNode(intervening).post_translation = gfx::Vector2dF(1, 1);
  CreateScrollNode(intervening);
  CreateClipNode(intervening);

  render_surface2->SetDrawsContent(true);
  render_surface2->SetBounds(gfx::Size(10, 10));
  CopyProperties(intervening, render_surface2);
  CreateTransformNode(render_surface2);
  CreateEffectNode(render_surface2).render_surface_reason =
      RenderSurfaceReason::kTest;

  clip_child->SetBounds(gfx::Size(60, 60));
  clip_child->SetDrawsContent(true);
  clip_child->SetOffsetToTransformParent(gfx::Vector2dF(-10, -10));
  CopyProperties(render_surface2, clip_child);
  clip_child->SetClipTreeIndex(clip_parent->clip_tree_index());

  SetScrollOffset(intervening, gfx::ScrollOffset(3, 3));
  UpdateActiveTreeDrawProperties();

  EXPECT_TRUE(GetRenderSurface(root));
  EXPECT_TRUE(GetRenderSurface(render_surface1));
  EXPECT_TRUE(GetRenderSurface(render_surface2));

  // render_surface1 should apply the clip from clip_parent. Though there is a
  // clip child, render_surface1 can apply the clip as there are no clips
  // between the clip parent and render_surface1
  EXPECT_EQ(gfx::Rect(3, 3, 40, 40),
            GetRenderSurface(render_surface1)->clip_rect());
  EXPECT_TRUE(GetRenderSurface(render_surface1)->is_clipped());
  EXPECT_EQ(gfx::Rect(), render_surface1->clip_rect());
  EXPECT_FALSE(render_surface1->is_clipped());

  // render_surface2 could have expanded, as there is a clip between
  // clip_child's clip (clip_parent) and render_surface2's clip (intervening).
  // So, it should not be clipped (their bounds would no longer be reliable).
  // We should resort to layer clipping in this case.
  EXPECT_EQ(gfx::Rect(0, 0, 0, 0),
            GetRenderSurface(render_surface2)->clip_rect());
  EXPECT_FALSE(GetRenderSurface(render_surface2)->is_clipped());
  // This value is inherited from the clipping ancestor layer, 'intervening'.
  EXPECT_EQ(gfx::Rect(0, 0, 5, 5), render_surface2->clip_rect());
  EXPECT_TRUE(render_surface2->is_clipped());

  // The content rects of render_surface2 should have expanded to contain the
  // clip child.
  EXPECT_EQ(gfx::Rect(0, 0, 40, 40),
            GetRenderSurface(render_surface1)->content_rect());
  EXPECT_EQ(gfx::Rect(-10, -10, 60, 60),
            GetRenderSurface(render_surface2)->content_rect());

  // The clip child should have inherited the clip parent's clip (projected to
  // the right space, of course), but as render_surface1 already applies that
  // clip, clip_child need not apply it again.
  EXPECT_EQ(gfx::Rect(), clip_child->clip_rect());
  EXPECT_EQ(gfx::Rect(12, 12, 40, 40), clip_child->visible_layer_rect());
  EXPECT_FALSE(clip_child->is_clipped());
}

TEST_F(DrawPropertiesTest, DescendantsOfClipChildren) {
  // Ensures that descendants of the clip child inherit the correct clip.
  //
  // Virtual layer tree:
  //   root (a render surface)
  //    + clip_parent (clips)
  //      + intervening (clips)
  //        + clip_child (clipped by clip_parent, skipping intervening)
  //          + child
  //
  LayerImpl* root = root_layer();
  LayerImpl* clip_parent = AddLayer<LayerImpl>();
  LayerImpl* intervening = AddLayer<LayerImpl>();
  LayerImpl* clip_child = AddLayer<LayerImpl>();
  LayerImpl* child = AddLayer<LayerImpl>();

  root->SetBounds(gfx::Size(50, 50));

  clip_parent->SetBounds(gfx::Size(40, 40));
  CopyProperties(root, clip_parent);
  CreateClipNode(clip_parent);

  intervening->SetBounds(gfx::Size(5, 5));
  CopyProperties(clip_parent, intervening);
  CreateClipNode(intervening);

  clip_child->SetDrawsContent(true);
  clip_child->SetBounds(gfx::Size(60, 60));
  CopyProperties(intervening, clip_child);
  clip_child->SetClipTreeIndex(clip_parent->clip_tree_index());

  child->SetDrawsContent(true);
  child->SetBounds(gfx::Size(60, 60));
  CopyProperties(clip_child, child);

  UpdateActiveTreeDrawProperties();

  EXPECT_TRUE(GetRenderSurface(root));

  // Neither the clip child nor its descendant should have inherited the clip
  // from |intervening|.
  EXPECT_EQ(gfx::Rect(0, 0, 40, 40), clip_child->clip_rect());
  EXPECT_TRUE(clip_child->is_clipped());
  EXPECT_EQ(gfx::Rect(0, 0, 40, 40), child->visible_layer_rect());
  EXPECT_TRUE(child->is_clipped());
}

TEST_F(DrawPropertiesTest,
       SurfacesShouldBeUnaffectedByNonDescendantClipChildren) {
  // Ensures that non-descendant clip children in the tree do not affect
  // render surfaces.
  //
  //   root (a render surface)
  //    + clip_parent (clips)
  //      + clip_layer (clips)
  //        + render_surface1
  //          + clip_child (clipped by clip_parent)
  //        + render_surface2
  //          + non_clip_child (in normal clip hierarchy)
  //
  // In this example render_surface2 should be unaffected by clip_child.
  LayerImpl* root = root_layer();
  LayerImpl* clip_parent = AddLayer<LayerImpl>();
  LayerImpl* clip_layer = AddLayer<LayerImpl>();
  LayerImpl* render_surface1 = AddLayer<LayerImpl>();
  LayerImpl* clip_child = AddLayer<LayerImpl>();
  LayerImpl* render_surface2 = AddLayer<LayerImpl>();
  LayerImpl* non_clip_child = AddLayer<LayerImpl>();

  root->SetBounds(gfx::Size(15, 15));
  clip_parent->SetBounds(gfx::Size(10, 10));
  clip_layer->SetBounds(gfx::Size(10, 10));
  render_surface1->SetDrawsContent(true);
  render_surface1->SetBounds(gfx::Size(5, 5));
  render_surface2->SetDrawsContent(true);
  render_surface2->SetBounds(gfx::Size(5, 5));
  clip_child->SetDrawsContent(true);
  clip_child->SetOffsetToTransformParent(gfx::Vector2dF(-1, 1));
  clip_child->SetBounds(gfx::Size(10, 10));
  non_clip_child->SetDrawsContent(true);
  non_clip_child->SetBounds(gfx::Size(5, 5));

  CopyProperties(root, clip_parent);
  CreateClipNode(clip_parent);
  CopyProperties(clip_parent, clip_layer);
  CreateClipNode(clip_layer);
  CopyProperties(clip_layer, render_surface1);
  CreateTransformNode(render_surface1).post_translation = gfx::Vector2dF(5, 5);
  CreateEffectNode(render_surface1).render_surface_reason =
      RenderSurfaceReason::kTest;
  CopyProperties(clip_layer, render_surface2);
  CreateTransformNode(render_surface2).post_translation = gfx::Vector2dF(5, 5);
  CreateEffectNode(render_surface2).render_surface_reason =
      RenderSurfaceReason::kTest;
  CopyProperties(render_surface1, clip_child);
  clip_child->SetClipTreeIndex(clip_parent->clip_tree_index());
  CopyProperties(render_surface2, non_clip_child);

  UpdateActiveTreeDrawProperties();

  EXPECT_TRUE(GetRenderSurface(root));
  EXPECT_TRUE(GetRenderSurface(render_surface1));
  EXPECT_TRUE(GetRenderSurface(render_surface2));

  EXPECT_EQ(gfx::Rect(-5, -5, 10, 10), render_surface1->clip_rect());
  EXPECT_TRUE(render_surface1->is_clipped());

  // The render surface should not clip (it has unclipped descendants), instead
  // it should rely on layer clipping.
  EXPECT_EQ(gfx::Rect(0, 0, 0, 0),
            GetRenderSurface(render_surface1)->clip_rect());
  EXPECT_FALSE(GetRenderSurface(render_surface1)->is_clipped());

  // That said, it should have grown to accomodate the unclipped descendant and
  // its own size.
  EXPECT_EQ(gfx::Rect(-1, 0, 6, 5),
            GetRenderSurface(render_surface1)->content_rect());

  // This render surface should clip. It has no unclipped descendants.
  EXPECT_EQ(gfx::Rect(0, 0, 10, 10),
            GetRenderSurface(render_surface2)->clip_rect());
  EXPECT_TRUE(GetRenderSurface(render_surface2)->is_clipped());
  EXPECT_FALSE(render_surface2->is_clipped());

  // It also shouldn't have grown to accomodate the clip child.
  EXPECT_EQ(gfx::Rect(0, 0, 5, 5),
            GetRenderSurface(render_surface2)->content_rect());
}

TEST_F(DrawPropertiesTest, TransformAnimationUpdatesBackfaceVisibility) {
  LayerImpl* root = root_layer();
  LayerImpl* back_facing = AddLayer<LayerImpl>();
  LayerImpl* render_surface1 = AddLayer<LayerImpl>();
  LayerImpl* render_surface2 = AddLayer<LayerImpl>();

  gfx::Transform rotate_about_y;
  rotate_about_y.RotateAboutYAxis(180.0);

  root->SetBounds(gfx::Size(50, 50));
  back_facing->SetBounds(gfx::Size(50, 50));
  render_surface1->SetBounds(gfx::Size(30, 30));
  render_surface2->SetBounds(gfx::Size(30, 30));
  SetElementIdsForTesting();

  CopyProperties(root, back_facing);
  auto& back_facing_transform_node = CreateTransformNode(back_facing);
  back_facing_transform_node.flattens_inherited_transform = false;
  back_facing_transform_node.sorting_context_id = 1;
  back_facing_transform_node.local = rotate_about_y;
  CopyProperties(back_facing, render_surface1);
  auto& render_surface1_transform_node = CreateTransformNode(render_surface1);
  render_surface1_transform_node.flattens_inherited_transform = false;
  render_surface1_transform_node.sorting_context_id = 1;
  auto& render_surface1_effect_node = CreateEffectNode(render_surface1);
  render_surface1_effect_node.render_surface_reason =
      RenderSurfaceReason::kTest;
  render_surface1_effect_node.double_sided = false;
  CopyProperties(back_facing, render_surface2);
  auto& render_surface2_transform_node = CreateTransformNode(render_surface2);
  render_surface2_transform_node.flattens_inherited_transform = false;
  render_surface2_transform_node.sorting_context_id = 1;
  auto& render_surface2_effect_node = CreateEffectNode(render_surface2);
  render_surface2_effect_node.render_surface_reason =
      RenderSurfaceReason::kTest;
  render_surface2_effect_node.double_sided = false;

  UpdateActiveTreeDrawProperties();

  EXPECT_TRUE(GetEffectNode(render_surface1)->hidden_by_backface_visibility);
  EXPECT_TRUE(GetEffectNode(render_surface2)->hidden_by_backface_visibility);

  root->layer_tree_impl()->SetTransformMutated(back_facing->element_id(),
                                               gfx::Transform());
  root->layer_tree_impl()->SetTransformMutated(render_surface2->element_id(),
                                               rotate_about_y);
  UpdateActiveTreeDrawProperties();
  EXPECT_FALSE(GetEffectNode(render_surface1)->hidden_by_backface_visibility);
  EXPECT_TRUE(GetEffectNode(render_surface2)->hidden_by_backface_visibility);

  root->layer_tree_impl()->SetTransformMutated(render_surface1->element_id(),
                                               rotate_about_y);
  UpdateActiveTreeDrawProperties();
  EXPECT_TRUE(GetEffectNode(render_surface1)->hidden_by_backface_visibility);
  EXPECT_TRUE(GetEffectNode(render_surface2)->hidden_by_backface_visibility);
}

TEST_F(DrawPropertiesTest, ScrollChildAndScrollParentDifferentTargets) {
  // Tests the computation of draw transform for the scroll child when its
  // render surface is different from its scroll parent's render surface.
  LayerImpl* root = root_layer();
  LayerImpl* scroll_child_target = AddLayer<LayerImpl>();
  LayerImpl* scroll_child = AddLayer<LayerImpl>();
  LayerImpl* scroll_parent_target = AddLayer<LayerImpl>();
  LayerImpl* scroll_parent = AddLayer<LayerImpl>();

  root->SetBounds(gfx::Size(50, 50));
  scroll_child_target->SetBounds(gfx::Size(50, 50));
  scroll_parent_target->SetBounds(gfx::Size(50, 50));
  scroll_parent->SetBounds(gfx::Size(50, 50));
  scroll_parent->SetDrawsContent(true);
  scroll_child->SetBounds(gfx::Size(50, 50));
  scroll_child->SetDrawsContent(true);

  CopyProperties(root, scroll_child_target);
  auto& child_target_effect_node = CreateEffectNode(scroll_child_target);
  child_target_effect_node.render_surface_reason = RenderSurfaceReason::kTest;
  CopyProperties(scroll_child_target, scroll_parent_target);
  CreateTransformNode(scroll_parent_target).post_translation =
      gfx::Vector2dF(10, 10);
  CreateScrollNode(scroll_parent_target);
  CreateEffectNode(scroll_parent_target).render_surface_reason =
      RenderSurfaceReason::kTest;
  CreateClipNode(scroll_parent_target);
  CopyProperties(scroll_parent_target, scroll_parent);
  // Let |scroll_child| inherit |scroll_parent|'s transform/clip/scroll states,
  CopyProperties(scroll_parent, scroll_child);
  // and |scroll_child_target|'s effect state.
  scroll_child->SetEffectTreeIndex(scroll_child_target->effect_tree_index());
  scroll_child->SetOffsetToTransformParent(gfx::Vector2dF(-10, -10));

  float device_scale_factor = 1.5f;
  UpdateActiveTreeDrawProperties(device_scale_factor);
  EXPECT_EQ(scroll_child->effect_tree_index(),
            scroll_child_target->effect_tree_index());
  EXPECT_EQ(scroll_child->visible_layer_rect(), gfx::Rect(10, 10, 40, 40));
  EXPECT_EQ(scroll_child->clip_rect(), gfx::Rect(15, 15, 75, 75));
  gfx::Transform scale;
  scale.Scale(device_scale_factor, device_scale_factor);
  EXPECT_TRANSFORMATION_MATRIX_EQ(scroll_child->DrawTransform(), scale);
}

TEST_F(DrawPropertiesTest, SingularTransformSubtreesDoNotDraw) {
  LayerImpl* root = root_layer();
  LayerImpl* parent = AddLayer<LayerImpl>();
  LayerImpl* child = AddLayer<LayerImpl>();

  root->SetBounds(gfx::Size(50, 50));
  root->SetDrawsContent(true);
  parent->SetBounds(gfx::Size(30, 30));
  parent->SetDrawsContent(true);
  child->SetBounds(gfx::Size(20, 20));
  child->SetDrawsContent(true);

  CopyProperties(root, parent);
  CreateTransformNode(parent).sorting_context_id = 1;
  CreateEffectNode(parent).render_surface_reason = RenderSurfaceReason::kTest;
  CopyProperties(parent, child);
  CreateTransformNode(child).sorting_context_id = 1;
  CreateEffectNode(child).render_surface_reason = RenderSurfaceReason::kTest;

  UpdateActiveTreeDrawProperties();

  EXPECT_EQ(3u, GetRenderSurfaceList().size());

  gfx::Transform singular_transform;
  singular_transform.Scale3d(SkDoubleToMScalar(1.0), SkDoubleToMScalar(1.0),
                             SkDoubleToMScalar(0.0));

  SetTransform(child, singular_transform);
  UpdateActiveTreeDrawProperties();

  EXPECT_EQ(2u, GetRenderSurfaceList().size());

  // Ensure that the entire subtree under a layer with singular transform does
  // not get rendered.
  SetTransform(parent, singular_transform);
  SetTransform(child, gfx::Transform());
  UpdateActiveTreeDrawProperties();

  EXPECT_EQ(1u, GetRenderSurfaceList().size());
}

TEST_F(DrawPropertiesTest, ScrollSnapping) {
  // This test verifies that a scrolling layer gets scroll offset snapped to
  // integer coordinates.
  //
  // Virtual layer hierarchy:
  // + root
  //   + container
  //     + scroller
  //
  LayerImpl* root = root_layer();
  LayerImpl* container = AddLayer<LayerImpl>();
  LayerImpl* scroller = AddLayer<LayerImpl>();

  root->SetBounds(gfx::Size(50, 50));

  container->SetBounds(gfx::Size(40, 40));
  container->SetDrawsContent(true);
  CopyProperties(root, container);

  gfx::Vector2dF container_offset(10, 20);

  scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id()));
  scroller->SetBounds(gfx::Size(30, 30));
  scroller->SetScrollable(container->bounds());
  scroller->SetDrawsContent(true);
  CopyProperties(container, scroller);
  CreateTransformNode(scroller).post_translation = container_offset;
  CreateScrollNode(scroller);

  // Rounded to integers already.
  {
    gfx::Vector2dF scroll_delta(3.0, 5.0);
    SetScrollOffsetDelta(scroller, scroll_delta);
    UpdateActiveTreeDrawProperties();

    EXPECT_VECTOR_EQ(
        scroller->draw_properties().screen_space_transform.To2dTranslation(),
        container_offset - scroll_delta);
  }

  // Scroll delta requiring rounding.
  {
    gfx::Vector2dF scroll_delta(4.1f, 8.1f);
    SetScrollOffsetDelta(scroller, scroll_delta);
    UpdateActiveTreeDrawProperties();

    gfx::Vector2dF rounded_scroll_delta(4.f, 8.f);
    EXPECT_VECTOR_EQ(
        scroller->draw_properties().screen_space_transform.To2dTranslation(),
        container_offset - rounded_scroll_delta);
  }
}

TEST_F(DrawPropertiesTest, ScrollSnappingWithAnimatedScreenSpaceTransform) {
  // This test verifies that a scrolling layer whose screen space transform is
  // animating doesn't get snapped to integer coordinates.
  //
  // Virtual layer hierarchy:
  // + root
  //   + animated layer
  //     + surface
  //       + container
  //         + scroller
  //
  LayerImpl* root = root_layer();
  LayerImpl* animated_layer = AddLayer<FakePictureLayerImpl>();
  LayerImpl* surface = AddLayer<LayerImpl>();
  LayerImpl* container = AddLayer<LayerImpl>();
  LayerImpl* scroller = AddLayer<LayerImpl>();
  SetElementIdsForTesting();

  root->SetBounds(gfx::Size(50, 50));

  gfx::Transform start_scale;
  start_scale.Scale(1.5f, 1.5f);

  animated_layer->SetBounds(gfx::Size(50, 50));
  CopyProperties(root, animated_layer);
  CreateTransformNode(animated_layer).local = start_scale;

  surface->SetBounds(gfx::Size(50, 50));
  CopyProperties(animated_layer, surface);
  CreateEffectNode(surface).render_surface_reason = RenderSurfaceReason::kTest;

  container->SetBounds(gfx::Size(50, 50));
  CopyProperties(surface, container);

  scroller->SetBounds(gfx::Size(100, 100));
  scroller->SetScrollable(container->bounds());
  scroller->SetDrawsContent(true);
  CopyProperties(container, scroller);
  CreateTransformNode(scroller);
  CreateScrollNode(scroller);

  gfx::Transform end_scale;
  end_scale.Scale(2.f, 2.f);
  TransformOperations start_operations;
  start_operations.AppendMatrix(start_scale);
  TransformOperations end_operations;
  end_operations.AppendMatrix(end_scale);

  AddAnimatedTransformToElementWithAnimation(animated_layer->element_id(),
                                             timeline_impl(), 1.0,
                                             start_operations, end_operations);

  gfx::Vector2dF scroll_delta(5.f, 9.f);
  SetScrollOffsetDelta(scroller, scroll_delta);

  UpdateActiveTreeDrawProperties();

  gfx::Vector2dF expected_draw_transform_translation(-7.5f, -13.5f);
  EXPECT_VECTOR2DF_EQ(expected_draw_transform_translation,
                      scroller->DrawTransform().To2dTranslation());
}

TEST_F(DrawPropertiesTest, ScrollSnappingWithScrollChild) {
  // This test verifies that a scrolling child of a scrolling layer doesn't get
  // snapped to integer coordinates.
  //
  // Virtual layer hierarchy:
  // + root
  //   + container
  //     + scroller
  //   + scroll_child (transform parent is scroller)
  //
  LayerImpl* root = root_layer();
  LayerImpl* container = AddLayer<LayerImpl>();
  LayerImpl* scroller = AddLayer<LayerImpl>();
  LayerImpl* scroll_child = AddLayer<LayerImpl>();
  SetElementIdsForTesting();

  root->SetBounds(gfx::Size(50, 50));

  container->SetBounds(gfx::Size(50, 50));
  CopyProperties(root, container);
  gfx::Vector2dF container_offset(10.3f, 10.3f);

  scroller->SetBounds(gfx::Size(100, 100));
  scroller->SetScrollable(container->bounds());
  CopyProperties(container, scroller);
  CreateTransformNode(scroller).post_translation = container_offset;
  CreateScrollNode(scroller);

  scroll_child->SetBounds(gfx::Size(10, 10));
  CopyProperties(root, scroll_child);
  auto& scroll_child_transform =
      CreateTransformNode(scroll_child, scroller->transform_tree_index());
  scroll_child_transform.local.RotateAboutYAxis(30);
  scroll_child_transform.post_translation = -container_offset;

  gfx::Vector2dF scroll_delta(5.f, 9.f);
  SetScrollOffsetDelta(scroller, scroll_delta);
  UpdateActiveTreeDrawProperties();

  gfx::Vector2dF expected_scroller_screen_space_transform_translation(5.f, 1.f);
  EXPECT_VECTOR2DF_EQ(expected_scroller_screen_space_transform_translation,
                      scroller->ScreenSpaceTransform().To2dTranslation());

  gfx::Transform expected_scroll_child_screen_space_transform;
  expected_scroll_child_screen_space_transform.Translate(-5.3f, -9.3f);
  expected_scroll_child_screen_space_transform.RotateAboutYAxis(30);
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_scroll_child_screen_space_transform,
                                  scroll_child->ScreenSpaceTransform());
}

class DrawPropertiesStickyPositionTest : public DrawPropertiesTest {
 protected:
  // Setup layers and property trees.
  // Virtual layer hierarchy:
  // + root
  //   + container
  //     + scroller
  //       + sticky_pos
  void CreateTree() {
    CreateRootAndScroller();
    sticky_pos_ = CreateSticky(scroller_.get());
  }

  void CreateRootAndScroller() {
    root_ = Layer::Create();
    container_ = Layer::Create();
    scroller_ = Layer::Create();
    scroller_->SetElementId(LayerIdToElementIdForTesting(scroller_->id()));

    root_->SetBounds(gfx::Size(100, 100));
    host()->SetRootLayer(root_);
    SetupRootProperties(root_.get());

    container_->SetBounds(gfx::Size(100, 100));
    CopyProperties(root_.get(), container_.get());
    root_->AddChild(container_);

    scroller_->SetBounds(gfx::Size(1000, 1000));
    scroller_->SetScrollable(container_->bounds());
    CopyProperties(container_.get(), scroller_.get());
    CreateTransformNode(scroller_.get());
    CreateScrollNode(scroller_.get());
    root_->AddChild(scroller_);
  }

  scoped_refptr<Layer> CreateSticky(Layer* parent) {
    scoped_refptr<Layer> sticky = Layer::Create();
    sticky->SetBounds(gfx::Size(10, 10));
    CopyProperties(parent, sticky.get());
    CreateTransformNode(sticky.get());
    EnsureStickyData(sticky.get()).scroll_ancestor =
        parent->scroll_tree_index();
    root_->AddChild(sticky);
    return sticky;
  }

  void CommitAndUpdateImplPointers() {
    UpdateMainDrawProperties();
    host_impl()->CreatePendingTree();
    host()->CommitAndCreatePendingTree();
    host_impl()->ActivateSyncTree();
    LayerTreeImpl* layer_tree_impl = host_impl()->active_tree();
    root_impl_ = layer_tree_impl->LayerById(root_->id());
    scroller_impl_ = layer_tree_impl->LayerById(scroller_->id());
    sticky_pos_impl_ = layer_tree_impl->LayerById(sticky_pos_->id());
  }

  StickyPositionNodeData& EnsureStickyData(Layer* layer) {
    return GetPropertyTrees(layer)->transform_tree.EnsureStickyPositionData(
        layer->transform_tree_index());
  }

  scoped_refptr<Layer> root_;
  scoped_refptr<Layer> container_;
  scoped_refptr<Layer> scroller_;
  scoped_refptr<Layer> sticky_pos_;
  LayerImpl* root_impl_;
  LayerImpl* scroller_impl_;
  LayerImpl* sticky_pos_impl_;
};

TEST_F(DrawPropertiesStickyPositionTest, StickyPositionTop) {
  CreateTree();

  SetPostTranslation(sticky_pos_.get(), gfx::Vector2dF(10, 20));
  auto& sticky_position = EnsureStickyData(sticky_pos_.get()).constraints;
  sticky_position.is_anchored_top = true;
  sticky_position.top_offset = 10.0f;
  sticky_position.scroll_container_relative_sticky_box_rect =
      gfx::Rect(10, 20, 10, 10);
  sticky_position.scroll_container_relative_containing_block_rect =
      gfx::Rect(0, 0, 50, 50);

  CommitAndUpdateImplPointers();

  EXPECT_VECTOR2DF_EQ(
      gfx::Vector2dF(10.f, 20.f),
      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());

  // Scroll less than sticking point, sticky element should move with scroll as
  // we haven't gotten to the initial sticky item location yet.
  SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(5.f, 5.f));

  UpdateActiveTreeDrawProperties();
  EXPECT_VECTOR2DF_EQ(
      gfx::Vector2dF(5.f, 15.f),
      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());

  // Scroll past the sticking point, the Y coordinate should now be clamped.
  SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(15.f, 15.f));
  UpdateActiveTreeDrawProperties();
  EXPECT_VECTOR2DF_EQ(
      gfx::Vector2dF(-5.f, 10.f),
      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
  SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(15.f, 25.f));
  UpdateActiveTreeDrawProperties();
  EXPECT_VECTOR2DF_EQ(
      gfx::Vector2dF(-5.f, 10.f),
      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());

  // Scroll past the end of the sticky container (note: this element does not
  // have its own layer as it does not need to be composited).
  SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(15.f, 50.f));
  UpdateActiveTreeDrawProperties();
  EXPECT_VECTOR2DF_EQ(
      gfx::Vector2dF(-5.f, -10.f),
      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
}

TEST_F(DrawPropertiesStickyPositionTest, StickyPositionSubpixelScroll) {
  CreateTree();

  SetPostTranslation(sticky_pos_.get(), gfx::Vector2dF(0, 200));
  auto& sticky_position = EnsureStickyData(sticky_pos_.get()).constraints;
  sticky_position.is_anchored_bottom = true;
  sticky_position.bottom_offset = 10.0f;
  sticky_position.constraint_box_rect = gfx::Rect(0, 0, 100, 100);
  sticky_position.scroll_container_relative_sticky_box_rect =
      gfx::Rect(0, 200, 10, 10);
  sticky_position.scroll_container_relative_containing_block_rect =
      gfx::Rect(0, 0, 100, 500);

  CommitAndUpdateImplPointers();

  SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 0.8f));

  UpdateActiveTreeDrawProperties();
  EXPECT_VECTOR2DF_EQ(
      gfx::Vector2dF(0.f, 80.f),
      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
}

TEST_F(DrawPropertiesStickyPositionTest, StickyPositionBottom) {
  CreateTree();

  SetPostTranslation(sticky_pos_.get(), gfx::Vector2dF(0, 150));
  auto& sticky_position = EnsureStickyData(sticky_pos_.get()).constraints;
  sticky_position.is_anchored_bottom = true;
  sticky_position.bottom_offset = 10.0f;
  sticky_position.constraint_box_rect = gfx::Rect(0, 0, 100, 100);
  sticky_position.scroll_container_relative_sticky_box_rect =
      gfx::Rect(0, 150, 10, 10);
  sticky_position.scroll_container_relative_containing_block_rect =
      gfx::Rect(0, 100, 50, 50);

  CommitAndUpdateImplPointers();

  // Initially the sticky element is moved up to the top of the container.
  EXPECT_VECTOR2DF_EQ(
      gfx::Vector2dF(0.f, 100.f),
      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
  SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 5.f));

  UpdateActiveTreeDrawProperties();
  EXPECT_VECTOR2DF_EQ(
      gfx::Vector2dF(0.f, 95.f),
      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());

  // Once we get past the top of the container it moves to be aligned 10px
  // up from the the bottom of the scroller.
  SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 25.f));
  UpdateActiveTreeDrawProperties();
  EXPECT_VECTOR2DF_EQ(
      gfx::Vector2dF(0.f, 80.f),
      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
  SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 30.f));
  UpdateActiveTreeDrawProperties();
  EXPECT_VECTOR2DF_EQ(
      gfx::Vector2dF(0.f, 80.f),
      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());

  // Once we scroll past its initial location, it sticks there.
  SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 150.f));
  UpdateActiveTreeDrawProperties();
  EXPECT_VECTOR2DF_EQ(
      gfx::Vector2dF(0.f, 0.f),
      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
}

TEST_F(DrawPropertiesStickyPositionTest,
       StickyPositionBottomOuterViewportDelta) {
  CreateTree();

  GetScrollNode(scroller_.get())->scrolls_outer_viewport = true;

  SetPostTranslation(sticky_pos_.get(), gfx::Vector2dF(0, 70));
  GetPropertyTrees(sticky_pos_.get())
      ->transform_tree.AddNodeAffectedByOuterViewportBoundsDelta(
          sticky_pos_->transform_tree_index());
  auto& sticky_position = EnsureStickyData(sticky_pos_.get()).constraints;
  sticky_position.is_anchored_bottom = true;
  sticky_position.bottom_offset = 10.0f;
  sticky_position.constraint_box_rect = gfx::Rect(0, 0, 100, 100);
  sticky_position.scroll_container_relative_sticky_box_rect =
      gfx::Rect(0, 70, 10, 10);
  sticky_position.scroll_container_relative_containing_block_rect =
      gfx::Rect(0, 60, 100, 100);

  CommitAndUpdateImplPointers();

  // Initially the sticky element is moved to the bottom of the container.
  EXPECT_VECTOR2DF_EQ(
      gfx::Vector2dF(0.f, 70.f),
      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());

  // We start to hide the toolbar, but not far enough that the sticky element
  // should be moved up yet.
  GetPropertyTrees(scroller_impl_)
      ->SetOuterViewportContainerBoundsDelta(gfx::Vector2dF(0.f, -10.f));

  UpdateActiveTreeDrawProperties();
  EXPECT_VECTOR2DF_EQ(
      gfx::Vector2dF(0.f, 70.f),
      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());

  // On hiding more of the toolbar the sticky element starts to stick.
  GetPropertyTrees(scroller_impl_)
      ->SetOuterViewportContainerBoundsDelta(gfx::Vector2dF(0.f, -20.f));
  UpdateActiveTreeDrawProperties();

  // On hiding more the sticky element stops moving as it has reached its
  // limit.
  EXPECT_VECTOR2DF_EQ(
      gfx::Vector2dF(0.f, 60.f),
      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());

  GetPropertyTrees(scroller_impl_)
      ->SetOuterViewportContainerBoundsDelta(gfx::Vector2dF(0.f, -30.f));
  UpdateActiveTreeDrawProperties();

  EXPECT_VECTOR2DF_EQ(
      gfx::Vector2dF(0.f, 60.f),
      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
}

TEST_F(DrawPropertiesStickyPositionTest, StickyPositionLeftRight) {
  CreateTree();

  SetPostTranslation(sticky_pos_.get(), gfx::Vector2dF(145, 0));
  auto& sticky_position = EnsureStickyData(sticky_pos_.get()).constraints;
  sticky_position.is_anchored_left = true;
  sticky_position.is_anchored_right = true;
  sticky_position.left_offset = 10.0f;
  sticky_position.right_offset = 10.0f;
  sticky_position.constraint_box_rect = gfx::Rect(0, 0, 100, 100);
  sticky_position.scroll_container_relative_sticky_box_rect =
      gfx::Rect(145, 0, 10, 10);
  sticky_position.scroll_container_relative_containing_block_rect =
      gfx::Rect(100, 0, 100, 100);

  CommitAndUpdateImplPointers();

  // Initially the sticky element is moved the leftmost side of the container.

  UpdateActiveTreeDrawProperties();
  EXPECT_VECTOR2DF_EQ(
      gfx::Vector2dF(100.f, 0.f),
      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
  SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(5.f, 0.f));
  UpdateActiveTreeDrawProperties();
  EXPECT_VECTOR2DF_EQ(
      gfx::Vector2dF(95.f, 0.f),
      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());

  // Once we get past the left side of the container it moves to be aligned 10px
  // up from the the right of the scroller.
  SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(25.f, 0.f));
  UpdateActiveTreeDrawProperties();
  EXPECT_VECTOR2DF_EQ(
      gfx::Vector2dF(80.f, 0.f),
      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
  SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(30.f, 0.f));
  UpdateActiveTreeDrawProperties();
  EXPECT_VECTOR2DF_EQ(
      gfx::Vector2dF(80.f, 0.f),
      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());

  // When we get to the sticky element's original position we stop sticking
  // to the right.
  SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(95.f, 0.f));
  UpdateActiveTreeDrawProperties();
  EXPECT_VECTOR2DF_EQ(
      gfx::Vector2dF(50.f, 0.f),
      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
  SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(105.f, 0.f));
  UpdateActiveTreeDrawProperties();
  EXPECT_VECTOR2DF_EQ(
      gfx::Vector2dF(40.f, 0.f),
      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());

  // The element starts sticking to the left once we scroll far enough.
  SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(150.f, 0.f));
  UpdateActiveTreeDrawProperties();
  EXPECT_VECTOR2DF_EQ(
      gfx::Vector2dF(10.f, 0.f),
      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
  SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(155.f, 0.f));
  UpdateActiveTreeDrawProperties();
  EXPECT_VECTOR2DF_EQ(
      gfx::Vector2dF(10.f, 0.f),
      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());

  // Finally it stops sticking when it hits the right side of the container.
  SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(190.f, 0.f));
  UpdateActiveTreeDrawProperties();
  EXPECT_VECTOR2DF_EQ(
      gfx::Vector2dF(0.f, 0.f),
      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
  SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(195.f, 0.f));
  UpdateActiveTreeDrawProperties();
  EXPECT_VECTOR2DF_EQ(
      gfx::Vector2dF(-5.f, 0.f),
      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
}

// This test ensures that the compositor sticky position code correctly accounts
// for the element having been given a position from the main thread sticky
// position code.
TEST_F(DrawPropertiesStickyPositionTest, StickyPositionMainThreadUpdates) {
  CreateTree();

  SetPostTranslation(sticky_pos_.get(), gfx::Vector2dF(10, 20));
  auto& sticky_position = EnsureStickyData(sticky_pos_.get()).constraints;
  sticky_position.is_anchored_top = true;
  sticky_position.top_offset = 10.0f;
  sticky_position.scroll_container_relative_sticky_box_rect =
      gfx::Rect(10, 20, 10, 10);
  sticky_position.scroll_container_relative_containing_block_rect =
      gfx::Rect(0, 0, 50, 50);

  CommitAndUpdateImplPointers();

  EXPECT_VECTOR2DF_EQ(
      gfx::Vector2dF(10.f, 20.f),
      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());

  // Scroll less than sticking point, sticky element should move with scroll as
  // we haven't gotten to the initial sticky item location yet.
  SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(5.f, 5.f));

  UpdateActiveTreeDrawProperties();
  EXPECT_VECTOR2DF_EQ(
      gfx::Vector2dF(5.f, 15.f),
      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());

  // Scroll past the sticking point, the Y coordinate should now be clamped.
  SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(15.f, 15.f));
  UpdateActiveTreeDrawProperties();
  EXPECT_VECTOR2DF_EQ(
      gfx::Vector2dF(-5.f, 10.f),
      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());

  // Now the main thread commits the new position of the sticky element.
  SetScrollOffset(scroller_.get(), gfx::ScrollOffset(15, 15));
  // Shift the layer by -offset_for_position_sticky.
  SetPostTranslation(sticky_pos_.get(),
                     gfx::PointF(10, 25) - gfx::PointF(0, 5));
  GetPropertyTrees(scroller_.get())->transform_tree.set_needs_update(true);

  CommitAndUpdateImplPointers();

  // The element should still be where it was before. We reset the delta to
  // (0, 0) because we have synced a scroll offset of (15, 15) from the main
  // thread.
  SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 0.f));
  UpdateActiveTreeDrawProperties();
  EXPECT_VECTOR2DF_EQ(
      gfx::Vector2dF(-5.f, 10.f),
      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());

  // And if we scroll a little further it remains there.
  SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 10.f));
  UpdateActiveTreeDrawProperties();
  EXPECT_VECTOR2DF_EQ(
      gfx::Vector2dF(-5.f, 10.f),
      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
}

// This tests the main thread updates with a composited sticky container. In
// this case the position received from main is relative to the container but
// the constraint rects are relative to the ancestor scroller.
TEST_F(DrawPropertiesStickyPositionTest, StickyPositionCompositedContainer) {
  CreateRootAndScroller();

  scoped_refptr<Layer> sticky_container = Layer::Create();
  sticky_container->SetBounds(gfx::Size(30, 30));
  sticky_container->SetOffsetToTransformParent(gfx::Vector2dF(20, 20));
  CopyProperties(scroller_.get(), sticky_container.get());
  root_->AddChild(sticky_container);

  sticky_pos_ = CreateSticky(sticky_container.get());
  SetPostTranslation(
      sticky_pos_.get(),
      gfx::Vector2dF(0, 10) + sticky_container->offset_to_transform_parent());
  auto& sticky_position = EnsureStickyData(sticky_pos_.get()).constraints;
  sticky_position.is_anchored_top = true;
  sticky_position.top_offset = 10.0f;
  sticky_position.scroll_container_relative_sticky_box_rect =
      gfx::Rect(20, 30, 10, 10);
  sticky_position.scroll_container_relative_containing_block_rect =
      gfx::Rect(20, 20, 30, 30);

  CommitAndUpdateImplPointers();

  EXPECT_VECTOR2DF_EQ(
      gfx::Vector2dF(20.f, 30.f),
      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());

  // Scroll less than sticking point, sticky element should move with scroll as
  // we haven't gotten to the initial sticky item location yet.
  SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 5.f));
  UpdateActiveTreeDrawProperties();
  EXPECT_VECTOR2DF_EQ(
      gfx::Vector2dF(20.f, 25.f),
      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());

  // Scroll past the sticking point, the Y coordinate should now be clamped.
  SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 25.f));
  UpdateActiveTreeDrawProperties();
  EXPECT_VECTOR2DF_EQ(
      gfx::Vector2dF(20.f, 10.f),
      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());

  // Now the main thread commits the new position of the sticky element.
  SetScrollOffset(scroller_.get(), gfx::ScrollOffset(0, 25));
  // Shift the layer by -offset_for_position_sticky.
  SetPostTranslation(sticky_pos_.get(),
                     gfx::PointF(0, 15) - gfx::PointF(0, 5) +
                         sticky_container->offset_to_transform_parent());
  CommitAndUpdateImplPointers();

  // The element should still be where it was before. We reset the delta to
  // (0, 0) because we have synced a scroll offset of (0, 25) from the main
  // thread.
  SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 0.f));
  UpdateActiveTreeDrawProperties();
  EXPECT_VECTOR2DF_EQ(
      gfx::Vector2dF(20.f, 10.f),
      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());

  // And if we scroll a little further it remains there.
  SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 5.f));
  UpdateActiveTreeDrawProperties();
  EXPECT_VECTOR2DF_EQ(
      gfx::Vector2dF(20.f, 10.f),
      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());

  // And hits the bottom of the container.
  SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 10.f));
  UpdateActiveTreeDrawProperties();
  EXPECT_VECTOR2DF_EQ(
      gfx::Vector2dF(20.f, 5.f),
      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
}

// A transform on a sticky element should not affect its sticky position.
TEST_F(DrawPropertiesStickyPositionTest, StickyPositionScaledStickyBox) {
  CreateTree();

  SetPostTranslation(sticky_pos_.get(), gfx::Vector2dF(0, 20));
  gfx::Transform scale;
  scale.Scale(2, 2);
  SetTransform(sticky_pos_.get(), scale);

  auto& sticky_position = EnsureStickyData(sticky_pos_.get()).constraints;
  sticky_position.is_anchored_top = true;
  sticky_position.top_offset = 0.0f;
  sticky_position.scroll_container_relative_sticky_box_rect =
      gfx::Rect(0, 20, 10, 10);
  sticky_position.scroll_container_relative_containing_block_rect =
      gfx::Rect(0, 0, 50, 50);

  CommitAndUpdateImplPointers();

  EXPECT_VECTOR2DF_EQ(
      gfx::Vector2dF(0.f, 20.f),
      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());

  // Scroll less than sticking point, sticky element should move with scroll as
  // we haven't gotten to the initial sticky item location yet.
  SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 15.f));

  UpdateActiveTreeDrawProperties();
  EXPECT_VECTOR2DF_EQ(
      gfx::Vector2dF(0.f, 5.f),
      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());

  // Scroll past the sticking point, the box is positioned at the scroller
  // edge.
  SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 25.f));
  UpdateActiveTreeDrawProperties();
  EXPECT_VECTOR2DF_EQ(
      gfx::Vector2dF(0.f, 0.f),
      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
  SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 30.f));
  UpdateActiveTreeDrawProperties();
  EXPECT_VECTOR2DF_EQ(
      gfx::Vector2dF(0.f, 0.f),
      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());

  // Scroll past the end of the sticky container.
  SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 50.f));
  UpdateActiveTreeDrawProperties();
  EXPECT_VECTOR2DF_EQ(
      gfx::Vector2dF(0.f, -10.f),
      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
}

// Tests that a transform does not affect the sticking points. The sticky
// element will however move relative to the viewport due to its transform.
TEST_F(DrawPropertiesStickyPositionTest, StickyPositionScaledContainer) {
  CreateRootAndScroller();

  scoped_refptr<Layer> sticky_container = Layer::Create();
  sticky_container->SetBounds(gfx::Size(50, 50));
  CopyProperties(scroller_.get(), sticky_container.get());
  CreateTransformNode(sticky_container.get()).local.Scale(2, 2);
  root_->AddChild(sticky_container);

  sticky_pos_ = CreateSticky(sticky_container.get());
  SetPostTranslation(sticky_pos_.get(), gfx::Vector2dF(0, 20));
  auto& sticky_position = EnsureStickyData(sticky_pos_.get()).constraints;
  sticky_position.is_anchored_top = true;
  sticky_position.top_offset = 0.0f;
  sticky_position.scroll_container_relative_sticky_box_rect =
      gfx::Rect(0, 20, 10, 10);
  sticky_position.scroll_container_relative_containing_block_rect =
      gfx::Rect(0, 0, 50, 50);

  CommitAndUpdateImplPointers();

  EXPECT_VECTOR2DF_EQ(
      gfx::Vector2dF(0.f, 40.f),
      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());

  // Scroll less than sticking point, sticky element should move with scroll as
  // we haven't gotten to the initial sticky item location yet.
  SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 15.f));
  UpdateActiveTreeDrawProperties();
  EXPECT_VECTOR2DF_EQ(
      gfx::Vector2dF(0.f, 25.f),
      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());

  // Scroll past the sticking point, the box is positioned at the scroller
  // edge but is also scaled by its container so it begins to move down.
  SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 25.f));
  UpdateActiveTreeDrawProperties();
  EXPECT_VECTOR2DF_EQ(
      gfx::Vector2dF(0.f, 25.f),
      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
  SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 30.f));
  UpdateActiveTreeDrawProperties();
  EXPECT_VECTOR2DF_EQ(
      gfx::Vector2dF(0.f, 30.f),
      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());

  // Scroll past the end of the sticky container.
  SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 50.f));
  UpdateActiveTreeDrawProperties();
  EXPECT_VECTOR2DF_EQ(
      gfx::Vector2dF(0.f, 30.f),
      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
}

TEST_F(DrawPropertiesStickyPositionTest, StickyPositionNested) {
  CreateTree();

  SetPostTranslation(sticky_pos_.get(), gfx::Vector2dF(0, 50));
  auto& outer_sticky_pos = EnsureStickyData(sticky_pos_.get()).constraints;
  outer_sticky_pos.is_anchored_top = true;
  outer_sticky_pos.top_offset = 10.0f;
  outer_sticky_pos.scroll_container_relative_sticky_box_rect =
      gfx::Rect(0, 50, 10, 50);
  outer_sticky_pos.scroll_container_relative_containing_block_rect =
      gfx::Rect(0, 0, 50, 400);

  scoped_refptr<Layer> inner_sticky = CreateSticky(sticky_pos_.get());
  auto& inner_sticky_pos = EnsureStickyData(inner_sticky.get()).constraints;
  inner_sticky_pos.is_anchored_top = true;
  inner_sticky_pos.top_offset = 25.0f;
  inner_sticky_pos.scroll_container_relative_sticky_box_rect =
      gfx::Rect(0, 50, 10, 10);
  inner_sticky_pos.scroll_container_relative_containing_block_rect =
      gfx::Rect(0, 50, 10, 50);
  EnsureStickyData(inner_sticky.get()).nearest_node_shifting_containing_block =
      sticky_pos_->transform_tree_index();

  CommitAndUpdateImplPointers();
  LayerTreeImpl* layer_tree_impl = host()->host_impl()->active_tree();
  LayerImpl* outer_sticky_impl = sticky_pos_impl_;
  LayerImpl* inner_sticky_impl = layer_tree_impl->LayerById(inner_sticky->id());

  // Before any scrolling is done, the sticky elements should still be at their
  // original positions.
  EXPECT_VECTOR2DF_EQ(
      gfx::Vector2dF(0.f, 50.f),
      outer_sticky_impl->ScreenSpaceTransform().To2dTranslation());
  EXPECT_VECTOR2DF_EQ(
      gfx::Vector2dF(0.f, 50.f),
      inner_sticky_impl->ScreenSpaceTransform().To2dTranslation());

  // Scroll less than the sticking point. Both sticky elements should move with
  // scroll as we haven't gotten to the sticky item locations yet.
  SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 5.f));
  UpdateActiveTreeDrawProperties();
  EXPECT_VECTOR2DF_EQ(
      gfx::Vector2dF(0.f, 45.f),
      outer_sticky_impl->ScreenSpaceTransform().To2dTranslation());
  EXPECT_VECTOR2DF_EQ(
      gfx::Vector2dF(0.f, 45.f),
      inner_sticky_impl->ScreenSpaceTransform().To2dTranslation());

  // Scroll such that the inner sticky should stick, but the outer one should
  // keep going as it hasn't reached its position yet.
  SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 30.f));
  UpdateActiveTreeDrawProperties();
  EXPECT_VECTOR2DF_EQ(
      gfx::Vector2dF(0.f, 20.f),
      outer_sticky_impl->ScreenSpaceTransform().To2dTranslation());
  EXPECT_VECTOR2DF_EQ(
      gfx::Vector2dF(0.f, 25.f),
      inner_sticky_impl->ScreenSpaceTransform().To2dTranslation());

  // Keep going, both should stick.
  SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 100.f));
  UpdateActiveTreeDrawProperties();
  EXPECT_VECTOR2DF_EQ(
      gfx::Vector2dF(0.f, 10.f),
      outer_sticky_impl->ScreenSpaceTransform().To2dTranslation());
  EXPECT_VECTOR2DF_EQ(
      gfx::Vector2dF(0.f, 25.f),
      inner_sticky_impl->ScreenSpaceTransform().To2dTranslation());
}

class AnimationScaleFactorTrackingLayerImpl : public LayerImpl {
 public:
  static std::unique_ptr<AnimationScaleFactorTrackingLayerImpl> Create(
      LayerTreeImpl* tree_impl,
      int id) {
    return base::WrapUnique(
        new AnimationScaleFactorTrackingLayerImpl(tree_impl, id));
  }

  ~AnimationScaleFactorTrackingLayerImpl() override = default;

 private:
  explicit AnimationScaleFactorTrackingLayerImpl(LayerTreeImpl* tree_impl,
                                                 int id)
      : LayerImpl(tree_impl, id) {
    SetDrawsContent(true);
  }
};

TEST_F(DrawPropertiesTest, MaximumAnimationScaleFactor) {
  LayerImpl* root = root_layer();
  auto* grand_parent = AddLayer<AnimationScaleFactorTrackingLayerImpl>();
  auto* parent = AddLayer<AnimationScaleFactorTrackingLayerImpl>();
  auto* child = AddLayer<AnimationScaleFactorTrackingLayerImpl>();
  auto* grand_child = AddLayer<AnimationScaleFactorTrackingLayerImpl>();
  SetElementIdsForTesting();

  root->SetBounds(gfx::Size(1, 2));
  grand_parent->SetBounds(gfx::Size(1, 2));
  parent->SetBounds(gfx::Size(1, 2));
  child->SetBounds(gfx::Size(1, 2));
  grand_child->SetBounds(gfx::Size(1, 2));

  CopyProperties(root, grand_parent);
  CreateTransformNode(grand_parent);
  CopyProperties(grand_parent, parent);
  CreateTransformNode(parent);
  CopyProperties(parent, child);
  CreateTransformNode(child);
  CopyProperties(child, grand_child);
  CreateTransformNode(grand_child);

  UpdateActiveTreeDrawProperties();

  // No layers have animations.
  EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(grand_parent));
  EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(parent));
  EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(child));
  EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(grand_child));

  EXPECT_EQ(kNotScaled, GetStartingAnimationScale(grand_parent));
  EXPECT_EQ(kNotScaled, GetStartingAnimationScale(parent));
  EXPECT_EQ(kNotScaled, GetStartingAnimationScale(child));
  EXPECT_EQ(kNotScaled, GetStartingAnimationScale(grand_child));

  TransformOperations translation;
  translation.AppendTranslate(1.f, 2.f, 3.f);

  scoped_refptr<SingleKeyframeEffectAnimation> grand_parent_animation =
      SingleKeyframeEffectAnimation::Create(
          AnimationIdProvider::NextAnimationId());
  timeline_impl()->AttachAnimation(grand_parent_animation);
  grand_parent_animation->AttachElement(grand_parent->element_id());

  scoped_refptr<SingleKeyframeEffectAnimation> parent_animation =
      SingleKeyframeEffectAnimation::Create(
          AnimationIdProvider::NextAnimationId());
  timeline_impl()->AttachAnimation(parent_animation);
  parent_animation->AttachElement(parent->element_id());

  scoped_refptr<SingleKeyframeEffectAnimation> child_animation =
      SingleKeyframeEffectAnimation::Create(
          AnimationIdProvider::NextAnimationId());
  timeline_impl()->AttachAnimation(child_animation);
  child_animation->AttachElement(child->element_id());

  scoped_refptr<SingleKeyframeEffectAnimation> grand_child_animation =
      SingleKeyframeEffectAnimation::Create(
          AnimationIdProvider::NextAnimationId());
  timeline_impl()->AttachAnimation(grand_child_animation);
  grand_child_animation->AttachElement(grand_child->element_id());

  AddAnimatedTransformToAnimation(parent_animation.get(), 1.0,
                                  TransformOperations(), translation);

  // No layers have scale-affecting animations.
  EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(grand_parent));
  EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(parent));
  EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(child));
  EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(grand_child));

  EXPECT_EQ(kNotScaled, GetStartingAnimationScale(grand_parent));
  EXPECT_EQ(kNotScaled, GetStartingAnimationScale(parent));
  EXPECT_EQ(kNotScaled, GetStartingAnimationScale(child));
  EXPECT_EQ(kNotScaled, GetStartingAnimationScale(grand_child));

  TransformOperations scale;
  scale.AppendScale(5.f, 4.f, 3.f);

  AddAnimatedTransformToAnimation(child_animation.get(), 1.0,
                                  TransformOperations(), scale);
  UpdateActiveTreeDrawProperties();

  // Only |child| has a scale-affecting animation.
  EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(grand_parent));
  EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(parent));
  EXPECT_EQ(5.f, GetMaximumAnimationScale(child));
  EXPECT_EQ(5.f, GetMaximumAnimationScale(grand_child));

  EXPECT_EQ(kNotScaled, GetStartingAnimationScale(grand_parent));
  EXPECT_EQ(kNotScaled, GetStartingAnimationScale(parent));
  EXPECT_EQ(1.f, GetStartingAnimationScale(child));
  EXPECT_EQ(1.f, GetStartingAnimationScale(grand_child));

  AddAnimatedTransformToAnimation(grand_parent_animation.get(), 1.0,
                                  TransformOperations(), scale);
  UpdateActiveTreeDrawProperties();

  // |grand_parent| and |child| have scale-affecting animations.
  EXPECT_EQ(5.f, GetMaximumAnimationScale(grand_parent));
  EXPECT_EQ(5.f, GetMaximumAnimationScale(parent));
  // We don't support combining animated scales from two nodes; 0.f means
  // that the maximum scale could not be computed.
  EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(child));
  EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(grand_child));

  EXPECT_EQ(1.f, GetStartingAnimationScale(grand_parent));
  EXPECT_EQ(1.f, GetStartingAnimationScale(parent));
  EXPECT_EQ(kNotScaled, GetStartingAnimationScale(child));
  EXPECT_EQ(kNotScaled, GetStartingAnimationScale(grand_child));

  AddAnimatedTransformToAnimation(parent_animation.get(), 1.0,
                                  TransformOperations(), scale);
  UpdateActiveTreeDrawProperties();

  // |grand_parent|, |parent|, and |child| have scale-affecting animations.
  EXPECT_EQ(5.f, GetMaximumAnimationScale(grand_parent));
  EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(parent));
  EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(child));
  EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(grand_child));

  EXPECT_EQ(1.f, GetStartingAnimationScale(grand_parent));
  EXPECT_EQ(kNotScaled, GetStartingAnimationScale(parent));
  EXPECT_EQ(kNotScaled, GetStartingAnimationScale(child));
  EXPECT_EQ(kNotScaled, GetStartingAnimationScale(grand_child));

  grand_parent_animation->AbortKeyframeModelsWithProperty(
      TargetProperty::TRANSFORM, false);
  parent_animation->AbortKeyframeModelsWithProperty(TargetProperty::TRANSFORM,
                                                    false);
  child_animation->AbortKeyframeModelsWithProperty(TargetProperty::TRANSFORM,
                                                   false);

  TransformOperations perspective;
  perspective.AppendPerspective(10.f);

  AddAnimatedTransformToAnimation(child_animation.get(), 1.0,
                                  TransformOperations(), perspective);
  UpdateActiveTreeDrawProperties();

  // |child| has a scale-affecting animation but computing the maximum of this
  // animation is not supported.
  EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(grand_parent));
  EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(parent));
  EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(child));
  EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(grand_child));

  EXPECT_EQ(kNotScaled, GetStartingAnimationScale(grand_parent));
  EXPECT_EQ(kNotScaled, GetStartingAnimationScale(parent));
  EXPECT_EQ(kNotScaled, GetStartingAnimationScale(child));
  EXPECT_EQ(kNotScaled, GetStartingAnimationScale(grand_child));

  child_animation->AbortKeyframeModelsWithProperty(TargetProperty::TRANSFORM,
                                                   false);

  gfx::Transform scale_matrix;
  scale_matrix.Scale(1.f, 2.f);
  SetTransform(grand_parent, scale_matrix);
  SetTransform(parent, scale_matrix);

  AddAnimatedTransformToAnimation(parent_animation.get(), 1.0,
                                  TransformOperations(), scale);
  UpdateActiveTreeDrawProperties();

  // |grand_parent| and |parent| each have scale 2.f. |parent| has a  scale
  // animation with maximum scale 5.f.
  EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(grand_parent));
  EXPECT_EQ(10.f, GetMaximumAnimationScale(parent));
  EXPECT_EQ(10.f, GetMaximumAnimationScale(child));
  EXPECT_EQ(10.f, GetMaximumAnimationScale(grand_child));

  EXPECT_EQ(kNotScaled, GetStartingAnimationScale(grand_parent));
  EXPECT_EQ(2.f, GetStartingAnimationScale(parent));
  EXPECT_EQ(2.f, GetStartingAnimationScale(child));
  EXPECT_EQ(2.f, GetStartingAnimationScale(grand_child));

  gfx::Transform perspective_matrix;
  perspective_matrix.ApplyPerspectiveDepth(2.f);
  SetTransform(child, perspective_matrix);
  UpdateActiveTreeDrawProperties();

  // |child| has a transform that's neither a translation nor a scale.
  EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(grand_parent));
  EXPECT_EQ(10.f, GetMaximumAnimationScale(parent));
  EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(child));
  EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(grand_child));

  EXPECT_EQ(kNotScaled, GetStartingAnimationScale(grand_parent));
  EXPECT_EQ(2.f, GetStartingAnimationScale(parent));
  EXPECT_EQ(kNotScaled, GetStartingAnimationScale(child));
  EXPECT_EQ(kNotScaled, GetStartingAnimationScale(grand_child));

  SetTransform(parent, perspective_matrix);
  UpdateActiveTreeDrawProperties();

  // |parent| and |child| have transforms that are neither translations nor
  // scales.
  EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(grand_parent));
  EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(parent));
  EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(child));
  EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(grand_child));

  EXPECT_EQ(kNotScaled, GetStartingAnimationScale(grand_parent));
  EXPECT_EQ(kNotScaled, GetStartingAnimationScale(parent));
  EXPECT_EQ(kNotScaled, GetStartingAnimationScale(child));
  EXPECT_EQ(kNotScaled, GetStartingAnimationScale(grand_child));

  SetTransform(parent, gfx::Transform());
  SetTransform(child, gfx::Transform());
  SetTransform(grand_parent, perspective_matrix);

  UpdateActiveTreeDrawProperties();

  // |grand_parent| has a transform that's neither a translation nor a scale.
  EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(grand_parent));
  EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(parent));
  EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(child));
  EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(grand_child));

  EXPECT_EQ(kNotScaled, GetStartingAnimationScale(grand_parent));
  EXPECT_EQ(kNotScaled, GetStartingAnimationScale(parent));
  EXPECT_EQ(kNotScaled, GetStartingAnimationScale(child));
  EXPECT_EQ(kNotScaled, GetStartingAnimationScale(grand_child));
}

static void GatherDrawnLayers(LayerTreeImpl* tree_impl,
                              std::set<LayerImpl*>* drawn_layers) {
  for (EffectTreeLayerListIterator it(tree_impl);
       it.state() != EffectTreeLayerListIterator::State::END; ++it) {
    if (it.state() == EffectTreeLayerListIterator::State::LAYER)
      drawn_layers->insert(it.current_layer());

    if (it.state() != EffectTreeLayerListIterator::State::CONTRIBUTING_SURFACE)
      continue;
  }
}

// Needs layer tree mode: mask layer.
TEST_F(DrawPropertiesTestWithLayerTree, RenderSurfaceLayerListMembership) {
  auto root = Layer::Create();
  auto grand_parent = Layer::Create();
  auto parent = Layer::Create();
  auto child = Layer::Create();
  auto grand_child1 = Layer::Create();
  auto grand_child2 = Layer::Create();

  root->SetBounds(gfx::Size(1, 2));
  grand_parent->SetBounds(gfx::Size(1, 2));
  parent->SetBounds(gfx::Size(1, 2));
  child->SetBounds(gfx::Size(1, 2));
  grand_child1->SetBounds(gfx::Size(1, 2));
  grand_child2->SetBounds(gfx::Size(1, 2));

  child->AddChild(grand_child1);
  child->AddChild(grand_child2);
  parent->AddChild(child);
  grand_parent->AddChild(parent);
  root->AddChild(grand_parent);
  host()->SetRootLayer(root);

  // Start with nothing being drawn.
  CommitAndActivate();

  EXPECT_FALSE(ImplOf(grand_parent)->contributes_to_drawn_render_surface());
  EXPECT_FALSE(ImplOf(parent)->contributes_to_drawn_render_surface());
  EXPECT_FALSE(ImplOf(child)->contributes_to_drawn_render_surface());
  EXPECT_FALSE(ImplOf(grand_child1)->contributes_to_drawn_render_surface());
  EXPECT_FALSE(ImplOf(grand_child2)->contributes_to_drawn_render_surface());

  std::set<LayerImpl*> expected;
  std::set<LayerImpl*> actual;
  GatherDrawnLayers(host_impl()->active_tree(), &actual);
  EXPECT_EQ(expected, actual);

  // If we force render surface, but none of the layers are in the layer list,
  // then this layer should not appear in RSLL.
  grand_child1->SetForceRenderSurfaceForTesting(true);

  CommitAndActivate();

  EXPECT_FALSE(ImplOf(grand_parent)->contributes_to_drawn_render_surface());
  EXPECT_FALSE(ImplOf(parent)->contributes_to_drawn_render_surface());
  EXPECT_FALSE(ImplOf(child)->contributes_to_drawn_render_surface());
  EXPECT_FALSE(ImplOf(grand_child1)->contributes_to_drawn_render_surface());
  EXPECT_FALSE(ImplOf(grand_child2)->contributes_to_drawn_render_surface());

  expected.clear();
  actual.clear();
  GatherDrawnLayers(host_impl()->active_tree(), &actual);
  EXPECT_EQ(expected, actual);

  // However, if we say that this layer also draws content, it will appear in
  // RSLL.
  grand_child1->SetIsDrawable(true);

  CommitAndActivate();

  EXPECT_FALSE(ImplOf(grand_parent)->contributes_to_drawn_render_surface());
  EXPECT_FALSE(ImplOf(parent)->contributes_to_drawn_render_surface());
  EXPECT_FALSE(ImplOf(child)->contributes_to_drawn_render_surface());
  EXPECT_TRUE(ImplOf(grand_child1)->contributes_to_drawn_render_surface());
  EXPECT_FALSE(ImplOf(grand_child2)->contributes_to_drawn_render_surface());

  expected.clear();
  expected.insert(ImplOf(grand_child1));

  actual.clear();
  GatherDrawnLayers(host_impl()->active_tree(), &actual);
  EXPECT_EQ(expected, actual);

  // Now child is forced to have a render surface, and one if its children draws
  // content.
  grand_child1->SetIsDrawable(false);
  grand_child1->SetForceRenderSurfaceForTesting(false);
  child->SetForceRenderSurfaceForTesting(true);
  grand_child2->SetIsDrawable(true);

  CommitAndActivate();

  EXPECT_FALSE(ImplOf(grand_parent)->contributes_to_drawn_render_surface());
  EXPECT_FALSE(ImplOf(parent)->contributes_to_drawn_render_surface());
  EXPECT_FALSE(ImplOf(child)->contributes_to_drawn_render_surface());
  EXPECT_FALSE(ImplOf(grand_child1)->contributes_to_drawn_render_surface());
  EXPECT_TRUE(ImplOf(grand_child2)->contributes_to_drawn_render_surface());

  expected.clear();
  expected.insert(ImplOf(grand_child2));

  actual.clear();
  GatherDrawnLayers(host_impl()->active_tree(), &actual);
  EXPECT_EQ(expected, actual);

  // Add a mask layer to child.
  FakeContentLayerClient client;
  auto mask = PictureLayer::Create(&client);
  mask->SetBounds(child->bounds());
  child->SetMaskLayer(mask);

  CommitAndActivate();

  EXPECT_FALSE(ImplOf(grand_parent)->contributes_to_drawn_render_surface());
  EXPECT_FALSE(ImplOf(parent)->contributes_to_drawn_render_surface());
  EXPECT_FALSE(ImplOf(child)->contributes_to_drawn_render_surface());
  EXPECT_TRUE(ImplOf(mask)->contributes_to_drawn_render_surface());
  EXPECT_FALSE(ImplOf(grand_child1)->contributes_to_drawn_render_surface());
  EXPECT_TRUE(ImplOf(grand_child2)->contributes_to_drawn_render_surface());

  expected.clear();
  expected.insert(ImplOf(grand_child2));
  expected.insert(ImplOf(mask));

  actual.clear();
  GatherDrawnLayers(host_impl()->active_tree(), &actual);
  EXPECT_EQ(expected, actual);

  CommitAndActivate();

  EXPECT_FALSE(ImplOf(grand_parent)->contributes_to_drawn_render_surface());
  EXPECT_FALSE(ImplOf(parent)->contributes_to_drawn_render_surface());
  EXPECT_FALSE(ImplOf(child)->contributes_to_drawn_render_surface());
  EXPECT_TRUE(ImplOf(mask)->contributes_to_drawn_render_surface());
  EXPECT_FALSE(ImplOf(grand_child1)->contributes_to_drawn_render_surface());
  EXPECT_TRUE(ImplOf(grand_child2)->contributes_to_drawn_render_surface());

  expected.clear();
  expected.insert(ImplOf(grand_child2));
  expected.insert(ImplOf(mask));

  actual.clear();
  GatherDrawnLayers(host_impl()->active_tree(), &actual);
  EXPECT_EQ(expected, actual);

  // With nothing drawing, we should have no layers.
  grand_child2->SetIsDrawable(false);

  CommitAndActivate();

  EXPECT_FALSE(ImplOf(grand_parent)->contributes_to_drawn_render_surface());
  EXPECT_FALSE(ImplOf(parent)->contributes_to_drawn_render_surface());
  EXPECT_FALSE(ImplOf(child)->contributes_to_drawn_render_surface());
  // Mask layer has its own render surface in layer tree mode.
  EXPECT_TRUE(ImplOf(mask)->contributes_to_drawn_render_surface());
  EXPECT_FALSE(ImplOf(grand_child1)->contributes_to_drawn_render_surface());
  EXPECT_FALSE(ImplOf(grand_child2)->contributes_to_drawn_render_surface());

  expected.clear();
  expected.insert(ImplOf(mask));
  actual.clear();
  GatherDrawnLayers(host_impl()->active_tree(), &actual);
  EXPECT_EQ(expected, actual);

  // When the child is drawable, both the child and the mask should be in the
  // render surface list.
  child->SetIsDrawable(true);

  CommitAndActivate();

  EXPECT_FALSE(ImplOf(grand_parent)->contributes_to_drawn_render_surface());
  EXPECT_FALSE(ImplOf(parent)->contributes_to_drawn_render_surface());
  EXPECT_TRUE(ImplOf(child)->contributes_to_drawn_render_surface());
  EXPECT_TRUE(ImplOf(mask)->contributes_to_drawn_render_surface());
  EXPECT_FALSE(ImplOf(grand_child1)->contributes_to_drawn_render_surface());
  EXPECT_FALSE(ImplOf(grand_child2)->contributes_to_drawn_render_surface());

  expected.clear();
  expected.insert(ImplOf(child));
  expected.insert(ImplOf(mask));
  actual.clear();
  GatherDrawnLayers(host_impl()->active_tree(), &actual);
  EXPECT_EQ(expected, actual);

  child->SetMaskLayer(nullptr);

  // Now everyone's a member!
  grand_parent->SetIsDrawable(true);
  parent->SetIsDrawable(true);
  child->SetIsDrawable(true);
  grand_child1->SetIsDrawable(true);
  grand_child2->SetIsDrawable(true);

  CommitAndActivate();

  EXPECT_TRUE(ImplOf(grand_parent)->contributes_to_drawn_render_surface());
  EXPECT_TRUE(ImplOf(parent)->contributes_to_drawn_render_surface());
  EXPECT_TRUE(ImplOf(child)->contributes_to_drawn_render_surface());
  EXPECT_TRUE(ImplOf(grand_child1)->contributes_to_drawn_render_surface());
  EXPECT_TRUE(ImplOf(grand_child2)->contributes_to_drawn_render_surface());

  expected.clear();
  expected.insert(ImplOf(grand_parent));
  expected.insert(ImplOf(parent));
  expected.insert(ImplOf(child));
  expected.insert(ImplOf(grand_child1));
  expected.insert(ImplOf(grand_child2));

  actual.clear();
  GatherDrawnLayers(host_impl()->active_tree(), &actual);
  EXPECT_EQ(expected, actual);
}

// Needs layer tree mode: mask layer.
TEST_F(DrawPropertiesTestWithLayerTree, DrawPropertyDeviceScale) {
  auto root = Layer::Create();
  auto child1 = Layer::Create();
  auto child2 = Layer::Create();

  gfx::Transform scale_transform_child1, scale_transform_child2;
  scale_transform_child1.Scale(2, 3);
  scale_transform_child2.Scale(4, 5);

  root->SetBounds(gfx::Size(1, 1));
  root->SetIsDrawable(true);
  child1->SetTransform(scale_transform_child1);
  child1->SetBounds(gfx::Size(1, 1));
  child1->SetIsDrawable(true);

  FakeContentLayerClient client;
  auto mask = PictureLayer::Create(&client);
  mask->SetBounds(child1->bounds());
  child1->SetMaskLayer(mask);

  root->AddChild(child1);
  root->AddChild(child2);
  host()->SetRootLayer(root);
  host()->SetElementIdsForTesting();

  TransformOperations scale;
  scale.AppendScale(5.f, 8.f, 3.f);

  child2->SetTransform(scale_transform_child2);
  child2->SetBounds(gfx::Size(1, 1));
  child2->SetIsDrawable(true);
  AddAnimatedTransformToElementWithAnimation(child2->element_id(), timeline(),
                                             1.0, TransformOperations(), scale);

  CommitAndActivate();

  EXPECT_FLOAT_EQ(1.f, ImplOf(root)->GetIdealContentsScale());
  EXPECT_FLOAT_EQ(3.f, ImplOf(child1)->GetIdealContentsScale());
  EXPECT_FLOAT_EQ(3.f, ImplOf(mask)->GetIdealContentsScale());
  EXPECT_FLOAT_EQ(5.f, ImplOf(child2)->GetIdealContentsScale());

  EXPECT_FLOAT_EQ(kNotScaled, GetMaximumAnimationScale(ImplOf(root)));
  EXPECT_FLOAT_EQ(kNotScaled, GetMaximumAnimationScale(ImplOf(child1)));
  EXPECT_FLOAT_EQ(8.f, GetMaximumAnimationScale(ImplOf(child2)));

  // Changing device-scale would affect ideal_contents_scale and
  // maximum_animation_contents_scale.

  float device_scale_factor = 4.0f;
  CommitAndActivate(device_scale_factor);

  EXPECT_FLOAT_EQ(4.f, ImplOf(root)->GetIdealContentsScale());
  EXPECT_FLOAT_EQ(12.f, ImplOf(child1)->GetIdealContentsScale());
  EXPECT_FLOAT_EQ(12.f, ImplOf(mask)->GetIdealContentsScale());
  EXPECT_FLOAT_EQ(20.f, ImplOf(child2)->GetIdealContentsScale());

  EXPECT_FLOAT_EQ(kNotScaled, GetMaximumAnimationScale(ImplOf(root)));
  EXPECT_FLOAT_EQ(kNotScaled, GetMaximumAnimationScale(ImplOf(child1)));
  EXPECT_FLOAT_EQ(32.f, GetMaximumAnimationScale(ImplOf(child2)));
}

TEST_F(DrawPropertiesTest, DrawPropertyScales) {
  auto root = Layer::Create();
  auto page_scale = Layer::Create();
  auto child1 = Layer::Create();
  auto child2 = Layer::Create();

  gfx::Transform scale_transform_child1, scale_transform_child2;
  scale_transform_child1.Scale(2, 3);
  scale_transform_child2.Scale(4, 5);

  root->SetBounds(gfx::Size(1, 1));
  root->SetIsDrawable(true);
  child1->SetBounds(gfx::Size(1, 1));
  child1->SetIsDrawable(true);
  child2->SetBounds(gfx::Size(1, 1));
  child2->SetIsDrawable(true);

  root->AddChild(child1);
  root->AddChild(child2);
  root->AddChild(page_scale);
  host()->SetRootLayer(root);
  host()->SetElementIdsForTesting();

  SetupRootProperties(root.get());
  CopyProperties(root.get(), page_scale.get());
  CreateTransformNode(page_scale.get());
  CopyProperties(page_scale.get(), child1.get());
  CreateTransformNode(child1.get()).local = scale_transform_child1;
  CopyProperties(page_scale.get(), child2.get());
  CreateTransformNode(child2.get()).local = scale_transform_child2;

  LayerTreeHost::ViewportPropertyIds viewport_property_ids;
  viewport_property_ids.page_scale_transform =
      page_scale->transform_tree_index();
  host()->RegisterViewportPropertyIds(viewport_property_ids);

  TransformOperations scale;
  scale.AppendScale(5.f, 8.f, 3.f);

  AddAnimatedTransformToElementWithAnimation(child2->element_id(), timeline(),
                                             1.0, TransformOperations(), scale);

  CommitAndActivate();

  EXPECT_FLOAT_EQ(1.f, ImplOf(root)->GetIdealContentsScale());
  EXPECT_FLOAT_EQ(1.f, ImplOf(page_scale)->GetIdealContentsScale());
  EXPECT_FLOAT_EQ(3.f, ImplOf(child1)->GetIdealContentsScale());
  EXPECT_FLOAT_EQ(5.f, ImplOf(child2)->GetIdealContentsScale());

  EXPECT_FLOAT_EQ(kNotScaled, GetMaximumAnimationScale(ImplOf(root)));
  EXPECT_FLOAT_EQ(kNotScaled, GetMaximumAnimationScale(ImplOf(page_scale)));
  EXPECT_FLOAT_EQ(kNotScaled, GetMaximumAnimationScale(ImplOf(child1)));
  EXPECT_FLOAT_EQ(8.f, GetMaximumAnimationScale(ImplOf(child2)));

  // Changing page-scale would affect ideal_contents_scale and
  // maximum_animation_contents_scale.

  float device_scale_factor = 1.0f;
  host()->SetPageScaleFactorAndLimits(3.f, 3.f, 3.f);
  CommitAndActivate();

  EXPECT_FLOAT_EQ(1.f, ImplOf(root)->GetIdealContentsScale());
  EXPECT_FLOAT_EQ(3.f, ImplOf(page_scale)->GetIdealContentsScale());
  EXPECT_FLOAT_EQ(9.f, ImplOf(child1)->GetIdealContentsScale());
  EXPECT_FLOAT_EQ(15.f, ImplOf(child2)->GetIdealContentsScale());

  EXPECT_FLOAT_EQ(kNotScaled, GetMaximumAnimationScale(ImplOf(root)));
  EXPECT_FLOAT_EQ(kNotScaled, GetMaximumAnimationScale(ImplOf(page_scale)));
  EXPECT_FLOAT_EQ(kNotScaled, GetMaximumAnimationScale(ImplOf(child1)));
  EXPECT_FLOAT_EQ(24.f, GetMaximumAnimationScale(ImplOf(child2)));

  // Changing device-scale would affect ideal_contents_scale and
  // maximum_animation_contents_scale.

  device_scale_factor = 4.0f;
  CommitAndActivate(device_scale_factor);

  EXPECT_FLOAT_EQ(4.f, ImplOf(root)->GetIdealContentsScale());
  EXPECT_FLOAT_EQ(12.f, ImplOf(page_scale)->GetIdealContentsScale());
  EXPECT_FLOAT_EQ(36.f, ImplOf(child1)->GetIdealContentsScale());
  EXPECT_FLOAT_EQ(60.f, ImplOf(child2)->GetIdealContentsScale());

  EXPECT_FLOAT_EQ(kNotScaled, GetMaximumAnimationScale(ImplOf(root)));
  EXPECT_FLOAT_EQ(kNotScaled, GetMaximumAnimationScale(ImplOf(page_scale)));
  EXPECT_FLOAT_EQ(kNotScaled, GetMaximumAnimationScale(ImplOf(child1)));
  EXPECT_FLOAT_EQ(96.f, GetMaximumAnimationScale(ImplOf(child2)));
}

TEST_F(DrawPropertiesTest, AnimationScales) {
  LayerImpl* root = root_layer();
  auto* child1 = AddLayer<LayerImpl>();
  auto* child2 = AddLayer<LayerImpl>();
  SetElementIdsForTesting();

  gfx::Transform scale_transform_child1, scale_transform_child2;
  scale_transform_child1.Scale(2, 3);
  scale_transform_child2.Scale(4, 5);

  root->SetBounds(gfx::Size(1, 1));
  child1->SetBounds(gfx::Size(1, 1));
  child2->SetBounds(gfx::Size(1, 1));

  CopyProperties(root, child1);
  CreateTransformNode(child1).local = scale_transform_child1;
  CopyProperties(child1, child2);
  CreateTransformNode(child2).local = scale_transform_child2;

  TransformOperations scale;
  scale.AppendScale(5.f, 8.f, 3.f);

  AddAnimatedTransformToElementWithAnimation(
      child2->element_id(), timeline_impl(), 1.0, TransformOperations(), scale);
  UpdateActiveTreeDrawProperties();

  EXPECT_FLOAT_EQ(kNotScaled, GetMaximumAnimationScale(root));
  EXPECT_FLOAT_EQ(kNotScaled, GetMaximumAnimationScale(child1));
  EXPECT_FLOAT_EQ(24.f, GetMaximumAnimationScale(child2));

  EXPECT_FLOAT_EQ(kNotScaled, GetStartingAnimationScale(root));
  EXPECT_FLOAT_EQ(kNotScaled, GetStartingAnimationScale(child1));
  EXPECT_FLOAT_EQ(3.f, GetStartingAnimationScale(child2));

  // Correctly updates animation scale when layer property changes.
  SetTransform(child1, gfx::Transform());
  root->layer_tree_impl()->SetTransformMutated(child1->element_id(),
                                               gfx::Transform());
  UpdateActiveTreeDrawProperties();
  EXPECT_FLOAT_EQ(8.f, GetMaximumAnimationScale(child2));
  EXPECT_FLOAT_EQ(1.f, GetStartingAnimationScale(child2));

  // Do not update animation scale if already updated.
  host_impl()->active_tree()->property_trees()->SetAnimationScalesForTesting(
      child2->transform_tree_index(), 100.f, 100.f);
  EXPECT_FLOAT_EQ(100.f, GetMaximumAnimationScale(child2));
  EXPECT_FLOAT_EQ(100.f, GetStartingAnimationScale(child2));
}

TEST_F(DrawPropertiesTest, VisibleContentRectInChildRenderSurface) {
  LayerImpl* root = root_layer();
  LayerImpl* clip = AddLayer<LayerImpl>();
  LayerImpl* content = AddLayer<LayerImpl>();

  root->SetBounds(gfx::Size(768 / 2, 3000));
  root->SetDrawsContent(true);
  clip->SetBounds(gfx::Size(768 / 2, 10000));
  clip->SetMasksToBounds(true);
  content->SetBounds(gfx::Size(768 / 2, 10000));
  content->SetDrawsContent(true);

  CopyProperties(root, clip);
  CreateClipNode(clip);
  CopyProperties(clip, content);
  CreateEffectNode(content).render_surface_reason = RenderSurfaceReason::kTest;

  // Not calling UpdateActiveTreeDrawProperties() because we want to set a
  // special device viewport rect.
  host_impl()->active_tree()->SetDeviceViewportRect(gfx::Rect(768, 582));
  float device_scale_factor = 2.f;
  host_impl()->active_tree()->SetDeviceScaleFactor(device_scale_factor);
  UpdateDrawProperties(host_impl()->active_tree());

  // Layers in the root render surface have their visible content rect clipped
  // by the viewport.
  EXPECT_EQ(gfx::Rect(768 / device_scale_factor, 582 / device_scale_factor),
            root->visible_layer_rect());

  // Layers drawing to a child render surface should still have their visible
  // content rect clipped by the viewport.
  EXPECT_EQ(gfx::Rect(768 / device_scale_factor, 582 / device_scale_factor),
            content->visible_layer_rect());
}

TEST_F(DrawPropertiesTest, ViewportBoundsDeltaAffectVisibleContentRect) {
  gfx::Size container_size = gfx::Size(300, 500);
  gfx::Size scroll_size = gfx::Size(300, 1000);

  // Device viewport accomidated the root and the browser controls.
  gfx::Rect device_viewport_rect = gfx::Rect(300, 600);

  LayerTreeImpl* active_tree = host_impl()->active_tree();
  active_tree->SetDeviceViewportRect(device_viewport_rect);
  active_tree->set_browser_controls_shrink_blink_size(true);
  active_tree->SetTopControlsHeight(50);
  active_tree->PushPageScaleFromMainThread(1.0f, 1.0f, 1.0f);

  LayerImpl* root = root_layer();
  root->SetBounds(device_viewport_rect.size());
  SetupViewport(root, container_size, scroll_size);

  LayerImpl* scroll_layer = InnerViewportScrollLayer();
  scroll_layer->SetDrawsContent(true);

  active_tree->SetCurrentBrowserControlsShownRatio(1.0f, 1.0f);
  active_tree->UpdateViewportContainerSizes();
  UpdateActiveTreeDrawProperties();
  EXPECT_EQ(gfx::Rect(container_size), scroll_layer->visible_layer_rect());

  active_tree->SetCurrentBrowserControlsShownRatio(0.0f, 0.0f);
  active_tree->UpdateViewportContainerSizes();
  UpdateActiveTreeDrawProperties();

  gfx::Rect affected_by_delta(container_size.width(),
                              container_size.height() + 50);
  EXPECT_EQ(affected_by_delta, scroll_layer->visible_layer_rect());
}

TEST_F(DrawPropertiesTest, VisibleContentRectForAnimatedLayer) {
  host_impl()->CreatePendingTree();
  LayerImpl* root = EnsureRootLayerInPendingTree();
  LayerImpl* animated = AddLayerInPendingTree<LayerImpl>();

  animated->SetDrawsContent(true);
  host_impl()->pending_tree()->SetElementIdsForTesting();

  root->SetBounds(gfx::Size(100, 100));
  animated->SetBounds(gfx::Size(20, 20));

  CopyProperties(root, animated);
  CreateEffectNode(animated).opacity = 0.f;

  AddOpacityTransitionToElementWithAnimation(
      animated->element_id(), timeline_impl(), 10.0, 0.f, 1.f, false);
  UpdatePendingTreeDrawProperties();

  EXPECT_FALSE(animated->visible_layer_rect().IsEmpty());
}

TEST_F(DrawPropertiesTest,
       VisibleContentRectForAnimatedLayerWithSingularTransform) {
  host_impl()->CreatePendingTree();
  LayerImpl* root = EnsureRootLayerInPendingTree();
  LayerImpl* clip = AddLayerInPendingTree<LayerImpl>();
  LayerImpl* animated = AddLayerInPendingTree<LayerImpl>();
  LayerImpl* surface = AddLayerInPendingTree<LayerImpl>();
  LayerImpl* descendant_of_keyframe_model = AddLayerInPendingTree<LayerImpl>();
  host_impl()->pending_tree()->SetElementIdsForTesting();

  root->SetDrawsContent(true);
  animated->SetDrawsContent(true);
  surface->SetDrawsContent(true);
  descendant_of_keyframe_model->SetDrawsContent(true);

  gfx::Transform uninvertible_matrix;
  uninvertible_matrix.Scale3d(6.f, 6.f, 0.f);

  root->SetBounds(gfx::Size(100, 100));
  clip->SetBounds(gfx::Size(10, 10));
  clip->SetMasksToBounds(true);
  animated->SetBounds(gfx::Size(120, 120));
  surface->SetBounds(gfx::Size(100, 100));
  descendant_of_keyframe_model->SetBounds(gfx::Size(200, 200));

  CopyProperties(root, clip);
  CreateClipNode(clip);
  CopyProperties(clip, animated);
  CreateTransformNode(animated).local = uninvertible_matrix;
  CopyProperties(animated, surface);
  CreateTransformNode(surface);
  CreateEffectNode(surface).render_surface_reason = RenderSurfaceReason::kTest;
  CopyProperties(surface, descendant_of_keyframe_model);

  TransformOperations start_transform_operations;
  start_transform_operations.AppendMatrix(uninvertible_matrix);
  TransformOperations end_transform_operations;

  AddAnimatedTransformToElementWithAnimation(
      animated->element_id(), timeline_impl(), 10.0, start_transform_operations,
      end_transform_operations);
  UpdatePendingTreeDrawProperties();
  // Since animated has singular transform, it is not be part of render
  // surface layer list but should be rastered.
  EXPECT_FALSE(animated->contributes_to_drawn_render_surface());
  EXPECT_TRUE(animated->raster_even_if_not_drawn());

  // The animated layer has a singular transform and maps to a non-empty rect in
  // clipped target space, so is treated as fully visible.
  EXPECT_EQ(gfx::Rect(120, 120), animated->visible_layer_rect());

  // The singular transform on |animated| is flattened when inherited by
  // |surface|, and this happens to make it invertible.
  EXPECT_EQ(gfx::Rect(2, 2), surface->visible_layer_rect());
  EXPECT_EQ(gfx::Rect(2, 2),
            descendant_of_keyframe_model->visible_layer_rect());

  gfx::Transform zero_matrix;
  zero_matrix.Scale3d(0.f, 0.f, 0.f);
  root->layer_tree_impl()->SetTransformMutated(animated->element_id(),
                                               zero_matrix);
  UpdatePendingTreeDrawProperties();

  // The animated layer will be treated as fully visible when we combine clips
  // in screen space.
  EXPECT_EQ(gfx::Rect(120, 120), animated->visible_layer_rect());

  // This time, flattening does not make |animated|'s transform invertible. This
  // means the clip cannot be projected into |surface|'s space, so we treat
  // |surface| and layers that draw into it as having empty visible rect.
  EXPECT_EQ(gfx::Rect(100, 100), surface->visible_layer_rect());
  EXPECT_EQ(gfx::Rect(200, 200),
            descendant_of_keyframe_model->visible_layer_rect());

  host_impl()->ActivateSyncTree();
  LayerImpl* active_root = host_impl()->active_tree()->LayerById(root->id());
  UpdateActiveTreeDrawProperties();

  // Since the animated has singular transform, it is not be part of render
  // surface layer list.
  LayerImpl* active_animated =
      host_impl()->active_tree()->LayerById(animated->id());
  EXPECT_TRUE(active_root->contributes_to_drawn_render_surface());
  EXPECT_FALSE(active_animated->contributes_to_drawn_render_surface());

  // Since animated has singular transform, it is not be part of render
  // surface layer list but should be rastered.
  EXPECT_TRUE(animated->raster_even_if_not_drawn());
  EXPECT_EQ(gfx::Rect(120, 120), active_animated->visible_layer_rect());
}

TEST_F(DrawPropertiesTest, ChangeTransformOrigin) {
  LayerImpl* root = root_layer();
  LayerImpl* child = AddLayer<LayerImpl>();

  gfx::Transform scale_matrix;
  scale_matrix.Scale(2.f, 2.f);

  root->SetBounds(gfx::Size(100, 100));
  root->SetDrawsContent(true);
  child->SetBounds(gfx::Size(10, 10));
  child->SetDrawsContent(true);

  CopyProperties(root, child);
  CreateTransformNode(child).local = scale_matrix;

  UpdateActiveTreeDrawProperties();
  EXPECT_EQ(gfx::Rect(10, 10), child->visible_layer_rect());

  SetTransformOrigin(child, gfx::Point3F(10.f, 10.f, 10.f));

  UpdateActiveTreeDrawProperties();
  EXPECT_EQ(gfx::Rect(5, 5, 5, 5), child->visible_layer_rect());
}

TEST_F(DrawPropertiesTest, UpdateScrollChildPosition) {
  LayerImpl* root = root_layer();
  LayerImpl* scroll_parent = AddLayer<LayerImpl>();
  LayerImpl* scroll_child = AddLayer<LayerImpl>();

  root->SetBounds(gfx::Size(50, 50));

  scroll_parent->SetBounds(gfx::Size(30, 30));
  scroll_parent->SetScrollable(gfx::Size(50, 50));
  scroll_parent->SetElementId(
      LayerIdToElementIdForTesting(scroll_parent->id()));
  scroll_parent->SetDrawsContent(true);

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

  CopyProperties(root, scroll_parent);
  CreateTransformNode(scroll_parent);
  CreateScrollNode(scroll_parent);
  CopyProperties(scroll_parent, scroll_child);
  CreateTransformNode(scroll_child).local.Scale(2.f, 2.f);

  UpdateActiveTreeDrawProperties();
  EXPECT_EQ(gfx::Rect(25, 25), scroll_child->visible_layer_rect());

  SetScrollOffset(scroll_parent, gfx::ScrollOffset(0.f, 10.f));
  UpdateActiveTreeDrawProperties();
  EXPECT_EQ(gfx::Rect(0, 5, 25, 25), scroll_child->visible_layer_rect());

  SetPostTranslation(scroll_child, gfx::Vector2dF(0, -10.f));
  UpdateActiveTreeDrawProperties();
  EXPECT_EQ(gfx::Rect(0, 10, 25, 25), scroll_child->visible_layer_rect());
}

// Needs layer tree mode: copy request. Not using impl-side PropertyTreeBuilder.
TEST_F(DrawPropertiesTestWithLayerTree, HasCopyRequestsInTargetSubtree) {
  scoped_refptr<Layer> root = Layer::Create();
  scoped_refptr<Layer> child1 = Layer::Create();
  scoped_refptr<Layer> child2 = Layer::Create();
  scoped_refptr<Layer> grandchild = Layer::Create();
  scoped_refptr<Layer> greatgrandchild = Layer::Create();

  root->AddChild(child1);
  root->AddChild(child2);
  child1->AddChild(grandchild);
  grandchild->AddChild(greatgrandchild);
  host()->SetRootLayer(root);

  root->SetBounds(gfx::Size(1, 1));
  child1->RequestCopyOfOutput(viz::CopyOutputRequest::CreateStubForTesting());
  greatgrandchild->RequestCopyOfOutput(
      viz::CopyOutputRequest::CreateStubForTesting());
  child2->SetOpacity(0.f);
  UpdateMainDrawProperties();

  EXPECT_TRUE(LayerSubtreeHasCopyRequest(root.get()));
  EXPECT_TRUE(LayerSubtreeHasCopyRequest(child1.get()));
  EXPECT_FALSE(LayerSubtreeHasCopyRequest(child2.get()));
  EXPECT_TRUE(LayerSubtreeHasCopyRequest(grandchild.get()));
  EXPECT_TRUE(LayerSubtreeHasCopyRequest(greatgrandchild.get()));
}

// Needs layer tree mode: hide_layer_and_subtree, etc.
// Not using impl-side PropertyTreeBuilder.
TEST_F(DrawPropertiesTestWithLayerTree, SkippingSubtreeMain) {
  FakeContentLayerClient client;

  scoped_refptr<Layer> root = Layer::Create();
  client.set_bounds(root->bounds());
  scoped_refptr<Layer> child = Layer::Create();
  child->SetIsDrawable(true);
  scoped_refptr<Layer> grandchild = Layer::Create();
  grandchild->SetIsDrawable(true);
  scoped_refptr<FakePictureLayer> greatgrandchild(
      FakePictureLayer::Create(&client));

  root->SetBounds(gfx::Size(100, 100));
  child->SetBounds(gfx::Size(10, 10));
  grandchild->SetBounds(gfx::Size(10, 10));
  greatgrandchild->SetBounds(gfx::Size(10, 10));

  root->AddChild(child);
  child->AddChild(grandchild);
  grandchild->AddChild(greatgrandchild);
  host()->SetRootLayer(root);
  host()->SetElementIdsForTesting();

  // Check the non-skipped case.
  UpdateMainDrawProperties();
  EXPECT_TRUE(UpdateLayerListContains(grandchild->id()));

  // Now we will reset the visible rect from property trees for the grandchild,
  // and we will configure |child| in several ways that should force the subtree
  // to be skipped. The visible content rect for |grandchild| should, therefore,
  // remain empty.
  gfx::Transform singular;
  singular.matrix().set(0, 0, 0);

  child->SetTransform(singular);
  UpdateMainDrawProperties();
  EXPECT_FALSE(UpdateLayerListContains(grandchild->id()));
  child->SetTransform(gfx::Transform());

  child->SetHideLayerAndSubtree(true);
  UpdateMainDrawProperties();
  EXPECT_FALSE(UpdateLayerListContains(grandchild->id()));
  child->SetHideLayerAndSubtree(false);

  gfx::Transform zero_z_scale;
  zero_z_scale.Scale3d(1, 1, 0);
  child->SetTransform(zero_z_scale);

  // Add a transform animation with a start delay. Now, even though |child| has
  // a singular transform, the subtree should still get processed.
  int keyframe_model_id = 0;
  std::unique_ptr<KeyframeModel> keyframe_model = KeyframeModel::Create(
      std::unique_ptr<AnimationCurve>(new FakeTransformTransition(1.0)),
      keyframe_model_id, 1, TargetProperty::TRANSFORM);
  keyframe_model->set_fill_mode(KeyframeModel::FillMode::NONE);
  keyframe_model->set_time_offset(base::TimeDelta::FromMilliseconds(-1000));
  AddKeyframeModelToElementWithAnimation(child->element_id(), timeline(),
                                         std::move(keyframe_model));
  UpdateMainDrawProperties();
  EXPECT_TRUE(UpdateLayerListContains(grandchild->id()));

  RemoveKeyframeModelFromElementWithExistingKeyframeEffect(
      child->element_id(), timeline(), keyframe_model_id);
  child->SetTransform(gfx::Transform());
  child->SetOpacity(0.f);
  UpdateMainDrawProperties();
  EXPECT_FALSE(UpdateLayerListContains(grandchild->id()));

  // Now, even though child has zero opacity, we will configure |grandchild| and
  // |greatgrandchild| in several ways that should force the subtree to be
  // processed anyhow.
  grandchild->RequestCopyOfOutput(
      viz::CopyOutputRequest::CreateStubForTesting());
  UpdateMainDrawProperties();
  EXPECT_TRUE(UpdateLayerListContains(grandchild->id()));

  // Add an opacity animation with a start delay.
  keyframe_model_id = 1;
  keyframe_model = KeyframeModel::Create(
      std::unique_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 0.f, 1.f)),
      keyframe_model_id, 1, TargetProperty::OPACITY);
  keyframe_model->set_fill_mode(KeyframeModel::FillMode::NONE);
  keyframe_model->set_time_offset(base::TimeDelta::FromMilliseconds(-1000));
  AddKeyframeModelToElementWithExistingKeyframeEffect(
      child->element_id(), timeline(), std::move(keyframe_model));
  UpdateMainDrawProperties();
  EXPECT_TRUE(UpdateLayerListContains(grandchild->id()));
}

// Needs layer tree mode: hide_layer_and_subtree, etc.
TEST_F(DrawPropertiesTestWithLayerTree, SkippingLayerImpl) {
  auto root = Layer::Create();
  host()->SetRootLayer(root);
  auto parent = Layer::Create();
  root->AddChild(parent);
  auto child = Layer::Create();
  parent->AddChild(child);
  auto grandchild = Layer::Create();
  child->AddChild(grandchild);
  FakeContentLayerClient client;
  auto greatgrandchild = PictureLayer::Create(&client);
  grandchild->AddChild(greatgrandchild);

  root->SetBounds(gfx::Size(100, 100));
  parent->SetBounds(gfx::Size(100, 100));
  child->SetBounds(gfx::Size(10, 10));
  child->SetIsDrawable(true);
  grandchild->SetBounds(gfx::Size(10, 10));
  grandchild->SetIsDrawable(true);
  greatgrandchild->SetIsDrawable(true);

  host()->SetElementIdsForTesting();

  // Check the non-skipped case.
  CommitAndActivate();
  EXPECT_EQ(gfx::Rect(10, 10), ImplOf(grandchild)->visible_layer_rect());

  // Now we will reset the visible rect from property trees for the grandchild,
  // and we will configure |child| in several ways that should force the subtree
  // to be skipped. The visible content rect for |grandchild| should, therefore,
  // remain empty.
  ImplOf(grandchild)->set_visible_layer_rect(gfx::Rect());

  gfx::Transform singular;
  singular.matrix().set(0, 0, 0);
  // This line is used to make the results of skipping and not skipping layers
  // different.
  singular.matrix().set(0, 1, 1);

  gfx::Transform rotate;
  rotate.Rotate(90);

  gfx::Transform rotate_back_and_translate;
  rotate_back_and_translate.RotateAboutYAxis(180);
  rotate_back_and_translate.Translate(-10, 0);

  child->SetTransform(singular);
  CommitAndActivate();
  EXPECT_EQ(gfx::Rect(0, 0), ImplOf(grandchild)->visible_layer_rect());
  child->SetTransform(gfx::Transform());

  child->SetHideLayerAndSubtree(true);
  CommitAndActivate();
  EXPECT_EQ(gfx::Rect(0, 0), ImplOf(grandchild)->visible_layer_rect());
  child->SetHideLayerAndSubtree(false);

  child->SetOpacity(0.f);
  CommitAndActivate();
  EXPECT_EQ(gfx::Rect(0, 0), ImplOf(grandchild)->visible_layer_rect());
  child->SetOpacity(1.f);

  parent->SetTransform(singular);
  // Force transform tree to have a node for child, so that ancestor's
  // invertible transform can be tested.
  child->SetTransform(rotate);
  CommitAndActivate();
  EXPECT_EQ(gfx::Rect(0, 0), ImplOf(grandchild)->visible_layer_rect());
  parent->SetTransform(gfx::Transform());
  child->SetTransform(gfx::Transform());

  parent->SetOpacity(0.f);
  child->SetOpacity(0.7f);
  CommitAndActivate();
  EXPECT_EQ(gfx::Rect(0, 0), ImplOf(grandchild)->visible_layer_rect());
  parent->SetOpacity(1.f);

  child->SetOpacity(0.f);
  // Now, even though child has zero opacity, we will configure |grandchild| and
  // |greatgrandchild| in several ways that should force the subtree to be
  // processed anyhow.
  grandchild->RequestCopyOfOutput(
      viz::CopyOutputRequest::CreateStubForTesting());
  CommitAndActivate();
  EXPECT_EQ(gfx::Rect(10, 10), ImplOf(grandchild)->visible_layer_rect());

  GetPropertyTrees(root.get())->effect_tree.ClearCopyRequests();
  child->SetOpacity(1.f);

  // A double sided render surface with backface visible should not be skipped
  ImplOf(grandchild)->set_visible_layer_rect(gfx::Rect());
  child->SetForceRenderSurfaceForTesting(true);
  child->SetDoubleSided(true);
  child->SetTransform(rotate_back_and_translate);
  CommitAndActivate();
  EXPECT_EQ(gfx::Rect(10, 10), ImplOf(grandchild)->visible_layer_rect());
  child->SetTransform(gfx::Transform());

  std::unique_ptr<KeyframedTransformAnimationCurve> curve(
      KeyframedTransformAnimationCurve::Create());
  TransformOperations start;
  start.AppendTranslate(1.f, 2.f, 3.f);
  gfx::Transform transform;
  transform.Scale3d(1.0, 2.0, 3.0);
  TransformOperations operation;
  operation.AppendMatrix(transform);
  curve->AddKeyframe(
      TransformKeyframe::Create(base::TimeDelta(), start, nullptr));
  curve->AddKeyframe(TransformKeyframe::Create(
      base::TimeDelta::FromSecondsD(1.0), operation, nullptr));
  std::unique_ptr<KeyframeModel> transform_animation(
      KeyframeModel::Create(std::move(curve), 3, 3, TargetProperty::TRANSFORM));
  scoped_refptr<SingleKeyframeEffectAnimation> animation(
      SingleKeyframeEffectAnimation::Create(1));
  timeline()->AttachAnimation(animation);
  animation->AttachElementForKeyframeEffect(parent->element_id(),
                                            animation->keyframe_effect()->id());
  animation->AddKeyframeModel(std::move(transform_animation));
  ImplOf(grandchild)->set_visible_layer_rect(gfx::Rect());
  parent->SetTransform(singular);
  child->SetTransform(singular);
  CommitAndActivate();
  EXPECT_EQ(gfx::Rect(0, 0), ImplOf(grandchild)->visible_layer_rect());
}

// This tests for correctness of an optimization.  If a node in the tree
// maps all possible spaces to a single point (ie has a singular transform)
// we can ignore the size of all its children.  We need to make sure that
// we don't do this if an animation can replace this transform in the
// compositor without recomputing the trees.
TEST_F(DrawPropertiesTest, LayerSkippingInSubtreeOfSingularTransform) {
  // Set up a transform animation
  std::unique_ptr<KeyframedTransformAnimationCurve> curve(
      KeyframedTransformAnimationCurve::Create());
  TransformOperations start;
  start.AppendTranslate(1.f, 2.f, 3.f);
  gfx::Transform transform;
  transform.Scale3d(1.0, 2.0, 3.0);
  TransformOperations operation;
  operation.AppendMatrix(transform);
  curve->AddKeyframe(
      TransformKeyframe::Create(base::TimeDelta(), start, nullptr));
  curve->AddKeyframe(TransformKeyframe::Create(
      base::TimeDelta::FromSecondsD(1.0), operation, nullptr));
  std::unique_ptr<KeyframeModel> transform_animation(
      KeyframeModel::Create(std::move(curve), 3, 3, TargetProperty::TRANSFORM));
  scoped_refptr<SingleKeyframeEffectAnimation> animation(
      SingleKeyframeEffectAnimation::Create(1));
  timeline_impl()->AttachAnimation(animation);
  animation->AddKeyframeModel(std::move(transform_animation));

  // Set up some layers to have a tree.
  LayerImpl* root = root_layer();
  LayerImpl* child = AddLayer<LayerImpl>();
  LayerImpl* grand_child = AddLayer<LayerImpl>();

  SetElementIdsForTesting();

  // If these are not on the same host we are doomed to fail.
  ASSERT_EQ(timeline_impl()->animation_host(),
            child->layer_tree_impl()->mutator_host());

  // A non-invertible matrix for use later.
  gfx::Transform singular;
  singular.matrix().set(0, 0, 0);
  singular.matrix().set(0, 1, 1);

  root->SetBounds(gfx::Size(10, 10));
  child->SetBounds(gfx::Size(10, 10));
  child->SetDrawsContent(true);
  grand_child->SetBounds(gfx::Size(10, 10));
  grand_child->SetDrawsContent(true);

  // Check that we set the visible sizes as expected in CalculateDrawProperties
  grand_child->set_visible_layer_rect(gfx::Rect());
  child->set_visible_layer_rect(gfx::Rect());

  CopyProperties(root, child);
  CreateTransformNode(child);
  CopyProperties(child, grand_child);

  UpdateActiveTreeDrawProperties();
  ASSERT_EQ(gfx::Rect(10, 10), grand_child->visible_layer_rect());
  ASSERT_EQ(gfx::Rect(10, 10), child->visible_layer_rect());

  // See if we optimize out irrelevant pieces of work.
  SetTransform(child, singular);
  grand_child->set_visible_layer_rect(gfx::Rect());
  child->set_visible_layer_rect(gfx::Rect());
  UpdateActiveTreeDrawProperties();
  EXPECT_EQ(gfx::Rect(), grand_child->visible_layer_rect());
  EXPECT_EQ(gfx::Rect(), child->visible_layer_rect());

  // Check that undoing the transform is still valid (memoryless enough)
  SetTransform(child, gfx::Transform());
  grand_child->set_visible_layer_rect(gfx::Rect());
  child->set_visible_layer_rect(gfx::Rect());
  root->layer_tree_impl()->property_trees()->needs_rebuild = true;
  UpdateActiveTreeDrawProperties();
  ASSERT_EQ(gfx::Rect(10, 10), grand_child->visible_layer_rect());
  ASSERT_EQ(gfx::Rect(10, 10), child->visible_layer_rect());

  // If the transform is singular, but there is an animation on it, we
  // should not skip the subtree.  Note that the animation has not started or
  // ticked, there is also code along that path.  This is not its test.
  animation->AttachElementForKeyframeEffect(child->element_id(),
                                            animation->keyframe_effect()->id());
  SetTransform(child, singular);
  grand_child->set_visible_layer_rect(gfx::Rect(1, 1));
  child->set_visible_layer_rect(gfx::Rect(1, 1));
  UpdateActiveTreeDrawProperties();
  EXPECT_EQ(gfx::Rect(10, 10), grand_child->visible_layer_rect());
  EXPECT_EQ(gfx::Rect(10, 10), child->visible_layer_rect());
}

// This tests that we skip computing the visible areas for the subtree
// rooted at nodes with constant zero opacity.
TEST_F(DrawPropertiesTestWithLayerTree, SkippingPendingLayerImpl) {
  auto root = Layer::Create();
  auto child = Layer::Create();
  auto grandchild = Layer::Create();
  FakeContentLayerClient client;
  auto greatgrandchild = PictureLayer::Create(&client);

  root->SetBounds(gfx::Size(100, 100));
  child->SetBounds(gfx::Size(10, 10));
  child->SetIsDrawable(true);
  grandchild->SetBounds(gfx::Size(10, 10));
  grandchild->SetIsDrawable(true);
  greatgrandchild->SetIsDrawable(true);

  child->AddChild(grandchild);
  root->AddChild(child);
  host()->SetRootLayer(root);
  host()->SetElementIdsForTesting();

  // Check the non-skipped case.
  root->SetOpacity(1.f);
  Commit();
  ASSERT_EQ(gfx::Rect(10, 10), PendingImplOf(grandchild)->visible_layer_rect());

  // Check the skipped case.
  root->SetOpacity(0.f);
  PendingImplOf(grandchild)->set_visible_layer_rect(gfx::Rect());
  Commit();
  EXPECT_EQ(gfx::Rect(), PendingImplOf(grandchild)->visible_layer_rect());

  // Check the animated case is not skipped.
  std::unique_ptr<KeyframedFloatAnimationCurve> curve(
      KeyframedFloatAnimationCurve::Create());
  std::unique_ptr<TimingFunction> func =
      CubicBezierTimingFunction::CreatePreset(
          CubicBezierTimingFunction::EaseType::EASE);
  curve->AddKeyframe(
      FloatKeyframe::Create(base::TimeDelta(), 0.9f, std::move(func)));
  curve->AddKeyframe(
      FloatKeyframe::Create(base::TimeDelta::FromSecondsD(1.0), 0.3f, nullptr));
  std::unique_ptr<KeyframeModel> keyframe_model(
      KeyframeModel::Create(std::move(curve), 3, 3, TargetProperty::OPACITY));
  scoped_refptr<SingleKeyframeEffectAnimation> animation(
      SingleKeyframeEffectAnimation::Create(1));
  timeline()->AttachAnimation(animation);
  animation->AddKeyframeModel(std::move(keyframe_model));
  animation->AttachElementForKeyframeEffect(root->element_id(),
                                            animation->keyframe_effect()->id());
  // Repeat the calculation invocation.
  PendingImplOf(grandchild)->set_visible_layer_rect(gfx::Rect());
  Commit();
  EXPECT_EQ(gfx::Rect(10, 10), PendingImplOf(grandchild)->visible_layer_rect());
}

// Needs layer tree mode: hide_layer_and_subtree.
TEST_F(DrawPropertiesTestWithLayerTree, SkippingLayer) {
  auto root = Layer::Create();
  host()->SetRootLayer(root);
  auto child = Layer::Create();
  root->AddChild(child);

  root->SetBounds(gfx::Size(100, 100));
  child->SetBounds(gfx::Size(10, 10));
  child->SetIsDrawable(true);

  CommitAndActivate();

  EXPECT_EQ(gfx::Rect(10, 10), ImplOf(child)->visible_layer_rect());
  ImplOf(child)->set_visible_layer_rect(gfx::Rect());

  child->SetHideLayerAndSubtree(true);
  CommitAndActivate();
  EXPECT_EQ(gfx::Rect(0, 0), ImplOf(child)->visible_layer_rect());
  child->SetHideLayerAndSubtree(false);

  child->SetBounds(gfx::Size());
  CommitAndActivate();
  EXPECT_EQ(gfx::Rect(0, 0), ImplOf(child)->visible_layer_rect());
  child->SetBounds(gfx::Size(10, 10));

  gfx::Transform rotate;
  child->SetDoubleSided(false);
  rotate.RotateAboutXAxis(180.f);
  child->SetTransform(rotate);
  CommitAndActivate();
  EXPECT_EQ(gfx::Rect(0, 0), ImplOf(child)->visible_layer_rect());
  child->SetDoubleSided(true);
  child->SetTransform(gfx::Transform());

  child->SetOpacity(0.f);
  CommitAndActivate();
  EXPECT_EQ(gfx::Rect(0, 0), ImplOf(child)->visible_layer_rect());
}

TEST_F(DrawPropertiesTest, TransformOfParentClipNodeAncestorOfTarget) {
  // Ensure that when parent clip node's transform is an ancestor of current
  // clip node's target, clip is 'projected' from parent space to current
  // target space and visible rects are calculated correctly.
  LayerImpl* root = root_layer();
  LayerImpl* clip_layer = AddLayer<LayerImpl>();
  LayerImpl* target_layer = AddLayer<LayerImpl>();
  LayerImpl* test_layer = AddLayer<LayerImpl>();

  gfx::Transform transform;
  transform.RotateAboutYAxis(45);

  root->SetBounds(gfx::Size(30, 30));
  clip_layer->SetBounds(gfx::Size(30, 30));
  clip_layer->SetMasksToBounds(true);
  target_layer->SetBounds(gfx::Size(30, 30));
  target_layer->SetMasksToBounds(true);
  test_layer->SetBounds(gfx::Size(30, 30));
  test_layer->SetDrawsContent(true);

  CopyProperties(root, clip_layer);
  CreateTransformNode(clip_layer).local = transform;
  CreateClipNode(clip_layer);
  CopyProperties(clip_layer, target_layer);
  CreateTransformNode(target_layer).local = transform;
  CreateClipNode(target_layer);
  CopyProperties(target_layer, test_layer);

  UpdateActiveTreeDrawProperties();

  EXPECT_EQ(gfx::Rect(30, 30), test_layer->visible_layer_rect());
}

TEST_F(DrawPropertiesTest, RenderSurfaceWithUnclippedDescendantsClipsSubtree) {
  // Ensure clip rect is calculated correctly when render surface has unclipped
  // descendants.
  LayerImpl* root = root_layer();
  LayerImpl* clip_parent = AddLayer<LayerImpl>();
  LayerImpl* between_clip_parent_and_child = AddLayer<LayerImpl>();
  LayerImpl* render_surface = AddLayer<LayerImpl>();
  LayerImpl* test_layer = AddLayer<LayerImpl>();

  root->SetBounds(gfx::Size(30, 30));
  clip_parent->SetBounds(gfx::Size(30, 30));
  between_clip_parent_and_child->SetBounds(gfx::Size(30, 30));
  render_surface->SetBounds(gfx::Size(30, 30));
  test_layer->SetBounds(gfx::Size(30, 30));
  test_layer->SetDrawsContent(true);

  CopyProperties(root, clip_parent);
  CreateTransformNode(clip_parent).local.Translate(2, 2);
  CreateClipNode(clip_parent);
  CopyProperties(clip_parent, between_clip_parent_and_child);
  CreateClipNode(between_clip_parent_and_child);
  CreateTransformNode(between_clip_parent_and_child).local.Translate(2, 2);
  CreateClipNode(between_clip_parent_and_child);
  CopyProperties(between_clip_parent_and_child, render_surface);
  CreateEffectNode(render_surface).render_surface_reason =
      RenderSurfaceReason::kTest;
  CopyProperties(render_surface, test_layer);
  test_layer->SetClipTreeIndex(clip_parent->clip_tree_index());

  UpdateActiveTreeDrawProperties();

  EXPECT_TRUE(test_layer->is_clipped());
  EXPECT_FALSE(test_layer->render_target()->is_clipped());
  EXPECT_EQ(gfx::Rect(-2, -2, 30, 30), test_layer->clip_rect());
  EXPECT_EQ(gfx::Rect(28, 28), test_layer->drawable_content_rect());
}

TEST_F(DrawPropertiesTest,
       RenderSurfaceWithUnclippedDescendantsButDoesntApplyOwnClip) {
  // Ensure that the visible layer rect of a descendant of a surface with
  // unclipped descendants is computed correctly, when the surface doesn't apply
  // a clip.
  LayerImpl* root = root_layer();
  LayerImpl* clip_parent = AddLayer<LayerImpl>();
  LayerImpl* render_surface = AddLayer<LayerImpl>();
  LayerImpl* clip_child = AddLayer<LayerImpl>();
  LayerImpl* child = AddLayer<LayerImpl>();

  root->SetBounds(gfx::Size(30, 10));
  clip_parent->SetBounds(gfx::Size(30, 30));
  render_surface->SetBounds(gfx::Size(10, 15));
  clip_child->SetBounds(gfx::Size(10, 10));
  clip_child->SetDrawsContent(true);
  child->SetBounds(gfx::Size(40, 40));
  child->SetDrawsContent(true);

  CopyProperties(root, clip_parent);
  CopyProperties(clip_parent, render_surface);
  CreateEffectNode(render_surface).render_surface_reason =
      RenderSurfaceReason::kTest;
  CopyProperties(render_surface, clip_child);
  clip_child->SetClipTreeIndex(clip_parent->clip_tree_index());
  CopyProperties(clip_child, child);

  UpdateActiveTreeDrawProperties();
  EXPECT_EQ(gfx::Rect(30, 10), child->visible_layer_rect());
}

TEST_F(DrawPropertiesTest,
       RenderSurfaceClipsSubtreeAndHasUnclippedDescendants) {
  LayerImpl* root = root_layer();
  LayerImpl* clip_parent = AddLayer<LayerImpl>();
  LayerImpl* render_surface = AddLayer<LayerImpl>();
  LayerImpl* test_layer1 = AddLayer<LayerImpl>();
  LayerImpl* clip_child = AddLayer<LayerImpl>();
  LayerImpl* test_layer2 = AddLayer<LayerImpl>();

  root->SetBounds(gfx::Size(30, 30));
  clip_parent->SetBounds(gfx::Size(30, 30));
  render_surface->SetBounds(gfx::Size(50, 50));
  render_surface->SetDrawsContent(true);
  test_layer1->SetBounds(gfx::Size(50, 50));
  test_layer1->SetDrawsContent(true);
  clip_child->SetBounds(gfx::Size(50, 50));
  clip_child->SetDrawsContent(true);
  test_layer2->SetBounds(gfx::Size(50, 50));
  test_layer2->SetDrawsContent(true);

  CreateClipNode(root);
  CopyProperties(root, clip_parent);
  CopyProperties(clip_parent, render_surface);
  CreateEffectNode(render_surface).render_surface_reason =
      RenderSurfaceReason::kTest;
  CreateClipNode(render_surface);
  CopyProperties(render_surface, test_layer1);
  CopyProperties(test_layer1, clip_child);
  clip_child->SetClipTreeIndex(clip_parent->clip_tree_index());
  CopyProperties(clip_child, test_layer2);

  UpdateActiveTreeDrawProperties();
  EXPECT_EQ(gfx::Rect(30, 30), render_surface->visible_layer_rect());
  EXPECT_EQ(gfx::Rect(30, 30), test_layer1->visible_layer_rect());
  EXPECT_EQ(gfx::Rect(30, 30), clip_child->visible_layer_rect());
  EXPECT_EQ(gfx::Rect(30, 30), test_layer2->visible_layer_rect());
}

TEST_F(DrawPropertiesTest, UnclippedClipParent) {
  LayerImpl* root = root_layer();
  LayerImpl* clip_parent = AddLayer<LayerImpl>();
  LayerImpl* render_surface = AddLayer<LayerImpl>();
  LayerImpl* clip_child = AddLayer<LayerImpl>();

  root->SetBounds(gfx::Size(50, 50));
  clip_parent->SetBounds(gfx::Size(50, 50));
  clip_parent->SetDrawsContent(true);
  render_surface->SetBounds(gfx::Size(30, 30));
  render_surface->SetDrawsContent(true);
  clip_child->SetBounds(gfx::Size(50, 50));
  clip_child->SetDrawsContent(true);

  CopyProperties(root, clip_parent);
  CopyProperties(clip_parent, render_surface);
  CreateEffectNode(render_surface).render_surface_reason =
      RenderSurfaceReason::kTest;
  CreateClipNode(render_surface);
  CopyProperties(render_surface, clip_child);
  clip_child->SetClipTreeIndex(clip_parent->clip_tree_index());

  UpdateActiveTreeDrawProperties();

  // The clip child should inherit its clip parent's clipping state, not its
  // tree parent's clipping state.
  EXPECT_FALSE(clip_parent->is_clipped());
  EXPECT_TRUE(render_surface->is_clipped());
  EXPECT_FALSE(clip_child->is_clipped());
}

TEST_F(DrawPropertiesTest, RenderSurfaceContentRectWithMultipleSurfaces) {
  // Tests the value of render surface content rect when we have multiple types
  // of surfaces : unclipped surfaces, surfaces with unclipped surfaces and
  // clipped surfaces.
  LayerImpl* root = root_layer();
  LayerImpl* unclipped_surface = AddLayer<LayerImpl>();
  LayerImpl* clip_parent = AddLayer<LayerImpl>();
  LayerImpl* clip_layer = AddLayer<LayerImpl>();
  LayerImpl* unclipped_desc_surface = AddLayer<LayerImpl>();
  LayerImpl* unclipped_desc_surface2 = AddLayer<LayerImpl>();
  LayerImpl* clip_child = AddLayer<LayerImpl>();
  LayerImpl* clipped_surface = AddLayer<LayerImpl>();

  root->SetBounds(gfx::Size(80, 80));

  unclipped_surface->SetBounds(gfx::Size(50, 50));
  unclipped_surface->SetDrawsContent(true);
  clip_parent->SetBounds(gfx::Size(50, 50));
  clip_layer->SetBounds(gfx::Size(100, 100));
  unclipped_desc_surface->SetBounds(gfx::Size(100, 100));
  unclipped_desc_surface->SetDrawsContent(true);
  unclipped_desc_surface2->SetBounds(gfx::Size(60, 60));
  unclipped_desc_surface2->SetDrawsContent(true);
  clip_child->SetBounds(gfx::Size(100, 100));
  clipped_surface->SetBounds(gfx::Size(70, 70));
  clipped_surface->SetDrawsContent(true);

  CopyProperties(root, unclipped_surface);
  CreateEffectNode(unclipped_surface).render_surface_reason =
      RenderSurfaceReason::kTest;
  CreateClipNode(unclipped_surface);
  CopyProperties(unclipped_surface, clip_parent);
  CreateClipNode(clip_parent);
  CopyProperties(clip_parent, clip_layer);
  CreateClipNode(clip_layer);
  CopyProperties(clip_layer, unclipped_desc_surface);
  CreateEffectNode(unclipped_desc_surface).render_surface_reason =
      RenderSurfaceReason::kTest;
  CopyProperties(unclipped_desc_surface, unclipped_desc_surface2);
  CreateEffectNode(unclipped_desc_surface2).render_surface_reason =
      RenderSurfaceReason::kTest;
  CopyProperties(unclipped_desc_surface2, clip_child);
  clip_child->SetClipTreeIndex(clip_parent->clip_tree_index());
  CopyProperties(clip_child, clipped_surface);
  CreateEffectNode(clipped_surface).render_surface_reason =
      RenderSurfaceReason::kTest;

  UpdateActiveTreeDrawProperties();
  EXPECT_EQ(gfx::Rect(50, 50),
            GetRenderSurface(unclipped_surface)->content_rect());
  EXPECT_EQ(gfx::Rect(50, 50),
            GetRenderSurface(unclipped_desc_surface)->content_rect());
  EXPECT_EQ(gfx::Rect(60, 60),
            GetRenderSurface(unclipped_desc_surface2)->content_rect());
  EXPECT_EQ(gfx::Rect(50, 50),
            GetRenderSurface(clipped_surface)->content_rect());
}

TEST_F(DrawPropertiesTest, ClipBetweenClipChildTargetAndClipParentTarget) {
  // Tests the value of render surface content rect when we have a layer that
  // clips between the clip parent's target and clip child's target.
  LayerImpl* root = root_layer();
  LayerImpl* surface = AddLayer<LayerImpl>();
  LayerImpl* clip_layer = AddLayer<LayerImpl>();
  LayerImpl* clip_parent = AddLayer<LayerImpl>();
  LayerImpl* unclipped_desc_surface = AddLayer<LayerImpl>();
  LayerImpl* clip_child = AddLayer<LayerImpl>();

  root->SetBounds(gfx::Size(100, 100));
  surface->SetBounds(gfx::Size(100, 100));
  clip_layer->SetBounds(gfx::Size(20, 20));
  clip_parent->SetBounds(gfx::Size(50, 50));
  unclipped_desc_surface->SetBounds(gfx::Size(100, 100));
  unclipped_desc_surface->SetDrawsContent(true);
  clip_child->SetBounds(gfx::Size(100, 100));
  clip_child->SetDrawsContent(true);

  CopyProperties(root, surface);
  CreateTransformNode(surface).local.RotateAboutXAxis(10);
  CreateEffectNode(surface).render_surface_reason = RenderSurfaceReason::kTest;
  CreateClipNode(surface);
  CopyProperties(surface, clip_layer);
  CreateClipNode(clip_layer);
  CopyProperties(clip_layer, clip_parent);
  CopyProperties(clip_parent, unclipped_desc_surface);
  CreateTransformNode(unclipped_desc_surface).local.Translate(10, 10);
  CreateEffectNode(unclipped_desc_surface).render_surface_reason =
      RenderSurfaceReason::kTest;
  CopyProperties(unclipped_desc_surface, clip_child);
  clip_child->SetClipTreeIndex(clip_parent->clip_tree_index());

  UpdateActiveTreeDrawProperties();

  EXPECT_EQ(gfx::Rect(10, 10),
            GetRenderSurface(unclipped_desc_surface)->content_rect());
}

TEST_F(DrawPropertiesTest, VisibleRectForDescendantOfScaledSurface) {
  LayerImpl* root = root_layer();
  LayerImpl* surface = AddLayer<LayerImpl>();
  LayerImpl* clip_layer = AddLayer<LayerImpl>();
  LayerImpl* clip_parent = AddLayer<LayerImpl>();
  LayerImpl* unclipped_desc_surface = AddLayer<LayerImpl>();
  LayerImpl* clip_child = AddLayer<LayerImpl>();

  root->SetBounds(gfx::Size(100, 100));
  surface->SetBounds(gfx::Size(100, 100));
  clip_layer->SetBounds(gfx::Size(20, 20));
  clip_parent->SetBounds(gfx::Size(50, 50));
  unclipped_desc_surface->SetBounds(gfx::Size(100, 100));
  unclipped_desc_surface->SetDrawsContent(true);
  clip_child->SetBounds(gfx::Size(100, 100));
  clip_child->SetDrawsContent(true);

  CopyProperties(root, surface);
  CreateTransformNode(surface).local.Scale(2, 2);
  CreateEffectNode(surface).render_surface_reason = RenderSurfaceReason::kTest;
  CreateClipNode(surface);
  CopyProperties(surface, clip_layer);
  CreateClipNode(clip_layer);
  CopyProperties(clip_layer, clip_parent);
  CopyProperties(clip_parent, unclipped_desc_surface);
  CreateEffectNode(unclipped_desc_surface).render_surface_reason =
      RenderSurfaceReason::kTest;
  CopyProperties(unclipped_desc_surface, clip_child);
  clip_child->SetClipTreeIndex(clip_parent->clip_tree_index());

  UpdateActiveTreeDrawProperties();

  EXPECT_EQ(gfx::Rect(20, 20), clip_child->visible_layer_rect());
}

TEST_F(DrawPropertiesTest, LayerWithInputHandlerAndZeroOpacity) {
  LayerImpl* root = root_layer();
  LayerImpl* render_surface = AddLayer<LayerImpl>();
  LayerImpl* test_layer = AddLayer<LayerImpl>();

  gfx::Transform translation;
  translation.Translate(10, 10);

  root->SetBounds(gfx::Size(30, 30));
  render_surface->SetBounds(gfx::Size(30, 30));
  render_surface->SetMasksToBounds(true);
  test_layer->SetBounds(gfx::Size(20, 20));
  test_layer->SetDrawsContent(true);

  TouchActionRegion touch_action_region;
  touch_action_region.Union(kTouchActionNone, gfx::Rect(0, 0, 20, 20));
  test_layer->SetTouchActionRegion(std::move(touch_action_region));

  CopyProperties(root, render_surface);
  CreateEffectNode(render_surface).render_surface_reason =
      RenderSurfaceReason::kTest;
  CreateClipNode(render_surface);
  CopyProperties(render_surface, test_layer);
  CreateTransformNode(test_layer).local = translation;
  CreateEffectNode(test_layer).opacity = 0.f;

  UpdateActiveTreeDrawProperties();
  EXPECT_TRANSFORMATION_MATRIX_EQ(translation,
                                  test_layer->ScreenSpaceTransform());
}

TEST_F(DrawPropertiesTest, ClipParentDrawsIntoScaledRootSurface) {
  LayerImpl* root = root_layer();
  LayerImpl* clip_layer = AddLayer<LayerImpl>();
  LayerImpl* clip_parent = AddLayer<LayerImpl>();
  LayerImpl* clip_parent_child = AddLayer<LayerImpl>();
  LayerImpl* unclipped_desc_surface = AddLayer<LayerImpl>();
  LayerImpl* clip_child = AddLayer<LayerImpl>();

  root->SetBounds(gfx::Size(100, 100));
  clip_layer->SetBounds(gfx::Size(20, 20));
  clip_parent->SetBounds(gfx::Size(50, 50));
  clip_parent_child->SetBounds(gfx::Size(20, 20));
  unclipped_desc_surface->SetBounds(gfx::Size(100, 100));
  unclipped_desc_surface->SetDrawsContent(true);
  clip_child->SetBounds(gfx::Size(100, 100));
  clip_child->SetDrawsContent(true);

  CopyProperties(root, clip_layer);
  CreateClipNode(clip_layer);
  CopyProperties(clip_layer, clip_parent);
  CopyProperties(clip_parent, clip_parent_child);
  CreateClipNode(clip_parent_child);
  CopyProperties(clip_parent_child, unclipped_desc_surface);
  CreateTransformNode(unclipped_desc_surface).local.Translate(10, 10);
  CreateEffectNode(unclipped_desc_surface).render_surface_reason =
      RenderSurfaceReason::kTest;
  CopyProperties(unclipped_desc_surface, clip_child);
  clip_child->SetClipTreeIndex(clip_parent->clip_tree_index());

  float device_scale_factor = 1.f;
  UpdateActiveTreeDrawProperties(device_scale_factor);
  EXPECT_EQ(gfx::Rect(-10, -10, 20, 20), clip_child->clip_rect());
  EXPECT_EQ(gfx::Rect(10, 10), clip_child->visible_layer_rect());

  device_scale_factor = 2.f;
  UpdateActiveTreeDrawProperties(device_scale_factor);
  EXPECT_EQ(gfx::Rect(-20, -20, 40, 40), clip_child->clip_rect());
  EXPECT_EQ(gfx::Rect(10, 10), clip_child->visible_layer_rect());
}

TEST_F(DrawPropertiesTest, ClipChildVisibleRect) {
  LayerImpl* root = root_layer();
  LayerImpl* clip_parent = AddLayer<LayerImpl>();
  LayerImpl* render_surface = AddLayer<LayerImpl>();
  LayerImpl* clip_child = AddLayer<LayerImpl>();

  root->SetBounds(gfx::Size(30, 30));
  clip_parent->SetBounds(gfx::Size(40, 40));
  render_surface->SetBounds(gfx::Size(50, 50));
  render_surface->SetDrawsContent(true);
  clip_child->SetBounds(gfx::Size(50, 50));
  clip_child->SetDrawsContent(true);

  CopyProperties(root, clip_parent);
  CreateClipNode(clip_parent);
  CopyProperties(clip_parent, render_surface);
  CreateEffectNode(render_surface).render_surface_reason =
      RenderSurfaceReason::kTest;
  CreateClipNode(render_surface);
  CopyProperties(render_surface, clip_child);
  clip_child->SetClipTreeIndex(clip_parent->clip_tree_index());

  UpdateActiveTreeDrawProperties();
  EXPECT_EQ(gfx::Rect(30, 30), clip_child->visible_layer_rect());
}

TEST_F(DrawPropertiesTest, LayerClipRectLargerThanClippingRenderSurfaceRect) {
  LayerImpl* root = root_layer();
  LayerImpl* render_surface = AddLayer<LayerImpl>();
  LayerImpl* test_layer = AddLayer<LayerImpl>();

  root->SetBounds(gfx::Size(30, 30));
  root->SetDrawsContent(true);
  render_surface->SetBounds(gfx::Size(50, 50));
  render_surface->SetDrawsContent(true);

  test_layer->SetBounds(gfx::Size(50, 50));
  test_layer->SetDrawsContent(true);

  CreateClipNode(root);
  CopyProperties(root, render_surface);
  CreateTransformNode(render_surface);
  CreateEffectNode(render_surface).render_surface_reason =
      RenderSurfaceReason::kTest;
  CreateClipNode(render_surface);
  CopyProperties(render_surface, test_layer);
  CreateClipNode(test_layer);

  UpdateActiveTreeDrawProperties();

  EXPECT_EQ(gfx::Rect(30, 30), root->clip_rect());
  EXPECT_EQ(gfx::Rect(50, 50), render_surface->clip_rect());
  EXPECT_EQ(gfx::Rect(50, 50), test_layer->clip_rect());
}

// Needs layer tree mode: hide_layer_and_subtree.
TEST_F(DrawPropertiesTestWithLayerTree, SubtreeIsHiddenTest) {
  // Tests that subtree is hidden is updated.
  auto root = Layer::Create();
  host()->SetRootLayer(root);
  auto hidden = Layer::Create();
  root->AddChild(hidden);
  auto test = Layer::Create();
  hidden->AddChild(test);

  root->SetBounds(gfx::Size(30, 30));
  hidden->SetBounds(gfx::Size(30, 30));
  hidden->SetForceRenderSurfaceForTesting(true);
  hidden->SetHideLayerAndSubtree(true);
  test->SetBounds(gfx::Size(30, 30));
  test->SetForceRenderSurfaceForTesting(true);

  CommitAndActivate();

  EXPECT_EQ(
      0.f,
      GetRenderSurfaceImpl(test)->OwningEffectNode()->screen_space_opacity);

  hidden->SetHideLayerAndSubtree(false);
  CommitAndActivate();
  EXPECT_EQ(
      1.f,
      GetRenderSurfaceImpl(test)->OwningEffectNode()->screen_space_opacity);
}

TEST_F(DrawPropertiesTest, TwoUnclippedRenderSurfaces) {
  LayerImpl* root = root_layer();
  LayerImpl* clip_layer = AddLayer<LayerImpl>();
  LayerImpl* render_surface1 = AddLayer<LayerImpl>();
  LayerImpl* render_surface2 = AddLayer<LayerImpl>();
  LayerImpl* clip_child = AddLayer<LayerImpl>();

  root->SetBounds(gfx::Size(30, 30));
  clip_layer->SetBounds(gfx::Size(30, 30));
  render_surface1->SetBounds(gfx::Size(30, 30));
  render_surface1->SetDrawsContent(true);
  render_surface2->SetBounds(gfx::Size(30, 30));
  render_surface2->SetDrawsContent(true);
  clip_child->SetBounds(gfx::Size(30, 30));
  clip_child->SetDrawsContent(true);

  CreateClipNode(root);
  CopyProperties(root, clip_layer);
  CreateClipNode(clip_layer);
  CopyProperties(clip_layer, render_surface1);
  CreateTransformNode(render_surface1).post_translation =
      gfx::Vector2dF(10, 10);
  CreateEffectNode(render_surface1).render_surface_reason =
      RenderSurfaceReason::kTest;
  CopyProperties(render_surface1, render_surface2);
  CreateEffectNode(render_surface2).render_surface_reason =
      RenderSurfaceReason::kTest;
  CopyProperties(render_surface2, clip_child);
  clip_child->SetClipTreeIndex(root->clip_tree_index());

  UpdateActiveTreeDrawProperties();

  EXPECT_EQ(gfx::Rect(-10, -10, 30, 30), render_surface2->clip_rect());
}

// Needs layer tree mode: mask layer.
TEST_F(DrawPropertiesTestWithLayerTree, MaskLayerDrawProperties) {
  // Tests that a mask layer's draw properties are computed correctly.
  auto root = Layer::Create();
  host()->SetRootLayer(root);
  auto child = Layer::Create();
  root->AddChild(child);
  FakeContentLayerClient client;
  auto mask = PictureLayer::Create(&client);
  child->SetMaskLayer(mask);

  gfx::Transform transform;
  transform.Translate(10, 10);

  root->SetBounds(gfx::Size(40, 40));
  root->SetIsDrawable(true);
  child->SetTransform(transform);
  child->SetBounds(gfx::Size(30, 30));
  child->SetIsDrawable(true);
  child->SetOpacity(0.f);
  mask->SetBounds(gfx::Size(30, 30));

  CommitAndActivate();

  // The render surface created for the mask has no contributing content, so the
  // mask doesn't contribute to a drawn render surface. This means it has an
  // empty visible rect, but its screen space transform can still be computed
  // correctly on-demand.
  EXPECT_FALSE(ImplOf(child)->contributes_to_drawn_render_surface());
  EXPECT_FALSE(ImplOf(mask)->contributes_to_drawn_render_surface());
  EXPECT_EQ(gfx::Rect(), ImplOf(mask)->visible_layer_rect());
  EXPECT_TRANSFORMATION_MATRIX_EQ(transform,
                                  ImplOf(mask)->ScreenSpaceTransform());

  // Make the child's render surface have contributing content.
  child->SetOpacity(1.f);
  CommitAndActivate();
  EXPECT_TRUE(ImplOf(mask)->contributes_to_drawn_render_surface());
  EXPECT_EQ(gfx::Rect(30, 30), ImplOf(mask)->visible_layer_rect());
  EXPECT_TRANSFORMATION_MATRIX_EQ(transform,
                                  ImplOf(mask)->ScreenSpaceTransform());

  transform.Translate(10, 10);
  child->SetTransform(transform);
  CommitAndActivate();
  EXPECT_TRANSFORMATION_MATRIX_EQ(transform,
                                  ImplOf(mask)->ScreenSpaceTransform());
  EXPECT_EQ(gfx::Rect(20, 20), ImplOf(mask)->visible_layer_rect());

  // For now SetIsDrawable of masked layer doesn't affect draw properties of
  // the mask layer because it doesn't affect property trees.
  child->SetIsDrawable(false);
  CommitAndActivate();
  EXPECT_TRUE(ImplOf(mask)->contributes_to_drawn_render_surface());

  // SetIsDrawable of mask layer itself affects its draw properties.
  mask->SetIsDrawable(false);
  CommitAndActivate();
  EXPECT_FALSE(ImplOf(mask)->contributes_to_drawn_render_surface());
}

TEST_F(DrawPropertiesTest, SublayerScaleWithTransformNodeBetweenTwoTargets) {
  LayerImpl* root = root_layer();
  LayerImpl* render_surface1 = AddLayer<LayerImpl>();
  LayerImpl* between_targets = AddLayer<LayerImpl>();
  LayerImpl* render_surface2 = AddLayer<LayerImpl>();
  LayerImpl* test_layer = AddLayer<LayerImpl>();

  gfx::Transform scale;
  scale.Scale(2.f, 2.f);

  root->SetBounds(gfx::Size(30, 30));
  render_surface1->SetBounds(gfx::Size(30, 30));
  between_targets->SetBounds(gfx::Size(30, 30));
  render_surface2->SetBounds(gfx::Size(30, 30));
  test_layer->SetBounds(gfx::Size(30, 30));
  test_layer->SetDrawsContent(true);

  // We want layer between the two targets to create a clip node and effect
  // node but it shouldn't create a render surface.
  between_targets->SetMasksToBounds(true);
  CopyProperties(root, render_surface1);
  CreateTransformNode(render_surface1).local = scale;
  CreateEffectNode(render_surface1).render_surface_reason =
      RenderSurfaceReason::kTest;
  CopyProperties(render_surface1, between_targets);
  CreateEffectNode(between_targets).opacity = 0.5f;
  CreateClipNode(between_targets);
  CopyProperties(between_targets, render_surface2);
  CreateEffectNode(render_surface2).render_surface_reason =
      RenderSurfaceReason::kTest;
  CopyProperties(render_surface2, test_layer);

  UpdateActiveTreeDrawProperties();

  EXPECT_EQ(gfx::Vector2dF(2.f, 2.f),
            GetEffectNode(render_surface1)->surface_contents_scale);
  EXPECT_EQ(gfx::Vector2dF(1.f, 1.f),
            GetEffectNode(between_targets)->surface_contents_scale);
  EXPECT_EQ(gfx::Vector2dF(2.f, 2.f),
            GetEffectNode(render_surface2)->surface_contents_scale);

  EXPECT_EQ(gfx::Rect(15, 15), test_layer->visible_layer_rect());
}

TEST_F(DrawPropertiesTest, NoisyTransform) {
  LayerImpl* root = root_layer();
  LayerImpl* render_surface = AddLayer<LayerImpl>();
  LayerImpl* parent = AddLayer<LayerImpl>();
  LayerImpl* child = AddLayer<LayerImpl>();

  root->SetBounds(gfx::Size(30, 30));
  parent->SetBounds(gfx::Size(30, 30));
  parent->SetDrawsContent(true);
  child->SetBounds(gfx::Size(30, 30));
  child->SetDrawsContent(true);

  // A noisy transform that's invertible.
  gfx::Transform transform;
  transform.matrix().setDouble(0, 0, 6.12323e-17);
  transform.matrix().setDouble(0, 2, 1);
  transform.matrix().setDouble(2, 2, 6.12323e-17);
  transform.matrix().setDouble(2, 0, -1);

  CopyProperties(root, render_surface);
  CreateTransformNode(render_surface).local = transform;
  CreateEffectNode(render_surface).render_surface_reason =
      RenderSurfaceReason::kTest;
  CopyProperties(render_surface, parent);
  CopyProperties(parent, child);
  CreateTransformNode(child).local = transform;

  UpdateActiveTreeDrawProperties();

  gfx::Transform expected;
  expected.matrix().setDouble(0, 0, 3.749395e-33);
  expected.matrix().setDouble(0, 2, 6.12323e-17);
  expected.matrix().setDouble(2, 0, -1);
  expected.matrix().setDouble(2, 2, 6.12323e-17);
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected, child->ScreenSpaceTransform());
}

TEST_F(DrawPropertiesTest, LargeTransformTest) {
  LayerImpl* root = root_layer();
  LayerImpl* render_surface1 = AddLayer<LayerImpl>();
  LayerImpl* child = AddLayer<LayerImpl>();

  child->SetDrawsContent(true);
  child->SetMasksToBounds(true);

  gfx::Transform large_transform;
  large_transform.Scale(99999999999999999999.f, 99999999999999999999.f);
  large_transform.Scale(9999999999999999999.f, 9999999999999999999.f);
  EXPECT_TRUE(std::isinf(large_transform.matrix().get(0, 0)));
  EXPECT_TRUE(std::isinf(large_transform.matrix().get(1, 1)));

  root->SetBounds(gfx::Size(30, 30));
  render_surface1->SetBounds(gfx::Size(30, 30));

  // TODO(sunxd): we make child have no render surface, because if the
  // child has one, the large transform applied to child will result in NaNs in
  // the draw_transform of the render_surface, thus make draw property updates
  // skip the child layer. We need further investigation into this to know
  // what exactly happens here.
  child->SetBounds(gfx::Size(30, 30));

  CopyProperties(root, render_surface1);
  CreateEffectNode(render_surface1).render_surface_reason =
      RenderSurfaceReason::kTest;
  CopyProperties(render_surface1, child);
  CreateTransformNode(child).local = large_transform;
  CreateClipNode(child);

  UpdateActiveTreeDrawProperties();

  EXPECT_EQ(gfx::RectF(),
            GetRenderSurface(render_surface1)->DrawableContentRect());

  bool is_inf_or_nan = std::isinf(child->DrawTransform().matrix().get(0, 0)) ||
                       std::isnan(child->DrawTransform().matrix().get(0, 0));
  EXPECT_TRUE(is_inf_or_nan);

  is_inf_or_nan = std::isinf(child->DrawTransform().matrix().get(1, 1)) ||
                  std::isnan(child->DrawTransform().matrix().get(1, 1));
  EXPECT_TRUE(is_inf_or_nan);

  // The root layer should be in the RenderSurfaceList.
  EXPECT_TRUE(base::Contains(GetRenderSurfaceList(), GetRenderSurface(root)));
}

// In layer tree mode, not using impl-side PropertyTreeBuilder.
TEST_F(DrawPropertiesTestWithLayerTree, OpacityAnimationsTrackingTest) {
  scoped_refptr<Layer> root = Layer::Create();
  scoped_refptr<Layer> animated = Layer::Create();
  animated->SetIsDrawable(true);
  root->AddChild(animated);
  host()->SetRootLayer(root);
  host()->SetElementIdsForTesting();

  root->SetBounds(gfx::Size(100, 100));
  root->SetForceRenderSurfaceForTesting(true);
  animated->SetBounds(gfx::Size(20, 20));
  animated->SetOpacity(0.f);

  scoped_refptr<SingleKeyframeEffectAnimation> animation =
      SingleKeyframeEffectAnimation::Create(
          AnimationIdProvider::NextAnimationId());
  timeline()->AttachAnimation(animation);

  animation->AttachElement(animated->element_id());

  int keyframe_model_id = 0;
  std::unique_ptr<KeyframeModel> keyframe_model = KeyframeModel::Create(
      std::unique_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 0.f, 1.f)),
      keyframe_model_id, 1, TargetProperty::OPACITY);
  keyframe_model->set_fill_mode(KeyframeModel::FillMode::NONE);
  keyframe_model->set_time_offset(base::TimeDelta::FromMilliseconds(-1000));
  KeyframeModel* keyframe_model_ptr = keyframe_model.get();
  AddKeyframeModelToElementWithExistingKeyframeEffect(
      animated->element_id(), timeline(), std::move(keyframe_model));

  UpdateMainDrawProperties();

  EffectNode* node = GetEffectNode(animated.get());
  EXPECT_FALSE(node->is_currently_animating_opacity);
  EXPECT_TRUE(node->has_potential_opacity_animation);

  keyframe_model_ptr->set_time_offset(base::TimeDelta::FromMilliseconds(0));
  host()->AnimateLayers(base::TimeTicks::Max());
  node = GetEffectNode(animated.get());
  EXPECT_TRUE(node->is_currently_animating_opacity);
  EXPECT_TRUE(node->has_potential_opacity_animation);

  animation->AbortKeyframeModelsWithProperty(TargetProperty::OPACITY,
                                             false /*needs_completion*/);
  node = GetEffectNode(animated.get());
  EXPECT_FALSE(node->is_currently_animating_opacity);
  EXPECT_FALSE(node->has_potential_opacity_animation);
}

// In layer tree mode, not using impl-side PropertyTreeBuilder.
TEST_F(DrawPropertiesTestWithLayerTree, TransformAnimationsTrackingTest) {
  scoped_refptr<Layer> root = Layer::Create();
  scoped_refptr<Layer> animated = Layer::Create();
  animated->SetIsDrawable(true);
  root->AddChild(animated);
  host()->SetRootLayer(root);
  host()->SetElementIdsForTesting();

  root->SetBounds(gfx::Size(100, 100));
  root->SetForceRenderSurfaceForTesting(true);
  animated->SetBounds(gfx::Size(20, 20));

  scoped_refptr<SingleKeyframeEffectAnimation> animation =
      SingleKeyframeEffectAnimation::Create(
          AnimationIdProvider::NextAnimationId());
  timeline()->AttachAnimation(animation);
  animation->AttachElement(animated->element_id());

  std::unique_ptr<KeyframedTransformAnimationCurve> curve(
      KeyframedTransformAnimationCurve::Create());
  TransformOperations start;
  start.AppendTranslate(1.f, 2.f, 3.f);
  gfx::Transform transform;
  transform.Scale3d(1.0, 2.0, 3.0);
  TransformOperations operation;
  operation.AppendMatrix(transform);
  curve->AddKeyframe(
      TransformKeyframe::Create(base::TimeDelta(), start, nullptr));
  curve->AddKeyframe(TransformKeyframe::Create(
      base::TimeDelta::FromSecondsD(1.0), operation, nullptr));
  std::unique_ptr<KeyframeModel> keyframe_model(
      KeyframeModel::Create(std::move(curve), 3, 3, TargetProperty::TRANSFORM));
  keyframe_model->set_fill_mode(KeyframeModel::FillMode::NONE);
  keyframe_model->set_time_offset(base::TimeDelta::FromMilliseconds(-1000));
  KeyframeModel* keyframe_model_ptr = keyframe_model.get();
  AddKeyframeModelToElementWithExistingKeyframeEffect(
      animated->element_id(), timeline(), std::move(keyframe_model));

  UpdateMainDrawProperties();

  TransformNode* node = GetTransformNode(animated.get());
  EXPECT_FALSE(node->is_currently_animating);
  EXPECT_TRUE(node->has_potential_animation);

  keyframe_model_ptr->set_time_offset(base::TimeDelta::FromMilliseconds(0));
  host()->AnimateLayers(base::TimeTicks::Max());
  node = GetTransformNode(animated.get());
  EXPECT_TRUE(node->is_currently_animating);
  EXPECT_TRUE(node->has_potential_animation);

  animation->AbortKeyframeModelsWithProperty(TargetProperty::TRANSFORM,
                                             false /*needs_completion*/);
  node = GetTransformNode(animated.get());
  EXPECT_FALSE(node->is_currently_animating);
  EXPECT_FALSE(node->has_potential_animation);
}

// Needs layer tree mode: copy request.
TEST_F(DrawPropertiesTestWithLayerTree, CopyRequestScalingTest) {
  auto root = Layer::Create();
  host()->SetRootLayer(root);
  auto scale_layer = Layer::Create();
  root->AddChild(scale_layer);
  auto copy_layer = Layer::Create();
  scale_layer->AddChild(copy_layer);
  auto clip_layer = Layer::Create();
  copy_layer->AddChild(clip_layer);
  auto test_layer = Layer::Create();
  clip_layer->AddChild(test_layer);

  root->SetBounds(gfx::Size(150, 150));

  scale_layer->SetBounds(gfx::Size(30, 30));
  gfx::Transform transform;
  transform.Scale(5.f, 5.f);
  scale_layer->SetTransform(transform);

  // Need to persist the render surface after copy request is cleared.
  copy_layer->SetForceRenderSurfaceForTesting(true);
  copy_layer->RequestCopyOfOutput(
      viz::CopyOutputRequest::CreateStubForTesting());

  clip_layer->SetIsDrawable(true);
  clip_layer->SetMasksToBounds(true);
  clip_layer->SetBounds(gfx::Size(10, 10));

  test_layer->SetIsDrawable(true);
  test_layer->SetMasksToBounds(true);
  test_layer->SetBounds(gfx::Size(20, 20));

  CommitAndActivate();

  // Check surface with copy request draw properties.
  EXPECT_EQ(gfx::Rect(50, 50),
            GetRenderSurfaceImpl(copy_layer)->content_rect());
  EXPECT_EQ(gfx::Transform(),
            GetRenderSurfaceImpl(copy_layer)->draw_transform());
  EXPECT_EQ(gfx::RectF(50.0f, 50.0f),
            GetRenderSurfaceImpl(copy_layer)->DrawableContentRect());

  // Check test layer draw properties.
  EXPECT_EQ(gfx::Rect(10, 10), ImplOf(test_layer)->visible_layer_rect());
  EXPECT_EQ(transform, ImplOf(test_layer)->DrawTransform());
  EXPECT_EQ(gfx::Rect(50, 50), ImplOf(test_layer)->clip_rect());
  EXPECT_EQ(gfx::Rect(50, 50), ImplOf(test_layer)->drawable_content_rect());

  // Clear the copy request and call UpdateSurfaceContentsScale.
  GetPropertyTrees(root.get())->effect_tree.ClearCopyRequests();
  CommitAndActivate();
}

// Needs layer tree mode: hide_layer_and_subtree, etc.
TEST_F(DrawPropertiesTestWithLayerTree, SubtreeHiddenWithCacheRenderSurface) {
  auto root = Layer::Create();
  host()->SetRootLayer(root);
  root->SetBounds(gfx::Size(50, 50));
  root->SetIsDrawable(true);

  auto cache_grand_parent_sibling_before = Layer::Create();
  root->AddChild(cache_grand_parent_sibling_before);
  cache_grand_parent_sibling_before->SetBounds(gfx::Size(40, 40));
  cache_grand_parent_sibling_before->SetIsDrawable(true);

  auto cache_grand_parent = Layer::Create();
  root->AddChild(cache_grand_parent);
  cache_grand_parent->SetBounds(gfx::Size(40, 40));
  cache_grand_parent->SetIsDrawable(true);

  auto cache_parent = Layer::Create();
  cache_grand_parent->AddChild(cache_parent);
  cache_parent->SetBounds(gfx::Size(30, 30));
  cache_parent->SetIsDrawable(true);
  cache_parent->SetForceRenderSurfaceForTesting(true);

  auto cache_render_surface = Layer::Create();
  cache_parent->AddChild(cache_render_surface);
  cache_render_surface->SetBounds(gfx::Size(20, 20));
  cache_render_surface->SetIsDrawable(true);
  cache_render_surface->SetCacheRenderSurface(true);

  auto cache_child = Layer::Create();
  cache_render_surface->AddChild(cache_child);
  cache_child->SetBounds(gfx::Size(20, 20));
  cache_child->SetIsDrawable(true);

  auto cache_grand_child = Layer::Create();
  cache_child->AddChild(cache_grand_child);
  cache_grand_child->SetBounds(gfx::Size(20, 20));
  cache_grand_child->SetIsDrawable(true);

  auto cache_grand_parent_sibling_after = Layer::Create();
  root->AddChild(cache_grand_parent_sibling_after);
  cache_grand_parent_sibling_after->SetBounds(gfx::Size(40, 40));
  cache_grand_parent_sibling_after->SetIsDrawable(true);

  // Hide the cache_grand_parent and its subtree. But cache a render surface in
  // that hidden subtree on cache_layer. Also hide the cache grand child and its
  // subtree.
  cache_grand_parent->SetHideLayerAndSubtree(true);
  cache_grand_parent_sibling_before->SetHideLayerAndSubtree(true);
  cache_grand_parent_sibling_after->SetHideLayerAndSubtree(true);
  cache_grand_child->SetHideLayerAndSubtree(true);

  CommitAndActivate();

  // We should have four render surfaces, one for the root, one for the grand
  // parent since it has opacity and two drawing descendants, one for the parent
  // since it owns a surface, and one for the cache.
  ASSERT_EQ(4u, GetRenderSurfaceList().size());
  EXPECT_EQ(static_cast<uint64_t>(root->id()),
            GetRenderSurfaceList().at(0)->id());
  EXPECT_EQ(static_cast<uint64_t>(cache_grand_parent->id()),
            GetRenderSurfaceList().at(1)->id());
  EXPECT_EQ(static_cast<uint64_t>(cache_parent->id()),
            GetRenderSurfaceList().at(2)->id());
  EXPECT_EQ(static_cast<uint64_t>(cache_render_surface->id()),
            GetRenderSurfaceList().at(3)->id());

  // The root render surface should have 2 contributing layers.
  EXPECT_EQ(2, GetRenderSurfaceImpl(root)->num_contributors());
  EXPECT_TRUE(ImplOf(root)->contributes_to_drawn_render_surface());
  EXPECT_FALSE(
      ImplOf(cache_grand_parent)->contributes_to_drawn_render_surface());
  EXPECT_FALSE(ImplOf(cache_grand_parent_sibling_before)
                   ->contributes_to_drawn_render_surface());
  EXPECT_FALSE(ImplOf(cache_grand_parent_sibling_after)
                   ->contributes_to_drawn_render_surface());

  // Nothing actually draws into the cache parent, so only the cache will
  // appear in its list, since it needs to be drawn for the cache render
  // surface.
  ASSERT_EQ(1, GetRenderSurfaceImpl(cache_parent)->num_contributors());
  EXPECT_FALSE(ImplOf(cache_parent)->contributes_to_drawn_render_surface());

  // The cache layer's render surface should have 2 contributing layers.
  ASSERT_EQ(2, GetRenderSurfaceImpl(cache_render_surface)->num_contributors());
  EXPECT_TRUE(
      ImplOf(cache_render_surface)->contributes_to_drawn_render_surface());
  EXPECT_TRUE(ImplOf(cache_child)->contributes_to_drawn_render_surface());
  EXPECT_FALSE(
      ImplOf(cache_grand_child)->contributes_to_drawn_render_surface());

  // cache_grand_parent, cache_parent shouldn't be drawn because they are
  // hidden, but the cache and cache_child should be drawn for the cache
  // render surface. cache grand child should not be drawn as its hidden even in
  // the cache render surface.
  EXPECT_FALSE(GetEffectNode(ImplOf(cache_grand_parent))->is_drawn);
  EXPECT_FALSE(GetEffectNode(ImplOf(cache_parent))->is_drawn);
  EXPECT_TRUE(GetEffectNode(ImplOf(cache_render_surface))->is_drawn);
  EXPECT_TRUE(GetEffectNode(ImplOf(cache_child))->is_drawn);
  EXPECT_FALSE(GetEffectNode(ImplOf(cache_grand_child))->is_drawn);

  // Though cache is drawn, it shouldn't contribute to drawn surface as
  // its actually hidden.
  EXPECT_FALSE(GetRenderSurfaceImpl(cache_render_surface)
                   ->contributes_to_drawn_surface());
}

// Needs layer tree mode: copy request.
TEST_F(DrawPropertiesTestWithLayerTree,
       VisibleRectInNonRootCacheRenderSurface) {
  auto root = Layer::Create();
  host()->SetRootLayer(root);
  root->SetBounds(gfx::Size(50, 50));
  root->SetIsDrawable(true);
  root->SetMasksToBounds(true);

  auto cache_render_surface_layer = Layer::Create();
  root->AddChild(cache_render_surface_layer);
  cache_render_surface_layer->SetBounds(gfx::Size(120, 120));
  cache_render_surface_layer->SetIsDrawable(true);
  cache_render_surface_layer->SetCacheRenderSurface(true);

  auto copy_layer = Layer::Create();
  cache_render_surface_layer->AddChild(copy_layer);
  copy_layer->SetBounds(gfx::Size(100, 100));
  copy_layer->SetIsDrawable(true);
  copy_layer->SetForceRenderSurfaceForTesting(true);

  auto copy_child = Layer::Create();
  copy_layer->AddChild(copy_child);
  copy_child->SetPosition(gfx::PointF(40.f, 40.f));
  copy_child->SetBounds(gfx::Size(20, 20));
  copy_child->SetIsDrawable(true);

  auto copy_clip = Layer::Create();
  copy_layer->AddChild(copy_clip);
  copy_clip->SetBounds(gfx::Size(55, 55));
  copy_clip->SetMasksToBounds(true);

  auto copy_clipped_child = Layer::Create();
  copy_clip->AddChild(copy_clipped_child);
  copy_clipped_child->SetPosition(gfx::PointF(40.f, 40.f));
  copy_clipped_child->SetBounds(gfx::Size(20, 20));
  copy_clipped_child->SetIsDrawable(true);

  auto cache_surface = Layer::Create();
  copy_clip->AddChild(cache_surface);
  cache_surface->SetPosition(gfx::PointF(45.f, 45.f));
  cache_surface->SetBounds(gfx::Size(20, 20));
  cache_surface->SetIsDrawable(true);

  CommitAndActivate();

  EXPECT_EQ(gfx::Rect(120, 120),
            ImplOf(cache_render_surface_layer)->visible_layer_rect());
  EXPECT_EQ(gfx::Rect(100, 100), ImplOf(copy_layer)->visible_layer_rect());
  EXPECT_EQ(gfx::Rect(20, 20), ImplOf(copy_child)->visible_layer_rect());
  EXPECT_EQ(gfx::Rect(15, 15),
            ImplOf(copy_clipped_child)->visible_layer_rect());
  EXPECT_EQ(gfx::Rect(10, 10), ImplOf(cache_surface)->visible_layer_rect());

  // Case 2: When the non root cache render surface layer is clipped.
  cache_render_surface_layer->SetBounds(gfx::Size(50, 50));
  cache_render_surface_layer->SetMasksToBounds(true);
  CommitAndActivate();
  EXPECT_EQ(gfx::Rect(50, 50),
            ImplOf(cache_render_surface_layer)->visible_layer_rect());
  EXPECT_EQ(gfx::Rect(50, 50), ImplOf(copy_layer)->visible_layer_rect());
  EXPECT_EQ(gfx::Rect(10, 10), ImplOf(copy_child)->visible_layer_rect());
  EXPECT_EQ(gfx::Rect(10, 10),
            ImplOf(copy_clipped_child)->visible_layer_rect());
  EXPECT_EQ(gfx::Rect(5, 5), ImplOf(cache_surface)->visible_layer_rect());

  // Case 3: When there is device scale factor.
  float device_scale_factor = 2.f;
  CommitAndActivate(device_scale_factor);
  EXPECT_EQ(gfx::Rect(50, 50),
            ImplOf(cache_render_surface_layer)->visible_layer_rect());
  EXPECT_EQ(gfx::Rect(50, 50), ImplOf(copy_layer)->visible_layer_rect());
  EXPECT_EQ(gfx::Rect(10, 10), ImplOf(copy_child)->visible_layer_rect());
  EXPECT_EQ(gfx::Rect(10, 10),
            ImplOf(copy_clipped_child)->visible_layer_rect());
  EXPECT_EQ(gfx::Rect(5, 5), ImplOf(cache_surface)->visible_layer_rect());

  // Case 4: When the non root cache render surface layer is clipped and there
  // is a copy request layer beneath it.
  copy_layer->RequestCopyOfOutput(
      viz::CopyOutputRequest::CreateStubForTesting());
  ASSERT_TRUE(copy_layer->HasCopyRequest());
  CommitAndActivate();
  ASSERT_FALSE(copy_layer->HasCopyRequest());
  EXPECT_EQ(gfx::Rect(50, 50),
            ImplOf(cache_render_surface_layer)->visible_layer_rect());
  EXPECT_EQ(gfx::Rect(100, 100), ImplOf(copy_layer)->visible_layer_rect());
  EXPECT_EQ(gfx::Rect(20, 20), ImplOf(copy_child)->visible_layer_rect());
  EXPECT_EQ(gfx::Rect(15, 15),
            ImplOf(copy_clipped_child)->visible_layer_rect());
  EXPECT_EQ(gfx::Rect(10, 10), ImplOf(cache_surface)->visible_layer_rect());

  // Case 5: When there is another cache render surface layer under the copy
  // request layer.
  cache_surface->SetCacheRenderSurface(true);
  copy_layer->RequestCopyOfOutput(
      viz::CopyOutputRequest::CreateStubForTesting());
  ASSERT_TRUE(copy_layer->HasCopyRequest());
  CommitAndActivate();
  ASSERT_FALSE(copy_layer->HasCopyRequest());
  EXPECT_EQ(gfx::Rect(50, 50),
            ImplOf(cache_render_surface_layer)->visible_layer_rect());
  EXPECT_EQ(gfx::Rect(100, 100), ImplOf(copy_layer)->visible_layer_rect());
  EXPECT_EQ(gfx::Rect(20, 20), ImplOf(copy_child)->visible_layer_rect());
  EXPECT_EQ(gfx::Rect(15, 15),
            ImplOf(copy_clipped_child)->visible_layer_rect());
  EXPECT_EQ(gfx::Rect(20, 20), ImplOf(cache_surface)->visible_layer_rect());
}

// In layer tree mode, not using impl-side PropertyTreeBuilder.
TEST_F(DrawPropertiesTestWithLayerTree, CustomLayerClipBounds) {
  // The custom clip API should have the same effect as if an intermediate
  // clip layer has been added to the layer tree. To check this the test creates
  // 2 subtree for a root layer. One of the subtree uses the clip API to clip
  // its subtree while the other uses an intermediate layer. The resulting clip
  // in draw properties are expected to be the same.
  // -Root
  //   - Parent [Clip set to |kClipBounds| using API]
  //     - Child
  //   - Clip Layer [Masks to bounds = true] [Layer bounds set to |kClipBounds|]
  //     - Expected Parent
  //       - Expected Child
  constexpr float kDeviceScale = 1.f;

  const gfx::Rect kRootLayerBounds(0, 0, 100, 100);
  const gfx::Rect kParentLayerBounds(0, 0, 50, 100);
  const gfx::Rect kChildLayerBounds(20, 20, 30, 60);

  constexpr gfx::Rect kClipBounds(10, 10, 50, 50);

  // The position of |Expected Parent| on screen should be same as |Parent|.
  const gfx::Rect kExpectedParentLayerBounds(
      gfx::Point(0, 0) - kClipBounds.OffsetFromOrigin(), gfx::Size(50, 100));

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

  scoped_refptr<Layer> clip_layer = Layer::Create();
  scoped_refptr<Layer> expected_parent = Layer::Create();
  scoped_refptr<Layer> expected_child = Layer::Create();

  root->AddChild(parent);
  parent->AddChild(child);

  root->AddChild(clip_layer);
  clip_layer->AddChild(expected_parent);
  expected_parent->AddChild(expected_child);

  host()->SetRootLayer(root);

  root->SetIsDrawable(true);
  parent->SetIsDrawable(true);
  child->SetIsDrawable(true);
  expected_parent->SetIsDrawable(true);
  expected_child->SetIsDrawable(true);

  // Set layer positions.
  root->SetPosition(gfx::PointF(kRootLayerBounds.origin()));
  parent->SetPosition(gfx::PointF(kParentLayerBounds.origin()));
  child->SetPosition(gfx::PointF(kChildLayerBounds.origin()));

  clip_layer->SetPosition(gfx::PointF(kClipBounds.origin()));
  expected_parent->SetPosition(
      gfx::PointF(kExpectedParentLayerBounds.origin()));
  expected_child->SetPosition(gfx::PointF(kChildLayerBounds.origin()));

  root->SetBounds(kRootLayerBounds.size());
  parent->SetBounds(kParentLayerBounds.size());
  child->SetBounds(kChildLayerBounds.size());

  clip_layer->SetBounds(kClipBounds.size());
  expected_parent->SetBounds(kExpectedParentLayerBounds.size());
  expected_child->SetBounds(kChildLayerBounds.size());

  parent->SetClipRect(kClipBounds);
  clip_layer->SetMasksToBounds(true);

  UpdateMainDrawProperties(kDeviceScale);

  EXPECT_EQ(GetClipNode(parent.get())->clip, gfx::RectF(kClipBounds));
  EXPECT_TRUE(!parent->clip_rect().IsEmpty());

  EXPECT_EQ(GetClipNode(child.get())->clip, gfx::RectF(kClipBounds));

  CommitAndActivate(kDeviceScale);
  LayerTreeImpl* layer_tree_impl = host()->host_impl()->active_tree();

  // Get the layer impl for each Layer.
  LayerImpl* parent_impl = layer_tree_impl->LayerById(parent->id());
  LayerImpl* child_impl = layer_tree_impl->LayerById(child->id());
  LayerImpl* expected_parent_impl =
      layer_tree_impl->LayerById(expected_parent->id());
  LayerImpl* expected_child_impl =
      layer_tree_impl->LayerById(expected_child->id());

  EXPECT_EQ(kDeviceScale, layer_tree_impl->device_scale_factor());

  EXPECT_TRUE(parent_impl->is_clipped());
  EXPECT_TRUE(child_impl->is_clipped());
  ASSERT_TRUE(expected_parent_impl->is_clipped());
  ASSERT_TRUE(expected_child_impl->is_clipped());

  EXPECT_EQ(parent_impl->clip_rect(), expected_parent_impl->clip_rect());
  EXPECT_EQ(child_impl->clip_rect(), expected_child_impl->clip_rect());
}

// In layer tree mode, not using impl-side PropertyTreeBuilder.
TEST_F(DrawPropertiesTestWithLayerTree, CustomLayerClipBoundsWithMaskToBounds) {
  // The custom clip API should have the same effect as if an intermediate
  // clip layer has been added to the layer tree. To check this the test creates
  // 2 subtree for a root layer. One of the subtree uses the clip API to clip
  // its subtree while the other uses an intermediate layer. The resulting clip
  // in draw properties are expected to be the same. In this test, the subtree
  // roots also have their masks to bounds property set.
  // -Root
  //   - Parent [Clip set to |kClipBounds| using API]
  //     - Child
  //   - Clip Layer [Masks to bounds = true] [Layer bounds set to |kClipBounds|]
  //     - Expected Parent [Masks to bounds = true]
  //       - Expected Child
  constexpr float kDeviceScale = 1.f;

  const gfx::Rect kRootLayerBounds(0, 0, 100, 100);
  const gfx::Rect kParentLayerBounds(0, 0, 50, 100);
  const gfx::Rect kChildLayerBounds(20, 20, 30, 60);

  constexpr gfx::Rect kClipBounds(10, 10, 50, 50);

  // The position of |Expected Parent| on screen should be same as |Parent|.
  const gfx::Rect kExpectedParentLayerBounds(
      gfx::Point(0, 0) - kClipBounds.OffsetFromOrigin(), gfx::Size(50, 100));

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

  scoped_refptr<Layer> clip_layer = Layer::Create();
  scoped_refptr<Layer> expected_parent = Layer::Create();
  scoped_refptr<Layer> expected_child = Layer::Create();

  root->AddChild(parent);
  parent->AddChild(child);

  root->AddChild(clip_layer);
  clip_layer->AddChild(expected_parent);
  expected_parent->AddChild(expected_child);

  host()->SetRootLayer(root);

  root->SetIsDrawable(true);
  parent->SetIsDrawable(true);
  child->SetIsDrawable(true);
  expected_parent->SetIsDrawable(true);
  expected_child->SetIsDrawable(true);

  // Set layer positions.
  root->SetPosition(gfx::PointF(kRootLayerBounds.origin()));
  parent->SetPosition(gfx::PointF(kParentLayerBounds.origin()));
  child->SetPosition(gfx::PointF(kChildLayerBounds.origin()));

  clip_layer->SetPosition(gfx::PointF(kClipBounds.origin()));
  expected_parent->SetPosition(
      gfx::PointF(kExpectedParentLayerBounds.origin()));
  expected_child->SetPosition(gfx::PointF(kChildLayerBounds.origin()));

  root->SetBounds(kRootLayerBounds.size());
  parent->SetBounds(kParentLayerBounds.size());
  child->SetBounds(kChildLayerBounds.size());

  clip_layer->SetBounds(kClipBounds.size());
  expected_parent->SetBounds(kExpectedParentLayerBounds.size());
  expected_child->SetBounds(kChildLayerBounds.size());

  parent->SetClipRect(kClipBounds);
  parent->SetMasksToBounds(true);

  clip_layer->SetMasksToBounds(true);
  expected_parent->SetMasksToBounds(true);

  UpdateMainDrawProperties(kDeviceScale);

  const gfx::RectF expected_clip_bounds = gfx::IntersectRects(
      gfx::RectF(kClipBounds), gfx::RectF(kParentLayerBounds));
  EXPECT_EQ(GetClipNode(parent.get())->clip, expected_clip_bounds);
  EXPECT_TRUE(!parent->clip_rect().IsEmpty());

  EXPECT_EQ(GetClipNode(child.get())->clip, expected_clip_bounds);

  CommitAndActivate(kDeviceScale);
  LayerTreeImpl* layer_tree_impl = host()->host_impl()->active_tree();

  // Get the layer impl for each Layer.
  LayerImpl* parent_impl = layer_tree_impl->LayerById(parent->id());
  LayerImpl* child_impl = layer_tree_impl->LayerById(child->id());
  LayerImpl* expected_parent_impl =
      layer_tree_impl->LayerById(expected_parent->id());
  LayerImpl* expected_child_impl =
      layer_tree_impl->LayerById(expected_child->id());

  EXPECT_EQ(kDeviceScale, layer_tree_impl->device_scale_factor());

  EXPECT_TRUE(parent_impl->is_clipped());
  EXPECT_TRUE(child_impl->is_clipped());
  ASSERT_TRUE(expected_parent_impl->is_clipped());
  ASSERT_TRUE(expected_child_impl->is_clipped());

  EXPECT_EQ(parent_impl->clip_rect(), expected_parent_impl->clip_rect());
  EXPECT_EQ(child_impl->clip_rect(), expected_child_impl->clip_rect());
}

// In layer tree mode, not using impl-side PropertyTreeBuilder.
TEST_F(DrawPropertiesTestWithLayerTree, RoundedCornerOnRenderSurface) {
  // -Root
  //   - Parent 1
  //     - [Render Surface] Child 1 with rounded corner
  //   - [Render Surface] Parent 2 with rounded corner
  //     - [Render Surface] Child 2
  //   - Parent 3 with rounded corner
  //     - [Render Surface] Child 3

  scoped_refptr<Layer> root = Layer::Create();
  host()->SetRootLayer(root);
  root->SetBounds(gfx::Size(250, 250));
  root->SetIsDrawable(true);

  scoped_refptr<Layer> parent_1 = Layer::Create();
  root->AddChild(parent_1);
  parent_1->SetBounds(gfx::Size(80, 80));
  parent_1->SetPosition(gfx::PointF(0, 0));
  parent_1->SetIsDrawable(true);

  scoped_refptr<Layer> parent_2 = Layer::Create();
  root->AddChild(parent_2);
  parent_2->SetBounds(gfx::Size(80, 80));
  parent_1->SetPosition(gfx::PointF(80, 80));
  parent_2->SetIsDrawable(true);
  parent_2->SetForceRenderSurfaceForTesting(true);
  parent_2->SetRoundedCorner(gfx::RoundedCornersF(10.f));
  parent_2->SetIsFastRoundedCorner(true);

  scoped_refptr<Layer> parent_3 = Layer::Create();
  root->AddChild(parent_3);
  parent_3->SetBounds(gfx::Size(80, 80));
  parent_1->SetPosition(gfx::PointF(160, 160));
  parent_3->SetIsDrawable(true);
  parent_3->SetRoundedCorner(gfx::RoundedCornersF(10.f));
  parent_3->SetIsFastRoundedCorner(true);

  scoped_refptr<Layer> child_1 = Layer::Create();
  parent_1->AddChild(child_1);
  child_1->SetBounds(gfx::Size(80, 80));
  child_1->SetIsDrawable(true);
  child_1->SetForceRenderSurfaceForTesting(true);
  child_1->SetRoundedCorner(gfx::RoundedCornersF(10.f));
  child_1->SetIsFastRoundedCorner(true);

  scoped_refptr<Layer> child_2 = Layer::Create();
  parent_2->AddChild(child_2);
  child_2->SetBounds(gfx::Size(80, 80));
  child_2->SetIsDrawable(true);
  child_2->SetForceRenderSurfaceForTesting(true);

  scoped_refptr<Layer> child_3 = Layer::Create();
  parent_3->AddChild(child_3);
  child_3->SetBounds(gfx::Size(80, 80));
  child_3->SetIsDrawable(true);
  child_3->SetForceRenderSurfaceForTesting(true);

  UpdateMainDrawProperties();
  CommitAndActivate();

  EXPECT_FALSE(
      GetRenderSurfaceImpl(child_1)->rounded_corner_bounds().IsEmpty());
  EXPECT_FALSE(
      GetRenderSurfaceImpl(child_2)->rounded_corner_bounds().IsEmpty());
  EXPECT_FALSE(
      GetRenderSurfaceImpl(child_3)->rounded_corner_bounds().IsEmpty());
}

}  // namespace
}  // namespace cc
