Skip to content

Commit b9475de

Browse files
committed
Emit destroy_surfaces() consistently on all platforms
Surface creation and destruction events exist "specifically" for Android which has diverging lifetimes for its `Surface` structure compared to other platforms; specifically Vulkan `VkSurfaceKHR` or `EGLSurface` objects need to be destroyed and recreated. Commit 6cdb317 ("Consistently deliver a Resumed event on all platforms") made sure to consistently call `can_create_surfaces()` (`Event::Resumed` back then) on all platforms directly after startup so that users don't have to have platform-specific surface creation behaviour in two disjoint places, but we forgot about `destroy_surfaces()` (back then `Event::Suspended`) leading to applications still having to handle this destruction in two different places. Solve that by calling the callback on all those platforms, directly before returning `PumpStatus::Exit` from `fn single_iteration()`.
1 parent 043c863 commit b9475de

File tree

7 files changed

+36
-8
lines changed

7 files changed

+36
-8
lines changed

winit-appkit/src/event_loop.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,7 @@ impl EventLoop {
315315

316316
if self.app_state.exiting() {
317317
self.app_state.internal_exit();
318+
app.destroy_surfaces(&self.window_target);
318319
PumpStatus::Exit(0)
319320
} else {
320321
PumpStatus::Continue

winit-core/src/application/mod.rs

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,9 @@ pub trait ApplicationHandler {
7272
/// applications to create a render surface until that point.
7373
///
7474
/// For consistency, all platforms call this method even if they don't themselves have a formal
75-
/// surface destroy/create lifecycle. For systems without a surface destroy/create lifecycle the
76-
/// [`can_create_surfaces()`] event is always emitted after the [`StartCause::Init`] event.
75+
/// surface create/destroy lifecycle. For systems without a surface create/destrory lifecycle
76+
/// the [`can_create_surfaces()`] event is always emitted after the [`StartCause::Init`]
77+
/// event.
7778
///
7879
/// Applications should be able to gracefully handle back-to-back [`can_create_surfaces()`] and
7980
/// [`destroy_surfaces()`] calls.
@@ -275,6 +276,21 @@ pub trait ApplicationHandler {
275276
///
276277
/// See [`can_create_surfaces()`] for more details.
277278
///
279+
/// ## Portability
280+
///
281+
/// It's recommended that applications should only destroy their render surfaces after the
282+
/// [`destroy_surfaces()`] method is called. Some systems (specifically Android) won't allow
283+
/// applications to use the render surface after that point.
284+
///
285+
/// For consistency, all platforms call this method even if they don't themselves have a formal
286+
/// surface create/destroy lifecycle. For systems without a surface create/destroy lifecycle the
287+
/// [`destroy_surfaces()`] event is always emitted before [`PumpStatus::Exit`] is returned.
288+
///
289+
/// Applications should be able to gracefully handle back-to-back [`can_create_surfaces()`] and
290+
/// [`destroy_surfaces()`] calls.
291+
///
292+
/// [`PumpStatus::Exit`]: crate::event_loop::pump_events::PumpStatus::Exit
293+
///
278294
/// ## Platform-specific
279295
///
280296
/// ### Android
@@ -298,10 +314,6 @@ pub trait ApplicationHandler {
298314
/// [`VkSurfaceKHR`]: https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/VkSurfaceKHR.html
299315
/// [`wgpu::Surface`]: https://docs.rs/wgpu/latest/wgpu/struct.Surface.html
300316
///
301-
/// ### Others
302-
///
303-
/// - **iOS / macOS / Orbital / Wayland / Web / Windows / X11:** Unsupported.
304-
///
305317
/// [`can_create_surfaces()`]: Self::can_create_surfaces()
306318
/// [`destroy_surfaces()`]: Self::destroy_surfaces()
307319
fn destroy_surfaces(&mut self, event_loop: &dyn ActiveEventLoop) {

winit-wayland/src/event_loop/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,8 @@ impl EventLoop {
218218
if let Some(code) = self.exit_code() {
219219
self.loop_running = false;
220220

221+
app.destroy_surfaces(&self.active_event_loop);
222+
221223
PumpStatus::Exit(code)
222224
} else {
223225
// NOTE: spawn a wake-up thread, thus if we have code reading the wayland connection

winit-win32/src/event_loop.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,9 @@ impl EventLoop {
303303
// Immediately reset the internal state for the loop to allow
304304
// the loop to be run more than once.
305305
self.runner.reset_runner();
306+
307+
app.destroy_surfaces(ActiveEventLoop::from_ref(&self.runner));
308+
306309
PumpStatus::Exit(code)
307310
} else {
308311
self.runner.prepare_wait();

winit-x11/src/event_loop.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -479,6 +479,8 @@ impl EventLoop {
479479
if let Some(code) = self.exit_code() {
480480
self.loop_running = false;
481481

482+
app.destroy_surfaces(&self.event_processor.target);
483+
482484
PumpStatus::Exit(code)
483485
} else {
484486
PumpStatus::Continue

winit/src/changelog/v0.31.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
## Unreleased
2+
3+
### Changed
4+
5+
- `destroy_surfaces()` is now emitted on all platforms for behaviour-parity.
6+
17
## 0.31.0-beta.2
28

39
### Added
@@ -86,8 +92,8 @@
8692
- `ApplicationHandler::can_create|destroy_surfaces()` was split off from
8793
`ApplicationHandler::resumed/suspended()`.
8894

89-
`ApplicationHandler::can_create_surfaces()` should, for portability reasons
90-
to Android, be the only place to create render surfaces.
95+
`ApplicationHandler::can_create_surfaces()` and `ApplicationHandler::destroy_surfaces()` should,
96+
for portability reasons to Android, be the only place to create and destroy render surfaces respectively.
9197

9298
`ApplicationHandler::resumed/suspended()` are now only emitted by iOS, Web
9399
and Android, and now signify actually resuming/suspending the application.

winit/src/event_loop.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,8 @@ impl EventLoop {
165165
/// start_cause = event_loop.wait_if_necessary();
166166
/// }
167167
///
168+
/// app.destroy_surfaces(event_loop);
169+
///
168170
/// // Finished running, drop application state.
169171
/// drop(app);
170172
/// ```

0 commit comments

Comments
 (0)