Open tkodw opened 8 years ago
I sympathize with the problem, but I'm not sure what we should do, given the historical APIs this code has to call.
In Chrome at least, it is unlikely that code would be accepted that requires increasing the timer frequency above the default 16ms due to concerns about battery.
Is the 8ms polling interval for the Xbox controllers documented somewhere? That might make a more compelling case.
I'm not really sure how we solve this with XInput, to be honest, since it doesn't provide a notification API. I don't think any browser is going to make getGamepads()
call directly into XInput, since it's likely to be executing in a sandboxed content process. For other sources of input we generally get notified on new data, so adding events to the spec would fix this use case.
Is the 8ms polling interval for the Xbox controllers documented somewhere? That might make a more compelling case.
I can't find any official documentation for it. I've observed an 8 ms refresh rate when testing both Xbox 360 and Xbox One controllers with the default USB drivers on Windows 10 and Ubuntu. Microsoft may change it by updating the driver in the future. The default polling rate for most USB input devices seems to be 8ms since it works with older USB hardware revisions.
I'm not really sure how we solve this with XInput, to be honest, since it doesn't provide a notification API.
I agree that there is no optimal solution with XInput. Applications using XInput must poll the API at an even higher rate than the driver poll rate to get accurate timing. The only power-friendly solution I can think of is to adaptively increase the XInput polling rate when the Gamepad API is frequently called.
In Chrome at least, it is unlikely that code would be accepted that requires increasing the timer frequency above the default 16ms due to concerns about battery.
Those timers shouldn't be firing at a high rate unless you have a gamepad connected and pressed a button on it. Seems like a low risk for mobile devices.
@luser Adding an events API would still not remove the latency when the browser's polling rate is the problem. It could alleviate the client's poll rate but we're still stuck with the browser's latency
@tkodw I don't know what we can add to the spec to discourage a browser from introducing latency.
Any suggestions?
The only power-friendly solution I can think of is to adaptively increase the XInput polling rate when the Gamepad API is frequently called.
Isn't the browser privy to the device's charge state? It'd make sense to simply enable a high poll if the device is charging, which would be a likely scenario where the high rate would be justified while having no impact on battery. Desktop devices would always poll at the fastest rate and devices with batteries would poll at the fastest rate when connected to power.
Updated link above for Firefox: https://searchfox.org/mozilla-central/source/dom/gamepad/windows/WindowsGamepad.cpp#52
const uint32_t kWindowsGamepadPollInterval = 50;
Chrome currently polls at 250 Hz (4ms polling interval):
In many current implementations of the Gamepad API calls to getGamepads does not make API calls to the OS to get updated gamepad state and instead return stale data.
Chrome has an arbitrarily chosen polling rate of 16 ms that applies to all platforms. https://cs.chromium.org/chromium/src/components/exo/gamepad.cc?sq=package:chromium&dr=C&rcl=1478013686&l=36
Firefox has an arbitrarily chosen polling rate of 50 ms (!!!) for windows. https://searchfox.org/mozilla-central/source/dom/gamepad/windows/WindowsGamepad.cpp#52
A very common OS + Gamepad configuration is probably Windows with an Xbox One or Xbox 360 controller. Both of those controllers have drivers that poll internally at 8 ms intervals by default.
In Chrome's case, since the internal polling rate is half of the gamepad polling rate, half of the updates from the controller will be lost.
With this configuration, buffering API calls adds additional latency of up to 24 ms on Chrome and up to 58 ms on Firefox.
You can test this yourself with a joy to key program. With a joy to key conversion program that polls for button presses at a 6 ms interval and converts them to keypresses, I've observed a keypress being detected by the browser 54 ms before the triggering button press in Firefox.
The additional latency is high enough that the Gamepad API typically provides a much worse experience for games compared to a keyboard or joy to key mapping program.
Can something be done to discourage providing very stale gamepad state when calling getGamepads?