Animated SVG: what it would actually take
Nobody has claimed this yet.
- Dominant language
- Shell
- Stars
- 1
- Forks
- 1
- Avg merge
- 1d 12h
- Merged PRs (30d)
- 4
Description
@garbear — following up on your question on repo-binary-addons#165 — "does this handle animated SVGs?". Short answer stays no, but the reason turned out to be worth writing down, because the blocker is on Kodi's side, not the library's, and it is the same blocker for any animated vector format.
There is no library to swap in
I checked the C/C++ ecosystem for anything that evaluates SVG animation (SMIL or CSS) outside a browser engine:
| library | animation | note |
|---|---|---|
| lunasvg (ours) | no | "animation is unlikely to be supported in the future" — static rendering is the design |
| resvg | no | "No animations. There are no plans on implementing them either." |
| librsvg | no | "Animation, interactivity, and scripting are not supported." |
| ThorVG | no (for SVG) | active, MIT, C++, very portable — but its SVG side lists Animation as unsupported. Its animation support is Lottie |
| plutosvg | no | data:-only, no CSS, no text — the OpenType-glyph renderer |
| plutobook | no | "static layout and print-ready output" |
| Egueb | yes — "Full state DOM, SVG, CSS, SMIL" | last commit 2016, 7 stars. Not a candidate |
| svg-rs | SMIL evaluation only | Rust, no C API, no renderer, first published Feb 2026 |
So the honest position is that SMIL is a browser feature. Everything portable enough for Kodi's platform matrix deliberately implements the static subset.
The Kodi side is the real constraint, and it is format-independent
Kodi's animated-texture machinery is already general and already works. Every texture is a CTextureArray — frames + per-frame delays + loop count (guilib/TextureManager.h) — and a static PNG is just a one-frame animation with delay = 100. CGUITexture::UpdateAnimFrame() walks the delays and honours loops == 0 as loop-forever. Two things are missing to reach it from an add-on:
- Animation is not on
IImage. Frame iteration exists only asReadFrame()on the concreteCFFmpegImage.ImageFactoryhands back anIImage*, so by the time you have a decoder you can no longer ask whether it has frames. CTextureManager::Load()switches on file extension —.gifand.apngare hardcoded and routed straight toCFFmpegImage, bypassingImageFactoryentirely. An add-on registered forimage/svg+xmlnever reaches that branch.
Both have the same fix, and it is a tidy one that deletes special-casing rather than adding it: put a frame-count and frame-read call on IImage (default 1), let CFFmpegImage and CImageDecoder both implement it, and replace the extension sniffing with asking the loader. I would be happy to look into it in more detail — it stands on its own merits regardless of SVG.
But I do not think that gets you what a user expects. Baking a vector animation to a frame list throws away the resolution independence that is the point of vector, and it hits a hard wall: CTextureManager caps animated textures at 91,238,400 bytes, about 12 full-HD frames. At 256×256 that is ~350 frames — fine for a spinner. At anything screen-sized it is a third of a second. A browser does not pre-bake; it re-renders at time t.
Doing that properly needs something Kodi does not have: a time-driven, per-instance texture source. Today CTextureMap is a shared cache keyed by name and size, so two controls showing the same file share one frame list; live re-rendering breaks that sharing model and needs a render-thread callback plus a per-instance GPU texture and a frame budget. That is core work, not an add-on API tweak — and note it is the same missing piece for Lottie, or for any other animated vector format. If it existed, the GIF/APNG path could also stop pre-baking 91 MB of frames.
The one part with a deadline
The library hunt has no deadline. The API shape does. Since you are already rebuilding every imagedecoder add-on for the 3.1.0 bump in #29068, it is worth deciding now whether a frame index belongs in Decode() — putting it in later costs a second ABI break. That decision is independent of whether an animated-SVG renderer ever appears.
Not asking for anything here — just recording what we found so the answer to "why not animation?" is on the record. Happy to take any of it further if you think it is worth doing.
Written by my AI co-author (Claude Code); posted from my account.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with guilib/TextureManager.h, IImage, CFFmpegImage, CImageDecoder, ImageFactory, and CTextureManager::Load(), then review the API discussion in #29068. The immediate outcome is a decision on whether a frame index belongs in Decode(); full animated-vector support would require broader Kodi core work.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- computer-graphics
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100