ecore_evas: always find a source for ticking legacy animator.

As we do not know when a window won't be able to tick, and we do
not know which window a legacy animator is attached to, we require
all windows to tick as often as they can and only generate one tick
per loop run.

This might need more adjustement especially with multi output.
This commit is contained in:
Cedric Bail 2017-11-02 15:21:37 -07:00
parent 82b0da0c8a
commit e5d1cc731a
2 changed files with 56 additions and 51 deletions

View File

@ -2641,7 +2641,7 @@ ecore_evas_manual_render_set(Ecore_Evas *ee, Eina_Bool manual_render)
{
ECORE_EVAS_CHECK(ee);
ee->manual_render = manual_render;
if (!ee->anim_count) return;
if (!ee->animator_count) return;
if (!ee->engine.func->fn_animator_register) return;
if (!ee->engine.func->fn_animator_unregister) return;
@ -3054,8 +3054,6 @@ _ecore_evas_fps_debug_rendertime_add(double t)
}
}
static Ecore_Evas *_general_tick = NULL;
EAPI void
ecore_evas_animator_tick(Ecore_Evas *ee, Eina_Rectangle *viewport, double loop_time)
{
@ -3083,23 +3081,22 @@ ecore_evas_animator_tick(Ecore_Evas *ee, Eina_Rectangle *viewport, double loop_t
ecore_evas_animator_tick(subee, NULL, loop_time);
}
// We are the source of sync for general animator.
if (_general_tick == ee)
// We are a source of sync for general animator.
// Let's only trigger the animator once per rendering loop
if (!ecore_main_loop_animator_ticked_get())
{
// Check first we didn't tick during this loop
if (!ecore_main_loop_animator_ticked_get())
ecore_animator_custom_tick();
// FIXME: We might want to enforce also Ecore_Animatore frametime
ecore_animator_custom_tick();
}
DBG("Animator ticked on %p.", ee->evas);
}
// Per Ecore_Evas ticking
static void
_ecore_evas_custom_tick_begin(void *data)
ecore_evas_tick_begin(Ecore_Evas *ee)
{
Ecore_Evas *ee = data;
if (ee->anim_count++ > 0) return;
if (ee->animator_count++ > 0) return;
if (ee->manual_render)
{
@ -3110,47 +3107,58 @@ _ecore_evas_custom_tick_begin(void *data)
}
static void
_ecore_evas_custom_tick_end(void *data)
ecore_evas_tick_end(Ecore_Evas *ee)
{
Ecore_Evas *ee = data;
if ((--ee->anim_count) > 0) return;
if ((--ee->animator_count) > 0) return;
if (ee->manual_render) return;
ee->engine.func->fn_animator_unregister(ee);
}
// Need all possible tick to tick for animator fallback as we don't
// know if a window is the source of animator
static void
_ecore_evas_custom_tick_begin(void *data EINA_UNUSED)
{
Ecore_Evas *ee;
EINA_INLIST_FOREACH(ecore_evases, ee)
if (!ee->deleted &&
ee->engine.func->fn_animator_register &&
ee->engine.func->fn_animator_unregister)
ecore_evas_tick_begin(ee);
}
static void
_ecore_evas_custom_tick_end(void *data EINA_UNUSED)
{
Ecore_Evas *ee;
EINA_INLIST_FOREACH(ecore_evases, ee)
if (!ee->deleted &&
ee->engine.func->fn_animator_register &&
ee->engine.func->fn_animator_unregister)
ecore_evas_tick_end(ee);
}
static void
_ecore_evas_tick_source_find(void)
{
Ecore_Evas *ee;
Ecore_Evas *standby = NULL;
Eina_Bool source = EINA_FALSE;
_general_tick = NULL;
EINA_INLIST_FOREACH(ecore_evases, ee)
if (!ee->deleted &&
ee->engine.func->fn_animator_register &&
ee->engine.func->fn_animator_unregister)
{
if (ee->anim_count)
{
_general_tick = ee;
break;
}
else
{
standby = ee;
}
source = EINA_TRUE;
break;
}
// If no general source is already ticking pick one.
if (!_general_tick && standby)
{
_general_tick = standby;
}
if (!_general_tick)
// If no source is available for ticking, fallback to timer.
if (!source)
{
ecore_animator_source_set(ECORE_ANIMATOR_SOURCE_TIMER);
}
@ -3158,9 +3166,9 @@ _ecore_evas_tick_source_find(void)
{
// Source set will trigger the previous tick end registered and then the new begin.
// As we don't what was in behind, better first begin and end after source is set.
ecore_animator_custom_source_tick_begin_callback_set(_ecore_evas_custom_tick_begin, _general_tick);
ecore_animator_custom_source_tick_begin_callback_set(_ecore_evas_custom_tick_begin, NULL);
ecore_animator_source_set(ECORE_ANIMATOR_SOURCE_CUSTOM);
ecore_animator_custom_source_tick_end_callback_set(_ecore_evas_custom_tick_end, _general_tick);
ecore_animator_custom_source_tick_end_callback_set(_ecore_evas_custom_tick_end, NULL);
}
}
@ -3182,22 +3190,19 @@ _check_animator_event_catcher_add(void *data, const Efl_Event *event)
{
if (array[i].desc == EFL_EVENT_ANIMATOR_TICK)
{
if (!ee->anim_count)
if (!ee->animator_count)
INF("Setting up animator for %p from '%s' with title '%s'.", ee->evas, ee->driver, ee->prop.title);
if (ee->engine.func->fn_animator_register &&
ee->engine.func->fn_animator_unregister)
{
// Backend support per window vsync
_ecore_evas_custom_tick_begin(ee);
if (ee->anim_count > 0) return;
if (!_general_tick) _general_tick = ee;
ecore_evas_tick_begin(ee);
}
else
{
// Backend doesn't support per window vsync, fallback to generic support
if (ee->anim_count++ > 0) return;
if (ee->animator_count++ > 0) return;
ee->anim = ecore_animator_add(_ecore_evas_animator_fallback, ee);
}
@ -3219,21 +3224,19 @@ _check_animator_event_catcher_del(void *data, const Efl_Event *event)
{
if (array[i].desc == EFL_EVENT_ANIMATOR_TICK)
{
if (ee->anim_count == 1)
if (ee->animator_count == 1)
INF("Unsetting up animator for %p from '%s' titled '%s'.", ee->evas, ee->driver, ee->prop.title);
if (ee->engine.func->fn_animator_register &&
ee->engine.func->fn_animator_unregister)
{
// Backend support per window vsync
_ecore_evas_custom_tick_end(ee);
if (ee->anim_count > 0) return;
if (_general_tick == ee) _ecore_evas_tick_source_find();
ecore_evas_tick_end(ee);
}
else
{
// Backend doesn't support per window vsync, fallback to generic support
if (--ee->anim_count > 0) return;
if (--ee->animator_count > 0) return;
ecore_animator_del(ee->anim);
ee->anim = NULL;
}
@ -3261,8 +3264,8 @@ _ecore_evas_register(Ecore_Evas *ee)
_ecore_evas_register_animators(ee);
_ecore_evas_tick_source_find();
if (_ecore_evas_render_sync) ee->first_frame = EINA_TRUE;
if (!_general_tick) _ecore_evas_tick_source_find();
if (!ee->engine.func->fn_render)
evas_event_callback_priority_add(ee->evas, EVAS_CALLBACK_RENDER_POST, EVAS_CALLBACK_PRIORITY_AFTER,
_evas_evas_buffer_rendered, ee);
@ -3320,13 +3323,15 @@ _ecore_evas_free(Ecore_Evas *ee)
if (ee->refcount > 0) return;
// Stop all vsync first
if (ee->engine.func->fn_animator_register &&
if (ee->animator_count > 0 &&
ee->engine.func->fn_animator_register &&
ee->engine.func->fn_animator_unregister)
{
// Backend support per window vsync
ee->engine.func->fn_animator_unregister(ee);
if (_general_tick == ee) _ecore_evas_tick_source_find();
_ecore_evas_tick_source_find();
}
ee->animator_count = 0;
efl_event_callback_array_del(ee->evas, animator_watch(), ee);
if (ee->anim)

View File

@ -330,7 +330,7 @@ struct _Ecore_Evas
// Animator code
Ecore_Animator *anim;
unsigned int anim_count;
unsigned int animator_count;
struct {
unsigned char avoid_damage;