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

Changeset 286753 in webkit


Ignore:
Timestamp:
Dec 8, 2021, 4:36:26 PM (5 years ago)
Author:
Said Abou-Hallawa
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):

Location:
trunk/Source
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r286752 r286753  
     12021-12-08  Said Abou-Hallawa  <said@apple.com>
     2
     3        [GPU Process] [Filters] Add the encoding and decoding for SVGFilter
     4        https://bugs.webkit.org/show_bug.cgi?id=234024
     5
     6        Reviewed by Wenson Hsieh.
     7
     8        Add new methods to help encoding and decoding SVGFilter members. Also
     9        add a new constructor for SVGFilter which is going to be called from
     10        FilterReference.
     11
     12        * Headers.cmake:
     13        * WebCore.xcodeproj/project.pbxproj:
     14        * platform/graphics/filters/FilterEffectGeometry.h:
     15        (WebCore::FilterEffectGeometry::encode const):
     16        (WebCore::FilterEffectGeometry::decode):
     17
     18        * platform/graphics/filters/SourceAlpha.cpp:
     19        (WebCore::SourceAlpha::create):
     20        (WebCore::SourceAlpha::SourceAlpha):
     21        * platform/graphics/filters/SourceAlpha.h:
     22        The plan is to remove the input effects from FilterEffect. Currently it
     23        is still used but not through FilterEffect::apply(). So it is okay for
     24        now for GPUProcess to create SourceAlpha without input since the input
     25        will not used inside GPUProcess.
     26
     27        * svg/SVGUnitTypes.h:
     28        * svg/graphics/filters/SVGFilter.cpp:
     29        (WebCore::SVGFilter::create):
     30        (WebCore::SVGFilter::SVGFilter):
     31        * svg/graphics/filters/SVGFilter.h:
     32
    1332021-12-08  Don Olmstead  <don.olmstead@sony.com>
    234
  • trunk/Source/WebCore/Headers.cmake

    r286709 r286753  
    15981598    platform/graphics/filters/FilterOperations.h
    15991599    platform/graphics/filters/LightSource.h
     1600    platform/graphics/filters/SourceAlpha.h
    16001601    platform/graphics/filters/SourceGraphic.h
    16011602
  • trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj

    r286709 r286753  
    27572757                8485227E1190162C006EDC7F /* JSSVGVKernElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 8485227A1190162C006EDC7F /* JSSVGVKernElement.h */; };
    27582758                8485228B1190173C006EDC7F /* SVGVKernElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 848522881190173C006EDC7F /* SVGVKernElement.h */; };
    2759                 84A81F3E0FC7DFF000955300 /* SourceAlpha.h in Headers */ = {isa = PBXBuildFile; fileRef = 84A81F3C0FC7DFF000955300 /* SourceAlpha.h */; };
     2759                84A81F3E0FC7DFF000955300 /* SourceAlpha.h in Headers */ = {isa = PBXBuildFile; fileRef = 84A81F3C0FC7DFF000955300 /* SourceAlpha.h */; settings = {ATTRIBUTES = (Private, ); }; };
    27602760                84A81F420FC7E02700955300 /* SourceGraphic.h in Headers */ = {isa = PBXBuildFile; fileRef = 84A81F400FC7E02700955300 /* SourceGraphic.h */; settings = {ATTRIBUTES = (Private, ); }; };
    27612761                84B349A222F86E7500D47BCF /* EventTargetConcrete.h in Headers */ = {isa = PBXBuildFile; fileRef = 84B349A022F86E7400D47BCF /* EventTargetConcrete.h */; };
  • trunk/Source/WebCore/platform/graphics/filters/FilterEffectGeometry.h

    r286466 r286753  
    7979    }
    8080
     81    template<class Encoder> void encode(Encoder&) const;
     82    template<class Decoder> static std::optional<FilterEffectGeometry> decode(Decoder&);
     83
    8184private:
    8285    FloatRect m_boundaries;
     
    8689using FilterEffectGeometryMap = HashMap<Ref<FilterEffect>, FilterEffectGeometry>;
    8790
     91template<class Encoder>
     92void FilterEffectGeometry::encode(Encoder& encoder) const
     93{
     94    encoder << m_boundaries;
     95    encoder << m_flags;
     96}
     97
     98template<class Decoder>
     99std::optional<FilterEffectGeometry> FilterEffectGeometry::decode(Decoder& decoder)
     100{
     101    std::optional<FloatRect> boundaries;
     102    decoder >> boundaries;
     103    if (!boundaries)
     104        return std::nullopt;
     105
     106    std::optional<OptionSet<Flags>> flags;
     107    decoder >> flags;
     108    if (!flags)
     109        return std::nullopt;
     110
     111    return FilterEffectGeometry(*boundaries, *flags);
     112}
     113
    88114} // namespace WebCore
     115
     116namespace WTF {
     117
     118template<> struct EnumTraits<WebCore::FilterEffectGeometry::Flags> {
     119    using values = EnumValues<
     120        WebCore::FilterEffectGeometry::Flags,
     121
     122        WebCore::FilterEffectGeometry::Flags::HasX,
     123        WebCore::FilterEffectGeometry::Flags::HasY,
     124        WebCore::FilterEffectGeometry::Flags::HasWidth,
     125        WebCore::FilterEffectGeometry::Flags::HasHeight
     126    >;
     127};
     128
     129} // namespace WTF
  • trunk/Source/WebCore/platform/graphics/filters/SourceAlpha.cpp

    r286589 r286753  
    2222#include "SourceAlpha.h"
    2323
    24 #include "Filter.h"
    2524#include "SourceAlphaSoftwareApplier.h"
    2625#include <wtf/text/TextStream.h>
     
    2827namespace WebCore {
    2928
     29Ref<SourceAlpha> SourceAlpha::create()
     30{
     31    return adoptRef(*new SourceAlpha());
     32}
     33
    3034Ref<SourceAlpha> SourceAlpha::create(FilterEffect& sourceEffect)
    3135{
    3236    return adoptRef(*new SourceAlpha(sourceEffect));
     37}
     38
     39SourceAlpha::SourceAlpha()
     40    : FilterEffect(FilterEffect::Type::SourceAlpha)
     41{
    3342}
    3443
  • trunk/Source/WebCore/platform/graphics/filters/SourceAlpha.h

    r286589 r286753  
    2626
    2727class SourceAlpha : public FilterEffect {
    28 public:       
     28public:
     29    WEBCORE_EXPORT static Ref<SourceAlpha> create();
    2930    static Ref<SourceAlpha> create(FilterEffect&);
    3031
     
    3233
    3334private:
     35    SourceAlpha();
    3436    explicit SourceAlpha(FilterEffect&);
    3537
  • trunk/Source/WebCore/svg/SVGUnitTypes.h

    r233122 r286753  
    6767
    6868} // namespace WebCore
     69
     70namespace WTF {
     71
     72template<> struct EnumTraits<WebCore::SVGUnitTypes::SVGUnitType> {
     73    using values = EnumValues<
     74        WebCore::SVGUnitTypes::SVGUnitType,
     75
     76        WebCore::SVGUnitTypes::SVG_UNIT_TYPE_UNKNOWN,
     77        WebCore::SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE,
     78        WebCore::SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX
     79    >;
     80};
     81
     82} // namespace WTF
  • trunk/Source/WebCore/svg/graphics/filters/SVGFilter.cpp

    r286589 r286753  
    7070}
    7171
     72RefPtr<SVGFilter> SVGFilter::create(const FloatRect& targetBoundingBox, SVGUnitTypes::SVGUnitType primitiveUnits, SVGFilterExpression&& expression)
     73{
     74    return adoptRef(*new SVGFilter(targetBoundingBox, primitiveUnits, WTFMove(expression)));
     75}
     76
    7277SVGFilter::SVGFilter(RenderingMode renderingMode, const FloatSize& filterScale, ClipOperation clipOperation, const FloatRect& filterRegion, const FloatRect& targetBoundingBox, SVGUnitTypes::SVGUnitType primitiveUnits)
    7378    : Filter(Filter::Type::SVGFilter, renderingMode, filterScale, clipOperation, filterRegion)
    7479    , m_targetBoundingBox(targetBoundingBox)
    7580    , m_primitiveUnits(primitiveUnits)
     81{
     82}
     83
     84SVGFilter::SVGFilter(const FloatRect& targetBoundingBox, SVGUnitTypes::SVGUnitType primitiveUnits, SVGFilterExpression&& expression)
     85    : Filter(Filter::Type::SVGFilter)
     86    , m_targetBoundingBox(targetBoundingBox)
     87    , m_primitiveUnits(primitiveUnits)
     88    , m_expression(WTFMove(expression))
    7689{
    7790}
  • trunk/Source/WebCore/svg/graphics/filters/SVGFilter.h

    r286589 r286753  
    4040    static RefPtr<SVGFilter> create(SVGFilterElement&, SVGFilterBuilder&, RenderingMode, const FloatSize& filterScale, const FloatRect& filterRegion, const FloatRect& targetBoundingBox);
    4141    static RefPtr<SVGFilter> create(SVGFilterElement&, SVGFilterBuilder&, RenderingMode, const FloatSize& filterScale, ClipOperation, const FloatRect& filterRegion, const FloatRect& targetBoundingBox, FilterEffect* previousEffect);
     42    WEBCORE_EXPORT static RefPtr<SVGFilter> create(const FloatRect& targetBoundingBox, SVGUnitTypes::SVGUnitType primitiveUnits, SVGFilterExpression&&);
    4243
    4344    FloatRect targetBoundingBox() const { return m_targetBoundingBox; }
     45    SVGUnitTypes::SVGUnitType primitiveUnits() const { return m_primitiveUnits; }
    4446
     47    const SVGFilterExpression& expression() const { return m_expression; }
     48   
    4549    RefPtr<FilterEffect> lastEffect() const final;
    4650
     
    5155private:
    5256    SVGFilter(RenderingMode, const FloatSize& filterScale, ClipOperation, const FloatRect& filterRegion, const FloatRect& targetBoundingBox, SVGUnitTypes::SVGUnitType primitiveUnits);
     57    SVGFilter(const FloatRect& targetBoundingBox, SVGUnitTypes::SVGUnitType primitiveUnits, SVGFilterExpression&&);
    5358
    5459    void setExpression(SVGFilterExpression&& expression) { m_expression = WTFMove(expression); }
  • trunk/Source/WebKit/ChangeLog

    r286751 r286753  
     12021-12-08  Said Abou-Hallawa  <said@apple.com>
     2
     3        [GPU Process] [Filters] Add the encoding and decoding for SVGFilter
     4        https://bugs.webkit.org/show_bug.cgi?id=234024
     5
     6        Reviewed by Wenson Hsieh.
     7
     8        When encoding the SVGFilter we need to encode the individual FilterEffects
     9        in filter.expression(). And for every SVGFilterExpressionTerm we need to
     10        encode the index of its Ref<FilterEffect> in the individual FilterEffects.
     11
     12        When decoding the SVGFilter we do the opposite. We get the Ref<FilterEffect>
     13        which corresponds to index of ExpressionReferenceTerm. We send the decoded
     14        expression to the constructor of SVGFilter.
     15
     16        * Platform/IPC/FilterReference.h:
     17        (IPC::FilterReference::decodeFilterEffect):
     18        (IPC::FilterReference::ExpressionReferenceTerm::encode const):
     19        (IPC::FilterReference::ExpressionReferenceTerm::decode):
     20        (IPC::FilterReference::encodeSVGFilter):
     21        (IPC::FilterReference::decodeSVGFilter):
     22
    1232021-12-08  Alex Christensen  <achristensen@webkit.org>
    224
  • trunk/Source/WebKit/Platform/IPC/FilterReference.h

    r286538 r286753  
    4646#include <WebCore/FilterEffectVector.h>
    4747#include <WebCore/SVGFilter.h>
     48#include <WebCore/SourceAlpha.h>
    4849#include <WebCore/SourceGraphic.h>
    4950
     
    6364
    6465private:
     66    struct ExpressionReferenceTerm {
     67        unsigned index;
     68        std::optional<WebCore::FilterEffectGeometry> geometry;
     69        unsigned level;
     70   
     71        template<class Encoder> void encode(Encoder&) const;
     72        template<class Decoder> static std::optional<ExpressionReferenceTerm> decode(Decoder&);
     73    };
     74   
     75    using ExpressionReference = Vector<ExpressionReferenceTerm>;
     76
    6577    template<class Encoder> static void encodeFilterEffect(const WebCore::FilterEffect&, Encoder&);
    6678    template<class Decoder> static RefPtr<WebCore::FilterEffect> decodeFilterEffect(Decoder&, WebCore::FilterFunction::Type);
     79    template<class Decoder> static RefPtr<WebCore::FilterEffect> decodeFilterEffect(Decoder&);
    6780
    6881    template<class Encoder> static void encodeSVGFilter(const WebCore::SVGFilter&, Encoder&);
     
    244257        break;
    245258
     259    case WebCore::FilterEffect::Type::SourceAlpha:
     260        effect = WebCore::SourceAlpha::create();
     261        break;
     262
    246263    case WebCore::FilterEffect::Type::SourceGraphic:
    247264        effect = WebCore::SourceGraphic::create();
    248265        break;
    249266
    250     case WebCore::FilterEffect::Type::SourceAlpha:
    251267    default:
    252268        ASSERT_NOT_REACHED();
     
    261277}
    262278
     279template<class Decoder>
     280RefPtr<WebCore::FilterEffect> FilterReference::decodeFilterEffect(Decoder& decoder)
     281{
     282    std::optional<WebCore::FilterFunction::Type> filterType;
     283    decoder >> filterType;
     284    if (!filterType)
     285        return nullptr;
     286
     287    return decodeFilterEffect(decoder, *filterType);
     288}
     289
     290template<class Encoder>
     291void FilterReference::ExpressionReferenceTerm::encode(Encoder& encoder) const
     292{
     293    encoder << index;
     294    encoder << geometry;
     295    encoder << level;
     296}
     297
     298template<class Decoder>
     299std::optional<FilterReference::ExpressionReferenceTerm> FilterReference::ExpressionReferenceTerm::decode(Decoder& decoder)
     300{
     301    std::optional<unsigned> index;
     302    decoder >> index;
     303    if (!index)
     304        return std::nullopt;
     305
     306    std::optional<std::optional<WebCore::FilterEffectGeometry>> geometry;
     307    decoder >> geometry;
     308    if (!geometry)
     309        return std::nullopt;
     310
     311    std::optional<unsigned> level;
     312    decoder >> level;
     313    if (!level)
     314        return std::nullopt;
     315
     316    return { { *index, *geometry, *level } };
     317}
     318
    263319template<class Encoder>
    264320void FilterReference::encodeSVGFilter(const WebCore::SVGFilter& filter, Encoder& encoder)
    265321{
    266     // FIXME: Encode the SVGFilter.
     322    HashMap<Ref<WebCore::FilterEffect>, unsigned> indicies;
     323    Vector<Ref<WebCore::FilterEffect>> effects;
     324
     325    // Get the individual FilterEffects in filter.expression().
     326    for (auto& term : filter.expression()) {
     327        if (indicies.contains(term.effect))
     328            continue;
     329        indicies.add(term.effect, effects.size());
     330        effects.append(term.effect);
     331    }
     332
     333    // Replace the Ref<FilterEffect> in SVGExpressionTerm with its index in indicies.
     334    auto expressionReference = WTF::map(filter.expression(), [&indicies] (auto&& term) -> ExpressionReferenceTerm {
     335        ASSERT(indicies.contains(term.effect));
     336        unsigned index = indicies.get(term.effect);
     337        return { index, term.geometry, term.level };
     338    });
     339
     340    encoder << filter.targetBoundingBox();
     341    encoder << filter.primitiveUnits();
     342   
     343    encoder << effects.size();
     344    for (auto& effect : effects)
     345        encodeFilterEffect(effect, encoder);
     346
     347    encoder << expressionReference;
    267348}
    268349
     
    270351RefPtr<WebCore::SVGFilter> FilterReference::decodeSVGFilter(Decoder& decoder)
    271352{
    272     // FIXME: Decode the SVGFilter.
    273     return nullptr;
     353    std::optional<WebCore::FloatRect> targetBoundingBox;
     354    decoder >> targetBoundingBox;
     355    if (!targetBoundingBox)
     356        return nullptr;
     357
     358    std::optional<WebCore::SVGUnitTypes::SVGUnitType> primitiveUnits;
     359    decoder >> primitiveUnits;
     360    if (!primitiveUnits)
     361        return nullptr;
     362
     363    std::optional<size_t> effectsSize;
     364    decoder >> effectsSize;
     365    if (!effectsSize || !*effectsSize)
     366        return nullptr;
     367
     368    Vector<Ref<WebCore::FilterEffect>> effects;
     369
     370    for (size_t i = 0; i < *effectsSize; ++i) {
     371        auto effect = decodeFilterEffect(decoder);
     372        if (!effect)
     373            return nullptr;
     374
     375        effects.append(effect.releaseNonNull());
     376    }
     377
     378    std::optional<ExpressionReference> expressionReference;
     379    decoder >> expressionReference;
     380    if (!expressionReference || expressionReference->isEmpty())
     381        return nullptr;
     382
     383    WebCore::SVGFilterExpression expression;
     384    expression.reserveInitialCapacity(expressionReference->size());
     385
     386    // Replace the index in ExpressionReferenceTerm with its Ref<FilterEffect> in effects.
     387    for (auto& term : *expressionReference) {
     388        if (term.index >= effects.size())
     389            return nullptr;
     390        expression.uncheckedAppend({ effects[term.index], term.geometry, term.level });
     391    }
     392   
     393    return WebCore::SVGFilter::create(*targetBoundingBox, *primitiveUnits, WTFMove(expression));
    274394}
    275395
Note: See TracChangeset for help on using the changeset viewer.