OpenTK 多线程:如何 "unbind" 一个 GraphicsContext

OpenTK MultiThreading: How to "unbind" a GraphicsContext

我正在使用 OpenTK 3 和 WinForms 开发多线程 OpenGL 应用程序。 我有 2 个共享的 GraphicsContext:

此辅助上下文用于加载来自 Windows 媒体基础会话(带有自定义媒体接收器)的视频帧。但是,我无法控制此媒体接收器 运行 在哪个线程上,所以我需要一种方法,在每次加载操作后,到 "unbind" 辅助 GraphicsContext,以便它可以绑定到下一个在需要的地方线程。

我必须 P/Invoke wglMakeCurrent(NULL, NULL) 还是有合适的 OpenTK 方法来做这个?

简答

使用 OpenTK 功能:

mycontext.MakeCurrent(null);

长答案

今天的wglMakeCurrent doc删除了这条旧评论:

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.

我相信评论仍然有效,因为有太多代码依赖它。
关注"releases the device context"。也许 OpenTK 会做一些与设备上下文相关的操作。也许 hdc 是私有的(通过使用 window 样式标志 CS_OWNDC)所以,让 OpenTK 处理这个 "NULL" 案例。

更好的方法

请注意,即使您使用多个共享上下文,也是执行加载的 GPU(通常是一张唯一的卡),并且没有多少卡允许在执行其他工作时加载。因此,不能保证您获得更好的性能。但是共享上下文以某种方式存在于此目的。

为什么要在不同的线程中使用相同的上下文?
我会使用不同的线程来加载视频帧(没有任何 gl 调用)并将它们上传到 GPU。最后一个线程是 permanent 并且有自己的 gl-context,所以它不需要在每次工作时都设置为当前线程。它会休眠或等待,直到另一个线程完成加载数据,并在该任务完成后将数据上传到 GPU。