Flash on iPhone – Better Than Blitting (Real World Performance Results)


I’ve been working with Flash on the iPhone for a few months now, and although I’ve successfully released a game on the App Store (check out The Hypnotist), I’ve spent most of my time experimenting and trying to discover ways of optimising code and working out just how to get the best performance out of the device with the Flash platform.

General Tips

There are a lot of great tutorials out there specifying how to get the best performance out of Flash on mobile devices (and in general). Many of them talk about the subtlties of structuring your code, and some of these do have tremendous impact, however I’ve always found that the graphics are the true bottleneck for me (and collision detection – but that’s for another day).

The key generally comes down to blitting. For those who don’t know, blitting can be very simply described as the act of copy and pasting flat pixels, rather than relying on multilayerd movieclips with vectors and tweening etc. for your animation. The thing that I’ve discovered is that it’s faster to use a hybrid blit technique on the iphone than to go the traditional way.

To explain, traditional blitting would copy the pixels for every object and sprite directly onto a single bitmap canvas, however the best performance I’ve found comes from blitting to individual Bitmap objects on the screen. In one sense that’s quite handy as it means we can still work in the mind set of having separate display objects that we can position independently, on the other hand it worries me a bit because it feels like there’s something not quite right going on for that to be faster than using the one single bitmap canvas.

The Technique

So the following results are based on this hybrid blit/display object technique. But there is one other little difference that I’ve seen increase performance considerably… and again it’s a departure from the standard blitting operation that can only be done with this hybrid technique. And that’s not to blit at all!

Let me explain – Blitting usually utilises a single sprite sheet to contain all of the frames of your animation, you then copy the pixels from that sheet for the particular frame as it’s being rendered, pasting them to the display, and so on as the animation cycle continues.

My approach is different, it splits the sprite sheet up into individual bitmapData objects, one for each frame, at the beginning of the program and stores them in an array. Then to render the animation, you don’t use copyPixels to blit, instead you set the bitmapData property of your sprite’s Bitmap to the appropriate bitmapData frame. Hence copyPixels never gets used – instead you’re swapping bitmapData objects. So I guess at the end of the day, this is a non-blit bitmap technique.

The real world results

Based on the above bitmapData Swap technique, the following results were recorded (compiling with Flex 4.5.1.21328 and Air Beta 3.0 with an app resolution of 480×320)

Sprite size: 40×40 pixels
Sprite frame count:100 frames
Results:

  • 25 Sprites: 60fps
  • 50 Sprites: 52 fps
  • 70 Sprites: 40 fps
  • 100 Sprites: 30fps

Notes about the iPhone’s memory

For these results I was actually using an iPod touch (4th gen) which is listed as having 256MB Ram and runs at 800khz. One very useful guideline I formulated whilst doing this experimentation is a rough approximation of the amount of image data that the device can hold in memory at an one time, and that is 25 mega pixels, or 25,000,000 pixels worth of data.

For instance, if you are working at a screen res of 480×320 that would equate to 153,600 pixels worth of data – so in that case you could hold around 150 frames of animation at that full screen resolution. To put it another way, the iPhone memory could cope with @ 2,500 frames of animation at 100×100 pixels.

Bare in mind that this doesn’t reflect any intimate knowledge of the device or it’s physical specs, but is just a real world observation, and should be a handy benchmark for you to use when determining how much room you have to work with. The key indicator that you’re using too much memory seems to be a black screen of death on the device that will shut down your app and return you to the springboard.

Can you do any better?

The main reason for posting this info is that I’ve been searching online to see the best performance people have been able to achieve and am really just keen to find out what’s yielding best results for everyone out there. So in the interests of pushing the limits and spreading the knowledge please post alternative approaches that might be producing faster results. At the end of the day we shouldn’t be struggling against the technology just to get suitable performance, I’d much rather be focusing on building the content and bringing ideas to life.

Corona?

I’ve looked around the web for information on measurable performance specs for Corona, if there’s anyone out there that can post a comparison it would be very interensting to see. This might be the topic for a future post.

  • If storing bitmapdata in arrays is that much faster than blitting a big bitmap, you could probably get a lower application bytesize by drawing your graphic assets as vector and at startup, capture them to bitmapdata, store it and use those at runtime. That would probably mean a little longer to load but it may be very much worth it.

    I haven’t tested at what level of detail a vector image takes up more bytes than a bitmap.
    Depends on your type of image as well of course.. A jpeg photo would not translate well into vector.

    • Hi Mediamonkey, I actually use that approach for most of the game work I do so that that my animations are rasterised once on level load. It can take up a bit of time (seconds) so you need to provide some sort of loading screen for the viewer while this is happening. To me the filesize is one potential benefit (though you’re right, most of the vector art I’m using is probably larger in size that the bitmap equivalent, also filesize really isn’t the issue here) but the huge plus is that you can make changes and tweaks to the animation and the results are availalbe immediately without having to save out a bitmap sheet and re-import it for compile *every* time you make a change.

  • Hey James,

    I’ve recently been testing the same stuff on my iPad and compared blitting vs. bitmapData assignment with similar results. I boiled it down to the essentials and also added collision detection. I also tested performance under GPU and CPU rendering mode.
    Eventually I ended up with a setup running 100 animations moving them across the screen and testing for collisions at 24 FPS. Since you asked for results from other people, I thought you may be eager to check out the tests and results on my blog http://blog.starnut.com/flash-to-ios-performance-tests/ . I tried to keep things pretty detailed to line out the differences of the various setups.

    Concerning Corona, you may want to ask Josh Tynjala about his experiences. AFAIK he used Corona in some of his games. Maybe knows more about how it performs.

    Cheers,
    Michel

Leave a Reply

Your email address will not be published. Required fields are marked *


Creative Digital Agency

Code and Visual works with clients around Australia to create and build outstanding and accessible digital services. If you want to discus a project contact us now for an initial consultation.


Categories

Recent Posts