evas: properly fix unref of ector renderer.
authorCedric BAIL <cedric@osg.samsung.com>
Thu, 20 Aug 2015 13:39:16 +0000 (15:39 +0200)
committerCedric BAIL <cedric@osg.samsung.com>
Thu, 20 Aug 2015 13:39:16 +0000 (15:39 +0200)
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
src/lib/evas/canvas/evas_vg.eo

index df4df41..628ade6 100644 (file)
@@ -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
index 9f466d4..6438fe3 100644 (file)
@@ -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;