mirror of
https://github.com/lvgl/lvgl.git
synced 2025-02-04 07:13:00 +08:00
feat(decoder): put decoded image to cache in bin decoder (#4928)
Signed-off-by: Xu Xingliang <xuxingliang@xiaomi.com>
This commit is contained in:
parent
7b6f360d46
commit
668fd1cffa
@ -61,6 +61,9 @@ 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 lv_result_t decompress_image(lv_image_decoder_dsc_t * dsc, const lv_image_compressed_t * compressed);
|
||||||
|
|
||||||
|
static lv_result_t try_cache(lv_image_decoder_dsc_t * dsc);
|
||||||
|
static void cache_invalidate_cb(lv_cache_entry_t * entry);
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
* STATIC VARIABLES
|
* STATIC VARIABLES
|
||||||
**********************/
|
**********************/
|
||||||
@ -160,7 +163,12 @@ lv_result_t lv_bin_decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_d
|
|||||||
{
|
{
|
||||||
LV_UNUSED(decoder);
|
LV_UNUSED(decoder);
|
||||||
LV_UNUSED(args);
|
LV_UNUSED(args);
|
||||||
|
|
||||||
|
/*Check the cache first*/
|
||||||
|
if(try_cache(dsc) == LV_RESULT_OK) return LV_RESULT_OK;
|
||||||
|
|
||||||
lv_fs_res_t res = LV_RESULT_INVALID;
|
lv_fs_res_t res = LV_RESULT_INVALID;
|
||||||
|
uint32_t t = lv_tick_get();
|
||||||
|
|
||||||
/*Open the file if it's a file*/
|
/*Open the file if it's a file*/
|
||||||
if(dsc->src_type == LV_IMAGE_SRC_FILE) {
|
if(dsc->src_type == LV_IMAGE_SRC_FILE) {
|
||||||
@ -257,8 +265,38 @@ lv_result_t lv_bin_decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_d
|
|||||||
|
|
||||||
if(res != LV_RESULT_OK) {
|
if(res != LV_RESULT_OK) {
|
||||||
free_decoder_data(dsc);
|
free_decoder_data(dsc);
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(dsc->img_data == NULL) return LV_RESULT_OK;
|
||||||
|
|
||||||
|
/*Add it to cache*/
|
||||||
|
t = lv_tick_elaps(t);
|
||||||
|
lv_cache_lock();
|
||||||
|
lv_cache_entry_t * cache = lv_cache_add(NULL, 0, decoder->cache_data_type, dsc->header.w * dsc->header.h * 4);
|
||||||
|
if(cache == NULL) {
|
||||||
|
lv_cache_unlock();
|
||||||
|
free_decoder_data(dsc);
|
||||||
|
return LV_RESULT_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
cache->weight = t;
|
||||||
|
cache->data = dsc->img_data;
|
||||||
|
cache->invalidate_cb = cache_invalidate_cb;
|
||||||
|
if(dsc->src_type == LV_IMAGE_SRC_FILE) {
|
||||||
|
cache->src = lv_strdup(dsc->src);
|
||||||
|
cache->src_type = LV_CACHE_SRC_TYPE_PATH;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
cache->src_type = LV_CACHE_SRC_TYPE_POINTER;
|
||||||
|
cache->src = dsc->src;
|
||||||
|
}
|
||||||
|
|
||||||
|
cache->user_data = dsc->user_data; /*Need to free data on cache invalidate instead of decoder_close*/
|
||||||
|
dsc->img_data = lv_cache_get_data(cache); /*@note: Must get from cache to increase reference count.*/
|
||||||
|
dsc->cache_entry = cache;
|
||||||
|
|
||||||
|
lv_cache_unlock();
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -270,7 +308,10 @@ lv_result_t lv_bin_decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_d
|
|||||||
void lv_bin_decoder_close(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc)
|
void lv_bin_decoder_close(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc)
|
||||||
{
|
{
|
||||||
LV_UNUSED(decoder); /*Unused*/
|
LV_UNUSED(decoder); /*Unused*/
|
||||||
free_decoder_data(dsc);
|
|
||||||
|
lv_cache_lock();
|
||||||
|
lv_cache_release(dsc->cache_entry);
|
||||||
|
lv_cache_unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
lv_result_t lv_bin_decoder_get_area(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc,
|
lv_result_t lv_bin_decoder_get_area(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc,
|
||||||
@ -891,3 +932,63 @@ static lv_result_t decompress_image(lv_image_decoder_dsc_t * dsc, const lv_image
|
|||||||
decoder_data->decompressed = decompressed; /*Free on decoder close*/
|
decoder_data->decompressed = decompressed; /*Free on decoder close*/
|
||||||
return LV_RESULT_OK;
|
return LV_RESULT_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static lv_result_t try_cache(lv_image_decoder_dsc_t * dsc)
|
||||||
|
{
|
||||||
|
lv_cache_lock();
|
||||||
|
if(dsc->src_type == LV_IMAGE_SRC_FILE) {
|
||||||
|
const char * fn = dsc->src;
|
||||||
|
|
||||||
|
lv_cache_entry_t * cache = lv_cache_find_by_src(NULL, fn, LV_CACHE_SRC_TYPE_PATH);
|
||||||
|
if(cache) {
|
||||||
|
dsc->img_data = lv_cache_get_data(cache);
|
||||||
|
/**
|
||||||
|
* The img_data may not be consistent with dsc->header.cf
|
||||||
|
* For indexed image, it could be converted to ARGB8888 when enabled.
|
||||||
|
* For alpha only image, it's always converted to A8 format.
|
||||||
|
*/
|
||||||
|
if(LV_COLOR_FORMAT_IS_ALPHA_ONLY(dsc->header.cf)) {
|
||||||
|
uint8_t bpp = lv_color_format_get_bpp(dsc->header.cf);
|
||||||
|
lv_image_header_t header;
|
||||||
|
lv_image_decoder_get_info(dsc->src, &header);
|
||||||
|
uint32_t w = (header.stride * 8) / bpp;
|
||||||
|
uint32_t buf_stride = (w * 8 + 7) >> 3; /*stride for img_data*/
|
||||||
|
dsc->header.cf = LV_COLOR_FORMAT_A8;
|
||||||
|
dsc->header.stride = buf_stride;
|
||||||
|
}
|
||||||
|
#if LV_BIN_DECODER_RAM_LOAD
|
||||||
|
else if(LV_COLOR_FORMAT_IS_INDEXED(dsc->header.cf)) {
|
||||||
|
dsc->header.stride = lv_draw_buf_width_to_stride(dsc->header.w, LV_COLOR_FORMAT_ARGB8888);
|
||||||
|
dsc->header.cf = LV_COLOR_FORMAT_ARGB8888;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
dsc->cache_entry = cache; /*Save the cache to release it in decoder_close*/
|
||||||
|
lv_cache_unlock();
|
||||||
|
return LV_RESULT_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if(dsc->src_type == LV_IMAGE_SRC_VARIABLE) {
|
||||||
|
const lv_image_dsc_t * img_dsc = dsc->src;
|
||||||
|
|
||||||
|
lv_cache_entry_t * cache = lv_cache_find_by_src(NULL, img_dsc, LV_CACHE_SRC_TYPE_POINTER);
|
||||||
|
if(cache) {
|
||||||
|
dsc->img_data = lv_cache_get_data(cache);
|
||||||
|
dsc->cache_entry = cache; /*Save the cache to release it in decoder_close*/
|
||||||
|
lv_cache_unlock();
|
||||||
|
return LV_RESULT_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lv_cache_unlock();
|
||||||
|
return LV_RESULT_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cache_invalidate_cb(lv_cache_entry_t * entry)
|
||||||
|
{
|
||||||
|
lv_image_decoder_dsc_t fake = { 0 };
|
||||||
|
fake.user_data = entry->user_data;
|
||||||
|
free_decoder_data(&fake);
|
||||||
|
|
||||||
|
if(entry->src_type == LV_CACHE_SRC_TYPE_PATH) lv_free((void *)entry->src);
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user