Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / cc / layers / layer_impl_unittest.cc
index f38809f..7aea7c7 100644 (file)
@@ -10,6 +10,7 @@
 #include "cc/test/fake_layer_tree_host_impl.h"
 #include "cc/test/fake_output_surface.h"
 #include "cc/test/geometry_test_utils.h"
+#include "cc/test/test_shared_bitmap_manager.h"
 #include "cc/trees/layer_tree_impl.h"
 #include "cc/trees/single_thread_proxy.h"
 #include "testing/gmock/include/gmock/gmock.h"
@@ -60,16 +61,6 @@ namespace {
   EXPECT_FALSE(child->LayerPropertyChanged());                                 \
   EXPECT_FALSE(grand_child->LayerPropertyChanged());
 
-#define EXECUTE_AND_VERIFY_ONLY_DESCENDANTS_CHANGED(code_to_test)              \
-  root->ResetAllChangeTrackingForSubtree();                                    \
-  code_to_test;                                                                \
-  EXPECT_TRUE(root->needs_push_properties());                                  \
-  EXPECT_FALSE(child->needs_push_properties());                                \
-  EXPECT_FALSE(grand_child->needs_push_properties());                          \
-  EXPECT_FALSE(root->LayerPropertyChanged());                                  \
-  EXPECT_TRUE(child->LayerPropertyChanged());                                  \
-  EXPECT_TRUE(grand_child->LayerPropertyChanged());
-
 #define VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(code_to_test)                      \
   root->ResetAllChangeTrackingForSubtree();                                    \
   host_impl.ForcePrepareToDraw();                                              \
@@ -92,30 +83,36 @@ TEST(LayerImplTest, VerifyLayerChangesAreTrackedProperly) {
   // The constructor on this will fake that we are on the correct thread.
   // Create a simple LayerImpl tree:
   FakeImplProxy proxy;
-  FakeLayerTreeHostImpl host_impl(&proxy);
-  EXPECT_TRUE(host_impl.InitializeRenderer(CreateFakeOutputSurface()));
-  scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl.active_tree(), 1);
-
-  scoped_ptr<LayerImpl> scroll_parent =
+  TestSharedBitmapManager shared_bitmap_manager;
+  FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager);
+  EXPECT_TRUE(host_impl.InitializeRenderer(
+      FakeOutputSurface::Create3d().PassAs<OutputSurface>()));
+  scoped_ptr<LayerImpl> root_clip =
+      LayerImpl::Create(host_impl.active_tree(), 1);
+  scoped_ptr<LayerImpl> root_ptr =
       LayerImpl::Create(host_impl.active_tree(), 2);
-  LayerImpl* scroll_child = LayerImpl::Create(host_impl.active_tree(), 3).get();
+  LayerImpl* root = root_ptr.get();
+  root_clip->AddChild(root_ptr.Pass());
+  scoped_ptr<LayerImpl> scroll_parent =
+      LayerImpl::Create(host_impl.active_tree(), 3);
+  LayerImpl* scroll_child = LayerImpl::Create(host_impl.active_tree(), 4).get();
   std::set<LayerImpl*>* scroll_children = new std::set<LayerImpl*>();
   scroll_children->insert(scroll_child);
-  scroll_children->insert(root.get());
+  scroll_children->insert(root);
 
   scoped_ptr<LayerImpl> clip_parent =
-      LayerImpl::Create(host_impl.active_tree(), 4);
-  LayerImpl* clip_child = LayerImpl::Create(host_impl.active_tree(), 5).get();
+      LayerImpl::Create(host_impl.active_tree(), 5);
+  LayerImpl* clip_child = LayerImpl::Create(host_impl.active_tree(), 6).get();
   std::set<LayerImpl*>* clip_children = new std::set<LayerImpl*>();
   clip_children->insert(clip_child);
-  clip_children->insert(root.get());
+  clip_children->insert(root);
 
-  root->AddChild(LayerImpl::Create(host_impl.active_tree(), 6));
+  root->AddChild(LayerImpl::Create(host_impl.active_tree(), 7));
   LayerImpl* child = root->children()[0];
-  child->AddChild(LayerImpl::Create(host_impl.active_tree(), 7));
+  child->AddChild(LayerImpl::Create(host_impl.active_tree(), 8));
   LayerImpl* grand_child = child->children()[0];
 
-  root->SetScrollable(true);
+  root->SetScrollClipLayer(root_clip->id());
 
   // Adding children is an internal operation and should not mark layers as
   // changed.
@@ -142,8 +139,7 @@ TEST(LayerImplTest, VerifyLayerChangesAreTrackedProperly) {
   // they are used.
   EXECUTE_AND_VERIFY_NEEDS_PUSH_PROPERTIES_AND_SUBTREE_DID_NOT_CHANGE(
       root->SetUpdateRect(arbitrary_rect_f));
-  EXECUTE_AND_VERIFY_NEEDS_PUSH_PROPERTIES_AND_SUBTREE_DID_NOT_CHANGE(
-      root->SetMaxScrollOffset(arbitrary_vector2d));
+  EXECUTE_AND_VERIFY_ONLY_LAYER_CHANGED(root->SetBounds(arbitrary_size));
 
   // Changing these properties affects the entire subtree of layers.
   EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetAnchorPoint(arbitrary_point_f));
@@ -151,13 +147,14 @@ TEST(LayerImplTest, VerifyLayerChangesAreTrackedProperly) {
   EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetFilters(arbitrary_filters));
   EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetFilters(FilterOperations()));
   EXECUTE_AND_VERIFY_SUBTREE_CHANGED(
-      root->SetMaskLayer(LayerImpl::Create(host_impl.active_tree(), 8)));
+      root->SetMaskLayer(LayerImpl::Create(host_impl.active_tree(), 9)));
   EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetMasksToBounds(true));
   EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetContentsOpaque(true));
   EXECUTE_AND_VERIFY_SUBTREE_CHANGED(
-      root->SetReplicaLayer(LayerImpl::Create(host_impl.active_tree(), 9)));
+      root->SetReplicaLayer(LayerImpl::Create(host_impl.active_tree(), 10)));
   EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetPosition(arbitrary_point_f));
-  EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetPreserves3d(true));
+  EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetShouldFlattenTransform(false));
+  EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetIs3dSorted(true));
   EXECUTE_AND_VERIFY_SUBTREE_CHANGED(
       root->SetDoubleSided(false));  // constructor initializes it to "true".
   EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->ScrollBy(arbitrary_vector2d));
@@ -178,11 +175,6 @@ TEST(LayerImplTest, VerifyLayerChangesAreTrackedProperly) {
   EXECUTE_AND_VERIFY_ONLY_LAYER_CHANGED(
       root->SetBackgroundFilters(arbitrary_filters));
 
-  // Changing these properties affects all layer's descendants,
-  // but not the layer itself.
-  EXECUTE_AND_VERIFY_ONLY_DESCENDANTS_CHANGED(
-      root->SetSublayerTransform(arbitrary_transform));
-
   // Special case: check that SetBounds changes behavior depending on
   // masksToBounds.
   root->SetMasksToBounds(false);
@@ -203,13 +195,9 @@ TEST(LayerImplTest, VerifyLayerChangesAreTrackedProperly) {
   EXECUTE_AND_VERIFY_NEEDS_PUSH_PROPERTIES_AND_SUBTREE_DID_NOT_CHANGE(
       root->SetScrollChildren(scroll_children));
   EXECUTE_AND_VERIFY_NEEDS_PUSH_PROPERTIES_AND_SUBTREE_DID_NOT_CHANGE(
-      root->RemoveScrollChild(scroll_child));
-  EXECUTE_AND_VERIFY_NEEDS_PUSH_PROPERTIES_AND_SUBTREE_DID_NOT_CHANGE(
       root->SetClipParent(clip_parent.get()));
   EXECUTE_AND_VERIFY_NEEDS_PUSH_PROPERTIES_AND_SUBTREE_DID_NOT_CHANGE(
       root->SetClipChildren(clip_children));
-  EXECUTE_AND_VERIFY_NEEDS_PUSH_PROPERTIES_AND_SUBTREE_DID_NOT_CHANGE(
-      root->RemoveClipChild(clip_child));
 
   // After setting all these properties already, setting to the exact same
   // values again should not cause any change.
@@ -220,7 +208,9 @@ TEST(LayerImplTest, VerifyLayerChangesAreTrackedProperly) {
   EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(root->SetMasksToBounds(true));
   EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(
       root->SetPosition(arbitrary_point_f));
-  EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(root->SetPreserves3d(true));
+  EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(
+      root->SetShouldFlattenTransform(false));
+  EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(root->SetIs3dSorted(true));
   EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(
       root->SetTransform(arbitrary_transform));
   EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(
@@ -240,8 +230,6 @@ TEST(LayerImplTest, VerifyLayerChangesAreTrackedProperly) {
   EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(
       root->SetIsRootForIsolatedGroup(true));
   EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(root->SetDrawsContent(true));
-  EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(
-      root->SetSublayerTransform(arbitrary_transform));
   EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(root->SetBounds(arbitrary_size));
   EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(
       root->SetScrollParent(scroll_parent.get()));
@@ -255,17 +243,26 @@ TEST(LayerImplTest, VerifyLayerChangesAreTrackedProperly) {
 
 TEST(LayerImplTest, VerifyNeedsUpdateDrawProperties) {
   FakeImplProxy proxy;
-  FakeLayerTreeHostImpl host_impl(&proxy);
-  EXPECT_TRUE(host_impl.InitializeRenderer(CreateFakeOutputSurface()));
-  scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl.active_tree(), 1);
-  root->SetScrollable(true);
+  TestSharedBitmapManager shared_bitmap_manager;
+  FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager);
+  EXPECT_TRUE(host_impl.InitializeRenderer(
+      FakeOutputSurface::Create3d().PassAs<OutputSurface>()));
+  host_impl.active_tree()->SetRootLayer(
+      LayerImpl::Create(host_impl.active_tree(), 1));
+  LayerImpl* root = host_impl.active_tree()->root_layer();
+  scoped_ptr<LayerImpl> layer_ptr =
+      LayerImpl::Create(host_impl.active_tree(), 2);
+  LayerImpl* layer = layer_ptr.get();
+  root->AddChild(layer_ptr.Pass());
+  layer->SetScrollClipLayer(root->id());
+  DCHECK(host_impl.CanDraw());
 
   gfx::PointF arbitrary_point_f = gfx::PointF(0.125f, 0.25f);
   float arbitrary_number = 0.352f;
   gfx::Size arbitrary_size = gfx::Size(111, 222);
   gfx::Point arbitrary_point = gfx::Point(333, 444);
   gfx::Vector2d arbitrary_vector2d = gfx::Vector2d(111, 222);
-  gfx::Vector2d large_vector2d = gfx::Vector2d(1000, 1000);
+  gfx::Size large_size = gfx::Size(1000, 1000);
   gfx::Rect arbitrary_rect = gfx::Rect(arbitrary_point, arbitrary_size);
   gfx::RectF arbitrary_rect_f =
       gfx::RectF(arbitrary_point_f, gfx::SizeF(1.234f, 5.678f));
@@ -277,89 +274,92 @@ TEST(LayerImplTest, VerifyNeedsUpdateDrawProperties) {
   SkXfermode::Mode arbitrary_blend_mode = SkXfermode::kMultiply_Mode;
 
   // Related filter functions.
-  VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(root->SetFilters(arbitrary_filters));
-  VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(root->SetFilters(arbitrary_filters));
-  VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(root->SetFilters(FilterOperations()));
-  VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(root->SetFilters(arbitrary_filters));
+  VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetFilters(arbitrary_filters));
+  VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetFilters(arbitrary_filters));
+  VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetFilters(FilterOperations()));
+  VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetFilters(arbitrary_filters));
 
   // Related scrolling functions.
-  VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(root->SetMaxScrollOffset(large_vector2d));
-  VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(
-      root->SetMaxScrollOffset(large_vector2d));
-  VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(root->ScrollBy(arbitrary_vector2d));
-  VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(root->ScrollBy(gfx::Vector2d()));
-  root->SetScrollDelta(gfx::Vector2d(0, 0));
+  VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetBounds(large_size));
+  VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetBounds(large_size));
+  VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer->ScrollBy(arbitrary_vector2d));
+  VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(layer->ScrollBy(gfx::Vector2d()));
+  layer->SetScrollDelta(gfx::Vector2d(0, 0));
   host_impl.ForcePrepareToDraw();
-  VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(root->SetScrollDelta(arbitrary_vector2d));
+  VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(
+      layer->SetScrollDelta(arbitrary_vector2d));
   VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(
-      root->SetScrollDelta(arbitrary_vector2d));
+      layer->SetScrollDelta(arbitrary_vector2d));
   VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(
-      root->SetScrollOffset(arbitrary_vector2d));
+      layer->SetScrollOffset(arbitrary_vector2d));
   VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(
-      root->SetScrollOffset(arbitrary_vector2d));
+      layer->SetScrollOffset(arbitrary_vector2d));
 
   // Unrelated functions, always set to new values, always set needs update.
-  VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(root->SetAnchorPointZ(arbitrary_number));
+  VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetAnchorPointZ(arbitrary_number));
   VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(
-      root->SetMaskLayer(LayerImpl::Create(host_impl.active_tree(), 4)));
-  VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(root->SetMasksToBounds(true));
-  VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(root->SetContentsOpaque(true));
+      layer->SetMaskLayer(LayerImpl::Create(host_impl.active_tree(), 4)));
+  VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetMasksToBounds(true));
+  VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetContentsOpaque(true));
   VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(
-      root->SetReplicaLayer(LayerImpl::Create(host_impl.active_tree(), 5)));
-  VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(root->SetPosition(arbitrary_point_f));
-  VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(root->SetPreserves3d(true));
+      layer->SetReplicaLayer(LayerImpl::Create(host_impl.active_tree(), 5)));
+  VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetPosition(arbitrary_point_f));
+  VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetShouldFlattenTransform(false));
+  VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetIs3dSorted(true));
+
   VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(
-      root->SetDoubleSided(false));  // constructor initializes it to "true".
-  VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(root->SetContentBounds(arbitrary_size));
+      layer->SetDoubleSided(false));  // constructor initializes it to "true".
+  VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetContentBounds(arbitrary_size));
   VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(
-      root->SetContentsScale(arbitrary_number, arbitrary_number));
-  VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(root->SetDrawsContent(true));
+      layer->SetContentsScale(arbitrary_number, arbitrary_number));
+  VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetDrawsContent(true));
   VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(
-      root->SetBackgroundColor(arbitrary_color));
+      layer->SetBackgroundColor(arbitrary_color));
   VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(
-      root->SetBackgroundFilters(arbitrary_filters));
-  VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(root->SetOpacity(arbitrary_number));
-  VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(root->SetBlendMode(arbitrary_blend_mode));
-  VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(root->SetTransform(arbitrary_transform));
+      layer->SetBackgroundFilters(arbitrary_filters));
+  VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetOpacity(arbitrary_number));
   VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(
-      root->SetSublayerTransform(arbitrary_transform));
-  VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(root->SetBounds(arbitrary_size));
+      layer->SetBlendMode(arbitrary_blend_mode));
+  VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetTransform(arbitrary_transform));
+  VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetBounds(arbitrary_size));
 
   // Unrelated functions, set to the same values, no needs update.
   VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(
-      root->SetAnchorPointZ(arbitrary_number));
-  VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(root->SetIsRootForIsolatedGroup(true));
-  VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(root->SetFilters(arbitrary_filters));
-  VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(root->SetMasksToBounds(true));
-  VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(root->SetContentsOpaque(true));
-  VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(root->SetPosition(arbitrary_point_f));
-  VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(root->SetPreserves3d(true));
+      layer->SetAnchorPointZ(arbitrary_number));
   VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(
-      root->SetDoubleSided(false));  // constructor initializes it to "true".
+      layer->SetIsRootForIsolatedGroup(true));
+  VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetFilters(arbitrary_filters));
+  VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetMasksToBounds(true));
+  VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetContentsOpaque(true));
+  VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetPosition(arbitrary_point_f));
+  VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetIs3dSorted(true));
   VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(
-      root->SetContentBounds(arbitrary_size));
+      layer->SetDoubleSided(false));  // constructor initializes it to "true".
   VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(
-      root->SetContentsScale(arbitrary_number, arbitrary_number));
-  VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(root->SetDrawsContent(true));
+      layer->SetContentBounds(arbitrary_size));
   VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(
-      root->SetBackgroundColor(arbitrary_color));
+      layer->SetContentsScale(arbitrary_number, arbitrary_number));
+  VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetDrawsContent(true));
   VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(
-      root->SetBackgroundFilters(arbitrary_filters));
-  VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(root->SetOpacity(arbitrary_number));
+      layer->SetBackgroundColor(arbitrary_color));
   VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(
-      root->SetBlendMode(arbitrary_blend_mode));
-  VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(root->SetIsRootForIsolatedGroup(true));
+      layer->SetBackgroundFilters(arbitrary_filters));
+  VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetOpacity(arbitrary_number));
   VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(
-      root->SetTransform(arbitrary_transform));
+      layer->SetBlendMode(arbitrary_blend_mode));
   VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(
-      root->SetSublayerTransform(arbitrary_transform));
-  VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(root->SetBounds(arbitrary_size));
+      layer->SetIsRootForIsolatedGroup(true));
+  VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(
+      layer->SetTransform(arbitrary_transform));
+  VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetBounds(arbitrary_size));
 }
 
 TEST(LayerImplTest, SafeOpaqueBackgroundColor) {
   FakeImplProxy proxy;
-  FakeLayerTreeHostImpl host_impl(&proxy);
-  EXPECT_TRUE(host_impl.InitializeRenderer(CreateFakeOutputSurface()));
+  TestSharedBitmapManager shared_bitmap_manager;
+  FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager);
+  EXPECT_TRUE(host_impl.InitializeRenderer(
+      FakeOutputSurface::Create3d().PassAs<OutputSurface>()));
   scoped_ptr<LayerImpl> layer = LayerImpl::Create(host_impl.active_tree(), 1);
 
   for (int contents_opaque = 0; contents_opaque < 2; ++contents_opaque) {
@@ -386,18 +386,60 @@ TEST(LayerImplTest, SafeOpaqueBackgroundColor) {
   }
 }
 
+TEST(LayerImplTest, TransformInvertibility) {
+  FakeImplProxy proxy;
+  TestSharedBitmapManager shared_bitmap_manager;
+  FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager);
+
+  scoped_ptr<LayerImpl> layer = LayerImpl::Create(host_impl.active_tree(), 1);
+  EXPECT_TRUE(layer->transform().IsInvertible());
+  EXPECT_TRUE(layer->transform_is_invertible());
+
+  gfx::Transform transform;
+  transform.Scale3d(
+      SkDoubleToMScalar(1.0), SkDoubleToMScalar(1.0), SkDoubleToMScalar(0.0));
+  layer->SetTransform(transform);
+  EXPECT_FALSE(layer->transform().IsInvertible());
+  EXPECT_FALSE(layer->transform_is_invertible());
+
+  transform.MakeIdentity();
+  transform.ApplyPerspectiveDepth(SkDoubleToMScalar(100.0));
+  transform.RotateAboutZAxis(75.0);
+  transform.RotateAboutXAxis(32.2);
+  transform.RotateAboutZAxis(-75.0);
+  transform.Translate3d(SkDoubleToMScalar(50.5),
+                        SkDoubleToMScalar(42.42),
+                        SkDoubleToMScalar(-100.25));
+
+  layer->SetTransform(transform);
+  EXPECT_TRUE(layer->transform().IsInvertible());
+  EXPECT_TRUE(layer->transform_is_invertible());
+}
+
 class LayerImplScrollTest : public testing::Test {
  public:
-  LayerImplScrollTest() : host_impl_(&proxy_), root_id_(7) {
-    host_impl_.active_tree()
-        ->SetRootLayer(LayerImpl::Create(host_impl_.active_tree(), root_id_));
-    host_impl_.active_tree()->root_layer()->SetScrollable(true);
+  LayerImplScrollTest()
+      : host_impl_(&proxy_, &shared_bitmap_manager_), root_id_(7) {
+    host_impl_.active_tree()->SetRootLayer(
+        LayerImpl::Create(host_impl_.active_tree(), root_id_));
+    host_impl_.active_tree()->root_layer()->AddChild(
+        LayerImpl::Create(host_impl_.active_tree(), root_id_ + 1));
+    layer()->SetScrollClipLayer(root_id_);
+    // Set the max scroll offset by noting that the root layer has bounds (1,1),
+    // thus whatever bounds are set for the layer will be the max scroll
+    // offset plus 1 in each direction.
+    host_impl_.active_tree()->root_layer()->SetBounds(gfx::Size(1, 1));
+    gfx::Vector2d max_scroll_offset(51, 81);
+    layer()->SetBounds(gfx::Size(max_scroll_offset.x(), max_scroll_offset.y()));
   }
 
-  LayerImpl* layer() { return host_impl_.active_tree()->root_layer(); }
+  LayerImpl* layer() {
+    return host_impl_.active_tree()->root_layer()->children()[0];
+  }
 
  private:
   FakeImplProxy proxy_;
+  TestSharedBitmapManager shared_bitmap_manager_;
   FakeLayerTreeHostImpl host_impl_;
   int root_id_;
 };
@@ -405,8 +447,6 @@ class LayerImplScrollTest : public testing::Test {
 TEST_F(LayerImplScrollTest, ScrollByWithZeroOffset) {
   // Test that LayerImpl::ScrollBy only affects ScrollDelta and total scroll
   // offset is bounded by the range [0, max scroll offset].
-  gfx::Vector2d max_scroll_offset(50, 80);
-  layer()->SetMaxScrollOffset(max_scroll_offset);
 
   EXPECT_VECTOR_EQ(gfx::Vector2dF(), layer()->TotalScrollOffset());
   EXPECT_VECTOR_EQ(gfx::Vector2dF(), layer()->scroll_offset());
@@ -426,9 +466,7 @@ TEST_F(LayerImplScrollTest, ScrollByWithZeroOffset) {
 }
 
 TEST_F(LayerImplScrollTest, ScrollByWithNonZeroOffset) {
-  gfx::Vector2d max_scroll_offset(50, 80);
   gfx::Vector2d scroll_offset(10, 5);
-  layer()->SetMaxScrollOffset(max_scroll_offset);
   layer()->SetScrollOffset(scroll_offset);
 
   EXPECT_VECTOR_EQ(scroll_offset, layer()->TotalScrollOffset());
@@ -464,7 +502,10 @@ class ScrollDelegateIgnore : public LayerScrollOffsetDelegate {
     fixed_offset_ = fixed_offset;
   }
 
-  virtual void SetTotalPageScaleFactor(float page_scale_factor) OVERRIDE {}
+  virtual void SetTotalPageScaleFactorAndLimits(
+      float page_scale_factor,
+      float min_page_scale_factor,
+      float max_page_scale_factor) OVERRIDE {}
   virtual void SetScrollableSize(const gfx::SizeF& scrollable_size) OVERRIDE {}
 
  private:
@@ -472,9 +513,7 @@ class ScrollDelegateIgnore : public LayerScrollOffsetDelegate {
 };
 
 TEST_F(LayerImplScrollTest, ScrollByWithIgnoringDelegate) {
-  gfx::Vector2d max_scroll_offset(50, 80);
   gfx::Vector2d scroll_offset(10, 5);
-  layer()->SetMaxScrollOffset(max_scroll_offset);
   layer()->SetScrollOffset(scroll_offset);
 
   EXPECT_VECTOR_EQ(scroll_offset, layer()->TotalScrollOffset());
@@ -517,7 +556,10 @@ class ScrollDelegateAccept : public LayerScrollOffsetDelegate {
     return current_offset_;
   }
   virtual bool IsExternalFlingActive() const OVERRIDE { return false; }
-  virtual void SetTotalPageScaleFactor(float page_scale_factor) OVERRIDE {}
+  virtual void SetTotalPageScaleFactorAndLimits(
+      float page_scale_factor,
+      float min_page_scale_factor,
+      float max_page_scale_factor) OVERRIDE {}
   virtual void SetScrollableSize(const gfx::SizeF& scrollable_size) OVERRIDE {}
 
  private:
@@ -525,9 +567,7 @@ class ScrollDelegateAccept : public LayerScrollOffsetDelegate {
 };
 
 TEST_F(LayerImplScrollTest, ScrollByWithAcceptingDelegate) {
-  gfx::Vector2d max_scroll_offset(50, 80);
   gfx::Vector2d scroll_offset(10, 5);
-  layer()->SetMaxScrollOffset(max_scroll_offset);
   layer()->SetScrollOffset(scroll_offset);
 
   EXPECT_VECTOR_EQ(scroll_offset, layer()->TotalScrollOffset());
@@ -559,12 +599,10 @@ TEST_F(LayerImplScrollTest, ScrollByWithAcceptingDelegate) {
 }
 
 TEST_F(LayerImplScrollTest, ApplySentScrollsNoDelegate) {
-  gfx::Vector2d max_scroll_offset(50, 80);
   gfx::Vector2d scroll_offset(10, 5);
   gfx::Vector2dF scroll_delta(20.5f, 8.5f);
   gfx::Vector2d sent_scroll_delta(12, -3);
 
-  layer()->SetMaxScrollOffset(max_scroll_offset);
   layer()->SetScrollOffset(scroll_offset);
   layer()->ScrollBy(scroll_delta);
   layer()->SetSentScrollDelta(sent_scroll_delta);
@@ -583,12 +621,10 @@ TEST_F(LayerImplScrollTest, ApplySentScrollsNoDelegate) {
 }
 
 TEST_F(LayerImplScrollTest, ApplySentScrollsWithIgnoringDelegate) {
-  gfx::Vector2d max_scroll_offset(50, 80);
   gfx::Vector2d scroll_offset(10, 5);
   gfx::Vector2d sent_scroll_delta(12, -3);
   gfx::Vector2dF fixed_offset(32, 12);
 
-  layer()->SetMaxScrollOffset(max_scroll_offset);
   layer()->SetScrollOffset(scroll_offset);
   ScrollDelegateIgnore delegate;
   delegate.set_fixed_offset(fixed_offset);
@@ -607,12 +643,10 @@ TEST_F(LayerImplScrollTest, ApplySentScrollsWithIgnoringDelegate) {
 }
 
 TEST_F(LayerImplScrollTest, ApplySentScrollsWithAcceptingDelegate) {
-  gfx::Vector2d max_scroll_offset(50, 80);
   gfx::Vector2d scroll_offset(10, 5);
   gfx::Vector2d sent_scroll_delta(12, -3);
   gfx::Vector2dF scroll_delta(20.5f, 8.5f);
 
-  layer()->SetMaxScrollOffset(max_scroll_offset);
   layer()->SetScrollOffset(scroll_offset);
   ScrollDelegateAccept delegate;
   layer()->SetScrollOffsetDelegate(&delegate);
@@ -633,12 +667,10 @@ TEST_F(LayerImplScrollTest, ApplySentScrollsWithAcceptingDelegate) {
 // The user-scrollability breaks for zoomed-in pages. So disable this.
 // http://crbug.com/322223
 TEST_F(LayerImplScrollTest, DISABLED_ScrollUserUnscrollableLayer) {
-  gfx::Vector2d max_scroll_offset(50, 80);
   gfx::Vector2d scroll_offset(10, 5);
   gfx::Vector2dF scroll_delta(20.5f, 8.5f);
 
   layer()->set_user_scrollable_vertical(false);
-  layer()->SetMaxScrollOffset(max_scroll_offset);
   layer()->SetScrollOffset(scroll_offset);
   gfx::Vector2dF unscrolled = layer()->ScrollBy(scroll_delta);