- 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