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

SDL_CaptureMouse performance regression #4789

Closed
graphitemaster opened this issue Sep 27, 2021 · 3 comments
Closed

SDL_CaptureMouse performance regression #4789

graphitemaster opened this issue Sep 27, 2021 · 3 comments
Assignees
Labels
abandoned Bug has been abandoned for various reasons waiting Waiting on user response

Comments

@graphitemaster
Copy link

graphitemaster commented Sep 27, 2021

On Windows, SDL_CaptureMouse is emulated in terms of relative mouse motion under raw input [1] since the use of Win32's SetCapture is avoided because it only tracks while the left mouse button is held [2]. This is actually the use case most people want, but I suppose some people must've reported bugs and this choice was made instead.

There's two problems with this:

  1. This emulation is actually far slower than SetCapture. Enough that mouse motion events can either double-fire or drop randomly while in capturing mode. You can test this yourself by printing mouse motion values while capture is enabled. This is unfortunate.
  2. Since capture is emulated in terms of relative mouse mode. It must register itself for RawInput if not already. This may be fine normally, if only done once (the registration is quite slow), however when capturing is disabled, SDL unregisters RawInput for the mouse. The documentation encourages to only use mouse capture in "short bursts" [3], implying that one captures and uncaptures only when one needs to, under this recommendation the mouse is consistently registered and unregistered for RawInput leading to a lot of overhead. When done during mouse interaction (common), you can drop events, double-fire, and stall input leading to stuttering of mouse input.

It's actually somewhat difficult now to get the performant behavior of SetCapture where you have mouse motion events relative to the window while still having a hardware cursor. There is no equivalent behavior in SDL for it. The use of SDL_SetRelativeMouseMode globally would hide the cursor (maybe it can be reenabled?) and only provide relative motion events (no window position values). Instead the best work around I've found has been to ignore events completely and emulate it like this:

int mouse_pos[2];
int window_pos[2];
SDL_GetWindowPosition(window, &window_pos[0], &window_pos[1]);
SDL_GetGlobalMouseState(&mouse_pos[0], &mouse_pos[1]);
int pos[2];
pos[0] = mouse_pos[0] - window_pos[0];
pos[1] = mouse_pos[1] - window_pos[1];

Not only is this far faster than the current SDL_MouseCapture API in my measurements, it's more responsive on Windows too. Despite what the documentation about SDL_GetGlobalMousePosition says [4]. It requires no raw input shenanigans and one can support the behavior of tracking while only left clicking (like SetCapture) and the current global tracking of SDL_MouseCapture without any of the performance loss currently experienced.

[1] https://github.com/libsdl-org/SDL/blob/main/src/video/windows/SDL_windowsmouse.c#L287
[2] https://github.com/libsdl-org/SDL/blob/main/src/video/windows/SDL_windowsmouse.c#L283-L286
[3] https://github.com/libsdl-org/sdlwiki/blob/main/SDL_CaptureMouse.mediawiki#remarks
[4] https://github.com/libsdl-org/sdlwiki/blob/main/SDL_GetGlobalMouseState.mediawiki#remarks

@DomGries
Copy link
Contributor

Might be fixed by 5e89b3c

@slouken slouken self-assigned this Nov 7, 2021
@slouken slouken added this to the 2.0.18 milestone Nov 7, 2021
@slouken slouken added the waiting Waiting on user response label Nov 7, 2021
@slouken
Copy link
Collaborator

slouken commented Nov 7, 2021

Can you check and see if this is still a problem in the latest snapshot?
http://www.libsdl.org/tmp/SDL-2.0.zip

@slouken slouken removed this from the 2.0.18 milestone Nov 26, 2021
@slouken slouken added the abandoned Bug has been abandoned for various reasons label Nov 7, 2023
@slouken
Copy link
Collaborator

slouken commented Nov 7, 2023

SDL 2.0 is now in maintenance mode, and all inactive issues are being closed. If this issue is impacting you, please feel free to reopen it with additional information.

@slouken slouken closed this as not planned Won't fix, can't repro, duplicate, stale Nov 7, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
abandoned Bug has been abandoned for various reasons waiting Waiting on user response
Projects
None yet
Development

No branches or pull requests

3 participants