diff --git a/legacy/evas/ChangeLog b/legacy/evas/ChangeLog index bf5ff5ccbc..7ef8fa5502 100644 --- a/legacy/evas/ChangeLog +++ b/legacy/evas/ChangeLog @@ -1034,3 +1034,4 @@ * Fix image alpha set bug if the image data has not been loaded yet from disk. Fixes across software and gl engines needed. + * Fix map surface leak. diff --git a/legacy/evas/NEWS b/legacy/evas/NEWS index d7c69ac43b..e261d9592a 100644 --- a/legacy/evas/NEWS +++ b/legacy/evas/NEWS @@ -17,6 +17,7 @@ Fixes: * Fix segmentation fault with the esvg loader. * Fix EGL/GLES dest alpha rendering bug (no rendering). * Fix evas_object_image_alpha_set when image data not loaded yet. + * Fix map surface leak. Evas 1.7.0 diff --git a/legacy/evas/src/lib/canvas/evas_map.c b/legacy/evas/src/lib/canvas/evas_map.c index ee6a4c8a9f..4466d8a4dc 100644 --- a/legacy/evas/src/lib/canvas/evas_map.c +++ b/legacy/evas/src/lib/canvas/evas_map.c @@ -166,9 +166,6 @@ _evas_map_free(Evas_Object *obj, Evas_Map *m) { if (obj) { - if (m->surface) - obj->layer->evas->engine.func->image_map_surface_free - (obj->layer->evas->engine.data.output, m->surface); if (obj->spans) { obj->layer->evas->engine.func->image_map_clean(obj->layer->evas->engine.data.output, obj->spans); @@ -408,6 +405,13 @@ evas_object_map_enable_set(Evas_Object *obj, Eina_Bool enabled) } else { + if (obj->map.surface) + { + obj->layer->evas->engine.func->image_map_surface_free + (obj->layer->evas->engine.data.output, + obj->map.surface); + obj->map.surface = NULL; + } if (obj->cur.map) { _evas_map_calc_geom_change(obj); @@ -449,19 +453,18 @@ evas_object_map_set(Evas_Object *obj, const Evas_Map *map) return; MAGIC_CHECK_END(); - if (!map || map->count < 4) + if ((!map) || (map->count < 4)) { + if (obj->map.surface) + { + obj->layer->evas->engine.func->image_map_surface_free + (obj->layer->evas->engine.data.output, + obj->map.surface); + obj->map.surface = NULL; + } if (obj->cur.map) { obj->changed_map = EINA_TRUE; - - if (obj->cur.map->surface) - { - obj->layer->evas->engine.func->image_map_surface_free - (obj->layer->evas->engine.data.output, - obj->cur.map->surface); - obj->cur.map->surface = NULL; - } obj->prev.geometry = obj->cur.map->normal_geometry; if (obj->prev.map == obj->cur.map) diff --git a/legacy/evas/src/lib/canvas/evas_object_main.c b/legacy/evas/src/lib/canvas/evas_object_main.c index 80f4d9da1e..71dacb10f3 100644 --- a/legacy/evas/src/lib/canvas/evas_object_main.c +++ b/legacy/evas/src/lib/canvas/evas_object_main.c @@ -66,6 +66,13 @@ evas_object_free(Evas_Object *obj, int clean_layer) evas_object_map_set(obj, NULL); if (obj->prev.map) evas_map_free(obj->prev.map); if (obj->cache_map) evas_map_free(obj->cache_map); + if (obj->map.surface) + { + obj->layer->evas->engine.func->image_map_surface_free + (obj->layer->evas->engine.data.output, + obj->map.surface); + obj->map.surface = NULL; + } evas_object_grabs_cleanup(obj); evas_object_intercept_cleanup(obj); if (obj->smart.parent) was_smart_child = 1; diff --git a/legacy/evas/src/lib/canvas/evas_render.c b/legacy/evas/src/lib/canvas/evas_render.c index 89de64e517..e6eff0cfb9 100644 --- a/legacy/evas/src/lib/canvas/evas_render.c +++ b/legacy/evas/src/lib/canvas/evas_render.c @@ -861,27 +861,27 @@ evas_render_mapped(Evas *e, Evas_Object *obj, void *context, void *surface, } evas_object_map_update(obj, off_x, off_y, sw, sh, sw, sh); - if (obj->cur.map->surface) + if (obj->map.surface) { - if ((obj->cur.map->surface_w != sw) || - (obj->cur.map->surface_h != sh)) + if ((obj->map.surface_w != sw) || + (obj->map.surface_h != sh)) { RDI(level); RD(" new surf: %ix%i\n", sw, sh); obj->layer->evas->engine.func->image_map_surface_free - (e->engine.data.output, obj->cur.map->surface); - obj->cur.map->surface = NULL; + (e->engine.data.output, obj->map.surface); + obj->map.surface = NULL; } } - if (!obj->cur.map->surface) + if (!obj->map.surface) { - obj->cur.map->surface_w = sw; - obj->cur.map->surface_h = sh; + obj->map.surface_w = sw; + obj->map.surface_h = sh; - obj->cur.map->surface = + obj->map.surface = obj->layer->evas->engine.func->image_map_surface_new - (e->engine.data.output, obj->cur.map->surface_w, - obj->cur.map->surface_h, + (e->engine.data.output, obj->map.surface_w, + obj->map.surface_h, obj->cur.map->alpha); RDI(level); RD(" fisrt surf: %ix%i\n", sw, sh); @@ -923,7 +923,7 @@ evas_render_mapped(Evas *e, Evas_Object *obj, void *context, void *surface, obj->prev.valid_map = EINA_FALSE; // clear surface before re-render - if ((changed) && (obj->cur.map->surface)) + if ((changed) && (obj->map.surface)) { int off_x2, off_y2; @@ -940,10 +940,10 @@ evas_render_mapped(Evas *e, Evas_Object *obj, void *context, void *surface, (e->engine.data.output, ctx, EVAS_RENDER_COPY); e->engine.func->rectangle_draw(e->engine.data.output, ctx, - obj->cur.map->surface, + obj->map.surface, 0, 0, - obj->cur.map->surface_w, - obj->cur.map->surface_h); + obj->map.surface_w, + obj->map.surface_h); e->engine.func->context_free(e->engine.data.output, ctx); } ctx = e->engine.func->context_new(e->engine.data.output); @@ -955,7 +955,7 @@ evas_render_mapped(Evas *e, Evas_Object *obj, void *context, void *surface, (evas_object_smart_members_get_direct(obj), obj2) { clean_them |= evas_render_mapped(e, obj2, ctx, - obj->cur.map->surface, + obj->map.surface, off_x2, off_y2, 1, ecx, ecy, ecw, ech #ifdef REND_DGB @@ -968,8 +968,8 @@ evas_render_mapped(Evas *e, Evas_Object *obj, void *context, void *surface, { int x = 0, y = 0, w = 0, h = 0; - w = obj->cur.map->surface_w; - h = obj->cur.map->surface_h; + w = obj->map.surface_w; + h = obj->map.surface_h; RECTS_CLIP_TO_RECT(x, y, w, h, obj->cur.geometry.x + off_x2, obj->cur.geometry.y + off_y2, @@ -979,7 +979,7 @@ evas_render_mapped(Evas *e, Evas_Object *obj, void *context, void *surface, e->engine.func->context_clip_set(e->engine.data.output, ctx, x, y, w, h); obj->func->render(obj, e->engine.data.output, ctx, - obj->cur.map->surface, off_x2, off_y2); + obj->map.surface, off_x2, off_y2); } e->engine.func->context_free(e->engine.data.output, ctx); rendered = EINA_TRUE; @@ -990,14 +990,14 @@ evas_render_mapped(Evas *e, Evas_Object *obj, void *context, void *surface, if (rendered) { - obj->cur.map->surface = e->engine.func->image_dirty_region - (e->engine.data.output, obj->cur.map->surface, - 0, 0, obj->cur.map->surface_w, obj->cur.map->surface_h); + obj->map.surface = e->engine.func->image_dirty_region + (e->engine.data.output, obj->map.surface, + 0, 0, obj->map.surface_w, obj->map.surface_h); obj->cur.valid_map = EINA_TRUE; } e->engine.func->context_clip_unset(e->engine.data.output, context); - if (obj->cur.map->surface) + if (obj->map.surface) { if (obj->cur.clipper) { @@ -1040,14 +1040,14 @@ evas_render_mapped(Evas *e, Evas_Object *obj, void *context, void *surface, (e->engine.data.output, context); obj->layer->evas->engine.func->image_map_draw (e->engine.data.output, context, surface, - obj->cur.map->surface, obj->spans, + obj->map.surface, obj->spans, obj->cur.map->smooth, 0); } // FIXME: needs to cache these maps and // keep them only rendering updates // obj->layer->evas->engine.func->image_map_surface_free - // (e->engine.data.output, obj->cur.map->surface); - // obj->cur.map->surface = NULL; + // (e->engine.data.output, obj->map.surface); + // obj->map.surface = NULL; } else { @@ -1754,11 +1754,11 @@ evas_sync(Evas *e) static void _evas_render_dump_map_surfaces(Evas_Object *obj) { - if ((obj->cur.map) && obj->cur.map->surface) + if ((obj->cur.map) && obj->map.surface) { obj->layer->evas->engine.func->image_map_surface_free - (obj->layer->evas->engine.data.output, obj->cur.map->surface); - obj->cur.map->surface = NULL; + (obj->layer->evas->engine.data.output, obj->map.surface); + obj->map.surface = NULL; } if (obj->smart.smart) diff --git a/legacy/evas/src/lib/include/evas_private.h b/legacy/evas/src/lib/include/evas_private.h index fdd24c7cb2..16c749b317 100644 --- a/legacy/evas/src/lib/include/evas_private.h +++ b/legacy/evas/src/lib/include/evas_private.h @@ -463,8 +463,8 @@ struct _Evas_Map DATA32 magic; int count; // num of points Evas_Coord_Rectangle normal_geometry; // bounding box of map geom actually - void *surface; // surface holding map if needed - int surface_w, surface_h; // current surface w & h alloc +// void *surface; // surface holding map if needed +// int surface_w, surface_h; // current surface w & h alloc Evas_Coord mx, my; // mouse x, y after conversion to map space struct { Evas_Coord px, py, z0, foc; @@ -544,6 +544,11 @@ struct _Evas_Object Eina_Bool parent_cached_surface : 1; } cur, prev; + struct { + void *surface; // surface holding map if needed + int surface_w, surface_h; // current surface w & h alloc + } map; + Evas_Map *cache_map; char *name;