1
0
mirror of https://github.com/lvgl/lvgl.git synced 2025-02-04 07:13: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; \ if((point)->y > max_y) max_y = (point)->y; \
} while(0) } while(0)
#define VLC_SET_OP_CODE(ptr, op) (*((uint32_t*)ptr) = (op))
#define COPY_POINT_NEXT() \ #define COPY_POINT_NEXT() \
do { \ do { \
CMP_BOUNDS(point); \ 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++) { for(uint32_t i = 0; i < op_size; i++) {
switch(ops[i]) { switch(ops[i]) {
case LV_VECTOR_PATH_OP_MOVE_TO: { 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(); COPY_POINT_NEXT();
} }
break; break;
case LV_VECTOR_PATH_OP_LINE_TO: { 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(); COPY_POINT_NEXT();
} }
break; break;
case LV_VECTOR_PATH_OP_QUAD_TO: { 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();
COPY_POINT_NEXT(); COPY_POINT_NEXT();
} }
break; break;
case LV_VECTOR_PATH_OP_CUBIC_TO: { 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(); COPY_POINT_NEXT();
COPY_POINT_NEXT(); COPY_POINT_NEXT();
} }
break; break;
case LV_VECTOR_PATH_OP_CLOSE: { 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; break;
default: default:

View File

@ -32,6 +32,9 @@
case VLC_OP_##OP: \ case VLC_OP_##OP: \
return (LEN) 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 * 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); 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(path);
LV_ASSERT_NULL(data); LV_ASSERT_NULL(data);
lv_vg_lite_path_reserve_space(path, len); lv_vg_lite_path_reserve_space(path, len);
lv_memcpy((uint8_t *)path->base.path + path->base.path_length, data, len); lv_memcpy(PATH_CURRENT_PTR(path), data, len);
path->base.path_length += 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) { if(path->has_transform) {
LV_VG_LITE_ASSERT_MATRIX(&path->matrix); 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]; 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) { #define PATH_APPEND_POINT_DATA(X, Y, TYPE) \
lv_vg_lite_path_append_data(path, &x, sizeof(x)); do { \
lv_vg_lite_path_append_data(path, &y, sizeof(y)); TYPE * data = ptr; \
return; *data++ = (TYPE)(X); \
} *data++ = (TYPE)(Y); \
PATH_LENGTH_INC(path, sizeof(TYPE) * 2); \
} while(0)
int32_t ix = (int32_t)(x); void * ptr = PATH_CURRENT_PTR(path);
int32_t iy = (int32_t)(y); switch(path->base.format) {
lv_vg_lite_path_append_data(path, &ix, path->format_len); case VG_LITE_FP32:
lv_vg_lite_path_append_data(path, &iy, path->format_len); 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, void lv_vg_lite_path_move_to(lv_vg_lite_path_t * path,
float x, float y) float x, float y)
{ {
LV_ASSERT_NULL(path); 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_op(path, VLC_OP_MOVE);
lv_vg_lite_path_append_point(path, x, y); 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) float x, float y)
{ {
LV_ASSERT_NULL(path); 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_op(path, VLC_OP_LINE);
lv_vg_lite_path_append_point(path, x, y); 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) float x, float y)
{ {
LV_ASSERT_NULL(path); 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_op(path, VLC_OP_QUAD);
lv_vg_lite_path_append_point(path, cx, cy); lv_vg_lite_path_append_point(path, cx, cy);
lv_vg_lite_path_append_point(path, x, y); 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) float x, float y)
{ {
LV_ASSERT_NULL(path); 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_op(path, VLC_OP_CUBIC);
lv_vg_lite_path_append_point(path, cx1, cy1); lv_vg_lite_path_append_point(path, cx1, cy1);
lv_vg_lite_path_append_point(path, cx2, cy2); 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) void lv_vg_lite_path_close(lv_vg_lite_path_t * path)
{ {
LV_ASSERT_NULL(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); lv_vg_lite_path_append_op(path, VLC_OP_CLOSE);
} }
void lv_vg_lite_path_end(lv_vg_lite_path_t * path) void lv_vg_lite_path_end(lv_vg_lite_path_t * path)
{ {
LV_ASSERT_NULL(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); lv_vg_lite_path_append_op(path, VLC_OP_END);
path->base.add_end = 1; 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, 5);
VLC_OP_ARG_LEN(LCWARC_REL, 5); VLC_OP_ARG_LEN(LCWARC_REL, 5);
default: default:
LV_ASSERT_FORMAT_MSG(false, "Invalid op code: %d", vlc_op);
break; break;
} }
LV_LOG_ERROR("UNKNOW_VLC_OP: 0x%x", vlc_op);
LV_ASSERT(false);
return 0; return 0;
} }
uint8_t lv_vg_lite_path_format_len(vg_lite_format_t format) uint8_t lv_vg_lite_path_format_len(vg_lite_format_t format)
{ {
switch(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: 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: default:
LV_ASSERT_FORMAT_MSG(false, "Invalid format: %d", format);
break; break;
} }
LV_LOG_ERROR("UNKNOW_FORMAT: %d", format);
LV_ASSERT(false);
return 0; 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) { while(cur < end) {
/* get op code */ /* 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 */ /* get arguments length */
uint8_t arg_len = lv_vg_lite_vlc_op_arg_len(op_code); 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); tmp_data[i] = *((float *)cur);
break; break;
default: default:
LV_LOG_ERROR("UNKNOW_FORMAT(%d)", path->format); LV_ASSERT_FORMAT_MSG(false, "Invalid format: %d", path->format);
LV_ASSERT(false);
break; break;
} }

View File

@ -22,15 +22,18 @@ extern "C" {
* DEFINES * DEFINES
*********************/ *********************/
typedef struct _lv_vg_lite_path_t lv_vg_lite_path_t; #define LV_VG_LITE_PATH_SET_OP_CODE(PTR, TYPE, OP_CODE) (*((TYPE*)PTR) = (OP_CODE))
typedef struct _lv_draw_vg_lite_unit_t lv_draw_vg_lite_unit_t; #define LV_VG_LITE_PATH_GET_OP_CODE(PTR) (*((uint8_t*)PTR))
typedef void (*lv_vg_lite_path_iter_cb_t)(void * user_data, uint8_t op_code, const float * data, uint32_t len);
/********************** /**********************
* TYPEDEFS * 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 * 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_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, void lv_vg_lite_path_move_to(lv_vg_lite_path_t * path,
float x, float y); 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) { while(cur < end) {
/* get op code */ /* 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 */ /* get arguments length */
uint8_t arg_len = lv_vg_lite_vlc_op_arg_len(op_code); 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_PATH:
case VG_LITE_DRAW_FILL_STROKE_PATH: { case VG_LITE_DRAW_FILL_STROKE_PATH: {
/* Check end op code */ /* 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) { 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)); LV_LOG_ERROR("%d (%s) -> is NOT VLC_OP_END", end_op_code, lv_vg_lite_vlc_op_string(end_op_code));
return false; return false;

View File

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