From 3fbdd7b6c11ac033ff49e82aead648ea3346b3f5 Mon Sep 17 00:00:00 2001 From: Neo Xu Date: Sat, 24 Jun 2023 02:32:25 +0800 Subject: [PATCH] fix(anim): fix compile warnings (#4305) Signed-off-by: Xu Xingliang --- src/misc/lv_anim.c | 11 ++++---- src/misc/lv_math.h | 29 +++++++++++++-------- src/widgets/spinner/lv_spinner.c | 17 +++++++++++- tests/CMakeLists.txt | 1 + tests/src/test_cases/test_math.c | 44 ++++++++++++++++++++++++-------- 5 files changed, 75 insertions(+), 27 deletions(-) diff --git a/src/misc/lv_anim.c b/src/misc/lv_anim.c index 13249cded..3106e65c7 100644 --- a/src/misc/lv_anim.c +++ b/src/misc/lv_anim.c @@ -25,8 +25,6 @@ * TYPEDEFS **********************/ -#define _path_cubic_bezier(a, x1, x2, y1, y2) lv_anim_path_cubic_bezier(a, (x1) * 1024, (y1) * 1024, (x2) * 1024, (y2) * 1024) - /********************** * STATIC PROTOTYPES **********************/ @@ -225,17 +223,20 @@ int32_t lv_anim_path_linear(const lv_anim_t * a) int32_t lv_anim_path_ease_in(const lv_anim_t * a) { - return _path_cubic_bezier(a, 0.42, 0.0, 1.0, 1.0); + return lv_anim_path_cubic_bezier(a, LV_BEZIER_VAL_FLOAT(0.42), LV_BEZIER_VAL_FLOAT(0), + LV_BEZIER_VAL_FLOAT(1), LV_BEZIER_VAL_FLOAT(1)); } int32_t lv_anim_path_ease_out(const lv_anim_t * a) { - return _path_cubic_bezier(a, 0.0, 0.0, 0.58, 1.0); + return lv_anim_path_cubic_bezier(a, LV_BEZIER_VAL_FLOAT(0), LV_BEZIER_VAL_FLOAT(0), + LV_BEZIER_VAL_FLOAT(0.58), LV_BEZIER_VAL_FLOAT(1)); } int32_t lv_anim_path_ease_in_out(const lv_anim_t * a) { - return _path_cubic_bezier(a, 0.42, 0.0, 0.58, 1.0); + return lv_anim_path_cubic_bezier(a, LV_BEZIER_VAL_FLOAT(0.42), LV_BEZIER_VAL_FLOAT(0), + LV_BEZIER_VAL_FLOAT(0.58), LV_BEZIER_VAL_FLOAT(1)); } int32_t lv_anim_path_overshoot(const lv_anim_t * a) diff --git a/src/misc/lv_math.h b/src/misc/lv_math.h index 88e7d5f52..af2036e86 100644 --- a/src/misc/lv_math.h +++ b/src/misc/lv_math.h @@ -15,6 +15,7 @@ extern "C" { *********************/ #include "../lv_conf_internal.h" #include +#include "lv_types.h" /********************* * DEFINES @@ -24,17 +25,7 @@ extern "C" { #define LV_BEZIER_VAL_SHIFT 10 /**< log2(LV_BEZIER_VAL_MAX): used to normalize up scaled values*/ #define LV_BEZIER_VAL_MAX (1L << LV_BEZIER_VAL_SHIFT) /**< Max time in Bezier functions (not [0..1] to use integers)*/ - -/** - * Calculate a value of a Cubic Bezier function. - * @param t time in range of [0..LV_BEZIER_VAL_MAX] - * @param u0 must be 0 - * @param u1 control value 1 values in range of [0..LV_BEZIER_VAL_MAX] - * @param u2 control value 2 in range of [0..LV_BEZIER_VAL_MAX] - * @param u3 must be LV_BEZIER_VAL_MAX - * @return the value calculated from the given parameters in range of [0..LV_BEZIER_VAL_MAX] - */ -#define lv_bezier3(t, u0, u1, u2, u3) lv_cubic_bezier(t, 341, u1, 683, u2) +#define LV_BEZIER_VAL_FLOAT(f) ((int32_t)((f) * LV_BEZIER_VAL_MAX)) /**< Convert const float number cubic-bezier values to fix-point value*/ /********************** * TYPEDEFS @@ -75,6 +66,22 @@ static inline LV_ATTRIBUTE_FAST_MEM int32_t lv_trigo_cos(int16_t angle) */ int32_t lv_cubic_bezier(int32_t x, int32_t x1, int32_t y1, int32_t x2, int32_t y2); +/** + * Calculate a value of a Cubic Bezier function. + * @param t time in range of [0..LV_BEZIER_VAL_MAX] + * @param u0 must be 0 + * @param u1 control value 1 values in range of [0..LV_BEZIER_VAL_MAX] + * @param u2 control value 2 in range of [0..LV_BEZIER_VAL_MAX] + * @param u3 must be LV_BEZIER_VAL_MAX + * @return the value calculated from the given parameters in range of [0..LV_BEZIER_VAL_MAX] + */ +static inline int32_t lv_bezier3(int32_t t, int32_t u0, uint32_t u1, int32_t u2, int32_t u3) +{ + LV_UNUSED(u0); + LV_UNUSED(u3); + return lv_cubic_bezier(t, 341, u1, 683, u2); +} + /** * Calculate the atan2 of a vector. * @param x diff --git a/src/widgets/spinner/lv_spinner.c b/src/widgets/spinner/lv_spinner.c index 6fc6d7421..659dac4f9 100644 --- a/src/widgets/spinner/lv_spinner.c +++ b/src/widgets/spinner/lv_spinner.c @@ -23,6 +23,7 @@ static void lv_spinner_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj); static void arc_anim_start_angle(void * obj, int32_t v); static void arc_anim_end_angle(void * obj, int32_t v); +static int32_t anim_path(const lv_anim_t * a); /********************** * STATIC VARIABLES @@ -80,7 +81,7 @@ static void lv_spinner_constructor(const lv_obj_class_t * class_p, lv_obj_t * ob lv_anim_set_values(&a, arc_length_param, 360 + arc_length_param); lv_anim_start(&a); - lv_anim_set_path_cb(&a, lv_anim_path_ease_in_out); + lv_anim_set_path_cb(&a, anim_path); lv_anim_set_values(&a, 0, 360); lv_anim_set_exec_cb(&a, arc_anim_start_angle); lv_anim_start(&a); @@ -101,4 +102,18 @@ static void arc_anim_end_angle(void * obj, int32_t v) lv_arc_set_end_angle(obj, (uint16_t) v); } +static int32_t anim_path(const lv_anim_t * a) +{ + uint32_t t = lv_map(a->act_time, 0, a->time, 0, LV_BEZIER_VAL_MAX); + int32_t step = lv_cubic_bezier(t, LV_BEZIER_VAL_FLOAT(0.42), LV_BEZIER_VAL_FLOAT(0.58), + LV_BEZIER_VAL_FLOAT(0), LV_BEZIER_VAL_FLOAT(1)); + + int32_t new_value; + new_value = step * (a->end_value - a->start_value); + new_value = new_value >> LV_BEZIER_VAL_SHIFT; + new_value += a->start_value; + + return new_value; +} + #endif /*LV_USE_SPINNER*/ diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 3493a2c53..576c71f1b 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -107,6 +107,7 @@ set(COMPILE_OPTIONS -Wundef -Wuninitialized -Wunreachable-code + -Werror=float-conversion ${BUILD_OPTIONS} ) diff --git a/tests/src/test_cases/test_math.c b/tests/src/test_cases/test_math.c index 8348be79f..9881845a4 100644 --- a/tests/src/test_cases/test_math.c +++ b/tests/src/test_cases/test_math.c @@ -81,15 +81,15 @@ static int test_cubic_bezier_ease_functions(float fx1, float fy1, float fx2, flo float t, t_step, fy; t_step = .001f; - x1 = fx1 * 1024; - y1 = fy1 * 1024; - x2 = fx2 * 1024; - y2 = fy2 * 1024; + x1 = LV_BEZIER_VAL_FLOAT(fx1); + y1 = LV_BEZIER_VAL_FLOAT(fy1); + x2 = LV_BEZIER_VAL_FLOAT(fx2); + y2 = LV_BEZIER_VAL_FLOAT(fy2); for(t = 0; t <= 1; t += t_step) { fy = lv_cubic_bezier_f(t, fx1, fy1, fx2, fy2); - y = lv_cubic_bezier(t * 1024, x1, y1, x2, y2); - if(LV_ABS(fy * 1024 - y) >= ERROR_THRESHOLD) { + y = lv_cubic_bezier(LV_BEZIER_VAL_FLOAT(t), x1, y1, x2, y2); + if(LV_ABS(LV_BEZIER_VAL_FLOAT(fy) - y) >= ERROR_THRESHOLD) { return 0; } } @@ -97,19 +97,43 @@ static int test_cubic_bezier_ease_functions(float fx1, float fy1, float fx2, flo return 1; } +static uint32_t lv_bezier3_legacy(uint32_t t, uint32_t u0, uint32_t u1, uint32_t u2, uint32_t u3) +{ + uint32_t t_rem = 1024 - t; + uint32_t t_rem2 = (t_rem * t_rem) >> 10; + uint32_t t_rem3 = (t_rem2 * t_rem) >> 10; + uint32_t t2 = (t * t) >> 10; + uint32_t t3 = (t2 * t) >> 10; + + uint32_t v1 = (t_rem3 * u0) >> 10; + uint32_t v2 = (3 * t_rem2 * t * u1) >> 20; + uint32_t v3 = (3 * t_rem * t2 * u2) >> 20; + uint32_t v4 = (t3 * u3) >> 10; + + return v1 + v2 + v3 + v4; +} + void test_math_cubic_bezier_result_should_be_precise(void) { /*ease-in-out function*/ - TEST_ASSERT_TRUE(test_cubic_bezier_ease_functions(.42, 0, .58, 1)); + TEST_ASSERT_TRUE(test_cubic_bezier_ease_functions(.42f, 0, .58f, 1)); /*ease-out function*/ - TEST_ASSERT_TRUE(test_cubic_bezier_ease_functions(0, 0, .58, 1)); + TEST_ASSERT_TRUE(test_cubic_bezier_ease_functions(0, 0, .58f, 1)); /*ease-in function*/ - TEST_ASSERT_TRUE(test_cubic_bezier_ease_functions(.42, 0, 1, 1)); + TEST_ASSERT_TRUE(test_cubic_bezier_ease_functions(.42f, 0, 1, 1)); /*ease function*/ - TEST_ASSERT_TRUE(test_cubic_bezier_ease_functions(.25, .1, .25, 1)); + TEST_ASSERT_TRUE(test_cubic_bezier_ease_functions(.25f, .1f, .25f, 1)); + + int32_t u0 = 0, u1 = 50, u2 = 952, u3 = LV_BEZIER_VAL_MAX; + for(int32_t i = 0; i <= 1024; i++) { + int32_t legacy = lv_bezier3_legacy(i, u0, u1, u2, u3); + int32_t cubic_bezier = lv_bezier3(i, u0, u1, u2, u3); + + TEST_ASSERT_TRUE(LV_ABS(legacy - cubic_bezier) <= 5); + } } #endif