3. Android显示架构

Android 的显示子系统并不是单一模块,而是一条从应用绘制到屏幕点亮的完整流水线。应用通过 Canvas、OpenGL ES 或 Vulkan 把内容画进图形缓冲区(GraphicBuffer),SurfaceFlinger 负责把这些来自不同进程的图层按 Z 序合成,Hardware Composer(HWC)决定哪些图层交给显示控制器硬件叠加、哪些必须由 GPU 先合成,Gralloc 负责缓冲区的分配与映射,BufferQueue 则承担生产者与消费者之间的缓冲区流转,而 VSync 为整条链路提供节拍。理解这六个角色的分工与协作,是后续做 DRM/KMS 集成、排查掉帧与撕裂问题的基础。

一、核心角色与职责

从下往上看,显示链路可以拆成“缓冲区生产—合成决策—硬件送显”三层。应用侧是生产者,SurfaceFlinger 是合成者,HWC 与显示驱动是最终执行者。

  • SurfaceFlinger:系统合成服务,管理所有 Layer,接收 VSync 后触发合成,输出到 HWC 或 GPU。
  • HWC(Hardware Composer):HAL 层合成抽象,向 SurfaceFlinger 提供显示能力与叠加策略,决定 Overlay 与 GPU 合成的划分。
  • Gralloc:图形内存分配器,按 usage、格式、宽高分配 GraphicBuffer,并处理跨进程句柄传递。
  • BufferQueue:生产者/消费者模型的核心,维护 dequeue、queue、acquire、release 状态机。
  • VSync:垂直同步信号,分为 HW VSync 与 SW VSync,驱动应用绘制与合成节奏。

二、显示合成流程与数据流

一次典型的合成周期如下:应用在收到 VSync 后开始绘制,把完成的缓冲区 queue 到 BufferQueue;SurfaceFlinger 在下一个 VSync 到来时被唤醒,遍历各 Layer 的 BufferQueue,调用 HWC 的 prepare 接口;HWC 根据图层数量、格式、缩放、遮挡关系给出合成策略;SurfaceFlinger 据此把需要 GPU 合成的图层先合成到一张目标缓冲区,再把所有 Overlay 图层与 GPU 合成结果一起交给 HWC set 接口;HWC 通过 DRM/KMS 提交到显示控制器,扫描输出到屏幕。整个过程中,BufferQueue 的 acquire/release 保证缓冲区不会被同时读写。

Android 显示合成数据流与 VSync 节拍 VSync 节拍 V1 V2 V3 V4 应用进程 Canvas / GL / Vulkan dequeueBuffer → 绘制 BufferQueue queue / acquire release 回收 SurfaceFlinger Layer 管理 / 合成调度 GPU 合成目标缓冲 HWC / HWC2 prepare / set Overlay 决策 Gralloc GraphicBuffer 分配 usage / format / 句柄 DRM / KMS 显示驱动 Plane 配置 → CRTC → Encoder → Connector → Panel 物理屏幕 / 显示面板 queue acquire prepare/set 分配 触发绘制 触发合成

三、BufferQueue 状态机与 Gralloc 参数

BufferQueue 是理解“为什么画面会延迟一帧”的关键。它内部维护 FREE、DEQUEUED、QUEUED、ACQUIRED 等状态,生产者 dequeue 拿到空闲槽位,绘制完成后 queue 交还,消费者 acquire 后使用,用完 release 归还。若生产者 queue 时所有槽位都被占用,就会阻塞等待,这正是掉帧的常见来源。

// 典型 BufferQueue 状态流转
FREE --dequeueBuffer--> DEQUEUED --queueBuffer--> QUEUED
QUEUED --acquireBuffer--> ACQUIRED --releaseBuffer--> FREE

// Gralloc 分配关键参数
usage  = GRALLOC_USAGE_HW_COMPOSER | GRALLOC_USAGE_HW_TEXTURE
format = HAL_PIXEL_FORMAT_RGBA_8888
width  = 1080, height = 2400, stride 由驱动对齐决定

Gralloc 的 usage 标志直接决定缓冲区放在哪块内存、能否被显示控制器直接扫描。例如带 GRALLOC_USAGE_HW_COMPOSER 的缓冲区才可能被 HWC 作为 Overlay 使用;若格式或对齐不满足硬件要求,HWC 会退回 GPU 合成,功耗和带宽随之上升。

四、典型场景与排障思路

假设一台设备在滑动列表时出现周期性卡顿。可以先通过 dumpsys SurfaceFlinger 查看各 Layer 的合成方式与帧率,再用 dumpsys gfxinfo 观察应用侧绘制耗时。若发现某层始终走 GPU 合成,应检查其格式是否为 HWC 不支持、是否被标记为 GRALLOC_USAGE_HW_COMPOSER,以及缩放比例是否超出 Overlay 能力。

现象可能原因排查入口
画面撕裂未按 VSync 提交,或 HWC 未启用dumpsys SurfaceFlinger --latency
掉帧卡顿BufferQueue 满、GPU 合成过多dumpsys gfxinfo、systrace
功耗偏高Overlay 退回 GPU 合成HWC 日志、Layer 合成类型
花屏/绿屏Gralloc 格式或 stride 不匹配Gralloc 分配参数、DRM plane 格式
调试显示问题时,优先确认三件事:当前帧由谁合成(HWC 还是 GPU)、缓冲区格式是否被硬件接受、VSync 是否按预期触发。这三项确定后,大部分显示异常都能快速定位到具体模块。
常见误区:认为 SurfaceFlinger 一定用 GPU 合成所有图层。实际上现代 Android 优先使用 HWC Overlay,GPU 只处理无法叠加的图层。若忽略这一点,在 DRM 集成时容易错误估计带宽与功耗预算。