Title: [118608] trunk/Source/WebCore
Revision
118608
Author
[email protected]
Date
2012-05-26 02:08:14 -0700 (Sat, 26 May 2012)

Log Message

Avoid updateFromElement() usage in SVG
https://bugs.webkit.org/show_bug.cgi?id=87573

Stop relying on updateFromElement() - instead rely on addChild/removeChild, which
allows us to optimize the resources re-fetching. When a child is added to the tree
we don't need to remove existing resources from the SVGResourcesCache - the renderer
can't be in the cache yet. Similary, remove the entry from the cache earlier: as soon
as the renderer is removed from the tree, instead of waiting for willBeDestroyed().

No new tests, refactoring only.

* rendering/svg/RenderSVGBlock.cpp:
* rendering/svg/RenderSVGBlock.h:
(RenderSVGBlock):
* rendering/svg/RenderSVGContainer.cpp:
(WebCore::RenderSVGContainer::addChild):
(WebCore):
(WebCore::RenderSVGContainer::removeChild):
* rendering/svg/RenderSVGContainer.h:
(RenderSVGContainer):
* rendering/svg/RenderSVGInline.cpp:
(WebCore::RenderSVGInline::addChild):
(WebCore::RenderSVGInline::removeChild):
* rendering/svg/RenderSVGInline.h:
(RenderSVGInline):
* rendering/svg/RenderSVGModelObject.cpp:
* rendering/svg/RenderSVGModelObject.h:
(RenderSVGModelObject):
* rendering/svg/RenderSVGResourceContainer.cpp:
(WebCore::RenderSVGResourceContainer::registerResource):
* rendering/svg/RenderSVGRoot.cpp:
(WebCore::RenderSVGRoot::addChild):
(WebCore):
(WebCore::RenderSVGRoot::removeChild):
* rendering/svg/RenderSVGRoot.h:
(RenderSVGRoot):
* rendering/svg/RenderSVGText.cpp:
(WebCore::RenderSVGText::addChild):
(WebCore::RenderSVGText::removeChild):
* rendering/svg/SVGResourcesCache.cpp:
(WebCore::SVGResourcesCache::clientStyleChanged):
(WebCore::rendererCanHaveResources):
(WebCore):
(WebCore::SVGResourcesCache::clientWasAddedToTree):
(WebCore::SVGResourcesCache::clientWillBeRemovedFromTree):
* rendering/svg/SVGResourcesCache.h:
(SVGResourcesCache):
* svg/SVGStyledElement.cpp:
* svg/SVGStyledElement.h:
(SVGStyledElement):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (118607 => 118608)


--- trunk/Source/WebCore/ChangeLog	2012-05-26 07:16:30 UTC (rev 118607)
+++ trunk/Source/WebCore/ChangeLog	2012-05-26 09:08:14 UTC (rev 118608)
@@ -1,3 +1,56 @@
+2012-05-26  Nikolas Zimmermann  <[email protected]>
+
+        Avoid updateFromElement() usage in SVG
+        https://bugs.webkit.org/show_bug.cgi?id=87573
+
+        Stop relying on updateFromElement() - instead rely on addChild/removeChild, which
+        allows us to optimize the resources re-fetching. When a child is added to the tree
+        we don't need to remove existing resources from the SVGResourcesCache - the renderer
+        can't be in the cache yet. Similary, remove the entry from the cache earlier: as soon
+        as the renderer is removed from the tree, instead of waiting for willBeDestroyed().
+
+        No new tests, refactoring only.
+
+        * rendering/svg/RenderSVGBlock.cpp:
+        * rendering/svg/RenderSVGBlock.h:
+        (RenderSVGBlock):
+        * rendering/svg/RenderSVGContainer.cpp:
+        (WebCore::RenderSVGContainer::addChild):
+        (WebCore):
+        (WebCore::RenderSVGContainer::removeChild):
+        * rendering/svg/RenderSVGContainer.h:
+        (RenderSVGContainer):
+        * rendering/svg/RenderSVGInline.cpp:
+        (WebCore::RenderSVGInline::addChild):
+        (WebCore::RenderSVGInline::removeChild):
+        * rendering/svg/RenderSVGInline.h:
+        (RenderSVGInline):
+        * rendering/svg/RenderSVGModelObject.cpp:
+        * rendering/svg/RenderSVGModelObject.h:
+        (RenderSVGModelObject):
+        * rendering/svg/RenderSVGResourceContainer.cpp:
+        (WebCore::RenderSVGResourceContainer::registerResource):
+        * rendering/svg/RenderSVGRoot.cpp:
+        (WebCore::RenderSVGRoot::addChild):
+        (WebCore):
+        (WebCore::RenderSVGRoot::removeChild):
+        * rendering/svg/RenderSVGRoot.h:
+        (RenderSVGRoot):
+        * rendering/svg/RenderSVGText.cpp:
+        (WebCore::RenderSVGText::addChild):
+        (WebCore::RenderSVGText::removeChild):
+        * rendering/svg/SVGResourcesCache.cpp:
+        (WebCore::SVGResourcesCache::clientStyleChanged):
+        (WebCore::rendererCanHaveResources):
+        (WebCore):
+        (WebCore::SVGResourcesCache::clientWasAddedToTree):
+        (WebCore::SVGResourcesCache::clientWillBeRemovedFromTree):
+        * rendering/svg/SVGResourcesCache.h:
+        (SVGResourcesCache):
+        * svg/SVGStyledElement.cpp:
+        * svg/SVGStyledElement.h:
+        (SVGStyledElement):
+
 2012-05-25  Nat Duca  <[email protected]>
 
         [chromium] Instrument V8 GC with TraceEvent

Modified: trunk/Source/WebCore/rendering/svg/RenderSVGBlock.cpp (118607 => 118608)


--- trunk/Source/WebCore/rendering/svg/RenderSVGBlock.cpp	2012-05-26 07:16:30 UTC (rev 118607)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGBlock.cpp	2012-05-26 09:08:14 UTC (rev 118608)
@@ -104,12 +104,6 @@
     SVGResourcesCache::clientStyleChanged(this, diff, style());
 }
 
-void RenderSVGBlock::updateFromElement()
-{
-    RenderBlock::updateFromElement();
-    SVGResourcesCache::clientUpdatedFromElement(this, style());
 }
 
-}
-
 #endif

Modified: trunk/Source/WebCore/rendering/svg/RenderSVGBlock.h (118607 => 118608)


--- trunk/Source/WebCore/rendering/svg/RenderSVGBlock.h	2012-05-26 07:16:30 UTC (rev 118607)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGBlock.h	2012-05-26 09:08:14 UTC (rev 118608)
@@ -45,7 +45,6 @@
 
     virtual void styleWillChange(StyleDifference, const RenderStyle* newStyle);
     virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
-    virtual void updateFromElement();
 };
 
 }

Modified: trunk/Source/WebCore/rendering/svg/RenderSVGContainer.cpp (118607 => 118608)


--- trunk/Source/WebCore/rendering/svg/RenderSVGContainer.cpp	2012-05-26 07:16:30 UTC (rev 118607)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGContainer.cpp	2012-05-26 09:08:14 UTC (rev 118608)
@@ -87,6 +87,19 @@
     setNeedsLayout(false);
 }
 
+void RenderSVGContainer::addChild(RenderObject* child, RenderObject* beforeChild)
+{
+    RenderSVGModelObject::addChild(child, beforeChild);
+    SVGResourcesCache::clientWasAddedToTree(child, child->style());
+}
+
+void RenderSVGContainer::removeChild(RenderObject* child)
+{
+    SVGResourcesCache::clientWillBeRemovedFromTree(child);
+    RenderSVGModelObject::removeChild(child);
+}
+
+
 bool RenderSVGContainer::selfWillPaint()
 {
     SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObject(this);

Modified: trunk/Source/WebCore/rendering/svg/RenderSVGContainer.h (118607 => 118608)


--- trunk/Source/WebCore/rendering/svg/RenderSVGContainer.h	2012-05-26 07:16:30 UTC (rev 118607)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGContainer.h	2012-05-26 09:08:14 UTC (rev 118608)
@@ -53,6 +53,8 @@
 
     virtual void layout();
 
+    virtual void addChild(RenderObject* child, RenderObject* beforeChild = 0) OVERRIDE;
+    virtual void removeChild(RenderObject*) OVERRIDE;
     virtual void addFocusRingRects(Vector<IntRect>&, const LayoutPoint&);
 
     virtual FloatRect objectBoundingBox() const { return m_objectBoundingBox; }

Modified: trunk/Source/WebCore/rendering/svg/RenderSVGInline.cpp (118607 => 118608)


--- trunk/Source/WebCore/rendering/svg/RenderSVGInline.cpp	2012-05-26 07:16:30 UTC (rev 118607)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGInline.cpp	2012-05-26 09:08:14 UTC (rev 118608)
@@ -119,21 +119,19 @@
     SVGResourcesCache::clientStyleChanged(this, diff, style());
 }
 
-void RenderSVGInline::updateFromElement()
-{
-    RenderInline::updateFromElement();
-    SVGResourcesCache::clientUpdatedFromElement(this, style());
-}
-
 void RenderSVGInline::addChild(RenderObject* child, RenderObject* beforeChild)
 {
     RenderInline::addChild(child, beforeChild);
+    SVGResourcesCache::clientWasAddedToTree(child, child->style());
+
     if (RenderSVGText* textRenderer = RenderSVGText::locateRenderSVGTextAncestor(this))
         textRenderer->subtreeChildWasAdded(child);
 }
 
 void RenderSVGInline::removeChild(RenderObject* child)
 {
+    SVGResourcesCache::clientWillBeRemovedFromTree(child);
+
     RenderSVGText* textRenderer = RenderSVGText::locateRenderSVGTextAncestor(this);
     if (!textRenderer) {
         RenderInline::removeChild(child);

Modified: trunk/Source/WebCore/rendering/svg/RenderSVGInline.h (118607 => 118608)


--- trunk/Source/WebCore/rendering/svg/RenderSVGInline.h	2012-05-26 07:16:30 UTC (rev 118607)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGInline.h	2012-05-26 09:08:14 UTC (rev 118608)
@@ -57,9 +57,8 @@
     virtual void willBeDestroyed();
     virtual void styleWillChange(StyleDifference, const RenderStyle* newStyle);
     virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
-    virtual void updateFromElement();
 
-    virtual void addChild(RenderObject* child, RenderObject* beforeChild = 0);
+    virtual void addChild(RenderObject* child, RenderObject* beforeChild = 0) OVERRIDE;
     virtual void removeChild(RenderObject*) OVERRIDE;
 };
 

Modified: trunk/Source/WebCore/rendering/svg/RenderSVGModelObject.cpp (118607 => 118608)


--- trunk/Source/WebCore/rendering/svg/RenderSVGModelObject.cpp	2012-05-26 07:16:30 UTC (rev 118607)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGModelObject.cpp	2012-05-26 09:08:14 UTC (rev 118608)
@@ -111,12 +111,6 @@
     SVGResourcesCache::clientStyleChanged(this, diff, style());
 }
 
-void RenderSVGModelObject::updateFromElement()
-{
-    RenderObject::updateFromElement();
-    SVGResourcesCache::clientUpdatedFromElement(this, style());
-}
-
 bool RenderSVGModelObject::nodeAtPoint(const HitTestRequest&, HitTestResult&, const LayoutPoint&, const LayoutPoint&, HitTestAction)
 {
     ASSERT_NOT_REACHED();

Modified: trunk/Source/WebCore/rendering/svg/RenderSVGModelObject.h (118607 => 118608)


--- trunk/Source/WebCore/rendering/svg/RenderSVGModelObject.h	2012-05-26 07:16:30 UTC (rev 118607)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGModelObject.h	2012-05-26 09:08:14 UTC (rev 118608)
@@ -62,7 +62,6 @@
     virtual const RenderObject* pushMappingToContainer(const RenderBoxModelObject* ancestorToStopAt, RenderGeometryMap&) const;
     virtual void styleWillChange(StyleDifference, const RenderStyle* newStyle);
     virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
-    virtual void updateFromElement();
 
     static bool checkIntersection(RenderObject*, const FloatRect&);
     static bool checkEnclosure(RenderObject*, const FloatRect&);

Modified: trunk/Source/WebCore/rendering/svg/RenderSVGResourceContainer.cpp (118607 => 118608)


--- trunk/Source/WebCore/rendering/svg/RenderSVGResourceContainer.cpp	2012-05-26 07:16:30 UTC (rev 118607)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGResourceContainer.cpp	2012-05-26 09:08:14 UTC (rev 118608)
@@ -165,7 +165,7 @@
         RenderObject* renderer = (*it)->renderer();
         if (!renderer)
             continue;
-        SVGResourcesCache::clientUpdatedFromElement(renderer, renderer->style());
+        SVGResourcesCache::clientStyleChanged(renderer, StyleDifferenceLayout, renderer->style());
         renderer->setNeedsLayout(true);
     }
 }

Modified: trunk/Source/WebCore/rendering/svg/RenderSVGRoot.cpp (118607 => 118608)


--- trunk/Source/WebCore/rendering/svg/RenderSVGRoot.cpp	2012-05-26 07:16:30 UTC (rev 118607)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGRoot.cpp	2012-05-26 09:08:14 UTC (rev 118608)
@@ -326,12 +326,18 @@
     SVGResourcesCache::clientStyleChanged(this, diff, style());
 }
 
-void RenderSVGRoot::updateFromElement()
+void RenderSVGRoot::addChild(RenderObject* child, RenderObject* beforeChild)
 {
-    RenderReplaced::updateFromElement();
-    SVGResourcesCache::clientUpdatedFromElement(this, style());
+    RenderReplaced::addChild(child, beforeChild);
+    SVGResourcesCache::clientWasAddedToTree(child, child->style());
 }
 
+void RenderSVGRoot::removeChild(RenderObject* child)
+{
+    SVGResourcesCache::clientWillBeRemovedFromTree(child);
+    RenderReplaced::removeChild(child);
+}
+
 // RenderBox methods will expect coordinates w/o any transforms in coordinates
 // relative to our borderBox origin.  This method gives us exactly that.
 void RenderSVGRoot::buildLocalToBorderBoxTransform()

Modified: trunk/Source/WebCore/rendering/svg/RenderSVGRoot.h (118607 => 118608)


--- trunk/Source/WebCore/rendering/svg/RenderSVGRoot.h	2012-05-26 07:16:30 UTC (rev 118607)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGRoot.h	2012-05-26 09:08:14 UTC (rev 118608)
@@ -78,7 +78,8 @@
     virtual void willBeDestroyed();
     virtual void styleWillChange(StyleDifference, const RenderStyle* newStyle);
     virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
-    virtual void updateFromElement();
+    virtual void addChild(RenderObject* child, RenderObject* beforeChild = 0) OVERRIDE;
+    virtual void removeChild(RenderObject*) OVERRIDE;
 
     virtual const AffineTransform& localToParentTransform() const;
 

Modified: trunk/Source/WebCore/rendering/svg/RenderSVGText.cpp (118607 => 118608)


--- trunk/Source/WebCore/rendering/svg/RenderSVGText.cpp	2012-05-26 07:16:30 UTC (rev 118607)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGText.cpp	2012-05-26 09:08:14 UTC (rev 118608)
@@ -529,11 +529,15 @@
 void RenderSVGText::addChild(RenderObject* child, RenderObject* beforeChild)
 {
     RenderSVGBlock::addChild(child, beforeChild);
+
+    SVGResourcesCache::clientWasAddedToTree(child, child->style());
     subtreeChildWasAdded(child);
 }
 
 void RenderSVGText::removeChild(RenderObject* child)
 {
+    SVGResourcesCache::clientWillBeRemovedFromTree(child);
+
     Vector<SVGTextLayoutAttributes*, 2> affectedAttributes;
     FontCachePurgePreventer fontCachePurgePreventer;
     subtreeChildWillBeRemoved(child, affectedAttributes);

Modified: trunk/Source/WebCore/rendering/svg/SVGResourcesCache.cpp (118607 => 118608)


--- trunk/Source/WebCore/rendering/svg/SVGResourcesCache.cpp	2012-05-26 07:16:30 UTC (rev 118607)
+++ trunk/Source/WebCore/rendering/svg/SVGResourcesCache.cpp	2012-05-26 09:08:14 UTC (rev 118608)
@@ -128,25 +128,45 @@
 void SVGResourcesCache::clientStyleChanged(RenderObject* renderer, StyleDifference diff, const RenderStyle* newStyle)
 {
     ASSERT(renderer);
-    if (diff == StyleDifferenceEqual)
+    if (diff == StyleDifferenceEqual || !renderer->parent())
         return;
 
     // In this case the proper SVGFE*Element will decide whether the modified CSS properties require a relayout or repaint.
     if (renderer->isSVGResourceFilterPrimitive() && diff == StyleDifferenceRepaint)
         return;
 
-    clientUpdatedFromElement(renderer, newStyle);
+    // Dynamic changes of CSS properties like 'clip-path' may require us to recompute the associated resources for a renderer.
+    // FIXME: Avoid passing in a useless StyleDifference, but instead compare oldStyle/newStyle to see which resources changed
+    // to be able to selectively rebuild individual resources, instead of all of them.
+    SVGResourcesCache* cache = resourcesCacheFromRenderObject(renderer);
+    cache->removeResourcesFromRenderObject(renderer);
+    cache->addResourcesFromRenderObject(renderer, newStyle);
+
+    RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer, false);
 }
 
-void SVGResourcesCache::clientUpdatedFromElement(RenderObject* renderer, const RenderStyle* newStyle)
+static inline bool rendererCanHaveResources(RenderObject* renderer)
 {
     ASSERT(renderer);
     ASSERT(renderer->parent());
+    return renderer->node() && !renderer->isSVGInlineText();
+}
 
+void SVGResourcesCache::clientWasAddedToTree(RenderObject* renderer, const RenderStyle* newStyle)
+{
+    if (!rendererCanHaveResources(renderer))
+        return;
     SVGResourcesCache* cache = resourcesCacheFromRenderObject(renderer);
-    cache->removeResourcesFromRenderObject(renderer);
     cache->addResourcesFromRenderObject(renderer, newStyle);
+}
 
+void SVGResourcesCache::clientWillBeRemovedFromTree(RenderObject* renderer)
+{
+    if (!rendererCanHaveResources(renderer))
+        return;
+    SVGResourcesCache* cache = resourcesCacheFromRenderObject(renderer);
+    cache->removeResourcesFromRenderObject(renderer);
+
     RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer, false);
 }
 

Modified: trunk/Source/WebCore/rendering/svg/SVGResourcesCache.h (118607 => 118608)


--- trunk/Source/WebCore/rendering/svg/SVGResourcesCache.h	2012-05-26 07:16:30 UTC (rev 118607)
+++ trunk/Source/WebCore/rendering/svg/SVGResourcesCache.h	2012-05-26 09:08:14 UTC (rev 118608)
@@ -37,10 +37,14 @@
     SVGResourcesCache();
     ~SVGResourcesCache();
 
-    void addResourcesFromRenderObject(RenderObject*, const RenderStyle*);
-    void removeResourcesFromRenderObject(RenderObject*);
     static SVGResources* cachedResourcesForRenderObject(const RenderObject*);
 
+    // Called from all SVG renderers addChild() methods.
+    static void clientWasAddedToTree(RenderObject*, const RenderStyle* newStyle);
+
+    // Called from all SVG renderers removeChild() methods.
+    static void clientWillBeRemovedFromTree(RenderObject*);
+
     // Called from all SVG renderers destroy() methods - except for RenderSVGResourceContainer.
     static void clientDestroyed(RenderObject*);
 
@@ -50,13 +54,13 @@
     // Called from all SVG renderers styleDidChange() methods.
     static void clientStyleChanged(RenderObject*, StyleDifference, const RenderStyle* newStyle);
 
-    // Called from all SVG renderers updateFromElement() methods.
-    static void clientUpdatedFromElement(RenderObject*, const RenderStyle* newStyle);
-
     // Called from RenderSVGResourceContainer::willBeDestroyed().
     static void resourceDestroyed(RenderSVGResourceContainer*);
 
 private:
+    void addResourcesFromRenderObject(RenderObject*, const RenderStyle*);
+    void removeResourcesFromRenderObject(RenderObject*);
+
     HashMap<const RenderObject*, SVGResources*> m_cache;
 };
 

Modified: trunk/Source/WebCore/svg/SVGStyledElement.cpp (118607 => 118608)


--- trunk/Source/WebCore/svg/SVGStyledElement.cpp	2012-05-26 07:16:30 UTC (rev 118607)
+++ trunk/Source/WebCore/svg/SVGStyledElement.cpp	2012-05-26 09:08:14 UTC (rev 118608)
@@ -350,14 +350,6 @@
     }
 }
 
-void SVGStyledElement::attach()
-{
-    SVGElement::attach();
-
-    if (RenderObject* object = renderer())
-        object->updateFromElement();
-}
-
 Node::InsertionNotificationRequest SVGStyledElement::insertedInto(ContainerNode* rootParent)
 {
     SVGElement::insertedInto(rootParent);

Modified: trunk/Source/WebCore/svg/SVGStyledElement.h (118607 => 118608)


--- trunk/Source/WebCore/svg/SVGStyledElement.h	2012-05-26 07:16:30 UTC (rev 118607)
+++ trunk/Source/WebCore/svg/SVGStyledElement.h	2012-05-26 09:08:14 UTC (rev 118608)
@@ -71,7 +71,6 @@
     virtual void collectStyleForAttribute(const Attribute&, StylePropertySet*) OVERRIDE;
     virtual void svgAttributeChanged(const QualifiedName&);
 
-    virtual void attach();
     virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
     virtual void removedFrom(ContainerNode*) OVERRIDE;
     virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to