xbmc / xbmc/imagedecoder.svg

Animated SVG: what it would actually take

Open
#3 0 comments 1 reaction 0 assignees View on GitHub

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:

  1. Animation is not on IImage. Frame iteration exists only as ReadFrame() on the concrete CFFmpegImage. ImageFactory hands back an IImage*, so by the time you have a decoder you can no longer ask whether it has frames.
  2. CTextureManager::Load() switches on file extension.gif and .apng are hardcoded and routed straight to CFFmpegImage, bypassing ImageFactory entirely. An add-on registered for image/svg+xml never 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

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.