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
This commit is contained in:
Cedric Bail 2019-09-27 14:19:38 +09:00 committed by Hermet Park
parent 04a2b7a048
commit 29beda7f4f
2 changed files with 14 additions and 10 deletions

View 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.

View 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; }