无法释放由共享上下文创建的纹理

Can't release textures created by a shared context

我在使用共享上下文时遇到问题:

我有两个线程,每个线程都有一个上下文,比如 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 被销毁之前;

这听起来像是预期的行为。

为了解释具有多个上下文的对象的生命周期,我将使用 "pool" 这个词来描述纹理集合。我不认为这个概念有通用的术语,所以这和任何东西一样好。

虽然您通常可能将纹理想象为由上下文拥有,但它们实际上由池拥有。只要你只有一个上下文,那就是学术差异。上下文拥有池,池拥有在上下文中创建的所有纹理。当上下文被销毁时,池也会随之消失,这又会破坏池中的所有纹理。

现在,有了两个共享上下文,事情就变得更有趣了。您仍然有 one 池,两个上下文共享所有权。当您在两个上下文中的任何一个中创建纹理时,该纹理都归共享池所有。当一个上下文被删除时,它放弃了它对池的共享所有权。只要至少有一个上下文处于活动状态,池(包括池中的所有纹理)就会一直存在。

在您的场景中,上下文 2 创建了一个纹理。该纹理被添加到上下文 1 和上下文 2 共享的池中。然后删除上下文 2。创建的纹理保留在池中。池本身保持活动状态,因为上下文 1(仍然存在)共享池的所有权。这意味着纹理也仍然存在。上下文 2 创建纹理是无关紧要的,因为纹理归池所有,而不是上下文 2 所有。

因此,如果您真的想删除纹理,则必须进行 glDeleteTexture() 调用。无论您是在上下文 1 还是上下文 2 中进行此调用都没有关系。

共享纹理被删除时有一些微妙的方面,例如与作为 FBO 附件的纹理相关,或者纹理在一个上下文中被删除而在另一个上下文中被绑定。但由于这不是这个问题的核心,而且有点复杂,我将参考规范了解详细信息(例如,参见 OpenGL 3.3 规范第 337 页的 D.1.2 节)。