Changeset 257920 in webkit


Ignore:
Timestamp:
Mar 5, 2020 9:18:00 AM (4 years ago)
Author:
Simon Fraser
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):

Location:
trunk/Source/WebCore
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r257919 r257920  
     12020-03-05  Simon Fraser  <simon.fraser@apple.com>
     2
     3        Track "scrolling scope" on RenderLayers
     4        https://bugs.webkit.org/show_bug.cgi?id=208620
     5
     6        Reviewed by Zalan Bujtas.
     7
     8        Keep track of a "scrolling scope" on RenderLayers. Layers that share a scrolling scope
     9        get scrolled by some common async-scrollable containing-block ancestor. The scope is just
     10        a unique identifier.
     11       
     12        Each layer has two scopes; a "box" scope that applies to the background/borders, and
     13        a "content" scope that applies to (potentially) scrollable content. For most layers,
     14        these will be the same, and shared with the layer's containing block ancestor layer.
     15
     16        For async-scrollable overflow, "box" scope is shared with the cb ancestor, but "content" scope
     17        will have a new value that applies to all the layers moved by that scroller.
     18
     19        Having this value makes it easy to ask the question "is this layer scrolled by some ancestor",
     20        which is a tricky computation for things like a position:absolute layer inside a non-containing block
     21        stacking context overflow:scroll. Also, position:fixed whose containing block is the root will share
     22        the scrolling scope of the root.
     23
     24        No behavior change.
     25
     26        * rendering/RenderLayer.cpp:
     27        (WebCore::nextScrollingScope):
     28        (WebCore::RenderLayer::RenderLayer):
     29        (WebCore::RenderLayer::updateLayerPositions):
     30        (WebCore::RenderLayer::updateLayerPosition):
     31        (WebCore::outputPaintOrderTreeLegend):
     32        (WebCore::outputPaintOrderTreeRecursive):
     33        * rendering/RenderLayer.h:
     34        * rendering/RenderLayerCompositor.cpp:
     35        (WebCore::isScrolledByOverflowScrollLayer):
     36
    1372020-03-05  youenn fablet  <youenn@apple.com>
    238
  • trunk/Source/WebCore/rendering/RenderLayer.cpp

    r255957 r257920  
    284284#endif
    285285
     286static ScrollingScope nextScrollingScope()
     287{
     288    static ScrollingScope currentScope = 0;
     289    return ++currentScope;
     290}
     291
    286292DEFINE_ALLOCATOR_WITH_HEAP_IDENTIFIER(RenderLayer);
    287293
     
    344350    m_isSelfPaintingLayer = shouldBeSelfPaintingLayer();
    345351
     352    if (isRenderViewLayer())
     353        m_boxScrollingScope = m_contentsScrollingScope = nextScrollingScope();
     354
    346355    if (!renderer().firstChild()) {
    347356        m_visibleContentStatusDirty = false;
     
    959968    // Clear our cached clip rect information.
    960969    clearClipRects();
    961    
     970
    962971    if (hasOverflowControls()) {
    963972        LayoutSize offsetFromRoot;
     
    17351744            localPoint -= toLayoutSize(positionedParent->scrollPosition());
    17361745       
    1737         if (renderer().isOutOfFlowPositioned() && positionedParent->renderer().isInFlowPositioned() && is<RenderInline>(positionedParent->renderer())) {
     1746        if (positionedParent->renderer().isInFlowPositioned() && is<RenderInline>(positionedParent->renderer())) {
    17381747            LayoutSize offset = downcast<RenderInline>(positionedParent->renderer()).offsetForInFlowPositionedInline(&downcast<RenderBox>(renderer()));
    17391748            localPoint += offset;
    17401749        }
    1741     } else if (parent()) {
    1742         if (parent()->renderer().hasOverflowClip())
     1750
     1751        ASSERT(positionedParent->contentsScrollingScope());
     1752        m_boxScrollingScope = positionedParent->contentsScrollingScope();
     1753    } else if (auto* parentLayer = parent()) {
     1754        if (parentLayer->renderer().hasOverflowClip())
    17431755            localPoint -= toLayoutSize(parent()->scrollPosition());
    1744     }
    1745    
     1756
     1757        ASSERT(parentLayer->contentsScrollingScope());
     1758        m_boxScrollingScope = parentLayer->contentsScrollingScope();
     1759    }
     1760
     1761    if (hasCompositedScrollableOverflow()) {
     1762        if (!m_contentsScrollingScope)
     1763            m_contentsScrollingScope = nextScrollingScope();
     1764    } else if (!m_contentsScrollingScope)
     1765        m_contentsScrollingScope = m_boxScrollingScope;
     1766
    17461767    bool positionOrOffsetChanged = false;
    17471768    if (renderer().isInFlowPositioned()) {
     
    70987119        "Dirty (z)-lists, Dirty (n)ormal flow lists\n"
    70997120        "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"
    7100         "Update needs:    post-(l)ayout requirements, (g)eometry, (k)ids geometry, (c)onfig, layer conne(x)ion, (s)crolling tree\n";
     7121        "Update needs:    post-(l)ayout requirements, (g)eometry, (k)ids geometry, (c)onfig, layer conne(x)ion, (s)crolling tree\n"
     7122        "Scrolling scope: box contents\n";
    71017123    stream.nextLine();
    71027124}
     
    71697191    stream << " ";
    71707192
     7193    stream << layer.boxScrollingScope();
     7194    stream << " ";
     7195    stream << layer.contentsScrollingScope();
     7196
     7197    stream << " ";
     7198
    71717199    outputIdent(stream, depth);
    71727200
  • trunk/Source/WebCore/rendering/RenderLayer.h

    r255957 r257920  
    5454#include "ScrollableArea.h"
    5555#include <memory>
     56#include <wtf/Markable.h>
    5657#include <wtf/WeakPtr.h>
    5758
     
    139140};
    140141
     142using ScrollingScope = uint64_t;
     143
    141144DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(RenderLayer);
    142145class RenderLayer final : public ScrollableArea {
     
    862865    void setHasCompositedScrollingAncestor(bool hasCompositedScrollingAncestor) { m_hasCompositedScrollingAncestor = hasCompositedScrollingAncestor; }
    863866
     867    // Layers with the same ScrollingScope are scrolled by some common ancestor scroller. Used for async scrolling.
     868    Optional<ScrollingScope> boxScrollingScope() const { return m_boxScrollingScope; }
     869    Optional<ScrollingScope> contentsScrollingScope() const { return m_contentsScrollingScope; }
     870
    864871    bool paintsWithTransparency(OptionSet<PaintBehavior> paintBehavior) const
    865872    {
     
    13221329    IntPoint m_cachedOverlayScrollbarOffset;
    13231330
     1331    Markable<ScrollingScope, IntegralMarkableTraits<ScrollingScope, 0>> m_boxScrollingScope;
     1332    Markable<ScrollingScope, IntegralMarkableTraits<ScrollingScope, 0>> m_contentsScrollingScope;
     1333
    13241334    std::unique_ptr<RenderMarquee> m_marquee; // Used for <marquee>.
    13251335   
  • trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp

    r257689 r257920  
    31793179static bool isScrolledByOverflowScrollLayer(const RenderLayer& layer, const RenderLayer& overflowScrollLayer)
    31803180{
    3181     bool scrolledByOverflowScroll = false;
    3182     traverseAncestorLayers(layer, [&](const RenderLayer& ancestorLayer, bool inContainingBlockChain, bool) {
    3183         if (&ancestorLayer == &overflowScrollLayer) {
    3184             scrolledByOverflowScroll = inContainingBlockChain;
    3185             return AncestorTraversal::Stop;
    3186         }
    3187         return AncestorTraversal::Continue;
    3188     });
    3189     return scrolledByOverflowScroll;
     3181    return layer.boxScrollingScope() == overflowScrollLayer.contentsScrollingScope();
    31903182}
    31913183
Note: See TracChangeset for help on using the changeset viewer.