0

I am working on a multi threaded OpenGL application with OpenTK 3 and WinForms. I have 2 shared GraphicsContexts:

  • a "main" rendering context, used for scene drawing and synchronous load operations.
  • a "secondary" resource loader context, used to load resources during draw.

This secondary context is used to load video frames coming from a Windows Media Foundation session (with a custom media sink). However, i have no control on what thread this media sink is running on, so i need a way, after each loading operation, to "unbind" that secondary GraphicsContext, so that it can be bound in the next thread where it will be needed.

Do I have to P/Invoke wglMakeCurrent(NULL, NULL) or is there a proper OpenTK way of doing this?

JPSgfx
  • 93
  • 3
  • 9

1 Answers1

1

Short answer

Use OpenTK feature:

mycontext.MakeCurrent(null);

Long answer

Today's wglMakeCurrent doc has eliminated this old comment:

If hglrc is NULL, the function makes the calling thread's current rendering context no longer current, and releases the device context that is used by the rendering context. In this case, hdc is ignored.

I would trust that comment is still valid, due to so many code relying on it.
Pay attention to "releases the device context". Perhaps OpenTK does some action related to the device context. Perhaps the hdc is private (by using window style flag CS_OWNDC) So, let OpenTK handles this "NULL" case.

Better approach

Be aware that even when you use several shared contexts, is the GPU (normally one unique card) that does the loading, and not many cards allow loading while doing other jobs. Thus, it isn't guaranteed you get better performance. But shared contexts exist to this purpose, somehow.

Why should you use the same context in different threads?
I'd use a different thread for load video frames (without any gl-call) and for upload them to the GPU. This last thread is permanent and has its own gl-context, so it doesn't need to set as current every time it works. It sleeps or waits until the other thread has finished loading data, and after that task is completed it uploads that data to the GPU.

genpfault
  • 47,669
  • 9
  • 68
  • 119
Ripi2
  • 6,098
  • 1
  • 12
  • 28
  • Loading in the same thread as the Media Foundation stuff would make managing the buffers easier, as I would have to manage only the OpenGL textures buffer, instead of that and a RAM buffer for texture upload. And thanks for the response, I’ll check this out tomorrow and (if I have permission, (god SO feels like an RPG where one has to lvl up) mark your answer as correct. – JPSgfx Sep 03 '18 at 17:06
  • I haven't tried to map/unmap a buffer in a thread but fill it in another thread. It may suffix. Also, read [OGL wiki streaming](https://www.khronos.org/opengl/wiki/Buffer_Object_Streaming) – Ripi2 Sep 03 '18 at 17:11
  • GraphicsContext.MakeCurrent(null) works like a charm. Thank you! If you want I can report back my texture loading endeavours – JPSgfx Sep 04 '18 at 07:03