Title: [195411] trunk
Revision
195411
Author
commit-qu...@webkit.org
Date
2016-01-21 09:50:26 -0800 (Thu, 21 Jan 2016)

Log Message

A crash reproducible in Path::isEmpty() under RenderSVGShape::paint()
https://bugs.webkit.org/show_bug.cgi?id=149613

Patch by Said Abou-Hallawa <sabouhall...@apple.com> on 2016-01-21
Reviewed by Darin Adler.
Source/WebCore:

When RenderSVGRoot::layout() realizes its layout size has changed and
it has resources which have relative sizes, it marks all the clients of
the resources for invalidates regardless whether they belong to the
same RenderSVGRoot or not. But it reruns the layout only for its children.
If one of these clients comes before the current RenderSVGRoot in the render
tree, ee end up having renderer marked for invalidation at rendering time.
This also prevents scheduling the layout if the same renderer is marked
for another invalidation later. We prevent this because we do not want
to schedule another layout for a renderer which is already marked for
invalidation. This can cause crash if the renderer is an RenderSVGPath.

The fix is to mark "only" the clients of a resource which belong to the
same RenderSVGRoot of the resource. Also we need to run the layout for
all the resources which belong to different RenderSVGRoots before running
the layout for an SVG renderer.

Tests: svg/custom/filter-update-different-root.html
       svg/custom/pattern-update-different-root.html

* rendering/svg/RenderSVGResourceContainer.cpp:
(WebCore::RenderSVGResourceContainer::markAllClientsForInvalidation):
We should not mark any client outside the current root for invalidation

* rendering/svg/RenderSVGResourceContainer.h: Remove unneeded private keyword.

* rendering/svg/RenderSVGRoot.cpp:
(WebCore::RenderSVGRoot::addResourceForClientInvalidation):
Code clean up; use findTreeRootObject() instead of repeating the same code.

* rendering/svg/RenderSVGShape.cpp:
(WebCore::RenderSVGShape::isEmpty): Avoid crashing if RenderSVGShape::isEmpty()
is called before calling RenderSVGShape::layout().

* rendering/svg/RenderSVGText.cpp:
(WebCore::RenderSVGText::layout): findTreeRootObject() now returns a pointer.

* rendering/svg/SVGRenderSupport.cpp:
(WebCore::SVGRenderSupport::findTreeRootObject): I do think nothing
guarantees that an SVG renderer has to have an RenderSVGRoot in its
ancestors. So change this function to return a pointer. Also Provide
the non-const version of this function.

(WebCore::SVGRenderSupport::layoutDifferentRootIfNeeded): Runs the layout
if needed for all the resources which belong to different RenderSVGRoots.

(WebCore::SVGRenderSupport::layoutChildren): Make sure all the renderer's
resources which belong to different RenderSVGRoots are laid out before
running the layout for this renderer.

* rendering/svg/SVGRenderSupport.h: Remove a mysterious comment.

* rendering/svg/SVGResources.cpp:
(WebCore::SVGResources::layoutDifferentRootIfNeeded): Run the layout for
all the resources which belong to different RenderSVGRoots outside the
context of their RenderSVGRoots.

* rendering/svg/SVGResources.h:
(WebCore::SVGResources::clipper):
(WebCore::SVGResources::markerStart):
(WebCore::SVGResources::markerMid):
(WebCore::SVGResources::markerEnd):
(WebCore::SVGResources::masker):
(WebCore::SVGResources::filter):
(WebCore::SVGResources::fill):
(WebCore::SVGResources::stroke):
Code clean up; use nullptr instead of 0.

LayoutTests:

When running the layout of an SVG root and it has resources which are
referenced by clients in other SVG roots, make sure we run the layout
for these resources before running the layout for their clients.

* svg/custom/filter-update-different-root-expected.html: Added.
* svg/custom/filter-update-different-root.html: Added.
Without this patch this test crashes because we paint a dirty RenderSVGShape.

* svg/custom/pattern-update-different-root-expected.html: Added.
* svg/custom/pattern-update-different-root.html: Added.
Without this patch this test works fine but it is good to have it to catch
cases where the SVG root needs to run re-layout for its children resources
and hence their clients if its size has changed.

* svg/custom/unicode-in-tspan-multi-svg-crash-expected.txt:
* svg/custom/unicode-in-tspan-multi-svg-crash.html:
This test was ported from Blink in http://trac.webkit.org/changeset/166420.
The expectation of this test was changed in Blink:
https://src.chromium.org/viewvc/blink?revision=158480&view=revision.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (195410 => 195411)


--- trunk/LayoutTests/ChangeLog	2016-01-21 17:15:16 UTC (rev 195410)
+++ trunk/LayoutTests/ChangeLog	2016-01-21 17:50:26 UTC (rev 195411)
@@ -1,3 +1,31 @@
+2016-01-21  Said Abou-Hallawa  <sabouhall...@apple.com>
+
+        A crash reproducible in Path::isEmpty() under RenderSVGShape::paint()
+        https://bugs.webkit.org/show_bug.cgi?id=149613
+
+        Reviewed by Darin Adler.
+        
+        When running the layout of an SVG root and it has resources which are
+        referenced by clients in other SVG roots, make sure we run the layout
+        for these resources before running the layout for their clients.
+
+        * svg/custom/filter-update-different-root-expected.html: Added.
+        * svg/custom/filter-update-different-root.html: Added.
+        Without this patch this test crashes because we paint a dirty RenderSVGShape.
+        
+        * svg/custom/pattern-update-different-root-expected.html: Added.
+        * svg/custom/pattern-update-different-root.html: Added.
+        Without this patch this test works fine but it is good to have it to catch
+        cases where the SVG root needs to run re-layout for its children resources
+        and hence their clients if its size has changed.
+
+        * svg/custom/unicode-in-tspan-multi-svg-crash-expected.txt:
+        * svg/custom/unicode-in-tspan-multi-svg-crash.html:
+        This test was ported from Blink in http://trac.webkit.org/changeset/166420.
+        The expectation of this test was changed in Blink:
+        https://src.chromium.org/viewvc/blink?revision=158480&view=revision.
+        
+
 2016-01-21  Nan Wang  <n_w...@apple.com>
 
         AX: [IOS] Implement next/previous text marker functions using TextIterator

Added: trunk/LayoutTests/svg/custom/filter-update-different-root-expected.html (0 => 195411)


--- trunk/LayoutTests/svg/custom/filter-update-different-root-expected.html	                        (rev 0)
+++ trunk/LayoutTests/svg/custom/filter-update-different-root-expected.html	2016-01-21 17:50:26 UTC (rev 195411)
@@ -0,0 +1,8 @@
+<!DOCTYPE html>
+<html>
+<body>
+    <svg>
+        <rect width="200" height="100" fill="green"/>
+    </svg>
+</body>
+</html>
\ No newline at end of file

Added: trunk/LayoutTests/svg/custom/filter-update-different-root.html (0 => 195411)


--- trunk/LayoutTests/svg/custom/filter-update-different-root.html	                        (rev 0)
+++ trunk/LayoutTests/svg/custom/filter-update-different-root.html	2016-01-21 17:50:26 UTC (rev 195411)
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <style>
+    .dummy { }
+    .hide-second-path > .second-path { display: none; }
+  </style>
+</head>
+<body>
+    <svg style="background-color: #fff">
+        <g id="parent-group" class="hide-second-path">
+            <path id="id1" d="m 0,0 H 100 V 100 H 0 z" fill="red"/>
+            <path id="id2" d="m 0,0 H 100 V 100 H 0 z" fill="green" class="second-path"/>
+            <g id="child-group" filter="url(#nop-filter)">
+                <path id="id3" d="m 100,0 H 200 V 100 H 100 z" fill="green"/>
+                <path id="id4" d="m 100,0 H 200 V 100 H 100 z" fill="red" class="second-path"/>
+            </g>
+        </g>
+    </svg>
+    <svg>
+        <filter id="nop-filter">
+            <feOffset dx="0" dy="0"/>
+        </filter>
+    </svg>
+    <script>
+        if (window.testRunner)
+            testRunner.waitUntilDone();
+        setTimeout(function() {
+            document.styleSheets[0].deleteRule(0);
+            setTimeout(function() {
+                document.getElementById('parent-group').removeAttribute('class');
+                document.getElementById('child-group').setAttribute('class', 'hide-second-path');
+                if (window.testRunner)
+                    testRunner.notifyDone();
+              }, 50);
+          }, 50);
+    </script>
+</body>
+</html>
\ No newline at end of file

Added: trunk/LayoutTests/svg/custom/pattern-update-different-root-expected.html (0 => 195411)


--- trunk/LayoutTests/svg/custom/pattern-update-different-root-expected.html	                        (rev 0)
+++ trunk/LayoutTests/svg/custom/pattern-update-different-root-expected.html	2016-01-21 17:50:26 UTC (rev 195411)
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+    svg {
+        width: 100px;
+        height: 100px;
+    }
+</style>
+</head>
+<body>
+    <svg>
+        <rect width="100%" height="100%" fill="green"/>
+    </svg>
+</body>
+</html>

Added: trunk/LayoutTests/svg/custom/pattern-update-different-root.html (0 => 195411)


--- trunk/LayoutTests/svg/custom/pattern-update-different-root.html	                        (rev 0)
+++ trunk/LayoutTests/svg/custom/pattern-update-different-root.html	2016-01-21 17:50:26 UTC (rev 195411)
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+    svg {
+        width: 100px;
+        height: 100px;
+    }
+</style>
+</head>
+<body>
+    <svg>
+        <pattern id="r1" width="100%" height="100%" xlink:href="" patternUnits="userSpaceOnUse"/>
+        <rect width="100%" height="100%" fill="url(#r1)"/>
+    </svg>
+    <svg>
+        <pattern id="r2">
+            <rect width="100%" height="100%" fill="green"/>
+        </pattern>
+    </svg>
+</body>
+</html>

Modified: trunk/LayoutTests/svg/custom/unicode-in-tspan-multi-svg-crash-expected.txt (195410 => 195411)


--- trunk/LayoutTests/svg/custom/unicode-in-tspan-multi-svg-crash-expected.txt	2016-01-21 17:15:16 UTC (rev 195410)
+++ trunk/LayoutTests/svg/custom/unicode-in-tspan-multi-svg-crash-expected.txt	2016-01-21 17:50:26 UTC (rev 195411)
@@ -1,2 +1,3 @@
+
  
-Test Passes if there is no crash in Debug or Asan builds. There should be no characters preceding "Test".
+Test Passes if there is no crash in Debug or Asan builds.

Modified: trunk/LayoutTests/svg/custom/unicode-in-tspan-multi-svg-crash.html (195410 => 195411)


--- trunk/LayoutTests/svg/custom/unicode-in-tspan-multi-svg-crash.html	2016-01-21 17:15:16 UTC (rev 195410)
+++ trunk/LayoutTests/svg/custom/unicode-in-tspan-multi-svg-crash.html	2016-01-21 17:50:26 UTC (rev 195411)
@@ -33,6 +33,6 @@
       <filter id="filterInSecondRoot"/>
     </svg>
 
-    <p>Test Passes if there is no crash in Debug or Asan builds. There should be no characters preceding "Test".</p>
+    <p>Test Passes if there is no crash in Debug or Asan builds.</p>
   </body>
 </html>

Modified: trunk/Source/WebCore/ChangeLog (195410 => 195411)


--- trunk/Source/WebCore/ChangeLog	2016-01-21 17:15:16 UTC (rev 195410)
+++ trunk/Source/WebCore/ChangeLog	2016-01-21 17:50:26 UTC (rev 195411)
@@ -1,3 +1,77 @@
+2016-01-21  Said Abou-Hallawa  <sabouhall...@apple.com>
+
+        A crash reproducible in Path::isEmpty() under RenderSVGShape::paint()
+        https://bugs.webkit.org/show_bug.cgi?id=149613
+
+        Reviewed by Darin Adler.
+
+        When RenderSVGRoot::layout() realizes its layout size has changed and
+        it has resources which have relative sizes, it marks all the clients of
+        the resources for invalidates regardless whether they belong to the
+        same RenderSVGRoot or not. But it reruns the layout only for its children.
+        If one of these clients comes before the current RenderSVGRoot in the render
+        tree, ee end up having renderer marked for invalidation at rendering time.
+        This also prevents scheduling the layout if the same renderer is marked
+        for another invalidation later. We prevent this because we do not want
+        to schedule another layout for a renderer which is already marked for
+        invalidation. This can cause crash if the renderer is an RenderSVGPath.
+        
+        The fix is to mark "only" the clients of a resource which belong to the
+        same RenderSVGRoot of the resource. Also we need to run the layout for
+        all the resources which belong to different RenderSVGRoots before running
+        the layout for an SVG renderer.
+         
+        Tests: svg/custom/filter-update-different-root.html
+               svg/custom/pattern-update-different-root.html
+
+        * rendering/svg/RenderSVGResourceContainer.cpp:
+        (WebCore::RenderSVGResourceContainer::markAllClientsForInvalidation):
+        We should not mark any client outside the current root for invalidation
+        
+        * rendering/svg/RenderSVGResourceContainer.h: Remove unneeded private keyword.
+        
+        * rendering/svg/RenderSVGRoot.cpp:
+        (WebCore::RenderSVGRoot::addResourceForClientInvalidation):
+        Code clean up; use findTreeRootObject() instead of repeating the same code.
+        
+        * rendering/svg/RenderSVGShape.cpp:
+        (WebCore::RenderSVGShape::isEmpty): Avoid crashing if RenderSVGShape::isEmpty()
+        is called before calling RenderSVGShape::layout().
+         
+        * rendering/svg/RenderSVGText.cpp:
+        (WebCore::RenderSVGText::layout): findTreeRootObject() now returns a pointer.
+        
+        * rendering/svg/SVGRenderSupport.cpp:
+        (WebCore::SVGRenderSupport::findTreeRootObject): I do think nothing 
+        guarantees that an SVG renderer has to have an RenderSVGRoot in its
+        ancestors. So change this function to return a pointer. Also Provide
+        the non-const version of this function.
+         
+        (WebCore::SVGRenderSupport::layoutDifferentRootIfNeeded): Runs the layout
+        if needed for all the resources which belong to different RenderSVGRoots.
+        
+        (WebCore::SVGRenderSupport::layoutChildren): Make sure all the renderer's
+        resources which belong to different RenderSVGRoots are laid out before
+        running the layout for this renderer.
+        
+        * rendering/svg/SVGRenderSupport.h: Remove a mysterious comment.
+        
+        * rendering/svg/SVGResources.cpp:
+        (WebCore::SVGResources::layoutDifferentRootIfNeeded): Run the layout for
+        all the resources which belong to different RenderSVGRoots outside the
+        context of their RenderSVGRoots.
+        
+        * rendering/svg/SVGResources.h:
+        (WebCore::SVGResources::clipper):
+        (WebCore::SVGResources::markerStart):
+        (WebCore::SVGResources::markerMid):
+        (WebCore::SVGResources::markerEnd):
+        (WebCore::SVGResources::masker):
+        (WebCore::SVGResources::filter):
+        (WebCore::SVGResources::fill):
+        (WebCore::SVGResources::stroke):
+        Code clean up; use nullptr instead of 0.
+
 2016-01-21  Jer Noble  <jer.no...@apple.com>
 
         [EME] Correctly report errors when generating key requests from AVContentKeySession.

Modified: trunk/Source/WebCore/rendering/svg/RenderSVGResourceContainer.cpp (195410 => 195411)


--- trunk/Source/WebCore/rendering/svg/RenderSVGResourceContainer.cpp	2016-01-21 17:15:16 UTC (rev 195410)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGResourceContainer.cpp	2016-01-21 17:50:26 UTC (rev 195411)
@@ -94,8 +94,13 @@
     m_isInvalidating = true;
     bool needsLayout = mode == LayoutAndBoundariesInvalidation;
     bool markForInvalidation = mode != ParentOnlyInvalidation;
+    auto* root = SVGRenderSupport::findTreeRootObject(*this);
 
     for (auto* client : m_clients) {
+        // We should not mark any client outside the current root for invalidation
+        if (root != SVGRenderSupport::findTreeRootObject(*client))
+            continue;
+
         if (is<RenderSVGResourceContainer>(*client)) {
             downcast<RenderSVGResourceContainer>(*client).removeAllClientsFromCache(markForInvalidation);
             continue;

Modified: trunk/Source/WebCore/rendering/svg/RenderSVGResourceContainer.h (195410 => 195411)


--- trunk/Source/WebCore/rendering/svg/RenderSVGResourceContainer.h	2016-01-21 17:15:16 UTC (rev 195410)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGResourceContainer.h	2016-01-21 17:50:26 UTC (rev 195411)
@@ -66,7 +66,6 @@
     void addClient(RenderElement&);
     void removeClient(RenderElement&);
 
-private:
     virtual void willBeDestroyed() override final;
     void registerResource();
 

Modified: trunk/Source/WebCore/rendering/svg/RenderSVGRoot.cpp (195410 => 195411)


--- trunk/Source/WebCore/rendering/svg/RenderSVGRoot.cpp	2016-01-21 17:15:16 UTC (rev 195410)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGRoot.cpp	2016-01-21 17:50:26 UTC (rev 195411)
@@ -455,12 +455,10 @@
 
 void RenderSVGRoot::addResourceForClientInvalidation(RenderSVGResourceContainer* resource)
 {
-    RenderElement* svgRoot = resource->parent();
-    while (svgRoot && !is<RenderSVGRoot>(*svgRoot))
-        svgRoot = svgRoot->parent();
+    RenderSVGRoot* svgRoot = SVGRenderSupport::findTreeRootObject(*resource);
     if (!svgRoot)
         return;
-    downcast<RenderSVGRoot>(*svgRoot).m_resourcesNeedingToInvalidateClients.add(resource);
+    svgRoot->m_resourcesNeedingToInvalidateClients.add(resource);
 }
 
 }

Modified: trunk/Source/WebCore/rendering/svg/RenderSVGShape.cpp (195410 => 195411)


--- trunk/Source/WebCore/rendering/svg/RenderSVGShape.cpp	2016-01-21 17:15:16 UTC (rev 195410)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGShape.cpp	2016-01-21 17:50:26 UTC (rev 195411)
@@ -89,7 +89,11 @@
 
 bool RenderSVGShape::isEmpty() const
 {
-    return path().isEmpty();
+    // This function should never be called before assigning a new Path to m_path.
+    // But this bug can happen if this renderer was created and its layout was not
+    // done before painting. Assert this did not happen but do not crash.
+    ASSERT(hasPath());
+    return !hasPath() || path().isEmpty();
 }
 
 void RenderSVGShape::fillShape(GraphicsContext& context) const

Modified: trunk/Source/WebCore/rendering/svg/RenderSVGText.cpp (195410 => 195411)


--- trunk/Source/WebCore/rendering/svg/RenderSVGText.cpp	2016-01-21 17:15:16 UTC (rev 195410)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGText.cpp	2016-01-21 17:50:26 UTC (rev 195411)
@@ -369,7 +369,7 @@
         m_needsReordering = true;
         m_needsPositioningValuesUpdate = false;
         updateCachedBoundariesInParents = true;
-    } else if (m_needsTextMetricsUpdate || SVGRenderSupport::findTreeRootObject(*this).isLayoutSizeChanged()) {
+    } else if (m_needsTextMetricsUpdate || SVGRenderSupport::findTreeRootObject(*this)->isLayoutSizeChanged()) {
         // If the root layout size changed (eg. window size changes) or the transform to the root
         // context has changed then recompute the on-screen font size.
         updateFontInAllDescendants(this, &m_layoutAttributesBuilder);

Modified: trunk/Source/WebCore/rendering/svg/SVGRenderSupport.cpp (195410 => 195411)


--- trunk/Source/WebCore/rendering/svg/SVGRenderSupport.cpp	2016-01-21 17:15:16 UTC (rev 195410)
+++ trunk/Source/WebCore/rendering/svg/SVGRenderSupport.cpp	2016-01-21 17:50:26 UTC (rev 195411)
@@ -184,11 +184,16 @@
     return localTransform.mapRect(localRepaintRect).intersects(paintInfo.rect);
 }
 
-const RenderSVGRoot& SVGRenderSupport::findTreeRootObject(const RenderElement& start)
+RenderSVGRoot* SVGRenderSupport::findTreeRootObject(RenderElement& start)
 {
-    return *lineageOfType<RenderSVGRoot>(start).first();
+    return lineageOfType<RenderSVGRoot>(start).first();
 }
 
+const RenderSVGRoot* SVGRenderSupport::findTreeRootObject(const RenderElement& start)
+{
+    return lineageOfType<RenderSVGRoot>(start).first();
+}
+
 static inline void invalidateResourcesOfChildren(RenderElement& renderer)
 {
     ASSERT(!renderer.needsLayout());
@@ -225,6 +230,15 @@
     return false;
 }
 
+void SVGRenderSupport::layoutDifferentRootIfNeeded(const RenderElement& renderer)
+{
+    if (auto* resources = SVGResourcesCache::cachedResourcesForRenderer(renderer)) {
+        auto* svgRoot = SVGRenderSupport::findTreeRootObject(renderer);
+        ASSERT(svgRoot);
+        resources->layoutDifferentRootIfNeeded(svgRoot);
+    }
+}
+
 void SVGRenderSupport::layoutChildren(RenderElement& start, bool selfNeedsLayout)
 {
     bool layoutSizeChanged = layoutSizeOfNearestViewportChanged(start);
@@ -273,6 +287,7 @@
             child->setNeedsLayout(MarkOnlyThis);
 
         if (child->needsLayout()) {
+            layoutDifferentRootIfNeeded(downcast<RenderElement>(*child));
             downcast<RenderElement>(*child).layout();
             // Renderers are responsible for repainting themselves when changing, except
             // for the initial paint to avoid potential double-painting caused by non-sensical "old" bounds.

Modified: trunk/Source/WebCore/rendering/svg/SVGRenderSupport.h (195410 => 195411)


--- trunk/Source/WebCore/rendering/svg/SVGRenderSupport.h	2016-01-21 17:15:16 UTC (rev 195410)
+++ trunk/Source/WebCore/rendering/svg/SVGRenderSupport.h	2016-01-21 17:50:26 UTC (rev 195411)
@@ -44,6 +44,8 @@
 // SVGRendererSupport is a helper class sharing code between all SVG renderers.
 class SVGRenderSupport {
 public:
+    static void layoutDifferentRootIfNeeded(const RenderElement&);
+
     // Shares child layouting code between RenderSVGRoot/RenderSVG(Hidden)Container
     static void layoutChildren(RenderElement&, bool selfNeedsLayout);
 
@@ -91,8 +93,8 @@
     static void updateMaskedAncestorShouldIsolateBlending(const RenderElement&);
 #endif
 
-    // FIXME: These methods do not belong here.
-    static const RenderSVGRoot& findTreeRootObject(const RenderElement&);
+    static RenderSVGRoot* findTreeRootObject(RenderElement&);
+    static const RenderSVGRoot* findTreeRootObject(const RenderElement&);
 
 private:
     // This class is not constructable.

Modified: trunk/Source/WebCore/rendering/svg/SVGResources.cpp (195410 => 195411)


--- trunk/Source/WebCore/rendering/svg/SVGResources.cpp	2016-01-21 17:15:16 UTC (rev 195410)
+++ trunk/Source/WebCore/rendering/svg/SVGResources.cpp	2016-01-21 17:50:26 UTC (rev 195411)
@@ -25,6 +25,7 @@
 #include "RenderSVGResourceFilter.h"
 #include "RenderSVGResourceMarker.h"
 #include "RenderSVGResourceMasker.h"
+#include "RenderSVGRoot.h"
 #include "SVGGradientElement.h"
 #include "SVGNames.h"
 #include "SVGPaint.h"
@@ -283,6 +284,27 @@
     return foundResources;
 }
 
+void SVGResources::layoutDifferentRootIfNeeded(const RenderSVGRoot* svgRoot)
+{
+    if (clipper() && svgRoot != SVGRenderSupport::findTreeRootObject(*clipper()))
+        clipper()->layoutIfNeeded();
+
+    if (masker() && svgRoot != SVGRenderSupport::findTreeRootObject(*masker()))
+        masker()->layoutIfNeeded();
+
+    if (filter() && svgRoot != SVGRenderSupport::findTreeRootObject(*filter()))
+        filter()->layoutIfNeeded();
+
+    if (markerStart() && svgRoot != SVGRenderSupport::findTreeRootObject(*markerStart()))
+        markerStart()->layoutIfNeeded();
+
+    if (markerMid() && svgRoot != SVGRenderSupport::findTreeRootObject(*markerMid()))
+        markerMid()->layoutIfNeeded();
+
+    if (markerEnd() && svgRoot != SVGRenderSupport::findTreeRootObject(*markerEnd()))
+        markerEnd()->layoutIfNeeded();
+}
+
 void SVGResources::removeClientFromCache(RenderElement& renderer, bool markForInvalidation) const
 {
     if (!m_clipperFilterMaskerData && !m_markerData && !m_fillStrokeData && !m_linkedResource)

Modified: trunk/Source/WebCore/rendering/svg/SVGResources.h (195410 => 195411)


--- trunk/Source/WebCore/rendering/svg/SVGResources.h	2016-01-21 17:15:16 UTC (rev 195410)
+++ trunk/Source/WebCore/rendering/svg/SVGResources.h	2016-01-21 17:50:26 UTC (rev 195411)
@@ -35,6 +35,7 @@
 class RenderSVGResourceFilter;
 class RenderSVGResourceMarker;
 class RenderSVGResourceMasker;
+class RenderSVGRoot;
 class SVGRenderStyle;
 
 // Holds a set of resources associated with a RenderObject
@@ -44,24 +45,19 @@
     SVGResources();
 
     bool buildCachedResources(const RenderElement&, const RenderStyle&);
+    void layoutDifferentRootIfNeeded(const RenderSVGRoot*);
 
     // Ordinary resources
-    RenderSVGResourceClipper* clipper() const { return m_clipperFilterMaskerData ? m_clipperFilterMaskerData->clipper : 0; }
-    RenderSVGResourceMarker* markerStart() const { return m_markerData ? m_markerData->markerStart : 0; }
-    RenderSVGResourceMarker* markerMid() const { return m_markerData ? m_markerData->markerMid : 0; }
-    RenderSVGResourceMarker* markerEnd() const { return m_markerData ? m_markerData->markerEnd : 0; }
-    RenderSVGResourceMasker* masker() const { return m_clipperFilterMaskerData ? m_clipperFilterMaskerData->masker : 0; }
+    RenderSVGResourceClipper* clipper() const { return m_clipperFilterMaskerData ? m_clipperFilterMaskerData->clipper : nullptr; }
+    RenderSVGResourceMarker* markerStart() const { return m_markerData ? m_markerData->markerStart : nullptr; }
+    RenderSVGResourceMarker* markerMid() const { return m_markerData ? m_markerData->markerMid : nullptr; }
+    RenderSVGResourceMarker* markerEnd() const { return m_markerData ? m_markerData->markerEnd : nullptr; }
+    RenderSVGResourceMasker* masker() const { return m_clipperFilterMaskerData ? m_clipperFilterMaskerData->masker : nullptr; }
+    RenderSVGResourceFilter* filter() const { return m_clipperFilterMaskerData ? m_clipperFilterMaskerData->filter : nullptr; }
 
-    RenderSVGResourceFilter* filter() const
-    {
-        if (m_clipperFilterMaskerData)
-            return m_clipperFilterMaskerData->filter;
-        return 0;
-    }
-
     // Paint servers
-    RenderSVGResourceContainer* fill() const { return m_fillStrokeData ? m_fillStrokeData->fill : 0; }
-    RenderSVGResourceContainer* stroke() const { return m_fillStrokeData ? m_fillStrokeData->stroke : 0; }
+    RenderSVGResourceContainer* fill() const { return m_fillStrokeData ? m_fillStrokeData->fill : nullptr; }
+    RenderSVGResourceContainer* stroke() const { return m_fillStrokeData ? m_fillStrokeData->stroke : nullptr; }
 
     // Chainable resources - linked through xlink:href
     RenderSVGResourceContainer* linkedResource() const { return m_linkedResource; }
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to