mirror of
https://github.com/lvgl/lvgl.git
synced 2026-05-10 04:37:55 +08:00
feat(anim): add vsync mode (#8087)
This commit is contained in:
+53
-3
@@ -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)
|
||||
|
||||
@@ -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
|
||||
**********************/
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user