-
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
Improve waiting for messages on Windows [PR to 0.30.x branch] #3949
Improve waiting for messages on Windows [PR to 0.30.x branch] #3949
Conversation
Current version in crates.io:TestWith0.30.5.mp4With my changes:TestWithPatch.mp4 |
I don't know why but when I run I would manually change formatting. |
Previous version used `CreateTimer` with `GetMessageW` for waiting. The downside of UI timers like ones created by `CreateTimer`, is that they may be late by up to 15-16 ms. To fix this behaviour, I added use of high precision timers created by [`CreateWaitableTimerExW`] with the flag `CREATE_WAITABLE_TIMER_HIGH_RESOLUTION`. In my previous experience, waiting on such timers have precision of roundly 0.5 ms which is the best available on Windows at the moment. I use [`MsgWaitForMultipleObjectsEx`] to wait simultaneously for both timer and newly arriving events. Unfortunately, high precision timers are available only since Windows 10 1803. However: 1. Win 10 is already getting to the end of support, like all previous versions, so it is OK to rely on APIs introduced in it; 2. I use `dwMilliseconds` parameter of `MsgWaitForMultipleObjectsEx` as a fallback. It should perform not worse compared to waiting for events from [`CreateTimer`]. I also refactored code to remove event dispatching from function responsible for waiting for events. This provides more clear separations of concern and avoids unnecessary duplication of dispatching logic. I have tested behaviour using a egui app with Vulkan rendering with `VK_PRESENT_MODE_IMMEDIATE_KHR`, and older version consistently have twice less FPS than requested (e.g. 30 FPS when limit is 60 and 60 FPS when limit is 120) while newer version works more correctly (almost always 60 FPS when limit is 60, and only 5-10 frames missing whne FPS is set to 120 or more). Fixes rust-windowing#1610 [`CreateWaitableTimerExW`]: https://learn.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-createwaitabletimerexw [`MsgWaitForMultipleObjectsEx`]: https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-msgwaitformultipleobjectsex
9b3510e
to
a381ea2
Compare
Please, open your changes against the master branch. You should use the nightly formatting. |
@kchibisov If my code gets merged to master, would those changes be ported and released as 0.30.x? I just finished migration to 0.30.x and I fear that I would need to wait long time for egui and egui-winit to catch up. |
Opened PR to master: #3950 |
I don't see why not. The only issue is that we currently lack active windows maintainer, so getting things reviewed could be a bit hard, unless e.g. @notgull wants to look into that. I myself don't really look into windows stuff. |
Closing in favor of #3950. |
Previous version used
CreateTimer
withGetMessageW
for waiting. The downside of UI timers like ones created byCreateTimer
, is that they may be late by up to 15-16 ms.To fix this behaviour, I added use of high precision timers created by
CreateWaitableTimerExW
with the flagCREATE_WAITABLE_TIMER_HIGH_RESOLUTION
. In my previous experience, waiting on such timers have precision of roundly 0.5 ms which is the best available on Windows at the moment. I useMsgWaitForMultipleObjectsEx
to wait simultaneously for both timer and newly arriving events.Unfortunately, high precision timers are available only since Windows 10 1803. However:
dwMilliseconds
parameter ofMsgWaitForMultipleObjectsEx
as a fallback. It should perform not worse compared to waiting for events from [CreateTimer
].I also refactored code to remove event dispatching from function responsible for waiting for events. This provides more clear separations of concern and avoids unnecessary duplication of dispatching logic.
I have tested behaviour using a egui app with Vulkan rendering with
VK_PRESENT_MODE_IMMEDIATE_KHR
, and older version consistently have twice less FPS than requested (e.g. 30 FPS when limit is 60 and 60 FPS when limit is 120) while newer version works more correctly (almost always 60 FPS when limit is 60, and only 5-10 frames missing whne FPS is set to 120 or more).Fixes #1610
changelog
module if knowledge of this change could be valuable to users