From c43704756fbc7bd0314ffb39aea18899afa0d3a5 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Wed, 5 Feb 2020 10:40:50 +0100 Subject: [PATCH 1/2] improve arc invalidation --- src/lv_api_map.h | 12 --------- src/lv_core/lv_refr.c | 2 +- src/lv_core/lv_style.c | 2 +- src/lv_objx/lv_arc.c | 53 ++++++++++++++++++++++++++++++++++++++-- src/lv_objx/lv_arc.h | 9 +++++++ src/lv_objx/lv_preload.c | 5 ++-- 6 files changed, 64 insertions(+), 19 deletions(-) diff --git a/src/lv_api_map.h b/src/lv_api_map.h index 904dcf93d..fde6f1633 100644 --- a/src/lv_api_map.h +++ b/src/lv_api_map.h @@ -31,18 +31,6 @@ extern "C" { * V6.0 COMPATIBILITY *--------------------*/ - -#if LV_USE_ARC - - -static inline void lv_arc_set_angles(lv_obj_t * arc, uint16_t start, uint16_t end) -{ - lv_arc_set_start_angle(arc, start); - lv_arc_set_end_angle(arc, end); -} - -#endif - #if LV_USE_CHART #define lv_chart_get_point_cnt lv_chart_get_point_count diff --git a/src/lv_core/lv_refr.c b/src/lv_core/lv_refr.c index 77fd95f13..c017491d6 100644 --- a/src/lv_core/lv_refr.c +++ b/src/lv_core/lv_refr.c @@ -539,7 +539,7 @@ static void lv_refr_obj(lv_obj_t * obj, const lv_area_t * mask_ori_p) style_debug.body.grad_color = debug_color; style_debug.body.border.width = 2; style_debug.body.border.color.full = (debug_color.full + 0x13) * 9; - lv_draw_rect(&obj_ext_mask, &obj_ext_mask, &style_debug, LV_OPA_50); + lv_draw_rect(&obj_ext_mask, &obj_ext_mask, &style_debug, LV_OPA_20); debug_color.full *= 17; debug_color.full += 0xA1; #endif diff --git a/src/lv_core/lv_style.c b/src/lv_core/lv_style.c index a2f69ecf5..c8a116632 100644 --- a/src/lv_core/lv_style.c +++ b/src/lv_core/lv_style.c @@ -117,7 +117,7 @@ void lv_style_init(void) lv_style_scr.line.opa = LV_OPA_COVER; lv_style_scr.line.color = lv_color_make(0x20, 0x20, 0x20); - lv_style_scr.line.width = 2; + lv_style_scr.line.width = 40; lv_style_scr.line.rounded = 0; lv_style_scr.line.blend_mode = LV_BLEND_MODE_NORMAL; diff --git a/src/lv_objx/lv_arc.c b/src/lv_objx/lv_arc.c index 5e6b1ab10..1c8df09c5 100644 --- a/src/lv_objx/lv_arc.c +++ b/src/lv_objx/lv_arc.c @@ -128,7 +128,6 @@ void lv_arc_set_start_angle(lv_obj_t * arc, int16_t start) lv_arc_ext_t * ext = lv_obj_get_ext_attr(arc); if(start > 360) start -= 360; - if(start < 0) start += 360; ext->angle_start = start; @@ -147,13 +146,35 @@ void lv_arc_set_end_angle(lv_obj_t * arc, int16_t end) lv_arc_ext_t * ext = lv_obj_get_ext_attr(arc); if(end > 360) end -= 360; - if(end < 0) end += 360; ext->angle_end= end; lv_obj_invalidate(arc); } + +/** + * Set the start and end angles + * @param arc pointer to an arc object + * @param start the start angle + * @param end the end angle + */ +void lv_arc_set_angles(lv_obj_t * arc, uint16_t start, uint16_t end) +{ + LV_ASSERT_OBJ(arc, LV_OBJX_NAME); + + lv_arc_ext_t * ext = lv_obj_get_ext_attr(arc); + + if(end > 360) end -= 360; + + if(start > 360) start -= 360; + + ext->angle_start = start; + ext->angle_end = end; + + lv_obj_invalidate(arc); +} + /** * Set a style of a arc. * @param arc pointer to arc object @@ -291,4 +312,32 @@ static lv_res_t lv_arc_signal(lv_obj_t * arc, lv_signal_t sign, void * param) return res; } + +static void inv_arc_area(lv_obj_t * arc, uint16_t start_angle, uint16_t end_angle) +{ + uint8_t start_quarter = start_angle / 90; + uint8_t end_quarter = end_angle / 90; + lv_coord_t r = (LV_MATH_MIN(lv_obj_get_width(arc), lv_obj_get_height(arc))) / 2; + lv_coord_t x = arc->coords.x1 + lv_obj_get_width(arc) / 2; + lv_coord_t y = arc->coords.y1 + lv_obj_get_height(arc) / 2; + const lv_style_t style = lv_arc_get_style(arc, LV_ARC_STYLE_MAIN); + lv_coord_t w = style->line.width; + lv_area_t inv_area; + + if(start_quarter == end_quarter) { + if(start_quarter == 3) { + /*Small arc here*/ + inv_area.x1 = x + ((lv_trigo_sin(start_angle + 90) * (r - q->width)) >> LV_TRIGO_SHIFT); + inv_area.y1 = y + ((lv_trigo_sin(start_angle) * (r)) >> LV_TRIGO_SHIFT); + + inv_area.x2 = x + ((lv_trigo_sin(end_angle + 90) * (r)) >> LV_TRIGO_SHIFT); + inv_area.y2 = y + ((lv_trigo_sin(end_angle) * (r - q->width)) >> LV_TRIGO_SHIFT); + + bool ok = lv_area_intersect(&quarter_area, &quarter_area, q->clip_area); + if(ok) lv_draw_rect(q->draw_area, &quarter_area, q->style, q->opa_scale); + } + } + +} + #endif diff --git a/src/lv_objx/lv_arc.h b/src/lv_objx/lv_arc.h index 1579f8baa..5717fa59a 100644 --- a/src/lv_objx/lv_arc.h +++ b/src/lv_objx/lv_arc.h @@ -74,6 +74,15 @@ void lv_arc_set_start_angle(lv_obj_t * arc, int16_t start); */ void lv_arc_set_end_angle(lv_obj_t * arc, int16_t end); +/** + * Set the start and end angles + * @param arc pointer to an arc object + * @param start the start angle + * @param end the end angle + */ +void lv_arc_set_angles(lv_obj_t * arc, uint16_t start, uint16_t end); + + /** * Set a style of a arc. * @param arc pointer to arc object diff --git a/src/lv_objx/lv_preload.c b/src/lv_objx/lv_preload.c index b00bb8cb5..fade599ed 100644 --- a/src/lv_objx/lv_preload.c +++ b/src/lv_objx/lv_preload.c @@ -87,7 +87,7 @@ lv_obj_t * lv_preload_create(lv_obj_t * par, const lv_obj_t * copy) ext->arc_length = LV_PRELOAD_DEF_ARC_LENGTH; ext->anim_type = LV_PRELOAD_DEF_ANIM; ext->anim_dir = LV_PRELOAD_DIR_FORWARD; - ext->time = LV_PRELOAD_DEF_SPIN_TIME; + ext->time = LV_PRELOAD_DEF_SPIN_TIME * 5; /*The signal and design functions are not copied so set them here*/ lv_obj_set_signal_cb(new_preload, lv_preload_signal); @@ -362,8 +362,7 @@ void lv_preload_spinner_anim(void * ptr, lv_anim_value_t val) angle_start = angle_start % 360; angle_end = angle_end % 360; - lv_arc_set_start_angle(preload, angle_start); - lv_arc_set_end_angle(preload, angle_end); + lv_arc_set_angles(preload, angle_start, angle_end); } /********************** From f5d20f5e305d4bd278777351bb322f96e18b23ec Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Wed, 5 Feb 2020 12:52:18 +0100 Subject: [PATCH 2/2] improve arc invalidation --- src/lv_core/lv_refr.c | 2 +- src/lv_objx/lv_arc.c | 85 +++++++++++++++++++++++++++++++++------- src/lv_objx/lv_preload.c | 2 +- 3 files changed, 72 insertions(+), 17 deletions(-) diff --git a/src/lv_core/lv_refr.c b/src/lv_core/lv_refr.c index c017491d6..c0932aefa 100644 --- a/src/lv_core/lv_refr.c +++ b/src/lv_core/lv_refr.c @@ -24,7 +24,7 @@ * DEFINES *********************/ /* Draw translucent random colored areas on the invalidated (redrawn) areas*/ -#define MASK_AREA_DEBUG 0 +#define MASK_AREA_DEBUG 1 /********************** * TYPEDEFS diff --git a/src/lv_objx/lv_arc.c b/src/lv_objx/lv_arc.c index 1c8df09c5..5ba4758de 100644 --- a/src/lv_objx/lv_arc.c +++ b/src/lv_objx/lv_arc.c @@ -28,6 +28,7 @@ **********************/ static lv_design_res_t lv_arc_design(lv_obj_t * arc, const lv_area_t * clip_area, lv_design_mode_t mode); static lv_res_t lv_arc_signal(lv_obj_t * arc, lv_signal_t sign, void * param); +static void inv_arc_area(lv_obj_t * arc, uint16_t start_angle, uint16_t end_angle); /********************** * STATIC VARIABLES @@ -166,13 +167,14 @@ void lv_arc_set_angles(lv_obj_t * arc, uint16_t start, uint16_t end) lv_arc_ext_t * ext = lv_obj_get_ext_attr(arc); if(end > 360) end -= 360; - if(start > 360) start -= 360; + inv_arc_area(arc, ext->angle_start, ext->angle_end); + ext->angle_start = start; ext->angle_end = end; - lv_obj_invalidate(arc); + inv_arc_area(arc, ext->angle_start, ext->angle_end); } /** @@ -317,27 +319,80 @@ static void inv_arc_area(lv_obj_t * arc, uint16_t start_angle, uint16_t end_angl { uint8_t start_quarter = start_angle / 90; uint8_t end_quarter = end_angle / 90; - lv_coord_t r = (LV_MATH_MIN(lv_obj_get_width(arc), lv_obj_get_height(arc))) / 2; lv_coord_t x = arc->coords.x1 + lv_obj_get_width(arc) / 2; lv_coord_t y = arc->coords.y1 + lv_obj_get_height(arc) / 2; - const lv_style_t style = lv_arc_get_style(arc, LV_ARC_STYLE_MAIN); - lv_coord_t w = style->line.width; + lv_coord_t rout = (LV_MATH_MIN(lv_obj_get_width(arc), lv_obj_get_height(arc))) / 2; + const lv_style_t * style = lv_arc_get_style(arc, LV_ARC_STYLE_MAIN); + lv_coord_t rin = rout - style->line.width; + lv_area_t inv_area; if(start_quarter == end_quarter) { - if(start_quarter == 3) { - /*Small arc here*/ - inv_area.x1 = x + ((lv_trigo_sin(start_angle + 90) * (r - q->width)) >> LV_TRIGO_SHIFT); - inv_area.y1 = y + ((lv_trigo_sin(start_angle) * (r)) >> LV_TRIGO_SHIFT); + if(start_quarter == 0) { + inv_area.y1 = y + ((lv_trigo_sin(start_angle) * rin) >> LV_TRIGO_SHIFT); + inv_area.x2 = x + ((lv_trigo_sin(start_angle + 90) * rout) >> LV_TRIGO_SHIFT); - inv_area.x2 = x + ((lv_trigo_sin(end_angle + 90) * (r)) >> LV_TRIGO_SHIFT); - inv_area.y2 = y + ((lv_trigo_sin(end_angle) * (r - q->width)) >> LV_TRIGO_SHIFT); + inv_area.y2 = y + ((lv_trigo_sin(end_angle) * rout) >> LV_TRIGO_SHIFT); + inv_area.x1 = x + ((lv_trigo_sin(end_angle + 90) * rin) >> LV_TRIGO_SHIFT); - bool ok = lv_area_intersect(&quarter_area, &quarter_area, q->clip_area); - if(ok) lv_draw_rect(q->draw_area, &quarter_area, q->style, q->opa_scale); + lv_obj_invalidate_area(arc, &inv_area); } + else if(start_quarter == 1) { + inv_area.y2 = y + ((lv_trigo_sin(start_angle) * rout) >> LV_TRIGO_SHIFT); + inv_area.x2 = x + ((lv_trigo_sin(start_angle + 90) * rin) >> LV_TRIGO_SHIFT); + + inv_area.y1 = y + ((lv_trigo_sin(end_angle) * rin) >> LV_TRIGO_SHIFT); + inv_area.x1 = x + ((lv_trigo_sin(end_angle + 90) * rout) >> LV_TRIGO_SHIFT); + + lv_obj_invalidate_area(arc, &inv_area); + } + else if(start_quarter == 2) { + inv_area.x1 = x + ((lv_trigo_sin(start_angle + 90) * rout) >> LV_TRIGO_SHIFT); + inv_area.y2 = y + ((lv_trigo_sin(start_angle) * rin) >> LV_TRIGO_SHIFT); + + inv_area.y1 = y + ((lv_trigo_sin(end_angle) * rout) >> LV_TRIGO_SHIFT); + inv_area.x2 = x + ((lv_trigo_sin(end_angle + 90) * rin) >> LV_TRIGO_SHIFT); + + lv_obj_invalidate_area(arc, &inv_area); + } + else if(start_quarter == 3) { + /*Small arc here*/ + inv_area.x1 = x + ((lv_trigo_sin(start_angle + 90) * rin) >> LV_TRIGO_SHIFT); + inv_area.y1 = y + ((lv_trigo_sin(start_angle) * rout) >> LV_TRIGO_SHIFT); + + inv_area.x2 = x + ((lv_trigo_sin(end_angle + 90) * rout) >> LV_TRIGO_SHIFT); + inv_area.y2 = y + ((lv_trigo_sin(end_angle) * rin) >> LV_TRIGO_SHIFT); + + lv_obj_invalidate_area(arc, &inv_area); + } + + } else if(start_quarter == 0 && end_quarter == 1) { + inv_area.x1 = x + ((lv_trigo_sin(end_angle + 90) * rout) >> LV_TRIGO_SHIFT); + inv_area.y1 = y + ((LV_MATH_MIN(lv_trigo_sin(end_angle), lv_trigo_sin(start_angle)) * rin) >> LV_TRIGO_SHIFT); + inv_area.x2 = x + ((lv_trigo_sin(start_angle + 90) * rout) >> LV_TRIGO_SHIFT); + inv_area.y2 = y + rout; + lv_obj_invalidate_area(arc, &inv_area); + } else if(start_quarter == 1 && end_quarter == 2) { + inv_area.x1 = x - rout; + inv_area.y1 = y + ((lv_trigo_sin(end_angle) * rout) >> LV_TRIGO_SHIFT); + inv_area.x2 = x + ((LV_MATH_MAX(lv_trigo_sin(start_angle + 90) , lv_trigo_sin(end_angle + 90)) * rin) >> LV_TRIGO_SHIFT); + inv_area.y2 = y + ((lv_trigo_sin(start_angle) * rout) >> LV_TRIGO_SHIFT); + lv_obj_invalidate_area(arc, &inv_area); + } else if(start_quarter == 2 && end_quarter == 3) { + inv_area.x1 = x + ((lv_trigo_sin(start_angle + 90) * rout) >> LV_TRIGO_SHIFT); + inv_area.y1 = y - rout; + inv_area.x2 = x + ((lv_trigo_sin(end_angle + 90) * rout) >> LV_TRIGO_SHIFT); + inv_area.y2 = y + (LV_MATH_MAX(lv_trigo_sin(end_angle) * rin, lv_trigo_sin(start_angle) * rin) >> LV_TRIGO_SHIFT); + lv_obj_invalidate_area(arc, &inv_area); + } else if(start_quarter == 3 && end_quarter == 0) { + inv_area.x1 = x + ((LV_MATH_MIN(lv_trigo_sin(end_angle + 90), lv_trigo_sin(start_angle + 90)) * rin) >> LV_TRIGO_SHIFT); + inv_area.y1 = y + ((lv_trigo_sin(start_angle) * rout) >> LV_TRIGO_SHIFT); + inv_area.x2 = x + rout; + inv_area.y2 = y + ((lv_trigo_sin(end_angle) * rout) >> LV_TRIGO_SHIFT); + + lv_obj_invalidate_area(arc, &inv_area); + } else { + lv_obj_invalidate(arc); } - } - #endif diff --git a/src/lv_objx/lv_preload.c b/src/lv_objx/lv_preload.c index fade599ed..005d82c02 100644 --- a/src/lv_objx/lv_preload.c +++ b/src/lv_objx/lv_preload.c @@ -87,7 +87,7 @@ lv_obj_t * lv_preload_create(lv_obj_t * par, const lv_obj_t * copy) ext->arc_length = LV_PRELOAD_DEF_ARC_LENGTH; ext->anim_type = LV_PRELOAD_DEF_ANIM; ext->anim_dir = LV_PRELOAD_DIR_FORWARD; - ext->time = LV_PRELOAD_DEF_SPIN_TIME * 5; + ext->time = LV_PRELOAD_DEF_SPIN_TIME * 10; /*The signal and design functions are not copied so set them here*/ lv_obj_set_signal_cb(new_preload, lv_preload_signal);