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

throttle updateControllerList while keeping getGamepads call #3112

Merged
merged 1 commit into from
Nov 7, 2017

Conversation

ngokevin
Copy link
Member

@ngokevin ngokevin commented Oct 3, 2017

Description:

Changes proposed:

Copy link
Member

@dmarcos dmarcos left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe we had this in the past and we removed it because we needed to request a new gamepad object in chrome in order to get an updated pose

@machenmusik
Copy link
Contributor

Make sure you test chrome rift/vive/daydream here, as @dmarcos notes we have encountered quirks or issues. (Actually I am not sure whether we characterized Edge once we realized that we broke Chrome)

@ngokevin
Copy link
Member Author

ngokevin commented Oct 3, 2017

If you check the code, see that we still call getGamepads. The only thing I'm throttling is rebuilding the controller list. It's different from what we did before.

@ngokevin ngokevin force-pushed the throttlecontrollerlist branch 3 times, most recently from 11567b3 to e86bca3 Compare October 3, 2017 16:08
@machenmusik
Copy link
Contributor

Yeah, we started down this avenue of approach but backed off at the time with #2984. One suggestion is to make the interval a system configurable parameter, as for some apps 500ms may be slower than desired (as this impacts all tracked controls, and we no longer have the event listeners which would fire immediately when available)

@machenmusik
Copy link
Contributor

I suspect that if we changed the throttle once we have seen 1 (for 3DOF) or 2 (for 6DOF) tracked controls, we could reduce the interval to almost never.

@ngokevin
Copy link
Member Author

ngokevin commented Oct 3, 2017

#2984 was to fix the Chrome issue with navigator.getGamepads not getting called, this avenue was not approached. I can't imagine a couple hundred milliseconds affecting applications in controller detection, it will be hardly noticeable.

this.updateControllerList();
var gamepads;
// Call getGamepads for Chrome.
gamepads = navigator.getGamepads && navigator.getGamepads();
Copy link
Contributor

@cvan cvan Oct 5, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how does this help if navigator.getGamepads() is still getting called on every tick?

why not keep this in updateControllerList (which is now throttled)?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some backstory, that @ngokevin @dmarcos and I ran into last time around - if you don't call navigator.getGamepads(), then if you are using Chromium/Chrome (which includes derivatives like Oculus Browser) you won't get gamepad updates until the next one. Firefox doesn't care, but on several prominent platforms (GearVR, Daydream) the only native WebVR browser options are Chromium/Chrome-based. As I mentioned, I don't recall if we characterized Edge in this regard.

Copy link
Contributor

@cvan cvan Oct 5, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks - yep, I know that about Chrome. that inconsistency in browser implementations is what this spec issue is for: w3c/gamepad#8

what I'm suggesting to do is move the navigator.getGamepads() call to be inside the throttled method, throttledUpdateControllerList. unless I'm missing something, that would still handle the Chrome case, since it's called on every tick.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought the point of the throttle was to NOT call the throttled method every tick, but rather to enforce a minimum interval by ignoring calls that happen too soon since the last one.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that’s what I’m suggesting. the code as is here checks for gamepads on every tick. can’t tell if I’m misunderstanding or not heh.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This has to be tested across all browsers before being considered for merge. The reason navigator.getGamepads is called on every tick is because is needed in order to get updated poses for the controllers in some browser. The gamepad handle pose won’t update automatically and you see judder in the controller motion. Calling navigator.getGamepads might not be enough and retriving a new gamepad object might be necessary. That’s has to be determined after testing

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dmarcos: awesome, thanks for the explanation. the pose information in each Gamepad object is the reason.

in Chrome, navigator.getGamepads() is always an array of length 4. and just get an index from that array, and the Gamepad object is live. can’t use reference variables, obviously, as you know.

I think a possible improvement here would be to check for conencted/disconnected gamepads every 500 milliseconds, and have tick have separate checks for each individual Gamepad object.

that’s admittedly a lot of work for perhaps little benefit. any flare charts available to look at for some examples?

@@ -10,7 +11,8 @@ module.exports.System = registerSystem('tracked-controls', {

this.controllers = [];

this.updateControllerList();
this.updateControllerList(navigator.getGamepads && navigator.getGamepads());
this.throttledUpdateControllerList = utils.throttle(this.updateControllerList, 500, this);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it might be nice to allow this throttle duration to be configured by a component value (with a default value of 500 milliseconds)

@ngokevin
Copy link
Member Author

ngokevin commented Oct 5, 2017

Works on FF. Need to test on Chrome/Daydream/GearVR.

@machenmusik
Copy link
Contributor

(We should test recent support for Edge as well)

@vincentfretin
Copy link
Contributor

It seems to be working fine on GearVR with Oculus browser. I don't see any difference.

@dmarcos
Copy link
Member

dmarcos commented Oct 6, 2017

@vincentfretin thanks for looking into it! Do you see any performance difference in the controller motion with and without the patch?

@vincentfretin
Copy link
Contributor

With or without the patch, the controller motion is smooth. I don't see any difference.

@machenmusik
Copy link
Contributor

Nice - for completeness I think we need to confirm
chromium/Rift+Touch and chrome/daydream - the former being what stopped us before IIRC.

@ngokevin
Copy link
Member Author

Worked fine on Chromium/Rift. Is that enough? Anyone want to try to Daydream?

@cvan
Copy link
Contributor

cvan commented Oct 26, 2017

I tried this on Gear VR: Oculus Browser and Samsung Internet on a Samsung Galaxy S8. compared to master, the controller doesn't seem worse. I can't perceive perf improvements, if there are any.

@ngokevin: which examples are you testing with? Laser Controls, Tracked Controls?

@ngokevin
Copy link
Member Author

Thanks. Either, anything with hands. Perf improvements are memory-leak/garbage related:

screen shot 2017-10-26 at 3 56 41 pm

Copy link
Contributor

@cvan cvan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good

@ngokevin
Copy link
Member Author

ngokevin commented Nov 3, 2017

@dmarcos r?

@machenmusik
Copy link
Contributor

I thought we merged this already, apparently I was wrong. Is anything blocking, or just haven't gotten to it yet?

@dmarcos
Copy link
Member

dmarcos commented Nov 7, 2017

@machemusik Have you had the chance to test it a bit? Do you remember the platforms where we had problems with low framerate controllers updates?

@ngokevin
Copy link
Member Author

ngokevin commented Nov 7, 2017

@dmarcos This was tested on Chromium/Rift which was one of the platforms. The Gamepad call is called every tick, it's just A-Frame's controller list rebuild is throttled.

@dmarcos dmarcos merged commit 7cc2cef into aframevr:master Nov 7, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants