We’ve been having issues in testing lately with all of our textures appearing white after opening an iAd or our more games menu (in both cases our GLView is fully concealed and not drawing). In particular, it would happen when YouTube was playing.
After a bit of debugging I discovered that the number of valid texture ids is dropping to zero, at several seemingly random times (for example when the video player is rotated or if the phone is put into sleep and then woken). This happens on iOS 4.0 and 3.1.3, but only 1st or 2nd gen hardware (3G, iPod 2nd gen, but not iPod 3rd gen), which would seem to indicate that the OS is trying to save memory by deleting the textures.
Actually it’s not just deleting the textures. A repeated timer that prints the EAGLSharegroup of the GL context reveals that it’s actually deleting, temporarily not having, and recreating the share group. This is what holds all the gl-side buffered data including textures, vbos, and frame/render buffers. This explains why going into a level after loosing the textures resulted, in one instance, of having one of the powerups drawing wrong models. Our resource manager was holding buffer ids to models that had been deleted, and reused for other models.
I wasn’t about to find much on Google or the Apple documentation regarding callbacks from the OS that would indicate when why or if the OS is deleting GL data (though I didn’t check if low memory warnings were occurring). So I’m a little stumped.
Nonetheless, this workaround might to do the trick:
backupContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1];
context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1 sharegroup:backupContext.sharegroup];
Since EAGLSharegroup can’t be created or managed by the app, I’m using a secondary context to create a sharegroup for me. Then I can specifically tell my main context to use the share group that I’m giving it. This seems to make it hold on to the share group tighter, perhaps because I’m telling it specifically to use that one. I was still able to get the textures to disappear once, but I can’t reproduce it. This seems better than polling for the number of textures and reloading if they are no longer there (that approach also wouldn’t work for other parts of the code that don’t register their buffers with the resource manager and have no way to know their ids are invalid).