From ca403ffaf7876bbdfdfa429ea9d888501d1002d8 Mon Sep 17 00:00:00 2001 From: pengyiqiang Date: Mon, 27 Feb 2023 14:36:43 +0800 Subject: [PATCH] lvgl/port: optimize fbdev buffer sync algorithm Signed-off-by: pengyiqiang --- graphics/lvgl/port/lv_port_fbdev.c | 122 +++++++++++++++-------------- 1 file changed, 62 insertions(+), 60 deletions(-) diff --git a/graphics/lvgl/port/lv_port_fbdev.c b/graphics/lvgl/port/lv_port_fbdev.c index 3200535b6..38eeda3c7 100644 --- a/graphics/lvgl/port/lv_port_fbdev.c +++ b/graphics/lvgl/port/lv_port_fbdev.c @@ -79,11 +79,12 @@ struct fbdev_obj_s * Private Functions ****************************************************************************/ +#if defined(CONFIG_FB_UPDATE) + /**************************************************************************** - * Name: buf_rotate_copy + * Name: fbdev_update_area ****************************************************************************/ -#if defined(CONFIG_FB_UPDATE) static void fbdev_update_area(FAR struct fbdev_obj_s *fbdev_obj, FAR const lv_area_t *area_p) { @@ -104,43 +105,6 @@ static void fbdev_update_area(FAR struct fbdev_obj_s *fbdev_obj, } #endif -/**************************************************************************** - * Name: fbdev_copy_areas - ****************************************************************************/ - -static void fbdev_copy_areas(FAR lv_color_t *fb_dest, - FAR const lv_color_t *fb_src, - FAR const lv_area_t *areas, - uint16_t len, - int fb_width) -{ - int i; - LV_LOG_TRACE("%p -> %p, len = %d", fb_src, fb_dest, len); - - for (i = 0; i < len; i++) - { - int y; - FAR const lv_area_t *area = &(areas[i]); - int width = lv_area_get_width(area); - int height = lv_area_get_height(area); - FAR lv_color_t *dest_pos = - fb_dest + area->y1 * fb_width + area->x1; - FAR const lv_color_t *src_pos = - fb_src + area->y1 * fb_width + area->x1; - size_t hor_size = width * sizeof(lv_color_t); - - LV_LOG_TRACE("area[%d]: (%d, %d) %d x %d", - i, area->x1, area->y1, width, height); - - for (y = 0; y < height; y++) - { - lv_memcpy(dest_pos, src_pos, hor_size); - dest_pos += fb_width; - src_pos += fb_width; - } - } -} - /**************************************************************************** * Name: fbdev_switch_buffer ****************************************************************************/ @@ -227,6 +191,39 @@ static void fbdev_disp_vsync_refr(FAR lv_timer_t *timer) #endif /* CONFIG_FB_SYNC */ +/**************************************************************************** + * Name: fbdev_check_inv_area_covered + ****************************************************************************/ + +static bool fbdev_check_inv_area_covered(FAR lv_disp_t *disp_refr, + FAR const lv_area_t *area_p) +{ + int i; + + for (i = 0; i < disp_refr->inv_p; i++) + { + FAR const lv_area_t *cur_area; + + /* Skip joined area */ + + if (disp_refr->inv_area_joined[i]) + { + continue; + } + + cur_area = &disp_refr->inv_areas[i]; + + /* Check cur_area is coverd area_p */ + + if (_lv_area_is_in(area_p, cur_area, 0)) + { + return true; + } + } + + return false; +} + /**************************************************************************** * Name: fbdev_render_start ****************************************************************************/ @@ -235,45 +232,50 @@ static void fbdev_render_start(FAR lv_disp_drv_t *disp_drv) { FAR struct fbdev_obj_s *fbdev_obj = disp_drv->user_data; FAR lv_disp_t *disp_refr; + FAR lv_draw_ctx_t *draw_ctx; lv_coord_t hor_res; - lv_coord_t ver_res; int i; /* No need sync buffer when inv_areas_len == 0 */ if (fbdev_obj->inv_areas_len == 0) { + LV_LOG_TRACE("No sync area"); return; } + LV_LOG_TRACE("Start sync %d areas...", fbdev_obj->inv_areas_len); + disp_refr = _lv_refr_get_disp_refreshing(); + draw_ctx = disp_drv->draw_ctx; hor_res = disp_drv->hor_res; - ver_res = disp_drv->ver_res; - for (i = 0; i < disp_refr->inv_p; i++) + for (i = 0; i < fbdev_obj->inv_areas_len; i++) { - if (disp_refr->inv_area_joined[i] == 0) + FAR const lv_area_t *last_area = &fbdev_obj->inv_areas[i]; + + LV_LOG_TRACE("Check area[%d]: (%d, %d) %d x %d", + i, + (int)last_area->x1, (int)last_area->y1, + (int)lv_area_get_width(last_area), + (int)lv_area_get_height(last_area)); + + if (fbdev_check_inv_area_covered(disp_refr, last_area)) { - FAR const lv_area_t *area_p = &disp_refr->inv_areas[i]; - - /* If a full screen redraw is detected, skip dirty areas sync */ - - if (lv_area_get_width(area_p) == hor_res - && lv_area_get_height(area_p) == ver_res) - { - LV_LOG_TRACE("Full screen redraw, skip dirty areas sync"); - fbdev_obj->inv_areas_len = 0; - return; - } + LV_LOG_TRACE("Skipped"); + continue; } + + /* Sync the inv area of ​​the previous frame */ + + draw_ctx->buffer_copy( + draw_ctx, + fbdev_obj->act_buffer, hor_res, last_area, + fbdev_obj->last_buffer, hor_res, last_area); + + LV_LOG_TRACE("Copied"); } - /* Sync the dirty area of ​​the previous frame */ - - fbdev_copy_areas(fbdev_obj->act_buffer, fbdev_obj->last_buffer, - fbdev_obj->inv_areas, fbdev_obj->inv_areas_len, - fbdev_obj->vinfo.xres); - fbdev_obj->inv_areas_len = 0; }