feat(svg): real-DOM SVG with SMIL, GPU rendering and shared sources - #153
Merged
Merged
Conversation
- canvas-svg crate: live SvgDocument DOM (nodes, attrs, frame scheduling) with its own SMIL engine, plus a C ABI crate (canvas-svg-c) - GPU backends: GL/Vulkan on Android (TextureView/SurfaceView hosts), Metal on iOS/tvOS/visionOS, with context-loss recovery and CPU fallback - Real element classes in @nativescript/canvas-svg backed by native nodes; same-src views share one document, clock and SkPicture - JSI module install on both platforms; tSpan + CharacterData in polyfill - canvas-core: Vulkan present/rebuild no longer panics on surface loss, drop leaked autorelease pools in Metal context - bump skia fork, packages to 3.0.0-alpha.12
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Advanced Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
- drawImage/createPattern/drawAtlas, texImage2D/texSubImage2D/texImage3D, createImageBitmap and copyExternalImageToTexture accept an Svg view (or polyfill <svg> element): the current frame, rasterized at the size it lands at for drawImage, reused until the document changes - ImageAsset.loadSvg/loadSvgSync for markup, paths, URLs and views, with width/height/scale/time options; <img> SVG sources use the same loader - canvas-svg registers the provider on import, so canvas keeps no dependency on it - ImageAsset.loadFromBytesSync takes a premultiplied flag; SVG rasters were being premultiplied twice (canvas aar rebuilt for the JSI change) - drop the dead _svg branches that called the removed getBitmap()
… frames - the Android aar and jniLibs were built before setText and the current frame/SMIL/GPU code, so text mutations threw on Android; rebuilt all four ABIs from current source (JSI lib now ships for every ABI) and regenerated the cbindgen header - NSCSVG.onDraw skipped the bitmap only for the single-threaded context, and nothing invalidated once a GPU context came up, so Android kept replaying an earlier bitmap frame under the GPU one (doubled shapes, removed nodes still visible) - exclude libNativeScript.so from the aar, as canvas does
…ontext use - one process-wide render thread serves every threaded Svg view (was a thread and wakeup per view); threaded is now the default on both platforms, as browsers raster off the main thread - canvas-2d binds its GL context before every draw and before texture promotion: Skia uploads a pattern's image while recording the draw, so with two GL canvases it landed in the other context (black or wrong pattern on Android) - GL resize keeps its Skia context instead of creating a second one on the same EGL context - SVG snapshots bypass the views' shared frame cache, which only holds four sizes - make exports the SDKROOT and deployment targets Xcode uses: cargo tracks them, so every make/Xcode switch rebuilt all Apple slices from scratch (~52 min for canvas); a no-change round is now seconds - canvas and canvas-svg binaries rebuilt for all Android ABIs and Apple
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Reworks
@nativescript/canvas-svgfrom a render-a-string component into a live SVG DOM: real element objects backed by native nodes, animated with SMIL, and drawn on the GPU.What's in it
Native (
crates/canvas-svg, newcrates/canvas-svg-c)SvgDocument: a mutable DOM (nodes, attributes, frame scheduling). Mutations coalesce into one redraw per frame.<animate>,<animateTransform>,<animateMotion>,<set>@keyframesfrom<style>blocks, via theanimationshorthand or longhands. These become the same animation records SMIL uses.crates/canvas-svg/tests.Rendering
TextureView(default) orSurfaceViewhosts. The bitmap path stays as the fallback.SVGMetalView, with the CPU path as the fallback.threaded(on by default) records on the UI thread and rasterizes on one render thread shared by every threaded view. If the GPU context is lost it gets rebuilt; if rebuilding fails, rendering drops to the CPU path and firescontextLost/contextRestored.srcshare one document, clock andSkPicture.JS (
packages/canvas-svg,packages/canvas-polyfill)NativeNode.ts).TSpanis new.SVGTSpanElement, plusCharacterData/Textfixes so text nodes work inside SVG.SVG as a canvas image source
drawImage,createPattern,drawAtlas, WebGLtexImage2D/texSubImage2D/texImage3D,createImageBitmapand WebGPUcopyExternalImageToTextureaccept anSvgview or polyfill<svg>element. They get the current frame;drawImagerasterizes at the drawn size, and an unchanged frame is reused.ImageAsset.loadSvg/loadSvgSyncfor markup, paths, URLs and views, withwidth,height,scaleandtimeoptions. SVG<img>sources use the same loader.ImageAsset.loadFromBytesSynctakes apremultipliedflag (JSI change; canvas aar rebuilt, Rust libs unchanged). SVG rasters were premultiplied twice before.canvas-2d
canvas-core
PresentStatus) instead of panicking, and the swapchain is rebuilt.NSAutoreleasePoolheld onMetalContext/MetalTexture, which was leaking.Other
b9d2907) and addedquick-xml.3.0.0-alpha.12..aar/.sofor all four ABIs. The canvas-svg aar no longer bundleslibNativeScript.so.makeexports theSDKROOTand deployment targets Xcode uses. Cargo tracks them, so before this every switch betweenmakeand the xcframework build recompiled every Apple slice from scratch, std included (about 52 minutes for canvas). A no-change round now takes seconds.tools/demo/canvas-svgis now a grid of test tiles (shapes, mutation, SMIL, a 200+ element exported animation, a CSS@keyframesexport, and shared-src views).Testing
makehost tests forcanvas-svgsimctl spawndrawImage(svgView)calls) and a Galaxy A53.nsc-svg-renderthread for the whole demo page on the A53; host tests cover the lifecycle.Known issue (pre-existing)
On Android GL, in roughly 1 of 5 launches the first image
drawImageafterclearRectis lost for the whole run. It reproduces on the previous canvas code, without SVG and without render threads, so it is not caused by this PR. Root cause still open.