1
0
mirror of https://github.com/lvgl/lvgl.git synced 2025-01-14 06:42:58 +08:00

feat(draw_buf): add API to reshape existing draw buf (#5133)

Signed-off-by: Xu Xingliang <xuxingliang@xiaomi.com>
This commit is contained in:
Neo Xu 2024-01-03 20:07:53 +08:00 committed by GitHub
parent 91e2617410
commit 398e181dd3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 62 additions and 14 deletions

View File

@ -27,6 +27,7 @@ static void * buf_malloc(size_t size, lv_color_format_t color_format);
static void buf_free(void * buf);
static void * buf_align(void * buf, 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 VARIABLES
@ -136,25 +137,12 @@ void lv_draw_buf_copy(void * dest_buf, uint32_t dest_w, uint32_t dest_h, const l
lv_draw_buf_t * lv_draw_buf_create(uint32_t w, uint32_t h, lv_color_format_t cf, uint32_t stride)
{
uint32_t size;
lv_draw_buf_t * draw_buf = lv_malloc_zeroed(sizeof(lv_draw_buf_t));
LV_ASSERT_MALLOC(draw_buf);
if(draw_buf == NULL) return NULL;
if(stride == 0) stride = lv_draw_buf_width_to_stride(w, cf);
size = stride * h;
if(cf == LV_COLOR_FORMAT_RGB565A8) {
size += (stride / 2) * h; /*A8 mask*/
}
else if(LV_COLOR_FORMAT_IS_INDEXED(cf)) {
/*@todo we have to include palette right before image data*/
size += LV_COLOR_INDEXED_PALETTE_SIZE(cf) * 4;
}
/*RLE decompression operates on pixel unit, thus add padding to make sure memory is enough*/
uint8_t bpp = lv_color_format_get_bpp(cf);
bpp = (bpp + 7) >> 3;
size += bpp;
uint32_t size = _calculate_draw_buf_size(w, h, cf, stride);
void * buf = lv_draw_buf_malloc(size, cf);
LV_ASSERT_MALLOC(buf);
@ -191,6 +179,28 @@ lv_draw_buf_t * lv_draw_buf_dup(const lv_draw_buf_t * draw_buf)
return new_buf;
}
lv_draw_buf_t * lv_draw_buf_reshape(lv_draw_buf_t * draw_buf, lv_color_format_t cf, uint32_t w, uint32_t h,
uint32_t stride)
{
if(draw_buf == NULL) return NULL;
if(stride == 0) stride = lv_draw_buf_width_to_stride(w, cf);
uint32_t size = _calculate_draw_buf_size(w, h, cf, stride);
if(size > draw_buf->data_size) {
LV_LOG_INFO("Draw buf too small for new shape");
return NULL;
}
draw_buf->header.cf = cf;
draw_buf->header.w = w;
draw_buf->header.h = h;
draw_buf->header.stride = stride;
return draw_buf;
}
void lv_draw_buf_destroy(lv_draw_buf_t * buf)
{
LV_ASSERT_NULL(buf);
@ -351,3 +361,29 @@ static uint32_t width_to_stride(uint32_t w, lv_color_format_t color_format)
width_byte = (width_byte + 7) >> 3; /*Round up*/
return (width_byte + LV_DRAW_BUF_STRIDE_ALIGN - 1) & ~(LV_DRAW_BUF_STRIDE_ALIGN - 1);
}
/**
* For given width, height, color format, and stride, calculate the size needed for a new draw buffer.
*/
static uint32_t _calculate_draw_buf_size(uint32_t w, uint32_t h, lv_color_format_t cf, uint32_t stride)
{
uint32_t size;
if(stride == 0) stride = lv_draw_buf_width_to_stride(w, cf);
size = stride * h;
if(cf == LV_COLOR_FORMAT_RGB565A8) {
size += (stride / 2) * h; /*A8 mask*/
}
else if(LV_COLOR_FORMAT_IS_INDEXED(cf)) {
/*@todo we have to include palette right before image data*/
size += LV_COLOR_INDEXED_PALETTE_SIZE(cf) * 4;
}
/*RLE decompression operates on pixel unit, thus add padding to make sure memory is enough*/
uint8_t bpp = lv_color_format_get_bpp(cf);
bpp = (bpp + 7) >> 3;
size += bpp;
return size;
}

View File

@ -188,6 +188,18 @@ lv_draw_buf_t * lv_draw_buf_create(uint32_t w, uint32_t h, lv_color_format_t cf,
*/
lv_draw_buf_t * lv_draw_buf_dup(const lv_draw_buf_t * draw_buf);
/**
* Keep using the existing memory, reshape the draw buffer to the given width and height.
* Return NULL if data_size is smaller than the required size.
* @param draw_buf pointer to a draw buffer
* @param cf the new color format
* @param w the new width in pixels
* @param h the new height in pixels
* @param stride the stride in bytes for image. Use 0 for automatic calculation.
*/
lv_draw_buf_t * lv_draw_buf_reshape(lv_draw_buf_t * draw_buf, lv_color_format_t cf, uint32_t w, uint32_t h,
uint32_t stride);
/**
* Destroy a draw buf by free the actual buffer if it's marked as LV_IMAGE_FLAGS_MODIFIABLE in header.
* Then free the lv_draw_buf_t struct.