第25章 显示调试:dumpsys display、亮度调节、色彩管理、HDR调试
显示调试,说白了你就是在跟屏幕“对话”。屏幕亮不亮、颜色对不对、HDR有没有生效,这些都得靠工具来验证。我这些年调过的屏,从LCD到OLED,从60Hz到120Hz,踩过的坑真不少。今天咱们就把显示调试这块掰开揉碎,讲清楚。
25.1 dumpsys display:你的屏幕“体检报告”
我个人习惯,拿到一台新设备,第一件事就是跑 dumpsys display。这命令能告诉你屏幕的几乎所有状态。
adb shell dumpsys display
输出内容很长,但核心信息就这几块:
- Display Device Info:物理显示设备信息,比如分辨率、刷新率、是否支持HDR。
- Display Power State:屏幕电源状态,ON、OFF、DOZE、SUSPEND。
- Display Brightness:当前亮度值,包括用户设置值和实际物理亮度。
- Color Mode:当前色彩模式,比如sRGB、DCI-P3、鲜艳模式。
- HDR Capabilities:HDR能力列表,比如HDR10、HLG、Dolby Vision。
关键字段解读
我重点关注 mCurrentHdrSdrRatio 和 mHdrBrightness。这两个值直接反映HDR内容是否被正确映射到屏幕亮度上。
举个例子,你播放HDR视频时,如果 mCurrentHdrSdrRatio 还是1.0,那说明HDR根本没生效。我曾经遇到一个案子,客户说HDR视频发灰,一查就是这个值没变,最后发现是SurfaceFlinger的HDR元数据传递出了问题。
25.2 亮度调节:从自动到手动,再到曲线
亮度调节,看似简单,其实门道很多。Android的亮度调节分两种:
- 手动亮度:用户直接拖滑块,系统直接设置背光值。
- 自动亮度:系统根据环境光传感器数据,通过亮度曲线映射出目标亮度。
调试自动亮度,我常用这个命令:
adb shell dumpsys sensorservice | grep -A 10 "Light Sensor"
这能实时看到环境光传感器的读数。然后配合 dumpsys display 看亮度变化。
我的调试技巧
我会在 /vendor/etc/ 下找到亮度曲线配置文件,比如 brightness_curve.xml。直接修改这个文件,重启后就能看到新的亮度映射效果。省去了反复编译固件的时间。
嗯,这里要注意:亮度曲线不是线性的。人眼对亮度的感知是对数的,所以曲线通常是一条“S”形。我曾经调过一款设备,自动亮度在暗光下跳变太明显,用户反馈“闪眼睛”。后来我把低亮度段的曲线斜率调缓了,问题就解决了。
25.3 色彩管理:sRGB、DCI-P3、广色域
色彩管理,说白了就是让屏幕显示的颜色“准”。Android从8.0开始引入了色彩管理框架,支持sRGB和DCI-P3色域。
调试色彩模式,用这个命令:
adb shell dumpsys display | grep -i "color mode"
输出会列出当前支持的色彩模式:
| 色彩模式 | 色域 | 典型用途 |
|---|---|---|
| sRGB | 约72% NTSC | 网页、普通图片 |
| DCI-P3 | 约96% NTSC | 电影、HDR内容 |
| Display P3 | 与DCI-P3接近 | 苹果生态、广色域应用 |
| 鲜艳模式 | 超过100% NTSC | 用户偏好、视觉冲击 |
我建议你在调试时,先确认应用是否声明了色域。比如一个图片应用,如果它没声明 android:colorMode,系统默认用sRGB渲染。这时候你屏幕虽然是广色域,但显示的内容还是被压缩在sRGB范围内。
避坑指南
我曾经遇到一个案子:某视频App播放HDR内容时,颜色明显过饱和。查了半天,发现是App在渲染时用了sRGB的纹理,但系统以为它是DCI-P3内容,做了两次色域转换。最后让App在Surface上正确标记了色彩空间,问题才解决。
25.4 HDR调试:从元数据到亮度映射
HDR调试是显示调试里最复杂的部分。它涉及三个环节:
- HDR元数据传递:播放器把HDR静态元数据(SMPTE ST 2086)传给SurfaceFlinger。
- 亮度映射:SurfaceFlinger根据元数据和屏幕能力,计算出HDR内容的亮度映射曲线。
- 显示输出:屏幕驱动根据映射曲线,控制每个像素的亮度。
调试HDR,我常用的命令组合:
adb shell dumpsys display | grep -i hdr
adb shell dumpsys SurfaceFlinger | grep -i hdr
重点关注这几个值:
mHdrCapabilities:屏幕支持的HDR格式列表。mCurrentHdrSdrRatio:当前HDR与SDR的亮度比。HDR内容播放时,这个值应该大于1.0。mHdrBrightness:HDR内容的峰值亮度,单位是nit。
实战案例
我记得有一次,客户反馈HDR视频播放时,画面整体偏暗。我查了 mCurrentHdrSdrRatio 是2.0,但屏幕峰值亮度只有400nit。理论上HDR内容应该映射到800nit,但屏幕实际只能到400nit。最后发现是亮度映射曲线里的 maxLuminance 参数写错了,写成了屏幕的峰值亮度,而不是HDR内容的目标亮度。修正后,画面亮度就正常了。
你想想看,HDR调试的本质是什么?就是让屏幕在有限的亮度范围内,尽可能还原HDR内容的亮度层次。如果映射曲线不对,要么画面发灰,要么过曝。
25.5 显示调试知识体系
下面这张图,是我自己总结的显示调试知识体系。你可以把它当作一个检查清单,遇到显示问题,按图索骥就行。
这张图把显示调试分成了四个维度。你遇到问题时,先定位是哪个维度,再深入对应的调试命令和参数。我个人觉得,HDR调试是最容易出问题的,因为涉及元数据传递和亮度映射两个环节,任何一个环节出错,画面都不对。
我的调试习惯
我每次调试显示问题,都会先跑一遍 dumpsys display,把输出保存下来。然后对比正常设备和异常设备的输出,差异点往往就是问题所在。这招屡试不爽。
好了,显示调试这块就讲这么多。记住,工具是死的,思路是活的。你只要掌握了 dumpsys display 的核心字段,理解了亮度曲线和色彩映射的原理,大部分显示问题都能迎刃而解。
公众号:蓝海资料掘金营,微信deep3321