diff --git a/crates/gpui_linux/src/linux/wayland/window.rs b/crates/gpui_linux/src/linux/wayland/window.rs index 71a4ee2ab5033a69c5872fab631fd13af6c82b0e..d2883dc3ac64f52a38ac496b025da6be45246a85 100644 --- a/crates/gpui_linux/src/linux/wayland/window.rs +++ b/crates/gpui_linux/src/linux/wayland/window.rs @@ -114,6 +114,7 @@ pub struct WaylandWindowState { handle: AnyWindowHandle, active: bool, hovered: bool, + pub(crate) force_render_after_recovery: bool, in_progress_configure: Option, resize_throttle: bool, in_progress_window_controls: Option, @@ -387,6 +388,7 @@ impl WaylandWindowState { handle, active: false, hovered: false, + force_render_after_recovery: false, in_progress_window_controls: None, window_controls: WindowControls::default(), client_inset: None, @@ -568,11 +570,16 @@ impl WaylandWindowStatePtr { let mut state = self.state.borrow_mut(); state.surface.frame(&state.globals.qh, state.surface.id()); state.resize_throttle = false; + let force_render = state.force_render_after_recovery; + state.force_render_after_recovery = false; drop(state); let mut cb = self.callbacks.borrow_mut(); if let Some(fun) = cb.request_frame.as_mut() { - fun(Default::default()); + fun(RequestFrameOptions { + force_render, + ..Default::default() + }); } } @@ -1367,6 +1374,7 @@ impl PlatformWindow for WaylandWindow { // The current scene references atlas textures that were cleared during recovery. // Skip this frame and let the next frame rebuild the scene with fresh textures. + state.force_render_after_recovery = true; return; } diff --git a/crates/gpui_linux/src/linux/x11/client.rs b/crates/gpui_linux/src/linux/x11/client.rs index 77f154201d3af6bb7504349e579a5be6b4edcbb5..38eb536792249952cfc0a523e555347c5e29122a 100644 --- a/crates/gpui_linux/src/linux/x11/client.rs +++ b/crates/gpui_linux/src/linux/x11/client.rs @@ -1874,11 +1874,14 @@ impl X11ClientState { if let Some(window) = state.windows.get_mut(&x_window) { let expose_event_received = window.expose_event_received; window.expose_event_received = false; + let force_render = std::mem::take( + &mut window.window.state.borrow_mut().force_render_after_recovery, + ); let window = window.window.clone(); drop(state); window.refresh(RequestFrameOptions { require_presentation: expose_event_received, - force_render: false, + force_render, }); } xcb_connection diff --git a/crates/gpui_linux/src/linux/x11/window.rs b/crates/gpui_linux/src/linux/x11/window.rs index 57600103ce9ec1a67abb4abc373b0ed4c26cb077..a1df1c9f9a839da62c56e8b4d0dc21ae42e0e046 100644 --- a/crates/gpui_linux/src/linux/x11/window.rs +++ b/crates/gpui_linux/src/linux/x11/window.rs @@ -275,6 +275,7 @@ pub struct X11WindowState { hidden: bool, active: bool, hovered: bool, + pub(crate) force_render_after_recovery: bool, fullscreen: bool, client_side_decorations_supported: bool, decorations: WindowDecorations, @@ -738,6 +739,7 @@ impl X11WindowState { input_handler: None, active: false, hovered: false, + force_render_after_recovery: false, fullscreen: false, maximized_vertical: false, maximized_horizontal: false, @@ -1623,6 +1625,7 @@ impl PlatformWindow for X11Window { // The current scene references atlas textures that were cleared during recovery. // Skip this frame and let the next frame rebuild the scene with fresh textures. + inner.force_render_after_recovery = true; return; } diff --git a/crates/gpui_windows/src/events.rs b/crates/gpui_windows/src/events.rs index 3506ae2a2cc22d57c4cefba1a4c5a1850c411453..985989a4c98dcaafa35661b0a496dcadf42665d3 100644 --- a/crates/gpui_windows/src/events.rs +++ b/crates/gpui_windows/src/events.rs @@ -1143,10 +1143,11 @@ impl WindowsWindowInner { fn draw_window(&self, handle: HWND, force_render: bool) -> Option { let mut request_frame = self.state.callbacks.request_frame.take()?; - // we are instructing gpui to force render a frame, this will - // re-populate all the gpu textures for us so we can resume drawing in - // case we disabled drawing earlier due to a device loss - self.state.renderer.borrow_mut().mark_drawable(); + if force_render { + // Re-enable drawing after a device loss recovery. The forced render + // will rebuild the scene with fresh atlas textures. + self.state.renderer.borrow_mut().mark_drawable(); + } request_frame(RequestFrameOptions { require_presentation: false, force_render,