Closed Bug 782689 Opened 12 years ago Closed 11 years ago

PlayCanvas 3rd person shooter is very slow

Categories

(Core :: Graphics: CanvasWebGL, defect)

x86
macOS
defect
Not set
normal

Tracking

()

RESOLVED WORKSFORME

People

(Reporter: ehsan.akhgari, Assigned: vlad)

References

(Blocks 1 open bug)

Details

(Whiteboard: [games:p?])

I also did a quick shark profile.  Some quick aggregate times:
 26% - jit code self time
  5% - GC
 10% - js::mjit::stubs::GetElem (obj[prop] slowest path)
 26% - under WebGLRenderingContextBinding::genericMethod
 13% - under WebGLRenderingContextBinding::drawElements

(That leaves 20% in smaller pieces.)
The profile shows a lot of time (2/3) spent in drawElements, itself being entirely spent in the corresponding OpenGL function, glDrawElements, meaning that it's not WebGL validation overhead and this part is not something we can do anything about. If my theory is correct, this part will run at the exact same speed in Chrome.

The remaining part (up to 1/3) is largely about the JS engine and JItted code. If it's currently very slow, even if we eliminated that 1/3 time, it would still be very slow.

So I don't see much to do here.
The demo runs pretty smoothly on my 10.6 MBP and shows significantly less time under drawElements; that does seem to indicate that there is something twitchy going on w/ the driver.
Regarding drawElements, would it always run at the same speed in all browsers? And the same as native code? I seem to remember a long time ago I was told that we do shader rewriting (to add bounds checks) which adds overhead?
We don't do shader rewriting to add bounds checks. Instead, we check the index buffer manually before doing the glDrawElements call. Assuming the profiler is correct, any such overhead would show under drawElements but not under glDrawElements.
On my W520 running linux 64bit + NVIDIA, the game is very fast and a profile doesn't show significant overhead from the WebGL impl.
Cool, sounds like the slowness might be just a GL driver issue then.

Side issue, does mouselock work in fullscreen for anyone in this demo? (It doesn't for me on nightly, linux.)
(In reply to comment #7)
> Cool, sounds like the slowness might be just a GL driver issue then.

Hmm, on my machine we're spending about 75% of the time in the WebGL DrawElements function...

> Side issue, does mouselock work in fullscreen for anyone in this demo? (It
> doesn't for me on nightly, linux.)

It works fine for me.
The fun thing on Ehsan's machine is that while Chrome is much faster than Firefox, both are spending most of their time in glDrawElements.

Which means that Chrome's glDrawElements calls are less expensive than ours.

This could be explained if e.g. the application was enabling more expensive rendering when run in Firefox compared to Chrome. If this is important, the way to tell would be to run this in a GL tracer/debugger (like gdebugger or apitrace).
(In reply to Alon Zakai (:azakai) from comment #7)

> Side issue, does mouselock work in fullscreen for anyone in this demo? (It
> doesn't for me on nightly, linux.)

Doesn't work for me either in linux. Seems like a linux-only bug? File a bug?
(In reply to Ehsan Akhgari [:ehsan] from comment #8)
> (In reply to comment #7)
> > Cool, sounds like the slowness might be just a GL driver issue then.
> 
> Hmm, on my machine we're spending about 75% of the time in the WebGL
> DrawElements function...

Interesting. I'm trying to think what could be reasonably specific to PlayCanvas that would cause this. The only thing I can think of is that the engine attempts to reduce the number of times the index buffer has to be bound. Each 3D object has a single index buffer and triangles are grouped by material, where each group of triangles is a subsection of the index buffer. When drawElements is called, a base index is provided. I do recall reading somewhere that this approach might cause the entire index buffer to be range checked for every drawElements call, but when I originally test on a few HW configurations, I didn't notice a slowdown - it's seemed a win on balance.  I can't think of anything else that might cause the problem though. Obvoiusly, the game runs the same engine code as any other PlayCanvas demo or sample.  Perhaps comparing the profile to another simpler app might give some additional insight.  Obviously, I'm reason keen to get any help from you guys to identify exactly what's going on.  :)
> I do recall reading somewhere that this approach might cause the entire index buffer to be
> range checked for every drawElements call

Indeed. Bug 732660 will fix that.

However, the profiles that we took showed that nearly 100% of the time under WebGL.drawElements was under the real OpenGL glDrawElements, leaving little room for time being spent in the WebGL drawElements validation. So, I don't expect that this issue is what is causing the slowness here.

The profiles we got, showing time spent in the OpenGL glDrawElements function, and thew speed difference with Chrome, are hard to explain; they mean that glDrawElements calls made by Firefox are more expensive than the ones made by Chrome; the only explanation that I can think of would be some configuration or shader difference e.g. if you turned on some feature, making shaders more expensive, in one browser and not the other. That could be determined using a GL debugging tool such as APItrace or gdebugger.
Assignee: nobody → vladimir
Whiteboard: [games:p2]
Is this still an issue?
Whiteboard: [games:p2] → [games:p?]
I can't load the demo in Nightly. Works fine in Chrome though.
(In reply to Alon Zakai (:azakai) from comment #15)
> I can't load the demo in Nightly. Works fine in Chrome though.

Sorry, there was an old engine bug which broke in the Web Audio API. I've redeployed with the latest engine. Should load fine in Nightly now.
(In reply to comment #16)
> (In reply to Alon Zakai (:azakai) from comment #15)
> > I can't load the demo in Nightly. Works fine in Chrome though.
> 
> Sorry, there was an old engine bug which broke in the Web Audio API. I've
> redeployed with the latest engine. Should load fine in Nightly now.

If that was a Web Audio bug in Gecko that you hit, please let me know, I'd be interested in fixing it.  Thanks!
It wasn't a Gecko bug. We hadn't updated to use the latest Web Audio API spec, which we now have.
Still doesn't work for me. I get

[09:59:01.422] ReferenceError: webkitAudioContext is not defined @ http://code.playcanvas.com/playcanvas-0.101.1.min.js:368

(on nightly)
Can you clear your cache? The currently deployed version uses http://code.playcanvas.com/playcanvas-0.107.4.min.js
Thanks, works now.

This looks quite fast to me on Nightly. I think we can close this, but if anyone else still sees bad performance please reopen.
Status: NEW → RESOLVED
Closed: 11 years ago
Resolution: --- → WORKSFORME
You need to log in before you can comment on or make changes to this bug.