jpeg pushed a commit to branch master. http://git.enlightenment.org/core/efl.git/commit/?id=15f7cefa68ff89bde8418092389faa670db8caeb
commit 15f7cefa68ff89bde8418092389faa670db8caeb Author: Jean-Philippe Andre <jp.an...@samsung.com> Date: Wed Jan 21 17:30:18 2015 +0900 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. --- src/lib/evas/canvas/evas_object_main.c | 15 +++++++++++++++ src/lib/evas/canvas/evas_render.c | 9 +++++++++ src/lib/evas/filters/evas_filter.c | 3 +++ src/modules/evas/engines/gl_generic/evas_engine.c | 12 ++++++++++++ src/modules/evas/engines/software_generic/evas_engine.c | 17 +++++++++++------ 5 files changed, 50 insertions(+), 6 deletions(-) diff --git a/src/lib/evas/canvas/evas_object_main.c b/src/lib/evas/canvas/evas_object_main.c index 65ed189..bf8aac2 100644 --- a/src/lib/evas/canvas/evas_object_main.c +++ b/src/lib/evas/canvas/evas_object_main.c @@ -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; diff --git a/src/lib/evas/canvas/evas_render.c b/src/lib/evas/canvas/evas_render.c index 18560bf..d67a4e5 100644 --- a/src/lib/evas/canvas/evas_render.c +++ b/src/lib/evas/canvas/evas_render.c @@ -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: diff --git a/src/lib/evas/filters/evas_filter.c b/src/lib/evas/filters/evas_filter.c index f7eba26..894f0fd 100644 --- a/src/lib/evas/filters/evas_filter.c +++ b/src/lib/evas/filters/evas_filter.c @@ -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) diff --git a/src/modules/evas/engines/gl_generic/evas_engine.c b/src/modules/evas/engines/gl_generic/evas_engine.c index ed628e4..fe8125a 100644 --- a/src/modules/evas/engines/gl_generic/evas_engine.c +++ b/src/modules/evas/engines/gl_generic/evas_engine.c @@ -1750,6 +1750,17 @@ eng_context_clip_image_get(void *data EINA_UNUSED, void *context, void **ie, int } 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) { Render_Engine_GL_Generic *re = 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); diff --git a/src/modules/evas/engines/software_generic/evas_engine.c b/src/modules/evas/engines/software_generic/evas_engine.c index 17ed7f3..95032e2 100644 --- a/src/modules/evas/engines/software_generic/evas_engine.c +++ b/src/modules/evas/engines/software_generic/evas_engine.c @@ -411,12 +411,6 @@ eng_context_new(void *data EINA_UNUSED) } 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) { evas_common_draw_context_set_clip(context, x, y, w, h); @@ -477,6 +471,17 @@ eng_context_clip_image_get(void *data EINA_UNUSED, void *context, void **ie, int } 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) { evas_common_draw_context_clip_clip(context, x, y, w, h); --