don't panic when swapchain frame is outdated
This commit is contained in:
parent
a42b3c6998
commit
4e391013c8
4 changed files with 140 additions and 108 deletions
|
|
@ -168,8 +168,8 @@ pub fn main() {
|
||||||
resized = false;
|
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(
|
let mut encoder = device.create_command_encoder(
|
||||||
&wgpu::CommandEncoderDescriptor { label: None },
|
&wgpu::CommandEncoderDescriptor { label: None },
|
||||||
);
|
);
|
||||||
|
|
@ -218,6 +218,15 @@ pub fn main() {
|
||||||
|
|
||||||
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),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,9 @@ 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,
|
||||||
|
|
@ -49,5 +52,5 @@ 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],
|
||||||
) -> mouse::Interaction;
|
) -> Result<mouse::Interaction, ()>;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -100,7 +100,7 @@ impl iced_graphics::window::Compositor for Compositor {
|
||||||
width: u32,
|
width: u32,
|
||||||
height: u32,
|
height: u32,
|
||||||
) -> Self::SwapChain {
|
) -> Self::SwapChain {
|
||||||
self.device.create_swap_chain(
|
let swap_chain = self.device.create_swap_chain(
|
||||||
surface,
|
surface,
|
||||||
&wgpu::SwapChainDescriptor {
|
&wgpu::SwapChainDescriptor {
|
||||||
usage: wgpu::TextureUsage::OUTPUT_ATTACHMENT,
|
usage: wgpu::TextureUsage::OUTPUT_ATTACHMENT,
|
||||||
|
|
@ -109,7 +109,9 @@ impl iced_graphics::window::Compositor for Compositor {
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
},
|
},
|
||||||
)
|
);
|
||||||
|
|
||||||
|
swap_chain
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw<T: AsRef<str>>(
|
fn draw<T: AsRef<str>>(
|
||||||
|
|
@ -120,22 +122,25 @@ 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],
|
||||||
) -> mouse::Interaction {
|
) -> Result<mouse::Interaction, ()> {
|
||||||
let frame = swap_chain.get_current_frame().expect("Next frame");
|
match swap_chain.get_current_frame() {
|
||||||
|
Ok(frame) => {
|
||||||
let mut encoder = self.device.create_command_encoder(
|
let mut encoder = self.device.create_command_encoder(
|
||||||
&wgpu::CommandEncoderDescriptor {
|
&wgpu::CommandEncoderDescriptor {
|
||||||
label: Some("iced_wgpu encoder"),
|
label: Some("iced_wgpu encoder"),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
let _ = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
|
let _ =
|
||||||
color_attachments: &[wgpu::RenderPassColorAttachmentDescriptor {
|
encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
|
||||||
|
color_attachments: &[
|
||||||
|
wgpu::RenderPassColorAttachmentDescriptor {
|
||||||
attachment: &frame.output.view,
|
attachment: &frame.output.view,
|
||||||
resolve_target: None,
|
resolve_target: None,
|
||||||
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),
|
||||||
|
|
@ -146,7 +151,8 @@ impl iced_graphics::window::Compositor for Compositor {
|
||||||
}),
|
}),
|
||||||
store: true,
|
store: true,
|
||||||
},
|
},
|
||||||
}],
|
},
|
||||||
|
],
|
||||||
depth_stencil_attachment: None,
|
depth_stencil_attachment: None,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -172,6 +178,15 @@ impl iced_graphics::window::Compositor for Compositor {
|
||||||
|
|
||||||
self.local_pool.run_until_stalled();
|
self.local_pool.run_until_stalled();
|
||||||
|
|
||||||
mouse_interaction
|
Ok(mouse_interaction)
|
||||||
|
}
|
||||||
|
Err(error) => match error {
|
||||||
|
wgpu::SwapChainError::Outdated => {
|
||||||
|
// Try again next frame.
|
||||||
|
Err(())
|
||||||
|
}
|
||||||
|
_ => panic!("Swapchain error: {:?}", error),
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -311,15 +311,14 @@ async fn run_instance<A, E, C>(
|
||||||
viewport_version = current_viewport_version;
|
viewport_version = current_viewport_version;
|
||||||
}
|
}
|
||||||
|
|
||||||
let new_mouse_interaction = compositor.draw(
|
if let Ok(new_mouse_interaction) = compositor.draw(
|
||||||
&mut renderer,
|
&mut renderer,
|
||||||
&mut swap_chain,
|
&mut swap_chain,
|
||||||
state.viewport(),
|
state.viewport(),
|
||||||
state.background_color(),
|
state.background_color(),
|
||||||
&primitive,
|
&primitive,
|
||||||
&debug.overlay(),
|
&debug.overlay(),
|
||||||
);
|
) {
|
||||||
|
|
||||||
debug.render_finished();
|
debug.render_finished();
|
||||||
|
|
||||||
if new_mouse_interaction != mouse_interaction {
|
if new_mouse_interaction != mouse_interaction {
|
||||||
|
|
@ -332,6 +331,12 @@ async fn run_instance<A, E, C>(
|
||||||
|
|
||||||
// TODO: Handle animations!
|
// TODO: Handle animations!
|
||||||
// Maybe we can use `ControlFlow::WaitUntil` for this.
|
// 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::Event::WindowEvent {
|
||||||
event: window_event,
|
event: window_event,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue