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.

[参考译文] Linux/AM5728:OpenGL DMABUF 导入内存泄漏

Guru**** 2564410 points
Other Parts Discussed in Thread: AM5728

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/612976/linux-am5728-opengl-dmabuf-import-memory-leak

器件型号:AM5728

工具/软件:Linux

在 AM5728上、我使用 SGX GPU 的 DMABUF 导入扩展将视频纹理上传到 GPU。 我从 Arago 上使用的 OpenGL 版本是"OpenGL ES 2.0 Build 1.14@3699939 (main)"。

我使用了 Arago SDK"display-ksmscalsc"示例代码作为模板、并尝试了 YUV 和 ARGB8888 (GBM_format_ARGB8888) DMABUF 像素格式。 两种格式类型都可以正常工作、我的 HDMI 显示屏可以正确显示帧。 问题是几分钟后 ARGB8888类型的内存泄漏。  

当我的应用程序启动并提供 ARGB8888 DMABUF 作为 EGLImageKHRs 时,它会成功运行大约5分钟,然后我才开始收到指示分配失败的重复控制台消息:

PVR:(错误):[ 961->964]< CreateDrawable():938|错误映射0缓冲区[0、]

PVR:(错误):[ 961->964]< CreateBuffer():859|error>无法获取缓冲区 FD [0、]

更多信息如下。 这是我如何创建映像的问题、还是 DMABUF 导入函数有错误?  

下面是我以 RGBA8888格式将 DMABUF 提交到 GPU 的代码:

void TestOpenGL::setFrameToProcess (dmabuf_buffer * dmaBuf){

//仅设置一次输入纹理
EGLint DFD = dmaBuf->FD[0];

//设置 RGB
struct GBM_import_FD_DATA GBM_dmabuf ={
.fd = DFD、
.width = dmaBuf->width、
.height = dmaBuf->身高、
.STRIDE = dmaBuf->螺 距[0]、
.format = GBM_FORMAT_ARGB8888
};

#ifdef DEBUG_OGL
qDebug()<<setFrameToProcess Width,Height,DMABUF:“<< dmaBuf->width << dmaBuf->height << dmaBuf->FD[0];
#endif

struct GBM_bo *bo = GBM_BO_IMPORT (gbmDev、GBM_BO_IMPORT_FD、&GBM_dmabuf、
GBM_BO_USE_SCANOUT);
if (!bo){
qDebug()<<"setFrameToProcess GBM_BO_IMPORT FAILED";
返回;
}

EGLint attrib_list = EGL_none;
eglImage =空;
eglImage = eglCreateImageKHR (eglDisplay、EGL_NO_Context、EGL_NATE_PIXMAP_KHR、bo、&attrib_list);
if (eglImage = EGL_NO_IMAGE_KHR){
#ifdef DEBUG_OGL
qDebug()<<"setFrameToProcess eglCreateImageKHR failed!";
#endif
}
否则{
#ifdef DEBUG_OGL
qDebug()<<"setFrameToProcess EGL 图像:"<<eglImage <<" BO:"<< bo;
#endif
}

#ifdef DEBUG_OGL
qDebug()<<"setFrameToProcess m_TextureLCD:"<< m_TextureLCD;
#endif

glBindTexture (GL_纹 理_外部_OES、m_TextureLCD);

GLENUM Number Err = glGetError();
if (Number Err!= GL_NO_ERROR){

qDebug()<<"setFrameToProcess Failed to glBindTexture!";
fprintf (stderr、"setFrameToProcess EGLImageTargetText2DOES ()返回%d\n"、Number Err);

//销毁 DMABUF 映像
eglDestroyImageKHR( eglDisplay, eglImage );

返回;
}

GlTextParameteri (GL_turete_external_OES、GL_turete_min_filter、GL_linear_linear);
GlTextParameteri (GL_turete_external_OES、GL_turete_mag_filter、GL_linear);

//更新视频纹理/EGL 图像。
glEGLImageTargetTexture2DOES (GL_T纹 理_EXTERNAL_OES、eglImage);

#ifdef DEBUG_OGL
qDebug()<<"setFrameToProcess 上传的纹理!";
#endif

//printf ("setFrameToProcess EGLImageTargetText2DOES()返回%d\n",glGetError());

if (glGetError()!= GL_NO_ERROR){
qDebug()<<"setFrameToProcess Failed to glEGLImageTargetTexture2DOES!";
返回;
}

glUniform1i (m_DataUniformLCD、2);

//销毁 DMABUF 映像
eglDestroyImageKHR( eglDisplay, eglImage );

} 

Linux 控制台在无法分配时开始重复打印以下消息:

[2491.096394] PVR_K:(错误):DevMemoryAlloc 错误 MMU_Alloc
[2491.101857] PVR_K:(错误):WrapMemory:DevMemoryAlloc (0x96000)失败
[2491.108390] PVR_K:(错误):BM_Wrap:WrapMemory failed
[2491.113467] PVR_K:(错误):PVRSRVMapDmaBufKM:无法包装 DMA-buf
[2491.120151] PVR_K:(错误):PVRSRVMapDmaBufBW:映射 dma-buf 句柄失败
[2491.127297] PVR_K:(错误):MMU_Alloc:VMArena 的 RA_Alloc 失败
[2491.133367] PVR_K:(错误):MMU_Alloc:Allloc of DevVAddr 从堆 General ID117440512中失败、pid:915、task:QThread
[2491.144093] PVR_K:(错误):DevMemoryAlloc 错误 MMU_Alloc
[2491.149537] PVR_K:(错误):WrapMemory:DevMemoryAlloc (0x1c3000)失败
[2491.156132] PVR_K:(错误):BM_Wrap:WrapMemory failed
[2491.161228] PVR_K:(错误):PVRSRVMapDmaBufKM:无法包装 dma-buf
[2491.167677] PVR_K:(错误):PVRSRVMapDmaBufBW:映射 dma-buf 句柄失败
[2491.212944] PVR_K:(错误):MMU_Alloc:VMArena 的 RA_Alloc 失败
[2491.219004] PVR_K:(错误):MMU_Alloc:Allloc of DevVAddr 从堆 General ID117440512失败,pid:915,task:QThread
[2491.229783] PVR_K:(错误):DevMemoryAlloc 错误 MMU_Alloc
[2491.235205] PVR_K:(错误):WrapMemory:DevMemoryAlloc (0x96000)失败
[2491.241698] PVR_K:(错误):BM_Wrap:WrapMemory failed
[2491.246833] PVR_K:(错误):PVRSRVMapDmaBufKM:无法包装 dma-buf
[2491.253217] PVR_K:(错误):PVRSRVMapDmaBufBW:映射 dma-buf 句柄失败
[2491.260462] PVR_K:(错误):MMU_Alloc:VMArena 的 RA_Alloc 失败
[2491.267169] PVR_K:(错误):MMU_Alloc:Allloc of DevVAddr 从堆中失败常规 ID117440512,pid:915,任务:QThread

我正在使用 omap5-SGX-DDK-um-Linux 中的以下提交:

提交 cf8cd620e96c9741bfcbe7f07c95328fe2d6ece9
作者:Anand Balagopalakrishnan
日期:2017年6月13日星期二11:02:20 +0530

UM:gles2:在1RGB FBO 完整性检查中修复 PVR_DBG 级别

签字人:Anand Balagopalakrishnan

它是几个比以下内容更新的提交:

提交 d1cb4ea42dbf275e2013aae95ad2d9182f05648c
作者:Anand Balagopalakrishnan
日期:2017年2月23日11:17:40日+0530

UM:通过 EGL 图像 DMABuf 导入修复内存泄漏问题

签字人:Anand Balagopalakrishnan

但是、我相信我仍然看到泄漏。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    软件团队已收到通知。 他们将在这里作出回应。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    对此有任何输入吗?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我在下面显示的函数调用中添加了一些其他内容、但仍然会泄漏。 在"eglDestroyImageKHR"之后将"eglImage"重置为 EGL_NO_IMAGE_KHR。 此外、我调用 GBM_BO_Destroy (bo)、但它没有帮助。 应用程序始终在1696帧后停止。 非常感谢您在这个问题上提供帮助。 谢谢你。

    
    
    /**
    * TestOpenGL setTestFrameToProcess ()
    *用途:setTestFrameToProcess -设置使用 DMABUF 处理 OpenGL 的帧的测试数据
    *
    *@param dmaBuf -可见光摄像机帧 DMABUF
    *
    / void TestOpenGL::::setTestFrameToProcess (dmabuf_buffer){*dmaBuf
    
    //销毁 DMABUF 映像
    eglDestroyImageKHR( eglDisplay, eglImage );
    eglImage = EGL_NO_IMAGE_KHR;
    if (glGetError()!= GL_NO_ERROR){
    qDebug()<<"TestOpenGL::setTestFrameToProcess 无法实现 eglDestroyImageKHR!";
    返回;
    }
    
    //绑定测试映像
    glBindTexture (GL_Texture_external_OES、m_TestTextureLCD);
    
    //仅设置一次输入纹理
    EGLint DFD = dmaBuf->FD[0];
    
    //设置 RGB
    struct GBM_import_FD_DATA GBM_dmabuf ={
    .fd = DFD、
    .width = dmaBuf->width、
    .height = dmaBuf->身高、
    .STRIDE = dmaBuf->螺 距[0]、
    .format = GBM_FORMAT_ARGB8888
    };
    
    #ifdef DEBUG_OGL
    qDebug()<<"TestOpenGL::setTestFrameToProcess Width、Height、DMABUF:"<< dmaBuf->width << dmaBuf->height << dmaBuf->FD[0];
    #endif
    
    struct GBM_bo *bo = GBM_BO_IMPORT (gbmDev、GBM_BO_IMPORT_FD、&GBM_dmabuf、
    GBM_BO_USE_SCANOUT);
    if (!bo){
    qDebug()<<"TestOpenGL::setTestFrameToProcess GBM_BO_IMPORT FAILED";
    返回;
    }
    
    EGLint attrib_list = EGL_none;
    eglImage =空;
    eglImage = eglCreateImageKHR (eglDisplay、EGL_NO_Context、EGL_NATE_PIXMAP_KHR、bo、&attrib_list);
    if (eglImage = EGL_NO_IMAGE_KHR){
    #ifdef DEBUG_OGL
    qDebug()<<"TestOpenGL::setTestFrameToProcess eglCreateImageKHR Failed!";
    #endif
    }
    否则{
    #ifdef DEBUG_OGL
    qDebug()<<"TestOpenGL::setTestFrameToProcess EGL 图像:"<< eglImage <<" BO:"<< bo;
    #endif
    }
    
    #ifdef DEBUG_OGL
    qDebug()<<"TestOpenGL::setTestFrameToProcess m_TestTextureLCD:"<< m_TestTextureLCD;
    #endif
    
    GLENUM Number Err = glGetError();
    if (Number Err!= GL_NO_ERROR){
    
    qDebug()<<"TestOpenGL::setTestFrameToProcess 无法显示 BindTexture!";
    fprintf (stderr、"TestOpenGL::setTestFrameToProcess EGLImageTargetText2DOES()返回%d\n"、Erenumr);
    
    //销毁 DMABUF 映像
    eglDestroyImageKHR( eglDisplay, eglImage );
    eglImage = EGL_NO_IMAGE_KHR;
    
    返回;
    }
    
    GlTextParameteri (GL_turete_external_OES、GL_turete_min_filter、GL_linear_linear);
    GlTextParameteri (GL_turete_external_OES、GL_turete_mag_filter、GL_linear);
    
    //更新视频纹理/EGL 图像。
    glEGLImageTargetTexture2DOES (GL_T纹 理_EXTERNAL_OES、eglImage);
    
    #ifdef DEBUG_OGL
    qDebug()<<"TestOpenGL::setTestFrameToProcess 上传的纹理!";
    #endif
    
    //printf ("TestOpenGL::setTestFrameToProcess EGLImageTargetText2DOES()返回了%d\n",glGetError());
    
    if (glGetError()!= GL_NO_ERROR){
    qDebug()<<"TestOpenGL::setTestFrameToProcess 未能显示 EGLImageTargetTexture2DOES!";
    睡眠(86400);
    返回;
    }
    
    glUniform1i (m_TestDataUniformLCD、2);
    
    //销毁 DMABUF 映像
    eglDestroyImageKHR( eglDisplay, eglImage );
    eglImage = EGL_NO_IMAGE_KHR;
    if (glGetError()!= GL_NO_ERROR){
    qDebug()<<"TestOpenGL::setTestFrameToProcess 无法实现 eglDestroyImageKHR!";
    返回;
    }
    
    //销毁 GBM bo
    GBM_BO_SABLE(波);
    
    //破坏纹理
    //glDeleteTextures (1、&m_TestTextureLCD);
    
    } 

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Philip、

    当您使用 gBindTexture 绑定纹理时、我想您需要使用 glDeleteTextures 调用删除纹理。

    RAM

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好 RAM、

    感谢您的回答。

    我尝试在函数顶部放置一个"DeleteText"调用、如下所示。 然而、PVR 低内存条件出现、并且最终仍然会消失。 你是说把格尔泰德克萨斯放到别的地方吗? 谢谢你。

    //销毁 DMABUF 映像
    eglDestroyImageKHR( eglDisplay, eglImage );
    eglImage = EGL_NO_IMAGE_KHR;
    if (glGetError()!= GL_NO_ERROR){
    qDebug()<<"TestOpenGL::setTestFrameToProcess 无法实现 eglDestroyImageKHR!";
    返回;
    }
    
    //破坏纹理
    GlDeleteTextures (1、&m_IRTextureLCD);
    
    //绑定 IR 映像
    glBindTexture (GL_Texture_external_OES、m_IRTextureLCD); 

    注:

    我还将删除纹理放在绑定之后-它仍然以相同的方式失败:

    //销毁 DMABUF 映像
    eglDestroyImageKHR( eglDisplay, eglImage );
    eglImage = EGL_NO_IMAGE_KHR;
    if (glGetError()!= GL_NO_ERROR){
    qDebug()<<"TestOpenGL::setTestFrameToProcess 无法实现 eglDestroyImageKHR!";
    返回;
    }
    
    //绑定 IR 映像
    glBindTexture (GL_Texture_external_OES、m_IRTextureLCD);
    
    //破坏纹理
    GlDeleteTextures (1、&m_IRTextureLCD); 

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Philip、

    请参阅随附的修改后的 display-kmscube.c、我很久以前就测试过这种情况、并观察到内存泄漏问题。

    使用 omap5-SGX-um->um 中的修复 :通过 EGL Image DMABuf 导入修复内存泄漏问题、我没有观察到内存泄漏问题。

    RAM

    e2e.ti.com/.../display_2D00_kmscube.c