Search code examples
iosios6opengl-es

iOS 6 OpenGL ES 2.0 video memory leak in a render buffer object


Below is an example code that behaves like one leaking a video memory on iPad 2 IOS 6.1 (basically it creates a render buffer object, allocates a memory for it and destroys it after drawing):

if I put it into a draw loop I see lots of memory warnings and finally the application is killed by OS. Instruments give no hints and I even cannot see any memory size growth, only memory warnings.

I understand that creating buffers in a draw loop is a bad idea, but the buffer needs to be recreated anyway in case if user rotates a device and resolution changes so the leak will remain but need more time to kill the app (also looks like springboard restarts sometimes when the application is killed).

So the example below is just a way to reproduce a problem that is usually hidden, I think. I would be glad to here any ideas on what's wrong here and how this leak can be fixed.

There are several things I tried (see commented code) but nothing really helped. The only thing that helps is commenting of a glClear and glDrawArrays calls.

Looks like GPU doesn't touch the render buffer in this case and the problem disappears, but I need to clear that buffer and draw something to it (the reason why I need that buffer is next:

I try to implement a multi-sampled rendering into a texture, which works in fact, but leaks memory). I check for glGetError() after every GL call and no errors appear.

GLuint rbo;
glGenRenderbuffers(1, &rbo);
glBindRenderbuffer(GL_RENDERBUFFER, rbo);
//glRenderbufferStorageMultisampleAPPLE(GL_RENDERBUFFER, 4, GL_RGBA4, 2000 , 2000);
glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA4, 2000 , 2000);

/*GLuint fbo_faa;
glGenFramebuffers(1, &fbo_faa);*/
glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebuffer/*fbo_faa*/);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);

glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, 0);
glDeleteRenderbuffers(1, &rbo);

Solution

  • I see now what you are doing and I have no idea why your code works in one of my projects. Anyway, it would seem you keep attaching render buffers to your frame buffer. The best guess would be they are not deleted as you did not signal the GL that those render buffers are no longer in use. So you do need to discard attachments and reattach the main render buffer.. Try pasting this code and tell me how it turns out..

        GLuint rbo;
        glGenRenderbuffers(1, &rbo);
        glBindRenderbuffer(GL_RENDERBUFFER, rbo);
        //glRenderbufferStorageMultisampleAPPLE(GL_RENDERBUFFER, 4, GL_RGBA4, 2000 , 2000);
        glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA4, 2000 , 2000);
    
        /*GLuint fbo_faa;
         glGenFramebuffers(1, &fbo_faa);*/
        glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebuffer/*fbo_faa*/);
        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
    
        glClearColor(0, 0, 0, 0);
        glClear(GL_COLOR_BUFFER_BIT);
        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
    
        const GLenum discards[]  = {GL_COLOR_ATTACHMENT0};
        glDiscardFramebufferEXT(GL_FRAMEBUFFER, 1, discards);
    
        glDeleteRenderbuffers(1, &rbo);
    
        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRenderbuffer);
        glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer);