Skip to content

v0.1.0-beta.4 — Skia 3.7.4, an EGL-free Android export a third faster

Pre-release
Pre-release

Choose a tag to compare

@batical batical released this 24 Oct 18:57
2c53c16

Requires react-native-skia@3.7.4 and react-native-webgpu@0.19.0.

Install

npm install --save-exact react-native-skia@3.7.4 react-native-webgpu@0.19.0 react-native-reanimated@4.5.3 react-native-worklets@0.11.3
npm install --save-exact react-native-skia-webgpu-video@0.1.0-beta.4
npx --no-install skia-video-patch-canvas

Add the last command to your app's postinstall, then rebuild the native app; see the README. The archive attached here is the same package, installable by URL.

Changes since v0.1.0-beta.3

Skia 3.7.4 / WebGPU 0.19.0: EGL-free Android export, a third faster (#26)

  • Requires react-native-skia@3.7.4 and react-native-webgpu@0.19.0 (Graphite and Dawn stay at 157). Run npx --no-install skia-video-patch-canvas again and rebuild the native app. The local Skia patch shrinks from 7 files to 3: canvas disposal and the image provider ownership fix are now upstream.
  • Android exports are a third faster, up to 45% with 4K sources (Pixel 8a, medians, beta.3 → beta.4). iOS is unchanged.
    • 8 × 4K clips at native size into a 1080 output: 9.8 → 7.0 s.
    • The same clips capped at 1280: 12.7 → 7.0 s.
    • 3 simultaneous 4K clips: 5.6 → 3.5 s.
    • HEVC 1080p: 3.12 → 2.08 s.
    • 640×360: 1.25 → 0.85 s.
    • One 4K clip exported at 4K: 25.3–25.8 → 22.3–23.0 s.
  • Android export renders straight into the codec's input Surface through WebGPU (MakeWebGPUCanvasContextFromNativeWindow, a Vulkan swapchain). There is no EGL context and no lent AHardwareBuffer anymore.
    • First problem found: the swapchain tagged frames sRGB, full range, so the codec wrote yuvj420p files 3–11% larger.
    • The window's dataspace is now reset before each frame. Files stay Rec.709 limited range, byte-identical to beta.3.
  • Fixed: the first 3.7.4 build was 24% slower than beta.3 on 8 native 4K clips.
    • A Perfetto trace found the cause. The export waited for the GPU after every frame, then left it idle while decoding the next one. Mali's frequency governor therefore kept the GPU at its lowest clock, 160 MHz, three quarters of the time.
    • The export now waits for a frame's GPU work only once it has decoded the next frame, so the GPU draws while the CPU decodes. A decoder buffer is still handed back only after the GPU is done with it.
  • The Android export thread reports its frames to Android's performance hints (ADPF, Android 13 and later). It gets faster cores, and from Android 15 more GPU capacity: 15–29% on most export cases. This is best effort; nothing changes on devices without hint sessions.
  • maxLongSide and resolution items now decode through ImageReader on Android (8-bit SDR H.264/HEVC). The codec keeps its YUV buffers, and the WebGPU conversion scales them instead of an OpenGL render pass. For 8 × 4K clips capped at 1280, decoding drops from 17 to 8.7 ms per frame. Capped clips keep their frame sizes, but their pixels change slightly, since the scaling is now bilinear in WebGPU.
  • Benchmark: two new cases, export-4k-h264 and export-4k-hevc, export a 30 s real-footage 4K clip at 4K. The 65 existing workloads are unchanged.

Release 0.1.0-beta.4 (#27)

Version bump for 0.1.0-beta.4. npm run ship merges it once CI passes, then tags and publishes it.

Not yet qualified

  • Memory over long sessions (last checked on 3.0.6).
  • HDR beyond the HLG to SDR conversion, audible output and A/V synchronization.
  • Known Pixel 8a issues, all predating beta.3: a seek while playing a 4K sequence leaves the clock stalled, and a paused seek into a 120-clip lazy montage does not show its frame.
  • An iOS export with yuv frames (the default) spends 2–4 ms more per frame than with framePixelFormat: 'rgba'.

Full changelog: v0.1.0-beta.3...v0.1.0-beta.4

SHA-256 of the archive: 32a48bfac830fbe82c5b22e0425dab80614ecea6f5d269eee4e807dfdc1a631e