diff --git a/env_support/cmsis-pack/lv_conf_cmsis.h b/env_support/cmsis-pack/lv_conf_cmsis.h index a2602c19b5..1282b8f6a1 100644 --- a/env_support/cmsis-pack/lv_conf_cmsis.h +++ b/env_support/cmsis-pack/lv_conf_cmsis.h @@ -300,7 +300,7 @@ /* Adjust color mix functions rounding. GPUs might calculate color mix (blending) differently. * 0: round down, 64: round up from x.75, 128: round up from half, 192: round up from x.25, 254: round up */ -#define lv_color_mix_ROUND_OFS 0 +#define LV_COLOR_MIX_ROUND_OFS 0 /*===================== * COMPILER SETTINGS diff --git a/lv_conf_template.h b/lv_conf_template.h index 61fb0fc740..c4fb695d65 100644 --- a/lv_conf_template.h +++ b/lv_conf_template.h @@ -269,7 +269,11 @@ /* Adjust color mix functions rounding. GPUs might calculate color mix (blending) differently. * 0: round down, 64: round up from x.75, 128: round up from half, 192: round up from x.25, 254: round up */ -#define lv_color_mix_ROUND_OFS 0 +#define LV_COLOR_MIX_ROUND_OFS 0 + + +/* Add 2 x 32 bit variables to each lv_obj_t to speed up getting style properties */ +#define LV_OBJ_STYLE_CACHE 1 /*===================== * COMPILER SETTINGS diff --git a/src/core/lv_obj.h b/src/core/lv_obj.h index 26a5887784..3a63d1fb78 100644 --- a/src/core/lv_obj.h +++ b/src/core/lv_obj.h @@ -176,6 +176,10 @@ typedef struct _lv_obj_t { struct _lv_obj_t * parent; _lv_obj_spec_attr_t * spec_attr; _lv_obj_style_t * styles; +#if LV_OBJ_STYLE_CACHE + uint32_t style_main_prop_is_set; + uint32_t style_other_prop_is_set; +#endif void * user_data; lv_area_t coords; lv_obj_flag_t flags; diff --git a/src/core/lv_obj_style.c b/src/core/lv_obj_style.c index 15cf79b585..9780383a3d 100644 --- a/src/core/lv_obj_style.c +++ b/src/core/lv_obj_style.c @@ -55,8 +55,10 @@ 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 full_cache_refresh(lv_obj_t * obj, lv_part_t part); static void fade_anim_cb(void * obj, int32_t v); static void fade_in_anim_ready(lv_anim_t * a); +static bool style_has_flag(const lv_style_t * style, uint32_t flag); /********************** * STATIC VARIABLES @@ -82,8 +84,11 @@ void lv_obj_add_style(lv_obj_t * obj, const lv_style_t * style, lv_style_selecto trans_del(obj, selector, LV_STYLE_PROP_ANY, NULL); - if(style && selector == LV_PART_MAIN && lv_style_prop_has_flag(style->prop1, LV_STYLE_PROP_FLAG_TRANSFORM)) + lv_part_t part = lv_obj_style_get_selector_part(selector); + + if(style && part == LV_PART_MAIN && style_has_flag(style, LV_STYLE_PROP_FLAG_TRANSFORM)) { lv_obj_invalidate(obj); + } /*Try removing the style first to be sure it won't be added twice*/ lv_obj_remove_style(obj, style, selector); @@ -113,6 +118,23 @@ void lv_obj_add_style(lv_obj_t * obj, const lv_style_t * style, lv_style_selecto obj->styles[i].style = style; obj->styles[i].selector = selector; + +#if LV_OBJ_STYLE_CACHE + uint32_t * prop_is_set = part == LV_PART_MAIN ? &obj->style_main_prop_is_set : &obj->style_other_prop_is_set; + if(style->prop_cnt == 255) { + lv_style_const_prop_t * props = style->values_and_props; + for(i = 0; props[i].prop_ptr; i++) { + (*prop_is_set) |= (uint32_t)1 << ((*props[i].prop_ptr) >> 2); + } + } + else { + lv_style_prop_t * props = (lv_style_prop_t *)style->values_and_props + style->prop_cnt * sizeof(lv_style_value_t); + for(i = 0; i < style->prop_cnt; i++) { + (*prop_is_set) |= (uint32_t)1 << (props[i] >> 2); + } + } +#endif + lv_obj_refresh_style(obj, selector, LV_STYLE_PROP_ANY); } @@ -156,6 +178,7 @@ bool lv_obj_replace_style(struct _lv_obj_t * obj, const lv_style_t * old_style, /*Don't break and continue replacing other occurrences*/ } if(replaced) { + full_cache_refresh(obj, part); lv_obj_refresh_style(obj, part, LV_STYLE_PROP_ANY); } return replaced; @@ -168,8 +191,9 @@ void lv_obj_remove_style(lv_obj_t * obj, const lv_style_t * style, lv_style_sele lv_style_prop_t prop = LV_STYLE_PROP_ANY; if(style && style->prop_cnt == 0) prop = LV_STYLE_PROP_INV; - if(style && selector == LV_PART_MAIN && lv_style_prop_has_flag(style->prop1, LV_STYLE_PROP_FLAG_TRANSFORM)) + if(style && part == LV_PART_MAIN && style_has_flag(style, LV_STYLE_PROP_FLAG_TRANSFORM)) { lv_obj_invalidate(obj); + } uint32_t i = 0; bool deleted = false; @@ -206,7 +230,9 @@ void lv_obj_remove_style(lv_obj_t * obj, const lv_style_t * style, lv_style_sele /*The style from the current `i` index is removed, so `i` points to the next style. *Therefore it doesn't needs to be incremented*/ } + if(deleted && prop != LV_STYLE_PROP_INV) { + full_cache_refresh(obj, part); lv_obj_refresh_style(obj, part, prop); } } @@ -286,70 +312,157 @@ void lv_obj_enable_style_refresh(bool en) style_refr = en; } + +static inline lv_style_value_t lv_style_prop_get_default_inlined(lv_style_prop_t prop) +{ + const lv_color_t black = LV_COLOR_MAKE(0x00, 0x00, 0x00); + const lv_color_t white = LV_COLOR_MAKE(0xff, 0xff, 0xff); + switch(prop) { + case LV_STYLE_TRANSFORM_ZOOM: + return (lv_style_value_t) { + .num = LV_ZOOM_NONE + }; + case LV_STYLE_BG_COLOR: + return (lv_style_value_t) { + .color = black + }; + case LV_STYLE_BG_GRAD_COLOR: + case LV_STYLE_BORDER_COLOR: + case LV_STYLE_SHADOW_COLOR: + case LV_STYLE_OUTLINE_COLOR: + case LV_STYLE_ARC_COLOR: + case LV_STYLE_LINE_COLOR: + case LV_STYLE_TEXT_COLOR: + case LV_STYLE_IMG_RECOLOR: + return (lv_style_value_t) { + .color = white + }; + case LV_STYLE_OPA: + case LV_STYLE_OPA_LAYERED: + case LV_STYLE_BORDER_OPA: + case LV_STYLE_TEXT_OPA: + case LV_STYLE_IMG_OPA: + case LV_STYLE_BG_IMG_OPA: + case LV_STYLE_OUTLINE_OPA: + case LV_STYLE_SHADOW_OPA: + case LV_STYLE_LINE_OPA: + case LV_STYLE_ARC_OPA: + return (lv_style_value_t) { + .num = LV_OPA_COVER + }; + case LV_STYLE_BG_GRAD_STOP: + return (lv_style_value_t) { + .num = 255 + }; + case LV_STYLE_BORDER_SIDE: + return (lv_style_value_t) { + .num = LV_BORDER_SIDE_FULL + }; + case LV_STYLE_TEXT_FONT: + return (lv_style_value_t) { + .ptr = LV_FONT_DEFAULT + }; + case LV_STYLE_MAX_WIDTH: + case LV_STYLE_MAX_HEIGHT: + return (lv_style_value_t) { + .num = LV_COORD_MAX + }; + default: + return (lv_style_value_t) { + .ptr = 0 + }; + } +} + + lv_style_value_t lv_obj_get_style_prop(const lv_obj_t * obj, lv_part_t part, lv_style_prop_t prop) { LV_ASSERT_NULL(obj) lv_style_value_t value_act = { .ptr = NULL }; - bool inheritable = lv_style_prop_has_flag(prop, LV_STYLE_PROP_FLAG_INHERITABLE); - lv_style_res_t found = LV_STYLE_RES_NOT_FOUND; - while(obj) { + lv_style_res_t found; + + /*The happy path*/ +#if LV_OBJ_STYLE_CACHE + const uint32_t prop_shifted = (uint32_t)1 << (prop >> 2); + if((part == LV_PART_MAIN ? obj->style_main_prop_is_set : obj->style_other_prop_is_set) & prop_shifted) +#endif + { found = get_prop_core(obj, part, prop, &value_act); - if(found == LV_STYLE_RES_FOUND) break; - if(!inheritable) break; - - /*If not found, check the `MAIN` style first*/ - if(found != LV_STYLE_RES_INHERIT && part != LV_PART_MAIN) { - part = LV_PART_MAIN; - continue; - } - - /*Check the parent too.*/ - obj = lv_obj_get_parent(obj); + if(found == LV_STYLE_RES_FOUND) return value_act; } - if(found != LV_STYLE_RES_FOUND) { + extern const uint8_t _lv_style_builtin_prop_flag_lookup_table[]; + bool inheritable; + if(prop < _LV_STYLE_NUM_BUILT_IN_PROPS) { + inheritable = _lv_style_builtin_prop_flag_lookup_table[prop] & LV_STYLE_PROP_FLAG_INHERITABLE; + } + else { + inheritable = LV_GC_ROOT(_lv_style_custom_prop_flag_lookup_table)[prop - _LV_STYLE_NUM_BUILT_IN_PROPS] & + LV_STYLE_PROP_FLAG_INHERITABLE; + } + + if(inheritable) { + /*If not found, check the `MAIN` style first, if already on the MAIN part go to the parent*/ + if(part != LV_PART_MAIN) part = LV_PART_MAIN; + else obj = obj->parent; + + while(obj) { +#if LV_OBJ_STYLE_CACHE + if(obj->style_main_prop_is_set & prop_shifted) +#endif + { + found = get_prop_core(obj, part, prop, &value_act); + if(found == LV_STYLE_RES_FOUND) return value_act; + } + /*Check the parent too.*/ + obj = obj->parent; + } + } + else { + /*Get the width and height from the class. + * WIDTH and HEIGHT are not inherited so add them in the `else` to skip checking them for inherited proeprties */ if(part == LV_PART_MAIN && (prop == LV_STYLE_WIDTH || prop == LV_STYLE_HEIGHT)) { const lv_obj_class_t * cls = obj->class_p; while(cls) { if(prop == LV_STYLE_WIDTH) { - if(cls->width_def != 0) break; + if(cls->width_def != 0) return (lv_style_value_t) { + .num = cls->width_def + }; } else { - if(cls->height_def != 0) break; + if(cls->height_def != 0) return (lv_style_value_t) { + .num = cls->height_def + }; } cls = cls->base_class; } - - if(cls) { - value_act.num = prop == LV_STYLE_WIDTH ? cls->width_def : cls->height_def; - } - else { - value_act.num = 0; - } - } - else { - value_act = lv_style_prop_get_default(prop); } } - return value_act; + + return lv_style_prop_get_default_inlined(prop); } void lv_obj_set_local_style_prop(lv_obj_t * obj, lv_style_prop_t prop, lv_style_value_t value, lv_style_selector_t selector) { lv_style_t * style = get_local_style(obj, selector); - if(selector == LV_PART_MAIN && lv_style_prop_has_flag(prop, LV_STYLE_PROP_FLAG_TRANSFORM)) + if(selector == LV_PART_MAIN && lv_style_prop_has_flag(prop, LV_STYLE_PROP_FLAG_TRANSFORM)) { lv_obj_invalidate(obj); - lv_style_set_prop(style, prop, value); - lv_obj_refresh_style(obj, selector, prop); -} + } + + lv_style_set_prop(style, prop, value); + +#if LV_OBJ_STYLE_CACHE + if(lv_obj_style_get_selector_part(selector) == LV_PART_MAIN) { + obj->style_main_prop_is_set |= (uint32_t)1 << (prop >> 2); + } + else { + obj->style_other_prop_is_set |= (uint32_t)1 << (prop >> 2); + } +#endif + -void lv_obj_set_local_style_prop_meta(lv_obj_t * obj, lv_style_prop_t prop, uint16_t meta, - lv_style_selector_t selector) -{ - lv_style_t * style = get_local_style(obj, selector); - lv_style_set_prop_meta(style, prop, meta); lv_obj_refresh_style(obj, selector, prop); } @@ -385,6 +498,7 @@ bool lv_obj_remove_local_style_prop(lv_obj_t * obj, lv_style_prop_t prop, lv_sty lv_res_t res = lv_style_remove_prop((lv_style_t *)obj->styles[i].style, prop); if(res == LV_RES_OK) { + full_cache_refresh(obj, lv_obj_style_get_selector_part(selector)); lv_obj_refresh_style(obj, selector, prop); } @@ -544,16 +658,6 @@ void lv_obj_fade_out(lv_obj_t * obj, uint32_t time, uint32_t delay) lv_anim_start(&a); } -lv_state_t lv_obj_style_get_selector_state(lv_style_selector_t selector) -{ - return selector & 0xFFFF; -} - -lv_part_t lv_obj_style_get_selector_part(lv_style_selector_t selector) -{ - return selector & 0xFF0000; -} - lv_text_align_t lv_obj_calculate_style_text_align(const struct _lv_obj_t * obj, lv_part_t part, const char * txt) { @@ -677,14 +781,14 @@ static _lv_obj_style_t * get_trans_style(lv_obj_t * obj, lv_style_selector_t se static lv_style_res_t get_prop_core(const lv_obj_t * obj, lv_part_t part, lv_style_prop_t prop, lv_style_value_t * v) { - uint8_t group = 1 << _lv_style_get_prop_group(prop); + + const uint32_t group = (uint32_t)1 << _lv_style_get_prop_group(prop); + const lv_state_t state = obj->state; + const lv_state_t state_inv = ~state; + const bool skip_trans = obj->skip_trans; int32_t weight = -1; - lv_state_t state = obj->state; - lv_state_t state_inv = ~state; - lv_style_value_t value_tmp; - bool skip_trans = obj->skip_trans; - uint32_t i; lv_style_res_t found; + uint32_t i; for(i = 0; i < obj->style_cnt; i++) { _lv_obj_style_t * obj_style = &obj->styles[i]; if(obj_style->is_trans == false) break; @@ -694,51 +798,36 @@ static lv_style_res_t get_prop_core(const lv_obj_t * obj, lv_part_t part, lv_sty if(part_act != part) continue; if((obj_style->style->has_group & group) == 0) continue; - found = lv_style_get_prop(obj_style->style, prop, &value_tmp); + found = lv_style_get_prop_inlined(obj_style->style, prop, v); if(found == LV_STYLE_RES_FOUND) { - *v = value_tmp; return LV_STYLE_RES_FOUND; } - else if(found == LV_STYLE_RES_INHERIT) { - return LV_STYLE_RES_INHERIT; - } } for(; i < obj->style_cnt; i++) { if((obj->styles[i].style->has_group & group) == 0) continue; _lv_obj_style_t * obj_style = &obj->styles[i]; lv_part_t part_act = lv_obj_style_get_selector_part(obj->styles[i].selector); - lv_state_t state_act = lv_obj_style_get_selector_state(obj->styles[i].selector); if(part_act != part) continue; /*Be sure the style not specifies other state than the requested. *E.g. For HOVER+PRESS object state, HOVER style only is OK, but HOVER+FOCUS style is not*/ + lv_state_t state_act = lv_obj_style_get_selector_state(obj->styles[i].selector); if((state_act & state_inv)) continue; /*Check only better candidates*/ if(state_act <= weight) continue; - found = lv_style_get_prop(obj_style->style, prop, &value_tmp); - + found = lv_style_get_prop_inlined(obj_style->style, prop, v); if(found == LV_STYLE_RES_FOUND) { if(state_act == state) { - *v = value_tmp; return LV_STYLE_RES_FOUND; } - if(weight < state_act) { - weight = state_act; - *v = value_tmp; - } - } - else if(found == LV_STYLE_RES_INHERIT) { - return LV_STYLE_RES_INHERIT; + weight = state_act; } } - if(weight >= 0) { - *v = value_tmp; - return LV_STYLE_RES_FOUND; - } + if(weight >= 0) return LV_STYLE_RES_FOUND; else return LV_STYLE_RES_NOT_FOUND; } @@ -958,6 +1047,57 @@ static lv_layer_type_t calculate_layer_type(lv_obj_t * obj) return LV_LAYER_TYPE_NONE; } + +static void full_cache_refresh(lv_obj_t * obj, lv_part_t part) +{ +#if LV_OBJ_STYLE_CACHE + uint32_t i; + if(part == LV_PART_MAIN || part == LV_PART_ANY) { + obj->style_main_prop_is_set = 0; + for(i = 0; i < obj->style_cnt; i++) { + if(lv_obj_style_get_selector_part(obj->styles[i].selector) != LV_PART_MAIN) continue; + lv_style_t * style = (lv_style_t *)obj->styles[i].style; + uint32_t j; + if(style->prop_cnt == 255) { + lv_style_const_prop_t * props = style->values_and_props; + for(j = 0; props[j].prop_ptr; j++) { + obj->style_main_prop_is_set |= (uint32_t)1 << ((*props[j].prop_ptr) >> 2); + } + } + else { + lv_style_prop_t * props = (lv_style_prop_t *)style->values_and_props + style->prop_cnt * sizeof(lv_style_value_t); + for(j = 0; j < style->prop_cnt; j++) { + obj->style_main_prop_is_set |= (uint32_t)1 << (props[j] >> 2); + } + } + } + } + if(part != LV_PART_MAIN || part == LV_PART_ANY) { + obj->style_other_prop_is_set = 0; + for(i = 0; i < obj->style_cnt; i++) { + if(lv_obj_style_get_selector_part(obj->styles[i].selector) == LV_PART_MAIN) continue; + lv_style_t * style = (lv_style_t *)obj->styles[i].style; + uint32_t j; + if(style->prop_cnt == 255) { + lv_style_const_prop_t * props = style->values_and_props; + for(j = 0; props[j].prop_ptr; j++) { + obj->style_other_prop_is_set |= (uint32_t)1 << ((*props[j].prop_ptr) >> 2); + } + } + else { + lv_style_prop_t * props = (lv_style_prop_t *)style->values_and_props + style->prop_cnt * sizeof(lv_style_value_t); + for(j = 0; j < style->prop_cnt; j++) { + obj->style_other_prop_is_set |= (uint32_t)1 << (props[j] >> 2); + } + } + } + } +#else + LV_UNUSED(obj); + LV_UNUSED(part); +#endif +} + static void fade_anim_cb(void * obj, int32_t v) { lv_obj_set_style_opa(obj, v, 0); @@ -968,3 +1108,25 @@ static void fade_in_anim_ready(lv_anim_t * a) lv_obj_remove_local_style_prop(a->var, LV_STYLE_OPA, 0); } +static bool style_has_flag(const lv_style_t * style, uint32_t flag) +{ + if(style->prop_cnt == 255) { + lv_style_const_prop_t * props = style->values_and_props; + uint32_t i; + for(i = 0; props[i].prop_ptr; i++) { + if(lv_style_prop_has_flag(*props[i].prop_ptr, flag)) { + return true; + } + } + } + else { + lv_style_prop_t * props = (lv_style_prop_t *)style->values_and_props + style->prop_cnt * sizeof(lv_style_value_t); + uint32_t i; + for(i = 0; i < style->prop_cnt; i++) { + if(lv_style_prop_has_flag(props[i], flag)) { + return true; + } + } + } + return false; +} diff --git a/src/core/lv_obj_style.h b/src/core/lv_obj_style.h index 532c47ee92..7062819b48 100644 --- a/src/core/lv_obj_style.h +++ b/src/core/lv_obj_style.h @@ -160,9 +160,6 @@ lv_style_value_t lv_obj_get_style_prop(const struct _lv_obj_t * obj, lv_part_t p void lv_obj_set_local_style_prop(struct _lv_obj_t * obj, lv_style_prop_t prop, lv_style_value_t value, lv_style_selector_t selector); -void lv_obj_set_local_style_prop_meta(struct _lv_obj_t * obj, lv_style_prop_t prop, uint16_t meta, - lv_style_selector_t selector); - lv_style_res_t lv_obj_get_local_style_prop(struct _lv_obj_t * obj, lv_style_prop_t prop, lv_style_value_t * value, lv_style_selector_t selector); @@ -216,9 +213,16 @@ void lv_obj_fade_in(struct _lv_obj_t * obj, uint32_t time, uint32_t delay); */ void lv_obj_fade_out(struct _lv_obj_t * obj, uint32_t time, uint32_t delay); -lv_state_t lv_obj_style_get_selector_state(lv_style_selector_t selector); -lv_part_t lv_obj_style_get_selector_part(lv_style_selector_t selector); +static inline lv_state_t lv_obj_style_get_selector_state(lv_style_selector_t selector) +{ + return selector & 0xFFFF; +} + +static inline lv_part_t lv_obj_style_get_selector_part(lv_style_selector_t selector) +{ + return selector & 0xFF0000; +} #include "lv_obj_style_gen.h" diff --git a/src/core/lv_obj_style_gen.h b/src/core/lv_obj_style_gen.h index 012c0a8cea..121a87c0e3 100644 --- a/src/core/lv_obj_style_gen.h +++ b/src/core/lv_obj_style_gen.h @@ -189,7 +189,8 @@ static inline lv_color_t lv_obj_get_style_bg_grad_color(const struct _lv_obj_t * static inline lv_color_t lv_obj_get_style_bg_grad_color_filtered(const struct _lv_obj_t * obj, uint32_t part) { - lv_style_value_t v = _lv_obj_style_apply_color_filter(obj, part, lv_obj_get_style_prop(obj, part, LV_STYLE_BG_GRAD_COLOR)); + lv_style_value_t v = _lv_obj_style_apply_color_filter(obj, part, lv_obj_get_style_prop(obj, part, + LV_STYLE_BG_GRAD_COLOR)); return v.color; } @@ -243,7 +244,8 @@ static inline lv_color_t lv_obj_get_style_bg_img_recolor(const struct _lv_obj_t static inline lv_color_t lv_obj_get_style_bg_img_recolor_filtered(const struct _lv_obj_t * obj, uint32_t part) { - lv_style_value_t v = _lv_obj_style_apply_color_filter(obj, part, lv_obj_get_style_prop(obj, part, LV_STYLE_BG_IMG_RECOLOR)); + lv_style_value_t v = _lv_obj_style_apply_color_filter(obj, part, lv_obj_get_style_prop(obj, part, + LV_STYLE_BG_IMG_RECOLOR)); return v.color; } @@ -267,7 +269,8 @@ static inline lv_color_t lv_obj_get_style_border_color(const struct _lv_obj_t * static inline lv_color_t lv_obj_get_style_border_color_filtered(const struct _lv_obj_t * obj, uint32_t part) { - lv_style_value_t v = _lv_obj_style_apply_color_filter(obj, part, lv_obj_get_style_prop(obj, part, LV_STYLE_BORDER_COLOR)); + lv_style_value_t v = _lv_obj_style_apply_color_filter(obj, part, lv_obj_get_style_prop(obj, part, + LV_STYLE_BORDER_COLOR)); return v.color; } @@ -309,7 +312,8 @@ static inline lv_color_t lv_obj_get_style_outline_color(const struct _lv_obj_t * static inline lv_color_t lv_obj_get_style_outline_color_filtered(const struct _lv_obj_t * obj, uint32_t part) { - lv_style_value_t v = _lv_obj_style_apply_color_filter(obj, part, lv_obj_get_style_prop(obj, part, LV_STYLE_OUTLINE_COLOR)); + lv_style_value_t v = _lv_obj_style_apply_color_filter(obj, part, lv_obj_get_style_prop(obj, part, + LV_STYLE_OUTLINE_COLOR)); return v.color; } @@ -357,7 +361,8 @@ static inline lv_color_t lv_obj_get_style_shadow_color(const struct _lv_obj_t * static inline lv_color_t lv_obj_get_style_shadow_color_filtered(const struct _lv_obj_t * obj, uint32_t part) { - lv_style_value_t v = _lv_obj_style_apply_color_filter(obj, part, lv_obj_get_style_prop(obj, part, LV_STYLE_SHADOW_COLOR)); + lv_style_value_t v = _lv_obj_style_apply_color_filter(obj, part, lv_obj_get_style_prop(obj, part, + LV_STYLE_SHADOW_COLOR)); return v.color; } @@ -381,7 +386,8 @@ static inline lv_color_t lv_obj_get_style_img_recolor(const struct _lv_obj_t * o static inline lv_color_t lv_obj_get_style_img_recolor_filtered(const struct _lv_obj_t * obj, uint32_t part) { - lv_style_value_t v = _lv_obj_style_apply_color_filter(obj, part, lv_obj_get_style_prop(obj, part, LV_STYLE_IMG_RECOLOR)); + lv_style_value_t v = _lv_obj_style_apply_color_filter(obj, part, lv_obj_get_style_prop(obj, part, + LV_STYLE_IMG_RECOLOR)); return v.color; } @@ -541,7 +547,8 @@ static inline lv_opa_t lv_obj_get_style_opa_layered(const struct _lv_obj_t * obj return (lv_opa_t)v.num; } -static inline const lv_color_filter_dsc_t * lv_obj_get_style_color_filter_dsc(const struct _lv_obj_t * obj, uint32_t part) +static inline const lv_color_filter_dsc_t * lv_obj_get_style_color_filter_dsc(const struct _lv_obj_t * obj, + uint32_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_COLOR_FILTER_DSC); return (const lv_color_filter_dsc_t *)v.ptr; @@ -675,12 +682,16 @@ void lv_obj_set_style_radius(struct _lv_obj_t * obj, lv_coord_t value, lv_style_ void lv_obj_set_style_clip_corner(struct _lv_obj_t * obj, bool value, lv_style_selector_t selector); void lv_obj_set_style_opa(struct _lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector); void lv_obj_set_style_opa_layered(struct _lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector); -void lv_obj_set_style_color_filter_dsc(struct _lv_obj_t * obj, const lv_color_filter_dsc_t * value, lv_style_selector_t selector); +void lv_obj_set_style_color_filter_dsc(struct _lv_obj_t * obj, const lv_color_filter_dsc_t * value, + lv_style_selector_t selector); +void lv_obj_set_style_color_filter_dsc(struct _lv_obj_t * obj, const lv_color_filter_dsc_t * value, + lv_style_selector_t selector); void lv_obj_set_style_color_filter_opa(struct _lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector); void lv_obj_set_style_anim(struct _lv_obj_t * obj, const lv_anim_t * value, lv_style_selector_t selector); void lv_obj_set_style_anim_time(struct _lv_obj_t * obj, uint32_t value, lv_style_selector_t selector); void lv_obj_set_style_anim_speed(struct _lv_obj_t * obj, uint32_t value, lv_style_selector_t selector); -void lv_obj_set_style_transition(struct _lv_obj_t * obj, const lv_style_transition_dsc_t * value, lv_style_selector_t selector); +void lv_obj_set_style_transition(struct _lv_obj_t * obj, const lv_style_transition_dsc_t * value, + lv_style_selector_t selector); void lv_obj_set_style_blend_mode(struct _lv_obj_t * obj, lv_blend_mode_t value, lv_style_selector_t selector); void lv_obj_set_style_layout(struct _lv_obj_t * obj, uint16_t value, lv_style_selector_t selector); void lv_obj_set_style_base_dir(struct _lv_obj_t * obj, lv_base_dir_t value, lv_style_selector_t selector); diff --git a/src/dev/sdl/lv_sdl_window.c b/src/dev/sdl/lv_sdl_window.c index c552e13c4f..2a4d2a5958 100644 --- a/src/dev/sdl/lv_sdl_window.c +++ b/src/dev/sdl/lv_sdl_window.c @@ -184,11 +184,9 @@ static void flush_cb(lv_disp_t * disp, const lv_area_t * area, uint8_t * px_map) } } - /* TYPICALLY YOU DO NOT NEED THIS * If it was the last part to refresh update the texture of the window.*/ if(lv_disp_flush_is_last(disp)) { - if(LV_SDL_RENDER_MODE != LV_DISP_RENDER_MODE_PARTIAL) { dsc->fb_act = px_map; } diff --git a/src/lv_conf_internal.h b/src/lv_conf_internal.h index 5e754c62aa..1d126731a5 100644 --- a/src/lv_conf_internal.h +++ b/src/lv_conf_internal.h @@ -725,11 +725,25 @@ /* Adjust color mix functions rounding. GPUs might calculate color mix (blending) differently. * 0: round down, 64: round up from x.75, 128: round up from half, 192: round up from x.25, 254: round up */ -#ifndef lv_color_mix_ROUND_OFS +#ifndef LV_COLOR_MIX_ROUND_OFS #ifdef CONFIG_LV_COLOR_MIX_ROUND_OFS - #define lv_color_mix_ROUND_OFS CONFIG_LV_COLOR_MIX_ROUND_OFS + #define LV_COLOR_MIX_ROUND_OFS CONFIG_LV_COLOR_MIX_ROUND_OFS #else - #define lv_color_mix_ROUND_OFS 0 + #define LV_COLOR_MIX_ROUND_OFS 0 + #endif +#endif + + +/* Add 2 x 32 bit variables to each lv_obj_t to speed up getting style properties */ +#ifndef LV_OBJ_STYLE_CACHE + #ifdef _LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_OBJ_STYLE_CACHE + #define LV_OBJ_STYLE_CACHE CONFIG_LV_OBJ_STYLE_CACHE + #else + #define LV_OBJ_STYLE_CACHE 0 + #endif + #else + #define LV_OBJ_STYLE_CACHE 1 #endif #endif diff --git a/src/misc/lv_color_op.h b/src/misc/lv_color_op.h index aac541d8b6..706943db2f 100644 --- a/src/misc/lv_color_op.h +++ b/src/misc/lv_color_op.h @@ -50,9 +50,9 @@ LV_ATTRIBUTE_FAST_MEM static inline lv_color_t lv_color_mix(lv_color_t c1, lv_co { lv_color_t ret; - ret.red = LV_UDIV255((uint16_t)c1.red * mix + c2.red * (255 - mix) + lv_color_mix_ROUND_OFS); - ret.green = LV_UDIV255((uint16_t)c1.green * mix + c2.green * (255 - mix) + lv_color_mix_ROUND_OFS); - ret.blue = LV_UDIV255((uint16_t)c1.blue * mix + c2.blue * (255 - mix) + lv_color_mix_ROUND_OFS); + ret.red = LV_UDIV255((uint16_t)c1.red * mix + c2.red * (255 - mix) + LV_COLOR_MIX_ROUND_OFS); + ret.green = LV_UDIV255((uint16_t)c1.green * mix + c2.green * (255 - mix) + LV_COLOR_MIX_ROUND_OFS); + ret.blue = LV_UDIV255((uint16_t)c1.blue * mix + c2.blue * (255 - mix) + LV_COLOR_MIX_ROUND_OFS); return ret; } diff --git a/src/misc/lv_style.c b/src/misc/lv_style.c index ba917225ac..7c9f065131 100644 --- a/src/misc/lv_style.c +++ b/src/misc/lv_style.c @@ -24,13 +24,6 @@ * STATIC PROTOTYPES **********************/ -static void lv_style_set_prop_internal(lv_style_t * style, lv_style_prop_t prop_and_meta, lv_style_value_t value, - void (*value_adjustment_helper)(lv_style_prop_t, lv_style_value_t, uint16_t *, lv_style_value_t *)); -static void lv_style_set_prop_helper(lv_style_prop_t prop, lv_style_value_t value, uint16_t * prop_storage, - lv_style_value_t * value_storage); -static void lv_style_set_prop_meta_helper(lv_style_prop_t prop, lv_style_value_t value, uint16_t * prop_storage, - lv_style_value_t * value_storage); - /********************** * GLOBAL VARIABLES **********************/ @@ -144,7 +137,6 @@ uint32_t _lv_style_custom_prop_flag_lookup_table_size = 0; **********************/ static uint16_t last_custom_prop_id = (uint16_t)_LV_STYLE_LAST_BUILT_IN_PROP; -static const lv_style_value_t null_style_value = { .num = 0 }; /********************** * MACROS @@ -172,12 +164,7 @@ void lv_style_reset(lv_style_t * style) { LV_ASSERT_STYLE(style); - if(style->prop1 == LV_STYLE_PROP_ANY) { - LV_LOG_ERROR("Cannot reset const style"); - return; - } - - if(style->prop_cnt > 1) lv_free(style->v_p.values_and_props); + if(style->prop_cnt != 255) lv_free(style->values_and_props); lv_memzero(style, sizeof(lv_style_t)); #if LV_USE_ASSERT_STYLE style->sentinel = LV_STYLE_SENTINEL_VALUE; @@ -191,10 +178,10 @@ lv_style_prop_t lv_style_register_prop(uint8_t flag) last_custom_prop_id = (uint16_t)_LV_STYLE_LAST_BUILT_IN_PROP; } - if(((last_custom_prop_id + 1) & LV_STYLE_PROP_META_MASK) != 0) { - LV_LOG_ERROR("No more custom property IDs available"); - return LV_STYLE_PROP_INV; - } + // if((last_custom_prop_id + 1) != 0) { + // LV_LOG_ERROR("No more custom property IDs available"); + // return LV_STYLE_PROP_INV; + // } /* * Allocate the lookup table if it's not yet available. @@ -229,52 +216,36 @@ bool lv_style_remove_prop(lv_style_t * style, lv_style_prop_t prop) { LV_ASSERT_STYLE(style); - if(style->prop1 == LV_STYLE_PROP_ANY) { + if(style->prop_cnt == 255) { LV_LOG_ERROR("Cannot remove prop from const style"); return false; } if(style->prop_cnt == 0) return false; - if(style->prop_cnt == 1) { - if(LV_STYLE_PROP_ID_MASK(style->prop1) == prop) { - style->prop1 = LV_STYLE_PROP_INV; - style->prop_cnt = 0; - return true; - } - return false; - } - - uint8_t * tmp = style->v_p.values_and_props + style->prop_cnt * sizeof(lv_style_value_t); - uint16_t * old_props = (uint16_t *)tmp; + uint8_t * tmp = (lv_style_prop_t *)style->values_and_props + style->prop_cnt * sizeof(lv_style_value_t); + uint8_t * old_props = (uint8_t *)tmp; uint32_t i; for(i = 0; i < style->prop_cnt; i++) { - if(LV_STYLE_PROP_ID_MASK(old_props[i]) == prop) { - lv_style_value_t * old_values = (lv_style_value_t *)style->v_p.values_and_props; + if(old_props[i] == prop) { + lv_style_value_t * old_values = (lv_style_value_t *)style->values_and_props; - if(style->prop_cnt == 2) { - style->prop_cnt = 1; - style->prop1 = i == 0 ? old_props[1] : old_props[0]; - style->v_p.value1 = i == 0 ? old_values[1] : old_values[0]; - } - else { - size_t size = (style->prop_cnt - 1) * (sizeof(lv_style_value_t) + sizeof(uint16_t)); - uint8_t * new_values_and_props = lv_malloc(size); - if(new_values_and_props == NULL) return false; - style->v_p.values_and_props = new_values_and_props; - style->prop_cnt--; + size_t size = (style->prop_cnt - 1) * (sizeof(lv_style_value_t) + sizeof(lv_style_prop_t)); + uint8_t * new_values_and_props = lv_malloc(size); + if(new_values_and_props == NULL) return false; + style->values_and_props = new_values_and_props; + style->prop_cnt--; - tmp = new_values_and_props + style->prop_cnt * sizeof(lv_style_value_t); - uint16_t * new_props = (uint16_t *)tmp; - lv_style_value_t * new_values = (lv_style_value_t *)new_values_and_props; + tmp = new_values_and_props + style->prop_cnt * sizeof(lv_style_value_t); + uint8_t * new_props = (uint8_t *)tmp; + lv_style_value_t * new_values = (lv_style_value_t *)new_values_and_props; - uint32_t j; - for(i = j = 0; j <= style->prop_cnt; - j++) { /*<=: because prop_cnt already reduced but all the old props. needs to be checked.*/ - if(old_props[j] != prop) { - new_values[i] = old_values[j]; - new_props[i++] = old_props[j]; - } + uint32_t j; + for(i = j = 0; j <= style->prop_cnt; + j++) { /*<=: because prop_cnt already reduced but all the old props. needs to be checked.*/ + if(old_props[j] != prop) { + new_values[i] = old_values[j]; + new_props[i++] = old_props[j]; } } @@ -288,12 +259,47 @@ bool lv_style_remove_prop(lv_style_t * style, lv_style_prop_t prop) void lv_style_set_prop(lv_style_t * style, lv_style_prop_t prop, lv_style_value_t value) { - lv_style_set_prop_internal(style, prop, value, lv_style_set_prop_helper); -} + LV_ASSERT_STYLE(style); -void lv_style_set_prop_meta(lv_style_t * style, lv_style_prop_t prop, uint16_t meta) -{ - lv_style_set_prop_internal(style, prop | meta, null_style_value, lv_style_set_prop_meta_helper); + if(style->prop_cnt == 255) { + LV_LOG_ERROR("Cannot set property of constant style"); + return; + } + + LV_ASSERT(prop != LV_STYLE_PROP_INV); + + lv_style_prop_t * props = (lv_style_prop_t *)style->values_and_props + style->prop_cnt * sizeof(lv_style_value_t); + int32_t i; + for(i = style->prop_cnt - 1; i >= 0; i--) { + if(props[i] == prop) { + lv_style_value_t * values = (lv_style_value_t *)style->values_and_props; + values[i] = value; + return; + } + } + + size_t size = (style->prop_cnt + 1) * (sizeof(lv_style_value_t) + sizeof(lv_style_prop_t)); + uint8_t * values_and_props = lv_realloc(style->values_and_props, size); + if(values_and_props == NULL) return; + style->values_and_props = values_and_props; + + props = values_and_props + style->prop_cnt * sizeof(lv_style_value_t); + /*Shift all props to make place for the value before them*/ + for(i = style->prop_cnt - 1; i >= 0; i--) { + props[i + sizeof(lv_style_value_t) / sizeof(lv_style_prop_t)] = props[i]; + } + style->prop_cnt++; + + /*Go to the new position wit the props*/ + props = values_and_props + style->prop_cnt * sizeof(lv_style_value_t); + lv_style_value_t * values = (lv_style_value_t *)values_and_props; + + /*Set the new property and value*/ + props[style->prop_cnt - 1] = prop; + values[style->prop_cnt - 1] = value; + + uint32_t group = _lv_style_get_prop_group(prop); + style->has_group |= (uint32_t)1 << group; } lv_style_res_t lv_style_get_prop(const lv_style_t * style, lv_style_prop_t prop, lv_style_value_t * value) @@ -314,14 +320,17 @@ void lv_style_transition_dsc_init(lv_style_transition_dsc_t * tr, const lv_style lv_style_value_t lv_style_prop_get_default(lv_style_prop_t prop) { - lv_style_value_t value = {0}; + const lv_color_t black = LV_COLOR_MAKE(0x00, 0x00, 0x00); + const lv_color_t white = LV_COLOR_MAKE(0xff, 0xff, 0xff); switch(prop) { case LV_STYLE_TRANSFORM_ZOOM: - value.num = LV_ZOOM_NONE; - break; + return (lv_style_value_t) { + .num = LV_ZOOM_NONE + }; case LV_STYLE_BG_COLOR: - value.color = lv_color_white(); - break; + return (lv_style_value_t) { + .color = black + }; case LV_STYLE_BG_GRAD_COLOR: case LV_STYLE_BORDER_COLOR: case LV_STYLE_SHADOW_COLOR: @@ -330,8 +339,9 @@ lv_style_value_t lv_style_prop_get_default(lv_style_prop_t prop) case LV_STYLE_LINE_COLOR: case LV_STYLE_TEXT_COLOR: case LV_STYLE_IMG_RECOLOR: - value.color = lv_color_black(); - break; + return (lv_style_value_t) { + .color = white + }; case LV_STYLE_OPA: case LV_STYLE_OPA_LAYERED: case LV_STYLE_BORDER_OPA: @@ -342,28 +352,31 @@ lv_style_value_t lv_style_prop_get_default(lv_style_prop_t prop) case LV_STYLE_SHADOW_OPA: case LV_STYLE_LINE_OPA: case LV_STYLE_ARC_OPA: - value.num = LV_OPA_COVER; - break; + return (lv_style_value_t) { + .num = LV_OPA_COVER + }; case LV_STYLE_BG_GRAD_STOP: - value.num = 255; - break; + return (lv_style_value_t) { + .num = 255 + }; case LV_STYLE_BORDER_SIDE: - value.num = LV_BORDER_SIDE_FULL; - break; + return (lv_style_value_t) { + .num = LV_BORDER_SIDE_FULL + }; case LV_STYLE_TEXT_FONT: - value.ptr = LV_FONT_DEFAULT; - break; + return (lv_style_value_t) { + .ptr = LV_FONT_DEFAULT + }; case LV_STYLE_MAX_WIDTH: case LV_STYLE_MAX_HEIGHT: - value.num = LV_COORD_MAX; - break; + return (lv_style_value_t) { + .num = LV_COORD_MAX + }; default: - value.ptr = NULL; - value.num = 0; - break; + return (lv_style_value_t) { + .ptr = 0 + }; } - - return value; } bool lv_style_is_empty(const lv_style_t * style) @@ -373,13 +386,6 @@ bool lv_style_is_empty(const lv_style_t * style) return style->prop_cnt == 0 ? true : false; } -uint8_t _lv_style_get_prop_group(lv_style_prop_t prop) -{ - uint16_t group = (prop & 0x1FF) >> 4; - if(group > 7) group = 7; /*The MSB marks all the custom properties*/ - return (uint8_t)group; -} - uint8_t _lv_style_prop_lookup_flags(lv_style_prop_t prop) { extern const uint8_t _lv_style_builtin_prop_flag_lookup_table[]; @@ -398,93 +404,3 @@ uint8_t _lv_style_prop_lookup_flags(lv_style_prop_t prop) /********************** * STATIC FUNCTIONS **********************/ - -static void lv_style_set_prop_helper(lv_style_prop_t prop, lv_style_value_t value, uint16_t * prop_storage, - lv_style_value_t * value_storage) -{ - *prop_storage = prop; - *value_storage = value; -} - -static void lv_style_set_prop_meta_helper(lv_style_prop_t prop, lv_style_value_t value, uint16_t * prop_storage, - lv_style_value_t * value_storage) -{ - LV_UNUSED(value); - LV_UNUSED(value_storage); - *prop_storage = prop; /* meta is OR-ed into the prop ID already */ -} - -static void lv_style_set_prop_internal(lv_style_t * style, lv_style_prop_t prop_and_meta, lv_style_value_t value, - void (*value_adjustment_helper)(lv_style_prop_t, lv_style_value_t, uint16_t *, lv_style_value_t *)) -{ - LV_ASSERT_STYLE(style); - - if(style->prop1 == LV_STYLE_PROP_ANY) { - LV_LOG_ERROR("Cannot set property of constant style"); - return; - } - - lv_style_prop_t prop_id = LV_STYLE_PROP_ID_MASK(prop_and_meta); - LV_ASSERT(prop_id != LV_STYLE_PROP_INV); - - if(style->prop_cnt > 1) { - uint8_t * tmp = style->v_p.values_and_props + style->prop_cnt * sizeof(lv_style_value_t); - uint16_t * props = (uint16_t *)tmp; - int32_t i; - for(i = style->prop_cnt - 1; i >= 0; i--) { - if(LV_STYLE_PROP_ID_MASK(props[i]) == prop_id) { - lv_style_value_t * values = (lv_style_value_t *)style->v_p.values_and_props; - value_adjustment_helper(prop_and_meta, value, &props[i], &values[i]); - return; - } - } - - size_t size = (style->prop_cnt + 1) * (sizeof(lv_style_value_t) + sizeof(uint16_t)); - uint8_t * values_and_props = lv_realloc(style->v_p.values_and_props, size); - if(values_and_props == NULL) return; - style->v_p.values_and_props = values_and_props; - - tmp = values_and_props + style->prop_cnt * sizeof(lv_style_value_t); - props = (uint16_t *)tmp; - /*Shift all props to make place for the value before them*/ - for(i = style->prop_cnt - 1; i >= 0; i--) { - props[i + sizeof(lv_style_value_t) / sizeof(uint16_t)] = props[i]; - } - style->prop_cnt++; - - /*Go to the new position with the props*/ - tmp = values_and_props + style->prop_cnt * sizeof(lv_style_value_t); - props = (uint16_t *)tmp; - lv_style_value_t * values = (lv_style_value_t *)values_and_props; - - /*Set the new property and value*/ - value_adjustment_helper(prop_and_meta, value, &props[style->prop_cnt - 1], &values[style->prop_cnt - 1]); - } - else if(style->prop_cnt == 1) { - if(LV_STYLE_PROP_ID_MASK(style->prop1) == prop_id) { - value_adjustment_helper(prop_and_meta, value, &style->prop1, &style->v_p.value1); - return; - } - size_t size = (style->prop_cnt + 1) * (sizeof(lv_style_value_t) + sizeof(uint16_t)); - uint8_t * values_and_props = lv_malloc(size); - if(values_and_props == NULL) return; - lv_style_value_t value_tmp = style->v_p.value1; - style->v_p.values_and_props = values_and_props; - style->prop_cnt++; - - uint8_t * tmp = values_and_props + style->prop_cnt * sizeof(lv_style_value_t); - uint16_t * props = (uint16_t *)tmp; - lv_style_value_t * values = (lv_style_value_t *)values_and_props; - props[0] = style->prop1; - values[0] = value_tmp; - value_adjustment_helper(prop_and_meta, value, &props[1], &values[1]); - } - else { - style->prop_cnt = 1; - value_adjustment_helper(prop_and_meta, value, &style->prop1, &style->v_p.value1); - } - - uint8_t group = _lv_style_get_prop_group(prop_id); - style->has_group |= 1 << group; -} - diff --git a/src/misc/lv_style.h b/src/misc/lv_style.h index 08d5cd4b44..42f5493218 100644 --- a/src/misc/lv_style.h +++ b/src/misc/lv_style.h @@ -55,29 +55,21 @@ LV_EXPORT_CONST_INT(LV_ZOOM_NONE); #define LV_STYLE_CONST_INIT(var_name, prop_array) \ const lv_style_t var_name = { \ .sentinel = LV_STYLE_SENTINEL_VALUE, \ - .v_p = { .const_props = prop_array }, \ - .has_group = 0xFF, \ - .prop1 = _LV_STYLE_PROP_CONST, \ - .prop_cnt = (sizeof(prop_array) / sizeof((prop_array)[0])), \ + .values_and_props = (void*)prop_array, \ + .has_group = 0xFFFFFFFF, \ + .prop_cnt = 255 \ } #else #define LV_STYLE_CONST_INIT(var_name, prop_array) \ const lv_style_t var_name = { \ - .v_p = { .const_props = prop_array }, \ - .has_group = 0xFF, \ - .prop1 = _LV_STYLE_PROP_CONST, \ - .prop_cnt = (sizeof(prop_array) / sizeof((prop_array)[0])), \ + .values_and_props = prop_array, \ + .has_group = 0xFFFFFFFF, \ + .prop_cnt = 255, \ } #endif // *INDENT-ON* -#define LV_STYLE_PROP_META_INHERIT 0x8000 -#define LV_STYLE_PROP_META_INITIAL 0x4000 -#define LV_STYLE_PROP_META_MASK (LV_STYLE_PROP_META_INHERIT | LV_STYLE_PROP_META_INITIAL) - -#define LV_STYLE_PROP_ID_MASK(prop) ((lv_style_prop_t)((prop) & ~LV_STYLE_PROP_META_MASK)) - -#define LV_STYLE_CONST_PROPS_END { .prop_ptr = &lv_style_const_prop_id_inv, .value = { .num = 0 } } +#define LV_STYLE_CONST_PROPS_END { .prop_ptr = NULL, .value = { .num = 0 } } /********************** * TYPEDEFS @@ -208,73 +200,90 @@ enum _lv_style_prop_t { /*Group 0*/ LV_STYLE_WIDTH = 1, - LV_STYLE_MIN_WIDTH = 2, - LV_STYLE_MAX_WIDTH = 3, - LV_STYLE_HEIGHT = 4, - LV_STYLE_MIN_HEIGHT = 5, - LV_STYLE_MAX_HEIGHT = 6, - LV_STYLE_X = 7, - LV_STYLE_Y = 8, - LV_STYLE_ALIGN = 9, - LV_STYLE_LAYOUT = 10, - LV_STYLE_RADIUS = 11, + LV_STYLE_HEIGHT = 2, + + LV_STYLE_MIN_WIDTH = 4, + LV_STYLE_MAX_WIDTH = 5, + LV_STYLE_MIN_HEIGHT = 6, + LV_STYLE_MAX_HEIGHT = 7, + + LV_STYLE_X = 8, + LV_STYLE_Y = 9, + LV_STYLE_ALIGN = 10, + + LV_STYLE_RADIUS = 12, + /*Group 1*/ LV_STYLE_PAD_TOP = 16, LV_STYLE_PAD_BOTTOM = 17, LV_STYLE_PAD_LEFT = 18, LV_STYLE_PAD_RIGHT = 19, + LV_STYLE_PAD_ROW = 20, LV_STYLE_PAD_COLUMN = 21, - LV_STYLE_BASE_DIR = 22, - LV_STYLE_CLIP_CORNER = 23, + LV_STYLE_LAYOUT = 22, + LV_STYLE_MARGIN_TOP = 24, LV_STYLE_MARGIN_BOTTOM = 25, LV_STYLE_MARGIN_LEFT = 26, LV_STYLE_MARGIN_RIGHT = 27, /*Group 2*/ - LV_STYLE_BG_COLOR = 32, - LV_STYLE_BG_OPA = 33, - LV_STYLE_BG_GRAD_COLOR = 34, - LV_STYLE_BG_GRAD_DIR = 35, - LV_STYLE_BG_MAIN_STOP = 36, - LV_STYLE_BG_GRAD_STOP = 37, - LV_STYLE_BG_GRAD = 38, - LV_STYLE_BG_DITHER_MODE = 39, + LV_STYLE_BG_COLOR = 28, + LV_STYLE_BG_OPA = 29, + + + LV_STYLE_BG_GRAD_DIR = 32, + LV_STYLE_BG_GRAD_COLOR = 33, + LV_STYLE_BG_MAIN_STOP = 34, + LV_STYLE_BG_GRAD_STOP = 35, + + LV_STYLE_BG_GRAD = 36, + LV_STYLE_BG_DITHER_MODE = 37, + LV_STYLE_BASE_DIR = 38, + LV_STYLE_BG_IMG_SRC = 40, LV_STYLE_BG_IMG_OPA = 41, LV_STYLE_BG_IMG_RECOLOR = 42, LV_STYLE_BG_IMG_RECOLOR_OPA = 43, + LV_STYLE_BG_IMG_TILED = 44, + LV_STYLE_CLIP_CORNER = 45, + /*Group 3*/ - LV_STYLE_BORDER_COLOR = 48, - LV_STYLE_BORDER_OPA = 49, - LV_STYLE_BORDER_WIDTH = 50, - LV_STYLE_BORDER_SIDE = 51, - LV_STYLE_BORDER_POST = 52, - LV_STYLE_OUTLINE_WIDTH = 53, - LV_STYLE_OUTLINE_COLOR = 54, - LV_STYLE_OUTLINE_OPA = 55, - LV_STYLE_OUTLINE_PAD = 56, + LV_STYLE_BORDER_WIDTH = 48, + LV_STYLE_BORDER_COLOR = 49, + LV_STYLE_BORDER_OPA = 50, + + LV_STYLE_BORDER_SIDE = 52, + LV_STYLE_BORDER_POST = 53, + + LV_STYLE_OUTLINE_WIDTH = 56, + LV_STYLE_OUTLINE_COLOR = 57, + LV_STYLE_OUTLINE_OPA = 58, + LV_STYLE_OUTLINE_PAD = 59, /*Group 4*/ - LV_STYLE_SHADOW_WIDTH = 64, - LV_STYLE_SHADOW_OFS_X = 65, - LV_STYLE_SHADOW_OFS_Y = 66, - LV_STYLE_SHADOW_SPREAD = 67, - LV_STYLE_SHADOW_COLOR = 68, - LV_STYLE_SHADOW_OPA = 69, - LV_STYLE_IMG_OPA = 70, - LV_STYLE_IMG_RECOLOR = 71, - LV_STYLE_IMG_RECOLOR_OPA = 72, - LV_STYLE_LINE_WIDTH = 73, - LV_STYLE_LINE_DASH_WIDTH = 74, - LV_STYLE_LINE_DASH_GAP = 75, - LV_STYLE_LINE_ROUNDED = 76, - LV_STYLE_LINE_COLOR = 77, - LV_STYLE_LINE_OPA = 78, + LV_STYLE_SHADOW_WIDTH = 60, + LV_STYLE_SHADOW_COLOR = 61, + LV_STYLE_SHADOW_OPA = 62, + + LV_STYLE_SHADOW_OFS_X = 64, + LV_STYLE_SHADOW_OFS_Y = 65, + LV_STYLE_SHADOW_SPREAD = 66, + + LV_STYLE_IMG_OPA = 68, + LV_STYLE_IMG_RECOLOR = 69, + LV_STYLE_IMG_RECOLOR_OPA = 70, + + LV_STYLE_LINE_WIDTH = 72, + LV_STYLE_LINE_DASH_WIDTH = 73, + LV_STYLE_LINE_DASH_GAP = 74, + LV_STYLE_LINE_ROUNDED = 75, + LV_STYLE_LINE_COLOR = 76, + LV_STYLE_LINE_OPA = 77, /*Group 5*/ LV_STYLE_ARC_WIDTH = 80, @@ -282,15 +291,16 @@ enum _lv_style_prop_t { LV_STYLE_ARC_COLOR = 82, LV_STYLE_ARC_OPA = 83, LV_STYLE_ARC_IMG_SRC = 84, - LV_STYLE_TEXT_COLOR = 85, - LV_STYLE_TEXT_OPA = 86, - LV_STYLE_TEXT_FONT = 87, - LV_STYLE_TEXT_LETTER_SPACE = 88, - LV_STYLE_TEXT_LINE_SPACE = 89, - LV_STYLE_TEXT_DECOR = 90, - LV_STYLE_TEXT_ALIGN = 91, - /*Group 6*/ + LV_STYLE_TEXT_COLOR = 88, + LV_STYLE_TEXT_OPA = 89, + LV_STYLE_TEXT_FONT = 90, + + LV_STYLE_TEXT_LETTER_SPACE = 92, + LV_STYLE_TEXT_LINE_SPACE = 93, + LV_STYLE_TEXT_DECOR = 94, + LV_STYLE_TEXT_ALIGN = 95, + LV_STYLE_OPA = 96, LV_STYLE_OPA_LAYERED = 97, LV_STYLE_COLOR_FILTER_DSC = 98, @@ -312,20 +322,19 @@ enum _lv_style_prop_t { _LV_STYLE_LAST_BUILT_IN_PROP = 112, _LV_STYLE_NUM_BUILT_IN_PROPS = _LV_STYLE_LAST_BUILT_IN_PROP + 1, - LV_STYLE_PROP_ANY = 0xFFFF, - _LV_STYLE_PROP_CONST = 0xFFFF /* magic value for const styles */ + LV_STYLE_PROP_ANY = 0xFF, + _LV_STYLE_PROP_CONST = 0xFF /* magic value for const styles */ }; #ifdef DOXYGEN typedef _lv_style_prop_t lv_style_prop_t; #else -typedef uint16_t lv_style_prop_t; +typedef uint8_t lv_style_prop_t; #endif /*DOXYGEN*/ enum _lv_style_res_t { LV_STYLE_RES_NOT_FOUND, LV_STYLE_RES_FOUND, - LV_STYLE_RES_INHERIT }; #ifdef DOXYGEN @@ -363,17 +372,10 @@ typedef struct { uint32_t sentinel; #endif - /*If there is only one property store it directly. - *For more properties allocate an array*/ - union { - lv_style_value_t value1; - uint8_t * values_and_props; - const lv_style_const_prop_t * const_props; - } v_p; + void * values_and_props; - uint16_t prop1; - uint8_t has_group; - uint8_t prop_cnt; + uint32_t has_group; + uint8_t prop_cnt; /**< 255 means it's a constant style*/ } lv_style_t; /********************** @@ -434,15 +436,6 @@ bool lv_style_remove_prop(lv_style_t * style, lv_style_prop_t prop); */ void lv_style_set_prop(lv_style_t * style, lv_style_prop_t prop, lv_style_value_t value); -/** - * Set a special meta state for a property in a style. - * This function shouldn't be used directly by the user. - * @param style pointer to style - * @param prop the ID of a property (e.g. `LV_STYLE_BG_COLOR`) - * @param meta the meta value to attach to the property in the style - */ -void lv_style_set_prop_meta(lv_style_t * style, lv_style_prop_t prop, uint16_t meta); - /** * Get the value of a property * @param style pointer to a style @@ -490,50 +483,26 @@ lv_style_value_t lv_style_prop_get_default(lv_style_prop_t prop); static inline lv_style_res_t lv_style_get_prop_inlined(const lv_style_t * style, lv_style_prop_t prop, lv_style_value_t * value) { - if(style->prop1 == LV_STYLE_PROP_ANY) { - const lv_style_const_prop_t * const_prop; + if(style->prop_cnt == 255) { + lv_style_const_prop_t * props = style->values_and_props; uint32_t i; - for(i = 0; i < style->prop_cnt; i++) { - const_prop = style->v_p.const_props + i; - lv_style_prop_t prop_id_and_meta = *const_prop->prop_ptr; - lv_style_prop_t prop_id = LV_STYLE_PROP_ID_MASK(prop_id_and_meta); - if(prop_id == prop) { - if(prop_id_and_meta & LV_STYLE_PROP_META_INHERIT) - return LV_STYLE_RES_INHERIT; - *value = (prop_id_and_meta & LV_STYLE_PROP_META_INITIAL) ? lv_style_prop_get_default(prop_id) : const_prop->value; - return LV_STYLE_RES_FOUND; - } - } - return LV_STYLE_RES_NOT_FOUND; - } - - if(style->prop_cnt == 0) return LV_STYLE_RES_NOT_FOUND; - - if(style->prop_cnt > 1) { - uint8_t * tmp = style->v_p.values_and_props + style->prop_cnt * sizeof(lv_style_value_t); - uint16_t * props = (uint16_t *)tmp; - uint32_t i; - for(i = 0; i < style->prop_cnt; i++) { - lv_style_prop_t prop_id = LV_STYLE_PROP_ID_MASK(props[i]); - if(prop_id == prop) { - if(props[i] & LV_STYLE_PROP_META_INHERIT) - return LV_STYLE_RES_INHERIT; - if(props[i] & LV_STYLE_PROP_META_INITIAL) - *value = lv_style_prop_get_default(prop_id); - else { - lv_style_value_t * values = (lv_style_value_t *)style->v_p.values_and_props; - *value = values[i]; - } + for(i = 0; props[i].prop_ptr; i++) { + if(*props[i].prop_ptr == prop) { + *value = props[i].value; return LV_STYLE_RES_FOUND; } } } - else if(LV_STYLE_PROP_ID_MASK(style->prop1) == prop) { - if(style->prop1 & LV_STYLE_PROP_META_INHERIT) - return LV_STYLE_RES_INHERIT; - *value = (style->prop1 & LV_STYLE_PROP_META_INITIAL) ? lv_style_prop_get_default(LV_STYLE_PROP_ID_MASK( - style->prop1)) : style->v_p.value1; - return LV_STYLE_RES_FOUND; + else { + lv_style_prop_t * props = (lv_style_prop_t *)style->values_and_props + style->prop_cnt * sizeof(lv_style_value_t); + uint32_t i; + for(i = 0; i < style->prop_cnt; i++) { + if(props[i] == prop) { + lv_style_value_t * values = (lv_style_value_t *)style->values_and_props; + *value = values[i]; + return LV_STYLE_RES_FOUND; + } + } } return LV_STYLE_RES_NOT_FOUND; } @@ -549,9 +518,15 @@ bool lv_style_is_empty(const lv_style_t * style); * Tell the group of a property. If the a property from a group is set in a style the (1 << group) bit of style->has_group is set. * It allows early skipping the style if the property is not exists in the style at all. * @param prop a style property - * @return the group [0..7] 7 means all the custom properties with index > 112 + * @return the group [0..30] 30 means all the custom properties with index > 120 */ -uint8_t _lv_style_get_prop_group(lv_style_prop_t prop); +static inline uint32_t _lv_style_get_prop_group(lv_style_prop_t prop) +{ + uint32_t group = prop >> 2; + if(group > 30) group = 31; /*The MSB marks all the custom properties*/ + return group; + +} /** * Get the flags of a built-in or custom property. @@ -561,6 +536,7 @@ uint8_t _lv_style_get_prop_group(lv_style_prop_t prop); */ uint8_t _lv_style_prop_lookup_flags(lv_style_prop_t prop); + #include "lv_style_gen.h" static inline void lv_style_set_size(lv_style_t * style, lv_coord_t width, lv_coord_t height) diff --git a/tests/src/lv_test_conf.h b/tests/src/lv_test_conf.h index 76d9007ef4..f138376462 100644 --- a/tests/src/lv_test_conf.h +++ b/tests/src/lv_test_conf.h @@ -21,12 +21,14 @@ extern "C" { #define LV_USE_STDLIB_STRING LV_STDLIB_CLIB #define LV_USE_STDLIB_SPRINTF LV_STDLIB_CLIB #define LV_USE_OS LV_OS_PTHREAD +#define LV_OBJ_STYLE_CACHE 0 #endif #ifdef LVGL_CI_USING_DEF_HEAP #define LV_USE_STDLIB_MALLOC LV_STDLIB_BUILTIN #define LV_USE_STDLIB_STRING LV_STDLIB_BUILTIN #define LV_USE_STDLIB_SPRINTF LV_STDLIB_BUILTIN +#define LV_OBJ_STYLE_CACHE 1 #endif diff --git a/tests/src/test_cases/test_style.c b/tests/src/test_cases/test_style.c index a0f0154363..550d44e09b 100644 --- a/tests/src/test_cases/test_style.c +++ b/tests/src/test_cases/test_style.c @@ -71,42 +71,6 @@ void test_custom_prop_ids(void) TEST_ASSERT_EQUAL(_lv_style_custom_prop_flag_lookup_table_size, 96); } -void test_inherit_meta(void) -{ - lv_obj_t * parent = lv_obj_create(lv_scr_act()); - lv_obj_t * child = lv_obj_create(parent); - lv_obj_t * grandchild = lv_label_create(child); - lv_obj_set_style_text_color(parent, lv_color_hex(0xff0000), LV_PART_MAIN); - lv_obj_set_local_style_prop_meta(child, LV_STYLE_TEXT_COLOR, LV_STYLE_PROP_META_INHERIT, LV_PART_MAIN); - TEST_ASSERT_EQUAL_COLOR(lv_color_hex(0xff0000), lv_obj_get_style_text_color(grandchild, LV_PART_MAIN)); -} - -void test_id_meta_overrun(void) -{ - /* Test that property ID registration is blocked once the ID reaches into the meta bits */ - lv_style_prop_t prop_id; - do { - prop_id = lv_style_register_prop(0); - if(prop_id != LV_STYLE_PROP_INV) { - TEST_ASSERT_EQUAL(0, prop_id & LV_STYLE_PROP_META_MASK); - } - } while(prop_id != LV_STYLE_PROP_INV); -} - -void test_inherit_meta_with_lower_precedence_style(void) -{ - lv_obj_t * parent = lv_obj_create(lv_scr_act()); - lv_obj_t * child = lv_obj_create(parent); - lv_obj_t * grandchild = lv_label_create(child); - lv_obj_set_style_text_color(parent, lv_color_hex(0xff0000), LV_PART_MAIN); - lv_style_t style; - lv_style_init(&style); - lv_style_set_text_color(&style, lv_color_hex(0xffffff)); - lv_obj_set_local_style_prop_meta(child, LV_STYLE_TEXT_COLOR, LV_STYLE_PROP_META_INHERIT, LV_PART_MAIN); - lv_obj_add_style(child, &style, LV_PART_MAIN); - TEST_ASSERT_EQUAL_COLOR(lv_color_hex(0xff0000), lv_obj_get_style_text_color(grandchild, LV_PART_MAIN)); -} - const lv_style_const_prop_t const_style_props[] = { LV_STYLE_CONST_WIDTH(51), LV_STYLE_CONST_HEIGHT(50), @@ -149,6 +113,9 @@ void test_style_replacement(void) replaced = lv_obj_replace_style(obj, &style_red, &style_blue, LV_PART_MAIN); TEST_ASSERT_EQUAL(false, replaced); TEST_ASSERT_EQUAL_COLOR(lv_color_hex(0x0000ff), lv_obj_get_style_bg_color(obj, LV_PART_MAIN)); + + lv_style_reset(&style_red); + lv_style_reset(&style_blue); } #endif