-
Notifications
You must be signed in to change notification settings - Fork 914
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
Add FrameThrottled
event and a way to request it
#2883
Conversation
I'm not sure that I like this naming, but I want to make it clear that it's about throttling and not a |
efaf3be
to
47b1207
Compare
Add a way to request a frame throttling hint from the windowing system. This is essential for platforms like Wayland where you don't have real vsync in OpenGL/Vulkan and you're advised to use 'frame callbacks' to throttle your rendering. `Window::request_frame_throttling_hint` is a an end point for users to request `FrameThrottled` event, which returns error when it can't be done, so the users could fallback to their own scheduling strategies. The API doesn't try to address all sort of frame presentation cases, like how much the frame took, etc. Such cases could be covered later, with different events in addition to the throttling hint. For now implemented only for Wayland. Fixes rust-windowing#2412.
47b1207
to
0fb68dc
Compare
c9ff490
to
02afd22
Compare
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.
Web is done.
Co-authored-by: daxpedda <[email protected]>
We already have Currently This is already problematic because on macOS we emit RedrawRequested via drawRect and after MainEventsCleared and applications just don't really know when they should render. I would really like us to emit
There shouldn't be any need to opt into frame throttling and this shouldn't require any new API, we can instead address the backend inconsistencies we have so that we can rely on the existing API. |
The issue is that some clients don't want to draw once they got the throttling event, like alacritty, for example, when nothing changes. However |
I'd say those semantics for Winit are too poorly defined / inconsistent right now and there is wiggle room to document clear semantics as part of any work to fix how RedrawRequested is emitted consistently.. In terms of the window system being able to demand that you redraw one of the things that's missing for that is being able to report expose rectangles. If the window system really requires a window to be redrawn then that'll likely either be because it's a legacy system, like X11 non-composited responding to Expose events, or e.g. on some systems because the window got resized. Those cases that require the window to be redrawn should be honored by alacritty. Those special cases are the exception not the rule for when RedrawRequested should be emitted though. Most of the time RedrawRequested would follow a redraw_request for a Window. Maybe I should have been clearer about that in the illustration. I didn't meant to say that There may be times that it's triggered for the (exceptional) window-system specific cases that you're referring too but normally it would only trigger if alacritty specifically requested it - so either way alacritty should be fine to redraw whenever it fires and it can still handle incremental redrawing correctly. If nothing has changed alacritty wouldn't request a redraw. |
There's a protocol in works for Wayland to request a new buffer to handle GPU resents, so the compositor could re upload stuff. Or, for example, when client side decorations change the state, and they require a commit from the primary surface, so the sync frame perfect rendering could be achieved. In this case
That's true, we do request a redraw, but sometimes we winit asks us to redraw to sync with its internal stuff, like subsurfaces.
That's true, but the event has established certain behavior, we can't really change the semantics, because it might not be followed.
That's good, but how we'd handle macOS/Windows now? How the event should behave on them? Should we throttle by the timer, how should we indicate the fallback? What should we do about sync requests, like resize on macOS? I agree that it's messy right now, but I don't see how we can merge them without removing |
yeah, that's ok - I'm not saying there aren't reasons for the window system to request redraws, there are. In my view though there's no reason for these to require a completely separate mechansim for notifying the app when to redraw. The app should be able to drive redraws off of one event, and it's a separate detail that sometimes that will be triggered for window system specific reasons and most of the time it will just be triggered because the app requested it. |
But it simply means that in one case the user must do a redraw and in other we want to draw right away? If what you want is |
This feels like a detail we're not seeing eye to eye on. I'm not sure what this means. From the app pov it shouldn't care about I'm trying to not complicate the discussion but I do think that E.g on macOS all redraw events should happen via a It's possible that macOS might call Similarly for Windows. It's possible the app might sometimes get a In all cases here though the application can just get a If the app isn't e.g. resizing it's window to trigger extra |
As far as I understood, this is the big discrepancy here. In some cases when it comes from the system the user MUST redraw, but in other cases the user DOES NOT NEED TO redraw. If I understand this correctly, we have the following cases we want to deal with:
I absolutely believe there is a use-case for all three to be differentiated by the user, this is important information! I would be in favor of merging these events and adding a field to |
@daxpedda I think that could work #2412 (comment) just fine, I'm just not sure if it'll really keep at the monitor frame rate on anything other than Wayland, and how to deal with X11, but we can basically throttle transparently for the user, given that if they want to draw as fast as they can, they don't need any |
I don't think we should. This is a bigger issue that we shouldn't be handling here. Drawing at the monitor frame rate requires some sort of frame pacing, which isn't what we are doing here. Even the whole frame throttling thing is just "frame pacing provided by the system", it's not accurate and far from ideal.
I thought they did, e.g. MacOS requires you to draw inside If this isn't the case and users can draw as fast as they can without |
But I don't see an issue here? For example on Wayland we simply request the callbacks behind the user, and once they do I'd wait for @rib input here, but I don't see an issue with such approach. If we don't want the throttling merged with Be aware that we don't force the re-drawings on users, they ask for them and we use windowing system mechanisms to 'start rendering at the right time'. |
After some IRC talk and clearing up some of the misconceptions I had, I arrived at the following conclusion: There's two use-cases/scenarios Winit needs to handle:
Instant redrawing doesn't require any interaction with Winit. To the API I would suggest is:
In the future we might also want to offer more time-based approaches to frame throttling, which I alluded to here: #2412 (comment). This is unrelated to this PR though. |
Closed in favor of #2896. |
Add a way to request a frame throttling hint from the windowing system. This is essential for platforms like Wayland where you don't have real vsync in OpenGL/Vulkan and you're advised to use 'frame callbacks' to throttle your rendering.
Window::request_frame_throttling_hint
is a an end point for users to requestFrameThrottled
event, which returns error when it can't be done, so the users could fallback to their own scheduling strategies.The API doesn't try to address all sort of frame presentation cases, like how much the frame took, etc. Such cases could be covered later, with different events in addition to the throttling hint.
For now implemented only for Wayland.
Fixes #2412.
--
cc @daxpedda for web.