Skip to content

Commit ca403ff

Browse files
pengyiqiangxiaoxiang781216
authored andcommitted
lvgl/port: optimize fbdev buffer sync algorithm
Signed-off-by: pengyiqiang <pengyiqiang@xiaomi.com>
1 parent 8160dd0 commit ca403ff

File tree

1 file changed

+60
-58
lines changed

1 file changed

+60
-58
lines changed

graphics/lvgl/port/lv_port_fbdev.c

Lines changed: 60 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -79,11 +79,12 @@ struct fbdev_obj_s
7979
* Private Functions
8080
****************************************************************************/
8181

82+
#if defined(CONFIG_FB_UPDATE)
83+
8284
/****************************************************************************
83-
* Name: buf_rotate_copy
85+
* Name: fbdev_update_area
8486
****************************************************************************/
8587

86-
#if defined(CONFIG_FB_UPDATE)
8788
static void fbdev_update_area(FAR struct fbdev_obj_s *fbdev_obj,
8889
FAR const lv_area_t *area_p)
8990
{
@@ -104,43 +105,6 @@ static void fbdev_update_area(FAR struct fbdev_obj_s *fbdev_obj,
104105
}
105106
#endif
106107

107-
/****************************************************************************
108-
* Name: fbdev_copy_areas
109-
****************************************************************************/
110-
111-
static void fbdev_copy_areas(FAR lv_color_t *fb_dest,
112-
FAR const lv_color_t *fb_src,
113-
FAR const lv_area_t *areas,
114-
uint16_t len,
115-
int fb_width)
116-
{
117-
int i;
118-
LV_LOG_TRACE("%p -> %p, len = %d", fb_src, fb_dest, len);
119-
120-
for (i = 0; i < len; i++)
121-
{
122-
int y;
123-
FAR const lv_area_t *area = &(areas[i]);
124-
int width = lv_area_get_width(area);
125-
int height = lv_area_get_height(area);
126-
FAR lv_color_t *dest_pos =
127-
fb_dest + area->y1 * fb_width + area->x1;
128-
FAR const lv_color_t *src_pos =
129-
fb_src + area->y1 * fb_width + area->x1;
130-
size_t hor_size = width * sizeof(lv_color_t);
131-
132-
LV_LOG_TRACE("area[%d]: (%d, %d) %d x %d",
133-
i, area->x1, area->y1, width, height);
134-
135-
for (y = 0; y < height; y++)
136-
{
137-
lv_memcpy(dest_pos, src_pos, hor_size);
138-
dest_pos += fb_width;
139-
src_pos += fb_width;
140-
}
141-
}
142-
}
143-
144108
/****************************************************************************
145109
* Name: fbdev_switch_buffer
146110
****************************************************************************/
@@ -227,6 +191,39 @@ static void fbdev_disp_vsync_refr(FAR lv_timer_t *timer)
227191

228192
#endif /* CONFIG_FB_SYNC */
229193

194+
/****************************************************************************
195+
* Name: fbdev_check_inv_area_covered
196+
****************************************************************************/
197+
198+
static bool fbdev_check_inv_area_covered(FAR lv_disp_t *disp_refr,
199+
FAR const lv_area_t *area_p)
200+
{
201+
int i;
202+
203+
for (i = 0; i < disp_refr->inv_p; i++)
204+
{
205+
FAR const lv_area_t *cur_area;
206+
207+
/* Skip joined area */
208+
209+
if (disp_refr->inv_area_joined[i])
210+
{
211+
continue;
212+
}
213+
214+
cur_area = &disp_refr->inv_areas[i];
215+
216+
/* Check cur_area is coverd area_p */
217+
218+
if (_lv_area_is_in(area_p, cur_area, 0))
219+
{
220+
return true;
221+
}
222+
}
223+
224+
return false;
225+
}
226+
230227
/****************************************************************************
231228
* Name: fbdev_render_start
232229
****************************************************************************/
@@ -235,44 +232,49 @@ static void fbdev_render_start(FAR lv_disp_drv_t *disp_drv)
235232
{
236233
FAR struct fbdev_obj_s *fbdev_obj = disp_drv->user_data;
237234
FAR lv_disp_t *disp_refr;
235+
FAR lv_draw_ctx_t *draw_ctx;
238236
lv_coord_t hor_res;
239-
lv_coord_t ver_res;
240237
int i;
241238

242239
/* No need sync buffer when inv_areas_len == 0 */
243240

244241
if (fbdev_obj->inv_areas_len == 0)
245242
{
243+
LV_LOG_TRACE("No sync area");
246244
return;
247245
}
248246

247+
LV_LOG_TRACE("Start sync %d areas...", fbdev_obj->inv_areas_len);
248+
249249
disp_refr = _lv_refr_get_disp_refreshing();
250+
draw_ctx = disp_drv->draw_ctx;
250251
hor_res = disp_drv->hor_res;
251-
ver_res = disp_drv->ver_res;
252252

253-
for (i = 0; i < disp_refr->inv_p; i++)
253+
for (i = 0; i < fbdev_obj->inv_areas_len; i++)
254254
{
255-
if (disp_refr->inv_area_joined[i] == 0)
256-
{
257-
FAR const lv_area_t *area_p = &disp_refr->inv_areas[i];
255+
FAR const lv_area_t *last_area = &fbdev_obj->inv_areas[i];
258256

259-
/* If a full screen redraw is detected, skip dirty areas sync */
257+
LV_LOG_TRACE("Check area[%d]: (%d, %d) %d x %d",
258+
i,
259+
(int)last_area->x1, (int)last_area->y1,
260+
(int)lv_area_get_width(last_area),
261+
(int)lv_area_get_height(last_area));
260262

261-
if (lv_area_get_width(area_p) == hor_res
262-
&& lv_area_get_height(area_p) == ver_res)
263-
{
264-
LV_LOG_TRACE("Full screen redraw, skip dirty areas sync");
265-
fbdev_obj->inv_areas_len = 0;
266-
return;
267-
}
263+
if (fbdev_check_inv_area_covered(disp_refr, last_area))
264+
{
265+
LV_LOG_TRACE("Skipped");
266+
continue;
268267
}
269-
}
270268

271-
/* Sync the dirty area of ​​the previous frame */
269+
/* Sync the inv area of ​​the previous frame */
272270

273-
fbdev_copy_areas(fbdev_obj->act_buffer, fbdev_obj->last_buffer,
274-
fbdev_obj->inv_areas, fbdev_obj->inv_areas_len,
275-
fbdev_obj->vinfo.xres);
271+
draw_ctx->buffer_copy(
272+
draw_ctx,
273+
fbdev_obj->act_buffer, hor_res, last_area,
274+
fbdev_obj->last_buffer, hor_res, last_area);
275+
276+
LV_LOG_TRACE("Copied");
277+
}
276278

277279
fbdev_obj->inv_areas_len = 0;
278280
}

0 commit comments

Comments
 (0)