This bug tracks the redesign of SVG resources (linear/radialGradient, mask, clipPath, filter, marker). In worst cases we need a 2-pass layout now from RenderSVGRoot, to avoid leaving the render tree with some objects still needing layout after RenderSVGRoot::layout() ran. The question came up why renderers are needed at all for SVG resources. Here's a list of reasons: - CSS Transitions/Animations support currently only work with RenderObjects (bug 87373 contains a fix) - Tracking of style changes (styleDidChange/styleWillChange) - this can be avoided nowadays using nonRendererRenderStyle (bug 86941 eliminates RenderSVGradientStop) These two can easily be fixed. That would already remove the need for <linearGradient> / <radialGradient> / <stop> renderers. But what about <pattern>? <pattern> has children which need to be rendered at some point (indirectly). <svg> <defs> <pattern id="somePattern"> <rect/> </pattern> </defs> <circle fill="url(#somePattern)"/> </svg> Once the <circle> paints, it'll look up the <pattern> fill resource, and apply it to the current rendering context. For that to work we need a renderer for the <rect> that we can paint into an ImageBuffer. In order to create renderers for the <rect> child of the <pattern>, the <pattern> needs a renderer as well: a RenderSVGHiddenContainer, which is never painted directly, nor participates in layout. In ToT the design is similar: RenderSVGResourcePattern inherits from both RenderSVGResource (abstract base class) and RenderSVGResourceContainer, which itself inherits from RenderSVGHiddenContainer. (RenderSVGHiddenContainer::layout() is not a no-op right now, it actually lays out the subtree, otherwise certain assumptions wouldn't hold anymore...) -- In an ideal world RenderSVGHiddenContainer::layout() would be a no-op. All children of the RenderSVGHiddenContainer would always remain in needsLayout=true state, until they're used. As they're used on paint() time, once the (see example above) <circle> paints, we basically would need to layout() the RenderSVGHiddenContainer subtree, while painting. This is dangerous in general, as the <rect> inside the pattern could for instance be used by another <use> element, like this: <svg> <defs> <pattern id="somePattern"> <rect id="rect"/> </pattern> </defs> <use xlink:href="#rect"/> <circle fill="url(#somePattern)"/> </svg> Why is that dangerous? RenderSVGRoot::layout() is invoked, which does nothing for the <defs> element and its subtree, then proceeds laying out the <use> element + cloned shadow tree. After that the <circle> is laid out, and the whole layout() is done, while the <rect> still needs layout. Upon painting the subtree following happens: <defs> doesn't paint anything, the <use> is painted, then the <circle>. Once the <circle> paints the <pattern> children would need to be laid out. As a result of laying out the <rect> the <use> element would be marked as needsLayout=true again. So after RenderSVGRoot::layout() + RenderSVGRoot::paint() we still have an element that needs to be laid out... This example is really basic, we have lots more complex test cases in LayoutTests/svg/ that would break when designing <pattern> like this. It's yet undecided how to fix it for real. We should collect ideas here and prototype them.
Time passed by and I am not sure if we still want to follow this approach. Closing the bug now.