Title: [243309] trunk
Revision
243309
Author
[email protected]
Date
2019-03-21 11:58:09 -0700 (Thu, 21 Mar 2019)

Log Message

Absolute in stacking-context scroller jiggles when scrolled
https://bugs.webkit.org/show_bug.cgi?id=196010

Reviewed by Zalan Bujtas.

Source/WebCore:

Updating compositing layers after a scroll (in a compositing update on the main thread)
failed to traverse to an absolute layer inside a stacking-context overflow:scroll,
because the overflow's layer didn't have the "hasCompositingAncestor" bit set on it.

This happened because childState.subtreeIsCompositing wasn't being set when indirect
reasons trigger compositing. So clean up RenderLayerCompositor::computeCompositingRequirements()
to set childState.subtreeIsCompositing for "late" compositing decisions, and move the
"Subsequent layers in the parent stacking context also need to composite" chunk
down to after the last compositing decision has been made.

Test: compositing/overflow/absolute-in-overflow.html

* page/scrolling/ScrollingTreeScrollingNode.cpp:
(WebCore::ScrollingTreeScrollingNode::scrollTo):
* page/scrolling/cocoa/ScrollingTreePositionedNode.mm:
(WebCore::ScrollingTreePositionedNode::applyLayerPositions):
* rendering/RenderLayerCompositor.cpp:
(WebCore::RenderLayerCompositor::computeCompositingRequirements):

LayoutTests:

* compositing/overflow/absolute-in-overflow-expected.html: Added.
* compositing/overflow/absolute-in-overflow.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (243308 => 243309)


--- trunk/LayoutTests/ChangeLog	2019-03-21 18:57:09 UTC (rev 243308)
+++ trunk/LayoutTests/ChangeLog	2019-03-21 18:58:09 UTC (rev 243309)
@@ -1,3 +1,13 @@
+2019-03-21  Simon Fraser  <[email protected]>
+
+        Absolute in stacking-context scroller jiggles when scrolled
+        https://bugs.webkit.org/show_bug.cgi?id=196010
+
+        Reviewed by Zalan Bujtas.
+
+        * compositing/overflow/absolute-in-overflow-expected.html: Added.
+        * compositing/overflow/absolute-in-overflow.html: Added.
+
 2019-03-21  Zalan Bujtas  <[email protected]>
 
         [ContentChangeObserver] Start tracking implicit transitions at touchStart

Added: trunk/LayoutTests/compositing/overflow/absolute-in-overflow-expected.html (0 => 243309)


--- trunk/LayoutTests/compositing/overflow/absolute-in-overflow-expected.html	                        (rev 0)
+++ trunk/LayoutTests/compositing/overflow/absolute-in-overflow-expected.html	2019-03-21 18:58:09 UTC (rev 243309)
@@ -0,0 +1,61 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <style>
+        body {
+            margin: 0;
+        }
+        #scroller {
+            margin: 10px;
+            background-color: silver;
+            width: 400px;
+            height: 300px;
+            overflow: scroll;
+            opacity: 0.8;
+        }
+        
+        .scrolling-content {
+            height: 1000px;
+        }
+        
+        .absolute {
+            top: 20px;
+            left: 20px;
+            width: 200px;
+            height: 200px;
+            background-color: blue;
+        }
+        
+        .changed {
+            position: absolute;
+        }
+    </style>
+    <script>
+        if (window.testRunner)
+            testRunner.waitUntilDone();
+
+        if (window.internals)
+            window.internals.settings.setAsyncOverflowScrollingEnabled(true);
+
+        function doTest()
+        {
+            setTimeout(() => {
+                scroller.scrollTop = 200;
+                target.classList.add('changed');
+
+                if (window.testRunner)
+                    testRunner.notifyDone();
+            }, 0);
+        }
+
+        window.addEventListener('load', doTest, false);
+    </script>
+</head>
+<body>
+    <div id="scroller">
+        <div class="scrolling-content">
+            <div id="target" class="absolute"></div>
+        </div>
+    </div>
+</body>
+</html>

Added: trunk/LayoutTests/compositing/overflow/absolute-in-overflow.html (0 => 243309)


--- trunk/LayoutTests/compositing/overflow/absolute-in-overflow.html	                        (rev 0)
+++ trunk/LayoutTests/compositing/overflow/absolute-in-overflow.html	2019-03-21 18:58:09 UTC (rev 243309)
@@ -0,0 +1,57 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <style>
+        body {
+            margin: 0;
+        }
+        #scroller {
+            margin: 10px;
+            background-color: silver;
+            width: 400px;
+            height: 300px;
+            overflow: scroll;
+            opacity: 0.8;
+        }
+        
+        .scrolling-content {
+            height: 1000px;
+        }
+        
+        .absolute {
+            position: absolute;
+            top: 20px;
+            left: 20px;
+            width: 200px;
+            height: 200px;
+            background-color: blue;
+        }
+    </style>
+    <script>
+        if (window.testRunner)
+            testRunner.waitUntilDone();
+
+        if (window.internals)
+            window.internals.settings.setAsyncOverflowScrollingEnabled(true);
+
+        function doTest()
+        {
+            setTimeout(() => {
+                scroller.scrollTop = 200;
+
+                if (window.testRunner)
+                    testRunner.notifyDone();
+            }, 0);
+        }
+
+        window.addEventListener('load', doTest, false);
+    </script>
+</head>
+<body>
+    <div id="scroller">
+        <div class="scrolling-content">
+            <div class="absolute"></div>
+        </div>
+    </div>
+</body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (243308 => 243309)


--- trunk/Source/WebCore/ChangeLog	2019-03-21 18:57:09 UTC (rev 243308)
+++ trunk/Source/WebCore/ChangeLog	2019-03-21 18:58:09 UTC (rev 243309)
@@ -1,3 +1,29 @@
+2019-03-21  Simon Fraser  <[email protected]>
+
+        Absolute in stacking-context scroller jiggles when scrolled
+        https://bugs.webkit.org/show_bug.cgi?id=196010
+
+        Reviewed by Zalan Bujtas.
+
+        Updating compositing layers after a scroll (in a compositing update on the main thread)
+        failed to traverse to an absolute layer inside a stacking-context overflow:scroll,
+        because the overflow's layer didn't have the "hasCompositingAncestor" bit set on it.
+
+        This happened because childState.subtreeIsCompositing wasn't being set when indirect
+        reasons trigger compositing. So clean up RenderLayerCompositor::computeCompositingRequirements()
+        to set childState.subtreeIsCompositing for "late" compositing decisions, and move the
+        "Subsequent layers in the parent stacking context also need to composite" chunk
+        down to after the last compositing decision has been made.
+
+        Test: compositing/overflow/absolute-in-overflow.html
+
+        * page/scrolling/ScrollingTreeScrollingNode.cpp:
+        (WebCore::ScrollingTreeScrollingNode::scrollTo):
+        * page/scrolling/cocoa/ScrollingTreePositionedNode.mm:
+        (WebCore::ScrollingTreePositionedNode::applyLayerPositions):
+        * rendering/RenderLayerCompositor.cpp:
+        (WebCore::RenderLayerCompositor::computeCompositingRequirements):
+
 2019-03-21  Zalan Bujtas  <[email protected]>
 
         [ContentChangeObserver] Start tracking implicit transitions at touchStart

Modified: trunk/Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.cpp (243308 => 243309)


--- trunk/Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.cpp	2019-03-21 18:57:09 UTC (rev 243308)
+++ trunk/Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.cpp	2019-03-21 18:58:09 UTC (rev 243309)
@@ -161,6 +161,9 @@
         return;
 
     m_currentScrollPosition = adjustedScrollPosition(position, clamp);
+    
+    LOG_WITH_STREAM(Scrolling, stream << "ScrollingTreeScrollingNode " << scrollingNodeID() << " scrollTo " << position << " (delta from last committed position " << (m_lastCommittedScrollPosition - m_currentScrollPosition) << ")");
+
     updateViewportForCurrentScrollPosition();
     currentScrollPositionChanged();
 }

Modified: trunk/Source/WebCore/page/scrolling/cocoa/ScrollingTreePositionedNode.mm (243308 => 243309)


--- trunk/Source/WebCore/page/scrolling/cocoa/ScrollingTreePositionedNode.mm	2019-03-21 18:57:09 UTC (rev 243308)
+++ trunk/Source/WebCore/page/scrolling/cocoa/ScrollingTreePositionedNode.mm	2019-03-21 18:58:09 UTC (rev 243309)
@@ -87,8 +87,6 @@
             }
         }
     }
-    LOG_WITH_STREAM(Scrolling, stream << "ScrollingTreePositionedNode " << scrollingNodeID() << " applyLayerPositions: overflow delta " << scrollOffsetSinceLastCommit);
-
     auto layerOffset = -scrollOffsetSinceLastCommit;
     if (m_constraints.scrollPositioningBehavior() == ScrollPositioningBehavior::Stationary) {
         // Stationary nodes move in the opposite direction.
@@ -96,6 +94,9 @@
     }
 
     FloatPoint layerPosition = m_constraints.layerPositionAtLastLayout() - layerOffset;
+
+    LOG_WITH_STREAM(Scrolling, stream << "ScrollingTreePositionedNode " << scrollingNodeID() << " applyLayerPositions: overflow delta " << scrollOffsetSinceLastCommit << " moving layer to " << layerPosition);
+
     [m_layer _web_setLayerTopLeftPosition:layerPosition - m_constraints.alignmentOffset()];
 
     // FIXME: Should our scroller deltas propagate to descendants?

Modified: trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp (243308 => 243309)


--- trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp	2019-03-21 18:57:09 UTC (rev 243308)
+++ trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp	2019-03-21 18:58:09 UTC (rev 243309)
@@ -958,6 +958,7 @@
         && requiresCompositingForIndirectReason(layer.renderer(), compositingState.compositingAncestor, childState.subtreeIsCompositing, anyDescendantHas3DTransform, indirectCompositingReason)) {
         layer.setIndirectCompositingReason(indirectCompositingReason);
         childState.compositingAncestor = &layer;
+        childState.subtreeIsCompositing = true;
         overlapMap.pushCompositingContainer();
         addToOverlapMapRecursive(overlapMap, layer);
         willBeComposited = true;
@@ -968,10 +969,6 @@
         layer.reflectionLayer()->setIndirectCompositingReason(willBeComposited ? RenderLayer::IndirectCompositingReason::Stacking : RenderLayer::IndirectCompositingReason::None);
     }
 
-    // Subsequent layers in the parent stacking context also need to composite.
-    compositingState.subtreeIsCompositing |= childState.subtreeIsCompositing;
-    compositingState.fullPaintOrderTraversalRequired |= childState.fullPaintOrderTraversalRequired;
-
     // Set the flag to say that this layer has compositing children.
     layer.setHasCompositingDescendant(childState.subtreeIsCompositing);
 
@@ -987,6 +984,7 @@
     if (isCompositedClippingLayer) {
         if (!willBeComposited) {
             childState.compositingAncestor = &layer;
+            childState.subtreeIsCompositing = true;
             overlapMap.pushCompositingContainer();
             addToOverlapMapRecursive(overlapMap, layer);
             willBeComposited = true;
@@ -994,8 +992,7 @@
     }
 
 #if ENABLE(CSS_COMPOSITING)
-    if ((willBeComposited && layer.hasBlendMode())
-        || (layer.hasNotIsolatedCompositedBlendingDescendants() && !layer.isolatesCompositedBlending()))
+    if ((willBeComposited && layer.hasBlendMode()) || (layer.hasNotIsolatedCompositedBlendingDescendants() && !layer.isolatesCompositedBlending()))
         compositingState.hasNotIsolatedCompositedBlendingDescendants = true;
 #endif
 
@@ -1013,7 +1010,11 @@
         willBeComposited = false;
 #endif
     }
-    
+
+    // Subsequent layers in the parent stacking context also need to composite.
+    compositingState.subtreeIsCompositing |= childState.subtreeIsCompositing;
+    compositingState.fullPaintOrderTraversalRequired |= childState.fullPaintOrderTraversalRequired;
+
     ASSERT(willBeComposited == needsToBeComposited(layer, queryData));
 
     // Create or destroy backing here. However, we can't update geometry because layers above us may become composited
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to