I’ve mentioned this in previous tutorials, but I keep forgetting to make a point out of it.
One great performance trick when using gpu renderMode on mobile, is to add this single line of code:
stage.quality = “low”;
On Android and Playbook, this can almost double your framerate without comprimising image quality at all. (Provided you use bitmap’s to render everything :p). On iOS the effects seem to be negligible. you can get a huge boost on older devices such as iPad 1 or 3GS, but the difference on newer devices like the iPad 2 seemed to be negligible from my testing.
Rather than charts I will simply give you two screenshots from my Galaxy Nexus:
The only difference in these two apps is the stage quality. And as you can see, they look identical.
The reason’s this works is because LOW stage quality still allows textFields to be rendered perfectly, and it also respects a bitmap.smoothing = true, or a draw() call with smoothing set to true. So text looks perfect, bitmap’s look perfect that’s almost everything… all that’s left are those pesky vector’s animations.
To render Vector’s with LOW stage quality, there’s an easy trick:
- set stage.quality = HIGH
- cache vector to bitmapData
- set stage.quality = LOW
Like So:
0 1 2 3 4 5 6 7 8 9 10 | stage.quality = StageQuality.HIGH; var asset:Sprite = new LibraryVectorAsset(); var bitmapData:BitmapData = new BitmapData(asset.width, asset.height, false, 0x0); bitmapData.draw(vectorAsset); //Here's our smoothly rendered vector :) var cachedVector:Bitmap = new Bitmap(); addChild(cachedVector); //Lets get that performance boost back stage.quality = StageQuality.LOW; |
This can be expanded upon by passing a matrix to pre-scale the vector to any size you see fit, just make sure to set smoothing=true in your draw() call.
Hi Shawn,
Great post. Just a quick question – when setting stage quality to low, display objects (bitmaps included, not just vectors) seem only able to move on full or half pixels, nothing in between. This makes it hard to tween or move even a small object over a short period of time e.g. 100 pixels in 10 seconds. Have you come across this, and if so have you found a work around? My situation only requires one instance of the object but it’s quite large (500×400) so blitting that sort animation is pretty memory heavy. Any ideas?
Thats a good point jassa, I haven’t really found this to be noticeable, but Ross has also stated this is the case.
I haven’t found any workaround for this, I think it’s a fact of life. if it’s really an issue I guess you’ll need to try MEDIUM or HIGH.
Isnt it solved by the PixelSnapping Property?
Thanks for the feedback Shawn. I have a few workaround ideas in mind – surely one of them will work!
[...] (source article) [...]
thanks for this.
what exactly is happening when the stage quality is set to low ?
why is this increasing performance of an all-bitmap app ?
It actually turns of AA, which is useless anyways since we’re using pre-rendered bitmaps.
Thanks Shawn for all your work on this blog, as I have enjoyed reviewing.
I am trying to develop an app for Android (an asteroid style shooter). Recently, I uploaded a level to a Samsung Galaxy Tab 2 10.1 inch and was disappointed with performance. The best I could squeeze out of it was 30 fps with GPU.
I have shooter objects that at 30 fps, do not appear smooth with their motion when translating in both x and y directions. The motion is small per frame (sometimes a few pixels), so I was aiming to run the at 60 fps the code that controls the motion of the shooter and all other code at 30 fps. (one enterframe event running the game) The problem from what I can tell, is that AIR updates the whole screen at 60 fps instead of just the one shooter object and cannot keep up, so there is a big lag whenever I fire the shooter.
I tried your techique with bitmaps and setting the stage quality to low, but then the animations get pixel snapped. Since they are small objects (no more than 8 mm by 8 mm, it is noticeable). Any idea to solve this?
I also set the stage quality to medium, but this then reduced the fps to around 48.
Finally, I have been reading about V-sync issues with Flash. I tried only animating a single shooter at 60 fps and it was really smooth but every about 1second, there was a particular stutter that was noticeable (even though it was running at 60 fps). It looked a lot like a V-sync issue, where the screen refreshes at a different rate then 60 fps game. Any ideas about this too?
So, the reason for this is that Android GPU’s (and mobiel GPU’s in general) really suck at AA, and when using High stage quality Flash applies 4xAA to everything, even pre-rendered Bitmap’s :/
Switching to Low quality gives you 0xAA, which is where the huge performance boost comes from. Unfortunately, yes, you must now live with Pixel Snapping…
There’s no fix, I’ve asked Adobe to expose AA as a standalone property, but they haven’t really responded. The alternative is to use Stage3D/Starling which does allow you to set AA levels manually.