diff options
author | Derek Foreman <derek.foreman.samsung@gmail.com> | 2018-09-18 09:42:38 -0500 |
---|---|---|
committer | Derek Foreman <derek.foreman.samsung@gmail.com> | 2018-09-18 09:42:38 -0500 |
commit | 4dc1e8273d3ee2e118c6ec7bdf6135771688e662 (patch) | |
tree | b68084a95b0d8652aa30184b557d4af35684e103 /src/lib/ecore_evas | |
parent | 448c7ca2ce6485d885b48407919e715de3365b28 (diff) |
ecore: Add new way to register animators
Summary:
We have back-ends that can generate their own tick sources, but
ecore_animator_add()/ecore_animator_timeline_add() gives no indication
which backend the animator is running on. This means that all animators
have to cause all currently in use backends to tick.
For example, if under wayland 4 application windows are open, all 4
windows will create ticks when any animator is present.
These new animator APIs that take an evas object allow us to figure out
out the backend and only cause the appropriate one to tick.
Depends on D7040
Reviewers: devilhorns
Reviewed By: devilhorns
Subscribers: devilhorns, cedric, #reviewers, #committers
Tags: #efl
Differential Revision: https://phab.enlightenment.org/D7041
Diffstat (limited to 'src/lib/ecore_evas')
-rw-r--r-- | src/lib/ecore_evas/ecore_evas.c | 220 | ||||
-rw-r--r-- | src/lib/ecore_evas/ecore_evas_private.h | 7 |
2 files changed, 227 insertions, 0 deletions
diff --git a/src/lib/ecore_evas/ecore_evas.c b/src/lib/ecore_evas/ecore_evas.c index e7540b6b94..99d1e1f21e 100644 --- a/src/lib/ecore_evas/ecore_evas.c +++ b/src/lib/ecore_evas/ecore_evas.c | |||
@@ -39,6 +39,8 @@ | |||
39 | #define EFL_INTERNAL_UNSTABLE | 39 | #define EFL_INTERNAL_UNSTABLE |
40 | #include "interfaces/efl_common_internal.h" | 40 | #include "interfaces/efl_common_internal.h" |
41 | 41 | ||
42 | #include "ecore_private.h" | ||
43 | |||
42 | #ifndef O_BINARY | 44 | #ifndef O_BINARY |
43 | # define O_BINARY 0 | 45 | # define O_BINARY 0 |
44 | #endif | 46 | #endif |
@@ -71,6 +73,14 @@ static const Efl_Event_Description *_event_description_get(Efl_Pointer_Action ac | |||
71 | //RENDER_SYNC | 73 | //RENDER_SYNC |
72 | static int _ecore_evas_render_sync = 1; | 74 | static int _ecore_evas_render_sync = 1; |
73 | 75 | ||
76 | static void _ecore_evas_animator_flush(Ecore_Evas *ee); | ||
77 | |||
78 | static Ecore_Animator *_ecore_evas_animator_timeline_add(void *evo, double runtime, Ecore_Timeline_Cb func, const void *data); | ||
79 | static Ecore_Animator *_ecore_evas_animator_add(void *evo, Ecore_Task_Cb func, const void *data); | ||
80 | static void _ecore_evas_animator_freeze(Ecore_Animator *animator); | ||
81 | static void _ecore_evas_animator_thaw(Ecore_Animator *animator); | ||
82 | static void *_ecore_evas_animator_del(Ecore_Animator *animator); | ||
83 | |||
74 | static void | 84 | static void |
75 | _ecore_evas_focus_out_dispatch(Ecore_Evas *ee, Efl_Input_Device *seat) | 85 | _ecore_evas_focus_out_dispatch(Ecore_Evas *ee, Efl_Input_Device *seat) |
76 | { | 86 | { |
@@ -215,6 +225,9 @@ _ecore_evas_idle_enter(void *data EINA_UNUSED) | |||
215 | } | 225 | } |
216 | EINA_INLIST_FOREACH(ecore_evases, ee) | 226 | EINA_INLIST_FOREACH(ecore_evases, ee) |
217 | { | 227 | { |
228 | if (ee->ee_anim.deleted) | ||
229 | _ecore_evas_animator_flush(ee); | ||
230 | |||
218 | if (ee->draw_block) continue; | 231 | if (ee->draw_block) continue; |
219 | 232 | ||
220 | if (ee->manual_render) | 233 | if (ee->manual_render) |
@@ -588,6 +601,8 @@ ecore_evas_engine_type_supported_get(Ecore_Evas_Engine_Type engine) | |||
588 | EAPI int | 601 | EAPI int |
589 | ecore_evas_init(void) | 602 | ecore_evas_init(void) |
590 | { | 603 | { |
604 | Ecore_Evas_Object_Animator_Interface iface; | ||
605 | |||
591 | if (++_ecore_evas_init_count != 1) | 606 | if (++_ecore_evas_init_count != 1) |
592 | return _ecore_evas_init_count; | 607 | return _ecore_evas_init_count; |
593 | 608 | ||
@@ -629,6 +644,14 @@ ecore_evas_init(void) | |||
629 | _ecore_evas_app_comp_sync = EINA_FALSE; | 644 | _ecore_evas_app_comp_sync = EINA_FALSE; |
630 | else if (getenv("ECORE_EVAS_COMP_SYNC")) | 645 | else if (getenv("ECORE_EVAS_COMP_SYNC")) |
631 | _ecore_evas_app_comp_sync = EINA_TRUE; | 646 | _ecore_evas_app_comp_sync = EINA_TRUE; |
647 | |||
648 | iface.add = _ecore_evas_animator_add; | ||
649 | iface.timeline_add = _ecore_evas_animator_timeline_add; | ||
650 | iface.freeze = _ecore_evas_animator_freeze; | ||
651 | iface.thaw = _ecore_evas_animator_thaw; | ||
652 | iface.del = _ecore_evas_animator_del; | ||
653 | ecore_evas_object_animator_init(&iface); | ||
654 | |||
632 | return _ecore_evas_init_count; | 655 | return _ecore_evas_init_count; |
633 | 656 | ||
634 | shutdown_ecore: | 657 | shutdown_ecore: |
@@ -3041,6 +3064,54 @@ _ecore_evas_fps_debug_rendertime_add(double t) | |||
3041 | } | 3064 | } |
3042 | } | 3065 | } |
3043 | 3066 | ||
3067 | static void | ||
3068 | _ecore_evas_animator_detach(Ecore_Animator *a) | ||
3069 | { | ||
3070 | Ecore_Evas *ee; | ||
3071 | Eina_Inlist *tmp; | ||
3072 | |||
3073 | if (a->delete_me) return; | ||
3074 | |||
3075 | tmp = EINA_INLIST_GET(a); | ||
3076 | |||
3077 | ee = a->ee; | ||
3078 | if (a->suspended) | ||
3079 | ee->ee_anim.suspended = eina_inlist_remove(ee->ee_anim.suspended, EINA_INLIST_GET(a)); | ||
3080 | else if ((!tmp->next) && (!tmp->prev) && (EINA_INLIST_GET(a) != ee->ee_anim.active)) | ||
3081 | return; | ||
3082 | else | ||
3083 | ee->ee_anim.active = eina_inlist_remove(ee->ee_anim.active, EINA_INLIST_GET(a)); | ||
3084 | |||
3085 | a->suspended = EINA_FALSE; | ||
3086 | } | ||
3087 | |||
3088 | static void | ||
3089 | _ecore_evas_animators_do(Ecore_Evas *ee) | ||
3090 | { | ||
3091 | ee->ee_anim.run_list = ee->ee_anim.active; | ||
3092 | ee->ee_anim.active = NULL; | ||
3093 | |||
3094 | while (ee->ee_anim.run_list) | ||
3095 | { | ||
3096 | Ecore_Animator *animator; | ||
3097 | |||
3098 | animator = EINA_INLIST_CONTAINER_GET(ee->ee_anim.run_list, Ecore_Animator); | ||
3099 | ee->ee_anim.run_list = eina_inlist_remove(ee->ee_anim.run_list, EINA_INLIST_GET(animator)); | ||
3100 | |||
3101 | if (!_ecore_call_task_cb(animator->func, animator->data) || animator->delete_me) | ||
3102 | { | ||
3103 | if (animator->delete_me) continue; | ||
3104 | |||
3105 | animator->delete_me = EINA_TRUE; | ||
3106 | ee->ee_anim.deleted = eina_inlist_append(ee->ee_anim.deleted, EINA_INLIST_GET(animator)); | ||
3107 | } | ||
3108 | else | ||
3109 | { | ||
3110 | ee->ee_anim.active = eina_inlist_append(ee->ee_anim.active, EINA_INLIST_GET(animator)); | ||
3111 | } | ||
3112 | } | ||
3113 | } | ||
3114 | |||
3044 | EAPI void | 3115 | EAPI void |
3045 | ecore_evas_animator_tick(Ecore_Evas *ee, Eina_Rectangle *viewport, double loop_time) | 3116 | ecore_evas_animator_tick(Ecore_Evas *ee, Eina_Rectangle *viewport, double loop_time) |
3046 | { | 3117 | { |
@@ -3062,6 +3133,8 @@ ecore_evas_animator_tick(Ecore_Evas *ee, Eina_Rectangle *viewport, double loop_t | |||
3062 | ee->animator_ran = EINA_TRUE; | 3133 | ee->animator_ran = EINA_TRUE; |
3063 | efl_event_callback_call(ee->evas, EFL_EVENT_ANIMATOR_TICK, &a); | 3134 | efl_event_callback_call(ee->evas, EFL_EVENT_ANIMATOR_TICK, &a); |
3064 | 3135 | ||
3136 | if (ee->ee_anim.active) | ||
3137 | _ecore_evas_animators_do(ee); | ||
3065 | // FIXME: We do not support partial animator in the subcanvas | 3138 | // FIXME: We do not support partial animator in the subcanvas |
3066 | EINA_LIST_FOREACH(ee->sub_ecore_evas, l, subee) | 3139 | EINA_LIST_FOREACH(ee->sub_ecore_evas, l, subee) |
3067 | { | 3140 | { |
@@ -5193,3 +5266,150 @@ ecore_evas_done(Ecore_Evas *ee, Eina_Bool single_window) | |||
5193 | if (single_window) | 5266 | if (single_window) |
5194 | evas_event_feed_mouse_in(ee->evas, (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff), NULL); | 5267 | evas_event_feed_mouse_in(ee->evas, (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff), NULL); |
5195 | } | 5268 | } |
5269 | |||
5270 | static Ecore_Animator * | ||
5271 | _ecore_evas_animator_add(void *evo, Ecore_Task_Cb func, const void *data) | ||
5272 | { | ||
5273 | Ecore_Evas *ee; | ||
5274 | Ecore_Animator *animator; | ||
5275 | |||
5276 | if (EINA_UNLIKELY(!eina_main_loop_is())) | ||
5277 | EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); | ||
5278 | |||
5279 | if (!func) | ||
5280 | { | ||
5281 | ERR("callback function must be set up for an Ecore_Animator object."); | ||
5282 | return NULL; | ||
5283 | } | ||
5284 | |||
5285 | ee = ecore_evas_ecore_evas_get(evas_object_evas_get(evo)); | ||
5286 | if (!ee) return NULL; | ||
5287 | |||
5288 | /* If we don't have back-end specific ticks, fallback to old animators */ | ||
5289 | if (!ee->engine.func->fn_animator_register) return NULL; | ||
5290 | |||
5291 | animator = calloc(1, sizeof(Ecore_Animator)); | ||
5292 | if (!animator) return NULL; | ||
5293 | |||
5294 | animator->func = func; | ||
5295 | animator->data = (void *)data; | ||
5296 | animator->ee = ee; | ||
5297 | ee->ee_anim.active = eina_inlist_append(ee->ee_anim.active, EINA_INLIST_GET(animator)); | ||
5298 | _ticking_start(ee); | ||
5299 | |||
5300 | return animator; | ||
5301 | } | ||
5302 | |||
5303 | static Eina_Bool | ||
5304 | _ecore_evas_animator_run(void *data) | ||
5305 | { | ||
5306 | Ecore_Animator *animator = data; | ||
5307 | double pos = 0.0, t; | ||
5308 | Eina_Bool run_ret; | ||
5309 | |||
5310 | t = ecore_loop_time_get(); | ||
5311 | if (animator->run > 0.0) | ||
5312 | { | ||
5313 | pos = (t - animator->start) / animator->run; | ||
5314 | if (pos > 1.0) pos = 1.0; | ||
5315 | else if (pos < 0.0) | ||
5316 | pos = 0.0; | ||
5317 | } | ||
5318 | run_ret = animator->run_func(animator->run_data, pos); | ||
5319 | if (eina_dbl_exact(pos, 1.0)) run_ret = EINA_FALSE; | ||
5320 | return run_ret; | ||
5321 | } | ||
5322 | |||
5323 | static Ecore_Animator * | ||
5324 | _ecore_evas_animator_timeline_add(void *evo, | ||
5325 | double runtime, | ||
5326 | Ecore_Timeline_Cb func, | ||
5327 | const void *data) | ||
5328 | { | ||
5329 | Ecore_Animator *animator; | ||
5330 | |||
5331 | if (runtime <= 0.0) runtime = 0.0; | ||
5332 | |||
5333 | animator = _ecore_evas_animator_add(evo, _ecore_evas_animator_run, NULL); | ||
5334 | if (!animator) return NULL; | ||
5335 | |||
5336 | animator->data = animator; | ||
5337 | animator->run_func = func; | ||
5338 | animator->run_data = (void *)data; | ||
5339 | animator->start = ecore_loop_time_get(); | ||
5340 | animator->run = runtime; | ||
5341 | |||
5342 | return animator; | ||
5343 | } | ||
5344 | |||
5345 | static void * | ||
5346 | _ecore_evas_animator_del(Ecore_Animator *in) | ||
5347 | { | ||
5348 | Ecore_Animator *animator = in; | ||
5349 | Ecore_Evas *ee; | ||
5350 | void *data = NULL; | ||
5351 | |||
5352 | if (animator->delete_me) | ||
5353 | return animator->data; | ||
5354 | ee = animator->ee; | ||
5355 | |||
5356 | _ecore_evas_animator_detach(animator); | ||
5357 | |||
5358 | ee->ee_anim.deleted = eina_inlist_append(ee->ee_anim.deleted, EINA_INLIST_GET(animator)); | ||
5359 | animator->delete_me = EINA_TRUE; | ||
5360 | |||
5361 | if (animator->run_func) | ||
5362 | data = animator->run_data; | ||
5363 | else | ||
5364 | data = animator->data; | ||
5365 | |||
5366 | _ticking_stop(ee); | ||
5367 | return data; | ||
5368 | } | ||
5369 | |||
5370 | static void | ||
5371 | _ecore_evas_animator_flush(Ecore_Evas *ee) | ||
5372 | { | ||
5373 | Ecore_Animator *l; | ||
5374 | |||
5375 | EINA_INLIST_FREE(ee->ee_anim.deleted, l) | ||
5376 | { | ||
5377 | ee->ee_anim.deleted = eina_inlist_remove(ee->ee_anim.deleted, EINA_INLIST_GET(l)); | ||
5378 | free(l); | ||
5379 | } | ||
5380 | } | ||
5381 | |||
5382 | void | ||
5383 | _ecore_evas_animator_freeze(Ecore_Animator *in) | ||
5384 | { | ||
5385 | Ecore_Animator *animator = in; | ||
5386 | Ecore_Evas *ee; | ||
5387 | |||
5388 | ee = animator->ee; | ||
5389 | _ecore_evas_animator_detach(animator); | ||
5390 | |||
5391 | ee->ee_anim.suspended = eina_inlist_append(ee->ee_anim.suspended, EINA_INLIST_GET(animator)); | ||
5392 | |||
5393 | animator->suspended = EINA_TRUE; | ||
5394 | _ticking_stop(ee); | ||
5395 | } | ||
5396 | |||
5397 | void | ||
5398 | _ecore_evas_animator_thaw(Ecore_Animator *in) | ||
5399 | { | ||
5400 | Ecore_Animator *animator = in; | ||
5401 | Ecore_Evas *ee; | ||
5402 | |||
5403 | EINA_MAIN_LOOP_CHECK_RETURN; | ||
5404 | if (!animator) return; | ||
5405 | if (animator->delete_me) return; | ||
5406 | if (!animator->suspended) return; | ||
5407 | |||
5408 | ee = animator->ee; | ||
5409 | ee->ee_anim.suspended = eina_inlist_remove(ee->ee_anim.suspended, | ||
5410 | EINA_INLIST_GET(animator)); | ||
5411 | animator->suspended = EINA_FALSE; | ||
5412 | ee->ee_anim.active = eina_inlist_append(ee->ee_anim.active, | ||
5413 | EINA_INLIST_GET(animator)); | ||
5414 | _ticking_start(ee); | ||
5415 | } | ||
diff --git a/src/lib/ecore_evas/ecore_evas_private.h b/src/lib/ecore_evas/ecore_evas_private.h index c9f158ee9b..9149c3e937 100644 --- a/src/lib/ecore_evas/ecore_evas_private.h +++ b/src/lib/ecore_evas/ecore_evas_private.h | |||
@@ -333,6 +333,13 @@ struct _Ecore_Evas | |||
333 | unsigned int animator_count; | 333 | unsigned int animator_count; |
334 | 334 | ||
335 | struct { | 335 | struct { |
336 | Eina_Inlist *active; | ||
337 | Eina_Inlist *deleted; | ||
338 | Eina_Inlist *suspended; | ||
339 | Eina_Inlist *run_list; | ||
340 | } ee_anim; | ||
341 | |||
342 | struct { | ||
336 | unsigned char avoid_damage; | 343 | unsigned char avoid_damage; |
337 | unsigned char resize_shape : 1; | 344 | unsigned char resize_shape : 1; |
338 | unsigned char shaped : 1; | 345 | unsigned char shaped : 1; |