macos: fix abort on first presented frame after winit 0.30 bump - #76
Open
tenox7 wants to merge 1 commit into
Open
macos: fix abort on first presented frame after winit 0.30 bump#76tenox7 wants to merge 1 commit into
tenox7 wants to merge 1 commit into
Conversation
…hread winit 0.30 (bumped in 6bbb609) returns HandleError::Unavailable from window_handle() on macOS when called off the main thread; winit 0.29 handed out the NSView pointer from any thread. GlRenderer::init_gl() runs on the REX3-Refresh thread — lazily, from the first present(), which is gated on the guest programming a video mode — so the CLI aborted on the first frame: thread 'REX3-Refresh' panicked at src/ui.rs:99: surface attributes: Unavailable Capture the RawWindowHandle once in Ui::new() on the main thread (it was already fetched there for GL context creation) and build the surface attributes from it in init_gl() instead of calling build_surface_attributes(), which re-queries the handle. glutin's CGL create_window_surface only reads the handle out of the attrs, so surface creation itself stays on the refresh thread per the existing ownership model. headless_gl.rs keeps its .ok()? pattern: it creates its own EventLoop on the calling thread, which already degrades gracefully off-main on macOS.
Contributor
There was a problem hiding this comment.
Pull request overview
Fixes a macOS crash introduced by the winit 0.30 upgrade by ensuring the window handle used for GL surface creation is acquired on the main thread and then reused safely from the refresh thread, aligning with the existing “GL owned by refresh thread” model in IRIS.
Changes:
- Cache
RawWindowHandleinUi::new()(main thread) and store it inGlRenderer. - Build GL surface attributes in
GlRenderer::init_gl()using the cached handle plus the currentwindow.inner_size(), avoidingwindow_handle()calls off the main thread on macOS. - Add a rules note documenting the winit 0.30 macOS main-thread-only handle constraint and the established workaround.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
src/ui.rs |
Caches RawWindowHandle on the main thread and uses it to create the window surface on the refresh thread, preventing the macOS abort after the winit 0.30 bump. |
rules/macos/winit-030-window-handle-main-thread-only.md |
Documents the winit 0.30 macOS behavior change and the required pattern for handle capture/surface creation. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Contributor
|
Looks good to me, thanks for this. I must have missed it during my testing! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Since 6bbb609 (winit 0.29 → 0.30), the CLI aborts on macOS the moment the guest programs a video mode:
100% reproducible:
present()is gated onscreen.width > 0, so the first-everpresent()→GlRenderer::init_gl()happens on the REX3-Refresh thread right at the first mode set.build_surface_attributes()callswindow_handle(), and winit 0.30's macOS backend returnsErr(HandleError::Unavailable)off the main thread (platform_impl/macos/window.rs, gated onMainThreadMarker). winit 0.29 handed out the NSView pointer from any thread, which is why this code was fine before.Fix
Capture the
RawWindowHandleonce inUi::new()on the main thread — it was already fetched there for GL context creation — stash it inGlRenderer, and build the surface attributes from it ininit_gl()withwindow.inner_size(). glutin 0.32's CGLcreate_window_surfaceonly reads the handle out of the attrs (no main-thread check of its own), so surface creation itself stays on the refresh thread, consistent with the existing GL-ownership model (unsafe impl Send for GlRenderer).headless_gl.rsis intentionally untouched: it creates its ownEventLoopon the calling thread, which already degrades gracefully (.ok()?→None) off-main on macOS.Also adds
rules/macos/winit-030-window-handle-main-thread-only.mddocumenting the gotcha.Testing
cargo build --release --features lightning,rex-jit,tlbvmap,idle-pauseclean on macOS arm64 (only pre-existing warnings)Resolution changed to 1282x1024with no panic🤖 Generated with Claude Code