diff options
author | 2021-07-22 13:08:13 -0500 | |
---|---|---|
committer | 2021-07-22 13:08:13 -0500 | |
commit | a7d2834a6d15466eecca29bb6357d3539cb652cd (patch) | |
tree | 4cd74ac7fbde634e32b90704184296568e220aaf | |
parent | 191288771f747f89e555dd315b424b468ab3d52a (diff) | |
download | iced-a7d2834a6d15466eecca29bb6357d3539cb652cd.tar.gz iced-a7d2834a6d15466eecca29bb6357d3539cb652cd.tar.bz2 iced-a7d2834a6d15466eecca29bb6357d3539cb652cd.zip |
add custom error for Compositor::draw()
-rw-r--r-- | examples/integration/src/main.rs | 6 | ||||
-rw-r--r-- | graphics/src/window.rs | 2 | ||||
-rw-r--r-- | graphics/src/window/compositor.rs | 33 | ||||
-rw-r--r-- | wgpu/src/window/compositor.rs | 19 | ||||
-rw-r--r-- | winit/src/application.rs | 41 |
5 files changed, 70 insertions, 31 deletions
diff --git a/examples/integration/src/main.rs b/examples/integration/src/main.rs index ab0e2299..9ef31203 100644 --- a/examples/integration/src/main.rs +++ b/examples/integration/src/main.rs @@ -220,11 +220,13 @@ pub fn main() { local_pool.run_until_stalled(); } Err(error) => match error { - wgpu::SwapChainError::Outdated => { + wgpu::SwapChainError::OutOfMemory => { + panic!("Swapchain error: {}. Rendering cannot continue.", error) + } + _ => { // Try rendering again next frame. window.request_redraw(); } - _ => panic!("Swapchain error: {:?}", error), }, } } diff --git a/graphics/src/window.rs b/graphics/src/window.rs index 3e74db5f..6813643d 100644 --- a/graphics/src/window.rs +++ b/graphics/src/window.rs @@ -4,7 +4,7 @@ mod compositor; #[cfg(feature = "opengl")] mod gl_compositor; -pub use compositor::Compositor; +pub use compositor::{Compositor, CompositorDrawError}; #[cfg(feature = "opengl")] pub use gl_compositor::GLCompositor; diff --git a/graphics/src/window/compositor.rs b/graphics/src/window/compositor.rs index 7342245c..9f7cb43f 100644 --- a/graphics/src/window/compositor.rs +++ b/graphics/src/window/compositor.rs @@ -43,9 +43,6 @@ pub trait Compositor: Sized { /// Draws the output primitives to the next frame of the given [`SwapChain`]. /// - /// This will return an error if drawing could not be completed on this frame. - /// If an error occurs, try calling this again on the next frame. - /// /// [`SwapChain`]: Self::SwapChain fn draw<T: AsRef<str>>( &mut self, @@ -55,5 +52,33 @@ pub trait Compositor: Sized { background_color: Color, output: &<Self::Renderer as iced_native::Renderer>::Output, overlay: &[T], - ) -> Result<mouse::Interaction, ()>; + ) -> Result<mouse::Interaction, CompositorDrawError>; +} + +/// Result of an unsuccessful call to [`Compositor::draw`]. +#[derive(Debug)] +pub enum CompositorDrawError { + /// The swapchain is outdated. Try rendering again next frame. + SwapchainOutdated(Box<dyn std::error::Error>), + /// A fatal swapchain error occured. Rendering cannot continue. + FatalSwapchainError(Box<dyn std::error::Error>), +} + +impl std::error::Error for CompositorDrawError {} + +impl std::fmt::Display for CompositorDrawError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + CompositorDrawError::SwapchainOutdated(e) => write!( + f, + "Swapchain is outdated: {}. Try rendering next frame.", + e + ), + CompositorDrawError::FatalSwapchainError(e) => write!( + f, + "Fatal swapchain error: {}. Rendering cannot continue.", + e + ), + } + } } diff --git a/wgpu/src/window/compositor.rs b/wgpu/src/window/compositor.rs index 7a995598..fd8fec6e 100644 --- a/wgpu/src/window/compositor.rs +++ b/wgpu/src/window/compositor.rs @@ -135,7 +135,8 @@ impl iced_graphics::window::Compositor for Compositor { background_color: Color, output: &<Self::Renderer as iced_native::Renderer>::Output, overlay: &[T], - ) -> Result<mouse::Interaction, ()> { + ) -> Result<mouse::Interaction, iced_graphics::window::CompositorDrawError> + { match swap_chain.get_current_frame() { Ok(frame) => { let mut encoder = self.device.create_command_encoder( @@ -152,7 +153,7 @@ impl iced_graphics::window::Compositor for Compositor { ops: wgpu::Operations { load: wgpu::LoadOp::Clear({ let [r, g, b, a] = background_color.into_linear(); - + wgpu::Color { r: f64::from(r), g: f64::from(g), @@ -165,7 +166,7 @@ impl iced_graphics::window::Compositor for Compositor { }], depth_stencil_attachment: None, }); - + let mouse_interaction = renderer.backend_mut().draw( &mut self.device, &mut self.staging_belt, @@ -175,28 +176,28 @@ impl iced_graphics::window::Compositor for Compositor { output, overlay, ); - + // Submit work self.staging_belt.finish(); self.queue.submit(Some(encoder.finish())); - + // Recall staging buffers self.local_pool .spawner() .spawn(self.staging_belt.recall()) .expect("Recall staging belt"); - + self.local_pool.run_until_stalled(); - + Ok(mouse_interaction) } Err(error) => match error { wgpu::SwapChainError::OutOfMemory => { - panic!("Wgpu swapchain error: {:?}", error); + Err(iced_graphics::window::CompositorDrawError::FatalSwapchainError(Box::new(error))) } _ => { // Try again next frame. - Err(()) + Err(iced_graphics::window::CompositorDrawError::SwapchainOutdated(Box::new(error))) } }, } diff --git a/winit/src/application.rs b/winit/src/application.rs index 903d03e2..b04fc609 100644 --- a/winit/src/application.rs +++ b/winit/src/application.rs @@ -366,7 +366,7 @@ async fn run_instance<A, E, C>( viewport_version = current_viewport_version; } - if let Ok(new_mouse_interaction) = compositor.draw( + match compositor.draw( &mut renderer, &mut swap_chain, state.viewport(), @@ -374,23 +374,34 @@ async fn run_instance<A, E, C>( &primitive, &debug.overlay(), ) { - debug.render_finished(); + Ok(new_mouse_interaction) => { + debug.render_finished(); - if new_mouse_interaction != mouse_interaction { - window.set_cursor_icon(conversion::mouse_interaction( - new_mouse_interaction, - )); + if new_mouse_interaction != mouse_interaction { + window.set_cursor_icon( + conversion::mouse_interaction( + new_mouse_interaction, + ), + ); - mouse_interaction = new_mouse_interaction; - } - - // TODO: Handle animations! - // Maybe we can use `ControlFlow::WaitUntil` for this. - } else { - debug.render_finished(); + mouse_interaction = new_mouse_interaction; + } - // Rendering could not complete, try again next frame. - window.request_redraw(); + // TODO: Handle animations! + // Maybe we can use `ControlFlow::WaitUntil` for this. + } + Err(error) => match error { + window::CompositorDrawError::SwapchainOutdated(_) => { + debug.render_finished(); + + // Swapchain is outdated. Try rendering again next frame. + window.request_redraw(); + } + window::CompositorDrawError::FatalSwapchainError(e) => { + // Fatal swapchain error. Rendering cannot continue. + panic!("{}", e); + } + }, } } event::Event::WindowEvent { |