1. 显示子系统概述

1.1 Linux 显示子系统整体架构

Linux 显示子系统是内核中负责图形输出、显示控制、帧缓冲管理与合成渲染的核心模块集合。它横跨用户态、内核态与硬件层,为桌面环境、嵌入式 GUI、游戏与 VR 提供统一的显示抽象。

从软件栈视角,显示子系统可划分为四个层次:

层次 组件/接口 职责
用户态应用 X11/Wayland 合成器、Qt/GTK、游戏引擎 发起渲染请求、管理窗口合成、接收输入事件
用户态库 libdrm、mesa (Gallium3D)、libva 封装 DRM ioctl、提供 OpenGL/Vulkan 实现、硬件编解码加速
内核显示框架 DRM/KMS、fbdev、VGEM、UDL 管理显示设备、模式设置、内存分配、同步与 fence
硬件驱动层 i915、amdgpu、msm、vc4、panfrost 操作 GPU/Display Controller 寄存器、处理中断、实现硬件特定功能
关键认知: 现代 Linux 显示以 DRM/KMS 为核心,fbdev 仅作为兼容层保留。所有新驱动开发都应基于 DRM 框架。

1.2 DRM/KMS 框架简介

DRM (Direct Rendering Manager) 是 Linux 内核中负责图形显示与 GPU 管理的子系统,提供用户态直接访问硬件的安全接口。KMS (Kernel Mode Setting) 是 DRM 的一部分,专门负责显示模式(分辨率、刷新率、连接器状态)的设置与管理。

DRM/KMS 的核心对象模型包含以下实体:

  • DRM Device — 代表一个显示控制器或 GPU,通过 /dev/dri/card0 暴露给用户态。
  • CRTC — 显示控制器内部的扫描输出引擎,负责从内存读取像素数据并生成视频时序信号。
  • Encoder — 将 CRTC 输出的并行像素流编码为特定接口协议(如 HDMI、DP、LVDS)。
  • Connector — 代表物理显示接口(HDMI 端口、DP 端口、eDP 面板),携带 EDID 信息。
  • Plane — 硬件叠加层,允许将多个帧缓冲以不同 Z 序合成后输出,减少 GPU 合成开销。
  • Framebuffer — 内存中的像素数据缓冲区,通常由 GEM (Graphics Execution Manager) 管理。
记忆口诀: "CRTC 读内存 → Encoder 编码 → Connector 输出" 是 KMS 的经典数据流路径。

下面展示 DRM/KMS 核心对象之间的连接关系:

DRM/KMS 核心对象关系图 Framebuffer GEM 内存对象 Plane 硬件叠加层 CRTC 扫描输出引擎 Encoder 接口编码器 Connector 物理接口 说明: 一个 CRTC 可连接多个 Plane(主层 + 光标层 + 叠加层), 一个 Encoder 只能连接一个 CRTC,一个 Connector 只能连接一个 Encoder。

1.3 显示流水线概念

显示流水线 (Display Pipeline) 描述像素数据从应用程序生成到最终在屏幕上显示的完整路径。理解流水线是掌握显示子系统性能调优与调试的基础。

典型的显示流水线包含以下阶段:

  1. 应用渲染 — 用户态应用通过 OpenGL/Vulkan 或 CPU 绘制生成帧数据。
  2. 缓冲区提交 — 应用通过 DRM ioctl 将渲染完成的帧缓冲提交到内核。
  3. 合成与叠加 — 内核或硬件合成器将多个 Plane 的帧缓冲按 Z 序合成。
  4. 扫描输出 — CRTC 按行/场时序从帧缓冲读取像素,生成视频流。
  5. 编码传输 — Encoder 将并行视频流编码为串行差分信号(如 TMDS、eDP)。
  6. 物理显示 — Connector 将信号送至显示器,显示器面板刷新显示。
性能陷阱: 流水线中最慢的阶段决定整体帧率。常见瓶颈包括:GPU 渲染超时、缓冲区交换等待 vblank、CRTC 带宽不足、Encoder 链路训练失败。

下面用 SVG 展示完整的显示流水线数据流:

Linux 显示流水线数据流 应用渲染 OpenGL/Vulkan 缓冲区提交 DRM ioctl 合成与叠加 Plane 合成 扫描输出 CRTC 读取 编码传输 Encoder 物理显示 Connector → 面板 关键时序约束: 整个流水线必须在 1 帧时间内(16.7ms @60Hz)完成,否则出现丢帧或画面撕裂。 vblank 期间是安全的缓冲区交换窗口,DRM 通过 fence 机制保证同步。

1.4 显示子系统关键设计原则

  • 分离机制与策略 — 内核只提供原子化的模式设置与缓冲区管理,合成策略由用户态合成器(Wayland/Weston/Xorg)决定。
  • 原子操作 — DRM 原子 API 保证多个 CRTC/Plane/Connector 的状态切换在同一个 vblank 边界完成,避免中间态闪烁。
  • 零拷贝路径 — 通过 DMA-BUF 机制,GPU 渲染输出可直接被显示控制器引用,无需 CPU 拷贝。
  • 硬件抽象 — 驱动只需实现 struct drm_driver 和 struct drm_mode_config_funcs 回调,框架自动处理 ioctl 分发与状态校验。
学习路线建议: 先掌握 DRM 核心对象模型与 KMS 模式设置流程,再深入 atomic commit 与 fence 同步机制,最后研究具体 GPU 驱动的实现差异。