Commit 08436a6b authored by David Bokan's avatar David Bokan Committed by Commit Bot

Convert sticky to layout units

Sticky constraints should use layout units like the rest of the layout
system. They should only be converted to float when passed to the
compositor.

Bug: 882075,1010961a
Change-Id: I34f54702c0918238171981fcd97a621dbe9bbdef
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1943339
Commit-Queue: David Bokan <bokan@chromium.org>
Auto-Submit: David Bokan <bokan@chromium.org>
Reviewed-by: default avatarXianzhu Wang <wangxianzhu@chromium.org>
Cr-Commit-Position: refs/heads/master@{#720336}
parent 5a4bbf1a
...@@ -144,7 +144,7 @@ class CORE_EXPORT LayoutBoxModelObject : public LayoutObject { ...@@ -144,7 +144,7 @@ class CORE_EXPORT LayoutBoxModelObject : public LayoutObject {
// Populates StickyPositionConstraints, setting the sticky box rect, // Populates StickyPositionConstraints, setting the sticky box rect,
// containing block rect and updating the constraint offsets according to the // containing block rect and updating the constraint offsets according to the
// available space. // available space.
FloatRect ComputeStickyConstrainingRect() const; PhysicalRect ComputeStickyConstrainingRect() const;
void UpdateStickyPositionConstraints() const; void UpdateStickyPositionConstraints() const;
PhysicalOffset StickyPositionOffset() const; PhysicalOffset StickyPositionOffset() const;
bool IsSlowRepaintConstrainedObject() const; bool IsSlowRepaintConstrainedObject() const;
......
...@@ -421,8 +421,7 @@ TEST_F(LayoutBoxModelObjectTest, StickyPositionConstraintInvalidation) { ...@@ -421,8 +421,7 @@ TEST_F(LayoutBoxModelObjectTest, StickyPositionConstraintInvalidation) {
scrollable_area->GetStickyConstraintsMap().Contains(sticky->Layer())); scrollable_area->GetStickyConstraintsMap().Contains(sticky->Layer()));
EXPECT_EQ(25.f, scrollable_area->GetStickyConstraintsMap() EXPECT_EQ(25.f, scrollable_area->GetStickyConstraintsMap()
.at(sticky->Layer()) .at(sticky->Layer())
.scroll_container_relative_sticky_box_rect.Location() .scroll_container_relative_sticky_box_rect.X());
.X());
To<HTMLElement>(target->GetNode())->classList().Add("hide"); To<HTMLElement>(target->GetNode())->classList().Add("hide");
GetDocument().View()->UpdateLifecycleToLayoutClean(); GetDocument().View()->UpdateLifecycleToLayoutClean();
// Layout should invalidate the sticky constraints of the sticky element and // Layout should invalidate the sticky constraints of the sticky element and
...@@ -435,8 +434,7 @@ TEST_F(LayoutBoxModelObjectTest, StickyPositionConstraintInvalidation) { ...@@ -435,8 +434,7 @@ TEST_F(LayoutBoxModelObjectTest, StickyPositionConstraintInvalidation) {
UpdateAllLifecyclePhasesForTest(); UpdateAllLifecyclePhasesForTest();
EXPECT_EQ(50.f, scrollable_area->GetStickyConstraintsMap() EXPECT_EQ(50.f, scrollable_area->GetStickyConstraintsMap()
.at(sticky->Layer()) .at(sticky->Layer())
.scroll_container_relative_sticky_box_rect.Location() .scroll_container_relative_sticky_box_rect.X());
.X());
} }
// Verifies that the correct sticky-box shifting ancestor is found when // Verifies that the correct sticky-box shifting ancestor is found when
......
...@@ -4,18 +4,19 @@ ...@@ -4,18 +4,19 @@
#include "third_party/blink/renderer/core/page/scrolling/sticky_position_scrolling_constraints.h" #include "third_party/blink/renderer/core/page/scrolling/sticky_position_scrolling_constraints.h"
#include "third_party/blink/renderer/core/paint/paint_layer.h" #include "third_party/blink/renderer/core/paint/paint_layer.h"
#include "third_party/blink/renderer/platform/geometry/layout_unit.h"
namespace blink { namespace blink {
FloatSize StickyPositionScrollingConstraints::ComputeStickyOffset( PhysicalOffset StickyPositionScrollingConstraints::ComputeStickyOffset(
const FloatRect& content_box_rect, const PhysicalRect& content_box_rect,
const StickyConstraintsMap& constraints_map) { const StickyConstraintsMap& constraints_map) {
FloatRect sticky_box_rect = scroll_container_relative_sticky_box_rect; PhysicalRect sticky_box_rect = scroll_container_relative_sticky_box_rect;
FloatRect containing_block_rect = PhysicalRect containing_block_rect =
scroll_container_relative_containing_block_rect; scroll_container_relative_containing_block_rect;
FloatSize ancestor_sticky_box_offset = PhysicalOffset ancestor_sticky_box_offset =
AncestorStickyBoxOffset(constraints_map); AncestorStickyBoxOffset(constraints_map);
FloatSize ancestor_containing_block_offset = PhysicalOffset ancestor_containing_block_offset =
AncestorContainingBlockOffset(constraints_map); AncestorContainingBlockOffset(constraints_map);
// Adjust the cached rect locations for any sticky ancestor elements. The // Adjust the cached rect locations for any sticky ancestor elements. The
...@@ -41,55 +42,69 @@ FloatSize StickyPositionScrollingConstraints::ComputeStickyOffset( ...@@ -41,55 +42,69 @@ FloatSize StickyPositionScrollingConstraints::ComputeStickyOffset(
// shifting produces the final sticky offset below. // shifting produces the final sticky offset below.
// //
// As per the spec, 'left' overrides 'right' and 'top' overrides 'bottom'. // As per the spec, 'left' overrides 'right' and 'top' overrides 'bottom'.
FloatRect box_rect = sticky_box_rect; PhysicalRect box_rect = sticky_box_rect;
if (is_anchored_right) { if (is_anchored_right) {
float right_limit = content_box_rect.MaxX() - right_offset; LayoutUnit right_limit = content_box_rect.Right() - right_offset;
float right_delta = LayoutUnit right_delta = right_limit - sticky_box_rect.Right();
std::min<float>(0, right_limit - sticky_box_rect.MaxX()); LayoutUnit available_space =
float available_space = containing_block_rect.X() - sticky_box_rect.X();
std::min<float>(0, containing_block_rect.X() - sticky_box_rect.X());
right_delta = right_delta.ClampPositiveToZero();
available_space = available_space.ClampPositiveToZero();
if (right_delta < available_space) if (right_delta < available_space)
right_delta = available_space; right_delta = available_space;
box_rect.Move(right_delta, 0); box_rect.Move(PhysicalOffset(right_delta, LayoutUnit()));
} }
if (is_anchored_left) { if (is_anchored_left) {
float left_limit = content_box_rect.X() + left_offset; LayoutUnit left_limit = content_box_rect.X() + left_offset;
float left_delta = std::max<float>(0, left_limit - sticky_box_rect.X()); LayoutUnit left_delta = left_limit - sticky_box_rect.X();
float available_space = std::max<float>( LayoutUnit available_space =
0, containing_block_rect.MaxX() - sticky_box_rect.MaxX()); containing_block_rect.Right() - sticky_box_rect.Right();
left_delta = left_delta.ClampNegativeToZero();
available_space = available_space.ClampNegativeToZero();
if (left_delta > available_space) if (left_delta > available_space)
left_delta = available_space; left_delta = available_space;
box_rect.Move(left_delta, 0); box_rect.Move(PhysicalOffset(left_delta, LayoutUnit()));
} }
if (is_anchored_bottom) { if (is_anchored_bottom) {
float bottom_limit = content_box_rect.MaxY() - bottom_offset; LayoutUnit bottom_limit = content_box_rect.Bottom() - bottom_offset;
float bottom_delta = LayoutUnit bottom_delta = bottom_limit - sticky_box_rect.Bottom();
std::min<float>(0, bottom_limit - sticky_box_rect.MaxY()); LayoutUnit available_space =
float available_space = containing_block_rect.Y() - sticky_box_rect.Y();
std::min<float>(0, containing_block_rect.Y() - sticky_box_rect.Y());
bottom_delta = bottom_delta.ClampPositiveToZero();
available_space = available_space.ClampPositiveToZero();
if (bottom_delta < available_space) if (bottom_delta < available_space)
bottom_delta = available_space; bottom_delta = available_space;
box_rect.Move(0, bottom_delta); box_rect.Move(PhysicalOffset(LayoutUnit(), bottom_delta));
} }
if (is_anchored_top) { if (is_anchored_top) {
float top_limit = content_box_rect.Y() + top_offset; LayoutUnit top_limit = content_box_rect.Y() + top_offset;
float top_delta = std::max<float>(0, top_limit - sticky_box_rect.Y()); LayoutUnit top_delta = top_limit - sticky_box_rect.Y();
float available_space = std::max<float>( LayoutUnit available_space =
0, containing_block_rect.MaxY() - sticky_box_rect.MaxY()); containing_block_rect.Bottom() - sticky_box_rect.Bottom();
top_delta = top_delta.ClampNegativeToZero();
available_space = available_space.ClampNegativeToZero();
if (top_delta > available_space) if (top_delta > available_space)
top_delta = available_space; top_delta = available_space;
box_rect.Move(0, top_delta); box_rect.Move(PhysicalOffset(LayoutUnit(), top_delta));
} }
FloatSize sticky_offset = box_rect.Location() - sticky_box_rect.Location(); PhysicalOffset sticky_offset = box_rect.offset - sticky_box_rect.offset;
// Now that we have computed our current sticky offset, update the cached // Now that we have computed our current sticky offset, update the cached
// accumulated sticky offsets. // accumulated sticky offsets.
...@@ -101,25 +116,26 @@ FloatSize StickyPositionScrollingConstraints::ComputeStickyOffset( ...@@ -101,25 +116,26 @@ FloatSize StickyPositionScrollingConstraints::ComputeStickyOffset(
return sticky_offset; return sticky_offset;
} }
FloatSize StickyPositionScrollingConstraints::GetOffsetForStickyPosition( PhysicalOffset StickyPositionScrollingConstraints::GetOffsetForStickyPosition(
const StickyConstraintsMap& constraints_map) const { const StickyConstraintsMap& constraints_map) const {
return total_sticky_box_sticky_offset - return total_sticky_box_sticky_offset -
AncestorStickyBoxOffset(constraints_map); AncestorStickyBoxOffset(constraints_map);
} }
FloatSize StickyPositionScrollingConstraints::AncestorStickyBoxOffset( PhysicalOffset StickyPositionScrollingConstraints::AncestorStickyBoxOffset(
const StickyConstraintsMap& constraints_map) const { const StickyConstraintsMap& constraints_map) const {
if (!nearest_sticky_layer_shifting_sticky_box) if (!nearest_sticky_layer_shifting_sticky_box)
return FloatSize(); return PhysicalOffset();
DCHECK(constraints_map.Contains(nearest_sticky_layer_shifting_sticky_box)); DCHECK(constraints_map.Contains(nearest_sticky_layer_shifting_sticky_box));
return constraints_map.at(nearest_sticky_layer_shifting_sticky_box) return constraints_map.at(nearest_sticky_layer_shifting_sticky_box)
.total_sticky_box_sticky_offset; .total_sticky_box_sticky_offset;
} }
FloatSize StickyPositionScrollingConstraints::AncestorContainingBlockOffset( PhysicalOffset
StickyPositionScrollingConstraints::AncestorContainingBlockOffset(
const StickyConstraintsMap& constraints_map) const { const StickyConstraintsMap& constraints_map) const {
if (!nearest_sticky_layer_shifting_containing_block) { if (!nearest_sticky_layer_shifting_containing_block) {
return FloatSize(); return PhysicalOffset();
} }
DCHECK( DCHECK(
constraints_map.Contains(nearest_sticky_layer_shifting_containing_block)); constraints_map.Contains(nearest_sticky_layer_shifting_containing_block));
......
...@@ -5,8 +5,8 @@ ...@@ -5,8 +5,8 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_PAGE_SCROLLING_STICKY_POSITION_SCROLLING_CONSTRAINTS_H_ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_PAGE_SCROLLING_STICKY_POSITION_SCROLLING_CONSTRAINTS_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_PAGE_SCROLLING_STICKY_POSITION_SCROLLING_CONSTRAINTS_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_PAGE_SCROLLING_STICKY_POSITION_SCROLLING_CONSTRAINTS_H_
#include "third_party/blink/renderer/platform/geometry/float_rect.h" #include "third_party/blink/renderer/core/layout/geometry/physical_rect.h"
#include "third_party/blink/renderer/platform/geometry/float_size.h" #include "third_party/blink/renderer/platform/geometry/layout_unit.h"
#include "third_party/blink/renderer/platform/wtf/hash_map.h" #include "third_party/blink/renderer/platform/wtf/hash_map.h"
namespace blink { namespace blink {
...@@ -85,8 +85,8 @@ struct StickyPositionScrollingConstraints final { ...@@ -85,8 +85,8 @@ struct StickyPositionScrollingConstraints final {
// //
// This method is non-const as we cache internal state for performance; see // This method is non-const as we cache internal state for performance; see
// documentation in the implementation for details. // documentation in the implementation for details.
FloatSize ComputeStickyOffset(const FloatRect& content_box_rect, PhysicalOffset ComputeStickyOffset(const PhysicalRect& content_box_rect,
const StickyConstraintsMap&); const StickyConstraintsMap&);
// Returns the last-computed offset of the sticky box from its original // Returns the last-computed offset of the sticky box from its original
// position before scroll. // position before scroll.
...@@ -94,17 +94,17 @@ struct StickyPositionScrollingConstraints final { ...@@ -94,17 +94,17 @@ struct StickyPositionScrollingConstraints final {
// This method exists for performance (to avoid recomputing the sticky offset) // This method exists for performance (to avoid recomputing the sticky offset)
// and must only be called when compositing inputs are clean for the sticky // and must only be called when compositing inputs are clean for the sticky
// element. (Or after prepaint for CompositeAfterPaint). // element. (Or after prepaint for CompositeAfterPaint).
FloatSize GetOffsetForStickyPosition(const StickyConstraintsMap&) const; PhysicalOffset GetOffsetForStickyPosition(const StickyConstraintsMap&) const;
bool is_anchored_left : 1; bool is_anchored_left : 1;
bool is_anchored_right : 1; bool is_anchored_right : 1;
bool is_anchored_top : 1; bool is_anchored_top : 1;
bool is_anchored_bottom : 1; bool is_anchored_bottom : 1;
float left_offset = 0.f; LayoutUnit left_offset;
float right_offset = 0.f; LayoutUnit right_offset;
float top_offset = 0.f; LayoutUnit top_offset;
float bottom_offset = 0.f; LayoutUnit bottom_offset;
// The containing block rect and sticky box rect are the basic components // The containing block rect and sticky box rect are the basic components
// for calculating the sticky offset to apply after a scroll. Consider the // for calculating the sticky offset to apply after a scroll. Consider the
...@@ -119,12 +119,12 @@ struct StickyPositionScrollingConstraints final { ...@@ -119,12 +119,12 @@ struct StickyPositionScrollingConstraints final {
// The layout position of the containing block relative to the scroll // The layout position of the containing block relative to the scroll
// container. When calculating the sticky offset it is used to ensure the // container. When calculating the sticky offset it is used to ensure the
// sticky element stays bounded by its containing block. // sticky element stays bounded by its containing block.
FloatRect scroll_container_relative_containing_block_rect; PhysicalRect scroll_container_relative_containing_block_rect;
// The layout position of the sticky element relative to the scroll container. // The layout position of the sticky element relative to the scroll container.
// When calculating the sticky offset it is used to determine how large the // When calculating the sticky offset it is used to determine how large the
// offset needs to be to satisfy the sticky constraints. // offset needs to be to satisfy the sticky constraints.
FloatRect scroll_container_relative_sticky_box_rect; PhysicalRect scroll_container_relative_sticky_box_rect;
// In the case of nested sticky elements the layout position of the sticky // In the case of nested sticky elements the layout position of the sticky
// element and its containing block are not accurate (as they are affected by // element and its containing block are not accurate (as they are affected by
...@@ -158,16 +158,17 @@ struct StickyPositionScrollingConstraints final { ...@@ -158,16 +158,17 @@ struct StickyPositionScrollingConstraints final {
// //
// In the above example, both outerInline and innerInline have the same // In the above example, both outerInline and innerInline have the same
// containing block - the outermost <div>. // containing block - the outermost <div>.
FloatSize total_sticky_box_sticky_offset; PhysicalOffset total_sticky_box_sticky_offset;
// The containing block offset accumulates all sticky-related offsets between // The containing block offset accumulates all sticky-related offsets between
// this element and the ancestor scroller. If this element is a containing // this element and the ancestor scroller. If this element is a containing
// block shifting ancestor for some descendant, it shifts the descendant's // block shifting ancestor for some descendant, it shifts the descendant's
// constraint rects by its entire offset. // constraint rects by its entire offset.
FloatSize total_containing_block_sticky_offset; PhysicalOffset total_containing_block_sticky_offset;
FloatSize AncestorStickyBoxOffset(const StickyConstraintsMap&) const; PhysicalOffset AncestorStickyBoxOffset(const StickyConstraintsMap&) const;
FloatSize AncestorContainingBlockOffset(const StickyConstraintsMap&) const; PhysicalOffset AncestorContainingBlockOffset(
const StickyConstraintsMap&) const;
}; };
} // namespace blink } // namespace blink
......
...@@ -560,17 +560,19 @@ void FragmentPaintPropertyTreeBuilder::UpdateStickyTranslation() { ...@@ -560,17 +560,19 @@ void FragmentPaintPropertyTreeBuilder::UpdateStickyTranslation() {
constraint->is_anchored_right = layout_constraint.is_anchored_right; constraint->is_anchored_right = layout_constraint.is_anchored_right;
constraint->is_anchored_top = layout_constraint.is_anchored_top; constraint->is_anchored_top = layout_constraint.is_anchored_top;
constraint->is_anchored_bottom = layout_constraint.is_anchored_bottom; constraint->is_anchored_bottom = layout_constraint.is_anchored_bottom;
constraint->left_offset = layout_constraint.left_offset; constraint->left_offset = layout_constraint.left_offset.ToFloat();
constraint->right_offset = layout_constraint.right_offset; constraint->right_offset = layout_constraint.right_offset.ToFloat();
constraint->top_offset = layout_constraint.top_offset; constraint->top_offset = layout_constraint.top_offset.ToFloat();
constraint->bottom_offset = layout_constraint.bottom_offset; constraint->bottom_offset = layout_constraint.bottom_offset.ToFloat();
constraint->constraint_box_rect = constraint->constraint_box_rect =
RoundedIntRect(box_model.ComputeStickyConstrainingRect()); PixelSnappedIntRect(box_model.ComputeStickyConstrainingRect());
constraint->scroll_container_relative_sticky_box_rect = RoundedIntRect( constraint->scroll_container_relative_sticky_box_rect =
layout_constraint.scroll_container_relative_sticky_box_rect); PixelSnappedIntRect(
constraint layout_constraint.scroll_container_relative_sticky_box_rect);
->scroll_container_relative_containing_block_rect = RoundedIntRect( constraint->scroll_container_relative_containing_block_rect =
layout_constraint.scroll_container_relative_containing_block_rect); PixelSnappedIntRect(
layout_constraint
.scroll_container_relative_containing_block_rect);
if (PaintLayer* sticky_box_shifting_ancestor = if (PaintLayer* sticky_box_shifting_ancestor =
layout_constraint.nearest_sticky_layer_shifting_sticky_box) { layout_constraint.nearest_sticky_layer_shifting_sticky_box) {
constraint->nearest_element_shifting_sticky_box = constraint->nearest_element_shifting_sticky_box =
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment