-
-
Notifications
You must be signed in to change notification settings - Fork 4.2k
mobile and webgpu: trigger redraw request when needed and improve window creation #11245
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
mobile and webgpu: trigger redraw request when needed and improve window creation #11245
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, this is a nice and straightforward fix. Sorry for missing this in my review.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can't really test it, so I'm not confident thumbing up.
But I see window creation on the Event::NewEvents(StartCause::Init) for ios and macos. (lines 367 to 391) Are those now redundant? If they don't run, we should probably remove those lines.
Right, we should! The first commit just fixed Android, and worked on iOS locally due to a cached build artefact with another change. I added a correct fix for iOS (don't request redraw during a I tested this PR on macOS, WebGL2, WebGPU, iOS and Android |
| ); | ||
|
|
||
| create_window_system_state.apply(&mut app.world); | ||
| Event::AboutToWait => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Whats the reason for moving Window::request_redraw() into Event::AboutToWait?
I would recommend to call Window::request_redraw() as soon as you know that you want to draw. Calling it in Event::AboutToWait has the disadvantage of queuing that request later then you could, which might let you miss frames.
The previous method of calling Window::request_redraw() at the end of the event loop was therefor better imo.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the previous method doesn't work on iOS, because most of Bevy request redraw come from the update which is called when reacting to a RedrawRequested event, and that doesn't work on iOS
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What exactly doesn't work on iOS?
Are you saying that WindowEvent::RedrawRequested is not being sent on iOS?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup, WindowEvent::RedrawRequested is not sent if request_redraw() is called while processing WindowEvent::RedrawRequested on iOS.
I also saw this assert in winit code that also makes me believe it should be avoided
https://github.com/rust-windowing/winit/blob/master/src/platform_impl/ios/app_state.rs#L648-L651
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, this would be a bug in Winit.
Will report back when I know more!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mockersf would you mind testing https://github.com/daxpedda/winit/tree/ios-fix-request-redraw-from-redraw-requested-v0.29 and checking if this solves the problem?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@daxpedda I haven't had time yet to test your branch and Bevy is currently broken for another reason on iOS. I will as soon as possible and update you!
| runner_state.active = ActiveState::WillSuspend; | ||
| } | ||
| Event::Resumed => { | ||
| #[cfg(any(target_os = "android", target_os = "ios", target_os = "macos"))] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Creating windows outside of Event::Resumed for these targets is indeed incorrect.
So this change is great!
I would recommend you to move window creation of all targets inside Event::Resumed, it would cut down on the cfg guards.
Let me know if there is a reason why this can't be done or isn't desirable!
| event: DeviceEvent::MouseMotion { delta: (x, y) }, | ||
| .. | ||
| } => { | ||
| runner_state.redraw_requested = true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe this is a good change, I tried to describe the issue in #11235 (comment).
However, as far as I'm aware Bevy currently doesn't call Window::request_redraw() when it actually needs to redraw when using reactive mode. Keep in mind that removing this line will make the current status worse until this is properly addressed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. Nice changes. I was wary of using AboutToWait, because of the disclaimer in the doc. But given the restriction on redraw_request on iOS and the fact there isn't an alternative seems to make it the only sensible choice.
# Objective Fixes #17488 ## Solution The world update logic happened in the the `about_to_wait` winit window callback, but this is is not correct as (1) the winit documentation states that the callback should not be used for that purpose and (2) the callback is not fired when the window is resized or being dragged. However, that callback was used in #11245 to fix an iOS bug (which caused the regression). The solution presented here is a workaround until the event loop code can be re-written. ## Testing I confirmed that the `eased_motion` example continued to be animated when dragging or resizing the window. https://github.com/user-attachments/assets/ffaf0abf-4cd7-479b-83e9-e1850aaf3513
# Objective Fixes #17488 ## Solution The world update logic happened in the the `about_to_wait` winit window callback, but this is is not correct as (1) the winit documentation states that the callback should not be used for that purpose and (2) the callback is not fired when the window is resized or being dragged. However, that callback was used in #11245 to fix an iOS bug (which caused the regression). The solution presented here is a workaround until the event loop code can be re-written. ## Testing I confirmed that the `eased_motion` example continued to be animated when dragging or resizing the window. https://github.com/user-attachments/assets/ffaf0abf-4cd7-479b-83e9-e1850aaf3513
Objective
Solution
Resumeevent. macOS is included because it's excluded from the other initial window creation and I didn't want it to feel alone. Also, it makes sense. this is needed for Androidbevy/crates/bevy_winit/src/lib.rs
Line 152 in cfcb688
AboutToWaitinstead of at the end of the event handler. request to redraw during aRedrawRequestedevent are ignored on iOS