Bicubic's picture

Disposing textures and other resources

I'm not sure if I missed something, but it seems like OpenTK doesn't allow threads other than the creator to work with resources like textures.
While implementing a higher level texture class I found that calling GL.DeleteTextures in the destructor resulted in the following crash when the GC hit them: "No context is current in the calling thread (ThreadId: 2)."

Is there a way to set the current context for the thread? If there is no way to dispose of these resources like this, it might be nice to have the GameWindow class take a list of resources to dispose and do it in the main loop, so that the destructors won't dispose of the resources straight away but tell the GameWindow to do it asap. That's what I will be doing if there is no better known way.


Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
nythrix's picture

I think, the GameWindow can't do it because it needn't be used on every project.

Releasing resources is a topic older than Jupiter. See here for a related discussion.

zahirtezcan's picture
Bicubic wrote:

...I found that calling GL.DeleteTextures in the destructor resulted in the following crash when the GC hit them: "No context is current in the calling thread (ThreadId: 2)."

Destructors are called by the .Net Runtime finalizer thread. You should not do anything regarding OpenGL on the finalizer thread. Please refer to .Net documentation on dispose pattern.
First of all, being called by a finalizer means that object is not referenced. I'd rather hold references to my resource classes(some kind of resource manager) and dispose them explicitly. Ok, but how to clean resources that are not disposed explicitly?-> Memory profiler.

the Fiddler's picture

This is an OpenGL limitation, actually. OpenTK itself is a low-level library that is not aware of concepts like textures or how to dispose them.

The solution, of course, is to add a resource manager to your application that can dispose resources when no longer needed. The exact implementation is application-specific: for example, you could subclass GameWindow and provide a thread-safe "DisposeResource()" method that would add the resource to a list. An UpdateFrame handler could then visit this list and clean it periodically.

Bicubic's picture
Quote:

for example, you could subclass GameWindow and provide a thread-safe "DisposeResource()" method that would add the resource to a list. An UpdateFrame handler could then visit this list and clean it periodically.

Just what I was thinking. Thanks.