1
0
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:
_VIFEXTech 2024-01-23 12:06:35 +08:00 committed by GitHub
parent 09cb87cdc6
commit b125d1baad
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 96 additions and 20 deletions

View File

@ -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

View File

@ -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
/*=======================

View File

@ -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;

View File

@ -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);
}
}

View File

@ -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);
}
/**********************

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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
**********************/

View File

@ -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
**********************/

View File

@ -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
/*=======================