Title: [295498] trunk/Source/WebCore
Revision
295498
Author
[email protected]
Date
2022-06-13 12:52:35 -0700 (Mon, 13 Jun 2022)

Log Message

[GPU Process] [Filters] Simplify the dynamic update of the SVG filter elements
https://bugs.webkit.org/show_bug.cgi?id=232842
rdar://85426197

Reviewed by Simon Fraser.

Consider this SVG as an example:

<svg>
    <filter id="blur">
        <feGaussianBlur stdDeviation="5"/>
    </filter>
    <circle ... filter="url(#blur)"/>
    <rect ... filter="url(#blur)"/>
</svg>

The renderers of the <circle> and the <rect> elements ask the renderer of the
<filter> element, i.e. RenderSVGResourceFilter to applyResource(). In this
function a new SVGFilter is created for each target renderer. A new entry
{ target_renderer, FilterData } is added to
RenderSVGResourceFilter::m_rendererFilterDataMap.

While building the SVGFilter, a new FilterEffect is created for every target
renderer and an entry { primitive_renderer, effect } is added to
SVGFilterBuilder::m_effectRenderer.

Suppose 'stdDeviation' of <feGaussianBlur> has been changed, this is the
current workflow:

    SVGFEGaussianBlurElement::svgAttributeChanged() will call
    SVGFilterPrimitiveStandardAttributes::primitiveAttributeChanged() which
    will call RenderSVGResourceFilterPrimitive::primitiveAttributeChanged().
    The last one will call RenderSVGResourceFilter::primitiveAttributeChanged()
    and pass itself as an argument.

    RenderSVGResourceFilter::primitiveAttributeChanged() will loop through
    all the entries in m_rendererFilterDataMap and get the FilterData. And
    then it gets the effect given the key primitive renderer from
    FilterData::SVGFilterBuilder::m_effectRenderer. Having this effect, its
    setFilterEffectAttribute() will be called.

This workflow is cumbersome since it was mainly done this way because the result
FilterImage was stored with the FilterEffect. But since the  result FilterImage
was moved out of the FilterEffect, we do not need to create a new FilterEffect
for every target renderer. The same FilterEffect can be shared among all the
target renderers.

This is the new workflow for dynamically updating the FilterEffect attributes:

    No need to create a separate FilterEffect for every SVGFilter (or target
    renderer). A shared FilterEffect can be used instead. This will be
    SVGFilterPrimitiveStandardAttributes::m_effect.

    SVGFEGaussianBlurElement::svgAttributeChanged() will call
    SVGFilterPrimitiveStandardAttributes::primitiveAttributeChanged() which
    will call SVGFEGaussianBlurElement::setFilterEffectAttribute() if m_effect
    is not null. setFilterEffectAttribute() will return true if it needs to
    be repainted. RenderSVGResourceFilterPrimitive::markFilterEffectForRepaint()
    will be called then.

    RenderSVGResourceFilterPrimitive::markFilterForInvalidation() will call
    RenderSVGResourceFilter::markFilterForRepaint() if effect is not null which
    will clear the result FilterImage of this effect and all other FilterImages
    which takes the result FilterImage of this effect as an input.

    If svgAttributeChanged() finds out it needs to rebuild the entire SVGFilter,
    it will call SVGFilterPrimitiveStandardAttributes::markFilterEffectForRebuild()
    which will call RenderSVGResourceFilterPrimitive::markFilterEffectForRebuild()
    and sets SVGFilterPrimitiveStandardAttributes::m_effect to nullptr.
    RenderSVGResourceFilterPrimitive::markFilterEffectForRebuild() will call
    RenderSVGResourceFilter::markFilterForRebuild() which will clear
    RenderSVGResourceFilter::m_rendererFilterDataMap. This will force rebuilding
    the SVGFilter for all renderers.

* Source/WebCore/platform/graphics/filters/FEDropShadow.cpp:
(WebCore::FEDropShadow::setStdDeviationX):
(WebCore::FEDropShadow::setStdDeviationY):
(WebCore::FEDropShadow::setDx):
(WebCore::FEDropShadow::setDy):
(WebCore::FEDropShadow::setShadowColor):
(WebCore::FEDropShadow::setShadowOpacity):
* Source/WebCore/platform/graphics/filters/FEDropShadow.h:
(WebCore::FEDropShadow::setStdDeviationX): Deleted.
(WebCore::FEDropShadow::setStdDeviationY): Deleted.
(WebCore::FEDropShadow::setDx): Deleted.
(WebCore::FEDropShadow::setDy): Deleted.
(WebCore::FEDropShadow::setShadowColor): Deleted.
(WebCore::FEDropShadow::setShadowOpacity): Deleted.
* Source/WebCore/platform/graphics/filters/FEGaussianBlur.cpp:
(WebCore::FEGaussianBlur::setStdDeviationX):
(WebCore::FEGaussianBlur::setStdDeviationY):
(WebCore::FEGaussianBlur::setEdgeMode):
* Source/WebCore/platform/graphics/filters/FEGaussianBlur.h:
* Source/WebCore/platform/graphics/filters/FEOffset.cpp:
(WebCore::FEOffset::setDx):
(WebCore::FEOffset::setDy):
* Source/WebCore/platform/graphics/filters/FEOffset.h:
* Source/WebCore/rendering/CSSFilter.cpp:
(WebCore::createReferenceFilter):
* Source/WebCore/rendering/svg/RenderSVGResourceContainer.h:
* Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp:
(WebCore::RenderSVGResourceFilter::applyResource):
(WebCore::RenderSVGResourceFilter::markFilterForRepaint):
(WebCore::RenderSVGResourceFilter::markFilterForRebuild):
(WebCore::RenderSVGResourceFilter::primitiveAttributeChanged): Deleted.
* Source/WebCore/rendering/svg/RenderSVGResourceFilter.h:
* Source/WebCore/rendering/svg/RenderSVGResourceFilterPrimitive.cpp:
(WebCore::RenderSVGResourceFilterPrimitive::styleDidChange):
(WebCore::RenderSVGResourceFilterPrimitive::markFilterEffectForRepaint):
(WebCore::RenderSVGResourceFilterPrimitive::markFilterEffectForRebuild):
* Source/WebCore/rendering/svg/RenderSVGResourceFilterPrimitive.h:
* Source/WebCore/rendering/svg/SVGRenderTreeAsText.cpp:
(WebCore::writeSVGResourceContainer):
* Source/WebCore/svg/SVGFEBlendElement.cpp:
(WebCore::SVGFEBlendElement::setFilterEffectAttribute):
(WebCore::SVGFEBlendElement::createFilterEffect const):
(WebCore::SVGFEBlendElement::filterEffect const): Deleted.
* Source/WebCore/svg/SVGFEBlendElement.h:
* Source/WebCore/svg/SVGFEColorMatrixElement.cpp:
(WebCore::SVGFEColorMatrixElement::isInvalidValuesLength const):
(WebCore::SVGFEColorMatrixElement::setFilterEffectAttribute):
(WebCore::SVGFEColorMatrixElement::svgAttributeChanged):
(WebCore::SVGFEColorMatrixElement::createFilterEffect const):
(WebCore::SVGFEColorMatrixElement::filterEffect const): Deleted.
* Source/WebCore/svg/SVGFEColorMatrixElement.h:
* Source/WebCore/svg/SVGFEComponentTransferElement.cpp:
(WebCore::SVGFEComponentTransferElement::svgAttributeChanged):
(WebCore::SVGFEComponentTransferElement::createFilterEffect const):
(WebCore::SVGFEComponentTransferElement::filterEffect const): Deleted.
* Source/WebCore/svg/SVGFEComponentTransferElement.h:
* Source/WebCore/svg/SVGFECompositeElement.cpp:
(WebCore::SVGFECompositeElement::setFilterEffectAttribute):
(WebCore::SVGFECompositeElement::svgAttributeChanged):
(WebCore::SVGFECompositeElement::createFilterEffect const):
(WebCore::SVGFECompositeElement::filterEffect const): Deleted.
* Source/WebCore/svg/SVGFECompositeElement.h:
* Source/WebCore/svg/SVGFEConvolveMatrixElement.cpp:
(WebCore::SVGFEConvolveMatrixElement::setFilterEffectAttribute):
(WebCore::SVGFEConvolveMatrixElement::svgAttributeChanged):
(WebCore::SVGFEConvolveMatrixElement::createFilterEffect const):
(WebCore::SVGFEConvolveMatrixElement::filterEffect const): Deleted.
* Source/WebCore/svg/SVGFEConvolveMatrixElement.h:
* Source/WebCore/svg/SVGFEDiffuseLightingElement.cpp:
(WebCore::SVGFEDiffuseLightingElement::setFilterEffectAttribute):
(WebCore::SVGFEDiffuseLightingElement::svgAttributeChanged):
(WebCore::SVGFEDiffuseLightingElement::createFilterEffect const):
(WebCore::SVGFEDiffuseLightingElement::filterEffect const): Deleted.
* Source/WebCore/svg/SVGFEDiffuseLightingElement.h:
* Source/WebCore/svg/SVGFEDisplacementMapElement.cpp:
(WebCore::SVGFEDisplacementMapElement::setFilterEffectAttribute):
(WebCore::SVGFEDisplacementMapElement::svgAttributeChanged):
(WebCore::SVGFEDisplacementMapElement::createFilterEffect const):
(WebCore::SVGFEDisplacementMapElement::filterEffect const): Deleted.
* Source/WebCore/svg/SVGFEDisplacementMapElement.h:
* Source/WebCore/svg/SVGFEDropShadowElement.cpp:
(WebCore::SVGFEDropShadowElement::svgAttributeChanged):
(WebCore::SVGFEDropShadowElement::setFilterEffectAttribute):
(WebCore::SVGFEDropShadowElement::createFilterEffect const):
(WebCore::SVGFEDropShadowElement::filterEffect const): Deleted.
* Source/WebCore/svg/SVGFEDropShadowElement.h:
* Source/WebCore/svg/SVGFEFloodElement.cpp:
(WebCore::SVGFEFloodElement::setFilterEffectAttribute):
(WebCore::SVGFEFloodElement::createFilterEffect const):
(WebCore::SVGFEFloodElement::filterEffect const): Deleted.
* Source/WebCore/svg/SVGFEFloodElement.h:
* Source/WebCore/svg/SVGFEGaussianBlurElement.cpp:
(WebCore::SVGFEGaussianBlurElement::svgAttributeChanged):
(WebCore::SVGFEGaussianBlurElement::setFilterEffectAttribute):
(WebCore::SVGFEGaussianBlurElement::createFilterEffect const):
(WebCore::SVGFEGaussianBlurElement::filterEffect const): Deleted.
* Source/WebCore/svg/SVGFEGaussianBlurElement.h:
* Source/WebCore/svg/SVGFEImageElement.cpp:
(WebCore::SVGFEImageElement::svgAttributeChanged):
(WebCore::SVGFEImageElement::createFilterEffect const):
(WebCore::SVGFEImageElement::filterEffect const): Deleted.
* Source/WebCore/svg/SVGFEImageElement.h:
* Source/WebCore/svg/SVGFEMergeElement.cpp:
(WebCore::SVGFEMergeElement::childrenChanged):
(WebCore::SVGFEMergeElement::createFilterEffect const):
(WebCore::SVGFEMergeElement::filterEffect const): Deleted.
* Source/WebCore/svg/SVGFEMergeElement.h:
* Source/WebCore/svg/SVGFEMorphologyElement.cpp:
(WebCore::SVGFEMorphologyElement::setFilterEffectAttribute):
(WebCore::SVGFEMorphologyElement::svgAttributeChanged):
(WebCore::SVGFEMorphologyElement::createFilterEffect const):
(WebCore::SVGFEMorphologyElement::filterEffect const): Deleted.
* Source/WebCore/svg/SVGFEMorphologyElement.h:
* Source/WebCore/svg/SVGFEOffsetElement.cpp:
(WebCore::SVGFEOffsetElement::svgAttributeChanged):
(WebCore::SVGFEOffsetElement::setFilterEffectAttribute):
(WebCore::SVGFEOffsetElement::createFilterEffect const):
(WebCore::SVGFEOffsetElement::filterEffect const): Deleted.
* Source/WebCore/svg/SVGFEOffsetElement.h:
* Source/WebCore/svg/SVGFESpecularLightingElement.cpp:
(WebCore::SVGFESpecularLightingElement::setFilterEffectAttribute):
(WebCore::SVGFESpecularLightingElement::createFilterEffect const):
(WebCore::SVGFESpecularLightingElement::filterEffect const): Deleted.
* Source/WebCore/svg/SVGFESpecularLightingElement.h:
* Source/WebCore/svg/SVGFETileElement.cpp:
(WebCore::SVGFETileElement::createFilterEffect const):
(WebCore::SVGFETileElement::filterEffect const): Deleted.
* Source/WebCore/svg/SVGFETileElement.h:
* Source/WebCore/svg/SVGFETurbulenceElement.cpp:
(WebCore::SVGFETurbulenceElement::setFilterEffectAttribute):
(WebCore::SVGFETurbulenceElement::createFilterEffect const):
(WebCore::SVGFETurbulenceElement::filterEffect const): Deleted.
* Source/WebCore/svg/SVGFETurbulenceElement.h:
* Source/WebCore/svg/SVGFilterPrimitiveStandardAttributes.cpp:
(WebCore::SVGFilterPrimitiveStandardAttributes::filterEffect):
(WebCore::SVGFilterPrimitiveStandardAttributes::primitiveAttributeChanged):
(WebCore::SVGFilterPrimitiveStandardAttributes::markFilterEffectForRebuild):
(WebCore::SVGFilterPrimitiveStandardAttributes::setFilterEffectAttribute): Deleted.
* Source/WebCore/svg/SVGFilterPrimitiveStandardAttributes.h:
(WebCore::SVGFilterPrimitiveStandardAttributes::setFilterEffectAttribute):
(WebCore::SVGFilterPrimitiveStandardAttributes::primitiveAttributeChanged): Deleted.
* Source/WebCore/svg/graphics/filters/SVGFilter.cpp:
(WebCore::SVGFilter::create):
* Source/WebCore/svg/graphics/filters/SVGFilter.h:
* Source/WebCore/svg/graphics/filters/SVGFilterBuilder.cpp:
(WebCore::SVGFilterBuilder::buildFilterExpression):
* Source/WebCore/svg/graphics/filters/SVGFilterBuilder.h:
(WebCore::SVGFilterBuilder::effectByRenderer): Deleted.

Canonical link: https://commits.webkit.org/251503@main

Modified Paths

Diff

Modified: trunk/Source/WebCore/platform/graphics/filters/FEDropShadow.cpp (295497 => 295498)


--- trunk/Source/WebCore/platform/graphics/filters/FEDropShadow.cpp	2022-06-13 19:23:41 UTC (rev 295497)
+++ trunk/Source/WebCore/platform/graphics/filters/FEDropShadow.cpp	2022-06-13 19:52:35 UTC (rev 295498)
@@ -45,6 +45,54 @@
 {
 }
 
+bool FEDropShadow::setStdDeviationX(float stdX)
+{
+    if (m_stdX == stdX)
+        return false;
+    m_stdX = stdX;
+    return true;
+}
+
+bool FEDropShadow::setStdDeviationY(float stdY)
+{
+    if (m_stdY == stdY)
+        return false;
+    m_stdY = stdY;
+    return true;
+}
+
+bool FEDropShadow::setDx(float dx)
+{
+    if (m_dx == dx)
+        return false;
+    m_dx = dx;
+    return true;
+}
+
+bool FEDropShadow::setDy(float dy)
+{
+    if (m_dy == dy)
+        return false;
+    m_dy = dy;
+    return true;
+}
+
+bool FEDropShadow::setShadowColor(const Color& shadowColor)
+{
+    if (m_shadowColor == shadowColor)
+        return false;
+    m_shadowColor = shadowColor;
+    return true;
+}
+
+bool FEDropShadow::setShadowOpacity(float shadowOpacity)
+{
+    if (m_shadowOpacity == shadowOpacity)
+        return false;
+    m_shadowOpacity = shadowOpacity;
+    return true;
+}
+
 FloatRect FEDropShadow::calculateImageRect(const Filter& filter, const FilterImageVector& inputs, const FloatRect& primitiveSubregion) const
 {
     auto imageRect = inputs[0]->imageRect();

Modified: trunk/Source/WebCore/platform/graphics/filters/FEDropShadow.h (295497 => 295498)


--- trunk/Source/WebCore/platform/graphics/filters/FEDropShadow.h	2022-06-13 19:23:41 UTC (rev 295497)
+++ trunk/Source/WebCore/platform/graphics/filters/FEDropShadow.h	2022-06-13 19:52:35 UTC (rev 295498)
@@ -30,22 +30,22 @@
     WEBCORE_EXPORT static Ref<FEDropShadow> create(float stdX, float stdY, float dx, float dy, const Color& shadowColor, float shadowOpacity);
 
     float stdDeviationX() const { return m_stdX; }
-    void setStdDeviationX(float stdX) { m_stdX = stdX; }
+    bool setStdDeviationX(float);
 
     float stdDeviationY() const { return m_stdY; }
-    void setStdDeviationY(float stdY) { m_stdY = stdY; }
+    bool setStdDeviationY(float);
 
     float dx() const { return m_dx; }
-    void setDx(float dx) { m_dx = dx; }
+    bool setDx(float);
 
     float dy() const { return m_dy; }
-    void setDy(float dy) { m_dy = dy; }
+    bool setDy(float);
 
     const Color& shadowColor() const { return m_shadowColor; } 
-    void setShadowColor(const Color& shadowColor) { m_shadowColor = shadowColor; }
+    bool setShadowColor(const Color&);
 
     float shadowOpacity() const { return m_shadowOpacity; }
-    void setShadowOpacity(float shadowOpacity) { m_shadowOpacity = shadowOpacity; }
+    bool setShadowOpacity(float);
 
     static IntOutsets calculateOutsets(const FloatSize& offset, const FloatSize& stdDeviation);
 

Modified: trunk/Source/WebCore/platform/graphics/filters/FEGaussianBlur.cpp (295497 => 295498)


--- trunk/Source/WebCore/platform/graphics/filters/FEGaussianBlur.cpp	2022-06-13 19:23:41 UTC (rev 295497)
+++ trunk/Source/WebCore/platform/graphics/filters/FEGaussianBlur.cpp	2022-06-13 19:52:35 UTC (rev 295498)
@@ -45,19 +45,28 @@
 {
 }
 
-void FEGaussianBlur::setStdDeviationX(float x)
+bool FEGaussianBlur::setStdDeviationX(float stdX)
 {
-    m_stdX = x;
+    if (m_stdX == stdX)
+        return false;
+    m_stdX = stdX;
+    return true;
 }
 
-void FEGaussianBlur::setStdDeviationY(float y)
+bool FEGaussianBlur::setStdDeviationY(float stdY)
 {
-    m_stdY = y;
+    if (m_stdY == stdY)
+        return false;
+    m_stdY = stdY;
+    return true;
 }
 
-void FEGaussianBlur::setEdgeMode(EdgeModeType edgeMode)
+bool FEGaussianBlur::setEdgeMode(EdgeModeType edgeMode)
 {
+    if (m_edgeMode == edgeMode)
+        return false;
     m_edgeMode = edgeMode;
+    return true;
 }
 
 static inline float gaussianKernelFactor()

Modified: trunk/Source/WebCore/platform/graphics/filters/FEGaussianBlur.h (295497 => 295498)


--- trunk/Source/WebCore/platform/graphics/filters/FEGaussianBlur.h	2022-06-13 19:23:41 UTC (rev 295497)
+++ trunk/Source/WebCore/platform/graphics/filters/FEGaussianBlur.h	2022-06-13 19:52:35 UTC (rev 295498)
@@ -32,13 +32,13 @@
     WEBCORE_EXPORT static Ref<FEGaussianBlur> create(float x, float y, EdgeModeType);
 
     float stdDeviationX() const { return m_stdX; }
-    void setStdDeviationX(float);
+    bool setStdDeviationX(float);
 
     float stdDeviationY() const { return m_stdY; }
-    void setStdDeviationY(float);
+    bool setStdDeviationY(float);
 
     EdgeModeType edgeMode() const { return m_edgeMode; }
-    void setEdgeMode(EdgeModeType);
+    bool setEdgeMode(EdgeModeType);
 
     static IntSize calculateKernelSize(const Filter&, FloatSize stdDeviation);
     static IntSize calculateUnscaledKernelSize(FloatSize stdDeviation);

Modified: trunk/Source/WebCore/platform/graphics/filters/FEOffset.cpp (295497 => 295498)


--- trunk/Source/WebCore/platform/graphics/filters/FEOffset.cpp	2022-06-13 19:23:41 UTC (rev 295497)
+++ trunk/Source/WebCore/platform/graphics/filters/FEOffset.cpp	2022-06-13 19:52:35 UTC (rev 295498)
@@ -43,14 +43,20 @@
 {
 }
 
-void FEOffset::setDx(float dx)
+bool FEOffset::setDx(float dx)
 {
+    if (m_dx == dx)
+        return false;
     m_dx = dx;
+    return true;
 }
 
-void FEOffset::setDy(float dy)
+bool FEOffset::setDy(float dy)
 {
+    if (m_dy == dy)
+        return false;
     m_dy = dy;
+    return true;
 }
 
 FloatRect FEOffset::calculateImageRect(const Filter& filter, const FilterImageVector& inputs, const FloatRect& primitiveSubregion) const

Modified: trunk/Source/WebCore/platform/graphics/filters/FEOffset.h (295497 => 295498)


--- trunk/Source/WebCore/platform/graphics/filters/FEOffset.h	2022-06-13 19:23:41 UTC (rev 295497)
+++ trunk/Source/WebCore/platform/graphics/filters/FEOffset.h	2022-06-13 19:52:35 UTC (rev 295498)
@@ -31,10 +31,10 @@
     WEBCORE_EXPORT static Ref<FEOffset> create(float dx, float dy);
 
     float dx() const { return m_dx; }
-    void setDx(float);
+    bool setDx(float);
 
     float dy() const { return m_dy; }
-    void setDy(float);
+    bool setDy(float);
 
     static IntOutsets calculateOutsets(const FloatSize& offset);
 

Modified: trunk/Source/WebCore/rendering/CSSFilter.cpp (295497 => 295498)


--- trunk/Source/WebCore/rendering/CSSFilter.cpp	2022-06-13 19:23:41 UTC (rev 295497)
+++ trunk/Source/WebCore/rendering/CSSFilter.cpp	2022-06-13 19:52:35 UTC (rev 295498)
@@ -264,8 +264,7 @@
 
     auto filterRegion = SVGLengthContext::resolveRectangle<SVGFilterElement>(filterElement, filterElement->filterUnits(), targetBoundingBox);
 
-    SVGFilterBuilder builder;
-    return SVGFilter::create(*filterElement, builder, filter.renderingMode(), filter.filterScale(), filter.clipOperation(), filterRegion, targetBoundingBox, destinationContext);
+    return SVGFilter::create(*filterElement, filter.renderingMode(), filter.filterScale(), filter.clipOperation(), filterRegion, targetBoundingBox, destinationContext);
 }
 
 bool CSSFilter::buildFilterFunctions(RenderElement& renderer, const FilterOperations& operations, const FloatRect& targetBoundingBox, const GraphicsContext& destinationContext)

Modified: trunk/Source/WebCore/rendering/svg/RenderSVGResourceContainer.h (295497 => 295498)


--- trunk/Source/WebCore/rendering/svg/RenderSVGResourceContainer.h	2022-06-13 19:23:41 UTC (rev 295497)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGResourceContainer.h	2022-06-13 19:52:35 UTC (rev 295498)
@@ -45,6 +45,7 @@
     void markAllClientsForRepaint();
     void addClientRenderLayer(RenderLayer*);
     void removeClientRenderLayer(RenderLayer*);
+    void markAllClientLayersForInvalidation();
 
 protected:
     RenderSVGResourceContainer(SVGElement&, RenderStyle&&);
@@ -60,7 +61,6 @@
     virtual bool selfNeedsClientInvalidation() const { return everHadLayout() && selfNeedsLayout(); }
 
     void markAllClientsForInvalidation(InvalidationMode);
-    void markAllClientLayersForInvalidation();
     void markClientForInvalidation(RenderObject&, InvalidationMode);
 
 private:

Modified: trunk/Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp (295497 => 295498)


--- trunk/Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp	2022-06-13 19:23:41 UTC (rev 295497)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp	2022-06-13 19:52:35 UTC (rev 295498)
@@ -25,24 +25,14 @@
 #include "config.h"
 #include "RenderSVGResourceFilter.h"
 
-#include "ElementChildIterator.h"
 #include "FilterEffect.h"
 #include "FloatPoint.h"
-#include "Frame.h"
 #include "GraphicsContext.h"
-#include "Image.h"
-#include "ImageData.h"
 #include "IntRect.h"
 #include "Logging.h"
 #include "RenderSVGResourceFilterInlines.h"
-#include "RenderSVGResourceFilterPrimitive.h"
-#include "RenderView.h"
 #include "SVGElementTypeHelpers.h"
-#include "SVGFilterPrimitiveStandardAttributes.h"
-#include "SVGNames.h"
 #include "SVGRenderingContext.h"
-#include "Settings.h"
-#include "SourceGraphic.h"
 #include <wtf/IsoMallocInlines.h>
 #include <wtf/text/TextStream.h>
 
@@ -129,8 +119,7 @@
     auto renderingMode = renderer.page().acceleratedFiltersEnabled() ? RenderingMode::Accelerated : RenderingMode::Unaccelerated;
 
     // Create the SVGFilter object.
-    filterData->builder = makeUnique<SVGFilterBuilder>();
-    filterData->filter = SVGFilter::create(filterElement(), *filterData->builder, renderingMode, filterScale, Filter::ClipOperation::Intersect, filterData->boundaries, targetBoundingBox, *context);
+    filterData->filter = SVGFilter::create(filterElement(), renderingMode, filterScale, Filter::ClipOperation::Intersect, filterData->boundaries, targetBoundingBox, *context);
     if (!filterData->filter) {
         m_rendererFilterDataMap.remove(&renderer);
         return false;
@@ -225,33 +214,29 @@
     return SVGLengthContext::resolveRectangle<SVGFilterElement>(&filterElement(), filterElement().filterUnits(), object.objectBoundingBox());
 }
 
-void RenderSVGResourceFilter::primitiveAttributeChanged(RenderObject* object, const QualifiedName& attribute)
+void RenderSVGResourceFilter::markFilterForRepaint(FilterEffect& effect)
 {
-    SVGFilterPrimitiveStandardAttributes* primitve = static_cast<SVGFilterPrimitiveStandardAttributes*>(object->node());
+    LOG(Filters, "RenderSVGResourceFilter %p markFilterForRepaint effect %p", this, &effect);
 
-    LOG(Filters, "RenderSVGResourceFilter %p primitiveAttributeChanged renderer %p", this, object);
-
     for (const auto& objectFilterDataPair : m_rendererFilterDataMap) {
         const auto& filterData = objectFilterDataPair.value;
         if (filterData->state != FilterData::Built)
             continue;
 
-        SVGFilterBuilder* builder = filterData->builder.get();
-        FilterEffect* effect = builder->effectByRenderer(object);
-        if (!effect)
-            continue;
-        // Since all effects shares the same attribute value, all
-        // or none of them will be changed.
-        if (!primitve->setFilterEffectAttribute(effect, attribute))
-            return;
-        filterData->results.clearEffectResult(*effect);
-
         // Repaint the image on the screen.
         markClientForInvalidation(*objectFilterDataPair.key, RepaintInvalidation);
+
+        filterData->results.clearEffectResult(effect);
     }
-    markAllClientLayersForInvalidation();
 }
 
+void RenderSVGResourceFilter::markFilterForRebuild()
+{
+    LOG(Filters, "RenderSVGResourceFilter %p markFilterForRebuild", this);
+
+    removeAllClientsFromCache();
+}
+
 FloatRect RenderSVGResourceFilter::drawingRegion(RenderObject* object) const
 {
     FilterData* filterData = m_rendererFilterDataMap.get(object);

Modified: trunk/Source/WebCore/rendering/svg/RenderSVGResourceFilter.h (295497 => 295498)


--- trunk/Source/WebCore/rendering/svg/RenderSVGResourceFilter.h	2022-06-13 19:23:41 UTC (rev 295497)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGResourceFilter.h	2022-06-13 19:52:35 UTC (rev 295498)
@@ -45,7 +45,6 @@
     FilterData() = default;
 
     RefPtr<SVGFilter> filter;
-    std::unique_ptr<SVGFilterBuilder> builder;
     RefPtr<ImageBuffer> sourceGraphicBuffer;
     GraphicsContext* savedContext { nullptr };
     FloatRect boundaries;
@@ -73,12 +72,11 @@
 
     FloatRect resourceBoundingBox(const RenderObject&) override;
 
-    std::unique_ptr<SVGFilterBuilder> buildPrimitives(SVGFilter&) const;
-
     inline SVGUnitTypes::SVGUnitType filterUnits() const;
     inline SVGUnitTypes::SVGUnitType primitiveUnits() const;
 
-    void primitiveAttributeChanged(RenderObject*, const QualifiedName&);
+    void markFilterForRepaint(FilterEffect&);
+    void markFilterForRebuild();
 
     RenderSVGResourceType resourceType() const override { return FilterResourceType; }
 

Modified: trunk/Source/WebCore/rendering/svg/RenderSVGResourceFilterPrimitive.cpp (295497 => 295498)


--- trunk/Source/WebCore/rendering/svg/RenderSVGResourceFilterPrimitive.cpp	2022-06-13 19:23:41 UTC (rev 295497)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGResourceFilterPrimitive.cpp	2022-06-13 19:52:35 UTC (rev 295498)
@@ -2,6 +2,7 @@
  * Copyright (C) 2010 University of Szeged
  * Copyright (C) 2010 Zoltan Herczeg
  * Copyright (C) 2011 Renata Hodovan ([email protected])
+ * 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
@@ -30,6 +31,7 @@
 
 #include "SVGElementTypeHelpers.h"
 #include "SVGFEDiffuseLightingElement.h"
+#include "SVGFEDropShadowElement.h"
 #include "SVGFEFloodElement.h"
 #include "SVGFESpecularLightingElement.h"
 #include "SVGFilterPrimitiveStandardAttributes.h"
@@ -54,23 +56,45 @@
 {
     RenderSVGHiddenContainer::styleDidChange(diff, oldStyle);
 
-    auto* filter = parent();
-    if (!filter)
-        return;
-
     if (diff == StyleDifference::Equal || !oldStyle)
         return;
 
     const SVGRenderStyle& newStyle = style().svgStyle();
-    if (is<SVGFEFloodElement>(filterPrimitiveElement())) {
+    if (is<SVGFEFloodElement>(filterPrimitiveElement()) || is<SVGFEDropShadowElement>(filterPrimitiveElement())) {
         if (newStyle.floodColor() != oldStyle->svgStyle().floodColor())
-            downcast<RenderSVGResourceFilter>(*filter).primitiveAttributeChanged(this, SVGNames::flood_colorAttr);
+            filterPrimitiveElement().primitiveAttributeChanged(SVGNames::flood_colorAttr);
         if (newStyle.floodOpacity() != oldStyle->svgStyle().floodOpacity())
-            downcast<RenderSVGResourceFilter>(*filter).primitiveAttributeChanged(this, SVGNames::flood_opacityAttr);
+            filterPrimitiveElement().primitiveAttributeChanged(SVGNames::flood_opacityAttr);
     } else if (is<SVGFEDiffuseLightingElement>(filterPrimitiveElement()) || is<SVGFESpecularLightingElement>(filterPrimitiveElement())) {
         if (newStyle.lightingColor() != oldStyle->svgStyle().lightingColor())
-            downcast<RenderSVGResourceFilter>(*filter).primitiveAttributeChanged(this, SVGNames::lighting_colorAttr);
+            filterPrimitiveElement().primitiveAttributeChanged(SVGNames::lighting_colorAttr);
     }
 }
 
+void RenderSVGResourceFilterPrimitive::markFilterEffectForRepaint(FilterEffect* effect)
+{
+    auto parent = this->parent();
+    if (!is<RenderSVGResourceFilter>(parent))
+        return;
+
+    auto& filterRenderer = downcast<RenderSVGResourceFilter>(*parent);
+
+    if (effect)
+        filterRenderer.markFilterForRepaint(*effect);
+
+    filterRenderer.markAllClientLayersForInvalidation();
+}
+
+void RenderSVGResourceFilterPrimitive::markFilterEffectForRebuild()
+{
+    auto parent = this->parent();
+    if (!is<RenderSVGResourceFilter>(parent))
+        return;
+
+    auto& filterRenderer = downcast<RenderSVGResourceFilter>(*parent);
+
+    filterRenderer.markFilterForRebuild();
+    filterRenderer.markAllClientLayersForInvalidation();
+}
+
 } // namespace WebCore

Modified: trunk/Source/WebCore/rendering/svg/RenderSVGResourceFilterPrimitive.h (295497 => 295498)


--- trunk/Source/WebCore/rendering/svg/RenderSVGResourceFilterPrimitive.h	2022-06-13 19:23:41 UTC (rev 295497)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGResourceFilterPrimitive.h	2022-06-13 19:52:35 UTC (rev 295498)
@@ -43,13 +43,9 @@
 
     ASCIILiteral renderName() const override { return "RenderSVGResourceFilterPrimitive"_s; }
 
-    inline void primitiveAttributeChanged(const QualifiedName& attribute)
-    {
-        RenderObject* filter = parent();
-        if (!filter || !filter->isSVGResourceFilter())
-            return;
-        static_cast<RenderSVGResourceFilter*>(filter)->primitiveAttributeChanged(this, attribute);
-    }
+    void markFilterEffectForRepaint(FilterEffect*);
+    void markFilterEffectForRebuild();
+
 private:
     bool isSVGResourceFilterPrimitive() const override { return true; }
     void element() const = delete;

Modified: trunk/Source/WebCore/rendering/svg/SVGRenderTreeAsText.cpp (295497 => 295498)


--- trunk/Source/WebCore/rendering/svg/SVGRenderTreeAsText.cpp	2022-06-13 19:23:41 UTC (rev 295497)
+++ trunk/Source/WebCore/rendering/svg/SVGRenderTreeAsText.cpp	2022-06-13 19:52:35 UTC (rev 295498)
@@ -477,8 +477,7 @@
         // Creating a placeholder filter which is passed to the builder.
         FloatRect dummyRect;
         FloatSize dummyScale(1, 1);
-        SVGFilterBuilder builder;
-        auto dummyFilter = SVGFilter::create(filter.filterElement(), builder, RenderingMode::Unaccelerated, dummyScale, Filter::ClipOperation::Intersect, dummyRect, dummyRect, NullGraphicsContext());
+        auto dummyFilter = SVGFilter::create(filter.filterElement(), RenderingMode::Unaccelerated, dummyScale, Filter::ClipOperation::Intersect, dummyRect, dummyRect, NullGraphicsContext());
         if (dummyFilter) {
             TextStream::IndentScope indentScope(ts);
             dummyFilter->externalRepresentation(ts, FilterRepresentation::TestOutput);

Modified: trunk/Source/WebCore/svg/SVGFEBlendElement.cpp (295497 => 295498)


--- trunk/Source/WebCore/svg/SVGFEBlendElement.cpp	2022-06-13 19:23:41 UTC (rev 295497)
+++ trunk/Source/WebCore/svg/SVGFEBlendElement.cpp	2022-06-13 19:52:35 UTC (rev 295498)
@@ -71,11 +71,11 @@
     SVGFilterPrimitiveStandardAttributes::parseAttribute(name, value);
 }
 
-bool SVGFEBlendElement::setFilterEffectAttribute(FilterEffect* effect, const QualifiedName& attrName)
+bool SVGFEBlendElement::setFilterEffectAttribute(FilterEffect& effect, const QualifiedName& attrName)
 {
-    FEBlend* blend = static_cast<FEBlend*>(effect);
+    auto& feBlend = downcast<FEBlend>(effect);
     if (attrName == SVGNames::modeAttr)
-        return blend->setBlendMode(mode());
+        return feBlend.setBlendMode(mode());
 
     ASSERT_NOT_REACHED();
     return false;
@@ -97,7 +97,7 @@
     SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName);
 }
 
-RefPtr<FilterEffect> SVGFEBlendElement::filterEffect(const FilterEffectVector&, const GraphicsContext&) const
+RefPtr<FilterEffect> SVGFEBlendElement::createFilterEffect(const FilterEffectVector&, const GraphicsContext&) const
 {
     return FEBlend::create(mode());
 }

Modified: trunk/Source/WebCore/svg/SVGFEBlendElement.h (295497 => 295498)


--- trunk/Source/WebCore/svg/SVGFEBlendElement.h	2022-06-13 19:23:41 UTC (rev 295497)
+++ trunk/Source/WebCore/svg/SVGFEBlendElement.h	2022-06-13 19:52:35 UTC (rev 295498)
@@ -69,9 +69,9 @@
     void parseAttribute(const QualifiedName&, const AtomString&) override;
     void svgAttributeChanged(const QualifiedName&) override;
 
-    bool setFilterEffectAttribute(FilterEffect*, const QualifiedName& attrName) override;
+    bool setFilterEffectAttribute(FilterEffect&, const QualifiedName& attrName) override;
     Vector<AtomString> filterEffectInputsNames() const override { return { AtomString { in1() }, AtomString { in2() } }; }
-    RefPtr<FilterEffect> filterEffect(const FilterEffectVector&, const GraphicsContext& destinationContext) const override;
+    RefPtr<FilterEffect> createFilterEffect(const FilterEffectVector&, const GraphicsContext& destinationContext) const override;
 
     PropertyRegistry m_propertyRegistry { *this };
     Ref<SVGAnimatedString> m_in1 { SVGAnimatedString::create(this) };

Modified: trunk/Source/WebCore/svg/SVGFEColorMatrixElement.cpp (295497 => 295498)


--- trunk/Source/WebCore/svg/SVGFEColorMatrixElement.cpp	2022-06-13 19:23:41 UTC (rev 295497)
+++ trunk/Source/WebCore/svg/SVGFEColorMatrixElement.cpp	2022-06-13 19:52:35 UTC (rev 295498)
@@ -48,6 +48,16 @@
     return adoptRef(*new SVGFEColorMatrixElement(tagName, document));
 }
 
+bool SVGFEColorMatrixElement::isInvalidValuesLength() const
+{
+    auto filterType = type();
+    auto size = values().size();
+
+    return (filterType == FECOLORMATRIX_TYPE_MATRIX    && size != 20)
+        || (filterType == FECOLORMATRIX_TYPE_HUEROTATE && size != 1)
+        || (filterType == FECOLORMATRIX_TYPE_SATURATE  && size != 1);
+}
+
 void SVGFEColorMatrixElement::parseAttribute(const QualifiedName& name, const AtomString& value)
 {
     if (name == SVGNames::typeAttr) {
@@ -70,13 +80,14 @@
     SVGFilterPrimitiveStandardAttributes::parseAttribute(name, value);
 }
 
-bool SVGFEColorMatrixElement::setFilterEffectAttribute(FilterEffect* effect, const QualifiedName& attrName)
+bool SVGFEColorMatrixElement::setFilterEffectAttribute(FilterEffect& effect, const QualifiedName& attrName)
 {
-    FEColorMatrix* colorMatrix = static_cast<FEColorMatrix*>(effect);
+    auto& feColorMatrix = downcast<FEColorMatrix>(effect);
+
     if (attrName == SVGNames::typeAttr)
-        return colorMatrix->setType(type());
+        return feColorMatrix.setType(type());
     if (attrName == SVGNames::valuesAttr)
-        return colorMatrix->setValues(values());
+        return feColorMatrix.setValues(values());
 
     ASSERT_NOT_REACHED();
     return false;
@@ -84,14 +95,18 @@
 
 void SVGFEColorMatrixElement::svgAttributeChanged(const QualifiedName& attrName)
 {
-    if (PropertyRegistry::isKnownAttribute(attrName)) {
+    if (attrName == SVGNames::inAttr) {
         InstanceInvalidationGuard guard(*this);
-        if (attrName == SVGNames::inAttr)
-            updateSVGRendererForElementChange();
-        else {
-            ASSERT(attrName == SVGNames::typeAttr || attrName == SVGNames::valuesAttr);
+        updateSVGRendererForElementChange();
+        return;
+    }
+
+    if (attrName == SVGNames::typeAttr || attrName == SVGNames::valuesAttr) {
+        InstanceInvalidationGuard guard(*this);
+        if (isInvalidValuesLength())
+            markFilterEffectForRebuild();
+        else
             primitiveAttributeChanged(attrName);
-        }
         return;
     }
 
@@ -98,7 +113,7 @@
     SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName);
 }
 
-RefPtr<FilterEffect> SVGFEColorMatrixElement::filterEffect(const FilterEffectVector&, const GraphicsContext&) const
+RefPtr<FilterEffect> SVGFEColorMatrixElement::createFilterEffect(const FilterEffectVector&, const GraphicsContext&) const
 {
     Vector<float> filterValues;
     ColorMatrixType filterType = type();
@@ -123,11 +138,7 @@
             break;
         }
     } else {
-        unsigned size = values().size();
-
-        if ((filterType == FECOLORMATRIX_TYPE_MATRIX && size != 20)
-            || (filterType == FECOLORMATRIX_TYPE_HUEROTATE && size != 1)
-            || (filterType == FECOLORMATRIX_TYPE_SATURATE && size != 1))
+        if (isInvalidValuesLength())
             return nullptr;
 
         filterValues = values();

Modified: trunk/Source/WebCore/svg/SVGFEColorMatrixElement.h (295497 => 295498)


--- trunk/Source/WebCore/svg/SVGFEColorMatrixElement.h	2022-06-13 19:23:41 UTC (rev 295497)
+++ trunk/Source/WebCore/svg/SVGFEColorMatrixElement.h	2022-06-13 19:52:35 UTC (rev 295498)
@@ -82,12 +82,14 @@
     using PropertyRegistry = SVGPropertyOwnerRegistry<SVGFEColorMatrixElement, SVGFilterPrimitiveStandardAttributes>;
     const SVGPropertyRegistry& propertyRegistry() const final { return m_propertyRegistry; }
 
+    bool isInvalidValuesLength() const;
+
     void parseAttribute(const QualifiedName&, const AtomString&) override;
     void svgAttributeChanged(const QualifiedName&) override;
 
-    bool setFilterEffectAttribute(FilterEffect*, const QualifiedName&) override;
+    bool setFilterEffectAttribute(FilterEffect&, const QualifiedName&) override;
     Vector<AtomString> filterEffectInputsNames() const override { return { AtomString { in1() } }; }
-    RefPtr<FilterEffect> filterEffect(const FilterEffectVector&, const GraphicsContext& destinationContext) const override;
+    RefPtr<FilterEffect> createFilterEffect(const FilterEffectVector&, const GraphicsContext& destinationContext) const override;
 
     PropertyRegistry m_propertyRegistry { *this };
     Ref<SVGAnimatedString> m_in1 { SVGAnimatedString::create(this) };

Modified: trunk/Source/WebCore/svg/SVGFEComponentTransferElement.cpp (295497 => 295498)


--- trunk/Source/WebCore/svg/SVGFEComponentTransferElement.cpp	2022-06-13 19:23:41 UTC (rev 295497)
+++ trunk/Source/WebCore/svg/SVGFEComponentTransferElement.cpp	2022-06-13 19:52:35 UTC (rev 295498)
@@ -62,8 +62,19 @@
     SVGFilterPrimitiveStandardAttributes::parseAttribute(name, value);
 }
 
-RefPtr<FilterEffect> SVGFEComponentTransferElement::filterEffect(const FilterEffectVector&, const GraphicsContext&) const
+void SVGFEComponentTransferElement::svgAttributeChanged(const QualifiedName& attrName)
 {
+    if (attrName == SVGNames::inAttr) {
+        InstanceInvalidationGuard guard(*this);
+        updateSVGRendererForElementChange();
+        return;
+    }
+
+    SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName);
+}
+
+RefPtr<FilterEffect> SVGFEComponentTransferElement::createFilterEffect(const FilterEffectVector&, const GraphicsContext&) const
+{
     ComponentTransferFunction red;
     ComponentTransferFunction green;
     ComponentTransferFunction blue;

Modified: trunk/Source/WebCore/svg/SVGFEComponentTransferElement.h (295497 => 295498)


--- trunk/Source/WebCore/svg/SVGFEComponentTransferElement.h	2022-06-13 19:23:41 UTC (rev 295497)
+++ trunk/Source/WebCore/svg/SVGFEComponentTransferElement.h	2022-06-13 19:52:35 UTC (rev 295498)
@@ -40,11 +40,11 @@
     using PropertyRegistry = SVGPropertyOwnerRegistry<SVGFEComponentTransferElement, SVGFilterPrimitiveStandardAttributes>;
     const SVGPropertyRegistry& propertyRegistry() const final { return m_propertyRegistry; }
 
-    // FIXME: https://bugs.webkit.org/show_bug.cgi?id=237702 - provide svgAttribute implementation for SVGFEComponentTransferElement.
     void parseAttribute(const QualifiedName&, const AtomString&) override;
+    void svgAttributeChanged(const QualifiedName&) override;
 
     Vector<AtomString> filterEffectInputsNames() const override { return { AtomString { in1() } }; }
-    RefPtr<FilterEffect> filterEffect(const FilterEffectVector&, const GraphicsContext& destinationContext) const override;
+    RefPtr<FilterEffect> createFilterEffect(const FilterEffectVector&, const GraphicsContext& destinationContext) const override;
 
     PropertyRegistry m_propertyRegistry { *this };
     Ref<SVGAnimatedString> m_in1 { SVGAnimatedString::create(this) };

Modified: trunk/Source/WebCore/svg/SVGFECompositeElement.cpp (295497 => 295498)


--- trunk/Source/WebCore/svg/SVGFECompositeElement.cpp	2022-06-13 19:23:41 UTC (rev 295497)
+++ trunk/Source/WebCore/svg/SVGFECompositeElement.cpp	2022-06-13 19:52:35 UTC (rev 295498)
@@ -94,19 +94,19 @@
     SVGFilterPrimitiveStandardAttributes::parseAttribute(name, value);
 }
 
-bool SVGFECompositeElement::setFilterEffectAttribute(FilterEffect* effect, const QualifiedName& attrName)
+bool SVGFECompositeElement::setFilterEffectAttribute(FilterEffect& effect, const QualifiedName& attrName)
 {
-    FEComposite* composite = static_cast<FEComposite*>(effect);
+    auto& feComposite = downcast<FEComposite>(effect);
     if (attrName == SVGNames::operatorAttr)
-        return composite->setOperation(svgOperator());
+        return feComposite.setOperation(svgOperator());
     if (attrName == SVGNames::k1Attr)
-        return composite->setK1(k1());
+        return feComposite.setK1(k1());
     if (attrName == SVGNames::k2Attr)
-        return composite->setK2(k2());
+        return feComposite.setK2(k2());
     if (attrName == SVGNames::k3Attr)
-        return composite->setK3(k3());
+        return feComposite.setK3(k3());
     if (attrName == SVGNames::k4Attr)
-        return composite->setK4(k4());
+        return feComposite.setK4(k4());
 
     ASSERT_NOT_REACHED();
     return false;
@@ -115,21 +115,22 @@
 
 void SVGFECompositeElement::svgAttributeChanged(const QualifiedName& attrName)
 {
-    if (PropertyRegistry::isKnownAttribute(attrName)) {
+    if (attrName == SVGNames::inAttr || attrName == SVGNames::in2Attr) {
         InstanceInvalidationGuard guard(*this);
-        if (attrName == SVGNames::inAttr || attrName == SVGNames::in2Attr)
-            updateSVGRendererForElementChange();
-        else {
-            ASSERT(attrName == SVGNames::k1Attr || attrName == SVGNames::k2Attr || attrName == SVGNames::k3Attr || attrName == SVGNames::k4Attr || attrName == SVGNames::operatorAttr);
-            primitiveAttributeChanged(attrName);
-        }
+        updateSVGRendererForElementChange();
         return;
     }
 
+    if (attrName == SVGNames::k1Attr || attrName == SVGNames::k2Attr || attrName == SVGNames::k3Attr || attrName == SVGNames::k4Attr || attrName == SVGNames::operatorAttr) {
+        InstanceInvalidationGuard guard(*this);
+        primitiveAttributeChanged(attrName);
+        return;
+    }
+
     SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName);
 }
 
-RefPtr<FilterEffect> SVGFECompositeElement::filterEffect(const FilterEffectVector&, const GraphicsContext&) const
+RefPtr<FilterEffect> SVGFECompositeElement::createFilterEffect(const FilterEffectVector&, const GraphicsContext&) const
 {
     return FEComposite::create(svgOperator(), k1(), k2(), k3(), k4());
 }

Modified: trunk/Source/WebCore/svg/SVGFECompositeElement.h (295497 => 295498)


--- trunk/Source/WebCore/svg/SVGFECompositeElement.h	2022-06-13 19:23:41 UTC (rev 295497)
+++ trunk/Source/WebCore/svg/SVGFECompositeElement.h	2022-06-13 19:52:35 UTC (rev 295498)
@@ -105,9 +105,9 @@
     void parseAttribute(const QualifiedName&, const AtomString&) override;
     void svgAttributeChanged(const QualifiedName&) override;
 
-    bool setFilterEffectAttribute(FilterEffect*, const QualifiedName&) override;
+    bool setFilterEffectAttribute(FilterEffect&, const QualifiedName&) override;
     Vector<AtomString> filterEffectInputsNames() const override { return { AtomString { in1() }, AtomString { in2() } }; }
-    RefPtr<FilterEffect> filterEffect(const FilterEffectVector&, const GraphicsContext& destinationContext) const override;
+    RefPtr<FilterEffect> createFilterEffect(const FilterEffectVector&, const GraphicsContext& destinationContext) const override;
 
     PropertyRegistry m_propertyRegistry { *this };
     Ref<SVGAnimatedString> m_in1 { SVGAnimatedString::create(this) };

Modified: trunk/Source/WebCore/svg/SVGFEConvolveMatrixElement.cpp (295497 => 295498)


--- trunk/Source/WebCore/svg/SVGFEConvolveMatrixElement.cpp	2022-06-13 19:23:41 UTC (rev 295497)
+++ trunk/Source/WebCore/svg/SVGFEConvolveMatrixElement.cpp	2022-06-13 19:52:35 UTC (rev 295498)
@@ -135,23 +135,23 @@
     SVGFilterPrimitiveStandardAttributes::parseAttribute(name, value);
 }
 
-bool SVGFEConvolveMatrixElement::setFilterEffectAttribute(FilterEffect* effect, const QualifiedName& attrName)
+bool SVGFEConvolveMatrixElement::setFilterEffectAttribute(FilterEffect& effect, const QualifiedName& attrName)
 {
-    FEConvolveMatrix* convolveMatrix = static_cast<FEConvolveMatrix*>(effect);
+    auto& feConvolveMatrix = downcast<FEConvolveMatrix>(effect);
     if (attrName == SVGNames::edgeModeAttr)
-        return convolveMatrix->setEdgeMode(edgeMode());
+        return feConvolveMatrix.setEdgeMode(edgeMode());
     if (attrName == SVGNames::divisorAttr)
-        return convolveMatrix->setDivisor(divisor());
+        return feConvolveMatrix.setDivisor(divisor());
     if (attrName == SVGNames::biasAttr)
-        return convolveMatrix->setBias(bias());
+        return feConvolveMatrix.setBias(bias());
     if (attrName == SVGNames::targetXAttr)
-        return convolveMatrix->setTargetOffset(IntPoint(targetX(), targetY()));
+        return feConvolveMatrix.setTargetOffset(IntPoint(targetX(), targetY()));
     if (attrName == SVGNames::targetYAttr)
-        return convolveMatrix->setTargetOffset(IntPoint(targetX(), targetY()));
+        return feConvolveMatrix.setTargetOffset(IntPoint(targetX(), targetY()));
     if (attrName == SVGNames::kernelUnitLengthAttr)
-        return convolveMatrix->setKernelUnitLength(FloatPoint(kernelUnitLengthX(), kernelUnitLengthY()));
+        return feConvolveMatrix.setKernelUnitLength(FloatPoint(kernelUnitLengthX(), kernelUnitLengthY()));
     if (attrName == SVGNames::preserveAlphaAttr)
-        return convolveMatrix->setPreserveAlpha(preserveAlpha());
+        return feConvolveMatrix.setPreserveAlpha(preserveAlpha());
 
     ASSERT_NOT_REACHED();
     return false;
@@ -173,22 +173,24 @@
 
 void SVGFEConvolveMatrixElement::svgAttributeChanged(const QualifiedName& attrName)
 {
-    if (PropertyRegistry::isKnownAttribute(attrName)) {
+    if (attrName == SVGNames::inAttr || attrName == SVGNames::orderAttr || attrName == SVGNames::kernelMatrixAttr) {
         InstanceInvalidationGuard guard(*this);
-        if (attrName == SVGNames::inAttr || attrName == SVGNames::orderAttr || attrName == SVGNames::kernelMatrixAttr)
-            updateSVGRendererForElementChange();
-        else {
-            ASSERT(attrName == SVGNames::edgeModeAttr || attrName == SVGNames::divisorAttr || attrName == SVGNames::biasAttr || attrName == SVGNames::targetXAttr
-                || attrName == SVGNames::targetYAttr || attrName == SVGNames::kernelUnitLengthAttr || attrName == SVGNames::preserveAlphaAttr);
-            primitiveAttributeChanged(attrName);
-        }
+        updateSVGRendererForElementChange();
         return;
     }
+    
+    if (attrName == SVGNames::edgeModeAttr || attrName == SVGNames::divisorAttr || attrName == SVGNames::biasAttr
+        || attrName == SVGNames::targetXAttr || attrName == SVGNames::targetYAttr
+        || attrName == SVGNames::kernelUnitLengthAttr || attrName == SVGNames::preserveAlphaAttr) {
+        InstanceInvalidationGuard guard(*this);
+        primitiveAttributeChanged(attrName);
+        return;
+    }
 
     SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName);
 }
 
-RefPtr<FilterEffect> SVGFEConvolveMatrixElement::filterEffect(const FilterEffectVector&, const GraphicsContext&) const
+RefPtr<FilterEffect> SVGFEConvolveMatrixElement::createFilterEffect(const FilterEffectVector&, const GraphicsContext&) const
 {
     int orderXValue = orderX();
     int orderYValue = orderY();

Modified: trunk/Source/WebCore/svg/SVGFEConvolveMatrixElement.h (295497 => 295498)


--- trunk/Source/WebCore/svg/SVGFEConvolveMatrixElement.h	2022-06-13 19:23:41 UTC (rev 295497)
+++ trunk/Source/WebCore/svg/SVGFEConvolveMatrixElement.h	2022-06-13 19:52:35 UTC (rev 295498)
@@ -103,9 +103,9 @@
     void parseAttribute(const QualifiedName&, const AtomString&) override;
     void svgAttributeChanged(const QualifiedName&) override;
 
-    bool setFilterEffectAttribute(FilterEffect*, const QualifiedName&) override;
+    bool setFilterEffectAttribute(FilterEffect&, const QualifiedName&) override;
     Vector<AtomString> filterEffectInputsNames() const override { return { AtomString { in1() } }; }
-    RefPtr<FilterEffect> filterEffect(const FilterEffectVector&, const GraphicsContext& destinationContext) const override;
+    RefPtr<FilterEffect> createFilterEffect(const FilterEffectVector&, const GraphicsContext& destinationContext) const override;
 
     PropertyRegistry m_propertyRegistry { *this };
     Ref<SVGAnimatedString> m_in1 { SVGAnimatedString::create(this) };

Modified: trunk/Source/WebCore/svg/SVGFEDiffuseLightingElement.cpp (295497 => 295498)


--- trunk/Source/WebCore/svg/SVGFEDiffuseLightingElement.cpp	2022-06-13 19:23:41 UTC (rev 295497)
+++ trunk/Source/WebCore/svg/SVGFEDiffuseLightingElement.cpp	2022-06-13 19:52:35 UTC (rev 295498)
@@ -79,22 +79,22 @@
     SVGFilterPrimitiveStandardAttributes::parseAttribute(name, value);
 }
 
-bool SVGFEDiffuseLightingElement::setFilterEffectAttribute(FilterEffect* effect, const QualifiedName& attrName)
+bool SVGFEDiffuseLightingElement::setFilterEffectAttribute(FilterEffect& effect, const QualifiedName& attrName)
 {
-    FEDiffuseLighting* diffuseLighting = static_cast<FEDiffuseLighting*>(effect);
+    auto& feDiffuseLighting = downcast<FEDiffuseLighting>(effect);
 
     if (attrName == SVGNames::lighting_colorAttr) {
         RenderObject* renderer = this->renderer();
         ASSERT(renderer);
         Color color = renderer->style().colorByApplyingColorFilter(renderer->style().svgStyle().lightingColor());
-        return diffuseLighting->setLightingColor(color);
+        return feDiffuseLighting.setLightingColor(color);
     }
     if (attrName == SVGNames::surfaceScaleAttr)
-        return diffuseLighting->setSurfaceScale(surfaceScale());
+        return feDiffuseLighting.setSurfaceScale(surfaceScale());
     if (attrName == SVGNames::diffuseConstantAttr)
-        return diffuseLighting->setDiffuseConstant(diffuseConstant());
+        return feDiffuseLighting.setDiffuseConstant(diffuseConstant());
 
-    auto& lightSource = const_cast<LightSource&>(diffuseLighting->lightSource());
+    auto& lightSource = const_cast<LightSource&>(feDiffuseLighting.lightSource());
     const SVGFELightElement* lightElement = SVGFELightElement::findLightElement(this);
     ASSERT(lightElement);
 
@@ -125,17 +125,18 @@
 
 void SVGFEDiffuseLightingElement::svgAttributeChanged(const QualifiedName& attrName)
 {
-    if (PropertyRegistry::isKnownAttribute(attrName)) {
+    if (attrName == SVGNames::inAttr) {
         InstanceInvalidationGuard guard(*this);
-        if (attrName == SVGNames::inAttr)
-            updateSVGRendererForElementChange();
-        else {
-            ASSERT(attrName == SVGNames::diffuseConstantAttr || attrName == SVGNames::surfaceScaleAttr || attrName == SVGNames::kernelUnitLengthAttr);
-            primitiveAttributeChanged(attrName);
-        }
+        updateSVGRendererForElementChange();
         return;
     }
 
+    if (attrName == SVGNames::diffuseConstantAttr || attrName == SVGNames::surfaceScaleAttr || attrName == SVGNames::kernelUnitLengthAttr) {
+        InstanceInvalidationGuard guard(*this);
+        primitiveAttributeChanged(attrName);
+        return;
+    }
+
     SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName);
 }
 
@@ -148,7 +149,7 @@
     primitiveAttributeChanged(attrName);
 }
 
-RefPtr<FilterEffect> SVGFEDiffuseLightingElement::filterEffect(const FilterEffectVector&, const GraphicsContext&) const
+RefPtr<FilterEffect> SVGFEDiffuseLightingElement::createFilterEffect(const FilterEffectVector&, const GraphicsContext&) const
 {
     RefPtr lightElement = SVGFELightElement::findLightElement(this);
     if (!lightElement)

Modified: trunk/Source/WebCore/svg/SVGFEDiffuseLightingElement.h (295497 => 295498)


--- trunk/Source/WebCore/svg/SVGFEDiffuseLightingElement.h	2022-06-13 19:23:41 UTC (rev 295497)
+++ trunk/Source/WebCore/svg/SVGFEDiffuseLightingElement.h	2022-06-13 19:52:35 UTC (rev 295498)
@@ -57,9 +57,9 @@
     void parseAttribute(const QualifiedName&, const AtomString&) override;
     void svgAttributeChanged(const QualifiedName&) override;
 
-    bool setFilterEffectAttribute(FilterEffect*, const QualifiedName&) override;
+    bool setFilterEffectAttribute(FilterEffect&, const QualifiedName&) override;
     Vector<AtomString> filterEffectInputsNames() const override { return { AtomString { in1() } }; }
-    RefPtr<FilterEffect> filterEffect(const FilterEffectVector&, const GraphicsContext& destinationContext) const override;
+    RefPtr<FilterEffect> createFilterEffect(const FilterEffectVector&, const GraphicsContext& destinationContext) const override;
 
     PropertyRegistry m_propertyRegistry { *this };
     Ref<SVGAnimatedString> m_in1 { SVGAnimatedString::create(this) };

Modified: trunk/Source/WebCore/svg/SVGFEDisplacementMapElement.cpp (295497 => 295498)


--- trunk/Source/WebCore/svg/SVGFEDisplacementMapElement.cpp	2022-06-13 19:23:41 UTC (rev 295497)
+++ trunk/Source/WebCore/svg/SVGFEDisplacementMapElement.cpp	2022-06-13 19:52:35 UTC (rev 295498)
@@ -83,15 +83,15 @@
     SVGFilterPrimitiveStandardAttributes::parseAttribute(name, value);
 }
 
-bool SVGFEDisplacementMapElement::setFilterEffectAttribute(FilterEffect* effect, const QualifiedName& attrName)
+bool SVGFEDisplacementMapElement::setFilterEffectAttribute(FilterEffect& effect, const QualifiedName& attrName)
 {
-    FEDisplacementMap* displacementMap = static_cast<FEDisplacementMap*>(effect);
+    auto& feDisplacementMap = downcast<FEDisplacementMap>(effect);
     if (attrName == SVGNames::xChannelSelectorAttr)
-        return displacementMap->setXChannelSelector(xChannelSelector());
+        return feDisplacementMap.setXChannelSelector(xChannelSelector());
     if (attrName == SVGNames::yChannelSelectorAttr)
-        return displacementMap->setYChannelSelector(yChannelSelector());
+        return feDisplacementMap.setYChannelSelector(yChannelSelector());
     if (attrName == SVGNames::scaleAttr)
-        return displacementMap->setScale(scale());
+        return feDisplacementMap.setScale(scale());
 
     ASSERT_NOT_REACHED();
     return false;
@@ -99,21 +99,22 @@
 
 void SVGFEDisplacementMapElement::svgAttributeChanged(const QualifiedName& attrName)
 {
-    if (PropertyRegistry::isKnownAttribute(attrName)) {
+    if (attrName == SVGNames::inAttr || attrName == SVGNames::in2Attr) {
         InstanceInvalidationGuard guard(*this);
-        if (attrName == SVGNames::inAttr || attrName == SVGNames::in2Attr)
-            updateSVGRendererForElementChange();
-        else {
-            ASSERT(attrName == SVGNames::xChannelSelectorAttr || attrName == SVGNames::yChannelSelectorAttr || attrName == SVGNames::scaleAttr);
-            primitiveAttributeChanged(attrName);
-        }
+        updateSVGRendererForElementChange();
         return;
     }
 
+    if (attrName == SVGNames::xChannelSelectorAttr || attrName == SVGNames::yChannelSelectorAttr || attrName == SVGNames::scaleAttr) {
+        InstanceInvalidationGuard guard(*this);
+        primitiveAttributeChanged(attrName);
+        return;
+    }
+
     SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName);
 }
 
-RefPtr<FilterEffect> SVGFEDisplacementMapElement::filterEffect(const FilterEffectVector&, const GraphicsContext&) const
+RefPtr<FilterEffect> SVGFEDisplacementMapElement::createFilterEffect(const FilterEffectVector&, const GraphicsContext&) const
 {
     return FEDisplacementMap::create(xChannelSelector(), yChannelSelector(), scale());
 }

Modified: trunk/Source/WebCore/svg/SVGFEDisplacementMapElement.h (295497 => 295498)


--- trunk/Source/WebCore/svg/SVGFEDisplacementMapElement.h	2022-06-13 19:23:41 UTC (rev 295497)
+++ trunk/Source/WebCore/svg/SVGFEDisplacementMapElement.h	2022-06-13 19:52:35 UTC (rev 295498)
@@ -90,9 +90,9 @@
     void parseAttribute(const QualifiedName&, const AtomString&) override;
     void svgAttributeChanged(const QualifiedName&) override;
 
-    bool setFilterEffectAttribute(FilterEffect*, const QualifiedName& attrName) override;
+    bool setFilterEffectAttribute(FilterEffect&, const QualifiedName& attrName) override;
     Vector<AtomString> filterEffectInputsNames() const override { return { AtomString { in1() }, AtomString { in2() } }; }
-    RefPtr<FilterEffect> filterEffect(const FilterEffectVector&, const GraphicsContext& destinationContext) const override;
+    RefPtr<FilterEffect> createFilterEffect(const FilterEffectVector&, const GraphicsContext& destinationContext) const override;
 
     PropertyRegistry m_propertyRegistry { *this };
     Ref<SVGAnimatedString> m_in1 { SVGAnimatedString::create(this) };

Modified: trunk/Source/WebCore/svg/SVGFEDropShadowElement.cpp (295497 => 295498)


--- trunk/Source/WebCore/svg/SVGFEDropShadowElement.cpp	2022-06-13 19:23:41 UTC (rev 295497)
+++ trunk/Source/WebCore/svg/SVGFEDropShadowElement.cpp	2022-06-13 19:52:35 UTC (rev 295498)
@@ -87,15 +87,55 @@
 
 void SVGFEDropShadowElement::svgAttributeChanged(const QualifiedName& attrName)
 {
-    if (PropertyRegistry::isKnownAttribute(attrName)) {
+    if (attrName == SVGNames::inAttr) {
         InstanceInvalidationGuard guard(*this);
         updateSVGRendererForElementChange();
         return;
     }
 
+    if (attrName == SVGNames::stdDeviationAttr && (stdDeviationX() < 0 || stdDeviationY() < 0)) {
+        InstanceInvalidationGuard guard(*this);
+        markFilterEffectForRebuild();
+        return;
+    }
+
+    if (attrName == SVGNames::stdDeviationAttr || attrName == SVGNames::dxAttr || attrName == SVGNames::dyAttr) {
+        InstanceInvalidationGuard guard(*this);
+        primitiveAttributeChanged(attrName);
+        return;
+    }
+
     SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName);
 }
 
+bool SVGFEDropShadowElement::setFilterEffectAttribute(FilterEffect& effect, const QualifiedName& attrName)
+{
+    auto& feDropShadow = downcast<FEDropShadow>(effect);
+
+    if (attrName == SVGNames::stdDeviationAttr) {
+        bool stdDeviationXChanged = feDropShadow.setStdDeviationX(stdDeviationX());
+        bool stdDeviationYChanged = feDropShadow.setStdDeviationY(stdDeviationY());
+        return stdDeviationXChanged || stdDeviationYChanged;
+    }
+
+    if (attrName == SVGNames::dxAttr)
+        return feDropShadow.setDx(dx());
+    if (attrName == SVGNames::dyAttr)
+        return feDropShadow.setDy(dy());
+
+    RenderObject* renderer = this->renderer();
+    ASSERT(renderer);
+    const RenderStyle& style = renderer->style();
+
+    if (attrName == SVGNames::flood_colorAttr)
+        return feDropShadow.setShadowColor(style.svgStyle().floodColor());
+    if (attrName == SVGNames::flood_opacityAttr)
+        return feDropShadow.setShadowOpacity(style.svgStyle().floodOpacity());
+
+    ASSERT_NOT_REACHED();
+    return false;
+}
+
 IntOutsets SVGFEDropShadowElement::outsets(const FloatRect& targetBoundingBox, SVGUnitTypes::SVGUnitType primitiveUnits) const
 {
     auto offset = SVGFilter::calculateResolvedSize({ dx(), dy() }, targetBoundingBox, primitiveUnits);
@@ -103,7 +143,7 @@
     return FEDropShadow::calculateOutsets(offset, stdDeviation);
 }
 
-RefPtr<FilterEffect> SVGFEDropShadowElement::filterEffect(const FilterEffectVector&, const GraphicsContext&) const
+RefPtr<FilterEffect> SVGFEDropShadowElement::createFilterEffect(const FilterEffectVector&, const GraphicsContext&) const
 {
     RenderObject* renderer = this->renderer();
     if (!renderer)

Modified: trunk/Source/WebCore/svg/SVGFEDropShadowElement.h (295497 => 295498)


--- trunk/Source/WebCore/svg/SVGFEDropShadowElement.h	2022-06-13 19:23:41 UTC (rev 295497)
+++ trunk/Source/WebCore/svg/SVGFEDropShadowElement.h	2022-06-13 19:52:35 UTC (rev 295498)
@@ -53,9 +53,10 @@
     void parseAttribute(const QualifiedName&, const AtomString&) override;
     void svgAttributeChanged(const QualifiedName&) override;
 
+    bool setFilterEffectAttribute(FilterEffect&, const QualifiedName&) override;
     Vector<AtomString> filterEffectInputsNames() const override { return { AtomString { in1() } }; }
     IntOutsets outsets(const FloatRect& targetBoundingBox, SVGUnitTypes::SVGUnitType primitiveUnits) const override;
-    RefPtr<FilterEffect> filterEffect(const FilterEffectVector&, const GraphicsContext& destinationContext) const override;
+    RefPtr<FilterEffect> createFilterEffect(const FilterEffectVector&, const GraphicsContext& destinationContext) const override;
 
     PropertyRegistry m_propertyRegistry { *this };
     Ref<SVGAnimatedString> m_in1 { SVGAnimatedString::create(this) };

Modified: trunk/Source/WebCore/svg/SVGFEFloodElement.cpp (295497 => 295498)


--- trunk/Source/WebCore/svg/SVGFEFloodElement.cpp	2022-06-13 19:23:41 UTC (rev 295497)
+++ trunk/Source/WebCore/svg/SVGFEFloodElement.cpp	2022-06-13 19:52:35 UTC (rev 295498)
@@ -43,23 +43,23 @@
     return adoptRef(*new SVGFEFloodElement(tagName, document));
 }
 
-bool SVGFEFloodElement::setFilterEffectAttribute(FilterEffect* effect, const QualifiedName& attrName)
+bool SVGFEFloodElement::setFilterEffectAttribute(FilterEffect& effect, const QualifiedName& attrName)
 {
     RenderObject* renderer = this->renderer();
     ASSERT(renderer);
     const RenderStyle& style = renderer->style();
-    FEFlood* flood = static_cast<FEFlood*>(effect);
 
+    auto& feFlood = downcast<FEFlood>(effect);
     if (attrName == SVGNames::flood_colorAttr)
-        return flood->setFloodColor(style.svgStyle().floodColor());
+        return feFlood.setFloodColor(style.svgStyle().floodColor());
     if (attrName == SVGNames::flood_opacityAttr)
-        return flood->setFloodOpacity(style.svgStyle().floodOpacity());
+        return feFlood.setFloodOpacity(style.svgStyle().floodOpacity());
 
     ASSERT_NOT_REACHED();
     return false;
 }
 
-RefPtr<FilterEffect> SVGFEFloodElement::filterEffect(const FilterEffectVector&, const GraphicsContext&) const
+RefPtr<FilterEffect> SVGFEFloodElement::createFilterEffect(const FilterEffectVector&, const GraphicsContext&) const
 {
     RenderObject* renderer = this->renderer();
     if (!renderer)

Modified: trunk/Source/WebCore/svg/SVGFEFloodElement.h (295497 => 295498)


--- trunk/Source/WebCore/svg/SVGFEFloodElement.h	2022-06-13 19:23:41 UTC (rev 295497)
+++ trunk/Source/WebCore/svg/SVGFEFloodElement.h	2022-06-13 19:52:35 UTC (rev 295498)
@@ -36,8 +36,8 @@
     using PropertyRegistry = SVGPropertyOwnerRegistry<SVGFEFloodElement, SVGFilterPrimitiveStandardAttributes>;
     const SVGPropertyRegistry& propertyRegistry() const final { return m_propertyRegistry; }
 
-    bool setFilterEffectAttribute(FilterEffect*, const QualifiedName& attrName) override;
-    RefPtr<FilterEffect> filterEffect(const FilterEffectVector&, const GraphicsContext& destinationContext) const override;
+    bool setFilterEffectAttribute(FilterEffect&, const QualifiedName& attrName) override;
+    RefPtr<FilterEffect> createFilterEffect(const FilterEffectVector&, const GraphicsContext& destinationContext) const override;
 
     PropertyRegistry m_propertyRegistry { *this };
 };

Modified: trunk/Source/WebCore/svg/SVGFEGaussianBlurElement.cpp (295497 => 295498)


--- trunk/Source/WebCore/svg/SVGFEGaussianBlurElement.cpp	2022-06-13 19:23:41 UTC (rev 295497)
+++ trunk/Source/WebCore/svg/SVGFEGaussianBlurElement.cpp	2022-06-13 19:52:35 UTC (rev 295498)
@@ -85,15 +85,44 @@
 
 void SVGFEGaussianBlurElement::svgAttributeChanged(const QualifiedName& attrName)
 {
-    if (PropertyRegistry::isKnownAttribute(attrName)) {
+    if (attrName == SVGNames::inAttr) {
         InstanceInvalidationGuard guard(*this);
         updateSVGRendererForElementChange();
         return;
     }
 
+    if (attrName == SVGNames::stdDeviationAttr && (stdDeviationX() < 0 || stdDeviationY() < 0)) {
+        InstanceInvalidationGuard guard(*this);
+        markFilterEffectForRebuild();
+        return;
+    }
+
+    if (attrName == SVGNames::stdDeviationAttr || attrName == SVGNames::edgeModeAttr) {
+        InstanceInvalidationGuard guard(*this);
+        primitiveAttributeChanged(attrName);
+        return;
+    }
+
     SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName);
 }
 
+bool SVGFEGaussianBlurElement::setFilterEffectAttribute(FilterEffect& effect, const QualifiedName& attrName)
+{
+    auto& feGaussianBlur = downcast<FEGaussianBlur>(effect);
+
+    if (attrName == SVGNames::stdDeviationAttr) {
+        bool stdDeviationXChanged = feGaussianBlur.setStdDeviationX(stdDeviationX());
+        bool stdDeviationYChanged = feGaussianBlur.setStdDeviationY(stdDeviationY());
+        return stdDeviationXChanged || stdDeviationYChanged;
+    }
+
+    if (attrName == SVGNames::edgeModeAttr)
+        return feGaussianBlur.setEdgeMode(edgeMode());
+
+    ASSERT_NOT_REACHED();
+    return false;
+}
+
 IntOutsets SVGFEGaussianBlurElement::outsets(const FloatRect& targetBoundingBox, SVGUnitTypes::SVGUnitType primitiveUnits) const
 {
     auto stdDeviation = SVGFilter::calculateResolvedSize({ stdDeviationX(), stdDeviationY() }, targetBoundingBox, primitiveUnits);
@@ -100,7 +129,7 @@
     return FEGaussianBlur::calculateOutsets(stdDeviation);
 }
 
-RefPtr<FilterEffect> SVGFEGaussianBlurElement::filterEffect(const FilterEffectVector&, const GraphicsContext&) const
+RefPtr<FilterEffect> SVGFEGaussianBlurElement::createFilterEffect(const FilterEffectVector&, const GraphicsContext&) const
 {
     if (stdDeviationX() < 0 || stdDeviationY() < 0)
         return nullptr;

Modified: trunk/Source/WebCore/svg/SVGFEGaussianBlurElement.h (295497 => 295498)


--- trunk/Source/WebCore/svg/SVGFEGaussianBlurElement.h	2022-06-13 19:23:41 UTC (rev 295497)
+++ trunk/Source/WebCore/svg/SVGFEGaussianBlurElement.h	2022-06-13 19:52:35 UTC (rev 295498)
@@ -53,9 +53,10 @@
     void parseAttribute(const QualifiedName&, const AtomString&) override;
     void svgAttributeChanged(const QualifiedName&) override;
 
+    bool setFilterEffectAttribute(FilterEffect&, const QualifiedName&) override;
     Vector<AtomString> filterEffectInputsNames() const override { return { AtomString { in1() } }; }
     IntOutsets outsets(const FloatRect& targetBoundingBox, SVGUnitTypes::SVGUnitType primitiveUnits) const override;
-    RefPtr<FilterEffect> filterEffect(const FilterEffectVector&, const GraphicsContext& destinationContext) const override;
+    RefPtr<FilterEffect> createFilterEffect(const FilterEffectVector&, const GraphicsContext& destinationContext) const override;
 
     PropertyRegistry m_propertyRegistry { *this };
     Ref<SVGAnimatedString> m_in1 { SVGAnimatedString::create(this) };

Modified: trunk/Source/WebCore/svg/SVGFEImageElement.cpp (295497 => 295498)


--- trunk/Source/WebCore/svg/SVGFEImageElement.cpp	2022-06-13 19:23:41 UTC (rev 295497)
+++ trunk/Source/WebCore/svg/SVGFEImageElement.cpp	2022-06-13 19:52:35 UTC (rev 295498)
@@ -137,6 +137,7 @@
     if (SVGURIReference::isKnownAttribute(attrName)) {
         InstanceInvalidationGuard guard(*this);
         buildPendingResource();
+        markFilterEffectForRebuild();
         return;
     }
 
@@ -210,7 +211,7 @@
     return { imageBuffer, imageRect };
 }
 
-RefPtr<FilterEffect> SVGFEImageElement::filterEffect(const FilterEffectVector&, const GraphicsContext& destinationContext) const
+RefPtr<FilterEffect> SVGFEImageElement::createFilterEffect(const FilterEffectVector&, const GraphicsContext& destinationContext) const
 {
     if (m_cachedImage) {
         auto image = m_cachedImage->imageForRenderer(renderer());

Modified: trunk/Source/WebCore/svg/SVGFEImageElement.h (295497 => 295498)


--- trunk/Source/WebCore/svg/SVGFEImageElement.h	2022-06-13 19:23:41 UTC (rev 295497)
+++ trunk/Source/WebCore/svg/SVGFEImageElement.h	2022-06-13 19:52:35 UTC (rev 295498)
@@ -56,7 +56,7 @@
 
     std::tuple<RefPtr<ImageBuffer>, FloatRect> imageBufferForEffect(const GraphicsContext& destinationContext) const;
 
-    RefPtr<FilterEffect> filterEffect(const FilterEffectVector&, const GraphicsContext& destinationContext) const override;
+    RefPtr<FilterEffect> createFilterEffect(const FilterEffectVector&, const GraphicsContext& destinationContext) const override;
 
     void clearResourceReferences();
     void requestImageResource();

Modified: trunk/Source/WebCore/svg/SVGFEMergeElement.cpp (295497 => 295498)


--- trunk/Source/WebCore/svg/SVGFEMergeElement.cpp	2022-06-13 19:23:41 UTC (rev 295497)
+++ trunk/Source/WebCore/svg/SVGFEMergeElement.cpp	2022-06-13 19:52:35 UTC (rev 295498)
@@ -44,6 +44,13 @@
     return adoptRef(*new SVGFEMergeElement(tagName, document));
 }
 
+void SVGFEMergeElement::childrenChanged(const ChildChange& change)
+{
+    SVGFilterPrimitiveStandardAttributes::childrenChanged(change);
+    InstanceInvalidationGuard guard(*this);
+    markFilterEffectForRebuild();
+}
+
 Vector<AtomString> SVGFEMergeElement::filterEffectInputsNames() const
 {
     Vector<AtomString> inputsNames;
@@ -52,7 +59,7 @@
     return inputsNames;
 }
 
-RefPtr<FilterEffect> SVGFEMergeElement::filterEffect(const FilterEffectVector& inputs, const GraphicsContext&) const
+RefPtr<FilterEffect> SVGFEMergeElement::createFilterEffect(const FilterEffectVector& inputs, const GraphicsContext&) const
 {
     return FEMerge::create(inputs.size());
 }

Modified: trunk/Source/WebCore/svg/SVGFEMergeElement.h (295497 => 295498)


--- trunk/Source/WebCore/svg/SVGFEMergeElement.h	2022-06-13 19:23:41 UTC (rev 295497)
+++ trunk/Source/WebCore/svg/SVGFEMergeElement.h	2022-06-13 19:52:35 UTC (rev 295498)
@@ -36,8 +36,10 @@
     using PropertyRegistry = SVGPropertyOwnerRegistry<SVGFEMergeElement, SVGFilterPrimitiveStandardAttributes>;
     const SVGPropertyRegistry& propertyRegistry() const final { return m_propertyRegistry; }
 
+    void childrenChanged(const ChildChange&) override;
+
     Vector<AtomString> filterEffectInputsNames() const override;
-    RefPtr<FilterEffect> filterEffect(const FilterEffectVector&, const GraphicsContext& destinationContext) const override;
+    RefPtr<FilterEffect> createFilterEffect(const FilterEffectVector&, const GraphicsContext& destinationContext) const override;
 
     PropertyRegistry m_propertyRegistry { *this };
 };

Modified: trunk/Source/WebCore/svg/SVGFEMorphologyElement.cpp (295497 => 295498)


--- trunk/Source/WebCore/svg/SVGFEMorphologyElement.cpp	2022-06-13 19:23:41 UTC (rev 295497)
+++ trunk/Source/WebCore/svg/SVGFEMorphologyElement.cpp	2022-06-13 19:52:35 UTC (rev 295498)
@@ -80,15 +80,15 @@
     SVGFilterPrimitiveStandardAttributes::parseAttribute(name, value);
 }
 
-bool SVGFEMorphologyElement::setFilterEffectAttribute(FilterEffect* effect, const QualifiedName& attrName)
+bool SVGFEMorphologyElement::setFilterEffectAttribute(FilterEffect& effect, const QualifiedName& attrName)
 {
-    FEMorphology* morphology = static_cast<FEMorphology*>(effect);
+    auto& feMorphology = downcast<FEMorphology>(effect);
     if (attrName == SVGNames::operatorAttr)
-        return morphology->setMorphologyOperator(svgOperator());
+        return feMorphology.setMorphologyOperator(svgOperator());
     if (attrName == SVGNames::radiusAttr) {
         // Both setRadius functions should be evaluated separately.
-        bool isRadiusXChanged = morphology->setRadiusX(radiusX());
-        bool isRadiusYChanged = morphology->setRadiusY(radiusY());
+        bool isRadiusXChanged = feMorphology.setRadiusX(radiusX());
+        bool isRadiusYChanged = feMorphology.setRadiusY(radiusY());
         return isRadiusXChanged || isRadiusYChanged;
     }
 
@@ -98,21 +98,22 @@
 
 void SVGFEMorphologyElement::svgAttributeChanged(const QualifiedName& attrName)
 {
-    if (PropertyRegistry::isKnownAttribute(attrName)) {
+    if (attrName == SVGNames::inAttr) {
         InstanceInvalidationGuard guard(*this);
-        if (attrName == SVGNames::inAttr)
-            updateSVGRendererForElementChange();
-        else {
-            ASSERT(attrName == SVGNames::operatorAttr || attrName == SVGNames::radiusAttr);
-            primitiveAttributeChanged(attrName);
-        }
+        updateSVGRendererForElementChange();
         return;
     }
 
+    if (attrName == SVGNames::operatorAttr || attrName == SVGNames::radiusAttr) {
+        InstanceInvalidationGuard guard(*this);
+        primitiveAttributeChanged(attrName);
+        return;
+    }
+
     SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName);
 }
 
-RefPtr<FilterEffect> SVGFEMorphologyElement::filterEffect(const FilterEffectVector&, const GraphicsContext&) const
+RefPtr<FilterEffect> SVGFEMorphologyElement::createFilterEffect(const FilterEffectVector&, const GraphicsContext&) const
 {
     if (radiusX() < 0 || radiusY() < 0)
         return nullptr;

Modified: trunk/Source/WebCore/svg/SVGFEMorphologyElement.h (295497 => 295498)


--- trunk/Source/WebCore/svg/SVGFEMorphologyElement.h	2022-06-13 19:23:41 UTC (rev 295497)
+++ trunk/Source/WebCore/svg/SVGFEMorphologyElement.h	2022-06-13 19:52:35 UTC (rev 295498)
@@ -80,9 +80,9 @@
     void parseAttribute(const QualifiedName&, const AtomString&) override;
     void svgAttributeChanged(const QualifiedName&) override;
 
-    bool setFilterEffectAttribute(FilterEffect*, const QualifiedName&) override;
+    bool setFilterEffectAttribute(FilterEffect&, const QualifiedName&) override;
     Vector<AtomString> filterEffectInputsNames() const override { return { AtomString { in1() } }; }
-    RefPtr<FilterEffect> filterEffect(const FilterEffectVector&, const GraphicsContext& destinationContext) const override;
+    RefPtr<FilterEffect> createFilterEffect(const FilterEffectVector&, const GraphicsContext& destinationContext) const override;
 
     PropertyRegistry m_propertyRegistry { *this };
     Ref<SVGAnimatedString> m_in1 { SVGAnimatedString::create(this) };

Modified: trunk/Source/WebCore/svg/SVGFEOffsetElement.cpp (295497 => 295498)


--- trunk/Source/WebCore/svg/SVGFEOffsetElement.cpp	2022-06-13 19:23:41 UTC (rev 295497)
+++ trunk/Source/WebCore/svg/SVGFEOffsetElement.cpp	2022-06-13 19:52:35 UTC (rev 295498)
@@ -70,15 +70,34 @@
 
 void SVGFEOffsetElement::svgAttributeChanged(const QualifiedName& attrName)
 {
-    if (PropertyRegistry::isKnownAttribute(attrName)) {
+    if (attrName == SVGNames::inAttr) {
         InstanceInvalidationGuard guard(*this);
         updateSVGRendererForElementChange();
         return;
     }
 
+    if (attrName == SVGNames::dxAttr || attrName == SVGNames::dyAttr) {
+        InstanceInvalidationGuard guard(*this);
+        primitiveAttributeChanged(attrName);
+        return;
+    }
+
     SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName);
 }
 
+bool SVGFEOffsetElement::setFilterEffectAttribute(FilterEffect& effect, const QualifiedName& attrName)
+{
+    auto& offset = downcast<FEOffset>(effect);
+
+    if (attrName == SVGNames::dxAttr)
+        return offset.setDx(dx());
+    if (attrName == SVGNames::dyAttr)
+        return offset.setDy(dy());
+
+    ASSERT_NOT_REACHED();
+    return false;
+}
+
 IntOutsets SVGFEOffsetElement::outsets(const FloatRect& targetBoundingBox, SVGUnitTypes::SVGUnitType primitiveUnits) const
 {
     auto offset = SVGFilter::calculateResolvedSize({ dx(), dy() }, targetBoundingBox, primitiveUnits);
@@ -85,7 +104,7 @@
     return FEOffset::calculateOutsets(offset);
 }
 
-RefPtr<FilterEffect> SVGFEOffsetElement::filterEffect(const FilterEffectVector&, const GraphicsContext&) const
+RefPtr<FilterEffect> SVGFEOffsetElement::createFilterEffect(const FilterEffectVector&, const GraphicsContext&) const
 {
     return FEOffset::create(dx(), dy());
 }

Modified: trunk/Source/WebCore/svg/SVGFEOffsetElement.h (295497 => 295498)


--- trunk/Source/WebCore/svg/SVGFEOffsetElement.h	2022-06-13 19:23:41 UTC (rev 295497)
+++ trunk/Source/WebCore/svg/SVGFEOffsetElement.h	2022-06-13 19:52:35 UTC (rev 295498)
@@ -47,9 +47,10 @@
     void parseAttribute(const QualifiedName&, const AtomString&) override;
     void svgAttributeChanged(const QualifiedName&) override;
 
+    bool setFilterEffectAttribute(FilterEffect&, const QualifiedName&) override;
     Vector<AtomString> filterEffectInputsNames() const override { return { AtomString { in1() } }; }
     IntOutsets outsets(const FloatRect& targetBoundingBox, SVGUnitTypes::SVGUnitType primitiveUnits) const override;
-    RefPtr<FilterEffect> filterEffect(const FilterEffectVector&, const GraphicsContext& destinationContext) const override;
+    RefPtr<FilterEffect> createFilterEffect(const FilterEffectVector&, const GraphicsContext& destinationContext) const override;
 
     PropertyRegistry m_propertyRegistry { *this };
     Ref<SVGAnimatedString> m_in1 { SVGAnimatedString::create(this) };

Modified: trunk/Source/WebCore/svg/SVGFESpecularLightingElement.cpp (295497 => 295498)


--- trunk/Source/WebCore/svg/SVGFESpecularLightingElement.cpp	2022-06-13 19:23:41 UTC (rev 295497)
+++ trunk/Source/WebCore/svg/SVGFESpecularLightingElement.cpp	2022-06-13 19:52:35 UTC (rev 295498)
@@ -87,24 +87,24 @@
     SVGFilterPrimitiveStandardAttributes::parseAttribute(name, value);
 }
 
-bool SVGFESpecularLightingElement::setFilterEffectAttribute(FilterEffect* effect, const QualifiedName& attrName)
+bool SVGFESpecularLightingElement::setFilterEffectAttribute(FilterEffect& effect, const QualifiedName& attrName)
 {
-    FESpecularLighting* specularLighting = static_cast<FESpecularLighting*>(effect);
+    auto& feSpecularLighting = downcast<FESpecularLighting>(effect);
 
     if (attrName == SVGNames::lighting_colorAttr) {
         RenderObject* renderer = this->renderer();
         ASSERT(renderer);
         Color color = renderer->style().colorByApplyingColorFilter(renderer->style().svgStyle().lightingColor());
-        return specularLighting->setLightingColor(color);
+        return feSpecularLighting.setLightingColor(color);
     }
     if (attrName == SVGNames::surfaceScaleAttr)
-        return specularLighting->setSurfaceScale(surfaceScale());
+        return feSpecularLighting.setSurfaceScale(surfaceScale());
     if (attrName == SVGNames::specularConstantAttr)
-        return specularLighting->setSpecularConstant(specularConstant());
+        return feSpecularLighting.setSpecularConstant(specularConstant());
     if (attrName == SVGNames::specularExponentAttr)
-        return specularLighting->setSpecularExponent(specularExponent());
+        return feSpecularLighting.setSpecularExponent(specularExponent());
 
-    auto& lightSource = const_cast<LightSource&>(specularLighting->lightSource());
+    auto& lightSource = const_cast<LightSource&>(feSpecularLighting.lightSource());
     const SVGFELightElement* lightElement = SVGFELightElement::findLightElement(this);
     ASSERT(lightElement);
 
@@ -158,7 +158,7 @@
     primitiveAttributeChanged(attrName);
 }
 
-RefPtr<FilterEffect> SVGFESpecularLightingElement::filterEffect(const FilterEffectVector&, const GraphicsContext&) const
+RefPtr<FilterEffect> SVGFESpecularLightingElement::createFilterEffect(const FilterEffectVector&, const GraphicsContext&) const
 {
     RefPtr lightElement = SVGFELightElement::findLightElement(this);
     if (!lightElement)

Modified: trunk/Source/WebCore/svg/SVGFESpecularLightingElement.h (295497 => 295498)


--- trunk/Source/WebCore/svg/SVGFESpecularLightingElement.h	2022-06-13 19:23:41 UTC (rev 295497)
+++ trunk/Source/WebCore/svg/SVGFESpecularLightingElement.h	2022-06-13 19:52:35 UTC (rev 295498)
@@ -57,9 +57,9 @@
     void parseAttribute(const QualifiedName&, const AtomString&) override;
     void svgAttributeChanged(const QualifiedName&) override;
 
-    bool setFilterEffectAttribute(FilterEffect*, const QualifiedName&) override;
+    bool setFilterEffectAttribute(FilterEffect&, const QualifiedName&) override;
     Vector<AtomString> filterEffectInputsNames() const override { return { AtomString { in1() } }; }
-    RefPtr<FilterEffect> filterEffect(const FilterEffectVector&, const GraphicsContext& destinationContext) const override;
+    RefPtr<FilterEffect> createFilterEffect(const FilterEffectVector&, const GraphicsContext& destinationContext) const override;
 
     PropertyRegistry m_propertyRegistry { *this };
     Ref<SVGAnimatedString> m_in1 { SVGAnimatedString::create(this) };

Modified: trunk/Source/WebCore/svg/SVGFETileElement.cpp (295497 => 295498)


--- trunk/Source/WebCore/svg/SVGFETileElement.cpp	2022-06-13 19:23:41 UTC (rev 295497)
+++ trunk/Source/WebCore/svg/SVGFETileElement.cpp	2022-06-13 19:52:35 UTC (rev 295498)
@@ -68,7 +68,7 @@
     SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName);
 }
 
-RefPtr<FilterEffect> SVGFETileElement::filterEffect(const FilterEffectVector&, const GraphicsContext&) const
+RefPtr<FilterEffect> SVGFETileElement::createFilterEffect(const FilterEffectVector&, const GraphicsContext&) const
 {
     return FETile::create();
 }

Modified: trunk/Source/WebCore/svg/SVGFETileElement.h (295497 => 295498)


--- trunk/Source/WebCore/svg/SVGFETileElement.h	2022-06-13 19:23:41 UTC (rev 295497)
+++ trunk/Source/WebCore/svg/SVGFETileElement.h	2022-06-13 19:52:35 UTC (rev 295498)
@@ -43,7 +43,7 @@
     void svgAttributeChanged(const QualifiedName&) override;
 
     Vector<AtomString> filterEffectInputsNames() const override { return { AtomString { in1() } }; }
-    RefPtr<FilterEffect> filterEffect(const FilterEffectVector&, const GraphicsContext& destinationContext) const override;
+    RefPtr<FilterEffect> createFilterEffect(const FilterEffectVector&, const GraphicsContext& destinationContext) const override;
 
     PropertyRegistry m_propertyRegistry { *this };
     Ref<SVGAnimatedString> m_in1 { SVGAnimatedString::create(this) };

Modified: trunk/Source/WebCore/svg/SVGFETurbulenceElement.cpp (295497 => 295498)


--- trunk/Source/WebCore/svg/SVGFETurbulenceElement.cpp	2022-06-13 19:23:41 UTC (rev 295497)
+++ trunk/Source/WebCore/svg/SVGFETurbulenceElement.cpp	2022-06-13 19:52:35 UTC (rev 295498)
@@ -88,19 +88,22 @@
     SVGFilterPrimitiveStandardAttributes::parseAttribute(name, value);
 }
 
-bool SVGFETurbulenceElement::setFilterEffectAttribute(FilterEffect* effect, const QualifiedName& attrName)
+bool SVGFETurbulenceElement::setFilterEffectAttribute(FilterEffect& effect, const QualifiedName& attrName)
 {
-    FETurbulence* turbulence = static_cast<FETurbulence*>(effect);
+    auto& feTurbulence = downcast<FETurbulence>(effect);
     if (attrName == SVGNames::typeAttr)
-        return turbulence->setType(type());
+        return feTurbulence.setType(type());
     if (attrName == SVGNames::stitchTilesAttr)
-        return turbulence->setStitchTiles(stitchTiles());
-    if (attrName == SVGNames::baseFrequencyAttr)
-        return (turbulence->setBaseFrequencyX(baseFrequencyX()) || turbulence->setBaseFrequencyY(baseFrequencyY()));
+        return feTurbulence.setStitchTiles(stitchTiles());
+    if (attrName == SVGNames::baseFrequencyAttr) {
+        bool baseFrequencyXChanged = feTurbulence.setBaseFrequencyX(baseFrequencyX());
+        bool baseFrequencyYChanged = feTurbulence.setBaseFrequencyY(baseFrequencyY());
+        return baseFrequencyXChanged || baseFrequencyYChanged;
+    }
     if (attrName == SVGNames::seedAttr)
-        return turbulence->setSeed(seed());
+        return feTurbulence.setSeed(seed());
     if (attrName == SVGNames::numOctavesAttr)
-        return turbulence->setNumOctaves(numOctaves());
+        return feTurbulence.setNumOctaves(numOctaves());
 
     ASSERT_NOT_REACHED();
     return false;
@@ -117,7 +120,7 @@
     SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName);
 }
 
-RefPtr<FilterEffect> SVGFETurbulenceElement::filterEffect(const FilterEffectVector&, const GraphicsContext&) const
+RefPtr<FilterEffect> SVGFETurbulenceElement::createFilterEffect(const FilterEffectVector&, const GraphicsContext&) const
 {
     if (baseFrequencyX() < 0 || baseFrequencyY() < 0)
         return nullptr;

Modified: trunk/Source/WebCore/svg/SVGFETurbulenceElement.h (295497 => 295498)


--- trunk/Source/WebCore/svg/SVGFETurbulenceElement.h	2022-06-13 19:23:41 UTC (rev 295497)
+++ trunk/Source/WebCore/svg/SVGFETurbulenceElement.h	2022-06-13 19:52:35 UTC (rev 295498)
@@ -118,8 +118,8 @@
     void parseAttribute(const QualifiedName&, const AtomString&) override;
     void svgAttributeChanged(const QualifiedName&) override;
 
-    bool setFilterEffectAttribute(FilterEffect*, const QualifiedName& attrName) override;
-    RefPtr<FilterEffect> filterEffect(const FilterEffectVector&, const GraphicsContext& destinationContext) const override;
+    bool setFilterEffectAttribute(FilterEffect&, const QualifiedName& attrName) override;
+    RefPtr<FilterEffect> createFilterEffect(const FilterEffectVector&, const GraphicsContext& destinationContext) const override;
 
     PropertyRegistry m_propertyRegistry { *this };
     Ref<SVGAnimatedNumber> m_baseFrequencyX { SVGAnimatedNumber::create(this) };

Modified: trunk/Source/WebCore/svg/SVGFilterPrimitiveStandardAttributes.cpp (295497 => 295498)


--- trunk/Source/WebCore/svg/SVGFilterPrimitiveStandardAttributes.cpp	2022-06-13 19:23:41 UTC (rev 295497)
+++ trunk/Source/WebCore/svg/SVGFilterPrimitiveStandardAttributes.cpp	2022-06-13 19:52:35 UTC (rev 295498)
@@ -2,7 +2,7 @@
  * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <[email protected]>
  * Copyright (C) 2004, 2005, 2006 Rob Buis <[email protected]>
  * Copyright (C) 2009 Dirk Schulze <[email protected]>
- * Copyright (C) 2018-2019 Apple Inc. All rights reserved.
+ * Copyright (C) 2018-2022 Apple Inc. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -66,13 +66,30 @@
     SVGElement::parseAttribute(name, value);
 }
 
-bool SVGFilterPrimitiveStandardAttributes::setFilterEffectAttribute(FilterEffect*, const QualifiedName&)
+RefPtr<FilterEffect> SVGFilterPrimitiveStandardAttributes::filterEffect(const FilterEffectVector& inputs, const GraphicsContext& destinationContext)
 {
-    // When all filters support this method, it will be changed to a pure virtual method.
-    ASSERT_NOT_REACHED();
-    return false;
+    if (!m_effect)
+        m_effect = createFilterEffect(inputs, destinationContext);
+    return m_effect;
 }
 
+void SVGFilterPrimitiveStandardAttributes::primitiveAttributeChanged(const QualifiedName& attribute)
+{
+    if (m_effect && !setFilterEffectAttribute(*m_effect, attribute))
+        return;
+
+    if (auto* renderer = this->renderer())
+        static_cast<RenderSVGResourceFilterPrimitive*>(renderer)->markFilterEffectForRepaint(m_effect.get());
+}
+
+void SVGFilterPrimitiveStandardAttributes::markFilterEffectForRebuild()
+{
+    if (auto* renderer = this->renderer())
+        static_cast<RenderSVGResourceFilterPrimitive*>(renderer)->markFilterEffectForRebuild();
+
+    m_effect = nullptr;
+}
+
 void SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(const QualifiedName& attrName)
 {
     if (PropertyRegistry::isKnownAttribute(attrName)) {

Modified: trunk/Source/WebCore/svg/SVGFilterPrimitiveStandardAttributes.h (295497 => 295498)


--- trunk/Source/WebCore/svg/SVGFilterPrimitiveStandardAttributes.h	2022-06-13 19:23:41 UTC (rev 295497)
+++ trunk/Source/WebCore/svg/SVGFilterPrimitiveStandardAttributes.h	2022-06-13 19:52:35 UTC (rev 295498)
@@ -50,11 +50,12 @@
     SVGAnimatedLength& heightAnimated() { return m_height; }
     SVGAnimatedString& resultAnimated() { return m_result; }
 
-    // Returns true, if the new value is different from the old one.
-    virtual bool setFilterEffectAttribute(FilterEffect*, const QualifiedName&);
+    void primitiveAttributeChanged(const QualifiedName&);
+    void markFilterEffectForRebuild();
+
     virtual Vector<AtomString> filterEffectInputsNames() const { return { }; }
     virtual IntOutsets outsets(const FloatRect&, SVGUnitTypes::SVGUnitType) const { return { }; }
-    virtual RefPtr<FilterEffect> filterEffect(const FilterEffectVector&, const GraphicsContext& destinationContext) const = 0;
+    RefPtr<FilterEffect> filterEffect(const FilterEffectVector&, const GraphicsContext& destinationContext);
 
     static void invalidateFilterPrimitiveParent(SVGElement*);
 
@@ -65,7 +66,8 @@
     void svgAttributeChanged(const QualifiedName&) override;
     void childrenChanged(const ChildChange&) override;
 
-    void primitiveAttributeChanged(const QualifiedName& attributeName);
+    virtual bool setFilterEffectAttribute(FilterEffect&, const QualifiedName&) { return false; }
+    virtual RefPtr<FilterEffect> createFilterEffect(const FilterEffectVector&, const GraphicsContext& destinationContext) const = 0;
 
 private:
     bool isFilterEffect() const override { return true; }
@@ -74,6 +76,8 @@
     bool rendererIsNeeded(const RenderStyle&) override;
     bool childShouldCreateRenderer(const Node&) const override { return false; }
 
+    RefPtr<FilterEffect> m_effect;
+
     // Spec: If the x/y attribute is not specified, the effect is as if a value of "0%" were specified.
     // Spec: If the width/height attribute is not specified, the effect is as if a value of "100%" were specified.
     Ref<SVGAnimatedLength> m_x { SVGAnimatedLength::create(this, SVGLengthMode::Width, "0%"_s) };
@@ -83,12 +87,6 @@
     Ref<SVGAnimatedString> m_result { SVGAnimatedString::create(this) };
 };
 
-inline void SVGFilterPrimitiveStandardAttributes::primitiveAttributeChanged(const QualifiedName& attribute)
-{
-    if (auto* primitiveRenderer = renderer())
-        static_cast<RenderSVGResourceFilterPrimitive*>(primitiveRenderer)->primitiveAttributeChanged(attribute);
-}
-
 } // namespace WebCore
 
 SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::SVGFilterPrimitiveStandardAttributes)

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


--- trunk/Source/WebCore/svg/graphics/filters/SVGFilter.cpp	2022-06-13 19:23:41 UTC (rev 295497)
+++ trunk/Source/WebCore/svg/graphics/filters/SVGFilter.cpp	2022-06-13 19:52:35 UTC (rev 295498)
@@ -31,11 +31,11 @@
 
 namespace WebCore {
 
-RefPtr<SVGFilter> SVGFilter::create(SVGFilterElement& filterElement, SVGFilterBuilder& builder, RenderingMode renderingMode, const FloatSize& filterScale, ClipOperation clipOperation, const FloatRect& filterRegion, const FloatRect& targetBoundingBox, const GraphicsContext& destinationContext)
+RefPtr<SVGFilter> SVGFilter::create(SVGFilterElement& filterElement, RenderingMode renderingMode, const FloatSize& filterScale, ClipOperation clipOperation, const FloatRect& filterRegion, const FloatRect& targetBoundingBox, const GraphicsContext& destinationContext)
 {
     auto filter = adoptRef(*new SVGFilter(renderingMode, filterScale, clipOperation, filterRegion, targetBoundingBox, filterElement.primitiveUnits()));
 
-    auto _expression_ = builder.buildFilterExpression(filterElement, filter, destinationContext);
+    auto _expression_ = SVGFilterBuilder::buildFilterExpression(filterElement, filter, destinationContext);
     if (!_expression_)
         return nullptr;
 

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


--- trunk/Source/WebCore/svg/graphics/filters/SVGFilter.h	2022-06-13 19:23:41 UTC (rev 295497)
+++ trunk/Source/WebCore/svg/graphics/filters/SVGFilter.h	2022-06-13 19:52:35 UTC (rev 295498)
@@ -32,12 +32,11 @@
 
 class FilterImage;
 class GraphicsContext;
-class SVGFilterBuilder;
 class SVGFilterElement;
 
 class SVGFilter final : public Filter {
 public:
-    static RefPtr<SVGFilter> create(SVGFilterElement&, SVGFilterBuilder&, RenderingMode, const FloatSize& filterScale, ClipOperation, const FloatRect& filterRegion, const FloatRect& targetBoundingBox, const GraphicsContext& destinationContext);
+    static RefPtr<SVGFilter> create(SVGFilterElement&, RenderingMode, const FloatSize& filterScale, ClipOperation, const FloatRect& filterRegion, const FloatRect& targetBoundingBox, const GraphicsContext& destinationContext);
     WEBCORE_EXPORT static RefPtr<SVGFilter> create(const FloatRect& targetBoundingBox, SVGUnitTypes::SVGUnitType primitiveUnits, SVGFilterExpression&&);
 
     FloatRect targetBoundingBox() const { return m_targetBoundingBox; }

Modified: trunk/Source/WebCore/svg/graphics/filters/SVGFilterBuilder.cpp (295497 => 295498)


--- trunk/Source/WebCore/svg/graphics/filters/SVGFilterBuilder.cpp	2022-06-13 19:23:41 UTC (rev 295497)
+++ trunk/Source/WebCore/svg/graphics/filters/SVGFilterBuilder.cpp	2022-06-13 19:52:35 UTC (rev 295498)
@@ -98,9 +98,6 @@
             effect->setOperatingColorSpace(DestinationColorSpace::LinearSRGB());
 #endif
 
-        if (auto renderer = effectElement.renderer())
-            m_effectRenderer.add(renderer, effect.get());
-
         graph.addNamedNode(AtomString { effectElement.result() }, { *effect });
         graph.setNodeInputs(*effect, WTFMove(*inputs));
     }

Modified: trunk/Source/WebCore/svg/graphics/filters/SVGFilterBuilder.h (295497 => 295498)


--- trunk/Source/WebCore/svg/graphics/filters/SVGFilterBuilder.h	2022-06-13 19:23:41 UTC (rev 295497)
+++ trunk/Source/WebCore/svg/graphics/filters/SVGFilterBuilder.h	2022-06-13 19:52:35 UTC (rev 295498)
@@ -23,7 +23,6 @@
 
 #include "SVGFilterExpression.h"
 #include "SVGUnitTypes.h"
-#include <wtf/HashMap.h>
 
 namespace WebCore {
 
@@ -34,18 +33,9 @@
 class SVGFilterElement;
 
 class SVGFilterBuilder {
-    WTF_MAKE_FAST_ALLOCATED;
 public:
-    SVGFilterBuilder() = default;
-
-    std::optional<SVGFilterExpression> buildFilterExpression(SVGFilterElement&, const SVGFilter&, const GraphicsContext& destinationContext);
+    static std::optional<SVGFilterExpression> buildFilterExpression(SVGFilterElement&, const SVGFilter&, const GraphicsContext& destinationContext);
     static IntOutsets calculateFilterOutsets(SVGFilterElement&, const FloatRect& targetBoundingBox);
-
-    // Required to change the attributes of a filter during an svgAttributeChanged.
-    FilterEffect* effectByRenderer(RenderObject* object) { return m_effectRenderer.get(object); }
-
-private:
-    HashMap<RenderObject*, FilterEffect*> m_effectRenderer;
 };
     
 } // namespace WebCore
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to