Commit de4c1142 authored by smcgruer's avatar smcgruer Committed by Commit bot

Composite sticky-positioned elements when they have composited descendants

In the case of nested sticky elements, if the descendant elements are promoted
but their ancestor is not we will position them incorrectly. Instead of trying
to re-compute main-thread positioning on the compositor, we can just promote
any sticky element that has promoted sticky descendants.

This CL goes slightly further and promotes any sticky element that has
composited descendants regardless of whether they are sticky - doing so makes
the code much simpler and the performance impact should be limited by the fact
that sticky is not common.

BUG=702229
CQ_INCLUDE_TRYBOTS=master.tryserver.chromium.linux:linux_layout_tests_slimming_paint_v2

Review-Url: https://codereview.chromium.org/2754983002
Cr-Commit-Position: refs/heads/master@{#471217}
parent d25e37df
# Expectations for slimming paint v2 # Expectations for slimming paint v2
# See: https://docs.google.com/document/d/1QCM912Dr6u38DqyQqd7pxQxDy8FFOoWMMDq7uAXqKdA/view # See: https://docs.google.com/document/d/1QCM912Dr6u38DqyQqd7pxQxDy8FFOoWMMDq7uAXqKdA/view
# We are focused on fast/, compositing/, and svg/ with all other directories skipped (for now). # We are focused on fast/, compositing/, and svg/ with all other directories skipped (for now).
Bug(none) accessibility/ [ Skip ] Bug(none) accessibility/ [ Skip ]
Bug(none) app_banner/ [ Skip ] Bug(none) app_banner/ [ Skip ]
Bug(none) battery-status/ [ Skip ] Bug(none) battery-status/ [ Skip ]
...@@ -330,6 +329,7 @@ Bug(none) compositing/overflow/content-loses-scrollbars.html [ Failure ] ...@@ -330,6 +329,7 @@ Bug(none) compositing/overflow/content-loses-scrollbars.html [ Failure ]
Bug(none) compositing/overflow/descendant-with-clip-path.html [ Failure ] Bug(none) compositing/overflow/descendant-with-clip-path.html [ Failure ]
Bug(none) compositing/overflow/mask-with-filter.html [ Failure Crash ] Bug(none) compositing/overflow/mask-with-filter.html [ Failure Crash ]
Bug(none) compositing/overflow/mask-with-small-content-rect.html [ Failure ] Bug(none) compositing/overflow/mask-with-small-content-rect.html [ Failure ]
crbug.com/718971 compositing/overflow/mixed-composited-nested-sticky-overflow-scroller.html [ Failure ]
Bug(none) compositing/overflow/nested-border-radius-clipping.html [ Failure ] Bug(none) compositing/overflow/nested-border-radius-clipping.html [ Failure ]
Bug(none) compositing/overflow/nested-render-surfaces-with-intervening-clip.html [ Failure Crash ] Bug(none) compositing/overflow/nested-render-surfaces-with-intervening-clip.html [ Failure Crash ]
Bug(none) compositing/overflow/nested-render-surfaces-with-rotation.html [ Failure ] Bug(none) compositing/overflow/nested-render-surfaces-with-rotation.html [ Failure ]
......
<style>
body {
margin: 0;
}
.container {
width: 200px;
height: 2000px;
}
.outerIndicator {
position: absolute;
top: 250px;
background-color: green;
width: 200px;
height: 200px;
}
.middleIndicator {
position: absolute;
top: 50px;
background-color: yellow;
width: 200px;
height: 100px;
}
.innerIndicator {
position: absolute;
top: 25px;
background-color: red;
width: 200px;
height: 50px;
}
</style>
<script>
if (window.testRunner)
testRunner.waitUntilDone();
function finishTest() {
window.scrollTo(0, 200);
if (window.testRunner)
testRunner.notifyDone();
}
window.addEventListener('load', function() {
requestAnimationFrame(function() {
requestAnimationFrame(finishTest);
});
});
</script>
<div class="container">
<div class="outerIndicator">
<div class="middleIndicator">
<div class="innerIndicator"></div>
</div>
</div>
</div>
<style>
body {
margin: 0;
}
.scroller {
overflow: auto;
height: 300px;
width: 250px;
}
.container {
width: 200px;
height: 2000px;
}
.outerIndicator {
position: absolute;
top: 50px;
background-color: green;
width: 200px;
height: 200px;
}
.middleIndicator {
position: absolute;
top: 50px;
background-color: yellow;
width: 200px;
height: 100px;
}
.innerIndicator {
position: absolute;
top: 25px;
background-color: red;
width: 200px;
height: 50px;
}
</style>
<script>
if (window.testRunner)
testRunner.waitUntilDone();
function finishTest() {
document.querySelector('.scroller').scrollTop = 200;
if (window.testRunner)
testRunner.notifyDone();
}
window.addEventListener('load', function() {
requestAnimationFrame(function() {
requestAnimationFrame(finishTest);
});
});
</script>
<div class="scroller">
<div class="container">
<div class="outerIndicator">
<div class="middleIndicator">
<div class="innerIndicator"></div>
</div>
</div>
</div>
</div>
<style>
body {
margin: 0;
}
.scroller {
overflow: auto;
height: 300px;
width: 250px;
}
.container {
width: 200px;
height: 2000px;
}
.composited {
/* Forces promotion without creating a stacking context. */
backface-visibility: hidden;
}
.outerSticky {
position: sticky;
top: 50px;
background-color: green;
width: 200px;
height: 200px;
}
.middleSticky {
position: sticky;
top: 100px;
background-color: yellow;
width: 200px;
height: 100px;
}
.innerSticky {
position: sticky;
top: 125px;
background-color: red;
width: 200px;
height: 50px;
}
</style>
<script>
if (window.testRunner)
testRunner.waitUntilDone();
function finishTest() {
document.querySelector('.scroller').scrollTop = 200;
if (window.testRunner)
testRunner.notifyDone();
}
window.addEventListener('load', function() {
requestAnimationFrame(function() {
requestAnimationFrame(finishTest);
});
});
</script>
<div class="scroller">
<div class="container">
<div class="outerSticky">
<div class="middleSticky composited">
<div class="innerSticky composited"></div>
</div>
</div>
</div>
</div>
<style>
body {
margin: 0;
}
.container {
width: 200px;
height: 2000px;
}
.composited {
/* Forces promotion without creating a stacking context. */
backface-visibility: hidden;
}
.outerSticky {
position: sticky;
top: 50px;
background-color: green;
width: 200px;
height: 200px;
}
.middleSticky {
position: sticky;
top: 100px;
background-color: yellow;
width: 200px;
height: 100px;
}
.innerSticky {
position: sticky;
top: 125px;
background-color: red;
width: 200px;
height: 50px;
}
</style>
<script>
if (window.testRunner)
testRunner.waitUntilDone();
function finishTest() {
window.scrollTo(0, 200);
if (window.testRunner)
testRunner.notifyDone();
}
window.addEventListener('load', function() {
requestAnimationFrame(function() {
requestAnimationFrame(finishTest);
});
});
</script>
<div class="container">
<div class="outerSticky">
<div class="middleSticky composited">
<div class="innerSticky composited"></div>
</div>
</div>
</div>
...@@ -195,11 +195,10 @@ static CompositingReasons SubtreeReasonsForCompositing( ...@@ -195,11 +195,10 @@ static CompositingReasons SubtreeReasonsForCompositing(
// scroll-dependant fixed position elements with composited descendants for // scroll-dependant fixed position elements with composited descendants for
// correctness - even if we lose LCD. // correctness - even if we lose LCD.
const bool ignore_lcd_text = true; const bool ignore_lcd_text = true;
if (layer->GetLayoutObject().Style()->GetPosition() == EPosition::kFixed && if (compositing_reason_finder.RequiresCompositingForScrollDependentPosition(
compositing_reason_finder.RequiresCompositingForScrollDependentPosition(
layer, ignore_lcd_text)) { layer, ignore_lcd_text)) {
subtree_reasons |= subtree_reasons |=
kCompositingReasonPositionFixedWithCompositedDescendants; kCompositingReasonPositionFixedOrStickyWithCompositedDescendants;
} }
} }
......
...@@ -88,9 +88,10 @@ const CompositingReasonStringMap kCompositingReasonStringMap[] = { ...@@ -88,9 +88,10 @@ const CompositingReasonStringMap kCompositingReasonStringMap[] = {
{kCompositingReasonIsolateCompositedDescendants, {kCompositingReasonIsolateCompositedDescendants,
"isolateCompositedDescendants", "isolateCompositedDescendants",
"Should isolate descendants to apply a blend effect"}, "Should isolate descendants to apply a blend effect"},
{kCompositingReasonPositionFixedWithCompositedDescendants, {kCompositingReasonPositionFixedOrStickyWithCompositedDescendants,
"positionFixedWithCompositedDescendants" "positionFixedOrStickyWithCompositedDescendants"
"Is a position:fixed element with composited descendants"}, "Is a position:fixed or position:sticky element with composited "
"descendants"},
{kCompositingReasonRoot, "root", "Is the root layer"}, {kCompositingReasonRoot, "root", "Is the root layer"},
{kCompositingReasonLayerForAncestorClip, "layerForAncestorClip", {kCompositingReasonLayerForAncestorClip, "layerForAncestorClip",
"Secondary layer, applies a clip due to a sibling in the compositing " "Secondary layer, applies a clip due to a sibling in the compositing "
......
...@@ -63,8 +63,9 @@ const uint64_t kCompositingReasonReflectionOfCompositedParent = UINT64_C(1) ...@@ -63,8 +63,9 @@ const uint64_t kCompositingReasonReflectionOfCompositedParent = UINT64_C(1)
<< 28; << 28;
const uint64_t kCompositingReasonIsolateCompositedDescendants = UINT64_C(1) const uint64_t kCompositingReasonIsolateCompositedDescendants = UINT64_C(1)
<< 29; << 29;
const uint64_t kCompositingReasonPositionFixedWithCompositedDescendants = const uint64_t
UINT64_C(1) << 30; kCompositingReasonPositionFixedOrStickyWithCompositedDescendants =
UINT64_C(1) << 30;
// The root layer is a special case. It may be forced to be a layer, but it also // The root layer is a special case. It may be forced to be a layer, but it also
// needs to be a layer if anything else in the subtree is composited. // needs to be a layer if anything else in the subtree is composited.
...@@ -130,7 +131,7 @@ const uint64_t kCompositingReasonComboCompositedDescendants = ...@@ -130,7 +131,7 @@ const uint64_t kCompositingReasonComboCompositedDescendants =
kCompositingReasonBlendingWithCompositedDescendants | kCompositingReasonBlendingWithCompositedDescendants |
kCompositingReasonReflectionWithCompositedDescendants | kCompositingReasonReflectionWithCompositedDescendants |
kCompositingReasonClipsCompositingDescendants | kCompositingReasonClipsCompositingDescendants |
kCompositingReasonPositionFixedWithCompositedDescendants; kCompositingReasonPositionFixedOrStickyWithCompositedDescendants;
const uint64_t kCompositingReasonCombo3DDescendants = const uint64_t kCompositingReasonCombo3DDescendants =
kCompositingReasonPreserve3DWith3DDescendants | kCompositingReasonPreserve3DWith3DDescendants |
...@@ -158,7 +159,7 @@ const uint64_t kCompositingReasonComboReasonsThatRequireOwnBacking = ...@@ -158,7 +159,7 @@ const uint64_t kCompositingReasonComboReasonsThatRequireOwnBacking =
// 3d-transformed elements // 3d-transformed elements
// intersect. // intersect.
kCompositingReasonBackdropFilter | kCompositingReasonBackdropFilter |
kCompositingReasonPositionFixedWithCompositedDescendants; kCompositingReasonPositionFixedOrStickyWithCompositedDescendants;
const uint64_t kCompositingReasonComboSquashableReasons = const uint64_t kCompositingReasonComboSquashableReasons =
kCompositingReasonOverlap | kCompositingReasonAssumedOverlap | kCompositingReasonOverlap | kCompositingReasonAssumedOverlap |
......
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