kwo pushed a commit to branch master.

http://git.enlightenment.org/legacy/imlib2.git/commit/?id=327f8c0ce4b9f95ff0af05d28504119ae85387dc

commit 327f8c0ce4b9f95ff0af05d28504119ae85387dc
Author: Kim Woelders <k...@woelders.dk>
Date:   Mon Feb 5 20:14:11 2018 +0100

    Refactor the XImage cache
    
    Simpler, faster.
---
 src/lib/ximage.c | 170 +++++++++++++++++++++++--------------------------------
 1 file changed, 70 insertions(+), 100 deletions(-)

diff --git a/src/lib/ximage.c b/src/lib/ximage.c
index 901860f..54430a6 100644
--- a/src/lib/ximage.c
+++ b/src/lib/ximage.c
@@ -13,19 +13,22 @@
 
 #include "ximage.h"
 
-/* global flags */
 static signed char  x_does_shm = -1;
 
 #ifdef HAVE_X11_SHM_FD
 static signed char  x_does_shm_fd = 0;
 #endif
 
-/* static private variables */
+typedef struct {
+   XImage             *xim;
+   XShmSegmentInfo    *si;
+   Display            *dpy;
+   char                used;
+} xim_cache_rec_t;
+
+static xim_cache_rec_t *xim_cache = NULL;
+
 static int          list_num = 0;
-static XImage     **list_xim = NULL;
-static XShmSegmentInfo **list_si = NULL;
-static Display    **list_d = NULL;
-static char        *list_used = NULL;
 static int          list_mem_use = 0;
 static int          list_max_mem = 1024 * 1024 * 1024;
 static int          list_max_count = 0;
@@ -244,22 +247,6 @@ __imlib_ShmDestroyXImage(Display * d, XImage * xim, 
XShmSegmentInfo * si)
    XDestroyImage(xim);
 }
 
-/* "safe" realloc allowing handling of out-of-memory situations */
-static void        *
-_safe_realloc(void *ptr, size_t size, int *err)
-{
-   void               *ptr_new;
-
-   ptr_new = realloc(ptr, size);
-   if (!ptr_new)
-     {
-        *err = 1;
-        return ptr;
-     }
-
-   return ptr_new;
-}
-
 void
 __imlib_SetMaxXImageCount(Display * d, int num)
 {
@@ -289,7 +276,7 @@ __imlib_GetMaxXImageTotalSize(Display * d)
 void
 __imlib_FlushXImage(Display * d)
 {
-   int                 i;
+   int                 i, j;
    XImage             *xim;
    char                did_free = 1;
 
@@ -297,58 +284,46 @@ __imlib_FlushXImage(Display * d)
           (did_free))
      {
         did_free = 0;
-        for (i = 0; i < list_num; i++)
+        for (i = 0; i < list_num;)
           {
-             if (list_used[i] == 0)
+             if (xim_cache[i].used)
                {
-                  int                 j;
+                  i++;
+                  continue;
+               }
 
-                  xim = list_xim[i];
-                  list_mem_use -= xim->bytes_per_line * xim->height;
-                  if (list_si[i])
-                    {
-                       __imlib_ShmDestroyXImage(d, xim, list_si[i]);
-                       free(list_si[i]);
-                    }
-                  else
-                    {
-                       XDestroyImage(xim);
-                    }
-                  list_num--;
-                  for (j = i; j < list_num; j++)
-                    {
-                       list_xim[j] = list_xim[j + 1];
-                       list_si[j] = list_si[j + 1];
-                       list_used[j] = list_used[j + 1];
-                       list_d[j] = list_d[j + 1];
-                    }
-                  if (list_num == 0)
-                    {
-                       if (list_xim)
-                          free(list_xim);
-                       if (list_si)
-                          free(list_si);
-                       if (list_used)
-                          free(list_used);
-                       if (list_d)
-                          free(list_d);
-                       list_xim = NULL;
-                       list_si = NULL;
-                       list_used = NULL;
-                       list_d = NULL;
-                    }
-                  else
-                    {
-                       list_xim =
-                          realloc(list_xim, sizeof(XImage *) * list_num);
-                       list_si =
-                          realloc(list_si,
-                                  sizeof(XShmSegmentInfo *) * list_num);
-                       list_used = realloc(list_used, sizeof(char) * list_num);
-                       list_d = realloc(list_d, sizeof(Display *) * list_num);
-                    }
-                  did_free = 1;
+             xim = xim_cache[i].xim;
+             list_mem_use -= xim->bytes_per_line * xim->height;
+
+             if (xim_cache[i].si)
+               {
+                  __imlib_ShmDestroyXImage(d, xim, xim_cache[i].si);
+                  free(xim_cache[i].si);
+               }
+             else
+               {
+                  XDestroyImage(xim);
+               }
+
+             list_num--;
+             for (j = i; j < list_num; j++)
+               {
+                  xim_cache[j] = xim_cache[j + 1];
                }
+
+             if (list_num == 0)
+               {
+                  if (xim_cache)
+                     free(xim_cache);
+                  xim_cache = NULL;
+               }
+             else
+               {
+                  xim_cache =
+                     realloc(xim_cache, sizeof(xim_cache_rec_t) * list_num);
+               }
+
+             did_free = 1;
           }
      }
 }
@@ -363,10 +338,10 @@ __imlib_ConsumeXImage(Display * d, XImage * xim)
    for (i = 0; i < list_num; i++)
      {
         /* find a match */
-        if (list_xim[i] == xim)
+        if (xim_cache[i].xim == xim)
           {
              /* we have a match = mark as unused */
-             list_used[i] = 0;
+             xim_cache[i].used = 0;
              /* flush the XImage list to get rud of stuff we dont want */
              __imlib_FlushXImage(d);
              /* return */
@@ -382,7 +357,8 @@ __imlib_ProduceXImage(Display * d, Visual * v, int depth, 
int w, int h,
                       char *shared)
 {
    XImage             *xim;
-   int                 i, err;
+   xim_cache_rec_t    *xim_cache_tmp;
+   int                 i;
 
    /* find a cached XImage (to avoid server to & fro) that is big enough */
    /* for our needs and the right depth */
@@ -390,43 +366,37 @@ __imlib_ProduceXImage(Display * d, Visual * v, int depth, 
int w, int h,
    /* go thru the current image list */
    for (i = 0; i < list_num; i++)
      {
-        int                 depth_ok = 0;
+        if (xim_cache[i].used)
+           continue;
+
+        xim = xim_cache[i].xim;
 
         /* if the image has the same depth, width and height - recycle it */
-        /* as long as its not used */
-        if (list_xim[i]->depth == depth)
-           depth_ok = 1;
-        if (depth_ok &&
-            (list_xim[i]->width >= w) && (list_xim[i]->height >= h) &&
-            /*   (list_d[i] == d) && */
-            (!list_used[i]))
+        if ((xim->depth == depth) && (xim->width >= w) && (xim->height >= h))
+           /*  && (xim_cache[i].dpy == d) */
           {
-             /* mark it as used */
-             list_used[i] = 1;
+             xim_cache[i].used = 1;
              /* if its shared set shared flag */
-             if (list_si[i])
+             if (xim_cache[i].si)
                 *shared = 1;
              /* return it */
-             return list_xim[i];
+             return xim;
           }
      }
 
    /* can't find a usable XImage on the cache - create one */
    /* add the new XImage to the XImage cache */
    list_num++;
-   err = 0;
-   list_xim = _safe_realloc(list_xim, sizeof(XImage *) * list_num, &err);
-   list_si = _safe_realloc(list_si, sizeof(XShmSegmentInfo *) * list_num, 
&err);
-   list_used = _safe_realloc(list_used, sizeof(char) * list_num, &err);
-   list_d = _safe_realloc(list_d, sizeof(Display *) * list_num, &err);
-   if (err)
+   xim_cache_tmp = realloc(xim_cache, sizeof(xim_cache_rec_t) * list_num);
+   if (!xim_cache_tmp)
      {
         /* failed to allocate memory */
         list_num--;
         return NULL;
      }
-   list_si[list_num - 1] = malloc(sizeof(XShmSegmentInfo));
-   if (!list_si[list_num - 1])
+   xim_cache = xim_cache_tmp;
+   xim_cache[list_num - 1].si = malloc(sizeof(XShmSegmentInfo));
+   if (!xim_cache[list_num - 1].si)
      {
         /* failed to allocate memory */
         list_num--;
@@ -435,7 +405,7 @@ __imlib_ProduceXImage(Display * d, Visual * v, int depth, 
int w, int h,
 
    /* work on making a shared image */
    xim = __imlib_ShmGetXImage(d, v, None, depth, 0, 0, w, h,
-                              list_si[list_num - 1]);
+                              xim_cache[list_num - 1].si);
    /* ok if xim == NULL it all failed - fall back to XImages */
    if (xim)
      {
@@ -444,9 +414,9 @@ __imlib_ProduceXImage(Display * d, Visual * v, int depth, 
int w, int h,
    else
      {
         /* get rid of out shm info struct */
-        free(list_si[list_num - 1]);
+        free(xim_cache[list_num - 1].si);
         /* flag it as NULL ot indicate a normal XImage */
-        list_si[list_num - 1] = NULL;
+        xim_cache[list_num - 1].si = NULL;
         /* create a normal ximage */
         xim = XCreateImage(d, v, depth, ZPixmap, 0, NULL, w, h, 32, 0);
         /* allocate data for it */
@@ -462,13 +432,13 @@ __imlib_ProduceXImage(Display * d, Visual * v, int depth, 
int w, int h,
           }
      }
    /* add xim to our list */
-   list_xim[list_num - 1] = xim;
+   xim_cache[list_num - 1].xim = xim;
    /* incriment our memory count */
    list_mem_use += xim->bytes_per_line * xim->height;
    /* mark image as used */
-   list_used[list_num - 1] = 1;
+   xim_cache[list_num - 1].used = 1;
    /* remember what display that XImage was for */
-   list_d[list_num - 1] = d;
+   xim_cache[list_num - 1].dpy = d;
 
    /* flush unused images from the image list */
    __imlib_FlushXImage(d);

-- 


Reply via email to