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;