sinisterchipmunk / jax

Framework for creating rich WebGL-enabled applications using JavaScript and Ruby
http://jaxgl.com
MIT License
96 stars 16 forks source link

Slow framerate on MacBook Pro with Firefox #20

Closed rubychan closed 13 years ago

rubychan commented 13 years ago

I'm not sure what the problem is, but I get VERY low frame rates here with my MBP. Actually, it's more like a slide show.

This is not a bug report, but if anybody else sees this problem, or has any idea about the cause, we could gather them here and maybe work towards a real problem report.

What I know:

I haven't tried other browsers. Safari crashed once, I'll try again.

sinisterchipmunk commented 13 years ago

Can you throw the source code for your demo up on Github somewhere? I'd like to examine it, fork it, make some tweaks, and see how they run for you. Alternatively I could take a few shots in the dark but I think we'll have more luck if we start from a known offending app.

How does the framerate look with no light sources?

You could also play with some settings ahead of me and see how your app reacts. In particular, I'm very curious to see the effects of the following (both on their own and in combination with one another):

Note that I only expect the lit property to actually result in visible differences; the other flags won't do anything visibly unless you add a shadow map to the material, BUT they do affect how Jax renders the scene, so they could have an effect on framerate even if they don't change the look of the scene.

That's all I can think of off-hand, but if none of the above have any effect, it may be time to take a closer look at the shader source code. I discovered some time back that the way in which a variable is passed into a function in GLSL can cause the program to completely crash on Windows 7 (see http://blog.jaxgl.com/2011/05/webgl-apps-crashing-on-windows-7/), so perhaps there's something equally mundane causing the implementation to barf at the driver level.

EDIT: I forgot to mention, but Firefox currently has known issues with JavaScript garbage collection of WebGL scenes. If you haven't done so recently, it may be worth shutting down and completely restarting Firefox. (I usually have to do this once or twice [but rarely more often than that] during the course of a full day of working on Jax.) The symptoms are similar to your report: very low framerates, and even sluggish systemwide response. Also, how does your app perform on Chrome?

rubychan commented 13 years ago

Sorry for taking so long to answer. I knew this would take longer to examine –_– WebGL is awesome, but debugging it is hell.

How does the framerate look with no light sources?

It's good! But as soon as I add any light source (regardless of the shadowcaster setting), it's slowing down. Setting "lit" to false didn't improve the framerate; neither did "casts_shadows".

Firefox currently has known issues with JavaScript garbage collection of WebGL scenes

Restarting didn't change anything. Chromium gives me this:

Fatal error encountered while drawing mesh:
Error: GL error in webgl-canvas: 1286 (GL_INVALID_FRAMEBUFFER_OPERATION)
Shaders: basic,lighting

Again, learningwebgl.com's examples run fine in both Chrome and Chromium.

Here's the code: https://github.com/rubychan/dungeon

sinisterchipmunk commented 13 years ago

Interesting result from Chromium! According to the GL/WebGL specs, INVALID_FRAMEBUFFER_OPERATION should be raised if the framebuffer is "incomplete" -- but if that were the case I'd think it would be a logical error and I'd be able to reproduce it. However, this does provide some insight. The problem could be linked to the internal framebuffers Jax manages for the shadowmap; maybe some part of the technique is not supported by your drivers (though it should have raised a more coherent error if that were the case, unless it's an outright driver bug). It gives me a place to start looking, at least. Additionally, this coincides well with the addition of a light source, which would be generating a shadowmap even if the object in question is not a shadowcaster (because what if other objects are?). The shadowmap would be empty, but it would still get generated.

Probably the most similar example at learningwebgl is this: http://learningwebgl.com/lessons/lesson16/index.html -- how does that one run for you?

If you fancy looking directly at the offending code, it'll likely be in either https://github.com/sinisterchipmunk/jax/blob/v1.0.0/src/jax/webgl/scene/light_source.js or https://github.com/sinisterchipmunk/jax/blob/v1.0.0/src/jax/webgl/core/framebuffer.js. Don't feel pressured to do so; I'm mentioning it just to give a head start to anyone who wants to. In the meantime, I'll see if I can't secure some similar hardware. (That could take awhile: one of the disadvantages of free software is lack of funding ;) )

Even if I can't find the root cause of this issue, I'll look into making an update to the shadow code so that the framebuffers are only generated if at least one object actually has shadow mapping enabled (as this is must be done from the Material level); I will also see about automatically disabling shadowmap generation if it encounters a rendering error, rather than throwing a fatal app-killing error. I can try to work the latter into a 1.0.1 release, but the former will have to wait for 1.1.0 (which, thankfully, is almost ready).

rubychan commented 13 years ago

Probably the most similar example at learningwebgl is this: http://learningwebgl.com/lessons/lesson16/index.html -- how does that one run for you?

Runs fine.

My gut feeling says your driver theory might be right. OS X is a bit special when it comes to Open GL support: http://developer.apple.com/graphicsimaging/opengl/capabilities/ (my system should be the last column there.)

Thanks for your hard work. I can test on my system any time, if that helps.

sinisterchipmunk commented 13 years ago

OS X is a bit special when it comes to Open GL support:

This is a very helpful resource! (Bookmarked.) Unfortunately, a quick scan through doesn't show that I might be exceeding the advertised capabilities of the card. I'll check it again in more detail later, though. Maybe I missed something.

I can test on my system any time, if that helps.

It absolutely does help :) but, of course, I have to have something for you to test, first. For now I think I'll just proceed with the workarounds in that last paragraph (namely, auto-disable shadow generation on error and be more picky about when to enable it in the first place), as those approaches will help make the Jax subsystem smarter overall. I'll update you when I have a test candidate.

sinisterchipmunk commented 13 years ago

I've just pushed v1.0.1.rc1 to rubygems; you can install it with gem install jax -v=1.0.1.rc1. Don't forget to run rake jax:update in your project directory, to update the javascripts. I'm eager to see how it works with Chromium on your box.

I'm unfortunately not anticipating anything spectacular from Firefox, since it wasn't throwing any errors to begin with. The new code only catches and adapts to true exceptions (as opposed to just generally low framerates), so this is really a Chromium-specific patch.

rubychan commented 13 years ago

Yay! Will try this in the next days.

rubychan commented 13 years ago

Sorry, Chromium still fails with the same error.

sinisterchipmunk commented 13 years ago

Darn! Is there any backtrace or line number information associated with the error?

Since it's raising a proper error in Chromium, and the error isn't being handled by my catch block (which pretty much encompasses any possible shadow-related errors), I can only assume at this point that it's a problem with the render process itself and nothing to do with the shadow mapping after all.

If there's no stack trace available, I might have to chalk this one up to driver issues and press forward with releasing v1.1.0. The new version changes some of the internal error handling, so it's possible (though unlikely) that you'll get slightly more information from the new release.

rubychan commented 13 years ago

Does this screenshot help? http://rubychan.de/share/jax-chromium-macbook-pro.png

sinisterchipmunk commented 13 years ago

Does this screenshot help?

Immensely! I'm stepping through the backtrace now, though the column offsets seem to be inaccurate (Chromium's fault, not yours) and that's making it more difficult. I'll have to reconsider whether minifying Jax prior to release is a good idea; maybe in v1.1 I'll switch it to only use the minified version in packaged apps, so that issues like yours are easier to track down.

In any case, I'll keep you posted.

sinisterchipmunk commented 13 years ago

Great news: I believe I've been able to reproduce the issue on a similar (albeit not identical) machine. Indeed, the learningwebgl.com example run fine so I'm confident this can be addressed. Soon as I find some extra time (and a chance to borrow the machine in question), I'm hopeful I can hack out a solution and we can resolve this once and for all.

sinisterchipmunk commented 13 years ago

On this machine, at least, I've narrowed down the problem. It's a driver bug, but one we can thankfully work around: the usage of the 'return' keyword in GLSL, believe it or not! By redesigning the offending functions so that they don't under any circumstance return prematurely, I believe we can make it work. (Hopefully the problem I'm addressing is truly the same as your own!) Expect a 1.0.1.rc2 release shortly once I've had a chance to make the appropriate changes.

rubychan commented 13 years ago

Wow…such bad drivers can effectively kill consumer trust in WebGL. I hope we get past this stage soon. I want to have great WebGL games and tools in my browser, without having to worry about incompatibilities and driver bugs :/

That's why we need great frameworks :)

sinisterchipmunk commented 13 years ago

Completely agree, but let's not confuse the culprits. As WebGL is basically just a proxy from JS into OpenGL ES, I doubt it is truly to blame. This issue arises in shader source which is compiled by the underlying video hardware -- at a much lower level than WebGL. Therefore, I blame the hardware manufacturers for releasing substandard drivers. They could get away with it in the past because developers on a deadline would just work around the issues into perpetuity instead of making sure the real problems get addressed; I think WebGL will expose a lot of inconsistencies in the short term, but I am hopeful that our community will help keep the vendors honest -- eventually.

sinisterchipmunk commented 13 years ago

OK, just pushed v1.0.1.rc2 to rubygems. After installing, be sure to run rake jax:update in your app to bring the JavaScripts up to date.

On the machine that I was using to debug your issue, (a MacBook [not pro] Intel GMA x3100), I'm now getting 70fps in Firefox on your previously failing teapot git repo. Chrome still sucks at 5-10fps, BUT these Chrome performance issues are unrelated. They have been resolved in Jax v1.1.0 (just tested using your app) and I'm seeing consistently high framerates using that version. I've not tested on Chromium.

rubychan commented 13 years ago

Runs smoothly in Chrome, and very fast in Firefox!

Chrome starts my fan (seems CPU bound); that seems weird. May be their fault, though.

Awesome, I can really start to play with Jax on my favorite browser now :D

sinisterchipmunk commented 13 years ago

Great news and glad to hear it! This was a tricky one! I'll move the 1.0.1 release candidate to release shortly.