Title: [227051] trunk/Source
Revision
227051
Author
[email protected]
Date
2018-01-17 01:20:54 -0800 (Wed, 17 Jan 2018)

Log Message

[Cairo] Use one-time ShadowBlur objects when performing shadowing
https://bugs.webkit.org/show_bug.cgi?id=181720

Reviewed by Carlos Garcia Campos.

Source/WebCore:

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):

Source/WebKit:

* Shared/cairo/ShareableBitmapCairo.cpp:
(WebKit::ShareableBitmap::paint):
Adjust the PlatformContextCairo::drawSurfaceToContext() invocation.
* WebProcess/WebCoreSupport/gtk/WebDragClientGtk.cpp:
(WebKit::convertCairoSurfaceToShareableBitmap): Ditto.

Modified Paths

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;
 }
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to