| Index: Source/core/rendering/svg/RenderSVGResourceContainer.cpp
|
| diff --git a/Source/core/rendering/svg/RenderSVGResourceContainer.cpp b/Source/core/rendering/svg/RenderSVGResourceContainer.cpp
|
| index 3e9db362b1955059d15f5dd7036689ab5380f579..53dcdfc025d55056f4f2085e3913c4470a3434ad 100644
|
| --- a/Source/core/rendering/svg/RenderSVGResourceContainer.cpp
|
| +++ b/Source/core/rendering/svg/RenderSVGResourceContainer.cpp
|
| @@ -21,6 +21,10 @@
|
| #include "core/rendering/svg/RenderSVGResourceContainer.h"
|
|
|
| #include "core/rendering/RenderLayer.h"
|
| +#include "core/rendering/svg/RenderSVGResourceClipper.h"
|
| +#include "core/rendering/svg/RenderSVGResourceFilter.h"
|
| +#include "core/rendering/svg/RenderSVGResourceMasker.h"
|
| +#include "core/rendering/svg/SVGResources.h"
|
| #include "core/rendering/svg/SVGResourcesCache.h"
|
|
|
| #include "wtf/TemporaryChange.h"
|
| @@ -117,7 +121,7 @@ void RenderSVGResourceContainer::markAllClientsForInvalidation(InvalidationMode
|
| if (markForInvalidation)
|
| markClientForInvalidation(client, mode);
|
|
|
| - RenderSVGResource::markForLayoutAndParentResourceInvalidation(client, needsLayout);
|
| + RenderSVGResourceContainer::markForLayoutAndParentResourceInvalidation(client, needsLayout);
|
| }
|
|
|
| markAllClientLayersForInvalidation();
|
| @@ -226,4 +230,70 @@ void RenderSVGResourceContainer::registerResource()
|
| }
|
| }
|
|
|
| +static inline void removeFromCacheAndInvalidateDependencies(RenderObject* object, bool needsLayout)
|
| +{
|
| + ASSERT(object);
|
| + if (SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObject(object)) {
|
| + if (RenderSVGResourceFilter* filter = resources->filter())
|
| + filter->removeClientFromCache(object);
|
| +
|
| + if (RenderSVGResourceMasker* masker = resources->masker())
|
| + masker->removeClientFromCache(object);
|
| +
|
| + if (RenderSVGResourceClipper* clipper = resources->clipper())
|
| + clipper->removeClientFromCache(object);
|
| + }
|
| +
|
| + if (!object->node() || !object->node()->isSVGElement())
|
| + return;
|
| + SVGElementSet* dependencies = toSVGElement(object->node())->setOfIncomingReferences();
|
| + if (!dependencies)
|
| + return;
|
| +
|
| + // We allow cycles in SVGDocumentExtensions reference sets in order to avoid expensive
|
| + // reference graph adjustments on changes, so we need to break possible cycles here.
|
| + // This strong reference is safe, as it is guaranteed that this set will be emptied
|
| + // at the end of recursion.
|
| + typedef WillBeHeapHashSet<RawPtrWillBeMember<SVGElement> > SVGElementSet;
|
| + DEFINE_STATIC_LOCAL(OwnPtrWillBePersistent<SVGElementSet>, invalidatingDependencies, (adoptPtrWillBeNoop(new SVGElementSet)));
|
| +
|
| + SVGElementSet::iterator end = dependencies->end();
|
| + for (SVGElementSet::iterator it = dependencies->begin(); it != end; ++it) {
|
| + if (RenderObject* renderer = (*it)->renderer()) {
|
| + if (UNLIKELY(!invalidatingDependencies->add(*it).isNewEntry)) {
|
| + // Reference cycle: we are in process of invalidating this dependant.
|
| + continue;
|
| + }
|
| +
|
| + RenderSVGResourceContainer::markForLayoutAndParentResourceInvalidation(renderer, needsLayout);
|
| + invalidatingDependencies->remove(*it);
|
| + }
|
| + }
|
| +}
|
| +
|
| +void RenderSVGResourceContainer::markForLayoutAndParentResourceInvalidation(RenderObject* object, bool needsLayout)
|
| +{
|
| + ASSERT(object);
|
| + ASSERT(object->node());
|
| +
|
| + if (needsLayout && !object->documentBeingDestroyed())
|
| + object->setNeedsLayoutAndFullPaintInvalidation();
|
| +
|
| + removeFromCacheAndInvalidateDependencies(object, needsLayout);
|
| +
|
| + // Invalidate resources in ancestor chain, if needed.
|
| + RenderObject* current = object->parent();
|
| + while (current) {
|
| + removeFromCacheAndInvalidateDependencies(current, needsLayout);
|
| +
|
| + if (current->isSVGResourceContainer()) {
|
| + // This will process the rest of the ancestors.
|
| + toRenderSVGResourceContainer(current)->removeAllClientsFromCache();
|
| + break;
|
| + }
|
| +
|
| + current = current->parent();
|
| + }
|
| +}
|
| +
|
| }
|
|
|