1. 课程导入
欢迎进入《Android HWC多显示器集成工程》。在车载座舱、折叠屏、AR/VR、桌面模式以及工业控制终端中,一块 SoC 同时驱动两三块甚至更多屏幕,已经从“加分项”变成“基本盘”。但很多工程师第一次接触多显示器时,会把它简单理解为“多接一根线、多开一个 Surface”,真正动手后才发现:显示链路、合成策略、热插拔时序、带宽分配、HWC 与 SurfaceFlinger 的职责边界,任何一环没打通,副屏就是黑屏、花屏、掉帧或延迟。本课程的目标,就是把这套链路从概念到代码、从配置到排障完整讲透。
一、学习目标:从“能亮”到“可控、可测、可量产”
本课程不是 API 手册的复述,而是围绕工程交付展开。学完之后,你应当具备四项能力:第一,能画出从应用层到显示控制器(Display Controller)的完整数据通路,说清每一层在多显示器场景下多出了什么;第二,能读懂并修改 HWC 的显示配置、图层合成与热插拔处理逻辑;第三,能针对镜像、扩展、独立三种显示模式设计合成策略并评估性能;第四,能使用 dumpsys、HWC 日志、trace 等工具定位黑屏、撕裂、掉帧、延迟等典型问题。
二、核心概念:先建立正确的对象模型
多显示器集成的第一道门槛是术语。Android 显示体系中,Physical Display 是真实存在的物理屏,由 HWC 枚举并管理;Logical Display 是 DisplayManagerService 面向应用暴露的逻辑显示单元,通常与物理屏一一对应,但在镜像或虚拟显示场景下可以多对一或一对多;DisplayDevice 是 SurfaceFlinger 内部的显示设备抽象,承载合成目标;Layer 是需要被合成的图层,最终由 HWC 决定“谁叠加、谁送 GPU、谁直接扫描输出”。
HWC(Hardware Composer)是本节最核心的对象。它位于 SurfaceFlinger 与显示驱动之间,职责是接收图层列表和显示配置,返回合成决策:哪些图层由硬件叠加器(Overlay)直接合成,哪些必须回退到 GPU(Client Composition)。多显示器场景下,HWC 还要处理每个显示设备独立的图层栈、独立的刷新率、独立的色彩空间以及热插拔事件。
- DisplayManagerService:显示设备的注册、状态维护与逻辑显示映射。
- SurfaceFlinger:图层管理、合成调度、与 HWC 交互。
- HWC HAL:厂商实现的硬件合成抽象层,负责能力上报与合成决策。
- DRM/KMS 或厂商显示驱动:真正操作 CRTC、Plane、Encoder、Connector 的底层。
三、整体框架:一张图看清多显示器数据流
下面的 SVG 展示了从应用到物理屏的完整链路,以及多显示器场景下新增的关键分支。请重点观察:每个物理屏在 HWC 层拥有独立的 Display 上下文,SurfaceFlinger 需要为每个显示设备分别准备合成输入,而 GPU 合成与硬件叠加的边界由 HWC 动态决定。
四、实战路线图:按阶段推进,避免“一上来就改 HWC”
多显示器集成工程最忌讳“先改代码再理解链路”。建议按以下五个阶段推进,每个阶段都有明确的交付物和验证手段。
| 阶段 | 核心任务 | 关键交付物 | 验证方式 |
|---|---|---|---|
| 1. 链路认知 | 梳理 App→SF→HWC→驱动→屏 的完整通路 | 数据流图、模块职责表 | 能口述每层输入输出 |
| 2. 环境搭建 | 确认 HWC 版本、显示接口、调试通道 | 可编译的 HWC 模块、dumpsys 基线 | dumpsys SurfaceFlinger 正常输出 |
| 3. 单屏打通 | 先让主屏在 HWC 下稳定合成 | Overlay 使用率、帧率基线 | systrace 无异常掉帧 |
| 4. 多屏扩展 | 增加副屏、处理热插拔与独立合成 | 多 Display 配置、热插拔回调 | 插拔 50 次无黑屏/崩溃 |
| 5. 性能与量产 | 带宽评估、延迟优化、异常恢复 | 性能报告、排障手册 | 长时间压测稳定 |
五、典型场景与常见误区
以车载双屏为例:中控屏与仪表屏通常要求独立显示、独立刷新率,仪表屏对延迟极其敏感。此时 HWC 需要为两个 Display 分别维护图层栈,并优先保证仪表屏走硬件叠加。若把仪表屏图层错误地回退到 GPU 合成,延迟会明显上升,甚至出现撕裂。
常见误区二:忽略 HWC 能力上报。不同厂商 HWC 支持的 Overlay 数量、缩放能力、色彩格式不同,盲目假设“都能硬件合成”会导致回退和性能塌陷。
常见误区三:热插拔只处理“插入”,不处理“拔出”和“异常重连”。量产环境里,拔出时的资源释放和状态清理往往才是崩溃高发点。
六、调试入口:先学会看,再学会改
在动手改 HWC 之前,先掌握几条最常用的观察命令。它们能帮你快速判断当前显示状态、合成方式和图层归属。
# 查看当前显示设备与逻辑显示映射
adb shell dumpsys display
# 查看 SurfaceFlinger 合成状态与 HWC 信息
adb shell dumpsys SurfaceFlinger
# 抓取显示相关 trace(含 HWC 合成决策)
adb shell atrace -t 5 -b 8192 gfx view sched freq
# 查看 HWC 能力与显示配置(厂商实现路径可能不同)
adb shell dumpsys SurfaceFlinger --display-id
建议在课程初期就建立一份“基线记录”:主屏在默认配置下的帧率、Overlay 使用数量、GPU 合成占比、热插拔耗时。后续任何修改都与此基线对比,才能判断优化是否真正有效。