Optimize non-rounded double border rendering to avoid transparency layers
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 12 Apr 2012 16:04:08 +0000 (16:04 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 12 Apr 2012 16:04:08 +0000 (16:04 +0000)
https://bugs.webkit.org/show_bug.cgi?id=83745

Patch by David Barr <davidbarr@chromium.org> on 2012-04-12
Reviewed by Simon Fraser.

No functional change, painting optimization only.

* rendering/RenderBoxModelObject.cpp:
(WebCore::RenderBoxModelObject::paintBorder):

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@113991 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/rendering/RenderBoxModelObject.cpp

index a6308c2..179beac 100644 (file)
@@ -1,3 +1,15 @@
+2012-04-12  David Barr  <davidbarr@chromium.org>
+
+        Optimize non-rounded double border rendering to avoid transparency layers
+        https://bugs.webkit.org/show_bug.cgi?id=83745
+
+        Reviewed by Simon Fraser.
+
+        No functional change, painting optimization only.
+
+        * rendering/RenderBoxModelObject.cpp:
+        (WebCore::RenderBoxModelObject::paintBorder):
+
 2012-04-12  Julien Chaffraix  <jchaffraix@webkit.org>
 
         Reduce the use of RenderLayer outside of the rendering code
index 4b3b8b7..4814d22 100644 (file)
@@ -1794,6 +1794,7 @@ void RenderBoxModelObject::paintBorder(const PaintInfo& info, const LayoutRect&
 
     bool haveAlphaColor = false;
     bool haveAllSolidEdges = true;
+    bool haveAllDoubleEdges = true;
     bool allEdgesVisible = true;
     bool allEdgesShareColor = true;
     int firstVisibleEdge = -1;
@@ -1821,6 +1822,9 @@ void RenderBoxModelObject::paintBorder(const PaintInfo& info, const LayoutRect&
         
         if (currEdge.style != SOLID)
             haveAllSolidEdges = false;
+
+        if (currEdge.style != DOUBLE)
+            haveAllDoubleEdges = false;
     }
 
     // If no corner intersects the clip region, we can pretend outerBorder is
@@ -1829,9 +1833,10 @@ void RenderBoxModelObject::paintBorder(const PaintInfo& info, const LayoutRect&
         outerBorder.setRadii(RoundedRect::Radii());
 
     // isRenderable() check avoids issue described in https://bugs.webkit.org/show_bug.cgi?id=38787
-    if (haveAllSolidEdges && allEdgesShareColor && innerBorder.isRenderable()) {
-        // Fast path for drawing all solid edges.
-        if (allEdgesVisible && (outerBorder.isRounded() || haveAlphaColor)) {
+    if ((haveAllSolidEdges || haveAllDoubleEdges) && allEdgesShareColor && innerBorder.isRenderable()) {
+        // Fast path for drawing all solid edges and all unrounded double edges
+        if (allEdgesVisible && (outerBorder.isRounded() || haveAlphaColor)
+            && (haveAllSolidEdges || (!outerBorder.isRounded() && !innerBorder.isRounded()))) {
             Path path;
             
             if (outerBorder.isRounded() && bleedAvoidance != BackgroundBleedUseTransparencyLayer)
@@ -1839,6 +1844,45 @@ void RenderBoxModelObject::paintBorder(const PaintInfo& info, const LayoutRect&
             else
                 path.addRect(outerBorder.rect());
 
+            if (haveAllDoubleEdges) {
+                LayoutRect innerThirdRect = outerBorder.rect();
+                LayoutRect outerThirdRect = outerBorder.rect();
+                for (int side = BSTop; side <= BSLeft; ++side) {
+                    int outerWidth;
+                    int innerWidth;
+                    edges[side].getDoubleBorderStripeWidths(outerWidth, innerWidth);
+
+                    if (side == BSTop) {
+                        innerThirdRect.shiftYEdgeTo(innerThirdRect.y() + innerWidth);
+                        outerThirdRect.shiftYEdgeTo(outerThirdRect.y() + outerWidth);
+                    } else if (side == BSBottom) {
+                        innerThirdRect.setHeight(innerThirdRect.height() - innerWidth);
+                        outerThirdRect.setHeight(outerThirdRect.height() - outerWidth);
+                    } else if (side == BSLeft) {
+                        innerThirdRect.shiftXEdgeTo(innerThirdRect.x() + innerWidth);
+                        outerThirdRect.shiftXEdgeTo(outerThirdRect.x() + outerWidth);
+                    } else {
+                        innerThirdRect.setWidth(innerThirdRect.width() - innerWidth);
+                        outerThirdRect.setWidth(outerThirdRect.width() - outerWidth);
+                    }
+                }
+
+                RoundedRect outerThird = outerBorder;
+                RoundedRect innerThird = innerBorder;
+                innerThird.setRect(innerThirdRect);
+                outerThird.setRect(outerThirdRect);
+
+                if (outerThird.isRounded() && bleedAvoidance != BackgroundBleedUseTransparencyLayer)
+                    path.addRoundedRect(outerThird);
+                else
+                    path.addRect(outerThird.rect());
+
+                if (innerThird.isRounded() && bleedAvoidance != BackgroundBleedUseTransparencyLayer)
+                    path.addRoundedRect(innerThird);
+                else
+                    path.addRect(innerThird.rect());
+            }
+
             if (innerBorder.isRounded())
                 path.addRoundedRect(innerBorder);
             else
@@ -1850,7 +1894,7 @@ void RenderBoxModelObject::paintBorder(const PaintInfo& info, const LayoutRect&
             return;
         } 
         // Avoid creating transparent layers
-        if (!allEdgesVisible && !outerBorder.isRounded() && haveAlphaColor) {
+        if (haveAllSolidEdges && !allEdgesVisible && !outerBorder.isRounded() && haveAlphaColor) {
             Path path;
 
             for (int i = BSTop; i <= BSLeft; ++i) {