2. Android显示系统基础

Android 的显示系统是一条从应用绘制到屏幕点亮的完整流水线。理解这条流水线,是诊断黑屏、花屏、闪屏、掉帧等问题的前提。很多工程师在排查显示故障时,习惯直接抓 logcat 或看 SurfaceFlinger 的 dump,但如果对各个模块的职责边界和协作顺序没有清晰认识,就很容易把问题定位到错误的层级。本节将围绕六个核心组件,梳理它们各自的角色以及彼此之间的数据流与控制流关系。

一、核心组件与职责边界

Android 显示栈可以粗略分为三层:应用与框架层、系统服务层、硬件抽象层。每一层都有明确的职责,任何一层出错都会表现为屏幕异常。

  • WindowManager(WMS):负责窗口的层级、位置、大小、可见性和焦点管理。它决定“谁应该显示、显示在哪里、谁在上面”,但不负责真正的像素合成。
  • DisplayManager(DMS):负责显示设备的枚举、状态管理、分辨率与刷新率配置,以及多屏场景下的逻辑显示划分。它回答“有哪些屏幕、当前处于什么状态”。
  • SurfaceFlinger(SF):系统合成器,接收各个应用和系统窗口提交的 Buffer,按照 WMS 给出的层级关系进行合成,输出到显示设备。
  • HWC(Hardware Composer):硬件合成抽象层,决定哪些图层由 GPU 合成、哪些由显示控制器直接叠加,是性能与功耗的关键。
  • Gralloc:图形内存分配器,负责为图形 Buffer 分配物理内存,并处理不同硬件模块之间的共享与同步。
  • 显示管线(Display Pipeline):从应用绘制、Buffer 提交、合成、送显到屏幕扫描输出的完整链路。
显示问题的定位口诀:先看“有没有内容”(应用/SF),再看“内容放对没有”(WMS/DMS),最后看“内容送出去没有”(HWC/Gralloc/驱动)。

二、显示管线的数据流与协作关系

下面这张图展示了从应用到屏幕的主要数据流与控制流。应用通过 Surface 提交图形 Buffer,SurfaceFlinger 依据 WindowManager 提供的层级信息组织图层,再通过 HWC 决定合成策略,最终由显示驱动扫描输出到屏幕。DisplayManager 则贯穿其中,管理显示设备状态与配置。

Android 显示管线核心组件协作关系 应用进程 Canvas / OpenGL / Vulkan Surface / BufferQueue 生产者-消费者队列 Gralloc 图形内存分配与共享 dequeueBuffer alloc / lock SurfaceFlinger 系统合成器 图层管理 Layer 合成策略 Composition VSync 调度 Buffer 消费 queueBuffer 共享内存 HWC Hardware Composer GPU 合成 / Overlay 决策 图层叠加与送显 图层列表 显示驱动 / DSI / DP 扫描输出到物理屏幕 送显 DisplayManager 显示设备枚举 / 状态 / 分辨率 刷新率 / 多屏逻辑显示 WindowManager 窗口层级 / 位置 / 大小 可见性 / 焦点 / Z-order 层级信息 显示配置 设备状态 数据流(Buffer 提交) 控制流(配置与层级) 硬件送显路径

三、关键协作机制解析

从图中可以看到,SurfaceFlinger 处于承上启下的核心位置。它向上接收来自应用和系统窗口的 Buffer,向下通过 HWC 与显示驱动交互。但 SurfaceFlinger 并不是孤立工作的,它需要 WindowManager 提供窗口层级,需要 DisplayManager 提供显示设备信息,需要 Gralloc 提供内存支持。

具体来说,当应用需要绘制一帧时,会通过 Surface 的 BufferQueue 申请一个空闲 Buffer,这个 Buffer 的物理内存由 Gralloc 分配。应用绘制完成后,将 Buffer 入队到 BufferQueue。SurfaceFlinger 在 VSync 信号到来时,从各个 BufferQueue 中取出待合成的 Buffer,结合 WindowManager 提供的 Z-order 和可见区域信息,生成图层列表。随后 SurfaceFlinger 将图层列表交给 HWC,HWC 根据硬件能力决定哪些图层由 GPU 合成、哪些由显示控制器直接叠加,最终将合成结果送入显示驱动,由驱动扫描输出到屏幕。

在排查黑屏问题时,可以按照“应用是否绘制 → Buffer 是否入队 → SF 是否合成 → HWC 是否送显 → 驱动是否输出”的顺序逐级确认,避免盲目猜测。

四、典型场景与故障映射

下面这张表将常见显示故障与可能的责任模块对应起来,帮助快速缩小排查范围。

故障现象 可能责任模块 典型排查手段
应用界面全黑但系统正常 应用绘制 / Surface / BufferQueue 检查应用是否 dequeueBuffer、是否 queueBuffer
窗口位置错乱或层级异常 WindowManager dumpsys window 查看窗口层级与可见性
分辨率或刷新率异常 DisplayManager dumpsys display 查看显示设备状态
合成掉帧、GPU 负载高 SurfaceFlinger / HWC dumpsys SurfaceFlinger 查看合成策略
花屏、绿屏、内存错乱 Gralloc / 显示驱动 检查 Gralloc 分配日志与驱动送显参数
完全无显示、背光亮但无图 HWC / 显示驱动 / 屏幕 检查 HWC 送显日志与 DSI 输出状态

五、常见误区与复盘要点

第一个常见误区是“黑屏就是 SurfaceFlinger 的问题”。实际上,SurfaceFlinger 只是合成器,如果应用根本没有提交 Buffer,或者 WindowManager 没有把窗口标记为可见,SurfaceFlinger 也无能为力。因此,排查时必须先确认上游是否有内容产生。

第二个误区是“HWC 只是硬件加速,不影响功能”。HWC 的合成策略直接决定了图层是否被正确叠加。如果 HWC 错误地将某个图层标记为跳过,或者 Overlay 配置与驱动不匹配,就会导致部分图层不显示或显示异常。

第三个误区是“Gralloc 只是内存分配,与显示无关”。Gralloc 分配的 Buffer 需要满足显示硬件的格式、对齐和共享要求。如果 Gralloc 分配的格式与 HWC 或驱动期望的不一致,就会出现颜色异常、花屏甚至无法送显。

在分析显示问题时,建议同时抓取 SurfaceFlinger、WindowManager、DisplayManager 三份 dumpsys 信息,并对照 HWC 的送显日志,形成完整的证据链,而不是只依赖单一模块的日志。

理解这六个组件的职责与协作关系,是后续学习启动流程、黑屏诊断和性能优化的基础。只有清楚每一层“应该做什么”和“实际做了什么”,才能在故障发生时快速定位到正确的层级。