The swipe-up-dismiss + relaunch bug (process survives, activity
re-creates) crashed or left a sparse grid. Root cause chain, fully
documented in docs/BUGS/recreation-stale-textures.md:
- Each android_main (per activity instance) is a fresh Slint world with
a fresh wgpu device (i-slint-core context is thread-local); the old
world zombie-parks (Slint 1.18 android backend never delivers
TerminateWindow/Destroy to it).
- Worker-side GPU uploads + a process-global loader let textures cross
world/device boundaries: a texture destroyed with its device left a
stale handle in the registry (wgpu-core assert in transition_resources
on the render thread) — either killing the process, or, with the
interim catch_unwind band-aid, keeping a poisoned world alive and
corrupting the VISIBLE world's imports (the sparse grid). A/B against
pristine Slint confirmed the mechanism (pristine: 1 self-killing panic
per recreation + full grid).
Fix:
- gputex rewrite: workers deliver plain RGBA8; the UI drain tick
uploads to the device captured from the rendering notifier
(Slint's borrowed-resource contract). Staleness impossible by
construction. Keepalive thread removed.
- Per-world lifecycle: CURRENT_WORLD gate silences zombie ticks;
re-init invalidates the dying device + swaps the engine; render
notifier handles RenderingTeardown/RenderingSetup (in-place cell
clear — never set_vec mid-render, which desyncs the for-loop).
- Vendor patch surface reduced to the single final-flush hunk
(catch_unwind guard reverted to pristine).