渲染管线全景:从 View 绘制到屏幕显示
2026/8/9大约 2 分钟渲染管线Android 14渲染绘制显示
渲染管线全景:从 View 绘制到屏幕显示
应用主线程遍历 View 树并记录绘制命令,RenderThread 与 GPU 生产图形缓冲,SurfaceFlinger 再按显示节拍合成输出。一帧迟到并不自动说明 draw() 慢,必须先确定延迟位于哪一段。
一帧跨过应用、GPU 与合成器
| 常见误解 | 正确理解 |
|---|---|
| View 绘制完就直接上屏 | 绘制结果要变成 Surface 缓冲,再经过合成才显示 |
| 所有绘制都在主线程 | 记录在主线程,真正画图在 RenderThread 与 GPU |
| 渲染就是 SurfaceFlinger 的事 | SurfaceFlinger 只做合成,应用侧绘制同样决定帧质量 |
核心结论
- 主链:measure/layout/draw(主线程)→ DisplayList 记录 → RenderThread 绘制 → GPU 输出 → Surface/BufferQueue → SurfaceFlinger 合成。
- 主线程只负责记录绘制指令,不在主线程真正画图。
- RenderThread 与主线程并行,减少主线程阻塞。
- Surface 是应用与合成系统的交接点,BufferQueue 承载缓冲流转。
- 掉帧可能发生在主线程、RenderThread、GPU 或合成任一段。
渲染主链全景
逐步解释:
- 测量/布局:主线程计算尺寸与位置。
- 记录绘制:onDraw 把指令记入 DisplayList。
- 执行绘制:RenderThread 在后台执行 DisplayList,GPU 出图。
- 输出:帧写入 Surface 的缓冲队列。
- 合成显示:SurfaceFlinger 合成各 Surface 并上屏。
常用在哪些地方
按排查频率排列:
- 页面卡顿与掉帧:主线程、RenderThread 或合成侧。
- 绘制性能:onDraw 复杂、DisplayList 过大。
- 黑屏/首帧慢:Surface 与合成时序。
- 动画流畅性:VSync 与缓冲调度。
- 多窗口/分屏:多 Surface 合成。
验证与排障
环境:开发设备或模拟器;以下命令不需要 root。
adb shell dumpsys gfxinfo <包名> framestats
adb shell dumpsys gfxinfo <包名> | grep -E "Janky|50th|95th"
adb shell dumpsys SurfaceFlinger | head -50gfxinfo 看应用侧帧数据;dumpsys SurfaceFlinger 看合成侧状态。先确认掉帧在应用侧 还是合成侧,再进入对应章节定位。
源码入口
| 文件 | 关键位置 | 作用 |
|---|---|---|
View.java | measure() / draw() | 主线程绘制 |
libs/hwui/ | RenderNode/DisplayList | 指令记录 |
RenderThread | 绘制执行 | 异步绘制 |
SurfaceFlinger | 合成 | 显示 |
公共路径:frameworks/base/core/java/android/view/ 与 frameworks/base/libs/hwui/。行号以 r75 检索为准。
从 View 树的工作开始,见 测量、布局与绘制。