2. 显示基础
在 DRM 显示驱动开发中,所有上层合成、图层混合、页面翻转最终都要落到“像素如何被描述、如何被传输、如何被扫描输出”这几个基础问题上。像素格式决定单个像素在内存中的排布方式,色彩空间决定这些数值如何被解释为颜色,时序与刷新率决定扫描控制器何时把像素送到屏幕,分辨率决定一帧的像素规模,而显示接口则决定这些像素以何种电气协议离开 SoC。理解这五者的关系,是后续调试花屏、偏色、撕裂、带宽不足等问题的前提。
一、像素格式:内存中的像素排布
像素格式描述的是像素在 framebuffer 中的存储布局,核心包含三部分信息:每像素位数(bpp)、通道顺序、以及是否带 Alpha。DRM 中用 fourcc 编码统一表示,例如 DRM_FORMAT_XRGB8888、DRM_FORMAT_ARGB8888、DRM_FORMAT_NV12。其中 X 表示该字节未使用,A 表示 Alpha 有效。
常见格式可分为打包格式(packed)和平面格式(planar)。打包格式如 XRGB8888,每个像素连续存放;平面格式如 NV12,Y 分量单独一个平面,UV 交错存放在第二个平面。GPU 合成通常偏好 ARGB8888,而视频解码输出常为 NV12,因此合成器需要做格式转换或让显示控制器直接支持多平面。
DRM_FORMAT_ARGB8888 // 每像素 32bit,A:R:G:B = 8:8:8:8
DRM_FORMAT_XRGB8888 // 每像素 32bit,忽略 Alpha
DRM_FORMAT_RGB565 // 每像素 16bit,R:G:B = 5:6:5
DRM_FORMAT_NV12 // YUV 4:2:0,Y 平面 + UV 交错平面
DRM_FORMAT_P010 // 10bit YUV 4:2:0,常用于 HDR 视频
二、色彩空间:数值到颜色的映射
同样的 RGB 数值,在不同色彩空间下呈现的颜色并不相同。显示基础中需要区分三类概念:RGB 与 YUV 的颜色模型差异、色域(sRGB、DCI-P3、BT.2020)、以及传递函数(Gamma、PQ、HLG)。RGB 适合渲染与合成,YUV 适合视频压缩与传输,因为人眼对亮度更敏感。
YUV 的采样方式用 4:4:4、4:2:2、4:2:0 表示色度下采样比例。4:2:0 意味着每 2×2 个像素共享一组 UV,带宽只有 4:4:4 的一半,但色度分辨率下降。驱动中必须正确设置 color_encoding 与 color_range,否则会出现“有限范围被当成全范围”导致的发灰或过暗。
三、时序、刷新率与分辨率
显示时序由一组参数描述:hdisplay/hsync_start/hsync_end/htotal 与 vdisplay/vsync_start/vsync_end/vtotal。它们共同决定有效像素区、消隐区以及同步脉冲位置。刷新率近似为 像素时钟 / (htotal × vtotal)。分辨率只是有效像素区大小,不等于时序全部。
下图展示了一条扫描线的时序结构与一帧的垂直时序关系,帮助理解消隐区、同步脉冲与有效显示区的位置。
刷新率是垂直时序每秒重复的次数。高刷新率意味着更短的 vtotal 周期,对带宽和 GPU 提交节奏要求更高。分辨率提升时,如果像素时钟不增加,刷新率会下降,因此 4K@60 与 1080p@60 的像素时钟差异巨大。
四、显示接口基础
显示接口负责把像素流从 SoC 送到面板或桥接芯片。常见接口包括 MIPI DSI、eDP、HDMI、DisplayPort。它们各有 lane 数、每 lane 速率、编码方式(如 8b/10b)和链路训练流程。驱动侧需要根据接口能力计算可用带宽,并与模式时序匹配。
| 接口 | 典型场景 | 关键参数 | 驱动关注点 |
|---|---|---|---|
| MIPI DSI | 手机、平板面板 | lane 数、HS/LP 速率 | 命令模式/视频模式、初始化序列 |
| eDP | 笔记本内屏 | lane 数、链路速率 | 链路训练、AUX 通道、PSR |
| HDMI | 电视、显示器 | TMDS 时钟、FRL | EDID 解析、HDR 元数据 |
| DisplayPort | 显示器、扩展坞 | lane 数、MST | 链路训练、多流传输 |
五、案例与常见误区
一个典型场景是:GPU 合成输出 ARGB8888,而视频图层是 NV12,显示控制器需要同时接受两种格式并做 CSC。如果驱动把 NV12 的 UV 平面 stride 算错,画面会出现绿色或紫色条纹;如果 color_range 未设置,视频会发灰。
复盘时建议按“格式 → 色彩空间 → 时序 → 带宽 → 接口”的顺序逐项核对,并用 modetest、drm_info 等工具确认内核实际接受的模式与 plane 属性,而不是只依赖应用层参数。