Merge pull request #667 from BillyDM/wgpu_outdatedframe

Don't panic when wgpu swapchain frame is outdated
This commit is contained in:
Héctor Ramón 2021-08-05 14:44:32 +07:00 committed by GitHub
commit 45778ed598
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 180 additions and 109 deletions

View file

@ -141,59 +141,79 @@ impl iced_graphics::window::Compositor for Compositor {
background_color: Color,
output: &<Self::Renderer as iced_native::Renderer>::Output,
overlay: &[T],
) -> mouse::Interaction {
let frame = swap_chain.get_current_frame().expect("Next frame");
) -> Result<mouse::Interaction, iced_graphics::window::SwapChainError> {
match swap_chain.get_current_frame() {
Ok(frame) => {
let mut encoder = self.device.create_command_encoder(
&wgpu::CommandEncoderDescriptor {
label: Some("iced_wgpu encoder"),
},
);
let mut encoder = self.device.create_command_encoder(
&wgpu::CommandEncoderDescriptor {
label: Some("iced_wgpu encoder"),
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,
&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::Timeout => {
Err(iced_graphics::window::SwapChainError::Timeout)
}
wgpu::SwapChainError::Outdated => {
Err(iced_graphics::window::SwapChainError::Outdated)
}
wgpu::SwapChainError::Lost => {
Err(iced_graphics::window::SwapChainError::Lost)
}
wgpu::SwapChainError::OutOfMemory => {
Err(iced_graphics::window::SwapChainError::OutOfMemory)
}
},
);
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,
&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
}
}
}