[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