常见SF耗时问题总结

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合成耗时。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值