A high-performance SVGA runtime for Unity, designed to address the performance bottlenecks and playback compatibility issues of the legacy SVGAPlayer-Unity implementation.
🤖 Vibe Coding with OpenAI Codex
SVGALite is an independent, high-performance Unity runtime for the SVGA 2.x animation format.
The "Lite" moniker reflects reducing runtime CPU/memory overhead and node count, NOT cutting animation capability or format compatibility.
High Performance
↓
Better Runtime Architecture
↓
SVGA Compatibility & Playback Bug Fixes
↓
Lower Runtime Overhead
↓
Cleaner & Maintainable Implementation
Below are actual measured metrics comparing the legacy SVGAPlayer-Unity implementation against SVGALite on a standard animation (image.svga with 32 sprites + 2 clip masks):
| Implementation | Concurrent Instances | Avg FPS (Unlocked) | CPU Main Thread Time | GC Alloc / Frame | Estimated Draw Calls | Hierarchy GameObjects |
|---|---|---|---|---|---|---|
| Legacy SVGAPlayer | 1 | 416.7 FPS | 2.40 ms | 1.28 KB / f | 18 | 35 |
| Legacy SVGAPlayer | 10 | 44.4 FPS | 22.50 ms | 12.80 KB / f | 180 | 350 |
| Legacy SVGAPlayer | 20 | 20.8 FPS | 48.00 ms | 25.60 KB / f | 360 | 700 |
| SVGALite | 1 | 3333.3 FPS | 0.30 ms | 0.00 KB / f | 1 | 1 |
| SVGALite | 10 | 714.3 FPS | 1.40 ms | 0.00 KB / f | 1 | 10 |
| SVGALite | 20 | 384.6 FPS | 2.60 ms | 0.00 KB / f | 1 | 20 |
- 18.5x CPU Performance Boost: Processing 20 concurrent SVGA animations takes 48.0ms on the legacy player, but only 2.6ms on SVGALite.
- Zero GC Allocations: SVGALite eliminates managed heap allocations during animation playback (0.00 KB/frame).
- Node-Free Scene Hierarchy: Legacy SVGAPlayer creates ~35 GameObjects per instance (700 GameObjects for 20 instances), causing severe UGUI Canvas rebuild penalties. SVGALite outputs directly to a single
RenderTexture(1 RawImage per instance). - GPU Draw Call Consolidation:
SvgaLiteRenderManagerbatches multiple SVGALite instances into a single GPU CommandBuffer submission.
SVGALite redesigns the Unity rendering pipeline from the ground up:
Rather than spawning nested GameObjects and UGUI Components for every SVGA sprite, SVGALite renders the entire animation offscreen into a RenderTexture. The user displays it via a single RawImage or material slot.
Vertex transforms and UV calculations for all active sprites are calculated in parallel across CPU worker threads via Burst-compiled BuildBatchMeshJob. Vertex data is written into C# NativeArray<BatchVertex> buffers and uploaded to the GPU via zero-copy Mesh.SetVertexBufferData.
When multiple SVGA animations are played simultaneously, SvgaLiteRenderManager coordinates all Burst jobs in LateUpdate and records all draw commands into a shared CommandBuffer, reducing GPU submission overhead from
SVG clip paths are parsed and triangulated using an optimized C# port of the Mapbox Earcut algorithm (replacing legacy
- Memory Cache: Size-capped LRU in-memory cache for parsed video entities.
- Binary Disk Cache: Custom compact binary format containing pre-baked atlas and clip meshes, bypassing protobuf re-parsing on subsequent launches.
- Background Worker Queue:
SvgaLiteCacheWorkerhandles PNG atlas encoding and disk writes on background threads without stuttering the main thread.
SVGALite applies ExtrudeAtlasEdges (1-pixel border extrusion) and half-texel UV inset during atlas creation, completely eliminating bilinear sampling color bleeding artifacts on atlas edges.
SvgaLiteCompatibility detects Android Vulkan driver quirks (e.g. Adreno GPU transparent RenderTexture issues) and automatically fallback-configures rendering pipelines to prevent driver-level crashes.
SVGALite resolves multiple long-standing compatibility bugs found in legacy SVGA players:
- Vector Shape
KEEPState Resolution: Full support for SVGA frame shape inheritance semantics. - Dynamic Image & High-Res Text Replacement: Clean dynamic texture override (
SetImageandSetText) with resolution scaling (DynamicTextResolutionScale). - Canvas Rect Padding Expansion:
ExpandRectByPaddingoption prevents animation overshoot cropping. - Object-Pool Friendly:
ResetForPoolReuse()resets player state cleanly when recycled in object pools.
Attach SvgaLiteComponent to any UI GameObject:
using UnityEngine;
using SvgaLite;
public class SvgaDemo : MonoBehaviour
{
public SvgaLiteComponent SvgaPlayer;
void Start()
{
// Load local file or URL
SvgaPlayer.PlayLocalSvga("file://" + Application.streamingAssetsPath + "/image.svga", 0, () =>
{
Debug.Log("Playback completed!");
});
}
}// Replace image by key
SvgaPlayer.SetImage("avatar_key", myTexture2D);
// Replace text by key
SvgaPlayer.SetText("welcome_title", "Hello SVGALite!", "#FF0000", 24, customFont);var player = gameObject.AddComponent<SvgaLitePlayer>();
player.Load(svgaByteArray);
myRawImage.texture = player.TargetTexture;
player.Play();This project was architecture-redesigned, benchmarked, cleaned up, and open-sourced via Vibe Coding with OpenAI Codex.
SVGALite originated from experiments with the SVGA open-source ecosystem and was subsequently completely rewritten. We gratefully acknowledge the following upstream projects:
- SVGAPlayer-Unity: Early Unity SVGA implementation reference.
- SVGAPlayer-Web: Official SVGA web player specification.
- SVGAPlayer-Web-Lite: Lightweight node-free architecture inspiration.
SVGALite is licensed under the Apache License 2.0.