2. Linux 图形栈全景:从应用程序到显示硬件的完整数据流

在深入 Weston 合成器与 KMS 框架配置之前,必须先建立 Linux 图形栈的整体视图。本章将剖析一条完整的显示数据流:从应用程序调用图形 API 开始,经过合成器调度、内存管理,最终通过 KMS 驱动将像素输出到物理显示器。理解这一全景是后续配置与调试的基础。

2.1 图形栈层次结构总览

Linux 图形栈自底向上可分为四层:硬件层、内核层、合成器/窗口管理层、应用层。每一层都承担特定的职责,并通过标准接口与相邻层通信。

核心要点:DRM/KMS 是内核空间的标准显示框架;GEM 负责显存管理;Wayland 是应用与合成器之间的通信协议;Weston 是 Wayland 协议的参考合成器实现。这四个组件构成了现代嵌入式 Linux 显示系统的软件支柱。
Linux 图形栈四层架构 Linux 图形栈四层架构 应用层 (Application Layer) Qt / GTK / SDL / 嵌入式 GUI 应用 合成器 / 窗口管理层 (Compositor / WM) Weston / Mutter / KWin / Sway 内核层 (Kernel Layer) DRM Core / KMS / GEM / DMA-BUF GPU 驱动 (i915 / msm / vc4 / etnaviv) 硬件层 (Hardware Layer) GPU / Display Controller / HDMI / LVDS / DSI 核心接口 DRM / KMS / GEM

2.2 核心组件层次关系

在图形栈中,DRM/KMS、GEM、Wayland 和 Weston 四个组件分别处于不同层级,它们之间的协作关系决定了显示系统的整体行为。

组件 全称 层级 核心职责
DRM Direct Rendering Manager 内核层 提供 GPU 和显示控制器的统一访问接口,管理显示资源(CRTC、Encoder、Connector、Plane)
KMS Kernel Mode Setting 内核层(DRM 子模块) 负责显示模式设置(分辨率、刷新率、像素时钟)、帧缓冲管理和页面翻转
GEM Graphics Execution Manager 内核层(DRM 子模块) 管理显存分配、释放、共享和同步,支持 DMA-BUF 跨设备共享
Wayland Wayland Protocol 协议层(应用与合成器之间) 定义应用(Client)与合成器(Compositor)之间的通信协议,取代 X11
Weston Weston Compositor 合成器层 Wayland 协议的参考实现,负责窗口管理、合成渲染、输入事件分发
层次关系速记:Weston 通过 Wayland 协议接收应用的图形缓冲区,然后调用 DRM/KMS 接口将这些缓冲区合成并输出到显示器。GEM 负责管理这些缓冲区在显存中的生命周期。简言之:应用 → Wayland → Weston → DRM/KMS/GEM → 硬件。

2.3 完整数据流:从应用像素到屏幕像素

一条完整的显示数据流包含以下关键步骤。理解每一步的参与者与数据载体,是调试显示问题的前提。

  1. 应用渲染:应用程序(如 Qt 或 GTK 应用)使用 OpenGL ES / Vulkan 或软件渲染,将内容绘制到 Wayland 共享缓冲区(wl_buffer)中。
  2. 缓冲区提交:应用通过 Wayland 协议将缓冲区句柄提交给 Weston 合成器,并附带窗口属性(位置、大小、透明度等)。
  3. 合成器接收:Weston 接收来自多个应用的缓冲区,使用 GPU 或 CPU 进行合成(Compositing),生成最终的帧缓冲区。
  4. GEM 管理:合成过程中,所有缓冲区都通过 GEM 分配在显存中,DMA-BUF 机制允许不同设备(如 GPU 与显示控制器)共享同一块物理内存。
  5. KMS 提交:Weston 将合成后的帧缓冲区通过 DRM/KMS 的 drmModeAtomicCommit 或 drmModePageFlip 提交给内核。
  6. 硬件扫描输出:KMS 驱动配置 CRTC(显示控制器)从指定帧缓冲中读取像素数据,经过 Encoder 编码,通过 Connector 输出到物理显示器。
显示数据流完整流程 显示数据流完整流程 应用 渲染 wl_buffer Wayland 协议 提交缓冲区 Weston 合成帧缓冲 DRM/KMS Atomic Commit GEM 显存管理 DMA-BUF 跨设备共享 显示硬件 扫描输出 数据流关键路径 应用 → Wayland → Weston → DRM/KMS → 硬件 GEM 和 DMA-BUF 在 Weston 与内核之间提供显存管理支持

2.4 DRM/KMS 核心对象模型

DRM/KMS 在内核中维护了一套标准化的显示对象模型。Weston 通过操作这些对象来完成显示配置。理解这些对象是编写或调试 KMS 代码的基础。

对象 描述 关键属性
CRTC 显示控制器,负责从帧缓冲读取数据并生成视频时序 分辨率、刷新率、扫描模式、关联的 Plane
Encoder 编码器,将 CRTC 输出的数字信号转换为特定接口标准(如 HDMI、LVDS、DSI) 编码类型、支持的 Connector 列表、可能的 CRTC 掩码
Connector 物理连接器,代表显示器接口(HDMI 端口、eDP 接口、DSI 接口) 连接状态(connected/disconnected)、EDID 数据、支持的显示模式列表
Plane 硬件图层(Overlay/Primary/Cursor),支持独立缩放和颜色转换 格式、位置、大小、关联的 Framebuffer、Alpha 值
Framebuffer 帧缓冲,内存中的像素数据容器,由 GEM 对象创建 宽度、高度、像素格式、GEM handle、DMA-BUF fd
常见误区:初学者常将 CRTC 与 Connector 混淆。CRTC 是控制器,负责生成时序;Connector 是物理接口,负责连接显示器。一个 CRTC 可以驱动多个 Connector(克隆模式),但通常一个 Connector 只连接一个 CRTC。

2.5 GEM 与 DMA-BUF:显存管理核心机制

GEM 是 DRM 框架中的显存管理器,提供以下核心能力:

  • 分配与释放:通过 drmIoctl(DRM_IOCTL_GEM_CREATE) 分配显存,返回 GEM handle。
  • 内存映射:通过 drmIoctl(DRM_IOCTL_GEM_MMAP) 将显存映射到用户空间地址。
  • 句柄与 FD 转换:GEM handle 是进程内的句柄,通过 drmIoctl(DRM_IOCTL_GEM_FLINK) 转换为全局名称(name),或通过 drmIoctl(DRM_IOCTL_PRIME_HANDLE_TO_FD) 转换为 DMA-BUF 文件描述符。
  • 跨进程/跨设备共享:DMA-BUF 是 Linux 内核的通用缓冲区共享机制,允许 GPU、显示控制器、VPU、ISP 等不同硬件模块共享同一块物理内存,避免数据拷贝。
// GEM 分配与 DMA-BUF 导出示例(伪代码)
int fd = open("/dev/dri/card0", O_RDWR);

// 1. 分配 GEM 对象
struct drm_gem_create gem_create = {
    .size = width * height * 4,  // RGBA8888
    .handle = 0
};
drmIoctl(fd, DRM_IOCTL_GEM_CREATE, &gem_create);

// 2. 导出为 DMA-BUF FD
int dma_buf_fd;
struct drm_prime_handle prime_handle = {
    .handle = gem_create.handle,
    .flags = DRM_CLOEXEC,
    .fd = 0
};
drmIoctl(fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &prime_handle);
dma_buf_fd = prime_handle.fd;

// 3. 将 DMA-BUF FD 传递给 Weston 或其他驱动
// 接收方可通过 prime_fd_to_handle 导入

2.6 Wayland 与 Weston 的协作模式

Wayland 协议定义了 Client(应用)与 Compositor(合成器)之间的通信规范。Weston 作为参考实现,遵循以下协作模式:

角色 职责 关键接口/对象
Wayland Client 创建 wl_surface,渲染内容到 wl_buffer,提交给 Compositor wl_display、wl_surface、wl_buffer、wl_shell/xdg_shell
Wayland Compositor (Weston) 接收所有 Client 的缓冲区,合成最终画面,通过 DRM/KMS 输出 wl_compositor、wl_subcompositor、wl_output、weston_output
共享机制 Client 与 Compositor 通过共享内存(wl_shm)或 DMA-BUF(linux_dmabuf)传递缓冲区 wl_shm、zwp_linux_dmabuf_v1
关键设计理念:Wayland 协议中,Compositor 是唯一可以直接访问 DRM/KMS 的实体。Client 不能直接操作显示硬件,只能通过 Wayland 协议将缓冲区交给 Compositor。这种设计保证了显示系统的安全性和稳定性,避免了 X11 中常见的窗口争用问题。
Wayland/Weston 协作关系 Wayland / Weston 协作关系 Client 1 wl_surface + wl_buffer Client 2 wl_surface + wl_buffer Client N ... Weston 合成器 接收 → 合成 → 提交 wl_compositor DRM / KMS 内核显示框架 Atomic Commit Page Flip Wayland 协议通信

2.7 本章小结