feat(anim): add vsync mode (#8087)

This commit is contained in:
VIFEX
2025-06-17 04:42:13 +08:00
committed by GitHub
parent a0a5a68e37
commit 1a36c4e61d
3 changed files with 103 additions and 3 deletions
+53 -3
View File
@@ -40,6 +40,7 @@
* STATIC PROTOTYPES
**********************/
static void anim_timer(lv_timer_t * param);
static void anim_vsync_event(lv_event_t * e);
static void anim_mark_list_change(void);
static void anim_completed_handler(lv_anim_t * a);
static int32_t lv_anim_path_cubic_bezier(const lv_anim_t * a, int32_t x1,
@@ -80,6 +81,30 @@ void lv_anim_core_deinit(void)
lv_anim_delete_all();
}
void lv_anim_enable_vsync_mode(bool enable)
{
if(enable) {
/* Remove animation timer, use vsync instead */
if(state.timer) {
lv_timer_delete(state.timer);
state.timer = NULL;
}
}
else {
if(!state.timer) {
state.timer = lv_timer_create(anim_timer, LV_DEF_REFR_PERIOD, NULL);
LV_ASSERT_NULL(state.timer);
if(state.anim_vsync_registered) {
lv_display_unregister_vsync_event(NULL, anim_vsync_event, NULL);
state.anim_vsync_registered = false;
}
}
}
anim_mark_list_change();
}
void lv_anim_init(lv_anim_t * a)
{
lv_memzero(a, sizeof(lv_anim_t));
@@ -682,13 +707,38 @@ static void anim_completed_handler(lv_anim_t * a)
}
}
static void anim_vsync_event(lv_event_t * e)
{
LV_UNUSED(e);
anim_timer(NULL);
}
static void anim_mark_list_change(void)
{
state.anim_list_changed = true;
if(lv_ll_get_head(anim_ll_p) == NULL)
lv_timer_pause(state.timer);
else
if(lv_ll_get_head(anim_ll_p) == NULL) {
if(state.timer) {
lv_timer_pause(state.timer);
return;
}
if(state.anim_vsync_registered) {
lv_display_unregister_vsync_event(NULL, anim_vsync_event, NULL);
state.anim_vsync_registered = false;
}
return;
}
if(state.timer) {
lv_timer_resume(state.timer);
return;
}
if(!state.anim_vsync_registered) {
lv_display_register_vsync_event(NULL, anim_vsync_event, NULL);
state.anim_vsync_registered = true;
}
}
static int32_t lv_anim_path_cubic_bezier(const lv_anim_t * a, int32_t x1, int32_t y1, int32_t x2, int32_t y2)
+7
View File
@@ -27,6 +27,7 @@ extern "C" {
typedef struct {
bool anim_list_changed;
bool anim_run_round;
bool anim_vsync_registered;
lv_timer_t * timer;
lv_ll_t anim_ll;
} lv_anim_state_t;
@@ -45,6 +46,12 @@ void lv_anim_core_init(void);
*/
void lv_anim_core_deinit(void);
/*
* Set animation use vsync mode.
* @param enable true: use vsync mode, false: use timer mode.
*/
void lv_anim_enable_vsync_mode(bool enable);
/**********************
* MACROS
**********************/
+43
View File
@@ -15,6 +15,7 @@ void tearDown(void)
/* Function run after every test */
lv_obj_clean(lv_screen_active());
lv_anim_delete_all();
lv_anim_enable_vsync_mode(false);
}
static void exec_cb(void * var, int32_t v)
@@ -193,4 +194,46 @@ void test_scroll_anim_delete(void)
TEST_ASSERT_EQUAL(1, var);
}
void test_anim_vsync_mode(void)
{
lv_anim_enable_vsync_mode(true);
/* anim timer should be NULL when vsync mode is enabled */
TEST_ASSERT_NULL(lv_anim_get_timer());
int32_t var;
/*Start an animation*/
lv_anim_t a;
lv_anim_init(&a);
lv_anim_set_var(&a, &var);
lv_anim_set_values(&a, 0, 1000);
lv_anim_set_exec_cb(&a, exec_cb);
lv_anim_set_duration(&a, 1000);
lv_anim_start(&a);
/*Use vsync events to notify anim updates*/
lv_tick_inc(10);
lv_display_send_vsync_event(NULL, NULL);
TEST_ASSERT_EQUAL(9, var);
lv_tick_inc(10);
lv_display_send_vsync_event(NULL, NULL);
TEST_ASSERT_EQUAL(19, var);
lv_anim_enable_vsync_mode(false);
TEST_ASSERT_NOT_NULL(lv_anim_get_timer());
/* Should not update the animation with vsync events when vsync mode is disabled */
lv_tick_inc(20);
lv_display_send_vsync_event(NULL, NULL);
TEST_ASSERT_EQUAL(19, var);
/* Test normal timer mode */
lv_test_wait(20);
TEST_ASSERT_EQUAL(59, var);
lv_anim_delete(&var, exec_cb);
}
#endif