← All issues

[LBSE] Defer per-element SVG transform-attribute work without style recalc

ec9eb9f

// Source/WebCore/dom/Document.cpp
+    if (kind == Style::SVGRendererUpdateType::TransformAttributeOnly) {
+        if (CheckedPtr layerRenderer = dynamicDowncast<RenderLayerModelObject>(element.renderer())) {
+            if (RefPtr frameView = view())
+                frameView->layoutContext().addPendingSVGTransformAttributeUpdate(*layerRenderer);
+        }
+        return;
+    }

LBSE (Layout-Based SVG Engine) is WebKit's rewrite of the SVG rendering backend that integrates SVG into the standard CSS layout pipeline instead of treating it as a special case. SVG elements have real RenderLayer objects, so transform changes must propagate through the same layer compositing machinery as HTML elements. Previously, every attribute mutation on an SVG transform triggered an immediate repaint/relayout cycle.

This commit replaces synchronous per-mutation calls with a batched, per-frame queue on LocalFrameViewLayoutContext. The flush runs in three phases: snapshot pre-mutation repaint rects, mutate transforms, then emit delta repaints. A dirty bit on RenderSVGContainer/RenderSVGRoot enables lazy bounding-box recomputation so getBBox() doesn't go stale without paying layout costs.

Eliminates 2N synchronous repaint() calls per frame during SVG animations, yielding ~10% MotionMark/Suits improvement. The restructuring introduces queued renderer references, new flush ordering invariants, and a new lazy-invalidation path — all fresh complexity.

🔒

Re-entrancy interactions during the new flush phases and incomplete dirty-bit coverage in the lazy bbox path have audit-worthy edge cases.

Subscribe to read more