Title: [249110] trunk/Source
Revision
249110
Author
bfulg...@apple.com
Date
2019-08-26 12:08:57 -0700 (Mon, 26 Aug 2019)

Log Message

[FTW] Go back to ID2D1Bitmap as our NativeImage type
https://bugs.webkit.org/show_bug.cgi?id=201122

Reviewed by Alex Christensen.

In Bug 200093 I switched the OS type of NativeImagePtr from ID2D1Bitmap to IWICBitmap.
However, this was an ill-advised approach, because it dramatically harmed performance due
to the heavy use of software rendering.

I originally made this change because I thought this was the only way to get to the backing
bits of the bitmaps, but it turns out that a more recent Direct2D data type (ID2D1Bitmap1)
has the ability to map its memory to CPU-accessible memory, allowing software filter effects.

This patch switches back to the ID2D1Bitap data type, and hooks up the ID2D1Bitmap1 data type
to access the underlying memory of the bitmaps when software filter effects are used.

Source/WebCore:

* platform/graphics/ImageBuffer.h:
* platform/graphics/NativeImage.h:
* platform/graphics/texmap/BitmapTextureGL.cpp:
* platform/graphics/win/Direct2DOperations.cpp:
* platform/graphics/win/Direct2DOperations.h:
* platform/graphics/win/Direct2DUtilities.cpp:
(WebCore::Direct2D::writeDiagnosticPNGToPath):
(WebCore::Direct2D::writeImageToDiskAsPNG): Deleted.
* platform/graphics/win/Direct2DUtilities.h:
* platform/graphics/win/GraphicsContextDirect2D.cpp:
* platform/graphics/win/ImageBufferDataDirect2D.cpp:
* platform/graphics/win/ImageBufferDataDirect2D.h:
* platform/graphics/win/ImageBufferDirect2D.cpp:
* platform/graphics/win/ImageDecoderDirect2D.cpp:
* platform/graphics/win/NativeImageDirect2D.cpp:
* platform/graphics/win/PatternDirect2D.cpp:
* svg/graphics/SVGImage.cpp:

Source/WebKit:

Reviewed by Alex Christensen.

* Shared/ShareableBitmap.h:
* Shared/win/ShareableBitmapDirect2D.cpp:
* UIProcess/win/BackingStoreDirect2D.cpp:
* WebProcess/WebPage/CoordinatedGraphics/DrawingAreaCoordinatedGraphics.cpp:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (249109 => 249110)


--- trunk/Source/WebCore/ChangeLog	2019-08-26 18:58:00 UTC (rev 249109)
+++ trunk/Source/WebCore/ChangeLog	2019-08-26 19:08:57 UTC (rev 249110)
@@ -1,3 +1,39 @@
+2019-08-26  Brent Fulgham  <bfulg...@apple.com>
+
+        [FTW] Go back to ID2D1Bitmap as our NativeImage type
+        https://bugs.webkit.org/show_bug.cgi?id=201122
+
+        Reviewed by Alex Christensen.
+
+        In Bug 200093 I switched the OS type of NativeImagePtr from ID2D1Bitmap to IWICBitmap.
+        However, this was an ill-advised approach, because it dramatically harmed performance due
+        to the heavy use of software rendering.
+
+        I originally made this change because I thought this was the only way to get to the backing
+        bits of the bitmaps, but it turns out that a more recent Direct2D data type (ID2D1Bitmap1)
+        has the ability to map its memory to CPU-accessible memory, allowing software filter effects.
+
+        This patch switches back to the ID2D1Bitap data type, and hooks up the ID2D1Bitmap1 data type
+        to access the underlying memory of the bitmaps when software filter effects are used.
+
+        * platform/graphics/ImageBuffer.h:
+        * platform/graphics/NativeImage.h:
+        * platform/graphics/texmap/BitmapTextureGL.cpp:
+        * platform/graphics/win/Direct2DOperations.cpp:
+        * platform/graphics/win/Direct2DOperations.h:
+        * platform/graphics/win/Direct2DUtilities.cpp:
+        (WebCore::Direct2D::writeDiagnosticPNGToPath):
+        (WebCore::Direct2D::writeImageToDiskAsPNG): Deleted.
+        * platform/graphics/win/Direct2DUtilities.h:
+        * platform/graphics/win/GraphicsContextDirect2D.cpp:
+        * platform/graphics/win/ImageBufferDataDirect2D.cpp:
+        * platform/graphics/win/ImageBufferDataDirect2D.h:
+        * platform/graphics/win/ImageBufferDirect2D.cpp:
+        * platform/graphics/win/ImageDecoderDirect2D.cpp:
+        * platform/graphics/win/NativeImageDirect2D.cpp:
+        * platform/graphics/win/PatternDirect2D.cpp:
+        * svg/graphics/SVGImage.cpp:
+
 2019-08-26  Sam Weinig  <wei...@apple.com>
 
         [WHLSL] TypeNamer can be simplified by replacing BaseTypeNameNode with uniqued AST::UnnamedTypes

Modified: trunk/Source/WebCore/platform/graphics/Image.cpp (249109 => 249110)


--- trunk/Source/WebCore/platform/graphics/Image.cpp	2019-08-26 18:58:00 UTC (rev 249109)
+++ trunk/Source/WebCore/platform/graphics/Image.cpp	2019-08-26 19:08:57 UTC (rev 249110)
@@ -140,7 +140,7 @@
 void Image::drawPattern(GraphicsContext& ctxt, const FloatRect& destRect, const FloatRect& tileRect, const AffineTransform& patternTransform,
     const FloatPoint& phase, const FloatSize& spacing, CompositeOperator op, BlendMode blendMode)
 {
-    if (!nativeImageForCurrentFrame())
+    if (!nativeImageForCurrentFrame(&ctxt))
         return;
 
     ctxt.drawPattern(*this, destRect, tileRect, patternTransform, phase, spacing, op, blendMode);

Modified: trunk/Source/WebCore/platform/graphics/ImageBuffer.h (249109 => 249110)


--- trunk/Source/WebCore/platform/graphics/ImageBuffer.h	2019-08-26 18:58:00 UTC (rev 249109)
+++ trunk/Source/WebCore/platform/graphics/ImageBuffer.h	2019-08-26 19:08:57 UTC (rev 249110)
@@ -146,8 +146,8 @@
     static RetainPtr<CGImageRef> sinkIntoNativeImage(std::unique_ptr<ImageBuffer>);
     void flushContext() const;
 #elif USE(DIRECT2D)
-    COMPtr<IWICBitmap> copyNativeImage(BackingStoreCopy = CopyBackingStore) const;
-    static COMPtr<IWICBitmap> sinkIntoNativeImage(std::unique_ptr<ImageBuffer>);
+    COMPtr<ID2D1Bitmap> copyNativeImage(BackingStoreCopy = CopyBackingStore) const;
+    static COMPtr<ID2D1Bitmap> sinkIntoNativeImage(std::unique_ptr<ImageBuffer>);
     void flushContext() const;
 #endif
     

Modified: trunk/Source/WebCore/platform/graphics/NativeImage.h (249109 => 249110)


--- trunk/Source/WebCore/platform/graphics/NativeImage.h	2019-08-26 18:58:00 UTC (rev 249109)
+++ trunk/Source/WebCore/platform/graphics/NativeImage.h	2019-08-26 19:08:57 UTC (rev 249110)
@@ -55,7 +55,7 @@
 #if USE(CG)
 typedef RetainPtr<CGImageRef> NativeImagePtr;
 #elif USE(DIRECT2D)
-typedef COMPtr<IWICBitmap> NativeImagePtr;
+typedef COMPtr<ID2D1Bitmap> NativeImagePtr;
 #elif USE(CAIRO)
 typedef RefPtr<cairo_surface_t> NativeImagePtr;
 #elif USE(WINGDI)

Modified: trunk/Source/WebCore/platform/graphics/texmap/BitmapTextureGL.cpp (249109 => 249110)


--- trunk/Source/WebCore/platform/graphics/texmap/BitmapTextureGL.cpp	2019-08-26 18:58:00 UTC (rev 249109)
+++ trunk/Source/WebCore/platform/graphics/texmap/BitmapTextureGL.cpp	2019-08-26 19:08:57 UTC (rev 249110)
@@ -163,28 +163,7 @@
     imageData = reinterpret_cast<const char*>(cairo_image_surface_get_data(surface));
     bytesPerLine = cairo_image_surface_get_stride(surface);
 #elif USE(DIRECT2D)
-    // We can't access the bitmap's memory when it is in the middle of a BeginDraw/EndDraw
-    WICRect rcLock = { 0, 0, targetRect.width(), targetRect.height() };
-
-    COMPtr<IWICBitmapLock> bitmapData;
-    HRESULT hr = frameImage->Lock(&rcLock, WICBitmapLockRead, &bitmapData);
-    if (!SUCCEEDED(hr))
-        return;
-
-    UINT stride = 0;
-    hr = bitmapData->GetStride(&stride);
-    if (!SUCCEEDED(hr))
-        return;
-
-    bytesPerLine = stride;
-
-    UINT bufferSize = 0;
-    WICInProcPointer dataPtr = nullptr;
-    hr = bitmapData->GetDataPointer(&bufferSize, &dataPtr);
-    if (!SUCCEEDED(hr))
-        return;
-
-    imageData = reinterpret_cast<char*>(dataPtr);
+    notImplemented();
 #endif
 
     updateContents(imageData, targetRect, offset, bytesPerLine);

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


--- trunk/Source/WebCore/platform/graphics/win/Direct2DOperations.cpp	2019-08-26 18:58:00 UTC (rev 249109)
+++ trunk/Source/WebCore/platform/graphics/win/Direct2DOperations.cpp	2019-08-26 19:08:57 UTC (rev 249110)
@@ -528,8 +528,6 @@
         FloatRect contextRect(FloatPoint(), context->GetSize());
         drawWithoutShadow(platformContext, contextRect, drawFunction);
     }
-
-    flush(platformContext);
 }
 
 void fillPath(PlatformContextDirect2D& platformContext, const Path& path, const Color& color, const ShadowState& shadowState)
@@ -554,8 +552,6 @@
         FloatRect contextRect(FloatPoint(), context->GetSize());
         drawWithoutShadow(platformContext, contextRect, drawFunction);
     }
-
-    flush(platformContext);
 }
 
 void strokeRect(PlatformContextDirect2D& platformContext, const FloatRect& rect, float lineWidth, const StrokeSource& strokeSource, const ShadowState& shadowState)
@@ -588,8 +584,6 @@
         drawWithShadow(platformContext, boundingRect, shadowState, drawFunction);
     else
         drawWithoutShadow(platformContext, boundingRect, drawFunction);
-
-    flush(platformContext);
 }
 
 void drawPath(PlatformContextDirect2D& platformContext, const Path& path, const StrokeSource& strokeSource, const ShadowState&)
@@ -640,13 +634,6 @@
     compositor->SetInputEffect(0, transformEffect.get());
     compositor->SetInput(1, bitmap);
 
-    // Flip the context
-    D2D1_MATRIX_3X2_F ctm;
-    deviceContext->GetTransform(&ctm);
-    auto translate = D2D1::Matrix3x2F::Translation(0.0f, deviceContext->GetSize().height);
-    auto flip = D2D1::Matrix3x2F::Scale(D2D1::SizeF(1.0f, -1.0f));
-    deviceContext->SetTransform(ctm * flip * translate);
-
     deviceContext->DrawImage(compositor.get(), D2D1_INTERPOLATION_MODE_LINEAR);
 }
 
@@ -655,13 +642,11 @@
     auto context = platformContext.renderTarget();
 
     // Render the current geometry to a bitmap context
-    COMPtr<ID2D1BitmapRenderTarget> bitmapTarget;
-    HRESULT hr = context->CreateCompatibleRenderTarget(&bitmapTarget);
-    RELEASE_ASSERT(SUCCEEDED(hr));
+    COMPtr<ID2D1BitmapRenderTarget> bitmapTarget = createBitmapRenderTarget(context);
 
     bitmapTarget->BeginDraw();
     drawCommands(bitmapTarget.get());
-    hr = bitmapTarget->EndDraw();
+    HRESULT hr = bitmapTarget->EndDraw();
     RELEASE_ASSERT(SUCCEEDED(hr));
 
     COMPtr<ID2D1Bitmap> bitmap;
@@ -836,13 +821,11 @@
     else
         drawWithoutShadow(platformContext, adjustedDestRect, drawFunction);
 
-    flush(platformContext);
-
     if (!stateSaver.didSave())
         context->SetTransform(ctm);
 }
 
-void drawPattern(PlatformContextDirect2D& platformContext, IWICBitmap* tileImage, const IntSize& size, const FloatRect& destRect, const FloatRect& tileRect, const AffineTransform& patternTransform, const FloatPoint& phase, CompositeOperator compositeOperator, BlendMode blendMode)
+void drawPattern(PlatformContextDirect2D& platformContext, COMPtr<ID2D1Bitmap>&& tileImage, const IntSize& size, const FloatRect& destRect, const FloatRect& tileRect, const AffineTransform& patternTransform, const FloatPoint& phase, CompositeOperator compositeOperator, BlendMode blendMode)
 {
     auto context = platformContext.renderTarget();
     PlatformContextStateSaver stateSaver(platformContext);
@@ -866,8 +849,6 @@
     // If we only want a subset of the bitmap, we need to create a cropped bitmap image. According to the documentation,
     // this does not allocate new bitmap memory.
     if (size.width() > destRect.width() || size.height() > destRect.height()) {
-        ASSERT(0);
-        /*
         float dpiX = 0;
         float dpiY = 0;
         tileImage->GetDpi(&dpiX, &dpiY);
@@ -880,16 +861,10 @@
             if (SUCCEEDED(hr))
                 tileImage = subImage;
         }
-        */
     }
 
-    COMPtr<ID2D1Bitmap> bitmap;
-    HRESULT hr = context->CreateBitmapFromWicBitmap(tileImage, nullptr, &bitmap);
-    if (!SUCCEEDED(hr))
-        return;
-
     COMPtr<ID2D1BitmapBrush> patternBrush;
-    hr = context->CreateBitmapBrush(bitmap.get(), &bitmapBrushProperties, &brushProperties, &patternBrush);
+    HRESULT hr = context->CreateBitmapBrush(tileImage.get(), &bitmapBrushProperties, &brushProperties, &patternBrush);
     ASSERT(SUCCEEDED(hr));
     if (!SUCCEEDED(hr))
         return;
@@ -1109,8 +1084,8 @@
     PlatformContextDirect2D::TransparencyLayerState transparencyLayer;
     transparencyLayer.opacity = opacity;
 
-    HRESULT hr = platformContext.renderTarget()->CreateCompatibleRenderTarget(&transparencyLayer.renderTarget);
-    RELEASE_ASSERT(SUCCEEDED(hr));
+    transparencyLayer.renderTarget = createBitmapRenderTarget(platformContext.renderTarget());
+
     platformContext.m_transparencyLayerStack.append(WTFMove(transparencyLayer));
 
     platformContext.m_transparencyLayerStack.last().renderTarget->BeginDraw();
@@ -1222,7 +1197,20 @@
     notImplemented();
 }
 
+
+void copyBits(const uint8_t* srcRows, unsigned rowCount, unsigned colCount, unsigned srcStride, unsigned destStride, uint8_t* destRows)
+{
+    for (unsigned y = 0; y < rowCount; ++y) {
+        // Source data may be power-of-two sized, so we need to only copy the bits that
+        // correspond to the rectangle supplied by the caller.
+        const uint32_t* srcRow = reinterpret_cast<const uint32_t*>(srcRows + srcStride * y);
+        uint32_t* destRow = reinterpret_cast<uint32_t*>(destRows + destStride * y);
+        memcpy(destRow, srcRow, colCount);
+    }
+}
+
 } // namespace Direct2D
+
 } // namespace WebCore
 
 #endif // USE(DIRECT2D)

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


--- trunk/Source/WebCore/platform/graphics/win/Direct2DOperations.h	2019-08-26 18:58:00 UTC (rev 249109)
+++ trunk/Source/WebCore/platform/graphics/win/Direct2DOperations.h	2019-08-26 19:08:57 UTC (rev 249110)
@@ -37,6 +37,7 @@
 #include "DashArray.h"
 #include "GraphicsContext.h"
 #include "GraphicsTypes.h"
+#include <_javascript_Core/Uint8ClampedArray.h>
 #include <d2d1.h>
 
 namespace WebCore {
@@ -130,7 +131,7 @@
 void drawNativeImage(PlatformContextDirect2D&, IWICBitmap*, const FloatSize& imageSize, const FloatRect&, const FloatRect&, CompositeOperator, BlendMode, ImageOrientation, InterpolationQuality, float, const ShadowState&);
 void drawNativeImage(PlatformContextDirect2D&, ID2D1Bitmap*, const FloatSize& imageSize, const FloatRect&, const FloatRect&, CompositeOperator, BlendMode, ImageOrientation, InterpolationQuality, float, const ShadowState&);
 void drawPath(PlatformContextDirect2D&, const Path&, const StrokeSource&, const ShadowState&);
-void drawPattern(PlatformContextDirect2D&, IWICBitmap*, const IntSize&, const FloatRect&, const FloatRect&, const AffineTransform&, const FloatPoint&, CompositeOperator, BlendMode);
+void drawPattern(PlatformContextDirect2D&, COMPtr<ID2D1Bitmap>&&, const IntSize&, const FloatRect&, const FloatRect&, const AffineTransform&, const FloatPoint&, CompositeOperator, BlendMode);
 
 void drawWithoutShadow(PlatformContextDirect2D&, const FloatRect& boundingRect, const WTF::Function<void(ID2D1RenderTarget*)>& drawCommands);
 void drawWithShadow(PlatformContextDirect2D&, const FloatRect& boundingRect, const ShadowState&, const WTF::Function<void(ID2D1RenderTarget*)>& drawCommands);

Modified: trunk/Source/WebCore/platform/graphics/win/Direct2DUtilities.cpp (249109 => 249110)


--- trunk/Source/WebCore/platform/graphics/win/Direct2DUtilities.cpp	2019-08-26 18:58:00 UTC (rev 249109)
+++ trunk/Source/WebCore/platform/graphics/win/Direct2DUtilities.cpp	2019-08-26 19:08:57 UTC (rev 249110)
@@ -115,7 +115,7 @@
         return nullptr;
 
     COMPtr<IWICBitmap> surface;
-    HRESULT hr = ImageDecoderDirect2D::systemImagingFactory()->CreateBitmapFromMemory(size.width(), size.height(), GUID_WICPixelFormat32bppPBGRA, stride, static_cast<UINT>(numBytes.unsafeGet()), reinterpret_cast<BYTE*>(data), &surface);
+    HRESULT hr = ImageDecoderDirect2D::systemImagingFactory()->CreateBitmapFromMemory(size.width(), size.height(), wicBitmapFormat(), stride, static_cast<UINT>(numBytes.unsafeGet()), reinterpret_cast<BYTE*>(data), &surface);
     if (!SUCCEEDED(hr))
         return nullptr;
 
@@ -125,7 +125,7 @@
 COMPtr<IWICBitmap> createWicBitmap(const IntSize& size)
 {
     COMPtr<IWICBitmap> surface;
-    HRESULT hr = ImageDecoderDirect2D::systemImagingFactory()->CreateBitmap(size.width(), size.height(), GUID_WICPixelFormat32bppPBGRA, WICBitmapCacheOnDemand, &surface);
+    HRESULT hr = ImageDecoderDirect2D::systemImagingFactory()->CreateBitmap(size.width(), size.height(), wicBitmapFormat(), WICBitmapCacheOnDemand, &surface);
     if (!SUCCEEDED(hr))
         return nullptr;
 
@@ -132,13 +132,36 @@
     return surface;
 }
 
+D2D1_PIXEL_FORMAT pixelFormatForSoftwareManipulation()
+{
+    return D2D1::PixelFormat(DXGI_FORMAT_R8G8B8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED);
+}
+
+D2D1_PIXEL_FORMAT pixelFormat()
+{
+    // Since we need to interact with HDC from time-to-time, we are forced to use DXGI_FORMAT_B8G8R8A8_UNORM and D2D1_ALPHA_MODE_PREMULTIPLIED
+    return D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED);
+}
+
+GUID wicBitmapFormat()
+{
+    // This is the WIC format compatible with DXGI_FORMAT_B8G8R8A8_UNORM. It is also supposedly the most efficient in-memory
+    // representation for WIC images.
+    return GUID_WICPixelFormat32bppPBGRA;
+}
+
+D2D1_BITMAP_PROPERTIES bitmapProperties()
+{
+    return D2D1::BitmapProperties(pixelFormat());
+}
+
 COMPtr<ID2D1Bitmap> createBitmap(ID2D1RenderTarget* renderTarget, const IntSize& size)
 {
-    auto bitmapProperties = D2D1::BitmapProperties(D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED));
+    auto bitmapCreateProperties = bitmapProperties();
 
     COMPtr<ID2D1Bitmap> bitmap;
     D2D1_SIZE_U bitmapSize = size;
-    HRESULT hr = renderTarget->CreateBitmap(bitmapSize, bitmapProperties, &bitmap);
+    HRESULT hr = renderTarget->CreateBitmap(bitmapSize, bitmapCreateProperties, &bitmap);
     if (!SUCCEEDED(hr))
         return nullptr;
 
@@ -145,11 +168,15 @@
     return bitmap;
 }
 
+D2D1_RENDER_TARGET_PROPERTIES renderTargetProperties()
+{
+    return D2D1::RenderTargetProperties(D2D1_RENDER_TARGET_TYPE_DEFAULT,
+        pixelFormat(), 0, 0, D2D1_RENDER_TARGET_USAGE_GDI_COMPATIBLE, D2D1_FEATURE_LEVEL_DEFAULT);
+}
+
 COMPtr<ID2D1RenderTarget> createRenderTargetFromWICBitmap(IWICBitmap* bitmapSource)
 {
-    auto targetProperties = D2D1::RenderTargetProperties(D2D1_RENDER_TARGET_TYPE_DEFAULT,
-        D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED),
-        0, 0, D2D1_RENDER_TARGET_USAGE_NONE, D2D1_FEATURE_LEVEL_DEFAULT);
+    auto targetProperties = renderTargetProperties();
 
     COMPtr<ID2D1RenderTarget> bitmapContext;
     HRESULT hr = GraphicsContext::systemFactory()->CreateWicBitmapRenderTarget(bitmapSource, &targetProperties, &bitmapContext);
@@ -161,9 +188,7 @@
 
 COMPtr<ID2D1DCRenderTarget> createGDIRenderTarget()
 {
-    auto targetProperties = D2D1::RenderTargetProperties(D2D1_RENDER_TARGET_TYPE_DEFAULT,
-        D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED),
-        0, 0, D2D1_RENDER_TARGET_USAGE_GDI_COMPATIBLE, D2D1_FEATURE_LEVEL_DEFAULT);
+    auto targetProperties = renderTargetProperties();
 
     COMPtr<ID2D1DCRenderTarget> renderTarget;
     HRESULT hr = GraphicsContext::systemFactory()->CreateDCRenderTarget(&targetProperties, &renderTarget);
@@ -173,6 +198,36 @@
     return renderTarget;
 }
 
+COMPtr<ID2D1BitmapRenderTarget> createBitmapRenderTarget(ID2D1RenderTarget* renderTarget)
+{
+    if (!renderTarget)
+        renderTarget = GraphicsContext::defaultRenderTarget();
+
+    COMPtr<ID2D1BitmapRenderTarget> bitmapContext;
+    HRESULT hr = renderTarget->CreateCompatibleRenderTarget(nullptr, nullptr, nullptr, D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_GDI_COMPATIBLE, &bitmapContext);
+    if (!SUCCEEDED(hr))
+        return nullptr;
+
+    return bitmapContext;
+}
+
+COMPtr<ID2D1BitmapRenderTarget> createBitmapRenderTargetOfSize(const IntSize& size, ID2D1RenderTarget* renderTarget, float deviceScaleFactor)
+{
+    UNUSED_PARAM(deviceScaleFactor);
+
+    if (!renderTarget)
+        renderTarget = GraphicsContext::defaultRenderTarget();
+
+    COMPtr<ID2D1BitmapRenderTarget> bitmapContext;
+    auto desiredSize = D2D1::SizeF(size.width(), size.height());
+    D2D1_SIZE_U pixelSize = size;
+    HRESULT hr = renderTarget->CreateCompatibleRenderTarget(&desiredSize, &pixelSize, nullptr, D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_GDI_COMPATIBLE, &bitmapContext);
+    if (!SUCCEEDED(hr))
+        return nullptr;
+
+    return bitmapContext;
+}
+
 void copyRectFromOneSurfaceToAnother(ID2D1Bitmap* from, ID2D1Bitmap* to, const IntSize& sourceOffset, const IntRect& rect, const IntSize& destOffset)
 {
     IntSize sourceBitmapSize = from->GetPixelSize();
@@ -199,7 +254,7 @@
     ASSERT(SUCCEEDED(hr));
 }
 
-void writeImageToDiskAsPNG(ID2D1RenderTarget* renderTarget, ID2D1Bitmap* bitmap, LPCWSTR fileName)
+void writeDiagnosticPNGToPath(ID2D1RenderTarget* renderTarget, ID2D1Bitmap* bitmap, LPCWSTR fileName)
 {
     COMPtr<IWICBitmapEncoder> wicBitmapEncoder;
     HRESULT hr = ImageDecoderDirect2D::systemImagingFactory()->CreateEncoder(GUID_ContainerFormatPng, nullptr, &wicBitmapEncoder);

Modified: trunk/Source/WebCore/platform/graphics/win/Direct2DUtilities.h (249109 => 249110)


--- trunk/Source/WebCore/platform/graphics/win/Direct2DUtilities.h	2019-08-26 18:58:00 UTC (rev 249109)
+++ trunk/Source/WebCore/platform/graphics/win/Direct2DUtilities.h	2019-08-26 19:08:57 UTC (rev 249110)
@@ -34,11 +34,16 @@
 #include "IntSize.h"
 
 interface ID2D1Bitmap;
+interface ID2D1BitmapRenderTarget;
 interface ID2D1DCRenderTarget;
 interface ID2D1RenderTarget;
 interface IWICBitmapSource;
 interface IWICBitmap;
 
+struct D2D1_BITMAP_PROPERTIES;
+struct D2D1_PIXEL_FORMAT;
+struct D2D1_RENDER_TARGET_PROPERTIES;
+
 namespace WebCore {
 
 class FloatPoint;
@@ -48,6 +53,14 @@
 
 namespace Direct2D {
 
+GUID wicBitmapFormat();
+D2D1_PIXEL_FORMAT pixelFormat(); // BGRA
+D2D1_PIXEL_FORMAT pixelFormatForSoftwareManipulation(); // RGBA
+D2D1_BITMAP_PROPERTIES bitmapProperties();
+D2D1_RENDER_TARGET_PROPERTIES renderTargetProperties();
+
+void inPlaceSwizzle(uint8_t* byteData, unsigned length, bool applyPremultiplication = false);
+
 IntSize bitmapSize(IWICBitmapSource*);
 FloatSize bitmapSize(ID2D1Bitmap*);
 FloatPoint bitmapResolution(IWICBitmapSource*);
@@ -57,11 +70,13 @@
 COMPtr<IWICBitmap> createWicBitmap(const IntSize&);
 COMPtr<IWICBitmap> createDirect2DImageSurfaceWithData(void* data, const IntSize&, unsigned stride);
 COMPtr<ID2D1RenderTarget> createRenderTargetFromWICBitmap(IWICBitmap*);
+COMPtr<ID2D1BitmapRenderTarget> createBitmapRenderTargetOfSize(const IntSize&, ID2D1RenderTarget* = nullptr, float deviceScaleFactor = 1.0);
+COMPtr<ID2D1BitmapRenderTarget> createBitmapRenderTarget(ID2D1RenderTarget* = nullptr);
 COMPtr<ID2D1DCRenderTarget> createGDIRenderTarget();
 
 void copyRectFromOneSurfaceToAnother(ID2D1Bitmap* from, ID2D1Bitmap* to, const IntSize& sourceOffset, const IntRect&, const IntSize& destOffset = IntSize());
 
-void writeImageToDiskAsPNG(ID2D1RenderTarget*, ID2D1Bitmap*, LPCWSTR fileName);
+void writeDiagnosticPNGToPath(ID2D1RenderTarget*, ID2D1Bitmap*, LPCWSTR fileName);
 
 } // namespace Direct2D
 

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


--- trunk/Source/WebCore/platform/graphics/win/GraphicsContextDirect2D.cpp	2019-08-26 18:58:00 UTC (rev 249109)
+++ trunk/Source/WebCore/platform/graphics/win/GraphicsContextDirect2D.cpp	2019-08-26 19:08:57 UTC (rev 249110)
@@ -28,6 +28,7 @@
 
 #include "COMPtr.h"
 #include "Direct2DOperations.h"
+#include "Direct2DUtilities.h"
 #include "DisplayListRecorder.h"
 #include "FloatRoundedRect.h"
 #include "GraphicsContextPlatformPrivateDirect2D.h"
@@ -54,9 +55,7 @@
 GraphicsContext::GraphicsContext(HDC hdc, ID2D1DCRenderTarget** renderTarget, RECT rect, bool hasAlpha)
 {
     // Create a DC render target.
-    auto targetProperties = D2D1::RenderTargetProperties(D2D1_RENDER_TARGET_TYPE_DEFAULT,
-        D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED),
-        0, 0, D2D1_RENDER_TARGET_USAGE_NONE, D2D1_FEATURE_LEVEL_DEFAULT);
+    auto targetProperties = Direct2D::renderTargetProperties();
 
     HRESULT hr = GraphicsContext::systemFactory()->CreateDCRenderTarget(&targetProperties, renderTarget);
     RELEASE_ASSERT(SUCCEEDED(hr));
@@ -99,6 +98,7 @@
         auto hwndRenderTargetProperties = D2D1::HwndRenderTargetProperties(::GetDesktopWindow(), D2D1::SizeU(10, 10));
         HRESULT hr = systemFactory()->CreateHwndRenderTarget(&renderTargetProperties, &hwndRenderTargetProperties, reinterpret_cast<ID2D1HwndRenderTarget**>(&defaultRenderTarget));
         RELEASE_ASSERT(SUCCEEDED(hr));
+        defaultRenderTarget->AddRef();
     }
 
     return defaultRenderTarget;
@@ -113,8 +113,7 @@
 
     DIBPixelData pixelData(bitmap);
 
-    auto targetProperties = D2D1::RenderTargetProperties();
-    targetProperties.pixelFormat = D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED);
+    auto targetProperties = Direct2D::renderTargetProperties();
 
     COMPtr<ID2D1DCRenderTarget> renderTarget;
     HRESULT hr = systemFactory()->CreateDCRenderTarget(&targetProperties, &renderTarget);
@@ -208,7 +207,7 @@
     Direct2D::restore(*platformContext());
 }
 
-void GraphicsContext::drawNativeImage(const COMPtr<IWICBitmap>& image, const FloatSize& imageSize, const FloatRect& destRect, const FloatRect& srcRect, CompositeOperator compositeOperator, BlendMode blendMode, ImageOrientation orientation)
+void GraphicsContext::drawNativeImage(const COMPtr<ID2D1Bitmap>& image, const FloatSize& imageSize, const FloatRect& destRect, const FloatRect& srcRect, CompositeOperator compositeOperator, BlendMode blendMode, ImageOrientation orientation)
 {
     if (paintingDisabled())
         return;
@@ -240,7 +239,7 @@
     DIBPixelData pixelData(sourceBitmap.get());
     ASSERT(pixelData.bitsPerPixel() == 32);
 
-    auto bitmapProperties = D2D1::BitmapProperties(D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED));
+    auto bitmapProperties = Direct2D::bitmapProperties();
 
     ASSERT(hasPlatformContext());
     auto& platformContext = *this->platformContext();
@@ -435,8 +434,8 @@
     }
 
     ASSERT(hasPlatformContext());
-    if (auto tileImage = image.nativeImageForCurrentFrame())
-        Direct2D::drawPattern(*platformContext(), tileImage.get(), IntSize(image.size()), destRect, tileRect, patternTransform, phase, compositeOperator, blendMode);
+    if (auto tileImage = image.nativeImageForCurrentFrame(this))
+        Direct2D::drawPattern(*platformContext(), WTFMove(tileImage), IntSize(image.size()), destRect, tileRect, patternTransform, phase, compositeOperator, blendMode);
 }
 
 void GraphicsContext::clipToImageBuffer(ImageBuffer& buffer, const FloatRect& destRect)

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


--- trunk/Source/WebCore/platform/graphics/win/GraphicsContextImplDirect2D.cpp	2019-08-26 18:58:00 UTC (rev 249109)
+++ trunk/Source/WebCore/platform/graphics/win/GraphicsContextImplDirect2D.cpp	2019-08-26 19:08:57 UTC (rev 249110)
@@ -291,8 +291,9 @@
 
 void GraphicsContextImplDirect2D::drawPattern(Image& image, const FloatRect& destRect, const FloatRect& tileRect, const AffineTransform& patternTransform, const FloatPoint& phase, const FloatSize&, CompositeOperator compositeOperator, BlendMode blendMode)
 {
-    if (auto surface = image.nativeImageForCurrentFrame())
-        Direct2D::drawPattern(m_platformContext, surface.get(), IntSize(image.size()), destRect, tileRect, patternTransform, phase, compositeOperator, blendMode);
+    auto* context = &graphicsContext();
+    if (auto surface = image.nativeImageForCurrentFrame(context))
+        Direct2D::drawPattern(m_platformContext, WTFMove(surface), IntSize(image.size()), destRect, tileRect, patternTransform, phase, compositeOperator, blendMode);
 }
 
 void GraphicsContextImplDirect2D::drawRect(const FloatRect& rect, float borderThickness)
@@ -421,8 +422,8 @@
     if (!image)
         return;
 
-
-    if (auto surface = image->nativeImageForCurrentFrame())
+    auto* context = &graphicsContext();
+    if (auto surface = image->nativeImageForCurrentFrame(context))
         notImplemented();
 }
 

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


--- trunk/Source/WebCore/platform/graphics/win/ImageBufferDataDirect2D.cpp	2019-08-26 18:58:00 UTC (rev 249109)
+++ trunk/Source/WebCore/platform/graphics/win/ImageBufferDataDirect2D.cpp	2019-08-26 19:08:57 UTC (rev 249110)
@@ -29,10 +29,12 @@
 #if USE(DIRECT2D)
 
 #include "BitmapInfo.h"
+#include "Direct2DUtilities.h"
 #include "GraphicsContext.h"
 #include "HWndDC.h"
 #include "IntRect.h"
 #include "NotImplemented.h"
+#include "PlatformContextDirect2D.h"
 #include <_javascript_Core/JSCInlines.h>
 #include <_javascript_Core/TypedArrayInlines.h>
 #include <_javascript_Core/Uint8ClampedArray.h>
@@ -42,8 +44,43 @@
 
 namespace WebCore {
 
-RefPtr<Uint8ClampedArray> ImageBufferData::getData(AlphaPremultiplication, const IntRect& rect, const IntSize& size, bool /* accelerateRendering */, float /* resolutionScale */) const
+// Swizzle the red and blue bytes of the pixels in a buffer
+template <AlphaPremultiplication desiredFormat>
+void swizzleAndPremultiply(const uint8_t* srcRows, unsigned rowCount, unsigned colCount, unsigned srcStride, unsigned destStride, uint8_t* destRows)
 {
+    for (unsigned y = 0; y < rowCount; ++y) {
+        // Source data may be power-of-two sized, so we need to only copy the bits that
+        // correspond to the rectangle supplied by the caller.
+        const uint32_t* srcRow = reinterpret_cast<const uint32_t*>(srcRows + srcStride * y);
+        uint8_t* destRow = destRows + destStride * y;
+        for (unsigned x = 0; x < colCount; ++x) {
+            unsigned bytePosition = x * 4;
+            const uint32_t* srcPixel = srcRow + x;
+
+            // Software filters expect (P)RGBA bytes. We need to swizzle from Direct2D's PBGRA to be compatible.
+            uint32_t alpha = (*srcPixel & 0xFF000000) >> 24;
+            uint32_t red = (*srcPixel & 0x00FF0000) >> 16;
+            uint32_t green = (*srcPixel & 0x0000FF00) >> 8;
+            uint32_t blue = (*srcPixel & 0x000000FF);
+
+            if (desiredFormat == AlphaPremultiplication::Unpremultiplied) {
+                if (alpha && alpha != 255) {
+                    red = red * 255 / alpha;
+                    green = green * 255 / alpha;
+                    blue = blue * 255 / alpha;
+                }
+            }
+
+            destRow[bytePosition]     = red;
+            destRow[bytePosition + 1] = green;
+            destRow[bytePosition + 2] = blue;
+            destRow[bytePosition + 3] = alpha;
+        }
+    }
+}
+
+RefPtr<Uint8ClampedArray> ImageBufferData::getData(AlphaPremultiplication desiredFormat, const IntRect& rect, const IntSize& size, bool /* accelerateRendering */, float /* resolutionScale */) const
+{
     auto numBytes = rect.area<RecordOverflow>() * 4;
     if (numBytes.hasOverflowed())
         return nullptr;
@@ -53,29 +90,81 @@
     if (!resultData)
         return nullptr;
 
-    WICRect rcLock = { 0, 0, rect.width(), rect.height() };
+    if (!bitmap)
+        return result;
 
-    // We cannot access the data backing an IWICBitmap while an active draw session is open.
     context->endDraw();
 
-    COMPtr<IWICBitmapLock> bitmapDataLock;
-    HRESULT hr = bitmapSource->Lock(&rcLock, WICBitmapLockRead, &bitmapDataLock);
-    if (SUCCEEDED(hr)) {
-        UINT bufferSize = 0;
-        WICInProcPointer dataPtr = nullptr;
-        hr = bitmapDataLock->GetDataPointer(&bufferSize, &dataPtr);
-        if (SUCCEEDED(hr))
-            memcpy(result->data(), reinterpret_cast<char*>(dataPtr), numBytes.unsafeGet());
-    }
+    COMPtr<ID2D1DeviceContext> d2dDeviceContext;
+    HRESULT hr = platformContext->renderTarget()->QueryInterface(__uuidof(ID2D1DeviceContext), reinterpret_cast<void**>(&d2dDeviceContext));
+    ASSERT(SUCCEEDED(hr));
 
-    // Once we are done modifying the data, unlock the bitmap
-    bitmapDataLock = nullptr;
+    auto bytesPerRowInData = size.width() * 4;
 
+    COMPtr<ID2D1Bitmap1> cpuBitmap;
+    D2D1_BITMAP_PROPERTIES1 bitmapProperties2 = D2D1::BitmapProperties1(D2D1_BITMAP_OPTIONS_CPU_READ | D2D1_BITMAP_OPTIONS_CANNOT_DRAW, Direct2D::pixelFormat());
+    hr = d2dDeviceContext->CreateBitmap(size, nullptr, bytesPerRowInData, bitmapProperties2, &cpuBitmap);
+    if (!SUCCEEDED(hr))
+        return nullptr;
+
+    D2D1_POINT_2U targetPos = D2D1::Point2U();
+    D2D1_RECT_U dataRect = rect;
+    hr = cpuBitmap->CopyFromBitmap(&targetPos, bitmap.get(), &dataRect);
+    if (!SUCCEEDED(hr))
+        return nullptr;
+
+    D2D1_MAPPED_RECT mappedData;
+    hr = cpuBitmap->Map(D2D1_MAP_OPTIONS_READ, &mappedData);
+    if (!SUCCEEDED(hr))
+        return nullptr;
+
+    // Software filters expect RGBA bytes. We need to swizzle from Direct2D's BGRA to be compatible.
+    Checked<int> height = rect.height();
+    Checked<int> width = rect.width();
+
+    if (desiredFormat == AlphaPremultiplication::Unpremultiplied)
+        swizzleAndPremultiply<AlphaPremultiplication::Unpremultiplied>(mappedData.bits, height.unsafeGet(), width.unsafeGet(), mappedData.pitch, bytesPerRowInData, resultData);
+    else
+        swizzleAndPremultiply<AlphaPremultiplication::Premultiplied>(mappedData.bits, height.unsafeGet(), width.unsafeGet(), mappedData.pitch, bytesPerRowInData, resultData);
+
+    hr = cpuBitmap->Unmap();
+    ASSERT(SUCCEEDED(hr));
+
     context->beginDraw();
 
     return result;
 }
 
+// Swizzle the red and blue bytes of the pixels in a buffer
+template <AlphaPremultiplication sourceFormat>
+void inPlaceSwizzle(uint8_t* byteData, unsigned byteCount)
+{
+    size_t pixelCount = byteCount / 4;
+    auto* pixelData = reinterpret_cast<uint32_t*>(byteData);
+
+    for (size_t i = 0; i < pixelCount; ++i) {
+        uint32_t pixel = *pixelData;
+        size_t bytePosition = i * 4;
+
+        uint32_t alpha = (pixel & 0xFF000000) >> 24;
+        uint32_t red = (pixel & 0x00FF0000) >> 16;
+        uint32_t green = (pixel & 0x0000FF00) >> 8;
+        uint32_t blue = (pixel & 0x000000FF);
+
+        // (P)RGBA -> PBGRA
+        if (sourceFormat == AlphaPremultiplication::Unpremultiplied) {
+            if (alpha != 255) {
+                red = (red * alpha + 254) / 255;
+                green = (green * alpha + 254) / 255;
+                blue = (blue * alpha + 254) / 255;
+            }
+        }
+
+        *pixelData = (alpha << 24) | red  << 16 | green  << 8 | blue;
+        ++pixelData;
+    }
+}
+
 void ImageBufferData::putData(const Uint8ClampedArray& source, AlphaPremultiplication sourceFormat, const IntSize& sourceSize, const IntRect& sourceRect, const IntPoint& destPoint, const IntSize& size, bool /* accelerateRendering */, float resolutionScale)
 {
     ASSERT(sourceRect.width() > 0);
@@ -114,59 +203,99 @@
     if (width <= 0 || height <= 0)
         return;
 
-    // We cannot access the data backing an IWICBitmap while an active draw session is open.
     context->endDraw();
 
-    WICRect rcLock = { 0, 0, sourceSize.width(), sourceSize.height() };
+    auto pixelSize = bitmap->GetPixelSize();
+    ASSERT(pixelSize.width >= sourceSize.width());
+    ASSERT(pixelSize.width >= size.width());
+    ASSERT(pixelSize.height >= sourceSize.height());
+    ASSERT(pixelSize.height >= size.height());
 
-    COMPtr<IWICBitmapLock> bitmapDataLock;
-    HRESULT hr = bitmapSource->Lock(&rcLock, WICBitmapLockWrite, &bitmapDataLock);
-    if (!SUCCEEDED(hr))
-        return;
+    // Software generated bitmap data is in RGBA. We need to swizzle to premultiplied BGRA to be compatible
+    // with the HWND/HDC render backing we use.
+    if (sourceFormat == AlphaPremultiplication::Unpremultiplied)
+        inPlaceSwizzle<AlphaPremultiplication::Unpremultiplied>(source.data(), source.length()); // RGBA -> PBGRA
+    else
+        inPlaceSwizzle<AlphaPremultiplication::Premultiplied>(source.data(), source.length()); // PRGBA -> PBGRA
 
-    UINT stride = 0;
-    hr = bitmapDataLock->GetStride(&stride);
-    if (!SUCCEEDED(hr))
-        return;
+    COMPtr<ID2D1BitmapRenderTarget> bitmapRenderTarget;
+    HRESULT hr = platformContext->renderTarget()->QueryInterface(__uuidof(ID2D1BitmapRenderTarget), reinterpret_cast<void**>(&bitmapRenderTarget));
+    ASSERT(SUCCEEDED(hr));
 
-    UINT bufferSize = 0;
-    WICInProcPointer dataPtr = nullptr;
-    hr = bitmapDataLock->GetDataPointer(&bufferSize, &dataPtr);
+    auto bytesPerRowInData = sourceRect.width() * 4;
+
+    COMPtr<ID2D1Bitmap> swizzledBitmap;
+    D2D1_BITMAP_PROPERTIES bitmapProperties = D2D1::BitmapProperties(Direct2D::pixelFormat());
+    hr = bitmapRenderTarget->CreateBitmap(sourceSize, source.data(), bytesPerRowInData, bitmapProperties, &swizzledBitmap);
     if (!SUCCEEDED(hr))
         return;
 
-    ASSERT(bufferSize == source.byteLength());
+    D2D1_POINT_2U destPointD2D = destPoint;
+    D2D1_RECT_U srcRect = sourceRect;
+    hr = bitmap->CopyFromMemory(&srcRect, source.data(), bytesPerRowInData);
+    ASSERT(SUCCEEDED(hr));
 
-    unsigned srcBytesPerRow = 4 * sourceSize.width();
+    context->beginDraw();
+}
 
-    ASSERT(srcBytesPerRow == stride);
+COMPtr<ID2D1Bitmap> ImageBufferData::compatibleBitmap(ID2D1RenderTarget* renderTarget)
+{
+    if (!renderTarget)
+        return bitmap;
 
-    const uint8_t* srcRows = source.data() + (originy * srcBytesPerRow + originx * 4).unsafeGet();
+    if (platformContext->renderTarget() == renderTarget)
+        return bitmap;
 
-    auto row = makeUniqueArray<uint8_t>(srcBytesPerRow);
+    auto size = bitmap->GetPixelSize();
 
-    for (int y = 0; y < height.unsafeGet(); ++y) {
-        for (int x = 0; x < width.unsafeGet(); x++) {
-            int basex = x * 4;
-            uint8_t alpha = srcRows[basex + 3];
-            if (sourceFormat == AlphaPremultiplication::Unpremultiplied && alpha != 255) {
-                row[basex] = (srcRows[basex] * alpha + 254) / 255;
-                row[basex + 1] = (srcRows[basex + 1] * alpha + 254) / 255;
-                row[basex + 2] = (srcRows[basex + 2] * alpha + 254) / 255;
-                row[basex + 3] = alpha;
-            } else
-                reinterpret_cast<uint32_t*>(row.get() + basex)[0] = reinterpret_cast<const uint32_t*>(srcRows + basex)[0];
-        }
+    Checked<unsigned, RecordOverflow> numBytes = size.width * size.height * 4;
+    if (numBytes.hasOverflowed())
+        return nullptr;
 
-        memcpy(reinterpret_cast<char*>(dataPtr + y * srcBytesPerRow), row.get(), srcBytesPerRow);
+    // Copy the bits from current renderTarget to the output target.
+    // We cannot access the data backing an IWICBitmap while an active draw session is open.
+    context->endDraw();
 
-        srcRows += srcBytesPerRow;
-    }
+    COMPtr<ID2D1DeviceContext> sourceDeviceContext;
+    HRESULT hr = platformContext->renderTarget()->QueryInterface(__uuidof(ID2D1DeviceContext), reinterpret_cast<void**>(&sourceDeviceContext));
+    ASSERT(SUCCEEDED(hr));
 
-    // Once we are done modifying the data, unlock the bitmap
-    bitmapDataLock = nullptr;
+    if (!sourceDeviceContext)
+        return nullptr;
 
+    COMPtr<ID2D1Bitmap1> sourceCPUBitmap;
+    D2D1_BITMAP_PROPERTIES1 bitmapProperties = D2D1::BitmapProperties1(D2D1_BITMAP_OPTIONS_CPU_READ | D2D1_BITMAP_OPTIONS_CANNOT_DRAW, Direct2D::pixelFormat());
+    hr = sourceDeviceContext->CreateBitmap(bitmap->GetPixelSize(), nullptr, bytesPerRow.unsafeGet(), bitmapProperties, &sourceCPUBitmap);
+    if (!SUCCEEDED(hr))
+        return nullptr;
+
+    if (!sourceCPUBitmap)
+        return nullptr;
+
+    hr = sourceCPUBitmap->CopyFromBitmap(nullptr, bitmap.get(), nullptr);
+    if (!SUCCEEDED(hr))
+        return nullptr;
+
+    D2D1_MAPPED_RECT mappedSourceData;
+    hr = sourceCPUBitmap->Map(D2D1_MAP_OPTIONS_READ, &mappedSourceData);
+    if (!SUCCEEDED(hr))
+        return nullptr;
+
+    COMPtr<ID2D1DeviceContext> targetDeviceContext;
+    hr = renderTarget->QueryInterface(__uuidof(ID2D1DeviceContext), reinterpret_cast<void**>(&targetDeviceContext));
+    ASSERT(SUCCEEDED(hr));
+
+    COMPtr<ID2D1Bitmap> compatibleBitmap;
+    hr = targetDeviceContext->CreateBitmap(bitmap->GetPixelSize(), mappedSourceData.bits, mappedSourceData.pitch, Direct2D::bitmapProperties(), &compatibleBitmap);
+    if (!SUCCEEDED(hr))
+        return nullptr;
+
+    hr = sourceCPUBitmap->Unmap();
+    ASSERT(SUCCEEDED(hr));
+
     context->beginDraw();
+
+    return compatibleBitmap;
 }
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/platform/graphics/win/ImageBufferDataDirect2D.h (249109 => 249110)


--- trunk/Source/WebCore/platform/graphics/win/ImageBufferDataDirect2D.h	2019-08-26 18:58:00 UTC (rev 249109)
+++ trunk/Source/WebCore/platform/graphics/win/ImageBufferDataDirect2D.h	2019-08-26 19:08:57 UTC (rev 249110)
@@ -32,6 +32,9 @@
 #include <wtf/RefPtr.h>
 #include <wtf/RetainPtr.h>
 
+interface ID2D1RenderTarget;
+interface ID2D1Bitmap;
+
 namespace WebCore {
 
 class PlatformContextDirect2D;
@@ -44,10 +47,12 @@
     Vector<char> data;
     std::unique_ptr<PlatformContextDirect2D> platformContext;
     std::unique_ptr<GraphicsContext> context;
-    COMPtr<IWICBitmap> bitmapSource;
+    COMPtr<ID2D1Bitmap> bitmap;
 
     RefPtr<Uint8ClampedArray> getData(AlphaPremultiplication, const IntRect&, const IntSize&, bool accelerateRendering, float resolutionScale) const;
     void putData(const Uint8ClampedArray& source, AlphaPremultiplication sourceFormat, const IntSize& sourceSize, const IntRect& sourceRect, const IntPoint& destPoint, const IntSize&, bool accelerateRendering, float resolutionScale);
+
+    COMPtr<ID2D1Bitmap> compatibleBitmap(ID2D1RenderTarget*);
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/platform/graphics/win/ImageBufferDirect2D.cpp (249109 => 249110)


--- trunk/Source/WebCore/platform/graphics/win/ImageBufferDirect2D.cpp	2019-08-26 18:58:00 UTC (rev 249109)
+++ trunk/Source/WebCore/platform/graphics/win/ImageBufferDirect2D.cpp	2019-08-26 19:08:57 UTC (rev 249110)
@@ -38,7 +38,7 @@
 #include "MIMETypeRegistry.h"
 #include "NotImplemented.h"
 #include "PlatformContextDirect2D.h"
-#include <d2d1.h>
+#include <d2d1_1.h>
 #include <math.h>
 #include <wincodec.h>
 #include <wtf/Assertions.h>
@@ -76,7 +76,7 @@
     return buffer;
 }
 
-ImageBuffer::ImageBuffer(const FloatSize& size, float resolutionScale, ColorSpace /*colorSpace*/, RenderingMode renderingMode, const HostWindow*, const GraphicsContext*, bool& success)
+ImageBuffer::ImageBuffer(const FloatSize& size, float resolutionScale, ColorSpace /*colorSpace*/, RenderingMode renderingMode, const HostWindow*, const GraphicsContext* targetContext, bool& success)
     : m_logicalSize(size)
     , m_resolutionScale(resolutionScale)
 {
@@ -101,17 +101,23 @@
     if (numBytes.hasOverflowed())
         return;
 
-    m_data.data = "" 0);
+    auto* platformContext = targetContext ? targetContext->platformContext() : nullptr;
+    auto* renderTarget = platformContext ? platformContext->renderTarget() : nullptr;
 
-    m_data.bitmapSource = Direct2D::createDirect2DImageSurfaceWithData(m_data.data.data(), m_size, m_data.bytesPerRow.unsafeGet());
-    if (!m_data.bitmapSource)
-        return;
+    if (!renderTarget)
+        renderTarget = GraphicsContext::defaultRenderTarget();
 
-    COMPtr<ID2D1RenderTarget> bitmapContext = Direct2D::createRenderTargetFromWICBitmap(m_data.bitmapSource.get());
+    D2D1_SIZE_F desiredSize = FloatSize(m_logicalSize);
+    D2D1_SIZE_U pixelSize = IntSize(m_logicalSize);
+
+    auto bitmapContext = Direct2D::createBitmapRenderTargetOfSize(m_logicalSize, renderTarget);
     if (!bitmapContext)
         return;
 
-    // Note: This places the bitmapcontext into a locked state because of the BeginDraw call in the constructor.
+    HRESULT hr = bitmapContext->GetBitmap(&m_data.bitmap);
+    if (!SUCCEEDED(hr))
+        return;
+
     m_data.platformContext = makeUnique<PlatformContextDirect2D>(bitmapContext.get());
     m_data.context = makeUnique<GraphicsContext>(m_data.platformContext.get(), GraphicsContext::BitmapRenderingContextType::GPUMemory);
 
@@ -140,24 +146,17 @@
     context().flush();
 }
 
-static COMPtr<IWICBitmap> createCroppedImageIfNecessary(IWICBitmap* image, const IntSize& bounds)
+static COMPtr<ID2D1Bitmap> createCroppedImageIfNecessary(ID2D1BitmapRenderTarget* bitmapTarget, ID2D1Bitmap* image, const IntSize& bounds)
 {
     FloatSize imageSize = image ? nativeImageSize(image) : FloatSize();
 
     if (image && (static_cast<size_t>(imageSize.width()) != static_cast<size_t>(bounds.width()) || static_cast<size_t>(imageSize.height()) != static_cast<size_t>(bounds.height()))) {
-        D2D_POINT_2U origin = { };
-        WICRect croppedDimensions = { 0, 0, bounds.width(), bounds.height() };
-
-        COMPtr<IWICBitmapClipper> bitmapClipper;
-        HRESULT hr = ImageDecoderDirect2D::systemImagingFactory()->CreateBitmapClipper(&bitmapClipper);
-        if (SUCCEEDED(hr)) {
-            hr = bitmapClipper->Initialize(image, &croppedDimensions);
-            if (SUCCEEDED(hr)) {
-                COMPtr<IWICBitmap> croppedBitmap;
-                hr = ImageDecoderDirect2D::systemImagingFactory()->CreateBitmapFromSource(image, WICBitmapNoCache, &croppedBitmap);
-                if (SUCCEEDED(hr))
-                    return croppedBitmap;
-            }
+        COMPtr<ID2D1Bitmap> croppedBitmap = Direct2D::createBitmap(bitmapTarget, bounds);
+        if (croppedBitmap) {
+            auto sourceRect = D2D1::RectU(0, 0, bounds.width(), bounds.height());
+            HRESULT hr = croppedBitmap->CopyFromBitmap(nullptr, image, &sourceRect);
+            if (SUCCEEDED(hr))
+                return croppedBitmap;
         }
     }
 
@@ -164,10 +163,10 @@
     return image;
 }
 
-static RefPtr<Image> createBitmapImageAfterScalingIfNeeded(COMPtr<IWICBitmap>&& image, IntSize internalSize, IntSize logicalSize, IntSize backingStoreSize, float resolutionScale, PreserveResolution preserveResolution)
+static RefPtr<Image> createBitmapImageAfterScalingIfNeeded(ID2D1BitmapRenderTarget* bitmapTarget, COMPtr<ID2D1Bitmap>&& image, IntSize internalSize, IntSize logicalSize, IntSize backingStoreSize, float resolutionScale, PreserveResolution preserveResolution)
 {
     if (resolutionScale == 1 || preserveResolution == PreserveResolution::Yes)
-        image = createCroppedImageIfNecessary(image.get(), internalSize);
+        image = createCroppedImageIfNecessary(bitmapTarget, image.get(), internalSize);
     else {
         // FIXME: Need to implement scaled version
         notImplemented();
@@ -181,13 +180,14 @@
 
 RefPtr<Image> ImageBuffer::copyImage(BackingStoreCopy copyBehavior, PreserveResolution preserveResolution) const
 {
-    COMPtr<IWICBitmap> image;
+    COMPtr<ID2D1Bitmap> image;
     if (m_resolutionScale == 1 || preserveResolution == PreserveResolution::Yes)
         image = copyNativeImage(copyBehavior);
     else
         image = copyNativeImage(DontCopyBackingStore);
 
-    return createBitmapImageAfterScalingIfNeeded(WTFMove(image), internalSize(), logicalSize(), m_data.backingStoreSize, m_resolutionScale, preserveResolution);
+    auto bitmapTarget = reinterpret_cast<ID2D1BitmapRenderTarget*>(context().platformContext());
+    return createBitmapImageAfterScalingIfNeeded(bitmapTarget, WTFMove(image), internalSize(), logicalSize(), m_data.backingStoreSize, m_resolutionScale, preserveResolution);
 }
 
 RefPtr<Image> ImageBuffer::sinkIntoImage(std::unique_ptr<ImageBuffer> imageBuffer, PreserveResolution preserveResolution)
@@ -197,7 +197,8 @@
     IntSize backingStoreSize = imageBuffer->m_data.backingStoreSize;
     float resolutionScale = imageBuffer->m_resolutionScale;
 
-    return createBitmapImageAfterScalingIfNeeded(sinkIntoNativeImage(WTFMove(imageBuffer)), internalSize, logicalSize, backingStoreSize, resolutionScale, preserveResolution);
+    auto bitmapTarget = reinterpret_cast<ID2D1BitmapRenderTarget*>(imageBuffer->context().platformContext()->renderTarget());
+    return createBitmapImageAfterScalingIfNeeded(bitmapTarget, sinkIntoNativeImage(WTFMove(imageBuffer)), internalSize, logicalSize, backingStoreSize, resolutionScale, preserveResolution);
 }
 
 BackingStoreCopy ImageBuffer::fastCopyImageMode()
@@ -205,14 +206,20 @@
     return DontCopyBackingStore;
 }
 
-COMPtr<IWICBitmap> ImageBuffer::sinkIntoNativeImage(std::unique_ptr<ImageBuffer> imageBuffer)
+COMPtr<ID2D1Bitmap> ImageBuffer::sinkIntoNativeImage(std::unique_ptr<ImageBuffer> imageBuffer)
 {
     // FIXME: See if we can reuse the on-hardware image.
     return imageBuffer->copyNativeImage(DontCopyBackingStore);
 }
 
-COMPtr<IWICBitmap> ImageBuffer::copyNativeImage(BackingStoreCopy copyBehavior) const
+COMPtr<ID2D1Bitmap> ImageBuffer::copyNativeImage(BackingStoreCopy copyBehavior) const
 {
+    auto bitmapTarget = reinterpret_cast<ID2D1BitmapRenderTarget*>(context().platformContext());
+
+    COMPtr<ID2D1Bitmap> image;
+    HRESULT hr = bitmapTarget->GetBitmap(&image);
+    ASSERT(SUCCEEDED(hr));
+
     // FIXME: m_data.data is nullptr even when asking to copy backing store leading to test failures.
     if (copyBehavior == CopyBackingStore && m_data.data.isEmpty())
         copyBehavior = DontCopyBackingStore;
@@ -221,15 +228,13 @@
     if (numBytes.hasOverflowed())
         return nullptr;
 
-    HRESULT hr = S_OK;
-    COMPtr<IWICBitmap> image;
     if (!context().isAcceleratedContext()) {
         switch (copyBehavior) {
         case DontCopyBackingStore:
-            hr = ImageDecoderDirect2D::systemImagingFactory()->CreateBitmapFromSource(m_data.bitmapSource.get(), WICBitmapNoCache, &image);
             break;
         case CopyBackingStore:
-            hr = ImageDecoderDirect2D::systemImagingFactory()->CreateBitmapFromSource(m_data.bitmapSource.get(), WICBitmapCacheOnDemand, &image);
+            D2D1_RECT_U backingStoreDimenstions = IntRect(IntPoint(), m_data.backingStoreSize);
+            image->CopyFromMemory(&backingStoreDimenstions, m_data.data.data(), 32);
             break;
         default:
             ASSERT_NOT_REACHED();
@@ -254,16 +259,13 @@
     FloatRect adjustedSrcRect = srcRect;
     adjustedSrcRect.scale(m_resolutionScale, m_resolutionScale);
 
-    FloatSize currentImageSize = nativeImageSize(m_data.bitmapSource);
+    auto compatibleBitmap = m_data.compatibleBitmap(destContext.platformContext()->renderTarget());
 
-    // You can't convert a IWICBitmap to a ID2D1Bitmap with an active GraphicsContext attached to it.
-    m_data.context->endDraw();
+    FloatSize currentImageSize = nativeImageSize(compatibleBitmap);
+    if (currentImageSize.isZero())
+        return;
 
-    destContext.drawNativeImage(m_data.bitmapSource, currentImageSize, destRect, adjustedSrcRect, op, blendMode);
-
-    m_data.context->beginDraw();
-
-    destContext.flush();
+    destContext.drawNativeImage(compatibleBitmap, currentImageSize, destRect, adjustedSrcRect, op, blendMode);
 }
 
 void ImageBuffer::drawPattern(GraphicsContext& destContext, const FloatRect& destRect, const FloatRect& srcRect, const AffineTransform& patternTransform, const FloatPoint& phase, const FloatSize& spacing, CompositeOperator op, BlendMode blendMode)

Modified: trunk/Source/WebCore/platform/graphics/win/ImageDecoderDirect2D.cpp (249109 => 249110)


--- trunk/Source/WebCore/platform/graphics/win/ImageDecoderDirect2D.cpp	2019-08-26 18:58:00 UTC (rev 249109)
+++ trunk/Source/WebCore/platform/graphics/win/ImageDecoderDirect2D.cpp	2019-08-26 19:08:57 UTC (rev 249110)
@@ -239,6 +239,9 @@
     if (!m_nativeDecoder)
         return nullptr;
 
+    if (!m_renderTarget)
+        return nullptr;
+
     COMPtr<IWICBitmapFrameDecode> frame;
     HRESULT hr = m_nativeDecoder->GetFrame(0, &frame);
     if (!SUCCEEDED(hr))
@@ -253,11 +256,16 @@
     if (!SUCCEEDED(hr))
         return nullptr;
 
-    COMPtr<IWICBitmap> bitmap;
-    hr = systemImagingFactory()->CreateBitmapFromSource(converter.get(), WICBitmapCacheOnDemand, &bitmap);
+    COMPtr<IWICBitmap> wicBitmap;
+    hr = systemImagingFactory()->CreateBitmapFromSource(converter.get(), WICBitmapCacheOnDemand, &wicBitmap);
     if (!SUCCEEDED(hr))
         return nullptr;
 
+    COMPtr<ID2D1Bitmap> bitmap;
+    hr = m_renderTarget->CreateBitmapFromWicBitmap(wicBitmap.get(), &bitmap);
+    if (!SUCCEEDED(hr))
+        return nullptr;
+
     return bitmap;
 }
 
@@ -286,6 +294,7 @@
 
     // Image was valid.
 }
+
 }
 
 #endif

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


--- trunk/Source/WebCore/platform/graphics/win/NativeImageDirect2D.cpp	2019-08-26 18:58:00 UTC (rev 249109)
+++ trunk/Source/WebCore/platform/graphics/win/NativeImageDirect2D.cpp	2019-08-26 19:08:57 UTC (rev 249110)
@@ -56,11 +56,7 @@
     if (!image)
         return { };
 
-    HRESULT hr = image->GetSize(&width, &height);
-    if (!SUCCEEDED(hr))
-        return { };
-
-    return IntSize(width, height);
+    return image->GetPixelSize();
 }
 
 bool nativeImageHasAlpha(const NativeImagePtr& image)
@@ -68,28 +64,8 @@
     if (!image)
         return false;
 
-    WICPixelFormatGUID pixelFormatGUID = { };
-    HRESULT hr = image->GetPixelFormat(&pixelFormatGUID);
-    if (!SUCCEEDED(hr))
-        return false;
-
-    // FIXME: Should we just check the pixelFormatGUID for relevant ID's we use?
-
-    COMPtr<IWICComponentInfo> componentInfo;
-    hr = imagingFactory()->CreateComponentInfo(pixelFormatGUID, &componentInfo);
-    if (!SUCCEEDED(hr))
-        return false;
-
-    COMPtr<IWICPixelFormatInfo> pixelFormatInfo(Query, componentInfo.get());
-    if (!pixelFormatInfo)
-        return false;
-
-    UINT channelCount = 0;
-    hr = pixelFormatInfo->GetChannelCount(&channelCount);
-    if (!SUCCEEDED(hr))
-        return false;
-
-    return channelCount > 3;
+    D2D1_PIXEL_FORMAT pixelFormat = image->GetPixelFormat();
+    return pixelFormat.alphaMode != D2D1_ALPHA_MODE_IGNORE;
 }
 
 Color nativeImageSinglePixelSolidColor(const NativeImagePtr& image)
@@ -116,13 +92,7 @@
 
     float opacity = 1.0f;
 
-    COMPtr<ID2D1Bitmap> bitmap;
-    HRESULT hr = platformContext->renderTarget()->CreateBitmapFromWicBitmap(image.get(), &bitmap);
-    if (!SUCCEEDED(hr))
-        return;
-
-    platformContext->renderTarget()->DrawBitmap(bitmap.get(), destRect, opacity, D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR, adjustedSrcRect);
-    context.flush();
+    platformContext->renderTarget()->DrawBitmap(image.get(), destRect, opacity, D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR, adjustedSrcRect);
 }
 
 void clearNativeImageSubimages(const NativeImagePtr& image)

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


--- trunk/Source/WebCore/platform/graphics/win/PatternDirect2D.cpp	2019-08-26 18:58:00 UTC (rev 249109)
+++ trunk/Source/WebCore/platform/graphics/win/PatternDirect2D.cpp	2019-08-26 19:08:57 UTC (rev 249110)
@@ -59,13 +59,8 @@
     auto& patternImage = tileImage();
     auto nativeImage = patternImage.nativeImage(nullptr);
 
-    COMPtr<ID2D1Bitmap> bitmap;
-    HRESULT hr = context.renderTarget()->CreateBitmapFromWicBitmap(nativeImage.get(), &bitmap);
-    if (!SUCCEEDED(hr))
-        return nullptr;
-
     ID2D1BitmapBrush* patternBrush = nullptr;
-    hr = context.renderTarget()->CreateBitmapBrush(bitmap.get(), &bitmapBrushProperties, &brushProperties, &patternBrush);
+    HRESULT hr = context.renderTarget()->CreateBitmapBrush(nativeImage.get(), &bitmapBrushProperties, &brushProperties, &patternBrush);
     ASSERT(SUCCEEDED(hr));
     return patternBrush;
 }

Modified: trunk/Source/WebCore/svg/graphics/SVGImage.cpp (249109 => 249110)


--- trunk/Source/WebCore/svg/graphics/SVGImage.cpp	2019-08-26 18:58:00 UTC (rev 249109)
+++ trunk/Source/WebCore/svg/graphics/SVGImage.cpp	2019-08-26 19:08:57 UTC (rev 249110)
@@ -69,6 +69,7 @@
 #if USE(DIRECT2D)
 #include "COMPtr.h"
 #include "Direct2DUtilities.h"
+#include "GraphicsContext.h"
 #include "ImageDecoderDirect2D.h"
 #include "PlatformContextDirect2D.h"
 #include <d2d1.h>
@@ -235,12 +236,11 @@
     if (!m_page || !targetContext)
         return nullptr;
 
-    COMPtr<IWICBitmap> nativeImage;
-    HRESULT hr = ImageDecoderDirect2D::systemImagingFactory()->CreateBitmap(rect().width(), rect().height(), GUID_WICPixelFormat32bppPRGBA, WICBitmapCacheOnLoad, &nativeImage);
-    if (!SUCCEEDED(hr))
-        return nullptr;
+    ASSERT(targetContext->hasPlatformContext());
+    auto* renderTarget = targetContext->platformContext()->renderTarget();
 
-    COMPtr<ID2D1RenderTarget> nativeImageTarget = Direct2D::createRenderTargetFromWICBitmap(nativeImage.get());
+    IntSize bitmapSize(size().width(), size().height());
+    auto nativeImageTarget = Direct2D::createBitmapRenderTargetOfSize(bitmapSize, renderTarget, 1.0);
     if (!nativeImageTarget)
         return nullptr;
 
@@ -249,6 +249,17 @@
 
     draw(localContext, rect(), rect(), CompositeSourceOver, BlendMode::Normal, DecodingMode::Synchronous, ImageOrientation::None);
 
+    COMPtr<ID2D1Bitmap> nativeImage;
+    HRESULT hr = nativeImageTarget->GetBitmap(&nativeImage);
+    if (!SUCCEEDED(hr))
+        return nullptr;
+
+#if !ASSERT_DISABLED
+    auto nativeImageSize = nativeImage->GetPixelSize();
+    ASSERT(nativeImageSize.height = rect().size().height());
+    ASSERT(nativeImageSize.width = rect().size().width());
+#endif
+
     return nativeImage;
 }
 #endif

Modified: trunk/Source/WebKit/ChangeLog (249109 => 249110)


--- trunk/Source/WebKit/ChangeLog	2019-08-26 18:58:00 UTC (rev 249109)
+++ trunk/Source/WebKit/ChangeLog	2019-08-26 19:08:57 UTC (rev 249110)
@@ -1,3 +1,28 @@
+2019-08-26  Brent Fulgham  <bfulg...@apple.com>
+
+        [FTW] Go back to ID2D1Bitmap as our NativeImage type
+        https://bugs.webkit.org/show_bug.cgi?id=201122
+
+        Reviewed by Alex Christensen.
+
+        In Bug 200093 I switched the OS type of NativeImagePtr from ID2D1Bitmap to IWICBitmap.
+        However, this was an ill-advised approach, because it dramatically harmed performance due
+        to the heavy use of software rendering.
+
+        I originally made this change because I thought this was the only way to get to the backing
+        bits of the bitmaps, but it turns out that a more recent Direct2D data type (ID2D1Bitmap1)
+        has the ability to map its memory to CPU-accessible memory, allowing software filter effects.
+
+        This patch switches back to the ID2D1Bitap data type, and hooks up the ID2D1Bitmap1 data type
+        to access the underlying memory of the bitmaps when software filter effects are used.
+
+        Reviewed by Alex Christensen.
+
+        * Shared/ShareableBitmap.h:
+        * Shared/win/ShareableBitmapDirect2D.cpp:
+        * UIProcess/win/BackingStoreDirect2D.cpp:
+        * WebProcess/WebPage/CoordinatedGraphics/DrawingAreaCoordinatedGraphics.cpp:
+
 2019-08-26  Jiewen Tan  <jiewen_...@apple.com>
 
         [WebAuthn] Support HID authenticators on iOS

Modified: trunk/Source/WebKit/Shared/ShareableBitmap.h (249109 => 249110)


--- trunk/Source/WebKit/Shared/ShareableBitmap.h	2019-08-26 18:58:00 UTC (rev 249109)
+++ trunk/Source/WebKit/Shared/ShareableBitmap.h	2019-08-26 19:08:57 UTC (rev 249110)
@@ -40,7 +40,8 @@
 #endif
 
 #if USE(DIRECT2D)
-interface IWICBitmap;
+interface ID2D1Bitmap;
+interface ID2D1RenderTarget;
 
 #include <WebCore/COMPtr.h>
 #endif
@@ -131,7 +132,7 @@
     // This is only safe to use when we know that the contents of the shareable bitmap won't change.
     RefPtr<cairo_surface_t> createCairoSurface();
 #elif USE(DIRECT2D)
-    COMPtr<IWICBitmap> createDirect2DSurface();
+    COMPtr<ID2D1Bitmap> createDirect2DSurface(ID2D1RenderTarget*);
     void sync(WebCore::GraphicsContext&);
 #endif
 
@@ -162,7 +163,7 @@
     Configuration m_configuration;
 
 #if USE(DIRECT2D)
-    COMPtr<IWICBitmap> m_bitmap;
+    COMPtr<ID2D1Bitmap> m_bitmap;
 #endif
 
     // If the shareable bitmap is backed by shared memory, this points to the shared memory object.
@@ -169,7 +170,7 @@
     RefPtr<SharedMemory> m_sharedMemory;
 
     // If the shareable bitmap is backed by fastMalloced memory, this points to the data.
-    void* m_data;
+    void* m_data { nullptr };
 };
 
 } // namespace WebKit

Modified: trunk/Source/WebKit/Shared/win/ShareableBitmapDirect2D.cpp (249109 => 249110)


--- trunk/Source/WebKit/Shared/win/ShareableBitmapDirect2D.cpp	2019-08-26 18:58:00 UTC (rev 249109)
+++ trunk/Source/WebKit/Shared/win/ShareableBitmapDirect2D.cpp	2019-08-26 19:08:57 UTC (rev 249110)
@@ -35,6 +35,7 @@
 #include <WebCore/GraphicsContextImplDirect2D.h>
 #include <WebCore/NotImplemented.h>
 #include <WebCore/PlatformContextDirect2D.h>
+#include <d2d1_1.h>
 #include <wincodec.h>
 #include <wtf/ProcessID.h>
 
@@ -42,11 +43,9 @@
 namespace WebKit {
 using namespace WebCore;
 
-static const auto bitmapFormat = GUID_WICPixelFormat32bppPBGRA;
-
 static unsigned strideForWidth(unsigned width)
 {
-    static unsigned bitsPerPixel = Direct2D::bitsPerPixel(bitmapFormat);
+    static unsigned bitsPerPixel = Direct2D::bitsPerPixel(Direct2D::wicBitmapFormat());
     return bitsPerPixel * width / 8;
 }
 
@@ -68,8 +67,12 @@
 
 std::unique_ptr<GraphicsContext> ShareableBitmap::createGraphicsContext()
 {
-    m_bitmap = createDirect2DSurface();
-    COMPtr<ID2D1RenderTarget> bitmapContext = Direct2D::createRenderTargetFromWICBitmap(m_bitmap.get());
+    auto bitmapContext = Direct2D::createBitmapRenderTargetOfSize(m_size);
+    if (!bitmapContext)
+        return nullptr;
+
+    HRESULT hr = bitmapContext->GetBitmap(&m_bitmap);
+    RELEASE_ASSERT(SUCCEEDED(hr));
     return makeUnique<GraphicsContext>(GraphicsContextImplDirect2D::createFactory(bitmapContext.get()));
 }
 
@@ -80,13 +83,12 @@
 
 void ShareableBitmap::paint(GraphicsContext& context, float scaleFactor, const IntPoint& dstPoint, const IntRect& srcRect)
 {
-    auto surface = createDirect2DSurface();
+    auto surface = createDirect2DSurface(context.platformContext()->renderTarget());
 
 #ifndef _NDEBUG
-    unsigned width, height;
-    HRESULT hr = surface->GetSize(&width, &height);
-    ASSERT(width == m_size.width());
-    ASSERT(height == m_size.height());
+    auto bitmapSize = surface->GetPixelSize();
+    ASSERT(bitmapSize.width == m_size.width());
+    ASSERT(bitmapSize.height == m_size.height());
 #endif
 
     FloatRect destRect(dstPoint, srcRect.size());
@@ -100,15 +102,22 @@
     Direct2D::drawNativeImage(platformContext, surface.get(), m_size, destRect, srcRectScaled, state.compositeOperator, state.blendMode, ImageOrientation(), state.imageInterpolationQuality, state.alpha, Direct2D::ShadowState(state));
 }
 
-COMPtr<IWICBitmap> ShareableBitmap::createDirect2DSurface()
+COMPtr<ID2D1Bitmap> ShareableBitmap::createDirect2DSurface(ID2D1RenderTarget* renderTarget)
 {
-    m_bitmap = createSurfaceFromData(data(), m_size);
-    return m_bitmap;
+    auto bitmapProperties = Direct2D::bitmapProperties();
+
+    COMPtr<ID2D1Bitmap> bitmap;
+    uint32_t stride = 4 * m_size.width();
+    HRESULT hr = renderTarget->CreateBitmap(m_size, data(), stride, &bitmapProperties, &bitmap);
+    if (!SUCCEEDED(hr))
+        return nullptr;
+
+    return bitmap;
 }
 
 RefPtr<Image> ShareableBitmap::createImage()
 {
-    auto surface = createDirect2DSurface();
+    auto surface = createDirect2DSurface(GraphicsContext::defaultRenderTarget());
     if (!surface)
         return nullptr;
 
@@ -121,20 +130,50 @@
 
     graphicsContext.endDraw();
 
-    WICRect rcLock = { 0, 0, m_size.width(), m_size.height() };
+    COMPtr<ID2D1DeviceContext> d2dDeviceContext;
+    HRESULT hr = graphicsContext.platformContext()->renderTarget()->QueryInterface(__uuidof(ID2D1DeviceContext), reinterpret_cast<void**>(&d2dDeviceContext));
+    ASSERT(SUCCEEDED(hr));
 
-    COMPtr<IWICBitmapLock> bitmapDataLock;
-    HRESULT hr = m_bitmap->Lock(&rcLock, WICBitmapLockRead, &bitmapDataLock);
-    if (SUCCEEDED(hr)) {
-        UINT bufferSize = 0;
-        WICInProcPointer dataPtr = nullptr;
-        hr = bitmapDataLock->GetDataPointer(&bufferSize, &dataPtr);
-        if (SUCCEEDED(hr))
-            memcpy(data(), reinterpret_cast<char*>(dataPtr), bufferSize);
+    const unsigned stride = strideForWidth(m_size.width());
+
+    COMPtr<ID2D1Bitmap1> cpuBitmap;
+    D2D1_BITMAP_PROPERTIES1 bitmapProperties = D2D1::BitmapProperties1(D2D1_BITMAP_OPTIONS_CPU_READ | D2D1_BITMAP_OPTIONS_CANNOT_DRAW, Direct2D::pixelFormat());
+    hr = d2dDeviceContext->CreateBitmap(m_size, nullptr, stride, bitmapProperties, &cpuBitmap);
+    if (!SUCCEEDED(hr))
+        return;
+
+    hr = cpuBitmap->CopyFromBitmap(nullptr, m_bitmap.get(), nullptr);
+    if (!SUCCEEDED(hr))
+        return;
+
+    D2D1_MAPPED_RECT mappedData;
+    hr = cpuBitmap->Map(D2D1_MAP_OPTIONS_READ, &mappedData);
+    if (!SUCCEEDED(hr))
+        return;
+
+    if (mappedData.pitch == stride)
+        memcpy(data(), reinterpret_cast<char*>(mappedData.bits), stride * m_size.height());
+    else {
+        // Stride is different, so must do a rowwise copy:
+        Checked<int> height = m_size.height();
+        Checked<int> width = m_size.width();
+
+        const uint8_t* srcRows = mappedData.bits;
+        uint8_t* row = reinterpret_cast<uint8_t*>(data());
+
+        for (int y = 0; y < height.unsafeGet(); ++y) {
+            for (int x = 0; x < width.unsafeGet(); x++) {
+                int basex = x * 4;
+                reinterpret_cast<uint32_t*>(row + basex)[0] = reinterpret_cast<const uint32_t*>(srcRows + basex)[0];
+            }
+
+            srcRows += mappedData.pitch;
+            row += stride;
+        }
     }
 
-    // Once we are done modifying the data, unlock the bitmap
-    bitmapDataLock = nullptr;
+    hr = cpuBitmap->Unmap();
+    ASSERT(SUCCEEDED(hr));
 }
 
 } // namespace WebKit

Modified: trunk/Source/WebKit/UIProcess/win/BackingStoreDirect2D.cpp (249109 => 249110)


--- trunk/Source/WebKit/UIProcess/win/BackingStoreDirect2D.cpp	2019-08-26 18:58:00 UTC (rev 249109)
+++ trunk/Source/WebKit/UIProcess/win/BackingStoreDirect2D.cpp	2019-08-26 19:08:57 UTC (rev 249110)
@@ -73,22 +73,9 @@
 
     IntPoint updateRectBoundsLocation = updateInfo.updateRectBounds.location();
 
-    auto updateWICBitmap = bitmap->createDirect2DSurface();
+    COMPtr<ID2D1Bitmap> deviceUpdateBitmap = bitmap->createDirect2DSurface(m_backend->renderTarget());
 
-    HRESULT hr = S_OK;
 #ifndef _NDEBUG
-    unsigned width, height;
-    hr = updateWICBitmap->GetSize(&width, &height);
-    ASSERT(width == updateInfo.updateRectBounds.width());
-    ASSERT(height == updateInfo.updateRectBounds.height());
-#endif
-
-    COMPtr<ID2D1Bitmap> deviceUpdateBitmap;
-    hr = m_backend->renderTarget()->CreateBitmapFromWicBitmap(updateWICBitmap.get(), &deviceUpdateBitmap);
-    if (!SUCCEEDED(hr))
-        return;
-
-#ifndef _NDEBUG
     auto deviceBitmapSize = deviceUpdateBitmap->GetPixelSize();
     ASSERT(deviceBitmapSize.width == updateInfo.updateRectBounds.width());
     ASSERT(deviceBitmapSize.height == updateInfo.updateRectBounds.height());

Modified: trunk/Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/DrawingAreaCoordinatedGraphics.cpp (249109 => 249110)


--- trunk/Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/DrawingAreaCoordinatedGraphics.cpp	2019-08-26 18:58:00 UTC (rev 249109)
+++ trunk/Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/DrawingAreaCoordinatedGraphics.cpp	2019-08-26 19:08:57 UTC (rev 249110)
@@ -754,7 +754,8 @@
     }
 
 #if USE(DIRECT2D)
-    bitmap->sync(*graphicsContext);
+    if (graphicsContext)
+        bitmap->sync(*graphicsContext);
 #endif
 
     // Layout can trigger more calls to setNeedsDisplay and we don't want to process them
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to