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

Improve waiting for messages on Windows #3950

Commits on Oct 28, 2024

  1. Improve waiting for messages on Windows

    Previous version used [`SetTimer`] with `GetMessageW` for waiting.
    The downside of UI timers like ones created by `SetTimer`,
    is that they may be late by up to 15-16 ms.
    
    To fix this behaviour, I added use of high resolution 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 resolution 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 `SetTimer`.
    
    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.
    
    After [review] from @rib, I also moved the waiting itself from `wait_for_messages` method to separate function, so it is clearly seen that `wait_for_messages` do 3 things: notify app that we about to wait, wait, notify that we have new events.
    
    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 when 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
    [`SetTimer`]: https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-settimer
    [review]: rust-windowing#3950 (comment)
    AngelicosPhosphoros committed Oct 28, 2024
    Configuration menu
    Copy the full SHA
    8301d4d View commit details
    Browse the repository at this point in the history