hermet pushed a commit to branch master. http://git.enlightenment.org/core/efl.git/commit/?id=29beda7f4f365425656e3340ea2da592d00fb52c
commit 29beda7f4f365425656e3340ea2da592d00fb52c Author: Cedric Bail <cedric.b...@free.fr> Date: Fri Sep 27 14:19:38 2019 +0900 evas: fix memory leak with Efl.Canvas.Vg 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 | 22 +++++++++++++--------- src/lib/evas/canvas/efl_canvas_vg_object.eo | 2 +- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/lib/evas/canvas/efl_canvas_vg_object.c b/src/lib/evas/canvas/efl_canvas_vg_object.c index 1f8e05189b..0c8e50bed3 100644 --- a/src/lib/evas/canvas/efl_canvas_vg_object.c +++ b/src/lib/evas/canvas/efl_canvas_vg_object.c @@ -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. diff --git a/src/lib/evas/canvas/efl_canvas_vg_object.eo b/src/lib/evas/canvas/efl_canvas_vg_object.eo index e414f1aaa7..2213c232ae 100644 --- a/src/lib/evas/canvas/efl_canvas_vg_object.eo +++ b/src/lib/evas/canvas/efl_canvas_vg_object.eo @@ -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; } --