Bitten by the multi-threading bug again

Wow. I think I’m still digesting thanksgiving dinner. Anyway, we just recently announced our newest game mode for Tilt to Live and it’s a doozy. In the midst of getting it all tested and ready to submit to Apple I had a bug lurking about the loading screen code. At seemingly random times the game would crash with an EXEC_BAD_ACCESS error somewhere in my loading assets functions usually stopping at CGContextDrawImage. The fact that I couldn’t replicate it with any sort of consistency really concerned me.

So what did I do? I put it off. hah! Through some beta testing our users submitted a few crash reports and after the pain of getting them to symbolicate (I can never get it to work on the first try) I wasn’t left with much to go off of. Then I noticed a peculiar thing in each of the different crash reports:

  • Thread 7 crashed
  • Thread 8 crashed
  • Thread 9 crashed

Wait what? Why am I crashing in different threads each…oh my. Apparently I haven’t learned my lesson. I wrote that post over a year ago mind you. I eventually went from libpng back to using CGImage loading for performance reasons. Most of my graphics were in texture atlases, but the new ones in turret’s syndrome were not. As a result they were lazy loaded in a background thread when I was pooling objects. The result? 95% of the time it worked without a hitch. Every now and then I would crash while loading some random asset from that method. *Face palm*.

Since I wrote that post I never really looked into any more info as to whether CoreGraphics or the methods usually used in UIImage were thread safe. In any case, it appears it’s not. For anyone that does want some sort of flexibility in loading assets in the background I’ve uploaded the small PNG loader code I wrote and used for a while in Tilt to Live. It’s a bit slower than using CoreGraphics libraries, but is thread safe. The main function of interest is LoadImagePNG(const char *path). It returns a struct called PNGImage that has all the data you should need to use the image. The function loads the image data into OpenGL so the struct contains the textureID if you need it. Pretty basic, and in order to get the same behavior on the iPhone I wrote a small transform that the loader uses to pre-multiply the alpha of the png’s.

The zip contains all the files needed to compile the loader. Just drop the files in a project and you should be good to go. If you’re wanting a more ‘official’ version, just download the latest libpng library to get the latest png.h and pngconf.h files. Enjoy!

Download: opengl-pngloader.zip

1 comment

Leave a Reply

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