Since WOT should run on all iPad devices, I have decided to do some profiling on the iPad 1. I want to ensure it could keep up with the 30 frames per second goal. At this first profiling session I quickly found two memory issues.
The first and simple one, was just the fact, that even though WOT is an ARC (automatic reference counting) project, you should still have some thoughts on autorelease pools in loops. This works now with the @autoreleasepool blocks.
The second memory issue was unexpected for me. The engine design was chosen the way that every mesh object contains its own GLKBaseEffect shader object. The GLKBaseEffect is the shader class from GLKit by the way. I thought that the GLKBaseEffect would surely somehow cache compiled shader and share them over all instances. But this seems not to be the case. Every time a mesh is cloned to create a new instance of a scene object, the shader in that mesh gets copied, too. But this is finally the reason for a huge memory increase. By huge I mean some value around 500 KB per shader object.
Sine every tower in the game contains at least one mesh and hence a GLKBaseEffect instance, you are not able to place more than 40 towers before you receive the first memory warning.
Long story short, the engine design has changed a bit to work around this memory issue. Every mesh now has to store textures and colors and some other material information, but not the GLKBaseEffect itself. The shader object is now part of the renderer state and exists only once, like a singleton. Before the renderer draws a mesh, it has to apply textures and material information to the shared shader.
In the near future, when I will implement a additional shader handling to the engine, I could move the shader back to the mesh. I think it is more elegant to have the shader assigned to the mesh. But I will have to cache shader programs over all shader object instances to avoid the memory effect from the GLKBaseEffect.