Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/macos/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Macos 如何完全解除GL\u元素\u数组\u缓冲区的绑定?_Macos_Opengl_Graphics_Memory Leaks_Vertex Buffer - Fatal编程技术网

Macos 如何完全解除GL\u元素\u数组\u缓冲区的绑定?

Macos 如何完全解除GL\u元素\u数组\u缓冲区的绑定?,macos,opengl,graphics,memory-leaks,vertex-buffer,Macos,Opengl,Graphics,Memory Leaks,Vertex Buffer,我正在开发一个多线程应用程序,它可以同时向多个FBO渲染几何体。我遇到泄漏(如上所述) 我已经能够把它缩小一点——如果我做一个改变,它就会停止泄漏——但我不知道为什么 在4个线程中的每个线程(每个线程都有自己的共享上下文)上,我在每个渲染周期中执行以下操作: // Upload positionBuffer = getUnusedArrayBufferFromPool(); glBindBuffer(GL_ARRAY_BUFFER, positionBuffer); glBufferData(

我正在开发一个多线程应用程序,它可以同时向多个FBO渲染几何体。我遇到泄漏(如上所述)

我已经能够把它缩小一点——如果我做一个改变,它就会停止泄漏——但我不知道为什么

在4个线程中的每个线程(每个线程都有自己的共享上下文)上,我在每个渲染周期中执行以下操作:

// Upload

positionBuffer = getUnusedArrayBufferFromPool();
glBindBuffer(GL_ARRAY_BUFFER, positionBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*4*vertexCount, positions, GL_STREAM_DRAW);

{
    GLuint vertexArray;
    glGenVertexArrays(1, &vertexArray);
    glBindVertexArray(vertexArray);

    elementBuffer = getUnusedElementArrayBufferFromPool();
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementBuffer);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int)*elementCount, elements, GL_STREAM_DRAW);

    glBindVertexArray(0);
    glDeleteVertexArrays(1, &vertexArray);
}

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);



// Render (possibly on a different context)

GLuint vertexArray;
glGenVertexArrays(1, &vertexArray);
glBindVertexArray(vertexArray);

glUseProgram(programName);
{
    GLint positionAttribute = glGetAttribLocation(programName, "position");
    glBindBuffer(GL_ARRAY_BUFFER, positionBuffer);
    glVertexAttribPointer((GLuint)positionAttribute, 4 /* XYZW */, GL_FLOAT, GL_FALSE, sizeof(float)*4, (void*)0);
    glEnableVertexAttribArray((GLuint)positionAttribute);

    {
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementBuffer);
        glDrawElements(GL_TRIANGLES, (GLsizei)elementCount, GL_UNSIGNED_INT, (void*)0);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
    }

    glDisableVertexAttribArray((GLuint)positionAttribute);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
}
glUseProgram(0);

glBindVertexArray(0);
glDeleteVertexArrays(1, &vertexArray);



// Cleanup (possibly on a different context)

glBindBuffer(GL_ARRAY_BUFFER, positionBuffer);
glBufferData(GL_ARRAY_BUFFER, 0, 0, GL_STREAM_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
throwArrayBufferBackInPool(positionBuffer);

//glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementBuffer);
//glBufferData(GL_ELEMENT_ARRAY_BUFFER, 0, 0, GL_STREAM_DRAW);
//glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
//throwElementArrayBufferBackInPool(elementBuffer); // Why does this leak if we recycle it?
glDeleteBuffers(1, &elementBuffer);
如果我交换最后两行-如果我在每个渲染周期都将元素缓冲区扔回池中而不是删除它-OpenGL驱动程序监视器指示一个巨大的泄漏

但我更愿意将其合并,因为调用
glDeleteBuffers()
每一帧都非常慢

我错过了什么?我假设我无法从某个对象中解除绑定
elementBuffer
,并且某个对象保留了对它的引用,导致了泄漏,但我不知道是什么原因


编辑:刚刚在另一个系统(Mac OS 10.6)上测试过-在该系统上,如果我回收任何缓冲区,它就会泄漏

编辑:我修改了我的应用程序,以便将
GL\u数组缓冲区
GL\u元素数组缓冲区
分开合并,并使
elementBuffer
始终绑定到
GL\u元素数组缓冲区
。但是如果我
通过ElementArrayBufferbackInPool(elementBuffer),它仍然会泄漏

编辑:阐明了我在上传和渲染期间创建和删除VAO的原因-因为它们可能发生在不同的共享GL上下文中,并且VAO不能在上下文之间共享


编辑:我修改了我的应用程序,在将缓冲区扔回池中之前提供了零大小的缓冲区数据,但它仍然以同样快的速度泄漏。

您的缓冲池用于绑定
GL\u ARRAY\u buffer
以及GL\u ELEMENT\u ARRAY\u buffer对象。更糟糕的是,您首先使用
elementBuffer
绑定
GL\u数组缓冲区
,然后继续将其用于
GL\u元素数组缓冲区
。我还没有完全理解它,但是在混合名称空间和不一致地使用绑定之间的某个地方,我已经投入了我的资金


我的建议是:为
GL\u-ELEMENT\u-ARRAY\u-buffer
使用创建一个单独的缓冲区名称池,并确保您仅为此目的而一致地使用它。

您的缓冲池用于绑定
GL\u-ARRAY\u-buffer
以及GL\u-ELEMENT\u-ARRAY\u-buffer对象。更糟糕的是,您首先使用
elementBuffer
绑定
GL\u数组缓冲区
,然后继续将其用于
GL\u元素数组缓冲区
。我还没有完全理解它,但是在混合名称空间和不一致地使用绑定之间的某个地方,我已经投入了我的资金


我的建议是:为
GL\u-ELEMENT\u-ARRAY\u-buffer
使用创建一个单独的缓冲区名称池,并确保您仅为此目的而一致地使用它。

我修改了我的应用程序(以及上面的示例代码),以便
GL\u-ARRAY\u-buffer
GL\u-ELEMENT\u-ARRAY\u-buffer
分开池,因此,
elementBuffer
始终绑定到
GL\u ELEMENT\u ARRAY\u BUFFER
。但是如果我
通过ElementArrayBufferbackInPool(elementBuffer),它仍然会泄漏
。我修改了我的应用程序(以及上面的示例代码),以便将
GL\u数组\u BUFFER
GL\u ELEMENT\u数组\u BUFFER
分开合并,从而
elementBuffer
始终绑定到
GL\u ELEMENT\u数组\u BUFFER
。但是如果我
通过ElementArrayBufferbackInPool(elementBuffer),它仍然会泄漏。您是否有机会解释/展示一下如何通过ElementarrayBufferbackInPool(…)
实现
?VAO是容器对象,如果在VAO本身未激活时删除绑定到某个对象的缓冲区对象(实际上,VAO跟踪的唯一缓冲区对象绑定是元素缓冲区,顶点指针的工作方式不同),则在移除VAO对该对象的引用之前,缓冲区对象不会被完全删除。如果删除元素缓冲区时VAO处于活动状态,则它将自动解除绑定。在这种情况下,这可能与此相关,但我需要查看实现。您可能可以通过使用0调用
glBufferData(…)
来解决所有问题,并保留一个保留但空的缓冲区名称池以供重用,而不是删除缓冲区对象。这将立即释放数据存储(相对而言),而不必等待所有上下文和容器对象的所有引用都被删除。C++ ANDON M.Celman:池只是C++ C++的简单线程安全包装::vector。我刚刚在这里发布了一段信息摘录:@AndonM.Coleman:谢谢。在将缓冲区扔回池之前,我修改了我的应用程序以提供零大小的缓冲区数据(请参阅上面修改的源代码),但它仍然以同样快的速度泄漏。我并不是说这是一个摆脱元素数组缓冲区悬空引用的解决方案。然而,它所做的是释放与这些缓冲区关联的任何内存(在使用它们的任何挂起的GL操作完成之后)。通过这种方式,即使您的名字到处飘浮,实际上已经丢失了,您也不会浪费任何GPU存储空间。这不是一个完美的解决方案,但它会在你追查真正的罪犯时解决一些问题。在我自己的工作中,我已经完全包装了VAOs和其他OpenGL对象-引擎会隐藏它们的所有状态以便于调试。您是否有机会解释/展示如何通过WelementarrayBufferbackInPool(…)
实现
?VAO是容器对象,如果在VAO本身未激活时删除绑定到某个对象的缓冲区对象(实际上,VAO跟踪的唯一缓冲区对象绑定是元素缓冲区,顶点指针的工作方式不同),则在移除VAO对该对象的引用之前,缓冲区对象不会被完全删除。如果VAO