mirror of
https://github.com/lvgl/lvgl.git
synced 2025-01-28 07:03:00 +08:00
perf(vg_lite): add asynchronous rendering support (#5398)
Signed-off-by: pengyiqiang <pengyiqiang@xiaomi.com> Signed-off-by: FASTSHIFT <vifextech@foxmail.com> Co-authored-by: pengyiqiang <pengyiqiang@xiaomi.com>
This commit is contained in:
parent
09cb87cdc6
commit
b125d1baad
7
Kconfig
7
Kconfig
@ -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
|
||||
|
@ -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
|
||||
|
||||
/*=======================
|
||||
|
@ -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);
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/**********************
|
||||
|
@ -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
|
||||
|
@ -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"
|
||||
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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>
|
||||
|
||||
/*********************
|
||||
@ -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)
|
||||
{
|
||||
@ -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
|
||||
**********************/
|
||||
|
@ -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);
|
||||
|
||||
@ -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
|
||||
**********************/
|
||||
|
@ -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
|
||||
|
||||
/*=======================
|
||||
|
Loading…
x
Reference in New Issue
Block a user