Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 8 of 8

Thread: Memory leak in glDrawArrays?

  1. #1
    Junior Member Newbie
    Join Date
    Jun 2010
    Location
    Melbourne, Australia
    Posts
    3

    Memory leak in glDrawArrays?

    G'day, long time lurker, first time poster.

    I've been tinkering with OpenGL on a more or less hobby basis for several years after learning how to use the fixed-function stuff in university, but I only recently began seriously studying the more modern version of the API with the eventual intent of updating my custom 2D game engine.

    Currently I've just finished re-tooling the sprite system to render using GLSL 1.2 shaders and competely custom attribute buffers with a homemade matrix system similar to the original OpenGL functionality (using CML). Everything draws fine, but when I examined the process in Task Manager, I noticed the memory use was increasing at about 4KB a second.

    Selectively commenting out lines allowed me to zero in on the problem, which turned out to be specific to only two types of sprite and correspondongly to three of the drawing routines.

    In the engine I have drawing routines for:

    *Monochrome lines
    *Bicoloured lines
    *Convex polygons
    *Line loops
    *Textured quads (this will eventually be updated since quads have been deprecated, I believe)

    The sprites that cause the problems are the monochrome line sprite and the polygon sprite that uses the polygon routine plus the loop routine for an optional border.

    That is to say, these snippets of code don't cause a leak:

    Code :
     
    inline void SLRenderer::drawBiLine(GLuint colour_index, Uint32 thickness, GLuint vertex_index)
    {
        SL_ASSERT(SLShaderProgram::getCurrentShader() != NULL, "ERROR: Current shader is null for some reason.");
     
        static GLuint vertex_loc;
        static string v_name("vertex_in");
        vertex_loc = SLShaderProgram::getCurrentShader()->getAttributeLocation(v_name);
     
        glBindBuffer(GL_ARRAY_BUFFER, SLVBOManager::SLVertexManager.VBOID());
        glEnableVertexAttribArray(vertex_loc);
        glVertexAttribPointer(vertex_loc, 2, GL_FLOAT, GL_FALSE, 0, (GLvoid*)vertex_index);
     
        static GLuint colour_loc;
        static string c_name("colour_in");
        colour_loc = SLShaderProgram::getCurrentShader()->getAttributeLocation(c_name);
     
        glBindBuffer(GL_ARRAY_BUFFER, SLVBOManager::SLColourManager.VBOID());
        glEnableVertexAttribArray(colour_loc);
        glVertexAttribPointer(colour_loc, 4, GL_FLOAT, GL_FALSE, 0, (GLvoid*)colour_index);
     
        static string MVM_Name("transform.model_view_matrix");
        static string PVM_Name("transform.projection_matrix");
        SLShaderProgram::getCurrentShader()->uniformM4(MVM_Name, SLGL::getModVMatrix());
        SLShaderProgram::getCurrentShader()->uniformM4(PVM_Name, SLGL::getProjMatrix());
     
        SLRenderer::switchTextures(false);
     
        glEnable(GL_LINE_SMOOTH);
        glLineWidth((GLfloat)thickness);
     
        glDrawArrays(GL_LINES, 0, 2);
     
        glDisable(GL_LINE_SMOOTH);
        glLineWidth(1.0);
     
        glDisableVertexAttribArray(vertex_loc);
        glDisableVertexAttribArray(colour_loc);
    }
     
    inline void SLRenderer::drawTQuad(cml::vector4f& col, SLTexSampleList& list, GLuint v_offset, GLuint t_offset)
    {
        SL_ASSERT(SLShaderProgram::getCurrentShader() != NULL, "ERROR: Current shader is null for some reason.");
     
        static GLuint vertex_loc;
        static string v_name("vertex_in");
        vertex_loc = SLShaderProgram::getCurrentShader()->getAttributeLocation(v_name);
     
        static GLuint t_coord_loc;
        static string t_name("t_coord_in");
        t_coord_loc = SLShaderProgram::getCurrentShader()->getAttributeLocation(t_name);
     
        glBindBuffer(GL_ARRAY_BUFFER, SLVBOManager::SLVertexManager.VBOID());
        glEnableVertexAttribArray(vertex_loc);
        glVertexAttribPointer(vertex_loc, 2, GL_FLOAT, GL_FALSE, 0, (GLvoid*)v_offset);
     
        glBindBuffer(GL_ARRAY_BUFFER, SLVBOManager::SLTCoordManager.VBOID());
        glEnableVertexAttribArray(t_coord_loc);
        glVertexAttribPointer(t_coord_loc, 2, GL_FLOAT, GL_FALSE, 0, (GLvoid*)t_offset);
     
        static string MVM_Name("transform.model_view_matrix");
        static string PVM_Name("transform.projection_matrix");
        static string col_name("colour_in");
        SLShaderProgram::getCurrentShader()->uniformM4(MVM_Name, SLGL::getModVMatrix());
        SLShaderProgram::getCurrentShader()->uniformM4(PVM_Name, SLGL::getProjMatrix());
        SLShaderProgram::getCurrentShader()->uniformVF4(col_name, col);
     
        SLRenderer::switchTextures(true);
     
            foreach(SLTexSamplePair p, list)
            {
                p.second->setActive();
                //SL_LOG("Setting sampler %s to use texture %s in texture unit %i", p.first.c_str(), p.second->getName().c_str(), p.second->getTextureUnit());
                SLShaderProgram::getCurrentShader()->texture(p.first, p.second->getTextureUnit());
            }
     
            glDrawArrays(GL_QUADS, 0, 4);
     
            foreach(SLTexSamplePair p, list)
            {
                p.second->setInactive();
            }
     
        glDisableVertexAttribArray(vertex_loc);
        glDisableVertexAttribArray(t_coord_loc);
    }

    And these routines do cause a leak:

    Code :
     
    inline void SLRenderer::drawLine(cml::vector4f& colour, Uint32 thickness, GLuint index)
    {
        SL_ASSERT(SLShaderProgram::getCurrentShader() != NULL, "ERROR: Current shader is null for some reason.");
     
        static GLuint vertex_loc;
        static string v_name("vertex_in");
        vertex_loc = SLShaderProgram::getCurrentShader()->getAttributeLocation(v_name);
     
        glBindBuffer(GL_ARRAY_BUFFER, SLVBOManager::SLVertexManager.VBOID());
        glEnableVertexAttribArray(vertex_loc);
        glVertexAttribPointer(vertex_loc, 2, GL_FLOAT, GL_FALSE, 0, (GLvoid*)index);
     
        static string MVM_Name("transform.model_view_matrix");
        static string PVM_Name("transform.projection_matrix");
        static string col_name("colour_in");
        SLShaderProgram::getCurrentShader()->uniformM4(MVM_Name, SLGL::getModVMatrix());
        SLShaderProgram::getCurrentShader()->uniformM4(PVM_Name, SLGL::getProjMatrix());
        SLShaderProgram::getCurrentShader()->uniformVF4(col_name, colour);
     
        SLRenderer::switchTextures(false);
     
        glEnable(GL_LINE_SMOOTH);
        glLineWidth((GLfloat)thickness);
     
        glDrawArrays(GL_LINES, 0, 2); // <-- Offending line, if commented out the memory leak doesn't occur (and, obviously, no drawing is performed)
     
        glDisable(GL_LINE_SMOOTH);
        glLineWidth(1.0);
     
        glDisableVertexAttribArray(vertex_loc);
    }
     
    inline void SLRenderer::drawPoly(cml::vector4f&amp; col, GLuint offset, int num_points)
    {
        SL_ASSERT(SLShaderProgram::getCurrentShader() != NULL, "ERROR: Current shader is null for some reason.");
     
        static GLuint vertex_loc;
        static string v_name("vertex_in");
        vertex_loc = SLShaderProgram::getCurrentShader()->getAttributeLocation(v_name);
     
        glBindBuffer(GL_ARRAY_BUFFER, SLVBOManager::SLVertexManager.VBOID());
        glEnableVertexAttribArray(vertex_loc);
        glVertexAttribPointer(vertex_loc, 2, GL_FLOAT, GL_FALSE, 0, (GLvoid*)offset);
     
        static string MVM_Name("transform.model_view_matrix");
        static string PVM_Name("transform.projection_matrix");
        static string col_name("colour_in");
        SLShaderProgram::getCurrentShader()->uniformM4(MVM_Name, SLGL::getModVMatrix());
        SLShaderProgram::getCurrentShader()->uniformM4(PVM_Name, SLGL::getProjMatrix());
        SLShaderProgram::getCurrentShader()->uniformVF4(col_name, col);
     
        SLRenderer::switchTextures(false);
     
        glEnable(GL_LINE_SMOOTH);
        glDrawArrays(GL_POLYGON, 0, num_points); // <-- another cuplrit
        glDisable(GL_LINE_SMOOTH);
     
        glDisableVertexAttribArray(vertex_loc);
    }
     
    inline void SLRenderer::drawLoop(cml::vector4f&amp; col, Uint32 thickness, GLuint offset, int num_points)
    {
        SL_ASSERT(SLShaderProgram::getCurrentShader() != NULL, "ERROR: Current shader is null for some reason.");
     
        static GLuint vertex_loc;
        static string v_name("vertex_in");
        vertex_loc = SLShaderProgram::getCurrentShader()->getAttributeLocation(v_name);
     
        glBindBuffer(GL_ARRAY_BUFFER, SLVBOManager::SLVertexManager.VBOID());
        glEnableVertexAttribArray(vertex_loc);
        glVertexAttribPointer(vertex_loc, 2, GL_FLOAT, GL_FALSE, 0, (GLvoid*)offset);
     
        static string MVM_Name("transform.model_view_matrix");
        static string PVM_Name("transform.projection_matrix");
        static string col_name("colour_in");
        SLShaderProgram::getCurrentShader()->uniformM4(MVM_Name, SLGL::getModVMatrix());
        SLShaderProgram::getCurrentShader()->uniformM4(PVM_Name, SLGL::getProjMatrix());
        SLShaderProgram::getCurrentShader()->uniformVF4(col_name, col);
     
        SLRenderer::switchTextures(false);
     
        glEnable(GL_LINE_SMOOTH);
        glLineWidth((GLfloat)thickness);
        glDrawArrays(GL_LINE_LOOP, 0, num_points); // <--Again, same thing
        glLineWidth(1.0);
        glDisable(GL_LINE_SMOOTH);
     
        glDisableVertexAttribArray(vertex_loc);
    }

    Now, I'm using a 5000HD series Radeon card, and I have encountered bugs in AMD/ATI's OpenGL implementation before (most recently the new shader-utilising version of the engine was drawing quads with bizarre faded-out edges until I upgraded the drivers). Is this a known bug, or am I just doing something stupid?

  2. #2
    Junior Member Regular Contributor Heiko's Avatar
    Join Date
    Aug 2008
    Location
    the Netherlands
    Posts
    170

    Re: Memory leak in glDrawArrays?

    I'm having a memory leak as well with some OpenGL code using Ati drivers (HD4870). I haven't been able to track down the problem yet, but I'm 95% sure it is not my own code that causes the leak. Unfortunately using a tool like memgrind isn't possible with Ati drivers (it generates millions of errors because the drivers themselves do some tricky things with memory allocation which are not understood by memgrind).

  3. #3
    Junior Member Newbie
    Join Date
    Jun 2010
    Location
    Melbourne, Australia
    Posts
    3

    Re: Memory leak in glDrawArrays?

    Should I have put this somewhere else?

  4. #4
    Junior Member Regular Contributor Heiko's Avatar
    Join Date
    Aug 2008
    Location
    the Netherlands
    Posts
    170

    Re: Memory leak in glDrawArrays?

    Most regular readers will probably read this topic, however if nobody shares your experience, there is not much too comment. You could try to create a minimal example program that demonstrates the bug which can be downloaded by others. That way they can test it for themselves (and maybe provide usefull feedback).

    There is also a drivers section on these boards. If you would have placed it overthere, the chances some AMD guy would see it would have been slightly better I think. You can also try and PM the AMD employees who have an account on this forum (Pierre Boudier, frank li, maybe others).

  5. #5
    Junior Member Newbie
    Join Date
    Jun 2010
    Location
    Melbourne, Australia
    Posts
    3

    Re: Memory leak in glDrawArrays?

    Maybe I could get a moderator to shuffle this over to the driver section in their own time, then? It's not urgent, at the current rate of memory consuption and under ideal conditions the leak would take something like 582 hours to crash a program that'll probably be run for 2, unless I've got the math wrong. Would it be considered proper to use the notify button to make the request?

    I was actually more concerned when I posted this that I'd done something stupid with glDrawArrays, but after scrathing my head for a while, I can't see that I have.

  6. #6
    Super Moderator OpenGL Guru dorbie's Avatar
    Join Date
    Jul 2000
    Location
    Bay Area, CA, USA
    Posts
    3,946

    Re: Memory leak in glDrawArrays?

    I don't think there's a problem with it being here, my (perhaps flawed) understanding is that drivers is more oriented towards end users looking for drivers. Then again this is probably isolated to a specific class of driver. Having it here is a reasonable sanity check.

  7. #7
    Super Moderator OpenGL Lord
    Join Date
    Dec 2003
    Location
    Grenoble - France
    Posts
    5,580

    Re: Memory leak in glDrawArrays?

    Quote Originally Posted by dorbie
    my (perhaps flawed) understanding is that drivers is more oriented towards end users looking for drivers
    Indeed, that is a flawed understanding
    End users should go to End users forum section.

    Having it here is a reasonable sanity check.
    Agreed.

  8. #8
    Junior Member Newbie
    Join Date
    Jan 2009
    Location
    Poland
    Posts
    26

    Re: Memory leak in glDrawArrays?

    I encounter the same behaviour, no idea if glDrawElements 'leaks' too. Nvidia 9600GT

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •