⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 294902 in webkit


Ignore:
Timestamp:
May 26, 2022, 3:22:08 PM (4 years ago)
Author:
Alan Bujtas
Message:

Do not issue repaint when the ancestor layer has already been scheduled for one
​https://bugs.webkit.org/show_bug.cgi?id=240728

Reviewed by Simon Fraser.

When a renderer needs repaint, we walk the layer tree to search for the repaint container (root for all the paints).
If we find a layer between the renderer and the repaint container that has already been scheduled for a full repaint
we know that this repaint is redundant and will be covered by the ancestor layer.
Since layers paint their overflow content, this works even when the renderer "sticks out" of the ancestor layer's renderer's border box (i.e. produces ink/scrollable overflow).

  • Source/WebCore/rendering/RenderLayer.cpp:

(WebCore::RenderLayer::enclosingCompositingLayerForRepaint const):
(WebCore::RenderLayer::clipCrossesPaintingBoundary const):
(WebCore::RenderLayer::calculateClipRects const):

  • Source/WebCore/rendering/RenderLayer.h:

(WebCore::RenderLayer::needsFullRepaint const):

  • Source/WebCore/rendering/RenderLayerCompositor.cpp:

(WebCore::RenderLayerCompositor::repaintInCompositedAncestor):

  • Source/WebCore/rendering/RenderObject.cpp:

(WebCore::RenderObject::containerForRepaint const):
(WebCore::fullRepaintIsScheduled): This covers the cases when the content is embedded inside an iframe and the iframe's view is not composited.
(WebCore::RenderObject::repaint const):
(WebCore::RenderObject::repaintRectangle const):

  • Source/WebCore/rendering/RenderView.cpp:

(WebCore::RenderView::paintBoxDecorations):

Canonical link: ​https://commits.webkit.org/251025@main

Location:
trunk/Source/WebCore/rendering
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/rendering/RenderLayer.cpp

    r294699 r294902  
    20252025}
    20262026
    2027 RenderLayer* RenderLayer::enclosingCompositingLayerForRepaint(IncludeSelfOrNot includeSelf) const
     2027RenderLayer::EnclosingCompositingLayerStatus RenderLayer::enclosingCompositingLayerForRepaint(IncludeSelfOrNot includeSelf) const
    20282028{
    20292029    auto repaintTargetForLayer = [](const RenderLayer& layer) -> RenderLayer* {
    … …  
    20362036        return nullptr;
    20372037    };
    2038 
     2038    auto isEligibleForFullRepaintCheck = [&](const auto& layer) {
     2039        return layer.isSelfPaintingLayer() && !layer.renderer().hasPotentiallyScrollableOverflow() && !is<RenderView>(layer.renderer());
     2040    };
     2041
     2042    auto fullRepaintAlreadyScheduled = isEligibleForFullRepaintCheck(*this) && needsFullRepaint();
    20392043    RenderLayer* repaintTarget = nullptr;
    20402044    if (includeSelf == IncludeSelf && (repaintTarget = repaintTargetForLayer(*this)))
    2041         return repaintTarget;
     2045        return { fullRepaintAlreadyScheduled, repaintTarget };
    20422046
    20432047    for (const RenderLayer* curr = paintOrderParent(); curr; curr = curr->paintOrderParent()) {
     2048        fullRepaintAlreadyScheduled = fullRepaintAlreadyScheduled || (isEligibleForFullRepaintCheck(*curr) && curr->needsFullRepaint());
    20442049        if ((repaintTarget = repaintTargetForLayer(*curr)))
    2045             return repaintTarget;
     2050            return { fullRepaintAlreadyScheduled, repaintTarget };
    20462051    }
    20472052         
    2048     return nullptr;
     2053    return { };
    20492054}
    20502055
    … …  
    46134618{
    46144619    return parent()->enclosingPaginationLayer(IncludeCompositedPaginatedLayers) != enclosingPaginationLayer(IncludeCompositedPaginatedLayers)
    4615         || parent()->enclosingCompositingLayerForRepaint() != enclosingCompositingLayerForRepaint();
     4620        || parent()->enclosingCompositingLayerForRepaint().layer != enclosingCompositingLayerForRepaint().layer;
    46164621}
    46174622
    … …  
    58125817{
    58135818#if ENABLE(ASYNC_SCROLLING)
    5814     auto* compositingLayer = enclosingCompositingLayerForRepaint();
     5819    auto* compositingLayer = enclosingCompositingLayerForRepaint().layer;
    58155820
    58165821    auto shouldInvalidate = [&] {
  • trunk/Source/WebCore/rendering/RenderLayer.h

    r294699 r294902  
    591591    // Enclosing compositing layer; if includeSelf is true, may return this.
    592592    RenderLayer* enclosingCompositingLayer(IncludeSelfOrNot = IncludeSelf) const;
    593     RenderLayer* enclosingCompositingLayerForRepaint(IncludeSelfOrNot = IncludeSelf) const;
     593    struct EnclosingCompositingLayerStatus {
     594        bool fullRepaintAlreadyScheduled { false };
     595        RenderLayer* layer { nullptr };
     596    };
     597    EnclosingCompositingLayerStatus enclosingCompositingLayerForRepaint(IncludeSelfOrNot = IncludeSelf) const;
    594598    // Ancestor compositing layer, excluding this.
    595599    RenderLayer* ancestorCompositingLayer() const { return enclosingCompositingLayer(ExcludeSelf); }
    … …  
    722726    void setRepaintStatus(RepaintStatus status) { m_repaintStatus = status; }
    723727    RepaintStatus repaintStatus() const { return static_cast<RepaintStatus>(m_repaintStatus); }
     728    bool needsFullRepaint() const { return m_repaintStatus == NeedsFullRepaint || m_repaintStatus == NeedsFullRepaintForPositionedMovementLayout; }
    724729
    725730    LayoutUnit staticInlinePosition() const { return m_offsetForPosition.width(); }
  • trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp

    r294699 r294902  
    19571957void RenderLayerCompositor::repaintInCompositedAncestor(RenderLayer& layer, const LayoutRect& rect)
    19581958{
    1959     auto* compositedAncestor = layer.enclosingCompositingLayerForRepaint(ExcludeSelf);
     1959    auto* compositedAncestor = layer.enclosingCompositingLayerForRepaint(ExcludeSelf).layer;
    19601960    if (!compositedAncestor)
    19611961        return;
  • trunk/Source/WebCore/rendering/RenderObject.cpp

    r294699 r294902  
    861861{
    862862    RenderLayerModelObject* repaintContainer = nullptr;
     863    auto fullRepaintAlreadyScheduled = false;
    863864
    864865    if (view().usesCompositing()) {
    865         if (RenderLayer* parentLayer = enclosingLayer()) {
    866             RenderLayer* compLayer = parentLayer->enclosingCompositingLayerForRepaint();
    867             if (compLayer)
    868                 repaintContainer = &compLayer->renderer();
     866        if (auto* parentLayer = enclosingLayer()) {
     867            auto compLayerStatus = parentLayer->enclosingCompositingLayerForRepaint();
     868            if (compLayerStatus.layer) {
     869                repaintContainer = &compLayerStatus.layer->renderer();
     870                fullRepaintAlreadyScheduled = compLayerStatus.fullRepaintAlreadyScheduled;
     871            }
    869872        }
    870873    }
    871874    if (view().hasSoftwareFilters()) {
    872         if (RenderLayer* parentLayer = enclosingLayer()) {
    873             RenderLayer* enclosingFilterLayer = parentLayer->enclosingFilterLayer();
    874             if (enclosingFilterLayer)
    875                 return { false, &enclosingFilterLayer->renderer() };
     875        if (auto* parentLayer = enclosingLayer()) {
     876            auto* enclosingFilterLayer = parentLayer->enclosingFilterLayer();
     877            if (enclosingFilterLayer) {
     878                fullRepaintAlreadyScheduled = parentLayer->needsFullRepaint();
     879                return { fullRepaintAlreadyScheduled, &enclosingFilterLayer->renderer() };
     880            }
    876881        }
    877882    }
    … …  
    888893            repaintContainer = parentRenderFragmentedFlow;
    889894    }
    890     return { false, repaintContainer };
     895    return { fullRepaintAlreadyScheduled, repaintContainer };
    891896}
    892897
    … …  
    962967}
    963968
     969static inline bool fullRepaintIsScheduled(const RenderObject& renderer)
     970{
     971    if (!renderer.view().usesCompositing() && !renderer.document().ownerElement())
     972        return false;
     973    for (auto* ancestorLayer = renderer.enclosingLayer(); ancestorLayer; ancestorLayer = ancestorLayer->paintOrderParent()) {
     974        if (ancestorLayer->needsFullRepaint())
     975            return true;
     976    }
     977    return false;
     978}
     979
    964980void RenderObject::repaint() const
    965981{
    … …  
    973989
    974990    auto repaintContainer = containerForRepaint();
     991    if (!repaintContainer.renderer)
     992        repaintContainer = { fullRepaintIsScheduled(*this), &view };
     993
    975994    if (!repaintContainer.fullRepaintIsScheduled)
    976995        repaintUsingContainer(repaintContainer.renderer, clippedOverflowRectForRepaint(repaintContainer.renderer));
    … …  
    9931012
    9941013    auto repaintContainer = containerForRepaint();
     1014    if (!repaintContainer.renderer)
     1015        repaintContainer = { fullRepaintIsScheduled(*this), &view };
     1016
    9951017    if (!repaintContainer.fullRepaintIsScheduled)
    9961018        repaintUsingContainer(repaintContainer.renderer, computeRectForRepaint(dirtyRect, repaintContainer.renderer), shouldClipToLayer);
  • trunk/Source/WebCore/rendering/RenderView.cpp

    r294699 r294902  
    381381        }
    382382
    383         if (RenderLayer* compositingLayer = layer->enclosingCompositingLayerForRepaint()) {
     383        if (auto* compositingLayer = layer->enclosingCompositingLayerForRepaint().layer) {
    384384            if (!compositingLayer->backing()->paintsIntoWindow()) {
    385385                frameView().setCannotBlitToWindow();
Note: See TracChangeset for help on using the changeset viewer.