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

feat(draw_buf): add lv_draw_buf_handlers to allow using custom callbacks

This commit is contained in:
Gabor Kiss-Vamosi 2023-08-25 22:47:59 +02:00
parent cd5c93b248
commit 45ff2a663b
9 changed files with 325 additions and 203 deletions

View File

@ -75,18 +75,11 @@
/*========================
* RENDERING CONFIGURATION
*========================*/
/* Select a draw buffer implementation. Possible values:
* - LV_DRAW_BUF_BASIC: LVGL's built in implementation
* - LV_DRAW_BUF_CUSTOM: Implement the function of lv_draw_buf.h externally
*/
#define LV_USE_DRAW_BUF LV_DRAW_BUF_BASIC
#if LV_USE_DRAW_BUF == LV_DRAW_BUF_BASIC
/*Align the stride of all layers and images to this bytes*/
#define LV_DRAW_BUF_STRIDE_ALIGN 1 /*Multiple of these Bytes*/
/*Align the start address of draw_buf addresses to this bytes*/
#define LV_DRAW_BUF_ALIGN 4
#endif
/*Align the stride of all layers and images to this bytes*/
#define LV_DRAW_BUF_STRIDE_ALIGN 1 /*Multiple of these Bytes*/
/*Align the start address of draw_buf addresses to this bytes*/
#define LV_DRAW_BUF_ALIGN 4
/*Align the stride of all layers and images to this bytes*/
#define LV_DRAW_BUF_STRIDE_ALIGN 1

View File

@ -98,6 +98,8 @@ typedef struct _lv_global_t {
lv_anim_state_t anim_state;
lv_tick_state_t tick_state;
lv_draw_buf_handlers_t draw_buf_handlers;
lv_ll_t img_decoder_ll;
lv_img_cache_manager_t img_cache_mgr;
#if LV_IMG_CACHE_DEF_SIZE

View File

@ -1,155 +0,0 @@
/**
* @file lv_draw_buf_basic.c
*
*/
/*********************
* INCLUDES
*********************/
#include "../../misc/lv_types.h"
#include "lv_draw_buf.h"
#if LV_USE_DRAW_BUF == LV_DRAW_BUF_BASIC
#include "../../stdlib/lv_string.h"
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
static uint8_t * buf_alloc(void * old_buf, lv_coord_t w, lv_coord_t h);
/**********************
* STATIC VARIABLES
**********************/
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
void lv_draw_buf_init(lv_draw_buf_t * draw_buf, lv_coord_t w, lv_coord_t h, lv_color_format_t color_format)
{
draw_buf->width = w;
draw_buf->height = h;
draw_buf->color_format = color_format;
draw_buf->buf = NULL;
}
void lv_draw_buf_malloc(lv_draw_buf_t * draw_buf)
{
if(draw_buf->width != 0 ||
draw_buf->height != 0) draw_buf->buf = buf_alloc(NULL, lv_draw_buf_get_stride(draw_buf), draw_buf->height);
else draw_buf->buf = NULL;
}
void lv_draw_buf_realloc(lv_draw_buf_t * draw_buf, lv_coord_t w, lv_coord_t h,
lv_color_format_t color_format)
{
draw_buf->width = w;
draw_buf->height = h;
draw_buf->color_format = color_format;
draw_buf->buf = buf_alloc(draw_buf->buf, lv_draw_buf_get_stride(draw_buf), h);
}
void lv_draw_buf_free(lv_draw_buf_t * draw_buf)
{
lv_free(draw_buf->buf);
}
void * lv_draw_buf_get_buf(lv_draw_buf_t * draw_buf)
{
uint8_t * buf = draw_buf->buf;
if(buf) {
buf += LV_DRAW_BUF_ALIGN - 1;
buf = (uint8_t *)((lv_uintptr_t) buf & ~(LV_DRAW_BUF_ALIGN - 1));
}
return buf;
}
void lv_draw_buf_invalidate_cache(lv_draw_buf_t * draw_buf)
{
LV_UNUSED(draw_buf);
}
uint32_t lv_draw_buf_width_to_stride(uint32_t w, lv_color_format_t color_format)
{
uint32_t width_byte = w * lv_color_format_get_size(color_format);
return (width_byte + LV_DRAW_BUF_STRIDE_ALIGN - 1) & ~(LV_DRAW_BUF_STRIDE_ALIGN - 1);
}
uint32_t lv_draw_buf_get_stride(const lv_draw_buf_t * draw_buf)
{
return lv_draw_buf_width_to_stride(draw_buf->width, draw_buf->color_format);
}
void * lv_draw_buf_go_to_xy(lv_draw_buf_t * draw_buf, lv_coord_t x, lv_coord_t y)
{
uint32_t px_size = lv_color_format_get_size(draw_buf->color_format);
uint32_t stride = lv_draw_buf_get_stride(draw_buf);
uint8_t * buf_tmp = lv_draw_buf_get_buf(draw_buf);
buf_tmp += stride * y;
buf_tmp += x * px_size;
return buf_tmp;
}
void lv_draw_buf_clear(lv_draw_buf_t * draw_buf, const lv_area_t * a)
{
//TODO clear the area
LV_UNUSED(a);
uint32_t stride = lv_draw_buf_get_stride(draw_buf);
uint8_t * buf = lv_draw_buf_get_buf(draw_buf);
lv_memzero(buf, stride * draw_buf->height);
}
void lv_draw_buf_copy(void * dest_buf, uint32_t dest_stride, const lv_area_t * dest_area,
void * src_buf, uint32_t src_stride, const lv_area_t * src_area, lv_color_format_t color_format)
{
uint8_t px_size = lv_color_format_get_size(color_format);
uint8_t * dest_bufc = dest_buf;
uint8_t * src_bufc = src_buf;
/*Got the first pixel of each buffer*/
dest_bufc += dest_stride * dest_area->y1;
dest_bufc += dest_area->x1 * px_size;
src_bufc += src_stride * src_area->y1;
src_bufc += src_area->x1 * px_size;
uint32_t line_length = lv_area_get_width(dest_area) * px_size;
lv_coord_t y;
for(y = dest_area->y1; y <= dest_area->y2; y++) {
lv_memcpy(dest_bufc, src_bufc, line_length);
dest_bufc += dest_stride;
src_bufc += src_stride;
}
}
/**********************
* STATIC FUNCTIONS
**********************/
static uint8_t * buf_alloc(void * old_buf, lv_coord_t w, lv_coord_t h)
{
uint8_t * buf;
size_t s = w * h + LV_DRAW_BUF_ALIGN - 1;
if(old_buf) buf = lv_realloc(old_buf, s);
else buf = lv_malloc(s);
return buf;
}
#endif /*LV_USE DRAW_BUF == LV_DRAW_BUF_BASIC*/

View File

@ -21,7 +21,7 @@ extern "C" {
#include "lv_img_decoder.h"
#include "lv_img_cache.h"
#include "../osal/lv_os.h"
#include "draw_buf/lv_draw_buf.h"
#include "lv_draw_buf.h"
/*********************
* DEFINES

245
src/draw/lv_draw_buf.c Normal file
View File

@ -0,0 +1,245 @@
/**
* @file lv_draw_buf_basic.c
*
*/
/*********************
* INCLUDES
*********************/
#include "../misc/lv_types.h"
#include "lv_draw_buf.h"
#include "../stdlib/lv_string.h"
#include "../core/lv_global.h"
/*********************
* DEFINES
*********************/
#define handlers LV_GLOBAL_DEFAULT()->draw_buf_handlers
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
static void buf_init(lv_draw_buf_t * draw_buf, lv_coord_t w, lv_coord_t h, lv_color_format_t color_format);
static void buf_malloc(lv_draw_buf_t * draw_buf);
static void buf_realloc(lv_draw_buf_t * draw_buf, lv_coord_t w, lv_coord_t h,
lv_color_format_t color_format);
static void buf_free(lv_draw_buf_t * draw_buf);
static void * buf_get(lv_draw_buf_t * draw_buf);
static uint32_t width_to_stride(uint32_t w, lv_color_format_t color_format);
static uint32_t get_stride(const lv_draw_buf_t * draw_buf);
static void * go_to_xy(lv_draw_buf_t * draw_buf, lv_coord_t x, lv_coord_t y);
static void buf_clear(lv_draw_buf_t * draw_buf, const lv_area_t * a);
static void buf_copy(void * dest_buf, uint32_t dest_stride, const lv_area_t * dest_area,
void * src_buf, uint32_t src_stride, const lv_area_t * src_area, lv_color_format_t color_format);
static uint8_t * buf_alloc_core(void * old_buf, lv_coord_t w, lv_coord_t h);
/**********************
* STATIC VARIABLES
**********************/
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
void _lv_draw_buf_init_handlers(void)
{
lv_memzero(&handlers, sizeof(lv_draw_buf_handlers_t));
handlers.init_cb = buf_init;
handlers.buf_malloc_cb = buf_malloc;
handlers.buf_realloc_cb = buf_realloc;
handlers.buf_free_cb = buf_free;
handlers.buf_get_cb = buf_get;
handlers.invalidate_cache_cb = NULL;
handlers.width_to_stride_cb = width_to_stride;
handlers.get_stride_cb = get_stride;
handlers.go_to_xy_cb = go_to_xy;
handlers.buf_clear_cb = buf_clear;
handlers.buf_copy_cb = buf_copy;
}
lv_draw_buf_handlers_t * lv_draw_bug_get_handlers(void)
{
return &handlers;
}
void lv_draw_buf_init(lv_draw_buf_t * draw_buf, lv_coord_t w, lv_coord_t h, lv_color_format_t color_format)
{
if(handlers.init_cb) handlers.init_cb(draw_buf, w, h, color_format);
}
void lv_draw_buf_malloc(lv_draw_buf_t * draw_buf)
{
if(handlers.buf_malloc_cb) handlers.buf_malloc_cb(draw_buf);
}
void lv_draw_buf_realloc(lv_draw_buf_t * draw_buf, lv_coord_t w, lv_coord_t h,
lv_color_format_t color_format)
{
if(handlers.buf_realloc_cb) handlers.buf_realloc_cb(draw_buf, w, h, color_format);
}
void lv_draw_buf_free(lv_draw_buf_t * draw_buf)
{
if(handlers.buf_free_cb) handlers.buf_free_cb(draw_buf);
}
void * lv_draw_buf_get_buf(lv_draw_buf_t * draw_buf)
{
if(handlers.buf_get_cb) return handlers.buf_get_cb(draw_buf);
else return NULL;
}
void lv_draw_buf_invalidate_cache(lv_draw_buf_t * draw_buf, const char * area)
{
if(handlers.invalidate_cache_cb) handlers.invalidate_cache_cb(draw_buf, area);
}
uint32_t lv_draw_buf_width_to_stride(uint32_t w, lv_color_format_t color_format)
{
if(handlers.width_to_stride_cb) return handlers.width_to_stride_cb(w, color_format);
else return 0;
}
uint32_t lv_draw_buf_get_stride(const lv_draw_buf_t * draw_buf)
{
if(handlers.get_stride_cb) return handlers.get_stride_cb(draw_buf);
else return 0;
}
void * lv_draw_buf_go_to_xy(lv_draw_buf_t * draw_buf, lv_coord_t x, lv_coord_t y)
{
if(handlers.go_to_xy_cb) return handlers.go_to_xy_cb(draw_buf, x, y);
else return NULL;
}
void lv_draw_buf_clear(lv_draw_buf_t * draw_buf, const lv_area_t * a)
{
if(handlers.buf_clear_cb) handlers.buf_clear_cb(draw_buf, a);
}
void lv_draw_buf_copy(void * dest_buf, uint32_t dest_stride, const lv_area_t * dest_area,
void * src_buf, uint32_t src_stride, const lv_area_t * src_area, lv_color_format_t color_format)
{
if(handlers.buf_copy_cb) handlers.buf_copy_cb(dest_buf, dest_stride, dest_area, src_buf, src_stride, src_area,
color_format);
}
/**********************
* STATIC FUNCTIONS
**********************/
static void buf_init(lv_draw_buf_t * draw_buf, lv_coord_t w, lv_coord_t h, lv_color_format_t color_format)
{
draw_buf->width = w;
draw_buf->height = h;
draw_buf->color_format = color_format;
draw_buf->buf = NULL;
}
static void buf_malloc(lv_draw_buf_t * draw_buf)
{
if(draw_buf->width != 0 ||
draw_buf->height != 0) draw_buf->buf = buf_alloc_core(NULL, lv_draw_buf_get_stride(draw_buf), draw_buf->height);
else draw_buf->buf = NULL;
}
static void buf_realloc(lv_draw_buf_t * draw_buf, lv_coord_t w, lv_coord_t h,
lv_color_format_t color_format)
{
draw_buf->width = w;
draw_buf->height = h;
draw_buf->color_format = color_format;
draw_buf->buf = buf_alloc_core(draw_buf->buf, lv_draw_buf_get_stride(draw_buf), h);
}
static void buf_free(lv_draw_buf_t * draw_buf)
{
lv_free(draw_buf->buf);
}
static void * buf_get(lv_draw_buf_t * draw_buf)
{
uint8_t * buf = draw_buf->buf;
if(buf) {
buf += LV_DRAW_BUF_ALIGN - 1;
buf = (uint8_t *)((lv_uintptr_t) buf & ~(LV_DRAW_BUF_ALIGN - 1));
}
return buf;
}
static uint32_t width_to_stride(uint32_t w, lv_color_format_t color_format)
{
uint32_t width_byte = w * lv_color_format_get_size(color_format);
return (width_byte + LV_DRAW_BUF_STRIDE_ALIGN - 1) & ~(LV_DRAW_BUF_STRIDE_ALIGN - 1);
}
static uint32_t get_stride(const lv_draw_buf_t * draw_buf)
{
return lv_draw_buf_width_to_stride(draw_buf->width, draw_buf->color_format);
}
static void * go_to_xy(lv_draw_buf_t * draw_buf, lv_coord_t x, lv_coord_t y)
{
uint32_t px_size = lv_color_format_get_size(draw_buf->color_format);
uint32_t stride = lv_draw_buf_get_stride(draw_buf);
uint8_t * buf_tmp = lv_draw_buf_get_buf(draw_buf);
buf_tmp += stride * y;
buf_tmp += x * px_size;
return buf_tmp;
}
static void buf_clear(lv_draw_buf_t * draw_buf, const lv_area_t * a)
{
//TODO clear the area
LV_UNUSED(a);
uint32_t stride = lv_draw_buf_get_stride(draw_buf);
uint8_t * buf = lv_draw_buf_get_buf(draw_buf);
lv_memzero(buf, stride * draw_buf->height);
}
static void buf_copy(void * dest_buf, uint32_t dest_stride, const lv_area_t * dest_area,
void * src_buf, uint32_t src_stride, const lv_area_t * src_area, lv_color_format_t color_format)
{
uint8_t px_size = lv_color_format_get_size(color_format);
uint8_t * dest_bufc = dest_buf;
uint8_t * src_bufc = src_buf;
/*Got the first pixel of each buffer*/
dest_bufc += dest_stride * dest_area->y1;
dest_bufc += dest_area->x1 * px_size;
src_bufc += src_stride * src_area->y1;
src_bufc += src_area->x1 * px_size;
uint32_t line_length = lv_area_get_width(dest_area) * px_size;
lv_coord_t y;
for(y = dest_area->y1; y <= dest_area->y2; y++) {
lv_memcpy(dest_bufc, src_bufc, line_length);
dest_bufc += dest_stride;
src_bufc += src_stride;
}
}
static uint8_t * buf_alloc_core(void * old_buf, lv_coord_t w, lv_coord_t h)
{
uint8_t * buf;
size_t s = w * h + LV_DRAW_BUF_ALIGN - 1;
if(old_buf) buf = lv_realloc(old_buf, s);
else buf = lv_malloc(s);
return buf;
}

View File

@ -13,8 +13,8 @@ extern "C" {
/*********************
* INCLUDES
*********************/
#include "../../misc/lv_area.h"
#include "../../misc/lv_color.h"
#include "../misc/lv_area.h"
#include "../misc/lv_color.h"
/*********************
* DEFINES
@ -33,10 +33,61 @@ typedef struct {
} lv_draw_buf_t;
typedef void (*lv_draw_buf_init_cb)(lv_draw_buf_t * draw_buf, lv_coord_t w, lv_coord_t h,
lv_color_format_t color_format);
typedef void (*lv_draw_buf_malloc_cb)(lv_draw_buf_t * draw_buf);
typedef void (*lv_draw_buf_realloc_cb)(lv_draw_buf_t * draw_buf, lv_coord_t w, lv_coord_t h,
lv_color_format_t color_format);
typedef void (*lv_draw_buf_free_cb)(lv_draw_buf_t * draw_buf);
typedef void * (*lv_draw_buf_get_buf_cb)(lv_draw_buf_t * draw_buf);
typedef void (*lv_draw_buf_invalidate_cache_cb)(lv_draw_buf_t * draw_buf, const char * 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_get_stride_cb)(const lv_draw_buf_t * draw_buf);
typedef void * (*lv_draw_buf_go_to_xy_cb)(lv_draw_buf_t * draw_buf, lv_coord_t x, lv_coord_t y);
typedef void (*lv_draw_buf_clear_cb)(lv_draw_buf_t * draw_buf, const lv_area_t * a);
typedef void (*lv_draw_buf_copy_cb)(void * dest_buf, uint32_t dest_stride, const lv_area_t * dest_area,
void * src_buf, uint32_t src_stride, const lv_area_t * src_area, lv_color_format_t color_format);
typedef struct {
lv_draw_buf_init_cb init_cb;
lv_draw_buf_malloc_cb buf_malloc_cb;
lv_draw_buf_realloc_cb buf_realloc_cb;
lv_draw_buf_free_cb buf_free_cb;
lv_draw_buf_get_buf_cb buf_get_cb;
lv_draw_buf_invalidate_cache_cb invalidate_cache_cb;
lv_draw_buf_width_to_stride_cb width_to_stride_cb;
lv_draw_buf_get_stride_cb get_stride_cb;
lv_draw_buf_go_to_xy_cb go_to_xy_cb;
lv_draw_buf_clear_cb buf_clear_cb;
lv_draw_buf_copy_cb buf_copy_cb;
} lv_draw_buf_handlers_t;
/**********************
* GLOBAL PROTOTYPES
**********************/
/**
* Called internally to initialize the draw_buf_handlers in lv_global
*/
void _lv_draw_buf_init_handlers(void);
/**
* Get the struct which holds the callbacks for draw buf management.
* Custom callback can be set on the returned value
* @return pointer to the struct of handlers
*/
lv_draw_buf_handlers_t * lv_draw_bug_get_handlers(void);
/**
* Initialize a draw buffer object. The buffer won't be allocated
* @param draw_buf pointer to a draw buffer
@ -78,9 +129,9 @@ void * lv_draw_buf_get_buf(lv_draw_buf_t * draw_buf);
/**
* Invalidate the cache of the buffer
* @param draw_buf pointer to a draw buffer
* @param arae the whose cache needs to be invalidated
*/
void lv_draw_buf_invalidate_cache(lv_draw_buf_t * draw_buf);
void lv_draw_buf_invalidate_cache(lv_draw_buf_t * draw_buf, const char * area);
/**
* Calculate the stride in bytes based on a width and color format

View File

@ -185,38 +185,25 @@
/*========================
* RENDERING CONFIGURATION
*========================*/
/* Select a draw buffer implementation. Possible values:
* - LV_DRAW_BUF_BASIC: LVGL's built in implementation
* - LV_DRAW_BUF_CUSTOM: Implement the function of lv_draw_buf.h externally
*/
#ifndef LV_USE_DRAW_BUF
#ifdef CONFIG_LV_USE_DRAW_BUF
#define LV_USE_DRAW_BUF CONFIG_LV_USE_DRAW_BUF
/*Align the stride of all layers and images to this bytes*/
#ifndef LV_DRAW_BUF_STRIDE_ALIGN
#ifdef _LV_KCONFIG_PRESENT
#ifdef CONFIG_LV_DRAW_BUF_STRIDE_ALIGN
#define LV_DRAW_BUF_STRIDE_ALIGN CONFIG_LV_DRAW_BUF_STRIDE_ALIGN
#else
#define LV_DRAW_BUF_STRIDE_ALIGN 0
#endif
#else
#define LV_USE_DRAW_BUF LV_DRAW_BUF_BASIC
#define LV_DRAW_BUF_STRIDE_ALIGN 1 /*Multiple of these Bytes*/
#endif
#endif
#if LV_USE_DRAW_BUF == LV_DRAW_BUF_BASIC
/*Align the stride of all layers and images to this bytes*/
#ifndef LV_DRAW_BUF_STRIDE_ALIGN
#ifdef _LV_KCONFIG_PRESENT
#ifdef CONFIG_LV_DRAW_BUF_STRIDE_ALIGN
#define LV_DRAW_BUF_STRIDE_ALIGN CONFIG_LV_DRAW_BUF_STRIDE_ALIGN
#else
#define LV_DRAW_BUF_STRIDE_ALIGN 0
#endif
#else
#define LV_DRAW_BUF_STRIDE_ALIGN 1 /*Multiple of these Bytes*/
#endif
#endif
/*Align the start address of draw_buf addresses to this bytes*/
#ifndef LV_DRAW_BUF_ALIGN
#ifdef CONFIG_LV_DRAW_BUF_ALIGN
#define LV_DRAW_BUF_ALIGN CONFIG_LV_DRAW_BUF_ALIGN
#else
#define LV_DRAW_BUF_ALIGN 4
#endif
/*Align the start address of draw_buf addresses to this bytes*/
#ifndef LV_DRAW_BUF_ALIGN
#ifdef CONFIG_LV_DRAW_BUF_ALIGN
#define LV_DRAW_BUF_ALIGN CONFIG_LV_DRAW_BUF_ALIGN
#else
#define LV_DRAW_BUF_ALIGN 4
#endif
#endif

View File

@ -103,6 +103,8 @@ void lv_init(void)
lv_mem_init();
_lv_draw_buf_init_handlers();
#if LV_USE_SPAN != 0
lv_span_stack_init();
#endif

View File

@ -44,9 +44,6 @@ extern "C" {
#define LV_STDLIB_MICROPYTHON 2
#define LV_STDLIB_CUSTOM 255
#define LV_DRAW_BUF_BASIC 0
#define LV_DRAW_BUF_CUSTOM 255
/**********************
* TYPEDEFS
**********************/