1
0
mirror of https://github.com/lvgl/lvgl.git synced 2025-01-28 07:03:00 +08:00

chore(draw_buf): add draw buf struct definition (#4833)

Signed-off-by: Xu Xingliang <xuxingliang@xiaomi.com>
This commit is contained in:
Neo Xu 2023-12-11 21:16:31 +08:00 committed by GitHub
parent f325e4d1c0
commit 39264bcd87
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 177 additions and 2 deletions

View File

@ -115,6 +115,108 @@ void lv_draw_buf_copy(void * dest_buf, uint32_t dest_w, uint32_t dest_h, const l
color_format); color_format);
} }
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;
void * buf = lv_draw_buf_malloc(size, cf);
LV_ASSERT_MALLOC(buf);
if(buf == NULL) {
lv_free(draw_buf);
return NULL;
}
draw_buf->header.w = w;
draw_buf->header.h = h;
draw_buf->header.cf = cf;
draw_buf->header.flags = LV_IMAGE_FLAGS_MODIFIABLE;
draw_buf->header.stride = stride;
draw_buf->data = lv_draw_buf_align(buf, cf);
draw_buf->_unaligned = buf;
draw_buf->data_size = size;
return draw_buf;
}
void lv_draw_buf_destroy(lv_draw_buf_t * buf)
{
LV_ASSERT_NULL(buf);
if(buf == NULL) return;
if(buf->header.flags & LV_IMAGE_FLAGS_MODIFIABLE)
lv_draw_buf_free(buf->_unaligned);
lv_free(buf);
}
void * lv_draw_buf_goto_xy(lv_draw_buf_t * buf, uint32_t x, uint32_t y)
{
LV_ASSERT_NULL(buf);
if(buf == NULL) return NULL;
uint8_t * data = buf->data;
data += buf->header.stride * y;
if(x == 0)
return data;
return data + x * lv_color_format_get_size(buf->header.cf);
}
/**
* Convert draw buffer stride and color format.
* @param src source draw buffer
* @param stride new stride
* @return converted draw buffer
*/
lv_draw_buf_t * lv_draw_buf_adjust_stride(const lv_draw_buf_t * src, uint32_t stride)
{
LV_ASSERT_NULL(src);
LV_ASSERT_NULL(src->data);
if(src == NULL) return NULL;
if(src->data == NULL) return NULL;
/*Check if stride already match*/
if(src->header.stride == stride) return NULL;
/*Calculate the minimal stride allowed from bpp*/
uint32_t bpp = lv_color_format_get_bpp(src->header.cf);
uint32_t min_stride = (src->header.w * bpp + 7) >> 3;
if(stride < min_stride) {
LV_LOG_WARN("New stride is too small. min: %" LV_PRId32, min_stride);
return NULL;
}
lv_draw_buf_t * dst = lv_draw_buf_create(src->header.w, src->header.h, src->header.cf, stride);
if(dst == NULL) return NULL;
uint8_t * dst_data = dst->data;
const uint8_t * src_data = src->data;
for(int32_t y = 0; y < src->header.h; y++) {
lv_memcpy(dst_data, src_data, min_stride);
src_data += src->header.stride;
dst_data += dst->header.stride;
}
return dst;
}
/********************** /**********************
* STATIC FUNCTIONS * STATIC FUNCTIONS
**********************/ **********************/

View File

@ -15,6 +15,7 @@ extern "C" {
*********************/ *********************/
#include "../misc/lv_area.h" #include "../misc/lv_area.h"
#include "../misc/lv_color.h" #include "../misc/lv_color.h"
#include "lv_image_buf.h"
/********************* /*********************
* DEFINES * DEFINES
@ -24,6 +25,13 @@ extern "C" {
* TYPEDEFS * TYPEDEFS
**********************/ **********************/
typedef struct {
lv_image_header_t header;
uint32_t data_size; /*Total buf size in bytes*/
void * data;
void * _unaligned; /*Unaligned address of data*/
} lv_draw_buf_t;
typedef void * (*lv_draw_buf_malloc_cb)(size_t size, lv_color_format_t color_format); typedef void * (*lv_draw_buf_malloc_cb)(size_t size, lv_color_format_t color_format);
typedef void (*lv_draw_buf_free_cb)(void * draw_buf); typedef void (*lv_draw_buf_free_cb)(void * draw_buf);
@ -152,6 +160,54 @@ void lv_draw_buf_clear(void * buf, uint32_t w, uint32_t h, lv_color_format_t col
void lv_draw_buf_copy(void * dest_buf, uint32_t dest_w, uint32_t dest_h, const lv_area_t * dest_area_to_copy, void lv_draw_buf_copy(void * dest_buf, uint32_t dest_w, uint32_t dest_h, const lv_area_t * dest_area_to_copy,
void * src_buf, uint32_t src_w, uint32_t src_h, const lv_area_t * src_area_to_copy, void * src_buf, uint32_t src_w, uint32_t src_h, const lv_area_t * src_area_to_copy,
lv_color_format_t color_format); lv_color_format_t color_format);
/**
* Note: Eventually, lv_draw_buf_malloc/free will be kept as private.
* For now, we use `create` to distinguish with malloc.
*
* Create an draw buf by allocating struct for `lv_draw_buf_t` and allocating a buffer for it
* that meets specified requirements.
*
* @param w the buffer width in pixels
* @param h
* @param cf the color format for image
* @param stride the stride in bytes for image. Use 0 for automatic calculation based on
* w, cf, and global stride alignment configuration.
*/
lv_draw_buf_t * lv_draw_buf_create(uint32_t w, uint32_t h, lv_color_format_t cf, 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.
*/
void lv_draw_buf_destroy(lv_draw_buf_t * buf);
/**
* @todo, need to replace lv_draw_buf_go_to_xy.
* Return pointer to the buffer at the given coordinates
*/
void * lv_draw_buf_goto_xy(lv_draw_buf_t * buf, uint32_t x, uint32_t y);
/**
* Adjust the stride of a draw buf.
*/
lv_draw_buf_t * lv_draw_buf_adjust_stride(const lv_draw_buf_t * src, uint32_t stride);
/**
* As of now, draw buf share same definition as `lv_image_dsc_t`.
* And is interchangeable with `lv_image_dsc_t`.
*/
static inline void lv_draw_buf_from_image(lv_draw_buf_t * buf, const lv_image_dsc_t * img)
{
lv_memcpy(buf, img, sizeof(lv_image_dsc_t));
}
static inline void lv_draw_buf_to_image(const lv_draw_buf_t * buf, lv_image_dsc_t * img)
{
lv_memcpy(img, buf, sizeof(lv_image_dsc_t));
}
/********************** /**********************
* MACROS * MACROS
**********************/ **********************/

View File

@ -16,6 +16,7 @@ extern "C" {
#include <stdbool.h> #include <stdbool.h>
#include "../misc/lv_color.h" #include "../misc/lv_color.h"
#include "../misc/lv_area.h" #include "../misc/lv_area.h"
#include "../stdlib/lv_string.h"
/********************* /*********************
* DEFINES * DEFINES
@ -122,8 +123,13 @@ typedef struct {
} lv_image_header_t; } lv_image_header_t;
#endif #endif
/** Image header it is compatible with /**
* the result from image converter utility*/ * Struct to describe an image. Both decoded and raw image can share
* the same struct.
*
* Image is also identical to lv_draw_buf_t for now.
* Ideally, decoded image should be lv_draw_buf_t.
*/
typedef struct { typedef struct {
lv_image_header_t header; /**< A header describing the basics of the image*/ lv_image_header_t header; /**< A header describing the basics of the image*/
uint32_t data_size; /**< Size of the image in bytes*/ uint32_t data_size; /**< Size of the image in bytes*/
@ -166,6 +172,17 @@ void _lv_image_buf_get_transformed_area(lv_area_t * res, int32_t w, int32_t h, i
uint16_t scale_y, uint16_t scale_y,
const lv_point_t * pivot); const lv_point_t * pivot);
static inline void lv_image_header_init(lv_image_header_t * header, uint32_t w, uint32_t h, lv_color_format_t cf,
uint32_t stride, lv_image_flags_t flags)
{
LV_ASSERT(header);
lv_memzero(header, sizeof(*header));
header->w = w;
header->h = h;
header->cf = cf;
header->stride = stride;
header->flags = flags;
}
/********************** /**********************
* MACROS * MACROS
**********************/ **********************/