⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 118608 in webkit


Ignore:
Timestamp:
May 26, 2012, 2:08:14 AM (14 years ago)
Author:
Nikolas Zimmermann
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):

Location:
trunk/Source/WebCore
Files:
17 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r118606 r118608  
     12012-05-26  Nikolas Zimmermann  <nzimmermann@rim.com>
     2
     3        Avoid updateFromElement() usage in SVG
     4        https://bugs.webkit.org/show_bug.cgi?id=87573
     5
     6        Stop relying on updateFromElement() - instead rely on addChild/removeChild, which
     7        allows us to optimize the resources re-fetching. When a child is added to the tree
     8        we don't need to remove existing resources from the SVGResourcesCache - the renderer
     9        can't be in the cache yet. Similary, remove the entry from the cache earlier: as soon
     10        as the renderer is removed from the tree, instead of waiting for willBeDestroyed().
     11
     12        No new tests, refactoring only.
     13
     14        * rendering/svg/RenderSVGBlock.cpp:
     15        * rendering/svg/RenderSVGBlock.h:
     16        (RenderSVGBlock):
     17        * rendering/svg/RenderSVGContainer.cpp:
     18        (WebCore::RenderSVGContainer::addChild):
     19        (WebCore):
     20        (WebCore::RenderSVGContainer::removeChild):
     21        * rendering/svg/RenderSVGContainer.h:
     22        (RenderSVGContainer):
     23        * rendering/svg/RenderSVGInline.cpp:
     24        (WebCore::RenderSVGInline::addChild):
     25        (WebCore::RenderSVGInline::removeChild):
     26        * rendering/svg/RenderSVGInline.h:
     27        (RenderSVGInline):
     28        * rendering/svg/RenderSVGModelObject.cpp:
     29        * rendering/svg/RenderSVGModelObject.h:
     30        (RenderSVGModelObject):
     31        * rendering/svg/RenderSVGResourceContainer.cpp:
     32        (WebCore::RenderSVGResourceContainer::registerResource):
     33        * rendering/svg/RenderSVGRoot.cpp:
     34        (WebCore::RenderSVGRoot::addChild):
     35        (WebCore):
     36        (WebCore::RenderSVGRoot::removeChild):
     37        * rendering/svg/RenderSVGRoot.h:
     38        (RenderSVGRoot):
     39        * rendering/svg/RenderSVGText.cpp:
     40        (WebCore::RenderSVGText::addChild):
     41        (WebCore::RenderSVGText::removeChild):
     42        * rendering/svg/SVGResourcesCache.cpp:
     43        (WebCore::SVGResourcesCache::clientStyleChanged):
     44        (WebCore::rendererCanHaveResources):
     45        (WebCore):
     46        (WebCore::SVGResourcesCache::clientWasAddedToTree):
     47        (WebCore::SVGResourcesCache::clientWillBeRemovedFromTree):
     48        * rendering/svg/SVGResourcesCache.h:
     49        (SVGResourcesCache):
     50        * svg/SVGStyledElement.cpp:
     51        * svg/SVGStyledElement.h:
     52        (SVGStyledElement):
     53
    1542012-05-25  Nat Duca  <nduca@chromium.org>
    255
  • trunk/Source/WebCore/rendering/svg/RenderSVGBlock.cpp

    r110224 r118608  
    105105}
    106106
    107 void RenderSVGBlock::updateFromElement()
    108 {
    109     RenderBlock::updateFromElement();
    110     SVGResourcesCache::clientUpdatedFromElement(this, style());
    111 }
    112 
    113107}
    114108
  • trunk/Source/WebCore/rendering/svg/RenderSVGBlock.h

    r117225 r118608  
    4646    virtual void styleWillChange(StyleDifference, const RenderStyle* newStyle);
    4747    virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
    48     virtual void updateFromElement();
    4948};
    5049
  • trunk/Source/WebCore/rendering/svg/RenderSVGContainer.cpp

    r112091 r118608  
    8888}
    8989
     90void RenderSVGContainer::addChild(RenderObject* child, RenderObject* beforeChild)
     91{
     92    RenderSVGModelObject::addChild(child, beforeChild);
     93    SVGResourcesCache::clientWasAddedToTree(child, child->style());
     94}
     95
     96void RenderSVGContainer::removeChild(RenderObject* child)
     97{
     98    SVGResourcesCache::clientWillBeRemovedFromTree(child);
     99    RenderSVGModelObject::removeChild(child);
     100}
     101
     102
    90103bool RenderSVGContainer::selfWillPaint()
    91104{
  • trunk/Source/WebCore/rendering/svg/RenderSVGContainer.h

    r112091 r118608  
    5454    virtual void layout();
    5555
     56    virtual void addChild(RenderObject* child, RenderObject* beforeChild = 0) OVERRIDE;
     57    virtual void removeChild(RenderObject*) OVERRIDE;
    5658    virtual void addFocusRingRects(Vector<IntRect>&, const LayoutPoint&);
    5759
  • trunk/Source/WebCore/rendering/svg/RenderSVGInline.cpp

    r118567 r118608  
    120120}
    121121
    122 void RenderSVGInline::updateFromElement()
    123 {
    124     RenderInline::updateFromElement();
    125     SVGResourcesCache::clientUpdatedFromElement(this, style());
    126 }
    127 
    128122void RenderSVGInline::addChild(RenderObject* child, RenderObject* beforeChild)
    129123{
    130124    RenderInline::addChild(child, beforeChild);
     125    SVGResourcesCache::clientWasAddedToTree(child, child->style());
     126
    131127    if (RenderSVGText* textRenderer = RenderSVGText::locateRenderSVGTextAncestor(this))
    132128        textRenderer->subtreeChildWasAdded(child);
     
    135131void RenderSVGInline::removeChild(RenderObject* child)
    136132{
     133    SVGResourcesCache::clientWillBeRemovedFromTree(child);
     134
    137135    RenderSVGText* textRenderer = RenderSVGText::locateRenderSVGTextAncestor(this);
    138136    if (!textRenderer) {
  • trunk/Source/WebCore/rendering/svg/RenderSVGInline.h

    r118567 r118608  
    5858    virtual void styleWillChange(StyleDifference, const RenderStyle* newStyle);
    5959    virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
    60     virtual void updateFromElement();
    6160
    62     virtual void addChild(RenderObject* child, RenderObject* beforeChild = 0);
     61    virtual void addChild(RenderObject* child, RenderObject* beforeChild = 0) OVERRIDE;
    6362    virtual void removeChild(RenderObject*) OVERRIDE;
    6463};
  • trunk/Source/WebCore/rendering/svg/RenderSVGModelObject.cpp

    r118567 r118608  
    112112}
    113113
    114 void RenderSVGModelObject::updateFromElement()
    115 {
    116     RenderObject::updateFromElement();
    117     SVGResourcesCache::clientUpdatedFromElement(this, style());
    118 }
    119 
    120114bool RenderSVGModelObject::nodeAtPoint(const HitTestRequest&, HitTestResult&, const LayoutPoint&, const LayoutPoint&, HitTestAction)
    121115{
  • trunk/Source/WebCore/rendering/svg/RenderSVGModelObject.h

    r118567 r118608  
    6363    virtual void styleWillChange(StyleDifference, const RenderStyle* newStyle);
    6464    virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
    65     virtual void updateFromElement();
    6665
    6766    static bool checkIntersection(RenderObject*, const FloatRect&);
  • trunk/Source/WebCore/rendering/svg/RenderSVGResourceContainer.cpp

    r111601 r118608  
    166166        if (!renderer)
    167167            continue;
    168         SVGResourcesCache::clientUpdatedFromElement(renderer, renderer->style());
     168        SVGResourcesCache::clientStyleChanged(renderer, StyleDifferenceLayout, renderer->style());
    169169        renderer->setNeedsLayout(true);
    170170    }
  • trunk/Source/WebCore/rendering/svg/RenderSVGRoot.cpp

    r118567 r118608  
    327327}
    328328
    329 void RenderSVGRoot::updateFromElement()
    330 {
    331     RenderReplaced::updateFromElement();
    332     SVGResourcesCache::clientUpdatedFromElement(this, style());
     329void RenderSVGRoot::addChild(RenderObject* child, RenderObject* beforeChild)
     330{
     331    RenderReplaced::addChild(child, beforeChild);
     332    SVGResourcesCache::clientWasAddedToTree(child, child->style());
     333}
     334
     335void RenderSVGRoot::removeChild(RenderObject* child)
     336{
     337    SVGResourcesCache::clientWillBeRemovedFromTree(child);
     338    RenderReplaced::removeChild(child);
    333339}
    334340
  • trunk/Source/WebCore/rendering/svg/RenderSVGRoot.h

    r118567 r118608  
    7979    virtual void styleWillChange(StyleDifference, const RenderStyle* newStyle);
    8080    virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
    81     virtual void updateFromElement();
     81    virtual void addChild(RenderObject* child, RenderObject* beforeChild = 0) OVERRIDE;
     82    virtual void removeChild(RenderObject*) OVERRIDE;
    8283
    8384    virtual const AffineTransform& localToParentTransform() const;
  • trunk/Source/WebCore/rendering/svg/RenderSVGText.cpp

    r118567 r118608  
    530530{
    531531    RenderSVGBlock::addChild(child, beforeChild);
     532
     533    SVGResourcesCache::clientWasAddedToTree(child, child->style());
    532534    subtreeChildWasAdded(child);
    533535}
     
    535537void RenderSVGText::removeChild(RenderObject* child)
    536538{
     539    SVGResourcesCache::clientWillBeRemovedFromTree(child);
     540
    537541    Vector<SVGTextLayoutAttributes*, 2> affectedAttributes;
    538542    FontCachePurgePreventer fontCachePurgePreventer;
  • trunk/Source/WebCore/rendering/svg/SVGResourcesCache.cpp

    r117971 r118608  
    129129{
    130130    ASSERT(renderer);
    131     if (diff == StyleDifferenceEqual)
     131    if (diff == StyleDifferenceEqual || !renderer->parent())
    132132        return;
    133133
     
    136136        return;
    137137
    138     clientUpdatedFromElement(renderer, newStyle);
    139 }
    140 
    141 void SVGResourcesCache::clientUpdatedFromElement(RenderObject* renderer, const RenderStyle* newStyle)
    142 {
    143     ASSERT(renderer);
    144     ASSERT(renderer->parent());
    145 
     138    // Dynamic changes of CSS properties like 'clip-path' may require us to recompute the associated resources for a renderer.
     139    // FIXME: Avoid passing in a useless StyleDifference, but instead compare oldStyle/newStyle to see which resources changed
     140    // to be able to selectively rebuild individual resources, instead of all of them.
    146141    SVGResourcesCache* cache = resourcesCacheFromRenderObject(renderer);
    147142    cache->removeResourcesFromRenderObject(renderer);
    148143    cache->addResourcesFromRenderObject(renderer, newStyle);
     144
     145    RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer, false);
     146}
     147
     148static inline bool rendererCanHaveResources(RenderObject* renderer)
     149{
     150    ASSERT(renderer);
     151    ASSERT(renderer->parent());
     152    return renderer->node() && !renderer->isSVGInlineText();
     153}
     154
     155void SVGResourcesCache::clientWasAddedToTree(RenderObject* renderer, const RenderStyle* newStyle)
     156{
     157    if (!rendererCanHaveResources(renderer))
     158        return;
     159    SVGResourcesCache* cache = resourcesCacheFromRenderObject(renderer);
     160    cache->addResourcesFromRenderObject(renderer, newStyle);
     161}
     162
     163void SVGResourcesCache::clientWillBeRemovedFromTree(RenderObject* renderer)
     164{
     165    if (!rendererCanHaveResources(renderer))
     166        return;
     167    SVGResourcesCache* cache = resourcesCacheFromRenderObject(renderer);
     168    cache->removeResourcesFromRenderObject(renderer);
    149169
    150170    RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer, false);
  • trunk/Source/WebCore/rendering/svg/SVGResourcesCache.h

    r117971 r118608  
    3838    ~SVGResourcesCache();
    3939
    40     void addResourcesFromRenderObject(RenderObject*, const RenderStyle*);
    41     void removeResourcesFromRenderObject(RenderObject*);
    4240    static SVGResources* cachedResourcesForRenderObject(const RenderObject*);
     41
     42    // Called from all SVG renderers addChild() methods.
     43    static void clientWasAddedToTree(RenderObject*, const RenderStyle* newStyle);
     44
     45    // Called from all SVG renderers removeChild() methods.
     46    static void clientWillBeRemovedFromTree(RenderObject*);
    4347
    4448    // Called from all SVG renderers destroy() methods - except for RenderSVGResourceContainer.
     
    5155    static void clientStyleChanged(RenderObject*, StyleDifference, const RenderStyle* newStyle);
    5256
    53     // Called from all SVG renderers updateFromElement() methods.
    54     static void clientUpdatedFromElement(RenderObject*, const RenderStyle* newStyle);
    55 
    5657    // Called from RenderSVGResourceContainer::willBeDestroyed().
    5758    static void resourceDestroyed(RenderSVGResourceContainer*);
    5859
    5960private:
     61    void addResourcesFromRenderObject(RenderObject*, const RenderStyle*);
     62    void removeResourcesFromRenderObject(RenderObject*);
     63
    6064    HashMap<const RenderObject*, SVGResources*> m_cache;
    6165};
  • trunk/Source/WebCore/svg/SVGStyledElement.cpp

    r118192 r118608  
    351351}
    352352
    353 void SVGStyledElement::attach()
    354 {
    355     SVGElement::attach();
    356 
    357     if (RenderObject* object = renderer())
    358         object->updateFromElement();
    359 }
    360 
    361353Node::InsertionNotificationRequest SVGStyledElement::insertedInto(ContainerNode* rootParent)
    362354{
  • trunk/Source/WebCore/svg/SVGStyledElement.h

    r118192 r118608  
    7272    virtual void svgAttributeChanged(const QualifiedName&);
    7373
    74     virtual void attach();
    7574    virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
    7675    virtual void removedFrom(ContainerNode*) OVERRIDE;
Note: See TracChangeset for help on using the changeset viewer.