[go: nahoru, domu]

Remove cc::Layer fixed and sticky position constraints

They were set by blink before BlinkGenPropertyTrees when
cc:PropertyTreeBuilder used them to generate property trees at
cc side. Now blink generate property trees directly, so remove them.

Bug: 994361, 754339, 993936
Change-Id: I98559a49778ef6f14f96de61f1f6f54ad16631b8
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1767492
Commit-Queue: Xianzhu Wang <wangxianzhu@chromium.org>
Reviewed-by: Robert Flack <flackr@chromium.org>
Reviewed-by: David Bokan <bokan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#690970}
diff --git a/cc/BUILD.gn b/cc/BUILD.gn
index 91ec472ce..fe73fff 100644
--- a/cc/BUILD.gn
+++ b/cc/BUILD.gn
@@ -84,10 +84,6 @@
     "layers/layer_impl_test_properties.h",
     "layers/layer_list_iterator.cc",
     "layers/layer_list_iterator.h",
-    "layers/layer_position_constraint.cc",
-    "layers/layer_position_constraint.h",
-    "layers/layer_sticky_position_constraint.cc",
-    "layers/layer_sticky_position_constraint.h",
     "layers/mirror_layer.cc",
     "layers/mirror_layer.h",
     "layers/mirror_layer_impl.cc",
@@ -349,6 +345,8 @@
     "trees/scroll_node.h",
     "trees/single_thread_proxy.cc",
     "trees/single_thread_proxy.h",
+    "trees/sticky_position_constraint.cc",
+    "trees/sticky_position_constraint.h",
     "trees/swap_promise.h",
     "trees/swap_promise_manager.cc",
     "trees/swap_promise_manager.h",
@@ -609,7 +607,6 @@
     "layers/heads_up_display_unittest.cc",
     "layers/layer_impl_unittest.cc",
     "layers/layer_list_iterator_unittest.cc",
-    "layers/layer_position_constraint_unittest.cc",
     "layers/layer_unittest.cc",
     "layers/mirror_layer_unittest.cc",
     "layers/nine_patch_generator_unittest.cc",
diff --git a/cc/layers/layer.cc b/cc/layers/layer.cc
index 660a145..7baf7506 100644
--- a/cc/layers/layer.cc
+++ b/cc/layers/layer.cc
@@ -64,8 +64,6 @@
       user_scrollable_vertical(true),
       main_thread_scrolling_reasons(
           MainThreadScrollingReason::kNotScrollingOnMain),
-      is_resized_by_browser_controls(false),
-      is_container_for_fixed_position_layers(false),
       scroll_parent(nullptr),
       clip_parent(nullptr),
       has_will_change_transform_hint(false),
@@ -824,10 +822,6 @@
   SetNeedsCommit();
 }
 
-bool Layer::IsContainerForFixedPositionLayers() const {
-  return inputs_.is_container_for_fixed_position_layers;
-}
-
 bool Are2dAxisAligned(const gfx::Transform& a, const gfx::Transform& b) {
   if (a.IsScaleOrTranslation() && b.IsScaleOrTranslation()) {
     return true;
@@ -1395,76 +1389,6 @@
     layer_tree_host_->SetNeedsUpdateLayers();
 }
 
-bool Layer::DescendantIsFixedToContainerLayer() const {
-  // Because position constraints are not set when using layer lists (see:
-  // Layer::SetPositionConstraint), this should only be called when not using
-  // layer lists.
-  DCHECK(!layer_tree_host_ || !layer_tree_host_->IsUsingLayerLists());
-
-  for (size_t i = 0; i < inputs_.children.size(); ++i) {
-    if (inputs_.children[i]->inputs_.position_constraint.is_fixed_position() ||
-        inputs_.children[i]->DescendantIsFixedToContainerLayer())
-      return true;
-  }
-  return false;
-}
-
-void Layer::SetIsResizedByBrowserControls(bool resized) {
-  if (inputs_.is_resized_by_browser_controls == resized)
-    return;
-  inputs_.is_resized_by_browser_controls = resized;
-
-  SetNeedsCommit();
-}
-
-bool Layer::IsResizedByBrowserControls() const {
-  return inputs_.is_resized_by_browser_controls;
-}
-
-void Layer::SetIsContainerForFixedPositionLayers(bool container) {
-  // |inputs_.is_container_for_fixed_position_layers| is only used by the cc
-  // property tree builder to build property trees and is not needed when using
-  // layer lists.
-  DCHECK(!layer_tree_host_ || !layer_tree_host_->IsUsingLayerLists());
-
-  if (inputs_.is_container_for_fixed_position_layers == container)
-    return;
-  inputs_.is_container_for_fixed_position_layers = container;
-
-  if (layer_tree_host_ && layer_tree_host_->CommitRequested())
-    return;
-
-  // Only request a commit if we have a fixed positioned descendant.
-  if (DescendantIsFixedToContainerLayer()) {
-    SetPropertyTreesNeedRebuild();
-    SetNeedsCommit();
-  }
-}
-
-void Layer::SetPositionConstraint(const LayerPositionConstraint& constraint) {
-  // Position constraints are only used by the cc property tree builder to build
-  // property trees and are not needed when using layer lists.
-  DCHECK(!layer_tree_host_ || !layer_tree_host_->IsUsingLayerLists());
-
-  DCHECK(IsPropertyChangeAllowed());
-  if (inputs_.position_constraint == constraint)
-    return;
-  inputs_.position_constraint = constraint;
-  SetPropertyTreesNeedRebuild();
-  SetNeedsCommit();
-}
-
-void Layer::SetStickyPositionConstraint(
-    const LayerStickyPositionConstraint& constraint) {
-  DCHECK(IsPropertyChangeAllowed());
-  if (inputs_.sticky_position_constraint == constraint)
-    return;
-  inputs_.sticky_position_constraint = constraint;
-  SetSubtreePropertyChanged();
-  SetPropertyTreesNeedRebuild();
-  SetNeedsCommit();
-}
-
 void Layer::SetLayerClient(base::WeakPtr<LayerClient> client) {
   inputs_.client = std::move(client);
   inputs_.debug_info = nullptr;
diff --git a/cc/layers/layer.h b/cc/layers/layer.h
index ae7e7367..ddda6d4 100644
--- a/cc/layers/layer.h
+++ b/cc/layers/layer.h
@@ -23,7 +23,6 @@
 #include "cc/input/input_handler.h"
 #include "cc/input/scroll_snap_data.h"
 #include "cc/layers/layer_collections.h"
-#include "cc/layers/layer_position_constraint.h"
 #include "cc/layers/touch_action_region.h"
 #include "cc/paint/element_id.h"
 #include "cc/paint/filter_operations.h"
@@ -343,50 +342,6 @@
   void SetHitTestable(bool should_hit_test);
   virtual bool HitTestable() const;
 
-  // Set or gets if this layer is a container for fixed position layers in its
-  // subtree. Such layers will be positioned and transformed relative to this
-  // layer instead of their direct parent.
-  //
-  // A layer that is a container for fixed position layers cannot be both
-  // scrollable and have a non-identity transform.
-  void SetIsContainerForFixedPositionLayers(bool container);
-  bool IsContainerForFixedPositionLayers() const;
-
-  // Set or get constraints applied to the layer's position, where it may be
-  // in a fixed position relative to the nearest ancestor that returns true for
-  // IsContainerForFixedPositionLayers(). This may also specify which edges
-  // of the layer are fixed to the same edges of the container ancestor. When
-  // fixed position, this layer's transform will be appended to the container
-  // ancestor's transform instead of to this layer's direct parent's.
-  // Position constraints are only used by the cc property tree builder to build
-  // property trees and are not needed when using layer lists.
-  void SetPositionConstraint(const LayerPositionConstraint& constraint);
-  const LayerPositionConstraint& position_constraint() const {
-    return inputs_.position_constraint;
-  }
-
-  // Set or get constraints applied to the layer's position, where it may act
-  // like a normal layer until, during scroll, its position triggers it to
-  // become fixed position relative to its scroller. See CSS position: sticky
-  // for more details.
-  void SetStickyPositionConstraint(
-      const LayerStickyPositionConstraint& constraint);
-  const LayerStickyPositionConstraint& sticky_position_constraint() const {
-    return inputs_.sticky_position_constraint;
-  }
-
-  // On some platforms (Android renderer) the viewport may resize during scroll
-  // on the compositor thread. During this resize and until the main thread
-  // matches, position fixed layers may need to have their position adjusted on
-  // the compositor thread to keep them fixed in place.  If
-  // IsContainerForFixedPositionLayers() is true for this layer, these set and
-  // get whether fixed position descendants of this layer should have this
-  // adjustment to their position applied during such a viewport resize.
-  // This value is only used by the cc property tree builder to build property
-  // trees and is not needed when using layer lists.
-  void SetIsResizedByBrowserControls(bool resized);
-  bool IsResizedByBrowserControls() const;
-
   // Set or get the transform to be used when compositing this layer into its
   // target. The transform is inherited by this layers children.
   void SetTransform(const gfx::Transform& transform);
@@ -611,7 +566,7 @@
   // While all layers have an index into the transform tree, this value
   // indicates whether the transform tree node was created for this layer.
   void SetHasTransformNode(bool val) { has_transform_node_ = val; }
-  bool has_transform_node() { return has_transform_node_; }
+  bool has_transform_node() const { return has_transform_node_; }
 
   // This value indicates whether a clip node was created for |this| layer.
   void SetHasClipNode(bool val) { has_clip_node_ = val; }
@@ -911,7 +866,6 @@
   void RemoveClipChild(Layer* child);
 
   void SetParent(Layer* layer);
-  bool DescendantIsFixedToContainerLayer() const;
 
   // This should only be called from RemoveFromParent().
   void RemoveChildOrDependent(Layer* child);
@@ -1017,22 +971,6 @@
 
     TouchActionRegion touch_action_region;
 
-    // When set, position: fixed children of this layer will be affected by URL
-    // bar movement. bottom-fixed element will be pushed down as the URL bar
-    // hides (and the viewport expands) so that the element stays fixed to the
-    // viewport bottom. This will always be set on the outer viewport scroll
-    // layer. In the case of a non-default rootScroller, all iframes in the
-    // rootScroller ancestor chain will also have it set on their scroll
-    // layers.
-    // TODO(pdr): These values are only used by blink and only when blink does
-    // not generate property trees. Remove these values when
-    // BlinkGenPropertyTrees ships.
-    bool is_resized_by_browser_controls : 1;
-    bool is_container_for_fixed_position_layers : 1;
-    LayerPositionConstraint position_constraint;
-
-    LayerStickyPositionConstraint sticky_position_constraint;
-
     ElementId element_id;
 
     Layer* scroll_parent;
diff --git a/cc/layers/layer_impl.h b/cc/layers/layer_impl.h
index be26a60..f5aa559c0 100644
--- a/cc/layers/layer_impl.h
+++ b/cc/layers/layer_impl.h
@@ -26,7 +26,6 @@
 #include "cc/layers/draw_properties.h"
 #include "cc/layers/layer_collections.h"
 #include "cc/layers/layer_impl_test_properties.h"
-#include "cc/layers/layer_position_constraint.h"
 #include "cc/layers/performance_properties.h"
 #include "cc/layers/render_surface_impl.h"
 #include "cc/layers/touch_action_region.h"
diff --git a/cc/layers/layer_impl_test_properties.h b/cc/layers/layer_impl_test_properties.h
index 16bb6c9..eb805bd 100644
--- a/cc/layers/layer_impl_test_properties.h
+++ b/cc/layers/layer_impl_test_properties.h
@@ -10,8 +10,7 @@
 
 #include "cc/input/scroll_snap_data.h"
 #include "cc/layers/layer_collections.h"
-#include "cc/layers/layer_position_constraint.h"
-#include "cc/layers/layer_sticky_position_constraint.h"
+#include "cc/paint/element_id.h"
 #include "cc/paint/filter_operations.h"
 #include "third_party/skia/include/core/SkBlendMode.h"
 #include "ui/gfx/geometry/point3_f.h"
@@ -53,8 +52,6 @@
   float backdrop_filter_quality;
   gfx::PointF filters_origin;
   SkBlendMode blend_mode;
-  LayerPositionConstraint position_constraint;
-  LayerStickyPositionConstraint sticky_position_constraint;
   gfx::Point3F transform_origin;
   gfx::Transform transform;
   gfx::PointF position;
diff --git a/cc/layers/layer_position_constraint.cc b/cc/layers/layer_position_constraint.cc
deleted file mode 100644
index 183b6b5..0000000
--- a/cc/layers/layer_position_constraint.cc
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "cc/layers/layer_position_constraint.h"
-
-namespace cc {
-
-LayerPositionConstraint::LayerPositionConstraint()
-    : is_fixed_position_(false),
-      is_fixed_to_right_edge_(false),
-      is_fixed_to_bottom_edge_(false) {
-}
-
-bool LayerPositionConstraint::operator==(
-    const LayerPositionConstraint& other) const {
-  if (!is_fixed_position_ && !other.is_fixed_position_)
-    return true;
-  return is_fixed_position_ == other.is_fixed_position_ &&
-          is_fixed_to_right_edge_ == other.is_fixed_to_right_edge_ &&
-          is_fixed_to_bottom_edge_ == other.is_fixed_to_bottom_edge_;
-}
-
-bool LayerPositionConstraint::operator!=(
-    const LayerPositionConstraint& other) const {
-  return !(*this == other);
-}
-
-}  // namespace cc
diff --git a/cc/layers/layer_position_constraint.h b/cc/layers/layer_position_constraint.h
deleted file mode 100644
index 9fef26b..0000000
--- a/cc/layers/layer_position_constraint.h
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CC_LAYERS_LAYER_POSITION_CONSTRAINT_H_
-#define CC_LAYERS_LAYER_POSITION_CONSTRAINT_H_
-
-#include "cc/cc_export.h"
-
-namespace cc {
-
-class CC_EXPORT LayerPositionConstraint {
- public:
-  LayerPositionConstraint();
-
-  void set_is_fixed_position(bool fixed) { is_fixed_position_ = fixed; }
-  bool is_fixed_position() const { return is_fixed_position_; }
-  void set_is_fixed_to_right_edge(bool fixed) {
-    is_fixed_to_right_edge_ = fixed;
-  }
-  bool is_fixed_to_right_edge() const { return is_fixed_to_right_edge_; }
-  void set_is_fixed_to_bottom_edge(bool fixed) {
-    is_fixed_to_bottom_edge_ = fixed;
-  }
-  bool is_fixed_to_bottom_edge() const { return is_fixed_to_bottom_edge_; }
-
-  bool operator==(const LayerPositionConstraint&) const;
-  bool operator!=(const LayerPositionConstraint&) const;
-
- private:
-  bool is_fixed_position_       : 1;
-  bool is_fixed_to_right_edge_  : 1;
-  bool is_fixed_to_bottom_edge_ : 1;
-};
-
-}  // namespace cc
-
-#endif  // CC_LAYERS_LAYER_POSITION_CONSTRAINT_H_
diff --git a/cc/layers/layer_position_constraint_unittest.cc b/cc/layers/layer_position_constraint_unittest.cc
deleted file mode 100644
index 85ee156..0000000
--- a/cc/layers/layer_position_constraint_unittest.cc
+++ /dev/null
@@ -1,1163 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "cc/layers/layer_position_constraint.h"
-
-#include <vector>
-
-#include "cc/animation/animation_host.h"
-#include "cc/layers/layer.h"
-#include "cc/layers/layer_impl.h"
-#include "cc/test/fake_layer_tree_host.h"
-#include "cc/test/fake_proxy.h"
-#include "cc/test/geometry_test_utils.h"
-#include "cc/test/layer_test_common.h"
-#include "cc/test/test_task_graph_runner.h"
-#include "cc/trees/layer_tree_host_common.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace cc {
-namespace {
-
-void SetLayerPropertiesForTesting(Layer* layer,
-                                  const gfx::Transform& transform,
-                                  const gfx::Point3F& transform_origin,
-                                  const gfx::PointF& position,
-                                  const gfx::Size& bounds,
-                                  bool flatten_transform) {
-  layer->SetTransform(transform);
-  layer->SetTransformOrigin(transform_origin);
-  layer->SetPosition(position);
-  layer->SetBounds(bounds);
-  layer->SetShouldFlattenTransform(flatten_transform);
-}
-
-void ExecuteCalculateDrawProperties(LayerImpl* root_layer) {
-  RenderSurfaceList dummy_render_surface_list;
-  LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
-      root_layer, root_layer->bounds(), &dummy_render_surface_list);
-  inputs.inner_viewport_scroll_layer =
-      root_layer->layer_tree_impl()->InnerViewportScrollLayer();
-  inputs.outer_viewport_scroll_layer =
-      root_layer->layer_tree_impl()->OuterViewportScrollLayer();
-  EXPECT_FALSE(root_layer->layer_tree_impl()->property_trees()->needs_rebuild);
-  LayerTreeHostCommon::CalculateDrawProperties(&inputs);
-}
-
-class LayerPositionConstraintTest : public testing::Test {
- public:
-  LayerPositionConstraintTest()
-      : animation_host_(AnimationHost::CreateForTesting(ThreadInstance::MAIN)),
-        layer_tree_host_(FakeLayerTreeHost::Create(&fake_client_,
-                                                   &task_graph_runner_,
-                                                   animation_host_.get())),
-        root_impl_(nullptr),
-        inner_viewport_container_layer_impl_(nullptr),
-        scroll_layer_impl_(nullptr),
-        outer_viewport_container_layer_impl_(nullptr),
-        child_transform_layer_impl_(nullptr),
-        child_impl_(nullptr),
-        grand_child_impl_(nullptr),
-        great_grand_child_impl_(nullptr) {
-    layer_tree_host_->InitializeForTesting(
-        TaskRunnerProvider::Create(nullptr, nullptr),
-        std::unique_ptr<Proxy>(new FakeProxy));
-    CreateTreeForTest();
-    fixed_to_top_left_.set_is_fixed_position(true);
-    fixed_to_bottom_right_.set_is_fixed_position(true);
-    fixed_to_bottom_right_.set_is_fixed_to_right_edge(true);
-    fixed_to_bottom_right_.set_is_fixed_to_bottom_edge(true);
-  }
-
-  void CreateTreeForTest() {
-    // scroll_layer_ is the inner viewport scroll layer and child_ is the outer
-    // viewport scroll layer.
-    root_ = Layer::Create();
-    inner_viewport_container_layer_ = Layer::Create();
-    page_scale_layer_ = Layer::Create();
-    scroll_layer_ = Layer::Create();
-    outer_viewport_container_layer_ = Layer::Create();
-    child_transform_layer_ = Layer::Create();
-    child_ = Layer::Create();
-    grand_child_ = Layer::Create();
-    grand_child_->SetIsDrawable(true);
-    great_grand_child_ = Layer::Create();
-    great_grand_child_->SetIsDrawable(true);
-
-    gfx::Transform IdentityMatrix;
-    gfx::Point3F transform_origin;
-    gfx::PointF position;
-    gfx::Size bounds(200, 200);
-    gfx::Size clip_bounds(100, 100);
-    SetLayerPropertiesForTesting(inner_viewport_container_layer_.get(),
-                                 IdentityMatrix, transform_origin, position,
-                                 clip_bounds, true);
-    SetLayerPropertiesForTesting(page_scale_layer_.get(), IdentityMatrix,
-                                 transform_origin, position, clip_bounds, true);
-    SetLayerPropertiesForTesting(scroll_layer_.get(), IdentityMatrix,
-                                 transform_origin, position, bounds, true);
-    SetLayerPropertiesForTesting(outer_viewport_container_layer_.get(),
-                                 IdentityMatrix, transform_origin, position,
-                                 clip_bounds, true);
-    SetLayerPropertiesForTesting(child_.get(), IdentityMatrix, transform_origin,
-                                 position, bounds, true);
-    SetLayerPropertiesForTesting(grand_child_.get(), IdentityMatrix,
-                                 transform_origin, position, bounds, true);
-    SetLayerPropertiesForTesting(great_grand_child_.get(), IdentityMatrix,
-                                 transform_origin, position, bounds, true);
-
-    root_->SetBounds(clip_bounds);
-
-    inner_viewport_container_layer_->SetMasksToBounds(true);
-    scroll_layer_->SetElementId(
-        LayerIdToElementIdForTesting(scroll_layer_->id()));
-    scroll_layer_->SetScrollable(clip_bounds);
-    scroll_layer_->SetIsContainerForFixedPositionLayers(true);
-
-    outer_viewport_container_layer_->SetMasksToBounds(true);
-    child_->SetElementId(LayerIdToElementIdForTesting(child_->id()));
-    child_->SetScrollable(clip_bounds);
-    grand_child_->SetElementId(
-        LayerIdToElementIdForTesting(grand_child_->id()));
-    grand_child_->SetScrollable(clip_bounds);
-    child_->SetIsContainerForFixedPositionLayers(true);
-
-    grand_child_->AddChild(great_grand_child_);
-    child_->AddChild(grand_child_);
-    child_transform_layer_->AddChild(child_);
-    outer_viewport_container_layer_->AddChild(child_transform_layer_);
-    scroll_layer_->AddChild(outer_viewport_container_layer_);
-    page_scale_layer_->AddChild(scroll_layer_);
-    inner_viewport_container_layer_->AddChild(page_scale_layer_);
-    root_->AddChild(inner_viewport_container_layer_);
-
-    child_->SetIsResizedByBrowserControls(true);
-
-    layer_tree_host_->SetRootLayer(root_);
-    ViewportLayers viewport_layers;
-    viewport_layers.page_scale = page_scale_layer_;
-    viewport_layers.inner_viewport_container = inner_viewport_container_layer_;
-    viewport_layers.outer_viewport_container = outer_viewport_container_layer_;
-    viewport_layers.inner_viewport_scroll = scroll_layer_;
-    viewport_layers.outer_viewport_scroll = child_;
-    layer_tree_host_->RegisterViewportLayers(viewport_layers);
-  }
-
-  void CommitAndUpdateImplPointers() {
-    LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
-        root_.get(), root_->bounds());
-    inputs.inner_viewport_scroll_layer =
-        layer_tree_host_->inner_viewport_scroll_layer();
-    inputs.outer_viewport_scroll_layer =
-        layer_tree_host_->outer_viewport_scroll_layer();
-    LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs);
-
-    // Since scroll deltas aren't sent back to the main thread in this test
-    // setup, clear them to maintain consistent state.
-    if (root_impl_) {
-      SetScrollOffsetDelta(scroll_layer_impl_, gfx::Vector2dF());
-      SetScrollOffsetDelta(child_impl_, gfx::Vector2dF());
-      SetScrollOffsetDelta(grand_child_impl_, gfx::Vector2dF());
-    }
-    root_impl_ = layer_tree_host_->CommitAndCreateLayerImplTree();
-    layer_tree_impl_ = root_impl_->layer_tree_impl();
-    inner_viewport_container_layer_impl_ =
-        layer_tree_impl_->LayerById(inner_viewport_container_layer_->id());
-    scroll_layer_impl_ = layer_tree_impl_->LayerById(scroll_layer_->id());
-    outer_viewport_container_layer_impl_ =
-        layer_tree_impl_->LayerById(outer_viewport_container_layer_->id());
-    child_transform_layer_impl_ =
-        layer_tree_impl_->LayerById(child_transform_layer_->id());
-    child_impl_ = layer_tree_impl_->LayerById(child_->id());
-    grand_child_impl_ = layer_tree_impl_->LayerById(grand_child_->id());
-    great_grand_child_impl_ =
-        layer_tree_impl_->LayerById(great_grand_child_->id());
-  }
-
- protected:
-  FakeLayerTreeHostClient fake_client_;
-  TestTaskGraphRunner task_graph_runner_;
-  std::unique_ptr<AnimationHost> animation_host_;
-  std::unique_ptr<FakeLayerTreeHost> layer_tree_host_;
-  scoped_refptr<Layer> root_;
-  scoped_refptr<Layer> page_scale_layer_;
-  scoped_refptr<Layer> inner_viewport_container_layer_;
-  scoped_refptr<Layer> scroll_layer_;
-  scoped_refptr<Layer> outer_viewport_container_layer_;
-  scoped_refptr<Layer> child_transform_layer_;
-  scoped_refptr<Layer> child_;
-  scoped_refptr<Layer> grand_child_;
-  scoped_refptr<Layer> great_grand_child_;
-  LayerTreeImpl* layer_tree_impl_;
-  LayerImpl* root_impl_;
-  LayerImpl* inner_viewport_container_layer_impl_;
-  LayerImpl* scroll_layer_impl_;
-  LayerImpl* outer_viewport_container_layer_impl_;
-  LayerImpl* child_transform_layer_impl_;
-  LayerImpl* child_impl_;
-  LayerImpl* grand_child_impl_;
-  LayerImpl* great_grand_child_impl_;
-
-  LayerPositionConstraint fixed_to_top_left_;
-  LayerPositionConstraint fixed_to_bottom_right_;
-
-  // LayerImpl should not be aware of synced property logics, this function is
-  // a hack for the test to arbitrarily set the scroll delta for setting up.
-  static void SetScrollOffsetDelta(LayerImpl* layer_impl,
-                                   const gfx::Vector2dF& delta) {
-    if (layer_impl->layer_tree_impl()
-            ->property_trees()
-            ->scroll_tree.SetScrollOffsetDeltaForTesting(
-                layer_impl->element_id(), delta))
-      layer_impl->layer_tree_impl()->DidUpdateScrollOffset(
-          layer_impl->element_id());
-  }
-};
-
-TEST_F(LayerPositionConstraintTest,
-     ScrollCompensationForFixedPositionLayerWithDirectContainer) {
-  // This test checks for correct scroll compensation when the fixed-position
-  // container is the direct parent of the fixed-position layer.
-  child_->SetIsContainerForFixedPositionLayers(true);
-  grand_child_->SetPositionConstraint(fixed_to_top_left_);
-
-  CommitAndUpdateImplPointers();
-
-  // Case 1: scroll delta of 0, 0
-  SetScrollOffsetDelta(child_impl_, gfx::Vector2d(0, 0));
-  ExecuteCalculateDrawProperties(root_impl_);
-
-  gfx::Transform expected_child_transform;
-  gfx::Transform expected_grand_child_transform = expected_child_transform;
-
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
-                                  child_impl_->DrawTransform());
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
-                                  grand_child_impl_->DrawTransform());
-
-  // Case 2: scroll delta of 10, 10
-  SetScrollOffsetDelta(child_impl_, gfx::Vector2d(10, 10));
-  child_impl_->SetDrawsContent(true);
-  ExecuteCalculateDrawProperties(root_impl_);
-
-  // Here the child is affected by scroll delta, but the fixed position
-  // grand_child should not be affected.
-  expected_child_transform.MakeIdentity();
-  expected_child_transform.Translate(-10.0, -10.0);
-
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
-                                  child_impl_->DrawTransform());
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
-                                  grand_child_impl_->DrawTransform());
-
-  // Case 3: fixed-container size delta of 20, 20
-  outer_viewport_container_layer_impl_->SetViewportBoundsDelta(
-      gfx::Vector2d(20, 20));
-  ExecuteCalculateDrawProperties(root_impl_);
-
-  // Top-left fixed-position layer should not be affected by container size.
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
-                                  child_impl_->DrawTransform());
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
-                                  grand_child_impl_->DrawTransform());
-
-  // Case 4: Bottom-right fixed-position layer.
-  grand_child_->SetPositionConstraint(fixed_to_bottom_right_);
-  CommitAndUpdateImplPointers();
-
-  SetScrollOffsetDelta(child_impl_, gfx::Vector2d(10, 10));
-  outer_viewport_container_layer_impl_->SetViewportBoundsDelta(
-      gfx::Vector2d(20, 20));
-  ExecuteCalculateDrawProperties(root_impl_);
-
-  // Bottom-right fixed-position layer moves as container resizes.
-  expected_grand_child_transform.MakeIdentity();
-  // Apply size delta from the child(container) layer.
-  expected_grand_child_transform.Translate(20.0, 20.0);
-
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
-                                  child_impl_->DrawTransform());
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
-                                  grand_child_impl_->DrawTransform());
-}
-
-TEST_F(LayerPositionConstraintTest,
-     ScrollCompensationForFixedPositionLayerWithDistantContainer) {
-  // This test checks for correct scroll compensation when the fixed-position
-  // container is NOT the direct parent of the fixed-position layer.
-  child_->SetIsContainerForFixedPositionLayers(true);
-  grand_child_->SetPosition(gfx::PointF(8.f, 6.f));
-  great_grand_child_->SetPositionConstraint(fixed_to_top_left_);
-
-  CommitAndUpdateImplPointers();
-
-  // Case 1: scroll delta of 0, 0
-  SetScrollOffsetDelta(child_impl_, gfx::Vector2d(0, 0));
-  child_impl_->SetDrawsContent(true);
-  ExecuteCalculateDrawProperties(root_impl_);
-
-  gfx::Transform expected_child_transform;
-  gfx::Transform expected_grand_child_transform;
-  expected_grand_child_transform.Translate(8.0, 6.0);
-
-  gfx::Transform expected_great_grand_child_transform =
-      expected_grand_child_transform;
-
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
-                                  child_impl_->DrawTransform());
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
-                                  grand_child_impl_->DrawTransform());
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
-                                  great_grand_child_impl_->DrawTransform());
-
-  // Case 2: scroll delta of 10, 10
-  SetScrollOffsetDelta(child_impl_, gfx::Vector2d(10, 10));
-  ExecuteCalculateDrawProperties(root_impl_);
-
-  // Here the child and grand_child are affected by scroll delta, but the fixed
-  // position great_grand_child should not be affected.
-  expected_child_transform.MakeIdentity();
-  expected_child_transform.Translate(-10.0, -10.0);
-  expected_grand_child_transform.MakeIdentity();
-  expected_grand_child_transform.Translate(-2.0, -4.0);
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
-                                  child_impl_->DrawTransform());
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
-                                  grand_child_impl_->DrawTransform());
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
-                                  great_grand_child_impl_->DrawTransform());
-
-  // Case 3: fixed-container size delta of 20, 20
-  outer_viewport_container_layer_impl_->SetViewportBoundsDelta(
-      gfx::Vector2d(20, 20));
-  ExecuteCalculateDrawProperties(root_impl_);
-
-  // Top-left fixed-position layer should not be affected by container size.
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
-                                  child_impl_->DrawTransform());
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
-                                  grand_child_impl_->DrawTransform());
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
-                                  great_grand_child_impl_->DrawTransform());
-
-  // Case 4: Bottom-right fixed-position layer.
-  great_grand_child_->SetPositionConstraint(fixed_to_bottom_right_);
-  CommitAndUpdateImplPointers();
-  SetScrollOffsetDelta(child_impl_, gfx::Vector2d(10, 10));
-  outer_viewport_container_layer_impl_->SetViewportBoundsDelta(
-      gfx::Vector2d(20, 20));
-  ExecuteCalculateDrawProperties(root_impl_);
-
-  // Bottom-right fixed-position layer moves as container resizes.
-  expected_great_grand_child_transform.MakeIdentity();
-  // Apply size delta from the child(container) layer.
-  expected_great_grand_child_transform.Translate(20.0, 20.0);
-  // Apply layer position from the grand child layer.
-  expected_great_grand_child_transform.Translate(8.0, 6.0);
-
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
-                                  child_impl_->DrawTransform());
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
-                                  grand_child_impl_->DrawTransform());
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
-                                  great_grand_child_impl_->DrawTransform());
-}
-
-TEST_F(LayerPositionConstraintTest,
-     ScrollCompensationForFixedPositionLayerWithMultipleScrollDeltas) {
-  // This test checks for correct scroll compensation when the fixed-position
-  // container has multiple ancestors that have nonzero scroll delta before
-  // reaching the space where the layer is fixed.
-  gfx::Transform rotation_about_z;
-  rotation_about_z.RotateAboutZAxis(90.0);
-
-  child_transform_layer_->SetIsContainerForFixedPositionLayers(true);
-  child_transform_layer_->SetTransform(rotation_about_z);
-  grand_child_->SetPosition(gfx::PointF(8.f, 6.f));
-  great_grand_child_->SetPositionConstraint(fixed_to_top_left_);
-
-  CommitAndUpdateImplPointers();
-
-  // Case 1: scroll delta of 0, 0
-  SetScrollOffsetDelta(child_impl_, gfx::Vector2d(0, 0));
-  child_impl_->SetDrawsContent(true);
-  ExecuteCalculateDrawProperties(root_impl_);
-
-  gfx::Transform expected_child_transform;
-  expected_child_transform.PreconcatTransform(rotation_about_z);
-
-  gfx::Transform expected_grand_child_transform;
-  expected_grand_child_transform.PreconcatTransform(
-      rotation_about_z);  // child's local transform is inherited
-  // translation because of position occurs before layer's local transform.
-  expected_grand_child_transform.Translate(8.0, 6.0);
-
-  gfx::Transform expected_great_grand_child_transform =
-      expected_grand_child_transform;
-
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
-                                  child_impl_->DrawTransform());
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
-                                  grand_child_impl_->DrawTransform());
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
-                                  great_grand_child_impl_->DrawTransform());
-
-  // Case 2: scroll delta of 10, 20
-  SetScrollOffsetDelta(child_impl_, gfx::Vector2d(10, 0));
-  SetScrollOffsetDelta(grand_child_impl_, gfx::Vector2d(5, 0));
-  ExecuteCalculateDrawProperties(root_impl_);
-
-  // Here the child and grand_child are affected by scroll delta, but the fixed
-  // position great_grand_child should not be affected.
-  expected_child_transform.MakeIdentity();
-  expected_child_transform.PreconcatTransform(rotation_about_z);
-  expected_child_transform.Translate(-10.0, 0.0);  // scroll delta
-
-  expected_grand_child_transform.MakeIdentity();
-  expected_grand_child_transform.PreconcatTransform(
-      rotation_about_z);  // child's local transform is inherited
-  expected_grand_child_transform.Translate(
-      -10.0, 0.0);  // child's scroll delta is inherited
-  expected_grand_child_transform.Translate(-5.0,
-                                           0.0);  // grand_child's scroll delta
-  // translation because of position
-  expected_grand_child_transform.Translate(8.0, 6.0);
-
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
-                                  child_impl_->DrawTransform());
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
-                                  grand_child_impl_->DrawTransform());
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
-                                  great_grand_child_impl_->DrawTransform());
-}
-
-TEST_F(LayerPositionConstraintTest,
-     ScrollCompensationForFixedPositionWithIntermediateSurfaceAndTransforms) {
-  // This test checks for correct scroll compensation when the fixed-position
-  // container contributes to a different render surface than the fixed-position
-  // layer. In this case, the surface draw transforms also have to be accounted
-  // for when checking the scroll delta.
-  child_->SetIsContainerForFixedPositionLayers(true);
-  grand_child_->SetPosition(gfx::PointF(8.f, 6.f));
-  grand_child_->SetForceRenderSurfaceForTesting(true);
-  great_grand_child_->SetPositionConstraint(fixed_to_top_left_);
-
-  gfx::Transform rotation_about_z;
-  rotation_about_z.RotateAboutZAxis(90.0);
-  great_grand_child_->SetTransform(rotation_about_z);
-
-  CommitAndUpdateImplPointers();
-
-  // Case 1: scroll delta of 0, 0
-  SetScrollOffsetDelta(child_impl_, gfx::Vector2d(0, 0));
-  ExecuteCalculateDrawProperties(root_impl_);
-
-  gfx::Transform expected_child_transform;
-  gfx::Transform expected_surface_draw_transform;
-  expected_surface_draw_transform.Translate(8.0, 6.0);
-  gfx::Transform expected_grand_child_transform;
-  gfx::Transform expected_great_grand_child_transform;
-  expected_great_grand_child_transform.PreconcatTransform(rotation_about_z);
-  EXPECT_TRUE(GetRenderSurface(grand_child_impl_));
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
-                                  child_impl_->DrawTransform());
-  EXPECT_TRANSFORMATION_MATRIX_EQ(
-      expected_surface_draw_transform,
-      GetRenderSurface(grand_child_impl_)->draw_transform());
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
-                                  grand_child_impl_->DrawTransform());
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
-                                  great_grand_child_impl_->DrawTransform());
-
-  // Case 2: scroll delta of 10, 30
-  SetScrollOffsetDelta(child_impl_, gfx::Vector2d(10, 30));
-  child_impl_->SetDrawsContent(true);
-  ExecuteCalculateDrawProperties(root_impl_);
-
-  // Here the grand_child remains unchanged, because it scrolls along with the
-  // render surface, and the translation is actually in the render surface. But,
-  // the fixed position great_grand_child is more awkward: its actually being
-  // drawn with respect to the render surface, but it needs to remain fixed with
-  // resepct to a container beyond that surface. So, the net result is that,
-  // unlike previous tests where the fixed position layer's transform remains
-  // unchanged, here the fixed position layer's transform explicitly contains
-  // the translation that cancels out the scroll.
-  expected_child_transform.MakeIdentity();
-  expected_child_transform.Translate(-10.0, -30.0);  // scroll delta
-
-  expected_surface_draw_transform.MakeIdentity();
-  expected_surface_draw_transform.Translate(-10.0, -30.0);  // scroll delta
-  expected_surface_draw_transform.Translate(8.0, 6.0);
-
-  expected_great_grand_child_transform.MakeIdentity();
-  // explicit canceling out the scroll delta that gets embedded in the fixed
-  // position layer's surface.
-  expected_great_grand_child_transform.Translate(10.0, 30.0);
-  expected_great_grand_child_transform.PreconcatTransform(rotation_about_z);
-
-  EXPECT_TRUE(GetRenderSurface(grand_child_impl_));
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
-                                  child_impl_->DrawTransform());
-  EXPECT_TRANSFORMATION_MATRIX_EQ(
-      expected_surface_draw_transform,
-      GetRenderSurface(grand_child_impl_)->draw_transform());
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
-                                  grand_child_impl_->DrawTransform());
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
-                                  great_grand_child_impl_->DrawTransform());
-
-  // Case 3: fixed-container size delta of 20, 20
-  outer_viewport_container_layer_impl_->SetViewportBoundsDelta(
-      gfx::Vector2d(20, 20));
-  ExecuteCalculateDrawProperties(root_impl_);
-
-  // Top-left fixed-position layer should not be affected by container size.
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
-                                  child_impl_->DrawTransform());
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
-                                  grand_child_impl_->DrawTransform());
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
-                                  great_grand_child_impl_->DrawTransform());
-
-  // Case 4: Bottom-right fixed-position layer.
-  great_grand_child_->SetPositionConstraint(fixed_to_bottom_right_);
-
-  CommitAndUpdateImplPointers();
-  SetScrollOffsetDelta(child_impl_, gfx::Vector2d(10, 30));
-  outer_viewport_container_layer_impl_->SetViewportBoundsDelta(
-      gfx::Vector2d(20, 20));
-
-  ExecuteCalculateDrawProperties(root_impl_);
-
-  // Bottom-right fixed-position layer moves as container resizes.
-  expected_great_grand_child_transform.MakeIdentity();
-  // explicit canceling out the scroll delta that gets embedded in the fixed
-  // position layer's surface.
-  expected_great_grand_child_transform.Translate(10.0, 30.0);
-  // Also apply size delta in the child(container) layer space.
-  expected_great_grand_child_transform.Translate(20.0, 20.0);
-  expected_great_grand_child_transform.PreconcatTransform(rotation_about_z);
-
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
-                                  child_impl_->DrawTransform());
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
-                                  grand_child_impl_->DrawTransform());
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
-                                  great_grand_child_impl_->DrawTransform());
-}
-
-TEST_F(LayerPositionConstraintTest,
-     ScrollCompensationForFixedPositionLayerWithMultipleIntermediateSurfaces) {
-  // This test checks for correct scroll compensation when the fixed-position
-  // container contributes to a different render surface than the fixed-position
-  // layer, with additional render surfaces in-between. This checks that the
-  // conversion to ancestor surfaces is accumulated properly in the final matrix
-  // transform.
-
-  // Add one more layer to the test tree for this scenario.
-  scoped_refptr<Layer> fixed_position_child = Layer::Create();
-  fixed_position_child->SetIsDrawable(true);
-  SetLayerPropertiesForTesting(fixed_position_child.get(), gfx::Transform(),
-                               gfx::Point3F(), gfx::PointF(),
-                               gfx::Size(100, 100), true);
-  great_grand_child_->AddChild(fixed_position_child);
-
-  // Actually set up the scenario here.
-  child_->SetIsContainerForFixedPositionLayers(true);
-  grand_child_->SetPosition(gfx::PointF(8.f, 6.f));
-  grand_child_->SetForceRenderSurfaceForTesting(true);
-  great_grand_child_->SetPosition(gfx::PointF(40.f, 60.f));
-  great_grand_child_->SetForceRenderSurfaceForTesting(true);
-  fixed_position_child->SetPositionConstraint(fixed_to_top_left_);
-
-  // The additional rotation, which is non-commutative with translations, helps
-  // to verify that we have correct order-of-operations in the final scroll
-  // compensation.  Note that rotating about the center of the layer ensures we
-  // do not accidentally clip away layers that we want to test.
-  gfx::Transform rotation_about_z;
-  rotation_about_z.Translate(50.0, 50.0);
-  rotation_about_z.RotateAboutZAxis(90.0);
-  rotation_about_z.Translate(-50.0, -50.0);
-  fixed_position_child->SetTransform(rotation_about_z);
-
-  CommitAndUpdateImplPointers();
-  LayerImpl* fixed_position_child_impl =
-      layer_tree_impl_->LayerById(fixed_position_child->id());
-
-  // Case 1: scroll delta of 0, 0
-  SetScrollOffsetDelta(child_impl_, gfx::Vector2d(0, 0));
-  child_impl_->SetDrawsContent(true);
-  ExecuteCalculateDrawProperties(root_impl_);
-
-  gfx::Transform expected_child_transform;
-
-  gfx::Transform expected_grand_child_surface_draw_transform;
-  expected_grand_child_surface_draw_transform.Translate(8.0, 6.0);
-
-  gfx::Transform expected_grand_child_transform;
-
-  gfx::Transform expected_great_grand_child_surface_draw_transform;
-  expected_great_grand_child_surface_draw_transform.Translate(40.0, 60.0);
-
-  gfx::Transform expected_great_grand_child_transform;
-
-  gfx::Transform expected_fixed_position_child_transform;
-  expected_fixed_position_child_transform.PreconcatTransform(rotation_about_z);
-
-  EXPECT_TRUE(GetRenderSurface(grand_child_impl_));
-  EXPECT_TRUE(GetRenderSurface(great_grand_child_impl_));
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
-                                  child_impl_->DrawTransform());
-  EXPECT_TRANSFORMATION_MATRIX_EQ(
-      expected_grand_child_surface_draw_transform,
-      GetRenderSurface(grand_child_impl_)->draw_transform());
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
-                                  grand_child_impl_->DrawTransform());
-  EXPECT_TRANSFORMATION_MATRIX_EQ(
-      expected_great_grand_child_surface_draw_transform,
-      GetRenderSurface(great_grand_child_impl_)->draw_transform());
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
-                                  great_grand_child_impl_->DrawTransform());
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_position_child_transform,
-                                  fixed_position_child_impl->DrawTransform());
-
-  // Case 2: scroll delta of 10, 30
-  SetScrollOffsetDelta(child_impl_, gfx::Vector2d(10, 30));
-  ExecuteCalculateDrawProperties(root_impl_);
-
-  expected_child_transform.MakeIdentity();
-  expected_child_transform.Translate(-10.0, -30.0);  // scroll delta
-
-  expected_grand_child_surface_draw_transform.MakeIdentity();
-  expected_grand_child_surface_draw_transform.Translate(-10.0,
-                                                        -30.0);  // scroll delta
-  expected_grand_child_surface_draw_transform.Translate(8.0, 6.0);
-
-  // grand_child, great_grand_child, and great_grand_child's surface are not
-  // expected to change, since they are all not fixed, and they are all drawn
-  // with respect to grand_child's surface that already has the scroll delta
-  // accounted for.
-
-  // But the great-great grandchild, "fixed_position_child", should have a
-  // transform that explicitly cancels out the scroll delta.
-  expected_fixed_position_child_transform.MakeIdentity();
-  expected_fixed_position_child_transform.Translate(10.0, 30.0);
-  expected_fixed_position_child_transform.PreconcatTransform(rotation_about_z);
-
-  EXPECT_TRUE(GetRenderSurface(grand_child_impl_));
-  EXPECT_TRUE(GetRenderSurface(great_grand_child_impl_));
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
-                                  child_impl_->DrawTransform());
-  EXPECT_TRANSFORMATION_MATRIX_EQ(
-      expected_grand_child_surface_draw_transform,
-      GetRenderSurface(grand_child_impl_)->draw_transform());
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
-                                  grand_child_impl_->DrawTransform());
-  EXPECT_TRANSFORMATION_MATRIX_EQ(
-      expected_great_grand_child_surface_draw_transform,
-      GetRenderSurface(great_grand_child_impl_)->draw_transform());
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
-                                  great_grand_child_impl_->DrawTransform());
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_position_child_transform,
-                                  fixed_position_child_impl->DrawTransform());
-
-  // Case 3: fixed-container size delta of 20, 20
-  outer_viewport_container_layer_impl_->SetViewportBoundsDelta(
-      gfx::Vector2d(20, 20));
-  ExecuteCalculateDrawProperties(root_impl_);
-
-  // Top-left fixed-position layer should not be affected by container size.
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
-                                  child_impl_->DrawTransform());
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
-                                  grand_child_impl_->DrawTransform());
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
-                                  great_grand_child_impl_->DrawTransform());
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_position_child_transform,
-                                  fixed_position_child_impl->DrawTransform());
-
-  // Case 4: Bottom-right fixed-position layer.
-  fixed_position_child->SetPositionConstraint(fixed_to_bottom_right_);
-  CommitAndUpdateImplPointers();
-  fixed_position_child_impl =
-      layer_tree_impl_->LayerById(fixed_position_child->id());
-  SetScrollOffsetDelta(child_impl_, gfx::Vector2d(10, 30));
-  outer_viewport_container_layer_impl_->SetViewportBoundsDelta(
-      gfx::Vector2d(20, 20));
-  ExecuteCalculateDrawProperties(root_impl_);
-
-  // Bottom-right fixed-position layer moves as container resizes.
-  expected_fixed_position_child_transform.MakeIdentity();
-  // explicit canceling out the scroll delta that gets embedded in the fixed
-  // position layer's surface.
-  expected_fixed_position_child_transform.Translate(10.0, 30.0);
-  // Also apply size delta in the child(container) layer space.
-  expected_fixed_position_child_transform.Translate(20.0, 20.0);
-  expected_fixed_position_child_transform.PreconcatTransform(rotation_about_z);
-
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
-                                  child_impl_->DrawTransform());
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
-                                  grand_child_impl_->DrawTransform());
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
-                                  great_grand_child_impl_->DrawTransform());
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_position_child_transform,
-                                  fixed_position_child_impl->DrawTransform());
-}
-
-TEST_F(
-    LayerPositionConstraintTest,
-    ScrollCompensationForFixedPositionLayerWithMultipleSurfacesAndTransforms) {
-  // This test checks for correct scroll compensation when the fixed-position
-  // container contributes to a different render surface than the fixed-position
-  // layer, with additional render surfaces in-between, and the fixed-position
-  // container is transformed. This checks that the conversion to ancestor
-  // surfaces is accumulated properly in the final matrix transform.
-
-  // Add one more layer to the test tree for this scenario.
-  scoped_refptr<Layer> fixed_position_child = Layer::Create();
-  fixed_position_child->SetIsDrawable(true);
-  SetLayerPropertiesForTesting(fixed_position_child.get(), gfx::Transform(),
-                               gfx::Point3F(), gfx::PointF(),
-                               gfx::Size(100, 100), true);
-  great_grand_child_->AddChild(fixed_position_child);
-
-  // Actually set up the scenario here.
-  child_transform_layer_->SetIsContainerForFixedPositionLayers(true);
-  grand_child_->SetPosition(gfx::PointF(8.f, 6.f));
-  grand_child_->SetForceRenderSurfaceForTesting(true);
-  great_grand_child_->SetPosition(gfx::PointF(40.f, 60.f));
-  great_grand_child_->SetForceRenderSurfaceForTesting(true);
-  fixed_position_child->SetPositionConstraint(fixed_to_top_left_);
-
-  // The additional rotations, which are non-commutative with translations, help
-  // to verify that we have correct order-of-operations in the final scroll
-  // compensation.  Note that rotating about the center of the layer ensures we
-  // do not accidentally clip away layers that we want to test.
-  gfx::Transform rotation_about_z;
-  rotation_about_z.Translate(50.0, 50.0);
-  rotation_about_z.RotateAboutZAxis(30.0);
-  rotation_about_z.Translate(-50.0, -50.0);
-  child_transform_layer_->SetTransform(rotation_about_z);
-  fixed_position_child->SetTransform(rotation_about_z);
-
-  CommitAndUpdateImplPointers();
-  LayerImpl* fixed_position_child_impl =
-      layer_tree_impl_->LayerById(fixed_position_child->id());
-
-  // Case 1: scroll delta of 0, 0
-  SetScrollOffsetDelta(child_impl_, gfx::Vector2d(0, 0));
-  child_impl_->SetDrawsContent(true);
-  ExecuteCalculateDrawProperties(root_impl_);
-
-  gfx::Transform expected_child_transform;
-  expected_child_transform.PreconcatTransform(rotation_about_z);
-
-  gfx::Transform expected_grand_child_surface_draw_transform;
-  expected_grand_child_surface_draw_transform.PreconcatTransform(
-      rotation_about_z);
-  expected_grand_child_surface_draw_transform.Translate(8.0, 6.0);
-
-  gfx::Transform expected_grand_child_transform;
-
-  gfx::Transform expected_great_grand_child_surface_draw_transform;
-  expected_great_grand_child_surface_draw_transform.Translate(40.0, 60.0);
-
-  gfx::Transform expected_great_grand_child_transform;
-
-  gfx::Transform expected_fixed_position_child_transform;
-  expected_fixed_position_child_transform.PreconcatTransform(rotation_about_z);
-
-  EXPECT_TRUE(GetRenderSurface(grand_child_impl_));
-  EXPECT_TRUE(GetRenderSurface(great_grand_child_impl_));
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
-                                  child_impl_->DrawTransform());
-  EXPECT_TRANSFORMATION_MATRIX_EQ(
-      expected_grand_child_surface_draw_transform,
-      GetRenderSurface(grand_child_impl_)->draw_transform());
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
-                                  grand_child_impl_->DrawTransform());
-  EXPECT_TRANSFORMATION_MATRIX_EQ(
-      expected_great_grand_child_surface_draw_transform,
-      GetRenderSurface(great_grand_child_impl_)->draw_transform());
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
-                                  great_grand_child_impl_->DrawTransform());
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_position_child_transform,
-                                  fixed_position_child_impl->DrawTransform());
-
-  // Case 2: scroll delta of 10, 30
-  SetScrollOffsetDelta(child_impl_, gfx::Vector2d(10, 30));
-  ExecuteCalculateDrawProperties(root_impl_);
-
-  expected_child_transform.MakeIdentity();
-  expected_child_transform.PreconcatTransform(rotation_about_z);
-  expected_child_transform.Translate(-10.0, -30.0);  // scroll delta
-
-  expected_grand_child_surface_draw_transform.MakeIdentity();
-  expected_grand_child_surface_draw_transform.PreconcatTransform(
-      rotation_about_z);
-  expected_grand_child_surface_draw_transform.Translate(-10.0,
-                                                        -30.0);  // scroll delta
-  expected_grand_child_surface_draw_transform.Translate(8.0, 6.0);
-
-  // grand_child, great_grand_child, and great_grand_child's surface are not
-  // expected to change, since they are all not fixed, and they are all drawn
-  // with respect to grand_child's surface that already has the scroll delta
-  // accounted for.
-
-  // But the great-great grandchild, "fixed_position_child", should have a
-  // transform that explicitly cancels out the scroll delta.
-  expected_fixed_position_child_transform.MakeIdentity();
-  // explicit canceling out the scroll delta that gets embedded in the fixed
-  // position layer's surface.
-  expected_fixed_position_child_transform.Translate(10.0, 30.0);
-  expected_fixed_position_child_transform.PreconcatTransform(rotation_about_z);
-
-  EXPECT_TRUE(GetRenderSurface(grand_child_impl_));
-  EXPECT_TRUE(GetRenderSurface(great_grand_child_impl_));
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
-                                  child_impl_->DrawTransform());
-  EXPECT_TRANSFORMATION_MATRIX_EQ(
-      expected_grand_child_surface_draw_transform,
-      GetRenderSurface(grand_child_impl_)->draw_transform());
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
-                                  grand_child_impl_->DrawTransform());
-  EXPECT_TRANSFORMATION_MATRIX_EQ(
-      expected_great_grand_child_surface_draw_transform,
-      GetRenderSurface(great_grand_child_impl_)->draw_transform());
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
-                                  great_grand_child_impl_->DrawTransform());
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_position_child_transform,
-                                  fixed_position_child_impl->DrawTransform());
-}
-
-TEST_F(LayerPositionConstraintTest,
-     ScrollCompensationForFixedPositionLayerWithContainerLayerThatHasSurface) {
-  // This test checks for correct scroll compensation when the fixed-position
-  // container itself has a render surface. In this case, the container layer
-  // should be treated like a layer that contributes to a render target, and
-  // that render target is completely irrelevant; it should not affect the
-  // scroll compensation.
-  child_->SetIsContainerForFixedPositionLayers(true);
-  child_->SetForceRenderSurfaceForTesting(true);
-  grand_child_->SetPositionConstraint(fixed_to_top_left_);
-
-  CommitAndUpdateImplPointers();
-
-  // Case 1: scroll delta of 0, 0
-  SetScrollOffsetDelta(child_impl_, gfx::Vector2d(0, 0));
-  ExecuteCalculateDrawProperties(root_impl_);
-
-  gfx::Transform expected_surface_draw_transform;
-  gfx::Transform expected_child_transform;
-  gfx::Transform expected_grand_child_transform;
-  EXPECT_TRUE(GetRenderSurface(child_impl_));
-  EXPECT_TRANSFORMATION_MATRIX_EQ(
-      expected_surface_draw_transform,
-      GetRenderSurface(child_impl_)->draw_transform());
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
-                                  child_impl_->DrawTransform());
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
-                                  grand_child_impl_->DrawTransform());
-
-  // Case 2: scroll delta of 10, 10
-  SetScrollOffsetDelta(child_impl_, gfx::Vector2d(10, 10));
-  ExecuteCalculateDrawProperties(root_impl_);
-
-  // The surface is translated by scroll delta, the child transform doesn't
-  // change because it scrolls along with the surface, but the fixed position
-  // grand_child needs to compensate for the scroll translation.
-  expected_surface_draw_transform.MakeIdentity();
-  expected_surface_draw_transform.Translate(-10.0, -10.0);
-  expected_grand_child_transform.MakeIdentity();
-  expected_grand_child_transform.Translate(10.0, 10.0);
-
-  EXPECT_TRUE(GetRenderSurface(child_impl_));
-  EXPECT_TRANSFORMATION_MATRIX_EQ(
-      expected_surface_draw_transform,
-      GetRenderSurface(child_impl_)->draw_transform());
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
-                                  child_impl_->DrawTransform());
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
-                                  grand_child_impl_->DrawTransform());
-
-  // Case 3: fixed-container size delta of 20, 20
-  outer_viewport_container_layer_impl_->SetViewportBoundsDelta(
-      gfx::Vector2d(20, 20));
-  ExecuteCalculateDrawProperties(root_impl_);
-
-  // Top-left fixed-position layer should not be affected by container size.
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
-                                  child_impl_->DrawTransform());
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
-                                  grand_child_impl_->DrawTransform());
-
-  // Case 4: Bottom-right fixed-position layer.
-  grand_child_->SetPositionConstraint(fixed_to_bottom_right_);
-  CommitAndUpdateImplPointers();
-  SetScrollOffsetDelta(child_impl_, gfx::Vector2d(10, 10));
-  outer_viewport_container_layer_impl_->SetViewportBoundsDelta(
-      gfx::Vector2d(20, 20));
-  ExecuteCalculateDrawProperties(root_impl_);
-
-  // Bottom-right fixed-position layer moves as container resizes.
-  expected_grand_child_transform.MakeIdentity();
-  // The surface is translated by scroll delta, the child transform doesn't
-  // change because it scrolls along with the surface, but the fixed position
-  // grand_child needs to compensate for the scroll translation.
-  expected_grand_child_transform.Translate(10.0, 10.0);
-  // Apply size delta from the child(container) layer.
-  expected_grand_child_transform.Translate(20.0, 20.0);
-
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
-                                  child_impl_->DrawTransform());
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
-                                  grand_child_impl_->DrawTransform());
-}
-
-TEST_F(LayerPositionConstraintTest,
-     ScrollCompensationForFixedPositionLayerThatIsAlsoFixedPositionContainer) {
-  // This test checks the scenario where a fixed-position layer also happens to
-  // be a container itself for a descendant fixed position layer. In particular,
-  // the layer should not accidentally be fixed to itself.
-  child_->SetIsContainerForFixedPositionLayers(true);
-  grand_child_->SetPositionConstraint(fixed_to_top_left_);
-
-  // This should not confuse the grand_child. If correct, the grand_child would
-  // still be considered fixed to its container (i.e. "child").
-  grand_child_->SetIsContainerForFixedPositionLayers(true);
-
-  CommitAndUpdateImplPointers();
-
-  // Case 1: scroll delta of 0, 0
-  SetScrollOffsetDelta(child_impl_, gfx::Vector2d(0, 0));
-  child_impl_->SetDrawsContent(true);
-  ExecuteCalculateDrawProperties(root_impl_);
-
-  gfx::Transform expected_child_transform;
-  gfx::Transform expected_grand_child_transform;
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
-                                  child_impl_->DrawTransform());
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
-                                  grand_child_impl_->DrawTransform());
-
-  // Case 2: scroll delta of 10, 10
-  SetScrollOffsetDelta(child_impl_, gfx::Vector2d(10, 10));
-  ExecuteCalculateDrawProperties(root_impl_);
-
-  // Here the child is affected by scroll delta, but the fixed position
-  // grand_child should not be affected.
-  expected_child_transform.MakeIdentity();
-  expected_child_transform.Translate(-10.0, -10.0);
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
-                                  child_impl_->DrawTransform());
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
-                                  grand_child_impl_->DrawTransform());
-
-  // Case 3: fixed-container size delta of 20, 20
-  outer_viewport_container_layer_impl_->SetViewportBoundsDelta(
-      gfx::Vector2d(20, 20));
-  ExecuteCalculateDrawProperties(root_impl_);
-
-  // Top-left fixed-position layer should not be affected by container size.
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
-                                  child_impl_->DrawTransform());
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
-                                  grand_child_impl_->DrawTransform());
-
-  // Case 4: Bottom-right fixed-position layer.
-  grand_child_->SetPositionConstraint(fixed_to_bottom_right_);
-  CommitAndUpdateImplPointers();
-  SetScrollOffsetDelta(child_impl_, gfx::Vector2d(10, 10));
-  outer_viewport_container_layer_impl_->SetViewportBoundsDelta(
-      gfx::Vector2d(20, 20));
-
-  ExecuteCalculateDrawProperties(root_impl_);
-
-  // Bottom-right fixed-position layer moves as container resizes.
-  expected_grand_child_transform.MakeIdentity();
-  // Apply size delta from the child(container) layer.
-  expected_grand_child_transform.Translate(20.0, 20.0);
-
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
-                                  child_impl_->DrawTransform());
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
-                                  grand_child_impl_->DrawTransform());
-}
-
-TEST_F(LayerPositionConstraintTest,
-     ScrollCompensationForFixedWithinFixedWithSameContainer) {
-  // This test checks scroll compensation for a fixed-position layer that is
-  // inside of another fixed-position layer and both share the same container.
-  // In this situation, the parent fixed-position layer will receive
-  // the scroll compensation, and the child fixed-position layer does not
-  // need to compensate further.
-  child_->SetIsContainerForFixedPositionLayers(true);
-  grand_child_->SetPositionConstraint(fixed_to_top_left_);
-
-  // Note carefully - great_grand_child is fixed to bottom right, to test
-  // sizeDelta being applied correctly; the compensation skips the grand_child
-  // because it is fixed to top left.
-  great_grand_child_->SetPositionConstraint(fixed_to_bottom_right_);
-
-  CommitAndUpdateImplPointers();
-
-  // Case 1: scrollDelta
-  SetScrollOffsetDelta(child_impl_, gfx::Vector2d(10, 10));
-  child_impl_->SetDrawsContent(true);
-  ExecuteCalculateDrawProperties(root_impl_);
-
-  // Here the child is affected by scroll delta, but the fixed position
-  // grand_child should not be affected.
-  gfx::Transform expected_child_transform;
-  expected_child_transform.Translate(-10.0, -10.0);
-
-  gfx::Transform expected_grand_child_transform;
-  gfx::Transform expected_great_grand_child_transform;
-
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
-                                  child_impl_->DrawTransform());
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
-                                  grand_child_impl_->DrawTransform());
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
-                                  great_grand_child_impl_->DrawTransform());
-
-  // Case 2: sizeDelta
-  SetScrollOffsetDelta(child_impl_, gfx::Vector2d(0, 0));
-  outer_viewport_container_layer_impl_->SetViewportBoundsDelta(
-      gfx::Vector2d(20, 20));
-  ExecuteCalculateDrawProperties(root_impl_);
-
-  expected_child_transform.MakeIdentity();
-
-  expected_grand_child_transform.MakeIdentity();
-
-  // Fixed to bottom-right, size-delta compensation is applied.
-  expected_great_grand_child_transform.MakeIdentity();
-  expected_great_grand_child_transform.Translate(20.0, 20.0);
-
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
-                                  child_impl_->DrawTransform());
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
-                                  grand_child_impl_->DrawTransform());
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
-                                  great_grand_child_impl_->DrawTransform());
-}
-
-TEST_F(LayerPositionConstraintTest,
-     ScrollCompensationForFixedWithinFixedWithInterveningContainer) {
-  // This test checks scroll compensation for a fixed-position layer that is
-  // inside of another fixed-position layer, but they have different fixed
-  // position containers. In this situation, the child fixed-position element
-  // would still have to compensate with respect to its container.
-
-  // Add one more layer to the hierarchy for this test.
-  scoped_refptr<Layer> great_great_grand_child = Layer::Create();
-  great_great_grand_child->SetIsDrawable(true);
-  great_grand_child_->AddChild(great_great_grand_child);
-
-  child_->SetIsContainerForFixedPositionLayers(true);
-  grand_child_->SetPositionConstraint(fixed_to_top_left_);
-  great_grand_child_->SetIsContainerForFixedPositionLayers(true);
-  great_grand_child_->SetElementId(
-      LayerIdToElementIdForTesting(great_grand_child_->id()));
-  great_grand_child_->SetScrollable(gfx::Size(100, 100));
-  great_great_grand_child->SetPositionConstraint(fixed_to_top_left_);
-
-  CommitAndUpdateImplPointers();
-
-  LayerImpl* container1 = child_impl_;
-  LayerImpl* fixed_to_container1 = grand_child_impl_;
-  LayerImpl* container2 = great_grand_child_impl_;
-  LayerImpl* fixed_to_container2 =
-      layer_tree_impl_->LayerById(great_great_grand_child->id());
-
-  SetScrollOffsetDelta(container1, gfx::Vector2d(0, 15));
-  container1->SetDrawsContent(true);
-  SetScrollOffsetDelta(container2, gfx::Vector2d(30, 0));
-  container2->SetDrawsContent(true);
-  ExecuteCalculateDrawProperties(root_impl_);
-
-  gfx::Transform expected_container1_transform;
-  expected_container1_transform.Translate(0.0, -15.0);
-
-  gfx::Transform expected_fixed_to_container1_transform;
-
-  // Since the container is a descendant of the fixed layer above,
-  // the expected draw transform for container2 would not
-  // include the scrollDelta that was applied to container1.
-  gfx::Transform expected_container2_transform;
-  expected_container2_transform.Translate(-30.0, 0.0);
-
-  gfx::Transform expected_fixed_to_container2_transform;
-
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_container1_transform,
-                                  container1->DrawTransform());
-
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_to_container1_transform,
-                                  fixed_to_container1->DrawTransform());
-
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_container2_transform,
-                                  container2->DrawTransform());
-
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_to_container2_transform,
-                                  fixed_to_container2->DrawTransform());
-}
-
-TEST_F(LayerPositionConstraintTest,
-       ScrollCompensationForOuterViewportBoundsDelta) {
-  // This test checks for correct scroll compensation when the fixed-position
-  // container is the outer viewport scroll layer and has non-zero bounds delta.
-  scoped_refptr<Layer> fixed_child = Layer::Create();
-  fixed_child->SetIsDrawable(true);
-  fixed_child->SetBounds(gfx::Size(300, 300));
-  child_->AddChild(fixed_child);
-  fixed_child->SetPositionConstraint(fixed_to_top_left_);
-
-  CommitAndUpdateImplPointers();
-
-  LayerImpl* fixed_child_impl =
-      root_impl_->layer_tree_impl()->FindActiveTreeLayerById(fixed_child->id());
-
-  // Case 1: fixed-container size delta of 20, 20
-  SetScrollOffsetDelta(child_impl_, gfx::Vector2d(10, 10));
-  child_impl_->SetDrawsContent(true);
-  outer_viewport_container_layer_impl_->SetViewportBoundsDelta(
-      gfx::Vector2d(20, 20));
-  gfx::Transform expected_scroll_layer_transform;
-  expected_scroll_layer_transform.Translate(-10.0, -10.0);
-  gfx::Transform expected_fixed_child_transform;
-
-  ExecuteCalculateDrawProperties(root_impl_);
-
-  // Top-left fixed-position layer should not be affected by container size.
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_scroll_layer_transform,
-                                  child_impl_->DrawTransform());
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_child_transform,
-                                  fixed_child_impl->DrawTransform());
-
-  // Case 2: Bottom-right fixed-position layer.
-  fixed_child->SetPositionConstraint(fixed_to_bottom_right_);
-  CommitAndUpdateImplPointers();
-  fixed_child_impl =
-      root_impl_->layer_tree_impl()->FindActiveTreeLayerById(fixed_child->id());
-
-  SetScrollOffsetDelta(child_impl_, gfx::Vector2d(10, 10));
-  outer_viewport_container_layer_impl_->SetViewportBoundsDelta(
-      gfx::Vector2d(20, 20));
-  ExecuteCalculateDrawProperties(root_impl_);
-
-  // Bottom-right fixed-position layer moves as container resizes.
-  expected_fixed_child_transform.MakeIdentity();
-  // Apply size delta.
-  expected_fixed_child_transform.Translate(20.0, 20.0);
-
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_scroll_layer_transform,
-                                  child_impl_->DrawTransform());
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_child_transform,
-                                  fixed_child_impl->DrawTransform());
-}
-
-}  // namespace
-}  // namespace cc
diff --git a/cc/layers/layer_sticky_position_constraint.cc b/cc/layers/layer_sticky_position_constraint.cc
deleted file mode 100644
index 4da9089..0000000
--- a/cc/layers/layer_sticky_position_constraint.cc
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "cc/layers/layer_sticky_position_constraint.h"
-
-#include "cc/layers/layer.h"
-
-namespace cc {
-
-LayerStickyPositionConstraint::LayerStickyPositionConstraint()
-    : is_sticky(false),
-      is_anchored_left(false),
-      is_anchored_right(false),
-      is_anchored_top(false),
-      is_anchored_bottom(false),
-      left_offset(0.f),
-      right_offset(0.f),
-      top_offset(0.f),
-      bottom_offset(0.f) {}
-
-LayerStickyPositionConstraint::LayerStickyPositionConstraint(
-    const LayerStickyPositionConstraint& other) = default;
-
-bool LayerStickyPositionConstraint::operator==(
-    const LayerStickyPositionConstraint& other) const {
-  if (!is_sticky && !other.is_sticky)
-    return true;
-  return is_sticky == other.is_sticky &&
-         is_anchored_left == other.is_anchored_left &&
-         is_anchored_right == other.is_anchored_right &&
-         is_anchored_top == other.is_anchored_top &&
-         is_anchored_bottom == other.is_anchored_bottom &&
-         left_offset == other.left_offset &&
-         right_offset == other.right_offset && top_offset == other.top_offset &&
-         bottom_offset == other.bottom_offset &&
-         constraint_box_rect == other.constraint_box_rect &&
-         scroll_container_relative_sticky_box_rect ==
-             other.scroll_container_relative_sticky_box_rect &&
-         scroll_container_relative_containing_block_rect ==
-             other.scroll_container_relative_containing_block_rect &&
-         nearest_element_shifting_sticky_box ==
-             other.nearest_element_shifting_sticky_box &&
-         nearest_element_shifting_containing_block ==
-             other.nearest_element_shifting_containing_block;
-}
-
-bool LayerStickyPositionConstraint::operator!=(
-    const LayerStickyPositionConstraint& other) const {
-  return !(*this == other);
-}
-
-ElementId LayerStickyPositionConstraint::NearestStickyAncestor() {
-  return nearest_element_shifting_sticky_box
-             ? nearest_element_shifting_sticky_box
-             : nearest_element_shifting_containing_block;
-}
-
-}  // namespace cc
diff --git a/cc/layers/layer_unittest.cc b/cc/layers/layer_unittest.cc
index bd3b89aa..ebf65ef 100644
--- a/cc/layers/layer_unittest.cc
+++ b/cc/layers/layer_unittest.cc
@@ -415,40 +415,6 @@
       child2->PushPropertiesTo(child2_impl.get());
       grand_child->PushPropertiesTo(grand_child_impl.get()));
 
-  // Setting the sticky constraints requires a subtree change. It shouldn't be
-  // required if they don't change.
-  LayerStickyPositionConstraint arbitrary_constraint;
-  arbitrary_constraint.is_sticky = true;
-  arbitrary_constraint.is_anchored_top = true;
-  arbitrary_constraint.top_offset = 50;
-  EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1);
-  EXECUTE_AND_VERIFY_SUBTREE_CHANGED(
-      root->SetStickyPositionConstraint(arbitrary_constraint));
-  EXECUTE_AND_VERIFY_SUBTREE_CHANGES_RESET(
-      root->PushPropertiesTo(root_impl.get());
-      child->PushPropertiesTo(child_impl.get());
-      child2->PushPropertiesTo(child2_impl.get());
-      grand_child->PushPropertiesTo(grand_child_impl.get());
-      layer_tree_host_->ClearLayersThatShouldPushProperties());
-
-  EXECUTE_AND_VERIFY_SUBTREE_NOT_CHANGED(
-      root->SetStickyPositionConstraint(arbitrary_constraint));
-  EXECUTE_AND_VERIFY_SUBTREE_CHANGES_RESET(
-      root->PushPropertiesTo(root_impl.get());
-      child->PushPropertiesTo(child_impl.get());
-      child2->PushPropertiesTo(child2_impl.get());
-      grand_child->PushPropertiesTo(grand_child_impl.get()));
-
-  arbitrary_constraint.top_offset = 10;
-  EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1);
-  EXECUTE_AND_VERIFY_SUBTREE_CHANGED(
-      root->SetStickyPositionConstraint(arbitrary_constraint));
-  EXECUTE_AND_VERIFY_SUBTREE_CHANGES_RESET(
-      root->PushPropertiesTo(root_impl.get());
-      child->PushPropertiesTo(child_impl.get());
-      child2->PushPropertiesTo(child2_impl.get());
-      grand_child->PushPropertiesTo(grand_child_impl.get()));
-
   gfx::PointF arbitrary_point_f = gfx::PointF(0.125f, 0.25f);
   EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1);
   root->SetPosition(arbitrary_point_f);
diff --git a/cc/test/property_tree_test_utils.cc b/cc/test/property_tree_test_utils.cc
index 87d9415..c370895 100644
--- a/cc/test/property_tree_test_utils.cc
+++ b/cc/test/property_tree_test_utils.cc
@@ -116,12 +116,18 @@
     property_trees->element_id_to_scroll_node_index[node->element_id] =
         node->id;
   }
-  node->transform_id = layer->transform_tree_index();
   node->container_bounds = layer->scroll_container_bounds();
   node->bounds = layer->bounds();
   node->scrollable = layer->scrollable();
   node->user_scrollable_horizontal = true;
   node->user_scrollable_vertical = true;
+
+  DCHECK(layer->has_transform_node());
+  node->transform_id = layer->transform_tree_index();
+  auto* transform_node = GetTransformNode(layer);
+  transform_node->should_be_snapped = true;
+  transform_node->scrolls = true;
+
   scroll_tree.set_needs_update(true);
   return *node;
 }
@@ -183,6 +189,16 @@
   return CreateScrollNodeInternal(layer, parent_id);
 }
 
+void SetScrollOffset(Layer* layer, const gfx::ScrollOffset& scroll_offset) {
+  layer->SetScrollOffset(scroll_offset);
+  auto* transform_node = GetTransformNode(layer);
+  transform_node->scroll_offset = scroll_offset;
+  transform_node->needs_local_transform_update = true;
+  GetPropertyTrees(layer)->transform_tree.set_needs_update(true);
+  GetPropertyTrees(layer)->scroll_tree.SetScrollOffset(layer->element_id(),
+                                                       scroll_offset);
+}
+
 void SetupViewport(Layer* root,
                    scoped_refptr<Layer> outer_scroll_layer,
                    const gfx::Size& outer_bounds) {
@@ -223,11 +239,13 @@
     CopyProperties(overscroll_elasticity_layer.get(), page_scale_layer.get());
     CreateTransformNode(page_scale_layer.get());
     CopyProperties(page_scale_layer.get(), inner_viewport_scroll_layer.get());
+    CreateTransformNode(inner_viewport_scroll_layer.get());
     CreateScrollNode(inner_viewport_scroll_layer.get());
     CopyProperties(inner_viewport_scroll_layer.get(),
                    outer_viewport_container_layer.get());
     CopyProperties(outer_viewport_container_layer.get(),
                    outer_scroll_layer.get());
+    CreateTransformNode(outer_scroll_layer.get());
     CreateScrollNode(outer_scroll_layer.get());
     // TODO(wangxianzhu): Create other property nodes when they are needed by
     // tests newly converted to layer list mode.
@@ -237,9 +255,6 @@
     page_scale_layer->AddChild(inner_viewport_scroll_layer);
     inner_viewport_scroll_layer->AddChild(outer_viewport_container_layer);
     outer_viewport_container_layer->AddChild(outer_scroll_layer);
-
-    inner_viewport_scroll_layer->SetIsContainerForFixedPositionLayers(true);
-    outer_scroll_layer->SetIsContainerForFixedPositionLayers(true);
     root->layer_tree_host()->property_trees()->needs_rebuild = true;
   }
 
diff --git a/cc/test/property_tree_test_utils.h b/cc/test/property_tree_test_utils.h
index d414835..9fab759 100644
--- a/cc/test/property_tree_test_utils.h
+++ b/cc/test/property_tree_test_utils.h
@@ -11,6 +11,7 @@
 #include "cc/trees/property_tree.h"
 #include "cc/trees/scroll_node.h"
 #include "cc/trees/transform_node.h"
+#include "ui/gfx/geometry/scroll_offset.h"
 
 namespace cc {
 
@@ -49,6 +50,8 @@
 ScrollNode& CreateScrollNode(LayerImpl*,
                              int parent_id = ScrollTree::kInvalidNodeId);
 
+void SetScrollOffset(Layer*, const gfx::ScrollOffset&);
+
 template <typename LayerType>
 TransformNode* GetTransformNode(LayerType* layer) {
   return GetPropertyTrees(layer)->transform_tree.Node(
diff --git a/cc/trees/layer_tree_host.cc b/cc/trees/layer_tree_host.cc
index 8352b9a..9683433 100644
--- a/cc/trees/layer_tree_host.cc
+++ b/cc/trees/layer_tree_host.cc
@@ -1567,8 +1567,6 @@
     if (viewport_layers_.outer_viewport_scroll)
       ids.outer_viewport_scroll = viewport_layers_.outer_viewport_scroll->id();
     tree_impl->SetViewportLayersFromIds(ids);
-    DCHECK(IsUsingLayerLists() || viewport_layers_.inner_viewport_scroll
-                                      ->IsContainerForFixedPositionLayers());
   } else {
     tree_impl->ClearViewportLayers();
   }
diff --git a/cc/trees/layer_tree_host_common.cc b/cc/trees/layer_tree_host_common.cc
index 52cfd10..6a0c1ca7 100644
--- a/cc/trees/layer_tree_host_common.cc
+++ b/cc/trees/layer_tree_host_common.cc
@@ -626,13 +626,20 @@
   LayerList update_layer_list;
   PropertyTrees* property_trees =
       inputs->root_layer->layer_tree_host()->property_trees();
-  gfx::Vector2dF elastic_overscroll;
-  PropertyTreeBuilder::BuildPropertyTrees(
-      inputs->root_layer, inputs->page_scale_layer,
-      inputs->inner_viewport_scroll_layer, inputs->outer_viewport_scroll_layer,
-      ElementId(), elastic_overscroll, inputs->page_scale_factor,
-      inputs->device_scale_factor, gfx::Rect(inputs->device_viewport_size),
-      inputs->device_transform, property_trees);
+  if (inputs->root_layer->layer_tree_host()->IsUsingLayerLists()) {
+    // TODO(wangxianzhu): We should DCHECK(!needs_rebuild) after we remove all
+    // unnecessary setting of the flag in layer list mode.
+    property_trees->needs_rebuild = false;
+  } else {
+    gfx::Vector2dF elastic_overscroll;
+    PropertyTreeBuilder::BuildPropertyTrees(
+        inputs->root_layer, inputs->page_scale_layer,
+        inputs->inner_viewport_scroll_layer,
+        inputs->outer_viewport_scroll_layer, ElementId(), elastic_overscroll,
+        inputs->page_scale_factor, inputs->device_scale_factor,
+        gfx::Rect(inputs->device_viewport_size), inputs->device_transform,
+        property_trees);
+  }
   draw_property_utils::UpdatePropertyTrees(
       inputs->root_layer->layer_tree_host(), property_trees);
   draw_property_utils::FindLayersThatNeedUpdates(
diff --git a/cc/trees/layer_tree_host_common_unittest.cc b/cc/trees/layer_tree_host_common_unittest.cc
index 55b7c53..fae8050 100644
--- a/cc/trees/layer_tree_host_common_unittest.cc
+++ b/cc/trees/layer_tree_host_common_unittest.cc
@@ -5925,74 +5925,9 @@
             render_surface_list_impl()->at(2));
 }
 
-TEST_F(LayerTreeHostCommonTest, FixedPositionWithInterveningRenderSurface) {
-  // Ensures that when we have a render surface between a fixed position layer
-  // and its container, we compute the fixed position layer's draw transform
-  // with respect to that intervening render surface, not with respect to its
-  // container's render target.
-  //
-  // + root
-  //   + render_surface
-  //     + fixed
-  //       + child
-  //
-  LayerImpl* root = root_layer_for_testing();
-  LayerImpl* render_surface = AddChild<LayerImpl>(root);
-  LayerImpl* fixed = AddChild<LayerImpl>(render_surface);
-  LayerImpl* child = AddChild<LayerImpl>(fixed);
-
-  render_surface->test_properties()->force_render_surface = true;
-  root->test_properties()->is_container_for_fixed_position_layers = true;
-
-  LayerPositionConstraint constraint;
-  constraint.set_is_fixed_position(true);
-  fixed->test_properties()->position_constraint = constraint;
-
-  root->SetBounds(gfx::Size(50, 50));
-  render_surface->test_properties()->position = gfx::PointF(7.f, 9.f);
-  render_surface->SetBounds(gfx::Size(50, 50));
-  render_surface->SetDrawsContent(true);
-  fixed->test_properties()->position = gfx::PointF(10.f, 15.f);
-  fixed->SetBounds(gfx::Size(50, 50));
-  fixed->SetDrawsContent(true);
-  child->test_properties()->position = gfx::PointF(1.f, 2.f);
-  child->SetBounds(gfx::Size(50, 50));
-  child->SetDrawsContent(true);
-  ExecuteCalculateDrawProperties(root);
-
-  TransformTree& transform_tree =
-      host_impl()->active_tree()->property_trees()->transform_tree;
-  EffectTree& effect_tree =
-      host_impl()->active_tree()->property_trees()->effect_tree;
-
-  gfx::Transform expected_fixed_draw_transform;
-  expected_fixed_draw_transform.Translate(10.f, 15.f);
-  EXPECT_TRANSFORMATION_MATRIX_EQ(
-      expected_fixed_draw_transform,
-      draw_property_utils::DrawTransform(fixed, transform_tree, effect_tree));
-
-  gfx::Transform expected_fixed_screen_space_transform;
-  expected_fixed_screen_space_transform.Translate(17.f, 24.f);
-  EXPECT_TRANSFORMATION_MATRIX_EQ(
-      expected_fixed_screen_space_transform,
-      draw_property_utils::ScreenSpaceTransform(fixed, transform_tree));
-
-  gfx::Transform expected_child_draw_transform;
-  expected_child_draw_transform.Translate(11.f, 17.f);
-  EXPECT_TRANSFORMATION_MATRIX_EQ(
-      expected_child_draw_transform,
-      draw_property_utils::DrawTransform(child, transform_tree, effect_tree));
-
-  gfx::Transform expected_child_screen_space_transform;
-  expected_child_screen_space_transform.Translate(18.f, 26.f);
-  EXPECT_TRANSFORMATION_MATRIX_EQ(
-      expected_child_screen_space_transform,
-      draw_property_utils::ScreenSpaceTransform(child, transform_tree));
-}
-
-TEST_F(LayerTreeHostCommonTest, ScrollCompensationWithRounding) {
-  // This test verifies that a scrolling layer that gets snapped to
-  // integer coordinates doesn't move a fixed position child.
+TEST_F(LayerTreeHostCommonTest, ScrollSnapping) {
+  // This test verifies that a scrolling layer gets snapped to integer
+  // coordinates.
   //
   // + root
   //   + container
@@ -6008,19 +5943,9 @@
   LayerImpl* root = root_ptr.get();
   std::unique_ptr<LayerImpl> container =
       LayerImpl::Create(host_impl.active_tree(), 2);
-  LayerImpl* container_layer = container.get();
   std::unique_ptr<LayerImpl> scroller =
       LayerImpl::Create(host_impl.active_tree(), 3);
   LayerImpl* scroll_layer = scroller.get();
-  std::unique_ptr<LayerImpl> fixed =
-      LayerImpl::Create(host_impl.active_tree(), 4);
-  LayerImpl* fixed_layer = fixed.get();
-
-  container->test_properties()->is_container_for_fixed_position_layers = true;
-
-  LayerPositionConstraint constraint;
-  constraint.set_is_fixed_position(true);
-  fixed->test_properties()->position_constraint = constraint;
 
   scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id()));
 
@@ -6035,10 +5960,7 @@
   scroller->SetBounds(gfx::Size(30, 30));
   scroller->SetScrollable(container->bounds());
   scroller->SetDrawsContent(true);
-  fixed->SetBounds(gfx::Size(50, 50));
-  fixed->SetDrawsContent(true);
 
-  scroller->test_properties()->AddChild(std::move(fixed));
   container->test_properties()->AddChild(std::move(scroller));
   root->test_properties()->AddChild(std::move(container));
   root->layer_tree_impl()->SetRootLayerForTesting(std::move(root_ptr));
@@ -6057,12 +5979,6 @@
         ->transform_tree.set_source_to_parent_updates_allowed(false);
     LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&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);
@@ -6080,43 +5996,10 @@
         root, root->bounds(), &render_surface_list);
     LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&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.
-  {
-    SetScrollOffsetDelta(scroll_layer, gfx::Vector2dF());
-    gfx::Transform scaled_container_transform = container_transform;
-    scaled_container_transform.Scale3d(2.0, 2.0, 1.0);
-    container_layer->test_properties()->transform = scaled_container_transform;
-
-    root->layer_tree_impl()->property_trees()->needs_rebuild = true;
-
-    gfx::Vector2dF scroll_delta(4.5f, 8.5f);
-    SetScrollOffsetDelta(scroll_layer, scroll_delta);
-
-    RenderSurfaceList render_surface_list;
-    LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
-        root, root->bounds(), &render_surface_list);
-    LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&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->test_properties()->transform = container_transform;
-  }
 }
 
 TEST_F(LayerTreeHostCommonTest,
@@ -6229,168 +6112,132 @@
                                   scroll_child_impl->ScreenSpaceTransform());
 }
 
-TEST_F(LayerTreeHostCommonTest, StickyPositionTop) {
-  scoped_refptr<Layer> root = Layer::Create();
-  scoped_refptr<Layer> container = Layer::Create();
-  scoped_refptr<Layer> scroller = Layer::Create();
-  scoped_refptr<Layer> sticky_pos = Layer::Create();
-  root->AddChild(container);
-  container->AddChild(scroller);
-  scroller->AddChild(sticky_pos);
-  host()->SetRootLayer(root);
-  scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id()));
+class LayerTreeHostCommonStickyPositionTest
+    : public LayerTreeHostCommonTestWithLayerLists {
+ protected:
+  // Setup layers and property trees.
+  // Virtual layer hierarchy:
+  // + root
+  //   + container
+  //     + scroller
+  //       + sticky_pos
+  void CreateTree() {
+    CreateRootAndScroller();
+    sticky_pos_ = CreateSticky(scroller_.get());
+  }
 
-  LayerStickyPositionConstraint sticky_position;
-  sticky_position.is_sticky = true;
+  void CreateRootAndScroller() {
+    root_ = Layer::Create();
+    container_ = Layer::Create();
+    scroller_ = Layer::Create();
+    scroller_->SetElementId(LayerIdToElementIdForTesting(scroller_->id()));
+
+    root_->SetBounds(gfx::Size(100, 100));
+    host()->SetRootLayer(root_);
+    SetupRootProperties(root_.get());
+
+    container_->SetBounds(gfx::Size(100, 100));
+    CopyProperties(root_.get(), container_.get());
+    root_->AddChild(container_);
+
+    scroller_->SetBounds(gfx::Size(1000, 1000));
+    scroller_->SetScrollable(container_->bounds());
+    CopyProperties(container_.get(), scroller_.get());
+    CreateTransformNode(scroller_.get()).should_be_snapped = true;
+    CreateScrollNode(scroller_.get());
+    root_->AddChild(scroller_);
+  }
+
+  scoped_refptr<Layer> CreateSticky(Layer* parent) {
+    scoped_refptr<Layer> sticky = Layer::Create();
+    sticky->SetBounds(gfx::Size(10, 10));
+    CopyProperties(parent, sticky.get());
+    CreateTransformNode(sticky.get());
+    EnsureStickyData(sticky.get()).scroll_ancestor =
+        parent->scroll_tree_index();
+    root_->AddChild(sticky);
+    return sticky;
+  }
+
+  void CommitAndUpdateImplPointers() {
+    ExecuteCalculateDrawProperties(root_.get());
+    host()->host_impl()->CreatePendingTree();
+    host()->CommitAndCreatePendingTree();
+    host()->host_impl()->ActivateSyncTree();
+    LayerTreeImpl* layer_tree_impl = host()->host_impl()->active_tree();
+    root_impl_ = layer_tree_impl->LayerById(root_->id());
+    scroller_impl_ = layer_tree_impl->LayerById(scroller_->id());
+    sticky_pos_impl_ = layer_tree_impl->LayerById(sticky_pos_->id());
+  }
+
+  StickyPositionNodeData& EnsureStickyData(Layer* layer) {
+    return GetPropertyTrees(layer)->transform_tree.EnsureStickyPositionData(
+        layer->transform_tree_index());
+  }
+
+  scoped_refptr<Layer> root_;
+  scoped_refptr<Layer> container_;
+  scoped_refptr<Layer> scroller_;
+  scoped_refptr<Layer> sticky_pos_;
+  LayerImpl* root_impl_;
+  LayerImpl* scroller_impl_;
+  LayerImpl* sticky_pos_impl_;
+};
+
+TEST_F(LayerTreeHostCommonStickyPositionTest, StickyPositionTop) {
+  CreateTree();
+
+  GetTransformNode(sticky_pos_.get())->post_translation =
+      gfx::Vector2dF(10, 20);
+  auto& sticky_position = EnsureStickyData(sticky_pos_.get()).constraints;
   sticky_position.is_anchored_top = true;
   sticky_position.top_offset = 10.0f;
   sticky_position.scroll_container_relative_sticky_box_rect =
       gfx::Rect(10, 20, 10, 10);
   sticky_position.scroll_container_relative_containing_block_rect =
       gfx::Rect(0, 0, 50, 50);
-  sticky_pos->SetStickyPositionConstraint(sticky_position);
 
-  root->SetBounds(gfx::Size(100, 100));
-  container->SetBounds(gfx::Size(100, 100));
-  scroller->SetBounds(gfx::Size(1000, 1000));
-  scroller->SetScrollable(container->bounds());
-  sticky_pos->SetBounds(gfx::Size(10, 10));
-  sticky_pos->SetPosition(gfx::PointF(10, 20));
+  CommitAndUpdateImplPointers();
 
-  ExecuteCalculateDrawProperties(root.get());
-  host()->host_impl()->CreatePendingTree();
-  host()->CommitAndCreatePendingTree();
-  host()->host_impl()->ActivateSyncTree();
-  LayerTreeImpl* layer_tree_impl = host()->host_impl()->active_tree();
-
-  LayerImpl* root_impl = layer_tree_impl->LayerById(root->id());
-  LayerImpl* scroller_impl = layer_tree_impl->LayerById(scroller->id());
-  LayerImpl* sticky_pos_impl = layer_tree_impl->LayerById(sticky_pos->id());
-
-  ExecuteCalculateDrawProperties(root_impl);
   EXPECT_VECTOR2DF_EQ(
       gfx::Vector2dF(10.f, 20.f),
-      sticky_pos_impl->ScreenSpaceTransform().To2dTranslation());
+      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
 
   // Scroll less than sticking point, sticky element should move with scroll as
   // we haven't gotten to the initial sticky item location yet.
-  SetScrollOffsetDelta(scroller_impl, gfx::Vector2dF(5.f, 5.f));
-  ExecuteCalculateDrawProperties(root_impl);
+  SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(5.f, 5.f));
+  ExecuteCalculateDrawProperties(root_impl_);
   EXPECT_VECTOR2DF_EQ(
       gfx::Vector2dF(5.f, 15.f),
-      sticky_pos_impl->ScreenSpaceTransform().To2dTranslation());
+      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
 
   // Scroll past the sticking point, the Y coordinate should now be clamped.
-  SetScrollOffsetDelta(scroller_impl, gfx::Vector2dF(15.f, 15.f));
-  ExecuteCalculateDrawProperties(root_impl);
+  SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(15.f, 15.f));
+  ExecuteCalculateDrawProperties(root_impl_);
   EXPECT_VECTOR2DF_EQ(
       gfx::Vector2dF(-5.f, 10.f),
-      sticky_pos_impl->ScreenSpaceTransform().To2dTranslation());
-  SetScrollOffsetDelta(scroller_impl, gfx::Vector2dF(15.f, 25.f));
-  ExecuteCalculateDrawProperties(root_impl);
+      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
+  SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(15.f, 25.f));
+  ExecuteCalculateDrawProperties(root_impl_);
   EXPECT_VECTOR2DF_EQ(
       gfx::Vector2dF(-5.f, 10.f),
-      sticky_pos_impl->ScreenSpaceTransform().To2dTranslation());
+      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
 
   // Scroll past the end of the sticky container (note: this element does not
   // have its own layer as it does not need to be composited).
-  SetScrollOffsetDelta(scroller_impl, gfx::Vector2dF(15.f, 50.f));
-  ExecuteCalculateDrawProperties(root_impl);
+  SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(15.f, 50.f));
+  ExecuteCalculateDrawProperties(root_impl_);
   EXPECT_VECTOR2DF_EQ(
       gfx::Vector2dF(-5.f, -10.f),
-      sticky_pos_impl->ScreenSpaceTransform().To2dTranslation());
+      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
 }
 
-TEST_F(LayerTreeHostCommonTest, StickyPositionTopScrollParent) {
-  scoped_refptr<Layer> root = Layer::Create();
-  scoped_refptr<Layer> container = Layer::Create();
-  scoped_refptr<Layer> scroller = Layer::Create();
-  scoped_refptr<Layer> sticky_pos = Layer::Create();
-  root->AddChild(container);
-  container->AddChild(scroller);
-  root->AddChild(sticky_pos);
-  sticky_pos->SetScrollParent(scroller.get());
-  host()->SetRootLayer(root);
-  scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id()));
+TEST_F(LayerTreeHostCommonStickyPositionTest, StickyPositionSubpixelScroll) {
+  CreateTree();
 
-  // The sticky layer has already been scrolled on the main thread side, and has
-  // stuck. This test then checks that further changes from cc-only scrolling
-  // are handled correctly.
-  LayerStickyPositionConstraint sticky_position;
-  sticky_position.is_sticky = true;
-  sticky_position.is_anchored_top = true;
-  sticky_position.top_offset = 10.0f;
-  sticky_position.scroll_container_relative_sticky_box_rect =
-      gfx::Rect(10, 20, 10, 10);
-  sticky_position.scroll_container_relative_containing_block_rect =
-      gfx::Rect(0, 0, 50, 50);
-  sticky_pos->SetStickyPositionConstraint(sticky_position);
-
-  root->SetBounds(gfx::Size(200, 200));
-  container->SetBounds(gfx::Size(100, 100));
-  container->SetPosition(gfx::PointF(50, 50));
-  scroller->SetBounds(gfx::Size(1000, 1000));
-  scroller->SetScrollable(container->bounds());
-  sticky_pos->SetBounds(gfx::Size(10, 10));
-  sticky_pos->SetPosition(gfx::PointF(60, 70));
-
-  ExecuteCalculateDrawProperties(root.get());
-  host()->host_impl()->CreatePendingTree();
-  host()->CommitAndCreatePendingTree();
-  host()->host_impl()->ActivateSyncTree();
-  LayerTreeImpl* layer_tree_impl = host()->host_impl()->active_tree();
-
-  LayerImpl* root_impl = layer_tree_impl->LayerById(root->id());
-  LayerImpl* scroller_impl = layer_tree_impl->LayerById(scroller->id());
-  LayerImpl* sticky_pos_impl = layer_tree_impl->LayerById(sticky_pos->id());
-
-  ExecuteCalculateDrawProperties(root_impl);
-  EXPECT_VECTOR2DF_EQ(
-      gfx::Vector2dF(60.f, 70.f),
-      sticky_pos_impl->ScreenSpaceTransform().To2dTranslation());
-
-  // Scroll less than sticking point, sticky element should move with scroll as
-  // we haven't gotten to the initial sticky item location yet.
-  SetScrollOffsetDelta(scroller_impl, gfx::Vector2dF(5.f, 5.f));
-  ExecuteCalculateDrawProperties(root_impl);
-  EXPECT_VECTOR2DF_EQ(
-      gfx::Vector2dF(55.f, 65.f),
-      sticky_pos_impl->ScreenSpaceTransform().To2dTranslation());
-
-  // Scroll past the sticking point, the Y coordinate should now be clamped.
-  SetScrollOffsetDelta(scroller_impl, gfx::Vector2dF(15.f, 15.f));
-  ExecuteCalculateDrawProperties(root_impl);
-  EXPECT_VECTOR2DF_EQ(
-      gfx::Vector2dF(45.f, 60.f),
-      sticky_pos_impl->ScreenSpaceTransform().To2dTranslation());
-  SetScrollOffsetDelta(scroller_impl, gfx::Vector2dF(15.f, 25.f));
-  ExecuteCalculateDrawProperties(root_impl);
-  EXPECT_VECTOR2DF_EQ(
-      gfx::Vector2dF(45.f, 60.f),
-      sticky_pos_impl->ScreenSpaceTransform().To2dTranslation());
-
-  // Scroll past the end of the sticky container (note: this element does not
-  // have its own layer as it does not need to be composited).
-  SetScrollOffsetDelta(scroller_impl, gfx::Vector2dF(15.f, 50.f));
-  ExecuteCalculateDrawProperties(root_impl);
-  EXPECT_VECTOR2DF_EQ(
-      gfx::Vector2dF(45.f, 40.f),
-      sticky_pos_impl->ScreenSpaceTransform().To2dTranslation());
-}
-
-TEST_F(LayerTreeHostCommonTest, StickyPositionSubpixelScroll) {
-  scoped_refptr<Layer> root = Layer::Create();
-  scoped_refptr<Layer> container = Layer::Create();
-  scoped_refptr<Layer> scroller = Layer::Create();
-  scoped_refptr<Layer> sticky_pos = Layer::Create();
-  root->AddChild(container);
-  container->AddChild(scroller);
-  scroller->AddChild(sticky_pos);
-  host()->SetRootLayer(root);
-  scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id()));
-
-  LayerStickyPositionConstraint sticky_position;
-  sticky_position.is_sticky = true;
+  GetTransformNode(sticky_pos_.get())->post_translation =
+      gfx::Vector2dF(0, 200);
+  auto& sticky_position = EnsureStickyData(sticky_pos_.get()).constraints;
   sticky_position.is_anchored_bottom = true;
   sticky_position.bottom_offset = 10.0f;
   sticky_position.constraint_box_rect = gfx::Rect(0, 0, 100, 100);
@@ -6398,46 +6245,22 @@
       gfx::Rect(0, 200, 10, 10);
   sticky_position.scroll_container_relative_containing_block_rect =
       gfx::Rect(0, 0, 100, 500);
-  sticky_pos->SetStickyPositionConstraint(sticky_position);
 
-  root->SetBounds(gfx::Size(100, 100));
-  container->SetBounds(gfx::Size(100, 100));
-  scroller->SetBounds(gfx::Size(100, 1000));
-  scroller->SetScrollable(container->bounds());
-  sticky_pos->SetBounds(gfx::Size(10, 10));
-  sticky_pos->SetPosition(gfx::PointF(0, 200));
+  CommitAndUpdateImplPointers();
 
-  ExecuteCalculateDrawProperties(root.get());
-  host()->host_impl()->CreatePendingTree();
-  host()->CommitAndCreatePendingTree();
-  host()->host_impl()->ActivateSyncTree();
-  LayerTreeImpl* layer_tree_impl = host()->host_impl()->active_tree();
-
-  LayerImpl* root_impl = layer_tree_impl->LayerById(root->id());
-  LayerImpl* scroller_impl = layer_tree_impl->LayerById(scroller->id());
-  LayerImpl* sticky_pos_impl = layer_tree_impl->LayerById(sticky_pos->id());
-
-  ExecuteCalculateDrawProperties(root_impl);
-  SetScrollOffsetDelta(scroller_impl, gfx::Vector2dF(0.f, 0.8f));
-  ExecuteCalculateDrawProperties(root_impl);
+  SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 0.8f));
+  ExecuteCalculateDrawProperties(root_impl_);
   EXPECT_VECTOR2DF_EQ(
       gfx::Vector2dF(0.f, 80.f),
-      sticky_pos_impl->ScreenSpaceTransform().To2dTranslation());
+      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
 }
 
-TEST_F(LayerTreeHostCommonTest, StickyPositionBottom) {
-  scoped_refptr<Layer> root = Layer::Create();
-  scoped_refptr<Layer> container = Layer::Create();
-  scoped_refptr<Layer> scroller = Layer::Create();
-  scoped_refptr<Layer> sticky_pos = Layer::Create();
-  root->AddChild(container);
-  container->AddChild(scroller);
-  scroller->AddChild(sticky_pos);
-  host()->SetRootLayer(root);
-  scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id()));
+TEST_F(LayerTreeHostCommonStickyPositionTest, StickyPositionBottom) {
+  CreateTree();
 
-  LayerStickyPositionConstraint sticky_position;
-  sticky_position.is_sticky = true;
+  GetTransformNode(sticky_pos_.get())->post_translation =
+      gfx::Vector2dF(0, 150);
+  auto& sticky_position = EnsureStickyData(sticky_pos_.get()).constraints;
   sticky_position.is_anchored_bottom = true;
   sticky_position.bottom_offset = 10.0f;
   sticky_position.constraint_box_rect = gfx::Rect(0, 0, 100, 100);
@@ -6445,81 +6268,52 @@
       gfx::Rect(0, 150, 10, 10);
   sticky_position.scroll_container_relative_containing_block_rect =
       gfx::Rect(0, 100, 50, 50);
-  sticky_pos->SetStickyPositionConstraint(sticky_position);
 
-  root->SetBounds(gfx::Size(100, 100));
-  container->SetBounds(gfx::Size(100, 100));
-  scroller->SetBounds(gfx::Size(1000, 1000));
-  scroller->SetScrollable(container->bounds());
-  sticky_pos->SetBounds(gfx::Size(10, 10));
-  sticky_pos->SetPosition(gfx::PointF(0, 150));
-
-  ExecuteCalculateDrawProperties(root.get());
-  host()->host_impl()->CreatePendingTree();
-  host()->CommitAndCreatePendingTree();
-  host()->host_impl()->ActivateSyncTree();
-  LayerTreeImpl* layer_tree_impl = host()->host_impl()->active_tree();
-
-  LayerImpl* root_impl = layer_tree_impl->LayerById(root->id());
-  LayerImpl* scroller_impl = layer_tree_impl->LayerById(scroller->id());
-  LayerImpl* sticky_pos_impl = layer_tree_impl->LayerById(sticky_pos->id());
+  CommitAndUpdateImplPointers();
 
   // Initially the sticky element is moved up to the top of the container.
-  ExecuteCalculateDrawProperties(root_impl);
   EXPECT_VECTOR2DF_EQ(
       gfx::Vector2dF(0.f, 100.f),
-      sticky_pos_impl->ScreenSpaceTransform().To2dTranslation());
-  SetScrollOffsetDelta(scroller_impl, gfx::Vector2dF(0.f, 5.f));
-  ExecuteCalculateDrawProperties(root_impl);
+      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
+  SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 5.f));
+  ExecuteCalculateDrawProperties(root_impl_);
   EXPECT_VECTOR2DF_EQ(
       gfx::Vector2dF(0.f, 95.f),
-      sticky_pos_impl->ScreenSpaceTransform().To2dTranslation());
+      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
 
   // Once we get past the top of the container it moves to be aligned 10px
   // up from the the bottom of the scroller.
-  SetScrollOffsetDelta(scroller_impl, gfx::Vector2dF(0.f, 25.f));
-  ExecuteCalculateDrawProperties(root_impl);
+  SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 25.f));
+  ExecuteCalculateDrawProperties(root_impl_);
   EXPECT_VECTOR2DF_EQ(
       gfx::Vector2dF(0.f, 80.f),
-      sticky_pos_impl->ScreenSpaceTransform().To2dTranslation());
-  SetScrollOffsetDelta(scroller_impl, gfx::Vector2dF(0.f, 30.f));
-  ExecuteCalculateDrawProperties(root_impl);
+      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
+  SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 30.f));
+  ExecuteCalculateDrawProperties(root_impl_);
   EXPECT_VECTOR2DF_EQ(
       gfx::Vector2dF(0.f, 80.f),
-      sticky_pos_impl->ScreenSpaceTransform().To2dTranslation());
+      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
 
   // Once we scroll past its initial location, it sticks there.
-  SetScrollOffsetDelta(scroller_impl, gfx::Vector2dF(0.f, 150.f));
-  ExecuteCalculateDrawProperties(root_impl);
+  SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 150.f));
+  ExecuteCalculateDrawProperties(root_impl_);
   EXPECT_VECTOR2DF_EQ(
       gfx::Vector2dF(0.f, 0.f),
-      sticky_pos_impl->ScreenSpaceTransform().To2dTranslation());
+      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
 }
 
-TEST_F(LayerTreeHostCommonTest, StickyPositionBottomOuterViewportDelta) {
-  scoped_refptr<Layer> root = Layer::Create();
-  scoped_refptr<Layer> page_scale = Layer::Create();
-  scoped_refptr<Layer> scroller = Layer::Create();
-  scoped_refptr<Layer> outer_clip = Layer::Create();
-  scoped_refptr<Layer> outer_viewport = Layer::Create();
-  scoped_refptr<Layer> sticky_pos = Layer::Create();
-  root->AddChild(page_scale);
-  page_scale->AddChild(scroller);
-  scroller->AddChild(outer_clip);
-  outer_clip->AddChild(outer_viewport);
-  outer_viewport->AddChild(sticky_pos);
-  host()->SetRootLayer(root);
-  scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id()));
-  ViewportLayers viewport_layers;
-  viewport_layers.page_scale = page_scale;
-  viewport_layers.inner_viewport_container = root;
-  viewport_layers.outer_viewport_container = outer_clip;
-  viewport_layers.inner_viewport_scroll = scroller;
-  viewport_layers.outer_viewport_scroll = outer_viewport;
-  host()->RegisterViewportLayers(viewport_layers);
+TEST_F(LayerTreeHostCommonStickyPositionTest,
+       StickyPositionBottomOuterViewportDelta) {
+  CreateTree();
 
-  LayerStickyPositionConstraint sticky_position;
-  sticky_position.is_sticky = true;
+  GetScrollNode(scroller_.get())->scrolls_outer_viewport = true;
+
+  auto* sticky_transform = GetTransformNode(sticky_pos_.get());
+  sticky_transform->post_translation = gfx::Vector2dF(0, 70);
+  GetPropertyTrees(sticky_pos_.get())
+      ->transform_tree.AddNodeAffectedByOuterViewportBoundsDelta(
+          sticky_transform->id);
+  auto& sticky_position = EnsureStickyData(sticky_pos_.get()).constraints;
   sticky_position.is_anchored_bottom = true;
   sticky_position.bottom_offset = 10.0f;
   sticky_position.constraint_box_rect = gfx::Rect(0, 0, 100, 100);
@@ -6527,574 +6321,403 @@
       gfx::Rect(0, 70, 10, 10);
   sticky_position.scroll_container_relative_containing_block_rect =
       gfx::Rect(0, 60, 100, 100);
-  sticky_pos->SetStickyPositionConstraint(sticky_position);
 
-  root->SetBounds(gfx::Size(100, 100));
-  scroller->SetScrollable(gfx::Size(100, 100));
-  scroller->SetBounds(gfx::Size(100, 1000));
-  outer_clip->SetBounds(gfx::Size(100, 100));
-  outer_viewport->SetScrollable(gfx::Size(100, 100));
-  sticky_pos->SetBounds(gfx::Size(10, 10));
-  sticky_pos->SetPosition(gfx::PointF(0, 70));
-
-  ExecuteCalculateDrawProperties(root.get(), 1.f, 1.f, nullptr, scroller.get(),
-                                 outer_viewport.get());
-  host()->CommitAndCreateLayerImplTree();
-  LayerTreeImpl* layer_tree_impl = host()->host_impl()->active_tree();
-  LayerImpl* root_impl = layer_tree_impl->LayerById(root->id());
-  ASSERT_EQ(outer_viewport->id(),
-            layer_tree_impl->OuterViewportScrollLayer()->id());
-
-  LayerImpl* inner_scroll = layer_tree_impl->InnerViewportScrollLayer();
-  LayerImpl* outer_scroll = layer_tree_impl->OuterViewportScrollLayer();
-  LayerImpl* sticky_pos_impl = layer_tree_impl->LayerById(sticky_pos->id());
-  LayerImpl* outer_clip_impl = layer_tree_impl->LayerById(outer_clip->id());
+  CommitAndUpdateImplPointers();
 
   // Initially the sticky element is moved to the bottom of the container.
   EXPECT_VECTOR2DF_EQ(
       gfx::Vector2dF(0.f, 70.f),
-      sticky_pos_impl->ScreenSpaceTransform().To2dTranslation());
+      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
 
   // We start to hide the toolbar, but not far enough that the sticky element
   // should be moved up yet.
-  outer_clip_impl->SetViewportBoundsDelta(gfx::Vector2dF(0.f, -10.f));
-  ExecuteCalculateDrawProperties(root_impl, 1.f, 1.f, nullptr, inner_scroll,
-                                 outer_scroll);
+  GetPropertyTrees(scroller_impl_)
+      ->SetOuterViewportContainerBoundsDelta(gfx::Vector2dF(0.f, -10.f));
+  ExecuteCalculateDrawProperties(root_impl_);
   EXPECT_VECTOR2DF_EQ(
       gfx::Vector2dF(0.f, 70.f),
-      sticky_pos_impl->ScreenSpaceTransform().To2dTranslation());
+      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
 
   // On hiding more of the toolbar the sticky element starts to stick.
-  outer_clip_impl->SetViewportBoundsDelta(gfx::Vector2dF(0.f, -20.f));
-  ExecuteCalculateDrawProperties(root_impl, 1.f, 1.f, nullptr, inner_scroll,
-                                 outer_scroll);
+  GetPropertyTrees(scroller_impl_)
+      ->SetOuterViewportContainerBoundsDelta(gfx::Vector2dF(0.f, -20.f));
+  ExecuteCalculateDrawProperties(root_impl_);
 
   // On hiding more the sticky element stops moving as it has reached its
   // limit.
   EXPECT_VECTOR2DF_EQ(
       gfx::Vector2dF(0.f, 60.f),
-      sticky_pos_impl->ScreenSpaceTransform().To2dTranslation());
+      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
 
-  outer_clip_impl->SetViewportBoundsDelta(gfx::Vector2dF(0.f, -30.f));
-  ExecuteCalculateDrawProperties(root_impl, 1.f, 1.f, nullptr, inner_scroll,
-                                 outer_scroll);
+  GetPropertyTrees(scroller_impl_)
+      ->SetOuterViewportContainerBoundsDelta(gfx::Vector2dF(0.f, -30.f));
+  ExecuteCalculateDrawProperties(root_impl_);
 
   EXPECT_VECTOR2DF_EQ(
       gfx::Vector2dF(0.f, 60.f),
-      sticky_pos_impl->ScreenSpaceTransform().To2dTranslation());
+      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
 }
 
-TEST_F(LayerTreeHostCommonTest, StickyPositionLeftRight) {
-  scoped_refptr<Layer> root = Layer::Create();
-  scoped_refptr<Layer> container = Layer::Create();
-  scoped_refptr<Layer> scroller = Layer::Create();
-  scoped_refptr<Layer> sticky_pos = Layer::Create();
-  root->AddChild(container);
-  container->AddChild(scroller);
-  scroller->AddChild(sticky_pos);
-  host()->SetRootLayer(root);
-  scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id()));
+TEST_F(LayerTreeHostCommonStickyPositionTest, StickyPositionLeftRight) {
+  CreateTree();
 
-  LayerStickyPositionConstraint sticky_position;
-  sticky_position.is_sticky = true;
+  GetTransformNode(sticky_pos_.get())->post_translation =
+      gfx::Vector2dF(145, 0);
+  auto& sticky_position = EnsureStickyData(sticky_pos_.get()).constraints;
   sticky_position.is_anchored_left = true;
   sticky_position.is_anchored_right = true;
-  sticky_position.left_offset = 10.f;
-  sticky_position.right_offset = 10.f;
+  sticky_position.left_offset = 10.0f;
+  sticky_position.right_offset = 10.0f;
   sticky_position.constraint_box_rect = gfx::Rect(0, 0, 100, 100);
   sticky_position.scroll_container_relative_sticky_box_rect =
       gfx::Rect(145, 0, 10, 10);
   sticky_position.scroll_container_relative_containing_block_rect =
       gfx::Rect(100, 0, 100, 100);
-  sticky_pos->SetStickyPositionConstraint(sticky_position);
 
-  root->SetBounds(gfx::Size(100, 100));
-  container->SetBounds(gfx::Size(100, 100));
-  scroller->SetBounds(gfx::Size(1000, 1000));
-  scroller->SetScrollable(container->bounds());
-  sticky_pos->SetBounds(gfx::Size(10, 10));
-  sticky_pos->SetPosition(gfx::PointF(145, 0));
-
-  ExecuteCalculateDrawProperties(root.get());
-  host()->host_impl()->CreatePendingTree();
-  host()->CommitAndCreatePendingTree();
-  host()->host_impl()->ActivateSyncTree();
-  LayerTreeImpl* layer_tree_impl = host()->host_impl()->active_tree();
-
-  LayerImpl* root_impl = layer_tree_impl->LayerById(root->id());
-  LayerImpl* scroller_impl = layer_tree_impl->LayerById(scroller->id());
-  LayerImpl* sticky_pos_impl = layer_tree_impl->LayerById(sticky_pos->id());
+  CommitAndUpdateImplPointers();
 
   // Initially the sticky element is moved the leftmost side of the container.
-  ExecuteCalculateDrawProperties(root_impl);
+  ExecuteCalculateDrawProperties(root_impl_);
   EXPECT_VECTOR2DF_EQ(
       gfx::Vector2dF(100.f, 0.f),
-      sticky_pos_impl->ScreenSpaceTransform().To2dTranslation());
-  SetScrollOffsetDelta(scroller_impl, gfx::Vector2dF(5.f, 0.f));
-  ExecuteCalculateDrawProperties(root_impl);
+      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
+  SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(5.f, 0.f));
+  ExecuteCalculateDrawProperties(root_impl_);
   EXPECT_VECTOR2DF_EQ(
       gfx::Vector2dF(95.f, 0.f),
-      sticky_pos_impl->ScreenSpaceTransform().To2dTranslation());
+      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
 
   // Once we get past the left side of the container it moves to be aligned 10px
   // up from the the right of the scroller.
-  SetScrollOffsetDelta(scroller_impl, gfx::Vector2dF(25.f, 0.f));
-  ExecuteCalculateDrawProperties(root_impl);
+  SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(25.f, 0.f));
+  ExecuteCalculateDrawProperties(root_impl_);
   EXPECT_VECTOR2DF_EQ(
       gfx::Vector2dF(80.f, 0.f),
-      sticky_pos_impl->ScreenSpaceTransform().To2dTranslation());
-  SetScrollOffsetDelta(scroller_impl, gfx::Vector2dF(30.f, 0.f));
-  ExecuteCalculateDrawProperties(root_impl);
+      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
+  SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(30.f, 0.f));
+  ExecuteCalculateDrawProperties(root_impl_);
   EXPECT_VECTOR2DF_EQ(
       gfx::Vector2dF(80.f, 0.f),
-      sticky_pos_impl->ScreenSpaceTransform().To2dTranslation());
+      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
 
   // When we get to the sticky element's original position we stop sticking
   // to the right.
-  SetScrollOffsetDelta(scroller_impl, gfx::Vector2dF(95.f, 0.f));
-  ExecuteCalculateDrawProperties(root_impl);
+  SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(95.f, 0.f));
+  ExecuteCalculateDrawProperties(root_impl_);
   EXPECT_VECTOR2DF_EQ(
       gfx::Vector2dF(50.f, 0.f),
-      sticky_pos_impl->ScreenSpaceTransform().To2dTranslation());
-  SetScrollOffsetDelta(scroller_impl, gfx::Vector2dF(105.f, 0.f));
-  ExecuteCalculateDrawProperties(root_impl);
+      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
+  SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(105.f, 0.f));
+  ExecuteCalculateDrawProperties(root_impl_);
   EXPECT_VECTOR2DF_EQ(
       gfx::Vector2dF(40.f, 0.f),
-      sticky_pos_impl->ScreenSpaceTransform().To2dTranslation());
+      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
 
   // The element starts sticking to the left once we scroll far enough.
-  SetScrollOffsetDelta(scroller_impl, gfx::Vector2dF(150.f, 0.f));
-  ExecuteCalculateDrawProperties(root_impl);
+  SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(150.f, 0.f));
+  ExecuteCalculateDrawProperties(root_impl_);
   EXPECT_VECTOR2DF_EQ(
       gfx::Vector2dF(10.f, 0.f),
-      sticky_pos_impl->ScreenSpaceTransform().To2dTranslation());
-  SetScrollOffsetDelta(scroller_impl, gfx::Vector2dF(155.f, 0.f));
-  ExecuteCalculateDrawProperties(root_impl);
+      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
+  SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(155.f, 0.f));
+  ExecuteCalculateDrawProperties(root_impl_);
   EXPECT_VECTOR2DF_EQ(
       gfx::Vector2dF(10.f, 0.f),
-      sticky_pos_impl->ScreenSpaceTransform().To2dTranslation());
+      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
 
   // Finally it stops sticking when it hits the right side of the container.
-  SetScrollOffsetDelta(scroller_impl, gfx::Vector2dF(190.f, 0.f));
-  ExecuteCalculateDrawProperties(root_impl);
+  SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(190.f, 0.f));
+  ExecuteCalculateDrawProperties(root_impl_);
   EXPECT_VECTOR2DF_EQ(
       gfx::Vector2dF(0.f, 0.f),
-      sticky_pos_impl->ScreenSpaceTransform().To2dTranslation());
-  SetScrollOffsetDelta(scroller_impl, gfx::Vector2dF(195.f, 0.f));
-  ExecuteCalculateDrawProperties(root_impl);
+      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
+  SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(195.f, 0.f));
+  ExecuteCalculateDrawProperties(root_impl_);
   EXPECT_VECTOR2DF_EQ(
       gfx::Vector2dF(-5.f, 0.f),
-      sticky_pos_impl->ScreenSpaceTransform().To2dTranslation());
+      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
 }
 
 // This test ensures that the compositor sticky position code correctly accounts
 // for the element having been given a position from the main thread sticky
 // position code.
-TEST_F(LayerTreeHostCommonTest, StickyPositionMainThreadUpdates) {
-  scoped_refptr<Layer> root = Layer::Create();
-  scoped_refptr<Layer> container = Layer::Create();
-  scoped_refptr<Layer> scroller = Layer::Create();
-  scoped_refptr<Layer> sticky_pos = Layer::Create();
-  root->AddChild(container);
-  container->AddChild(scroller);
-  scroller->AddChild(sticky_pos);
-  host()->SetRootLayer(root);
-  scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id()));
+TEST_F(LayerTreeHostCommonStickyPositionTest, StickyPositionMainThreadUpdates) {
+  CreateTree();
 
-  LayerStickyPositionConstraint sticky_position;
-  sticky_position.is_sticky = true;
+  GetTransformNode(sticky_pos_.get())->post_translation =
+      gfx::Vector2dF(10, 20);
+  auto& sticky_position = EnsureStickyData(sticky_pos_.get()).constraints;
   sticky_position.is_anchored_top = true;
   sticky_position.top_offset = 10.0f;
   sticky_position.scroll_container_relative_sticky_box_rect =
       gfx::Rect(10, 20, 10, 10);
   sticky_position.scroll_container_relative_containing_block_rect =
       gfx::Rect(0, 0, 50, 50);
-  sticky_pos->SetStickyPositionConstraint(sticky_position);
 
-  root->SetBounds(gfx::Size(100, 100));
-  container->SetBounds(gfx::Size(100, 100));
-  scroller->SetBounds(gfx::Size(1000, 1000));
-  scroller->SetScrollable(container->bounds());
-  sticky_pos->SetBounds(gfx::Size(10, 10));
-  sticky_pos->SetPosition(gfx::PointF(10, 20));
+  CommitAndUpdateImplPointers();
 
-  ExecuteCalculateDrawProperties(root.get());
-  host()->host_impl()->CreatePendingTree();
-  host()->CommitAndCreatePendingTree();
-  host()->host_impl()->ActivateSyncTree();
-  LayerTreeImpl* layer_tree_impl = host()->host_impl()->active_tree();
-
-  LayerImpl* root_impl = layer_tree_impl->LayerById(root->id());
-  LayerImpl* scroller_impl = layer_tree_impl->LayerById(scroller->id());
-  LayerImpl* sticky_pos_impl = layer_tree_impl->LayerById(sticky_pos->id());
-
-  ExecuteCalculateDrawProperties(root_impl);
   EXPECT_VECTOR2DF_EQ(
       gfx::Vector2dF(10.f, 20.f),
-      sticky_pos_impl->ScreenSpaceTransform().To2dTranslation());
+      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
 
   // Scroll less than sticking point, sticky element should move with scroll as
   // we haven't gotten to the initial sticky item location yet.
-  SetScrollOffsetDelta(scroller_impl, gfx::Vector2dF(5.f, 5.f));
-  ExecuteCalculateDrawProperties(root_impl);
+  SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(5.f, 5.f));
+  ExecuteCalculateDrawProperties(root_impl_);
   EXPECT_VECTOR2DF_EQ(
       gfx::Vector2dF(5.f, 15.f),
-      sticky_pos_impl->ScreenSpaceTransform().To2dTranslation());
+      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
 
   // Scroll past the sticking point, the Y coordinate should now be clamped.
-  SetScrollOffsetDelta(scroller_impl, gfx::Vector2dF(15.f, 15.f));
-  ExecuteCalculateDrawProperties(root_impl);
+  SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(15.f, 15.f));
+  ExecuteCalculateDrawProperties(root_impl_);
   EXPECT_VECTOR2DF_EQ(
       gfx::Vector2dF(-5.f, 10.f),
-      sticky_pos_impl->ScreenSpaceTransform().To2dTranslation());
+      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
 
   // Now the main thread commits the new position of the sticky element.
-  scroller->SetScrollOffset(gfx::ScrollOffset(15, 15));
+  SetScrollOffset(scroller_.get(), gfx::ScrollOffset(15, 15));
   // Shift the layer by -offset_for_position_sticky.
-  sticky_pos->SetPosition(gfx::PointF(10, 25) - gfx::Vector2dF(0, 5));
-  ExecuteCalculateDrawProperties(root.get());
-  host()->host_impl()->CreatePendingTree();
-  host()->CommitAndCreatePendingTree();
-  host()->host_impl()->ActivateSyncTree();
-  layer_tree_impl = host()->host_impl()->active_tree();
-  root_impl = layer_tree_impl->LayerById(root->id());
-  scroller_impl = layer_tree_impl->LayerById(scroller->id());
-  sticky_pos_impl = layer_tree_impl->LayerById(sticky_pos->id());
+  auto* sticky_transform = GetTransformNode(sticky_pos_.get());
+  sticky_transform->post_translation = gfx::PointF(10, 25) - gfx::PointF(0, 5);
+  sticky_transform->needs_local_transform_update = true;
+  GetPropertyTrees(scroller_.get())->transform_tree.set_needs_update(true);
+
+  CommitAndUpdateImplPointers();
 
   // The element should still be where it was before. We reset the delta to
   // (0, 0) because we have synced a scroll offset of (15, 15) from the main
   // thread.
-  SetScrollOffsetDelta(scroller_impl, gfx::Vector2dF(0.f, 0.f));
-  ExecuteCalculateDrawProperties(root_impl);
+  SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 0.f));
+  ExecuteCalculateDrawProperties(root_impl_);
   EXPECT_VECTOR2DF_EQ(
       gfx::Vector2dF(-5.f, 10.f),
-      sticky_pos_impl->ScreenSpaceTransform().To2dTranslation());
+      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
 
   // And if we scroll a little further it remains there.
-  SetScrollOffsetDelta(scroller_impl, gfx::Vector2dF(0.f, 10.f));
-  ExecuteCalculateDrawProperties(root_impl);
+  SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 10.f));
+  ExecuteCalculateDrawProperties(root_impl_);
   EXPECT_VECTOR2DF_EQ(
       gfx::Vector2dF(-5.f, 10.f),
-      sticky_pos_impl->ScreenSpaceTransform().To2dTranslation());
+      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
 }
 
 // This tests the main thread updates with a composited sticky container. In
 // this case the position received from main is relative to the container but
 // the constraint rects are relative to the ancestor scroller.
-TEST_F(LayerTreeHostCommonTest, StickyPositionCompositedContainer) {
-  scoped_refptr<Layer> root = Layer::Create();
-  scoped_refptr<Layer> container = Layer::Create();
-  scoped_refptr<Layer> scroller = Layer::Create();
-  scoped_refptr<Layer> sticky_container = Layer::Create();
-  scoped_refptr<Layer> sticky_pos = Layer::Create();
-  root->AddChild(container);
-  container->AddChild(scroller);
-  scroller->AddChild(sticky_container);
-  sticky_container->AddChild(sticky_pos);
-  host()->SetRootLayer(root);
-  scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id()));
+TEST_F(LayerTreeHostCommonStickyPositionTest,
+       StickyPositionCompositedContainer) {
+  CreateRootAndScroller();
 
-  LayerStickyPositionConstraint sticky_position;
-  sticky_position.is_sticky = true;
+  scoped_refptr<Layer> sticky_container = Layer::Create();
+  sticky_container->SetBounds(gfx::Size(30, 30));
+  sticky_container->SetOffsetToTransformParent(gfx::Vector2dF(20, 20));
+  CopyProperties(scroller_.get(), sticky_container.get());
+  root_->AddChild(sticky_container);
+
+  sticky_pos_ = CreateSticky(sticky_container.get());
+  GetTransformNode(sticky_pos_.get())->post_translation =
+      gfx::Vector2dF(0, 10) + sticky_container->offset_to_transform_parent();
+  auto& sticky_position = EnsureStickyData(sticky_pos_.get()).constraints;
   sticky_position.is_anchored_top = true;
   sticky_position.top_offset = 10.0f;
   sticky_position.scroll_container_relative_sticky_box_rect =
       gfx::Rect(20, 30, 10, 10);
   sticky_position.scroll_container_relative_containing_block_rect =
       gfx::Rect(20, 20, 30, 30);
-  sticky_pos->SetStickyPositionConstraint(sticky_position);
 
-  root->SetBounds(gfx::Size(100, 100));
-  container->SetBounds(gfx::Size(100, 100));
-  scroller->SetBounds(gfx::Size(1000, 1000));
-  scroller->SetScrollable(container->bounds());
-  sticky_container->SetPosition(gfx::PointF(20, 20));
-  sticky_container->SetBounds(gfx::Size(30, 30));
-  sticky_pos->SetBounds(gfx::Size(10, 10));
-  sticky_pos->SetPosition(gfx::PointF(0, 10));
+  CommitAndUpdateImplPointers();
 
-  ExecuteCalculateDrawProperties(root.get());
-  host()->host_impl()->CreatePendingTree();
-  host()->CommitAndCreatePendingTree();
-  host()->host_impl()->ActivateSyncTree();
-  LayerTreeImpl* layer_tree_impl = host()->host_impl()->active_tree();
-
-  LayerImpl* root_impl = layer_tree_impl->LayerById(root->id());
-  LayerImpl* scroller_impl = layer_tree_impl->LayerById(scroller->id());
-  LayerImpl* sticky_pos_impl = layer_tree_impl->LayerById(sticky_pos->id());
-
-  ExecuteCalculateDrawProperties(root_impl);
   EXPECT_VECTOR2DF_EQ(
       gfx::Vector2dF(20.f, 30.f),
-      sticky_pos_impl->ScreenSpaceTransform().To2dTranslation());
+      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
 
   // Scroll less than sticking point, sticky element should move with scroll as
   // we haven't gotten to the initial sticky item location yet.
-  SetScrollOffsetDelta(scroller_impl, gfx::Vector2dF(0.f, 5.f));
-  ExecuteCalculateDrawProperties(root_impl);
+  SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 5.f));
+  ExecuteCalculateDrawProperties(root_impl_);
   EXPECT_VECTOR2DF_EQ(
       gfx::Vector2dF(20.f, 25.f),
-      sticky_pos_impl->ScreenSpaceTransform().To2dTranslation());
+      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
 
   // Scroll past the sticking point, the Y coordinate should now be clamped.
-  SetScrollOffsetDelta(scroller_impl, gfx::Vector2dF(0.f, 25.f));
-  ExecuteCalculateDrawProperties(root_impl);
+  SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 25.f));
+  ExecuteCalculateDrawProperties(root_impl_);
   EXPECT_VECTOR2DF_EQ(
       gfx::Vector2dF(20.f, 10.f),
-      sticky_pos_impl->ScreenSpaceTransform().To2dTranslation());
+      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
 
   // Now the main thread commits the new position of the sticky element.
-  scroller->SetScrollOffset(gfx::ScrollOffset(0, 25));
+  SetScrollOffset(scroller_.get(), gfx::ScrollOffset(0, 25));
   // Shift the layer by -offset_for_position_sticky.
-  sticky_pos->SetPosition(gfx::PointF(0, 15) - gfx::Vector2dF(0, 5));
-  ExecuteCalculateDrawProperties(root.get());
-  host()->host_impl()->CreatePendingTree();
-  host()->CommitAndCreatePendingTree();
-  host()->host_impl()->ActivateSyncTree();
-  layer_tree_impl = host()->host_impl()->active_tree();
-  root_impl = layer_tree_impl->LayerById(root->id());
-  scroller_impl = layer_tree_impl->LayerById(scroller->id());
-  sticky_pos_impl = layer_tree_impl->LayerById(sticky_pos->id());
+  GetTransformNode(sticky_pos_.get())->post_translation =
+      gfx::PointF(0, 15) - gfx::PointF(0, 5) +
+      sticky_container->offset_to_transform_parent();
+  CommitAndUpdateImplPointers();
 
   // The element should still be where it was before. We reset the delta to
   // (0, 0) because we have synced a scroll offset of (0, 25) from the main
   // thread.
-  SetScrollOffsetDelta(scroller_impl, gfx::Vector2dF(0.f, 0.f));
-  ExecuteCalculateDrawProperties(root_impl);
+  SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 0.f));
+  ExecuteCalculateDrawProperties(root_impl_);
   EXPECT_VECTOR2DF_EQ(
       gfx::Vector2dF(20.f, 10.f),
-      sticky_pos_impl->ScreenSpaceTransform().To2dTranslation());
+      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
 
   // And if we scroll a little further it remains there.
-  SetScrollOffsetDelta(scroller_impl, gfx::Vector2dF(0.f, 5.f));
-  ExecuteCalculateDrawProperties(root_impl);
+  SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 5.f));
+  ExecuteCalculateDrawProperties(root_impl_);
   EXPECT_VECTOR2DF_EQ(
       gfx::Vector2dF(20.f, 10.f),
-      sticky_pos_impl->ScreenSpaceTransform().To2dTranslation());
+      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
 
   // And hits the bottom of the container.
-  SetScrollOffsetDelta(scroller_impl, gfx::Vector2dF(0.f, 10.f));
-  ExecuteCalculateDrawProperties(root_impl);
+  SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 10.f));
+  ExecuteCalculateDrawProperties(root_impl_);
   EXPECT_VECTOR2DF_EQ(
       gfx::Vector2dF(20.f, 5.f),
-      sticky_pos_impl->ScreenSpaceTransform().To2dTranslation());
+      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
 }
 
 // A transform on a sticky element should not affect its sticky position.
-TEST_F(LayerTreeHostCommonTest, StickyPositionScaledStickyBox) {
-  scoped_refptr<Layer> root = Layer::Create();
-  scoped_refptr<Layer> container = Layer::Create();
-  scoped_refptr<Layer> scroller = Layer::Create();
-  scoped_refptr<Layer> sticky_pos = Layer::Create();
-  root->AddChild(container);
-  container->AddChild(scroller);
-  scroller->AddChild(sticky_pos);
-  host()->SetRootLayer(root);
-  scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id()));
+TEST_F(LayerTreeHostCommonStickyPositionTest, StickyPositionScaledStickyBox) {
+  CreateTree();
+
   gfx::Transform t;
   t.Scale(2, 2);
-  sticky_pos->SetTransform(t);
+  auto* transform_node = GetTransformNode(sticky_pos_.get());
+  transform_node->local = t;
+  transform_node->post_translation = gfx::Vector2dF(0, 20);
 
-  LayerStickyPositionConstraint sticky_position;
-  sticky_position.is_sticky = true;
+  auto& sticky_position = EnsureStickyData(sticky_pos_.get()).constraints;
   sticky_position.is_anchored_top = true;
   sticky_position.top_offset = 0.0f;
   sticky_position.scroll_container_relative_sticky_box_rect =
       gfx::Rect(0, 20, 10, 10);
   sticky_position.scroll_container_relative_containing_block_rect =
       gfx::Rect(0, 0, 50, 50);
-  sticky_pos->SetStickyPositionConstraint(sticky_position);
 
-  root->SetBounds(gfx::Size(100, 100));
-  container->SetBounds(gfx::Size(100, 100));
-  scroller->SetBounds(gfx::Size(1000, 1000));
-  scroller->SetScrollable(container->bounds());
-  sticky_pos->SetBounds(gfx::Size(10, 10));
-  sticky_pos->SetPosition(gfx::PointF(0, 20));
+  CommitAndUpdateImplPointers();
 
-  ExecuteCalculateDrawProperties(root.get());
-  host()->host_impl()->CreatePendingTree();
-  host()->CommitAndCreatePendingTree();
-  host()->host_impl()->ActivateSyncTree();
-  LayerTreeImpl* layer_tree_impl = host()->host_impl()->active_tree();
-
-  LayerImpl* root_impl = layer_tree_impl->LayerById(root->id());
-  LayerImpl* scroller_impl = layer_tree_impl->LayerById(scroller->id());
-  LayerImpl* sticky_pos_impl = layer_tree_impl->LayerById(sticky_pos->id());
-
-  ExecuteCalculateDrawProperties(root_impl);
   EXPECT_VECTOR2DF_EQ(
       gfx::Vector2dF(0.f, 20.f),
-      sticky_pos_impl->ScreenSpaceTransform().To2dTranslation());
+      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
 
   // Scroll less than sticking point, sticky element should move with scroll as
   // we haven't gotten to the initial sticky item location yet.
-  SetScrollOffsetDelta(scroller_impl, gfx::Vector2dF(0.f, 15.f));
-  ExecuteCalculateDrawProperties(root_impl);
+  SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 15.f));
+  ExecuteCalculateDrawProperties(root_impl_);
   EXPECT_VECTOR2DF_EQ(
       gfx::Vector2dF(0.f, 5.f),
-      sticky_pos_impl->ScreenSpaceTransform().To2dTranslation());
+      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
 
   // Scroll past the sticking point, the box is positioned at the scroller
   // edge.
-  SetScrollOffsetDelta(scroller_impl, gfx::Vector2dF(0.f, 25.f));
-  ExecuteCalculateDrawProperties(root_impl);
+  SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 25.f));
+  ExecuteCalculateDrawProperties(root_impl_);
   EXPECT_VECTOR2DF_EQ(
       gfx::Vector2dF(0.f, 0.f),
-      sticky_pos_impl->ScreenSpaceTransform().To2dTranslation());
-  SetScrollOffsetDelta(scroller_impl, gfx::Vector2dF(0.f, 30.f));
-  ExecuteCalculateDrawProperties(root_impl);
+      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
+  SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 30.f));
+  ExecuteCalculateDrawProperties(root_impl_);
   EXPECT_VECTOR2DF_EQ(
       gfx::Vector2dF(0.f, 0.f),
-      sticky_pos_impl->ScreenSpaceTransform().To2dTranslation());
+      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
 
   // Scroll past the end of the sticky container.
-  SetScrollOffsetDelta(scroller_impl, gfx::Vector2dF(0.f, 50.f));
-  ExecuteCalculateDrawProperties(root_impl);
+  SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 50.f));
+  ExecuteCalculateDrawProperties(root_impl_);
   EXPECT_VECTOR2DF_EQ(
       gfx::Vector2dF(0.f, -10.f),
-      sticky_pos_impl->ScreenSpaceTransform().To2dTranslation());
+      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
 }
 
 // Tests that a transform does not affect the sticking points. The sticky
 // element will however move relative to the viewport due to its transform.
-TEST_F(LayerTreeHostCommonTest, StickyPositionScaledContainer) {
-  scoped_refptr<Layer> root = Layer::Create();
-  scoped_refptr<Layer> container = Layer::Create();
-  scoped_refptr<Layer> scroller = Layer::Create();
+TEST_F(LayerTreeHostCommonStickyPositionTest, StickyPositionScaledContainer) {
+  CreateRootAndScroller();
+
   scoped_refptr<Layer> sticky_container = Layer::Create();
-  scoped_refptr<Layer> sticky_pos = Layer::Create();
-  root->AddChild(container);
-  container->AddChild(scroller);
-  scroller->AddChild(sticky_container);
-  sticky_container->AddChild(sticky_pos);
-  host()->SetRootLayer(root);
-  scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id()));
+  sticky_container->SetBounds(gfx::Size(50, 50));
+  CopyProperties(scroller_.get(), sticky_container.get());
   gfx::Transform t;
   t.Scale(2, 2);
-  sticky_container->SetTransform(t);
+  CreateTransformNode(sticky_container.get()).local = t;
+  root_->AddChild(sticky_container);
 
-  LayerStickyPositionConstraint sticky_position;
-  sticky_position.is_sticky = true;
+  sticky_pos_ = CreateSticky(sticky_container.get());
+  GetTransformNode(sticky_pos_.get())->post_translation = gfx::Vector2dF(0, 20);
+  auto& sticky_position = EnsureStickyData(sticky_pos_.get()).constraints;
   sticky_position.is_anchored_top = true;
   sticky_position.top_offset = 0.0f;
   sticky_position.scroll_container_relative_sticky_box_rect =
       gfx::Rect(0, 20, 10, 10);
   sticky_position.scroll_container_relative_containing_block_rect =
       gfx::Rect(0, 0, 50, 50);
-  sticky_pos->SetStickyPositionConstraint(sticky_position);
 
-  root->SetBounds(gfx::Size(100, 100));
-  container->SetBounds(gfx::Size(100, 100));
-  scroller->SetBounds(gfx::Size(1000, 1000));
-  scroller->SetScrollable(container->bounds());
-  sticky_container->SetBounds(gfx::Size(50, 50));
-  sticky_pos->SetBounds(gfx::Size(10, 10));
-  sticky_pos->SetPosition(gfx::PointF(0, 20));
+  CommitAndUpdateImplPointers();
 
-  ExecuteCalculateDrawProperties(root.get());
-  host()->host_impl()->CreatePendingTree();
-  host()->CommitAndCreatePendingTree();
-  host()->host_impl()->ActivateSyncTree();
-  LayerTreeImpl* layer_tree_impl = host()->host_impl()->active_tree();
-
-  LayerImpl* root_impl = layer_tree_impl->LayerById(root->id());
-  LayerImpl* scroller_impl = layer_tree_impl->LayerById(scroller->id());
-  LayerImpl* sticky_pos_impl = layer_tree_impl->LayerById(sticky_pos->id());
-
-  ExecuteCalculateDrawProperties(root_impl);
   EXPECT_VECTOR2DF_EQ(
       gfx::Vector2dF(0.f, 40.f),
-      sticky_pos_impl->ScreenSpaceTransform().To2dTranslation());
+      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
 
   // Scroll less than sticking point, sticky element should move with scroll as
   // we haven't gotten to the initial sticky item location yet.
-  SetScrollOffsetDelta(scroller_impl, gfx::Vector2dF(0.f, 15.f));
-  ExecuteCalculateDrawProperties(root_impl);
+  SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 15.f));
+  ExecuteCalculateDrawProperties(root_impl_);
   EXPECT_VECTOR2DF_EQ(
       gfx::Vector2dF(0.f, 25.f),
-      sticky_pos_impl->ScreenSpaceTransform().To2dTranslation());
+      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
 
   // Scroll past the sticking point, the box is positioned at the scroller
   // edge but is also scaled by its container so it begins to move down.
-  SetScrollOffsetDelta(scroller_impl, gfx::Vector2dF(0.f, 25.f));
-  ExecuteCalculateDrawProperties(root_impl);
+  SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 25.f));
+  ExecuteCalculateDrawProperties(root_impl_);
   EXPECT_VECTOR2DF_EQ(
       gfx::Vector2dF(0.f, 25.f),
-      sticky_pos_impl->ScreenSpaceTransform().To2dTranslation());
-  SetScrollOffsetDelta(scroller_impl, gfx::Vector2dF(0.f, 30.f));
-  ExecuteCalculateDrawProperties(root_impl);
+      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
+  SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 30.f));
+  ExecuteCalculateDrawProperties(root_impl_);
   EXPECT_VECTOR2DF_EQ(
       gfx::Vector2dF(0.f, 30.f),
-      sticky_pos_impl->ScreenSpaceTransform().To2dTranslation());
+      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
 
   // Scroll past the end of the sticky container.
-  SetScrollOffsetDelta(scroller_impl, gfx::Vector2dF(0.f, 50.f));
-  ExecuteCalculateDrawProperties(root_impl);
+  SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 50.f));
+  ExecuteCalculateDrawProperties(root_impl_);
   EXPECT_VECTOR2DF_EQ(
       gfx::Vector2dF(0.f, 30.f),
-      sticky_pos_impl->ScreenSpaceTransform().To2dTranslation());
+      sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
 }
 
-TEST_F(LayerTreeHostCommonTest, StickyPositionNested) {
-  scoped_refptr<Layer> root = Layer::Create();
-  scoped_refptr<Layer> container = Layer::Create();
-  scoped_refptr<Layer> scroller = Layer::Create();
-  scoped_refptr<Layer> outer_sticky = Layer::Create();
-  scoped_refptr<Layer> inner_sticky = Layer::Create();
+TEST_F(LayerTreeHostCommonStickyPositionTest, StickyPositionNested) {
+  CreateTree();
 
-  root->AddChild(container);
-  container->AddChild(scroller);
-  scroller->AddChild(outer_sticky);
-  outer_sticky->AddChild(inner_sticky);
-  host()->SetRootLayer(root);
-  scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id()));
-  outer_sticky->SetElementId(LayerIdToElementIdForTesting(outer_sticky->id()));
-
-  root->SetBounds(gfx::Size(100, 100));
-  container->SetBounds(gfx::Size(100, 100));
-  scroller->SetBounds(gfx::Size(100, 1000));
-  scroller->SetScrollable(container->bounds());
-  outer_sticky->SetBounds(gfx::Size(10, 50));
-  outer_sticky->SetPosition(gfx::PointF(0, 50));
-  inner_sticky->SetBounds(gfx::Size(10, 10));
-  inner_sticky->SetPosition(gfx::PointF(0, 0));
-
-  LayerStickyPositionConstraint outer_sticky_pos;
-  outer_sticky_pos.is_sticky = true;
+  GetTransformNode(sticky_pos_.get())->post_translation = gfx::Vector2dF(0, 50);
+  auto& outer_sticky_pos = EnsureStickyData(sticky_pos_.get()).constraints;
   outer_sticky_pos.is_anchored_top = true;
   outer_sticky_pos.top_offset = 10.0f;
   outer_sticky_pos.scroll_container_relative_sticky_box_rect =
       gfx::Rect(0, 50, 10, 50);
   outer_sticky_pos.scroll_container_relative_containing_block_rect =
       gfx::Rect(0, 0, 50, 400);
-  outer_sticky->SetStickyPositionConstraint(outer_sticky_pos);
 
-  LayerStickyPositionConstraint inner_sticky_pos;
-  inner_sticky_pos.is_sticky = true;
+  scoped_refptr<Layer> inner_sticky = CreateSticky(sticky_pos_.get());
+  auto& inner_sticky_pos = EnsureStickyData(inner_sticky.get()).constraints;
   inner_sticky_pos.is_anchored_top = true;
   inner_sticky_pos.top_offset = 25.0f;
   inner_sticky_pos.scroll_container_relative_sticky_box_rect =
       gfx::Rect(0, 50, 10, 10);
   inner_sticky_pos.scroll_container_relative_containing_block_rect =
       gfx::Rect(0, 50, 10, 50);
-  inner_sticky_pos.nearest_element_shifting_containing_block =
-      outer_sticky->element_id();
-  inner_sticky->SetStickyPositionConstraint(inner_sticky_pos);
+  EnsureStickyData(inner_sticky.get()).nearest_node_shifting_containing_block =
+      sticky_pos_->transform_tree_index();
 
-  ExecuteCalculateDrawProperties(root.get());
-  host()->host_impl()->CreatePendingTree();
-  host()->CommitAndCreatePendingTree();
-  host()->host_impl()->ActivateSyncTree();
+  CommitAndUpdateImplPointers();
   LayerTreeImpl* layer_tree_impl = host()->host_impl()->active_tree();
-
-  LayerImpl* root_impl = layer_tree_impl->LayerById(root->id());
-  LayerImpl* scroller_impl = layer_tree_impl->LayerById(scroller->id());
-  LayerImpl* outer_sticky_impl = layer_tree_impl->LayerById(outer_sticky->id());
+  LayerImpl* outer_sticky_impl = sticky_pos_impl_;
   LayerImpl* inner_sticky_impl = layer_tree_impl->LayerById(inner_sticky->id());
 
-  ExecuteCalculateDrawProperties(root_impl);
-
   // Before any scrolling is done, the sticky elements should still be at their
   // original positions.
   EXPECT_VECTOR2DF_EQ(
@@ -7106,8 +6729,8 @@
 
   // Scroll less than the sticking point. Both sticky elements should move with
   // scroll as we haven't gotten to the sticky item locations yet.
-  SetScrollOffsetDelta(scroller_impl, gfx::Vector2dF(0.f, 5.f));
-  ExecuteCalculateDrawProperties(root_impl);
+  SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 5.f));
+  ExecuteCalculateDrawProperties(root_impl_);
   EXPECT_VECTOR2DF_EQ(
       gfx::Vector2dF(0.f, 45.f),
       outer_sticky_impl->ScreenSpaceTransform().To2dTranslation());
@@ -7117,8 +6740,8 @@
 
   // Scroll such that the inner sticky should stick, but the outer one should
   // keep going as it hasn't reached its position yet.
-  SetScrollOffsetDelta(scroller_impl, gfx::Vector2dF(0.f, 30.f));
-  ExecuteCalculateDrawProperties(root_impl);
+  SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 30.f));
+  ExecuteCalculateDrawProperties(root_impl_);
   EXPECT_VECTOR2DF_EQ(
       gfx::Vector2dF(0.f, 20.f),
       outer_sticky_impl->ScreenSpaceTransform().To2dTranslation());
@@ -7127,8 +6750,8 @@
       inner_sticky_impl->ScreenSpaceTransform().To2dTranslation());
 
   // Keep going, both should stick.
-  SetScrollOffsetDelta(scroller_impl, gfx::Vector2dF(0.f, 100.f));
-  ExecuteCalculateDrawProperties(root_impl);
+  SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 100.f));
+  ExecuteCalculateDrawProperties(root_impl_);
   EXPECT_VECTOR2DF_EQ(
       gfx::Vector2dF(0.f, 10.f),
       outer_sticky_impl->ScreenSpaceTransform().To2dTranslation());
@@ -7137,100 +6760,6 @@
       inner_sticky_impl->ScreenSpaceTransform().To2dTranslation());
 }
 
-TEST_F(LayerTreeHostCommonTest, NonFlatContainerForFixedPosLayer) {
-  scoped_refptr<Layer> root = Layer::Create();
-  scoped_refptr<Layer> container = Layer::Create();
-  scoped_refptr<Layer> scroller = Layer::Create();
-  scoped_refptr<Layer> fixed_pos = Layer::Create();
-
-  scroller->SetIsContainerForFixedPositionLayers(true);
-  root->AddChild(container);
-  container->AddChild(scroller);
-  scroller->AddChild(fixed_pos);
-  host()->SetRootLayer(root);
-
-  LayerPositionConstraint fixed_position;
-  fixed_position.set_is_fixed_position(true);
-  scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id()));
-  fixed_pos->SetPositionConstraint(fixed_position);
-
-  root->SetBounds(gfx::Size(50, 50));
-  container->SetBounds(gfx::Size(50, 50));
-  scroller->SetBounds(gfx::Size(50, 50));
-  scroller->SetScrollable(container->bounds());
-  fixed_pos->SetBounds(gfx::Size(50, 50));
-
-  gfx::Transform rotate;
-  rotate.RotateAboutXAxis(20);
-  container->SetTransform(rotate);
-
-  ExecuteCalculateDrawProperties(root.get());
-  TransformTree& tree =
-      root->layer_tree_host()->property_trees()->transform_tree;
-  gfx::Transform transform;
-  tree.ComputeTranslation(fixed_pos->transform_tree_index(),
-                          container->transform_tree_index(), &transform);
-  EXPECT_TRUE(transform.IsIdentity());
-}
-
-TEST_F(LayerTreeHostCommonTest, ScrollSnappingWithFixedPosChild) {
-  // This test verifies that a fixed pos child of a scrolling layer doesn't get
-  // snapped to integer coordinates.
-  //
-  // + root
-  //   + container
-  //    + scroller
-  //     + fixed_pos
-  //
-  scoped_refptr<Layer> root = Layer::Create();
-  scoped_refptr<Layer> container = Layer::Create();
-  scoped_refptr<Layer> scroller = Layer::Create();
-  scoped_refptr<Layer> fixed_pos = Layer::Create();
-
-  scroller->SetIsContainerForFixedPositionLayers(true);
-
-  root->AddChild(container);
-  container->AddChild(scroller);
-  scroller->AddChild(fixed_pos);
-  host()->SetRootLayer(root);
-
-  LayerPositionConstraint fixed_position;
-  fixed_position.set_is_fixed_position(true);
-  scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id()));
-  fixed_pos->SetPositionConstraint(fixed_position);
-
-  root->SetBounds(gfx::Size(50, 50));
-  container->SetBounds(gfx::Size(50, 50));
-  scroller->SetBounds(gfx::Size(100, 100));
-  scroller->SetScrollable(container->bounds());
-  scroller->SetPosition(gfx::PointF(10.3f, 10.3f));
-  fixed_pos->SetBounds(gfx::Size(10, 10));
-
-  ExecuteCalculateDrawProperties(root.get());
-
-  host()->host_impl()->CreatePendingTree();
-  host()->CommitAndCreatePendingTree();
-  host()->host_impl()->ActivateSyncTree();
-  LayerTreeImpl* layer_tree_impl = host()->host_impl()->active_tree();
-
-  LayerImpl* root_impl = layer_tree_impl->LayerById(root->id());
-  LayerImpl* scroller_impl = layer_tree_impl->LayerById(scroller->id());
-  LayerImpl* fixed_pos_impl = layer_tree_impl->LayerById(fixed_pos->id());
-  gfx::Vector2dF scroll_delta(5.f, 9.f);
-  SetScrollOffsetDelta(scroller_impl, scroll_delta);
-
-  ExecuteCalculateDrawProperties(root_impl);
-
-  gfx::Vector2dF expected_scroller_screen_space_transform_translation(5.f, 1.f);
-  EXPECT_VECTOR2DF_EQ(expected_scroller_screen_space_transform_translation,
-                      scroller_impl->ScreenSpaceTransform().To2dTranslation());
-
-  gfx::Vector2dF expected_fixed_pos_screen_space_transform_translation(10.3f,
-                                                                       10.3f);
-  EXPECT_VECTOR2DF_EQ(expected_fixed_pos_screen_space_transform_translation,
-                      fixed_pos_impl->ScreenSpaceTransform().To2dTranslation());
-}
-
 class AnimationScaleFactorTrackingLayerImpl : public LayerImpl {
  public:
   static std::unique_ptr<AnimationScaleFactorTrackingLayerImpl> Create(
@@ -8027,64 +7556,6 @@
   EXPECT_EQ(affected_by_delta, sublayer->visible_layer_rect());
 }
 
-TEST_F(LayerTreeHostCommonTest, NodesAffectedByViewportBoundsDeltaGetUpdated) {
-  scoped_refptr<Layer> root = Layer::Create();
-  scoped_refptr<Layer> page_scale_layer = Layer::Create();
-  scoped_refptr<Layer> inner_viewport_container_layer = Layer::Create();
-  scoped_refptr<Layer> inner_viewport_scroll_layer = Layer::Create();
-  scoped_refptr<Layer> outer_viewport_container_layer = Layer::Create();
-  scoped_refptr<Layer> outer_viewport_scroll_layer = Layer::Create();
-
-  root->AddChild(inner_viewport_container_layer);
-  inner_viewport_container_layer->AddChild(page_scale_layer);
-  page_scale_layer->AddChild(inner_viewport_scroll_layer);
-  inner_viewport_scroll_layer->AddChild(outer_viewport_container_layer);
-  outer_viewport_container_layer->AddChild(outer_viewport_scroll_layer);
-
-  inner_viewport_scroll_layer->SetIsContainerForFixedPositionLayers(true);
-  outer_viewport_scroll_layer->SetIsContainerForFixedPositionLayers(true);
-  outer_viewport_scroll_layer->SetIsResizedByBrowserControls(true);
-
-  host()->SetRootLayer(root);
-  ViewportLayers viewport_layers;
-  viewport_layers.page_scale = page_scale_layer;
-  viewport_layers.inner_viewport_container = inner_viewport_container_layer;
-  viewport_layers.outer_viewport_container = outer_viewport_container_layer;
-  viewport_layers.inner_viewport_scroll = inner_viewport_scroll_layer;
-  viewport_layers.outer_viewport_scroll = outer_viewport_scroll_layer;
-  host()->RegisterViewportLayers(viewport_layers);
-
-  scoped_refptr<Layer> fixed_to_inner = Layer::Create();
-  scoped_refptr<Layer> fixed_to_outer = Layer::Create();
-
-  inner_viewport_scroll_layer->AddChild(fixed_to_inner);
-  outer_viewport_scroll_layer->AddChild(fixed_to_outer);
-
-  LayerPositionConstraint fixed_to_right;
-  fixed_to_right.set_is_fixed_position(true);
-  fixed_to_right.set_is_fixed_to_right_edge(true);
-
-  fixed_to_inner->SetPositionConstraint(fixed_to_right);
-  fixed_to_outer->SetPositionConstraint(fixed_to_right);
-
-  ExecuteCalculateDrawPropertiesAndSaveUpdateLayerList(root.get());
-
-  TransformTree& transform_tree = host()->property_trees()->transform_tree;
-  EXPECT_TRUE(transform_tree.HasNodesAffectedByOuterViewportBoundsDelta());
-
-  LayerPositionConstraint fixed_to_left;
-  fixed_to_left.set_is_fixed_position(true);
-  fixed_to_inner->SetPositionConstraint(fixed_to_left);
-
-  ExecuteCalculateDrawPropertiesAndSaveUpdateLayerList(root.get());
-  EXPECT_TRUE(transform_tree.HasNodesAffectedByOuterViewportBoundsDelta());
-
-  fixed_to_outer->SetPositionConstraint(fixed_to_left);
-
-  ExecuteCalculateDrawPropertiesAndSaveUpdateLayerList(root.get());
-  EXPECT_FALSE(transform_tree.HasNodesAffectedByOuterViewportBoundsDelta());
-}
-
 TEST_F(LayerTreeHostCommonTest, VisibleContentRectForAnimatedLayer) {
   host_impl()->CreatePendingTree();
   std::unique_ptr<LayerImpl> pending_root =
@@ -8327,124 +7798,6 @@
   EXPECT_FALSE(HasPotentiallyRunningFilterAnimation(*grandchild));
 }
 
-// Ensures that the property tree code accounts for offsets between fixed
-// position layers and their respective containers.
-TEST_F(LayerTreeHostCommonTest, PropertyTreesAccountForFixedParentOffset) {
-  LayerImpl* root = root_layer_for_testing();
-  LayerImpl* child = AddChild<LayerImpl>(root);
-  LayerImpl* grandchild = AddChild<LayerImpl>(child);
-
-  root->SetBounds(gfx::Size(50, 50));
-  root->SetMasksToBounds(true);
-  root->test_properties()->is_container_for_fixed_position_layers = true;
-  child->test_properties()->position = gfx::PointF(1000, 1000);
-  child->SetBounds(gfx::Size(50, 50));
-  grandchild->test_properties()->position = gfx::PointF(-1000, -1000);
-  grandchild->SetBounds(gfx::Size(50, 50));
-  grandchild->SetDrawsContent(true);
-
-  LayerPositionConstraint constraint;
-  constraint.set_is_fixed_position(true);
-  grandchild->test_properties()->position_constraint = constraint;
-
-  ExecuteCalculateDrawProperties(root);
-
-  EXPECT_EQ(gfx::Rect(0, 0, 50, 50), grandchild->visible_layer_rect());
-}
-
-// Ensures that the property tree code accounts for offsets between fixed
-// position containers and their transform tree parents, when a fixed position
-// layer's container is its layer tree parent, but this parent doesn't have its
-// own transform tree node.
-TEST_F(LayerTreeHostCommonTest,
-       PropertyTreesAccountForFixedParentOffsetWhenContainerIsParent) {
-  LayerImpl* root = root_layer_for_testing();
-  LayerImpl* child = AddChild<LayerImpl>(root);
-  LayerImpl* grandchild = AddChild<LayerImpl>(child);
-
-  root->SetBounds(gfx::Size(50, 50));
-  root->SetMasksToBounds(true);
-  root->test_properties()->is_container_for_fixed_position_layers = true;
-  child->test_properties()->position = gfx::PointF(1000, 1000);
-  child->SetBounds(gfx::Size(50, 50));
-  child->test_properties()->is_container_for_fixed_position_layers = true;
-  grandchild->test_properties()->position = gfx::PointF(-1000, -1000);
-  grandchild->SetBounds(gfx::Size(50, 50));
-  grandchild->SetDrawsContent(true);
-
-  LayerPositionConstraint constraint;
-  constraint.set_is_fixed_position(true);
-  grandchild->test_properties()->position_constraint = constraint;
-
-  ExecuteCalculateDrawProperties(root);
-
-  EXPECT_EQ(gfx::Rect(0, 0, 50, 50), grandchild->visible_layer_rect());
-}
-
-TEST_F(LayerTreeHostCommonTest, OnlyApplyFixedPositioningOnce) {
-  LayerImpl* root = root_layer_for_testing();
-  LayerImpl* frame_clip = AddChild<LayerImpl>(root);
-  LayerImpl* fixed = AddChild<LayerImpl>(frame_clip);
-  gfx::Transform translate_z;
-  translate_z.Translate3d(0, 0, 10);
-
-  root->SetBounds(gfx::Size(800, 800));
-  root->test_properties()->is_container_for_fixed_position_layers = true;
-
-  frame_clip->test_properties()->position = gfx::PointF(500, 100);
-  frame_clip->SetBounds(gfx::Size(100, 100));
-  frame_clip->SetMasksToBounds(true);
-
-  fixed->SetBounds(gfx::Size(1000, 1000));
-  fixed->SetDrawsContent(true);
-
-  LayerPositionConstraint constraint;
-  constraint.set_is_fixed_position(true);
-  fixed->test_properties()->position_constraint = constraint;
-
-  ExecuteCalculateDrawProperties(root);
-
-  gfx::Rect expected(0, 0, 100, 100);
-  EXPECT_EQ(expected, fixed->visible_layer_rect());
-}
-
-TEST_F(LayerTreeHostCommonTest, FixedClipsShouldBeAssociatedWithTheRightNode) {
-  LayerImpl* root = root_layer_for_testing();
-  LayerImpl* frame_clip = AddChild<LayerImpl>(root);
-  LayerImpl* scroller = AddChild<LayerImpl>(frame_clip);
-  LayerImpl* fixed = AddChild<LayerImpl>(scroller);
-
-  root->SetBounds(gfx::Size(800, 800));
-  root->SetDrawsContent(true);
-  root->test_properties()->is_container_for_fixed_position_layers = true;
-  frame_clip->test_properties()->position = gfx::PointF(500, 100);
-  frame_clip->SetBounds(gfx::Size(100, 100));
-  frame_clip->SetMasksToBounds(true);
-  frame_clip->SetDrawsContent(true);
-  scroller->SetBounds(gfx::Size(1000, 1000));
-  scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id()));
-  scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id()));
-  scroller->SetScrollable(frame_clip->bounds());
-  scroller->SetDrawsContent(true);
-  fixed->test_properties()->position = gfx::PointF(100, 100);
-  fixed->SetBounds(gfx::Size(50, 50));
-  fixed->SetMasksToBounds(true);
-  fixed->SetDrawsContent(true);
-  fixed->test_properties()->force_render_surface = true;
-
-  BuildPropertyTreesForTesting();
-  scroller->SetCurrentScrollOffset(gfx::ScrollOffset(100, 100));
-
-  LayerPositionConstraint constraint;
-  constraint.set_is_fixed_position(true);
-  fixed->test_properties()->position_constraint = constraint;
-
-  ExecuteCalculateDrawProperties(root);
-
-  gfx::Rect expected(0, 0, 50, 50);
-  EXPECT_EQ(expected, fixed->visible_layer_rect());
-}
-
 TEST_F(LayerTreeHostCommonTest, ChangingAxisAlignmentTriggersRebuild) {
   gfx::Transform translate;
   gfx::Transform rotate;
@@ -8454,7 +7807,6 @@
 
   scoped_refptr<Layer> root = Layer::Create();
   root->SetBounds(gfx::Size(800, 800));
-  root->SetIsContainerForFixedPositionLayers(true);
 
   host()->SetRootLayer(root);
 
@@ -9866,206 +9218,6 @@
   EXPECT_FALSE(node->has_potential_animation);
 }
 
-TEST_F(LayerTreeHostCommonTest, ScrollTreeBuilderTest) {
-  // Test the behavior of scroll tree builder
-  // Topology:
-  // +root1(1)[inner_viewport_container_layer]
-  // +-page_scale_layer
-  // +----parent2(2)[kHasBackgroundAttachmentFixedObjects|kScrollbarScrolling &
-  // scrollable, inner_viewport_scroll_layer]
-  // +------child6(6)[kScrollbarScrolling]
-  // +--------grand_child10(10)[kScrollbarScrolling]
-  // +----parent3(3)
-  // +------child7(7)[scrollable]
-  // +------child8(8)[scroll_parent=7]
-  // +--------grand_child11(11)[scrollable]
-  // +----parent4(4)
-  // +------child9(9)
-  // +--------grand_child12(12)
-  // +----parent5(5)[contains_non_fast_scrollable_region]
-  //
-  // Expected scroll tree topology:
-  // +property_tree_root---owner:-1
-  // +--root---owner:1, id:1
-  // +----node---owner:2, id:2
-  // +------node---owner:6, id:3
-  // +----node---owner:7, id:4
-  // +------node---owner:11, id:5
-  // +----node---owner:5, id:6
-  //
-  // Extra check:
-  //   scroll_tree_index() of:
-  //     grand_child10:3
-  //     parent3:1
-  //     child8:4
-  //     parent4:1
-  //     child9:1
-  //     grand_child12:1
-  scoped_refptr<Layer> root1 = Layer::Create();
-  scoped_refptr<Layer> page_scale_layer = Layer::Create();
-  scoped_refptr<Layer> parent2 = Layer::Create();
-  scoped_refptr<Layer> parent3 = Layer::Create();
-  scoped_refptr<Layer> parent4 = Layer::Create();
-  scoped_refptr<Layer> parent5 = Layer::Create();
-  scoped_refptr<Layer> child6 = Layer::Create();
-  scoped_refptr<Layer> child7 = Layer::Create();
-  scoped_refptr<Layer> child8 = Layer::Create();
-  scoped_refptr<Layer> child9 = Layer::Create();
-  scoped_refptr<Layer> grand_child10 = Layer::Create();
-  scoped_refptr<Layer> grand_child11 = Layer::Create();
-  scoped_refptr<Layer> grand_child12 = Layer::Create();
-
-  root1->AddChild(page_scale_layer);
-  page_scale_layer->AddChild(parent2);
-  page_scale_layer->AddChild(parent3);
-  page_scale_layer->AddChild(parent4);
-  page_scale_layer->AddChild(parent5);
-  parent2->AddChild(child6);
-  parent3->AddChild(child7);
-  parent3->AddChild(child8);
-  parent4->AddChild(child9);
-  child6->AddChild(grand_child10);
-  child8->AddChild(grand_child11);
-  child9->AddChild(grand_child12);
-  host()->SetRootLayer(root1);
-
-  root1->SetBounds(gfx::Size(1, 1));
-  parent2->AddMainThreadScrollingReasons(
-      MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects);
-  parent2->AddMainThreadScrollingReasons(
-      MainThreadScrollingReason::kScrollbarScrolling);
-  parent2->SetElementId(LayerIdToElementIdForTesting(parent2->id()));
-  parent2->SetScrollable(root1->bounds());
-  child6->AddMainThreadScrollingReasons(
-      MainThreadScrollingReason::kScrollbarScrolling);
-  grand_child10->AddMainThreadScrollingReasons(
-      MainThreadScrollingReason::kScrollbarScrolling);
-
-  parent3->SetBounds(gfx::Size(2, 2));
-  child7->SetScrollable(parent3->bounds());
-  child7->SetElementId(LayerIdToElementIdForTesting(child7->id()));
-
-  child8->SetScrollParent(child7.get());
-  child8->SetBounds(gfx::Size(3, 3));
-  grand_child11->SetScrollable(child8->bounds());
-  grand_child11->SetElementId(
-      LayerIdToElementIdForTesting(grand_child11->id()));
-
-  parent5->SetNonFastScrollableRegion(gfx::Rect(0, 0, 50, 50));
-  parent5->SetBounds(gfx::Size(10, 10));
-
-  ViewportLayers viewport_layers;
-  viewport_layers.page_scale = page_scale_layer;
-  viewport_layers.inner_viewport_container = root1;
-  viewport_layers.inner_viewport_scroll = parent2;
-  host()->RegisterViewportLayers(viewport_layers);
-  ExecuteCalculateDrawPropertiesAndSaveUpdateLayerList(root1.get());
-
-  const int kRootPropertyTreeNodeId = 0;
-
-  // Property tree root
-  ScrollTree& scroll_tree = host()->property_trees()->scroll_tree;
-  PropertyTrees property_trees;
-  property_trees.is_main_thread = true;
-  property_trees.is_active = false;
-  ScrollTree& expected_scroll_tree = property_trees.scroll_tree;
-  ScrollNode* property_tree_root = expected_scroll_tree.Node(0);
-  property_tree_root->id = kRootPropertyTreeNodeId;
-  property_tree_root->parent_id = ScrollTree::kInvalidNodeId;
-  property_tree_root->scrollable = false;
-  property_tree_root->main_thread_scrolling_reasons =
-      MainThreadScrollingReason::kNotScrollingOnMain;
-  property_tree_root->transform_id = kRootPropertyTreeNodeId;
-
-  // The node owned by root1
-  ScrollNode scroll_root1;
-  scroll_root1.id = 1;
-  scroll_root1.bounds = root1->bounds();
-  scroll_root1.user_scrollable_horizontal = true;
-  scroll_root1.user_scrollable_vertical = true;
-  scroll_root1.transform_id = root1->transform_tree_index();
-  expected_scroll_tree.Insert(scroll_root1, 0);
-
-  // The node owned by parent2
-  ScrollNode scroll_parent2;
-  scroll_parent2.id = 2;
-  scroll_parent2.element_id = parent2->element_id();
-  scroll_parent2.scrollable = true;
-  scroll_parent2.main_thread_scrolling_reasons =
-      parent2->GetMainThreadScrollingReasons();
-  scroll_parent2.container_bounds = root1->bounds();
-  scroll_parent2.bounds = parent2->bounds();
-  scroll_parent2.max_scroll_offset_affected_by_page_scale = true;
-  scroll_parent2.scrolls_inner_viewport = true;
-  scroll_parent2.user_scrollable_horizontal = true;
-  scroll_parent2.user_scrollable_vertical = true;
-  scroll_parent2.transform_id = parent2->transform_tree_index();
-  expected_scroll_tree.Insert(scroll_parent2, 1);
-
-  // The node owned by child6
-  ScrollNode scroll_child6;
-  scroll_child6.id = 3;
-  scroll_child6.main_thread_scrolling_reasons =
-      child6->GetMainThreadScrollingReasons();
-  scroll_child6.should_flatten = true;
-  scroll_child6.user_scrollable_horizontal = true;
-  scroll_child6.user_scrollable_vertical = true;
-  scroll_child6.transform_id = child6->transform_tree_index();
-  expected_scroll_tree.Insert(scroll_child6, 2);
-
-  // The node owned by child7, child7 also owns a transform node
-  ScrollNode scroll_child7;
-  scroll_child7.id = 4;
-  scroll_child7.element_id = child7->element_id();
-  scroll_child7.scrollable = true;
-  scroll_child7.container_bounds = parent3->bounds();
-  scroll_child7.bounds = child7->bounds();
-  scroll_child7.user_scrollable_horizontal = true;
-  scroll_child7.user_scrollable_vertical = true;
-  scroll_child7.transform_id = child7->transform_tree_index();
-  expected_scroll_tree.Insert(scroll_child7, 1);
-
-  // The node owned by grand_child11, grand_child11 also owns a transform node
-  ScrollNode scroll_grand_child11;
-  scroll_grand_child11.id = 5;
-  scroll_grand_child11.element_id = grand_child11->element_id();
-  scroll_grand_child11.scrollable = true;
-  scroll_grand_child11.container_bounds = child8->bounds();
-  scroll_grand_child11.user_scrollable_horizontal = true;
-  scroll_grand_child11.user_scrollable_vertical = true;
-  scroll_grand_child11.transform_id = grand_child11->transform_tree_index();
-  expected_scroll_tree.Insert(scroll_grand_child11, 4);
-
-  // The node owned by parent5
-  ScrollNode scroll_parent5;
-  scroll_parent5.id = 8;
-  scroll_parent5.bounds = gfx::Size(10, 10);
-  scroll_parent5.should_flatten = true;
-  scroll_parent5.user_scrollable_horizontal = true;
-  scroll_parent5.user_scrollable_vertical = true;
-  scroll_parent5.transform_id = parent5->transform_tree_index();
-  expected_scroll_tree.Insert(scroll_parent5, 1);
-
-  expected_scroll_tree.SetScrollOffset(parent2->element_id(),
-                                       gfx::ScrollOffset(0, 0));
-  expected_scroll_tree.SetScrollOffset(child7->element_id(),
-                                       gfx::ScrollOffset(0, 0));
-  expected_scroll_tree.SetScrollOffset(grand_child11->element_id(),
-                                       gfx::ScrollOffset(0, 0));
-  expected_scroll_tree.set_needs_update(false);
-
-  EXPECT_EQ(expected_scroll_tree, scroll_tree);
-
-  // Check other layers' scroll_tree_index
-  EXPECT_EQ(scroll_root1.id, page_scale_layer->scroll_tree_index());
-  EXPECT_EQ(scroll_child6.id, grand_child10->scroll_tree_index());
-  EXPECT_EQ(scroll_root1.id, parent3->scroll_tree_index());
-  EXPECT_EQ(scroll_child7.id, child8->scroll_tree_index());
-  EXPECT_EQ(scroll_root1.id, parent4->scroll_tree_index());
-  EXPECT_EQ(scroll_root1.id, child9->scroll_tree_index());
-  EXPECT_EQ(scroll_root1.id, grand_child12->scroll_tree_index());
-}
-
 TEST_F(LayerTreeHostCommonTest, CopyRequestScalingTest) {
   LayerImpl* root = root_layer_for_testing();
   LayerImpl* scale_layer = AddChild<LayerImpl>(root);
diff --git a/cc/trees/layer_tree_host_unittest.cc b/cc/trees/layer_tree_host_unittest.cc
index ee47dc4e..5e1ca7aa 100644
--- a/cc/trees/layer_tree_host_unittest.cc
+++ b/cc/trees/layer_tree_host_unittest.cc
@@ -3177,7 +3177,6 @@
     scoped_refptr<Layer> pinch = Layer::Create();
     pinch->SetBounds(gfx::Size(500, 500));
     pinch->SetScrollable(gfx::Size(200, 200));
-    pinch->SetIsContainerForFixedPositionLayers(true);
     page_scale_layer->AddChild(pinch);
     root_clip->AddChild(page_scale_layer);
 
@@ -5405,7 +5404,6 @@
     scoped_refptr<Layer> inner_viewport_scroll_layer = Layer::Create();
     inner_viewport_scroll_layer->SetScrollable(
         inner_viewport_container_layer->bounds());
-    inner_viewport_scroll_layer->SetIsContainerForFixedPositionLayers(true);
 
     root_layer_->AddChild(inner_viewport_container_layer);
     inner_viewport_container_layer->AddChild(overscroll_elasticity_layer);
@@ -6910,7 +6908,6 @@
     scoped_refptr<Layer> pinch = Layer::Create();
     pinch->SetBounds(gfx::Size(500, 500));
     pinch->SetScrollable(gfx::Size(500, 500));
-    pinch->SetIsContainerForFixedPositionLayers(true);
     page_scale_layer->AddChild(pinch);
     root_clip->AddChild(page_scale_layer);
 
@@ -7215,7 +7212,6 @@
     scoped_refptr<Layer> pinch = Layer::Create();
     pinch->SetBounds(gfx::Size(500, 500));
     pinch->SetScrollable(gfx::Size(500, 500));
-    pinch->SetIsContainerForFixedPositionLayers(true);
     page_scale_layer->AddChild(pinch);
     root_clip->AddChild(page_scale_layer);
 
@@ -7593,7 +7589,6 @@
 
     page_scale->AddChild(inner_viewport_scroll);
     inner_viewport_scroll->AddChild(page_scale_grandchild);
-    inner_viewport_scroll->SetIsContainerForFixedPositionLayers(true);
 
     layer_tree_host()->SetRootLayer(root);
     LayerTreeTest::SetupTree();
diff --git a/cc/trees/layer_tree_host_unittest_picture.cc b/cc/trees/layer_tree_host_unittest_picture.cc
index 5601f8f9..b37ff84 100644
--- a/cc/trees/layer_tree_host_unittest_picture.cc
+++ b/cc/trees/layer_tree_host_unittest_picture.cc
@@ -410,7 +410,6 @@
     pinch_ = Layer::Create();
     pinch_->SetBounds(gfx::Size(500, 500));
     pinch_->SetScrollable(root_clip->bounds());
-    pinch_->SetIsContainerForFixedPositionLayers(true);
     page_scale_layer->AddChild(pinch_);
     root_clip->AddChild(page_scale_layer);
 
diff --git a/cc/trees/layer_tree_host_unittest_scroll.cc b/cc/trees/layer_tree_host_unittest_scroll.cc
index bb9b5e2..451a337 100644
--- a/cc/trees/layer_tree_host_unittest_scroll.cc
+++ b/cc/trees/layer_tree_host_unittest_scroll.cc
@@ -1125,6 +1125,7 @@
     scroller_->SetElementId(LayerIdToElementIdForTesting(scroller_->id()));
     CopyProperties(layer_tree_host()->outer_viewport_scroll_layer(),
                    scroller_.get());
+    CreateTransformNode(scroller_.get());
     CreateScrollNode(scroller_.get());
     layer_tree_host()->outer_viewport_scroll_layer()->AddChild(scroller_.get());
   }
@@ -2255,9 +2256,8 @@
     middle_scrollable_->SetScrollable(gfx::Size(100, 200));
     middle_scrollable_->SetHitTestable(true);
     CopyProperties(bottom_.get(), middle_scrollable_.get());
-    auto& scroll_node = CreateScrollNode(middle_scrollable_.get());
-    scroll_node.scrollable = true;
-    scroll_node.bounds = gfx::Size(100, 200);
+    CreateTransformNode(middle_scrollable_.get());
+    CreateScrollNode(middle_scrollable_.get());
     root->AddChild(middle_scrollable_);
 
     top_ = FakePictureLayer::Create(&fake_content_layer_client_);
diff --git a/cc/trees/layer_tree_impl_unittest.cc b/cc/trees/layer_tree_impl_unittest.cc
index f22b137..b3cd3ef 100644
--- a/cc/trees/layer_tree_impl_unittest.cc
+++ b/cc/trees/layer_tree_impl_unittest.cc
@@ -2594,9 +2594,11 @@
 
   std::unique_ptr<LayerImpl> child_ptr =
       LayerImpl::Create(host_impl().pending_tree(), 3);
-  // The easiest way to force the child to have a TransformNode is to make it
-  // fixed position. Similarly a non-one opacity forces an EffectNode.
-  child_ptr->test_properties()->position_constraint.set_is_fixed_position(true);
+  // A scale transform forces a TransformNode.
+  gfx::Transform scale3d;
+  scale3d.Scale3d(1, 1, 0.5);
+  child_ptr->test_properties()->transform = scale3d;
+  // A non-one opacity forces an EffectNode.
   child_ptr->test_properties()->opacity = 0.9f;
   LayerImpl* child = child_ptr.get();
   pending_root->test_properties()->AddChild(std::move(child_ptr));
diff --git a/cc/trees/property_tree.cc b/cc/trees/property_tree.cc
index 10faf5d..fb8e1b9 100644
--- a/cc/trees/property_tree.cc
+++ b/cc/trees/property_tree.cc
@@ -355,18 +355,16 @@
 
 // This function should match the offset we set for sticky position layer in
 // CompositedLayerMapping::UpdateMainGraphicsLayerGeometry.
-gfx::Vector2dF StickyPositionOffset(TransformTree* tree, TransformNode* node) {
-  if (node->sticky_position_constraint_id == -1)
+gfx::Vector2dF TransformTree::StickyPositionOffset(TransformNode* node) {
+  StickyPositionNodeData* sticky_data = MutableStickyPositionData(node->id);
+  if (!sticky_data)
     return gfx::Vector2dF();
-  StickyPositionNodeData* sticky_data = tree->StickyPositionData(node->id);
-  const LayerStickyPositionConstraint& constraint = sticky_data->constraints;
-  auto& property_trees = *tree->property_trees();
+  const StickyPositionConstraint& constraint = sticky_data->constraints;
   ScrollNode* scroll_node =
-      property_trees.scroll_tree.Node(sticky_data->scroll_ancestor);
-  TransformNode* transform_node =
-      property_trees.transform_tree.Node(scroll_node->transform_id);
+      property_trees()->scroll_tree.Node(sticky_data->scroll_ancestor);
+  TransformNode* transform_node = Node(scroll_node->transform_id);
   const auto& scroll_offset = transform_node->scroll_offset;
-  DCHECK(property_trees.scroll_tree.current_scroll_offset(
+  DCHECK(property_trees()->scroll_tree.current_scroll_offset(
              scroll_node->element_id) == scroll_offset);
   gfx::PointF scroll_position(scroll_offset.x(), scroll_offset.y());
   if (transform_node->scrolls) {
@@ -384,27 +382,32 @@
   // viewport since it shouldn't be affected by pinch-zoom.
   DCHECK(!scroll_node->scrolls_inner_viewport);
   if (scroll_node->scrolls_outer_viewport) {
-    clip.set_width(clip.width() +
-                   property_trees.outer_viewport_container_bounds_delta().x());
-    clip.set_height(clip.height() +
-                    property_trees.outer_viewport_container_bounds_delta().y());
+    clip.set_width(
+        clip.width() +
+        property_trees()->outer_viewport_container_bounds_delta().x());
+    clip.set_height(
+        clip.height() +
+        property_trees()->outer_viewport_container_bounds_delta().y());
   }
 
   gfx::Vector2dF ancestor_sticky_box_offset;
   if (sticky_data->nearest_node_shifting_sticky_box !=
       TransformTree::kInvalidNodeId) {
+    const StickyPositionNodeData* ancestor_sticky_data =
+        GetStickyPositionData(sticky_data->nearest_node_shifting_sticky_box);
+    DCHECK(ancestor_sticky_data);
     ancestor_sticky_box_offset =
-        tree->StickyPositionData(sticky_data->nearest_node_shifting_sticky_box)
-            ->total_sticky_box_sticky_offset;
+        ancestor_sticky_data->total_sticky_box_sticky_offset;
   }
 
   gfx::Vector2dF ancestor_containing_block_offset;
   if (sticky_data->nearest_node_shifting_containing_block !=
       TransformTree::kInvalidNodeId) {
+    const StickyPositionNodeData* ancestor_sticky_data = GetStickyPositionData(
+        sticky_data->nearest_node_shifting_containing_block);
+    DCHECK(ancestor_sticky_data);
     ancestor_containing_block_offset =
-        tree->StickyPositionData(
-                sticky_data->nearest_node_shifting_containing_block)
-            ->total_containing_block_sticky_offset;
+        ancestor_sticky_data->total_containing_block_sticky_offset;
   }
 
   // Compute the current position of the constraint rects based on the original
@@ -514,20 +517,16 @@
     node->source_to_parent = to_parent.To2dTranslation();
   }
 
-  gfx::Vector2dF fixed_position_adjustment;
-  gfx::Vector2dF outer_viewport_bounds_delta =
-      property_trees()->outer_viewport_container_bounds_delta();
-  if (node->moved_by_outer_viewport_bounds_delta_x)
-    fixed_position_adjustment.set_x(outer_viewport_bounds_delta.x());
+  float fixed_position_adjustment = 0;
+  if (node->moved_by_outer_viewport_bounds_delta_y) {
+    fixed_position_adjustment =
+        property_trees()->outer_viewport_container_bounds_delta().y();
+  }
 
-  if (node->moved_by_outer_viewport_bounds_delta_y)
-    fixed_position_adjustment.set_y(outer_viewport_bounds_delta.y());
-
-  transform.Translate(node->source_to_parent.x() - node->scroll_offset.x() +
-                          fixed_position_adjustment.x(),
+  transform.Translate(node->source_to_parent.x() - node->scroll_offset.x(),
                       node->source_to_parent.y() - node->scroll_offset.y() +
-                          fixed_position_adjustment.y());
-  transform.Translate(StickyPositionOffset(this, node));
+                          fixed_position_adjustment);
+  transform.Translate(StickyPositionOffset(node));
   transform.PreconcatTransform(node->local);
   transform.Translate3d(gfx::Point3F() - node->origin);
 
@@ -732,13 +731,20 @@
          cached_data_ == other.cached_data();
 }
 
-StickyPositionNodeData* TransformTree::StickyPositionData(int node_id) {
+StickyPositionNodeData* TransformTree::MutableStickyPositionData(int node_id) {
+  const TransformNode* node = Node(node_id);
+  if (node->sticky_position_constraint_id == -1)
+    return nullptr;
+  return &sticky_position_data_[node->sticky_position_constraint_id];
+}
+
+StickyPositionNodeData& TransformTree::EnsureStickyPositionData(int node_id) {
   TransformNode* node = Node(node_id);
   if (node->sticky_position_constraint_id == -1) {
     node->sticky_position_constraint_id = sticky_position_data_.size();
     sticky_position_data_.push_back(StickyPositionNodeData());
   }
-  return &sticky_position_data_[node->sticky_position_constraint_id];
+  return sticky_position_data_[node->sticky_position_constraint_id];
 }
 
 EffectTree::EffectTree() {
diff --git a/cc/trees/property_tree.h b/cc/trees/property_tree.h
index f550442..095f9aa3 100644
--- a/cc/trees/property_tree.h
+++ b/cc/trees/property_tree.h
@@ -14,10 +14,10 @@
 #include "base/containers/flat_map.h"
 #include "cc/base/synced_property.h"
 #include "cc/cc_export.h"
-#include "cc/layers/layer_sticky_position_constraint.h"
 #include "cc/paint/element_id.h"
 #include "cc/paint/filter_operations.h"
 #include "cc/trees/mutator_host_client.h"
+#include "cc/trees/sticky_position_constraint.h"
 #include "ui/gfx/geometry/rect_f.h"
 #include "ui/gfx/geometry/scroll_offset.h"
 #include "ui/gfx/transform.h"
@@ -219,7 +219,10 @@
     return cached_data_;
   }
 
-  StickyPositionNodeData* StickyPositionData(int node_id);
+  const StickyPositionNodeData* GetStickyPositionData(int node_id) const {
+    return const_cast<TransformTree*>(this)->MutableStickyPositionData(node_id);
+  }
+  StickyPositionNodeData& EnsureStickyPositionData(int node_id);
 
   // Computes the combined transform between |source_id| and |dest_id|. These
   // two nodes must be on the same ancestor chain.
@@ -239,6 +242,8 @@
   // |anc_id|.
   bool IsDescendant(int desc_id, int anc_id) const;
 
+  StickyPositionNodeData* MutableStickyPositionData(int node_id);
+  gfx::Vector2dF StickyPositionOffset(TransformNode* node);
   void UpdateLocalTransform(TransformNode* node);
   void UpdateScreenSpaceTransform(TransformNode* node,
                                   TransformNode* parent_node);
@@ -265,7 +270,7 @@
 
 struct StickyPositionNodeData {
   int scroll_ancestor;
-  LayerStickyPositionConstraint constraints;
+  StickyPositionConstraint constraints;
 
   // In order to properly compute the sticky offset, we need to know if we have
   // any sticky ancestors both between ourselves and our containing block and
diff --git a/cc/trees/property_tree_builder.cc b/cc/trees/property_tree_builder.cc
index a297ead..9ef20eb 100644
--- a/cc/trees/property_tree_builder.cc
+++ b/cc/trees/property_tree_builder.cc
@@ -32,7 +32,6 @@
 
 struct DataForRecursion {
   int transform_tree_parent;
-  int transform_tree_parent_fixed;
   int clip_tree_parent;
   int effect_tree_parent;
   int scroll_tree_parent;
@@ -131,23 +130,6 @@
   std::multimap<const LayerType*, LayerType*> scroll_children_map_;
 };
 
-static LayerPositionConstraint PositionConstraint(Layer* layer) {
-  return layer->position_constraint();
-}
-
-static LayerPositionConstraint PositionConstraint(LayerImpl* layer) {
-  return layer->test_properties()->position_constraint;
-}
-
-static LayerStickyPositionConstraint StickyPositionConstraint(Layer* layer) {
-  return layer->sticky_position_constraint();
-}
-
-static LayerStickyPositionConstraint StickyPositionConstraint(
-    LayerImpl* layer) {
-  return layer->test_properties()->sticky_position_constraint;
-}
-
 static LayerImplList& LayerChildren(LayerImpl* layer) {
   return layer->test_properties()->children;
 }
@@ -302,13 +284,6 @@
 // -------------------------------------------------------------------
 
 template <typename LayerType>
-static int GetTransformParent(const DataForRecursion& data, LayerType* layer) {
-  return PositionConstraint(layer).is_fixed_position()
-             ? data.transform_tree_parent_fixed
-             : data.transform_tree_parent;
-}
-
-template <typename LayerType>
 static bool LayerClipsSubtreeToItsBounds(LayerType* layer) {
   return layer->masks_to_bounds() || MaskLayer(layer);
 }
@@ -409,7 +384,7 @@
 
     node.transform_id = created_transform_node
                             ? data_for_children->transform_tree_parent
-                            : GetTransformParent(data_from_ancestor, layer);
+                            : data_from_ancestor.transform_tree_parent;
     if (layer_clips_subtree) {
       node.clip_type = ClipNode::ClipType::APPLIES_LOCAL_CLIP;
     } else {
@@ -439,14 +414,6 @@
   return layer->test_properties()->transform_origin;
 }
 
-static inline bool IsContainerForFixedPositionLayers(Layer* layer) {
-  return layer->IsContainerForFixedPositionLayers();
-}
-
-static inline bool IsContainerForFixedPositionLayers(LayerImpl* layer) {
-  return layer->test_properties()->is_container_for_fixed_position_layers;
-}
-
 static inline bool ShouldFlattenTransform(Layer* layer) {
   return layer->should_flatten_transform();
 }
@@ -467,8 +434,6 @@
       overscroll_elasticity_element_id_ &&
       layer->element_id() == overscroll_elasticity_element_id_;
   const bool is_scrollable = layer->scrollable();
-  const bool is_fixed = PositionConstraint(layer).is_fixed_position();
-  const bool is_sticky = StickyPositionConstraint(layer).is_sticky;
   // Scrolling a layer should not move it from being pixel-aligned to moving off
   // the pixel grid and becoming fuzzy. So always snap scrollable things to the
   // pixel grid. Layers may also request to be snapped as such.
@@ -495,9 +460,9 @@
 
   DCHECK(!is_scrollable || is_snapped);
   bool requires_node = is_root || is_snapped || has_significant_transform ||
-                       has_any_transform_animation || has_surface || is_fixed ||
+                       has_any_transform_animation || has_surface ||
                        is_page_scale_layer || is_overscroll_elasticity_layer ||
-                       is_sticky || is_at_boundary_of_3d_rendering_context ||
+                       is_at_boundary_of_3d_rendering_context ||
                        HasRoundedCorner(layer);
 
   int parent_index = TransformTree::kRootNodeId;
@@ -505,7 +470,7 @@
   gfx::Vector2dF source_offset;
 
   if (!is_root) {
-    parent_index = GetTransformParent(data_from_ancestor, layer);
+    parent_index = data_from_ancestor.transform_tree_parent;
     // Because Blink still provides positions with respect to the parent layer,
     // we track both a parent TransformNode (which is the parent in the
     // TransformTree) and a 'source' TransformNode (which is the TransformNode
@@ -514,31 +479,6 @@
     source_offset = LayerParent(layer)->offset_to_transform_parent();
   }
 
-  // For a container of fixed position descendants, define for them their
-  // fixed-position transform parent as being this layer's transform node, or
-  // its transform parent's node if this layer won't have a node of its own.
-  //
-  // But if this layer is scrollable, then we point fixed position descendants
-  // to not be affected by this layer as it changes its scroll offset during
-  // a compositor thread scroll. We do this by pointing them to the direct
-  // parent of this layer, which acts as a proxy for this layer, without
-  // including scrolling, based on the assumption this layer has no transform
-  // itself when scrollable.
-  if (IsContainerForFixedPositionLayers(layer) || is_root) {
-    data_for_children->affected_by_outer_viewport_bounds_delta =
-        layer->IsResizedByBrowserControls();
-    if (is_scrollable) {
-      DCHECK(Transform(layer).IsIdentity());
-      if (!is_root) {
-        data_for_children->transform_tree_parent_fixed =
-            LayerParent(layer)->transform_tree_index();
-      }
-    } else {
-      data_for_children->transform_tree_parent_fixed =
-          requires_node ? transform_tree_.next_available_id() : parent_index;
-    }
-  }
-
   if (!requires_node) {
     data_for_children->should_flatten |= ShouldFlattenTransform(layer);
     gfx::Vector2dF local_offset =
@@ -619,62 +559,6 @@
     node->scroll_offset = layer->CurrentScrollOffset();
   }
 
-  if (is_fixed) {
-    if (data_from_ancestor.affected_by_outer_viewport_bounds_delta) {
-      node->moved_by_outer_viewport_bounds_delta_x =
-          PositionConstraint(layer).is_fixed_to_right_edge();
-      node->moved_by_outer_viewport_bounds_delta_y =
-          PositionConstraint(layer).is_fixed_to_bottom_edge();
-      if (node->moved_by_outer_viewport_bounds_delta_x ||
-          node->moved_by_outer_viewport_bounds_delta_y) {
-        transform_tree_.AddNodeAffectedByOuterViewportBoundsDelta(node->id);
-      }
-    }
-  }
-
-  if (StickyPositionConstraint(layer).is_sticky) {
-    StickyPositionNodeData* sticky_data =
-        transform_tree_.StickyPositionData(node->id);
-    sticky_data->constraints = StickyPositionConstraint(layer);
-    sticky_data->scroll_ancestor = GetScrollParentId(data_from_ancestor, layer);
-    ScrollNode* scroll_ancestor =
-        scroll_tree_.Node(sticky_data->scroll_ancestor);
-
-    // Position sticky should never attach to the inner viewport since it
-    // shouldn't be affected by pinch-zoom. If we did then we'd need setting
-    // the inner viewport bounds delta to cause a TransformTree update, which
-    // it currently doesn't.
-    DCHECK(!scroll_ancestor->scrolls_inner_viewport);
-
-    if (sticky_data->constraints.is_anchored_right ||
-        sticky_data->constraints.is_anchored_bottom) {
-      // Sticky nodes whose ancestor scroller is the inner / outer viewport
-      // need to have their local transform updated when the inner / outer
-      // viewport bounds change, but do not unconditionally move by that delta
-      // like fixed position nodes.
-      if (scroll_ancestor->scrolls_outer_viewport)
-        transform_tree_.AddNodeAffectedByOuterViewportBoundsDelta(node->id);
-    }
-    // Copy the ancestor nodes for later use. These elements are guaranteed to
-    // have transform nodes at this point because they are our ancestors (so
-    // have already been processed) and are sticky (so have transform nodes).
-    ElementId shifting_sticky_box_element_id =
-        sticky_data->constraints.nearest_element_shifting_sticky_box;
-    if (shifting_sticky_box_element_id) {
-      sticky_data->nearest_node_shifting_sticky_box =
-          transform_tree_.FindNodeFromElementId(shifting_sticky_box_element_id)
-              ->id;
-    }
-    ElementId shifting_containing_block_element_id =
-        sticky_data->constraints.nearest_element_shifting_containing_block;
-    if (shifting_containing_block_element_id) {
-      sticky_data->nearest_node_shifting_containing_block =
-          transform_tree_
-              .FindNodeFromElementId(shifting_containing_block_element_id)
-              ->id;
-    }
-  }
-
   node->needs_local_transform_update = true;
   transform_tree_.UpdateTransforms(node->id);
 
@@ -1492,8 +1376,6 @@
 
   DataForRecursion data_for_recursion;
   data_for_recursion.transform_tree_parent = TransformTree::kInvalidNodeId;
-  data_for_recursion.transform_tree_parent_fixed =
-      TransformTree::kInvalidNodeId;
   data_for_recursion.clip_tree_parent = ClipTree::kRootNodeId;
   data_for_recursion.effect_tree_parent = EffectTree::kInvalidNodeId;
   data_for_recursion.scroll_tree_parent = ScrollTree::kRootNodeId;
diff --git a/cc/trees/sticky_position_constraint.cc b/cc/trees/sticky_position_constraint.cc
new file mode 100644
index 0000000..19f4cabe
--- /dev/null
+++ b/cc/trees/sticky_position_constraint.cc
@@ -0,0 +1,47 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "cc/trees/sticky_position_constraint.h"
+
+namespace cc {
+
+StickyPositionConstraint::StickyPositionConstraint()
+    : is_anchored_left(false),
+      is_anchored_right(false),
+      is_anchored_top(false),
+      is_anchored_bottom(false),
+      left_offset(0.f),
+      right_offset(0.f),
+      top_offset(0.f),
+      bottom_offset(0.f) {}
+
+StickyPositionConstraint::StickyPositionConstraint(
+    const StickyPositionConstraint& other) = default;
+
+bool StickyPositionConstraint::operator==(
+    const StickyPositionConstraint& other) const {
+  return is_anchored_left == other.is_anchored_left &&
+         is_anchored_right == other.is_anchored_right &&
+         is_anchored_top == other.is_anchored_top &&
+         is_anchored_bottom == other.is_anchored_bottom &&
+         left_offset == other.left_offset &&
+         right_offset == other.right_offset && top_offset == other.top_offset &&
+         bottom_offset == other.bottom_offset &&
+         constraint_box_rect == other.constraint_box_rect &&
+         scroll_container_relative_sticky_box_rect ==
+             other.scroll_container_relative_sticky_box_rect &&
+         scroll_container_relative_containing_block_rect ==
+             other.scroll_container_relative_containing_block_rect &&
+         nearest_element_shifting_sticky_box ==
+             other.nearest_element_shifting_sticky_box &&
+         nearest_element_shifting_containing_block ==
+             other.nearest_element_shifting_containing_block;
+}
+
+bool StickyPositionConstraint::operator!=(
+    const StickyPositionConstraint& other) const {
+  return !(*this == other);
+}
+
+}  // namespace cc
diff --git a/cc/layers/layer_sticky_position_constraint.h b/cc/trees/sticky_position_constraint.h
similarity index 72%
rename from cc/layers/layer_sticky_position_constraint.h
rename to cc/trees/sticky_position_constraint.h
index d3075d9..3a0b06b0 100644
--- a/cc/layers/layer_sticky_position_constraint.h
+++ b/cc/trees/sticky_position_constraint.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CC_LAYERS_LAYER_STICKY_POSITION_CONSTRAINT_H_
-#define CC_LAYERS_LAYER_STICKY_POSITION_CONSTRAINT_H_
+#ifndef CC_TREES_STICKY_POSITION_CONSTRAINT_H_
+#define CC_TREES_STICKY_POSITION_CONSTRAINT_H_
 
 #include "cc/cc_export.h"
 
@@ -14,11 +14,10 @@
 
 namespace cc {
 
-struct CC_EXPORT LayerStickyPositionConstraint {
-  LayerStickyPositionConstraint();
-  LayerStickyPositionConstraint(const LayerStickyPositionConstraint& other);
+struct CC_EXPORT StickyPositionConstraint {
+  StickyPositionConstraint();
+  StickyPositionConstraint(const StickyPositionConstraint& other);
 
-  bool is_sticky : 1;
   bool is_anchored_left : 1;
   bool is_anchored_right : 1;
   bool is_anchored_top : 1;
@@ -48,17 +47,17 @@
 
   // The nearest ancestor sticky element ids that affect the sticky box
   // constraint rect and the containing block constraint rect respectively.
+  // They are used to generate nearest_node_shifting_sticky_box and
+  // nearest_node_shifting_containing_block in StickyPositionNodeData when the
+  // property trees are generated. They are useless after the property trees
+  // are generated.
   ElementId nearest_element_shifting_sticky_box;
   ElementId nearest_element_shifting_containing_block;
 
-  // Returns the nearest sticky ancestor element id or the default element id if
-  // none exists.
-  ElementId NearestStickyAncestor();
-
-  bool operator==(const LayerStickyPositionConstraint&) const;
-  bool operator!=(const LayerStickyPositionConstraint&) const;
+  bool operator==(const StickyPositionConstraint&) const;
+  bool operator!=(const StickyPositionConstraint&) const;
 };
 
 }  // namespace cc
 
-#endif  // CC_LAYERS_LAYER_STICKY_POSITION_CONSTRAINT_H_
+#endif  // CC_TREES_STICKY_POSITION_CONSTRAINT_H_
diff --git a/cc/trees/transform_node.cc b/cc/trees/transform_node.cc
index 3a791c4..b5712ac 100644
--- a/cc/trees/transform_node.cc
+++ b/cc/trees/transform_node.cc
@@ -30,7 +30,6 @@
       node_and_ancestors_have_only_integer_translation(true),
       scrolls(false),
       should_be_snapped(false),
-      moved_by_outer_viewport_bounds_delta_x(false),
       moved_by_outer_viewport_bounds_delta_y(false),
       in_subtree_of_page_scale_layer(false),
       transform_changed(false),
@@ -61,8 +60,6 @@
              other.node_and_ancestors_have_only_integer_translation &&
          scrolls == other.scrolls &&
          should_be_snapped == other.should_be_snapped &&
-         moved_by_outer_viewport_bounds_delta_x ==
-             other.moved_by_outer_viewport_bounds_delta_x &&
          moved_by_outer_viewport_bounds_delta_y ==
              other.moved_by_outer_viewport_bounds_delta_y &&
          in_subtree_of_page_scale_layer ==
diff --git a/cc/trees/transform_node.h b/cc/trees/transform_node.h
index 9a7eb49..a017516 100644
--- a/cc/trees/transform_node.h
+++ b/cc/trees/transform_node.h
@@ -95,13 +95,9 @@
 
   bool should_be_snapped : 1;
 
-  // These are used by the compositor to determine which layers need to be
-  // repositioned by the compositor as a result of browser controls
-  // expanding/contracting the outer viewport size before Blink repositions the
-  // fixed layers.
-  // TODO(bokan): Note: we never change bounds_delta in the x direction so we
-  // can remove this variable.
-  bool moved_by_outer_viewport_bounds_delta_x : 1;
+  // Used by the compositor to determine which layers need to be repositioned by
+  // the compositor as a result of browser controls expanding/contracting the
+  // outer viewport size before Blink repositions the fixed layers.
   bool moved_by_outer_viewport_bounds_delta_y : 1;
 
   // Layer scale factor is used as a fallback when we either cannot adjust
diff --git a/third_party/blink/renderer/core/exported/web_layer_test.cc b/third_party/blink/renderer/core/exported/web_layer_test.cc
index 9125fd8..6b09254 100644
--- a/third_party/blink/renderer/core/exported/web_layer_test.cc
+++ b/third_party/blink/renderer/core/exported/web_layer_test.cc
@@ -699,7 +699,6 @@
         GetPropertyTrees()->transform_tree.Node(transform_tree_index);
 
     DCHECK(transform_node);
-    EXPECT_FALSE(transform_node->moved_by_outer_viewport_bounds_delta_x);
     EXPECT_TRUE(transform_node->moved_by_outer_viewport_bounds_delta_y);
   }
 
@@ -715,7 +714,6 @@
         GetPropertyTrees()->transform_tree.Node(transform_tree_index);
 
     DCHECK(transform_node);
-    EXPECT_FALSE(transform_node->moved_by_outer_viewport_bounds_delta_x);
     EXPECT_FALSE(transform_node->moved_by_outer_viewport_bounds_delta_y);
   }
 }
diff --git a/third_party/blink/renderer/core/inspector/DEPS b/third_party/blink/renderer/core/inspector/DEPS
index 97ba2c0b..6d25280 100644
--- a/third_party/blink/renderer/core/inspector/DEPS
+++ b/third_party/blink/renderer/core/inspector/DEPS
@@ -5,4 +5,5 @@
     "+base/sampling_heap_profiler/sampling_heap_profiler.h",
     # for base::GetUniqueIdForProcess
     "+base/process/process_handle.h",
+    "+cc/trees/transform_node.h",
 ]
diff --git a/third_party/blink/renderer/core/inspector/inspector_layer_tree_agent.cc b/third_party/blink/renderer/core/inspector/inspector_layer_tree_agent.cc
index b1dd96b5..1143488 100644
--- a/third_party/blink/renderer/core/inspector/inspector_layer_tree_agent.cc
+++ b/third_party/blink/renderer/core/inspector/inspector_layer_tree_agent.cc
@@ -36,6 +36,7 @@
 #include "base/stl_util.h"
 #include "cc/base/region.h"
 #include "cc/layers/picture_layer.h"
+#include "cc/trees/transform_node.h"
 #include "third_party/blink/public/platform/web_float_point.h"
 #include "third_party/blink/renderer/core/dom/document.h"
 #include "third_party/blink/renderer/core/dom/dom_node_ids.h"
@@ -139,10 +140,17 @@
 
 static std::unique_ptr<protocol::LayerTree::StickyPositionConstraint>
 BuildStickyInfoForLayer(const cc::Layer* root, const cc::Layer* layer) {
-  cc::LayerStickyPositionConstraint constraints =
-      layer->sticky_position_constraint();
-  if (!constraints.is_sticky)
+  if (!layer->has_transform_node())
     return nullptr;
+  // Note that we'll miss the sticky transform node if multiple transform nodes
+  // apply to the layer.
+  const cc::StickyPositionNodeData* sticky_data =
+      layer->layer_tree_host()
+          ->property_trees()
+          ->transform_tree.GetStickyPositionData(layer->transform_tree_index());
+  if (!sticky_data)
+    return nullptr;
+  const cc::StickyPositionConstraint& constraints = sticky_data->constraints;
 
   std::unique_ptr<protocol::DOM::Rect> sticky_box_rect =
       BuildObjectForRect(constraints.scroll_container_relative_sticky_box_rect);
diff --git a/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator_test.cc b/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator_test.cc
index 70f6322..6e873205 100644
--- a/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator_test.cc
+++ b/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator_test.cc
@@ -25,8 +25,8 @@
 #include "third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.h"
 
 #include "build/build_config.h"
-#include "cc/layers/layer_sticky_position_constraint.h"
 #include "cc/layers/picture_layer.h"
+#include "cc/trees/sticky_position_constraint.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/blink/public/platform/platform.h"
 #include "third_party/blink/public/platform/web_cache.h"
@@ -222,7 +222,7 @@
 }
 
 // Sticky constraints are stored on transform property tree nodes.
-static cc::LayerStickyPositionConstraint GetStickyConstraint(Element* element) {
+static cc::StickyPositionConstraint GetStickyConstraint(Element* element) {
   const auto* properties =
       element->GetLayoutObject()->FirstFragment().PaintProperties();
   DCHECK(properties);
@@ -243,7 +243,6 @@
   {
     Element* element = document->getElementById("div-tl");
     auto constraint = GetStickyConstraint(element);
-    ASSERT_TRUE(constraint.is_sticky);
     EXPECT_TRUE(constraint.is_anchored_top && constraint.is_anchored_left &&
                 !constraint.is_anchored_right &&
                 !constraint.is_anchored_bottom);
@@ -257,28 +256,24 @@
   {
     Element* element = document->getElementById("div-tr");
     auto constraint = GetStickyConstraint(element);
-    ASSERT_TRUE(constraint.is_sticky);
     EXPECT_TRUE(constraint.is_anchored_top && !constraint.is_anchored_left &&
                 constraint.is_anchored_right && !constraint.is_anchored_bottom);
   }
   {
     Element* element = document->getElementById("div-bl");
     auto constraint = GetStickyConstraint(element);
-    ASSERT_TRUE(constraint.is_sticky);
     EXPECT_TRUE(!constraint.is_anchored_top && constraint.is_anchored_left &&
                 !constraint.is_anchored_right && constraint.is_anchored_bottom);
   }
   {
     Element* element = document->getElementById("div-br");
     auto constraint = GetStickyConstraint(element);
-    ASSERT_TRUE(constraint.is_sticky);
     EXPECT_TRUE(!constraint.is_anchored_top && !constraint.is_anchored_left &&
                 constraint.is_anchored_right && constraint.is_anchored_bottom);
   }
   {
     Element* element = document->getElementById("span-tl");
     auto constraint = GetStickyConstraint(element);
-    ASSERT_TRUE(constraint.is_sticky);
     EXPECT_TRUE(constraint.is_anchored_top && constraint.is_anchored_left &&
                 !constraint.is_anchored_right &&
                 !constraint.is_anchored_bottom);
@@ -286,7 +281,6 @@
   {
     Element* element = document->getElementById("span-tlbr");
     auto constraint = GetStickyConstraint(element);
-    ASSERT_TRUE(constraint.is_sticky);
     EXPECT_TRUE(constraint.is_anchored_top && constraint.is_anchored_left &&
                 constraint.is_anchored_right && constraint.is_anchored_bottom);
     EXPECT_EQ(1.f, constraint.top_offset);
@@ -297,7 +291,6 @@
   {
     Element* element = document->getElementById("composited-top");
     auto constraint = GetStickyConstraint(element);
-    ASSERT_TRUE(constraint.is_sticky);
     EXPECT_TRUE(constraint.is_anchored_top);
     EXPECT_EQ(gfx::Rect(100, 110, 10, 10),
               constraint.scroll_container_relative_sticky_box_rect);
diff --git a/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc b/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc
index 98b1d11..04c77de 100644
--- a/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc
+++ b/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc
@@ -556,7 +556,6 @@
                 ->GetStickyConstraintsMap()
                 .at(layer);
         auto constraint = std::make_unique<CompositorStickyConstraint>();
-        constraint->is_sticky = true;
         constraint->is_anchored_left = layout_constraint.is_anchored_left;
         constraint->is_anchored_right = layout_constraint.is_anchored_right;
         constraint->is_anchored_top = layout_constraint.is_anchored_top;
diff --git a/third_party/blink/renderer/core/paint/paint_property_tree_builder_test.cc b/third_party/blink/renderer/core/paint/paint_property_tree_builder_test.cc
index 8c5a2a7d3..1f6bbec6f 100644
--- a/third_party/blink/renderer/core/paint/paint_property_tree_builder_test.cc
+++ b/third_party/blink/renderer/core/paint/paint_property_tree_builder_test.cc
@@ -6225,8 +6225,6 @@
             outer_properties->StickyTranslation()->Translation2D());
   ASSERT_NE(nullptr,
             outer_properties->StickyTranslation()->GetStickyConstraint());
-  EXPECT_TRUE(
-      outer_properties->StickyTranslation()->GetStickyConstraint()->is_sticky);
   EXPECT_EQ(CompositorElementId(), outer_properties->StickyTranslation()
                                        ->GetStickyConstraint()
                                        ->nearest_element_shifting_sticky_box);
@@ -6241,8 +6239,6 @@
             middle_properties->StickyTranslation()->Translation2D());
   ASSERT_NE(nullptr,
             middle_properties->StickyTranslation()->GetStickyConstraint());
-  EXPECT_TRUE(
-      middle_properties->StickyTranslation()->GetStickyConstraint()->is_sticky);
   EXPECT_EQ(CompositorElementId(), middle_properties->StickyTranslation()
                                        ->GetStickyConstraint()
                                        ->nearest_element_shifting_sticky_box);
@@ -6257,8 +6253,6 @@
             inner_properties->StickyTranslation()->Translation2D());
   ASSERT_NE(nullptr,
             inner_properties->StickyTranslation()->GetStickyConstraint());
-  EXPECT_TRUE(
-      inner_properties->StickyTranslation()->GetStickyConstraint()->is_sticky);
   EXPECT_EQ(middle_properties->StickyTranslation()->GetCompositorElementId(),
             inner_properties->StickyTranslation()
                 ->GetStickyConstraint()
diff --git a/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.cc b/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.cc
index df2fcc5..2e230da 100644
--- a/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.cc
+++ b/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.cc
@@ -409,28 +409,26 @@
       transform_node.IsInSubtreeOfPageScale();
 
   if (const auto* sticky_constraint = transform_node.GetStickyConstraint()) {
-    DCHECK(sticky_constraint->is_sticky);
-    cc::StickyPositionNodeData* sticky_data =
-        GetTransformTree().StickyPositionData(id);
-    sticky_data->constraints = *sticky_constraint;
+    cc::StickyPositionNodeData& sticky_data =
+        GetTransformTree().EnsureStickyPositionData(id);
+    sticky_data.constraints = *sticky_constraint;
     // TODO(pdr): This could be a performance issue because it crawls up the
     // transform tree for each pending layer. If this is on profiles, we should
     // cache a lookup of transform node to scroll translation transform node.
     const auto& scroll_ancestor = transform_node.NearestScrollTranslationNode();
-    sticky_data->scroll_ancestor = EnsureCompositorScrollNode(scroll_ancestor);
+    sticky_data.scroll_ancestor = EnsureCompositorScrollNode(scroll_ancestor);
     if (scroll_ancestor.ScrollNode()->ScrollsOuterViewport())
       GetTransformTree().AddNodeAffectedByOuterViewportBoundsDelta(id);
     if (auto shifting_sticky_box_element_id =
-            sticky_data->constraints.nearest_element_shifting_sticky_box) {
-      sticky_data->nearest_node_shifting_sticky_box =
+            sticky_data.constraints.nearest_element_shifting_sticky_box) {
+      sticky_data.nearest_node_shifting_sticky_box =
           GetTransformTree()
               .FindNodeFromElementId(shifting_sticky_box_element_id)
               ->id;
     }
     if (auto shifting_containing_block_element_id =
-            sticky_data->constraints
-                .nearest_element_shifting_containing_block) {
-      sticky_data->nearest_node_shifting_containing_block =
+            sticky_data.constraints.nearest_element_shifting_containing_block) {
+      sticky_data.nearest_node_shifting_containing_block =
           GetTransformTree()
               .FindNodeFromElementId(shifting_containing_block_element_id)
               ->id;
diff --git a/third_party/blink/renderer/platform/graphics/graphics_layer.h b/third_party/blink/renderer/platform/graphics/graphics_layer.h
index 99470c7..0d784787 100644
--- a/third_party/blink/renderer/platform/graphics/graphics_layer.h
+++ b/third_party/blink/renderer/platform/graphics/graphics_layer.h
@@ -35,7 +35,6 @@
 #include "cc/layers/content_layer_client.h"
 #include "cc/layers/layer.h"
 #include "cc/layers/layer_client.h"
-#include "cc/layers/layer_sticky_position_constraint.h"
 #include "third_party/blink/renderer/platform/geometry/float_point.h"
 #include "third_party/blink/renderer/platform/geometry/float_point_3d.h"
 #include "third_party/blink/renderer/platform/geometry/float_size.h"
diff --git a/third_party/blink/renderer/platform/graphics/paint/transform_paint_property_node.h b/third_party/blink/renderer/platform/graphics/paint/transform_paint_property_node.h
index da6ed6ce..f48c35cf 100644
--- a/third_party/blink/renderer/platform/graphics/paint/transform_paint_property_node.h
+++ b/third_party/blink/renderer/platform/graphics/paint/transform_paint_property_node.h
@@ -6,7 +6,7 @@
 #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_PAINT_TRANSFORM_PAINT_PROPERTY_NODE_H_
 
 #include <algorithm>
-#include "cc/layers/layer_sticky_position_constraint.h"
+#include "cc/trees/sticky_position_constraint.h"
 #include "third_party/blink/renderer/platform/geometry/float_point_3d.h"
 #include "third_party/blink/renderer/platform/graphics/compositing_reasons.h"
 #include "third_party/blink/renderer/platform/graphics/compositor_element_id.h"
@@ -20,7 +20,7 @@
 
 namespace blink {
 
-using CompositorStickyConstraint = cc::LayerStickyPositionConstraint;
+using CompositorStickyConstraint = cc::StickyPositionConstraint;
 
 // A transform (e.g., created by css "transform" or "perspective", or for
 // internal positioning such as paint offset or scrolling) along with a
@@ -292,7 +292,7 @@
     return state_.flags.in_subtree_of_page_scale;
   }
 
-  const cc::LayerStickyPositionConstraint* GetStickyConstraint() const {
+  const CompositorStickyConstraint* GetStickyConstraint() const {
     return state_.sticky_constraint.get();
   }
 
diff --git a/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py b/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py
index 8a947d2..1bb5c47 100755
--- a/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py
+++ b/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py
@@ -254,12 +254,13 @@
             # cc::Layer helper data structs.
             'cc::ElementId',
             'cc::LayerPositionConstraint',
-            'cc::LayerStickyPositionConstraint',
             'cc::OverscrollBehavior',
             'cc::Scrollbar',
             'cc::ScrollbarLayerInterface',
             'cc::ScrollbarOrientation',
             'cc::ScrollbarPart',
+            'cc::StickyPositionConstraint',
+            'cc::StickyPositionNodeData',
             'cc::ViewportLayers',
 
             # cc::Layer helper enums.