From c17b4367d59f23b7d74cd612b91dbc064e5f2a6e Mon Sep 17 00:00:00 2001 From: Leonard Seibold Date: Tue, 23 Jun 2026 05:15:54 +0200 Subject: [PATCH] gpui: Add gpu_device_lost() to query device-loss state on Linux (#78) --- crates/gpui/src/platform.rs | 11 +++++++++++ crates/gpui/src/window.rs | 10 ++++++++++ crates/gpui_linux/src/linux/wayland/window.rs | 6 ++++++ crates/gpui_linux/src/linux/x11/window.rs | 6 ++++++ 4 files changed, 33 insertions(+) diff --git a/crates/gpui/src/platform.rs b/crates/gpui/src/platform.rs index 4652d4016b..32125b6a78 100644 --- a/crates/gpui/src/platform.rs +++ b/crates/gpui/src/platform.rs @@ -725,6 +725,17 @@ pub trait PlatformWindow: HasWindowHandle + HasDisplayHandle { None } + /// Whether this window's GPU device has been lost (the platform renderer + /// recovers it on a subsequent draw). `None` when the backend cannot + /// know. Safe to call mid-recovery, unlike `gpu_context`. Embedders that + /// captured the device from `gpu_context` should stop submitting while + /// this is `Some(true)` and re-acquire the device once it reads + /// `Some(false)` again. + #[cfg(any(target_os = "linux", target_os = "freebsd"))] + fn gpu_device_lost(&self) -> Option { + None + } + fn update_ime_position(&self, _bounds: Bounds); fn play_system_bell(&self) {} diff --git a/crates/gpui/src/window.rs b/crates/gpui/src/window.rs index aa005bbcb8..b5a2faab92 100644 --- a/crates/gpui/src/window.rs +++ b/crates/gpui/src/window.rs @@ -5531,6 +5531,16 @@ impl Window { self.platform_window.gpu_context() } + /// Whether the GPU device backing this window has been lost (recovery + /// happens on a subsequent platform draw). `None` when the backend + /// cannot know. Embedders that captured the device from + /// [`Self::gpu_context`] should stop submitting while this is + /// `Some(true)` and re-acquire the device once it reads `Some(false)`. + #[cfg(any(target_os = "linux", target_os = "freebsd"))] + pub fn gpu_device_lost(&self) -> Option { + self.platform_window.gpu_device_lost() + } + /// Perform titlebar double-click action. /// This is macOS specific. pub fn titlebar_double_click(&self) { diff --git a/crates/gpui_linux/src/linux/wayland/window.rs b/crates/gpui_linux/src/linux/wayland/window.rs index e42342d239..c8d3819429 100644 --- a/crates/gpui_linux/src/linux/wayland/window.rs +++ b/crates/gpui_linux/src/linux/wayland/window.rs @@ -1569,6 +1569,12 @@ impl PlatformWindow for WaylandWindow { Some(Box::new((device, queue))) } + fn gpu_device_lost(&self) -> Option { + // Only loads an atomic flag — safe even mid-recovery, when + // `gpu_context` would panic on the torn-down resources. + Some(self.borrow().renderer.device_lost()) + } + fn play_system_bell(&self) { let state = self.borrow(); let surface = if state.surface_state.toplevel().is_some() { diff --git a/crates/gpui_linux/src/linux/x11/window.rs b/crates/gpui_linux/src/linux/x11/window.rs index 7cd66b982c..e56a47f54d 100644 --- a/crates/gpui_linux/src/linux/x11/window.rs +++ b/crates/gpui_linux/src/linux/x11/window.rs @@ -1901,6 +1901,12 @@ impl PlatformWindow for X11Window { Some(Box::new((device, queue))) } + fn gpu_device_lost(&self) -> Option { + // Only loads an atomic flag — safe even mid-recovery, when + // `gpu_context` would panic on the torn-down resources. + Some(self.0.state.borrow().renderer.device_lost()) + } + fn play_system_bell(&self) { // Volume 0% means don't increase or decrease from system volume let _ = self.0.xcb.bell(0);