Title: [143498] trunk/Source/WebCore
- Revision
- 143498
- Author
- fmal...@chromium.org
- Date
- 2013-02-20 13:43:29 -0800 (Wed, 20 Feb 2013)
Log Message
[SVG] Update of element referenced by multiple 'use' nodes is absurdly slow
https://bugs.webkit.org/show_bug.cgi?id=97905
Reviewed by Dirk Schulze.
Rebuilding the shadow and instance trees of dependent use nodes recursively can be
extremely inefficient with non-trivial dependency graphs (the trees are not constructed
in topological order).
To avoid redundant buildShadowAndInstanceTree() invokations, separate the invalidation
phase from the actual tree (re)building phase, and only descend into the dependency DAG
during the invalidation phase (recursion also stops at nodes that have been previously
invalidated).
No new tests: functional coverage provided by existing tests, perfomance tracked by
PerformanceTests/SVG/SvgNestedUse.html.
* svg/SVGUseElement.cpp:
(WebCore::SVGUseElement::buildPendingResource):
(WebCore::SVGUseElement::buildShadowAndInstanceTree):
(WebCore::SVGUseElement::invalidateShadowTree):
(WebCore):
(WebCore::SVGUseElement::invalidateDependentShadowTrees):
* svg/SVGUseElement.h:
(SVGUseElement):
Modified Paths
Diff
Modified: trunk/Source/WebCore/ChangeLog (143497 => 143498)
--- trunk/Source/WebCore/ChangeLog 2013-02-20 21:34:19 UTC (rev 143497)
+++ trunk/Source/WebCore/ChangeLog 2013-02-20 21:43:29 UTC (rev 143498)
@@ -1,3 +1,31 @@
+2013-02-20 Florin Malita <fmal...@chromium.org>
+
+ [SVG] Update of element referenced by multiple 'use' nodes is absurdly slow
+ https://bugs.webkit.org/show_bug.cgi?id=97905
+
+ Reviewed by Dirk Schulze.
+
+ Rebuilding the shadow and instance trees of dependent use nodes recursively can be
+ extremely inefficient with non-trivial dependency graphs (the trees are not constructed
+ in topological order).
+
+ To avoid redundant buildShadowAndInstanceTree() invokations, separate the invalidation
+ phase from the actual tree (re)building phase, and only descend into the dependency DAG
+ during the invalidation phase (recursion also stops at nodes that have been previously
+ invalidated).
+
+ No new tests: functional coverage provided by existing tests, perfomance tracked by
+ PerformanceTests/SVG/SvgNestedUse.html.
+
+ * svg/SVGUseElement.cpp:
+ (WebCore::SVGUseElement::buildPendingResource):
+ (WebCore::SVGUseElement::buildShadowAndInstanceTree):
+ (WebCore::SVGUseElement::invalidateShadowTree):
+ (WebCore):
+ (WebCore::SVGUseElement::invalidateDependentShadowTrees):
+ * svg/SVGUseElement.h:
+ (SVGUseElement):
+
2013-02-20 Tim Horton <timothy_hor...@apple.com>
RenderLayerBacking should initialize TiledBacking's isInWindow state with Page's isInWindow, not isOnscreen
Modified: trunk/Source/WebCore/svg/SVGUseElement.cpp (143497 => 143498)
--- trunk/Source/WebCore/svg/SVGUseElement.cpp 2013-02-20 21:34:19 UTC (rev 143497)
+++ trunk/Source/WebCore/svg/SVGUseElement.cpp 2013-02-20 21:43:29 UTC (rev 143498)
@@ -409,10 +409,10 @@
void SVGUseElement::buildPendingResource()
{
- if (!referencedDocument())
+ if (!referencedDocument() || isInShadowTree())
return;
clearResourceReferences();
- if (!inDocument() || isInShadowTree())
+ if (!inDocument())
return;
String id;
@@ -430,8 +430,11 @@
return;
}
- if (target->isSVGElement())
+ if (target->isSVGElement()) {
buildShadowAndInstanceTree(static_cast<SVGElement*>(target));
+ invalidateDependentShadowTrees();
+ }
+
ASSERT(!m_needsShadowTreeRecreation);
}
@@ -517,10 +520,6 @@
// Update relative length information.
updateRelativeLengthsInformation();
- // Rebuild all dependent use elements.
- ASSERT(document());
- document()->accessSVGExtensions()->rebuildAllElementReferencesForTarget(this);
-
// Eventually dump instance tree
#ifdef DUMP_INSTANCE_TREE
String text;
@@ -906,8 +905,22 @@
return;
m_needsShadowTreeRecreation = true;
setNeedsStyleRecalc();
+ invalidateDependentShadowTrees();
}
+void SVGUseElement::invalidateDependentShadowTrees()
+{
+ // Recursively invalidate dependent <use> shadow trees
+ const HashSet<SVGElementInstance*>& instances = instancesForElement();
+ const HashSet<SVGElementInstance*>::const_iterator end = instances.end();
+ for (HashSet<SVGElementInstance*>::const_iterator it = instances.begin(); it != end; ++it) {
+ if (SVGUseElement* element = (*it)->correspondingUseElement()) {
+ ASSERT(element->inDocument());
+ element->invalidateShadowTree();
+ }
+ }
+}
+
void SVGUseElement::transferUseAttributesToReplacedElement(SVGElement* from, SVGElement* to) const
{
ASSERT(from);
Modified: trunk/Source/WebCore/svg/SVGUseElement.h (143497 => 143498)
--- trunk/Source/WebCore/svg/SVGUseElement.h 2013-02-20 21:34:19 UTC (rev 143497)
+++ trunk/Source/WebCore/svg/SVGUseElement.h 2013-02-20 21:43:29 UTC (rev 143498)
@@ -50,6 +50,7 @@
SVGElementInstance* animatedInstanceRoot() const;
SVGElementInstance* instanceForShadowTreeElement(Node*) const;
void invalidateShadowTree();
+ void invalidateDependentShadowTrees();
RenderObject* rendererClipChild() const;
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes