| Differences between
and this patch
- Source/WebCore/ChangeLog +106 lines
Lines 1-3 Source/WebCore/ChangeLog_sec1
1
2021-05-14  Sam Weinig  <weinig@apple.com>
2
3
        Use PixelBufferFormat to specify ImageBuffer::getPixelData destination format allowing for more control over data conversion
4
        https://bugs.webkit.org/show_bug.cgi?id=225813
5
6
        Reviewed by NOBODY (OOPS!).
7
8
        The reprevious signature of ImageBuffer::getPixelBuffer:
9
10
            ImageBuffer::getPixelBuffer(AlphaPremultiplication, const IntRect&);
11
        
12
        only allowed specifying the type of alpha premultiplication wanted, and hard coded
13
        a pixel format of RGBA8 and color space of SRGB. To support accurate and efficient
14
        access to pixel buffers with different pixel formats and color spaces we need to be
15
        able to tell getPixelBuffer what we want up front, so that if the ImageBuffer already
16
        has a DisplayP3 buffer, and we want DisplayP3 pixels, we don't first convert to SRGB
17
        and then convert back to DisplayP3 (which would be slow and lose any out of gamut
18
        data). The new signature allows us to specify the entire format triple:
19
        
20
            ImageBuffer::getPixelBuffer(const PixelBufferFormat&, const IntRect&);
21
22
        Additionally, ImageBuffer::putPixelBuffer() no longer needs to provide the source
23
        AlphaPremultiplication either, as the PixelBuffer itself also contains that information.
24
25
        Now that we are passing color space information, we need to support color space conversion,
26
        so PixelBufferConversion was updated to support color space conversion on CG platforms
27
        using vImageConvert_AnyToAny. This is not currently excersised, but will be in a subsequent
28
        change where canvas ImageData gains a color space setting, at which point it can be tested.
29
30
        We also don't currently support color space conversion on non-CG platforms. This won't
31
        be a problem in the short term, as only CG platforms support DisplayP3, the only other
32
        color space that can be specified currently, but as cleanup, we should add support for
33
        color space conversion using the ColorConversion and ColorTransferFunction infrastructure
34
        for other ports, moving the existing support for SRGB to/from LinearSRGB conversions from
35
        ImageBufferCairoBackend and ImageBufferCairoImageSurfaceBackend.
36
37
        * html/ImageBitmap.cpp:
38
        (WebCore::ImageBitmap::createPromise):
39
        * html/canvas/CanvasRenderingContext2DBase.cpp:
40
        (WebCore::CanvasRenderingContext2DBase::getImageData const):
41
        (WebCore::CanvasRenderingContext2DBase::putImageData):
42
        * page/PageConsoleClient.cpp:
43
        (WebCore::PageConsoleClient::screenshot):
44
        * platform/graphics/ConcreteImageBuffer.h:
45
        (WebCore::ConcreteImageBuffer::putPixelBuffer):
46
        * platform/graphics/ImageBuffer.h:
47
        (WebCore::ImageBuffer::putPixelBuffer):
48
        * platform/graphics/ImageBufferBackend.cpp:
49
        (WebCore::ImageBufferBackend::convertToLuminanceMask):
50
        (WebCore::ImageBufferBackend::getPixelBuffer const):
51
        (WebCore::ImageBufferBackend::putPixelBuffer):
52
        * platform/graphics/ImageBufferBackend.h:
53
        * platform/graphics/PixelBufferConversion.cpp:
54
        (WebCore::makeVImageCGImageFormat):
55
        (WebCore::makeVImageBuffer):
56
        (WebCore::convertImagePixelsAccelerated):
57
        (WebCore::convertImagePixels):
58
        * platform/graphics/ShadowBlur.cpp:
59
        (WebCore::ShadowBlur::blurShadowBuffer):
60
        * platform/graphics/cairo/ImageBufferCairoSurfaceBackend.cpp:
61
        (WebCore::ImageBufferCairoSurfaceBackend::getPixelBuffer const):
62
        (WebCore::ImageBufferCairoSurfaceBackend::putPixelBuffer):
63
        * platform/graphics/cairo/ImageBufferCairoSurfaceBackend.h:
64
        * platform/graphics/cg/ImageBufferCGBackend.cpp:
65
        (WebCore::ImageBufferCGBackend::toCFData const):
66
        * platform/graphics/cg/ImageBufferCGBitmapBackend.cpp:
67
        (WebCore::ImageBufferCGBitmapBackend::getPixelBuffer const):
68
        (WebCore::ImageBufferCGBitmapBackend::putPixelBuffer):
69
        * platform/graphics/cg/ImageBufferCGBitmapBackend.h:
70
        * platform/graphics/cg/ImageBufferIOSurfaceBackend.cpp:
71
        (WebCore::ImageBufferIOSurfaceBackend::getPixelBuffer const):
72
        (WebCore::ImageBufferIOSurfaceBackend::putPixelBuffer):
73
        * platform/graphics/cg/ImageBufferIOSurfaceBackend.h:
74
        * platform/graphics/displaylists/DisplayListItems.cpp:
75
        (WebCore::DisplayList::PutPixelBuffer::PutPixelBuffer):
76
        (WebCore::DisplayList::PutPixelBuffer::swap):
77
        (WebCore::DisplayList::operator<<):
78
        * platform/graphics/displaylists/DisplayListItems.h:
79
        (WebCore::DisplayList::GetPixelBuffer::GetPixelBuffer):
80
        (WebCore::DisplayList::GetPixelBuffer::outputFormat const):
81
        (WebCore::DisplayList::PutPixelBuffer::encode const):
82
        (WebCore::DisplayList::PutPixelBuffer::decode):
83
        (WebCore::DisplayList::PutPixelBuffer::inputFormat const): Deleted.
84
        * platform/graphics/displaylists/DisplayListRecorder.cpp:
85
        (WebCore::DisplayList::Recorder::getPixelBuffer):
86
        (WebCore::DisplayList::Recorder::putPixelBuffer):
87
        * platform/graphics/displaylists/DisplayListRecorder.h:
88
        * platform/graphics/filters/FEColorMatrix.cpp:
89
        (WebCore::FEColorMatrix::platformApplySoftware):
90
        * platform/graphics/filters/FEDropShadow.cpp:
91
        (WebCore::FEDropShadow::platformApplySoftware):
92
        * platform/graphics/filters/FilterEffect.cpp:
93
        (WebCore::FilterEffect::imageBufferResult):
94
        (WebCore::FilterEffect::convertPixelBufferToColorSpace):
95
        (WebCore::FilterEffect::convertImageBufferToColorSpace):
96
        (WebCore::FilterEffect::copyConvertedPixelBufferToDestination):
97
        (WebCore::FilterEffect::copyUnmultipliedResult):
98
        (WebCore::FilterEffect::copyPremultipliedResult):
99
        * platform/graphics/filters/FilterEffect.h:
100
        * platform/graphics/win/ImageBufferDirect2DBackend.cpp:
101
        (WebCore::ImageBufferDirect2DBackend::getPixelBuffer const):
102
        (WebCore::ImageBufferDirect2DBackend::putPixelBuffer):
103
        * platform/graphics/win/ImageBufferDirect2DBackend.h:
104
        * rendering/shapes/Shape.cpp:
105
        (WebCore::Shape::createRasterShape):
106
1
2021-05-14  Alex Christensen  <achristensen@webkit.org>
107
2021-05-14  Alex Christensen  <achristensen@webkit.org>
2
108
3
        Resource Timing: secureConnectionStart == 0 when a connection is re-used
109
        Resource Timing: secureConnectionStart == 0 when a connection is re-used
- Source/WebCore/bindings/js/SerializedScriptValue.cpp -2 / +3 lines
Lines 1075-1082 private: Source/WebCore/bindings/js/SerializedScriptValue.cpp_sec1
1075
            return;
1075
            return;
1076
        }
1076
        }
1077
1077
1078
        PixelBufferFormat format { AlphaPremultiplication::Premultiplied, PixelFormat::RGBA8, DestinationColorSpace::SRGB };
1078
        const IntSize& logicalSize = buffer->logicalSize();
1079
        const IntSize& logicalSize = buffer->logicalSize();
1079
        auto pixelBuffer = buffer->getPixelBuffer(AlphaPremultiplication::Premultiplied, { IntPoint::zero(), logicalSize });
1080
        auto pixelBuffer = buffer->getPixelBuffer(format, { IntPoint::zero(), logicalSize });
1080
        if (!pixelBuffer) {
1081
        if (!pixelBuffer) {
1081
            code = SerializationReturnCode::ValidationError;
1082
            code = SerializationReturnCode::ValidationError;
1082
            return;
1083
            return;
Lines 3163-3169 private: Source/WebCore/bindings/js/SerializedScriptValue.cpp_sec2
3163
            return JSValue();
3164
            return JSValue();
3164
        }
3165
        }
3165
3166
3166
        buffer->putPixelBuffer(AlphaPremultiplication::Premultiplied, imageData->pixelBuffer(), { IntPoint::zero(), logicalSize });
3167
        buffer->putPixelBuffer(imageData->pixelBuffer(), { IntPoint::zero(), logicalSize });
3167
3168
3168
        auto bitmap = ImageBitmap::create(ImageBitmapBacking(WTFMove(buffer), OptionSet<SerializationState>::fromRaw(serializationState)));
3169
        auto bitmap = ImageBitmap::create(ImageBitmapBacking(WTFMove(buffer), OptionSet<SerializationState>::fromRaw(serializationState)));
3169
        return getJSValue(bitmap);
3170
        return getJSValue(bitmap);
- Source/WebCore/html/ImageBitmap.cpp -2 / +2 lines
Lines 807-813 void ImageBitmap::createPromise(ScriptEx Source/WebCore/html/ImageBitmap.cpp_sec1
807
    // resulting ImageBuffer directly.
807
    // resulting ImageBuffer directly.
808
    auto alphaPremultiplication = alphaPremultiplicationForPremultiplyAlpha(options.premultiplyAlpha);
808
    auto alphaPremultiplication = alphaPremultiplicationForPremultiplyAlpha(options.premultiplyAlpha);
809
    if (sourceRectangle.returnValue().location().isZero() && sourceRectangle.returnValue().size() == imageData->size() && sourceRectangle.returnValue().size() == outputSize && options.imageOrientation == ImageBitmapOptions::Orientation::None) {
809
    if (sourceRectangle.returnValue().location().isZero() && sourceRectangle.returnValue().size() == imageData->size() && sourceRectangle.returnValue().size() == outputSize && options.imageOrientation == ImageBitmapOptions::Orientation::None) {
810
        bitmapData->putPixelBuffer(AlphaPremultiplication::Unpremultiplied, imageData->pixelBuffer(), sourceRectangle.releaseReturnValue(), { }, alphaPremultiplication);
810
        bitmapData->putPixelBuffer(imageData->pixelBuffer(), sourceRectangle.releaseReturnValue(), { }, alphaPremultiplication);
811
        
811
        
812
        auto imageBitmap = create(ImageBitmapBacking(WTFMove(bitmapData)));
812
        auto imageBitmap = create(ImageBitmapBacking(WTFMove(bitmapData)));
813
        // The result is implicitly origin-clean, and alpha premultiplication has already been handled.
813
        // The result is implicitly origin-clean, and alpha premultiplication has already been handled.
Lines 822-828 void ImageBitmap::createPromise(ScriptEx Source/WebCore/html/ImageBitmap.cpp_sec2
822
        resolveWithBlankImageBuffer(scriptExecutionContext, true, WTFMove(promise));
822
        resolveWithBlankImageBuffer(scriptExecutionContext, true, WTFMove(promise));
823
        return;
823
        return;
824
    }
824
    }
825
    tempBitmapData->putPixelBuffer(AlphaPremultiplication::Unpremultiplied, imageData->pixelBuffer(), IntRect(0, 0, imageData->width(), imageData->height()), { }, alphaPremultiplication);
825
    tempBitmapData->putPixelBuffer(imageData->pixelBuffer(), IntRect(0, 0, imageData->width(), imageData->height()), { }, alphaPremultiplication);
826
    FloatRect destRect(FloatPoint(), outputSize);
826
    FloatRect destRect(FloatPoint(), outputSize);
827
    bitmapData->context().drawImageBuffer(*tempBitmapData, destRect, sourceRectangle.releaseReturnValue(), { interpolationQualityForResizeQuality(options.resizeQuality), imageOrientationForOrientation(options.imageOrientation) });
827
    bitmapData->context().drawImageBuffer(*tempBitmapData, destRect, sourceRectangle.releaseReturnValue(), { interpolationQualityForResizeQuality(options.resizeQuality), imageOrientationForOrientation(options.imageOrientation) });
828
828
- Source/WebCore/html/canvas/CanvasRenderingContext2DBase.cpp -2 / +3 lines
Lines 2199-2205 ExceptionOr<RefPtr<ImageData>> CanvasRen Source/WebCore/html/canvas/CanvasRenderingContext2DBase.cpp_sec1
2199
    if (!buffer)
2199
    if (!buffer)
2200
        return createEmptyImageData(imageDataRect.size());
2200
        return createEmptyImageData(imageDataRect.size());
2201
2201
2202
    auto pixelBuffer = buffer->getPixelBuffer(AlphaPremultiplication::Unpremultiplied, imageDataRect);
2202
    PixelBufferFormat format { AlphaPremultiplication::Unpremultiplied, PixelFormat::RGBA8, DestinationColorSpace::SRGB };
2203
    auto pixelBuffer = buffer->getPixelBuffer(format, imageDataRect);
2203
    if (!pixelBuffer) {
2204
    if (!pixelBuffer) {
2204
        canvasBase().scriptExecutionContext()->addConsoleMessage(MessageSource::Rendering, MessageLevel::Error,
2205
        canvasBase().scriptExecutionContext()->addConsoleMessage(MessageSource::Rendering, MessageLevel::Error,
2205
            makeString("Unable to get image data from canvas. Requested size was ", imageDataRect.width(), " x ", imageDataRect.height()));
2206
            makeString("Unable to get image data from canvas. Requested size was ", imageDataRect.width(), " x ", imageDataRect.height()));
Lines 2246-2252 void CanvasRenderingContext2DBase::putIm Source/WebCore/html/canvas/CanvasRenderingContext2DBase.cpp_sec2
2246
    sourceRect.intersect(IntRect { 0, 0, data.width(), data.height() });
2247
    sourceRect.intersect(IntRect { 0, 0, data.width(), data.height() });
2247
2248
2248
    if (!sourceRect.isEmpty())
2249
    if (!sourceRect.isEmpty())
2249
        buffer->putPixelBuffer(AlphaPremultiplication::Unpremultiplied, data.pixelBuffer(), sourceRect, IntPoint { destOffset });
2250
        buffer->putPixelBuffer(data.pixelBuffer(), sourceRect, IntPoint { destOffset });
2250
2251
2251
    didDraw(FloatRect { destRect }, { }); // ignore transform, shadow and clip
2252
    didDraw(FloatRect { destRect }, { }); // ignore transform, shadow and clip
2252
}
2253
}
- Source/WebCore/page/PageConsoleClient.cpp -1 / +1 lines
Lines 370-376 void PageConsoleClient::screenshot(JSC:: Source/WebCore/page/PageConsoleClient.cpp_sec1
370
                auto sourceSize = imageData->size();
370
                auto sourceSize = imageData->size();
371
                if (auto imageBuffer = ImageBuffer::create(sourceSize, RenderingMode::Unaccelerated, 1, DestinationColorSpace::SRGB, PixelFormat::BGRA8)) {
371
                if (auto imageBuffer = ImageBuffer::create(sourceSize, RenderingMode::Unaccelerated, 1, DestinationColorSpace::SRGB, PixelFormat::BGRA8)) {
372
                    IntRect sourceRect(IntPoint(), sourceSize);
372
                    IntRect sourceRect(IntPoint(), sourceSize);
373
                    imageBuffer->putPixelBuffer(AlphaPremultiplication::Unpremultiplied, imageData->pixelBuffer(), sourceRect);
373
                    imageBuffer->putPixelBuffer(imageData->pixelBuffer(), sourceRect);
374
                    dataURL = imageBuffer->toDataURL("image/png"_s, WTF::nullopt, PreserveResolution::Yes);
374
                    dataURL = imageBuffer->toDataURL("image/png"_s, WTF::nullopt, PreserveResolution::Yes);
375
                }
375
                }
376
            }
376
            }
- Source/WebCore/platform/graphics/ConcreteImageBuffer.h -3 / +3 lines
Lines 230-236 protected: Source/WebCore/platform/graphics/ConcreteImageBuffer.h_sec1
230
        return { };
230
        return { };
231
    }
231
    }
232
232
233
    Optional<PixelBuffer> getPixelBuffer(AlphaPremultiplication outputFormat, const IntRect& srcRect) const override
233
    Optional<PixelBuffer> getPixelBuffer(const PixelBufferFormat& outputFormat, const IntRect& srcRect) const override
234
    {
234
    {
235
        if (auto* backend = ensureBackendCreated()) {
235
        if (auto* backend = ensureBackendCreated()) {
236
            const_cast<ConcreteImageBuffer&>(*this).flushContext();
236
            const_cast<ConcreteImageBuffer&>(*this).flushContext();
Lines 239-249 protected: Source/WebCore/platform/graphics/ConcreteImageBuffer.h_sec2
239
        return WTF::nullopt;
239
        return WTF::nullopt;
240
    }
240
    }
241
241
242
    void putPixelBuffer(AlphaPremultiplication inputFormat, const PixelBuffer& pixelBuffer, const IntRect& srcRect, const IntPoint& destPoint = { }, AlphaPremultiplication destFormat = AlphaPremultiplication::Premultiplied) override
242
    void putPixelBuffer(const PixelBuffer& pixelBuffer, const IntRect& srcRect, const IntPoint& destPoint = { }, AlphaPremultiplication destFormat = AlphaPremultiplication::Premultiplied) override
243
    {
243
    {
244
        if (auto* backend = ensureBackendCreated()) {
244
        if (auto* backend = ensureBackendCreated()) {
245
            flushContext();
245
            flushContext();
246
            backend->putPixelBuffer(inputFormat, pixelBuffer, srcRect, destPoint, destFormat);
246
            backend->putPixelBuffer(pixelBuffer, srcRect, destPoint, destFormat);
247
        }
247
        }
248
    }
248
    }
249
249
- Source/WebCore/platform/graphics/ImageBuffer.h -2 / +2 lines
Lines 126-133 public: Source/WebCore/platform/graphics/ImageBuffer.h_sec1
126
    virtual Vector<uint8_t> toData(const String& mimeType, Optional<double> quality = WTF::nullopt) const = 0;
126
    virtual Vector<uint8_t> toData(const String& mimeType, Optional<double> quality = WTF::nullopt) const = 0;
127
    virtual Vector<uint8_t> toBGRAData() const = 0;
127
    virtual Vector<uint8_t> toBGRAData() const = 0;
128
128
129
    virtual Optional<PixelBuffer> getPixelBuffer(AlphaPremultiplication outputFormat, const IntRect& srcRect) const = 0;
129
    virtual Optional<PixelBuffer> getPixelBuffer(const PixelBufferFormat& outputFormat, const IntRect& srcRect) const = 0;
130
    virtual void putPixelBuffer(AlphaPremultiplication inputFormat, const PixelBuffer&, const IntRect& srcRect, const IntPoint& destPoint = { }, AlphaPremultiplication destFormat = AlphaPremultiplication::Premultiplied) = 0;
130
    virtual void putPixelBuffer(const PixelBuffer&, const IntRect& srcRect, const IntPoint& destPoint = { }, AlphaPremultiplication destFormat = AlphaPremultiplication::Premultiplied) = 0;
131
131
132
    // FIXME: current implementations of this method have the restriction that they only work
132
    // FIXME: current implementations of this method have the restriction that they only work
133
    // with textures that are RGB or RGBA format, and UNSIGNED_BYTE type.
133
    // with textures that are RGB or RGBA format, and UNSIGNED_BYTE type.
- Source/WebCore/platform/graphics/ImageBufferBackend.cpp -11 / +10 lines
Lines 70-76 void ImageBufferBackend::drawConsuming(G Source/WebCore/platform/graphics/ImageBufferBackend.cpp_sec1
70
70
71
void ImageBufferBackend::convertToLuminanceMask()
71
void ImageBufferBackend::convertToLuminanceMask()
72
{
72
{
73
    auto pixelBuffer = getPixelBuffer(AlphaPremultiplication::Unpremultiplied, logicalRect());
73
    PixelBufferFormat format { AlphaPremultiplication::Unpremultiplied, PixelFormat::RGBA8, DestinationColorSpace::SRGB };
74
    auto pixelBuffer = getPixelBuffer(format, logicalRect());
74
    if (!pixelBuffer)
75
    if (!pixelBuffer)
75
        return;
76
        return;
76
77
Lines 88-94 void ImageBufferBackend::convertToLumina Source/WebCore/platform/graphics/ImageBufferBackend.cpp_sec2
88
        pixelArray.set(pixelOffset + 3, luma);
89
        pixelArray.set(pixelOffset + 3, luma);
89
    }
90
    }
90
91
91
    putPixelBuffer(AlphaPremultiplication::Unpremultiplied, *pixelBuffer, logicalRect(), IntPoint::zero(), AlphaPremultiplication::Premultiplied);
92
    putPixelBuffer(*pixelBuffer, logicalRect(), IntPoint::zero(), AlphaPremultiplication::Premultiplied);
92
}
93
}
93
94
94
Vector<uint8_t> ImageBufferBackend::toBGRAData(void* data) const
95
Vector<uint8_t> ImageBufferBackend::toBGRAData(void* data) const
Lines 113-124 Vector<uint8_t> ImageBufferBackend::toBG Source/WebCore/platform/graphics/ImageBufferBackend.cpp_sec3
113
    return result;
114
    return result;
114
}
115
}
115
116
116
Optional<PixelBuffer> ImageBufferBackend::getPixelBuffer(AlphaPremultiplication destinationAlphaFormat, const IntRect& sourceRect, void* data) const
117
Optional<PixelBuffer> ImageBufferBackend::getPixelBuffer(const PixelBufferFormat& destinationFormat, const IntRect& sourceRect, void* data) const
117
{
118
{
118
    auto sourceRectScaled = toBackendCoordinates(sourceRect);
119
    auto sourceRectScaled = toBackendCoordinates(sourceRect);
119
120
120
    PixelBufferFormat destinationFormat { destinationAlphaFormat, PixelFormat::RGBA8, DestinationColorSpace::SRGB };
121
122
    auto pixelBuffer = PixelBuffer::tryCreate(destinationFormat, sourceRectScaled.size());
121
    auto pixelBuffer = PixelBuffer::tryCreate(destinationFormat, sourceRectScaled.size());
123
    if (!pixelBuffer)
122
    if (!pixelBuffer)
124
        return WTF::nullopt;
123
        return WTF::nullopt;
Lines 158-172 Optional<PixelBuffer> ImageBufferBackend Source/WebCore/platform/graphics/ImageBufferBackend.cpp_sec4
158
    return pixelBuffer;
157
    return pixelBuffer;
159
}
158
}
160
159
161
void ImageBufferBackend::putPixelBuffer(AlphaPremultiplication sourceAlphaFormat, const PixelBuffer& pixelBuffer, const IntRect& sourceRect, const IntPoint& destinationPoint, AlphaPremultiplication destinationAlphaFormat, void* data)
160
void ImageBufferBackend::putPixelBuffer(const PixelBuffer& sourcePixelBuffer, const IntRect& sourceRect, const IntPoint& destinationPoint, AlphaPremultiplication destinationAlphaFormat, void* data)
162
{
161
{
163
    // FIXME: Add support for non-RGBA8 pixel formats.
162
    // FIXME: Add support for non-RGBA8 pixel formats.
164
    ASSERT(pixelBuffer.format().pixelFormat == PixelFormat::RGBA8);
163
    ASSERT(sourcePixelBuffer.format().pixelFormat == PixelFormat::RGBA8);
165
164
166
    auto sourceRectScaled = toBackendCoordinates(sourceRect);
165
    auto sourceRectScaled = toBackendCoordinates(sourceRect);
167
    auto destinationPointScaled = toBackendCoordinates(destinationPoint);
166
    auto destinationPointScaled = toBackendCoordinates(destinationPoint);
168
167
169
    IntRect sourceRectClipped = intersection({ IntPoint::zero(), pixelBuffer.size() }, sourceRectScaled);
168
    IntRect sourceRectClipped = intersection({ IntPoint::zero(), sourcePixelBuffer.size() }, sourceRectScaled);
170
    IntRect destinationRect = sourceRectClipped;
169
    IntRect destinationRect = sourceRectClipped;
171
    destinationRect.moveBy(destinationPointScaled);
170
    destinationRect.moveBy(destinationPointScaled);
172
171
Lines 179-191 void ImageBufferBackend::putPixelBuffer( Source/WebCore/platform/graphics/ImageBufferBackend.cpp_sec5
179
    destinationRect.intersect(backendRect());
178
    destinationRect.intersect(backendRect());
180
    sourceRectClipped.setSize(destinationRect.size());
179
    sourceRectClipped.setSize(destinationRect.size());
181
180
182
    unsigned sourceBytesPerRow = 4 * pixelBuffer.size().width();
181
    unsigned sourceBytesPerRow = 4 * sourcePixelBuffer.size().width();
183
    const uint8_t* sourceRows = pixelBuffer.data().data() + sourceRectClipped.y() * sourceBytesPerRow + sourceRectClipped.x() * 4;
182
    const uint8_t* sourceRows = sourcePixelBuffer.data().data() + sourceRectClipped.y() * sourceBytesPerRow + sourceRectClipped.x() * 4;
184
183
185
    unsigned destinationBytesPerRow = bytesPerRow();
184
    unsigned destinationBytesPerRow = bytesPerRow();
186
    uint8_t* destinationRows = reinterpret_cast<uint8_t*>(data) + destinationRect.y() * destinationBytesPerRow + destinationRect.x() * 4;
185
    uint8_t* destinationRows = reinterpret_cast<uint8_t*>(data) + destinationRect.y() * destinationBytesPerRow + destinationRect.x() * 4;
187
186
188
    PixelBufferFormat sourceFormat { sourceAlphaFormat, PixelFormat::RGBA8, DestinationColorSpace::SRGB };
187
    PixelBufferFormat sourceFormat = sourcePixelBuffer.format();
189
    PixelBufferFormat destinationFormat { destinationAlphaFormat, pixelFormat(), DestinationColorSpace::SRGB };
188
    PixelBufferFormat destinationFormat { destinationAlphaFormat, pixelFormat(), DestinationColorSpace::SRGB };
190
189
191
    ConstPixelBufferConversionView source;
190
    ConstPixelBufferConversionView source;
- Source/WebCore/platform/graphics/ImageBufferBackend.h -6 / +5 lines
Lines 25-37 Source/WebCore/platform/graphics/ImageBufferBackend.h_sec1
25
25
26
#pragma once
26
#pragma once
27
27
28
#include "AlphaPremultiplication.h"
29
#include "ColorSpace.h"
28
#include "ColorSpace.h"
30
#include "FloatRect.h"
29
#include "FloatRect.h"
31
#include "GraphicsTypesGL.h"
30
#include "GraphicsTypesGL.h"
32
#include "ImagePaintingOptions.h"
31
#include "ImagePaintingOptions.h"
33
#include "IntRect.h"
32
#include "IntRect.h"
34
#include "PixelFormat.h"
33
#include "PixelBufferFormat.h"
35
#include "PlatformLayer.h"
34
#include "PlatformLayer.h"
36
#include "RenderingMode.h"
35
#include "RenderingMode.h"
37
#include <wtf/RefPtr.h>
36
#include <wtf/RefPtr.h>
Lines 109-116 public: Source/WebCore/platform/graphics/ImageBufferBackend.h_sec2
109
    virtual Vector<uint8_t> toData(const String& mimeType, Optional<double> quality) const = 0;
108
    virtual Vector<uint8_t> toData(const String& mimeType, Optional<double> quality) const = 0;
110
    virtual Vector<uint8_t> toBGRAData() const = 0;
109
    virtual Vector<uint8_t> toBGRAData() const = 0;
111
110
112
    virtual Optional<PixelBuffer> getPixelBuffer(AlphaPremultiplication outputFormat, const IntRect&) const = 0;
111
    virtual Optional<PixelBuffer> getPixelBuffer(const PixelBufferFormat& outputFormat, const IntRect&) const = 0;
113
    virtual void putPixelBuffer(AlphaPremultiplication inputFormat, const PixelBuffer&, const IntRect& srcRect, const IntPoint& destPoint, AlphaPremultiplication destFormat) = 0;
112
    virtual void putPixelBuffer(const PixelBuffer&, const IntRect& srcRect, const IntPoint& destPoint, AlphaPremultiplication destFormat) = 0;
114
113
115
    virtual PlatformLayer* platformLayer() const { return nullptr; }
114
    virtual PlatformLayer* platformLayer() const { return nullptr; }
116
    virtual bool copyToPlatformTexture(GraphicsContextGL&, GCGLenum, PlatformGLObject, GCGLenum, bool, bool) const { return false; }
115
    virtual bool copyToPlatformTexture(GraphicsContextGL&, GCGLenum, PlatformGLObject, GCGLenum, bool, bool) const { return false; }
Lines 150-157 protected: Source/WebCore/platform/graphics/ImageBufferBackend.h_sec3
150
149
151
    WEBCORE_EXPORT Vector<uint8_t> toBGRAData(void* data) const;
150
    WEBCORE_EXPORT Vector<uint8_t> toBGRAData(void* data) const;
152
151
153
    WEBCORE_EXPORT Optional<PixelBuffer> getPixelBuffer(AlphaPremultiplication outputFormat, const IntRect& srcRect, void* data) const;
152
    WEBCORE_EXPORT Optional<PixelBuffer> getPixelBuffer(const PixelBufferFormat& outputFormat, const IntRect& srcRect, void* data) const;
154
    WEBCORE_EXPORT void putPixelBuffer(AlphaPremultiplication inputFormat, const PixelBuffer&, const IntRect& srcRect, const IntPoint& destPoint, AlphaPremultiplication destFormat, void* data);
153
    WEBCORE_EXPORT void putPixelBuffer(const PixelBuffer&, const IntRect& srcRect, const IntPoint& destPoint, AlphaPremultiplication destFormat, void* data);
155
154
156
    Parameters m_parameters;
155
    Parameters m_parameters;
157
};
156
};
- Source/WebCore/platform/graphics/PixelBufferConversion.cpp -12 / +100 lines
Lines 31-54 Source/WebCore/platform/graphics/PixelBufferConversion.cpp_sec1
31
#include "IntSize.h"
31
#include "IntSize.h"
32
#include "PixelFormat.h"
32
#include "PixelFormat.h"
33
33
34
#if USE(ACCELERATE)
34
#if USE(ACCELERATE) && USE(CG)
35
#include "ColorSpaceCG.h"
35
#include <Accelerate/Accelerate.h>
36
#include <Accelerate/Accelerate.h>
36
#endif
37
#endif
37
38
38
namespace WebCore {
39
namespace WebCore {
39
40
40
#if USE(ACCELERATE)
41
#if USE(ACCELERATE) && USE(CG)
42
43
static inline vImage_CGImageFormat makeVImageCGImageFormat(const PixelBufferFormat& format)
44
{
45
    // We currently only support 8 bit pixel formats for these conversions.
46
47
    auto bitsPerComponent = [] (PixelFormat pixelFormat) -> unsigned {
48
        switch (pixelFormat) {
49
        case PixelFormat::RGBA8:
50
        case PixelFormat::BGRA8:
51
            return 8;
52
53
        case PixelFormat::RGB10:
54
        case PixelFormat::RGB10A8:
55
            break;
56
        }
57
58
        ASSERT_NOT_REACHED();
59
        return 8;
60
    };
61
62
    auto bitsPerPixel = [] (PixelFormat pixelFormat) -> unsigned {
63
        switch (pixelFormat) {
64
        case PixelFormat::RGBA8:
65
        case PixelFormat::BGRA8:
66
            return 32;
67
68
        case PixelFormat::RGB10:
69
        case PixelFormat::RGB10A8:
70
            break;
71
        }
72
73
        ASSERT_NOT_REACHED();
74
        return 32;
75
    };
76
77
    auto bitmapInfo = [] (AlphaPremultiplication alphaFormat, PixelFormat pixelFormat) -> CGBitmapInfo {
78
        switch (pixelFormat) {
79
        case PixelFormat::RGBA8:
80
            if (alphaFormat == AlphaPremultiplication::Premultiplied)
81
                return kCGBitmapByteOrder32Big | kCGImageAlphaPremultipliedLast;
82
            else
83
                return kCGBitmapByteOrder32Big | kCGImageAlphaLast;
84
85
        case PixelFormat::BGRA8:
86
            if (alphaFormat == AlphaPremultiplication::Premultiplied)
87
                return kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst;
88
            else
89
                return kCGBitmapByteOrder32Little | kCGImageAlphaFirst;
90
91
        case PixelFormat::RGB10:
92
        case PixelFormat::RGB10A8:
93
            break;
94
        }
95
96
        ASSERT_NOT_REACHED();
97
        return kCGBitmapByteOrder32Little | kCGImageAlphaFirst;
98
    };
99
100
    vImage_CGImageFormat result;
101
102
    result.bitsPerComponent = bitsPerComponent(format.pixelFormat);
103
    result.bitsPerPixel = bitsPerPixel(format.pixelFormat);
104
    result.colorSpace = cachedCGColorSpace(format.colorSpace);
105
    result.bitmapInfo = bitmapInfo(format.alphaFormat, format.pixelFormat);
106
    result.version = 0;
107
    result.decode = nullptr;
108
    result.renderingIntent = kCGRenderingIntentDefault;
109
110
    return result;
111
}
41
112
42
template<typename View> static vImage_Buffer makeVImageBuffer(const View& view, const IntSize& size)
113
template<typename View> static vImage_Buffer makeVImageBuffer(const View& view, const IntSize& size)
43
{
114
{
44
    vImage_Buffer vImageBuffer;
115
    vImage_Buffer result;
45
116
46
    vImageBuffer.height = static_cast<vImagePixelCount>(size.height());
117
    result.height = static_cast<vImagePixelCount>(size.height());
47
    vImageBuffer.width = static_cast<vImagePixelCount>(size.width());
118
    result.width = static_cast<vImagePixelCount>(size.width());
48
    vImageBuffer.rowBytes = view.bytesPerRow;
119
    result.rowBytes = view.bytesPerRow;
49
    vImageBuffer.data = const_cast<uint8_t*>(view.rows);
120
    result.data = const_cast<uint8_t*>(view.rows);
50
121
51
    return vImageBuffer;
122
    return result;
52
}
123
}
53
124
54
static void convertImagePixelsAccelerated(const ConstPixelBufferConversionView& source, const PixelBufferConversionView& destination, const IntSize& destinationSize)
125
static void convertImagePixelsAccelerated(const ConstPixelBufferConversionView& source, const PixelBufferConversionView& destination, const IntSize& destinationSize)
Lines 56-61 static void convertImagePixelsAccelerate Source/WebCore/platform/graphics/PixelBufferConversion.cpp_sec2
56
    auto sourceVImageBuffer = makeVImageBuffer(source, destinationSize);
127
    auto sourceVImageBuffer = makeVImageBuffer(source, destinationSize);
57
    auto destinationVImageBuffer = makeVImageBuffer(destination, destinationSize);
128
    auto destinationVImageBuffer = makeVImageBuffer(destination, destinationSize);
58
129
130
    if (source.format.colorSpace != destination.format.colorSpace) {
131
        // FIXME: Consider using vImageConvert_AnyToAny for all conversions, not just ones that need a color space conversion,
132
        // after judiciously performance testing them against each other.
133
134
        auto sourceCGImageFormat = makeVImageCGImageFormat(source.format);
135
        auto destinationCGImageFormat = makeVImageCGImageFormat(destination.format);
136
137
        vImage_Error converterCreateError = kvImageNoError;
138
        auto converter = adoptCF(vImageConverter_CreateWithCGImageFormat(&sourceCGImageFormat, &destinationCGImageFormat, nullptr, kvImageNoFlags, &converterCreateError));
139
        ASSERT_WITH_MESSAGE_UNUSED(converterCreateError != kvImageNoError, "vImageConverter creation failed with error: %zd", converterCreateError);
140
141
        vImage_Error converterConvertError = vImageConvert_AnyToAny(converter.get(), &sourceVImageBuffer, &destinationVImageBuffer, nullptr, kvImageNoFlags);
142
        ASSERT_WITH_MESSAGE_UNUSED(converterConvertError == kvImageNoError, "vImageConvert_AnyToAny failed conversion with error: %zd", converterConvertError);
143
        return;
144
    }
145
59
    if (source.format.alphaFormat != destination.format.alphaFormat) {
146
    if (source.format.alphaFormat != destination.format.alphaFormat) {
60
        if (destination.format.alphaFormat == AlphaPremultiplication::Unpremultiplied) {
147
        if (destination.format.alphaFormat == AlphaPremultiplication::Unpremultiplied) {
61
            if (source.format.pixelFormat == PixelFormat::RGBA8)
148
            if (source.format.pixelFormat == PixelFormat::RGBA8)
Lines 184-193 void convertImagePixels(const ConstPixel Source/WebCore/platform/graphics/PixelBufferConversion.cpp_sec3
184
    ASSERT(source.format.pixelFormat == PixelFormat::RGBA8 || source.format.pixelFormat == PixelFormat::BGRA8);
271
    ASSERT(source.format.pixelFormat == PixelFormat::RGBA8 || source.format.pixelFormat == PixelFormat::BGRA8);
185
    ASSERT(destination.format.pixelFormat == PixelFormat::RGBA8 || destination.format.pixelFormat == PixelFormat::BGRA8);
272
    ASSERT(destination.format.pixelFormat == PixelFormat::RGBA8 || destination.format.pixelFormat == PixelFormat::BGRA8);
186
273
187
    // We don't currently support converting pixel data between different color spaces.
274
#if USE(ACCELERATE) && USE(CG)
188
    ASSERT(source.format.colorSpace == destination.format.colorSpace);
189
190
#if USE(ACCELERATE)
191
    if (source.format.alphaFormat == destination.format.alphaFormat && source.format.pixelFormat == destination.format.pixelFormat) {
275
    if (source.format.alphaFormat == destination.format.alphaFormat && source.format.pixelFormat == destination.format.pixelFormat) {
192
        // FIXME: Can thes both just use per-row memcpy?
276
        // FIXME: Can thes both just use per-row memcpy?
193
        if (source.format.alphaFormat == AlphaPremultiplication::Premultiplied)
277
        if (source.format.alphaFormat == AlphaPremultiplication::Premultiplied)
Lines 197-202 void convertImagePixels(const ConstPixel Source/WebCore/platform/graphics/PixelBufferConversion.cpp_sec4
197
    } else
281
    } else
198
        convertImagePixelsAccelerated(source, destination, destinationSize);
282
        convertImagePixelsAccelerated(source, destination, destinationSize);
199
#else
283
#else
284
    // FIXME: We don't currently support converting pixel data between different color spaces in the non-accelerated path.
285
    // This could be added using conversion functions from ColorConversion.h.
286
    ASSERT(source.format.colorSpace == destination.format.colorSpace);
287
200
    if (source.format.alphaFormat == destination.format.alphaFormat) {
288
    if (source.format.alphaFormat == destination.format.alphaFormat) {
201
        if (source.format.pixelFormat == destination.format.pixelFormat) {
289
        if (source.format.pixelFormat == destination.format.pixelFormat) {
202
            if (source.format.alphaFormat == AlphaPremultiplication::Premultiplied)
290
            if (source.format.alphaFormat == AlphaPremultiplication::Premultiplied)
- Source/WebCore/platform/graphics/ShadowBlur.cpp -2 / +3 lines
Lines 903-915 void ShadowBlur::blurShadowBuffer(ImageB Source/WebCore/platform/graphics/ShadowBlur.cpp_sec1
903
    if (m_type != BlurShadow)
903
    if (m_type != BlurShadow)
904
        return;
904
        return;
905
905
906
    PixelBufferFormat format { AlphaPremultiplication::Unpremultiplied, PixelFormat::RGBA8, DestinationColorSpace::SRGB };
906
    IntRect blurRect(IntPoint(), templateSize);
907
    IntRect blurRect(IntPoint(), templateSize);
907
    auto layerData = layerImage.getPixelBuffer(AlphaPremultiplication::Unpremultiplied, blurRect);
908
    auto layerData = layerImage.getPixelBuffer(format, blurRect);
908
    if (!layerData)
909
    if (!layerData)
909
        return;
910
        return;
910
911
911
    blurLayerImage(layerData->data().data(), blurRect.size(), blurRect.width() * 4);
912
    blurLayerImage(layerData->data().data(), blurRect.size(), blurRect.width() * 4);
912
    layerImage.putPixelBuffer(AlphaPremultiplication::Unpremultiplied, *layerData, blurRect);
913
    layerImage.putPixelBuffer(*layerData, blurRect);
913
}
914
}
914
915
915
void ShadowBlur::blurAndColorShadowBuffer(ImageBuffer& layerImage, const IntSize& templateSize)
916
void ShadowBlur::blurAndColorShadowBuffer(ImageBuffer& layerImage, const IntSize& templateSize)
- Source/WebCore/platform/graphics/cairo/ImageBufferCairoSurfaceBackend.cpp -3 / +3 lines
Lines 120-133 Vector<uint8_t> ImageBufferCairoSurfaceB Source/WebCore/platform/graphics/cairo/ImageBufferCairoSurfaceBackend.cpp_sec1
120
    return imageData;
120
    return imageData;
121
}
121
}
122
122
123
Optional<PixelBuffer> ImageBufferCairoSurfaceBackend::getPixelBuffer(AlphaPremultiplication outputFormat, const IntRect& srcRect) const
123
Optional<PixelBuffer> ImageBufferCairoSurfaceBackend::getPixelBuffer(PixelBufferFormat outputFormat, const IntRect& srcRect) const
124
{
124
{
125
    return ImageBufferBackend::getPixelBuffer(outputFormat, srcRect, cairo_image_surface_get_data(m_surface.get()));
125
    return ImageBufferBackend::getPixelBuffer(outputFormat, srcRect, cairo_image_surface_get_data(m_surface.get()));
126
}
126
}
127
127
128
void ImageBufferCairoSurfaceBackend::putPixelBuffer(AlphaPremultiplication inputFormat, const PixelBuffer& pixelBuffer, const IntRect& srcRect, const IntPoint& destPoint, AlphaPremultiplication destFormat)
128
void ImageBufferCairoSurfaceBackend::putPixelBuffer(const PixelBuffer& pixelBuffer, const IntRect& srcRect, const IntPoint& destPoint, AlphaPremultiplication destFormat)
129
{
129
{
130
    ImageBufferBackend::putPixelBuffer(inputFormat, pixelBuffer, srcRect, destPoint, destFormat, cairo_image_surface_get_data(m_surface.get()));
130
    ImageBufferBackend::putPixelBuffer(pixelBuffer, srcRect, destPoint, destFormat, cairo_image_surface_get_data(m_surface.get()));
131
131
132
    IntRect srcRectScaled = toBackendCoordinates(srcRect);
132
    IntRect srcRectScaled = toBackendCoordinates(srcRect);
133
    IntPoint destPointScaled = toBackendCoordinates(destPoint);
133
    IntPoint destPointScaled = toBackendCoordinates(destPoint);
- Source/WebCore/platform/graphics/cairo/ImageBufferCairoSurfaceBackend.h -2 / +2 lines
Lines 45-52 public: Source/WebCore/platform/graphics/cairo/ImageBufferCairoSurfaceBackend.h_sec1
45
    RefPtr<NativeImage> copyNativeImage(BackingStoreCopy) const override;
45
    RefPtr<NativeImage> copyNativeImage(BackingStoreCopy) const override;
46
46
47
    Vector<uint8_t> toBGRAData() const override;
47
    Vector<uint8_t> toBGRAData() const override;
48
    Optional<PixelBuffer> getPixelBuffer(AlphaPremultiplication outputFormat, const IntRect&) const override;
48
    Optional<PixelBuffer> getPixelBuffer(PixelBufferFormat outputFormat, const IntRect&) const override;
49
    void putPixelBuffer(AlphaPremultiplication inputFormat, const PixelBuffer&, const IntRect& srcRect, const IntPoint& destPoint, AlphaPremultiplication destFormat) override;
49
    void putPixelBuffer(const PixelBuffer&, const IntRect& srcRect, const IntPoint& destPoint, AlphaPremultiplication destFormat) override;
50
50
51
protected:
51
protected:
52
    ImageBufferCairoSurfaceBackend(const Parameters&, RefPtr<cairo_surface_t>&&);
52
    ImageBufferCairoSurfaceBackend(const Parameters&, RefPtr<cairo_surface_t>&&);
- Source/WebCore/platform/graphics/cg/ImageBufferCGBackend.cpp -1 / +2 lines
Lines 183-189 RetainPtr<CFDataRef> ImageBufferCGBacken Source/WebCore/platform/graphics/cg/ImageBufferCGBackend.cpp_sec1
183
183
184
    if (CFEqual(uti.get(), jpegUTI())) {
184
    if (CFEqual(uti.get(), jpegUTI())) {
185
        // JPEGs don't have an alpha channel, so we have to manually composite on top of black.
185
        // JPEGs don't have an alpha channel, so we have to manually composite on top of black.
186
        auto pixelBuffer = getPixelBuffer(AlphaPremultiplication::Premultiplied, logicalRect());
186
        PixelBufferFormat format { AlphaPremultiplication::Premultiplied, PixelFormat::RGBA8, DestinationColorSpace::SRGB };
187
        auto pixelBuffer = getPixelBuffer(format, logicalRect());
187
        if (!pixelBuffer)
188
        if (!pixelBuffer)
188
            return nullptr;
189
            return nullptr;
189
190
- Source/WebCore/platform/graphics/cg/ImageBufferCGBitmapBackend.cpp -3 / +3 lines
Lines 159-172 Vector<uint8_t> ImageBufferCGBitmapBacke Source/WebCore/platform/graphics/cg/ImageBufferCGBitmapBackend.cpp_sec1
159
    return ImageBufferBackend::toBGRAData(m_data);
159
    return ImageBufferBackend::toBGRAData(m_data);
160
}
160
}
161
161
162
Optional<PixelBuffer> ImageBufferCGBitmapBackend::getPixelBuffer(AlphaPremultiplication outputFormat, const IntRect& srcRect) const
162
Optional<PixelBuffer> ImageBufferCGBitmapBackend::getPixelBuffer(const PixelBufferFormat& outputFormat, const IntRect& srcRect) const
163
{
163
{
164
    return ImageBufferBackend::getPixelBuffer(outputFormat, srcRect, m_data);
164
    return ImageBufferBackend::getPixelBuffer(outputFormat, srcRect, m_data);
165
}
165
}
166
166
167
void ImageBufferCGBitmapBackend::putPixelBuffer(AlphaPremultiplication inputFormat, const PixelBuffer& pixelBuffer, const IntRect& srcRect, const IntPoint& destPoint, AlphaPremultiplication destFormat)
167
void ImageBufferCGBitmapBackend::putPixelBuffer(const PixelBuffer& pixelBuffer, const IntRect& srcRect, const IntPoint& destPoint, AlphaPremultiplication destFormat)
168
{
168
{
169
    ImageBufferBackend::putPixelBuffer(inputFormat, pixelBuffer, srcRect, destPoint, destFormat, m_data);
169
    ImageBufferBackend::putPixelBuffer(pixelBuffer, srcRect, destPoint, destFormat, m_data);
170
}
170
}
171
171
172
} // namespace WebCore
172
} // namespace WebCore
- Source/WebCore/platform/graphics/cg/ImageBufferCGBitmapBackend.h -2 / +2 lines
Lines 51-58 public: Source/WebCore/platform/graphics/cg/ImageBufferCGBitmapBackend.h_sec1
51
51
52
    Vector<uint8_t> toBGRAData() const override;
52
    Vector<uint8_t> toBGRAData() const override;
53
53
54
    Optional<PixelBuffer> getPixelBuffer(AlphaPremultiplication outputFormat, const IntRect&) const override;
54
    Optional<PixelBuffer> getPixelBuffer(const PixelBufferFormat& outputFormat, const IntRect&) const override;
55
    void putPixelBuffer(AlphaPremultiplication inputFormat, const PixelBuffer&, const IntRect& srcRect, const IntPoint& destPoint, AlphaPremultiplication destFormat) override;
55
    void putPixelBuffer(const PixelBuffer&, const IntRect& srcRect, const IntPoint& destPoint, AlphaPremultiplication destFormat) override;
56
56
57
    static constexpr bool isOriginAtUpperLeftCorner = true;
57
    static constexpr bool isOriginAtUpperLeftCorner = true;
58
58
- Source/WebCore/platform/graphics/cg/ImageBufferIOSurfaceBackend.cpp -3 / +3 lines
Lines 183-198 Vector<uint8_t> ImageBufferIOSurfaceBack Source/WebCore/platform/graphics/cg/ImageBufferIOSurfaceBackend.cpp_sec1
183
    return ImageBufferBackend::toBGRAData(lock.surfaceBaseAddress());
183
    return ImageBufferBackend::toBGRAData(lock.surfaceBaseAddress());
184
}
184
}
185
185
186
Optional<PixelBuffer> ImageBufferIOSurfaceBackend::getPixelBuffer(AlphaPremultiplication outputFormat, const IntRect& srcRect) const
186
Optional<PixelBuffer> ImageBufferIOSurfaceBackend::getPixelBuffer(const PixelBufferFormat& outputFormat, const IntRect& srcRect) const
187
{
187
{
188
    IOSurface::Locker lock(*m_surface);
188
    IOSurface::Locker lock(*m_surface);
189
    return ImageBufferBackend::getPixelBuffer(outputFormat, srcRect, lock.surfaceBaseAddress());
189
    return ImageBufferBackend::getPixelBuffer(outputFormat, srcRect, lock.surfaceBaseAddress());
190
}
190
}
191
191
192
void ImageBufferIOSurfaceBackend::putPixelBuffer(AlphaPremultiplication inputFormat, const PixelBuffer& pixelBuffer, const IntRect& srcRect, const IntPoint& destPoint, AlphaPremultiplication destFormat)
192
void ImageBufferIOSurfaceBackend::putPixelBuffer(const PixelBuffer& pixelBuffer, const IntRect& srcRect, const IntPoint& destPoint, AlphaPremultiplication destFormat)
193
{
193
{
194
    IOSurface::Locker lock(*m_surface, IOSurface::Locker::AccessMode::ReadWrite);
194
    IOSurface::Locker lock(*m_surface, IOSurface::Locker::AccessMode::ReadWrite);
195
    ImageBufferBackend::putPixelBuffer(inputFormat, pixelBuffer, srcRect, destPoint, destFormat, lock.surfaceBaseAddress());
195
    ImageBufferBackend::putPixelBuffer(pixelBuffer, srcRect, destPoint, destFormat, lock.surfaceBaseAddress());
196
    m_requiresDrawAfterPutPixelBuffer = true;
196
    m_requiresDrawAfterPutPixelBuffer = true;
197
}
197
}
198
198
- Source/WebCore/platform/graphics/cg/ImageBufferIOSurfaceBackend.h -2 / +2 lines
Lines 63-70 public: Source/WebCore/platform/graphics/cg/ImageBufferIOSurfaceBackend.h_sec1
63
    RetainPtr<CFDataRef> toCFData(const String& mimeType, Optional<double> quality, PreserveResolution) const override;
63
    RetainPtr<CFDataRef> toCFData(const String& mimeType, Optional<double> quality, PreserveResolution) const override;
64
    Vector<uint8_t> toBGRAData() const override;
64
    Vector<uint8_t> toBGRAData() const override;
65
65
66
    Optional<PixelBuffer> getPixelBuffer(AlphaPremultiplication outputFormat, const IntRect&) const override;
66
    Optional<PixelBuffer> getPixelBuffer(const PixelBufferFormat& outputFormat, const IntRect&) const override;
67
    void putPixelBuffer(AlphaPremultiplication inputFormat, const PixelBuffer&, const IntRect& srcRect, const IntPoint& destPoint, AlphaPremultiplication destFormat) override;
67
    void putPixelBuffer(const PixelBuffer&, const IntRect& srcRect, const IntPoint& destPoint, AlphaPremultiplication destFormat) override;
68
68
69
    bool isInUse() const override;
69
    bool isInUse() const override;
70
    void releaseGraphicsContext() override;
70
    void releaseGraphicsContext() override;
- Source/WebCore/platform/graphics/displaylists/DisplayListItems.cpp -7 / +2 lines
Lines 775-794 static TextStream& operator<<(TextStream Source/WebCore/platform/graphics/displaylists/DisplayListItems.cpp_sec1
775
    return ts;
775
    return ts;
776
}
776
}
777
777
778
PutPixelBuffer::PutPixelBuffer(AlphaPremultiplication inputFormat, const PixelBuffer& pixelBuffer, const IntRect& srcRect, const IntPoint& destPoint, AlphaPremultiplication destFormat)
778
PutPixelBuffer::PutPixelBuffer(const PixelBuffer& pixelBuffer, const IntRect& srcRect, const IntPoint& destPoint, AlphaPremultiplication destFormat)
779
    : m_srcRect(srcRect)
779
    : m_srcRect(srcRect)
780
    , m_destPoint(destPoint)
780
    , m_destPoint(destPoint)
781
    , m_pixelBuffer(pixelBuffer.deepClone()) // This copy is actually required to preserve the semantics of putPixelBuffer().
781
    , m_pixelBuffer(pixelBuffer.deepClone()) // This copy is actually required to preserve the semantics of putPixelBuffer().
782
    , m_inputFormat(inputFormat)
783
    , m_destFormat(destFormat)
782
    , m_destFormat(destFormat)
784
{
783
{
785
}
784
}
786
785
787
PutPixelBuffer::PutPixelBuffer(AlphaPremultiplication inputFormat, PixelBuffer&& pixelBuffer, const IntRect& srcRect, const IntPoint& destPoint, AlphaPremultiplication destFormat)
786
PutPixelBuffer::PutPixelBuffer(PixelBuffer&& pixelBuffer, const IntRect& srcRect, const IntPoint& destPoint, AlphaPremultiplication destFormat)
788
    : m_srcRect(srcRect)
787
    : m_srcRect(srcRect)
789
    , m_destPoint(destPoint)
788
    , m_destPoint(destPoint)
790
    , m_pixelBuffer(WTFMove(pixelBuffer))
789
    , m_pixelBuffer(WTFMove(pixelBuffer))
791
    , m_inputFormat(inputFormat)
792
    , m_destFormat(destFormat)
790
    , m_destFormat(destFormat)
793
{
791
{
794
}
792
}
Lines 797-803 PutPixelBuffer::PutPixelBuffer(const Put Source/WebCore/platform/graphics/displaylists/DisplayListItems.cpp_sec2
797
    : m_srcRect(other.m_srcRect)
795
    : m_srcRect(other.m_srcRect)
798
    , m_destPoint(other.m_destPoint)
796
    , m_destPoint(other.m_destPoint)
799
    , m_pixelBuffer(other.m_pixelBuffer.deepClone())
797
    , m_pixelBuffer(other.m_pixelBuffer.deepClone())
800
    , m_inputFormat(other.m_inputFormat)
801
    , m_destFormat(other.m_destFormat)
798
    , m_destFormat(other.m_destFormat)
802
{
799
{
803
}
800
}
Lines 814-826 void PutPixelBuffer::swap(PutPixelBuffer Source/WebCore/platform/graphics/displaylists/DisplayListItems.cpp_sec3
814
    std::swap(m_srcRect, other.m_srcRect);
811
    std::swap(m_srcRect, other.m_srcRect);
815
    std::swap(m_destPoint, other.m_destPoint);
812
    std::swap(m_destPoint, other.m_destPoint);
816
    std::swap(m_pixelBuffer, other.m_pixelBuffer);
813
    std::swap(m_pixelBuffer, other.m_pixelBuffer);
817
    std::swap(m_inputFormat, other.m_inputFormat);
818
    std::swap(m_destFormat, other.m_destFormat);
814
    std::swap(m_destFormat, other.m_destFormat);
819
}
815
}
820
816
821
static TextStream& operator<<(TextStream& ts, const PutPixelBuffer& item)
817
static TextStream& operator<<(TextStream& ts, const PutPixelBuffer& item)
822
{
818
{
823
    ts.dumpProperty("inputFormat", item.inputFormat());
824
    ts.dumpProperty("pixelBufferSize", item.pixelBuffer().size());
819
    ts.dumpProperty("pixelBufferSize", item.pixelBuffer().size());
825
    ts.dumpProperty("srcRect", item.srcRect());
820
    ts.dumpProperty("srcRect", item.srcRect());
826
    ts.dumpProperty("destPoint", item.destPoint());
821
    ts.dumpProperty("destPoint", item.destPoint());
- Source/WebCore/platform/graphics/displaylists/DisplayListItems.h -14 / +6 lines
Lines 1905-1922 public: Source/WebCore/platform/graphics/displaylists/DisplayListItems.h_sec1
1905
    static constexpr bool isInlineItem = true;
1905
    static constexpr bool isInlineItem = true;
1906
    static constexpr bool isDrawingItem = false;
1906
    static constexpr bool isDrawingItem = false;
1907
1907
1908
    GetPixelBuffer(WebCore::AlphaPremultiplication outputFormat, const WebCore::IntRect& srcRect)
1908
    GetPixelBuffer(WebCore::PixelBufferFormat outputFormat, const WebCore::IntRect& srcRect)
1909
        : m_srcRect(srcRect)
1909
        : m_srcRect(srcRect)
1910
        , m_outputFormat(outputFormat)
1910
        , m_outputFormat(outputFormat)
1911
    {
1911
    {
1912
    }
1912
    }
1913
1913
1914
    AlphaPremultiplication outputFormat() const { return m_outputFormat; }
1914
    PixelBufferFormat outputFormat() const { return m_outputFormat; }
1915
    IntRect srcRect() const { return m_srcRect; }
1915
    IntRect srcRect() const { return m_srcRect; }
1916
1916
1917
private:
1917
private:
1918
    IntRect m_srcRect;
1918
    IntRect m_srcRect;
1919
    AlphaPremultiplication m_outputFormat;
1919
    PixelBufferFormat m_outputFormat;
1920
};
1920
};
1921
1921
1922
class PutPixelBuffer {
1922
class PutPixelBuffer {
Lines 1925-1932 public: Source/WebCore/platform/graphics/displaylists/DisplayListItems.h_sec2
1925
    static constexpr bool isInlineItem = false;
1925
    static constexpr bool isInlineItem = false;
1926
    static constexpr bool isDrawingItem = true;
1926
    static constexpr bool isDrawingItem = true;
1927
1927
1928
    WEBCORE_EXPORT PutPixelBuffer(AlphaPremultiplication inputFormat, const PixelBuffer&, const IntRect& srcRect, const IntPoint& destPoint, AlphaPremultiplication destFormat);
1928
    WEBCORE_EXPORT PutPixelBuffer(const PixelBuffer&, const IntRect& srcRect, const IntPoint& destPoint, AlphaPremultiplication destFormat);
1929
    WEBCORE_EXPORT PutPixelBuffer(AlphaPremultiplication inputFormat, PixelBuffer&&, const IntRect& srcRect, const IntPoint& destPoint, AlphaPremultiplication destFormat);
1929
    WEBCORE_EXPORT PutPixelBuffer(PixelBuffer&&, const IntRect& srcRect, const IntPoint& destPoint, AlphaPremultiplication destFormat);
1930
1930
1931
    PutPixelBuffer(const PutPixelBuffer&);
1931
    PutPixelBuffer(const PutPixelBuffer&);
1932
    PutPixelBuffer(PutPixelBuffer&&) = default;
1932
    PutPixelBuffer(PutPixelBuffer&&) = default;
Lines 1935-1941 public: Source/WebCore/platform/graphics/displaylists/DisplayListItems.h_sec3
1935
1935
1936
    void swap(PutPixelBuffer&);
1936
    void swap(PutPixelBuffer&);
1937
1937
1938
    AlphaPremultiplication inputFormat() const { return m_inputFormat; }
1939
    const PixelBuffer& pixelBuffer() const { return m_pixelBuffer; }
1938
    const PixelBuffer& pixelBuffer() const { return m_pixelBuffer; }
1940
    IntRect srcRect() const { return m_srcRect; }
1939
    IntRect srcRect() const { return m_srcRect; }
1941
    IntPoint destPoint() const { return m_destPoint; }
1940
    IntPoint destPoint() const { return m_destPoint; }
Lines 1951-1964 private: Source/WebCore/platform/graphics/displaylists/DisplayListItems.h_sec4
1951
    IntRect m_srcRect;
1950
    IntRect m_srcRect;
1952
    IntPoint m_destPoint;
1951
    IntPoint m_destPoint;
1953
    PixelBuffer m_pixelBuffer;
1952
    PixelBuffer m_pixelBuffer;
1954
    AlphaPremultiplication m_inputFormat;
1955
    AlphaPremultiplication m_destFormat;
1953
    AlphaPremultiplication m_destFormat;
1956
};
1954
};
1957
1955
1958
template<class Encoder>
1956
template<class Encoder>
1959
void PutPixelBuffer::encode(Encoder& encoder) const
1957
void PutPixelBuffer::encode(Encoder& encoder) const
1960
{
1958
{
1961
    encoder << m_inputFormat;
1962
    encoder << m_pixelBuffer;
1959
    encoder << m_pixelBuffer;
1963
    encoder << m_srcRect;
1960
    encoder << m_srcRect;
1964
    encoder << m_destPoint;
1961
    encoder << m_destPoint;
Lines 1968-1983 void PutPixelBuffer::encode(Encoder& enc Source/WebCore/platform/graphics/displaylists/DisplayListItems.h_sec5
1968
template<class Decoder>
1965
template<class Decoder>
1969
Optional<PutPixelBuffer> PutPixelBuffer::decode(Decoder& decoder)
1966
Optional<PutPixelBuffer> PutPixelBuffer::decode(Decoder& decoder)
1970
{
1967
{
1971
    Optional<AlphaPremultiplication> inputFormat;
1972
    Optional<PixelBuffer> pixelBuffer;
1968
    Optional<PixelBuffer> pixelBuffer;
1973
    Optional<IntRect> srcRect;
1969
    Optional<IntRect> srcRect;
1974
    Optional<IntPoint> destPoint;
1970
    Optional<IntPoint> destPoint;
1975
    Optional<AlphaPremultiplication> destFormat;
1971
    Optional<AlphaPremultiplication> destFormat;
1976
1972
1977
    decoder >> inputFormat;
1978
    if (!inputFormat)
1979
        return WTF::nullopt;
1980
1981
    decoder >> pixelBuffer;
1973
    decoder >> pixelBuffer;
1982
    if (!pixelBuffer)
1974
    if (!pixelBuffer)
1983
        return WTF::nullopt;
1975
        return WTF::nullopt;
Lines 1994-2000 Optional<PutPixelBuffer> PutPixelBuffer: Source/WebCore/platform/graphics/displaylists/DisplayListItems.h_sec6
1994
    if (!destFormat)
1986
    if (!destFormat)
1995
        return WTF::nullopt;
1987
        return WTF::nullopt;
1996
1988
1997
    return {{ *inputFormat, WTFMove(*pixelBuffer), *srcRect, *destPoint, *destFormat }};
1989
    return {{ WTFMove(*pixelBuffer), *srcRect, *destPoint, *destFormat }};
1998
}
1990
}
1999
1991
2000
#if ENABLE(VIDEO)
1992
#if ENABLE(VIDEO)
- Source/WebCore/platform/graphics/displaylists/DisplayListRecorder.cpp -3 / +3 lines
Lines 55-68 Recorder::~Recorder() Source/WebCore/platform/graphics/displaylists/DisplayListRecorder.cpp_sec1
55
    LOG(DisplayLists, "Recorded display list:\n%s", m_displayList.description().data());
55
    LOG(DisplayLists, "Recorded display list:\n%s", m_displayList.description().data());
56
}
56
}
57
57
58
void Recorder::getPixelBuffer(AlphaPremultiplication outputFormat, const IntRect& sourceRect)
58
void Recorder::getPixelBuffer(const PixelBufferFormat& outputFormat, const IntRect& sourceRect)
59
{
59
{
60
    append<GetPixelBuffer>(outputFormat, sourceRect);
60
    append<GetPixelBuffer>(outputFormat, sourceRect);
61
}
61
}
62
62
63
void Recorder::putPixelBuffer(WebCore::AlphaPremultiplication inputFormat, const WebCore::PixelBuffer& pixelBuffer, const WebCore::IntRect& srcRect, const WebCore::IntPoint& destPoint, WebCore::AlphaPremultiplication destFormat)
63
void Recorder::putPixelBuffer(const WebCore::PixelBuffer& pixelBuffer, const WebCore::IntRect& srcRect, const WebCore::IntPoint& destPoint, WebCore::AlphaPremultiplication destFormat)
64
{
64
{
65
    append<PutPixelBuffer>(inputFormat, pixelBuffer, srcRect, destPoint, destFormat);
65
    append<PutPixelBuffer>(pixelBuffer, srcRect, destPoint, destFormat);
66
}
66
}
67
67
68
static bool containsOnlyInlineStateChanges(const GraphicsContextStateChange& changes, GraphicsContextState::StateChangeFlags changeFlags)
68
static bool containsOnlyInlineStateChanges(const GraphicsContextStateChange& changes, GraphicsContextState::StateChangeFlags changeFlags)
- Source/WebCore/platform/graphics/displaylists/DisplayListRecorder.h -2 / +2 lines
Lines 58-65 public: Source/WebCore/platform/graphics/displaylists/DisplayListRecorder.h_sec1
58
    WEBCORE_EXPORT Recorder(GraphicsContext&, DisplayList&, const GraphicsContextState&, const FloatRect& initialClip, const AffineTransform&, Delegate* = nullptr, DrawGlyphsRecorder::DrawGlyphsDeconstruction = DrawGlyphsRecorder::DrawGlyphsDeconstruction::Deconstruct);
58
    WEBCORE_EXPORT Recorder(GraphicsContext&, DisplayList&, const GraphicsContextState&, const FloatRect& initialClip, const AffineTransform&, Delegate* = nullptr, DrawGlyphsRecorder::DrawGlyphsDeconstruction = DrawGlyphsRecorder::DrawGlyphsDeconstruction::Deconstruct);
59
    WEBCORE_EXPORT virtual ~Recorder();
59
    WEBCORE_EXPORT virtual ~Recorder();
60
60
61
    WEBCORE_EXPORT void getPixelBuffer(AlphaPremultiplication outputFormat, const IntRect& sourceRect);
61
    WEBCORE_EXPORT void getPixelBuffer(const PixelBufferFormat& outputFormat, const IntRect& sourceRect);
62
    WEBCORE_EXPORT void putPixelBuffer(AlphaPremultiplication inputFormat, const PixelBuffer&, const IntRect& srcRect, const IntPoint& destPoint, AlphaPremultiplication destFormat);
62
    WEBCORE_EXPORT void putPixelBuffer(const PixelBuffer&, const IntRect& srcRect, const IntPoint& destPoint, AlphaPremultiplication destFormat);
63
63
64
    bool isEmpty() const { return m_displayList.isEmpty(); }
64
    bool isEmpty() const { return m_displayList.isEmpty(); }
65
65
- Source/WebCore/platform/graphics/filters/FEColorMatrix.cpp -2 / +3 lines
Lines 285-292 void FEColorMatrix::platformApplySoftwar Source/WebCore/platform/graphics/filters/FEColorMatrix.cpp_sec1
285
    if (inBuffer)
285
    if (inBuffer)
286
        resultImage->context().drawImageBuffer(*inBuffer, drawingRegionOfInputImage(in->absolutePaintRect()));
286
        resultImage->context().drawImageBuffer(*inBuffer, drawingRegionOfInputImage(in->absolutePaintRect()));
287
287
288
    PixelBufferFormat format { AlphaPremultiplication::Unpremultiplied, PixelFormat::RGBA8, DestinationColorSpace::SRGB };
288
    IntRect imageRect(IntPoint(), resultImage->logicalSize());
289
    IntRect imageRect(IntPoint(), resultImage->logicalSize());
289
    auto pixelBuffer = resultImage->getPixelBuffer(AlphaPremultiplication::Unpremultiplied, imageRect);
290
    auto pixelBuffer = resultImage->getPixelBuffer(format, imageRect);
290
    if (!pixelBuffer)
291
    if (!pixelBuffer)
291
        return;
292
        return;
292
293
Lines 313-319 void FEColorMatrix::platformApplySoftwar Source/WebCore/platform/graphics/filters/FEColorMatrix.cpp_sec2
313
        break;
314
        break;
314
    }
315
    }
315
316
316
    resultImage->putPixelBuffer(AlphaPremultiplication::Unpremultiplied, *pixelBuffer, imageRect);
317
    resultImage->putPixelBuffer(*pixelBuffer, imageRect);
317
}
318
}
318
319
319
static TextStream& operator<<(TextStream& ts, const ColorMatrixType& type)
320
static TextStream& operator<<(TextStream& ts, const ColorMatrixType& type)
- Source/WebCore/platform/graphics/filters/FEDropShadow.cpp -2 / +3 lines
Lines 99-113 void FEDropShadow::platformApplySoftware Source/WebCore/platform/graphics/filters/FEDropShadow.cpp_sec1
99
99
100
    ShadowBlur contextShadow(blurRadius, offset, m_shadowColor);
100
    ShadowBlur contextShadow(blurRadius, offset, m_shadowColor);
101
101
102
    PixelBufferFormat format { AlphaPremultiplication::Premultiplied, PixelFormat::RGBA8, DestinationColorSpace::SRGB };
102
    IntRect shadowArea(IntPoint(), resultImage->logicalSize());
103
    IntRect shadowArea(IntPoint(), resultImage->logicalSize());
103
    auto pixelBuffer = resultImage->getPixelBuffer(AlphaPremultiplication::Premultiplied, shadowArea);
104
    auto pixelBuffer = resultImage->getPixelBuffer(format, shadowArea);
104
    if (!pixelBuffer)
105
    if (!pixelBuffer)
105
        return;
106
        return;
106
107
107
    auto& sourcePixelArray = pixelBuffer->data();
108
    auto& sourcePixelArray = pixelBuffer->data();
108
    contextShadow.blurLayerImage(sourcePixelArray.data(), pixelBuffer->size(), 4 * pixelBuffer->size().width());
109
    contextShadow.blurLayerImage(sourcePixelArray.data(), pixelBuffer->size(), 4 * pixelBuffer->size().width());
109
    
110
    
110
    resultImage->putPixelBuffer(AlphaPremultiplication::Premultiplied, *pixelBuffer, shadowArea);
111
    resultImage->putPixelBuffer(*pixelBuffer, shadowArea);
111
112
112
    resultContext.setCompositeOperation(CompositeOperator::SourceIn);
113
    resultContext.setCompositeOperation(CompositeOperator::SourceIn);
113
    resultContext.fillRect(FloatRect(FloatPoint(), absolutePaintRect().size()), m_shadowColor);
114
    resultContext.fillRect(FloatRect(FloatPoint(), absolutePaintRect().size()), m_shadowColor);
- Source/WebCore/platform/graphics/filters/FilterEffect.cpp -13 / +21 lines
Lines 279-287 ImageBuffer* FilterEffect::imageBufferRe Source/WebCore/platform/graphics/filters/FilterEffect.cpp_sec1
279
279
280
    IntRect destinationRect(IntPoint(), m_absolutePaintRect.size());
280
    IntRect destinationRect(IntPoint(), m_absolutePaintRect.size());
281
    if (m_premultipliedImageResult)
281
    if (m_premultipliedImageResult)
282
        m_imageBufferResult->putPixelBuffer(AlphaPremultiplication::Premultiplied, *m_premultipliedImageResult, destinationRect);
282
        m_imageBufferResult->putPixelBuffer(*m_premultipliedImageResult, destinationRect);
283
    else
283
    else
284
        m_imageBufferResult->putPixelBuffer(AlphaPremultiplication::Unpremultiplied, *m_unmultipliedImageResult, destinationRect);
284
        m_imageBufferResult->putPixelBuffer(*m_unmultipliedImageResult, destinationRect);
285
    return m_imageBufferResult.get();
285
    return m_imageBufferResult.get();
286
}
286
}
287
287
Lines 439-445 static void copyUnpremultiplyingAlpha(co Source/WebCore/platform/graphics/filters/FilterEffect.cpp_sec2
439
#endif
439
#endif
440
}
440
}
441
441
442
Optional<PixelBuffer> FilterEffect::convertPixelBufferToColorSpace(DestinationColorSpace targetColorSpace, PixelBuffer& pixelBuffer, AlphaPremultiplication outputFormat)
442
Optional<PixelBuffer> FilterEffect::convertPixelBufferToColorSpace(DestinationColorSpace targetColorSpace, PixelBuffer& pixelBuffer)
443
{
443
{
444
    // FIXME: Using an ImageBuffer to perform the color space conversion is unnecessary. We can do it directly.
444
    // FIXME: Using an ImageBuffer to perform the color space conversion is unnecessary. We can do it directly.
445
445
Lines 450-469 Optional<PixelBuffer> FilterEffect::conv Source/WebCore/platform/graphics/filters/FilterEffect.cpp_sec3
450
    auto buffer = ImageBuffer::create(clampedSize, m_filter.renderingMode(), m_filter.filterScale(), operatingColorSpace(), PixelFormat::BGRA8);
450
    auto buffer = ImageBuffer::create(clampedSize, m_filter.renderingMode(), m_filter.filterScale(), operatingColorSpace(), PixelFormat::BGRA8);
451
    if (!buffer)
451
    if (!buffer)
452
        return WTF::nullopt;
452
        return WTF::nullopt;
453
    buffer->putPixelBuffer(outputFormat, pixelBuffer, destinationRect);
453
    buffer->putPixelBuffer(pixelBuffer, destinationRect);
454
    return convertImageBufferToColorSpace(targetColorSpace, *buffer, destinationRect, outputFormat);
454
    return convertImageBufferToColorSpace(targetColorSpace, *buffer, destinationRect, pixelBuffer.format().alphaFormat);
455
}
455
}
456
456
457
Optional<PixelBuffer> FilterEffect::convertImageBufferToColorSpace(DestinationColorSpace targetColorSpace, ImageBuffer& inputBuffer, const IntRect& rect, AlphaPremultiplication outputFormat)
457
Optional<PixelBuffer> FilterEffect::convertImageBufferToColorSpace(DestinationColorSpace targetColorSpace, ImageBuffer& inputBuffer, const IntRect& rect, AlphaPremultiplication outputAlphaFormat)
458
{
458
{
459
    // FIXME: This can be done more directly using PixelBufferConversion.
460
459
    FloatSize clampedSize = ImageBuffer::clampedSize(rect.size());
461
    FloatSize clampedSize = ImageBuffer::clampedSize(rect.size());
462
460
    // Create an ImageBuffer with the correct color space and utilize CG to handle color space conversion
463
    // Create an ImageBuffer with the correct color space and utilize CG to handle color space conversion
461
    auto convertedBuffer = ImageBuffer::create(clampedSize, m_filter.renderingMode(), m_filter.filterScale(), targetColorSpace, PixelFormat::BGRA8);
464
    auto convertedBuffer = ImageBuffer::create(clampedSize, m_filter.renderingMode(), m_filter.filterScale(), targetColorSpace, PixelFormat::BGRA8);
462
    if (!convertedBuffer)
465
    if (!convertedBuffer)
463
        return WTF::nullopt;
466
        return WTF::nullopt;
467
464
    // Color space conversion happens internally when drawing from one image buffer to another
468
    // Color space conversion happens internally when drawing from one image buffer to another
465
    convertedBuffer->context().drawImageBuffer(inputBuffer, rect);
469
    convertedBuffer->context().drawImageBuffer(inputBuffer, rect);
466
    return convertedBuffer->getPixelBuffer(outputFormat, rect);
470
    
471
    PixelBufferFormat format { outputAlphaFormat, PixelFormat::RGBA8, DestinationColorSpace::SRGB };
472
    return convertedBuffer->getPixelBuffer(format, rect);
467
}
473
}
468
474
469
void FilterEffect::copyConvertedImageBufferToDestination(Uint8ClampedArray& destination, DestinationColorSpace colorSpace, AlphaPremultiplication outputFormat, const IntRect& destRect)
475
void FilterEffect::copyConvertedImageBufferToDestination(Uint8ClampedArray& destination, DestinationColorSpace colorSpace, AlphaPremultiplication outputFormat, const IntRect& destRect)
Lines 475-485 void FilterEffect::copyConvertedImageBuf Source/WebCore/platform/graphics/filters/FilterEffect.cpp_sec4
475
    copyImageBytes(convertedPixelBuffer->data(), destination, destRect);
481
    copyImageBytes(convertedPixelBuffer->data(), destination, destRect);
476
}
482
}
477
483
478
void FilterEffect::copyConvertedPixelBufferToDestination(Uint8ClampedArray& destination, PixelBuffer& pixelBuffer, DestinationColorSpace colorSpace, AlphaPremultiplication outputFormat, const IntRect& destRect)
484
void FilterEffect::copyConvertedPixelBufferToDestination(Uint8ClampedArray& destination, PixelBuffer& pixelBuffer, DestinationColorSpace colorSpace, const IntRect& destRect)
479
{
485
{
480
    // Converts the data stored in m_unmultipliedImageResult/m_premultipliedImageResult,
486
    // Converts the data stored in m_unmultipliedImageResult/m_premultipliedImageResult,
481
    // whichever isn't null, and save to destination
487
    // whichever isn't null, and save to destination
482
    auto convertedPixelBuffer = convertPixelBufferToColorSpace(colorSpace, pixelBuffer, outputFormat);
488
    auto convertedPixelBuffer = convertPixelBufferToColorSpace(colorSpace, pixelBuffer);
483
    if (!convertedPixelBuffer)
489
    if (!convertedPixelBuffer)
484
        return;
490
        return;
485
    copyImageBytes(convertedPixelBuffer->data(), destination, destRect);
491
    copyImageBytes(convertedPixelBuffer->data(), destination, destRect);
Lines 498-504 void FilterEffect::copyUnmultipliedResul Source/WebCore/platform/graphics/filters/FilterEffect.cpp_sec5
498
                copyConvertedImageBufferToDestination(destination, *colorSpace, AlphaPremultiplication::Unpremultiplied, rect);
504
                copyConvertedImageBufferToDestination(destination, *colorSpace, AlphaPremultiplication::Unpremultiplied, rect);
499
                return;
505
                return;
500
            }
506
            }
501
            m_unmultipliedImageResult = m_imageBufferResult->getPixelBuffer(AlphaPremultiplication::Unpremultiplied, { IntPoint(), m_absolutePaintRect.size() });
507
            PixelBufferFormat format { AlphaPremultiplication::Unpremultiplied, PixelFormat::RGBA8, DestinationColorSpace::SRGB };
508
            m_unmultipliedImageResult = m_imageBufferResult->getPixelBuffer(format, { IntPoint(), m_absolutePaintRect.size() });
502
            if (!m_unmultipliedImageResult)
509
            if (!m_unmultipliedImageResult)
503
                return;
510
                return;
504
        } else {
511
        } else {
Lines 513-519 void FilterEffect::copyUnmultipliedResul Source/WebCore/platform/graphics/filters/FilterEffect.cpp_sec6
513
        }
520
        }
514
    }
521
    }
515
    if (requiresPixelBufferColorSpaceConversion(colorSpace)) {
522
    if (requiresPixelBufferColorSpaceConversion(colorSpace)) {
516
        copyConvertedPixelBufferToDestination(destination, *m_unmultipliedImageResult, *colorSpace, AlphaPremultiplication::Unpremultiplied, rect);
523
        copyConvertedPixelBufferToDestination(destination, *m_unmultipliedImageResult, *colorSpace, rect);
517
        return;
524
        return;
518
    }
525
    }
519
    copyImageBytes(m_unmultipliedImageResult->data(), destination, rect);
526
    copyImageBytes(m_unmultipliedImageResult->data(), destination, rect);
Lines 532-538 void FilterEffect::copyPremultipliedResu Source/WebCore/platform/graphics/filters/FilterEffect.cpp_sec7
532
                copyConvertedImageBufferToDestination(destination, *colorSpace, AlphaPremultiplication::Premultiplied, rect);
539
                copyConvertedImageBufferToDestination(destination, *colorSpace, AlphaPremultiplication::Premultiplied, rect);
533
                return;
540
                return;
534
            }
541
            }
535
            m_premultipliedImageResult = m_imageBufferResult->getPixelBuffer(AlphaPremultiplication::Premultiplied, { IntPoint(), m_absolutePaintRect.size() });
542
            PixelBufferFormat format { AlphaPremultiplication::Premultiplied, PixelFormat::RGBA8, DestinationColorSpace::SRGB };
543
            m_premultipliedImageResult = m_imageBufferResult->getPixelBuffer(format, { IntPoint(), m_absolutePaintRect.size() });
536
            if (!m_premultipliedImageResult)
544
            if (!m_premultipliedImageResult)
537
                return;
545
                return;
538
        } else {
546
        } else {
Lines 548-554 void FilterEffect::copyPremultipliedResu Source/WebCore/platform/graphics/filters/FilterEffect.cpp_sec8
548
    }
556
    }
549
557
550
    if (requiresPixelBufferColorSpaceConversion(colorSpace)) {
558
    if (requiresPixelBufferColorSpaceConversion(colorSpace)) {
551
        copyConvertedPixelBufferToDestination(destination, *m_premultipliedImageResult, *colorSpace, AlphaPremultiplication::Premultiplied, rect);
559
        copyConvertedPixelBufferToDestination(destination, *m_premultipliedImageResult, *colorSpace, rect);
552
        return;
560
        return;
553
    }
561
    }
554
    copyImageBytes(m_premultipliedImageResult->data(), destination, rect);
562
    copyImageBytes(m_premultipliedImageResult->data(), destination, rect);
- Source/WebCore/platform/graphics/filters/FilterEffect.h -2 / +2 lines
Lines 204-213 private: Source/WebCore/platform/graphics/filters/FilterEffect.h_sec1
204
204
205
    void copyImageBytes(const Uint8ClampedArray& source, Uint8ClampedArray& destination, const IntRect&) const;
205
    void copyImageBytes(const Uint8ClampedArray& source, Uint8ClampedArray& destination, const IntRect&) const;
206
    void copyConvertedImageBufferToDestination(Uint8ClampedArray&, DestinationColorSpace, AlphaPremultiplication, const IntRect&);
206
    void copyConvertedImageBufferToDestination(Uint8ClampedArray&, DestinationColorSpace, AlphaPremultiplication, const IntRect&);
207
    void copyConvertedPixelBufferToDestination(Uint8ClampedArray&, PixelBuffer&, DestinationColorSpace, AlphaPremultiplication, const IntRect&);
207
    void copyConvertedPixelBufferToDestination(Uint8ClampedArray&, PixelBuffer&, DestinationColorSpace, const IntRect&);
208
    bool requiresPixelBufferColorSpaceConversion(Optional<DestinationColorSpace>);
208
    bool requiresPixelBufferColorSpaceConversion(Optional<DestinationColorSpace>);
209
    Optional<PixelBuffer> convertPixelBufferToColorSpace(DestinationColorSpace, PixelBuffer&, AlphaPremultiplication);
210
    Optional<PixelBuffer> convertImageBufferToColorSpace(DestinationColorSpace, ImageBuffer&, const IntRect&, AlphaPremultiplication);
209
    Optional<PixelBuffer> convertImageBufferToColorSpace(DestinationColorSpace, ImageBuffer&, const IntRect&, AlphaPremultiplication);
210
    Optional<PixelBuffer> convertPixelBufferToColorSpace(DestinationColorSpace, PixelBuffer&);
211
    
211
    
212
212
213
    Filter& m_filter;
213
    Filter& m_filter;
- Source/WebCore/platform/graphics/win/ImageBufferDirect2DBackend.cpp -3 / +3 lines
Lines 312-327 Vector<uint8_t> ImageBufferDirect2DBacke Source/WebCore/platform/graphics/win/ImageBufferDirect2DBackend.cpp_sec1
312
    return { };
312
    return { };
313
}
313
}
314
314
315
Optional<PixelBuffer> ImageBufferDirect2DBackend::getPixelBuffer(AlphaPremultiplication outputFormat, const IntRect& srcRect) const
315
Optional<PixelBuffer> ImageBufferDirect2DBackend::getPixelBuffer(PixelBufferFormat outputFormat, const IntRect& srcRect) const
316
{
316
{
317
    notImplemented();
317
    notImplemented();
318
    return ImageBufferBackend::getPixelBuffer(outputFormat, srcRect, nullptr);
318
    return ImageBufferBackend::getPixelBuffer(outputFormat, srcRect, nullptr);
319
}
319
}
320
320
321
void ImageBufferDirect2DBackend::putPixelBuffer(AlphaPremultiplication inputFormat, const PixelBuffer& pixelBuffer, const IntRect& srcRect, const IntPoint& destPoint, AlphaPremultiplication destFormat)
321
void ImageBufferDirect2DBackend::putPixelBuffer(const PixelBuffer& pixelBuffer, const IntRect& srcRect, const IntPoint& destPoint, AlphaPremultiplication destFormat)
322
{
322
{
323
    notImplemented();
323
    notImplemented();
324
    ImageBufferBackend::putPixelBuffer(inputFormat, pixelBuffer, srcRect, destPoint, destFormat, nullptr);
324
    ImageBufferBackend::putPixelBuffer(pixelBuffer, srcRect, destPoint, destFormat, nullptr);
325
}
325
}
326
326
327
} // namespace WebCore
327
} // namespace WebCore
- Source/WebCore/platform/graphics/win/ImageBufferDirect2DBackend.h -2 / +2 lines
Lines 53-60 public: Source/WebCore/platform/graphics/win/ImageBufferDirect2DBackend.h_sec1
53
    Vector<uint8_t> toData(const String& mimeType, Optional<double> quality) const override;
53
    Vector<uint8_t> toData(const String& mimeType, Optional<double> quality) const override;
54
    Vector<uint8_t> toBGRAData() const override;
54
    Vector<uint8_t> toBGRAData() const override;
55
55
56
    Optional<PixelBuffer> getPixelBuffer(AlphaPremultiplication outputFormat, const IntRect&) const override;
56
    Optional<PixelBuffer> getPixelBuffer(PixelBufferFormat outputFormat, const IntRect&) const override;
57
    void putPixelBuffer(AlphaPremultiplication inputFormat, const PixelBuffer&, const IntRect& srcRect, const IntPoint& destPoint, AlphaPremultiplication destFormat) override;
57
    void putPixelBuffer(const PixelBuffer&, const IntRect& srcRect, const IntPoint& destPoint, AlphaPremultiplication destFormat) override;
58
58
59
protected:
59
protected:
60
    ImageBufferDirect2DBackend(const FloatSize& logicalSize, const IntSize& physicalSize, float resolutionScale, ColorSpace);
60
    ImageBufferDirect2DBackend(const FloatSize& logicalSize, const IntSize& physicalSize, float resolutionScale, ColorSpace);
- Source/WebCore/rendering/shapes/Shape.cpp -1 / +2 lines
Lines 197-203 std::unique_ptr<Shape> Shape::createRast Source/WebCore/rendering/shapes/Shape.cpp_sec1
197
    if (image)
197
    if (image)
198
        graphicsContext.drawImage(*image, IntRect(IntPoint(), imageRect.size()));
198
        graphicsContext.drawImage(*image, IntRect(IntPoint(), imageRect.size()));
199
199
200
    auto pixelBuffer = imageBuffer->getPixelBuffer(AlphaPremultiplication::Unpremultiplied, { IntPoint(), imageRect.size() });
200
    PixelBufferFormat format { AlphaPremultiplication::Unpremultiplied, PixelFormat::RGBA8, DestinationColorSpace::SRGB };
201
    auto pixelBuffer = imageBuffer->getPixelBuffer(format, { IntPoint(), imageRect.size() });
201
    
202
    
202
    // We could get to a value where PixelBuffer could be nullopt. A case where ImageRect.size() is huge, PixelBuffer::tryCreate
203
    // We could get to a value where PixelBuffer could be nullopt. A case where ImageRect.size() is huge, PixelBuffer::tryCreate
203
    // can return a nullopt because data size has overflowed. Refer rdar://problem/61793884
204
    // can return a nullopt because data size has overflowed. Refer rdar://problem/61793884
- Source/WebKit/ChangeLog +26 lines
Lines 1-3 Source/WebKit/ChangeLog_sec1
1
2021-05-14  Sam Weinig  <weinig@apple.com>
2
3
        Use PixelBufferFormat to specify ImageBuffer::getPixelBuffer destination format allowing for more control over data conversion
4
        https://bugs.webkit.org/show_bug.cgi?id=225813
5
6
        Reviewed by NOBODY (OOPS!).
7
8
        Update calls/implementations of getPixelBuffer/putPixelBuffer to adjust
9
        to new signature. 
10
11
        * GPUProcess/graphics/RemoteImageBuffer.h:
12
        * Shared/RemoteLayerTree/CGDisplayListImageBufferBackend.cpp:
13
        (WebKit::CGDisplayListImageBufferBackend::getPixelBuffer const):
14
        (WebKit::CGDisplayListImageBufferBackend::putPixelBuffer):
15
        * Shared/RemoteLayerTree/CGDisplayListImageBufferBackend.h:
16
        * WebProcess/GPU/graphics/ImageBufferShareableBitmapBackend.cpp:
17
        (WebKit::ImageBufferShareableBitmapBackend::getPixelBuffer const):
18
        (WebKit::ImageBufferShareableBitmapBackend::putPixelBuffer):
19
        * WebProcess/GPU/graphics/ImageBufferShareableBitmapBackend.h:
20
        * WebProcess/GPU/graphics/RemoteImageBufferProxy.h:
21
        (WebKit::RemoteImageBufferProxy::putPixelBuffer):
22
        * WebProcess/GPU/graphics/cocoa/ImageBufferShareableIOSurfaceBackend.cpp:
23
        (WebKit::ImageBufferShareableIOSurfaceBackend::getPixelBuffer const):
24
        (WebKit::ImageBufferShareableIOSurfaceBackend::putPixelBuffer):
25
        * WebProcess/GPU/graphics/cocoa/ImageBufferShareableIOSurfaceBackend.h:
26
1
2021-05-14  Alex Christensen  <achristensen@webkit.org>
27
2021-05-14  Alex Christensen  <achristensen@webkit.org>
2
28
3
        Resource Timing: secureConnectionStart == 0 when a connection is re-used
29
        Resource Timing: secureConnectionStart == 0 when a connection is re-used
- Source/WebKit/GPUProcess/graphics/RemoteImageBuffer.h -1 / +1 lines
Lines 85-91 private: Source/WebKit/GPUProcess/graphics/RemoteImageBuffer.h_sec1
85
85
86
        if (item.is<WebCore::DisplayList::PutPixelBuffer>()) {
86
        if (item.is<WebCore::DisplayList::PutPixelBuffer>()) {
87
            auto& putPixelBufferItem = item.get<WebCore::DisplayList::PutPixelBuffer>();
87
            auto& putPixelBufferItem = item.get<WebCore::DisplayList::PutPixelBuffer>();
88
            putPixelBuffer(putPixelBufferItem.inputFormat(), putPixelBufferItem.pixelBuffer(), putPixelBufferItem.srcRect(), putPixelBufferItem.destPoint(), putPixelBufferItem.destFormat());
88
            putPixelBuffer(putPixelBufferItem.pixelBuffer(), putPixelBufferItem.srcRect(), putPixelBufferItem.destPoint(), putPixelBufferItem.destFormat());
89
            return true;
89
            return true;
90
        }
90
        }
91
91
- Source/WebKit/Shared/RemoteLayerTree/CGDisplayListImageBufferBackend.cpp -2 / +2 lines
Lines 105-117 Vector<uint8_t> CGDisplayListImageBuffer Source/WebKit/Shared/RemoteLayerTree/CGDisplayListImageBufferBackend.cpp_sec1
105
    return { };
105
    return { };
106
}
106
}
107
107
108
Optional<WebCore::PixelBuffer> CGDisplayListImageBufferBackend::getPixelBuffer(WebCore::AlphaPremultiplication, const WebCore::IntRect&) const
108
Optional<WebCore::PixelBuffer> CGDisplayListImageBufferBackend::getPixelBuffer(const WebCore::PixelBufferFormat&, const WebCore::IntRect&) const
109
{
109
{
110
    ASSERT_NOT_REACHED();
110
    ASSERT_NOT_REACHED();
111
    return { };
111
    return { };
112
}
112
}
113
113
114
void CGDisplayListImageBufferBackend::putPixelBuffer(WebCore::AlphaPremultiplication, const WebCore::PixelBuffer&, const WebCore::IntRect&, const WebCore::IntPoint&, WebCore::AlphaPremultiplication)
114
void CGDisplayListImageBufferBackend::putPixelBuffer(const WebCore::PixelBuffer&, const WebCore::IntRect&, const WebCore::IntPoint&, WebCore::AlphaPremultiplication)
115
{
115
{
116
    ASSERT_NOT_REACHED();
116
    ASSERT_NOT_REACHED();
117
}
117
}
- Source/WebKit/Shared/RemoteLayerTree/CGDisplayListImageBufferBackend.h -2 / +2 lines
Lines 50-57 public: Source/WebKit/Shared/RemoteLayerTree/CGDisplayListImageBufferBackend.h_sec1
50
    // NOTE: These all ASSERT_NOT_REACHED().
50
    // NOTE: These all ASSERT_NOT_REACHED().
51
    RefPtr<WebCore::NativeImage> copyNativeImage(WebCore::BackingStoreCopy = WebCore::CopyBackingStore) const override;
51
    RefPtr<WebCore::NativeImage> copyNativeImage(WebCore::BackingStoreCopy = WebCore::CopyBackingStore) const override;
52
    Vector<uint8_t> toBGRAData() const override;
52
    Vector<uint8_t> toBGRAData() const override;
53
    Optional<WebCore::PixelBuffer> getPixelBuffer(WebCore::AlphaPremultiplication outputFormat, const WebCore::IntRect&) const override;
53
    Optional<WebCore::PixelBuffer> getPixelBuffer(const WebCore::PixelBufferFormat& outputFormat, const WebCore::IntRect&) const override;
54
    void putPixelBuffer(WebCore::AlphaPremultiplication inputFormat, const WebCore::PixelBuffer&, const WebCore::IntRect& srcRect, const WebCore::IntPoint& destPoint, WebCore::AlphaPremultiplication destFormat) override;
54
    void putPixelBuffer(const WebCore::PixelBuffer&, const WebCore::IntRect& srcRect, const WebCore::IntPoint& destPoint, WebCore::AlphaPremultiplication destFormat) override;
55
55
56
    static constexpr bool isOriginAtUpperLeftCorner = true;
56
    static constexpr bool isOriginAtUpperLeftCorner = true;
57
57
- Source/WebKit/WebProcess/GPU/graphics/ImageBufferShareableBitmapBackend.cpp -3 / +3 lines
Lines 163-176 Vector<uint8_t> ImageBufferShareableBitm Source/WebKit/WebProcess/GPU/graphics/ImageBufferShareableBitmapBackend.cpp_sec1
163
    return ImageBufferBackend::toBGRAData(m_bitmap->data());
163
    return ImageBufferBackend::toBGRAData(m_bitmap->data());
164
}
164
}
165
165
166
Optional<PixelBuffer> ImageBufferShareableBitmapBackend::getPixelBuffer(AlphaPremultiplication outputFormat, const IntRect& srcRect) const
166
Optional<PixelBuffer> ImageBufferShareableBitmapBackend::getPixelBuffer(const PixelBufferFormat& outputFormat, const IntRect& srcRect) const
167
{
167
{
168
    return ImageBufferBackend::getPixelBuffer(outputFormat, srcRect, m_bitmap->data());
168
    return ImageBufferBackend::getPixelBuffer(outputFormat, srcRect, m_bitmap->data());
169
}
169
}
170
170
171
void ImageBufferShareableBitmapBackend::putPixelBuffer(AlphaPremultiplication inputFormat, const PixelBuffer& pixelBuffer, const IntRect& srcRect, const IntPoint& destPoint, WebCore::AlphaPremultiplication destFormat)
171
void ImageBufferShareableBitmapBackend::putPixelBuffer(const PixelBuffer& pixelBuffer, const IntRect& srcRect, const IntPoint& destPoint, WebCore::AlphaPremultiplication destFormat)
172
{
172
{
173
    ImageBufferBackend::putPixelBuffer(inputFormat, pixelBuffer, srcRect, destPoint, destFormat, m_bitmap->data());
173
    ImageBufferBackend::putPixelBuffer(pixelBuffer, srcRect, destPoint, destFormat, m_bitmap->data());
174
}
174
}
175
175
176
} // namespace WebKit
176
} // namespace WebKit
- Source/WebKit/WebProcess/GPU/graphics/ImageBufferShareableBitmapBackend.h -2 / +2 lines
Lines 59-66 public: Source/WebKit/WebProcess/GPU/graphics/ImageBufferShareableBitmapBackend.h_sec1
59
    RefPtr<WebCore::Image> copyImage(WebCore::BackingStoreCopy = WebCore::CopyBackingStore, WebCore::PreserveResolution = WebCore::PreserveResolution::No) const override;
59
    RefPtr<WebCore::Image> copyImage(WebCore::BackingStoreCopy = WebCore::CopyBackingStore, WebCore::PreserveResolution = WebCore::PreserveResolution::No) const override;
60
60
61
    Vector<uint8_t> toBGRAData() const override;
61
    Vector<uint8_t> toBGRAData() const override;
62
    Optional<WebCore::PixelBuffer> getPixelBuffer(WebCore::AlphaPremultiplication outputFormat, const WebCore::IntRect&) const override;
62
    Optional<WebCore::PixelBuffer> getPixelBuffer(const WebCore::PixelBufferFormat& outputFormat, const WebCore::IntRect&) const override;
63
    void putPixelBuffer(WebCore::AlphaPremultiplication inputFormat, const WebCore::PixelBuffer&, const WebCore::IntRect& srcRect, const WebCore::IntPoint& destPoint, WebCore::AlphaPremultiplication destFormat) override;
63
    void putPixelBuffer(const WebCore::PixelBuffer&, const WebCore::IntRect& srcRect, const WebCore::IntPoint& destPoint, WebCore::AlphaPremultiplication destFormat) override;
64
64
65
private:
65
private:
66
    unsigned bytesPerRow() const override;
66
    unsigned bytesPerRow() const override;
- Source/WebKit/WebProcess/GPU/graphics/RemoteImageBufferProxy.h -5 / +4 lines
Lines 194-205 protected: Source/WebKit/WebProcess/GPU/graphics/RemoteImageBufferProxy.h_sec1
194
        return bitmap->createImage();
194
        return bitmap->createImage();
195
    }
195
    }
196
196
197
    Optional<WebCore::PixelBuffer> getPixelBuffer(WebCore::AlphaPremultiplication outputFormat, const WebCore::IntRect& srcRect) const override
197
    Optional<WebCore::PixelBuffer> getPixelBuffer(const WebCore::PixelBufferFormat& destinationFormat, const WebCore::IntRect& srcRect) const override
198
    {
198
    {
199
        if (UNLIKELY(!m_remoteRenderingBackendProxy))
199
        if (UNLIKELY(!m_remoteRenderingBackendProxy))
200
            return WTF::nullopt;
200
            return WTF::nullopt;
201
201
202
        WebCore::PixelBufferFormat destinationFormat { outputFormat, WebCore::PixelFormat::RGBA8, WebCore::DestinationColorSpace::SRGB };
203
        auto pixelBuffer = WebCore::PixelBuffer::tryCreate(destinationFormat, srcRect.size());
202
        auto pixelBuffer = WebCore::PixelBuffer::tryCreate(destinationFormat, srcRect.size());
204
        if (!pixelBuffer)
203
        if (!pixelBuffer)
205
            return WTF::nullopt;
204
            return WTF::nullopt;
Lines 211-217 protected: Source/WebKit/WebProcess/GPU/graphics/RemoteImageBufferProxy.h_sec2
211
            return WTF::nullopt;
210
            return WTF::nullopt;
212
211
213
        auto& mutableThis = const_cast<RemoteImageBufferProxy&>(*this);
212
        auto& mutableThis = const_cast<RemoteImageBufferProxy&>(*this);
214
        mutableThis.m_drawingContext.recorder().getPixelBuffer(outputFormat, srcRect);
213
        mutableThis.m_drawingContext.recorder().getPixelBuffer(destinationFormat, srcRect);
215
        mutableThis.flushDrawingContextAsync();
214
        mutableThis.flushDrawingContextAsync();
216
215
217
        if (m_remoteRenderingBackendProxy->waitForGetPixelBufferToComplete(timeout))
216
        if (m_remoteRenderingBackendProxy->waitForGetPixelBufferToComplete(timeout))
Lines 221-232 protected: Source/WebKit/WebProcess/GPU/graphics/RemoteImageBufferProxy.h_sec3
221
        return pixelBuffer;
220
        return pixelBuffer;
222
    }
221
    }
223
222
224
    void putPixelBuffer(WebCore::AlphaPremultiplication inputFormat, const WebCore::PixelBuffer& pixelBuffer, const WebCore::IntRect& srcRect, const WebCore::IntPoint& destPoint = { }, WebCore::AlphaPremultiplication destFormat = WebCore::AlphaPremultiplication::Premultiplied) override
223
    void putPixelBuffer(const WebCore::PixelBuffer& pixelBuffer, const WebCore::IntRect& srcRect, const WebCore::IntPoint& destPoint = { }, WebCore::AlphaPremultiplication destFormat = WebCore::AlphaPremultiplication::Premultiplied) override
225
    {
224
    {
226
        // 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.
225
        // 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.
227
        // This means that putPixelBuffer() is only called when resolutionScale() == 1.
226
        // This means that putPixelBuffer() is only called when resolutionScale() == 1.
228
        ASSERT(resolutionScale() == 1);
227
        ASSERT(resolutionScale() == 1);
229
        m_drawingContext.recorder().putPixelBuffer(inputFormat, pixelBuffer, srcRect, destPoint, destFormat);
228
        m_drawingContext.recorder().putPixelBuffer(pixelBuffer, srcRect, destPoint, destFormat);
230
    }
229
    }
231
230
232
    bool prefersPreparationForDisplay() override { return true; }
231
    bool prefersPreparationForDisplay() override { return true; }
- Source/WebKit/WebProcess/GPU/graphics/cocoa/ImageBufferShareableIOSurfaceBackend.cpp -2 / +2 lines
Lines 120-132 Vector<uint8_t> ImageBufferShareableIOSu Source/WebKit/WebProcess/GPU/graphics/cocoa/ImageBufferShareableIOSurfaceBackend.cpp_sec1
120
    return { };
120
    return { };
121
}
121
}
122
122
123
Optional<PixelBuffer> ImageBufferShareableIOSurfaceBackend::getPixelBuffer(AlphaPremultiplication, const IntRect&) const
123
Optional<PixelBuffer> ImageBufferShareableIOSurfaceBackend::getPixelBuffer(const PixelBufferFormat&, const IntRect&) const
124
{
124
{
125
    RELEASE_ASSERT_NOT_REACHED();
125
    RELEASE_ASSERT_NOT_REACHED();
126
    return { };
126
    return { };
127
}
127
}
128
128
129
void ImageBufferShareableIOSurfaceBackend::putPixelBuffer(AlphaPremultiplication, const PixelBuffer&, const IntRect&, const IntPoint&, AlphaPremultiplication)
129
void ImageBufferShareableIOSurfaceBackend::putPixelBuffer(const PixelBuffer&, const IntRect&, const IntPoint&, AlphaPremultiplication)
130
{
130
{
131
    RELEASE_ASSERT_NOT_REACHED();
131
    RELEASE_ASSERT_NOT_REACHED();
132
}
132
}
- Source/WebKit/WebProcess/GPU/graphics/cocoa/ImageBufferShareableIOSurfaceBackend.h -2 / +2 lines
Lines 60-67 public: Source/WebKit/WebProcess/GPU/graphics/cocoa/ImageBufferShareableIOSurfaceBackend.h_sec1
60
    String toDataURL(const String& mimeType, Optional<double> quality, WebCore::PreserveResolution) const override;
60
    String toDataURL(const String& mimeType, Optional<double> quality, WebCore::PreserveResolution) const override;
61
    Vector<uint8_t> toData(const String& mimeType, Optional<double> quality) const override;
61
    Vector<uint8_t> toData(const String& mimeType, Optional<double> quality) const override;
62
    Vector<uint8_t> toBGRAData() const override;
62
    Vector<uint8_t> toBGRAData() const override;
63
    Optional<WebCore::PixelBuffer> getPixelBuffer(WebCore::AlphaPremultiplication outputFormat, const WebCore::IntRect&) const override;
63
    Optional<WebCore::PixelBuffer> getPixelBuffer(const WebCore::PixelBufferFormat& outputFormat, const WebCore::IntRect&) const override;
64
    void putPixelBuffer(WebCore::AlphaPremultiplication inputFormat, const WebCore::PixelBuffer&, const WebCore::IntRect& srcRect, const WebCore::IntPoint& destPoint, WebCore::AlphaPremultiplication destFormat) override;
64
    void putPixelBuffer(const WebCore::PixelBuffer&, const WebCore::IntRect& srcRect, const WebCore::IntPoint& destPoint, WebCore::AlphaPremultiplication destFormat) override;
65
65
66
    static constexpr bool isOriginAtUpperLeftCorner = true;
66
    static constexpr bool isOriginAtUpperLeftCorner = true;
67
    static constexpr bool canMapBackingStore = false;
67
    static constexpr bool canMapBackingStore = false;

Return to Bug 225813