图形 API 探险之旅

许多人正在努力将桌面虚拟化 UI 移植到 GTK4。这通常涉及 virgl,而 GTK3 的解决方案是使用 GtkGLArea。

在 GTK4 中,渲染无论如何都会在 GL 中进行,因此只需将您的内容包装在 GdkTexture 中,并将其交给 GTK 即可,可以通过将其作为 GtkPicture 的可绘制对象,或在您自己的 snapshot() 实现中使用 GskTextureNode。

dmabuf 绕行

这只是一个美好的理论,但实践起来更为复杂 – 内容通常以 dmabuf 对象的形式提供,并且对于 4k 渲染,如果可以避免额外的复制,您真的会希望这样做。 因此,我们不得不研究可用的解决方案,以便在不复制的情况下将 dmabuf 作为纹理导入到 GL 中。

这变成了一场图形 API 迷宫的快速游览:OpenGL、EGL、GL ES、GLX、DRI,等等。最后,我们发现您可以使用 EGL 将 dmabuf 包装到 EGLImage 中,并使用 GL_OES_EGL_image 扩展从中创建 GL 纹理。

GLX 到 EGL

这在我们的 Wayland 后端(使用 EGL)中工作正常。不幸的是,我们更旧的 X11 后端使用 GLX 实现 GL,而且似乎没有办法将 dmabuf 导入到 GLX 上下文中。

所以我们不得不做一些额外的工作,让我们的 X11 后端也使用 EGL。值得庆幸的是,Emmanuele 几年前有一个未完成的分支,其中包含这样的转换,该分支可以工作(在一些最初的抓耳挠腮之后,为什么它不渲染任何东西——当进行 GL 工作时总是这样)。

解决方案

事实证明,使用 EGL 导入 dmabuf 可以很好地在 GTK 之外完成,因此我们不需要为其添加 Linux 特定的 API。为了避免您自己编写此类代码的麻烦,这里 是我提出的代码。

在我们已经决定将 X11 后端移植到 EGL 之后,我了解到导入 dmabuf 的另一种可能性可能是使用 DRI3PixmapFromBuffer 从 dmabuf 创建 X11 像素映射,将其转换为 GLXPixmap 并使用 glxBindTexImageEXT 来生成纹理。

图形 API 不是都很棒吗! :-)