From 139737247d563f53a064c7f4a025a89ed64c2983 Mon Sep 17 00:00:00 2001 From: Daniel Willmann Date: Fri, 8 Feb 2013 15:49:50 +0000 Subject: [PATCH] Refactor evas_sw_xlib_outbuf to allocate less in case of rotations. Previously whenever evas_software_xlib_outbuf_new_region_for_update was called for images that were rotated (!= 0) we created a new evas_cache_image. This resulted in (quite severe) memory spikes whenever an image was rotated. Now we try to get the original image first and only if that fails allocate a new one. TDevilhorns is already working on the port to the xcb backend. Signed-off-by: Daniel Willmann Signed-off-by: Stefan Schmidt SVN revision: 83789 --- ChangeLog | 11 ++- NEWS | 3 + .../engines/software_x11/evas_xlib_outbuf.c | 76 ++++++++++++++++--- 3 files changed, 77 insertions(+), 13 deletions(-) diff --git a/ChangeLog b/ChangeLog index be15c6da63..c845b4679a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,8 +1,17 @@ +2013-02-08 Stefan Schmidt + + * Fix memory leak in eina_xattr_value_ls. + * Fix memory leak in gstreamer_ecore_x_check + +2013-02-08 Daniel Willman + + * Fix memory usage spike when rotating with the software_x11 engine. + 2013-02-08 Tom Hacohen (TAsn) * Evas textblock: Fixed a selection issue with different scripts and bidi. - + 2013-02-08 Guillaume Friloux * Fix usage of Ecore_Con_Server's internal buffer. diff --git a/NEWS b/NEWS index 392cd33f74..91c9bf0d49 100644 --- a/NEWS +++ b/NEWS @@ -158,4 +158,7 @@ Fixes: * Fix memleak in Eina_File. * Fix ecore_x_screen_is_composited/set() to work on multihead. * Fix memory usage of Ecore_Con_Server + * Fix memory leak in eina_xattr_value_ls. + * Fix memory leak in gstreamer_ecore_x_check + * Fix memory usage spike when rotating with the software_x11 engine. * Evas textblock: Fixed a selection issue with different scripts and bidi. diff --git a/src/modules/evas/engines/software_x11/evas_xlib_outbuf.c b/src/modules/evas/engines/software_x11/evas_xlib_outbuf.c index d495931e5e..132bfb0535 100644 --- a/src/modules/evas/engines/software_x11/evas_xlib_outbuf.c +++ b/src/modules/evas/engines/software_x11/evas_xlib_outbuf.c @@ -364,7 +364,7 @@ evas_software_xlib_outbuf_setup_x(int w, int h, int rot, Outbuf_Depth depth, RGBA_Image * evas_software_xlib_outbuf_new_region_for_update(Outbuf *buf, int x, int y, int w, int h, int *cx, int *cy, int *cw, int *ch) { - RGBA_Image *im; + RGBA_Image *im = NULL; Outbuf_Region *obr; int bpl = 0; int use_shm = 1; @@ -459,6 +459,11 @@ evas_software_xlib_outbuf_new_region_for_update(Outbuf *buf, int x, int y, int w } else { + /* FIXME: For the onebuf case we probably need to do the same thing we did below + * (try to get an existing image before we allocate a new one). This code path + * is not really used at the moment so no way to test (and that's why the change + * is not implemented here as well. + */ #ifdef EVAS_CSERVE2 if (evas_cserve2_use_get()) im = (RGBA_Image *)evas_cache2_image_empty(evas_common_image_cache2_get()); @@ -612,26 +617,73 @@ evas_software_xlib_outbuf_new_region_for_update(Outbuf *buf, int x, int y, int w } else { + obr->xob = _find_xob(buf->priv.x11.xlib.disp, + buf->priv.x11.xlib.vis, + buf->priv.x11.xlib.depth, + w, h, + use_shm, + NULL); #ifdef EVAS_CSERVE2 if (evas_cserve2_use_get()) - im = (RGBA_Image *)evas_cache2_image_empty(evas_common_image_cache2_get()); + { + if (obr->xob) + im = (RGBA_Image *)evas_cache2_image_data(evas_common_image_cache2_get(), + w, h, + (DATA32 *) evas_software_xlib_x_output_buffer_data(obr->xob, &bpl), + alpha, EVAS_COLORSPACE_ARGB8888); + + if (!im) + { + if (obr->xob) _unfind_xob(obr->xob, 0); + im = (RGBA_Image *)evas_cache2_image_empty(evas_common_image_cache2_get()); + if (!im) + { + free(obr); + return NULL; + } + else + { + im->cache_entry.w = w; + im->cache_entry.h = h; + im->cache_entry.flags.alpha |= alpha ? 1 : 0; + evas_cache2_image_surface_alloc(&im->cache_entry, w, h); + } + } + } else #endif - im = (RGBA_Image *)evas_cache_image_empty(evas_common_image_cache_get()); - if (!im) { - free(obr); - return NULL; + if (obr->xob) + im = (RGBA_Image *)evas_cache_image_data(evas_common_image_cache_get(), + w, h, + (DATA32 *) evas_software_xlib_x_output_buffer_data(obr->xob, &bpl), + alpha, EVAS_COLORSPACE_ARGB8888); + + if (!im) + { + if (obr->xob) _unfind_xob(obr->xob, 0); + im = (RGBA_Image *)evas_cache_image_empty(evas_common_image_cache_get()); + if (!im) + { + free(obr); + return NULL; + } + else + { + im->cache_entry.w = w; + im->cache_entry.h = h; + im->cache_entry.flags.alpha |= alpha ? 1 : 0; + evas_cache_image_surface_alloc(&im->cache_entry, w, h); + } + } } + + /* Need to update cache_entry w/h here because the render path expects them to be updated + * to the new geometry. */ im->cache_entry.w = w; im->cache_entry.h = h; im->cache_entry.flags.alpha |= alpha ? 1 : 0; -#ifdef EVAS_CSERVE2 - if (evas_cserve2_use_get()) - evas_cache2_image_surface_alloc(&im->cache_entry, w, h); - else -#endif - evas_cache_image_surface_alloc(&im->cache_entry, w, h); + im->extended_info = obr; if ((buf->rot == 0) || (buf->rot == 180)) {