diff --git a/crates/eframe/src/web/web_painter_wgpu.rs b/crates/eframe/src/web/web_painter_wgpu.rs index c5bc9fd42..ebce9d981 100644 --- a/crates/eframe/src/web/web_painter_wgpu.rs +++ b/crates/eframe/src/web/web_painter_wgpu.rs @@ -22,6 +22,7 @@ pub(crate) struct WebPainterWgpu { capture_tx: CaptureSender, capture_rx: CaptureReceiver, ctx: egui::Context, + needs_reconfigure: bool, } impl WebPainterWgpu { @@ -110,6 +111,7 @@ impl WebPainterWgpu { capture_tx, capture_rx, ctx, + needs_reconfigure: false, }) } } @@ -195,11 +197,16 @@ impl WebPainter for WebPainterWgpu { ); } + if self.needs_reconfigure { + self.surface + .configure(&render_state.device, &self.surface_configuration); + self.needs_reconfigure = false; + } + let output_frame = match self.surface.get_current_texture() { wgpu::CurrentSurfaceTexture::Success(frame) => frame, wgpu::CurrentSurfaceTexture::Suboptimal(frame) => { - self.surface - .configure(&render_state.device, &self.surface_configuration); + self.needs_reconfigure = true; frame } other => { diff --git a/crates/egui-wgpu/src/lib.rs b/crates/egui-wgpu/src/lib.rs index c981027db..05936d6cd 100644 --- a/crates/egui-wgpu/src/lib.rs +++ b/crates/egui-wgpu/src/lib.rs @@ -307,8 +307,9 @@ pub struct WgpuConfiguration { /// /// Called with the [`wgpu::CurrentSurfaceTexture`] result whenever acquiring a frame /// does not return [`wgpu::CurrentSurfaceTexture::Success`]. For - /// [`wgpu::CurrentSurfaceTexture::Suboptimal`], egui automatically reconfigures the - /// surface and uses the frame — the callback is not invoked in that case. + /// [`wgpu::CurrentSurfaceTexture::Suboptimal`], egui uses the frame as-is and + /// defers surface reconfiguration to the next frame — the callback is not invoked + /// in that case either. pub on_surface_status: Arc SurfaceErrorAction + Send + Sync>, } diff --git a/crates/egui-wgpu/src/winit.rs b/crates/egui-wgpu/src/winit.rs index b51c3e5cd..3f6adfc27 100644 --- a/crates/egui-wgpu/src/winit.rs +++ b/crates/egui-wgpu/src/winit.rs @@ -17,6 +17,7 @@ struct SurfaceState { width: u32, height: u32, resizing: bool, + needs_reconfigure: bool, } /// Everything you need to paint egui with [`wgpu`] on [`winit`]. @@ -234,6 +235,7 @@ impl Painter { height: size.height, alpha_mode, resizing: false, + needs_reconfigure: false, }, ); let Some(width) = NonZeroU32::new(size.width) else { @@ -454,7 +456,7 @@ impl Painter { commands_submitted: false, }; - let Some(surface_state) = self.surfaces.get(&viewport_id) else { + let Some(surface_state) = self.surfaces.get_mut(&viewport_id) else { return vsync_sec; }; @@ -491,6 +493,11 @@ impl Painter { ) }; + if surface_state.needs_reconfigure { + Self::configure_surface(surface_state, render_state, &self.configuration); + surface_state.needs_reconfigure = false; + } + let output_frame = { profiling::scope!("get_current_texture"); // This is what vsync-waiting happens on my Mac. @@ -503,7 +510,7 @@ impl Painter { let output_frame = match output_frame { wgpu::CurrentSurfaceTexture::Success(frame) => frame, wgpu::CurrentSurfaceTexture::Suboptimal(frame) => { - Self::configure_surface(surface_state, render_state, &self.configuration); + surface_state.needs_reconfigure = true; frame } other => {