Textures, Memory, and Footprints.. oh my...
For the last couple of months, Chris (the creative guy :)) has been steadily cranking out massive amounts of content: textures, sprites, models, backdrops, buttons, overlays, etc. And with each passing day, our memory footprint grows and grows. To the point where last weekend Alex wasn't able to test anything because we were crashing within seconds of the app starting up on the iPhone. Now, to set the record straight, we did all the 'good practices' of building textures and sprites for a 2D/3D game. We load the textures into 16-bit buffers of the best pixel format for the image. We atlas all our 2D content to fit as many images onto a single texture as possible: (like this soldier atlas, which is 1024x1024 in it's final state).
So how do we solve these memory problems? First off, how much texture data is the game using at run time, and is it feasible? We took a look at all our content and counted up the size of all the images the game could be using at any given time, and with 16-bit textures, it should sit around 10-11 megs of memory on the iPhone.. Which is just barely within the 'safe-zone' for older 3G iPhones... (approximately 13 megs).
Next, we added some memory counting code for textures and Alex loaded up the Apple iPhone profiling tools to check out our memory footprint at run time to see what was going on. At peek load times.. we were hitting upwards of 40 Megs!! which is way out of the safe zone for iPhone apps.. Now with our estimated max of 11 megs.. and maybe another 1 meg for various buffers and such, why are we hitting 40 megs?!
The short answer: Image loading and conversion.. The long of it: What does it really take to get a PNG file loaded into a 16-bit texture. And the answer is, given that you must use Apples built in png loader, you load the 32-bit image, convert it to a 16-bit image, then uploads the texture to memory.. At run time... :( Way too many operations, way too much work, and way too much memory for what really needs to be done.
So, we moved all this work and memory usage to the build process by writing a custom step in our asset tool chain, that takes texture images, converts them to the destination pixel format, and saves them to a custom file format using simple ZLib zip compression. At load time, we simply allocate a texture, and use the fast Zlib library to decompress chunks of the file & upload them to the texture. In the end, our load time is about 3x faster and we peak at 14 megs of memory in load times.. back in the safe zone. And most importantly, we haven't seen an iPhone crash in days :D

Leave a comment...