Title: [201040] trunk/Source/WebCore
Revision
201040
Author
[email protected]
Date
2016-05-17 14:02:01 -0700 (Tue, 17 May 2016)

Log Message

Optimize layer repaint rect computation and painting.
https://bugs.webkit.org/show_bug.cgi?id=157631

Reviewed by Zalan Bujtas.

This patch changes the computation of repaint rects to be for self-painting layers
only. In addition, hasBoxDecorations() has been changed to hasVisibleBoxDecorations(),
and it will no longer be set for transparent borders.

For scrolling layer position updating, visually empty layers have their repaint rects
cleared, and we don't compute repaint rects during the scroll. We would like to do this
all the time, but computeRepaintRects can be called at times when the visually empty
state is stale/unknown. For now we limit it to scrolling, since we know that the layer's
visually empty state is correct.

* rendering/InlineFlowBox.cpp:
(WebCore::InlineFlowBox::paintBoxDecorations):
* rendering/RenderBlock.cpp:
(WebCore::RenderBlock::paintObject):
* rendering/RenderBlockLineLayout.cpp:
(WebCore::RenderBlockFlow::layoutRunsAndFloats):
* rendering/RenderBox.cpp:
(WebCore::RenderBox::updateFromStyle):
(WebCore::RenderBox::paintBoxDecorations):
* rendering/RenderBoxModelObject.cpp:
(WebCore::RenderBoxModelObject::willBeDestroyed):
(WebCore::RenderBoxModelObject::hasVisibleBoxDecorationStyle):
(WebCore::RenderBoxModelObject::updateFromStyle):
(WebCore::RenderBoxModelObject::hasBoxDecorationStyle): Deleted.
* rendering/RenderBoxModelObject.h:
* rendering/RenderElement.cpp:
(WebCore::RenderElement::styleWillChange):
(WebCore::mustRepaintBackgroundOrBorder):
* rendering/RenderImage.cpp:
(WebCore::RenderImage::imageChanged):
* rendering/RenderInline.cpp:
(WebCore::RenderInline::styleDidChange):
* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::RenderLayer):
(WebCore::RenderLayer::updateLayerPositions):
(WebCore::RenderLayer::repaintRectIncludingNonCompositingDescendants):
(WebCore::RenderLayer::computeRepaintRects):
(WebCore::RenderLayer::clearRepaintRects):
(WebCore::RenderLayer::updateLayerPositionsAfterScroll):
(WebCore::RenderLayer::scrollTo):
(WebCore::RenderLayer::calculateClipRects):
* rendering/RenderLayer.h:
* rendering/RenderLayerBacking.cpp:
(WebCore::RenderLayerBacking::updateDrawsContent):
(WebCore::RenderLayerBacking::compositingOpacity):
(WebCore::hasVisibleBoxDecorations):
(WebCore::canCreateTiledImage):
(WebCore::hasVisibleBoxDecorationsOrBackgroundImage):
(WebCore::supportsDirectBoxDecorationsComposition):
(WebCore::RenderLayerBacking::isSimpleContainerCompositingLayer):
(WebCore::RenderLayerBacking::containsPaintedContent):
(WebCore::RenderLayerBacking::isDirectlyCompositedImage):
(WebCore::hasBoxDecorations): Deleted.
(WebCore::hasBoxDecorationsOrBackgroundImage): Deleted.
* rendering/RenderLayerModelObject.cpp:
(WebCore::RenderLayerModelObject::styleDidChange):
* rendering/RenderNamedFlowFragment.cpp:
(WebCore::RenderNamedFlowFragment::setObjectStyleInRegion):
* rendering/RenderObject.h:
(WebCore::RenderObject::hasVisibleBoxDecorations):
(WebCore::RenderObject::setFloating):
(WebCore::RenderObject::setInline):
(WebCore::RenderObject::computeBackgroundIsKnownToBeObscured):
(WebCore::RenderObject::setSelectionStateIfNeeded):
(WebCore::RenderObject::setHasVisibleBoxDecorations):
(WebCore::RenderObject::invalidateBackgroundObscurationStatus):
(WebCore::RenderObject::hasBoxDecorations): Deleted.
(WebCore::RenderObject::setHasBoxDecorations): Deleted.
* rendering/RenderReplaced.cpp:
(WebCore::RenderReplaced::paint):
* rendering/RenderTable.cpp:
(WebCore::RenderTable::paintObject):
(WebCore::RenderTable::paintBoxDecorations):
* rendering/RenderTableCell.cpp:
(WebCore::RenderTableCell::styleDidChange):
* rendering/RenderWidget.cpp:
(WebCore::RenderWidget::paint):
* rendering/style/BorderData.h:
(WebCore::BorderData::hasBorder):
(WebCore::BorderData::hasVisibleBorder):
(WebCore::BorderData::hasFill):
(WebCore::BorderData::hasBorderRadius):
* rendering/style/RenderStyle.h:
* rendering/svg/RenderSVGRoot.cpp:
(WebCore::RenderSVGRoot::layout):
(WebCore::RenderSVGRoot::styleDidChange):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (201039 => 201040)


--- trunk/Source/WebCore/ChangeLog	2016-05-17 20:38:36 UTC (rev 201039)
+++ trunk/Source/WebCore/ChangeLog	2016-05-17 21:02:01 UTC (rev 201040)
@@ -1,3 +1,97 @@
+2016-05-17  Dave Hyatt  <[email protected]>
+
+        Optimize layer repaint rect computation and painting.
+        https://bugs.webkit.org/show_bug.cgi?id=157631
+
+        Reviewed by Zalan Bujtas.
+
+        This patch changes the computation of repaint rects to be for self-painting layers
+        only. In addition, hasBoxDecorations() has been changed to hasVisibleBoxDecorations(),
+        and it will no longer be set for transparent borders.
+
+        For scrolling layer position updating, visually empty layers have their repaint rects
+        cleared, and we don't compute repaint rects during the scroll. We would like to do this
+        all the time, but computeRepaintRects can be called at times when the visually empty
+        state is stale/unknown. For now we limit it to scrolling, since we know that the layer's
+        visually empty state is correct.
+
+        * rendering/InlineFlowBox.cpp:
+        (WebCore::InlineFlowBox::paintBoxDecorations):
+        * rendering/RenderBlock.cpp:
+        (WebCore::RenderBlock::paintObject):
+        * rendering/RenderBlockLineLayout.cpp:
+        (WebCore::RenderBlockFlow::layoutRunsAndFloats):
+        * rendering/RenderBox.cpp:
+        (WebCore::RenderBox::updateFromStyle):
+        (WebCore::RenderBox::paintBoxDecorations):
+        * rendering/RenderBoxModelObject.cpp:
+        (WebCore::RenderBoxModelObject::willBeDestroyed):
+        (WebCore::RenderBoxModelObject::hasVisibleBoxDecorationStyle):
+        (WebCore::RenderBoxModelObject::updateFromStyle):
+        (WebCore::RenderBoxModelObject::hasBoxDecorationStyle): Deleted.
+        * rendering/RenderBoxModelObject.h:
+        * rendering/RenderElement.cpp:
+        (WebCore::RenderElement::styleWillChange):
+        (WebCore::mustRepaintBackgroundOrBorder):
+        * rendering/RenderImage.cpp:
+        (WebCore::RenderImage::imageChanged):
+        * rendering/RenderInline.cpp:
+        (WebCore::RenderInline::styleDidChange):
+        * rendering/RenderLayer.cpp:
+        (WebCore::RenderLayer::RenderLayer):
+        (WebCore::RenderLayer::updateLayerPositions):
+        (WebCore::RenderLayer::repaintRectIncludingNonCompositingDescendants):
+        (WebCore::RenderLayer::computeRepaintRects):
+        (WebCore::RenderLayer::clearRepaintRects):
+        (WebCore::RenderLayer::updateLayerPositionsAfterScroll):
+        (WebCore::RenderLayer::scrollTo):
+        (WebCore::RenderLayer::calculateClipRects):
+        * rendering/RenderLayer.h:
+        * rendering/RenderLayerBacking.cpp:
+        (WebCore::RenderLayerBacking::updateDrawsContent):
+        (WebCore::RenderLayerBacking::compositingOpacity):
+        (WebCore::hasVisibleBoxDecorations):
+        (WebCore::canCreateTiledImage):
+        (WebCore::hasVisibleBoxDecorationsOrBackgroundImage):
+        (WebCore::supportsDirectBoxDecorationsComposition):
+        (WebCore::RenderLayerBacking::isSimpleContainerCompositingLayer):
+        (WebCore::RenderLayerBacking::containsPaintedContent):
+        (WebCore::RenderLayerBacking::isDirectlyCompositedImage):
+        (WebCore::hasBoxDecorations): Deleted.
+        (WebCore::hasBoxDecorationsOrBackgroundImage): Deleted.
+        * rendering/RenderLayerModelObject.cpp:
+        (WebCore::RenderLayerModelObject::styleDidChange):
+        * rendering/RenderNamedFlowFragment.cpp:
+        (WebCore::RenderNamedFlowFragment::setObjectStyleInRegion):
+        * rendering/RenderObject.h:
+        (WebCore::RenderObject::hasVisibleBoxDecorations):
+        (WebCore::RenderObject::setFloating):
+        (WebCore::RenderObject::setInline):
+        (WebCore::RenderObject::computeBackgroundIsKnownToBeObscured):
+        (WebCore::RenderObject::setSelectionStateIfNeeded):
+        (WebCore::RenderObject::setHasVisibleBoxDecorations):
+        (WebCore::RenderObject::invalidateBackgroundObscurationStatus):
+        (WebCore::RenderObject::hasBoxDecorations): Deleted.
+        (WebCore::RenderObject::setHasBoxDecorations): Deleted.
+        * rendering/RenderReplaced.cpp:
+        (WebCore::RenderReplaced::paint):
+        * rendering/RenderTable.cpp:
+        (WebCore::RenderTable::paintObject):
+        (WebCore::RenderTable::paintBoxDecorations):
+        * rendering/RenderTableCell.cpp:
+        (WebCore::RenderTableCell::styleDidChange):
+        * rendering/RenderWidget.cpp:
+        (WebCore::RenderWidget::paint):
+        * rendering/style/BorderData.h:
+        (WebCore::BorderData::hasBorder):
+        (WebCore::BorderData::hasVisibleBorder):
+        (WebCore::BorderData::hasFill):
+        (WebCore::BorderData::hasBorderRadius):
+        * rendering/style/RenderStyle.h:
+        * rendering/svg/RenderSVGRoot.cpp:
+        (WebCore::RenderSVGRoot::layout):
+        (WebCore::RenderSVGRoot::styleDidChange):
+
 2016-05-17  Filip Pizlo  <[email protected]>
 
         WTF should know about Language

Modified: trunk/Source/WebCore/rendering/InlineFlowBox.cpp (201039 => 201040)


--- trunk/Source/WebCore/rendering/InlineFlowBox.cpp	2016-05-17 20:38:36 UTC (rev 201039)
+++ trunk/Source/WebCore/rendering/InlineFlowBox.cpp	2016-05-17 21:02:01 UTC (rev 201040)
@@ -1366,7 +1366,7 @@
 
     // You can use p::first-line to specify a background. If so, the root line boxes for
     // a line may actually have to paint a background.
-    if (parent() && !renderer().hasBoxDecorations())
+    if (parent() && !renderer().hasVisibleBoxDecorations())
         return;
     const RenderStyle& lineStyle = this->lineStyle();
     if (!parent() && (!isFirstLine() || &lineStyle == &renderer().style()))
@@ -1385,7 +1385,7 @@
 
     // :first-line cannot be used to put borders on a line. Always paint borders with our
     // non-first-line style.
-    if (!parent() || !renderer().style().hasBorderDecoration())
+    if (!parent() || !renderer().style().hasVisibleBorderDecoration())
         return;
     const NinePieceImage& borderImage = renderer().style().borderImage();
     StyleImage* borderImageSource = borderImage.image();

Modified: trunk/Source/WebCore/rendering/RenderBlock.cpp (201039 => 201040)


--- trunk/Source/WebCore/rendering/RenderBlock.cpp	2016-05-17 20:38:36 UTC (rev 201039)
+++ trunk/Source/WebCore/rendering/RenderBlock.cpp	2016-05-17 21:02:01 UTC (rev 201040)
@@ -1539,7 +1539,7 @@
 
     // 1. paint background, borders etc
     if ((paintPhase == PaintPhaseBlockBackground || paintPhase == PaintPhaseChildBlockBackground) && style().visibility() == VISIBLE) {
-        if (hasBoxDecorations()) {
+        if (hasVisibleBoxDecorations()) {
             bool didClipToRegion = false;
             
             RenderNamedFlowFragment* namedFlowFragment = currentRenderNamedFlowFragment();

Modified: trunk/Source/WebCore/rendering/RenderBlockLineLayout.cpp (201039 => 201040)


--- trunk/Source/WebCore/rendering/RenderBlockLineLayout.cpp	2016-05-17 20:38:36 UTC (rev 201039)
+++ trunk/Source/WebCore/rendering/RenderBlockLineLayout.cpp	2016-05-17 21:02:01 UTC (rev 201040)
@@ -1259,7 +1259,7 @@
     // determineStartPosition first will break fast/repaint/line-flow-with-floats-9.html.
     if (layoutState.isFullLayout() && hasInlineChild && !selfNeedsLayout()) {
         setNeedsLayout(MarkOnlyThis); // Mark as needing a full layout to force us to repaint.
-        if (!view().doingFullRepaint() && hasLayer()) {
+        if (!view().doingFullRepaint() && hasSelfPaintingLayer() && layer()->hasComputedRepaintRect()) {
             // Because we waited until we were already inside layout to discover
             // that the block really needed a full layout, we missed our chance to repaint the layer
             // before layout started.  Luckily the layer has cached the repaint rect for its original

Modified: trunk/Source/WebCore/rendering/RenderBox.cpp (201039 => 201040)


--- trunk/Source/WebCore/rendering/RenderBox.cpp	2016-05-17 20:38:36 UTC (rev 201039)
+++ trunk/Source/WebCore/rendering/RenderBox.cpp	2016-05-17 21:02:01 UTC (rev 201040)
@@ -494,7 +494,7 @@
 
     // The root and the RenderView always paint their backgrounds/borders.
     if (isDocElementRenderer || isViewObject)
-        setHasBoxDecorations(true);
+        setHasVisibleBoxDecorations(true);
 
     setFloating(!isOutOfFlowPositioned() && styleToUse.isFloating());
 
@@ -1369,7 +1369,7 @@
     paintBoxShadow(paintInfo, paintRect, style(), Inset);
 
     // The theme will tell us whether or not we should also paint the CSS border.
-    if (bleedAvoidance != BackgroundBleedBackgroundOverBorder && (!style().hasAppearance() || (borderOrBackgroundPaintingIsNeeded && theme().paintBorderOnly(*this, paintInfo, paintRect))) && style().hasBorderDecoration())
+    if (bleedAvoidance != BackgroundBleedBackgroundOverBorder && (!style().hasAppearance() || (borderOrBackgroundPaintingIsNeeded && theme().paintBorderOnly(*this, paintInfo, paintRect))) && style().hasVisibleBorderDecoration())
         paintBorder(paintInfo, paintRect, style(), bleedAvoidance);
 
     if (bleedAvoidance == BackgroundBleedUseTransparencyLayer)

Modified: trunk/Source/WebCore/rendering/RenderBoxModelObject.cpp (201039 => 201040)


--- trunk/Source/WebCore/rendering/RenderBoxModelObject.cpp	2016-05-17 20:38:36 UTC (rev 201039)
+++ trunk/Source/WebCore/rendering/RenderBoxModelObject.cpp	2016-05-17 21:02:01 UTC (rev 201040)
@@ -193,9 +193,9 @@
     RenderLayerModelObject::willBeDestroyed();
 }
 
-bool RenderBoxModelObject::hasBoxDecorationStyle() const
+bool RenderBoxModelObject::hasVisibleBoxDecorationStyle() const
 {
-    return hasBackground() || style().hasBorderDecoration() || style().hasAppearance() || style().boxShadow();
+    return hasBackground() || style().hasVisibleBorderDecoration() || style().hasAppearance() || style().boxShadow();
 }
 
 void RenderBoxModelObject::updateFromStyle()
@@ -205,7 +205,7 @@
     // Set the appropriate bits for a box model object.  Since all bits are cleared in styleWillChange,
     // we only check for bits that could possibly be set to true.
     const RenderStyle& styleToUse = style();
-    setHasBoxDecorations(hasBoxDecorationStyle());
+    setHasVisibleBoxDecorations(hasVisibleBoxDecorationStyle());
     setInline(styleToUse.isDisplayInlineType());
     setPositionState(styleToUse.position());
     setHorizontalWritingMode(styleToUse.isHorizontalWritingMode());

Modified: trunk/Source/WebCore/rendering/RenderBoxModelObject.h (201039 => 201040)


--- trunk/Source/WebCore/rendering/RenderBoxModelObject.h	2016-05-17 20:38:36 UTC (rev 201039)
+++ trunk/Source/WebCore/rendering/RenderBoxModelObject.h	2016-05-17 21:02:01 UTC (rev 201040)
@@ -245,7 +245,7 @@
 
     LayoutPoint adjustedPositionRelativeToOffsetParent(const LayoutPoint&) const;
 
-    bool hasBoxDecorationStyle() const;
+    bool hasVisibleBoxDecorationStyle() const;
     BackgroundImageGeometry calculateBackgroundImageGeometry(const RenderLayerModelObject* paintContainer, const FillLayer&, const LayoutPoint& paintOffset,
         const LayoutRect& paintRect, RenderElement* = nullptr) const;
     bool borderObscuresBackgroundEdge(const FloatSize& contextScale) const;

Modified: trunk/Source/WebCore/rendering/RenderElement.cpp (201039 => 201040)


--- trunk/Source/WebCore/rendering/RenderElement.cpp	2016-05-17 20:38:36 UTC (rev 201039)
+++ trunk/Source/WebCore/rendering/RenderElement.cpp	2016-05-17 21:02:01 UTC (rev 201040)
@@ -860,7 +860,7 @@
             clearPositionedState();
         }
         setHorizontalWritingMode(true);
-        setHasBoxDecorations(false);
+        setHasVisibleBoxDecorations(false);
         setHasOverflowClip(false);
         setHasTransformRelatedProperty(false);
         setHasReflection(false);
@@ -1257,7 +1257,7 @@
         return true;
 
     // If we don't have a background/border/mask, then nothing to do.
-    if (!renderer.hasBoxDecorations())
+    if (!renderer.hasVisibleBoxDecorations())
         return false;
 
     if (mustRepaintFillLayers(renderer, renderer.style().backgroundLayers()))

Modified: trunk/Source/WebCore/rendering/RenderImage.cpp (201039 => 201040)


--- trunk/Source/WebCore/rendering/RenderImage.cpp	2016-05-17 20:38:36 UTC (rev 201039)
+++ trunk/Source/WebCore/rendering/RenderImage.cpp	2016-05-17 21:02:01 UTC (rev 201040)
@@ -225,7 +225,7 @@
     if (documentBeingDestroyed() || document().inPageCache())
         return;
 
-    if (hasBoxDecorations() || hasMask() || hasShapeOutside())
+    if (hasVisibleBoxDecorations() || hasMask() || hasShapeOutside())
         RenderReplaced::imageChanged(newImage, rect);
 
     if (newImage != imageResource().imagePtr() || !newImage)

Modified: trunk/Source/WebCore/rendering/RenderInline.cpp (201039 => 201040)


--- trunk/Source/WebCore/rendering/RenderInline.cpp	2016-05-17 20:38:36 UTC (rev 201039)
+++ trunk/Source/WebCore/rendering/RenderInline.cpp	2016-05-17 21:02:01 UTC (rev 201040)
@@ -204,7 +204,7 @@
     }
 
     if (!alwaysCreateLineBoxes()) {
-        bool alwaysCreateLineBoxes = hasSelfPaintingLayer() || hasBoxDecorations() || newStyle.hasPadding() || newStyle.hasMargin() || hasOutline();
+        bool alwaysCreateLineBoxes = hasSelfPaintingLayer() || hasVisibleBoxDecorations() || newStyle.hasBorder() || newStyle.hasPadding() || newStyle.hasMargin() || hasOutline();
         if (oldStyle && alwaysCreateLineBoxes) {
             dirtyLineBoxes(false);
             setNeedsLayout();

Modified: trunk/Source/WebCore/rendering/RenderLayer.cpp (201039 => 201040)


--- trunk/Source/WebCore/rendering/RenderLayer.cpp	2016-05-17 20:38:36 UTC (rev 201039)
+++ trunk/Source/WebCore/rendering/RenderLayer.cpp	2016-05-17 21:02:01 UTC (rev 201040)
@@ -305,6 +305,7 @@
     , m_layerListMutationAllowed(true)
 #endif
     , m_hasFilterInfo(false)
+    , m_hasComputedRepaintRect(false)
 #if ENABLE(CSS_COMPOSITING)
     , m_blendMode(BlendModeNormal)
     , m_hasNotIsolatedCompositedBlendingDescendants(false)
@@ -509,7 +510,7 @@
 
         // FIXME: Should ASSERT that value calculated for m_outlineBox using the cached offset is the same
         // as the value not using the cached offset, but we can't due to https://bugs.webkit.org/show_bug.cgi?id=37048
-        if (flags & CheckForRepaint) {
+        if ((flags & CheckForRepaint) && m_hasComputedRepaintRect) {
             if (!renderer().view().printing()) {
                 bool didRepaint = false;
                 if (m_repaintStatus & NeedsFullRepaint) {
@@ -594,7 +595,7 @@
         if (child->isComposited())
             continue;
 
-        repaintRect.unite(child->repaintRectIncludingNonCompositingDescendants());
+        repaintRect.uniteIfNonZero(child->repaintRectIncludingNonCompositingDescendants());
     }
     return repaintRect;
 }
@@ -785,6 +786,12 @@
 {
     ASSERT(!m_visibleContentStatusDirty);
 
+    if (!isSelfPaintingLayer()) {
+        clearRepaintRects();
+        return;
+    }
+    
+    m_hasComputedRepaintRect = true;
     m_repaintRect = renderer().clippedOverflowRectForRepaint(repaintContainer);
     m_outlineBox = renderer().outlineBoundsForRepaint(repaintContainer, geometryMap);
 }
@@ -803,9 +810,9 @@
 
 void RenderLayer::clearRepaintRects()
 {
-    ASSERT(!m_hasVisibleContent);
     ASSERT(!m_visibleContentStatusDirty);
 
+    m_hasComputedRepaintRect = false;
     m_repaintRect = LayoutRect();
     m_outlineBox = LayoutRect();
 }
@@ -845,9 +852,6 @@
     if (positionChanged)
         flags |= HasChangedAncestor;
 
-    if (geometryMap)
-        geometryMap->pushMappingsToAncestor(this, parent());
-
     if (flags & HasChangedAncestor || flags & HasSeenViewportConstrainedAncestor || flags & IsOverflowScroll)
         clearClipRects();
 
@@ -856,15 +860,23 @@
 
     if (renderer().hasOverflowClip())
         flags |= HasSeenAncestorWithOverflowClip;
+    
+    bool shouldComputeRepaintRects = (flags & HasSeenViewportConstrainedAncestor || (flags & IsOverflowScroll && flags & HasSeenAncestorWithOverflowClip)) && isSelfPaintingLayer();
+    bool isVisuallyEmpty = !isVisuallyNonEmpty();
+    bool shouldPushAndPopMappings = geometryMap && ((shouldComputeRepaintRects && !isVisuallyEmpty) || firstChild());
+    if (shouldPushAndPopMappings)
+        geometryMap->pushMappingsToAncestor(this, parent());
 
-    if (flags & HasSeenViewportConstrainedAncestor
-        || (flags & IsOverflowScroll && flags & HasSeenAncestorWithOverflowClip)) {
-        // FIXME: We could track the repaint container as we walk down the tree.
-        computeRepaintRects(renderer().containerForRepaint(), geometryMap);
+    if (shouldComputeRepaintRects) {
+        // When scrolling, we don't compute repaint rects for visually non-empty layers.
+        if (isVisuallyEmpty)
+            clearRepaintRects();
+        else // FIXME: We could track the repaint container as we walk down the tree.
+            computeRepaintRects(renderer().containerForRepaint(), geometryMap);
     } else {
         // Check that our cached rects are correct.
-        ASSERT(m_repaintRect == renderer().clippedOverflowRectForRepaint(renderer().containerForRepaint()));
-        ASSERT(m_outlineBox == renderer().outlineBoundsForRepaint(renderer().containerForRepaint(), geometryMap));
+        ASSERT(!m_hasComputedRepaintRect || (m_repaintRect == renderer().clippedOverflowRectForRepaint(renderer().containerForRepaint())));
+        ASSERT(!m_hasComputedRepaintRect || m_outlineBox == renderer().outlineBoundsForRepaint(renderer().containerForRepaint()));
     }
     
     for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
@@ -881,7 +893,7 @@
         m_updatingMarqueePosition = oldUpdatingMarqueePosition;
     }
 
-    if (geometryMap)
+    if (shouldPushAndPopMappings)
         geometryMap->popMappingsToAncestor(parent());
 
     renderer().document().markers().invalidateRectsForAllMarkers();
@@ -2411,8 +2423,10 @@
     RenderLayerModelObject* repaintContainer = renderer().containerForRepaint();
     // The caret rect needs to be invalidated after scrolling
     frame.selection().setCaretRectNeedsUpdate();
+    
+    LayoutRect rectForRepaint = m_hasComputedRepaintRect ? m_repaintRect : renderer().clippedOverflowRectForRepaint(repaintContainer);
 
-    FloatQuad quadForFakeMouseMoveEvent = FloatQuad(m_repaintRect);
+    FloatQuad quadForFakeMouseMoveEvent = FloatQuad(rectForRepaint);
     if (repaintContainer)
         quadForFakeMouseMoveEvent = repaintContainer->localToAbsoluteQuad(quadForFakeMouseMoveEvent);
     frame.eventHandler().dispatchFakeMouseMoveEventSoonInQuad(quadForFakeMouseMoveEvent);
@@ -2423,7 +2437,7 @@
 
     // Just schedule a full repaint of our object.
     if (requiresRepaint)
-        renderer().repaintUsingContainer(repaintContainer, m_repaintRect);
+        renderer().repaintUsingContainer(repaintContainer, rectForRepaint);
 
     // Schedule the scroll and scroll-related DOM events.
     if (Element* element = renderer().element()) {
@@ -6500,9 +6514,9 @@
         parent()->dirtyAncestorChainHasSelfPaintingLayerDescendantStatus();
 }
 
-static bool hasBoxDecorationsOrBackground(const RenderElement& renderer)
+static bool hasVisibleBoxDecorationsOrBackground(const RenderElement& renderer)
 {
-    return renderer.hasBoxDecorations() || renderer.style().hasOutline();
+    return renderer.hasVisibleBoxDecorations() || renderer.style().hasOutline();
 }
 
 // Constrain the depth and breadth of the search for performance.
@@ -6533,7 +6547,7 @@
         if (is<RenderLayerModelObject>(renderElementChild) && downcast<RenderLayerModelObject>(renderElementChild).hasSelfPaintingLayer())
             continue;
 
-        if (hasBoxDecorationsOrBackground(renderElementChild))
+        if (hasVisibleBoxDecorationsOrBackground(renderElementChild))
             return true;
         
         if (is<RenderReplaced>(renderElementChild))
@@ -6551,9 +6565,9 @@
     return hasPaintingNonLayerDescendants(renderer(), 0);
 }
 
-bool RenderLayer::hasBoxDecorationsOrBackground() const
+bool RenderLayer::hasVisibleBoxDecorationsOrBackground() const
 {
-    return WebCore::hasBoxDecorationsOrBackground(renderer());
+    return WebCore::hasVisibleBoxDecorationsOrBackground(renderer());
 }
 
 bool RenderLayer::hasVisibleBoxDecorations() const
@@ -6561,7 +6575,7 @@
     if (!hasVisibleContent())
         return false;
 
-    return hasBoxDecorationsOrBackground() || hasOverflowControls();
+    return hasVisibleBoxDecorationsOrBackground() || hasOverflowControls();
 }
 
 bool RenderLayer::isVisuallyNonEmpty() const
@@ -6574,7 +6588,7 @@
     if (renderer().isRenderReplaced() || hasOverflowControls())
         return true;
 
-    if (hasBoxDecorationsOrBackground())
+    if (hasVisibleBoxDecorationsOrBackground())
         return true;
     
     if (hasNonEmptyChildRenderers())

Modified: trunk/Source/WebCore/rendering/RenderLayer.h (201039 => 201040)


--- trunk/Source/WebCore/rendering/RenderLayer.h	2016-05-17 20:38:36 UTC (rev 201039)
+++ trunk/Source/WebCore/rendering/RenderLayer.h	2016-05-17 21:02:01 UTC (rev 201040)
@@ -386,7 +386,7 @@
     void setHasVisibleContent();
     void dirtyVisibleContentStatus();
 
-    bool hasBoxDecorationsOrBackground() const;
+    bool hasVisibleBoxDecorationsOrBackground() const;
     bool hasVisibleBoxDecorations() const;
     // Returns true if this layer has visible content (ignoring any child layers).
     bool isVisuallyNonEmpty() const;
@@ -538,7 +538,8 @@
     LayoutRect calculateLayerBounds(const RenderLayer* ancestorLayer, const LayoutSize& offsetFromRoot, CalculateLayerBoundsFlags = DefaultCalculateLayerBoundsFlags) const;
     
     // Return a cached repaint rect, computed relative to the layer renderer's containerForRepaint.
-    LayoutRect repaintRect() const { return m_repaintRect; }
+    bool hasComputedRepaintRect() const { return m_hasComputedRepaintRect; }
+    LayoutRect repaintRect() const { ASSERT(hasComputedRepaintRect()); return m_repaintRect; }
     LayoutRect repaintRectIncludingNonCompositingDescendants() const;
 
     void setRepaintStatus(RepaintStatus status) { m_repaintStatus = status; }
@@ -1068,6 +1069,8 @@
 #endif
 
     bool m_hasFilterInfo : 1;
+    
+    bool m_hasComputedRepaintRect : 1;
 
 #if ENABLE(CSS_COMPOSITING)
     unsigned m_blendMode : 5;

Modified: trunk/Source/WebCore/rendering/RenderLayerBacking.cpp (201039 => 201040)


--- trunk/Source/WebCore/rendering/RenderLayerBacking.cpp	2016-05-17 20:38:36 UTC (rev 201039)
+++ trunk/Source/WebCore/rendering/RenderLayerBacking.cpp	2016-05-17 21:02:01 UTC (rev 201040)
@@ -1229,7 +1229,7 @@
         // m_graphicsLayer only needs backing store if the non-scrolling parts (background, outlines, borders, shadows etc) need to paint.
         // m_scrollingLayer never has backing store.
         // m_scrollingContentsLayer only needs backing store if the scrolled contents need to paint.
-        bool hasNonScrollingPaintedContent = m_owningLayer.hasVisibleContent() && m_owningLayer.hasBoxDecorationsOrBackground();
+        bool hasNonScrollingPaintedContent = m_owningLayer.hasVisibleContent() && m_owningLayer.hasVisibleBoxDecorationsOrBackground();
         m_graphicsLayer->setDrawsContent(hasNonScrollingPaintedContent);
 
         bool hasScrollingPaintedContent = m_owningLayer.hasVisibleContent() && (renderer().hasBackground() || paintsChildren());
@@ -1675,9 +1675,9 @@
 }
 
 // FIXME: Code is duplicated in RenderLayer. Also, we should probably not consider filters a box decoration here.
-static inline bool hasBoxDecorations(const RenderStyle& style)
+static inline bool hasVisibleBoxDecorations(const RenderStyle& style)
 {
-    return style.hasBorder() || style.hasBorderRadius() || style.hasOutline() || style.hasAppearance() || style.boxShadow() || style.hasFilter();
+    return style.hasVisibleBorder() || style.hasBorderRadius() || style.hasOutline() || style.hasAppearance() || style.boxShadow() || style.hasFilter();
 }
 
 static bool canCreateTiledImage(const RenderStyle& style)
@@ -1712,9 +1712,9 @@
     return true;
 }
 
-static bool hasBoxDecorationsOrBackgroundImage(const RenderStyle& style)
+static bool hasVisibleBoxDecorationsOrBackgroundImage(const RenderStyle& style)
 {
-    if (hasBoxDecorations(style))
+    if (hasVisibleBoxDecorations(style))
         return true;
 
     if (!style.hasBackgroundImage())
@@ -1810,7 +1810,7 @@
     if (renderer.hasClip())
         return false;
 
-    if (hasBoxDecorationsOrBackgroundImage(style))
+    if (hasVisibleBoxDecorationsOrBackgroundImage(style))
         return false;
 
     // FIXME: We can't create a directly composited background if this
@@ -1895,7 +1895,7 @@
         
         // Reject anything that has a border, a border-radius or outline,
         // or is not a simple background (no background, or solid color).
-        if (hasBoxDecorationsOrBackgroundImage(rootObject->style()))
+        if (hasVisibleBoxDecorationsOrBackgroundImage(rootObject->style()))
             return false;
         
         // Now look at the body's renderer.
@@ -1906,7 +1906,7 @@
         if (!bodyRenderer)
             return false;
         
-        if (hasBoxDecorationsOrBackgroundImage(bodyRenderer->style()))
+        if (hasVisibleBoxDecorationsOrBackgroundImage(bodyRenderer->style()))
             return false;
     }
 
@@ -1979,12 +1979,12 @@
     // and set background color on the layer in that case, instead of allocating backing store and painting.
 #if ENABLE(VIDEO)
     if (is<RenderVideo>(renderer()) && downcast<RenderVideo>(renderer()).shouldDisplayVideo())
-        return m_owningLayer.hasBoxDecorationsOrBackground() || (!(downcast<RenderVideo>(renderer()).supportsAcceleratedRendering()) && m_requiresOwnBackingStore);
+        return m_owningLayer.hasVisibleBoxDecorationsOrBackground() || (!(downcast<RenderVideo>(renderer()).supportsAcceleratedRendering()) && m_requiresOwnBackingStore);
 #endif
 
 #if ENABLE(WEBGL) || ENABLE(ACCELERATED_2D_CANVAS)
     if (is<RenderHTMLCanvas>(renderer()) && canvasCompositingStrategy(renderer()) == CanvasAsLayerContents)
-        return m_owningLayer.hasBoxDecorationsOrBackground();
+        return m_owningLayer.hasVisibleBoxDecorationsOrBackground();
 #endif
 
     return true;
@@ -1994,7 +1994,7 @@
 // that require painting. Direct compositing saves backing store.
 bool RenderLayerBacking::isDirectlyCompositedImage() const
 {
-    if (!is<RenderImage>(renderer()) || m_owningLayer.hasBoxDecorationsOrBackground() || m_owningLayer.paintsWithFilters() || renderer().hasClip())
+    if (!is<RenderImage>(renderer()) || m_owningLayer.hasVisibleBoxDecorationsOrBackground() || m_owningLayer.paintsWithFilters() || renderer().hasClip())
         return false;
 
 #if ENABLE(VIDEO)

Modified: trunk/Source/WebCore/rendering/RenderLayerModelObject.cpp (201039 => 201040)


--- trunk/Source/WebCore/rendering/RenderLayerModelObject.cpp	2016-05-17 20:38:36 UTC (rev 201039)
+++ trunk/Source/WebCore/rendering/RenderLayerModelObject.cpp	2016-05-17 21:02:01 UTC (rev 201040)
@@ -161,7 +161,7 @@
         setHasTransformRelatedProperty(false); // All transform-related propeties force layers, so we know we don't have one or the object doesn't support them.
         setHasReflection(false);
         // Repaint the about to be destroyed self-painting layer when style change also triggers repaint.
-        if (layer()->isSelfPaintingLayer() && layer()->repaintStatus() == NeedsFullRepaint)
+        if (layer()->isSelfPaintingLayer() && layer()->repaintStatus() == NeedsFullRepaint && layer()->hasComputedRepaintRect())
             repaintUsingContainer(containerForRepaint(), layer()->repaintRect());
         layer()->removeOnlyThisLayer(); // calls destroyLayer() which clears m_layer
         if (s_wasFloating && isFloating())

Modified: trunk/Source/WebCore/rendering/RenderNamedFlowFragment.cpp (201039 => 201040)


--- trunk/Source/WebCore/rendering/RenderNamedFlowFragment.cpp	2016-05-17 20:38:36 UTC (rev 201039)
+++ trunk/Source/WebCore/rendering/RenderNamedFlowFragment.cpp	2016-05-17 21:02:01 UTC (rev 201040)
@@ -392,13 +392,13 @@
     if (is<RenderElement>(*object))
         downcast<RenderElement>(*object).setStyleInternal(WTFMove(*styleInRegion));
 
-    if (is<RenderBoxModelObject>(*object) && !object->hasBoxDecorations()) {
-        bool hasBoxDecorations = is<RenderTableCell>(*object)
+    if (is<RenderBoxModelObject>(*object) && !object->hasVisibleBoxDecorations()) {
+        bool hasVisibleBoxDecorations = is<RenderTableCell>(*object)
         || object->style().hasBackground()
-        || object->style().hasBorder()
+        || object->style().hasVisibleBorder()
         || object->style().hasAppearance()
         || object->style().boxShadow();
-        object->setHasBoxDecorations(hasBoxDecorations);
+        object->setHasVisibleBoxDecorations(hasVisibleBoxDecorations);
     }
 
     ObjectRegionStyleInfo styleInfo;

Modified: trunk/Source/WebCore/rendering/RenderObject.h (201039 => 201040)


--- trunk/Source/WebCore/rendering/RenderObject.h	2016-05-17 20:38:36 UTC (rev 201039)
+++ trunk/Source/WebCore/rendering/RenderObject.h	2016-05-17 21:02:01 UTC (rev 201040)
@@ -518,7 +518,7 @@
         HasBoxDecorationsAndBackgroundIsKnownToBeObscured,
         HasBoxDecorationsAndBackgroundMayBeVisible,
     };
-    bool hasBoxDecorations() const { return m_bitfields.boxDecorationState() != NoBoxDecorations; }
+    bool hasVisibleBoxDecorations() const { return m_bitfields.boxDecorationState() != NoBoxDecorations; }
     bool backgroundIsKnownToBeObscured(const LayoutPoint& paintOffset);
     bool hasEntirelyFixedBackground() const;
 
@@ -601,7 +601,7 @@
     void setFloating(bool b = true) { m_bitfields.setFloating(b); }
     void setInline(bool b = true) { m_bitfields.setIsInline(b); }
 
-    void setHasBoxDecorations(bool = true);
+    void setHasVisibleBoxDecorations(bool = true);
     void invalidateBackgroundObscurationStatus();
     virtual bool computeBackgroundIsKnownToBeObscured(const LayoutPoint&) { return false; }
 
@@ -1125,20 +1125,20 @@
     setSelectionState(state);
 }
 
-inline void RenderObject::setHasBoxDecorations(bool b)
+inline void RenderObject::setHasVisibleBoxDecorations(bool b)
 {
     if (!b) {
         m_bitfields.setBoxDecorationState(NoBoxDecorations);
         return;
     }
-    if (hasBoxDecorations())
+    if (hasVisibleBoxDecorations())
         return;
     m_bitfields.setBoxDecorationState(HasBoxDecorationsAndBackgroundObscurationStatusInvalid);
 }
 
 inline void RenderObject::invalidateBackgroundObscurationStatus()
 {
-    if (!hasBoxDecorations())
+    if (!hasVisibleBoxDecorations())
         return;
     m_bitfields.setBoxDecorationState(HasBoxDecorationsAndBackgroundObscurationStatusInvalid);
 }

Modified: trunk/Source/WebCore/rendering/RenderReplaced.cpp (201039 => 201040)


--- trunk/Source/WebCore/rendering/RenderReplaced.cpp	2016-05-17 20:38:36 UTC (rev 201039)
+++ trunk/Source/WebCore/rendering/RenderReplaced.cpp	2016-05-17 21:02:01 UTC (rev 201040)
@@ -145,7 +145,7 @@
 #endif
     LayoutPoint adjustedPaintOffset = paintOffset + location();
     
-    if (hasBoxDecorations() && paintInfo.phase == PaintPhaseForeground)
+    if (hasVisibleBoxDecorations() && paintInfo.phase == PaintPhaseForeground)
         paintBoxDecorations(paintInfo, adjustedPaintOffset);
     
     if (paintInfo.phase == PaintPhaseMask) {

Modified: trunk/Source/WebCore/rendering/RenderTable.cpp (201039 => 201040)


--- trunk/Source/WebCore/rendering/RenderTable.cpp	2016-05-17 20:38:36 UTC (rev 201039)
+++ trunk/Source/WebCore/rendering/RenderTable.cpp	2016-05-17 21:02:01 UTC (rev 201040)
@@ -689,7 +689,7 @@
 void RenderTable::paintObject(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
 {
     PaintPhase paintPhase = paintInfo.phase;
-    if ((paintPhase == PaintPhaseBlockBackground || paintPhase == PaintPhaseChildBlockBackground) && hasBoxDecorations() && style().visibility() == VISIBLE)
+    if ((paintPhase == PaintPhaseBlockBackground || paintPhase == PaintPhaseChildBlockBackground) && hasVisibleBoxDecorations() && style().visibility() == VISIBLE)
         paintBoxDecorations(paintInfo, paintOffset);
 
     if (paintPhase == PaintPhaseMask) {
@@ -768,7 +768,7 @@
     paintBackground(paintInfo, rect, bleedAvoidance);
     paintBoxShadow(paintInfo, rect, style(), Inset);
 
-    if (style().hasBorderDecoration() && !collapseBorders())
+    if (style().hasVisibleBorderDecoration() && !collapseBorders())
         paintBorder(paintInfo, rect, style());
 }
 

Modified: trunk/Source/WebCore/rendering/RenderTableCell.cpp (201039 => 201040)


--- trunk/Source/WebCore/rendering/RenderTableCell.cpp	2016-05-17 20:38:36 UTC (rev 201039)
+++ trunk/Source/WebCore/rendering/RenderTableCell.cpp	2016-05-17 21:02:01 UTC (rev 201040)
@@ -410,7 +410,7 @@
     ASSERT(!row() || row()->rowIndexWasSet());
 
     RenderBlockFlow::styleDidChange(diff, oldStyle);
-    setHasBoxDecorations(true);
+    setHasVisibleBoxDecorations(true); // FIXME: Optimize this to only set to true if necessary.
 
     if (parent() && section() && oldStyle && style().height() != oldStyle->height())
         section()->rowLogicalHeightChanged(rowIndex());

Modified: trunk/Source/WebCore/rendering/RenderWidget.cpp (201039 => 201040)


--- trunk/Source/WebCore/rendering/RenderWidget.cpp	2016-05-17 20:38:36 UTC (rev 201039)
+++ trunk/Source/WebCore/rendering/RenderWidget.cpp	2016-05-17 21:02:01 UTC (rev 201040)
@@ -254,7 +254,7 @@
 
     LayoutPoint adjustedPaintOffset = paintOffset + location();
 
-    if (hasBoxDecorations() && (paintInfo.phase == PaintPhaseForeground || paintInfo.phase == PaintPhaseSelection))
+    if (hasVisibleBoxDecorations() && (paintInfo.phase == PaintPhaseForeground || paintInfo.phase == PaintPhaseSelection))
         paintBoxDecorations(paintInfo, adjustedPaintOffset);
 
     if (paintInfo.phase == PaintPhaseMask) {

Modified: trunk/Source/WebCore/rendering/style/BorderData.h (201039 => 201040)


--- trunk/Source/WebCore/rendering/style/BorderData.h	2016-05-17 20:38:36 UTC (rev 201039)
+++ trunk/Source/WebCore/rendering/style/BorderData.h	2016-05-17 21:02:01 UTC (rev 201040)
@@ -46,12 +46,18 @@
         bool haveImage = m_image.hasImage();
         return m_left.nonZero(!haveImage) || m_right.nonZero(!haveImage) || m_top.nonZero(!haveImage) || m_bottom.nonZero(!haveImage);
     }
+    
+    bool hasVisibleBorder() const
+    {
+        bool haveImage = m_image.hasImage();
+        return m_left.isVisible(!haveImage) || m_right.isVisible(!haveImage) || m_top.isVisible(!haveImage) || m_bottom.isVisible(!haveImage);
+    }
 
     bool hasFill() const
     {
         return m_image.hasImage() && m_image.fill();
     }
-
+    
     bool hasBorderRadius() const
     {
         if (!m_topLeft.width().isZero())

Modified: trunk/Source/WebCore/rendering/style/RenderStyle.h (201039 => 201040)


--- trunk/Source/WebCore/rendering/style/RenderStyle.h	2016-05-17 20:38:36 UTC (rev 201039)
+++ trunk/Source/WebCore/rendering/style/RenderStyle.h	2016-05-17 21:02:01 UTC (rev 201040)
@@ -554,7 +554,8 @@
     bool hasMargin() const { return !surround->margin.isZero(); }
     bool hasBorder() const { return surround->border.hasBorder(); }
     bool hasBorderFill() const { return surround->border.hasFill(); }
-    bool hasBorderDecoration() const { return hasBorder() || hasBorderFill(); }
+    bool hasVisibleBorderDecoration() const { return hasVisibleBorder() || hasBorderFill(); }
+    bool hasVisibleBorder() const { return surround->border.hasVisibleBorder(); }
     bool hasPadding() const { return !surround->padding.isZero(); }
     bool hasOffset() const { return !surround->offset.isZero(); }
     bool hasMarginBeforeQuirk() const { return marginBefore().hasQuirk(); }

Modified: trunk/Source/WebCore/rendering/svg/RenderSVGRoot.cpp (201039 => 201040)


--- trunk/Source/WebCore/rendering/svg/RenderSVGRoot.cpp	2016-05-17 20:38:36 UTC (rev 201039)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGRoot.cpp	2016-05-17 21:02:01 UTC (rev 201040)
@@ -204,7 +204,7 @@
     }
 
     updateLayerTransform();
-    m_hasBoxDecorations = isDocumentElementRenderer() ? hasBoxDecorationStyle() : hasBoxDecorations();
+    m_hasBoxDecorations = isDocumentElementRenderer() ? hasVisibleBoxDecorationStyle() : hasVisibleBoxDecorations();
     invalidateBackgroundObscurationStatus();
 
     repainter.repaintAfterLayout();
@@ -305,7 +305,7 @@
 
     // Box decorations may have appeared/disappeared - recompute status.
     if (diff == StyleDifferenceRepaint)
-        m_hasBoxDecorations = hasBoxDecorationStyle();
+        m_hasBoxDecorations = hasVisibleBoxDecorationStyle();
 
     RenderReplaced::styleDidChange(diff, oldStyle);
     SVGResourcesCache::clientStyleChanged(*this, diff, style());
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to