perf(meter): invalidate only the needle area

This commit is contained in:
Gabor Kiss-Vamosi
2021-03-16 15:24:52 +01:00
parent 0f70859758
commit 9e8e892dff

View File

@@ -35,6 +35,7 @@ static void draw_ticks_and_labels(lv_obj_t * obj, const lv_area_t * clip_area, c
static void draw_needles(lv_obj_t * obj, const lv_area_t * clip_area, const lv_area_t * scale_area); static void draw_needles(lv_obj_t * obj, const lv_area_t * clip_area, const lv_area_t * scale_area);
static lv_meter_scale_t * get_scale_of_indic(lv_obj_t * obj, lv_meter_indicator_t * indic); static lv_meter_scale_t * get_scale_of_indic(lv_obj_t * obj, lv_meter_indicator_t * indic);
static void inv_arc(lv_obj_t * obj, lv_meter_indicator_t * indic, int32_t old_value, int32_t new_value); static void inv_arc(lv_obj_t * obj, lv_meter_indicator_t * indic, int32_t old_value, int32_t new_value);
static void inv_line(lv_obj_t * obj, lv_meter_indicator_t * indic, int32_t value);
/********************** /**********************
* STATIC VARIABLES * STATIC VARIABLES
@@ -197,6 +198,11 @@ void lv_meter_set_indicator_value(lv_obj_t * obj, lv_meter_indicator_t * indic,
if(indic->type == LV_METER_INDICATOR_TYPE_ARC) { if(indic->type == LV_METER_INDICATOR_TYPE_ARC) {
inv_arc(obj, indic, old_start, value); inv_arc(obj, indic, old_start, value);
inv_arc(obj, indic, old_end, value); inv_arc(obj, indic, old_end, value);
}
else if(indic->type == LV_METER_INDICATOR_TYPE_NEEDLE_IMG || indic->type == LV_METER_INDICATOR_TYPE_NEEDLE_LINE) {
inv_line(obj, indic, old_start);
inv_line(obj, indic, old_end);
inv_line(obj, indic, value);
} else { } else {
lv_obj_invalidate(obj); lv_obj_invalidate(obj);
} }
@@ -209,7 +215,12 @@ void lv_meter_set_indicator_start_value(lv_obj_t * obj, lv_meter_indicator_t * i
if(indic->type == LV_METER_INDICATOR_TYPE_ARC) { if(indic->type == LV_METER_INDICATOR_TYPE_ARC) {
inv_arc(obj, indic, old_value, value); inv_arc(obj, indic, old_value, value);
} else { }
else if(indic->type == LV_METER_INDICATOR_TYPE_NEEDLE_IMG || indic->type == LV_METER_INDICATOR_TYPE_NEEDLE_LINE) {
inv_line(obj, indic, old_value);
inv_line(obj, indic, value);
}
else {
lv_obj_invalidate(obj); lv_obj_invalidate(obj);
} }
} }
@@ -221,7 +232,12 @@ void lv_meter_set_indicator_end_value(lv_obj_t * obj, lv_meter_indicator_t * ind
if(indic->type == LV_METER_INDICATOR_TYPE_ARC) { if(indic->type == LV_METER_INDICATOR_TYPE_ARC) {
inv_arc(obj, indic, old_value, value); inv_arc(obj, indic, old_value, value);
} else { }
else if(indic->type == LV_METER_INDICATOR_TYPE_NEEDLE_IMG || indic->type == LV_METER_INDICATOR_TYPE_NEEDLE_LINE) {
inv_line(obj, indic, old_value);
inv_line(obj, indic, value);
}
else {
lv_obj_invalidate(obj); lv_obj_invalidate(obj);
} }
} }
@@ -285,11 +301,7 @@ static lv_draw_res_t lv_meter_draw(lv_obj_t * obj, const lv_area_t * clip_area,
lv_obj_draw_base(MY_CLASS, obj, clip_area, mode); lv_obj_draw_base(MY_CLASS, obj, clip_area, mode);
lv_area_t scale_area; lv_area_t scale_area;
lv_obj_get_coords(obj, &scale_area); lv_obj_get_coords_fit(obj, &scale_area);
scale_area.x1 += lv_obj_get_style_pad_left(obj, LV_PART_MAIN);
scale_area.y1 += lv_obj_get_style_pad_top(obj, LV_PART_MAIN);
scale_area.x2 -= lv_obj_get_style_pad_right(obj, LV_PART_MAIN);
scale_area.y2 -= lv_obj_get_style_pad_bottom(obj, LV_PART_MAIN);
draw_arcs(obj, clip_area, &scale_area); draw_arcs(obj, clip_area, &scale_area);
draw_ticks_and_labels(obj, clip_area, &scale_area); draw_ticks_and_labels(obj, clip_area, &scale_area);
@@ -577,7 +589,6 @@ static void draw_needles(lv_obj_t * obj, const lv_area_t * clip_area, const lv_a
line_dsc.width = indic->type_data.needle_line.width; line_dsc.width = indic->type_data.needle_line.width;
line_dsc.opa = indic->opa > LV_OPA_MAX ? opa_main : (opa_main * indic->opa) >> 8; line_dsc.opa = indic->opa > LV_OPA_MAX ? opa_main : (opa_main * indic->opa) >> 8;
lv_draw_line(&scale_center, &p_end, clip_area, &line_dsc); lv_draw_line(&scale_center, &p_end, clip_area, &line_dsc);
} }
else if(indic->type == LV_METER_INDICATOR_TYPE_NEEDLE_IMG) { else if(indic->type == LV_METER_INDICATOR_TYPE_NEEDLE_IMG) {
if(indic->type_data.needle_img.src == NULL) continue; if(indic->type_data.needle_img.src == NULL) continue;
@@ -625,11 +636,7 @@ static void inv_arc(lv_obj_t * obj, lv_meter_indicator_t * indic, int32_t old_va
bool rounded = lv_obj_get_style_arc_rounded(obj, LV_PART_ITEMS); bool rounded = lv_obj_get_style_arc_rounded(obj, LV_PART_ITEMS);
lv_area_t scale_area; lv_area_t scale_area;
lv_obj_get_coords(obj, &scale_area); lv_obj_get_coords_fit(obj, &scale_area);
scale_area.x1 += lv_obj_get_style_pad_left(obj, LV_PART_MAIN);
scale_area.y1 += lv_obj_get_style_pad_top(obj, LV_PART_MAIN);
scale_area.x2 -= lv_obj_get_style_pad_right(obj, LV_PART_MAIN);
scale_area.y2 -= lv_obj_get_style_pad_bottom(obj, LV_PART_MAIN);
lv_coord_t r_out = lv_area_get_width(&scale_area) / 2; lv_coord_t r_out = lv_area_get_width(&scale_area) / 2;
lv_point_t scale_center; lv_point_t scale_center;
@@ -647,4 +654,50 @@ static void inv_arc(lv_obj_t * obj, lv_meter_indicator_t * indic, int32_t old_va
lv_obj_invalidate_area(obj, &a); lv_obj_invalidate_area(obj, &a);
} }
static void inv_line(lv_obj_t * obj, lv_meter_indicator_t * indic, int32_t value)
{
lv_area_t scale_area;
lv_obj_get_coords_fit(obj, &scale_area);
lv_coord_t r_out = lv_area_get_width(&scale_area) / 2;
lv_point_t scale_center;
scale_center.x = scale_area.x1 + r_out;
scale_center.y = scale_area.y1 + r_out;
lv_meter_scale_t * scale = get_scale_of_indic(obj, indic);
if(indic->type == LV_METER_INDICATOR_TYPE_NEEDLE_LINE) {
int32_t angle = lv_map(value, scale->min, scale->max, scale->rotation, scale->rotation + scale->angle_range);
r_out += scale->r_mod + indic->type_data.needle_line.r_mod;
lv_point_t p_end;
p_end.y = (lv_trigo_sin(angle) * (r_out)) / LV_TRIGO_SIN_MAX + scale_center.y;
p_end.x = (lv_trigo_cos(angle) * (r_out)) / LV_TRIGO_SIN_MAX + scale_center.x;
lv_area_t a;
a.x1 = LV_MIN(scale_center.x, p_end.x) - indic->type_data.needle_line.width - 2;
a.y1 = LV_MIN(scale_center.y, p_end.y) - indic->type_data.needle_line.width - 2;
a.x2 = LV_MAX(scale_center.x, p_end.x) + indic->type_data.needle_line.width + 2;
a.y2 = LV_MAX(scale_center.y, p_end.y) + indic->type_data.needle_line.width + 2;
lv_obj_invalidate_area(obj, &a);
}
else if(indic->type == LV_METER_INDICATOR_TYPE_NEEDLE_IMG) {
int32_t angle = lv_map(value, scale->min, scale->max, scale->rotation, scale->rotation + scale->angle_range);
lv_img_header_t info;
lv_img_decoder_get_info(indic->type_data.needle_img.src, &info);
angle = angle * 10;
if(angle > 3600) angle -= 3600;
lv_area_t a;
_lv_img_buf_get_transformed_area(&a, info.w, info.h, angle, LV_IMG_ZOOM_NONE, &indic->type_data.needle_img.pivot);
a.x1 += scale_center.x;
a.y1 += scale_center.y;
a.x2 += scale_center.x;
a.y2 += scale_center.y;
lv_obj_invalidate_area(obj, &a);
}
}
#endif #endif