evas: fix memory leak with Efl.Canvas.Vg
authorCedric Bail <cedric.bail@free.fr>
Fri, 27 Sep 2019 05:19:38 +0000 (14:19 +0900)
committerJongmin Lee <jm105.lee@samsung.com>
Sun, 29 Sep 2019 21:18:39 +0000 (06:18 +0900)
Summary:
It is not correct to change the parent and hope that refcount will work
for you. The parent chain is a decision made by the user, not something
a widget can touch. Only ref count are to be used when given an outside
object. As things where not triggering destruction, there was also no
point where the image buffer would be getting to zero and be freed. This
commit also fix this.

Reviewers: Hermet, zmike

Reviewed By: Hermet

Subscribers: #reviewers, #committers

Tags: #efl

Differential Revision: https://phab.enlightenment.org/D10169

src/lib/evas/canvas/efl_canvas_vg_object.c
src/lib/evas/canvas/efl_canvas_vg_object.eo

index 1f8e051..0c8e50b 100644 (file)
@@ -145,7 +145,7 @@ _efl_canvas_vg_object_root_node_set(Eo *eo_obj, Efl_Canvas_Vg_Object_Data *pd, E
    if (pd->user_entry && pd->user_entry->root)
      {
         efl_canvas_vg_node_vg_obj_set(pd->user_entry->root, NULL, NULL);
-        efl_parent_set(pd->user_entry->root, NULL);
+        efl_replace(&pd->user_entry->root, NULL);
      }
 
    if (root_node)
@@ -160,10 +160,8 @@ _efl_canvas_vg_object_root_node_set(Eo *eo_obj, Efl_Canvas_Vg_Object_Data *pd, E
                }
           }
         pd->user_entry->w = pd->user_entry->h = 0;
-        pd->user_entry->root = root_node;
 
-        // set the parent so that vg canvas can render it.
-        efl_parent_set(pd->user_entry->root, pd->root);
+        efl_replace(&pd->user_entry->root, root_node);
         efl_canvas_vg_node_vg_obj_set(root_node, eo_obj, pd);
      }
    else if (pd->user_entry)
@@ -333,8 +331,9 @@ _cleanup_reference(void *data, const Efl_Event *event EINA_UNUSED)
 }
 
 EOLIAN static void
-_efl_canvas_vg_object_efl_object_destructor(Eo *eo_obj, Efl_Canvas_Vg_Object_Data *pd)
+_efl_canvas_vg_object_efl_object_invalidate(Eo *eo_obj, Efl_Canvas_Vg_Object_Data *pd)
 {
+   Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
    Evas *e = evas_object_evas_get(eo_obj);
 
    efl_event_callback_del(e, EFL_CANVAS_SCENE_EVENT_RENDER_POST, _cleanup_reference, pd);
@@ -343,11 +342,17 @@ _efl_canvas_vg_object_efl_object_destructor(Eo *eo_obj, Efl_Canvas_Vg_Object_Dat
    efl_unref(pd->root);
    pd->root = NULL;
 
-   if (pd->user_entry) free(pd->user_entry);
+   if (pd->user_entry)
+     {
+        Vg_User_Entry *user_entry = pd->user_entry;
+
+        ENFN->ector_surface_cache_drop(ENC, user_entry->root);
+        free(pd->user_entry);
+     }
    pd->user_entry = NULL;
    evas_cache_vg_entry_del(pd->vg_entry);
 
-   efl_destructor(efl_super(eo_obj, MY_CLASS));
+   efl_invalidate(efl_super(eo_obj, MY_CLASS));
 }
 
 EOLIAN static Eo *
@@ -364,7 +369,7 @@ _efl_canvas_vg_object_efl_object_constructor(Eo *eo_obj, Efl_Canvas_Vg_Object_Da
 
    /* default root node */
    pd->obj = obj;
-   pd->root = efl_add_ref(EFL_CANVAS_VG_CONTAINER_CLASS, NULL);
+   pd->root = efl_add_ref(EFL_CANVAS_VG_CONTAINER_CLASS, eo_obj);
 
    eina_array_step_set(&pd->cleanup, sizeof(pd->cleanup), 8);
 
@@ -375,7 +380,6 @@ static Efl_Object *
 _efl_canvas_vg_object_efl_object_finalize(Eo *obj, Efl_Canvas_Vg_Object_Data *pd)
 {
    Evas *e = evas_object_evas_get(obj);
-   efl_parent_set(pd->root, 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.
index e414f1a..2213c23 100644 (file)
@@ -78,7 +78,7 @@ class @beta Efl.Canvas.Vg.Object extends Efl.Canvas.Object implements Efl.File,
    implements {
       Efl.Object.constructor;
       Efl.Object.finalize;
-      Efl.Object.destructor;
+      Efl.Object.invalidate;
       Efl.File.load;
       Efl.File.unload;
       Efl.File.file { set; }