cedric pushed a commit to branch master. http://git.enlightenment.org/core/efl.git/commit/?id=67ef1b11ff05a8c09aa6975f29bc28584ce15187
commit 67ef1b11ff05a8c09aa6975f29bc28584ce15187 Author: Cedric BAIL <ced...@osg.samsung.com> Date: Thu Aug 20 15:39:16 2015 +0200 evas: properly fix unref of ector renderer. Async rendering doesn't have a main loop cleanup function. The only one being called is in the rendering thread. I wrongly assumed in my previous patch that render_post on an object was called after the async render was done which is obviously not the case as pointed by Subhransu. This patch now wait for the async rendering to be done. --- src/lib/evas/canvas/evas_object_vg.c | 42 ++++++++++++++++++++++++++++-------- src/lib/evas/canvas/evas_vg.eo | 1 + 2 files changed, 34 insertions(+), 9 deletions(-) diff --git a/src/lib/evas/canvas/evas_object_vg.c b/src/lib/evas/canvas/evas_object_vg.c index df4df41..628ade6 100644 --- a/src/lib/evas/canvas/evas_object_vg.c +++ b/src/lib/evas/canvas/evas_object_vg.c @@ -94,9 +94,29 @@ _evas_vg_root_node_get(Eo *obj EINA_UNUSED, Evas_VG_Data *pd) return pd->root; } +static Eina_Bool +_cleanup_reference(void *data, + Eo *obj EINA_UNUSED, + const Eo_Event_Description *desc EINA_UNUSED, + void *event_info EINA_UNUSED) +{ + Evas_VG_Data *pd = data; + Eo *renderer; + + /* unref all renderer and may also destroy them async */ + while ((renderer = eina_array_pop(&pd->cleanup))) + eo_unref(renderer); + + return EO_CALLBACK_CONTINUE; +} + void _evas_vg_eo_base_destructor(Eo *eo_obj, Evas_VG_Data *pd) { + Evas *e = evas_object_evas_get(eo_obj); + + eo_do(e, eo_event_callback_del(EVAS_CANVAS_EVENT_RENDER_POST, _cleanup_reference, pd)); + eo_unref(pd->root); pd->root = NULL; eo_do_super(eo_obj, MY_CLASS, eo_destructor()); @@ -123,6 +143,18 @@ _evas_vg_eo_base_constructor(Eo *eo_obj, Evas_VG_Data *pd) return eo_obj; } +static Eo_Base * +_evas_vg_eo_base_finalize(Eo *obj, Evas_VG_Data *pd) +{ + Evas *e = evas_object_evas_get(obj); + + // TODO: If we start to have to many Evas_Object_VG per canvas, it may be nice + // to actually have one event per canvas and one array per canvas to. + eo_do(e, eo_event_callback_add(EVAS_CANVAS_EVENT_RENDER_POST, _cleanup_reference, pd)); + + return obj; +} + static void _evas_vg_render(Evas_Object_Protected_Data *obj, Evas_VG_Data *vd, void *output, void *context, void *surface, Efl_VG *n, @@ -335,13 +367,8 @@ evas_object_vg_render_pre(Evas_Object *eo_obj, static void evas_object_vg_render_post(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj EINA_UNUSED, - void *type_private_data) + void *type_private_data EINA_UNUSED) { - Evas_VG_Data *vd = type_private_data; - Eo *renderer; - Eina_Array_Iterator iterator; - unsigned int i; - /* this moves the current data to the previous state parts of the object */ /* in whatever way is safest for the object. also if we don't need object */ /* data anymore we can free it if the object deems this is a good idea */ @@ -349,9 +376,6 @@ evas_object_vg_render_post(Evas_Object *eo_obj, evas_object_clip_changes_clean(eo_obj); /* move cur to prev safely for object data */ evas_object_cur_prev(eo_obj); - /* unref all renderer and may also destroy them async */ - EINA_ARRAY_ITER_NEXT((&vd->cleanup), i, renderer, iterator) - eo_unref(renderer); } static unsigned int diff --git a/src/lib/evas/canvas/evas_vg.eo b/src/lib/evas/canvas/evas_vg.eo index 9f466d4..6438fe3 100644 --- a/src/lib/evas/canvas/evas_vg.eo +++ b/src/lib/evas/canvas/evas_vg.eo @@ -20,6 +20,7 @@ class Evas.VG (Evas.Object, Efl.Gfx.Fill, Efl.Gfx.View) } implements { Eo.Base.constructor; + Eo.Base.finalize; Eo.Base.destructor; Efl.Gfx.Fill.fill.set; Efl.Gfx.Fill.fill.get; --