add custom error for Compositor::draw()
This commit is contained in:
parent
191288771f
commit
a7d2834a6d
5 changed files with 69 additions and 30 deletions
|
|
@ -220,11 +220,13 @@ pub fn main() {
|
||||||
local_pool.run_until_stalled();
|
local_pool.run_until_stalled();
|
||||||
}
|
}
|
||||||
Err(error) => match error {
|
Err(error) => match error {
|
||||||
wgpu::SwapChainError::Outdated => {
|
wgpu::SwapChainError::OutOfMemory => {
|
||||||
|
panic!("Swapchain error: {}. Rendering cannot continue.", error)
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
// Try rendering again next frame.
|
// Try rendering again next frame.
|
||||||
window.request_redraw();
|
window.request_redraw();
|
||||||
}
|
}
|
||||||
_ => panic!("Swapchain error: {:?}", error),
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ mod compositor;
|
||||||
#[cfg(feature = "opengl")]
|
#[cfg(feature = "opengl")]
|
||||||
mod gl_compositor;
|
mod gl_compositor;
|
||||||
|
|
||||||
pub use compositor::Compositor;
|
pub use compositor::{Compositor, CompositorDrawError};
|
||||||
|
|
||||||
#[cfg(feature = "opengl")]
|
#[cfg(feature = "opengl")]
|
||||||
pub use gl_compositor::GLCompositor;
|
pub use gl_compositor::GLCompositor;
|
||||||
|
|
|
||||||
|
|
@ -43,9 +43,6 @@ pub trait Compositor: Sized {
|
||||||
|
|
||||||
/// Draws the output primitives to the next frame of the given [`SwapChain`].
|
/// 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
|
/// [`SwapChain`]: Self::SwapChain
|
||||||
fn draw<T: AsRef<str>>(
|
fn draw<T: AsRef<str>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
|
@ -55,5 +52,33 @@ 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, ()>;
|
) -> 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
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -135,7 +135,8 @@ 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, ()> {
|
) -> Result<mouse::Interaction, iced_graphics::window::CompositorDrawError>
|
||||||
|
{
|
||||||
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(
|
||||||
|
|
@ -152,7 +153,7 @@ impl iced_graphics::window::Compositor for Compositor {
|
||||||
ops: wgpu::Operations {
|
ops: wgpu::Operations {
|
||||||
load: wgpu::LoadOp::Clear({
|
load: wgpu::LoadOp::Clear({
|
||||||
let [r, g, b, a] = background_color.into_linear();
|
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),
|
||||||
|
|
@ -165,7 +166,7 @@ impl iced_graphics::window::Compositor for Compositor {
|
||||||
}],
|
}],
|
||||||
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,
|
||||||
&mut self.staging_belt,
|
&mut self.staging_belt,
|
||||||
|
|
@ -175,28 +176,28 @@ impl iced_graphics::window::Compositor for Compositor {
|
||||||
output,
|
output,
|
||||||
overlay,
|
overlay,
|
||||||
);
|
);
|
||||||
|
|
||||||
// Submit work
|
// Submit work
|
||||||
self.staging_belt.finish();
|
self.staging_belt.finish();
|
||||||
self.queue.submit(Some(encoder.finish()));
|
self.queue.submit(Some(encoder.finish()));
|
||||||
|
|
||||||
// Recall staging buffers
|
// Recall staging buffers
|
||||||
self.local_pool
|
self.local_pool
|
||||||
.spawner()
|
.spawner()
|
||||||
.spawn(self.staging_belt.recall())
|
.spawn(self.staging_belt.recall())
|
||||||
.expect("Recall staging belt");
|
.expect("Recall staging belt");
|
||||||
|
|
||||||
self.local_pool.run_until_stalled();
|
self.local_pool.run_until_stalled();
|
||||||
|
|
||||||
Ok(mouse_interaction)
|
Ok(mouse_interaction)
|
||||||
}
|
}
|
||||||
Err(error) => match error {
|
Err(error) => match error {
|
||||||
wgpu::SwapChainError::OutOfMemory => {
|
wgpu::SwapChainError::OutOfMemory => {
|
||||||
panic!("Wgpu swapchain error: {:?}", error);
|
Err(iced_graphics::window::CompositorDrawError::FatalSwapchainError(Box::new(error)))
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
// Try again next frame.
|
// Try again next frame.
|
||||||
Err(())
|
Err(iced_graphics::window::CompositorDrawError::SwapchainOutdated(Box::new(error)))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -366,7 +366,7 @@ async fn run_instance<A, E, C>(
|
||||||
viewport_version = current_viewport_version;
|
viewport_version = current_viewport_version;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Ok(new_mouse_interaction) = compositor.draw(
|
match compositor.draw(
|
||||||
&mut renderer,
|
&mut renderer,
|
||||||
&mut swap_chain,
|
&mut swap_chain,
|
||||||
state.viewport(),
|
state.viewport(),
|
||||||
|
|
@ -374,23 +374,34 @@ async fn run_instance<A, E, C>(
|
||||||
&primitive,
|
&primitive,
|
||||||
&debug.overlay(),
|
&debug.overlay(),
|
||||||
) {
|
) {
|
||||||
debug.render_finished();
|
Ok(new_mouse_interaction) => {
|
||||||
|
debug.render_finished();
|
||||||
|
|
||||||
if new_mouse_interaction != mouse_interaction {
|
if new_mouse_interaction != mouse_interaction {
|
||||||
window.set_cursor_icon(conversion::mouse_interaction(
|
window.set_cursor_icon(
|
||||||
new_mouse_interaction,
|
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.
|
||||||
}
|
}
|
||||||
|
Err(error) => match error {
|
||||||
|
window::CompositorDrawError::SwapchainOutdated(_) => {
|
||||||
|
debug.render_finished();
|
||||||
|
|
||||||
// TODO: Handle animations!
|
// Swapchain is outdated. Try rendering again next frame.
|
||||||
// Maybe we can use `ControlFlow::WaitUntil` for this.
|
window.request_redraw();
|
||||||
} else {
|
}
|
||||||
debug.render_finished();
|
window::CompositorDrawError::FatalSwapchainError(e) => {
|
||||||
|
// Fatal swapchain error. Rendering cannot continue.
|
||||||
// Rendering could not complete, try again next frame.
|
panic!("{}", e);
|
||||||
window.request_redraw();
|
}
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
event::Event::WindowEvent {
|
event::Event::WindowEvent {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue