- Revision
- 99803
- Author
- mrobin...@webkit.org
- Date
- 2011-11-09 19:10:09 -0800 (Wed, 09 Nov 2011)
Log Message
[Cairo] Avoid clipping when painting more often
https://bugs.webkit.org/show_bug.cgi?id=71179
Reviewed by Xan Lopez.
No new tests. These changes are covered by existing tests.
* platform/graphics/Gradient.h: Add a Cairo-specific method
that gets the platform gradient with a particular alpha value.
* platform/graphics/cairo/GradientCairo.cpp: Now cache the alpha
value of the last created platform gradient.
(WebCore::Gradient::platformGradient): If the cached platform gradient
has a different alpha value than the one requested, destroy it and start
over.
* platform/graphics/cairo/GraphicsContextCairo.cpp:
(WebCore::drawPathShadow): Adjust the source to avoid calling
cairo_clip/cairo_paint_with_alpha and just do a fill.
(WebCore::shadowAndFillCurrentCairoPath): No need to clip here. Just
call cairo_fill.
* platform/graphics/cairo/PlatformContextCairo.cpp:
(WebCore::drawPatternToCairoContext): If we have a >= 1 alpha value
we can simply fill and avoid calling cairo_clip here.
(WebCore::prepareCairoContextSource): Remove TODO about recreating the
gradient. No longer need to reduce the gradient source.
Modified Paths
Diff
Modified: trunk/Source/WebCore/ChangeLog (99802 => 99803)
--- trunk/Source/WebCore/ChangeLog 2011-11-10 03:00:43 UTC (rev 99802)
+++ trunk/Source/WebCore/ChangeLog 2011-11-10 03:10:09 UTC (rev 99803)
@@ -1,3 +1,30 @@
+2011-11-09 Martin Robinson <mrobin...@igalia.com>
+
+ [Cairo] Avoid clipping when painting more often
+ https://bugs.webkit.org/show_bug.cgi?id=71179
+
+ Reviewed by Xan Lopez.
+
+ No new tests. These changes are covered by existing tests.
+
+ * platform/graphics/Gradient.h: Add a Cairo-specific method
+ that gets the platform gradient with a particular alpha value.
+ * platform/graphics/cairo/GradientCairo.cpp: Now cache the alpha
+ value of the last created platform gradient.
+ (WebCore::Gradient::platformGradient): If the cached platform gradient
+ has a different alpha value than the one requested, destroy it and start
+ over.
+ * platform/graphics/cairo/GraphicsContextCairo.cpp:
+ (WebCore::drawPathShadow): Adjust the source to avoid calling
+ cairo_clip/cairo_paint_with_alpha and just do a fill.
+ (WebCore::shadowAndFillCurrentCairoPath): No need to clip here. Just
+ call cairo_fill.
+ * platform/graphics/cairo/PlatformContextCairo.cpp:
+ (WebCore::drawPatternToCairoContext): If we have a >= 1 alpha value
+ we can simply fill and avoid calling cairo_clip here.
+ (WebCore::prepareCairoContextSource): Remove TODO about recreating the
+ gradient. No longer need to reduce the gradient source.
+
2011-11-09 Alexey Proskuryakov <a...@apple.com>
<rdar://problem/10423024> WebProcess doesn't use AuthBrokerAgent for proxy credentials
Modified: trunk/Source/WebCore/platform/graphics/Gradient.h (99802 => 99803)
--- trunk/Source/WebCore/platform/graphics/Gradient.h 2011-11-10 03:00:43 UTC (rev 99802)
+++ trunk/Source/WebCore/platform/graphics/Gradient.h 2011-11-10 03:10:09 UTC (rev 99803)
@@ -138,6 +138,8 @@
#if USE(CG)
void paint(CGContextRef);
void paint(GraphicsContext*);
+#elif USE(CAIRO)
+ PlatformGradient platformGradient(float globalAlpha);
#endif
private:
@@ -163,6 +165,11 @@
AffineTransform m_gradientSpaceTransformation;
PlatformGradient m_gradient;
+
+#if USE(CAIRO)
+ float m_platformGradientAlpha;
+#endif
+
};
} //namespace
Modified: trunk/Source/WebCore/platform/graphics/cairo/GradientCairo.cpp (99802 => 99803)
--- trunk/Source/WebCore/platform/graphics/cairo/GradientCairo.cpp 2011-11-10 03:00:43 UTC (rev 99802)
+++ trunk/Source/WebCore/platform/graphics/cairo/GradientCairo.cpp 2011-11-10 03:10:09 UTC (rev 99803)
@@ -44,9 +44,17 @@
cairo_pattern_t* Gradient::platformGradient()
{
- if (m_gradient)
+ return platformGradient(1);
+}
+
+cairo_pattern_t* Gradient::platformGradient(float globalAlpha)
+{
+ if (m_gradient && m_platformGradientAlpha == globalAlpha)
return m_gradient;
+ platformDestroy();
+ m_platformGradientAlpha = globalAlpha;
+
if (m_radial)
m_gradient = cairo_pattern_create_radial(m_p0.x(), m_p0.y(), m_r0, m_p1.x(), m_p1.y(), m_r1);
else
@@ -54,7 +62,9 @@
Vector<ColorStop>::iterator stopIterator = m_stops.begin();
while (stopIterator != m_stops.end()) {
- cairo_pattern_add_color_stop_rgba(m_gradient, stopIterator->stop, stopIterator->red, stopIterator->green, stopIterator->blue, stopIterator->alpha);
+ cairo_pattern_add_color_stop_rgba(m_gradient, stopIterator->stop,
+ stopIterator->red, stopIterator->green, stopIterator->blue,
+ stopIterator->alpha * globalAlpha);
++stopIterator;
}
Modified: trunk/Source/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp (99802 => 99803)
--- trunk/Source/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp 2011-11-10 03:00:43 UTC (rev 99802)
+++ trunk/Source/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp 2011-11-10 03:10:09 UTC (rev 99803)
@@ -134,8 +134,7 @@
cairo_save(cairoShadowContext);
cairo_append_path(cairoShadowContext, path.get());
shadowContext->platformContext()->prepareForFilling(context->state(), PlatformContextCairo::NoAdjustment);
- cairo_clip(cairoShadowContext);
- cairo_paint(cairoShadowContext);
+ cairo_fill(cairoShadowContext);
cairo_restore(cairoShadowContext);
}
@@ -157,12 +156,11 @@
cairo_t* cr = context->platformContext()->cr();
cairo_save(cr);
- context->platformContext()->prepareForFilling(context->state(), PlatformContextCairo::NoAdjustment);
-
drawPathShadow(context, Fill);
- cairo_clip(cr);
- cairo_paint_with_alpha(cr, context->platformContext()->globalAlpha());
+ context->platformContext()->prepareForFilling(context->state(), PlatformContextCairo::AdjustPatternForGlobalAlpha);
+ cairo_fill(cr);
+
cairo_restore(cr);
}
Modified: trunk/Source/WebCore/platform/graphics/cairo/PlatformContextCairo.cpp (99802 => 99803)
--- trunk/Source/WebCore/platform/graphics/cairo/PlatformContextCairo.cpp 2011-11-10 03:00:43 UTC (rev 99802)
+++ trunk/Source/WebCore/platform/graphics/cairo/PlatformContextCairo.cpp 2011-11-10 03:10:09 UTC (rev 99803)
@@ -143,8 +143,12 @@
cairo_translate(cr, destRect.x(), destRect.y());
cairo_set_source(cr, pattern);
cairo_rectangle(cr, 0, 0, destRect.width(), destRect.height());
- cairo_clip(cr);
- cairo_paint_with_alpha(cr, alpha);
+
+ if (alpha < 1) {
+ cairo_clip(cr);
+ cairo_paint_with_alpha(cr, alpha);
+ } else
+ cairo_fill(cr);
}
void PlatformContextCairo::drawSurfaceToContext(cairo_surface_t* surface, const FloatRect& destRect, const FloatRect& srcRect, GraphicsContext* context)
@@ -213,13 +217,9 @@
RefPtr<cairo_pattern_t> cairoPattern(adoptRef(pattern->createPlatformPattern(AffineTransform())));
cairo_set_source(cr, cairoPattern.get());
reduceSourceByAlpha(cr, globalAlpha);
- } else if (gradient) {
- cairo_set_source(cr, gradient->platformGradient());
-
- // FIXME: It would be faster to simply recreate the Cairo gradient and multiply the
- // color stops by the global alpha.
- reduceSourceByAlpha(cr, globalAlpha);
- } else { // Solid color source.
+ } else if (gradient)
+ cairo_set_source(cr, gradient->platformGradient(globalAlpha));
+ else { // Solid color source.
if (globalAlpha < 1)
setSourceRGBAFromColor(cr, colorWithOverrideAlpha(color.rgb(), color.alpha() / 255.f * globalAlpha));
else