This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Compiler/PROCESSOR-SDK-AM57X: Memory leak in EGL library

Part Number: PROCESSOR-SDK-AM57X

Tool/software: TI C/C++ Compiler

For every operation loop I am getting 64 bytes memory leak in libIMGegl.so.1.14.3699939.
I checked with valgrind.

I am using ti-sgx-ddk-um_1.14.3699939.bb
{
.
.
.

DESCRIPTION = "Userspace libraries for PowerVR SGX chipset on TI SoCs"
HOMEPAGE = "git.ti.com/.../omap5-sgx-ddk-um-linux"
LICENSE = "TI-TSPA"
LIC_FILES_CHKSUM = "file://TI-Linux-Graphics-DDK-UM-Manifest.doc;md5=550702a031857e0426ef7d6f6cf2d9f4"

PACKAGE_ARCH = "${MACHINE_ARCH}"

BRANCH = "ti-img-sgx/${PV}"

SRC_URI = "git://git.ti.com/graphics/omap5-sgx-ddk-um-linux.git;protocol=git;branch=${BRANCH}"
SRCREV = "cf8cd620e96c9741bfcbe7f07c95328fe2d6ece9"
.
.
.

}

Here is my code sequences
---------------------------

OPERATION LOOP
{

eglMakeCurrent(pDRMDisplayInternalContext->sDRMDisplayEGLContext.pEGLDisplay, pDRMDisplayInternalContext->sDRMDisplayEGLContext.pEGLSurface,
pDRMDisplayInternalContext->sDRMDisplayEGLContext.pEGLSurface, pDRMDisplayInternalContext->sDRMDisplayEGLContext.pEGLContext);


/* eglInitlize sheders */
pDRMDisplayShaderContext->glVertexShader = DRMDisplayLoadShader(pVertexShaderSource, GL_VERTEX_SHADER);
pDRMDisplayShaderContext->glFragmentShader = DRMDisplayLoadShader(pFragmentShaderSource, GL_FRAGMENT_SHADER);
pDRMDisplayShaderContext->glProgram = glCreateProgram();
glAttachShader(pDRMDisplayShaderContext->glProgram, pDRMDisplayShaderContext->glVertexShader);
glAttachShader(pDRMDisplayShaderContext->glProgram, pDRMDisplayShaderContext->glFragmentShader);
.
.
glLinkProgram(pDRMDisplayShaderContext->glProgram);
glUseProgram(pDRMDisplayShaderContext->glProgram);
.
pDRMDisplayEGLContext->u32TextureId = glGetUniformLocation(pDRMDisplayShaderContext->glProgram, "textureId");
pDRMDisplayEGLContext->modelviewMatrix = glGetUniformLocation(pDRMDisplayShaderContext->glProgram, "modelviewMatrix");
pDRMDisplayEGLContext->bDeviceConnectedOnHDMI = glGetUniformLocation(pDRMDisplayShaderContext->glProgram, "bDeviceConnectedOnHDMI");
...
.
.
.

/* Creating Textures for video/Image objects */
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glGenTextures(1, &pFifoBuffer->hTextureName);
glBindTexture(GL_TEXTURE_2D, pFifoBuffer->hTextureName);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, pFifoBuffer->u32BufferWidth,
pFifoBuffer->u32BufferHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,
NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

.
.
/* Filinng video/image buffers */
glBindTexture(GL_TEXTURE_2D, hTextureName);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, pFifoBuffer->u32BufferWidth,
pFifoBuffer->u32BufferHeight, GL_RGBA, GL_UNSIGNED_BYTE,
pFifoBuffer->pBuffer);
.
.
glDrawArrays(GL_TRIANGLE_STRIP, (u32Index * 4), 4);

.
.

/* Delete textures after work completed */
glDeleteTextures(1, &(pDRMDisplayInternalContext->phTextureName[i32Counter]));


/* Deinit shaders */
glDeleteShader(pDRMDisplayShaderContext->glFragmentShader);
glDeleteShader(pDRMDisplayShaderContext->glVertexShader);
glDeleteProgram(pDRMDisplayShaderContext->glProgram);


eglMakeCurrent(pDRMDisplayInternalContext->sDRMDisplayEGLContext.pEGLDisplay, pDRMDisplayInternalContext->sDRMDisplayEGLContext.pEGLSurface,
pDRMDisplayInternalContext->sDRMDisplayEGLContext.pEGLSurface, pDRMDisplayInternalContext->sDRMDisplayEGLContext.pEGLContext);

}

  • "OPERATION LOOP" mention in above code is in different thread. So as loop will be called, it will be called in different thread.

    As of now,
    I had narrow down issue at some level. look at below code

    OPERATION LOOP (This is in different thread for each time)
    {
    eglMakeCurrent( pEGLDisplay, pEGLSurface, pEGLSurface, pEGLContext);

    eglMakeCurrent( pEGLDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);

    }

    this code makes 64 bytes leak every time thread will be called.

    Then I do different test

    OPERATION LOOP (This is in different thread for each time)
    {
    for(int i=0; i<3; i++)
    {
    eglMakeCurrent( pEGLDisplay, pEGLSurface, pEGLSurface, pEGLContext);

    eglMakeCurrent( pEGLDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
    }
    }

    It cause same, It is still takes 64 bytes leak for each operation loop thread.

    So what I think it may some memory not got freed for each thread.

    Can you help me out what needs to be done further?
  • Can you please share standalone test bench that we can use to replicate the issue at our end?

  • Hi Manisha,

    I don't have any standalone app for this. My all code is integrated with our system. Though I got alternative way to stop memory leak.

    Here is what I found.

    In thread if you do call eglMakeCurrent with display and egl surface then for freeing that memory we need to call eglMakeCurrent with specific argument. like example in below

    Thread
    {
    eglMakeCurrent( pEGLDisplay, pEGLSurface, pEGLSurface, pEGLContext);
    .
    .
    .
    eglMakeCurrent( pEGLDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);

    }

    Though this will not release all the memory. It still consuming 64bytes of memory in it. So,
    we need to call eglTerminate for cleaning all memory.

    Now my code is just like this thread is calling again and again and I am going to call eglTerminate once at last when I application going to stop. So my understanding is due to this design I am getting increasing memory leak in my application.

    So for now I have did some changes in my design where I am just keeping one thread running all time (never getting stop). and
    during initial point of thread I am calling eglMakeCurrent for initialization and when application getting stop I am doing eglMakeCurrent with EGL_NO_SURFACE call. So that I am not getting Increasing memory leak in my app.


    Manisha, If you have any suggestion on this then please let me know.


    Ref: forums.khronos.org/.../5620-eglTerminate()
  • Hi Sandeep,

    We tried to recreate the 64 bytes leak scenario and we don't see any leaks. Could you please let us know how you verified 64 bytes leak with loop of below function call?

    {
    eglMakeCurrent( pEGLDisplay, pEGLSurface, pEGLSurface, pEGLContext);
    eglMakeCurrent( pEGLDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
    }
  • I had checked with valgrind tool.

    Make sure this call should be on different thread.

    For example.

    thread_func
    {
    eglMakeCurrent( pEGLDisplay, pEGLSurface, pEGLSurface, pEGLContext);
    eglMakeCurrent( pEGLDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
    }

    main()
    {

    create_thread (thread_func);
    thread_join

    create_thread (thread_func);
    thread_join

    create_thread (thread_func);
    thread_join

    }


    So each time it will give me leaks of 64 bytes. so it give me at-least 192 bytes.
  • Sandip,

    I'm sorry for the delay. We should be able to update you early next week.
  • Hi Sandip,

    Thanks for sharing the steps. We will try to replicate the scenario of 64 bytes leak but hope you not gated with this issue any more.

    The modified code is the right design. We should not be doing frequent EGL state transitions unless required.

    You call eglMakeCurrent only to switch between two different contexts / surfaces. If there is only one surface / context, best option is to keep that context always alive.