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

#include "cc/trees/layer_tree_host_common.h"

#include <algorithm>
#include <set>

#include "cc/animation/layer_animation_controller.h"
#include "cc/animation/transform_operations.h"
#include "cc/base/math_util.h"
#include "cc/layers/content_layer.h"
#include "cc/layers/content_layer_client.h"
#include "cc/layers/layer.h"
#include "cc/layers/layer_client.h"
#include "cc/layers/layer_impl.h"
#include "cc/layers/layer_iterator.h"
#include "cc/layers/render_surface.h"
#include "cc/layers/render_surface_impl.h"
#include "cc/output/copy_output_request.h"
#include "cc/output/copy_output_result.h"
#include "cc/test/animation_test_common.h"
#include "cc/test/fake_impl_proxy.h"
#include "cc/test/fake_layer_tree_host.h"
#include "cc/test/fake_layer_tree_host_impl.h"
#include "cc/test/fake_picture_layer.h"
#include "cc/test/fake_picture_layer_impl.h"
#include "cc/test/geometry_test_utils.h"
#include "cc/test/layer_tree_host_common_test.h"
#include "cc/trees/layer_tree_impl.h"
#include "cc/trees/proxy.h"
#include "cc/trees/single_thread_proxy.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gfx/geometry/quad_f.h"
#include "ui/gfx/transform.h"

namespace cc {
namespace {

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

  bool DrawsContent() const override;

 private:
  ~LayerWithForcedDrawsContent() override {}
};

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

class MockContentLayerClient : public ContentLayerClient {
 public:
  MockContentLayerClient() {}
  ~MockContentLayerClient() override {}
  void PaintContents(
      SkCanvas* canvas,
      const gfx::Rect& clip,
      ContentLayerClient::GraphicsContextStatus gc_status) override {}
  scoped_refptr<DisplayItemList> PaintContentsToDisplayList(
      const gfx::Rect& clip,
      GraphicsContextStatus gc_status) override {
    NOTIMPLEMENTED();
    return DisplayItemList::Create();
  }
  bool FillsBoundsCompletely() const override { return false; }
};

scoped_refptr<FakePictureLayer> CreateDrawablePictureLayer(
    ContentLayerClient* delegate) {
  scoped_refptr<FakePictureLayer> to_return =
      FakePictureLayer::Create(delegate);
  to_return->SetIsDrawable(true);
  return to_return;
}

scoped_refptr<ContentLayer> CreateDrawableContentLayer(
    ContentLayerClient* delegate) {
  scoped_refptr<ContentLayer> to_return = ContentLayer::Create(delegate);
  to_return->SetIsDrawable(true);
  return to_return;
}

#define EXPECT_CONTENTS_SCALE_EQ(expected, layer)         \
  do {                                                    \
    EXPECT_FLOAT_EQ(expected, layer->contents_scale_x()); \
    EXPECT_FLOAT_EQ(expected, layer->contents_scale_y()); \
  } while (false)

#define EXPECT_IDEAL_SCALE_EQ(expected, layer)                                \
  do {                                                                        \
    EXPECT_FLOAT_EQ(expected, layer->draw_properties().ideal_contents_scale); \
  } while (false)

TEST_F(LayerTreeHostCommonTest, TransformsForNoOpLayer) {
  // Sanity check: For layers positioned at zero, with zero size,
  // and with identity transforms, then the draw transform,
  // screen space transform, and the hierarchy passed on to children
  // layers should also be identity transforms.

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

  scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
  host->SetRootLayer(parent);

  gfx::Transform identity_matrix;
  SetLayerPropertiesForTesting(parent.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(100, 100),
                               true,
                               false);
  SetLayerPropertiesForTesting(child.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(),
                               true,
                               false);
  SetLayerPropertiesForTesting(grand_child.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(),
                               true,
                               false);

  ExecuteCalculateDrawProperties(parent.get());

  EXPECT_TRANSFORMATION_MATRIX_EQ(identity_matrix, child->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(identity_matrix,
                                  child->screen_space_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(identity_matrix,
                                  grand_child->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(identity_matrix,
                                  grand_child->screen_space_transform());
}

TEST_F(LayerTreeHostCommonTest, DoNotSkipLayersWithHandlers) {
  scoped_refptr<Layer> parent = Layer::Create();
  scoped_refptr<Layer> child = Layer::Create();
  scoped_refptr<Layer> grand_child = Layer::Create();
  parent->AddChild(child);
  child->AddChild(grand_child);

  scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
  host->SetRootLayer(parent);

  gfx::Transform identity_matrix;
  SetLayerPropertiesForTesting(parent.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(100, 100),
                               true,
                               false);
  SetLayerPropertiesForTesting(child.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(10, 10),
                               gfx::Size(100, 100),
                               true,
                               false);
  // This would have previously caused us to skip our subtree, but this would be
  // wrong; we need up-to-date draw properties to do hit testing on the layers
  // with handlers.
  child->SetOpacity(0.f);
  SetLayerPropertiesForTesting(grand_child.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(10, 10),
                               gfx::Size(100, 100),
                               true,
                               false);
  grand_child->SetTouchEventHandlerRegion(gfx::Rect(0, 0, 100, 100));

  ExecuteCalculateDrawProperties(parent.get());

  // Check that we've computed draw properties for the subtree rooted at
  // |child|.
  EXPECT_FALSE(child->draw_transform().IsIdentity());
  EXPECT_FALSE(grand_child->draw_transform().IsIdentity());
}

TEST_F(LayerTreeHostCommonTest, TransformsForSingleLayer) {
  gfx::Transform identity_matrix;
  scoped_refptr<Layer> layer = Layer::Create();

  scoped_refptr<Layer> root = Layer::Create();
  SetLayerPropertiesForTesting(root.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(1, 2),
                               true,
                               false);
  root->AddChild(layer);

  scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
  host->SetRootLayer(root);

  // Case 2: Setting the bounds of the layer should not affect either the draw
  // transform or the screenspace transform.
  gfx::Transform translation_to_center;
  translation_to_center.Translate(5.0, 6.0);
  SetLayerPropertiesForTesting(layer.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(10, 12),
                               true,
                               false);
  ExecuteCalculateDrawProperties(root.get());
  EXPECT_TRANSFORMATION_MATRIX_EQ(identity_matrix, layer->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(identity_matrix,
                                  layer->screen_space_transform());

  // Case 3: The anchor point by itself (without a layer transform) should have
  // no effect on the transforms.
  SetLayerPropertiesForTesting(layer.get(),
                               identity_matrix,
                               gfx::Point3F(2.5f, 3.0f, 0.f),
                               gfx::PointF(),
                               gfx::Size(10, 12),
                               true,
                               false);
  ExecuteCalculateDrawProperties(root.get());
  EXPECT_TRANSFORMATION_MATRIX_EQ(identity_matrix, layer->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(identity_matrix,
                                  layer->screen_space_transform());

  // Case 4: A change in actual position affects both the draw transform and
  // screen space transform.
  gfx::Transform position_transform;
  position_transform.Translate(0.f, 1.2f);
  SetLayerPropertiesForTesting(layer.get(),
                               identity_matrix,
                               gfx::Point3F(2.5f, 3.0f, 0.f),
                               gfx::PointF(0.f, 1.2f),
                               gfx::Size(10, 12),
                               true,
                               false);
  ExecuteCalculateDrawProperties(root.get());
  EXPECT_TRANSFORMATION_MATRIX_EQ(position_transform, layer->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(position_transform,
                                  layer->screen_space_transform());

  // Case 5: In the correct sequence of transforms, the layer transform should
  // pre-multiply the translation_to_center. This is easily tested by using a
  // scale transform, because scale and translation are not commutative.
  gfx::Transform layer_transform;
  layer_transform.Scale3d(2.0, 2.0, 1.0);
  SetLayerPropertiesForTesting(layer.get(),
                               layer_transform,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(10, 12),
                               true,
                               false);
  ExecuteCalculateDrawProperties(root.get());
  EXPECT_TRANSFORMATION_MATRIX_EQ(layer_transform, layer->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(layer_transform,
                                  layer->screen_space_transform());

  // Case 6: The layer transform should occur with respect to the anchor point.
  gfx::Transform translation_to_anchor;
  translation_to_anchor.Translate(5.0, 0.0);
  gfx::Transform expected_result =
      translation_to_anchor * layer_transform * Inverse(translation_to_anchor);
  SetLayerPropertiesForTesting(layer.get(),
                               layer_transform,
                               gfx::Point3F(5.0f, 0.f, 0.f),
                               gfx::PointF(),
                               gfx::Size(10, 12),
                               true,
                               false);
  ExecuteCalculateDrawProperties(root.get());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_result, layer->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_result,
                                  layer->screen_space_transform());

  // Case 7: Verify that position pre-multiplies the layer transform.  The
  // current implementation of CalculateDrawProperties does this implicitly, but
  // it is still worth testing to detect accidental regressions.
  expected_result = position_transform * translation_to_anchor *
                    layer_transform * Inverse(translation_to_anchor);
  SetLayerPropertiesForTesting(layer.get(),
                               layer_transform,
                               gfx::Point3F(5.0f, 0.f, 0.f),
                               gfx::PointF(0.f, 1.2f),
                               gfx::Size(10, 12),
                               true,
                               false);
  ExecuteCalculateDrawProperties(root.get());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_result, layer->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_result,
                                  layer->screen_space_transform());
}

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

  FakeImplProxy proxy;
  TestSharedBitmapManager shared_bitmap_manager;
  FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager);

  gfx::Transform identity_matrix;
  scoped_ptr<LayerImpl> sublayer_scoped_ptr(
      LayerImpl::Create(host_impl.active_tree(), 1));
  LayerImpl* sublayer = sublayer_scoped_ptr.get();
  sublayer->SetContentsScale(kPageScale * kDeviceScale,
                             kPageScale * kDeviceScale);
  SetLayerPropertiesForTesting(sublayer, identity_matrix, gfx::Point3F(),
                               gfx::PointF(), gfx::Size(500, 500), true, false,
                               false);

  scoped_ptr<LayerImpl> scroll_layer_scoped_ptr(
      LayerImpl::Create(host_impl.active_tree(), 2));
  LayerImpl* scroll_layer = scroll_layer_scoped_ptr.get();
  SetLayerPropertiesForTesting(scroll_layer, identity_matrix, gfx::Point3F(),
                               gfx::PointF(), gfx::Size(10, 20), true, false,
                               false);
  scoped_ptr<LayerImpl> clip_layer_scoped_ptr(
      LayerImpl::Create(host_impl.active_tree(), 4));
  LayerImpl* clip_layer = clip_layer_scoped_ptr.get();

  scroll_layer->SetScrollClipLayer(clip_layer->id());
  clip_layer->SetBounds(
      gfx::Size(scroll_layer->bounds().width() + kMaxScrollOffset.x(),
                scroll_layer->bounds().height() + kMaxScrollOffset.y()));
  scroll_layer->SetScrollClipLayer(clip_layer->id());
  scroll_layer->SetScrollDelta(kScrollDelta);
  gfx::Transform impl_transform;
  scroll_layer->AddChild(sublayer_scoped_ptr.Pass());
  LayerImpl* scroll_layer_raw_ptr = scroll_layer_scoped_ptr.get();
  clip_layer->AddChild(scroll_layer_scoped_ptr.Pass());
  scroll_layer_raw_ptr->SetScrollOffset(kScrollOffset);

  scoped_ptr<LayerImpl> root(LayerImpl::Create(host_impl.active_tree(), 3));
  SetLayerPropertiesForTesting(root.get(), identity_matrix, gfx::Point3F(),
                               gfx::PointF(), gfx::Size(3, 4), true, false,
                               false);
  root->AddChild(clip_layer_scoped_ptr.Pass());
  root->SetHasRenderSurface(true);

  ExecuteCalculateDrawProperties(
      root.get(), kDeviceScale, kPageScale, scroll_layer->parent());
  gfx::Transform expected_transform = identity_matrix;
  gfx::PointF sub_layer_screen_position = kScrollLayerPosition - kScrollDelta;
  sub_layer_screen_position.Scale(kPageScale * kDeviceScale);
  expected_transform.Translate(MathUtil::Round(sub_layer_screen_position.x()),
                               MathUtil::Round(sub_layer_screen_position.y()));
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_transform,
                                  sublayer->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_transform,
                                  sublayer->screen_space_transform());

  gfx::Transform arbitrary_translate;
  const float kTranslateX = 10.6f;
  const float kTranslateY = 20.6f;
  arbitrary_translate.Translate(kTranslateX, kTranslateY);
  SetLayerPropertiesForTesting(scroll_layer, arbitrary_translate,
                               gfx::Point3F(), gfx::PointF(), gfx::Size(10, 20),
                               true, false, false);
  ExecuteCalculateDrawProperties(
      root.get(), kDeviceScale, kPageScale, scroll_layer->parent());
  expected_transform.MakeIdentity();
  expected_transform.Translate(
      MathUtil::Round(kTranslateX * kPageScale * kDeviceScale +
                      sub_layer_screen_position.x()),
      MathUtil::Round(kTranslateY * kPageScale * kDeviceScale +
                      sub_layer_screen_position.y()));
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_transform,
                                  sublayer->draw_transform());
}

TEST_F(LayerTreeHostCommonTest, TransformsForSimpleHierarchy) {
  gfx::Transform identity_matrix;
  scoped_refptr<Layer> root = Layer::Create();
  scoped_refptr<Layer> parent = Layer::Create();
  scoped_refptr<Layer> child = Layer::Create();
  scoped_refptr<Layer> grand_child = Layer::Create();
  root->AddChild(parent);
  parent->AddChild(child);
  child->AddChild(grand_child);

  scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
  host->SetRootLayer(root);

  // One-time setup of root layer
  SetLayerPropertiesForTesting(root.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(1, 2),
                               true,
                               false);

  // Case 1: parent's anchor point should not affect child or grand_child.
  SetLayerPropertiesForTesting(parent.get(),
                               identity_matrix,
                               gfx::Point3F(2.5f, 3.0f, 0.f),
                               gfx::PointF(),
                               gfx::Size(10, 12),
                               true,
                               false);
  SetLayerPropertiesForTesting(child.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(16, 18),
                               true,
                               false);
  SetLayerPropertiesForTesting(grand_child.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(76, 78),
                               true,
                               false);
  ExecuteCalculateDrawProperties(root.get());
  EXPECT_TRANSFORMATION_MATRIX_EQ(identity_matrix, child->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(identity_matrix,
                                  child->screen_space_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(identity_matrix,
                                  grand_child->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(identity_matrix,
                                  grand_child->screen_space_transform());

  // Case 2: parent's position affects child and grand_child.
  gfx::Transform parent_position_transform;
  parent_position_transform.Translate(0.f, 1.2f);
  SetLayerPropertiesForTesting(parent.get(),
                               identity_matrix,
                               gfx::Point3F(2.5f, 3.0f, 0.f),
                               gfx::PointF(0.f, 1.2f),
                               gfx::Size(10, 12),
                               true,
                               false);
  SetLayerPropertiesForTesting(child.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(16, 18),
                               true,
                               false);
  SetLayerPropertiesForTesting(grand_child.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(76, 78),
                               true,
                               false);
  ExecuteCalculateDrawProperties(root.get());
  EXPECT_TRANSFORMATION_MATRIX_EQ(parent_position_transform,
                                  child->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(parent_position_transform,
                                  child->screen_space_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(parent_position_transform,
                                  grand_child->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(parent_position_transform,
                                  grand_child->screen_space_transform());

  // Case 3: parent's local transform affects child and grandchild
  gfx::Transform parent_layer_transform;
  parent_layer_transform.Scale3d(2.0, 2.0, 1.0);
  gfx::Transform parent_translation_to_anchor;
  parent_translation_to_anchor.Translate(2.5, 3.0);
  gfx::Transform parent_composite_transform =
      parent_translation_to_anchor * parent_layer_transform *
      Inverse(parent_translation_to_anchor);
  SetLayerPropertiesForTesting(parent.get(),
                               parent_layer_transform,
                               gfx::Point3F(2.5f, 3.0f, 0.f),
                               gfx::PointF(),
                               gfx::Size(10, 12),
                               true,
                               false);
  SetLayerPropertiesForTesting(child.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(16, 18),
                               true,
                               false);
  SetLayerPropertiesForTesting(grand_child.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(76, 78),
                               true,
                               false);
  ExecuteCalculateDrawProperties(root.get());
  EXPECT_TRANSFORMATION_MATRIX_EQ(parent_composite_transform,
                                  child->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(parent_composite_transform,
                                  child->screen_space_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(parent_composite_transform,
                                  grand_child->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(parent_composite_transform,
                                  grand_child->screen_space_transform());
}

TEST_F(LayerTreeHostCommonTest, TransformsForSingleRenderSurface) {
  scoped_refptr<Layer> root = Layer::Create();
  scoped_refptr<Layer> parent = Layer::Create();
  scoped_refptr<Layer> child = Layer::Create();
  scoped_refptr<LayerWithForcedDrawsContent> grand_child =
      make_scoped_refptr(new LayerWithForcedDrawsContent());
  root->AddChild(parent);
  parent->AddChild(child);
  child->AddChild(grand_child);

  scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
  host->SetRootLayer(root);

  // One-time setup of root layer
  gfx::Transform identity_matrix;
  SetLayerPropertiesForTesting(root.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(1, 2),
                               true,
                               false);

  // Child is set up so that a new render surface should be created.
  child->SetOpacity(0.5f);
  child->SetForceRenderSurface(true);

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

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

  // Child's render surface should not exist yet.
  ASSERT_FALSE(child->render_surface());

  SetLayerPropertiesForTesting(parent.get(),
                               parent_layer_transform,
                               gfx::Point3F(25.0f, 30.0f, 0.f),
                               gfx::PointF(),
                               gfx::Size(100, 120),
                               true,
                               false);
  SetLayerPropertiesForTesting(child.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(16, 18),
                               true,
                               false);
  SetLayerPropertiesForTesting(grand_child.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(8, 10),
                               true,
                               false);
  ExecuteCalculateDrawProperties(root.get());

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

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

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

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

TEST_F(LayerTreeHostCommonTest, TransformsForReplica) {
  scoped_refptr<Layer> root = Layer::Create();
  scoped_refptr<Layer> parent = Layer::Create();
  scoped_refptr<Layer> child = Layer::Create();
  scoped_refptr<Layer> child_replica = Layer::Create();
  scoped_refptr<LayerWithForcedDrawsContent> grand_child =
      make_scoped_refptr(new LayerWithForcedDrawsContent());
  root->AddChild(parent);
  parent->AddChild(child);
  child->AddChild(grand_child);
  child->SetReplicaLayer(child_replica.get());

  scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
  host->SetRootLayer(root);

  // One-time setup of root layer
  gfx::Transform identity_matrix;
  SetLayerPropertiesForTesting(root.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(1, 2),
                               true,
                               false);

  // Child is set up so that a new render surface should be created.
  child->SetOpacity(0.5f);

  gfx::Transform parent_layer_transform;
  parent_layer_transform.Scale3d(2.0, 2.0, 1.0);
  gfx::Transform parent_translation_to_anchor;
  parent_translation_to_anchor.Translate(2.5, 3.0);
  gfx::Transform parent_composite_transform =
      parent_translation_to_anchor * parent_layer_transform *
      Inverse(parent_translation_to_anchor);
  gfx::Transform replica_layer_transform;
  replica_layer_transform.Scale3d(3.0, 3.0, 1.0);
  gfx::Vector2dF parent_composite_scale =
      MathUtil::ComputeTransform2dScaleComponents(parent_composite_transform,
                                                  1.f);
  gfx::Transform surface_sublayer_transform;
  surface_sublayer_transform.Scale(parent_composite_scale.x(),
                                   parent_composite_scale.y());
  gfx::Transform replica_composite_transform =
      parent_composite_transform * replica_layer_transform *
      Inverse(surface_sublayer_transform);
  child_replica->SetIsDrawable(true);
  // Child's render surface should not exist yet.
  ASSERT_FALSE(child->render_surface());

  SetLayerPropertiesForTesting(parent.get(),
                               parent_layer_transform,
                               gfx::Point3F(2.5f, 3.0f, 0.f),
                               gfx::PointF(),
                               gfx::Size(10, 12),
                               true,
                               false);
  SetLayerPropertiesForTesting(child.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(16, 18),
                               true,
                               false);
  SetLayerPropertiesForTesting(grand_child.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(-0.5f, -0.5f),
                               gfx::Size(1, 1),
                               true,
                               false);
  SetLayerPropertiesForTesting(child_replica.get(),
                               replica_layer_transform,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(),
                               true,
                               false);
  ExecuteCalculateDrawProperties(root.get());

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

  EXPECT_TRANSFORMATION_MATRIX_EQ(
      replica_composite_transform,
      child->render_target()->render_surface()->replica_draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(replica_composite_transform,
                                  child->render_target()
                                      ->render_surface()
                                      ->replica_screen_space_transform());
}

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

  scoped_refptr<Layer> root = Layer::Create();
  scoped_refptr<Layer> parent = Layer::Create();
  scoped_refptr<Layer> render_surface1 = Layer::Create();
  scoped_refptr<Layer> render_surface2 = Layer::Create();
  scoped_refptr<Layer> child_of_root = Layer::Create();
  scoped_refptr<Layer> child_of_rs1 = Layer::Create();
  scoped_refptr<Layer> child_of_rs2 = Layer::Create();
  scoped_refptr<Layer> replica_of_rs1 = Layer::Create();
  scoped_refptr<Layer> replica_of_rs2 = Layer::Create();
  scoped_refptr<Layer> grand_child_of_root = Layer::Create();
  scoped_refptr<LayerWithForcedDrawsContent> grand_child_of_rs1 =
      make_scoped_refptr(new LayerWithForcedDrawsContent());
  scoped_refptr<LayerWithForcedDrawsContent> grand_child_of_rs2 =
      make_scoped_refptr(new LayerWithForcedDrawsContent());
  root->AddChild(parent);
  parent->AddChild(render_surface1);
  parent->AddChild(child_of_root);
  render_surface1->AddChild(child_of_rs1);
  render_surface1->AddChild(render_surface2);
  render_surface2->AddChild(child_of_rs2);
  child_of_root->AddChild(grand_child_of_root);
  child_of_rs1->AddChild(grand_child_of_rs1);
  child_of_rs2->AddChild(grand_child_of_rs2);
  render_surface1->SetReplicaLayer(replica_of_rs1.get());
  render_surface2->SetReplicaLayer(replica_of_rs2.get());

  scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
  host->SetRootLayer(root);

  // In combination with descendant draws content, opacity != 1 forces the layer
  // to have a new render surface.
  render_surface1->SetOpacity(0.5f);
  render_surface2->SetOpacity(0.33f);

  // One-time setup of root layer
  gfx::Transform identity_matrix;
  SetLayerPropertiesForTesting(root.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(1, 2),
                               true,
                               false);

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

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

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

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

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

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

  SetLayerPropertiesForTesting(parent.get(),
                               layer_transform,
                               gfx::Point3F(2.5f, 0.f, 0.f),
                               gfx::PointF(),
                               gfx::Size(10, 10),
                               true,
                               false);
  SetLayerPropertiesForTesting(render_surface1.get(),
                               layer_transform,
                               gfx::Point3F(2.5f, 0.f, 0.f),
                               gfx::PointF(),
                               gfx::Size(10, 10),
                               true,
                               false);
  SetLayerPropertiesForTesting(render_surface2.get(),
                               layer_transform,
                               gfx::Point3F(2.5f, 0.f, 0.f),
                               gfx::PointF(),
                               gfx::Size(10, 10),
                               true,
                               false);
  SetLayerPropertiesForTesting(child_of_root.get(),
                               layer_transform,
                               gfx::Point3F(2.5f, 0.f, 0.f),
                               gfx::PointF(),
                               gfx::Size(10, 10),
                               true,
                               false);
  SetLayerPropertiesForTesting(child_of_rs1.get(),
                               layer_transform,
                               gfx::Point3F(2.5f, 0.f, 0.f),
                               gfx::PointF(),
                               gfx::Size(10, 10),
                               true,
                               false);
  SetLayerPropertiesForTesting(child_of_rs2.get(),
                               layer_transform,
                               gfx::Point3F(2.5f, 0.f, 0.f),
                               gfx::PointF(),
                               gfx::Size(10, 10),
                               true,
                               false);
  SetLayerPropertiesForTesting(grand_child_of_root.get(),
                               layer_transform,
                               gfx::Point3F(2.5f, 0.f, 0.f),
                               gfx::PointF(),
                               gfx::Size(10, 10),
                               true,
                               false);
  SetLayerPropertiesForTesting(grand_child_of_rs1.get(),
                               layer_transform,
                               gfx::Point3F(2.5f, 0.f, 0.f),
                               gfx::PointF(),
                               gfx::Size(10, 10),
                               true,
                               false);
  SetLayerPropertiesForTesting(grand_child_of_rs2.get(),
                               layer_transform,
                               gfx::Point3F(2.5f, 0.f, 0.f),
                               gfx::PointF(),
                               gfx::Size(10, 10),
                               true,
                               false);
  SetLayerPropertiesForTesting(replica_of_rs1.get(),
                               replica_layer_transform,
                               gfx::Point3F(2.5f, 0.f, 0.f),
                               gfx::PointF(),
                               gfx::Size(),
                               true,
                               false);
  SetLayerPropertiesForTesting(replica_of_rs2.get(),
                               replica_layer_transform,
                               gfx::Point3F(2.5f, 0.f, 0.f),
                               gfx::PointF(),
                               gfx::Size(),
                               true,
                               false);

  ExecuteCalculateDrawProperties(root.get());

  // Only layers that are associated with render surfaces should have an actual
  // RenderSurface() value.
  ASSERT_TRUE(root->render_surface());
  ASSERT_FALSE(child_of_root->render_surface());
  ASSERT_FALSE(grand_child_of_root->render_surface());

  ASSERT_TRUE(render_surface1->render_surface());
  ASSERT_FALSE(child_of_rs1->render_surface());
  ASSERT_FALSE(grand_child_of_rs1->render_surface());

  ASSERT_TRUE(render_surface2->render_surface());
  ASSERT_FALSE(child_of_rs2->render_surface());
  ASSERT_FALSE(grand_child_of_rs2->render_surface());

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

  EXPECT_EQ(render_surface1.get(), render_surface1->render_target());
  EXPECT_EQ(render_surface1.get(), child_of_rs1->render_target());
  EXPECT_EQ(render_surface1.get(), grand_child_of_rs1->render_target());

  EXPECT_EQ(render_surface2.get(), render_surface2->render_target());
  EXPECT_EQ(render_surface2.get(), child_of_rs2->render_target());
  EXPECT_EQ(render_surface2.get(), grand_child_of_rs2->render_target());

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

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

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

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

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

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

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

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

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

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

TEST_F(LayerTreeHostCommonTest, TransformsForFlatteningLayer) {
  // For layers that flatten their subtree, there should be an orthographic
  // projection (for x and y values) in the middle of the transform sequence.
  // Note that the way the code is currently implemented, it is not expected to
  // use a canonical orthographic projection.

  scoped_refptr<Layer> root = Layer::Create();
  scoped_refptr<Layer> child = Layer::Create();
  scoped_refptr<LayerWithForcedDrawsContent> grand_child =
      make_scoped_refptr(new LayerWithForcedDrawsContent());

  gfx::Transform rotation_about_y_axis;
  rotation_about_y_axis.RotateAboutYAxis(30.0);

  const gfx::Transform identity_matrix;
  SetLayerPropertiesForTesting(root.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(100, 100),
                               true,
                               false);
  SetLayerPropertiesForTesting(child.get(),
                               rotation_about_y_axis,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(10, 10),
                               true,
                               false);
  SetLayerPropertiesForTesting(grand_child.get(),
                               rotation_about_y_axis,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(10, 10),
                               true,
                               false);

  root->AddChild(child);
  child->AddChild(grand_child);
  child->SetForceRenderSurface(true);

  scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
  host->SetRootLayer(root);

  // No layers in this test should preserve 3d.
  ASSERT_TRUE(root->should_flatten_transform());
  ASSERT_TRUE(child->should_flatten_transform());
  ASSERT_TRUE(grand_child->should_flatten_transform());

  gfx::Transform expected_child_draw_transform = rotation_about_y_axis;
  gfx::Transform expected_child_screen_space_transform = rotation_about_y_axis;
  gfx::Transform expected_grand_child_draw_transform =
      rotation_about_y_axis;  // draws onto child's render surface
  gfx::Transform flattened_rotation_about_y = rotation_about_y_axis;
  flattened_rotation_about_y.FlattenTo2d();
  gfx::Transform expected_grand_child_screen_space_transform =
      flattened_rotation_about_y * rotation_about_y_axis;

  ExecuteCalculateDrawProperties(root.get());

  // The child's draw transform should have been taken by its surface.
  ASSERT_TRUE(child->render_surface());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_draw_transform,
                                  child->render_surface()->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(
      expected_child_screen_space_transform,
      child->render_surface()->screen_space_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(identity_matrix, child->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_screen_space_transform,
                                  child->screen_space_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_draw_transform,
                                  grand_child->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_screen_space_transform,
                                  grand_child->screen_space_transform());
}

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

  scoped_refptr<Layer> root = Layer::Create();
  scoped_refptr<Layer> child = Layer::Create();
  scoped_refptr<LayerWithForcedDrawsContent> grand_child =
      make_scoped_refptr(new LayerWithForcedDrawsContent());

  // The child height is zero, but has non-zero width that should be accounted
  // for while computing draw transforms.
  const gfx::Transform identity_matrix;
  SetLayerPropertiesForTesting(root.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(100, 100),
                               true,
                               false);
  SetLayerPropertiesForTesting(child.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(10, 0),
                               true,
                               false);
  SetLayerPropertiesForTesting(grand_child.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(10, 10),
                               true,
                               false);

  root->AddChild(child);
  child->AddChild(grand_child);
  child->SetForceRenderSurface(true);

  scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
  host->SetRootLayer(root);

  ExecuteCalculateDrawProperties(root.get());

  ASSERT_TRUE(child->render_surface());
  // This is the real test, the rest are sanity checks.
  EXPECT_TRANSFORMATION_MATRIX_EQ(identity_matrix,
                                  child->render_surface()->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(identity_matrix, child->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(identity_matrix,
                                  grand_child->draw_transform());
}

TEST_F(LayerTreeHostCommonTest, TransformAboveRootLayer) {
  // Transformations applied at the root of the tree should be forwarded
  // to child layers instead of applied to the root RenderSurface.
  const gfx::Transform identity_matrix;
  scoped_refptr<LayerWithForcedDrawsContent> root =
      new LayerWithForcedDrawsContent;
  scoped_refptr<LayerWithForcedDrawsContent> child =
      new LayerWithForcedDrawsContent;
  child->SetScrollClipLayerId(root->id());
  root->AddChild(child);

  scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
  host->SetRootLayer(root);

  SetLayerPropertiesForTesting(root.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(20, 20),
                               true,
                               false);
  SetLayerPropertiesForTesting(child.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(20, 20),
                               true,
                               false);

  gfx::Transform translate;
  translate.Translate(50, 50);
  {
    RenderSurfaceLayerList render_surface_layer_list;
    LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
        root.get(), root->bounds(), translate, &render_surface_layer_list);
    inputs.can_adjust_raster_scales = true;
    LayerTreeHostCommon::CalculateDrawProperties(&inputs);
    EXPECT_EQ(translate, root->draw_properties().target_space_transform);
    EXPECT_EQ(translate, child->draw_properties().target_space_transform);
    EXPECT_EQ(identity_matrix, root->render_surface()->draw_transform());
    EXPECT_EQ(1.f, root->draw_properties().device_scale_factor);
    EXPECT_EQ(1.f, child->draw_properties().device_scale_factor);
  }

  gfx::Transform scale;
  scale.Scale(2, 2);
  {
    RenderSurfaceLayerList render_surface_layer_list;
    LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
        root.get(), root->bounds(), scale, &render_surface_layer_list);
    inputs.can_adjust_raster_scales = true;
    LayerTreeHostCommon::CalculateDrawProperties(&inputs);
    EXPECT_EQ(scale, root->draw_properties().target_space_transform);
    EXPECT_EQ(scale, child->draw_properties().target_space_transform);
    EXPECT_EQ(identity_matrix, root->render_surface()->draw_transform());
    EXPECT_EQ(2.f, root->draw_properties().device_scale_factor);
    EXPECT_EQ(2.f, child->draw_properties().device_scale_factor);
  }

  gfx::Transform rotate;
  rotate.Rotate(2);
  {
    RenderSurfaceLayerList render_surface_layer_list;
    LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
        root.get(), root->bounds(), rotate, &render_surface_layer_list);
    inputs.can_adjust_raster_scales = true;
    LayerTreeHostCommon::CalculateDrawProperties(&inputs);
    EXPECT_EQ(rotate, root->draw_properties().target_space_transform);
    EXPECT_EQ(rotate, child->draw_properties().target_space_transform);
    EXPECT_EQ(identity_matrix, root->render_surface()->draw_transform());
    EXPECT_EQ(1.f, root->draw_properties().device_scale_factor);
    EXPECT_EQ(1.f, child->draw_properties().device_scale_factor);
  }

  gfx::Transform composite;
  composite.ConcatTransform(translate);
  composite.ConcatTransform(scale);
  composite.ConcatTransform(rotate);
  {
    RenderSurfaceLayerList render_surface_layer_list;
    LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
        root.get(), root->bounds(), composite, &render_surface_layer_list);
    inputs.can_adjust_raster_scales = true;
    LayerTreeHostCommon::CalculateDrawProperties(&inputs);
    EXPECT_EQ(composite, root->draw_properties().target_space_transform);
    EXPECT_EQ(composite, child->draw_properties().target_space_transform);
    EXPECT_EQ(identity_matrix, root->render_surface()->draw_transform());
  }

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

  {
    RenderSurfaceLayerList render_surface_layer_list;
    LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
        root.get(), root->bounds(), translate, &render_surface_layer_list);
    inputs.device_scale_factor = device_scale_factor;
    inputs.can_adjust_raster_scales = true;
    LayerTreeHostCommon::CalculateDrawProperties(&inputs);
    gfx::Transform device_scaled_translate = translate;
    device_scaled_translate.Scale(device_scale_factor, device_scale_factor);
    EXPECT_EQ(device_scaled_translate,
              root->draw_properties().target_space_transform);
    EXPECT_EQ(device_scaled_translate,
              child->draw_properties().target_space_transform);
    EXPECT_EQ(identity_matrix, root->render_surface()->draw_transform());
    EXPECT_EQ(device_scale_factor, root->draw_properties().device_scale_factor);
    EXPECT_EQ(device_scale_factor,
              child->draw_properties().device_scale_factor);
  }

  // Verify it composes correctly with page scale.
  float page_scale_factor = 2.f;

  {
    RenderSurfaceLayerList render_surface_layer_list;
    LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
        root.get(), root->bounds(), translate, &render_surface_layer_list);
    inputs.page_scale_factor = page_scale_factor;
    inputs.page_scale_application_layer = root.get();
    inputs.can_adjust_raster_scales = true;
    LayerTreeHostCommon::CalculateDrawProperties(&inputs);
    gfx::Transform page_scaled_translate = translate;
    page_scaled_translate.Scale(page_scale_factor, page_scale_factor);
    EXPECT_EQ(translate, root->draw_properties().target_space_transform);
    EXPECT_EQ(page_scaled_translate,
              child->draw_properties().target_space_transform);
    EXPECT_EQ(identity_matrix, root->render_surface()->draw_transform());
    EXPECT_EQ(1.f, root->draw_properties().device_scale_factor);
    EXPECT_EQ(1.f, child->draw_properties().device_scale_factor);
  }

  // Verify that it composes correctly with transforms directly on root layer.
  root->SetTransform(composite);

  {
    RenderSurfaceLayerList render_surface_layer_list;
    LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
        root.get(), root->bounds(), composite, &render_surface_layer_list);
    inputs.can_adjust_raster_scales = true;
    LayerTreeHostCommon::CalculateDrawProperties(&inputs);
    gfx::Transform compositeSquared = composite;
    compositeSquared.ConcatTransform(composite);
    EXPECT_TRANSFORMATION_MATRIX_EQ(
        compositeSquared, root->draw_properties().target_space_transform);
    EXPECT_TRANSFORMATION_MATRIX_EQ(
        compositeSquared, child->draw_properties().target_space_transform);
    EXPECT_EQ(identity_matrix, root->render_surface()->draw_transform());
  }
}

TEST_F(LayerTreeHostCommonTest,
       RenderSurfaceListForRenderSurfaceWithClippedLayer) {
  scoped_refptr<Layer> parent = Layer::Create();
  scoped_refptr<Layer> render_surface1 = Layer::Create();
  scoped_refptr<LayerWithForcedDrawsContent> child =
      make_scoped_refptr(new LayerWithForcedDrawsContent());

  scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
  host->SetRootLayer(parent);

  const gfx::Transform identity_matrix;
  SetLayerPropertiesForTesting(parent.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(10, 10),
                               true,
                               false);
  SetLayerPropertiesForTesting(render_surface1.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(10, 10),
                               true,
                               false);
  SetLayerPropertiesForTesting(child.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(30.f, 30.f),
                               gfx::Size(10, 10),
                               true,
                               false);

  parent->AddChild(render_surface1);
  parent->SetMasksToBounds(true);
  render_surface1->AddChild(child);
  render_surface1->SetForceRenderSurface(true);

  RenderSurfaceLayerList render_surface_layer_list;
  LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
      parent.get(),
      parent->bounds(),
      gfx::Transform(),
      &render_surface_layer_list);
  LayerTreeHostCommon::CalculateDrawProperties(&inputs);

  // The child layer's content is entirely outside the parent's clip rect, so
  // the intermediate render surface should not be listed here, even if it was
  // forced to be created. Render surfaces without children or visible content
  // are unexpected at draw time (e.g. we might try to create a content texture
  // of size 0).
  ASSERT_TRUE(parent->render_surface());
  EXPECT_EQ(1U, render_surface_layer_list.size());
}

TEST_F(LayerTreeHostCommonTest, RenderSurfaceListForTransparentChild) {
  scoped_refptr<Layer> parent = Layer::Create();
  scoped_refptr<Layer> render_surface1 = Layer::Create();
  scoped_refptr<LayerWithForcedDrawsContent> child =
      make_scoped_refptr(new LayerWithForcedDrawsContent());

  scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
  host->SetRootLayer(parent);

  const gfx::Transform identity_matrix;
  SetLayerPropertiesForTesting(render_surface1.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(10, 10),
                               true,
                               false);
  SetLayerPropertiesForTesting(child.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(10, 10),
                               true,
                               false);

  parent->AddChild(render_surface1);
  render_surface1->AddChild(child);
  render_surface1->SetForceRenderSurface(true);
  render_surface1->SetOpacity(0.f);

  RenderSurfaceLayerList render_surface_layer_list;
  LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
      parent.get(), parent->bounds(), &render_surface_layer_list);
  inputs.can_adjust_raster_scales = true;
  LayerTreeHostCommon::CalculateDrawProperties(&inputs);

  // Since the layer is transparent, render_surface1->render_surface() should
  // not have gotten added anywhere.  Also, the drawable content rect should not
  // have been extended by the children.
  ASSERT_TRUE(parent->render_surface());
  EXPECT_EQ(0U, parent->render_surface()->layer_list().size());
  EXPECT_EQ(1U, render_surface_layer_list.size());
  EXPECT_EQ(parent->id(), render_surface_layer_list.at(0)->id());
  EXPECT_EQ(gfx::Rect(), parent->drawable_content_rect());
}

TEST_F(LayerTreeHostCommonTest, RenderSurfaceForBlendMode) {
  scoped_refptr<Layer> parent = Layer::Create();
  scoped_refptr<LayerWithForcedDrawsContent> child =
      make_scoped_refptr(new LayerWithForcedDrawsContent());

  scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
  host->SetRootLayer(parent);

  const gfx::Transform identity_matrix;
  const SkXfermode::Mode blend_mode = SkXfermode::kMultiply_Mode;
  SetLayerPropertiesForTesting(child.get(), identity_matrix, gfx::Point3F(),
                               gfx::PointF(), gfx::Size(10, 10), true, false);

  parent->AddChild(child);
  child->SetBlendMode(blend_mode);

  RenderSurfaceLayerList render_surface_layer_list;
  LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
      parent.get(), parent->bounds(), &render_surface_layer_list);
  LayerTreeHostCommon::CalculateDrawProperties(&inputs);

  // Since the child layer has a blend mode other than normal, it should get
  // its own render surface. Also, layer's draw_properties should contain the
  // default blend mode, since the render surface becomes responsible for
  // applying the blend mode.
  ASSERT_TRUE(child->render_surface());
  EXPECT_EQ(1U, child->render_surface()->layer_list().size());
  EXPECT_EQ(SkXfermode::kSrcOver_Mode, child->draw_properties().blend_mode);
}

TEST_F(LayerTreeHostCommonTest, ForceRenderSurface) {
  scoped_refptr<Layer> parent = Layer::Create();
  scoped_refptr<Layer> render_surface1 = Layer::Create();
  scoped_refptr<LayerWithForcedDrawsContent> child =
      make_scoped_refptr(new LayerWithForcedDrawsContent());
  render_surface1->SetForceRenderSurface(true);

  scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
  host->SetRootLayer(parent);

  const gfx::Transform identity_matrix;
  SetLayerPropertiesForTesting(parent.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(10, 10),
                               true,
                               false);
  SetLayerPropertiesForTesting(render_surface1.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(10, 10),
                               true,
                               false);
  SetLayerPropertiesForTesting(child.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(10, 10),
                               true,
                               false);

  parent->AddChild(render_surface1);
  render_surface1->AddChild(child);

  // Sanity check before the actual test
  EXPECT_FALSE(parent->render_surface());
  EXPECT_FALSE(render_surface1->render_surface());

  {
    RenderSurfaceLayerList render_surface_layer_list;
    LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
        parent.get(), parent->bounds(), &render_surface_layer_list);
    inputs.can_adjust_raster_scales = true;
    LayerTreeHostCommon::CalculateDrawProperties(&inputs);

    // The root layer always creates a render surface
    EXPECT_TRUE(parent->render_surface());
    EXPECT_TRUE(render_surface1->render_surface());
    EXPECT_EQ(2U, render_surface_layer_list.size());
  }

  {
    RenderSurfaceLayerList render_surface_layer_list;
    render_surface1->SetForceRenderSurface(false);
    LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
        parent.get(), parent->bounds(), &render_surface_layer_list);
    inputs.can_adjust_raster_scales = true;
    LayerTreeHostCommon::CalculateDrawProperties(&inputs);
    EXPECT_TRUE(parent->render_surface());
    EXPECT_FALSE(render_surface1->render_surface());
    EXPECT_EQ(1U, render_surface_layer_list.size());
  }
}

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

  const gfx::Transform identity_matrix;
  scoped_refptr<Layer> parent = Layer::Create();
  scoped_refptr<Layer> child = Layer::Create();
  scoped_refptr<Layer> grand_child = Layer::Create();
  scoped_refptr<Layer> great_grand_child = Layer::Create();
  scoped_refptr<LayerWithForcedDrawsContent> leaf_node1 =
      make_scoped_refptr(new LayerWithForcedDrawsContent());
  scoped_refptr<LayerWithForcedDrawsContent> leaf_node2 =
      make_scoped_refptr(new LayerWithForcedDrawsContent());
  parent->AddChild(child);
  child->AddChild(grand_child);
  grand_child->AddChild(great_grand_child);

  scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
  host->SetRootLayer(parent);

  // leaf_node1 ensures that parent and child are kept on the
  // render_surface_layer_list, even though grand_child and great_grand_child
  // should be clipped.
  child->AddChild(leaf_node1);
  great_grand_child->AddChild(leaf_node2);

  SetLayerPropertiesForTesting(parent.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(500, 500),
                               true,
                               false);
  SetLayerPropertiesForTesting(child.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(20, 20),
                               true,
                               false);
  SetLayerPropertiesForTesting(grand_child.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(45.f, 45.f),
                               gfx::Size(10, 10),
                               true,
                               false);
  SetLayerPropertiesForTesting(great_grand_child.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(10, 10),
                               true,
                               false);
  SetLayerPropertiesForTesting(leaf_node1.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(500, 500),
                               true,
                               false);
  SetLayerPropertiesForTesting(leaf_node2.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(20, 20),
                               true,
                               false);

  child->SetMasksToBounds(true);
  child->SetOpacity(0.4f);
  child->SetForceRenderSurface(true);
  grand_child->SetOpacity(0.5f);
  great_grand_child->SetOpacity(0.4f);

  RenderSurfaceLayerList render_surface_layer_list;
  LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
      parent.get(), parent->bounds(), &render_surface_layer_list);
  inputs.can_adjust_raster_scales = true;
  LayerTreeHostCommon::CalculateDrawProperties(&inputs);

  ASSERT_EQ(2U, render_surface_layer_list.size());
  EXPECT_EQ(parent->id(), render_surface_layer_list.at(0)->id());
  EXPECT_EQ(child->id(), render_surface_layer_list.at(1)->id());
}

TEST_F(LayerTreeHostCommonTest, ClipRectCullsSurfaceWithoutVisibleContent) {
  // When a render surface has a clip rect, it is used to clip the content rect
  // of the surface. When the render surface is animating its transforms, then
  // the content rect's position in the clip rect is not defined on the main
  // thread, and its content rect should not be clipped.

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

  // In this configuration, grand_child should be outside the clipped
  // content rect of the child, making grand_child not appear in the
  // render_surface_layer_list. However, when we place an animation on the
  // child, this clipping should be avoided and we should keep the grand_child
  // in the render_surface_layer_list.

  const gfx::Transform identity_matrix;
  scoped_refptr<Layer> parent = Layer::Create();
  scoped_refptr<Layer> child = Layer::Create();
  scoped_refptr<Layer> grand_child = Layer::Create();
  scoped_refptr<LayerWithForcedDrawsContent> leaf_node =
      make_scoped_refptr(new LayerWithForcedDrawsContent());
  parent->AddChild(child);
  child->AddChild(grand_child);
  grand_child->AddChild(leaf_node);

  scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
  host->SetRootLayer(parent);

  SetLayerPropertiesForTesting(parent.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(100, 100),
                               true,
                               false);
  SetLayerPropertiesForTesting(child.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(20, 20),
                               true,
                               false);
  SetLayerPropertiesForTesting(grand_child.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(200.f, 200.f),
                               gfx::Size(10, 10),
                               true,
                               false);
  SetLayerPropertiesForTesting(leaf_node.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(10, 10),
                               true,
                               false);

  parent->SetMasksToBounds(true);
  child->SetOpacity(0.4f);
  child->SetForceRenderSurface(true);
  grand_child->SetOpacity(0.4f);
  grand_child->SetForceRenderSurface(true);

  {
    RenderSurfaceLayerList render_surface_layer_list;
    LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
        parent.get(), parent->bounds(), &render_surface_layer_list);
    inputs.can_adjust_raster_scales = true;
    LayerTreeHostCommon::CalculateDrawProperties(&inputs);

    // Without an animation, we should cull child and grand_child from the
    // render_surface_layer_list.
    ASSERT_EQ(1U, render_surface_layer_list.size());
    EXPECT_EQ(parent->id(), render_surface_layer_list.at(0)->id());
  }

  // Now put an animating transform on child.
  AddAnimatedTransformToController(
      child->layer_animation_controller(), 10.0, 30, 0);

  {
    RenderSurfaceLayerList render_surface_layer_list;
    LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
        parent.get(), parent->bounds(), &render_surface_layer_list);
    inputs.can_adjust_raster_scales = true;
    LayerTreeHostCommon::CalculateDrawProperties(&inputs);

    // With an animating transform, we should keep child and grand_child in the
    // render_surface_layer_list.
    ASSERT_EQ(3U, render_surface_layer_list.size());
    EXPECT_EQ(parent->id(), render_surface_layer_list.at(0)->id());
    EXPECT_EQ(child->id(), render_surface_layer_list.at(1)->id());
    EXPECT_EQ(grand_child->id(), render_surface_layer_list.at(2)->id());
  }
}

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

  const gfx::Transform identity_matrix;
  scoped_refptr<Layer> root = Layer::Create();
  scoped_refptr<Layer> parent = Layer::Create();
  scoped_refptr<Layer> child1 = Layer::Create();
  scoped_refptr<Layer> child2 = Layer::Create();
  scoped_refptr<Layer> grand_child = Layer::Create();
  scoped_refptr<LayerWithForcedDrawsContent> leaf_node1 =
      make_scoped_refptr(new LayerWithForcedDrawsContent());
  scoped_refptr<LayerWithForcedDrawsContent> leaf_node2 =
      make_scoped_refptr(new LayerWithForcedDrawsContent());
  root->AddChild(parent);
  parent->AddChild(child1);
  parent->AddChild(child2);
  child1->AddChild(grand_child);
  child2->AddChild(leaf_node2);
  grand_child->AddChild(leaf_node1);

  scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
  host->SetRootLayer(root);

  child2->SetForceRenderSurface(true);

  SetLayerPropertiesForTesting(root.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(100, 100),
                               true,
                               false);
  SetLayerPropertiesForTesting(parent.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(100, 100),
                               true,
                               false);
  SetLayerPropertiesForTesting(child1.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(100, 100),
                               true,
                               false);
  SetLayerPropertiesForTesting(child2.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(100, 100),
                               true,
                               false);
  SetLayerPropertiesForTesting(grand_child.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(100, 100),
                               true,
                               false);
  SetLayerPropertiesForTesting(leaf_node1.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(100, 100),
                               true,
                               false);
  SetLayerPropertiesForTesting(leaf_node2.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(100, 100),
                               true,
                               false);

  // Case 1: nothing is clipped except the root render surface.
  {
    RenderSurfaceLayerList render_surface_layer_list;
    LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
        root.get(), parent->bounds(), &render_surface_layer_list);
    inputs.can_adjust_raster_scales = true;
    LayerTreeHostCommon::CalculateDrawProperties(&inputs);

    ASSERT_TRUE(root->render_surface());
    ASSERT_TRUE(child2->render_surface());

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

  // Case 2: parent masksToBounds, so the parent, child1, and child2's
  // surface are clipped. But layers that contribute to child2's surface are
  // not clipped explicitly because child2's surface already accounts for
  // that clip.
  {
    RenderSurfaceLayerList render_surface_layer_list;
    parent->SetMasksToBounds(true);
    LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
        root.get(), parent->bounds(), &render_surface_layer_list);
    inputs.can_adjust_raster_scales = true;
    LayerTreeHostCommon::CalculateDrawProperties(&inputs);

    ASSERT_TRUE(root->render_surface());
    ASSERT_TRUE(child2->render_surface());

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

  // Case 3: child2 masksToBounds. The layer and subtree are clipped, and
  // child2's render surface is not clipped.
  {
    RenderSurfaceLayerList render_surface_layer_list;
    parent->SetMasksToBounds(false);
    child2->SetMasksToBounds(true);
    LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
        root.get(), parent->bounds(), &render_surface_layer_list);
    inputs.can_adjust_raster_scales = true;
    LayerTreeHostCommon::CalculateDrawProperties(&inputs);

    ASSERT_TRUE(root->render_surface());
    ASSERT_TRUE(child2->render_surface());

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

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

  const gfx::Transform identity_matrix;
  scoped_refptr<Layer> parent = Layer::Create();
  scoped_refptr<Layer> child = Layer::Create();
  scoped_refptr<Layer> grand_child1 = Layer::Create();
  scoped_refptr<Layer> grand_child2 = Layer::Create();
  scoped_refptr<Layer> grand_child3 = Layer::Create();
  scoped_refptr<Layer> grand_child4 = Layer::Create();

  parent->AddChild(child);
  child->AddChild(grand_child1);
  child->AddChild(grand_child2);
  child->AddChild(grand_child3);
  child->AddChild(grand_child4);

  scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
  host->SetRootLayer(parent);

  SetLayerPropertiesForTesting(parent.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(500, 500),
                               true,
                               false);
  SetLayerPropertiesForTesting(child.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(20, 20),
                               true,
                               false);
  SetLayerPropertiesForTesting(grand_child1.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(5.f, 5.f),
                               gfx::Size(10, 10),
                               true,
                               false);
  SetLayerPropertiesForTesting(grand_child2.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(15.f, 15.f),
                               gfx::Size(10, 10),
                               true,
                               false);
  SetLayerPropertiesForTesting(grand_child3.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(15.f, 15.f),
                               gfx::Size(10, 10),
                               true,
                               false);
  SetLayerPropertiesForTesting(grand_child4.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(45.f, 45.f),
                               gfx::Size(10, 10),
                               true,
                               false);

  child->SetMasksToBounds(true);
  grand_child3->SetMasksToBounds(true);

  // Force everyone to be a render surface.
  child->SetOpacity(0.4f);
  grand_child1->SetOpacity(0.5f);
  grand_child2->SetOpacity(0.5f);
  grand_child3->SetOpacity(0.5f);
  grand_child4->SetOpacity(0.5f);

  RenderSurfaceLayerList render_surface_layer_list;
  LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
      parent.get(), parent->bounds(), &render_surface_layer_list);
  inputs.can_adjust_raster_scales = true;
  LayerTreeHostCommon::CalculateDrawProperties(&inputs);

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

TEST_F(LayerTreeHostCommonTest, ClipRectIsPropagatedCorrectlyToSurfaces) {
  // Verify that render surfaces (and their layers) get the appropriate
  // clip rects when their parent masksToBounds is true.
  //
  // Layers that own render surfaces (at least for now) do not inherit any
  // clipping; instead the surface will enforce the clip for the entire subtree.
  // They may still have a clip rect of their own layer bounds, however, if
  // masksToBounds was true.
  const gfx::Transform identity_matrix;
  scoped_refptr<Layer> parent = Layer::Create();
  scoped_refptr<Layer> child = Layer::Create();
  scoped_refptr<Layer> grand_child1 = Layer::Create();
  scoped_refptr<Layer> grand_child2 = Layer::Create();
  scoped_refptr<Layer> grand_child3 = Layer::Create();
  scoped_refptr<Layer> grand_child4 = Layer::Create();
  scoped_refptr<LayerWithForcedDrawsContent> leaf_node1 =
      make_scoped_refptr(new LayerWithForcedDrawsContent());
  scoped_refptr<LayerWithForcedDrawsContent> leaf_node2 =
      make_scoped_refptr(new LayerWithForcedDrawsContent());
  scoped_refptr<LayerWithForcedDrawsContent> leaf_node3 =
      make_scoped_refptr(new LayerWithForcedDrawsContent());
  scoped_refptr<LayerWithForcedDrawsContent> leaf_node4 =
      make_scoped_refptr(new LayerWithForcedDrawsContent());

  parent->AddChild(child);
  child->AddChild(grand_child1);
  child->AddChild(grand_child2);
  child->AddChild(grand_child3);
  child->AddChild(grand_child4);

  scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
  host->SetRootLayer(parent);

  // the leaf nodes ensure that these grand_children become render surfaces for
  // this test.
  grand_child1->AddChild(leaf_node1);
  grand_child2->AddChild(leaf_node2);
  grand_child3->AddChild(leaf_node3);
  grand_child4->AddChild(leaf_node4);

  SetLayerPropertiesForTesting(parent.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(500, 500),
                               true,
                               false);
  SetLayerPropertiesForTesting(child.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(20, 20),
                               true,
                               false);
  SetLayerPropertiesForTesting(grand_child1.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(5.f, 5.f),
                               gfx::Size(10, 10),
                               true,
                               false);
  SetLayerPropertiesForTesting(grand_child2.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(15.f, 15.f),
                               gfx::Size(10, 10),
                               true,
                               false);
  SetLayerPropertiesForTesting(grand_child3.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(15.f, 15.f),
                               gfx::Size(10, 10),
                               true,
                               false);
  SetLayerPropertiesForTesting(grand_child4.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(45.f, 45.f),
                               gfx::Size(10, 10),
                               true,
                               false);
  SetLayerPropertiesForTesting(leaf_node1.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(10, 10),
                               true,
                               false);
  SetLayerPropertiesForTesting(leaf_node2.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(10, 10),
                               true,
                               false);
  SetLayerPropertiesForTesting(leaf_node3.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(10, 10),
                               true,
                               false);
  SetLayerPropertiesForTesting(leaf_node4.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(10, 10),
                               true,
                               false);

  child->SetMasksToBounds(true);
  grand_child3->SetMasksToBounds(true);
  grand_child4->SetMasksToBounds(true);

  // Force everyone to be a render surface.
  child->SetOpacity(0.4f);
  child->SetForceRenderSurface(true);
  grand_child1->SetOpacity(0.5f);
  grand_child1->SetForceRenderSurface(true);
  grand_child2->SetOpacity(0.5f);
  grand_child2->SetForceRenderSurface(true);
  grand_child3->SetOpacity(0.5f);
  grand_child3->SetForceRenderSurface(true);
  grand_child4->SetOpacity(0.5f);
  grand_child4->SetForceRenderSurface(true);

  RenderSurfaceLayerList render_surface_layer_list;
  LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
      parent.get(), parent->bounds(), &render_surface_layer_list);
  inputs.can_adjust_raster_scales = true;
  LayerTreeHostCommon::CalculateDrawProperties(&inputs);
  ASSERT_TRUE(grand_child1->render_surface());
  ASSERT_TRUE(grand_child2->render_surface());
  ASSERT_TRUE(grand_child3->render_surface());

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

TEST_F(LayerTreeHostCommonTest, AnimationsForRenderSurfaceHierarchy) {
  scoped_refptr<Layer> parent = Layer::Create();
  scoped_refptr<Layer> render_surface1 = Layer::Create();
  scoped_refptr<Layer> render_surface2 = Layer::Create();
  scoped_refptr<Layer> child_of_root = Layer::Create();
  scoped_refptr<Layer> child_of_rs1 = Layer::Create();
  scoped_refptr<Layer> child_of_rs2 = Layer::Create();
  scoped_refptr<Layer> grand_child_of_root = Layer::Create();
  scoped_refptr<LayerWithForcedDrawsContent> grand_child_of_rs1 =
      make_scoped_refptr(new LayerWithForcedDrawsContent());
  scoped_refptr<LayerWithForcedDrawsContent> grand_child_of_rs2 =
      make_scoped_refptr(new LayerWithForcedDrawsContent());
  parent->AddChild(render_surface1);
  parent->AddChild(child_of_root);
  render_surface1->AddChild(child_of_rs1);
  render_surface1->AddChild(render_surface2);
  render_surface2->AddChild(child_of_rs2);
  child_of_root->AddChild(grand_child_of_root);
  child_of_rs1->AddChild(grand_child_of_rs1);
  child_of_rs2->AddChild(grand_child_of_rs2);

  scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
  host->SetRootLayer(parent);

  // Make our render surfaces.
  render_surface1->SetForceRenderSurface(true);
  render_surface2->SetForceRenderSurface(true);

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

  SetLayerPropertiesForTesting(parent.get(),
                               layer_transform,
                               gfx::Point3F(0.25f, 0.f, 0.f),
                               gfx::PointF(2.5f, 0.f),
                               gfx::Size(10, 10),
                               true,
                               false);
  SetLayerPropertiesForTesting(render_surface1.get(),
                               layer_transform,
                               gfx::Point3F(0.25f, 0.f, 0.f),
                               gfx::PointF(2.5f, 0.f),
                               gfx::Size(10, 10),
                               true,
                               false);
  SetLayerPropertiesForTesting(render_surface2.get(),
                               layer_transform,
                               gfx::Point3F(0.25f, 0.f, 0.f),
                               gfx::PointF(2.5f, 0.f),
                               gfx::Size(10, 10),
                               true,
                               false);
  SetLayerPropertiesForTesting(child_of_root.get(),
                               layer_transform,
                               gfx::Point3F(0.25f, 0.f, 0.f),
                               gfx::PointF(2.5f, 0.f),
                               gfx::Size(10, 10),
                               true,
                               false);
  SetLayerPropertiesForTesting(child_of_rs1.get(),
                               layer_transform,
                               gfx::Point3F(0.25f, 0.f, 0.f),
                               gfx::PointF(2.5f, 0.f),
                               gfx::Size(10, 10),
                               true,
                               false);
  SetLayerPropertiesForTesting(child_of_rs2.get(),
                               layer_transform,
                               gfx::Point3F(0.25f, 0.f, 0.f),
                               gfx::PointF(2.5f, 0.f),
                               gfx::Size(10, 10),
                               true,
                               false);
  SetLayerPropertiesForTesting(grand_child_of_root.get(),
                               layer_transform,
                               gfx::Point3F(0.25f, 0.f, 0.f),
                               gfx::PointF(2.5f, 0.f),
                               gfx::Size(10, 10),
                               true,
                               false);
  SetLayerPropertiesForTesting(grand_child_of_rs1.get(),
                               layer_transform,
                               gfx::Point3F(0.25f, 0.f, 0.f),
                               gfx::PointF(2.5f, 0.f),
                               gfx::Size(10, 10),
                               true,
                               false);
  SetLayerPropertiesForTesting(grand_child_of_rs2.get(),
                               layer_transform,
                               gfx::Point3F(0.25f, 0.f, 0.f),
                               gfx::PointF(2.5f, 0.f),
                               gfx::Size(10, 10),
                               true,
                               false);

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

  // Also put an animated opacity on a layer without descendants.
  AddOpacityTransitionToController(
      grand_child_of_root->layer_animation_controller(), 10.0, 1.f, 0.f, false);

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

  // Also put transform animations on grand_child_of_root, and
  // grand_child_of_rs2
  AddAnimatedTransformToController(
      grand_child_of_root->layer_animation_controller(), 10.0, 30, 0);
  AddAnimatedTransformToController(
      grand_child_of_rs2->layer_animation_controller(), 10.0, 30, 0);

  ExecuteCalculateDrawProperties(parent.get());

  // Only layers that are associated with render surfaces should have an actual
  // RenderSurface() value.
  ASSERT_TRUE(parent->render_surface());
  ASSERT_FALSE(child_of_root->render_surface());
  ASSERT_FALSE(grand_child_of_root->render_surface());

  ASSERT_TRUE(render_surface1->render_surface());
  ASSERT_FALSE(child_of_rs1->render_surface());
  ASSERT_FALSE(grand_child_of_rs1->render_surface());

  ASSERT_TRUE(render_surface2->render_surface());
  ASSERT_FALSE(child_of_rs2->render_surface());
  ASSERT_FALSE(grand_child_of_rs2->render_surface());

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

  EXPECT_EQ(render_surface1.get(), render_surface1->render_target());
  EXPECT_EQ(render_surface1.get(), child_of_rs1->render_target());
  EXPECT_EQ(render_surface1.get(), grand_child_of_rs1->render_target());

  EXPECT_EQ(render_surface2.get(), render_surface2->render_target());
  EXPECT_EQ(render_surface2.get(), child_of_rs2->render_target());
  EXPECT_EQ(render_surface2.get(), grand_child_of_rs2->render_target());

  // Verify draw_opacity_is_animating values
  EXPECT_FALSE(parent->draw_opacity_is_animating());
  EXPECT_FALSE(child_of_root->draw_opacity_is_animating());
  EXPECT_TRUE(grand_child_of_root->draw_opacity_is_animating());
  EXPECT_FALSE(render_surface1->draw_opacity_is_animating());
  EXPECT_TRUE(render_surface1->render_surface()->draw_opacity_is_animating());
  EXPECT_FALSE(child_of_rs1->draw_opacity_is_animating());
  EXPECT_FALSE(grand_child_of_rs1->draw_opacity_is_animating());
  EXPECT_FALSE(render_surface2->draw_opacity_is_animating());
  EXPECT_FALSE(render_surface2->render_surface()->draw_opacity_is_animating());
  EXPECT_FALSE(child_of_rs2->draw_opacity_is_animating());
  EXPECT_FALSE(grand_child_of_rs2->draw_opacity_is_animating());

  // Verify draw_transform_is_animating values
  EXPECT_FALSE(parent->draw_transform_is_animating());
  EXPECT_FALSE(child_of_root->draw_transform_is_animating());
  EXPECT_TRUE(grand_child_of_root->draw_transform_is_animating());
  EXPECT_FALSE(render_surface1->draw_transform_is_animating());
  EXPECT_FALSE(render_surface1->render_surface()
                   ->target_surface_transforms_are_animating());
  EXPECT_FALSE(child_of_rs1->draw_transform_is_animating());
  EXPECT_FALSE(grand_child_of_rs1->draw_transform_is_animating());
  EXPECT_FALSE(render_surface2->draw_transform_is_animating());
  EXPECT_TRUE(render_surface2->render_surface()
                  ->target_surface_transforms_are_animating());
  EXPECT_FALSE(child_of_rs2->draw_transform_is_animating());
  EXPECT_TRUE(grand_child_of_rs2->draw_transform_is_animating());

  // Verify screen_space_transform_is_animating values
  EXPECT_FALSE(parent->screen_space_transform_is_animating());
  EXPECT_FALSE(child_of_root->screen_space_transform_is_animating());
  EXPECT_TRUE(grand_child_of_root->screen_space_transform_is_animating());
  EXPECT_FALSE(render_surface1->screen_space_transform_is_animating());
  EXPECT_FALSE(render_surface1->render_surface()
                   ->screen_space_transforms_are_animating());
  EXPECT_FALSE(child_of_rs1->screen_space_transform_is_animating());
  EXPECT_FALSE(grand_child_of_rs1->screen_space_transform_is_animating());
  EXPECT_TRUE(render_surface2->screen_space_transform_is_animating());
  EXPECT_TRUE(render_surface2->render_surface()
                  ->screen_space_transforms_are_animating());
  EXPECT_TRUE(child_of_rs2->screen_space_transform_is_animating());
  EXPECT_TRUE(grand_child_of_rs2->screen_space_transform_is_animating());

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

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

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

TEST_F(LayerTreeHostCommonTest, VisibleRectForIdentityTransform) {
  // Test the calculateVisibleRect() function works correctly for identity
  // transforms.

  gfx::Rect target_surface_rect = gfx::Rect(0, 0, 100, 100);
  gfx::Transform layer_to_surface_transform;

  // Case 1: Layer is contained within the surface.
  gfx::Rect layer_content_rect = gfx::Rect(10, 10, 30, 30);
  gfx::Rect expected = gfx::Rect(10, 10, 30, 30);
  gfx::Rect actual = LayerTreeHostCommon::CalculateVisibleRect(
      target_surface_rect, layer_content_rect, layer_to_surface_transform);
  EXPECT_EQ(expected, actual);

  // Case 2: Layer is outside the surface rect.
  layer_content_rect = gfx::Rect(120, 120, 30, 30);
  actual = LayerTreeHostCommon::CalculateVisibleRect(
      target_surface_rect, layer_content_rect, layer_to_surface_transform);
  EXPECT_TRUE(actual.IsEmpty());

  // Case 3: Layer is partially overlapping the surface rect.
  layer_content_rect = gfx::Rect(80, 80, 30, 30);
  expected = gfx::Rect(80, 80, 20, 20);
  actual = LayerTreeHostCommon::CalculateVisibleRect(
      target_surface_rect, layer_content_rect, layer_to_surface_transform);
  EXPECT_EQ(expected, actual);
}

TEST_F(LayerTreeHostCommonTest, VisibleRectForTranslations) {
  // Test the calculateVisibleRect() function works correctly for scaling
  // transforms.

  gfx::Rect target_surface_rect = gfx::Rect(0, 0, 100, 100);
  gfx::Rect layer_content_rect = gfx::Rect(0, 0, 30, 30);
  gfx::Transform layer_to_surface_transform;

  // Case 1: Layer is contained within the surface.
  layer_to_surface_transform.MakeIdentity();
  layer_to_surface_transform.Translate(10.0, 10.0);
  gfx::Rect expected = gfx::Rect(0, 0, 30, 30);
  gfx::Rect actual = LayerTreeHostCommon::CalculateVisibleRect(
      target_surface_rect, layer_content_rect, layer_to_surface_transform);
  EXPECT_EQ(expected, actual);

  // Case 2: Layer is outside the surface rect.
  layer_to_surface_transform.MakeIdentity();
  layer_to_surface_transform.Translate(120.0, 120.0);
  actual = LayerTreeHostCommon::CalculateVisibleRect(
      target_surface_rect, layer_content_rect, layer_to_surface_transform);
  EXPECT_TRUE(actual.IsEmpty());

  // Case 3: Layer is partially overlapping the surface rect.
  layer_to_surface_transform.MakeIdentity();
  layer_to_surface_transform.Translate(80.0, 80.0);
  expected = gfx::Rect(0, 0, 20, 20);
  actual = LayerTreeHostCommon::CalculateVisibleRect(
      target_surface_rect, layer_content_rect, layer_to_surface_transform);
  EXPECT_EQ(expected, actual);
}

TEST_F(LayerTreeHostCommonTest, VisibleRectFor2DRotations) {
  // Test the calculateVisibleRect() function works correctly for rotations
  // about z-axis (i.e. 2D rotations).  Remember that calculateVisibleRect()
  // should return the g in the layer's space.

  gfx::Rect target_surface_rect = gfx::Rect(0, 0, 100, 100);
  gfx::Rect layer_content_rect = gfx::Rect(0, 0, 30, 30);
  gfx::Transform layer_to_surface_transform;

  // Case 1: Layer is contained within the surface.
  layer_to_surface_transform.MakeIdentity();
  layer_to_surface_transform.Translate(50.0, 50.0);
  layer_to_surface_transform.Rotate(45.0);
  gfx::Rect expected = gfx::Rect(0, 0, 30, 30);
  gfx::Rect actual = LayerTreeHostCommon::CalculateVisibleRect(
      target_surface_rect, layer_content_rect, layer_to_surface_transform);
  EXPECT_EQ(expected, actual);

  // Case 2: Layer is outside the surface rect.
  layer_to_surface_transform.MakeIdentity();
  layer_to_surface_transform.Translate(-50.0, 0.0);
  layer_to_surface_transform.Rotate(45.0);
  actual = LayerTreeHostCommon::CalculateVisibleRect(
      target_surface_rect, layer_content_rect, layer_to_surface_transform);
  EXPECT_TRUE(actual.IsEmpty());

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

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

TEST_F(LayerTreeHostCommonTest, VisibleRectFor3dOrthographicTransform) {
  // Test that the calculateVisibleRect() function works correctly for 3d
  // transforms.

  gfx::Rect target_surface_rect = gfx::Rect(0, 0, 100, 100);
  gfx::Rect layer_content_rect = gfx::Rect(0, 0, 100, 100);
  gfx::Transform layer_to_surface_transform;

  // Case 1: Orthographic projection of a layer rotated about y-axis by 45
  // degrees, should be fully contained in the render surface.
  layer_to_surface_transform.MakeIdentity();
  layer_to_surface_transform.RotateAboutYAxis(45.0);
  gfx::Rect expected = gfx::Rect(0, 0, 100, 100);
  gfx::Rect actual = LayerTreeHostCommon::CalculateVisibleRect(
      target_surface_rect, layer_content_rect, layer_to_surface_transform);
  EXPECT_EQ(expected, actual);

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

TEST_F(LayerTreeHostCommonTest, VisibleRectFor3dPerspectiveTransform) {
  // Test the calculateVisibleRect() function works correctly when the layer has
  // a perspective projection onto the target surface.

  gfx::Rect target_surface_rect = gfx::Rect(0, 0, 100, 100);
  gfx::Rect layer_content_rect = gfx::Rect(-50, -50, 200, 200);
  gfx::Transform layer_to_surface_transform;

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

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

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

  gfx::Rect expected = gfx::Rect(-50, -50, 200, 200);
  gfx::Rect actual = LayerTreeHostCommon::CalculateVisibleRect(
      target_surface_rect, layer_content_rect, layer_to_surface_transform);
  EXPECT_EQ(expected, actual);

  // Case 2: same projection as before, except that the layer is also translated
  // to the side, so that only the right half of the layer should be visible.
  //
  // Explanation of expected result: The perspective ratio is (z distance
  // between layer and camera origin) / (z distance between projection plane and
  // camera origin) == ((-27 - 9) / 9) Then, by similar triangles, if we want to
  // move a layer by translating -50 units in projected surface units (so that
  // only half of it is visible), then we would need to translate by (-36 / 9) *
  // -50 == -200 in the layer's units.
  layer_to_surface_transform.Translate3d(-200.0, 0.0, 0.0);
  expected = gfx::Rect(gfx::Point(50, -50),
                       gfx::Size(100, 200));  // The right half of the layer's
                                              // bounding rect.
  actual = LayerTreeHostCommon::CalculateVisibleRect(
      target_surface_rect, layer_content_rect, layer_to_surface_transform);
  EXPECT_EQ(expected, actual);
}

TEST_F(LayerTreeHostCommonTest,
       VisibleRectFor3dOrthographicIsNotClippedBehindSurface) {
  // There is currently no explicit concept of an orthographic projection plane
  // in our code (nor in the CSS spec to my knowledge). Therefore, layers that
  // are technically behind the surface in an orthographic world should not be
  // clipped when they are flattened to the surface.

  gfx::Rect target_surface_rect = gfx::Rect(0, 0, 100, 100);
  gfx::Rect layer_content_rect = gfx::Rect(0, 0, 100, 100);
  gfx::Transform layer_to_surface_transform;

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

  gfx::Rect expected = gfx::Rect(0, 0, 100, 100);
  gfx::Rect actual = LayerTreeHostCommon::CalculateVisibleRect(
      target_surface_rect, layer_content_rect, layer_to_surface_transform);
  EXPECT_EQ(expected, actual);
}

TEST_F(LayerTreeHostCommonTest, VisibleRectFor3dPerspectiveWhenClippedByW) {
  // Test the calculateVisibleRect() function works correctly when projecting a
  // surface onto a layer, but the layer is partially behind the camera (not
  // just behind the projection plane). In this case, the cartesian coordinates
  // may seem to be valid, but actually they are not. The visible rect needs to
  // be properly clipped by the w = 0 plane in homogeneous coordinates before
  // converting to cartesian coordinates.

  gfx::Rect target_surface_rect = gfx::Rect(-50, -50, 100, 100);
  gfx::Rect layer_content_rect = gfx::Rect(-10, -1, 20, 2);
  gfx::Transform layer_to_surface_transform;

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

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

  int expected_x_position = 0;
  int expected_width = 10;
  gfx::Rect actual = LayerTreeHostCommon::CalculateVisibleRect(
      target_surface_rect, layer_content_rect, layer_to_surface_transform);
  EXPECT_EQ(expected_x_position, actual.x());
  EXPECT_EQ(expected_width, actual.width());
}

TEST_F(LayerTreeHostCommonTest, VisibleRectForPerspectiveUnprojection) {
  // To determine visible rect in layer space, there needs to be an
  // un-projection from surface space to layer space. When the original
  // transform was a perspective projection that was clipped, it returns a rect
  // that encloses the clipped bounds.  Un-projecting this new rect may require
  // clipping again.

  // This sequence of transforms causes one corner of the layer to protrude
  // across the w = 0 plane, and should be clipped.
  gfx::Rect target_surface_rect = gfx::Rect(-50, -50, 100, 100);
  gfx::Rect layer_content_rect = gfx::Rect(-10, -10, 20, 20);
  gfx::Transform layer_to_surface_transform;
  layer_to_surface_transform.MakeIdentity();
  layer_to_surface_transform.ApplyPerspectiveDepth(1.0);
  layer_to_surface_transform.Translate3d(0.0, 0.0, -5.0);
  layer_to_surface_transform.RotateAboutYAxis(45.0);
  layer_to_surface_transform.RotateAboutXAxis(80.0);

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

  // Only the corner of the layer is not visible on the surface because of being
  // clipped. But, the net result of rounding visible region to an axis-aligned
  // rect is that the entire layer should still be considered visible.
  gfx::Rect expected = gfx::Rect(-10, -10, 20, 20);
  gfx::Rect actual = LayerTreeHostCommon::CalculateVisibleRect(
      target_surface_rect, layer_content_rect, layer_to_surface_transform);
  EXPECT_EQ(expected, actual);
}

TEST_F(LayerTreeHostCommonTest, DrawableAndVisibleContentRectsForSimpleLayers) {
  scoped_refptr<Layer> root = Layer::Create();
  scoped_refptr<LayerWithForcedDrawsContent> child1 =
      make_scoped_refptr(new LayerWithForcedDrawsContent());
  scoped_refptr<LayerWithForcedDrawsContent> child2 =
      make_scoped_refptr(new LayerWithForcedDrawsContent());
  scoped_refptr<LayerWithForcedDrawsContent> child3 =
      make_scoped_refptr(new LayerWithForcedDrawsContent());
  root->AddChild(child1);
  root->AddChild(child2);
  root->AddChild(child3);

  scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
  host->SetRootLayer(root);

  gfx::Transform identity_matrix;
  SetLayerPropertiesForTesting(root.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(100, 100),
                               true,
                               false);
  SetLayerPropertiesForTesting(child1.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(50, 50),
                               true,
                               false);
  SetLayerPropertiesForTesting(child2.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(75.f, 75.f),
                               gfx::Size(50, 50),
                               true,
                               false);
  SetLayerPropertiesForTesting(child3.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(125.f, 125.f),
                               gfx::Size(50, 50),
                               true,
                               false);

  ExecuteCalculateDrawProperties(root.get());

  EXPECT_EQ(gfx::Rect(0, 0, 100, 100),
            root->render_surface()->DrawableContentRect());
  EXPECT_EQ(gfx::Rect(0, 0, 100, 100), root->drawable_content_rect());

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

  // layer visible_content_rects are clipped by their target surface.
  EXPECT_EQ(gfx::Rect(0, 0, 50, 50), child1->visible_content_rect());
  EXPECT_EQ(gfx::Rect(0, 0, 25, 25), child2->visible_content_rect());
  EXPECT_TRUE(child3->visible_content_rect().IsEmpty());

  // layer drawable_content_rects are not clipped.
  EXPECT_EQ(gfx::Rect(0, 0, 50, 50), child1->drawable_content_rect());
  EXPECT_EQ(gfx::Rect(75, 75, 50, 50), child2->drawable_content_rect());
  EXPECT_EQ(gfx::Rect(125, 125, 50, 50), child3->drawable_content_rect());
}

TEST_F(LayerTreeHostCommonTest,
       DrawableAndVisibleContentRectsForLayersClippedByLayer) {
  scoped_refptr<Layer> root = Layer::Create();
  scoped_refptr<Layer> child = Layer::Create();
  scoped_refptr<LayerWithForcedDrawsContent> grand_child1 =
      make_scoped_refptr(new LayerWithForcedDrawsContent());
  scoped_refptr<LayerWithForcedDrawsContent> grand_child2 =
      make_scoped_refptr(new LayerWithForcedDrawsContent());
  scoped_refptr<LayerWithForcedDrawsContent> grand_child3 =
      make_scoped_refptr(new LayerWithForcedDrawsContent());
  root->AddChild(child);
  child->AddChild(grand_child1);
  child->AddChild(grand_child2);
  child->AddChild(grand_child3);

  scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
  host->SetRootLayer(root);

  gfx::Transform identity_matrix;
  SetLayerPropertiesForTesting(root.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(100, 100),
                               true,
                               false);
  SetLayerPropertiesForTesting(child.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(100, 100),
                               true,
                               false);
  SetLayerPropertiesForTesting(grand_child1.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(5.f, 5.f),
                               gfx::Size(50, 50),
                               true,
                               false);
  SetLayerPropertiesForTesting(grand_child2.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(75.f, 75.f),
                               gfx::Size(50, 50),
                               true,
                               false);
  SetLayerPropertiesForTesting(grand_child3.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(125.f, 125.f),
                               gfx::Size(50, 50),
                               true,
                               false);

  child->SetMasksToBounds(true);
  ExecuteCalculateDrawProperties(root.get());

  ASSERT_FALSE(child->render_surface());

  EXPECT_EQ(gfx::Rect(0, 0, 100, 100),
            root->render_surface()->DrawableContentRect());
  EXPECT_EQ(gfx::Rect(0, 0, 100, 100), root->drawable_content_rect());

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

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

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

TEST_F(LayerTreeHostCommonTest,
       DrawableAndVisibleContentRectsForLayersInUnclippedRenderSurface) {
  scoped_refptr<Layer> root = Layer::Create();
  scoped_refptr<Layer> render_surface1 = Layer::Create();
  scoped_refptr<LayerWithForcedDrawsContent> child1 =
      make_scoped_refptr(new LayerWithForcedDrawsContent());
  scoped_refptr<LayerWithForcedDrawsContent> child2 =
      make_scoped_refptr(new LayerWithForcedDrawsContent());
  scoped_refptr<LayerWithForcedDrawsContent> child3 =
      make_scoped_refptr(new LayerWithForcedDrawsContent());
  root->AddChild(render_surface1);
  render_surface1->AddChild(child1);
  render_surface1->AddChild(child2);
  render_surface1->AddChild(child3);

  scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
  host->SetRootLayer(root);

  gfx::Transform identity_matrix;
  SetLayerPropertiesForTesting(root.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(100, 100),
                               true,
                               false);
  SetLayerPropertiesForTesting(render_surface1.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(3, 4),
                               true,
                               false);
  SetLayerPropertiesForTesting(child1.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(5.f, 5.f),
                               gfx::Size(50, 50),
                               true,
                               false);
  SetLayerPropertiesForTesting(child2.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(75.f, 75.f),
                               gfx::Size(50, 50),
                               true,
                               false);
  SetLayerPropertiesForTesting(child3.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(125.f, 125.f),
                               gfx::Size(50, 50),
                               true,
                               false);

  render_surface1->SetForceRenderSurface(true);
  ExecuteCalculateDrawProperties(root.get());

  ASSERT_TRUE(render_surface1->render_surface());

  EXPECT_EQ(gfx::Rect(0, 0, 100, 100),
            root->render_surface()->DrawableContentRect());
  EXPECT_EQ(gfx::Rect(0, 0, 100, 100), root->drawable_content_rect());

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

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

  // All layers that draw content into the unclipped surface are also unclipped.
  EXPECT_EQ(gfx::Rect(0, 0, 50, 50), child1->visible_content_rect());
  EXPECT_EQ(gfx::Rect(0, 0, 50, 50), child2->visible_content_rect());
  EXPECT_EQ(gfx::Rect(0, 0, 50, 50), child3->visible_content_rect());

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

TEST_F(LayerTreeHostCommonTest,
       VisibleContentRectsForClippedSurfaceWithEmptyClip) {
  scoped_refptr<Layer> root = Layer::Create();
  scoped_refptr<LayerWithForcedDrawsContent> child1 =
      make_scoped_refptr(new LayerWithForcedDrawsContent());
  scoped_refptr<LayerWithForcedDrawsContent> child2 =
      make_scoped_refptr(new LayerWithForcedDrawsContent());
  scoped_refptr<LayerWithForcedDrawsContent> child3 =
      make_scoped_refptr(new LayerWithForcedDrawsContent());
  root->AddChild(child1);
  root->AddChild(child2);
  root->AddChild(child3);

  scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
  host->SetRootLayer(root);

  gfx::Transform identity_matrix;
  SetLayerPropertiesForTesting(root.get(), identity_matrix, gfx::Point3F(),
                               gfx::PointF(), gfx::Size(100, 100), true, false);
  SetLayerPropertiesForTesting(child1.get(), identity_matrix, gfx::Point3F(),
                               gfx::PointF(5.f, 5.f), gfx::Size(50, 50), true,
                               false);
  SetLayerPropertiesForTesting(child2.get(), identity_matrix, gfx::Point3F(),
                               gfx::PointF(75.f, 75.f), gfx::Size(50, 50), true,
                               false);
  SetLayerPropertiesForTesting(child3.get(), identity_matrix, gfx::Point3F(),
                               gfx::PointF(125.f, 125.f), gfx::Size(50, 50),
                               true, false);

  RenderSurfaceLayerList render_surface_layer_list;
  // Now set the root render surface an empty clip.
  LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
      root.get(), gfx::Size(), &render_surface_layer_list);

  LayerTreeHostCommon::CalculateDrawProperties(&inputs);
  ASSERT_TRUE(root->render_surface());
  EXPECT_FALSE(root->is_clipped());

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

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

TEST_F(LayerTreeHostCommonTest,
       DrawableAndVisibleContentRectsForLayersWithUninvertibleTransform) {
  scoped_refptr<Layer> root = Layer::Create();
  scoped_refptr<LayerWithForcedDrawsContent> child =
      make_scoped_refptr(new LayerWithForcedDrawsContent());
  root->AddChild(child);

  scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
  host->SetRootLayer(root);

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

  SetLayerPropertiesForTesting(root.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(100, 100),
                               true,
                               false);
  SetLayerPropertiesForTesting(child.get(),
                               uninvertible_matrix,
                               gfx::Point3F(),
                               gfx::PointF(5.f, 5.f),
                               gfx::Size(50, 50),
                               true,
                               false);

  ExecuteCalculateDrawProperties(root.get());

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

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

  SetLayerPropertiesForTesting(child.get(),
                               uninvertible_matrix,
                               gfx::Point3F(),
                               gfx::PointF(5.f, 5.f),
                               gfx::Size(50, 50),
                               true,
                               false);

  ExecuteCalculateDrawProperties(root.get());

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

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

  SetLayerPropertiesForTesting(child.get(),
                               uninvertible_matrix,
                               gfx::Point3F(),
                               gfx::PointF(5.f, 5.f),
                               gfx::Size(50, 50),
                               true,
                               false);

  ExecuteCalculateDrawProperties(root.get());

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

TEST_F(LayerTreeHostCommonTest,
       SingularTransformDoesNotPreventClearingDrawProperties) {
  scoped_refptr<Layer> root = Layer::Create();
  scoped_refptr<LayerWithForcedDrawsContent> child =
      make_scoped_refptr(new LayerWithForcedDrawsContent());
  root->AddChild(child);

  scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
  host->SetRootLayer(root);

  gfx::Transform identity_matrix;
  gfx::Transform uninvertible_matrix(0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
  ASSERT_FALSE(uninvertible_matrix.IsInvertible());

  SetLayerPropertiesForTesting(root.get(),
                               uninvertible_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(100, 100),
                               true,
                               false);
  SetLayerPropertiesForTesting(child.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(5.f, 5.f),
                               gfx::Size(50, 50),
                               true,
                               false);

  child->draw_properties().sorted_for_recursion = true;

  TransformOperations start_transform_operations;
  start_transform_operations.AppendScale(1.f, 0.f, 0.f);

  TransformOperations end_transform_operations;
  end_transform_operations.AppendScale(1.f, 1.f, 0.f);

  AddAnimatedTransformToLayer(
      root.get(), 10.0, start_transform_operations, end_transform_operations);

  EXPECT_TRUE(root->TransformIsAnimating());

  ExecuteCalculateDrawProperties(root.get());

  EXPECT_FALSE(child->draw_properties().sorted_for_recursion);
}

TEST_F(LayerTreeHostCommonTest,
       SingularNonAnimatingTransformDoesNotPreventClearingDrawProperties) {
  scoped_refptr<Layer> root = Layer::Create();

  scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
  host->SetRootLayer(root);

  gfx::Transform identity_matrix;
  gfx::Transform uninvertible_matrix(0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
  ASSERT_FALSE(uninvertible_matrix.IsInvertible());

  SetLayerPropertiesForTesting(root.get(),
                               uninvertible_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(100, 100),
                               true,
                               false);

  root->draw_properties().sorted_for_recursion = true;

  EXPECT_FALSE(root->TransformIsAnimating());

  ExecuteCalculateDrawProperties(root.get());

  EXPECT_FALSE(root->draw_properties().sorted_for_recursion);
}

TEST_F(LayerTreeHostCommonTest,
       DrawableAndVisibleContentRectsForLayersInClippedRenderSurface) {
  scoped_refptr<Layer> root = Layer::Create();
  scoped_refptr<Layer> render_surface1 = Layer::Create();
  scoped_refptr<LayerWithForcedDrawsContent> child1 =
      make_scoped_refptr(new LayerWithForcedDrawsContent());
  scoped_refptr<LayerWithForcedDrawsContent> child2 =
      make_scoped_refptr(new LayerWithForcedDrawsContent());
  scoped_refptr<LayerWithForcedDrawsContent> child3 =
      make_scoped_refptr(new LayerWithForcedDrawsContent());
  root->AddChild(render_surface1);
  render_surface1->AddChild(child1);
  render_surface1->AddChild(child2);
  render_surface1->AddChild(child3);

  scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
  host->SetRootLayer(root);

  gfx::Transform identity_matrix;
  SetLayerPropertiesForTesting(root.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(100, 100),
                               true,
                               false);
  SetLayerPropertiesForTesting(render_surface1.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(3, 4),
                               true,
                               false);
  SetLayerPropertiesForTesting(child1.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(5.f, 5.f),
                               gfx::Size(50, 50),
                               true,
                               false);
  SetLayerPropertiesForTesting(child2.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(75.f, 75.f),
                               gfx::Size(50, 50),
                               true,
                               false);
  SetLayerPropertiesForTesting(child3.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(125.f, 125.f),
                               gfx::Size(50, 50),
                               true,
                               false);

  root->SetMasksToBounds(true);
  render_surface1->SetForceRenderSurface(true);
  ExecuteCalculateDrawProperties(root.get());

  ASSERT_TRUE(render_surface1->render_surface());

  EXPECT_EQ(gfx::Rect(0, 0, 100, 100),
            root->render_surface()->DrawableContentRect());
  EXPECT_EQ(gfx::Rect(0, 0, 100, 100), root->drawable_content_rect());

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

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

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

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

TEST_F(LayerTreeHostCommonTest,
       DrawableAndVisibleContentRectsForSurfaceHierarchy) {
  // Check that clipping does not propagate down surfaces.
  scoped_refptr<Layer> root = Layer::Create();
  scoped_refptr<Layer> render_surface1 = Layer::Create();
  scoped_refptr<Layer> render_surface2 = Layer::Create();
  scoped_refptr<LayerWithForcedDrawsContent> child1 =
      make_scoped_refptr(new LayerWithForcedDrawsContent());
  scoped_refptr<LayerWithForcedDrawsContent> child2 =
      make_scoped_refptr(new LayerWithForcedDrawsContent());
  scoped_refptr<LayerWithForcedDrawsContent> child3 =
      make_scoped_refptr(new LayerWithForcedDrawsContent());
  root->AddChild(render_surface1);
  render_surface1->AddChild(render_surface2);
  render_surface2->AddChild(child1);
  render_surface2->AddChild(child2);
  render_surface2->AddChild(child3);

  scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
  host->SetRootLayer(root);

  gfx::Transform identity_matrix;
  SetLayerPropertiesForTesting(root.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(100, 100),
                               true,
                               false);
  SetLayerPropertiesForTesting(render_surface1.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(3, 4),
                               true,
                               false);
  SetLayerPropertiesForTesting(render_surface2.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(7, 13),
                               true,
                               false);
  SetLayerPropertiesForTesting(child1.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(5.f, 5.f),
                               gfx::Size(50, 50),
                               true,
                               false);
  SetLayerPropertiesForTesting(child2.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(75.f, 75.f),
                               gfx::Size(50, 50),
                               true,
                               false);
  SetLayerPropertiesForTesting(child3.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(125.f, 125.f),
                               gfx::Size(50, 50),
                               true,
                               false);

  root->SetMasksToBounds(true);
  render_surface1->SetForceRenderSurface(true);
  render_surface2->SetForceRenderSurface(true);
  ExecuteCalculateDrawProperties(root.get());

  ASSERT_TRUE(render_surface1->render_surface());
  ASSERT_TRUE(render_surface2->render_surface());

  EXPECT_EQ(gfx::Rect(0, 0, 100, 100),
            root->render_surface()->DrawableContentRect());
  EXPECT_EQ(gfx::Rect(0, 0, 100, 100), root->drawable_content_rect());

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

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

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

  // All layers that draw content into render_surface2 think they are unclipped.
  EXPECT_EQ(gfx::Rect(0, 0, 50, 50), child1->visible_content_rect());
  EXPECT_EQ(gfx::Rect(0, 0, 50, 50), child2->visible_content_rect());
  EXPECT_EQ(gfx::Rect(0, 0, 50, 50), child3->visible_content_rect());

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

TEST_F(LayerTreeHostCommonTest,
       DrawableAndVisibleContentRectsWithTransformOnUnclippedSurface) {
  // Layers that have non-axis aligned bounds (due to transforms) have an
  // expanded, axis-aligned DrawableContentRect and visible content rect.

  scoped_refptr<Layer> root = Layer::Create();
  scoped_refptr<Layer> render_surface1 = Layer::Create();
  scoped_refptr<LayerWithForcedDrawsContent> child1 =
      make_scoped_refptr(new LayerWithForcedDrawsContent());
  root->AddChild(render_surface1);
  render_surface1->AddChild(child1);

  scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
  host->SetRootLayer(root);

  gfx::Transform identity_matrix;
  gfx::Transform child_rotation;
  child_rotation.Rotate(45.0);
  SetLayerPropertiesForTesting(root.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(100, 100),
                               true,
                               false);
  SetLayerPropertiesForTesting(render_surface1.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(3, 4),
                               true,
                               false);
  SetLayerPropertiesForTesting(child1.get(),
                               child_rotation,
                               gfx::Point3F(25, 25, 0.f),
                               gfx::PointF(25.f, 25.f),
                               gfx::Size(50, 50),
                               true,
                               false);

  render_surface1->SetForceRenderSurface(true);
  ExecuteCalculateDrawProperties(root.get());

  ASSERT_TRUE(render_surface1->render_surface());

  EXPECT_EQ(gfx::Rect(0, 0, 100, 100),
            root->render_surface()->DrawableContentRect());
  EXPECT_EQ(gfx::Rect(0, 0, 100, 100), root->drawable_content_rect());

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

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

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

TEST_F(LayerTreeHostCommonTest,
       DrawableAndVisibleContentRectsWithTransformOnClippedSurface) {
  // Layers that have non-axis aligned bounds (due to transforms) have an
  // expanded, axis-aligned DrawableContentRect and visible content rect.

  scoped_refptr<Layer> root = Layer::Create();
  scoped_refptr<Layer> render_surface1 = Layer::Create();
  scoped_refptr<LayerWithForcedDrawsContent> child1 =
      make_scoped_refptr(new LayerWithForcedDrawsContent());
  root->AddChild(render_surface1);
  render_surface1->AddChild(child1);

  scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
  host->SetRootLayer(root);

  gfx::Transform identity_matrix;
  gfx::Transform child_rotation;
  child_rotation.Rotate(45.0);
  SetLayerPropertiesForTesting(root.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(50, 50),
                               true,
                               false);
  SetLayerPropertiesForTesting(render_surface1.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(3, 4),
                               true,
                               false);

  SetLayerPropertiesForTesting(child1.get(),
                               child_rotation,
                               gfx::Point3F(25, 25, 0.f),
                               gfx::PointF(25.f, 25.f),
                               gfx::Size(50, 50),
                               true,
                               false);

  root->SetMasksToBounds(true);
  render_surface1->SetForceRenderSurface(true);
  ExecuteCalculateDrawProperties(root.get());

  ASSERT_TRUE(render_surface1->render_surface());

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

  // On the clipped surface, only a quarter  of the child1 is visible, but when
  // rotating it back to  child1's content space, the actual enclosing rect ends
  // up covering the full left half of child1.
  //
  // Given the floating point math, this number is a little bit fuzzy.
  EXPECT_EQ(gfx::Rect(0, 0, 26, 50), child1->visible_content_rect());

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

TEST_F(LayerTreeHostCommonTest, DrawableAndVisibleContentRectsInHighDPI) {
  MockContentLayerClient client;

  scoped_refptr<Layer> root = Layer::Create();
  scoped_refptr<FakePictureLayer> render_surface1 =
      CreateDrawablePictureLayer(&client);
  scoped_refptr<FakePictureLayer> render_surface2 =
      CreateDrawablePictureLayer(&client);
  scoped_refptr<FakePictureLayer> child1 = CreateDrawablePictureLayer(&client);
  scoped_refptr<FakePictureLayer> child2 = CreateDrawablePictureLayer(&client);
  scoped_refptr<FakePictureLayer> child3 = CreateDrawablePictureLayer(&client);
  root->AddChild(render_surface1);
  render_surface1->AddChild(render_surface2);
  render_surface2->AddChild(child1);
  render_surface2->AddChild(child2);
  render_surface2->AddChild(child3);

  scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
  host->SetRootLayer(root);

  gfx::Transform identity_matrix;
  SetLayerPropertiesForTesting(root.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(100, 100),
                               true,
                               false);
  SetLayerPropertiesForTesting(render_surface1.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(5.f, 5.f),
                               gfx::Size(3, 4),
                               true,
                               false);
  SetLayerPropertiesForTesting(render_surface2.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(5.f, 5.f),
                               gfx::Size(7, 13),
                               true,
                               false);
  SetLayerPropertiesForTesting(child1.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(5.f, 5.f),
                               gfx::Size(50, 50),
                               true,
                               false);
  SetLayerPropertiesForTesting(child2.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(75.f, 75.f),
                               gfx::Size(50, 50),
                               true,
                               false);
  SetLayerPropertiesForTesting(child3.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(125.f, 125.f),
                               gfx::Size(50, 50),
                               true,
                               false);

  float device_scale_factor = 2.f;

  root->SetMasksToBounds(true);
  render_surface1->SetForceRenderSurface(true);
  render_surface2->SetForceRenderSurface(true);
  ExecuteCalculateDrawProperties(root.get(), device_scale_factor);

  ASSERT_TRUE(render_surface1->render_surface());
  ASSERT_TRUE(render_surface2->render_surface());

  // drawable_content_rects for all layers and surfaces are scaled by
  // device_scale_factor.
  EXPECT_EQ(gfx::Rect(0, 0, 200, 200),
            root->render_surface()->DrawableContentRect());
  EXPECT_EQ(gfx::Rect(0, 0, 200, 200), root->drawable_content_rect());
  EXPECT_EQ(gfx::Rect(10, 10, 190, 190),
            render_surface1->render_surface()->DrawableContentRect());

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

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

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

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

TEST_F(LayerTreeHostCommonTest, BackFaceCullingWithoutPreserves3d) {
  // Verify the behavior of back-face culling when there are no preserve-3d
  // layers. Note that 3d transforms still apply in this case, but they are
  // "flattened" to each parent layer according to current W3C spec.

  const gfx::Transform identity_matrix;
  scoped_refptr<Layer> parent = Layer::Create();
  scoped_refptr<LayerWithForcedDrawsContent> front_facing_child =
      make_scoped_refptr(new LayerWithForcedDrawsContent());
  scoped_refptr<LayerWithForcedDrawsContent> back_facing_child =
      make_scoped_refptr(new LayerWithForcedDrawsContent());
  scoped_refptr<LayerWithForcedDrawsContent> front_facing_surface =
      make_scoped_refptr(new LayerWithForcedDrawsContent());
  scoped_refptr<LayerWithForcedDrawsContent> back_facing_surface =
      make_scoped_refptr(new LayerWithForcedDrawsContent());
  scoped_refptr<LayerWithForcedDrawsContent>
      front_facing_child_of_front_facing_surface =
          make_scoped_refptr(new LayerWithForcedDrawsContent());
  scoped_refptr<LayerWithForcedDrawsContent>
      back_facing_child_of_front_facing_surface =
          make_scoped_refptr(new LayerWithForcedDrawsContent());
  scoped_refptr<LayerWithForcedDrawsContent>
      front_facing_child_of_back_facing_surface =
          make_scoped_refptr(new LayerWithForcedDrawsContent());
  scoped_refptr<LayerWithForcedDrawsContent>
      back_facing_child_of_back_facing_surface =
          make_scoped_refptr(new LayerWithForcedDrawsContent());

  parent->AddChild(front_facing_child);
  parent->AddChild(back_facing_child);
  parent->AddChild(front_facing_surface);
  parent->AddChild(back_facing_surface);
  front_facing_surface->AddChild(front_facing_child_of_front_facing_surface);
  front_facing_surface->AddChild(back_facing_child_of_front_facing_surface);
  back_facing_surface->AddChild(front_facing_child_of_back_facing_surface);
  back_facing_surface->AddChild(back_facing_child_of_back_facing_surface);

  scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
  host->SetRootLayer(parent);

  // Nothing is double-sided
  front_facing_child->SetDoubleSided(false);
  back_facing_child->SetDoubleSided(false);
  front_facing_surface->SetDoubleSided(false);
  back_facing_surface->SetDoubleSided(false);
  front_facing_child_of_front_facing_surface->SetDoubleSided(false);
  back_facing_child_of_front_facing_surface->SetDoubleSided(false);
  front_facing_child_of_back_facing_surface->SetDoubleSided(false);
  back_facing_child_of_back_facing_surface->SetDoubleSided(false);

  gfx::Transform backface_matrix;
  backface_matrix.Translate(50.0, 50.0);
  backface_matrix.RotateAboutYAxis(180.0);
  backface_matrix.Translate(-50.0, -50.0);

  // Having a descendant and opacity will force these to have render surfaces.
  front_facing_surface->SetOpacity(0.5f);
  back_facing_surface->SetOpacity(0.5f);

  // Nothing preserves 3d. According to current W3C CSS gfx::Transforms spec,
  // these layers should blindly use their own local transforms to determine
  // back-face culling.
  SetLayerPropertiesForTesting(parent.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(100, 100),
                               true,
                               false);
  SetLayerPropertiesForTesting(front_facing_child.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(100, 100),
                               true,
                               false);
  SetLayerPropertiesForTesting(back_facing_child.get(),
                               backface_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(100, 100),
                               true,
                               false);
  SetLayerPropertiesForTesting(front_facing_surface.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(100, 100),
                               true,
                               false);
  SetLayerPropertiesForTesting(back_facing_surface.get(),
                               backface_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(100, 100),
                               true,
                               false);
  SetLayerPropertiesForTesting(front_facing_child_of_front_facing_surface.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(100, 100),
                               true,
                               false);
  SetLayerPropertiesForTesting(back_facing_child_of_front_facing_surface.get(),
                               backface_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(100, 100),
                               true,
                               false);
  SetLayerPropertiesForTesting(front_facing_child_of_back_facing_surface.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(100, 100),
                               true,
                               false);
  SetLayerPropertiesForTesting(back_facing_child_of_back_facing_surface.get(),
                               backface_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(100, 100),
                               true,
                               false);

  RenderSurfaceLayerList render_surface_layer_list;
  LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
      parent.get(), parent->bounds(), &render_surface_layer_list);
  inputs.can_adjust_raster_scales = true;
  LayerTreeHostCommon::CalculateDrawProperties(&inputs);

  // Verify which render surfaces were created.
  EXPECT_FALSE(front_facing_child->render_surface());
  EXPECT_FALSE(back_facing_child->render_surface());
  EXPECT_TRUE(front_facing_surface->render_surface());
  EXPECT_TRUE(back_facing_surface->render_surface());
  EXPECT_FALSE(front_facing_child_of_front_facing_surface->render_surface());
  EXPECT_FALSE(back_facing_child_of_front_facing_surface->render_surface());
  EXPECT_FALSE(front_facing_child_of_back_facing_surface->render_surface());
  EXPECT_FALSE(back_facing_child_of_back_facing_surface->render_surface());

  // Verify the render_surface_layer_list.
  ASSERT_EQ(3u, render_surface_layer_list.size());
  EXPECT_EQ(parent->id(), render_surface_layer_list.at(0)->id());
  EXPECT_EQ(front_facing_surface->id(), render_surface_layer_list.at(1)->id());
  // Even though the back facing surface LAYER gets culled, the other
  // descendants should still be added, so the SURFACE should not be culled.
  EXPECT_EQ(back_facing_surface->id(), render_surface_layer_list.at(2)->id());

  // Verify root surface's layer list.
  ASSERT_EQ(
      3u,
      render_surface_layer_list.at(0)->render_surface()->layer_list().size());
  EXPECT_EQ(front_facing_child->id(),
            render_surface_layer_list.at(0)
                ->render_surface()
                ->layer_list()
                .at(0)
                ->id());
  EXPECT_EQ(front_facing_surface->id(),
            render_surface_layer_list.at(0)
                ->render_surface()
                ->layer_list()
                .at(1)
                ->id());
  EXPECT_EQ(back_facing_surface->id(),
            render_surface_layer_list.at(0)
                ->render_surface()
                ->layer_list()
                .at(2)
                ->id());

  // Verify front_facing_surface's layer list.
  ASSERT_EQ(
      2u,
      render_surface_layer_list.at(1)->render_surface()->layer_list().size());
  EXPECT_EQ(front_facing_surface->id(),
            render_surface_layer_list.at(1)
                ->render_surface()
                ->layer_list()
                .at(0)
                ->id());
  EXPECT_EQ(front_facing_child_of_front_facing_surface->id(),
            render_surface_layer_list.at(1)
                ->render_surface()
                ->layer_list()
                .at(1)
                ->id());

  // Verify back_facing_surface's layer list; its own layer should be culled
  // from the surface list.
  ASSERT_EQ(
      1u,
      render_surface_layer_list.at(2)->render_surface()->layer_list().size());
  EXPECT_EQ(front_facing_child_of_back_facing_surface->id(),
            render_surface_layer_list.at(2)
                ->render_surface()
                ->layer_list()
                .at(0)
                ->id());
}

TEST_F(LayerTreeHostCommonTest, BackFaceCullingWithPreserves3d) {
  // Verify the behavior of back-face culling when preserves-3d transform style
  // is used.

  const gfx::Transform identity_matrix;
  scoped_refptr<Layer> parent = Layer::Create();
  scoped_refptr<LayerWithForcedDrawsContent> front_facing_child =
      make_scoped_refptr(new LayerWithForcedDrawsContent());
  scoped_refptr<LayerWithForcedDrawsContent> back_facing_child =
      make_scoped_refptr(new LayerWithForcedDrawsContent());
  scoped_refptr<LayerWithForcedDrawsContent> front_facing_surface =
      make_scoped_refptr(new LayerWithForcedDrawsContent());
  scoped_refptr<LayerWithForcedDrawsContent> back_facing_surface =
      make_scoped_refptr(new LayerWithForcedDrawsContent());
  scoped_refptr<LayerWithForcedDrawsContent>
  front_facing_child_of_front_facing_surface =
      make_scoped_refptr(new LayerWithForcedDrawsContent());
  scoped_refptr<LayerWithForcedDrawsContent>
  back_facing_child_of_front_facing_surface =
      make_scoped_refptr(new LayerWithForcedDrawsContent());
  scoped_refptr<LayerWithForcedDrawsContent>
  front_facing_child_of_back_facing_surface =
      make_scoped_refptr(new LayerWithForcedDrawsContent());
  scoped_refptr<LayerWithForcedDrawsContent>
  back_facing_child_of_back_facing_surface =
      make_scoped_refptr(new LayerWithForcedDrawsContent());
  scoped_refptr<LayerWithForcedDrawsContent> dummy_replica_layer1 =
      make_scoped_refptr(new LayerWithForcedDrawsContent());
  scoped_refptr<LayerWithForcedDrawsContent> dummy_replica_layer2 =
      make_scoped_refptr(new LayerWithForcedDrawsContent());

  parent->AddChild(front_facing_child);
  parent->AddChild(back_facing_child);
  parent->AddChild(front_facing_surface);
  parent->AddChild(back_facing_surface);
  front_facing_surface->AddChild(front_facing_child_of_front_facing_surface);
  front_facing_surface->AddChild(back_facing_child_of_front_facing_surface);
  back_facing_surface->AddChild(front_facing_child_of_back_facing_surface);
  back_facing_surface->AddChild(back_facing_child_of_back_facing_surface);

  scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
  host->SetRootLayer(parent);

  // Nothing is double-sided
  front_facing_child->SetDoubleSided(false);
  back_facing_child->SetDoubleSided(false);
  front_facing_surface->SetDoubleSided(false);
  back_facing_surface->SetDoubleSided(false);
  front_facing_child_of_front_facing_surface->SetDoubleSided(false);
  back_facing_child_of_front_facing_surface->SetDoubleSided(false);
  front_facing_child_of_back_facing_surface->SetDoubleSided(false);
  back_facing_child_of_back_facing_surface->SetDoubleSided(false);

  gfx::Transform backface_matrix;
  backface_matrix.Translate(50.0, 50.0);
  backface_matrix.RotateAboutYAxis(180.0);
  backface_matrix.Translate(-50.0, -50.0);

  // Opacity will not force creation of render surfaces in this case because of
  // the preserve-3d transform style. Instead, an example of when a surface
  // would be created with preserve-3d is when there is a replica layer.
  front_facing_surface->SetReplicaLayer(dummy_replica_layer1.get());
  back_facing_surface->SetReplicaLayer(dummy_replica_layer2.get());

  // Each surface creates its own new 3d rendering context (as defined by W3C
  // spec).  According to current W3C CSS gfx::Transforms spec, layers in a 3d
  // rendering context should use the transform with respect to that context.
  // This 3d rendering context occurs when (a) parent's transform style is flat
  // and (b) the layer's transform style is preserve-3d.
  SetLayerPropertiesForTesting(parent.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(100, 100),
                               true,
                               false);  // parent transform style is flat.
  SetLayerPropertiesForTesting(front_facing_child.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(100, 100),
                               true,
                               false);
  SetLayerPropertiesForTesting(back_facing_child.get(),
                               backface_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(100, 100),
                               true,
                               false);
  // surface transform style is preserve-3d.
  SetLayerPropertiesForTesting(front_facing_surface.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(100, 100),
                               false,
                               true);
  // surface transform style is preserve-3d.
  SetLayerPropertiesForTesting(back_facing_surface.get(),
                               backface_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(100, 100),
                               false,
                               true);
  SetLayerPropertiesForTesting(front_facing_child_of_front_facing_surface.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(100, 100),
                               true,
                               true);
  SetLayerPropertiesForTesting(back_facing_child_of_front_facing_surface.get(),
                               backface_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(100, 100),
                               true,
                               true);
  SetLayerPropertiesForTesting(front_facing_child_of_back_facing_surface.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(100, 100),
                               true,
                               true);
  SetLayerPropertiesForTesting(back_facing_child_of_back_facing_surface.get(),
                               backface_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(100, 100),
                               true,
                               true);

  RenderSurfaceLayerList render_surface_layer_list;
  LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
      parent.get(), parent->bounds(), &render_surface_layer_list);
  inputs.can_adjust_raster_scales = true;
  LayerTreeHostCommon::CalculateDrawProperties(&inputs);

  // Verify which render surfaces were created and used.
  EXPECT_FALSE(front_facing_child->render_surface());
  EXPECT_FALSE(back_facing_child->render_surface());
  EXPECT_TRUE(front_facing_surface->render_surface());
  EXPECT_NE(back_facing_surface->render_target(), back_facing_surface);
  // We expect that a render_surface was created but not used.
  EXPECT_TRUE(back_facing_surface->render_surface());
  EXPECT_FALSE(front_facing_child_of_front_facing_surface->render_surface());
  EXPECT_FALSE(back_facing_child_of_front_facing_surface->render_surface());
  EXPECT_FALSE(front_facing_child_of_back_facing_surface->render_surface());
  EXPECT_FALSE(back_facing_child_of_back_facing_surface->render_surface());

  // Verify the render_surface_layer_list. The back-facing surface should be
  // culled.
  ASSERT_EQ(2u, render_surface_layer_list.size());
  EXPECT_EQ(parent->id(), render_surface_layer_list.at(0)->id());
  EXPECT_EQ(front_facing_surface->id(), render_surface_layer_list.at(1)->id());

  // Verify root surface's layer list.
  ASSERT_EQ(
      2u,
      render_surface_layer_list.at(0)->render_surface()->layer_list().size());
  EXPECT_EQ(front_facing_child->id(),
            render_surface_layer_list.at(0)
                ->render_surface()->layer_list().at(0)->id());
  EXPECT_EQ(front_facing_surface->id(),
            render_surface_layer_list.at(0)
                ->render_surface()->layer_list().at(1)->id());

  // Verify front_facing_surface's layer list.
  ASSERT_EQ(
      2u,
      render_surface_layer_list.at(1)->render_surface()->layer_list().size());
  EXPECT_EQ(front_facing_surface->id(),
            render_surface_layer_list.at(1)
                ->render_surface()->layer_list().at(0)->id());
  EXPECT_EQ(front_facing_child_of_front_facing_surface->id(),
            render_surface_layer_list.at(1)
                ->render_surface()->layer_list().at(1)->id());
}

TEST_F(LayerTreeHostCommonTest, BackFaceCullingWithAnimatingTransforms) {
  // Verify that layers are appropriately culled when their back face is showing
  // and they are not double sided, while animations are going on.
  //
  // Layers that are animating do not get culled on the main thread, as their
  // transforms should be treated as "unknown" so we can not be sure that their
  // back face is really showing.
  const gfx::Transform identity_matrix;
  scoped_refptr<Layer> parent = Layer::Create();
  scoped_refptr<LayerWithForcedDrawsContent> child =
      make_scoped_refptr(new LayerWithForcedDrawsContent());
  scoped_refptr<LayerWithForcedDrawsContent> animating_surface =
      make_scoped_refptr(new LayerWithForcedDrawsContent());
  scoped_refptr<LayerWithForcedDrawsContent> child_of_animating_surface =
      make_scoped_refptr(new LayerWithForcedDrawsContent());
  scoped_refptr<LayerWithForcedDrawsContent> animating_child =
      make_scoped_refptr(new LayerWithForcedDrawsContent());
  scoped_refptr<LayerWithForcedDrawsContent> child2 =
      make_scoped_refptr(new LayerWithForcedDrawsContent());

  parent->AddChild(child);
  parent->AddChild(animating_surface);
  animating_surface->AddChild(child_of_animating_surface);
  parent->AddChild(animating_child);
  parent->AddChild(child2);

  scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
  host->SetRootLayer(parent);

  // Nothing is double-sided
  child->SetDoubleSided(false);
  child2->SetDoubleSided(false);
  animating_surface->SetDoubleSided(false);
  child_of_animating_surface->SetDoubleSided(false);
  animating_child->SetDoubleSided(false);

  gfx::Transform backface_matrix;
  backface_matrix.Translate(50.0, 50.0);
  backface_matrix.RotateAboutYAxis(180.0);
  backface_matrix.Translate(-50.0, -50.0);

  // Make our render surface.
  animating_surface->SetForceRenderSurface(true);

  // Animate the transform on the render surface.
  AddAnimatedTransformToController(
      animating_surface->layer_animation_controller(), 10.0, 30, 0);
  // This is just an animating layer, not a surface.
  AddAnimatedTransformToController(
      animating_child->layer_animation_controller(), 10.0, 30, 0);

  SetLayerPropertiesForTesting(parent.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(100, 100),
                               true,
                               false);
  SetLayerPropertiesForTesting(child.get(),
                               backface_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(100, 100),
                               true,
                               false);
  SetLayerPropertiesForTesting(animating_surface.get(),
                               backface_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(100, 100),
                               true,
                               false);
  SetLayerPropertiesForTesting(child_of_animating_surface.get(),
                               backface_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(100, 100),
                               true,
                               false);
  SetLayerPropertiesForTesting(animating_child.get(),
                               backface_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(100, 100),
                               true,
                               false);
  SetLayerPropertiesForTesting(child2.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(100, 100),
                               true,
                               false);

  RenderSurfaceLayerList render_surface_layer_list;
  LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
      parent.get(), parent->bounds(), &render_surface_layer_list);
  inputs.can_adjust_raster_scales = true;
  LayerTreeHostCommon::CalculateDrawProperties(&inputs);

  EXPECT_FALSE(child->render_surface());
  EXPECT_TRUE(animating_surface->render_surface());
  EXPECT_FALSE(child_of_animating_surface->render_surface());
  EXPECT_FALSE(animating_child->render_surface());
  EXPECT_FALSE(child2->render_surface());

  // Verify that the animating_child and child_of_animating_surface were not
  // culled, but that child was.
  ASSERT_EQ(2u, render_surface_layer_list.size());
  EXPECT_EQ(parent->id(), render_surface_layer_list.at(0)->id());
  EXPECT_EQ(animating_surface->id(), render_surface_layer_list.at(1)->id());

  // The non-animating child be culled from the layer list for the parent render
  // surface.
  ASSERT_EQ(
      3u,
      render_surface_layer_list.at(0)->render_surface()->layer_list().size());
  EXPECT_EQ(animating_surface->id(),
            render_surface_layer_list.at(0)
                ->render_surface()->layer_list().at(0)->id());
  EXPECT_EQ(animating_child->id(),
            render_surface_layer_list.at(0)
                ->render_surface()->layer_list().at(1)->id());
  EXPECT_EQ(child2->id(),
            render_surface_layer_list.at(0)
                ->render_surface()->layer_list().at(2)->id());

  ASSERT_EQ(
      2u,
      render_surface_layer_list.at(1)->render_surface()->layer_list().size());
  EXPECT_EQ(animating_surface->id(),
            render_surface_layer_list.at(1)
                ->render_surface()->layer_list().at(0)->id());
  EXPECT_EQ(child_of_animating_surface->id(),
            render_surface_layer_list.at(1)
                ->render_surface()->layer_list().at(1)->id());

  EXPECT_FALSE(child2->visible_content_rect().IsEmpty());

  // The animating layers should have a visible content rect that represents the
  // area of the front face that is within the viewport.
  EXPECT_EQ(animating_child->visible_content_rect(),
            gfx::Rect(animating_child->content_bounds()));
  EXPECT_EQ(animating_surface->visible_content_rect(),
            gfx::Rect(animating_surface->content_bounds()));
  // And layers in the subtree of the animating layer should have valid visible
  // content rects also.
  EXPECT_EQ(child_of_animating_surface->visible_content_rect(),
            gfx::Rect(child_of_animating_surface->content_bounds()));
}

TEST_F(LayerTreeHostCommonTest,
     BackFaceCullingWithPreserves3dForFlatteningSurface) {
  // Verify the behavior of back-face culling for a render surface that is
  // created when it flattens its subtree, and its parent has preserves-3d.

  const gfx::Transform identity_matrix;
  scoped_refptr<Layer> parent = Layer::Create();
  scoped_refptr<LayerWithForcedDrawsContent> front_facing_surface =
      make_scoped_refptr(new LayerWithForcedDrawsContent());
  scoped_refptr<LayerWithForcedDrawsContent> back_facing_surface =
      make_scoped_refptr(new LayerWithForcedDrawsContent());
  scoped_refptr<LayerWithForcedDrawsContent> child1 =
      make_scoped_refptr(new LayerWithForcedDrawsContent());
  scoped_refptr<LayerWithForcedDrawsContent> child2 =
      make_scoped_refptr(new LayerWithForcedDrawsContent());

  parent->AddChild(front_facing_surface);
  parent->AddChild(back_facing_surface);
  front_facing_surface->AddChild(child1);
  back_facing_surface->AddChild(child2);

  scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
  host->SetRootLayer(parent);

  // RenderSurfaces are not double-sided
  front_facing_surface->SetDoubleSided(false);
  back_facing_surface->SetDoubleSided(false);

  gfx::Transform backface_matrix;
  backface_matrix.Translate(50.0, 50.0);
  backface_matrix.RotateAboutYAxis(180.0);
  backface_matrix.Translate(-50.0, -50.0);

  SetLayerPropertiesForTesting(parent.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(100, 100),
                               false,
                               true);  // parent transform style is preserve3d.
  SetLayerPropertiesForTesting(front_facing_surface.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(100, 100),
                               true,
                               true);  // surface transform style is flat.
  SetLayerPropertiesForTesting(back_facing_surface.get(),
                               backface_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(100, 100),
                               true,
                               true);  // surface transform style is flat.
  SetLayerPropertiesForTesting(child1.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(100, 100),
                               true,
                               false);
  SetLayerPropertiesForTesting(child2.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(100, 100),
                               true,
                               false);

  front_facing_surface->Set3dSortingContextId(1);
  back_facing_surface->Set3dSortingContextId(1);

  RenderSurfaceLayerList render_surface_layer_list;
  LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
      parent.get(), parent->bounds(), &render_surface_layer_list);
  inputs.can_adjust_raster_scales = true;
  LayerTreeHostCommon::CalculateDrawProperties(&inputs);

  // Verify which render surfaces were created and used.
  EXPECT_TRUE(front_facing_surface->render_surface());

  // We expect the render surface to have been created, but remain unused.
  EXPECT_TRUE(back_facing_surface->render_surface());
  EXPECT_NE(back_facing_surface->render_target(),
            back_facing_surface);  // because it should be culled
  EXPECT_FALSE(child1->render_surface());
  EXPECT_FALSE(child2->render_surface());

  // Verify the render_surface_layer_list. The back-facing surface should be
  // culled.
  ASSERT_EQ(2u, render_surface_layer_list.size());
  EXPECT_EQ(parent->id(), render_surface_layer_list.at(0)->id());
  EXPECT_EQ(front_facing_surface->id(), render_surface_layer_list.at(1)->id());

  // Verify root surface's layer list.
  ASSERT_EQ(
      1u,
      render_surface_layer_list.at(0)->render_surface()->layer_list().size());
  EXPECT_EQ(front_facing_surface->id(),
            render_surface_layer_list.at(0)
                ->render_surface()->layer_list().at(0)->id());

  // Verify front_facing_surface's layer list.
  ASSERT_EQ(
      2u,
      render_surface_layer_list.at(1)->render_surface()->layer_list().size());
  EXPECT_EQ(front_facing_surface->id(),
            render_surface_layer_list.at(1)
                ->render_surface()->layer_list().at(0)->id());
  EXPECT_EQ(child1->id(),
            render_surface_layer_list.at(1)
                ->render_surface()->layer_list().at(1)->id());
}

class NoScaleContentLayer : public ContentLayer {
 public:
  static scoped_refptr<NoScaleContentLayer> Create(ContentLayerClient* client) {
    return make_scoped_refptr(new NoScaleContentLayer(client));
  }

  void CalculateContentsScale(float ideal_contents_scale,
                              float* contents_scale_x,
                              float* contents_scale_y,
                              gfx::Size* content_bounds) override {
    // Skip over the ContentLayer to the base Layer class.
    Layer::CalculateContentsScale(ideal_contents_scale,
                                  contents_scale_x,
                                  contents_scale_y,
                                  content_bounds);
  }

 protected:
  explicit NoScaleContentLayer(ContentLayerClient* client)
      : ContentLayer(client) {}
  ~NoScaleContentLayer() override {}
};

scoped_refptr<NoScaleContentLayer> CreateNoScaleDrawableContentLayer(
    ContentLayerClient* delegate) {
  scoped_refptr<NoScaleContentLayer> to_return =
      NoScaleContentLayer::Create(delegate);
  to_return->SetIsDrawable(true);
  return to_return;
}

TEST_F(LayerTreeHostCommonTest, LayerTransformsInHighDPI) {
  // Verify draw and screen space transforms of layers not in a surface.
  MockContentLayerClient delegate;
  gfx::Transform identity_matrix;

  scoped_refptr<FakePictureLayer> parent =
      CreateDrawablePictureLayer(&delegate);
  SetLayerPropertiesForTesting(parent.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(100, 100),
                               false,
                               true);

  scoped_refptr<FakePictureLayer> child = CreateDrawablePictureLayer(&delegate);
  SetLayerPropertiesForTesting(child.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(2.f, 2.f),
                               gfx::Size(10, 10),
                               false,
                               true);

  scoped_refptr<FakePictureLayer> child_empty =
      CreateDrawablePictureLayer(&delegate);
  SetLayerPropertiesForTesting(child_empty.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(2.f, 2.f),
                               gfx::Size(),
                               false,
                               true);

  parent->AddChild(child);
  parent->AddChild(child_empty);

  scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
  host->SetRootLayer(parent);

  float device_scale_factor = 2.5f;
  float page_scale_factor = 1.f;

  RenderSurfaceLayerList render_surface_layer_list;
  LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
      parent.get(), parent->bounds(), &render_surface_layer_list);
  inputs.device_scale_factor = device_scale_factor;
  inputs.page_scale_factor = page_scale_factor;
  inputs.can_adjust_raster_scales = true;
  LayerTreeHostCommon::CalculateDrawProperties(&inputs);

  EXPECT_IDEAL_SCALE_EQ(device_scale_factor * page_scale_factor, parent);
  EXPECT_IDEAL_SCALE_EQ(device_scale_factor * page_scale_factor, child);
  EXPECT_IDEAL_SCALE_EQ(device_scale_factor * page_scale_factor, child_empty);

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

  // Verify parent transforms
  gfx::Transform expected_parent_transform;
  expected_parent_transform.Scale(device_scale_factor * page_scale_factor,
                                  device_scale_factor * page_scale_factor);
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_parent_transform,
                                  parent->screen_space_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_parent_transform,
                                  parent->draw_transform());

  // Verify results of transformed parent rects
  gfx::RectF parent_content_bounds(parent->content_bounds());

  gfx::RectF parent_draw_rect =
      MathUtil::MapClippedRect(parent->draw_transform(), parent_content_bounds);
  gfx::RectF parent_screen_space_rect = MathUtil::MapClippedRect(
      parent->screen_space_transform(), parent_content_bounds);

  gfx::RectF expected_parent_draw_rect(parent->bounds());
  expected_parent_draw_rect.Scale(device_scale_factor);
  EXPECT_FLOAT_RECT_EQ(expected_parent_draw_rect, parent_draw_rect);
  EXPECT_FLOAT_RECT_EQ(expected_parent_draw_rect, parent_screen_space_rect);

  // Verify child and child_empty transforms. They should match.
  gfx::Transform expected_child_transform;
  expected_child_transform.Scale(device_scale_factor, device_scale_factor);
  expected_child_transform.Translate(child->position().x(),
                                     child->position().y());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
                                  child->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
                                  child->screen_space_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
                                  child_empty->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
                                  child_empty->screen_space_transform());

  // Verify results of transformed child and child_empty rects. They should
  // match.
  gfx::RectF child_content_bounds(child->content_bounds());

  gfx::RectF child_draw_rect =
      MathUtil::MapClippedRect(child->draw_transform(), child_content_bounds);
  gfx::RectF child_screen_space_rect = MathUtil::MapClippedRect(
      child->screen_space_transform(), child_content_bounds);

  gfx::RectF child_empty_draw_rect = MathUtil::MapClippedRect(
      child_empty->draw_transform(), child_content_bounds);
  gfx::RectF child_empty_screen_space_rect = MathUtil::MapClippedRect(
      child_empty->screen_space_transform(), child_content_bounds);

  gfx::RectF expected_child_draw_rect(child->position(), child->bounds());
  expected_child_draw_rect.Scale(device_scale_factor);
  EXPECT_FLOAT_RECT_EQ(expected_child_draw_rect, child_draw_rect);
  EXPECT_FLOAT_RECT_EQ(expected_child_draw_rect, child_screen_space_rect);
  EXPECT_FLOAT_RECT_EQ(expected_child_draw_rect, child_empty_draw_rect);
  EXPECT_FLOAT_RECT_EQ(expected_child_draw_rect, child_empty_screen_space_rect);
}

TEST_F(LayerTreeHostCommonTest, SurfaceLayerTransformsInHighDPI) {
  // Verify draw and screen space transforms of layers in a surface.
  MockContentLayerClient delegate;
  gfx::Transform identity_matrix;

  gfx::Transform perspective_matrix;
  perspective_matrix.ApplyPerspectiveDepth(2.0);

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

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

  scoped_refptr<FakePictureLayer> parent =
      CreateDrawablePictureLayer(&delegate);
  SetLayerPropertiesForTesting(parent.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(100, 100),
                               false,
                               true);

  scoped_refptr<FakePictureLayer> perspective_surface =
      CreateDrawablePictureLayer(&delegate);
  SetLayerPropertiesForTesting(perspective_surface.get(),
                               perspective_matrix * scale_small_matrix,
                               gfx::Point3F(),
                               gfx::PointF(2.f, 2.f),
                               gfx::Size(10, 10),
                               false,
                               true);

  scoped_refptr<FakePictureLayer> scale_surface =
      CreateDrawablePictureLayer(&delegate);
  SetLayerPropertiesForTesting(scale_surface.get(),
                               scale_small_matrix,
                               gfx::Point3F(),
                               gfx::PointF(2.f, 2.f),
                               gfx::Size(10, 10),
                               false,
                               true);

  perspective_surface->SetForceRenderSurface(true);
  scale_surface->SetForceRenderSurface(true);

  parent->AddChild(perspective_surface);
  parent->AddChild(scale_surface);
  root->AddChild(parent);

  scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
  host->SetRootLayer(root);

  float device_scale_factor = 2.5f;
  float page_scale_factor = 3.f;

  RenderSurfaceLayerList render_surface_layer_list;
  LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
      root.get(), parent->bounds(), &render_surface_layer_list);
  inputs.device_scale_factor = device_scale_factor;
  inputs.page_scale_factor = page_scale_factor;
  inputs.page_scale_application_layer = root.get();
  inputs.can_adjust_raster_scales = true;
  LayerTreeHostCommon::CalculateDrawProperties(&inputs);

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

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

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

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

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

// TODO(sohanjg): Remove this test when ContentLayer is removed.
TEST_F(LayerTreeHostCommonTest,
     LayerTransformsInHighDPIAccurateScaleZeroChildPosition) {
  // Verify draw and screen space transforms of layers not in a surface.
  MockContentLayerClient delegate;
  gfx::Transform identity_matrix;

  scoped_refptr<ContentLayer> parent = CreateDrawableContentLayer(&delegate);
  SetLayerPropertiesForTesting(parent.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(133, 133),
                               false,
                               true);

  scoped_refptr<ContentLayer> child = CreateDrawableContentLayer(&delegate);
  SetLayerPropertiesForTesting(child.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(13, 13),
                               false,
                               true);

  scoped_refptr<NoScaleContentLayer> child_no_scale =
      CreateNoScaleDrawableContentLayer(&delegate);
  SetLayerPropertiesForTesting(child_no_scale.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(13, 13),
                               false,
                               true);

  parent->AddChild(child);
  parent->AddChild(child_no_scale);

  scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
  host->SetRootLayer(parent);

  float device_scale_factor = 1.7f;
  float page_scale_factor = 1.f;

  RenderSurfaceLayerList render_surface_layer_list;
  LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
      parent.get(), parent->bounds(), &render_surface_layer_list);
  inputs.device_scale_factor = device_scale_factor;
  inputs.page_scale_factor = page_scale_factor;
  inputs.page_scale_application_layer = parent.get();
  inputs.can_adjust_raster_scales = true;
  LayerTreeHostCommon::CalculateDrawProperties(&inputs);

  EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor, parent);
  EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor, child);
  EXPECT_CONTENTS_SCALE_EQ(1, child_no_scale);

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

  // Verify parent transforms
  gfx::Transform expected_parent_transform;
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_parent_transform,
                                  parent->screen_space_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_parent_transform,
                                  parent->draw_transform());

  // Verify results of transformed parent rects
  gfx::RectF parent_content_bounds(parent->content_bounds());

  gfx::RectF parent_draw_rect =
      MathUtil::MapClippedRect(parent->draw_transform(), parent_content_bounds);
  gfx::RectF parent_screen_space_rect = MathUtil::MapClippedRect(
      parent->screen_space_transform(), parent_content_bounds);

  gfx::RectF expected_parent_draw_rect(parent->bounds());
  expected_parent_draw_rect.Scale(device_scale_factor);
  expected_parent_draw_rect.set_width(ceil(expected_parent_draw_rect.width()));
  expected_parent_draw_rect.set_height(
      ceil(expected_parent_draw_rect.height()));
  EXPECT_FLOAT_RECT_EQ(expected_parent_draw_rect, parent_draw_rect);
  EXPECT_FLOAT_RECT_EQ(expected_parent_draw_rect, parent_screen_space_rect);

  // Verify child transforms
  gfx::Transform expected_child_transform;
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
                                  child->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
                                  child->screen_space_transform());

  // Verify results of transformed child rects
  gfx::RectF child_content_bounds(child->content_bounds());

  gfx::RectF child_draw_rect =
      MathUtil::MapClippedRect(child->draw_transform(), child_content_bounds);
  gfx::RectF child_screen_space_rect = MathUtil::MapClippedRect(
      child->screen_space_transform(), child_content_bounds);

  gfx::RectF expected_child_draw_rect(child->bounds());
  expected_child_draw_rect.Scale(device_scale_factor);
  expected_child_draw_rect.set_width(ceil(expected_child_draw_rect.width()));
  expected_child_draw_rect.set_height(ceil(expected_child_draw_rect.height()));
  EXPECT_FLOAT_RECT_EQ(expected_child_draw_rect, child_draw_rect);
  EXPECT_FLOAT_RECT_EQ(expected_child_draw_rect, child_screen_space_rect);

  // Verify child_no_scale transforms
  gfx::Transform expected_child_no_scale_transform = child->draw_transform();
  // All transforms operate on content rects. The child's content rect
  // incorporates device scale, but the child_no_scale does not; add it here.
  expected_child_no_scale_transform.Scale(device_scale_factor,
                                          device_scale_factor);
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_no_scale_transform,
                                  child_no_scale->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_no_scale_transform,
                                  child_no_scale->screen_space_transform());
}

// TODO(sohanjg): Remove this test when ContentLayer is removed.
TEST_F(LayerTreeHostCommonTest, ContentsScale) {
  MockContentLayerClient delegate;
  gfx::Transform identity_matrix;

  gfx::Transform parent_scale_matrix;
  SkMScalar initial_parent_scale = 1.75;
  parent_scale_matrix.Scale(initial_parent_scale, initial_parent_scale);

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

  scoped_refptr<Layer> root = Layer::Create();
  root->SetBounds(gfx::Size(100, 100));

  scoped_refptr<ContentLayer> parent = CreateDrawableContentLayer(&delegate);
  SetLayerPropertiesForTesting(parent.get(),
                               parent_scale_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(100, 100),
                               false,
                               true);

  scoped_refptr<ContentLayer> child_scale =
      CreateDrawableContentLayer(&delegate);
  SetLayerPropertiesForTesting(child_scale.get(),
                               child_scale_matrix,
                               gfx::Point3F(),
                               gfx::PointF(2.f, 2.f),
                               gfx::Size(10, 10),
                               false,
                               true);

  scoped_refptr<ContentLayer> child_empty =
      CreateDrawableContentLayer(&delegate);
  SetLayerPropertiesForTesting(child_empty.get(),
                               child_scale_matrix,
                               gfx::Point3F(),
                               gfx::PointF(2.f, 2.f),
                               gfx::Size(),
                               false,
                               true);

  scoped_refptr<NoScaleContentLayer> child_no_scale =
      CreateNoScaleDrawableContentLayer(&delegate);
  SetLayerPropertiesForTesting(child_no_scale.get(),
                               child_scale_matrix,
                               gfx::Point3F(),
                               gfx::PointF(12.f, 12.f),
                               gfx::Size(10, 10),
                               false,
                               true);

  root->AddChild(parent);

  parent->AddChild(child_scale);
  parent->AddChild(child_empty);
  parent->AddChild(child_no_scale);

  scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
  host->SetRootLayer(root);

  float device_scale_factor = 2.5f;
  float page_scale_factor = 1.f;

  {
    RenderSurfaceLayerList render_surface_layer_list;
    LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
        root.get(), root->bounds(), &render_surface_layer_list);
    inputs.device_scale_factor = device_scale_factor;
    inputs.page_scale_factor = page_scale_factor;
    inputs.page_scale_application_layer = root.get();
    inputs.can_adjust_raster_scales = true;
    LayerTreeHostCommon::CalculateDrawProperties(&inputs);

    EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor *
                             initial_parent_scale, parent);
    EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor *
                             initial_parent_scale * initial_child_scale,
                             child_scale);
    EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor *
                             initial_parent_scale * initial_child_scale,
                             child_empty);
    EXPECT_CONTENTS_SCALE_EQ(1, child_no_scale);

    // The parent is scaled up and shouldn't need to scale during draw. The
    // child that can scale its contents should also not need to scale during
    // draw. This shouldn't change if the child has empty bounds. The other
    // children should.
    EXPECT_FLOAT_EQ(1.0, parent->draw_transform().matrix().get(0, 0));
    EXPECT_FLOAT_EQ(1.0, parent->draw_transform().matrix().get(1, 1));
    EXPECT_FLOAT_EQ(1.0, child_scale->draw_transform().matrix().get(0, 0));
    EXPECT_FLOAT_EQ(1.0, child_scale->draw_transform().matrix().get(1, 1));
    EXPECT_FLOAT_EQ(1.0, child_empty->draw_transform().matrix().get(0, 0));
    EXPECT_FLOAT_EQ(1.0, child_empty->draw_transform().matrix().get(1, 1));
    EXPECT_FLOAT_EQ(device_scale_factor * page_scale_factor *
                        initial_parent_scale * initial_child_scale,
                    child_no_scale->draw_transform().matrix().get(0, 0));
    EXPECT_FLOAT_EQ(device_scale_factor * page_scale_factor *
                        initial_parent_scale * initial_child_scale,
                    child_no_scale->draw_transform().matrix().get(1, 1));
  }

  // If the device_scale_factor or page_scale_factor changes, then it should be
  // updated using the initial transform as the raster scale.
  device_scale_factor = 2.25f;
  page_scale_factor = 1.25f;

  {
    RenderSurfaceLayerList render_surface_layer_list;
    LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
        root.get(), root->bounds(), &render_surface_layer_list);
    inputs.device_scale_factor = device_scale_factor;
    inputs.page_scale_factor = page_scale_factor;
    inputs.page_scale_application_layer = root.get();
    inputs.can_adjust_raster_scales = true;
    LayerTreeHostCommon::CalculateDrawProperties(&inputs);

    EXPECT_CONTENTS_SCALE_EQ(
        device_scale_factor * page_scale_factor * initial_parent_scale, parent);
    EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor *
                                 initial_parent_scale * initial_child_scale,
                             child_scale);
    EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor *
                             initial_parent_scale * initial_child_scale,
                             child_empty);
    EXPECT_CONTENTS_SCALE_EQ(1, child_no_scale);
  }

  // If the transform changes, we expect the raster scale to be reset to 1.0.
  SkMScalar second_child_scale = 1.75;
  child_scale_matrix.Scale(second_child_scale / initial_child_scale,
                           second_child_scale / initial_child_scale);
  child_scale->SetTransform(child_scale_matrix);
  child_empty->SetTransform(child_scale_matrix);

  {
    RenderSurfaceLayerList render_surface_layer_list;
    LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
        root.get(), root->bounds(), &render_surface_layer_list);
    inputs.device_scale_factor = device_scale_factor;
    inputs.page_scale_factor = page_scale_factor;
    inputs.page_scale_application_layer = root.get();
    inputs.can_adjust_raster_scales = true;
    LayerTreeHostCommon::CalculateDrawProperties(&inputs);

    EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor *
                             initial_parent_scale,
                             parent);
    EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor,
                             child_scale);
    EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor,
                             child_empty);
    EXPECT_CONTENTS_SCALE_EQ(1, child_no_scale);
  }

  // If the device_scale_factor or page_scale_factor changes, then it should be
  // updated, but still using 1.0 as the raster scale.
  device_scale_factor = 2.75f;
  page_scale_factor = 1.75f;

  {
    RenderSurfaceLayerList render_surface_layer_list;
    LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
        root.get(), root->bounds(), &render_surface_layer_list);
    inputs.device_scale_factor = device_scale_factor;
    inputs.page_scale_factor = page_scale_factor;
    inputs.page_scale_application_layer = root.get();
    inputs.can_adjust_raster_scales = true;
    LayerTreeHostCommon::CalculateDrawProperties(&inputs);

    EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor *
                             initial_parent_scale,
                             parent);
    EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor,
                             child_scale);
    EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor,
                             child_empty);
    EXPECT_CONTENTS_SCALE_EQ(1, child_no_scale);
  }
}

// TODO(sohanjg): Remove this test when ContentLayer is removed.
TEST_F(LayerTreeHostCommonTest,
       ContentsScale_LayerTransformsDontAffectContentsScale) {
  MockContentLayerClient delegate;
  gfx::Transform identity_matrix;

  gfx::Transform parent_scale_matrix;
  SkMScalar initial_parent_scale = 1.75;
  parent_scale_matrix.Scale(initial_parent_scale, initial_parent_scale);

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

  scoped_refptr<Layer> root = Layer::Create();
  root->SetBounds(gfx::Size(100, 100));

  scoped_refptr<ContentLayer> parent = CreateDrawableContentLayer(&delegate);
  SetLayerPropertiesForTesting(parent.get(),
                               parent_scale_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(100, 100),
                               false,
                               true);

  scoped_refptr<ContentLayer> child_scale =
      CreateDrawableContentLayer(&delegate);
  SetLayerPropertiesForTesting(child_scale.get(),
                               child_scale_matrix,
                               gfx::Point3F(),
                               gfx::PointF(2.f, 2.f),
                               gfx::Size(10, 10),
                               false,
                               true);

  scoped_refptr<ContentLayer> child_empty =
      CreateDrawableContentLayer(&delegate);
  SetLayerPropertiesForTesting(child_empty.get(),
                               child_scale_matrix,
                               gfx::Point3F(),
                               gfx::PointF(2.f, 2.f),
                               gfx::Size(),
                               false,
                               true);

  scoped_refptr<NoScaleContentLayer> child_no_scale =
      CreateNoScaleDrawableContentLayer(&delegate);
  SetLayerPropertiesForTesting(child_no_scale.get(),
                               child_scale_matrix,
                               gfx::Point3F(),
                               gfx::PointF(12.f, 12.f),
                               gfx::Size(10, 10),
                               false,
                               true);

  root->AddChild(parent);

  parent->AddChild(child_scale);
  parent->AddChild(child_empty);
  parent->AddChild(child_no_scale);

  scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
  host->SetRootLayer(root);

  RenderSurfaceLayerList render_surface_layer_list;

  float device_scale_factor = 2.5f;
  float page_scale_factor = 1.f;

  LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
      root.get(), root->bounds(), &render_surface_layer_list);
  inputs.device_scale_factor = device_scale_factor;
  inputs.page_scale_factor = page_scale_factor;
  inputs.page_scale_application_layer = root.get(),
  LayerTreeHostCommon::CalculateDrawProperties(&inputs);

  EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor, parent);
  EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor,
                           child_scale);
  EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor,
                           child_empty);
  EXPECT_CONTENTS_SCALE_EQ(1, child_no_scale);

  // Since the transform scale does not affect contents scale, it should affect
  // the draw transform instead.
  EXPECT_FLOAT_EQ(initial_parent_scale,
                  parent->draw_transform().matrix().get(0, 0));
  EXPECT_FLOAT_EQ(initial_parent_scale,
                  parent->draw_transform().matrix().get(1, 1));
  EXPECT_FLOAT_EQ(initial_parent_scale * initial_child_scale,
                  child_scale->draw_transform().matrix().get(0, 0));
  EXPECT_FLOAT_EQ(initial_parent_scale * initial_child_scale,
                  child_scale->draw_transform().matrix().get(1, 1));
  EXPECT_FLOAT_EQ(initial_parent_scale * initial_child_scale,
                  child_empty->draw_transform().matrix().get(0, 0));
  EXPECT_FLOAT_EQ(initial_parent_scale * initial_child_scale,
                  child_empty->draw_transform().matrix().get(1, 1));
  EXPECT_FLOAT_EQ(device_scale_factor * page_scale_factor *
                      initial_parent_scale * initial_child_scale,
                  child_no_scale->draw_transform().matrix().get(0, 0));
  EXPECT_FLOAT_EQ(device_scale_factor * page_scale_factor *
                      initial_parent_scale * initial_child_scale,
                  child_no_scale->draw_transform().matrix().get(1, 1));
}

TEST_F(LayerTreeHostCommonTest, SmallIdealScale) {
  MockContentLayerClient delegate;
  gfx::Transform identity_matrix;

  gfx::Transform parent_scale_matrix;
  SkMScalar initial_parent_scale = 1.75;
  parent_scale_matrix.Scale(initial_parent_scale, initial_parent_scale);

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

  scoped_refptr<Layer> root = Layer::Create();
  root->SetBounds(gfx::Size(100, 100));

  scoped_refptr<FakePictureLayer> parent =
      CreateDrawablePictureLayer(&delegate);
  SetLayerPropertiesForTesting(parent.get(),
                               parent_scale_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(100, 100),
                               false,
                               true);

  scoped_refptr<FakePictureLayer> child_scale =
      CreateDrawablePictureLayer(&delegate);
  SetLayerPropertiesForTesting(child_scale.get(),
                               child_scale_matrix,
                               gfx::Point3F(),
                               gfx::PointF(2.f, 2.f),
                               gfx::Size(10, 10),
                               false,
                               true);

  root->AddChild(parent);

  parent->AddChild(child_scale);

  scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
  host->SetRootLayer(root);

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

  {
    RenderSurfaceLayerList render_surface_layer_list;
    LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
        root.get(), root->bounds(), &render_surface_layer_list);
    inputs.device_scale_factor = device_scale_factor;
    inputs.page_scale_factor = page_scale_factor;
    inputs.page_scale_application_layer = root.get();
    inputs.can_adjust_raster_scales = true;
    LayerTreeHostCommon::CalculateDrawProperties(&inputs);

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

    expected_ideal_scale = device_scale_factor * page_scale_factor *
                           initial_parent_scale * initial_child_scale;
    EXPECT_LT(expected_ideal_scale, 1.f);
    EXPECT_IDEAL_SCALE_EQ(expected_ideal_scale, child_scale);
  }
}

TEST_F(LayerTreeHostCommonTest, ContentsScaleForSurfaces) {
  MockContentLayerClient delegate;
  gfx::Transform identity_matrix;

  gfx::Transform parent_scale_matrix;
  SkMScalar initial_parent_scale = 2.0;
  parent_scale_matrix.Scale(initial_parent_scale, initial_parent_scale);

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

  scoped_refptr<Layer> root = Layer::Create();
  root->SetBounds(gfx::Size(100, 100));

  scoped_refptr<ContentLayer> parent = CreateDrawableContentLayer(&delegate);
  SetLayerPropertiesForTesting(parent.get(),
                               parent_scale_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(100, 100),
                               false,
                               true);

  scoped_refptr<ContentLayer> surface_scale =
      CreateDrawableContentLayer(&delegate);
  SetLayerPropertiesForTesting(surface_scale.get(),
                               child_scale_matrix,
                               gfx::Point3F(),
                               gfx::PointF(2.f, 2.f),
                               gfx::Size(10, 10),
                               false,
                               true);

  scoped_refptr<ContentLayer> surface_scale_child_scale =
      CreateDrawableContentLayer(&delegate);
  SetLayerPropertiesForTesting(surface_scale_child_scale.get(),
                               child_scale_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(10, 10),
                               false,
                               true);

  scoped_refptr<NoScaleContentLayer> surface_scale_child_no_scale =
      CreateNoScaleDrawableContentLayer(&delegate);
  SetLayerPropertiesForTesting(surface_scale_child_no_scale.get(),
                               child_scale_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(10, 10),
                               false,
                               true);

  scoped_refptr<NoScaleContentLayer> surface_no_scale =
      CreateNoScaleDrawableContentLayer(&delegate);
  SetLayerPropertiesForTesting(surface_no_scale.get(),
                               child_scale_matrix,
                               gfx::Point3F(),
                               gfx::PointF(12.f, 12.f),
                               gfx::Size(10, 10),
                               false,
                               true);

  scoped_refptr<ContentLayer> surface_no_scale_child_scale =
      CreateDrawableContentLayer(&delegate);
  SetLayerPropertiesForTesting(surface_no_scale_child_scale.get(),
                               child_scale_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(10, 10),
                               false,
                               true);

  scoped_refptr<NoScaleContentLayer> surface_no_scale_child_no_scale =
      CreateNoScaleDrawableContentLayer(&delegate);
  SetLayerPropertiesForTesting(surface_no_scale_child_no_scale.get(),
                               child_scale_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(10, 10),
                               false,
                               true);

  root->AddChild(parent);

  parent->AddChild(surface_scale);
  parent->AddChild(surface_no_scale);

  surface_scale->SetForceRenderSurface(true);
  surface_scale->AddChild(surface_scale_child_scale);
  surface_scale->AddChild(surface_scale_child_no_scale);

  surface_no_scale->SetForceRenderSurface(true);
  surface_no_scale->AddChild(surface_no_scale_child_scale);
  surface_no_scale->AddChild(surface_no_scale_child_no_scale);

  scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
  host->SetRootLayer(root);

  SkMScalar device_scale_factor = 5;
  SkMScalar page_scale_factor = 7;

  RenderSurfaceLayerList render_surface_layer_list;
  LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
      root.get(), root->bounds(), &render_surface_layer_list);
  inputs.device_scale_factor = device_scale_factor;
  inputs.page_scale_factor = page_scale_factor;
  inputs.page_scale_application_layer = root.get();
  inputs.can_adjust_raster_scales = true;
  LayerTreeHostCommon::CalculateDrawProperties(&inputs);

  EXPECT_CONTENTS_SCALE_EQ(
      device_scale_factor * page_scale_factor * initial_parent_scale, parent);
  EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor *
                               initial_parent_scale * initial_child_scale,
                           surface_scale);
  EXPECT_CONTENTS_SCALE_EQ(1, surface_no_scale);
  EXPECT_CONTENTS_SCALE_EQ(
      device_scale_factor * page_scale_factor * initial_parent_scale *
      initial_child_scale * initial_child_scale,
      surface_scale_child_scale);
  EXPECT_CONTENTS_SCALE_EQ(1, surface_scale_child_no_scale);
  EXPECT_CONTENTS_SCALE_EQ(
      device_scale_factor * page_scale_factor * initial_parent_scale *
      initial_child_scale * initial_child_scale,
      surface_no_scale_child_scale);
  EXPECT_CONTENTS_SCALE_EQ(1, surface_no_scale_child_no_scale);

  // The parent is scaled up and shouldn't need to scale during draw.
  EXPECT_FLOAT_EQ(1.0, parent->draw_transform().matrix().get(0, 0));
  EXPECT_FLOAT_EQ(1.0, parent->draw_transform().matrix().get(1, 1));

  // RenderSurfaces should always be 1:1 with their target.
  EXPECT_FLOAT_EQ(
      1.0,
      surface_scale->render_surface()->draw_transform().matrix().get(0, 0));
  EXPECT_FLOAT_EQ(
      1.0,
      surface_scale->render_surface()->draw_transform().matrix().get(1, 1));

  // The surface_scale can apply contents scale so the layer shouldn't need to
  // scale during draw.
  EXPECT_FLOAT_EQ(1.0, surface_scale->draw_transform().matrix().get(0, 0));
  EXPECT_FLOAT_EQ(1.0, surface_scale->draw_transform().matrix().get(1, 1));

  // The surface_scale_child_scale can apply contents scale so it shouldn't need
  // to scale during draw.
  EXPECT_FLOAT_EQ(
      1.0, surface_scale_child_scale->draw_transform().matrix().get(0, 0));
  EXPECT_FLOAT_EQ(
      1.0, surface_scale_child_scale->draw_transform().matrix().get(1, 1));

  // The surface_scale_child_no_scale can not apply contents scale, so it needs
  // to be scaled during draw.
  EXPECT_FLOAT_EQ(
      device_scale_factor * page_scale_factor * initial_parent_scale *
          initial_child_scale * initial_child_scale,
      surface_scale_child_no_scale->draw_transform().matrix().get(0, 0));
  EXPECT_FLOAT_EQ(
      device_scale_factor * page_scale_factor * initial_parent_scale *
          initial_child_scale * initial_child_scale,
      surface_scale_child_no_scale->draw_transform().matrix().get(1, 1));

  // RenderSurfaces should always be 1:1 with their target.
  EXPECT_FLOAT_EQ(
      1.0,
      surface_no_scale->render_surface()->draw_transform().matrix().get(0, 0));
  EXPECT_FLOAT_EQ(
      1.0,
      surface_no_scale->render_surface()->draw_transform().matrix().get(1, 1));

  // The surface_no_scale layer can not apply contents scale, so it needs to be
  // scaled during draw.
  EXPECT_FLOAT_EQ(device_scale_factor * page_scale_factor *
                      initial_parent_scale * initial_child_scale,
                  surface_no_scale->draw_transform().matrix().get(0, 0));
  EXPECT_FLOAT_EQ(device_scale_factor * page_scale_factor *
                      initial_parent_scale * initial_child_scale,
                  surface_no_scale->draw_transform().matrix().get(1, 1));

  // The surface_scale_child_scale can apply contents scale so it shouldn't need
  // to scale during draw.
  EXPECT_FLOAT_EQ(
      1.0, surface_no_scale_child_scale->draw_transform().matrix().get(0, 0));
  EXPECT_FLOAT_EQ(
      1.0, surface_no_scale_child_scale->draw_transform().matrix().get(1, 1));

  // The surface_scale_child_no_scale can not apply contents scale, so it needs
  // to be scaled during draw.
  EXPECT_FLOAT_EQ(
      device_scale_factor * page_scale_factor * initial_parent_scale *
          initial_child_scale * initial_child_scale,
      surface_no_scale_child_no_scale->draw_transform().matrix().get(0, 0));
  EXPECT_FLOAT_EQ(
      device_scale_factor * page_scale_factor * initial_parent_scale *
          initial_child_scale * initial_child_scale,
      surface_no_scale_child_no_scale->draw_transform().matrix().get(1, 1));
}

// TODO(sohanjg): Remove this test when ContentLayer is removed.
TEST_F(LayerTreeHostCommonTest,
       ContentsScaleForSurfaces_LayerTransformsDontAffectContentsScale) {
  MockContentLayerClient delegate;
  gfx::Transform identity_matrix;

  gfx::Transform parent_scale_matrix;
  SkMScalar initial_parent_scale = 2.0;
  parent_scale_matrix.Scale(initial_parent_scale, initial_parent_scale);

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

  scoped_refptr<Layer> root = Layer::Create();
  root->SetBounds(gfx::Size(100, 100));

  scoped_refptr<ContentLayer> parent = CreateDrawableContentLayer(&delegate);
  SetLayerPropertiesForTesting(parent.get(),
                               parent_scale_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(100, 100),
                               false,
                               true);

  scoped_refptr<ContentLayer> surface_scale =
      CreateDrawableContentLayer(&delegate);
  SetLayerPropertiesForTesting(surface_scale.get(),
                               child_scale_matrix,
                               gfx::Point3F(),
                               gfx::PointF(2.f, 2.f),
                               gfx::Size(10, 10),
                               false,
                               true);

  scoped_refptr<ContentLayer> surface_scale_child_scale =
      CreateDrawableContentLayer(&delegate);
  SetLayerPropertiesForTesting(surface_scale_child_scale.get(),
                               child_scale_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(10, 10),
                               false,
                               true);

  scoped_refptr<NoScaleContentLayer> surface_scale_child_no_scale =
      CreateNoScaleDrawableContentLayer(&delegate);
  SetLayerPropertiesForTesting(surface_scale_child_no_scale.get(),
                               child_scale_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(10, 10),
                               false,
                               true);

  scoped_refptr<NoScaleContentLayer> surface_no_scale =
      CreateNoScaleDrawableContentLayer(&delegate);
  SetLayerPropertiesForTesting(surface_no_scale.get(),
                               child_scale_matrix,
                               gfx::Point3F(),
                               gfx::PointF(12.f, 12.f),
                               gfx::Size(10, 10),
                               false,
                               true);

  scoped_refptr<ContentLayer> surface_no_scale_child_scale =
      CreateDrawableContentLayer(&delegate);
  SetLayerPropertiesForTesting(surface_no_scale_child_scale.get(),
                               child_scale_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(10, 10),
                               false,
                               true);

  scoped_refptr<NoScaleContentLayer> surface_no_scale_child_no_scale =
      CreateNoScaleDrawableContentLayer(&delegate);
  SetLayerPropertiesForTesting(surface_no_scale_child_no_scale.get(),
                               child_scale_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(10, 10),
                               false,
                               true);

  root->AddChild(parent);

  parent->AddChild(surface_scale);
  parent->AddChild(surface_no_scale);

  surface_scale->SetForceRenderSurface(true);
  surface_scale->AddChild(surface_scale_child_scale);
  surface_scale->AddChild(surface_scale_child_no_scale);

  surface_no_scale->SetForceRenderSurface(true);
  surface_no_scale->AddChild(surface_no_scale_child_scale);
  surface_no_scale->AddChild(surface_no_scale_child_no_scale);

  scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
  host->SetRootLayer(root);

  RenderSurfaceLayerList render_surface_layer_list;

  SkMScalar device_scale_factor = 5.0;
  SkMScalar page_scale_factor = 7.0;
  LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
      root.get(), root->bounds(), &render_surface_layer_list);
  inputs.device_scale_factor = device_scale_factor;
  inputs.page_scale_factor = page_scale_factor;
  inputs.page_scale_application_layer = root.get();
  LayerTreeHostCommon::CalculateDrawProperties(&inputs);

  EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor,
                           parent);
  EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor,
                           surface_scale);
  EXPECT_CONTENTS_SCALE_EQ(1.f, surface_no_scale);
  EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor,
                           surface_scale_child_scale);
  EXPECT_CONTENTS_SCALE_EQ(1.f, surface_scale_child_no_scale);
  EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor,
                           surface_no_scale_child_scale);
  EXPECT_CONTENTS_SCALE_EQ(1.f, surface_no_scale_child_no_scale);

  // The parent is scaled up during draw, since its contents are not scaled by
  // the transform hierarchy.
  EXPECT_FLOAT_EQ(initial_parent_scale,
                  parent->draw_transform().matrix().get(0, 0));
  EXPECT_FLOAT_EQ(initial_parent_scale,
                  parent->draw_transform().matrix().get(1, 1));

  // The child surface is scaled up during draw since its subtree is not scaled
  // by the transform hierarchy.
  EXPECT_FLOAT_EQ(
      initial_parent_scale * initial_child_scale,
      surface_scale->render_surface()->draw_transform().matrix().get(0, 0));
  EXPECT_FLOAT_EQ(
      initial_parent_scale * initial_child_scale,
      surface_scale->render_surface()->draw_transform().matrix().get(1, 1));

  // The surface_scale's RenderSurface is scaled during draw, so the layer does
  // not need to be scaled when drawing into its surface.
  EXPECT_FLOAT_EQ(1.0, surface_scale->draw_transform().matrix().get(0, 0));
  EXPECT_FLOAT_EQ(1.0, surface_scale->draw_transform().matrix().get(1, 1));

  // The surface_scale_child_scale is scaled when drawing into its surface,
  // since its content bounds are not scaled by the transform hierarchy.
  EXPECT_FLOAT_EQ(
      initial_child_scale,
      surface_scale_child_scale->draw_transform().matrix().get(0, 0));
  EXPECT_FLOAT_EQ(
      initial_child_scale,
      surface_scale_child_scale->draw_transform().matrix().get(1, 1));

  // The surface_scale_child_no_scale has a fixed contents scale of 1, so it
  // needs to be scaled by the device and page scale factors, along with the
  // transform hierarchy.
  EXPECT_FLOAT_EQ(
      device_scale_factor * page_scale_factor * initial_child_scale,
      surface_scale_child_no_scale->draw_transform().matrix().get(0, 0));
  EXPECT_FLOAT_EQ(
      device_scale_factor * page_scale_factor * initial_child_scale,
      surface_scale_child_no_scale->draw_transform().matrix().get(1, 1));

  // The child surface is scaled up during draw since its subtree is not scaled
  // by the transform hierarchy.
  EXPECT_FLOAT_EQ(
      initial_parent_scale * initial_child_scale,
      surface_no_scale->render_surface()->draw_transform().matrix().get(0, 0));
  EXPECT_FLOAT_EQ(
      initial_parent_scale * initial_child_scale,
      surface_no_scale->render_surface()->draw_transform().matrix().get(1, 1));

  // The surface_no_scale layer has a fixed contents scale of 1, so it needs to
  // be scaled by the device and page scale factors. Its surface is already
  // scaled by the transform hierarchy so those don't need to scale the layer's
  // drawing.
  EXPECT_FLOAT_EQ(device_scale_factor * page_scale_factor,
                  surface_no_scale->draw_transform().matrix().get(0, 0));
  EXPECT_FLOAT_EQ(device_scale_factor * page_scale_factor,
                  surface_no_scale->draw_transform().matrix().get(1, 1));

  // The surface_no_scale_child_scale has its contents scaled by the page and
  // device scale factors, but needs to be scaled by the transform hierarchy
  // when drawing.
  EXPECT_FLOAT_EQ(
      initial_child_scale,
      surface_no_scale_child_scale->draw_transform().matrix().get(0, 0));
  EXPECT_FLOAT_EQ(
      initial_child_scale,
      surface_no_scale_child_scale->draw_transform().matrix().get(1, 1));

  // The surface_no_scale_child_no_scale has a fixed contents scale of 1, so it
  // needs to be scaled by the device and page scale factors. It also needs to
  // be scaled by any transform heirarchy below its target surface.
  EXPECT_FLOAT_EQ(
      device_scale_factor * page_scale_factor * initial_child_scale,
      surface_no_scale_child_no_scale->draw_transform().matrix().get(0, 0));
  EXPECT_FLOAT_EQ(
      device_scale_factor * page_scale_factor * initial_child_scale,
      surface_no_scale_child_no_scale->draw_transform().matrix().get(1, 1));
}

TEST_F(LayerTreeHostCommonTest, IdealScaleForAnimatingLayer) {
  MockContentLayerClient delegate;
  gfx::Transform identity_matrix;

  gfx::Transform parent_scale_matrix;
  SkMScalar initial_parent_scale = 1.75;
  parent_scale_matrix.Scale(initial_parent_scale, initial_parent_scale);

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

  scoped_refptr<Layer> root = Layer::Create();
  root->SetBounds(gfx::Size(100, 100));

  scoped_refptr<FakePictureLayer> parent =
      CreateDrawablePictureLayer(&delegate);
  SetLayerPropertiesForTesting(parent.get(),
                               parent_scale_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(100, 100),
                               false,
                               true);

  scoped_refptr<FakePictureLayer> child_scale =
      CreateDrawablePictureLayer(&delegate);
  SetLayerPropertiesForTesting(child_scale.get(),
                               child_scale_matrix,
                               gfx::Point3F(),
                               gfx::PointF(2.f, 2.f),
                               gfx::Size(10, 10),
                               false,
                               true);

  root->AddChild(parent);

  parent->AddChild(child_scale);

  scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
  host->SetRootLayer(root);

  {
    RenderSurfaceLayerList render_surface_layer_list;
    LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
        root.get(), root->bounds(), &render_surface_layer_list);
    inputs.can_adjust_raster_scales = true;
    LayerTreeHostCommon::CalculateDrawProperties(&inputs);

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

// TODO(sohanjg): Remove this test when ContentLayer is removed.
TEST_F(LayerTreeHostCommonTest,
       ChangeInContentBoundsOrScaleTriggersPushProperties) {
  MockContentLayerClient delegate;
  scoped_refptr<Layer> root = Layer::Create();
  scoped_refptr<Layer> child = CreateDrawableContentLayer(&delegate);
  root->AddChild(child);

  scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
  host->SetRootLayer(root);

  gfx::Transform identity_matrix;
  SetLayerPropertiesForTesting(root.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(100, 100),
                               true,
                               false);
  SetLayerPropertiesForTesting(child.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(100, 100),
                               true,
                               false);

  root->reset_needs_push_properties_for_testing();
  child->reset_needs_push_properties_for_testing();

  // This will change both layers' content bounds.
  ExecuteCalculateDrawProperties(root.get());
  EXPECT_TRUE(root->needs_push_properties());
  EXPECT_TRUE(child->needs_push_properties());

  root->reset_needs_push_properties_for_testing();
  child->reset_needs_push_properties_for_testing();

  // This will change only the child layer's contents scale and content bounds,
  // since the root layer is not a ContentsScalingLayer.
  ExecuteCalculateDrawProperties(root.get(), 2.f);
  EXPECT_FALSE(root->needs_push_properties());
  EXPECT_TRUE(child->needs_push_properties());

  root->reset_needs_push_properties_for_testing();
  child->reset_needs_push_properties_for_testing();

  // This will not change either layer's contents scale or content bounds.
  ExecuteCalculateDrawProperties(root.get(), 2.f);
  EXPECT_FALSE(root->needs_push_properties());
  EXPECT_FALSE(child->needs_push_properties());
}

TEST_F(LayerTreeHostCommonTest, RenderSurfaceTransformsInHighDPI) {
  MockContentLayerClient delegate;
  gfx::Transform identity_matrix;

  scoped_refptr<FakePictureLayer> parent =
      CreateDrawablePictureLayer(&delegate);
  SetLayerPropertiesForTesting(parent.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(30, 30),
                               false,
                               true);

  scoped_refptr<FakePictureLayer> child = CreateDrawablePictureLayer(&delegate);
  SetLayerPropertiesForTesting(child.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(2.f, 2.f),
                               gfx::Size(10, 10),
                               false,
                               true);

  gfx::Transform replica_transform;
  replica_transform.Scale(1.0, -1.0);
  scoped_refptr<FakePictureLayer> replica =
      CreateDrawablePictureLayer(&delegate);
  SetLayerPropertiesForTesting(replica.get(),
                               replica_transform,
                               gfx::Point3F(),
                               gfx::PointF(2.f, 2.f),
                               gfx::Size(10, 10),
                               false,
                               true);

  // This layer should end up in the same surface as child, with the same draw
  // and screen space transforms.
  scoped_refptr<FakePictureLayer> duplicate_child_non_owner =
      CreateDrawablePictureLayer(&delegate);
  SetLayerPropertiesForTesting(duplicate_child_non_owner.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(10, 10),
                               false,
                               true);

  parent->AddChild(child);
  child->AddChild(duplicate_child_non_owner);
  child->SetReplicaLayer(replica.get());

  scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
  host->SetRootLayer(parent);

  RenderSurfaceLayerList render_surface_layer_list;

  float device_scale_factor = 1.5f;
  LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
      parent.get(), parent->bounds(), &render_surface_layer_list);
  inputs.device_scale_factor = device_scale_factor;
  inputs.can_adjust_raster_scales = true;
  LayerTreeHostCommon::CalculateDrawProperties(&inputs);

  // We should have two render surfaces. The root's render surface and child's
  // render surface (it needs one because it has a replica layer).
  EXPECT_EQ(2u, render_surface_layer_list.size());

  gfx::Transform expected_parent_transform;
  expected_parent_transform.Scale(device_scale_factor, device_scale_factor);
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_parent_transform,
                                  parent->screen_space_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_parent_transform,
                                  parent->draw_transform());

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

  gfx::Transform expected_screen_space_transform;
  expected_screen_space_transform.Scale(device_scale_factor,
                                        device_scale_factor);
  expected_screen_space_transform.Translate(child->position().x(),
                                            child->position().y());
  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_screen_space_transform,
                                  child->screen_space_transform());

  gfx::Transform expected_duplicate_child_draw_transform =
      child->draw_transform();
  EXPECT_TRANSFORMATION_MATRIX_EQ(child->draw_transform(),
                                  duplicate_child_non_owner->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(
      child->screen_space_transform(),
      duplicate_child_non_owner->screen_space_transform());
  EXPECT_EQ(child->drawable_content_rect(),
            duplicate_child_non_owner->drawable_content_rect());
  EXPECT_EQ(child->content_bounds(),
            duplicate_child_non_owner->content_bounds());

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

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

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

  gfx::Transform expected_replica_draw_transform;
  expected_replica_draw_transform.matrix().set(1, 1, -1.0);
  expected_replica_draw_transform.matrix().set(0, 3, 6.0);
  expected_replica_draw_transform.matrix().set(1, 3, 6.0);
  EXPECT_TRANSFORMATION_MATRIX_EQ(
      expected_replica_draw_transform,
      child->render_surface()->replica_draw_transform());

  gfx::Transform expected_replica_screen_space_transform;
  expected_replica_screen_space_transform.matrix().set(1, 1, -1.0);
  expected_replica_screen_space_transform.matrix().set(0, 3, 6.0);
  expected_replica_screen_space_transform.matrix().set(1, 3, 6.0);
  EXPECT_TRANSFORMATION_MATRIX_EQ(
      expected_replica_screen_space_transform,
      child->render_surface()->replica_screen_space_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(
      expected_replica_screen_space_transform,
      child->render_surface()->replica_screen_space_transform());
}

TEST_F(LayerTreeHostCommonTest,
     RenderSurfaceTransformsInHighDPIAccurateScaleZeroPosition) {
  MockContentLayerClient delegate;
  gfx::Transform identity_matrix;

  scoped_refptr<FakePictureLayer> parent =
      CreateDrawablePictureLayer(&delegate);
  SetLayerPropertiesForTesting(parent.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(33, 31),
                               false,
                               true);

  scoped_refptr<FakePictureLayer> child = CreateDrawablePictureLayer(&delegate);
  SetLayerPropertiesForTesting(child.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(13, 11),
                               false,
                               true);

  gfx::Transform replica_transform;
  replica_transform.Scale(1.0, -1.0);
  scoped_refptr<FakePictureLayer> replica =
      CreateDrawablePictureLayer(&delegate);
  SetLayerPropertiesForTesting(replica.get(),
                               replica_transform,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(13, 11),
                               false,
                               true);

  parent->AddChild(child);
  child->SetReplicaLayer(replica.get());

  scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
  host->SetRootLayer(parent);

  float device_scale_factor = 1.7f;

  RenderSurfaceLayerList render_surface_layer_list;
  LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
      parent.get(), parent->bounds(), &render_surface_layer_list);
  inputs.device_scale_factor = device_scale_factor;
  inputs.can_adjust_raster_scales = true;
  LayerTreeHostCommon::CalculateDrawProperties(&inputs);

  // We should have two render surfaces. The root's render surface and child's
  // render surface (it needs one because it has a replica layer).
  EXPECT_EQ(2u, render_surface_layer_list.size());

  gfx::Transform identity_transform;
  EXPECT_TRANSFORMATION_MATRIX_EQ(identity_transform,
                                  child->render_surface()->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(identity_transform,
                                  child->render_surface()->draw_transform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(
      identity_transform, child->render_surface()->screen_space_transform());

  gfx::Transform expected_replica_draw_transform;
  expected_replica_draw_transform.matrix().set(1, 1, -1.0);
  EXPECT_TRANSFORMATION_MATRIX_EQ(
      expected_replica_draw_transform,
      child->render_surface()->replica_draw_transform());

  gfx::Transform expected_replica_screen_space_transform;
  expected_replica_screen_space_transform.matrix().set(1, 1, -1.0);
  EXPECT_TRANSFORMATION_MATRIX_EQ(
      expected_replica_screen_space_transform,
      child->render_surface()->replica_screen_space_transform());
}

TEST_F(LayerTreeHostCommonTest, SubtreeSearch) {
  scoped_refptr<Layer> root = Layer::Create();
  scoped_refptr<Layer> child = Layer::Create();
  scoped_refptr<Layer> grand_child = Layer::Create();
  scoped_refptr<Layer> mask_layer = Layer::Create();
  scoped_refptr<Layer> replica_layer = Layer::Create();

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

  scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
  host->SetRootLayer(root);

  int nonexistent_id = -1;
  EXPECT_EQ(root.get(),
            LayerTreeHostCommon::FindLayerInSubtree(root.get(), root->id()));
  EXPECT_EQ(child.get(),
            LayerTreeHostCommon::FindLayerInSubtree(root.get(), child->id()));
  EXPECT_EQ(
      grand_child.get(),
      LayerTreeHostCommon::FindLayerInSubtree(root.get(), grand_child->id()));
  EXPECT_EQ(
      mask_layer.get(),
      LayerTreeHostCommon::FindLayerInSubtree(root.get(), mask_layer->id()));
  EXPECT_EQ(
      replica_layer.get(),
      LayerTreeHostCommon::FindLayerInSubtree(root.get(), replica_layer->id()));
  EXPECT_EQ(
      0, LayerTreeHostCommon::FindLayerInSubtree(root.get(), nonexistent_id));
}

TEST_F(LayerTreeHostCommonTest, TransparentChildRenderSurfaceCreation) {
  scoped_refptr<Layer> root = Layer::Create();
  scoped_refptr<Layer> child = Layer::Create();
  scoped_refptr<LayerWithForcedDrawsContent> grand_child =
      make_scoped_refptr(new LayerWithForcedDrawsContent());

  const gfx::Transform identity_matrix;
  SetLayerPropertiesForTesting(root.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(100, 100),
                               true,
                               false);
  SetLayerPropertiesForTesting(child.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(10, 10),
                               true,
                               false);
  SetLayerPropertiesForTesting(grand_child.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(10, 10),
                               true,
                               false);

  root->AddChild(child);
  child->AddChild(grand_child);
  child->SetOpacity(0.5f);

  scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
  host->SetRootLayer(root);

  ExecuteCalculateDrawProperties(root.get());

  EXPECT_FALSE(child->render_surface());
}

TEST_F(LayerTreeHostCommonTest, OpacityAnimatingOnPendingTree) {
  FakeImplProxy proxy;
  TestSharedBitmapManager shared_bitmap_manager;
  FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager);
  host_impl.CreatePendingTree();
  scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl.pending_tree(), 1);

  const gfx::Transform identity_matrix;
  SetLayerPropertiesForTesting(root.get(), identity_matrix, gfx::Point3F(),
                               gfx::PointF(), gfx::Size(100, 100), true, false,
                               false);
  root->SetDrawsContent(true);

  scoped_ptr<LayerImpl> child = LayerImpl::Create(host_impl.pending_tree(), 2);
  SetLayerPropertiesForTesting(child.get(), identity_matrix, gfx::Point3F(),
                               gfx::PointF(), gfx::Size(50, 50), true, false,
                               false);
  child->SetDrawsContent(true);
  child->SetOpacity(0.0f);

  // Add opacity animation.
  AddOpacityTransitionToController(
      child->layer_animation_controller(), 10.0, 0.0f, 1.0f, false);

  root->AddChild(child.Pass());
  root->SetHasRenderSurface(true);

  LayerImplList render_surface_layer_list;
  LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
      root.get(), root->bounds(), &render_surface_layer_list);
  inputs.can_adjust_raster_scales = true;
  LayerTreeHostCommon::CalculateDrawProperties(&inputs);

  // We should have one render surface and two layers. The child
  // layer should be included even though it is transparent.
  ASSERT_EQ(1u, render_surface_layer_list.size());
  ASSERT_EQ(2u, root->render_surface()->layer_list().size());
}

using LCDTextTestParam = std::tr1::tuple<bool, bool, bool>;
class LCDTextTest
    : public LayerTreeHostCommonTestBase,
      public testing::TestWithParam<LCDTextTestParam> {
 protected:
  void SetUp() override {
    can_use_lcd_text_ = std::tr1::get<0>(GetParam());
    layers_always_allowed_lcd_text_ = std::tr1::get<1>(GetParam());

    root_ = Layer::Create();
    child_ = Layer::Create();
    grand_child_ = Layer::Create();
    child_->AddChild(grand_child_.get());
    root_->AddChild(child_.get());

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

    gfx::Transform identity_matrix;
    SetLayerPropertiesForTesting(root_.get(),
                                 identity_matrix,
                                 gfx::Point3F(),
                                 gfx::PointF(),
                                 gfx::Size(1, 1),
                                 true,
                                 false);
    SetLayerPropertiesForTesting(child_.get(),
                                 identity_matrix,
                                 gfx::Point3F(),
                                 gfx::PointF(),
                                 gfx::Size(1, 1),
                                 true,
                                 false);
    SetLayerPropertiesForTesting(grand_child_.get(),
                                 identity_matrix,
                                 gfx::Point3F(),
                                 gfx::PointF(),
                                 gfx::Size(1, 1),
                                 true,
                                 false);

    child_->SetForceRenderSurface(std::tr1::get<2>(GetParam()));

    host_ = CreateFakeLayerTreeHost();
    host_->SetRootLayer(root_);
  }

  bool can_use_lcd_text_;
  bool layers_always_allowed_lcd_text_;
  scoped_ptr<FakeLayerTreeHost> host_;
  scoped_refptr<Layer> root_;
  scoped_refptr<Layer> child_;
  scoped_refptr<Layer> grand_child_;
};

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

  // Case 1: Identity transform.
  gfx::Transform identity_matrix;
  ExecuteCalculateDrawProperties(root_.get(), 1.f, 1.f, NULL, can_use_lcd_text_,
                                 layers_always_allowed_lcd_text_);
  EXPECT_EQ(expect_lcd_text, root_->can_use_lcd_text());
  EXPECT_EQ(expect_lcd_text, child_->can_use_lcd_text());
  EXPECT_EQ(expect_lcd_text, grand_child_->can_use_lcd_text());

  // Case 2: Integral translation.
  gfx::Transform integral_translation;
  integral_translation.Translate(1.0, 2.0);
  child_->SetTransform(integral_translation);
  ExecuteCalculateDrawProperties(root_.get(), 1.f, 1.f, NULL, can_use_lcd_text_,
                                 layers_always_allowed_lcd_text_);
  EXPECT_EQ(expect_lcd_text, root_->can_use_lcd_text());
  EXPECT_EQ(expect_lcd_text, child_->can_use_lcd_text());
  EXPECT_EQ(expect_lcd_text, grand_child_->can_use_lcd_text());

  // Case 3: Non-integral translation.
  gfx::Transform non_integral_translation;
  non_integral_translation.Translate(1.5, 2.5);
  child_->SetTransform(non_integral_translation);
  ExecuteCalculateDrawProperties(root_.get(), 1.f, 1.f, NULL, can_use_lcd_text_,
                                 layers_always_allowed_lcd_text_);
  EXPECT_EQ(expect_lcd_text, root_->can_use_lcd_text());
  EXPECT_EQ(expect_not_lcd_text, child_->can_use_lcd_text());
  EXPECT_EQ(expect_not_lcd_text, grand_child_->can_use_lcd_text());

  // Case 4: Rotation.
  gfx::Transform rotation;
  rotation.Rotate(10.0);
  child_->SetTransform(rotation);
  ExecuteCalculateDrawProperties(root_.get(), 1.f, 1.f, NULL, can_use_lcd_text_,
                                 layers_always_allowed_lcd_text_);
  EXPECT_EQ(expect_lcd_text, root_->can_use_lcd_text());
  EXPECT_EQ(expect_not_lcd_text, child_->can_use_lcd_text());
  EXPECT_EQ(expect_not_lcd_text, grand_child_->can_use_lcd_text());

  // Case 5: Scale.
  gfx::Transform scale;
  scale.Scale(2.0, 2.0);
  child_->SetTransform(scale);
  ExecuteCalculateDrawProperties(root_.get(), 1.f, 1.f, NULL, can_use_lcd_text_,
                                 layers_always_allowed_lcd_text_);
  EXPECT_EQ(expect_lcd_text, root_->can_use_lcd_text());
  EXPECT_EQ(expect_not_lcd_text, child_->can_use_lcd_text());
  EXPECT_EQ(expect_not_lcd_text, grand_child_->can_use_lcd_text());

  // Case 6: Skew.
  gfx::Transform skew;
  skew.SkewX(10.0);
  child_->SetTransform(skew);
  ExecuteCalculateDrawProperties(root_.get(), 1.f, 1.f, NULL, can_use_lcd_text_,
                                 layers_always_allowed_lcd_text_);
  EXPECT_EQ(expect_lcd_text, root_->can_use_lcd_text());
  EXPECT_EQ(expect_not_lcd_text, child_->can_use_lcd_text());
  EXPECT_EQ(expect_not_lcd_text, grand_child_->can_use_lcd_text());

  // Case 7: Translucent.
  child_->SetTransform(identity_matrix);
  child_->SetOpacity(0.5f);
  ExecuteCalculateDrawProperties(root_.get(), 1.f, 1.f, NULL, can_use_lcd_text_,
                                 layers_always_allowed_lcd_text_);
  EXPECT_EQ(expect_lcd_text, root_->can_use_lcd_text());
  EXPECT_EQ(expect_not_lcd_text, child_->can_use_lcd_text());
  EXPECT_EQ(expect_not_lcd_text, grand_child_->can_use_lcd_text());

  // Case 8: Sanity check: restore transform and opacity.
  child_->SetTransform(identity_matrix);
  child_->SetOpacity(1.f);
  ExecuteCalculateDrawProperties(root_.get(), 1.f, 1.f, NULL, can_use_lcd_text_,
                                 layers_always_allowed_lcd_text_);
  EXPECT_EQ(expect_lcd_text, root_->can_use_lcd_text());
  EXPECT_EQ(expect_lcd_text, child_->can_use_lcd_text());
  EXPECT_EQ(expect_lcd_text, grand_child_->can_use_lcd_text());

  // Case 9: Non-opaque content.
  child_->SetContentsOpaque(false);
  ExecuteCalculateDrawProperties(root_.get(), 1.f, 1.f, NULL, can_use_lcd_text_,
                                 layers_always_allowed_lcd_text_);
  EXPECT_EQ(expect_lcd_text, root_->can_use_lcd_text());
  EXPECT_EQ(expect_not_lcd_text, child_->can_use_lcd_text());
  EXPECT_EQ(expect_lcd_text, grand_child_->can_use_lcd_text());

  // Case 10: Sanity check: restore content opaqueness.
  child_->SetContentsOpaque(true);
  ExecuteCalculateDrawProperties(root_.get(), 1.f, 1.f, NULL, can_use_lcd_text_,
                                 layers_always_allowed_lcd_text_);
  EXPECT_EQ(expect_lcd_text, root_->can_use_lcd_text());
  EXPECT_EQ(expect_lcd_text, child_->can_use_lcd_text());
  EXPECT_EQ(expect_lcd_text, grand_child_->can_use_lcd_text());
}

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

  // Sanity check: Make sure can_use_lcd_text_ is set on each node.
  ExecuteCalculateDrawProperties(root_.get(), 1.f, 1.f, NULL, can_use_lcd_text_,
                                 layers_always_allowed_lcd_text_);
  EXPECT_EQ(expect_lcd_text, root_->can_use_lcd_text());
  EXPECT_EQ(expect_lcd_text, child_->can_use_lcd_text());
  EXPECT_EQ(expect_lcd_text, grand_child_->can_use_lcd_text());

  // Add opacity animation.
  child_->SetOpacity(0.9f);
  AddOpacityTransitionToController(
      child_->layer_animation_controller(), 10.0, 0.9f, 0.1f, false);

  ExecuteCalculateDrawProperties(root_.get(), 1.f, 1.f, NULL, can_use_lcd_text_,
                                 layers_always_allowed_lcd_text_);
  // Text AA should not be adjusted while animation is active.
  // Make sure LCD text AA setting remains unchanged.
  EXPECT_EQ(expect_lcd_text, root_->can_use_lcd_text());
  EXPECT_EQ(expect_lcd_text, child_->can_use_lcd_text());
  EXPECT_EQ(expect_lcd_text, grand_child_->can_use_lcd_text());
}

INSTANTIATE_TEST_CASE_P(LayerTreeHostCommonTest,
                        LCDTextTest,
                        testing::Combine(testing::Bool(),
                                         testing::Bool(),
                                         testing::Bool()));

TEST_F(LayerTreeHostCommonTest, SubtreeHidden_SingleLayer) {
  FakeImplProxy proxy;
  TestSharedBitmapManager shared_bitmap_manager;
  FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager);
  host_impl.CreatePendingTree();
  const gfx::Transform identity_matrix;

  scoped_refptr<Layer> root = Layer::Create();
  SetLayerPropertiesForTesting(root.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(50, 50),
                               true,
                               false);
  root->SetIsDrawable(true);

  scoped_refptr<Layer> child = Layer::Create();
  SetLayerPropertiesForTesting(child.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(40, 40),
                               true,
                               false);
  child->SetIsDrawable(true);

  scoped_refptr<Layer> grand_child = Layer::Create();
  SetLayerPropertiesForTesting(grand_child.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(30, 30),
                               true,
                               false);
  grand_child->SetIsDrawable(true);
  grand_child->SetHideLayerAndSubtree(true);

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

  scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
  host->SetRootLayer(root);

  RenderSurfaceLayerList render_surface_layer_list;
  LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
      root.get(), root->bounds(), &render_surface_layer_list);
  inputs.can_adjust_raster_scales = true;
  LayerTreeHostCommon::CalculateDrawProperties(&inputs);

  // We should have one render surface and two layers. The grand child has
  // hidden itself.
  ASSERT_EQ(1u, render_surface_layer_list.size());
  ASSERT_EQ(2u, root->render_surface()->layer_list().size());
  EXPECT_EQ(root->id(), root->render_surface()->layer_list().at(0)->id());
  EXPECT_EQ(child->id(), root->render_surface()->layer_list().at(1)->id());
}

TEST_F(LayerTreeHostCommonTest, SubtreeHidden_SingleLayerImpl) {
  FakeImplProxy proxy;
  TestSharedBitmapManager shared_bitmap_manager;
  FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager);
  host_impl.CreatePendingTree();
  const gfx::Transform identity_matrix;

  scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl.pending_tree(), 1);
  SetLayerPropertiesForTesting(root.get(), identity_matrix, gfx::Point3F(),
                               gfx::PointF(), gfx::Size(50, 50), true, false,
                               false);
  root->SetDrawsContent(true);

  scoped_ptr<LayerImpl> child = LayerImpl::Create(host_impl.pending_tree(), 2);
  SetLayerPropertiesForTesting(child.get(), identity_matrix, gfx::Point3F(),
                               gfx::PointF(), gfx::Size(40, 40), true, false,
                               false);
  child->SetDrawsContent(true);

  scoped_ptr<LayerImpl> grand_child =
      LayerImpl::Create(host_impl.pending_tree(), 3);
  SetLayerPropertiesForTesting(grand_child.get(), identity_matrix,
                               gfx::Point3F(), gfx::PointF(), gfx::Size(30, 30),
                               true, false, false);
  grand_child->SetDrawsContent(true);
  grand_child->SetHideLayerAndSubtree(true);

  child->AddChild(grand_child.Pass());
  root->AddChild(child.Pass());
  root->SetHasRenderSurface(true);

  LayerImplList render_surface_layer_list;
  LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
      root.get(), root->bounds(), &render_surface_layer_list);
  inputs.can_adjust_raster_scales = true;
  LayerTreeHostCommon::CalculateDrawProperties(&inputs);

  // We should have one render surface and two layers. The grand child has
  // hidden itself.
  ASSERT_EQ(1u, render_surface_layer_list.size());
  ASSERT_EQ(2u, root->render_surface()->layer_list().size());
  EXPECT_EQ(1, root->render_surface()->layer_list().at(0)->id());
  EXPECT_EQ(2, root->render_surface()->layer_list().at(1)->id());
}

TEST_F(LayerTreeHostCommonTest, SubtreeHidden_TwoLayers) {
  FakeImplProxy proxy;
  TestSharedBitmapManager shared_bitmap_manager;
  FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager);
  host_impl.CreatePendingTree();
  const gfx::Transform identity_matrix;

  scoped_refptr<Layer> root = Layer::Create();
  SetLayerPropertiesForTesting(root.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(50, 50),
                               true,
                               false);
  root->SetIsDrawable(true);

  scoped_refptr<Layer> child = Layer::Create();
  SetLayerPropertiesForTesting(child.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(40, 40),
                               true,
                               false);
  child->SetIsDrawable(true);
  child->SetHideLayerAndSubtree(true);

  scoped_refptr<Layer> grand_child = Layer::Create();
  SetLayerPropertiesForTesting(grand_child.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(30, 30),
                               true,
                               false);
  grand_child->SetIsDrawable(true);

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

  scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
  host->SetRootLayer(root);

  RenderSurfaceLayerList render_surface_layer_list;
  LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
      root.get(), root->bounds(), &render_surface_layer_list);
  inputs.can_adjust_raster_scales = true;
  LayerTreeHostCommon::CalculateDrawProperties(&inputs);

  // We should have one render surface and one layers. The child has
  // hidden itself and the grand child.
  ASSERT_EQ(1u, render_surface_layer_list.size());
  ASSERT_EQ(1u, root->render_surface()->layer_list().size());
  EXPECT_EQ(root->id(), root->render_surface()->layer_list().at(0)->id());
}

TEST_F(LayerTreeHostCommonTest, SubtreeHidden_TwoLayersImpl) {
  FakeImplProxy proxy;
  TestSharedBitmapManager shared_bitmap_manager;
  FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager);
  host_impl.CreatePendingTree();
  const gfx::Transform identity_matrix;

  scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl.pending_tree(), 1);
  SetLayerPropertiesForTesting(root.get(), identity_matrix, gfx::Point3F(),
                               gfx::PointF(), gfx::Size(50, 50), true, false,
                               true);
  root->SetDrawsContent(true);

  scoped_ptr<LayerImpl> child = LayerImpl::Create(host_impl.pending_tree(), 2);
  SetLayerPropertiesForTesting(child.get(), identity_matrix, gfx::Point3F(),
                               gfx::PointF(), gfx::Size(40, 40), true, false,
                               false);
  child->SetDrawsContent(true);
  child->SetHideLayerAndSubtree(true);

  scoped_ptr<LayerImpl> grand_child =
      LayerImpl::Create(host_impl.pending_tree(), 3);
  SetLayerPropertiesForTesting(grand_child.get(), identity_matrix,
                               gfx::Point3F(), gfx::PointF(), gfx::Size(30, 30),
                               true, false, false);
  grand_child->SetDrawsContent(true);

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

  LayerImplList render_surface_layer_list;
  LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
      root.get(), root->bounds(), &render_surface_layer_list);
  inputs.can_adjust_raster_scales = true;
  LayerTreeHostCommon::CalculateDrawProperties(&inputs);

  // We should have one render surface and one layers. The child has
  // hidden itself and the grand child.
  ASSERT_EQ(1u, render_surface_layer_list.size());
  ASSERT_EQ(1u, root->render_surface()->layer_list().size());
  EXPECT_EQ(1, root->render_surface()->layer_list().at(0)->id());
}

void EmptyCopyOutputCallback(scoped_ptr<CopyOutputResult> result) {}

TEST_F(LayerTreeHostCommonTest, SubtreeHiddenWithCopyRequest) {
  FakeImplProxy proxy;
  TestSharedBitmapManager shared_bitmap_manager;
  FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager);
  host_impl.CreatePendingTree();
  const gfx::Transform identity_matrix;

  scoped_refptr<Layer> root = Layer::Create();
  SetLayerPropertiesForTesting(root.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(50, 50),
                               true,
                               false);
  root->SetIsDrawable(true);

  scoped_refptr<Layer> copy_grand_parent = Layer::Create();
  SetLayerPropertiesForTesting(copy_grand_parent.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(40, 40),
                               true,
                               false);
  copy_grand_parent->SetIsDrawable(true);

  scoped_refptr<Layer> copy_parent = Layer::Create();
  SetLayerPropertiesForTesting(copy_parent.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(30, 30),
                               true,
                               false);
  copy_parent->SetIsDrawable(true);
  copy_parent->SetForceRenderSurface(true);

  scoped_refptr<Layer> copy_layer = Layer::Create();
  SetLayerPropertiesForTesting(copy_layer.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(20, 20),
                               true,
                               false);
  copy_layer->SetIsDrawable(true);

  scoped_refptr<Layer> copy_child = Layer::Create();
  SetLayerPropertiesForTesting(copy_child.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(20, 20),
                               true,
                               false);
  copy_child->SetIsDrawable(true);

  scoped_refptr<Layer> copy_grand_parent_sibling_before = Layer::Create();
  SetLayerPropertiesForTesting(copy_grand_parent_sibling_before.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(40, 40),
                               true,
                               false);
  copy_grand_parent_sibling_before->SetIsDrawable(true);

  scoped_refptr<Layer> copy_grand_parent_sibling_after = Layer::Create();
  SetLayerPropertiesForTesting(copy_grand_parent_sibling_after.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(40, 40),
                               true,
                               false);
  copy_grand_parent_sibling_after->SetIsDrawable(true);

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

  scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
  host->SetRootLayer(root);

  // Hide the copy_grand_parent and its subtree. But make a copy request in that
  // hidden subtree on copy_layer.
  copy_grand_parent->SetHideLayerAndSubtree(true);
  copy_grand_parent_sibling_before->SetHideLayerAndSubtree(true);
  copy_grand_parent_sibling_after->SetHideLayerAndSubtree(true);
  copy_layer->RequestCopyOfOutput(CopyOutputRequest::CreateRequest(
      base::Bind(&EmptyCopyOutputCallback)));
  EXPECT_TRUE(copy_layer->HasCopyRequest());

  RenderSurfaceLayerList render_surface_layer_list;
  LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
      root.get(), root->bounds(), &render_surface_layer_list);
  inputs.can_adjust_raster_scales = true;
  LayerTreeHostCommon::CalculateDrawProperties(&inputs);

  EXPECT_TRUE(root->draw_properties().layer_or_descendant_has_copy_request);
  EXPECT_TRUE(copy_grand_parent->draw_properties().
              layer_or_descendant_has_copy_request);
  EXPECT_TRUE(copy_parent->draw_properties().
              layer_or_descendant_has_copy_request);
  EXPECT_TRUE(copy_layer->draw_properties().
              layer_or_descendant_has_copy_request);
  EXPECT_FALSE(copy_child->draw_properties().
               layer_or_descendant_has_copy_request);
  EXPECT_FALSE(copy_grand_parent_sibling_before->draw_properties().
               layer_or_descendant_has_copy_request);
  EXPECT_FALSE(copy_grand_parent_sibling_after->draw_properties().
               layer_or_descendant_has_copy_request);

  // We should have three render surfaces, one for the root, one for the parent
  // since it owns a surface, and one for the copy_layer.
  ASSERT_EQ(3u, render_surface_layer_list.size());
  EXPECT_EQ(root->id(), render_surface_layer_list.at(0)->id());
  EXPECT_EQ(copy_parent->id(), render_surface_layer_list.at(1)->id());
  EXPECT_EQ(copy_layer->id(), render_surface_layer_list.at(2)->id());

  // The root render surface should have 2 contributing layers. The
  // copy_grand_parent is hidden along with its siblings, but the copy_parent
  // will appear since something in its subtree needs to be drawn for a copy
  // request.
  ASSERT_EQ(2u, root->render_surface()->layer_list().size());
  EXPECT_EQ(root->id(), root->render_surface()->layer_list().at(0)->id());
  EXPECT_EQ(copy_parent->id(),
            root->render_surface()->layer_list().at(1)->id());

  // Nothing actually draws into the copy parent, so only the copy_layer will
  // appear in its list, since it needs to be drawn for the copy request.
  ASSERT_EQ(1u, copy_parent->render_surface()->layer_list().size());
  EXPECT_EQ(copy_layer->id(),
            copy_parent->render_surface()->layer_list().at(0)->id());

  // The copy_layer's render surface should have two contributing layers.
  ASSERT_EQ(2u, copy_layer->render_surface()->layer_list().size());
  EXPECT_EQ(copy_layer->id(),
            copy_layer->render_surface()->layer_list().at(0)->id());
  EXPECT_EQ(copy_child->id(),
            copy_layer->render_surface()->layer_list().at(1)->id());
}

TEST_F(LayerTreeHostCommonTest, ClippedOutCopyRequest) {
  FakeImplProxy proxy;
  TestSharedBitmapManager shared_bitmap_manager;
  FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager);
  host_impl.CreatePendingTree();
  const gfx::Transform identity_matrix;

  scoped_refptr<Layer> root = Layer::Create();
  SetLayerPropertiesForTesting(root.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(50, 50),
                               true,
                               false);
  root->SetIsDrawable(true);

  scoped_refptr<Layer> copy_parent = Layer::Create();
  SetLayerPropertiesForTesting(copy_parent.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(),
                               true,
                               false);
  copy_parent->SetIsDrawable(true);
  copy_parent->SetMasksToBounds(true);

  scoped_refptr<Layer> copy_layer = Layer::Create();
  SetLayerPropertiesForTesting(copy_layer.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(30, 30),
                               true,
                               false);
  copy_layer->SetIsDrawable(true);

  scoped_refptr<Layer> copy_child = Layer::Create();
  SetLayerPropertiesForTesting(copy_child.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(20, 20),
                               true,
                               false);
  copy_child->SetIsDrawable(true);

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

  scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
  host->SetRootLayer(root);

  copy_layer->RequestCopyOfOutput(CopyOutputRequest::CreateRequest(
      base::Bind(&EmptyCopyOutputCallback)));
  EXPECT_TRUE(copy_layer->HasCopyRequest());

  RenderSurfaceLayerList render_surface_layer_list;
  LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
      root.get(), root->bounds(), &render_surface_layer_list);
  inputs.can_adjust_raster_scales = true;
  LayerTreeHostCommon::CalculateDrawProperties(&inputs);

  // We should have one render surface, as the others are clipped out.
  ASSERT_EQ(1u, render_surface_layer_list.size());
  EXPECT_EQ(root->id(), render_surface_layer_list.at(0)->id());

  // The root render surface should only have 1 contributing layer, since the
  // other layers are empty/clipped away.
  ASSERT_EQ(1u, root->render_surface()->layer_list().size());
  EXPECT_EQ(root->id(), root->render_surface()->layer_list().at(0)->id());
}

TEST_F(LayerTreeHostCommonTest, VisibleContentRectInsideSurface) {
  FakeImplProxy proxy;
  TestSharedBitmapManager shared_bitmap_manager;
  FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager);
  host_impl.CreatePendingTree();
  const gfx::Transform identity_matrix;

  scoped_refptr<Layer> root = Layer::Create();
  SetLayerPropertiesForTesting(root.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(50, 50),
                               true,
                               false);
  root->SetIsDrawable(true);

  // The surface is moved slightly outside of the viewport.
  scoped_refptr<Layer> surface = Layer::Create();
  SetLayerPropertiesForTesting(surface.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(-10, -20),
                               gfx::Size(),
                               true,
                               false);
  surface->SetForceRenderSurface(true);

  scoped_refptr<Layer> surface_child = Layer::Create();
  SetLayerPropertiesForTesting(surface_child.get(),
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(50, 50),
                               true,
                               false);
  surface_child->SetIsDrawable(true);

  surface->AddChild(surface_child);
  root->AddChild(surface);

  scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
  host->SetRootLayer(root);

  RenderSurfaceLayerList render_surface_layer_list;
  LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
      root.get(), root->bounds(), &render_surface_layer_list);
  inputs.can_adjust_raster_scales = true;
  LayerTreeHostCommon::CalculateDrawProperties(&inputs);

  // The visible_content_rect for the |surface_child| should not be clipped by
  // the viewport.
  EXPECT_EQ(gfx::Rect(50, 50).ToString(),
            surface_child->visible_content_rect().ToString());
}

TEST_F(LayerTreeHostCommonTest, TransformedClipParent) {
  // Ensure that a transform between the layer and its render surface is not a
  // problem. Constructs the following layer tree.
  //
  //   root (a render surface)
  //     + render_surface
  //       + clip_parent (scaled)
  //         + intervening_clipping_layer
  //           + clip_child
  //
  // The render surface should be resized correctly and the clip child should
  // inherit the right clip rect.
  scoped_refptr<Layer> root = Layer::Create();
  scoped_refptr<Layer> render_surface = Layer::Create();
  scoped_refptr<Layer> clip_parent = Layer::Create();
  scoped_refptr<Layer> intervening = Layer::Create();
  scoped_refptr<LayerWithForcedDrawsContent> clip_child =
      make_scoped_refptr(new LayerWithForcedDrawsContent);

  root->AddChild(render_surface);
  render_surface->AddChild(clip_parent);
  clip_parent->AddChild(intervening);
  intervening->AddChild(clip_child);

  clip_child->SetClipParent(clip_parent.get());

  intervening->SetMasksToBounds(true);
  clip_parent->SetMasksToBounds(true);

  render_surface->SetForceRenderSurface(true);

  gfx::Transform scale_transform;
  scale_transform.Scale(2, 2);

  gfx::Transform identity_transform;

  SetLayerPropertiesForTesting(root.get(),
                               identity_transform,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(50, 50),
                               true,
                               false);
  SetLayerPropertiesForTesting(render_surface.get(),
                               identity_transform,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(10, 10),
                               true,
                               false);
  SetLayerPropertiesForTesting(clip_parent.get(),
                               scale_transform,
                               gfx::Point3F(),
                               gfx::PointF(1.f, 1.f),
                               gfx::Size(10, 10),
                               true,
                               false);
  SetLayerPropertiesForTesting(intervening.get(),
                               identity_transform,
                               gfx::Point3F(),
                               gfx::PointF(1.f, 1.f),
                               gfx::Size(5, 5),
                               true,
                               false);
  SetLayerPropertiesForTesting(clip_child.get(),
                               identity_transform,
                               gfx::Point3F(),
                               gfx::PointF(1.f, 1.f),
                               gfx::Size(10, 10),
                               true,
                               false);

  scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
  host->SetRootLayer(root);

  ExecuteCalculateDrawProperties(root.get());

  ASSERT_TRUE(root->render_surface());
  ASSERT_TRUE(render_surface->render_surface());

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

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

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

TEST_F(LayerTreeHostCommonTest, ClipParentWithInterveningRenderSurface) {
  // Ensure that intervening render surfaces are not a problem in the basic
  // case. In the following tree, both render surfaces should be resized to
  // accomodate for the clip child, despite an intervening clip.
  //
  //   root (a render surface)
  //    + clip_parent (masks to bounds)
  //      + render_surface1 (sets opacity)
  //        + intervening (masks to bounds)
  //          + render_surface2 (also sets opacity)
  //            + clip_child
  //
  scoped_refptr<Layer> root = Layer::Create();
  scoped_refptr<Layer> clip_parent = Layer::Create();
  scoped_refptr<Layer> render_surface1 = Layer::Create();
  scoped_refptr<Layer> intervening = Layer::Create();
  scoped_refptr<Layer> render_surface2 = Layer::Create();
  scoped_refptr<LayerWithForcedDrawsContent> clip_child =
      make_scoped_refptr(new LayerWithForcedDrawsContent);

  root->AddChild(clip_parent);
  clip_parent->AddChild(render_surface1);
  render_surface1->AddChild(intervening);
  intervening->AddChild(render_surface2);
  render_surface2->AddChild(clip_child);

  clip_child->SetClipParent(clip_parent.get());

  intervening->SetMasksToBounds(true);
  clip_parent->SetMasksToBounds(true);

  render_surface1->SetForceRenderSurface(true);
  render_surface2->SetForceRenderSurface(true);

  gfx::Transform translation_transform;
  translation_transform.Translate(2, 2);

  gfx::Transform identity_transform;
  SetLayerPropertiesForTesting(root.get(),
                               identity_transform,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(50, 50),
                               true,
                               false);
  SetLayerPropertiesForTesting(clip_parent.get(),
                               translation_transform,
                               gfx::Point3F(),
                               gfx::PointF(1.f, 1.f),
                               gfx::Size(40, 40),
                               true,
                               false);
  SetLayerPropertiesForTesting(render_surface1.get(),
                               identity_transform,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(10, 10),
                               true,
                               false);
  SetLayerPropertiesForTesting(intervening.get(),
                               identity_transform,
                               gfx::Point3F(),
                               gfx::PointF(1.f, 1.f),
                               gfx::Size(5, 5),
                               true,
                               false);
  SetLayerPropertiesForTesting(render_surface2.get(),
                               identity_transform,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(10, 10),
                               true,
                               false);
  SetLayerPropertiesForTesting(clip_child.get(),
                               identity_transform,
                               gfx::Point3F(),
                               gfx::PointF(-10.f, -10.f),
                               gfx::Size(60, 60),
                               true,
                               false);

  scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
  host->SetRootLayer(root);

  ExecuteCalculateDrawProperties(root.get());

  EXPECT_TRUE(root->render_surface());
  EXPECT_TRUE(render_surface1->render_surface());
  EXPECT_TRUE(render_surface2->render_surface());

  // Since the render surfaces could have expanded, they should not clip (their
  // bounds would no longer be reliable). We should resort to layer clipping
  // in this case.
  EXPECT_EQ(gfx::Rect(0, 0, 0, 0).ToString(),
            render_surface1->render_surface()->clip_rect().ToString());
  EXPECT_FALSE(render_surface1->render_surface()->is_clipped());
  EXPECT_EQ(gfx::Rect(0, 0, 0, 0).ToString(),
            render_surface2->render_surface()->clip_rect().ToString());
  EXPECT_FALSE(render_surface2->render_surface()->is_clipped());

  // NB: clip rects are in target space.
  EXPECT_EQ(gfx::Rect(0, 0, 40, 40).ToString(),
            render_surface1->clip_rect().ToString());
  EXPECT_TRUE(render_surface1->is_clipped());

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

  // The content rects of both render surfaces should both have expanded to
  // contain the clip child.
  EXPECT_EQ(gfx::Rect(0, 0, 40, 40).ToString(),
            render_surface1->render_surface()->content_rect().ToString());
  EXPECT_EQ(gfx::Rect(-1, -1, 40, 40).ToString(),
            render_surface2->render_surface()->content_rect().ToString());

  // The clip child should have inherited the clip parent's clip (projected to
  // the right space, of course), and should have the correctly sized visible
  // content rect.
  EXPECT_EQ(gfx::Rect(-1, -1, 40, 40).ToString(),
            clip_child->clip_rect().ToString());
  EXPECT_EQ(gfx::Rect(9, 9, 40, 40).ToString(),
            clip_child->visible_content_rect().ToString());
  EXPECT_TRUE(clip_child->is_clipped());
}

TEST_F(LayerTreeHostCommonTest, ClipParentScrolledInterveningLayer) {
  // Ensure that intervening render surfaces are not a problem, even if there
  // is a scroll involved. Note, we do _not_ have to consider any other sort
  // of transform.
  //
  //   root (a render surface)
  //    + clip_parent (masks to bounds)
  //      + render_surface1 (sets opacity)
  //        + intervening (masks to bounds AND scrolls)
  //          + render_surface2 (also sets opacity)
  //            + clip_child
  //
  scoped_refptr<Layer> root = Layer::Create();
  scoped_refptr<Layer> clip_parent = Layer::Create();
  scoped_refptr<Layer> render_surface1 = Layer::Create();
  scoped_refptr<Layer> intervening = Layer::Create();
  scoped_refptr<Layer> render_surface2 = Layer::Create();
  scoped_refptr<LayerWithForcedDrawsContent> clip_child =
      make_scoped_refptr(new LayerWithForcedDrawsContent);

  root->AddChild(clip_parent);
  clip_parent->AddChild(render_surface1);
  render_surface1->AddChild(intervening);
  intervening->AddChild(render_surface2);
  render_surface2->AddChild(clip_child);

  clip_child->SetClipParent(clip_parent.get());

  intervening->SetMasksToBounds(true);
  clip_parent->SetMasksToBounds(true);
  intervening->SetScrollClipLayerId(clip_parent->id());
  intervening->SetScrollOffset(gfx::ScrollOffset(3, 3));

  render_surface1->SetForceRenderSurface(true);
  render_surface2->SetForceRenderSurface(true);

  gfx::Transform translation_transform;
  translation_transform.Translate(2, 2);

  gfx::Transform identity_transform;
  SetLayerPropertiesForTesting(root.get(),
                               identity_transform,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(50, 50),
                               true,
                               false);
  SetLayerPropertiesForTesting(clip_parent.get(),
                               translation_transform,
                               gfx::Point3F(),
                               gfx::PointF(1.f, 1.f),
                               gfx::Size(40, 40),
                               true,
                               false);
  SetLayerPropertiesForTesting(render_surface1.get(),
                               identity_transform,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(10, 10),
                               true,
                               false);
  SetLayerPropertiesForTesting(intervening.get(),
                               identity_transform,
                               gfx::Point3F(),
                               gfx::PointF(1.f, 1.f),
                               gfx::Size(5, 5),
                               true,
                               false);
  SetLayerPropertiesForTesting(render_surface2.get(),
                               identity_transform,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(10, 10),
                               true,
                               false);
  SetLayerPropertiesForTesting(clip_child.get(),
                               identity_transform,
                               gfx::Point3F(),
                               gfx::PointF(-10.f, -10.f),
                               gfx::Size(60, 60),
                               true,
                               false);

  scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
  host->SetRootLayer(root);

  ExecuteCalculateDrawProperties(root.get());

  EXPECT_TRUE(root->render_surface());
  EXPECT_TRUE(render_surface1->render_surface());
  EXPECT_TRUE(render_surface2->render_surface());

  // Since the render surfaces could have expanded, they should not clip (their
  // bounds would no longer be reliable). We should resort to layer clipping
  // in this case.
  EXPECT_EQ(gfx::Rect(0, 0, 0, 0).ToString(),
            render_surface1->render_surface()->clip_rect().ToString());
  EXPECT_FALSE(render_surface1->render_surface()->is_clipped());
  EXPECT_EQ(gfx::Rect(0, 0, 0, 0).ToString(),
            render_surface2->render_surface()->clip_rect().ToString());
  EXPECT_FALSE(render_surface2->render_surface()->is_clipped());

  // NB: clip rects are in target space.
  EXPECT_EQ(gfx::Rect(0, 0, 40, 40).ToString(),
            render_surface1->clip_rect().ToString());
  EXPECT_TRUE(render_surface1->is_clipped());

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

  // The content rects of both render surfaces should both have expanded to
  // contain the clip child.
  EXPECT_EQ(gfx::Rect(0, 0, 40, 40).ToString(),
            render_surface1->render_surface()->content_rect().ToString());
  EXPECT_EQ(gfx::Rect(2, 2, 40, 40).ToString(),
            render_surface2->render_surface()->content_rect().ToString());

  // The clip child should have inherited the clip parent's clip (projected to
  // the right space, of course), and should have the correctly sized visible
  // content rect.
  EXPECT_EQ(gfx::Rect(2, 2, 40, 40).ToString(),
            clip_child->clip_rect().ToString());
  EXPECT_EQ(gfx::Rect(12, 12, 40, 40).ToString(),
            clip_child->visible_content_rect().ToString());
  EXPECT_TRUE(clip_child->is_clipped());
}

TEST_F(LayerTreeHostCommonTest, DescendantsOfClipChildren) {
  // Ensures that descendants of the clip child inherit the correct clip.
  //
  //   root (a render surface)
  //    + clip_parent (masks to bounds)
  //      + intervening (masks to bounds)
  //        + clip_child
  //          + child
  //
  scoped_refptr<Layer> root = Layer::Create();
  scoped_refptr<Layer> clip_parent = Layer::Create();
  scoped_refptr<Layer> intervening = Layer::Create();
  scoped_refptr<Layer> clip_child = Layer::Create();
  scoped_refptr<LayerWithForcedDrawsContent> child =
      make_scoped_refptr(new LayerWithForcedDrawsContent);

  root->AddChild(clip_parent);
  clip_parent->AddChild(intervening);
  intervening->AddChild(clip_child);
  clip_child->AddChild(child);

  clip_child->SetClipParent(clip_parent.get());

  intervening->SetMasksToBounds(true);
  clip_parent->SetMasksToBounds(true);

  gfx::Transform identity_transform;
  SetLayerPropertiesForTesting(root.get(),
                               identity_transform,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(50, 50),
                               true,
                               false);
  SetLayerPropertiesForTesting(clip_parent.get(),
                               identity_transform,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(40, 40),
                               true,
                               false);
  SetLayerPropertiesForTesting(intervening.get(),
                               identity_transform,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(5, 5),
                               true,
                               false);
  SetLayerPropertiesForTesting(clip_child.get(),
                               identity_transform,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(60, 60),
                               true,
                               false);
  SetLayerPropertiesForTesting(child.get(),
                               identity_transform,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(60, 60),
                               true,
                               false);

  scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
  host->SetRootLayer(root);

  ExecuteCalculateDrawProperties(root.get());

  EXPECT_TRUE(root->render_surface());

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

TEST_F(LayerTreeHostCommonTest,
       SurfacesShouldBeUnaffectedByNonDescendantClipChildren) {
  // Ensures that non-descendant clip children in the tree do not affect
  // render surfaces.
  //
  //   root (a render surface)
  //    + clip_parent (masks to bounds)
  //      + render_surface1
  //        + clip_child
  //      + render_surface2
  //        + non_clip_child
  //
  // In this example render_surface2 should be unaffected by clip_child.
  scoped_refptr<Layer> root = Layer::Create();
  scoped_refptr<Layer> clip_parent = Layer::Create();
  scoped_refptr<Layer> render_surface1 = Layer::Create();
  scoped_refptr<LayerWithForcedDrawsContent> clip_child =
      make_scoped_refptr(new LayerWithForcedDrawsContent);
  scoped_refptr<Layer> render_surface2 = Layer::Create();
  scoped_refptr<LayerWithForcedDrawsContent> non_clip_child =
      make_scoped_refptr(new LayerWithForcedDrawsContent);

  root->AddChild(clip_parent);
  clip_parent->AddChild(render_surface1);
  render_surface1->AddChild(clip_child);
  clip_parent->AddChild(render_surface2);
  render_surface2->AddChild(non_clip_child);

  clip_child->SetClipParent(clip_parent.get());

  clip_parent->SetMasksToBounds(true);
  render_surface1->SetMasksToBounds(true);

  gfx::Transform identity_transform;
  SetLayerPropertiesForTesting(root.get(),
                               identity_transform,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(15, 15),
                               true,
                               false);
  SetLayerPropertiesForTesting(clip_parent.get(),
                               identity_transform,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(10, 10),
                               true,
                               false);
  SetLayerPropertiesForTesting(render_surface1.get(),
                               identity_transform,
                               gfx::Point3F(),
                               gfx::PointF(5, 5),
                               gfx::Size(5, 5),
                               true,
                               false);
  SetLayerPropertiesForTesting(render_surface2.get(),
                               identity_transform,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(5, 5),
                               true,
                               false);
  SetLayerPropertiesForTesting(clip_child.get(),
                               identity_transform,
                               gfx::Point3F(),
                               gfx::PointF(-1, 1),
                               gfx::Size(10, 10),
                               true,
                               false);
  SetLayerPropertiesForTesting(non_clip_child.get(),
                               identity_transform,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(5, 5),
                               true,
                               false);

  render_surface1->SetForceRenderSurface(true);
  render_surface2->SetForceRenderSurface(true);

  scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
  host->SetRootLayer(root);

  ExecuteCalculateDrawProperties(root.get());

  EXPECT_TRUE(root->render_surface());
  EXPECT_TRUE(render_surface1->render_surface());
  EXPECT_TRUE(render_surface2->render_surface());

  EXPECT_EQ(gfx::Rect(0, 0, 5, 5).ToString(),
            render_surface1->clip_rect().ToString());
  EXPECT_TRUE(render_surface1->is_clipped());

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

  // That said, it should have grown to accomodate the unclipped descendant.
  EXPECT_EQ(gfx::Rect(-1, 1, 6, 4).ToString(),
            render_surface1->render_surface()->content_rect().ToString());

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

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

  // Sanity check our num_unclipped_descendants values.
  EXPECT_EQ(1, render_surface1->num_unclipped_descendants());
  EXPECT_EQ(0, render_surface2->num_unclipped_descendants());
}

TEST_F(LayerTreeHostCommonTest, CanRenderToSeparateSurface) {
  FakeImplProxy proxy;
  TestSharedBitmapManager shared_bitmap_manager;
  FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager);
  scoped_ptr<LayerImpl> root =
      LayerImpl::Create(host_impl.active_tree(), 12345);
  scoped_ptr<LayerImpl> child1 =
      LayerImpl::Create(host_impl.active_tree(), 123456);
  scoped_ptr<LayerImpl> child2 =
      LayerImpl::Create(host_impl.active_tree(), 1234567);
  scoped_ptr<LayerImpl> child3 =
      LayerImpl::Create(host_impl.active_tree(), 12345678);

  gfx::Transform identity_matrix;
  gfx::Point3F transform_origin;
  gfx::PointF position;
  gfx::Size bounds(100, 100);
  SetLayerPropertiesForTesting(root.get(), identity_matrix, transform_origin,
                               position, bounds, true, false, true);
  root->SetDrawsContent(true);

  // This layer structure normally forces render surface due to preserves3d
  // behavior.
  SetLayerPropertiesForTesting(child1.get(), identity_matrix, transform_origin,
                               position, bounds, false, true, true);
  child1->SetDrawsContent(true);
  SetLayerPropertiesForTesting(child2.get(), identity_matrix, transform_origin,
                               position, bounds, true, false, false);
  child2->SetDrawsContent(true);
  SetLayerPropertiesForTesting(child3.get(), identity_matrix, transform_origin,
                               position, bounds, true, false, false);
  child3->SetDrawsContent(true);

  child2->Set3dSortingContextId(1);
  child3->Set3dSortingContextId(1);

  child2->AddChild(child3.Pass());
  child1->AddChild(child2.Pass());
  root->AddChild(child1.Pass());

  {
    LayerImplList render_surface_layer_list;
    FakeLayerTreeHostImpl::RecursiveUpdateNumChildren(root.get());
    LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
        root.get(), root->bounds(), &render_surface_layer_list);
    inputs.can_render_to_separate_surface = true;
    LayerTreeHostCommon::CalculateDrawProperties(&inputs);

    EXPECT_EQ(2u, render_surface_layer_list.size());
  }

  {
    LayerImplList render_surface_layer_list;
    LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
        root.get(), root->bounds(), &render_surface_layer_list);
    inputs.can_render_to_separate_surface = false;
    LayerTreeHostCommon::CalculateDrawProperties(&inputs);

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

TEST_F(LayerTreeHostCommonTest, DoNotIncludeBackfaceInvisibleSurfaces) {
  scoped_refptr<Layer> root = Layer::Create();
  scoped_refptr<Layer> render_surface = Layer::Create();
  scoped_refptr<LayerWithForcedDrawsContent> child =
      make_scoped_refptr(new LayerWithForcedDrawsContent);

  root->AddChild(render_surface);
  render_surface->AddChild(child);

  gfx::Transform identity_transform;
  SetLayerPropertiesForTesting(root.get(),
                               identity_transform,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(50, 50),
                               true,
                               false);
  SetLayerPropertiesForTesting(render_surface.get(),
                               identity_transform,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(30, 30),
                               false,
                               true);
  SetLayerPropertiesForTesting(child.get(),
                               identity_transform,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(20, 20),
                               true,
                               false);

  root->SetShouldFlattenTransform(false);
  root->Set3dSortingContextId(1);
  render_surface->SetDoubleSided(false);
  render_surface->SetForceRenderSurface(true);

  scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
  host->SetRootLayer(root);

  ExecuteCalculateDrawProperties(root.get());

  EXPECT_EQ(2u, render_surface_layer_list()->size());
  EXPECT_EQ(1u,
            render_surface_layer_list()->at(0)
                ->render_surface()->layer_list().size());
  EXPECT_EQ(1u,
            render_surface_layer_list()->at(1)
                ->render_surface()->layer_list().size());

  gfx::Transform rotation_transform = identity_transform;
  rotation_transform.RotateAboutXAxis(180.0);

  render_surface->SetTransform(rotation_transform);

  ExecuteCalculateDrawProperties(root.get());

  EXPECT_EQ(1u, render_surface_layer_list()->size());
  EXPECT_EQ(0u,
            render_surface_layer_list()->at(0)
                ->render_surface()->layer_list().size());
}

TEST_F(LayerTreeHostCommonTest, ClippedByScrollParent) {
  // Checks that the simple case (being clipped by a scroll parent that would
  // have been processed before you anyhow) results in the right clips.
  //
  // + root
  //   + scroll_parent_border
  //   | + scroll_parent_clip
  //   |   + scroll_parent
  //   + scroll_child
  //
  scoped_refptr<Layer> root = Layer::Create();
  scoped_refptr<Layer> scroll_parent_border = Layer::Create();
  scoped_refptr<Layer> scroll_parent_clip = Layer::Create();
  scoped_refptr<LayerWithForcedDrawsContent> scroll_parent =
      make_scoped_refptr(new LayerWithForcedDrawsContent);
  scoped_refptr<LayerWithForcedDrawsContent> scroll_child =
      make_scoped_refptr(new LayerWithForcedDrawsContent);

  root->AddChild(scroll_child);

  root->AddChild(scroll_parent_border);
  scroll_parent_border->AddChild(scroll_parent_clip);
  scroll_parent_clip->AddChild(scroll_parent);

  scroll_parent_clip->SetMasksToBounds(true);

  scroll_child->SetScrollParent(scroll_parent.get());

  gfx::Transform identity_transform;
  SetLayerPropertiesForTesting(root.get(),
                               identity_transform,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(50, 50),
                               true,
                               false);
  SetLayerPropertiesForTesting(scroll_parent_border.get(),
                               identity_transform,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(40, 40),
                               true,
                               false);
  SetLayerPropertiesForTesting(scroll_parent_clip.get(),
                               identity_transform,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(30, 30),
                               true,
                               false);
  SetLayerPropertiesForTesting(scroll_parent.get(),
                               identity_transform,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(50, 50),
                               true,
                               false);
  SetLayerPropertiesForTesting(scroll_child.get(),
                               identity_transform,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(50, 50),
                               true,
                               false);

  scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
  host->SetRootLayer(root);

  ExecuteCalculateDrawProperties(root.get());

  EXPECT_TRUE(root->render_surface());

  EXPECT_EQ(gfx::Rect(0, 0, 30, 30).ToString(),
            scroll_child->clip_rect().ToString());
  EXPECT_TRUE(scroll_child->is_clipped());
}

TEST_F(LayerTreeHostCommonTest, SingularTransformSubtreesDoNotDraw) {
  scoped_refptr<LayerWithForcedDrawsContent> root =
      make_scoped_refptr(new LayerWithForcedDrawsContent);
  scoped_refptr<LayerWithForcedDrawsContent> parent =
      make_scoped_refptr(new LayerWithForcedDrawsContent);
  scoped_refptr<LayerWithForcedDrawsContent> child =
      make_scoped_refptr(new LayerWithForcedDrawsContent);

  root->AddChild(parent);
  parent->AddChild(child);

  gfx::Transform identity_transform;
  SetLayerPropertiesForTesting(root.get(),
                               identity_transform,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(50, 50),
                               true,
                               true);
  root->SetForceRenderSurface(true);
  SetLayerPropertiesForTesting(parent.get(),
                               identity_transform,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(30, 30),
                               true,
                               true);
  parent->SetForceRenderSurface(true);
  SetLayerPropertiesForTesting(child.get(),
                               identity_transform,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(20, 20),
                               true,
                               true);
  child->SetForceRenderSurface(true);

  scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
  host->SetRootLayer(root);

  ExecuteCalculateDrawProperties(root.get());

  EXPECT_EQ(3u, render_surface_layer_list()->size());

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

  child->SetTransform(singular_transform);

  ExecuteCalculateDrawProperties(root.get());

  EXPECT_EQ(2u, render_surface_layer_list()->size());

  // Ensure that the entire subtree under a layer with singular transform does
  // not get rendered.
  parent->SetTransform(singular_transform);
  child->SetTransform(identity_transform);

  ExecuteCalculateDrawProperties(root.get());

  EXPECT_EQ(1u, render_surface_layer_list()->size());
}

TEST_F(LayerTreeHostCommonTest, ClippedByOutOfOrderScrollParent) {
  // Checks that clipping by a scroll parent that follows you in paint order
  // still results in correct clipping.
  //
  // + root
  //   + scroll_child
  //   + scroll_parent_border
  //     + scroll_parent_clip
  //       + scroll_parent
  //
  scoped_refptr<Layer> root = Layer::Create();
  scoped_refptr<Layer> scroll_parent_border = Layer::Create();
  scoped_refptr<Layer> scroll_parent_clip = Layer::Create();
  scoped_refptr<LayerWithForcedDrawsContent> scroll_parent =
      make_scoped_refptr(new LayerWithForcedDrawsContent);
  scoped_refptr<LayerWithForcedDrawsContent> scroll_child =
      make_scoped_refptr(new LayerWithForcedDrawsContent);

  root->AddChild(scroll_parent_border);
  scroll_parent_border->AddChild(scroll_parent_clip);
  scroll_parent_clip->AddChild(scroll_parent);

  root->AddChild(scroll_child);

  scroll_parent_clip->SetMasksToBounds(true);

  scroll_child->SetScrollParent(scroll_parent.get());

  gfx::Transform identity_transform;
  SetLayerPropertiesForTesting(root.get(),
                               identity_transform,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(50, 50),
                               true,
                               false);
  SetLayerPropertiesForTesting(scroll_parent_border.get(),
                               identity_transform,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(40, 40),
                               true,
                               false);
  SetLayerPropertiesForTesting(scroll_parent_clip.get(),
                               identity_transform,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(30, 30),
                               true,
                               false);
  SetLayerPropertiesForTesting(scroll_parent.get(),
                               identity_transform,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(50, 50),
                               true,
                               false);
  SetLayerPropertiesForTesting(scroll_child.get(),
                               identity_transform,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(50, 50),
                               true,
                               false);

  scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
  host->SetRootLayer(root);

  ExecuteCalculateDrawProperties(root.get());

  EXPECT_TRUE(root->render_surface());

  EXPECT_EQ(gfx::Rect(0, 0, 30, 30).ToString(),
            scroll_child->clip_rect().ToString());
  EXPECT_TRUE(scroll_child->is_clipped());
}

TEST_F(LayerTreeHostCommonTest, ClippedByOutOfOrderScrollGrandparent) {
  // Checks that clipping by a scroll parent and scroll grandparent that follow
  // you in paint order still results in correct clipping.
  //
  // + root
  //   + scroll_child
  //   + scroll_parent_border
  //   | + scroll_parent_clip
  //   |   + scroll_parent
  //   + scroll_grandparent_border
  //     + scroll_grandparent_clip
  //       + scroll_grandparent
  //
  scoped_refptr<Layer> root = Layer::Create();
  scoped_refptr<Layer> scroll_parent_border = Layer::Create();
  scoped_refptr<Layer> scroll_parent_clip = Layer::Create();
  scoped_refptr<LayerWithForcedDrawsContent> scroll_parent =
      make_scoped_refptr(new LayerWithForcedDrawsContent);

  scoped_refptr<Layer> scroll_grandparent_border = Layer::Create();
  scoped_refptr<Layer> scroll_grandparent_clip = Layer::Create();
  scoped_refptr<LayerWithForcedDrawsContent> scroll_grandparent =
      make_scoped_refptr(new LayerWithForcedDrawsContent);

  scoped_refptr<LayerWithForcedDrawsContent> scroll_child =
      make_scoped_refptr(new LayerWithForcedDrawsContent);

  root->AddChild(scroll_child);

  root->AddChild(scroll_parent_border);
  scroll_parent_border->AddChild(scroll_parent_clip);
  scroll_parent_clip->AddChild(scroll_parent);

  root->AddChild(scroll_grandparent_border);
  scroll_grandparent_border->AddChild(scroll_grandparent_clip);
  scroll_grandparent_clip->AddChild(scroll_grandparent);

  scroll_parent_clip->SetMasksToBounds(true);
  scroll_grandparent_clip->SetMasksToBounds(true);

  scroll_child->SetScrollParent(scroll_parent.get());
  scroll_parent_border->SetScrollParent(scroll_grandparent.get());

  gfx::Transform identity_transform;
  SetLayerPropertiesForTesting(root.get(),
                               identity_transform,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(50, 50),
                               true,
                               false);
  SetLayerPropertiesForTesting(scroll_grandparent_border.get(),
                               identity_transform,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(40, 40),
                               true,
                               false);
  SetLayerPropertiesForTesting(scroll_grandparent_clip.get(),
                               identity_transform,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(20, 20),
                               true,
                               false);
  SetLayerPropertiesForTesting(scroll_grandparent.get(),
                               identity_transform,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(50, 50),
                               true,
                               false);
  SetLayerPropertiesForTesting(scroll_parent_border.get(),
                               identity_transform,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(40, 40),
                               true,
                               false);
  SetLayerPropertiesForTesting(scroll_parent_clip.get(),
                               identity_transform,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(30, 30),
                               true,
                               false);
  SetLayerPropertiesForTesting(scroll_parent.get(),
                               identity_transform,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(50, 50),
                               true,
                               false);
  SetLayerPropertiesForTesting(scroll_child.get(),
                               identity_transform,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(50, 50),
                               true,
                               false);

  scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
  host->SetRootLayer(root);

  ExecuteCalculateDrawProperties(root.get());

  EXPECT_TRUE(root->render_surface());

  EXPECT_EQ(gfx::Rect(0, 0, 20, 20).ToString(),
            scroll_child->clip_rect().ToString());
  EXPECT_TRUE(scroll_child->is_clipped());

  // Despite the fact that we visited the above layers out of order to get the
  // correct clip, the layer lists should be unaffected.
  EXPECT_EQ(3u, root->render_surface()->layer_list().size());
  EXPECT_EQ(scroll_child.get(),
            root->render_surface()->layer_list().at(0).get());
  EXPECT_EQ(scroll_parent.get(),
            root->render_surface()->layer_list().at(1).get());
  EXPECT_EQ(scroll_grandparent.get(),
            root->render_surface()->layer_list().at(2).get());
}

TEST_F(LayerTreeHostCommonTest, OutOfOrderClippingRequiresRSLLSorting) {
  // Ensures that even if we visit layers out of order, we still produce a
  // correctly ordered render surface layer list.
  // + root
  //   + scroll_child
  //   + scroll_parent_border
  //     + scroll_parent_clip
  //       + scroll_parent
  //         + render_surface1
  //   + scroll_grandparent_border
  //     + scroll_grandparent_clip
  //       + scroll_grandparent
  //         + render_surface2
  //
  scoped_refptr<LayerWithForcedDrawsContent> root =
      make_scoped_refptr(new LayerWithForcedDrawsContent);

  scoped_refptr<Layer> scroll_parent_border = Layer::Create();
  scoped_refptr<Layer> scroll_parent_clip = Layer::Create();
  scoped_refptr<LayerWithForcedDrawsContent> scroll_parent =
      make_scoped_refptr(new LayerWithForcedDrawsContent);
  scoped_refptr<LayerWithForcedDrawsContent> render_surface1 =
      make_scoped_refptr(new LayerWithForcedDrawsContent);

  scoped_refptr<Layer> scroll_grandparent_border = Layer::Create();
  scoped_refptr<Layer> scroll_grandparent_clip = Layer::Create();
  scoped_refptr<LayerWithForcedDrawsContent> scroll_grandparent =
      make_scoped_refptr(new LayerWithForcedDrawsContent);
  scoped_refptr<LayerWithForcedDrawsContent> render_surface2 =
      make_scoped_refptr(new LayerWithForcedDrawsContent);

  scoped_refptr<LayerWithForcedDrawsContent> scroll_child =
      make_scoped_refptr(new LayerWithForcedDrawsContent);

  root->AddChild(scroll_child);

  root->AddChild(scroll_parent_border);
  scroll_parent_border->AddChild(scroll_parent_clip);
  scroll_parent_clip->AddChild(scroll_parent);
  scroll_parent->AddChild(render_surface2);

  root->AddChild(scroll_grandparent_border);
  scroll_grandparent_border->AddChild(scroll_grandparent_clip);
  scroll_grandparent_clip->AddChild(scroll_grandparent);
  scroll_grandparent->AddChild(render_surface1);

  scroll_parent_clip->SetMasksToBounds(true);
  scroll_grandparent_clip->SetMasksToBounds(true);

  scroll_child->SetScrollParent(scroll_parent.get());
  scroll_parent_border->SetScrollParent(scroll_grandparent.get());

  render_surface1->SetForceRenderSurface(true);
  render_surface2->SetForceRenderSurface(true);

  gfx::Transform identity_transform;
  SetLayerPropertiesForTesting(root.get(),
                               identity_transform,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(50, 50),
                               true,
                               false);
  SetLayerPropertiesForTesting(scroll_grandparent_border.get(),
                               identity_transform,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(40, 40),
                               true,
                               false);
  SetLayerPropertiesForTesting(scroll_grandparent_clip.get(),
                               identity_transform,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(20, 20),
                               true,
                               false);
  SetLayerPropertiesForTesting(scroll_grandparent.get(),
                               identity_transform,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(50, 50),
                               true,
                               false);
  SetLayerPropertiesForTesting(render_surface1.get(),
                               identity_transform,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(50, 50),
                               true,
                               false);
  SetLayerPropertiesForTesting(scroll_parent_border.get(),
                               identity_transform,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(40, 40),
                               true,
                               false);
  SetLayerPropertiesForTesting(scroll_parent_clip.get(),
                               identity_transform,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(30, 30),
                               true,
                               false);
  SetLayerPropertiesForTesting(scroll_parent.get(),
                               identity_transform,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(50, 50),
                               true,
                               false);
  SetLayerPropertiesForTesting(render_surface2.get(),
                               identity_transform,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(50, 50),
                               true,
                               false);
  SetLayerPropertiesForTesting(scroll_child.get(),
                               identity_transform,
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(50, 50),
                               true,
                               false);

  scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
  host->SetRootLayer(root);

  RenderSurfaceLayerList render_surface_layer_list;
  LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
      root.get(),
      root->bounds(),
      identity_transform,
      &render_surface_layer_list);

  LayerTreeHostCommon::CalculateDrawProperties(&inputs);

  EXPECT_TRUE(root->render_surface());

  EXPECT_EQ(gfx::Rect(0, 0, 20, 20).ToString(),
            scroll_child->clip_rect().ToString());
  EXPECT_TRUE(scroll_child->is_clipped());

  // Despite the fact that we had to process the layers out of order to get the
  // right clip, our render_surface_layer_list's order should be unaffected.
  EXPECT_EQ(3u, render_surface_layer_list.size());
  EXPECT_EQ(root.get(), render_surface_layer_list.at(0));
  EXPECT_EQ(render_surface2.get(), render_surface_layer_list.at(1));
  EXPECT_EQ(render_surface1.get(), render_surface_layer_list.at(2));
  EXPECT_TRUE(render_surface_layer_list.at(0)->render_surface());
  EXPECT_TRUE(render_surface_layer_list.at(1)->render_surface());
  EXPECT_TRUE(render_surface_layer_list.at(2)->render_surface());
}

TEST_F(LayerTreeHostCommonTest, DoNotClobberSorting) {
  // We rearrange layer list contributions if we have to visit children out of
  // order, but it should be a 'stable' rearrangement. That is, the layer list
  // additions for a single layer should not be reordered, though their position
  // wrt to the contributions due to a sibling may vary.
  //
  // + root
  //   + scroll_child
  //     + top_content
  //     + bottom_content
  //   + scroll_parent_border
  //     + scroll_parent_clip
  //       + scroll_parent
  //
  FakeImplProxy proxy;
  TestSharedBitmapManager shared_bitmap_manager;
  FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager);
  host_impl.CreatePendingTree();
  scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl.active_tree(), 1);
  scoped_ptr<LayerImpl> scroll_parent_border =
      LayerImpl::Create(host_impl.active_tree(), 2);
  scoped_ptr<LayerImpl> scroll_parent_clip =
      LayerImpl::Create(host_impl.active_tree(), 3);
  scoped_ptr<LayerImpl> scroll_parent =
      LayerImpl::Create(host_impl.active_tree(), 4);
  scoped_ptr<LayerImpl> scroll_child =
      LayerImpl::Create(host_impl.active_tree(), 5);
  scoped_ptr<LayerImpl> bottom_content =
      LayerImpl::Create(host_impl.active_tree(), 6);
  scoped_ptr<LayerImpl> top_content =
      LayerImpl::Create(host_impl.active_tree(), 7);

  scroll_parent_clip->SetMasksToBounds(true);

  scroll_child->SetScrollParent(scroll_parent.get());
  scoped_ptr<std::set<LayerImpl*>> scroll_children(new std::set<LayerImpl*>);
  scroll_children->insert(scroll_child.get());
  scroll_parent->SetScrollChildren(scroll_children.release());

  scroll_child->SetDrawsContent(true);
  scroll_parent->SetDrawsContent(true);
  top_content->SetDrawsContent(true);
  bottom_content->SetDrawsContent(true);

  gfx::Transform identity_transform;
  gfx::Transform top_transform;
  top_transform.Translate3d(0.0, 0.0, 5.0);
  gfx::Transform bottom_transform;
  bottom_transform.Translate3d(0.0, 0.0, 3.0);

  SetLayerPropertiesForTesting(root.get(), identity_transform, gfx::Point3F(),
                               gfx::PointF(), gfx::Size(50, 50), true, false,
                               true);
  SetLayerPropertiesForTesting(scroll_parent_border.get(), identity_transform,
                               gfx::Point3F(), gfx::PointF(), gfx::Size(40, 40),
                               true, false, false);
  SetLayerPropertiesForTesting(scroll_parent_clip.get(), identity_transform,
                               gfx::Point3F(), gfx::PointF(), gfx::Size(30, 30),
                               true, false, false);
  SetLayerPropertiesForTesting(scroll_parent.get(), identity_transform,
                               gfx::Point3F(), gfx::PointF(), gfx::Size(50, 50),
                               true, false, false);
  SetLayerPropertiesForTesting(scroll_child.get(), identity_transform,
                               gfx::Point3F(), gfx::PointF(), gfx::Size(50, 50),
                               true, false, false);
  SetLayerPropertiesForTesting(top_content.get(), top_transform, gfx::Point3F(),
                               gfx::PointF(), gfx::Size(50, 50), false, true,
                               true);
  SetLayerPropertiesForTesting(bottom_content.get(), bottom_transform,
                               gfx::Point3F(), gfx::PointF(), gfx::Size(50, 50),
                               false, true, true);

  scroll_child->SetShouldFlattenTransform(false);
  scroll_child->Set3dSortingContextId(1);

  scroll_child->AddChild(top_content.Pass());
  scroll_child->AddChild(bottom_content.Pass());
  root->AddChild(scroll_child.Pass());

  scroll_parent_clip->AddChild(scroll_parent.Pass());
  scroll_parent_border->AddChild(scroll_parent_clip.Pass());
  root->AddChild(scroll_parent_border.Pass());

  LayerImplList render_surface_layer_list;
  LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
      root.get(), root->bounds(), &render_surface_layer_list);

  LayerTreeHostCommon::CalculateDrawProperties(&inputs);

  EXPECT_TRUE(root->render_surface());

  // If we don't sort by depth and let the layers get added in the order they
  // would normally be visited in, then layers 6 and 7 will be out of order. In
  // other words, although we've had to shift 5, 6, and 7 to appear before 4
  // in the list (because of the scroll parent relationship), this should not
  // have an effect on the the order of 5, 6, and 7 (which had been reordered
  // due to layer sorting).
  EXPECT_EQ(4u, root->render_surface()->layer_list().size());
  EXPECT_EQ(5, root->render_surface()->layer_list().at(0)->id());
  EXPECT_EQ(6, root->render_surface()->layer_list().at(1)->id());
  EXPECT_EQ(7, root->render_surface()->layer_list().at(2)->id());
  EXPECT_EQ(4, root->render_surface()->layer_list().at(3)->id());
}

TEST_F(LayerTreeHostCommonTest, ScrollCompensationWithRounding) {
  // This test verifies that a scrolling layer that gets snapped to
  // integer coordinates doesn't move a fixed position child.
  //
  // + root
  //   + container
  //     + scroller
  //       + fixed
  //
  FakeImplProxy proxy;
  TestSharedBitmapManager shared_bitmap_manager;
  FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager);
  host_impl.CreatePendingTree();
  scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl.active_tree(), 1);
  scoped_ptr<LayerImpl> container =
      LayerImpl::Create(host_impl.active_tree(), 2);
  LayerImpl* container_layer = container.get();
  scoped_ptr<LayerImpl> scroller =
      LayerImpl::Create(host_impl.active_tree(), 3);
  LayerImpl* scroll_layer = scroller.get();
  scoped_ptr<LayerImpl> fixed = LayerImpl::Create(host_impl.active_tree(), 4);
  LayerImpl* fixed_layer = fixed.get();

  container->SetIsContainerForFixedPositionLayers(true);

  LayerPositionConstraint constraint;
  constraint.set_is_fixed_position(true);
  fixed->SetPositionConstraint(constraint);

  scroller->SetScrollClipLayer(container->id());

  gfx::Transform identity_transform;
  gfx::Transform container_transform;
  container_transform.Translate3d(10.0, 20.0, 0.0);
  gfx::Vector2dF container_offset = container_transform.To2dTranslation();

  SetLayerPropertiesForTesting(root.get(), identity_transform, gfx::Point3F(),
                               gfx::PointF(), gfx::Size(50, 50), true, false,
                               true);
  SetLayerPropertiesForTesting(container.get(), container_transform,
                               gfx::Point3F(), gfx::PointF(), gfx::Size(40, 40),
                               true, false, false);
  SetLayerPropertiesForTesting(scroller.get(), identity_transform,
                               gfx::Point3F(), gfx::PointF(), gfx::Size(30, 30),
                               true, false, false);
  SetLayerPropertiesForTesting(fixed.get(), identity_transform, gfx::Point3F(),
                               gfx::PointF(), gfx::Size(50, 50), true, false,
                               false);

  scroller->AddChild(fixed.Pass());
  container->AddChild(scroller.Pass());
  root->AddChild(container.Pass());

  // Rounded to integers already.
  {
    gfx::Vector2dF scroll_delta(3.0, 5.0);
    scroll_layer->SetScrollDelta(scroll_delta);

    LayerImplList render_surface_layer_list;
    LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
        root.get(), root->bounds(), &render_surface_layer_list);
    LayerTreeHostCommon::CalculateDrawProperties(&inputs);

    EXPECT_TRANSFORMATION_MATRIX_EQ(
        container_layer->draw_properties().screen_space_transform,
        fixed_layer->draw_properties().screen_space_transform);
    EXPECT_VECTOR_EQ(
        fixed_layer->draw_properties().screen_space_transform.To2dTranslation(),
        container_offset);
    EXPECT_VECTOR_EQ(scroll_layer->draw_properties()
                         .screen_space_transform.To2dTranslation(),
                     container_offset - scroll_delta);
  }

  // Scroll delta requiring rounding.
  {
    gfx::Vector2dF scroll_delta(4.1f, 8.1f);
    scroll_layer->SetScrollDelta(scroll_delta);

    gfx::Vector2dF rounded_scroll_delta(4.f, 8.f);

    LayerImplList render_surface_layer_list;
    LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
        root.get(), root->bounds(), &render_surface_layer_list);
    LayerTreeHostCommon::CalculateDrawProperties(&inputs);

    EXPECT_TRANSFORMATION_MATRIX_EQ(
        container_layer->draw_properties().screen_space_transform,
        fixed_layer->draw_properties().screen_space_transform);
    EXPECT_VECTOR_EQ(
        fixed_layer->draw_properties().screen_space_transform.To2dTranslation(),
        container_offset);
    EXPECT_VECTOR_EQ(scroll_layer->draw_properties()
                         .screen_space_transform.To2dTranslation(),
                     container_offset - rounded_scroll_delta);
  }

  // Scale is applied earlier in the tree.
  {
    gfx::Transform scaled_container_transform = container_transform;
    scaled_container_transform.Scale3d(3.0, 3.0, 1.0);
    container_layer->SetTransform(scaled_container_transform);

    gfx::Vector2dF scroll_delta(4.5f, 8.5f);
    scroll_layer->SetScrollDelta(scroll_delta);

    LayerImplList render_surface_layer_list;
    LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
        root.get(), root->bounds(), &render_surface_layer_list);
    LayerTreeHostCommon::CalculateDrawProperties(&inputs);

    EXPECT_TRANSFORMATION_MATRIX_EQ(
        container_layer->draw_properties().screen_space_transform,
        fixed_layer->draw_properties().screen_space_transform);
    EXPECT_VECTOR_EQ(
        fixed_layer->draw_properties().screen_space_transform.To2dTranslation(),
        container_offset);

    container_layer->SetTransform(container_transform);
  }

  // Scale is applied on the scroll layer itself.
  {
    gfx::Transform scale_transform;
    scale_transform.Scale3d(3.0, 3.0, 1.0);
    scroll_layer->SetTransform(scale_transform);

    gfx::Vector2dF scroll_delta(4.5f, 8.5f);
    scroll_layer->SetScrollDelta(scroll_delta);

    LayerImplList render_surface_layer_list;
    LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
        root.get(), root->bounds(), &render_surface_layer_list);
    LayerTreeHostCommon::CalculateDrawProperties(&inputs);

    EXPECT_VECTOR_EQ(
        fixed_layer->draw_properties().screen_space_transform.To2dTranslation(),
        container_offset);

    scroll_layer->SetTransform(identity_transform);
  }
}

class AnimationScaleFactorTrackingLayerImpl : public LayerImpl {
 public:
  static scoped_ptr<AnimationScaleFactorTrackingLayerImpl> Create(
      LayerTreeImpl* tree_impl,
      int id) {
    return make_scoped_ptr(
        new AnimationScaleFactorTrackingLayerImpl(tree_impl, id));
  }

  ~AnimationScaleFactorTrackingLayerImpl() override {}

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

TEST_F(LayerTreeHostCommonTest, MaximumAnimationScaleFactor) {
  FakeImplProxy proxy;
  TestSharedBitmapManager shared_bitmap_manager;
  FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager);
  gfx::Transform identity_matrix;
  scoped_ptr<AnimationScaleFactorTrackingLayerImpl> grand_parent =
      AnimationScaleFactorTrackingLayerImpl::Create(host_impl.active_tree(), 1);
  scoped_ptr<AnimationScaleFactorTrackingLayerImpl> parent =
      AnimationScaleFactorTrackingLayerImpl::Create(host_impl.active_tree(), 2);
  scoped_ptr<AnimationScaleFactorTrackingLayerImpl> child =
      AnimationScaleFactorTrackingLayerImpl::Create(host_impl.active_tree(), 3);
  scoped_ptr<AnimationScaleFactorTrackingLayerImpl> grand_child =
      AnimationScaleFactorTrackingLayerImpl::Create(host_impl.active_tree(), 4);

  AnimationScaleFactorTrackingLayerImpl* parent_raw = parent.get();
  AnimationScaleFactorTrackingLayerImpl* child_raw = child.get();
  AnimationScaleFactorTrackingLayerImpl* grand_child_raw = grand_child.get();

  child->AddChild(grand_child.Pass());
  parent->AddChild(child.Pass());
  grand_parent->AddChild(parent.Pass());

  SetLayerPropertiesForTesting(grand_parent.get(), identity_matrix,
                               gfx::Point3F(), gfx::PointF(), gfx::Size(1, 2),
                               true, false, true);
  SetLayerPropertiesForTesting(parent_raw, identity_matrix, gfx::Point3F(),
                               gfx::PointF(), gfx::Size(1, 2), true, false,
                               false);
  SetLayerPropertiesForTesting(child_raw, identity_matrix, gfx::Point3F(),
                               gfx::PointF(), gfx::Size(1, 2), true, false,
                               false);

  SetLayerPropertiesForTesting(grand_child_raw, identity_matrix, gfx::Point3F(),
                               gfx::PointF(), gfx::Size(1, 2), true, false,
                               false);

  ExecuteCalculateDrawProperties(grand_parent.get());

  // No layers have animations.
  EXPECT_EQ(0.f,
            grand_parent->draw_properties().maximum_animation_contents_scale);
  EXPECT_EQ(0.f,
            parent_raw->draw_properties().maximum_animation_contents_scale);
  EXPECT_EQ(0.f, child_raw->draw_properties().maximum_animation_contents_scale);
  EXPECT_EQ(
      0.f, grand_child_raw->draw_properties().maximum_animation_contents_scale);

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

  AddAnimatedTransformToLayer(
      parent_raw, 1.0, TransformOperations(), translation);

  // No layers have scale-affecting animations.
  EXPECT_EQ(0.f,
            grand_parent->draw_properties().maximum_animation_contents_scale);
  EXPECT_EQ(0.f,
            parent_raw->draw_properties().maximum_animation_contents_scale);
  EXPECT_EQ(0.f, child_raw->draw_properties().maximum_animation_contents_scale);
  EXPECT_EQ(
      0.f, grand_child_raw->draw_properties().maximum_animation_contents_scale);

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

  AddAnimatedTransformToLayer(child_raw, 1.0, TransformOperations(), scale);
  ExecuteCalculateDrawProperties(grand_parent.get());

  // Only |child| has a scale-affecting animation.
  EXPECT_EQ(0.f,
            grand_parent->draw_properties().maximum_animation_contents_scale);
  EXPECT_EQ(0.f,
            parent_raw->draw_properties().maximum_animation_contents_scale);
  EXPECT_EQ(5.f, child_raw->draw_properties().maximum_animation_contents_scale);
  EXPECT_EQ(
      5.f, grand_child_raw->draw_properties().maximum_animation_contents_scale);

  AddAnimatedTransformToLayer(
      grand_parent.get(), 1.0, TransformOperations(), scale);
  ExecuteCalculateDrawProperties(grand_parent.get());

  // |grand_parent| and |child| have scale-affecting animations.
  EXPECT_EQ(5.f,
            grand_parent->draw_properties().maximum_animation_contents_scale);
  EXPECT_EQ(5.f,
            parent_raw->draw_properties().maximum_animation_contents_scale);
  // We don't support combining animated scales from two nodes; 0.f means
  // that the maximum scale could not be computed.
  EXPECT_EQ(0.f, child_raw->draw_properties().maximum_animation_contents_scale);
  EXPECT_EQ(
      0.f, grand_child_raw->draw_properties().maximum_animation_contents_scale);

  AddAnimatedTransformToLayer(parent_raw, 1.0, TransformOperations(), scale);
  ExecuteCalculateDrawProperties(grand_parent.get());

  // |grand_parent|, |parent|, and |child| have scale-affecting animations.
  EXPECT_EQ(5.f,
            grand_parent->draw_properties().maximum_animation_contents_scale);
  EXPECT_EQ(0.f,
            parent_raw->draw_properties().maximum_animation_contents_scale);
  EXPECT_EQ(0.f, child_raw->draw_properties().maximum_animation_contents_scale);
  EXPECT_EQ(
      0.f, grand_child_raw->draw_properties().maximum_animation_contents_scale);

  grand_parent->layer_animation_controller()->AbortAnimations(
      Animation::Transform);
  parent_raw->layer_animation_controller()->AbortAnimations(
      Animation::Transform);
  child_raw->layer_animation_controller()->AbortAnimations(
      Animation::Transform);

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

  AddAnimatedTransformToLayer(
      child_raw, 1.0, TransformOperations(), perspective);
  ExecuteCalculateDrawProperties(grand_parent.get());

  // |child| has a scale-affecting animation but computing the maximum of this
  // animation is not supported.
  EXPECT_EQ(0.f,
            grand_parent->draw_properties().maximum_animation_contents_scale);
  EXPECT_EQ(0.f,
            parent_raw->draw_properties().maximum_animation_contents_scale);
  EXPECT_EQ(0.f, child_raw->draw_properties().maximum_animation_contents_scale);
  EXPECT_EQ(
      0.f, grand_child_raw->draw_properties().maximum_animation_contents_scale);

  child_raw->layer_animation_controller()->AbortAnimations(
      Animation::Transform);

  gfx::Transform scale_matrix;
  scale_matrix.Scale(1.f, 2.f);
  grand_parent->SetTransform(scale_matrix);
  parent_raw->SetTransform(scale_matrix);
  AddAnimatedTransformToLayer(parent_raw, 1.0, TransformOperations(), scale);
  ExecuteCalculateDrawProperties(grand_parent.get());

  // |grand_parent| and |parent| each have scale 2.f. |parent| has a  scale
  // animation with maximum scale 5.f.
  EXPECT_EQ(0.f,
            grand_parent->draw_properties().maximum_animation_contents_scale);
  EXPECT_EQ(10.f,
            parent_raw->draw_properties().maximum_animation_contents_scale);
  EXPECT_EQ(10.f,
            child_raw->draw_properties().maximum_animation_contents_scale);
  EXPECT_EQ(
      10.f,
      grand_child_raw->draw_properties().maximum_animation_contents_scale);

  gfx::Transform perspective_matrix;
  perspective_matrix.ApplyPerspectiveDepth(2.f);
  child_raw->SetTransform(perspective_matrix);
  ExecuteCalculateDrawProperties(grand_parent.get());

  // |child| has a transform that's neither a translation nor a scale.
  EXPECT_EQ(0.f,
            grand_parent->draw_properties().maximum_animation_contents_scale);
  EXPECT_EQ(10.f,
            parent_raw->draw_properties().maximum_animation_contents_scale);
  EXPECT_EQ(0.f, child_raw->draw_properties().maximum_animation_contents_scale);
  EXPECT_EQ(
      0.f, grand_child_raw->draw_properties().maximum_animation_contents_scale);

  parent_raw->SetTransform(perspective_matrix);
  ExecuteCalculateDrawProperties(grand_parent.get());

  // |parent| and |child| have transforms that are neither translations nor
  // scales.
  EXPECT_EQ(0.f,
            grand_parent->draw_properties().maximum_animation_contents_scale);
  EXPECT_EQ(0.f,
            parent_raw->draw_properties().maximum_animation_contents_scale);
  EXPECT_EQ(0.f, child_raw->draw_properties().maximum_animation_contents_scale);
  EXPECT_EQ(
      0.f, grand_child_raw->draw_properties().maximum_animation_contents_scale);

  parent_raw->SetTransform(identity_matrix);
  child_raw->SetTransform(identity_matrix);
  grand_parent->SetTransform(perspective_matrix);

  ExecuteCalculateDrawProperties(grand_parent.get());

  // |grand_parent| has a transform that's neither a translation nor a scale.
  EXPECT_EQ(0.f,
            grand_parent->draw_properties().maximum_animation_contents_scale);
  EXPECT_EQ(0.f,
            parent_raw->draw_properties().maximum_animation_contents_scale);
  EXPECT_EQ(0.f, child_raw->draw_properties().maximum_animation_contents_scale);
  EXPECT_EQ(
      0.f, grand_child_raw->draw_properties().maximum_animation_contents_scale);
}

static int membership_id(LayerImpl* layer) {
  return layer->draw_properties().last_drawn_render_surface_layer_list_id;
}

static void GatherDrawnLayers(LayerImplList* rsll,
                              std::set<LayerImpl*>* drawn_layers) {
  for (LayerIterator<LayerImpl> it = LayerIterator<LayerImpl>::Begin(rsll),
                                end = LayerIterator<LayerImpl>::End(rsll);
       it != end;
       ++it) {
    LayerImpl* layer = *it;
    if (it.represents_itself())
      drawn_layers->insert(layer);

    if (!it.represents_contributing_render_surface())
      continue;

    if (layer->mask_layer())
      drawn_layers->insert(layer->mask_layer());
    if (layer->replica_layer() && layer->replica_layer()->mask_layer())
      drawn_layers->insert(layer->replica_layer()->mask_layer());
  }
}

TEST_F(LayerTreeHostCommonTest, RenderSurfaceLayerListMembership) {
  FakeImplProxy proxy;
  TestSharedBitmapManager shared_bitmap_manager;
  FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager);
  gfx::Transform identity_matrix;

  scoped_ptr<LayerImpl> grand_parent =
      LayerImpl::Create(host_impl.active_tree(), 1);
  scoped_ptr<LayerImpl> parent = LayerImpl::Create(host_impl.active_tree(), 3);
  scoped_ptr<LayerImpl> child = LayerImpl::Create(host_impl.active_tree(), 5);
  scoped_ptr<LayerImpl> grand_child1 =
      LayerImpl::Create(host_impl.active_tree(), 7);
  scoped_ptr<LayerImpl> grand_child2 =
      LayerImpl::Create(host_impl.active_tree(), 9);

  LayerImpl* grand_parent_raw = grand_parent.get();
  LayerImpl* parent_raw = parent.get();
  LayerImpl* child_raw = child.get();
  LayerImpl* grand_child1_raw = grand_child1.get();
  LayerImpl* grand_child2_raw = grand_child2.get();

  child->AddChild(grand_child1.Pass());
  child->AddChild(grand_child2.Pass());
  parent->AddChild(child.Pass());
  grand_parent->AddChild(parent.Pass());

  SetLayerPropertiesForTesting(grand_parent_raw, identity_matrix,
                               gfx::Point3F(), gfx::PointF(), gfx::Size(1, 2),
                               true, false, true);
  SetLayerPropertiesForTesting(parent_raw, identity_matrix, gfx::Point3F(),
                               gfx::PointF(), gfx::Size(1, 2), true, false,
                               false);

  SetLayerPropertiesForTesting(child_raw, identity_matrix, gfx::Point3F(),
                               gfx::PointF(), gfx::Size(1, 2), true, false,
                               false);

  SetLayerPropertiesForTesting(grand_child1_raw, identity_matrix,
                               gfx::Point3F(), gfx::PointF(), gfx::Size(1, 2),
                               true, false, false);

  SetLayerPropertiesForTesting(grand_child2_raw, identity_matrix,
                               gfx::Point3F(), gfx::PointF(), gfx::Size(1, 2),
                               true, false, false);

  // Start with nothing being drawn.
  ExecuteCalculateDrawProperties(grand_parent_raw);
  int member_id = render_surface_layer_list_count();

  EXPECT_NE(member_id, membership_id(grand_parent_raw));
  EXPECT_NE(member_id, membership_id(parent_raw));
  EXPECT_NE(member_id, membership_id(child_raw));
  EXPECT_NE(member_id, membership_id(grand_child1_raw));
  EXPECT_NE(member_id, membership_id(grand_child2_raw));

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

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

  ExecuteCalculateDrawProperties(grand_parent_raw);
  member_id = render_surface_layer_list_count();

  EXPECT_NE(member_id, membership_id(grand_parent_raw));
  EXPECT_NE(member_id, membership_id(parent_raw));
  EXPECT_NE(member_id, membership_id(child_raw));
  EXPECT_NE(member_id, membership_id(grand_child1_raw));
  EXPECT_NE(member_id, membership_id(grand_child2_raw));

  expected.clear();
  actual.clear();
  GatherDrawnLayers(render_surface_layer_list_impl(), &actual);
  EXPECT_EQ(expected, actual);

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

  ExecuteCalculateDrawProperties(grand_parent_raw);
  member_id = render_surface_layer_list_count();

  EXPECT_NE(member_id, membership_id(grand_parent_raw));
  EXPECT_NE(member_id, membership_id(parent_raw));
  EXPECT_NE(member_id, membership_id(child_raw));
  EXPECT_EQ(member_id, membership_id(grand_child1_raw));
  EXPECT_NE(member_id, membership_id(grand_child2_raw));

  expected.clear();
  expected.insert(grand_child1_raw);

  actual.clear();
  GatherDrawnLayers(render_surface_layer_list_impl(), &actual);
  EXPECT_EQ(expected, actual);

  // Now child is forced to have a render surface, and one if its children draws
  // content.
  grand_child1_raw->SetDrawsContent(false);
  grand_child1_raw->SetHasRenderSurface(false);
  child_raw->SetHasRenderSurface(true);
  grand_child2_raw->SetDrawsContent(true);

  ExecuteCalculateDrawProperties(grand_parent_raw);
  member_id = render_surface_layer_list_count();

  EXPECT_NE(member_id, membership_id(grand_parent_raw));
  EXPECT_NE(member_id, membership_id(parent_raw));
  EXPECT_NE(member_id, membership_id(child_raw));
  EXPECT_NE(member_id, membership_id(grand_child1_raw));
  EXPECT_EQ(member_id, membership_id(grand_child2_raw));

  expected.clear();
  expected.insert(grand_child2_raw);

  actual.clear();
  GatherDrawnLayers(render_surface_layer_list_impl(), &actual);
  EXPECT_EQ(expected, actual);

  // Add a mask layer to child.
  child_raw->SetMaskLayer(LayerImpl::Create(host_impl.active_tree(), 6).Pass());

  ExecuteCalculateDrawProperties(grand_parent_raw);
  member_id = render_surface_layer_list_count();

  EXPECT_NE(member_id, membership_id(grand_parent_raw));
  EXPECT_NE(member_id, membership_id(parent_raw));
  EXPECT_NE(member_id, membership_id(child_raw));
  EXPECT_EQ(member_id, membership_id(child_raw->mask_layer()));
  EXPECT_NE(member_id, membership_id(grand_child1_raw));
  EXPECT_EQ(member_id, membership_id(grand_child2_raw));

  expected.clear();
  expected.insert(grand_child2_raw);
  expected.insert(child_raw->mask_layer());

  expected.clear();
  expected.insert(grand_child2_raw);
  expected.insert(child_raw->mask_layer());

  actual.clear();
  GatherDrawnLayers(render_surface_layer_list_impl(), &actual);
  EXPECT_EQ(expected, actual);

  // Add replica mask layer.
  scoped_ptr<LayerImpl> replica_layer =
      LayerImpl::Create(host_impl.active_tree(), 20);
  replica_layer->SetMaskLayer(LayerImpl::Create(host_impl.active_tree(), 21));
  child_raw->SetReplicaLayer(replica_layer.Pass());

  ExecuteCalculateDrawProperties(grand_parent_raw);
  member_id = render_surface_layer_list_count();

  EXPECT_NE(member_id, membership_id(grand_parent_raw));
  EXPECT_NE(member_id, membership_id(parent_raw));
  EXPECT_NE(member_id, membership_id(child_raw));
  EXPECT_EQ(member_id, membership_id(child_raw->mask_layer()));
  EXPECT_EQ(member_id, membership_id(child_raw->replica_layer()->mask_layer()));
  EXPECT_NE(member_id, membership_id(grand_child1_raw));
  EXPECT_EQ(member_id, membership_id(grand_child2_raw));

  expected.clear();
  expected.insert(grand_child2_raw);
  expected.insert(child_raw->mask_layer());
  expected.insert(child_raw->replica_layer()->mask_layer());

  actual.clear();
  GatherDrawnLayers(render_surface_layer_list_impl(), &actual);
  EXPECT_EQ(expected, actual);

  child_raw->TakeReplicaLayer();

  // With nothing drawing, we should have no layers.
  grand_child2_raw->SetDrawsContent(false);

  ExecuteCalculateDrawProperties(grand_parent_raw);
  member_id = render_surface_layer_list_count();

  EXPECT_NE(member_id, membership_id(grand_parent_raw));
  EXPECT_NE(member_id, membership_id(parent_raw));
  EXPECT_NE(member_id, membership_id(child_raw));
  EXPECT_NE(member_id, membership_id(child_raw->mask_layer()));
  EXPECT_NE(member_id, membership_id(grand_child1_raw));
  EXPECT_NE(member_id, membership_id(grand_child2_raw));

  expected.clear();
  actual.clear();
  GatherDrawnLayers(render_surface_layer_list_impl(), &actual);
  EXPECT_EQ(expected, actual);

  // Child itself draws means that we should have the child and the mask in the
  // list.
  child_raw->SetDrawsContent(true);

  ExecuteCalculateDrawProperties(grand_parent_raw);
  member_id = render_surface_layer_list_count();

  EXPECT_NE(member_id, membership_id(grand_parent_raw));
  EXPECT_NE(member_id, membership_id(parent_raw));
  EXPECT_EQ(member_id, membership_id(child_raw));
  EXPECT_EQ(member_id, membership_id(child_raw->mask_layer()));
  EXPECT_NE(member_id, membership_id(grand_child1_raw));
  EXPECT_NE(member_id, membership_id(grand_child2_raw));

  expected.clear();
  expected.insert(child_raw);
  expected.insert(child_raw->mask_layer());
  actual.clear();
  GatherDrawnLayers(render_surface_layer_list_impl(), &actual);
  EXPECT_EQ(expected, actual);

  child_raw->TakeMaskLayer();

  // Now everyone's a member!
  grand_parent_raw->SetDrawsContent(true);
  parent_raw->SetDrawsContent(true);
  child_raw->SetDrawsContent(true);
  grand_child1_raw->SetDrawsContent(true);
  grand_child2_raw->SetDrawsContent(true);

  ExecuteCalculateDrawProperties(grand_parent_raw);
  member_id = render_surface_layer_list_count();

  EXPECT_EQ(member_id, membership_id(grand_parent_raw));
  EXPECT_EQ(member_id, membership_id(parent_raw));
  EXPECT_EQ(member_id, membership_id(child_raw));
  EXPECT_EQ(member_id, membership_id(grand_child1_raw));
  EXPECT_EQ(member_id, membership_id(grand_child2_raw));

  expected.clear();
  expected.insert(grand_parent_raw);
  expected.insert(parent_raw);
  expected.insert(child_raw);
  expected.insert(grand_child1_raw);
  expected.insert(grand_child2_raw);

  actual.clear();
  GatherDrawnLayers(render_surface_layer_list_impl(), &actual);
  EXPECT_EQ(expected, actual);
}

TEST_F(LayerTreeHostCommonTest, DrawPropertyScales) {
  FakeImplProxy proxy;
  TestSharedBitmapManager shared_bitmap_manager;
  FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager);

  scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl.active_tree(), 1);
  LayerImpl* root_layer = root.get();
  scoped_ptr<LayerImpl> child1 = LayerImpl::Create(host_impl.active_tree(), 2);
  LayerImpl* child1_layer = child1.get();
  scoped_ptr<LayerImpl> child2 = LayerImpl::Create(host_impl.active_tree(), 3);
  LayerImpl* child2_layer = child2.get();

  root->AddChild(child1.Pass());
  root->AddChild(child2.Pass());
  root->SetHasRenderSurface(true);

  gfx::Transform identity_matrix, scale_transform_child1,
      scale_transform_child2;
  scale_transform_child1.Scale(2, 3);
  scale_transform_child2.Scale(4, 5);

  SetLayerPropertiesForTesting(root_layer, identity_matrix, gfx::Point3F(),
                               gfx::PointF(), gfx::Size(1, 1), true, false,
                               true);
  SetLayerPropertiesForTesting(child1_layer, scale_transform_child1,
                               gfx::Point3F(), gfx::PointF(), gfx::Size(), true,
                               false, false);

  child1_layer->SetMaskLayer(
      LayerImpl::Create(host_impl.active_tree(), 4).Pass());

  scoped_ptr<LayerImpl> replica_layer =
      LayerImpl::Create(host_impl.active_tree(), 5);
  replica_layer->SetHasRenderSurface(true);
  replica_layer->SetMaskLayer(LayerImpl::Create(host_impl.active_tree(), 6));
  child1_layer->SetReplicaLayer(replica_layer.Pass());
  child1_layer->SetHasRenderSurface(true);

  ExecuteCalculateDrawProperties(root_layer);

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

  AddAnimatedTransformToLayer(child2_layer, 1.0, TransformOperations(), scale);
  SetLayerPropertiesForTesting(child2_layer, scale_transform_child2,
                               gfx::Point3F(), gfx::PointF(), gfx::Size(), true,
                               false, false);

  ExecuteCalculateDrawProperties(root_layer);

  EXPECT_FLOAT_EQ(1.f, root_layer->draw_properties().ideal_contents_scale);
  EXPECT_FLOAT_EQ(3.f, child1_layer->draw_properties().ideal_contents_scale);
  EXPECT_FLOAT_EQ(
      3.f, child1_layer->mask_layer()->draw_properties().ideal_contents_scale);
  EXPECT_FLOAT_EQ(3.f,
                  child1_layer->replica_layer()
                      ->mask_layer()
                      ->draw_properties()
                      .ideal_contents_scale);
  EXPECT_FLOAT_EQ(5.f, child2_layer->draw_properties().ideal_contents_scale);

  EXPECT_FLOAT_EQ(
      0.f, root_layer->draw_properties().maximum_animation_contents_scale);
  EXPECT_FLOAT_EQ(
      0.f, child1_layer->draw_properties().maximum_animation_contents_scale);
  EXPECT_FLOAT_EQ(0.f,
                  child1_layer->mask_layer()
                      ->draw_properties()
                      .maximum_animation_contents_scale);
  EXPECT_FLOAT_EQ(0.f,
                  child1_layer->replica_layer()
                      ->mask_layer()
                      ->draw_properties()
                      .maximum_animation_contents_scale);
  EXPECT_FLOAT_EQ(
      8.f, child2_layer->draw_properties().maximum_animation_contents_scale);

  EXPECT_FLOAT_EQ(1.f, root_layer->draw_properties().page_scale_factor);
  EXPECT_FLOAT_EQ(1.f, child1_layer->draw_properties().page_scale_factor);
  EXPECT_FLOAT_EQ(
      1.f, child1_layer->mask_layer()->draw_properties().page_scale_factor);
  EXPECT_FLOAT_EQ(1.f,
                  child1_layer->replica_layer()
                      ->mask_layer()
                      ->draw_properties()
                      .page_scale_factor);
  EXPECT_FLOAT_EQ(1.f, child2_layer->draw_properties().page_scale_factor);

  EXPECT_FLOAT_EQ(1.f, root_layer->draw_properties().device_scale_factor);
  EXPECT_FLOAT_EQ(1.f, child1_layer->draw_properties().device_scale_factor);
  EXPECT_FLOAT_EQ(
      1.f, child1_layer->mask_layer()->draw_properties().device_scale_factor);
  EXPECT_FLOAT_EQ(1.f,
                  child1_layer->replica_layer()
                      ->mask_layer()
                      ->draw_properties()
                      .device_scale_factor);
  EXPECT_FLOAT_EQ(1.f, child2_layer->draw_properties().device_scale_factor);

  // Changing page-scale would affect ideal_contents_scale and
  // maximum_animation_contents_scale.

  float page_scale_factor = 3.f;
  float device_scale_factor = 1.0f;
  std::vector<LayerImpl*> render_surface_layer_list;
  gfx::Size device_viewport_size =
      gfx::Size(root_layer->bounds().width() * device_scale_factor,
                root_layer->bounds().height() * device_scale_factor);
  LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
      root_layer, device_viewport_size, &render_surface_layer_list);

  inputs.page_scale_factor = page_scale_factor;
  inputs.can_adjust_raster_scales = true;
  inputs.page_scale_application_layer = root_layer;
  LayerTreeHostCommon::CalculateDrawProperties(&inputs);

  EXPECT_FLOAT_EQ(1.f, root_layer->draw_properties().ideal_contents_scale);
  EXPECT_FLOAT_EQ(9.f, child1_layer->draw_properties().ideal_contents_scale);
  EXPECT_FLOAT_EQ(
      9.f, child1_layer->mask_layer()->draw_properties().ideal_contents_scale);
  EXPECT_FLOAT_EQ(9.f,
                  child1_layer->replica_layer()
                      ->mask_layer()
                      ->draw_properties()
                      .ideal_contents_scale);
  EXPECT_FLOAT_EQ(15.f, child2_layer->draw_properties().ideal_contents_scale);

  EXPECT_FLOAT_EQ(
      0.f, root_layer->draw_properties().maximum_animation_contents_scale);
  EXPECT_FLOAT_EQ(
      0.f, child1_layer->draw_properties().maximum_animation_contents_scale);
  EXPECT_FLOAT_EQ(0.f,
                  child1_layer->mask_layer()
                      ->draw_properties()
                      .maximum_animation_contents_scale);
  EXPECT_FLOAT_EQ(0.f,
                  child1_layer->replica_layer()
                      ->mask_layer()
                      ->draw_properties()
                      .maximum_animation_contents_scale);
  EXPECT_FLOAT_EQ(
      24.f, child2_layer->draw_properties().maximum_animation_contents_scale);

  EXPECT_FLOAT_EQ(1.f, root_layer->draw_properties().page_scale_factor);
  EXPECT_FLOAT_EQ(3.f, child1_layer->draw_properties().page_scale_factor);
  EXPECT_FLOAT_EQ(
      3.f, child1_layer->mask_layer()->draw_properties().page_scale_factor);
  EXPECT_FLOAT_EQ(3.f,
                  child1_layer->replica_layer()
                      ->mask_layer()
                      ->draw_properties()
                      .page_scale_factor);
  EXPECT_FLOAT_EQ(3.f, child2_layer->draw_properties().page_scale_factor);

  EXPECT_FLOAT_EQ(1.f, root_layer->draw_properties().device_scale_factor);
  EXPECT_FLOAT_EQ(1.f, child1_layer->draw_properties().device_scale_factor);
  EXPECT_FLOAT_EQ(
      1.f, child1_layer->mask_layer()->draw_properties().device_scale_factor);
  EXPECT_FLOAT_EQ(1.f,
                  child1_layer->replica_layer()
                      ->mask_layer()
                      ->draw_properties()
                      .device_scale_factor);
  EXPECT_FLOAT_EQ(1.f, child2_layer->draw_properties().device_scale_factor);

  // Changing device-scale would affect ideal_contents_scale and
  // maximum_animation_contents_scale.

  device_scale_factor = 4.0f;
  inputs.device_scale_factor = device_scale_factor;
  inputs.can_adjust_raster_scales = true;
  LayerTreeHostCommon::CalculateDrawProperties(&inputs);

  EXPECT_FLOAT_EQ(4.f, root_layer->draw_properties().ideal_contents_scale);
  EXPECT_FLOAT_EQ(36.f, child1_layer->draw_properties().ideal_contents_scale);
  EXPECT_FLOAT_EQ(
      36.f, child1_layer->mask_layer()->draw_properties().ideal_contents_scale);
  EXPECT_FLOAT_EQ(36.f,
                  child1_layer->replica_layer()
                      ->mask_layer()
                      ->draw_properties()
                      .ideal_contents_scale);
  EXPECT_FLOAT_EQ(60.f, child2_layer->draw_properties().ideal_contents_scale);

  EXPECT_FLOAT_EQ(
      0.f, root_layer->draw_properties().maximum_animation_contents_scale);
  EXPECT_FLOAT_EQ(
      0.f, child1_layer->draw_properties().maximum_animation_contents_scale);
  EXPECT_FLOAT_EQ(0.f,
                  child1_layer->mask_layer()
                      ->draw_properties()
                      .maximum_animation_contents_scale);
  EXPECT_FLOAT_EQ(0.f,
                  child1_layer->replica_layer()
                      ->mask_layer()
                      ->draw_properties()
                      .maximum_animation_contents_scale);
  EXPECT_FLOAT_EQ(
      96.f, child2_layer->draw_properties().maximum_animation_contents_scale);

  EXPECT_FLOAT_EQ(1.f, root_layer->draw_properties().page_scale_factor);
  EXPECT_FLOAT_EQ(3.f, child1_layer->draw_properties().page_scale_factor);
  EXPECT_FLOAT_EQ(
      3.f, child1_layer->mask_layer()->draw_properties().page_scale_factor);
  EXPECT_FLOAT_EQ(3.f,
                  child1_layer->replica_layer()
                      ->mask_layer()
                      ->draw_properties()
                      .page_scale_factor);
  EXPECT_FLOAT_EQ(3.f, child2_layer->draw_properties().page_scale_factor);

  EXPECT_FLOAT_EQ(4.f, root_layer->draw_properties().device_scale_factor);
  EXPECT_FLOAT_EQ(4.f, child1_layer->draw_properties().device_scale_factor);
  EXPECT_FLOAT_EQ(
      4.f, child1_layer->mask_layer()->draw_properties().device_scale_factor);
  EXPECT_FLOAT_EQ(4.f,
                  child1_layer->replica_layer()
                      ->mask_layer()
                      ->draw_properties()
                      .device_scale_factor);
  EXPECT_FLOAT_EQ(4.f, child2_layer->draw_properties().device_scale_factor);
}

TEST_F(LayerTreeHostCommonTest, VisibleContentRectInChildRenderSurface) {
  scoped_refptr<Layer> root = Layer::Create();
  SetLayerPropertiesForTesting(root.get(),
                               gfx::Transform(),
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(768 / 2, 3000),
                               true,
                               false);
  root->SetIsDrawable(true);

  scoped_refptr<Layer> clip = Layer::Create();
  SetLayerPropertiesForTesting(clip.get(),
                               gfx::Transform(),
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(768 / 2, 10000),
                               true,
                               false);
  clip->SetMasksToBounds(true);

  scoped_refptr<Layer> content = Layer::Create();
  SetLayerPropertiesForTesting(content.get(),
                               gfx::Transform(),
                               gfx::Point3F(),
                               gfx::PointF(),
                               gfx::Size(768 / 2, 10000),
                               true,
                               false);
  content->SetIsDrawable(true);
  content->SetForceRenderSurface(true);

  root->AddChild(clip);
  clip->AddChild(content);

  FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
  scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(&client);
  host->SetRootLayer(root);

  gfx::Size device_viewport_size(768, 582);
  RenderSurfaceLayerList render_surface_layer_list;
  LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
      host->root_layer(), device_viewport_size, &render_surface_layer_list);
  inputs.device_scale_factor = 2.f;
  inputs.page_scale_factor = 1.f;
  inputs.page_scale_application_layer = NULL;
  LayerTreeHostCommon::CalculateDrawProperties(&inputs);

  // Layers in the root render surface have their visible content rect clipped
  // by the viewport.
  EXPECT_EQ(gfx::Rect(768 / 2, 582 / 2), root->visible_content_rect());

  // Layers drawing to a child render surface should still have their visible
  // content rect clipped by the viewport.
  EXPECT_EQ(gfx::Rect(768 / 2, 582 / 2), content->visible_content_rect());
}

TEST_F(LayerTreeHostCommonTest, BoundsDeltaAffectVisibleContentRect) {
  FakeImplProxy proxy;
  TestSharedBitmapManager shared_bitmap_manager;
  FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager);

  // Set two layers: the root layer clips it's child,
  // the child draws its content.

  gfx::Size root_size = gfx::Size(300, 500);

  // Sublayer should be bigger than the root enlarged by bounds_delta.
  gfx::Size sublayer_size = gfx::Size(300, 1000);

  // Device viewport accomidated the root and the top controls.
  gfx::Size device_viewport_size = gfx::Size(300, 600);
  gfx::Transform identity_matrix;

  host_impl.active_tree()->SetRootLayer(
      LayerImpl::Create(host_impl.active_tree(), 1));

  LayerImpl* root = host_impl.active_tree()->root_layer();
  SetLayerPropertiesForTesting(root,
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               root_size,
                               false,
                               false,
                               true);

  root->SetContentBounds(root_size);
  root->SetMasksToBounds(true);

  root->AddChild(LayerImpl::Create(host_impl.active_tree(), 2));

  LayerImpl* sublayer = root->child_at(0);
  SetLayerPropertiesForTesting(sublayer,
                               identity_matrix,
                               gfx::Point3F(),
                               gfx::PointF(),
                               sublayer_size,
                               false,
                               false,
                               false);

  sublayer->SetContentBounds(sublayer_size);
  sublayer->SetDrawsContent(true);

  LayerImplList layer_impl_list;
  LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
      root, device_viewport_size, &layer_impl_list);

  LayerTreeHostCommon::CalculateDrawProperties(&inputs);

  EXPECT_EQ(gfx::Rect(root_size), sublayer->visible_content_rect());

  root->SetBoundsDelta(gfx::Vector2dF(0.0, 50.0));

  LayerTreeHostCommon::CalculateDrawProperties(&inputs);

  gfx::Rect affected_by_delta(0, 0, root_size.width(),
                              root_size.height() + 50);
  EXPECT_EQ(affected_by_delta, sublayer->visible_content_rect());
}

}  // namespace
}  // namespace cc
