Changeset 249110 in webkit
- Timestamp:
- Aug 26, 2019, 12:08:57 PM (7 years ago)
- Location:
- trunk/Source
- Files:
-
- 23 edited
-
WebCore/ChangeLog (modified) (1 diff)
-
WebCore/platform/graphics/Image.cpp (modified) (1 diff)
-
WebCore/platform/graphics/ImageBuffer.h (modified) (1 diff)
-
WebCore/platform/graphics/NativeImage.h (modified) (1 diff)
-
WebCore/platform/graphics/texmap/BitmapTextureGL.cpp (modified) (1 diff)
-
WebCore/platform/graphics/win/Direct2DOperations.cpp (modified) (10 diffs)
-
WebCore/platform/graphics/win/Direct2DOperations.h (modified) (2 diffs)
-
WebCore/platform/graphics/win/Direct2DUtilities.cpp (modified) (7 diffs)
-
WebCore/platform/graphics/win/Direct2DUtilities.h (modified) (3 diffs)
-
WebCore/platform/graphics/win/GraphicsContextDirect2D.cpp (modified) (7 diffs)
-
WebCore/platform/graphics/win/GraphicsContextImplDirect2D.cpp (modified) (2 diffs)
-
WebCore/platform/graphics/win/ImageBufferDataDirect2D.cpp (modified) (4 diffs)
-
WebCore/platform/graphics/win/ImageBufferDataDirect2D.h (modified) (2 diffs)
-
WebCore/platform/graphics/win/ImageBufferDirect2D.cpp (modified) (12 diffs)
-
WebCore/platform/graphics/win/ImageDecoderDirect2D.cpp (modified) (3 diffs)
-
WebCore/platform/graphics/win/NativeImageDirect2D.cpp (modified) (3 diffs)
-
WebCore/platform/graphics/win/PatternDirect2D.cpp (modified) (1 diff)
-
WebCore/svg/graphics/SVGImage.cpp (modified) (3 diffs)
-
WebKit/ChangeLog (modified) (1 diff)
-
WebKit/Shared/ShareableBitmap.h (modified) (4 diffs)
-
WebKit/Shared/win/ShareableBitmapDirect2D.cpp (modified) (6 diffs)
-
WebKit/UIProcess/win/BackingStoreDirect2D.cpp (modified) (1 diff)
-
WebKit/WebProcess/WebPage/CoordinatedGraphics/DrawingAreaCoordinatedGraphics.cpp (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r249109 r249110 1 2019-08-26 Brent Fulgham <bfulgham@apple.com> 2 3 [FTW] Go back to ID2D1Bitmap as our NativeImage type 4 https://bugs.webkit.org/show_bug.cgi?id=201122 5 6 Reviewed by Alex Christensen. 7 8 In Bug 200093 I switched the OS type of NativeImagePtr from ID2D1Bitmap to IWICBitmap. 9 However, this was an ill-advised approach, because it dramatically harmed performance due 10 to the heavy use of software rendering. 11 12 I originally made this change because I thought this was the only way to get to the backing 13 bits of the bitmaps, but it turns out that a more recent Direct2D data type (ID2D1Bitmap1) 14 has the ability to map its memory to CPU-accessible memory, allowing software filter effects. 15 16 This patch switches back to the ID2D1Bitap data type, and hooks up the ID2D1Bitmap1 data type 17 to access the underlying memory of the bitmaps when software filter effects are used. 18 19 * platform/graphics/ImageBuffer.h: 20 * platform/graphics/NativeImage.h: 21 * platform/graphics/texmap/BitmapTextureGL.cpp: 22 * platform/graphics/win/Direct2DOperations.cpp: 23 * platform/graphics/win/Direct2DOperations.h: 24 * platform/graphics/win/Direct2DUtilities.cpp: 25 (WebCore::Direct2D::writeDiagnosticPNGToPath): 26 (WebCore::Direct2D::writeImageToDiskAsPNG): Deleted. 27 * platform/graphics/win/Direct2DUtilities.h: 28 * platform/graphics/win/GraphicsContextDirect2D.cpp: 29 * platform/graphics/win/ImageBufferDataDirect2D.cpp: 30 * platform/graphics/win/ImageBufferDataDirect2D.h: 31 * platform/graphics/win/ImageBufferDirect2D.cpp: 32 * platform/graphics/win/ImageDecoderDirect2D.cpp: 33 * platform/graphics/win/NativeImageDirect2D.cpp: 34 * platform/graphics/win/PatternDirect2D.cpp: 35 * svg/graphics/SVGImage.cpp: 36 1 37 2019-08-26 Sam Weinig <weinig@apple.com> 2 38 -
trunk/Source/WebCore/platform/graphics/Image.cpp
r248846 r249110 141 141 const FloatPoint& phase, const FloatSize& spacing, CompositeOperator op, BlendMode blendMode) 142 142 { 143 if (!nativeImageForCurrentFrame( ))143 if (!nativeImageForCurrentFrame(&ctxt)) 144 144 return; 145 145 -
trunk/Source/WebCore/platform/graphics/ImageBuffer.h
r249025 r249110 147 147 void flushContext() const; 148 148 #elif USE(DIRECT2D) 149 COMPtr<I WICBitmap> copyNativeImage(BackingStoreCopy = CopyBackingStore) const;150 static COMPtr<I WICBitmap> sinkIntoNativeImage(std::unique_ptr<ImageBuffer>);149 COMPtr<ID2D1Bitmap> copyNativeImage(BackingStoreCopy = CopyBackingStore) const; 150 static COMPtr<ID2D1Bitmap> sinkIntoNativeImage(std::unique_ptr<ImageBuffer>); 151 151 void flushContext() const; 152 152 #endif -
trunk/Source/WebCore/platform/graphics/NativeImage.h
r248657 r249110 56 56 typedef RetainPtr<CGImageRef> NativeImagePtr; 57 57 #elif USE(DIRECT2D) 58 typedef COMPtr<I WICBitmap> NativeImagePtr;58 typedef COMPtr<ID2D1Bitmap> NativeImagePtr; 59 59 #elif USE(CAIRO) 60 60 typedef RefPtr<cairo_surface_t> NativeImagePtr; -
trunk/Source/WebCore/platform/graphics/texmap/BitmapTextureGL.cpp
r247841 r249110 164 164 bytesPerLine = cairo_image_surface_get_stride(surface); 165 165 #elif USE(DIRECT2D) 166 // We can't access the bitmap's memory when it is in the middle of a BeginDraw/EndDraw 167 WICRect rcLock = { 0, 0, targetRect.width(), targetRect.height() }; 168 169 COMPtr<IWICBitmapLock> bitmapData; 170 HRESULT hr = frameImage->Lock(&rcLock, WICBitmapLockRead, &bitmapData); 171 if (!SUCCEEDED(hr)) 172 return; 173 174 UINT stride = 0; 175 hr = bitmapData->GetStride(&stride); 176 if (!SUCCEEDED(hr)) 177 return; 178 179 bytesPerLine = stride; 180 181 UINT bufferSize = 0; 182 WICInProcPointer dataPtr = nullptr; 183 hr = bitmapData->GetDataPointer(&bufferSize, &dataPtr); 184 if (!SUCCEEDED(hr)) 185 return; 186 187 imageData = reinterpret_cast<char*>(dataPtr); 166 notImplemented(); 188 167 #endif 189 168 -
trunk/Source/WebCore/platform/graphics/win/Direct2DOperations.cpp
r248907 r249110 529 529 drawWithoutShadow(platformContext, contextRect, drawFunction); 530 530 } 531 532 flush(platformContext);533 531 } 534 532 … … 555 553 drawWithoutShadow(platformContext, contextRect, drawFunction); 556 554 } 557 558 flush(platformContext);559 555 } 560 556 … … 589 585 else 590 586 drawWithoutShadow(platformContext, boundingRect, drawFunction); 591 592 flush(platformContext);593 587 } 594 588 … … 641 635 compositor->SetInput(1, bitmap); 642 636 643 // Flip the context644 D2D1_MATRIX_3X2_F ctm;645 deviceContext->GetTransform(&ctm);646 auto translate = D2D1::Matrix3x2F::Translation(0.0f, deviceContext->GetSize().height);647 auto flip = D2D1::Matrix3x2F::Scale(D2D1::SizeF(1.0f, -1.0f));648 deviceContext->SetTransform(ctm * flip * translate);649 650 637 deviceContext->DrawImage(compositor.get(), D2D1_INTERPOLATION_MODE_LINEAR); 651 638 } … … 656 643 657 644 // Render the current geometry to a bitmap context 658 COMPtr<ID2D1BitmapRenderTarget> bitmapTarget; 659 HRESULT hr = context->CreateCompatibleRenderTarget(&bitmapTarget); 660 RELEASE_ASSERT(SUCCEEDED(hr)); 645 COMPtr<ID2D1BitmapRenderTarget> bitmapTarget = createBitmapRenderTarget(context); 661 646 662 647 bitmapTarget->BeginDraw(); 663 648 drawCommands(bitmapTarget.get()); 664 hr = bitmapTarget->EndDraw();649 HRESULT hr = bitmapTarget->EndDraw(); 665 650 RELEASE_ASSERT(SUCCEEDED(hr)); 666 651 … … 837 822 drawWithoutShadow(platformContext, adjustedDestRect, drawFunction); 838 823 839 flush(platformContext);840 841 824 if (!stateSaver.didSave()) 842 825 context->SetTransform(ctm); 843 826 } 844 827 845 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)828 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) 846 829 { 847 830 auto context = platformContext.renderTarget(); … … 867 850 // this does not allocate new bitmap memory. 868 851 if (size.width() > destRect.width() || size.height() > destRect.height()) { 869 ASSERT(0);870 /*871 852 float dpiX = 0; 872 853 float dpiY = 0; … … 881 862 tileImage = subImage; 882 863 } 883 */ 884 } 885 886 COMPtr<ID2D1Bitmap> bitmap; 887 HRESULT hr = context->CreateBitmapFromWicBitmap(tileImage, nullptr, &bitmap); 888 if (!SUCCEEDED(hr)) 889 return; 864 } 890 865 891 866 COMPtr<ID2D1BitmapBrush> patternBrush; 892 hr = context->CreateBitmapBrush(bitmap.get(), &bitmapBrushProperties, &brushProperties, &patternBrush);867 HRESULT hr = context->CreateBitmapBrush(tileImage.get(), &bitmapBrushProperties, &brushProperties, &patternBrush); 893 868 ASSERT(SUCCEEDED(hr)); 894 869 if (!SUCCEEDED(hr)) … … 1110 1085 transparencyLayer.opacity = opacity; 1111 1086 1112 HRESULT hr = platformContext.renderTarget()->CreateCompatibleRenderTarget(&transparencyLayer.renderTarget);1113 RELEASE_ASSERT(SUCCEEDED(hr)); 1087 transparencyLayer.renderTarget = createBitmapRenderTarget(platformContext.renderTarget()); 1088 1114 1089 platformContext.m_transparencyLayerStack.append(WTFMove(transparencyLayer)); 1115 1090 … … 1223 1198 } 1224 1199 1200 1201 void copyBits(const uint8_t* srcRows, unsigned rowCount, unsigned colCount, unsigned srcStride, unsigned destStride, uint8_t* destRows) 1202 { 1203 for (unsigned y = 0; y < rowCount; ++y) { 1204 // Source data may be power-of-two sized, so we need to only copy the bits that 1205 // correspond to the rectangle supplied by the caller. 1206 const uint32_t* srcRow = reinterpret_cast<const uint32_t*>(srcRows + srcStride * y); 1207 uint32_t* destRow = reinterpret_cast<uint32_t*>(destRows + destStride * y); 1208 memcpy(destRow, srcRow, colCount); 1209 } 1210 } 1211 1225 1212 } // namespace Direct2D 1213 1226 1214 } // namespace WebCore 1227 1215 -
trunk/Source/WebCore/platform/graphics/win/Direct2DOperations.h
r248444 r249110 38 38 #include "GraphicsContext.h" 39 39 #include "GraphicsTypes.h" 40 #include <JavaScriptCore/Uint8ClampedArray.h> 40 41 #include <d2d1.h> 41 42 … … 131 132 void drawNativeImage(PlatformContextDirect2D&, ID2D1Bitmap*, const FloatSize& imageSize, const FloatRect&, const FloatRect&, CompositeOperator, BlendMode, ImageOrientation, InterpolationQuality, float, const ShadowState&); 132 133 void drawPath(PlatformContextDirect2D&, const Path&, const StrokeSource&, const ShadowState&); 133 void drawPattern(PlatformContextDirect2D&, IWICBitmap*, const IntSize&, const FloatRect&, const FloatRect&, const AffineTransform&, const FloatPoint&, CompositeOperator, BlendMode);134 void drawPattern(PlatformContextDirect2D&, COMPtr<ID2D1Bitmap>&&, const IntSize&, const FloatRect&, const FloatRect&, const AffineTransform&, const FloatPoint&, CompositeOperator, BlendMode); 134 135 135 136 void drawWithoutShadow(PlatformContextDirect2D&, const FloatRect& boundingRect, const WTF::Function<void(ID2D1RenderTarget*)>& drawCommands); -
trunk/Source/WebCore/platform/graphics/win/Direct2DUtilities.cpp
r248907 r249110 116 116 117 117 COMPtr<IWICBitmap> surface; 118 HRESULT hr = ImageDecoderDirect2D::systemImagingFactory()->CreateBitmapFromMemory(size.width(), size.height(), GUID_WICPixelFormat32bppPBGRA, stride, static_cast<UINT>(numBytes.unsafeGet()), reinterpret_cast<BYTE*>(data), &surface);118 HRESULT hr = ImageDecoderDirect2D::systemImagingFactory()->CreateBitmapFromMemory(size.width(), size.height(), wicBitmapFormat(), stride, static_cast<UINT>(numBytes.unsafeGet()), reinterpret_cast<BYTE*>(data), &surface); 119 119 if (!SUCCEEDED(hr)) 120 120 return nullptr; … … 126 126 { 127 127 COMPtr<IWICBitmap> surface; 128 HRESULT hr = ImageDecoderDirect2D::systemImagingFactory()->CreateBitmap(size.width(), size.height(), GUID_WICPixelFormat32bppPBGRA, WICBitmapCacheOnDemand, &surface);128 HRESULT hr = ImageDecoderDirect2D::systemImagingFactory()->CreateBitmap(size.width(), size.height(), wicBitmapFormat(), WICBitmapCacheOnDemand, &surface); 129 129 if (!SUCCEEDED(hr)) 130 130 return nullptr; … … 133 133 } 134 134 135 D2D1_PIXEL_FORMAT pixelFormatForSoftwareManipulation() 136 { 137 return D2D1::PixelFormat(DXGI_FORMAT_R8G8B8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED); 138 } 139 140 D2D1_PIXEL_FORMAT pixelFormat() 141 { 142 // 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 143 return D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED); 144 } 145 146 GUID wicBitmapFormat() 147 { 148 // This is the WIC format compatible with DXGI_FORMAT_B8G8R8A8_UNORM. It is also supposedly the most efficient in-memory 149 // representation for WIC images. 150 return GUID_WICPixelFormat32bppPBGRA; 151 } 152 153 D2D1_BITMAP_PROPERTIES bitmapProperties() 154 { 155 return D2D1::BitmapProperties(pixelFormat()); 156 } 157 135 158 COMPtr<ID2D1Bitmap> createBitmap(ID2D1RenderTarget* renderTarget, const IntSize& size) 136 159 { 137 auto bitmap Properties = D2D1::BitmapProperties(D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED));160 auto bitmapCreateProperties = bitmapProperties(); 138 161 139 162 COMPtr<ID2D1Bitmap> bitmap; 140 163 D2D1_SIZE_U bitmapSize = size; 141 HRESULT hr = renderTarget->CreateBitmap(bitmapSize, bitmap Properties, &bitmap);164 HRESULT hr = renderTarget->CreateBitmap(bitmapSize, bitmapCreateProperties, &bitmap); 142 165 if (!SUCCEEDED(hr)) 143 166 return nullptr; … … 146 169 } 147 170 171 D2D1_RENDER_TARGET_PROPERTIES renderTargetProperties() 172 { 173 return D2D1::RenderTargetProperties(D2D1_RENDER_TARGET_TYPE_DEFAULT, 174 pixelFormat(), 0, 0, D2D1_RENDER_TARGET_USAGE_GDI_COMPATIBLE, D2D1_FEATURE_LEVEL_DEFAULT); 175 } 176 148 177 COMPtr<ID2D1RenderTarget> createRenderTargetFromWICBitmap(IWICBitmap* bitmapSource) 149 178 { 150 auto targetProperties = D2D1::RenderTargetProperties(D2D1_RENDER_TARGET_TYPE_DEFAULT, 151 D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED), 152 0, 0, D2D1_RENDER_TARGET_USAGE_NONE, D2D1_FEATURE_LEVEL_DEFAULT); 179 auto targetProperties = renderTargetProperties(); 153 180 154 181 COMPtr<ID2D1RenderTarget> bitmapContext; … … 162 189 COMPtr<ID2D1DCRenderTarget> createGDIRenderTarget() 163 190 { 164 auto targetProperties = D2D1::RenderTargetProperties(D2D1_RENDER_TARGET_TYPE_DEFAULT, 165 D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED), 166 0, 0, D2D1_RENDER_TARGET_USAGE_GDI_COMPATIBLE, D2D1_FEATURE_LEVEL_DEFAULT); 191 auto targetProperties = renderTargetProperties(); 167 192 168 193 COMPtr<ID2D1DCRenderTarget> renderTarget; … … 174 199 } 175 200 201 COMPtr<ID2D1BitmapRenderTarget> createBitmapRenderTarget(ID2D1RenderTarget* renderTarget) 202 { 203 if (!renderTarget) 204 renderTarget = GraphicsContext::defaultRenderTarget(); 205 206 COMPtr<ID2D1BitmapRenderTarget> bitmapContext; 207 HRESULT hr = renderTarget->CreateCompatibleRenderTarget(nullptr, nullptr, nullptr, D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_GDI_COMPATIBLE, &bitmapContext); 208 if (!SUCCEEDED(hr)) 209 return nullptr; 210 211 return bitmapContext; 212 } 213 214 COMPtr<ID2D1BitmapRenderTarget> createBitmapRenderTargetOfSize(const IntSize& size, ID2D1RenderTarget* renderTarget, float deviceScaleFactor) 215 { 216 UNUSED_PARAM(deviceScaleFactor); 217 218 if (!renderTarget) 219 renderTarget = GraphicsContext::defaultRenderTarget(); 220 221 COMPtr<ID2D1BitmapRenderTarget> bitmapContext; 222 auto desiredSize = D2D1::SizeF(size.width(), size.height()); 223 D2D1_SIZE_U pixelSize = size; 224 HRESULT hr = renderTarget->CreateCompatibleRenderTarget(&desiredSize, &pixelSize, nullptr, D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_GDI_COMPATIBLE, &bitmapContext); 225 if (!SUCCEEDED(hr)) 226 return nullptr; 227 228 return bitmapContext; 229 } 230 176 231 void copyRectFromOneSurfaceToAnother(ID2D1Bitmap* from, ID2D1Bitmap* to, const IntSize& sourceOffset, const IntRect& rect, const IntSize& destOffset) 177 232 { … … 200 255 } 201 256 202 void write ImageToDiskAsPNG(ID2D1RenderTarget* renderTarget, ID2D1Bitmap* bitmap, LPCWSTR fileName)257 void writeDiagnosticPNGToPath(ID2D1RenderTarget* renderTarget, ID2D1Bitmap* bitmap, LPCWSTR fileName) 203 258 { 204 259 COMPtr<IWICBitmapEncoder> wicBitmapEncoder; -
trunk/Source/WebCore/platform/graphics/win/Direct2DUtilities.h
r248907 r249110 35 35 36 36 interface ID2D1Bitmap; 37 interface ID2D1BitmapRenderTarget; 37 38 interface ID2D1DCRenderTarget; 38 39 interface ID2D1RenderTarget; 39 40 interface IWICBitmapSource; 40 41 interface IWICBitmap; 42 43 struct D2D1_BITMAP_PROPERTIES; 44 struct D2D1_PIXEL_FORMAT; 45 struct D2D1_RENDER_TARGET_PROPERTIES; 41 46 42 47 namespace WebCore { … … 49 54 namespace Direct2D { 50 55 56 GUID wicBitmapFormat(); 57 D2D1_PIXEL_FORMAT pixelFormat(); // BGRA 58 D2D1_PIXEL_FORMAT pixelFormatForSoftwareManipulation(); // RGBA 59 D2D1_BITMAP_PROPERTIES bitmapProperties(); 60 D2D1_RENDER_TARGET_PROPERTIES renderTargetProperties(); 61 62 void inPlaceSwizzle(uint8_t* byteData, unsigned length, bool applyPremultiplication = false); 63 51 64 IntSize bitmapSize(IWICBitmapSource*); 52 65 FloatSize bitmapSize(ID2D1Bitmap*); … … 58 71 COMPtr<IWICBitmap> createDirect2DImageSurfaceWithData(void* data, const IntSize&, unsigned stride); 59 72 COMPtr<ID2D1RenderTarget> createRenderTargetFromWICBitmap(IWICBitmap*); 73 COMPtr<ID2D1BitmapRenderTarget> createBitmapRenderTargetOfSize(const IntSize&, ID2D1RenderTarget* = nullptr, float deviceScaleFactor = 1.0); 74 COMPtr<ID2D1BitmapRenderTarget> createBitmapRenderTarget(ID2D1RenderTarget* = nullptr); 60 75 COMPtr<ID2D1DCRenderTarget> createGDIRenderTarget(); 61 76 62 77 void copyRectFromOneSurfaceToAnother(ID2D1Bitmap* from, ID2D1Bitmap* to, const IntSize& sourceOffset, const IntRect&, const IntSize& destOffset = IntSize()); 63 78 64 void write ImageToDiskAsPNG(ID2D1RenderTarget*, ID2D1Bitmap*, LPCWSTR fileName);79 void writeDiagnosticPNGToPath(ID2D1RenderTarget*, ID2D1Bitmap*, LPCWSTR fileName); 65 80 66 81 } // namespace Direct2D -
trunk/Source/WebCore/platform/graphics/win/GraphicsContextDirect2D.cpp
r248846 r249110 29 29 #include "COMPtr.h" 30 30 #include "Direct2DOperations.h" 31 #include "Direct2DUtilities.h" 31 32 #include "DisplayListRecorder.h" 32 33 #include "FloatRoundedRect.h" … … 55 56 { 56 57 // Create a DC render target. 57 auto targetProperties = D2D1::RenderTargetProperties(D2D1_RENDER_TARGET_TYPE_DEFAULT, 58 D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED), 59 0, 0, D2D1_RENDER_TARGET_USAGE_NONE, D2D1_FEATURE_LEVEL_DEFAULT); 58 auto targetProperties = Direct2D::renderTargetProperties(); 60 59 61 60 HRESULT hr = GraphicsContext::systemFactory()->CreateDCRenderTarget(&targetProperties, renderTarget); … … 100 99 HRESULT hr = systemFactory()->CreateHwndRenderTarget(&renderTargetProperties, &hwndRenderTargetProperties, reinterpret_cast<ID2D1HwndRenderTarget**>(&defaultRenderTarget)); 101 100 RELEASE_ASSERT(SUCCEEDED(hr)); 101 defaultRenderTarget->AddRef(); 102 102 } 103 103 … … 114 114 DIBPixelData pixelData(bitmap); 115 115 116 auto targetProperties = D2D1::RenderTargetProperties(); 117 targetProperties.pixelFormat = D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED); 116 auto targetProperties = Direct2D::renderTargetProperties(); 118 117 119 118 COMPtr<ID2D1DCRenderTarget> renderTarget; … … 209 208 } 210 209 211 void GraphicsContext::drawNativeImage(const COMPtr<I WICBitmap>& image, const FloatSize& imageSize, const FloatRect& destRect, const FloatRect& srcRect, CompositeOperator compositeOperator, BlendMode blendMode, ImageOrientation orientation)210 void GraphicsContext::drawNativeImage(const COMPtr<ID2D1Bitmap>& image, const FloatSize& imageSize, const FloatRect& destRect, const FloatRect& srcRect, CompositeOperator compositeOperator, BlendMode blendMode, ImageOrientation orientation) 212 211 { 213 212 if (paintingDisabled()) … … 241 240 ASSERT(pixelData.bitsPerPixel() == 32); 242 241 243 auto bitmapProperties = D 2D1::BitmapProperties(D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED));242 auto bitmapProperties = Direct2D::bitmapProperties(); 244 243 245 244 ASSERT(hasPlatformContext()); … … 436 435 437 436 ASSERT(hasPlatformContext()); 438 if (auto tileImage = image.nativeImageForCurrentFrame( ))439 Direct2D::drawPattern(*platformContext(), tileImage.get(), IntSize(image.size()), destRect, tileRect, patternTransform, phase, compositeOperator, blendMode);437 if (auto tileImage = image.nativeImageForCurrentFrame(this)) 438 Direct2D::drawPattern(*platformContext(), WTFMove(tileImage), IntSize(image.size()), destRect, tileRect, patternTransform, phase, compositeOperator, blendMode); 440 439 } 441 440 -
trunk/Source/WebCore/platform/graphics/win/GraphicsContextImplDirect2D.cpp
r248846 r249110 292 292 void GraphicsContextImplDirect2D::drawPattern(Image& image, const FloatRect& destRect, const FloatRect& tileRect, const AffineTransform& patternTransform, const FloatPoint& phase, const FloatSize&, CompositeOperator compositeOperator, BlendMode blendMode) 293 293 { 294 if (auto surface = image.nativeImageForCurrentFrame()) 295 Direct2D::drawPattern(m_platformContext, surface.get(), IntSize(image.size()), destRect, tileRect, patternTransform, phase, compositeOperator, blendMode); 294 auto* context = &graphicsContext(); 295 if (auto surface = image.nativeImageForCurrentFrame(context)) 296 Direct2D::drawPattern(m_platformContext, WTFMove(surface), IntSize(image.size()), destRect, tileRect, patternTransform, phase, compositeOperator, blendMode); 296 297 } 297 298 … … 422 423 return; 423 424 424 425 if (auto surface = image->nativeImageForCurrentFrame( ))425 auto* context = &graphicsContext(); 426 if (auto surface = image->nativeImageForCurrentFrame(context)) 426 427 notImplemented(); 427 428 } -
trunk/Source/WebCore/platform/graphics/win/ImageBufferDataDirect2D.cpp
r247841 r249110 30 30 31 31 #include "BitmapInfo.h" 32 #include "Direct2DUtilities.h" 32 33 #include "GraphicsContext.h" 33 34 #include "HWndDC.h" 34 35 #include "IntRect.h" 35 36 #include "NotImplemented.h" 37 #include "PlatformContextDirect2D.h" 36 38 #include <JavaScriptCore/JSCInlines.h> 37 39 #include <JavaScriptCore/TypedArrayInlines.h> … … 43 45 namespace WebCore { 44 46 45 RefPtr<Uint8ClampedArray> ImageBufferData::getData(AlphaPremultiplication, const IntRect& rect, const IntSize& size, bool /* accelerateRendering */, float /* resolutionScale */) const 47 // Swizzle the red and blue bytes of the pixels in a buffer 48 template <AlphaPremultiplication desiredFormat> 49 void swizzleAndPremultiply(const uint8_t* srcRows, unsigned rowCount, unsigned colCount, unsigned srcStride, unsigned destStride, uint8_t* destRows) 50 { 51 for (unsigned y = 0; y < rowCount; ++y) { 52 // Source data may be power-of-two sized, so we need to only copy the bits that 53 // correspond to the rectangle supplied by the caller. 54 const uint32_t* srcRow = reinterpret_cast<const uint32_t*>(srcRows + srcStride * y); 55 uint8_t* destRow = destRows + destStride * y; 56 for (unsigned x = 0; x < colCount; ++x) { 57 unsigned bytePosition = x * 4; 58 const uint32_t* srcPixel = srcRow + x; 59 60 // Software filters expect (P)RGBA bytes. We need to swizzle from Direct2D's PBGRA to be compatible. 61 uint32_t alpha = (*srcPixel & 0xFF000000) >> 24; 62 uint32_t red = (*srcPixel & 0x00FF0000) >> 16; 63 uint32_t green = (*srcPixel & 0x0000FF00) >> 8; 64 uint32_t blue = (*srcPixel & 0x000000FF); 65 66 if (desiredFormat == AlphaPremultiplication::Unpremultiplied) { 67 if (alpha && alpha != 255) { 68 red = red * 255 / alpha; 69 green = green * 255 / alpha; 70 blue = blue * 255 / alpha; 71 } 72 } 73 74 destRow[bytePosition] = red; 75 destRow[bytePosition + 1] = green; 76 destRow[bytePosition + 2] = blue; 77 destRow[bytePosition + 3] = alpha; 78 } 79 } 80 } 81 82 RefPtr<Uint8ClampedArray> ImageBufferData::getData(AlphaPremultiplication desiredFormat, const IntRect& rect, const IntSize& size, bool /* accelerateRendering */, float /* resolutionScale */) const 46 83 { 47 84 auto numBytes = rect.area<RecordOverflow>() * 4; … … 54 91 return nullptr; 55 92 56 WICRect rcLock = { 0, 0, rect.width(), rect.height() };57 58 // We cannot access the data backing an IWICBitmap while an active draw session is open. 93 if (!bitmap) 94 return result; 95 59 96 context->endDraw(); 60 97 61 COMPtr<IWICBitmapLock> bitmapDataLock; 62 HRESULT hr = bitmapSource->Lock(&rcLock, WICBitmapLockRead, &bitmapDataLock); 63 if (SUCCEEDED(hr)) { 64 UINT bufferSize = 0; 65 WICInProcPointer dataPtr = nullptr; 66 hr = bitmapDataLock->GetDataPointer(&bufferSize, &dataPtr); 67 if (SUCCEEDED(hr)) 68 memcpy(result->data(), reinterpret_cast<char*>(dataPtr), numBytes.unsafeGet()); 98 COMPtr<ID2D1DeviceContext> d2dDeviceContext; 99 HRESULT hr = platformContext->renderTarget()->QueryInterface(__uuidof(ID2D1DeviceContext), reinterpret_cast<void**>(&d2dDeviceContext)); 100 ASSERT(SUCCEEDED(hr)); 101 102 auto bytesPerRowInData = size.width() * 4; 103 104 COMPtr<ID2D1Bitmap1> cpuBitmap; 105 D2D1_BITMAP_PROPERTIES1 bitmapProperties2 = D2D1::BitmapProperties1(D2D1_BITMAP_OPTIONS_CPU_READ | D2D1_BITMAP_OPTIONS_CANNOT_DRAW, Direct2D::pixelFormat()); 106 hr = d2dDeviceContext->CreateBitmap(size, nullptr, bytesPerRowInData, bitmapProperties2, &cpuBitmap); 107 if (!SUCCEEDED(hr)) 108 return nullptr; 109 110 D2D1_POINT_2U targetPos = D2D1::Point2U(); 111 D2D1_RECT_U dataRect = rect; 112 hr = cpuBitmap->CopyFromBitmap(&targetPos, bitmap.get(), &dataRect); 113 if (!SUCCEEDED(hr)) 114 return nullptr; 115 116 D2D1_MAPPED_RECT mappedData; 117 hr = cpuBitmap->Map(D2D1_MAP_OPTIONS_READ, &mappedData); 118 if (!SUCCEEDED(hr)) 119 return nullptr; 120 121 // Software filters expect RGBA bytes. We need to swizzle from Direct2D's BGRA to be compatible. 122 Checked<int> height = rect.height(); 123 Checked<int> width = rect.width(); 124 125 if (desiredFormat == AlphaPremultiplication::Unpremultiplied) 126 swizzleAndPremultiply<AlphaPremultiplication::Unpremultiplied>(mappedData.bits, height.unsafeGet(), width.unsafeGet(), mappedData.pitch, bytesPerRowInData, resultData); 127 else 128 swizzleAndPremultiply<AlphaPremultiplication::Premultiplied>(mappedData.bits, height.unsafeGet(), width.unsafeGet(), mappedData.pitch, bytesPerRowInData, resultData); 129 130 hr = cpuBitmap->Unmap(); 131 ASSERT(SUCCEEDED(hr)); 132 133 context->beginDraw(); 134 135 return result; 136 } 137 138 // Swizzle the red and blue bytes of the pixels in a buffer 139 template <AlphaPremultiplication sourceFormat> 140 void inPlaceSwizzle(uint8_t* byteData, unsigned byteCount) 141 { 142 size_t pixelCount = byteCount / 4; 143 auto* pixelData = reinterpret_cast<uint32_t*>(byteData); 144 145 for (size_t i = 0; i < pixelCount; ++i) { 146 uint32_t pixel = *pixelData; 147 size_t bytePosition = i * 4; 148 149 uint32_t alpha = (pixel & 0xFF000000) >> 24; 150 uint32_t red = (pixel & 0x00FF0000) >> 16; 151 uint32_t green = (pixel & 0x0000FF00) >> 8; 152 uint32_t blue = (pixel & 0x000000FF); 153 154 // (P)RGBA -> PBGRA 155 if (sourceFormat == AlphaPremultiplication::Unpremultiplied) { 156 if (alpha != 255) { 157 red = (red * alpha + 254) / 255; 158 green = (green * alpha + 254) / 255; 159 blue = (blue * alpha + 254) / 255; 160 } 161 } 162 163 *pixelData = (alpha << 24) | red << 16 | green << 8 | blue; 164 ++pixelData; 69 165 } 70 71 // Once we are done modifying the data, unlock the bitmap72 bitmapDataLock = nullptr;73 74 context->beginDraw();75 76 return result;77 166 } 78 167 … … 115 204 return; 116 205 206 context->endDraw(); 207 208 auto pixelSize = bitmap->GetPixelSize(); 209 ASSERT(pixelSize.width >= sourceSize.width()); 210 ASSERT(pixelSize.width >= size.width()); 211 ASSERT(pixelSize.height >= sourceSize.height()); 212 ASSERT(pixelSize.height >= size.height()); 213 214 // Software generated bitmap data is in RGBA. We need to swizzle to premultiplied BGRA to be compatible 215 // with the HWND/HDC render backing we use. 216 if (sourceFormat == AlphaPremultiplication::Unpremultiplied) 217 inPlaceSwizzle<AlphaPremultiplication::Unpremultiplied>(source.data(), source.length()); // RGBA -> PBGRA 218 else 219 inPlaceSwizzle<AlphaPremultiplication::Premultiplied>(source.data(), source.length()); // PRGBA -> PBGRA 220 221 COMPtr<ID2D1BitmapRenderTarget> bitmapRenderTarget; 222 HRESULT hr = platformContext->renderTarget()->QueryInterface(__uuidof(ID2D1BitmapRenderTarget), reinterpret_cast<void**>(&bitmapRenderTarget)); 223 ASSERT(SUCCEEDED(hr)); 224 225 auto bytesPerRowInData = sourceRect.width() * 4; 226 227 COMPtr<ID2D1Bitmap> swizzledBitmap; 228 D2D1_BITMAP_PROPERTIES bitmapProperties = D2D1::BitmapProperties(Direct2D::pixelFormat()); 229 hr = bitmapRenderTarget->CreateBitmap(sourceSize, source.data(), bytesPerRowInData, bitmapProperties, &swizzledBitmap); 230 if (!SUCCEEDED(hr)) 231 return; 232 233 D2D1_POINT_2U destPointD2D = destPoint; 234 D2D1_RECT_U srcRect = sourceRect; 235 hr = bitmap->CopyFromMemory(&srcRect, source.data(), bytesPerRowInData); 236 ASSERT(SUCCEEDED(hr)); 237 238 context->beginDraw(); 239 } 240 241 COMPtr<ID2D1Bitmap> ImageBufferData::compatibleBitmap(ID2D1RenderTarget* renderTarget) 242 { 243 if (!renderTarget) 244 return bitmap; 245 246 if (platformContext->renderTarget() == renderTarget) 247 return bitmap; 248 249 auto size = bitmap->GetPixelSize(); 250 251 Checked<unsigned, RecordOverflow> numBytes = size.width * size.height * 4; 252 if (numBytes.hasOverflowed()) 253 return nullptr; 254 255 // Copy the bits from current renderTarget to the output target. 117 256 // We cannot access the data backing an IWICBitmap while an active draw session is open. 118 257 context->endDraw(); 119 258 120 WICRect rcLock = { 0, 0, sourceSize.width(), sourceSize.height() }; 121 122 COMPtr<IWICBitmapLock> bitmapDataLock; 123 HRESULT hr = bitmapSource->Lock(&rcLock, WICBitmapLockWrite, &bitmapDataLock); 124 if (!SUCCEEDED(hr)) 125 return; 126 127 UINT stride = 0; 128 hr = bitmapDataLock->GetStride(&stride); 129 if (!SUCCEEDED(hr)) 130 return; 131 132 UINT bufferSize = 0; 133 WICInProcPointer dataPtr = nullptr; 134 hr = bitmapDataLock->GetDataPointer(&bufferSize, &dataPtr); 135 if (!SUCCEEDED(hr)) 136 return; 137 138 ASSERT(bufferSize == source.byteLength()); 139 140 unsigned srcBytesPerRow = 4 * sourceSize.width(); 141 142 ASSERT(srcBytesPerRow == stride); 143 144 const uint8_t* srcRows = source.data() + (originy * srcBytesPerRow + originx * 4).unsafeGet(); 145 146 auto row = makeUniqueArray<uint8_t>(srcBytesPerRow); 147 148 for (int y = 0; y < height.unsafeGet(); ++y) { 149 for (int x = 0; x < width.unsafeGet(); x++) { 150 int basex = x * 4; 151 uint8_t alpha = srcRows[basex + 3]; 152 if (sourceFormat == AlphaPremultiplication::Unpremultiplied && alpha != 255) { 153 row[basex] = (srcRows[basex] * alpha + 254) / 255; 154 row[basex + 1] = (srcRows[basex + 1] * alpha + 254) / 255; 155 row[basex + 2] = (srcRows[basex + 2] * alpha + 254) / 255; 156 row[basex + 3] = alpha; 157 } else 158 reinterpret_cast<uint32_t*>(row.get() + basex)[0] = reinterpret_cast<const uint32_t*>(srcRows + basex)[0]; 159 } 160 161 memcpy(reinterpret_cast<char*>(dataPtr + y * srcBytesPerRow), row.get(), srcBytesPerRow); 162 163 srcRows += srcBytesPerRow; 164 } 165 166 // Once we are done modifying the data, unlock the bitmap 167 bitmapDataLock = nullptr; 259 COMPtr<ID2D1DeviceContext> sourceDeviceContext; 260 HRESULT hr = platformContext->renderTarget()->QueryInterface(__uuidof(ID2D1DeviceContext), reinterpret_cast<void**>(&sourceDeviceContext)); 261 ASSERT(SUCCEEDED(hr)); 262 263 if (!sourceDeviceContext) 264 return nullptr; 265 266 COMPtr<ID2D1Bitmap1> sourceCPUBitmap; 267 D2D1_BITMAP_PROPERTIES1 bitmapProperties = D2D1::BitmapProperties1(D2D1_BITMAP_OPTIONS_CPU_READ | D2D1_BITMAP_OPTIONS_CANNOT_DRAW, Direct2D::pixelFormat()); 268 hr = sourceDeviceContext->CreateBitmap(bitmap->GetPixelSize(), nullptr, bytesPerRow.unsafeGet(), bitmapProperties, &sourceCPUBitmap); 269 if (!SUCCEEDED(hr)) 270 return nullptr; 271 272 if (!sourceCPUBitmap) 273 return nullptr; 274 275 hr = sourceCPUBitmap->CopyFromBitmap(nullptr, bitmap.get(), nullptr); 276 if (!SUCCEEDED(hr)) 277 return nullptr; 278 279 D2D1_MAPPED_RECT mappedSourceData; 280 hr = sourceCPUBitmap->Map(D2D1_MAP_OPTIONS_READ, &mappedSourceData); 281 if (!SUCCEEDED(hr)) 282 return nullptr; 283 284 COMPtr<ID2D1DeviceContext> targetDeviceContext; 285 hr = renderTarget->QueryInterface(__uuidof(ID2D1DeviceContext), reinterpret_cast<void**>(&targetDeviceContext)); 286 ASSERT(SUCCEEDED(hr)); 287 288 COMPtr<ID2D1Bitmap> compatibleBitmap; 289 hr = targetDeviceContext->CreateBitmap(bitmap->GetPixelSize(), mappedSourceData.bits, mappedSourceData.pitch, Direct2D::bitmapProperties(), &compatibleBitmap); 290 if (!SUCCEEDED(hr)) 291 return nullptr; 292 293 hr = sourceCPUBitmap->Unmap(); 294 ASSERT(SUCCEEDED(hr)); 168 295 169 296 context->beginDraw(); 297 298 return compatibleBitmap; 170 299 } 171 300 -
trunk/Source/WebCore/platform/graphics/win/ImageBufferDataDirect2D.h
r248020 r249110 33 33 #include <wtf/RetainPtr.h> 34 34 35 interface ID2D1RenderTarget; 36 interface ID2D1Bitmap; 37 35 38 namespace WebCore { 36 39 … … 45 48 std::unique_ptr<PlatformContextDirect2D> platformContext; 46 49 std::unique_ptr<GraphicsContext> context; 47 COMPtr<I WICBitmap> bitmapSource;50 COMPtr<ID2D1Bitmap> bitmap; 48 51 49 52 RefPtr<Uint8ClampedArray> getData(AlphaPremultiplication, const IntRect&, const IntSize&, bool accelerateRendering, float resolutionScale) const; 50 53 void putData(const Uint8ClampedArray& source, AlphaPremultiplication sourceFormat, const IntSize& sourceSize, const IntRect& sourceRect, const IntPoint& destPoint, const IntSize&, bool accelerateRendering, float resolutionScale); 54 55 COMPtr<ID2D1Bitmap> compatibleBitmap(ID2D1RenderTarget*); 51 56 }; 52 57 -
trunk/Source/WebCore/platform/graphics/win/ImageBufferDirect2D.cpp
r248846 r249110 39 39 #include "NotImplemented.h" 40 40 #include "PlatformContextDirect2D.h" 41 #include <d2d1 .h>41 #include <d2d1_1.h> 42 42 #include <math.h> 43 43 #include <wincodec.h> … … 77 77 } 78 78 79 ImageBuffer::ImageBuffer(const FloatSize& size, float resolutionScale, ColorSpace /*colorSpace*/, RenderingMode renderingMode, const HostWindow*, const GraphicsContext* , bool& success)79 ImageBuffer::ImageBuffer(const FloatSize& size, float resolutionScale, ColorSpace /*colorSpace*/, RenderingMode renderingMode, const HostWindow*, const GraphicsContext* targetContext, bool& success) 80 80 : m_logicalSize(size) 81 81 , m_resolutionScale(resolutionScale) … … 102 102 return; 103 103 104 m_data.data = Vector<char>(numBytes.unsafeGet(), 0); 105 106 m_data.bitmapSource = Direct2D::createDirect2DImageSurfaceWithData(m_data.data.data(), m_size, m_data.bytesPerRow.unsafeGet()); 107 if (!m_data.bitmapSource) 108 return; 109 110 COMPtr<ID2D1RenderTarget> bitmapContext = Direct2D::createRenderTargetFromWICBitmap(m_data.bitmapSource.get()); 104 auto* platformContext = targetContext ? targetContext->platformContext() : nullptr; 105 auto* renderTarget = platformContext ? platformContext->renderTarget() : nullptr; 106 107 if (!renderTarget) 108 renderTarget = GraphicsContext::defaultRenderTarget(); 109 110 D2D1_SIZE_F desiredSize = FloatSize(m_logicalSize); 111 D2D1_SIZE_U pixelSize = IntSize(m_logicalSize); 112 113 auto bitmapContext = Direct2D::createBitmapRenderTargetOfSize(m_logicalSize, renderTarget); 111 114 if (!bitmapContext) 112 115 return; 113 116 114 // Note: This places the bitmapcontext into a locked state because of the BeginDraw call in the constructor. 117 HRESULT hr = bitmapContext->GetBitmap(&m_data.bitmap); 118 if (!SUCCEEDED(hr)) 119 return; 120 115 121 m_data.platformContext = makeUnique<PlatformContextDirect2D>(bitmapContext.get()); 116 122 m_data.context = makeUnique<GraphicsContext>(m_data.platformContext.get(), GraphicsContext::BitmapRenderingContextType::GPUMemory); … … 141 147 } 142 148 143 static COMPtr<I WICBitmap> createCroppedImageIfNecessary(IWICBitmap* image, const IntSize& bounds)149 static COMPtr<ID2D1Bitmap> createCroppedImageIfNecessary(ID2D1BitmapRenderTarget* bitmapTarget, ID2D1Bitmap* image, const IntSize& bounds) 144 150 { 145 151 FloatSize imageSize = image ? nativeImageSize(image) : FloatSize(); 146 152 147 153 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()))) { 148 D2D_POINT_2U origin = { }; 149 WICRect croppedDimensions = { 0, 0, bounds.width(), bounds.height() }; 150 151 COMPtr<IWICBitmapClipper> bitmapClipper; 152 HRESULT hr = ImageDecoderDirect2D::systemImagingFactory()->CreateBitmapClipper(&bitmapClipper); 153 if (SUCCEEDED(hr)) { 154 hr = bitmapClipper->Initialize(image, &croppedDimensions); 155 if (SUCCEEDED(hr)) { 156 COMPtr<IWICBitmap> croppedBitmap; 157 hr = ImageDecoderDirect2D::systemImagingFactory()->CreateBitmapFromSource(image, WICBitmapNoCache, &croppedBitmap); 158 if (SUCCEEDED(hr)) 159 return croppedBitmap; 160 } 154 COMPtr<ID2D1Bitmap> croppedBitmap = Direct2D::createBitmap(bitmapTarget, bounds); 155 if (croppedBitmap) { 156 auto sourceRect = D2D1::RectU(0, 0, bounds.width(), bounds.height()); 157 HRESULT hr = croppedBitmap->CopyFromBitmap(nullptr, image, &sourceRect); 158 if (SUCCEEDED(hr)) 159 return croppedBitmap; 161 160 } 162 161 } … … 165 164 } 166 165 167 static RefPtr<Image> createBitmapImageAfterScalingIfNeeded( COMPtr<IWICBitmap>&& image, IntSize internalSize, IntSize logicalSize, IntSize backingStoreSize, float resolutionScale, PreserveResolution preserveResolution)166 static RefPtr<Image> createBitmapImageAfterScalingIfNeeded(ID2D1BitmapRenderTarget* bitmapTarget, COMPtr<ID2D1Bitmap>&& image, IntSize internalSize, IntSize logicalSize, IntSize backingStoreSize, float resolutionScale, PreserveResolution preserveResolution) 168 167 { 169 168 if (resolutionScale == 1 || preserveResolution == PreserveResolution::Yes) 170 image = createCroppedImageIfNecessary( image.get(), internalSize);169 image = createCroppedImageIfNecessary(bitmapTarget, image.get(), internalSize); 171 170 else { 172 171 // FIXME: Need to implement scaled version … … 182 181 RefPtr<Image> ImageBuffer::copyImage(BackingStoreCopy copyBehavior, PreserveResolution preserveResolution) const 183 182 { 184 COMPtr<I WICBitmap> image;183 COMPtr<ID2D1Bitmap> image; 185 184 if (m_resolutionScale == 1 || preserveResolution == PreserveResolution::Yes) 186 185 image = copyNativeImage(copyBehavior); … … 188 187 image = copyNativeImage(DontCopyBackingStore); 189 188 190 return createBitmapImageAfterScalingIfNeeded(WTFMove(image), internalSize(), logicalSize(), m_data.backingStoreSize, m_resolutionScale, preserveResolution); 189 auto bitmapTarget = reinterpret_cast<ID2D1BitmapRenderTarget*>(context().platformContext()); 190 return createBitmapImageAfterScalingIfNeeded(bitmapTarget, WTFMove(image), internalSize(), logicalSize(), m_data.backingStoreSize, m_resolutionScale, preserveResolution); 191 191 } 192 192 … … 198 198 float resolutionScale = imageBuffer->m_resolutionScale; 199 199 200 return createBitmapImageAfterScalingIfNeeded(sinkIntoNativeImage(WTFMove(imageBuffer)), internalSize, logicalSize, backingStoreSize, resolutionScale, preserveResolution); 200 auto bitmapTarget = reinterpret_cast<ID2D1BitmapRenderTarget*>(imageBuffer->context().platformContext()->renderTarget()); 201 return createBitmapImageAfterScalingIfNeeded(bitmapTarget, sinkIntoNativeImage(WTFMove(imageBuffer)), internalSize, logicalSize, backingStoreSize, resolutionScale, preserveResolution); 201 202 } 202 203 … … 206 207 } 207 208 208 COMPtr<I WICBitmap> ImageBuffer::sinkIntoNativeImage(std::unique_ptr<ImageBuffer> imageBuffer)209 COMPtr<ID2D1Bitmap> ImageBuffer::sinkIntoNativeImage(std::unique_ptr<ImageBuffer> imageBuffer) 209 210 { 210 211 // FIXME: See if we can reuse the on-hardware image. … … 212 213 } 213 214 214 COMPtr<IWICBitmap> ImageBuffer::copyNativeImage(BackingStoreCopy copyBehavior) const 215 { 215 COMPtr<ID2D1Bitmap> ImageBuffer::copyNativeImage(BackingStoreCopy copyBehavior) const 216 { 217 auto bitmapTarget = reinterpret_cast<ID2D1BitmapRenderTarget*>(context().platformContext()); 218 219 COMPtr<ID2D1Bitmap> image; 220 HRESULT hr = bitmapTarget->GetBitmap(&image); 221 ASSERT(SUCCEEDED(hr)); 222 216 223 // FIXME: m_data.data is nullptr even when asking to copy backing store leading to test failures. 217 224 if (copyBehavior == CopyBackingStore && m_data.data.isEmpty()) … … 222 229 return nullptr; 223 230 224 HRESULT hr = S_OK;225 COMPtr<IWICBitmap> image;226 231 if (!context().isAcceleratedContext()) { 227 232 switch (copyBehavior) { 228 233 case DontCopyBackingStore: 229 hr = ImageDecoderDirect2D::systemImagingFactory()->CreateBitmapFromSource(m_data.bitmapSource.get(), WICBitmapNoCache, &image);230 234 break; 231 235 case CopyBackingStore: 232 hr = ImageDecoderDirect2D::systemImagingFactory()->CreateBitmapFromSource(m_data.bitmapSource.get(), WICBitmapCacheOnDemand, &image); 236 D2D1_RECT_U backingStoreDimenstions = IntRect(IntPoint(), m_data.backingStoreSize); 237 image->CopyFromMemory(&backingStoreDimenstions, m_data.data.data(), 32); 233 238 break; 234 239 default: … … 255 260 adjustedSrcRect.scale(m_resolutionScale, m_resolutionScale); 256 261 257 FloatSize currentImageSize = nativeImageSize(m_data.bitmapSource); 258 259 // You can't convert a IWICBitmap to a ID2D1Bitmap with an active GraphicsContext attached to it. 260 m_data.context->endDraw(); 261 262 destContext.drawNativeImage(m_data.bitmapSource, currentImageSize, destRect, adjustedSrcRect, op, blendMode); 263 264 m_data.context->beginDraw(); 265 266 destContext.flush(); 262 auto compatibleBitmap = m_data.compatibleBitmap(destContext.platformContext()->renderTarget()); 263 264 FloatSize currentImageSize = nativeImageSize(compatibleBitmap); 265 if (currentImageSize.isZero()) 266 return; 267 268 destContext.drawNativeImage(compatibleBitmap, currentImageSize, destRect, adjustedSrcRect, op, blendMode); 267 269 } 268 270 -
trunk/Source/WebCore/platform/graphics/win/ImageDecoderDirect2D.cpp
r248907 r249110 240 240 return nullptr; 241 241 242 if (!m_renderTarget) 243 return nullptr; 244 242 245 COMPtr<IWICBitmapFrameDecode> frame; 243 246 HRESULT hr = m_nativeDecoder->GetFrame(0, &frame); … … 254 257 return nullptr; 255 258 256 COMPtr<IWICBitmap> bitmap; 257 hr = systemImagingFactory()->CreateBitmapFromSource(converter.get(), WICBitmapCacheOnDemand, &bitmap); 259 COMPtr<IWICBitmap> wicBitmap; 260 hr = systemImagingFactory()->CreateBitmapFromSource(converter.get(), WICBitmapCacheOnDemand, &wicBitmap); 261 if (!SUCCEEDED(hr)) 262 return nullptr; 263 264 COMPtr<ID2D1Bitmap> bitmap; 265 hr = m_renderTarget->CreateBitmapFromWicBitmap(wicBitmap.get(), &bitmap); 258 266 if (!SUCCEEDED(hr)) 259 267 return nullptr; … … 287 295 // Image was valid. 288 296 } 297 289 298 } 290 299 -
trunk/Source/WebCore/platform/graphics/win/NativeImageDirect2D.cpp
r248657 r249110 57 57 return { }; 58 58 59 HRESULT hr = image->GetSize(&width, &height); 60 if (!SUCCEEDED(hr)) 61 return { }; 62 63 return IntSize(width, height); 59 return image->GetPixelSize(); 64 60 } 65 61 … … 69 65 return false; 70 66 71 WICPixelFormatGUID pixelFormatGUID = { }; 72 HRESULT hr = image->GetPixelFormat(&pixelFormatGUID); 73 if (!SUCCEEDED(hr)) 74 return false; 75 76 // FIXME: Should we just check the pixelFormatGUID for relevant ID's we use? 77 78 COMPtr<IWICComponentInfo> componentInfo; 79 hr = imagingFactory()->CreateComponentInfo(pixelFormatGUID, &componentInfo); 80 if (!SUCCEEDED(hr)) 81 return false; 82 83 COMPtr<IWICPixelFormatInfo> pixelFormatInfo(Query, componentInfo.get()); 84 if (!pixelFormatInfo) 85 return false; 86 87 UINT channelCount = 0; 88 hr = pixelFormatInfo->GetChannelCount(&channelCount); 89 if (!SUCCEEDED(hr)) 90 return false; 91 92 return channelCount > 3; 67 D2D1_PIXEL_FORMAT pixelFormat = image->GetPixelFormat(); 68 return pixelFormat.alphaMode != D2D1_ALPHA_MODE_IGNORE; 93 69 } 94 70 … … 117 93 float opacity = 1.0f; 118 94 119 COMPtr<ID2D1Bitmap> bitmap; 120 HRESULT hr = platformContext->renderTarget()->CreateBitmapFromWicBitmap(image.get(), &bitmap); 121 if (!SUCCEEDED(hr)) 122 return; 123 124 platformContext->renderTarget()->DrawBitmap(bitmap.get(), destRect, opacity, D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR, adjustedSrcRect); 125 context.flush(); 95 platformContext->renderTarget()->DrawBitmap(image.get(), destRect, opacity, D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR, adjustedSrcRect); 126 96 } 127 97 -
trunk/Source/WebCore/platform/graphics/win/PatternDirect2D.cpp
r248020 r249110 60 60 auto nativeImage = patternImage.nativeImage(nullptr); 61 61 62 COMPtr<ID2D1Bitmap> bitmap;63 HRESULT hr = context.renderTarget()->CreateBitmapFromWicBitmap(nativeImage.get(), &bitmap);64 if (!SUCCEEDED(hr))65 return nullptr;66 67 62 ID2D1BitmapBrush* patternBrush = nullptr; 68 hr = context.renderTarget()->CreateBitmapBrush(bitmap.get(), &bitmapBrushProperties, &brushProperties, &patternBrush);63 HRESULT hr = context.renderTarget()->CreateBitmapBrush(nativeImage.get(), &bitmapBrushProperties, &brushProperties, &patternBrush); 69 64 ASSERT(SUCCEEDED(hr)); 70 65 return patternBrush; -
trunk/Source/WebCore/svg/graphics/SVGImage.cpp
r248846 r249110 70 70 #include "COMPtr.h" 71 71 #include "Direct2DUtilities.h" 72 #include "GraphicsContext.h" 72 73 #include "ImageDecoderDirect2D.h" 73 74 #include "PlatformContextDirect2D.h" … … 236 237 return nullptr; 237 238 238 COMPtr<IWICBitmap> nativeImage; 239 HRESULT hr = ImageDecoderDirect2D::systemImagingFactory()->CreateBitmap(rect().width(), rect().height(), GUID_WICPixelFormat32bppPRGBA, WICBitmapCacheOnLoad, &nativeImage); 240 if (!SUCCEEDED(hr)) 241 return nullptr; 242 243 COMPtr<ID2D1RenderTarget> nativeImageTarget = Direct2D::createRenderTargetFromWICBitmap(nativeImage.get()); 239 ASSERT(targetContext->hasPlatformContext()); 240 auto* renderTarget = targetContext->platformContext()->renderTarget(); 241 242 IntSize bitmapSize(size().width(), size().height()); 243 auto nativeImageTarget = Direct2D::createBitmapRenderTargetOfSize(bitmapSize, renderTarget, 1.0); 244 244 if (!nativeImageTarget) 245 245 return nullptr; … … 249 249 250 250 draw(localContext, rect(), rect(), CompositeSourceOver, BlendMode::Normal, DecodingMode::Synchronous, ImageOrientation::None); 251 252 COMPtr<ID2D1Bitmap> nativeImage; 253 HRESULT hr = nativeImageTarget->GetBitmap(&nativeImage); 254 if (!SUCCEEDED(hr)) 255 return nullptr; 256 257 #if !ASSERT_DISABLED 258 auto nativeImageSize = nativeImage->GetPixelSize(); 259 ASSERT(nativeImageSize.height = rect().size().height()); 260 ASSERT(nativeImageSize.width = rect().size().width()); 261 #endif 251 262 252 263 return nativeImage; -
trunk/Source/WebKit/ChangeLog
r249108 r249110 1 2019-08-26 Brent Fulgham <bfulgham@apple.com> 2 3 [FTW] Go back to ID2D1Bitmap as our NativeImage type 4 https://bugs.webkit.org/show_bug.cgi?id=201122 5 6 Reviewed by Alex Christensen. 7 8 In Bug 200093 I switched the OS type of NativeImagePtr from ID2D1Bitmap to IWICBitmap. 9 However, this was an ill-advised approach, because it dramatically harmed performance due 10 to the heavy use of software rendering. 11 12 I originally made this change because I thought this was the only way to get to the backing 13 bits of the bitmaps, but it turns out that a more recent Direct2D data type (ID2D1Bitmap1) 14 has the ability to map its memory to CPU-accessible memory, allowing software filter effects. 15 16 This patch switches back to the ID2D1Bitap data type, and hooks up the ID2D1Bitmap1 data type 17 to access the underlying memory of the bitmaps when software filter effects are used. 18 19 Reviewed by Alex Christensen. 20 21 * Shared/ShareableBitmap.h: 22 * Shared/win/ShareableBitmapDirect2D.cpp: 23 * UIProcess/win/BackingStoreDirect2D.cpp: 24 * WebProcess/WebPage/CoordinatedGraphics/DrawingAreaCoordinatedGraphics.cpp: 25 1 26 2019-08-26 Jiewen Tan <jiewen_tan@apple.com> 2 27 -
trunk/Source/WebKit/Shared/ShareableBitmap.h
r248755 r249110 41 41 42 42 #if USE(DIRECT2D) 43 interface IWICBitmap; 43 interface ID2D1Bitmap; 44 interface ID2D1RenderTarget; 44 45 45 46 #include <WebCore/COMPtr.h> … … 132 133 RefPtr<cairo_surface_t> createCairoSurface(); 133 134 #elif USE(DIRECT2D) 134 COMPtr<I WICBitmap> createDirect2DSurface();135 COMPtr<ID2D1Bitmap> createDirect2DSurface(ID2D1RenderTarget*); 135 136 void sync(WebCore::GraphicsContext&); 136 137 #endif … … 163 164 164 165 #if USE(DIRECT2D) 165 COMPtr<I WICBitmap> m_bitmap;166 COMPtr<ID2D1Bitmap> m_bitmap; 166 167 #endif 167 168 … … 170 171 171 172 // If the shareable bitmap is backed by fastMalloced memory, this points to the data. 172 void* m_data ;173 void* m_data { nullptr }; 173 174 }; 174 175 -
trunk/Source/WebKit/Shared/win/ShareableBitmapDirect2D.cpp
r248907 r249110 36 36 #include <WebCore/NotImplemented.h> 37 37 #include <WebCore/PlatformContextDirect2D.h> 38 #include <d2d1_1.h> 38 39 #include <wincodec.h> 39 40 #include <wtf/ProcessID.h> … … 43 44 using namespace WebCore; 44 45 45 static const auto bitmapFormat = GUID_WICPixelFormat32bppPBGRA;46 47 46 static unsigned strideForWidth(unsigned width) 48 47 { 49 static unsigned bitsPerPixel = Direct2D::bitsPerPixel( bitmapFormat);48 static unsigned bitsPerPixel = Direct2D::bitsPerPixel(Direct2D::wicBitmapFormat()); 50 49 return bitsPerPixel * width / 8; 51 50 } … … 69 68 std::unique_ptr<GraphicsContext> ShareableBitmap::createGraphicsContext() 70 69 { 71 m_bitmap = createDirect2DSurface(); 72 COMPtr<ID2D1RenderTarget> bitmapContext = Direct2D::createRenderTargetFromWICBitmap(m_bitmap.get()); 70 auto bitmapContext = Direct2D::createBitmapRenderTargetOfSize(m_size); 71 if (!bitmapContext) 72 return nullptr; 73 74 HRESULT hr = bitmapContext->GetBitmap(&m_bitmap); 75 RELEASE_ASSERT(SUCCEEDED(hr)); 73 76 return makeUnique<GraphicsContext>(GraphicsContextImplDirect2D::createFactory(bitmapContext.get())); 74 77 } … … 81 84 void ShareableBitmap::paint(GraphicsContext& context, float scaleFactor, const IntPoint& dstPoint, const IntRect& srcRect) 82 85 { 83 auto surface = createDirect2DSurface( );86 auto surface = createDirect2DSurface(context.platformContext()->renderTarget()); 84 87 85 88 #ifndef _NDEBUG 86 unsigned width, height; 87 HRESULT hr = surface->GetSize(&width, &height); 88 ASSERT(width == m_size.width()); 89 ASSERT(height == m_size.height()); 89 auto bitmapSize = surface->GetPixelSize(); 90 ASSERT(bitmapSize.width == m_size.width()); 91 ASSERT(bitmapSize.height == m_size.height()); 90 92 #endif 91 93 … … 101 103 } 102 104 103 COMPtr<I WICBitmap> ShareableBitmap::createDirect2DSurface()105 COMPtr<ID2D1Bitmap> ShareableBitmap::createDirect2DSurface(ID2D1RenderTarget* renderTarget) 104 106 { 105 m_bitmap = createSurfaceFromData(data(), m_size); 106 return m_bitmap; 107 auto bitmapProperties = Direct2D::bitmapProperties(); 108 109 COMPtr<ID2D1Bitmap> bitmap; 110 uint32_t stride = 4 * m_size.width(); 111 HRESULT hr = renderTarget->CreateBitmap(m_size, data(), stride, &bitmapProperties, &bitmap); 112 if (!SUCCEEDED(hr)) 113 return nullptr; 114 115 return bitmap; 107 116 } 108 117 109 118 RefPtr<Image> ShareableBitmap::createImage() 110 119 { 111 auto surface = createDirect2DSurface( );120 auto surface = createDirect2DSurface(GraphicsContext::defaultRenderTarget()); 112 121 if (!surface) 113 122 return nullptr; … … 122 131 graphicsContext.endDraw(); 123 132 124 WICRect rcLock = { 0, 0, m_size.width(), m_size.height() }; 133 COMPtr<ID2D1DeviceContext> d2dDeviceContext; 134 HRESULT hr = graphicsContext.platformContext()->renderTarget()->QueryInterface(__uuidof(ID2D1DeviceContext), reinterpret_cast<void**>(&d2dDeviceContext)); 135 ASSERT(SUCCEEDED(hr)); 125 136 126 COMPtr<IWICBitmapLock> bitmapDataLock; 127 HRESULT hr = m_bitmap->Lock(&rcLock, WICBitmapLockRead, &bitmapDataLock); 128 if (SUCCEEDED(hr)) { 129 UINT bufferSize = 0; 130 WICInProcPointer dataPtr = nullptr; 131 hr = bitmapDataLock->GetDataPointer(&bufferSize, &dataPtr); 132 if (SUCCEEDED(hr)) 133 memcpy(data(), reinterpret_cast<char*>(dataPtr), bufferSize); 137 const unsigned stride = strideForWidth(m_size.width()); 138 139 COMPtr<ID2D1Bitmap1> cpuBitmap; 140 D2D1_BITMAP_PROPERTIES1 bitmapProperties = D2D1::BitmapProperties1(D2D1_BITMAP_OPTIONS_CPU_READ | D2D1_BITMAP_OPTIONS_CANNOT_DRAW, Direct2D::pixelFormat()); 141 hr = d2dDeviceContext->CreateBitmap(m_size, nullptr, stride, bitmapProperties, &cpuBitmap); 142 if (!SUCCEEDED(hr)) 143 return; 144 145 hr = cpuBitmap->CopyFromBitmap(nullptr, m_bitmap.get(), nullptr); 146 if (!SUCCEEDED(hr)) 147 return; 148 149 D2D1_MAPPED_RECT mappedData; 150 hr = cpuBitmap->Map(D2D1_MAP_OPTIONS_READ, &mappedData); 151 if (!SUCCEEDED(hr)) 152 return; 153 154 if (mappedData.pitch == stride) 155 memcpy(data(), reinterpret_cast<char*>(mappedData.bits), stride * m_size.height()); 156 else { 157 // Stride is different, so must do a rowwise copy: 158 Checked<int> height = m_size.height(); 159 Checked<int> width = m_size.width(); 160 161 const uint8_t* srcRows = mappedData.bits; 162 uint8_t* row = reinterpret_cast<uint8_t*>(data()); 163 164 for (int y = 0; y < height.unsafeGet(); ++y) { 165 for (int x = 0; x < width.unsafeGet(); x++) { 166 int basex = x * 4; 167 reinterpret_cast<uint32_t*>(row + basex)[0] = reinterpret_cast<const uint32_t*>(srcRows + basex)[0]; 168 } 169 170 srcRows += mappedData.pitch; 171 row += stride; 172 } 134 173 } 135 174 136 // Once we are done modifying the data, unlock the bitmap137 bitmapDataLock = nullptr;175 hr = cpuBitmap->Unmap(); 176 ASSERT(SUCCEEDED(hr)); 138 177 } 139 178 -
trunk/Source/WebKit/UIProcess/win/BackingStoreDirect2D.cpp
r248907 r249110 74 74 IntPoint updateRectBoundsLocation = updateInfo.updateRectBounds.location(); 75 75 76 auto updateWICBitmap = bitmap->createDirect2DSurface(); 77 78 HRESULT hr = S_OK; 79 #ifndef _NDEBUG 80 unsigned width, height; 81 hr = updateWICBitmap->GetSize(&width, &height); 82 ASSERT(width == updateInfo.updateRectBounds.width()); 83 ASSERT(height == updateInfo.updateRectBounds.height()); 84 #endif 85 86 COMPtr<ID2D1Bitmap> deviceUpdateBitmap; 87 hr = m_backend->renderTarget()->CreateBitmapFromWicBitmap(updateWICBitmap.get(), &deviceUpdateBitmap); 88 if (!SUCCEEDED(hr)) 89 return; 76 COMPtr<ID2D1Bitmap> deviceUpdateBitmap = bitmap->createDirect2DSurface(m_backend->renderTarget()); 90 77 91 78 #ifndef _NDEBUG -
trunk/Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/DrawingAreaCoordinatedGraphics.cpp
r248846 r249110 755 755 756 756 #if USE(DIRECT2D) 757 bitmap->sync(*graphicsContext); 757 if (graphicsContext) 758 bitmap->sync(*graphicsContext); 758 759 #endif 759 760
Note:
See TracChangeset
for help on using the changeset viewer.