如何在 2 个进程之间共享 OpenGL context/texture (linux)

How can I share an OpenGL context/texture between 2 processes (linux)

我正在尝试在不同的进程中构建 2 个应用程序 运行。一个应用程序将显示来自摄像机(服务器)的实时视频,另一个应用程序将覆盖 UI(客户端)在该视频之上。该解决方案需要低延迟,因此我想在不通过 OS 合成器的情况下渲染两者。 我试图实现的解决方案涉及创建一个共享的 OpenGL 上下文或纹理,以便 UI 可以将其部分渲染到屏幕外 buffer/texture。 在呈现每个实时图像帧后,服务器可以从屏幕外 buffer/texture 获取信息并将其呈现在顶部。 这样就不会因为进程的同步而增加延迟。如果准备好,服务器将从 UI 获取最新图像。如果它还没有准备好,它不应该等待它,而是使用以前的图像。

如何在进程之间传递纹理或上下文? CreateContext 函数可以获取另一个上下文的指针并使其共享,但据我所知,该地址在进程外无效 space.

如今,在进程之间共享 GPU 资源的“最干净”方式是使用 Vulkan 创建这些资源,将它们导出到文件描述符 (POSIX) 或 HANDLE (Win32) 中,然后将它们导入到创建的 OpenGL 上下文中在两边。您可以通过常用方法传递的文件描述符(sendmsg 和 SCM_RIGHTS,或 pidfd_getfd,或 open("/proc/${PID}/fd/${FD}")

从 Vulkan 导出:

https://www.khronos.org/registry/vulkan/specs/1.2-khr-extensions/html/chap46.html#VK_KHR_external_memory_fd (ff.)

导入 OpenGL:

https://www.khronos.org/registry/OpenGL/extensions/EXT/EXT_external_objects.txt

https://www.khronos.org/registry/OpenGL/extensions/EXT/EXT_external_objects_fd.txt

https://www.khronos.org/registry/OpenGL/extensions/EXT/EXT_external_objects_win32.txt

仅使用“纯”OpenGL 需要大量技巧。一种方法是强制使用间接上下文(以现代功能为代价,因为缺少对这些上下文的 GLX 支持)并为此共享 X11 ID。另一种方法是使用 ptrace 访问其他进程中的映射缓冲区。与设置 Vulkan 实例、在其中创建所有纹理然后将它们导入 OpenGL 相比,要正确实施(BT;DT。),两者都相当艰巨,并且需要做更多的工作。