mirror of
https://github.com/zed-industries/zed.git
synced 2026-04-18 07:47:53 +00:00
ef42f9db2d
## Summary - Add `unconfigure_surface()` and `replace_surface()` methods to `WgpuRenderer` for mobile platform window lifecycle management - Prefer `PresentMode::Mailbox` (triple-buffering) over `Fifo` to avoid blocking during lifecycle transitions - Early return in `draw()` when surface is unconfigured to prevent driver hangs ## Motivation On Android, the native window (`ANativeWindow`) is destroyed when the app goes to the background and recreated when it returns to the foreground. The same happens during orientation changes. Without surface lifecycle methods, the only option is to destroy the entire `WgpuRenderer` and create a new one on resume. The problem: GPUI's scene cache holds `AtlasTextureId` references from the old renderer's atlas. A new renderer has an empty atlas, so those cached IDs cause index-out-of-bounds panics. The fix: Keep the renderer (device, queue, atlas, pipelines) alive across surface destruction. Only the wgpu `Surface` needs to be replaced. ### `unconfigure_surface()` Marks the surface as unconfigured so `draw()` skips rendering via the existing `surface_configured` guard. Drops intermediate textures that reference the old surface dimensions. The renderer stays fully alive. ### `replace_surface()` Creates a new `wgpu::Surface` from fresh window handles using the **same** `wgpu::Instance` that created the original adapter/device. Reconfigures the surface and marks it as configured so rendering resumes. All cached atlas textures remain valid. ### PresentMode::Mailbox `Fifo` (VSync) blocks in `get_current_texture()` and can deadlock if the compositor is frozen during a lifecycle transition (e.g. `TerminateWindow` → `InitWindow` on Android). Mailbox (triple-buffering) avoids this. Falls back to `AutoNoVsync` → `Fifo` if unsupported. ### draw() early return Some drivers (notably Adreno) block indefinitely when acquiring a texture from an unconfigured surface. The early return prevents this. ## Context This is needed by [gpui-mobile](https://github.com/itsbalamurali/gpui-mobile), a project bringing GPUI to Android and iOS. The Android implementation needs these methods to handle: 1. **Background/foreground transitions** — `TerminateWindow` destroys the native window, `InitWindow` recreates it 2. **Orientation changes** — Surface is destroyed and recreated with new dimensions 3. **Split-screen transitions** — Similar surface recreation Without this change, we maintain a local fork of `gpui_wgpu` with just these additions. Upstreaming them would let mobile platform implementations use the official crate directly. ## Test plan - [x] Tested on Android (Motorola, Adreno 720 GPU) — 3 consecutive background/foreground cycles, zero panics, atlas textures preserved - [x] Tested orientation changes (portrait→landscape→portrait) — surface replacement completed in <40ms per rotation - [x] Verified `draw()` correctly skips rendering when surface is unconfigured - [x] Verified no regression on desktop — methods are additive, existing code paths unchanged - [x] PresentMode fallback chain works on devices that don't support Mailbox ## Release Notes - N/A