Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I am trying to build 2 applications running in separate processes. One application will display live video from a camera (server) and the other will overlay UI (client) on top of that video. The solution requires low latency and therefore I would like to render both without going thru the OS compositor. The solution I am trying to implement involves creating a shared OpenGL context or texture so that the UI can render its part to some off screen buffer/texture. After every live image frame is rendered the server can take the information from the off-screen buffer/texture and render it on top. This way there is no latency added due to synchronization of the processes. The server will take the latest image from the UI if one is ready. In case it is not ready it shouldnt wait for it, and use a previous image instead.

How can i pass a texture or context between processes? The CreateContext function can take a pointer of another context and make it shared but the address as far as I understand will not be valid outside the process space.

like image 374
Shachar Avatar asked Jan 28 '21 13:01

Shachar


Video Answer


1 Answers

These days the "cleanest" way to share GPU resources between processes is to create those resources using Vulkan, export them into file descriptors (POSIX) or HANDLEs (Win32) and import those into OpenGL contexts created at either side. The file descriptors you can pass by the usual methods (sendmsg with SCM_RIGHTS, or pidfd_getfd, or open("/proc/${PID}/fd/${FD}").

Exporting from Vulkan:

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

Importing into 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

Doing with just "pure" OpenGL requires a lot of hacks. One way would be to force indirect contexts (at the cost of modern capabilities, due to the lack of GLX support for those) and sharing the X11 IDs for that. Another method is to use ptrace to access to mapped buffers in the other process. Either is quite daunting and a lot more work to properly implement (BT;DT.), than setting up a Vulkan instance, creating all the textures therein and then importing them to OpenGL.

like image 147
datenwolf Avatar answered Oct 18 '22 22:10

datenwolf