Process-wide cache for parsed SVG documents (SkSVGDOM). More...
Go to the source code of this file.
Process-wide cache for parsed SVG documents (SkSVGDOM).
Canvas::draw_svg parses its SVG string into an SkSVGDOM every call (SkSVGDOM::Builder().make(stream)). For a large faithful design frame — the faithful-vector design-import lane's DesignFrameView, which can carry a 100+ KB SVG — rebuilding that DOM every repaint is wasteful when the document string has not changed: a static design frame, a frame that only has native-overlay children animating, or a high-refresh repaint of unchanged chrome.
This cache stores the parsed DOM keyed on the exact SVG document bytes (FNV-1a hash of the string, plus the length, with a stored copy of the source string to defend against hash collisions). The render itself — dom->render(canvas_) after setContainerSize / scale — is unchanged, so the rasterized output is byte-identical to the uncached path; only the parse step is skipped on a hit.
Crucially the key is the document content, NOT a logical asset id. The DesignFrameView render-patch path (knob needle rotate, fader / xy_pad thumb translate, toggle-switch slide) mutates the SVG string before handing it to draw_svg — wrapping the patched element in a <g transform=...>. A patched string is therefore a different document, so it misses the cache and is re-parsed. That is exactly what keeps a dragged knob live: each value produces a distinct document, each rebuilds its DOM. The cache only ever reuses a DOM when the bytes are identical, so it can never freeze a moving needle. A size change reuses the same DOM and re-applies the scale at draw time (the scale lives in the SkCanvas transform, not the DOM), so resizing is also a cache hit — correctly.
Painting is on the UI thread (not the realtime audio thread), so a small mutex is acceptable; the cache is process-global with an LRU cap. SkSVGDOM is immutable once built and render() only reads it, so a shared sk_sp across frames is safe.