Title: [208019] trunk
Revision
208019
Author
[email protected]
Date
2016-10-27 17:21:31 -0700 (Thu, 27 Oct 2016)

Log Message

[Win][Direct2D] Create a RAII Helper Class for the Render Target
https://bugs.webkit.org/show_bug.cgi?id=164005

Reviewed by Alex Christensen.

Source/WebCore:

Tested by existing SVG, image, and Canvas layout tests.

* platform/graphics/GraphicsContext.h:
* platform/graphics/win/GradientDirect2D.cpp:
(WebCore::Gradient::fill): Use new convenience helper class.
* platform/graphics/win/GraphicsContextDirect2D.cpp:
(WebCore::GraphicsContext::didBeginDraw):
(WebCore::GraphicsContextPlatformPrivate::GraphicsContextPlatformPrivate):
(WebCore::GraphicsContextPlatformPrivate::~GraphicsContextPlatformPrivate): Add an
assertion that we are in a valid state when cleaning up the graphics context.
(WebCore::GraphicsContextPlatformPrivate::clip): Clipping can only happen in a Draw operation.
Open a new BeginDraw if asked to Clip. The Begin must stay active when this method returns,
as the Clip layer is only valid during a Draw operation.
(WebCore::GraphicsContextPlatformPrivate::beginDraw): Added.
(WebCore::GraphicsContextPlatformPrivate::endDraw): Added.
(WebCore::GraphicsContext::beginDrawIfNeeded): Added.
(WebCore::GraphicsContext::endDraw): Added.
(WebCore::GraphicsContext::drawWithoutShadow): Revise to use new RenderTargetHelper class.
(WebCore::GraphicsContext::drawWithShadow): Ditto.
(WebCore::GraphicsContext::platformFillRoundedRect): Ditto.
(WebCore::GraphicsContext::fillRectWithRoundedHole): Ditto.
(WebCore::GraphicsContext::setDidBeginDraw): Deleted.
* platform/graphics/win/GraphicsContextPlatformPrivateDirect2D.h:
(WebCore::GraphicsContextPlatformPrivate::didBeginDraw): Revise to use count instead of
a separate boolean.
* platform/graphics/win/ImageBufferDataDirect2D.cpp:
(WebCore::ImageBufferData::getData): Revise to use new RenderTargetHelper class.
* platform/graphics/win/NativeImageDirect2D.cpp:
(WebCore::drawNativeImage): Ditto.
* platform/graphics/win/RenderTargetHelper.h: Added.
(WebCore::RenderTargetHelper::RenderTargetHelper):
(WebCore::RenderTargetHelper::~RenderTargetHelper):
(WebCore::RenderTargetHelper::endDraw):
* svg/graphics/SVGImage.cpp:
(WebCore::SVGImage::nativeImage): Revise to use new RenderTargetHelper class.

Source/WebKit/win:

* WebView.cpp:
(WebView::sizeChanged): Construct RenderTarget with higher-resolution display timer.
(WebView::paintWithDirect2D): Revise to use new RenderTargetHelper class.

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (208018 => 208019)


--- trunk/Source/WebCore/ChangeLog	2016-10-27 23:46:13 UTC (rev 208018)
+++ trunk/Source/WebCore/ChangeLog	2016-10-28 00:21:31 UTC (rev 208019)
@@ -1,3 +1,46 @@
+2016-10-25  Brent Fulgham  <[email protected]>
+
+        [Win][Direct2D] Create a RAII Helper Class for the Render Target
+        https://bugs.webkit.org/show_bug.cgi?id=164005
+
+        Reviewed by Alex Christensen.
+
+        Tested by existing SVG, image, and Canvas layout tests.
+
+        * platform/graphics/GraphicsContext.h:
+        * platform/graphics/win/GradientDirect2D.cpp:
+        (WebCore::Gradient::fill): Use new convenience helper class.
+        * platform/graphics/win/GraphicsContextDirect2D.cpp:
+        (WebCore::GraphicsContext::didBeginDraw):
+        (WebCore::GraphicsContextPlatformPrivate::GraphicsContextPlatformPrivate):
+        (WebCore::GraphicsContextPlatformPrivate::~GraphicsContextPlatformPrivate): Add an
+        assertion that we are in a valid state when cleaning up the graphics context.
+        (WebCore::GraphicsContextPlatformPrivate::clip): Clipping can only happen in a Draw operation.
+        Open a new BeginDraw if asked to Clip. The Begin must stay active when this method returns,
+        as the Clip layer is only valid during a Draw operation.
+        (WebCore::GraphicsContextPlatformPrivate::beginDraw): Added.
+        (WebCore::GraphicsContextPlatformPrivate::endDraw): Added.
+        (WebCore::GraphicsContext::beginDrawIfNeeded): Added.
+        (WebCore::GraphicsContext::endDraw): Added.
+        (WebCore::GraphicsContext::drawWithoutShadow): Revise to use new RenderTargetHelper class.
+        (WebCore::GraphicsContext::drawWithShadow): Ditto.
+        (WebCore::GraphicsContext::platformFillRoundedRect): Ditto.
+        (WebCore::GraphicsContext::fillRectWithRoundedHole): Ditto.
+        (WebCore::GraphicsContext::setDidBeginDraw): Deleted.
+        * platform/graphics/win/GraphicsContextPlatformPrivateDirect2D.h:
+        (WebCore::GraphicsContextPlatformPrivate::didBeginDraw): Revise to use count instead of
+        a separate boolean.
+        * platform/graphics/win/ImageBufferDataDirect2D.cpp:
+        (WebCore::ImageBufferData::getData): Revise to use new RenderTargetHelper class.
+        * platform/graphics/win/NativeImageDirect2D.cpp:
+        (WebCore::drawNativeImage): Ditto.
+        * platform/graphics/win/RenderTargetHelper.h: Added.
+        (WebCore::RenderTargetHelper::RenderTargetHelper):
+        (WebCore::RenderTargetHelper::~RenderTargetHelper):
+        (WebCore::RenderTargetHelper::endDraw):
+        * svg/graphics/SVGImage.cpp:
+        (WebCore::SVGImage::nativeImage): Revise to use new RenderTargetHelper class.
+
 2016-10-27  Wenson Hsieh  <[email protected]>
 
         Support "insertFromDrop" and "deleteByDrag" for the InputEvent spec

Modified: trunk/Source/WebCore/platform/graphics/GraphicsContext.h (208018 => 208019)


--- trunk/Source/WebCore/platform/graphics/GraphicsContext.h	2016-10-27 23:46:13 UTC (rev 208018)
+++ trunk/Source/WebCore/platform/graphics/GraphicsContext.h	2016-10-28 00:21:31 UTC (rev 208019)
@@ -552,9 +552,10 @@
     WEBCORE_EXPORT static ID2D1Factory* systemFactory();
     WEBCORE_EXPORT static ID2D1RenderTarget* defaultRenderTarget();
 
-    WEBCORE_EXPORT void setDidBeginDraw(bool);
+    WEBCORE_EXPORT bool beginDrawIfNeeded();
     WEBCORE_EXPORT bool didBeginDraw() const;
     D2D1_COLOR_F colorWithGlobalAlpha(const Color&) const;
+    WEBCORE_EXPORT void endDraw();
 
     ID2D1Brush* solidStrokeBrush() const;
     ID2D1Brush* solidFillBrush() const;

Modified: trunk/Source/WebCore/platform/graphics/win/GradientDirect2D.cpp (208018 => 208019)


--- trunk/Source/WebCore/platform/graphics/win/GradientDirect2D.cpp	2016-10-27 23:46:13 UTC (rev 208018)
+++ trunk/Source/WebCore/platform/graphics/win/GradientDirect2D.cpp	2016-10-28 00:21:31 UTC (rev 208019)
@@ -28,6 +28,7 @@
 
 #include "FloatPoint.h"
 #include "GraphicsContext.h"
+#include "RenderTargetScopedDrawing.h"
 #include <d2d1.h>
 #include <wtf/RetainPtr.h>
 
@@ -120,8 +121,7 @@
     if (!m_cachedHash || !m_gradient)
         generateGradient(d2dContext);
 
-    if (!context->didBeginDraw())
-        d2dContext->BeginDraw();
+    RenderTargetScopedDrawing scopedDraw(*context);
 
     d2dContext->SetTags(GRADIENT_DRAWING, __LINE__);
 
@@ -128,12 +128,6 @@
     const D2D1_RECT_F d2dRect = rect;
     d2dContext->FillRectangle(&d2dRect, m_gradient);
 
-    if (!context->didBeginDraw()) {
-        D2D1_TAG first, second;
-        HRESULT hr = d2dContext->EndDraw(&first, &second);
-        RELEASE_ASSERT(SUCCEEDED(hr));
-    }
-
     if (needScaling)
         context->restore();
 }

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


--- trunk/Source/WebCore/platform/graphics/win/GraphicsContextDirect2D.cpp	2016-10-27 23:46:13 UTC (rev 208018)
+++ trunk/Source/WebCore/platform/graphics/win/GraphicsContextDirect2D.cpp	2016-10-28 00:21:31 UTC (rev 208019)
@@ -34,6 +34,7 @@
 #include "ImageBuffer.h"
 #include "Logging.h"
 #include "NotImplemented.h"
+#include "RenderTargetScopedDrawing.h"
 #include "URL.h"
 #include <d2d1.h>
 #include <d2d1effects.h>
@@ -98,15 +99,9 @@
     return defaultRenderTarget;
 }
 
-void GraphicsContext::setDidBeginDraw(bool didBeginDraw)
-{
-    RELEASE_ASSERT(m_data);
-    m_data->m_didBeginDraw = didBeginDraw;
-}
-
 bool GraphicsContext::didBeginDraw() const
 {
-    return m_data->m_didBeginDraw;
+    return m_data->didBeginDraw();
 }
 
 void GraphicsContext::platformInit(HDC hdc, bool hasAlpha)
@@ -277,14 +272,9 @@
     HRESULT hr = platformContext()->CreateBitmap(pixelData.size(), pixelData.buffer(), pixelData.bytesPerRow(), &bitmapProperties, &bitmap);
     ASSERT(SUCCEEDED(hr));
 
-    if (!didBeginDraw())
-        platformContext()->BeginDraw();
-
+    RenderTargetScopedDrawing scopedDraw(*this);
     platformContext()->DrawBitmap(bitmap.get(), dstRect);
 
-    if (!didBeginDraw())
-        hr = platformContext()->EndDraw();
-
     ::DeleteDC(hdc);
 }
 
@@ -308,6 +298,19 @@
 {
 }
 
+GraphicsContextPlatformPrivate::GraphicsContextPlatformPrivate(ID2D1RenderTarget* renderTarget)
+    : m_renderTarget(renderTarget)
+{
+}
+
+GraphicsContextPlatformPrivate::~GraphicsContextPlatformPrivate()
+{
+    if (!m_renderTarget)
+        return;
+
+    ASSERT(!m_beginDrawCount.unsafeGet());
+}
+
 COMPtr<ID2D1SolidColorBrush> GraphicsContextPlatformPrivate::brushWithColor(const D2D1_COLOR_F& color)
 {
     RGBA32 colorKey = makeRGBA32FromFloats(color.r, color.g, color.b, color.a);
@@ -340,6 +343,10 @@
 
 void GraphicsContextPlatformPrivate::clip(const FloatRect& rect)
 {
+    // In D2D, we can only clip in the context of a 'BeginDraw', and the clip can
+    // only live as long as the draw is happening.
+    beginDrawIfNeeded();
+
     if (m_renderStates.isEmpty())
         save();
 
@@ -354,6 +361,10 @@
 
 void GraphicsContextPlatformPrivate::clip(ID2D1Geometry* path)
 {
+    // In D2D, we can only clip in the context of a 'BeginDraw', and the clip can
+    // only live as long as the draw is happening.
+    beginDrawIfNeeded();
+
     ASSERT(m_renderStates.size());
     if (!m_renderStates.size())
         return;
@@ -389,6 +400,17 @@
     RELEASE_ASSERT(SUCCEEDED(hr));
 }
 
+void GraphicsContextPlatformPrivate::beginDrawIfNeeded()
+{
+    ASSERT(m_renderTarget.get());
+    if (didBeginDraw())
+        return;
+
+    m_renderTarget->BeginDraw();
+
+    ++m_beginDrawCount;
+}
+
 void GraphicsContextPlatformPrivate::endDraw()
 {
     ASSERT(m_renderTarget.get());
@@ -397,6 +419,8 @@
 
     if (!SUCCEEDED(hr))
         WTFLogAlways("Failed in GraphicsContextPlatformPrivate::endDraw: hr=%ld, first=%ld, second=%ld", hr, first, second);
+
+    --m_beginDrawCount;
 }
 
 void GraphicsContextPlatformPrivate::restore()
@@ -493,6 +517,19 @@
     return m_data->m_patternFillBrush.get();
 }
 
+bool GraphicsContext::beginDrawIfNeeded()
+{
+    bool neededToBeginDraw = !m_data->didBeginDraw();
+
+    m_data->beginDrawIfNeeded();
+    return neededToBeginDraw;
+}
+
+void GraphicsContext::endDraw()
+{
+    m_data->endDraw();
+}
+
 void GraphicsContext::drawPattern(Image& image, const FloatRect& destRect, const FloatRect& tileRect, const AffineTransform& patternTransform, const FloatPoint& phase, const FloatSize& spacing, CompositeOperator op, BlendMode blendMode)
 {
     if (paintingDisabled() || !patternTransform.isInvertible())
@@ -877,19 +914,14 @@
 
 void GraphicsContext::drawWithoutShadow(const FloatRect& /*boundingRect*/, const std::function<void(ID2D1RenderTarget*)>& drawCommands)
 {
-    auto context = platformContext();
-
-    if (!didBeginDraw())
-        context->BeginDraw();
-
-    drawCommands(context);
-
-    if (!didBeginDraw())
-        m_data->endDraw();
+    RenderTargetScopedDrawing scopedDraw(*this);
+    drawCommands(platformContext());
 }
 
 void GraphicsContext::drawWithShadow(const FloatRect& boundingRect, const std::function<void(ID2D1RenderTarget*)>& drawCommands)
 {
+    RenderTargetScopedDrawing scopedDraw(*this);
+
     auto context = platformContext();
 
     // Render the current geometry to a bitmap context
@@ -942,10 +974,7 @@
     auto flip = D2D1::Matrix3x2F::Scale(D2D1::SizeF(1.0f, -1.0f));
     deviceContext->SetTransform(ctm * flip * translate);
 
-    deviceContext->BeginDraw();
     deviceContext->DrawImage(compositor.get(), D2D1_INTERPOLATION_MODE_LINEAR);
-    hr = deviceContext->EndDraw();
-    ASSERT(SUCCEEDED(hr));
 }
 
 void GraphicsContext::fillPath(const Path& path)
@@ -1136,9 +1165,8 @@
         notImplemented();
     }
 
-    if (!didBeginDraw())
-        context->BeginDraw();
-    
+    RenderTargetScopedDrawing scopedDraw(*this);
+
     context->SetTags(1, __LINE__);
 
     const FloatRect& r = rect.rect();
@@ -1158,9 +1186,6 @@
         fillPath(path);
     }
 
-    if (!didBeginDraw())
-        m_data->endDraw();
-
     if (drawOwnShadow)
         stateSaver.restore();
 }
@@ -1177,8 +1202,7 @@
 
     auto context = platformContext();
 
-    if (!didBeginDraw())
-        context->BeginDraw();
+    RenderTargetScopedDrawing scopedDraw(*this);
 
     context->SetTags(1, __LINE__);
 
@@ -1208,9 +1232,6 @@
 
     fillPath(path);
 
-    if (!didBeginDraw())
-        m_data->endDraw();
-
     if (drawOwnShadow)
         stateSaver.restore();
 

Modified: trunk/Source/WebCore/platform/graphics/win/GraphicsContextPlatformPrivateDirect2D.h (208018 => 208019)


--- trunk/Source/WebCore/platform/graphics/win/GraphicsContextPlatformPrivateDirect2D.h	2016-10-27 23:46:13 UTC (rev 208018)
+++ trunk/Source/WebCore/platform/graphics/win/GraphicsContextPlatformPrivateDirect2D.h	2016-10-28 00:21:31 UTC (rev 208019)
@@ -32,6 +32,7 @@
 #include <d2d1effects.h>
 #include <d2d1helper.h>
 #include <windows.h>
+#include <wtf/CheckedArithmetic.h>
 #include <wtf/TinyLRUCache.h>
 
 namespace WebCore {
@@ -39,10 +40,8 @@
 class GraphicsContextPlatformPrivate {
     WTF_MAKE_FAST_ALLOCATED;
 public:
-    GraphicsContextPlatformPrivate(ID2D1RenderTarget* renderTarget)
-        : m_renderTarget(renderTarget)
-    {
-    }
+    GraphicsContextPlatformPrivate(ID2D1RenderTarget*);
+    ~GraphicsContextPlatformPrivate();
 
     enum Direct2DLayerType { AxisAlignedClip, LayerClip };
 
@@ -49,6 +48,7 @@
     void clip(const FloatRect&);
     void clip(const Path&);
     void clip(ID2D1Geometry*);
+    void beginDrawIfNeeded();
     void endDraw();
     void flush();
     void save();
@@ -75,11 +75,13 @@
 
     COMPtr<ID2D1SolidColorBrush> brushWithColor(const D2D1_COLOR_F&);
 
+    bool didBeginDraw() const { return m_beginDrawCount.unsafeGet(); }
+
     HDC m_hdc { nullptr };
     D2D1_BLEND_MODE m_blendMode { D2D1_BLEND_MODE_MULTIPLY };
     D2D1_COMPOSITE_MODE m_compositeMode { D2D1_COMPOSITE_MODE_SOURCE_OVER };
+    Checked<unsigned> m_beginDrawCount { 0 };
     bool m_shouldIncludeChildWindows { false };
-    bool m_didBeginDraw { false };
     bool m_strokeSyleIsDirty { false };
 
     COMPtr<ID2D1SolidColorBrush> m_solidStrokeBrush;

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


--- trunk/Source/WebCore/platform/graphics/win/ImageBufferDataDirect2D.cpp	2016-10-27 23:46:13 UTC (rev 208018)
+++ trunk/Source/WebCore/platform/graphics/win/ImageBufferDataDirect2D.cpp	2016-10-28 00:21:31 UTC (rev 208019)
@@ -33,6 +33,7 @@
 #include "HWndDC.h"
 #include "IntRect.h"
 #include "NotImplemented.h"
+#include "RenderTargetScopedDrawing.h"
 #include <d2d1.h>
 #include <runtime/JSCInlines.h>
 #include <runtime/TypedArrayInlines.h>
@@ -63,24 +64,24 @@
     auto bitmapDC = adoptGDIObject(::CreateCompatibleDC(windowDC));
     HGDIOBJ oldBitmap = ::SelectObject(bitmapDC.get(), bitmap.get());
 
-    HRESULT hr;
+    BOOL ok = TRUE;
 
-    COMPtr<ID2D1GdiInteropRenderTarget> gdiRenderTarget;
-    hr = platformContext->QueryInterface(__uuidof(ID2D1GdiInteropRenderTarget), (void**)&gdiRenderTarget);
-    if (FAILED(hr))
-        return nullptr;
+    {
+        RenderTargetScopedDrawing scopedDraw(*context);
 
-    platformContext->BeginDraw();
+        COMPtr<ID2D1GdiInteropRenderTarget> gdiRenderTarget;
+        HRESULT hr = platformContext->QueryInterface(__uuidof(ID2D1GdiInteropRenderTarget), (void**)&gdiRenderTarget);
+        if (FAILED(hr))
+            return nullptr;
 
-    HDC hdc = nullptr;
-    hr = gdiRenderTarget->GetDC(D2D1_DC_INITIALIZE_MODE_COPY, &hdc);
+        HDC hdc = nullptr;
+        hr = gdiRenderTarget->GetDC(D2D1_DC_INITIALIZE_MODE_COPY, &hdc);
 
-    BOOL ok = ::BitBlt(bitmapDC.get(), 0, 0, rect.width(), rect.height(), hdc, rect.x(), rect.y(), SRCCOPY);
+        ok = ::BitBlt(bitmapDC.get(), 0, 0, rect.width(), rect.height(), hdc, rect.x(), rect.y(), SRCCOPY);
 
-    hr = gdiRenderTarget->ReleaseDC(nullptr);
+        hr = gdiRenderTarget->ReleaseDC(nullptr);
+    }
 
-    hr = platformContext->EndDraw();
-
     if (!ok)
         return nullptr;
 

Modified: trunk/Source/WebCore/platform/graphics/win/NativeImageDirect2D.cpp (208018 => 208019)


--- trunk/Source/WebCore/platform/graphics/win/NativeImageDirect2D.cpp	2016-10-27 23:46:13 UTC (rev 208018)
+++ trunk/Source/WebCore/platform/graphics/win/NativeImageDirect2D.cpp	2016-10-28 00:21:31 UTC (rev 208019)
@@ -32,6 +32,7 @@
 #include "GraphicsContext.h"
 #include "IntSize.h"
 #include "NotImplemented.h"
+#include "RenderTargetScopedDrawing.h"
 #include <d2d1.h>
 
 namespace WebCore {
@@ -85,14 +86,13 @@
 
     float opacity = 1.0f;
 
-    if (!context.didBeginDraw())
-        platformContext->BeginDraw();
+    bool temporaryDraw = context.beginDrawIfNeeded();
 
     platformContext->DrawBitmap(image.get(), destRect, opacity, D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR, adjustedSrcRect);
 
     HRESULT hr = S_OK;
-    if (!context.didBeginDraw())
-        hr = platformContext->EndDraw();
+    if (temporaryDraw)
+        context.endDraw();
     else
         hr = platformContext->Flush();
 

Added: trunk/Source/WebCore/platform/graphics/win/RenderTargetScopedDrawing.h (0 => 208019)


--- trunk/Source/WebCore/platform/graphics/win/RenderTargetScopedDrawing.h	                        (rev 0)
+++ trunk/Source/WebCore/platform/graphics/win/RenderTargetScopedDrawing.h	2016-10-28 00:21:31 UTC (rev 208019)
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "GraphicsContext.h"
+
+namespace WebCore {
+
+class RenderTargetScopedDrawing {
+    WTF_MAKE_NONCOPYABLE(RenderTargetScopedDrawing);
+public:
+    RenderTargetScopedDrawing(GraphicsContext& context)
+        : m_context(context)
+    {
+        m_drawIsScoped = context.beginDrawIfNeeded();
+    }
+
+    ~RenderTargetScopedDrawing()
+    {
+        endDraw();
+    }
+
+    void endDraw()
+    {
+        if (!m_drawIsScoped)
+            return;
+            
+        m_context.endDraw();
+        m_drawIsScoped = false;
+    }
+
+private:
+    GraphicsContext& m_context;
+    bool m_drawIsScoped;
+};
+
+} // namespace WebCore

Modified: trunk/Source/WebCore/svg/graphics/SVGImage.cpp (208018 => 208019)


--- trunk/Source/WebCore/svg/graphics/SVGImage.cpp	2016-10-27 23:46:13 UTC (rev 208018)
+++ trunk/Source/WebCore/svg/graphics/SVGImage.cpp	2016-10-28 00:21:31 UTC (rev 208019)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2006 Eric Seidel <[email protected]>
- * Copyright (C) 2008, 2009, 2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2008-2009, 2015-2016 Apple Inc. All rights reserved.
  * Copyright (C) Research In Motion Limited 2011. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -56,6 +56,7 @@
 
 #if USE(DIRECT2D)
 #include "COMPtr.h"
+#include "RenderTargetScopedDrawing.h"
 #include <d2d1.h>
 #endif
 
@@ -224,15 +225,13 @@
     HRESULT hr = platformContext->CreateCompatibleRenderTarget(IntSize(rect().size()), &nativeImageTarget);
     ASSERT(SUCCEEDED(hr));
 
-    nativeImageTarget->BeginDraw();
     GraphicsContext localContext(nativeImageTarget.get());
-    localContext.setDidBeginDraw(true);
 
-    draw(localContext, rect(), rect(), CompositeSourceOver, BlendModeNormal, ImageOrientationDescription());
+    {
+        RenderTargetScopedDrawing scopedDraw(localContext);
+        draw(localContext, rect(), rect(), CompositeSourceOver, BlendModeNormal, ImageOrientationDescription());
+    }
 
-    hr = nativeImageTarget->Flush();
-    ASSERT(SUCCEEDED(hr));
-
     COMPtr<ID2D1Bitmap> nativeImage;
     hr = nativeImageTarget->GetBitmap(&nativeImage);
     ASSERT(SUCCEEDED(hr));

Modified: trunk/Source/WebKit/win/ChangeLog (208018 => 208019)


--- trunk/Source/WebKit/win/ChangeLog	2016-10-27 23:46:13 UTC (rev 208018)
+++ trunk/Source/WebKit/win/ChangeLog	2016-10-28 00:21:31 UTC (rev 208019)
@@ -1,3 +1,14 @@
+2016-10-25  Brent Fulgham  <[email protected]>
+
+        [Win][Direct2D] Create a RAII Helper Class for the Render Target
+        https://bugs.webkit.org/show_bug.cgi?id=164005
+
+        Reviewed by Alex Christensen.
+
+        * WebView.cpp:
+        (WebView::sizeChanged): Construct RenderTarget with higher-resolution display timer.
+        (WebView::paintWithDirect2D): Revise to use new RenderTargetHelper class.
+
 2016-10-27  Wenson Hsieh  <[email protected]>
 
         Support "insertFromDrop" and "deleteByDrag" for the InputEvent spec

Modified: trunk/Source/WebKit/win/WebView.cpp (208018 => 208019)


--- trunk/Source/WebKit/win/WebView.cpp	2016-10-27 23:46:13 UTC (rev 208018)
+++ trunk/Source/WebKit/win/WebView.cpp	2016-10-28 00:21:31 UTC (rev 208019)
@@ -164,6 +164,7 @@
 #include <WebCore/WindowMessageBroadcaster.h>
 #include <WebCore/WindowsTouch.h>
 #include <bindings/ScriptValue.h>
+#include <comdef.h>
 #include <d2d1.h>
 #include <wtf/MainThread.h>
 #include <wtf/RAMSize.h>
@@ -196,6 +197,10 @@
 #include <WebCore/FullScreenController.h>
 #endif
 
+#if USE(DIRECT2D)
+#include <WebCore/RenderTargetScopedDrawing.h>
+#endif
+
 #include <ShlObj.h>
 #include <comutil.h>
 #include <dimm.h>
@@ -1063,7 +1068,7 @@
     // Create a Direct2D render target.
     auto renderTargetProperties = D2D1::RenderTargetProperties();
     renderTargetProperties.usage = D2D1_RENDER_TARGET_USAGE_GDI_COMPATIBLE;
-    auto hwndRenderTargetProperties = D2D1::HwndRenderTargetProperties(m_viewWindow, newSize);
+    auto hwndRenderTargetProperties = D2D1::HwndRenderTargetProperties(m_viewWindow, newSize, D2D1_PRESENT_OPTIONS_IMMEDIATELY);
     HRESULT hr = GraphicsContext::systemFactory()->CreateHwndRenderTarget(&renderTargetProperties, &hwndRenderTargetProperties, &m_renderTarget);
     ASSERT(SUCCEEDED(hr));
 #endif
@@ -1217,7 +1222,6 @@
 
 void WebView::paintWithDirect2D()
 {
-#if USE(DIRECT2D)
     Frame* coreFrame = core(m_mainFrame);
     if (!coreFrame)
         return;
@@ -1236,46 +1240,43 @@
 
         auto pixelSize = D2D1::SizeU(clientRect.width(), clientRect.height());
 
-        auto hwndRenderTargetProperties = D2D1::HwndRenderTargetProperties(m_viewWindow, pixelSize);
+        auto hwndRenderTargetProperties = D2D1::HwndRenderTargetProperties(m_viewWindow, pixelSize, D2D1_PRESENT_OPTIONS_IMMEDIATELY);
         HRESULT hr = GraphicsContext::systemFactory()->CreateHwndRenderTarget(&renderTargetProperties, &hwndRenderTargetProperties, &m_renderTarget);
         if (!SUCCEEDED(hr))
             return;
     }
 
-    m_renderTarget->BeginDraw();
+    RECT clientRect = {};
+    GraphicsContext gc(m_renderTarget.get());
 
-    m_renderTarget->SetTags(WEBKIT_DRAWING, __LINE__);
-    m_renderTarget->Clear();
+    {
+        WebCore::RenderTargetScopedDrawing scopedDraw(gc);
 
-    // Direct2D honors the scale factor natively.
-    float scaleFactor = 1.0f;
-    float inverseScaleFactor = 1.0f / scaleFactor;
+        m_renderTarget->SetTags(WEBKIT_DRAWING, __LINE__);
+        m_renderTarget->Clear();
 
-    RECT clientRect;
-    GetClientRect(m_viewWindow, &clientRect);
+        // Direct2D honors the scale factor natively.
+        float scaleFactor = 1.0f;
+        float inverseScaleFactor = 1.0f / scaleFactor;
 
-    IntRect dirtyRectPixels(0, 0, clientRect.right, clientRect.bottom);
-    FloatRect logicalDirtyRectFloat = dirtyRectPixels;
-    logicalDirtyRectFloat.scale(inverseScaleFactor);
-    IntRect logicalDirtyRect(enclosingIntRect(logicalDirtyRectFloat));
+        GetClientRect(m_viewWindow, &clientRect);
 
-    GraphicsContext gc(m_renderTarget.get());
-    gc.setDidBeginDraw(true);
+        IntRect dirtyRectPixels(0, 0, clientRect.right, clientRect.bottom);
+        FloatRect logicalDirtyRectFloat = dirtyRectPixels;
+        logicalDirtyRectFloat.scale(inverseScaleFactor);
+        IntRect logicalDirtyRect(enclosingIntRect(logicalDirtyRectFloat));
 
-    if (frameView && frameView->frame().contentRenderer()) {
-        gc.save();
-        gc.scale(FloatSize(scaleFactor, scaleFactor));
-        gc.clip(logicalDirtyRect);
-        frameView->paint(gc, logicalDirtyRect);
-        gc.restore();
-        if (m_shouldInvertColors)
-            gc.fillRect(logicalDirtyRect, Color::white, CompositeDifference);
+        if (frameView && frameView->frame().contentRenderer()) {
+            gc.save();
+            gc.scale(FloatSize(scaleFactor, scaleFactor));
+            gc.clip(logicalDirtyRect);
+            frameView->paint(gc, logicalDirtyRect);
+            gc.restore();
+            if (m_shouldInvertColors)
+                gc.fillRect(logicalDirtyRect, Color::white, CompositeDifference);
+        }
     }
 
-    HRESULT hr = m_renderTarget->EndDraw();
-    // FIXME: Recognize and recover from error state:
-    UNUSED_PARAM(hr);
-
     ::ValidateRect(m_viewWindow, &clientRect);
 #else
     ASSERT_NOT_REACHED();
@@ -3151,6 +3152,7 @@
     m_page->setDeviceScaleFactor(deviceScaleFactor());
 
     setSmartInsertDeleteEnabled(TRUE);
+
     return hr;
 }
 

Modified: trunk/Tools/TestWebKitAPI/PlatformWin.cmake (208018 => 208019)


--- trunk/Tools/TestWebKitAPI/PlatformWin.cmake	2016-10-27 23:46:13 UTC (rev 208018)
+++ trunk/Tools/TestWebKitAPI/PlatformWin.cmake	2016-10-28 00:21:31 UTC (rev 208019)
@@ -28,6 +28,8 @@
 set(test_webcore_LIBRARIES
     Crypt32
     D2d1
+    Dwrite
+    dxguid
     Iphlpapi
     Psapi
     Shlwapi
@@ -35,6 +37,7 @@
     WebCore${DEBUG_SUFFIX}
     WebCoreDerivedSources${DEBUG_SUFFIX}
     WebKit${DEBUG_SUFFIX}
+    WindowsCodecs
     gtest
 )
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to