From 2b6616cd1d873260978722be2bfc3975e809a793 Mon Sep 17 00:00:00 2001 From: Jinkun Hong Date: Mon, 6 Jun 2022 09:46:49 +0800 Subject: [PATCH 4/6] gif add cache Signed-off-by: Jinkun Hong --- src/extra/libs/gif/lv_gif.c | 79 ++++++++++++++++++++++++++++++++++++++++++++- src/extra/libs/gif/lv_gif.h | 10 ++++++ 2 files changed, 88 insertions(+), 1 deletion(-) diff --git a/src/extra/libs/gif/lv_gif.c b/src/extra/libs/gif/lv_gif.c index 4cb2955..a2eaaf9 100644 --- a/src/extra/libs/gif/lv_gif.c +++ b/src/extra/libs/gif/lv_gif.c @@ -65,6 +65,17 @@ void lv_gif_set_src(lv_obj_t * obj, const void * src) gd_close_gif(gifobj->gif); gifobj->gif = NULL; gifobj->imgdsc.data = NULL; +#if LV_GIF_CACHE + while (gifobj->canvas_list) { + lv_gif_canvas_t *next = gifobj->canvas_list->next; + if (gifobj->canvas_list->data) + free(gifobj->canvas_list->data); + free(gifobj->canvas_list); + gifobj->canvas_list = next; + } + gifobj->canvas_list = NULL; + gifobj->canvas_cur = NULL; +#endif } if(lv_img_src_get_type(src) == LV_IMG_SRC_VARIABLE) { @@ -86,6 +97,52 @@ void lv_gif_set_src(lv_obj_t * obj, const void * src) gifobj->imgdsc.header.w = gifobj->gif->width; gifobj->last_call = lv_tick_get(); +#if LV_GIF_CACHE + int data_len; + int i = 0; + lv_gif_canvas_t *canvas_tmp; + lv_gif_canvas_t *canvas = malloc(sizeof(lv_gif_canvas_t)); + gifobj->canvas_list = canvas; + gifobj->canvas_cur = canvas; +#if LV_COLOR_DEPTH == 32 + data_len = gifobj->gif->height * gifobj->gif->width * 4; +#elif LV_COLOR_DEPTH == 16 + data_len = gifobj->gif->height * gifobj->gif->width * 2; +#else + data_len = gifobj->gif->height * gifobj->gif->width; +#endif + canvas->data = malloc(data_len); + memcpy(canvas->data, gifobj->gif->canvas, data_len); + canvas->next = NULL; + gifobj->imgdsc.data = canvas->data; + while (1) { + int has_next = gd_get_frame(gifobj->gif); + if(has_next == 0) { + if(gifobj->gif->loop_count > 1) gifobj->gif->loop_count--; + gd_rewind(gifobj->gif); + break; + } + gd_render_frame(gifobj->gif, (uint8_t *)gifobj->gif->canvas); + canvas_tmp = malloc(sizeof(lv_gif_canvas_t)); + canvas_tmp->next = NULL; + canvas->next = canvas_tmp; + canvas = canvas_tmp; + canvas->data = malloc(data_len); + memcpy(canvas->data, gifobj->gif->canvas, data_len); + } + canvas_tmp = gifobj->canvas_list; + for (i = 0; i < 2 && canvas_tmp; i++) { + int has_next = gd_get_frame(gifobj->gif); + if(has_next == 0) { + if(gifobj->gif->loop_count > 1) gifobj->gif->loop_count--; + gd_rewind(gifobj->gif); + break; + } + gd_render_frame(gifobj->gif, (uint8_t *)gifobj->gif->canvas); + memcpy(canvas_tmp->data, gifobj->gif->canvas, data_len); + canvas_tmp = canvas_tmp->next; + } +#endif lv_img_set_src(obj, &gifobj->imgdsc); lv_timer_resume(gifobj->timer); @@ -121,6 +178,17 @@ static void lv_gif_destructor(const lv_obj_class_t * class_p, lv_obj_t * obj) lv_gif_t * gifobj = (lv_gif_t *) obj; lv_img_cache_invalidate_src(&gifobj->imgdsc); gd_close_gif(gifobj->gif); +#if LV_GIF_CACHE + while (gifobj->canvas_list) { + lv_gif_canvas_t *next = gifobj->canvas_list->next; + if (gifobj->canvas_list->data) + free(gifobj->canvas_list->data); + free(gifobj->canvas_list); + gifobj->canvas_list = next; + } + gifobj->canvas_list = NULL; + gifobj->canvas_cur = NULL; +#endif lv_timer_del(gifobj->timer); } @@ -133,6 +201,15 @@ static void next_frame_task_cb(lv_timer_t * t) gifobj->last_call = lv_tick_get(); +#if LV_GIF_CACHE + if (gifobj->canvas_cur->next) { + gifobj->canvas_cur = gifobj->canvas_cur->next; + } else { + gifobj->canvas_cur = gifobj->canvas_list; + } + if (gifobj->canvas_cur) + gifobj->imgdsc.data = gifobj->canvas_cur->data; +#else int has_next = gd_get_frame(gifobj->gif); if(has_next == 0) { /*It was the last repeat*/ @@ -147,7 +224,7 @@ static void next_frame_task_cb(lv_timer_t * t) } gd_render_frame(gifobj->gif, (uint8_t *)gifobj->imgdsc.data); - +#endif lv_img_cache_invalidate_src(lv_img_get_src(obj)); lv_obj_invalidate(obj); } diff --git a/src/extra/libs/gif/lv_gif.h b/src/extra/libs/gif/lv_gif.h index d8c93db..1ea6564 100644 --- a/src/extra/libs/gif/lv_gif.h +++ b/src/extra/libs/gif/lv_gif.h @@ -26,6 +26,12 @@ extern "C" { /********************** * TYPEDEFS **********************/ +#if LV_GIF_CACHE +typedef struct lv_gif_canvas { + uint8_t *data; + struct lv_gif_canvas *next; +} lv_gif_canvas_t; +#endif typedef struct { lv_img_t img; @@ -33,6 +39,10 @@ typedef struct { lv_timer_t * timer; lv_img_dsc_t imgdsc; uint32_t last_call; +#if LV_GIF_CACHE + lv_gif_canvas_t *canvas_list; + lv_gif_canvas_t *canvas_cur; +#endif } lv_gif_t; extern const lv_obj_class_t lv_gif_class; -- 2.7.4