Title: [250188] trunk/Source/WebCore
Revision
250188
Author
bfulg...@apple.com
Date
2019-09-21 19:40:44 -0700 (Sat, 21 Sep 2019)

Log Message

[FTW] Resolve crashes found while running canvas tests
https://bugs.webkit.org/show_bug.cgi?id=202062

Reviewed by Don Olmstead.

* platform/graphics/Pattern.h:
* platform/graphics/win/Direct2DOperations.cpp:
(WebCore::Direct2D::FillSource::FillSource): Take GraphicsContext as argument, rather than
a PlatformContextDirect2D since downstream operations require the former.
(WebCore::Direct2D::StrokeSource::StrokeSource): Ditto.
(WebCore::Direct2D::clip): Use new 'pushClip' helper function.
* platform/graphics/win/Direct2DOperations.h:
* platform/graphics/win/GraphicsContextDirect2D.cpp:
(WebCore::GraphicsContext::drawPath):
(WebCore::GraphicsContext::fillPath):
(WebCore::GraphicsContext::strokePath):
(WebCore::GraphicsContext::fillRect):
(WebCore::GraphicsContext::fillRectWithRoundedHole):
(WebCore::GraphicsContext::strokeRect):
* platform/graphics/win/GraphicsContextImplDirect2D.cpp:
(WebCore::GraphicsContextImplDirect2D::fillRect): Update to pass GraphicsContext.
(WebCore::GraphicsContextImplDirect2D::fillRectWithRoundedHole): Ditto.
(WebCore::GraphicsContextImplDirect2D::fillPath): Ditto.
(WebCore::GraphicsContextImplDirect2D::strokeRect): Ditto.
(WebCore::GraphicsContextImplDirect2D::strokePath): Ditto.
(WebCore::GraphicsContextImplDirect2D::drawGlyphs): Ditto.
* platform/graphics/win/ImageBufferDataDirect2D.cpp:
(WebCore::ImageBufferData::copyRectFromSourceToData): Correct return behavior.
(WebCore::ImageBufferData::compatibleBitmap): Make a copy if the render target is
backed by the ID2D1Bitmap we are trying to draw with.
* platform/graphics/win/PatternDirect2D.cpp:
(WebCore::Pattern::createPlatformPattern const): Remove 'PlatformContextDirect2D' contructor,
since we always need a GraphicsContext for the Image class.
* platform/graphics/win/PlatformContextDirect2D.cpp:
(WebCore::PlatformContextDirect2D::clipLayer const): Added.
(WebCore::PlatformContextDirect2D::clearClips): Added.
(WebCore::PlatformContextDirect2D::restore): Update to use m_stateStack, rather than
the m_renderStates vector.
(WebCore::PlatformContextDirect2D::save): Ditto.
(WebCore::PlatformContextDirect2D::pushRenderClip): Ditto.
(WebCore::PlatformContextDirect2D::setActiveLayer): Ditto.
(WebCore::PlatformContextDirect2D::endDraw): Ditto.
(WebCore::PlatformContextDirect2D::notifyPostDrawObserver): Ditto.
(WebCore::PlatformContextDirect2D::pushClip): Ditto.
* platform/graphics/win/PlatformContextDirect2D.h:
(WebCore::PlatformContextDirect2D::hasSavedState const):
(WebCore::PlatformContextDirect2D::clipLayer const): Deleted.

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (250187 => 250188)


--- trunk/Source/WebCore/ChangeLog	2019-09-21 23:13:47 UTC (rev 250187)
+++ trunk/Source/WebCore/ChangeLog	2019-09-22 02:40:44 UTC (rev 250188)
@@ -1,3 +1,53 @@
+2019-09-21  Brent Fulgham  <bfulg...@apple.com>
+
+        [FTW] Resolve crashes found while running canvas tests
+        https://bugs.webkit.org/show_bug.cgi?id=202062
+
+        Reviewed by Don Olmstead.
+
+        * platform/graphics/Pattern.h:
+        * platform/graphics/win/Direct2DOperations.cpp:
+        (WebCore::Direct2D::FillSource::FillSource): Take GraphicsContext as argument, rather than
+        a PlatformContextDirect2D since downstream operations require the former.        
+        (WebCore::Direct2D::StrokeSource::StrokeSource): Ditto.
+        (WebCore::Direct2D::clip): Use new 'pushClip' helper function.
+        * platform/graphics/win/Direct2DOperations.h:
+        * platform/graphics/win/GraphicsContextDirect2D.cpp:
+        (WebCore::GraphicsContext::drawPath):
+        (WebCore::GraphicsContext::fillPath):
+        (WebCore::GraphicsContext::strokePath):
+        (WebCore::GraphicsContext::fillRect):
+        (WebCore::GraphicsContext::fillRectWithRoundedHole):
+        (WebCore::GraphicsContext::strokeRect):
+        * platform/graphics/win/GraphicsContextImplDirect2D.cpp:
+        (WebCore::GraphicsContextImplDirect2D::fillRect): Update to pass GraphicsContext.
+        (WebCore::GraphicsContextImplDirect2D::fillRectWithRoundedHole): Ditto.
+        (WebCore::GraphicsContextImplDirect2D::fillPath): Ditto.
+        (WebCore::GraphicsContextImplDirect2D::strokeRect): Ditto.
+        (WebCore::GraphicsContextImplDirect2D::strokePath): Ditto.
+        (WebCore::GraphicsContextImplDirect2D::drawGlyphs): Ditto.
+        * platform/graphics/win/ImageBufferDataDirect2D.cpp:
+        (WebCore::ImageBufferData::copyRectFromSourceToData): Correct return behavior.
+        (WebCore::ImageBufferData::compatibleBitmap): Make a copy if the render target is
+        backed by the ID2D1Bitmap we are trying to draw with.
+        * platform/graphics/win/PatternDirect2D.cpp:
+        (WebCore::Pattern::createPlatformPattern const): Remove 'PlatformContextDirect2D' contructor,
+        since we always need a GraphicsContext for the Image class.
+        * platform/graphics/win/PlatformContextDirect2D.cpp:
+        (WebCore::PlatformContextDirect2D::clipLayer const): Added.
+        (WebCore::PlatformContextDirect2D::clearClips): Added.
+        (WebCore::PlatformContextDirect2D::restore): Update to use m_stateStack, rather than
+        the m_renderStates vector.
+        (WebCore::PlatformContextDirect2D::save): Ditto.
+        (WebCore::PlatformContextDirect2D::pushRenderClip): Ditto.
+        (WebCore::PlatformContextDirect2D::setActiveLayer): Ditto.
+        (WebCore::PlatformContextDirect2D::endDraw): Ditto.
+        (WebCore::PlatformContextDirect2D::notifyPostDrawObserver): Ditto.
+        (WebCore::PlatformContextDirect2D::pushClip): Ditto.
+        * platform/graphics/win/PlatformContextDirect2D.h:
+        (WebCore::PlatformContextDirect2D::hasSavedState const):
+        (WebCore::PlatformContextDirect2D::clipLayer const): Deleted.
+
 2019-09-20  Antoine Quint  <grao...@apple.com>
 
         releasePointerCapture() not working for implicit capture; can't opt-in to pointerenter/leave for touches

Modified: trunk/Source/WebCore/platform/graphics/Pattern.h (250187 => 250188)


--- trunk/Source/WebCore/platform/graphics/Pattern.h	2019-09-21 23:13:47 UTC (rev 250187)
+++ trunk/Source/WebCore/platform/graphics/Pattern.h	2019-09-22 02:40:44 UTC (rev 250188)
@@ -66,7 +66,6 @@
 #if !USE(DIRECT2D)
     PlatformPatternPtr createPlatformPattern(const AffineTransform& userSpaceTransformation) const;
 #else
-    PlatformPatternPtr createPlatformPattern(PlatformGraphicsContext&, float alpha, const AffineTransform& userSpaceTransformation) const;
     PlatformPatternPtr createPlatformPattern(const GraphicsContext&, float alpha, const AffineTransform& userSpaceTransformation) const;
 #endif
     void setPatternSpaceTransform(const AffineTransform& patternSpaceTransformation);

Modified: trunk/Source/WebCore/platform/graphics/win/Direct2DOperations.cpp (250187 => 250188)


--- trunk/Source/WebCore/platform/graphics/win/Direct2DOperations.cpp	2019-09-21 23:13:47 UTC (rev 250187)
+++ trunk/Source/WebCore/platform/graphics/win/Direct2DOperations.cpp	2019-09-22 02:40:44 UTC (rev 250188)
@@ -289,28 +289,34 @@
 
 } // namespace State
 
-FillSource::FillSource(const GraphicsContextState& state, PlatformContextDirect2D& platformContext)
+FillSource::FillSource(const GraphicsContextState& state, const GraphicsContext& context)
     : globalAlpha(state.alpha)
     , color(state.fillColor)
     , fillRule(state.fillRule)
 {
+    ASSERT(context.hasPlatformContext());
+    auto& platformContext = *context.platformContext();
+
     if (state.fillPattern) {
         AffineTransform userToBaseCTM; // FIXME: This isn't really needed on Windows
-        brush = state.fillPattern->createPlatformPattern(platformContext, state.alpha, userToBaseCTM);
-    } else if (state.fillGradient)
+        brush = state.fillPattern->createPlatformPattern(context, state.alpha, userToBaseCTM);
+    } else if (state.fillGradient && !state.fillGradient->stops().isEmpty())
         brush = state.fillGradient->createPlatformGradientIfNecessary(platformContext.renderTarget());
     else
         brush = platformContext.brushWithColor(color);
 }
 
-StrokeSource::StrokeSource(const GraphicsContextState& state, PlatformContextDirect2D& platformContext)
+StrokeSource::StrokeSource(const GraphicsContextState& state, const GraphicsContext& context)
     : globalAlpha(state.alpha)
     , thickness(state.strokeThickness)
     , color(state.strokeColor)
 {
+    ASSERT(context.hasPlatformContext());
+    auto& platformContext = *context.platformContext();
+
     if (state.strokePattern) {
         AffineTransform userToBaseCTM; // FIXME: This isn't really needed on Windows
-        brush = state.strokePattern->createPlatformPattern(platformContext, state.alpha, userToBaseCTM);
+        brush = state.strokePattern->createPlatformPattern(context, state.alpha, userToBaseCTM);
     } else if (state.strokeGradient)
         brush = state.strokeGradient->createPlatformGradientIfNecessary(platformContext.renderTarget());
     else
@@ -1116,11 +1122,8 @@
 
 void clip(PlatformContextDirect2D& platformContext, const FloatRect& rect)
 {
-    if (platformContext.m_renderStates.isEmpty())
-        save(platformContext);
-
     platformContext.renderTarget()->PushAxisAlignedClip(rect, D2D1_ANTIALIAS_MODE_PER_PRIMITIVE);
-    platformContext.m_renderStates.last().m_clips.append(PlatformContextDirect2D::AxisAlignedClip);
+    platformContext.pushClip(PlatformContextDirect2D::AxisAlignedClip);
 
     if (auto* graphicsContextPrivate = platformContext.graphicsContextPrivate())
         graphicsContextPrivate->clip(rect);

Modified: trunk/Source/WebCore/platform/graphics/win/Direct2DOperations.h (250187 => 250188)


--- trunk/Source/WebCore/platform/graphics/win/Direct2DOperations.h	2019-09-21 23:13:47 UTC (rev 250187)
+++ trunk/Source/WebCore/platform/graphics/win/Direct2DOperations.h	2019-09-22 02:40:44 UTC (rev 250188)
@@ -74,7 +74,7 @@
 
 struct FillSource {
     FillSource() = default;
-    explicit FillSource(const GraphicsContextState&, PlatformContextDirect2D&);
+    explicit FillSource(const GraphicsContextState&, const GraphicsContext&);
 
     float globalAlpha { 0 };
     COMPtr<ID2D1Brush> brush;
@@ -85,7 +85,7 @@
 
 struct StrokeSource {
     StrokeSource() = default;
-    explicit StrokeSource(const GraphicsContextState&, PlatformContextDirect2D&);
+    explicit StrokeSource(const GraphicsContextState&, const GraphicsContext&);
 
     float globalAlpha { 0 };
     float thickness { 0 };

Modified: trunk/Source/WebCore/platform/graphics/win/GraphicsContextDirect2D.cpp (250187 => 250188)


--- trunk/Source/WebCore/platform/graphics/win/GraphicsContextDirect2D.cpp	2019-09-21 23:13:47 UTC (rev 250187)
+++ trunk/Source/WebCore/platform/graphics/win/GraphicsContextDirect2D.cpp	2019-09-22 02:40:44 UTC (rev 250188)
@@ -589,7 +589,7 @@
     ASSERT(hasPlatformContext());
     auto& state = this->state();
     auto& context = *platformContext();
-    Direct2D::drawPath(context, path, Direct2D::StrokeSource(state, context), Direct2D::ShadowState(state));
+    Direct2D::drawPath(context, path, Direct2D::StrokeSource(state, *this), Direct2D::ShadowState(state));
 }
 
 void GraphicsContext::fillPath(const Path& path)
@@ -605,7 +605,7 @@
     ASSERT(hasPlatformContext());
     auto& state = this->state();
     auto& context = *platformContext();
-    Direct2D::fillPath(context, path, Direct2D::FillSource(state, context), Direct2D::ShadowState(state));
+    Direct2D::fillPath(context, path, Direct2D::FillSource(state, *this), Direct2D::ShadowState(state));
 }
 
 void GraphicsContext::strokePath(const Path& path)
@@ -621,7 +621,7 @@
     ASSERT(hasPlatformContext());
     auto& state = this->state();
     auto& context = *platformContext();
-    Direct2D::strokePath(context, path, Direct2D::StrokeSource(state, context), Direct2D::ShadowState(state));
+    Direct2D::strokePath(context, path, Direct2D::StrokeSource(state, *this), Direct2D::ShadowState(state));
 }
 
 void GraphicsContext::fillRect(const FloatRect& rect)
@@ -637,7 +637,7 @@
     ASSERT(hasPlatformContext());
     auto& state = this->state();
     auto& context = *platformContext();
-    Direct2D::fillRect(context, rect, Direct2D::FillSource(state, context), Direct2D::ShadowState(state));
+    Direct2D::fillRect(context, rect, Direct2D::FillSource(state, *this), Direct2D::ShadowState(state));
 }
 
 void GraphicsContext::fillRect(const FloatRect& rect, const Color& color)
@@ -681,7 +681,7 @@
     ASSERT(hasPlatformContext());
     auto& state = this->state();
     auto& context = *platformContext();
-    Direct2D::fillRectWithRoundedHole(context, rect, roundedHoleRect, Direct2D::FillSource(state, context), Direct2D::ShadowState(state));
+    Direct2D::fillRectWithRoundedHole(context, rect, roundedHoleRect, Direct2D::FillSource(state, *this), Direct2D::ShadowState(state));
 }
 
 void GraphicsContext::clip(const FloatRect& rect)
@@ -861,7 +861,7 @@
     ASSERT(hasPlatformContext());
     auto& state = this->state();
     auto& context = *platformContext();
-    Direct2D::strokeRect(context, rect, lineWidth, Direct2D::StrokeSource(state, context), Direct2D::ShadowState(state));
+    Direct2D::strokeRect(context, rect, lineWidth, Direct2D::StrokeSource(state, *this), Direct2D::ShadowState(state));
 }
 
 void GraphicsContext::setLineCap(LineCap cap)

Modified: trunk/Source/WebCore/platform/graphics/win/GraphicsContextImplDirect2D.cpp (250187 => 250188)


--- trunk/Source/WebCore/platform/graphics/win/GraphicsContextImplDirect2D.cpp	2019-09-21 23:13:47 UTC (rev 250187)
+++ trunk/Source/WebCore/platform/graphics/win/GraphicsContextImplDirect2D.cpp	2019-09-22 02:40:44 UTC (rev 250188)
@@ -145,7 +145,7 @@
 void GraphicsContextImplDirect2D::fillRect(const FloatRect& rect)
 {
     auto& state = graphicsContext().state();
-    Direct2D::fillRect(m_platformContext, rect, Direct2D::FillSource(state, m_platformContext), Direct2D::ShadowState(state));
+    Direct2D::fillRect(m_platformContext, rect, Direct2D::FillSource(state, graphicsContext()), Direct2D::ShadowState(state));
 }
 
 void GraphicsContextImplDirect2D::fillRect(const FloatRect& rect, const Color& color)
@@ -192,7 +192,7 @@
 {
     auto& state = graphicsContext().state();
 
-    Direct2D::FillSource fillSource(state, m_platformContext);
+    Direct2D::FillSource fillSource(state, graphicsContext());
     fillSource.brush = m_platformContext.brushWithColor(color);
 
     Direct2D::fillRectWithRoundedHole(m_platformContext, rect, roundedHoleRect, fillSource, Direct2D::ShadowState(graphicsContext().state()));
@@ -201,7 +201,7 @@
 void GraphicsContextImplDirect2D::fillPath(const Path& path)
 {
     auto& state = graphicsContext().state();
-    Direct2D::fillPath(m_platformContext, path, Direct2D::FillSource(state, m_platformContext), Direct2D::ShadowState(state));
+    Direct2D::fillPath(m_platformContext, path, Direct2D::FillSource(state, graphicsContext()), Direct2D::ShadowState(state));
 }
 
 void GraphicsContextImplDirect2D::fillEllipse(const FloatRect& rect)
@@ -214,13 +214,13 @@
 void GraphicsContextImplDirect2D::strokeRect(const FloatRect& rect, float lineWidth)
 {
     auto& state = graphicsContext().state();
-    Direct2D::strokeRect(m_platformContext, rect, lineWidth, Direct2D::StrokeSource(state, m_platformContext), Direct2D::ShadowState(state));
+    Direct2D::strokeRect(m_platformContext, rect, lineWidth, Direct2D::StrokeSource(state, graphicsContext()), Direct2D::ShadowState(state));
 }
 
 void GraphicsContextImplDirect2D::strokePath(const Path& path)
 {
     auto& state = graphicsContext().state();
-    Direct2D::strokePath(m_platformContext, path, Direct2D::StrokeSource(state, m_platformContext), Direct2D::ShadowState(state));
+    Direct2D::strokePath(m_platformContext, path, Direct2D::StrokeSource(state, graphicsContext()), Direct2D::ShadowState(state));
 }
 
 void GraphicsContextImplDirect2D::strokeEllipse(const FloatRect& rect)
@@ -263,7 +263,7 @@
     double syntheticBoldOffset = font.syntheticBoldOffset();
 
     auto& state = graphicsContext().state();
-    Direct2D::drawGlyphs(m_platformContext, Direct2D::FillSource(state, m_platformContext), Direct2D::StrokeSource(state, m_platformContext),
+    Direct2D::drawGlyphs(m_platformContext, Direct2D::FillSource(state, graphicsContext()), Direct2D::StrokeSource(state, graphicsContext()),
         Direct2D::ShadowState(state), point, font, syntheticBoldOffset, glyphs, horizontalAdvances, glyphOffsets, xOffset,
         state.textDrawingMode, state.strokeThickness, state.shadowOffset, state.shadowColor);
 }

Modified: trunk/Source/WebCore/platform/graphics/win/ImageBufferDataDirect2D.cpp (250187 => 250188)


--- trunk/Source/WebCore/platform/graphics/win/ImageBufferDataDirect2D.cpp	2019-09-21 23:13:47 UTC (rev 250187)
+++ trunk/Source/WebCore/platform/graphics/win/ImageBufferDataDirect2D.cpp	2019-09-22 02:40:44 UTC (rev 250188)
@@ -428,9 +428,9 @@
         return copyRectFromSourceToDest(sourceRect, sourceRect.size(), source.data(), backingStoreSize, data.data(), destBufferPosition);
 
     if (byteFormat == AlphaPremultiplication::Unpremultiplied)
-        copyRectFromSourceToDestAndSetPremultiplication<AlphaPremultiplication::Unpremultiplied>(sourceRect, sourceRect.size(), source.data(), backingStoreSize, data.data(), destBufferPosition);
-    else
-        copyRectFromSourceToDestAndSetPremultiplication<AlphaPremultiplication::Premultiplied>(sourceRect, sourceRect.size(), source.data(), backingStoreSize, data.data(), destBufferPosition);
+        return copyRectFromSourceToDestAndSetPremultiplication<AlphaPremultiplication::Unpremultiplied>(sourceRect, sourceRect.size(), source.data(), backingStoreSize, data.data(), destBufferPosition);
+
+    return copyRectFromSourceToDestAndSetPremultiplication<AlphaPremultiplication::Premultiplied>(sourceRect, sourceRect.size(), source.data(), backingStoreSize, data.data(), destBufferPosition);
 }
 
 void ImageBufferData::loadDataToBitmapIfNeeded()
@@ -478,9 +478,24 @@
     if (!renderTarget)
         return bitmap;
 
-    if (platformContext->renderTarget() == renderTarget)
-        return bitmap;
+    if (platformContext->renderTarget() == renderTarget) {
+        COMPtr<ID2D1BitmapRenderTarget> bitmapTarget(Query, renderTarget);
+        if (bitmapTarget) {
+            COMPtr<ID2D1Bitmap> backingBitmap;
+            if (SUCCEEDED(bitmapTarget->GetBitmap(&backingBitmap))) {
+                if (backingBitmap != bitmap)
+                    return bitmap;
 
+                // We can't draw an ID2D1Bitmap to itself. Must return a copy.
+                COMPtr<ID2D1Bitmap> copiedBitmap;
+                if (SUCCEEDED(renderTarget->CreateBitmap(bitmap->GetPixelSize(), Direct2D::bitmapProperties(), &copiedBitmap))) {
+                    if (SUCCEEDED(copiedBitmap->CopyFromBitmap(nullptr, bitmap.get(), nullptr)))
+                        return copiedBitmap;
+                }
+            }
+        }
+    }
+
     auto size = bitmap->GetPixelSize();
 
     Checked<unsigned, RecordOverflow> numBytes = size.width * size.height * 4;

Modified: trunk/Source/WebCore/platform/graphics/win/PatternDirect2D.cpp (250187 => 250188)


--- trunk/Source/WebCore/platform/graphics/win/PatternDirect2D.cpp	2019-09-21 23:13:47 UTC (rev 250187)
+++ trunk/Source/WebCore/platform/graphics/win/PatternDirect2D.cpp	2019-09-22 02:40:44 UTC (rev 250188)
@@ -39,14 +39,6 @@
 
 ID2D1BitmapBrush* Pattern::createPlatformPattern(const GraphicsContext& context, float alpha, const AffineTransform& userSpaceTransformation) const
 {
-    auto platformContext = context.platformContext();
-    RELEASE_ASSERT(platformContext);
-
-    return createPlatformPattern(*platformContext, alpha, userSpaceTransformation);
-}
-
-ID2D1BitmapBrush* Pattern::createPlatformPattern(PlatformGraphicsContext& context, float alpha, const AffineTransform& userSpaceTransformation) const
-{
     AffineTransform patternTransform = userSpaceTransformation * m_patternSpaceTransformation;
     auto bitmapBrushProperties = D2D1::BitmapBrushProperties();
     bitmapBrushProperties.extendModeX = m_repeatX ? D2D1_EXTEND_MODE_WRAP : D2D1_EXTEND_MODE_CLAMP;
@@ -57,10 +49,15 @@
     brushProperties.opacity = alpha;
 
     auto& patternImage = tileImage();
-    auto nativeImage = patternImage.nativeImage(nullptr);
+    auto nativeImage = patternImage.nativeImage(&context);
+    if (!nativeImage)
+        return nullptr;
 
+    auto platformContext = context.platformContext();
+    RELEASE_ASSERT(platformContext);
+
     ID2D1BitmapBrush* patternBrush = nullptr;
-    HRESULT hr = context.renderTarget()->CreateBitmapBrush(nativeImage.get(), &bitmapBrushProperties, &brushProperties, &patternBrush);
+    HRESULT hr = platformContext->renderTarget()->CreateBitmapBrush(nativeImage.get(), &bitmapBrushProperties, &brushProperties, &patternBrush);
     ASSERT(SUCCEEDED(hr));
     return patternBrush;
 }

Modified: trunk/Source/WebCore/platform/graphics/win/PlatformContextDirect2D.cpp (250187 => 250188)


--- trunk/Source/WebCore/platform/graphics/win/PlatformContextDirect2D.cpp	2019-09-21 23:13:47 UTC (rev 250187)
+++ trunk/Source/WebCore/platform/graphics/win/PlatformContextDirect2D.cpp	2019-09-22 02:40:44 UTC (rev 250188)
@@ -38,6 +38,10 @@
 class PlatformContextDirect2D::State {
 public:
     State() = default;
+
+    COMPtr<ID2D1DrawingStateBlock> m_drawingStateBlock;
+    COMPtr<ID2D1Layer> m_activeLayer;
+    Vector<Direct2DLayerType> m_clips;
 };
 
 PlatformContextDirect2D::PlatformContextDirect2D(ID2D1RenderTarget* renderTarget, WTF::Function<void()>&& preDrawHandler, WTF::Function<void()>&& postDrawHandler)
@@ -49,6 +53,23 @@
     m_state = &m_stateStack.last();
 }
 
+ID2D1Layer* PlatformContextDirect2D::clipLayer() const
+{
+    return m_state->m_activeLayer.get();
+}
+
+void PlatformContextDirect2D::clearClips(Vector<Direct2DLayerType>& clips)
+{
+    for (auto clipType = clips.rbegin(); clipType != clips.rend(); ++clipType) {
+        if (*clipType == AxisAlignedClip)
+            m_renderTarget->PopAxisAlignedClip();
+        else
+            m_renderTarget->PopLayer();
+    }
+
+    clips.clear();
+}
+
 void PlatformContextDirect2D::restore()
 {
     ASSERT(m_renderTarget);
@@ -60,18 +81,14 @@
     if (m_stateStack.size() == 1)
         return;
 
-    if (!m_renderStates.isEmpty()) {
-        auto restoreState = m_renderStates.takeLast();
+    auto& restoreState = m_stateStack.last();
+    if (restoreState.m_drawingStateBlock) {
         m_renderTarget->RestoreDrawingState(restoreState.m_drawingStateBlock.get());
-
-        for (auto clipType = restoreState.m_clips.rbegin(); clipType != restoreState.m_clips.rend(); ++clipType) {
-            if (*clipType == AxisAlignedClip)
-                m_renderTarget->PopAxisAlignedClip();
-            else
-                m_renderTarget->PopLayer();
-        }
+        restoreState.m_drawingStateBlock = nullptr;
     }
 
+    clearClips(restoreState.m_clips);
+
     m_stateStack.removeLast();
     ASSERT(!m_stateStack.isEmpty());
     m_state = &m_stateStack.last();
@@ -87,24 +104,21 @@
     m_stateStack.append(State());
     m_state = &m_stateStack.last();
 
-    RenderState currentState;
-    GraphicsContext::systemFactory()->CreateDrawingStateBlock(&currentState.m_drawingStateBlock);
+    GraphicsContext::systemFactory()->CreateDrawingStateBlock(&m_state->m_drawingStateBlock);
 
-    m_renderTarget->SaveDrawingState(currentState.m_drawingStateBlock.get());
-
-    m_renderStates.append(currentState);
+    m_renderTarget->SaveDrawingState(m_state->m_drawingStateBlock.get());
 }
 
 void PlatformContextDirect2D::pushRenderClip(Direct2DLayerType clipType)
 {
     ASSERT(hasSavedState());
-    m_renderStates.last().m_clips.append(clipType);
+    m_state->m_clips.append(clipType);
 }
 
 void PlatformContextDirect2D::setActiveLayer(COMPtr<ID2D1Layer>&& layer)
 {
     ASSERT(hasSavedState());
-    m_renderStates.last().m_activeLayer = layer;
+    m_state->m_activeLayer = layer;
 }
 
 COMPtr<ID2D1SolidColorBrush> PlatformContextDirect2D::brushWithColor(const D2D1_COLOR_F& color)
@@ -264,9 +278,11 @@
 {
     ASSERT(m_renderTarget);
 
-    while (!m_renderStates.isEmpty())
+    while (m_stateStack.size() > 1)
         restore();
 
+    clearClips(m_state->m_clips);
+
     ASSERT(m_stateStack.size() >= 1);
 
     D2D1_TAG first, second;
@@ -298,6 +314,11 @@
     m_postDrawHandler();
 }
 
+void PlatformContextDirect2D::pushClip(Direct2DLayerType clipType)
+{
+    m_state->m_clips.append(clipType);
+}
+
 } // namespace WebCore
 
 #endif // USE(DIRECT2D)

Modified: trunk/Source/WebCore/platform/graphics/win/PlatformContextDirect2D.h (250187 => 250188)


--- trunk/Source/WebCore/platform/graphics/win/PlatformContextDirect2D.h	2019-09-21 23:13:47 UTC (rev 250187)
+++ trunk/Source/WebCore/platform/graphics/win/PlatformContextDirect2D.h	2019-09-22 02:40:44 UTC (rev 250188)
@@ -61,7 +61,7 @@
     GraphicsContextPlatformPrivate* graphicsContextPrivate() { return m_graphicsContextPrivate; }
     void setGraphicsContextPrivate(GraphicsContextPlatformPrivate* graphicsContextPrivate) { m_graphicsContextPrivate = graphicsContextPrivate; }
 
-    ID2D1Layer* clipLayer() const { return m_renderStates.last().m_activeLayer.get(); }
+    ID2D1Layer* clipLayer() const;
     ID2D1StrokeStyle* strokeStyle();
     D2D1_STROKE_STYLE_PROPERTIES strokeStyleProperties() const;
     ID2D1StrokeStyle* platformStrokeStyle() const;
@@ -71,7 +71,7 @@
     void save();
     void restore();
 
-    bool hasSavedState() const { return !m_renderStates.isEmpty(); }
+    bool hasSavedState() const { return !m_stateStack.isEmpty(); }
 
     void beginDraw();
     void endDraw();
@@ -83,13 +83,6 @@
     void recomputeStrokeStyle();
     float strokeThickness() const { return m_strokeThickness; }
 
-    struct RenderState {
-        COMPtr<ID2D1DrawingStateBlock> m_drawingStateBlock;
-        COMPtr<ID2D1Layer> m_activeLayer;
-        Vector<Direct2DLayerType> m_clips;
-    };
-    Vector<RenderState> m_renderStates;
-
     struct TransparencyLayerState {
         COMPtr<ID2D1BitmapRenderTarget> renderTarget;
         Color shadowColor;
@@ -117,7 +110,11 @@
     void notifyPreDrawObserver();
     void notifyPostDrawObserver();
 
+    void pushClip(Direct2DLayerType);
+
 private:
+    void clearClips(Vector<Direct2DLayerType>&);
+
     GraphicsContextPlatformPrivate* m_graphicsContextPrivate { nullptr };
 
     COMPtr<ID2D1RenderTarget> m_renderTarget;
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to