Changeset 220479 in webkit


Ignore:
Timestamp:
Aug 9, 2017 2:03:03 PM (7 years ago)
Author:
hyatt@apple.com
Message:

[Repaint from Layout Removal] Move layer repaint rects into a map
https://bugs.webkit.org/show_bug.cgi?id=175393

Reviewed by Zalan Bujtas.

Move the two repaint rects held by RenderLayer into a RenderLayerModelObject -> RepaintLayoutRects hash map.
RepaintLayoutRects is a new struct that holds both rects.

Eventually more objects than just self painting layers will be caching repaint rects, so this takes a first
step towards having a common cache for these repaint rects. In addition this change saves memory, since
layers that aren't self-painting no longer have empty repaint rects taking up space in RenderLayer.

  • rendering/RenderBlockLineLayout.cpp:

(WebCore::RenderBlockFlow::layoutRunsAndFloats):

  • rendering/RenderLayer.cpp:

(WebCore::RenderLayer::RenderLayer):
(WebCore::RenderLayer::updateLayerPositions):
(WebCore::RenderLayer::repaintRectIncludingNonCompositingDescendants):
(WebCore::RenderLayer::computeRepaintRects):
(WebCore::RenderLayer::clearRepaintRects):
(WebCore::RenderLayer::updateLayerPositionsAfterScroll):
(WebCore::RenderLayer::scrollTo):

  • rendering/RenderLayer.h:
  • rendering/RenderLayerModelObject.cpp:

(WebCore::RepaintLayoutRects::RepaintLayoutRects):
(WebCore::RenderLayerModelObject::willBeDestroyed):
(WebCore::RenderLayerModelObject::destroyLayer):
(WebCore::RenderLayerModelObject::styleDidChange):
(WebCore::RenderLayerModelObject::hasRepaintLayoutRects):
(WebCore::RenderLayerModelObject::setRepaintLayoutRects):
(WebCore::RenderLayerModelObject::clearRepaintLayoutRects):
(WebCore::RenderLayerModelObject::repaintLayoutRects):
(WebCore::RenderLayerModelObject::computeRepaintLayoutRects):

  • rendering/RenderLayerModelObject.h:

(WebCore::RepaintLayoutRects::RepaintLayoutRects):

Location:
trunk/Source/WebCore
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r220478 r220479  
     12017-08-09  Dave Hyatt  <hyatt@apple.com>
     2
     3        [Repaint from Layout Removal] Move layer repaint rects into a map
     4        https://bugs.webkit.org/show_bug.cgi?id=175393
     5
     6        Reviewed by Zalan Bujtas.
     7
     8        Move the two repaint rects held by RenderLayer into a RenderLayerModelObject -> RepaintLayoutRects hash map.
     9        RepaintLayoutRects is a new struct that holds both rects.
     10
     11        Eventually more objects than just self painting layers will be caching repaint rects, so this takes a first
     12        step towards having a common cache for these repaint rects. In addition this change saves memory, since
     13        layers that aren't self-painting no longer have empty repaint rects taking up space in RenderLayer.
     14
     15        * rendering/RenderBlockLineLayout.cpp:
     16        (WebCore::RenderBlockFlow::layoutRunsAndFloats):
     17        * rendering/RenderLayer.cpp:
     18        (WebCore::RenderLayer::RenderLayer):
     19        (WebCore::RenderLayer::updateLayerPositions):
     20        (WebCore::RenderLayer::repaintRectIncludingNonCompositingDescendants):
     21        (WebCore::RenderLayer::computeRepaintRects):
     22        (WebCore::RenderLayer::clearRepaintRects):
     23        (WebCore::RenderLayer::updateLayerPositionsAfterScroll):
     24        (WebCore::RenderLayer::scrollTo):
     25        * rendering/RenderLayer.h:
     26        * rendering/RenderLayerModelObject.cpp:
     27        (WebCore::RepaintLayoutRects::RepaintLayoutRects):
     28        (WebCore::RenderLayerModelObject::willBeDestroyed):
     29        (WebCore::RenderLayerModelObject::destroyLayer):
     30        (WebCore::RenderLayerModelObject::styleDidChange):
     31        (WebCore::RenderLayerModelObject::hasRepaintLayoutRects):
     32        (WebCore::RenderLayerModelObject::setRepaintLayoutRects):
     33        (WebCore::RenderLayerModelObject::clearRepaintLayoutRects):
     34        (WebCore::RenderLayerModelObject::repaintLayoutRects):
     35        (WebCore::RenderLayerModelObject::computeRepaintLayoutRects):
     36        * rendering/RenderLayerModelObject.h:
     37        (WebCore::RepaintLayoutRects::RepaintLayoutRects):
     38
    1392017-08-09  Sam Weinig  <sam@webkit.org>
    240
  • trunk/Source/WebCore/rendering/RenderBlockLineLayout.cpp

    r219190 r220479  
    12821282    if (layoutState.isFullLayout() && hasInlineChild && !selfNeedsLayout()) {
    12831283        setNeedsLayout(MarkOnlyThis); // Mark as needing a full layout to force us to repaint.
    1284         if (!view().doingFullRepaint() && hasSelfPaintingLayer() && layer()->hasComputedRepaintRect()) {
     1284        if (!view().doingFullRepaint() && hasSelfPaintingLayer() && hasRepaintLayoutRects()) {
    12851285            // Because we waited until we were already inside layout to discover
    12861286            // that the block really needed a full layout, we missed our chance to repaint the layer
    12871287            // before layout started.  Luckily the layer has cached the repaint rect for its original
    12881288            // position and size, and so we can use that to make a repaint happen now.
    1289             repaintUsingContainer(containerForRepaint(), layer()->repaintRect());
     1289            repaintUsingContainer(containerForRepaint(), repaintLayoutRects().m_repaintRect);
    12901290        }
    12911291    }
  • trunk/Source/WebCore/rendering/RenderLayer.cpp

    r219961 r220479  
    311311#endif
    312312    , m_hasFilterInfo(false)
    313     , m_hasComputedRepaintRect(false)
    314313#if ENABLE(CSS_COMPOSITING)
    315314    , m_blendMode(BlendModeNormal)
     
    517516
    518517        RenderLayerModelObject* repaintContainer = renderer().containerForRepaint();
    519         LayoutRect oldRepaintRect = m_repaintRect;
    520         LayoutRect oldOutlineBox = m_outlineBox;
     518       
     519        auto hadRepaintLayoutRects = renderer().hasRepaintLayoutRects();
     520        RepaintLayoutRects oldRects = hadRepaintLayoutRects ? renderer().repaintLayoutRects() : RepaintLayoutRects();
    521521        computeRepaintRects(repaintContainer, geometryMap);
    522 
     522       
     523        auto hasRepaintLayoutRects = renderer().hasRepaintLayoutRects();
     524        RepaintLayoutRects newRects = hasRepaintLayoutRects ? renderer().repaintLayoutRects() : RepaintLayoutRects();
    523525        // FIXME: Should ASSERT that value calculated for m_outlineBox using the cached offset is the same
    524526        // as the value not using the cached offset, but we can't due to https://bugs.webkit.org/show_bug.cgi?id=37048
    525         if ((flags & CheckForRepaint) && m_hasComputedRepaintRect) {
     527        if ((flags & CheckForRepaint) && hasRepaintLayoutRects) {
    526528            if (!renderer().view().printing()) {
    527529                bool didRepaint = false;
    528530                if (m_repaintStatus & NeedsFullRepaint) {
    529                     renderer().repaintUsingContainer(repaintContainer, oldRepaintRect);
    530                     if (m_repaintRect != oldRepaintRect) {
    531                         renderer().repaintUsingContainer(repaintContainer, m_repaintRect);
     531                    if (hadRepaintLayoutRects)
     532                        renderer().repaintUsingContainer(repaintContainer, oldRects.m_repaintRect);
     533                    if (!hadRepaintLayoutRects || newRects.m_repaintRect != oldRects.m_repaintRect) {
     534                        renderer().repaintUsingContainer(repaintContainer, newRects.m_repaintRect);
    532535                        didRepaint = true;
    533536                    }
    534537                } else if (shouldRepaintAfterLayout()) {
    535                     renderer().repaintAfterLayoutIfNeeded(repaintContainer, oldRepaintRect, oldOutlineBox, &m_repaintRect, &m_outlineBox);
     538                    // FIXME: We will convert this to just take the old and new RepaintLayoutRects once
     539                    // we change other callers to use RepaintLayoutRects.
     540                    renderer().repaintAfterLayoutIfNeeded(repaintContainer, oldRects.m_repaintRect, oldRects.m_outlineBox, &newRects.m_repaintRect, &newRects.m_outlineBox);
    536541                    didRepaint = true;
    537542                }
     
    602607LayoutRect RenderLayer::repaintRectIncludingNonCompositingDescendants() const
    603608{
    604     LayoutRect repaintRect = m_repaintRect;
     609    LayoutRect repaintRect = renderer().repaintLayoutRects().m_repaintRect;
    605610    for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) {
    606611        // Don't include repaint rects for composited child layers; they will paint themselves and have a different origin.
     
    798803{
    799804    ASSERT(!m_visibleContentStatusDirty);
    800 
    801     if (!isSelfPaintingLayer()) {
    802         clearRepaintRects();
    803         return;
    804     }
    805    
    806     m_hasComputedRepaintRect = true;
    807     m_repaintRect = renderer().clippedOverflowRectForRepaint(repaintContainer);
    808     m_outlineBox = renderer().outlineBoundsForRepaint(repaintContainer, geometryMap);
    809 }
    810 
     805    renderer().computeRepaintLayoutRects(repaintContainer, geometryMap);
     806}
    811807
    812808void RenderLayer::computeRepaintRectsIncludingDescendants()
     
    825821    ASSERT(!m_visibleContentStatusDirty);
    826822
    827     m_hasComputedRepaintRect = false;
    828     m_repaintRect = LayoutRect();
    829     m_outlineBox = LayoutRect();
     823    renderer().clearRepaintLayoutRects();
    830824}
    831825
     
    890884    } else {
    891885        // Check that our cached rects are correct.
    892         ASSERT(!m_hasComputedRepaintRect || (m_repaintRect == renderer().clippedOverflowRectForRepaint(renderer().containerForRepaint())));
    893         ASSERT(!m_hasComputedRepaintRect || m_outlineBox == renderer().outlineBoundsForRepaint(renderer().containerForRepaint()));
     886        ASSERT(!renderer().hasRepaintLayoutRects() || renderer().repaintLayoutRects().m_repaintRect == renderer().clippedOverflowRectForRepaint(renderer().containerForRepaint()));
     887        ASSERT(!renderer().hasRepaintLayoutRects() || renderer().repaintLayoutRects().m_outlineBox == renderer().outlineBoundsForRepaint(renderer().containerForRepaint()));
    894888    }
    895889   
     
    24412435    frame.selection().setCaretRectNeedsUpdate();
    24422436   
    2443     LayoutRect rectForRepaint = m_hasComputedRepaintRect ? m_repaintRect : renderer().clippedOverflowRectForRepaint(repaintContainer);
     2437    LayoutRect rectForRepaint = renderer().hasRepaintLayoutRects() ? renderer().repaintLayoutRects().m_repaintRect : renderer().clippedOverflowRectForRepaint(repaintContainer);
    24442438
    24452439    FloatQuad quadForFakeMouseMoveEvent = FloatQuad(rectForRepaint);
  • trunk/Source/WebCore/rendering/RenderLayer.h

    r218396 r220479  
    582582   
    583583    // Return a cached repaint rect, computed relative to the layer renderer's containerForRepaint.
    584     bool hasComputedRepaintRect() const { return m_hasComputedRepaintRect; }
    585     LayoutRect repaintRect() const { ASSERT(hasComputedRepaintRect()); return m_repaintRect; }
     584    bool hasComputedRepaintRects() const { return renderer().hasRepaintLayoutRects(); }
    586585    LayoutRect repaintRectIncludingNonCompositingDescendants() const;
    587586
     
    11161115
    11171116    bool m_hasFilterInfo : 1;
    1118    
    1119     bool m_hasComputedRepaintRect : 1;
    11201117
    11211118#if ENABLE(CSS_COMPOSITING)
     
    11331130    RenderLayer* m_first;
    11341131    RenderLayer* m_last;
    1135 
    1136     LayoutRect m_repaintRect; // Cached repaint rects. Used by layout.
    1137     LayoutRect m_outlineBox;
    11381132
    11391133    // Our current relative position offset.
  • trunk/Source/WebCore/rendering/RenderLayerModelObject.cpp

    r214173 r220479  
    3939bool RenderLayerModelObject::s_layerWasSelfPainting = false;
    4040
     41typedef WTF::HashMap<const RenderLayerModelObject*, RepaintLayoutRects> RepaintLayoutRectsMap;
     42static RepaintLayoutRectsMap* gRepaintLayoutRectsMap = nullptr;
     43
     44RepaintLayoutRects::RepaintLayoutRects(const RenderLayerModelObject& renderer, const RenderLayerModelObject* repaintContainer, const RenderGeometryMap* geometryMap)
     45    : m_repaintRect(renderer.clippedOverflowRectForRepaint(repaintContainer))
     46    , m_outlineBox(renderer.outlineBoundsForRepaint(repaintContainer, geometryMap))
     47{
     48}
     49
    4150RenderLayerModelObject::RenderLayerModelObject(Element& element, RenderStyle&& style, BaseTypeFlags baseTypeFlags)
    4251    : RenderElement(element, WTFMove(style), baseTypeFlags | RenderLayerModelObjectFlag)
     
    6271
    6372    RenderElement::willBeDestroyed();
    64 
     73   
     74    clearRepaintLayoutRects();
     75   
    6576    // Our layer should have been destroyed and cleared by now
    6677    ASSERT(!hasLayer());
     
    7283    ASSERT(!hasLayer()); // Callers should have already called setHasLayer(false)
    7384    ASSERT(m_layer);
     85    if (m_layer->isSelfPaintingLayer())
     86        clearRepaintLayoutRects();
    7487    m_layer = nullptr;
    7588}
     
    167180        setHasReflection(false);
    168181        // Repaint the about to be destroyed self-painting layer when style change also triggers repaint.
    169         if (layer()->isSelfPaintingLayer() && layer()->repaintStatus() == NeedsFullRepaint && layer()->hasComputedRepaintRect())
    170             repaintUsingContainer(containerForRepaint(), layer()->repaintRect());
     182        if (layer()->isSelfPaintingLayer() && layer()->repaintStatus() == NeedsFullRepaint && hasRepaintLayoutRects())
     183            repaintUsingContainer(containerForRepaint(), repaintLayoutRects().m_repaintRect);
    171184        layer()->removeOnlyThisLayer(); // calls destroyLayer() which clears m_layer
    172185        if (s_wasFloating && isFloating())
     
    236249}
    237250
     251bool RenderLayerModelObject::hasRepaintLayoutRects() const
     252{
     253    return gRepaintLayoutRectsMap && gRepaintLayoutRectsMap->contains(this);
     254}
     255
     256void RenderLayerModelObject::setRepaintLayoutRects(const RepaintLayoutRects& rects)
     257{
     258    if (!gRepaintLayoutRectsMap)
     259        gRepaintLayoutRectsMap = new RepaintLayoutRectsMap();
     260    gRepaintLayoutRectsMap->set(this, rects);
     261}
     262
     263void RenderLayerModelObject::clearRepaintLayoutRects()
     264{
     265    if (gRepaintLayoutRectsMap)
     266        gRepaintLayoutRectsMap->remove(this);
     267}
     268
     269RepaintLayoutRects RenderLayerModelObject::repaintLayoutRects() const
     270{
     271    if (!hasRepaintLayoutRects())
     272        return RepaintLayoutRects();
     273    return gRepaintLayoutRectsMap->get(this);
     274}
     275
     276void RenderLayerModelObject::computeRepaintLayoutRects(const RenderLayerModelObject* repaintContainer, const RenderGeometryMap* geometryMap)
     277{
     278    if (!m_layer || !m_layer->isSelfPaintingLayer())
     279        clearRepaintLayoutRects();
     280    else
     281        setRepaintLayoutRects(RepaintLayoutRects(*this, repaintContainer, geometryMap));
     282}
     283
    238284} // namespace WebCore
    239285
  • trunk/Source/WebCore/rendering/RenderLayerModelObject.h

    r214173 r220479  
    2929class RenderLayer;
    3030
     31struct RepaintLayoutRects {
     32    LayoutRect m_repaintRect; // This rect is clipped by enclosing objects (e.g., overflow:hidden).
     33    LayoutRect m_outlineBox; // This rect is unclipped.
     34
     35    RepaintLayoutRects(const RenderLayerModelObject& renderer, const RenderLayerModelObject* repaintContainer, const RenderGeometryMap* = nullptr);
     36    RepaintLayoutRects() { };
     37};
     38
    3139class RenderLayerModelObject : public RenderElement {
    3240public:
     
    5260
    5361    bool shouldPlaceBlockDirectionScrollbarOnLeft() const;
     62   
     63    void computeRepaintLayoutRects(const RenderLayerModelObject* repaintContainer, const RenderGeometryMap* = nullptr);
     64
     65    RepaintLayoutRects repaintLayoutRects() const;
     66   
     67    bool hasRepaintLayoutRects() const;
     68    void setRepaintLayoutRects(const RepaintLayoutRects&);
     69    void clearRepaintLayoutRects();
    5470
    5571protected:
Note: See TracChangeset for help on using the changeset viewer.