Title: [289518] trunk/Source
Revision
289518
Author
s...@apple.com
Date
2022-02-09 21:18:02 -0800 (Wed, 09 Feb 2022)

Log Message

[GPU Process] Move ImageBuffer::createCompatibleImageBuffer() and SVGRenderingContext::createImageBuffer to GraphicsContext
https://bugs.webkit.org/show_bug.cgi?id=235758
rdar://88478470

Reviewed by Simon Fraser.

Source/WebCore:

The goal of this patch is to record the drawing if the concrete type of
the GraphicsContext is RemoteDisplayListRecorderProxy. Currently all the
intermediate compatible ImageBuffers are of type ConcreteImageBuffer.
The drawing to these ImageBuffers still happens in the WebProcess. Moreover
when we call drawImageBuffer() or clipToImageBuffer() for one of these
intermediate ImageBuffers to a remote ImageBuffer, we have to sink the
intermediate ImageBuffer to a NativeImage and send it to GPUProcess.

To fix this, the new enum 'RenderingMethod' will be used when creating
the ImageBuffer methods. The value of RenderingMethod can be one of the
following constants:

1. Default: The type of the created ImageBuffer will match the type of
   the underlying ImageBuffer of the GraphicsContext.

2. DisplayList: A DisplayList::ImageBuffer will be created whose
   GraphicsContext will be of type DisplayList::RecorderImpl.

3. Local: The ImageBuffer will be of type ConcreteImageBuffer and it will
   hold a platform GraphicsContext.

Also GraphicsContext will provide these functions for creating an
ImageBuffer:

1. GraphicsContext::createImageBuffer() (virtual): Creates a
   ConcreteImageBuffer or a DisplayList::ImageBuffer. The type of the created
   ImageBuffer is controlled by the argument 'renderingMethod'. Because
   RemoteDisplayListRecorderProxy is a super class of GraphicsContext,
   it overrides this method and returns the desired RemoteImageBuffer.
   RemoteDisplayListRecorderProxy has access to RemotRenderingBackendProxy
   so it can call its createImageBuffer().

2. GraphicsContext::createImageBuffer() (non-virtual): Creates a scaled
   ImageBuffer and sets the context accordingly. The type of the created
   ImageBuffer is controlled by the argument 'renderingMethod'.

3. GraphicsContext::createCompatibleImageBuffer() (virtual): Takes the
   scaleFactor() into consideration when creating the ImageBuffer.
   RemoteDisplayListRecorderProxy will override this function to return
   an Unaccelerated ImageBuffer if 'renderingMethod != Default'. This is
   to ensure that for GPUProcess drawing, no intermediate local
   ImageBuffers will draw to an IOSurface in WebProcess.

Two versions of these functions are provided: one takes a FloatSize and
the other takes a FloatRecct. The FloatRect version expands the four
corners of the rectangle to full pixels.

* html/CustomPaintCanvas.cpp:
(WebCore::CustomPaintCanvas::replayDisplayList const):
* html/CustomPaintImage.cpp:
(WebCore::CustomPaintImage::drawPattern):
* html/OffscreenCanvas.cpp:
(WebCore::OffscreenCanvas::transferToImageBitmap):
(WebCore::OffscreenCanvas::commitToPlaceholderCanvas):
* html/canvas/CanvasRenderingContext2DBase.cpp:
(WebCore::CanvasRenderingContext2DBase::drawImage):
* platform/cocoa/ThemeCocoa.mm:
(WebCore::drawApplePayButton):
* platform/graphics/BitmapImage.cpp:
(WebCore::BitmapImage::drawPattern):
* platform/graphics/CrossfadeGeneratedImage.cpp:
(WebCore::CrossfadeGeneratedImage::drawPattern):
* platform/graphics/GradientImage.cpp:
(WebCore::GradientImage::drawPattern):
* platform/graphics/GraphicsContext.cpp:
(WebCore::scaledImageBufferSize):
(WebCore::scaledImageBufferRect):
(WebCore::clampingScaleForImageBufferSize):
(WebCore::GraphicsContext::compatibleImageBufferSize const):
(WebCore::GraphicsContext::createImageBuffer const):
(WebCore::GraphicsContext::createCompatibleImageBuffer const):
(WebCore::GraphicsContext::clipToDrawingCommands):
* platform/graphics/GraphicsContext.h:
(WebCore::GraphicsContext::createImageBuffer):
* platform/graphics/ImageBuffer.cpp:
(WebCore::ImageBuffer::clone const):
(WebCore::ImageBuffer::createCompatibleBuffer): Deleted.
(WebCore::ImageBuffer::compatibleBufferSize): Deleted.
(WebCore::ImageBuffer::compatibleBufferInfo): Deleted.
(WebCore::ImageBuffer::copyRectToBuffer): Deleted.
* platform/graphics/ImageBuffer.h:
* platform/graphics/NamedImageGeneratedImage.cpp:
(WebCore::NamedImageGeneratedImage::drawPattern):
* platform/graphics/RenderingMode.h:
* platform/graphics/cg/PDFDocumentImage.cpp:
(WebCore::PDFDocumentImage::updateCachedImageIfNeeded):
(WebCore::PDFDocumentImage::draw):
* platform/graphics/coretext/DrawGlyphsRecorderCoreText.cpp:
(WebCore::DrawGlyphsRecorder::drawOTSVGRun):
* platform/graphics/displaylists/DisplayListRecorder.cpp:
(WebCore::DisplayList::Recorder::createImageBuffer const):
* platform/graphics/displaylists/DisplayListRecorder.h:
* platform/graphics/displaylists/DisplayListReplayer.cpp:
(WebCore::DisplayList::Replayer::applyItem):
* platform/mac/ThemeMac.mm:
(WebCore::ThemeMac::drawCellOrFocusRingWithViewIntoContext):
* rendering/RenderBoxModelObject.cpp:
(WebCore::RenderBoxModelObject::paintFillLayerExtended):
* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::setupFilters):
* rendering/RenderLayerBacking.cpp:
(WebCore::patternForDescription):
* rendering/RenderLayerFilters.cpp:
(WebCore::RenderLayerFilters::allocateBackingStoreIfNeeded):
(WebCore::RenderLayerFilters::beginFilterEffect):
* rendering/RenderLayerFilters.h:
* rendering/RenderThemeCocoa.mm:
(WebCore::RenderThemeCocoa::paintApplePayButton):
* rendering/RenderThemeMac.mm:
(WebCore::RenderThemeMac::paintListButtonForInput):
(WebCore::RenderThemeMac::paintProgressBar):
* rendering/svg/RenderSVGResourceClipper.cpp:
(WebCore::RenderSVGResourceClipper::applyClippingToContext):
* rendering/svg/RenderSVGResourceFilter.cpp:
(WebCore::RenderSVGResourceFilter::applyResource):
* rendering/svg/RenderSVGResourceGradient.cpp:
(WebCore::createMaskAndSwapContextForTextGradient):
(WebCore::clipToTextMask):
* rendering/svg/RenderSVGResourceMasker.cpp:
(WebCore::RenderSVGResourceMasker::applyResource):
* rendering/svg/RenderSVGResourcePattern.cpp:
(WebCore::RenderSVGResourcePattern::buildPattern):
(WebCore::RenderSVGResourcePattern::createTileImage const):
* rendering/svg/RenderSVGResourcePattern.h:
* rendering/svg/SVGRenderingContext.cpp:
(WebCore::SVGRenderingContext::clipToImageBuffer):
(WebCore::SVGRenderingContext::bufferForeground):
(WebCore::SVGRenderingContext::createImageBuffer): Deleted.
(WebCore::SVGRenderingContext::clear2DRotation): Deleted.
* rendering/svg/SVGRenderingContext.h:
* svg/SVGFEImageElement.cpp:
(WebCore::scaledImageBufferRect):
(WebCore::clampingScaleForImageBufferSize):
(WebCore::createImageBuffer):
(WebCore::SVGFEImageElement::imageBufferForEffect const):
* svg/graphics/SVGImage.cpp:
(WebCore::SVGImage::drawPatternForContainer):

Source/WebKit:

* GPUProcess/graphics/RemoteDisplayListRecorder.cpp:
(WebKit::RemoteDisplayListRecorder::beginClipToDrawingCommands):
* WebProcess/GPU/graphics/RemoteDisplayListRecorderProxy.cpp:
(WebKit::RemoteDisplayListRecorderProxy::createImageBuffer const):
(WebKit::RemoteDisplayListRecorderProxy::createCompatibleImageBuffer const):
* WebProcess/GPU/graphics/RemoteDisplayListRecorderProxy.h:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (289517 => 289518)


--- trunk/Source/WebCore/ChangeLog	2022-02-10 04:11:48 UTC (rev 289517)
+++ trunk/Source/WebCore/ChangeLog	2022-02-10 05:18:02 UTC (rev 289518)
@@ -1,3 +1,149 @@
+2022-02-09  Said Abou-Hallawa  <s...@apple.com>
+
+        [GPU Process] Move ImageBuffer::createCompatibleImageBuffer() and SVGRenderingContext::createImageBuffer to GraphicsContext
+        https://bugs.webkit.org/show_bug.cgi?id=235758
+        rdar://88478470
+
+        Reviewed by Simon Fraser.
+
+        The goal of this patch is to record the drawing if the concrete type of 
+        the GraphicsContext is RemoteDisplayListRecorderProxy. Currently all the
+        intermediate compatible ImageBuffers are of type ConcreteImageBuffer.
+        The drawing to these ImageBuffers still happens in the WebProcess. Moreover
+        when we call drawImageBuffer() or clipToImageBuffer() for one of these
+        intermediate ImageBuffers to a remote ImageBuffer, we have to sink the
+        intermediate ImageBuffer to a NativeImage and send it to GPUProcess.
+
+        To fix this, the new enum 'RenderingMethod' will be used when creating
+        the ImageBuffer methods. The value of RenderingMethod can be one of the 
+        following constants:
+
+        1. Default: The type of the created ImageBuffer will match the type of
+           the underlying ImageBuffer of the GraphicsContext.
+
+        2. DisplayList: A DisplayList::ImageBuffer will be created whose
+           GraphicsContext will be of type DisplayList::RecorderImpl.
+
+        3. Local: The ImageBuffer will be of type ConcreteImageBuffer and it will
+           hold a platform GraphicsContext.
+
+        Also GraphicsContext will provide these functions for creating an 
+        ImageBuffer:
+
+        1. GraphicsContext::createImageBuffer() (virtual): Creates a 
+           ConcreteImageBuffer or a DisplayList::ImageBuffer. The type of the created
+           ImageBuffer is controlled by the argument 'renderingMethod'. Because
+           RemoteDisplayListRecorderProxy is a super class of GraphicsContext,
+           it overrides this method and returns the desired RemoteImageBuffer.
+           RemoteDisplayListRecorderProxy has access to RemotRenderingBackendProxy
+           so it can call its createImageBuffer().
+
+        2. GraphicsContext::createImageBuffer() (non-virtual): Creates a scaled
+           ImageBuffer and sets the context accordingly. The type of the created
+           ImageBuffer is controlled by the argument 'renderingMethod'.
+
+        3. GraphicsContext::createCompatibleImageBuffer() (virtual): Takes the
+           scaleFactor() into consideration when creating the ImageBuffer. 
+           RemoteDisplayListRecorderProxy will override this function to return
+           an Unaccelerated ImageBuffer if 'renderingMethod != Default'. This is
+           to ensure that for GPUProcess drawing, no intermediate local
+           ImageBuffers will draw to an IOSurface in WebProcess.
+
+        Two versions of these functions are provided: one takes a FloatSize and
+        the other takes a FloatRecct. The FloatRect version expands the four
+        corners of the rectangle to full pixels.
+
+        * html/CustomPaintCanvas.cpp:
+        (WebCore::CustomPaintCanvas::replayDisplayList const):
+        * html/CustomPaintImage.cpp:
+        (WebCore::CustomPaintImage::drawPattern):
+        * html/OffscreenCanvas.cpp:
+        (WebCore::OffscreenCanvas::transferToImageBitmap):
+        (WebCore::OffscreenCanvas::commitToPlaceholderCanvas):
+        * html/canvas/CanvasRenderingContext2DBase.cpp:
+        (WebCore::CanvasRenderingContext2DBase::drawImage):
+        * platform/cocoa/ThemeCocoa.mm:
+        (WebCore::drawApplePayButton):
+        * platform/graphics/BitmapImage.cpp:
+        (WebCore::BitmapImage::drawPattern):
+        * platform/graphics/CrossfadeGeneratedImage.cpp:
+        (WebCore::CrossfadeGeneratedImage::drawPattern):
+        * platform/graphics/GradientImage.cpp:
+        (WebCore::GradientImage::drawPattern):
+        * platform/graphics/GraphicsContext.cpp:
+        (WebCore::scaledImageBufferSize):
+        (WebCore::scaledImageBufferRect):
+        (WebCore::clampingScaleForImageBufferSize):
+        (WebCore::GraphicsContext::compatibleImageBufferSize const):
+        (WebCore::GraphicsContext::createImageBuffer const):
+        (WebCore::GraphicsContext::createCompatibleImageBuffer const):
+        (WebCore::GraphicsContext::clipToDrawingCommands):
+        * platform/graphics/GraphicsContext.h:
+        (WebCore::GraphicsContext::createImageBuffer):
+        * platform/graphics/ImageBuffer.cpp:
+        (WebCore::ImageBuffer::clone const):
+        (WebCore::ImageBuffer::createCompatibleBuffer): Deleted.
+        (WebCore::ImageBuffer::compatibleBufferSize): Deleted.
+        (WebCore::ImageBuffer::compatibleBufferInfo): Deleted.
+        (WebCore::ImageBuffer::copyRectToBuffer): Deleted.
+        * platform/graphics/ImageBuffer.h:
+        * platform/graphics/NamedImageGeneratedImage.cpp:
+        (WebCore::NamedImageGeneratedImage::drawPattern):
+        * platform/graphics/RenderingMode.h:
+        * platform/graphics/cg/PDFDocumentImage.cpp:
+        (WebCore::PDFDocumentImage::updateCachedImageIfNeeded):
+        (WebCore::PDFDocumentImage::draw):
+        * platform/graphics/coretext/DrawGlyphsRecorderCoreText.cpp:
+        (WebCore::DrawGlyphsRecorder::drawOTSVGRun):
+        * platform/graphics/displaylists/DisplayListRecorder.cpp:
+        (WebCore::DisplayList::Recorder::createImageBuffer const):
+        * platform/graphics/displaylists/DisplayListRecorder.h:
+        * platform/graphics/displaylists/DisplayListReplayer.cpp:
+        (WebCore::DisplayList::Replayer::applyItem):
+        * platform/mac/ThemeMac.mm:
+        (WebCore::ThemeMac::drawCellOrFocusRingWithViewIntoContext):
+        * rendering/RenderBoxModelObject.cpp:
+        (WebCore::RenderBoxModelObject::paintFillLayerExtended):
+        * rendering/RenderLayer.cpp:
+        (WebCore::RenderLayer::setupFilters):
+        * rendering/RenderLayerBacking.cpp:
+        (WebCore::patternForDescription):
+        * rendering/RenderLayerFilters.cpp:
+        (WebCore::RenderLayerFilters::allocateBackingStoreIfNeeded):
+        (WebCore::RenderLayerFilters::beginFilterEffect):
+        * rendering/RenderLayerFilters.h:
+        * rendering/RenderThemeCocoa.mm:
+        (WebCore::RenderThemeCocoa::paintApplePayButton):
+        * rendering/RenderThemeMac.mm:
+        (WebCore::RenderThemeMac::paintListButtonForInput):
+        (WebCore::RenderThemeMac::paintProgressBar):
+        * rendering/svg/RenderSVGResourceClipper.cpp:
+        (WebCore::RenderSVGResourceClipper::applyClippingToContext):
+        * rendering/svg/RenderSVGResourceFilter.cpp:
+        (WebCore::RenderSVGResourceFilter::applyResource):
+        * rendering/svg/RenderSVGResourceGradient.cpp:
+        (WebCore::createMaskAndSwapContextForTextGradient):
+        (WebCore::clipToTextMask):
+        * rendering/svg/RenderSVGResourceMasker.cpp:
+        (WebCore::RenderSVGResourceMasker::applyResource):
+        * rendering/svg/RenderSVGResourcePattern.cpp:
+        (WebCore::RenderSVGResourcePattern::buildPattern):
+        (WebCore::RenderSVGResourcePattern::createTileImage const):
+        * rendering/svg/RenderSVGResourcePattern.h:
+        * rendering/svg/SVGRenderingContext.cpp:
+        (WebCore::SVGRenderingContext::clipToImageBuffer):
+        (WebCore::SVGRenderingContext::bufferForeground):
+        (WebCore::SVGRenderingContext::createImageBuffer): Deleted.
+        (WebCore::SVGRenderingContext::clear2DRotation): Deleted.
+        * rendering/svg/SVGRenderingContext.h:
+        * svg/SVGFEImageElement.cpp:
+        (WebCore::scaledImageBufferRect):
+        (WebCore::clampingScaleForImageBufferSize):
+        (WebCore::createImageBuffer):
+        (WebCore::SVGFEImageElement::imageBufferForEffect const):
+        * svg/graphics/SVGImage.cpp:
+        (WebCore::SVGImage::drawPatternForContainer):
+
 2022-02-09  Lauro Moura  <lmo...@igalia.com>
 
         Unreviewed, non-unified build fix after r289474

Modified: trunk/Source/WebCore/html/CustomPaintCanvas.cpp (289517 => 289518)


--- trunk/Source/WebCore/html/CustomPaintCanvas.cpp	2022-02-10 04:11:48 UTC (rev 289517)
+++ trunk/Source/WebCore/html/CustomPaintCanvas.cpp	2022-02-10 05:18:02 UTC (rev 289518)
@@ -73,7 +73,7 @@
     // FIXME: Using an intermediate buffer is not needed if there are no composite operations.
     auto clipBounds = ctx->clipBounds();
 
-    auto image = ImageBuffer::createCompatibleBuffer(clipBounds.size(), *ctx);
+    auto image = ctx->createCompatibleImageBuffer(clipBounds.size());
     if (!image)
         return;
 

Modified: trunk/Source/WebCore/html/CustomPaintImage.cpp (289517 => 289518)


--- trunk/Source/WebCore/html/CustomPaintImage.cpp	2022-02-10 04:11:48 UTC (rev 289517)
+++ trunk/Source/WebCore/html/CustomPaintImage.cpp	2022-02-10 05:18:02 UTC (rev 289518)
@@ -199,7 +199,7 @@
     adjustedPatternCTM.scale(1.0 / xScale, 1.0 / yScale);
     adjustedSrcRect.scale(xScale, yScale);
 
-    auto buffer = ImageBuffer::createCompatibleBuffer(adjustedSize, DestinationColorSpace::SRGB(), destContext);
+    auto buffer = destContext.createCompatibleImageBuffer(adjustedSize);
     if (!buffer)
         return;
     doCustomPaint(buffer->context(), adjustedSize);

Modified: trunk/Source/WebCore/html/OffscreenCanvas.cpp (289517 => 289518)


--- trunk/Source/WebCore/html/OffscreenCanvas.cpp	2022-02-10 04:11:48 UTC (rev 289517)
+++ trunk/Source/WebCore/html/OffscreenCanvas.cpp	2022-02-10 05:18:02 UTC (rev 289518)
@@ -283,7 +283,7 @@
         // As the canvas context state is stored in GraphicsContext, which is owned
         // by buffer(), to avoid resetting the context state, we have to make a copy and
         // clear the original buffer rather than returning the original buffer.
-        auto bufferCopy = buffer()->copyRectToBuffer(FloatRect(FloatPoint(), buffer()->logicalSize()), buffer()->colorSpace(), *drawingContext());
+        auto bufferCopy = buffer()->clone();
         downcast<OffscreenCanvasRenderingContext2D>(*m_context).clearCanvas();
         clearCopiedImage();
 
@@ -451,14 +451,13 @@
         m_context->paintRenderingResultsToCanvas();
 
     if (m_placeholderData->bufferPipeSource) {
-        auto bufferCopy = imageBuffer->copyRectToBuffer(FloatRect(FloatPoint(), imageBuffer->logicalSize()), DestinationColorSpace::SRGB(), imageBuffer->context());
-        if (bufferCopy)
+        if (auto bufferCopy = imageBuffer->clone())
             m_placeholderData->bufferPipeSource->handle(WTFMove(bufferCopy));
     }
 
     Locker locker { m_placeholderData->bufferLock };
     bool shouldPushBuffer = !m_placeholderData->pendingCommitBuffer;
-    m_placeholderData->pendingCommitBuffer = imageBuffer->copyRectToBuffer(FloatRect(FloatPoint(), imageBuffer->logicalSize()), DestinationColorSpace::SRGB(), imageBuffer->context());
+    m_placeholderData->pendingCommitBuffer = imageBuffer->clone();
     if (m_placeholderData->pendingCommitBuffer && shouldPushBuffer)
         pushBufferToPlaceholder();
 }

Modified: trunk/Source/WebCore/html/canvas/CanvasRenderingContext2DBase.cpp (289517 => 289518)


--- trunk/Source/WebCore/html/canvas/CanvasRenderingContext2DBase.cpp	2022-02-10 04:11:48 UTC (rev 289517)
+++ trunk/Source/WebCore/html/canvas/CanvasRenderingContext2DBase.cpp	2022-02-10 05:18:02 UTC (rev 289518)
@@ -1611,7 +1611,8 @@
         repaintEntireCanvas = true;
     } else if (state().globalComposite == CompositeOperator::Copy) {
         if (&sourceCanvas == &canvasBase()) {
-            if (auto copy = buffer->copyRectToBuffer(srcRect, colorSpace(), *c)) {
+            if (auto copy = c->createCompatibleImageBuffer(srcRect.size(), colorSpace())) {
+                copy->context().drawImageBuffer(*buffer, -srcRect.location());
                 clearCanvas();
                 c->drawImageBuffer(*copy, dstRect, { { }, srcRect.size() }, { state().globalComposite, state().globalBlend });
             }

Modified: trunk/Source/WebCore/platform/cocoa/ThemeCocoa.mm (289517 => 289518)


--- trunk/Source/WebCore/platform/cocoa/ThemeCocoa.mm	2022-02-10 04:11:48 UTC (rev 289517)
+++ trunk/Source/WebCore/platform/cocoa/ThemeCocoa.mm	2022-02-10 05:18:02 UTC (rev 289518)
@@ -110,7 +110,8 @@
 
 static void drawApplePayButton(GraphicsContext& context, CGPDFPageRef page, const FloatSize& size)
 {
-    auto imageBuffer = ImageBuffer::createCompatibleBuffer(size, context);
+    // Create a local ImageBuffer because decoding the PDF images has to happen in WebProcess.
+    auto imageBuffer = context.createCompatibleImageBuffer(size, DestinationColorSpace::SRGB(), RenderingMethod::Local);
     if (!imageBuffer)
         return;
 

Modified: trunk/Source/WebCore/platform/graphics/BitmapImage.cpp (289517 => 289518)


--- trunk/Source/WebCore/platform/graphics/BitmapImage.cpp	2022-02-10 04:11:48 UTC (rev 289517)
+++ trunk/Source/WebCore/platform/graphics/BitmapImage.cpp	2022-02-10 05:18:02 UTC (rev 289518)
@@ -347,7 +347,7 @@
     }
 
     if (!m_cachedImage) {
-        auto buffer = ImageBuffer::createCompatibleBuffer(expandedIntSize(tileRect.size()), DestinationColorSpace::SRGB(), ctxt);
+        auto buffer = ctxt.createCompatibleImageBuffer(expandedIntSize(tileRect.size()));
         if (!buffer)
             return;
 

Modified: trunk/Source/WebCore/platform/graphics/CrossfadeGeneratedImage.cpp (289517 => 289518)


--- trunk/Source/WebCore/platform/graphics/CrossfadeGeneratedImage.cpp	2022-02-10 04:11:48 UTC (rev 289517)
+++ trunk/Source/WebCore/platform/graphics/CrossfadeGeneratedImage.cpp	2022-02-10 05:18:02 UTC (rev 289518)
@@ -103,7 +103,7 @@
 
 void CrossfadeGeneratedImage::drawPattern(GraphicsContext& context, const FloatRect& dstRect, const FloatRect& srcRect, const AffineTransform& patternTransform, const FloatPoint& phase, const FloatSize& spacing, const ImagePaintingOptions& options)
 {
-    auto imageBuffer = ImageBuffer::create(size(), context.renderingMode(), 1, DestinationColorSpace::SRGB(), PixelFormat::BGRA8);
+    auto imageBuffer = context.createImageBuffer(size());
     if (!imageBuffer)
         return;
 

Modified: trunk/Source/WebCore/platform/graphics/GradientImage.cpp (289517 => 289518)


--- trunk/Source/WebCore/platform/graphics/GradientImage.cpp	2022-02-10 04:11:48 UTC (rev 289517)
+++ trunk/Source/WebCore/platform/graphics/GradientImage.cpp	2022-02-10 05:18:02 UTC (rev 289518)
@@ -72,7 +72,7 @@
     unsigned generatorHash = m_gradient->hash();
 
     if (!m_cachedImage || m_cachedGeneratorHash != generatorHash || m_cachedAdjustedSize != adjustedSize || !areEssentiallyEqual(destContext.scaleFactor(), m_cachedScaleFactor)) {
-        auto imageBuffer = ImageBuffer::createCompatibleBuffer(adjustedSize, DestinationColorSpace::SRGB(), destContext);
+        auto imageBuffer = destContext.createCompatibleImageBuffer(adjustedSize);
         if (!imageBuffer)
             return;
 

Modified: trunk/Source/WebCore/platform/graphics/GraphicsContext.cpp (289517 => 289518)


--- trunk/Source/WebCore/platform/graphics/GraphicsContext.cpp	2022-02-10 04:11:48 UTC (rev 289517)
+++ trunk/Source/WebCore/platform/graphics/GraphicsContext.cpp	2022-02-10 05:18:02 UTC (rev 289518)
@@ -551,6 +551,93 @@
     bidiRuns.clear();
 }
 
+static IntSize scaledImageBufferSize(const FloatSize& size, const FloatSize& scale)
+{
+    // Enlarge the buffer size if the context's transform is scaling it so we need a higher
+    // resolution than one pixel per unit.
+    return expandedIntSize(size * scale);
+}
+
+static IntRect scaledImageBufferRect(const FloatRect& rect, const FloatSize& scale)
+{
+    auto scaledRect = rect;
+    scaledRect.scale(scale);
+    return enclosingIntRect(scaledRect);
+}
+
+static FloatSize clampingScaleForImageBufferSize(const FloatSize& size)
+{
+    FloatSize clampingScale(1, 1);
+    ImageBuffer::sizeNeedsClamping(size, clampingScale);
+    return clampingScale;
+}
+
+IntSize GraphicsContext::compatibleImageBufferSize(const FloatSize& size) const
+{
+    return scaledImageBufferSize(size, scaleFactor());
+}
+
+RefPtr<ImageBuffer> GraphicsContext::createImageBuffer(const FloatSize& size, const DestinationColorSpace& colorSpace, RenderingMode renderingMode, RenderingMethod renderingMethod) const
+{
+    if (renderingMethod == RenderingMethod::DisplayList)
+        return ImageBuffer::create(size, renderingMode, ShouldUseDisplayList::Yes, RenderingPurpose::Unspecified, 1, colorSpace, PixelFormat::BGRA8);
+
+    return ImageBuffer::create(size, renderingMode, 1, colorSpace, PixelFormat::BGRA8);
+}
+
+RefPtr<ImageBuffer> GraphicsContext::createImageBuffer(const FloatSize& size, const FloatSize& scale, const DestinationColorSpace& colorSpace, std::optional<RenderingMode> renderingMode, RenderingMethod renderingMethod) const
+{
+    auto expandedScaledSize = scaledImageBufferSize(size, scale);
+    if (expandedScaledSize.isEmpty())
+        return nullptr;
+
+    auto clampingScale = clampingScaleForImageBufferSize(expandedScaledSize);
+
+    auto imageBuffer = createImageBuffer(expandedScaledSize * clampingScale, colorSpace, renderingMode.value_or(this->renderingMode()), renderingMethod);
+    if (!imageBuffer)
+        return nullptr;
+
+    imageBuffer->context().scale(clampingScale);
+
+    // 'expandedScaledSize' is mapped to 'size'. So use 'expandedScaledSize / size'
+    // not 'scale' because they are not necessarily equal.
+    imageBuffer->context().scale(expandedScaledSize / size);
+    return imageBuffer;
+}
+
+RefPtr<ImageBuffer> GraphicsContext::createImageBuffer(const FloatRect& rect, const FloatSize& scale, const DestinationColorSpace& colorSpace, std::optional<RenderingMode> renderingMode, RenderingMethod renderingMethod) const
+{
+    auto expandedScaledRect = scaledImageBufferRect(rect, scale);
+    if (expandedScaledRect.isEmpty())
+        return nullptr;
+
+    auto clampingScale = clampingScaleForImageBufferSize(expandedScaledRect.size());
+
+    auto imageBuffer = createImageBuffer(expandedScaledRect.size() * clampingScale, colorSpace, renderingMode.value_or(this->renderingMode()), renderingMethod);
+    if (!imageBuffer)
+        return nullptr;
+
+    imageBuffer->context().scale(clampingScale);
+    
+    // 'rect' is mapped to a rectangle inside expandedScaledRect.
+    imageBuffer->context().translate(-expandedScaledRect.location());
+    
+    // The size of this rectangle is not necessarily equal to expandedScaledRect.size().
+    // So use 'scale' not 'expandedScaledRect.size() / rect.size()'.
+    imageBuffer->context().scale(scale);
+    return imageBuffer;
+}
+
+RefPtr<ImageBuffer> GraphicsContext::createCompatibleImageBuffer(const FloatSize& size, const DestinationColorSpace& colorSpace, RenderingMethod renderingMethod) const
+{
+    return createImageBuffer(size, scaleFactor(), colorSpace, renderingMode(), renderingMethod);
+}
+
+RefPtr<ImageBuffer> GraphicsContext::createCompatibleImageBuffer(const FloatRect& rect, const DestinationColorSpace& colorSpace, RenderingMethod renderingMethod) const
+{
+    return createImageBuffer(rect, scaleFactor(), colorSpace, renderingMode(), renderingMethod);
+}
+
 ImageDrawResult GraphicsContext::drawImage(Image& image, const FloatPoint& destination, const ImagePaintingOptions& imagePaintingOptions)
 {
     return drawImage(image, FloatRect(destination, image.size()), FloatRect(FloatPoint(), image.size()), imagePaintingOptions);
@@ -668,7 +755,7 @@
 
 GraphicsContext::ClipToDrawingCommandsResult GraphicsContext::clipToDrawingCommands(const FloatRect& destination, const DestinationColorSpace& colorSpace, Function<void(GraphicsContext&)>&& drawingFunction)
 {
-    auto imageBuffer = ImageBuffer::createCompatibleBuffer(destination.size(), colorSpace, *this);
+    auto imageBuffer = createCompatibleImageBuffer(destination.size(), colorSpace);
     if (!imageBuffer)
         return ClipToDrawingCommandsResult::FailedToCreateImageBuffer;
 

Modified: trunk/Source/WebCore/platform/graphics/GraphicsContext.h (289517 => 289518)


--- trunk/Source/WebCore/platform/graphics/GraphicsContext.h	2022-02-10 04:11:48 UTC (rev 289517)
+++ trunk/Source/WebCore/platform/graphics/GraphicsContext.h	2022-02-10 05:18:02 UTC (rev 289518)
@@ -416,6 +416,14 @@
 
     // Images, Patterns, and Media
 
+    IntSize compatibleImageBufferSize(const FloatSize&) const;
+
+    WEBCORE_EXPORT RefPtr<ImageBuffer> createImageBuffer(const FloatSize&, const FloatSize& scale = { 1, 1 }, const DestinationColorSpace& = DestinationColorSpace::SRGB(), std::optional<RenderingMode> = std::nullopt, RenderingMethod = RenderingMethod::Default) const;
+    WEBCORE_EXPORT RefPtr<ImageBuffer> createImageBuffer(const FloatRect&, const FloatSize& scale = { 1, 1 }, const DestinationColorSpace& = DestinationColorSpace::SRGB(), std::optional<RenderingMode> = std::nullopt, RenderingMethod = RenderingMethod::Default) const;
+
+    virtual RefPtr<ImageBuffer> createCompatibleImageBuffer(const FloatSize&, const DestinationColorSpace& = DestinationColorSpace::SRGB(), RenderingMethod = RenderingMethod::Default) const;
+    virtual RefPtr<ImageBuffer> createCompatibleImageBuffer(const FloatRect&, const DestinationColorSpace& = DestinationColorSpace::SRGB(), RenderingMethod = RenderingMethod::Default) const;
+
     virtual void drawNativeImage(NativeImage&, const FloatSize& selfSize, const FloatRect& destRect, const FloatRect& srcRect, const ImagePaintingOptions& = { }) = 0;
 
     WEBCORE_EXPORT ImageDrawResult drawImage(Image&, const FloatPoint& destination, const ImagePaintingOptions& = { ImageOrientation::FromImage });
@@ -546,6 +554,8 @@
     void fillEllipseAsPath(const FloatRect&);
     void strokeEllipseAsPath(const FloatRect&);
 
+    virtual RefPtr<ImageBuffer> createImageBuffer(const FloatSize&, const DestinationColorSpace&, RenderingMode, RenderingMethod) const;
+
     FloatRect computeLineBoundsAndAntialiasingModeForText(const FloatRect&, bool printing, Color&);
 
     float dashedLineCornerWidthForStrokeWidth(float) const;

Modified: trunk/Source/WebCore/platform/graphics/ImageBuffer.cpp (289517 => 289518)


--- trunk/Source/WebCore/platform/graphics/ImageBuffer.cpp	2022-02-10 04:11:48 UTC (rev 289517)
+++ trunk/Source/WebCore/platform/graphics/ImageBuffer.cpp	2022-02-10 05:18:02 UTC (rev 289518)
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 2009 Dirk Schulze <k...@webkit.org>
  * Copyright (C) Research In Motion Limited 2011. All rights reserved.
- * Copyright (C) 2016-2020 Apple Inc. All rights reserved.
+ * Copyright (C) 2016-2022 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -72,75 +72,16 @@
     return imageBuffer;
 }
 
-RefPtr<ImageBuffer> ImageBuffer::createCompatibleBuffer(const FloatSize& size, const GraphicsContext& context)
+RefPtr<ImageBuffer> ImageBuffer::clone() const
 {
-    if (size.isEmpty())
+    auto clone = context().createCompatibleImageBuffer(logicalSize(), colorSpace());
+    if (!clone)
         return nullptr;
 
-    IntSize scaledSize = ImageBuffer::compatibleBufferSize(size, context);
-
-    RefPtr<ImageBuffer> imageBuffer;
-
-    if (context.renderingMode() == RenderingMode::Accelerated)
-        imageBuffer = AcceleratedImageBuffer::create(scaledSize, context);
-    
-    if (!imageBuffer)
-        imageBuffer = UnacceleratedImageBuffer::create(scaledSize, context);
-
-    if (!imageBuffer)
-        return nullptr;
-
-    imageBuffer->context().scale(scaledSize / size);
-    return imageBuffer;
+    clone->context().drawImageBuffer(const_cast<ImageBuffer&>(*this), FloatPoint());
+    return clone;
 }
 
-// This is useful when you need to make sure the pixel grid of the ImageBuffer aligns with the pixel grid of the context.
-// Simply saying createCompatibleBuffer(rect.size(), context) isn't sufficient in this situation, because rect.location() may not lie on a pixel boundary.
-// In this situation, we have to inflate both the left side and the right side, which can lead to different results than
-// createCompatibleBuffer(rect.size(), context) would have produced.
-auto ImageBuffer::createCompatibleBuffer(const FloatRect& rect, const GraphicsContext& context) -> std::optional<CompatibleBufferDescription>
-{
-    if (rect.isEmpty())
-        return std::nullopt;
-
-    auto info = ImageBuffer::compatibleBufferInfo(rect, context);
-
-    RefPtr<ImageBuffer> imageBuffer;
-
-    if (context.renderingMode() == RenderingMode::Accelerated)
-        imageBuffer = AcceleratedImageBuffer::create(info.physicalSizeInDeviceCoordinates, context);
-    
-    if (!imageBuffer)
-        imageBuffer = UnacceleratedImageBuffer::create(info.physicalSizeInDeviceCoordinates, context);
-
-    if (!imageBuffer)
-        return std::nullopt;
-
-    imageBuffer->context().scale(info.scale);
-    imageBuffer->context().translate(-info.inflatedRectInUserCoordinates.location());
-    return { { imageBuffer.releaseNonNull(), info.inflatedRectInUserCoordinates } };
-}
-
-RefPtr<ImageBuffer> ImageBuffer::createCompatibleBuffer(const FloatSize& size, const DestinationColorSpace& colorSpace, const GraphicsContext& context)
-{
-    if (size.isEmpty())
-        return nullptr;
-
-    IntSize scaledSize = ImageBuffer::compatibleBufferSize(size, context);
-
-    auto imageBuffer = ImageBuffer::createCompatibleBuffer(scaledSize, 1, colorSpace, context);
-    if (!imageBuffer)
-        return nullptr;
-
-    imageBuffer->context().scale(scaledSize / size);
-    return imageBuffer;
-}
-
-RefPtr<ImageBuffer> ImageBuffer::createCompatibleBuffer(const FloatSize& size, float resolutionScale, const DestinationColorSpace& colorSpace, const GraphicsContext& context)
-{
-    return ImageBuffer::create(size, context.renderingMode(), resolutionScale, colorSpace, PixelFormat::BGRA8);
-}
-
 bool ImageBuffer::sizeNeedsClamping(const FloatSize& size)
 {
     if (size.isEmpty())
@@ -185,58 +126,6 @@
     return FloatRect(rect.location(), clampedSize(rect.size()));
 }
 
-IntSize ImageBuffer::compatibleBufferSize(const FloatSize& size, const GraphicsContext& context)
-{
-    // Enlarge the buffer size if the context's transform is scaling it so we need a higher
-    // resolution than one pixel per unit.
-    return expandedIntSize(size * context.scaleFactor());
-}
-
-auto ImageBuffer::compatibleBufferInfo(const FloatRect& rect, const GraphicsContext& context) -> CompatibleBufferInfo
-{
-    auto scaleFactor = context.scaleFactor();
-    auto scaledRect = rect;
-    scaledRect.scale(scaleFactor);
-    auto inflatedScaledRect = enclosingIntRect(scaledRect);
-    auto inflatedRectInUserCoordinates = FloatRect(inflatedScaledRect);
-
-    // We don't want to allocate huge ImageBuffers because they can take a lot of memory,
-    // so if the size would have been too big, decrease resolution and scale the resulting context.
-    // This will mean that the ImageBuffer will lose quality, but will still generally look correct.
-    constexpr int maxDimension = 4096;
-    if (inflatedScaledRect.width() > maxDimension) {
-        // The pixel grids won't align any more, so there's no need to try to handle fractions of pixels.
-        inflatedScaledRect.setWidth(maxDimension);
-        inflatedRectInUserCoordinates.scale(maxDimension / inflatedRectInUserCoordinates.width(), 1);
-        scaleFactor.setWidth(maxDimension / rect.width());
-    }
-    if (inflatedScaledRect.height() > maxDimension) {
-        // The pixel grids won't align any more, so there's no need to try to handle fractions of pixels.
-        inflatedScaledRect.setHeight(maxDimension);
-        inflatedRectInUserCoordinates.scale(1, maxDimension / inflatedRectInUserCoordinates.height());
-        scaleFactor.setHeight(maxDimension / rect.height());
-    }
-
-    auto physicalSizeInDeviceCoordinates = inflatedScaledRect.size();
-    inflatedRectInUserCoordinates.scale(1.0f / scaleFactor);
-    return { WTFMove(physicalSizeInDeviceCoordinates), WTFMove(inflatedRectInUserCoordinates), scaleFactor };
-}
-
-RefPtr<ImageBuffer> ImageBuffer::copyRectToBuffer(const FloatRect& rect, const DestinationColorSpace& colorSpace, const GraphicsContext& context)
-{
-    if (rect.isEmpty())
-        return nullptr;
-
-    IntSize scaledSize = ImageBuffer::compatibleBufferSize(rect.size(), context);
-
-    auto buffer = ImageBuffer::createCompatibleBuffer(scaledSize, 1, colorSpace, context);
-    if (!buffer)
-        return nullptr;
-
-    buffer->context().drawImageBuffer(*this, -rect.location());
-    return buffer;
-}
-
 RefPtr<NativeImage> ImageBuffer::sinkIntoNativeImage(RefPtr<ImageBuffer> imageBuffer)
 {
     return imageBuffer->sinkIntoNativeImage();

Modified: trunk/Source/WebCore/platform/graphics/ImageBuffer.h (289517 => 289518)


--- trunk/Source/WebCore/platform/graphics/ImageBuffer.h	2022-02-10 04:11:48 UTC (rev 289517)
+++ trunk/Source/WebCore/platform/graphics/ImageBuffer.h	2022-02-10 05:18:02 UTC (rev 289518)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2006 Nikolas Zimmermann <zimmerm...@kde.org>
- * Copyright (C) 2007-2020 Apple Inc. All rights reserved.
+ * Copyright (C) 2007-2022 Apple Inc. All rights reserved.
  * Copyright (C) 2010 Torch Mobile (Beijing) Co. Ltd. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -44,15 +44,7 @@
     WEBCORE_EXPORT static RefPtr<ImageBuffer> create(const FloatSize&, RenderingMode, ShouldUseDisplayList, RenderingPurpose, float resolutionScale, const DestinationColorSpace&, PixelFormat, const HostWindow* = nullptr);
     WEBCORE_EXPORT static RefPtr<ImageBuffer> create(const FloatSize&, RenderingMode, float resolutionScale, const DestinationColorSpace&, PixelFormat, const HostWindow* = nullptr);
 
-    // Create an image buffer compatible with the context, with suitable resolution for drawing into the buffer and then into this context.
-    static RefPtr<ImageBuffer> createCompatibleBuffer(const FloatSize&, const GraphicsContext&);
-    struct CompatibleBufferDescription {
-        Ref<ImageBuffer> imageBuffer;
-        FloatRect inflatedRectInUserCoordinates;
-    };
-    static std::optional<CompatibleBufferDescription> createCompatibleBuffer(const FloatRect& rectInUserCoordinates, const GraphicsContext&);
-    WEBCORE_EXPORT static RefPtr<ImageBuffer> createCompatibleBuffer(const FloatSize&, const DestinationColorSpace&, const GraphicsContext&);
-    static RefPtr<ImageBuffer> createCompatibleBuffer(const FloatSize&, float resolutionScale, const DestinationColorSpace&, const GraphicsContext&);
+    RefPtr<ImageBuffer> clone() const;
 
     // These functions are used when clamping the ImageBuffer which is created for filter, masker or clipper.
     static bool sizeNeedsClamping(const FloatSize&);
@@ -61,15 +53,7 @@
     static FloatSize clampedSize(const FloatSize&, FloatSize& scale);
     static FloatRect clampedRect(const FloatRect&);
 
-    static IntSize compatibleBufferSize(const FloatSize&, const GraphicsContext&);
-    struct CompatibleBufferInfo {
-        IntSize physicalSizeInDeviceCoordinates;
-        FloatRect inflatedRectInUserCoordinates;
-        FloatSize scale;
-    };
-    static CompatibleBufferInfo compatibleBufferInfo(const FloatRect&, const GraphicsContext&);
-    
-    WEBCORE_EXPORT virtual ~ImageBuffer() = default;
+    virtual ~ImageBuffer() = default;
 
     virtual void setBackend(std::unique_ptr<ImageBufferBackend>&&) = 0;
     virtual void clearBackend() = 0;
@@ -113,9 +97,6 @@
     virtual RefPtr<Image> copyImage(BackingStoreCopy = CopyBackingStore, PreserveResolution = PreserveResolution::No) const = 0;
     virtual RefPtr<Image> filteredImage(Filter&) = 0;
 
-    // Create an image buffer compatible with the context and copy rect from this buffer into this new one.
-    RefPtr<ImageBuffer> copyRectToBuffer(const FloatRect&, const DestinationColorSpace&, const GraphicsContext&);
-
     virtual void draw(GraphicsContext&, const FloatRect& destRect, const FloatRect& srcRect = FloatRect(0, 0, -1, -1), const ImagePaintingOptions& = { }) = 0;
     virtual void drawPattern(GraphicsContext&, const FloatRect& destRect, const FloatRect& srcRect, const AffineTransform& patternTransform, const FloatPoint& phase, const FloatSize& spacing, const ImagePaintingOptions& = { }) = 0;
 

Modified: trunk/Source/WebCore/platform/graphics/NamedImageGeneratedImage.cpp (289517 => 289518)


--- trunk/Source/WebCore/platform/graphics/NamedImageGeneratedImage.cpp	2022-02-10 04:11:48 UTC (rev 289517)
+++ trunk/Source/WebCore/platform/graphics/NamedImageGeneratedImage.cpp	2022-02-10 05:18:02 UTC (rev 289518)
@@ -65,7 +65,7 @@
 void NamedImageGeneratedImage::drawPattern(GraphicsContext& context, const FloatRect& dstRect, const FloatRect& srcRect, const AffineTransform& patternTransform, const FloatPoint& phase, const FloatSize& spacing, const ImagePaintingOptions& options)
 {
 #if USE(NEW_THEME)
-    auto imageBuffer = ImageBuffer::createCompatibleBuffer(size(), context);
+    auto imageBuffer = context.createCompatibleImageBuffer(size());
     if (!imageBuffer)
         return;
 

Modified: trunk/Source/WebCore/platform/graphics/RenderingMode.h (289517 => 289518)


--- trunk/Source/WebCore/platform/graphics/RenderingMode.h	2022-02-10 04:11:48 UTC (rev 289517)
+++ trunk/Source/WebCore/platform/graphics/RenderingMode.h	2022-02-10 05:18:02 UTC (rev 289518)
@@ -37,4 +37,10 @@
 enum class ShouldUseDisplayList : bool { No, Yes };
 enum class RenderingMode : bool { Unaccelerated, Accelerated };
 
+enum class RenderingMethod : uint8_t {
+    Default,
+    Local,
+    DisplayList
+};
+
 } // namespace WebCore

Modified: trunk/Source/WebCore/platform/graphics/cg/PDFDocumentImage.cpp (289517 => 289518)


--- trunk/Source/WebCore/platform/graphics/cg/PDFDocumentImage.cpp	2022-02-10 04:11:48 UTC (rev 289517)
+++ trunk/Source/WebCore/platform/graphics/cg/PDFDocumentImage.cpp	2022-02-10 05:18:02 UTC (rev 289518)
@@ -232,7 +232,7 @@
 
     // Cache the PDF image only if the size of the new image won't exceed the cache threshold.
     if (m_pdfImageCachingPolicy == PDFImageCachingPolicy::BelowMemoryLimit) {
-        IntSize scaledSize = ImageBuffer::compatibleBufferSize(cachedImageSize, context);
+        auto scaledSize = context.compatibleImageBufferSize(cachedImageSize);
         if (s_allDecodedDataSize + scaledSize.unclampedArea() * 4 - m_cachedBytes > s_maxDecodedDataSize) {
             destroyDecodedData();
             return;
@@ -239,7 +239,8 @@
         }
     }
 
-    m_cachedImageBuffer = ImageBuffer::createCompatibleBuffer(cachedImageSize, context);
+    // Create a local ImageBuffer because decoding the PDF images has to happen in WebProcess.
+    m_cachedImageBuffer = context.createCompatibleImageBuffer(cachedImageSize, DestinationColorSpace::SRGB(), RenderingMethod::Local);
     if (!m_cachedImageBuffer) {
         destroyDecodedData();
         return;
@@ -292,7 +293,7 @@
             // scalar = sqrt(max number of pixels / (width * height))
             auto scalar = std::min(1.f, std::sqrt(static_cast<float>(s_maxCachedImageArea) / (dstRect.width() * dstRect.height())));
             FloatRect localDestinationRect(FloatPoint(), dstRect.size() * scalar);
-            if (auto imageBuffer = ImageBuffer::createCompatibleBuffer(localDestinationRect.size(), context)) {
+            if (auto imageBuffer = context.createCompatibleImageBuffer(localDestinationRect.size(), DestinationColorSpace::SRGB(), RenderingMethod::Local)) {
                 auto& bufferContext = imageBuffer->context();
                 transformContextForPainting(bufferContext, localDestinationRect, srcRect);
                 drawPDFPage(bufferContext);

Modified: trunk/Source/WebCore/platform/graphics/coretext/DrawGlyphsRecorderCoreText.cpp (289517 => 289518)


--- trunk/Source/WebCore/platform/graphics/coretext/DrawGlyphsRecorderCoreText.cpp	2022-02-10 04:11:48 UTC (rev 289517)
+++ trunk/Source/WebCore/platform/graphics/coretext/DrawGlyphsRecorderCoreText.cpp	2022-02-10 05:18:02 UTC (rev 289518)
@@ -374,14 +374,19 @@
 void DrawGlyphsRecorder::drawOTSVGRun(const Font& font, const GlyphBufferGlyph* glyphs, const GlyphBufferAdvance* advances, unsigned numGlyphs, const FloatPoint& startPoint, FontSmoothingMode smoothingMode)
 {
     FloatPoint penPosition = startPoint;
+
     for (unsigned i = 0; i < numGlyphs; ++i) {
         auto bounds = font.boundsForGlyph(glyphs[i]);
-        if (auto imageBufferDescription = ImageBuffer::createCompatibleBuffer(bounds, m_owner)) {
-            FontCascade::drawGlyphs(imageBufferDescription->imageBuffer->context(), font, glyphs + i, advances + i, 1, FloatPoint(), smoothingMode);
-            auto destinationRect = imageBufferDescription->inflatedRectInUserCoordinates;
+
+        // Create a local ImageBuffer because decoding the SVG fonts has to happen in WebProcess.
+        if (auto imageBuffer = m_owner.createCompatibleImageBuffer(bounds, DestinationColorSpace::SRGB(), RenderingMethod::Local)) {
+            FontCascade::drawGlyphs(imageBuffer->context(), font, glyphs + i, advances + i, 1, FloatPoint(), smoothingMode);
+
+            FloatRect destinationRect = enclosingIntRect(bounds);
             destinationRect.moveBy(penPosition);
-            m_owner.drawImageBuffer(imageBufferDescription->imageBuffer, destinationRect);
+            m_owner.drawImageBuffer(*imageBuffer, destinationRect);
         }
+
         penPosition.move(size(advances[i]));
     }
 }

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


--- trunk/Source/WebCore/platform/graphics/displaylists/DisplayListRecorder.cpp	2022-02-10 04:11:48 UTC (rev 289517)
+++ trunk/Source/WebCore/platform/graphics/displaylists/DisplayListRecorder.cpp	2022-02-10 05:18:02 UTC (rev 289518)
@@ -507,6 +507,14 @@
     return ClipToDrawingCommandsResult::Success;
 }
 
+RefPtr<ImageBuffer> Recorder::createImageBuffer(const FloatSize& size, const DestinationColorSpace& colorSpace, RenderingMode renderingMode, RenderingMethod renderingMethod) const
+{
+    if (renderingMethod == RenderingMethod::Default)
+        renderingMethod = RenderingMethod::DisplayList;
+
+    return GraphicsContext::createImageBuffer(size, colorSpace, renderingMode, renderingMethod);
+}
+
 #if ENABLE(VIDEO)
 void Recorder::paintFrameForMedia(MediaPlayer& player, const FloatRect& destination)
 {

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


--- trunk/Source/WebCore/platform/graphics/displaylists/DisplayListRecorder.h	2022-02-10 04:11:48 UTC (rev 289517)
+++ trunk/Source/WebCore/platform/graphics/displaylists/DisplayListRecorder.h	2022-02-10 05:18:02 UTC (rev 289518)
@@ -185,6 +185,8 @@
     const ContextState& currentState() const;
     ContextState& currentState();
 
+    WEBCORE_EXPORT RefPtr<ImageBuffer> createImageBuffer(const FloatSize&, const DestinationColorSpace&, RenderingMode, RenderingMethod) const override;
+
 private:
     bool hasPlatformContext() const final { return false; }
     PlatformGraphicsContext* platformContext() const final { return nullptr; }

Modified: trunk/Source/WebCore/platform/graphics/displaylists/DisplayListReplayer.cpp (289517 => 289518)


--- trunk/Source/WebCore/platform/graphics/displaylists/DisplayListReplayer.cpp	2022-02-10 04:11:48 UTC (rev 289517)
+++ trunk/Source/WebCore/platform/graphics/displaylists/DisplayListReplayer.cpp	2022-02-10 05:18:02 UTC (rev 289518)
@@ -154,7 +154,7 @@
         if (m_maskImageBuffer)
             return { StopReplayReason::InvalidItemOrExtent, std::nullopt };
         auto& clipItem = item.get<BeginClipToDrawingCommands>();
-        m_maskImageBuffer = ImageBuffer::createCompatibleBuffer(clipItem.destination().size(), clipItem.colorSpace(), m_context);
+        m_maskImageBuffer = m_context.createCompatibleImageBuffer(clipItem.destination().size(), clipItem.colorSpace());
         if (!m_maskImageBuffer)
             return { StopReplayReason::OutOfMemory, std::nullopt };
         return { std::nullopt, std::nullopt };

Modified: trunk/Source/WebCore/platform/mac/ThemeMac.mm (289517 => 289518)


--- trunk/Source/WebCore/platform/mac/ThemeMac.mm	2022-02-10 04:11:48 UTC (rev 289517)
+++ trunk/Source/WebCore/platform/mac/ThemeMac.mm	2022-02-10 05:18:02 UTC (rev 289518)
@@ -734,7 +734,7 @@
 
     if (useImageBuffer) {
         NSRect imageBufferDrawRect = NSRect(FloatRect(buttonFocusRectOutlineWidth, buttonFocusRectOutlineWidth, rect.width(), rect.height()));
-        auto imageBuffer = ImageBuffer::createCompatibleBuffer(rect.size() + 2 * FloatSize(buttonFocusRectOutlineWidth, buttonFocusRectOutlineWidth), deviceScaleFactor, DestinationColorSpace::SRGB(), context);
+        auto imageBuffer = context.createImageBuffer(rect.size() + 2 * FloatSize(buttonFocusRectOutlineWidth, buttonFocusRectOutlineWidth), { deviceScaleFactor, deviceScaleFactor });
         if (!imageBuffer)
             return needsRepaint;
         {

Modified: trunk/Source/WebCore/rendering/RenderBoxModelObject.cpp (289517 => 289518)


--- trunk/Source/WebCore/rendering/RenderBoxModelObject.cpp	2022-02-10 04:11:48 UTC (rev 289517)
+++ trunk/Source/WebCore/rendering/RenderBoxModelObject.cpp	2022-02-10 05:18:02 UTC (rev 289518)
@@ -894,7 +894,7 @@
         maskRect.intersect(snapRectToDevicePixels(paintInfo.rect, deviceScaleFactor));
 
         // Now create the mask.
-        maskImage = ImageBuffer::createCompatibleBuffer(maskRect.size(), DestinationColorSpace::SRGB(), context);
+        maskImage = context.createCompatibleImageBuffer(maskRect.size());
         if (!maskImage)
             return;
         paintMaskForTextFillBox(maskImage.get(), maskRect, box, scrolledPaintRect);

Modified: trunk/Source/WebCore/rendering/RenderLayer.cpp (289517 => 289518)


--- trunk/Source/WebCore/rendering/RenderLayer.cpp	2022-02-10 04:11:48 UTC (rev 289517)
+++ trunk/Source/WebCore/rendering/RenderLayer.cpp	2022-02-10 05:18:02 UTC (rev 289518)
@@ -3276,7 +3276,7 @@
 
     auto rootRelativeBounds = calculateLayerBounds(paintingInfo.rootLayer, offsetFromRoot, { });
 
-    GraphicsContext* filterContext = paintingFilters->beginFilterEffect(renderer(), enclosingIntRect(rootRelativeBounds), enclosingIntRect(paintingInfo.paintDirtyRect), enclosingIntRect(filterRepaintRect));
+    GraphicsContext* filterContext = paintingFilters->beginFilterEffect(renderer(), destinationContext, enclosingIntRect(rootRelativeBounds), enclosingIntRect(paintingInfo.paintDirtyRect), enclosingIntRect(filterRepaintRect));
     if (!filterContext)
         return nullptr;
 

Modified: trunk/Source/WebCore/rendering/RenderLayerBacking.cpp (289517 => 289518)


--- trunk/Source/WebCore/rendering/RenderLayerBacking.cpp	2022-02-10 04:11:48 UTC (rev 289517)
+++ trunk/Source/WebCore/rendering/RenderLayerBacking.cpp	2022-02-10 05:18:02 UTC (rev 289518)
@@ -3340,7 +3340,7 @@
 {
     const FloatSize tileSize { 32, 18 };
 
-    auto imageBuffer = ImageBuffer::createCompatibleBuffer(tileSize, DestinationColorSpace::SRGB(), destContext);
+    auto imageBuffer = destContext.createCompatibleImageBuffer(tileSize);
     if (!imageBuffer)
         return nullptr;
 

Modified: trunk/Source/WebCore/rendering/RenderLayerFilters.cpp (289517 => 289518)


--- trunk/Source/WebCore/rendering/RenderLayerFilters.cpp	2022-02-10 04:11:48 UTC (rev 289517)
+++ trunk/Source/WebCore/rendering/RenderLayerFilters.cpp	2022-02-10 05:18:02 UTC (rev 289518)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved.
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2022 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -129,19 +129,16 @@
     return m_sourceImage ? &m_sourceImage->context() : nullptr;
 }
 
-void RenderLayerFilters::allocateBackingStoreIfNeeded()
+void RenderLayerFilters::allocateBackingStoreIfNeeded(GraphicsContext& context)
 {
     auto& filter = *m_filter;
     auto logicalSize = filter.scaledByFilterScale(m_filterRegion.size());
 
-    if (!m_sourceImage || m_sourceImage->logicalSize() != logicalSize) {
-        m_sourceImage = ImageBuffer::create(logicalSize, filter.renderingMode(), ShouldUseDisplayList::No, RenderingPurpose::DOM, 1, DestinationColorSpace::SRGB(), PixelFormat::BGRA8, m_layer.renderer().hostWindow());
-        if (auto context = inputContext())
-            context->scale(filter.filterScale());
-    }
+    if (!m_sourceImage || m_sourceImage->logicalSize() != logicalSize)
+        m_sourceImage = context.createImageBuffer(m_filterRegion.size(), filter.filterScale(), DestinationColorSpace::SRGB(), filter.renderingMode());
 }
 
-GraphicsContext* RenderLayerFilters::beginFilterEffect(RenderElement& renderer, const LayoutRect& filterBoxRect, const LayoutRect& dirtyRect, const LayoutRect& layerRepaintRect)
+GraphicsContext* RenderLayerFilters::beginFilterEffect(RenderElement& renderer, GraphicsContext& context, const LayoutRect& filterBoxRect, const LayoutRect& dirtyRect, const LayoutRect& layerRepaintRect)
 {
     if (!m_filter)
         return nullptr;
@@ -193,7 +190,7 @@
     resetDirtySourceRect();
 
     filter.setFilterRegion(m_filterRegion);
-    allocateBackingStoreIfNeeded();
+    allocateBackingStoreIfNeeded(context);
 
     auto* sourceGraphicsContext = inputContext();
     if (!sourceGraphicsContext)

Modified: trunk/Source/WebCore/rendering/RenderLayerFilters.h (289517 => 289518)


--- trunk/Source/WebCore/rendering/RenderLayerFilters.h	2022-02-10 04:11:48 UTC (rev 289517)
+++ trunk/Source/WebCore/rendering/RenderLayerFilters.h	2022-02-10 05:18:02 UTC (rev 289518)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved.
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2022 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -63,7 +63,7 @@
     // Per render
     LayoutRect repaintRect() const { return m_repaintRect; }
 
-    GraphicsContext* beginFilterEffect(RenderElement&, const LayoutRect& filterBoxRect, const LayoutRect& dirtyRect, const LayoutRect& layerRepaintRect);
+    GraphicsContext* beginFilterEffect(RenderElement&, GraphicsContext&, const LayoutRect& filterBoxRect, const LayoutRect& dirtyRect, const LayoutRect& layerRepaintRect);
     void applyFilterEffect(GraphicsContext& destinationContext);
 
 private:
@@ -70,7 +70,7 @@
     void notifyFinished(CachedResource&, const NetworkLoadMetrics&) final;
     void resetDirtySourceRect() { m_dirtySourceRect = LayoutRect(); }
     GraphicsContext* inputContext();
-    void allocateBackingStoreIfNeeded();
+    void allocateBackingStoreIfNeeded(GraphicsContext&);
 
     RenderLayer& m_layer;
 

Modified: trunk/Source/WebCore/rendering/RenderThemeCocoa.mm (289517 => 289518)


--- trunk/Source/WebCore/rendering/RenderThemeCocoa.mm	2022-02-10 04:11:48 UTC (rev 289517)
+++ trunk/Source/WebCore/rendering/RenderThemeCocoa.mm	2022-02-10 05:18:02 UTC (rev 289518)
@@ -154,7 +154,7 @@
 {
     auto& destinationContext = paintInfo.context();
 
-    auto imageBuffer = ImageBuffer::createCompatibleBuffer(paintRect.size(), destinationContext);
+    auto imageBuffer = destinationContext.createCompatibleImageBuffer(paintRect.size());
     if (!imageBuffer)
         return false;
 

Modified: trunk/Source/WebCore/rendering/RenderThemeMac.mm (289517 => 289518)


--- trunk/Source/WebCore/rendering/RenderThemeMac.mm	2022-02-10 04:11:48 UTC (rev 289517)
+++ trunk/Source/WebCore/rendering/RenderThemeMac.mm	2022-02-10 05:18:02 UTC (rev 289518)
@@ -996,7 +996,7 @@
 
     float deviceScaleFactor = o.document().deviceScaleFactor();
 
-    auto comboBoxImageBuffer = ImageBuffer::createCompatibleBuffer(comboBoxSize, deviceScaleFactor, DestinationColorSpace::SRGB(), context);
+    auto comboBoxImageBuffer = context.createImageBuffer(comboBoxSize, { deviceScaleFactor, deviceScaleFactor });
     if (!comboBoxImageBuffer)
         return;
 
@@ -1020,7 +1020,7 @@
         (__bridge NSString *)kCUIUserInterfaceLayoutDirectionKey : (__bridge NSString *)kCUIUserInterfaceLayoutDirectionLeftToRight,
     }];
 
-    auto comboBoxButtonImageBuffer = ImageBuffer::createCompatibleBuffer(desiredComboBoxButtonSize, deviceScaleFactor, DestinationColorSpace::SRGB(), context);
+    auto comboBoxButtonImageBuffer = context.createImageBuffer(desiredComboBoxButtonSize, { deviceScaleFactor, deviceScaleFactor });
     if (!comboBoxButtonImageBuffer)
         return;
 
@@ -1379,7 +1379,7 @@
     const auto& renderProgress = downcast<RenderProgress>(renderObject);
     float deviceScaleFactor = renderObject.document().deviceScaleFactor();
     bool isIndeterminate = renderProgress.position() < 0;
-    auto imageBuffer = ImageBuffer::createCompatibleBuffer(inflatedRect.size(), deviceScaleFactor, DestinationColorSpace::SRGB(), paintInfo.context());
+    auto imageBuffer = paintInfo.context().createImageBuffer(inflatedRect.size(), { deviceScaleFactor, deviceScaleFactor });
     if (!imageBuffer)
         return true;
 

Modified: trunk/Source/WebCore/rendering/svg/RenderSVGResourceClipper.cpp (289517 => 289518)


--- trunk/Source/WebCore/rendering/svg/RenderSVGResourceClipper.cpp	2022-02-10 04:11:48 UTC (rev 289517)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGResourceClipper.cpp	2022-02-10 05:18:02 UTC (rev 289518)
@@ -3,6 +3,7 @@
  * Copyright (C) 2004, 2005, 2006, 2007, 2008 Rob Buis <b...@kde.org>
  * Copyright (C) Research In Motion Limited 2009-2010. All rights reserved.
  * Copyright (C) 2011 Dirk Schulze <k...@webkit.org>
+ * Copyright (C) 2022 Apple Inc. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -152,9 +153,16 @@
         return true;
 
     AffineTransform absoluteTransform = SVGRenderingContext::calculateTransformationToOutermostCoordinateSystem(renderer);
+
+    // Ignore 2D rotation, as it doesn't affect the size of the mask.
+    FloatSize scale(absoluteTransform.xScale(), absoluteTransform.yScale());
+
+    // Determine scale factor for the clipper. The size of intermediate ImageBuffers shouldn't be bigger than kMaxFilterSize.
+    ImageBuffer::sizeNeedsClamping(objectBoundingBox.size(), scale);
+
     if (!clipperData.isValidForGeometry(objectBoundingBox, clippedContentBounds, absoluteTransform)) {
         // FIXME (149469): This image buffer should not be unconditionally unaccelerated. Making it match the context breaks nested clipping, though.
-        auto maskImage = SVGRenderingContext::createImageBuffer(clippedContentBounds, absoluteTransform, DestinationColorSpace::SRGB(), RenderingMode::Unaccelerated, hostWindow());
+        auto maskImage = context.createImageBuffer(clippedContentBounds, scale, DestinationColorSpace::SRGB(), RenderingMode::Unaccelerated);
         if (!maskImage)
             return false;
 
@@ -185,7 +193,7 @@
     if (!clipperData.imageBuffer)
         return false;
 
-    SVGRenderingContext::clipToImageBuffer(context, absoluteTransform, clippedContentBounds, clipperData.imageBuffer, true);
+    SVGRenderingContext::clipToImageBuffer(context, clippedContentBounds, scale, clipperData.imageBuffer, true);
     return true;
 }
 

Modified: trunk/Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp (289517 => 289518)


--- trunk/Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp	2022-02-10 04:11:48 UTC (rev 289517)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp	2022-02-10 05:18:02 UTC (rev 289518)
@@ -4,6 +4,7 @@
  * Copyright (C) 2005 Eric Seidel <e...@webkit.org>
  * Copyright (C) 2009 Dirk Schulze <k...@webkit.org>
  * Copyright (C) Research In Motion Limited 2010. All rights reserved.
+ * Copyright (C) 2021-2022 Apple Inc. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -146,23 +147,21 @@
         return false;
     }
 
-    // Change the coordinate transformation applied to the filtered element to reflect the resolution of the filter.
-    auto effectiveTransform = AffineTransform(filterScale.width(), 0, 0, filterScale.height(), 0, 0);
-
 #if ENABLE(DESTINATION_COLOR_SPACE_LINEAR_SRGB)
     auto colorSpace = DestinationColorSpace::LinearSRGB();
 #else
     auto colorSpace = DestinationColorSpace::SRGB();
 #endif
-    auto sourceGraphic = SVGRenderingContext::createImageBuffer(filterData->drawingRegion, effectiveTransform, colorSpace, filterData->filter->renderingMode(), renderer.hostWindow());
+
+    auto sourceGraphic = context->createImageBuffer(filterData->drawingRegion, filterScale, colorSpace, filterData->filter->renderingMode());
     if (!sourceGraphic) {
         ASSERT(m_rendererFilterDataMap.contains(&renderer));
         filterData->savedContext = context;
         return false;
     }
-    
+
     auto& sourceGraphicContext = sourceGraphic->context();
-  
+
     filterData->sourceGraphicBuffer = WTFMove(sourceGraphic);
     filterData->savedContext = context;
 

Modified: trunk/Source/WebCore/rendering/svg/RenderSVGResourceGradient.cpp (289517 => 289518)


--- trunk/Source/WebCore/rendering/svg/RenderSVGResourceGradient.cpp	2022-02-10 04:11:48 UTC (rev 289517)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGResourceGradient.cpp	2022-02-10 05:18:02 UTC (rev 289518)
@@ -3,6 +3,7 @@
  * Copyright (C) 2008 Eric Seidel <e...@webkit.org>
  * Copyright (C) 2008 Dirk Schulze <k...@webkit.org>
  * Copyright (C) Research In Motion Limited 2010. All rights reserved.
+ * Copyright (C) 2022 Apple Inc. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -60,7 +61,13 @@
     AffineTransform absoluteTransform = SVGRenderingContext::calculateTransformationToOutermostCoordinateSystem(*textRootBlock);
     FloatRect repaintRect = textRootBlock->repaintRectInLocalCoordinates();
 
-    auto maskImage = SVGRenderingContext::createImageBuffer(repaintRect, absoluteTransform, DestinationColorSpace::SRGB(), context->renderingMode(), renderer.hostWindow());
+    // Ignore 2D rotation, as it doesn't affect the size of the mask.
+    FloatSize scale(absoluteTransform.xScale(), absoluteTransform.yScale());
+
+    // Determine scale factor for the clipper. The size of intermediate ImageBuffers shouldn't be bigger than kMaxFilterSize.
+    ImageBuffer::sizeNeedsClamping(repaintRect.size(), scale);
+
+    auto maskImage = context->createImageBuffer(repaintRect, scale);
     if (!maskImage)
         return false;
 
@@ -80,9 +87,15 @@
     AffineTransform absoluteTransform = SVGRenderingContext::calculateTransformationToOutermostCoordinateSystem(*textRootBlock);
 
     targetRect = textRootBlock->repaintRectInLocalCoordinates();
+    
+    // Ignore 2D rotation, as it doesn't affect the size of the mask.
+    FloatSize scale(absoluteTransform.xScale(), absoluteTransform.yScale());
 
-    SVGRenderingContext::clipToImageBuffer(context, absoluteTransform, targetRect, imageBuffer, false);
+    // Determine scale factor for the clipper. The size of intermediate ImageBuffers shouldn't be bigger than kMaxFilterSize.
+    ImageBuffer::sizeNeedsClamping(targetRect.size(), scale);
 
+    SVGRenderingContext::clipToImageBuffer(context, targetRect, scale, imageBuffer, false);
+
     AffineTransform matrix;
     if (boundingBoxMode) {
         FloatRect maskBoundingBox = textRootBlock->objectBoundingBox();

Modified: trunk/Source/WebCore/rendering/svg/RenderSVGResourceMasker.cpp (289517 => 289518)


--- trunk/Source/WebCore/rendering/svg/RenderSVGResourceMasker.cpp	2022-02-10 04:11:48 UTC (rev 289517)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGResourceMasker.cpp	2022-02-10 05:18:02 UTC (rev 289518)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) Research In Motion Limited 2009-2010. All rights reserved.
+ * Copyright (C) 2022 Apple Inc. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -68,6 +69,12 @@
     AffineTransform absoluteTransform = SVGRenderingContext::calculateTransformationToOutermostCoordinateSystem(renderer);
     FloatRect repaintRect = renderer.repaintRectInLocalCoordinates();
 
+    // Ignore 2D rotation, as it doesn't affect the size of the mask.
+    FloatSize scale(absoluteTransform.xScale(), absoluteTransform.yScale());
+
+    // Determine scale factor for the mask. The size of intermediate ImageBuffers shouldn't be bigger than kMaxFilterSize.
+    ImageBuffer::sizeNeedsClamping(repaintRect.size(), scale);
+
     if (!maskerData->maskImage && !repaintRect.isEmpty()) {
         const SVGRenderStyle& svgStyle = style().svgStyle();
 
@@ -82,9 +89,8 @@
             drawColorSpace = DestinationColorSpace::LinearSRGB();
         }
 #endif
-
         // FIXME (149470): This image buffer should not be unconditionally unaccelerated. Making it match the context breaks alpha masking, though.
-        maskerData->maskImage = SVGRenderingContext::createImageBuffer(repaintRect, absoluteTransform, maskColorSpace, RenderingMode::Unaccelerated, hostWindow());
+        maskerData->maskImage = context->createImageBuffer(repaintRect, scale, maskColorSpace, RenderingMode::Unaccelerated);
         if (!maskerData->maskImage)
             return false;
 
@@ -95,7 +101,7 @@
     if (!maskerData->maskImage)
         return false;
 
-    SVGRenderingContext::clipToImageBuffer(*context, absoluteTransform, repaintRect, maskerData->maskImage, missingMaskerData);
+    SVGRenderingContext::clipToImageBuffer(*context, repaintRect, scale, maskerData->maskImage, missingMaskerData);
     return true;
 }
 

Modified: trunk/Source/WebCore/rendering/svg/RenderSVGResourcePattern.cpp (289517 => 289518)


--- trunk/Source/WebCore/rendering/svg/RenderSVGResourcePattern.cpp	2022-02-10 04:11:48 UTC (rev 289517)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGResourcePattern.cpp	2022-02-10 05:18:02 UTC (rev 289518)
@@ -1,6 +1,7 @@
 /*
  * Copyright (C) 2006 Nikolas Zimmermann <zimmerm...@kde.org>
  * Copyright (C) Research In Motion Limited 2010. All rights reserved.
+ * Copyright (C) 2022 Apple Inc. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -95,19 +96,16 @@
     if (!buildTileImageTransform(renderer, m_attributes, patternElement(), tileBoundaries, tileImageTransform))
         return nullptr;
 
-    AffineTransform absoluteTransformIgnoringRotation = SVGRenderingContext::calculateTransformationToOutermostCoordinateSystem(renderer);
+    auto absoluteTransform = SVGRenderingContext::calculateTransformationToOutermostCoordinateSystem(renderer);
 
     // Ignore 2D rotation, as it doesn't affect the size of the tile.
-    SVGRenderingContext::clear2DRotation(absoluteTransformIgnoringRotation);
-    FloatRect absoluteTileBoundaries = absoluteTransformIgnoringRotation.mapRect(tileBoundaries);
-    FloatRect clampedAbsoluteTileBoundaries;
+    FloatSize tileScale(absoluteTransform.xScale(), absoluteTransform.yScale());
 
     // Scale the tile size to match the scale level of the patternTransform.
-    absoluteTileBoundaries.scale(static_cast<float>(m_attributes.patternTransform().xScale()),
-        static_cast<float>(m_attributes.patternTransform().yScale()));
+    tileScale.scale(static_cast<float>(m_attributes.patternTransform().xScale()), static_cast<float>(m_attributes.patternTransform().yScale()));
 
     // Build tile image.
-    auto tileImage = createTileImage(m_attributes, tileBoundaries, absoluteTileBoundaries, tileImageTransform, clampedAbsoluteTileBoundaries, context.renderingMode());
+    auto tileImage = createTileImage(context, tileBoundaries.size(), tileScale, tileImageTransform, m_attributes);
     if (!tileImage)
         return nullptr;
 
@@ -234,18 +232,23 @@
     return true;
 }
 
-RefPtr<ImageBuffer> RenderSVGResourcePattern::createTileImage(const PatternAttributes& attributes, const FloatRect& tileBoundaries, const FloatRect& absoluteTileBoundaries, const AffineTransform& tileImageTransform, FloatRect& clampedAbsoluteTileBoundaries, RenderingMode renderingMode) const
+RefPtr<ImageBuffer> RenderSVGResourcePattern::createTileImage(GraphicsContext& context, const FloatSize& size, const FloatSize& scale, const AffineTransform& tileImageTransform, const PatternAttributes& attributes) const
 {
-    clampedAbsoluteTileBoundaries = ImageBuffer::clampedRect(absoluteTileBoundaries);
-    auto tileImage = SVGRenderingContext::createImageBuffer(absoluteTileBoundaries, clampedAbsoluteTileBoundaries, DestinationColorSpace::SRGB(), renderingMode, hostWindow());
+    // This is equivalent to making createImageBuffer() use roundedIntSize().
+    auto roundedUnscaledImageBufferSize = [](const FloatSize& size, const FloatSize& scale) -> FloatSize {
+        auto scaledSize = size * scale;
+        return size - (expandedIntSize(scaledSize) - roundedIntSize(scaledSize)) * (scaledSize - flooredIntSize(scaledSize)) / scale;
+    };
+
+    auto tileSize = roundedUnscaledImageBufferSize(size, scale);
+
+    // FIXME: Use createImageBuffer(rect, scale), delete the above calculations and fix 'tileImageTransform'
+    auto tileImage = context.createImageBuffer(tileSize, scale);
     if (!tileImage)
         return nullptr;
 
     GraphicsContext& tileImageContext = tileImage->context();
 
-    // The image buffer represents the final rendered size, so the content has to be scaled (to avoid pixelation).
-    tileImageContext.scale(clampedAbsoluteTileBoundaries.size() / tileBoundaries.size());
-
     // Apply tile image transformations.
     if (!tileImageTransform.isIdentity())
         tileImageContext.concatCTM(tileImageTransform);

Modified: trunk/Source/WebCore/rendering/svg/RenderSVGResourcePattern.h (289517 => 289518)


--- trunk/Source/WebCore/rendering/svg/RenderSVGResourcePattern.h	2022-02-10 04:11:48 UTC (rev 289517)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGResourcePattern.h	2022-02-10 05:18:02 UTC (rev 289518)
@@ -1,6 +1,7 @@
 /*
  * Copyright (C) 2006 Nikolas Zimmermann <zimmerm...@kde.org>
  * Copyright (C) Research In Motion Limited 2010. All rights reserved.
+ * Copyright (C) 2022 Apple Inc. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -61,7 +62,7 @@
 
     bool buildTileImageTransform(RenderElement&, const PatternAttributes&, const SVGPatternElement&, FloatRect& patternBoundaries, AffineTransform& tileImageTransform) const;
 
-    RefPtr<ImageBuffer> createTileImage(const PatternAttributes&, const FloatRect& tileBoundaries, const FloatRect& absoluteTileBoundaries, const AffineTransform& tileImageTransform, FloatRect& clampedAbsoluteTileBoundaries, RenderingMode) const;
+    RefPtr<ImageBuffer> createTileImage(GraphicsContext&, const FloatSize&, const FloatSize& scale, const AffineTransform& tileImageTransform, const PatternAttributes&) const;
 
     PatternData* buildPattern(RenderElement&, OptionSet<RenderSVGResourceMode>, GraphicsContext&);
 

Modified: trunk/Source/WebCore/rendering/svg/SVGRenderingContext.cpp (289517 => 289518)


--- trunk/Source/WebCore/rendering/svg/SVGRenderingContext.cpp	2022-02-10 04:11:48 UTC (rev 289517)
+++ trunk/Source/WebCore/rendering/svg/SVGRenderingContext.cpp	2022-02-10 05:18:02 UTC (rev 289518)
@@ -227,52 +227,6 @@
     return absoluteTransform;
 }
 
-RefPtr<ImageBuffer> SVGRenderingContext::createImageBuffer(const FloatRect& targetRect, const AffineTransform& absoluteTransform, const DestinationColorSpace& colorSpace, RenderingMode renderingMode, const HostWindow* hostWindow)
-{
-    IntRect paintRect = calculateImageBufferRect(targetRect, absoluteTransform);
-    // Don't create empty ImageBuffers.
-    if (paintRect.isEmpty())
-        return nullptr;
-
-    FloatSize scale(1, 1);
-    FloatSize clampedSize = paintRect.size();
-    if (ImageBuffer::sizeNeedsClamping(clampedSize, scale))
-        clampedSize = clampedSize * scale;
-
-    auto imageBuffer = ImageBuffer::create(clampedSize, renderingMode, ShouldUseDisplayList::No, RenderingPurpose::DOM, 1, colorSpace, PixelFormat::BGRA8, hostWindow);
-    if (!imageBuffer)
-        return nullptr;
-
-    AffineTransform transform;
-    transform.scale(scale).translate(-paintRect.location()).multiply(absoluteTransform);
-
-    GraphicsContext& imageContext = imageBuffer->context();
-    imageContext.concatCTM(transform);
-
-    return imageBuffer;
-}
-
-RefPtr<ImageBuffer> SVGRenderingContext::createImageBuffer(const FloatRect& targetRect, const FloatRect& clampedRect, const DestinationColorSpace& colorSpace, RenderingMode renderingMode, const HostWindow* hostWindow)
-{
-    IntSize clampedSize = roundedIntSize(clampedRect.size());
-    FloatSize unclampedSize = roundedIntSize(targetRect.size());
-
-    // Don't create empty ImageBuffers.
-    if (clampedSize.isEmpty())
-        return nullptr;
-
-    auto imageBuffer = ImageBuffer::create(clampedSize, renderingMode, ShouldUseDisplayList::No, RenderingPurpose::DOM, 1, colorSpace, PixelFormat::BGRA8, hostWindow);
-    if (!imageBuffer)
-        return nullptr;
-
-    GraphicsContext& imageContext = imageBuffer->context();
-
-    // Compensate rounding effects, as the absolute target rect is using floating-point numbers and the image buffer size is integer.
-    imageContext.scale(unclampedSize / targetRect.size());
-
-    return imageBuffer;
-}
-
 void SVGRenderingContext::renderSubtreeToContext(GraphicsContext& context, RenderElement& item, const AffineTransform& subtreeContentTransformation)
 {
     // Rendering into a buffer implies we're being used for masking, clipping, patterns or filters. In each of these
@@ -289,13 +243,16 @@
     contentTransformation = savedContentTransformation;
 }
 
-void SVGRenderingContext::clipToImageBuffer(GraphicsContext& context, const AffineTransform& absoluteTransform, const FloatRect& targetRect, RefPtr<ImageBuffer>& imageBuffer, bool safeToClear)
+void SVGRenderingContext::clipToImageBuffer(GraphicsContext& context, const FloatRect& targetRect, const FloatSize& scale, RefPtr<ImageBuffer>& imageBuffer, bool safeToClear)
 {
     if (!imageBuffer)
         return;
 
-    FloatRect absoluteTargetRect = calculateImageBufferRect(targetRect, absoluteTransform);
+    AffineTransform absoluteTransform;
+    absoluteTransform.scale(scale.width(), scale.height());
 
+    auto absoluteTargetRect = calculateImageBufferRect(targetRect, absoluteTransform);
+
     // The mask image has been created in the absolute coordinate space, as the image should not be scaled.
     // So the actual masking process has to be done in the absolute coordinate space as well.
     context.concatCTM(valueOrDefault(absoluteTransform.inverse()));
@@ -308,14 +265,6 @@
         imageBuffer = nullptr;
 }
 
-void SVGRenderingContext::clear2DRotation(AffineTransform& transform)
-{
-    AffineTransform::DecomposedType decomposition;
-    transform.decompose(decomposition);
-    decomposition.angle = 0;
-    transform.recompose(decomposition);
-}
-
 bool SVGRenderingContext::bufferForeground(RefPtr<ImageBuffer>& imageBuffer)
 {
     ASSERT(m_paintInfo);
@@ -333,7 +282,7 @@
 
     // Create a new buffer and paint the foreground into it.
     if (!imageBuffer) {
-        imageBuffer = ImageBuffer::createCompatibleBuffer(expandedIntSize(boundingBox.size()), DestinationColorSpace::SRGB(), m_paintInfo->context());
+        imageBuffer = m_paintInfo->context().createCompatibleImageBuffer(expandedIntSize(boundingBox.size()));
         if (!imageBuffer)
             return false;
     }

Modified: trunk/Source/WebCore/rendering/svg/SVGRenderingContext.h (289517 => 289518)


--- trunk/Source/WebCore/rendering/svg/SVGRenderingContext.h	2022-02-10 04:11:48 UTC (rev 289517)
+++ trunk/Source/WebCore/rendering/svg/SVGRenderingContext.h	2022-02-10 05:18:02 UTC (rev 289518)
@@ -60,15 +60,11 @@
     void prepareToRenderSVGContent(RenderElement&, PaintInfo&, NeedsGraphicsContextSave = DontSaveGraphicsContext);
     bool isRenderingPrepared() const { return m_renderingFlags & RenderingPrepared; }
 
-    static RefPtr<ImageBuffer> createImageBuffer(const FloatRect& targetRect, const AffineTransform& absoluteTransform, const DestinationColorSpace&, RenderingMode, const HostWindow* = nullptr);
-    static RefPtr<ImageBuffer> createImageBuffer(const FloatRect& targetRect, const FloatRect& clampedRect, const DestinationColorSpace&, RenderingMode, const HostWindow* = nullptr);
-
     static void renderSubtreeToContext(GraphicsContext&, RenderElement&, const AffineTransform&);
-    static void clipToImageBuffer(GraphicsContext&, const AffineTransform& absoluteTransform, const FloatRect& targetRect, RefPtr<ImageBuffer>&, bool safeToClear);
+    static void clipToImageBuffer(GraphicsContext&, const FloatRect& targetRect, const FloatSize& scale, RefPtr<ImageBuffer>&, bool safeToClear);
 
     static float calculateScreenFontSizeScalingFactor(const RenderObject&);
     static AffineTransform calculateTransformationToOutermostCoordinateSystem(const RenderObject&);
-    static void clear2DRotation(AffineTransform&);
 
     static IntRect calculateImageBufferRect(const FloatRect& targetRect, const AffineTransform& absoluteTransform)
     {

Modified: trunk/Source/WebCore/svg/SVGFEImageElement.cpp (289517 => 289518)


--- trunk/Source/WebCore/svg/SVGFEImageElement.cpp	2022-02-10 04:11:48 UTC (rev 289517)
+++ trunk/Source/WebCore/svg/SVGFEImageElement.cpp	2022-02-10 05:18:02 UTC (rev 289518)
@@ -177,6 +177,38 @@
     RenderSVGResource::markForLayoutAndParentResourceInvalidation(*parentRenderer);
 }
 
+static inline IntRect scaledImageBufferRect(const FloatRect& rect, const FloatSize& scale)
+{
+    auto scaledRect = rect;
+    scaledRect.scale(scale);
+    return enclosingIntRect(scaledRect);
+}
+
+static inline FloatSize clampingScaleForImageBufferSize(const FloatSize& size)
+{
+    FloatSize clampingScale(1, 1);
+    ImageBuffer::sizeNeedsClamping(size, clampingScale);
+    return clampingScale;
+}
+
+static RefPtr<ImageBuffer> createImageBuffer(const FloatRect& rect, const FloatSize& scale, HostWindow* hostWindow)
+{
+    auto scaledRect = scaledImageBufferRect(rect, scale);
+    if (scaledRect.isEmpty())
+        return nullptr;
+
+    auto clampingScale = clampingScaleForImageBufferSize(scaledRect.size());
+
+    auto imageBuffer = ImageBuffer::create(scaledRect.size() * clampingScale, RenderingMode::Unaccelerated, ShouldUseDisplayList::No, RenderingPurpose::DOM, 1, DestinationColorSpace::SRGB(), PixelFormat::BGRA8, hostWindow);
+    if (!imageBuffer)
+        return nullptr;
+
+    imageBuffer->context().scale(clampingScale);
+    imageBuffer->context().translate(-scaledRect.location());
+    imageBuffer->context().scale(scale);
+    return imageBuffer;
+}
+
 std::tuple<RefPtr<ImageBuffer>, FloatRect> SVGFEImageElement::imageBufferForEffect() const
 {
     auto target = SVGURIReference::targetElementFromIRIString(href(), treeScope());
@@ -195,11 +227,12 @@
     if (!absoluteTransform.isInvertible())
         return { };
 
-    auto shearFreeAbsoluteTransform = AffineTransform(absoluteTransform.xScale(), 0, 0, absoluteTransform.yScale(), 0, 0);
-
+    // Ignore 2D rotation, as it doesn't affect the image size.
+    FloatSize scale(absoluteTransform.xScale(), absoluteTransform.yScale());
     auto imageRect = renderer->repaintRectInLocalCoordinates();
 
-    auto imageBuffer = SVGRenderingContext::createImageBuffer(imageRect, shearFreeAbsoluteTransform, DestinationColorSpace::SRGB(), RenderingMode::Unaccelerated, renderer->hostWindow());
+    // FIXME: Replace this call with GraphicsContext::createImageBuffer() once the destination GraphicsContext is passed to this function.
+    auto imageBuffer = createImageBuffer(imageRect, scale, renderer->hostWindow());
     if (!imageBuffer)
         return { };
 

Modified: trunk/Source/WebCore/svg/graphics/SVGImage.cpp (289517 => 289518)


--- trunk/Source/WebCore/svg/graphics/SVGImage.cpp	2022-02-10 04:11:48 UTC (rev 289517)
+++ trunk/Source/WebCore/svg/graphics/SVGImage.cpp	2022-02-10 05:18:02 UTC (rev 289518)
@@ -250,7 +250,7 @@
     FloatRect imageBufferSize = zoomedContainerRect;
     imageBufferSize.scale(imageBufferScale.width(), imageBufferScale.height());
 
-    auto buffer = ImageBuffer::createCompatibleBuffer(expandedIntSize(imageBufferSize.size()), 1, DestinationColorSpace::SRGB(), context);
+    auto buffer = context.createImageBuffer(expandedIntSize(imageBufferSize.size()));
     if (!buffer) // Failed to allocate buffer.
         return;
     drawForContainer(buffer->context(), containerSize, containerZoom, initialFragmentURL, imageBufferSize, zoomedContainerRect);

Modified: trunk/Source/WebKit/ChangeLog (289517 => 289518)


--- trunk/Source/WebKit/ChangeLog	2022-02-10 04:11:48 UTC (rev 289517)
+++ trunk/Source/WebKit/ChangeLog	2022-02-10 05:18:02 UTC (rev 289518)
@@ -1,3 +1,18 @@
+2022-02-09  Said Abou-Hallawa  <s...@apple.com>
+
+        [GPU Process] Move ImageBuffer::createCompatibleImageBuffer() and SVGRenderingContext::createImageBuffer to GraphicsContext
+        https://bugs.webkit.org/show_bug.cgi?id=235758
+        rdar://88478470
+
+        Reviewed by Simon Fraser.
+
+        * GPUProcess/graphics/RemoteDisplayListRecorder.cpp:
+        (WebKit::RemoteDisplayListRecorder::beginClipToDrawingCommands):
+        * WebProcess/GPU/graphics/RemoteDisplayListRecorderProxy.cpp:
+        (WebKit::RemoteDisplayListRecorderProxy::createImageBuffer const):
+        (WebKit::RemoteDisplayListRecorderProxy::createCompatibleImageBuffer const):
+        * WebProcess/GPU/graphics/RemoteDisplayListRecorderProxy.h:
+
 2022-02-09  Wenson Hsieh  <wenson_hs...@apple.com>
 
         Add some WebKitAdditions extension points in VisionKitCore SPI and softlinking headers

Modified: trunk/Source/WebKit/GPUProcess/graphics/RemoteDisplayListRecorder.cpp (289517 => 289518)


--- trunk/Source/WebKit/GPUProcess/graphics/RemoteDisplayListRecorder.cpp	2022-02-10 04:11:48 UTC (rev 289517)
+++ trunk/Source/WebKit/GPUProcess/graphics/RemoteDisplayListRecorder.cpp	2022-02-10 05:18:02 UTC (rev 289518)
@@ -202,7 +202,7 @@
 
 void RemoteDisplayListRecorder::beginClipToDrawingCommands(const FloatRect& destination, const DestinationColorSpace& colorSpace)
 {
-    m_maskImageBuffer = ImageBuffer::createCompatibleBuffer(destination.size(), colorSpace, drawingContext());
+    m_maskImageBuffer = drawingContext().createCompatibleImageBuffer(destination.size(), colorSpace);
 }
 
 void RemoteDisplayListRecorder::endClipToDrawingCommands(const FloatRect& destination)

Modified: trunk/Source/WebKit/WebProcess/GPU/graphics/RemoteDisplayListRecorderProxy.cpp (289517 => 289518)


--- trunk/Source/WebKit/WebProcess/GPU/graphics/RemoteDisplayListRecorderProxy.cpp	2022-02-10 04:11:48 UTC (rev 289517)
+++ trunk/Source/WebKit/WebProcess/GPU/graphics/RemoteDisplayListRecorderProxy.cpp	2022-02-10 05:18:02 UTC (rev 289518)
@@ -467,6 +467,31 @@
     return makeUnique<RemoteDisplayListRecorderProxy>(*this, initialClip, initialCTM);
 }
 
+RefPtr<ImageBuffer> RemoteDisplayListRecorderProxy::createImageBuffer(const FloatSize& size, const DestinationColorSpace& colorSpace, RenderingMode renderingMode, RenderingMethod renderingMethod) const
+{
+    if (UNLIKELY(!m_renderingBackend)) {
+        ASSERT_NOT_REACHED();
+        return nullptr;
+    }
+
+    if (renderingMethod != RenderingMethod::Default)
+        return Recorder::createImageBuffer(size, colorSpace, renderingMode, renderingMethod);
+
+    return m_renderingBackend->createImageBuffer(size, renderingMode, 1, colorSpace, PixelFormat::BGRA8);
+}
+
+RefPtr<ImageBuffer> RemoteDisplayListRecorderProxy::createCompatibleImageBuffer(const FloatSize& size, const DestinationColorSpace& colorSpace, RenderingMethod renderingMethod) const
+{
+    auto renderingMode = renderingMethod == RenderingMethod::Default ? this->renderingMode() : RenderingMode::Unaccelerated;
+    return GraphicsContext::createImageBuffer(size, scaleFactor(), colorSpace, renderingMode, renderingMethod);
+}
+
+RefPtr<ImageBuffer> RemoteDisplayListRecorderProxy::createCompatibleImageBuffer(const FloatRect& rect, const DestinationColorSpace& colorSpace, RenderingMethod renderingMethod) const
+{
+    auto renderingMode = renderingMethod == RenderingMethod::Default ? this->renderingMode() : RenderingMode::Unaccelerated;
+    return GraphicsContext::createImageBuffer(rect, scaleFactor(), colorSpace, renderingMode, renderingMethod);
+}
+
 } // namespace WebCore
 
 #endif // ENABLE(GPU_PROCESS)

Modified: trunk/Source/WebKit/WebProcess/GPU/graphics/RemoteDisplayListRecorderProxy.h (289517 => 289518)


--- trunk/Source/WebKit/WebProcess/GPU/graphics/RemoteDisplayListRecorderProxy.h	2022-02-10 04:11:48 UTC (rev 289517)
+++ trunk/Source/WebKit/WebProcess/GPU/graphics/RemoteDisplayListRecorderProxy.h	2022-02-10 05:18:02 UTC (rev 289518)
@@ -144,6 +144,10 @@
 
     std::unique_ptr<WebCore::GraphicsContext> createNestedContext(const WebCore::FloatRect& initialClip, const WebCore::AffineTransform& initialCTM) final;
 
+    RefPtr<WebCore::ImageBuffer> createImageBuffer(const WebCore::FloatSize&, const WebCore::DestinationColorSpace&, WebCore::RenderingMode, WebCore::RenderingMethod) const final;
+    RefPtr<WebCore::ImageBuffer> createCompatibleImageBuffer(const WebCore::FloatSize&, const WebCore::DestinationColorSpace& = WebCore::DestinationColorSpace::SRGB(), WebCore::RenderingMethod = WebCore::RenderingMethod::Default) const final;
+    RefPtr<WebCore::ImageBuffer> createCompatibleImageBuffer(const WebCore::FloatRect&, const WebCore::DestinationColorSpace& = WebCore::DestinationColorSpace::SRGB(), WebCore::RenderingMethod = WebCore::RenderingMethod::Default) const final;
+
     WebCore::RenderingResourceIdentifier m_destinationBufferIdentifier;
     WeakPtr<WebCore::ImageBuffer> m_imageBuffer;
     WeakPtr<RemoteRenderingBackendProxy> m_renderingBackend;
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to