mirror of
https://github.com/lvgl/lvgl.git
synced 2026-05-21 14:32:44 +08:00
feat(cache): use unified cache entry free callback (#5612)
Signed-off-by: Neo Xu <neo.xu1990@gmail.com>
This commit is contained in:
@@ -422,12 +422,23 @@ static lv_cache_compare_res_t image_decoder_cache_compare_cb(
|
||||
|
||||
static void image_decoder_cache_free_cb(lv_image_cache_data_t * entry, void * user_data)
|
||||
{
|
||||
LV_UNUSED(user_data); /*Unused*/
|
||||
|
||||
const lv_image_decoder_t * decoder = entry->decoder;
|
||||
if(decoder && decoder->cache_free_cb) {
|
||||
if(decoder == NULL) return; /* Why ? */
|
||||
|
||||
if(decoder->cache_free_cb) {
|
||||
/* Decoder wants to free the cache by itself. */
|
||||
decoder->cache_free_cb(entry, user_data);
|
||||
}
|
||||
else {
|
||||
/* Destroy the decoded draw buffer if necessary. */
|
||||
lv_draw_buf_t * decoded = (lv_draw_buf_t *)entry->decoded;
|
||||
if(lv_draw_buf_has_flag(decoded, LV_IMAGE_FLAGS_ALLOCATED)) {
|
||||
lv_draw_buf_destroy(decoded);
|
||||
}
|
||||
|
||||
/*Free the duplicated file name*/
|
||||
if(entry->src_type == LV_IMAGE_SRC_FILE) lv_free((void *)entry->src);
|
||||
}
|
||||
}
|
||||
|
||||
static lv_result_t try_cache(lv_image_decoder_dsc_t * dsc)
|
||||
|
||||
@@ -278,6 +278,15 @@ void lv_image_decoder_set_get_area_cb(lv_image_decoder_t * decoder, lv_image_dec
|
||||
*/
|
||||
void lv_image_decoder_set_close_cb(lv_image_decoder_t * decoder, lv_image_decoder_close_f_t close_cb);
|
||||
|
||||
/**
|
||||
* Set a custom method to free cache data.
|
||||
* Normally this is not needed. If the custom decoder allocates additional memory other than dsc->decoded
|
||||
* draw buffer, then you need to register your own method to free it. By default the cache entry is free'ed
|
||||
* in `image_decoder_cache_free_cb`.
|
||||
*
|
||||
* @param decoder pointer to the image decoder
|
||||
* @param cache_free_cb the custom callback to free cache data. Refer to `image_decoder_cache_free_cb`.
|
||||
*/
|
||||
void lv_image_decoder_set_cache_free_cb(lv_image_decoder_t * decoder, lv_cache_free_cb_t cache_free_cb);
|
||||
|
||||
#if LV_CACHE_DEF_SIZE > 0
|
||||
|
||||
@@ -17,13 +17,6 @@
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/* If the original image can directly satisfy the GPU requirements, there is no need to create a copy */
|
||||
#define LV_VG_LITE_IMAGE_NO_DUP LV_IMAGE_FLAGS_USER1
|
||||
|
||||
/* VG_LITE_INDEX1, 2, and 4 require endian flipping + bit flipping,
|
||||
* so for simplicity, they are uniformly converted to I8 for display.
|
||||
*/
|
||||
@@ -35,6 +28,14 @@
|
||||
#define DEST_IMG_OFFSET \
|
||||
LV_VG_LITE_ALIGN(LV_COLOR_INDEXED_PALETTE_SIZE(DEST_IMG_FORMAT) * sizeof(lv_color32_t), LV_DRAW_BUF_ALIGN)
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
typedef struct {
|
||||
lv_draw_buf_t yuv; /*A draw buffer struct for yuv variable image*/
|
||||
} decoder_data_t;
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
@@ -42,7 +43,6 @@
|
||||
static lv_result_t decoder_info(lv_image_decoder_t * decoder, const void * src, lv_image_header_t * header);
|
||||
static lv_result_t decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc);
|
||||
static void decoder_close(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc);
|
||||
static void decoder_cache_free(lv_image_cache_data_t * cached_data, void * user_data);
|
||||
static void image_color32_pre_mul(lv_color32_t * img_data, uint32_t px_size);
|
||||
|
||||
/**********************
|
||||
@@ -63,7 +63,7 @@ void lv_vg_lite_decoder_init(void)
|
||||
lv_image_decoder_set_info_cb(decoder, decoder_info);
|
||||
lv_image_decoder_set_open_cb(decoder, decoder_open);
|
||||
lv_image_decoder_set_close_cb(decoder, decoder_close);
|
||||
lv_image_decoder_set_cache_free_cb(decoder, (lv_cache_free_cb_t)decoder_cache_free);
|
||||
lv_image_decoder_set_cache_free_cb(decoder, NULL); /*Use general cache free method*/
|
||||
}
|
||||
|
||||
void lv_vg_lite_decoder_deinit(void)
|
||||
@@ -185,13 +185,20 @@ static lv_result_t decoder_open_variable(lv_image_decoder_t * decoder, lv_image_
|
||||
|
||||
/* if is YUV format, no need to copy */
|
||||
if(LV_COLOR_FORMAT_IS_YUV(src_cf)) {
|
||||
lv_draw_buf_t * draw_buf = lv_malloc_zeroed(sizeof(lv_draw_buf_t));
|
||||
LV_ASSERT_MALLOC(draw_buf);
|
||||
decoder_data_t * decoder_data = dsc->user_data;
|
||||
if(decoder_data == NULL) {
|
||||
decoder_data = lv_malloc_zeroed(sizeof(decoder_data_t));
|
||||
LV_ASSERT_MALLOC(decoder_data);
|
||||
}
|
||||
lv_draw_buf_t * draw_buf = &decoder_data->yuv;
|
||||
uint32_t stride = lv_draw_buf_width_to_stride(width, src_cf);
|
||||
lv_draw_buf_init(draw_buf, width, height, src_cf, stride, (void *)image_data, image_data_size);
|
||||
|
||||
/* mark no dup */
|
||||
draw_buf->header.flags |= LV_VG_LITE_IMAGE_NO_DUP;
|
||||
/* Use alloced bit to indicate we should not free the memory */
|
||||
draw_buf->header.flags &= ~LV_IMAGE_FLAGS_ALLOCATED;
|
||||
|
||||
/* Do not add this kind of image to cache, since its life is managed by user. */
|
||||
dsc->args.no_cache = true;
|
||||
|
||||
dsc->decoded = draw_buf;
|
||||
return LV_RESULT_OK;
|
||||
@@ -354,9 +361,8 @@ failed:
|
||||
|
||||
static void decoder_draw_buf_free(lv_draw_buf_t * draw_buf)
|
||||
{
|
||||
if(draw_buf->header.flags & LV_VG_LITE_IMAGE_NO_DUP) {
|
||||
/* free draw buf struct only */
|
||||
lv_free(draw_buf);
|
||||
if((draw_buf->header.flags & LV_IMAGE_FLAGS_ALLOCATED) == 0) {
|
||||
/* This must be the yuv variable image. */
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -413,16 +419,9 @@ static void decoder_close(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t *
|
||||
|
||||
if(dsc->args.no_cache || LV_CACHE_DEF_SIZE == 0)
|
||||
decoder_draw_buf_free((lv_draw_buf_t *)dsc->decoded);
|
||||
if(decoder->user_data) free(decoder->user_data);
|
||||
else
|
||||
lv_cache_release(dsc->cache, dsc->cache_entry, NULL);
|
||||
}
|
||||
|
||||
static void decoder_cache_free(lv_image_cache_data_t * cached_data, void * user_data)
|
||||
{
|
||||
LV_UNUSED(user_data);
|
||||
|
||||
if(cached_data->src_type == LV_IMAGE_SRC_FILE) lv_free((void *)cached_data->src);
|
||||
decoder_draw_buf_free((lv_draw_buf_t *)cached_data->decoded);
|
||||
}
|
||||
|
||||
#endif /*LV_USE_DRAW_VG_LITE*/
|
||||
|
||||
@@ -71,8 +71,6 @@ static lv_fs_res_t fs_read_file_at(lv_fs_file_t * f, uint32_t pos, void * buff,
|
||||
|
||||
static lv_result_t decompress_image(lv_image_decoder_dsc_t * dsc, const lv_image_compressed_t * compressed);
|
||||
|
||||
static void bin_decoder_cache_free_cb(lv_image_cache_data_t * cached_data, void * user_data);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
@@ -103,7 +101,7 @@ void lv_bin_decoder_init(void)
|
||||
lv_image_decoder_set_open_cb(decoder, lv_bin_decoder_open);
|
||||
lv_image_decoder_set_get_area_cb(decoder, lv_bin_decoder_get_area);
|
||||
lv_image_decoder_set_close_cb(decoder, lv_bin_decoder_close);
|
||||
lv_image_decoder_set_cache_free_cb(decoder, (lv_cache_free_cb_t)bin_decoder_cache_free_cb);
|
||||
lv_image_decoder_set_cache_free_cb(decoder, NULL); /*Use general cache free method*/
|
||||
}
|
||||
|
||||
lv_result_t lv_bin_decoder_info(lv_image_decoder_t * decoder, const void * src, lv_image_header_t * header)
|
||||
@@ -1144,11 +1142,3 @@ static lv_result_t decompress_image(lv_image_decoder_dsc_t * dsc, const lv_image
|
||||
decoder_data->decompressed = decompressed; /*Free on decoder close*/
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
|
||||
static void bin_decoder_cache_free_cb(lv_image_cache_data_t * cached_data, void * user_data)
|
||||
{
|
||||
LV_UNUSED(user_data); /*Unused*/
|
||||
|
||||
lv_draw_buf_destroy((lv_draw_buf_t *)cached_data->decoded);
|
||||
if(cached_data->src_type == LV_IMAGE_SRC_FILE) lv_free((void *)cached_data->src);
|
||||
}
|
||||
|
||||
@@ -38,7 +38,6 @@ static void decoder_close(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t *
|
||||
static lv_draw_buf_t * decode_jpeg_file(const char * filename);
|
||||
static bool get_jpeg_size(const char * filename, uint32_t * width, uint32_t * height);
|
||||
static void error_exit(j_common_ptr cinfo);
|
||||
static void jpeg_decoder_cache_free_cb(lv_image_cache_data_t * cached_data, void * user_data);
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
@@ -60,7 +59,7 @@ void lv_libjpeg_turbo_init(void)
|
||||
lv_image_decoder_set_info_cb(dec, decoder_info);
|
||||
lv_image_decoder_set_open_cb(dec, decoder_open);
|
||||
lv_image_decoder_set_close_cb(dec, decoder_close);
|
||||
lv_image_decoder_set_cache_free_cb(dec, (lv_cache_free_cb_t)jpeg_decoder_cache_free_cb);
|
||||
lv_image_decoder_set_cache_free_cb(dec, NULL); /*Use general cache free method*/
|
||||
}
|
||||
|
||||
void lv_libjpeg_turbo_deinit(void)
|
||||
@@ -448,12 +447,4 @@ static void error_exit(j_common_ptr cinfo)
|
||||
longjmp(myerr->jb, 1);
|
||||
}
|
||||
|
||||
static void jpeg_decoder_cache_free_cb(lv_image_cache_data_t * cached_data, void * user_data)
|
||||
{
|
||||
LV_UNUSED(user_data);
|
||||
|
||||
if(cached_data->src_type == LV_IMAGE_SRC_FILE) lv_free((void *)cached_data->src);
|
||||
lv_draw_buf_destroy((lv_draw_buf_t *)cached_data->decoded);
|
||||
}
|
||||
|
||||
#endif /*LV_USE_LIBJPEG_TURBO*/
|
||||
|
||||
@@ -28,7 +28,6 @@ static lv_result_t decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_d
|
||||
static void decoder_close(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc);
|
||||
static lv_draw_buf_t * decode_png_file(const char * filename);
|
||||
|
||||
static void png_decoder_cache_free_cb(lv_image_cache_data_t * cached_data, void * user_data);
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
@@ -50,7 +49,7 @@ void lv_libpng_init(void)
|
||||
lv_image_decoder_set_info_cb(dec, decoder_info);
|
||||
lv_image_decoder_set_open_cb(dec, decoder_open);
|
||||
lv_image_decoder_set_close_cb(dec, decoder_close);
|
||||
lv_image_decoder_set_cache_free_cb(dec, (lv_cache_free_cb_t)png_decoder_cache_free_cb);
|
||||
lv_image_decoder_set_cache_free_cb(dec, NULL); /*Use general cache free method*/
|
||||
}
|
||||
|
||||
void lv_libpng_deinit(void)
|
||||
@@ -285,12 +284,4 @@ static lv_draw_buf_t * decode_png_file(const char * filename)
|
||||
return decoded;
|
||||
}
|
||||
|
||||
static void png_decoder_cache_free_cb(lv_image_cache_data_t * cached_data, void * user_data)
|
||||
{
|
||||
LV_UNUSED(user_data);
|
||||
|
||||
if(cached_data->src_type == LV_IMAGE_SRC_FILE) lv_free((void *)cached_data->src);
|
||||
lv_draw_buf_destroy((lv_draw_buf_t *)cached_data->decoded);
|
||||
}
|
||||
|
||||
#endif /*LV_USE_LIBPNG*/
|
||||
|
||||
@@ -29,7 +29,6 @@ static lv_result_t decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_d
|
||||
static void decoder_close(lv_image_decoder_t * dec, lv_image_decoder_dsc_t * dsc);
|
||||
static void convert_color_depth(uint8_t * img_p, uint32_t px_cnt);
|
||||
static lv_draw_buf_t * decode_png_data(const void * png_data, size_t png_data_size);
|
||||
static void lodepng_decoder_cache_free_cb(lv_image_cache_data_t * cached_data, void * user_data);
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
@@ -51,7 +50,6 @@ void lv_lodepng_init(void)
|
||||
lv_image_decoder_set_info_cb(dec, decoder_info);
|
||||
lv_image_decoder_set_open_cb(dec, decoder_open);
|
||||
lv_image_decoder_set_close_cb(dec, decoder_close);
|
||||
lv_image_decoder_set_cache_free_cb(dec, (lv_cache_free_cb_t)lodepng_decoder_cache_free_cb);
|
||||
}
|
||||
|
||||
void lv_lodepng_deinit(void)
|
||||
@@ -271,12 +269,4 @@ static void convert_color_depth(uint8_t * img_p, uint32_t px_cnt)
|
||||
}
|
||||
}
|
||||
|
||||
static void lodepng_decoder_cache_free_cb(lv_image_cache_data_t * cached_data, void * user_data)
|
||||
{
|
||||
LV_UNUSED(user_data);
|
||||
|
||||
if(cached_data->src_type == LV_IMAGE_SRC_FILE) lv_free((void *)cached_data->src);
|
||||
lv_draw_buf_destroy((lv_draw_buf_t *)cached_data->decoded);
|
||||
}
|
||||
|
||||
#endif /*LV_USE_LODEPNG*/
|
||||
|
||||
Reference in New Issue
Block a user