Use a QPC wrapper to avoid NtGetTickCount, which is coupled to the 16 millisecond user_shared_data_timeout in server/fd.c.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=57442
-- v2: win32u: Check for driver events more often.
From: William Horvath william@horvath.blog
Use a QPC wrapper to avoid NtGetTickCount, which is coupled to the 16 millisecond user_shared_data_timeout in server/fd.c. This lowers the throttling period to 0.25ms (8khz), which is quick enough to consume driver events from high polling rate devices.
Fixes: 54ca1ab6 Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=57442 --- dlls/win32u/message.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-)
diff --git a/dlls/win32u/message.c b/dlls/win32u/message.c index ef8b6f86431..fc3b0f26827 100644 --- a/dlls/win32u/message.c +++ b/dlls/win32u/message.c @@ -3059,14 +3059,22 @@ static HANDLE get_server_queue_handle(void) return ret; }
+/* monotonic timer tick for driver event check throttling */ +static inline DWORD get_driver_check_time(void) +{ + LARGE_INTEGER counter, freq; + NtQueryPerformanceCounter( &counter, &freq ); + return counter.QuadPart * 8000 / freq.QuadPart; /* 8kHz */ +} + /* check for driver events if we detect that the app is not properly consuming messages */ static inline void check_for_driver_events(void) { - if (get_user_thread_info()->last_driver_time != NtGetTickCount()) + if (get_user_thread_info()->last_driver_time != get_driver_check_time()) { flush_window_surfaces( FALSE ); user_driver->pProcessEvents( QS_ALLINPUT ); - get_user_thread_info()->last_driver_time = NtGetTickCount(); + get_user_thread_info()->last_driver_time = get_driver_check_time(); } }
@@ -3108,7 +3116,7 @@ static DWORD wait_message( DWORD count, const HANDLE *handles, DWORD timeout, DW }
if (ret == WAIT_TIMEOUT && !count && !timeout) NtYieldExecution(); - if (ret == count - 1) get_user_thread_info()->last_driver_time = NtGetTickCount(); + if (ret == count - 1) get_user_thread_info()->last_driver_time = get_driver_check_time();
KeUserDispatchCallback( ¶ms.dispatch, sizeof(params), &ret_ptr, &ret_len );