You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2023/03/02 05:52:11 UTC

[nuttx-apps] branch master updated: lvgl/port: optimize fbdev buffer sync algorithm

This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx-apps.git


The following commit(s) were added to refs/heads/master by this push:
     new ca403ffaf lvgl/port: optimize fbdev buffer sync algorithm
ca403ffaf is described below

commit ca403ffaf7876bbdfdfa429ea9d888501d1002d8
Author: pengyiqiang <pe...@xiaomi.com>
AuthorDate: Mon Feb 27 14:36:43 2023 +0800

    lvgl/port: optimize fbdev buffer sync algorithm
    
    Signed-off-by: pengyiqiang <pe...@xiaomi.com>
---
 graphics/lvgl/port/lv_port_fbdev.c | 118 +++++++++++++++++++------------------
 1 file changed, 60 insertions(+), 58 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,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 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 *area_p = &disp_refr->inv_areas[i];
+      FAR const lv_area_t *last_area = &fbdev_obj->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
-           && 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;
-            }
+      if (fbdev_check_inv_area_covered(disp_refr, last_area))
+        {
+          LV_LOG_TRACE("Skipped");
+          continue;
         }
-    }
 
-  /* 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,
-                   fbdev_obj->inv_areas, fbdev_obj->inv_areas_len,
-                   fbdev_obj->vinfo.xres);
+      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");
+    }
 
   fbdev_obj->inv_areas_len = 0;
 }