-
-
Notifications
You must be signed in to change notification settings - Fork 10.7k
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
Horrendous keyboard lag in games that compounds with time pressed #1013
Comments
Hi, Thank you for your report. I just tested a random game (minetest) on a tablet, and indeed I can reproduce (a bit) the problem. However, I added some logs, which show all key and touch events are transmitted and injected immediately by scrcpy. After some delay (sometimes a few seconds), the game reacts to the events, but there are no new event injected at that time. So it seems the device/game takes time to consume the events. Not sure if there are possible workarounds on our side. |
Maybe related to the issue, but I get a similar problem randomly sometimes on normal use. scrcpy still inputs everything as expected in the end, backspaces and all, but stuff like parsing a long link can take almost a minute. For the record, I'm using the latest release with the --prefer-text modifier, but I remember this happening before the text fix. |
I just did another test: inject key events by pressing a key for several seconds in scrcpy, then touch with a finger on the physical device. The touch events consumption is also delayed. |
After looking into #109 i think the issues are related. With this small change xeropresence@3d52cd5 games instantly start working correctly, however this has a side-effect where now text apps would not work as expected where if you hold a key down it would start repeating. Does disabling key-repeating make the most sense? |
@xeropresence thank you 👍 By default, letters are sent as key events (instead of text events), unless However, this will cause the same issue for other keys like Space and Enter (keeping space pressed should inject several spaces). I will think about it. |
I had tried prefer-text before this and character would move but then stop, so i then started looking at what was going on. Do you know what the actual behavior is on android when holding down a key via a physical keyboard? If my understanding of the current system is correct, isn't the key repeating a hack since we are sending a keydown event, shouldn't that mean it's the responsibility of whatever app to repeat the key? On the server-side, can you check if the virtual keyboard is open, or even better if a text input is active? If you can then it would make sense to not process the duplicate keydown events when either of those cases was false. |
That is what I just tested, but it seems it does not (if you disable repeat on the client side, it does not repeat letters or space).
No (and it would be too hacky). Anyway, I think adding a command-line option |
My thought was if key repeating did not occur with a physical keyboard, then that would be a big part of if repeating would be enabled by default or not. I'm not a huge fan of it being only a flag since you may want to switch between repeating mode and non repeating mode and it would be silly to have to restart the program with different flags each time.
So, I was reading the android documentation, https://developer.android.com/reference/android/view/KeyEvent is scrcpy incrementing the repeat counter on events past the first one? It seems like for every event past the initial keydown, repeat should be incremented by one, where as the value for the keyup is always 0. |
On the device side, scrcpy always injects the events with
On the client-side, SDL only reports It would be interesting to know if passing the actual repeat value would solve the keyboard lag. |
That's what im wondering, can you store a counter, unordered_map<key,int>, increment every time sdl repeat is true, wipe on repeat is false, and send the counter with the key press event? |
(This is C++) 😄 A simple counter should be sufficient (not one per key, in practice only one key may be repeated at the same time). Do you want to work on that to see if it improves things? Here is a list of things to do:
|
I guess testing with one number would be a start, but if that does resolve the issue then it would be best to adhere to the spec and have the repeat value track each individual key. I guess an array would suffice since were working with only c. I'll give it a shot, doesn't sound too bad. |
A single |
I was thinking tracking the count inside input_manager.h, i'm reading thru the code now. I miss protobuff already. |
|
https://github.com/Genymobile/scrcpy/blob/master/app/src/input_manager.c#L414 |
Yes, for exemple, you could just add a field Add pass this count to |
Setting repeat properly does seem to alleviate the lag. Looking at the logging, I don't think i completely understand how sending multiple keys down at the same time is handled, figure it be best to report the findings before I delve any deeper. (It's this lack of understanding as to why im suggesting an array in this implementation)
this was quick and dirty to test and see if it even worked, so what do you think the best way to proceed would be? I did some testing, and setting repeat to one or zero based on sdl repeat did not resolve the issue, so it seems that the repeat counter incrementing is integral to the issue being resolved. Also, from the documentation https://developer.android.com/reference/android/view/KeyEvent#getRepeatCount()
Not sure how this should be handled. |
I don't think this matches the documentation 100% either, as the sdl fires multiple keydown events before repeat is set to true, so the counter is technically off by a few. |
Do you have a branch with your changes? |
I'll push it now. |
Thank you 👍 So I guess the issue is not related to (IIRC there is also the same problem with multitouch events on a touchscreen.)
If your device lags on successive events, I think it's ok to always pass |
Are events being dropped when the repeat counter > 0 and events come in with a higher count? An issue with this is that there are some keys you would want to repeat, ie backspace,delete, arrow keys,peroid(...), maybe space. I play games, but also send text messages, snapchat, etc where those repeats would be desirable. If tracking the repeat count resolves the issue, and better matches what the documentation expects, im in favor of that over adding a flag or a shortcut. |
Yes, but apparently, it does not.
Isn't there a lag when you press those keys repeated on your device? |
With my branch, there is a slightly delay in games when the key is released, but it is only slightly longer then when I was disabling repeats entirely, which is still much faster then using the v1.14 Outside of games, ie in snapchat I don't notice any lag. |
Oh, so it improves the situation? The difference is reproducible after several tests switching back and forth between v1.14 and this branch?
I can't reproduce that. |
Just to clarify my position: in any case, |
Sounds good. I'm currently trying to do some testing to quantify the results of the change using recording. |
Ok, so i modified my branch to limit a maximum of 40 repeat events to be generated. After 40 events were reached a fake keyup event was sent and all further events were ignored until an actual keyup event occurred. Repeat with a hardcoded 0 value, v1.14 Repeat incrementing Not sending repeat at all I also did some additional testing with stardew valley. Stardew valley is much less cpu, gpu intensive and displayed no noticeable difference between versions until I went and locked the cpu frequency to its smallest possible value. Once the cpu frequency was limited, there was no difference between the hardcoded 0 value and the incrementing version. Both versions exhibited a noticeable delay when stopping. The version where repeat keys were not sent at all exhibited no delay. In conclusion: Not sending repeat keys offers the best performance, but will inhibit scenarios where the user does want the keys to actually be repeated, ie (delete,backspace, arrow keys, etc) I think a flag is good, but a shortcut is better so that you can disable repeats, play games, then when you swap to sending messages you don't need to restart the program. |
OK, so first let's inject the correct
The issue is that a stateful toggle flag without visual feedback is confusing. That's why I haven't added one for Oh, also, please implement on |
I've rebased my branch onto dev. Sounds like a OSD could be useful for displaying information about state changes. |
(see #1484) But even with that, I'm not sure I want to consume a shortcut for such an advanced feature (which is only necessary on some devices, as a workaround to avoid sending too many events). |
What other changes would you like to see, just using a single unsigned int for tracking the count? |
Yes, and resetting it if and only if the current event has repeat set to Thank you 😉 |
So using v1.15 with |
It's as if scrcpy places "key pressed" events in a queue with every other event, which quickly clogs up and doesn't let other events through. E.g.: open
anygame that supports keyboard and press W for a brief moment and at the same time, try to swipe a screen. It goes through. Then, press W for ten seconds and then try to swipe the screen. Touch input goes through after a few seconds(!). And so on: input lag is proportional to the time spent pressing a keyboard button.EDIT: Only some games have this issue. From what I have on my phone, Minecraft and Survivalcraft exhibit this problem while Sonic 1 does not. Apologies if this issue is not scrcpy's fault
The text was updated successfully, but these errors were encountered: