Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3008)

Unified Diff: cc/trees/layer_tree_host_common_unittest.cc

Issue 2733633002: Handle nested position:sticky elements correctly (compositor) (Closed)
Patch Set: More layer id fixes Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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 ed9c242b68386d43fd351d9226f4b8c73677186b..1924e964a4ce535d01755ad98d562b64069b3444 100644
--- a/cc/trees/layer_tree_host_common_unittest.cc
+++ b/cc/trees/layer_tree_host_common_unittest.cc
@@ -7074,11 +7074,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));
@@ -7143,15 +7143,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));
@@ -7220,11 +7223,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));
@@ -7266,11 +7269,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));
@@ -7335,11 +7338,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));
@@ -7408,11 +7411,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));
@@ -7485,11 +7488,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));
@@ -7588,11 +7591,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));
@@ -7683,11 +7686,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));
@@ -7783,11 +7786,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));
@@ -7862,11 +7865,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));
@@ -7920,6 +7923,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 hasnt reached its position yet.
ajuma 2017/03/17 23:59:52 hasn't
smcgruer 2017/03/20 13:36:29 Done.
+ 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();

Powered by Google App Engine
This is Rietveld 408576698