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);

-- 


Reply via email to