Skip to content

macOS: Fix one-second delay when switching a wgpu app to the foreground#9141

Merged
Wumpf merged 9 commits intogfx-rs:trunkfrom
rerun-io:emilk/fix-mac-switch-delay
Mar 8, 2026
Merged

macOS: Fix one-second delay when switching a wgpu app to the foreground#9141
Wumpf merged 9 commits intogfx-rs:trunkfrom
rerun-io:emilk/fix-mac-switch-delay

Conversation

@emilk
Copy link
Contributor

@emilk emilk commented Mar 2, 2026

Connections

Description

  • Fix 1-second hang when switching to a wgpu application that was in the background on macOS
  • ⚠️ get_current_texture can now return SurfaceError::Occluded (only on Mac currently)
  • Change return type of fn acquire_texture to return timeouts as an error variant

On macOS, when a window is occluded (minimized, behind other windows, or on another virtual desktop), CAMetalLayer.nextDrawable() can block for up to 1 second. This happens because presented drawables get stuck waiting for vsync that isn't happening while the window is hidden.

When switching back to a wgpu application that was in the background, users experience a noticeable 1-second delay before the application becomes responsive.

This PR adds a fix: in the top of aquire_texture we first check if the window is occluded. If it is, we return a new SurfaceError::Occluded error right away, avoiding the 1 second delay.

This then requires users to actually handle this new error by attempting again later.

Thanks to Claude and @Wumpf for helping me with this PR!

Testing
I ran cargo r -p wgpu-example-02-hello-window, switching the app to be behind and then in front of another opaque window.

  • cargo run --bin wgpu-examples cube
  • cargo run --bin wgpu-examples hello_triangle
  • cargo run --bin wgpu-examples uniform_values
  • cargo r -p wgpu-example-02-hello-window

Squash or Rebase?
Squash

Checklist

  • Run cargo fmt.
  • Run taplo format.
  • Run cargo clippy --tests. If applicable, add:
    • --target wasm32-unknown-unknown
  • Run cargo xtask test to run tests.
  • If this contains user-facing changes, add a CHANGELOG.md entry.

@emilk emilk changed the title Metal: Skip frame acquisition when window is occluded to avoid drawable stall macOS: Fix one-second delay when switching a wgpu app to the foreground Mar 2, 2026
@emilk emilk marked this pull request as ready for review March 2, 2026 14:25
@Wumpf Wumpf self-assigned this Mar 2, 2026
@Wumpf Wumpf self-requested a review March 2, 2026 14:45
@cwfitzgerald cwfitzgerald self-assigned this Mar 4, 2026
@emilk
Copy link
Contributor Author

emilk commented Mar 6, 2026

I hear from @Wumpf (on other channels) that we should return a new error code instead of returning None (indicating timeout).

My plan is to change acquire_texture from returning a Result<Option<Surface>, SurfaceError> to returning Result<Surface, SurfaceError>, and add Timeout as an error variant in SurfaceError instead (mirroring SurfaceStatus). After that, add Occluded as an error variant both to SurfaceError and to SurfaceStatus.

@emilk emilk marked this pull request as draft March 6, 2026 09:09
@emilk emilk marked this pull request as ready for review March 6, 2026 10:29
Copy link
Member

@Wumpf Wumpf left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good to me, except for the wrong comment I found. Much cleaner than before!

@emilk emilk requested a review from Wumpf March 8, 2026 16:18
Copy link
Member

@Wumpf Wumpf left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice. Going to land that and further investigate correct reaction to inclusion events as part of #9089
Which I want to review soonish; I'll then put some effort into learning about how to correctly process occluded events on winit and will transfer those learnings to eframe as well if it can be mitigated there

@Wumpf Wumpf merged commit 12b9d49 into gfx-rs:trunk Mar 8, 2026
58 checks passed
@Wumpf Wumpf deleted the emilk/fix-mac-switch-delay branch March 8, 2026 22:40
@emilk
Copy link
Contributor Author

emilk commented Mar 9, 2026

It actually looks like I accidentally counteracted the same problem in this PR:

On egui main now (without the fix in this wgpu PR), I get zero delay when moving the window to the front EXCEPT if I do so very quickly (switch back and forth within a single second).

ErichDonGubler added a commit to erichdongubler-mozilla/wgpu that referenced this pull request Mar 10, 2026
andyleiserson pushed a commit that referenced this pull request Mar 11, 2026
* style(CHANGELOG): ensure double newline b/w paragraph and fenced code blocks

Regressed by <#9180>. I missed this
in review.

* docs(CHANGELOG): fix up formatting for #9141

* docs(CHANGELOG): clarify that `get_current_texture` in a `Surface` method
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Mac/Metal: After alt-tab, get_current_texture locks for exactly one second

3 participants