ios: implement required mtkView:drawableSizeWillChange: selector#642
Merged
Conversation
`MTKViewDelegate` declares two `@required` methods:
`mtkView:drawableSizeWillChange:` and `drawInMTKView:`. The
`QuadViewDlg` class only registered the latter, so any actual
drawable-size change (window resize, rotation under a non-locked
orientation set, split-view drag on iPad) crashed:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException',
reason: '-[QuadViewDlg mtkView:drawableSizeWillChange:]:
unrecognized selector sent to instance 0x...'
... [MTKView _resizeDrawable]
... [UIView setFrame:]
... [UIWindow _rotateWindowToOrientation:...]
Reproduced on the iPad Air 11-inch simulator on iOS 27 by rotating
the device. Did not reproduce on the iPhone 17 simulator there
because CHOMP's Info.plist locks orientation, so the drawable size
never actually changes.
Implementation is a stub: `draw_in_rect` already polls
`UIScreen.mainScreen.bounds` every frame and emits `Message::Resize`
on a delta, so a no-op satisfies the protocol without changing the
existing resize path.
92ec060 to
b8062d0
Compare
Per Apple's MTKView contract, `drawableSizeWillChange:` is invoked
before the next `drawInMTKView:` whenever the drawable's pixel
dimensions change (window resize, rotation under a non-locked
orientation set, split-view drag on iPad). The previous commit added
a no-op stub to satisfy the protocol; that prevents the
"unrecognized selector" crash but leaves `native_display`'s stored
dimensions stale until the next frame's
`UIScreen.mainScreen.bounds` poll catches up.
During iPad rotation animations the stored dimensions stay one frame
behind the resized drawable. Anything that depends on the
framebuffer dimensions for the current pass — `setScissorRect` is
the common case — gets computed against the old size and fails
Metal validation:
-[MTLDebugRenderCommandEncoder setScissorRect:]: failed assertion
`Set Scissor Rect Validation
(rect.y(688) + rect.height(2064))(2752) must be <=
render pass height(2064)'
Update `native_display`'s `screen_width`/`screen_height` from the
size argument immediately and send `Message::Resize` so the event
handler resizes before the next draw. `draw_in_rect`'s own
`UIScreen.bounds` poll still runs as a fallback (e.g. for full-screen
size changes that don't go through the delegate).
b8062d0 to
b83cdd2
Compare
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.
MTKViewDelegatedeclares two@requiredmethods:mtkView:drawableSizeWillChange:anddrawInMTKView:. TheQuadViewDlgclass only registered the latter, so any actual drawable-size change (window resize, rotation under a non-locked orientation set, split-view drag on iPad) crashed:Implementing the selector as a no-op fixes the immediate crash, but the handler also needs to sync
native_display'sscreen_width/screen_heightto the new drawable size and emitMessage::Resizebefore the nextdrawInMTKView:. The fallback resize-detect path indraw_in_rectpollsUIScreen.mainScreen.bounds, which lags MTKView's drawableSize during rotation animations — anything that depends on the framebuffer dimensions for the current pass then computes against stale values and fails Metal validation:Reproduced on iPad Air 11-inch and iPad Pro 13-inch simulators on iOS 27 by rotating the device. Apps that lock orientation via
Info.plist(or runtime supported-orientations) never see a drawable-size change and so don't hit either crash.The full path:
drawableSizeWillChangeupdatesnative_displayimmediately and sendsMessage::Resize;draw_in_rect's ownUIScreen.boundspoll still runs as a fallback (e.g. for size changes that don't go through the delegate).