Title: [162150] trunk/Source/WebCore
Revision
162150
Author
mmaxfi...@apple.com
Date
2014-01-16 13:56:26 -0800 (Thu, 16 Jan 2014)

Log Message

Draw all underline segments in a particular run in the same call
https://bugs.webkit.org/show_bug.cgi?id=127082

Reviewed by Simon Fraser.

Instead of running CGContextFillRect() in a loop, we can instead call CGContextFillRects()

In my tests, this seems to have about 0.5% speedup.

This patch creates some redundant code, but I think that refactoring would make the code
much less readable. I also am hesitant to make drawLineForText call drawLinesForText because
of the overhead of the vector that would be needed.

As there is no behavior change, no new tests are necessary

* platform/graphics/GraphicsContext.h:
* platform/graphics/cairo/GraphicsContextCairo.cpp:
(WebCore::GraphicsContext::drawLinesForText):
* platform/graphics/cg/GraphicsContextCG.cpp:
(WebCore::GraphicsContext::platformInit):
* platform/graphics/wince/GraphicsContextWinCE.cpp:
(WebCore::GraphicsContext::drawLinesForText):
* rendering/InlineTextBox.cpp:
(WebCore::drawSkipInkUnderline):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (162149 => 162150)


--- trunk/Source/WebCore/ChangeLog	2014-01-16 21:52:44 UTC (rev 162149)
+++ trunk/Source/WebCore/ChangeLog	2014-01-16 21:56:26 UTC (rev 162150)
@@ -1,3 +1,30 @@
+2014-01-15  Myles C. Maxfield  <mmaxfi...@apple.com>
+
+        Draw all underline segments in a particular run in the same call
+        https://bugs.webkit.org/show_bug.cgi?id=127082
+
+        Reviewed by Simon Fraser.
+
+        Instead of running CGContextFillRect() in a loop, we can instead call CGContextFillRects()
+
+        In my tests, this seems to have about 0.5% speedup.
+
+        This patch creates some redundant code, but I think that refactoring would make the code
+        much less readable. I also am hesitant to make drawLineForText call drawLinesForText because
+        of the overhead of the vector that would be needed.
+
+        As there is no behavior change, no new tests are necessary
+
+        * platform/graphics/GraphicsContext.h:
+        * platform/graphics/cairo/GraphicsContextCairo.cpp:
+        (WebCore::GraphicsContext::drawLinesForText):
+        * platform/graphics/cg/GraphicsContextCG.cpp:
+        (WebCore::GraphicsContext::platformInit):
+        * platform/graphics/wince/GraphicsContextWinCE.cpp:
+        (WebCore::GraphicsContext::drawLinesForText):
+        * rendering/InlineTextBox.cpp:
+        (WebCore::drawSkipInkUnderline):
+
 2014-01-16  Brady Eidson  <beid...@apple.com>
 
         Use KeyedCoding as a persistent storage mechanism for blobs

Modified: trunk/Source/WebCore/platform/graphics/GraphicsContext.h (162149 => 162150)


--- trunk/Source/WebCore/platform/graphics/GraphicsContext.h	2014-01-16 21:52:44 UTC (rev 162149)
+++ trunk/Source/WebCore/platform/graphics/GraphicsContext.h	2014-01-16 21:56:26 UTC (rev 162150)
@@ -371,6 +371,7 @@
 
         FloatRect computeLineBoundsForText(const FloatPoint&, float width, bool printing);
         void drawLineForText(const FloatPoint&, float width, bool printing);
+        void drawLinesForText(const FloatPoint&, const DashArray& widths, bool printing);
         enum DocumentMarkerLineStyle {
 #if PLATFORM(IOS)
             TextCheckingDictationPhraseWithAlternativesLineStyle,

Modified: trunk/Source/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp (162149 => 162150)


--- trunk/Source/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp	2014-01-16 21:52:44 UTC (rev 162149)
+++ trunk/Source/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp	2014-01-16 21:56:26 UTC (rev 162150)
@@ -641,6 +641,12 @@
     cairo_restore(cairoContext);
 }
 
+void GraphicsContext::drawLinesForText(const FloatPoint& point, const DashArray& widths, bool printing)
+{
+    for (size_t i = 0; i < widths.size(); i += 2)
+        drawLineForText(FloatPoint(point.x() + widths[i], point.y()), widths[i+1] - widths[i], printing);
+}
+
 void GraphicsContext::updateDocumentMarkerResources()
 {
     // Unnecessary, since our document markers don't use resources.

Modified: trunk/Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp (162149 => 162150)


--- trunk/Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp	2014-01-16 21:52:44 UTC (rev 162149)
+++ trunk/Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp	2014-01-16 21:56:26 UTC (rev 162150)
@@ -1455,10 +1455,11 @@
     if (restoreAntialiasMode)
         CGContextSetShouldAntialias(platformContext(), shouldAntialiasLine);
 
-    if (fillColor() != strokeColor())
+    bool fillColorIsNotEqualToStrokeColor = fillColor() != strokeColor();
+    if (fillColorIsNotEqualToStrokeColor)
         setCGFillColor(platformContext(), strokeColor(), strokeColorSpace());
     CGContextFillRect(platformContext(), bounds);
-    if (fillColor() != strokeColor())
+    if (fillColorIsNotEqualToStrokeColor)
         setCGFillColor(platformContext(), fillColor(), fillColorSpace());
     CGContextSetShouldAntialias(platformContext(), savedShouldAntialias);
 
@@ -1481,6 +1482,63 @@
 #endif
 }
 
+void GraphicsContext::drawLinesForText(const FloatPoint& point, const DashArray& widths, bool printing)
+{
+    if (paintingDisabled())
+        return;
+
+    if (widths.size() <= 0)
+        return;
+
+#if !PLATFORM(IOS)
+    bool shouldAntialiasLine;
+    FloatRect bounds = computeLineBoundsAndAntialiasingModeForText(*this, point, widths.last(), printing, shouldAntialiasLine);
+    
+    Vector<CGRect, 4> dashBounds;
+    ASSERT(!(widths.size() % 2));
+    dashBounds.reserveInitialCapacity(dashBounds.size() / 2);
+    for (size_t i = 0; i < widths.size(); i += 2)
+        dashBounds.append(CGRectMake(bounds.x() + widths[i], bounds.y(), widths[i+1] - widths[i], bounds.height()));
+
+    bool savedShouldAntialias = shouldAntialias();
+    bool restoreAntialiasMode = savedShouldAntialias != shouldAntialiasLine;
+
+    if (restoreAntialiasMode)
+        CGContextSetShouldAntialias(platformContext(), shouldAntialiasLine);
+
+    bool fillColorIsNotEqualToStrokeColor = fillColor() != strokeColor();
+    if (fillColorIsNotEqualToStrokeColor)
+        setCGFillColor(platformContext(), strokeColor(), strokeColorSpace());
+    CGContextFillRects(platformContext(), dashBounds.data(), dashBounds.size());
+    if (fillColorIsNotEqualToStrokeColor)
+        setCGFillColor(platformContext(), fillColor(), fillColorSpace());
+    CGContextSetShouldAntialias(platformContext(), savedShouldAntialias);
+
+    if (restoreAntialiasMode)
+        CGContextSetShouldAntialias(platformContext(), true);
+#else
+    CGContextRef context = platformContext();
+    CGContextSaveGState(context);
+
+    Color color(strokeColor());
+    
+    bool shouldAntialiasLine;
+    FloatRect rect = computeLineBoundsAndAntialiasingModeForText(*this, point, width, printing, shouldAntialiasLine, color);
+    
+    Vector<CGRect, 4> dashBounds;
+    ASSERT(!(widths.size() % 2));
+    dashBounds.reserveInitialCapacity(dashBounds.size() / 2);
+    for (size_t i = 0; i < widths.size(); i += 2)
+        dashBounds.append(CGRectMake(rect.x() + widths[i], rect.y(), widths[i+1] - widths[i], rect.height()));
+
+    if (m_state.shouldUseContextColors)
+        setCGFillColor(context, color, strokeColorSpace());
+    CGContextFillRects(context, dashBounds.data(), dashBounds.size());
+
+    CGContextRestoreGState(context);
+#endif
+}
+
 void GraphicsContext::setURLForRect(const URL& link, const IntRect& destRect)
 {
 #if !PLATFORM(IOS)

Modified: trunk/Source/WebCore/platform/graphics/wince/GraphicsContextWinCE.cpp (162149 => 162150)


--- trunk/Source/WebCore/platform/graphics/wince/GraphicsContextWinCE.cpp	2014-01-16 21:52:44 UTC (rev 162149)
+++ trunk/Source/WebCore/platform/graphics/wince/GraphicsContextWinCE.cpp	2014-01-16 21:56:26 UTC (rev 162150)
@@ -966,6 +966,12 @@
     setStrokeStyle(oldStyle);
 }
 
+void GraphicsContext::drawLinesForText(const FloatPoint& point, const DashArray& widths, bool printing)
+{
+    for (size_t i = 0; i < widths.size(); i += 2)
+        drawLineForText(FloatPoint(point.x() + widths[i], point.y()), widths[i+1] - widths[i], printing);
+}
+
 void GraphicsContext::updateDocumentMarkerResources()
 {
     notImplemented();

Modified: trunk/Source/WebCore/rendering/InlineTextBox.cpp (162149 => 162150)


--- trunk/Source/WebCore/rendering/InlineTextBox.cpp	2014-01-16 21:52:44 UTC (rev 162149)
+++ trunk/Source/WebCore/rendering/InlineTextBox.cpp	2014-01-16 21:56:26 UTC (rev 162150)
@@ -127,8 +127,7 @@
     DashArray a = translateIntersectionPointsToSkipInkBoundaries(intersections, underlineBoundingBox.height(), width);
 
     ASSERT(!(a.size() % 2));
-    for (auto i = a.begin(); i != a.end(); i++, i++)
-        context.drawLineForText(FloatPoint(localOrigin.x() + *i, localOrigin.y() + underlineOffset), *(i+1) - *i, isPrinting);
+    context.drawLinesForText(adjustedLocalOrigin, a, isPrinting);
 }
 #endif
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to