From 11c3602f34584e829a793263a86f9affb53858a8 Mon Sep 17 00:00:00 2001 From: Joe Cuffney Date: Fri, 18 Sep 2026 15:50:58 -0400 Subject: [PATCH] Do not panic when device().poll() times out Both wgpu window renderers ended `render` by unwrapping the completion poll, so a driver that never signals the submission complete takes the process down with it. The frame has already been presented by the time the poll runs - the call waits for GPU completion rather than producing output - so there is nothing to retry and nothing to skip. Drop the error instead, matching the `maybe_blit_and_present().is_err() => return` check six lines above. Same class as #38 and #46. Co-Authored-By: Claude Opus 5 --- crates/anyrender_vello/CHANGELOG.md | 6 ++++++ crates/anyrender_vello/src/window_renderer.rs | 10 +++++++--- crates/anyrender_vello_hybrid/CHANGELOG.md | 6 ++++++ crates/anyrender_vello_hybrid/src/window_renderer.rs | 10 +++++++--- 4 files changed, 26 insertions(+), 6 deletions(-) diff --git a/crates/anyrender_vello/CHANGELOG.md b/crates/anyrender_vello/CHANGELOG.md index a491492..f57af68 100644 --- a/crates/anyrender_vello/CHANGELOG.md +++ b/crates/anyrender_vello/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this crate are documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [Unreleased] + +### Fixed + +- A `wgpu::PollError::Timeout` from the completion `poll` at the end of `WindowRenderer::render` no longer panics. The frame has already been presented at that point, so the error is dropped instead of bringing the process down (#96). + ## [0.14.0] - 2026-08-16 ### Added diff --git a/crates/anyrender_vello/src/window_renderer.rs b/crates/anyrender_vello/src/window_renderer.rs index 13b8024..dbc0019 100644 --- a/crates/anyrender_vello/src/window_renderer.rs +++ b/crates/anyrender_vello/src/window_renderer.rs @@ -487,10 +487,14 @@ impl WindowRenderer for VelloWindowRenderer { } timer.record_time("present"); - render_surface + // A timeout here means the driver has not signalled the submission + // complete. The frame has already been presented, so there is nothing to + // retry and nothing to skip; carrying on is strictly better than + // bringing the process down. Same reasoning as the + // `maybe_blit_and_present` check above. + let _ = render_surface .device() - .poll(wgpu::PollType::wait_indefinitely()) - .unwrap(); + .poll(wgpu::PollType::wait_indefinitely()); timer.record_time("wait"); timer.print_times("vello: "); diff --git a/crates/anyrender_vello_hybrid/CHANGELOG.md b/crates/anyrender_vello_hybrid/CHANGELOG.md index ad0fbfe..4a8a917 100644 --- a/crates/anyrender_vello_hybrid/CHANGELOG.md +++ b/crates/anyrender_vello_hybrid/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this crate are documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [Unreleased] + +### Fixed + +- A `wgpu::PollError::Timeout` from the completion `poll` at the end of `WindowRenderer::render` no longer panics. The frame has already been presented at that point, so the error is dropped instead of bringing the process down (#96). + ## [0.10.0] - 2026-08-16 ### Changed diff --git a/crates/anyrender_vello_hybrid/src/window_renderer.rs b/crates/anyrender_vello_hybrid/src/window_renderer.rs index c326650..31a1fab 100644 --- a/crates/anyrender_vello_hybrid/src/window_renderer.rs +++ b/crates/anyrender_vello_hybrid/src/window_renderer.rs @@ -539,10 +539,14 @@ impl WindowRenderer for VelloHybridWindowRenderer { } timer.record_time("present"); - render_surface + // A timeout here means the driver has not signalled the submission + // complete. The frame has already been presented, so there is nothing to + // retry and nothing to skip; carrying on is strictly better than + // bringing the process down. Same reasoning as the + // `maybe_blit_and_present` check above. + let _ = render_surface .device() - .poll(wgpu::PollType::wait_indefinitely()) - .unwrap(); + .poll(wgpu::PollType::wait_indefinitely()); timer.record_time("wait"); timer.print_times("vello_hybrid: ");