Skip to content

11.15.0

Latest

Choose a tag to compare

@github-actions github-actions released this 22 Oct 21:37
· 21 commits to master since this release

Features

Shader precompilation

This release adds optional background shader precompilation to reduce compilation stalls when Rive first draws. Enable it with rememberRiveWorker(precompileShaders = true) or RiveWorker(precompileShaders = true). It is off by default. Create the worker ahead of its first draw to give compilation time to finish. (Change, Change, Change, Change)

Warmup supports Vulkan and OpenGL, with OpenGL requiring driver support for parallel shader compilation. If that support is unavailable, enabling the option is still safe: warmup is skipped, and shaders compile on demand when first needed for drawing, as before. It prepares common Rive drawing shaders, but does not precompile GPU Canvas shaders or guarantee a stall-free first frame. Changing the option in Compose recreates the worker.

Angular gradients

Angular gradients configured in the Rive Editor now play back on Android. Also called sweep or conic gradients, they blend colors around a center rather than along a line or outward from a point. Their position, rotation, and scale can be animated. This requires the Rive renderer. Legacy Android Canvas rendering does not support angular gradients. (Change, Change)

Fixes

  • Mali OpenGL crashes: Rendering could crash inside glTexSubImage2D, sometimes reporting a destroyed mutex, when a texture was updated while the GPU was still reading it. On affected Mali devices, the renderer now rotates storage textures and checks when they are safe to reuse. (Fix)
  • Legacy image-update ANRs: Replacing a data-bound image through ViewModelImageProperty.set could deadlock the main thread if the previous image was still waiting for its GPU texture to be created. Image destruction no longer waits for that queued work. (Fix)
  • Legacy surface resizing: Repeatedly resizing RiveAnimationView could crash while replacing its rendering surface. The old native worker is now stopped before its implementation is destroyed. (Fix)
  • Vulkan initialization and cleanup: Failed extension or layer enumeration could abort initialization instead of allowing fallback to OpenGL. These failures are now handled. Cleaning up a surface that never became ready also avoids an unnecessary device wait that could overlap rendering. (Fix, Fix)
  • Trigger delivery: A component trigger fired during its binding's first frame could be lost before reaching the view model. A trigger fired by a later state machine layer could also be missed by an earlier layer. Both now remain available to the consumers that have not processed them. (Fix, Fix)
  • Semantics after visibility changes: Showing previously hidden content could leave deeply nested semantic nodes missing, while hiding it could leave descendants exposed. The semantic tree now follows visibility throughout nested artboards and excludes hidden content from semantic actions. (Fix)
  • Component-list reuse: Reusing a row could crash when its default state machine was not the first one, retain input gestures or focus events from the previous item, or leave stale semantics. Reused rows now reset the appropriate state and rebuild their semantic tree. Emptying a list also releases its rows' focus nodes. These fixes accompany the list performance improvements below. (Fix)
  • Stack layout sizing: Content larger than a fixed or fill-sized stack could force the stack's internal cell to grow, ignoring overflow alignment and allowing fill children to exceed the stack. The cell now matches the stack, and bounded hug children respect its size. Unbounded hug children can still overflow according to alignment. This also removes redundant layout work. (Fix)
  • Gradient animation: Animated gradient position, rotation, and scale could remain visually unchanged because the runtime did not rebuild the gradient. Transform changes now update the shader. (Fix)
  • Inner feathering: Switching a fill from outer to inner feathering could make the shape disappear until its geometry changed. The inner feather path is now rebuilt immediately. (Fix)
  • Font and image updates: Clearing a data-bound font could leave some text spans displaying the old variable font. The cached font is now cleared too. Updated image assets also trigger layout measurement so hug-sized images reflect their new dimensions. (Fix, Fix)
  • Data converter interpolation: Repeated transitions to new values could hold the previous value for an extra frame. Interpolators now advance the correct animation and only smooth interruptions of an unfinished transition. (Fix)
  • Script pointer handling: Scripts without pointer handlers could incorrectly report hits across the artboard when their exported method metadata was missing. Hit testing now checks which handlers the script actually implements. (Fix)
  • Script property lifetimes and text: A property listener that disposed its own property could leave a change notification accessing freed memory. Property changes now retain the values they need while notifying listeners, and disposed properties are handled safely. Text decoding also handles truncated UTF-8 sequences without reading beyond the string. (Fix)
  • GPU Canvas memory: Textures and renderbuffers created by GPU Canvas scripts on OpenGL were not being deleted, allowing GPU memory usage to grow. Owned resources are now released. (Fix)
  • GPU Canvas shaders: Shaders with multiple entry points could draw nothing on Adreno Vulkan devices. Pipelines now use a separate module for each stage's entry point, including for files already exported. Automatic resource layouts and texture-sampler pairing also use only the entry points selected by the pipeline, avoiding requirements from unrelated shaders in the same module. (Fix, Fix, Fix)
  • Canvas frame recording: Beginning the same canvas more than once in a frame could accumulate transforms or replay stale content. Only its final recording is now replayed. Canvas recording also guards against unbalanced save/restore calls and drawing after the canvas frame has ended. (Fix)

Performance

Fewer GPU Canvas stalls

GPU Canvas rendering no longer waits for the GPU after each canvas on Android Vulkan. Canvas work is recorded into the frame's command buffer instead. OpenGL also submits GPU Canvas work without waiting for it to finish, reducing CPU stalls in frames that use it. (Change)

Less layout, text, and list work

This release removes repeated layout calculations in nested stacks and avoids solving a text's layout twice for the same change. Paint-only text changes no longer force a relayout, unchanged variable fonts are reused, and glyph outlines are cached. Component lists also reuse eligible rows during replacement and avoid duplicate layout and text shaping when new rows appear. (Change)

In a release-build C++ benchmark on an M-series Mac, a UI with ten entries went from 2.68 ms to 0.112 ms per update after the stack-layout change, with layout calculations falling from 1,812 to 20. This illustrates one reduction in redundant work, and gains depend on the content.

Lower artboard instance allocation overhead

Artboard instances now share their source's animation and state machine lists, reserve space for cloned objects up front, and avoid copying lists during traversal. Rarely used and source-only state also moves out of each artboard's inline storage. These changes reduce allocation and memory overhead, particularly for scenes with many nested artboards or component-list rows. (Change, Change)

Faster path preparation and script cleanup

The renderer does less CPU work to prepare paths, including reusing bounds for translated or scaled paths, skipping unnecessary curve subdivision, processing curves in SIMD batches, and simplifying sharp stroke turns. Float minimum and maximum operations also use a faster implementation on 32-bit ARM. (Change, Change, Change, Change, Change, Change)

Shaders that do not use angular gradients avoid their extra shader work. (Change)

Disposing large groups of script properties now takes linear rather than quadratic work, reducing cleanup overhead for scripts with many tracked properties. (Change)


Full comparison