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

#include "cc/layers/layer_position_constraint.h"

#include <vector>

#include "cc/layers/layer.h"
#include "cc/layers/layer_impl.h"
#include "cc/proto/layer_position_constraint.pb.h"
#include "cc/test/fake_layer_tree_host.h"
#include "cc/test/fake_proxy.h"
#include "cc/test/geometry_test_utils.h"
#include "cc/test/test_task_graph_runner.h"
#include "cc/trees/layer_tree_host_common.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace cc {
namespace {

class LayerWithForcedDrawsContent : public Layer {
 public:
  LayerWithForcedDrawsContent() {}

  bool DrawsContent() const override;

 private:
  ~LayerWithForcedDrawsContent() override {}
};

bool LayerWithForcedDrawsContent::DrawsContent() const {
  return true;
}

void SetLayerPropertiesForTesting(Layer* layer,
                                  const gfx::Transform& transform,
                                  const gfx::Point3F& transform_origin,
                                  const gfx::PointF& position,
                                  const gfx::Size& bounds,
                                  bool flatten_transform) {
  layer->SetTransform(transform);
  layer->SetTransformOrigin(transform_origin);
  layer->SetPosition(position);
  layer->SetBounds(bounds);
  layer->SetShouldFlattenTransform(flatten_transform);
}

void ExecuteCalculateDrawProperties(LayerImpl* root_layer) {
  std::vector<LayerImpl*> dummy_render_surface_layer_list;
  LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
      root_layer, root_layer->bounds(), &dummy_render_surface_layer_list);
  inputs.inner_viewport_scroll_layer =
      root_layer->layer_tree_impl()->InnerViewportScrollLayer();
  inputs.outer_viewport_scroll_layer =
      root_layer->layer_tree_impl()->OuterViewportScrollLayer();
  EXPECT_FALSE(root_layer->layer_tree_impl()->property_trees()->needs_rebuild);
  LayerTreeHostCommon::CalculateDrawProperties(&inputs);
}

class LayerPositionConstraintTest : public testing::Test {
 public:
  LayerPositionConstraintTest()
      : layer_tree_host_(
            FakeLayerTreeHost::Create(&fake_client_, &task_graph_runner_)),
        root_impl_(nullptr),
        inner_viewport_container_layer_impl_(nullptr),
        scroll_layer_impl_(nullptr),
        outer_viewport_container_layer_impl_(nullptr),
        child_transform_layer_impl_(nullptr),
        child_impl_(nullptr),
        grand_child_impl_(nullptr),
        great_grand_child_impl_(nullptr) {
    layer_tree_host_->InitializeForTesting(
        TaskRunnerProvider::Create(nullptr, nullptr),
        std::unique_ptr<Proxy>(new FakeProxy), nullptr);
    CreateTreeForTest();
    fixed_to_top_left_.set_is_fixed_position(true);
    fixed_to_bottom_right_.set_is_fixed_position(true);
    fixed_to_bottom_right_.set_is_fixed_to_right_edge(true);
    fixed_to_bottom_right_.set_is_fixed_to_bottom_edge(true);
  }

  void CreateTreeForTest() {
    // scroll_layer_ is the inner viewport scroll layer and child_ is the outer
    // viewport scroll layer.
    root_ = Layer::Create();
    inner_viewport_container_layer_ = Layer::Create();
    scroll_layer_ = Layer::Create();
    outer_viewport_container_layer_ = Layer::Create();
    child_transform_layer_ = Layer::Create();
    child_ = Layer::Create();
    grand_child_ = make_scoped_refptr(new LayerWithForcedDrawsContent());
    great_grand_child_ = make_scoped_refptr(new LayerWithForcedDrawsContent());

    gfx::Transform IdentityMatrix;
    gfx::Point3F transform_origin;
    gfx::PointF position;
    gfx::Size bounds(200, 200);
    gfx::Size clip_bounds(100, 100);
    SetLayerPropertiesForTesting(inner_viewport_container_layer_.get(),
                                 IdentityMatrix, transform_origin, position,
                                 clip_bounds, true);
    SetLayerPropertiesForTesting(scroll_layer_.get(), IdentityMatrix,
                                 transform_origin, position, bounds, true);
    SetLayerPropertiesForTesting(outer_viewport_container_layer_.get(),
                                 IdentityMatrix, transform_origin, position,
                                 clip_bounds, true);
    SetLayerPropertiesForTesting(child_.get(), IdentityMatrix, transform_origin,
                                 position, bounds, true);
    SetLayerPropertiesForTesting(grand_child_.get(), IdentityMatrix,
                                 transform_origin, position, bounds, true);
    SetLayerPropertiesForTesting(great_grand_child_.get(), IdentityMatrix,
                                 transform_origin, position, bounds, true);

    root_->SetBounds(clip_bounds);

    inner_viewport_container_layer_->SetMasksToBounds(true);
    scroll_layer_->SetScrollClipLayerId(inner_viewport_container_layer_->id());
    scroll_layer_->SetIsContainerForFixedPositionLayers(true);

    outer_viewport_container_layer_->SetMasksToBounds(true);
    child_->SetScrollClipLayerId(outer_viewport_container_layer_->id());
    grand_child_->SetScrollClipLayerId(outer_viewport_container_layer_->id());

    grand_child_->AddChild(great_grand_child_);
    child_->AddChild(grand_child_);
    child_transform_layer_->AddChild(child_);
    outer_viewport_container_layer_->AddChild(child_transform_layer_);
    scroll_layer_->AddChild(outer_viewport_container_layer_);
    inner_viewport_container_layer_->AddChild(scroll_layer_);
    root_->AddChild(inner_viewport_container_layer_);

    layer_tree_host_->SetRootLayer(root_);
    layer_tree_host_->GetLayerTree()->RegisterViewportLayers(
        nullptr, root_, scroll_layer_, child_);
  }

  void CommitAndUpdateImplPointers() {
    LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
        root_.get(), root_->bounds());
    inputs.inner_viewport_scroll_layer =
        layer_tree_host_->GetLayerTree()->inner_viewport_scroll_layer();
    inputs.outer_viewport_scroll_layer =
        layer_tree_host_->GetLayerTree()->outer_viewport_scroll_layer();
    LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs);

    // Since scroll deltas aren't sent back to the main thread in this test
    // setup, clear them to maintain consistent state.
    if (root_impl_) {
      SetScrollOffsetDelta(scroll_layer_impl_, gfx::Vector2dF());
      SetScrollOffsetDelta(child_impl_, gfx::Vector2dF());
      SetScrollOffsetDelta(grand_child_impl_, gfx::Vector2dF());
    }
    root_impl_ = layer_tree_host_->CommitAndCreateLayerImplTree();
    layer_tree_impl_ = root_impl_->layer_tree_impl();
    inner_viewport_container_layer_impl_ =
        layer_tree_impl_->LayerById(inner_viewport_container_layer_->id());
    scroll_layer_impl_ = layer_tree_impl_->LayerById(scroll_layer_->id());
    outer_viewport_container_layer_impl_ =
        layer_tree_impl_->LayerById(outer_viewport_container_layer_->id());
    child_transform_layer_impl_ =
        layer_tree_impl_->LayerById(child_transform_layer_->id());
    child_impl_ = layer_tree_impl_->LayerById(child_->id());
    grand_child_impl_ = layer_tree_impl_->LayerById(grand_child_->id());
    great_grand_child_impl_ =
        layer_tree_impl_->LayerById(great_grand_child_->id());
  }

 protected:
  FakeLayerTreeHostClient fake_client_;
  TestTaskGraphRunner task_graph_runner_;
  std::unique_ptr<FakeLayerTreeHost> layer_tree_host_;
  scoped_refptr<Layer> root_;
  scoped_refptr<Layer> inner_viewport_container_layer_;
  scoped_refptr<Layer> scroll_layer_;
  scoped_refptr<Layer> outer_viewport_container_layer_;
  scoped_refptr<Layer> child_transform_layer_;
  scoped_refptr<Layer> child_;
  scoped_refptr<Layer> grand_child_;
  scoped_refptr<Layer> great_grand_child_;
  LayerTreeImpl* layer_tree_impl_;
  LayerImpl* root_impl_;
  LayerImpl* inner_viewport_container_layer_impl_;
  LayerImpl* scroll_layer_impl_;
  LayerImpl* outer_viewport_container_layer_impl_;
  LayerImpl* child_transform_layer_impl_;
  LayerImpl* child_impl_;
  LayerImpl* grand_child_impl_;
  LayerImpl* great_grand_child_impl_;

  LayerPositionConstraint fixed_to_top_left_;
  LayerPositionConstraint fixed_to_bottom_right_;

  // LayerImpl should not be aware of synced property logics, this function is
  // a hack for the test to arbitrarily set the scroll delta for setting up.
  static void SetScrollOffsetDelta(LayerImpl* layer_impl,
                                   const gfx::Vector2dF& delta) {
    if (layer_impl->layer_tree_impl()
            ->property_trees()
            ->scroll_tree.SetScrollOffsetDeltaForTesting(layer_impl->id(),
                                                         delta))
      layer_impl->layer_tree_impl()->DidUpdateScrollOffset(
          layer_impl->id(), layer_impl->transform_tree_index());
  }
};

namespace {

void SetFixedContainerSizeDelta(LayerImpl* scroll_layer,
                                const gfx::Vector2d& delta) {
  DCHECK(scroll_layer);
  DCHECK(scroll_layer->scrollable());

  LayerImpl* container_layer = scroll_layer->scroll_clip_layer();
  container_layer->SetBoundsDelta(delta);
}
}  // namespace

TEST_F(LayerPositionConstraintTest,
     ScrollCompensationForFixedPositionLayerWithDirectContainer) {
  // This test checks for correct scroll compensation when the fixed-position
  // container is the direct parent of the fixed-position layer.
  child_->SetIsContainerForFixedPositionLayers(true);
  grand_child_->SetPositionConstraint(fixed_to_top_left_);

  CommitAndUpdateImplPointers();

  // Case 1: scroll delta of 0, 0
  SetScrollOffsetDelta(child_impl_, gfx::Vector2d(0, 0));
  ExecuteCalculateDrawProperties(root_impl_);

  gfx::Transform expected_child_transform;
  gfx::Transform expected_grand_child_transform = expected_child_transform;

  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
                                  child_impl_->DrawTransform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
                                  grand_child_impl_->DrawTransform());

  // Case 2: scroll delta of 10, 10
  SetScrollOffsetDelta(child_impl_, gfx::Vector2d(10, 10));
  child_impl_->SetDrawsContent(true);
  ExecuteCalculateDrawProperties(root_impl_);

  // Here the child is affected by scroll delta, but the fixed position
  // grand_child should not be affected.
  expected_child_transform.MakeIdentity();
  expected_child_transform.Translate(-10.0, -10.0);

  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
                                  child_impl_->DrawTransform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
                                  grand_child_impl_->DrawTransform());

  // Case 3: fixed-container size delta of 20, 20
  SetFixedContainerSizeDelta(child_impl_, gfx::Vector2d(20, 20));
  ExecuteCalculateDrawProperties(root_impl_);

  // Top-left fixed-position layer should not be affected by container size.
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
                                  child_impl_->DrawTransform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
                                  grand_child_impl_->DrawTransform());

  // Case 4: Bottom-right fixed-position layer.
  grand_child_->SetPositionConstraint(fixed_to_bottom_right_);
  CommitAndUpdateImplPointers();

  SetScrollOffsetDelta(child_impl_, gfx::Vector2d(10, 10));
  SetFixedContainerSizeDelta(child_impl_, gfx::Vector2d(20, 20));
  ExecuteCalculateDrawProperties(root_impl_);

  // Bottom-right fixed-position layer moves as container resizes.
  expected_grand_child_transform.MakeIdentity();
  // Apply size delta from the child(container) layer.
  expected_grand_child_transform.Translate(20.0, 20.0);

  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
                                  child_impl_->DrawTransform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
                                  grand_child_impl_->DrawTransform());
}

TEST_F(LayerPositionConstraintTest,
     ScrollCompensationForFixedPositionLayerWithDistantContainer) {
  // This test checks for correct scroll compensation when the fixed-position
  // container is NOT the direct parent of the fixed-position layer.
  child_->SetIsContainerForFixedPositionLayers(true);
  grand_child_->SetPosition(gfx::PointF(8.f, 6.f));
  great_grand_child_->SetPositionConstraint(fixed_to_top_left_);

  CommitAndUpdateImplPointers();

  // Case 1: scroll delta of 0, 0
  SetScrollOffsetDelta(child_impl_, gfx::Vector2d(0, 0));
  child_impl_->SetDrawsContent(true);
  ExecuteCalculateDrawProperties(root_impl_);

  gfx::Transform expected_child_transform;
  gfx::Transform expected_grand_child_transform;
  expected_grand_child_transform.Translate(8.0, 6.0);

  gfx::Transform expected_great_grand_child_transform =
      expected_grand_child_transform;

  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
                                  child_impl_->DrawTransform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
                                  grand_child_impl_->DrawTransform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
                                  great_grand_child_impl_->DrawTransform());

  // Case 2: scroll delta of 10, 10
  SetScrollOffsetDelta(child_impl_, gfx::Vector2d(10, 10));
  ExecuteCalculateDrawProperties(root_impl_);

  // Here the child and grand_child are affected by scroll delta, but the fixed
  // position great_grand_child should not be affected.
  expected_child_transform.MakeIdentity();
  expected_child_transform.Translate(-10.0, -10.0);
  expected_grand_child_transform.MakeIdentity();
  expected_grand_child_transform.Translate(-2.0, -4.0);
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
                                  child_impl_->DrawTransform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
                                  grand_child_impl_->DrawTransform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
                                  great_grand_child_impl_->DrawTransform());

  // Case 3: fixed-container size delta of 20, 20
  SetFixedContainerSizeDelta(child_impl_, gfx::Vector2d(20, 20));
  ExecuteCalculateDrawProperties(root_impl_);

  // Top-left fixed-position layer should not be affected by container size.
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
                                  child_impl_->DrawTransform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
                                  grand_child_impl_->DrawTransform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
                                  great_grand_child_impl_->DrawTransform());

  // Case 4: Bottom-right fixed-position layer.
  great_grand_child_->SetPositionConstraint(fixed_to_bottom_right_);
  CommitAndUpdateImplPointers();
  SetScrollOffsetDelta(child_impl_, gfx::Vector2d(10, 10));
  SetFixedContainerSizeDelta(child_impl_, gfx::Vector2d(20, 20));
  ExecuteCalculateDrawProperties(root_impl_);

  // Bottom-right fixed-position layer moves as container resizes.
  expected_great_grand_child_transform.MakeIdentity();
  // Apply size delta from the child(container) layer.
  expected_great_grand_child_transform.Translate(20.0, 20.0);
  // Apply layer position from the grand child layer.
  expected_great_grand_child_transform.Translate(8.0, 6.0);

  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
                                  child_impl_->DrawTransform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
                                  grand_child_impl_->DrawTransform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
                                  great_grand_child_impl_->DrawTransform());
}

TEST_F(LayerPositionConstraintTest,
     ScrollCompensationForFixedPositionLayerWithMultipleScrollDeltas) {
  // This test checks for correct scroll compensation when the fixed-position
  // container has multiple ancestors that have nonzero scroll delta before
  // reaching the space where the layer is fixed.
  gfx::Transform rotation_about_z;
  rotation_about_z.RotateAboutZAxis(90.0);

  child_transform_layer_->SetIsContainerForFixedPositionLayers(true);
  child_transform_layer_->SetTransform(rotation_about_z);
  grand_child_->SetPosition(gfx::PointF(8.f, 6.f));
  great_grand_child_->SetPositionConstraint(fixed_to_top_left_);

  CommitAndUpdateImplPointers();

  // Case 1: scroll delta of 0, 0
  SetScrollOffsetDelta(child_impl_, gfx::Vector2d(0, 0));
  child_impl_->SetDrawsContent(true);
  ExecuteCalculateDrawProperties(root_impl_);

  gfx::Transform expected_child_transform;
  expected_child_transform.PreconcatTransform(rotation_about_z);

  gfx::Transform expected_grand_child_transform;
  expected_grand_child_transform.PreconcatTransform(
      rotation_about_z);  // child's local transform is inherited
  // translation because of position occurs before layer's local transform.
  expected_grand_child_transform.Translate(8.0, 6.0);

  gfx::Transform expected_great_grand_child_transform =
      expected_grand_child_transform;

  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
                                  child_impl_->DrawTransform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
                                  grand_child_impl_->DrawTransform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
                                  great_grand_child_impl_->DrawTransform());

  // Case 2: scroll delta of 10, 20
  SetScrollOffsetDelta(child_impl_, gfx::Vector2d(10, 0));
  SetScrollOffsetDelta(grand_child_impl_, gfx::Vector2d(5, 0));
  ExecuteCalculateDrawProperties(root_impl_);

  // Here the child and grand_child are affected by scroll delta, but the fixed
  // position great_grand_child should not be affected.
  expected_child_transform.MakeIdentity();
  expected_child_transform.PreconcatTransform(rotation_about_z);
  expected_child_transform.Translate(-10.0, 0.0);  // scroll delta

  expected_grand_child_transform.MakeIdentity();
  expected_grand_child_transform.PreconcatTransform(
      rotation_about_z);  // child's local transform is inherited
  expected_grand_child_transform.Translate(
      -10.0, 0.0);  // child's scroll delta is inherited
  expected_grand_child_transform.Translate(-5.0,
                                           0.0);  // grand_child's scroll delta
  // translation because of position
  expected_grand_child_transform.Translate(8.0, 6.0);

  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
                                  child_impl_->DrawTransform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
                                  grand_child_impl_->DrawTransform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
                                  great_grand_child_impl_->DrawTransform());
}

TEST_F(LayerPositionConstraintTest,
     ScrollCompensationForFixedPositionWithIntermediateSurfaceAndTransforms) {
  // This test checks for correct scroll compensation when the fixed-position
  // container contributes to a different render surface than the fixed-position
  // layer. In this case, the surface draw transforms also have to be accounted
  // for when checking the scroll delta.
  child_->SetIsContainerForFixedPositionLayers(true);
  grand_child_->SetPosition(gfx::PointF(8.f, 6.f));
  grand_child_->SetForceRenderSurfaceForTesting(true);
  great_grand_child_->SetPositionConstraint(fixed_to_top_left_);

  gfx::Transform rotation_about_z;
  rotation_about_z.RotateAboutZAxis(90.0);
  great_grand_child_->SetTransform(rotation_about_z);

  CommitAndUpdateImplPointers();

  // Case 1: scroll delta of 0, 0
  SetScrollOffsetDelta(child_impl_, gfx::Vector2d(0, 0));
  ExecuteCalculateDrawProperties(root_impl_);

  gfx::Transform expected_child_transform;
  gfx::Transform expected_surface_draw_transform;
  expected_surface_draw_transform.Translate(8.0, 6.0);
  gfx::Transform expected_grand_child_transform;
  gfx::Transform expected_great_grand_child_transform;
  expected_great_grand_child_transform.PreconcatTransform(rotation_about_z);
  EXPECT_TRUE(grand_child_impl_->render_surface());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
                                  child_impl_->DrawTransform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(
      expected_surface_draw_transform,
      grand_child_impl_->render_surface()->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
                                  grand_child_impl_->DrawTransform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
                                  great_grand_child_impl_->DrawTransform());

  // Case 2: scroll delta of 10, 30
  SetScrollOffsetDelta(child_impl_, gfx::Vector2d(10, 30));
  child_impl_->SetDrawsContent(true);
  ExecuteCalculateDrawProperties(root_impl_);

  // Here the grand_child remains unchanged, because it scrolls along with the
  // render surface, and the translation is actually in the render surface. But,
  // the fixed position great_grand_child is more awkward: its actually being
  // drawn with respect to the render surface, but it needs to remain fixed with
  // resepct to a container beyond that surface. So, the net result is that,
  // unlike previous tests where the fixed position layer's transform remains
  // unchanged, here the fixed position layer's transform explicitly contains
  // the translation that cancels out the scroll.
  expected_child_transform.MakeIdentity();
  expected_child_transform.Translate(-10.0, -30.0);  // scroll delta

  expected_surface_draw_transform.MakeIdentity();
  expected_surface_draw_transform.Translate(-10.0, -30.0);  // scroll delta
  expected_surface_draw_transform.Translate(8.0, 6.0);

  expected_great_grand_child_transform.MakeIdentity();
  // explicit canceling out the scroll delta that gets embedded in the fixed
  // position layer's surface.
  expected_great_grand_child_transform.Translate(10.0, 30.0);
  expected_great_grand_child_transform.PreconcatTransform(rotation_about_z);

  EXPECT_TRUE(grand_child_impl_->render_surface());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
                                  child_impl_->DrawTransform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(
      expected_surface_draw_transform,
      grand_child_impl_->render_surface()->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
                                  grand_child_impl_->DrawTransform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
                                  great_grand_child_impl_->DrawTransform());

  // Case 3: fixed-container size delta of 20, 20
  SetFixedContainerSizeDelta(child_impl_, gfx::Vector2d(20, 20));
  ExecuteCalculateDrawProperties(root_impl_);

  // Top-left fixed-position layer should not be affected by container size.
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
                                  child_impl_->DrawTransform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
                                  grand_child_impl_->DrawTransform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
                                  great_grand_child_impl_->DrawTransform());

  // Case 4: Bottom-right fixed-position layer.
  great_grand_child_->SetPositionConstraint(fixed_to_bottom_right_);

  CommitAndUpdateImplPointers();
  SetScrollOffsetDelta(child_impl_, gfx::Vector2d(10, 30));
  SetFixedContainerSizeDelta(child_impl_, gfx::Vector2d(20, 20));

  ExecuteCalculateDrawProperties(root_impl_);

  // Bottom-right fixed-position layer moves as container resizes.
  expected_great_grand_child_transform.MakeIdentity();
  // explicit canceling out the scroll delta that gets embedded in the fixed
  // position layer's surface.
  expected_great_grand_child_transform.Translate(10.0, 30.0);
  // Also apply size delta in the child(container) layer space.
  expected_great_grand_child_transform.Translate(20.0, 20.0);
  expected_great_grand_child_transform.PreconcatTransform(rotation_about_z);

  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
                                  child_impl_->DrawTransform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
                                  grand_child_impl_->DrawTransform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
                                  great_grand_child_impl_->DrawTransform());
}

TEST_F(LayerPositionConstraintTest,
     ScrollCompensationForFixedPositionLayerWithMultipleIntermediateSurfaces) {
  // This test checks for correct scroll compensation when the fixed-position
  // container contributes to a different render surface than the fixed-position
  // layer, with additional render surfaces in-between. This checks that the
  // conversion to ancestor surfaces is accumulated properly in the final matrix
  // transform.

  // Add one more layer to the test tree for this scenario.
  scoped_refptr<Layer> fixed_position_child =
      make_scoped_refptr(new LayerWithForcedDrawsContent());
  SetLayerPropertiesForTesting(fixed_position_child.get(), gfx::Transform(),
                               gfx::Point3F(), gfx::PointF(),
                               gfx::Size(100, 100), true);
  great_grand_child_->AddChild(fixed_position_child);

  // Actually set up the scenario here.
  child_->SetIsContainerForFixedPositionLayers(true);
  grand_child_->SetPosition(gfx::PointF(8.f, 6.f));
  grand_child_->SetForceRenderSurfaceForTesting(true);
  great_grand_child_->SetPosition(gfx::PointF(40.f, 60.f));
  great_grand_child_->SetForceRenderSurfaceForTesting(true);
  fixed_position_child->SetPositionConstraint(fixed_to_top_left_);

  // The additional rotation, which is non-commutative with translations, helps
  // to verify that we have correct order-of-operations in the final scroll
  // compensation.  Note that rotating about the center of the layer ensures we
  // do not accidentally clip away layers that we want to test.
  gfx::Transform rotation_about_z;
  rotation_about_z.Translate(50.0, 50.0);
  rotation_about_z.RotateAboutZAxis(90.0);
  rotation_about_z.Translate(-50.0, -50.0);
  fixed_position_child->SetTransform(rotation_about_z);

  CommitAndUpdateImplPointers();
  LayerImpl* fixed_position_child_impl =
      layer_tree_impl_->LayerById(fixed_position_child->id());

  // Case 1: scroll delta of 0, 0
  SetScrollOffsetDelta(child_impl_, gfx::Vector2d(0, 0));
  child_impl_->SetDrawsContent(true);
  ExecuteCalculateDrawProperties(root_impl_);

  gfx::Transform expected_child_transform;

  gfx::Transform expected_grand_child_surface_draw_transform;
  expected_grand_child_surface_draw_transform.Translate(8.0, 6.0);

  gfx::Transform expected_grand_child_transform;

  gfx::Transform expected_great_grand_child_surface_draw_transform;
  expected_great_grand_child_surface_draw_transform.Translate(40.0, 60.0);

  gfx::Transform expected_great_grand_child_transform;

  gfx::Transform expected_fixed_position_child_transform;
  expected_fixed_position_child_transform.PreconcatTransform(rotation_about_z);

  EXPECT_TRUE(grand_child_impl_->render_surface());
  EXPECT_TRUE(great_grand_child_impl_->render_surface());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
                                  child_impl_->DrawTransform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(
      expected_grand_child_surface_draw_transform,
      grand_child_impl_->render_surface()->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
                                  grand_child_impl_->DrawTransform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(
      expected_great_grand_child_surface_draw_transform,
      great_grand_child_impl_->render_surface()->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
                                  great_grand_child_impl_->DrawTransform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_position_child_transform,
                                  fixed_position_child_impl->DrawTransform());

  // Case 2: scroll delta of 10, 30
  SetScrollOffsetDelta(child_impl_, gfx::Vector2d(10, 30));
  ExecuteCalculateDrawProperties(root_impl_);

  expected_child_transform.MakeIdentity();
  expected_child_transform.Translate(-10.0, -30.0);  // scroll delta

  expected_grand_child_surface_draw_transform.MakeIdentity();
  expected_grand_child_surface_draw_transform.Translate(-10.0,
                                                        -30.0);  // scroll delta
  expected_grand_child_surface_draw_transform.Translate(8.0, 6.0);

  // grand_child, great_grand_child, and great_grand_child's surface are not
  // expected to change, since they are all not fixed, and they are all drawn
  // with respect to grand_child's surface that already has the scroll delta
  // accounted for.

  // But the great-great grandchild, "fixed_position_child", should have a
  // transform that explicitly cancels out the scroll delta.
  expected_fixed_position_child_transform.MakeIdentity();
  expected_fixed_position_child_transform.Translate(10.0, 30.0);
  expected_fixed_position_child_transform.PreconcatTransform(rotation_about_z);

  EXPECT_TRUE(grand_child_impl_->render_surface());
  EXPECT_TRUE(great_grand_child_impl_->render_surface());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
                                  child_impl_->DrawTransform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(
      expected_grand_child_surface_draw_transform,
      grand_child_impl_->render_surface()->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
                                  grand_child_impl_->DrawTransform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(
      expected_great_grand_child_surface_draw_transform,
      great_grand_child_impl_->render_surface()->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
                                  great_grand_child_impl_->DrawTransform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_position_child_transform,
                                  fixed_position_child_impl->DrawTransform());

  // Case 3: fixed-container size delta of 20, 20
  SetFixedContainerSizeDelta(child_impl_, gfx::Vector2d(20, 20));
  ExecuteCalculateDrawProperties(root_impl_);

  // Top-left fixed-position layer should not be affected by container size.
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
                                  child_impl_->DrawTransform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
                                  grand_child_impl_->DrawTransform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
                                  great_grand_child_impl_->DrawTransform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_position_child_transform,
                                  fixed_position_child_impl->DrawTransform());

  // Case 4: Bottom-right fixed-position layer.
  fixed_position_child->SetPositionConstraint(fixed_to_bottom_right_);
  CommitAndUpdateImplPointers();
  fixed_position_child_impl =
      layer_tree_impl_->LayerById(fixed_position_child->id());
  SetScrollOffsetDelta(child_impl_, gfx::Vector2d(10, 30));
  SetFixedContainerSizeDelta(child_impl_, gfx::Vector2d(20, 20));
  ExecuteCalculateDrawProperties(root_impl_);

  // Bottom-right fixed-position layer moves as container resizes.
  expected_fixed_position_child_transform.MakeIdentity();
  // explicit canceling out the scroll delta that gets embedded in the fixed
  // position layer's surface.
  expected_fixed_position_child_transform.Translate(10.0, 30.0);
  // Also apply size delta in the child(container) layer space.
  expected_fixed_position_child_transform.Translate(20.0, 20.0);
  expected_fixed_position_child_transform.PreconcatTransform(rotation_about_z);

  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
                                  child_impl_->DrawTransform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
                                  grand_child_impl_->DrawTransform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
                                  great_grand_child_impl_->DrawTransform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_position_child_transform,
                                  fixed_position_child_impl->DrawTransform());
}

TEST_F(
    LayerPositionConstraintTest,
    ScrollCompensationForFixedPositionLayerWithMultipleSurfacesAndTransforms) {
  // This test checks for correct scroll compensation when the fixed-position
  // container contributes to a different render surface than the fixed-position
  // layer, with additional render surfaces in-between, and the fixed-position
  // container is transformed. This checks that the conversion to ancestor
  // surfaces is accumulated properly in the final matrix transform.

  // Add one more layer to the test tree for this scenario.
  scoped_refptr<Layer> fixed_position_child =
      make_scoped_refptr(new LayerWithForcedDrawsContent());
  SetLayerPropertiesForTesting(fixed_position_child.get(), gfx::Transform(),
                               gfx::Point3F(), gfx::PointF(),
                               gfx::Size(100, 100), true);
  great_grand_child_->AddChild(fixed_position_child);

  // Actually set up the scenario here.
  child_transform_layer_->SetIsContainerForFixedPositionLayers(true);
  grand_child_->SetPosition(gfx::PointF(8.f, 6.f));
  grand_child_->SetForceRenderSurfaceForTesting(true);
  great_grand_child_->SetPosition(gfx::PointF(40.f, 60.f));
  great_grand_child_->SetForceRenderSurfaceForTesting(true);
  fixed_position_child->SetPositionConstraint(fixed_to_top_left_);

  // The additional rotations, which are non-commutative with translations, help
  // to verify that we have correct order-of-operations in the final scroll
  // compensation.  Note that rotating about the center of the layer ensures we
  // do not accidentally clip away layers that we want to test.
  gfx::Transform rotation_about_z;
  rotation_about_z.Translate(50.0, 50.0);
  rotation_about_z.RotateAboutZAxis(30.0);
  rotation_about_z.Translate(-50.0, -50.0);
  child_transform_layer_->SetTransform(rotation_about_z);
  fixed_position_child->SetTransform(rotation_about_z);

  CommitAndUpdateImplPointers();
  LayerImpl* fixed_position_child_impl =
      layer_tree_impl_->LayerById(fixed_position_child->id());

  // Case 1: scroll delta of 0, 0
  SetScrollOffsetDelta(child_impl_, gfx::Vector2d(0, 0));
  child_impl_->SetDrawsContent(true);
  ExecuteCalculateDrawProperties(root_impl_);

  gfx::Transform expected_child_transform;
  expected_child_transform.PreconcatTransform(rotation_about_z);

  gfx::Transform expected_grand_child_surface_draw_transform;
  expected_grand_child_surface_draw_transform.PreconcatTransform(
      rotation_about_z);
  expected_grand_child_surface_draw_transform.Translate(8.0, 6.0);

  gfx::Transform expected_grand_child_transform;

  gfx::Transform expected_great_grand_child_surface_draw_transform;
  expected_great_grand_child_surface_draw_transform.Translate(40.0, 60.0);

  gfx::Transform expected_great_grand_child_transform;

  gfx::Transform expected_fixed_position_child_transform;
  expected_fixed_position_child_transform.PreconcatTransform(rotation_about_z);

  EXPECT_TRUE(grand_child_impl_->render_surface());
  EXPECT_TRUE(great_grand_child_impl_->render_surface());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
                                  child_impl_->DrawTransform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(
      expected_grand_child_surface_draw_transform,
      grand_child_impl_->render_surface()->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
                                  grand_child_impl_->DrawTransform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(
      expected_great_grand_child_surface_draw_transform,
      great_grand_child_impl_->render_surface()->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
                                  great_grand_child_impl_->DrawTransform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_position_child_transform,
                                  fixed_position_child_impl->DrawTransform());

  // Case 2: scroll delta of 10, 30
  SetScrollOffsetDelta(child_impl_, gfx::Vector2d(10, 30));
  ExecuteCalculateDrawProperties(root_impl_);

  expected_child_transform.MakeIdentity();
  expected_child_transform.PreconcatTransform(rotation_about_z);
  expected_child_transform.Translate(-10.0, -30.0);  // scroll delta

  expected_grand_child_surface_draw_transform.MakeIdentity();
  expected_grand_child_surface_draw_transform.PreconcatTransform(
      rotation_about_z);
  expected_grand_child_surface_draw_transform.Translate(-10.0,
                                                        -30.0);  // scroll delta
  expected_grand_child_surface_draw_transform.Translate(8.0, 6.0);

  // grand_child, great_grand_child, and great_grand_child's surface are not
  // expected to change, since they are all not fixed, and they are all drawn
  // with respect to grand_child's surface that already has the scroll delta
  // accounted for.

  // But the great-great grandchild, "fixed_position_child", should have a
  // transform that explicitly cancels out the scroll delta.
  expected_fixed_position_child_transform.MakeIdentity();
  // explicit canceling out the scroll delta that gets embedded in the fixed
  // position layer's surface.
  expected_fixed_position_child_transform.Translate(10.0, 30.0);
  expected_fixed_position_child_transform.PreconcatTransform(rotation_about_z);

  EXPECT_TRUE(grand_child_impl_->render_surface());
  EXPECT_TRUE(great_grand_child_impl_->render_surface());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
                                  child_impl_->DrawTransform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(
      expected_grand_child_surface_draw_transform,
      grand_child_impl_->render_surface()->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
                                  grand_child_impl_->DrawTransform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(
      expected_great_grand_child_surface_draw_transform,
      great_grand_child_impl_->render_surface()->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
                                  great_grand_child_impl_->DrawTransform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_position_child_transform,
                                  fixed_position_child_impl->DrawTransform());
}

TEST_F(LayerPositionConstraintTest,
     ScrollCompensationForFixedPositionLayerWithContainerLayerThatHasSurface) {
  // This test checks for correct scroll compensation when the fixed-position
  // container itself has a render surface. In this case, the container layer
  // should be treated like a layer that contributes to a render target, and
  // that render target is completely irrelevant; it should not affect the
  // scroll compensation.
  child_->SetIsContainerForFixedPositionLayers(true);
  child_->SetForceRenderSurfaceForTesting(true);
  grand_child_->SetPositionConstraint(fixed_to_top_left_);

  CommitAndUpdateImplPointers();

  // Case 1: scroll delta of 0, 0
  SetScrollOffsetDelta(child_impl_, gfx::Vector2d(0, 0));
  ExecuteCalculateDrawProperties(root_impl_);

  gfx::Transform expected_surface_draw_transform;
  gfx::Transform expected_child_transform;
  gfx::Transform expected_grand_child_transform;
  EXPECT_TRUE(child_impl_->render_surface());
  EXPECT_TRANSFORMATION_MATRIX_EQ(
      expected_surface_draw_transform,
      child_impl_->render_surface()->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
                                  child_impl_->DrawTransform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
                                  grand_child_impl_->DrawTransform());

  // Case 2: scroll delta of 10, 10
  SetScrollOffsetDelta(child_impl_, gfx::Vector2d(10, 10));
  ExecuteCalculateDrawProperties(root_impl_);

  // The surface is translated by scroll delta, the child transform doesn't
  // change because it scrolls along with the surface, but the fixed position
  // grand_child needs to compensate for the scroll translation.
  expected_surface_draw_transform.MakeIdentity();
  expected_surface_draw_transform.Translate(-10.0, -10.0);
  expected_grand_child_transform.MakeIdentity();
  expected_grand_child_transform.Translate(10.0, 10.0);

  EXPECT_TRUE(child_impl_->render_surface());
  EXPECT_TRANSFORMATION_MATRIX_EQ(
      expected_surface_draw_transform,
      child_impl_->render_surface()->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
                                  child_impl_->DrawTransform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
                                  grand_child_impl_->DrawTransform());

  // Case 3: fixed-container size delta of 20, 20
  SetFixedContainerSizeDelta(child_impl_, gfx::Vector2d(20, 20));
  ExecuteCalculateDrawProperties(root_impl_);

  // Top-left fixed-position layer should not be affected by container size.
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
                                  child_impl_->DrawTransform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
                                  grand_child_impl_->DrawTransform());

  // Case 4: Bottom-right fixed-position layer.
  grand_child_->SetPositionConstraint(fixed_to_bottom_right_);
  CommitAndUpdateImplPointers();
  SetScrollOffsetDelta(child_impl_, gfx::Vector2d(10, 10));
  SetFixedContainerSizeDelta(child_impl_, gfx::Vector2d(20, 20));
  ExecuteCalculateDrawProperties(root_impl_);

  // Bottom-right fixed-position layer moves as container resizes.
  expected_grand_child_transform.MakeIdentity();
  // The surface is translated by scroll delta, the child transform doesn't
  // change because it scrolls along with the surface, but the fixed position
  // grand_child needs to compensate for the scroll translation.
  expected_grand_child_transform.Translate(10.0, 10.0);
  // Apply size delta from the child(container) layer.
  expected_grand_child_transform.Translate(20.0, 20.0);

  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
                                  child_impl_->DrawTransform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
                                  grand_child_impl_->DrawTransform());
}

TEST_F(LayerPositionConstraintTest,
     ScrollCompensationForFixedPositionLayerThatIsAlsoFixedPositionContainer) {
  // This test checks the scenario where a fixed-position layer also happens to
  // be a container itself for a descendant fixed position layer. In particular,
  // the layer should not accidentally be fixed to itself.
  child_->SetIsContainerForFixedPositionLayers(true);
  grand_child_->SetPositionConstraint(fixed_to_top_left_);

  // This should not confuse the grand_child. If correct, the grand_child would
  // still be considered fixed to its container (i.e. "child").
  grand_child_->SetIsContainerForFixedPositionLayers(true);

  CommitAndUpdateImplPointers();

  // Case 1: scroll delta of 0, 0
  SetScrollOffsetDelta(child_impl_, gfx::Vector2d(0, 0));
  child_impl_->SetDrawsContent(true);
  ExecuteCalculateDrawProperties(root_impl_);

  gfx::Transform expected_child_transform;
  gfx::Transform expected_grand_child_transform;
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
                                  child_impl_->DrawTransform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
                                  grand_child_impl_->DrawTransform());

  // Case 2: scroll delta of 10, 10
  SetScrollOffsetDelta(child_impl_, gfx::Vector2d(10, 10));
  ExecuteCalculateDrawProperties(root_impl_);

  // Here the child is affected by scroll delta, but the fixed position
  // grand_child should not be affected.
  expected_child_transform.MakeIdentity();
  expected_child_transform.Translate(-10.0, -10.0);
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
                                  child_impl_->DrawTransform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
                                  grand_child_impl_->DrawTransform());

  // Case 3: fixed-container size delta of 20, 20
  SetFixedContainerSizeDelta(child_impl_, gfx::Vector2d(20, 20));
  ExecuteCalculateDrawProperties(root_impl_);

  // Top-left fixed-position layer should not be affected by container size.
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
                                  child_impl_->DrawTransform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
                                  grand_child_impl_->DrawTransform());

  // Case 4: Bottom-right fixed-position layer.
  grand_child_->SetPositionConstraint(fixed_to_bottom_right_);
  CommitAndUpdateImplPointers();
  SetScrollOffsetDelta(child_impl_, gfx::Vector2d(10, 10));
  SetFixedContainerSizeDelta(child_impl_, gfx::Vector2d(20, 20));

  ExecuteCalculateDrawProperties(root_impl_);

  // Bottom-right fixed-position layer moves as container resizes.
  expected_grand_child_transform.MakeIdentity();
  // Apply size delta from the child(container) layer.
  expected_grand_child_transform.Translate(20.0, 20.0);

  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
                                  child_impl_->DrawTransform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
                                  grand_child_impl_->DrawTransform());
}

TEST_F(LayerPositionConstraintTest,
     ScrollCompensationForFixedWithinFixedWithSameContainer) {
  // This test checks scroll compensation for a fixed-position layer that is
  // inside of another fixed-position layer and both share the same container.
  // In this situation, the parent fixed-position layer will receive
  // the scroll compensation, and the child fixed-position layer does not
  // need to compensate further.
  child_->SetIsContainerForFixedPositionLayers(true);
  grand_child_->SetPositionConstraint(fixed_to_top_left_);

  // Note carefully - great_grand_child is fixed to bottom right, to test
  // sizeDelta being applied correctly; the compensation skips the grand_child
  // because it is fixed to top left.
  great_grand_child_->SetPositionConstraint(fixed_to_bottom_right_);

  CommitAndUpdateImplPointers();

  // Case 1: scrollDelta
  SetScrollOffsetDelta(child_impl_, gfx::Vector2d(10, 10));
  child_impl_->SetDrawsContent(true);
  ExecuteCalculateDrawProperties(root_impl_);

  // Here the child is affected by scroll delta, but the fixed position
  // grand_child should not be affected.
  gfx::Transform expected_child_transform;
  expected_child_transform.Translate(-10.0, -10.0);

  gfx::Transform expected_grand_child_transform;
  gfx::Transform expected_great_grand_child_transform;

  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
                                  child_impl_->DrawTransform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
                                  grand_child_impl_->DrawTransform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
                                  great_grand_child_impl_->DrawTransform());

  // Case 2: sizeDelta
  SetScrollOffsetDelta(child_impl_, gfx::Vector2d(0, 0));
  SetFixedContainerSizeDelta(child_impl_, gfx::Vector2d(20, 20));
  ExecuteCalculateDrawProperties(root_impl_);

  expected_child_transform.MakeIdentity();

  expected_grand_child_transform.MakeIdentity();

  // Fixed to bottom-right, size-delta compensation is applied.
  expected_great_grand_child_transform.MakeIdentity();
  expected_great_grand_child_transform.Translate(20.0, 20.0);

  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
                                  child_impl_->DrawTransform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
                                  grand_child_impl_->DrawTransform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
                                  great_grand_child_impl_->DrawTransform());
}

TEST_F(LayerPositionConstraintTest,
     ScrollCompensationForFixedWithinFixedWithInterveningContainer) {
  // This test checks scroll compensation for a fixed-position layer that is
  // inside of another fixed-position layer, but they have different fixed
  // position containers. In this situation, the child fixed-position element
  // would still have to compensate with respect to its container.

  // Add one more layer to the hierarchy for this test.
  scoped_refptr<Layer> great_great_grand_child =
      make_scoped_refptr(new LayerWithForcedDrawsContent());
  great_grand_child_->AddChild(great_great_grand_child);

  child_->SetIsContainerForFixedPositionLayers(true);
  grand_child_->SetPositionConstraint(fixed_to_top_left_);
  great_grand_child_->SetIsContainerForFixedPositionLayers(true);
  great_grand_child_->SetScrollClipLayerId(root_->id());
  great_great_grand_child->SetPositionConstraint(fixed_to_top_left_);

  CommitAndUpdateImplPointers();

  LayerImpl* container1 = child_impl_;
  LayerImpl* fixed_to_container1 = grand_child_impl_;
  LayerImpl* container2 = great_grand_child_impl_;
  LayerImpl* fixed_to_container2 =
      layer_tree_impl_->LayerById(great_great_grand_child->id());

  SetScrollOffsetDelta(container1, gfx::Vector2d(0, 15));
  container1->SetDrawsContent(true);
  SetScrollOffsetDelta(container2, gfx::Vector2d(30, 0));
  container2->SetDrawsContent(true);
  ExecuteCalculateDrawProperties(root_impl_);

  gfx::Transform expected_container1_transform;
  expected_container1_transform.Translate(0.0, -15.0);

  gfx::Transform expected_fixed_to_container1_transform;

  // Since the container is a descendant of the fixed layer above,
  // the expected draw transform for container2 would not
  // include the scrollDelta that was applied to container1.
  gfx::Transform expected_container2_transform;
  expected_container2_transform.Translate(-30.0, 0.0);

  gfx::Transform expected_fixed_to_container2_transform;

  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_container1_transform,
                                  container1->DrawTransform());

  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_to_container1_transform,
                                  fixed_to_container1->DrawTransform());

  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_container2_transform,
                                  container2->DrawTransform());

  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_to_container2_transform,
                                  fixed_to_container2->DrawTransform());
}

TEST_F(LayerPositionConstraintTest,
       ScrollCompensationForInnerViewportBoundsDelta) {
  // This test checks for correct scroll compensation when the fixed-position
  // container is the inner viewport scroll layer and has non-zero bounds delta.
  scoped_refptr<Layer> fixed_child =
      make_scoped_refptr(new LayerWithForcedDrawsContent());
  fixed_child->SetBounds(gfx::Size(300, 300));
  scroll_layer_->AddChild(fixed_child);
  fixed_child->SetPositionConstraint(fixed_to_top_left_);

  CommitAndUpdateImplPointers();

  LayerImpl* fixed_child_impl =
      root_impl_->layer_tree_impl()->FindActiveTreeLayerById(fixed_child->id());

  // Case 1: fixed-container size delta of 20, 20
  SetScrollOffsetDelta(scroll_layer_impl_, gfx::Vector2d(10, 10));
  scroll_layer_impl_->SetDrawsContent(true);
  SetFixedContainerSizeDelta(scroll_layer_impl_, gfx::Vector2d(20, 20));
  gfx::Transform expected_scroll_layer_transform;
  expected_scroll_layer_transform.Translate(-10.0, -10.0);
  gfx::Transform expected_fixed_child_transform;

  ExecuteCalculateDrawProperties(root_impl_);

  // Top-left fixed-position layer should not be affected by container size.
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_scroll_layer_transform,
                                  scroll_layer_impl_->DrawTransform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_child_transform,
                                  fixed_child_impl->DrawTransform());

  // Case 2: Bottom-right fixed-position layer.
  fixed_child->SetPositionConstraint(fixed_to_bottom_right_);
  CommitAndUpdateImplPointers();
  fixed_child_impl =
      root_impl_->layer_tree_impl()->FindActiveTreeLayerById(fixed_child->id());

  SetScrollOffsetDelta(scroll_layer_impl_, gfx::Vector2d(10, 10));
  SetFixedContainerSizeDelta(scroll_layer_impl_, gfx::Vector2d(20, 20));
  ExecuteCalculateDrawProperties(root_impl_);

  // Bottom-right fixed-position layer moves as container resizes.
  expected_fixed_child_transform.MakeIdentity();
  // Apply size delta.
  expected_fixed_child_transform.Translate(20.0, 20.0);

  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_scroll_layer_transform,
                                  scroll_layer_impl_->DrawTransform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_child_transform,
                                  fixed_child_impl->DrawTransform());
}

void VerifySerializeAndDeserializeProto(bool is_fixed_position,
                                        bool is_fixed_to_right_edge,
                                        bool is_fixed_to_bottom_edge) {
  LayerPositionConstraint constraint;
  constraint.set_is_fixed_position(is_fixed_position);
  constraint.set_is_fixed_to_right_edge(is_fixed_to_right_edge);
  constraint.set_is_fixed_to_bottom_edge(is_fixed_to_bottom_edge);
  proto::LayerPositionConstraint proto;
  constraint.ToProtobuf(&proto);

  LayerPositionConstraint constraint2;
  constraint2.FromProtobuf(proto);
  EXPECT_EQ(constraint, constraint2);
}

TEST(LayerPositionConstraintSerializationTest, SerializeAndDeserializeProto) {
  VerifySerializeAndDeserializeProto(true, true, true);
  VerifySerializeAndDeserializeProto(true, true, false);
  VerifySerializeAndDeserializeProto(true, false, true);
  VerifySerializeAndDeserializeProto(true, false, false);
  VerifySerializeAndDeserializeProto(false, true, true);
  VerifySerializeAndDeserializeProto(false, true, false);
  VerifySerializeAndDeserializeProto(false, false, true);
  VerifySerializeAndDeserializeProto(false, false, false);
}

}  // namespace
}  // namespace cc
