Ignore:
Timestamp:
Jun 19, 2022, 8:57:23 PM (3 years ago)
Author:
Alan Bujtas
Message:

REGRESSION (r294902): Content with continuation leaves decoration bits behind when removed
https://bugs.webkit.org/show_bug.cgi?id=241734
<rdar://95308322>

Reviewed by Simon Fraser.

This patch ensures that when a renderer is removed we always issue a repaint regardless of what the associated layer's repaint bit says.

  1. after r294902, repaint is not issued anymore if either the associated or an ancestor layer have the "full repaint" bit set.
  2. such layer-driven repaints happen after layout.

In some dynamic content cases, the layer may be removed before layout happens. This patch ensures that we preemptively issue such repaints.

  • LayoutTests/fast/repaint/force-repaint-when-layer-is-destroyed-expected.txt: Added.
  • LayoutTests/fast/repaint/force-repaint-when-layer-is-destroyed.html: Added.
  • Source/WebCore/rendering/RenderLayerModelObject.cpp: Force (full) repaint when the renderer is being destroyed (detached -> non-internal move).

(WebCore::RenderLayerModelObject::willBeRemovedFromTree):

  • Source/WebCore/rendering/RenderLayerModelObject.h:
  • Source/WebCore/rendering/RenderObject.cpp: move duplicated code from repaint() and repaintRectangle() to issueRepaint().

Canonical link: https://commits.webkit.org/251670@main

File:
1 edited

Legend:

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

    r294902 r295665  
    978978}
    979979
    980 void RenderObject::repaint() const
    981 {
    982     // Don't repaint if we're unrooted (note that view() still returns the view when unrooted)
    983     if (!isRooted())
    984         return;
    985 
    986     const RenderView& view = this->view();
    987     if (view.printing())
    988         return;
    989 
     980void RenderObject::issueRepaint(std::optional<LayoutRect> partialRepaintRect, ClipRepaintToLayer clipRepaintToLayer, ForceRepaint forceRepaint) const
     981{
    990982    auto repaintContainer = containerForRepaint();
    991983    if (!repaintContainer.renderer)
    992         repaintContainer = { fullRepaintIsScheduled(*this), &view };
    993 
    994     if (!repaintContainer.fullRepaintIsScheduled)
    995         repaintUsingContainer(repaintContainer.renderer, clippedOverflowRectForRepaint(repaintContainer.renderer));
    996 }
    997 
    998 void RenderObject::repaintRectangle(const LayoutRect& r, bool shouldClipToLayer) const
     984        repaintContainer = { fullRepaintIsScheduled(*this), &view() };
     985
     986    if (repaintContainer.fullRepaintIsScheduled && forceRepaint == ForceRepaint::No)
     987        return;
     988
     989    auto repaintRect = partialRepaintRect ? computeRectForRepaint(*partialRepaintRect, repaintContainer.renderer) : clippedOverflowRectForRepaint(repaintContainer.renderer);
     990    repaintUsingContainer(repaintContainer.renderer, repaintRect, clipRepaintToLayer == ClipRepaintToLayer::Yes);
     991}
     992
     993void RenderObject::repaint() const
    999994{
    1000995    // Don't repaint if we're unrooted (note that view() still returns the view when unrooted)
    1001     if (!isRooted())
    1002         return;
    1003 
    1004     const RenderView& view = this->view();
    1005     if (view.printing())
    1006         return;
    1007 
    1008     LayoutRect dirtyRect(r);
     996    if (!isRooted() || view().printing())
     997        return;
     998    issueRepaint();
     999}
     1000
     1001void RenderObject::repaintRectangle(const LayoutRect& repaintRect, bool shouldClipToLayer) const
     1002{
     1003    // Don't repaint if we're unrooted (note that view() still returns the view when unrooted)
     1004    if (!isRooted() || view().printing())
     1005        return;
    10091006    // FIXME: layoutDelta needs to be applied in parts before/after transforms and
    10101007    // repaint containers. https://bugs.webkit.org/show_bug.cgi?id=23308
    1011     dirtyRect.move(view.frameView().layoutContext().layoutDelta());
    1012 
    1013     auto repaintContainer = containerForRepaint();
    1014     if (!repaintContainer.renderer)
    1015         repaintContainer = { fullRepaintIsScheduled(*this), &view };
    1016 
    1017     if (!repaintContainer.fullRepaintIsScheduled)
    1018         repaintUsingContainer(repaintContainer.renderer, computeRectForRepaint(dirtyRect, repaintContainer.renderer), shouldClipToLayer);
     1008    auto dirtyRect = repaintRect;
     1009    dirtyRect.move(view().frameView().layoutContext().layoutDelta());
     1010    issueRepaint(dirtyRect, shouldClipToLayer ? ClipRepaintToLayer::Yes : ClipRepaintToLayer::No);
    10191011}
    10201012
Note: See TracChangeset for help on using the changeset viewer.