Commit f89757bc authored by pdr's avatar pdr Committed by Commit bot

Add position sticky main thread scrolling reason [spv2]

This patch builds on [1] and adds position: sticky main thread scrolling
reasons to the blink and cc scroll property trees. Position: sticky
disables threaded scrolling because the compositor is not yet
able to update these.

Incremental updates are not yet possible but TODOs and tests have been
updated to ensure the main thread scroll reasons are recomputed.

[1] https://crrev.com/6da0810c8c2362fc73d911750400ccd5c33cd6ca
BUG=644514
CQ_INCLUDE_TRYBOTS=master.tryserver.chromium.linux:linux_layout_tests_slimming_paint_v2

Review-Url: https://codereview.chromium.org/2353843002
Cr-Commit-Position: refs/heads/master@{#419946}
parent ca3d26dd
......@@ -358,6 +358,10 @@ void LayoutBoxModelObject::styleDidChange(StyleDifference diff, const ComputedSt
// the sticky position constraints then.
if (layer())
layer()->setNeedsCompositingInputsUpdate();
// TODO(pdr): When slimming paint v2 is enabled, we will need to
// invalidate the scroll paint property subtree for this so main
// thread scroll reasons are recomputed.
} else {
// This may get re-added to viewport constrained objects if the object went
// from sticky to fixed.
......@@ -370,6 +374,10 @@ void LayoutBoxModelObject::styleDidChange(StyleDifference diff, const ComputedSt
if (const PaintLayer* ancestorOverflowLayer = layer()->ancestorOverflowLayer())
ancestorOverflowLayer->getScrollableArea()->invalidateStickyConstraintsFor(layer());
}
// TODO(pdr): When slimming paint v2 is enabled, we will need to
// invalidate the scroll paint property subtree for this so main
// thread scroll reasons are recomputed.
}
}
......
......@@ -2752,8 +2752,12 @@ void PaintLayer::removeAncestorOverflowLayer(const PaintLayer* removedLayer)
if (ancestorOverflowLayer() && ancestorOverflowLayer() != removedLayer)
return;
if (ancestorOverflowLayer())
if (ancestorOverflowLayer()) {
// TODO(pdr): When slimming paint v2 is enabled, we will need to
// invalidate the scroll paint property subtree for this so main
// thread scroll reasons are recomputed.
ancestorOverflowLayer()->getScrollableArea()->invalidateStickyConstraintsFor(this);
}
updateAncestorOverflowLayer(nullptr);
PaintLayer* current = m_first;
while (current) {
......
......@@ -345,6 +345,13 @@ void PaintPropertyTreeBuilder::updateMainThreadScrollingReasons(const LayoutObje
scrollNode = scrollNode->parent();
}
}
if (object.styleRef().position() == StickyPosition) {
auto* scrollNode = context.current.scroll;
while (scrollNode && !scrollNode->hasMainThreadScrollingReasons(MainThreadScrollingReason::kHasStickyPositionObjects)) {
scrollNode->addMainThreadScrollingReasons(MainThreadScrollingReason::kHasStickyPositionObjects);
scrollNode = scrollNode->parent();
}
}
}
void PaintPropertyTreeBuilder::updateOverflowClip(const LayoutObject& object, PaintPropertyTreeBuilderContext& context)
......
......@@ -2038,7 +2038,7 @@ TEST_P(PaintPropertyTreeBuilderTest, ThreadedScrollingDisabledMainThreadScrollRe
EXPECT_TRUE(overflowA->layoutObject()->objectPaintProperties()->scroll()->hasMainThreadScrollingReasons(MainThreadScrollingReason::kThreadedScrollingDisabled));
}
TEST_P(PaintPropertyTreeBuilderTest, MainThreadScrollReasonsWithNestedScrollers)
TEST_P(PaintPropertyTreeBuilderTest, BackgroundAttachmentFixedMainThreadScrollReasonsWithNestedScrollers)
{
setBodyInnerHTML(
"<style>"
......@@ -2091,7 +2091,7 @@ TEST_P(PaintPropertyTreeBuilderTest, MainThreadScrollReasonsWithNestedScrollers)
EXPECT_FALSE(overflowB->layoutObject()->objectPaintProperties()->scroll()->hasMainThreadScrollingReasons(MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects));
}
TEST_P(PaintPropertyTreeBuilderTest, MainThreadScrollReasonsWithFixedScroller)
TEST_P(PaintPropertyTreeBuilderTest, BackgroundAttachmentFixedMainThreadScrollReasonsWithFixedScroller)
{
setBodyInnerHTML(
"<style>"
......@@ -2137,4 +2137,99 @@ TEST_P(PaintPropertyTreeBuilderTest, MainThreadScrollReasonsWithFixedScroller)
EXPECT_FALSE(overflowB->layoutObject()->objectPaintProperties()->scroll()->hasMainThreadScrollingReasons(MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects));
}
TEST_P(PaintPropertyTreeBuilderTest, PositionStickyMainThreadScrollReasonsWithNestedScrollers)
{
setBodyInnerHTML(
"<style>"
" #overflowA {"
" overflow: scroll;"
" width: 20px;"
" height: 20px;"
" }"
" #overflowB {"
" overflow: scroll;"
" width: 5px;"
" height: 3px;"
" }"
" .positionSticky {"
" position: sticky;"
" top: 0;"
" left: 0;"
" }"
" .forceScroll {"
" height: 4000px;"
" }"
"</style>"
"<div id='overflowA'>"
" <div id='overflowB' class='positionSticky'>"
" <div id='overflowBChild'></div>"
" <div class='forceScroll'></div>"
" </div>"
" <div class='forceScroll'></div>"
"</div>"
"<div class='forceScroll'></div>");
Element* overflowA = document().getElementById("overflowA");
Element* overflowB = document().getElementById("overflowB");
Element* overflowBChild = document().getElementById("overflowBChild");
EXPECT_TRUE(frameScroll()->hasMainThreadScrollingReasons(MainThreadScrollingReason::kHasStickyPositionObjects));
EXPECT_TRUE(overflowA->layoutObject()->objectPaintProperties()->scroll()->hasMainThreadScrollingReasons(MainThreadScrollingReason::kHasStickyPositionObjects));
EXPECT_FALSE(overflowB->layoutObject()->objectPaintProperties()->scroll()->hasMainThreadScrollingReasons(MainThreadScrollingReason::kHasStickyPositionObjects));
EXPECT_TRUE(!overflowBChild->layoutObject()->objectPaintProperties() || !overflowBChild->layoutObject()->objectPaintProperties()->scroll());
// Removing a main thread scrolling reason should update the entire tree.
overflowB->removeAttribute("class");
document().view()->updateAllLifecyclePhases();
EXPECT_FALSE(frameScroll()->hasMainThreadScrollingReasons(MainThreadScrollingReason::kHasStickyPositionObjects));
EXPECT_FALSE(overflowA->layoutObject()->objectPaintProperties()->scroll()->hasMainThreadScrollingReasons(MainThreadScrollingReason::kHasStickyPositionObjects));
EXPECT_FALSE(overflowB->layoutObject()->objectPaintProperties()->scroll()->hasMainThreadScrollingReasons(MainThreadScrollingReason::kHasStickyPositionObjects));
EXPECT_TRUE(!overflowBChild->layoutObject()->objectPaintProperties() || !overflowBChild->layoutObject()->objectPaintProperties()->scroll());
// Adding a main thread scrolling reason should update the entire tree.
overflowBChild->setAttribute(HTMLNames::classAttr, "positionSticky");
document().view()->updateAllLifecyclePhases();
EXPECT_TRUE(frameScroll()->hasMainThreadScrollingReasons(MainThreadScrollingReason::kHasStickyPositionObjects));
EXPECT_TRUE(overflowA->layoutObject()->objectPaintProperties()->scroll()->hasMainThreadScrollingReasons(MainThreadScrollingReason::kHasStickyPositionObjects));
EXPECT_TRUE(overflowB->layoutObject()->objectPaintProperties()->scroll()->hasMainThreadScrollingReasons(MainThreadScrollingReason::kHasStickyPositionObjects));
EXPECT_TRUE(!overflowBChild->layoutObject()->objectPaintProperties() || !overflowBChild->layoutObject()->objectPaintProperties()->scroll());
}
TEST_P(PaintPropertyTreeBuilderTest, MainThreadScrollReasonsWithNestedPositionStickyScrollers)
{
setBodyInnerHTML(
"<style>"
" #overflowA {"
" overflow: scroll;"
" width: 20px;"
" height: 20px;"
" }"
" #overflowB {"
" overflow: scroll;"
" width: 5px;"
" height: 3px;"
" }"
" .positionSticky {"
" position: sticky;"
" top: 0;"
" left: 0;"
" }"
" .forceScroll {"
" height: 4000px;"
" }"
"</style>"
"<div id='overflowA' class='positionSticky'>"
" <div id='overflowB'>"
" <div class='forceScroll'></div>"
" </div>"
" <div class='forceScroll'></div>"
"</div>"
"<div class='forceScroll'></div>");
Element* overflowA = document().getElementById("overflowA");
Element* overflowB = document().getElementById("overflowB");
EXPECT_TRUE(frameScroll()->hasMainThreadScrollingReasons(MainThreadScrollingReason::kHasStickyPositionObjects));
EXPECT_FALSE(overflowA->layoutObject()->objectPaintProperties()->scroll()->hasMainThreadScrollingReasons(MainThreadScrollingReason::kHasStickyPositionObjects));
EXPECT_FALSE(overflowB->layoutObject()->objectPaintProperties()->scroll()->hasMainThreadScrollingReasons(MainThreadScrollingReason::kHasStickyPositionObjects));
}
} // namespace blink
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