Skip to content

perf(ShaderView): share one GPUDevice across all ShaderViews - #24

Merged
blazejkustra merged 1 commit into
mainfrom
feat/shared-gpu-device
Jun 28, 2026
Merged

perf(ShaderView): share one GPUDevice across all ShaderViews#24
blazejkustra merged 1 commit into
mainfrom
feat/shared-gpu-device

Conversation

@blazejkustra

Copy link
Copy Markdown
Owner

What

Each ShaderView previously requested its own adapter + device. A screen that mounts several effects (Banners, card stacks, the home list's live thumbnails) therefore spun up N GPUDevices on the one background runtime — real GPU/memory cost and slower init.

This introduces a module-level shared GPUDevice singleton (getSharedGPUDevice) that every view awaits. The promise is cached for the JS runtime's lifetime and self-heals: if the device is lost, the cache is cleared so the next mount requests a fresh one.

Lifecycle change

Because the device is now shared, useWGPUSetup no longer destroys it on unmount. Per-view resources (the uniform buffer) are still torn down by the render loop; pipeline/shader modules are released when the loop's worklet closure is GC'd.

Verification (argent, iOS — iPhone 17)

  • Home list renders all live shader thumbnails simultaneously off one device.
  • Banners screen renders all 5 effects (fireworks, confetti, fire, coin geyser, storm) concurrently — previously 5 devices, now 1.
  • Unmount → remount (Back, then re-open Banners) reuses the still-alive device with no blank canvas or crash.

Files

  • src/utils/gpuDevice.ts (new) — the singleton
  • src/hooks/useWGPUSetup.tsx — use the shared device; drop per-view device destroy

Each ShaderView used to request its own adapter + device. A screen that
mounts several effects (e.g. Banners, card stacks) therefore spun up N
devices on the one background runtime — real GPU/memory cost and slower
init.

Introduce a module-level shared GPUDevice singleton (getSharedGPUDevice)
that every view awaits. The promise is cached for the JS runtime's
lifetime and self-heals: if the device is lost, the cache is cleared so
the next mount requests a fresh one.

Because the device is now shared, useWGPUSetup no longer destroys it on
unmount. Per-view resources (uniform buffer) are still torn down by the
render loop; pipeline/shader modules are released when the loop's worklet
closure is GC'd.

Verified on iOS: Banners screen renders all 5 effects off one device,
and unmount → remount reuses the still-alive device.
@blazejkustra
blazejkustra merged commit ec0207a into main Jun 28, 2026
2 checks passed
@blazejkustra
blazejkustra deleted the feat/shared-gpu-device branch June 28, 2026 13:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant