cedric pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=7c83af2ae3c83d82b23e73115db1aad7f19bcecc

commit 7c83af2ae3c83d82b23e73115db1aad7f19bcecc
Author: Cedric BAIL <ced...@osg.samsung.com>
Date:   Wed Aug 19 16:06:39 2015 +0200

    evas: fix ref/unref of ector renderer to always happen in the main loop.
---
 src/lib/evas/canvas/evas_object_vg.c               | 29 +++++++++++++++++-----
 .../evas/engines/software_generic/evas_engine.c    |  3 +--
 2 files changed, 24 insertions(+), 8 deletions(-)

diff --git a/src/lib/evas/canvas/evas_object_vg.c 
b/src/lib/evas/canvas/evas_object_vg.c
index abf12c3..bdda637 100644
--- a/src/lib/evas/canvas/evas_object_vg.c
+++ b/src/lib/evas/canvas/evas_object_vg.c
@@ -22,6 +22,8 @@ struct _Evas_VG_Data
    Eina_Rectangle fill;
 
    unsigned int width, height;
+
+   Eina_Array cleanup;
 };
 
 static void evas_object_vg_render(Evas_Object *eo_obj,
@@ -116,23 +118,25 @@ _evas_vg_eo_base_constructor(Eo *eo_obj, Evas_VG_Data *pd)
    pd->root = eo_add(EFL_VG_ROOT_NODE_CLASS, eo_obj);
    eo_ref(pd->root);
 
+   eina_array_step_set(&pd->cleanup, sizeof(pd->cleanup), 8);
+
    return eo_obj;
 }
 
 static void
-_evas_vg_render(Evas_Object_Protected_Data *obj,
+_evas_vg_render(Evas_Object_Protected_Data *obj, Evas_VG_Data *vd,
                 void *output, void *context, void *surface, Efl_VG *n,
                 Eina_Array *clips, Eina_Bool do_async)
 {
-   Efl_VG_Container_Data *vd = eo_data_scope_get(n, EFL_VG_CONTAINER_CLASS);
+   Efl_VG_Container_Data *vc = eo_data_scope_get(n, EFL_VG_CONTAINER_CLASS);
 
    if (eo_isa(n, EFL_VG_CONTAINER_CLASS))
      {
         Efl_VG *child;
         Eina_List *l;
 
-        EINA_LIST_FOREACH(vd->children, l, child)
-          _evas_vg_render(obj,
+        EINA_LIST_FOREACH(vc->children, l, child)
+          _evas_vg_render(obj, vd,
                           output, context, surface, child,
                           clips, do_async);
      }
@@ -143,6 +147,9 @@ _evas_vg_render(Evas_Object_Protected_Data *obj,
         nd = eo_data_scope_get(n, EFL_VG_BASE_CLASS);
 
         obj->layer->evas->engine.func->ector_renderer_draw(output, context, 
surface, nd->renderer, clips, do_async);
+
+        if (do_async)
+          eina_array_push(&vd->cleanup, eo_ref(nd->renderer));
      }
 }
 
@@ -182,7 +189,9 @@ evas_object_vg_render(Evas_Object *eo_obj EINA_UNUSED,
    obj->layer->evas->engine.func->ector_begin(output, context, surface,
                                               obj->cur->geometry.x + x, 
obj->cur->geometry.y + y,
                                               do_async);
-   _evas_vg_render(obj, output, context, surface, vd->root, NULL,
+   _evas_vg_render(obj, vd,
+                   output, context, surface,
+                   vd->root, NULL,
                    do_async);
    obj->layer->evas->engine.func->ector_end(output, context, surface, 
do_async);
 }
@@ -325,8 +334,13 @@ 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 EINA_UNUSED)
+                           void *type_private_data)
 {
+   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 */
@@ -334,6 +348,9 @@ 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/modules/evas/engines/software_generic/evas_engine.c 
b/src/modules/evas/engines/software_generic/evas_engine.c
index 3b50c4f..cdaba07 100644
--- a/src/modules/evas/engines/software_generic/evas_engine.c
+++ b/src/modules/evas/engines/software_generic/evas_engine.c
@@ -3532,7 +3532,6 @@ _draw_thread_ector_cleanup(Evas_Thread_Command_Ector 
*ector)
    while ((r = eina_array_pop(ector->clips)))
      eina_rectangle_free(r);
    eina_array_free(ector->clips);
-   eo_unref(ector->r);
 
    if (ector->free_it)
      eina_mempool_free(_mp_command_ector, ector);
@@ -3605,7 +3604,7 @@ eng_ector_renderer_draw(void *data EINA_UNUSED, void 
*context, void *surface, Ec
    if (eina_array_count(c) == 0)
      eina_array_push(c, eina_rectangle_new(clip.x, clip.y, clip.w, clip.h));
 
-   ector.r = eo_ref(renderer);
+   ector.r = renderer; // This has already been refcounted by Evas_Object_VG
    ector.clips = c;
    ector.render_op = _evas_render_op_to_ector_rop(dc->render_op);
    ector.mul_col = ector_color_multiply(dc->mul.use ? dc->mul.col : 0xffffffff,

-- 


Reply via email to