summaryrefslogtreecommitdiff
path: root/src/lib/ecore_evas/ecore_evas.c
diff options
context:
space:
mode:
authorDerek Foreman <derek.foreman.samsung@gmail.com>2018-09-18 09:42:38 -0500
committerDerek Foreman <derek.foreman.samsung@gmail.com>2018-09-18 09:42:38 -0500
commit4dc1e8273d3ee2e118c6ec7bdf6135771688e662 (patch)
treeb68084a95b0d8652aa30184b557d4af35684e103 /src/lib/ecore_evas/ecore_evas.c
parent448c7ca2ce6485d885b48407919e715de3365b28 (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/ecore_evas.c')
-rw-r--r--src/lib/ecore_evas/ecore_evas.c220
1 files changed, 220 insertions, 0 deletions
diff --git a/src/lib/ecore_evas/ecore_evas.c b/src/lib/ecore_evas/ecore_evas.c
index e7540b6..99d1e1f2 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
72static int _ecore_evas_render_sync = 1; 74static int _ecore_evas_render_sync = 1;
73 75
76static void _ecore_evas_animator_flush(Ecore_Evas *ee);
77
78static Ecore_Animator *_ecore_evas_animator_timeline_add(void *evo, double runtime, Ecore_Timeline_Cb func, const void *data);
79static Ecore_Animator *_ecore_evas_animator_add(void *evo, Ecore_Task_Cb func, const void *data);
80static void _ecore_evas_animator_freeze(Ecore_Animator *animator);
81static void _ecore_evas_animator_thaw(Ecore_Animator *animator);
82static void *_ecore_evas_animator_del(Ecore_Animator *animator);
83
74static void 84static 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)
588EAPI int 601EAPI int
589ecore_evas_init(void) 602ecore_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
3067static 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
3088static 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
3044EAPI void 3115EAPI void
3045ecore_evas_animator_tick(Ecore_Evas *ee, Eina_Rectangle *viewport, double loop_time) 3116ecore_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
5270static 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
5303static 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
5323static 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
5345static 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
5370static 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
5382void
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
5397void
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}