mirror of
https://github.com/lvgl/lvgl.git
synced 2026-05-28 05:26:18 +08:00
fix(vg_lite): fix incorrect cache operation (#6054)
Signed-off-by: pengyiqiang <pengyiqiang@xiaomi.com> Co-authored-by: pengyiqiang <pengyiqiang@xiaomi.com>
This commit is contained in:
+46
-13
@@ -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 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 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 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
|
* 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)
|
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,
|
void lv_draw_buf_init_handlers(lv_draw_buf_handlers_t * handlers,
|
||||||
lv_draw_buf_malloc_cb buf_malloc_cb,
|
lv_draw_buf_malloc_cb buf_malloc_cb,
|
||||||
lv_draw_buf_free_cb buf_free_cb,
|
lv_draw_buf_free_cb buf_free_cb,
|
||||||
lv_draw_buf_align_cb align_pointer_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_width_to_stride_cb width_to_stride_cb)
|
||||||
{
|
{
|
||||||
lv_memzero(handlers, sizeof(lv_draw_buf_handlers_t));
|
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->buf_free_cb = buf_free_cb;
|
||||||
handlers->align_pointer_cb = align_pointer_cb;
|
handlers->align_pointer_cb = align_pointer_cb;
|
||||||
handlers->invalidate_cache_cb = invalidate_cache_cb;
|
handlers->invalidate_cache_cb = invalidate_cache_cb;
|
||||||
|
handlers->flush_cache_cb = flush_cache_cb;
|
||||||
handlers->width_to_stride_cb = width_to_stride_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,
|
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)
|
const lv_area_t * area)
|
||||||
{
|
{
|
||||||
if(handlers->invalidate_cache_cb) {
|
LV_ASSERT_NULL(draw_buf);
|
||||||
LV_ASSERT_NULL(draw_buf);
|
|
||||||
const lv_image_header_t * header = &draw_buf->header;
|
if(!handlers->invalidate_cache_cb) {
|
||||||
lv_area_t full;
|
return;
|
||||||
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_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)
|
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;
|
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);
|
||||||
|
}
|
||||||
|
|||||||
+22
-3
@@ -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_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);
|
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_malloc_cb buf_malloc_cb;
|
||||||
lv_draw_buf_free_cb buf_free_cb;
|
lv_draw_buf_free_cb buf_free_cb;
|
||||||
lv_draw_buf_align_cb align_pointer_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_width_to_stride_cb width_to_stride_cb;
|
||||||
} lv_draw_buf_handlers_t;
|
} 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_malloc_cb buf_malloc_cb,
|
||||||
lv_draw_buf_free_cb buf_free_cb,
|
lv_draw_buf_free_cb buf_free_cb,
|
||||||
lv_draw_buf_align_cb align_pointer_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_width_to_stride_cb width_to_stride_cb);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -162,6 +164,23 @@ 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,
|
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);
|
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
|
* Calculate the stride in bytes based on a width and color format
|
||||||
* @param w the width in pixels
|
* @param w the width in pixels
|
||||||
|
|||||||
@@ -112,6 +112,7 @@ lv_result_t lv_image_decoder_open(lv_image_decoder_dsc_t * dsc, const void * src
|
|||||||
.premultiply = false,
|
.premultiply = false,
|
||||||
.no_cache = false,
|
.no_cache = false,
|
||||||
.use_indexed = 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);
|
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;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -62,6 +62,7 @@ typedef struct _lv_image_decoder_args_t {
|
|||||||
bool premultiply; /*Whether image should be premultiplied or not after decoding*/
|
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 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 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;
|
} lv_image_decoder_args_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -248,11 +248,6 @@ static lv_result_t decoder_open_variable(lv_image_decoder_t * decoder, lv_image_
|
|||||||
dest += dest_stride;
|
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;
|
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_free(src_temp);
|
||||||
|
|
||||||
lv_fs_close(&file);
|
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;
|
return LV_RESULT_OK;
|
||||||
|
|
||||||
failed:
|
failed:
|
||||||
|
|||||||
@@ -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.stride_align = true;
|
||||||
args.use_indexed = true;
|
args.use_indexed = true;
|
||||||
args.no_cache = no_cache;
|
args.no_cache = no_cache;
|
||||||
|
args.flush_cache = true;
|
||||||
|
|
||||||
lv_result_t res = lv_image_decoder_open(decoder_dsc, src, &args);
|
lv_result_t res = lv_image_decoder_open(decoder_dsc, src, &args);
|
||||||
if(res != LV_RESULT_OK) {
|
if(res != LV_RESULT_OK) {
|
||||||
|
|||||||
@@ -27,6 +27,7 @@
|
|||||||
**********************/
|
**********************/
|
||||||
|
|
||||||
static void invalidate_cache(const lv_draw_buf_t * draw_buf, const lv_area_t * area);
|
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
|
* STATIC VARIABLES
|
||||||
@@ -44,28 +45,44 @@ void lv_nuttx_cache_init(void)
|
|||||||
{
|
{
|
||||||
lv_draw_buf_handlers_t * handlers = lv_draw_buf_get_handlers();
|
lv_draw_buf_handlers_t * handlers = lv_draw_buf_get_handlers();
|
||||||
handlers->invalidate_cache_cb = invalidate_cache;
|
handlers->invalidate_cache_cb = invalidate_cache;
|
||||||
|
handlers->flush_cache_cb = flush_cache;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
* STATIC FUNCTIONS
|
* 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(draw_buf);
|
||||||
|
LV_ASSERT_NULL(area);
|
||||||
|
LV_ASSERT_NULL(start);
|
||||||
|
LV_ASSERT_NULL(end);
|
||||||
|
|
||||||
void * buf = draw_buf->data;
|
void * buf = draw_buf->data;
|
||||||
uint32_t stride = draw_buf->header.stride;
|
uint32_t stride = draw_buf->header.stride;
|
||||||
|
|
||||||
|
int32_t h = lv_area_get_height(area);
|
||||||
|
*start = (lv_uintptr_t)buf + area->y1 * stride;
|
||||||
|
*end = *start + h * stride;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void invalidate_cache(const lv_draw_buf_t * draw_buf, const lv_area_t * area)
|
||||||
|
{
|
||||||
lv_uintptr_t start;
|
lv_uintptr_t start;
|
||||||
lv_uintptr_t end;
|
lv_uintptr_t end;
|
||||||
|
draw_buf_to_region(draw_buf, area, &start, &end);
|
||||||
int32_t h = lv_area_get_height(area);
|
|
||||||
start = (lv_uintptr_t)buf + area->y1 * stride;
|
|
||||||
end = start + h * stride;
|
|
||||||
|
|
||||||
LV_UNUSED(start);
|
|
||||||
LV_UNUSED(end);
|
|
||||||
up_invalidate_dcache(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 */
|
#endif /* LV_USE_NUTTX */
|
||||||
|
|||||||
Reference in New Issue
Block a user