Refactor ShadowBlur: remove some class variables and use function parameters instead.
authorclopez@igalia.com <clopez@igalia.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 12 Jul 2019 12:31:42 +0000 (12:31 +0000)
committerclopez@igalia.com <clopez@igalia.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 12 Jul 2019 12:31:42 +0000 (12:31 +0000)
https://bugs.webkit.org/show_bug.cgi?id=199511

Reviewed by Said Abou-Hallawa.

On the ShadowBlur class it is confusing to know if the status of the m_layerImage buffer or the
values calculated by calculateLayerBoundingRect() are valid between the different function calls.

To avoid this problem, pass this values as function parameters instead of storing them in the class.

No new tests, no intended behaviour change.

* platform/graphics/ShadowBlur.cpp:
(WebCore::ShadowBlur::ShadowBlur):
(WebCore::ShadowBlur::calculateLayerBoundingRect):
(WebCore::ShadowBlur::drawShadowBuffer):
(WebCore::ShadowBlur::drawRectShadow): Pass the parameters from the callback.
(WebCore::ShadowBlur::drawInsetShadow): Ditto.
(WebCore::ShadowBlur::drawRectShadowWithoutTiling):
(WebCore::ShadowBlur::drawInsetShadowWithoutTiling):
(WebCore::ShadowBlur::drawRectShadowWithTiling):
(WebCore::ShadowBlur::drawInsetShadowWithTiling):
(WebCore::ShadowBlur::drawLayerPieces):
(WebCore::ShadowBlur::drawLayerPiecesAndFillCenter):
(WebCore::ShadowBlur::blurShadowBuffer):
(WebCore::ShadowBlur::blurAndColorShadowBuffer):
(WebCore::ShadowBlur::drawShadowLayer):
* platform/graphics/ShadowBlur.h: Use a struct to pass the values calculated on calculateLayerBoundingRect().

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@247385 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/platform/graphics/ShadowBlur.cpp
Source/WebCore/platform/graphics/ShadowBlur.h

index d4b20ee..98d1b15 100644 (file)
@@ -1,3 +1,34 @@
+2019-07-12  Carlos Alberto Lopez Perez  <clopez@igalia.com>
+
+        Refactor ShadowBlur: remove some class variables and use function parameters instead.
+        https://bugs.webkit.org/show_bug.cgi?id=199511
+
+        Reviewed by Said Abou-Hallawa.
+
+        On the ShadowBlur class it is confusing to know if the status of the m_layerImage buffer or the
+        values calculated by calculateLayerBoundingRect() are valid between the different function calls.
+
+        To avoid this problem, pass this values as function parameters instead of storing them in the class.
+
+        No new tests, no intended behaviour change.
+
+        * platform/graphics/ShadowBlur.cpp:
+        (WebCore::ShadowBlur::ShadowBlur):
+        (WebCore::ShadowBlur::calculateLayerBoundingRect):
+        (WebCore::ShadowBlur::drawShadowBuffer):
+        (WebCore::ShadowBlur::drawRectShadow): Pass the parameters from the callback.
+        (WebCore::ShadowBlur::drawInsetShadow): Ditto.
+        (WebCore::ShadowBlur::drawRectShadowWithoutTiling):
+        (WebCore::ShadowBlur::drawInsetShadowWithoutTiling):
+        (WebCore::ShadowBlur::drawRectShadowWithTiling):
+        (WebCore::ShadowBlur::drawInsetShadowWithTiling):
+        (WebCore::ShadowBlur::drawLayerPieces):
+        (WebCore::ShadowBlur::drawLayerPiecesAndFillCenter):
+        (WebCore::ShadowBlur::blurShadowBuffer):
+        (WebCore::ShadowBlur::blurAndColorShadowBuffer):
+        (WebCore::ShadowBlur::drawShadowLayer):
+        * platform/graphics/ShadowBlur.h: Use a struct to pass the values calculated on calculateLayerBoundingRect().
+
 2019-07-12  Adrian Perez de Castro  <aperez@igalia.com>
 
         [ATK] Avoid unneeded call to to core(selection) in listObjectForSelection()
index b01596d..eadaa18 100644 (file)
@@ -184,7 +184,6 @@ ShadowBlur::ShadowBlur(const GraphicsContextState& state)
     : m_color(state.shadowColor)
     , m_blurRadius(state.shadowBlur, state.shadowBlur)
     , m_offset(state.shadowOffset)
-    , m_layerImage(0)
     , m_shadowsIgnoreTransforms(state.shadowsIgnoreTransforms)
 {
 #if USE(CG)
@@ -379,8 +378,10 @@ IntSize ShadowBlur::blurredEdgeSize() const
     return edgeSize;
 }
 
-IntSize ShadowBlur::calculateLayerBoundingRect(const AffineTransform& transform, const FloatRect& shadowedRect, const IntRect& clipRect)
+Optional<ShadowBlur::LayerImageProperties> ShadowBlur::calculateLayerBoundingRect(const AffineTransform& transform, const FloatRect& shadowedRect, const IntRect& clipRect)
 {
+    LayerImageProperties calculatedLayerImageProperties;
+
     IntSize edgeSize = blurredEdgeSize();
 
     // Calculate the destination of the blurred and/or transformed layer.
@@ -408,7 +409,7 @@ IntSize ShadowBlur::calculateLayerBoundingRect(const AffineTransform& transform,
     if (!clipRect.contains(enclosingIntRect(layerRect))) {
         // If we are totally outside the clip region, we aren't painting at all.
         if (intersection(layerRect, clipRect).isEmpty())
-            return IntSize();
+            return WTF::nullopt;
 
         IntRect inflatedClip = clipRect;
         // Pixels at the edges can be affected by pixels outside the buffer,
@@ -428,40 +429,37 @@ IntSize ShadowBlur::calculateLayerBoundingRect(const AffineTransform& transform,
 
     IntSize frameSize = inflation;
     frameSize.scale(2);
-    m_shadowedResultSize = FloatSize(shadowedRect.width() + frameSize.width(), shadowedRect.height() + frameSize.height());
-    m_layerOrigin = FloatPoint(layerRect.x(), layerRect.y());
-    m_layerSize = layerRect.size();
+    calculatedLayerImageProperties.shadowedResultSize = FloatSize(shadowedRect.width() + frameSize.width(), shadowedRect.height() + frameSize.height());
+    calculatedLayerImageProperties.layerOrigin = FloatPoint(layerRect.x(), layerRect.y());
+    calculatedLayerImageProperties.layerSize = layerRect.size();
 
     const FloatPoint unclippedLayerOrigin = FloatPoint(unclippedLayerRect.x(), unclippedLayerRect.y());
-    const FloatSize clippedOut = unclippedLayerOrigin - m_layerOrigin;
+    const FloatSize clippedOut = unclippedLayerOrigin - calculatedLayerImageProperties.layerOrigin;
 
     // Set the origin as the top left corner of the scratch image, or, in case there's a clipped
     // out region, set the origin accordingly to the full bounding rect's top-left corner.
     float translationX = -shadowedRect.x() + inflation.width() - fabsf(clippedOut.width());
     float translationY = -shadowedRect.y() + inflation.height() - fabsf(clippedOut.height());
-    m_layerContextTranslation = FloatSize(translationX, translationY);
+    calculatedLayerImageProperties.layerContextTranslation = FloatSize(translationX, translationY);
 
-    return expandedIntSize(layerRect.size());
+    return calculatedLayerImageProperties;
 }
 
-void ShadowBlur::drawShadowBuffer(GraphicsContext& graphicsContext)
+void ShadowBlur::drawShadowBuffer(GraphicsContext& graphicsContext, ImageBuffer& layerImage, const FloatPoint& layerOrigin, const FloatSize& layerSize)
 {
-    if (!m_layerImage)
-        return;
-
     GraphicsContextStateSaver stateSaver(graphicsContext);
 
-    IntSize bufferSize = m_layerImage->internalSize();
-    if (bufferSize != m_layerSize) {
+    IntSize bufferSize = layerImage.internalSize();
+    if (bufferSize != layerSize) {
         // The rect passed to clipToImageBuffer() has to be the size of the entire buffer,
         // but we may not have cleared it all, so clip to the filled part first.
-        graphicsContext.clip(FloatRect(m_layerOrigin, m_layerSize));
+        graphicsContext.clip(FloatRect(layerOrigin, layerSize));
     }
-    graphicsContext.clipToImageBuffer(*m_layerImage, FloatRect(m_layerOrigin, bufferSize));
+    graphicsContext.clipToImageBuffer(layerImage, FloatRect(layerOrigin, bufferSize));
     graphicsContext.setFillColor(m_color);
 
     graphicsContext.clearShadow();
-    graphicsContext.fillRect(FloatRect(m_layerOrigin, m_layerSize));
+    graphicsContext.fillRect(FloatRect(layerOrigin, layerSize));
 }
 
 static void computeSliceSizesFromRadii(const IntSize& twiceRadius, const FloatRoundedRect::Radii& radii, int& leftSlice, int& rightSlice, int& topSlice, int& bottomSlice)
@@ -493,9 +491,8 @@ IntSize ShadowBlur::templateSize(const IntSize& radiusPadding, const FloatRounde
 void ShadowBlur::drawRectShadow(GraphicsContext& graphicsContext, const FloatRoundedRect& shadowedRect)
 {
     drawRectShadow(graphicsContext.getCTM(), graphicsContext.clipBounds(), shadowedRect,
-        [this, &graphicsContext](ImageBuffer&, const FloatPoint&, const FloatSize&) {
-            // FIXME: Use parameters instead of implicit parameters defined as class variables.
-            drawShadowBuffer(graphicsContext);
+        [this, &graphicsContext](ImageBuffer& layerImage, const FloatPoint& layerOrigin, const FloatSize& layerSize) {
+            drawShadowBuffer(graphicsContext, layerImage, layerOrigin, layerSize);
         },
         [&graphicsContext](ImageBuffer& image, const FloatRect& destRect, const FloatRect& srcRect) {
             GraphicsContextStateSaver stateSaver(graphicsContext);
@@ -513,9 +510,8 @@ void ShadowBlur::drawRectShadow(GraphicsContext& graphicsContext, const FloatRou
 void ShadowBlur::drawInsetShadow(GraphicsContext& graphicsContext, const FloatRect& fullRect, const FloatRoundedRect& holeRect)
 {
     drawInsetShadow(graphicsContext.getCTM(), graphicsContext.clipBounds(), fullRect, holeRect,
-        [this, &graphicsContext](ImageBuffer&, const FloatPoint&, const FloatSize&) {
-            // FIXME: Use parameters instead of implicit parameters defined as class variables.
-            drawShadowBuffer(graphicsContext);
+        [this, &graphicsContext](ImageBuffer& layerImage, const FloatPoint& layerOrigin, const FloatSize& layerSize) {
+            drawShadowBuffer(graphicsContext, layerImage, layerOrigin, layerSize);
         },
         [&graphicsContext](ImageBuffer& image, const FloatRect& destRect, const FloatRect& srcRect) {
             // Note that drawing the ImageBuffer is faster than creating a Image and drawing that,
@@ -539,8 +535,8 @@ void ShadowBlur::drawInsetShadow(GraphicsContext& graphicsContext, const FloatRe
 
 void ShadowBlur::drawRectShadow(const AffineTransform& transform, const IntRect& clipBounds, const FloatRoundedRect& shadowedRect, const DrawBufferCallback& drawBuffer, const DrawImageCallback& drawImage, const FillRectCallback& fillRect)
 {
-    IntSize layerSize = calculateLayerBoundingRect(transform, shadowedRect.rect(), clipBounds);
-    if (layerSize.isEmpty())
+    auto layerImageProperties = calculateLayerBoundingRect(transform, shadowedRect.rect(), clipBounds);
+    if (!layerImageProperties)
         return;
 
     adjustBlurRadius(transform);
@@ -557,19 +553,19 @@ void ShadowBlur::drawRectShadow(const AffineTransform& transform, const IntRect&
     const FloatRect& rect = shadowedRect.rect();
 
     if (templateSize.width() > rect.width() || templateSize.height() > rect.height()
-        || (templateSize.width() * templateSize.height() > m_shadowedResultSize.width() * m_shadowedResultSize.height()))
+        || (templateSize.area() > layerImageProperties->shadowedResultSize.area()))
         canUseTilingTechnique = false;
 
     if (canUseTilingTechnique)
-        drawRectShadowWithTiling(transform, shadowedRect, templateSize, edgeSize, drawImage, fillRect);
+        drawRectShadowWithTiling(transform, shadowedRect, templateSize, edgeSize, drawImage, fillRect, *layerImageProperties);
     else
-        drawRectShadowWithoutTiling(transform, shadowedRect, layerSize, drawBuffer);
+        drawRectShadowWithoutTiling(transform, shadowedRect, *layerImageProperties, drawBuffer);
 }
 
 void ShadowBlur::drawInsetShadow(const AffineTransform& transform, const IntRect& clipBounds, const FloatRect& fullRect, const FloatRoundedRect& holeRect, const DrawBufferCallback& drawBuffer, const DrawImageCallback& drawImage, const FillRectWithHoleCallback& fillRectWithHole)
 {
-    IntSize layerSize = calculateLayerBoundingRect(transform, fullRect, clipBounds);
-    if (layerSize.isEmpty())
+    auto layerImageProperties = calculateLayerBoundingRect(transform, fullRect, clipBounds);
+    if (!layerImageProperties)
         return;
 
     adjustBlurRadius(transform);
@@ -592,15 +588,14 @@ void ShadowBlur::drawInsetShadow(const AffineTransform& transform, const IntRect
     if (canUseTilingTechnique)
         drawInsetShadowWithTiling(transform, fullRect, holeRect, templateSize, edgeSize, drawImage, fillRectWithHole);
     else
-        drawInsetShadowWithoutTiling(transform, fullRect, holeRect, layerSize, drawBuffer);
+        drawInsetShadowWithoutTiling(transform, fullRect, holeRect, *layerImageProperties, drawBuffer);
 }
 
-void ShadowBlur::drawRectShadowWithoutTiling(const AffineTransform&, const FloatRoundedRect& shadowedRect, const IntSize& layerSize, const DrawBufferCallback& drawBuffer)
+void ShadowBlur::drawRectShadowWithoutTiling(const AffineTransform&, const FloatRoundedRect& shadowedRect, const LayerImageProperties& layerImageProperties, const DrawBufferCallback& drawBuffer)
 {
-    auto layerImage = ImageBuffer::create(layerSize, Unaccelerated, 1);
+    auto layerImage = ImageBuffer::create(expandedIntSize(layerImageProperties.layerSize), Unaccelerated, 1);
     if (!layerImage)
         return;
-    m_layerImage = layerImage.get();
 
     GraphicsContext& shadowContext = layerImage->context();
     GraphicsContextStateSaver stateSaver(shadowContext);
@@ -609,7 +604,7 @@ void ShadowBlur::drawRectShadowWithoutTiling(const AffineTransform&, const Float
     {
         GraphicsContext& shadowContext = layerImage->context();
         GraphicsContextStateSaver stateSaver(shadowContext);
-        shadowContext.translate(m_layerContextTranslation);
+        shadowContext.translate(layerImageProperties.layerContextTranslation);
         shadowContext.setFillColor(Color::black);
         if (shadowedRect.radii().isZero())
             shadowContext.fillRect(shadowedRect.rect());
@@ -619,22 +614,21 @@ void ShadowBlur::drawRectShadowWithoutTiling(const AffineTransform&, const Float
             shadowContext.fillPath(path);
         }
 
-        blurShadowBuffer(layerSize);
+        blurShadowBuffer(*layerImage, expandedIntSize(layerImageProperties.layerSize));
     }
-    drawBuffer(*layerImage, m_layerOrigin, m_layerSize);
+    drawBuffer(*layerImage, layerImageProperties.layerOrigin, layerImageProperties.layerSize);
 }
 
-void ShadowBlur::drawInsetShadowWithoutTiling(const AffineTransform&, const FloatRect& fullRect, const FloatRoundedRect& holeRect, const IntSize& layerSize, const DrawBufferCallback& drawBuffer)
+void ShadowBlur::drawInsetShadowWithoutTiling(const AffineTransform&, const FloatRect& fullRect, const FloatRoundedRect& holeRect, const LayerImageProperties& layerImageProperties, const DrawBufferCallback& drawBuffer)
 {
-    auto layerImage = ImageBuffer::create(layerSize, Unaccelerated, 1);
+    auto layerImage = ImageBuffer::create(expandedIntSize(layerImageProperties.layerSize), Unaccelerated, 1);
     if (!layerImage)
         return;
-    m_layerImage = layerImage.get();
 
     {
         GraphicsContext& shadowContext = layerImage->context();
         GraphicsContextStateSaver stateSaver(shadowContext);
-        shadowContext.translate(m_layerContextTranslation);
+        shadowContext.translate(layerImageProperties.layerContextTranslation);
 
         Path path;
         path.addRect(fullRect);
@@ -647,10 +641,10 @@ void ShadowBlur::drawInsetShadowWithoutTiling(const AffineTransform&, const Floa
         shadowContext.setFillColor(Color::black);
         shadowContext.fillPath(path);
 
-        blurShadowBuffer(layerSize);
+        blurShadowBuffer(*layerImage, expandedIntSize(layerImageProperties.layerSize));
     }
 
-    drawBuffer(*layerImage, m_layerOrigin, m_layerSize);
+    drawBuffer(*layerImage, layerImageProperties.layerOrigin, layerImageProperties.layerSize);
 }
 
 /*
@@ -685,16 +679,17 @@ void ShadowBlur::drawInsetShadowWithoutTiling(const AffineTransform&, const Floa
      the shadow.
  */
 
-void ShadowBlur::drawRectShadowWithTiling(const AffineTransform& transform, const FloatRoundedRect& shadowedRect, const IntSize& templateSize, const IntSize& edgeSize, const DrawImageCallback& drawImage, const FillRectCallback& fillRect)
+void ShadowBlur::drawRectShadowWithTiling(const AffineTransform& transform, const FloatRoundedRect& shadowedRect, const IntSize& templateSize, const IntSize& edgeSize, const DrawImageCallback& drawImage, const FillRectCallback& fillRect, const LayerImageProperties& layerImageProperties)
 {
 #if USE(CG)
-    m_layerImage = ScratchBuffer::singleton().getScratchBuffer(templateSize);
+    auto* layerImage = ScratchBuffer::singleton().getScratchBuffer(templateSize);
 #else
-    auto layerImage = ImageBuffer::create(templateSize, Unaccelerated, 1);
-    m_layerImage = layerImage.get();
+    UNUSED_PARAM(layerImageProperties);
+    auto layerImageBuffer = ImageBuffer::create(templateSize, Unaccelerated, 1);
+    auto* layerImage = layerImageBuffer.get();
 #endif
 
-    if (!m_layerImage)
+    if (!layerImage)
         return;
 
     FloatRect templateShadow = FloatRect(edgeSize.width(), edgeSize.height(), templateSize.width() - 2 * edgeSize.width(), templateSize.height() - 2 * edgeSize.height());
@@ -702,12 +697,12 @@ void ShadowBlur::drawRectShadowWithTiling(const AffineTransform& transform, cons
     bool redrawNeeded = true;
 #if USE(CG)
     // Only redraw in the scratch buffer if its cached contents don't match our needs
-    redrawNeeded = ScratchBuffer::singleton().setCachedShadowValues(m_blurRadius, m_color, templateShadow, shadowedRect.radii(), m_layerSize);
+    redrawNeeded = ScratchBuffer::singleton().setCachedShadowValues(m_blurRadius, m_color, templateShadow, shadowedRect.radii(), layerImageProperties.layerSize);
 #endif
 
     if (redrawNeeded) {
         // Draw shadow into the ImageBuffer.
-        GraphicsContext& shadowContext = m_layerImage->context();
+        GraphicsContext& shadowContext = layerImage->context();
         GraphicsContextStateSaver shadowStateSaver(shadowContext);
 
         shadowContext.clearRect(FloatRect(0, 0, templateSize.width(), templateSize.height()));
@@ -720,7 +715,7 @@ void ShadowBlur::drawRectShadowWithTiling(const AffineTransform& transform, cons
             path.addRoundedRect(FloatRoundedRect(templateShadow, shadowedRect.radii()));
             shadowContext.fillPath(path);
         }
-        blurAndColorShadowBuffer(templateSize);
+        blurAndColorShadowBuffer(*layerImage, templateSize);
     }
 
     FloatSize offset = m_offset;
@@ -732,9 +727,7 @@ void ShadowBlur::drawRectShadowWithTiling(const AffineTransform& transform, cons
     shadowBounds.inflateX(edgeSize.width());
     shadowBounds.inflateY(edgeSize.height());
 
-    drawLayerPiecesAndFillCenter(shadowBounds, shadowedRect.radii(), edgeSize, templateSize, drawImage, fillRect);
-
-    m_layerImage = nullptr;
+    drawLayerPiecesAndFillCenter(*layerImage, shadowBounds, shadowedRect.radii(), edgeSize, templateSize, drawImage, fillRect);
 
 #if USE(CG)
     ScratchBuffer::singleton().scheduleScratchBufferPurge();
@@ -744,13 +737,13 @@ void ShadowBlur::drawRectShadowWithTiling(const AffineTransform& transform, cons
 void ShadowBlur::drawInsetShadowWithTiling(const AffineTransform& transform, const FloatRect& fullRect, const FloatRoundedRect& holeRect, const IntSize& templateSize, const IntSize& edgeSize, const DrawImageCallback& drawImage, const FillRectWithHoleCallback& fillRectWithHole)
 {
 #if USE(CG)
-    m_layerImage = ScratchBuffer::singleton().getScratchBuffer(templateSize);
+    auto* layerImage = ScratchBuffer::singleton().getScratchBuffer(templateSize);
 #else
-    auto layerImage = ImageBuffer::create(templateSize, Unaccelerated, 1);
-    m_layerImage = layerImage.get();
+    auto layerImageBuffer = ImageBuffer::create(templateSize, Unaccelerated, 1);
+    auto* layerImage = layerImageBuffer.get();
 #endif
 
-    if (!m_layerImage)
+    if (!layerImage)
         return;
 
     // Draw the rectangle with hole.
@@ -765,7 +758,7 @@ void ShadowBlur::drawInsetShadowWithTiling(const AffineTransform& transform, con
 
     if (redrawNeeded) {
         // Draw shadow into a new ImageBuffer.
-        GraphicsContext& shadowContext = m_layerImage->context();
+        GraphicsContext& shadowContext = layerImage->context();
         GraphicsContextStateSaver shadowStateSaver(shadowContext);
         shadowContext.clearRect(templateBounds);
         shadowContext.setFillRule(WindRule::EvenOdd);
@@ -780,7 +773,7 @@ void ShadowBlur::drawInsetShadowWithTiling(const AffineTransform& transform, con
 
         shadowContext.fillPath(path);
 
-        blurAndColorShadowBuffer(templateSize);
+        blurAndColorShadowBuffer(*layerImage, templateSize);
     }
     FloatSize offset = m_offset;
     if (shadowsIgnoreTransforms())
@@ -798,16 +791,14 @@ void ShadowBlur::drawInsetShadowWithTiling(const AffineTransform& transform, con
     // Fill the external part of the shadow (which may be visible because of offset).
     fillRectWithHole(boundingRect, destHoleBounds, m_color);
 
-    drawLayerPieces(destHoleBounds, holeRect.radii(), edgeSize, templateSize, drawImage);
-
-    m_layerImage = nullptr;
+    drawLayerPieces(*layerImage, destHoleBounds, holeRect.radii(), edgeSize, templateSize, drawImage);
 
 #if USE(CG)
     ScratchBuffer::singleton().scheduleScratchBufferPurge();
 #endif
 }
 
-void ShadowBlur::drawLayerPieces(const FloatRect& shadowBounds, const FloatRoundedRect::Radii& radii, const IntSize& bufferPadding, const IntSize& templateSize, const DrawImageCallback& drawImage)
+void ShadowBlur::drawLayerPieces(ImageBuffer& layerImage, const FloatRect& shadowBounds, const FloatRoundedRect::Radii& radii, const IntSize& bufferPadding, const IntSize& templateSize, const DrawImageCallback& drawImage)
 {
     const IntSize twiceRadius = IntSize(bufferPadding.width() * 2, bufferPadding.height() * 2);
 
@@ -824,49 +815,49 @@ void ShadowBlur::drawLayerPieces(const FloatRect& shadowBounds, const FloatRound
     // Top side.
     FloatRect tileRect = FloatRect(leftSlice, 0, templateSideLength, topSlice);
     FloatRect destRect = FloatRect(centerRect.x(), centerRect.y() - topSlice, centerRect.width(), topSlice);
-    drawImage(*m_layerImage, destRect, tileRect);
+    drawImage(layerImage, destRect, tileRect);
 
     // Draw the bottom side.
     tileRect.setY(templateSize.height() - bottomSlice);
     tileRect.setHeight(bottomSlice);
     destRect.setY(centerRect.maxY());
     destRect.setHeight(bottomSlice);
-    drawImage(*m_layerImage, destRect, tileRect);
+    drawImage(layerImage, destRect, tileRect);
 
     // Left side.
     tileRect = FloatRect(0, topSlice, leftSlice, templateSideLength);
     destRect = FloatRect(centerRect.x() - leftSlice, centerRect.y(), leftSlice, centerRect.height());
-    drawImage(*m_layerImage, destRect, tileRect);
+    drawImage(layerImage, destRect, tileRect);
 
     // Right side.
     tileRect.setX(templateSize.width() - rightSlice);
     tileRect.setWidth(rightSlice);
     destRect.setX(centerRect.maxX());
     destRect.setWidth(rightSlice);
-    drawImage(*m_layerImage, destRect, tileRect);
+    drawImage(layerImage, destRect, tileRect);
 
     // Top left corner.
     tileRect = FloatRect(0, 0, leftSlice, topSlice);
     destRect = FloatRect(centerRect.x() - leftSlice, centerRect.y() - topSlice, leftSlice, topSlice);
-    drawImage(*m_layerImage, destRect, tileRect);
+    drawImage(layerImage, destRect, tileRect);
 
     // Top right corner.
     tileRect = FloatRect(templateSize.width() - rightSlice, 0, rightSlice, topSlice);
     destRect = FloatRect(centerRect.maxX(), centerRect.y() - topSlice, rightSlice, topSlice);
-    drawImage(*m_layerImage, destRect, tileRect);
+    drawImage(layerImage, destRect, tileRect);
 
     // Bottom right corner.
     tileRect = FloatRect(templateSize.width() - rightSlice, templateSize.height() - bottomSlice, rightSlice, bottomSlice);
     destRect = FloatRect(centerRect.maxX(), centerRect.maxY(), rightSlice, bottomSlice);
-    drawImage(*m_layerImage, destRect, tileRect);
+    drawImage(layerImage, destRect, tileRect);
 
     // Bottom left corner.
     tileRect = FloatRect(0, templateSize.height() - bottomSlice, leftSlice, bottomSlice);
     destRect = FloatRect(centerRect.x() - leftSlice, centerRect.maxY(), leftSlice, bottomSlice);
-    drawImage(*m_layerImage, destRect, tileRect);
+    drawImage(layerImage, destRect, tileRect);
 }
 
-void ShadowBlur::drawLayerPiecesAndFillCenter(const FloatRect& shadowBounds, const FloatRoundedRect::Radii& radii, const IntSize& bufferPadding, const IntSize& templateSize, const DrawImageCallback& drawImage, const FillRectCallback& fillRect)
+void ShadowBlur::drawLayerPiecesAndFillCenter(ImageBuffer& layerImage, const FloatRect& shadowBounds, const FloatRoundedRect::Radii& radii, const IntSize& bufferPadding, const IntSize& templateSize, const DrawImageCallback& drawImage, const FillRectCallback& fillRect)
 {
     const IntSize twiceRadius = IntSize(bufferPadding.width() * 2, bufferPadding.height() * 2);
 
@@ -884,29 +875,29 @@ void ShadowBlur::drawLayerPiecesAndFillCenter(const FloatRect& shadowBounds, con
     if (!centerRect.isEmpty())
         fillRect(centerRect, m_color);
 
-    drawLayerPieces(shadowBounds, radii, bufferPadding, templateSize, drawImage);
+    drawLayerPieces(layerImage, shadowBounds, radii, bufferPadding, templateSize, drawImage);
 }
 
-void ShadowBlur::blurShadowBuffer(const IntSize& templateSize)
+void ShadowBlur::blurShadowBuffer(ImageBuffer& layerImage, const IntSize& templateSize)
 {
     if (m_type != BlurShadow)
         return;
 
     IntRect blurRect(IntPoint(), templateSize);
-    auto layerData = m_layerImage->getUnmultipliedImageData(blurRect);
+    auto layerData = layerImage.getUnmultipliedImageData(blurRect);
     if (!layerData)
         return;
 
     blurLayerImage(layerData->data(), blurRect.size(), blurRect.width() * 4);
-    m_layerImage->putByteArray(*layerData, AlphaPremultiplication::Unpremultiplied, blurRect.size(), blurRect, { });
+    layerImage.putByteArray(*layerData, AlphaPremultiplication::Unpremultiplied, blurRect.size(), blurRect, { });
 }
 
-void ShadowBlur::blurAndColorShadowBuffer(const IntSize& templateSize)
+void ShadowBlur::blurAndColorShadowBuffer(ImageBuffer& layerImage, const IntSize& templateSize)
 {
-    blurShadowBuffer(templateSize);
+    blurShadowBuffer(layerImage, templateSize);
 
     // Mask the image with the shadow color.
-    GraphicsContext& shadowContext = m_layerImage->context();
+    GraphicsContext& shadowContext = layerImage.context();
     GraphicsContextStateSaver stateSaver(shadowContext);
     shadowContext.setCompositeOperation(CompositeSourceIn);
     shadowContext.setFillColor(m_color);
@@ -915,26 +906,25 @@ void ShadowBlur::blurAndColorShadowBuffer(const IntSize& templateSize)
 
 void ShadowBlur::drawShadowLayer(const AffineTransform& transform, const IntRect& clipBounds, const FloatRect& layerArea, const DrawShadowCallback& drawShadow, const DrawBufferCallback& drawBuffer)
 {
-    IntSize layerSize = calculateLayerBoundingRect(transform, layerArea, clipBounds);
-    if (layerSize.isEmpty())
+    auto layerImageProperties = calculateLayerBoundingRect(transform, layerArea, clipBounds);
+    if (!layerImageProperties)
         return;
 
     adjustBlurRadius(transform);
 
-    auto layerImage = ImageBuffer::create(layerSize, Unaccelerated, 1);
+    auto layerImage = ImageBuffer::create(expandedIntSize(layerImageProperties->layerSize), Unaccelerated, 1);
     if (!layerImage)
         return;
-    m_layerImage = layerImage.get();
 
     {
         GraphicsContext& shadowContext = layerImage->context();
         GraphicsContextStateSaver stateSaver(shadowContext);
-        shadowContext.translate(m_layerContextTranslation);
+        shadowContext.translate(layerImageProperties->layerContextTranslation);
         drawShadow(shadowContext);
     }
 
-    blurAndColorShadowBuffer(expandedIntSize(m_layerSize));
-    drawBuffer(*layerImage, m_layerOrigin, m_layerSize);
+    blurAndColorShadowBuffer(*layerImage, expandedIntSize(layerImageProperties->layerSize));
+    drawBuffer(*layerImage, layerImageProperties->layerOrigin, layerImageProperties->layerSize);
 }
 
 } // namespace WebCore
index d6af402..8dae90c 100644 (file)
@@ -83,7 +83,7 @@ public:
 private:
     void updateShadowBlurValues();
 
-    void drawShadowBuffer(GraphicsContext&);
+    void drawShadowBuffer(GraphicsContext&, ImageBuffer&, const FloatPoint&, const FloatSize&);
 
     void adjustBlurRadius(const AffineTransform&);
 
@@ -92,20 +92,27 @@ private:
         InnerShadow
     };
 
-    IntSize calculateLayerBoundingRect(const AffineTransform&, const FloatRect& layerArea, const IntRect& clipRect);
+    struct LayerImageProperties {
+        FloatSize shadowedResultSize; // Size of the result of shadowing which is same as shadowedRect + blurred edges.
+        FloatPoint layerOrigin; // Top-left corner of the (possibly clipped) bounding rect to draw the shadow to.
+        FloatSize layerSize; // Size of layerImage pixels that need blurring.
+        FloatSize layerContextTranslation; // Translation to apply to layerContext for the shadow to be correctly clipped.
+    };
+
+    Optional<ShadowBlur::LayerImageProperties> calculateLayerBoundingRect(const AffineTransform&, const FloatRect& layerArea, const IntRect& clipRect);
     IntSize templateSize(const IntSize& blurredEdgeSize, const FloatRoundedRect::Radii&) const;
 
-    void blurShadowBuffer(const IntSize& templateSize);
-    void blurAndColorShadowBuffer(const IntSize& templateSize);
+    void blurShadowBuffer(ImageBuffer& layerImage, const IntSize& templateSize);
+    void blurAndColorShadowBuffer(ImageBuffer& layerImage, const IntSize& templateSize);
 
-    void drawInsetShadowWithoutTiling(const AffineTransform&, const FloatRect& fullRect, const FloatRoundedRect& holeRect, const IntSize& layerSize, const DrawBufferCallback&);
+    void drawInsetShadowWithoutTiling(const AffineTransform&, const FloatRect& fullRect, const FloatRoundedRect& holeRect, const LayerImageProperties&, const DrawBufferCallback&);
     void drawInsetShadowWithTiling(const AffineTransform&, const FloatRect& fullRect, const FloatRoundedRect& holeRect, const IntSize& shadowTemplateSize, const IntSize& blurredEdgeSize, const DrawImageCallback&, const FillRectWithHoleCallback&);
 
-    void drawRectShadowWithoutTiling(const AffineTransform&, const FloatRoundedRect& shadowedRect, const IntSize& layerSize, const DrawBufferCallback&);
-    void drawRectShadowWithTiling(const AffineTransform&, const FloatRoundedRect& shadowedRect, const IntSize& shadowTemplateSize, const IntSize& blurredEdgeSize, const DrawImageCallback&, const FillRectCallback&);
+    void drawRectShadowWithoutTiling(const AffineTransform&, const FloatRoundedRect& shadowedRect, const LayerImageProperties&, const DrawBufferCallback&);
+    void drawRectShadowWithTiling(const AffineTransform&, const FloatRoundedRect& shadowedRect, const IntSize& shadowTemplateSize, const IntSize& blurredEdgeSize, const DrawImageCallback&, const FillRectCallback&, const LayerImageProperties&);
 
-    void drawLayerPiecesAndFillCenter(const FloatRect& shadowBounds, const FloatRoundedRect::Radii&, const IntSize& roundedRadius, const IntSize& templateSize, const DrawImageCallback&, const FillRectCallback&);
-    void drawLayerPieces(const FloatRect& shadowBounds, const FloatRoundedRect::Radii&, const IntSize& roundedRadius, const IntSize& templateSize, const DrawImageCallback&);
+    void drawLayerPiecesAndFillCenter(ImageBuffer& layerImage, const FloatRect& shadowBounds, const FloatRoundedRect::Radii&, const IntSize& roundedRadius, const IntSize& templateSize, const DrawImageCallback&, const FillRectCallback&);
+    void drawLayerPieces(ImageBuffer& layerImage, const FloatRect& shadowBounds, const FloatRoundedRect::Radii&, const IntSize& roundedRadius, const IntSize& templateSize, const DrawImageCallback&);
 
     IntSize blurredEdgeSize() const;
 
@@ -115,13 +122,6 @@ private:
     FloatSize m_blurRadius;
     FloatSize m_offset;
 
-    ImageBuffer* m_layerImage { nullptr }; // Buffer to where the temporary shadow will be drawn to.
-
-    FloatSize m_shadowedResultSize; // Size of the result of shadowing which is same as shadowedRect + blurred edges.
-    FloatPoint m_layerOrigin; // Top-left corner of the (possibly clipped) bounding rect to draw the shadow to.
-    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 { false };
 };