summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Billy Messenger <BillyDM@tutamail.com>2021-07-22 13:08:13 -0500
committerLibravatar Billy Messenger <BillyDM@tutamail.com>2021-07-22 13:08:13 -0500
commita7d2834a6d15466eecca29bb6357d3539cb652cd (patch)
tree4cd74ac7fbde634e32b90704184296568e220aaf
parent191288771f747f89e555dd315b424b468ab3d52a (diff)
downloadiced-a7d2834a6d15466eecca29bb6357d3539cb652cd.tar.gz
iced-a7d2834a6d15466eecca29bb6357d3539cb652cd.tar.bz2
iced-a7d2834a6d15466eecca29bb6357d3539cb652cd.zip
add custom error for Compositor::draw()
-rw-r--r--examples/integration/src/main.rs6
-rw-r--r--graphics/src/window.rs2
-rw-r--r--graphics/src/window/compositor.rs33
-rw-r--r--wgpu/src/window/compositor.rs19
-rw-r--r--winit/src/application.rs41
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 {