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 双目渲染等。虚拟显示的内容最终需要经过编码或合成后送到某个真实输出。
核心区别:主显与副显是“物理输出端”,虚拟显示是“逻辑输出端”。虚拟显示本身不发光,它必须借助 MediaCodec、SurfaceFlinger 或 HWC 的写回路径才能被看到。

二、Overlay 与合成路径

Overlay 在 Android 中有两层含义,需要区分清楚:

  1. HWC Overlay(硬件叠加层):HWC 将多个 Layer 直接交给显示控制器(Display Controller)的叠加单元进行合成,不经过 GPU。它能显著降低 GPU 负载和功耗,但受限于硬件叠加器数量、Layer 格式、缩放能力和 Z 序限制。
  2. 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 → 编码/写回 → 网络或本地文件。

Android 多显示器数据流与合成路径 应用 / Activity Surface 绘制 SurfaceFlinger Layer 管理 / 合成调度 HWC Overlay / GPU 决策 Display Driver 时序 / 接口输出 主显 / 副显 HDMI / DP / MIPI DSI 虚拟显示 VirtualDisplay 编码 / 写回 MediaCodec / GPU 回读 网络 / 本地文件 投屏 / 录屏 镜像模式 同一 Layer 列表 → 多路输出 需缩放对齐,带宽翻倍 扩展模式 每屏独立 Display ID 与 Layer 栈 按原生分辨率输出,合成压力分散

五、典型场景与配置示例

以车机双屏为例:中控屏为主显,副驾屏为副显。若采用扩展模式,副驾屏可独立运行视频 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 限制,选择最合适的显示模式与合成路径。