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
-- v3: 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 +++++++++++--- dlls/win32u/ntuser_private.h | 2 +- 2 files changed, 12 insertions(+), 4 deletions(-)
diff --git a/dlls/win32u/message.c b/dlls/win32u/message.c index ef8b6f86431..d8da5a0f48f 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 throttling driver event checks */ +static inline LONGLONG 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 );
diff --git a/dlls/win32u/ntuser_private.h b/dlls/win32u/ntuser_private.h index f7a3460a0a6..2f3bbdf91c0 100644 --- a/dlls/win32u/ntuser_private.h +++ b/dlls/win32u/ntuser_private.h @@ -109,7 +109,7 @@ struct user_thread_info struct ntuser_thread_info client_info; /* Data shared with client */ HANDLE server_queue; /* Handle to server-side queue */ DWORD last_getmsg_time; /* Get/PeekMessage last request time */ - DWORD last_driver_time; /* Get/PeekMessage driver event time */ + LONGLONG last_driver_time; /* Get/PeekMessage driver event time */ WORD hook_call_depth; /* Number of recursively called hook procs */ WORD hook_unicode; /* Is current hook unicode? */ HHOOK hook; /* Current hook */
Looks good, thank you!
This merge request was approved by Rémi Bernon.