【求助】【已解决】rk3588芯片的板子运行4.0 Release版本开机动画卡顿怎么排查?
板卡不是dayu210,但是芯片是rk3588,使用hdmi接口,编译的系统能够正常启动进入锁屏页面,但是启动时开机动画非常卡。 从内核启动日志看,mali能够正常初始化。 开机过程视频和启动日志参见附件。 这个问题应该怎么排查呢?
板卡不是dayu210,但是芯片是rk3588,使用hdmi接口,编译的系统能够正常启动进入锁屏页面,但是启动时开机动画非常卡。
从内核启动日志看,mali能够正常初始化。
开机过程视频和启动日志参见附件。
这个问题应该怎么排查呢?
一、htrace分析
按照回复里提供的指导,使用smartperf工具连接rk3588开发板,修改bootanimation采用图片显示模式,采集了运行时的tracing数据,htrace文件已经作为附件上传(rk3588_boot.zip)。
自己分析了以下,发现以下现象:
1、rs服务周期性地能够正常处理4帧然后卡1.1s
2、单帧处理时长30ms左右,是没法满足60Hz帧率要求的
二、原因及处理办法
1、rs为什么会延迟vsync处理1.1s呢?VSync-rs distributor是正常发送了vsync事件的。
这个问题通过在VSyncGenerator、VSyncDistributor、VSyncReceiver、RSMainThread这几个UI更新链条上的处理类加了些日志,对比正常处理循环和异常处理循环的执行过程,发现vsync处理延迟时,distributor向rs发送vsync事件后,rs服务没有立即执行,同时从rs恢复执行后的tracing发现,rs一次接收到了2条vsync数据(一条数据的dataCount:24bytes),基本确定vsync是正常发送了的,只是rs没有及时处理。
rs回复处理vsync事件之前,有如下报错日志,就顺便查了一下Subscribe Failed是rs的哪个方法记录的,定位到RSMainThread::SubscribeAppState(),而它的处理是通过rs的主线程异步执行的,这才怀疑到是不是它阻塞了主线程。注释掉这个方法的调用后,UI果然不卡顿了。
01-23 13:08:02.667 766 766 E C01800/SA_CLIENT: GetSystemAbilityWrapper sa 1909 didn't start. Returning nullptr
01-23 13:08:02.667 766 766 E C01799/MemMgr: MemMgrClient::GetMemMgrService get service failed
01-23 13:08:02.667 766 766 E C01799/MemMgr: MemMgrClient::SubscribeAppState MemMgrService is null
01-23 13:08:02.667 766 766 E C01400/OHOS::RS: Subscribe Failed, try again
01-23 13:08:02.667 766 766 I C01400/Vsync: OnReadable: dataCount:48, cb == nullptr:0, now: 139927861374, vsyncId: 440
01-23 13:08:02.667 766 766 I C01400/OHOS::RS: sam: RSMainThread::OnVsync timestamp: 139927861374
01-23 13:08:02.667 766 766 I C01400/OHOS::RS: sam: mainLoop start
2、估计根本原因是单帧合成送显时间太长,所以根本解决办法应该是提高合成效率?是否可以通过降低刷新频率解决卡顿?
这个是最开始怀疑的原因,从合成送显时长来看,的确可能导致丢帧。后来结合VSync事件的distribute逻辑,rs没有调用RequestNextVSync()之前,distributor是不会给rs发送VSync事件的,相当于自动降低帧率了。
3、layer的fencing
经原厂支持,还修改了一处代码,防止多个layer使用一个fencing导致获取buffer产生等待。
device/soc/rockchip/rk3588$ git diff hardware/display/src/display_device/hdi_drm_composition.cpp
diff --git a/rk3588/hardware/display/src/display_device/hdi_drm_composition.cpp b/rk3588/hardware/display/src/display_device/hdi_drm_composition.cpp
index a3de27c..357cdee 100755
--- a/rk3588/hardware/display/src/display_device/hdi_drm_composition.cpp
+++ b/rk3588/hardware/display/src/display_device/hdi_drm_composition.cpp
@@ -308,8 +308,16 @@ int32_t HdiDrmComposition::Apply(bool modeSet)
DISPLAY_CHK_RETURN((ret != 0), DISPLAY_FAILURE,
DISPLAY_LOGE("drmModeAtomicCommit failed %{public}d errno %{public}d", ret, errno));
// set the release fence
- for (auto layer : mCompLayers) {
- layer->SetReleaseFence(static_cast<int>(crtcOutFence));
+ // SAM:S multiple layers need different fence^M
+ //for (auto layer : mCompLayers) {^M
+ // layer->SetReleaseFence(static_cast<int>(crtcOutFence));^M
+ //}^M
+ for (uint32_t i = 0; i < mCompLayers.size(); i++) {^M
+ auto layer = mCompLayers[i];^M
+ if (i == 0)^M
+ layer->SetReleaseFence(static_cast<int>(crtcOutFence));^M
+ else^M
+ layer->SetReleaseFence(dup(static_cast<int>(crtcOutFence)));^M
}
return DISPLAY_SUCCESS;
更多推荐
所有评论(0)