Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can't release textures created by a shared context

I met a problem using shared contexts:

I have two threads and each has one context, say Thr1(thread1) with Ctx1(Context1) and Thr2 and Ctx2. Ctx2 was created sharing with Ctx1.

Then, in Thr2, I create some textures with Ctx2 as current context, and do some rendering. After that, I destroy the Ctx2 and finish Thr2.

Now the problem arised: after I destroy the Ctx2, the textures created under the Ctx2 not released(Some of then, not all). I use gDebugger to profile my program, and see that, these textures are not released, and listed under Ctx1.

As I repeat create Thr2/Ctx2 and create textures and destroy Thr2/Ctx2, the textures are getting more and more, as well as the memory.

What I have tried:

Delete the textures in Thr2 before destroy Ctx2;

In Thr2 make Ctx1 as current and try to delete the textures, before Ctx2 is destroy;

like image 996
CurtisGuo Avatar asked Apr 23 '15 04:04

CurtisGuo


1 Answers

This sounds like expected behavior.

To explain the lifetime of objects with multiple contexts, I'm going to use the word "pool" to describe a collection of textures. I don't think there's universal terminology for the concept, so this is as good as anything.

While you may normally picture textures being owned by a context, they are in fact owned by a pool. As long as you just have a single context, that's an academic difference. The context owns the pool, the pool owns all the textures that were created in the context. When the context is destroyed, the pool goes away with it, which in turn destroys all textures in the pool.

Now, with two sharing contexts, things get more interesting. You still have one pool, which both contexts have shared ownership for. When you create a texture in any one of the two contexts, the texture is owned by the shared pool. When a context is deleted, it gives up its shared ownership of the pool. The pool (including all textures in the pool) stays around as long as at least one of the contexts is alive.

In your scenario, context 2 creates a texture. This texture is added to the pool shared by context 1 and context 2. Then you delete context 2. The created texture remains in the pool. The pool itself remains alive because context 1 (which still exists) has shared ownership of the pool. This means that the texture also remains alive. It is irrelevant that context 2 created the texture, since the texture is owned by the pool, not by context 2.

Therefore, if you really want to delete the texture, you'll have to make a glDeleteTexture() call. It does not matter if you make this call in context 1 or context 2.

There are some subtle aspects when shared textures are deleted, related for example to textures being FBO attachments, or textures being deleted in one context while being bound in another context. But since this is not at the core of this question, and it's somewhat complicated, I'll refer to the spec for the details (see for example section D.1.2 on page 337 of the OpenGL 3.3 spec).

like image 176
Reto Koradi Avatar answered Oct 15 '22 22:10

Reto Koradi