lvgl/port: optimize fbdev buffer sync algorithm
Signed-off-by: pengyiqiang <pengyiqiang@xiaomi.com>
This commit is contained in:
parent
8160dd0d56
commit
ca403ffaf7
@ -79,11 +79,12 @@ struct fbdev_obj_s
|
|||||||
* Private Functions
|
* 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,
|
static void fbdev_update_area(FAR struct fbdev_obj_s *fbdev_obj,
|
||||||
FAR const lv_area_t *area_p)
|
FAR const lv_area_t *area_p)
|
||||||
{
|
{
|
||||||
@ -104,43 +105,6 @@ static void fbdev_update_area(FAR struct fbdev_obj_s *fbdev_obj,
|
|||||||
}
|
}
|
||||||
#endif
|
#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
|
* Name: fbdev_switch_buffer
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@ -227,6 +191,39 @@ static void fbdev_disp_vsync_refr(FAR lv_timer_t *timer)
|
|||||||
|
|
||||||
#endif /* CONFIG_FB_SYNC */
|
#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
|
* Name: fbdev_render_start
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@ -235,44 +232,49 @@ static void fbdev_render_start(FAR lv_disp_drv_t *disp_drv)
|
|||||||
{
|
{
|
||||||
FAR struct fbdev_obj_s *fbdev_obj = disp_drv->user_data;
|
FAR struct fbdev_obj_s *fbdev_obj = disp_drv->user_data;
|
||||||
FAR lv_disp_t *disp_refr;
|
FAR lv_disp_t *disp_refr;
|
||||||
|
FAR lv_draw_ctx_t *draw_ctx;
|
||||||
lv_coord_t hor_res;
|
lv_coord_t hor_res;
|
||||||
lv_coord_t ver_res;
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* No need sync buffer when inv_areas_len == 0 */
|
/* No need sync buffer when inv_areas_len == 0 */
|
||||||
|
|
||||||
if (fbdev_obj->inv_areas_len == 0)
|
if (fbdev_obj->inv_areas_len == 0)
|
||||||
{
|
{
|
||||||
|
LV_LOG_TRACE("No sync area");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LV_LOG_TRACE("Start sync %d areas...", fbdev_obj->inv_areas_len);
|
||||||
|
|
||||||
disp_refr = _lv_refr_get_disp_refreshing();
|
disp_refr = _lv_refr_get_disp_refreshing();
|
||||||
|
draw_ctx = disp_drv->draw_ctx;
|
||||||
hor_res = disp_drv->hor_res;
|
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];
|
||||||
{
|
|
||||||
FAR const lv_area_t *area_p = &disp_refr->inv_areas[i];
|
|
||||||
|
|
||||||
/* If a full screen redraw is detected, skip dirty areas sync */
|
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 (lv_area_get_width(area_p) == hor_res
|
if (fbdev_check_inv_area_covered(disp_refr, last_area))
|
||||||
&& lv_area_get_height(area_p) == ver_res)
|
|
||||||
{
|
{
|
||||||
LV_LOG_TRACE("Full screen redraw, skip dirty areas sync");
|
LV_LOG_TRACE("Skipped");
|
||||||
fbdev_obj->inv_areas_len = 0;
|
continue;
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Sync the dirty area of the previous frame */
|
/* Sync the inv area of the previous frame */
|
||||||
|
|
||||||
fbdev_copy_areas(fbdev_obj->act_buffer, fbdev_obj->last_buffer,
|
draw_ctx->buffer_copy(
|
||||||
fbdev_obj->inv_areas, fbdev_obj->inv_areas_len,
|
draw_ctx,
|
||||||
fbdev_obj->vinfo.xres);
|
fbdev_obj->act_buffer, hor_res, last_area,
|
||||||
|
fbdev_obj->last_buffer, hor_res, last_area);
|
||||||
|
|
||||||
|
LV_LOG_TRACE("Copied");
|
||||||
|
}
|
||||||
|
|
||||||
fbdev_obj->inv_areas_len = 0;
|
fbdev_obj->inv_areas_len = 0;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user