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