Title: [257920] trunk/Source/WebCore
Revision
257920
Author
simon.fra...@apple.com
Date
2020-03-05 09:18:00 -0800 (Thu, 05 Mar 2020)

Log Message

Track "scrolling scope" on RenderLayers
https://bugs.webkit.org/show_bug.cgi?id=208620

Reviewed by Zalan Bujtas.

Keep track of a "scrolling scope" on RenderLayers. Layers that share a scrolling scope
get scrolled by some common async-scrollable containing-block ancestor. The scope is just
a unique identifier.

Each layer has two scopes; a "box" scope that applies to the background/borders, and
a "content" scope that applies to (potentially) scrollable content. For most layers,
these will be the same, and shared with the layer's containing block ancestor layer.

For async-scrollable overflow, "box" scope is shared with the cb ancestor, but "content" scope
will have a new value that applies to all the layers moved by that scroller.

Having this value makes it easy to ask the question "is this layer scrolled by some ancestor",
which is a tricky computation for things like a position:absolute layer inside a non-containing block
stacking context overflow:scroll. Also, position:fixed whose containing block is the root will share
the scrolling scope of the root.

No behavior change.

* rendering/RenderLayer.cpp:
(WebCore::nextScrollingScope):
(WebCore::RenderLayer::RenderLayer):
(WebCore::RenderLayer::updateLayerPositions):
(WebCore::RenderLayer::updateLayerPosition):
(WebCore::outputPaintOrderTreeLegend):
(WebCore::outputPaintOrderTreeRecursive):
* rendering/RenderLayer.h:
* rendering/RenderLayerCompositor.cpp:
(WebCore::isScrolledByOverflowScrollLayer):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (257919 => 257920)


--- trunk/Source/WebCore/ChangeLog	2020-03-05 17:13:01 UTC (rev 257919)
+++ trunk/Source/WebCore/ChangeLog	2020-03-05 17:18:00 UTC (rev 257920)
@@ -1,3 +1,39 @@
+2020-03-05  Simon Fraser  <simon.fra...@apple.com>
+
+        Track "scrolling scope" on RenderLayers
+        https://bugs.webkit.org/show_bug.cgi?id=208620
+
+        Reviewed by Zalan Bujtas.
+
+        Keep track of a "scrolling scope" on RenderLayers. Layers that share a scrolling scope
+        get scrolled by some common async-scrollable containing-block ancestor. The scope is just
+        a unique identifier.
+        
+        Each layer has two scopes; a "box" scope that applies to the background/borders, and
+        a "content" scope that applies to (potentially) scrollable content. For most layers,
+        these will be the same, and shared with the layer's containing block ancestor layer.
+
+        For async-scrollable overflow, "box" scope is shared with the cb ancestor, but "content" scope
+        will have a new value that applies to all the layers moved by that scroller.
+
+        Having this value makes it easy to ask the question "is this layer scrolled by some ancestor",
+        which is a tricky computation for things like a position:absolute layer inside a non-containing block
+        stacking context overflow:scroll. Also, position:fixed whose containing block is the root will share
+        the scrolling scope of the root.
+
+        No behavior change.
+
+        * rendering/RenderLayer.cpp:
+        (WebCore::nextScrollingScope):
+        (WebCore::RenderLayer::RenderLayer):
+        (WebCore::RenderLayer::updateLayerPositions):
+        (WebCore::RenderLayer::updateLayerPosition):
+        (WebCore::outputPaintOrderTreeLegend):
+        (WebCore::outputPaintOrderTreeRecursive):
+        * rendering/RenderLayer.h:
+        * rendering/RenderLayerCompositor.cpp:
+        (WebCore::isScrolledByOverflowScrollLayer):
+
 2020-03-05  youenn fablet  <you...@apple.com>
 
         Add logging support for capture sources in GPUProcess

Modified: trunk/Source/WebCore/rendering/RenderLayer.cpp (257919 => 257920)


--- trunk/Source/WebCore/rendering/RenderLayer.cpp	2020-03-05 17:13:01 UTC (rev 257919)
+++ trunk/Source/WebCore/rendering/RenderLayer.cpp	2020-03-05 17:18:00 UTC (rev 257920)
@@ -283,6 +283,12 @@
 
 #endif
 
+static ScrollingScope nextScrollingScope()
+{
+    static ScrollingScope currentScope = 0;
+    return ++currentScope;
+}
+
 DEFINE_ALLOCATOR_WITH_HEAP_IDENTIFIER(RenderLayer);
 
 RenderLayer::RenderLayer(RenderLayerModelObject& rendererLayerModelObject)
@@ -343,6 +349,9 @@
 
     m_isSelfPaintingLayer = shouldBeSelfPaintingLayer();
 
+    if (isRenderViewLayer())
+        m_boxScrollingScope = m_contentsScrollingScope = nextScrollingScope();
+
     if (!renderer().firstChild()) {
         m_visibleContentStatusDirty = false;
         m_hasVisibleContent = renderer().style().visibility() == Visibility::Visible;
@@ -958,7 +967,7 @@
 
     // Clear our cached clip rect information.
     clearClipRects();
-    
+
     if (hasOverflowControls()) {
         LayoutSize offsetFromRoot;
         if (geometryMap)
@@ -1734,15 +1743,27 @@
         if (positionedParent->renderer().hasOverflowClip())
             localPoint -= toLayoutSize(positionedParent->scrollPosition());
         
-        if (renderer().isOutOfFlowPositioned() && positionedParent->renderer().isInFlowPositioned() && is<RenderInline>(positionedParent->renderer())) {
+        if (positionedParent->renderer().isInFlowPositioned() && is<RenderInline>(positionedParent->renderer())) {
             LayoutSize offset = downcast<RenderInline>(positionedParent->renderer()).offsetForInFlowPositionedInline(&downcast<RenderBox>(renderer()));
             localPoint += offset;
         }
-    } else if (parent()) {
-        if (parent()->renderer().hasOverflowClip())
+
+        ASSERT(positionedParent->contentsScrollingScope());
+        m_boxScrollingScope = positionedParent->contentsScrollingScope();
+    } else if (auto* parentLayer = parent()) {
+        if (parentLayer->renderer().hasOverflowClip())
             localPoint -= toLayoutSize(parent()->scrollPosition());
+
+        ASSERT(parentLayer->contentsScrollingScope());
+        m_boxScrollingScope = parentLayer->contentsScrollingScope();
     }
-    
+
+    if (hasCompositedScrollableOverflow()) {
+        if (!m_contentsScrollingScope)
+            m_contentsScrollingScope = nextScrollingScope();
+    } else if (!m_contentsScrollingScope)
+        m_contentsScrollingScope = m_boxScrollingScope;
+
     bool positionOrOffsetChanged = false;
     if (renderer().isInFlowPositioned()) {
         LayoutSize newOffset = downcast<RenderBoxModelObject>(renderer()).offsetForInFlowPosition();
@@ -7097,7 +7118,8 @@
     stream << "(S)tacking Context/(F)orced SC/O(P)portunistic SC, (N)ormal flow only, (O)verflow clip, (A)lpha (opacity or mask), has (B)lend mode, (I)solates blending, (T)ransform-ish, (F)ilter, Fi(X)ed position, Behaves as fi(x)ed, (C)omposited, (P)rovides backing/uses (p)rovided backing/paints to (a)ncestor, (c)omposited descendant, (s)scrolling ancestor, (t)transformed ancestor\n"
         "Dirty (z)-lists, Dirty (n)ormal flow lists\n"
         "Traversal needs: requirements (t)raversal on descendants, (b)acking or hierarchy traversal on descendants, (r)equirements traversal on all descendants, requirements traversal on all (s)ubsequent layers, (h)ierarchy traversal on all descendants, update of paint (o)rder children\n"
-        "Update needs:    post-(l)ayout requirements, (g)eometry, (k)ids geometry, (c)onfig, layer conne(x)ion, (s)crolling tree\n";
+        "Update needs:    post-(l)ayout requirements, (g)eometry, (k)ids geometry, (c)onfig, layer conne(x)ion, (s)crolling tree\n"
+        "Scrolling scope: box contents\n";
     stream.nextLine();
 }
 
@@ -7168,6 +7190,12 @@
 
     stream << " ";
 
+    stream << layer.boxScrollingScope();
+    stream << " ";
+    stream << layer.contentsScrollingScope();
+
+    stream << " ";
+
     outputIdent(stream, depth);
 
     stream << prefix;

Modified: trunk/Source/WebCore/rendering/RenderLayer.h (257919 => 257920)


--- trunk/Source/WebCore/rendering/RenderLayer.h	2020-03-05 17:13:01 UTC (rev 257919)
+++ trunk/Source/WebCore/rendering/RenderLayer.h	2020-03-05 17:18:00 UTC (rev 257920)
@@ -53,6 +53,7 @@
 #include "ScrollBehavior.h"
 #include "ScrollableArea.h"
 #include <memory>
+#include <wtf/Markable.h>
 #include <wtf/WeakPtr.h>
 
 namespace WTF {
@@ -138,6 +139,8 @@
     ScrollBehavior behavior { ScrollBehavior::Auto };
 };
 
+using ScrollingScope = uint64_t;
+
 DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(RenderLayer);
 class RenderLayer final : public ScrollableArea {
     WTF_MAKE_FAST_ALLOCATED_WITH_HEAP_IDENTIFIER(RenderLayer);
@@ -861,6 +864,10 @@
     bool hasCompositedScrollingAncestor() const { return m_hasCompositedScrollingAncestor; }
     void setHasCompositedScrollingAncestor(bool hasCompositedScrollingAncestor) { m_hasCompositedScrollingAncestor = hasCompositedScrollingAncestor; }
 
+    // Layers with the same ScrollingScope are scrolled by some common ancestor scroller. Used for async scrolling.
+    Optional<ScrollingScope> boxScrollingScope() const { return m_boxScrollingScope; }
+    Optional<ScrollingScope> contentsScrollingScope() const { return m_contentsScrollingScope; }
+
     bool paintsWithTransparency(OptionSet<PaintBehavior> paintBehavior) const
     {
         return (isTransparent() || hasBlendMode() || (isolatesBlending() && !renderer().isDocumentElementRenderer())) && ((paintBehavior & PaintBehavior::FlattenCompositingLayers) || !isComposited());
@@ -1321,6 +1328,9 @@
     
     IntPoint m_cachedOverlayScrollbarOffset;
 
+    Markable<ScrollingScope, IntegralMarkableTraits<ScrollingScope, 0>> m_boxScrollingScope;
+    Markable<ScrollingScope, IntegralMarkableTraits<ScrollingScope, 0>> m_contentsScrollingScope;
+
     std::unique_ptr<RenderMarquee> m_marquee; // Used for <marquee>.
     
     // Cached normal flow values for absolute positioned elements with static left/top values.

Modified: trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp (257919 => 257920)


--- trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp	2020-03-05 17:13:01 UTC (rev 257919)
+++ trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp	2020-03-05 17:18:00 UTC (rev 257920)
@@ -3178,15 +3178,7 @@
 
 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;
+    return layer.boxScrollingScope() == overflowScrollLayer.contentsScrollingScope();
 }
 
 static RenderLayer* enclosingCompositedScrollingLayer(const RenderLayer& layer, const RenderLayer& intermediateLayer, bool& sawIntermediateLayer)
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to