perf(label): reduce lv_label_refr_text calls (#9041)

Signed-off-by: yushuailong1 <yushuailong1@xiaomi.com>
This commit is contained in:
yushuailong
2025-10-26 17:17:45 +08:00
committed by GitHub
parent 8cd5eaff87
commit 1b5b484f27
11 changed files with 55 additions and 13 deletions
+19 -1
View File
@@ -35,7 +35,7 @@ static int32_t calc_content_height(lv_obj_t * obj);
static void layout_update_core(lv_obj_t * obj);
static void transform_point_array(const lv_obj_t * obj, lv_point_t * p, size_t p_count, bool inv);
static bool is_transformed(const lv_obj_t * obj);
static lv_obj_tree_walk_res_t update_layout_completed_cb(lv_obj_t * obj, void * user_data);
/**********************
* STATIC VARIABLES
**********************/
@@ -304,6 +304,12 @@ void lv_obj_mark_layout_as_dirty(lv_obj_t * obj)
lv_display_send_event(disp, LV_EVENT_REFR_REQUEST, NULL);
}
void lv_obj_request_layout_complete_event(lv_obj_t * obj)
{
lv_obj_t * scr = lv_obj_get_screen(obj);
scr->scr_layout_complete_pending = 1;
}
void lv_obj_update_layout(const lv_obj_t * obj)
{
if(update_layout_mutex) {
@@ -322,6 +328,11 @@ void lv_obj_update_layout(const lv_obj_t * obj)
LV_LOG_TRACE("Layout update end");
}
if(scr->scr_layout_complete_pending) {
scr->scr_layout_complete_pending = 0;
lv_obj_tree_walk(scr, update_layout_completed_cb, NULL);
}
update_layout_mutex = false;
LV_PROFILER_LAYOUT_END;
}
@@ -1316,3 +1327,10 @@ static void transform_point_array(const lv_obj_t * obj, lv_point_t * p, size_t p
lv_point_array_transform(p, p_count, angle, scale_x, scale_y, &pivot, !inv);
}
static lv_obj_tree_walk_res_t update_layout_completed_cb(lv_obj_t * obj, void * user_data)
{
LV_UNUSED(user_data);
lv_obj_send_event(obj, LV_EVENT_UPDATE_LAYOUT_COMPLETED, NULL);
return LV_OBJ_TREE_WALK_NEXT;
}
+6
View File
@@ -153,6 +153,12 @@ bool lv_obj_is_layout_positioned(const lv_obj_t * obj);
*/
void lv_obj_mark_layout_as_dirty(lv_obj_t * obj);
/**
* Mark screen to send layout completed event after update.
* @param obj Any object on the target screen
*/
void lv_obj_request_layout_complete_event(lv_obj_t * obj);
/**
* Update the layout of an object.
* @param obj pointer to an object whose position and size needs to be updated
+1
View File
@@ -71,6 +71,7 @@ struct _lv_obj_t {
uint16_t layout_inv : 1;
uint16_t readjust_scroll_after_layout : 1;
uint16_t scr_layout_inv : 1;
uint16_t scr_layout_complete_pending : 1;
uint16_t skip_trans : 1;
uint16_t style_cnt : 6;
uint16_t h_layout : 1;
+1
View File
@@ -353,6 +353,7 @@ const char * lv_event_code_get_name(lv_event_code_t code)
ENUM_CASE(EVENT_STYLE_CHANGED);
ENUM_CASE(EVENT_LAYOUT_CHANGED);
ENUM_CASE(EVENT_GET_SELF_SIZE);
ENUM_CASE(EVENT_UPDATE_LAYOUT_COMPLETED);
/** Events of optional LVGL components*/
ENUM_CASE(EVENT_INVALIDATE_AREA);
+1
View File
@@ -93,6 +93,7 @@ typedef enum {
LV_EVENT_STYLE_CHANGED, /**< Object's style has changed */
LV_EVENT_LAYOUT_CHANGED, /**< A child's position position has changed due to a layout recalculation */
LV_EVENT_GET_SELF_SIZE, /**< Get internal size of a widget */
LV_EVENT_UPDATE_LAYOUT_COMPLETED, /**< Sent after layout update completes*/
/** Events of optional LVGL components */
LV_EVENT_INVALIDATE_AREA, /**< An area is invalidated (marked for redraw). `lv_event_get_param(e)`
+26 -12
View File
@@ -62,7 +62,7 @@ static void copy_text_to_label(lv_label_t * label, const char * text);
static lv_text_flag_t get_label_flags(lv_label_t * label);
static void calculate_x_coordinate(int32_t * x, const lv_text_align_t align, const char * txt,
uint32_t length, const lv_font_t * font, lv_area_t * txt_coords, lv_text_attributes_t * attributes);
static void lv_label_mark_need_refr_text(lv_obj_t * obj);
#if LV_USE_OBSERVER
static void label_text_observer_cb(lv_observer_t * observer, lv_subject_t * subject);
#endif
@@ -166,7 +166,7 @@ void lv_label_set_text_vfmt(lv_obj_t * obj, const char * fmt, va_list args)
/*If text is NULL then refresh*/
if(fmt == NULL) {
lv_label_refr_text(obj);
lv_label_mark_need_refr_text(obj);
return;
}
@@ -178,7 +178,7 @@ void lv_label_set_text_vfmt(lv_obj_t * obj, const char * fmt, va_list args)
label->text = lv_text_set_text_vfmt(fmt, args);
label->static_txt = 0; /*Now the text is dynamically allocated*/
lv_label_refr_text(obj);
lv_label_mark_need_refr_text(obj);
}
void lv_label_set_text_static(lv_obj_t * obj, const char * text)
@@ -197,7 +197,7 @@ void lv_label_set_text_static(lv_obj_t * obj, const char * text)
label->text = (char *)text;
}
lv_label_refr_text(obj);
lv_label_mark_need_refr_text(obj);
}
#if LV_USE_TRANSLATION
@@ -240,7 +240,7 @@ void lv_label_set_long_mode(lv_obj_t * obj, lv_label_long_mode_t long_mode)
label->expand = 0;
label->long_mode = long_mode;
lv_label_refr_text(obj);
lv_label_mark_need_refr_text(obj);
}
void lv_label_set_text_selection_start(lv_obj_t * obj, uint32_t index)
@@ -281,7 +281,7 @@ void lv_label_set_recolor(lv_obj_t * obj, bool en)
label->recolor = en == false ? 0 : 1;
/*Refresh the text because the potential color codes in text needs to be hidden or revealed*/
lv_label_refr_text(obj);
lv_label_mark_need_refr_text(obj);
}
/*=====================
@@ -740,7 +740,7 @@ void lv_label_cut_text(lv_obj_t * obj, uint32_t pos, uint32_t cnt)
lv_text_cut(label_txt, pos, cnt);
/*Refresh the label*/
lv_label_refr_text(obj);
lv_label_mark_need_refr_text(obj);
}
@@ -806,7 +806,7 @@ static void lv_label_event(const lv_obj_class_t * class_p, lv_event_t * e)
lv_obj_t * obj = lv_event_get_current_target(e);
if((code == LV_EVENT_STYLE_CHANGED) || (code == LV_EVENT_SIZE_CHANGED)) {
lv_label_refr_text(obj);
lv_label_mark_need_refr_text(obj);
}
else if(code == LV_EVENT_REFR_EXT_DRAW_SIZE) {
/* Italic or other non-typical letters can be drawn of out of the object.
@@ -859,6 +859,9 @@ static void lv_label_event(const lv_obj_class_t * class_p, lv_event_t * e)
draw_main(e);
}
else if(code == LV_EVENT_UPDATE_LAYOUT_COMPLETED) {
lv_label_refr_text(obj);
}
#if LV_USE_TRANSLATION
else if(code == LV_EVENT_TRANSLATION_LANGUAGE_CHANGED) {
lv_label_t * label = (lv_label_t *)obj;
@@ -1022,7 +1025,7 @@ static void set_text_internal(lv_obj_t * obj, const char * text)
label->static_txt = 0;
}
lv_label_refr_text(obj);
lv_label_mark_need_refr_text(obj);
}
static void remove_translation_tag(lv_obj_t * obj)
@@ -1062,6 +1065,18 @@ static void overwrite_anim_property(lv_anim_t * dest, const lv_anim_t * src, lv_
}
}
static void lv_label_mark_need_refr_text(lv_obj_t * obj)
{
lv_label_t * label = (lv_label_t *)obj;
if(label->text == NULL) return;
label->invalid_size_cache = true;
label->need_refr_text = true;
lv_obj_refresh_self_size(obj);
lv_obj_request_layout_complete_event(obj);
}
/**
* Refresh the label with its text stored in its extended data
* @param label pointer to a label object
@@ -1070,10 +1085,11 @@ static void lv_label_refr_text(lv_obj_t * obj)
{
lv_label_t * label = (lv_label_t *)obj;
if(label->text == NULL) return;
if(!label->need_refr_text) return;
label->need_refr_text = false;
#if LV_LABEL_LONG_TXT_HINT
label->hint.line_start = -1; /*The hint is invalid if the text changes*/
#endif
label->invalid_size_cache = true;
lv_area_t txt_coords;
lv_text_attributes_t attributes = {0};
@@ -1091,8 +1107,6 @@ static void lv_label_refr_text(lv_obj_t * obj)
lv_text_get_size_attributes(&size, label->text, font, &attributes);
label->text_size = size;
lv_obj_refresh_self_size(obj);
/*In scroll mode start an offset animation*/
if(label->long_mode == LV_LABEL_LONG_MODE_SCROLL) {
const lv_anim_t * anim_template = lv_obj_get_style_anim(obj, LV_PART_MAIN);
+1
View File
@@ -53,6 +53,7 @@ struct _lv_label_t {
uint8_t recolor : 1; /**< Enable in-line letter re-coloring*/
uint8_t expand : 1; /**< Ignore real width (used by the library with LV_LABEL_LONG_MODE_SCROLL) */
uint8_t invalid_size_cache : 1; /**< 1: Recalculate size and update cache */
uint8_t need_refr_text : 1; /**< 1: Refresh text after layout update completion */
lv_point_t text_size;
};
Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB