Title: [286203] trunk/Source/WebCore
Revision
286203
Author
s...@apple.com
Date
2021-11-28 22:08:27 -0800 (Sun, 28 Nov 2021)

Log Message

[GPU Process] Apply the filter to an ImageBuffer through GraphicsContext and ImageBuffer
https://bugs.webkit.org/show_bug.cgi?id=232843

Reviewed by Cameron McCormack.

This step will allow sending the Filter to GPUProcess and applying it to
a remote ImageBuffer.

In this patch, managing the sourceImageBuffer of the CSSFilter is moved
to RenderLayerFilters. This is similar to what RenderSVGResourceFilter
does by maintaining the sourceImage for the SVGFilter.

* Headers.cmake:
* Sources.txt:
* WebCore.xcodeproj/project.pbxproj:
* css/CSSFilterImageValue.cpp:
(WebCore::CSSFilterImageValue::image):
* platform/graphics/ConcreteImageBuffer.h:
* platform/graphics/GraphicsContext.cpp:
(WebCore::GraphicsContext::drawFilteredImageBuffer):
* platform/graphics/GraphicsContext.h:
* platform/graphics/ImageBuffer.h:
* platform/graphics/filters/Filter.cpp: Added.
(WebCore::Filter::Filter):
(WebCore::Filter::apply):
* platform/graphics/filters/Filter.h:
(WebCore::Filter::renderingMode const):
(WebCore::Filter::setRenderingMode):
(WebCore::Filter::scaledByFilterScale const):
(WebCore::Filter::Filter): Deleted.
* platform/graphics/filters/FilterImage.h:
* platform/graphics/filters/software/FETileSoftwareApplier.cpp:
* platform/graphics/filters/software/SourceAlphaSoftwareApplier.cpp:
* platform/graphics/filters/software/SourceGraphicSoftwareApplier.cpp:
* rendering/CSSFilter.cpp:
(WebCore::CSSFilter::apply):
(WebCore::CSSFilter::setSourceImageRect):
(WebCore::CSSFilter::inputContext): Deleted.
(WebCore::CSSFilter::allocateBackingStoreIfNeeded): Deleted.
(WebCore::CSSFilter::output): Deleted.
(WebCore::CSSFilter::outputRect): Deleted.
* rendering/CSSFilter.h:
* rendering/RenderLayerFilters.cpp:
(WebCore::RenderLayerFilters::inputContext):
(WebCore::RenderLayerFilters::allocateBackingStore):
(WebCore::RenderLayerFilters::beginFilterEffect):
(WebCore::RenderLayerFilters::applyFilterEffect):
* rendering/RenderLayerFilters.h:
* rendering/svg/RenderSVGResourceFilter.cpp:
(WebCore::RenderSVGResourceFilter::postApplyResource):
* svg/graphics/filters/SVGFilter.cpp:
(WebCore::SVGFilter::apply):
* svg/graphics/filters/SVGFilter.h:

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (286202 => 286203)


--- trunk/Source/WebCore/ChangeLog	2021-11-29 05:11:26 UTC (rev 286202)
+++ trunk/Source/WebCore/ChangeLog	2021-11-29 06:08:27 UTC (rev 286203)
@@ -1,3 +1,59 @@
+2021-11-28  Said Abou-Hallawa  <s...@apple.com>
+
+        [GPU Process] Apply the filter to an ImageBuffer through GraphicsContext and ImageBuffer
+        https://bugs.webkit.org/show_bug.cgi?id=232843
+
+        Reviewed by Cameron McCormack.
+
+        This step will allow sending the Filter to GPUProcess and applying it to
+        a remote ImageBuffer.
+
+        In this patch, managing the sourceImageBuffer of the CSSFilter is moved
+        to RenderLayerFilters. This is similar to what RenderSVGResourceFilter 
+        does by maintaining the sourceImage for the SVGFilter.
+
+        * Headers.cmake:
+        * Sources.txt:
+        * WebCore.xcodeproj/project.pbxproj:
+        * css/CSSFilterImageValue.cpp:
+        (WebCore::CSSFilterImageValue::image):
+        * platform/graphics/ConcreteImageBuffer.h:
+        * platform/graphics/GraphicsContext.cpp:
+        (WebCore::GraphicsContext::drawFilteredImageBuffer):
+        * platform/graphics/GraphicsContext.h:
+        * platform/graphics/ImageBuffer.h:
+        * platform/graphics/filters/Filter.cpp: Added.
+        (WebCore::Filter::Filter):
+        (WebCore::Filter::apply):
+        * platform/graphics/filters/Filter.h:
+        (WebCore::Filter::renderingMode const):
+        (WebCore::Filter::setRenderingMode):
+        (WebCore::Filter::scaledByFilterScale const):
+        (WebCore::Filter::Filter): Deleted.
+        * platform/graphics/filters/FilterImage.h:
+        * platform/graphics/filters/software/FETileSoftwareApplier.cpp:
+        * platform/graphics/filters/software/SourceAlphaSoftwareApplier.cpp:
+        * platform/graphics/filters/software/SourceGraphicSoftwareApplier.cpp:
+        * rendering/CSSFilter.cpp:
+        (WebCore::CSSFilter::apply):
+        (WebCore::CSSFilter::setSourceImageRect):
+        (WebCore::CSSFilter::inputContext): Deleted.
+        (WebCore::CSSFilter::allocateBackingStoreIfNeeded): Deleted.
+        (WebCore::CSSFilter::output): Deleted.
+        (WebCore::CSSFilter::outputRect): Deleted.
+        * rendering/CSSFilter.h:
+        * rendering/RenderLayerFilters.cpp:
+        (WebCore::RenderLayerFilters::inputContext):
+        (WebCore::RenderLayerFilters::allocateBackingStore):
+        (WebCore::RenderLayerFilters::beginFilterEffect):
+        (WebCore::RenderLayerFilters::applyFilterEffect):
+        * rendering/RenderLayerFilters.h:
+        * rendering/svg/RenderSVGResourceFilter.cpp:
+        (WebCore::RenderSVGResourceFilter::postApplyResource):
+        * svg/graphics/filters/SVGFilter.cpp:
+        (WebCore::SVGFilter::apply):
+        * svg/graphics/filters/SVGFilter.h:
+
 2021-11-28  Matt Woodrow  <matt.wood...@gmail.com>
 
         Serialize computed style of background shorthand with multiple layers correctly.

Modified: trunk/Source/WebCore/Headers.cmake (286202 => 286203)


--- trunk/Source/WebCore/Headers.cmake	2021-11-29 05:11:26 UTC (rev 286202)
+++ trunk/Source/WebCore/Headers.cmake	2021-11-29 06:08:27 UTC (rev 286203)
@@ -1423,6 +1423,9 @@
 
     platform/graphics/cv/ImageTransferSessionVT.h
 
+    platform/graphics/filters/Filter.h
+    platform/graphics/filters/FilterFunction.h
+    platform/graphics/filters/FilterImage.h
     platform/graphics/filters/FilterOperation.h
     platform/graphics/filters/FilterOperations.h
 

Modified: trunk/Source/WebCore/Sources.txt (286202 => 286203)


--- trunk/Source/WebCore/Sources.txt	2021-11-29 05:11:26 UTC (rev 286202)
+++ trunk/Source/WebCore/Sources.txt	2021-11-29 06:08:27 UTC (rev 286203)
@@ -2101,6 +2101,7 @@
 platform/graphics/filters/FESpecularLighting.cpp
 platform/graphics/filters/FETile.cpp
 platform/graphics/filters/FETurbulence.cpp
+platform/graphics/filters/Filter.cpp
 platform/graphics/filters/FilterEffect.cpp
 platform/graphics/filters/FilterFunction.cpp
 platform/graphics/filters/FilterImage.cpp

Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (286202 => 286203)


--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2021-11-29 05:11:26 UTC (rev 286202)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2021-11-29 06:08:27 UTC (rev 286203)
@@ -2305,6 +2305,8 @@
 		7299BC6823D6A53E00CC6883 /* RenderingMode.h in Headers */ = {isa = PBXBuildFile; fileRef = 7299BC6623D686C600CC6883 /* RenderingMode.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		729D05302531424300422098 /* RenderingResourceIdentifier.h in Headers */ = {isa = PBXBuildFile; fileRef = 729D052E25313E2600422098 /* RenderingResourceIdentifier.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		72A73BEF245A3F90001C9D03 /* AnimationFrameRate.h in Headers */ = {isa = PBXBuildFile; fileRef = 722A815C238FD50500C00583 /* AnimationFrameRate.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		72B8B0352753438600F752AA /* FilterFunction.h in Headers */ = {isa = PBXBuildFile; fileRef = 7262D756272A174100C56A09 /* FilterFunction.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		72B8B0362753441400F752AA /* FilterImage.h in Headers */ = {isa = PBXBuildFile; fileRef = 72435EF4273D07670005E7EE /* FilterImage.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		72BAC3AE23E1F0B0008D741C /* ImageBufferBackend.h in Headers */ = {isa = PBXBuildFile; fileRef = 72BAC3A523E17328008D741C /* ImageBufferBackend.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		72F667E1260C26AC00EE36AD /* DiagnosticLoggingDomain.h in Headers */ = {isa = PBXBuildFile; fileRef = 72F667DF260C264400EE36AD /* DiagnosticLoggingDomain.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		7553CFE8108F473F00EA281E /* TimelineRecordFactory.h in Headers */ = {isa = PBXBuildFile; fileRef = 7553CFE6108F473F00EA281E /* TimelineRecordFactory.h */; };
@@ -2707,7 +2709,7 @@
 		84224194107E78A700766A87 /* SVGFEMorphologyElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 84224191107E78A700766A87 /* SVGFEMorphologyElement.h */; };
 		84300BD6120C9AAC0021954A /* SVGPathStringSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 84300BD5120C9AAC0021954A /* SVGPathStringSource.h */; };
 		84300BD8120C9AD40021954A /* SVGPathSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 84300BD7120C9AD40021954A /* SVGPathSource.h */; };
-		845E72F80FD261EE00A87D79 /* Filter.h in Headers */ = {isa = PBXBuildFile; fileRef = 845E72F70FD261EE00A87D79 /* Filter.h */; };
+		845E72F80FD261EE00A87D79 /* Filter.h in Headers */ = {isa = PBXBuildFile; fileRef = 845E72F70FD261EE00A87D79 /* Filter.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		845E72FC0FD2623900A87D79 /* SVGFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = 845E72FA0FD2623900A87D79 /* SVGFilter.h */; };
 		84650E7E2387AD7D006266E2 /* MediaQueryListEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 84650E7C2387AD7C006266E2 /* MediaQueryListEvent.h */; };
 		84730D771248F0B300D3A9C9 /* DistantLightSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 84730D5A1248F0B300D3A9C9 /* DistantLightSource.h */; };
@@ -11204,6 +11206,7 @@
 		72B8B01E2751B91000F752AA /* FEColorMatrixCoreImageApplier.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = FEColorMatrixCoreImageApplier.mm; sourceTree = "<group>"; };
 		72B8B01F2751B92800F752AA /* FEColorMatrixCoreImageApplier.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FEColorMatrixCoreImageApplier.h; sourceTree = "<group>"; };
 		72B8B0202751C4B700F752AA /* FilterImageCoreImage.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = FilterImageCoreImage.mm; sourceTree = "<group>"; };
+		72B8B03227533F8100F752AA /* Filter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Filter.cpp; sourceTree = "<group>"; };
 		72BAC3A423E17327008D741C /* ImageBufferBackend.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ImageBufferBackend.cpp; sourceTree = "<group>"; };
 		72BAC3A523E17328008D741C /* ImageBufferBackend.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageBufferBackend.h; sourceTree = "<group>"; };
 		72BAC3A623E17328008D741C /* PlatformImageBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlatformImageBuffer.h; sourceTree = "<group>"; };
@@ -26566,6 +26569,7 @@
 				84730D6E1248F0B300D3A9C9 /* FETile.h */,
 				84730D6F1248F0B300D3A9C9 /* FETurbulence.cpp */,
 				84730D701248F0B300D3A9C9 /* FETurbulence.h */,
+				72B8B03227533F8100F752AA /* Filter.cpp */,
 				845E72F70FD261EE00A87D79 /* Filter.h */,
 				08C925170FCC7C4A00480DEC /* FilterEffect.cpp */,
 				08C925180FCC7C4A00480DEC /* FilterEffect.h */,
@@ -34110,6 +34114,8 @@
 				712BE4831FE865DD002031CC /* FillMode.h in Headers */,
 				845E72F80FD261EE00A87D79 /* Filter.h in Headers */,
 				08C9251A0FCC7C4A00480DEC /* FilterEffect.h in Headers */,
+				72B8B0352753438600F752AA /* FilterFunction.h in Headers */,
+				72B8B0362753441400F752AA /* FilterImage.h in Headers */,
 				49ECEB6E1499790D00CDD3A4 /* FilterOperation.h in Headers */,
 				49ECEB701499790D00CDD3A4 /* FilterOperations.h in Headers */,
 				372C00D9129619F8005C9575 /* FindOptions.h in Headers */,

Modified: trunk/Source/WebCore/css/CSSFilterImageValue.cpp (286202 => 286203)


--- trunk/Source/WebCore/css/CSSFilterImageValue.cpp	2021-11-29 05:11:26 UTC (rev 286202)
+++ trunk/Source/WebCore/css/CSSFilterImageValue.cpp	2021-11-29 06:08:27 UTC (rev 286203)
@@ -130,14 +130,10 @@
     if (!cssFilter->buildFilterFunctions(renderer, m_filterOperations, FilterConsumer::FilterFunction))
         return &Image::nullImage();
 
-    cssFilter->setSourceImage(WTFMove(sourceImage));
-    cssFilter->apply();
+    if (auto image = sourceImage->filteredImage(*cssFilter))
+        return image;
 
-    auto* output = cssFilter->output();
-    if (!output)
-        return &Image::nullImage();
-
-    return output->copyImage();
+    return &Image::nullImage();
 }
 
 void CSSFilterImageValue::filterImageChanged(const IntRect&)

Modified: trunk/Source/WebCore/platform/graphics/ConcreteImageBuffer.h (286202 => 286203)


--- trunk/Source/WebCore/platform/graphics/ConcreteImageBuffer.h	2021-11-29 05:11:26 UTC (rev 286202)
+++ trunk/Source/WebCore/platform/graphics/ConcreteImageBuffer.h	2021-11-29 06:08:27 UTC (rev 286203)
@@ -25,6 +25,8 @@
 
 #pragma once
 
+#include "Filter.h"
+#include "FilterImage.h"
 #include "ImageBuffer.h"
 #include "PixelBuffer.h"
 
@@ -137,6 +139,24 @@
         return nullptr;
     }
 
+    RefPtr<Image> filteredImage(Filter& filter) override
+    {
+        auto* backend = ensureBackendCreated();
+        if (!backend)
+            return nullptr;
+
+        const_cast<ConcreteImageBuffer&>(*this).flushDrawingContext();
+        auto result = filter.apply(this);
+        if (!result)
+            return nullptr;
+
+        auto imageBuffer = result->imageBuffer();
+        if (!imageBuffer)
+            return nullptr;
+
+        return imageBuffer->copyImage();
+    }
+
     void draw(GraphicsContext& destContext, const FloatRect& destRect, const FloatRect& srcRect, const ImagePaintingOptions& options) override
     {
         if (auto* backend = ensureBackendCreated()) {

Modified: trunk/Source/WebCore/platform/graphics/GraphicsContext.cpp (286202 => 286203)


--- trunk/Source/WebCore/platform/graphics/GraphicsContext.cpp	2021-11-29 05:11:26 UTC (rev 286202)
+++ trunk/Source/WebCore/platform/graphics/GraphicsContext.cpp	2021-11-29 06:08:27 UTC (rev 286203)
@@ -28,6 +28,8 @@
 
 #include "BidiResolver.h"
 #include "BitmapImage.h"
+#include "Filter.h"
+#include "FilterImage.h"
 #include "FloatRoundedRect.h"
 #include "Gradient.h"
 #include "ImageBuffer.h"
@@ -629,6 +631,19 @@
     ImageBuffer::drawConsuming(WTFMove(image), *this, destination, source, options);
 }
 
+void GraphicsContext::drawFilteredImageBuffer(ImageBuffer* sourceImage, Filter& filter)
+{
+    auto result = filter.apply(sourceImage);
+    if (!result)
+        return;
+    
+    auto imageBuffer = result->imageBuffer();
+    if (!imageBuffer)
+        return;
+
+    drawImageBuffer(*imageBuffer, result->absoluteImageRect());
+}
+
 void GraphicsContext::clipRoundedRect(const FloatRoundedRect& rect)
 {
     Path path;

Modified: trunk/Source/WebCore/platform/graphics/GraphicsContext.h (286202 => 286203)


--- trunk/Source/WebCore/platform/graphics/GraphicsContext.h	2021-11-29 05:11:26 UTC (rev 286202)
+++ trunk/Source/WebCore/platform/graphics/GraphicsContext.h	2021-11-29 06:08:27 UTC (rev 286203)
@@ -85,6 +85,7 @@
 namespace WebCore {
 
 class AffineTransform;
+class Filter;
 class FloatRoundedRect;
 class Gradient;
 class GraphicsContextPlatformPrivate;
@@ -451,6 +452,8 @@
     WEBCORE_EXPORT void drawConsumingImageBuffer(RefPtr<ImageBuffer>, const FloatRect& destination, const ImagePaintingOptions& = { });
     WEBCORE_EXPORT virtual void drawConsumingImageBuffer(RefPtr<ImageBuffer>, const FloatRect& destination, const FloatRect& source, const ImagePaintingOptions& = { });
 
+    WEBCORE_EXPORT virtual void drawFilteredImageBuffer(ImageBuffer* sourceImage, Filter&);
+
     virtual void drawPattern(NativeImage&, const FloatSize& imageSize, const FloatRect& destRect, const FloatRect& tileRect, const AffineTransform& patternTransform, const FloatPoint& phase, const FloatSize& spacing, const ImagePaintingOptions& = { }) = 0;
 
 #if ENABLE(VIDEO)

Modified: trunk/Source/WebCore/platform/graphics/ImageBuffer.h (286202 => 286203)


--- trunk/Source/WebCore/platform/graphics/ImageBuffer.h	2021-11-29 05:11:26 UTC (rev 286202)
+++ trunk/Source/WebCore/platform/graphics/ImageBuffer.h	2021-11-29 06:08:27 UTC (rev 286203)
@@ -42,6 +42,8 @@
 struct ItemBufferHandle;
 }
 
+class Filter;
+
 class ImageBuffer : public ThreadSafeRefCounted<ImageBuffer, WTF::DestructionThread::Main>, public CanMakeWeakPtr<ImageBuffer> {
 public:
     // Will return a null pointer on allocation failure.
@@ -107,6 +109,7 @@
 
     virtual RefPtr<NativeImage> copyNativeImage(BackingStoreCopy = CopyBackingStore) const = 0;
     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&);

Added: trunk/Source/WebCore/platform/graphics/filters/Filter.cpp (0 => 286203)


--- trunk/Source/WebCore/platform/graphics/filters/Filter.cpp	                        (rev 0)
+++ trunk/Source/WebCore/platform/graphics/filters/Filter.cpp	2021-11-29 06:08:27 UTC (rev 286203)
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2021 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 "Filter.h"
+
+#include "FilterImage.h"
+
+namespace WebCore {
+
+Filter::Filter(Filter::Type filterType, RenderingMode renderingMode, const FloatSize& filterScale)
+    : FilterFunction(filterType)
+    , m_renderingMode(renderingMode)
+    , m_filterScale(filterScale)
+{
+}
+
+Filter::Filter(Filter::Type filterType, RenderingMode renderingMode, const FloatSize& filterScale, const FloatRect& sourceImageRect, const FloatRect& filterRegion)
+    : FilterFunction(filterType)
+    , m_renderingMode(renderingMode)
+    , m_filterScale(filterScale)
+    , m_sourceImageRect(sourceImageRect)
+    , m_filterRegion(filterRegion)
+{
+}
+
+RefPtr<FilterImage> Filter::apply(ImageBuffer* sourceImage)
+{
+    setSourceImage(sourceImage);
+
+    auto result = apply();
+    if (!result)
+        return { };
+
+    result->transformToColorSpace(DestinationColorSpace::SRGB());
+    return result;
+}
+
+} // namespace WebCore

Modified: trunk/Source/WebCore/platform/graphics/filters/Filter.h (286202 => 286203)


--- trunk/Source/WebCore/platform/graphics/filters/Filter.h	2021-11-29 05:11:26 UTC (rev 286202)
+++ trunk/Source/WebCore/platform/graphics/filters/Filter.h	2021-11-29 06:08:27 UTC (rev 286203)
@@ -29,12 +29,15 @@
 
 namespace WebCore {
 
-class FilterEffect;
+class FilterImage;
 
 class Filter : public FilterFunction {
     using FilterFunction::apply;
 
 public:
+    RenderingMode renderingMode() const { return m_renderingMode; }
+    void setRenderingMode(RenderingMode renderingMode) { m_renderingMode = renderingMode; }
+    
     FloatSize filterScale() const { return m_filterScale; }
     void setFilterScale(const FloatSize& filterScale) { m_filterScale = filterScale; }
 
@@ -44,32 +47,18 @@
     FloatRect filterRegion() const { return m_filterRegion; }
     void setFilterRegion(const FloatRect& filterRegion) { m_filterRegion = filterRegion; }
 
-    virtual FloatSize scaledByFilterScale(FloatSize size) const { return size * m_filterScale; }
-    virtual bool apply() = 0;
-
     ImageBuffer* sourceImage() const { return m_sourceImage.get(); }
     void setSourceImage(RefPtr<ImageBuffer>&& sourceImage) { m_sourceImage = WTFMove(sourceImage); }
 
-    RenderingMode renderingMode() const { return m_renderingMode; }
-    void setRenderingMode(RenderingMode renderingMode) { m_renderingMode = renderingMode; }
+    virtual FloatSize scaledByFilterScale(FloatSize size) const { return size * m_filterScale; }
 
+    virtual RefPtr<FilterImage> apply() = 0;
+    WEBCORE_EXPORT RefPtr<FilterImage> apply(ImageBuffer* sourceImage);
+
 protected:
-    Filter(Filter::Type filterType, RenderingMode renderingMode, const FloatSize& filterScale)
-        : FilterFunction(filterType)
-        , m_renderingMode(renderingMode)
-        , m_filterScale(filterScale)
-    {
-    }
+    Filter(Filter::Type, RenderingMode, const FloatSize& filterScale);
+    Filter(Filter::Type, RenderingMode, const FloatSize& filterScale, const FloatRect& sourceImageRect, const FloatRect& filterRegion);
 
-    Filter(Filter::Type filterType, RenderingMode renderingMode, const FloatSize& filterScale, const FloatRect& sourceImageRect, const FloatRect& filterRegion)
-        : FilterFunction(filterType)
-        , m_renderingMode(renderingMode)
-        , m_filterScale(filterScale)
-        , m_sourceImageRect(sourceImageRect)
-        , m_filterRegion(filterRegion)
-    {
-    }
-
 private:
     RenderingMode m_renderingMode;
 

Modified: trunk/Source/WebCore/platform/graphics/filters/FilterImage.h (286202 => 286203)


--- trunk/Source/WebCore/platform/graphics/filters/FilterImage.h	2021-11-29 05:11:26 UTC (rev 286202)
+++ trunk/Source/WebCore/platform/graphics/filters/FilterImage.h	2021-11-29 06:08:27 UTC (rev 286203)
@@ -25,8 +25,9 @@
 
 #pragma once
 
-#include "ImageBuffer.h"
+#include "IntRect.h"
 #include "PixelBuffer.h"
+#include "RenderingMode.h"
 #include <_javascript_Core/Forward.h>
 #include <wtf/RefCounted.h>
 #include <wtf/Vector.h>
@@ -40,7 +41,6 @@
 class Filter;
 class FloatRect;
 class ImageBuffer;
-class PixelBuffer;
 
 class FilterImage : public RefCounted<FilterImage> {
 public:
@@ -56,7 +56,7 @@
     RenderingMode renderingMode() const { return m_renderingMode; }
     const DestinationColorSpace& colorSpace() const { return m_colorSpace; }
 
-    ImageBuffer* imageBuffer();
+    WEBCORE_EXPORT ImageBuffer* imageBuffer();
     PixelBuffer* pixelBuffer(AlphaPremultiplication);
 
     std::optional<PixelBuffer> getPixelBuffer(AlphaPremultiplication, const IntRect& sourceRect, std::optional<DestinationColorSpace> = std::nullopt);

Modified: trunk/Source/WebCore/platform/graphics/filters/software/FETileSoftwareApplier.cpp (286202 => 286203)


--- trunk/Source/WebCore/platform/graphics/filters/software/FETileSoftwareApplier.cpp	2021-11-29 05:11:26 UTC (rev 286202)
+++ trunk/Source/WebCore/platform/graphics/filters/software/FETileSoftwareApplier.cpp	2021-11-29 06:08:27 UTC (rev 286203)
@@ -26,6 +26,7 @@
 #include "FETile.h"
 #include "Filter.h"
 #include "GraphicsContext.h"
+#include "ImageBuffer.h"
 #include "Pattern.h"
 
 namespace WebCore {

Modified: trunk/Source/WebCore/platform/graphics/filters/software/SourceAlphaSoftwareApplier.cpp (286202 => 286203)


--- trunk/Source/WebCore/platform/graphics/filters/software/SourceAlphaSoftwareApplier.cpp	2021-11-29 05:11:26 UTC (rev 286202)
+++ trunk/Source/WebCore/platform/graphics/filters/software/SourceAlphaSoftwareApplier.cpp	2021-11-29 06:08:27 UTC (rev 286203)
@@ -23,6 +23,7 @@
 
 #include "Color.h"
 #include "GraphicsContext.h"
+#include "ImageBuffer.h"
 #include "SourceAlpha.h"
 
 namespace WebCore {

Modified: trunk/Source/WebCore/platform/graphics/filters/software/SourceGraphicSoftwareApplier.cpp (286202 => 286203)


--- trunk/Source/WebCore/platform/graphics/filters/software/SourceGraphicSoftwareApplier.cpp	2021-11-29 05:11:26 UTC (rev 286202)
+++ trunk/Source/WebCore/platform/graphics/filters/software/SourceGraphicSoftwareApplier.cpp	2021-11-29 06:08:27 UTC (rev 286203)
@@ -23,6 +23,7 @@
 
 #include "Filter.h"
 #include "GraphicsContext.h"
+#include "ImageBuffer.h"
 #include "SourceGraphic.h"
 
 namespace WebCore {

Modified: trunk/Source/WebCore/rendering/CSSFilter.cpp (286202 => 286203)


--- trunk/Source/WebCore/rendering/CSSFilter.cpp	2021-11-29 05:11:26 UTC (rev 286202)
+++ trunk/Source/WebCore/rendering/CSSFilter.cpp	2021-11-29 06:08:27 UTC (rev 286203)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011-2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2011-2021 Apple Inc. All rights reserved.
  * Copyright (C) 2013 Google Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -332,11 +332,6 @@
     return true;
 }
 
-GraphicsContext* CSSFilter::inputContext()
-{
-    return sourceImage() ? &sourceImage()->context() : nullptr;
-}
-
 bool CSSFilter::updateBackingStoreRect(const FloatRect& filterRect)
 {
     if (filterRect.isEmpty() || ImageBuffer::sizeNeedsClamping(filterRect.size()))
@@ -349,30 +344,6 @@
     return true;
 }
 
-void CSSFilter::allocateBackingStoreIfNeeded(const GraphicsContext& targetContext)
-{
-    // At this point the effect chain has been built, and the
-    // source image sizes set. We just need to attach the graphic
-    // buffer if we have not yet done so.
-
-    if (m_graphicsBufferAttached)
-        return;
-
-    auto logicalSize = sourceImageRect().size();
-    if (!sourceImage() || sourceImage()->logicalSize() != logicalSize) {
-#if USE(DIRECT2D)
-        setSourceImage(ImageBuffer::create(logicalSize, renderingMode(), &targetContext, 1, DestinationColorSpace::SRGB(), PixelFormat::BGRA8));
-#else
-        UNUSED_PARAM(targetContext);
-        setSourceImage(ImageBuffer::create(logicalSize, renderingMode(), 1, DestinationColorSpace::SRGB(), PixelFormat::BGRA8));
-#endif
-        if (auto context = inputContext())
-            context->scale(filterScale());
-    }
-
-    m_graphicsBufferAttached = true;
-}
-
 RefPtr<FilterEffect> CSSFilter::lastEffect()
 {
     if (m_functions.isEmpty())
@@ -419,15 +390,13 @@
         function->clearResult();
 }
 
-bool CSSFilter::apply()
+RefPtr<FilterImage> CSSFilter::apply()
 {
     for (auto& function : m_functions) {
         if (!function->apply(*this))
-            return false;
+            return nullptr;
     }
-
-    lastEffect()->transformResultColorSpace(DestinationColorSpace::SRGB());
-    return true;
+    return lastEffect()->filterImage();
 }
 
 LayoutRect CSSFilter::computeSourceImageRectForDirtyRect(const LayoutRect& filterBoxRect, const LayoutRect& dirtyRect)
@@ -440,14 +409,6 @@
     return rectForRepaint;
 }
 
-ImageBuffer* CSSFilter::output()
-{
-    if (auto result = lastEffect()->filterImage())
-        return result->imageBuffer();
-
-    return nullptr;
-}
-
 void CSSFilter::setSourceImageRect(const FloatRect& sourceImageRect)
 {
     auto scaledSourceImageRect = sourceImageRect;
@@ -462,20 +423,8 @@
             downcast<SVGFilter>(function.ptr())->setSourceImageRect(scaledSourceImageRect);
         }
     }
-
-    m_graphicsBufferAttached = false;
 }
 
-IntRect CSSFilter::outputRect()
-{
-    auto effect = lastEffect();
-
-    if (auto result = effect->filterImage())
-        return result->absoluteImageRect() - IntPoint(filterRegion().location());
-
-    return { };
-}
-
 IntOutsets CSSFilter::outsets() const
 {
     if (!m_hasFilterThatMovesPixels)

Modified: trunk/Source/WebCore/rendering/CSSFilter.h (286202 => 286203)


--- trunk/Source/WebCore/rendering/CSSFilter.h	2021-11-29 05:11:26 UTC (rev 286202)
+++ trunk/Source/WebCore/rendering/CSSFilter.h	2021-11-29 06:08:27 UTC (rev 286203)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011-2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2011-2021 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -54,19 +54,13 @@
     bool hasFilterThatShouldBeRestrictedBySecurityOrigin() const { return m_hasFilterThatShouldBeRestrictedBySecurityOrigin; }
 
     RefPtr<FilterEffect> lastEffect();
-    GraphicsContext* inputContext();
     IntOutsets outsets() const override;
 
     void clearIntermediateResults();
-    bool apply() override;
+    RefPtr<FilterImage> apply() override;
 
-    ImageBuffer* output();
-
     bool updateBackingStoreRect(const FloatRect& filterRect);
-    void allocateBackingStoreIfNeeded(const GraphicsContext&);
 
-    IntRect outputRect();
-
     LayoutRect computeSourceImageRectForDirtyRect(const LayoutRect& filterBoxRect, const LayoutRect& dirtyRect);
 
 private:
@@ -76,7 +70,6 @@
     bool supportsCoreImageRendering() const override;
 #endif
 
-    bool m_graphicsBufferAttached { false };
     bool m_hasFilterThatMovesPixels { false };
     bool m_hasFilterThatShouldBeRestrictedBySecurityOrigin { false };
 

Modified: trunk/Source/WebCore/rendering/RenderLayerFilters.cpp (286202 => 286203)


--- trunk/Source/WebCore/rendering/RenderLayerFilters.cpp	2021-11-29 05:11:26 UTC (rev 286202)
+++ trunk/Source/WebCore/rendering/RenderLayerFilters.cpp	2021-11-29 06:08:27 UTC (rev 286203)
@@ -124,6 +124,28 @@
     m_filter = CSSFilter::create(renderer.style().filter(), renderingMode, scaleFactor);
 }
 
+GraphicsContext* RenderLayerFilters::inputContext()
+{
+    return m_sourceImage ? &m_sourceImage->context() : nullptr;
+}
+
+void RenderLayerFilters::allocateBackingStore(const GraphicsContext& targetContext)
+{
+    auto& filter = *m_filter;
+    auto logicalSize = filter.sourceImageRect().size();
+    
+    if (!m_sourceImage || m_sourceImage->logicalSize() != logicalSize) {
+#if USE(DIRECT2D)
+        m_sourceImage = ImageBuffer::create(logicalSize, filter.renderingMode(), &targetContext, 1, DestinationColorSpace::SRGB(), PixelFormat::BGRA8);
+#else
+        UNUSED_PARAM(targetContext);
+        m_sourceImage = ImageBuffer::create(logicalSize, filter.renderingMode(), 1, DestinationColorSpace::SRGB(), PixelFormat::BGRA8);
+#endif
+        if (auto context = inputContext())
+            context->scale(filter.filterScale());
+    }
+}
+
 GraphicsContext* RenderLayerFilters::beginFilterEffect(GraphicsContext& destinationContext, RenderElement& renderer, const LayoutRect& filterBoxRect, const LayoutRect& dirtyRect, const LayoutRect& layerRepaintRect)
 {
     if (!m_filter)
@@ -160,8 +182,10 @@
 
     filter.determineFilterPrimitiveSubregion();
 
-    filter.allocateBackingStoreIfNeeded(destinationContext);
-    auto* sourceGraphicsContext = filter.inputContext();
+    if (hasUpdatedBackingStore)
+        allocateBackingStore(destinationContext);
+
+    auto* sourceGraphicsContext = inputContext();
     if (!sourceGraphicsContext || filter.filterRegion().isEmpty() || ImageBuffer::sizeNeedsClamping(filter.filterRegion().size()))
         return nullptr;
 
@@ -176,25 +200,18 @@
 
 void RenderLayerFilters::applyFilterEffect(GraphicsContext& destinationContext)
 {
-    ASSERT(m_filter->inputContext());
+    ASSERT(inputContext());
 
     LOG_WITH_STREAM(Filters, stream << "\nRenderLayerFilters " << this << " applyFilterEffect");
 
+    inputContext()->restore();
+
     auto& filter = *m_filter;
-    filter.inputContext()->restore();
 
-    filter.apply();
+    destinationContext.scale({ 1 / filter.filterScale().width(), 1 / filter.filterScale().height() });
+    destinationContext.drawFilteredImageBuffer(m_sourceImage.get(), filter);
+    destinationContext.scale(filter.filterScale());
 
-    // Get the filtered output and draw it in place.
-    LayoutRect destRect = filter.outputRect();
-    destRect.move(m_paintOffset.x(), m_paintOffset.y());
-
-    if (auto* outputBuffer = filter.output()) {
-        destinationContext.scale({ 1 / filter.filterScale().width(), 1 / filter.filterScale().height() });
-        destinationContext.drawImageBuffer(*outputBuffer, snapRectToDevicePixels(destRect, m_layer.renderer().document().deviceScaleFactor()));
-        destinationContext.scale(filter.filterScale());
-    }
-
     filter.clearIntermediateResults();
 
     LOG_WITH_STREAM(Filters, stream << "RenderLayerFilters " << this << " applyFilterEffect done\n");

Modified: trunk/Source/WebCore/rendering/RenderLayerFilters.h (286202 => 286203)


--- trunk/Source/WebCore/rendering/RenderLayerFilters.h	2021-11-29 05:11:26 UTC (rev 286202)
+++ trunk/Source/WebCore/rendering/RenderLayerFilters.h	2021-11-29 06:08:27 UTC (rev 286203)
@@ -69,6 +69,8 @@
 private:
     void notifyFinished(CachedResource&, const NetworkLoadMetrics&) final;
     void resetDirtySourceRect() { m_dirtySourceRect = LayoutRect(); }
+    GraphicsContext* inputContext();
+    void allocateBackingStore(const GraphicsContext& targetContext);
 
     RenderLayer& m_layer;
 
@@ -75,6 +77,7 @@
     Vector<RefPtr<Element>> m_internalSVGReferences;
     Vector<CachedResourceHandle<CachedSVGDocument>> m_externalSVGReferences;
 
+    RefPtr<ImageBuffer> m_sourceImage;
     RefPtr<CSSFilter> m_filter;
     LayoutRect m_dirtySourceRect;
     

Modified: trunk/Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp (286202 => 286203)


--- trunk/Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp	2021-11-29 05:11:26 UTC (rev 286202)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp	2021-11-29 06:08:27 UTC (rev 286203)
@@ -227,31 +227,13 @@
         break;
     }
 
-    auto lastEffect = filterData.filter->lastEffect();
-
-    if (lastEffect && !filterData.boundaries.isEmpty() && !lastEffect->filterPrimitiveSubregion().isEmpty()) {
-        // This is the real filtering of the object. It just needs to be called on the
-        // initial filtering process. We just take the stored filter result on a
-        // second drawing.
-        if (filterData.state != FilterData::Built)
-            filterData.filter->setSourceImage(WTFMove(filterData.sourceGraphicBuffer));
-
-        // Always true if filterData is just built (filterData->state == FilterData::Built).
-        if (!lastEffect->hasResult()) {
-            filterData.state = FilterData::Applying;
-            filterData.filter->apply();
-            lastEffect->correctPremultipliedResultIfNeeded();
-            lastEffect->transformResultColorSpace(DestinationColorSpace::SRGB());
-        }
+    if (!filterData.boundaries.isEmpty()) {
         filterData.state = FilterData::Built;
+        context->scale(FloatSize(1 / filterData.filter->filterScale().width(), 1 / filterData.filter->filterScale().height()));
+        context->drawFilteredImageBuffer(filterData.sourceGraphicBuffer.get(), *filterData.filter);
+        context->scale(filterData.scale);
+    }
 
-        if (auto result = lastEffect->filterImage()) {
-            auto resultImage = result->imageBuffer();
-            context->scale(FloatSize(1 / filterData.filter->filterScale().width(), 1 / filterData.filter->filterScale().height()));
-            context->drawImageBuffer(*resultImage, result->absoluteImageRect());
-            context->scale(filterData.filter->filterScale());
-        }
-    }
     filterData.sourceGraphicBuffer = nullptr;
 
     LOG_WITH_STREAM(Filters, stream << "RenderSVGResourceFilter " << this << " postApplyResource done\n");

Modified: trunk/Source/WebCore/svg/graphics/filters/SVGFilter.cpp (286202 => 286203)


--- trunk/Source/WebCore/svg/graphics/filters/SVGFilter.cpp	2021-11-29 05:11:26 UTC (rev 286202)
+++ trunk/Source/WebCore/svg/graphics/filters/SVGFilter.cpp	2021-11-29 06:08:27 UTC (rev 286203)
@@ -2,6 +2,7 @@
  * Copyright (C) 2009 Dirk Schulze <k...@webkit.org>
  * Copyright (C) Research In Motion Limited 2010. All rights reserved.
  * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2021 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
@@ -108,14 +109,14 @@
     return apply();
 }
 
-bool SVGFilter::apply()
+RefPtr<FilterImage> SVGFilter::apply()
 {
     ASSERT(!m_expression.isEmpty());
     for (auto& effect : m_expression) {
         if (!effect->apply(*this))
-            return false;
+            return nullptr;
     }
-    return true;
+    return lastEffect()->filterImage();
 }
 
 IntOutsets SVGFilter::outsets() const

Modified: trunk/Source/WebCore/svg/graphics/filters/SVGFilter.h (286202 => 286203)


--- trunk/Source/WebCore/svg/graphics/filters/SVGFilter.h	2021-11-29 05:11:26 UTC (rev 286202)
+++ trunk/Source/WebCore/svg/graphics/filters/SVGFilter.h	2021-11-29 06:08:27 UTC (rev 286203)
@@ -1,6 +1,7 @@
 /*
  * Copyright (C) 2009 Dirk Schulze <k...@webkit.org>
  * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2021 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
@@ -28,6 +29,7 @@
 
 namespace WebCore {
 
+class FilterImage;
 class SVGFilterBuilder;
 class SVGFilterElement;
 
@@ -37,14 +39,15 @@
     static RefPtr<SVGFilter> create(SVGFilterElement&, SVGFilterBuilder&, RenderingMode, const FloatSize& filterScale, const FloatRect& sourceImageRect, const FloatRect& filterRegion, const FloatRect& targetBoundingBox);
     static RefPtr<SVGFilter> create(SVGFilterElement&, SVGFilterBuilder&, RenderingMode, const FloatSize& filterScale, const FloatRect& sourceImageRect, const FloatRect& filterRegion, const FloatRect& targetBoundingBox, FilterEffect* previousEffect);
 
-    FloatSize scaledByFilterScale(FloatSize) const final;
-
     FloatRect targetBoundingBox() const { return m_targetBoundingBox; }
-    bool apply() override;
 
     void setExpression(FilterEffectVector&& _expression_) { m_expression = WTFMove(_expression_); }
     RefPtr<FilterEffect> lastEffect() const { return !m_expression.isEmpty() ? m_expression.last() : nullptr; }
 
+    FloatSize scaledByFilterScale(FloatSize) const final;
+
+    RefPtr<FilterImage> apply() override;
+
 private:
     SVGFilter(RenderingMode, const FloatSize& filterScale, const FloatRect& sourceImageRect, const FloatRect& targetBoundingBox, const FloatRect& filterRegion, bool effectBBoxMode);
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to