diff options
author | VIFEX <vifextech@foxmail.com> | 2024-04-30 17:23:32 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-04-30 11:23:32 +0200 |
commit | 447f9b8f4876e4ca6e63b9be05e5ff3ecc368894 (patch) | |
tree | fe3055c1b4fc2041eade5d05195c86b545fa77e5 | |
parent | eb1fe43595c29a46e305be128de9c6d356eec606 (diff) | |
download | lvgl-447f9b8f4876e4ca6e63b9be05e5ff3ecc368894.tar.gz lvgl-447f9b8f4876e4ca6e63b9be05e5ff3ecc368894.zip |
fix(vg_lite): fix incorrect cache operation (#6054)
Signed-off-by: pengyiqiang <pengyiqiang@xiaomi.com>
Co-authored-by: pengyiqiang <pengyiqiang@xiaomi.com>
-rw-r--r-- | src/draw/lv_draw_buf.c | 59 | ||||
-rw-r--r-- | src/draw/lv_draw_buf.h | 25 | ||||
-rw-r--r-- | src/draw/lv_image_decoder.c | 13 | ||||
-rw-r--r-- | src/draw/lv_image_decoder.h | 1 | ||||
-rw-r--r-- | src/draw/vg_lite/lv_vg_lite_decoder.c | 11 | ||||
-rw-r--r-- | src/draw/vg_lite/lv_vg_lite_utils.c | 1 | ||||
-rw-r--r-- | src/drivers/nuttx/lv_nuttx_cache.c | 33 |
7 files changed, 108 insertions, 35 deletions
diff --git a/src/draw/lv_draw_buf.c b/src/draw/lv_draw_buf.c index 1610f84b9..1a9059855 100644 --- a/src/draw/lv_draw_buf.c +++ b/src/draw/lv_draw_buf.c @@ -33,6 +33,7 @@ static void * draw_buf_malloc(const lv_draw_buf_handlers_t * handler, size_t siz static void draw_buf_free(const lv_draw_buf_handlers_t * handler, void * buf); static uint32_t width_to_stride(uint32_t w, lv_color_format_t color_format); static uint32_t _calculate_draw_buf_size(uint32_t w, uint32_t h, lv_color_format_t cf, uint32_t stride); +static void draw_buf_get_full_area(const lv_draw_buf_t * draw_buf, lv_area_t * full_area); /********************** * STATIC VARIABLES @@ -54,14 +55,15 @@ void _lv_draw_buf_init_handlers(void) void lv_draw_buf_init_with_default_handlers(lv_draw_buf_handlers_t * handlers) { - lv_draw_buf_init_handlers(handlers, buf_malloc, buf_free, buf_align, NULL, width_to_stride); + lv_draw_buf_init_handlers(handlers, buf_malloc, buf_free, buf_align, NULL, NULL, width_to_stride); } void lv_draw_buf_init_handlers(lv_draw_buf_handlers_t * handlers, lv_draw_buf_malloc_cb buf_malloc_cb, lv_draw_buf_free_cb buf_free_cb, lv_draw_buf_align_cb align_pointer_cb, - lv_draw_buf_invalidate_cache_cb invalidate_cache_cb, + lv_draw_buf_cache_operation_cb invalidate_cache_cb, + lv_draw_buf_cache_operation_cb flush_cache_cb, lv_draw_buf_width_to_stride_cb width_to_stride_cb) { lv_memzero(handlers, sizeof(lv_draw_buf_handlers_t)); @@ -69,6 +71,7 @@ void lv_draw_buf_init_handlers(lv_draw_buf_handlers_t * handlers, handlers->buf_free_cb = buf_free_cb; handlers->align_pointer_cb = align_pointer_cb; handlers->invalidate_cache_cb = invalidate_cache_cb; + handlers->flush_cache_cb = flush_cache_cb; handlers->width_to_stride_cb = width_to_stride_cb; } @@ -108,18 +111,42 @@ void lv_draw_buf_invalidate_cache(const lv_draw_buf_t * draw_buf, const lv_area_ void lv_draw_buf_invalidate_cache_user(const lv_draw_buf_handlers_t * handlers, const lv_draw_buf_t * draw_buf, const lv_area_t * area) { - if(handlers->invalidate_cache_cb) { - LV_ASSERT_NULL(draw_buf); - const lv_image_header_t * header = &draw_buf->header; - lv_area_t full; - if(area == NULL) { - full = (lv_area_t) { - 0, 0, header->w - 1, header->h - 1 - }; - area = &full; - } - handlers->invalidate_cache_cb(draw_buf, area); + LV_ASSERT_NULL(draw_buf); + + if(!handlers->invalidate_cache_cb) { + return; + } + + lv_area_t full; + if(area == NULL) { + draw_buf_get_full_area(draw_buf, &full); + area = &full; + } + + handlers->invalidate_cache_cb(draw_buf, area); +} + +void lv_draw_buf_flush_cache(const lv_draw_buf_t * draw_buf, const lv_area_t * area) +{ + lv_draw_buf_flush_cache_user(&default_handlers, draw_buf, area); +} + +void lv_draw_buf_flush_cache_user(const lv_draw_buf_handlers_t * handlers, const lv_draw_buf_t * draw_buf, + const lv_area_t * area) +{ + LV_ASSERT_NULL(draw_buf); + + if(!handlers->flush_cache_cb) { + return; + } + + lv_area_t full; + if(area == NULL) { + draw_buf_get_full_area(draw_buf, &full); + area = &full; } + + handlers->flush_cache_cb(draw_buf, area); } void lv_draw_buf_clear(lv_draw_buf_t * draw_buf, const lv_area_t * a) @@ -569,3 +596,9 @@ static uint32_t _calculate_draw_buf_size(uint32_t w, uint32_t h, lv_color_format return size; } + +static void draw_buf_get_full_area(const lv_draw_buf_t * draw_buf, lv_area_t * full_area) +{ + const lv_image_header_t * header = &draw_buf->header; + lv_area_set(full_area, 0, 0, header->w - 1, header->h - 1); +} diff --git a/src/draw/lv_draw_buf.h b/src/draw/lv_draw_buf.h index 39b44572e..753fc3c07 100644 --- a/src/draw/lv_draw_buf.h +++ b/src/draw/lv_draw_buf.h @@ -76,7 +76,7 @@ typedef void (*lv_draw_buf_free_cb)(void * draw_buf); typedef void * (*lv_draw_buf_align_cb)(void * buf, lv_color_format_t color_format); -typedef void (*lv_draw_buf_invalidate_cache_cb)(const lv_draw_buf_t * draw_buf, const lv_area_t * area); +typedef void (*lv_draw_buf_cache_operation_cb)(const lv_draw_buf_t * draw_buf, const lv_area_t * area); typedef uint32_t (*lv_draw_buf_width_to_stride_cb)(uint32_t w, lv_color_format_t color_format); @@ -84,7 +84,8 @@ typedef struct { lv_draw_buf_malloc_cb buf_malloc_cb; lv_draw_buf_free_cb buf_free_cb; lv_draw_buf_align_cb align_pointer_cb; - lv_draw_buf_invalidate_cache_cb invalidate_cache_cb; + lv_draw_buf_cache_operation_cb invalidate_cache_cb; + lv_draw_buf_cache_operation_cb flush_cache_cb; lv_draw_buf_width_to_stride_cb width_to_stride_cb; } lv_draw_buf_handlers_t; @@ -118,7 +119,8 @@ void lv_draw_buf_init_handlers(lv_draw_buf_handlers_t * handlers, lv_draw_buf_malloc_cb buf_malloc_cb, lv_draw_buf_free_cb buf_free_cb, lv_draw_buf_align_cb align_pointer_cb, - lv_draw_buf_invalidate_cache_cb invalidate_cache_cb, + lv_draw_buf_cache_operation_cb invalidate_cache_cb, + lv_draw_buf_cache_operation_cb flush_cache_cb, lv_draw_buf_width_to_stride_cb width_to_stride_cb); /** @@ -163,6 +165,23 @@ void lv_draw_buf_invalidate_cache_user(const lv_draw_buf_handlers_t * handlers, const lv_area_t * area); /** + * Flush the cache of the buffer + * @param draw_buf the draw buffer needs to be flushed + * @param area the area to flush in the buffer, + * use NULL to flush the whole draw buffer address range + */ +void lv_draw_buf_flush_cache(const lv_draw_buf_t * draw_buf, const lv_area_t * area); + +/** + * Flush the cache of the buffer using the user-defined callback + * @param handlers the draw buffer handlers + * @param draw_buf the draw buffer needs to be flushed + * @param area the area to flush in the buffer, + */ +void lv_draw_buf_flush_cache_user(const lv_draw_buf_handlers_t * handlers, const lv_draw_buf_t * draw_buf, + const lv_area_t * area); + +/** * Calculate the stride in bytes based on a width and color format * @param w the width in pixels * @param color_format the color format diff --git a/src/draw/lv_image_decoder.c b/src/draw/lv_image_decoder.c index e6b503e26..7e839f34d 100644 --- a/src/draw/lv_image_decoder.c +++ b/src/draw/lv_image_decoder.c @@ -112,6 +112,7 @@ lv_result_t lv_image_decoder_open(lv_image_decoder_dsc_t * dsc, const void * src .premultiply = false, .no_cache = false, .use_indexed = false, + .flush_cache = false, }; /* @@ -121,6 +122,18 @@ lv_result_t lv_image_decoder_open(lv_image_decoder_dsc_t * dsc, const void * src * */ lv_result_t res = dsc->decoder->open_cb(dsc->decoder, dsc); + /* Flush the D-Cache if enabled and the image was successfully opened */ + if(dsc->args.flush_cache && res == LV_RESULT_OK) { + lv_draw_buf_flush_cache(dsc->decoded, NULL); + LV_LOG_INFO("Flushed D-cache: src %p (%s) (W%" LV_PRId32 " x H%" LV_PRId32 ", data: %p cf: %d)", + src, + dsc->src_type == LV_IMAGE_SRC_FILE ? (const char *)src : "c-array", + dsc->decoded->header.w, + dsc->decoded->header.h, + dsc->decoded->data, + dsc->decoded->header.cf); + } + return res; } diff --git a/src/draw/lv_image_decoder.h b/src/draw/lv_image_decoder.h index 646a72ebe..eede76ec9 100644 --- a/src/draw/lv_image_decoder.h +++ b/src/draw/lv_image_decoder.h @@ -62,6 +62,7 @@ typedef struct _lv_image_decoder_args_t { bool premultiply; /*Whether image should be premultiplied or not after decoding*/ bool no_cache; /*When set, decoded image won't be put to cache, and decoder open will also ignore cache.*/ bool use_indexed; /*Decoded indexed image as is. Convert to ARGB8888 if false.*/ + bool flush_cache; /*Whether to flush the data cache after decoding*/ } lv_image_decoder_args_t; /** diff --git a/src/draw/vg_lite/lv_vg_lite_decoder.c b/src/draw/vg_lite/lv_vg_lite_decoder.c index 6015ef32f..133ae5354 100644 --- a/src/draw/vg_lite/lv_vg_lite_decoder.c +++ b/src/draw/vg_lite/lv_vg_lite_decoder.c @@ -248,11 +248,6 @@ static lv_result_t decoder_open_variable(lv_image_decoder_t * decoder, lv_image_ dest += dest_stride; } - /* invalidate D-Cache */ - lv_draw_buf_invalidate_cache(draw_buf, NULL); - LV_LOG_INFO("image %p (W%" LV_PRId32 " x H%" LV_PRId32 ", buffer: %p, cf: %d) decode finish", - image_data, width, height, draw_buf->data, src_cf); - return LV_RESULT_OK; } @@ -345,12 +340,6 @@ static lv_result_t decoder_open_file(lv_image_decoder_t * decoder, lv_image_deco lv_free(src_temp); lv_fs_close(&file); - - /* invalidate D-Cache */ - lv_draw_buf_invalidate_cache(draw_buf, NULL); - - LV_LOG_INFO("image %s (W%" LV_PRId32 " x H%" LV_PRId32 ", buffer: %p cf: %d) decode finish", - path, width, height, draw_buf->data, src_header.cf); return LV_RESULT_OK; failed: diff --git a/src/draw/vg_lite/lv_vg_lite_utils.c b/src/draw/vg_lite/lv_vg_lite_utils.c index 90206f034..b730d5306 100644 --- a/src/draw/vg_lite/lv_vg_lite_utils.c +++ b/src/draw/vg_lite/lv_vg_lite_utils.c @@ -629,6 +629,7 @@ bool lv_vg_lite_buffer_open_image(vg_lite_buffer_t * buffer, lv_image_decoder_ds args.stride_align = true; args.use_indexed = true; args.no_cache = no_cache; + args.flush_cache = true; lv_result_t res = lv_image_decoder_open(decoder_dsc, src, &args); if(res != LV_RESULT_OK) { diff --git a/src/drivers/nuttx/lv_nuttx_cache.c b/src/drivers/nuttx/lv_nuttx_cache.c index 0655d2f56..0d5a9742c 100644 --- a/src/drivers/nuttx/lv_nuttx_cache.c +++ b/src/drivers/nuttx/lv_nuttx_cache.c @@ -27,6 +27,7 @@ **********************/ static void invalidate_cache(const lv_draw_buf_t * draw_buf, const lv_area_t * area); +static void flush_cache(const lv_draw_buf_t * draw_buf, const lv_area_t * area); /********************** * STATIC VARIABLES @@ -44,28 +45,44 @@ void lv_nuttx_cache_init(void) { lv_draw_buf_handlers_t * handlers = lv_draw_buf_get_handlers(); handlers->invalidate_cache_cb = invalidate_cache; + handlers->flush_cache_cb = flush_cache; } /********************** * STATIC FUNCTIONS **********************/ -static void invalidate_cache(const lv_draw_buf_t * draw_buf, const lv_area_t * area) +static void draw_buf_to_region( + const lv_draw_buf_t * draw_buf, const lv_area_t * area, + lv_uintptr_t * start, lv_uintptr_t * end) { LV_ASSERT_NULL(draw_buf); + LV_ASSERT_NULL(area); + LV_ASSERT_NULL(start); + LV_ASSERT_NULL(end); + void * buf = draw_buf->data; uint32_t stride = draw_buf->header.stride; - lv_uintptr_t start; - lv_uintptr_t end; - int32_t h = lv_area_get_height(area); - start = (lv_uintptr_t)buf + area->y1 * stride; - end = start + h * stride; + *start = (lv_uintptr_t)buf + area->y1 * stride; + *end = *start + h * stride; +} - LV_UNUSED(start); - LV_UNUSED(end); +static void invalidate_cache(const lv_draw_buf_t * draw_buf, const lv_area_t * area) +{ + lv_uintptr_t start; + lv_uintptr_t end; + draw_buf_to_region(draw_buf, area, &start, &end); up_invalidate_dcache(start, end); } +static void flush_cache(const lv_draw_buf_t * draw_buf, const lv_area_t * area) +{ + lv_uintptr_t start; + lv_uintptr_t end; + draw_buf_to_region(draw_buf, area, &start, &end); + up_flush_dcache(start, end); +} + #endif /* LV_USE_NUTTX */ |