← 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)는 SVG를 특수 케이스로 처리하던 기존 방식 대신, 표준 CSS layout pipeline에 통합하는 방향으로 SVG rendering backend를 재작성한 결과물입니다. SVG 요소는 실제 RenderLayer 객체를 갖기 때문에, transform 변경 사항은 HTML 요소와 동일한 layer compositing 메커니즘을 통해 전파되어야 합니다. 이전에는 SVG transform의 attribute가 변경될 때마다 즉시 repaint/relayout cycle이 발생했습니다.

이 commit은 변경 발생 시마다 동기적으로 호출하던 방식을 LocalFrameViewLayoutContext 위에 구성된 프레임 단위 batched queue로 대체했습니다. flush는 세 단계로 진행됩니다. 먼저 변경 전 repaint rect를 snapshot으로 저장하고, transform을 변경한 뒤, delta repaint를 방출합니다. 한편 RenderSVGContainerRenderSVGRoot에 dirty bit가 추가되어 bounding box의 지연 재계산이 가능해졌습니다. 이를 통해 layout 비용을 치르지 않고도 getBBox()가 최신 상태를 유지할 수 있습니다.

SVG 애니메이션 실행 중 프레임당 2N번 발생하던 동기 repaint() 호출이 제거되었으며, MotionMark/Suits 벤치마크에서 약 10% 성능 향상이 확인되었습니다. 다만 이번 재구성으로 queued renderer 참조, 새로운 flush 순서 불변식, 지연 무효화 경로가 도입되어 복잡도가 증가했습니다.

🔒

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

더 확인하려면 구독해 주세요