1. DRM 框架概述:Linux 图形栈中的位置与核心组件

DRM(Direct Rendering Manager)是 Linux 内核中负责图形显示与渲染管理的核心框架。它位于内核空间,向上为用户态的图形栈(如 Mesa、Wayland、Xorg)提供标准接口,向下直接操作 GPU 和显示控制器硬件。理解 DRM 在 Linux 图形栈中的位置及其核心组件,是进行显示性能调优与帧率配置的基础。

1.1 DRM 在 Linux 图形栈中的位置

Linux 图形栈从用户态到内核态通常分为三层:应用层、合成/窗口管理层、内核驱动层。DRM 处于最底层的内核驱动层,直接与硬件交互。

关键定位: DRM 是用户态图形库(如 Mesa 的 EGL/GLES)与显示硬件之间的桥梁。所有帧缓冲区分配、页面翻转、垂直同步(VBlank)控制最终都通过 DRM 系统调用完成。
Linux 图形栈分层架构 Linux 图形栈分层架构 用户态应用层 游戏 / 浏览器 / 视频播放器 / GUI 桌面 合成 / 窗口管理层 Wayland Compositor / Xorg Server / Weston 用户态图形库层 Mesa 3D (EGL/GLES/Vulkan) / libdrm 内核 DRM 层 DRM Core / KMS / GEM / Dumb Buffer GPU / Display Controller / HDMI / DP 硬件

1.2 DRM 核心组件详解

DRM 框架由四个核心子系统构成:DRM Core、KMS、GEM 和 Dumb Buffer。它们各司其职,共同完成从内存管理到显示输出的完整链路。

组件 全称 核心职责 用户态接口
DRM Core Direct Rendering Manager Core 提供基础框架、设备管理、文件操作、IOCTL 分发 open() / ioctl() / mmap()
KMS Kernel Mode Setting 显示模式设置、分辨率/刷新率配置、页面翻转、VBlank 控制 drmModeGetResources() / drmModeSetCrtc()
GEM Graphics Execution Manager 显存分配与管理、GPU 缓冲区共享、同步对象 drmIoctl(DRM_IOCTL_GEM_CREATE)
Dumb Buffer Dumb Buffer 为无需 GPU 加速的简单应用提供连续物理内存帧缓冲 drmIoctl(DRM_IOCTL_MODE_CREATE_DUMB)

1.3 DRM Core:框架的基石

DRM Core 是整个 DRM 框架的入口和基础设施。它负责注册 DRM 设备节点(/dev/dri/card0)、管理打开文件的上下文、分发 IOCTL 请求到对应的子模块(KMS、GEM 等)。

  • 设备注册: 每个 GPU 或显示控制器对应一个 drm_device 结构体,通过 drm_dev_register() 注册到系统。
  • IOCTL 路由: 根据命令号将用户态请求分发到 KMS、GEM 或 Dumb Buffer 的处理函数。
  • 驱动模型: 提供 struct drm_driver 回调接口,硬件厂商只需实现这些回调即可适配 DRM 框架。
性能提示: DRM Core 的 IOCTL 分发路径是帧率调优的第一道关卡。频繁的 ioctl() 调用(如每帧一次页面翻转)会引入上下文切换开销。在调优时,应关注 perf 统计中 drm_ioctl 的耗时占比。

1.4 KMS:显示模式设置与帧率控制

KMS(Kernel Mode Setting)是 DRM 中直接控制显示输出参数的子系统。它负责配置显示控制器的时序、分辨率、刷新率,并管理页面翻转(Page Flip)操作。

KMS 的核心对象包括:

  • CRTC: 显示控制器,负责生成视频时序信号。每个 CRTC 对应一个独立的显示管道。
  • Encoder: 编码器,将 CRTC 输出的像素数据转换为特定接口信号(如 HDMI、DP、LVDS)。
  • Connector: 物理连接器,代表实际的显示接口(如 HDMI-A-1、DP-2)。
  • Plane: 硬件图层,支持叠加多个帧缓冲区进行合成,减少 CPU 合成开销。
KMS 核心对象关系 KMS 核心对象关系图 CRTC 显示控制器 / 时序生成 Plane 硬件图层 / 帧缓冲 Encoder 编码器 / 信号转换 Connector 物理连接器 / 显示器 帧率配置关键:CRTC 的 mode 结构体中的 vrefresh 字段直接决定刷新率 通过 drmModeSetCrtc() 设置包含刷新率的 drmModeModeInfo

1.5 GEM:显存管理与缓冲区共享

GEM(Graphics Execution Manager)是 DRM 的显存管理子系统。它提供了一套统一的 API 用于分配、释放和共享 GPU 缓冲区对象(BO)。

  • 缓冲区创建: 通过 DRM_IOCTL_GEM_CREATE 分配指定大小的显存,返回一个句柄(handle)。
  • 内存映射: 通过 mmap() 将 GPU 缓冲区映射到用户态地址空间,供 CPU 读写。
  • 共享与导出: 通过 DRM_IOCTL_GEM_FLINK 或 dma-buf 机制,在不同进程或不同 DRM 设备间共享缓冲区。
  • 同步对象: 支持 drm_syncobj 用于 GPU 与 CPU 之间的同步,避免帧撕裂。
调优注意: GEM 缓冲区分配和映射是帧率瓶颈的常见来源。频繁的 GEM_CREATE 和 mmap 操作会引入延迟。生产环境中应使用缓冲区池(Buffer Pool)复用已分配的缓冲区,避免每帧重新分配。

1.6 Dumb Buffer:轻量级帧缓冲方案

Dumb Buffer 是 DRM 为不需要 GPU 加速的简单应用(如嵌入式设备的 framebuffer console、轻量级 UI)提供的帧缓冲机制。它分配的是连续的物理内存,CPU 可以直接访问。

特性 Dumb Buffer GEM Buffer
内存类型 连续物理内存 GPU 显存(可能不连续)
GPU 加速 不支持 支持
适用场景 简单 2D 显示、控制台 3D 渲染、视频播放、合成器
分配接口 DRM_IOCTL_MODE_CREATE_DUMB DRM_IOCTL_GEM_CREATE
性能特征 低延迟、低吞吐 高吞吐、支持 DMA

Dumb Buffer 的典型使用流程如下:

// 1. 创建 Dumb Buffer
struct drm_mode_create_dumb create = {0};
create.width = 1920;
create.height = 1080;
create.bpp = 32;
ioctl(fd, DRM_IOCTL_MODE_CREATE_DUMB, &create);

// 2. 获取偏移量用于 mmap
struct drm_mode_map_dumb map = {0};
map.handle = create.handle;
ioctl(fd, DRM_IOCTL_MODE_MAP_DUMB, &map);

// 3. 映射到用户态
uint32_t *fb = mmap(NULL, create.size, PROT_READ | PROT_WRITE,
                    MAP_SHARED, fd, map.offset);

// 4. 将 Dumb Buffer 添加为 Framebuffer
uint32_t fb_id;
drmModeAddFB(fd, 1920, 1080, 24, 32, create.pitch, create.handle, &fb_id);

// 5. 设置 CRTC 显示
drmModeSetCrtc(fd, crtc_id, fb_id, 0, 0, &connector_id, 1, &mode);

1.7 组件协作流程:从帧缓冲区到屏幕显示

理解四个组件如何协同工作,是后续调优的前提。一个典型的显示帧提交流程如下:

  1. 缓冲区分配: 用户态通过 GEM 或 Dumb Buffer 分配帧缓冲区。
  2. 渲染: CPU 或 GPU 将内容渲染到缓冲区。
  3. 提交: 用户态调用 drmModeSetCrtc() 或 drmModePageFlip() 将缓冲区提交给 KMS。
  4. 页面翻转: KMS 在 VBlank 期间切换 CRTC 的扫描缓冲区指针,实现无撕裂显示。
  5. 同步: 通过 VBlank 事件或同步对象通知用户态下一帧可以开始渲染。
帧率调优核心: 整个流程中,页面翻转(Page Flip)和 VBlank 同步 是决定实际帧率的关键。如果应用程序无法在 VBlank 间隔内完成渲染和提交,就会发生丢帧或帧率下降。后续章节将深入分析这些环节的调优方法。
DRM 组件协作流程 DRM 组件协作流程:从帧缓冲区到屏幕 1. 分配缓冲区 GEM / Dumb Buffer 2. 渲染内容 CPU / GPU 渲染 3. 提交翻转 KMS Page Flip 4. VBlank 切换 CRTC 扫描切换 5. 同步通知 VBlank 事件 / Syncobj 虚线回环表示:VBlank 事件触发后,应用程序开始渲染下一帧,形成流水线 帧率 = 1 / (渲染时间 + 翻转等待时间),调优目标是让渲染时间 < VBlank 间隔

1.8 本章小结

本章介绍了 DRM 框架在 Linux 图形栈中的核心位置,并详细剖析了四大核心组件:

  • DRM Core 提供基础框架和 IOCTL 路由。
  • KMS 负责显示模式设置和帧率控制。
  • GEM 管理 GPU 显存和缓冲区共享。
  • Dumb Buffer 提供轻量级连续内存帧缓冲方案。