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 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 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 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
|
* 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);
|
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)
|
void lv_obj_update_layout(const lv_obj_t * obj)
|
||||||
{
|
{
|
||||||
if(update_layout_mutex) {
|
if(update_layout_mutex) {
|
||||||
@@ -322,6 +328,11 @@ void lv_obj_update_layout(const lv_obj_t * obj)
|
|||||||
LV_LOG_TRACE("Layout update end");
|
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;
|
update_layout_mutex = false;
|
||||||
LV_PROFILER_LAYOUT_END;
|
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);
|
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);
|
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.
|
* Update the layout of an object.
|
||||||
* @param obj pointer to an object whose position and size needs to be updated
|
* @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 layout_inv : 1;
|
||||||
uint16_t readjust_scroll_after_layout : 1;
|
uint16_t readjust_scroll_after_layout : 1;
|
||||||
uint16_t scr_layout_inv : 1;
|
uint16_t scr_layout_inv : 1;
|
||||||
|
uint16_t scr_layout_complete_pending : 1;
|
||||||
uint16_t skip_trans : 1;
|
uint16_t skip_trans : 1;
|
||||||
uint16_t style_cnt : 6;
|
uint16_t style_cnt : 6;
|
||||||
uint16_t h_layout : 1;
|
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_STYLE_CHANGED);
|
||||||
ENUM_CASE(EVENT_LAYOUT_CHANGED);
|
ENUM_CASE(EVENT_LAYOUT_CHANGED);
|
||||||
ENUM_CASE(EVENT_GET_SELF_SIZE);
|
ENUM_CASE(EVENT_GET_SELF_SIZE);
|
||||||
|
ENUM_CASE(EVENT_UPDATE_LAYOUT_COMPLETED);
|
||||||
|
|
||||||
/** Events of optional LVGL components*/
|
/** Events of optional LVGL components*/
|
||||||
ENUM_CASE(EVENT_INVALIDATE_AREA);
|
ENUM_CASE(EVENT_INVALIDATE_AREA);
|
||||||
|
|||||||
@@ -93,6 +93,7 @@ typedef enum {
|
|||||||
LV_EVENT_STYLE_CHANGED, /**< Object's style has changed */
|
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_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_GET_SELF_SIZE, /**< Get internal size of a widget */
|
||||||
|
LV_EVENT_UPDATE_LAYOUT_COMPLETED, /**< Sent after layout update completes*/
|
||||||
|
|
||||||
/** Events of optional LVGL components */
|
/** Events of optional LVGL components */
|
||||||
LV_EVENT_INVALIDATE_AREA, /**< An area is invalidated (marked for redraw). `lv_event_get_param(e)`
|
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 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,
|
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);
|
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
|
#if LV_USE_OBSERVER
|
||||||
static void label_text_observer_cb(lv_observer_t * observer, lv_subject_t * subject);
|
static void label_text_observer_cb(lv_observer_t * observer, lv_subject_t * subject);
|
||||||
#endif
|
#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 text is NULL then refresh*/
|
||||||
if(fmt == NULL) {
|
if(fmt == NULL) {
|
||||||
lv_label_refr_text(obj);
|
lv_label_mark_need_refr_text(obj);
|
||||||
return;
|
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->text = lv_text_set_text_vfmt(fmt, args);
|
||||||
label->static_txt = 0; /*Now the text is dynamically allocated*/
|
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)
|
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;
|
label->text = (char *)text;
|
||||||
}
|
}
|
||||||
|
|
||||||
lv_label_refr_text(obj);
|
lv_label_mark_need_refr_text(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LV_USE_TRANSLATION
|
#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->expand = 0;
|
||||||
|
|
||||||
label->long_mode = long_mode;
|
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)
|
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;
|
label->recolor = en == false ? 0 : 1;
|
||||||
|
|
||||||
/*Refresh the text because the potential color codes in text needs to be hidden or revealed*/
|
/*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);
|
lv_text_cut(label_txt, pos, cnt);
|
||||||
|
|
||||||
/*Refresh the label*/
|
/*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);
|
lv_obj_t * obj = lv_event_get_current_target(e);
|
||||||
|
|
||||||
if((code == LV_EVENT_STYLE_CHANGED) || (code == LV_EVENT_SIZE_CHANGED)) {
|
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) {
|
else if(code == LV_EVENT_REFR_EXT_DRAW_SIZE) {
|
||||||
/* Italic or other non-typical letters can be drawn of out of the object.
|
/* 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);
|
draw_main(e);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
else if(code == LV_EVENT_UPDATE_LAYOUT_COMPLETED) {
|
||||||
|
lv_label_refr_text(obj);
|
||||||
|
}
|
||||||
#if LV_USE_TRANSLATION
|
#if LV_USE_TRANSLATION
|
||||||
else if(code == LV_EVENT_TRANSLATION_LANGUAGE_CHANGED) {
|
else if(code == LV_EVENT_TRANSLATION_LANGUAGE_CHANGED) {
|
||||||
lv_label_t * label = (lv_label_t *)obj;
|
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;
|
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)
|
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
|
* Refresh the label with its text stored in its extended data
|
||||||
* @param label pointer to a label object
|
* @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;
|
lv_label_t * label = (lv_label_t *)obj;
|
||||||
if(label->text == NULL) return;
|
if(label->text == NULL) return;
|
||||||
|
if(!label->need_refr_text) return;
|
||||||
|
label->need_refr_text = false;
|
||||||
#if LV_LABEL_LONG_TXT_HINT
|
#if LV_LABEL_LONG_TXT_HINT
|
||||||
label->hint.line_start = -1; /*The hint is invalid if the text changes*/
|
label->hint.line_start = -1; /*The hint is invalid if the text changes*/
|
||||||
#endif
|
#endif
|
||||||
label->invalid_size_cache = true;
|
|
||||||
|
|
||||||
lv_area_t txt_coords;
|
lv_area_t txt_coords;
|
||||||
lv_text_attributes_t attributes = {0};
|
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);
|
lv_text_get_size_attributes(&size, label->text, font, &attributes);
|
||||||
label->text_size = size;
|
label->text_size = size;
|
||||||
|
|
||||||
lv_obj_refresh_self_size(obj);
|
|
||||||
|
|
||||||
/*In scroll mode start an offset animation*/
|
/*In scroll mode start an offset animation*/
|
||||||
if(label->long_mode == LV_LABEL_LONG_MODE_SCROLL) {
|
if(label->long_mode == LV_LABEL_LONG_MODE_SCROLL) {
|
||||||
const lv_anim_t * anim_template = lv_obj_get_style_anim(obj, LV_PART_MAIN);
|
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 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 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 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;
|
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 |