views:

289

answers:

3

Using OpenGLES 1.1 on the iPhone 3G (device, not simulator), I do normal drawing fun. But at points during the run of the application I get giant memory spikes, after a lot of digging with instruments I have found that it is glDrawElements that is grabbing the memory.

The buffer being allocated is 4 meg, which to me means its loading a texture into RAM, which I guess could be valid, but its never releasing this buffer, and is allocating multiple of them.

How do I make sure that these buffers that GL is creating get destroyed, instead of just hanging around?

A: 

Check to see if this is on the simulator or the iPhone device itself. Instruments/Leaks can and will report false positives on the simulator, which you will not encounter on the device.

Alex Reynolds
definitely testing on device, edited the question to match
Joshua Weinberg
+2  A: 

This doesn't sound like a leak, more like a driver optimization where the GPU holds on to a memory block (vertexbuffer, texture, whatever) in case it's needed again. If you run your application for some time does it keep allocating more and more memory until the device eventually run out of memory?

It's an unfortunate fact the the first generation of iPhone 3G doesn't have proper support for vertex buffer objects (VBO), they are exposed by the API but they work in exactly the same way as ordinary software vertex buffers. This means that whenever you call glDrawElements whatever vertex buffers you've set with glVertexPointer etc will be copied from system memory to the GPU.

The only way you can "leak" memory to OpenGL is by repeatedly allocate various buffer objects (texture objects, vertex buffer objects, frame buffer objects etc.) and not releasing them, like doing this every frame:

GLuint id;  
glGenTextures(1, &id);
glBindTexture(GL_TEXTURE_2D, id);        
glTexImage2D(...);

you'll eventually run out of memory. I'm using glDrawElements on the iPhone 3G myself and I'm not seeing this problem, can you give a small repro code sample?

Andreas Brinck
+1. As a side note, destroying the GL context should return the memory, if it's been programmed properly.
Bahbar
Yes, this is causing me to run out of memory, and is happening multiple times. I can try trashing and rebuilding my context whenever I get a memory warning, but that seems like it shouldn't be needed.
Joshua Weinberg
@Joshou Check my edited answer
Andreas Brinck
Thats the thing, I'm not doing that. I did some more digging, and it seems to be coming from me using -[NSObject performSelectorOnMainThread:] from a background ticking thread to do the render. If I collapse that back to one thread, this issue goes away, but I verified in the threaded version that all the calls to any GL state were happening only on the main thread, and all textures were being loaded on the main thread. So I'm at a loss as to what would cause this to happen.
Joshua Weinberg
@Joshua I'm sorry I have nothing more right now, this sounds very strange indeed. I'll talk with my fellow iPhone programmers and see if they know anything.
Andreas Brinck
A: 

I figured this out with the help of some people on IRC. The issue ended up being the way I was doing threading in my app. By moving GL and the game update loop to the same thread, the issue disappeared, I have no idea WHY the other way caused the memory allocations it did, but the issue is resolved.

Joshua Weinberg