redo custom error for Compositor::draw()

This commit is contained in:
Billy Messenger 2021-07-22 13:23:36 -05:00
parent a7d2834a6d
commit e5010b8ab8
4 changed files with 62 additions and 55 deletions

View file

@ -4,7 +4,7 @@ mod compositor;
#[cfg(feature = "opengl")] #[cfg(feature = "opengl")]
mod gl_compositor; mod gl_compositor;
pub use compositor::{Compositor, CompositorDrawError}; pub use compositor::{Compositor, SwapChainError};
#[cfg(feature = "opengl")] #[cfg(feature = "opengl")]
pub use gl_compositor::GLCompositor; pub use gl_compositor::GLCompositor;

View file

@ -52,33 +52,32 @@ pub trait Compositor: Sized {
background_color: Color, background_color: Color,
output: &<Self::Renderer as iced_native::Renderer>::Output, output: &<Self::Renderer as iced_native::Renderer>::Output,
overlay: &[T], overlay: &[T],
) -> Result<mouse::Interaction, CompositorDrawError>; ) -> Result<mouse::Interaction, SwapChainError>;
} }
/// Result of an unsuccessful call to [`Compositor::draw`]. /// Result of an unsuccessful call to [`Compositor::draw`].
#[derive(Debug)] /// Result of an unsuccessful call to [`SwapChain::get_current_frame`].
pub enum CompositorDrawError { #[derive(Clone, PartialEq, Eq, Debug)]
/// The swapchain is outdated. Try rendering again next frame. pub enum SwapChainError {
SwapchainOutdated(Box<dyn std::error::Error>), /// A timeout was encountered while trying to acquire the next frame.
/// A fatal swapchain error occured. Rendering cannot continue. Timeout,
FatalSwapchainError(Box<dyn std::error::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.
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 { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self { write!(f, "{}", match self {
CompositorDrawError::SwapchainOutdated(e) => write!( Self::Timeout => "A timeout was encountered while trying to acquire the next frame",
f, Self::Outdated => "The underlying surface has changed, and therefore the swap chain must be updated",
"Swapchain is outdated: {}. Try rendering next frame.", Self::Lost => "The swap chain has been lost and needs to be recreated",
e Self::OutOfMemory => "There is no more memory left to allocate a new frame",
), })
CompositorDrawError::FatalSwapchainError(e) => write!(
f,
"Fatal swapchain error: {}. Rendering cannot continue.",
e
),
}
} }
} }

View file

@ -135,8 +135,7 @@ impl iced_graphics::window::Compositor for Compositor {
background_color: Color, background_color: Color,
output: &<Self::Renderer as iced_native::Renderer>::Output, output: &<Self::Renderer as iced_native::Renderer>::Output,
overlay: &[T], overlay: &[T],
) -> Result<mouse::Interaction, iced_graphics::window::CompositorDrawError> ) -> Result<mouse::Interaction, iced_graphics::window::SwapChainError> {
{
match swap_chain.get_current_frame() { match swap_chain.get_current_frame() {
Ok(frame) => { Ok(frame) => {
let mut encoder = self.device.create_command_encoder( 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 { let _ =
label: Some("iced_wgpu::window::Compositor render pass"), encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
color_attachments: &[wgpu::RenderPassColorAttachment { label: Some(
view: &frame.output.view, "iced_wgpu::window::Compositor render pass",
resolve_target: None, ),
ops: wgpu::Operations { color_attachments: &[wgpu::RenderPassColorAttachment {
load: wgpu::LoadOp::Clear({ view: &frame.output.view,
let [r, g, b, a] = background_color.into_linear(); resolve_target: None,
ops: wgpu::Operations {
load: wgpu::LoadOp::Clear({
let [r, g, b, a] =
background_color.into_linear();
wgpu::Color { wgpu::Color {
r: f64::from(r), r: f64::from(r),
g: f64::from(g), g: f64::from(g),
b: f64::from(b), b: f64::from(b),
a: f64::from(a), a: f64::from(a),
} }
}), }),
store: true, store: true,
}, },
}], }],
depth_stencil_attachment: None, depth_stencil_attachment: None,
}); });
let mouse_interaction = renderer.backend_mut().draw( let mouse_interaction = renderer.backend_mut().draw(
&mut self.device, &mut self.device,
@ -192,12 +195,17 @@ impl iced_graphics::window::Compositor for Compositor {
Ok(mouse_interaction) Ok(mouse_interaction)
} }
Err(error) => match error { Err(error) => match error {
wgpu::SwapChainError::OutOfMemory => { wgpu::SwapChainError::Timeout => {
Err(iced_graphics::window::CompositorDrawError::FatalSwapchainError(Box::new(error))) Err(iced_graphics::window::SwapChainError::Timeout)
} }
_ => { wgpu::SwapChainError::Outdated => {
// Try again next frame. Err(iced_graphics::window::SwapChainError::Outdated)
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)
} }
}, },
} }

View file

@ -391,16 +391,16 @@ async fn run_instance<A, E, C>(
// Maybe we can use `ControlFlow::WaitUntil` for this. // Maybe we can use `ControlFlow::WaitUntil` for this.
} }
Err(error) => match error { Err(error) => match error {
window::CompositorDrawError::SwapchainOutdated(_) => { // This is an unrecoverable error.
window::SwapChainError::OutOfMemory => {
panic!("{}", error);
}
_ => {
debug.render_finished(); debug.render_finished();
// Swapchain is outdated. Try rendering again next frame. // Try rendering again next frame.
window.request_redraw(); window.request_redraw();
} }
window::CompositorDrawError::FatalSwapchainError(e) => {
// Fatal swapchain error. Rendering cannot continue.
panic!("{}", e);
}
}, },
} }
} }