我们最初在去年秋季引入了对 dmabufs 和图形卸载的支持,它包含在 GTK 4.14 中。自那以后,发生了一些改进,现在是时候进行更新了。
堆栈底层的改进
GStreamer 1.24版本改进了对显式修饰符的支持,GTK 中的 GStreamer 媒体后端已更新为从 GStreamer 请求 dmabufs。
GStreamer 方面发生的另一件事是,dmabufs 有时会带有填充:在这种情况下,GStreamer 将为我们提供一个带有视口的缓冲区,并期望我们只显示缓冲区的该部分。这有时是必要的,以适应硬件解码器的步幅和大小要求。
GTK 4.14 在卸载时支持此功能,并且只显示视口指示的 dmabuf 部分。
GTK 内部的改进
我们为 GTK 4.14 合并了新的GSK 渲染器。新的渲染器以与旧的 gl 渲染器相同的方式支持 dmabufs。此外,新的 Vulkan 渲染器在渲染到纹理时会生成 dmabufs。
在 GTK 4.16 中,如果 GtkGLArea 小部件可以提供 dmabuf 纹理,它也会提供,因此您可以将其放入 GtkGraphicsOffload 小部件中,以将其输出直接发送到合成器。
您可以在 git main 中的 gtk4-demo 的 shadertoy 演示中看到这一点。

改进的合成器交互
图形卸载的一个好处是,合成器可能能够将 dmabuf 传递给内核的 KMS api,而无需任何额外的复制或合成。这被称为直接扫描输出,它有助于降低功耗,因为 GPU 的大部分区域都不会被使用。
只有当 dmabuf 附加到全屏表面并且具有覆盖它的正确尺寸时,合成器才能执行此操作。如果它没有完全覆盖,合成器需要一些保证,即允许将外部部分留为黑色。
客户端提供该保证的一种方法是将一个专门构造的黑色缓冲区附加到具有 dmabuf 附件的表面之下的表面。如果 GSK 在渲染节点树中找到黑色颜色节点,它现在会执行此操作,并且如果您设置了 “black-background” 属性,GtkGraphicsOffload 小部件会将该颜色放在那里。这应该会大大增加您在播放全屏视频时享受直接扫描输出好处的机会。

在为 GTK 4.16 实现此功能时,我们发现 mutter 对单像素缓冲区的支持存在一些问题,但这些问题已得到快速修复。
要在 GTK4 视频播放器中查看图形卸载和直接扫描输出的实际效果,您可以尝试Light Video Player。
如果您想了解图形卸载是否在您的系统上工作或调试它为什么不工作,Benjamin 最近的这篇文章非常有帮助。
总结
GTK 4 继续改进以实现高效的视频播放,并推动这一领域在堆栈上下层的改进。
非常感谢 Robert Mader 推动这一切向前发展。 ❤️