Title: [286753] trunk/Source
Revision
286753
Author
s...@apple.com
Date
2021-12-08 16:36:26 -0800 (Wed, 08 Dec 2021)

Log Message

[GPU Process] [Filters] Add the encoding and decoding for SVGFilter
https://bugs.webkit.org/show_bug.cgi?id=234024

Reviewed by Wenson Hsieh.

Source/WebCore:

Add new methods to help encoding and decoding SVGFilter members. Also
add a new constructor for SVGFilter which is going to be called from
FilterReference.

* Headers.cmake:
* WebCore.xcodeproj/project.pbxproj:
* platform/graphics/filters/FilterEffectGeometry.h:
(WebCore::FilterEffectGeometry::encode const):
(WebCore::FilterEffectGeometry::decode):

* platform/graphics/filters/SourceAlpha.cpp:
(WebCore::SourceAlpha::create):
(WebCore::SourceAlpha::SourceAlpha):
* platform/graphics/filters/SourceAlpha.h:
The plan is to remove the input effects from FilterEffect. Currently it
is still used but not through FilterEffect::apply(). So it is okay for
now for GPUProcess to create SourceAlpha without input since the input
will not used inside GPUProcess.

* svg/SVGUnitTypes.h:
* svg/graphics/filters/SVGFilter.cpp:
(WebCore::SVGFilter::create):
(WebCore::SVGFilter::SVGFilter):
* svg/graphics/filters/SVGFilter.h:

Source/WebKit:

When encoding the SVGFilter we need to encode the individual FilterEffects
in filter._expression_(). And for every SVGFilterExpressionTerm we need to
encode the index of its Ref<FilterEffect> in the individual FilterEffects.

When decoding the SVGFilter we do the opposite. We get the Ref<FilterEffect>
which corresponds to index of ExpressionReferenceTerm. We send the decoded
_expression_ to the constructor of SVGFilter.

* Platform/IPC/FilterReference.h:
(IPC::FilterReference::decodeFilterEffect):
(IPC::FilterReference::ExpressionReferenceTerm::encode const):
(IPC::FilterReference::ExpressionReferenceTerm::decode):
(IPC::FilterReference::encodeSVGFilter):
(IPC::FilterReference::decodeSVGFilter):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (286752 => 286753)


--- trunk/Source/WebCore/ChangeLog	2021-12-09 00:32:05 UTC (rev 286752)
+++ trunk/Source/WebCore/ChangeLog	2021-12-09 00:36:26 UTC (rev 286753)
@@ -1,3 +1,35 @@
+2021-12-08  Said Abou-Hallawa  <s...@apple.com>
+
+        [GPU Process] [Filters] Add the encoding and decoding for SVGFilter
+        https://bugs.webkit.org/show_bug.cgi?id=234024
+
+        Reviewed by Wenson Hsieh.
+
+        Add new methods to help encoding and decoding SVGFilter members. Also
+        add a new constructor for SVGFilter which is going to be called from
+        FilterReference.
+
+        * Headers.cmake:
+        * WebCore.xcodeproj/project.pbxproj:
+        * platform/graphics/filters/FilterEffectGeometry.h:
+        (WebCore::FilterEffectGeometry::encode const):
+        (WebCore::FilterEffectGeometry::decode):
+
+        * platform/graphics/filters/SourceAlpha.cpp:
+        (WebCore::SourceAlpha::create):
+        (WebCore::SourceAlpha::SourceAlpha):
+        * platform/graphics/filters/SourceAlpha.h:
+        The plan is to remove the input effects from FilterEffect. Currently it
+        is still used but not through FilterEffect::apply(). So it is okay for 
+        now for GPUProcess to create SourceAlpha without input since the input
+        will not used inside GPUProcess.
+
+        * svg/SVGUnitTypes.h:
+        * svg/graphics/filters/SVGFilter.cpp:
+        (WebCore::SVGFilter::create):
+        (WebCore::SVGFilter::SVGFilter):
+        * svg/graphics/filters/SVGFilter.h:
+
 2021-12-08  Don Olmstead  <don.olmst...@sony.com>
 
         [Win] Remove CF when using Windows clipboard

Modified: trunk/Source/WebCore/Headers.cmake (286752 => 286753)


--- trunk/Source/WebCore/Headers.cmake	2021-12-09 00:32:05 UTC (rev 286752)
+++ trunk/Source/WebCore/Headers.cmake	2021-12-09 00:36:26 UTC (rev 286753)
@@ -1597,6 +1597,7 @@
     platform/graphics/filters/FilterOperation.h
     platform/graphics/filters/FilterOperations.h
     platform/graphics/filters/LightSource.h
+    platform/graphics/filters/SourceAlpha.h
     platform/graphics/filters/SourceGraphic.h
 
     platform/graphics/iso/ISOBox.h

Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (286752 => 286753)


--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2021-12-09 00:32:05 UTC (rev 286752)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2021-12-09 00:36:26 UTC (rev 286753)
@@ -2756,7 +2756,7 @@
 		8485227C1190162C006EDC7F /* JSSVGHKernElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 848522781190162C006EDC7F /* JSSVGHKernElement.h */; };
 		8485227E1190162C006EDC7F /* JSSVGVKernElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 8485227A1190162C006EDC7F /* JSSVGVKernElement.h */; };
 		8485228B1190173C006EDC7F /* SVGVKernElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 848522881190173C006EDC7F /* SVGVKernElement.h */; };
-		84A81F3E0FC7DFF000955300 /* SourceAlpha.h in Headers */ = {isa = PBXBuildFile; fileRef = 84A81F3C0FC7DFF000955300 /* SourceAlpha.h */; };
+		84A81F3E0FC7DFF000955300 /* SourceAlpha.h in Headers */ = {isa = PBXBuildFile; fileRef = 84A81F3C0FC7DFF000955300 /* SourceAlpha.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		84A81F420FC7E02700955300 /* SourceGraphic.h in Headers */ = {isa = PBXBuildFile; fileRef = 84A81F400FC7E02700955300 /* SourceGraphic.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		84B349A222F86E7500D47BCF /* EventTargetConcrete.h in Headers */ = {isa = PBXBuildFile; fileRef = 84B349A022F86E7400D47BCF /* EventTargetConcrete.h */; };
 		84B6B978120F13E500B8EFAF /* SVGPathSegListSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 84B6B976120F13E500B8EFAF /* SVGPathSegListSource.h */; };

Modified: trunk/Source/WebCore/platform/graphics/filters/FilterEffectGeometry.h (286752 => 286753)


--- trunk/Source/WebCore/platform/graphics/filters/FilterEffectGeometry.h	2021-12-09 00:32:05 UTC (rev 286752)
+++ trunk/Source/WebCore/platform/graphics/filters/FilterEffectGeometry.h	2021-12-09 00:36:26 UTC (rev 286753)
@@ -78,6 +78,9 @@
         return std::nullopt;
     }
 
+    template<class Encoder> void encode(Encoder&) const;
+    template<class Decoder> static std::optional<FilterEffectGeometry> decode(Decoder&);
+
 private:
     FloatRect m_boundaries;
     OptionSet<Flags> m_flags;
@@ -85,4 +88,42 @@
 
 using FilterEffectGeometryMap = HashMap<Ref<FilterEffect>, FilterEffectGeometry>;
 
+template<class Encoder>
+void FilterEffectGeometry::encode(Encoder& encoder) const
+{
+    encoder << m_boundaries;
+    encoder << m_flags;
+}
+
+template<class Decoder>
+std::optional<FilterEffectGeometry> FilterEffectGeometry::decode(Decoder& decoder)
+{
+    std::optional<FloatRect> boundaries;
+    decoder >> boundaries;
+    if (!boundaries)
+        return std::nullopt;
+
+    std::optional<OptionSet<Flags>> flags;
+    decoder >> flags;
+    if (!flags)
+        return std::nullopt;
+
+    return FilterEffectGeometry(*boundaries, *flags);
+}
+
 } // namespace WebCore
+
+namespace WTF {
+
+template<> struct EnumTraits<WebCore::FilterEffectGeometry::Flags> {
+    using values = EnumValues<
+        WebCore::FilterEffectGeometry::Flags,
+
+        WebCore::FilterEffectGeometry::Flags::HasX,
+        WebCore::FilterEffectGeometry::Flags::HasY,
+        WebCore::FilterEffectGeometry::Flags::HasWidth,
+        WebCore::FilterEffectGeometry::Flags::HasHeight
+    >;
+};
+
+} // namespace WTF

Modified: trunk/Source/WebCore/platform/graphics/filters/SourceAlpha.cpp (286752 => 286753)


--- trunk/Source/WebCore/platform/graphics/filters/SourceAlpha.cpp	2021-12-09 00:32:05 UTC (rev 286752)
+++ trunk/Source/WebCore/platform/graphics/filters/SourceAlpha.cpp	2021-12-09 00:36:26 UTC (rev 286753)
@@ -21,17 +21,26 @@
 #include "config.h"
 #include "SourceAlpha.h"
 
-#include "Filter.h"
 #include "SourceAlphaSoftwareApplier.h"
 #include <wtf/text/TextStream.h>
 
 namespace WebCore {
 
+Ref<SourceAlpha> SourceAlpha::create()
+{
+    return adoptRef(*new SourceAlpha());
+}
+
 Ref<SourceAlpha> SourceAlpha::create(FilterEffect& sourceEffect)
 {
     return adoptRef(*new SourceAlpha(sourceEffect));
 }
 
+SourceAlpha::SourceAlpha()
+    : FilterEffect(FilterEffect::Type::SourceAlpha)
+{
+}
+
 SourceAlpha::SourceAlpha(FilterEffect& sourceEffect)
     : FilterEffect(FilterEffect::Type::SourceAlpha)
 {

Modified: trunk/Source/WebCore/platform/graphics/filters/SourceAlpha.h (286752 => 286753)


--- trunk/Source/WebCore/platform/graphics/filters/SourceAlpha.h	2021-12-09 00:32:05 UTC (rev 286752)
+++ trunk/Source/WebCore/platform/graphics/filters/SourceAlpha.h	2021-12-09 00:36:26 UTC (rev 286753)
@@ -25,12 +25,14 @@
 namespace WebCore {
 
 class SourceAlpha : public FilterEffect {
-public:        
+public:
+    WEBCORE_EXPORT static Ref<SourceAlpha> create();
     static Ref<SourceAlpha> create(FilterEffect&);
 
     static AtomString effectName() { return FilterEffect::sourceAlphaName(); }
 
 private:
+    SourceAlpha();
     explicit SourceAlpha(FilterEffect&);
 
     FloatRect calculateImageRect(const Filter&, const FilterImageVector& inputs, const FloatRect& primitiveSubregion) const override;

Modified: trunk/Source/WebCore/svg/SVGUnitTypes.h (286752 => 286753)


--- trunk/Source/WebCore/svg/SVGUnitTypes.h	2021-12-09 00:32:05 UTC (rev 286752)
+++ trunk/Source/WebCore/svg/SVGUnitTypes.h	2021-12-09 00:36:26 UTC (rev 286753)
@@ -66,3 +66,17 @@
 };
 
 } // namespace WebCore
+
+namespace WTF {
+
+template<> struct EnumTraits<WebCore::SVGUnitTypes::SVGUnitType> {
+    using values = EnumValues<
+        WebCore::SVGUnitTypes::SVGUnitType,
+
+        WebCore::SVGUnitTypes::SVG_UNIT_TYPE_UNKNOWN,
+        WebCore::SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE,
+        WebCore::SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX
+    >;
+};
+
+} // namespace WTF

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


--- trunk/Source/WebCore/svg/graphics/filters/SVGFilter.cpp	2021-12-09 00:32:05 UTC (rev 286752)
+++ trunk/Source/WebCore/svg/graphics/filters/SVGFilter.cpp	2021-12-09 00:36:26 UTC (rev 286753)
@@ -69,6 +69,11 @@
     return filter;
 }
 
+RefPtr<SVGFilter> SVGFilter::create(const FloatRect& targetBoundingBox, SVGUnitTypes::SVGUnitType primitiveUnits, SVGFilterExpression&& _expression_)
+{
+    return adoptRef(*new SVGFilter(targetBoundingBox, primitiveUnits, WTFMove(_expression_)));
+}
+
 SVGFilter::SVGFilter(RenderingMode renderingMode, const FloatSize& filterScale, ClipOperation clipOperation, const FloatRect& filterRegion, const FloatRect& targetBoundingBox, SVGUnitTypes::SVGUnitType primitiveUnits)
     : Filter(Filter::Type::SVGFilter, renderingMode, filterScale, clipOperation, filterRegion)
     , m_targetBoundingBox(targetBoundingBox)
@@ -76,6 +81,14 @@
 {
 }
 
+SVGFilter::SVGFilter(const FloatRect& targetBoundingBox, SVGUnitTypes::SVGUnitType primitiveUnits, SVGFilterExpression&& _expression_)
+    : Filter(Filter::Type::SVGFilter)
+    , m_targetBoundingBox(targetBoundingBox)
+    , m_primitiveUnits(primitiveUnits)
+    , m_expression(WTFMove(_expression_))
+{
+}
+
 FloatSize SVGFilter::resolvedSize(const FloatSize& size) const
 {
     return m_primitiveUnits == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX ? size * m_targetBoundingBox.size() : size;

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


--- trunk/Source/WebCore/svg/graphics/filters/SVGFilter.h	2021-12-09 00:32:05 UTC (rev 286752)
+++ trunk/Source/WebCore/svg/graphics/filters/SVGFilter.h	2021-12-09 00:36:26 UTC (rev 286753)
@@ -39,9 +39,13 @@
     static RefPtr<SVGFilter> create(SVGFilterElement&, SVGFilterBuilder&, RenderingMode, const FloatSize& filterScale, ClipOperation, const FloatRect& targetBoundingBox, FilterEffect& previousEffect);
     static RefPtr<SVGFilter> create(SVGFilterElement&, SVGFilterBuilder&, RenderingMode, const FloatSize& filterScale, const FloatRect& filterRegion, const FloatRect& targetBoundingBox);
     static RefPtr<SVGFilter> create(SVGFilterElement&, SVGFilterBuilder&, RenderingMode, const FloatSize& filterScale, ClipOperation, const FloatRect& filterRegion, const FloatRect& targetBoundingBox, FilterEffect* previousEffect);
+    WEBCORE_EXPORT static RefPtr<SVGFilter> create(const FloatRect& targetBoundingBox, SVGUnitTypes::SVGUnitType primitiveUnits, SVGFilterExpression&&);
 
     FloatRect targetBoundingBox() const { return m_targetBoundingBox; }
+    SVGUnitTypes::SVGUnitType primitiveUnits() const { return m_primitiveUnits; }
 
+    const SVGFilterExpression& _expression_() const { return m_expression; }
+    
     RefPtr<FilterEffect> lastEffect() const final;
 
     RefPtr<FilterImage> apply() final;
@@ -50,6 +54,7 @@
 
 private:
     SVGFilter(RenderingMode, const FloatSize& filterScale, ClipOperation, const FloatRect& filterRegion, const FloatRect& targetBoundingBox, SVGUnitTypes::SVGUnitType primitiveUnits);
+    SVGFilter(const FloatRect& targetBoundingBox, SVGUnitTypes::SVGUnitType primitiveUnits, SVGFilterExpression&&);
 
     void setExpression(SVGFilterExpression&& _expression_) { m_expression = WTFMove(_expression_); }
 

Modified: trunk/Source/WebKit/ChangeLog (286752 => 286753)


--- trunk/Source/WebKit/ChangeLog	2021-12-09 00:32:05 UTC (rev 286752)
+++ trunk/Source/WebKit/ChangeLog	2021-12-09 00:36:26 UTC (rev 286753)
@@ -1,3 +1,25 @@
+2021-12-08  Said Abou-Hallawa  <s...@apple.com>
+
+        [GPU Process] [Filters] Add the encoding and decoding for SVGFilter
+        https://bugs.webkit.org/show_bug.cgi?id=234024
+
+        Reviewed by Wenson Hsieh.
+
+        When encoding the SVGFilter we need to encode the individual FilterEffects
+        in filter._expression_(). And for every SVGFilterExpressionTerm we need to
+        encode the index of its Ref<FilterEffect> in the individual FilterEffects.
+
+        When decoding the SVGFilter we do the opposite. We get the Ref<FilterEffect>
+        which corresponds to index of ExpressionReferenceTerm. We send the decoded
+        _expression_ to the constructor of SVGFilter.
+
+        * Platform/IPC/FilterReference.h:
+        (IPC::FilterReference::decodeFilterEffect):
+        (IPC::FilterReference::ExpressionReferenceTerm::encode const):
+        (IPC::FilterReference::ExpressionReferenceTerm::decode):
+        (IPC::FilterReference::encodeSVGFilter):
+        (IPC::FilterReference::decodeSVGFilter):
+
 2021-12-08  Alex Christensen  <achristen...@webkit.org>
 
         Add SPI to load a resource in the context of a page

Modified: trunk/Source/WebKit/Platform/IPC/FilterReference.h (286752 => 286753)


--- trunk/Source/WebKit/Platform/IPC/FilterReference.h	2021-12-09 00:32:05 UTC (rev 286752)
+++ trunk/Source/WebKit/Platform/IPC/FilterReference.h	2021-12-09 00:36:26 UTC (rev 286753)
@@ -45,6 +45,7 @@
 #include <WebCore/Filter.h>
 #include <WebCore/FilterEffectVector.h>
 #include <WebCore/SVGFilter.h>
+#include <WebCore/SourceAlpha.h>
 #include <WebCore/SourceGraphic.h>
 
 namespace IPC {
@@ -62,8 +63,20 @@
     template<class Decoder> static std::optional<FilterReference> decode(Decoder&);
 
 private:
+    struct ExpressionReferenceTerm {
+        unsigned index;
+        std::optional<WebCore::FilterEffectGeometry> geometry;
+        unsigned level;
+    
+        template<class Encoder> void encode(Encoder&) const;
+        template<class Decoder> static std::optional<ExpressionReferenceTerm> decode(Decoder&);
+    };
+    
+    using ExpressionReference = Vector<ExpressionReferenceTerm>;
+
     template<class Encoder> static void encodeFilterEffect(const WebCore::FilterEffect&, Encoder&);
     template<class Decoder> static RefPtr<WebCore::FilterEffect> decodeFilterEffect(Decoder&, WebCore::FilterFunction::Type);
+    template<class Decoder> static RefPtr<WebCore::FilterEffect> decodeFilterEffect(Decoder&);
 
     template<class Encoder> static void encodeSVGFilter(const WebCore::SVGFilter&, Encoder&);
     template<class Decoder> static RefPtr<WebCore::SVGFilter> decodeSVGFilter(Decoder&);
@@ -243,11 +256,14 @@
         effect = WebCore::FETurbulence::decode(decoder);
         break;
 
+    case WebCore::FilterEffect::Type::SourceAlpha:
+        effect = WebCore::SourceAlpha::create();
+        break;
+
     case WebCore::FilterEffect::Type::SourceGraphic:
         effect = WebCore::SourceGraphic::create();
         break;
 
-    case WebCore::FilterEffect::Type::SourceAlpha:
     default:
         ASSERT_NOT_REACHED();
     }
@@ -260,17 +276,121 @@
     return nullptr;
 }
 
+template<class Decoder>
+RefPtr<WebCore::FilterEffect> FilterReference::decodeFilterEffect(Decoder& decoder)
+{
+    std::optional<WebCore::FilterFunction::Type> filterType;
+    decoder >> filterType;
+    if (!filterType)
+        return nullptr;
+
+    return decodeFilterEffect(decoder, *filterType);
+}
+
 template<class Encoder>
+void FilterReference::ExpressionReferenceTerm::encode(Encoder& encoder) const
+{
+    encoder << index;
+    encoder << geometry;
+    encoder << level;
+}
+
+template<class Decoder>
+std::optional<FilterReference::ExpressionReferenceTerm> FilterReference::ExpressionReferenceTerm::decode(Decoder& decoder)
+{
+    std::optional<unsigned> index;
+    decoder >> index;
+    if (!index)
+        return std::nullopt;
+
+    std::optional<std::optional<WebCore::FilterEffectGeometry>> geometry;
+    decoder >> geometry;
+    if (!geometry)
+        return std::nullopt;
+
+    std::optional<unsigned> level;
+    decoder >> level;
+    if (!level)
+        return std::nullopt;
+
+    return { { *index, *geometry, *level } };
+}
+
+template<class Encoder>
 void FilterReference::encodeSVGFilter(const WebCore::SVGFilter& filter, Encoder& encoder)
 {
-    // FIXME: Encode the SVGFilter.
+    HashMap<Ref<WebCore::FilterEffect>, unsigned> indicies;
+    Vector<Ref<WebCore::FilterEffect>> effects;
+
+    // Get the individual FilterEffects in filter._expression_().
+    for (auto& term : filter._expression_()) {
+        if (indicies.contains(term.effect))
+            continue;
+        indicies.add(term.effect, effects.size());
+        effects.append(term.effect);
+    }
+
+    // Replace the Ref<FilterEffect> in SVGExpressionTerm with its index in indicies.
+    auto expressionReference = WTF::map(filter._expression_(), [&indicies] (auto&& term) -> ExpressionReferenceTerm {
+        ASSERT(indicies.contains(term.effect));
+        unsigned index = indicies.get(term.effect);
+        return { index, term.geometry, term.level };
+    });
+
+    encoder << filter.targetBoundingBox();
+    encoder << filter.primitiveUnits();
+    
+    encoder << effects.size();
+    for (auto& effect : effects)
+        encodeFilterEffect(effect, encoder);
+
+    encoder << expressionReference;
 }
 
 template<class Decoder>
 RefPtr<WebCore::SVGFilter> FilterReference::decodeSVGFilter(Decoder& decoder)
 {
-    // FIXME: Decode the SVGFilter.
-    return nullptr;
+    std::optional<WebCore::FloatRect> targetBoundingBox;
+    decoder >> targetBoundingBox;
+    if (!targetBoundingBox)
+        return nullptr;
+
+    std::optional<WebCore::SVGUnitTypes::SVGUnitType> primitiveUnits;
+    decoder >> primitiveUnits;
+    if (!primitiveUnits)
+        return nullptr;
+
+    std::optional<size_t> effectsSize;
+    decoder >> effectsSize;
+    if (!effectsSize || !*effectsSize)
+        return nullptr;
+
+    Vector<Ref<WebCore::FilterEffect>> effects;
+
+    for (size_t i = 0; i < *effectsSize; ++i) {
+        auto effect = decodeFilterEffect(decoder);
+        if (!effect)
+            return nullptr;
+
+        effects.append(effect.releaseNonNull());
+    }
+
+    std::optional<ExpressionReference> expressionReference;
+    decoder >> expressionReference;
+    if (!expressionReference || expressionReference->isEmpty())
+        return nullptr;
+
+    WebCore::SVGFilterExpression _expression_;
+    _expression_.reserveInitialCapacity(expressionReference->size());
+
+    // Replace the index in ExpressionReferenceTerm with its Ref<FilterEffect> in effects.
+    for (auto& term : *expressionReference) {
+        if (term.index >= effects.size())
+            return nullptr;
+        _expression_.uncheckedAppend({ effects[term.index], term.geometry, term.level });
+    }
+    
+    return WebCore::SVGFilter::create(*targetBoundingBox, *primitiveUnits, WTFMove(_expression_));
 }
 
 template<class Encoder>
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to