BUGOS2-211770
1、连续latch buffer两次
app线程在指定VSYNC-app(app)周期内完成渲染的绘制,SurfaceFlinger在指定VSYNC-sf周期内完成合成。
binde是一种通讯机制,app线程通过binder提交transition进入bufferTX队列中。
Surfaceflinger main thread:latch buffer拿到buffer之后,才开始合成。
VSYNC-sf:信号值发生改变时,通知surfaceflinger进行侧桌面绘制。(framework框架)
连续latch buffer:一帧对应一个buffer,连续两次latch buffer说明前面有一个buffer没有latch并堆积在一起latch buffer。重点看前一个buffer由于什么原因没有被latch?
桌面绘制合成表现为:SF端transactionReadyTimelineChec里面找不到:Surface(name=Task=23#1131)/@0xc270608_transition-leash#4635,说明SurfaceFlinger当前合成的内容没有进入桌面动画。
原因:VSYNC-app通知FsGsturePriori进行绘制,FsGsturePriori线程的CPU状态处在Runnable、暂时没有多余的资源,第一次动画Transaction晚于SF flushTransaction,SF没有latch到此帧动画transaction,导致没有来的及参与合成。
2、未latch buffer 但buffer少了
(1)未找到桌面绘制表现,SF端transactionReadyBufferCheck里面找不到:Surface(name=Task=23#1131)/@0xc270608_transition-leash#4635,说明SurfaceFlinger当前合成的内容没有进入桌面动画。
(3)往前分析buffer是从哪传过来的?
绘制流程:Vsync-app信号 ——> com.miui.home主线程处理事件 ——> 渲染绘制线程 ——> 执行渲染绘制指令 ———> BufferQueue ———> Vsync-sf信号 ———> 取出BufferQueue合成 ———> 屏幕显示
a.第一种由于binder给了一个假buffer,导致脚本统计错了
b、第二种是桌面会有FsGesturePriori动画和InsetAnimator两个动画,同一个applyToken提交到SF SF flush遍历时PendingTransactionQueues时,InsetAnimator判断frameISEarly返回NotReady,退出队列遍历,导致后面的FsGesturePriori动画也没有flush。这是个已知问题,请带入这笔提交重新测试。https://gerrit.pt.mioffice.cn/c/platform/frameworks/base/+w/4698690
3、latch buffer了但不进行composite
桌面Transactions收集到的未发生变化,属于正常现象。所以这段时间的sf未合成。
正常情况下TransactionHandler:flushTransactions和上一笔发生变化时,onFrameSignal会调用doCommitTransactions,如下图所示:
BUGOS2-277859:sf 的gpu 耗时较长分析:
1、由丢帧数和客观丢帧数可以看出1-5和3-5掉帧更严重
2、3-5trace在此位置总共掉了4帧
3、确认sf和app端,谁先丢的帧
4、app端丢帧就是没有绘制,就看app端的doframe / RenderThread 卡顿原因分为三种情况
(1)确定应用的的Buffer是否充足
(2)确定SurefaceFlinger合成是否慢,及SurfaceFlinger主线程的running时间是否过长
(3)确定上屏时间是否过长,即crtc_commit的时间
原因:由图可知由于buffer空间不充足,app端给buffer太慢导致的丢帧。
5、分析什么原因导致buffer太慢
(1)情况一:GC导致renderthread线程出现texture release,running时间过长导致丢帧。
连续丢帧时com.miui.home的rt线程一直在texture upload running超时。
(2)情况二:应用绘制操作复杂,GPU压力大,出现queueBuffer超时问题,导致buffer过来的慢,引起丢帧。
(3)情况三:应用前几帧layout binder与systemserver通信和主线程执行的其他操作耗时,导致buffer过来的慢,引起掉帧。
(4)情况四:渲染线程renderFrame耗时长,引起丢帧
BUGLC-5188
1、说明
trace中找不到丢帧TAG,说明抓的普通trace、不是用脚本抓的trace,需要手动定位不流畅卡顿的位置。
2、分析
dequeuebuffer耗时长,可先查看sf合成是否超时,一帧耗时超过一个Vsync(60hz 16.66ms), 导致后面的dequeueBuffer耗时长,由于sf合成每一帧的耗时都在30ms左右,需要性能同学帮忙看一下是否有优化空间。可以考虑上大核。
BUGO16UUPV-886:sf 绘制时Transactions未发生变化
合成分为commit和composite两部分,commit执行TransactionHandler函数负责收集。
1、正常情况下onFrameSignal会调用doCommitTransactions。sf绘制时Transactions属性没有发生变化时,这段时间的sf未合成导致sf侧掉18帧。
2、这段时间已经出buffer、latch buffer了,需要桌面动画确定下没有发生变化?
BUGOS2-288766
1、sf侧丢帧。queuebuffer和binder耗时长
BUGOS2-241147
1、VSYNC-sf耗时,查看surfaceflinger
2、sf main thread的drawLayers调用了RenderEngine,surfaceflinger main thread耗时过长,经发现是finishFrame导致的耗时。需要复现问题抓取火焰图
3、finishFrame被RenderEngine 线程唤醒,渲染线程flushsurface耗时
4、复现问题、抓取火焰图
(1)cd /Android/Sdk/ndk/27.0.11718014/simpleperf
(2)抓取应用-p
python3 app_profiler.py -p com.ss.android.article.news -r "-e task-clock:u -f 100 -g"
(3)抓取sf用--pid
adb shell ps -ef | grep -Ei "surfaceflinger"
python3 app_profiler.py --pid 1140 -r "-e task-clock:u -f 100 -g"
(4)转换成report.html
python3 report_html.py
(5)对比U系统抓取火焰图和trace
a.找到丢帧位置:
b.sf耗时
c. 对比U系统上的DrawLayer次数
5、flush surface耗时导致binder耗时
6、crtc_commit导致binder耗时
7、V系统RenderEngine调用的DrawLayer次数较多导致flush surface超时。大部分合成时间超过一个VSYNC周期,则出现合成挤压丢帧。
8、结论:U和V上都会出现RenderEngine DrawLayer次数过多导致丢帧,U DrawLayer是10次、V DrawLayer是13次。N7处理器是sm6225,sm6225只支持4个layer之后,多增加layer就会强推GPU合成,引起整机卡顿。针对这种硬件性能导致的丢帧问题无法进行优化。
BUGOS2-316755
1、抓取gl_trace
查看哪个函数耗时导致flush command等待时间过长。
adb root
adb remount
adb reboot
重启后输入
adb root
adb shell setenforce 0
adb remount
adb shell "mkdir -p /data/vendor/gpu/"
adb shell "chmod 777 /data/vendor/gpu/"
adb shell "rm /data/vendor/gpu/*"
adb shell "echo 0x71e25046=0x7fffffff > /data/vendor/gpu/esx_config.txt"
adb shell "echo 0x19a8f6d0=0x7fffffff >> /data/vendor/gpu/esx_config.txt"
adb shell "echo 0x1429e0e6=0x070b8885 >> /data/vendor/gpu/esx_config.txt"
adb shell "echo 0x200cb3ad=0x618f22ec >> /data/vendor/gpu/esx_config.txt"
adb shell "echo '0x9ac36b79=TRUE' >> /data/vendor/gpu/esx_config.txt"
adb shell "echo '0x8b436b4a=TRUE' >> /data/vendor/gpu/esx_config.txt"
adb shell "echo '0xbf90204d=TRUE' >> /data/vendor/gpu/esx_config.txt"
adb shell "echo '0x1d2b21ec=TRUE' >> /data/vendor/gpu/esx_config.txt"
adb shell "echo > /sys/kernel/tracing/set_event"
adb shell "echo 0 > /sys/kernel/tracing/tracing_on"
adb shell "echo > /sys/kernel/tracing/trace"
adb shell "echo 40960 >/sys/kernel/tracing/buffer_size_kb"
adb shell "echo kgsl:* >> /sys/kernel/tracing/set_event"
adb shell "echo 0 > /sys/kernel/tracing/events/kgsl/kgsl_regwrite/enable"
adb shell "echo 1 > /sys/kernel/tracing/tracing_on"
adb shell setprop "debug.hwui.skia_atrace_enabled" true
adb shell setprop debug.hwui.skia_use_perfetto_track_events false
adb shell setprop debug.renderengine.skia_atrace_enabled true
adb shell "setprop vendor.debug.gpu.provider meow"
adb shell setprop "debug.hwui.skia_tracing_enabled" true
adb shell "stop;start"
2、从gl-trace看flush commands耗时原因是GslMemoryAllocProfile(gpu内存分配机制)函数耗时。
结论:GslMemoryAllocProfile 耗时问题主要是上层Texture纹理太大导致。SF没有优化方法,需要业务修改Texture大小或者缩减个数。GPU耗时问题是因为模糊效果导致的。
文档说明:N16_V_NJ_【Performance】多任务流畅度拆解文档澄清
2、queuebuffer超时,此时应用层gpu占用时间15ms多,sf层GPU耗时7ms多,可能因为sf层gpu抢占了应用层gpu、从而导致queuebuffer超时。
3、命令adb shell dumpsys SurfaceFlinger --hwclayers 查看到锁屏上划场景涉及到四个layer,从trace看到sf层RenderEngine只调用了一次Wallpaper BBQ wrapper,所以不存在加剧了sf层GPU压力。
5、gpu耗时原因。应用gpu被sf gpu抢占,sf每帧都在合成,GPU耗时约4ms多,2-3帧一起阻塞应用GPU,导致应用GPU耗时20多ms。
(1)sf binder耗时,此时binder对端是composer-servic
(2)crtc_commit上屏晚composer-servic耗时
(3)归根结底,还是gpu耗时导致的。
6、在相同机型的对比机上复现问题场景并抓取trace,也出现了gpu耗时引起丢帧。
暂时无法在飞书文档外展示此内容
7、打开KGSL开关抓取trace,查看gpu频率
adb root
adb shell "echo 1024 >/sys/kernel/tracing/buffer_size_kb"
adb shell "chmod 666 /sys/kernel/tracing/events/kgsl/adreno_cmdbatch_queued/enable"
adb shell "chmod 666 /sys/kernel/tracing/events/kgsl/adreno_cmdbatch_ready/enable"
adb shell "chmod 666 /sys/kernel/tracing/events/kgsl/adreno_cmdbatch_submitted/enable"
adb shell "chmod 666 /sys/kernel/tracing/events/kgsl/adreno_cmdbatch_sync/enable"
adb shell "chmod 666 /sys/kernel/tracing/events/kgsl/adreno_preempt_trigger/enable"
adb shell "chmod 666 /sys/kernel/tracing/events/kgsl/adreno_preempt_done/enable"
adb shell "chmod 666 /sys/kernel/tracing/events/kgsl/adreno_cmdbatch_done/enable"
adb shell "chmod 666 /sys/kernel/tracing/events/kgsl/adreno_cmdbatch_retired/enable"
adb shell "chmod 666 /sys/kernel/debug/tracing/events/kgsl/kgsl_pwr_request_state/enable"
adb shell "chmod 666 /sys/kernel/debug/tracing/events/kgsl/kgsl_pwr_set_state/enable"
adb shell "chmod 666 /sys/kernel/debug/tracing/events/kgsl/kgsl_pwrstats/enable"
adb shell "chmod 666 /sys/kernel/debug/tracing/events/kgsl/kgsl_gpubusy/enable"
adb shell "chmod 666 /sys/kernel/debug/tracing/events/kgsl/kgsl_buslevel/enable"
adb shell "chmod 666 /sys/kernel/debug/tracing/events/kgsl/kgsl_pwrlevel/enable"
adb shell "chmod 666 /sys/kernel/debug/tracing/events/kgsl/kgsl_clk/enable"
查看kgsl_pwrlevel和adreno_smdbatch_queued
8、结论:GPU耗时问题是因为模糊效果导致的,U和V都有类似问题。
对比U上,U上也有类似问题,但V上更严重一些,V比U上多了一个离屏layer:drawLayer [FrameLayout] 1220.0 x 2712.0,麻烦业务看下能否优化吧。
V:
U:
BUGOS2-304036
结论:送显不及时导致sf侧丢帧,SF 与display binder通信耗时,HwBinder:1524_3 线程running耗时(3-5ms),HwBinder:1524_3 线程跑在CPU0-3小核上,导致SF合成耗时。