从应用程序到硬件层面,GUI输出是如何工作的?

12

我正在学习GUI编程并做了一些研究,但现在我并不是很清楚其中的所有内容。 如果我使用GTK+作为工具包,它是如何与显卡通信的?

在Linux系统上,我想它应该是GTK --> X服务器 --(OpenGL)--> 显卡。 这是对的吗?

我读到有些GUI直接绘制OpenGL(例如Blender3D),那么其他应用程序如何绘制它们的GUI?

如果我所知道的唯一用于显卡的API是Direct3D和OpenGL,那么软件渲染和硬件加速之间有什么区别?

能否将执行“软件渲染”的软件直接写入显卡的帧缓冲区,以使OpenGL不受影响?

PS:抱歉问题太多,但我真的不明白这些是如何运作的,感谢每一个回答 :)

2个回答

17

在Linux系统上,我认为应该是 GTK --> X Server --(OpenGL)--> 显卡。这样对吗?

不对。在Linux上,GTK+ 的流程是:


                                              /-[ if direct context ]---\
                     /--> OpenGL >-+---------/                           \
                    /              \-> GLX -+--------------\              \
                   /                         \              \              \
GTK+ -+-> cairo >-+---> XRender >--------+----+-> Xlib/xcb >-+-> X server >-+-> Kernel Module >-> GPU
       \           \–-> pixmap buffer >–/
        \                              /
         \―---------------------------/
我读到一些GUI直接使用OpenGL(例如Blender3D),那其他应用程序如何绘制它们的GUI?
这只是“Blender”(没有后缀3D)。Blender的GUI工具包仅使用OpenGL作为其后端。但是GUI并不是直接使用OpenGL进行绘制,因为这样会非常麻烦(使用OpenGL调用每个按钮并绘制它们)。 Blender拥有自己的工具包。GTK+是另一个工具包,但与Blender无关(事实上,我的其中一个兴趣项目就是提取Blender的GUI工具包,以便可以在独立项目中使用)。
像GTK+和Qt这样的工具包旨在实现最大化的可移植性。 Blender有幸知道OpenGL将可用。针对GTK+或Qt开发的应用程序可能能够在非3D系统上运行,因此GTK+和Qt的设计允许在多种后端上运行。 GTK+现在版本3使用Cairo图形引擎作为图形后端。 Cairo再次有其自己的后端,即绘制进入像素图(像素图像)的软件光栅化器,或者将绘制命令代理到底层图形架构。在Linux上,Cairo可以是OpenGL或X11(核心和XRender协议扩展)之一。
如果我所知道的唯一用于图形卡的API是Direct3D和OpenGL,那么软件渲染和硬件加速之间有什么区别?
OpenGL和Direct3D都不直接与图形卡通信,它们与图形卡的驱动程序通信。因此,您将拥有的选项是绕过OpenGL和Direct3D直接与驱动程序通信。但为什么要这样做呢?这很繁琐。
在Windows上,您还可以使用GDI和/或WPF(Windows Presentation Foundation)来绘制东西,以及Direct2D。
在Linux上,您可以获得X11核心和XRender扩展协议,以绘制漂亮的图片。
另一个正在崛起的API是OpenVG,旨在标准化所有这些2D绘图API。至少在Linux上,OpenGL和OpenVG已被选为长期内唯一可用的抽象绘图API,其中一些窗口系统用于管理帧缓冲区和用户输入。Wayland正在开发中(我完全不喜欢其设计),而X11我认为具有更好的设计(它是一个面向网络的系统,允许分布式执行,这是我认为未来非常重要的一点),但需要进行完全的彻底改革成某种“X12”-清除传统的遗留问题,使它在接触颜色空间中运行,使连接可过渡(这样您就可以在X服务器之间迁移客户端,从而允许更优雅的方式锁定X会话,通过将所有连接移到某个影子X服务器中,而不是尝试使用锁定屏幕保护程序阻止访问)。
如果软件执行“软件渲染”,它是否可以直接写入图形卡的帧缓冲区,以便OpenGL未受影响?
现代操作系统上不能这样做。但是,操作系统可能会通过一些帧缓冲区API(/dev/fb0在Linux上)为您提供对图形卡的抽象访问。但是,帧缓冲区未经管理,因此如果正在运行X服务器或Wayland,则这两者都需要负责管理FB,那么这与您无关。

软件加速和硬件加速有什么区别? - Suraj Jain
我是GUI开发的初学者,你能推荐一本从基础到硬件层面都讲解得很清楚的书吗? - Suraj Jain
最后,据我所知,如果我在C中使用库。那么库中的函数必须能够最终分解为C中的最低级别。我的意思是,如果我在C中使用scanf。它最终会使用C中存在的任何其他函数,并且逐步地,所有东西最终都会沸腾到我们可以在C中获得的最低抽象层。我想问的是,如果我使用cairo库并使用其函数。我能否在不使用任何额外库的情况下绘制GUI。C本身是否可以进行GUI编程? - Suraj Jain
@SurajJain:OpenGL是一种规范。而针对单个硬件的大量C函数组成了该硬件的OpenGL驱动程序。另一块硬件需要不同的驱动程序,这又需要大量的函数,因为它们是为不同的GPU设计的,所以无法重用其他驱动程序的函数。这就是为什么你需要一个统一的API。你不想自己编写所有的东西。这是繁琐、困难的工作。例如,NVidia的OpenGL驱动程序及其所有启发式和边角情况约有100万行代码。 - datenwolf
@SurajJain:各自的函数充当了C代码和架构特定的机器指令之间的一种粘合剂,这些指令需要发送到连接设备的I/O端口。例如,您插入计算机的每个PCI卡都有许多I/O端口,您可以通过向这些端口写入正确的位模式来控制PCI卡。PCI总线在非常低的级别上连接到机器。有关详细信息,建议您简单地查找Linux内核中以“.s”结尾的所有文件,并查看它们的作用。 - datenwolf
显示剩余14条评论

2
软件渲染是否可以直接写入显卡的帧缓冲区,从而不影响OpenGL?这取决于驱动程序。像XServer(或Windows和MacOS的等效物)这样的显示系统不使用API,而是描述API。具体称为驱动程序模型(在XServer的情况下是多个模型之一,如XAA,EXA,UXA和DRI),显示驱动程序必须满足该模型。这些模型未定义的所有内容都必须在“软件”中完成并在CPU上计算。此外,驱动程序可能还会在CPU上计算由模型定义的某些操作。OpenGL曾经完全与这些模型分开。图形驱动程序根本不需要实现OpenGL就可以被操作系统使用。但随着现代操作系统中3D图形和更复杂的合成的不断集成,驱动程序模型开始依赖于与OpenGL和Direct3D相同的范例。例如,WDDM(Windows显示驱动程序模型)要求直接支持Direct3D 9。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接