Skip to content
This repository has been archived by the owner on Jul 22, 2024. It is now read-only.

Extremely poor performance in immersive mode in Sketchfab.com #374

Closed
avrignaud opened this issue Aug 20, 2018 · 14 comments
Closed

Extremely poor performance in immersive mode in Sketchfab.com #374

avrignaud opened this issue Aug 20, 2018 · 14 comments
Labels
ARCHIVED CLOSED at time of archiving blocked bug This issue is a software or functional defect compatibility Web content compatibility issues P3 Backlog perf Performance WebVR/XR
Milestone

Comments

@avrignaud
Copy link

avrignaud commented Aug 20, 2018

Hardware

Oculus Go

Steps to Reproduce

  1. Visit sketchfab.com
  2. Attempt to interact with sample 3D mech model

Current Behavior

Initially site says to touch and drag, but pointing laser pointer and clicking does not cause model to move.

Entering immersive (using same mech model) is very slow, and several graphic glitches occur on way. Once loaded, performance is terrible - 2-5 FPS? Then locks up.

Backing out of model brings you back to home page, at which point user can click/drag model on page, but again, with extremely poor performance.

Expected Behavior

Should be able to visit website, point and click to interact with model, enter immersive, navigate in immersive at full performance, and return seamlessly.

Possible Solution

Hoping we have ideas. :)

@avrignaud avrignaud added bug This issue is a software or functional defect P0 Hotfix or blocker during release preparation WebVR/XR labels Aug 20, 2018
@avrignaud
Copy link
Author

For reference, sketchfab works very well in the just released Samsung Internet browser for the Oculus Go. Both in terms of immersive mode and framerate.

@MortimerGoro
Copy link
Contributor

MortimerGoro commented Aug 21, 2018

Did some research on Sketchfab issues:

  • One of the problems of the long startup delay/glitches is that Gecko WebVR implementation is running unneeded WebGL RAF calls than are discarded later. I'm going to try to add a patch to avoid this, instead of the exponentially increased max RAF timeouts (which are cleared after a successfull frame)
  • I reduced our Oculus WebVR size to the recommended one by the SDK (1024x1024 for each eye). It helps with the performance. Anyway even with that size our WebVR quality (e.g. mech drone model) is much better that the one I see with the Samsung Browser. They also report 1024x1024 size, but the quality is very poor, looks very blurry in the Mech drone model. I think they are using less quality than reported, or maybe reducing the quality if they detect that the framerate is not good enough?
  • They use "Samsung Gear VR" as the immersive headset. I wonder if those things could affect, some webpages sniffing those names to disable features, set quality etc. It already happened with https://virtualart.chromeexperiments.com/vr/ (edited)

@nancyhang nancyhang added this to the V1.0 milestone Aug 21, 2018
@MortimerGoro
Copy link
Contributor

Update:

  • We landed https://phabricator.services.mozilla.com/D3152 to fix the WebVR startup delays and glitches
  • We landed the size recommended by the SDK (1024x1024 for each eye)
  • We fixed the quality differences between FxR and the other browsers by setting the correct window sizes and devicePixelRatio

Important things that we need to land

  • Enable multiprocess. This helps a lot with the loading time performance, specially on the Go. WebVR multiprocess support is ready but enabling it it's blocked by a Gecko Video issue that Randal is looking at.
  • @daoshengmu is researching WebGL stale frames Research stale frames on WebVR #433

@avrignaud In summary, I think the ship blocker is enabling multiprocess preference. Our WebGL is also slower but that may be difficult to be fixed

@MortimerGoro
Copy link
Contributor

Blocked by #451

@daoshengmu
Copy link
Contributor

@MortimerGoro I have a few progress about the performance investigation.

First of all, we take too much waiting time for posting VR tasks in the immersive mode. Ideally, for Oculus Go, it expects 16 ms per frame for 60 FPS. That means for one rAF to the next rAF only has 16 ms. But our delayed thread makes it postpone to 50ms [1][2]. After changing them to 0, in the immersive mode, we can normally only need 16 ms for rAF for most WebVR examples.

I can show you some stats for aframe/sky [3] and playcanvas[4] when calling VRManagerChild::RunFrameRequestCallbacks() in Gecko.

  1. aframe/sky
  • Non immersive
    60 fps stale frames 0
    VR profiling 'raf time' delta time: 16.790127
    no loop time for callback, it seems a-frame doesn't call it when away from the immersive.

  • Immersive
    60 fps stale frames 8
    VR profiling 'raf time' delta time: 16.712757
    VR profiling 'loop time' delta time: 7.943081

  1. playcanvas
  • Non immersive
    60 fps stale frames 0
    VR profiling 'raf time' delta time: 16.170517
    VR profiling 'loop time' delta time: 10.691268

  • Immersive
    45 fps stale frames 50
    VR profiling 'raf time' delta time: 23.471530
    VR profiling 'loop time' delta time: 17.729856

According to the PlayCanvas example, we can understand the VSync time still work properly even the FPS is not good enough. In the immersive mode, the loop time increase to 17 ms from 10 ms, that also make rAF increase 7 ms for waiting the finish of rAF loop. So, we can realize PlayCanvas is a CPU bound from WebGL, and we need to investigate WebGL functions' bottleneck. But, for aframe/sky, the only strange thing is its stale frames, we can solve it by #453 but no idea why this kind of simple demo would happen stale frames.

[1]

const float kConditionTimeout = 0.1f;

[2] https://dxr.mozilla.org/mozilla-central/rev/c2e3be6a1dd352b969a45f0b85e87674e24ad284/gfx/vr/gfxVRExternal.cpp#144
[3] https://aframe.io/examples/showcase/sky/
[4] https://developer.playcanvas.com/en/tutorials/webvr-lab/

@larsbergstrom larsbergstrom changed the title Extremely poor performance and crashes in immersive mode in Sketchfab.com Extremely poor performance in immersive mode in Sketchfab.com Sep 8, 2018
@larsbergstrom larsbergstrom modified the milestones: V1.0, v1.1 Sep 8, 2018
@larsbergstrom larsbergstrom removed the P0 Hotfix or blocker during release preparation label Sep 8, 2018
@larsbergstrom
Copy link

Moving to V1.1, as blocked on a key bug we can't fix for V1.

@MortimerGoro
Copy link
Contributor

First of all, we take too much waiting time for posting VR tasks in the immersive mode. Ideally, for Oculus Go, it expects 16 ms per frame for 60 FPS. That means for one rAF to the next rAF only has 16 ms. But our delayed thread makes it postpone to 50ms [1][2]. After changing them to 0, in the immersive mode, we can normally only need 16 ms for rAF for most WebVR examples.

[1] Should not be changed to 0, because it will skip most of the frame submits or use the previous frame.

[2] as I understand that's used to trigger the watchdog, which only triggers a new frame in special situations. A new frame should be triggered immediately (with no timers) just after finishing the previous one, isn't Gecko WebVR doing that?

@daoshengmu
Copy link
Contributor

After removing Wait wait(m.data.browserMutex, m.data.browserCond); at ExternalVR::WaitFrameResult, we would have no stale frames, and the FPS would be steady to 60. I think the problem is from pthread mutex between GV and FxR. I am confused with the value of kConditionTimeout = 0.1f, does it mean 100 ms? That would be huge for the waiting time.

Besides, the Playcanvas immersive demo was doing stereo render in the content side, so they have more draw calls, so it makes sense to take more time in their render loop.

The purpose of watchdog in the desktop is in order to force calling rAF again if it has been stuck 50ms after the last update of VRDisplay.rAF. But the VR thread.PostDelayedTask() in Android seems to make it only calls VRDisplay.rAF every 50ms instead of watchdog behavior. [1][2]

https://dxr.mozilla.org/mozilla-central/source/gfx/vr/VRDisplayHost.cpp#274
https://dxr.mozilla.org/mozilla-central/source/gfx/vr/VRDisplayHost.cpp#217

@MortimerGoro
Copy link
Contributor

MortimerGoro commented Sep 13, 2018

After removing Wait wait(m.data.browserMutex, m.data.browserCond); at ExternalVR::WaitFrameResult, we would have no stale frames, and the FPS would be steady to 60. I think the problem is from pthread mutex between GV and FxR. I am confused with the value of kConditionTimeout = 0.1f, does it mean 100 ms? That would be huge for the waiting time.

Removing the wait can cause discarded frames or using old WebGL frames. Stats are going to show 60 FPS but the latency is going to be high or inconsistent.

kConditionTimeout is the maximum wait time, it's set to 100ms (10FPS) but ideally it should exit before 16ms when Gecko notifies that the WebGL frame for the latest pose is ready.

The purpose of watchdog in the desktop is in order to force calling rAF again if it has been stuck 50ms after the last update of VRDisplay.rAF. But the VR thread.PostDelayedTask() in Android seems to make it only calls VRDisplay.rAF every 50ms instead of watchdog behavior. [1][2]

That 50ms should be used for the watchdog checks only. A new frame is submitted immediately after the last frame was submitted succesfully. It's a bit confusing but I found that the loop call is done here: https://dxr.mozilla.org/mozilla-central/source/gfx/vr/VRDisplayHost.cpp#317.

@cvan
Copy link
Contributor

cvan commented Sep 19, 2018

There was a recent regression here - possibly on Sketchfab's side because of mobile sniffing vs. feature detection. Not sure if from FxR's last UA change. But entering VR from a Sketchfab model page is currently not possible.

@larsbergstrom
Copy link

@cvan Are things better with the latest builds and the updates from Sketchfab, especially around the UA sniffing?

@cvan
Copy link
Contributor

cvan commented Nov 2, 2018

@lbergstrom: the perf is not in good shape still. I can send them perf traces, but I am not sure they will be optimising for the Go hardware.

the otherwise two WebCompat/ContentFeed issues I found and asked about having fixed are these:

  1. Hook up the Go controller's trigger to teleport (whilst keeping the existing button controls).
  2. Hide the Vive controller mesh when using a non-Vive controller.

I can friendly ping them, as it has been a while.

@cvan cvan removed this from the v1.1 milestone Nov 21, 2018
@cvan cvan added the backlog label Nov 21, 2018
@cvan
Copy link
Contributor

cvan commented Nov 21, 2018

Thanks for all the investigation.

No noticeable perf improvements, and we still have the controller issues per my comment above.

This is unfortunate, but it looks like we are blocked on Sketchfab. And Multiprocess (issue #451) will help. We can address this after v1.1.

@caseyyee caseyyee added the compatibility Web content compatibility issues label Nov 26, 2018
@philip-lamb philip-lamb added this to the v1.2 milestone Mar 7, 2019
@philip-lamb philip-lamb added P3 Backlog perf Performance and removed backlog labels Mar 7, 2019
@philip-lamb philip-lamb modified the milestones: v1.2, v1.3 May 16, 2019
@cvan
Copy link
Contributor

cvan commented May 21, 2019

BTW: The performance of Sketchfab models on the Oculus Go is still significantly worse than that of Oculus Browser.

@jvonitter jvonitter modified the milestones: v1.3, v1.4, v1.x Jul 3, 2019
@cknowles-admin cknowles-admin added the ARCHIVED CLOSED at time of archiving label Jul 22, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
ARCHIVED CLOSED at time of archiving blocked bug This issue is a software or functional defect compatibility Web content compatibility issues P3 Backlog perf Performance WebVR/XR
Projects
None yet
Development

No branches or pull requests

10 participants