Title: [91090] trunk/Source/WebCore
Revision
91090
Author
[email protected]
Date
2011-07-15 12:27:30 -0700 (Fri, 15 Jul 2011)

Log Message

Avoid rounded rect corner-drawing overhead if no corners are visible
https://bugs.webkit.org/show_bug.cgi?id=64584

Patch by Ian Henderson <[email protected]> on 2011-07-15
Reviewed by Simon Fraser.

No new tests, rendering is visually identical.

* rendering/InlineFlowBox.cpp:
(WebCore::InlineFlowBox::paintBoxDecorations): Pass PaintInfo into
paintBorder.
* rendering/RenderBox.cpp:
(WebCore::RenderBox::paintBoxDecorations): Ditto.
* rendering/RenderBoxModelObject.cpp:
(WebCore::unroundClippedCorners):
(WebCore::RenderBoxModelObject::paintBorder):
Any invisible corner may be replaced with a corner of radius zero, as
long as the stroke style is solid.  Change the GraphicsContext
parameter into a PaintInfo parameter so we can get the rect to be
drawn.
* rendering/RenderBoxModelObject.h:
* rendering/RenderFieldset.cpp:
(WebCore::RenderFieldset::paintBoxDecorations): Pass PaintInfo into
paintBorder.
* rendering/RenderTable.cpp:
(WebCore::RenderTable::paintBoxDecorations): Ditto.
* rendering/RenderTableCell.cpp:
(WebCore::RenderTableCell::paintBoxDecorations): Ditto.

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (91089 => 91090)


--- trunk/Source/WebCore/ChangeLog	2011-07-15 19:23:32 UTC (rev 91089)
+++ trunk/Source/WebCore/ChangeLog	2011-07-15 19:27:30 UTC (rev 91090)
@@ -1,3 +1,33 @@
+2011-07-15  Ian Henderson  <[email protected]>
+
+        Avoid rounded rect corner-drawing overhead if no corners are visible
+        https://bugs.webkit.org/show_bug.cgi?id=64584
+
+        Reviewed by Simon Fraser.
+
+        No new tests, rendering is visually identical.
+
+        * rendering/InlineFlowBox.cpp:
+        (WebCore::InlineFlowBox::paintBoxDecorations): Pass PaintInfo into
+        paintBorder.
+        * rendering/RenderBox.cpp:
+        (WebCore::RenderBox::paintBoxDecorations): Ditto.
+        * rendering/RenderBoxModelObject.cpp:
+        (WebCore::unroundClippedCorners):
+        (WebCore::RenderBoxModelObject::paintBorder):
+        Any invisible corner may be replaced with a corner of radius zero, as
+        long as the stroke style is solid.  Change the GraphicsContext
+        parameter into a PaintInfo parameter so we can get the rect to be
+        drawn.
+        * rendering/RenderBoxModelObject.h:
+        * rendering/RenderFieldset.cpp:
+        (WebCore::RenderFieldset::paintBoxDecorations): Pass PaintInfo into
+        paintBorder.
+        * rendering/RenderTable.cpp:
+        (WebCore::RenderTable::paintBoxDecorations): Ditto.
+        * rendering/RenderTableCell.cpp:
+        (WebCore::RenderTableCell::paintBoxDecorations): Ditto.
+
 2011-07-15  Jeff Miller  <[email protected]>
 
         Add UserAgentStyleSheetsData.cpp to WebCore.vcproj

Modified: trunk/Source/WebCore/rendering/InlineFlowBox.cpp (91089 => 91090)


--- trunk/Source/WebCore/rendering/InlineFlowBox.cpp	2011-07-15 19:23:32 UTC (rev 91089)
+++ trunk/Source/WebCore/rendering/InlineFlowBox.cpp	2011-07-15 19:27:30 UTC (rev 91090)
@@ -1134,7 +1134,7 @@
             // The simple case is where we either have no border image or we are the only box for this object.  In those
             // cases only a single call to draw is required.
             if (!hasBorderImage || (!prevLineBox() && !nextLineBox()))
-                boxModelObject()->paintBorder(context, paintRect, renderer()->style(), BackgroundBleedNone, includeLogicalLeftEdge(), includeLogicalRightEdge());
+                boxModelObject()->paintBorder(paintInfo, paintRect, renderer()->style(), BackgroundBleedNone, includeLogicalLeftEdge(), includeLogicalRightEdge());
             else {
                 // We have a border image that spans multiple lines.
                 // We need to adjust tx and ty by the width of all previous lines.
@@ -1157,7 +1157,7 @@
 
                 GraphicsContextStateSaver stateSaver(*context);
                 context->clip(paintRect);
-                boxModelObject()->paintBorder(context, LayoutRect(stripX, stripY, stripWidth, stripHeight), renderer()->style());
+                boxModelObject()->paintBorder(paintInfo, LayoutRect(stripX, stripY, stripWidth, stripHeight), renderer()->style());
             }
         }
     }

Modified: trunk/Source/WebCore/rendering/RenderBox.cpp (91089 => 91090)


--- trunk/Source/WebCore/rendering/RenderBox.cpp	2011-07-15 19:23:32 UTC (rev 91089)
+++ trunk/Source/WebCore/rendering/RenderBox.cpp	2011-07-15 19:27:30 UTC (rev 91090)
@@ -874,7 +874,7 @@
 
     // The theme will tell us whether or not we should also paint the CSS border.
     if ((!style()->hasAppearance() || (!themePainted && theme()->paintBorderOnly(this, paintInfo, paintRect))) && style()->hasBorder())
-        paintBorder(paintInfo.context, paintRect, style(), bleedAvoidance);
+        paintBorder(paintInfo, paintRect, style(), bleedAvoidance);
 
     if (bleedAvoidance == BackgroundBleedUseTransparencyLayer)
         paintInfo.context->endTransparencyLayer();

Modified: trunk/Source/WebCore/rendering/RenderBoxModelObject.cpp (91089 => 91090)


--- trunk/Source/WebCore/rendering/RenderBoxModelObject.cpp	2011-07-15 19:23:32 UTC (rev 91089)
+++ trunk/Source/WebCore/rendering/RenderBoxModelObject.cpp	2011-07-15 19:27:30 UTC (rev 91090)
@@ -1371,9 +1371,51 @@
     }
 }
 
-void RenderBoxModelObject::paintBorder(GraphicsContext* graphicsContext, const IntRect& rect, const RenderStyle* style,
+static void unroundClippedCorners(RoundedRect& border, const LayoutRect& clipRect)
+{
+    LayoutRect boundingRect = border.rect();
+    if (!border.isRounded() || clipRect.contains(boundingRect))
+        return;
+
+    RoundedRect::Radii adjustedRadii = border.radii();
+    bool didAdjustRadii = false;
+
+    LayoutRect topLeftRect(boundingRect.location(), adjustedRadii.topLeft());
+    if (!clipRect.intersects(topLeftRect)) {
+        adjustedRadii.setTopLeft(IntSize());
+        didAdjustRadii = true;
+    }
+
+    LayoutRect topRightRect(boundingRect.location(), adjustedRadii.topRight());
+    topRightRect.setX(boundingRect.maxX() - topRightRect.width());
+    if (!clipRect.intersects(topRightRect)) {
+        adjustedRadii.setTopRight(IntSize());
+        didAdjustRadii = true;
+    }
+
+    LayoutRect bottomLeftRect(boundingRect.location(), adjustedRadii.bottomLeft());
+    bottomLeftRect.setY(boundingRect.maxY() - bottomLeftRect.height());
+    if (!clipRect.intersects(bottomLeftRect)) {
+        adjustedRadii.setBottomLeft(IntSize());
+        didAdjustRadii = true;
+    }
+
+    LayoutRect bottomRightRect(boundingRect.location(), adjustedRadii.bottomRight());
+    bottomRightRect.setX(boundingRect.maxX() - bottomRightRect.width());
+    bottomRightRect.setY(boundingRect.maxY() - bottomRightRect.height());
+    if (!clipRect.intersects(bottomRightRect)) {
+        adjustedRadii.setBottomRight(IntSize());
+        didAdjustRadii = true;
+    }
+
+    if (didAdjustRadii)
+        border.setRadii(adjustedRadii);
+}
+
+void RenderBoxModelObject::paintBorder(const PaintInfo& info, const IntRect& rect, const RenderStyle* style,
                                        BackgroundBleedAvoidance bleedAvoidance, bool includeLogicalLeftEdge, bool includeLogicalRightEdge)
 {
+    GraphicsContext* graphicsContext = info.context;
     // border-image is not affected by border-radius.
     if (paintNinePieceImage(graphicsContext, rect, style, style->borderImage()))
         return;
@@ -1420,7 +1462,12 @@
         if (currEdge.style != SOLID)
             haveAllSolidEdges = false;
     }
-    
+
+    // If one of the corners falls outside the clip region, pretend it has no
+    // radius to improve performance.
+    if (haveAllSolidEdges)
+        unroundClippedCorners(outerBorder, info.rect);
+
     // isRenderable() check avoids issue described in https://bugs.webkit.org/show_bug.cgi?id=38787
     if (haveAllSolidEdges && allEdgesVisible && allEdgesShareColor && innerBorder.isRenderable()) {
         // Fast path for drawing all solid edges.
@@ -1613,9 +1660,10 @@
     graphicsContext->drawRect(borderRect);
 }
 #else
-void RenderBoxModelObject::paintBorder(GraphicsContext* graphicsContext, const IntRect& rect, const RenderStyle* style,
+void RenderBoxModelObject::paintBorder(const PaintInfo& info, const IntRect& rect, const RenderStyle* style,
                                        BackgroundBleedAvoidance, bool includeLogicalLeftEdge, bool includeLogicalRightEdge)
 {
+    GraphicsContext* graphicsContext = info.context;
     // FIXME: This old version of paintBorder should be removed when all ports implement 
     // GraphicsContext::clipConvexPolygon()!! This should happen soon.
     if (paintNinePieceImage(graphicsContext, rect, style, style->borderImage()))

Modified: trunk/Source/WebCore/rendering/RenderBoxModelObject.h (91089 => 91090)


--- trunk/Source/WebCore/rendering/RenderBoxModelObject.h	2011-07-15 19:23:32 UTC (rev 91089)
+++ trunk/Source/WebCore/rendering/RenderBoxModelObject.h	2011-07-15 19:27:30 UTC (rev 91090)
@@ -116,7 +116,7 @@
 
     virtual void childBecameNonInline(RenderObject* /*child*/) { }
 
-    void paintBorder(GraphicsContext*, const IntRect&, const RenderStyle*, BackgroundBleedAvoidance = BackgroundBleedNone, bool includeLogicalLeftEdge = true, bool includeLogicalRightEdge = true);
+    void paintBorder(const PaintInfo&, const IntRect&, const RenderStyle*, BackgroundBleedAvoidance = BackgroundBleedNone, bool includeLogicalLeftEdge = true, bool includeLogicalRightEdge = true);
     bool paintNinePieceImage(GraphicsContext*, const IntRect&, const RenderStyle*, const NinePieceImage&, CompositeOperator = CompositeSourceOver);
     void paintBoxShadow(GraphicsContext*, const LayoutRect&, const RenderStyle*, ShadowStyle, bool includeLogicalLeftEdge = true, bool includeLogicalRightEdge = true);
     void paintFillLayerExtended(const PaintInfo&, const Color&, const FillLayer*, const LayoutRect&, BackgroundBleedAvoidance, InlineFlowBox* = 0, const LayoutSize& = LayoutSize(), CompositeOperator = CompositeSourceOver, RenderObject* backgroundObject = 0);

Modified: trunk/Source/WebCore/rendering/RenderFieldset.cpp (91089 => 91090)


--- trunk/Source/WebCore/rendering/RenderFieldset.cpp	2011-07-15 19:23:32 UTC (rev 91089)
+++ trunk/Source/WebCore/rendering/RenderFieldset.cpp	2011-07-15 19:27:30 UTC (rev 91090)
@@ -165,7 +165,7 @@
         graphicsContext->clipOut(LayoutRect(clipLeft, paintRect.y() + legend->y(), clipWidth, legend->height()));
     }
 
-    paintBorder(paintInfo.context, paintRect, style());
+    paintBorder(paintInfo, paintRect, style());
 }
 
 void RenderFieldset::paintMask(PaintInfo& paintInfo, const LayoutPoint& paintOffset)

Modified: trunk/Source/WebCore/rendering/RenderTable.cpp (91089 => 91090)


--- trunk/Source/WebCore/rendering/RenderTable.cpp	2011-07-15 19:23:32 UTC (rev 91089)
+++ trunk/Source/WebCore/rendering/RenderTable.cpp	2011-07-15 19:27:30 UTC (rev 91090)
@@ -569,7 +569,7 @@
     paintBoxShadow(paintInfo.context, rect, style(), Inset);
 
     if (style()->hasBorder() && !collapseBorders())
-        paintBorder(paintInfo.context, rect, style());
+        paintBorder(paintInfo, rect, style());
 }
 
 void RenderTable::paintMask(PaintInfo& paintInfo, const LayoutPoint& paintOffset)

Modified: trunk/Source/WebCore/rendering/RenderTableCell.cpp (91089 => 91090)


--- trunk/Source/WebCore/rendering/RenderTableCell.cpp	2011-07-15 19:23:32 UTC (rev 91089)
+++ trunk/Source/WebCore/rendering/RenderTableCell.cpp	2011-07-15 19:27:30 UTC (rev 91090)
@@ -1017,7 +1017,7 @@
     if (!style()->hasBorder() || tableElt->collapseBorders())
         return;
 
-    paintBorder(paintInfo.context, paintRect, style());
+    paintBorder(paintInfo, paintRect, style());
 }
 
 void RenderTableCell::paintMask(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to