diff --git a/src/draw/vg_lite/lv_draw_vg_lite.c b/src/draw/vg_lite/lv_draw_vg_lite.c index a154f9df15..0c6cc97d6b 100644 --- a/src/draw/vg_lite/lv_draw_vg_lite.c +++ b/src/draw/vg_lite/lv_draw_vg_lite.c @@ -79,7 +79,7 @@ void lv_draw_vg_lite_init(void) #endif lv_vg_lite_path_init(unit); lv_vg_lite_decoder_init(); - lv_draw_vg_lite_label_init(&unit->base_unit); + lv_draw_vg_lite_label_init(unit); } void lv_draw_vg_lite_deinit(void) @@ -294,6 +294,7 @@ static int32_t draw_delete(lv_draw_unit_t * draw_unit) #endif lv_vg_lite_path_deinit(unit); lv_vg_lite_decoder_deinit(); + lv_draw_vg_lite_label_deinit(unit); return 1; } diff --git a/src/draw/vg_lite/lv_draw_vg_lite.h b/src/draw/vg_lite/lv_draw_vg_lite.h index e166bbf4af..0b873848bd 100644 --- a/src/draw/vg_lite/lv_draw_vg_lite.h +++ b/src/draw/vg_lite/lv_draw_vg_lite.h @@ -33,6 +33,8 @@ extern "C" { * TYPEDEFS **********************/ +struct _lv_draw_vg_lite_unit_t; + /********************** * GLOBAL PROTOTYPES **********************/ @@ -57,7 +59,9 @@ void lv_draw_vg_lite_fill(lv_draw_task_t * t, const lv_draw_fill_dsc_t * dsc, void lv_draw_vg_lite_img(lv_draw_task_t * t, const lv_draw_image_dsc_t * dsc, const lv_area_t * coords, bool no_cache); -void lv_draw_vg_lite_label_init(lv_draw_unit_t * draw_unit); +void lv_draw_vg_lite_label_init(struct _lv_draw_vg_lite_unit_t * u); + +void lv_draw_vg_lite_label_deinit(struct _lv_draw_vg_lite_unit_t * u); void lv_draw_vg_lite_letter(lv_draw_task_t * t, const lv_draw_letter_dsc_t * dsc, const lv_area_t * coords); 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 87fb3724e9..e7a91266a8 100644 --- a/src/draw/vg_lite/lv_draw_vg_lite_label.c +++ b/src/draw/vg_lite/lv_draw_vg_lite_label.c @@ -7,19 +7,20 @@ * INCLUDES *********************/ -#include "../../misc/lv_area_private.h" -#include "../../libs/freetype/lv_freetype_private.h" -#include "../lv_draw_label_private.h" -#include "lv_draw_vg_lite.h" - #include "../../lvgl.h" #if LV_USE_DRAW_VG_LITE +#include "lv_draw_vg_lite.h" +#include "lv_draw_vg_lite_type.h" #include "lv_vg_lite_utils.h" #include "lv_vg_lite_path.h" -#include "lv_draw_vg_lite_type.h" -#include +#include "lv_vg_lite_pending.h" +#include "../../misc/cache/lv_cache_entry_private.h" +#include "../../misc/lv_area_private.h" +#include "../../libs/freetype/lv_freetype_private.h" +#include "../lv_draw_label_private.h" + /********************* * DEFINES @@ -54,6 +55,8 @@ static void draw_letter_cb(lv_draw_task_t * t, lv_draw_glyph_dsc_t * glyph_draw_ static void draw_letter_bitmap(lv_draw_task_t * t, const lv_draw_glyph_dsc_t * dsc); +static void bitmap_cache_release_cb(void * entry, void * user_data); + #if LV_USE_FREETYPE static void freetype_outline_event_cb(lv_event_t * e); static void draw_letter_outline(lv_draw_task_t * t, const lv_draw_glyph_dsc_t * dsc); @@ -70,14 +73,26 @@ static void draw_letter_bitmap(lv_draw_task_t * t, const lv_draw_glyph_dsc_t * d /********************** * GLOBAL FUNCTIONS **********************/ -void lv_draw_vg_lite_label_init(lv_draw_unit_t * draw_unit) + +void lv_draw_vg_lite_label_init(struct _lv_draw_vg_lite_unit_t * u) { + LV_ASSERT_NULL(u); + #if LV_USE_FREETYPE /*Set up the freetype outline event*/ - lv_freetype_outline_add_event(freetype_outline_event_cb, LV_EVENT_ALL, draw_unit); -#else - LV_UNUSED(draw_unit); + lv_freetype_outline_add_event(freetype_outline_event_cb, LV_EVENT_ALL, u); #endif /* LV_USE_FREETYPE */ + + u->bitmap_font_pending = lv_vg_lite_pending_create(sizeof(lv_font_glyph_dsc_t), 8); + lv_vg_lite_pending_set_free_cb(u->bitmap_font_pending, bitmap_cache_release_cb, NULL); +} + +void lv_draw_vg_lite_label_deinit(struct _lv_draw_vg_lite_unit_t * u) +{ + LV_ASSERT_NULL(u); + LV_ASSERT_NULL(u->bitmap_font_pending) + lv_vg_lite_pending_destroy(u->bitmap_font_pending); + u->bitmap_font_pending = NULL; } void lv_draw_vg_lite_letter(lv_draw_task_t * t, const lv_draw_letter_dsc_t * dsc, const lv_area_t * coords) @@ -136,6 +151,10 @@ static void draw_letter_cb(lv_draw_task_t * t, lv_draw_glyph_dsc_t * glyph_draw_ case LV_FONT_GLYPH_FORMAT_A4_ALIGNED: case LV_FONT_GLYPH_FORMAT_A8_ALIGNED: { glyph_draw_dsc->glyph_data = lv_font_get_glyph_bitmap(glyph_draw_dsc->g, glyph_draw_dsc->_draw_buf); + if(!glyph_draw_dsc->glyph_data) { + return; + } + draw_letter_bitmap(t, glyph_draw_dsc); } break; @@ -144,6 +163,10 @@ static void draw_letter_cb(lv_draw_task_t * t, lv_draw_glyph_dsc_t * glyph_draw_ case LV_FONT_GLYPH_FORMAT_VECTOR: { if(lv_freetype_is_outline_font(glyph_draw_dsc->g->resolved_font)) { glyph_draw_dsc->glyph_data = lv_font_get_glyph_bitmap(glyph_draw_dsc->g, glyph_draw_dsc->_draw_buf); + if(!glyph_draw_dsc->glyph_data) { + return; + } + draw_letter_outline(t, glyph_draw_dsc); } } @@ -152,6 +175,10 @@ static void draw_letter_cb(lv_draw_task_t * t, lv_draw_glyph_dsc_t * glyph_draw_ case LV_FONT_GLYPH_FORMAT_IMAGE: { glyph_draw_dsc->glyph_data = lv_font_get_glyph_bitmap(glyph_draw_dsc->g, glyph_draw_dsc->_draw_buf); + if(!glyph_draw_dsc->glyph_data) { + return; + } + lv_draw_image_dsc_t image_dsc; lv_draw_image_dsc_init(&image_dsc); image_dsc.opa = glyph_draw_dsc->opa; @@ -270,14 +297,27 @@ static void draw_letter_bitmap(lv_draw_task_t * t, const lv_draw_glyph_dsc_t * d lv_vg_lite_path_drop(u, path); } - /* TODO: The temporary buffer of the built-in font is reused. - * 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_finish(u); + /* Check if the data has cache and add it to the pending list */ + if(dsc->g->entry) { + /* Increment the cache reference count */ + lv_cache_entry_acquire_data(dsc->g->entry); + lv_vg_lite_pending_add(u->bitmap_font_pending, dsc->g); + } + else { + /* No caching, wait for GPU finish before releasing the data */ + lv_vg_lite_finish(u); + } + LV_PROFILER_DRAW_END; } +static void bitmap_cache_release_cb(void * entry, void * user_data) +{ + LV_UNUSED(user_data); + lv_font_glyph_dsc_t * g_dsc = entry; + lv_font_glyph_release_draw_data(g_dsc); +} + #if LV_USE_FREETYPE static void draw_letter_outline(lv_draw_task_t * t, const lv_draw_glyph_dsc_t * dsc) 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 e06fc75df5..bd91270369 100644 --- a/src/draw/vg_lite/lv_draw_vg_lite_type.h +++ b/src/draw/vg_lite/lv_draw_vg_lite_type.h @@ -48,6 +48,8 @@ struct _lv_draw_vg_lite_unit_t { lv_cache_t * stroke_cache; + struct _lv_vg_lite_pending_t * bitmap_font_pending; + uint16_t flush_count; uint16_t letter_count; vg_lite_buffer_t target_buffer; diff --git a/src/draw/vg_lite/lv_vg_lite_path.h b/src/draw/vg_lite/lv_vg_lite_path.h index 41ac3057cb..a9ffee3dc6 100644 --- a/src/draw/vg_lite/lv_vg_lite_path.h +++ b/src/draw/vg_lite/lv_vg_lite_path.h @@ -17,6 +17,7 @@ extern "C" { #include "lv_vg_lite_utils.h" #if LV_USE_DRAW_VG_LITE +#include /********************* * DEFINES diff --git a/src/draw/vg_lite/lv_vg_lite_utils.c b/src/draw/vg_lite/lv_vg_lite_utils.c index 947587394a..6d362e6167 100644 --- a/src/draw/vg_lite/lv_vg_lite_utils.c +++ b/src/draw/vg_lite/lv_vg_lite_utils.c @@ -1326,6 +1326,8 @@ void lv_vg_lite_flush(struct _lv_draw_vg_lite_unit_t * u) lv_vg_lite_pending_swap(u->image_dsc_pending); + lv_vg_lite_pending_swap(u->bitmap_font_pending); + u->flush_count = 0; LV_PROFILER_DRAW_END; } @@ -1344,6 +1346,10 @@ void lv_vg_lite_finish(struct _lv_draw_vg_lite_unit_t * u) /* Clear image decoder dsc reference */ lv_vg_lite_pending_remove_all(u->image_dsc_pending); + + /* Clear bitmap font dsc reference */ + lv_vg_lite_pending_remove_all(u->bitmap_font_pending); + u->flush_count = 0; u->letter_count = 0; LV_PROFILER_DRAW_END; diff --git a/src/font/lv_font.c b/src/font/lv_font.c index 3d9afcb5c1..06a8c9e65c 100644 --- a/src/font/lv_font.c +++ b/src/font/lv_font.c @@ -57,6 +57,11 @@ const void * lv_font_get_glyph_bitmap(lv_font_glyph_dsc_t * g_dsc, lv_draw_buf_t void lv_font_glyph_release_draw_data(lv_font_glyph_dsc_t * g_dsc) { + LV_ASSERT_NULL(g_dsc); + if(!g_dsc->entry) { + return; + } + const lv_font_t * font = g_dsc->resolved_font; if(font != NULL && font->release_glyph) { @@ -77,8 +82,7 @@ bool lv_font_get_glyph_dsc(const lv_font_t * font_p, lv_font_glyph_dsc_t * dsc_o const lv_font_t * f = font_p; - dsc_out->resolved_font = NULL; - dsc_out->req_raw_bitmap = 0; + lv_memzero(dsc_out, sizeof(lv_font_glyph_dsc_t)); while(f) { bool found = f->get_glyph_dsc(f, dsc_out, letter, f->kerning == LV_FONT_KERNING_NONE ? 0 : letter_next); diff --git a/tests/src/lv_test_conf_full.h b/tests/src/lv_test_conf_full.h index 5034db9ba5..6646b5498a 100644 --- a/tests/src/lv_test_conf_full.h +++ b/tests/src/lv_test_conf_full.h @@ -165,7 +165,7 @@ #define LV_USE_FREETYPE 1 #define LV_FREETYPE_USE_LVGL_PORT 0 -#define LV_FREETYPE_CACHE_FT_GLYPH_CNT 10 +#define LV_FREETYPE_CACHE_FT_GLYPH_CNT 64 #define LV_USE_FONT_MANAGER 1 diff --git a/tests/src/test_cases/libs/test_font_stress.c b/tests/src/test_cases/libs/test_font_stress.c index ffbdc655de..33ba01fed1 100644 --- a/tests/src/test_cases/libs/test_font_stress.c +++ b/tests/src/test_cases/libs/test_font_stress.c @@ -204,6 +204,8 @@ void setUp(void) void tearDown(void) { + font_stress_label_delete_all(&g_ctx); + lv_freetype_uninit(); lv_free(g_ctx.label_arr); g_ctx.label_arr = NULL;