Corrected use of visibility to drive rendering on unsupported platforms #12607
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.
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 theWindowEvent::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 withStartCause::ResumeTimeReached
events repeatedly in response to an agingControlFlow::WaitUntil
end time.Upon investigation, the winit docs on Window::is_visible mention:
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'sWindow::is_visible()
, and defaults it tofalse
in the aforementionedNone
cases. This means that we are always firing the inner update duringAboutToWait
on these platforms, which should be the correct place from what I can tell. This needs to be further tested on those platforms mentioned:Something that needs to be hashed out is the original
ControlFlow::Poll
behavior. It seems to me that we should only need to setPoll
once, and the current behavior gets around theControlFlow
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 newWait
/WaitUntil
each time, and I believe we should remove it entirely. For now I gated just those platforms with visibility concerns, which feels wrong.