Hi. In order to improve the FPS of LVGL, I tried to use the memory obtained by mmap of the /dev/fb0 interface of the LINUX platform as draw_buf, but there would be flickering.
On my SOC platform, FRAMEBUFFER supports the FBIOPAN_DISPLAY command. So I want to switch screens in flush_cb to avoid flickering caused by direct access to the screen.
The following code is LVGL initialization:
fbfd = open("/dev/fb0", O_RDWR);
if (fbfd == -1)
{
return -1;
}
if (ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo) == -1)
{
perror("Error reading fixed information");
return -1;
}
if (ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo) == -1)
{
perror("Error reading variable information");
return -1;
}
fbp = (char *)mmap(0, finfo.smem_len, PROT_READ | PROT_WRITE, MAP_SHARED, fbfd, 0);
lv_disp_draw_buf_init(&disp_buf, fbp, fbp + vinfo.xres * vinfo.yres * 4, vinfo.xres * vinfo.yres);
lv_disp_drv_init(&disp_drv);
disp_drv.draw_buf = &disp_buf;
disp_drv.flush_cb = gpu_flush;
disp_drv.hor_res = vinfo.xres;
disp_drv.ver_res = vinfo.yres;
disp_drv.full_refresh = 1;
lv_disp_drv_register(&disp_drv);
The following code is LVGL flush_cb:
static bool pan_state = false;
if (pan_state)
{
vinfo.yoffset = vinfo.yres;
}
else
{
vinfo.yoffset = 0;
}
pan_state = !pan_state;
if (ioctl(fbfd, FBIOPAN_DISPLAY, &vinfo) == -1)
{
printf("Error: failed to FBIOPAN_DISPLAY\n");
return;
}
lv_disp_flush_ready(drv);
The following code is main:
lv_demo_widgets();
while (1)
{
usleep(1000);
lv_task_handler();
}
I found that changing usleep in the main function to 10000 can avoid screen flickering.
my lv_conf.h
/Default display refresh period. LVG will redraw changed ares with this period time/
#define LV_DISP_DEF_REFR_PERIOD 10 /[ms]/
/Input device read period in milliseconds/
#define LV_INDEV_DEF_READ_PERIOD 1 /[ms]/