This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

glTexImage2D memory leak

Hello Everyone! I have a question about function glTexImage2D.

There is some code that cause GL memory leak on the devices with mali gpu (t760) and force close android application.

  ....

    struct Vertex

    {

         float x, y, z;

         float u, v;

    };

  ...

    glBindFramebuffer(GL_FRAMEBUFFER, fbo);

    glViewport(0, 0, 1440, 2560);

    while(true)

    {      

        glActiveTexture(GL_TEXTURE0);

        glBindTexture(GL_TEXTURE_2D, texID);

       glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);

        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

   

        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1440, 2560, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer);

   

        glUseProgram(shader);

        int position = glGetAttribLocation(shader, "aPosition");

        glVertexAttribPointer(hPosition, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), &vertexBuffer[0]);

        glEnableVertexAttribArray(position);

   

        int texCoord = glGetAttribLocation(data.shader, "aTexCoord");

        glVertexAttribPointer(texCoord, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), &vertexBuffer[0].u);

        glEnableVertexAttribArray(texCoord);

        int textureLocation = glGetUniformLocation(shader, "texture0");

        glUniform1i(textureLocation, 0);

        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);

        glDisableVertexAttribArray(position);

        glDisableVertexAttribArray(texCoord);

    }

The shaders program is a trivial, just gets texture sampler and draws at the target FBO.

This code is just rendering texture into FBO. On each steps texture is updated by glTexImage2D call.

The question is why this code leads to memory leak?

I suppose, the reason is that glTexImage2D on each call allocates new chunk of memory for texture's data.

Texture memory that are used at previous rendering step is never released, until we call glFinish or glBindFramebuffer(GL_FRAMEBUFFER, 0).

It looks like some optimization on driver side, but is it standard behavior? Please, correct me if I'm wrong.

Thanks a lot!

P.S Code above works fine on the devices with Adreno GPU.

Parents
  • Hi Kirrero,

    I haven an answer for you.Your supposition about the behavior on Mali is quite correct,

    "the reason is that glTexImage2D on each call allocates new chunk of memory for texture's data. Texture memory that are used at previous rendering step is never released, until we call glFinish or glBindFramebuffer(GL_FRAMEBUFFER, 0)."


    The reason behind this is that Mali is a deferred renderer.  What your sample code is doing is building an infinite queue of draw calls which we batch up ready to process when a flush occurs triggered by either from a call to glFinish or glBindFramebuffer.  The "old" texture data that was allocated and had your texture uploaded to can't be flushed because the draw calls using it haven't actually happened yet! The data has to be kept so the draw calls that sample from it can do so when that draw call is executed.


    Other immediate mode renders will process the issued draw call immediately so don't need to hang onto these textures in memory.


    I hope this helps,


    Kind Regards,

    Rich

Reply
  • Hi Kirrero,

    I haven an answer for you.Your supposition about the behavior on Mali is quite correct,

    "the reason is that glTexImage2D on each call allocates new chunk of memory for texture's data. Texture memory that are used at previous rendering step is never released, until we call glFinish or glBindFramebuffer(GL_FRAMEBUFFER, 0)."


    The reason behind this is that Mali is a deferred renderer.  What your sample code is doing is building an infinite queue of draw calls which we batch up ready to process when a flush occurs triggered by either from a call to glFinish or glBindFramebuffer.  The "old" texture data that was allocated and had your texture uploaded to can't be flushed because the draw calls using it haven't actually happened yet! The data has to be kept so the draw calls that sample from it can do so when that draw call is executed.


    Other immediate mode renders will process the issued draw call immediately so don't need to hang onto these textures in memory.


    I hope this helps,


    Kind Regards,

    Rich

Children