perf(layer): cache the layer_type

fixes #3334
This commit is contained in:
Gabor Kiss-Vamosi
2022-05-07 22:01:19 +02:00
parent e577b7a616
commit ac2e2f132e
9 changed files with 53 additions and 29 deletions

View File

@@ -35,7 +35,7 @@ void lv_example_style_15(void)
*The button and the label is rendered to a layer first and that layer is transformed*/
btn = lv_btn_create(lv_scr_act());
lv_obj_set_size(btn, 100, 40);
lv_obj_set_style_transform_angle(btn, 150, 0); /*150 deg*/
lv_obj_set_style_transform_angle(btn, 150, 0); /*15 deg*/
lv_obj_set_style_transform_zoom(btn, 256 + 64, 0); /*1.25x*/
lv_obj_set_style_transform_pivot_x(btn, 50, 0);
lv_obj_set_style_transform_pivot_y(btn, 20, 0);

View File

@@ -167,7 +167,8 @@ typedef struct {
lv_scroll_snap_t scroll_snap_x : 2; /**< Where to align the snappable children horizontally*/
lv_scroll_snap_t scroll_snap_y : 2; /**< Where to align the snappable children vertically*/
lv_dir_t scroll_dir : 4; /**< The allowed scroll direction(s)*/
uint8_t event_dsc_cnt; /**< Number of event callbacks stored in `event_dsc` array*/
uint8_t event_dsc_cnt : 6; /**< Number of event callbacks stored in `event_dsc` array*/
uint8_t layer_type : 2; /**< Cache the layer type here. Element of @lv_intermediate_layer_type_t */
} _lv_obj_spec_attr_t;
typedef struct _lv_obj_t {

View File

@@ -394,16 +394,11 @@ lv_coord_t _lv_obj_get_ext_draw_size(const lv_obj_t * obj)
else return 0;
}
lv_intermediate_layer_type_t _lv_obj_is_intermediate_layer(const lv_obj_t * obj)
lv_layer_type_t _lv_obj_get_layer_type(const lv_obj_t * obj)
{
if(lv_obj_get_style_transform_angle(obj, 0) != 0) return LV_INTERMEDIATE_LAYER_TYPE_TRANSFORM;
if(lv_obj_get_style_transform_zoom(obj, 0) != 256) return LV_INTERMEDIATE_LAYER_TYPE_TRANSFORM;
if(lv_obj_get_style_opa(obj, 0) != LV_OPA_COVER) return LV_INTERMEDIATE_LAYER_TYPE_SIMPLE;
#if LV_DRAW_COMPLEX
if(lv_obj_get_style_blend_mode(obj, 0) != LV_BLEND_MODE_NORMAL) return LV_INTERMEDIATE_LAYER_TYPE_SIMPLE;
#endif
return LV_INTERMEDIATE_LAYER_TYPE_NONE;
if(obj->spec_attr) return obj->spec_attr->layer_type;
else return LV_LAYER_TYPE_NONE;
}
/**********************

View File

@@ -34,10 +34,10 @@ typedef enum {
} lv_cover_res_t;
typedef enum {
LV_INTERMEDIATE_LAYER_TYPE_NONE,
LV_INTERMEDIATE_LAYER_TYPE_SIMPLE,
LV_INTERMEDIATE_LAYER_TYPE_TRANSFORM,
} lv_intermediate_layer_type_t;
LV_LAYER_TYPE_NONE,
LV_LAYER_TYPE_SIMPLE,
LV_LAYER_TYPE_TRANSFORM,
} lv_layer_type_t;
typedef struct {
lv_draw_ctx_t * draw_ctx; /**< Draw context*/
@@ -159,7 +159,7 @@ void lv_obj_refresh_ext_draw_size(struct _lv_obj_t * obj);
lv_coord_t _lv_obj_get_ext_draw_size(const struct _lv_obj_t * obj);
lv_intermediate_layer_type_t _lv_obj_is_intermediate_layer(const struct _lv_obj_t * obj);
lv_layer_type_t _lv_obj_get_layer_type(const struct _lv_obj_t * obj);
/**********************
* MACROS

View File

@@ -798,12 +798,14 @@ void lv_obj_move_children_by(lv_obj_t * obj, lv_coord_t x_diff, lv_coord_t y_dif
void lv_obj_transform_point(const lv_obj_t * obj, lv_point_t * p, bool recursive, bool inv)
{
if(obj) {
lv_layer_type_t layer_type = _lv_obj_get_layer_type(obj);
bool do_tranf = layer_type == LV_LAYER_TYPE_TRANSFORM;
if(inv) {
if(recursive) lv_obj_transform_point(lv_obj_get_parent(obj), p, recursive, inv);
transform_point(obj, p, inv);
if(do_tranf) transform_point(obj, p, inv);
}
else {
transform_point(obj, p, inv);
if(do_tranf) transform_point(obj, p, inv);
if(recursive) lv_obj_transform_point(lv_obj_get_parent(obj), p, recursive, inv);
}
}
@@ -818,6 +820,7 @@ void lv_obj_get_transformed_area(const lv_obj_t * obj, lv_area_t * area, bool re
{area->x2, area->y1},
{area->x2, area->y2},
};
lv_obj_transform_point(obj, &p[0], recursive, inv);
lv_obj_transform_point(obj, &p[1], recursive, inv);
lv_obj_transform_point(obj, &p[2], recursive, inv);

View File

@@ -51,6 +51,7 @@ static bool trans_del(lv_obj_t * obj, lv_part_t part, lv_style_prop_t prop, tran
static void trans_anim_cb(void * _tr, int32_t v);
static void trans_anim_start_cb(lv_anim_t * a);
static void trans_anim_ready_cb(lv_anim_t * a);
static lv_layer_type_t calculate_layer_type(lv_obj_t * obj);
static void fade_anim_cb(void * obj, int32_t v);
static void fade_in_anim_ready(lv_anim_t * a);
@@ -176,6 +177,7 @@ void lv_obj_refresh_style(lv_obj_t * obj, lv_style_selector_t selector, lv_style
bool is_layout_refr = lv_style_prop_has_flag(prop, LV_STYLE_PROP_LAYOUT_REFR);
bool is_ext_draw = lv_style_prop_has_flag(prop, LV_STYLE_PROP_EXT_DRAW);
bool is_inherit = lv_style_prop_has_flag(prop, LV_STYLE_PROP_INHERIT);
bool is_layer_refr = lv_style_prop_has_flag(prop, LV_STYLE_PROP_LAYER_REFR);
if(is_layout_refr) {
if(part == LV_PART_ANY ||
@@ -191,6 +193,16 @@ void lv_obj_refresh_style(lv_obj_t * obj, lv_style_selector_t selector, lv_style
if(parent) lv_obj_mark_layout_as_dirty(parent);
}
/*Cache the layer type*/
if((part == LV_PART_ANY || part == LV_PART_MAIN) && is_layer_refr) {
lv_layer_type_t layer_type = calculate_layer_type(obj);
if(obj->spec_attr) obj->spec_attr->layer_type = layer_type;
else if(layer_type != LV_LAYER_TYPE_NONE) {
lv_obj_allocate_spec_attr(obj);
obj->spec_attr->layer_type = layer_type;
}
}
if(prop == LV_STYLE_PROP_ANY || is_ext_draw) {
lv_obj_refresh_ext_draw_size(obj);
}
@@ -810,6 +822,18 @@ static void trans_anim_ready_cb(lv_anim_t * a)
}
}
static lv_layer_type_t calculate_layer_type(lv_obj_t * obj)
{
if(lv_obj_get_style_transform_angle(obj, 0) != 0) return LV_LAYER_TYPE_TRANSFORM;
if(lv_obj_get_style_transform_zoom(obj, 0) != 256) return LV_LAYER_TYPE_TRANSFORM;
if(lv_obj_get_style_opa(obj, 0) != LV_OPA_COVER) return LV_LAYER_TYPE_SIMPLE;
#if LV_DRAW_COMPLEX
if(lv_obj_get_style_blend_mode(obj, 0) != LV_BLEND_MODE_NORMAL) return LV_LAYER_TYPE_SIMPLE;
#endif
return LV_LAYER_TYPE_NONE;
}
static void fade_anim_cb(void * obj, int32_t v)
{
lv_obj_set_style_opa(obj, v, 0);

View File

@@ -731,7 +731,7 @@ static lv_obj_t * lv_refr_get_top_obj(const lv_area_t * area_p, lv_obj_t * obj)
if(_lv_area_is_in(area_p, &obj->coords, 0) == false) return NULL;
if(lv_obj_has_flag(obj, LV_OBJ_FLAG_HIDDEN)) return NULL;
if(_lv_obj_is_intermediate_layer(obj)) return NULL;
if(_lv_obj_get_layer_type(obj)) return NULL;
/*If this object is fully cover the draw area then check the children too*/
lv_cover_check_info_t info;
@@ -815,8 +815,8 @@ void refr_obj(lv_draw_ctx_t * draw_ctx, lv_obj_t * obj)
{
/*Do not refresh hidden objects*/
if(lv_obj_has_flag(obj, LV_OBJ_FLAG_HIDDEN)) return;
lv_intermediate_layer_type_t inlayer = _lv_obj_is_intermediate_layer(obj);
if(inlayer == LV_INTERMEDIATE_LAYER_TYPE_NONE) {
lv_layer_type_t inlayer = _lv_obj_get_layer_type(obj);
if(inlayer == LV_LAYER_TYPE_NONE) {
lv_obj_redraw(draw_ctx, obj);
}
else {
@@ -831,7 +831,7 @@ void refr_obj(lv_draw_ctx_t * draw_ctx, lv_obj_t * obj)
lv_area_increase(&obj_coords_ext, ext_draw_size, ext_draw_size);
uint32_t buf_size_sub;
if(inlayer == LV_INTERMEDIATE_LAYER_TYPE_TRANSFORM) {
if(inlayer == LV_LAYER_TYPE_TRANSFORM) {
lv_area_t clip_coords_for_obj;
lv_area_t tranf_coords = obj_coords_ext;
lv_obj_get_transformed_area(obj, &tranf_coords, false, false);
@@ -847,7 +847,7 @@ void refr_obj(lv_draw_ctx_t * draw_ctx, lv_obj_t * obj)
draw_area = inverse_clip_coords_for_obj;
}
else if(inlayer == LV_INTERMEDIATE_LAYER_TYPE_SIMPLE) {
else if(inlayer == LV_LAYER_TYPE_SIMPLE) {
lv_area_t clip_coords_for_obj;
if(!_lv_area_intersect(&clip_coords_for_obj, clip_area_ori, &obj_coords_ext)) {
return;
@@ -875,7 +875,7 @@ void refr_obj(lv_draw_ctx_t * draw_ctx, lv_obj_t * obj)
uint32_t px_size = full_cover ? sizeof(lv_color_t) : LV_IMG_PX_SIZE_ALPHA_BYTE;
if(inlayer == LV_INTERMEDIATE_LAYER_TYPE_SIMPLE) {
if(inlayer == LV_LAYER_TYPE_SIMPLE) {
buf_size_sub = LV_LAYER_SIMPLE_BUF_SIZE;
}
else {
@@ -887,7 +887,7 @@ void refr_obj(lv_draw_ctx_t * draw_ctx, lv_obj_t * obj)
uint8_t * layer_buf = lv_mem_alloc(buf_size_sub);
/*Try again with a smaller buf size*/
if(inlayer == LV_INTERMEDIATE_LAYER_TYPE_SIMPLE) {
if(inlayer == LV_LAYER_TYPE_SIMPLE) {
if(layer_buf == NULL) {
LV_LOG_WARN("Cannot allocate %"LV_PRIu32" bytes for layer buffer. Allocating %"LV_PRIu32" bytes instead. (Reduced performance)",
(uint32_t)buf_size_sub * px_size, (uint32_t)LV_LAYER_SIMPLE_FALLBACK_BUF_SIZE * px_size);

View File

@@ -40,8 +40,8 @@ const uint8_t _lv_style_builtin_prop_flag_lookup_table[_LV_STYLE_NUM_BUILT_IN_PR
[LV_STYLE_TRANSFORM_HEIGHT] = LV_STYLE_PROP_EXT_DRAW,
[LV_STYLE_TRANSLATE_X] = LV_STYLE_PROP_LAYOUT_REFR | LV_STYLE_PROP_PARENT_LAYOUT_REFR,
[LV_STYLE_TRANSLATE_Y] = LV_STYLE_PROP_LAYOUT_REFR | LV_STYLE_PROP_PARENT_LAYOUT_REFR,
[LV_STYLE_TRANSFORM_ZOOM] = LV_STYLE_PROP_EXT_DRAW | LV_STYLE_PROP_LAYOUT_REFR | LV_STYLE_PROP_PARENT_LAYOUT_REFR,
[LV_STYLE_TRANSFORM_ANGLE] = LV_STYLE_PROP_EXT_DRAW | LV_STYLE_PROP_LAYOUT_REFR | LV_STYLE_PROP_PARENT_LAYOUT_REFR,
[LV_STYLE_TRANSFORM_ZOOM] = LV_STYLE_PROP_EXT_DRAW | LV_STYLE_PROP_LAYER_REFR,
[LV_STYLE_TRANSFORM_ANGLE] = LV_STYLE_PROP_EXT_DRAW | LV_STYLE_PROP_LAYER_REFR,
[LV_STYLE_PAD_TOP] = LV_STYLE_PROP_EXT_DRAW | LV_STYLE_PROP_LAYOUT_REFR,
[LV_STYLE_PAD_BOTTOM] = LV_STYLE_PROP_EXT_DRAW | LV_STYLE_PROP_LAYOUT_REFR,
@@ -110,13 +110,13 @@ const uint8_t _lv_style_builtin_prop_flag_lookup_table[_LV_STYLE_NUM_BUILT_IN_PR
[LV_STYLE_RADIUS] = 0,
[LV_STYLE_CLIP_CORNER] = 0,
[LV_STYLE_OPA] = 0,
[LV_STYLE_OPA] = LV_STYLE_PROP_LAYER_REFR,
[LV_STYLE_COLOR_FILTER_DSC] = LV_STYLE_PROP_INHERIT,
[LV_STYLE_COLOR_FILTER_OPA] = LV_STYLE_PROP_INHERIT,
[LV_STYLE_ANIM_TIME] = 0,
[LV_STYLE_ANIM_SPEED] = 0,
[LV_STYLE_TRANSITION] = 0,
[LV_STYLE_BLEND_MODE] = 0,
[LV_STYLE_BLEND_MODE] = LV_STYLE_PROP_LAYER_REFR,
[LV_STYLE_LAYOUT] = LV_STYLE_PROP_LAYOUT_REFR,
[LV_STYLE_BASE_DIR] = LV_STYLE_PROP_INHERIT | LV_STYLE_PROP_LAYOUT_REFR,
};

View File

@@ -40,7 +40,8 @@ extern "C" {
#define LV_STYLE_PROP_EXT_DRAW (1 << 1) /*Requires ext. draw size update when changed*/
#define LV_STYLE_PROP_LAYOUT_REFR (1 << 2) /*Requires layout update when changed*/
#define LV_STYLE_PROP_PARENT_LAYOUT_REFR (1 << 3) /*Requires layout update on parent when changed*/
#define LV_STYLE_PROP_ALL (0xf) /*Indicating all flags*/
#define LV_STYLE_PROP_LAYER_REFR (1 << 4) /*Affects layer handling*/
#define LV_STYLE_PROP_ALL (0x1F) /*Indicating all flags*/
/**
* Other constants