Rive Runtime runtime-v0.1.249
feat(deferred): one session per render context, multi target replay, and the context tier deleted (#13368) e9f24d0296 * feat(deferred): one session per render context with multi target replay, the shared context tier deleted, and script GPU work routed from the import factory * fix(editor): paint the stage background while a new file's scripts compile, the vm swap skip was keeping the previous file's frame on the shared texture * fix(web): detach the deferred session before a pooled renderer is released, deleting a bound renderer left the session replaying into dead GL state * fix(editor): retry the shared texture clear until it lands or the new stage paints, opening from the file browser skipped it while the canvas was off screen * fix(editor): hold the shared texture clear until the canvas is displayed with real size, a frame recorded before then replays with no screen to present to * fix(editor): clear the shared texture when leaving for the file browser and let a transferred canvas clear while detached, the worker draws its bitmap regardless of the DOM * fix(web): present every screen target on the web sink, a frame recorded before a repoint carried the prior texture's target and static content went blank when it was refused * chore: move the investigation scripts and write ups to archive/deferred-investigation-scripts, the suite carries the conclusions as asserts * test(gm): the deferred GMs check themselves against their immediate frame in process, each pair was two identical goldens standing in for one parity assert, 487 baselines gone * chore: drop the working notes and dated benchmark reports from the tree, the archive branch keeps them * docs: pull the deferred rendering write up out of the tree, it lives on the archive branch * chore: pull the benchmark suite, its skill, driver, and bench only assets out of this landing, the archive branch carries them for the follow up * ci: run the example integration tests by directory again, the target list script left with the benchmark suite * ci: claim parity gm families so one worker runs each, and fetch the parity rivs over lfs in the unit test jobs * test(gm): seed browserstack baselines for the canvas dag gms from a metal render, the device rebaseline flow can refresh them if a threshold trips * refactor(runtime): drop the file level instance factory params, every dart call site passed null since the session became the import factory * refactor(deferred): drop the unused dart gpu census mirror, the investigation tooling that read it moved to the archive branch * refactor(native): drop exports with zero callers, riveShutdownGPUScripting was the only path freeing the context session so wiring real process exit teardown is a conscious follow-up * refactor(deferred): fold the dispose helper into its only caller and stop exporting it, nothing outside the package disposed a session * refactor(cmd): drop accessors nothing reads, the live counter's asserting recorder destructor is long gone * refactor(cmd): guard the 2d producer with the recording thread check, make id reuse unconditional, and drop the inert ore replay marker opcode and the canvas hook seam nothing plugs into * fix(web): an explicit released flag for isDisposed and an eager context for immediate consumers, a lazy texture read as disposed from birth and the pool bound stopped meaning live contexts * fix(cmd): read past the canvas id without naming it, the hook deletion left the variable unused and ci builds with werror * fix(tests): a lost context makes isReady false again, the parity rivs ship as plain assets so devices get real bytes, and the corpus walks use filesystem so msvc builds * fix(cmd): the 2d recording thread bind sat unreachable after a lambda return, move it into the constructor body * fix(deferred): probe the whole deferred abi before enabling it, make a failed worker renderer terminal instead of forever pending, and assert when a neighbor's frame reaches a native sink * chore(deferred): name the slot store as the worker bind publication point, pin factory immutability on the widget, and give the editor clear retries one generation * chore: move the factory immutability note above the condition it explains * test(gm): allow the golden diff tolerance on atomic backends in the parity compare, their raster order differs run to run and exactness failed frames no two of theirs ever matched * test(goldens): rebaseline Hero_v2 on vulkan atomic, our vulkan prepass fixes move 72 pixels by up to 14 and the shift reproduced twice, candidate eyeballed at full size * refactor(canvas): replace the deferBacking bool and sticky recording flag with makeDeferredRenderCanvas, only GL overrides it * chore(ps5): restore the agc canvas overloads to master, the base signature no longer forces the reshape Co-authored-by: Luigi Rosso <luigi-rosso@users.noreply.github.com>

Rive's C++ runtime — the lowest-level Rive runtime. Loads .riv files, advances state machines and animations, and draws via the abstract Renderer interface. The built-in GPU renderer (RiveRenderer) has RenderContextImpl backends for Metal, Vulkan, D3D11, D3D12, and OpenGL/WebGL.
Rive's Apple, Android, Flutter, Unity, Unreal, and web runtimes all wrap this library.
Features:
.riv files.Artboard::advance.Renderer interface for hooking up an external vector renderer.xcode-select --install).apt install clang).premake5 on first run. On Windows, install Git for Windows and during setup pick “Use Git and optional Unix tools from the Command Prompt” so that sh.exe ends up on PATH.The build is driven by premake5 wrapped by a helper script:
build/build_rive.sh — macOS / Linux (bash) / Windows (MinGW).build/build_rive.ps1 — a PowerShell convenience wrapper for Windows; it shells out to the bash script, so a bash environment (Git for Windows / MinGW, see Prerequisites) must still be on PATH.The helper self-installs the pinned premake version on first run and dispatches to the right build system for your platform (gmake2 on macOS/Linux, MSBuild on Windows). It must be run from a directory that contains a premake5.lua — typically tests/, which builds the core library, the GPU renderer, and the player sample app.
git clone https://github.com/rive-app/rive-runtime.git cd rive-runtime/tests ../build/build_rive.sh release
git clone https://github.com/rive-app/rive-runtime.git cd rive-runtime\tests ..\build\build_rive.ps1 release
(On Windows, substitute build_rive.ps1 for build_rive.sh.)
build_rive.sh (no args) — debug build for the host.build_rive.sh release clean — clean then build release.build_rive.sh ninja release — use Ninja instead of make/MSBuild.build_rive.sh ios release — cross-compile for iOS.build_rive.sh android release — cross-compile for Android (defaults to arm64).build_rive.sh ninja release wasm — cross-compile for WebAssembly.build_rive.sh --toolset=msc release (Windows) — build with MSVC's cl.exe instead of clang-cl. The build supports both toolchains; the lua warning suppressions cover MSVC too.See the comment header at the top of build/build_rive.sh for the complete flag reference.
Artifacts land in out/<config>/ relative to the directory you built from (typically tests/). The config directory encodes any OS/arch flags you passed:
out/release, out/debug — host build.out/ios_release, out/android_arm64_release, out/wasm_release — cross-compile builds.| Artifact | Description |
|---|---|
librive.a / rive.lib | Core runtime library. |
librive_pls_renderer.a / rive_pls_renderer.lib | GPU renderer. |
player / player.exe | Sample app — loads and renders a .riv file. |
out/<config>/goldens, out/<config>/gms, out/<config>/bench | Test harness binaries (regression, golden-image, benchmarking). |
librive_decoders.a, librive_harfbuzz.a, … | Supporting libraries. |
The runtime's primary form of testing is golden testing — rendering known scenes and diffing the output against checked-in reference images via the goldens and gms test harness binaries (built into out/<config>/goldens and out/<config>/gms). See tests/ for how to run and rebaseline goldens.
Unit tests are secondary and use the Catch2 framework. From the repo root:
cd tests/unit_tests ./test.sh
Unit tests live in tests/unit_tests/runtime/ (core runtime) and tests/unit_tests/renderer/ (renderer). To add a test, create an xxx_test.cpp file in the appropriate directory — the harness picks it up automatically.
rive-runtime uses clang-format.
brew install clang-format.clang-format.exe alongside clang-cl.exe at C:\Program Files\Microsoft Visual Studio\2022\<edition>\VC\Tools\Llvm\x64\bin\. You can also install LLVM standalone from llvm.org or via winget install LLVM.LLVM.apt install clang-format).To run the tests under macOS's built-in leaks tool:
cd tests/unit_tests ./test.sh memory
This wraps the test binary with leaks --atExit, which ships with macOS — no install required. The memory flag is ignored on Linux and Windows.
To inspect generated assembly per cpp file, install the Disassembly Explorer VSCode extension. A disassemble task is provided in .vscode/tasks.json. The underlying gen assembly task invokes clang++ directly, so it needs clang++ on PATH — works out of the box on macOS (Xcode CLI tools) and most Linux distros, but not on a default Windows + VS install (which provides clang-cl.exe, not clang++.exe).
Reach the task from Tasks: Run Task, or bind a key in keybindings.json:
[ { "key": "cmd+d", "command": "workbench.action.tasks.runTask", "args": "disassemble" } ]