multithreadingopenglopentkwgl

OpenTK MultiThreading: How to "unbind" a GraphicsContext


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

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?


Solution

  • 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.