第2篇:DRM 是什么?为什么显示驱动绕不开它?

摘要

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 子系统负责:

● 设备初始化

● 资源管理

● 模式设置

● 属性解析

● 提交调度

● 同步处理

image.png

第三层:硬件驱动

具体芯片的 CRTC、Encoder、Connector、Plane、Panel、MIPI 驱动,按照 DRM 框架实现硬件操作。

3. DRM 最核心的几个概念

这几个概念需要理解记忆,甚至背诵,以后看日志、看驱动代码必须认识。在MTK等平台driver代码里,专门有对应的驱动文件。

image.png

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要显示一帧,通常不是简单“写一下显存”,而是一个完整提交过程。

大致步骤:

  1. 准备图形 Buffer

  2. 用户态设置显示属性

  3. 检查配置是否合法

  4. commit到内核

  5. DRM 完成模式设置或更新

  6. 等待present fence,等画面真正显示完成

  7. 释放旧 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 这条链路上看。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容