Ahao's Technical Blog Ahao's Technical Blog
首页
  • 001.基础篇
  • 002.玩转AOSP篇
  • 003.学穿Binder篇
  • 004.基础组件篇
  • 005.系统启动过程分析
  • 006.Hal开发入门与实践
  • 007.显示系统
  • 008.核心系统服务
  • 009.开发工具
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

阿豪讲Framework

不积跬步无以至千里
首页
  • 001.基础篇
  • 002.玩转AOSP篇
  • 003.学穿Binder篇
  • 004.基础组件篇
  • 005.系统启动过程分析
  • 006.Hal开发入门与实践
  • 007.显示系统
  • 008.核心系统服务
  • 009.开发工具
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 基础篇

  • 玩转AOSP篇

  • 学穿Binder篇

  • 基础组件篇

  • 系统启动过程分析

  • Hal开发入门与实践

  • 显示系统

    • 如何调试SurfaceFlinger
    • SurfaceFlinger概述
    • HWC 接口分析
    • 启动过程总览
    • SurfaceFlinger 初始化
    • RenderEnginge 初始化
    • 显示疑难问题分析基础
      • Android 显示疑难问题分析基础
      • 1. 显示基本流程
      • 2 Peffetto 中,显示相关 Slice
        • 2.1 Vsync 信号
        • 2.2 绘制过程
        • 2.3 SF 中的合成过程
  • 核心系统服务

  • 开发工具

  • Framework
  • 显示系统
ahao
2025-10-08
目录

显示疑难问题分析基础

# Android 显示疑难问题分析基础

# 1. 显示基本流程

分析卡顿需要了解显示的基本流程:

  • 绘制过程(DrawFrame)
    • 申请 Buffer
    • 绘制(HWUI Opengl/Vulkan 视频解码等方式绘制)
    • 提交 buffer
  • 合成 (Compose):
    • 一个 Vsycn 周期内收集到多个 Buffer
    • 多个 Buffer 叠合成到一个 Buffer(Device/Clent 合成)
    • 送到 panel 显示
    • 显示完成,release buffer

整体的 Buffer 流转如下图所示:

20250928130244

# 2 Peffetto 中,显示相关 Slice

# 2.1 Vsync 信号

20250927160802

  • VSYNC-app VSYNC-sf,是在 VSYNC—HW 信号基础上重新计算以后发出周期性软件信号
  • VSYNC-app 是控制 App 端绘制过程帧率的,VSYNC-sf 是控制 SurfaceFlinger 合成过程的帧率的
  • 两者一般会有一定的相位差,用于避免短时间内过高的资源占用。

# 2.2 绘制过程

App 中的帧绘制:

20250927174802

同步 DisplayList 过程会调用到主线程的 wait 操作,会阻塞主线程,绝大部分情况,阻塞时间很短。在 ANR 堆栈中经常会出现类型如下的堆栈信息:

android.graphics.HardwareRenderer.nSyncAndDrawFrame(Native method)
android.graphics.HardwareRenderer.syncAndDrawFrame(HardwareRenderer.java:465)
android.view.ThreadedRenderer.draw(ThreadedRenderer.java:645)
android.view.ViewRootImpl.draw(ViewRootImpl.java:4831)
android.view.ViewRootImpl.performDraw(ViewRootImpl.java:4537)
android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:3630)
android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:2357)
android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:9304)
android.view.Choreographer$CallbackRecord.run(Choreographer.java:1129)
android.view.Choreographer.doCallbacks(Choreographer.java:926)
android.view.Choreographer.doFrame(Choreographer.java:840)
android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1114)
android.os.Handler.handleCallback(Handler.java:938)
android.os.Handler.dispatchMessage(Handler.java:99)
android.os.Looper.loopOnce(Looper.java:210)
android.os.Looper.loop(Looper.java:299)
android.app.ActivityThread.main(ActivityThread.java:8306)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

nSyncAndDrawFrame 方法用于发起同步和 RenderThread 后续的回执操作,这里会有一个主线程的 wait 操作,如果这个时候发生了 ANR ,会去扫描所有线程状态,打印出 wait 状态的调用栈信息。如果发生 ANR 的时候,主线程正在执行同步操作,就会看到 nSyncAndDrawFrame 相关堆栈,很多时候并不是同步操作本身造成的。

显示 Buffer 申请与 Fence 处理:

20250928131250

显示 Buffer 的提交:

20250928133453

GPU 渲染过程可能会等待 HWC Fence:

20250928133024

# 2.3 SF 中的合成过程

Vsync 申请与分发过程:

20250928164311

SurfaceFlinger 主线程 commit 过程:

20250928220326

  • updateLayerSnapshots 函数负责在每个帧周期中处理图层事务、更新图层状态、生成图层快照,并执行缓冲区闩锁(buffer latching)操作
  • chooseRefreshRateForContent 函数用于选择当前的刷新率。

sf 主线程 composite 过程:

  • device 合成的情况

20250928222322


20250928225319

OverlayEngine 是 HWC 中处理图层合成的主要线程,调用显示驱动完成显示相关的操作(mtk 平台)。

  • client + device 合成的情况

20250928230703

需要注意的是,drawLayers 只是在做 GPU 合成需要的 texture 的准备工作,如果是 drawLayers 本身时间久,则瓶颈是在 CPU, 需分析 CPU 频率, Loading 以及大小核状况


20250928230935

  • 在 Client 合成中,“RE Completion” 与 “GPU Completion” 本质上通过同一个 Fence 串联在一起:RenderEngine 提交 GPU 作业并返回一个 Fence ;当该 Fence 发出信号时,表示 GPU 完成了这次 Client 目标缓冲的渲染。
  • 这个 Fence 随后充当多重角色:作为 readyFence 入队到 BufferQueue 、作为 client target acquire fence 传递给 HWC 的 setClientTarget 、并被 FrameTracker / TimeStats 记录时序。

Fence 的整体流程分析可以参考下图:

20250928133252

Fence 还有一点需要特别注意,当系统属性配置如下时:

  • debug.sf.latch_unsignaled = false
  • debug.sf.auto_latch_unsignaled = true

SurfaceFlinger 会被配置为 AutoSingleLayer 模式,会存在锁存 unsignaled buffer 的情况。

20250928153846

AutoSingleLayer 模式主要在视频播放,游戏,相机等场景适用,更多信息可以参考 google 文档:https://source.android.google.cn/docs/core/graphics/unsignaled-buffer-latch?hl=zh-cn

RenderEnginge 初始化
Perfetto 上手指南1 —— Trace 的抓取

← RenderEnginge 初始化 Perfetto 上手指南1 —— Trace 的抓取→

最近更新
01
Perfetto 上手指南1 —— Trace 的抓取
10-08
02
Perfetto 上手指南2 —— 基础使用
10-08
03
Perfetto 上手指南3 —— CPU 信息分析
10-08
更多文章>
Theme by Vdoing | Copyright © 2020-2025 AHao Framework | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式