Index: cc/trees/layer_tree_host_common_unittest.cc |
diff --git a/cc/trees/layer_tree_host_common_unittest.cc b/cc/trees/layer_tree_host_common_unittest.cc |
index 755e6f8ef13f4233c99cbe99f679ce2c2fa276b7..4493dde1efe0bc10807c1ddb51b02a1d7fe8d63e 100644 |
--- a/cc/trees/layer_tree_host_common_unittest.cc |
+++ b/cc/trees/layer_tree_host_common_unittest.cc |
@@ -7086,11 +7086,11 @@ TEST_F(LayerTreeHostCommonTest, StickyPositionTop) { |
sticky_position.is_sticky = true; |
sticky_position.is_anchored_top = true; |
sticky_position.top_offset = 10.0f; |
- sticky_position.parent_relative_sticky_box_offset = gfx::Point(10, 20); |
+ sticky_position.parent_relative_sticky_box_offset = gfx::PointF(10, 20); |
sticky_position.scroll_container_relative_sticky_box_rect = |
- gfx::Rect(10, 20, 10, 10); |
+ gfx::RectF(10, 20, 10, 10); |
sticky_position.scroll_container_relative_containing_block_rect = |
- gfx::Rect(0, 0, 50, 50); |
+ gfx::RectF(0, 0, 50, 50); |
sticky_pos->SetStickyPositionConstraint(sticky_position); |
root->SetBounds(gfx::Size(100, 100)); |
@@ -7155,15 +7155,18 @@ TEST_F(LayerTreeHostCommonTest, StickyPositionTopScrollParent) { |
host()->SetRootLayer(root); |
scroller->SetScrollClipLayerId(container->id()); |
+ // 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.parent_relative_sticky_box_offset = gfx::Point(10, 20); |
+ sticky_position.parent_relative_sticky_box_offset = gfx::PointF(10, 20); |
sticky_position.scroll_container_relative_sticky_box_rect = |
- gfx::Rect(10, 20, 10, 10); |
+ gfx::RectF(10, 20, 10, 10); |
sticky_position.scroll_container_relative_containing_block_rect = |
- gfx::Rect(0, 0, 50, 50); |
+ gfx::RectF(0, 0, 50, 50); |
sticky_pos->SetStickyPositionConstraint(sticky_position); |
root->SetBounds(gfx::Size(200, 200)); |
@@ -7232,11 +7235,11 @@ TEST_F(LayerTreeHostCommonTest, StickyPositionSubpixelScroll) { |
sticky_position.is_sticky = true; |
sticky_position.is_anchored_bottom = true; |
sticky_position.bottom_offset = 10.0f; |
- sticky_position.parent_relative_sticky_box_offset = gfx::Point(0, 200); |
+ sticky_position.parent_relative_sticky_box_offset = gfx::PointF(0, 200); |
sticky_position.scroll_container_relative_sticky_box_rect = |
- gfx::Rect(0, 200, 10, 10); |
+ gfx::RectF(0, 200, 10, 10); |
sticky_position.scroll_container_relative_containing_block_rect = |
- gfx::Rect(0, 0, 100, 500); |
+ gfx::RectF(0, 0, 100, 500); |
sticky_pos->SetStickyPositionConstraint(sticky_position); |
root->SetBounds(gfx::Size(100, 100)); |
@@ -7278,11 +7281,11 @@ TEST_F(LayerTreeHostCommonTest, StickyPositionBottom) { |
sticky_position.is_sticky = true; |
sticky_position.is_anchored_bottom = true; |
sticky_position.bottom_offset = 10.0f; |
- sticky_position.parent_relative_sticky_box_offset = gfx::Point(0, 150); |
+ sticky_position.parent_relative_sticky_box_offset = gfx::PointF(0, 150); |
sticky_position.scroll_container_relative_sticky_box_rect = |
- gfx::Rect(0, 150, 10, 10); |
+ gfx::RectF(0, 150, 10, 10); |
sticky_position.scroll_container_relative_containing_block_rect = |
- gfx::Rect(0, 100, 50, 50); |
+ gfx::RectF(0, 100, 50, 50); |
sticky_pos->SetStickyPositionConstraint(sticky_position); |
root->SetBounds(gfx::Size(100, 100)); |
@@ -7347,11 +7350,11 @@ TEST_F(LayerTreeHostCommonTest, StickyPositionBottomInnerViewportDelta) { |
sticky_position.is_sticky = true; |
sticky_position.is_anchored_bottom = true; |
sticky_position.bottom_offset = 10.0f; |
- sticky_position.parent_relative_sticky_box_offset = gfx::Point(0, 70); |
+ sticky_position.parent_relative_sticky_box_offset = gfx::PointF(0, 70); |
sticky_position.scroll_container_relative_sticky_box_rect = |
- gfx::Rect(0, 70, 10, 10); |
+ gfx::RectF(0, 70, 10, 10); |
sticky_position.scroll_container_relative_containing_block_rect = |
- gfx::Rect(0, 60, 100, 100); |
+ gfx::RectF(0, 60, 100, 100); |
sticky_pos->SetStickyPositionConstraint(sticky_position); |
root->SetBounds(gfx::Size(100, 100)); |
@@ -7420,11 +7423,11 @@ TEST_F(LayerTreeHostCommonTest, StickyPositionBottomOuterViewportDelta) { |
sticky_position.is_sticky = true; |
sticky_position.is_anchored_bottom = true; |
sticky_position.bottom_offset = 10.0f; |
- sticky_position.parent_relative_sticky_box_offset = gfx::Point(0, 70); |
+ sticky_position.parent_relative_sticky_box_offset = gfx::PointF(0, 70); |
sticky_position.scroll_container_relative_sticky_box_rect = |
- gfx::Rect(0, 70, 10, 10); |
+ gfx::RectF(0, 70, 10, 10); |
sticky_position.scroll_container_relative_containing_block_rect = |
- gfx::Rect(0, 60, 100, 100); |
+ gfx::RectF(0, 60, 100, 100); |
sticky_pos->SetStickyPositionConstraint(sticky_position); |
root->SetBounds(gfx::Size(100, 100)); |
@@ -7497,11 +7500,11 @@ TEST_F(LayerTreeHostCommonTest, StickyPositionLeftRight) { |
sticky_position.is_anchored_right = true; |
sticky_position.left_offset = 10.f; |
sticky_position.right_offset = 10.f; |
- sticky_position.parent_relative_sticky_box_offset = gfx::Point(145, 0); |
+ sticky_position.parent_relative_sticky_box_offset = gfx::PointF(145, 0); |
sticky_position.scroll_container_relative_sticky_box_rect = |
- gfx::Rect(145, 0, 10, 10); |
+ gfx::RectF(145, 0, 10, 10); |
sticky_position.scroll_container_relative_containing_block_rect = |
- gfx::Rect(100, 0, 100, 100); |
+ gfx::RectF(100, 0, 100, 100); |
sticky_pos->SetStickyPositionConstraint(sticky_position); |
root->SetBounds(gfx::Size(100, 100)); |
@@ -7600,11 +7603,11 @@ TEST_F(LayerTreeHostCommonTest, StickyPositionMainThreadUpdates) { |
sticky_position.is_sticky = true; |
sticky_position.is_anchored_top = true; |
sticky_position.top_offset = 10.0f; |
- sticky_position.parent_relative_sticky_box_offset = gfx::Point(10, 20); |
+ sticky_position.parent_relative_sticky_box_offset = gfx::PointF(10, 20); |
sticky_position.scroll_container_relative_sticky_box_rect = |
- gfx::Rect(10, 20, 10, 10); |
+ gfx::RectF(10, 20, 10, 10); |
sticky_position.scroll_container_relative_containing_block_rect = |
- gfx::Rect(0, 0, 50, 50); |
+ gfx::RectF(0, 0, 50, 50); |
sticky_pos->SetStickyPositionConstraint(sticky_position); |
root->SetBounds(gfx::Size(100, 100)); |
@@ -7695,11 +7698,11 @@ TEST_F(LayerTreeHostCommonTest, StickyPositionCompositedContainer) { |
// The sticky position layer is only offset by (0, 10) from its parent |
// layer, this position is used to determine the offset applied by the main |
// thread. |
- sticky_position.parent_relative_sticky_box_offset = gfx::Point(0, 10); |
+ sticky_position.parent_relative_sticky_box_offset = gfx::PointF(0, 10); |
sticky_position.scroll_container_relative_sticky_box_rect = |
- gfx::Rect(20, 30, 10, 10); |
+ gfx::RectF(20, 30, 10, 10); |
sticky_position.scroll_container_relative_containing_block_rect = |
- gfx::Rect(20, 20, 30, 30); |
+ gfx::RectF(20, 20, 30, 30); |
sticky_pos->SetStickyPositionConstraint(sticky_position); |
root->SetBounds(gfx::Size(100, 100)); |
@@ -7795,11 +7798,11 @@ TEST_F(LayerTreeHostCommonTest, StickyPositionScaledStickyBox) { |
sticky_position.is_sticky = true; |
sticky_position.is_anchored_top = true; |
sticky_position.top_offset = 0.0f; |
- sticky_position.parent_relative_sticky_box_offset = gfx::Point(0, 20); |
+ sticky_position.parent_relative_sticky_box_offset = gfx::PointF(0, 20); |
sticky_position.scroll_container_relative_sticky_box_rect = |
- gfx::Rect(0, 20, 10, 10); |
+ gfx::RectF(0, 20, 10, 10); |
sticky_position.scroll_container_relative_containing_block_rect = |
- gfx::Rect(0, 0, 50, 50); |
+ gfx::RectF(0, 0, 50, 50); |
sticky_pos->SetStickyPositionConstraint(sticky_position); |
root->SetBounds(gfx::Size(100, 100)); |
@@ -7874,11 +7877,11 @@ TEST_F(LayerTreeHostCommonTest, StickyPositionScaledContainer) { |
sticky_position.is_sticky = true; |
sticky_position.is_anchored_top = true; |
sticky_position.top_offset = 0.0f; |
- sticky_position.parent_relative_sticky_box_offset = gfx::Point(0, 20); |
+ sticky_position.parent_relative_sticky_box_offset = gfx::PointF(0, 20); |
sticky_position.scroll_container_relative_sticky_box_rect = |
- gfx::Rect(0, 20, 10, 10); |
+ gfx::RectF(0, 20, 10, 10); |
sticky_position.scroll_container_relative_containing_block_rect = |
- gfx::Rect(0, 0, 50, 50); |
+ gfx::RectF(0, 0, 50, 50); |
sticky_pos->SetStickyPositionConstraint(sticky_position); |
root->SetBounds(gfx::Size(100, 100)); |
@@ -7932,6 +7935,106 @@ TEST_F(LayerTreeHostCommonTest, StickyPositionScaledContainer) { |
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(); |
+ |
+ root->AddChild(container); |
+ container->AddChild(scroller); |
+ scroller->AddChild(outer_sticky); |
+ outer_sticky->AddChild(inner_sticky); |
+ host()->SetRootLayer(root); |
+ scroller->SetScrollClipLayerId(container->id()); |
+ |
+ root->SetBounds(gfx::Size(100, 100)); |
+ container->SetBounds(gfx::Size(100, 100)); |
+ scroller->SetBounds(gfx::Size(100, 1000)); |
+ 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; |
+ outer_sticky_pos.is_anchored_top = true; |
+ outer_sticky_pos.top_offset = 10.0f; |
+ outer_sticky_pos.parent_relative_sticky_box_offset = gfx::PointF(0, 50); |
+ outer_sticky_pos.scroll_container_relative_sticky_box_rect = |
+ gfx::RectF(0, 50, 10, 50); |
+ outer_sticky_pos.scroll_container_relative_containing_block_rect = |
+ gfx::RectF(0, 0, 50, 400); |
+ outer_sticky->SetStickyPositionConstraint(outer_sticky_pos); |
+ |
+ LayerStickyPositionConstraint inner_sticky_pos; |
+ inner_sticky_pos.is_sticky = true; |
+ inner_sticky_pos.is_anchored_top = true; |
+ inner_sticky_pos.top_offset = 25.0f; |
+ inner_sticky_pos.parent_relative_sticky_box_offset = gfx::PointF(0, 0); |
+ inner_sticky_pos.scroll_container_relative_sticky_box_rect = |
+ gfx::RectF(0, 50, 10, 10); |
+ inner_sticky_pos.scroll_container_relative_containing_block_rect = |
+ gfx::RectF(0, 50, 10, 50); |
+ inner_sticky_pos.nearest_layer_shifting_containing_block = outer_sticky->id(); |
+ inner_sticky->SetStickyPositionConstraint(inner_sticky_pos); |
+ |
+ 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* outer_sticky_impl = layer_tree_impl->LayerById(outer_sticky->id()); |
+ 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( |
+ gfx::Vector2dF(0.f, 50.f), |
+ outer_sticky_impl->ScreenSpaceTransform().To2dTranslation()); |
+ EXPECT_VECTOR2DF_EQ( |
+ gfx::Vector2dF(0.f, 50.f), |
+ inner_sticky_impl->ScreenSpaceTransform().To2dTranslation()); |
+ |
+ // 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); |
+ EXPECT_VECTOR2DF_EQ( |
+ gfx::Vector2dF(0.f, 45.f), |
+ outer_sticky_impl->ScreenSpaceTransform().To2dTranslation()); |
+ EXPECT_VECTOR2DF_EQ( |
+ gfx::Vector2dF(0.f, 45.f), |
+ inner_sticky_impl->ScreenSpaceTransform().To2dTranslation()); |
+ |
+ // 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); |
+ EXPECT_VECTOR2DF_EQ( |
+ gfx::Vector2dF(0.f, 20.f), |
+ outer_sticky_impl->ScreenSpaceTransform().To2dTranslation()); |
+ EXPECT_VECTOR2DF_EQ( |
+ gfx::Vector2dF(0.f, 25.f), |
+ inner_sticky_impl->ScreenSpaceTransform().To2dTranslation()); |
+ |
+ // Keep going, both should stick. |
+ 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()); |
+ EXPECT_VECTOR2DF_EQ( |
+ gfx::Vector2dF(0.f, 25.f), |
+ inner_sticky_impl->ScreenSpaceTransform().To2dTranslation()); |
+} |
+ |
TEST_F(LayerTreeHostCommonTest, NonFlatContainerForFixedPosLayer) { |
scoped_refptr<Layer> root = Layer::Create(); |
scoped_refptr<Layer> container = Layer::Create(); |