[SCM] WebKit Debian packaging branch, webkit-1.3, updated. upstream/1.3.7-4207-g178b198

zherczeg at webkit.org zherczeg at webkit.org
Sun Feb 20 23:48:29 UTC 2011


The following commit has been merged in the webkit-1.3 branch:
commit dde95236edd010864d1a098318fd00e3d8cb20a5
Author: zherczeg at webkit.org <zherczeg at webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Tue Jan 25 15:10:44 2011 +0000

    Repaint SVG elements with filter instead of relayout where possible
    https://bugs.webkit.org/show_bug.cgi?id=52200
    
    Reviewed by Dirk Schulze.
    
    This patch allows repainting of filters, when their
    attribute changes does not require relayout.
    
    Existing dynamic-update tests cover this feature.
    
    * platform/graphics/filters/FilterEffect.cpp:
    (WebCore::FilterEffect::clearResult): Clearing the currently stored image
    before repainting.
    * platform/graphics/filters/FilterEffect.h:
    * rendering/RenderObject.h:
    (WebCore::RenderObject::isSVGResourceFilter): Not only the filter primitives,
    but filters should also be detected to allow safe testing and casting.
    * rendering/svg/RenderSVGResourceFilter.cpp:
    (WebCore::RenderSVGResourceFilter::buildPrimitives): Passing the renderer.
    (WebCore::RenderSVGResourceFilter::applyResource):
    determineFilterPrimitiveSubregion does not require the filter anymore.
    (WebCore::RenderSVGResourceFilter::postApplyResource): Repaint
    if lastEffect->hasResult() is false.
    (WebCore::RenderSVGResourceFilter::primitiveAttributeChanged):
    Searching for all FilterEffects, whose created by the current FilterElement,
    and clearing all resulting images depending on those FilterEffects.
    * rendering/svg/RenderSVGResourceFilter.h:
    (WebCore::RenderSVGResourceFilter::isSVGResourceFilter):
    * rendering/svg/RenderSVGResourceFilterPrimitive.cpp:
    (WebCore::RenderSVGResourceFilterPrimitive::determineFilterPrimitiveSubregion):
    The filter argument is unnecessary anymore. But is is still kept as a static
    member, since the primitive renderer still does not know about the
    FilterEffect objects.
    * rendering/svg/RenderSVGResourceFilterPrimitive.h:
    (WebCore::RenderSVGResourceFilterPrimitive::RenderSVGResourceFilterPrimitive):
    (WebCore::RenderSVGResourceFilterPrimitive::primitiveAttributeChanged):
    Calls RenderSVGResourceFilter::primitiveAttributeChanged.
    * svg/SVGFEDiffuseLightingElement.cpp:
    (WebCore::SVGFEDiffuseLightingElement::setFilterEffectAttribute):
    Setting the new attribute value for each FilterEffect.
    (WebCore::SVGFEDiffuseLightingElement::svgAttributeChanged):
    * svg/SVGFEDiffuseLightingElement.h:
    Calling primitiveAttributeChanged.
    * svg/SVGFilterPrimitiveStandardAttributes.cpp:
    (WebCore::SVGFilterPrimitiveStandardAttributes::setFilterEffectAttribute):
    This function will be removed when all FilterElement implements
    their setFilterEffectAttribute
    * svg/SVGFilterPrimitiveStandardAttributes.h:
    (WebCore::SVGFilterPrimitiveStandardAttributes::primitiveAttributeChanged):
    * svg/graphics/filters/SVGFilterBuilder.cpp:
    (WebCore::SVGFilterBuilder::appendEffectToEffectReferences): The
    renderers are assigned to the filter effects.
    (WebCore::SVGFilterBuilder::clearEffects):
    (WebCore::SVGFilterBuilder::clearResultsRecursive): Recursively
    clearing the result images for those filters, whose depend on
    the starting filter.
    * svg/graphics/filters/SVGFilterBuilder.h:
    (WebCore::SVGFilterBuilder::effectReferences): 'get' is unnecessary
    (WebCore::SVGFilterBuilder::effectByRenderer): returns the
    FilterEffect belongs to this RenderObject.
    
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@76590 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index 5c6c83f..b627bef 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,66 @@
+2011-01-25  Zoltan Herczeg  <zherczeg at webkit.org>
+
+        Reviewed by Dirk Schulze.
+
+        Repaint SVG elements with filter instead of relayout where possible
+        https://bugs.webkit.org/show_bug.cgi?id=52200
+
+        This patch allows repainting of filters, when their
+        attribute changes does not require relayout.
+
+        Existing dynamic-update tests cover this feature.
+
+        * platform/graphics/filters/FilterEffect.cpp:
+        (WebCore::FilterEffect::clearResult): Clearing the currently stored image
+        before repainting.
+        * platform/graphics/filters/FilterEffect.h:
+        * rendering/RenderObject.h:
+        (WebCore::RenderObject::isSVGResourceFilter): Not only the filter primitives,
+        but filters should also be detected to allow safe testing and casting.
+        * rendering/svg/RenderSVGResourceFilter.cpp:
+        (WebCore::RenderSVGResourceFilter::buildPrimitives): Passing the renderer.
+        (WebCore::RenderSVGResourceFilter::applyResource):
+        determineFilterPrimitiveSubregion does not require the filter anymore.
+        (WebCore::RenderSVGResourceFilter::postApplyResource): Repaint
+        if lastEffect->hasResult() is false.
+        (WebCore::RenderSVGResourceFilter::primitiveAttributeChanged):
+        Searching for all FilterEffects, whose created by the current FilterElement,
+        and clearing all resulting images depending on those FilterEffects.
+        * rendering/svg/RenderSVGResourceFilter.h:
+        (WebCore::RenderSVGResourceFilter::isSVGResourceFilter):
+        * rendering/svg/RenderSVGResourceFilterPrimitive.cpp:
+        (WebCore::RenderSVGResourceFilterPrimitive::determineFilterPrimitiveSubregion):
+        The filter argument is unnecessary anymore. But is is still kept as a static
+        member, since the primitive renderer still does not know about the
+        FilterEffect objects.
+        * rendering/svg/RenderSVGResourceFilterPrimitive.h:
+        (WebCore::RenderSVGResourceFilterPrimitive::RenderSVGResourceFilterPrimitive):
+        (WebCore::RenderSVGResourceFilterPrimitive::primitiveAttributeChanged):
+        Calls RenderSVGResourceFilter::primitiveAttributeChanged.
+        * svg/SVGFEDiffuseLightingElement.cpp:
+        (WebCore::SVGFEDiffuseLightingElement::setFilterEffectAttribute):
+        Setting the new attribute value for each FilterEffect.
+        (WebCore::SVGFEDiffuseLightingElement::svgAttributeChanged):
+        * svg/SVGFEDiffuseLightingElement.h:
+        Calling primitiveAttributeChanged.
+        * svg/SVGFilterPrimitiveStandardAttributes.cpp:
+        (WebCore::SVGFilterPrimitiveStandardAttributes::setFilterEffectAttribute):
+        This function will be removed when all FilterElement implements
+        their setFilterEffectAttribute
+        * svg/SVGFilterPrimitiveStandardAttributes.h:
+        (WebCore::SVGFilterPrimitiveStandardAttributes::primitiveAttributeChanged):
+        * svg/graphics/filters/SVGFilterBuilder.cpp:
+        (WebCore::SVGFilterBuilder::appendEffectToEffectReferences): The
+        renderers are assigned to the filter effects.
+        (WebCore::SVGFilterBuilder::clearEffects):
+        (WebCore::SVGFilterBuilder::clearResultsRecursive): Recursively
+        clearing the result images for those filters, whose depend on
+        the starting filter.
+        * svg/graphics/filters/SVGFilterBuilder.h:
+        (WebCore::SVGFilterBuilder::effectReferences): 'get' is unnecessary
+        (WebCore::SVGFilterBuilder::effectByRenderer): returns the
+        FilterEffect belongs to this RenderObject.
+
 2011-01-25  Dirk Schulze  <krit at webkit.org>
 
         Reviewed by Nikolas Zimmermann.
diff --git a/Source/WebCore/platform/graphics/filters/FilterEffect.cpp b/Source/WebCore/platform/graphics/filters/FilterEffect.cpp
index 85154b5..a84fab8 100644
--- a/Source/WebCore/platform/graphics/filters/FilterEffect.cpp
+++ b/Source/WebCore/platform/graphics/filters/FilterEffect.cpp
@@ -77,6 +77,16 @@ FilterEffect* FilterEffect::inputEffect(unsigned number) const
     return m_inputEffects.at(number).get();
 }
 
+void FilterEffect::clearResult()
+{
+    if (m_imageBufferResult)
+        m_imageBufferResult.clear();
+    if (m_unmultipliedImageResult)
+        m_unmultipliedImageResult.clear();
+    if (m_premultipliedImageResult)
+        m_premultipliedImageResult.clear();
+}
+
 ImageBuffer* FilterEffect::asImageBuffer()
 {
     if (!hasResult())
diff --git a/Source/WebCore/platform/graphics/filters/FilterEffect.h b/Source/WebCore/platform/graphics/filters/FilterEffect.h
index 062dd1b..2de8ac5 100644
--- a/Source/WebCore/platform/graphics/filters/FilterEffect.h
+++ b/Source/WebCore/platform/graphics/filters/FilterEffect.h
@@ -53,6 +53,7 @@ public:
     virtual ~FilterEffect();
 
     bool hasResult() const { return m_imageBufferResult || m_unmultipliedImageResult || m_premultipliedImageResult; }
+    void clearResult();
     ImageBuffer* asImageBuffer();
     PassRefPtr<ByteArray> asUnmultipliedImage(const IntRect&);
     PassRefPtr<ByteArray> asPremultipliedImage(const IntRect&);
diff --git a/Source/WebCore/rendering/RenderObject.h b/Source/WebCore/rendering/RenderObject.h
index f2e7f13..f65f217 100644
--- a/Source/WebCore/rendering/RenderObject.h
+++ b/Source/WebCore/rendering/RenderObject.h
@@ -332,6 +332,7 @@ public:
     virtual bool isSVGImage() const { return false; }
     virtual bool isSVGForeignObject() const { return false; }
     virtual bool isSVGResourceContainer() const { return false; }
+    virtual bool isSVGResourceFilter() const { return false; }
     virtual bool isSVGResourceFilterPrimitive() const { return false; }
     virtual bool isSVGShadowTreeRootContainer() const { return false; }
 
diff --git a/Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp b/Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp
index 4ba4e0a..ce95891 100644
--- a/Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp
@@ -111,7 +111,7 @@ PassRefPtr<SVGFilterBuilder> RenderSVGResourceFilter::buildPrimitives(Filter* fi
             builder->clearEffects();
             return 0;
         }
-        builder->appendEffectToEffectReferences(effect);
+        builder->appendEffectToEffectReferences(effect, effectElement->renderer());
         effectElement->setStandardAttributes(primitiveBoundingBoxMode, effect.get());
         builder->add(effectElement->result(), effect);
     }
@@ -208,13 +208,13 @@ bool RenderSVGResourceFilter::applyResource(RenderObject* object, RenderStyle*,
     if (!lastEffect)
         return false;
 
-    RenderSVGResourceFilterPrimitive::determineFilterPrimitiveSubregion(lastEffect, filterData->filter.get());
+    RenderSVGResourceFilterPrimitive::determineFilterPrimitiveSubregion(lastEffect);
     FloatRect subRegion = lastEffect->maxEffectRect();
     // At least one FilterEffect has a too big image size,
     // recalculate the effect sizes with new scale factors.
     if (!fitsInMaximumImageSize(subRegion.size(), scale)) {
         filterData->filter->setFilterResolution(scale);
-        RenderSVGResourceFilterPrimitive::determineFilterPrimitiveSubregion(lastEffect, filterData->filter.get());
+        RenderSVGResourceFilterPrimitive::determineFilterPrimitiveSubregion(lastEffect);
     }
 
     // If the drawingRegion is empty, we have something like <g filter=".."/>.
@@ -290,16 +290,19 @@ void RenderSVGResourceFilter::postApplyResource(RenderObject* object, GraphicsCo
         // This is the real filtering of the object. It just needs to be called on the
         // initial filtering process. We just take the stored filter result on a
         // second drawing.
-        if (!filterData->builded) {
+        if (!filterData->builded)
             filterData->filter->setSourceImage(filterData->sourceGraphicBuffer.release());
+
+        // Always true if filterData is just built (filterData->builded is false).
+        if (!lastEffect->hasResult()) {
             lastEffect->apply();
 #if !PLATFORM(CG)
             ImageBuffer* resultImage = lastEffect->asImageBuffer();
             if (resultImage)
                 resultImage->transformColorSpace(ColorSpaceLinearRGB, ColorSpaceDeviceRGB);
 #endif
-            filterData->builded = true;
         }
+        filterData->builded = true;
 
         ImageBuffer* resultImage = lastEffect->asImageBuffer();
         if (resultImage) {
@@ -324,5 +327,28 @@ FloatRect RenderSVGResourceFilter::resourceBoundingBox(RenderObject* object)
     return FloatRect();
 }
 
+void RenderSVGResourceFilter::primitiveAttributeChanged(RenderObject* object, const QualifiedName& attribute)
+{
+    HashMap<RenderObject*, FilterData*>::iterator it = m_filter.begin();
+    HashMap<RenderObject*, FilterData*>::iterator end = m_filter.end();
+    SVGFilterPrimitiveStandardAttributes* primitve = static_cast<SVGFilterPrimitiveStandardAttributes*>(object->node());
+
+    for (; it != end; ++it) {
+        FilterData* filterData = it->second;
+        if (!filterData->builded)
+            continue;
+
+        SVGFilterBuilder* builder = filterData->builder.get();
+        FilterEffect* effect = builder->effectByRenderer(object);
+        if (!effect)
+            continue;
+        primitve->setFilterEffectAttribute(effect, attribute);
+        builder->clearResultsRecursive(effect);
+
+        // Repaint the image on the screen.
+        markClientForInvalidation(it->first, RepaintInvalidation);
+    }
+}
+
 }
 #endif
diff --git a/Source/WebCore/rendering/svg/RenderSVGResourceFilter.h b/Source/WebCore/rendering/svg/RenderSVGResourceFilter.h
index f9a15ce..c809f23 100644
--- a/Source/WebCore/rendering/svg/RenderSVGResourceFilter.h
+++ b/Source/WebCore/rendering/svg/RenderSVGResourceFilter.h
@@ -64,6 +64,7 @@ public:
     virtual ~RenderSVGResourceFilter();
 
     virtual const char* renderName() const { return "RenderSVGResourceFilter"; }
+    virtual bool isSVGResourceFilter() const { return true; }
 
     virtual void removeAllClientsFromCache(bool markForInvalidation = true);
     virtual void removeClientFromCache(RenderObject*, bool markForInvalidation = true);
@@ -78,6 +79,8 @@ public:
     SVGUnitTypes::SVGUnitType filterUnits() const { return toUnitType(static_cast<SVGFilterElement*>(node())->filterUnits()); }
     SVGUnitTypes::SVGUnitType primitiveUnits() const { return toUnitType(static_cast<SVGFilterElement*>(node())->primitiveUnits()); }
 
+    void primitiveAttributeChanged(RenderObject*, const QualifiedName&);
+
     virtual RenderSVGResourceType resourceType() const { return s_resourceType; }
     static RenderSVGResourceType s_resourceType;
 
diff --git a/Source/WebCore/rendering/svg/RenderSVGResourceFilterPrimitive.cpp b/Source/WebCore/rendering/svg/RenderSVGResourceFilterPrimitive.cpp
index fc7362e..64df700 100644
--- a/Source/WebCore/rendering/svg/RenderSVGResourceFilterPrimitive.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGResourceFilterPrimitive.cpp
@@ -29,25 +29,29 @@
 #if ENABLE(SVG) && ENABLE(FILTERS)
 #include "RenderSVGResourceFilterPrimitive.h"
 
+#include "RenderSVGResource.h"
 #include "SVGFEImage.h"
+#include "SVGFilter.h"
 
 namespace WebCore {
 
-FloatRect RenderSVGResourceFilterPrimitive::determineFilterPrimitiveSubregion(FilterEffect* effect, SVGFilter* filter)
+FloatRect RenderSVGResourceFilterPrimitive::determineFilterPrimitiveSubregion(FilterEffect* effect)
 {
     FloatRect uniteRect;
     FloatRect subregionBoundingBox = effect->effectBoundaries();
     FloatRect subregion = subregionBoundingBox;
+    SVGFilter* filter = static_cast<SVGFilter*>(effect->filter());
+    ASSERT(filter);
 
     if (effect->filterEffectType() != FilterEffectTypeTile) {
         // FETurbulence, FEImage and FEFlood don't have input effects, take the filter region as unite rect.
         if (unsigned numberOfInputEffects = effect->inputEffects().size()) {
             for (unsigned i = 0; i < numberOfInputEffects; ++i)
-                uniteRect.unite(determineFilterPrimitiveSubregion(effect->inputEffect(i), filter));
+                uniteRect.unite(determineFilterPrimitiveSubregion(effect->inputEffect(i)));
         } else
             uniteRect = filter->filterRegionInUserSpace();
     } else {
-        determineFilterPrimitiveSubregion(effect->inputEffect(0), filter);
+        determineFilterPrimitiveSubregion(effect->inputEffect(0));
         uniteRect = filter->filterRegionInUserSpace();
     }
 
@@ -90,7 +94,7 @@ FloatRect RenderSVGResourceFilterPrimitive::determineFilterPrimitiveSubregion(Fi
     // FEImage needs the unclipped subregion in absolute coordinates to determine the correct
     // destination rect in combination with preserveAspectRatio.
     if (effect->filterEffectType() == FilterEffectTypeImage)
-        reinterpret_cast<FEImage*>(effect)->setAbsoluteSubregion(absoluteSubregion);
+        static_cast<FEImage*>(effect)->setAbsoluteSubregion(absoluteSubregion);
 
     // Clip every filter effect to the filter region.
     FloatRect absoluteScaledFilterRegion = filter->filterRegion();
diff --git a/Source/WebCore/rendering/svg/RenderSVGResourceFilterPrimitive.h b/Source/WebCore/rendering/svg/RenderSVGResourceFilterPrimitive.h
index f25f62e..8176d29 100644
--- a/Source/WebCore/rendering/svg/RenderSVGResourceFilterPrimitive.h
+++ b/Source/WebCore/rendering/svg/RenderSVGResourceFilterPrimitive.h
@@ -30,25 +30,32 @@
 #if ENABLE(SVG) && ENABLE(FILTERS)
 
 #include "RenderSVGHiddenContainer.h"
-#include "SVGFilter.h"
-#include "SVGFilterPrimitiveStandardAttributes.h"
+#include "RenderSVGResourceFilter.h"
 
 namespace WebCore {
 
+class FilterEffect;
+
 class RenderSVGResourceFilterPrimitive : public RenderSVGHiddenContainer {
 public:
-
-    explicit RenderSVGResourceFilterPrimitive(SVGFilterPrimitiveStandardAttributes* filterPrimitiveElement)
+    explicit RenderSVGResourceFilterPrimitive(SVGStyledElement* filterPrimitiveElement)
         : RenderSVGHiddenContainer(filterPrimitiveElement)
     {
     }
 
-    // They depend on the RenderObject argument of RenderSVGResourceFilter::applyResource.
-    static FloatRect determineFilterPrimitiveSubregion(FilterEffect*, SVGFilter*);
-
-private:
     virtual const char* renderName() const { return "RenderSVGResourceFilterPrimitive"; }
     virtual bool isSVGResourceFilterPrimitive() const { return true; }
+
+    // They depend on the RenderObject argument of RenderSVGResourceFilter::applyResource.
+    static FloatRect determineFilterPrimitiveSubregion(FilterEffect*);
+
+    inline void primitiveAttributeChanged(const QualifiedName& attribute)
+    {
+        RenderObject* filter = parent();
+        if (!filter || !filter->isSVGResourceFilter())
+            return;
+        static_cast<RenderSVGResourceFilter*>(filter)->primitiveAttributeChanged(this, attribute);
+    }
 };
 
 } // namespace WebCore
diff --git a/Source/WebCore/svg/SVGFEDiffuseLightingElement.cpp b/Source/WebCore/svg/SVGFEDiffuseLightingElement.cpp
index 49888da..10f7439 100644
--- a/Source/WebCore/svg/SVGFEDiffuseLightingElement.cpp
+++ b/Source/WebCore/svg/SVGFEDiffuseLightingElement.cpp
@@ -84,15 +84,30 @@ void SVGFEDiffuseLightingElement::parseMappedAttribute(Attribute* attr)
         SVGFilterPrimitiveStandardAttributes::parseMappedAttribute(attr);
 }
 
+void SVGFEDiffuseLightingElement::setFilterEffectAttribute(FilterEffect* effect, const QualifiedName& attrName)
+{
+    FEDiffuseLighting* diffuseLighting = static_cast<FEDiffuseLighting*>(effect);
+    if (attrName == SVGNames::surfaceScaleAttr)
+        diffuseLighting->setSurfaceScale(surfaceScale());
+    else if (attrName == SVGNames::diffuseConstantAttr)
+        diffuseLighting->setDiffuseConstant(diffuseConstant());
+    else if (attrName == SVGNames::lighting_colorAttr) {
+        RefPtr<RenderStyle> filterStyle = styleForRenderer();
+        diffuseLighting->setLightingColor(filterStyle->svgStyle()->lightingColor());
+    }
+}
+
 void SVGFEDiffuseLightingElement::svgAttributeChanged(const QualifiedName& attrName)
 {
     SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName);
 
-    if (attrName == SVGNames::inAttr
-        || attrName == SVGNames::surfaceScaleAttr
+    if (attrName == SVGNames::surfaceScaleAttr
         || attrName == SVGNames::diffuseConstantAttr
         || attrName == SVGNames::kernelUnitLengthAttr
         || attrName == SVGNames::lighting_colorAttr)
+        primitiveAttributeChanged(attrName);
+
+    if (attrName == SVGNames::inAttr)
         invalidate();
 }
 
diff --git a/Source/WebCore/svg/SVGFEDiffuseLightingElement.h b/Source/WebCore/svg/SVGFEDiffuseLightingElement.h
index d56ced9..e502831 100644
--- a/Source/WebCore/svg/SVGFEDiffuseLightingElement.h
+++ b/Source/WebCore/svg/SVGFEDiffuseLightingElement.h
@@ -39,6 +39,7 @@ private:
     SVGFEDiffuseLightingElement(const QualifiedName&, Document*);
 
     virtual void parseMappedAttribute(Attribute*);
+    virtual void setFilterEffectAttribute(FilterEffect*, const QualifiedName&);
     virtual void svgAttributeChanged(const QualifiedName&);
     virtual void synchronizeProperty(const QualifiedName&);
     virtual PassRefPtr<FilterEffect> build(SVGFilterBuilder*, Filter*);
diff --git a/Source/WebCore/svg/SVGFilterPrimitiveStandardAttributes.cpp b/Source/WebCore/svg/SVGFilterPrimitiveStandardAttributes.cpp
index 00f99c5..1030b5b 100644
--- a/Source/WebCore/svg/SVGFilterPrimitiveStandardAttributes.cpp
+++ b/Source/WebCore/svg/SVGFilterPrimitiveStandardAttributes.cpp
@@ -70,6 +70,12 @@ void SVGFilterPrimitiveStandardAttributes::parseMappedAttribute(Attribute* attr)
         return SVGStyledElement::parseMappedAttribute(attr);
 }
 
+void SVGFilterPrimitiveStandardAttributes::setFilterEffectAttribute(FilterEffect*, const QualifiedName&)
+{
+    // When all filters support this method, it will be changed to a pure virtual method.
+    ASSERT_NOT_REACHED();
+}
+
 void SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(const QualifiedName& attrName)
 {
     SVGStyledElement::svgAttributeChanged(attrName);
diff --git a/Source/WebCore/svg/SVGFilterPrimitiveStandardAttributes.h b/Source/WebCore/svg/SVGFilterPrimitiveStandardAttributes.h
index 34e19ea..e00c9c0 100644
--- a/Source/WebCore/svg/SVGFilterPrimitiveStandardAttributes.h
+++ b/Source/WebCore/svg/SVGFilterPrimitiveStandardAttributes.h
@@ -22,7 +22,8 @@
 #define SVGFilterPrimitiveStandardAttributes_h
 
 #if ENABLE(SVG) && ENABLE(FILTERS)
-#include "RenderSVGResource.h"
+#include "RenderSVGResourceFilter.h"
+#include "RenderSVGResourceFilterPrimitive.h"
 #include "SVGAnimatedLength.h"
 #include "SVGAnimatedString.h"
 #include "SVGStyledElement.h"
@@ -41,6 +42,7 @@ public:
     void setStandardAttributes(bool, FilterEffect*) const;
 
     virtual PassRefPtr<FilterEffect> build(SVGFilterBuilder*, Filter* filter) = 0;
+    virtual void setFilterEffectAttribute(FilterEffect*, const QualifiedName&);
 
 protected:
     SVGFilterPrimitiveStandardAttributes(const QualifiedName&, Document*);
@@ -50,13 +52,18 @@ protected:
     virtual void synchronizeProperty(const QualifiedName&);
     virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
 
-protected:
     inline void invalidate()
     {
         if (RenderObject* primitiveRenderer = renderer())
             RenderSVGResource::markForLayoutAndParentResourceInvalidation(primitiveRenderer);
     }
 
+    inline void primitiveAttributeChanged(const QualifiedName& attribute)
+    {
+        if (RenderObject* primitiveRenderer = renderer())
+            static_cast<RenderSVGResourceFilterPrimitive*>(primitiveRenderer)->primitiveAttributeChanged(attribute);
+    }
+
 private:
     virtual bool isFilterEffect() const { return true; }
 
diff --git a/Source/WebCore/svg/graphics/filters/SVGFilterBuilder.cpp b/Source/WebCore/svg/graphics/filters/SVGFilterBuilder.cpp
index b31b994..e6d0e65 100644
--- a/Source/WebCore/svg/graphics/filters/SVGFilterBuilder.cpp
+++ b/Source/WebCore/svg/graphics/filters/SVGFilterBuilder.cpp
@@ -68,10 +68,11 @@ FilterEffect* SVGFilterBuilder::getEffectById(const AtomicString& id) const
     return m_namedEffects.get(id).get();
 }
 
-void SVGFilterBuilder::appendEffectToEffectReferences(RefPtr<FilterEffect> effectReference)
+void SVGFilterBuilder::appendEffectToEffectReferences(RefPtr<FilterEffect> effectReference, RenderObject* object)
 {
     // The effect must be a newly created filter effect.
     ASSERT(!m_effectReferences.contains(effectReference));
+    ASSERT(object && !m_effectRenderer.contains(object));
     m_effectReferences.add(effectReference, FilterEffectSet());
 
     FilterEffect* effect = effectReference.get();
@@ -79,7 +80,8 @@ void SVGFilterBuilder::appendEffectToEffectReferences(RefPtr<FilterEffect> effec
 
     // It is not possible to add the same value to a set twice.
     for (unsigned i = 0; i < numberOfInputEffects; ++i)
-        getEffectReferences(effect->inputEffect(i)).add(effect);
+        effectReferences(effect->inputEffect(i)).add(effect);
+    m_effectRenderer.add(object, effectReference.get());
 }
 
 void SVGFilterBuilder::clearEffects()
@@ -87,9 +89,23 @@ void SVGFilterBuilder::clearEffects()
     m_lastEffect = 0;
     m_namedEffects.clear();
     m_effectReferences.clear();
+    m_effectRenderer.clear();
     addBuiltinEffects();
 }
 
+void SVGFilterBuilder::clearResultsRecursive(FilterEffect* effect)
+{
+    if (!effect->hasResult())
+        return;
+
+    effect->clearResult();
+
+    HashSet<FilterEffect*>& effectReferences = this->effectReferences(effect);
+    HashSet<FilterEffect*>::iterator end = effectReferences.end();
+    for (HashSet<FilterEffect*>::iterator it = effectReferences.begin(); it != end; ++it)
+         clearResultsRecursive(*it);
+}
+
 } // namespace WebCore
 
 #endif // ENABLE(SVG) && ENABLE(FILTERS)
diff --git a/Source/WebCore/svg/graphics/filters/SVGFilterBuilder.h b/Source/WebCore/svg/graphics/filters/SVGFilterBuilder.h
index a3c1244..9e7b2fe 100644
--- a/Source/WebCore/svg/graphics/filters/SVGFilterBuilder.h
+++ b/Source/WebCore/svg/graphics/filters/SVGFilterBuilder.h
@@ -24,6 +24,7 @@
 #if ENABLE(SVG) && ENABLE(FILTERS)
 #include "FilterEffect.h"
 #include "PlatformString.h"
+#include "RenderObject.h"
 
 #include <wtf/HashMap.h>
 #include <wtf/HashSet.h>
@@ -43,16 +44,20 @@ public:
     FilterEffect* getEffectById(const AtomicString& id) const;
     FilterEffect* lastEffect() const { return m_lastEffect.get(); }
 
-    void appendEffectToEffectReferences(RefPtr<FilterEffect>);
+    void appendEffectToEffectReferences(RefPtr<FilterEffect>, RenderObject*);
 
-    inline FilterEffectSet& getEffectReferences(FilterEffect* effect)
+    inline FilterEffectSet& effectReferences(FilterEffect* effect)
     {
         // Only allowed for effects belongs to this builder.
         ASSERT(m_effectReferences.contains(effect));
         return m_effectReferences.find(effect)->second;
     }
 
+    // Required to change the attributes of a filter during an svgAttributeChanged.
+    inline FilterEffect* effectByRenderer(RenderObject* object) { return m_effectRenderer.get(object); }
+
     void clearEffects();
+    void clearResultsRecursive(FilterEffect*);
 
 private:
     SVGFilterBuilder(Filter*);
@@ -69,6 +74,7 @@ private:
     // The value is a list, which contains those filter effects,
     // which depends on the key filter effect.
     HashMap<RefPtr<FilterEffect>, FilterEffectSet> m_effectReferences;
+    HashMap<RenderObject*, FilterEffect*> m_effectRenderer;
 
     RefPtr<FilterEffect> m_lastEffect;
 };

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list