Diff
Modified: trunk/Source/WebCore/ChangeLog (207356 => 207357)
--- trunk/Source/WebCore/ChangeLog 2016-10-14 22:25:09 UTC (rev 207356)
+++ trunk/Source/WebCore/ChangeLog 2016-10-14 22:42:14 UTC (rev 207357)
@@ -1,3 +1,84 @@
+2016-10-14 Brent Fulgham <[email protected]>
+
+ [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 <[email protected]>
Unreviewed, rolling out r207319.
Modified: trunk/Source/WebCore/platform/graphics/BitmapImage.cpp (207356 => 207357)
--- trunk/Source/WebCore/platform/graphics/BitmapImage.cpp 2016-10-14 22:25:09 UTC (rev 207356)
+++ trunk/Source/WebCore/platform/graphics/BitmapImage.cpp 2016-10-14 22:42:14 UTC (rev 207357)
@@ -80,7 +80,7 @@
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)));
@@ -87,32 +87,32 @@
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)
-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) {
- 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
- return frameImageAtIndex(0);
+ return frameImageAtIndex(0, SubsamplingLevel::Default, targetContext);
}
Vector<NativeImagePtr> BitmapImage::framesNativeImages()
@@ -141,10 +141,6 @@
if (destRect.isEmpty() || srcRect.isEmpty())
return;
-#if USE(DIRECT2D)
- setRenderTarget(context);
-#endif
-
#if PLATFORM(IOS)
startAnimation(DoNotCatchUp);
#else
@@ -161,7 +157,7 @@
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;
Modified: trunk/Source/WebCore/platform/graphics/BitmapImage.h (207356 => 207357)
--- trunk/Source/WebCore/platform/graphics/BitmapImage.h 2016-10-14 22:25:09 UTC (rev 207356)
+++ trunk/Source/WebCore/platform/graphics/BitmapImage.h 2016-10-14 22:42:14 UTC (rev 207357)
@@ -117,21 +117,18 @@
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)
- NativeImagePtr nativeImageOfSize(const IntSize&) override;
+ NativeImagePtr nativeImageOfSize(const IntSize&, const GraphicsContext* = nullptr) override;
Vector<NativeImagePtr> framesNativeImages() override;
#endif
-#if USE(DIRECT2D)
- void setRenderTarget(GraphicsContext&);
-#endif
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
Modified: trunk/Source/WebCore/platform/graphics/Image.h (207356 => 207357)
--- trunk/Source/WebCore/platform/graphics/Image.h 2016-10-14 22:25:09 UTC (rev 207356)
+++ trunk/Source/WebCore/platform/graphics/Image.h 2016-10-14 22:42:14 UTC (rev 207357)
@@ -137,9 +137,9 @@
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 { }; }
Modified: trunk/Source/WebCore/platform/graphics/ImageBuffer.cpp (207356 => 207357)
--- trunk/Source/WebCore/platform/graphics/ImageBuffer.cpp 2016-10-14 22:25:09 UTC (rev 207356)
+++ trunk/Source/WebCore/platform/graphics/ImageBuffer.cpp 2016-10-14 22:42:14 UTC (rev 207357)
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2009 Dirk Schulze <[email protected]>
* 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
@@ -37,6 +38,26 @@
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())
Modified: trunk/Source/WebCore/platform/graphics/ImageBuffer.h (207356 => 207357)
--- trunk/Source/WebCore/platform/graphics/ImageBuffer.h 2016-10-14 22:25:09 UTC (rev 207356)
+++ trunk/Source/WebCore/platform/graphics/ImageBuffer.h 2016-10-14 22:42:14 UTC (rev 207357)
@@ -35,15 +35,12 @@
#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>
-#if PLATFORM(WIN)
-interface ID2D1RenderTarget;
-#endif
-
namespace WebCore {
class FloatRect;
@@ -74,14 +71,10 @@
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&);
@@ -182,7 +175,7 @@
#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
};
Modified: trunk/Source/WebCore/platform/graphics/ImageFrameCache.cpp (207356 => 207357)
--- trunk/Source/WebCore/platform/graphics/ImageFrameCache.cpp 2016-10-14 22:25:09 UTC (rev 207356)
+++ trunk/Source/WebCore/platform/graphics/ImageFrameCache.cpp 2016-10-14 22:42:14 UTC (rev 207357)
@@ -31,6 +31,9 @@
#if USE(CG)
#include "ImageDecoderCG.h"
+#elif USE(DIRECT2D)
+#include "ImageDecoderDirect2D.h"
+#include <WinCodec.h>
#else
#include "ImageDecoder.h"
#endif
Modified: trunk/Source/WebCore/platform/graphics/ImageSource.cpp (207356 => 207357)
--- trunk/Source/WebCore/platform/graphics/ImageSource.cpp 2016-10-14 22:25:09 UTC (rev 207356)
+++ trunk/Source/WebCore/platform/graphics/ImageSource.cpp 2016-10-14 22:42:14 UTC (rev 207357)
@@ -115,15 +115,18 @@
return true;
}
+void ImageSource::setDecoderTargetContext(const GraphicsContext* targetContext)
+{
#if USE(DIRECT2D)
-void ImageSource::setRenderTarget(GraphicsContext& context)
-{
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)
{
@@ -209,6 +212,13 @@
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());
Modified: trunk/Source/WebCore/platform/graphics/ImageSource.h (207356 => 207357)
--- trunk/Source/WebCore/platform/graphics/ImageSource.h 2016-10-14 22:25:09 UTC (rev 207356)
+++ trunk/Source/WebCore/platform/graphics/ImageSource.h 2016-10-14 22:42:14 UTC (rev 207357)
@@ -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
@@ -59,10 +59,6 @@
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);
@@ -93,7 +89,7 @@
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);
@@ -104,7 +100,9 @@
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;
Modified: trunk/Source/WebCore/platform/graphics/Pattern.h (207356 => 207357)
--- trunk/Source/WebCore/platform/graphics/Pattern.h 2016-10-14 22:25:09 UTC (rev 207356)
+++ trunk/Source/WebCore/platform/graphics/Pattern.h 2016-10-14 22:42:14 UTC (rev 207357)
@@ -39,7 +39,6 @@
typedef CGPatternRef PlatformPatternPtr;
#elif USE(DIRECT2D)
interface ID2D1BitmapBrush;
-interface ID2D1RenderTarget;
typedef ID2D1BitmapBrush* PlatformPatternPtr;
#elif USE(CAIRO)
#include <cairo.h>
@@ -51,6 +50,7 @@
namespace WebCore {
class AffineTransform;
+class GraphicsContext;
class Image;
class Pattern final : public RefCounted<Pattern> {
@@ -66,7 +66,7 @@
#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; };
Modified: trunk/Source/WebCore/platform/graphics/win/GraphicsContextDirect2D.cpp (207356 => 207357)
--- trunk/Source/WebCore/platform/graphics/win/GraphicsContextDirect2D.cpp 2016-10-14 22:25:09 UTC (rev 207356)
+++ trunk/Source/WebCore/platform/graphics/win/GraphicsContextDirect2D.cpp 2016-10-14 22:42:14 UTC (rev 207357)
@@ -338,7 +338,8 @@
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()
@@ -736,7 +737,7 @@
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();
@@ -758,7 +759,7 @@
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()
@@ -770,7 +771,7 @@
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)
@@ -1329,24 +1330,58 @@
return;
}
- auto context = platformContext();
+ drawWithoutShadow(rect, [this, rect](ID2D1RenderTarget* renderTarget) {
+ FloatRect renderTargetRect(FloatPoint(), renderTarget->GetSize());
+ FloatRect rectToClear(rect);
- context->SetTags(1, __LINE__);
+ if (rectToClear.contains(renderTargetRect)) {
+ renderTarget->SetTags(1, __LINE__);
+ renderTarget->Clear();
+ return;
+ }
- drawWithoutShadow(rect, [this, rect](ID2D1RenderTarget* renderTarget) {
- FloatSize renderTargetSize = renderTarget->GetSize();
- if (rect.size() == renderTargetSize)
- renderTarget->Clear();
- else
- renderTarget->FillRectangle(rect, m_data->brushWithColor(colorWithGlobalAlpha(fillColor())).get());
+ 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)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)
@@ -1813,7 +1848,7 @@
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__);
@@ -1835,7 +1870,7 @@
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__);
Modified: trunk/Source/WebCore/platform/graphics/win/ImageBufferDirect2D.cpp (207356 => 207357)
--- trunk/Source/WebCore/platform/graphics/win/ImageBufferDirect2D.cpp 2016-10-14 22:25:09 UTC (rev 207356)
+++ trunk/Source/WebCore/platform/graphics/win/ImageBufferDirect2D.cpp 2016-10-14 22:42:14 UTC (rev 207357)
@@ -66,7 +66,7 @@
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;
@@ -76,7 +76,7 @@
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)
{
@@ -101,6 +101,7 @@
if (numBytes.hasOverflowed())
return;
+ auto renderTarget = targetContext ? targetContext->platformContext() : nullptr;
if (!renderTarget)
renderTarget = GraphicsContext::defaultRenderTarget();
RELEASE_ASSERT(renderTarget);
Modified: trunk/Source/WebCore/platform/graphics/win/ImageDecoderDirect2D.cpp (207356 => 207357)
--- trunk/Source/WebCore/platform/graphics/win/ImageDecoderDirect2D.cpp 2016-10-14 22:25:09 UTC (rev 207356)
+++ trunk/Source/WebCore/platform/graphics/win/ImageDecoderDirect2D.cpp 2016-10-14 22:42:14 UTC (rev 207357)
@@ -187,7 +187,7 @@
return width * height * 4;
}
-void ImageDecoder::setRenderTarget(ID2D1RenderTarget* renderTarget)
+void ImageDecoder::setTargetContext(ID2D1RenderTarget* renderTarget)
{
m_renderTarget = renderTarget;
}
@@ -194,7 +194,7 @@
NativeImagePtr ImageDecoder::createFrameImageAtIndex(size_t index, SubsamplingLevel subsamplingLevel, DecodingMode) const
{
- if (!m_nativeDecoder)
+ if (!m_nativeDecoder || !m_renderTarget)
return nullptr;
COMPtr<IWICBitmapFrameDecode> frame;
@@ -211,10 +211,6 @@
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))
Modified: trunk/Source/WebCore/platform/graphics/win/ImageDecoderDirect2D.h (207356 => 207357)
--- trunk/Source/WebCore/platform/graphics/win/ImageDecoderDirect2D.h 2016-10-14 22:25:09 UTC (rev 207356)
+++ trunk/Source/WebCore/platform/graphics/win/ImageDecoderDirect2D.h 2016-10-14 22:42:14 UTC (rev 207357)
@@ -73,7 +73,7 @@
bool isAllDataReceived() const { return m_isAllDataReceived; }
void clearFrameBufferCache(size_t) { }
- void setRenderTarget(ID2D1RenderTarget*);
+ void setTargetContext(ID2D1RenderTarget*);
static IWICImagingFactory* systemImagingFactory();
Modified: trunk/Source/WebCore/platform/graphics/win/ImageDirect2D.cpp (207356 => 207357)
--- trunk/Source/WebCore/platform/graphics/win/ImageDirect2D.cpp 2016-10-14 22:25:09 UTC (rev 207356)
+++ trunk/Source/WebCore/platform/graphics/win/ImageDirect2D.cpp 2016-10-14 22:42:14 UTC (rev 207357)
@@ -92,11 +92,6 @@
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)
{
Modified: trunk/Source/WebCore/platform/graphics/win/NativeImageDirect2D.cpp (207356 => 207357)
--- trunk/Source/WebCore/platform/graphics/win/NativeImageDirect2D.cpp 2016-10-14 22:25:09 UTC (rev 207356)
+++ trunk/Source/WebCore/platform/graphics/win/NativeImageDirect2D.cpp 2016-10-14 22:42:14 UTC (rev 207357)
@@ -32,6 +32,7 @@
#include "GraphicsContext.h"
#include "IntSize.h"
#include "NotImplemented.h"
+#include <d2d1.h>
namespace WebCore {
Modified: trunk/Source/WebCore/platform/graphics/win/PatternDirect2D.cpp (207356 => 207357)
--- trunk/Source/WebCore/platform/graphics/win/PatternDirect2D.cpp 2016-10-14 22:25:09 UTC (rev 207356)
+++ trunk/Source/WebCore/platform/graphics/win/PatternDirect2D.cpp 2016-10-14 22:42:14 UTC (rev 207357)
@@ -37,12 +37,8 @@
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;
@@ -52,9 +48,14 @@
brushProperties.transform = patternTransform;
brushProperties.opacity = alpha;
+ auto patternImage = tileImage();
+
+ auto platformContext = context.platformContext();
+ RELEASE_ASSERT(platformContext);
+
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;
}
Modified: trunk/Source/WebCore/rendering/FilterEffectRenderer.cpp (207356 => 207357)
--- trunk/Source/WebCore/rendering/FilterEffectRenderer.cpp 2016-10-14 22:25:09 UTC (rev 207356)
+++ trunk/Source/WebCore/rendering/FilterEffectRenderer.cpp 2016-10-14 22:42:14 UTC (rev 207357)
@@ -48,6 +48,10 @@
#include <algorithm>
#include <wtf/MathExtras.h>
+#if USE(DIRECT2D)
+#include <d2d1.h>
+#endif
+
namespace WebCore {
static inline void endMatrixRow(Vector<float>& parameters)
@@ -313,7 +317,7 @@
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
@@ -320,8 +324,14 @@
// 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()));
+#endif
+ }
m_graphicsBufferAttached = true;
}
}
@@ -396,7 +406,7 @@
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())) {
Modified: trunk/Source/WebCore/rendering/FilterEffectRenderer.h (207356 => 207357)
--- trunk/Source/WebCore/rendering/FilterEffectRenderer.h 2016-10-14 22:25:09 UTC (rev 207356)
+++ trunk/Source/WebCore/rendering/FilterEffectRenderer.h 2016-10-14 22:42:14 UTC (rev 207357)
@@ -40,6 +40,7 @@
#include <wtf/RefCounted.h>
#include <wtf/RefPtr.h>
+
namespace WebCore {
class Document;
@@ -57,8 +58,9 @@
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 @@
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 };
};
@@ -107,7 +110,7 @@
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();
Modified: trunk/Source/WebCore/rendering/RenderLayer.cpp (207356 => 207357)
--- trunk/Source/WebCore/rendering/RenderLayer.cpp 2016-10-14 22:25:09 UTC (rev 207356)
+++ trunk/Source/WebCore/rendering/RenderLayer.cpp 2016-10-14 22:42:14 UTC (rev 207357)
@@ -4168,7 +4168,7 @@
if (!hasPaintedFilter)
return false;
- auto filterPainter = std::make_unique<FilterEffectRendererHelper>(hasPaintedFilter);
+ auto filterPainter = std::make_unique<FilterEffectRendererHelper>(hasPaintedFilter, context);
if (!filterPainter->haveFilterEffect())
return false;
@@ -4182,7 +4182,7 @@
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);
Modified: trunk/Source/WebCore/svg/graphics/SVGImage.cpp (207356 => 207357)
--- trunk/Source/WebCore/svg/graphics/SVGImage.cpp 2016-10-14 22:25:09 UTC (rev 207356)
+++ trunk/Source/WebCore/svg/graphics/SVGImage.cpp 2016-10-14 22:42:14 UTC (rev 207357)
@@ -54,6 +54,11 @@
#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)
@@ -187,7 +192,7 @@
#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;
@@ -204,6 +209,38 @@
}
#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)
{
Modified: trunk/Source/WebCore/svg/graphics/SVGImage.h (207356 => 207357)
--- trunk/Source/WebCore/svg/graphics/SVGImage.h 2016-10-14 22:25:09 UTC (rev 207356)
+++ trunk/Source/WebCore/svg/graphics/SVGImage.h 2016-10-14 22:42:14 UTC (rev 207357)
@@ -66,8 +66,11 @@
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:
friend class SVGImageChromeClient;
Modified: trunk/Source/WebCore/svg/graphics/SVGImageForContainer.cpp (207356 => 207357)
--- trunk/Source/WebCore/svg/graphics/SVGImageForContainer.cpp 2016-10-14 22:25:09 UTC (rev 207356)
+++ trunk/Source/WebCore/svg/graphics/SVGImageForContainer.cpp 2016-10-14 22:42:14 UTC (rev 207357)
@@ -46,9 +46,9 @@
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
Modified: trunk/Source/WebCore/svg/graphics/SVGImageForContainer.h (207356 => 207357)
--- trunk/Source/WebCore/svg/graphics/SVGImageForContainer.h 2016-10-14 22:25:09 UTC (rev 207356)
+++ trunk/Source/WebCore/svg/graphics/SVGImageForContainer.h 2016-10-14 22:42:14 UTC (rev 207357)
@@ -63,7 +63,7 @@
// 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)