From 4e391013c8bf8544fb766bee5dbae10cfdbc9d93 Mon Sep 17 00:00:00 2001 From: Billy Messenger Date: Wed, 16 Dec 2020 10:03:51 -0600 Subject: don't panic when swapchain frame is outdated --- examples/integration/src/main.rs | 97 ++++++++++++++++-------------- graphics/src/window/compositor.rs | 5 +- wgpu/src/window/compositor.rs | 123 +++++++++++++++++++++----------------- winit/src/application.rs | 25 ++++---- 4 files changed, 141 insertions(+), 109 deletions(-) diff --git a/examples/integration/src/main.rs b/examples/integration/src/main.rs index 9b52f3a5..88d8d023 100644 --- a/examples/integration/src/main.rs +++ b/examples/integration/src/main.rs @@ -168,55 +168,64 @@ pub fn main() { resized = false; } - let frame = swap_chain.get_current_frame().expect("Next frame"); + match swap_chain.get_current_frame() { + Ok(frame) => { + let mut encoder = device.create_command_encoder( + &wgpu::CommandEncoderDescriptor { label: None }, + ); - let mut encoder = device.create_command_encoder( - &wgpu::CommandEncoderDescriptor { label: None }, - ); + let program = state.program(); + + { + // We clear the frame + let mut render_pass = scene.clear( + &frame.output.view, + &mut encoder, + program.background_color(), + ); + + // Draw the scene + scene.draw(&mut render_pass); + } + + // And then iced on top + let mouse_interaction = renderer.backend_mut().draw( + &mut device, + &mut staging_belt, + &mut encoder, + &frame.output.view, + &viewport, + state.primitive(), + &debug.overlay(), + ); - let program = state.program(); + // Then we submit the work + staging_belt.finish(); + queue.submit(Some(encoder.finish())); - { - // We clear the frame - let mut render_pass = scene.clear( - &frame.output.view, - &mut encoder, - program.background_color(), - ); + // Update the mouse cursor + window.set_cursor_icon( + iced_winit::conversion::mouse_interaction( + mouse_interaction, + ), + ); - // Draw the scene - scene.draw(&mut render_pass); - } + // And recall staging buffers + local_pool + .spawner() + .spawn(staging_belt.recall()) + .expect("Recall staging buffers"); - // And then iced on top - let mouse_interaction = renderer.backend_mut().draw( - &mut device, - &mut staging_belt, - &mut encoder, - &frame.output.view, - &viewport, - state.primitive(), - &debug.overlay(), - ); - - // Then we submit the work - staging_belt.finish(); - queue.submit(Some(encoder.finish())); - - // Update the mouse cursor - window.set_cursor_icon( - iced_winit::conversion::mouse_interaction( - mouse_interaction, - ), - ); - - // And recall staging buffers - local_pool - .spawner() - .spawn(staging_belt.recall()) - .expect("Recall staging buffers"); - - local_pool.run_until_stalled(); + local_pool.run_until_stalled(); + } + Err(error) => match error { + wgpu::SwapChainError::Outdated => { + // Try rendering again next frame. + window.request_redraw(); + } + _ => panic!("Swapchain error: {:?}", error), + }, + } } _ => {} } diff --git a/graphics/src/window/compositor.rs b/graphics/src/window/compositor.rs index 0bc8cbc8..39485153 100644 --- a/graphics/src/window/compositor.rs +++ b/graphics/src/window/compositor.rs @@ -40,6 +40,9 @@ 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>( &mut self, @@ -49,5 +52,5 @@ pub trait Compositor: Sized { background_color: Color, output: &::Output, overlay: &[T], - ) -> mouse::Interaction; + ) -> Result; } diff --git a/wgpu/src/window/compositor.rs b/wgpu/src/window/compositor.rs index 492efb42..ad1e609c 100644 --- a/wgpu/src/window/compositor.rs +++ b/wgpu/src/window/compositor.rs @@ -100,7 +100,7 @@ impl iced_graphics::window::Compositor for Compositor { width: u32, height: u32, ) -> Self::SwapChain { - self.device.create_swap_chain( + let swap_chain = self.device.create_swap_chain( surface, &wgpu::SwapChainDescriptor { usage: wgpu::TextureUsage::OUTPUT_ATTACHMENT, @@ -109,7 +109,9 @@ impl iced_graphics::window::Compositor for Compositor { width, height, }, - ) + ); + + swap_chain } fn draw>( @@ -120,58 +122,71 @@ impl iced_graphics::window::Compositor for Compositor { background_color: Color, output: &::Output, overlay: &[T], - ) -> mouse::Interaction { - let frame = swap_chain.get_current_frame().expect("Next frame"); - - let mut encoder = self.device.create_command_encoder( - &wgpu::CommandEncoderDescriptor { - label: Some("iced_wgpu encoder"), + ) -> Result { + match swap_chain.get_current_frame() { + Ok(frame) => { + let mut encoder = self.device.create_command_encoder( + &wgpu::CommandEncoderDescriptor { + label: Some("iced_wgpu encoder"), + }, + ); + + let _ = + encoder.begin_render_pass(&wgpu::RenderPassDescriptor { + color_attachments: &[ + wgpu::RenderPassColorAttachmentDescriptor { + attachment: &frame.output.view, + resolve_target: None, + 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), + b: f64::from(b), + a: f64::from(a), + } + }), + store: true, + }, + }, + ], + depth_stencil_attachment: None, + }); + + let mouse_interaction = renderer.backend_mut().draw( + &mut self.device, + &mut self.staging_belt, + &mut encoder, + &frame.output.view, + viewport, + 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::Outdated => { + // Try again next frame. + Err(()) + } + _ => panic!("Swapchain error: {:?}", error), }, - ); - - let _ = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { - color_attachments: &[wgpu::RenderPassColorAttachmentDescriptor { - attachment: &frame.output.view, - resolve_target: None, - 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), - b: f64::from(b), - a: f64::from(a), - } - }), - store: true, - }, - }], - depth_stencil_attachment: None, - }); - - let mouse_interaction = renderer.backend_mut().draw( - &mut self.device, - &mut self.staging_belt, - &mut encoder, - &frame.output.view, - viewport, - 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(); - - mouse_interaction + } } } diff --git a/winit/src/application.rs b/winit/src/application.rs index d1a94864..f19526cb 100644 --- a/winit/src/application.rs +++ b/winit/src/application.rs @@ -311,27 +311,32 @@ async fn run_instance( viewport_version = current_viewport_version; } - let new_mouse_interaction = compositor.draw( + if let Ok(new_mouse_interaction) = compositor.draw( &mut renderer, &mut swap_chain, state.viewport(), state.background_color(), &primitive, &debug.overlay(), - ); + ) { + debug.render_finished(); - 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; - } + mouse_interaction = new_mouse_interaction; + } // TODO: Handle animations! // Maybe we can use `ControlFlow::WaitUntil` for this. + } else { + debug.render_finished(); + + // Rendering could not complete, try again next frame. + window.request_redraw(); + } } event::Event::WindowEvent { event: window_event, -- cgit From 1c06920158e1a47977b2762bf8b34e56fd1a935a Mon Sep 17 00:00:00 2001 From: Billy Messenger Date: Wed, 16 Dec 2020 10:10:40 -0600 Subject: remove unused code --- wgpu/src/window/compositor.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/wgpu/src/window/compositor.rs b/wgpu/src/window/compositor.rs index ad1e609c..072521ef 100644 --- a/wgpu/src/window/compositor.rs +++ b/wgpu/src/window/compositor.rs @@ -100,7 +100,7 @@ impl iced_graphics::window::Compositor for Compositor { width: u32, height: u32, ) -> Self::SwapChain { - let swap_chain = self.device.create_swap_chain( + self.device.create_swap_chain( surface, &wgpu::SwapChainDescriptor { usage: wgpu::TextureUsage::OUTPUT_ATTACHMENT, @@ -109,9 +109,7 @@ impl iced_graphics::window::Compositor for Compositor { width, height, }, - ); - - swap_chain + ) } fn draw>( -- cgit From 191288771f747f89e555dd315b424b468ab3d52a Mon Sep 17 00:00:00 2001 From: Billy Messenger Date: Thu, 22 Jul 2021 12:38:56 -0500 Subject: only panic when wgpu gives OutOfMemory swapchain error --- wgpu/src/window/compositor.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wgpu/src/window/compositor.rs b/wgpu/src/window/compositor.rs index c21b0868..7a995598 100644 --- a/wgpu/src/window/compositor.rs +++ b/wgpu/src/window/compositor.rs @@ -192,7 +192,7 @@ impl iced_graphics::window::Compositor for Compositor { } Err(error) => match error { wgpu::SwapChainError::OutOfMemory => { - panic!("Swapchain error: {:?}", error); + panic!("Wgpu swapchain error: {:?}", error); } _ => { // Try again next frame. -- cgit From a7d2834a6d15466eecca29bb6357d3539cb652cd Mon Sep 17 00:00:00 2001 From: Billy Messenger Date: Thu, 22 Jul 2021 13:08:13 -0500 Subject: add custom error for Compositor::draw() --- examples/integration/src/main.rs | 6 ++++-- graphics/src/window.rs | 2 +- graphics/src/window/compositor.rs | 33 +++++++++++++++++++++++++++---- wgpu/src/window/compositor.rs | 19 +++++++++--------- 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>( &mut self, @@ -55,5 +52,33 @@ pub trait Compositor: Sized { background_color: Color, output: &::Output, overlay: &[T], - ) -> Result; + ) -> Result; +} + +/// Result of an unsuccessful call to [`Compositor::draw`]. +#[derive(Debug)] +pub enum CompositorDrawError { + /// The swapchain is outdated. Try rendering again next frame. + SwapchainOutdated(Box), + /// A fatal swapchain error occured. Rendering cannot continue. + FatalSwapchainError(Box), +} + +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: &::Output, overlay: &[T], - ) -> Result { + ) -> Result + { 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( 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( &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 { -- cgit From e5010b8ab87b2e30feea366396bc060c8e793d8d Mon Sep 17 00:00:00 2001 From: Billy Messenger Date: Thu, 22 Jul 2021 13:23:36 -0500 Subject: redo custom error for Compositor::draw() --- graphics/src/window.rs | 2 +- graphics/src/window/compositor.rs | 41 ++++++++++++------------- wgpu/src/window/compositor.rs | 64 ++++++++++++++++++++++----------------- winit/src/application.rs | 12 ++++---- 4 files changed, 63 insertions(+), 56 deletions(-) diff --git a/graphics/src/window.rs b/graphics/src/window.rs index 6813643d..365ddfbc 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, CompositorDrawError}; +pub use compositor::{Compositor, SwapChainError}; #[cfg(feature = "opengl")] pub use gl_compositor::GLCompositor; diff --git a/graphics/src/window/compositor.rs b/graphics/src/window/compositor.rs index 9f7cb43f..9811d95d 100644 --- a/graphics/src/window/compositor.rs +++ b/graphics/src/window/compositor.rs @@ -52,33 +52,32 @@ pub trait Compositor: Sized { background_color: Color, output: &::Output, overlay: &[T], - ) -> Result; + ) -> Result; } /// Result of an unsuccessful call to [`Compositor::draw`]. -#[derive(Debug)] -pub enum CompositorDrawError { - /// The swapchain is outdated. Try rendering again next frame. - SwapchainOutdated(Box), - /// A fatal swapchain error occured. Rendering cannot continue. - FatalSwapchainError(Box), +/// Result of an unsuccessful call to [`SwapChain::get_current_frame`]. +#[derive(Clone, PartialEq, Eq, Debug)] +pub enum SwapChainError { + /// A timeout was encountered while trying to acquire the next frame. + Timeout, + /// The underlying surface has changed, and therefore the swap chain must be updated. + Outdated, + /// The swap chain has been lost and needs to be recreated. + Lost, + /// There is no more memory left to allocate a new frame. + OutOfMemory, } -impl std::error::Error for CompositorDrawError {} +impl std::error::Error for SwapChainError {} -impl std::fmt::Display for CompositorDrawError { +impl std::fmt::Display for SwapChainError { 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 - ), - } + write!(f, "{}", match self { + Self::Timeout => "A timeout was encountered while trying to acquire the next frame", + Self::Outdated => "The underlying surface has changed, and therefore the swap chain must be updated", + Self::Lost => "The swap chain has been lost and needs to be recreated", + Self::OutOfMemory => "There is no more memory left to allocate a new frame", + }) } } diff --git a/wgpu/src/window/compositor.rs b/wgpu/src/window/compositor.rs index fd8fec6e..fb25fca4 100644 --- a/wgpu/src/window/compositor.rs +++ b/wgpu/src/window/compositor.rs @@ -135,8 +135,7 @@ impl iced_graphics::window::Compositor for Compositor { background_color: Color, output: &::Output, overlay: &[T], - ) -> Result - { + ) -> Result { match swap_chain.get_current_frame() { Ok(frame) => { let mut encoder = self.device.create_command_encoder( @@ -145,27 +144,31 @@ impl iced_graphics::window::Compositor for Compositor { }, ); - let _ = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { - label: Some("iced_wgpu::window::Compositor render pass"), - color_attachments: &[wgpu::RenderPassColorAttachment { - view: &frame.output.view, - resolve_target: None, - 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), - b: f64::from(b), - a: f64::from(a), - } - }), - store: true, - }, - }], - depth_stencil_attachment: None, - }); + let _ = + encoder.begin_render_pass(&wgpu::RenderPassDescriptor { + label: Some( + "iced_wgpu::window::Compositor render pass", + ), + color_attachments: &[wgpu::RenderPassColorAttachment { + view: &frame.output.view, + resolve_target: None, + 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), + b: f64::from(b), + a: f64::from(a), + } + }), + store: true, + }, + }], + depth_stencil_attachment: None, + }); let mouse_interaction = renderer.backend_mut().draw( &mut self.device, @@ -192,12 +195,17 @@ impl iced_graphics::window::Compositor for Compositor { Ok(mouse_interaction) } Err(error) => match error { - wgpu::SwapChainError::OutOfMemory => { - Err(iced_graphics::window::CompositorDrawError::FatalSwapchainError(Box::new(error))) + wgpu::SwapChainError::Timeout => { + Err(iced_graphics::window::SwapChainError::Timeout) + } + wgpu::SwapChainError::Outdated => { + Err(iced_graphics::window::SwapChainError::Outdated) } - _ => { - // Try again next frame. - Err(iced_graphics::window::CompositorDrawError::SwapchainOutdated(Box::new(error))) + wgpu::SwapChainError::Lost => { + Err(iced_graphics::window::SwapChainError::Lost) + } + wgpu::SwapChainError::OutOfMemory => { + Err(iced_graphics::window::SwapChainError::OutOfMemory) } }, } diff --git a/winit/src/application.rs b/winit/src/application.rs index b04fc609..1d32a5f3 100644 --- a/winit/src/application.rs +++ b/winit/src/application.rs @@ -391,16 +391,16 @@ async fn run_instance( // Maybe we can use `ControlFlow::WaitUntil` for this. } Err(error) => match error { - window::CompositorDrawError::SwapchainOutdated(_) => { + // This is an unrecoverable error. + window::SwapChainError::OutOfMemory => { + panic!("{}", error); + } + _ => { debug.render_finished(); - // Swapchain is outdated. Try rendering again next frame. + // Try rendering again next frame. window.request_redraw(); } - window::CompositorDrawError::FatalSwapchainError(e) => { - // Fatal swapchain error. Rendering cannot continue. - panic!("{}", e); - } }, } } -- cgit From b629a8025426afd5a6a03a5d17f4e28a6bed6e30 Mon Sep 17 00:00:00 2001 From: Billy Messenger Date: Thu, 22 Jul 2021 13:26:27 -0500 Subject: small documentation error --- graphics/src/window/compositor.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/graphics/src/window/compositor.rs b/graphics/src/window/compositor.rs index 9811d95d..e6633293 100644 --- a/graphics/src/window/compositor.rs +++ b/graphics/src/window/compositor.rs @@ -56,7 +56,6 @@ pub trait Compositor: Sized { } /// Result of an unsuccessful call to [`Compositor::draw`]. -/// Result of an unsuccessful call to [`SwapChain::get_current_frame`]. #[derive(Clone, PartialEq, Eq, Debug)] pub enum SwapChainError { /// A timeout was encountered while trying to acquire the next frame. -- cgit From 3e03a42bc69562639784a1b560978bf184576824 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Wed, 4 Aug 2021 21:45:38 +0700 Subject: Use `thiserror` to derive `Error` for `SwapChainError` --- graphics/src/window/compositor.rs | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/graphics/src/window/compositor.rs b/graphics/src/window/compositor.rs index e6633293..de2a6990 100644 --- a/graphics/src/window/compositor.rs +++ b/graphics/src/window/compositor.rs @@ -1,6 +1,9 @@ use crate::{Color, Error, Viewport}; + use iced_native::mouse; + use raw_window_handle::HasRawWindowHandle; +use thiserror::Error; /// A graphics compositor that can draw to windows. pub trait Compositor: Sized { @@ -56,27 +59,22 @@ pub trait Compositor: Sized { } /// Result of an unsuccessful call to [`Compositor::draw`]. -#[derive(Clone, PartialEq, Eq, Debug)] +#[derive(Clone, PartialEq, Eq, Debug, Error)] pub enum SwapChainError { /// A timeout was encountered while trying to acquire the next frame. + #[error( + "A timeout was encountered while trying to acquire the next frame" + )] Timeout, /// The underlying surface has changed, and therefore the swap chain must be updated. + #[error( + "The underlying surface has changed, and therefore the swap chain must be updated." + )] Outdated, /// The swap chain has been lost and needs to be recreated. + #[error("The swap chain has been lost and needs to be recreated")] Lost, /// There is no more memory left to allocate a new frame. + #[error("There is no more memory left to allocate a new frame")] OutOfMemory, } - -impl std::error::Error for SwapChainError {} - -impl std::fmt::Display for SwapChainError { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{}", match self { - Self::Timeout => "A timeout was encountered while trying to acquire the next frame", - Self::Outdated => "The underlying surface has changed, and therefore the swap chain must be updated", - Self::Lost => "The swap chain has been lost and needs to be recreated", - Self::OutOfMemory => "There is no more memory left to allocate a new frame", - }) - } -} -- cgit