在两个应用程序之间共享 OpenGL 帧缓冲区/渲染缓冲区
假设我有一个应用程序 A,它负责通过 OpenGL 库在屏幕上绘制内容。出于紧密集成的目的,我想让此应用程序 A
完成其工作,但在 FBO 中渲染或直接在渲染缓冲区中渲染,并允许应用程序 B
具有 只读访问此缓冲区以处理屏幕上的显示(基本上将其渲染为 2D 纹理)。
看来 FBO 属于 OpenGL 上下文,并且上下文在进程之间不可共享。我绝对明白,允许多个进程在相同的上下文中出现两个混乱是邪恶的。但就我的具体情况而言,我认为认为它可能非常安全是合理的。
编辑:
渲染大小接近全屏,我正在考虑 2048x2048 32bits
缓冲区(我现在不使用 Alpha 通道,但为什么以后不使用)。
Let's say I have an application A
which is responsible for painting stuff on-screen via OpenGL
library. For tight integration purposes I would like to let this application A
do its job, but render in a FBO or directly in a render buffer and allow an application B
to have read-only access to this buffer to handle the display on-screen (basically rendering it as a 2D texture).
It seems FBOs belong to OpenGL contexts and contexts are not shareable between processes. I definitely understand that allowing several processes two mess with the same context is evil. But in my particular case, I think it's reasonable to think it could be pretty safe.
EDIT:
Render size is near full screen, I was thinking of a 2048x2048 32bits
buffer (I don't use the alpha channel for now but why not later).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
帧缓冲区对象不能在 OpenGL 上下文之间共享,无论它们是否属于同一进程。但是纹理可以共享,并且纹理可以用作帧缓冲区对象的颜色缓冲区附件。
如果图形系统为这项工作提供 API,那么在进程之间共享 OpenGL 上下文实际上是可能的。对于 X11/GLX,可以在多个进程之间共享间接渲染上下文。在 Windows 中,通过使用一些非常非常粗糙的技巧,这可能是可能的。 MacOS X,不知道该怎么做。
因此,最简单的方法可能是使用像素缓冲区对象来获得对渲染图片的高性能访问。然后通过共享内存将其发送到其他应用程序并将其上传到那里的纹理中(再次通过像素缓冲区对象)。
Framebuffer Objects can not be shared between OpenGL contexts, be it that they belong to the same process or not. But textures can be shared and textures can be used as color buffer attachment to a framebuffer objects.
Sharing OpenGL contexts between processes it actually possible if the graphics system provides the API for this job. In the case of X11/GLX it is possible to share indirect rendering contexts between multiple processes. It may be possible in Windows by emplyoing a few really, really crude hacks. MacOS X, no idea how to do this.
So what's probably the easiest to do is using a Pixel Buffer Object to gain performant access to the rendered picture. Then send it over to the other application through shared memory and upload it into a texture there (again through pixel buffer object).
在 MacOS 中,您可以使用 IOSurface 在两个应用程序之间共享帧缓冲区。
In MacOS,you can use IOSurface to share framebuffer between two application.
根据我的理解,你将无法在 Windows 下的进程之间共享对象,除非它是内核模式对象。即使共享纹理和上下文也会造成性能影响,它也会给您同步 SwapBuffer() 调用的额外责任。特别是在Windows平台下OpenGL的实现是臭名昭著的。
在我看来,您可以依靠进程间通信机制(如事件、互斥体、窗口消息、管道)来同步渲染。但要意识到以这种方式接近需要考虑性能。内核模式对象很好,但每次转换到内核的成本为 100 毫秒。对于高性能渲染应用程序来说,这实在是太昂贵了。我认为你必须重新考虑多进程渲染设计。
In my understanding, you won't be able to share the objects between the process under Windows, unless it's a kernel mode object. Even the shared textures and contexts can create performance hits also it has give you the additional responsibility of syncing the SwapBuffer() calls. Especially under windows platform the OpenGL implementation is notorious.
In my opinion, you can relay on inter-process communication mechanisms like Events, mutex, window messages, pipes to sync the rendering. but just realize that there's a performance consideration on approaching in this way. Kernel mode objects are good but the transition to kernel each time has a cost of 100ms. Which is damns costly for a high performance rendering application. In my opinion you have to reconsider the multi-process rendering design.
在 Linux 上,解决方案是使用 DMABUF,如本博客中所述:https:/ /blaztinn.gitlab.io/post/dmabuf-texture-sharing/
On Linux, a solution is to use DMABUF, as explained in this blog: https://blaztinn.gitlab.io/post/dmabuf-texture-sharing/