4. 多显示器基础
在 Android 多显示器集成工程中,HWC(Hardware Composer)是连接 SurfaceFlinger 与显示硬件的关键抽象层。理解主显、副显、虚拟显示、Overlay、镜像与扩展模式这几个基础概念,是后续进行多屏配置、性能调优和问题定位的前提。本节从显示对象的角色、数据流向和合成路径三个维度,梳理这些概念的本质区别。
一、显示对象的角色划分
Android 显示系统把每一个可独立刷新的输出目标抽象为 DisplayDevice。按照物理连接方式和用途,可以划分为以下几类:
- 主显(Primary Display):系统启动时默认激活的物理显示设备,通常对应内置屏幕。它承载 SystemUI、Launcher、状态栏等系统级 UI,是
DisplayManagerService中 ID 为 0 的默认显示。 - 副显(Secondary Display):除主显之外的物理显示设备,如通过 HDMI、DP、USB-C 接入的外接显示器,或车机中的后排屏、副驾屏。副显可以独立承载 Activity,也可以仅作为主显的镜像输出。
- 虚拟显示(Virtual Display):不对应真实物理接口的逻辑显示设备,由应用或系统通过
DisplayManager.createVirtualDisplay()创建。典型用途包括录屏、投屏、CarPlay/Android Auto 投射、VR 双目渲染等。虚拟显示的内容最终需要经过编码或合成后送到某个真实输出。
二、Overlay 与合成路径
Overlay 在 Android 中有两层含义,需要区分清楚:
- HWC Overlay(硬件叠加层):HWC 将多个 Layer 直接交给显示控制器(Display Controller)的叠加单元进行合成,不经过 GPU。它能显著降低 GPU 负载和功耗,但受限于硬件叠加器数量、Layer 格式、缩放能力和 Z 序限制。
- Overlay 显示类型:在
DisplayManager中,VIRTUAL_DISPLAY_FLAG_PUBLIC、PRESENTATION等标志决定虚拟显示是否作为 Overlay 呈现给用户。
当 HWC 无法处理某个 Layer 时,会将其标记为 GPU 合成(Client Composition),由 SurfaceFlinger 用 RenderEngine 完成。多显示器场景下,每个显示设备都有独立的 Layer 列表和合成策略,HWC 需要为每个 Display 分别决策 Overlay 与 GPU 的分配。
// 典型 HWC 合成决策日志片段
HWC2: display=0 layers=5 overlay=3 client=2
HWC2: display=1 layers=2 overlay=2 client=0
HWC2: virtual display=2 layers=1 client=1 (GPU fallback)
三、镜像模式与扩展模式
镜像(Mirroring)与扩展(Extension)是多显示器最上层的两种呈现模式,直接决定内容如何分配到各个屏幕。
| 对比维度 | 镜像模式 | 扩展模式 |
|---|---|---|
| 内容关系 | 副显复制主显内容 | 各屏显示独立内容 |
| Display ID | 副显复用主显逻辑显示 | 每屏独立 Display ID |
| 分辨率处理 | 需缩放对齐,可能降采样 | 各屏按原生分辨率输出 |
| HWC 合成 | 同一 Layer 列表送多路 | 每路独立 Layer 列表 |
| 典型场景 | 会议投屏、车机同显 | 副驾娱乐、后排独立屏 |
| 性能影响 | 带宽翻倍,GPU 负载较低 | 合成压力分散,但总带宽高 |
镜像模式下,SurfaceFlinger 会把主显的合成结果同时送到副显,HWC 需要处理缩放和色彩空间转换。扩展模式下,每个 Display 拥有独立的 Layer 栈,WindowManager 根据 Activity 的 displayId 将其分配到对应屏幕。
四、数据流与信号链
从应用绘制到屏幕点亮,多显示器场景的数据流可以概括为:应用 → SurfaceFlinger → HWC → Display Driver → 物理接口/编码器。虚拟显示则多一条分支:虚拟显示 Surface → 编码/写回 → 网络或本地文件。
五、典型场景与配置示例
以车机双屏为例:中控屏为主显,副驾屏为副显。若采用扩展模式,副驾屏可独立运行视频 App;若采用镜像模式,副驾屏与中控屏显示相同内容。虚拟显示则常用于将副驾屏内容投送到后排头枕屏。
# 查看当前显示设备
adb shell dumpsys display | grep -E "DisplayDeviceInfo|mDisplayId"
# 强制启用副显扩展模式(示例)
adb shell wm set-display-user-rotation 1 0
adb shell settings put global overlay_display_devices "1920x1080/320"
dumpsys SurfaceFlinger 中每个 Display 的 Layer 数量和合成类型。若副显出现黑屏,先检查 HWC 是否支持该分辨率与色彩格式,再排查 DisplayDriver 的时序配置。
六、常见误区与复盘
- 误区一:虚拟显示等于副显。虚拟显示没有物理接口,其内容必须经过编码或写回才能被外部看到;副显是真实物理输出。
- 误区二:镜像模式没有性能开销。镜像需要额外缩放和带宽,高分辨率下可能触发 GPU 合成回退。
- 误区三:Overlay 越多越好。Overlay 受硬件叠加器数量和格式限制,超出后仍会回退到 GPU 合成,需结合具体平台验证。
- 复盘要点:多显示器问题应沿着“应用 Surface → SurfaceFlinger Layer → HWC 合成决策 → DisplayDriver 输出”这条链路逐段排查,避免只盯应用层。
掌握主显、副显、虚拟显示、Overlay、镜像与扩展模式的概念与区别,是后续进行 HWC 多屏合成策略配置、带宽评估和故障定位的基础。在实际工程中,应结合具体平台的 HWC 能力集和 DisplayDriver 限制,选择最合适的显示模式与合成路径。