Title: [245772] trunk
Revision
245772
Author
[email protected]
Date
2019-05-25 08:01:14 -0700 (Sat, 25 May 2019)

Log Message

[Async overflow scrolling] Absolute positioned element inside async overflow scroll didn't get composited sometimes
https://bugs.webkit.org/show_bug.cgi?id=198237

Reviewed by Antti Koivisto.

Source/WebCore:

The logic in requiresCompositingForIndirectReason() that decides if we need to do
compositing for a layer that needs to move independently of its enclosing scroller
was wrong.

Instead of asking question about the enclosing compositing layer, it needs to ask
whether it has different positioning behavior from the layer that it would
otherwise paint into, which is its paint-order parent.

"paintsIntoProvidedBacking" already does a containing-block check against the
scroller, so we know we don't have to do the check in that case.

Test: scrollingcoordinator/scrolling-tree/absolute-inside-stacking-in-scroller.html

* rendering/RenderLayerCompositor.cpp:
(WebCore::RenderLayerCompositor::computeCompositingRequirements):
(WebCore::enclosingCompositedScrollingLayer):
(WebCore::isScrolledByOverflowScrollLayer):
(WebCore::isNonScrolledLayerInsideScrolledCompositedAncestor):
(WebCore::RenderLayerCompositor::requiresCompositingForIndirectReason const):
* rendering/RenderLayerCompositor.h:

LayoutTests:

* platform/ios-wk2/scrollingcoordinator/scrolling-tree/absolute-inside-stacking-in-scroller-expected.txt: Added.
* scrollingcoordinator/scrolling-tree/absolute-inside-stacking-in-scroller-expected.txt: Added.
* scrollingcoordinator/scrolling-tree/absolute-inside-stacking-in-scroller.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (245771 => 245772)


--- trunk/LayoutTests/ChangeLog	2019-05-25 15:01:09 UTC (rev 245771)
+++ trunk/LayoutTests/ChangeLog	2019-05-25 15:01:14 UTC (rev 245772)
@@ -1,5 +1,16 @@
 2019-05-25  Simon Fraser  <[email protected]>
 
+        [Async overflow scrolling] Absolute positioned element inside async overflow scroll didn't get composited sometimes
+        https://bugs.webkit.org/show_bug.cgi?id=198237
+
+        Reviewed by Antti Koivisto.
+
+        * platform/ios-wk2/scrollingcoordinator/scrolling-tree/absolute-inside-stacking-in-scroller-expected.txt: Added.
+        * scrollingcoordinator/scrolling-tree/absolute-inside-stacking-in-scroller-expected.txt: Added.
+        * scrollingcoordinator/scrolling-tree/absolute-inside-stacking-in-scroller.html: Added.
+
+2019-05-25  Simon Fraser  <[email protected]>
+
         [macOS] Fix programmatic scroll in RTL overflow with async scrolling enabled
         https://bugs.webkit.org/show_bug.cgi?id=198226
 

Added: trunk/LayoutTests/platform/ios-wk2/scrollingcoordinator/scrolling-tree/absolute-inside-stacking-in-scroller-expected.txt (0 => 245772)


--- trunk/LayoutTests/platform/ios-wk2/scrollingcoordinator/scrolling-tree/absolute-inside-stacking-in-scroller-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/platform/ios-wk2/scrollingcoordinator/scrolling-tree/absolute-inside-stacking-in-scroller-expected.txt	2019-05-25 15:01:14 UTC (rev 245772)
@@ -0,0 +1,44 @@
+
+(Frame scrolling node
+  (scrollable area size 800 600)
+  (contents size 800 600)
+  (parent relative scrollable rect at (0,0) size 800x600)
+  (scrollable area parameters 
+    (horizontal scroll elasticity 1)
+    (vertical scroll elasticity 1)
+    (horizontal scrollbar mode 0)
+    (vertical scrollbar mode 0))
+  (layout viewport at (0,0) size 800x600)
+  (min layout viewport origin (0,0))
+  (max layout viewport origin (0,0))
+  (behavior for fixed 0)
+  (children 2
+    (Overflow scrolling node
+      (scrollable area size 220 170)
+      (contents size 220 1020)
+      (parent relative scrollable rect at (19,11) size 220x170)
+      (scrollable area parameters 
+        (horizontal scroll elasticity 1)
+        (vertical scroll elasticity 1)
+        (horizontal scrollbar mode 0)
+        (vertical scrollbar mode 0)
+        (has enabled vertical scrollbar 1))
+    )
+    (Positioned node
+      (layout constraints 
+        (layer-position-at-last-layout (10,10))
+        (positioning-behavior moves))
+      (related overflow nodes 1)
+      (children 1
+        (Positioned node
+          (layout constraints 
+            (layer-position-at-last-layout (71,22))
+            (positioning-behavior stationary))
+          (related overflow nodes 1)
+        )
+      )
+    )
+  )
+)
+
+

Added: trunk/LayoutTests/scrollingcoordinator/scrolling-tree/absolute-inside-stacking-in-scroller-expected.txt (0 => 245772)


--- trunk/LayoutTests/scrollingcoordinator/scrolling-tree/absolute-inside-stacking-in-scroller-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/scrollingcoordinator/scrolling-tree/absolute-inside-stacking-in-scroller-expected.txt	2019-05-25 15:01:14 UTC (rev 245772)
@@ -0,0 +1,44 @@
+
+(Frame scrolling node
+  (scrollable area size 800 600)
+  (contents size 800 600)
+  (parent relative scrollable rect at (0,0) size 800x600)
+  (scrollable area parameters 
+    (horizontal scroll elasticity 2)
+    (vertical scroll elasticity 2)
+    (horizontal scrollbar mode 0)
+    (vertical scrollbar mode 0))
+  (layout viewport at (0,0) size 800x600)
+  (min layout viewport origin (0,0))
+  (max layout viewport origin (0,0))
+  (behavior for fixed 0)
+  (children 2
+    (Overflow scrolling node
+      (scrollable area size 205 155)
+      (contents size 205 1020)
+      (parent relative scrollable rect at (19,11) size 205x155)
+      (scrollable area parameters 
+        (horizontal scroll elasticity 0)
+        (vertical scroll elasticity 0)
+        (horizontal scrollbar mode 0)
+        (vertical scrollbar mode 0)
+        (has enabled vertical scrollbar 1))
+    )
+    (Positioned node
+      (layout constraints 
+        (layer-position-at-last-layout (10,10))
+        (positioning-behavior moves))
+      (related overflow nodes 1)
+      (children 1
+        (Positioned node
+          (layout constraints 
+            (layer-position-at-last-layout (71,22))
+            (positioning-behavior stationary))
+          (related overflow nodes 1)
+        )
+      )
+    )
+  )
+)
+
+

Added: trunk/LayoutTests/scrollingcoordinator/scrolling-tree/absolute-inside-stacking-in-scroller.html (0 => 245772)


--- trunk/LayoutTests/scrollingcoordinator/scrolling-tree/absolute-inside-stacking-in-scroller.html	                        (rev 0)
+++ trunk/LayoutTests/scrollingcoordinator/scrolling-tree/absolute-inside-stacking-in-scroller.html	2019-05-25 15:01:14 UTC (rev 245772)
@@ -0,0 +1,59 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ internal:AsyncOverflowScrollingEnabled=true ] -->
+<html>
+<head>
+	<title>Tests that we make a compositing layer for an abspost element inside something that paints into the scroller</title>
+    <style>
+	    .scroller {
+	        overflow: scroll;
+	        margin: 10px;
+	        background-color: silver;
+	        border: 1px solid black;
+	        padding: 10px;
+	        width: 200px;
+	        height: 150px;
+	    }
+
+	    .stacking {
+			border: 2px solid gray;
+			padding: 20px;
+	        opacity: 0.75;
+	    }
+
+	    .box {
+	        width: 100px;
+	        height: 100px;
+			background-color: blue;
+	    }
+	
+	    .absolute {
+	        position: absolute;
+	        left: 100px;
+	    }
+
+	    .scrolling-content {
+	        height: 1000px;
+	    }
+    </style>
+    <script>
+	    if (window.testRunner)
+	        testRunner.dumpAsText();
+
+	    window.addEventListener('load', () => {
+	        if (window.internals)
+	            document.getElementById('scrollingTree').innerText = window.internals.scrollingStateTreeAsText() + "\n";
+	    }, false);
+    </script>
+</head>
+<body>
+    <div class="container">
+        <div class="scroller">
+            <div class="scrolling-content">
+                <div class="stacking">
+                    <div class="absolute stationary box"></div>
+                </div>
+            </div>
+        </div>
+    </div>
+<pre id="scrollingTree"></pre>
+</body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (245771 => 245772)


--- trunk/Source/WebCore/ChangeLog	2019-05-25 15:01:09 UTC (rev 245771)
+++ trunk/Source/WebCore/ChangeLog	2019-05-25 15:01:14 UTC (rev 245772)
@@ -1,5 +1,33 @@
 2019-05-25  Simon Fraser  <[email protected]>
 
+        [Async overflow scrolling] Absolute positioned element inside async overflow scroll didn't get composited sometimes
+        https://bugs.webkit.org/show_bug.cgi?id=198237
+
+        Reviewed by Antti Koivisto.
+
+        The logic in requiresCompositingForIndirectReason() that decides if we need to do
+        compositing for a layer that needs to move independently of its enclosing scroller
+        was wrong.
+
+        Instead of asking question about the enclosing compositing layer, it needs to ask
+        whether it has different positioning behavior from the layer that it would
+        otherwise paint into, which is its paint-order parent.
+
+        "paintsIntoProvidedBacking" already does a containing-block check against the
+        scroller, so we know we don't have to do the check in that case.
+
+        Test: scrollingcoordinator/scrolling-tree/absolute-inside-stacking-in-scroller.html
+
+        * rendering/RenderLayerCompositor.cpp:
+        (WebCore::RenderLayerCompositor::computeCompositingRequirements):
+        (WebCore::enclosingCompositedScrollingLayer):
+        (WebCore::isScrolledByOverflowScrollLayer):
+        (WebCore::isNonScrolledLayerInsideScrolledCompositedAncestor):
+        (WebCore::RenderLayerCompositor::requiresCompositingForIndirectReason const):
+        * rendering/RenderLayerCompositor.h:
+
+2019-05-25  Simon Fraser  <[email protected]>
+
         [macOS] Fix programmatic scroll in RTL overflow with async scrolling enabled
         https://bugs.webkit.org/show_bug.cgi?id=198226
 

Modified: trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp (245771 => 245772)


--- trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp	2019-05-25 15:01:09 UTC (rev 245771)
+++ trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp	2019-05-25 15:01:14 UTC (rev 245772)
@@ -1009,7 +1009,7 @@
     // Now check for reasons to become composited that depend on the state of descendant layers.
     IndirectCompositingReason indirectCompositingReason;
     if (!willBeComposited && canBeComposited(layer)
-        && requiresCompositingForIndirectReason(layer, compositingState.compositingAncestor, currentState.subtreeIsCompositing, anyDescendantHas3DTransform, layerPaintsIntoProvidedBacking, indirectCompositingReason)) {
+        && requiresCompositingForIndirectReason(layer, currentState.subtreeIsCompositing, anyDescendantHas3DTransform, layerPaintsIntoProvidedBacking, indirectCompositingReason)) {
         layer.setIndirectCompositingReason(indirectCompositingReason);
         layerWillCompositePostDescendants();
     }
@@ -2916,8 +2916,45 @@
     return layer.hasCompositedScrollableOverflow();
 }
 
+static RenderLayer* enclosingCompositedScrollingLayer(const RenderLayer& layer, const RenderLayer& intermediateLayer, bool& sawIntermediateLayer)
+{
+    const auto* ancestorLayer = layer.parent();
+    while (ancestorLayer) {
+        if (ancestorLayer == &intermediateLayer)
+            sawIntermediateLayer = true;
+
+        if (ancestorLayer->hasCompositedScrollableOverflow())
+            return const_cast<RenderLayer*>(ancestorLayer);
+
+        ancestorLayer = ancestorLayer->parent();
+    }
+
+    return nullptr;
+}
+
+static bool isScrolledByOverflowScrollLayer(const RenderLayer& layer, const RenderLayer& overflowScrollLayer)
+{
+    bool scrolledByOverflowScroll = false;
+    traverseAncestorLayers(layer, [&](const RenderLayer& ancestorLayer, bool inContainingBlockChain, bool) {
+        if (&ancestorLayer == &overflowScrollLayer) {
+            scrolledByOverflowScroll = inContainingBlockChain;
+            return AncestorTraversal::Stop;
+        }
+        return AncestorTraversal::Continue;
+    });
+    return scrolledByOverflowScroll;
+}
+
+static bool isNonScrolledLayerInsideScrolledCompositedAncestor(const RenderLayer& layer, const RenderLayer& compositedAncestor, const RenderLayer& scrollingAncestor)
+{
+    bool ancestorMovedByScroller = &compositedAncestor == &scrollingAncestor || isScrolledByOverflowScrollLayer(compositedAncestor, scrollingAncestor);
+    bool layerMovedByScroller = isScrolledByOverflowScrollLayer(layer, scrollingAncestor);
+
+    return ancestorMovedByScroller && !layerMovedByScroller;
+}
+
 // FIXME: why doesn't this handle the clipping cases?
-bool RenderLayerCompositor::requiresCompositingForIndirectReason(const RenderLayer& layer, const RenderLayer* compositingAncestor, bool hasCompositedDescendants, bool has3DTransformedDescendants, bool paintsIntoProvidedBacking, IndirectCompositingReason& reason) const
+bool RenderLayerCompositor::requiresCompositingForIndirectReason(const RenderLayer& layer, bool hasCompositedDescendants, bool has3DTransformedDescendants, bool paintsIntoProvidedBacking, IndirectCompositingReason& reason) const
 {
     // When a layer has composited descendants, some effects, like 2d transforms, filters, masks etc must be implemented
     // via compositing so that they also apply to those composited descendants.
@@ -2941,8 +2978,12 @@
         }
     }
 
-    if (!paintsIntoProvidedBacking && renderer.isAbsolutelyPositioned() && compositingAncestor && layer.hasCompositedScrollingAncestor()) {
-        if (layerContainingBlockCrossesCoordinatedScrollingBoundary(layer, *compositingAncestor)) {
+    // If this layer scrolls independently from the layer that it would paint into, it needs to get composited.
+    if (!paintsIntoProvidedBacking && layer.hasCompositedScrollingAncestor()) {
+        auto* paintDestination = layer.paintOrderParent();
+        bool paintDestinationIsScrolling = false;
+        auto* scrollingAncestor = enclosingCompositedScrollingLayer(layer, *paintDestination, paintDestinationIsScrolling);
+        if (isNonScrolledLayerInsideScrolledCompositedAncestor(layer, *paintDestination, *scrollingAncestor)) {
             reason = IndirectCompositingReason::OverflowScrollPositioning;
             return true;
         }
@@ -3045,43 +3086,6 @@
     return false;
 }
 
-static RenderLayer* enclosingCompositedScrollingLayer(const RenderLayer& layer, const RenderLayer& intermediateLayer, bool& sawIntermediateLayer)
-{
-    const auto* currLayer = layer.parent();
-    while (currLayer) {
-        if (currLayer == &intermediateLayer)
-            sawIntermediateLayer = true;
-
-        if (currLayer->hasCompositedScrollableOverflow())
-            return const_cast<RenderLayer*>(currLayer);
-
-        currLayer = currLayer->parent();
-    }
-
-    return nullptr;
-}
-
-static bool isScrolledByOverflowScrollLayer(const RenderLayer& layer, const RenderLayer& overflowScrollLayer)
-{
-    bool scrolledByOverflowScroll = false;
-    traverseAncestorLayers(layer, [&](const RenderLayer& ancestorLayer, bool inContainingBlockChain, bool) {
-        if (&ancestorLayer == &overflowScrollLayer) {
-            scrolledByOverflowScroll = inContainingBlockChain;
-            return AncestorTraversal::Stop;
-        }
-        return AncestorTraversal::Continue;
-    });
-    return scrolledByOverflowScroll;
-}
-
-static bool isNonScrolledLayerInsideScrolledCompositedAncestor(const RenderLayer& layer, const RenderLayer& compositedAncestor, const RenderLayer& scrollingAncestor)
-{
-    bool ancestorMovedByScroller = &compositedAncestor == &scrollingAncestor || isScrolledByOverflowScrollLayer(compositedAncestor, scrollingAncestor);
-    bool layerMovedByScroller = isScrolledByOverflowScrollLayer(layer, scrollingAncestor);
-
-    return ancestorMovedByScroller && !layerMovedByScroller;
-}
-
 bool RenderLayerCompositor::layerContainingBlockCrossesCoordinatedScrollingBoundary(const RenderLayer& layer, const RenderLayer& compositedAncestor)
 {
     bool compositedAncestorIsInsideScroller = false;

Modified: trunk/Source/WebCore/rendering/RenderLayerCompositor.h (245771 => 245772)


--- trunk/Source/WebCore/rendering/RenderLayerCompositor.h	2019-05-25 15:01:09 UTC (rev 245771)
+++ trunk/Source/WebCore/rendering/RenderLayerCompositor.h	2019-05-25 15:01:14 UTC (rev 245772)
@@ -479,7 +479,7 @@
     bool requiresCompositingForPosition(RenderLayerModelObject&, const RenderLayer&, RequiresCompositingData&) const;
     bool requiresCompositingForOverflowScrolling(const RenderLayer&, RequiresCompositingData&) const;
     bool requiresCompositingForEditableImage(RenderLayerModelObject&) const;
-    bool requiresCompositingForIndirectReason(const RenderLayer&, const RenderLayer* compositingAncestor, bool hasCompositedDescendants, bool has3DTransformedDescendants, bool paintsIntoProvidedBacking, IndirectCompositingReason&) const;
+    bool requiresCompositingForIndirectReason(const RenderLayer&, bool hasCompositedDescendants, bool has3DTransformedDescendants, bool paintsIntoProvidedBacking, IndirectCompositingReason&) const;
 
     static bool layerContainingBlockCrossesCoordinatedScrollingBoundary(const RenderLayer&, const RenderLayer& compositedAncestor);
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to