Diff
Modified: trunk/Source/WebCore/ChangeLog (227050 => 227051)
--- trunk/Source/WebCore/ChangeLog 2018-01-17 08:59:01 UTC (rev 227050)
+++ trunk/Source/WebCore/ChangeLog 2018-01-17 09:20:54 UTC (rev 227051)
@@ -1,5 +1,76 @@
2018-01-17 Zan Dobersek <[email protected]>
+ [Cairo] Use one-time ShadowBlur objects when performing shadowing
+ https://bugs.webkit.org/show_bug.cgi?id=181720
+
+ Reviewed by Carlos Garcia Campos.
+
+ Don't maintain a ShadowBlur object in the PlatformContextCairo class.
+ Instead, use temporary ShadowBlur objects whenever shadowing is needed,
+ providing all the shadow state information to it and drawing shadow into
+ the given GraphicsContext object.
+
+ ShadowBlur constructors are cleaned up. The 'shadows ignored' argument
+ can now also be provided to the variant that accepts explicit shadow
+ attributes, but the argument is false by default.
+
+ In CairoOperations, the ShadowBlurUsage functionality is rolled into the
+ new ShadowState class. ShadowState parameter is now used for operations
+ that might need to perform shadow painting. Call sites are modified
+ accordingly.
+
+ Cairo::State::setShadowValues() and Cairo::State::clearShadow() are
+ removed, since the ShadowBlur object that was modified through those is
+ being removed from the PlatformContextCairo class. We still have to flip
+ the Y-axis of the shadow offset in GraphicsContext::setPlatformShadow()
+ when shadows are ignoring transformations.
+
+ No new tests -- no change in behavior.
+
+ * platform/graphics/ShadowBlur.cpp:
+ (WebCore::ShadowBlur::ShadowBlur):
+ * platform/graphics/ShadowBlur.h:
+ * platform/graphics/cairo/CairoOperations.cpp:
+ (WebCore::Cairo::drawPathShadow):
+ (WebCore::Cairo::drawGlyphsShadow):
+ (WebCore::Cairo::ShadowState::ShadowState):
+ (WebCore::Cairo::ShadowState::isVisible const):
+ (WebCore::Cairo::ShadowState::isRequired const):
+ (WebCore::Cairo::fillRect):
+ (WebCore::Cairo::fillRoundedRect):
+ (WebCore::Cairo::fillRectWithRoundedHole):
+ (WebCore::Cairo::fillPath):
+ (WebCore::Cairo::strokeRect):
+ (WebCore::Cairo::strokePath):
+ (WebCore::Cairo::drawGlyphs):
+ (WebCore::Cairo::drawNativeImage):
+ (WebCore::Cairo::State::setShadowValues): Deleted.
+ (WebCore::Cairo::State::clearShadow): Deleted.
+ (WebCore::Cairo::ShadowBlurUsage::ShadowBlurUsage): Deleted.
+ (WebCore::Cairo::ShadowBlurUsage::required const): Deleted.
+ * platform/graphics/cairo/CairoOperations.h:
+ * platform/graphics/cairo/FontCairo.cpp:
+ (WebCore::FontCascade::drawGlyphs):
+ * platform/graphics/cairo/GraphicsContextCairo.cpp:
+ (WebCore::GraphicsContext::restorePlatformState):
+ (WebCore::GraphicsContext::drawNativeImage):
+ (WebCore::GraphicsContext::fillPath):
+ (WebCore::GraphicsContext::strokePath):
+ (WebCore::GraphicsContext::fillRect):
+ (WebCore::GraphicsContext::setPlatformShadow):
+ (WebCore::GraphicsContext::clearPlatformShadow):
+ (WebCore::GraphicsContext::strokeRect):
+ (WebCore::GraphicsContext::platformFillRoundedRect):
+ (WebCore::GraphicsContext::fillRectWithRoundedHole):
+ * platform/graphics/cairo/PlatformContextCairo.cpp:
+ (WebCore::PlatformContextCairo::drawSurfaceToContext):
+ * platform/graphics/cairo/PlatformContextCairo.h:
+ (WebCore::PlatformContextCairo::shadowBlur): Deleted.
+ * platform/graphics/win/MediaPlayerPrivateMediaFoundation.cpp:
+ (WebCore::MediaPlayerPrivateMediaFoundation::Direct3DPresenter::paintCurrentFrame):
+
+2018-01-17 Zan Dobersek <[email protected]>
+
CanvasImageData: createImageData() parameter should not be nullable
https://bugs.webkit.org/show_bug.cgi?id=181670
Modified: trunk/Source/WebCore/platform/graphics/ShadowBlur.cpp (227050 => 227051)
--- trunk/Source/WebCore/platform/graphics/ShadowBlur.cpp 2018-01-17 08:59:01 UTC (rev 227050)
+++ trunk/Source/WebCore/platform/graphics/ShadowBlur.cpp 2018-01-17 09:20:54 UTC (rev 227051)
@@ -169,12 +169,13 @@
}
#endif
-ShadowBlur::ShadowBlur(const FloatSize& radius, const FloatSize& offset, const Color& color)
+ShadowBlur::ShadowBlur() = default;
+
+ShadowBlur::ShadowBlur(const FloatSize& radius, const FloatSize& offset, const Color& color, bool shadowsIgnoreTransforms)
: m_color(color)
, m_blurRadius(radius)
, m_offset(offset)
- , m_layerImage(0)
- , m_shadowsIgnoreTransforms(false)
+ , m_shadowsIgnoreTransforms(shadowsIgnoreTransforms)
{
updateShadowBlurValues();
}
@@ -195,13 +196,6 @@
updateShadowBlurValues();
}
-ShadowBlur::ShadowBlur()
- : m_type(NoShadow)
- , m_blurRadius(0, 0)
- , m_shadowsIgnoreTransforms(false)
-{
-}
-
void ShadowBlur::setShadowValues(const FloatSize& radius, const FloatSize& offset, const Color& color, bool ignoreTransforms)
{
m_blurRadius = radius;
Modified: trunk/Source/WebCore/platform/graphics/ShadowBlur.h (227050 => 227051)
--- trunk/Source/WebCore/platform/graphics/ShadowBlur.h 2018-01-17 08:59:01 UTC (rev 227050)
+++ trunk/Source/WebCore/platform/graphics/ShadowBlur.h 2018-01-17 09:20:54 UTC (rev 227051)
@@ -50,9 +50,9 @@
BlurShadow
};
- ShadowBlur(const FloatSize& radius, const FloatSize& offset, const Color&);
+ ShadowBlur();
+ ShadowBlur(const FloatSize& radius, const FloatSize& offset, const Color&, bool shadowsIgnoreTransforms = false);
ShadowBlur(const GraphicsContextState&);
- ShadowBlur();
void setShadowValues(const FloatSize&, const FloatSize& , const Color&, bool ignoreTransforms = false);
@@ -100,13 +100,13 @@
IntSize blurredEdgeSize() const;
- ShadowType m_type;
+ ShadowType m_type { NoShadow };
Color m_color;
FloatSize m_blurRadius;
FloatSize m_offset;
- ImageBuffer* m_layerImage; // Buffer to where the temporary shadow will be drawn to.
+ ImageBuffer* m_layerImage { nullptr }; // Buffer to where the temporary shadow will be drawn to.
FloatRect m_sourceRect; // Sub-rect of m_layerImage that contains the shadow pixels.
FloatPoint m_layerOrigin; // Top-left corner of the (possibly clipped) bounding rect to draw the shadow to.
@@ -113,7 +113,7 @@
FloatSize m_layerSize; // Size of m_layerImage pixels that need blurring.
FloatSize m_layerContextTranslation; // Translation to apply to m_layerContext for the shadow to be correctly clipped.
- bool m_shadowsIgnoreTransforms;
+ bool m_shadowsIgnoreTransforms { false };
};
} // namespace WebCore
Modified: trunk/Source/WebCore/platform/graphics/cairo/CairoOperations.cpp (227050 => 227051)
--- trunk/Source/WebCore/platform/graphics/cairo/CairoOperations.cpp 2018-01-17 08:59:01 UTC (rev 227050)
+++ trunk/Source/WebCore/platform/graphics/cairo/CairoOperations.cpp 2018-01-17 09:20:54 UTC (rev 227051)
@@ -66,9 +66,9 @@
FillAndStroke = Fill + Stroke
};
-static inline void drawPathShadow(PlatformContextCairo& platformContext, const FillSource& fillSource, const StrokeSource& strokeSource, GraphicsContext& targetContext, PathDrawingStyle drawingStyle)
+static inline void drawPathShadow(PlatformContextCairo& platformContext, const FillSource& fillSource, const StrokeSource& strokeSource, const ShadowState& shadowState, GraphicsContext& targetContext, PathDrawingStyle drawingStyle)
{
- ShadowBlur& shadow = platformContext.shadowBlur();
+ ShadowBlur shadow({ shadowState.blur, shadowState.blur }, shadowState.offset, shadowState.color, shadowState.ignoreTransforms);
if (shadow.type() == ShadowBlur::NoShadow)
return;
@@ -182,14 +182,13 @@
}
}
-static void drawGlyphsShadow(PlatformContextCairo& platformContext, const ShadowBlurUsage& shadowBlurUsage, TextDrawingModeFlags textDrawingMode, const FloatSize& shadowOffset, const Color& shadowColor, const FloatPoint& point, cairo_scaled_font_t* scaledFont, double syntheticBoldOffset, const Vector<cairo_glyph_t>& glyphs, GraphicsContext& targetContext)
+static void drawGlyphsShadow(PlatformContextCairo& platformContext, const ShadowState& shadowState, TextDrawingModeFlags textDrawingMode, const FloatSize& shadowOffset, const Color& shadowColor, const FloatPoint& point, cairo_scaled_font_t* scaledFont, double syntheticBoldOffset, const Vector<cairo_glyph_t>& glyphs, GraphicsContext& targetContext)
{
- ShadowBlur& shadow = platformContext.shadowBlur();
-
+ ShadowBlur shadow({ shadowState.blur, shadowState.blur }, shadowState.offset, shadowState.color, shadowState.ignoreTransforms);
if (!(textDrawingMode & TextModeFill) || shadow.type() == ShadowBlur::NoShadow)
return;
- if (!shadowBlurUsage.required(platformContext)) {
+ if (!shadowState.isRequired(platformContext)) {
// Optimize non-blurry shadows, by just drawing text without the ShadowBlur.
cairo_t* context = platformContext.cr();
cairo_save(context);
@@ -376,17 +375,6 @@
return AffineTransform(m.xx, m.yx, m.xy, m.yy, m.x0, m.y0);
}
-void setShadowValues(PlatformContextCairo& platformContext, const FloatSize& radius, const FloatSize& offset, const Color& color, bool ignoreTransforms)
-{
- // Cairo doesn't support shadows natively, they are drawn manually in the draw* functions using ShadowBlur.
- platformContext.shadowBlur().setShadowValues(radius, offset, color, ignoreTransforms);
-}
-
-void clearShadow(PlatformContextCairo& platformContext)
-{
- platformContext.shadowBlur().clear();
-}
-
IntRect getClipBounds(PlatformContextCairo& platformContext)
{
double x1, x2, y1, y2;
@@ -439,32 +427,6 @@
} // namespace State
-ShadowBlurUsage::ShadowBlurUsage(const GraphicsContextState& state)
- : shadowColor(state.shadowColor)
- , shadowBlur(state.shadowBlur)
- , shadowsIgnoreTransforms(state.shadowsIgnoreTransforms)
-{
-}
-
-bool ShadowBlurUsage::required(PlatformContextCairo& platformContext) const
-{
- // We can't avoid ShadowBlur if the shadow has blur.
- if (shadowColor.isVisible() && shadowBlur)
- return true;
-
- // We can avoid ShadowBlur and optimize, since we're not drawing on a
- // canvas and box shadows are affected by the transformation matrix.
- if (!shadowsIgnoreTransforms)
- return false;
-
- // We can avoid ShadowBlur, since there are no transformations to apply to the canvas.
- if (State::getCTM(platformContext).isIdentity())
- return false;
-
- // Otherwise, no chance avoiding ShadowBlur.
- return true;
-}
-
FillSource::FillSource(const GraphicsContextState& state)
{
if (state.fillPattern) {
@@ -497,6 +459,38 @@
color = state.strokeColor;
}
+ShadowState::ShadowState(const GraphicsContextState& state)
+ : offset(state.shadowOffset)
+ , blur(state.shadowBlur)
+ , color(state.shadowColor)
+ , ignoreTransforms(state.shadowsIgnoreTransforms)
+{
+}
+
+bool ShadowState::isVisible() const
+{
+ return color.isVisible() && (offset.width() || offset.height() || blur);
+}
+
+bool ShadowState::isRequired(PlatformContextCairo& platformContext) const
+{
+ // We can't avoid ShadowBlur if the shadow has blur.
+ if (color.isVisible() && blur)
+ return true;
+
+ // We can avoid ShadowBlur and optimize, since we're not drawing on a
+ // canvas and box shadows are affected by the transformation matrix.
+ if (!ignoreTransforms)
+ return false;
+
+ // We can avoid ShadowBlur, since there are no transformations to apply to the canvas.
+ if (State::getCTM(platformContext).isIdentity())
+ return false;
+
+ // Otherwise, no chance avoiding ShadowBlur.
+ return true;
+}
+
void setLineCap(PlatformContextCairo& platformContext, LineCap lineCap)
{
cairo_line_cap_t cairoCap;
@@ -544,19 +538,21 @@
cairo_set_miter_limit(platformContext.cr(), miterLimit);
}
-void fillRect(PlatformContextCairo& platformContext, const FloatRect& rect, const FillSource& fillSource, GraphicsContext& targetContext)
+void fillRect(PlatformContextCairo& platformContext, const FloatRect& rect, const FillSource& fillSource, const ShadowState& shadowState, GraphicsContext& targetContext)
{
cairo_t* cr = platformContext.cr();
cairo_rectangle(cr, rect.x(), rect.y(), rect.width(), rect.height());
- drawPathShadow(platformContext, fillSource, { }, targetContext, Fill);
+ drawPathShadow(platformContext, fillSource, { }, shadowState, targetContext, Fill);
fillCurrentCairoPath(platformContext, fillSource);
}
-void fillRect(PlatformContextCairo& platformContext, const FloatRect& rect, const Color& color, bool hasShadow, GraphicsContext& targetContext)
+void fillRect(PlatformContextCairo& platformContext, const FloatRect& rect, const Color& color, const ShadowState& shadowState, GraphicsContext& targetContext)
{
- if (hasShadow)
- platformContext.shadowBlur().drawRectShadow(targetContext, FloatRoundedRect(rect));
+ if (shadowState.isVisible()) {
+ ShadowBlur shadow({ shadowState.blur, shadowState.blur }, shadowState.offset, shadowState.color, shadowState.ignoreTransforms);
+ shadow.drawRectShadow(targetContext, FloatRoundedRect(rect));
+ }
fillRectWithColor(platformContext.cr(), rect, color);
}
@@ -570,10 +566,12 @@
cairo_fill(cr);
}
-void fillRoundedRect(PlatformContextCairo& platformContext, const FloatRoundedRect& rect, const Color& color, bool hasShadow, GraphicsContext& targetContext)
+void fillRoundedRect(PlatformContextCairo& platformContext, const FloatRoundedRect& rect, const Color& color, const ShadowState& shadowState, GraphicsContext& targetContext)
{
- if (hasShadow)
- platformContext.shadowBlur().drawRectShadow(targetContext, rect);
+ if (shadowState.isVisible()) {
+ ShadowBlur shadow({ shadowState.blur, shadowState.blur }, shadowState.offset, shadowState.color, shadowState.ignoreTransforms);
+ shadow.drawRectShadow(targetContext, rect);
+ }
cairo_t* cr = platformContext.cr();
cairo_save(cr);
@@ -587,12 +585,14 @@
cairo_restore(cr);
}
-void fillRectWithRoundedHole(PlatformContextCairo& platformContext, const FloatRect& rect, const FloatRoundedRect& roundedHoleRect, const FillSource& fillSource, const ShadowBlurUsage& shadowBlurUsage, GraphicsContext& targetContext)
+void fillRectWithRoundedHole(PlatformContextCairo& platformContext, const FloatRect& rect, const FloatRoundedRect& roundedHoleRect, const FillSource& fillSource, const ShadowState& shadowState, GraphicsContext& targetContext)
{
// FIXME: this should leverage the specified color.
- if (shadowBlurUsage.required(platformContext))
- platformContext.shadowBlur().drawInsetShadow(targetContext, rect, roundedHoleRect);
+ if (shadowState.isRequired(platformContext)) {
+ ShadowBlur shadow({ shadowState.blur, shadowState.blur }, shadowState.offset, shadowState.color, shadowState.ignoreTransforms);
+ shadow.drawInsetShadow(targetContext, rect, roundedHoleRect);
+ }
Path path;
path.addRect(rect);
@@ -609,16 +609,16 @@
cairo_restore(cr);
}
-void fillPath(PlatformContextCairo& platformContext, const Path& path, const FillSource& fillSource, GraphicsContext& targetContext)
+void fillPath(PlatformContextCairo& platformContext, const Path& path, const FillSource& fillSource, const ShadowState& shadowState, GraphicsContext& targetContext)
{
cairo_t* cr = platformContext.cr();
setPathOnCairoContext(cr, path.platformPath()->context());
- drawPathShadow(platformContext, fillSource, { }, targetContext, Fill);
+ drawPathShadow(platformContext, fillSource, { }, shadowState, targetContext, Fill);
fillCurrentCairoPath(platformContext, fillSource);
}
-void strokeRect(PlatformContextCairo& platformContext, const FloatRect& rect, float lineWidth, const StrokeSource& strokeSource, GraphicsContext& targetContext)
+void strokeRect(PlatformContextCairo& platformContext, const FloatRect& rect, float lineWidth, const StrokeSource& strokeSource, const ShadowState& shadowState, GraphicsContext& targetContext)
{
cairo_t* cr = platformContext.cr();
cairo_save(cr);
@@ -625,7 +625,7 @@
cairo_rectangle(cr, rect.x(), rect.y(), rect.width(), rect.height());
cairo_set_line_width(cr, lineWidth);
- drawPathShadow(platformContext, { }, strokeSource, targetContext, Stroke);
+ drawPathShadow(platformContext, { }, strokeSource, shadowState, targetContext, Stroke);
platformContext.prepareForStroking(strokeSource, PlatformContextCairo::PreserveAlpha);
cairo_stroke(cr);
@@ -632,12 +632,12 @@
cairo_restore(cr);
}
-void strokePath(PlatformContextCairo& platformContext, const Path& path, const StrokeSource& strokeSource, GraphicsContext& targetContext)
+void strokePath(PlatformContextCairo& platformContext, const Path& path, const StrokeSource& strokeSource, const ShadowState& shadowState, GraphicsContext& targetContext)
{
cairo_t* cr = platformContext.cr();
setPathOnCairoContext(cr, path.platformPath()->context());
- drawPathShadow(platformContext, { }, strokeSource, targetContext, Stroke);
+ drawPathShadow(platformContext, { }, strokeSource, shadowState, targetContext, Stroke);
platformContext.prepareForStroking(strokeSource, PlatformContextCairo::PreserveAlpha);
cairo_stroke(cr);
}
@@ -653,9 +653,9 @@
cairo_restore(cr);
}
-void drawGlyphs(PlatformContextCairo& platformContext, const FillSource& fillSource, const StrokeSource& strokeSource, const ShadowBlurUsage& shadowBlurUsage, const FloatPoint& point, cairo_scaled_font_t* scaledFont, double syntheticBoldOffset, const Vector<cairo_glyph_t>& glyphs, float xOffset, TextDrawingModeFlags textDrawingMode, float strokeThickness, const FloatSize& shadowOffset, const Color& shadowColor, GraphicsContext& targetContext)
+void drawGlyphs(PlatformContextCairo& platformContext, const FillSource& fillSource, const StrokeSource& strokeSource, const ShadowState& shadowState, const FloatPoint& point, cairo_scaled_font_t* scaledFont, double syntheticBoldOffset, const Vector<cairo_glyph_t>& glyphs, float xOffset, TextDrawingModeFlags textDrawingMode, float strokeThickness, const FloatSize& shadowOffset, const Color& shadowColor, GraphicsContext& targetContext)
{
- drawGlyphsShadow(platformContext, shadowBlurUsage, textDrawingMode, shadowOffset, shadowColor, point, scaledFont, syntheticBoldOffset, glyphs, targetContext);
+ drawGlyphsShadow(platformContext, shadowState, textDrawingMode, shadowOffset, shadowColor, point, scaledFont, syntheticBoldOffset, glyphs, targetContext);
cairo_t* cr = platformContext.cr();
cairo_save(cr);
@@ -682,7 +682,7 @@
cairo_restore(cr);
}
-void drawNativeImage(PlatformContextCairo& platformContext, cairo_surface_t* surface, const FloatRect& destRect, const FloatRect& srcRect, CompositeOperator compositeOperator, BlendMode blendMode, ImageOrientation orientation, GraphicsContext& targetContext)
+void drawNativeImage(PlatformContextCairo& platformContext, cairo_surface_t* surface, const FloatRect& destRect, const FloatRect& srcRect, CompositeOperator compositeOperator, BlendMode blendMode, ImageOrientation orientation, const ShadowState& shadowState, GraphicsContext& targetContext)
{
platformContext.save();
@@ -705,7 +705,7 @@
}
}
- platformContext.drawSurfaceToContext(surface, dst, srcRect, targetContext);
+ platformContext.drawSurfaceToContext(surface, dst, srcRect, shadowState, targetContext);
platformContext.restore();
}
Modified: trunk/Source/WebCore/platform/graphics/cairo/CairoOperations.h (227050 => 227051)
--- trunk/Source/WebCore/platform/graphics/cairo/CairoOperations.h 2018-01-17 08:59:01 UTC (rev 227050)
+++ trunk/Source/WebCore/platform/graphics/cairo/CairoOperations.h 2018-01-17 09:20:54 UTC (rev 227051)
@@ -67,9 +67,6 @@
void setCTM(PlatformContextCairo&, const AffineTransform&);
AffineTransform getCTM(PlatformContextCairo&);
-void setShadowValues(PlatformContextCairo&, const FloatSize&, const FloatSize&, const Color&, bool);
-void clearShadow(PlatformContextCairo&);
-
IntRect getClipBounds(PlatformContextCairo&);
FloatRect roundToDevicePixels(PlatformContextCairo&, const FloatRect&);
@@ -109,14 +106,16 @@
Color color;
};
-struct ShadowBlurUsage {
- explicit ShadowBlurUsage(const GraphicsContextState&);
+struct ShadowState {
+ explicit ShadowState(const GraphicsContextState&);
- bool required(PlatformContextCairo&) const;
+ bool isVisible() const;
+ bool isRequired(PlatformContextCairo&) const;
- Color shadowColor;
- float shadowBlur { 0 };
- bool shadowsIgnoreTransforms { false };
+ FloatSize offset;
+ float blur { 0 };
+ Color color;
+ bool ignoreTransforms { false };
};
void setLineCap(PlatformContextCairo&, LineCap);
@@ -124,19 +123,19 @@
void setLineJoin(PlatformContextCairo&, LineJoin);
void setMiterLimit(PlatformContextCairo&, float);
-void fillRect(PlatformContextCairo&, const FloatRect&, const FillSource&, GraphicsContext&);
-void fillRect(PlatformContextCairo&, const FloatRect&, const Color&, bool, GraphicsContext&);
+void fillRect(PlatformContextCairo&, const FloatRect&, const FillSource&, const ShadowState&, GraphicsContext&);
+void fillRect(PlatformContextCairo&, const FloatRect&, const Color&, const ShadowState&, GraphicsContext&);
void fillRect(PlatformContextCairo&, const FloatRect&, cairo_pattern_t*);
-void fillRoundedRect(PlatformContextCairo&, const FloatRoundedRect&, const Color&, bool, GraphicsContext&);
-void fillRectWithRoundedHole(PlatformContextCairo&, const FloatRect&, const FloatRoundedRect&, const FillSource&, const ShadowBlurUsage&, GraphicsContext&);
-void fillPath(PlatformContextCairo&, const Path&, const FillSource&, GraphicsContext&);
-void strokeRect(PlatformContextCairo&, const FloatRect&, float, const StrokeSource&, GraphicsContext&);
-void strokePath(PlatformContextCairo&, const Path&, const StrokeSource&, GraphicsContext&);
+void fillRoundedRect(PlatformContextCairo&, const FloatRoundedRect&, const Color&, const ShadowState&, bool, GraphicsContext&);
+void fillRectWithRoundedHole(PlatformContextCairo&, const FloatRect&, const FloatRoundedRect&, const FillSource&, const ShadowState&, GraphicsContext&);
+void fillPath(PlatformContextCairo&, const Path&, const FillSource&, const ShadowState&, GraphicsContext&);
+void strokeRect(PlatformContextCairo&, const FloatRect&, float, const StrokeSource&, const ShadowState&, GraphicsContext&);
+void strokePath(PlatformContextCairo&, const Path&, const StrokeSource&, const ShadowState&, GraphicsContext&);
void clearRect(PlatformContextCairo&, const FloatRect&);
-void drawGlyphs(PlatformContextCairo&, const FillSource&, const StrokeSource&, const ShadowBlurUsage&, const FloatPoint&, cairo_scaled_font_t*, double, const Vector<cairo_glyph_t>&, float, TextDrawingModeFlags, float, const FloatSize&, const Color&, GraphicsContext&);
+void drawGlyphs(PlatformContextCairo&, const FillSource&, const StrokeSource&, const ShadowState&, const FloatPoint&, cairo_scaled_font_t*, double, const Vector<cairo_glyph_t>&, float, TextDrawingModeFlags, float, const FloatSize&, const Color&, GraphicsContext&);
-void drawNativeImage(PlatformContextCairo&, cairo_surface_t*, const FloatRect&, const FloatRect&, CompositeOperator, BlendMode, ImageOrientation, GraphicsContext&);
+void drawNativeImage(PlatformContextCairo&, cairo_surface_t*, const FloatRect&, const FloatRect&, CompositeOperator, BlendMode, ImageOrientation, const ShadowState&, GraphicsContext&);
void drawPattern(PlatformContextCairo&, cairo_surface_t*, const IntSize&, const FloatRect&, const FloatRect&, const AffineTransform&, const FloatPoint&, CompositeOperator, BlendMode);
void drawRect(PlatformContextCairo&, const FloatRect&, float, const Color&, StrokeStyle, const Color&);
Modified: trunk/Source/WebCore/platform/graphics/cairo/FontCairo.cpp (227050 => 227051)
--- trunk/Source/WebCore/platform/graphics/cairo/FontCairo.cpp 2018-01-17 08:59:01 UTC (rev 227050)
+++ trunk/Source/WebCore/platform/graphics/cairo/FontCairo.cpp 2018-01-17 09:20:54 UTC (rev 227051)
@@ -73,7 +73,7 @@
ASSERT(context.hasPlatformContext());
auto& state = context.state();
Cairo::drawGlyphs(*context.platformContext(), Cairo::FillSource(state), Cairo::StrokeSource(state),
- Cairo::ShadowBlurUsage(state), point, scaledFont, syntheticBoldOffset, glyphs, xOffset,
+ Cairo::ShadowState(state), point, scaledFont, syntheticBoldOffset, glyphs, xOffset,
state.textDrawingMode, state.strokeThickness, state.shadowOffset, state.shadowColor, context);
}
Modified: trunk/Source/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp (227050 => 227051)
--- trunk/Source/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp 2018-01-17 08:59:01 UTC (rev 227050)
+++ trunk/Source/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp 2018-01-17 09:20:54 UTC (rev 227051)
@@ -109,9 +109,6 @@
{
ASSERT(hasPlatformContext());
Cairo::restore(*platformContext());
-
- Cairo::State::setShadowValues(*platformContext(), FloatSize { m_state.shadowBlur, m_state.shadowBlur },
- m_state.shadowOffset, m_state.shadowColor, m_state.shadowsIgnoreTransforms);
}
// Draws a filled rectangle with a stroked border.
@@ -142,7 +139,7 @@
}
ASSERT(hasPlatformContext());
- Cairo::drawNativeImage(*platformContext(), image.get(), destRect, srcRect, compositeOperator, blendMode, orientation, *this);
+ Cairo::drawNativeImage(*platformContext(), image.get(), destRect, srcRect, compositeOperator, blendMode, orientation, Cairo::ShadowState(state()), *this);
}
// This is only used to draw borders, so we should not draw shadows.
@@ -191,7 +188,8 @@
}
ASSERT(hasPlatformContext());
- Cairo::fillPath(*platformContext(), path, Cairo::FillSource(state()), *this);
+ auto& state = this->state();
+ Cairo::fillPath(*platformContext(), path, Cairo::FillSource(state), Cairo::ShadowState(state), *this);
}
void GraphicsContext::strokePath(const Path& path)
@@ -205,7 +203,8 @@
}
ASSERT(hasPlatformContext());
- Cairo::strokePath(*platformContext(), path, Cairo::StrokeSource(state()), *this);
+ auto& state = this->state();
+ Cairo::strokePath(*platformContext(), path, Cairo::StrokeSource(state), Cairo::ShadowState(state), *this);
}
void GraphicsContext::fillRect(const FloatRect& rect)
@@ -219,7 +218,8 @@
}
ASSERT(hasPlatformContext());
- Cairo::fillRect(*platformContext(), rect, Cairo::FillSource(state()), *this);
+ auto& state = this->state();
+ Cairo::fillRect(*platformContext(), rect, Cairo::FillSource(state), Cairo::ShadowState(state), *this);
}
void GraphicsContext::fillRect(const FloatRect& rect, const Color& color)
@@ -233,7 +233,7 @@
}
ASSERT(hasPlatformContext());
- Cairo::fillRect(*platformContext(), rect, color, hasShadow(), *this);
+ Cairo::fillRect(*platformContext(), rect, color, Cairo::ShadowState(state()), *this);
}
void GraphicsContext::clip(const FloatRect& rect)
@@ -451,31 +451,17 @@
Cairo::State::setCTM(*platformContext(), transform);
}
-void GraphicsContext::setPlatformShadow(const FloatSize& offset, float blur, const Color& color)
+void GraphicsContext::setPlatformShadow(const FloatSize& offset, float, const Color&)
{
- if (paintingDisabled())
- return;
-
- FloatSize adjustedOffset = offset;
if (m_state.shadowsIgnoreTransforms) {
// Meaning that this graphics context is associated with a CanvasRenderingContext
// We flip the height since CG and HTML5 Canvas have opposite Y axis
- adjustedOffset.setHeight(-offset.height());
- m_state.shadowOffset = adjustedOffset;
+ m_state.shadowOffset = { offset.width(), -offset.height() };
}
-
- ASSERT(hasPlatformContext());
- Cairo::State::setShadowValues(*platformContext(), FloatSize { blur, blur },
- adjustedOffset, color, m_state.shadowsIgnoreTransforms);
}
void GraphicsContext::clearPlatformShadow()
{
- if (paintingDisabled())
- return;
-
- ASSERT(hasPlatformContext());
- Cairo::State::clearShadow(*platformContext());
}
void GraphicsContext::beginPlatformTransparencyLayer(float opacity)
@@ -526,7 +512,8 @@
}
ASSERT(hasPlatformContext());
- Cairo::strokeRect(*platformContext(), rect, lineWidth, Cairo::StrokeSource(state()), *this);
+ auto& state = this->state();
+ Cairo::strokeRect(*platformContext(), rect, lineWidth, Cairo::StrokeSource(state), Cairo::ShadowState(state), *this);
}
void GraphicsContext::setLineCap(LineCap lineCap)
@@ -667,7 +654,7 @@
return;
ASSERT(hasPlatformContext());
- Cairo::fillRoundedRect(*platformContext(), rect, color, hasShadow(), *this);
+ Cairo::fillRoundedRect(*platformContext(), rect, color, Cairo::ShadowState(state()), *this);
}
void GraphicsContext::fillRectWithRoundedHole(const FloatRect& rect, const FloatRoundedRect& roundedHoleRect, const Color& color)
@@ -682,7 +669,7 @@
ASSERT(hasPlatformContext());
auto& state = this->state();
- Cairo::fillRectWithRoundedHole(*platformContext(), rect, roundedHoleRect, Cairo::FillSource(state), Cairo::ShadowBlurUsage(state), *this);
+ Cairo::fillRectWithRoundedHole(*platformContext(), rect, roundedHoleRect, Cairo::FillSource(state), Cairo::ShadowState(state), *this);
}
void GraphicsContext::drawPattern(Image& image, const FloatRect& destRect, const FloatRect& tileRect, const AffineTransform& patternTransform, const FloatPoint& phase, const FloatSize& spacing, CompositeOperator compositeOperator, BlendMode blendMode)
Modified: trunk/Source/WebCore/platform/graphics/cairo/PlatformContextCairo.cpp (227050 => 227051)
--- trunk/Source/WebCore/platform/graphics/cairo/PlatformContextCairo.cpp 2018-01-17 08:59:01 UTC (rev 227050)
+++ trunk/Source/WebCore/platform/graphics/cairo/PlatformContextCairo.cpp 2018-01-17 09:20:54 UTC (rev 227051)
@@ -157,7 +157,7 @@
cairo_fill(cr);
}
-void PlatformContextCairo::drawSurfaceToContext(cairo_surface_t* surface, const FloatRect& destRect, const FloatRect& originalSrcRect, GraphicsContext& context)
+void PlatformContextCairo::drawSurfaceToContext(cairo_surface_t* surface, const FloatRect& destRect, const FloatRect& originalSrcRect, const Cairo::ShadowState& shadowState, GraphicsContext& context)
{
// Avoid invalid cairo matrix with small values.
if (std::fabs(destRect.width()) < 0.5f || std::fabs(destRect.height()) < 0.5f)
@@ -218,7 +218,7 @@
cairo_matrix_t matrix = { scaleX, 0, 0, scaleY, leftPadding, topPadding };
cairo_pattern_set_matrix(pattern.get(), &matrix);
- ShadowBlur& shadow = context.platformContext()->shadowBlur();
+ ShadowBlur shadow({ shadowState.blur, shadowState.blur }, shadowState.offset, shadowState.color, shadowState.ignoreTransforms);
if (shadow.type() != ShadowBlur::NoShadow) {
if (GraphicsContext* shadowContext = shadow.beginShadowLayer(context, destRect)) {
drawPatternToCairoContext(shadowContext->platformContext()->cr(), pattern.get(), destRect, 1);
Modified: trunk/Source/WebCore/platform/graphics/cairo/PlatformContextCairo.h (227050 => 227051)
--- trunk/Source/WebCore/platform/graphics/cairo/PlatformContextCairo.h 2018-01-17 08:59:01 UTC (rev 227050)
+++ trunk/Source/WebCore/platform/graphics/cairo/PlatformContextCairo.h 2018-01-17 09:20:54 UTC (rev 227051)
@@ -40,6 +40,7 @@
namespace Cairo {
struct FillSource;
struct StrokeSource;
+struct ShadowState;
}
// Much like PlatformContextSkia in the Skia port, this class holds information that
@@ -59,7 +60,6 @@
GraphicsContextPlatformPrivate* graphicsContextPrivate() { return m_graphicsContextPrivate; }
void setGraphicsContextPrivate(GraphicsContextPlatformPrivate* graphicsContextPrivate) { m_graphicsContextPrivate = graphicsContextPrivate; }
- ShadowBlur& shadowBlur() { return m_shadowBlur; }
Vector<float>& layers() { return m_layers; }
void save();
@@ -68,7 +68,7 @@
float globalAlpha() const;
void pushImageMask(cairo_surface_t*, const FloatRect&);
- WEBCORE_EXPORT void drawSurfaceToContext(cairo_surface_t*, const FloatRect& destRect, const FloatRect& srcRect, GraphicsContext&);
+ WEBCORE_EXPORT void drawSurfaceToContext(cairo_surface_t*, const FloatRect& destRect, const FloatRect& srcRect, const Cairo::ShadowState&, GraphicsContext&);
void setImageInterpolationQuality(InterpolationQuality);
InterpolationQuality imageInterpolationQuality() const;
@@ -93,9 +93,6 @@
State* m_state;
WTF::Vector<State> m_stateStack;
- // GraphicsContext is responsible for managing the state of the ShadowBlur,
- // so it does not need to be on the state stack.
- ShadowBlur m_shadowBlur;
// Transparency layers.
Vector<float> m_layers;
};
Modified: trunk/Source/WebCore/platform/graphics/win/MediaPlayerPrivateMediaFoundation.cpp (227050 => 227051)
--- trunk/Source/WebCore/platform/graphics/win/MediaPlayerPrivateMediaFoundation.cpp 2018-01-17 08:59:01 UTC (rev 227050)
+++ trunk/Source/WebCore/platform/graphics/win/MediaPlayerPrivateMediaFoundation.cpp 2018-01-17 09:20:54 UTC (rev 227051)
@@ -34,6 +34,7 @@
#include "HostWindow.h"
#include "NotImplemented.h"
#if USE(CAIRO)
+#include "CairoOperations.h"
#include "PlatformContextCairo.h"
#include <cairo.h>
#endif
@@ -2973,7 +2974,7 @@
FloatRect srcRect(0, 0, width, height);
if (image) {
WebCore::PlatformContextCairo* ctxt = context.platformContext();
- ctxt->drawSurfaceToContext(image, destRect, srcRect, context);
+ ctxt->drawSurfaceToContext(image, destRect, srcRect, Cairo::ShadowState(context.state()), context);
cairo_surface_destroy(image);
}
#else
Modified: trunk/Source/WebKit/ChangeLog (227050 => 227051)
--- trunk/Source/WebKit/ChangeLog 2018-01-17 08:59:01 UTC (rev 227050)
+++ trunk/Source/WebKit/ChangeLog 2018-01-17 09:20:54 UTC (rev 227051)
@@ -1,3 +1,16 @@
+2018-01-17 Zan Dobersek <[email protected]>
+
+ [Cairo] Use one-time ShadowBlur objects when performing shadowing
+ https://bugs.webkit.org/show_bug.cgi?id=181720
+
+ Reviewed by Carlos Garcia Campos.
+
+ * Shared/cairo/ShareableBitmapCairo.cpp:
+ (WebKit::ShareableBitmap::paint):
+ Adjust the PlatformContextCairo::drawSurfaceToContext() invocation.
+ * WebProcess/WebCoreSupport/gtk/WebDragClientGtk.cpp:
+ (WebKit::convertCairoSurfaceToShareableBitmap): Ditto.
+
2018-01-16 Fujii Hironori <[email protected]>
[CMake] Remove WebCoreDerivedSources library target
Modified: trunk/Source/WebKit/Shared/cairo/ShareableBitmapCairo.cpp (227050 => 227051)
--- trunk/Source/WebKit/Shared/cairo/ShareableBitmapCairo.cpp 2018-01-17 08:59:01 UTC (rev 227050)
+++ trunk/Source/WebKit/Shared/cairo/ShareableBitmapCairo.cpp 2018-01-17 09:20:54 UTC (rev 227051)
@@ -29,6 +29,7 @@
#include "ShareableBitmap.h"
#include <WebCore/BitmapImage.h>
+#include <WebCore/CairoOperations.h>
#include <WebCore/CairoUtilities.h>
#include <WebCore/GraphicsContext.h>
#include <WebCore/PlatformContextCairo.h>
@@ -74,7 +75,7 @@
FloatRect destRect(dstPoint, srcRect.size());
FloatRect srcRectScaled(srcRect);
srcRectScaled.scale(scaleFactor);
- context.platformContext()->drawSurfaceToContext(surface.get(), destRect, srcRectScaled, context);
+ context.platformContext()->drawSurfaceToContext(surface.get(), destRect, srcRectScaled, Cairo::ShadowState(context.state()), context);
}
RefPtr<cairo_surface_t> ShareableBitmap::createCairoSurface()
Modified: trunk/Source/WebKit/WebProcess/WebCoreSupport/gtk/WebDragClientGtk.cpp (227050 => 227051)
--- trunk/Source/WebKit/WebProcess/WebCoreSupport/gtk/WebDragClientGtk.cpp 2018-01-17 08:59:01 UTC (rev 227050)
+++ trunk/Source/WebKit/WebProcess/WebCoreSupport/gtk/WebDragClientGtk.cpp 2018-01-17 09:20:54 UTC (rev 227051)
@@ -33,6 +33,7 @@
#include "WebPage.h"
#include "WebPageProxyMessages.h"
#include "WebSelectionData.h"
+#include <WebCore/CairoOperations.h>
#include <WebCore/DataTransfer.h>
#include <WebCore/DragData.h>
#include <WebCore/GraphicsContext.h>
@@ -53,7 +54,7 @@
RefPtr<ShareableBitmap> bitmap = ShareableBitmap::createShareable(imageSize, { });
auto graphicsContext = bitmap->createGraphicsContext();
- graphicsContext->platformContext()->drawSurfaceToContext(surface, IntRect(IntPoint(), imageSize), IntRect(IntPoint(), imageSize), *graphicsContext);
+ graphicsContext->platformContext()->drawSurfaceToContext(surface, IntRect(IntPoint(), imageSize), IntRect(IntPoint(), imageSize), Cairo::ShadowState(graphicsContext->state()), *graphicsContext);
return bitmap;
}