Android性能优化:定性和定位Android图形性能问题

作者:飞起来_飞过来
转载地址:https://juejin.cn/post/7096288511053004830

简介

本文记录一次Android图形性能问题的分析过程——发现定性定位图形性能问题,以及探讨的性能优化方案。

环境:Android Q + MTK + ARM Mali-G72。

所分析的性能问题(下称case):打开录屏应用并启动后台录屏,滑动前台应用(滑屏)。性能表现差:CPU、GPU负载显著升高、掉帧、用户明显卡顿感,帧率不足30帧,帧渲染、合成耗时急剧飙升(渲染耗时平均为29ms左右)。

经过优化后,相同环境和条件下,渲染帧率稳定在60帧(提升一倍),渲染耗时平均为8.44ms左右(为优化前的不到三分之一的消耗)。

关键词 Keywords: Screen Recording; Frame rate; FPS; GPU utilization; Jank; MediaProjection; VirtualDisplay; MediaCodec; Perfetto; Inferno; Surface; SurfaceTexture; VSYNC; SurfaceFlinger; HWC; Hardware composer; GPU; OpenGL;

发现、定性与定位

FPS

  • 计算FPS的方法和工具

Android框架层通过hwui配合底层完成渲染。该框架本身提供了逐帧渲染分段耗时记录。通过dumpsys gfxinfo可以获取。

io.microshow.screenrecorder/io.microshow.screenrecorder.activity.MainActivity/android.view.ViewRootImpl@6b9b8a9 (visibility=0)
	Draw	Prepare	Process	Execute
	3.80	0.48	13.88	1.64
	1.08	0.50	14.29	1.59
	1.12	0.51	17.49	1.74
	1.74	0.17	15.56	1.39
...
	1.38	0.45	17.64	1.38
	1.56	0.44	10.85	1.38
	3.09	0.24	18.03	1.73
	1.25	0.30	12.43	1.38

使用工具统计帧率与平均耗时(同时打印GPU负载),在开启后台录屏的情况下滑动屏幕,平均渲染耗时高达~29ms,超出16.67ms一倍,导致帧率仅31帧,显著低于60帧。

Average elapsed 28.96 ms
FPS: 31 │ 9.03 0.73 16.76 2.44

# GPU负载 LOADING BLOCKING IDLE
70 0 30

# case的对比——未开启后台录屏
Average elapsed 9.00 ms
FPS: 60 │ 1.56 0.65 5.62 1.17
  • 通过gfx柱状图直观感受性能数据

直观地感受图形渲染性能,除了帧率感受、触控延时外,还可以通过将gfxinfo的分段耗时通过柱状图展示在屏幕上。

这是case性能问题的gfxinfo柱状图,可以看到红柱和绿柱都非常高,远远超越了流畅标准。

其中,绿柱异常放大表明两个Vsync之间耗时显著增长,红柱异常放大表明应用层应用加速使用的DisplayLists大量增长、或图形层使用GLES调用GPU耗时显著增多导致的GPU执行绘制指令耗时变长。

初步定位问题

本节记录初步的分析思路和定位过程。首先我们完成实验(启停后台录屏并滑动屏幕触发渲染)、观测以及记录,拿到了后台录屏启停情况下的FPS、分阶段耗时以及GPU负载(相关数据位于FPS小节)。

开发的工具输出的统计数据计算结果非常直观,一眼可见,后台录屏为Draw阶段带来额外的8倍或8ms耗时,给Process阶段带来额外的2倍或11ms耗时。帧率从60帧坠落到~30帧。

  • 耗时分析 可以看到,主要的额外耗时来自Draw和Process。接下来重点围绕着两part定位问题问题。

60Hz下,上述4个步骤合计耗时小于16.67ms为正常情况。case为~29ms。主要增量来自Draw和Process

经过上述初步分析、观测后,接下来的分析可以围绕Draw和Process开展。由于Android Draw部分涉及较广,包含App 渲染线程(DisplayLists)、UI线程(onDraw方法创建DisplayLists),以及图形栈耗时如SurfaceFlinger、RenderEngine等都可能增加Draw耗时。

这里一个技巧可以初步判断耗时来自App进程(渲染线程和UI线程)还是来自图形栈。如果能判断耗时来自App或图形栈,那么可以缩小分析范围、减少分析工作量。上述四大阶段的耗时统计分类比较宽,实际上还有更详细的分阶段耗时,它呈现在前文描述过的gfx统计信息柱状图上。gfx柱状图会以蓝色(RGB(66,122,249))呈现onDraw方法创建和更新DisplayLists的耗时。如果case与正常情况对比后,这部分耗时(蓝柱大小对比)差异很小,即可说明额外的Draw耗时不是来自App的,极可能来自图形栈。Besides,结合过度绘制分析,判断case与正常情况下是否有更多的额外绘制次数可以协同判断。

——根据上述指导思想,排查出了case的额外Draw耗时与App onDraw无关,多出来的DisplayLists来自App以外的进程,可能是图形栈如SurfaceFlinger

定性问题

本小节介绍问题追踪过程,通过一些方法定位到各阶段的耗时原因,并定性地得出case性能问题的性质。从本小节开始,围绕Perfetto进行分析。这里贴出perfetto的总览,我将关键的信息排序到顶部。前四行分别为

  • 4
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值