Refactor evas_sw_xlib_outbuf to allocate less in case of rotations.
authorDaniel Willmann <d.willmann@samsung.com>
Fri, 8 Feb 2013 15:49:50 +0000 (15:49 +0000)
committerStefan Schmidt <stefan@datenfreihafen.org>
Fri, 8 Feb 2013 15:49:50 +0000 (15:49 +0000)
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 <d.willmann@samsung.com>
Signed-off-by: Stefan Schmidt <s.schmidt@samsung.com>
SVN revision: 83789

ChangeLog
NEWS
src/modules/evas/engines/software_x11/evas_xlib_outbuf.c

index be15c6d..c845b46 100644 (file)
--- 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 392cd33..91c9bf0 100644 (file)
--- 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.
index d495931..132bfb0 100644 (file)
@@ -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))
           {