本页内容

Wayland 与 Qt

Wayland 是作为 Linux 平台上 X11 的替代方案而开发的。其主要目的是管理应用程序的内容如何在共享屏幕上协同显示,以及用户如何与共享同一输入设备的多个应用程序进行交互。

操作系统中的这一角色通常被称为显示服务器。Wayland 显示服务器有时也被称为合成器或窗口管理器,这指的是它作为职责的一部分所执行的特定任务。

下文将简要介绍 Wayland 及其在 Qt 中的作用。有关 Wayland 本身的更多详细信息和背景知识,请参阅官方文档。

什么是显示服务器

显示服务器是操作系统中负责管理屏幕空间及其他共享资源的组件。在典型的桌面系统中,可能会有许多独立的应用程序同时运行,每个应用程序都期望能够将图形渲染到屏幕上并接收输入。

显示服务器是应用程序与屏幕、输入设备等共享资源之间的桥梁。 桌面系统中的典型显示服务器会将应用程序内容放置在独立的矩形“窗口”中,用户可以移动和调整这些窗口的大小。显示服务器确保应用程序内容在屏幕上的正确位置显示,确保活动窗口能够接收来自键盘的输入,确保重叠的窗口按正确顺序绘制,等等。

在其他类型的系统中,显示服务器的限制可能更多。例如,如果屏幕是汽车的仪表盘或叉车的控制面板,那么移动和调整窗口大小可能并不合适。相反,每个应用程序可能会被锁定在屏幕的预定义区域内,并从预先分配的设备接收输入。

无论哪种情况,只要存在多个相互隔离的进程在争夺相同的资源,显示服务器就很有用。

Wayland 的作用

“Wayland”这一名称可能指代以下几个相关概念:

  • 一套用于显示服务器与其客户端之间通信的协议。
  • 一个用 C 语言编写的库,包含用于进程间通信的函数,是实现上述协议的基础。
  • 一种基于XML的语言,用于扩展该协议,同时也是一种工具,可据此生成C语言的绑定代码。

Qt 为该协议的客户端和服务器端均提供了实现。

通过选择“wayland” QPA 插件(在某些系统上这是默认设置),普通 Qt 应用程序可在 Wayland 显示服务器上作为客户端运行。您可以通过使用-qpa wayland 选项来实现这一点。此外, Qt Wayland Compositor 模块还可用于开发显示服务器本身。

Qt 还提供了便捷功能,可轻松通过新接口扩展 Wayland 协议。

Wayland 与其他技术

在 Linux 桌面上,Wayland 是 X11 及其相关扩展的替代方案。其核心是一个合成显示服务器,因此“合成器”(compositor)一词常被用来描述 Wayland 服务器。 这意味着客户端会将内容渲染到屏幕外的缓冲区中,随后该内容将与屏幕上其他客户端的内容进行“合成”,从而实现阴影、透明度、背景模糊等窗口特效。

原始 X11 协议的一项重要设计原则是:显示服务器可以在仅配备屏幕和输入设备的瘦终端上运行。其客户端则运行在具有更强处理能力的远程系统上,并通过网络连接与服务器通信。

相比之下,Wayland 的设计基于这样一种观察:在现代配置中,客户端和显示服务器通常运行在同一台硬件上。分布式计算、远程存储和远程桌面功能通常通过其他机制来处理。 将这一特性设计到协议中,使得客户端和服务器之间能够共享图形内存:当合成器将客户端内容放置到屏幕上时,只需将其从图形内存的一个区域复制到另一个区域即可。

为了使该机制发挥最佳效果,图形驱动程序必须支持 Wayland。这种支持是通过EGL 的一个名为EXT_platform_wayland 的扩展提供的。

注意:Qt Wayland 还支持在不支持EXT_platform_wayland 的系统上进行合成处理,方法是通过XComposite ,或者将应用程序内容复制到共享的 CPU 内存中。但为了获得最佳性能,我们建议使用支持相关驱动程序的系统。

X11 已通过扩展支持合成和直接渲染等功能,但 Wayland 则是从底层开始专为这些用例设计的。与 X11 随时间推移逐渐变得日益复杂不同,Wayland 旨在保持轻量且可扩展。

可扩展性与嵌入式系统

由于 Wayland 核心轻量且易于扩展,因此在构建嵌入式 Linux 平台时,它是一个理想的工具。

例如,桌面风格的窗口系统功能并不属于核心协议的一部分。相反,Wayland 提供了一类名为“shell”的特殊协议扩展,用于让客户端管理其显示区域。 桌面风格的功能是通过名为XDG Shell 的shell提供的。对于其他类型的系统,可以使用更专业(或许也更受限制)的“shell”。例如,在构建In-Vehicle Infotainment 系统时,IVI Shell 可能更合适。

当客户端连接时,Wayland 服务器会广播其支持的协议(或“接口”)列表,客户端可绑定至其希望使用的协议。这些可以是任何标准接口,但新增扩展也非常简单。 Wayland 定义了一种易于理解的 XML 格式来定义协议,并可使用waylandscanner 工具根据这些协议生成 C 代码。(在 Qt 中,我们还提供了qtwaylandscanner ,它可生成额外的 C++ 绑定代码。)

客户端绑定到接口后,即可向服务器发出“请求”,服务器也可向客户端发送“事件”。这些请求和事件及其参数,均在描述该协议的 XML 文件中定义。

对于从零开始构建平台的情况,当您同时控制服务器和客户端的代码时,添加扩展是一种简单且可控的方式,用于增加操作系统功能。

多进程还是单进程

在使用 Qt 构建简单的嵌入式平台时,让用户界面的所有组件都在单个进程中运行是一个完全可行的选择。然而,随着系统变得越来越复杂,你可能需要考虑改用多进程系统。这就是 Wayland 派上用场的地方。 使用 Qt 时,在开发过程的任何阶段,你都可以选择在单进程和多进程之间切换。

多进程的优势

下图展示了多进程系统与单进程系统之间的区别。

多进程 Wayland 客户端架构图

多进程客户端架构

单进程 EGLFS 客户端架构图

单进程客户端架构

该 Qt Wayland Compositor 模块非常适合在嵌入式 Linux 的多进程系统中创建显示服务器和合成器。采用多进程架构具有以下优点:

稳定性
当客户端挂起或崩溃时,更容易恢复如果您的用户界面较为复杂,那么多进程架构就非常有用,因为即使用户界面的某一部分发生崩溃,也不会影响整个系统。同样地,即使某个客户端卡死,界面也不会冻结。

注意:如果 法律规定您的客户端必须呈现安全关键信息,请考虑使用 Qt Safe Renderer。

防范潜在的内存泄漏在多进程系统中,如果某个客户端出现内存泄漏并消耗大量内存,该内存会在该客户端退出时被回收。这与单进程系统不同,在单进程系统中,内存泄漏会一直存在,直到整个系统重启为止。
安全性
在单进程系统中,所有客户端都可以访问彼此的内存。例如,敏感数据传输没有隔离机制;每一行代码都必须同样值得信赖。而在多进程系统中,这种隔离机制是设计使然。
性能
如果您的 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 可能并非最佳选择:

  1. 硬件或平台较旧且仅支持 X11;在这种情况下,您别无选择。
  2. 您必须支持那些依赖于 Wayland 协议因安全性和简洁性考量而未提供的功能的旧版应用程序。
  3. 必须支持使用完全无法在 Wayland 上运行的用户界面工具包的旧版应用程序。在某些情况下,您可以通过在XWayland上运行这些应用程序来解决此问题。

在 X11 非常流行的时候,开发者曾编写自己的自定义解决方案来规避 X11 存在的问题。早期版本的 Qt 曾包含 Qt 窗口系统(QWS),但该系统现已停止维护。如今,Wayland 已能覆盖其中大多数用例,自定义解决方案也越来越少见。

Qt Wayland 提供的功能

针对客户端
Qt 客户端可以在任何 Wayland 合成器上运行,包括作为 Wayland 项目一部分开发的参考合成器 Weston。

任何 Qt 程序均可作为 Wayland 客户端(作为多进程系统的一部分)或独立客户端(单进程)运行。这由启动时的选择决定,您可在启动时在不同的后端之间进行选择。在开发过程中,您可以先在桌面上开发客户端,随后在目标硬件上进行测试。 您无需始终在实际的目标硬件上运行客户端。

单进程 Wayland 客户端开发环境的示意图

单进程客户端开发

如果您在 Linux 机器上进行开发,还可以在开发机上的窗口中运行合成器。这使您能够在与目标设备高度相似的环境中运行客户端。无需重新构建客户端,您还可以使用 `-platform wayland ` 命令将其在合成器内部运行。 如果您使用-platform xcb (适用于 X11),则可以在桌面上运行客户端。换言之,您可以在合成器准备就绪之前就开始开发客户端。

关于服务器
服务器(即合成器)连接到显示器,并在屏幕上显示每个客户端的内容。合成器处理输入并将输入事件发送给相应的客户端。反过来,每个客户端连接到合成器并发送其窗口的内容。由合成器决定:

  • 如何以及在何处显示内容
  • 显示哪些内容
  • 如何处理不同的客户端图形缓冲区

这意味着,由合成器来决定什么是多进程系统。例如,客户端可以是3D场景的一部分,其窗口位于墙壁上;也可以位于VR系统中;还可以映射到一个球体上,等等。

该 Qt Wayland Compositor 是一个用于构建自定义合成器的API。它赋予您完全的自由,可构建自定义的合成器用户界面并管理各个客户端的窗口。您可以将Qt Quick 和QML与Qt Wayland Compositor 相结合,创建令人印象深刻且富有创意的用户界面。更多信息,请参阅 Qt Wayland Compositor。

Qt 还提供了功能强大且易于使用的 API,用于实现 Wayland 扩展,并可在 Qml 或 C++ 中调用这些扩展。

© 2026 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.