// 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_impl.h"
#include "cc/test/fake_impl_proxy.h"
#include "cc/test/fake_layer_tree_host_impl.h"
#include "cc/test/geometry_test_utils.h"
#include "cc/test/test_shared_bitmap_manager.h"
#include "cc/trees/layer_tree_host_common.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace cc {
namespace {

void SetLayerPropertiesForTesting(LayerImpl* 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);
  layer->SetContentBounds(bounds);
}

void ExecuteCalculateDrawProperties(LayerImpl* root_layer,
                                    float device_scale_factor,
                                    float page_scale_factor,
                                    LayerImpl* page_scale_application_layer,
                                    bool can_use_lcd_text) {
  gfx::Transform identity_matrix;
  std::vector<LayerImpl*> dummy_render_surface_layer_list;
  LayerImpl* scroll_layer = root_layer->children()[0];
  gfx::Size device_viewport_size =
      gfx::Size(root_layer->bounds().width() * device_scale_factor,
                root_layer->bounds().height() * device_scale_factor);

  // We are probably not testing what is intended if the scroll_layer bounds are
  // empty.
  DCHECK(!scroll_layer->bounds().IsEmpty());
  LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
      root_layer, device_viewport_size, &dummy_render_surface_layer_list);
  inputs.device_scale_factor = device_scale_factor;
  inputs.page_scale_factor = page_scale_factor;
  inputs.page_scale_application_layer = page_scale_application_layer;
  inputs.can_use_lcd_text = can_use_lcd_text;
  LayerTreeHostCommon::CalculateDrawProperties(&inputs);
}

void ExecuteCalculateDrawProperties(LayerImpl* root_layer) {
  LayerImpl* page_scale_application_layer = nullptr;
  ExecuteCalculateDrawProperties(
      root_layer, 1.f, 1.f, page_scale_application_layer, false);
}

class LayerPositionConstraintTest : public testing::Test {
 public:
  LayerPositionConstraintTest() : host_impl_(&proxy_, &shared_bitmap_manager_) {
    root_ = CreateTreeForTest();
    scroll_ = root_->children()[0];
    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);
  }

  scoped_ptr<LayerImpl> CreateTreeForTest() {
    scoped_ptr<LayerImpl> root =
        LayerImpl::Create(host_impl_.active_tree(), 42);
    scoped_ptr<LayerImpl> scroll_layer =
        LayerImpl::Create(host_impl_.active_tree(), 1);
    scoped_ptr<LayerImpl> child =
        LayerImpl::Create(host_impl_.active_tree(), 2);
    scoped_ptr<LayerImpl> grand_child =
        LayerImpl::Create(host_impl_.active_tree(), 3);
    scoped_ptr<LayerImpl> great_grand_child =
        LayerImpl::Create(host_impl_.active_tree(), 4);

    root->SetHasRenderSurface(true);
    gfx::Transform IdentityMatrix;
    gfx::Point3F transform_origin;
    gfx::PointF position;
    gfx::Size bounds(200, 200);
    gfx::Size clip_bounds(100, 100);
    SetLayerPropertiesForTesting(scroll_layer.get(),
                                 IdentityMatrix,
                                 transform_origin,
                                 position,
                                 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);
    scroll_layer->SetScrollClipLayer(root->id());
    child->SetScrollClipLayer(root->id());
    grand_child->SetScrollClipLayer(root->id());

    grand_child->AddChild(great_grand_child.Pass());
    child->AddChild(grand_child.Pass());
    scroll_layer->AddChild(child.Pass());
    root->AddChild(scroll_layer.Pass());

    return root.Pass();
  }

 protected:
  FakeImplProxy proxy_;
  TestSharedBitmapManager shared_bitmap_manager_;
  FakeLayerTreeHostImpl host_impl_;
  scoped_ptr<LayerImpl> root_;
  LayerImpl* scroll_;

  LayerPositionConstraint fixed_to_top_left_;
  LayerPositionConstraint fixed_to_bottom_right_;
};

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.
  LayerImpl* child = scroll_->children()[0];
  LayerImpl* grand_child = child->children()[0];

  child->SetIsContainerForFixedPositionLayers(true);
  grand_child->SetPositionConstraint(fixed_to_top_left_);

  // Case 1: scroll delta of 0, 0
  child->SetScrollDelta(gfx::Vector2d(0, 0));
  ExecuteCalculateDrawProperties(root_.get());

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

  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
                                  child->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
                                  grand_child->draw_transform());

  // Case 2: scroll delta of 10, 10
  child->SetScrollDelta(gfx::Vector2d(10, 10));
  ExecuteCalculateDrawProperties(root_.get());

  // 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->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
                                  grand_child->draw_transform());

  // Case 3: fixed-container size delta of 20, 20
  SetFixedContainerSizeDelta(child, gfx::Vector2d(20, 20));
  ExecuteCalculateDrawProperties(root_.get());

  // Top-left fixed-position layer should not be affected by container size.
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
                                  child->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
                                  grand_child->draw_transform());

  // Case 4: Bottom-right fixed-position layer.
  grand_child->SetPositionConstraint(fixed_to_bottom_right_);
  ExecuteCalculateDrawProperties(root_.get());

  // 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->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
                                  grand_child->draw_transform());
}

TEST_F(LayerPositionConstraintTest,
     ScrollCompensationForFixedPositionLayerWithTransformedDirectContainer) {
  // This test checks for correct scroll compensation when the fixed-position
  // container is the direct parent of the fixed-position layer, but that
  // container is transformed.  In this case, the fixed position element
  // inherits the container's transform, but the scroll delta that has to be
  // undone should not be affected by that transform.
  //
  // Transforms are in general non-commutative; using something like a
  // non-uniform scale helps to verify that translations and non-uniform scales
  // are applied in the correct order.
  LayerImpl* child = scroll_->children()[0];
  LayerImpl* grand_child = child->children()[0];

  // This scale will cause child and grand_child to be effectively 200 x 800
  // with respect to the render target.
  gfx::Transform non_uniform_scale;
  non_uniform_scale.Scale(2.0, 8.0);
  child->SetTransform(non_uniform_scale);

  child->SetIsContainerForFixedPositionLayers(true);
  grand_child->SetPositionConstraint(fixed_to_top_left_);

  // Case 1: scroll delta of 0, 0
  child->SetScrollDelta(gfx::Vector2d(0, 0));
  ExecuteCalculateDrawProperties(root_.get());

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

  gfx::Transform expected_grand_child_transform = expected_child_transform;

  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
                                  child->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
                                  grand_child->draw_transform());

  // Case 2: scroll delta of 10, 20
  child->SetScrollDelta(gfx::Vector2d(10, 20));
  ExecuteCalculateDrawProperties(root_.get());

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

  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
                                  child->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
                                  grand_child->draw_transform());

  // Case 3: fixed-container size delta of 20, 20
  SetFixedContainerSizeDelta(child, gfx::Vector2d(20, 20));
  ExecuteCalculateDrawProperties(root_.get());

  // Top-left fixed-position layer should not be affected by container size.
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
                                  child->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
                                  grand_child->draw_transform());

  // Case 4: Bottom-right fixed-position layer.
  grand_child->SetPositionConstraint(fixed_to_bottom_right_);
  ExecuteCalculateDrawProperties(root_.get());

  // Bottom-right fixed-position layer moves as container resizes.
  expected_grand_child_transform.MakeIdentity();
  // Apply child layer transform.
  expected_grand_child_transform.PreconcatTransform(non_uniform_scale);
  // 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->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
                                  grand_child->draw_transform());
}

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.
  LayerImpl* child = scroll_->children()[0];
  LayerImpl* grand_child = child->children()[0];
  LayerImpl* great_grand_child = grand_child->children()[0];

  child->SetIsContainerForFixedPositionLayers(true);
  grand_child->SetPosition(gfx::PointF(8.f, 6.f));
  great_grand_child->SetPositionConstraint(fixed_to_top_left_);

  // Case 1: scroll delta of 0, 0
  child->SetScrollDelta(gfx::Vector2d(0, 0));
  ExecuteCalculateDrawProperties(root_.get());

  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->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
                                  grand_child->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
                                  great_grand_child->draw_transform());

  // Case 2: scroll delta of 10, 10
  child->SetScrollDelta(gfx::Vector2d(10, 10));
  ExecuteCalculateDrawProperties(root_.get());

  // 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->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
                                  grand_child->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
                                  great_grand_child->draw_transform());

  // Case 3: fixed-container size delta of 20, 20
  SetFixedContainerSizeDelta(child, gfx::Vector2d(20, 20));
  ExecuteCalculateDrawProperties(root_.get());

  // Top-left fixed-position layer should not be affected by container size.
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
                                  child->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
                                  grand_child->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
                                  great_grand_child->draw_transform());

  // Case 4: Bottom-right fixed-position layer.
  great_grand_child->SetPositionConstraint(fixed_to_bottom_right_);
  ExecuteCalculateDrawProperties(root_.get());

  // 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->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
                                  grand_child->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
                                  great_grand_child->draw_transform());
}

TEST_F(LayerPositionConstraintTest,
     ScrollCompensationForFixedPositionLayerWithDistantContainerAndTransforms) {
  // This test checks for correct scroll compensation when the fixed-position
  // container is NOT the direct parent of the fixed-position layer, and the
  // hierarchy has various transforms that have to be processed in the correct
  // order.
  LayerImpl* child = scroll_->children()[0];
  LayerImpl* grand_child = child->children()[0];
  LayerImpl* great_grand_child = grand_child->children()[0];

  gfx::Transform rotation_about_z;
  rotation_about_z.RotateAboutZAxis(90.0);

  child->SetIsContainerForFixedPositionLayers(true);
  child->SetTransform(rotation_about_z);
  grand_child->SetPosition(gfx::PointF(8.f, 6.f));
  grand_child->SetTransform(rotation_about_z);
  // great_grand_child is positioned upside-down with respect to the render
  // target.
  great_grand_child->SetPositionConstraint(fixed_to_top_left_);

  // Case 1: scroll delta of 0, 0
  child->SetScrollDelta(gfx::Vector2d(0, 0));
  ExecuteCalculateDrawProperties(root_.get());

  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);
  expected_grand_child_transform.PreconcatTransform(
      rotation_about_z);  // grand_child's local transform

  gfx::Transform expected_great_grand_child_transform =
      expected_grand_child_transform;

  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
                                  child->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
                                  grand_child->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
                                  great_grand_child->draw_transform());

  // Case 2: scroll delta of 10, 20
  child->SetScrollDelta(gfx::Vector2d(10, 20));
  ExecuteCalculateDrawProperties(root_.get());

  // 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, -20.0);  // scroll delta
  expected_child_transform.PreconcatTransform(rotation_about_z);

  expected_grand_child_transform.MakeIdentity();
  expected_grand_child_transform.Translate(
      -10.0, -20.0);      // child's scroll delta is inherited
  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);
  expected_grand_child_transform.PreconcatTransform(
      rotation_about_z);  // grand_child's local transform

  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
                                  child->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
                                  grand_child->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
                                  great_grand_child->draw_transform());

  // Case 3: fixed-container size delta of 20, 20
  SetFixedContainerSizeDelta(child, gfx::Vector2d(20, 20));
  ExecuteCalculateDrawProperties(root_.get());

  // Top-left fixed-position layer should not be affected by container size.
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
                                  child->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
                                  grand_child->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
                                  great_grand_child->draw_transform());

  // Case 4: Bottom-right fixed-position layer.
  great_grand_child->SetPositionConstraint(fixed_to_bottom_right_);
  ExecuteCalculateDrawProperties(root_.get());

  // Bottom-right fixed-position layer moves as container resizes.
  expected_great_grand_child_transform.MakeIdentity();
  // Apply child layer transform.
  expected_great_grand_child_transform.PreconcatTransform(rotation_about_z);
  // 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);
  // Apply grand child layer transform.
  expected_great_grand_child_transform.PreconcatTransform(rotation_about_z);

  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
                                  child->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
                                  grand_child->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
                                  great_grand_child->draw_transform());
}

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.  In this test, each scroll
  // delta occurs in a different space because of each layer's local transform.
  // This test checks for correct scroll compensation when the fixed-position
  // container is NOT the direct parent of the fixed-position layer, and the
  // hierarchy has various transforms that have to be processed in the correct
  // order.
  LayerImpl* child = scroll_->children()[0];
  LayerImpl* grand_child = child->children()[0];
  LayerImpl* great_grand_child = grand_child->children()[0];

  gfx::Transform rotation_about_z;
  rotation_about_z.RotateAboutZAxis(90.0);

  child->SetIsContainerForFixedPositionLayers(true);
  child->SetTransform(rotation_about_z);
  grand_child->SetPosition(gfx::PointF(8.f, 6.f));
  grand_child->SetTransform(rotation_about_z);
  // great_grand_child is positioned upside-down with respect to the render
  // target.
  great_grand_child->SetPositionConstraint(fixed_to_top_left_);

  // Case 1: scroll delta of 0, 0
  child->SetScrollDelta(gfx::Vector2d(0, 0));
  ExecuteCalculateDrawProperties(root_.get());

  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);
  expected_grand_child_transform.PreconcatTransform(
      rotation_about_z);  // grand_child's local transform

  gfx::Transform expected_great_grand_child_transform =
      expected_grand_child_transform;

  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
                                  child->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
                                  grand_child->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
                                  great_grand_child->draw_transform());

  // Case 2: scroll delta of 10, 20
  child->SetScrollDelta(gfx::Vector2d(10, 0));
  grand_child->SetScrollDelta(gfx::Vector2d(5, 0));
  ExecuteCalculateDrawProperties(root_.get());

  // 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, 0.0);  // scroll delta
  expected_child_transform.PreconcatTransform(rotation_about_z);

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

  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
                                  child->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
                                  grand_child->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
                                  great_grand_child->draw_transform());

  // Case 3: fixed-container size delta of 20, 20
  SetFixedContainerSizeDelta(child, gfx::Vector2d(20, 20));
  ExecuteCalculateDrawProperties(root_.get());

  // Top-left fixed-position layer should not be affected by container size.
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
                                  child->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
                                  grand_child->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
                                  great_grand_child->draw_transform());

  // Case 4: Bottom-right fixed-position layer.
  great_grand_child->SetPositionConstraint(fixed_to_bottom_right_);
  ExecuteCalculateDrawProperties(root_.get());

  // Bottom-right fixed-position layer moves as container resizes.
  expected_great_grand_child_transform.MakeIdentity();
  // Apply child layer transform.
  expected_great_grand_child_transform.PreconcatTransform(rotation_about_z);
  // 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);
  // Apply grand child layer transform.
  expected_great_grand_child_transform.PreconcatTransform(rotation_about_z);

  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
                                  child->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
                                  grand_child->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
                                  great_grand_child->draw_transform());
}

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.
  LayerImpl* child = scroll_->children()[0];
  LayerImpl* grand_child = child->children()[0];
  LayerImpl* great_grand_child = grand_child->children()[0];

  child->SetIsContainerForFixedPositionLayers(true);
  grand_child->SetPosition(gfx::PointF(8.f, 6.f));
  grand_child->SetHasRenderSurface(true);
  great_grand_child->SetPositionConstraint(fixed_to_top_left_);
  great_grand_child->SetDrawsContent(true);

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

  // Case 1: scroll delta of 0, 0
  child->SetScrollDelta(gfx::Vector2d(0, 0));
  ExecuteCalculateDrawProperties(root_.get());

  gfx::Transform expected_child_transform;
  gfx::Transform expected_surface_draw_transform;
  expected_surface_draw_transform.Translate(8.0, 6.0);
  expected_surface_draw_transform.PreconcatTransform(rotation_about_z);
  gfx::Transform expected_grand_child_transform;
  gfx::Transform expected_great_grand_child_transform;
  ASSERT_TRUE(grand_child->render_surface());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
                                  child->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(
      expected_surface_draw_transform,
      grand_child->render_surface()->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
                                  grand_child->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
                                  great_grand_child->draw_transform());

  // Case 2: scroll delta of 10, 30
  child->SetScrollDelta(gfx::Vector2d(10, 30));
  ExecuteCalculateDrawProperties(root_.get());

  // 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_surface_draw_transform.PreconcatTransform(rotation_about_z);

  // The rotation and its inverse are needed to place the scroll delta
  // compensation in the correct space. This test will fail if the
  // rotation/inverse are backwards, too, so it requires perfect order of
  // operations.
  expected_great_grand_child_transform.MakeIdentity();
  expected_great_grand_child_transform.PreconcatTransform(
      Inverse(rotation_about_z));
  // 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);

  ASSERT_TRUE(grand_child->render_surface());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
                                  child->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(
      expected_surface_draw_transform,
      grand_child->render_surface()->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
                                  grand_child->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
                                  great_grand_child->draw_transform());

  // Case 3: fixed-container size delta of 20, 20
  SetFixedContainerSizeDelta(child, gfx::Vector2d(20, 20));
  ExecuteCalculateDrawProperties(root_.get());

  // Top-left fixed-position layer should not be affected by container size.
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
                                  child->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
                                  grand_child->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
                                  great_grand_child->draw_transform());

  // Case 4: Bottom-right fixed-position layer.
  great_grand_child->SetPositionConstraint(fixed_to_bottom_right_);
  ExecuteCalculateDrawProperties(root_.get());

  // Bottom-right fixed-position layer moves as container resizes.
  expected_great_grand_child_transform.MakeIdentity();
  // The rotation and its inverse are needed to place the scroll delta
  // compensation in the correct space. This test will fail if the
  // rotation/inverse are backwards, too, so it requires perfect order of
  // operations.
  expected_great_grand_child_transform.PreconcatTransform(
      Inverse(rotation_about_z));
  // 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->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
                                  grand_child->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
                                  great_grand_child->draw_transform());
}

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.
  LayerImpl* child = scroll_->children()[0];
  LayerImpl* grand_child = child->children()[0];
  LayerImpl* great_grand_child = grand_child->children()[0];

  // Add one more layer to the test tree for this scenario.
  {
    gfx::Transform identity;
    scoped_ptr<LayerImpl> fixed_position_child =
        LayerImpl::Create(host_impl_.active_tree(), 5);
    SetLayerPropertiesForTesting(fixed_position_child.get(),
                                 identity,
                                 gfx::Point3F(),
                                 gfx::PointF(),
                                 gfx::Size(100, 100),
                                 true);
    great_grand_child->AddChild(fixed_position_child.Pass());
  }
  LayerImpl* fixed_position_child = great_grand_child->children()[0];

  // Actually set up the scenario here.
  child->SetIsContainerForFixedPositionLayers(true);
  grand_child->SetPosition(gfx::PointF(8.f, 6.f));
  grand_child->SetHasRenderSurface(true);
  great_grand_child->SetPosition(gfx::PointF(40.f, 60.f));
  great_grand_child->SetHasRenderSurface(true);
  fixed_position_child->SetPositionConstraint(fixed_to_top_left_);
  fixed_position_child->SetDrawsContent(true);

  // 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(90.0);
  rotation_about_z.Translate(-50.0, -50.0);
  grand_child->SetTransform(rotation_about_z);
  great_grand_child->SetTransform(rotation_about_z);

  // Case 1: scroll delta of 0, 0
  child->SetScrollDelta(gfx::Vector2d(0, 0));
  ExecuteCalculateDrawProperties(root_.get());

  gfx::Transform expected_child_transform;

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

  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);
  expected_great_grand_child_surface_draw_transform.PreconcatTransform(
      rotation_about_z);

  gfx::Transform expected_great_grand_child_transform;

  gfx::Transform expected_fixed_position_child_transform;

  ASSERT_TRUE(grand_child->render_surface());
  ASSERT_TRUE(great_grand_child->render_surface());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
                                  child->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(
      expected_grand_child_surface_draw_transform,
      grand_child->render_surface()->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
                                  grand_child->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(
      expected_great_grand_child_surface_draw_transform,
      great_grand_child->render_surface()->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
                                  great_grand_child->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_position_child_transform,
                                  fixed_position_child->draw_transform());

  // Case 2: scroll delta of 10, 30
  child->SetScrollDelta(gfx::Vector2d(10, 30));
  ExecuteCalculateDrawProperties(root_.get());

  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);
  expected_grand_child_surface_draw_transform.PreconcatTransform(
      rotation_about_z);

  // 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.  The expected
  // transform is: compound_draw_transform.Inverse() * translate(positive scroll
  // delta) * compound_origin_transform from great_grand_childSurface's origin
  // to the root surface.
  gfx::Transform compound_draw_transform;
  compound_draw_transform.Translate(8.0,
                                    6.0);  // origin translation of grand_child
  compound_draw_transform.PreconcatTransform(
      rotation_about_z);                   // rotation of grand_child
  compound_draw_transform.Translate(
      40.0, 60.0);        // origin translation of great_grand_child
  compound_draw_transform.PreconcatTransform(
      rotation_about_z);  // rotation of great_grand_child

  expected_fixed_position_child_transform.MakeIdentity();
  expected_fixed_position_child_transform.PreconcatTransform(
      Inverse(compound_draw_transform));
  // 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(
      compound_draw_transform);

  ASSERT_TRUE(grand_child->render_surface());
  ASSERT_TRUE(great_grand_child->render_surface());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
                                  child->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(
      expected_grand_child_surface_draw_transform,
      grand_child->render_surface()->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
                                  grand_child->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(
      expected_great_grand_child_surface_draw_transform,
      great_grand_child->render_surface()->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
                                  great_grand_child->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_position_child_transform,
                                  fixed_position_child->draw_transform());


  // Case 3: fixed-container size delta of 20, 20
  SetFixedContainerSizeDelta(child, gfx::Vector2d(20, 20));
  ExecuteCalculateDrawProperties(root_.get());

  // Top-left fixed-position layer should not be affected by container size.
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
                                  child->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
                                  grand_child->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
                                  great_grand_child->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_position_child_transform,
                                  fixed_position_child->draw_transform());

  // Case 4: Bottom-right fixed-position layer.
  fixed_position_child->SetPositionConstraint(fixed_to_bottom_right_);
  ExecuteCalculateDrawProperties(root_.get());

  // Bottom-right fixed-position layer moves as container resizes.
  expected_fixed_position_child_transform.MakeIdentity();
  expected_fixed_position_child_transform.PreconcatTransform(
      Inverse(compound_draw_transform));
  // 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(
      compound_draw_transform);

  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
                                  child->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
                                  grand_child->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
                                  great_grand_child->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_position_child_transform,
                                  fixed_position_child->draw_transform());
}

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.
  LayerImpl* child = scroll_->children()[0];
  LayerImpl* grand_child = child->children()[0];

  child->SetIsContainerForFixedPositionLayers(true);
  child->SetHasRenderSurface(true);
  grand_child->SetPositionConstraint(fixed_to_top_left_);
  grand_child->SetDrawsContent(true);

  // Case 1: scroll delta of 0, 0
  child->SetScrollDelta(gfx::Vector2d(0, 0));
  ExecuteCalculateDrawProperties(root_.get());

  gfx::Transform expected_surface_draw_transform;
  expected_surface_draw_transform.Translate(0.0, 0.0);
  gfx::Transform expected_child_transform;
  gfx::Transform expected_grand_child_transform;
  ASSERT_TRUE(child->render_surface());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_surface_draw_transform,
                                  child->render_surface()->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
                                  child->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
                                  grand_child->draw_transform());

  // Case 2: scroll delta of 10, 10
  child->SetScrollDelta(gfx::Vector2d(10, 10));
  ExecuteCalculateDrawProperties(root_.get());

  // 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);

  ASSERT_TRUE(child->render_surface());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_surface_draw_transform,
                                  child->render_surface()->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
                                  child->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
                                  grand_child->draw_transform());

  // Case 3: fixed-container size delta of 20, 20
  SetFixedContainerSizeDelta(child, gfx::Vector2d(20, 20));
  ExecuteCalculateDrawProperties(root_.get());

  // Top-left fixed-position layer should not be affected by container size.
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
                                  child->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
                                  grand_child->draw_transform());

  // Case 4: Bottom-right fixed-position layer.
  grand_child->SetPositionConstraint(fixed_to_bottom_right_);
  ExecuteCalculateDrawProperties(root_.get());

  // 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->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
                                  grand_child->draw_transform());
}

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.
  LayerImpl* child = scroll_->children()[0];
  LayerImpl* grand_child = child->children()[0];

  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);

  // Case 1: scroll delta of 0, 0
  child->SetScrollDelta(gfx::Vector2d(0, 0));
  ExecuteCalculateDrawProperties(root_.get());

  gfx::Transform expected_child_transform;
  gfx::Transform expected_grand_child_transform;
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
                                  child->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
                                  grand_child->draw_transform());

  // Case 2: scroll delta of 10, 10
  child->SetScrollDelta(gfx::Vector2d(10, 10));
  ExecuteCalculateDrawProperties(root_.get());

  // 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->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
                                  grand_child->draw_transform());

  // Case 3: fixed-container size delta of 20, 20
  SetFixedContainerSizeDelta(child, gfx::Vector2d(20, 20));
  ExecuteCalculateDrawProperties(root_.get());

  // Top-left fixed-position layer should not be affected by container size.
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
                                  child->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
                                  grand_child->draw_transform());

  // Case 4: Bottom-right fixed-position layer.
  grand_child->SetPositionConstraint(fixed_to_bottom_right_);
  ExecuteCalculateDrawProperties(root_.get());

  // 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->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
                                  grand_child->draw_transform());
}

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.

  LayerImpl* child = scroll_->children()[0];
  LayerImpl* grand_child = child->children()[0];
  LayerImpl* great_grand_child = grand_child->children()[0];

  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_);

  // Case 1: scrollDelta
  child->SetScrollDelta(gfx::Vector2d(10, 10));
  ExecuteCalculateDrawProperties(root_.get());

  // 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->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
                                  grand_child->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
                                  great_grand_child->draw_transform());

  // Case 2: sizeDelta
  child->SetScrollDelta(gfx::Vector2d(0, 0));
  SetFixedContainerSizeDelta(child, gfx::Vector2d(20, 20));
  ExecuteCalculateDrawProperties(root_.get());

  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->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
                                  grand_child->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
                                  great_grand_child->draw_transform());
}

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.

  LayerImpl* container1 = scroll_->children()[0];
  LayerImpl* fixed_to_container1 = container1->children()[0];
  LayerImpl* container2 = fixed_to_container1->children()[0];

  {
    // Add one more layer to the hierarchy for this test.
    scoped_ptr<LayerImpl> fixed_to_container2_ptr =
        LayerImpl::Create(host_impl_.active_tree(), 5);
    container2->AddChild(fixed_to_container2_ptr.Pass());
  }

  LayerImpl* fixed_to_container2 = container2->children()[0];

  container1->SetIsContainerForFixedPositionLayers(true);
  fixed_to_container1->SetPositionConstraint(fixed_to_top_left_);
  container2->SetIsContainerForFixedPositionLayers(true);
  fixed_to_container2->SetPositionConstraint(fixed_to_top_left_);

  container1->SetScrollDelta(gfx::Vector2d(0, 15));
  container2->SetScrollDelta(gfx::Vector2d(30, 0));
  ExecuteCalculateDrawProperties(root_.get());

  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->draw_transform());

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

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

  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_to_container2_transform,
                                  fixed_to_container2->draw_transform());
}
}  // namespace
}  // namespace cc
