4. 色彩管理基础
在 DRM 显示驱动开发中,色彩管理并不是“调一下饱和度”这么简单。它决定了同一帧 framebuffer 数据,经过显示管线后,最终在屏幕上呈现成什么颜色。若把显示链路看作一条数据通路,那么色彩空间定义“数值代表什么颜色”,Gamma 定义“数值如何映射到亮度”,色域定义“能显示的颜色边界”,色调映射负责“高动态范围到低动态范围的压缩”,色彩校正则用于“补偿面板与背光的偏差”。这五个概念共同构成 DRM 色彩管理的基础。
一、色彩空间:像素数值的“语义约定”
色彩空间规定了颜色如何用数值表示。常见的有 sRGB、Display P3、BT.2020、Adobe RGB 等。它们不仅色域范围不同,传递函数、白点、编码方式也可能不同。例如 sRGB 使用 D65 白点和约 2.2 的等效 Gamma,而 BT.2020 面向超高清电视,色域更广,常与 PQ 或 HLG 传递函数配合。
在 DRM 中,framebuffer 的格式(如 XRGB8888、NV12)只说明“每个分量占多少位”,并不说明“这些数值属于哪个色彩空间”。因此驱动必须通过 plane 的 color encoding、color range、以及 CRTC 的 CTM、LUT 等属性,把色彩空间信息显式传递给硬件。否则,有限范围(16-235)的视频被当作全范围(0-255)处理,就会出现发灰或死黑。
二、Gamma 与传递函数:亮度不是线性的
人眼对暗部亮度变化更敏感,而显示器的电光转换也并非线性。Gamma 就是描述“编码值”与“实际亮度”之间非线性关系的参数。传统 Gamma 2.2 用于 SDR 显示;HDR 则使用 PQ(SMPTE ST 2084)或 HLG。DRM 通过 gamma_lut、degamma_lut 以及 plane 的 COLOR_ENCODING 等属性,让驱动在扫描出前完成线性化或反向补偿。
# 查看当前 CRTC 的 Gamma LUT 属性
modetest -M rockchip -c 0 -p
# 典型属性:
# gamma_lut: 0
# gamma_lut_size: 1024
# DEGAMMA_LUT: 0
# DEGAMMA_LUT_SIZE: 1024
如果 Gamma 配置错误,画面会整体偏亮或偏暗,暗部细节丢失,肤色发灰。调试时可用灰阶渐变图配合示波器或色彩分析仪,检查 0%、10%、50%、100% 灰阶的亮度是否符合目标曲线。
三、色域与色调映射:从“能显示”到“显示得好”
色域是显示设备能够呈现的颜色集合。广色域面板可以覆盖 P3 甚至 BT.2020 的一部分,但若输入是 sRGB 内容,直接映射到广色域会导致颜色过饱和。此时需要色彩校正矩阵(CTM)或 3D LUT 做色域映射。色调映射则用于 HDR 内容在低动态范围屏幕上显示,常见方法有 Reinhard、ACES、Hable 等,目标是在保留高光细节的同时避免暗部过暗。
在 DRM 驱动中,CTM 通常以 3x3 矩阵形式配置,用于线性色彩空间转换;而 3D LUT 则用于更精细的非线性校正。两者结合,可实现“输入色彩空间 → 线性化 → 色域映射 → 目标色彩空间 → Gamma 编码”的完整链路。
四、色彩校正:让面板“说真话”
即使色彩空间和 Gamma 都正确,面板本身的色偏、背光色温、老化衰减仍会导致显示偏差。色彩校正就是通过测量实际输出,建立补偿矩阵或 LUT,写入 DRM 的 CTM、Gamma LUT 或 3D LUT 属性。常见流程如下:
- 用色彩分析仪测量面板在 R、G、B、W 及灰阶下的色度与亮度。
- 计算目标色彩空间与实测值之间的误差矩阵。
- 生成 3x3 CTM 或 3D LUT 数据。
- 通过 DRM atomic 提交,将校正数据下发到显示控制器。
- 复测并迭代,直到 ΔE 小于目标阈值(如 ΔE < 2)。
modetest 或 kmscube 验证基础管线,再通过 drmModeAtomicCommit 设置 CTM、GAMMA_LUT 等属性。注意:不同 SoC 的 LUT 大小和精度不同,提交前需检查 *_LUT_SIZE。
五、典型应用场景与参数对照
| 场景 | 输入色彩空间 | 关键处理 | DRM 属性 |
|---|---|---|---|
| 手机 SDR 桌面 | sRGB | Gamma 2.2,色域保持 sRGB | GAMMA_LUT、CTM(单位矩阵) |
| HDR 视频播放 | BT.2020 + PQ | 色调映射到面板能力,保留高光 | PLANE COLOR_ENCODING、CTM、GAMMA_LUT |
| 广色域照片 | Display P3 | 色域映射到 sRGB 或面板原生色域 | CTM、3D LUT |
| 面板白点校准 | 任意 | 测量后补偿色偏 | CTM、GAMMA_LUT |
六、常见误区与复盘
- 误区一:认为 framebuffer 格式决定色彩空间。实际上格式只决定位深和排列,色彩空间需额外配置。
- 误区二:忽略有限/全范围。视频常用 16-235,若按 0-255 处理,黑色会发灰,白色会过曝。
- 误区三:Gamma LUT 与 Degamma LUT 混用。Degamma 用于线性化输入,Gamma 用于输出编码,顺序不能颠倒。
- 误区四:只调 CTM 不做测量。没有色彩分析仪数据,校正矩阵可能让颜色更偏。
总结来说,色彩空间解决“数值含义”,Gamma 解决“亮度映射”,色域解决“颜色边界”,色调映射解决“动态范围压缩”,色彩校正解决“设备偏差”。在 DRM 驱动中,这些能力通过 plane 与 CRTC 的属性暴露给用户空间,并由 atomic 机制与 VBlank 同步生效。理解这条链路,才能在显示驱动开发中正确配置色彩管理,避免偏色、发灰、过饱和等常见问题。