Evas masking: Fix major memory leak

The memory usage graph was going up and to the right!
I was told this is always a good thing!

... maybe not this time :)

Hopefully I didn't forget a case. An intense session of
genlist scrolling with masks all over the place and masks
of masks didn't show any glitch, crash or memory leak.
This commit is contained in:
Jean-Philippe Andre 2015-01-21 17:30:18 +09:00
parent 0793dee86a
commit 15f7cefa68
5 changed files with 50 additions and 6 deletions

View File

@ -179,6 +179,21 @@ evas_object_free(Evas_Object *eo_obj, int clean_layer)
map_write->surface = NULL;
EINA_COW_WRITE_END(evas_object_map_cow, obj->map, map_write);
}
if (obj->mask->is_mask)
{
EINA_COW_WRITE_BEGIN(evas_object_mask_cow, obj->mask, Evas_Object_Mask_Data, mask)
mask->is_mask = EINA_FALSE;
mask->redraw = EINA_FALSE;
mask->is_alpha = EINA_FALSE;
mask->x = mask->y = mask->w = mask->h = 0;
if (mask->surface)
{
obj->layer->evas->engine.func->image_map_surface_free
(obj->layer->evas->engine.data.output, mask->surface);
mask->surface = NULL;
}
EINA_COW_WRITE_END(evas_object_mask_cow, obj->mask, mask);
}
evas_object_grabs_cleanup(eo_obj, obj);
evas_object_intercept_cleanup(eo_obj);
if (obj->smart.parent) was_smart_child = 1;

View File

@ -1519,6 +1519,7 @@ evas_render_mapped(Evas_Public_Data *e, Evas_Object *eo_obj,
}
else
{
Eina_Bool unset_image_clip = EINA_FALSE;
RDI(level);
if (obj->cur->clipper)
@ -1540,6 +1541,7 @@ evas_render_mapped(Evas_Public_Data *e, Evas_Object *eo_obj,
if (mask->mask->surface)
{
unset_image_clip = EINA_TRUE;
e->engine.func->context_clip_image_set
(e->engine.data.output, ctx,
mask->mask->surface,
@ -1551,6 +1553,11 @@ evas_render_mapped(Evas_Public_Data *e, Evas_Object *eo_obj,
obj->func->render(eo_obj, obj, obj->private_data,
e->engine.data.output, ctx,
surface, off_x, off_y, EINA_FALSE);
if (unset_image_clip)
{
e->engine.func->context_clip_image_unset
(e->engine.data.output, ctx);
}
}
if (!use_mapped_ctx)
e->engine.func->context_free(e->engine.data.output, ctx);
@ -1808,6 +1815,8 @@ evas_render_mask_subrender(Evas_Public_Data *evas,
mdata->is_alpha = EINA_TRUE;
}
mdata->surface = ENFN->image_dirty_region(ENDT, mdata->surface, 0, 0, w, h);
/* END OF HACK */
end:

View File

@ -1635,6 +1635,9 @@ _filter_target_render(Evas_Filter_Context *ctx)
ctx->target.x, ctx->target.y, src->w, src->h,
EINA_TRUE, EINA_FALSE);
if (ctx->target.mask)
ENFN->context_clip_image_unset(ENDT, drawctx);
if (!ctx->gl_engine)
ENFN->context_free(ENDT, drawctx);
else if (use_clip)

View File

@ -1749,6 +1749,17 @@ eng_context_clip_image_get(void *data EINA_UNUSED, void *context, void **ie, int
if (y) *y = ctx->clip.mask_y;
}
static void
eng_context_free(void *data, void *context)
{
RGBA_Draw_Context *ctx = context;
if (!ctx) return;
if (ctx->clip.mask)
eng_context_clip_image_unset(data, context);
evas_common_draw_context_free(context);
}
static void
eng_context_3d_use(void *data)
{
@ -1942,6 +1953,7 @@ module_open(Evas_Module *em)
ORD(context_clip_image_set);
ORD(context_clip_image_unset);
ORD(context_clip_image_get);
ORD(context_free);
ORD(rectangle_draw);
ORD(line_draw);

View File

@ -410,12 +410,6 @@ eng_context_new(void *data EINA_UNUSED)
return evas_common_draw_context_new();
}
static void
eng_context_free(void *data EINA_UNUSED, void *context)
{
evas_common_draw_context_free(context);
}
static void
eng_context_clip_set(void *data EINA_UNUSED, void *context, int x, int y, int w, int h)
{
@ -476,6 +470,17 @@ eng_context_clip_image_get(void *data EINA_UNUSED, void *context, void **ie, int
if (y) *y = ctx->clip.mask_y;
}
static void
eng_context_free(void *data, void *context)
{
RGBA_Draw_Context *ctx = context;
if (!ctx) return;
if (ctx->clip.mask)
eng_context_clip_image_unset(data, context);
evas_common_draw_context_free(context);
}
static void
eng_context_clip_clip(void *data EINA_UNUSED, void *context, int x, int y, int w, int h)
{