diff --git a/Kconfig b/Kconfig index 91a7da4b6f45..ba56443348e6 100644 --- a/Kconfig +++ b/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 diff --git a/lv_conf_template.h b/lv_conf_template.h index 742d95cb04f7..089da0d103bc 100644 --- a/lv_conf_template.h +++ b/lv_conf_template.h @@ -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 /*======================= diff --git a/src/draw/vg_lite/lv_draw_vg_lite.c b/src/draw/vg_lite/lv_draw_vg_lite.c index ad49c4a52891..5a6e52a812e0 100644 --- a/src/draw/vg_lite/lv_draw_vg_lite.c +++ b/src/draw/vg_lite/lv_draw_vg_lite.c @@ -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; diff --git a/src/draw/vg_lite/lv_draw_vg_lite_arc.c b/src/draw/vg_lite/lv_draw_vg_lite_arc.c index a253b6148005..1b932e05b02e 100644 --- a/src/draw/vg_lite/lv_draw_vg_lite_arc.c +++ b/src/draw/vg_lite/lv_draw_vg_lite_arc.c @@ -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); } } diff --git a/src/draw/vg_lite/lv_draw_vg_lite_img.c b/src/draw/vg_lite/lv_draw_vg_lite_img.c index 05c8debd0c6e..bd91046baf53 100644 --- a/src/draw/vg_lite/lv_draw_vg_lite_img.c +++ b/src/draw/vg_lite/lv_draw_vg_lite_img.c @@ -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); } /********************** diff --git a/src/draw/vg_lite/lv_draw_vg_lite_label.c b/src/draw/vg_lite/lv_draw_vg_lite_label.c index 91bcf2e2de88..536dfda9d0f6 100644 --- a/src/draw/vg_lite/lv_draw_vg_lite_label.c +++ b/src/draw/vg_lite/lv_draw_vg_lite_label.c @@ -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 diff --git a/src/draw/vg_lite/lv_draw_vg_lite_type.h b/src/draw/vg_lite/lv_draw_vg_lite_type.h index 59da4122b567..a445ff1d403b 100644 --- a/src/draw/vg_lite/lv_draw_vg_lite_type.h +++ b/src/draw/vg_lite/lv_draw_vg_lite_type.h @@ -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; diff --git a/src/draw/vg_lite/lv_draw_vg_lite_vector.c b/src/draw/vg_lite/lv_draw_vg_lite_vector.c index 1326588c698b..355bcf79e9d3 100644 --- a/src/draw/vg_lite/lv_draw_vg_lite_vector.c +++ b/src/draw/vg_lite/lv_draw_vg_lite_vector.c @@ -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; diff --git a/src/draw/vg_lite/lv_vg_lite_utils.c b/src/draw/vg_lite/lv_vg_lite_utils.c index c8bf9f85959d..eba139cf11b6 100644 --- a/src/draw/vg_lite/lv_vg_lite_utils.c +++ b/src/draw/vg_lite/lv_vg_lite_utils.c @@ -13,6 +13,7 @@ #include "lv_vg_lite_decoder.h" #include "lv_vg_lite_path.h" +#include "lv_draw_vg_lite_type.h" #include /********************* @@ -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 **********************/ diff --git a/src/draw/vg_lite/lv_vg_lite_utils.h b/src/draw/vg_lite/lv_vg_lite_utils.h index a0edc735c4b3..ca4372bb13a4 100644 --- a/src/draw/vg_lite/lv_vg_lite_utils.h +++ b/src/draw/vg_lite/lv_vg_lite_utils.h @@ -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 **********************/ diff --git a/src/lv_conf_internal.h b/src/lv_conf_internal.h index 2fff711cf6a5..f0842b0d1c4e 100644 --- a/src/lv_conf_internal.h +++ b/src/lv_conf_internal.h @@ -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 /*=======================