⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 289518 in webkit


Ignore:
Timestamp:
Feb 9, 2022, 9:18:02 PM (5 years ago)
Author:
Said Abou-Hallawa
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.
  1. DisplayList: A DisplayList::ImageBuffer will be created whose GraphicsContext will be of type DisplayList::RecorderImpl.
  1. 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().
  1. 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'.
  1. 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:
Location:
trunk/Source
Files:
42 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r289517 r289518  
     12022-02-09  Said Abou-Hallawa  <said@apple.com>
     2
     3        [GPU Process] Move ImageBuffer::createCompatibleImageBuffer() and SVGRenderingContext::createImageBuffer to GraphicsContext
     4        https://bugs.webkit.org/show_bug.cgi?id=235758
     5        rdar://88478470
     6
     7        Reviewed by Simon Fraser.
     8
     9        The goal of this patch is to record the drawing if the concrete type of
     10        the GraphicsContext is RemoteDisplayListRecorderProxy. Currently all the
     11        intermediate compatible ImageBuffers are of type ConcreteImageBuffer.
     12        The drawing to these ImageBuffers still happens in the WebProcess. Moreover
     13        when we call drawImageBuffer() or clipToImageBuffer() for one of these
     14        intermediate ImageBuffers to a remote ImageBuffer, we have to sink the
     15        intermediate ImageBuffer to a NativeImage and send it to GPUProcess.
     16
     17        To fix this, the new enum 'RenderingMethod' will be used when creating
     18        the ImageBuffer methods. The value of RenderingMethod can be one of the
     19        following constants:
     20
     21        1. Default: The type of the created ImageBuffer will match the type of
     22           the underlying ImageBuffer of the GraphicsContext.
     23
     24        2. DisplayList: A DisplayList::ImageBuffer will be created whose
     25           GraphicsContext will be of type DisplayList::RecorderImpl.
     26
     27        3. Local: The ImageBuffer will be of type ConcreteImageBuffer and it will
     28           hold a platform GraphicsContext.
     29
     30        Also GraphicsContext will provide these functions for creating an
     31        ImageBuffer:
     32
     33        1. GraphicsContext::createImageBuffer() (virtual): Creates a
     34           ConcreteImageBuffer or a DisplayList::ImageBuffer. The type of the created
     35           ImageBuffer is controlled by the argument 'renderingMethod'. Because
     36           RemoteDisplayListRecorderProxy is a super class of GraphicsContext,
     37           it overrides this method and returns the desired RemoteImageBuffer.
     38           RemoteDisplayListRecorderProxy has access to RemotRenderingBackendProxy
     39           so it can call its createImageBuffer().
     40
     41        2. GraphicsContext::createImageBuffer() (non-virtual): Creates a scaled
     42           ImageBuffer and sets the context accordingly. The type of the created
     43           ImageBuffer is controlled by the argument 'renderingMethod'.
     44
     45        3. GraphicsContext::createCompatibleImageBuffer() (virtual): Takes the
     46           scaleFactor() into consideration when creating the ImageBuffer.
     47           RemoteDisplayListRecorderProxy will override this function to return
     48           an Unaccelerated ImageBuffer if 'renderingMethod != Default'. This is
     49           to ensure that for GPUProcess drawing, no intermediate local
     50           ImageBuffers will draw to an IOSurface in WebProcess.
     51
     52        Two versions of these functions are provided: one takes a FloatSize and
     53        the other takes a FloatRecct. The FloatRect version expands the four
     54        corners of the rectangle to full pixels.
     55
     56        * html/CustomPaintCanvas.cpp:
     57        (WebCore::CustomPaintCanvas::replayDisplayList const):
     58        * html/CustomPaintImage.cpp:
     59        (WebCore::CustomPaintImage::drawPattern):
     60        * html/OffscreenCanvas.cpp:
     61        (WebCore::OffscreenCanvas::transferToImageBitmap):
     62        (WebCore::OffscreenCanvas::commitToPlaceholderCanvas):
     63        * html/canvas/CanvasRenderingContext2DBase.cpp:
     64        (WebCore::CanvasRenderingContext2DBase::drawImage):
     65        * platform/cocoa/ThemeCocoa.mm:
     66        (WebCore::drawApplePayButton):
     67        * platform/graphics/BitmapImage.cpp:
     68        (WebCore::BitmapImage::drawPattern):
     69        * platform/graphics/CrossfadeGeneratedImage.cpp:
     70        (WebCore::CrossfadeGeneratedImage::drawPattern):
     71        * platform/graphics/GradientImage.cpp:
     72        (WebCore::GradientImage::drawPattern):
     73        * platform/graphics/GraphicsContext.cpp:
     74        (WebCore::scaledImageBufferSize):
     75        (WebCore::scaledImageBufferRect):
     76        (WebCore::clampingScaleForImageBufferSize):
     77        (WebCore::GraphicsContext::compatibleImageBufferSize const):
     78        (WebCore::GraphicsContext::createImageBuffer const):
     79        (WebCore::GraphicsContext::createCompatibleImageBuffer const):
     80        (WebCore::GraphicsContext::clipToDrawingCommands):
     81        * platform/graphics/GraphicsContext.h:
     82        (WebCore::GraphicsContext::createImageBuffer):
     83        * platform/graphics/ImageBuffer.cpp:
     84        (WebCore::ImageBuffer::clone const):
     85        (WebCore::ImageBuffer::createCompatibleBuffer): Deleted.
     86        (WebCore::ImageBuffer::compatibleBufferSize): Deleted.
     87        (WebCore::ImageBuffer::compatibleBufferInfo): Deleted.
     88        (WebCore::ImageBuffer::copyRectToBuffer): Deleted.
     89        * platform/graphics/ImageBuffer.h:
     90        * platform/graphics/NamedImageGeneratedImage.cpp:
     91        (WebCore::NamedImageGeneratedImage::drawPattern):
     92        * platform/graphics/RenderingMode.h:
     93        * platform/graphics/cg/PDFDocumentImage.cpp:
     94        (WebCore::PDFDocumentImage::updateCachedImageIfNeeded):
     95        (WebCore::PDFDocumentImage::draw):
     96        * platform/graphics/coretext/DrawGlyphsRecorderCoreText.cpp:
     97        (WebCore::DrawGlyphsRecorder::drawOTSVGRun):
     98        * platform/graphics/displaylists/DisplayListRecorder.cpp:
     99        (WebCore::DisplayList::Recorder::createImageBuffer const):
     100        * platform/graphics/displaylists/DisplayListRecorder.h:
     101        * platform/graphics/displaylists/DisplayListReplayer.cpp:
     102        (WebCore::DisplayList::Replayer::applyItem):
     103        * platform/mac/ThemeMac.mm:
     104        (WebCore::ThemeMac::drawCellOrFocusRingWithViewIntoContext):
     105        * rendering/RenderBoxModelObject.cpp:
     106        (WebCore::RenderBoxModelObject::paintFillLayerExtended):
     107        * rendering/RenderLayer.cpp:
     108        (WebCore::RenderLayer::setupFilters):
     109        * rendering/RenderLayerBacking.cpp:
     110        (WebCore::patternForDescription):
     111        * rendering/RenderLayerFilters.cpp:
     112        (WebCore::RenderLayerFilters::allocateBackingStoreIfNeeded):
     113        (WebCore::RenderLayerFilters::beginFilterEffect):
     114        * rendering/RenderLayerFilters.h:
     115        * rendering/RenderThemeCocoa.mm:
     116        (WebCore::RenderThemeCocoa::paintApplePayButton):
     117        * rendering/RenderThemeMac.mm:
     118        (WebCore::RenderThemeMac::paintListButtonForInput):
     119        (WebCore::RenderThemeMac::paintProgressBar):
     120        * rendering/svg/RenderSVGResourceClipper.cpp:
     121        (WebCore::RenderSVGResourceClipper::applyClippingToContext):
     122        * rendering/svg/RenderSVGResourceFilter.cpp:
     123        (WebCore::RenderSVGResourceFilter::applyResource):
     124        * rendering/svg/RenderSVGResourceGradient.cpp:
     125        (WebCore::createMaskAndSwapContextForTextGradient):
     126        (WebCore::clipToTextMask):
     127        * rendering/svg/RenderSVGResourceMasker.cpp:
     128        (WebCore::RenderSVGResourceMasker::applyResource):
     129        * rendering/svg/RenderSVGResourcePattern.cpp:
     130        (WebCore::RenderSVGResourcePattern::buildPattern):
     131        (WebCore::RenderSVGResourcePattern::createTileImage const):
     132        * rendering/svg/RenderSVGResourcePattern.h:
     133        * rendering/svg/SVGRenderingContext.cpp:
     134        (WebCore::SVGRenderingContext::clipToImageBuffer):
     135        (WebCore::SVGRenderingContext::bufferForeground):
     136        (WebCore::SVGRenderingContext::createImageBuffer): Deleted.
     137        (WebCore::SVGRenderingContext::clear2DRotation): Deleted.
     138        * rendering/svg/SVGRenderingContext.h:
     139        * svg/SVGFEImageElement.cpp:
     140        (WebCore::scaledImageBufferRect):
     141        (WebCore::clampingScaleForImageBufferSize):
     142        (WebCore::createImageBuffer):
     143        (WebCore::SVGFEImageElement::imageBufferForEffect const):
     144        * svg/graphics/SVGImage.cpp:
     145        (WebCore::SVGImage::drawPatternForContainer):
     146
    11472022-02-09  Lauro Moura  <lmoura@igalia.com>
    2148
  • trunk/Source/WebCore/html/CustomPaintCanvas.cpp

    r277986 r289518  
    7474    auto clipBounds = ctx->clipBounds();
    7575
    76     auto image = ImageBuffer::createCompatibleBuffer(clipBounds.size(), *ctx);
     76    auto image = ctx->createCompatibleImageBuffer(clipBounds.size());
    7777    if (!image)
    7878        return;
  • trunk/Source/WebCore/html/CustomPaintImage.cpp

    r284093 r289518  
    200200    adjustedSrcRect.scale(xScale, yScale);
    201201
    202     auto buffer = ImageBuffer::createCompatibleBuffer(adjustedSize, DestinationColorSpace::SRGB(), destContext);
     202    auto buffer = destContext.createCompatibleImageBuffer(adjustedSize);
    203203    if (!buffer)
    204204        return;
  • trunk/Source/WebCore/html/OffscreenCanvas.cpp

    r287294 r289518  
    284284        // by buffer(), to avoid resetting the context state, we have to make a copy and
    285285        // clear the original buffer rather than returning the original buffer.
    286         auto bufferCopy = buffer()->copyRectToBuffer(FloatRect(FloatPoint(), buffer()->logicalSize()), buffer()->colorSpace(), *drawingContext());
     286        auto bufferCopy = buffer()->clone();
    287287        downcast<OffscreenCanvasRenderingContext2D>(*m_context).clearCanvas();
    288288        clearCopiedImage();
    … …  
    452452
    453453    if (m_placeholderData->bufferPipeSource) {
    454         auto bufferCopy = imageBuffer->copyRectToBuffer(FloatRect(FloatPoint(), imageBuffer->logicalSize()), DestinationColorSpace::SRGB(), imageBuffer->context());
    455         if (bufferCopy)
     454        if (auto bufferCopy = imageBuffer->clone())
    456455            m_placeholderData->bufferPipeSource->handle(WTFMove(bufferCopy));
    457456    }
    … …  
    459458    Locker locker { m_placeholderData->bufferLock };
    460459    bool shouldPushBuffer = !m_placeholderData->pendingCommitBuffer;
    461     m_placeholderData->pendingCommitBuffer = imageBuffer->copyRectToBuffer(FloatRect(FloatPoint(), imageBuffer->logicalSize()), DestinationColorSpace::SRGB(), imageBuffer->context());
     460    m_placeholderData->pendingCommitBuffer = imageBuffer->clone();
    462461    if (m_placeholderData->pendingCommitBuffer && shouldPushBuffer)
    463462        pushBufferToPlaceholder();
  • trunk/Source/WebCore/html/canvas/CanvasRenderingContext2DBase.cpp

    r288942 r289518  
    16121612    } else if (state().globalComposite == CompositeOperator::Copy) {
    16131613        if (&sourceCanvas == &canvasBase()) {
    1614             if (auto copy = buffer->copyRectToBuffer(srcRect, colorSpace(), *c)) {
     1614            if (auto copy = c->createCompatibleImageBuffer(srcRect.size(), colorSpace())) {
     1615                copy->context().drawImageBuffer(*buffer, -srcRect.location());
    16151616                clearCanvas();
    16161617                c->drawImageBuffer(*copy, dstRect, { { }, srcRect.size() }, { state().globalComposite, state().globalBlend });
  • trunk/Source/WebCore/platform/cocoa/ThemeCocoa.mm

    r284624 r289518  
    111111static void drawApplePayButton(GraphicsContext& context, CGPDFPageRef page, const FloatSize& size)
    112112{
    113     auto imageBuffer = ImageBuffer::createCompatibleBuffer(size, context);
     113    // Create a local ImageBuffer because decoding the PDF images has to happen in WebProcess.
     114    auto imageBuffer = context.createCompatibleImageBuffer(size, DestinationColorSpace::SRGB(), RenderingMethod::Local);
    114115    if (!imageBuffer)
    115116        return;
  • trunk/Source/WebCore/platform/graphics/BitmapImage.cpp

    r287829 r289518  
    348348
    349349    if (!m_cachedImage) {
    350         auto buffer = ImageBuffer::createCompatibleBuffer(expandedIntSize(tileRect.size()), DestinationColorSpace::SRGB(), ctxt);
     350        auto buffer = ctxt.createCompatibleImageBuffer(expandedIntSize(tileRect.size()));
    351351        if (!buffer)
    352352            return;
  • trunk/Source/WebCore/platform/graphics/CrossfadeGeneratedImage.cpp

    r279793 r289518  
    104104void CrossfadeGeneratedImage::drawPattern(GraphicsContext& context, const FloatRect& dstRect, const FloatRect& srcRect, const AffineTransform& patternTransform, const FloatPoint& phase, const FloatSize& spacing, const ImagePaintingOptions& options)
    105105{
    106     auto imageBuffer = ImageBuffer::create(size(), context.renderingMode(), 1, DestinationColorSpace::SRGB(), PixelFormat::BGRA8);
     106    auto imageBuffer = context.createImageBuffer(size());
    107107    if (!imageBuffer)
    108108        return;
  • trunk/Source/WebCore/platform/graphics/GradientImage.cpp

    r277986 r289518  
    7373
    7474    if (!m_cachedImage || m_cachedGeneratorHash != generatorHash || m_cachedAdjustedSize != adjustedSize || !areEssentiallyEqual(destContext.scaleFactor(), m_cachedScaleFactor)) {
    75         auto imageBuffer = ImageBuffer::createCompatibleBuffer(adjustedSize, DestinationColorSpace::SRGB(), destContext);
     75        auto imageBuffer = destContext.createCompatibleImageBuffer(adjustedSize);
    7676        if (!imageBuffer)
    7777            return;
  • trunk/Source/WebCore/platform/graphics/GraphicsContext.cpp

    r288395 r289518  
    552552}
    553553
     554static IntSize scaledImageBufferSize(const FloatSize& size, const FloatSize& scale)
     555{
     556    // Enlarge the buffer size if the context's transform is scaling it so we need a higher
     557    // resolution than one pixel per unit.
     558    return expandedIntSize(size * scale);
     559}
     560
     561static IntRect scaledImageBufferRect(const FloatRect& rect, const FloatSize& scale)
     562{
     563    auto scaledRect = rect;
     564    scaledRect.scale(scale);
     565    return enclosingIntRect(scaledRect);
     566}
     567
     568static FloatSize clampingScaleForImageBufferSize(const FloatSize& size)
     569{
     570    FloatSize clampingScale(1, 1);
     571    ImageBuffer::sizeNeedsClamping(size, clampingScale);
     572    return clampingScale;
     573}
     574
     575IntSize GraphicsContext::compatibleImageBufferSize(const FloatSize& size) const
     576{
     577    return scaledImageBufferSize(size, scaleFactor());
     578}
     579
     580RefPtr<ImageBuffer> GraphicsContext::createImageBuffer(const FloatSize& size, const DestinationColorSpace& colorSpace, RenderingMode renderingMode, RenderingMethod renderingMethod) const
     581{
     582    if (renderingMethod == RenderingMethod::DisplayList)
     583        return ImageBuffer::create(size, renderingMode, ShouldUseDisplayList::Yes, RenderingPurpose::Unspecified, 1, colorSpace, PixelFormat::BGRA8);
     584
     585    return ImageBuffer::create(size, renderingMode, 1, colorSpace, PixelFormat::BGRA8);
     586}
     587
     588RefPtr<ImageBuffer> GraphicsContext::createImageBuffer(const FloatSize& size, const FloatSize& scale, const DestinationColorSpace& colorSpace, std::optional<RenderingMode> renderingMode, RenderingMethod renderingMethod) const
     589{
     590    auto expandedScaledSize = scaledImageBufferSize(size, scale);
     591    if (expandedScaledSize.isEmpty())
     592        return nullptr;
     593
     594    auto clampingScale = clampingScaleForImageBufferSize(expandedScaledSize);
     595
     596    auto imageBuffer = createImageBuffer(expandedScaledSize * clampingScale, colorSpace, renderingMode.value_or(this->renderingMode()), renderingMethod);
     597    if (!imageBuffer)
     598        return nullptr;
     599
     600    imageBuffer->context().scale(clampingScale);
     601
     602    // 'expandedScaledSize' is mapped to 'size'. So use 'expandedScaledSize / size'
     603    // not 'scale' because they are not necessarily equal.
     604    imageBuffer->context().scale(expandedScaledSize / size);
     605    return imageBuffer;
     606}
     607
     608RefPtr<ImageBuffer> GraphicsContext::createImageBuffer(const FloatRect& rect, const FloatSize& scale, const DestinationColorSpace& colorSpace, std::optional<RenderingMode> renderingMode, RenderingMethod renderingMethod) const
     609{
     610    auto expandedScaledRect = scaledImageBufferRect(rect, scale);
     611    if (expandedScaledRect.isEmpty())
     612        return nullptr;
     613
     614    auto clampingScale = clampingScaleForImageBufferSize(expandedScaledRect.size());
     615
     616    auto imageBuffer = createImageBuffer(expandedScaledRect.size() * clampingScale, colorSpace, renderingMode.value_or(this->renderingMode()), renderingMethod);
     617    if (!imageBuffer)
     618        return nullptr;
     619
     620    imageBuffer->context().scale(clampingScale);
     621   
     622    // 'rect' is mapped to a rectangle inside expandedScaledRect.
     623    imageBuffer->context().translate(-expandedScaledRect.location());
     624   
     625    // The size of this rectangle is not necessarily equal to expandedScaledRect.size().
     626    // So use 'scale' not 'expandedScaledRect.size() / rect.size()'.
     627    imageBuffer->context().scale(scale);
     628    return imageBuffer;
     629}
     630
     631RefPtr<ImageBuffer> GraphicsContext::createCompatibleImageBuffer(const FloatSize& size, const DestinationColorSpace& colorSpace, RenderingMethod renderingMethod) const
     632{
     633    return createImageBuffer(size, scaleFactor(), colorSpace, renderingMode(), renderingMethod);
     634}
     635
     636RefPtr<ImageBuffer> GraphicsContext::createCompatibleImageBuffer(const FloatRect& rect, const DestinationColorSpace& colorSpace, RenderingMethod renderingMethod) const
     637{
     638    return createImageBuffer(rect, scaleFactor(), colorSpace, renderingMode(), renderingMethod);
     639}
     640
    554641ImageDrawResult GraphicsContext::drawImage(Image& image, const FloatPoint& destination, const ImagePaintingOptions& imagePaintingOptions)
    555642{
    … …  
    669756GraphicsContext::ClipToDrawingCommandsResult GraphicsContext::clipToDrawingCommands(const FloatRect& destination, const DestinationColorSpace& colorSpace, Function<void(GraphicsContext&)>&& drawingFunction)
    670757{
    671     auto imageBuffer = ImageBuffer::createCompatibleBuffer(destination.size(), colorSpace, *this);
     758    auto imageBuffer = createCompatibleImageBuffer(destination.size(), colorSpace);
    672759    if (!imageBuffer)
    673760        return ClipToDrawingCommandsResult::FailedToCreateImageBuffer;
  • trunk/Source/WebCore/platform/graphics/GraphicsContext.h

    r287829 r289518  
    417417    // Images, Patterns, and Media
    418418
     419    IntSize compatibleImageBufferSize(const FloatSize&) const;
     420
     421    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;
     422    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;
     423
     424    virtual RefPtr<ImageBuffer> createCompatibleImageBuffer(const FloatSize&, const DestinationColorSpace& = DestinationColorSpace::SRGB(), RenderingMethod = RenderingMethod::Default) const;
     425    virtual RefPtr<ImageBuffer> createCompatibleImageBuffer(const FloatRect&, const DestinationColorSpace& = DestinationColorSpace::SRGB(), RenderingMethod = RenderingMethod::Default) const;
     426
    419427    virtual void drawNativeImage(NativeImage&, const FloatSize& selfSize, const FloatRect& destRect, const FloatRect& srcRect, const ImagePaintingOptions& = { }) = 0;
    420428
    … …  
    546554    void fillEllipseAsPath(const FloatRect&);
    547555    void strokeEllipseAsPath(const FloatRect&);
     556
     557    virtual RefPtr<ImageBuffer> createImageBuffer(const FloatSize&, const DestinationColorSpace&, RenderingMode, RenderingMethod) const;
    548558
    549559    FloatRect computeLineBoundsAndAntialiasingModeForText(const FloatRect&, bool printing, Color&);
  • trunk/Source/WebCore/platform/graphics/ImageBuffer.cpp

    r286889 r289518  
    22 * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
    33 * Copyright (C) Research In Motion Limited 2011. All rights reserved.
    4  * Copyright (C) 2016-2020 Apple Inc. All rights reserved.
     4 * Copyright (C) 2016-2022 Apple Inc. All rights reserved.
    55 *
    66 * Redistribution and use in source and binary forms, with or without
    … …  
    7373}
    7474
    75 RefPtr<ImageBuffer> ImageBuffer::createCompatibleBuffer(const FloatSize& size, const GraphicsContext& context)
     75RefPtr<ImageBuffer> ImageBuffer::clone() const
    7676{
    77     if (size.isEmpty())
     77    auto clone = context().createCompatibleImageBuffer(logicalSize(), colorSpace());
     78    if (!clone)
    7879        return nullptr;
    7980
    80     IntSize scaledSize = ImageBuffer::compatibleBufferSize(size, context);
    81 
    82     RefPtr<ImageBuffer> imageBuffer;
    83 
    84     if (context.renderingMode() == RenderingMode::Accelerated)
    85         imageBuffer = AcceleratedImageBuffer::create(scaledSize, context);
    86    
    87     if (!imageBuffer)
    88         imageBuffer = UnacceleratedImageBuffer::create(scaledSize, context);
    89 
    90     if (!imageBuffer)
    91         return nullptr;
    92 
    93     imageBuffer->context().scale(scaledSize / size);
    94     return imageBuffer;
    95 }
    96 
    97 // This is useful when you need to make sure the pixel grid of the ImageBuffer aligns with the pixel grid of the context.
    98 // Simply saying createCompatibleBuffer(rect.size(), context) isn't sufficient in this situation, because rect.location() may not lie on a pixel boundary.
    99 // In this situation, we have to inflate both the left side and the right side, which can lead to different results than
    100 // createCompatibleBuffer(rect.size(), context) would have produced.
    101 auto ImageBuffer::createCompatibleBuffer(const FloatRect& rect, const GraphicsContext& context) -> std::optional<CompatibleBufferDescription>
    102 {
    103     if (rect.isEmpty())
    104         return std::nullopt;
    105 
    106     auto info = ImageBuffer::compatibleBufferInfo(rect, context);
    107 
    108     RefPtr<ImageBuffer> imageBuffer;
    109 
    110     if (context.renderingMode() == RenderingMode::Accelerated)
    111         imageBuffer = AcceleratedImageBuffer::create(info.physicalSizeInDeviceCoordinates, context);
    112    
    113     if (!imageBuffer)
    114         imageBuffer = UnacceleratedImageBuffer::create(info.physicalSizeInDeviceCoordinates, context);
    115 
    116     if (!imageBuffer)
    117         return std::nullopt;
    118 
    119     imageBuffer->context().scale(info.scale);
    120     imageBuffer->context().translate(-info.inflatedRectInUserCoordinates.location());
    121     return { { imageBuffer.releaseNonNull(), info.inflatedRectInUserCoordinates } };
    122 }
    123 
    124 RefPtr<ImageBuffer> ImageBuffer::createCompatibleBuffer(const FloatSize& size, const DestinationColorSpace& colorSpace, const GraphicsContext& context)
    125 {
    126     if (size.isEmpty())
    127         return nullptr;
    128 
    129     IntSize scaledSize = ImageBuffer::compatibleBufferSize(size, context);
    130 
    131     auto imageBuffer = ImageBuffer::createCompatibleBuffer(scaledSize, 1, colorSpace, context);
    132     if (!imageBuffer)
    133         return nullptr;
    134 
    135     imageBuffer->context().scale(scaledSize / size);
    136     return imageBuffer;
    137 }
    138 
    139 RefPtr<ImageBuffer> ImageBuffer::createCompatibleBuffer(const FloatSize& size, float resolutionScale, const DestinationColorSpace& colorSpace, const GraphicsContext& context)
    140 {
    141     return ImageBuffer::create(size, context.renderingMode(), resolutionScale, colorSpace, PixelFormat::BGRA8);
     81    clone->context().drawImageBuffer(const_cast<ImageBuffer&>(*this), FloatPoint());
     82    return clone;
    14283}
    14384
    … …  
    186127}
    187128
    188 IntSize ImageBuffer::compatibleBufferSize(const FloatSize& size, const GraphicsContext& context)
    189 {
    190     // Enlarge the buffer size if the context's transform is scaling it so we need a higher
    191     // resolution than one pixel per unit.
    192     return expandedIntSize(size * context.scaleFactor());
    193 }
    194 
    195 auto ImageBuffer::compatibleBufferInfo(const FloatRect& rect, const GraphicsContext& context) -> CompatibleBufferInfo
    196 {
    197     auto scaleFactor = context.scaleFactor();
    198     auto scaledRect = rect;
    199     scaledRect.scale(scaleFactor);
    200     auto inflatedScaledRect = enclosingIntRect(scaledRect);
    201     auto inflatedRectInUserCoordinates = FloatRect(inflatedScaledRect);
    202 
    203     // We don't want to allocate huge ImageBuffers because they can take a lot of memory,
    204     // so if the size would have been too big, decrease resolution and scale the resulting context.
    205     // This will mean that the ImageBuffer will lose quality, but will still generally look correct.
    206     constexpr int maxDimension = 4096;
    207     if (inflatedScaledRect.width() > maxDimension) {
    208         // The pixel grids won't align any more, so there's no need to try to handle fractions of pixels.
    209         inflatedScaledRect.setWidth(maxDimension);
    210         inflatedRectInUserCoordinates.scale(maxDimension / inflatedRectInUserCoordinates.width(), 1);
    211         scaleFactor.setWidth(maxDimension / rect.width());
    212     }
    213     if (inflatedScaledRect.height() > maxDimension) {
    214         // The pixel grids won't align any more, so there's no need to try to handle fractions of pixels.
    215         inflatedScaledRect.setHeight(maxDimension);
    216         inflatedRectInUserCoordinates.scale(1, maxDimension / inflatedRectInUserCoordinates.height());
    217         scaleFactor.setHeight(maxDimension / rect.height());
    218     }
    219 
    220     auto physicalSizeInDeviceCoordinates = inflatedScaledRect.size();
    221     inflatedRectInUserCoordinates.scale(1.0f / scaleFactor);
    222     return { WTFMove(physicalSizeInDeviceCoordinates), WTFMove(inflatedRectInUserCoordinates), scaleFactor };
    223 }
    224 
    225 RefPtr<ImageBuffer> ImageBuffer::copyRectToBuffer(const FloatRect& rect, const DestinationColorSpace& colorSpace, const GraphicsContext& context)
    226 {
    227     if (rect.isEmpty())
    228         return nullptr;
    229 
    230     IntSize scaledSize = ImageBuffer::compatibleBufferSize(rect.size(), context);
    231 
    232     auto buffer = ImageBuffer::createCompatibleBuffer(scaledSize, 1, colorSpace, context);
    233     if (!buffer)
    234         return nullptr;
    235 
    236     buffer->context().drawImageBuffer(*this, -rect.location());
    237     return buffer;
    238 }
    239 
    240129RefPtr<NativeImage> ImageBuffer::sinkIntoNativeImage(RefPtr<ImageBuffer> imageBuffer)
    241130{
  • trunk/Source/WebCore/platform/graphics/ImageBuffer.h

    r289240 r289518  
    11/*
    22 * Copyright (C) 2006 Nikolas Zimmermann <zimmermann@kde.org>
    3  * Copyright (C) 2007-2020 Apple Inc. All rights reserved.
     3 * Copyright (C) 2007-2022 Apple Inc. All rights reserved.
    44 * Copyright (C) 2010 Torch Mobile (Beijing) Co. Ltd. All rights reserved.
    55 *
    … …  
    4545    WEBCORE_EXPORT static RefPtr<ImageBuffer> create(const FloatSize&, RenderingMode, float resolutionScale, const DestinationColorSpace&, PixelFormat, const HostWindow* = nullptr);
    4646
    47     // Create an image buffer compatible with the context, with suitable resolution for drawing into the buffer and then into this context.
    48     static RefPtr<ImageBuffer> createCompatibleBuffer(const FloatSize&, const GraphicsContext&);
    49     struct CompatibleBufferDescription {
    50         Ref<ImageBuffer> imageBuffer;
    51         FloatRect inflatedRectInUserCoordinates;
    52     };
    53     static std::optional<CompatibleBufferDescription> createCompatibleBuffer(const FloatRect& rectInUserCoordinates, const GraphicsContext&);
    54     WEBCORE_EXPORT static RefPtr<ImageBuffer> createCompatibleBuffer(const FloatSize&, const DestinationColorSpace&, const GraphicsContext&);
    55     static RefPtr<ImageBuffer> createCompatibleBuffer(const FloatSize&, float resolutionScale, const DestinationColorSpace&, const GraphicsContext&);
     47    RefPtr<ImageBuffer> clone() const;
    5648
    5749    // These functions are used when clamping the ImageBuffer which is created for filter, masker or clipper.
    … …  
    6254    static FloatRect clampedRect(const FloatRect&);
    6355
    64     static IntSize compatibleBufferSize(const FloatSize&, const GraphicsContext&);
    65     struct CompatibleBufferInfo {
    66         IntSize physicalSizeInDeviceCoordinates;
    67         FloatRect inflatedRectInUserCoordinates;
    68         FloatSize scale;
    69     };
    70     static CompatibleBufferInfo compatibleBufferInfo(const FloatRect&, const GraphicsContext&);
    71    
    72     WEBCORE_EXPORT virtual ~ImageBuffer() = default;
     56    virtual ~ImageBuffer() = default;
    7357
    7458    virtual void setBackend(std::unique_ptr<ImageBufferBackend>&&) = 0;
    … …  
    11498    virtual RefPtr<Image> filteredImage(Filter&) = 0;
    11599
    116     // Create an image buffer compatible with the context and copy rect from this buffer into this new one.
    117     RefPtr<ImageBuffer> copyRectToBuffer(const FloatRect&, const DestinationColorSpace&, const GraphicsContext&);
    118 
    119100    virtual void draw(GraphicsContext&, const FloatRect& destRect, const FloatRect& srcRect = FloatRect(0, 0, -1, -1), const ImagePaintingOptions& = { }) = 0;
    120101    virtual void drawPattern(GraphicsContext&, const FloatRect& destRect, const FloatRect& srcRect, const AffineTransform& patternTransform, const FloatPoint& phase, const FloatSize& spacing, const ImagePaintingOptions& = { }) = 0;
  • trunk/Source/WebCore/platform/graphics/NamedImageGeneratedImage.cpp

    r284624 r289518  
    6666{
    6767#if USE(NEW_THEME)
    68     auto imageBuffer = ImageBuffer::createCompatibleBuffer(size(), context);
     68    auto imageBuffer = context.createCompatibleImageBuffer(size());
    6969    if (!imageBuffer)
    7070        return;
  • trunk/Source/WebCore/platform/graphics/RenderingMode.h

    r269416 r289518  
    3838enum class RenderingMode : bool { Unaccelerated, Accelerated };
    3939
     40enum class RenderingMethod : uint8_t {
     41    Default,
     42    Local,
     43    DisplayList
     44};
     45
    4046} // namespace WebCore
  • trunk/Source/WebCore/platform/graphics/cg/PDFDocumentImage.cpp

    r288922 r289518  
    233233    // Cache the PDF image only if the size of the new image won't exceed the cache threshold.
    234234    if (m_pdfImageCachingPolicy == PDFImageCachingPolicy::BelowMemoryLimit) {
    235         IntSize scaledSize = ImageBuffer::compatibleBufferSize(cachedImageSize, context);
     235        auto scaledSize = context.compatibleImageBufferSize(cachedImageSize);
    236236        if (s_allDecodedDataSize + scaledSize.unclampedArea() * 4 - m_cachedBytes > s_maxDecodedDataSize) {
    237237            destroyDecodedData();
    … …  
    240240    }
    241241
    242     m_cachedImageBuffer = ImageBuffer::createCompatibleBuffer(cachedImageSize, context);
     242    // Create a local ImageBuffer because decoding the PDF images has to happen in WebProcess.
     243    m_cachedImageBuffer = context.createCompatibleImageBuffer(cachedImageSize, DestinationColorSpace::SRGB(), RenderingMethod::Local);
    243244    if (!m_cachedImageBuffer) {
    244245        destroyDecodedData();
    … …  
    293294            auto scalar = std::min(1.f, std::sqrt(static_cast<float>(s_maxCachedImageArea) / (dstRect.width() * dstRect.height())));
    294295            FloatRect localDestinationRect(FloatPoint(), dstRect.size() * scalar);
    295             if (auto imageBuffer = ImageBuffer::createCompatibleBuffer(localDestinationRect.size(), context)) {
     296            if (auto imageBuffer = context.createCompatibleImageBuffer(localDestinationRect.size(), DestinationColorSpace::SRGB(), RenderingMethod::Local)) {
    296297                auto& bufferContext = imageBuffer->context();
    297298                transformContextForPainting(bufferContext, localDestinationRect, srcRect);
  • trunk/Source/WebCore/platform/graphics/coretext/DrawGlyphsRecorderCoreText.cpp

    r286889 r289518  
    375375{
    376376    FloatPoint penPosition = startPoint;
     377
    377378    for (unsigned i = 0; i < numGlyphs; ++i) {
    378379        auto bounds = font.boundsForGlyph(glyphs[i]);
    379         if (auto imageBufferDescription = ImageBuffer::createCompatibleBuffer(bounds, m_owner)) {
    380             FontCascade::drawGlyphs(imageBufferDescription->imageBuffer->context(), font, glyphs + i, advances + i, 1, FloatPoint(), smoothingMode);
    381             auto destinationRect = imageBufferDescription->inflatedRectInUserCoordinates;
     380
     381        // Create a local ImageBuffer because decoding the SVG fonts has to happen in WebProcess.
     382        if (auto imageBuffer = m_owner.createCompatibleImageBuffer(bounds, DestinationColorSpace::SRGB(), RenderingMethod::Local)) {
     383            FontCascade::drawGlyphs(imageBuffer->context(), font, glyphs + i, advances + i, 1, FloatPoint(), smoothingMode);
     384
     385            FloatRect destinationRect = enclosingIntRect(bounds);
    382386            destinationRect.moveBy(penPosition);
    383             m_owner.drawImageBuffer(imageBufferDescription->imageBuffer, destinationRect);
     387            m_owner.drawImageBuffer(*imageBuffer, destinationRect);
    384388        }
     389
    385390        penPosition.move(size(advances[i]));
    386391    }
  • trunk/Source/WebCore/platform/graphics/displaylists/DisplayListRecorder.cpp

    r289492 r289518  
    508508}
    509509
     510RefPtr<ImageBuffer> Recorder::createImageBuffer(const FloatSize& size, const DestinationColorSpace& colorSpace, RenderingMode renderingMode, RenderingMethod renderingMethod) const
     511{
     512    if (renderingMethod == RenderingMethod::Default)
     513        renderingMethod = RenderingMethod::DisplayList;
     514
     515    return GraphicsContext::createImageBuffer(size, colorSpace, renderingMode, renderingMethod);
     516}
     517
    510518#if ENABLE(VIDEO)
    511519void Recorder::paintFrameForMedia(MediaPlayer& player, const FloatRect& destination)
  • trunk/Source/WebCore/platform/graphics/displaylists/DisplayListRecorder.h

    r289492 r289518  
    186186    ContextState& currentState();
    187187
     188    WEBCORE_EXPORT RefPtr<ImageBuffer> createImageBuffer(const FloatSize&, const DestinationColorSpace&, RenderingMode, RenderingMethod) const override;
     189
    188190private:
    189191    bool hasPlatformContext() const final { return false; }
  • trunk/Source/WebCore/platform/graphics/displaylists/DisplayListReplayer.cpp

    r288991 r289518  
    155155            return { StopReplayReason::InvalidItemOrExtent, std::nullopt };
    156156        auto& clipItem = item.get<BeginClipToDrawingCommands>();
    157         m_maskImageBuffer = ImageBuffer::createCompatibleBuffer(clipItem.destination().size(), clipItem.colorSpace(), m_context);
     157        m_maskImageBuffer = m_context.createCompatibleImageBuffer(clipItem.destination().size(), clipItem.colorSpace());
    158158        if (!m_maskImageBuffer)
    159159            return { StopReplayReason::OutOfMemory, std::nullopt };
  • trunk/Source/WebCore/platform/mac/ThemeMac.mm

    r287753 r289518  
    735735    if (useImageBuffer) {
    736736        NSRect imageBufferDrawRect = NSRect(FloatRect(buttonFocusRectOutlineWidth, buttonFocusRectOutlineWidth, rect.width(), rect.height()));
    737         auto imageBuffer = ImageBuffer::createCompatibleBuffer(rect.size() + 2 * FloatSize(buttonFocusRectOutlineWidth, buttonFocusRectOutlineWidth), deviceScaleFactor, DestinationColorSpace::SRGB(), context);
     737        auto imageBuffer = context.createImageBuffer(rect.size() + 2 * FloatSize(buttonFocusRectOutlineWidth, buttonFocusRectOutlineWidth), { deviceScaleFactor, deviceScaleFactor });
    738738        if (!imageBuffer)
    739739            return needsRepaint;
  • trunk/Source/WebCore/rendering/RenderBoxModelObject.cpp

    r289455 r289518  
    895895
    896896        // Now create the mask.
    897         maskImage = ImageBuffer::createCompatibleBuffer(maskRect.size(), DestinationColorSpace::SRGB(), context);
     897        maskImage = context.createCompatibleImageBuffer(maskRect.size());
    898898        if (!maskImage)
    899899            return;
  • trunk/Source/WebCore/rendering/RenderLayer.cpp

    r289360 r289518  
    32773277    auto rootRelativeBounds = calculateLayerBounds(paintingInfo.rootLayer, offsetFromRoot, { });
    32783278
    3279     GraphicsContext* filterContext = paintingFilters->beginFilterEffect(renderer(), enclosingIntRect(rootRelativeBounds), enclosingIntRect(paintingInfo.paintDirtyRect), enclosingIntRect(filterRepaintRect));
     3279    GraphicsContext* filterContext = paintingFilters->beginFilterEffect(renderer(), destinationContext, enclosingIntRect(rootRelativeBounds), enclosingIntRect(paintingInfo.paintDirtyRect), enclosingIntRect(filterRepaintRect));
    32803280    if (!filterContext)
    32813281        return nullptr;
  • trunk/Source/WebCore/rendering/RenderLayerBacking.cpp

    r289497 r289518  
    33413341    const FloatSize tileSize { 32, 18 };
    33423342
    3343     auto imageBuffer = ImageBuffer::createCompatibleBuffer(tileSize, DestinationColorSpace::SRGB(), destContext);
     3343    auto imageBuffer = destContext.createCompatibleImageBuffer(tileSize);
    33443344    if (!imageBuffer)
    33453345        return nullptr;
  • trunk/Source/WebCore/rendering/RenderLayerFilters.cpp

    r288183 r289518  
    11/*
    22 * Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved.
    3  * Copyright (C) 2013 Apple Inc. All rights reserved.
     3 * Copyright (C) 2013-2022 Apple Inc. All rights reserved.
    44 *
    55 * Redistribution and use in source and binary forms, with or without
    … …  
    130130}
    131131
    132 void RenderLayerFilters::allocateBackingStoreIfNeeded()
     132void RenderLayerFilters::allocateBackingStoreIfNeeded(GraphicsContext& context)
    133133{
    134134    auto& filter = *m_filter;
    135135    auto logicalSize = filter.scaledByFilterScale(m_filterRegion.size());
    136136
    137     if (!m_sourceImage || m_sourceImage->logicalSize() != logicalSize) {
    138         m_sourceImage = ImageBuffer::create(logicalSize, filter.renderingMode(), ShouldUseDisplayList::No, RenderingPurpose::DOM, 1, DestinationColorSpace::SRGB(), PixelFormat::BGRA8, m_layer.renderer().hostWindow());
    139         if (auto context = inputContext())
    140             context->scale(filter.filterScale());
    141     }
    142 }
    143 
    144 GraphicsContext* RenderLayerFilters::beginFilterEffect(RenderElement& renderer, const LayoutRect& filterBoxRect, const LayoutRect& dirtyRect, const LayoutRect& layerRepaintRect)
     137    if (!m_sourceImage || m_sourceImage->logicalSize() != logicalSize)
     138        m_sourceImage = context.createImageBuffer(m_filterRegion.size(), filter.filterScale(), DestinationColorSpace::SRGB(), filter.renderingMode());
     139}
     140
     141GraphicsContext* RenderLayerFilters::beginFilterEffect(RenderElement& renderer, GraphicsContext& context, const LayoutRect& filterBoxRect, const LayoutRect& dirtyRect, const LayoutRect& layerRepaintRect)
    145142{
    146143    if (!m_filter)
    … …  
    194191
    195192    filter.setFilterRegion(m_filterRegion);
    196     allocateBackingStoreIfNeeded();
     193    allocateBackingStoreIfNeeded(context);
    197194
    198195    auto* sourceGraphicsContext = inputContext();
  • trunk/Source/WebCore/rendering/RenderLayerFilters.h

    r287829 r289518  
    11/*
    22 * Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved.
    3  * Copyright (C) 2013 Apple Inc. All rights reserved.
     3 * Copyright (C) 2013-2022 Apple Inc. All rights reserved.
    44 *
    55 * Redistribution and use in source and binary forms, with or without
    … …  
    6464    LayoutRect repaintRect() const { return m_repaintRect; }
    6565
    66     GraphicsContext* beginFilterEffect(RenderElement&, const LayoutRect& filterBoxRect, const LayoutRect& dirtyRect, const LayoutRect& layerRepaintRect);
     66    GraphicsContext* beginFilterEffect(RenderElement&, GraphicsContext&, const LayoutRect& filterBoxRect, const LayoutRect& dirtyRect, const LayoutRect& layerRepaintRect);
    6767    void applyFilterEffect(GraphicsContext& destinationContext);
    6868
    … …  
    7171    void resetDirtySourceRect() { m_dirtySourceRect = LayoutRect(); }
    7272    GraphicsContext* inputContext();
    73     void allocateBackingStoreIfNeeded();
     73    void allocateBackingStoreIfNeeded(GraphicsContext&);
    7474
    7575    RenderLayer& m_layer;
  • trunk/Source/WebCore/rendering/RenderThemeCocoa.mm

    r287138 r289518  
    155155    auto& destinationContext = paintInfo.context();
    156156
    157     auto imageBuffer = ImageBuffer::createCompatibleBuffer(paintRect.size(), destinationContext);
     157    auto imageBuffer = destinationContext.createCompatibleImageBuffer(paintRect.size());
    158158    if (!imageBuffer)
    159159        return false;
  • trunk/Source/WebCore/rendering/RenderThemeMac.mm

    r287663 r289518  
    997997    float deviceScaleFactor = o.document().deviceScaleFactor();
    998998
    999     auto comboBoxImageBuffer = ImageBuffer::createCompatibleBuffer(comboBoxSize, deviceScaleFactor, DestinationColorSpace::SRGB(), context);
     999    auto comboBoxImageBuffer = context.createImageBuffer(comboBoxSize, { deviceScaleFactor, deviceScaleFactor });
    10001000    if (!comboBoxImageBuffer)
    10011001        return;
    … …  
    10211021    }];
    10221022
    1023     auto comboBoxButtonImageBuffer = ImageBuffer::createCompatibleBuffer(desiredComboBoxButtonSize, deviceScaleFactor, DestinationColorSpace::SRGB(), context);
     1023    auto comboBoxButtonImageBuffer = context.createImageBuffer(desiredComboBoxButtonSize, { deviceScaleFactor, deviceScaleFactor });
    10241024    if (!comboBoxButtonImageBuffer)
    10251025        return;
    … …  
    13801380    float deviceScaleFactor = renderObject.document().deviceScaleFactor();
    13811381    bool isIndeterminate = renderProgress.position() < 0;
    1382     auto imageBuffer = ImageBuffer::createCompatibleBuffer(inflatedRect.size(), deviceScaleFactor, DestinationColorSpace::SRGB(), paintInfo.context());
     1382    auto imageBuffer = paintInfo.context().createImageBuffer(inflatedRect.size(), { deviceScaleFactor, deviceScaleFactor });
    13831383    if (!imageBuffer)
    13841384        return true;
  • trunk/Source/WebCore/rendering/svg/RenderSVGResourceClipper.cpp

    r287911 r289518  
    44 * Copyright (C) Research In Motion Limited 2009-2010. All rights reserved.
    55 * Copyright (C) 2011 Dirk Schulze <krit@webkit.org>
     6 * Copyright (C) 2022 Apple Inc. All rights reserved.
    67 *
    78 * This library is free software; you can redistribute it and/or
    … …  
    153154
    154155    AffineTransform absoluteTransform = SVGRenderingContext::calculateTransformationToOutermostCoordinateSystem(renderer);
     156
     157    // Ignore 2D rotation, as it doesn't affect the size of the mask.
     158    FloatSize scale(absoluteTransform.xScale(), absoluteTransform.yScale());
     159
     160    // Determine scale factor for the clipper. The size of intermediate ImageBuffers shouldn't be bigger than kMaxFilterSize.
     161    ImageBuffer::sizeNeedsClamping(objectBoundingBox.size(), scale);
     162
    155163    if (!clipperData.isValidForGeometry(objectBoundingBox, clippedContentBounds, absoluteTransform)) {
    156164        // FIXME (149469): This image buffer should not be unconditionally unaccelerated. Making it match the context breaks nested clipping, though.
    157         auto maskImage = SVGRenderingContext::createImageBuffer(clippedContentBounds, absoluteTransform, DestinationColorSpace::SRGB(), RenderingMode::Unaccelerated, hostWindow());
     165        auto maskImage = context.createImageBuffer(clippedContentBounds, scale, DestinationColorSpace::SRGB(), RenderingMode::Unaccelerated);
    158166        if (!maskImage)
    159167            return false;
    … …  
    186194        return false;
    187195
    188     SVGRenderingContext::clipToImageBuffer(context, absoluteTransform, clippedContentBounds, clipperData.imageBuffer, true);
     196    SVGRenderingContext::clipToImageBuffer(context, clippedContentBounds, scale, clipperData.imageBuffer, true);
    189197    return true;
    190198}
  • trunk/Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp

    r288352 r289518  
    55 * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
    66 * Copyright (C) Research In Motion Limited 2010. All rights reserved.
     7 * Copyright (C) 2021-2022 Apple Inc. All rights reserved.
    78 *
    89 * This library is free software; you can redistribute it and/or
    … …  
    147148    }
    148149
    149     // Change the coordinate transformation applied to the filtered element to reflect the resolution of the filter.
    150     auto effectiveTransform = AffineTransform(filterScale.width(), 0, 0, filterScale.height(), 0, 0);
    151 
    152150#if ENABLE(DESTINATION_COLOR_SPACE_LINEAR_SRGB)
    153151    auto colorSpace = DestinationColorSpace::LinearSRGB();
    … …  
    155153    auto colorSpace = DestinationColorSpace::SRGB();
    156154#endif
    157     auto sourceGraphic = SVGRenderingContext::createImageBuffer(filterData->drawingRegion, effectiveTransform, colorSpace, filterData->filter->renderingMode(), renderer.hostWindow());
     155
     156    auto sourceGraphic = context->createImageBuffer(filterData->drawingRegion, filterScale, colorSpace, filterData->filter->renderingMode());
    158157    if (!sourceGraphic) {
    159158        ASSERT(m_rendererFilterDataMap.contains(&renderer));
    … …  
    161160        return false;
    162161    }
    163    
     162
    164163    auto& sourceGraphicContext = sourceGraphic->context();
    165  
     164
    166165    filterData->sourceGraphicBuffer = WTFMove(sourceGraphic);
    167166    filterData->savedContext = context;
  • trunk/Source/WebCore/rendering/svg/RenderSVGResourceGradient.cpp

    r287911 r289518  
    44 * Copyright (C) 2008 Dirk Schulze <krit@webkit.org>
    55 * Copyright (C) Research In Motion Limited 2010. All rights reserved.
     6 * Copyright (C) 2022 Apple Inc. All rights reserved.
    67 *
    78 * This library is free software; you can redistribute it and/or
    … …  
    6162    FloatRect repaintRect = textRootBlock->repaintRectInLocalCoordinates();
    6263
    63     auto maskImage = SVGRenderingContext::createImageBuffer(repaintRect, absoluteTransform, DestinationColorSpace::SRGB(), context->renderingMode(), renderer.hostWindow());
     64    // Ignore 2D rotation, as it doesn't affect the size of the mask.
     65    FloatSize scale(absoluteTransform.xScale(), absoluteTransform.yScale());
     66
     67    // Determine scale factor for the clipper. The size of intermediate ImageBuffers shouldn't be bigger than kMaxFilterSize.
     68    ImageBuffer::sizeNeedsClamping(repaintRect.size(), scale);
     69
     70    auto maskImage = context->createImageBuffer(repaintRect, scale);
    6471    if (!maskImage)
    6572        return false;
    … …  
    8188
    8289    targetRect = textRootBlock->repaintRectInLocalCoordinates();
    83 
    84     SVGRenderingContext::clipToImageBuffer(context, absoluteTransform, targetRect, imageBuffer, false);
     90   
     91    // Ignore 2D rotation, as it doesn't affect the size of the mask.
     92    FloatSize scale(absoluteTransform.xScale(), absoluteTransform.yScale());
     93
     94    // Determine scale factor for the clipper. The size of intermediate ImageBuffers shouldn't be bigger than kMaxFilterSize.
     95    ImageBuffer::sizeNeedsClamping(targetRect.size(), scale);
     96
     97    SVGRenderingContext::clipToImageBuffer(context, targetRect, scale, imageBuffer, false);
    8598
    8699    AffineTransform matrix;
  • trunk/Source/WebCore/rendering/svg/RenderSVGResourceMasker.cpp

    r287911 r289518  
    11/*
    22 * Copyright (C) Research In Motion Limited 2009-2010. All rights reserved.
     3 * Copyright (C) 2022 Apple Inc. All rights reserved.
    34 *
    45 * This library is free software; you can redistribute it and/or
    … …  
    6970    FloatRect repaintRect = renderer.repaintRectInLocalCoordinates();
    7071
     72    // Ignore 2D rotation, as it doesn't affect the size of the mask.
     73    FloatSize scale(absoluteTransform.xScale(), absoluteTransform.yScale());
     74
     75    // Determine scale factor for the mask. The size of intermediate ImageBuffers shouldn't be bigger than kMaxFilterSize.
     76    ImageBuffer::sizeNeedsClamping(repaintRect.size(), scale);
     77
    7178    if (!maskerData->maskImage && !repaintRect.isEmpty()) {
    7279        const SVGRenderStyle& svgStyle = style().svgStyle();
    … …  
    8390        }
    8491#endif
    85 
    8692        // FIXME (149470): This image buffer should not be unconditionally unaccelerated. Making it match the context breaks alpha masking, though.
    87         maskerData->maskImage = SVGRenderingContext::createImageBuffer(repaintRect, absoluteTransform, maskColorSpace, RenderingMode::Unaccelerated, hostWindow());
     93        maskerData->maskImage = context->createImageBuffer(repaintRect, scale, maskColorSpace, RenderingMode::Unaccelerated);
    8894        if (!maskerData->maskImage)
    8995            return false;
    … …  
    96102        return false;
    97103
    98     SVGRenderingContext::clipToImageBuffer(*context, absoluteTransform, repaintRect, maskerData->maskImage, missingMaskerData);
     104    SVGRenderingContext::clipToImageBuffer(*context, repaintRect, scale, maskerData->maskImage, missingMaskerData);
    99105    return true;
    100106}
  • trunk/Source/WebCore/rendering/svg/RenderSVGResourcePattern.cpp

    r288865 r289518  
    22 * Copyright (C) 2006 Nikolas Zimmermann <zimmermann@kde.org>
    33 * Copyright (C) Research In Motion Limited 2010. All rights reserved.
     4 * Copyright (C) 2022 Apple Inc. All rights reserved.
    45 *
    56 * This library is free software; you can redistribute it and/or
    … …  
    9697        return nullptr;
    9798
    98     AffineTransform absoluteTransformIgnoringRotation = SVGRenderingContext::calculateTransformationToOutermostCoordinateSystem(renderer);
     99    auto absoluteTransform = SVGRenderingContext::calculateTransformationToOutermostCoordinateSystem(renderer);
    99100
    100101    // Ignore 2D rotation, as it doesn't affect the size of the tile.
    101     SVGRenderingContext::clear2DRotation(absoluteTransformIgnoringRotation);
    102     FloatRect absoluteTileBoundaries = absoluteTransformIgnoringRotation.mapRect(tileBoundaries);
    103     FloatRect clampedAbsoluteTileBoundaries;
     102    FloatSize tileScale(absoluteTransform.xScale(), absoluteTransform.yScale());
    104103
    105104    // Scale the tile size to match the scale level of the patternTransform.
    106     absoluteTileBoundaries.scale(static_cast<float>(m_attributes.patternTransform().xScale()),
    107         static_cast<float>(m_attributes.patternTransform().yScale()));
     105    tileScale.scale(static_cast<float>(m_attributes.patternTransform().xScale()), static_cast<float>(m_attributes.patternTransform().yScale()));
    108106
    109107    // Build tile image.
    110     auto tileImage = createTileImage(m_attributes, tileBoundaries, absoluteTileBoundaries, tileImageTransform, clampedAbsoluteTileBoundaries, context.renderingMode());
     108    auto tileImage = createTileImage(context, tileBoundaries.size(), tileScale, tileImageTransform, m_attributes);
    111109    if (!tileImage)
    112110        return nullptr;
    … …  
    235233}
    236234
    237 RefPtr<ImageBuffer> RenderSVGResourcePattern::createTileImage(const PatternAttributes& attributes, const FloatRect& tileBoundaries, const FloatRect& absoluteTileBoundaries, const AffineTransform& tileImageTransform, FloatRect& clampedAbsoluteTileBoundaries, RenderingMode renderingMode) const
    238 {
    239     clampedAbsoluteTileBoundaries = ImageBuffer::clampedRect(absoluteTileBoundaries);
    240     auto tileImage = SVGRenderingContext::createImageBuffer(absoluteTileBoundaries, clampedAbsoluteTileBoundaries, DestinationColorSpace::SRGB(), renderingMode, hostWindow());
     235RefPtr<ImageBuffer> RenderSVGResourcePattern::createTileImage(GraphicsContext& context, const FloatSize& size, const FloatSize& scale, const AffineTransform& tileImageTransform, const PatternAttributes& attributes) const
     236{
     237    // This is equivalent to making createImageBuffer() use roundedIntSize().
     238    auto roundedUnscaledImageBufferSize = [](const FloatSize& size, const FloatSize& scale) -> FloatSize {
     239        auto scaledSize = size * scale;
     240        return size - (expandedIntSize(scaledSize) - roundedIntSize(scaledSize)) * (scaledSize - flooredIntSize(scaledSize)) / scale;
     241    };
     242
     243    auto tileSize = roundedUnscaledImageBufferSize(size, scale);
     244
     245    // FIXME: Use createImageBuffer(rect, scale), delete the above calculations and fix 'tileImageTransform'
     246    auto tileImage = context.createImageBuffer(tileSize, scale);
    241247    if (!tileImage)
    242248        return nullptr;
    243249
    244250    GraphicsContext& tileImageContext = tileImage->context();
    245 
    246     // The image buffer represents the final rendered size, so the content has to be scaled (to avoid pixelation).
    247     tileImageContext.scale(clampedAbsoluteTileBoundaries.size() / tileBoundaries.size());
    248251
    249252    // Apply tile image transformations.
  • trunk/Source/WebCore/rendering/svg/RenderSVGResourcePattern.h

    r287832 r289518  
    22 * Copyright (C) 2006 Nikolas Zimmermann <zimmermann@kde.org>
    33 * Copyright (C) Research In Motion Limited 2010. All rights reserved.
     4 * Copyright (C) 2022 Apple Inc. All rights reserved.
    45 *
    56 * This library is free software; you can redistribute it and/or
    … …  
    6263    bool buildTileImageTransform(RenderElement&, const PatternAttributes&, const SVGPatternElement&, FloatRect& patternBoundaries, AffineTransform& tileImageTransform) const;
    6364
    64     RefPtr<ImageBuffer> createTileImage(const PatternAttributes&, const FloatRect& tileBoundaries, const FloatRect& absoluteTileBoundaries, const AffineTransform& tileImageTransform, FloatRect& clampedAbsoluteTileBoundaries, RenderingMode) const;
     65    RefPtr<ImageBuffer> createTileImage(GraphicsContext&, const FloatSize&, const FloatSize& scale, const AffineTransform& tileImageTransform, const PatternAttributes&) const;
    6566
    6667    PatternData* buildPattern(RenderElement&, OptionSet<RenderSVGResourceMode>, GraphicsContext&);
  • trunk/Source/WebCore/rendering/svg/SVGRenderingContext.cpp

    r287911 r289518  
    228228}
    229229
    230 RefPtr<ImageBuffer> SVGRenderingContext::createImageBuffer(const FloatRect& targetRect, const AffineTransform& absoluteTransform, const DestinationColorSpace& colorSpace, RenderingMode renderingMode, const HostWindow* hostWindow)
    231 {
    232     IntRect paintRect = calculateImageBufferRect(targetRect, absoluteTransform);
    233     // Don't create empty ImageBuffers.
    234     if (paintRect.isEmpty())
    235         return nullptr;
    236 
    237     FloatSize scale(1, 1);
    238     FloatSize clampedSize = paintRect.size();
    239     if (ImageBuffer::sizeNeedsClamping(clampedSize, scale))
    240         clampedSize = clampedSize * scale;
    241 
    242     auto imageBuffer = ImageBuffer::create(clampedSize, renderingMode, ShouldUseDisplayList::No, RenderingPurpose::DOM, 1, colorSpace, PixelFormat::BGRA8, hostWindow);
    243     if (!imageBuffer)
    244         return nullptr;
    245 
    246     AffineTransform transform;
    247     transform.scale(scale).translate(-paintRect.location()).multiply(absoluteTransform);
    248 
    249     GraphicsContext& imageContext = imageBuffer->context();
    250     imageContext.concatCTM(transform);
    251 
    252     return imageBuffer;
    253 }
    254 
    255 RefPtr<ImageBuffer> SVGRenderingContext::createImageBuffer(const FloatRect& targetRect, const FloatRect& clampedRect, const DestinationColorSpace& colorSpace, RenderingMode renderingMode, const HostWindow* hostWindow)
    256 {
    257     IntSize clampedSize = roundedIntSize(clampedRect.size());
    258     FloatSize unclampedSize = roundedIntSize(targetRect.size());
    259 
    260     // Don't create empty ImageBuffers.
    261     if (clampedSize.isEmpty())
    262         return nullptr;
    263 
    264     auto imageBuffer = ImageBuffer::create(clampedSize, renderingMode, ShouldUseDisplayList::No, RenderingPurpose::DOM, 1, colorSpace, PixelFormat::BGRA8, hostWindow);
    265     if (!imageBuffer)
    266         return nullptr;
    267 
    268     GraphicsContext& imageContext = imageBuffer->context();
    269 
    270     // Compensate rounding effects, as the absolute target rect is using floating-point numbers and the image buffer size is integer.
    271     imageContext.scale(unclampedSize / targetRect.size());
    272 
    273     return imageBuffer;
    274 }
    275 
    276230void SVGRenderingContext::renderSubtreeToContext(GraphicsContext& context, RenderElement& item, const AffineTransform& subtreeContentTransformation)
    277231{
    … …  
    290244}
    291245
    292 void SVGRenderingContext::clipToImageBuffer(GraphicsContext& context, const AffineTransform& absoluteTransform, const FloatRect& targetRect, RefPtr<ImageBuffer>& imageBuffer, bool safeToClear)
     246void SVGRenderingContext::clipToImageBuffer(GraphicsContext& context, const FloatRect& targetRect, const FloatSize& scale, RefPtr<ImageBuffer>& imageBuffer, bool safeToClear)
    293247{
    294248    if (!imageBuffer)
    295249        return;
    296250
    297     FloatRect absoluteTargetRect = calculateImageBufferRect(targetRect, absoluteTransform);
     251    AffineTransform absoluteTransform;
     252    absoluteTransform.scale(scale.width(), scale.height());
     253
     254    auto absoluteTargetRect = calculateImageBufferRect(targetRect, absoluteTransform);
    298255
    299256    // The mask image has been created in the absolute coordinate space, as the image should not be scaled.
    … …  
    307264    if (safeToClear && !currentContentTransformation().isIdentity())
    308265        imageBuffer = nullptr;
    309 }
    310 
    311 void SVGRenderingContext::clear2DRotation(AffineTransform& transform)
    312 {
    313     AffineTransform::DecomposedType decomposition;
    314     transform.decompose(decomposition);
    315     decomposition.angle = 0;
    316     transform.recompose(decomposition);
    317266}
    318267
    … …  
    334283    // Create a new buffer and paint the foreground into it.
    335284    if (!imageBuffer) {
    336         imageBuffer = ImageBuffer::createCompatibleBuffer(expandedIntSize(boundingBox.size()), DestinationColorSpace::SRGB(), m_paintInfo->context());
     285        imageBuffer = m_paintInfo->context().createCompatibleImageBuffer(expandedIntSize(boundingBox.size()));
    337286        if (!imageBuffer)
    338287            return false;
  • trunk/Source/WebCore/rendering/svg/SVGRenderingContext.h

    r287911 r289518  
    6161    bool isRenderingPrepared() const { return m_renderingFlags & RenderingPrepared; }
    6262
    63     static RefPtr<ImageBuffer> createImageBuffer(const FloatRect& targetRect, const AffineTransform& absoluteTransform, const DestinationColorSpace&, RenderingMode, const HostWindow* = nullptr);
    64     static RefPtr<ImageBuffer> createImageBuffer(const FloatRect& targetRect, const FloatRect& clampedRect, const DestinationColorSpace&, RenderingMode, const HostWindow* = nullptr);
    65 
    6663    static void renderSubtreeToContext(GraphicsContext&, RenderElement&, const AffineTransform&);
    67     static void clipToImageBuffer(GraphicsContext&, const AffineTransform& absoluteTransform, const FloatRect& targetRect, RefPtr<ImageBuffer>&, bool safeToClear);
     64    static void clipToImageBuffer(GraphicsContext&, const FloatRect& targetRect, const FloatSize& scale, RefPtr<ImageBuffer>&, bool safeToClear);
    6865
    6966    static float calculateScreenFontSizeScalingFactor(const RenderObject&);
    7067    static AffineTransform calculateTransformationToOutermostCoordinateSystem(const RenderObject&);
    71     static void clear2DRotation(AffineTransform&);
    7268
    7369    static IntRect calculateImageBufferRect(const FloatRect& targetRect, const AffineTransform& absoluteTransform)
  • trunk/Source/WebCore/svg/SVGFEImageElement.cpp

    r288432 r289518  
    178178}
    179179
     180static inline IntRect scaledImageBufferRect(const FloatRect& rect, const FloatSize& scale)
     181{
     182    auto scaledRect = rect;
     183    scaledRect.scale(scale);
     184    return enclosingIntRect(scaledRect);
     185}
     186
     187static inline FloatSize clampingScaleForImageBufferSize(const FloatSize& size)
     188{
     189    FloatSize clampingScale(1, 1);
     190    ImageBuffer::sizeNeedsClamping(size, clampingScale);
     191    return clampingScale;
     192}
     193
     194static RefPtr<ImageBuffer> createImageBuffer(const FloatRect& rect, const FloatSize& scale, HostWindow* hostWindow)
     195{
     196    auto scaledRect = scaledImageBufferRect(rect, scale);
     197    if (scaledRect.isEmpty())
     198        return nullptr;
     199
     200    auto clampingScale = clampingScaleForImageBufferSize(scaledRect.size());
     201
     202    auto imageBuffer = ImageBuffer::create(scaledRect.size() * clampingScale, RenderingMode::Unaccelerated, ShouldUseDisplayList::No, RenderingPurpose::DOM, 1, DestinationColorSpace::SRGB(), PixelFormat::BGRA8, hostWindow);
     203    if (!imageBuffer)
     204        return nullptr;
     205
     206    imageBuffer->context().scale(clampingScale);
     207    imageBuffer->context().translate(-scaledRect.location());
     208    imageBuffer->context().scale(scale);
     209    return imageBuffer;
     210}
     211
    180212std::tuple<RefPtr<ImageBuffer>, FloatRect> SVGFEImageElement::imageBufferForEffect() const
    181213{
    … …  
    196228        return { };
    197229
    198     auto shearFreeAbsoluteTransform = AffineTransform(absoluteTransform.xScale(), 0, 0, absoluteTransform.yScale(), 0, 0);
    199 
     230    // Ignore 2D rotation, as it doesn't affect the image size.
     231    FloatSize scale(absoluteTransform.xScale(), absoluteTransform.yScale());
    200232    auto imageRect = renderer->repaintRectInLocalCoordinates();
    201233
    202     auto imageBuffer = SVGRenderingContext::createImageBuffer(imageRect, shearFreeAbsoluteTransform, DestinationColorSpace::SRGB(), RenderingMode::Unaccelerated, renderer->hostWindow());
     234    // FIXME: Replace this call with GraphicsContext::createImageBuffer() once the destination GraphicsContext is passed to this function.
     235    auto imageBuffer = createImageBuffer(imageRect, scale, renderer->hostWindow());
    203236    if (!imageBuffer)
    204237        return { };
  • trunk/Source/WebCore/svg/graphics/SVGImage.cpp

    r288412 r289518  
    251251    imageBufferSize.scale(imageBufferScale.width(), imageBufferScale.height());
    252252
    253     auto buffer = ImageBuffer::createCompatibleBuffer(expandedIntSize(imageBufferSize.size()), 1, DestinationColorSpace::SRGB(), context);
     253    auto buffer = context.createImageBuffer(expandedIntSize(imageBufferSize.size()));
    254254    if (!buffer) // Failed to allocate buffer.
    255255        return;
  • trunk/Source/WebKit/ChangeLog

    r289514 r289518  
     12022-02-09  Said Abou-Hallawa  <said@apple.com>
     2
     3        [GPU Process] Move ImageBuffer::createCompatibleImageBuffer() and SVGRenderingContext::createImageBuffer to GraphicsContext
     4        https://bugs.webkit.org/show_bug.cgi?id=235758
     5        rdar://88478470
     6
     7        Reviewed by Simon Fraser.
     8
     9        * GPUProcess/graphics/RemoteDisplayListRecorder.cpp:
     10        (WebKit::RemoteDisplayListRecorder::beginClipToDrawingCommands):
     11        * WebProcess/GPU/graphics/RemoteDisplayListRecorderProxy.cpp:
     12        (WebKit::RemoteDisplayListRecorderProxy::createImageBuffer const):
     13        (WebKit::RemoteDisplayListRecorderProxy::createCompatibleImageBuffer const):
     14        * WebProcess/GPU/graphics/RemoteDisplayListRecorderProxy.h:
     15
    1162022-02-09  Wenson Hsieh  <wenson_hsieh@apple.com>
    217
  • trunk/Source/WebKit/GPUProcess/graphics/RemoteDisplayListRecorder.cpp

    r288865 r289518  
    203203void RemoteDisplayListRecorder::beginClipToDrawingCommands(const FloatRect& destination, const DestinationColorSpace& colorSpace)
    204204{
    205     m_maskImageBuffer = ImageBuffer::createCompatibleBuffer(destination.size(), colorSpace, drawingContext());
     205    m_maskImageBuffer = drawingContext().createCompatibleImageBuffer(destination.size(), colorSpace);
    206206}
    207207
  • trunk/Source/WebKit/WebProcess/GPU/graphics/RemoteDisplayListRecorderProxy.cpp

    r289492 r289518  
    468468}
    469469
     470RefPtr<ImageBuffer> RemoteDisplayListRecorderProxy::createImageBuffer(const FloatSize& size, const DestinationColorSpace& colorSpace, RenderingMode renderingMode, RenderingMethod renderingMethod) const
     471{
     472    if (UNLIKELY(!m_renderingBackend)) {
     473        ASSERT_NOT_REACHED();
     474        return nullptr;
     475    }
     476
     477    if (renderingMethod != RenderingMethod::Default)
     478        return Recorder::createImageBuffer(size, colorSpace, renderingMode, renderingMethod);
     479
     480    return m_renderingBackend->createImageBuffer(size, renderingMode, 1, colorSpace, PixelFormat::BGRA8);
     481}
     482
     483RefPtr<ImageBuffer> RemoteDisplayListRecorderProxy::createCompatibleImageBuffer(const FloatSize& size, const DestinationColorSpace& colorSpace, RenderingMethod renderingMethod) const
     484{
     485    auto renderingMode = renderingMethod == RenderingMethod::Default ? this->renderingMode() : RenderingMode::Unaccelerated;
     486    return GraphicsContext::createImageBuffer(size, scaleFactor(), colorSpace, renderingMode, renderingMethod);
     487}
     488
     489RefPtr<ImageBuffer> RemoteDisplayListRecorderProxy::createCompatibleImageBuffer(const FloatRect& rect, const DestinationColorSpace& colorSpace, RenderingMethod renderingMethod) const
     490{
     491    auto renderingMode = renderingMethod == RenderingMethod::Default ? this->renderingMode() : RenderingMode::Unaccelerated;
     492    return GraphicsContext::createImageBuffer(rect, scaleFactor(), colorSpace, renderingMode, renderingMethod);
     493}
     494
    470495} // namespace WebCore
    471496
  • trunk/Source/WebKit/WebProcess/GPU/graphics/RemoteDisplayListRecorderProxy.h

    r289492 r289518  
    145145    std::unique_ptr<WebCore::GraphicsContext> createNestedContext(const WebCore::FloatRect& initialClip, const WebCore::AffineTransform& initialCTM) final;
    146146
     147    RefPtr<WebCore::ImageBuffer> createImageBuffer(const WebCore::FloatSize&, const WebCore::DestinationColorSpace&, WebCore::RenderingMode, WebCore::RenderingMethod) const final;
     148    RefPtr<WebCore::ImageBuffer> createCompatibleImageBuffer(const WebCore::FloatSize&, const WebCore::DestinationColorSpace& = WebCore::DestinationColorSpace::SRGB(), WebCore::RenderingMethod = WebCore::RenderingMethod::Default) const final;
     149    RefPtr<WebCore::ImageBuffer> createCompatibleImageBuffer(const WebCore::FloatRect&, const WebCore::DestinationColorSpace& = WebCore::DestinationColorSpace::SRGB(), WebCore::RenderingMethod = WebCore::RenderingMethod::Default) const final;
     150
    147151    WebCore::RenderingResourceIdentifier m_destinationBufferIdentifier;
    148152    WeakPtr<WebCore::ImageBuffer> m_imageBuffer;
Note: See TracChangeset for help on using the changeset viewer.