This message triggers screensaver notification in the user drivers, but it is not useful to send it on every input message, and it even hurts performance when high polling mouse is used.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=33643 Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=46976 Signed-off-by: Rémi Bernon rbernon@codeweavers.com ---
Notes: This only partially solves the mentionned bugs. Performance can be improved even more by using rawinput API instead of low-level hooks, but it requires the wineserver side to be implemented first.
Because wiggling the mouse is a bit unpredictable, I've used evemu to create a fake evdev mouse device. And I've then injected events using this python / evemu-play script:
python -u - <<EOF | stdbuf -oL evemu-play /dev/input/eventX for i in range(0, 1000*10000): print('E: {:.06f} 0002 0001 +001 # EV_REL / REL_Y' ' +1'.format(i / 1000.)) print('E: {:.06f} 0000 0000 0000 # ------------ ' 'SYN_REPORT (0) ---------- +1ms'.format(i / 1000.)) EOF
Event injection time is not 100% reliable, but it is consistent and the event frequency is approximately 1kHz, similar to a high polling rate mouse.
I've used Sekiro as a test case, with graphics settings set to lowest possible. The game runs at ~60fps without mouse input. The fps is not completely stable, and I believe it may be because the game is doing things at the same time. So I've measured the average fps of the first game scene after letting the injection run for a long time.
Only positive REL_Y events are used so that the game camera gets down quickly and stops moving, to smooth variation that could be caused by the draw calls.
With Wine 5.10, the fps drop to about ~40fps while input is injected, and PATCH #1 makes it go up to ~50fps.
The other two patches have smaller effect and not easily measurable, but I believe they are still helpful -- perf indicates a lot of cache misses around the list iterations -- and they are also preparing ground for the rawinput patches.
dlls/dinput/device.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/dlls/dinput/device.c b/dlls/dinput/device.c index 8c5aa318837..51ae349f34e 100644 --- a/dlls/dinput/device.c +++ b/dlls/dinput/device.c @@ -931,13 +931,19 @@ HRESULT _set_action_map(LPDIRECTINPUTDEVICE8W iface, LPDIACTIONFORMATW lpdiaf, L
void queue_event(LPDIRECTINPUTDEVICE8A iface, int inst_id, DWORD data, DWORD time, DWORD seq) { + static ULONGLONG notify_ms = 0; IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8A(iface); int next_pos, ofs = id_to_offset(&This->data_format, inst_id); + ULONGLONG time_ms = GetTickCount64();
/* Event is being set regardless of the queue state */ if (This->hEvent) SetEvent(This->hEvent);
- PostMessageW(GetDesktopWindow(), WM_WINE_NOTIFY_ACTIVITY, 0, 0); + if (time_ms - notify_ms > 1000) + { + PostMessageW(GetDesktopWindow(), WM_WINE_NOTIFY_ACTIVITY, 0, 0); + notify_ms = time_ms; + }
if (!This->queue_len || This->overflow || ofs < 0) return;