perf(label): reduce lv_label_refr_text calls (#9041)
Signed-off-by: yushuailong1 <yushuailong1@xiaomi.com>
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)`
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 1.3 KiB |