许多人正在将桌面虚拟化 UI 移植到 GTK4。这通常涉及到 virgl,而 GTK3 的解决方案是使用 GtkGLArea。
对于 GTK4,渲染无论如何都是在 GL 中进行的,因此只需将内容包装在 GdkTexture 中并将其交给 GTK 即可,可以通过将其用作带有 GtkPicture 的可绘制对象,或者在您自己的 snapshot() 实现中使用 GskTextureNode。
dmabuf 绕道
这只是一个美好的理论,但实践起来更加复杂 – 内容通常以 dmabuf 对象的形式提供,并且对于 4k 渲染,如果可以避免额外的复制,那么您真的希望避免。因此,我们不得不研究可用的解决方案,以便在不进行复制的情况下将 dmabufs 作为纹理导入到 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 导入 dmabufs 可以在 GTK 之外正常完成,因此我们不需要为此添加特定于 Linux 的 API。为了避免您自己编写此类代码的麻烦,这里 是我所想到的。
在我们已经决定将 X11 后端移植到 EGL 之后,我了解到另一种导入 dmabufs 的可能性可能是使用 DRI3PixmapFromBuffer 从 dmabuf 创建 X11 pixmap,将其转换为 GLXPixmap 并使用 glxBindTexImageEXT 创建纹理。
图形 API 真是太棒了! :-)