refact(vg_lite): abstract common pending release logic (#5756)

Signed-off-by: pengyiqiang <pengyiqiang@xiaomi.com>
Co-authored-by: pengyiqiang <pengyiqiang@xiaomi.com>
This commit is contained in:
_VIFEXTech
2024-03-06 10:32:55 +08:00
committed by GitHub
parent 2e3b5dc667
commit 0297fac1b2
11 changed files with 244 additions and 65 deletions

View File

@@ -17,6 +17,7 @@
#include "lv_vg_lite_utils.h"
#include "lv_vg_lite_decoder.h"
#include "lv_vg_lite_grad.h"
#include "lv_vg_lite_pending.h"
/*********************
* DEFINES
@@ -69,12 +70,10 @@ 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_image_dsc_init(unit);
lv_vg_lite_grad_init(unit);
lv_vg_lite_path_init(unit);
lv_vg_lite_decoder_init();
}
@@ -243,7 +242,8 @@ 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_image_dsc_deinit(unit);
lv_vg_lite_grad_deinit(unit);
lv_vg_lite_path_deinit(unit);
lv_vg_lite_decoder_deinit();

View File

@@ -14,6 +14,7 @@
#include "lv_draw_vg_lite_type.h"
#include "lv_vg_lite_math.h"
#include "lv_vg_lite_path.h"
#include "lv_vg_lite_pending.h"
#include "lv_vg_lite_utils.h"
#include <math.h>
@@ -201,7 +202,7 @@ void lv_draw_vg_lite_arc(lv_draw_unit_t * draw_unit, const lv_draw_arc_dsc_t * d
color,
VG_LITE_FILTER_BI_LINEAR));
LV_PROFILER_END_TAG("vg_lite_draw_pattern");
lv_vg_lite_push_image_decoder_dsc(u, &decoder_dsc);
lv_vg_lite_pending_add(u->image_dsc_pending, &decoder_dsc);
}
}

View File

@@ -14,6 +14,7 @@
#include "lv_draw_vg_lite_type.h"
#include "lv_vg_lite_decoder.h"
#include "lv_vg_lite_path.h"
#include "lv_vg_lite_pending.h"
#include "lv_vg_lite_utils.h"
/*********************
@@ -157,7 +158,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_vg_lite_push_image_decoder_dsc(u, &decoder_dsc);
lv_vg_lite_pending_add(u->image_dsc_pending, &decoder_dsc);
LV_PROFILER_END;
}

View File

@@ -107,11 +107,11 @@ static void draw_letter_cb(lv_draw_unit_t * draw_unit, lv_draw_glyph_dsc_t * gly
#endif /* LV_USE_FREETYPE */
case LV_FONT_GLYPH_FORMAT_IMAGE: {
lv_draw_image_dsc_t img_dsc;
lv_draw_image_dsc_init(&img_dsc);
img_dsc.opa = glyph_draw_dsc->opa;
img_dsc.src = glyph_draw_dsc->glyph_data;
lv_draw_vg_lite_img(draw_unit, &img_dsc, glyph_draw_dsc->letter_coords, false);
lv_draw_image_dsc_t image_dsc;
lv_draw_image_dsc_init(&image_dsc);
image_dsc.opa = glyph_draw_dsc->opa;
image_dsc.src = glyph_draw_dsc->glyph_data;
lv_draw_vg_lite_img(draw_unit, &image_dsc, glyph_draw_dsc->letter_coords, false);
}
break;

View File

@@ -34,12 +34,15 @@ extern "C" {
/**********************
* TYPEDEFS
**********************/
struct _lv_vg_lite_pending_t;
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;
struct _lv_vg_lite_pending_t * image_dsc_pending;
lv_cache_t * grad_cache;
lv_array_t grad_pending;
struct _lv_vg_lite_pending_t * grad_pending;
uint16_t flush_count;
vg_lite_buffer_t target_buffer;
vg_lite_matrix_t global_matrix;

View File

@@ -13,6 +13,7 @@
#include "lv_draw_vg_lite_type.h"
#include "lv_vg_lite_path.h"
#include "lv_vg_lite_pending.h"
#include "lv_vg_lite_utils.h"
#include "lv_vg_lite_grad.h"
@@ -187,7 +188,7 @@ static void task_draw_cb(void * ctx, const lv_vector_path_t * path, const lv_vec
VG_LITE_FILTER_BI_LINEAR));
LV_PROFILER_END_TAG("vg_lite_draw_pattern");
lv_vg_lite_push_image_decoder_dsc(u, &decoder_dsc);
lv_vg_lite_pending_add(u->image_dsc_pending, &decoder_dsc);
}
}
break;

View File

@@ -12,6 +12,7 @@
#if LV_USE_DRAW_VG_LITE
#include "lv_draw_vg_lite_type.h"
#include "lv_vg_lite_pending.h"
/*********************
* DEFINES
@@ -36,6 +37,7 @@ static vg_lite_linear_gradient_t * lv_vg_lite_linear_grad_get(struct _lv_draw_vg
static bool grad_create_cb(grad_item_t * item, void * user_data);
static void grad_free_cb(grad_item_t * item, void * user_data);
static lv_cache_compare_res_t grad_compare_cb(const grad_item_t * lhs, const grad_item_t * rhs);
static void grad_cache_release_cb(void * entry, void * user_data);
/**********************
* STATIC VARIABLES
@@ -62,14 +64,14 @@ void lv_vg_lite_grad_init(struct _lv_draw_vg_lite_unit_t * u)
u->grad_cache = lv_cache_create(&lv_cache_class_lru_rb_count, sizeof(grad_item_t), LV_VG_LITE_GRAD_CACHE_SIZE, ops);
LV_ASSERT_NULL(u->grad_cache);
lv_array_init(&u->grad_pending, 4, sizeof(lv_cache_entry_t *));
u->grad_pending = lv_vg_lite_pending_create(sizeof(lv_cache_entry_t *), 4);
lv_vg_lite_pending_set_free_cb(u->grad_pending, grad_cache_release_cb, u->grad_cache);
}
void lv_vg_lite_grad_deinit(struct _lv_draw_vg_lite_unit_t * u)
{
LV_ASSERT_NULL(u);
lv_vg_lite_linear_grad_release_all(u);
lv_array_deinit(&u->grad_pending);
lv_vg_lite_pending_destroy(u->grad_pending);
lv_cache_destroy(u->grad_cache, NULL);
}
@@ -146,24 +148,6 @@ void lv_vg_lite_draw_linear_grad(
LV_PROFILER_END;
}
void lv_vg_lite_linear_grad_release_all(struct _lv_draw_vg_lite_unit_t * u)
{
LV_ASSERT_NULL(u);
lv_array_t * arr = &u->grad_pending;
uint32_t size = lv_array_size(arr);
if(size == 0) {
return;
}
/* release all pending cache entries */
lv_cache_entry_t ** entry_p = lv_array_front(arr);
for(uint32_t i = 0; i < size; i++) {
lv_cache_release(u->grad_cache, *entry_p, NULL);
entry_p++;
}
lv_array_clear(arr);
}
/**********************
* STATIC FUNCTIONS
**********************/
@@ -195,7 +179,7 @@ static vg_lite_linear_gradient_t * lv_vg_lite_linear_grad_get(struct _lv_draw_vg
}
/* Add the new entry to the pending list */
lv_array_push_back(&u->grad_pending, &cache_node_entry);
lv_vg_lite_pending_add(u->grad_pending, &cache_node_entry);
grad_item_t * item = lv_cache_entry_get_data(cache_node_entry);
return &item->vg_grad;
@@ -261,4 +245,11 @@ static lv_cache_compare_res_t grad_compare_cb(const grad_item_t * lhs, const gra
return 0;
}
static void grad_cache_release_cb(void * entry, void * user_data)
{
lv_cache_entry_t ** entry_p = entry;
lv_cache_t * cache = user_data;
lv_cache_release(cache, *entry_p, NULL);
}
#endif /*LV_USE_DRAW_VG_LITE*/

View File

@@ -0,0 +1,99 @@
/**
* @file lv_vg_lite_pending.c
*
*/
/*********************
* INCLUDES
*********************/
#include "lv_vg_lite_pending.h"
#if LV_USE_DRAW_VG_LITE
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
struct _lv_vg_lite_pending_t {
lv_array_t objs;
lv_vg_lite_pending_free_cb_t free_cb;
void * user_data;
};
/**********************
* STATIC PROTOTYPES
**********************/
/**********************
* STATIC VARIABLES
**********************/
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
lv_vg_lite_pending_t * lv_vg_lite_pending_create(size_t obj_size, uint32_t capacity_default)
{
lv_vg_lite_pending_t * pending = lv_malloc_zeroed(sizeof(lv_vg_lite_pending_t));
LV_ASSERT_MALLOC(pending);
lv_array_init(&pending->objs, capacity_default, obj_size);
return pending;
}
void lv_vg_lite_pending_destroy(lv_vg_lite_pending_t * pending)
{
LV_ASSERT_NULL(pending);
lv_vg_lite_pending_remove_all(pending);
lv_array_deinit(&pending->objs);
lv_memzero(pending, sizeof(lv_vg_lite_pending_t));
lv_free(pending);
}
void lv_vg_lite_pending_set_free_cb(lv_vg_lite_pending_t * pending, lv_vg_lite_pending_free_cb_t free_cb,
void * user_data)
{
LV_ASSERT_NULL(pending);
LV_ASSERT_NULL(free_cb);
pending->free_cb = free_cb;
pending->user_data = user_data;
}
void lv_vg_lite_pending_add(lv_vg_lite_pending_t * pending, void * obj)
{
LV_ASSERT_NULL(pending);
LV_ASSERT_NULL(obj);
lv_array_push_back(&pending->objs, obj);
}
void lv_vg_lite_pending_remove_all(lv_vg_lite_pending_t * pending)
{
LV_ASSERT_NULL(pending);
LV_ASSERT_NULL(pending->free_cb);
uint32_t size = lv_array_size(&pending->objs);
if(size == 0) {
return;
}
/* remove all the pending objects */
for(uint32_t i = 0; i < size; i++) {
pending->free_cb(lv_array_at(&pending->objs, i), pending->user_data);
}
lv_array_clear(&pending->objs);
}
/**********************
* STATIC FUNCTIONS
**********************/
#endif /*LV_USE_DRAW_VG_LITE*/

View File

@@ -0,0 +1,83 @@
/**
* @file lv_vg_lite_pending.h
*
*/
#ifndef LV_VG_LITE_PENDING_H
#define LV_VG_LITE_PENDING_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
#include "../../lvgl.h"
#if LV_USE_DRAW_VG_LITE
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
typedef struct _lv_vg_lite_pending_t lv_vg_lite_pending_t;
typedef void (*lv_vg_lite_pending_free_cb_t)(void * obj, void * user_data);
/**********************
* GLOBAL PROTOTYPES
**********************/
/**
* Create a pending list
* @param obj_size the size of the objects in the list
* @param capacity_default the default capacity of the list
* @return a pointer to the pending list
*/
lv_vg_lite_pending_t * lv_vg_lite_pending_create(size_t obj_size, uint32_t capacity_default);
/**
* Destroy a pending list
* @param pending pointer to the pending list
*/
void lv_vg_lite_pending_destroy(lv_vg_lite_pending_t * pending);
/**
* Set a free callback for the pending list
* @param pending pointer to the pending list
* @param free_cb the free callback
* @param user_data user data to pass to the free callback
*/
void lv_vg_lite_pending_set_free_cb(lv_vg_lite_pending_t * pending, lv_vg_lite_pending_free_cb_t free_cb,
void * user_data);
/**
* Add an object to the pending list
* @param pending pointer to the pending list
* @param obj pointer to the object to add
*/
void lv_vg_lite_pending_add(lv_vg_lite_pending_t * pending, void * obj);
/**
* Remove all objects from the pending list
* @param pending pointer to the pending list
*/
void lv_vg_lite_pending_remove_all(lv_vg_lite_pending_t * pending);
/**********************
* MACROS
**********************/
#endif /*LV_USE_DRAW_VG_LITE*/
#ifdef __cplusplus
} /*extern "C"*/
#endif
#endif /*LV_VG_LITE_PENDING_H*/

View File

@@ -13,6 +13,7 @@
#include "lv_vg_lite_decoder.h"
#include "lv_vg_lite_path.h"
#include "lv_vg_lite_pending.h"
#include "lv_vg_lite_grad.h"
#include "lv_draw_vg_lite_type.h"
#include <string.h>
@@ -45,6 +46,8 @@
* STATIC PROTOTYPES
**********************/
static void image_dsc_free_cb(void * dsc, void * user_data);
/**********************
* STATIC VARIABLES
**********************/
@@ -613,29 +616,6 @@ 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(struct _lv_draw_vg_lite_unit_t * u, lv_image_decoder_dsc_t * img_dsc)
{
LV_ASSERT_NULL(u);
LV_ASSERT_NULL(img_dsc);
lv_array_push_back(&u->img_dsc_pending, img_dsc);
}
void lv_vg_lite_clear_image_decoder_dsc(struct _lv_draw_vg_lite_unit_t * u)
{
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 */
lv_image_decoder_dsc_t * img_dsc = lv_array_front(arr);
for(uint32_t i = 0; i < size; i++) {
lv_image_decoder_close(&img_dsc[i]);
}
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)
{
@@ -680,6 +660,18 @@ bool lv_vg_lite_buffer_open_image(vg_lite_buffer_t * buffer, lv_image_decoder_ds
return true;
}
void lv_vg_lite_image_dsc_init(struct _lv_draw_vg_lite_unit_t * unit)
{
unit->image_dsc_pending = lv_vg_lite_pending_create(sizeof(lv_image_decoder_dsc_t), 4);
lv_vg_lite_pending_set_free_cb(unit->image_dsc_pending, image_dsc_free_cb, NULL);
}
void lv_vg_lite_image_dsc_deinit(struct _lv_draw_vg_lite_unit_t * unit)
{
lv_vg_lite_pending_destroy(unit->image_dsc_pending);
unit->image_dsc_pending = NULL;
}
void lv_vg_lite_rect(vg_lite_rectangle_t * rect, const lv_area_t * area)
{
rect->x = area->x1;
@@ -1071,11 +1063,11 @@ void lv_vg_lite_finish(struct _lv_draw_vg_lite_unit_t * u)
LV_VG_LITE_CHECK_ERROR(vg_lite_finish());
/* Clear all gradient caches */
lv_vg_lite_linear_grad_release_all(u);
/* Clear all gradient caches reference */
lv_vg_lite_pending_remove_all(u->grad_pending);
/* Clear image decoder dsc reference */
lv_vg_lite_clear_image_decoder_dsc(u);
lv_vg_lite_pending_remove_all(u->image_dsc_pending);
u->flush_count = 0;
LV_PROFILER_END;
}
@@ -1084,4 +1076,10 @@ void lv_vg_lite_finish(struct _lv_draw_vg_lite_unit_t * u)
* STATIC FUNCTIONS
**********************/
static void image_dsc_free_cb(void * dsc, void * user_data)
{
LV_UNUSED(user_data);
lv_image_decoder_close(dsc);
}
#endif /*LV_USE_DRAW_VG_LITE*/

View File

@@ -125,13 +125,15 @@ 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(struct _lv_draw_vg_lite_unit_t * u, lv_image_decoder_dsc_t * img_dsc);
void lv_vg_lite_clear_image_decoder_dsc(struct _lv_draw_vg_lite_unit_t * u);
void lv_vg_lite_image_dec_init(vg_lite_matrix_t * matrix, int32_t x, int32_t y, const lv_draw_image_dsc_t * dsc);
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);
void lv_vg_lite_image_dsc_init(struct _lv_draw_vg_lite_unit_t * unit);
void lv_vg_lite_image_dsc_deinit(struct _lv_draw_vg_lite_unit_t * unit);
vg_lite_blend_t lv_vg_lite_blend_mode(lv_blend_mode_t blend_mode);
uint32_t lv_vg_lite_get_palette_size(vg_lite_buffer_format_t format);