Wayland 和 Qt
Wayland 是作为 Linux X11 的替代方案而开发的。其主要目的是管理如何在共享屏幕上一起显示应用程序的内容,以及用户如何与共享相同输入设备的多个应用程序进行交互。
操作系统中的这一角色通常被称为显示服务器。Wayland 显示服务器有时也被称为合成器和窗口管理器,指的是它作为其职责的一部分所执行的特定任务。
下面,我们将简要介绍 Wayland 及其在 Qt 中的作用。有关 Wayland 本身的更多细节和背景,请参阅官方文档。
什么是显示服务器
显示服务器是操作系统中管理屏幕空间和其他共享资源的部分。在典型的桌面系统中,可能有许多独立的应用程序同时运行,每个应用程序都希望能向屏幕呈现图形并接收输入。
显示服务器是应用程序与屏幕和输入设备等共享资源之间的纽带。桌面系统上典型的显示服务器会将应用程序内容放置在不同的矩形 "窗口 "中,用户可以移动和调整窗口大小。显示服务器确保应用程序内容显示在屏幕的正确位置,活动窗口接收键盘输入,重叠窗口按正确顺序绘制,等等。
在其他类型的系统中,显示服务器的限制可能会更多。例如,如果屏幕是汽车仪表板或叉车的控制面板,那么就不需要移动和调整窗口大小。相反,每个应用程序都可能被锁定在屏幕的一个预定区域内,并接收来自预定设备的输入。
无论采用哪种方式,只要有多个独立进程在争夺相同的资源,显示服务器都是有用的。
Wayland 的作用
Wayland的名称可能指几个相关的项目:
- 一套用于在显示服务器与其客户端之间进行通信的协议。
- 一个用 C 语言编写的库,包含用于进程间通信的函数,是实施上述协议的基础。
- 一种用于扩展协议的基于 XML 的语言,以及一种用于根据此类扩展生成 C 语言绑定代码的工具。
Qt 为协议的客户端和服务器端提供了实现方法。
通过选择 "wayland "QPA 插件(某些系统的默认设置),普通 Qt 应用程序可作为客户端在 Wayland 显示服务器上运行。此外,该 Qt Wayland Compositor模块可用于开发显示服务器本身。
Qt 还具有方便的功能,可通过新的接口轻松扩展 Wayland 协议。
Wayland 和其他技术
在 Linux 桌面上,Wayland 是 X11 和相关扩展的替代方案。它的核心是一个合成显示服务器,"合成器 "一词经常被用来描述 Wayland 服务器。这意味着客户端会将内容渲染到屏幕外的缓冲区中,随后与屏幕上的其他客户端 "合成",从而实现阴影、透明、背景模糊等窗口效果。
原始 X11 协议的一个重要设计原则是,显示服务器可以运行在一个只有屏幕和输入设备的瘦终端上。客户端则运行在处理能力更强的远程系统上,通过网络连接与服务器通信。
相比之下,Wayland 在设计时考虑到,在现代设置中,客户端和显示服务器通常运行在相同的硬件上。分布式计算、远程存储和远程桌面功能通常通过其他机制处理。将这一功能设计到协议中,可实现客户端和服务器之间共享图形内存:当合成器在屏幕上放置客户端内容时,只需将其从图形存储器的一部分复制到另一部分即可。
要实现最佳效果,图形驱动程序必须支持 Wayland。该支持通过EGL
的扩展提供,扩展名为EXT_platform_wayland
。
注: 在不支持EXT_platform_wayland
的系统上,Qt Wayland 也支持合成,可通过XComposite
或将应用程序内容复制到共享 CPU 内存。但为了获得最佳性能,我们建议使用支持驱动程序的系统。
X11 已被扩展以支持合成和直接渲染等功能,但 Wayland 从一开始就是围绕这种用例设计的。此外,Wayland 还力求小巧、可扩展,这与 X11 随着时间推移而产生的复杂性形成鲜明对比。
可扩展性和嵌入式系统
由于 Wayland 的内核最小且易于扩展,因此是构建嵌入式 Linux 平台的理想工具。
例如,桌面风格的窗口系统功能并不是核心协议的一部分。相反,Wayland 有一类特殊的协议扩展,称为 "shell",为客户端提供了一种管理其表面的方法。桌面风格的功能通过名为XDG Shell
的外壳提供。对于其他类型的系统,可以使用更专业(也许限制性更强)的 "shell"。例如,在制作In-Vehicle Infotainment 系统时,最好使用IVI Shell
。
当客户端连接时,Wayland 服务器会广播其支持的协议(或 "接口")列表,客户端可以绑定其希望使用的协议。这可以是任何一个标准接口,但也很容易添加新的扩展。Wayland 定义了一种易于理解的 XML 格式来定义协议,waylandscanner
工具可用于根据这些协议生成 C 代码。(在 Qt XML 中,我们还可以使用qtwaylandscanner
生成额外的 C++ 绑定代码)。
客户端绑定接口后,可以向服务器发出 "请求",服务器也可以向客户端发送 "事件"。请求和事件以及它们的参数都在描述协议的 XML 文件中定义。
对于从零开始构建平台的用户来说,如果服务器和客户端的代码都由自己控制,那么添加扩展功能就是一种简单、可控的操作系统功能添加方式。
多进程或单进程
当使用 Qt 构建一个简单的嵌入式平台时,一个完全可行的选择是在单进程中运行用户界面的所有部分。不过,当系统变得越来越复杂时,您可能需要考虑使用多进程系统。这就是 Wayland 的用武之地。有了 Qt,在开发过程中的任何时候,您都可以选择在单进程和多进程之间切换。
多进程的优势
下图说明了多进程和单进程系统之间的区别。
多进程客户端架构
单进程客户端架构
该 Qt Wayland Compositor模块是在嵌入式 Linux 多进程系统中创建显示服务器和合成器的理想选择。使用多进程有以下好处:
稳定性 | |
---|---|
客户端挂起或崩溃时更容易恢复 | 如果您有一个复杂的用户界面,那么多进程就非常有用,因为如果用户界面的某个部分崩溃,也不会影响整个系统。同样,即使一个客户端死机,显示屏也不会冻结。 注意: 如果法律规定您的客户端必须提供对安全至关重要的信息,请考虑使用Qt Safe Renderer Overview。 |
防止可能的内存泄漏 | 在多进程系统中,如果一个客户端出现内存泄漏并消耗大量内存,那么该客户端退出时内存就会恢复。与单进程相比,内存泄漏会一直存在,直到整个系统重新启动。 |
安全性 |
---|
在单进程系统中,所有客户端都可以访问彼此的内存。例如,敏感数据传输没有隔离;每一行代码都必须同样可信。在多进程系统中,这种隔离是设计出来的。 |
性能 |
---|
如果 CPU 有多个内核,多进程系统可以帮助将负载平均分配给不同的内核,从而更有效地利用 CPU。 |
互操作性 |
---|
只要你的客户端能理解 Wayland 或 X11,你就能在多进程系统中与非 Qt 客户端进行交互。例如,如果您使用 gstreamer 来播放视频,或者您想使用使用其他 UI 工具包构建的导航应用程序,您就可以在运行其他基于 Qt 的客户端的同时运行这些客户端。 |
多进程的权衡
从单进程转向多进程时,必须注意以下权衡:
视频内存消耗增加 |
---|
对于嵌入式设备来说,这可能是一个限制因素。在多进程中,每个客户端都需要有自己的图形缓冲区,并将其发送给合成器。因此,与单进程情况相比,您需要使用更多的视频内存:在单进程情况下,所有内容都是一次性绘制,无需将不同部分存储在中间缓冲区中。 |
主内存消耗增加 |
---|
除了操作系统层面的一些额外开支外,运行多个客户端还可能会占用更多的主内存,因为有些部分需要在每个客户端重复一次。例如,如果运行 QML,每个客户端都需要一个单独的 QML 引擎。因此,如果运行一个使用Qt Quick Controls 的客户端,只需加载一次。如果将该客户端拆分为多个客户端,则需要多次加载Qt Quick Controls ,从而导致客户端初始化的启动成本较高。 |
图形资源的重复存储 |
---|
在单进程系统中,如果在多个地方使用相同的纹理、背景或图标,这些图像只需存储一次。相反,如果在多进程系统中使用这些图像,则必须多次存储。在这种情况下,一种解决方案是在客户端之间共享图形资源。Qt 已经允许跨进程共享主内存中的图像资源,而不涉及 Wayland。而跨进程共享 GPU 纹理则需要更复杂的解决方案。在 Qt 中,这种解决方案可以作为 Wayland 扩展协议进行开发,例如使用QQuickImageProvider 。 |
输入到光子的延迟 |
---|
在单进程系统中,应用程序直接访问主帧缓冲区。这意味着在这种设置下,输入事件与将其反映到屏幕上之间的延迟可以降到最低。在多进程系统中,应用程序内容必须采用三重缓冲,以确保客户端不会在服务器读取缓冲区内容的同时向其中绘制内容,因为这样会导致撕裂。这意味着多进程系统中存在隐性延迟。 |
为何使用 Wayland 而非 X11 或自定义解决方案
如前所述,X11 并不是当今典型系统设置的最佳选择。它相当庞大和复杂,而且缺乏定制能力。事实上,使用 X11 很难流畅地运行客户端,也很难达到 60 fps 而不撕裂。相比之下,Wayland 更容易实现,性能更好,而且包含在现代图形硬件上高效运行所需的所有部件。对于 Linux 上的嵌入式多进程系统,Wayland 是标准配置。
不过,如果你使用的是旧硬件或传统应用程序,那么 Wayland 可能不是一个好选择。Wayland 协议在设计时考虑到了安全性和隔离性,并对客户端可使用的信息和功能进行了严格/保守的规定。虽然这样能带来更简洁、更安全的界面,但传统应用程序所期望的某些功能在 Wayland 上可能不再可用。
特别是在三种常见的使用情况下,Wayland 可能不是最佳选择:
- 硬件或平台老旧,仅支持 X11;在这种情况下,你别无选择。
- 你必须支持那些依赖于 Wayland 协议所不具备的安全和简单特性的旧版应用程序。
- 你必须支持使用完全无法在 Wayland 上运行的 UI 工具包的传统应用程序。在某些情况下,您可以通过在XWayland上运行这些应用程序来解决这个问题。
在 X11 非常流行的时候,开发人员会编写自己的自定义解决方案来规避 X11 问题。旧版本的 Qt 有 Qt 视窗系统 (QWS),但现已停产。如今,Wayland 已经涵盖了大部分这些用例,自定义解决方案也越来越少。
Qt Wayland 提供的功能
对于客户端
Qt客户端可以在任何 Wayland 合成器上运行,包括作为 Wayland 项目一部分开发的参考合成器 Weston。
任何 Qt 程序都可以作为 Wayland 客户端(多进程系统的一部分)或独立客户端(单进程)运行。这将在启动时确定,您可以在不同的后端之间进行选择。在开发过程中,可以先在桌面上开发客户端,然后再在目标硬件上测试。您不需要一直在实际的目标硬件上运行客户端。
单进程客户端开发
如果在 Linux 机器上进行开发,还可以在开发机器的窗口中运行合成器。这样就能在与目标设备非常相似的环境中运行客户端。在不重建客户端的情况下,也可以使用-platform wayland
在合成器内运行客户端。如果使用-platform xcb
(X11),则可以在桌面上运行客户端。换句话说,您可以在合成器准备就绪之前就开始开发客户端。
对于服务器
服务器或合成器连接到显示器,并在屏幕上显示每个客户端的内容。合成器处理输入,并将输入事件发送到相应的客户端。反过来,每个客户端连接到合成器并发送其窗口的内容。这取决于合成器的决定:
- 如何以及在何处显示内容
- 显示哪些内容
- 如何处理不同的客户端图形缓冲区
这意味着,什么是多进程系统取决于合成器。例如,客户端可以是三维场景的一部分,可以是墙壁上的窗户,也可以是 VR 系统上的窗户,还可以是映射到球体上的窗户等等。
多进程 Qt Wayland Compositor是一个用于构建自己的合成器的应用程序接口。它能让你完全自由地创建自定义合成器用户界面并管理不同客户端的窗口。您可以将Qt Quick 和 QML 与Qt Wayland Compositor 结合起来,创建令人印象深刻、富有想象力的用户界面。更多信息,请参阅 Qt Wayland Compositor.
Qt 还提供了功能强大、用户友好的 API 来实现 Wayland 扩展,并从 QML 或 C++ 中使用它们。
相关内容
© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.