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;

-- 


Reply via email to