我在使用共享上下文时遇到了问题:
我有两个线程,每个线程都有一个上下文,例如 Thr1(thread1) 与 Ctx1(Context1) 以及 Thr2 和 Ctx2。 Ctx2 是与 Ctx1 共享创建的。
然后,在 Thr2 中,我使用 Ctx2 作为当前上下文创建一些纹理,并进行一些渲染。之后,我销毁 Ctx2 并完成 Thr2。
现在问题出现了:在我销毁Ctx2之后,在Ctx2下创建的纹理没有被释放(是部分纹理,不是全部)。我使用 gDebugger 来分析我的程序,发现这些纹理没有被释放,并列在 Ctx1 下。
当我重复创建 Thr2/Ctx2 并创建纹理并销毁 Thr2/Ctx2 时,纹理越来越多,内存也越来越多。
我尝试过:
在销毁Ctx2之前删除Thr2中的纹理;
在 Thr2 中,将 Ctx1 设置为当前状态,并在 Ctx2 销毁之前尝试删除纹理;
最佳答案
这听起来像是预期的行为。
为了解释具有多个上下文的对象的生命周期,我将使用“池”一词来描述纹理的集合。我认为这个概念没有通用的术语,所以这已经是最好的了。
虽然您通常可能认为纹理由上下文拥有,但它们实际上由池拥有。只要你只有一个背景,那就是学术差异。上下文拥有该池,该池拥有在上下文中创建的所有纹理。当上下文被破坏时,池也会随之消失,这反过来又会破坏池中的所有纹理。
现在,有了两个共享上下文,事情就变得更有趣了。您仍然拥有一个池,两个上下文都共享该池的所有权。当您在两个上下文中的任何一个中创建纹理时,该纹理都归共享池所有。当上下文被删除时,它放弃了它对池的共享所有权。只要至少一个上下文处于事件状态,池(包括池中的所有纹理)就会保持不变。
在您的场景中,上下文 2 创建纹理。该纹理被添加到上下文 1 和上下文 2 共享的池中。然后删除上下文 2。创建的纹理保留在池中。池本身仍然处于事件状态,因为上下文 1(仍然存在)共享池的所有权。这意味着纹理也仍然存在。上下文 2 创建纹理是无关紧要的,因为纹理由池拥有,而不是上下文 2。
因此,如果您确实想要删除纹理,则必须进行 glDeleteTexture()
调用。无论您是在上下文 1 还是上下文 2 中进行此调用都没有关系。
删除共享纹理时存在一些微妙的方面,例如与作为 FBO 附件的纹理有关,或者在一个上下文中删除纹理而在另一个上下文中绑定(bind)的纹理。但由于这不是这个问题的核心,而且有点复杂,我将引用规范了解详细信息(例如,请参见 OpenGL 3.3 规范第 337 页的 D.1.2 节)。
关于opengl - 无法释放共享上下文创建的纹理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29813500/