From 41fd83e1d326da37210fc8bdbdc851e79c1683eb Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Sun, 2 Aug 2020 10:14:29 +0200 Subject: [PATCH 1/7] implement caching on style lists --- src/lv_core/lv_obj.c | 168 +++++++++++++++++++++++++++++++++++++---- src/lv_core/lv_obj.h | 14 ++++ src/lv_core/lv_style.c | 3 + src/lv_core/lv_style.h | 31 ++++++-- 4 files changed, 197 insertions(+), 19 deletions(-) diff --git a/src/lv_core/lv_obj.c b/src/lv_core/lv_obj.c index 8eedc3da0..ec443efd3 100644 --- a/src/lv_core/lv_obj.c +++ b/src/lv_core/lv_obj.c @@ -1300,6 +1300,8 @@ void lv_obj_refresh_style(lv_obj_t * obj, lv_style_property_t prop) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); + _lv_obj_invalidate_style_cache(obj); + /*If a real style refresh is required*/ bool real_refr = false; switch(prop) { @@ -1387,6 +1389,64 @@ void lv_obj_report_style_mod(lv_style_t * style) } } + +/** + * Update the cache of style list + * @param obj pointer to an obejct + * @param part the part of the object + */ +void _lv_obj_update_style_cache(lv_obj_t * obj, uint8_t part) +{ + lv_style_list_t * list = lv_obj_get_style_list(obj, part); + if(list->valid_cache) return; + + bool ignore_cache_ori = list->ignore_cache; + list->ignore_cache = 1; + list->bg_grad_dir_none = lv_obj_get_style_bg_grad_dir(obj, part) == LV_GRAD_DIR_NONE ? 1 : 0; + list->bg_opa_transp = lv_obj_get_style_bg_opa(obj, part) == LV_OPA_TRANSP ? 1 : 0; + list->border_width_zero = lv_obj_get_style_border_width(obj, part) == LV_OPA_TRANSP ? 1 : 0; + list->clip_corner_off = lv_obj_get_style_clip_corner(obj, part) == false ? 1 : 0; + list->img_recolor_opa_transp = lv_obj_get_style_image_recolor_opa(obj, part) == LV_OPA_TRANSP ? 1 : 0; + list->line_width_zerop = lv_obj_get_style_line_width(obj, part) == 0 ? 1 : 0; + list->opa_scale_transp = lv_obj_get_style_opa_scale(obj, part) == LV_OPA_TRANSP ? 1 : 0; + list->outline_width_zero = lv_obj_get_style_outline_width(obj, part) == 0 ? 1 : 0; + list->pattern_img_null = lv_obj_get_style_pattern_image(obj, part) == NULL ? 1 : 0; + list->shadow_width_zero = lv_obj_get_style_shadow_width(obj, part) == 0 ? 1 : 0; + list->text_decor_none = lv_obj_get_style_text_decor(obj, part) == LV_TEXT_DECOR_NONE ? 1 : 0; + list->text_letter_space_zero = lv_obj_get_style_text_letter_space(obj, part) == 0 ? 1 : 0; + list->text_line_space_zero = lv_obj_get_style_text_line_space(obj, part) == 0 ? 1 : 0; + list->transform_angle_zero = lv_obj_get_style_transform_angle(obj, part) == 0 ? 1 : 0; + list->transform_height_zero = lv_obj_get_style_transform_width(obj, part) == 0 ? 1 : 0; + list->transform_width_zero = lv_obj_get_style_transform_height(obj, part) == 0 ? 1 : 0; + list->transform_zoom_zero = lv_obj_get_style_transform_zoom(obj, part) == LV_IMG_ZOOM_NONE ? 1 : 0; + list->value_txt_str = lv_obj_get_style_value_str(obj, part) == NULL ? 1 : 0; + + list->ignore_cache = ignore_cache_ori; + list->valid_cache = 1; +} + +/** + * Mark the object and all of it's children's style lists as invalid. + * The cache will be updated when a cached property asked nest time + * @param obj pointer to an object + */ +void _lv_obj_invalidate_style_cache(lv_obj_t * obj) +{ + uint8_t part; + for(part = 0; part != _LV_OBJ_PART_REAL_LAST; part++) { + lv_style_list_t * list = lv_obj_get_style_list(obj, part); + if(list == NULL) break; + list->valid_cache = 0; + + } + + lv_obj_t * child = lv_obj_get_child(obj, NULL); + while(child) { + _lv_obj_invalidate_style_cache(child); + child = lv_obj_get_child(obj, child); + } +} + /*----------------- * Attribute set *----------------*/ @@ -2448,12 +2508,58 @@ lv_style_int_t _lv_obj_get_style_int(const lv_obj_t * obj, uint8_t part, lv_styl lv_res_t res = LV_RES_INV; const lv_obj_t * parent = obj; while(parent) { - lv_style_list_t * dsc = lv_obj_get_style_list(parent, part); + lv_style_list_t * list = lv_obj_get_style_list(parent, part); + + if(!list->ignore_cache) { + _lv_obj_update_style_cache((lv_obj_t*)parent, part); + bool def = false; + switch(prop & (~LV_STYLE_STATE_MASK)) { + case LV_STYLE_BG_GRAD_DIR: + if(list->bg_grad_dir_none) def = true; + break; + case LV_STYLE_CLIP_CORNER: + if(list->clip_corner_off) def = true; + break; + case LV_STYLE_TEXT_LETTER_SPACE: + if(list->text_letter_space_zero) def = true; + break; + case LV_STYLE_TEXT_LINE_SPACE: + if(list->text_line_space_zero) def = true; + break; + case LV_STYLE_TRANSFORM_ANGLE: + if(list->transform_angle_zero) def = true; + break; + case LV_STYLE_TRANSFORM_WIDTH: + if(list->transform_width_zero) def = true; + break; + case LV_STYLE_TRANSFORM_HEIGHT: + if(list->transform_height_zero) def = true; + break; + case LV_STYLE_TRANSFORM_ZOOM: + if(list->transform_zoom_zero) def = true; + break; + case LV_STYLE_BORDER_WIDTH: + if(list->border_width_zero) def = true; + break; + case LV_STYLE_LINE_WIDTH: + if(list->line_width_zerop) def = true; + break; + case LV_STYLE_OUTLINE_WIDTH: + if(list->outline_width_zero) def = true; + break; + case LV_STYLE_SHADOW_WIDTH: + if(list->shadow_width_zero) def = true; + break; + } + + if(def) break; + } + lv_state_t state = lv_obj_get_state(parent, part); prop = (uint16_t)prop_ori + ((uint16_t)state << LV_STYLE_STATE_POS); - res = _lv_style_list_get_int(dsc, prop, &value_act); + res = _lv_style_list_get_int(list, prop, &value_act); if(res == LV_RES_OK) return value_act; if(LV_STYLE_ATTR_GET_INHERIT(attr) == 0) break; @@ -2511,12 +2617,12 @@ lv_color_t _lv_obj_get_style_color(const lv_obj_t * obj, uint8_t part, lv_style_ lv_res_t res = LV_RES_INV; const lv_obj_t * parent = obj; while(parent) { - lv_style_list_t * dsc = lv_obj_get_style_list(parent, part); + lv_style_list_t * list = lv_obj_get_style_list(parent, part); lv_state_t state = lv_obj_get_state(parent, part); prop = (uint16_t)prop_ori + ((uint16_t)state << LV_STYLE_STATE_POS); - res = _lv_style_list_get_color(dsc, prop, &value_act); + res = _lv_style_list_get_color(list, prop, &value_act); if(res == LV_RES_OK) return value_act; if(LV_STYLE_ATTR_GET_INHERIT(attr) == 0) break; @@ -2567,12 +2673,31 @@ lv_opa_t _lv_obj_get_style_opa(const lv_obj_t * obj, uint8_t part, lv_style_prop lv_res_t res = LV_RES_INV; const lv_obj_t * parent = obj; while(parent) { - lv_style_list_t * dsc = lv_obj_get_style_list(parent, part); + lv_style_list_t * list = lv_obj_get_style_list(parent, part); + + + if(!list->ignore_cache) { + _lv_obj_update_style_cache((lv_obj_t*)parent, part); + bool def = false; + switch(prop & (~LV_STYLE_STATE_MASK)) { + case LV_STYLE_OPA_SCALE: + if(list->opa_scale_transp) def = true; + break; + case LV_STYLE_BG_OPA: + if(list->bg_opa_transp) def = true; + break; + case LV_STYLE_IMAGE_RECOLOR_OPA: + if(list->img_recolor_opa_transp) def = true; + break; + } + if(def) break; + } + lv_state_t state = lv_obj_get_state(parent, part); prop = (uint16_t)prop_ori + ((uint16_t)state << LV_STYLE_STATE_POS); - res = _lv_style_list_get_opa(dsc, prop, &value_act); + res = _lv_style_list_get_opa(list, prop, &value_act); if(res == LV_RES_OK) return value_act; if(LV_STYLE_ATTR_GET_INHERIT(attr) == 0) break; @@ -2624,12 +2749,27 @@ const void * _lv_obj_get_style_ptr(const lv_obj_t * obj, uint8_t part, lv_style_ lv_res_t res = LV_RES_INV; const lv_obj_t * parent = obj; while(parent) { - lv_style_list_t * dsc = lv_obj_get_style_list(parent, part); + lv_style_list_t * list = lv_obj_get_style_list(parent, part); + + if(!list->ignore_cache) { + bool def = false; + _lv_obj_update_style_cache((lv_obj_t*)parent, part); + switch(prop & (~LV_STYLE_STATE_MASK)) { + case LV_STYLE_VALUE_STR: + if(list->opa_scale_transp) def = true; + break; + case LV_STYLE_PATTERN_IMAGE: + if(list->pattern_img_null) def = true; + break; + } + + if(def) break; + } lv_state_t state = lv_obj_get_state(parent, part); prop = (uint16_t)prop_ori + ((uint16_t)state << LV_STYLE_STATE_POS); - res = _lv_style_list_get_ptr(dsc, prop, &value_act); + res = _lv_style_list_get_ptr(list, prop, &value_act); if(res == LV_RES_OK) return value_act; if(LV_STYLE_ATTR_GET_INHERIT(attr) == 0) break; @@ -3809,14 +3949,14 @@ static void refresh_children_position(lv_obj_t * obj, lv_coord_t x_diff, lv_coor */ static void report_style_mod_core(void * style, lv_obj_t * obj) { - uint8_t part_sub; - for(part_sub = 0; part_sub != _LV_OBJ_PART_REAL_LAST; part_sub++) { - lv_style_list_t * dsc = lv_obj_get_style_list(obj, part_sub); - if(dsc == NULL) break; + uint8_t part; + for(part = 0; part != _LV_OBJ_PART_REAL_LAST; part++) { + lv_style_list_t * list = lv_obj_get_style_list(obj, part); + if(list == NULL) break; uint8_t ci; - for(ci = 0; ci < dsc->style_cnt; ci++) { - lv_style_t * class = lv_style_list_get_style(dsc, ci); + for(ci = 0; ci < list->style_cnt; ci++) { + lv_style_t * class = lv_style_list_get_style(list, ci); if(class == style || style == NULL) { lv_obj_refresh_style(obj, LV_STYLE_PROP_ALL); break; diff --git a/src/lv_core/lv_obj.h b/src/lv_core/lv_obj.h index 9815d3b9b..06d2bc070 100644 --- a/src/lv_core/lv_obj.h +++ b/src/lv_core/lv_obj.h @@ -595,6 +595,20 @@ void lv_obj_refresh_style(lv_obj_t * obj, lv_style_property_t prop); */ void lv_obj_report_style_mod(lv_style_t * style); +/** + * Update the cache of style list + * @param obj pointer to an obejct + * @param part the part of the object + */ +void _lv_obj_update_style_cache(lv_obj_t * obj, uint8_t part); + +/** + * Mark the object and all of it's children's style lists as invalid. + * The cache will be updated when a cached property asked nest time + * @param obj pointer to an object + */ +void _lv_obj_invalidate_style_cache(lv_obj_t * obj); + /** * Set a local style property of a part of an object in a given state. * @param obj pointer to an object diff --git a/src/lv_core/lv_style.c b/src/lv_core/lv_style.c index ce3665e0d..7428ac731 100644 --- a/src/lv_core/lv_style.c +++ b/src/lv_core/lv_style.c @@ -1052,6 +1052,9 @@ bool lv_debug_check_style_list(const lv_style_list_t * list) */ LV_ATTRIBUTE_FAST_MEM static inline int32_t get_property_index(const lv_style_t * style, lv_style_property_t prop) { + static uint32_t c = 0; + c++; + if(c % 100 == 0) printf("%d\n", c); LV_ASSERT_STYLE(style); if(style->map == NULL) return -1; diff --git a/src/lv_core/lv_style.h b/src/lv_core/lv_style.h index 5909299b6..391c17459 100644 --- a/src/lv_core/lv_style.h +++ b/src/lv_core/lv_style.h @@ -221,11 +221,32 @@ typedef struct { #if LV_USE_ASSERT_STYLE uint32_t sentinel; #endif - uint8_t style_cnt; - uint8_t has_local : 1; - uint8_t has_trans : 1; - uint8_t skip_trans : 1; /*1: Temporally skip the transition style if any*/ - uint8_t ignore_trans : 1; /*1: Mark that this style list shouldn't receive transitions at all*/ + uint32_t style_cnt :7; + uint32_t has_local :1; + uint32_t has_trans :1; + uint32_t skip_trans :1; /*1: Temporally skip the transition style if any*/ + uint32_t ignore_trans :1; /*1: Mark that this style list shouldn't receive transitions at all*/ + uint32_t ignore_cache :1; /*1: Ignore cache while getting value of properties*/ + uint32_t valid_cache :1; /*1: The cache is invalid and needs to be updated*/ + + uint32_t opa_scale_transp :1; + uint32_t clip_corner_off :1; + uint32_t transform_width_zero :1; + uint32_t transform_height_zero :1; + uint32_t transform_angle_zero :1; + uint32_t transform_zoom_zero :1; + uint32_t bg_opa_transp :1; + uint32_t bg_grad_dir_none :1; + uint32_t border_width_zero :1; + uint32_t outline_width_zero :1; + uint32_t pattern_img_null :1; + uint32_t shadow_width_zero :1; + uint32_t value_txt_str :1; + uint32_t line_width_zerop :1; + uint32_t img_recolor_opa_transp :1; + uint32_t text_letter_space_zero :1; + uint32_t text_line_space_zero :1; + uint32_t text_decor_none :1; } lv_style_list_t; /********************** From 11cab40103e781c01ad8f2503473de58ed292dd3 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Sun, 2 Aug 2020 11:36:27 +0200 Subject: [PATCH 2/7] import style caching --- src/lv_core/lv_obj.c | 218 ++++++++++++++++++++---------- src/lv_core/lv_obj.h | 16 +-- src/lv_core/lv_style.h | 4 +- src/lv_themes/lv_theme_material.c | 2 +- src/lv_themes/lv_theme_mono.c | 2 +- src/lv_themes/lv_theme_template.c | 2 +- src/lv_widgets/lv_arc.c | 2 +- src/lv_widgets/lv_bar.c | 2 +- src/lv_widgets/lv_btn.c | 2 +- src/lv_widgets/lv_btnmatrix.c | 6 + src/lv_widgets/lv_calendar.c | 5 + src/lv_widgets/lv_chart.c | 2 +- src/lv_widgets/lv_cont.c | 2 +- src/lv_widgets/lv_cpicker.c | 2 +- src/lv_widgets/lv_dropdown.c | 18 ++- src/lv_widgets/lv_gauge.c | 2 +- src/lv_widgets/lv_img.c | 2 +- src/lv_widgets/lv_imgbtn.c | 2 +- src/lv_widgets/lv_label.c | 2 +- src/lv_widgets/lv_led.c | 2 +- src/lv_widgets/lv_line.c | 2 +- src/lv_widgets/lv_linemeter.c | 2 +- src/lv_widgets/lv_list.c | 2 +- src/lv_widgets/lv_msgbox.c | 2 +- src/lv_widgets/lv_objmask.c | 2 +- src/lv_widgets/lv_roller.c | 2 +- src/lv_widgets/lv_slider.c | 2 +- src/lv_widgets/lv_spinbox.c | 2 +- src/lv_widgets/lv_spinner.c | 2 +- src/lv_widgets/lv_switch.c | 2 +- src/lv_widgets/lv_table.c | 2 +- src/lv_widgets/lv_tabview.c | 4 +- src/lv_widgets/lv_textarea.c | 2 +- src/lv_widgets/lv_tileview.c | 2 +- src/lv_widgets/lv_win.c | 2 +- 35 files changed, 199 insertions(+), 128 deletions(-) diff --git a/src/lv_core/lv_obj.c b/src/lv_core/lv_obj.c index ec443efd3..88474cd0b 100644 --- a/src/lv_core/lv_obj.c +++ b/src/lv_core/lv_obj.c @@ -103,7 +103,9 @@ static void lv_event_mark_deleted(lv_obj_t * obj); static bool obj_valid_child(const lv_obj_t * parent, const lv_obj_t * obj_to_find); static void lv_obj_del_async_cb(void * obj); static void obj_del_core(lv_obj_t * obj); - +static void update_style_cache(lv_obj_t * obj, uint8_t part, uint16_t prop); +static void update_style_cache_children(lv_obj_t * obj); +static void invalidate_style_cache(lv_obj_t * obj, uint8_t part); /********************** * STATIC VARIABLES **********************/ @@ -1120,7 +1122,7 @@ void lv_obj_add_style(lv_obj_t * obj, uint8_t part, lv_style_t * style) #if LV_USE_ANIMATION trans_del(obj, part, 0xFF, NULL); #endif - lv_obj_refresh_style(obj, LV_STYLE_PROP_ALL); + lv_obj_refresh_style(obj, part, LV_STYLE_PROP_ALL); } /** @@ -1144,7 +1146,7 @@ void lv_obj_remove_style(lv_obj_t * obj, uint8_t part, lv_style_t * style) #if LV_USE_ANIMATION trans_del(obj, part, 0xFF, NULL); #endif - lv_obj_refresh_style(obj, LV_STYLE_PROP_ALL); + lv_obj_refresh_style(obj, part, LV_STYLE_PROP_ALL); } /** @@ -1181,7 +1183,7 @@ void lv_obj_reset_style_list(lv_obj_t * obj, uint8_t part) { lv_obj_clean_style_list(obj, part); - lv_obj_refresh_style(obj, LV_STYLE_PROP_ALL); + lv_obj_refresh_style(obj, part, LV_STYLE_PROP_ALL); } /** @@ -1203,7 +1205,7 @@ void _lv_obj_set_style_local_int(lv_obj_t * obj, uint8_t part, lv_style_property #if LV_USE_ANIMATION trans_del(obj, part, prop, NULL); #endif - lv_obj_refresh_style(obj, prop & (~LV_STYLE_STATE_MASK)); + lv_obj_refresh_style(obj, part, prop & (~LV_STYLE_STATE_MASK)); } /** @@ -1225,7 +1227,7 @@ void _lv_obj_set_style_local_color(lv_obj_t * obj, uint8_t part, lv_style_proper #if LV_USE_ANIMATION trans_del(obj, part, prop, NULL); #endif - lv_obj_refresh_style(obj, prop & (~LV_STYLE_STATE_MASK)); + lv_obj_refresh_style(obj, part, prop & (~LV_STYLE_STATE_MASK)); } /** @@ -1247,7 +1249,7 @@ void _lv_obj_set_style_local_opa(lv_obj_t * obj, uint8_t part, lv_style_property #if LV_USE_ANIMATION trans_del(obj, part, prop, NULL); #endif - lv_obj_refresh_style(obj, prop & (~LV_STYLE_STATE_MASK)); + lv_obj_refresh_style(obj, part, prop & (~LV_STYLE_STATE_MASK)); } /** @@ -1269,7 +1271,7 @@ void _lv_obj_set_style_local_ptr(lv_obj_t * obj, uint8_t part, lv_style_property #if LV_USE_ANIMATION trans_del(obj, part, prop, NULL); #endif - lv_obj_refresh_style(obj, prop & (~LV_STYLE_STATE_MASK)); + lv_obj_refresh_style(obj, part, prop & (~LV_STYLE_STATE_MASK)); } /** @@ -1296,11 +1298,11 @@ bool lv_obj_remove_style_local_prop(lv_obj_t * obj, uint8_t part, lv_style_prope * @param obj pointer to an object * @param prop `LV_STYLE_PROP_ALL` or an `LV_STYLE_...` property. It is used to optimize what needs to be refreshed. */ -void lv_obj_refresh_style(lv_obj_t * obj, lv_style_property_t prop) +void lv_obj_refresh_style(lv_obj_t * obj, uint8_t part, lv_style_property_t prop) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); - _lv_obj_invalidate_style_cache(obj); + invalidate_style_cache(obj, part); /*If a real style refresh is required*/ bool real_refr = false; @@ -1390,63 +1392,6 @@ void lv_obj_report_style_mod(lv_style_t * style) } -/** - * Update the cache of style list - * @param obj pointer to an obejct - * @param part the part of the object - */ -void _lv_obj_update_style_cache(lv_obj_t * obj, uint8_t part) -{ - lv_style_list_t * list = lv_obj_get_style_list(obj, part); - if(list->valid_cache) return; - - bool ignore_cache_ori = list->ignore_cache; - list->ignore_cache = 1; - list->bg_grad_dir_none = lv_obj_get_style_bg_grad_dir(obj, part) == LV_GRAD_DIR_NONE ? 1 : 0; - list->bg_opa_transp = lv_obj_get_style_bg_opa(obj, part) == LV_OPA_TRANSP ? 1 : 0; - list->border_width_zero = lv_obj_get_style_border_width(obj, part) == LV_OPA_TRANSP ? 1 : 0; - list->clip_corner_off = lv_obj_get_style_clip_corner(obj, part) == false ? 1 : 0; - list->img_recolor_opa_transp = lv_obj_get_style_image_recolor_opa(obj, part) == LV_OPA_TRANSP ? 1 : 0; - list->line_width_zerop = lv_obj_get_style_line_width(obj, part) == 0 ? 1 : 0; - list->opa_scale_transp = lv_obj_get_style_opa_scale(obj, part) == LV_OPA_TRANSP ? 1 : 0; - list->outline_width_zero = lv_obj_get_style_outline_width(obj, part) == 0 ? 1 : 0; - list->pattern_img_null = lv_obj_get_style_pattern_image(obj, part) == NULL ? 1 : 0; - list->shadow_width_zero = lv_obj_get_style_shadow_width(obj, part) == 0 ? 1 : 0; - list->text_decor_none = lv_obj_get_style_text_decor(obj, part) == LV_TEXT_DECOR_NONE ? 1 : 0; - list->text_letter_space_zero = lv_obj_get_style_text_letter_space(obj, part) == 0 ? 1 : 0; - list->text_line_space_zero = lv_obj_get_style_text_line_space(obj, part) == 0 ? 1 : 0; - list->transform_angle_zero = lv_obj_get_style_transform_angle(obj, part) == 0 ? 1 : 0; - list->transform_height_zero = lv_obj_get_style_transform_width(obj, part) == 0 ? 1 : 0; - list->transform_width_zero = lv_obj_get_style_transform_height(obj, part) == 0 ? 1 : 0; - list->transform_zoom_zero = lv_obj_get_style_transform_zoom(obj, part) == LV_IMG_ZOOM_NONE ? 1 : 0; - list->value_txt_str = lv_obj_get_style_value_str(obj, part) == NULL ? 1 : 0; - - list->ignore_cache = ignore_cache_ori; - list->valid_cache = 1; -} - -/** - * Mark the object and all of it's children's style lists as invalid. - * The cache will be updated when a cached property asked nest time - * @param obj pointer to an object - */ -void _lv_obj_invalidate_style_cache(lv_obj_t * obj) -{ - uint8_t part; - for(part = 0; part != _LV_OBJ_PART_REAL_LAST; part++) { - lv_style_list_t * list = lv_obj_get_style_list(obj, part); - if(list == NULL) break; - list->valid_cache = 0; - - } - - lv_obj_t * child = lv_obj_get_child(obj, NULL); - while(child) { - _lv_obj_invalidate_style_cache(child); - child = lv_obj_get_child(obj, child); - } -} - /*----------------- * Attribute set *----------------*/ @@ -1720,10 +1665,10 @@ void lv_obj_set_state(lv_obj_t * obj, lv_state_t new_state) } } + lv_obj_refresh_style(obj, part, LV_STYLE_PROP_ALL); } #endif - lv_obj_refresh_style(obj, LV_STYLE_PROP_ALL); } @@ -2511,7 +2456,8 @@ lv_style_int_t _lv_obj_get_style_int(const lv_obj_t * obj, uint8_t part, lv_styl lv_style_list_t * list = lv_obj_get_style_list(parent, part); if(!list->ignore_cache) { - _lv_obj_update_style_cache((lv_obj_t*)parent, part); + if(!list->valid_cache) update_style_cache((lv_obj_t*)parent, part, prop & (~LV_STYLE_STATE_MASK)); + bool def = false; switch(prop & (~LV_STYLE_STATE_MASK)) { case LV_STYLE_BG_GRAD_DIR: @@ -2555,7 +2501,6 @@ lv_style_int_t _lv_obj_get_style_int(const lv_obj_t * obj, uint8_t part, lv_styl if(def) break; } - lv_state_t state = lv_obj_get_state(parent, part); prop = (uint16_t)prop_ori + ((uint16_t)state << LV_STYLE_STATE_POS); @@ -2675,9 +2620,8 @@ lv_opa_t _lv_obj_get_style_opa(const lv_obj_t * obj, uint8_t part, lv_style_prop while(parent) { lv_style_list_t * list = lv_obj_get_style_list(parent, part); - if(!list->ignore_cache) { - _lv_obj_update_style_cache((lv_obj_t*)parent, part); + if(!list->valid_cache) update_style_cache((lv_obj_t*)parent, part, prop & (~LV_STYLE_STATE_MASK)); bool def = false; switch(prop & (~LV_STYLE_STATE_MASK)) { case LV_STYLE_OPA_SCALE: @@ -2752,8 +2696,8 @@ const void * _lv_obj_get_style_ptr(const lv_obj_t * obj, uint8_t part, lv_style_ lv_style_list_t * list = lv_obj_get_style_list(parent, part); if(!list->ignore_cache) { + if(!list->valid_cache) update_style_cache((lv_obj_t*)parent, part, prop & (~LV_STYLE_STATE_MASK)); bool def = false; - _lv_obj_update_style_cache((lv_obj_t*)parent, part); switch(prop & (~LV_STYLE_STATE_MASK)) { case LV_STYLE_VALUE_STR: if(list->opa_scale_transp) def = true; @@ -3958,7 +3902,7 @@ static void report_style_mod_core(void * style, lv_obj_t * obj) for(ci = 0; ci < list->style_cnt; ci++) { lv_style_t * class = lv_style_list_get_style(list, ci); if(class == style || style == NULL) { - lv_obj_refresh_style(obj, LV_STYLE_PROP_ALL); + lv_obj_refresh_style(obj, part, LV_STYLE_PROP_ALL); break; } } @@ -4339,7 +4283,7 @@ static void trans_anim_cb(lv_style_trans_t * tr, lv_anim_value_t v) else x = tr->end_value._ptr; _lv_style_set_ptr(style, tr->prop, x); } - lv_obj_refresh_style(tr->obj, tr->prop); + lv_obj_refresh_style(tr->obj, tr->part, tr->prop); } @@ -4434,3 +4378,127 @@ static bool obj_valid_child(const lv_obj_t * parent, const lv_obj_t * obj_to_fin return false; } + +/** + * Update the cache of style list + * @param obj pointer to an obejct + * @param part the part of the object + * @param prop the property which triggered the update + */ +static void update_style_cache(lv_obj_t * obj, uint8_t part, uint16_t prop) +{ + + bool cachable; + switch(prop) { + case LV_STYLE_BG_GRAD_DIR: + case LV_STYLE_CLIP_CORNER: + case LV_STYLE_TEXT_LETTER_SPACE: + case LV_STYLE_TEXT_LINE_SPACE: + case LV_STYLE_TRANSFORM_ANGLE: + case LV_STYLE_TRANSFORM_WIDTH: + case LV_STYLE_TRANSFORM_HEIGHT: + case LV_STYLE_TRANSFORM_ZOOM: + case LV_STYLE_BORDER_WIDTH: + case LV_STYLE_LINE_WIDTH: + case LV_STYLE_OUTLINE_WIDTH: + case LV_STYLE_SHADOW_WIDTH: + case LV_STYLE_OPA_SCALE: + case LV_STYLE_BG_OPA: + case LV_STYLE_IMAGE_RECOLOR_OPA: + case LV_STYLE_VALUE_STR: + case LV_STYLE_PATTERN_IMAGE: + cachable = true; + break; + default: + cachable = false; + } + + if(!cachable) return; + + lv_style_list_t * list = lv_obj_get_style_list(obj, part); + + bool ignore_cache_ori = list->ignore_cache; + list->ignore_cache = 1; + + list->opa_scale_transp = lv_obj_get_style_opa_scale(obj, part) == LV_OPA_TRANSP ? 1 : 0; + list->text_decor_none = lv_obj_get_style_text_decor(obj, part) == LV_TEXT_DECOR_NONE ? 1 : 0; + list->text_letter_space_zero = lv_obj_get_style_text_letter_space(obj, part) == 0 ? 1 : 0; + list->text_line_space_zero = lv_obj_get_style_text_line_space(obj, part) == 0 ? 1 : 0; + + list->bg_grad_dir_none = lv_obj_get_style_bg_grad_dir(obj, part) == LV_GRAD_DIR_NONE ? 1 : 0; + list->bg_opa_transp = lv_obj_get_style_bg_opa(obj, part) == LV_OPA_TRANSP ? 1 : 0; + list->border_width_zero = lv_obj_get_style_border_width(obj, part) == LV_OPA_TRANSP ? 1 : 0; + list->clip_corner_off = lv_obj_get_style_clip_corner(obj, part) == false ? 1 : 0; + list->img_recolor_opa_transp = lv_obj_get_style_image_recolor_opa(obj, part) == LV_OPA_TRANSP ? 1 : 0; + list->line_width_zerop = lv_obj_get_style_line_width(obj, part) == 0 ? 1 : 0; + list->outline_width_zero = lv_obj_get_style_outline_width(obj, part) == 0 ? 1 : 0; + list->pattern_img_null = lv_obj_get_style_pattern_image(obj, part) == NULL ? 1 : 0; + list->shadow_width_zero = lv_obj_get_style_shadow_width(obj, part) == 0 ? 1 : 0; + list->transform_angle_zero = lv_obj_get_style_transform_angle(obj, part) == 0 ? 1 : 0; + list->transform_height_zero = lv_obj_get_style_transform_width(obj, part) == 0 ? 1 : 0; + list->transform_width_zero = lv_obj_get_style_transform_height(obj, part) == 0 ? 1 : 0; + list->transform_zoom_zero = lv_obj_get_style_transform_zoom(obj, part) == LV_IMG_ZOOM_NONE ? 1 : 0; + list->value_txt_str = lv_obj_get_style_value_str(obj, part) == NULL ? 1 : 0; + + list->ignore_cache = ignore_cache_ori; + list->valid_cache = 1; +} + +void _lv_obj_disable_style_cahcing(lv_obj_t * obj, bool dis) +{ + uint8_t part; + for(part = 0; part < _LV_OBJ_PART_REAL_FIRST; part++) { + lv_style_list_t * list = lv_obj_get_style_list(obj, part); + if(list == NULL) break; + list->ignore_cache = dis; + } + for(part = _LV_OBJ_PART_REAL_FIRST; part < 0xFF; part++) { + lv_style_list_t * list = lv_obj_get_style_list(obj, part); + if(list == NULL) break; + list->ignore_cache = dis; + } +} + +/** + * Update the cache of style list + * @param obj pointer to an object + * @param part the part of the object + */ +static void update_style_cache_children(lv_obj_t * obj) +{ + uint8_t part; + for(part = 0; part != _LV_OBJ_PART_REAL_LAST; part++) { + lv_style_list_t * list = lv_obj_get_style_list(obj, part); + if(list == NULL) break; + + bool ignore_cache_ori = list->ignore_cache; + list->ignore_cache = 1; + + list->opa_scale_transp = lv_obj_get_style_opa_scale(obj, part) == LV_OPA_TRANSP ? 1 : 0; + list->text_decor_none = lv_obj_get_style_text_decor(obj, part) == LV_TEXT_DECOR_NONE ? 1 : 0; + list->text_letter_space_zero = lv_obj_get_style_text_letter_space(obj, part) == 0 ? 1 : 0; + list->text_line_space_zero = lv_obj_get_style_text_line_space(obj, part) == 0 ? 1 : 0; + list->img_recolor_opa_transp = lv_obj_get_style_image_recolor_opa(obj, part) == LV_OPA_TRANSP ? 1 : 0; + + list->ignore_cache = ignore_cache_ori; + } +} + +/** + * Mark the object and all of it's children's style lists as invalid. + * The cache will be updated when a cached property asked nest time + * @param obj pointer to an object + */ +static void invalidate_style_cache(lv_obj_t * obj, uint8_t part) +{ + lv_style_list_t * list = lv_obj_get_style_list(obj, part); + if(list == NULL) return; + list->valid_cache = 0; + + lv_obj_t * child = lv_obj_get_child(obj, NULL); + while(child) { + update_style_cache_children(child); + child = lv_obj_get_child(obj, child); + } +} + diff --git a/src/lv_core/lv_obj.h b/src/lv_core/lv_obj.h index 06d2bc070..c5f9b0cd4 100644 --- a/src/lv_core/lv_obj.h +++ b/src/lv_core/lv_obj.h @@ -586,7 +586,7 @@ void lv_obj_reset_style_list(lv_obj_t * obj, uint8_t part); * @param obj pointer to an object * @param prop `LV_STYLE_PROP_ALL` or an `LV_STYLE_...` property. It is used to optimize what needs to be refreshed. */ -void lv_obj_refresh_style(lv_obj_t * obj, lv_style_property_t prop); +void lv_obj_refresh_style(lv_obj_t * obj, uint8_t part, lv_style_property_t prop); /** * Notify all object if a style is modified @@ -595,20 +595,6 @@ void lv_obj_refresh_style(lv_obj_t * obj, lv_style_property_t prop); */ void lv_obj_report_style_mod(lv_style_t * style); -/** - * Update the cache of style list - * @param obj pointer to an obejct - * @param part the part of the object - */ -void _lv_obj_update_style_cache(lv_obj_t * obj, uint8_t part); - -/** - * Mark the object and all of it's children's style lists as invalid. - * The cache will be updated when a cached property asked nest time - * @param obj pointer to an object - */ -void _lv_obj_invalidate_style_cache(lv_obj_t * obj); - /** * Set a local style property of a part of an object in a given state. * @param obj pointer to an object diff --git a/src/lv_core/lv_style.h b/src/lv_core/lv_style.h index 391c17459..0db481ec8 100644 --- a/src/lv_core/lv_style.h +++ b/src/lv_core/lv_style.h @@ -226,8 +226,8 @@ typedef struct { uint32_t has_trans :1; uint32_t skip_trans :1; /*1: Temporally skip the transition style if any*/ uint32_t ignore_trans :1; /*1: Mark that this style list shouldn't receive transitions at all*/ - uint32_t ignore_cache :1; /*1: Ignore cache while getting value of properties*/ - uint32_t valid_cache :1; /*1: The cache is invalid and needs to be updated*/ + uint32_t valid_cache :1; /*1: The cache is invalid and needs to be updated*/ + uint8_t ignore_cache :1; /**1: Ignore style cache while getting value of properties*/ uint32_t opa_scale_transp :1; uint32_t clip_corner_off :1; diff --git a/src/lv_themes/lv_theme_material.c b/src/lv_themes/lv_theme_material.c index 1aa9fe580..031cd2a06 100644 --- a/src/lv_themes/lv_theme_material.c +++ b/src/lv_themes/lv_theme_material.c @@ -1366,7 +1366,7 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj, lv_theme_style_t name) break; } - lv_obj_refresh_style(obj, LV_STYLE_PROP_ALL); + lv_obj_refresh_style(obj, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL); } /********************** diff --git a/src/lv_themes/lv_theme_mono.c b/src/lv_themes/lv_theme_mono.c index ba5357088..e9f0f9015 100644 --- a/src/lv_themes/lv_theme_mono.c +++ b/src/lv_themes/lv_theme_mono.c @@ -1023,7 +1023,7 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj, lv_theme_style_t name) } - lv_obj_refresh_style(obj, LV_STYLE_PROP_ALL); + lv_obj_refresh_style(obj, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL); } diff --git a/src/lv_themes/lv_theme_template.c b/src/lv_themes/lv_theme_template.c index 2a22fad4e..722e72e07 100644 --- a/src/lv_themes/lv_theme_template.c +++ b/src/lv_themes/lv_theme_template.c @@ -855,7 +855,7 @@ void theme_apply(lv_theme_t * th, lv_obj_t * obj, lv_theme_style_t name) break; } - lv_obj_refresh_style(obj, LV_STYLE_PROP_ALL); + lv_obj_refresh_style(obj, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL); } /********************** diff --git a/src/lv_widgets/lv_arc.c b/src/lv_widgets/lv_arc.c index 4dd7d9f45..f7cf087f1 100644 --- a/src/lv_widgets/lv_arc.c +++ b/src/lv_widgets/lv_arc.c @@ -101,7 +101,7 @@ lv_obj_t * lv_arc_create(lv_obj_t * par, const lv_obj_t * copy) lv_style_list_copy(&ext->style_arc, ©_ext->style_arc); /*Refresh the style with new signal function*/ - lv_obj_refresh_style(arc, LV_STYLE_PROP_ALL); + lv_obj_refresh_style(arc, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL); } LV_LOG_INFO("arc created"); diff --git a/src/lv_widgets/lv_bar.c b/src/lv_widgets/lv_bar.c index f76a2e13f..f787e2680 100644 --- a/src/lv_widgets/lv_bar.c +++ b/src/lv_widgets/lv_bar.c @@ -130,7 +130,7 @@ lv_obj_t * lv_bar_create(lv_obj_t * par, const lv_obj_t * copy) lv_style_list_copy(&ext->style_indic, &ext_copy->style_indic); /*Refresh the style with new signal function*/ - lv_obj_refresh_style(bar, LV_STYLE_PROP_ALL); + lv_obj_refresh_style(bar, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL); lv_bar_set_value(bar, ext->cur_value, LV_ANIM_OFF); } diff --git a/src/lv_widgets/lv_btn.c b/src/lv_widgets/lv_btn.c index fa327bd6e..3d5556083 100644 --- a/src/lv_widgets/lv_btn.c +++ b/src/lv_widgets/lv_btn.c @@ -100,7 +100,7 @@ lv_obj_t * lv_btn_create(lv_obj_t * par, const lv_obj_t * copy) ext->checkable = copy_ext->checkable; /*Refresh the style with new signal function*/ - lv_obj_refresh_style(btn, LV_STYLE_PROP_ALL); + lv_obj_refresh_style(btn, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL); } LV_LOG_INFO("button created"); diff --git a/src/lv_widgets/lv_btnmatrix.c b/src/lv_widgets/lv_btnmatrix.c index 5501fcfa6..f604cb10f 100644 --- a/src/lv_widgets/lv_btnmatrix.c +++ b/src/lv_widgets/lv_btnmatrix.c @@ -660,6 +660,7 @@ static lv_design_res_t lv_btnmatrix_design(lv_obj_t * btnm, const lv_area_t * cl /*The state changes without re-caching the styles, disable the use of cache*/ lv_state_t state_ori = btnm->state; + _lv_obj_disable_style_cahcing(btnm, true); btnm->state = LV_STATE_DEFAULT; lv_draw_rect_dsc_init(&draw_rect_rel_dsc); lv_draw_label_dsc_init(&draw_label_rel_dsc); @@ -667,6 +668,7 @@ static lv_design_res_t lv_btnmatrix_design(lv_obj_t * btnm, const lv_area_t * cl lv_obj_init_draw_label_dsc(btnm, LV_BTNMATRIX_PART_BTN, &draw_label_rel_dsc); draw_label_rel_dsc.flag = txt_flag; btnm->state = state_ori; + _lv_obj_disable_style_cahcing(btnm, false); bool chk_inited = false; bool disabled_inited = false; @@ -700,12 +702,14 @@ static lv_design_res_t lv_btnmatrix_design(lv_obj_t * btnm, const lv_area_t * cl if(tgl_state) { if(!chk_inited) { btnm->state = LV_STATE_CHECKED; + _lv_obj_disable_style_cahcing(btnm, true); lv_draw_rect_dsc_init(&draw_rect_chk_dsc); lv_draw_label_dsc_init(&draw_label_chk_dsc); lv_obj_init_draw_rect_dsc(btnm, LV_BTNMATRIX_PART_BTN, &draw_rect_chk_dsc); lv_obj_init_draw_label_dsc(btnm, LV_BTNMATRIX_PART_BTN, &draw_label_chk_dsc); draw_label_chk_dsc.flag = txt_flag; btnm->state = state_ori; + _lv_obj_disable_style_cahcing(btnm, false); chk_inited = true; } } @@ -713,12 +717,14 @@ static lv_design_res_t lv_btnmatrix_design(lv_obj_t * btnm, const lv_area_t * cl if(button_is_inactive(ext->ctrl_bits[btn_i])) { if(!disabled_inited) { btnm->state = LV_STATE_DISABLED; + _lv_obj_disable_style_cahcing(btnm, true); lv_draw_rect_dsc_init(&draw_rect_ina_dsc); lv_draw_label_dsc_init(&draw_label_ina_dsc); lv_obj_init_draw_rect_dsc(btnm, LV_BTNMATRIX_PART_BTN, &draw_rect_ina_dsc); lv_obj_init_draw_label_dsc(btnm, LV_BTNMATRIX_PART_BTN, &draw_label_ina_dsc); draw_label_ina_dsc.flag = txt_flag; btnm->state = state_ori; + _lv_obj_disable_style_cahcing(btnm, false); disabled_inited = true; } draw_rect_dsc_act = &draw_rect_ina_dsc; diff --git a/src/lv_widgets/lv_calendar.c b/src/lv_widgets/lv_calendar.c index 9936b624b..ab9835007 100644 --- a/src/lv_widgets/lv_calendar.c +++ b/src/lv_widgets/lv_calendar.c @@ -705,6 +705,7 @@ static void draw_header(lv_obj_t * calendar, const lv_area_t * mask) strcpy(&txt_buf[5], get_month_name(calendar, ext->showed_date.month)); calendar->state = LV_STATE_DEFAULT; + _lv_obj_disable_style_cahcing(calendar, true); lv_draw_label_dsc_t label_dsc; lv_draw_label_dsc_init(&label_dsc); @@ -738,6 +739,7 @@ static void draw_header(lv_obj_t * calendar, const lv_area_t * mask) lv_draw_label(&header_area, mask, &label_dsc, LV_SYMBOL_RIGHT, NULL); calendar->state = state_ori; /*Restore the state*/ + _lv_obj_disable_style_cahcing(calendar, false); } /** @@ -810,6 +812,7 @@ static void draw_dates(lv_obj_t * calendar, const lv_area_t * clip_area) /*The state changes without re-caching the styles, disable the use of cache*/ lv_state_t state_ori = calendar->state; calendar->state = LV_STATE_DEFAULT; + _lv_obj_disable_style_cahcing(calendar, true); lv_state_t month_state = LV_STATE_DISABLED; @@ -856,6 +859,7 @@ static void draw_dates(lv_obj_t * calendar, const lv_area_t * clip_area) if(box_area.y1 > clip_area->y2) { calendar->state = state_ori; + _lv_obj_disable_style_cahcing(calendar, false); return; } @@ -926,6 +930,7 @@ static void draw_dates(lv_obj_t * calendar, const lv_area_t * clip_area) } } calendar->state = state_ori; + _lv_obj_disable_style_cahcing(calendar, false); } diff --git a/src/lv_widgets/lv_chart.c b/src/lv_widgets/lv_chart.c index d7308cf88..75d0a146c 100644 --- a/src/lv_widgets/lv_chart.c +++ b/src/lv_widgets/lv_chart.c @@ -152,7 +152,7 @@ lv_obj_t * lv_chart_create(lv_obj_t * par, const lv_obj_t * copy) _lv_memcpy(&ext->secondary_y_axis, &ext_copy->secondary_y_axis, sizeof(lv_chart_axis_cfg_t)); /*Refresh the style with new signal function*/ - lv_obj_refresh_style(chart, LV_STYLE_PROP_ALL); + lv_obj_refresh_style(chart, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL); } LV_LOG_INFO("chart created"); diff --git a/src/lv_widgets/lv_cont.c b/src/lv_widgets/lv_cont.c index ffb716832..04a81343e 100644 --- a/src/lv_widgets/lv_cont.c +++ b/src/lv_widgets/lv_cont.c @@ -112,7 +112,7 @@ lv_obj_t * lv_cont_create(lv_obj_t * par, const lv_obj_t * copy) ext->layout = copy_ext->layout; /*Refresh the style with new signal function*/ - lv_obj_refresh_style(cont, LV_STYLE_PROP_ALL); + lv_obj_refresh_style(cont, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL); } LV_LOG_INFO("container created"); diff --git a/src/lv_widgets/lv_cpicker.c b/src/lv_widgets/lv_cpicker.c index d80c9a56c..bc46ffcc4 100644 --- a/src/lv_widgets/lv_cpicker.c +++ b/src/lv_widgets/lv_cpicker.c @@ -144,7 +144,7 @@ lv_obj_t * lv_cpicker_create(lv_obj_t * par, const lv_obj_t * copy) lv_style_list_copy(&ext->knob.style_list, ©_ext->knob.style_list); /*Refresh the style with new signal function*/ - lv_obj_refresh_style(cpicker, LV_STYLE_PROP_ALL); + lv_obj_refresh_style(cpicker, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL); } refr_knob_pos(cpicker); diff --git a/src/lv_widgets/lv_dropdown.c b/src/lv_widgets/lv_dropdown.c index c7bbd8746..09c073318 100644 --- a/src/lv_widgets/lv_dropdown.c +++ b/src/lv_widgets/lv_dropdown.c @@ -609,7 +609,7 @@ void lv_dropdown_open(lv_obj_t * ddlist) lv_style_list_copy(lv_obj_get_style_list(ext->page, LV_PAGE_PART_BG), &ext->style_page); lv_style_list_copy(lv_obj_get_style_list(ext->page, LV_PAGE_PART_SCROLLBAR), &ext->style_scrlbar); lv_obj_clean_style_list(ext->page, LV_PAGE_PART_SCROLLABLE); - lv_obj_refresh_style(ext->page, LV_STYLE_PROP_ALL); + lv_obj_refresh_style(ext->page, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL); lv_obj_t * label = lv_label_create(ext->page, NULL); lv_label_set_text_static(label, ext->options); @@ -965,7 +965,7 @@ static lv_res_t lv_dropdown_signal(lv_obj_t * ddlist, lv_signal_t sign, void * p const lv_font_t * font = lv_obj_get_style_text_font(ddlist, LV_DROPDOWN_PART_MAIN); lv_obj_set_height(ddlist, top + bottom + lv_font_get_line_height(font)); - if(ext->page) lv_obj_refresh_style(ext->page, LV_STYLE_PROP_ALL); + if(ext->page) lv_obj_refresh_style(ext->page, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL); } else if(sign == LV_SIGNAL_CONTROL) { #if LV_USE_GROUP @@ -1134,8 +1134,10 @@ static void draw_box(lv_obj_t * ddlist, const lv_area_t * clip_area, uint16_t id lv_obj_t * page = ext->page; lv_state_t state_orig = page->state; - page->state = LV_STATE_DEFAULT; - page->state |= state; + if(state != page->state) { + _lv_obj_disable_style_cahcing(ddlist, true); + page->state = state; + } /*Draw a rectangle under the selected item*/ const lv_font_t * font = lv_obj_get_style_text_font(ddlist, LV_DROPDOWN_PART_LIST); @@ -1159,6 +1161,7 @@ static void draw_box(lv_obj_t * ddlist, const lv_area_t * clip_area, uint16_t id lv_draw_rect(&rect_area, clip_area, &sel_rect); page->state = state_orig; + _lv_obj_disable_style_cahcing(ddlist, false); } @@ -1169,8 +1172,10 @@ static void draw_box_label(lv_obj_t * ddlist, const lv_area_t * clip_area, uint1 lv_obj_t * page = ext->page; lv_state_t state_orig = page->state; - page->state = LV_STATE_DEFAULT; - page->state |= state; + if(state != page->state) { + page->state = state; + _lv_obj_disable_style_cahcing(ddlist, true); + } lv_draw_label_dsc_t label_dsc; lv_draw_label_dsc_init(&label_dsc); @@ -1204,6 +1209,7 @@ static void draw_box_label(lv_obj_t * ddlist, const lv_area_t * clip_area, uint1 lv_draw_label(&label->coords, &mask_sel, &label_dsc, lv_label_get_text(label), NULL); } page->state = state_orig; + _lv_obj_disable_style_cahcing(ddlist, false); } /** diff --git a/src/lv_widgets/lv_gauge.c b/src/lv_widgets/lv_gauge.c index ad7cb32e1..4457c9ba5 100644 --- a/src/lv_widgets/lv_gauge.c +++ b/src/lv_widgets/lv_gauge.c @@ -124,7 +124,7 @@ lv_obj_t * lv_gauge_create(lv_obj_t * par, const lv_obj_t * copy) ext->format_cb = copy_ext->format_cb; /*Refresh the style with new signal function*/ - lv_obj_refresh_style(gauge, LV_STYLE_PROP_ALL); + lv_obj_refresh_style(gauge, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL); } LV_LOG_INFO("gauge created"); diff --git a/src/lv_widgets/lv_img.c b/src/lv_widgets/lv_img.c index 6c6f65791..d92dcc2d8 100644 --- a/src/lv_widgets/lv_img.c +++ b/src/lv_widgets/lv_img.c @@ -121,7 +121,7 @@ lv_obj_t * lv_img_create(lv_obj_t * par, const lv_obj_t * copy) lv_img_set_src(img, copy_ext->src); /*Refresh the style with new signal function*/ - lv_obj_refresh_style(img, LV_STYLE_PROP_ALL); + lv_obj_refresh_style(img, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL); } LV_LOG_INFO("image created"); diff --git a/src/lv_widgets/lv_imgbtn.c b/src/lv_widgets/lv_imgbtn.c index 1c37d92a9..43bf7e37b 100644 --- a/src/lv_widgets/lv_imgbtn.c +++ b/src/lv_widgets/lv_imgbtn.c @@ -100,7 +100,7 @@ lv_obj_t * lv_imgbtn_create(lv_obj_t * par, const lv_obj_t * copy) #endif ext->tiled = copy_ext->tiled; /*Refresh the style with new signal function*/ - lv_obj_refresh_style(imgbtn, LV_STYLE_PROP_ALL); + lv_obj_refresh_style(imgbtn, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL); } LV_LOG_INFO("image button created"); diff --git a/src/lv_widgets/lv_label.c b/src/lv_widgets/lv_label.c index 1113a6b10..65e6397f6 100644 --- a/src/lv_widgets/lv_label.c +++ b/src/lv_widgets/lv_label.c @@ -161,7 +161,7 @@ lv_obj_t * lv_label_create(lv_obj_t * par, const lv_obj_t * copy) ext->dot_end = copy_ext->dot_end; /*Refresh the style with new signal function*/ - lv_obj_refresh_style(new_label, LV_STYLE_PROP_ALL); + lv_obj_refresh_style(new_label, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL); } LV_LOG_INFO("label created"); diff --git a/src/lv_widgets/lv_led.c b/src/lv_widgets/lv_led.c index 53c679c2f..dea778d7d 100644 --- a/src/lv_widgets/lv_led.c +++ b/src/lv_widgets/lv_led.c @@ -88,7 +88,7 @@ lv_obj_t * lv_led_create(lv_obj_t * par, const lv_obj_t * copy) ext->bright = copy_ext->bright; /*Refresh the style with new signal function*/ - lv_obj_refresh_style(led, LV_STYLE_PROP_ALL); + lv_obj_refresh_style(led, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL); } LV_LOG_INFO("led created"); diff --git a/src/lv_widgets/lv_line.c b/src/lv_widgets/lv_line.c index e2c53e925..c54a0ecf5 100644 --- a/src/lv_widgets/lv_line.c +++ b/src/lv_widgets/lv_line.c @@ -95,7 +95,7 @@ lv_obj_t * lv_line_create(lv_obj_t * par, const lv_obj_t * copy) lv_line_set_points(line, copy_ext->point_array, copy_ext->point_num); /*Refresh the style with new signal function*/ - lv_obj_refresh_style(line, LV_STYLE_PROP_ALL); + lv_obj_refresh_style(line, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL); } LV_LOG_INFO("line created"); diff --git a/src/lv_widgets/lv_linemeter.c b/src/lv_widgets/lv_linemeter.c index c8e7ae724..5b643058f 100644 --- a/src/lv_widgets/lv_linemeter.c +++ b/src/lv_widgets/lv_linemeter.c @@ -96,7 +96,7 @@ lv_obj_t * lv_linemeter_create(lv_obj_t * par, const lv_obj_t * copy) ext->cur_value = copy_ext->cur_value; /*Refresh the style with new signal function*/ - lv_obj_refresh_style(linemeter, LV_STYLE_PROP_ALL); + lv_obj_refresh_style(linemeter, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL); } LV_LOG_INFO("line meter created"); diff --git a/src/lv_widgets/lv_list.c b/src/lv_widgets/lv_list.c index dfd2b32af..526e53adf 100644 --- a/src/lv_widgets/lv_list.c +++ b/src/lv_widgets/lv_list.c @@ -115,7 +115,7 @@ lv_obj_t * lv_list_create(lv_obj_t * par, const lv_obj_t * copy) } /*Refresh the style with new signal function*/ - lv_obj_refresh_style(list, LV_STYLE_PROP_ALL); + lv_obj_refresh_style(list, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL); } LV_LOG_INFO("list created"); diff --git a/src/lv_widgets/lv_msgbox.c b/src/lv_widgets/lv_msgbox.c index 60f4cdc9c..9448bec58 100644 --- a/src/lv_widgets/lv_msgbox.c +++ b/src/lv_widgets/lv_msgbox.c @@ -127,7 +127,7 @@ lv_obj_t * lv_msgbox_create(lv_obj_t * par, const lv_obj_t * copy) if(copy_ext->btnm) ext->btnm = lv_btnmatrix_create(mbox, copy_ext->btnm); /*Refresh the style with new signal function*/ - lv_obj_refresh_style(mbox, LV_STYLE_PROP_ALL); + lv_obj_refresh_style(mbox, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL); } LV_LOG_INFO("message box created"); diff --git a/src/lv_widgets/lv_objmask.c b/src/lv_widgets/lv_objmask.c index 2c817fb17..ed22bb30b 100644 --- a/src/lv_widgets/lv_objmask.c +++ b/src/lv_widgets/lv_objmask.c @@ -86,7 +86,7 @@ lv_obj_t * lv_objmask_create(lv_obj_t * par, const lv_obj_t * copy) /* lv_objmask_ext_t * copy_ext = lv_obj_get_ext_attr(copy); */ /*Refresh the style with new signal function*/ - lv_obj_refresh_style(objmask, LV_STYLE_PROP_ALL); + lv_obj_refresh_style(objmask, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL); } LV_LOG_INFO("object mask created"); diff --git a/src/lv_widgets/lv_roller.c b/src/lv_widgets/lv_roller.c index 7c67fcb68..8b6818edc 100644 --- a/src/lv_widgets/lv_roller.c +++ b/src/lv_widgets/lv_roller.c @@ -135,7 +135,7 @@ lv_obj_t * lv_roller_create(lv_obj_t * par, const lv_obj_t * copy) lv_obj_set_signal_cb(scrl, lv_roller_scrl_signal); lv_style_list_copy(&ext->style_sel, ©_ext->style_sel); - lv_obj_refresh_style(roller, LV_STYLE_PROP_ALL); + lv_obj_refresh_style(roller, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL); } LV_LOG_INFO("roller created"); diff --git a/src/lv_widgets/lv_slider.c b/src/lv_widgets/lv_slider.c index bb83f9298..7e658226d 100644 --- a/src/lv_widgets/lv_slider.c +++ b/src/lv_widgets/lv_slider.c @@ -103,7 +103,7 @@ lv_obj_t * lv_slider_create(lv_obj_t * par, const lv_obj_t * copy) lv_area_copy(&ext->left_knob_area, ©_ext->left_knob_area); lv_area_copy(&ext->right_knob_area, ©_ext->right_knob_area); - lv_obj_refresh_style(slider, LV_OBJ_PART_ALL); + lv_obj_refresh_style(slider, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL); } LV_LOG_INFO("slider created"); diff --git a/src/lv_widgets/lv_spinbox.c b/src/lv_widgets/lv_spinbox.c index 669c72d38..1fac9de80 100644 --- a/src/lv_widgets/lv_spinbox.c +++ b/src/lv_widgets/lv_spinbox.c @@ -106,7 +106,7 @@ lv_obj_t * lv_spinbox_create(lv_obj_t * par, const lv_obj_t * copy) lv_spinbox_set_rollover(spinbox, copy_ext->rollover); /*Refresh the style with new signal function*/ - lv_obj_refresh_style(spinbox, LV_STYLE_PROP_ALL); + lv_obj_refresh_style(spinbox, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL); } lv_spinbox_updatevalue(spinbox); diff --git a/src/lv_widgets/lv_spinner.c b/src/lv_widgets/lv_spinner.c index 16c0e570b..8e0e2dcd0 100644 --- a/src/lv_widgets/lv_spinner.c +++ b/src/lv_widgets/lv_spinner.c @@ -106,7 +106,7 @@ lv_obj_t * lv_spinner_create(lv_obj_t * par, const lv_obj_t * copy) ext->time = copy_ext->time; ext->anim_dir = copy_ext->anim_dir; /*Refresh the style with new signal function*/ - lv_obj_refresh_style(spinner, LV_STYLE_PROP_ALL); + lv_obj_refresh_style(spinner, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL); } lv_spinner_set_type(spinner, ext->anim_type); diff --git a/src/lv_widgets/lv_switch.c b/src/lv_widgets/lv_switch.c index dfc1aa964..9340f1efa 100644 --- a/src/lv_widgets/lv_switch.c +++ b/src/lv_widgets/lv_switch.c @@ -100,7 +100,7 @@ lv_obj_t * lv_switch_create(lv_obj_t * par, const lv_obj_t * copy) lv_switch_ext_t * copy_ext = lv_obj_get_ext_attr(copy); lv_style_list_copy(&ext->style_knob, ©_ext->style_knob); - lv_obj_refresh_style(sw, LV_STYLE_PROP_ALL); + lv_obj_refresh_style(sw, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL); } /*Refresh the style with new signal function*/ diff --git a/src/lv_widgets/lv_table.c b/src/lv_widgets/lv_table.c index 0e44d1e5c..b35484e9a 100644 --- a/src/lv_widgets/lv_table.c +++ b/src/lv_widgets/lv_table.c @@ -110,7 +110,7 @@ lv_obj_t * lv_table_create(lv_obj_t * par, const lv_obj_t * copy) } /*Refresh the style with new signal function*/ - lv_obj_refresh_style(table, LV_STYLE_PROP_ALL); + lv_obj_refresh_style(table, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL); } LV_LOG_INFO("table created"); diff --git a/src/lv_widgets/lv_tabview.c b/src/lv_widgets/lv_tabview.c index f68d69a36..3f4efb3e8 100644 --- a/src/lv_widgets/lv_tabview.c +++ b/src/lv_widgets/lv_tabview.c @@ -180,11 +180,11 @@ lv_obj_t * lv_tabview_create(lv_obj_t * par, const lv_obj_t * copy) LV_PAGE_PART_SCROLLABLE)); lv_style_list_copy(lv_obj_get_style_list(new_tab, LV_PAGE_PART_SCROLLBAR), lv_obj_get_style_list(copy_tab, LV_PAGE_PART_SCROLLBAR)); - lv_obj_refresh_style(new_tab, LV_STYLE_PROP_ALL); + lv_obj_refresh_style(new_tab, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL); } /*Refresh the style with new signal function*/ - lv_obj_refresh_style(tabview, LV_STYLE_PROP_ALL); + lv_obj_refresh_style(tabview, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL); } tabview_realign(tabview); diff --git a/src/lv_widgets/lv_textarea.c b/src/lv_widgets/lv_textarea.c index 9cf859f82..e8a332c9e 100644 --- a/src/lv_widgets/lv_textarea.c +++ b/src/lv_widgets/lv_textarea.c @@ -187,7 +187,7 @@ lv_obj_t * lv_textarea_create(lv_obj_t * par, const lv_obj_t * copy) if(copy_ext->one_line) lv_textarea_set_one_line(ta, true); /*Refresh the style with new signal function*/ - lv_obj_refresh_style(ta, LV_STYLE_PROP_ALL); + lv_obj_refresh_style(ta, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL); } #if LV_USE_ANIMATION diff --git a/src/lv_widgets/lv_tileview.c b/src/lv_widgets/lv_tileview.c index 0ea0f8133..3fa01503c 100644 --- a/src/lv_widgets/lv_tileview.c +++ b/src/lv_widgets/lv_tileview.c @@ -133,7 +133,7 @@ lv_obj_t * lv_tileview_create(lv_obj_t * par, const lv_obj_t * copy) #endif /*Refresh the style with new signal function*/ - lv_obj_refresh_style(new_tileview, LV_STYLE_PROP_ALL); + lv_obj_refresh_style(new_tileview, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL); } LV_LOG_INFO("tileview created"); diff --git a/src/lv_widgets/lv_win.c b/src/lv_widgets/lv_win.c index 20fbb7426..0e122976d 100644 --- a/src/lv_widgets/lv_win.c +++ b/src/lv_widgets/lv_win.c @@ -156,7 +156,7 @@ lv_obj_t * lv_win_create(lv_obj_t * par, const lv_obj_t * copy) } /*Refresh the style with new signal function*/ - lv_obj_refresh_style(new_win, LV_STYLE_PROP_ALL); + lv_obj_refresh_style(new_win, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL); lv_win_realign(new_win); From ae0e855d912af9b3cbe4a0e1387f6b8d90dfe09f Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Sun, 2 Aug 2020 20:49:21 +0200 Subject: [PATCH 3/7] style cache fixes --- src/lv_core/lv_obj.c | 35 ++++++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/src/lv_core/lv_obj.c b/src/lv_core/lv_obj.c index 88474cd0b..0d32a25e1 100644 --- a/src/lv_core/lv_obj.c +++ b/src/lv_core/lv_obj.c @@ -2454,8 +2454,7 @@ lv_style_int_t _lv_obj_get_style_int(const lv_obj_t * obj, uint8_t part, lv_styl const lv_obj_t * parent = obj; while(parent) { lv_style_list_t * list = lv_obj_get_style_list(parent, part); - - if(!list->ignore_cache) { + if(!list->ignore_cache && list->style_cnt > 0) { if(!list->valid_cache) update_style_cache((lv_obj_t*)parent, part, prop & (~LV_STYLE_STATE_MASK)); bool def = false; @@ -2620,7 +2619,7 @@ lv_opa_t _lv_obj_get_style_opa(const lv_obj_t * obj, uint8_t part, lv_style_prop while(parent) { lv_style_list_t * list = lv_obj_get_style_list(parent, part); - if(!list->ignore_cache) { + if(!list->ignore_cache && list->style_cnt > 0) { if(!list->valid_cache) update_style_cache((lv_obj_t*)parent, part, prop & (~LV_STYLE_STATE_MASK)); bool def = false; switch(prop & (~LV_STYLE_STATE_MASK)) { @@ -2695,7 +2694,7 @@ const void * _lv_obj_get_style_ptr(const lv_obj_t * obj, uint8_t part, lv_style_ while(parent) { lv_style_list_t * list = lv_obj_get_style_list(parent, part); - if(!list->ignore_cache) { + if(!list->ignore_cache && list->style_cnt > 0) { if(!list->valid_cache) update_style_cache((lv_obj_t*)parent, part, prop & (~LV_STYLE_STATE_MASK)); bool def = false; switch(prop & (~LV_STYLE_STATE_MASK)) { @@ -4482,6 +4481,14 @@ static void update_style_cache_children(lv_obj_t * obj) list->ignore_cache = ignore_cache_ori; } + + + lv_obj_t * child = lv_obj_get_child(obj, NULL); + while(child) { + update_style_cache_children(child); + child = lv_obj_get_child(obj, child); + } + } /** @@ -4491,9 +4498,23 @@ static void update_style_cache_children(lv_obj_t * obj) */ static void invalidate_style_cache(lv_obj_t * obj, uint8_t part) { - lv_style_list_t * list = lv_obj_get_style_list(obj, part); - if(list == NULL) return; - list->valid_cache = 0; + if(part != LV_OBJ_PART_ALL) { + lv_style_list_t * list = lv_obj_get_style_list(obj, part); + if(list == NULL) return; + list->valid_cache = 0; + } else { + + for(part = 0; part < _LV_OBJ_PART_REAL_FIRST; part++) { + lv_style_list_t * list = lv_obj_get_style_list(obj, part); + if(list == NULL) break; + list->valid_cache = 0; + } + for(part = _LV_OBJ_PART_REAL_FIRST; part < 0xFF; part++) { + lv_style_list_t * list = lv_obj_get_style_list(obj, part); + if(list == NULL) break; + list->valid_cache = 0; + } + } lv_obj_t * child = lv_obj_get_child(obj, NULL); while(child) { From 1b29814e1ea4bdd6cf8b365e467e16e9c29c3036 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Sun, 2 Aug 2020 22:25:26 +0200 Subject: [PATCH 4/7] improve style caching --- src/lv_core/lv_obj.c | 248 +++++++++++++++++++++++++++++----------- src/lv_core/lv_obj.h | 16 +++ src/lv_core/lv_style.c | 3 - src/lv_core/lv_style.h | 12 +- src/lv_widgets/lv_arc.c | 3 + 5 files changed, 204 insertions(+), 78 deletions(-) diff --git a/src/lv_core/lv_obj.c b/src/lv_core/lv_obj.c index 0d32a25e1..d3de68f0a 100644 --- a/src/lv_core/lv_obj.c +++ b/src/lv_core/lv_obj.c @@ -105,7 +105,7 @@ static void lv_obj_del_async_cb(void * obj); static void obj_del_core(lv_obj_t * obj); static void update_style_cache(lv_obj_t * obj, uint8_t part, uint16_t prop); static void update_style_cache_children(lv_obj_t * obj); -static void invalidate_style_cache(lv_obj_t * obj, uint8_t part); +static void invalidate_style_cache(lv_obj_t * obj, uint8_t part, lv_style_property_t prop); /********************** * STATIC VARIABLES **********************/ @@ -505,43 +505,11 @@ void lv_obj_invalidate_area(const lv_obj_t * obj, const lv_area_t * area) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); - if(lv_obj_get_hidden(obj)) return; + lv_area_t area_tmp; + lv_area_copy(&area_tmp, area); + bool visible = lv_obj_area_is_visible(obj, &area_tmp); - /*Invalidate the object only if it belongs to the curent or previous'*/ - lv_obj_t * obj_scr = lv_obj_get_screen(obj); - lv_disp_t * disp = lv_obj_get_disp(obj_scr); - if(obj_scr == lv_disp_get_scr_act(disp) || - obj_scr == lv_disp_get_scr_prev(disp) || - obj_scr == lv_disp_get_layer_top(disp) || - obj_scr == lv_disp_get_layer_sys(disp)) { - - /*Truncate the area to the object*/ - lv_area_t obj_coords; - lv_coord_t ext_size = obj->ext_draw_pad; - lv_area_copy(&obj_coords, &obj->coords); - obj_coords.x1 -= ext_size; - obj_coords.y1 -= ext_size; - obj_coords.x2 += ext_size; - obj_coords.y2 += ext_size; - - bool is_common; - lv_area_t area_trunc; - - is_common = _lv_area_intersect(&area_trunc, area, &obj_coords); - if(is_common == false) return; /*The area is not on the object*/ - - /*Truncate recursively to the parents*/ - lv_obj_t * par = lv_obj_get_parent(obj); - while(par != NULL) { - is_common = _lv_area_intersect(&area_trunc, &area_trunc, &par->coords); - if(is_common == false) break; /*If no common parts with parent break;*/ - if(lv_obj_get_hidden(par)) return; /*If the parent is hidden then the child is hidden and won't be drawn*/ - - par = lv_obj_get_parent(par); - } - - if(is_common) _lv_inv_area(disp, &area_trunc); - } + if(visible) _lv_inv_area(lv_obj_get_disp(obj), &area_tmp); } /** @@ -564,6 +532,74 @@ void lv_obj_invalidate(const lv_obj_t * obj) lv_obj_invalidate_area(obj, &obj_coords); } + +/** + * Tell whether an area of an object is visible (even partially) now or not + * @param obj pointer to an object + * @param area the are to check. The visible part of the area will be written back here. + * @return true: visible; false: not visible (hidden, out of parent, on other screen, etc) + */ +bool lv_obj_area_is_visible(const lv_obj_t * obj, lv_area_t * area) +{ + if(lv_obj_get_hidden(obj)) return false; + + /*Invalidate the object only if it belongs to the curent or previous'*/ + lv_obj_t * obj_scr = lv_obj_get_screen(obj); + lv_disp_t * disp = lv_obj_get_disp(obj_scr); + if(obj_scr == lv_disp_get_scr_act(disp) || + obj_scr == lv_disp_get_scr_prev(disp) || + obj_scr == lv_disp_get_layer_top(disp) || + obj_scr == lv_disp_get_layer_sys(disp)) { + + /*Truncate the area to the object*/ + lv_area_t obj_coords; + lv_coord_t ext_size = obj->ext_draw_pad; + lv_area_copy(&obj_coords, &obj->coords); + obj_coords.x1 -= ext_size; + obj_coords.y1 -= ext_size; + obj_coords.x2 += ext_size; + obj_coords.y2 += ext_size; + + bool is_common; + + is_common = _lv_area_intersect(area, area, &obj_coords); + if(is_common == false) return false; /*The area is not on the object*/ + + /*Truncate recursively to the parents*/ + lv_obj_t * par = lv_obj_get_parent(obj); + while(par != NULL) { + is_common = _lv_area_intersect(area, area, &par->coords); + if(is_common == false) return false; /*If no common parts with parent break;*/ + if(lv_obj_get_hidden(par)) return false; /*If the parent is hidden then the child is hidden and won't be drawn*/ + + par = lv_obj_get_parent(par); + } + } + + return true; +} + +/** + * Tell whether an object is visible (even partially) now or not + * @param obj pointer to an object + * @return true: visible; false: not visible (hidden, out of parent, on other screen, etc) + */ +bool lv_obj_is_visible(const lv_obj_t * obj) +{ + LV_ASSERT_OBJ(obj, LV_OBJX_NAME); + + lv_area_t obj_coords; + lv_coord_t ext_size = obj->ext_draw_pad; + lv_area_copy(&obj_coords, &obj->coords); + obj_coords.x1 -= ext_size; + obj_coords.y1 -= ext_size; + obj_coords.x2 += ext_size; + obj_coords.y2 += ext_size; + + return lv_obj_area_is_visible(obj, &obj_coords); + +} + /*===================== * Setter functions *====================*/ @@ -1302,7 +1338,7 @@ void lv_obj_refresh_style(lv_obj_t * obj, uint8_t part, lv_style_property_t prop { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); - invalidate_style_cache(obj, part); + invalidate_style_cache(obj, part, prop); /*If a real style refresh is required*/ bool real_refr = false; @@ -2472,16 +2508,10 @@ lv_style_int_t _lv_obj_get_style_int(const lv_obj_t * obj, uint8_t part, lv_styl if(list->text_line_space_zero) def = true; break; case LV_STYLE_TRANSFORM_ANGLE: - if(list->transform_angle_zero) def = true; - break; case LV_STYLE_TRANSFORM_WIDTH: - if(list->transform_width_zero) def = true; - break; case LV_STYLE_TRANSFORM_HEIGHT: - if(list->transform_height_zero) def = true; - break; case LV_STYLE_TRANSFORM_ZOOM: - if(list->transform_zoom_zero) def = true; + if(list->transform_all_zero) def = true; break; case LV_STYLE_BORDER_WIDTH: if(list->border_width_zero) def = true; @@ -2495,9 +2525,28 @@ lv_style_int_t _lv_obj_get_style_int(const lv_obj_t * obj, uint8_t part, lv_styl case LV_STYLE_SHADOW_WIDTH: if(list->shadow_width_zero) def = true; break; + case LV_STYLE_PAD_TOP: + case LV_STYLE_PAD_BOTTOM: + case LV_STYLE_PAD_LEFT: + case LV_STYLE_PAD_RIGHT: + if(list->pad_all_zero) def = true; + break; + case LV_STYLE_BG_BLEND_MODE: + case LV_STYLE_BORDER_BLEND_MODE: + case LV_STYLE_IMAGE_BLEND_MODE: + case LV_STYLE_LINE_BLEND_MODE: + case LV_STYLE_OUTLINE_BLEND_MODE: + case LV_STYLE_PATTERN_BLEND_MODE: + case LV_STYLE_SHADOW_BLEND_MODE: + case LV_STYLE_TEXT_BLEND_MODE: + case LV_STYLE_VALUE_BLEND_MODE: + if(list->blend_mode_all_normal) def = true; + break; } - if(def) break; + if(def) { + break; + } } lv_state_t state = lv_obj_get_state(parent, part); @@ -2624,7 +2673,7 @@ lv_opa_t _lv_obj_get_style_opa(const lv_obj_t * obj, uint8_t part, lv_style_prop bool def = false; switch(prop & (~LV_STYLE_STATE_MASK)) { case LV_STYLE_OPA_SCALE: - if(list->opa_scale_transp) def = true; + if(list->opa_scale_cover) def = true; break; case LV_STYLE_BG_OPA: if(list->bg_opa_transp) def = true; @@ -2633,7 +2682,10 @@ lv_opa_t _lv_obj_get_style_opa(const lv_obj_t * obj, uint8_t part, lv_style_prop if(list->img_recolor_opa_transp) def = true; break; } - if(def) break; + + if(def) { + break; + } } @@ -2699,14 +2751,19 @@ const void * _lv_obj_get_style_ptr(const lv_obj_t * obj, uint8_t part, lv_style_ bool def = false; switch(prop & (~LV_STYLE_STATE_MASK)) { case LV_STYLE_VALUE_STR: - if(list->opa_scale_transp) def = true; + if(list->value_txt_str) def = true; break; case LV_STYLE_PATTERN_IMAGE: if(list->pattern_img_null) def = true; break; + case LV_STYLE_TEXT_FONT: + if(list->text_font_normal) def = true; + break; } - if(def) break; + if(def) { + break; + } } lv_state_t state = lv_obj_get_state(parent, part); @@ -4378,17 +4435,11 @@ static bool obj_valid_child(const lv_obj_t * parent, const lv_obj_t * obj_to_fin return false; } -/** - * Update the cache of style list - * @param obj pointer to an obejct - * @param part the part of the object - * @param prop the property which triggered the update - */ -static void update_style_cache(lv_obj_t * obj, uint8_t part, uint16_t prop) +static bool style_prop_is_cacheble(lv_style_property_t prop) { - bool cachable; switch(prop) { + case LV_STYLE_PROP_ALL: case LV_STYLE_BG_GRAD_DIR: case LV_STYLE_CLIP_CORNER: case LV_STYLE_TEXT_LETTER_SPACE: @@ -4406,23 +4457,50 @@ static void update_style_cache(lv_obj_t * obj, uint8_t part, uint16_t prop) case LV_STYLE_IMAGE_RECOLOR_OPA: case LV_STYLE_VALUE_STR: case LV_STYLE_PATTERN_IMAGE: - cachable = true; + case LV_STYLE_PAD_TOP: + case LV_STYLE_PAD_BOTTOM: + case LV_STYLE_PAD_LEFT: + case LV_STYLE_PAD_RIGHT: + case LV_STYLE_BG_BLEND_MODE: + case LV_STYLE_BORDER_BLEND_MODE: + case LV_STYLE_IMAGE_BLEND_MODE: + case LV_STYLE_LINE_BLEND_MODE: + case LV_STYLE_OUTLINE_BLEND_MODE: + case LV_STYLE_PATTERN_BLEND_MODE: + case LV_STYLE_SHADOW_BLEND_MODE: + case LV_STYLE_TEXT_BLEND_MODE: + case LV_STYLE_VALUE_BLEND_MODE: + return true; break; default: - cachable = false; + return false; } +} - if(!cachable) return; +/** + * Update the cache of style list + * @param obj pointer to an obejct + * @param part the part of the object + * @param prop the property which triggered the update + */ +static void update_style_cache(lv_obj_t * obj, uint8_t part, uint16_t prop) +{ + if(style_prop_is_cacheble(prop) == false) return; lv_style_list_t * list = lv_obj_get_style_list(obj, part); bool ignore_cache_ori = list->ignore_cache; list->ignore_cache = 1; - list->opa_scale_transp = lv_obj_get_style_opa_scale(obj, part) == LV_OPA_TRANSP ? 1 : 0; +#if LV_USE_OPA_SCALE + list->opa_scale_cover = lv_obj_get_style_opa_scale(obj, part) == LV_OPA_COVER ? 1 : 0; +#else + list->opa_scale_cover = 1; +#endif list->text_decor_none = lv_obj_get_style_text_decor(obj, part) == LV_TEXT_DECOR_NONE ? 1 : 0; list->text_letter_space_zero = lv_obj_get_style_text_letter_space(obj, part) == 0 ? 1 : 0; list->text_line_space_zero = lv_obj_get_style_text_line_space(obj, part) == 0 ? 1 : 0; + list->text_font_normal = lv_obj_get_style_text_font(obj, part) == LV_THEME_DEFAULT_FONT_NORMAL ? 1 : 0; list->bg_grad_dir_none = lv_obj_get_style_bg_grad_dir(obj, part) == LV_GRAD_DIR_NONE ? 1 : 0; list->bg_opa_transp = lv_obj_get_style_bg_opa(obj, part) == LV_OPA_TRANSP ? 1 : 0; @@ -4433,12 +4511,42 @@ static void update_style_cache(lv_obj_t * obj, uint8_t part, uint16_t prop) list->outline_width_zero = lv_obj_get_style_outline_width(obj, part) == 0 ? 1 : 0; list->pattern_img_null = lv_obj_get_style_pattern_image(obj, part) == NULL ? 1 : 0; list->shadow_width_zero = lv_obj_get_style_shadow_width(obj, part) == 0 ? 1 : 0; - list->transform_angle_zero = lv_obj_get_style_transform_angle(obj, part) == 0 ? 1 : 0; - list->transform_height_zero = lv_obj_get_style_transform_width(obj, part) == 0 ? 1 : 0; - list->transform_width_zero = lv_obj_get_style_transform_height(obj, part) == 0 ? 1 : 0; - list->transform_zoom_zero = lv_obj_get_style_transform_zoom(obj, part) == LV_IMG_ZOOM_NONE ? 1 : 0; list->value_txt_str = lv_obj_get_style_value_str(obj, part) == NULL ? 1 : 0; + + list->transform_all_zero = 1; + if(lv_obj_get_style_transform_angle(obj, part) != 0 || + lv_obj_get_style_transform_width(obj, part) != 0 || + lv_obj_get_style_transform_height(obj, part) != 0 || + lv_obj_get_style_transform_zoom(obj, part) != LV_IMG_ZOOM_NONE) + { + list->transform_all_zero = 0; + } + + list->pad_all_zero = 1; + if(lv_obj_get_style_pad_top(obj, part) != 0 || + lv_obj_get_style_pad_bottom(obj, part) != 0 || + lv_obj_get_style_pad_left(obj, part) != 0 || + lv_obj_get_style_pad_right(obj, part) != 0) + { + list->pad_all_zero = 0; + } + + list->blend_mode_all_normal = 1; +#if LV_USE_BLEND_MODES + if(lv_obj_get_style_bg_blend_mode(obj, part) != LV_BLEND_MODE_NORMAL || + lv_obj_get_style_border_blend_mode(obj, part) != LV_BLEND_MODE_NORMAL || + lv_obj_get_style_pattern_blend_mode(obj, part) != LV_BLEND_MODE_NORMAL || + lv_obj_get_style_outline_blend_mode(obj, part) != LV_BLEND_MODE_NORMAL || + lv_obj_get_style_value_blend_mode(obj, part) != LV_BLEND_MODE_NORMAL || + lv_obj_get_style_text_blend_mode(obj, part) != LV_BLEND_MODE_NORMAL || + lv_obj_get_style_line_blend_mode(obj, part) != LV_BLEND_MODE_NORMAL || + lv_obj_get_style_image_blend_mode(obj, part) != LV_BLEND_MODE_NORMAL || + lv_obj_get_style_shadow_blend_mode(obj, part) != LV_BLEND_MODE_NORMAL) + { + list->blend_mode_all_normal = 0; + } +#endif list->ignore_cache = ignore_cache_ori; list->valid_cache = 1; } @@ -4473,16 +4581,16 @@ static void update_style_cache_children(lv_obj_t * obj) bool ignore_cache_ori = list->ignore_cache; list->ignore_cache = 1; - list->opa_scale_transp = lv_obj_get_style_opa_scale(obj, part) == LV_OPA_TRANSP ? 1 : 0; + list->opa_scale_cover = lv_obj_get_style_opa_scale(obj, part) == LV_OPA_COVER ? 1 : 0; list->text_decor_none = lv_obj_get_style_text_decor(obj, part) == LV_TEXT_DECOR_NONE ? 1 : 0; list->text_letter_space_zero = lv_obj_get_style_text_letter_space(obj, part) == 0 ? 1 : 0; list->text_line_space_zero = lv_obj_get_style_text_line_space(obj, part) == 0 ? 1 : 0; + list->text_font_normal = lv_obj_get_style_text_font(obj, part) == lv_theme_get_font_normal() ? 1 : 0; list->img_recolor_opa_transp = lv_obj_get_style_image_recolor_opa(obj, part) == LV_OPA_TRANSP ? 1 : 0; list->ignore_cache = ignore_cache_ori; } - lv_obj_t * child = lv_obj_get_child(obj, NULL); while(child) { update_style_cache_children(child); @@ -4496,8 +4604,10 @@ static void update_style_cache_children(lv_obj_t * obj) * The cache will be updated when a cached property asked nest time * @param obj pointer to an object */ -static void invalidate_style_cache(lv_obj_t * obj, uint8_t part) +static void invalidate_style_cache(lv_obj_t * obj, uint8_t part, lv_style_property_t prop) { + if(style_prop_is_cacheble(prop) == false) return; + if(part != LV_OBJ_PART_ALL) { lv_style_list_t * list = lv_obj_get_style_list(obj, part); if(list == NULL) return; diff --git a/src/lv_core/lv_obj.h b/src/lv_core/lv_obj.h index c5f9b0cd4..0a68c4d1e 100644 --- a/src/lv_core/lv_obj.h +++ b/src/lv_core/lv_obj.h @@ -353,6 +353,22 @@ void lv_obj_invalidate_area(const lv_obj_t * obj, const lv_area_t * area); */ void lv_obj_invalidate(const lv_obj_t * obj); + +/** + * Tell whether an area of an object is visible (even partially) now or not + * @param obj pointer to an object + * @param area the are to check. The visible part of the area will be written back here. + * @return true: visible; false: not visible (hidden, out of parent, on other screen, etc) + */ +bool lv_obj_area_is_visible(const lv_obj_t * obj, lv_area_t * area); + +/** + * Tell whether an object is visible (even partially) now or not + * @param obj pointer to an object + * @return true: visible; false: not visible (hidden, out of parent, on other screen, etc) + */ +bool lv_obj_is_visible(const lv_obj_t * obj); + /*===================== * Setter functions *====================*/ diff --git a/src/lv_core/lv_style.c b/src/lv_core/lv_style.c index 7428ac731..ce3665e0d 100644 --- a/src/lv_core/lv_style.c +++ b/src/lv_core/lv_style.c @@ -1052,9 +1052,6 @@ bool lv_debug_check_style_list(const lv_style_list_t * list) */ LV_ATTRIBUTE_FAST_MEM static inline int32_t get_property_index(const lv_style_t * style, lv_style_property_t prop) { - static uint32_t c = 0; - c++; - if(c % 100 == 0) printf("%d\n", c); LV_ASSERT_STYLE(style); if(style->map == NULL) return -1; diff --git a/src/lv_core/lv_style.h b/src/lv_core/lv_style.h index 0db481ec8..c2eb75e77 100644 --- a/src/lv_core/lv_style.h +++ b/src/lv_core/lv_style.h @@ -227,19 +227,18 @@ typedef struct { uint32_t skip_trans :1; /*1: Temporally skip the transition style if any*/ uint32_t ignore_trans :1; /*1: Mark that this style list shouldn't receive transitions at all*/ uint32_t valid_cache :1; /*1: The cache is invalid and needs to be updated*/ - uint8_t ignore_cache :1; /**1: Ignore style cache while getting value of properties*/ + uint32_t ignore_cache :1; /**1: Ignore style cache while getting value of properties*/ - uint32_t opa_scale_transp :1; + uint32_t opa_scale_cover :1; uint32_t clip_corner_off :1; - uint32_t transform_width_zero :1; - uint32_t transform_height_zero :1; - uint32_t transform_angle_zero :1; - uint32_t transform_zoom_zero :1; + uint32_t transform_all_zero :1; uint32_t bg_opa_transp :1; uint32_t bg_grad_dir_none :1; + uint32_t blend_mode_all_normal :1; uint32_t border_width_zero :1; uint32_t outline_width_zero :1; uint32_t pattern_img_null :1; + uint32_t pad_all_zero :1; uint32_t shadow_width_zero :1; uint32_t value_txt_str :1; uint32_t line_width_zerop :1; @@ -247,6 +246,7 @@ typedef struct { uint32_t text_letter_space_zero :1; uint32_t text_line_space_zero :1; uint32_t text_decor_none :1; + uint32_t text_font_normal :1; } lv_style_list_t; /********************** diff --git a/src/lv_widgets/lv_arc.c b/src/lv_widgets/lv_arc.c index f7cf087f1..f85b29c60 100644 --- a/src/lv_widgets/lv_arc.c +++ b/src/lv_widgets/lv_arc.c @@ -515,6 +515,9 @@ static lv_style_list_t * lv_arc_get_style(lv_obj_t * arc, uint8_t part) static void inv_arc_area(lv_obj_t * arc, uint16_t start_angle, uint16_t end_angle) { + /*Skip this complicated invalidation if the arc is not visible*/ + if(lv_obj_is_visible(arc) == false) return; + lv_arc_ext_t * ext = lv_obj_get_ext_attr(arc); start_angle += ext->rotation_angle; From 6ccfd0101afbcb3cc8e60ab9b15871665643edab Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Mon, 3 Aug 2020 07:03:54 +0200 Subject: [PATCH 5/7] style cache: add missing LV_STYLE_FONT_TEXT to cachable proeprties --- src/lv_core/lv_obj.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lv_core/lv_obj.c b/src/lv_core/lv_obj.c index d3de68f0a..b4e964e44 100644 --- a/src/lv_core/lv_obj.c +++ b/src/lv_core/lv_obj.c @@ -4444,6 +4444,7 @@ static bool style_prop_is_cacheble(lv_style_property_t prop) case LV_STYLE_CLIP_CORNER: case LV_STYLE_TEXT_LETTER_SPACE: case LV_STYLE_TEXT_LINE_SPACE: + case LV_STYLE_TEXT_FONT: case LV_STYLE_TRANSFORM_ANGLE: case LV_STYLE_TRANSFORM_WIDTH: case LV_STYLE_TRANSFORM_HEIGHT: From 61a5cb44b8ff13237ba66cc4de0a946ee04f4395 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Mon, 3 Aug 2020 07:17:21 +0200 Subject: [PATCH 6/7] optimze style asking order in lv_obj_init_draw_xxx_dsc function --- src/lv_core/lv_obj.c | 43 +++++++++++++++++++++--------------------- src/lv_core/lv_style.h | 6 +++--- 2 files changed, 24 insertions(+), 25 deletions(-) diff --git a/src/lv_core/lv_obj.c b/src/lv_core/lv_obj.c index b4e964e44..33122c96d 100644 --- a/src/lv_core/lv_obj.c +++ b/src/lv_core/lv_obj.c @@ -2517,7 +2517,7 @@ lv_style_int_t _lv_obj_get_style_int(const lv_obj_t * obj, uint8_t part, lv_styl if(list->border_width_zero) def = true; break; case LV_STYLE_LINE_WIDTH: - if(list->line_width_zerop) def = true; + if(list->line_width_zero) def = true; break; case LV_STYLE_OUTLINE_WIDTH: if(list->outline_width_zero) def = true; @@ -3283,9 +3283,9 @@ void lv_obj_init_draw_rect_dsc(lv_obj_t * obj, uint8_t part, lv_draw_rect_dsc_t } } - if(draw_dsc->border_opa != LV_OPA_TRANSP) { - draw_dsc->border_width = lv_obj_get_style_border_width(obj, part); - if(draw_dsc->border_width) { + draw_dsc->border_width = lv_obj_get_style_border_width(obj, part); + if(draw_dsc->border_width) { + if(draw_dsc->border_opa != LV_OPA_TRANSP) { draw_dsc->border_opa = lv_obj_get_style_border_opa(obj, part); if(draw_dsc->border_opa > LV_OPA_MIN) { draw_dsc->border_side = lv_obj_get_style_border_side(obj, part); @@ -3297,10 +3297,9 @@ void lv_obj_init_draw_rect_dsc(lv_obj_t * obj, uint8_t part, lv_draw_rect_dsc_t } } - - if(draw_dsc->outline_opa != LV_OPA_TRANSP) { - draw_dsc->outline_width = lv_obj_get_style_outline_width(obj, part); - if(draw_dsc->outline_width) { + draw_dsc->outline_width = lv_obj_get_style_outline_width(obj, part); + if(draw_dsc->outline_width) { + if(draw_dsc->outline_opa != LV_OPA_TRANSP) { draw_dsc->outline_opa = lv_obj_get_style_outline_opa(obj, part); if(draw_dsc->outline_opa > LV_OPA_MIN) { draw_dsc->outline_pad = lv_obj_get_style_outline_pad(obj, part); @@ -3312,9 +3311,9 @@ void lv_obj_init_draw_rect_dsc(lv_obj_t * obj, uint8_t part, lv_draw_rect_dsc_t } } - if(draw_dsc->pattern_opa != LV_OPA_TRANSP) { - draw_dsc->pattern_image = lv_obj_get_style_pattern_image(obj, part); - if(draw_dsc->pattern_image) { + draw_dsc->pattern_image = lv_obj_get_style_pattern_image(obj, part); + if(draw_dsc->pattern_image) { + if(draw_dsc->pattern_opa != LV_OPA_TRANSP) { draw_dsc->pattern_opa = lv_obj_get_style_pattern_opa(obj, part); if(draw_dsc->pattern_opa > LV_OPA_MIN) { draw_dsc->pattern_recolor_opa = lv_obj_get_style_pattern_recolor_opa(obj, part); @@ -3333,9 +3332,9 @@ void lv_obj_init_draw_rect_dsc(lv_obj_t * obj, uint8_t part, lv_draw_rect_dsc_t } } #if LV_USE_SHADOW - if(draw_dsc->shadow_opa > LV_OPA_MIN) { - draw_dsc->shadow_width = lv_obj_get_style_shadow_width(obj, part); - if(draw_dsc->shadow_width) { + draw_dsc->shadow_width = lv_obj_get_style_shadow_width(obj, part); + if(draw_dsc->shadow_width) { + if(draw_dsc->shadow_opa > LV_OPA_MIN) { draw_dsc->shadow_opa = lv_obj_get_style_shadow_opa(obj, part); if(draw_dsc->shadow_opa > LV_OPA_MIN) { draw_dsc->shadow_ofs_x = lv_obj_get_style_shadow_ofs_x(obj, part); @@ -3350,9 +3349,9 @@ void lv_obj_init_draw_rect_dsc(lv_obj_t * obj, uint8_t part, lv_draw_rect_dsc_t } #endif - if(draw_dsc->value_opa > LV_OPA_MIN) { - draw_dsc->value_str = lv_obj_get_style_value_str(obj, part); - if(draw_dsc->value_str) { + draw_dsc->value_str = lv_obj_get_style_value_str(obj, part); + if(draw_dsc->value_str) { + if(draw_dsc->value_opa > LV_OPA_MIN) { draw_dsc->value_opa = lv_obj_get_style_value_opa(obj, part); if(draw_dsc->value_opa > LV_OPA_MIN) { draw_dsc->value_ofs_x = lv_obj_get_style_value_ofs_x(obj, part); @@ -3441,6 +3440,9 @@ void lv_obj_init_draw_img_dsc(lv_obj_t * obj, uint8_t part, lv_draw_img_dsc_t * void lv_obj_init_draw_line_dsc(lv_obj_t * obj, uint8_t part, lv_draw_line_dsc_t * draw_dsc) { + draw_dsc->width = lv_obj_get_style_line_width(obj, part); + if(draw_dsc->width == 0) return; + draw_dsc->opa = lv_obj_get_style_line_opa(obj, part); if(draw_dsc->opa <= LV_OPA_MIN) return; @@ -3452,9 +3454,6 @@ void lv_obj_init_draw_line_dsc(lv_obj_t * obj, uint8_t part, lv_draw_line_dsc_t if(draw_dsc->opa <= LV_OPA_MIN) return; #endif - draw_dsc->width = lv_obj_get_style_line_width(obj, part); - if(draw_dsc->width == 0) return; - draw_dsc->color = lv_obj_get_style_line_color(obj, part); draw_dsc->dash_width = lv_obj_get_style_line_dash_width(obj, part); @@ -4505,10 +4504,10 @@ static void update_style_cache(lv_obj_t * obj, uint8_t part, uint16_t prop) list->bg_grad_dir_none = lv_obj_get_style_bg_grad_dir(obj, part) == LV_GRAD_DIR_NONE ? 1 : 0; list->bg_opa_transp = lv_obj_get_style_bg_opa(obj, part) == LV_OPA_TRANSP ? 1 : 0; - list->border_width_zero = lv_obj_get_style_border_width(obj, part) == LV_OPA_TRANSP ? 1 : 0; + list->border_width_zero = lv_obj_get_style_border_width(obj, part) == 0 ? 1 : 0; list->clip_corner_off = lv_obj_get_style_clip_corner(obj, part) == false ? 1 : 0; list->img_recolor_opa_transp = lv_obj_get_style_image_recolor_opa(obj, part) == LV_OPA_TRANSP ? 1 : 0; - list->line_width_zerop = lv_obj_get_style_line_width(obj, part) == 0 ? 1 : 0; + list->line_width_zero = lv_obj_get_style_line_width(obj, part) == 0 ? 1 : 0; list->outline_width_zero = lv_obj_get_style_outline_width(obj, part) == 0 ? 1 : 0; list->pattern_img_null = lv_obj_get_style_pattern_image(obj, part) == NULL ? 1 : 0; list->shadow_width_zero = lv_obj_get_style_shadow_width(obj, part) == 0 ? 1 : 0; diff --git a/src/lv_core/lv_style.h b/src/lv_core/lv_style.h index c2eb75e77..78bb93783 100644 --- a/src/lv_core/lv_style.h +++ b/src/lv_core/lv_style.h @@ -226,8 +226,8 @@ typedef struct { uint32_t has_trans :1; uint32_t skip_trans :1; /*1: Temporally skip the transition style if any*/ uint32_t ignore_trans :1; /*1: Mark that this style list shouldn't receive transitions at all*/ - uint32_t valid_cache :1; /*1: The cache is invalid and needs to be updated*/ - uint32_t ignore_cache :1; /**1: Ignore style cache while getting value of properties*/ + uint32_t valid_cache :1; /*1: The cache is valid and can be used*/ + uint32_t ignore_cache :1; /*1: Ignore cache while getting value of properties*/ uint32_t opa_scale_cover :1; uint32_t clip_corner_off :1; @@ -241,7 +241,7 @@ typedef struct { uint32_t pad_all_zero :1; uint32_t shadow_width_zero :1; uint32_t value_txt_str :1; - uint32_t line_width_zerop :1; + uint32_t line_width_zero :1; uint32_t img_recolor_opa_transp :1; uint32_t text_letter_space_zero :1; uint32_t text_line_space_zero :1; From 07cb113c0a1b0892e67f5340a6ed402b347a26b9 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Mon, 3 Aug 2020 09:37:01 +0200 Subject: [PATCH 7/7] add radius, border_side and boder_post to style cache --- src/lv_core/lv_obj.c | 45 +++++++++++++++++++++++++++++++----------- src/lv_core/lv_style.c | 1 - src/lv_core/lv_style.h | 19 +++++++++++------- 3 files changed, 45 insertions(+), 20 deletions(-) diff --git a/src/lv_core/lv_obj.c b/src/lv_core/lv_obj.c index 33122c96d..4b51c7b04 100644 --- a/src/lv_core/lv_obj.c +++ b/src/lv_core/lv_obj.c @@ -2502,10 +2502,8 @@ lv_style_int_t _lv_obj_get_style_int(const lv_obj_t * obj, uint8_t part, lv_styl if(list->clip_corner_off) def = true; break; case LV_STYLE_TEXT_LETTER_SPACE: - if(list->text_letter_space_zero) def = true; - break; case LV_STYLE_TEXT_LINE_SPACE: - if(list->text_line_space_zero) def = true; + if(list->text_space_zero) def = true; break; case LV_STYLE_TRANSFORM_ANGLE: case LV_STYLE_TRANSFORM_WIDTH: @@ -2516,12 +2514,18 @@ lv_style_int_t _lv_obj_get_style_int(const lv_obj_t * obj, uint8_t part, lv_styl case LV_STYLE_BORDER_WIDTH: if(list->border_width_zero) def = true; break; - case LV_STYLE_LINE_WIDTH: - if(list->line_width_zero) def = true; + case LV_STYLE_BORDER_SIDE: + if(list->border_side_full) def = true; + break; + case LV_STYLE_BORDER_POST: + if(list->border_post_off) def = true; break; case LV_STYLE_OUTLINE_WIDTH: if(list->outline_width_zero) def = true; break; + case LV_STYLE_RADIUS: + if(list->radius_zero) def = true; + break; case LV_STYLE_SHADOW_WIDTH: if(list->shadow_width_zero) def = true; break; @@ -2676,6 +2680,7 @@ lv_opa_t _lv_obj_get_style_opa(const lv_obj_t * obj, uint8_t part, lv_style_prop if(list->opa_scale_cover) def = true; break; case LV_STYLE_BG_OPA: + if(list->bg_opa_cover) return LV_OPA_COVER; /*Special case, not the default value is used*/ if(list->bg_opa_transp) def = true; break; case LV_STYLE_IMAGE_RECOLOR_OPA: @@ -4449,11 +4454,13 @@ static bool style_prop_is_cacheble(lv_style_property_t prop) case LV_STYLE_TRANSFORM_HEIGHT: case LV_STYLE_TRANSFORM_ZOOM: case LV_STYLE_BORDER_WIDTH: - case LV_STYLE_LINE_WIDTH: case LV_STYLE_OUTLINE_WIDTH: + case LV_STYLE_RADIUS: case LV_STYLE_SHADOW_WIDTH: case LV_STYLE_OPA_SCALE: case LV_STYLE_BG_OPA: + case LV_STYLE_BORDER_SIDE: + case LV_STYLE_BORDER_POST: case LV_STYLE_IMAGE_RECOLOR_OPA: case LV_STYLE_VALUE_STR: case LV_STYLE_PATTERN_IMAGE: @@ -4498,18 +4505,28 @@ static void update_style_cache(lv_obj_t * obj, uint8_t part, uint16_t prop) list->opa_scale_cover = 1; #endif list->text_decor_none = lv_obj_get_style_text_decor(obj, part) == LV_TEXT_DECOR_NONE ? 1 : 0; - list->text_letter_space_zero = lv_obj_get_style_text_letter_space(obj, part) == 0 ? 1 : 0; - list->text_line_space_zero = lv_obj_get_style_text_line_space(obj, part) == 0 ? 1 : 0; list->text_font_normal = lv_obj_get_style_text_font(obj, part) == LV_THEME_DEFAULT_FONT_NORMAL ? 1 : 0; + list->text_space_zero = 1; + if(lv_obj_get_style_text_letter_space(obj, part) != 0 || + lv_obj_get_style_text_line_space(obj, part) != 0) { + list->text_space_zero = 0; + } + + + lv_opa_t bg_opa = lv_obj_get_style_bg_opa(obj, part); + list->bg_opa_transp = bg_opa == LV_OPA_TRANSP ? 1 : 0; + list->bg_opa_cover = bg_opa == LV_OPA_COVER ? 1 : 0; + list->bg_grad_dir_none = lv_obj_get_style_bg_grad_dir(obj, part) == LV_GRAD_DIR_NONE ? 1 : 0; - list->bg_opa_transp = lv_obj_get_style_bg_opa(obj, part) == LV_OPA_TRANSP ? 1 : 0; list->border_width_zero = lv_obj_get_style_border_width(obj, part) == 0 ? 1 : 0; + list->border_side_full = lv_obj_get_style_border_side(obj, part) == LV_BORDER_SIDE_FULL ? 1 : 0; + list->border_post_off = lv_obj_get_style_border_post(obj, part) == 0 ? 1 : 0; list->clip_corner_off = lv_obj_get_style_clip_corner(obj, part) == false ? 1 : 0; list->img_recolor_opa_transp = lv_obj_get_style_image_recolor_opa(obj, part) == LV_OPA_TRANSP ? 1 : 0; - list->line_width_zero = lv_obj_get_style_line_width(obj, part) == 0 ? 1 : 0; list->outline_width_zero = lv_obj_get_style_outline_width(obj, part) == 0 ? 1 : 0; list->pattern_img_null = lv_obj_get_style_pattern_image(obj, part) == NULL ? 1 : 0; + list->radius_zero = lv_obj_get_style_radius(obj, part) == 0 ? 1 : 0; list->shadow_width_zero = lv_obj_get_style_shadow_width(obj, part) == 0 ? 1 : 0; list->value_txt_str = lv_obj_get_style_value_str(obj, part) == NULL ? 1 : 0; @@ -4583,11 +4600,15 @@ static void update_style_cache_children(lv_obj_t * obj) list->opa_scale_cover = lv_obj_get_style_opa_scale(obj, part) == LV_OPA_COVER ? 1 : 0; list->text_decor_none = lv_obj_get_style_text_decor(obj, part) == LV_TEXT_DECOR_NONE ? 1 : 0; - list->text_letter_space_zero = lv_obj_get_style_text_letter_space(obj, part) == 0 ? 1 : 0; - list->text_line_space_zero = lv_obj_get_style_text_line_space(obj, part) == 0 ? 1 : 0; list->text_font_normal = lv_obj_get_style_text_font(obj, part) == lv_theme_get_font_normal() ? 1 : 0; list->img_recolor_opa_transp = lv_obj_get_style_image_recolor_opa(obj, part) == LV_OPA_TRANSP ? 1 : 0; + list->text_space_zero = 1; + if(lv_obj_get_style_text_letter_space(obj, part) != 0 || + lv_obj_get_style_text_line_space(obj, part) != 0) { + list->text_space_zero = 0; + } + list->ignore_cache = ignore_cache_ori; } diff --git a/src/lv_core/lv_style.c b/src/lv_core/lv_style.c index ce3665e0d..04ccd3a16 100644 --- a/src/lv_core/lv_style.c +++ b/src/lv_core/lv_style.c @@ -1037,7 +1037,6 @@ bool lv_debug_check_style_list(const lv_style_list_t * list) return true; } - /********************** * STATIC FUNCTIONS **********************/ diff --git a/src/lv_core/lv_style.h b/src/lv_core/lv_style.h index 78bb93783..93f7371b5 100644 --- a/src/lv_core/lv_style.h +++ b/src/lv_core/lv_style.h @@ -221,7 +221,7 @@ typedef struct { #if LV_USE_ASSERT_STYLE uint32_t sentinel; #endif - uint32_t style_cnt :7; + uint32_t style_cnt :6; uint32_t has_local :1; uint32_t has_trans :1; uint32_t skip_trans :1; /*1: Temporally skip the transition style if any*/ @@ -229,22 +229,27 @@ typedef struct { uint32_t valid_cache :1; /*1: The cache is valid and can be used*/ uint32_t ignore_cache :1; /*1: Ignore cache while getting value of properties*/ + uint32_t radius_zero :1; uint32_t opa_scale_cover :1; uint32_t clip_corner_off :1; uint32_t transform_all_zero :1; - uint32_t bg_opa_transp :1; - uint32_t bg_grad_dir_none :1; + uint32_t pad_all_zero :1; uint32_t blend_mode_all_normal :1; + uint32_t bg_opa_transp :1; + uint32_t bg_opa_cover :1; + uint32_t bg_grad_dir_none :1; + uint32_t border_width_zero :1; + uint32_t border_side_full :1; + uint32_t border_post_off :1; + uint32_t outline_width_zero :1; uint32_t pattern_img_null :1; - uint32_t pad_all_zero :1; uint32_t shadow_width_zero :1; uint32_t value_txt_str :1; - uint32_t line_width_zero :1; uint32_t img_recolor_opa_transp :1; - uint32_t text_letter_space_zero :1; - uint32_t text_line_space_zero :1; + + uint32_t text_space_zero :1; uint32_t text_decor_none :1; uint32_t text_font_normal :1; } lv_style_list_t;