Skip to content
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

Corrected use of visibility to drive rendering on unsupported platforms #12607

Closed
wants to merge 3 commits into from

Conversation

thebluefish
Copy link
Contributor

@thebluefish thebluefish commented Mar 21, 2024

Objective

Resolves an issue on Chrome where CPU usage spikes while the tab is inactive.

Looks related to #12126, but actually it's actually a different bug.

Solution

The root issue is that window.request_redraw() fails to provoke the WindowEvent::RedrawRequested event we expect when another tab in Chrome has focus. This breaks the event loop, and causes winit to hound bevy_winit's runner with StartCause::ResumeTimeReached events repeatedly in response to an aging ControlFlow::WaitUntil end time.

Upon investigation, the winit docs on Window::is_visible mention:

None means it couldn’t be determined, so it is not recommended to use this to drive your rendering backend.

This suggests to me that we cannot rely on window visibility to determine if we can request_redraw on these platforms, and we should just run the inner update immediately.

This PR changes the check from bevy's Window::visible to winit's Window::is_visible(), and defaults it to false in the aforementioned None cases. This means that we are always firing the inner update during AboutToWait on these platforms, which should be the correct place from what I can tell. This needs to be further tested on those platforms mentioned:

  • Web
  • iOS
  • Android
  • X11
  • Wayland

Something that needs to be hashed out is the original ControlFlow::Poll behavior. It seems to me that we should only need to set Poll once, and the current behavior gets around the ControlFlow set during inner update. I could not ascertain the scenarios where it would be useful to set it in the manner we were before, overriding the new Wait/WaitUntil each time, and I believe we should remove it entirely. For now I gated just those platforms with visibility concerns, which feels wrong.

@alice-i-cecile alice-i-cecile added this to the 0.13.2 milestone Mar 21, 2024
@alice-i-cecile alice-i-cecile added C-Bug An unexpected or incorrect behavior A-Windowing Platform-agnostic interface layer to run your app in O-Web Specific to web (WASM) builds labels Mar 21, 2024
@alice-i-cecile
Copy link
Member

I've reopened the corresponding issue, added a link to the user reproduction on 0.13.1, and noted that this PR should fix that issue in your PR description :)

@thebluefish
Copy link
Contributor Author

I would like to note this actually has nothing to do with #12126, but this issue is currently only documented on discord roughly here.

Both issues have the same root problem because winit does not handle an old WaitUntil end time gracefully.

@thebluefish
Copy link
Contributor Author

This update runs more closely in line with how I believe winit expects us to drive the loop. There is still something to be ironed out, as Continuous mode runs too fast. I believe the Poll/Wait stuff from the related PR might be the right approach there.

@alice-i-cecile alice-i-cecile added the D-Complex Quite challenging from either a design or technical perspective. Ask for help! label Mar 22, 2024
@thebluefish
Copy link
Contributor Author

Closing in favor of the other PR that addresses this same issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-Windowing Platform-agnostic interface layer to run your app in C-Bug An unexpected or incorrect behavior D-Complex Quite challenging from either a design or technical perspective. Ask for help! O-Web Specific to web (WASM) builds
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants