Commit 851414c6 authored by Stefan Zager's avatar Stefan Zager Committed by Commit Bot

[RootLayerScrolling] Fix position:sticky

If there are any non-composited position:sticky objects that stick
to the root layer, then we must force main thread scrolling to
prevent an "over-scrolling" effect.

BUG=711468
R=skobes@chromium.org,pdr@chromium.org,bokan@chromium.org

Cq-Include-Trybots: master.tryserver.chromium.linux:linux_layout_tests_slimming_paint_v2;master.tryserver.chromium.linux:linux_layout_tests_root_layer_scrolls
Change-Id: I4c36eaf118b8d4d0078c4d5c5e8b633eb71fe733
Reviewed-on: https://chromium-review.googlesource.com/797221
Commit-Queue: Stefan Zager <szager@chromium.org>
Reviewed-by: default avatarRobert Flack <flackr@chromium.org>
Reviewed-by: default avatarSteve Kobes <skobes@chromium.org>
Reviewed-by: default avatarPhilip Rogers <pdr@chromium.org>
Cr-Commit-Position: refs/heads/master@{#520807}
parent ddc8598e
......@@ -4,9 +4,6 @@ crbug.com/417782 compositing/squashing/dont-squash-into-videos.html [ Failure ]
crbug.com/417782 compositing/squashing/squash-above-fixed-1.html [ Failure ]
crbug.com/417782 compositing/squashing/squash-above-fixed-3.html [ Failure ]
crbug.com/417782 compositing/visibility/visibility-image-layers-dynamic.html [ Failure ]
crbug.com/417782 external/wpt/css/css-position/position-sticky-root-scroller.html [ Failure ]
crbug.com/417782 fast/css/sticky/replaced-sticky.html [ Failure ]
crbug.com/417782 fast/css/sticky/sticky-style-change.html [ Failure ]
crbug.com/417782 fast/dom/Window/window-xy-properties.html [ Failure ]
crbug.com/417782 [ Linux Mac ] fast/dom/horizontal-scrollbar-when-dir-change.html [ Failure ]
crbug.com/417782 fast/dom/rtl-scroll-to-leftmost-and-resize.html [ Failure ]
......
......@@ -5446,32 +5446,11 @@ int LocalFrameView::InitialViewportHeight() const {
bool LocalFrameView::HasVisibleSlowRepaintViewportConstrainedObjects() const {
if (!ViewportConstrainedObjects())
return false;
for (const LayoutObject* layout_object : *ViewportConstrainedObjects()) {
DCHECK(layout_object->IsBoxModelObject() && layout_object->HasLayer());
DCHECK(layout_object->Style()->GetPosition() == EPosition::kFixed ||
layout_object->Style()->GetPosition() == EPosition::kSticky);
PaintLayer* layer = ToLayoutBoxModelObject(layout_object)->Layer();
// Whether the Layer sticks to the viewport is a tree-depenent
// property and our viewportConstrainedObjects collection is maintained
// with only LayoutObject-level information.
if (!layer->FixedToViewport() && !layer->SticksToScroller())
continue;
// If the whole subtree is invisible, there's no reason to scroll on
// the main thread because we don't need to generate invalidations
// for invisible content.
if (layer->SubtreeIsInvisible())
continue;
// We're only smart enough to scroll viewport-constrainted objects
// in the compositor if they have their own backing or they paint
// into a grouped back (which necessarily all have the same viewport
// constraints).
CompositingState compositing_state = layer->GetCompositingState();
if (compositing_state != kPaintsIntoOwnBacking &&
compositing_state != kPaintsIntoGroupedBacking)
if (ToLayoutBoxModelObject(layout_object)->IsSlowRepaintConstrainedObject())
return true;
}
return false;
......
......@@ -843,7 +843,8 @@ void LayoutBoxModelObject::UpdateStickyPositionConstraints() const {
.BoundingBox()
.Location());
LayoutBox* scroll_ancestor =
Layer()->AncestorOverflowLayer()->IsRootLayer()
Layer()->AncestorOverflowLayer()->IsRootLayer() &&
!RuntimeEnabledFeatures::RootLayerScrollingEnabled()
? nullptr
: &ToLayoutBox(Layer()->AncestorOverflowLayer()->GetLayoutObject());
......@@ -1022,9 +1023,40 @@ void LayoutBoxModelObject::UpdateStickyPositionConstraints() const {
scrollable_area->GetStickyConstraintsMap().Set(Layer(), constraints);
}
bool LayoutBoxModelObject::IsSlowRepaintConstrainedObject() const {
if (!HasLayer() || (Style()->GetPosition() != EPosition::kFixed &&
Style()->GetPosition() != EPosition::kSticky)) {
return false;
}
PaintLayer* layer = Layer();
// Whether the Layer sticks to the viewport is a tree-depenent
// property and our viewportConstrainedObjects collection is maintained
// with only LayoutObject-level information.
if (!layer->FixedToViewport() && !layer->SticksToScroller())
return false;
// If the whole subtree is invisible, there's no reason to scroll on
// the main thread because we don't need to generate invalidations
// for invisible content.
if (layer->SubtreeIsInvisible())
return false;
// We're only smart enough to scroll viewport-constrainted objects
// in the compositor if they have their own backing or they paint
// into a grouped back (which necessarily all have the same viewport
// constraints).
return (layer->GetCompositingState() == kNotComposited);
}
FloatRect LayoutBoxModelObject::ComputeStickyConstrainingRect() const {
if (Layer()->AncestorOverflowLayer()->IsRootLayer())
return View()->GetFrameView()->VisibleContentRect();
if (Layer()->AncestorOverflowLayer()->IsRootLayer()) {
return View()
->GetFrameView()
->LayoutViewportScrollableArea()
->VisibleContentRect();
}
LayoutBox* enclosing_clipping_box =
Layer()->AncestorOverflowLayer()->GetLayoutBox();
......
......@@ -145,6 +145,7 @@ class CORE_EXPORT LayoutBoxModelObject : public LayoutObject {
FloatRect ComputeStickyConstrainingRect() const;
void UpdateStickyPositionConstraints() const;
LayoutSize StickyPositionOffset() const;
bool IsSlowRepaintConstrainedObject() const;
LayoutSize OffsetForInFlowPosition() const;
......
......@@ -548,6 +548,7 @@ void PaintLayerScrollableArea::InvalidatePaintForScrollOffsetChange(
if (!frame_view->InvalidateViewportConstrainedObjects())
requires_paint_invalidation = true;
}
InvalidatePaintForStickyDescendants();
}
if (requires_paint_invalidation)
......@@ -1737,6 +1738,25 @@ void PaintLayerScrollableArea::InvalidateStickyConstraintsFor(
}
}
bool PaintLayerScrollableArea::HasNonCompositedStickyDescendants() const {
if (const PaintLayerScrollableAreaRareData* d = RareData()) {
for (const PaintLayer* sticky_layer : d->sticky_constraints_map_.Keys()) {
if (sticky_layer->GetLayoutObject().IsSlowRepaintConstrainedObject())
return true;
}
}
return false;
}
void PaintLayerScrollableArea::InvalidatePaintForStickyDescendants() {
if (PaintLayerScrollableAreaRareData* d = RareData()) {
for (PaintLayer* sticky_layer : d->sticky_constraints_map_.Keys()) {
sticky_layer->GetLayoutObject()
.SetShouldDoFullPaintInvalidationIncludingNonCompositingDescendants();
}
}
}
IntSize PaintLayerScrollableArea::OffsetFromResizeCorner(
const IntPoint& absolute_point) const {
// Currently the resize corner is either the bottom right corner or the bottom
......@@ -1981,6 +2001,8 @@ bool PaintLayerScrollableArea::ShouldScrollOnMainThread() const {
if (frame->View()->GetMainThreadScrollingReasons())
return true;
}
if (HasNonCompositedStickyDescendants())
return true;
return ScrollableArea::ShouldScrollOnMainThread();
}
......
......@@ -482,6 +482,8 @@ class CORE_EXPORT PaintLayerScrollableArea final
void InvalidateAllStickyConstraints();
void InvalidateStickyConstraintsFor(PaintLayer*,
bool needs_compositing_update = true);
void InvalidatePaintForStickyDescendants();
bool HasNonCompositedStickyDescendants() const;
uint32_t GetNonCompositedMainThreadScrollingReasons() {
return non_composited_main_thread_scrolling_reasons_;
}
......@@ -546,6 +548,9 @@ class CORE_EXPORT PaintLayerScrollableArea final
ScrollingCoordinator* GetScrollingCoordinator() const;
PaintLayerScrollableAreaRareData* RareData() { return rare_data_.get(); }
const PaintLayerScrollableAreaRareData* RareData() const {
return rare_data_.get();
}
PaintLayerScrollableAreaRareData& EnsureRareData() {
if (!rare_data_)
......
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