2. DRM与CRTC基础
在Linux显示子系统中,DRM(Direct Rendering Manager)是内核态管理显示控制器、显存与渲染任务的核心框架。要理解gamma校正与色彩管理为何必须落在CRTC层,首先需要建立对DRM整体架构、CRTC职责以及显示管线数据流的清晰认知。本节从对象模型出发,逐步展开到像素从帧缓冲到屏幕的完整路径。
一、DRM架构:对象模型与职责分层
DRM并非单一模块,而是一组按职责划分的内核对象集合。用户空间通过libdrm或内核ioctl与这些对象交互,内核驱动则负责将抽象对象映射到具体硬件寄存器。核心对象包括:
- DRM Device:代表一个显示设备节点(如/dev/dri/card0),承载全局能力与资源管理。
- Framebuffer(FB):描述一块可被扫描输出的像素缓冲区,包含格式、宽高、pitch与GEM handle。
- Plane:图层抽象,负责从FB取像素并叠加、缩放、旋转后送入CRTC。分为Primary、Overlay、Cursor三类。
- CRTC:显示控制器通道,负责时序生成、扫描输出与后处理(gamma、色彩变换等)。
- Encoder:将CRTC的像素流转换为特定接口信号(HDMI、DP、DSI、eDP等)。
- Connector:物理输出接口,管理连接状态、EDID与支持的显示模式。
这些对象通过“possible_crtcs”“possible_clones”等位图建立约束关系,形成一张有向的资源拓扑图。驱动在初始化阶段注册对象,用户空间通过Atomic或Legacy API提交配置。
二、CRTC的作用:不只是“扫描输出”
CRTC(Cathode Ray Tube Controller)名称源于CRT时代,但在现代DRM中它已演化为一个通用的显示控制器通道。其核心职责可归纳为四类:
- 时序生成:根据mode信息产生HSYNC、VSYNC、DE等时序信号,控制像素扫描节奏。
- 图层合成:将多个Plane的像素按Z-order、Alpha、Blending规则合成为最终输出画面。
- 后处理:在像素输出前执行gamma校正、色彩空间转换、抖动等操作。这是gamma LUT的挂载点。
- 状态管理:维护active、mode、gamma_lut、ctm等属性,支持Atomic提交与回滚。
一个DRM设备可能包含多个CRTC,每个CRTC可独立驱动一个显示通道。例如双屏异显场景中,CRTC0驱动eDP,CRTC1驱动HDMI。gamma校正配置必须明确指定目标CRTC,否则会作用到错误的显示通道。
三、显示管线概述:像素的完整旅程
从应用提交画面到屏幕发光,像素经历了一条严格的流水线。以Atomic模式为例:
用户空间:
drmModeAtomicAddProperty(req, crtc_id, "GAMMA_LUT", blob_id)
drmModeAtomicCommit(fd, req, DRM_MODE_ATOMIC_ALLOW_MODESET, NULL)
内核DRM Core:
1. 校验属性合法性(blob大小、LUT点数、CRTC状态)
2. 调用驱动 atomic_check 回调
3. 驱动计算硬件寄存器值,检查时序冲突
4. atomic_commit 提交,更新CRTC状态
5. 在vblank期间切换gamma LUT,避免撕裂
硬件执行:
Plane取像素 → 合成 → CRTC后处理(gamma LUT查表)→ Encoder编码 → PHY发送 → 屏幕
这条管线中有两个关键同步点:一是Atomic Commit的“全有或全无”语义,保证配置一致性;二是vblank同步,确保gamma切换发生在消隐期,避免画面闪烁。
四、案例与场景:双屏异显下的gamma配置
假设一台设备同时连接eDP内置屏与HDMI外接屏,两块屏幕的gamma特性不同。工程师需要分别配置:
| 对象 | eDP通道 | HDMI通道 | 说明 |
|---|---|---|---|
| CRTC | CRTC0 | CRTC1 | 独立控制器 |
| Connector | eDP-1 | HDMI-A-1 | 物理接口 |
| Gamma LUT | sRGB曲线 | BT.709曲线 | 不同色彩空间 |
| LUT点数 | 256 | 1024 | 硬件能力差异 |
| 提交方式 | Atomic | Atomic | 统一API |
若错误地将HDMI的gamma LUT提交到CRTC0,eDP画面会偏色,而HDMI无变化。排障时应先通过drmModeGetCrtc确认CRTC与Connector的绑定关系,再检查Atomic请求中的crtc_id字段。
五、复盘:建立对象与数据流的双重认知
掌握DRM与CRTC基础,需要同时建立两套认知:
- 对象关系认知:FB→Plane→CRTC→Encoder→Connector的绑定与约束,理解possible_crtcs位图的意义。
- 数据流认知:像素从内存到屏幕的路径,明确gamma LUT在CRTC后处理阶段的位置。
后续配置gamma校正时,所有操作都将围绕CRTC对象展开:获取CRTC能力、构造LUT blob、通过Atomic提交、在vblank中生效。只有先厘清架构与管线,才能避免“配置了但没效果”或“配错通道”的典型问题。