[Win][Direct2D] Implement basic SVG support
authorbfulgham@apple.com <bfulgham@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 14 Oct 2016 22:42:14 +0000 (22:42 +0000)
committerbfulgham@apple.com <bfulgham@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 14 Oct 2016 22:42:14 +0000 (22:42 +0000)
https://bugs.webkit.org/show_bug.cgi?id=163349

Reviewed by Brent Fulgham.

Direct2D needs access to the target graphics context when generating bitmap
images so that it can properly match pixel format and other settings.

Add implementations for a number of drawing primitives used in the SVG
test cases. Correct some differences between CG and Direct2D for drawing
different primitives.

No new tests. Tested by existing 'svg' tests.

* platform/graphics/BitmapImage.cpp:
       (WebCore::BitmapImage::frameImageAtIndex): Take optional target graphics
       context. Also pass the graphics context to the image decoder.
       (WebCore::BitmapImage::nativeImage): Accept an optional target context.
       (WebCore::BitmapImage::nativeImageForCurrentFrame): Ditto.
       (WebCore::BitmapImage::draw): Pass target graphics context to the
       'frameImageAtIndex' method.
* platform/graphics/BitmapImage.h:
* platform/graphics/Image.h:
* platform/graphics/ImageBuffer.cpp:
(WebCore::ImageBuffer::create): Moved from header. Add create function that
takes an optional GraphicsContext argument.
* platform/graphics/ImageBuffer.h:
* platform/graphics/ImageFrameCache.cpp: Add missing include needed to build
under Direct2D.
* platform/graphics/ImageSource.cpp:
(WebCore::ImageSource::setDecoderTargetContext): Added.
(WebCore::ImageSource::setRenderTarget): Deleted.
* platform/graphics/ImageSource.h:
* platform/graphics/Pattern.h:
* platform/graphics/win/GraphicsContextDirect2D.cpp:
(WebCore::GraphicsContextPlatformPrivate::endDraw): Log error state instead of crashing
each time.
(WebCore::GraphicsContext::drawEllipse): Ellipses are defined in D2D as a center, an
X-radius, and a Y-radius.
(WebCore::GraphicsContext::applyStrokePattern):
(WebCore::GraphicsContext::applyFillPattern):
(WebCore::GraphicsContext::clearRect): Use 'Clear' function if possible. Don't clear
anything if the clear rect is outside the drawing area.
(WebCore::GraphicsContext::strokeRect): Provide implementation (needed by SVG).
(WebCore::GraphicsContext::platformFillEllipse): Ellipses are defined in D2D as
a center, an X-radius, and a Y-radius.
(WebCore::GraphicsContext::platformStrokeEllipse): Ditto.
* platform/graphics/win/ImageBufferDirect2D.cpp:
(WebCore::ImageBuffer::createCompatibleBuffer): Accept optional GraphicsContext argument.
(WebCore::ImageBuffer::ImageBuffer): Ditto.
* platform/graphics/win/ImageDecoderDirect2D.cpp:
(WebCore::ImageDecoder::setTargetContext): Renamed from 'setRenderTarget'.
(WebCore::ImageDecoder::createFrameImageAtIndex): Take optional GraphicsContext argument.
(WebCore::ImageDecoder::setRenderTarget): Deleted.
* platform/graphics/win/ImageDecoderDirect2D.h:
* platform/graphics/win/ImageDirect2D.cpp:
(WebCore::BitmapImage::setRenderTarget): Deleted.
* platform/graphics/win/NativeImageDirect2D.cpp: Add missing include.
* platform/graphics/win/PatternDirect2D.cpp:
(WebCore::Pattern::createPlatformPattern): Revise for new signature.
* rendering/FilterEffectRenderer.cpp:
(WebCore::FilterEffectRenderer::allocateBackingStoreIfNeeded): Pass GraphicsContext
to ImageBuffer constructor.
(WebCore::FilterEffectRendererHelper::beginFilterEffect): Pass target context to
filter when allocating backing store.
* rendering/FilterEffectRenderer.h: Add GraphicsContext as argument to constructor.
* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::hasFilterThatIsPainting): Supply GraphicsContext argument when
building new FilterEffectRenderer and helper.
(WebCore::RenderLayer::setupFilters): Ditto.
* svg/graphics/SVGImage.cpp:
(WebCore::SVGImage::nativeImageForCurrentFrame): Revise to take optional GraphicsContext
argument.
(WebCore::SVGImage::nativeImage): Ditto.
* svg/graphics/SVGImage.h:
* svg/graphics/SVGImageForContainer.cpp:
(WebCore::SVGImageForContainer::nativeImageForCurrentFrame): Ditto.
* svg/graphics/SVGImageForContainer.h:

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

24 files changed:
Source/WebCore/ChangeLog
Source/WebCore/platform/graphics/BitmapImage.cpp
Source/WebCore/platform/graphics/BitmapImage.h
Source/WebCore/platform/graphics/Image.h
Source/WebCore/platform/graphics/ImageBuffer.cpp
Source/WebCore/platform/graphics/ImageBuffer.h
Source/WebCore/platform/graphics/ImageFrameCache.cpp
Source/WebCore/platform/graphics/ImageSource.cpp
Source/WebCore/platform/graphics/ImageSource.h
Source/WebCore/platform/graphics/Pattern.h
Source/WebCore/platform/graphics/win/GraphicsContextDirect2D.cpp
Source/WebCore/platform/graphics/win/ImageBufferDirect2D.cpp
Source/WebCore/platform/graphics/win/ImageDecoderDirect2D.cpp
Source/WebCore/platform/graphics/win/ImageDecoderDirect2D.h
Source/WebCore/platform/graphics/win/ImageDirect2D.cpp
Source/WebCore/platform/graphics/win/NativeImageDirect2D.cpp
Source/WebCore/platform/graphics/win/PatternDirect2D.cpp
Source/WebCore/rendering/FilterEffectRenderer.cpp
Source/WebCore/rendering/FilterEffectRenderer.h
Source/WebCore/rendering/RenderLayer.cpp
Source/WebCore/svg/graphics/SVGImage.cpp
Source/WebCore/svg/graphics/SVGImage.h
Source/WebCore/svg/graphics/SVGImageForContainer.cpp
Source/WebCore/svg/graphics/SVGImageForContainer.h

index ee6c3d8..d76da11 100644 (file)
@@ -1,3 +1,84 @@
+2016-10-14  Brent Fulgham  <bfulgham@apple.com>
+
+        [Win][Direct2D] Implement basic SVG support
+        https://bugs.webkit.org/show_bug.cgi?id=163349
+
+        Reviewed by Brent Fulgham.
+
+        Direct2D needs access to the target graphics context when generating bitmap
+        images so that it can properly match pixel format and other settings.
+
+        Add implementations for a number of drawing primitives used in the SVG
+        test cases. Correct some differences between CG and Direct2D for drawing
+        different primitives.
+
+        No new tests. Tested by existing 'svg' tests.
+
+        * platform/graphics/BitmapImage.cpp:
+       (WebCore::BitmapImage::frameImageAtIndex): Take optional target graphics
+       context. Also pass the graphics context to the image decoder.
+       (WebCore::BitmapImage::nativeImage): Accept an optional target context.
+       (WebCore::BitmapImage::nativeImageForCurrentFrame): Ditto.
+       (WebCore::BitmapImage::draw): Pass target graphics context to the
+       'frameImageAtIndex' method.
+        * platform/graphics/BitmapImage.h:
+        * platform/graphics/Image.h:
+        * platform/graphics/ImageBuffer.cpp:
+        (WebCore::ImageBuffer::create): Moved from header. Add create function that
+        takes an optional GraphicsContext argument.
+        * platform/graphics/ImageBuffer.h:
+        * platform/graphics/ImageFrameCache.cpp: Add missing include needed to build
+        under Direct2D.
+        * platform/graphics/ImageSource.cpp:
+        (WebCore::ImageSource::setDecoderTargetContext): Added.
+        (WebCore::ImageSource::setRenderTarget): Deleted.
+        * platform/graphics/ImageSource.h:
+        * platform/graphics/Pattern.h:
+        * platform/graphics/win/GraphicsContextDirect2D.cpp:
+        (WebCore::GraphicsContextPlatformPrivate::endDraw): Log error state instead of crashing
+        each time.
+        (WebCore::GraphicsContext::drawEllipse): Ellipses are defined in D2D as a center, an
+        X-radius, and a Y-radius.
+        (WebCore::GraphicsContext::applyStrokePattern):
+        (WebCore::GraphicsContext::applyFillPattern):
+        (WebCore::GraphicsContext::clearRect): Use 'Clear' function if possible. Don't clear
+        anything if the clear rect is outside the drawing area.
+        (WebCore::GraphicsContext::strokeRect): Provide implementation (needed by SVG).
+        (WebCore::GraphicsContext::platformFillEllipse): Ellipses are defined in D2D as
+        a center, an X-radius, and a Y-radius.
+        (WebCore::GraphicsContext::platformStrokeEllipse): Ditto.
+        * platform/graphics/win/ImageBufferDirect2D.cpp:
+        (WebCore::ImageBuffer::createCompatibleBuffer): Accept optional GraphicsContext argument.
+        (WebCore::ImageBuffer::ImageBuffer): Ditto.
+        * platform/graphics/win/ImageDecoderDirect2D.cpp:
+        (WebCore::ImageDecoder::setTargetContext): Renamed from 'setRenderTarget'.
+        (WebCore::ImageDecoder::createFrameImageAtIndex): Take optional GraphicsContext argument.
+        (WebCore::ImageDecoder::setRenderTarget): Deleted.
+        * platform/graphics/win/ImageDecoderDirect2D.h:
+        * platform/graphics/win/ImageDirect2D.cpp:
+        (WebCore::BitmapImage::setRenderTarget): Deleted.
+        * platform/graphics/win/NativeImageDirect2D.cpp: Add missing include.
+        * platform/graphics/win/PatternDirect2D.cpp: 
+        (WebCore::Pattern::createPlatformPattern): Revise for new signature.
+        * rendering/FilterEffectRenderer.cpp:
+        (WebCore::FilterEffectRenderer::allocateBackingStoreIfNeeded): Pass GraphicsContext
+        to ImageBuffer constructor.
+        (WebCore::FilterEffectRendererHelper::beginFilterEffect): Pass target context to
+        filter when allocating backing store.
+        * rendering/FilterEffectRenderer.h: Add GraphicsContext as argument to constructor.
+        * rendering/RenderLayer.cpp:
+        (WebCore::RenderLayer::hasFilterThatIsPainting): Supply GraphicsContext argument when
+        building new FilterEffectRenderer and helper.
+        (WebCore::RenderLayer::setupFilters): Ditto.
+        * svg/graphics/SVGImage.cpp:
+        (WebCore::SVGImage::nativeImageForCurrentFrame): Revise to take optional GraphicsContext
+        argument.
+        (WebCore::SVGImage::nativeImage): Ditto.
+        * svg/graphics/SVGImage.h:
+        * svg/graphics/SVGImageForContainer.cpp:
+        (WebCore::SVGImageForContainer::nativeImageForCurrentFrame): Ditto.
+        * svg/graphics/SVGImageForContainer.h:
+
 2016-10-14  Chris Dumez  <cdumez@apple.com>
 
         Unreviewed, rolling out r207319.
 2016-10-14  Chris Dumez  <cdumez@apple.com>
 
         Unreviewed, rolling out r207319.
index 0c189c6..c65f7cb 100644 (file)
@@ -80,39 +80,39 @@ bool BitmapImage::dataChanged(bool allDataReceived)
     return m_source.dataChanged(data(), allDataReceived);
 }
 
     return m_source.dataChanged(data(), allDataReceived);
 }
 
-NativeImagePtr BitmapImage::frameImageAtIndex(size_t index, SubsamplingLevel subsamplingLevel)
+NativeImagePtr BitmapImage::frameImageAtIndex(size_t index, SubsamplingLevel subsamplingLevel, const GraphicsContext* targetContext)
 {
     if (frameHasInvalidNativeImageAtIndex(index, subsamplingLevel)) {
         LOG(Images, "BitmapImage %p frameImageAtIndex - subsamplingLevel was %d, resampling", this, static_cast<int>(frameSubsamplingLevelAtIndex(index)));
         invalidatePlatformData();
     }
 
 {
     if (frameHasInvalidNativeImageAtIndex(index, subsamplingLevel)) {
         LOG(Images, "BitmapImage %p frameImageAtIndex - subsamplingLevel was %d, resampling", this, static_cast<int>(frameSubsamplingLevelAtIndex(index)));
         invalidatePlatformData();
     }
 
-    return m_source.frameImageAtIndex(index, subsamplingLevel);
+    return m_source.frameImageAtIndex(index, subsamplingLevel, targetContext);
 }
 
 }
 
-NativeImagePtr BitmapImage::nativeImage()
+NativeImagePtr BitmapImage::nativeImage(const GraphicsContext* targetContext)
 {
 {
-    return frameImageAtIndex(0);
+    return frameImageAtIndex(0, SubsamplingLevel::Default, targetContext);
 }
 
 }
 
-NativeImagePtr BitmapImage::nativeImageForCurrentFrame()
+NativeImagePtr BitmapImage::nativeImageForCurrentFrame(const GraphicsContext* targetContext)
 {
 {
-    return frameImageAtIndex(m_currentFrame);
+    return frameImageAtIndex(m_currentFrame, SubsamplingLevel::Default, targetContext);
 }
 
 #if USE(CG)
 }
 
 #if USE(CG)
-NativeImagePtr BitmapImage::nativeImageOfSize(const IntSize& size)
+NativeImagePtr BitmapImage::nativeImageOfSize(const IntSize& size, const GraphicsContext* targetContext)
 {
     size_t count = frameCount();
 
     for (size_t i = 0; i < count; ++i) {
 {
     size_t count = frameCount();
 
     for (size_t i = 0; i < count; ++i) {
-        auto image = frameImageAtIndex(i);
+        auto image = frameImageAtIndex(i, SubsamplingLevel::Default, targetContext);
         if (image && nativeImageSize(image) == size)
             return image;
     }
 
     // Fallback to the first frame image if we can't find the right size
         if (image && nativeImageSize(image) == size)
             return image;
     }
 
     // Fallback to the first frame image if we can't find the right size
-    return frameImageAtIndex(0);
+    return frameImageAtIndex(0, SubsamplingLevel::Default, targetContext);
 }
 
 Vector<NativeImagePtr> BitmapImage::framesNativeImages()
 }
 
 Vector<NativeImagePtr> BitmapImage::framesNativeImages()
@@ -141,10 +141,6 @@ void BitmapImage::draw(GraphicsContext& context, const FloatRect& destRect, cons
     if (destRect.isEmpty() || srcRect.isEmpty())
         return;
 
     if (destRect.isEmpty() || srcRect.isEmpty())
         return;
 
-#if USE(DIRECT2D)
-    setRenderTarget(context);
-#endif
-
 #if PLATFORM(IOS)
     startAnimation(DoNotCatchUp);
 #else
 #if PLATFORM(IOS)
     startAnimation(DoNotCatchUp);
 #else
@@ -161,7 +157,7 @@ void BitmapImage::draw(GraphicsContext& context, const FloatRect& destRect, cons
     SubsamplingLevel subsamplingLevel = m_source.subsamplingLevelForScale(scale);
     LOG(Images, "BitmapImage %p draw - subsamplingLevel %d at scale %.4f", this, static_cast<int>(subsamplingLevel), scale);
 
     SubsamplingLevel subsamplingLevel = m_source.subsamplingLevelForScale(scale);
     LOG(Images, "BitmapImage %p draw - subsamplingLevel %d at scale %.4f", this, static_cast<int>(subsamplingLevel), scale);
 
-    auto image = frameImageAtIndex(m_currentFrame, subsamplingLevel);
+    auto image = frameImageAtIndex(m_currentFrame, subsamplingLevel, &context);
     if (!image) // If it's too early we won't have an image yet.
         return;
 
     if (!image) // If it's too early we won't have an image yet.
         return;
 
index 74c22a2..092ae63 100644 (file)
@@ -117,21 +117,18 @@ public:
     Evas_Object* getEvasObject(Evas*) override;
 #endif
 
     Evas_Object* getEvasObject(Evas*) override;
 #endif
 
-    WEBCORE_EXPORT NativeImagePtr nativeImage() override;
-    NativeImagePtr nativeImageForCurrentFrame() override;
+    WEBCORE_EXPORT NativeImagePtr nativeImage(const GraphicsContext* = nullptr) override;
+    NativeImagePtr nativeImageForCurrentFrame(const GraphicsContext* = nullptr) override;
 #if USE(CG)
 #if USE(CG)
-    NativeImagePtr nativeImageOfSize(const IntSize&) override;
+    NativeImagePtr nativeImageOfSize(const IntSize&, const GraphicsContext* = nullptr) override;
     Vector<NativeImagePtr> framesNativeImages() override;
 #endif
     Vector<NativeImagePtr> framesNativeImages() override;
 #endif
-#if USE(DIRECT2D)
-    void setRenderTarget(GraphicsContext&);
-#endif
 
 protected:
     WEBCORE_EXPORT BitmapImage(NativeImagePtr&&, ImageObserver* = nullptr);
     WEBCORE_EXPORT BitmapImage(ImageObserver* = nullptr);
 
 
 protected:
     WEBCORE_EXPORT BitmapImage(NativeImagePtr&&, ImageObserver* = nullptr);
     WEBCORE_EXPORT BitmapImage(ImageObserver* = nullptr);
 
-    NativeImagePtr frameImageAtIndex(size_t, SubsamplingLevel = SubsamplingLevel::Default);
+    NativeImagePtr frameImageAtIndex(size_t, SubsamplingLevel = SubsamplingLevel::Default, const GraphicsContext* = nullptr);
 
     // Called to invalidate cached data. When |destroyAll| is true, we wipe out
     // the entire frame buffer cache and tell the image source to destroy
 
     // Called to invalidate cached data. When |destroyAll| is true, we wipe out
     // the entire frame buffer cache and tell the image source to destroy
index a1d0952..915018f 100644 (file)
@@ -137,9 +137,9 @@ public:
 
     enum TileRule { StretchTile, RoundTile, SpaceTile, RepeatTile };
 
 
     enum TileRule { StretchTile, RoundTile, SpaceTile, RepeatTile };
 
-    virtual NativeImagePtr nativeImage() { return nullptr; }
-    virtual NativeImagePtr nativeImageOfSize(const IntSize&) { return nullptr; }
-    virtual NativeImagePtr nativeImageForCurrentFrame() { return nullptr; }
+    virtual NativeImagePtr nativeImage(const GraphicsContext* = nullptr) { return nullptr; }
+    virtual NativeImagePtr nativeImageOfSize(const IntSize&, const GraphicsContext* = nullptr) { return nullptr; }
+    virtual NativeImagePtr nativeImageForCurrentFrame(const GraphicsContext* = nullptr) { return nullptr; }
     virtual ImageOrientation orientationForCurrentFrame() const { return ImageOrientation(); }
     virtual Vector<NativeImagePtr> framesNativeImages() { return { }; }
 
     virtual ImageOrientation orientationForCurrentFrame() const { return ImageOrientation(); }
     virtual Vector<NativeImagePtr> framesNativeImages() { return { }; }
 
index ef986c9..eae4c4e 100644 (file)
@@ -1,6 +1,7 @@
 /*
  * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
  * Copyright (C) Research In Motion Limited 2011. All rights reserved.
 /*
  * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
  * Copyright (C) Research In Motion Limited 2011. All rights reserved.
+ * 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
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -37,6 +38,26 @@ namespace WebCore {
 static const float MaxClampedLength = 4096;
 static const float MaxClampedArea = MaxClampedLength * MaxClampedLength;
 
 static const float MaxClampedLength = 4096;
 static const float MaxClampedArea = MaxClampedLength * MaxClampedLength;
 
+std::unique_ptr<ImageBuffer> ImageBuffer::create(const FloatSize& size, RenderingMode renderingMode, float resolutionScale, ColorSpace colorSpace)
+{
+    bool success = false;
+    std::unique_ptr<ImageBuffer> buffer(new ImageBuffer(size, resolutionScale, colorSpace, renderingMode, success));
+    if (!success)
+        return nullptr;
+    return buffer;
+}
+
+#if USE(DIRECT2D)
+std::unique_ptr<ImageBuffer> ImageBuffer::create(const FloatSize& size, RenderingMode renderingMode, const GraphicsContext* targetContext, float resolutionScale, ColorSpace colorSpace)
+{
+    bool success = false;
+    std::unique_ptr<ImageBuffer> buffer(new ImageBuffer(size, resolutionScale, colorSpace, renderingMode, targetContext, success));
+    if (!success)
+        return nullptr;
+    return buffer;
+}
+#endif
+
 bool ImageBuffer::sizeNeedsClamping(const FloatSize& size)
 {
     if (size.isEmpty())
 bool ImageBuffer::sizeNeedsClamping(const FloatSize& size)
 {
     if (size.isEmpty())
index 63080ee..f819720 100644 (file)
 #include "IntSize.h"
 #include "ImageBufferData.h"
 #include "PlatformLayer.h"
 #include "IntSize.h"
 #include "ImageBufferData.h"
 #include "PlatformLayer.h"
+#include <memory>
 #include <runtime/Uint8ClampedArray.h>
 #include <wtf/Forward.h>
 #include <wtf/RefPtr.h>
 #include <wtf/Vector.h>
 
 #include <runtime/Uint8ClampedArray.h>
 #include <wtf/Forward.h>
 #include <wtf/RefPtr.h>
 #include <wtf/Vector.h>
 
-#if PLATFORM(WIN)
-interface ID2D1RenderTarget;
-#endif
-
 namespace WebCore {
 
 class FloatRect;
 namespace WebCore {
 
 class FloatRect;
@@ -74,14 +71,10 @@ class ImageBuffer {
     friend class IOSurface;
 public:
     // Will return a null pointer on allocation failure.
     friend class IOSurface;
 public:
     // Will return a null pointer on allocation failure.
-    static std::unique_ptr<ImageBuffer> create(const FloatSize& size, RenderingMode renderingMode, float resolutionScale = 1, ColorSpace colorSpace = ColorSpaceSRGB)
-    {
-        bool success = false;
-        std::unique_ptr<ImageBuffer> buffer(new ImageBuffer(size, resolutionScale, colorSpace, renderingMode, success));
-        if (!success)
-            return nullptr;
-        return buffer;
-    }
+    WEBCORE_EXPORT static std::unique_ptr<ImageBuffer> create(const FloatSize&, RenderingMode, float resolutionScale = 1, ColorSpace = ColorSpaceSRGB);
+#if USE(DIRECT2D)
+    WEBCORE_EXPORT static std::unique_ptr<ImageBuffer> create(const FloatSize&, RenderingMode, const GraphicsContext*, float resolutionScale = 1, ColorSpace = ColorSpaceSRGB);
+#endif
 
     // Create an image buffer compatible with the context, with suitable resolution for drawing into the buffer and then into this context.
     static std::unique_ptr<ImageBuffer> createCompatibleBuffer(const FloatSize&, const GraphicsContext&);
 
     // Create an image buffer compatible with the context, with suitable resolution for drawing into the buffer and then into this context.
     static std::unique_ptr<ImageBuffer> createCompatibleBuffer(const FloatSize&, const GraphicsContext&);
@@ -182,7 +175,7 @@ private:
 #if USE(CG)
     ImageBuffer(const FloatSize&, float resolutionScale, CGColorSpaceRef, RenderingMode, bool& success);
 #elif USE(DIRECT2D)
 #if USE(CG)
     ImageBuffer(const FloatSize&, float resolutionScale, CGColorSpaceRef, RenderingMode, bool& success);
 #elif USE(DIRECT2D)
-    ImageBuffer(const FloatSize&, float resolutionScale, ColorSpace, RenderingMode, ID2D1RenderTarget*, bool& success);
+    ImageBuffer(const FloatSize&, float resolutionScale, ColorSpace, RenderingMode, const GraphicsContext*, bool& success);
 #endif
 };
 
 #endif
 };
 
index fbfd601..4b948e5 100644 (file)
@@ -31,6 +31,9 @@
 
 #if USE(CG)
 #include "ImageDecoderCG.h"
 
 #if USE(CG)
 #include "ImageDecoderCG.h"
+#elif USE(DIRECT2D)
+#include "ImageDecoderDirect2D.h"
+#include <WinCodec.h>
 #else
 #include "ImageDecoder.h"
 #endif
 #else
 #include "ImageDecoder.h"
 #endif
index 8256034..e835beb 100644 (file)
@@ -115,15 +115,18 @@ bool ImageSource::ensureDecoderAvailable(SharedBuffer* data)
     return true;
 }
 
     return true;
 }
 
-#if USE(DIRECT2D)
-void ImageSource::setRenderTarget(GraphicsContext& context)
+void ImageSource::setDecoderTargetContext(const GraphicsContext* targetContext)
 {
 {
+#if USE(DIRECT2D)
     if (!isDecoderAvailable())
         return;
 
     if (!isDecoderAvailable())
         return;
 
-    m_decoder->setRenderTarget(context.platformContext());
-}
+    if (targetContext)
+        m_decoder->setTargetContext(targetContext->platformContext());
+#else
+    UNUSED_PARAM(targetContext);
 #endif
 #endif
+}
 
 void ImageSource::setData(SharedBuffer* data, bool allDataReceived)
 {
 
 void ImageSource::setData(SharedBuffer* data, bool allDataReceived)
 {
@@ -209,6 +212,13 @@ NativeImagePtr ImageSource::createFrameImageAtIndex(size_t index, SubsamplingLev
     return isDecoderAvailable() ? m_decoder->createFrameImageAtIndex(index, subsamplingLevel) : nullptr;
 }
 
     return isDecoderAvailable() ? m_decoder->createFrameImageAtIndex(index, subsamplingLevel) : nullptr;
 }
 
+NativeImagePtr ImageSource::frameImageAtIndex(size_t index, SubsamplingLevel subsamplingLevel, const GraphicsContext* targetContext)
+{
+    setDecoderTargetContext(targetContext);
+
+    return m_frameCache.frameImageAtIndex(index, subsamplingLevel);
+}
+
 void ImageSource::dump(TextStream& ts)
 {
     ts.dumpProperty("type", filenameExtension());
 void ImageSource::dump(TextStream& ts)
 {
     ts.dumpProperty("type", filenameExtension());
index ccdf7f1..76e9809 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2010, 2012, 2014, 2016 Apple Inc.  All rights reserved.
+ * Copyright (C) 2004-2008, 2010, 2012, 2014, 2016 Apple Inc.  All rights reserved.
  * Copyright (C) 2007-2008 Torch Mobile, Inc.
  *
  * Redistribution and use in source and binary forms, with or without
  * Copyright (C) 2007-2008 Torch Mobile, Inc.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -59,10 +59,6 @@ public:
     bool ensureDecoderAvailable(SharedBuffer*);
     bool isDecoderAvailable() const { return m_decoder.get(); }
 
     bool ensureDecoderAvailable(SharedBuffer*);
     bool isDecoderAvailable() const { return m_decoder.get(); }
 
-#if USE(DIRECT2D)
-    void setRenderTarget(GraphicsContext&);
-#endif
-
     void setData(SharedBuffer* data, bool allDataReceived);
     bool dataChanged(SharedBuffer* data, bool allDataReceived);
 
     void setData(SharedBuffer* data, bool allDataReceived);
     bool dataChanged(SharedBuffer* data, bool allDataReceived);
 
@@ -93,7 +89,7 @@ public:
     unsigned frameBytesAtIndex(size_t index, SubsamplingLevel subsamplingLevel = SubsamplingLevel::Default) { return m_frameCache.frameBytesAtIndex(index, subsamplingLevel); }
     float frameDurationAtIndex(size_t index) { return m_frameCache.frameDurationAtIndex(index); }
     ImageOrientation frameOrientationAtIndex(size_t index) { return m_frameCache.frameOrientationAtIndex(index); }
     unsigned frameBytesAtIndex(size_t index, SubsamplingLevel subsamplingLevel = SubsamplingLevel::Default) { return m_frameCache.frameBytesAtIndex(index, subsamplingLevel); }
     float frameDurationAtIndex(size_t index) { return m_frameCache.frameDurationAtIndex(index); }
     ImageOrientation frameOrientationAtIndex(size_t index) { return m_frameCache.frameOrientationAtIndex(index); }
-    NativeImagePtr frameImageAtIndex(size_t index, SubsamplingLevel subsamplingLevel = SubsamplingLevel::Default) { return m_frameCache.frameImageAtIndex(index, subsamplingLevel); }
+    NativeImagePtr frameImageAtIndex(size_t index, SubsamplingLevel = SubsamplingLevel::Default, const GraphicsContext* targetContext = nullptr);
 
     SubsamplingLevel maximumSubsamplingLevel();
     SubsamplingLevel subsamplingLevelForScale(float);
 
     SubsamplingLevel maximumSubsamplingLevel();
     SubsamplingLevel subsamplingLevelForScale(float);
@@ -104,7 +100,9 @@ private:
     void clearFrameBufferCache(size_t);
     void clear(bool destroyAll, size_t count, SharedBuffer* data);
     void dump(TextStream&);
     void clearFrameBufferCache(size_t);
     void clear(bool destroyAll, size_t count, SharedBuffer* data);
     void dump(TextStream&);
-    
+
+    void setDecoderTargetContext(const GraphicsContext*);
+
     ImageFrameCache m_frameCache;
     std::unique_ptr<ImageDecoder> m_decoder;
 
     ImageFrameCache m_frameCache;
     std::unique_ptr<ImageDecoder> m_decoder;
 
index 01a73b6..256fa2d 100644 (file)
@@ -39,7 +39,6 @@ typedef struct CGPattern* CGPatternRef;
 typedef CGPatternRef PlatformPatternPtr;
 #elif USE(DIRECT2D)
 interface ID2D1BitmapBrush;
 typedef CGPatternRef PlatformPatternPtr;
 #elif USE(DIRECT2D)
 interface ID2D1BitmapBrush;
-interface ID2D1RenderTarget;
 typedef ID2D1BitmapBrush* PlatformPatternPtr;
 #elif USE(CAIRO)
 #include <cairo.h>
 typedef ID2D1BitmapBrush* PlatformPatternPtr;
 #elif USE(CAIRO)
 #include <cairo.h>
@@ -51,6 +50,7 @@ typedef void* PlatformPatternPtr;
 namespace WebCore {
 
 class AffineTransform;
 namespace WebCore {
 
 class AffineTransform;
+class GraphicsContext;
 class Image;
 
 class Pattern final : public RefCounted<Pattern> {
 class Image;
 
 class Pattern final : public RefCounted<Pattern> {
@@ -66,7 +66,7 @@ public:
 #if !USE(DIRECT2D)
     PlatformPatternPtr createPlatformPattern(const AffineTransform& userSpaceTransformation) const;
 #else
 #if !USE(DIRECT2D)
     PlatformPatternPtr createPlatformPattern(const AffineTransform& userSpaceTransformation) const;
 #else
-    PlatformPatternPtr createPlatformPattern(ID2D1RenderTarget*, float alpha, const AffineTransform& userSpaceTransformation) const;
+    PlatformPatternPtr createPlatformPattern(const GraphicsContext&, float alpha, const AffineTransform& userSpaceTransformation) const;
 #endif
     void setPatternSpaceTransform(const AffineTransform& patternSpaceTransformation);
     const AffineTransform& getPatternSpaceTransform() { return m_patternSpaceTransformation; };
 #endif
     void setPatternSpaceTransform(const AffineTransform& patternSpaceTransformation);
     const AffineTransform& getPatternSpaceTransform() { return m_patternSpaceTransformation; };
index fa9fb4c..7bea0b6 100644 (file)
@@ -338,7 +338,8 @@ void GraphicsContextPlatformPrivate::endDraw()
     D2D1_TAG first, second;
     HRESULT hr = m_renderTarget->EndDraw(&first, &second);
 
     D2D1_TAG first, second;
     HRESULT hr = m_renderTarget->EndDraw(&first, &second);
 
-    RELEASE_ASSERT(SUCCEEDED(hr));
+    if (!SUCCEEDED(hr))
+        WTFLogAlways("Failed in GraphicsContextPlatformPrivate::endDraw: hr=%ld, first=%ld, second=%ld", hr, first, second);
 }
 
 void GraphicsContextPlatformPrivate::restore()
 }
 
 void GraphicsContextPlatformPrivate::restore()
@@ -736,7 +737,7 @@ void GraphicsContext::drawEllipse(const FloatRect& rect)
         return;
     }
 
         return;
     }
 
-    auto ellipse = D2D1::Ellipse(D2D1::Point2F(rect.x(), rect.y()), rect.width(), rect.height());
+    auto ellipse = D2D1::Ellipse(rect.center(), 0.5 * rect.width(), 0.5 * rect.height());
 
     auto context = platformContext();
 
 
     auto context = platformContext();
 
@@ -758,7 +759,7 @@ void GraphicsContext::applyStrokePattern()
     AffineTransform userToBaseCTM; // FIXME: This isn't really needed on Windows
 
     const float patternAlpha = 1;
     AffineTransform userToBaseCTM; // FIXME: This isn't really needed on Windows
 
     const float patternAlpha = 1;
-    m_data->m_patternStrokeBrush = adoptCOM(m_state.strokePattern->createPlatformPattern(context, patternAlpha, userToBaseCTM));
+    m_data->m_patternStrokeBrush = adoptCOM(m_state.strokePattern->createPlatformPattern(*this, patternAlpha, userToBaseCTM));
 }
 
 void GraphicsContext::applyFillPattern()
 }
 
 void GraphicsContext::applyFillPattern()
@@ -770,7 +771,7 @@ void GraphicsContext::applyFillPattern()
     AffineTransform userToBaseCTM; // FIXME: This isn't really needed on Windows
 
     const float patternAlpha = 1;
     AffineTransform userToBaseCTM; // FIXME: This isn't really needed on Windows
 
     const float patternAlpha = 1;
-    m_data->m_patternFillBrush = adoptCOM(m_state.fillPattern->createPlatformPattern(context, patternAlpha, userToBaseCTM));
+    m_data->m_patternFillBrush = adoptCOM(m_state.fillPattern->createPlatformPattern(*this, patternAlpha, userToBaseCTM));
 }
 
 void GraphicsContext::drawPath(const Path& path)
 }
 
 void GraphicsContext::drawPath(const Path& path)
@@ -1329,24 +1330,58 @@ void GraphicsContext::clearRect(const FloatRect& rect)
         return;
     }
 
         return;
     }
 
-    auto context = platformContext();
-
-    context->SetTags(1, __LINE__);
-
     drawWithoutShadow(rect, [this, rect](ID2D1RenderTarget* renderTarget) {
     drawWithoutShadow(rect, [this, rect](ID2D1RenderTarget* renderTarget) {
-        FloatSize renderTargetSize = renderTarget->GetSize();
-        if (rect.size() == renderTargetSize)
+        FloatRect renderTargetRect(FloatPoint(), renderTarget->GetSize());
+        FloatRect rectToClear(rect);
+
+        if (rectToClear.contains(renderTargetRect)) {
+            renderTarget->SetTags(1, __LINE__);
             renderTarget->Clear();
             renderTarget->Clear();
-        else
-            renderTarget->FillRectangle(rect, m_data->brushWithColor(colorWithGlobalAlpha(fillColor())).get());
+            return;
+        }
+
+        if (!rectToClear.intersects(renderTargetRect))
+            return;
+
+        renderTarget->SetTags(1, __LINE__);
+        rectToClear.intersect(renderTargetRect);
+        renderTarget->FillRectangle(rectToClear, m_data->brushWithColor(colorWithGlobalAlpha(fillColor())).get());
     });
 }
 
 void GraphicsContext::strokeRect(const FloatRect& rect, float lineWidth)
 {
     });
 }
 
 void GraphicsContext::strokeRect(const FloatRect& rect, float lineWidth)
 {
-    (void)rect;
-    (void)lineWidth;
-    notImplemented();
+    if (paintingDisabled())
+        return;
+
+    if (isRecording()) {
+        m_displayListRecorder->strokeRect(rect, lineWidth);
+        return;
+    }
+
+    if (m_state.strokeGradient) {
+        auto drawFunction = [this, rect, lineWidth](ID2D1RenderTarget* renderTarget) {
+            renderTarget->SetTags(1, __LINE__);
+            const D2D1_RECT_F d2dRect = rect;
+            renderTarget->DrawRectangle(&d2dRect, m_state.strokeGradient->createPlatformGradientIfNecessary(renderTarget), lineWidth, m_data->strokeStyle());
+        };
+
+        if (hasShadow())
+            drawWithShadow(rect, drawFunction);
+        else
+            drawWithoutShadow(rect, drawFunction);
+        return;
+    }
+
+    if (m_state.strokePattern)
+        applyStrokePattern();
+
+    drawWithoutShadow(rect, [this, rect, lineWidth](ID2D1RenderTarget* renderTarget) {
+        renderTarget->SetTags(1, __LINE__);
+        const D2D1_RECT_F d2dRect = rect;
+        auto brush = m_state.strokePattern ? patternStrokeBrush() : solidStrokeBrush();
+        renderTarget->DrawRectangle(&d2dRect, brush, lineWidth, m_data->strokeStyle());
+    });
 }
 
 void GraphicsContext::setLineCap(LineCap cap)
 }
 
 void GraphicsContext::setLineCap(LineCap cap)
@@ -1813,7 +1848,7 @@ void GraphicsContext::platformFillEllipse(const FloatRect& ellipse)
         return;
     }
 
         return;
     }
 
-    auto d2dEllipse = D2D1::Ellipse(D2D1::Point2F(ellipse.x(), ellipse.y()), ellipse.width(), ellipse.height());
+    auto d2dEllipse = D2D1::Ellipse(ellipse.center(), 0.5 * ellipse.width(), 0.5 * ellipse.height());
 
     platformContext()->SetTags(1, __LINE__);
 
 
     platformContext()->SetTags(1, __LINE__);
 
@@ -1835,7 +1870,7 @@ void GraphicsContext::platformStrokeEllipse(const FloatRect& ellipse)
         return;
     }
 
         return;
     }
 
-    auto d2dEllipse = D2D1::Ellipse(D2D1::Point2F(ellipse.x(), ellipse.y()), ellipse.width(), ellipse.height());
+    auto d2dEllipse = D2D1::Ellipse(ellipse.center(), 0.5 * ellipse.width(), 0.5 * ellipse.height());
 
     platformContext()->SetTags(1, __LINE__);
 
 
     platformContext()->SetTags(1, __LINE__);
 
index 5734868..a94836e 100644 (file)
@@ -66,7 +66,7 @@ std::unique_ptr<ImageBuffer> ImageBuffer::createCompatibleBuffer(const FloatSize
     RenderingMode renderingMode = context.renderingMode();
     IntSize scaledSize = ImageBuffer::compatibleBufferSize(size, context);
     bool success = false;
     RenderingMode renderingMode = context.renderingMode();
     IntSize scaledSize = ImageBuffer::compatibleBufferSize(size, context);
     bool success = false;
-    std::unique_ptr<ImageBuffer> buffer(new ImageBuffer(scaledSize, 1, ColorSpaceSRGB, renderingMode, context.platformContext(), success));
+    std::unique_ptr<ImageBuffer> buffer(new ImageBuffer(scaledSize, 1, ColorSpaceSRGB, renderingMode, &context, success));
 
     if (!success)
         return nullptr;
 
     if (!success)
         return nullptr;
@@ -76,7 +76,7 @@ std::unique_ptr<ImageBuffer> ImageBuffer::createCompatibleBuffer(const FloatSize
     return buffer;
 }
 
     return buffer;
 }
 
-ImageBuffer::ImageBuffer(const FloatSize& size, float resolutionScale, ColorSpace /*colorSpace*/, RenderingMode renderingMode, ID2D1RenderTarget* renderTarget, bool& success)
+ImageBuffer::ImageBuffer(const FloatSize& size, float resolutionScale, ColorSpace /*colorSpace*/, RenderingMode renderingMode, const GraphicsContext* targetContext, bool& success)
     : m_logicalSize(size)
     , m_resolutionScale(resolutionScale)
 {
     : m_logicalSize(size)
     , m_resolutionScale(resolutionScale)
 {
@@ -101,6 +101,7 @@ ImageBuffer::ImageBuffer(const FloatSize& size, float resolutionScale, ColorSpac
     if (numBytes.hasOverflowed())
         return;
 
     if (numBytes.hasOverflowed())
         return;
 
+    auto renderTarget = targetContext ? targetContext->platformContext() : nullptr;
     if (!renderTarget)
         renderTarget = GraphicsContext::defaultRenderTarget();
     RELEASE_ASSERT(renderTarget);
     if (!renderTarget)
         renderTarget = GraphicsContext::defaultRenderTarget();
     RELEASE_ASSERT(renderTarget);
index 0f1bcb1..a51961f 100644 (file)
@@ -187,14 +187,14 @@ unsigned ImageDecoder::frameBytesAtIndex(size_t index, SubsamplingLevel subsampl
     return width * height * 4;
 }
 
     return width * height * 4;
 }
 
-void ImageDecoder::setRenderTarget(ID2D1RenderTarget* renderTarget)
+void ImageDecoder::setTargetContext(ID2D1RenderTarget* renderTarget)
 {
     m_renderTarget = renderTarget;
 }
 
 NativeImagePtr ImageDecoder::createFrameImageAtIndex(size_t index, SubsamplingLevel subsamplingLevel, DecodingMode) const
 {
 {
     m_renderTarget = renderTarget;
 }
 
 NativeImagePtr ImageDecoder::createFrameImageAtIndex(size_t index, SubsamplingLevel subsamplingLevel, DecodingMode) const
 {
-    if (!m_nativeDecoder)
+    if (!m_nativeDecoder || !m_renderTarget)
         return nullptr;
 
     COMPtr<IWICBitmapFrameDecode> frame;
         return nullptr;
 
     COMPtr<IWICBitmapFrameDecode> frame;
@@ -211,10 +211,6 @@ NativeImagePtr ImageDecoder::createFrameImageAtIndex(size_t index, SubsamplingLe
     if (!SUCCEEDED(hr))
         return nullptr;
 
     if (!SUCCEEDED(hr))
         return nullptr;
 
-    ASSERT(m_renderTarget);
-    if (!m_renderTarget)
-        return nullptr;
-
     COMPtr<ID2D1Bitmap> bitmap;
     hr = m_renderTarget->CreateBitmapFromWicBitmap(converter.get(), nullptr, &bitmap);
     if (!SUCCEEDED(hr))
     COMPtr<ID2D1Bitmap> bitmap;
     hr = m_renderTarget->CreateBitmapFromWicBitmap(converter.get(), nullptr, &bitmap);
     if (!SUCCEEDED(hr))
index dd002cb..e538267 100644 (file)
@@ -73,7 +73,7 @@ public:
     bool isAllDataReceived() const { return m_isAllDataReceived; }
     void clearFrameBufferCache(size_t) { }
 
     bool isAllDataReceived() const { return m_isAllDataReceived; }
     void clearFrameBufferCache(size_t) { }
 
-    void setRenderTarget(ID2D1RenderTarget*);
+    void setTargetContext(ID2D1RenderTarget*);
 
     static IWICImagingFactory* systemImagingFactory();
 
 
     static IWICImagingFactory* systemImagingFactory();
 
index c81757f..2507c1c 100644 (file)
@@ -92,11 +92,6 @@ void BitmapImage::drawFrameMatchingSourceSize(GraphicsContext& ctxt, const Float
     draw(ctxt, dstRect, FloatRect(0.0f, 0.0f, imageSize.width(), imageSize.height()), compositeOp, BlendModeNormal, ImageOrientationDescription());
 }
 
     draw(ctxt, dstRect, FloatRect(0.0f, 0.0f, imageSize.width(), imageSize.height()), compositeOp, BlendModeNormal, ImageOrientationDescription());
 }
 
-void BitmapImage::setRenderTarget(GraphicsContext& context)
-{
-    m_source.setRenderTarget(context);
-}
-
 void Image::drawPattern(GraphicsContext& ctxt, const FloatRect& destRect, const FloatRect& tileRect, const AffineTransform& patternTransform,
     const FloatPoint& phase, const FloatSize& spacing, CompositeOperator op, BlendMode blendMode)
 {
 void Image::drawPattern(GraphicsContext& ctxt, const FloatRect& destRect, const FloatRect& tileRect, const AffineTransform& patternTransform,
     const FloatPoint& phase, const FloatSize& spacing, CompositeOperator op, BlendMode blendMode)
 {
index fd61380..ad277a9 100644 (file)
@@ -32,6 +32,7 @@
 #include "GraphicsContext.h"
 #include "IntSize.h"
 #include "NotImplemented.h"
 #include "GraphicsContext.h"
 #include "IntSize.h"
 #include "NotImplemented.h"
+#include <d2d1.h>
 
 namespace WebCore {
 
 
 namespace WebCore {
 
index 2f4fd4b..1b9229e 100644 (file)
 
 namespace WebCore {
 
 
 namespace WebCore {
 
-ID2D1BitmapBrush* Pattern::createPlatformPattern(ID2D1RenderTarget* renderTarget, float alpha, const AffineTransform& userSpaceTransformation) const
+ID2D1BitmapBrush* Pattern::createPlatformPattern(const GraphicsContext& context, float alpha, const AffineTransform& userSpaceTransformation) const
 {
 {
-    RELEASE_ASSERT(renderTarget);
-
-    FloatRect tileRect = tileImage()->rect();
-
     AffineTransform patternTransform = userSpaceTransformation * m_patternSpaceTransformation;
     auto bitmapBrushProperties = D2D1::BitmapBrushProperties();
     bitmapBrushProperties.extendModeX = m_repeatX ? D2D1_EXTEND_MODE_WRAP : D2D1_EXTEND_MODE_CLAMP;
     AffineTransform patternTransform = userSpaceTransformation * m_patternSpaceTransformation;
     auto bitmapBrushProperties = D2D1::BitmapBrushProperties();
     bitmapBrushProperties.extendModeX = m_repeatX ? D2D1_EXTEND_MODE_WRAP : D2D1_EXTEND_MODE_CLAMP;
@@ -52,9 +48,14 @@ ID2D1BitmapBrush* Pattern::createPlatformPattern(ID2D1RenderTarget* renderTarget
     brushProperties.transform = patternTransform;
     brushProperties.opacity = alpha;
 
     brushProperties.transform = patternTransform;
     brushProperties.opacity = alpha;
 
+    auto patternImage = tileImage();
+
+    auto platformContext = context.platformContext();
+    RELEASE_ASSERT(platformContext);
+
     ID2D1BitmapBrush* patternBrush = nullptr;
     ID2D1BitmapBrush* patternBrush = nullptr;
-    HRESULT hr = renderTarget->CreateBitmapBrush(tileImage()->nativeImage().get(), &bitmapBrushProperties, &brushProperties, &patternBrush);
-    ASSERT(hr);
+    HRESULT hr = platformContext->CreateBitmapBrush(patternImage->nativeImage(&context).get(), &bitmapBrushProperties, &brushProperties, &patternBrush);
+    ASSERT(SUCCEEDED(hr));
     return patternBrush;
 }
 
     return patternBrush;
 }
 
index ba511cc..8c67554 100644 (file)
 #include <algorithm>
 #include <wtf/MathExtras.h>
 
 #include <algorithm>
 #include <wtf/MathExtras.h>
 
+#if USE(DIRECT2D)
+#include <d2d1.h>
+#endif
+
 namespace WebCore {
 
 static inline void endMatrixRow(Vector<float>& parameters)
 namespace WebCore {
 
 static inline void endMatrixRow(Vector<float>& parameters)
@@ -313,15 +317,21 @@ bool FilterEffectRenderer::updateBackingStoreRect(const FloatRect& filterRect)
     return true;
 }
 
     return true;
 }
 
-void FilterEffectRenderer::allocateBackingStoreIfNeeded()
+void FilterEffectRenderer::allocateBackingStoreIfNeeded(const GraphicsContext& targetContext)
 {
     // At this point the effect chain has been built, and the
     // source image sizes set. We just need to attach the graphic
     // buffer if we have not yet done so.
     if (!m_graphicsBufferAttached) {
         IntSize logicalSize(m_sourceDrawingRegion.width(), m_sourceDrawingRegion.height());
 {
     // At this point the effect chain has been built, and the
     // source image sizes set. We just need to attach the graphic
     // buffer if we have not yet done so.
     if (!m_graphicsBufferAttached) {
         IntSize logicalSize(m_sourceDrawingRegion.width(), m_sourceDrawingRegion.height());
-        if (!sourceImage() || sourceImage()->logicalSize() != logicalSize)
+        if (!sourceImage() || sourceImage()->logicalSize() != logicalSize) {
+#if USE(DIRECT2D)
+            setSourceImage(ImageBuffer::create(logicalSize, renderingMode(), &targetContext, filterScale()));
+#else
+            UNUSED_PARAM(targetContext);
             setSourceImage(ImageBuffer::create(logicalSize, renderingMode(), filterScale()));
             setSourceImage(ImageBuffer::create(logicalSize, renderingMode(), filterScale()));
+#endif
+        }
         m_graphicsBufferAttached = true;
     }
 }
         m_graphicsBufferAttached = true;
     }
 }
@@ -396,7 +406,7 @@ bool FilterEffectRendererHelper::beginFilterEffect()
     ASSERT(m_renderLayer);
     
     FilterEffectRenderer* filter = m_renderLayer->filterRenderer();
     ASSERT(m_renderLayer);
     
     FilterEffectRenderer* filter = m_renderLayer->filterRenderer();
-    filter->allocateBackingStoreIfNeeded();
+    filter->allocateBackingStoreIfNeeded(m_targetContext);
     // Paint into the context that represents the SourceGraphic of the filter.
     GraphicsContext* sourceGraphicsContext = filter->inputContext();
     if (!sourceGraphicsContext || filter->filterRegion().isEmpty() || ImageBuffer::sizeNeedsClamping(filter->filterRegion().size())) {
     // Paint into the context that represents the SourceGraphic of the filter.
     GraphicsContext* sourceGraphicsContext = filter->inputContext();
     if (!sourceGraphicsContext || filter->filterRegion().isEmpty() || ImageBuffer::sizeNeedsClamping(filter->filterRegion().size())) {
index c731adb..2ed8870 100644 (file)
@@ -40,6 +40,7 @@
 #include <wtf/RefCounted.h>
 #include <wtf/RefPtr.h>
 
 #include <wtf/RefCounted.h>
 #include <wtf/RefPtr.h>
 
+
 namespace WebCore {
 
 class Document;
 namespace WebCore {
 
 class Document;
@@ -57,8 +58,9 @@ enum FilterConsumer {
 class FilterEffectRendererHelper {
     WTF_MAKE_FAST_ALLOCATED;
 public:
 class FilterEffectRendererHelper {
     WTF_MAKE_FAST_ALLOCATED;
 public:
-    FilterEffectRendererHelper(bool haveFilterEffect)
-        : m_haveFilterEffect(haveFilterEffect)
+    FilterEffectRendererHelper(bool haveFilterEffect, GraphicsContext& targetContext)
+        : m_targetContext(targetContext)
+        , m_haveFilterEffect(haveFilterEffect)
     {
     }
     
     {
     }
     
@@ -77,6 +79,7 @@ private:
     RenderLayer* m_renderLayer { nullptr }; // FIXME: this is mainly used to get the FilterEffectRenderer. FilterEffectRendererHelper should be weaned off it.
     LayoutPoint m_paintOffset;
     LayoutRect m_repaintRect;
     RenderLayer* m_renderLayer { nullptr }; // FIXME: this is mainly used to get the FilterEffectRenderer. FilterEffectRendererHelper should be weaned off it.
     LayoutPoint m_paintOffset;
     LayoutRect m_repaintRect;
+    const GraphicsContext& m_targetContext;
     bool m_haveFilterEffect { false };
     bool m_startedFilterEffect { false };
 };
     bool m_haveFilterEffect { false };
     bool m_startedFilterEffect { false };
 };
@@ -107,7 +110,7 @@ public:
     bool build(RenderElement*, const FilterOperations&, FilterConsumer);
     PassRefPtr<FilterEffect> buildReferenceFilter(RenderElement*, PassRefPtr<FilterEffect> previousEffect, ReferenceFilterOperation*);
     bool updateBackingStoreRect(const FloatRect& filterRect);
     bool build(RenderElement*, const FilterOperations&, FilterConsumer);
     PassRefPtr<FilterEffect> buildReferenceFilter(RenderElement*, PassRefPtr<FilterEffect> previousEffect, ReferenceFilterOperation*);
     bool updateBackingStoreRect(const FloatRect& filterRect);
-    void allocateBackingStoreIfNeeded();
+    void allocateBackingStoreIfNeeded(const GraphicsContext&);
     void clearIntermediateResults();
     void apply();
     
     void clearIntermediateResults();
     void apply();
     
index 0c4d1bf..3543528 100644 (file)
@@ -4168,7 +4168,7 @@ bool RenderLayer::hasFilterThatIsPainting(GraphicsContext& context, PaintLayerFl
     if (!hasPaintedFilter)
         return false;
 
     if (!hasPaintedFilter)
         return false;
 
-    auto filterPainter = std::make_unique<FilterEffectRendererHelper>(hasPaintedFilter);
+    auto filterPainter = std::make_unique<FilterEffectRendererHelper>(hasPaintedFilter, context);
     if (!filterPainter->haveFilterEffect())
         return false;
 
     if (!filterPainter->haveFilterEffect())
         return false;
 
@@ -4182,7 +4182,7 @@ std::unique_ptr<FilterEffectRendererHelper> RenderLayer::setupFilters(GraphicsCo
 
     FilterInfo* filterInfo = FilterInfo::getIfExists(*this);
     bool hasPaintedFilter = filterInfo && filterInfo->renderer() && paintsWithFilters();
 
     FilterInfo* filterInfo = FilterInfo::getIfExists(*this);
     bool hasPaintedFilter = filterInfo && filterInfo->renderer() && paintsWithFilters();
-    auto filterPainter = std::make_unique<FilterEffectRendererHelper>(hasPaintedFilter);
+    auto filterPainter = std::make_unique<FilterEffectRendererHelper>(hasPaintedFilter, context);
 
     LayoutRect filterRepaintRect = filterInfo->dirtySourceRect();
     filterRepaintRect.move(offsetFromRoot);
 
     LayoutRect filterRepaintRect = filterInfo->dirtySourceRect();
     filterRepaintRect.move(offsetFromRoot);
index a6a733f..c5a4ba0 100644 (file)
 #include <runtime/JSCInlines.h>
 #include <runtime/JSLock.h>
 
 #include <runtime/JSCInlines.h>
 #include <runtime/JSLock.h>
 
+#if USE(DIRECT2D)
+#include "COMPtr.h"
+#include <d2d1.h>
+#endif
+
 namespace WebCore {
 
 SVGImage::SVGImage(ImageObserver& observer, const URL& url)
 namespace WebCore {
 
 SVGImage::SVGImage(ImageObserver& observer, const URL& url)
@@ -187,7 +192,7 @@ void SVGImage::drawForContainer(GraphicsContext& context, const FloatSize contai
 #if USE(CAIRO)
 // Passes ownership of the native image to the caller so NativeImagePtr needs
 // to be a smart pointer type.
 #if USE(CAIRO)
 // Passes ownership of the native image to the caller so NativeImagePtr needs
 // to be a smart pointer type.
-NativeImagePtr SVGImage::nativeImageForCurrentFrame()
+NativeImagePtr SVGImage::nativeImageForCurrentFrame(const GraphicsContext*)
 {
     if (!m_page)
         return nullptr;
 {
     if (!m_page)
         return nullptr;
@@ -204,6 +209,38 @@ NativeImagePtr SVGImage::nativeImageForCurrentFrame()
 }
 #endif
 
 }
 #endif
 
+#if USE(DIRECT2D)
+NativeImagePtr SVGImage::nativeImage(const GraphicsContext* targetContext)
+{
+    ASSERT(targetContext);
+    if (!m_page || !targetContext)
+        return nullptr;
+
+    auto platformContext = targetContext->platformContext();
+    ASSERT(platformContext);
+
+    // Draw the SVG into a bitmap.
+    COMPtr<ID2D1BitmapRenderTarget> nativeImageTarget;
+    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());
+
+    hr = nativeImageTarget->Flush();
+    ASSERT(SUCCEEDED(hr));
+
+    COMPtr<ID2D1Bitmap> nativeImage;
+    hr = nativeImageTarget->GetBitmap(&nativeImage);
+    ASSERT(SUCCEEDED(hr));
+
+    return nativeImage;
+}
+#endif
+
 void SVGImage::drawPatternForContainer(GraphicsContext& context, const FloatSize& containerSize, float zoom, const FloatRect& srcRect,
     const AffineTransform& patternTransform, const FloatPoint& phase, const FloatSize& spacing, CompositeOperator compositeOp, const FloatRect& dstRect, BlendMode blendMode)
 {
 void SVGImage::drawPatternForContainer(GraphicsContext& context, const FloatSize& containerSize, float zoom, const FloatRect& srcRect,
     const AffineTransform& patternTransform, const FloatPoint& phase, const FloatSize& spacing, CompositeOperator compositeOp, const FloatRect& dstRect, BlendMode blendMode)
 {
index e32a401..80bb9df 100644 (file)
@@ -66,7 +66,10 @@ public:
     void resetAnimation() final;
 
 #if USE(CAIRO)
     void resetAnimation() final;
 
 #if USE(CAIRO)
-    NativeImagePtr nativeImageForCurrentFrame() final;
+    NativeImagePtr nativeImageForCurrentFrame(const GraphicsContext* = nullptr) final;
+#endif
+#if USE(DIRECT2D)
+    NativeImagePtr nativeImage(const GraphicsContext* = nullptr) final;
 #endif
 
 private:
 #endif
 
 private:
index bb6fb5a..482c394 100644 (file)
@@ -46,9 +46,9 @@ void SVGImageForContainer::drawPattern(GraphicsContext& context, const FloatRect
     m_image->drawPatternForContainer(context, m_containerSize, m_zoom, srcRect, patternTransform, phase, spacing, compositeOp, dstRect, blendMode);
 }
 
     m_image->drawPatternForContainer(context, m_containerSize, m_zoom, srcRect, patternTransform, phase, spacing, compositeOp, dstRect, blendMode);
 }
 
-NativeImagePtr SVGImageForContainer::nativeImageForCurrentFrame()
+NativeImagePtr SVGImageForContainer::nativeImageForCurrentFrame(const GraphicsContext* targetContext)
 {
 {
-    return m_image->nativeImageForCurrentFrame();
+    return m_image->nativeImageForCurrentFrame(targetContext);
 }
 
 } // namespace WebCore
 }
 
 } // namespace WebCore
index c3051a7..c42728d 100644 (file)
@@ -63,7 +63,7 @@ public:
     // FIXME: Implement this to be less conservative.
     bool currentFrameKnownToBeOpaque() const final { return false; }
 
     // FIXME: Implement this to be less conservative.
     bool currentFrameKnownToBeOpaque() const final { return false; }
 
-    NativeImagePtr nativeImageForCurrentFrame() final;
+    NativeImagePtr nativeImageForCurrentFrame(const GraphicsContext* = nullptr) final;
 
 private:
     SVGImageForContainer(SVGImage* image, const FloatSize& containerSize, float zoom)
 
 private:
     SVGImageForContainer(SVGImage* image, const FloatSize& containerSize, float zoom)