说明
前面好早写过一个文章,说明如何把LVGL移到RV1109上的操作,使用DRM方式!但出现刷新效率不高的问题!
因为一直没有真正的应用在产品中,所以也就放下了!
最近开发上需要考虑低成本,低内存的方案,所以后续考虑使用LVGL上来做UI,所以这里捡回来再炒一次!
性能分析
这里还是使用的LV_DEMO中的lv_demo_benchmark来测试的!
代码见前一相关的文:LVGL - RV1109 LVGL UI开发-01
先找到了为什么刷新FPS如此低的原因,主要耗时花在了:
lvgl_drm_flush->display_commit_ex->drm_commit_ex->drmCommit
上面!
这样导致UI的线程绘图也很慢!
解决方式
最开始想使用双缓存的方式来提交,但看代码drmCommit是整屏修改提交的!不过对drm里的这个commit底层操作还是不太了解!
还是把耗时的这个操作分开操作!使用另一个线程来commit,这样只要在另一个线程中,如是UI线程有调用lvgl_drm_flush 这个后,发送一个消息通知刷新线程drm commit操即可!
代码修改很简单,在 drm_commit_ex 中使用一个mutex和cond来通知另一个线程:
#ifdef DRM_COMMIT_THREAD
printf("commit request!!!!!!!!!!!\n");
pthread_mutex_lock(&g_commit_mutex);
pthread_cond_broadcast(&g_commit_cond);
pthread_mutex_unlock(&g_commit_mutex);
#else
ret = drmCommit(&disp->buf[num], disp->width, disp->height, 0, 0, &disp->dev, disp->plane_type);
if (ret) {
fprintf(stderr, "display commit error, ret = %d\n", ret);
}
#endif
这里用了一个宏 DRM_COMMIT_THREAD 来控制!
在另一个线程中主要处理如下,即把drmCommit动作放在这里来操作:
#ifdef DRM_COMMIT_THREAD
void* dsiplay_commit_thread_process(void* data)
{
int ret = 0;
while(g_commit_thread_start_flag)
{
pthread_mutex_lock(&g_commit_mutex);
pthread_cond_wait(&g_commit_cond, &g_commit_mutex);
pthread_mutex_unlock(&g_commit_mutex);
//printf("dsiplay_commit_thread_process!!!!!!............\n");
ret = drmCommit(&g_disp.buf[g_num], g_disp.width, g_disp.height, 0, 0, &g_disp.dev, g_disp.plane_type);
if (ret) {
fprintf(stderr, "display commit error, ret = %d\n", ret);
}
usleep(1000 * 40);
}
}
int display_commit_thread_start()
{
int ret = 0;
pthread_t pid = 0;
pthread_attr_t attr;
ret = pthread_attr_init(&attr);
if(ret != 0)
{
printf("start pthread_attr_init failure!!!\n");
return -1;
}
ret = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
if(ret != 0)
{
pthread_attr_destroy(&attr);
printf( "pthread_attr_setdetachstate PTHREAD_CREATE_DETACHED failure!!!\n");
return -1;
}
ret = pthread_create(&pid, &attr, dsiplay_commit_thread_process, NULL);
if(ret == 0)
{
printf(" pthread_create OK! \n");
}else{
printf(" pthread_create failure!! \n");
pthread_attr_destroy(&attr);
return -1;
}
pthread_attr_destroy(&attr);
return 0;
}
#endif
性能表现
下面是 lv_demo_widgets 的统计数据:
lv_demo_widgets示例数据
FPS统计方式:
FPS统计方式,这里统计drmCommit花费的时间,看一定时长里能提交多少次:
ts = _clockTime_getCurrentMscTime();
ret = drmCommit(&g_disp.buf[g_num], g_disp.width, g_disp.height, 0, 0, &g_disp.dev, g_disp.plane_type);
if (ret) {
fprintf(stderr, "display commit error, ret = %d\n", ret);
}
commit_count++;
//usleep(1000 * 40);
commit_count_cost_time += _clockTime_checkLostMscTime(ts);
if(commit_count >= 64 || commit_count_cost_time > 1000 * 30)
{
int fps = commit_count / (commit_count_cost_time / 1000.0);
printf("FPS:%d\n", fps);
commit_count = 0;
commit_count_cost_time = 0;
}
}
FPS打印统计:
FPS:81
FPS:86
FPS:77
FPS:80
FPS:79
FPS:83
FPS:76
FPS:77
FPS:93
FPS:82
FPS:83
FPS:72
FPS:82
FPS:80
FPS:80
CPU占用
top - 15:57:46 up 6:57, 2 users, load average: 1.40, 0.84, 0.85
Tasks: 106 total, 3 running, 46 sleeping, 1 stopped, 0 zombie
%Cpu0 : 3.0/21.8 25[||||||||||||||||||||||||| ]
%Cpu1 : 25.7/23.8 50[|||||||||||||||||||||||||||||||||||||||||||||||||| ]
GiB Mem : 7.9/0.876 [ ]
GiB Swap: 0.0/0.000 [ ]
PID USER PR NI VIRT RES %CPU %MEM TIME+ S COMMAND
1 root 20 0 2.0m 0.2m 0.0 0.0 0:00.51 S init
102 root 20 0 2.0m 0.2m