Platform: ARM9
Software: Linux, support rgb565, hardware double FB
Display: 480x480
The initialization and refresh codes are as follows:
static void _lv_init(void)
{
uint32_t width, height;
uint32_t size;
/*LittlevGL init*/
lv_init();
/*Linux frame buffer device init*/
fbdev_init();
fbdev_get_sizes(&width,&height);
fr_kprintf("width:%d height:%d\n",width,height);
size = width*height;
#ifdef LV_DOUBLE_FB_EN
lv_color_t *p_buf1 = (lv_color_t *)fr_malloc(size*sizeof(lv_color_t));
lv_color_t *p_buf2 = (lv_color_t *)fr_malloc(size*sizeof(lv_color_t));
static lv_disp_draw_buf_t disp_buf;
lv_disp_draw_buf_init(&disp_buf, p_buf1, p_buf2, size);
#else
/*A small buffer for LittlevGL to draw the screen's content*/
lv_color_t *p_buf = (lv_color_t *)fr_malloc(size*sizeof(lv_color_t));
/*Initialize a descriptor for the buffer*/
static lv_disp_draw_buf_t disp_buf;
lv_disp_draw_buf_init(&disp_buf, p_buf, NULL, size);
#endif
/*Initialize and register a display driver*/
static lv_disp_drv_t disp_drv;
lv_disp_drv_init(&disp_drv);
disp_drv.draw_buf = &disp_buf;
disp_drv.flush_cb = fbdev_flush;
disp_drv.hor_res = width;
disp_drv.ver_res = height;
#ifdef LV_DOUBLE_FB_EN
disp_drv.full_refresh = 1;
#endif
lv_disp_drv_register(&disp_drv);
/* Linux input device init */
evdev_init();
/* Initialize and register a display input driver */
static lv_indev_drv_t indev_drv;
lv_indev_drv_init(&indev_drv); /*Basic initialization*/
indev_drv.type = LV_INDEV_TYPE_POINTER;
indev_drv.read_cb = evdev_read; //lv_gesture_dir_t lv_indev_get_gesture_dir(const lv_indev_t * indev)
lv_indev_drv_register(&indev_drv);
}
void fbdev_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_p)
{
if(fbp == NULL ||
area->x2 < 0 ||
area->y2 < 0 ||
area->x1 > (int32_t)vinfo.xres - 1 ||
area->y1 > (int32_t)vinfo.yres - 1) {
lv_disp_flush_ready(drv);
return;
}
#ifdef LV_DOUBLE_FB_EN
static int fb_double_toggle_flg = 0;
vinfo.yoffset = vinfo.yres*fb_double_toggle_flg;
fb_double_toggle_flg=!fb_double_toggle_flg;
#endif
/*Truncate the area to the screen*/
int32_t act_x1 = area->x1 < 0 ? 0 : area->x1;
int32_t act_y1 = area->y1 < 0 ? 0 : area->y1;
int32_t act_x2 = area->x2 > (int32_t)vinfo.xres - 1 ? (int32_t)vinfo.xres - 1 : area->x2;
int32_t act_y2 = area->y2 > (int32_t)vinfo.yres - 1 ? (int32_t)vinfo.yres - 1 : area->y2;
lv_coord_t w = (act_x2 - act_x1 + 1);
long int location = 0;
long int byte_location = 0;
unsigned char bit_location = 0;
/*16 bit per pixel*/
if(vinfo.bits_per_pixel == 16) {
uint16_t * fbp16 = (uint16_t *)fbp;
int32_t y;
for(y = act_y1; y <= act_y2; y++) {
location = (act_x1 + vinfo.xoffset) + (y + vinfo.yoffset) * finfo.line_length / 2;
memcpy(&fbp16[location], (uint32_t *)color_p, (act_x2 - act_x1 + 1) * 2);
color_p += w;
}
} else {
/*Not supported bit per pixel*/
}
//May be some direct update command is required
//ret = ioctl(state->fd, FBIO_UPDATE, (unsigned long)((uintptr_t)rect));
#ifdef LV_DOUBLE_FB_EN
int zero = 0;
if(ioctl(fbfd, FBIO_WAITFORVSYNC, &zero)<0){
fprintf(stderr, "wait vsync fb swap failed\n");
}
if (ioctl(fbfd, FBIOPAN_DISPLAY, &vinfo) < 0) {
fprintf(stderr, "active fb swap failed\n");
}
#endif
lv_disp_flush_ready(drv);
}
-When the hardware double is not turned on(LV_DOUBLE_FB_EN is not defined), FPS can reach 33, and the experience is better
-When the hardware double is enabled (LV_DOUBLE_FB_EN is defined), the FPS can only reach 14, and the experience is very bad
why?