Skip to content

Commit

Permalink
perf(vg_lite): add asynchronous rendering support (lvgl#5398)
Browse files Browse the repository at this point in the history
Signed-off-by: pengyiqiang <pengyiqiang@xiaomi.com>
Signed-off-by: FASTSHIFT <vifextech@foxmail.com>
Co-authored-by: pengyiqiang <pengyiqiang@xiaomi.com>
  • Loading branch information
FASTSHIFT and pengyiqiang authored Jan 23, 2024
1 parent 09cb87c commit b125d1b
Show file tree
Hide file tree
Showing 11 changed files with 96 additions and 20 deletions.
7 changes: 7 additions & 0 deletions Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,13 @@ menu "LVGL configuration"
default n
depends on LV_USE_DRAW_VG_LITE

config LV_VG_LITE_FLUSH_MAX_COUNT
int "VG-Lite flush commit trigger threshold."
default 8
depends on LV_USE_DRAW_VG_LITE
help
GPU will try to batch these many draw tasks.

config LV_USE_GPU_SDL
bool "Use SDL renderer API"
default n
Expand Down
3 changes: 3 additions & 0 deletions lv_conf_template.h
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,9 @@
/* Enable VG-Lite assert. */
#define LV_VG_LITE_USE_ASSERT 0

/* VG-Lite flush commit trigger threshold. GPU will try to batch these many draw tasks. */
#define LV_VG_LITE_FLUSH_MAX_COUNT 8

#endif

/*=======================
Expand Down
29 changes: 13 additions & 16 deletions src/draw/vg_lite/lv_draw_vg_lite.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ void lv_draw_vg_lite_init(void)
unit->base_unit.dispatch_cb = draw_dispatch;
unit->base_unit.evaluate_cb = draw_evaluate;
unit->base_unit.delete_cb = draw_delete;
lv_array_init(&unit->img_dsc_pending, 4, sizeof(lv_image_decoder_dsc_t));

lv_vg_lite_path_init(unit);

Expand Down Expand Up @@ -134,21 +135,15 @@ static void draw_execute(lv_draw_vg_lite_unit_t * u)
break;
}

#if LV_USE_PARALLEL_DRAW_DEBUG
/* Layers manage it for themselves. */
if(t->type != LV_DRAW_TASK_TYPE_LAYER) {
}
#endif

LV_VG_LITE_CHECK_ERROR(vg_lite_finish());
lv_vg_lite_flush(draw_unit);
}

static int32_t draw_dispatch(lv_draw_unit_t * draw_unit, lv_layer_t * layer)
{
lv_draw_vg_lite_unit_t * draw_vg_lite_unit = (lv_draw_vg_lite_unit_t *)draw_unit;
lv_draw_vg_lite_unit_t * u = (lv_draw_vg_lite_unit_t *)draw_unit;

/* Return immediately if it's busy with draw task. */
if(draw_vg_lite_unit->task_act) {
if(u->task_act) {
return 0;
}

Expand All @@ -157,6 +152,7 @@ static int32_t draw_dispatch(lv_draw_unit_t * draw_unit, lv_layer_t * layer)

/* Return 0 is no selection, some tasks can be supported by other units. */
if(!t || t->preferred_draw_unit_id != VG_LITE_DRAW_UNIT_ID) {
lv_vg_lite_finish(draw_unit);
return -1;
}

Expand All @@ -171,16 +167,16 @@ static int32_t draw_dispatch(lv_draw_unit_t * draw_unit, lv_layer_t * layer)
}

t->state = LV_DRAW_TASK_STATE_IN_PROGRESS;
draw_vg_lite_unit->base_unit.target_layer = layer;
draw_vg_lite_unit->base_unit.clip_area = &t->clip_area;
draw_vg_lite_unit->task_act = t;
u->base_unit.target_layer = layer;
u->base_unit.clip_area = &t->clip_area;
u->task_act = t;

draw_execute(draw_vg_lite_unit);
draw_execute(u);

draw_vg_lite_unit->task_act->state = LV_DRAW_TASK_STATE_READY;
draw_vg_lite_unit->task_act = NULL;
u->task_act->state = LV_DRAW_TASK_STATE_READY;
u->task_act = NULL;

/* The draw unit is free now. Request a new dispatching as it can get a new task. */
/*The draw unit is free now. Request a new dispatching as it can get a new task*/
lv_draw_dispatch_request();

return 1;
Expand Down Expand Up @@ -217,6 +213,7 @@ static int32_t draw_evaluate(lv_draw_unit_t * draw_unit, lv_draw_task_t * task)
static int32_t draw_delete(lv_draw_unit_t * draw_unit)
{
lv_draw_vg_lite_unit_t * unit = (lv_draw_vg_lite_unit_t *)draw_unit;
lv_array_deinit(&unit->img_dsc_pending);
lv_vg_lite_path_deinit(unit);
lv_vg_lite_decoder_deinit();
return 1;
Expand Down
2 changes: 1 addition & 1 deletion src/draw/vg_lite/lv_draw_vg_lite_arc.c
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ void lv_draw_vg_lite_arc(lv_draw_unit_t * draw_unit, const lv_draw_arc_dsc_t * d
0,
color,
VG_LITE_FILTER_BI_LINEAR));
lv_image_decoder_close(&decoder_dsc);
lv_vg_lite_push_image_decoder_dsc(draw_unit, &decoder_dsc);
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/draw/vg_lite/lv_draw_vg_lite_img.c
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ void lv_draw_vg_lite_img(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t *
lv_vg_lite_path_drop(u, path);
}

lv_image_decoder_close(&decoder_dsc);
lv_vg_lite_push_image_decoder_dsc(draw_unit, &decoder_dsc);
}

/**********************
Expand Down
2 changes: 1 addition & 1 deletion src/draw/vg_lite/lv_draw_vg_lite_label.c
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ static void draw_letter_bitmap(lv_draw_vg_lite_unit_t * u, const lv_draw_glyph_d
* You need to wait for the GPU to finish using the buffer before releasing it.
* Later, use the font cache for management to improve efficiency.
*/
LV_VG_LITE_CHECK_ERROR(vg_lite_finish());
lv_vg_lite_finish(&u->base_unit);
}

#if LV_USE_FREETYPE
Expand Down
3 changes: 3 additions & 0 deletions src/draw/vg_lite/lv_draw_vg_lite_type.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ extern "C" {
#if LV_USE_DRAW_VG_LITE

#include "../lv_draw.h"
#include "../../misc/lv_array.h"

#if LV_USE_VG_LITE_THORVG
#include "../../others/vg_lite_tvg/vg_lite.h"
Expand All @@ -37,6 +38,8 @@ extern "C" {
struct _lv_draw_vg_lite_unit_t {
lv_draw_unit_t base_unit;
lv_draw_task_t * task_act;
lv_array_t img_dsc_pending;
uint16_t flush_count;
vg_lite_buffer_t target_buffer;
vg_lite_matrix_t global_matrix;
struct _lv_vg_lite_path_t * global_path;
Expand Down
2 changes: 1 addition & 1 deletion src/draw/vg_lite/lv_draw_vg_lite_vector.c
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ static void task_draw_cb(void * ctx, const lv_vector_path_t * path, const lv_vec
recolor,
vg_color,
VG_LITE_FILTER_BI_LINEAR));
lv_image_decoder_close(&decoder_dsc);
lv_vg_lite_push_image_decoder_dsc(&u->base_unit, &decoder_dsc);
}
}
break;
Expand Down
49 changes: 49 additions & 0 deletions src/draw/vg_lite/lv_vg_lite_utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

#include "lv_vg_lite_decoder.h"
#include "lv_vg_lite_path.h"
#include "lv_draw_vg_lite_type.h"
#include <string.h>

/*********************
Expand Down Expand Up @@ -592,6 +593,29 @@ void lv_vg_lite_image_matrix(vg_lite_matrix_t * matrix, int32_t x, int32_t y, co
}
}

void lv_vg_lite_push_image_decoder_dsc(lv_draw_unit_t * draw_unit, lv_image_decoder_dsc_t * img_dsc)
{
lv_draw_vg_lite_unit_t * u = (lv_draw_vg_lite_unit_t *)draw_unit;
lv_array_push_back(&u->img_dsc_pending, img_dsc);
}

void lv_vg_lite_clear_image_decoder_dsc(lv_draw_unit_t * draw_unit)
{
lv_draw_vg_lite_unit_t * u = (lv_draw_vg_lite_unit_t *)draw_unit;
lv_array_t * arr = &u->img_dsc_pending;
uint32_t size = lv_array_size(arr);
if(size == 0) {
return;
}

/* Close all pending image decoder dsc */
for(uint32_t i = 0; i < size; i++) {
lv_image_decoder_dsc_t * img_dsc = lv_array_at(arr, i);
lv_image_decoder_close(img_dsc);
}
lv_array_clear(arr);
}

bool lv_vg_lite_buffer_open_image(vg_lite_buffer_t * buffer, lv_image_decoder_dsc_t * decoder_dsc, const void * src,
bool no_cache)
{
Expand Down Expand Up @@ -1022,6 +1046,31 @@ void lv_vg_lite_disable_scissor(void)
vg_lite_disable_scissor();
}

void lv_vg_lite_flush(lv_draw_unit_t * draw_unit)
{
lv_draw_vg_lite_unit_t * u = (lv_draw_vg_lite_unit_t *)draw_unit;

u->flush_count++;
if(u->flush_count < LV_VG_LITE_FLUSH_MAX_COUNT) {
/* Do not flush too often */
return;
}

LV_VG_LITE_CHECK_ERROR(vg_lite_flush());
u->flush_count = 0;
}

void lv_vg_lite_finish(lv_draw_unit_t * draw_unit)
{
lv_draw_vg_lite_unit_t * u = (lv_draw_vg_lite_unit_t *)draw_unit;

LV_VG_LITE_CHECK_ERROR(vg_lite_finish());

/* Clear image decoder dsc reference */
lv_vg_lite_clear_image_decoder_dsc(draw_unit);
u->flush_count = 0;
}

/**********************
* STATIC FUNCTIONS
**********************/
Expand Down
8 changes: 8 additions & 0 deletions src/draw/vg_lite/lv_vg_lite_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,10 @@ void lv_vg_lite_buffer_from_draw_buf(vg_lite_buffer_t * buffer, const lv_draw_bu

void lv_vg_lite_image_matrix(vg_lite_matrix_t * matrix, int32_t x, int32_t y, const lv_draw_image_dsc_t * dsc);

void lv_vg_lite_push_image_decoder_dsc(lv_draw_unit_t * draw_unit, lv_image_decoder_dsc_t * img_dsc);

void lv_vg_lite_clear_image_decoder_dsc(lv_draw_unit_t * draw_unit);

bool lv_vg_lite_buffer_open_image(vg_lite_buffer_t * buffer, lv_image_decoder_dsc_t * decoder_dsc, const void * src,
bool no_cache);

Expand Down Expand Up @@ -168,6 +172,10 @@ void lv_vg_lite_set_scissor_area(const lv_area_t * area);

void lv_vg_lite_disable_scissor(void);

void lv_vg_lite_flush(lv_draw_unit_t * draw_unit);

void lv_vg_lite_finish(lv_draw_unit_t * draw_unit);

/**********************
* MACROS
**********************/
Expand Down
9 changes: 9 additions & 0 deletions src/lv_conf_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,15 @@
#endif
#endif

/* VG-Lite flush commit trigger threshold. GPU will try to batch these many draw tasks. */
#ifndef LV_VG_LITE_FLUSH_MAX_COUNT
#ifdef CONFIG_LV_VG_LITE_FLUSH_MAX_COUNT
#define LV_VG_LITE_FLUSH_MAX_COUNT CONFIG_LV_VG_LITE_FLUSH_MAX_COUNT
#else
#define LV_VG_LITE_FLUSH_MAX_COUNT 8
#endif
#endif

#endif

/*=======================
Expand Down

0 comments on commit b125d1b

Please sign in to comment.