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:
parent
bd39f984b8
commit
f378299370
@ -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:
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user