From 9a69055405a0bbffd4980d5f992cb0e442203deb Mon Sep 17 00:00:00 2001 From: Jonathan Johnson Date: Tue, 19 Dec 2023 10:39:59 -0800 Subject: [PATCH 1/2] Requesting surface from winit thread when lost Refs #67 Thanks to @Plecra for reviewing the unsafe code in this crate, this error of calling create_surface from the window thread rather than the winit thread was spotted. Sorry it took me so long to realize the ultimate solution. This reduces the unsafe surface even further, which is nice. --- src/app.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/app.rs b/src/app.rs index e3be9dfef..8cd10b1e6 100644 --- a/src/app.rs +++ b/src/app.rs @@ -607,7 +607,6 @@ struct KludgineWindow { queue: wgpu::Queue, msaa_texture: Option, _adapter: wgpu::Adapter, - wgpu: Arc, } impl appit::WindowBehavior> for KludgineWindow @@ -688,7 +687,6 @@ where surface.configure(&device, &config); Self { - wgpu, kludgine: state, last_render, last_render_duration: Duration::ZERO, @@ -702,7 +700,6 @@ where } } - #[allow(unsafe_code)] fn redraw(&mut self, window: &mut RunningWindow>) { let surface = loop { match self.surface.get_current_texture() { @@ -716,9 +713,12 @@ where return; } wgpu::SurfaceError::Lost => { - // SAFETY: redraw is only called while the event loop - // and window are still alive. - self.surface = unsafe { self.wgpu.create_surface(window.winit()).unwrap() }; + self.surface = window + .send(CreateSurfaceRequest { + window: window.winit().id(), + data: PhantomData, + }) + .expect("app not running"); self.surface.configure(&self.device, &self.config); } wgpu::SurfaceError::OutOfMemory => { From 65417049af9c640ca09888d129ed23dfeee5441e Mon Sep 17 00:00:00 2001 From: Jonathan Johnson Date: Tue, 19 Dec 2023 10:52:54 -0800 Subject: [PATCH 2/2] Updating safety comment Refs #67 Previously I was documenting some of the requirements to not panic rather than specifically the safety requirements. This new comment addresses the two safety requirements of create_surface. --- src/app.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/app.rs b/src/app.rs index 8cd10b1e6..18c597fa2 100644 --- a/src/app.rs +++ b/src/app.rs @@ -341,11 +341,10 @@ where let app = PendingApp::new_with_event_callback( |request: CreateSurfaceRequest, windows: &appit::Windows| { let window = windows.get(request.window).expect("window not found"); - // SAFETY: This callback is only invoked by the winit event - // loop, where the window will already be removed from the - // collection if it is closed. Additionally, because this - // callback is only invoked from the winit event loop, we are - // guaranteed that we are on the original thread winit began on. + // SAFETY: The winit window is valid and open when it is + // contained in the windows collection. The surface being + // created is stored on the KludgineWindow, which is dropped + // prior to the appit/winit window closing. unsafe { shared_wgpu() .create_surface(&*window)