Title: [277525] trunk/Source
Revision
277525
Author
wei...@apple.com
Date
2021-05-14 17:59:56 -0700 (Fri, 14 May 2021)

Log Message

Source/WebCore:
Use PixelBufferFormat to specify ImageBuffer::getPixelData destination format allowing for more control over data conversion
https://bugs.webkit.org/show_bug.cgi?id=225813

Reviewed by Darin Adler.

The reprevious signature of ImageBuffer::getPixelBuffer:

    ImageBuffer::getPixelBuffer(AlphaPremultiplication, const IntRect&);

only allowed specifying the type of alpha premultiplication wanted, and hard coded
a pixel format of RGBA8 and color space of SRGB. To support accurate and efficient
access to pixel buffers with different pixel formats and color spaces we need to be
able to tell getPixelBuffer what we want up front, so that if the ImageBuffer already
has a DisplayP3 buffer, and we want DisplayP3 pixels, we don't first convert to SRGB
and then convert back to DisplayP3 (which would be slow and lose any out of gamut
data). The new signature allows us to specify the entire format triple:

    ImageBuffer::getPixelBuffer(const PixelBufferFormat&, const IntRect&);

Additionally, ImageBuffer::putPixelBuffer() no longer needs to provide the source
AlphaPremultiplication either, as the PixelBuffer itself also contains that information.

Now that we are passing color space information, we need to support color space conversion,
so PixelBufferConversion was updated to support color space conversion on CG platforms
using vImageConvert_AnyToAny. This is not currently excersised, but will be in a subsequent
change where canvas ImageData gains a color space setting, at which point it can be tested.

We also don't currently support color space conversion on non-CG platforms. This won't
be a problem in the short term, as only CG platforms support DisplayP3, the only other
color space that can be specified currently, but as cleanup, we should add support for
color space conversion using the ColorConversion and ColorTransferFunction infrastructure
for other ports, moving the existing support for SRGB to/from LinearSRGB conversions from
ImageBufferCairoBackend and ImageBufferCairoImageSurfaceBackend.

* html/ImageBitmap.cpp:
(WebCore::ImageBitmap::createPromise):
* html/canvas/CanvasRenderingContext2DBase.cpp:
(WebCore::CanvasRenderingContext2DBase::getImageData const):
(WebCore::CanvasRenderingContext2DBase::putImageData):
* page/PageConsoleClient.cpp:
(WebCore::PageConsoleClient::screenshot):
* platform/graphics/ConcreteImageBuffer.h:
(WebCore::ConcreteImageBuffer::putPixelBuffer):
* platform/graphics/ImageBuffer.h:
(WebCore::ImageBuffer::putPixelBuffer):
* platform/graphics/ImageBufferBackend.cpp:
(WebCore::ImageBufferBackend::convertToLuminanceMask):
(WebCore::ImageBufferBackend::getPixelBuffer const):
(WebCore::ImageBufferBackend::putPixelBuffer):
* platform/graphics/ImageBufferBackend.h:
* platform/graphics/PixelBufferConversion.cpp:
(WebCore::makeVImageCGImageFormat):
(WebCore::makeVImageBuffer):
(WebCore::convertImagePixelsAccelerated):
(WebCore::convertImagePixels):
* platform/graphics/ShadowBlur.cpp:
(WebCore::ShadowBlur::blurShadowBuffer):
* platform/graphics/cairo/ImageBufferCairoSurfaceBackend.cpp:
(WebCore::ImageBufferCairoSurfaceBackend::getPixelBuffer const):
(WebCore::ImageBufferCairoSurfaceBackend::putPixelBuffer):
* platform/graphics/cairo/ImageBufferCairoSurfaceBackend.h:
* platform/graphics/cg/ImageBufferCGBackend.cpp:
(WebCore::ImageBufferCGBackend::toCFData const):
* platform/graphics/cg/ImageBufferCGBitmapBackend.cpp:
(WebCore::ImageBufferCGBitmapBackend::getPixelBuffer const):
(WebCore::ImageBufferCGBitmapBackend::putPixelBuffer):
* platform/graphics/cg/ImageBufferCGBitmapBackend.h:
* platform/graphics/cg/ImageBufferIOSurfaceBackend.cpp:
(WebCore::ImageBufferIOSurfaceBackend::getPixelBuffer const):
(WebCore::ImageBufferIOSurfaceBackend::putPixelBuffer):
* platform/graphics/cg/ImageBufferIOSurfaceBackend.h:
* platform/graphics/displaylists/DisplayListItems.cpp:
(WebCore::DisplayList::PutPixelBuffer::PutPixelBuffer):
(WebCore::DisplayList::PutPixelBuffer::swap):
(WebCore::DisplayList::operator<<):
* platform/graphics/displaylists/DisplayListItems.h:
(WebCore::DisplayList::GetPixelBuffer::GetPixelBuffer):
(WebCore::DisplayList::GetPixelBuffer::outputFormat const):
(WebCore::DisplayList::PutPixelBuffer::encode const):
(WebCore::DisplayList::PutPixelBuffer::decode):
(WebCore::DisplayList::PutPixelBuffer::inputFormat const): Deleted.
* platform/graphics/displaylists/DisplayListRecorder.cpp:
(WebCore::DisplayList::Recorder::getPixelBuffer):
(WebCore::DisplayList::Recorder::putPixelBuffer):
* platform/graphics/displaylists/DisplayListRecorder.h:
* platform/graphics/filters/FEColorMatrix.cpp:
(WebCore::FEColorMatrix::platformApplySoftware):
* platform/graphics/filters/FEDropShadow.cpp:
(WebCore::FEDropShadow::platformApplySoftware):
* platform/graphics/filters/FilterEffect.cpp:
(WebCore::FilterEffect::imageBufferResult):
(WebCore::FilterEffect::convertPixelBufferToColorSpace):
(WebCore::FilterEffect::convertImageBufferToColorSpace):
(WebCore::FilterEffect::copyConvertedPixelBufferToDestination):
(WebCore::FilterEffect::copyUnmultipliedResult):
(WebCore::FilterEffect::copyPremultipliedResult):
* platform/graphics/filters/FilterEffect.h:
* platform/graphics/win/ImageBufferDirect2DBackend.cpp:
(WebCore::ImageBufferDirect2DBackend::getPixelBuffer const):
(WebCore::ImageBufferDirect2DBackend::putPixelBuffer):
* platform/graphics/win/ImageBufferDirect2DBackend.h:
* rendering/shapes/Shape.cpp:
(WebCore::Shape::createRasterShape):

Source/WebKit:
Use PixelBufferFormat to specify ImageBuffer::getPixelBuffer destination format allowing for more control over data conversion
https://bugs.webkit.org/show_bug.cgi?id=225813

Reviewed by Darin Adler.

Update calls/implementations of getPixelBuffer/putPixelBuffer to adjust
to new signature.

* GPUProcess/graphics/RemoteImageBuffer.h:
* Shared/RemoteLayerTree/CGDisplayListImageBufferBackend.cpp:
(WebKit::CGDisplayListImageBufferBackend::getPixelBuffer const):
(WebKit::CGDisplayListImageBufferBackend::putPixelBuffer):
* Shared/RemoteLayerTree/CGDisplayListImageBufferBackend.h:
* WebProcess/GPU/graphics/ImageBufferShareableBitmapBackend.cpp:
(WebKit::ImageBufferShareableBitmapBackend::getPixelBuffer const):
(WebKit::ImageBufferShareableBitmapBackend::putPixelBuffer):
* WebProcess/GPU/graphics/ImageBufferShareableBitmapBackend.h:
* WebProcess/GPU/graphics/RemoteImageBufferProxy.h:
(WebKit::RemoteImageBufferProxy::putPixelBuffer):
* WebProcess/GPU/graphics/cocoa/ImageBufferShareableIOSurfaceBackend.cpp:
(WebKit::ImageBufferShareableIOSurfaceBackend::getPixelBuffer const):
(WebKit::ImageBufferShareableIOSurfaceBackend::putPixelBuffer):
* WebProcess/GPU/graphics/cocoa/ImageBufferShareableIOSurfaceBackend.h:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (277524 => 277525)


--- trunk/Source/WebCore/ChangeLog	2021-05-15 00:47:33 UTC (rev 277524)
+++ trunk/Source/WebCore/ChangeLog	2021-05-15 00:59:56 UTC (rev 277525)
@@ -1,3 +1,109 @@
+2021-05-14  Sam Weinig  <wei...@apple.com>
+
+        Use PixelBufferFormat to specify ImageBuffer::getPixelData destination format allowing for more control over data conversion
+        https://bugs.webkit.org/show_bug.cgi?id=225813
+
+        Reviewed by Darin Adler.
+
+        The reprevious signature of ImageBuffer::getPixelBuffer:
+
+            ImageBuffer::getPixelBuffer(AlphaPremultiplication, const IntRect&);
+        
+        only allowed specifying the type of alpha premultiplication wanted, and hard coded
+        a pixel format of RGBA8 and color space of SRGB. To support accurate and efficient
+        access to pixel buffers with different pixel formats and color spaces we need to be
+        able to tell getPixelBuffer what we want up front, so that if the ImageBuffer already
+        has a DisplayP3 buffer, and we want DisplayP3 pixels, we don't first convert to SRGB
+        and then convert back to DisplayP3 (which would be slow and lose any out of gamut
+        data). The new signature allows us to specify the entire format triple:
+        
+            ImageBuffer::getPixelBuffer(const PixelBufferFormat&, const IntRect&);
+
+        Additionally, ImageBuffer::putPixelBuffer() no longer needs to provide the source
+        AlphaPremultiplication either, as the PixelBuffer itself also contains that information.
+
+        Now that we are passing color space information, we need to support color space conversion,
+        so PixelBufferConversion was updated to support color space conversion on CG platforms
+        using vImageConvert_AnyToAny. This is not currently excersised, but will be in a subsequent
+        change where canvas ImageData gains a color space setting, at which point it can be tested.
+
+        We also don't currently support color space conversion on non-CG platforms. This won't
+        be a problem in the short term, as only CG platforms support DisplayP3, the only other
+        color space that can be specified currently, but as cleanup, we should add support for
+        color space conversion using the ColorConversion and ColorTransferFunction infrastructure
+        for other ports, moving the existing support for SRGB to/from LinearSRGB conversions from
+        ImageBufferCairoBackend and ImageBufferCairoImageSurfaceBackend.
+
+        * html/ImageBitmap.cpp:
+        (WebCore::ImageBitmap::createPromise):
+        * html/canvas/CanvasRenderingContext2DBase.cpp:
+        (WebCore::CanvasRenderingContext2DBase::getImageData const):
+        (WebCore::CanvasRenderingContext2DBase::putImageData):
+        * page/PageConsoleClient.cpp:
+        (WebCore::PageConsoleClient::screenshot):
+        * platform/graphics/ConcreteImageBuffer.h:
+        (WebCore::ConcreteImageBuffer::putPixelBuffer):
+        * platform/graphics/ImageBuffer.h:
+        (WebCore::ImageBuffer::putPixelBuffer):
+        * platform/graphics/ImageBufferBackend.cpp:
+        (WebCore::ImageBufferBackend::convertToLuminanceMask):
+        (WebCore::ImageBufferBackend::getPixelBuffer const):
+        (WebCore::ImageBufferBackend::putPixelBuffer):
+        * platform/graphics/ImageBufferBackend.h:
+        * platform/graphics/PixelBufferConversion.cpp:
+        (WebCore::makeVImageCGImageFormat):
+        (WebCore::makeVImageBuffer):
+        (WebCore::convertImagePixelsAccelerated):
+        (WebCore::convertImagePixels):
+        * platform/graphics/ShadowBlur.cpp:
+        (WebCore::ShadowBlur::blurShadowBuffer):
+        * platform/graphics/cairo/ImageBufferCairoSurfaceBackend.cpp:
+        (WebCore::ImageBufferCairoSurfaceBackend::getPixelBuffer const):
+        (WebCore::ImageBufferCairoSurfaceBackend::putPixelBuffer):
+        * platform/graphics/cairo/ImageBufferCairoSurfaceBackend.h:
+        * platform/graphics/cg/ImageBufferCGBackend.cpp:
+        (WebCore::ImageBufferCGBackend::toCFData const):
+        * platform/graphics/cg/ImageBufferCGBitmapBackend.cpp:
+        (WebCore::ImageBufferCGBitmapBackend::getPixelBuffer const):
+        (WebCore::ImageBufferCGBitmapBackend::putPixelBuffer):
+        * platform/graphics/cg/ImageBufferCGBitmapBackend.h:
+        * platform/graphics/cg/ImageBufferIOSurfaceBackend.cpp:
+        (WebCore::ImageBufferIOSurfaceBackend::getPixelBuffer const):
+        (WebCore::ImageBufferIOSurfaceBackend::putPixelBuffer):
+        * platform/graphics/cg/ImageBufferIOSurfaceBackend.h:
+        * platform/graphics/displaylists/DisplayListItems.cpp:
+        (WebCore::DisplayList::PutPixelBuffer::PutPixelBuffer):
+        (WebCore::DisplayList::PutPixelBuffer::swap):
+        (WebCore::DisplayList::operator<<):
+        * platform/graphics/displaylists/DisplayListItems.h:
+        (WebCore::DisplayList::GetPixelBuffer::GetPixelBuffer):
+        (WebCore::DisplayList::GetPixelBuffer::outputFormat const):
+        (WebCore::DisplayList::PutPixelBuffer::encode const):
+        (WebCore::DisplayList::PutPixelBuffer::decode):
+        (WebCore::DisplayList::PutPixelBuffer::inputFormat const): Deleted.
+        * platform/graphics/displaylists/DisplayListRecorder.cpp:
+        (WebCore::DisplayList::Recorder::getPixelBuffer):
+        (WebCore::DisplayList::Recorder::putPixelBuffer):
+        * platform/graphics/displaylists/DisplayListRecorder.h:
+        * platform/graphics/filters/FEColorMatrix.cpp:
+        (WebCore::FEColorMatrix::platformApplySoftware):
+        * platform/graphics/filters/FEDropShadow.cpp:
+        (WebCore::FEDropShadow::platformApplySoftware):
+        * platform/graphics/filters/FilterEffect.cpp:
+        (WebCore::FilterEffect::imageBufferResult):
+        (WebCore::FilterEffect::convertPixelBufferToColorSpace):
+        (WebCore::FilterEffect::convertImageBufferToColorSpace):
+        (WebCore::FilterEffect::copyConvertedPixelBufferToDestination):
+        (WebCore::FilterEffect::copyUnmultipliedResult):
+        (WebCore::FilterEffect::copyPremultipliedResult):
+        * platform/graphics/filters/FilterEffect.h:
+        * platform/graphics/win/ImageBufferDirect2DBackend.cpp:
+        (WebCore::ImageBufferDirect2DBackend::getPixelBuffer const):
+        (WebCore::ImageBufferDirect2DBackend::putPixelBuffer):
+        * platform/graphics/win/ImageBufferDirect2DBackend.h:
+        * rendering/shapes/Shape.cpp:
+        (WebCore::Shape::createRasterShape):
+
 2021-05-14  Devin Rousso  <drou...@apple.com>
 
         Sampled Page Top Color: move logic out of `Document`

Modified: trunk/Source/WebCore/bindings/js/SerializedScriptValue.cpp (277524 => 277525)


--- trunk/Source/WebCore/bindings/js/SerializedScriptValue.cpp	2021-05-15 00:47:33 UTC (rev 277524)
+++ trunk/Source/WebCore/bindings/js/SerializedScriptValue.cpp	2021-05-15 00:59:56 UTC (rev 277525)
@@ -1075,8 +1075,9 @@
             return;
         }
 
+        PixelBufferFormat format { AlphaPremultiplication::Premultiplied, PixelFormat::RGBA8, DestinationColorSpace::SRGB };
         const IntSize& logicalSize = buffer->logicalSize();
-        auto pixelBuffer = buffer->getPixelBuffer(AlphaPremultiplication::Premultiplied, { IntPoint::zero(), logicalSize });
+        auto pixelBuffer = buffer->getPixelBuffer(format, { IntPoint::zero(), logicalSize });
         if (!pixelBuffer) {
             code = SerializationReturnCode::ValidationError;
             return;
@@ -3163,7 +3164,7 @@
             return JSValue();
         }
 
-        buffer->putPixelBuffer(AlphaPremultiplication::Premultiplied, imageData->pixelBuffer(), { IntPoint::zero(), logicalSize });
+        buffer->putPixelBuffer(imageData->pixelBuffer(), { IntPoint::zero(), logicalSize });
 
         auto bitmap = ImageBitmap::create(ImageBitmapBacking(WTFMove(buffer), OptionSet<SerializationState>::fromRaw(serializationState)));
         return getJSValue(bitmap);

Modified: trunk/Source/WebCore/html/ImageBitmap.cpp (277524 => 277525)


--- trunk/Source/WebCore/html/ImageBitmap.cpp	2021-05-15 00:47:33 UTC (rev 277524)
+++ trunk/Source/WebCore/html/ImageBitmap.cpp	2021-05-15 00:59:56 UTC (rev 277525)
@@ -807,7 +807,7 @@
     // resulting ImageBuffer directly.
     auto alphaPremultiplication = alphaPremultiplicationForPremultiplyAlpha(options.premultiplyAlpha);
     if (sourceRectangle.returnValue().location().isZero() && sourceRectangle.returnValue().size() == imageData->size() && sourceRectangle.returnValue().size() == outputSize && options.imageOrientation == ImageBitmapOptions::Orientation::None) {
-        bitmapData->putPixelBuffer(AlphaPremultiplication::Unpremultiplied, imageData->pixelBuffer(), sourceRectangle.releaseReturnValue(), { }, alphaPremultiplication);
+        bitmapData->putPixelBuffer(imageData->pixelBuffer(), sourceRectangle.releaseReturnValue(), { }, alphaPremultiplication);
         
         auto imageBitmap = create(ImageBitmapBacking(WTFMove(bitmapData)));
         // The result is implicitly origin-clean, and alpha premultiplication has already been handled.
@@ -822,7 +822,7 @@
         resolveWithBlankImageBuffer(scriptExecutionContext, true, WTFMove(promise));
         return;
     }
-    tempBitmapData->putPixelBuffer(AlphaPremultiplication::Unpremultiplied, imageData->pixelBuffer(), IntRect(0, 0, imageData->width(), imageData->height()), { }, alphaPremultiplication);
+    tempBitmapData->putPixelBuffer(imageData->pixelBuffer(), IntRect(0, 0, imageData->width(), imageData->height()), { }, alphaPremultiplication);
     FloatRect destRect(FloatPoint(), outputSize);
     bitmapData->context().drawImageBuffer(*tempBitmapData, destRect, sourceRectangle.releaseReturnValue(), { interpolationQualityForResizeQuality(options.resizeQuality), imageOrientationForOrientation(options.imageOrientation) });
 

Modified: trunk/Source/WebCore/html/canvas/CanvasRenderingContext2DBase.cpp (277524 => 277525)


--- trunk/Source/WebCore/html/canvas/CanvasRenderingContext2DBase.cpp	2021-05-15 00:47:33 UTC (rev 277524)
+++ trunk/Source/WebCore/html/canvas/CanvasRenderingContext2DBase.cpp	2021-05-15 00:59:56 UTC (rev 277525)
@@ -2199,7 +2199,8 @@
     if (!buffer)
         return createEmptyImageData(imageDataRect.size());
 
-    auto pixelBuffer = buffer->getPixelBuffer(AlphaPremultiplication::Unpremultiplied, imageDataRect);
+    PixelBufferFormat format { AlphaPremultiplication::Unpremultiplied, PixelFormat::RGBA8, DestinationColorSpace::SRGB };
+    auto pixelBuffer = buffer->getPixelBuffer(format, imageDataRect);
     if (!pixelBuffer) {
         canvasBase().scriptExecutionContext()->addConsoleMessage(MessageSource::Rendering, MessageLevel::Error,
             makeString("Unable to get image data from canvas. Requested size was ", imageDataRect.width(), " x ", imageDataRect.height()));
@@ -2246,7 +2247,7 @@
     sourceRect.intersect(IntRect { 0, 0, data.width(), data.height() });
 
     if (!sourceRect.isEmpty())
-        buffer->putPixelBuffer(AlphaPremultiplication::Unpremultiplied, data.pixelBuffer(), sourceRect, IntPoint { destOffset });
+        buffer->putPixelBuffer(data.pixelBuffer(), sourceRect, IntPoint { destOffset });
 
     didDraw(FloatRect { destRect }, { }); // ignore transform, shadow and clip
 }

Modified: trunk/Source/WebCore/page/PageConsoleClient.cpp (277524 => 277525)


--- trunk/Source/WebCore/page/PageConsoleClient.cpp	2021-05-15 00:47:33 UTC (rev 277524)
+++ trunk/Source/WebCore/page/PageConsoleClient.cpp	2021-05-15 00:59:56 UTC (rev 277525)
@@ -370,7 +370,7 @@
                 auto sourceSize = imageData->size();
                 if (auto imageBuffer = ImageBuffer::create(sourceSize, RenderingMode::Unaccelerated, 1, DestinationColorSpace::SRGB, PixelFormat::BGRA8)) {
                     IntRect sourceRect(IntPoint(), sourceSize);
-                    imageBuffer->putPixelBuffer(AlphaPremultiplication::Unpremultiplied, imageData->pixelBuffer(), sourceRect);
+                    imageBuffer->putPixelBuffer(imageData->pixelBuffer(), sourceRect);
                     dataURL = imageBuffer->toDataURL("image/png"_s, WTF::nullopt, PreserveResolution::Yes);
                 }
             }

Modified: trunk/Source/WebCore/platform/graphics/ConcreteImageBuffer.h (277524 => 277525)


--- trunk/Source/WebCore/platform/graphics/ConcreteImageBuffer.h	2021-05-15 00:47:33 UTC (rev 277524)
+++ trunk/Source/WebCore/platform/graphics/ConcreteImageBuffer.h	2021-05-15 00:59:56 UTC (rev 277525)
@@ -230,7 +230,7 @@
         return { };
     }
 
-    Optional<PixelBuffer> getPixelBuffer(AlphaPremultiplication outputFormat, const IntRect& srcRect) const override
+    Optional<PixelBuffer> getPixelBuffer(const PixelBufferFormat& outputFormat, const IntRect& srcRect) const override
     {
         if (auto* backend = ensureBackendCreated()) {
             const_cast<ConcreteImageBuffer&>(*this).flushContext();
@@ -239,11 +239,11 @@
         return WTF::nullopt;
     }
 
-    void putPixelBuffer(AlphaPremultiplication inputFormat, const PixelBuffer& pixelBuffer, const IntRect& srcRect, const IntPoint& destPoint = { }, AlphaPremultiplication destFormat = AlphaPremultiplication::Premultiplied) override
+    void putPixelBuffer(const PixelBuffer& pixelBuffer, const IntRect& srcRect, const IntPoint& destPoint = { }, AlphaPremultiplication destFormat = AlphaPremultiplication::Premultiplied) override
     {
         if (auto* backend = ensureBackendCreated()) {
             flushContext();
-            backend->putPixelBuffer(inputFormat, pixelBuffer, srcRect, destPoint, destFormat);
+            backend->putPixelBuffer(pixelBuffer, srcRect, destPoint, destFormat);
         }
     }
 

Modified: trunk/Source/WebCore/platform/graphics/ImageBuffer.h (277524 => 277525)


--- trunk/Source/WebCore/platform/graphics/ImageBuffer.h	2021-05-15 00:47:33 UTC (rev 277524)
+++ trunk/Source/WebCore/platform/graphics/ImageBuffer.h	2021-05-15 00:59:56 UTC (rev 277525)
@@ -126,8 +126,8 @@
     virtual Vector<uint8_t> toData(const String& mimeType, Optional<double> quality = WTF::nullopt) const = 0;
     virtual Vector<uint8_t> toBGRAData() const = 0;
 
-    virtual Optional<PixelBuffer> getPixelBuffer(AlphaPremultiplication outputFormat, const IntRect& srcRect) const = 0;
-    virtual void putPixelBuffer(AlphaPremultiplication inputFormat, const PixelBuffer&, const IntRect& srcRect, const IntPoint& destPoint = { }, AlphaPremultiplication destFormat = AlphaPremultiplication::Premultiplied) = 0;
+    virtual Optional<PixelBuffer> getPixelBuffer(const PixelBufferFormat& outputFormat, const IntRect& srcRect) const = 0;
+    virtual void putPixelBuffer(const PixelBuffer&, const IntRect& srcRect, const IntPoint& destPoint = { }, AlphaPremultiplication destFormat = AlphaPremultiplication::Premultiplied) = 0;
 
     // FIXME: current implementations of this method have the restriction that they only work
     // with textures that are RGB or RGBA format, and UNSIGNED_BYTE type.

Modified: trunk/Source/WebCore/platform/graphics/ImageBufferBackend.cpp (277524 => 277525)


--- trunk/Source/WebCore/platform/graphics/ImageBufferBackend.cpp	2021-05-15 00:47:33 UTC (rev 277524)
+++ trunk/Source/WebCore/platform/graphics/ImageBufferBackend.cpp	2021-05-15 00:59:56 UTC (rev 277525)
@@ -70,7 +70,8 @@
 
 void ImageBufferBackend::convertToLuminanceMask()
 {
-    auto pixelBuffer = getPixelBuffer(AlphaPremultiplication::Unpremultiplied, logicalRect());
+    PixelBufferFormat format { AlphaPremultiplication::Unpremultiplied, PixelFormat::RGBA8, DestinationColorSpace::SRGB };
+    auto pixelBuffer = getPixelBuffer(format, logicalRect());
     if (!pixelBuffer)
         return;
 
@@ -88,7 +89,7 @@
         pixelArray.set(pixelOffset + 3, luma);
     }
 
-    putPixelBuffer(AlphaPremultiplication::Unpremultiplied, *pixelBuffer, logicalRect(), IntPoint::zero(), AlphaPremultiplication::Premultiplied);
+    putPixelBuffer(*pixelBuffer, logicalRect(), IntPoint::zero(), AlphaPremultiplication::Premultiplied);
 }
 
 Vector<uint8_t> ImageBufferBackend::toBGRAData(void* data) const
@@ -113,12 +114,10 @@
     return result;
 }
 
-Optional<PixelBuffer> ImageBufferBackend::getPixelBuffer(AlphaPremultiplication destinationAlphaFormat, const IntRect& sourceRect, void* data) const
+Optional<PixelBuffer> ImageBufferBackend::getPixelBuffer(const PixelBufferFormat& destinationFormat, const IntRect& sourceRect, void* data) const
 {
     auto sourceRectScaled = toBackendCoordinates(sourceRect);
 
-    PixelBufferFormat destinationFormat { destinationAlphaFormat, PixelFormat::RGBA8, DestinationColorSpace::SRGB };
-
     auto pixelBuffer = PixelBuffer::tryCreate(destinationFormat, sourceRectScaled.size());
     if (!pixelBuffer)
         return WTF::nullopt;
@@ -158,15 +157,15 @@
     return pixelBuffer;
 }
 
-void ImageBufferBackend::putPixelBuffer(AlphaPremultiplication sourceAlphaFormat, const PixelBuffer& pixelBuffer, const IntRect& sourceRect, const IntPoint& destinationPoint, AlphaPremultiplication destinationAlphaFormat, void* data)
+void ImageBufferBackend::putPixelBuffer(const PixelBuffer& sourcePixelBuffer, const IntRect& sourceRect, const IntPoint& destinationPoint, AlphaPremultiplication destinationAlphaFormat, void* data)
 {
     // FIXME: Add support for non-RGBA8 pixel formats.
-    ASSERT(pixelBuffer.format().pixelFormat == PixelFormat::RGBA8);
+    ASSERT(sourcePixelBuffer.format().pixelFormat == PixelFormat::RGBA8);
 
     auto sourceRectScaled = toBackendCoordinates(sourceRect);
     auto destinationPointScaled = toBackendCoordinates(destinationPoint);
 
-    IntRect sourceRectClipped = intersection({ IntPoint::zero(), pixelBuffer.size() }, sourceRectScaled);
+    IntRect sourceRectClipped = intersection({ IntPoint::zero(), sourcePixelBuffer.size() }, sourceRectScaled);
     IntRect destinationRect = sourceRectClipped;
     destinationRect.moveBy(destinationPointScaled);
 
@@ -179,13 +178,13 @@
     destinationRect.intersect(backendRect());
     sourceRectClipped.setSize(destinationRect.size());
 
-    unsigned sourceBytesPerRow = 4 * pixelBuffer.size().width();
-    const uint8_t* sourceRows = pixelBuffer.data().data() + sourceRectClipped.y() * sourceBytesPerRow + sourceRectClipped.x() * 4;
+    unsigned sourceBytesPerRow = 4 * sourcePixelBuffer.size().width();
+    const uint8_t* sourceRows = sourcePixelBuffer.data().data() + sourceRectClipped.y() * sourceBytesPerRow + sourceRectClipped.x() * 4;
 
     unsigned destinationBytesPerRow = bytesPerRow();
     uint8_t* destinationRows = reinterpret_cast<uint8_t*>(data) + destinationRect.y() * destinationBytesPerRow + destinationRect.x() * 4;
 
-    PixelBufferFormat sourceFormat { sourceAlphaFormat, PixelFormat::RGBA8, DestinationColorSpace::SRGB };
+    PixelBufferFormat sourceFormat = sourcePixelBuffer.format();
     PixelBufferFormat destinationFormat { destinationAlphaFormat, pixelFormat(), DestinationColorSpace::SRGB };
 
     ConstPixelBufferConversionView source;

Modified: trunk/Source/WebCore/platform/graphics/ImageBufferBackend.h (277524 => 277525)


--- trunk/Source/WebCore/platform/graphics/ImageBufferBackend.h	2021-05-15 00:47:33 UTC (rev 277524)
+++ trunk/Source/WebCore/platform/graphics/ImageBufferBackend.h	2021-05-15 00:59:56 UTC (rev 277525)
@@ -25,13 +25,12 @@
 
 #pragma once
 
-#include "AlphaPremultiplication.h"
 #include "ColorSpace.h"
 #include "FloatRect.h"
 #include "GraphicsTypesGL.h"
 #include "ImagePaintingOptions.h"
 #include "IntRect.h"
-#include "PixelFormat.h"
+#include "PixelBufferFormat.h"
 #include "PlatformLayer.h"
 #include "RenderingMode.h"
 #include <wtf/RefPtr.h>
@@ -109,8 +108,8 @@
     virtual Vector<uint8_t> toData(const String& mimeType, Optional<double> quality) const = 0;
     virtual Vector<uint8_t> toBGRAData() const = 0;
 
-    virtual Optional<PixelBuffer> getPixelBuffer(AlphaPremultiplication outputFormat, const IntRect&) const = 0;
-    virtual void putPixelBuffer(AlphaPremultiplication inputFormat, const PixelBuffer&, const IntRect& srcRect, const IntPoint& destPoint, AlphaPremultiplication destFormat) = 0;
+    virtual Optional<PixelBuffer> getPixelBuffer(const PixelBufferFormat& outputFormat, const IntRect&) const = 0;
+    virtual void putPixelBuffer(const PixelBuffer&, const IntRect& srcRect, const IntPoint& destPoint, AlphaPremultiplication destFormat) = 0;
 
     virtual PlatformLayer* platformLayer() const { return nullptr; }
     virtual bool copyToPlatformTexture(GraphicsContextGL&, GCGLenum, PlatformGLObject, GCGLenum, bool, bool) const { return false; }
@@ -150,8 +149,8 @@
 
     WEBCORE_EXPORT Vector<uint8_t> toBGRAData(void* data) const;
 
-    WEBCORE_EXPORT Optional<PixelBuffer> getPixelBuffer(AlphaPremultiplication outputFormat, const IntRect& srcRect, void* data) const;
-    WEBCORE_EXPORT void putPixelBuffer(AlphaPremultiplication inputFormat, const PixelBuffer&, const IntRect& srcRect, const IntPoint& destPoint, AlphaPremultiplication destFormat, void* data);
+    WEBCORE_EXPORT Optional<PixelBuffer> getPixelBuffer(const PixelBufferFormat& outputFormat, const IntRect& srcRect, void* data) const;
+    WEBCORE_EXPORT void putPixelBuffer(const PixelBuffer&, const IntRect& srcRect, const IntPoint& destPoint, AlphaPremultiplication destFormat, void* data);
 
     Parameters m_parameters;
 };

Modified: trunk/Source/WebCore/platform/graphics/PixelBufferConversion.cpp (277524 => 277525)


--- trunk/Source/WebCore/platform/graphics/PixelBufferConversion.cpp	2021-05-15 00:47:33 UTC (rev 277524)
+++ trunk/Source/WebCore/platform/graphics/PixelBufferConversion.cpp	2021-05-15 00:59:56 UTC (rev 277525)
@@ -31,24 +31,65 @@
 #include "IntSize.h"
 #include "PixelFormat.h"
 
-#if USE(ACCELERATE)
+#if USE(ACCELERATE) && USE(CG)
+#include "ColorSpaceCG.h"
 #include <Accelerate/Accelerate.h>
 #endif
 
 namespace WebCore {
 
-#if USE(ACCELERATE)
+#if USE(ACCELERATE) && USE(CG)
 
+static inline vImage_CGImageFormat makeVImageCGImageFormat(const PixelBufferFormat& format)
+{
+    auto [bitsPerComponent, bitsPerPixel, bitmapInfo] = [] (const PixelBufferFormat& format) -> std::tuple<unsigned, unsigned, CGBitmapInfo> {
+        switch (format.pixelFormat) {
+        case PixelFormat::RGBA8:
+            if (format.alphaFormat == AlphaPremultiplication::Premultiplied)
+                return std::make_tuple(8u, 32u, kCGBitmapByteOrder32Big | kCGImageAlphaPremultipliedLast);
+            else
+                return std::make_tuple(8u, 32u, kCGBitmapByteOrder32Big | kCGImageAlphaLast);
+
+        case PixelFormat::BGRA8:
+            if (format.alphaFormat == AlphaPremultiplication::Premultiplied)
+                return std::make_tuple(8u, 32u, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst);
+            else
+                return std::make_tuple(8u, 32u, kCGBitmapByteOrder32Little | kCGImageAlphaFirst);
+
+        case PixelFormat::RGB10:
+        case PixelFormat::RGB10A8:
+            break;
+        }
+
+        // We currently only support 8 bit pixel formats for these conversions.
+
+        ASSERT_NOT_REACHED();
+        return std::make_tuple(8u, 32u, kCGBitmapByteOrder32Little | kCGImageAlphaFirst);
+    }(format);
+
+    vImage_CGImageFormat result;
+
+    result.bitsPerComponent = bitsPerComponent;
+    result.bitsPerPixel = bitsPerPixel;
+    result.colorSpace = cachedCGColorSpace(format.colorSpace);
+    result.bitmapInfo = bitmapInfo;
+    result.version = 0;
+    result.decode = nullptr;
+    result.renderingIntent = kCGRenderingIntentDefault;
+
+    return result;
+}
+
 template<typename View> static vImage_Buffer makeVImageBuffer(const View& view, const IntSize& size)
 {
-    vImage_Buffer vImageBuffer;
+    vImage_Buffer result;
 
-    vImageBuffer.height = static_cast<vImagePixelCount>(size.height());
-    vImageBuffer.width = static_cast<vImagePixelCount>(size.width());
-    vImageBuffer.rowBytes = view.bytesPerRow;
-    vImageBuffer.data = ""
+    result.height = static_cast<vImagePixelCount>(size.height());
+    result.width = static_cast<vImagePixelCount>(size.width());
+    result.rowBytes = view.bytesPerRow;
+    result.data = ""
 
-    return vImageBuffer;
+    return result;
 }
 
 static void convertImagePixelsAccelerated(const ConstPixelBufferConversionView& source, const PixelBufferConversionView& destination, const IntSize& destinationSize)
@@ -56,6 +97,22 @@
     auto sourceVImageBuffer = makeVImageBuffer(source, destinationSize);
     auto destinationVImageBuffer = makeVImageBuffer(destination, destinationSize);
 
+    if (source.format.colorSpace != destination.format.colorSpace) {
+        // FIXME: Consider using vImageConvert_AnyToAny for all conversions, not just ones that need a color space conversion,
+        // after judiciously performance testing them against each other.
+
+        auto sourceCGImageFormat = makeVImageCGImageFormat(source.format);
+        auto destinationCGImageFormat = makeVImageCGImageFormat(destination.format);
+
+        vImage_Error converterCreateError = kvImageNoError;
+        auto converter = adoptCF(vImageConverter_CreateWithCGImageFormat(&sourceCGImageFormat, &destinationCGImageFormat, nullptr, kvImageNoFlags, &converterCreateError));
+        ASSERT_WITH_MESSAGE_UNUSED(converterCreateError, converterCreateError != kvImageNoError, "vImageConverter creation failed with error: %zd", converterCreateError);
+
+        vImage_Error converterConvertError = vImageConvert_AnyToAny(converter.get(), &sourceVImageBuffer, &destinationVImageBuffer, nullptr, kvImageNoFlags);
+        ASSERT_WITH_MESSAGE_UNUSED(converterConvertError, converterConvertError == kvImageNoError, "vImageConvert_AnyToAny failed conversion with error: %zd", converterConvertError);
+        return;
+    }
+
     if (source.format.alphaFormat != destination.format.alphaFormat) {
         if (destination.format.alphaFormat == AlphaPremultiplication::Unpremultiplied) {
             if (source.format.pixelFormat == PixelFormat::RGBA8)
@@ -184,10 +241,7 @@
     ASSERT(source.format.pixelFormat == PixelFormat::RGBA8 || source.format.pixelFormat == PixelFormat::BGRA8);
     ASSERT(destination.format.pixelFormat == PixelFormat::RGBA8 || destination.format.pixelFormat == PixelFormat::BGRA8);
 
-    // We don't currently support converting pixel data between different color spaces.
-    ASSERT(source.format.colorSpace == destination.format.colorSpace);
-
-#if USE(ACCELERATE)
+#if USE(ACCELERATE) && USE(CG)
     if (source.format.alphaFormat == destination.format.alphaFormat && source.format.pixelFormat == destination.format.pixelFormat) {
         // FIXME: Can thes both just use per-row memcpy?
         if (source.format.alphaFormat == AlphaPremultiplication::Premultiplied)
@@ -197,6 +251,10 @@
     } else
         convertImagePixelsAccelerated(source, destination, destinationSize);
 #else
+    // FIXME: We don't currently support converting pixel data between different color spaces in the non-accelerated path.
+    // This could be added using conversion functions from ColorConversion.h.
+    ASSERT(source.format.colorSpace == destination.format.colorSpace);
+
     if (source.format.alphaFormat == destination.format.alphaFormat) {
         if (source.format.pixelFormat == destination.format.pixelFormat) {
             if (source.format.alphaFormat == AlphaPremultiplication::Premultiplied)

Modified: trunk/Source/WebCore/platform/graphics/ShadowBlur.cpp (277524 => 277525)


--- trunk/Source/WebCore/platform/graphics/ShadowBlur.cpp	2021-05-15 00:47:33 UTC (rev 277524)
+++ trunk/Source/WebCore/platform/graphics/ShadowBlur.cpp	2021-05-15 00:59:56 UTC (rev 277525)
@@ -903,13 +903,14 @@
     if (m_type != BlurShadow)
         return;
 
+    PixelBufferFormat format { AlphaPremultiplication::Unpremultiplied, PixelFormat::RGBA8, DestinationColorSpace::SRGB };
     IntRect blurRect(IntPoint(), templateSize);
-    auto layerData = layerImage.getPixelBuffer(AlphaPremultiplication::Unpremultiplied, blurRect);
+    auto layerData = layerImage.getPixelBuffer(format, blurRect);
     if (!layerData)
         return;
 
     blurLayerImage(layerData->data().data(), blurRect.size(), blurRect.width() * 4);
-    layerImage.putPixelBuffer(AlphaPremultiplication::Unpremultiplied, *layerData, blurRect);
+    layerImage.putPixelBuffer(*layerData, blurRect);
 }
 
 void ShadowBlur::blurAndColorShadowBuffer(ImageBuffer& layerImage, const IntSize& templateSize)

Modified: trunk/Source/WebCore/platform/graphics/cairo/ImageBufferCairoSurfaceBackend.cpp (277524 => 277525)


--- trunk/Source/WebCore/platform/graphics/cairo/ImageBufferCairoSurfaceBackend.cpp	2021-05-15 00:47:33 UTC (rev 277524)
+++ trunk/Source/WebCore/platform/graphics/cairo/ImageBufferCairoSurfaceBackend.cpp	2021-05-15 00:59:56 UTC (rev 277525)
@@ -120,14 +120,14 @@
     return imageData;
 }
 
-Optional<PixelBuffer> ImageBufferCairoSurfaceBackend::getPixelBuffer(AlphaPremultiplication outputFormat, const IntRect& srcRect) const
+Optional<PixelBuffer> ImageBufferCairoSurfaceBackend::getPixelBuffer(const PixelBufferFormat& outputFormat, const IntRect& srcRect) const
 {
     return ImageBufferBackend::getPixelBuffer(outputFormat, srcRect, cairo_image_surface_get_data(m_surface.get()));
 }
 
-void ImageBufferCairoSurfaceBackend::putPixelBuffer(AlphaPremultiplication inputFormat, const PixelBuffer& pixelBuffer, const IntRect& srcRect, const IntPoint& destPoint, AlphaPremultiplication destFormat)
+void ImageBufferCairoSurfaceBackend::putPixelBuffer(const PixelBuffer& pixelBuffer, const IntRect& srcRect, const IntPoint& destPoint, AlphaPremultiplication destFormat)
 {
-    ImageBufferBackend::putPixelBuffer(inputFormat, pixelBuffer, srcRect, destPoint, destFormat, cairo_image_surface_get_data(m_surface.get()));
+    ImageBufferBackend::putPixelBuffer(pixelBuffer, srcRect, destPoint, destFormat, cairo_image_surface_get_data(m_surface.get()));
 
     IntRect srcRectScaled = toBackendCoordinates(srcRect);
     IntPoint destPointScaled = toBackendCoordinates(destPoint);

Modified: trunk/Source/WebCore/platform/graphics/cairo/ImageBufferCairoSurfaceBackend.h (277524 => 277525)


--- trunk/Source/WebCore/platform/graphics/cairo/ImageBufferCairoSurfaceBackend.h	2021-05-15 00:47:33 UTC (rev 277524)
+++ trunk/Source/WebCore/platform/graphics/cairo/ImageBufferCairoSurfaceBackend.h	2021-05-15 00:59:56 UTC (rev 277525)
@@ -45,8 +45,8 @@
     RefPtr<NativeImage> copyNativeImage(BackingStoreCopy) const override;
 
     Vector<uint8_t> toBGRAData() const override;
-    Optional<PixelBuffer> getPixelBuffer(AlphaPremultiplication outputFormat, const IntRect&) const override;
-    void putPixelBuffer(AlphaPremultiplication inputFormat, const PixelBuffer&, const IntRect& srcRect, const IntPoint& destPoint, AlphaPremultiplication destFormat) override;
+    Optional<PixelBuffer> getPixelBuffer(const PixelBufferFormat& outputFormat, const IntRect&) const override;
+    void putPixelBuffer(const PixelBuffer&, const IntRect& srcRect, const IntPoint& destPoint, AlphaPremultiplication destFormat) override;
 
 protected:
     ImageBufferCairoSurfaceBackend(const Parameters&, RefPtr<cairo_surface_t>&&);

Modified: trunk/Source/WebCore/platform/graphics/cg/ImageBufferCGBackend.cpp (277524 => 277525)


--- trunk/Source/WebCore/platform/graphics/cg/ImageBufferCGBackend.cpp	2021-05-15 00:47:33 UTC (rev 277524)
+++ trunk/Source/WebCore/platform/graphics/cg/ImageBufferCGBackend.cpp	2021-05-15 00:59:56 UTC (rev 277525)
@@ -183,7 +183,8 @@
 
     if (CFEqual(uti.get(), jpegUTI())) {
         // JPEGs don't have an alpha channel, so we have to manually composite on top of black.
-        auto pixelBuffer = getPixelBuffer(AlphaPremultiplication::Premultiplied, logicalRect());
+        PixelBufferFormat format { AlphaPremultiplication::Premultiplied, PixelFormat::RGBA8, DestinationColorSpace::SRGB };
+        auto pixelBuffer = getPixelBuffer(format, logicalRect());
         if (!pixelBuffer)
             return nullptr;
 

Modified: trunk/Source/WebCore/platform/graphics/cg/ImageBufferCGBitmapBackend.cpp (277524 => 277525)


--- trunk/Source/WebCore/platform/graphics/cg/ImageBufferCGBitmapBackend.cpp	2021-05-15 00:47:33 UTC (rev 277524)
+++ trunk/Source/WebCore/platform/graphics/cg/ImageBufferCGBitmapBackend.cpp	2021-05-15 00:59:56 UTC (rev 277525)
@@ -159,14 +159,14 @@
     return ImageBufferBackend::toBGRAData(m_data);
 }
 
-Optional<PixelBuffer> ImageBufferCGBitmapBackend::getPixelBuffer(AlphaPremultiplication outputFormat, const IntRect& srcRect) const
+Optional<PixelBuffer> ImageBufferCGBitmapBackend::getPixelBuffer(const PixelBufferFormat& outputFormat, const IntRect& srcRect) const
 {
     return ImageBufferBackend::getPixelBuffer(outputFormat, srcRect, m_data);
 }
 
-void ImageBufferCGBitmapBackend::putPixelBuffer(AlphaPremultiplication inputFormat, const PixelBuffer& pixelBuffer, const IntRect& srcRect, const IntPoint& destPoint, AlphaPremultiplication destFormat)
+void ImageBufferCGBitmapBackend::putPixelBuffer(const PixelBuffer& pixelBuffer, const IntRect& srcRect, const IntPoint& destPoint, AlphaPremultiplication destFormat)
 {
-    ImageBufferBackend::putPixelBuffer(inputFormat, pixelBuffer, srcRect, destPoint, destFormat, m_data);
+    ImageBufferBackend::putPixelBuffer(pixelBuffer, srcRect, destPoint, destFormat, m_data);
 }
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/platform/graphics/cg/ImageBufferCGBitmapBackend.h (277524 => 277525)


--- trunk/Source/WebCore/platform/graphics/cg/ImageBufferCGBitmapBackend.h	2021-05-15 00:47:33 UTC (rev 277524)
+++ trunk/Source/WebCore/platform/graphics/cg/ImageBufferCGBitmapBackend.h	2021-05-15 00:59:56 UTC (rev 277525)
@@ -51,8 +51,8 @@
 
     Vector<uint8_t> toBGRAData() const override;
 
-    Optional<PixelBuffer> getPixelBuffer(AlphaPremultiplication outputFormat, const IntRect&) const override;
-    void putPixelBuffer(AlphaPremultiplication inputFormat, const PixelBuffer&, const IntRect& srcRect, const IntPoint& destPoint, AlphaPremultiplication destFormat) override;
+    Optional<PixelBuffer> getPixelBuffer(const PixelBufferFormat& outputFormat, const IntRect&) const override;
+    void putPixelBuffer(const PixelBuffer&, const IntRect& srcRect, const IntPoint& destPoint, AlphaPremultiplication destFormat) override;
 
     static constexpr bool isOriginAtUpperLeftCorner = true;
 

Modified: trunk/Source/WebCore/platform/graphics/cg/ImageBufferIOSurfaceBackend.cpp (277524 => 277525)


--- trunk/Source/WebCore/platform/graphics/cg/ImageBufferIOSurfaceBackend.cpp	2021-05-15 00:47:33 UTC (rev 277524)
+++ trunk/Source/WebCore/platform/graphics/cg/ImageBufferIOSurfaceBackend.cpp	2021-05-15 00:59:56 UTC (rev 277525)
@@ -183,16 +183,16 @@
     return ImageBufferBackend::toBGRAData(lock.surfaceBaseAddress());
 }
 
-Optional<PixelBuffer> ImageBufferIOSurfaceBackend::getPixelBuffer(AlphaPremultiplication outputFormat, const IntRect& srcRect) const
+Optional<PixelBuffer> ImageBufferIOSurfaceBackend::getPixelBuffer(const PixelBufferFormat& outputFormat, const IntRect& srcRect) const
 {
     IOSurface::Locker lock(*m_surface);
     return ImageBufferBackend::getPixelBuffer(outputFormat, srcRect, lock.surfaceBaseAddress());
 }
 
-void ImageBufferIOSurfaceBackend::putPixelBuffer(AlphaPremultiplication inputFormat, const PixelBuffer& pixelBuffer, const IntRect& srcRect, const IntPoint& destPoint, AlphaPremultiplication destFormat)
+void ImageBufferIOSurfaceBackend::putPixelBuffer(const PixelBuffer& pixelBuffer, const IntRect& srcRect, const IntPoint& destPoint, AlphaPremultiplication destFormat)
 {
     IOSurface::Locker lock(*m_surface, IOSurface::Locker::AccessMode::ReadWrite);
-    ImageBufferBackend::putPixelBuffer(inputFormat, pixelBuffer, srcRect, destPoint, destFormat, lock.surfaceBaseAddress());
+    ImageBufferBackend::putPixelBuffer(pixelBuffer, srcRect, destPoint, destFormat, lock.surfaceBaseAddress());
     m_requiresDrawAfterPutPixelBuffer = true;
 }
 

Modified: trunk/Source/WebCore/platform/graphics/cg/ImageBufferIOSurfaceBackend.h (277524 => 277525)


--- trunk/Source/WebCore/platform/graphics/cg/ImageBufferIOSurfaceBackend.h	2021-05-15 00:47:33 UTC (rev 277524)
+++ trunk/Source/WebCore/platform/graphics/cg/ImageBufferIOSurfaceBackend.h	2021-05-15 00:59:56 UTC (rev 277525)
@@ -63,8 +63,8 @@
     RetainPtr<CFDataRef> toCFData(const String& mimeType, Optional<double> quality, PreserveResolution) const override;
     Vector<uint8_t> toBGRAData() const override;
 
-    Optional<PixelBuffer> getPixelBuffer(AlphaPremultiplication outputFormat, const IntRect&) const override;
-    void putPixelBuffer(AlphaPremultiplication inputFormat, const PixelBuffer&, const IntRect& srcRect, const IntPoint& destPoint, AlphaPremultiplication destFormat) override;
+    Optional<PixelBuffer> getPixelBuffer(const PixelBufferFormat& outputFormat, const IntRect&) const override;
+    void putPixelBuffer(const PixelBuffer&, const IntRect& srcRect, const IntPoint& destPoint, AlphaPremultiplication destFormat) override;
 
     bool isInUse() const override;
     void releaseGraphicsContext() override;

Modified: trunk/Source/WebCore/platform/graphics/displaylists/DisplayListItems.cpp (277524 => 277525)


--- trunk/Source/WebCore/platform/graphics/displaylists/DisplayListItems.cpp	2021-05-15 00:47:33 UTC (rev 277524)
+++ trunk/Source/WebCore/platform/graphics/displaylists/DisplayListItems.cpp	2021-05-15 00:59:56 UTC (rev 277525)
@@ -775,20 +775,18 @@
     return ts;
 }
 
-PutPixelBuffer::PutPixelBuffer(AlphaPremultiplication inputFormat, const PixelBuffer& pixelBuffer, const IntRect& srcRect, const IntPoint& destPoint, AlphaPremultiplication destFormat)
+PutPixelBuffer::PutPixelBuffer(const PixelBuffer& pixelBuffer, const IntRect& srcRect, const IntPoint& destPoint, AlphaPremultiplication destFormat)
     : m_srcRect(srcRect)
     , m_destPoint(destPoint)
     , m_pixelBuffer(pixelBuffer.deepClone()) // This copy is actually required to preserve the semantics of putPixelBuffer().
-    , m_inputFormat(inputFormat)
     , m_destFormat(destFormat)
 {
 }
 
-PutPixelBuffer::PutPixelBuffer(AlphaPremultiplication inputFormat, PixelBuffer&& pixelBuffer, const IntRect& srcRect, const IntPoint& destPoint, AlphaPremultiplication destFormat)
+PutPixelBuffer::PutPixelBuffer(PixelBuffer&& pixelBuffer, const IntRect& srcRect, const IntPoint& destPoint, AlphaPremultiplication destFormat)
     : m_srcRect(srcRect)
     , m_destPoint(destPoint)
     , m_pixelBuffer(WTFMove(pixelBuffer))
-    , m_inputFormat(inputFormat)
     , m_destFormat(destFormat)
 {
 }
@@ -797,7 +795,6 @@
     : m_srcRect(other.m_srcRect)
     , m_destPoint(other.m_destPoint)
     , m_pixelBuffer(other.m_pixelBuffer.deepClone())
-    , m_inputFormat(other.m_inputFormat)
     , m_destFormat(other.m_destFormat)
 {
 }
@@ -814,13 +811,11 @@
     std::swap(m_srcRect, other.m_srcRect);
     std::swap(m_destPoint, other.m_destPoint);
     std::swap(m_pixelBuffer, other.m_pixelBuffer);
-    std::swap(m_inputFormat, other.m_inputFormat);
     std::swap(m_destFormat, other.m_destFormat);
 }
 
 static TextStream& operator<<(TextStream& ts, const PutPixelBuffer& item)
 {
-    ts.dumpProperty("inputFormat", item.inputFormat());
     ts.dumpProperty("pixelBufferSize", item.pixelBuffer().size());
     ts.dumpProperty("srcRect", item.srcRect());
     ts.dumpProperty("destPoint", item.destPoint());

Modified: trunk/Source/WebCore/platform/graphics/displaylists/DisplayListItems.h (277524 => 277525)


--- trunk/Source/WebCore/platform/graphics/displaylists/DisplayListItems.h	2021-05-15 00:47:33 UTC (rev 277524)
+++ trunk/Source/WebCore/platform/graphics/displaylists/DisplayListItems.h	2021-05-15 00:59:56 UTC (rev 277525)
@@ -1905,18 +1905,18 @@
     static constexpr bool isInlineItem = true;
     static constexpr bool isDrawingItem = false;
 
-    GetPixelBuffer(WebCore::AlphaPremultiplication outputFormat, const WebCore::IntRect& srcRect)
+    GetPixelBuffer(WebCore::PixelBufferFormat outputFormat, const WebCore::IntRect& srcRect)
         : m_srcRect(srcRect)
         , m_outputFormat(outputFormat)
     {
     }
 
-    AlphaPremultiplication outputFormat() const { return m_outputFormat; }
+    PixelBufferFormat outputFormat() const { return m_outputFormat; }
     IntRect srcRect() const { return m_srcRect; }
 
 private:
     IntRect m_srcRect;
-    AlphaPremultiplication m_outputFormat;
+    PixelBufferFormat m_outputFormat;
 };
 
 class PutPixelBuffer {
@@ -1925,8 +1925,8 @@
     static constexpr bool isInlineItem = false;
     static constexpr bool isDrawingItem = true;
 
-    WEBCORE_EXPORT PutPixelBuffer(AlphaPremultiplication inputFormat, const PixelBuffer&, const IntRect& srcRect, const IntPoint& destPoint, AlphaPremultiplication destFormat);
-    WEBCORE_EXPORT PutPixelBuffer(AlphaPremultiplication inputFormat, PixelBuffer&&, const IntRect& srcRect, const IntPoint& destPoint, AlphaPremultiplication destFormat);
+    WEBCORE_EXPORT PutPixelBuffer(const PixelBuffer&, const IntRect& srcRect, const IntPoint& destPoint, AlphaPremultiplication destFormat);
+    WEBCORE_EXPORT PutPixelBuffer(PixelBuffer&&, const IntRect& srcRect, const IntPoint& destPoint, AlphaPremultiplication destFormat);
 
     PutPixelBuffer(const PutPixelBuffer&);
     PutPixelBuffer(PutPixelBuffer&&) = default;
@@ -1935,7 +1935,6 @@
 
     void swap(PutPixelBuffer&);
 
-    AlphaPremultiplication inputFormat() const { return m_inputFormat; }
     const PixelBuffer& pixelBuffer() const { return m_pixelBuffer; }
     IntRect srcRect() const { return m_srcRect; }
     IntPoint destPoint() const { return m_destPoint; }
@@ -1951,7 +1950,6 @@
     IntRect m_srcRect;
     IntPoint m_destPoint;
     PixelBuffer m_pixelBuffer;
-    AlphaPremultiplication m_inputFormat;
     AlphaPremultiplication m_destFormat;
 };
 
@@ -1958,7 +1956,6 @@
 template<class Encoder>
 void PutPixelBuffer::encode(Encoder& encoder) const
 {
-    encoder << m_inputFormat;
     encoder << m_pixelBuffer;
     encoder << m_srcRect;
     encoder << m_destPoint;
@@ -1968,16 +1965,11 @@
 template<class Decoder>
 Optional<PutPixelBuffer> PutPixelBuffer::decode(Decoder& decoder)
 {
-    Optional<AlphaPremultiplication> inputFormat;
     Optional<PixelBuffer> pixelBuffer;
     Optional<IntRect> srcRect;
     Optional<IntPoint> destPoint;
     Optional<AlphaPremultiplication> destFormat;
 
-    decoder >> inputFormat;
-    if (!inputFormat)
-        return WTF::nullopt;
-
     decoder >> pixelBuffer;
     if (!pixelBuffer)
         return WTF::nullopt;
@@ -1994,7 +1986,7 @@
     if (!destFormat)
         return WTF::nullopt;
 
-    return {{ *inputFormat, WTFMove(*pixelBuffer), *srcRect, *destPoint, *destFormat }};
+    return {{ WTFMove(*pixelBuffer), *srcRect, *destPoint, *destFormat }};
 }
 
 #if ENABLE(VIDEO)

Modified: trunk/Source/WebCore/platform/graphics/displaylists/DisplayListRecorder.cpp (277524 => 277525)


--- trunk/Source/WebCore/platform/graphics/displaylists/DisplayListRecorder.cpp	2021-05-15 00:47:33 UTC (rev 277524)
+++ trunk/Source/WebCore/platform/graphics/displaylists/DisplayListRecorder.cpp	2021-05-15 00:59:56 UTC (rev 277525)
@@ -55,14 +55,14 @@
     LOG(DisplayLists, "Recorded display list:\n%s", m_displayList.description().data());
 }
 
-void Recorder::getPixelBuffer(AlphaPremultiplication outputFormat, const IntRect& sourceRect)
+void Recorder::getPixelBuffer(const PixelBufferFormat& outputFormat, const IntRect& sourceRect)
 {
     append<GetPixelBuffer>(outputFormat, sourceRect);
 }
 
-void Recorder::putPixelBuffer(WebCore::AlphaPremultiplication inputFormat, const WebCore::PixelBuffer& pixelBuffer, const WebCore::IntRect& srcRect, const WebCore::IntPoint& destPoint, WebCore::AlphaPremultiplication destFormat)
+void Recorder::putPixelBuffer(const WebCore::PixelBuffer& pixelBuffer, const WebCore::IntRect& srcRect, const WebCore::IntPoint& destPoint, WebCore::AlphaPremultiplication destFormat)
 {
-    append<PutPixelBuffer>(inputFormat, pixelBuffer, srcRect, destPoint, destFormat);
+    append<PutPixelBuffer>(pixelBuffer, srcRect, destPoint, destFormat);
 }
 
 static bool containsOnlyInlineStateChanges(const GraphicsContextStateChange& changes, GraphicsContextState::StateChangeFlags changeFlags)

Modified: trunk/Source/WebCore/platform/graphics/displaylists/DisplayListRecorder.h (277524 => 277525)


--- trunk/Source/WebCore/platform/graphics/displaylists/DisplayListRecorder.h	2021-05-15 00:47:33 UTC (rev 277524)
+++ trunk/Source/WebCore/platform/graphics/displaylists/DisplayListRecorder.h	2021-05-15 00:59:56 UTC (rev 277525)
@@ -58,8 +58,8 @@
     WEBCORE_EXPORT Recorder(GraphicsContext&, DisplayList&, const GraphicsContextState&, const FloatRect& initialClip, const AffineTransform&, Delegate* = nullptr, DrawGlyphsRecorder::DrawGlyphsDeconstruction = DrawGlyphsRecorder::DrawGlyphsDeconstruction::Deconstruct);
     WEBCORE_EXPORT virtual ~Recorder();
 
-    WEBCORE_EXPORT void getPixelBuffer(AlphaPremultiplication outputFormat, const IntRect& sourceRect);
-    WEBCORE_EXPORT void putPixelBuffer(AlphaPremultiplication inputFormat, const PixelBuffer&, const IntRect& srcRect, const IntPoint& destPoint, AlphaPremultiplication destFormat);
+    WEBCORE_EXPORT void getPixelBuffer(const PixelBufferFormat& outputFormat, const IntRect& sourceRect);
+    WEBCORE_EXPORT void putPixelBuffer(const PixelBuffer&, const IntRect& srcRect, const IntPoint& destPoint, AlphaPremultiplication destFormat);
 
     bool isEmpty() const { return m_displayList.isEmpty(); }
 

Modified: trunk/Source/WebCore/platform/graphics/filters/FEColorMatrix.cpp (277524 => 277525)


--- trunk/Source/WebCore/platform/graphics/filters/FEColorMatrix.cpp	2021-05-15 00:47:33 UTC (rev 277524)
+++ trunk/Source/WebCore/platform/graphics/filters/FEColorMatrix.cpp	2021-05-15 00:59:56 UTC (rev 277525)
@@ -285,8 +285,9 @@
     if (inBuffer)
         resultImage->context().drawImageBuffer(*inBuffer, drawingRegionOfInputImage(in->absolutePaintRect()));
 
+    PixelBufferFormat format { AlphaPremultiplication::Unpremultiplied, PixelFormat::RGBA8, DestinationColorSpace::SRGB };
     IntRect imageRect(IntPoint(), resultImage->logicalSize());
-    auto pixelBuffer = resultImage->getPixelBuffer(AlphaPremultiplication::Unpremultiplied, imageRect);
+    auto pixelBuffer = resultImage->getPixelBuffer(format, imageRect);
     if (!pixelBuffer)
         return;
 
@@ -313,7 +314,7 @@
         break;
     }
 
-    resultImage->putPixelBuffer(AlphaPremultiplication::Unpremultiplied, *pixelBuffer, imageRect);
+    resultImage->putPixelBuffer(*pixelBuffer, imageRect);
 }
 
 static TextStream& operator<<(TextStream& ts, const ColorMatrixType& type)

Modified: trunk/Source/WebCore/platform/graphics/filters/FEDropShadow.cpp (277524 => 277525)


--- trunk/Source/WebCore/platform/graphics/filters/FEDropShadow.cpp	2021-05-15 00:47:33 UTC (rev 277524)
+++ trunk/Source/WebCore/platform/graphics/filters/FEDropShadow.cpp	2021-05-15 00:59:56 UTC (rev 277525)
@@ -99,8 +99,9 @@
 
     ShadowBlur contextShadow(blurRadius, offset, m_shadowColor);
 
+    PixelBufferFormat format { AlphaPremultiplication::Premultiplied, PixelFormat::RGBA8, DestinationColorSpace::SRGB };
     IntRect shadowArea(IntPoint(), resultImage->logicalSize());
-    auto pixelBuffer = resultImage->getPixelBuffer(AlphaPremultiplication::Premultiplied, shadowArea);
+    auto pixelBuffer = resultImage->getPixelBuffer(format, shadowArea);
     if (!pixelBuffer)
         return;
 
@@ -107,7 +108,7 @@
     auto& sourcePixelArray = pixelBuffer->data();
     contextShadow.blurLayerImage(sourcePixelArray.data(), pixelBuffer->size(), 4 * pixelBuffer->size().width());
     
-    resultImage->putPixelBuffer(AlphaPremultiplication::Premultiplied, *pixelBuffer, shadowArea);
+    resultImage->putPixelBuffer(*pixelBuffer, shadowArea);
 
     resultContext.setCompositeOperation(CompositeOperator::SourceIn);
     resultContext.fillRect(FloatRect(FloatPoint(), absolutePaintRect().size()), m_shadowColor);

Modified: trunk/Source/WebCore/platform/graphics/filters/FilterEffect.cpp (277524 => 277525)


--- trunk/Source/WebCore/platform/graphics/filters/FilterEffect.cpp	2021-05-15 00:47:33 UTC (rev 277524)
+++ trunk/Source/WebCore/platform/graphics/filters/FilterEffect.cpp	2021-05-15 00:59:56 UTC (rev 277525)
@@ -279,9 +279,9 @@
 
     IntRect destinationRect(IntPoint(), m_absolutePaintRect.size());
     if (m_premultipliedImageResult)
-        m_imageBufferResult->putPixelBuffer(AlphaPremultiplication::Premultiplied, *m_premultipliedImageResult, destinationRect);
+        m_imageBufferResult->putPixelBuffer(*m_premultipliedImageResult, destinationRect);
     else
-        m_imageBufferResult->putPixelBuffer(AlphaPremultiplication::Unpremultiplied, *m_unmultipliedImageResult, destinationRect);
+        m_imageBufferResult->putPixelBuffer(*m_unmultipliedImageResult, destinationRect);
     return m_imageBufferResult.get();
 }
 
@@ -439,7 +439,7 @@
 #endif
 }
 
-Optional<PixelBuffer> FilterEffect::convertPixelBufferToColorSpace(DestinationColorSpace targetColorSpace, PixelBuffer& pixelBuffer, AlphaPremultiplication outputFormat)
+Optional<PixelBuffer> FilterEffect::convertPixelBufferToColorSpace(DestinationColorSpace targetColorSpace, PixelBuffer& pixelBuffer)
 {
     // FIXME: Using an ImageBuffer to perform the color space conversion is unnecessary. We can do it directly.
 
@@ -450,20 +450,26 @@
     auto buffer = ImageBuffer::create(clampedSize, m_filter.renderingMode(), m_filter.filterScale(), operatingColorSpace(), PixelFormat::BGRA8);
     if (!buffer)
         return WTF::nullopt;
-    buffer->putPixelBuffer(outputFormat, pixelBuffer, destinationRect);
-    return convertImageBufferToColorSpace(targetColorSpace, *buffer, destinationRect, outputFormat);
+    buffer->putPixelBuffer(pixelBuffer, destinationRect);
+    return convertImageBufferToColorSpace(targetColorSpace, *buffer, destinationRect, pixelBuffer.format().alphaFormat);
 }
 
-Optional<PixelBuffer> FilterEffect::convertImageBufferToColorSpace(DestinationColorSpace targetColorSpace, ImageBuffer& inputBuffer, const IntRect& rect, AlphaPremultiplication outputFormat)
+Optional<PixelBuffer> FilterEffect::convertImageBufferToColorSpace(DestinationColorSpace targetColorSpace, ImageBuffer& inputBuffer, const IntRect& rect, AlphaPremultiplication outputAlphaFormat)
 {
+    // FIXME: This can be done more directly using PixelBufferConversion.
+
     FloatSize clampedSize = ImageBuffer::clampedSize(rect.size());
+
     // Create an ImageBuffer with the correct color space and utilize CG to handle color space conversion
     auto convertedBuffer = ImageBuffer::create(clampedSize, m_filter.renderingMode(), m_filter.filterScale(), targetColorSpace, PixelFormat::BGRA8);
     if (!convertedBuffer)
         return WTF::nullopt;
+
     // Color space conversion happens internally when drawing from one image buffer to another
     convertedBuffer->context().drawImageBuffer(inputBuffer, rect);
-    return convertedBuffer->getPixelBuffer(outputFormat, rect);
+    
+    PixelBufferFormat format { outputAlphaFormat, PixelFormat::RGBA8, DestinationColorSpace::SRGB };
+    return convertedBuffer->getPixelBuffer(format, rect);
 }
 
 void FilterEffect::copyConvertedImageBufferToDestination(Uint8ClampedArray& destination, DestinationColorSpace colorSpace, AlphaPremultiplication outputFormat, const IntRect& destRect)
@@ -475,11 +481,11 @@
     copyImageBytes(convertedPixelBuffer->data(), destination, destRect);
 }
 
-void FilterEffect::copyConvertedPixelBufferToDestination(Uint8ClampedArray& destination, PixelBuffer& pixelBuffer, DestinationColorSpace colorSpace, AlphaPremultiplication outputFormat, const IntRect& destRect)
+void FilterEffect::copyConvertedPixelBufferToDestination(Uint8ClampedArray& destination, PixelBuffer& pixelBuffer, DestinationColorSpace colorSpace, const IntRect& destRect)
 {
     // Converts the data stored in m_unmultipliedImageResult/m_premultipliedImageResult,
     // whichever isn't null, and save to destination
-    auto convertedPixelBuffer = convertPixelBufferToColorSpace(colorSpace, pixelBuffer, outputFormat);
+    auto convertedPixelBuffer = convertPixelBufferToColorSpace(colorSpace, pixelBuffer);
     if (!convertedPixelBuffer)
         return;
     copyImageBytes(convertedPixelBuffer->data(), destination, destRect);
@@ -498,7 +504,8 @@
                 copyConvertedImageBufferToDestination(destination, *colorSpace, AlphaPremultiplication::Unpremultiplied, rect);
                 return;
             }
-            m_unmultipliedImageResult = m_imageBufferResult->getPixelBuffer(AlphaPremultiplication::Unpremultiplied, { IntPoint(), m_absolutePaintRect.size() });
+            PixelBufferFormat format { AlphaPremultiplication::Unpremultiplied, PixelFormat::RGBA8, DestinationColorSpace::SRGB };
+            m_unmultipliedImageResult = m_imageBufferResult->getPixelBuffer(format, { IntPoint(), m_absolutePaintRect.size() });
             if (!m_unmultipliedImageResult)
                 return;
         } else {
@@ -513,7 +520,7 @@
         }
     }
     if (requiresPixelBufferColorSpaceConversion(colorSpace)) {
-        copyConvertedPixelBufferToDestination(destination, *m_unmultipliedImageResult, *colorSpace, AlphaPremultiplication::Unpremultiplied, rect);
+        copyConvertedPixelBufferToDestination(destination, *m_unmultipliedImageResult, *colorSpace, rect);
         return;
     }
     copyImageBytes(m_unmultipliedImageResult->data(), destination, rect);
@@ -532,7 +539,8 @@
                 copyConvertedImageBufferToDestination(destination, *colorSpace, AlphaPremultiplication::Premultiplied, rect);
                 return;
             }
-            m_premultipliedImageResult = m_imageBufferResult->getPixelBuffer(AlphaPremultiplication::Premultiplied, { IntPoint(), m_absolutePaintRect.size() });
+            PixelBufferFormat format { AlphaPremultiplication::Premultiplied, PixelFormat::RGBA8, DestinationColorSpace::SRGB };
+            m_premultipliedImageResult = m_imageBufferResult->getPixelBuffer(format, { IntPoint(), m_absolutePaintRect.size() });
             if (!m_premultipliedImageResult)
                 return;
         } else {
@@ -548,7 +556,7 @@
     }
 
     if (requiresPixelBufferColorSpaceConversion(colorSpace)) {
-        copyConvertedPixelBufferToDestination(destination, *m_premultipliedImageResult, *colorSpace, AlphaPremultiplication::Premultiplied, rect);
+        copyConvertedPixelBufferToDestination(destination, *m_premultipliedImageResult, *colorSpace, rect);
         return;
     }
     copyImageBytes(m_premultipliedImageResult->data(), destination, rect);

Modified: trunk/Source/WebCore/platform/graphics/filters/FilterEffect.h (277524 => 277525)


--- trunk/Source/WebCore/platform/graphics/filters/FilterEffect.h	2021-05-15 00:47:33 UTC (rev 277524)
+++ trunk/Source/WebCore/platform/graphics/filters/FilterEffect.h	2021-05-15 00:59:56 UTC (rev 277525)
@@ -204,10 +204,10 @@
 
     void copyImageBytes(const Uint8ClampedArray& source, Uint8ClampedArray& destination, const IntRect&) const;
     void copyConvertedImageBufferToDestination(Uint8ClampedArray&, DestinationColorSpace, AlphaPremultiplication, const IntRect&);
-    void copyConvertedPixelBufferToDestination(Uint8ClampedArray&, PixelBuffer&, DestinationColorSpace, AlphaPremultiplication, const IntRect&);
+    void copyConvertedPixelBufferToDestination(Uint8ClampedArray&, PixelBuffer&, DestinationColorSpace, const IntRect&);
     bool requiresPixelBufferColorSpaceConversion(Optional<DestinationColorSpace>);
-    Optional<PixelBuffer> convertPixelBufferToColorSpace(DestinationColorSpace, PixelBuffer&, AlphaPremultiplication);
     Optional<PixelBuffer> convertImageBufferToColorSpace(DestinationColorSpace, ImageBuffer&, const IntRect&, AlphaPremultiplication);
+    Optional<PixelBuffer> convertPixelBufferToColorSpace(DestinationColorSpace, PixelBuffer&);
     
 
     Filter& m_filter;

Modified: trunk/Source/WebCore/platform/graphics/win/ImageBufferDirect2DBackend.cpp (277524 => 277525)


--- trunk/Source/WebCore/platform/graphics/win/ImageBufferDirect2DBackend.cpp	2021-05-15 00:47:33 UTC (rev 277524)
+++ trunk/Source/WebCore/platform/graphics/win/ImageBufferDirect2DBackend.cpp	2021-05-15 00:59:56 UTC (rev 277525)
@@ -312,16 +312,16 @@
     return { };
 }
 
-Optional<PixelBuffer> ImageBufferDirect2DBackend::getPixelBuffer(AlphaPremultiplication outputFormat, const IntRect& srcRect) const
+Optional<PixelBuffer> ImageBufferDirect2DBackend::getPixelBuffer(const PixelBufferFormat& outputFormat, const IntRect& srcRect) const
 {
     notImplemented();
     return ImageBufferBackend::getPixelBuffer(outputFormat, srcRect, nullptr);
 }
 
-void ImageBufferDirect2DBackend::putPixelBuffer(AlphaPremultiplication inputFormat, const PixelBuffer& pixelBuffer, const IntRect& srcRect, const IntPoint& destPoint, AlphaPremultiplication destFormat)
+void ImageBufferDirect2DBackend::putPixelBuffer(const PixelBuffer& pixelBuffer, const IntRect& srcRect, const IntPoint& destPoint, AlphaPremultiplication destFormat)
 {
     notImplemented();
-    ImageBufferBackend::putPixelBuffer(inputFormat, pixelBuffer, srcRect, destPoint, destFormat, nullptr);
+    ImageBufferBackend::putPixelBuffer(pixelBuffer, srcRect, destPoint, destFormat, nullptr);
 }
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/platform/graphics/win/ImageBufferDirect2DBackend.h (277524 => 277525)


--- trunk/Source/WebCore/platform/graphics/win/ImageBufferDirect2DBackend.h	2021-05-15 00:47:33 UTC (rev 277524)
+++ trunk/Source/WebCore/platform/graphics/win/ImageBufferDirect2DBackend.h	2021-05-15 00:59:56 UTC (rev 277525)
@@ -53,8 +53,8 @@
     Vector<uint8_t> toData(const String& mimeType, Optional<double> quality) const override;
     Vector<uint8_t> toBGRAData() const override;
 
-    Optional<PixelBuffer> getPixelBuffer(AlphaPremultiplication outputFormat, const IntRect&) const override;
-    void putPixelBuffer(AlphaPremultiplication inputFormat, const PixelBuffer&, const IntRect& srcRect, const IntPoint& destPoint, AlphaPremultiplication destFormat) override;
+    Optional<PixelBuffer> getPixelBuffer(const PixelBufferFormat& outputFormat, const IntRect&) const override;
+    void putPixelBuffer(const PixelBuffer&, const IntRect& srcRect, const IntPoint& destPoint, AlphaPremultiplication destFormat) override;
 
 protected:
     ImageBufferDirect2DBackend(const FloatSize& logicalSize, const IntSize& physicalSize, float resolutionScale, ColorSpace);

Modified: trunk/Source/WebCore/rendering/shapes/Shape.cpp (277524 => 277525)


--- trunk/Source/WebCore/rendering/shapes/Shape.cpp	2021-05-15 00:47:33 UTC (rev 277524)
+++ trunk/Source/WebCore/rendering/shapes/Shape.cpp	2021-05-15 00:59:56 UTC (rev 277525)
@@ -197,7 +197,8 @@
     if (image)
         graphicsContext.drawImage(*image, IntRect(IntPoint(), imageRect.size()));
 
-    auto pixelBuffer = imageBuffer->getPixelBuffer(AlphaPremultiplication::Unpremultiplied, { IntPoint(), imageRect.size() });
+    PixelBufferFormat format { AlphaPremultiplication::Unpremultiplied, PixelFormat::RGBA8, DestinationColorSpace::SRGB };
+    auto pixelBuffer = imageBuffer->getPixelBuffer(format, { IntPoint(), imageRect.size() });
     
     // We could get to a value where PixelBuffer could be nullopt. A case where ImageRect.size() is huge, PixelBuffer::tryCreate
     // can return a nullopt because data size has overflowed. Refer rdar://problem/61793884

Modified: trunk/Source/WebKit/ChangeLog (277524 => 277525)


--- trunk/Source/WebKit/ChangeLog	2021-05-15 00:47:33 UTC (rev 277524)
+++ trunk/Source/WebKit/ChangeLog	2021-05-15 00:59:56 UTC (rev 277525)
@@ -1,3 +1,29 @@
+2021-05-14  Sam Weinig  <wei...@apple.com>
+
+        Use PixelBufferFormat to specify ImageBuffer::getPixelBuffer destination format allowing for more control over data conversion
+        https://bugs.webkit.org/show_bug.cgi?id=225813
+
+        Reviewed by Darin Adler.
+
+        Update calls/implementations of getPixelBuffer/putPixelBuffer to adjust
+        to new signature. 
+
+        * GPUProcess/graphics/RemoteImageBuffer.h:
+        * Shared/RemoteLayerTree/CGDisplayListImageBufferBackend.cpp:
+        (WebKit::CGDisplayListImageBufferBackend::getPixelBuffer const):
+        (WebKit::CGDisplayListImageBufferBackend::putPixelBuffer):
+        * Shared/RemoteLayerTree/CGDisplayListImageBufferBackend.h:
+        * WebProcess/GPU/graphics/ImageBufferShareableBitmapBackend.cpp:
+        (WebKit::ImageBufferShareableBitmapBackend::getPixelBuffer const):
+        (WebKit::ImageBufferShareableBitmapBackend::putPixelBuffer):
+        * WebProcess/GPU/graphics/ImageBufferShareableBitmapBackend.h:
+        * WebProcess/GPU/graphics/RemoteImageBufferProxy.h:
+        (WebKit::RemoteImageBufferProxy::putPixelBuffer):
+        * WebProcess/GPU/graphics/cocoa/ImageBufferShareableIOSurfaceBackend.cpp:
+        (WebKit::ImageBufferShareableIOSurfaceBackend::getPixelBuffer const):
+        (WebKit::ImageBufferShareableIOSurfaceBackend::putPixelBuffer):
+        * WebProcess/GPU/graphics/cocoa/ImageBufferShareableIOSurfaceBackend.h:
+
 2021-05-14  Patrick Angle  <pan...@apple.com>
 
         Web Inspector: `_WKInspector` leaks `WebInspectorUIProxy`

Modified: trunk/Source/WebKit/GPUProcess/graphics/RemoteImageBuffer.h (277524 => 277525)


--- trunk/Source/WebKit/GPUProcess/graphics/RemoteImageBuffer.h	2021-05-15 00:47:33 UTC (rev 277524)
+++ trunk/Source/WebKit/GPUProcess/graphics/RemoteImageBuffer.h	2021-05-15 00:59:56 UTC (rev 277525)
@@ -85,7 +85,7 @@
 
         if (item.is<WebCore::DisplayList::PutPixelBuffer>()) {
             auto& putPixelBufferItem = item.get<WebCore::DisplayList::PutPixelBuffer>();
-            putPixelBuffer(putPixelBufferItem.inputFormat(), putPixelBufferItem.pixelBuffer(), putPixelBufferItem.srcRect(), putPixelBufferItem.destPoint(), putPixelBufferItem.destFormat());
+            putPixelBuffer(putPixelBufferItem.pixelBuffer(), putPixelBufferItem.srcRect(), putPixelBufferItem.destPoint(), putPixelBufferItem.destFormat());
             return true;
         }
 

Modified: trunk/Source/WebKit/Shared/RemoteLayerTree/CGDisplayListImageBufferBackend.cpp (277524 => 277525)


--- trunk/Source/WebKit/Shared/RemoteLayerTree/CGDisplayListImageBufferBackend.cpp	2021-05-15 00:47:33 UTC (rev 277524)
+++ trunk/Source/WebKit/Shared/RemoteLayerTree/CGDisplayListImageBufferBackend.cpp	2021-05-15 00:59:56 UTC (rev 277525)
@@ -105,13 +105,13 @@
     return { };
 }
 
-Optional<WebCore::PixelBuffer> CGDisplayListImageBufferBackend::getPixelBuffer(WebCore::AlphaPremultiplication, const WebCore::IntRect&) const
+Optional<WebCore::PixelBuffer> CGDisplayListImageBufferBackend::getPixelBuffer(const WebCore::PixelBufferFormat&, const WebCore::IntRect&) const
 {
     ASSERT_NOT_REACHED();
     return { };
 }
 
-void CGDisplayListImageBufferBackend::putPixelBuffer(WebCore::AlphaPremultiplication, const WebCore::PixelBuffer&, const WebCore::IntRect&, const WebCore::IntPoint&, WebCore::AlphaPremultiplication)
+void CGDisplayListImageBufferBackend::putPixelBuffer(const WebCore::PixelBuffer&, const WebCore::IntRect&, const WebCore::IntPoint&, WebCore::AlphaPremultiplication)
 {
     ASSERT_NOT_REACHED();
 }

Modified: trunk/Source/WebKit/Shared/RemoteLayerTree/CGDisplayListImageBufferBackend.h (277524 => 277525)


--- trunk/Source/WebKit/Shared/RemoteLayerTree/CGDisplayListImageBufferBackend.h	2021-05-15 00:47:33 UTC (rev 277524)
+++ trunk/Source/WebKit/Shared/RemoteLayerTree/CGDisplayListImageBufferBackend.h	2021-05-15 00:59:56 UTC (rev 277525)
@@ -50,8 +50,8 @@
     // NOTE: These all ASSERT_NOT_REACHED().
     RefPtr<WebCore::NativeImage> copyNativeImage(WebCore::BackingStoreCopy = WebCore::CopyBackingStore) const override;
     Vector<uint8_t> toBGRAData() const override;
-    Optional<WebCore::PixelBuffer> getPixelBuffer(WebCore::AlphaPremultiplication outputFormat, const WebCore::IntRect&) const override;
-    void putPixelBuffer(WebCore::AlphaPremultiplication inputFormat, const WebCore::PixelBuffer&, const WebCore::IntRect& srcRect, const WebCore::IntPoint& destPoint, WebCore::AlphaPremultiplication destFormat) override;
+    Optional<WebCore::PixelBuffer> getPixelBuffer(const WebCore::PixelBufferFormat& outputFormat, const WebCore::IntRect&) const override;
+    void putPixelBuffer(const WebCore::PixelBuffer&, const WebCore::IntRect& srcRect, const WebCore::IntPoint& destPoint, WebCore::AlphaPremultiplication destFormat) override;
 
     static constexpr bool isOriginAtUpperLeftCorner = true;
 

Modified: trunk/Source/WebKit/WebProcess/GPU/graphics/ImageBufferShareableBitmapBackend.cpp (277524 => 277525)


--- trunk/Source/WebKit/WebProcess/GPU/graphics/ImageBufferShareableBitmapBackend.cpp	2021-05-15 00:47:33 UTC (rev 277524)
+++ trunk/Source/WebKit/WebProcess/GPU/graphics/ImageBufferShareableBitmapBackend.cpp	2021-05-15 00:59:56 UTC (rev 277525)
@@ -163,14 +163,14 @@
     return ImageBufferBackend::toBGRAData(m_bitmap->data());
 }
 
-Optional<PixelBuffer> ImageBufferShareableBitmapBackend::getPixelBuffer(AlphaPremultiplication outputFormat, const IntRect& srcRect) const
+Optional<PixelBuffer> ImageBufferShareableBitmapBackend::getPixelBuffer(const PixelBufferFormat& outputFormat, const IntRect& srcRect) const
 {
     return ImageBufferBackend::getPixelBuffer(outputFormat, srcRect, m_bitmap->data());
 }
 
-void ImageBufferShareableBitmapBackend::putPixelBuffer(AlphaPremultiplication inputFormat, const PixelBuffer& pixelBuffer, const IntRect& srcRect, const IntPoint& destPoint, WebCore::AlphaPremultiplication destFormat)
+void ImageBufferShareableBitmapBackend::putPixelBuffer(const PixelBuffer& pixelBuffer, const IntRect& srcRect, const IntPoint& destPoint, WebCore::AlphaPremultiplication destFormat)
 {
-    ImageBufferBackend::putPixelBuffer(inputFormat, pixelBuffer, srcRect, destPoint, destFormat, m_bitmap->data());
+    ImageBufferBackend::putPixelBuffer(pixelBuffer, srcRect, destPoint, destFormat, m_bitmap->data());
 }
 
 } // namespace WebKit

Modified: trunk/Source/WebKit/WebProcess/GPU/graphics/ImageBufferShareableBitmapBackend.h (277524 => 277525)


--- trunk/Source/WebKit/WebProcess/GPU/graphics/ImageBufferShareableBitmapBackend.h	2021-05-15 00:47:33 UTC (rev 277524)
+++ trunk/Source/WebKit/WebProcess/GPU/graphics/ImageBufferShareableBitmapBackend.h	2021-05-15 00:59:56 UTC (rev 277525)
@@ -59,8 +59,8 @@
     RefPtr<WebCore::Image> copyImage(WebCore::BackingStoreCopy = WebCore::CopyBackingStore, WebCore::PreserveResolution = WebCore::PreserveResolution::No) const override;
 
     Vector<uint8_t> toBGRAData() const override;
-    Optional<WebCore::PixelBuffer> getPixelBuffer(WebCore::AlphaPremultiplication outputFormat, const WebCore::IntRect&) const override;
-    void putPixelBuffer(WebCore::AlphaPremultiplication inputFormat, const WebCore::PixelBuffer&, const WebCore::IntRect& srcRect, const WebCore::IntPoint& destPoint, WebCore::AlphaPremultiplication destFormat) override;
+    Optional<WebCore::PixelBuffer> getPixelBuffer(const WebCore::PixelBufferFormat& outputFormat, const WebCore::IntRect&) const override;
+    void putPixelBuffer(const WebCore::PixelBuffer&, const WebCore::IntRect& srcRect, const WebCore::IntPoint& destPoint, WebCore::AlphaPremultiplication destFormat) override;
 
 private:
     unsigned bytesPerRow() const override;

Modified: trunk/Source/WebKit/WebProcess/GPU/graphics/RemoteImageBufferProxy.h (277524 => 277525)


--- trunk/Source/WebKit/WebProcess/GPU/graphics/RemoteImageBufferProxy.h	2021-05-15 00:47:33 UTC (rev 277524)
+++ trunk/Source/WebKit/WebProcess/GPU/graphics/RemoteImageBufferProxy.h	2021-05-15 00:59:56 UTC (rev 277525)
@@ -194,12 +194,11 @@
         return bitmap->createImage();
     }
 
-    Optional<WebCore::PixelBuffer> getPixelBuffer(WebCore::AlphaPremultiplication outputFormat, const WebCore::IntRect& srcRect) const override
+    Optional<WebCore::PixelBuffer> getPixelBuffer(const WebCore::PixelBufferFormat& destinationFormat, const WebCore::IntRect& srcRect) const override
     {
         if (UNLIKELY(!m_remoteRenderingBackendProxy))
             return WTF::nullopt;
 
-        WebCore::PixelBufferFormat destinationFormat { outputFormat, WebCore::PixelFormat::RGBA8, WebCore::DestinationColorSpace::SRGB };
         auto pixelBuffer = WebCore::PixelBuffer::tryCreate(destinationFormat, srcRect.size());
         if (!pixelBuffer)
             return WTF::nullopt;
@@ -211,7 +210,7 @@
             return WTF::nullopt;
 
         auto& mutableThis = const_cast<RemoteImageBufferProxy&>(*this);
-        mutableThis.m_drawingContext.recorder().getPixelBuffer(outputFormat, srcRect);
+        mutableThis.m_drawingContext.recorder().getPixelBuffer(destinationFormat, srcRect);
         mutableThis.flushDrawingContextAsync();
 
         if (m_remoteRenderingBackendProxy->waitForGetPixelBufferToComplete(timeout))
@@ -221,12 +220,12 @@
         return pixelBuffer;
     }
 
-    void putPixelBuffer(WebCore::AlphaPremultiplication inputFormat, const WebCore::PixelBuffer& pixelBuffer, const WebCore::IntRect& srcRect, const WebCore::IntPoint& destPoint = { }, WebCore::AlphaPremultiplication destFormat = WebCore::AlphaPremultiplication::Premultiplied) override
+    void putPixelBuffer(const WebCore::PixelBuffer& pixelBuffer, const WebCore::IntRect& srcRect, const WebCore::IntPoint& destPoint = { }, WebCore::AlphaPremultiplication destFormat = WebCore::AlphaPremultiplication::Premultiplied) override
     {
         // The math inside PixelBuffer::create() doesn't agree with the math inside ImageBufferBackend::putPixelBuffer() about how m_resolutionScale interacts with the data in the ImageBuffer.
         // This means that putPixelBuffer() is only called when resolutionScale() == 1.
         ASSERT(resolutionScale() == 1);
-        m_drawingContext.recorder().putPixelBuffer(inputFormat, pixelBuffer, srcRect, destPoint, destFormat);
+        m_drawingContext.recorder().putPixelBuffer(pixelBuffer, srcRect, destPoint, destFormat);
     }
 
     bool prefersPreparationForDisplay() override { return true; }

Modified: trunk/Source/WebKit/WebProcess/GPU/graphics/cocoa/ImageBufferShareableIOSurfaceBackend.cpp (277524 => 277525)


--- trunk/Source/WebKit/WebProcess/GPU/graphics/cocoa/ImageBufferShareableIOSurfaceBackend.cpp	2021-05-15 00:47:33 UTC (rev 277524)
+++ trunk/Source/WebKit/WebProcess/GPU/graphics/cocoa/ImageBufferShareableIOSurfaceBackend.cpp	2021-05-15 00:59:56 UTC (rev 277525)
@@ -120,13 +120,13 @@
     return { };
 }
 
-Optional<PixelBuffer> ImageBufferShareableIOSurfaceBackend::getPixelBuffer(AlphaPremultiplication, const IntRect&) const
+Optional<PixelBuffer> ImageBufferShareableIOSurfaceBackend::getPixelBuffer(const PixelBufferFormat&, const IntRect&) const
 {
     RELEASE_ASSERT_NOT_REACHED();
     return { };
 }
 
-void ImageBufferShareableIOSurfaceBackend::putPixelBuffer(AlphaPremultiplication, const PixelBuffer&, const IntRect&, const IntPoint&, AlphaPremultiplication)
+void ImageBufferShareableIOSurfaceBackend::putPixelBuffer(const PixelBuffer&, const IntRect&, const IntPoint&, AlphaPremultiplication)
 {
     RELEASE_ASSERT_NOT_REACHED();
 }

Modified: trunk/Source/WebKit/WebProcess/GPU/graphics/cocoa/ImageBufferShareableIOSurfaceBackend.h (277524 => 277525)


--- trunk/Source/WebKit/WebProcess/GPU/graphics/cocoa/ImageBufferShareableIOSurfaceBackend.h	2021-05-15 00:47:33 UTC (rev 277524)
+++ trunk/Source/WebKit/WebProcess/GPU/graphics/cocoa/ImageBufferShareableIOSurfaceBackend.h	2021-05-15 00:59:56 UTC (rev 277525)
@@ -60,8 +60,8 @@
     String toDataURL(const String& mimeType, Optional<double> quality, WebCore::PreserveResolution) const override;
     Vector<uint8_t> toData(const String& mimeType, Optional<double> quality) const override;
     Vector<uint8_t> toBGRAData() const override;
-    Optional<WebCore::PixelBuffer> getPixelBuffer(WebCore::AlphaPremultiplication outputFormat, const WebCore::IntRect&) const override;
-    void putPixelBuffer(WebCore::AlphaPremultiplication inputFormat, const WebCore::PixelBuffer&, const WebCore::IntRect& srcRect, const WebCore::IntPoint& destPoint, WebCore::AlphaPremultiplication destFormat) override;
+    Optional<WebCore::PixelBuffer> getPixelBuffer(const WebCore::PixelBufferFormat& outputFormat, const WebCore::IntRect&) const override;
+    void putPixelBuffer(const WebCore::PixelBuffer&, const WebCore::IntRect& srcRect, const WebCore::IntPoint& destPoint, WebCore::AlphaPremultiplication destFormat) override;
 
     static constexpr bool isOriginAtUpperLeftCorner = true;
     static constexpr bool canMapBackingStore = false;
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to