Erik's blog

http://twitter.com/#!/erikjmoller

All hail iOS 5

, , ,

I'm not going to bash Apple so don't worry if you're a fanboi, you can read on...I have at least 7 Apple devices at home that are frequently used.

iOS 5 is here, there is much rejoicing in the streets! While I followed flowery prose comments on twitter about how blazingly fast everyones HTML5 got with this update I was silently muttering words a family father will have to just mutter instead of saying out loud. My neat little iOS game Emberwind had gone from running perfectly smooth on any prior iOS version to a stuttering sluggish mess on iOS 5.
The first choice for a programmer is of course always to blame the OS or gfx-driver or keyboard or whatever seems remotely plausible before scrutinizing your own code... to be perfectly honest it did seem reasonable to do so this time... I hadn't changed a thing and it went from 30 FPS to 10-ish FPS.
I think I muttered more than once "POS iOS 5.. don't they do any automated regression testing on their releases at Apple!?!".

I don't know the answer to that question... I'd be interested to hear, but I'm guessing not or they would've spotted this and let people know.

I'm not going to ramble too much, let's dive into the solution... precision!

Yes, you heard right... precision, you know the little precision qualifiers everyone who's starting out with some WebGL or GLSL copies from a sample, that little seemingly insignificant
precision highp float;
Cause let's face it...everyone always picks highp!
What it does is to determine how much precision the GPU should use for your floats and ints etc. At least 2^-8 for lowp, 2^-10 for mediump and 2^-16 for highp when we're talking floats.

So how did this affect Emberwind? Well, it's a 2d game so you're mostly only moving textured clip space quads so there really is no need to use anything but lowp (EDIT: Re-read my post when it was mentioned on the WebGL mailing list and I actually meant to say mediump here). Or at least that's what I thought I was doing... turns out there was one place, in the vertex shader where I hadn't specified precision. The GLES Shading Language spec clearly says


The vertex language has the following predeclared globally scoped default precision statements:
precision highp float;
precision highp int;
precision lowp sampler2D;
precision lowp samplerCube;

The fragment language has the following predeclared globally scoped default precision statements:
precision mediump int;
precision lowp sampler2D;
precision lowp samplerCube;




Which meant I really were using highp in the vertex shader. Now the regression in iOS 5 appears to be that using a highp varying in the vertex shader will promote any mismatched varying in the fragment shader to highp thereby causing a major performance hit. You can see a profile run of the game using highp struggling to reach 13-14 FPS. (Note how lovely quiet it is on the CPU except when loading)


Using lowp in the second sample it sits quite comfortably at 33 FPS. It's a quite staggering difference. And if you say "You call 30FPS smooth?" Then my only defence is... well...it's a port...they're always second class citizens! You're so damn tired of the game by the time you get to ports so you're bound to take a few shortcuts. 30 FPS seemed like a reasonable one.

So, summing up... dropping from 33 to 13 fps because of precision! It may not matter much on desktop graphics hardware, but it apparently very much does on mobile... that goes for you WebGL-ers as well... not just native app devs!

Now I just need to send my one line optimization off to Chillingo and get it all fixed on the appstore!

And finally.. I'm speaking at New Game Conference in SF together with heaps of other talented speakers. It'll be awesome... and you should come! Free Chromebooks for everyone if they sell out 97% of the tickets!

Emberwind and what's nextrequestAnimationFrame for smart(er) animating

Comments

Constantine Vesnac69 Wednesday, October 19, 2011 8:28:29 PM

+1, but this only matters for WebGL ? you cannot specify precision for 2d canvas ?

Erik Mölleremoller Thursday, December 1, 2011 11:48:34 PM

Made a small edit marked above after reading this again when it was linked to on the WebGL mailing list... typed lowp where it should've been mediump.

Erik Mölleremoller Thursday, December 1, 2011 11:50:43 PM

Originally posted by emoller:

Made a small edit marked above after reading this again when it was linked to on the WebGL mailing list... typed lowp where it should've been mediump.



I actually did try lowp as well back when I were experimenting with this, but lowp didn't have enough precision so cracks and seams were visible in the game. mediump rendered just fine.

Write a comment

New comments have been disabled for this post.