摘要
Android/Linux 显示体系里,DRM 不是某个单点模块,DRM 是 Linux 显示体系的核心框架。它统一管理 CRTC、Encoder、Connector、Plane、内存与同步,把上层图层安全提交给显示硬件;是在内核中负责显示资源管理、模式设置、图层提交和同步调度的核心框架。理解 DRM,是从“会调屏”走向“能定位黑屏、花屏、闪屏和图层异常问题”的关键一步。
前言
很多人刚接触显示驱动时,会把 DRM 理解成一个“屏幕驱动”。
其实不是。
在我理解看来DRM 更像是内核显示子系统的“基础设施”:它统一管理显卡、显示控制器、图层、连接器、内存和同步机制。Panel、MIPI、HWC 这些模块,最终都要挂到这套框架上工作。
1. DRM 到底解决了什么问题?
在 DRM 出现之前,Linux 显示路径比较分散,不同硬件各自管理显示资源,容易出现几个问题:
- 多个程序同时申请显示资源,谁都可以抢屏幕
- 图层叠加、模式切换没有统一协调
- 内存管理、同步机制不统一
- 用户态和内核态接口混乱
DRM 的目标,就是把这些能力统一起来:把显示资源抽象成统一模型,让用户态按规则申请、配置和提交。
它解决的不是“屏幕怎么亮”这一件事,而是:
- 谁可以访问显示设备
- 怎么设置显示模式
- 怎么提交图层
- 怎么分配和共享图形内存
- 怎么同步一帧画面的完成时机,时机很关键,时机不对送来图也不会正常显示.
2. DRM 在显示链路中的位置
回顾第1篇的链路:
App → SurfaceFlinger → HWC → Gralloc → DRM → Panel / MIPI → 屏幕
DRM 位于图形链路的内核入口,是用户态和显示硬件之间的桥梁。
可以把它理解成三层:
第一层:**user space interface**
App、SurfaceFlinger、HWC 通过 libdrm 或框架接口访问 DRM。
第二层:DRM 核心框架
内核里的 DRM 子系统负责:
- 设备初始化
- 资源管理
- 模式设置
- 属性解析
- 提交调度
- 同步处理

第三层:硬件驱动
具体芯片的 CRTC、Encoder、Connector、Plane、Panel、MIPI 驱动,按照 DRM 框架实现硬件操作。
3. DRM 最核心的几个概念
这几个概念需要理解记忆,甚至背诵,以后看日志、看驱动代码必须认识。在MTK等平台driver代码里,专门有对应的驱动文件。

CRTC
CRTC 可以理解为“显示控制器”。
它负责把一帧数据扫描出来,按照一定时序送到显示接口。
可以简单记:
CRTC 是真正产生显示时序、扫描帧数据的地方。
Encoder
Encoder 负责把 CRTC 输出的画面数据,转换成适合当前接口传输的格式或协议。
比如:
- 转换成 MIPI-DSI 流
- 转换成 HDMI 信号
- 转换成 DP 信号
可以理解为:
Encoder 是数据传输格式的转换器。
Connector
Connector 代表一个可见的显示输出接口。
比如:
- MIPI DSI接口
- HDMI 接口
- DP 接口
- 外接显示屏
用户看到的“某个屏幕已连接”,在 DRM 里通常对应一个 Connector。
Plane
Plane 是图层。
Android 里每个窗口(比如桌面和大家喜欢用的悬浮窗)、状态栏、视频层,都可能对应一个或多个 Plane(当前界面具体几个layer,需要dumpsys SurfaceFlinger确认)。
DRM 允许硬件把多个 Plane 叠加起来显示。
所以 Plane 的关键作用是:支持多图层硬件叠加。**(手机SOC硬件基本是会支持4层,当然也得看具体平台)**
FB / Framebuffer
Framebuffer 是一帧画面的内存缓冲区。
上层把绘制好的 Buffer 交给 DRM,DRM 把它映射到 Framebuffer,再由 CRTC 扫描输出。
可以理解为:Framebuffer 就是当前要显示的那帧数据。
4. DRM 提交一帧的大致过程
app要显示一帧,通常不是简单“写一下显存”,而是一个完整提交过程。
大致步骤:
- 准备图形 Buffer
- 用户态设置显示属性
- 检查配置是否合法
- commit到内核
- DRM 完成模式设置或更新
- 等待present fence,等画面真正显示完成
- 释放旧 Buffer
这里面最关键的一步,是“commit”。
DRM 不是改完寄存器立刻显示,而是把一次更新打包提交,由框架统一调度,通过fence来实现同步,后续章节再详细讨论。
5. 为什么现在强调 DRM Atomic?
Atomic 是 DRM 的重要改进。
它的核心思想是:把一次显示更新的所有配置,当成一个完整事务检查后再提交。
这有几个好处:
- 多个图层、模式、属性可以一起更新
- 配置不合法时,可以提前拒绝
- 减少中间状态错乱
- 更适合 Android 这种复杂合成场景
所以你会经常看到这些关键词:
- atomic_check
- atomic_commit
- state
- properties
它们本质上都围绕“原子提交”展开。
6. DRM 和 HWC 是什么关系?
这是很多人最容易混淆的地方。
可以这样理解:
- HWC:Android 用户态的硬件合成器,决定哪些图层走硬件合成
- DRM:Linux 内核里的显示框架,负责把最终图层提交给硬件
HWC 更像“策略选择器”,DRM 更像“执行入口”。
HWC 告诉系统:这几个图层可以硬件叠加。
然后由 DRM 完成真正的图层配置和提交。
7. 从调试角度看,DRM 为什么重要?
显示问题不一定都出在 DRM,但很多问题最终都会在 DRM 层留下痕迹。
遇到这些问题时,DRM 是关键排查点:
- 黑屏
- 花屏
- 闪屏
- 图层错位
- 模式切换失败
- 帧率异常
- 休眠唤醒异常
- Buffer 显示异常
因为 DRM 连接了:
- 上层 Buffer
- 图层配置
- 显示模式
- 同步机制
- 硬件寄存器
所以它是显示问题的“必经之路”。
8. 初学者怎么学 DRM?
建议按这个顺序来:
第一步:先看概念
搞懂 CRTC、Encoder、Connector、Plane、Framebuffer。
第二步:看日志
用 modetest、drm_info 看系统里有哪些显示资源。
第三步:看驱动结构
不必一开始啃完整源码,先看驱动里这几个部分:
- 初始化
- 模式设置
- 图层更新
- 电源管理
- 中断处理
第四步:再看 Atomic
理解 Atomic 前,先理解普通提交模型。后续章节再详细讨论。
结语
DRM 不是单一功能模块,而是 Linux 显示体系的骨架。
你可以暂时不深究每一个源码细节,但最好先建立这个认知:
DRM 负责统一管理显示资源,把上层图层和配置,安全、有序地提交给显示硬件。
以后遇到显示问题,不要只怀疑屏幕或 MIPI,也记得往 DRM 这条链路上看。