ecore: simplify usage of poller by giving 3 class of event on the main loop object.

The internal logic should be improved further in the future to synchronize itself
with loop wake up whenever possible (Especially true for the high frequency poller).
This commit is contained in:
Cedric BAIL 2017-06-02 16:27:02 -07:00
parent 88fc88a305
commit bc13f96ae8
3 changed files with 86 additions and 2 deletions

View File

@ -2868,6 +2868,14 @@ _efl_loop_efl_object_provider_find(Eo *obj, Efl_Loop_Data *pd, const Efl_Object
return efl_provider_find(efl_super(obj, EFL_LOOP_CLASS), klass);
}
static void
_poll_trigger(void *data, const Efl_Event *event)
{
Eo *parent = efl_parent_get(event->object);
efl_event_callback_call(parent, data, NULL);
}
static void
_check_event_catcher_add(void *data, const Efl_Event *event)
{
@ -2881,6 +2889,38 @@ _check_event_catcher_add(void *data, const Efl_Event *event)
{
++pd->idlers;
}
else if (array[i].desc == EFL_LOOP_EVENT_POLL_HIGH)
{
if (!pd->poll_high)
{
// Would be better to have it in sync with normal wake up
// of the main loop for better energy efficiency, I guess.
pd->poll_high = efl_add(EFL_LOOP_TIMER_CLASS, event->object,
efl_event_callback_add(efl_added, EFL_LOOP_TIMER_EVENT_TICK, _poll_trigger, EFL_LOOP_EVENT_POLL_HIGH),
efl_loop_timer_interval_set(efl_added, 1/60));
}
++pd->pollers.high;
}
else if (array[i].desc == EFL_LOOP_EVENT_POLL_MEDIUM)
{
if (!pd->poll_medium)
{
pd->poll_medium = efl_add(EFL_LOOP_TIMER_CLASS, event->object,
efl_event_callback_add(efl_added, EFL_LOOP_TIMER_EVENT_TICK, _poll_trigger, EFL_LOOP_EVENT_POLL_MEDIUM),
efl_loop_timer_interval_set(efl_added, 6));
}
++pd->pollers.medium;
}
else if (array[i].desc == EFL_LOOP_EVENT_POLL_LOW)
{
if (!pd->poll_low)
{
pd->poll_low = efl_add(EFL_LOOP_TIMER_CLASS, event->object,
efl_event_callback_add(efl_added, EFL_LOOP_TIMER_EVENT_TICK, _poll_trigger, EFL_LOOP_EVENT_POLL_LOW),
efl_loop_timer_interval_set(efl_added, 66));
}
++pd->pollers.low;
}
}
}
@ -2897,6 +2937,33 @@ _check_event_catcher_del(void *data, const Efl_Event *event)
{
--pd->idlers;
}
else if (array[i].desc == EFL_LOOP_EVENT_POLL_HIGH)
{
--pd->pollers.high;
if (!pd->pollers.high)
{
ecore_timer_del(pd->poll_high);
pd->poll_high = NULL;
}
}
else if (array[i].desc == EFL_LOOP_EVENT_POLL_MEDIUM)
{
--pd->pollers.medium;
if (!pd->pollers.medium)
{
ecore_timer_del(pd->poll_medium);
pd->poll_medium = NULL;
}
}
else if (array[i].desc == EFL_LOOP_EVENT_POLL_LOW)
{
--pd->pollers.low;
if (!pd->pollers.low)
{
ecore_timer_del(pd->poll_low);
pd->poll_low = NULL;
}
}
}
}
@ -2920,9 +2987,13 @@ _efl_loop_efl_object_constructor(Eo *obj, Efl_Loop_Data *pd)
EOLIAN static void
_efl_loop_efl_object_destructor(Eo *obj, Efl_Loop_Data *pd)
{
efl_destructor(efl_super(obj, EFL_LOOP_CLASS));
eina_hash_free(pd->providers);
efl_del(pd->poll_low);
efl_del(pd->poll_medium);
efl_del(pd->poll_high);
efl_destructor(efl_super(obj, EFL_LOOP_CLASS));
}
typedef struct _Efl_Internal_Promise Efl_Internal_Promise;

View File

@ -86,7 +86,17 @@ struct _Efl_Loop_Data
{
Eina_Hash *providers;
Ecore_Timer *poll_high;
Ecore_Timer *poll_medium;
Ecore_Timer *poll_low;
int idlers;
struct {
int high;
int medium;
int low;
} pollers;
};
#define EVAS_FRAME_QUEUING 1 /* for test */

View File

@ -106,6 +106,9 @@ class Efl.Loop (Efl.Object)
idle,exit @restart; [[Event occurs once the main loop exits the idle state.]]
idle @restart; [[Event occurs once the main loop is idler. Be carefull, this will spin your CPU high if you keep listening on this event.]]
arguments: Efl.Loop.Arguments; [[Event happens when args are provided to the loop by args_add().]]
poll,high; [[Event occurs multiple time per second. The exact tick is undefined and could be adjusted system wide.]]
poll,medium; [[Event occurs multiple time per minute. The exact tick is undefined and could be adjusted system wide.]]
poll,low; [[Event occurs multiple time every 15 minutes. The exact tick is undefined and could be adjusted system wide.]]
}
implements {
Efl.Object.constructor;