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

perf(vg_lite): improve path append data performance (#7504)

Signed-off-by: pengyiqiang <pengyiqiang@xiaomi.com>
Co-authored-by: pengyiqiang <pengyiqiang@xiaomi.com>
This commit is contained in:
VIFEX 2024-12-24 18:48:36 +08:00 committed by GitHub
parent bd39f984b8
commit f378299370
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 83 additions and 46 deletions

View File

@ -346,8 +346,6 @@ static void lv_path_to_vg(lv_vg_lite_path_t * dest, const lv_vector_path_t * src
if((point)->y > max_y) max_y = (point)->y; \
} while(0)
#define VLC_SET_OP_CODE(ptr, op) (*((uint32_t*)ptr) = (op))
#define COPY_POINT_NEXT() \
do { \
CMP_BOUNDS(point); \
@ -371,30 +369,30 @@ static void lv_path_to_vg(lv_vg_lite_path_t * dest, const lv_vector_path_t * src
for(uint32_t i = 0; i < op_size; i++) {
switch(ops[i]) {
case LV_VECTOR_PATH_OP_MOVE_TO: {
VLC_SET_OP_CODE(path_data++, VLC_OP_MOVE);
LV_VG_LITE_PATH_SET_OP_CODE(path_data++, uint32_t, VLC_OP_MOVE);
COPY_POINT_NEXT();
}
break;
case LV_VECTOR_PATH_OP_LINE_TO: {
VLC_SET_OP_CODE(path_data++, VLC_OP_LINE);
LV_VG_LITE_PATH_SET_OP_CODE(path_data++, uint32_t, VLC_OP_LINE);
COPY_POINT_NEXT();
}
break;
case LV_VECTOR_PATH_OP_QUAD_TO: {
VLC_SET_OP_CODE(path_data++, VLC_OP_QUAD);
LV_VG_LITE_PATH_SET_OP_CODE(path_data++, uint32_t, VLC_OP_QUAD);
COPY_POINT_NEXT();
COPY_POINT_NEXT();
}
break;
case LV_VECTOR_PATH_OP_CUBIC_TO: {
VLC_SET_OP_CODE(path_data++, VLC_OP_CUBIC);
LV_VG_LITE_PATH_SET_OP_CODE(path_data++, uint32_t, VLC_OP_CUBIC);
COPY_POINT_NEXT();
COPY_POINT_NEXT();
COPY_POINT_NEXT();
}
break;
case LV_VECTOR_PATH_OP_CLOSE: {
VLC_SET_OP_CODE(path_data++, VLC_OP_CLOSE);
LV_VG_LITE_PATH_SET_OP_CODE(path_data++, uint32_t, VLC_OP_CLOSE);
}
break;
default:

View File

@ -32,6 +32,9 @@
case VLC_OP_##OP: \
return (LEN)
#define PATH_CURRENT_PTR(PATH) ((uint8_t*)(PATH)->base.path + (PATH)->base.path_length)
#define PATH_LENGTH_INC(PATH, LENGTH) ((PATH)->base.path_length += (LENGTH))
/**********************
* TYPEDEFS
**********************/
@ -279,21 +282,39 @@ void lv_vg_lite_path_reserve_space(lv_vg_lite_path_t * path, size_t len)
LV_ASSERT_MALLOC(path->base.path);
}
void lv_vg_lite_path_append_data(lv_vg_lite_path_t * path, const void * data, size_t len)
static inline void lv_vg_lite_path_append_data(lv_vg_lite_path_t * path, const void * data, size_t len)
{
LV_ASSERT_NULL(path);
LV_ASSERT_NULL(data);
lv_vg_lite_path_reserve_space(path, len);
lv_memcpy((uint8_t *)path->base.path + path->base.path_length, data, len);
path->base.path_length += len;
lv_memcpy(PATH_CURRENT_PTR(path), data, len);
PATH_LENGTH_INC(path, len);
}
static void lv_vg_lite_path_append_op(lv_vg_lite_path_t * path, uint32_t op)
static inline void lv_vg_lite_path_append_op(lv_vg_lite_path_t * path, uint32_t op)
{
lv_vg_lite_path_append_data(path, &op, path->format_len);
void * ptr = PATH_CURRENT_PTR(path);
switch(path->base.format) {
case VG_LITE_FP32:
case VG_LITE_S32:
LV_VG_LITE_PATH_SET_OP_CODE(ptr, uint32_t, op);
PATH_LENGTH_INC(path, sizeof(uint32_t));
break;
case VG_LITE_S16:
LV_VG_LITE_PATH_SET_OP_CODE(ptr, uint16_t, op);
PATH_LENGTH_INC(path, sizeof(uint16_t));
break;
case VG_LITE_S8:
LV_VG_LITE_PATH_SET_OP_CODE(ptr, uint8_t, op);
PATH_LENGTH_INC(path, sizeof(uint8_t));
break;
default:
LV_ASSERT_FORMAT_MSG(false, "Invalid format: %d", path->base.format);
break;
}
}
static void lv_vg_lite_path_append_point(lv_vg_lite_path_t * path, float x, float y)
static inline void lv_vg_lite_path_append_point(lv_vg_lite_path_t * path, float x, float y)
{
if(path->has_transform) {
LV_VG_LITE_ASSERT_MATRIX(&path->matrix);
@ -304,22 +325,39 @@ static void lv_vg_lite_path_append_point(lv_vg_lite_path_t * path, float x, floa
y = ori_x * path->matrix.m[1][0] + ori_y * path->matrix.m[1][1] + path->matrix.m[1][2];
}
if(path->base.format == VG_LITE_FP32) {
lv_vg_lite_path_append_data(path, &x, sizeof(x));
lv_vg_lite_path_append_data(path, &y, sizeof(y));
return;
}
#define PATH_APPEND_POINT_DATA(X, Y, TYPE) \
do { \
TYPE * data = ptr; \
*data++ = (TYPE)(X); \
*data++ = (TYPE)(Y); \
PATH_LENGTH_INC(path, sizeof(TYPE) * 2); \
} while(0)
int32_t ix = (int32_t)(x);
int32_t iy = (int32_t)(y);
lv_vg_lite_path_append_data(path, &ix, path->format_len);
lv_vg_lite_path_append_data(path, &iy, path->format_len);
void * ptr = PATH_CURRENT_PTR(path);
switch(path->base.format) {
case VG_LITE_FP32:
PATH_APPEND_POINT_DATA(x, y, float);
break;
case VG_LITE_S32:
PATH_APPEND_POINT_DATA(x, y, int32_t);
break;
case VG_LITE_S16:
PATH_APPEND_POINT_DATA(x, y, int16_t);
break;
case VG_LITE_S8:
PATH_APPEND_POINT_DATA(x, y, int8_t);
break;
default:
LV_ASSERT_FORMAT_MSG(false, "Invalid format: %d", path->base.format);
break;
}
}
void lv_vg_lite_path_move_to(lv_vg_lite_path_t * path,
float x, float y)
{
LV_ASSERT_NULL(path);
lv_vg_lite_path_reserve_space(path, (1 + 2) * path->format_len);
lv_vg_lite_path_append_op(path, VLC_OP_MOVE);
lv_vg_lite_path_append_point(path, x, y);
}
@ -328,6 +366,7 @@ void lv_vg_lite_path_line_to(lv_vg_lite_path_t * path,
float x, float y)
{
LV_ASSERT_NULL(path);
lv_vg_lite_path_reserve_space(path, (1 + 2) * path->format_len);
lv_vg_lite_path_append_op(path, VLC_OP_LINE);
lv_vg_lite_path_append_point(path, x, y);
}
@ -337,6 +376,7 @@ void lv_vg_lite_path_quad_to(lv_vg_lite_path_t * path,
float x, float y)
{
LV_ASSERT_NULL(path);
lv_vg_lite_path_reserve_space(path, (1 + 4) * path->format_len);
lv_vg_lite_path_append_op(path, VLC_OP_QUAD);
lv_vg_lite_path_append_point(path, cx, cy);
lv_vg_lite_path_append_point(path, x, y);
@ -348,6 +388,7 @@ void lv_vg_lite_path_cubic_to(lv_vg_lite_path_t * path,
float x, float y)
{
LV_ASSERT_NULL(path);
lv_vg_lite_path_reserve_space(path, (1 + 6) * path->format_len);
lv_vg_lite_path_append_op(path, VLC_OP_CUBIC);
lv_vg_lite_path_append_point(path, cx1, cy1);
lv_vg_lite_path_append_point(path, cx2, cy2);
@ -357,12 +398,14 @@ void lv_vg_lite_path_cubic_to(lv_vg_lite_path_t * path,
void lv_vg_lite_path_close(lv_vg_lite_path_t * path)
{
LV_ASSERT_NULL(path);
lv_vg_lite_path_reserve_space(path, 1 * path->format_len);
lv_vg_lite_path_append_op(path, VLC_OP_CLOSE);
}
void lv_vg_lite_path_end(lv_vg_lite_path_t * path)
{
LV_ASSERT_NULL(path);
lv_vg_lite_path_reserve_space(path, 1 * path->format_len);
lv_vg_lite_path_append_op(path, VLC_OP_END);
path->base.add_end = 1;
}
@ -570,31 +613,29 @@ uint8_t lv_vg_lite_vlc_op_arg_len(uint8_t vlc_op)
VLC_OP_ARG_LEN(LCWARC, 5);
VLC_OP_ARG_LEN(LCWARC_REL, 5);
default:
LV_ASSERT_FORMAT_MSG(false, "Invalid op code: %d", vlc_op);
break;
}
LV_LOG_ERROR("UNKNOW_VLC_OP: 0x%x", vlc_op);
LV_ASSERT(false);
return 0;
}
uint8_t lv_vg_lite_path_format_len(vg_lite_format_t format)
{
switch(format) {
case VG_LITE_S8:
return 1;
case VG_LITE_S16:
return 2;
case VG_LITE_S32:
return 4;
case VG_LITE_FP32:
return 4;
return sizeof(float);
case VG_LITE_S32:
return sizeof(int32_t);
case VG_LITE_S16:
return sizeof(int16_t);
case VG_LITE_S8:
return sizeof(int8_t);
default:
LV_ASSERT_FORMAT_MSG(false, "Invalid format: %d", format);
break;
}
LV_LOG_ERROR("UNKNOW_FORMAT: %d", format);
LV_ASSERT(false);
return 0;
}
@ -610,7 +651,7 @@ void lv_vg_lite_path_for_each_data(const vg_lite_path_t * path, lv_vg_lite_path_
while(cur < end) {
/* get op code */
uint8_t op_code = VLC_GET_OP_CODE(cur);
uint8_t op_code = LV_VG_LITE_PATH_GET_OP_CODE(cur);
/* get arguments length */
uint8_t arg_len = lv_vg_lite_vlc_op_arg_len(op_code);
@ -634,8 +675,7 @@ void lv_vg_lite_path_for_each_data(const vg_lite_path_t * path, lv_vg_lite_path_
tmp_data[i] = *((float *)cur);
break;
default:
LV_LOG_ERROR("UNKNOW_FORMAT(%d)", path->format);
LV_ASSERT(false);
LV_ASSERT_FORMAT_MSG(false, "Invalid format: %d", path->format);
break;
}

View File

@ -22,15 +22,18 @@ extern "C" {
* DEFINES
*********************/
typedef struct _lv_vg_lite_path_t lv_vg_lite_path_t;
typedef struct _lv_draw_vg_lite_unit_t lv_draw_vg_lite_unit_t;
typedef void (*lv_vg_lite_path_iter_cb_t)(void * user_data, uint8_t op_code, const float * data, uint32_t len);
#define LV_VG_LITE_PATH_SET_OP_CODE(PTR, TYPE, OP_CODE) (*((TYPE*)PTR) = (OP_CODE))
#define LV_VG_LITE_PATH_GET_OP_CODE(PTR) (*((uint8_t*)PTR))
/**********************
* TYPEDEFS
**********************/
typedef struct _lv_vg_lite_path_t lv_vg_lite_path_t;
typedef struct _lv_draw_vg_lite_unit_t lv_draw_vg_lite_unit_t;
typedef void (*lv_vg_lite_path_iter_cb_t)(void * user_data, uint8_t op_code, const float * data, uint32_t len);
/**********************
* GLOBAL PROTOTYPES
**********************/
@ -69,8 +72,6 @@ vg_lite_path_t * lv_vg_lite_path_get_path(lv_vg_lite_path_t * path);
void lv_vg_lite_path_reserve_space(lv_vg_lite_path_t * path, size_t len);
void lv_vg_lite_path_append_data(lv_vg_lite_path_t * path, const void * data, size_t len);
void lv_vg_lite_path_move_to(lv_vg_lite_path_t * path,
float x, float y);

View File

@ -1052,7 +1052,7 @@ bool lv_vg_lite_path_check(const vg_lite_path_t * path)
while(cur < end) {
/* get op code */
uint8_t op_code = VLC_GET_OP_CODE(cur);
uint8_t op_code = LV_VG_LITE_PATH_GET_OP_CODE(cur);
/* get arguments length */
uint8_t arg_len = lv_vg_lite_vlc_op_arg_len(op_code);
@ -1076,7 +1076,7 @@ bool lv_vg_lite_path_check(const vg_lite_path_t * path)
case VG_LITE_DRAW_FILL_PATH:
case VG_LITE_DRAW_FILL_STROKE_PATH: {
/* Check end op code */
uint8_t end_op_code = VLC_GET_OP_CODE(end - fmt_len);
uint8_t end_op_code = LV_VG_LITE_PATH_GET_OP_CODE(end - fmt_len);
if(end_op_code != VLC_OP_END) {
LV_LOG_ERROR("%d (%s) -> is NOT VLC_OP_END", end_op_code, lv_vg_lite_vlc_op_string(end_op_code));
return false;

View File

@ -33,8 +33,6 @@ extern "C" {
#define LV_VG_LITE_IS_ERROR(err) (err > 0)
#define VLC_GET_OP_CODE(ptr) (*((uint8_t*)ptr))
#if LV_VG_LITE_USE_ASSERT
#define LV_VG_LITE_ASSERT(expr) LV_ASSERT(expr)
#else