Title: [288412] trunk/Source
Revision
288412
Author
s...@apple.com
Date
2022-01-22 17:03:39 -0800 (Sat, 22 Jan 2022)

Log Message

[GPU Process] Add the class 'SourceImage' to represent variants of image
https://bugs.webkit.org/show_bug.cgi?id=235467

Reviewed by Cameron McCormack.

Source/WebCore:

Before the existence of GPUProcess we used to do some drawing on an
ImageBuffer, get a NativeImage from the ImageBuffer and then use this
NativeImage. With GPUProces, this will require bouncing the NativeImage
between WebProcess and GPUProcess at least two times. To make this scenario
efficient, a new class called 'SourceImage' will be introduced. The purpose
of this class is to provide a new level of abstraction for the images
such that no conversion is needed before the actual use.

Replace FEImage::SourceImage with a new class named 'SourceImage'. Let
the new class handle the encoding and decoding and the conversion from
NativeImage to ImageBuffer and vice versa.

Make Recorder::recordResourceUse() returns a boolean which indicates
whether the resource can be cached for later replay or not.

* Headers.cmake:
* Sources.txt:
* WebCore.xcodeproj/project.pbxproj:
* platform/graphics/Image.h:
(WebCore::Image::nativeImageForCurrentFrame):
(WebCore::Image::preTransformedNativeImageForCurrentFrame):
* platform/graphics/SourceImage.cpp: Added.
(WebCore::SourceImage::SourceImage):
(WebCore::SourceImage::nativeImageIfExists const):
(WebCore::SourceImage::nativeImage):
(WebCore::SourceImage::imageBufferIfExists const):
(WebCore::SourceImage::imageBuffer):
(WebCore::SourceImage::imageIdentifier const):
* platform/graphics/SourceImage.h: Added.
(WebCore::SourceImage::encode const):
(WebCore::SourceImage::decode):
* platform/graphics/displaylists/DisplayListRecorder.cpp:
(WebCore::DisplayList::Recorder::drawFilteredImageBuffer):
(WebCore::DisplayList::Recorder::drawImageBuffer):
* platform/graphics/displaylists/DisplayListRecorder.h:
* platform/graphics/displaylists/DisplayListRecorderImpl.cpp:
(WebCore::DisplayList::RecorderImpl::recordResourceUse):
* platform/graphics/displaylists/DisplayListRecorderImpl.h:
* svg/SVGFEImageElement.cpp:
(WebCore::SVGFEImageElement::filterEffect const):
* svg/graphics/SVGImage.cpp:
(WebCore::SVGImage::nativeImageForCurrentFrame): Deleted.
* svg/graphics/SVGImage.h:
* svg/graphics/filters/SVGFEImage.cpp:
(WebCore::FEImage::calculateImageRect const):
(WebCore::FEImageSoftwareApplier::apply const):
* svg/graphics/filters/SVGFEImage.h:
(WebCore::FEImage::encode const):
(WebCore::FEImage::decode):

Source/WebKit:

Provide a new recordResourceUse() for the SourceImage.

* GPUProcess/graphics/RemoteDisplayListRecorder.cpp:
(WebKit::RemoteDisplayListRecorder::drawFilteredImageBuffer):
* WebProcess/GPU/graphics/RemoteDisplayListRecorderProxy.cpp:
(WebKit::RemoteDisplayListRecorderProxy::recordResourceUse):
* WebProcess/GPU/graphics/RemoteDisplayListRecorderProxy.h:

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (288411 => 288412)


--- trunk/Source/WebCore/ChangeLog	2022-01-23 00:00:38 UTC (rev 288411)
+++ trunk/Source/WebCore/ChangeLog	2022-01-23 01:03:39 UTC (rev 288412)
@@ -1,3 +1,60 @@
+2022-01-22  Said Abou-Hallawa  <s...@apple.com>
+
+        [GPU Process] Add the class 'SourceImage' to represent variants of image
+        https://bugs.webkit.org/show_bug.cgi?id=235467
+
+        Reviewed by Cameron McCormack.
+
+        Before the existence of GPUProcess we used to do some drawing on an 
+        ImageBuffer, get a NativeImage from the ImageBuffer and then use this
+        NativeImage. With GPUProces, this will require bouncing the NativeImage 
+        between WebProcess and GPUProcess at least two times. To make this scenario 
+        efficient, a new class called 'SourceImage' will be introduced. The purpose
+        of this class is to provide a new level of abstraction for the images
+        such that no conversion is needed before the actual use.
+
+        Replace FEImage::SourceImage with a new class named 'SourceImage'. Let 
+        the new class handle the encoding and decoding and the conversion from
+        NativeImage to ImageBuffer and vice versa.
+
+        Make Recorder::recordResourceUse() returns a boolean which indicates
+        whether the resource can be cached for later replay or not.
+
+        * Headers.cmake:
+        * Sources.txt:
+        * WebCore.xcodeproj/project.pbxproj:
+        * platform/graphics/Image.h:
+        (WebCore::Image::nativeImageForCurrentFrame):
+        (WebCore::Image::preTransformedNativeImageForCurrentFrame):
+        * platform/graphics/SourceImage.cpp: Added.
+        (WebCore::SourceImage::SourceImage):
+        (WebCore::SourceImage::nativeImageIfExists const):
+        (WebCore::SourceImage::nativeImage):
+        (WebCore::SourceImage::imageBufferIfExists const):
+        (WebCore::SourceImage::imageBuffer):
+        (WebCore::SourceImage::imageIdentifier const):
+        * platform/graphics/SourceImage.h: Added.
+        (WebCore::SourceImage::encode const):
+        (WebCore::SourceImage::decode):
+        * platform/graphics/displaylists/DisplayListRecorder.cpp:
+        (WebCore::DisplayList::Recorder::drawFilteredImageBuffer):
+        (WebCore::DisplayList::Recorder::drawImageBuffer):
+        * platform/graphics/displaylists/DisplayListRecorder.h:
+        * platform/graphics/displaylists/DisplayListRecorderImpl.cpp:
+        (WebCore::DisplayList::RecorderImpl::recordResourceUse):
+        * platform/graphics/displaylists/DisplayListRecorderImpl.h:
+        * svg/SVGFEImageElement.cpp:
+        (WebCore::SVGFEImageElement::filterEffect const):
+        * svg/graphics/SVGImage.cpp:
+        (WebCore::SVGImage::nativeImageForCurrentFrame): Deleted.
+        * svg/graphics/SVGImage.h:
+        * svg/graphics/filters/SVGFEImage.cpp:
+        (WebCore::FEImage::calculateImageRect const):
+        (WebCore::FEImageSoftwareApplier::apply const):
+        * svg/graphics/filters/SVGFEImage.h:
+        (WebCore::FEImage::encode const):
+        (WebCore::FEImage::decode):
+
 2022-01-22  Alan Bujtas  <za...@apple.com>
 
         [LFC][IFC] Add InlineDisplay::Box::isHorizontal

Modified: trunk/Source/WebCore/Headers.cmake (288411 => 288412)


--- trunk/Source/WebCore/Headers.cmake	2022-01-23 00:00:38 UTC (rev 288411)
+++ trunk/Source/WebCore/Headers.cmake	2022-01-23 01:03:39 UTC (rev 288412)
@@ -1550,6 +1550,7 @@
     platform/graphics/ShouldLocalizeAxisNames.h
     platform/graphics/SourceBufferPrivate.h
     platform/graphics/SourceBufferPrivateClient.h
+    platform/graphics/SourceImage.h
     platform/graphics/StringTruncator.h
     platform/graphics/TabSize.h
     platform/graphics/TextRun.h

Modified: trunk/Source/WebCore/Sources.txt (288411 => 288412)


--- trunk/Source/WebCore/Sources.txt	2022-01-23 00:00:38 UTC (rev 288411)
+++ trunk/Source/WebCore/Sources.txt	2022-01-23 01:03:39 UTC (rev 288412)
@@ -2076,6 +2076,7 @@
 platform/graphics/RoundedRect.cpp
 platform/graphics/ShadowBlur.cpp
 platform/graphics/SourceBufferPrivate.cpp
+platform/graphics/SourceImage.cpp
 platform/graphics/StringTruncator.cpp
 platform/graphics/TextRun.cpp
 platform/graphics/TextTrackRepresentation.cpp

Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (288411 => 288412)


--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2022-01-23 00:00:38 UTC (rev 288411)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2022-01-23 01:03:39 UTC (rev 288412)
@@ -2339,6 +2339,7 @@
 		72BAC3AE23E1F0B0008D741C /* ImageBufferBackend.h in Headers */ = {isa = PBXBuildFile; fileRef = 72BAC3A523E17328008D741C /* ImageBufferBackend.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		72D73644278461A000398663 /* FilterResults.h in Headers */ = {isa = PBXBuildFile; fileRef = 7211B5D6276536820076FEF8 /* FilterResults.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		72F667E1260C26AC00EE36AD /* DiagnosticLoggingDomain.h in Headers */ = {isa = PBXBuildFile; fileRef = 72F667DF260C264400EE36AD /* DiagnosticLoggingDomain.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		72F7E746279B8F7500D82D2D /* SourceImage.h in Headers */ = {isa = PBXBuildFile; fileRef = 72F7E744279B8F7400D82D2D /* SourceImage.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		7553CFE8108F473F00EA281E /* TimelineRecordFactory.h in Headers */ = {isa = PBXBuildFile; fileRef = 7553CFE6108F473F00EA281E /* TimelineRecordFactory.h */; };
 		75793E840D0CE0B3007FC0AC /* MessageEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 75793E810D0CE0B3007FC0AC /* MessageEvent.h */; };
 		75793EC90D0CE72D007FC0AC /* JSMessageEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 75793EC70D0CE72D007FC0AC /* JSMessageEvent.h */; };
@@ -11350,6 +11351,8 @@
 		72F1ADA31A390B9F00014E18 /* JSEXTFragDepth.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSEXTFragDepth.cpp; sourceTree = "<group>"; };
 		72F1ADA41A390B9F00014E18 /* JSEXTFragDepth.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSEXTFragDepth.h; sourceTree = "<group>"; };
 		72F667DF260C264400EE36AD /* DiagnosticLoggingDomain.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DiagnosticLoggingDomain.h; sourceTree = "<group>"; };
+		72F7E742279B8F7400D82D2D /* SourceImage.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SourceImage.cpp; sourceTree = "<group>"; };
+		72F7E744279B8F7400D82D2D /* SourceImage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SourceImage.h; sourceTree = "<group>"; };
 		72FB238422497AD4007E5AC7 /* SVGValuePropertyAnimatorImpl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGValuePropertyAnimatorImpl.h; sourceTree = "<group>"; };
 		72FB238622497AD5007E5AC7 /* SVGValuePropertyAnimator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGValuePropertyAnimator.h; sourceTree = "<group>"; };
 		72FB238722497B15007E5AC7 /* SVGValuePropertyListAnimatorImpl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGValuePropertyListAnimatorImpl.h; sourceTree = "<group>"; };
@@ -28994,6 +28997,8 @@
 				1DD127AC256E3A8700B227D7 /* SourceBufferPrivate.cpp */,
 				CD641EB21818F5ED00EE4C41 /* SourceBufferPrivate.h */,
 				CDC8B5AC1804AE5D0016E685 /* SourceBufferPrivateClient.h */,
+				72F7E742279B8F7400D82D2D /* SourceImage.cpp */,
+				72F7E744279B8F7400D82D2D /* SourceImage.h */,
 				7C83DE851D04CBD400FEBCF3 /* SpringSolver.h */,
 				B23540F00D00782E002382FA /* StringTruncator.cpp */,
 				B23540F10D00782E002382FA /* StringTruncator.h */,
@@ -37174,6 +37179,7 @@
 				CDC8B5AB18047FF10016E685 /* SourceBufferPrivateAVFObjC.h in Headers */,
 				CDC8B5AD1804AE5D0016E685 /* SourceBufferPrivateClient.h in Headers */,
 				84A81F420FC7E02700955300 /* SourceGraphic.h in Headers */,
+				72F7E746279B8F7500D82D2D /* SourceImage.h in Headers */,
 				D01A27AE10C9BFD800026A42 /* SpaceSplitString.h in Headers */,
 				626CDE0F1140424C001E5A68 /* SpatialNavigation.h in Headers */,
 				934950CD253943610099F171 /* SpeechRecognition.h in Headers */,

Modified: trunk/Source/WebCore/platform/graphics/Image.h (288411 => 288412)


--- trunk/Source/WebCore/platform/graphics/Image.h	2022-01-23 00:00:38 UTC (rev 288411)
+++ trunk/Source/WebCore/platform/graphics/Image.h	2022-01-23 01:03:39 UTC (rev 288412)
@@ -157,8 +157,8 @@
     enum TileRule { StretchTile, RoundTile, SpaceTile, RepeatTile };
 
     virtual RefPtr<NativeImage> nativeImage() { return nullptr; }
-    virtual RefPtr<NativeImage> nativeImageForCurrentFrame() { return nullptr; }
-    virtual RefPtr<NativeImage> preTransformedNativeImageForCurrentFrame(bool = true) { return nullptr; }
+    virtual RefPtr<NativeImage> nativeImageForCurrentFrame() { return nativeImage(); }
+    virtual RefPtr<NativeImage> preTransformedNativeImageForCurrentFrame(bool = true) { return nativeImageForCurrentFrame(); }
     virtual RefPtr<NativeImage> nativeImageOfSize(const IntSize&) { return nullptr; }
 
     // Accessors for native image formats.

Added: trunk/Source/WebCore/platform/graphics/SourceImage.cpp (0 => 288412)


--- trunk/Source/WebCore/platform/graphics/SourceImage.cpp	                        (rev 0)
+++ trunk/Source/WebCore/platform/graphics/SourceImage.cpp	2022-01-23 01:03:39 UTC (rev 288412)
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 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
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "SourceImage.h"
+
+#include "GraphicsContext.h"
+
+namespace WebCore {
+
+SourceImage::SourceImage(ImageVariant&& imageVariant)
+    : m_imageVariant(WTFMove(imageVariant))
+{
+}
+
+NativeImage* SourceImage::nativeImageIfExists() const
+{
+    if (auto* nativeImage = std::get_if<Ref<NativeImage>>(&m_imageVariant))
+        return nativeImage->ptr();
+    return nullptr;
+}
+
+NativeImage* SourceImage::nativeImage()
+{
+    if (!std::holds_alternative<Ref<ImageBuffer>>(m_imageVariant))
+        return nativeImageIfExists();
+
+    auto imageBuffer = std::get<Ref<ImageBuffer>>(m_imageVariant);
+    auto nativeImage = ImageBuffer::sinkIntoNativeImage(WTFMove(imageBuffer));
+    if (!nativeImage)
+        return nullptr;
+
+    m_imageVariant = nativeImage.releaseNonNull();
+    return nativeImageIfExists();
+}
+
+ImageBuffer* SourceImage::imageBufferIfExists() const
+{
+    if (auto* imageBuffer = std::get_if<Ref<ImageBuffer>>(&m_imageVariant))
+        return imageBuffer->ptr();
+    return nullptr;
+}
+
+ImageBuffer* SourceImage::imageBuffer()
+{
+    if (!std::holds_alternative<Ref<NativeImage>>(m_imageVariant))
+        return imageBufferIfExists();
+
+    auto nativeImage = std::get<Ref<NativeImage>>(m_imageVariant);
+    auto rect = FloatRect { { }, nativeImage->size() };
+
+    auto imageBuffer = ImageBuffer::create(nativeImage->size(), RenderingMode::Unaccelerated, 1, DestinationColorSpace::SRGB(), PixelFormat::BGRA8);
+    if (!imageBuffer)
+        return nullptr;
+
+    imageBuffer->context().drawNativeImage(nativeImage, rect.size(), rect, rect);
+
+    m_imageVariant = imageBuffer.releaseNonNull();
+    return imageBufferIfExists();
+}
+
+RenderingResourceIdentifier SourceImage::imageIdentifier() const
+{
+    return WTF::switchOn(m_imageVariant,
+        [&] (const Ref<NativeImage>& nativeImage) {
+            return nativeImage->renderingResourceIdentifier();
+        },
+        [&] (const Ref<ImageBuffer>& imageBuffer) {
+            return imageBuffer->renderingResourceIdentifier();
+        },
+        [&] (RenderingResourceIdentifier renderingResourceIdentifier) {
+            return renderingResourceIdentifier;
+        }
+    );
+}
+
+} // namespace WebCore

Added: trunk/Source/WebCore/platform/graphics/SourceImage.h (0 => 288412)


--- trunk/Source/WebCore/platform/graphics/SourceImage.h	                        (rev 0)
+++ trunk/Source/WebCore/platform/graphics/SourceImage.h	2022-01-23 01:03:39 UTC (rev 288412)
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 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
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "ImageBuffer.h"
+#include "NativeImage.h"
+#include "RenderingResourceIdentifier.h"
+
+namespace WebCore {
+
+class WEBCORE_EXPORT SourceImage {
+public:
+    using ImageVariant = std::variant<
+        Ref<NativeImage>,
+        Ref<ImageBuffer>,
+        RenderingResourceIdentifier
+    >;
+
+    SourceImage(ImageVariant&&);
+
+    NativeImage* nativeImageIfExists() const;
+    NativeImage* nativeImage();
+
+    ImageBuffer* imageBufferIfExists() const;
+    ImageBuffer* imageBuffer();
+
+    RenderingResourceIdentifier imageIdentifier() const;
+
+    template<class Encoder> void encode(Encoder&) const;
+    template<class Decoder> static std::optional<SourceImage> decode(Decoder&);
+
+private:
+    ImageVariant m_imageVariant;
+};
+
+template<class Encoder>
+void SourceImage::encode(Encoder& encoder) const
+{
+    encoder << imageIdentifier();
+}
+
+template<class Decoder>
+std::optional<SourceImage> SourceImage::decode(Decoder& decoder)
+{
+    std::optional<RenderingResourceIdentifier> imageIdentifier;
+    decoder >> imageIdentifier;
+    if (!imageIdentifier)
+        return std::nullopt;
+
+    return SourceImage(*imageIdentifier);
+}
+
+} // namespace WebCore

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


--- trunk/Source/WebCore/platform/graphics/displaylists/DisplayListRecorder.cpp	2022-01-23 00:00:38 UTC (rev 288411)
+++ trunk/Source/WebCore/platform/graphics/displaylists/DisplayListRecorder.cpp	2022-01-23 01:03:39 UTC (rev 288412)
@@ -150,33 +150,9 @@
 {
     appendStateChangeItemIfNecessary();
 
-    if (sourceImage && !canDrawImageBuffer(*sourceImage)) {
-        GraphicsContext::drawFilteredImageBuffer(sourceImage, sourceImageRect, filter, results);
-        return;
-    }
-
     for (auto& effect : filter.effectsOfType(FilterEffect::Type::FEImage)) {
-        bool isRecorded = WTF::switchOn(downcast<FEImage>(effect.get()).sourceImage(),
-            [&] (const Ref<Image>& image) {
-                if (auto nativeImage = image->nativeImage()) {
-                    recordResourceUse(*nativeImage);
-                    return true;
-                }
-                return false;
-            },
-            [&] (const Ref<ImageBuffer>& imageBuffer) {
-                if (canDrawImageBuffer(imageBuffer)) {
-                    recordResourceUse(imageBuffer);
-                    return true;
-                }
-                return false;
-            },
-            [&] (RenderingResourceIdentifier) {
-                return true;
-            }
-        );
-
-        if (!isRecorded) {
+        auto& feImage = downcast<FEImage>(effect.get());
+        if (!recordResourceUse(feImage.sourceImage())) {
             GraphicsContext::drawFilteredImageBuffer(sourceImage, sourceImageRect, filter, results);
             return;
         }
@@ -187,7 +163,11 @@
         return;
     }
 
-    recordResourceUse(*sourceImage);
+    if (!recordResourceUse(*sourceImage)) {
+        GraphicsContext::drawFilteredImageBuffer(sourceImage, sourceImageRect, filter, results);
+        return;
+    }
+
     recordDrawFilteredImageBuffer(sourceImage->renderingResourceIdentifier(), sourceImageRect, filter);
 }
 
@@ -206,12 +186,12 @@
 void Recorder::drawImageBuffer(ImageBuffer& imageBuffer, const FloatRect& destRect, const FloatRect& srcRect, const ImagePaintingOptions& options)
 {
     appendStateChangeItemIfNecessary();
-    if (!canDrawImageBuffer(imageBuffer)) {
+
+    if (!recordResourceUse(imageBuffer)) {
         GraphicsContext::drawImageBuffer(imageBuffer, destRect, srcRect, options);
         return;
     }
 
-    recordResourceUse(imageBuffer);
     recordDrawImageBuffer(imageBuffer.renderingResourceIdentifier(), destRect, srcRect, options);
 }
 

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


--- trunk/Source/WebCore/platform/graphics/displaylists/DisplayListRecorder.h	2022-01-23 00:00:38 UTC (rev 288411)
+++ trunk/Source/WebCore/platform/graphics/displaylists/DisplayListRecorder.h	2022-01-23 01:03:39 UTC (rev 288412)
@@ -45,6 +45,7 @@
 class GlyphBuffer;
 class Image;
 class PixelBuffer;
+class SourceImage;
 
 struct GraphicsContextState;
 struct ImagePaintingOptions;
@@ -138,9 +139,10 @@
 #endif
     virtual void recordApplyDeviceScaleFactor(float) = 0;
 
-    virtual void recordResourceUse(NativeImage&) = 0;
-    virtual void recordResourceUse(Font&) = 0;
-    virtual void recordResourceUse(ImageBuffer&) = 0;
+    virtual bool recordResourceUse(NativeImage&) = 0;
+    virtual bool recordResourceUse(ImageBuffer&) = 0;
+    virtual bool recordResourceUse(const SourceImage&) = 0;
+    virtual bool recordResourceUse(Font&) = 0;
 
     // FIXME: Maybe remove this?
     virtual bool canDrawImageBuffer(const ImageBuffer&) const = 0;

Modified: trunk/Source/WebCore/platform/graphics/displaylists/DisplayListRecorderImpl.cpp (288411 => 288412)


--- trunk/Source/WebCore/platform/graphics/displaylists/DisplayListRecorderImpl.cpp	2022-01-23 00:00:38 UTC (rev 288411)
+++ trunk/Source/WebCore/platform/graphics/displaylists/DisplayListRecorderImpl.cpp	2022-01-23 01:03:39 UTC (rev 288412)
@@ -35,6 +35,7 @@
 #include "Logging.h"
 #include "MediaPlayer.h"
 #include "NotImplemented.h"
+#include "SourceImage.h"
 #include <wtf/MathExtras.h>
 #include <wtf/text/TextStream.h>
 
@@ -418,25 +419,41 @@
     append<ApplyDeviceScaleFactor>(scaleFactor);
 }
 
-void RecorderImpl::recordResourceUse(NativeImage& image)
+bool RecorderImpl::recordResourceUse(NativeImage& nativeImage)
 {
     if (m_delegate)
-        m_delegate->recordNativeImageUse(image);
-    m_displayList.cacheNativeImage(image);
+        m_delegate->recordNativeImageUse(nativeImage);
+    m_displayList.cacheNativeImage(nativeImage);
+    return true;
 }
 
-void RecorderImpl::recordResourceUse(Font& font)
+bool RecorderImpl::recordResourceUse(ImageBuffer& imageBuffer)
 {
+    if (!canDrawImageBuffer(imageBuffer))
+        return false;
     if (m_delegate)
-        m_delegate->recordFontUse(font);
-    m_displayList.cacheFont(font);
+        m_delegate->recordImageBufferUse(imageBuffer);
+    m_displayList.cacheImageBuffer(imageBuffer);
+    return true;
 }
 
-void RecorderImpl::recordResourceUse(ImageBuffer& imageBuffer)
+bool RecorderImpl::recordResourceUse(const SourceImage& image)
 {
+    if (auto imageBuffer = image.imageBufferIfExists())
+        return recordResourceUse(*imageBuffer);
+
+    if (auto nativeImage = image.nativeImageIfExists())
+        return recordResourceUse(*nativeImage);
+
+    return true;
+}
+
+bool RecorderImpl::recordResourceUse(Font& font)
+{
     if (m_delegate)
-        m_delegate->recordImageBufferUse(imageBuffer);
-    m_displayList.cacheImageBuffer(imageBuffer);
+        m_delegate->recordFontUse(font);
+    m_displayList.cacheFont(font);
+    return true;
 }
 
 // FIXME: share with ShadowData

Modified: trunk/Source/WebCore/platform/graphics/displaylists/DisplayListRecorderImpl.h (288411 => 288412)


--- trunk/Source/WebCore/platform/graphics/displaylists/DisplayListRecorderImpl.h	2022-01-23 00:00:38 UTC (rev 288411)
+++ trunk/Source/WebCore/platform/graphics/displaylists/DisplayListRecorderImpl.h	2022-01-23 01:03:39 UTC (rev 288412)
@@ -136,9 +136,10 @@
 #endif
     void recordApplyDeviceScaleFactor(float) final;
 
-    void recordResourceUse(NativeImage&) final;
-    void recordResourceUse(Font&) final;
-    void recordResourceUse(ImageBuffer&) final;
+    bool recordResourceUse(NativeImage&) final;
+    bool recordResourceUse(ImageBuffer&) final;
+    bool recordResourceUse(const SourceImage&) final;
+    bool recordResourceUse(Font&) final;
 
     std::unique_ptr<GraphicsContext> createNestedContext(const FloatRect& initialClip, const AffineTransform& initialCTM) final;
 

Modified: trunk/Source/WebCore/svg/SVGFEImageElement.cpp (288411 => 288412)


--- trunk/Source/WebCore/svg/SVGFEImageElement.cpp	2022-01-23 00:00:38 UTC (rev 288411)
+++ trunk/Source/WebCore/svg/SVGFEImageElement.cpp	2022-01-23 01:03:39 UTC (rev 288412)
@@ -210,14 +210,24 @@
 
 RefPtr<FilterEffect> SVGFEImageElement::filterEffect(const SVGFilterBuilder&, const FilterEffectVector&) const
 {
-    if (m_cachedImage)
-        return FEImage::create(Ref { *m_cachedImage->imageForRenderer(renderer()) }, preserveAspectRatio());
+    if (m_cachedImage) {
+        auto image = m_cachedImage->imageForRenderer(renderer());
+        if (!image || image->isNull())
+            return nullptr;
 
+        auto nativeImage = image->preTransformedNativeImageForCurrentFrame();
+        if (!nativeImage)
+            return nullptr;
+
+        auto imageRect = FloatRect { { }, image->size() };
+        return FEImage::create({ nativeImage.releaseNonNull() }, imageRect, preserveAspectRatio());
+    }
+
     auto [imageBuffer, imageRect] = imageBufferForEffect();
     if (!imageBuffer)
         return nullptr;
 
-    return FEImage::create(imageBuffer.releaseNonNull(), imageRect, preserveAspectRatio());
+    return FEImage::create({ imageBuffer.releaseNonNull() }, imageRect, preserveAspectRatio());
 }
 
 void SVGFEImageElement::addSubresourceAttributeURLs(ListHashSet<URL>& urls) const

Modified: trunk/Source/WebCore/svg/graphics/SVGImage.cpp (288411 => 288412)


--- trunk/Source/WebCore/svg/graphics/SVGImage.cpp	2022-01-23 00:00:38 UTC (rev 288411)
+++ trunk/Source/WebCore/svg/graphics/SVGImage.cpp	2022-01-23 01:03:39 UTC (rev 288412)
@@ -208,11 +208,6 @@
     return result;
 }
 
-RefPtr<NativeImage> SVGImage::nativeImageForCurrentFrame()
-{
-    return nativeImage();
-}
-
 RefPtr<NativeImage> SVGImage::nativeImage()
 {
     return nativeImage(size(), FloatRect(FloatPoint(), size()), DestinationColorSpace::SRGB());

Modified: trunk/Source/WebCore/svg/graphics/SVGImage.h (288411 => 288412)


--- trunk/Source/WebCore/svg/graphics/SVGImage.h	2022-01-23 00:00:38 UTC (rev 288411)
+++ trunk/Source/WebCore/svg/graphics/SVGImage.h	2022-01-23 01:03:39 UTC (rev 288412)
@@ -86,7 +86,6 @@
     // FIXME: Implement this to be less conservative.
     bool currentFrameKnownToBeOpaque() const final { return false; }
 
-    RefPtr<NativeImage> nativeImageForCurrentFrame() final;
     RefPtr<NativeImage> nativeImage() final;
     RefPtr<NativeImage> nativeImage(const FloatSize& imageSize, const FloatRect& sourceRect, DestinationColorSpace);
 

Modified: trunk/Source/WebCore/svg/graphics/filters/SVGFEImage.cpp (288411 => 288412)


--- trunk/Source/WebCore/svg/graphics/filters/SVGFEImage.cpp	2022-01-23 00:00:38 UTC (rev 288411)
+++ trunk/Source/WebCore/svg/graphics/filters/SVGFEImage.cpp	2022-01-23 01:03:39 UTC (rev 288412)
@@ -31,12 +31,6 @@
 
 namespace WebCore {
 
-Ref<FEImage> FEImage::create(Ref<Image>&& image, const SVGPreserveAspectRatioValue& preserveAspectRatio)
-{
-    auto imageRect = FloatRect { { }, image->size() };
-    return create(WTFMove(image), imageRect, preserveAspectRatio);
-}
-
 Ref<FEImage> FEImage::create(SourceImage&& sourceImage, const FloatRect& sourceImageRect, const SVGPreserveAspectRatioValue& preserveAspectRatio)
 {
     return adoptRef(*new FEImage(WTFMove(sourceImage), sourceImageRect, preserveAspectRatio));
@@ -52,22 +46,18 @@
 
 FloatRect FEImage::calculateImageRect(const Filter& filter, const FilterImageVector&, const FloatRect& primitiveSubregion) const
 {
-    auto imageRect = WTF::switchOn(m_sourceImage,
-        [&] (const Ref<Image>&) {
-            auto imageRect = primitiveSubregion;
-            auto srcRect = m_sourceImageRect;
-            m_preserveAspectRatio.transformRect(imageRect, srcRect);
-            return imageRect;
-        },
-        [&] (const Ref<ImageBuffer>&) {
-            return primitiveSubregion;
-        },
-        [&] (RenderingResourceIdentifier) {
-            ASSERT_NOT_REACHED();
-            return FloatRect();
-        }
-    );
-    return filter.clipToMaxEffectRect(imageRect, primitiveSubregion);
+    if (m_sourceImage.nativeImageIfExists()) {
+        auto imageRect = primitiveSubregion;
+        auto srcRect = m_sourceImageRect;
+        m_preserveAspectRatio.transformRect(imageRect, srcRect);
+        return filter.clipToMaxEffectRect(imageRect, primitiveSubregion);
+    }
+
+    if (m_sourceImage.imageBufferIfExists())
+        return filter.maxEffectRect(primitiveSubregion);
+
+    ASSERT_NOT_REACHED();
+    return FloatRect();
 }
 
 // FIXME: Move the class FEImageSoftwareApplier to separate source and header files.
@@ -87,31 +77,31 @@
     if (!resultImage)
         return false;
 
+    auto& sourceImage = m_effect.sourceImage();
     auto primitiveSubregion = result.primitiveSubregion();
     auto& context = resultImage->context();
 
-    WTF::switchOn(m_effect.sourceImage(),
-        [&] (const Ref<Image>& image) {
-            auto imageRect = primitiveSubregion;
-            auto srcRect = m_effect.sourceImageRect();
-            m_effect.preserveAspectRatio().transformRect(imageRect, srcRect);
-            imageRect.scale(filter.filterScale());
-            imageRect = IntRect(imageRect) - result.absoluteImageRect().location();
-            context.drawImage(image, imageRect, srcRect);
-        },
-        [&] (const Ref<ImageBuffer>& imageBuffer) {
-            auto imageRect = primitiveSubregion;
-            imageRect.moveBy(m_effect.sourceImageRect().location());
-            imageRect.scale(filter.filterScale());
-            imageRect = IntRect(imageRect) - result.absoluteImageRect().location();
-            context.drawImageBuffer(imageBuffer, imageRect.location());
-        },
-        [&] (RenderingResourceIdentifier) {
-            ASSERT_NOT_REACHED();
-        }
-    );
+    if (auto nativeImage = sourceImage.nativeImageIfExists()) {
+        auto imageRect = primitiveSubregion;
+        auto srcRect = m_effect.sourceImageRect();
+        m_effect.preserveAspectRatio().transformRect(imageRect, srcRect);
+        imageRect.scale(filter.filterScale());
+        imageRect = IntRect(imageRect) - result.absoluteImageRect().location();
+        context.drawNativeImage(*nativeImage, srcRect.size(), imageRect, srcRect);
+        return true;
+    }
 
-    return true;
+    if (auto imageBuffer = sourceImage.imageBufferIfExists()) {
+        auto imageRect = primitiveSubregion;
+        imageRect.moveBy(m_effect.sourceImageRect().location());
+        imageRect.scale(filter.filterScale());
+        imageRect = IntRect(imageRect) - result.absoluteImageRect().location();
+        context.drawImageBuffer(*imageBuffer, imageRect.location());
+        return true;
+    }
+    
+    ASSERT_NOT_REACHED();
+    return false;
 }
 
 std::unique_ptr<FilterEffectApplier> FEImage::createSoftwareApplier() const

Modified: trunk/Source/WebCore/svg/graphics/filters/SVGFEImage.h (288411 => 288412)


--- trunk/Source/WebCore/svg/graphics/filters/SVGFEImage.h	2022-01-23 00:00:38 UTC (rev 288411)
+++ trunk/Source/WebCore/svg/graphics/filters/SVGFEImage.h	2022-01-23 01:03:39 UTC (rev 288412)
@@ -27,6 +27,7 @@
 #include "Image.h"
 #include "ImageBuffer.h"
 #include "SVGPreserveAspectRatioValue.h"
+#include "SourceImage.h"
 
 namespace WebCore {
 
@@ -35,13 +36,6 @@
 
 class FEImage final : public FilterEffect {
 public:
-    using SourceImage = std::variant<
-        Ref<Image>,
-        Ref<ImageBuffer>,
-        RenderingResourceIdentifier
-    >;
-
-    static Ref<FEImage> create(Ref<Image>&&, const SVGPreserveAspectRatioValue&);
     WEBCORE_EXPORT static Ref<FEImage> create(SourceImage&&, const FloatRect& sourceImageRect, const SVGPreserveAspectRatioValue&);
 
     const SourceImage& sourceImage() const { return m_sourceImage; }
@@ -75,19 +69,7 @@
 template<class Encoder>
 void FEImage::encode(Encoder& encoder) const
 {
-    WTF::switchOn(m_sourceImage,
-        [&] (const Ref<Image>& image) {
-            if (auto nativeImage = image->nativeImage())
-                encoder << nativeImage->renderingResourceIdentifier();
-        },
-        [&] (const Ref<ImageBuffer>& imageBuffer) {
-            encoder << imageBuffer->renderingResourceIdentifier();
-        },
-        [&] (RenderingResourceIdentifier renderingResourceIdentifier) {
-            encoder << renderingResourceIdentifier;
-        }
-    );
-
+    encoder << m_sourceImage;
     encoder << m_sourceImageRect;
     encoder << m_preserveAspectRatio;
 }
@@ -95,9 +77,9 @@
 template<class Decoder>
 std::optional<Ref<FEImage>> FEImage::decode(Decoder& decoder)
 {
-    std::optional<RenderingResourceIdentifier> imageIdentifier;
-    decoder >> imageIdentifier;
-    if (!imageIdentifier)
+    std::optional<SourceImage> sourceImage;
+    decoder >> sourceImage;
+    if (!sourceImage)
         return std::nullopt;
 
     std::optional<FloatRect> sourceImageRect;
@@ -110,7 +92,7 @@
     if (!preserveAspectRatio)
         return std::nullopt;
 
-    return FEImage::create(*imageIdentifier, *sourceImageRect, *preserveAspectRatio);
+    return FEImage::create(WTFMove(*sourceImage), *sourceImageRect, *preserveAspectRatio);
 }
 
 } // namespace WebCore

Modified: trunk/Source/WebKit/ChangeLog (288411 => 288412)


--- trunk/Source/WebKit/ChangeLog	2022-01-23 00:00:38 UTC (rev 288411)
+++ trunk/Source/WebKit/ChangeLog	2022-01-23 01:03:39 UTC (rev 288412)
@@ -1,3 +1,18 @@
+2022-01-22  Said Abou-Hallawa  <s...@apple.com>
+
+        [GPU Process] Add the class 'SourceImage' to represent variants of image
+        https://bugs.webkit.org/show_bug.cgi?id=235467
+
+        Reviewed by Cameron McCormack.
+
+        Provide a new recordResourceUse() for the SourceImage.
+
+        * GPUProcess/graphics/RemoteDisplayListRecorder.cpp:
+        (WebKit::RemoteDisplayListRecorder::drawFilteredImageBuffer):
+        * WebProcess/GPU/graphics/RemoteDisplayListRecorderProxy.cpp:
+        (WebKit::RemoteDisplayListRecorderProxy::recordResourceUse):
+        * WebProcess/GPU/graphics/RemoteDisplayListRecorderProxy.h:
+
 2022-01-22  Elliott Williams  <e...@apple.com>
 
         Skip installing webpushd in STP and downlevel builds

Modified: trunk/Source/WebKit/GPUProcess/graphics/RemoteDisplayListRecorder.cpp (288411 => 288412)


--- trunk/Source/WebKit/GPUProcess/graphics/RemoteDisplayListRecorder.cpp	2022-01-23 00:00:38 UTC (rev 288411)
+++ trunk/Source/WebKit/GPUProcess/graphics/RemoteDisplayListRecorder.cpp	2022-01-23 01:03:39 UTC (rev 288412)
@@ -239,18 +239,18 @@
     for (auto& effect : filter->effectsOfType(FilterEffect::Type::FEImage)) {
         auto& feImage = downcast<FEImage>(effect.get());
 
-        const auto* resourceIdentifier = std::get_if<RenderingResourceIdentifier>(&feImage.sourceImage());
-        if (!resourceIdentifier) {
+        auto imageIdentifier = feImage.sourceImage().imageIdentifier();
+        if (!imageIdentifier) {
             ASSERT_NOT_REACHED();
             return;
         }
 
-        if (auto nativeImage = resourceCache().cachedNativeImage({ *resourceIdentifier, m_webProcessIdentifier })) {
-            feImage.setImageSource(Ref<Image> { BitmapImage::create(nativeImage) });
+        if (auto nativeImage = resourceCache().cachedNativeImage({ imageIdentifier, m_webProcessIdentifier })) {
+            feImage.setImageSource({ *nativeImage });
             continue;
         }
 
-        if (auto imageBuffer = resourceCache().cachedImageBuffer({ *resourceIdentifier, m_webProcessIdentifier })) {
+        if (auto imageBuffer = resourceCache().cachedImageBuffer({ imageIdentifier, m_webProcessIdentifier })) {
             feImage.setImageSource({ *imageBuffer });
             continue;
         }

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


--- trunk/Source/WebKit/WebProcess/GPU/graphics/RemoteDisplayListRecorderProxy.cpp	2022-01-23 00:00:38 UTC (rev 288411)
+++ trunk/Source/WebKit/WebProcess/GPU/graphics/RemoteDisplayListRecorderProxy.cpp	2022-01-23 01:03:39 UTC (rev 288412)
@@ -412,34 +412,51 @@
     send(Messages::RemoteDisplayListRecorder::ApplyDeviceScaleFactor(scaleFactor));
 }
 
-void RemoteDisplayListRecorderProxy::recordResourceUse(NativeImage& image)
+bool RemoteDisplayListRecorderProxy::recordResourceUse(NativeImage& image)
 {
     if (UNLIKELY(!m_renderingBackend)) {
         ASSERT_NOT_REACHED();
-        return;
+        return false;
     }
 
     m_renderingBackend->recordNativeImageUse(image);
+    return true;
 }
 
-void RemoteDisplayListRecorderProxy::recordResourceUse(Font& font)
+bool RemoteDisplayListRecorderProxy::recordResourceUse(ImageBuffer& imageBuffer)
 {
     if (UNLIKELY(!m_renderingBackend)) {
         ASSERT_NOT_REACHED();
-        return;
+        return false;
     }
 
-    m_renderingBackend->recordFontUse(font);
+    if (!canDrawImageBuffer(imageBuffer))
+        return false;
+
+    m_renderingBackend->recordImageBufferUse(imageBuffer);
+    return true;
 }
 
-void RemoteDisplayListRecorderProxy::recordResourceUse(ImageBuffer& imageBuffer)
+bool RemoteDisplayListRecorderProxy::recordResourceUse(const SourceImage& image)
 {
+    if (auto imageBuffer = image.imageBufferIfExists())
+        return recordResourceUse(*imageBuffer);
+
+    if (auto nativeImage = image.nativeImageIfExists())
+        return recordResourceUse(*nativeImage);
+
+    return true;
+}
+
+bool RemoteDisplayListRecorderProxy::recordResourceUse(Font& font)
+{
     if (UNLIKELY(!m_renderingBackend)) {
         ASSERT_NOT_REACHED();
-        return;
+        return false;
     }
 
-    m_renderingBackend->recordImageBufferUse(imageBuffer);
+    m_renderingBackend->recordFontUse(font);
+    return true;
 }
 
 void RemoteDisplayListRecorderProxy::flushContext(GraphicsContextFlushIdentifier identifier)

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


--- trunk/Source/WebKit/WebProcess/GPU/graphics/RemoteDisplayListRecorderProxy.h	2022-01-23 00:00:38 UTC (rev 288411)
+++ trunk/Source/WebKit/WebProcess/GPU/graphics/RemoteDisplayListRecorderProxy.h	2022-01-23 01:03:39 UTC (rev 288412)
@@ -138,9 +138,10 @@
 #endif
     void recordApplyDeviceScaleFactor(float) final;
 
-    void recordResourceUse(WebCore::NativeImage&) final;
-    void recordResourceUse(WebCore::Font&) final;
-    void recordResourceUse(WebCore::ImageBuffer&) final;
+    bool recordResourceUse(WebCore::NativeImage&) final;
+    bool recordResourceUse(WebCore::ImageBuffer&) final;
+    bool recordResourceUse(const WebCore::SourceImage&) final;
+    bool recordResourceUse(WebCore::Font&) final;
 
     std::unique_ptr<WebCore::GraphicsContext> createNestedContext(const WebCore::FloatRect& initialClip, const WebCore::AffineTransform& initialCTM) final;
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to