Evas_image_cache fix memory leak related with cache image
authorJiyoun Park <jy0703.park@samsung.com>
Fri, 22 Apr 2011 07:07:08 +0000 (16:07 +0900)
committerJiyoun Park <jy0703.park@samsung.com>
Fri, 22 Apr 2011 07:07:08 +0000 (16:07 +0900)
before we didn't insert cache entry into lru because of flush error.
cache entry is not lru cache so cache system can't release some cache entry.
this code is alredy in open source

Change-Id: I20f59c0fe2fcca47fd4b9dcafc7008fa018f0a8f

src/lib/cache/evas_cache_image.c [changed mode: 0644->0755]
src/lib/engines/common/evas_image_main.c
src/lib/include/evas_common.h

old mode 100644 (file)
new mode 100755 (executable)
index b48e53f..2c0b5a3
@@ -15,6 +15,8 @@
 #include "evas_common.h"
 #include "evas_private.h"
 
+//#define CACHEDUMP 1
+
 #ifdef EVAS_CSERVE
 // FIXME: cache server and threaded preload clash badly atm - disable
 //#undef BUILD_ASYNC_PRELOAD
@@ -43,65 +45,32 @@ static void _evas_cache_image_entry_preload_remove(Image_Entry *ie, const void *
        eina_stringshare_del(Var);  \
        Var = NULL;                 \
     }
-//#define CACHEDUMP 1
-
-#ifdef CACHEDUMP
-static void
-_dump_img(Image_Entry *im, const char *type)
-{
-  printf("%s: %4i: %4ikb, %4ix%4i alloc[%4ix%4i] [%s] [%s]\n",
-         type,
-         im->references,
-         (im->allocated.w * im->allocated.h * 4) / 1024,
-         im->w, im->h, im->allocated.w, im->allocated.h,
-         im->file, im->key);
-}
-
-static Eina_Bool
-_dump_cache_active(__UNUSED__ const Eina_Hash *hash, __UNUSED__ const void *key, void *data, void *fdata __UNUSED__)
-{
-  Image_Entry *im = data;
-  _dump_img(im, "ACTIVE");
-   return EINA_TRUE;
-}
-
-static void
-_dump_cache(Evas_Cache_Image *cache)
-{
-  Image_Entry *im;
   
-  printf("--CACHE DUMP----------------------------------------------------\n");
-  printf("%cache: %ikb / %ikb\n",
-         cache->usage / 1024,
-         cache->limit / 1024);
-  printf("................................................................\n");
-  EINA_INLIST_FOREACH(cache->lru_nodata, im)
-    _dump_img(im, "NODATA");
-  EINA_INLIST_FOREACH(cache->lru, im)
-    _dump_img(im, "DATA  ");
-  eina_hash_foreach(cache->activ, _dump_cache_active, NULL);
-}
-#endif
-
-static void _evas_cache_image_entry_delete(Evas_Cache_Image *cache, Image_Entry *ie);
+static void _evas_cache_image_dirty_add(Image_Entry *im);
+static void _evas_cache_image_dirty_del(Image_Entry *im);
+static void _evas_cache_image_activ_add(Image_Entry *im);
+static void _evas_cache_image_activ_del(Image_Entry *im);
+static void _evas_cache_image_lru_add(Image_Entry *im);
+static void _evas_cache_image_lru_del(Image_Entry *im);
+static void _evas_cache_image_lru_nodata_add(Image_Entry *im);
+static void _evas_cache_image_lru_nodata_del(Image_Entry *im);
 
 static void
-_evas_cache_image_make_dirty(Evas_Cache_Image *cache, Image_Entry *im)
+_evas_cache_image_dirty_add(Image_Entry *im)
 {
    if (im->flags.dirty) return;
-   im->flags.cached = 1;
+   _evas_cache_image_activ_del(im);
+   _evas_cache_image_lru_del(im);
+   _evas_cache_image_lru_nodata_del(im);
    im->flags.dirty = 1;
-   im->flags.activ = 0;
-   im->flags.lru_nodata = 0;
+   im->flags.cached = 1;
 #ifdef EVAS_FRAME_QUEUING
-   LKL(cache->lock);
+   LKL(im->cache->lock);
 #endif
-   cache->dirty = eina_inlist_prepend(cache->dirty, EINA_INLIST_GET(im));
+   im->cache->dirty = eina_inlist_prepend(im->cache->dirty, EINA_INLIST_GET(im));
 #ifdef EVAS_FRAME_QUEUING
-   LKU(cache->lock);
+   LKU(im->cache->lock);
 #endif
-
    if (im->cache_key)
      {
         eina_stringshare_del(im->cache_key);
@@ -110,168 +79,152 @@ _evas_cache_image_make_dirty(Evas_Cache_Image *cache, Image_Entry *im)
 }
 
 static void
-_evas_cache_image_make_activ(Evas_Cache_Image *cache,
-                             Image_Entry *im, const char *key)
+_evas_cache_image_dirty_del(Image_Entry *im)
 {
-   /* FIXME: Handle case when image is being processed anyway and don't do a double decode. */
-   if (im->flags.activ) return;
-   im->cache_key = key;
-   if (key)
-     {
-        im->flags.cached = 1;
-        im->flags.activ = 1;
-        im->flags.lru_nodata = 0;
+   if (!im->flags.dirty) return;
         im->flags.dirty = 0;
+   im->flags.cached = 0;
 #ifdef EVAS_FRAME_QUEUING
-        LKL(cache->lock);
+   LKL(im->cache->lock);
 #endif
-       eina_hash_direct_add(cache->activ, key, im);
+   im->cache->dirty = eina_inlist_remove(im->cache->dirty, EINA_INLIST_GET(im));
 #ifdef EVAS_FRAME_QUEUING
-        LKU(cache->lock);
+   LKU(im->cache->lock);
 #endif
      }
-   else
+
+static void
+_evas_cache_image_activ_add(Image_Entry *im)
      {
-        _evas_cache_image_make_dirty(cache, im);
-     }
+   if (im->flags.activ) return;
+   _evas_cache_image_dirty_del(im);
+   _evas_cache_image_lru_del(im);
+   _evas_cache_image_lru_nodata_del(im);
+   if (!im->cache_key) return;
+   im->flags.activ = 1;
+   im->flags.cached = 1;
+#ifdef EVAS_FRAME_QUEUING
+   LKL(im->cache->lock);
+#endif
+   eina_hash_direct_add(im->cache->activ, im->cache_key, im);
+#ifdef EVAS_FRAME_QUEUING
+   LKU(im->cache->lock);
+#endif
 }
 
 static void
-_evas_cache_image_make_inactiv(Evas_Cache_Image *cache,
-                               Image_Entry *im, const char *key)
+_evas_cache_image_activ_del(Image_Entry *im)
 {
    if (!im->flags.activ) return;
-   if (im->cache_key)
-     {
+   if (!im->cache_key) return;
        im->flags.activ = 0;
-       im->flags.dirty = 0;
-       im->flags.cached = 1;
+   im->flags.cached = 0;
 #ifdef EVAS_FRAME_QUEUING
-        LKL(cache->lock);
+   LKL(im->cache->lock);
 #endif
-       eina_hash_direct_add(cache->inactiv, key, im);
-       cache->lru = eina_inlist_prepend(cache->lru, EINA_INLIST_GET(im));
-       cache->usage += cache->func.mem_size_get(im);
+   eina_hash_del(im->cache->activ, im->cache_key, im);
 #ifdef EVAS_FRAME_QUEUING
-        LKU(cache->lock);
+   LKU(im->cache->lock);
 #endif
      }
-   else
-     {
-       _evas_cache_image_entry_delete(cache, im);
-     }
- }
 
 static void
-_evas_cache_image_remove_lru_nodata(Evas_Cache_Image *cache, Image_Entry *im)
+_evas_cache_image_lru_add(Image_Entry *im)
 {
-   if (im->flags.lru_nodata)
-     {
-        im->flags.lru_nodata = 0;
+   if (im->flags.lru) return;
+   _evas_cache_image_dirty_del(im);
+   _evas_cache_image_activ_del(im);
+   _evas_cache_image_lru_nodata_del(im); 
+   if (!im->cache_key) return;
+   im->flags.lru = 1;
+   im->flags.cached = 1;
 #ifdef EVAS_FRAME_QUEUING
-        LKL(cache->lock);
+   LKL(im->cache->lock);
 #endif
-        cache->lru_nodata = eina_inlist_remove(cache->lru_nodata, EINA_INLIST_GET(im));
-        cache->usage -= cache->func.mem_size_get(im);
+   eina_hash_direct_add(im->cache->inactiv, im->cache_key, im);
+   im->cache->lru = eina_inlist_prepend(im->cache->lru, EINA_INLIST_GET(im));
+   im->cache->usage += im->cache->func.mem_size_get(im);
 #ifdef EVAS_FRAME_QUEUING
-        LKU(cache->lock);
+   LKU(im->cache->lock);
 #endif
     }
-}
 
 static void
-_evas_cache_image_activ_lru_nodata(Evas_Cache_Image *cache, Image_Entry *im)
+_evas_cache_image_lru_del(Image_Entry *im)
 {
-   if (!im->flags.lru_nodata) return;
-   im->flags.need_data = 0;
-   im->flags.lru_nodata = 1;
+   if (!im->flags.lru) return;
+   if (!im->cache_key) return;
+   im->flags.lru = 0;
+   im->flags.cached = 0;
 #ifdef EVAS_FRAME_QUEUING
-   LKL(cache->lock);
+   LKL(im->cache->lock);
 #endif
-   cache->lru_nodata = eina_inlist_prepend(cache->lru_nodata, EINA_INLIST_GET(im));
-   cache->usage += cache->func.mem_size_get(im);
+   eina_hash_del(im->cache->inactiv, im->cache_key, im);
+   im->cache->lru = eina_inlist_remove(im->cache->lru, EINA_INLIST_GET(im));
+   im->cache->usage -= im->cache->func.mem_size_get(im);
 #ifdef EVAS_FRAME_QUEUING
-   LKU(cache->lock);
+   LKU(im->cache->lock);
 #endif
 }
 
 static void
-_evas_cache_image_remove_activ(Evas_Cache_Image *cache, Image_Entry *ie)
-{
-   if (ie->flags.cached)
-     {
-        if (ie->flags.activ)
+_evas_cache_image_lru_nodata_add(Image_Entry *im)
           {
+   if (im->flags.lru_nodata) return;
+   _evas_cache_image_dirty_del(im);
+   _evas_cache_image_activ_del(im);
+   _evas_cache_image_lru_del(im);
+   im->flags.lru = 1;
+   im->flags.cached = 1;
 #ifdef EVAS_FRAME_QUEUING
-             LKL(cache->lock);
+   LKL(im->cache->lock);
 #endif
-            eina_hash_del(cache->activ, ie->cache_key, ie);
+   im->cache->lru_nodata = eina_inlist_prepend(im->cache->lru_nodata, EINA_INLIST_GET(im));
 #ifdef EVAS_FRAME_QUEUING
-             LKU(cache->lock);
+   LKU(im->cache->lock);
 #endif
-             _evas_cache_image_remove_lru_nodata(cache, ie);
           }
-        else
+
+static void
+_evas_cache_image_lru_nodata_del(Image_Entry *im)
           {
+   if (!im->flags.lru_nodata) return;
+   im->flags.lru = 0;
+   im->flags.cached = 0;
 #ifdef EVAS_FRAME_QUEUING
-             LKL(cache->lock);
+   LKL(im->cache->lock);
 #endif
-             if (ie->flags.dirty)
-               {
-                 cache->dirty = eina_inlist_remove(cache->dirty, EINA_INLIST_GET(ie));
-               }
-             else
-               {
-                 eina_hash_del(cache->inactiv, ie->cache_key, ie);
-                  cache->lru = eina_inlist_remove(cache->lru, EINA_INLIST_GET(ie));
-                  cache->usage -= cache->func.mem_size_get(ie);
-               }
+   im->cache->lru_nodata = eina_inlist_remove(im->cache->lru_nodata, EINA_INLIST_GET(im));
 #ifdef EVAS_FRAME_QUEUING
-             LKU(cache->lock);
+   LKU(im->cache->lock);
 #endif
           }
-        ie->flags.cached = 0;
-        ie->flags.dirty = 0;
-        ie->flags.activ = 0;
-     }
-}
 
 static void
 _evas_cache_image_entry_delete(Evas_Cache_Image *cache, Image_Entry *ie)
 {
    if (!ie) return;
-
-   if (cache->func.debug)
-     cache->func.debug("deleting", ie);
-
+   if (cache->func.debug) cache->func.debug("deleting", ie);
 #ifdef BUILD_ASYNC_PRELOAD
-   if (ie->flags.delete_me == 1)
-     return ;
-
+   if (ie->flags.delete_me == 1) return;
    if (ie->preload)
      {
        ie->flags.delete_me = 1;
-
        _evas_cache_image_entry_preload_remove(ie, NULL);
        return ;
      }
 #endif
 
-   _evas_cache_image_remove_activ(cache, ie);
+   _evas_cache_image_dirty_del(ie);
+   _evas_cache_image_activ_del(ie);
+   _evas_cache_image_lru_del(ie);
+   _evas_cache_image_lru_nodata_del(ie);
 
    cache->func.destructor(ie);
-
-   if (ie->cache_key)
-     {
-        eina_stringshare_del(ie->cache_key);
-        ie->cache_key = NULL;
-     }
-
+   FREESTRC(ie->cache_key);
    FREESTRC(ie->file);
    FREESTRC(ie->key);
-
    ie->cache = NULL;
-
    cache->func.surface_delete(ie);
 
 #ifdef BUILD_ASYNC_PRELOAD
@@ -281,7 +234,6 @@ _evas_cache_image_entry_delete(Evas_Cache_Image *cache, Image_Entry *ie)
 #ifdef EVAS_FRAME_QUEUING
    LKD(ie->lock_references);
 #endif
-
    cache->func.dealloc(ie);
 }
 
@@ -293,9 +245,11 @@ _timestamp_compare(Image_Timestamp *tstamp, struct stat *st)
    if (tstamp->ino != st->st_ino) return EINA_FALSE;
 #ifdef _STAT_VER_LINUX
 #if (defined __USE_MISC && defined st_mtime)
-   if (tstamp->mtime_nsec != (unsigned long int)st->st_mtim.tv_nsec) return EINA_FALSE;
+   if (tstamp->mtime_nsec != (unsigned long int)st->st_mtim.tv_nsec)
+      return EINA_FALSE;
 #else
-   if (tstamp->mtime_nsec != (unsigned long int)st->st_mtimensec) return EINA_FALSE;
+   if (tstamp->mtime_nsec != (unsigned long int)st->st_mtimensec)
+      return EINA_FALSE;
 #endif
 #endif
    return EINA_TRUE;
@@ -326,7 +280,6 @@ _evas_cache_image_entry_new(Evas_Cache_Image *cache,
                             int *error)
 {
    Image_Entry  *ie;
-   const char   *cache_key;
 
    ie = cache->func.alloc();
    if (!ie)
@@ -334,54 +287,28 @@ _evas_cache_image_entry_new(Evas_Cache_Image *cache,
        *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
        return NULL;
      }
-
-   cache_key = hkey ? eina_stringshare_add(hkey) : NULL;
-
-   ie->flags.loaded = 0;
+   ie->cache = cache;
+   if (hkey) ie->cache_key = eina_stringshare_add(hkey);
    ie->flags.need_data = 1;
-
-   _evas_cache_image_make_activ(cache, ie, cache_key);
-
    ie->space = EVAS_COLORSPACE_ARGB8888;
    ie->w = -1;
    ie->h = -1;
-   ie->allocated.w = 0;
-   ie->allocated.h = 0;
+   ie->scale = 1;
+   if (file) ie->file = eina_stringshare_add(file);
+   if (key) ie->key = eina_stringshare_add(key);
+   if (tstamp) ie->tstamp = *tstamp;
+   else memset(&ie->tstamp, 0, sizeof(Image_Timestamp));
 
 #ifdef EVAS_FRAME_QUEUING
    LKI(ie->lock_references);
 #endif
-   ie->references = 0;
-   ie->cache = cache;
-
-   ie->file = file ? eina_stringshare_add(file) : NULL;
-   ie->key = key ? eina_stringshare_add(key) : NULL;
-
-   if (tstamp) ie->tstamp = *tstamp;
-   else memset(&ie->tstamp, 0, sizeof(Image_Timestamp));
-
-   ie->load_opts.scale_down_by = 0;
-   ie->load_opts.dpi = 0;
-   ie->load_opts.w = 0;
-   ie->load_opts.h = 0;
-   ie->load_opts.region.x = 0;
-   ie->load_opts.region.y = 0;
-   ie->load_opts.region.w = 0;
-   ie->load_opts.region.h = 0;
-   ie->scale = 1;
-
 #ifdef BUILD_ASYNC_PRELOAD
    LKI(ie->lock);
    LKI(ie->lock_cancel); 
-   ie->targets = NULL;
-   ie->preload = NULL;
-   ie->flags.delete_me = 0;
 #endif
 
-   if (lo)
-     ie->load_opts = *lo;
-
-   if (file)
+   if (lo) ie->load_opts = *lo;
+   if (ie->file)
      {
         *error = cache->func.constructor(ie);
         if (*error != EVAS_LOAD_ERROR_NONE)
@@ -390,9 +317,9 @@ _evas_cache_image_entry_new(Evas_Cache_Image *cache,
              return NULL;
           }
      }
-   if (cache->func.debug)
-     cache->func.debug("build", ie);
-
+   if (cache->func.debug) cache->func.debug("build", ie);
+   if (ie->cache_key) _evas_cache_image_activ_add(ie);
+   else _evas_cache_image_dirty_add(ie);
    return ie;
 }
 
@@ -402,15 +329,12 @@ _evas_cache_image_entry_surface_alloc__locked(Evas_Cache_Image *cache,
                                              unsigned int wmin,
                                               unsigned int hmin)
 {
-   if (ie->allocated.w == wmin && ie->allocated.h == hmin)
-     return ;
-
+   if ((ie->allocated.w == wmin) && (ie->allocated.h == hmin)) return;
    if (cache->func.surface_alloc(ie, wmin, hmin))
      {
         wmin = 0;
         hmin = 0;
      }
-
    ie->w = wmin;
    ie->h = hmin;
    ie->allocated.w = wmin;
@@ -421,12 +345,8 @@ static void
 _evas_cache_image_entry_surface_alloc(Evas_Cache_Image *cache,
                                       Image_Entry *ie, int w, int h)
 {
-   int  wmin;
-   int  hmin;
-
-   wmin = w > 0 ? w : 1;
-   hmin = h > 0 ? h : 1;
-
+   int wmin = w > 0 ? w : 1;
+   int hmin = h > 0 ? h : 1;
 #ifdef BUILD_ASYNC_PRELOAD
    LKL(engine_lock);
 #endif
@@ -452,23 +372,20 @@ _evas_cache_image_async_heavy(void *data)
    current->channel++;
    cache = current->cache;
 
-   if (!current->flags.loaded && ((Evas_Image_Load_Func*) current->info.module)->threadable)
+   if ((!current->flags.loaded) && 
+       ((Evas_Image_Load_Func*) current->info.module)->threadable)
      {
        error = cache->func.load(current);
-       if (cache->func.debug)
-         cache->func.debug("load", current);
+       if (cache->func.debug) cache->func.debug("load", current);
        if (error != EVAS_LOAD_ERROR_NONE)
          {
             current->flags.loaded = 0;
             _evas_cache_image_entry_surface_alloc(cache, current,
                                                   current->w, current->h);
          }
-       else
-         current->flags.loaded = 1;
+       else current->flags.loaded = 1;
      }
-
    current->channel = pchannel;
-   
    // check the unload cancel flag
    LKL(current->lock_cancel);
    if (current->unload_cancel)
@@ -479,7 +396,6 @@ _evas_cache_image_async_heavy(void *data)
         current->flags.preload_done = 0;
      }
    LKU(current->lock_cancel);
-   
    LKU(current->lock);
 }
 
@@ -491,15 +407,14 @@ _evas_cache_image_async_end(void *data)
 
    ie->cache->preload = eina_list_remove(ie->cache->preload, ie);
    ie->cache->pending = eina_list_remove(ie->cache->pending, ie);
-
    ie->preload = NULL;
    ie->flags.preload_done = ie->flags.loaded;
-   while (ie->targets)
+   while ((tmp = ie->targets))
      {
-       tmp = ie->targets;
-
        evas_object_inform_call_image_preloaded((Evas_Object*) tmp->target);
-       ie->targets = (Evas_Cache_Target*) eina_inlist_remove(EINA_INLIST_GET(ie->targets), EINA_INLIST_GET(ie->targets));
+       ie->targets = (Evas_Cache_Target *)
+           eina_inlist_remove(EINA_INLIST_GET(ie->targets), 
+                              EINA_INLIST_GET(ie->targets));
        free(tmp);
      }
 }
@@ -512,27 +427,19 @@ _evas_cache_image_async_cancel(void *data)
 
    ie->preload = NULL;
    ie->cache->pending = eina_list_remove(ie->cache->pending, ie);
-
-   if (ie->flags.delete_me || ie->flags.dirty)
+   if ((ie->flags.delete_me) || (ie->flags.dirty))
      {
        ie->flags.delete_me = 0;
        _evas_cache_image_entry_delete(ie->cache, ie);
-
        return ;
      }
-
-   if (ie->flags.loaded)
-     {
-       _evas_cache_image_async_end(ie);
-     }
-
+   if (ie->flags.loaded) _evas_cache_image_async_end(ie);
 #ifdef EVAS_FRAME_QUEUING
    LKL(ie->lock_references);
 #endif
    if (ie->references == 0)
      {
-       _evas_cache_image_remove_activ(ie->cache, ie);
-       _evas_cache_image_make_inactiv(ie->cache, ie, ie->cache_key);
+        _evas_cache_image_lru_add(ie);
         cache = ie->cache;
      }
 #ifdef EVAS_FRAME_QUEUING
@@ -547,25 +454,21 @@ _evas_cache_image_entry_preload_add(Image_Entry *ie, const void *target)
    Evas_Cache_Target *tg;
 
    if (ie->flags.preload_done) return 0;
-
    tg = malloc(sizeof (Evas_Cache_Target));
    if (!tg) return 0;
 
    tg->target = target;
-
-   ie->targets = (Evas_Cache_Target*) eina_inlist_append(EINA_INLIST_GET(ie->targets), EINA_INLIST_GET(tg));
-
+   ie->targets = (Evas_Cache_Target *)
+      eina_inlist_append(EINA_INLIST_GET(ie->targets), EINA_INLIST_GET(tg));
    if (!ie->preload)
      {
         ie->cache->preload = eina_list_append(ie->cache->preload, ie);
         ie->flags.pending = 0;
-
         ie->preload = evas_preload_thread_run(_evas_cache_image_async_heavy,
                                               _evas_cache_image_async_end,
                                               _evas_cache_image_async_cancel,
                                               ie);
      }
-
    return 1;
 }
 
@@ -581,7 +484,9 @@ _evas_cache_image_entry_preload_remove(Image_Entry *ie, const void *target)
             if (tg->target == target)
               {
                  // FIXME: No callback when we cancel only for one target ?
-                 ie->targets = (Evas_Cache_Target*) eina_inlist_remove(EINA_INLIST_GET(ie->targets), EINA_INLIST_GET(tg));
+                 ie->targets = (Evas_Cache_Target *)
+                     eina_inlist_remove(EINA_INLIST_GET(ie->targets),
+                                        EINA_INLIST_GET(tg));
                  free(tg);
                  break;
               }
@@ -594,19 +499,18 @@ _evas_cache_image_entry_preload_remove(Image_Entry *ie, const void *target)
        while (ie->targets)
          {
             tg = ie->targets;
-
-            ie->targets = (Evas_Cache_Target*) eina_inlist_remove(EINA_INLIST_GET(ie->targets), EINA_INLIST_GET(tg));
+            ie->targets = (Evas_Cache_Target *)
+                eina_inlist_remove(EINA_INLIST_GET(ie->targets),
+                                   EINA_INLIST_GET(tg));
             free(tg);
          }
      }
 
-   if (!ie->targets && ie->preload && !ie->flags.pending)
+   if ((!ie->targets) && (ie->preload) && (!ie->flags.pending))
      {
        ie->cache->preload = eina_list_remove(ie->cache->preload, ie);
        ie->cache->pending = eina_list_append(ie->cache->pending, ie);
-
        ie->flags.pending = 1;
-
        evas_preload_thread_cancel(ie->preload);
      }
 }
@@ -615,23 +519,18 @@ _evas_cache_image_entry_preload_remove(Image_Entry *ie, const void *target)
 EAPI int
 evas_cache_image_usage_get(Evas_Cache_Image *cache)
 {
-   assert(cache != NULL);
-
    return cache->usage;
 }
 
 EAPI int
 evas_cache_image_get(Evas_Cache_Image *cache)
 {
-   assert(cache != NULL);
-
    return cache->limit;
 }
 
 EAPI void
 evas_cache_image_set(Evas_Cache_Image *cache, unsigned int limit)
 {
-   assert(cache != NULL);
 #ifdef EVAS_FRAME_QUEUING
    LKL(cache->lock);
 #endif
@@ -651,42 +550,26 @@ evas_cache_image_set(Evas_Cache_Image *cache, unsigned int limit)
 
 EAPI Evas_Cache_Image *
 evas_cache_image_init(const Evas_Cache_Image_Func *cb)
-{
-   Evas_Cache_Image *new;
-
-   new = malloc(sizeof (Evas_Cache_Image));
-   if (!new) return NULL;
-
-   new->func = *cb;
-
-   new->limit = 0;
-   new->usage = 0;
-
-   new->dirty = NULL;
-   new->lru = NULL;
-   new->lru_nodata = NULL;
-   new->inactiv = eina_hash_string_superfast_new(NULL);
-   new->activ = eina_hash_string_superfast_new(NULL);
-
-   new->references = 1;
-
-   new->preload = NULL;
-   new->pending = NULL;
+{printf("[%s][%d]\n",__FUNCTION__,__LINE__);
+   Evas_Cache_Image *cache;
 
+   cache = calloc(1, sizeof(Evas_Cache_Image));
+   if (!cache) return NULL;
+   cache->func = *cb;
+   cache->inactiv = eina_hash_string_superfast_new(NULL);
+   cache->activ = eina_hash_string_superfast_new(NULL);
+   cache->references = 1;
 #ifdef EVAS_FRAME_QUEUING
-   LKI(new->lock);
+   LKI(cache->lock);
 #endif
-
-   return new;
+   return cache;
 }
 
 static Eina_Bool
 _evas_cache_image_free_cb(__UNUSED__ const Eina_Hash *hash, __UNUSED__ const void *key, void *data, void *fdata)
 {
    Eina_List **delete_list = fdata;
-
    *delete_list = eina_list_prepend(*delete_list, data);
-
    return EINA_TRUE;
 }
 
@@ -696,12 +579,10 @@ evas_cache_image_shutdown(Evas_Cache_Image *cache)
    Eina_List *delete_list;
    Image_Entry  *im;
 
-   assert(cache != NULL);
 #ifdef EVAS_FRAME_QUEUING
    LKL(cache->lock);
 #endif
    cache->references--;
-
    if (cache->references > 0)
      {
 #ifdef EVAS_FRAME_QUEUING
@@ -709,7 +590,6 @@ evas_cache_image_shutdown(Evas_Cache_Image *cache)
 #endif
         return ;
      }
-
 #ifdef BUILD_ASYNC_PRELOAD
    EINA_LIST_FREE(cache->preload, im)
      {
@@ -717,32 +597,26 @@ evas_cache_image_shutdown(Evas_Cache_Image *cache)
        im->flags.delete_me = 1;
        _evas_cache_image_entry_preload_remove(im, NULL);
      }
-
    evas_async_events_process();
 #endif
-
    while (cache->lru)
      {
         im = (Image_Entry *) cache->lru;
         _evas_cache_image_entry_delete(cache, im);
      }
-
    while (cache->lru_nodata)
      {
         im = (Image_Entry *) cache->lru_nodata;
         _evas_cache_image_entry_delete(cache, im);
      }
-
    /* This is mad, I am about to destroy image still alive, but we need to prevent leak. */
    while (cache->dirty)
      {
         im = (Image_Entry *) cache->dirty;
         _evas_cache_image_entry_delete(cache, im);
      }
-
    delete_list = NULL;
    eina_hash_foreach(cache->activ, _evas_cache_image_free_cb, &delete_list);
-
    while (delete_list)
      {
        _evas_cache_image_entry_delete(cache, eina_list_data_get(delete_list));
@@ -754,27 +628,23 @@ evas_cache_image_shutdown(Evas_Cache_Image *cache)
    while (cache->pending)
      {
        evas_async_events_process();
-
        LKL(wakeup);
-       if (cache->pending)
-         pthread_cond_wait(&cond_wakeup, &wakeup);
+       if (cache->pending) pthread_cond_wait(&cond_wakeup, &wakeup);
        LKU(wakeup);
      }
 #endif
-
    eina_hash_free(cache->activ);
    eina_hash_free(cache->inactiv);
-
 #ifdef EVAS_FRAME_QUEUING
    LKU(cache->lock);
    LKD(cache->lock);
 #endif
-
    free(cache);
 }
 
 EAPI Image_Entry *
-evas_cache_image_request(Evas_Cache_Image *cache, const char *file, const char *key, RGBA_Image_Loadopts *lo, int *error)
+evas_cache_image_request(Evas_Cache_Image *cache, const char *file, 
+                         const char *key, RGBA_Image_Loadopts *lo, int *error)
 {
    const char           *ckey = "(null)";
    char                 *hkey;
@@ -787,30 +657,24 @@ evas_cache_image_request(Evas_Cache_Image *cache, const char *file, const char *
    struct stat           st;
    Image_Timestamp       tstamp;
 
-   assert(cache != NULL);
-
    if ((!file) || ((!file) && (!key)))
      {
        *error = EVAS_LOAD_ERROR_GENERIC;
        return NULL;
      }
 
+   /* generate hkey from file+key+load opts */
    file_length = strlen(file);
    key_length = key ? strlen(key) : 6;
-
    size = file_length + key_length + 128;
    hkey = alloca(sizeof (char) * size);
-
    memcpy(hkey, file, file_length);
    size = file_length;
-
    memcpy(hkey + size, "//://", 5);
    size += 5;
-
    if (key) ckey = key;
    memcpy(hkey + size, ckey, key_length);
    size += key_length;
-
    if ((!lo) ||
        (lo &&
         (lo->scale_down_by == 0) &&
@@ -820,56 +684,37 @@ evas_cache_image_request(Evas_Cache_Image *cache, const char *file, const char *
         ))
      {
         lo = &prevent;
-//        if (key)
-//          format = "%s//://%s";
-//        else
-//          format = "%s//://%p";
      }
    else
      {
        memcpy(hkey + size, "//@/", 4);
        size += 4;
-
        size += eina_convert_xtoa(lo->scale_down_by, hkey + size);
-
        hkey[size] = '/';
        size += 1;
-
        size += eina_convert_dtoa(lo->dpi, hkey + size);
-
        hkey[size] = '/';
        size += 1;
-
        size += eina_convert_xtoa(lo->w, hkey + size);
-
        hkey[size] = 'x';
        size += 1;
-
        size += eina_convert_xtoa(lo->h, hkey + size);
-        
        hkey[size] = '/';
        size += 1;
-
        size += eina_convert_xtoa(lo->region.x, hkey + size);
-        
        hkey[size] = '+';
        size += 1;
-        
        size += eina_convert_xtoa(lo->region.y, hkey + size);
-        
        hkey[size] = '.';
        size += 1;
-        
        size += eina_convert_xtoa(lo->region.w, hkey + size);
-        
        hkey[size] = 'x';
        size += 1;
-        
        size += eina_convert_xtoa(lo->region.h, hkey + size);
      }
-
    hkey[size] = '\0';
 
+   /* find image by key in active hash */
 #ifdef EVAS_FRAME_QUEUING
    LKL(cache->lock);
 #endif
@@ -889,12 +734,16 @@ evas_cache_image_request(Evas_Cache_Image *cache, const char *file, const char *
           }
         else if (!_timestamp_compare(&(im->tstamp), &st)) ok = 0;
         if (ok) goto on_ok;
-
-        _evas_cache_image_remove_activ(cache, im);
-       _evas_cache_image_make_dirty(cache, im);
+        /* image we found doesn't match what's on disk (stat info wise)
+         * so dirty the active cache entry so we never find it again. this
+         * also implicitly guarantees that we only have 1 active copy
+         * of an image at a given key. we wither find it and keep re-reffing
+         * it or we dirty it and get it out */
+        _evas_cache_image_dirty_add(im);
         im = NULL;
      }
 
+   /* find image by key in inactive/lru hash */
 #ifdef EVAS_FRAME_QUEUING
    LKL(cache->lock);
 #endif
@@ -920,11 +769,13 @@ evas_cache_image_request(Evas_Cache_Image *cache, const char *file, const char *
 
         if (ok)
           {
-             _evas_cache_image_remove_activ(cache, im);
-             _evas_cache_image_make_activ(cache, im, im->cache_key);
+             /* remove from lru and make it active again */
+             _evas_cache_image_lru_del(im);
+             _evas_cache_image_activ_add(im);
              goto on_ok;
           }
-        _evas_cache_image_make_dirty(cache, im);
+        /* as avtive cache find - if we match in lru and its invalid, dirty */
+        _evas_cache_image_dirty_add(im);
         im = NULL;
      }
    if (stat_failed) goto on_stat_error;
@@ -934,11 +785,10 @@ evas_cache_image_request(Evas_Cache_Image *cache, const char *file, const char *
         if (stat(file, &st) < 0) goto on_stat_error;
      }
    _timestamp_build(&tstamp, &st);
-   im = _evas_cache_image_entry_new(cache, hkey, &tstamp, file, key, lo, error);
+   im = _evas_cache_image_entry_new(cache, hkey, &tstamp, file, key, 
+                                    lo, error);
    if (!im) return NULL;
-
-   if (cache->func.debug)
-     cache->func.debug("request", im);
+   if (cache->func.debug) cache->func.debug("request", im);
 
  on_ok:
    *error = EVAS_LOAD_ERROR_NONE;
@@ -946,12 +796,9 @@ evas_cache_image_request(Evas_Cache_Image *cache, const char *file, const char *
    LKL(im->lock_references);
 #endif
    im->references++;
-   if (im->references > 1 && im->flags.lru_nodata)
-     _evas_cache_image_remove_lru_nodata(cache, im);
 #ifdef EVAS_FRAME_QUEUING
    LKU(im->lock_references);
 #endif
-
    return im;
 
  on_stat_error:
@@ -983,9 +830,6 @@ evas_cache_image_drop(Image_Entry *im)
    Evas_Cache_Image *cache;
    int references;
 
-   assert(im);
-   assert(im->cache);
-
 #ifdef EVAS_FRAME_QUEUING
    LKL(im->lock_references);
 #endif
@@ -1026,9 +870,7 @@ evas_cache_image_drop(Image_Entry *im)
             _evas_cache_image_entry_delete(cache, im);
             return;
          }
-
-        _evas_cache_image_remove_activ(cache, im);
-       _evas_cache_image_make_inactiv(cache, im, im->cache_key);
+        _evas_cache_image_lru_add(im);
        evas_cache_image_flush(cache);
      }
 }
@@ -1039,11 +881,9 @@ evas_cache_image_data_not_needed(Image_Entry *im)
    Evas_Cache_Image *cache;
    int references;
 
-   assert(im);
-   assert(im->cache);
-
+   /* FIXME: no one uses this api... well evas_cache_engine_parent_not_needed()
+    * does, but nothing uses that! */
    cache = im->cache;
-
 #ifdef EVAS_FRAME_QUEUING
    LKL(im->lock_references);
 #endif
@@ -1051,11 +891,9 @@ evas_cache_image_data_not_needed(Image_Entry *im)
 #ifdef EVAS_FRAME_QUEUING
    LKU(im->lock_references);
 #endif
-
    if (references > 1) return ;
-   if (im->flags.dirty || !im->flags.need_data) return ;
-
-   _evas_cache_image_activ_lru_nodata(cache, im);
+   if ((im->flags.dirty) || (!im->flags.need_data)) return;
+   _evas_cache_image_lru_nodata_add(im);
 }
 
 EAPI Image_Entry *
@@ -1065,9 +903,6 @@ evas_cache_image_dirty(Image_Entry *im, unsigned int x, unsigned int y, unsigned
    Evas_Cache_Image *cache;
    int references;
 
-   assert(im);
-   assert(im->cache);
-
    cache = im->cache;
    if (!(im->flags.dirty))
      {
@@ -1078,7 +913,6 @@ evas_cache_image_dirty(Image_Entry *im, unsigned int x, unsigned int y, unsigned
 #ifdef EVAS_FRAME_QUEUING
    LKU(im->lock_references);
 #endif
-
 #ifndef EVAS_CSERVE
 // if ref 1 also copy if using shared cache as its read-only
         if (references == 1) im_dirty = im;
@@ -1092,11 +926,9 @@ evas_cache_image_dirty(Image_Entry *im, unsigned int x, unsigned int y, unsigned
                                             evas_cache_image_pixels(im), 
                                             im->flags.alpha, im->space);
              if (!im_dirty) goto on_error;
-             if (cache->func.debug)
-               cache->func.debug("dirty-src", im);
+             if (cache->func.debug) cache->func.debug("dirty-src", im);
              error = cache->func.dirty(im_dirty, im);
-             if (cache->func.debug)
-               cache->func.debug("dirty-out", im_dirty);
+             if (cache->func.debug) cache->func.debug("dirty-out", im_dirty);
 #ifdef EVAS_FRAME_QUEUING
              LKL(im_dirty->lock_references);
 #endif
@@ -1104,19 +936,14 @@ evas_cache_image_dirty(Image_Entry *im, unsigned int x, unsigned int y, unsigned
 #ifdef EVAS_FRAME_QUEUING
              LKU(im_dirty->lock_references);
 #endif
-
              evas_cache_image_drop(im);
           }
-
-       _evas_cache_image_remove_activ(cache, im_dirty);
-        _evas_cache_image_make_dirty(cache, im_dirty);
+        _evas_cache_image_dirty_add(im_dirty);
      }
 
-   if (cache->func.debug)
-     cache->func.debug("dirty-region", im_dirty);
+   if (cache->func.debug) cache->func.debug("dirty-region", im_dirty);
    if (cache->func.dirty_region)
      cache->func.dirty_region(im_dirty, x, y, w, h);
-
    return im_dirty;
 
  on_error:
@@ -1132,9 +959,6 @@ evas_cache_image_alone(Image_Entry *im)
    Image_Entry *im_dirty = im;
    int references;
 
-   assert(im);
-   assert(im->cache);
-
    cache = im->cache;
 #ifdef EVAS_FRAME_QUEUING
    LKL(im->lock_references);
@@ -1146,27 +970,20 @@ evas_cache_image_alone(Image_Entry *im)
 
    if (references <= 1)
      {
-        if (!(im->flags.dirty))
-          {
-             _evas_cache_image_remove_activ(cache, im);
-             _evas_cache_image_make_dirty(cache, im);
-          }
+        if (!im->flags.dirty) _evas_cache_image_dirty_add(im);
      }
    else
      {
         int error;
 
-        im_dirty = evas_cache_image_copied_data
-          (cache, im->w, im->h, 
+        im_dirty = evas_cache_image_copied_data(cache, im->w, im->h, 
            evas_cache_image_pixels(im), 
            im->flags.alpha, 
            im->space);
         if (!im_dirty) goto on_error;
-        if (cache->func.debug)
-          cache->func.debug("dirty-src", im);
+        if (cache->func.debug) cache->func.debug("dirty-src", im);
         error = cache->func.dirty(im_dirty, im);
-        if (cache->func.debug)
-          cache->func.debug("dirty-out", im_dirty);
+        if (cache->func.debug) cache->func.debug("dirty-out", im_dirty);
 #ifdef EVAS_FRAME_QUEUING
    LKL(im_dirty->lock_references);
 #endif
@@ -1174,10 +991,8 @@ evas_cache_image_alone(Image_Entry *im)
 #ifdef EVAS_FRAME_QUEUING
    LKU(im_dirty->lock_references);
 #endif
-
         evas_cache_image_drop(im);
      }
-
    return im_dirty;
    
    on_error:
@@ -1187,24 +1002,21 @@ evas_cache_image_alone(Image_Entry *im)
 }
 
 EAPI Image_Entry *
-evas_cache_image_copied_data(Evas_Cache_Image *cache, unsigned int w, unsigned int h, DATA32 *image_data, int alpha, int cspace)
+evas_cache_image_copied_data(Evas_Cache_Image *cache, 
+                             unsigned int w, unsigned int h, 
+                             DATA32 *image_data, int alpha, int cspace)
 {
    Image_Entry *im;
 
-   assert(cache);
-
    if ((cspace == EVAS_COLORSPACE_YCBCR422P601_PL) ||
        (cspace == EVAS_COLORSPACE_YCBCR422P709_PL))
      w &= ~0x1;
 
    im = _evas_cache_image_entry_new(cache, NULL, NULL, NULL, NULL, NULL, NULL);
    if (!im) return NULL;
-
    im->space = cspace;
    im->flags.alpha = alpha;
-
    _evas_cache_image_entry_surface_alloc(cache, im, w, h);
-
    if (cache->func.copied_data(im, w, h, image_data, alpha, cspace) != 0)
      {
         _evas_cache_image_entry_delete(cache, im);
@@ -1217,9 +1029,7 @@ evas_cache_image_copied_data(Evas_Cache_Image *cache, unsigned int w, unsigned i
 #ifdef EVAS_FRAME_QUEUING
    LKU(im->lock_references);
 #endif
-
-   if (cache->func.debug)
-     cache->func.debug("copied-data", im);
+   if (cache->func.debug) cache->func.debug("copied-data", im);
    return im;
 }
 
@@ -1228,17 +1038,15 @@ evas_cache_image_data(Evas_Cache_Image *cache, unsigned int w, unsigned int h, D
 {
    Image_Entry *im;
 
-   assert(cache);
-
    if ((cspace == EVAS_COLORSPACE_YCBCR422P601_PL) ||
        (cspace == EVAS_COLORSPACE_YCBCR422P709_PL))
      w &= ~0x1;
 
    im = _evas_cache_image_entry_new(cache, NULL, NULL, NULL, NULL, NULL, NULL);
+   if (!im) return NULL;
    im->w = w;
    im->h = h;
    im->flags.alpha = alpha;
-
    if (cache->func.data(im, w, h, image_data, alpha, cspace) != 0)
      {
         _evas_cache_image_entry_delete(cache, im);
@@ -1251,87 +1059,64 @@ evas_cache_image_data(Evas_Cache_Image *cache, unsigned int w, unsigned int h, D
 #ifdef EVAS_FRAME_QUEUING
    LKU(im->lock_references);
 #endif
-
-   if (cache->func.debug)
-     cache->func.debug("data", im);
+   if (cache->func.debug) cache->func.debug("data", im);
    return im;
 }
 
 EAPI void
 evas_cache_image_surface_alloc(Image_Entry *im, unsigned int w, unsigned int h)
 {
-   Evas_Cache_Image *cache;
-
-   assert(im);
-   assert(im->cache);
-
-   cache = im->cache;
+   Evas_Cache_Image *cache = im->cache;
 
    if ((im->space == EVAS_COLORSPACE_YCBCR422P601_PL) ||
        (im->space == EVAS_COLORSPACE_YCBCR422P709_PL))
      w &= ~0x1;
 
    _evas_cache_image_entry_surface_alloc(cache, im, w, h);
-
-   if (cache->func.debug)
-     cache->func.debug("surface-alloc", im);
+   if (cache->func.debug) cache->func.debug("surface-alloc", im);
 }
 
 EAPI Image_Entry *
 evas_cache_image_size_set(Image_Entry *im, unsigned int w, unsigned int h)
 {
    Evas_Cache_Image *cache;
-   Image_Entry *new;
+   Image_Entry *im2 = NULL;
    int error;
 
-   assert(im);
-   assert(im->cache);
 #ifdef EVAS_FRAME_QUEUING
    LKL(im->lock_references);
 #endif
-   assert(im->references > 0);
 #ifdef EVAS_FRAME_QUEUING
    LKU(im->lock_references);
 #endif
-
    if ((im->space == EVAS_COLORSPACE_YCBCR422P601_PL) ||
        (im->space == EVAS_COLORSPACE_YCBCR422P709_PL))
      w &= ~0x1;
-
-   if ((im->w == w) && (im->h == h))
-     return im;
+   if ((im->w == w) && (im->h == h)) return im;
 
    cache = im->cache;
-
-   new = _evas_cache_image_entry_new(cache, NULL, NULL, NULL, NULL, NULL, &error);
-   if (!new) goto on_error;
-
-   new->flags.alpha = im->flags.alpha;
-   new->space = im->space;
-   new->load_opts = im->load_opts;
-
-   _evas_cache_image_entry_surface_alloc(cache, new, w, h);
-
-   error = cache->func.size_set(new, im, w, h);
+   im2 = _evas_cache_image_entry_new(cache, NULL, NULL, NULL, NULL, NULL, &error);
+   if (!im2) goto on_error;
+
+   im2->flags.alpha = im->flags.alpha;
+   im2->space = im->space;
+   im2->load_opts = im->load_opts;
+   _evas_cache_image_entry_surface_alloc(cache, im2, w, h);
+   error = cache->func.size_set(im2, im, w, h);
    if (error != 0) goto on_error;
-
 #ifdef EVAS_FRAME_QUEUING
-   LKL(new->lock_references);
+   LKL(im2->lock_references);
 #endif
-   new->references = 1;
+   im->references = 1;
 #ifdef EVAS_FRAME_QUEUING
-   LKU(new->lock_references);
+   LKU(im2->lock_references);
 #endif
-
-   evas_cache_image_drop(im);
-
-   if (cache->func.debug)
-     cache->func.debug("size_set", new);
-
-   return new;
+   _evas_cache_image_dirty_add(im);
+   if (cache->func.debug) cache->func.debug("size_set", im2);
+   return im2;
 
  on_error:
-   if (new) _evas_cache_image_entry_delete(cache, new);
+   if (im2) _evas_cache_image_entry_delete(cache, im2);
    evas_cache_image_drop(im);
    return NULL;
 }
@@ -1342,39 +1127,27 @@ evas_cache_image_load_data(Image_Entry *im)
 #ifdef BUILD_ASYNC_PRELOAD
    Eina_Bool preload = EINA_FALSE;
 #endif
-   Evas_Cache_Image *cache;
    int error;
 
-   assert(im);
-   assert(im->cache);
-   cache = im->cache;
-
    if (im->flags.loaded) return;
-
 #ifdef BUILD_ASYNC_PRELOAD
    if (im->preload)
      {
        preload = EINA_TRUE;
-
        if (!im->flags.pending)
          {
             im->cache->preload = eina_list_remove(im->cache->preload, im);
             im->cache->pending = eina_list_append(im->cache->pending, im);
             im->flags.pending = 1;
-
             evas_preload_thread_cancel(im->preload);
          }
-
        evas_async_events_process();
-
        LKL(wakeup);
        while (im->preload)
          {
             pthread_cond_wait(&cond_wakeup, &wakeup);
             LKU(wakeup);
-
             evas_async_events_process();
-
             LKL(wakeup);
          }
        LKU(wakeup);
@@ -1383,45 +1156,29 @@ evas_cache_image_load_data(Image_Entry *im)
    if (im->flags.loaded) return ;
    LKL(im->lock);
 #endif
-
    im->flags.in_progress = EINA_TRUE;
-   error = cache->func.load(im);
+   error = im->cache->func.load(im);
    im->flags.in_progress = EINA_FALSE;
-
 #ifdef BUILD_ASYNC_PRELOAD
    LKU(im->lock);
 #endif
-
    im->flags.loaded = 1;
-
-   if (cache->func.debug)
-     cache->func.debug("load", im);
-
+   if (im->cache->func.debug) im->cache->func.debug("load", im);
    if (error != EVAS_LOAD_ERROR_NONE)
      {
-        _evas_cache_image_entry_surface_alloc(cache, im, im->w, im->h);
+        _evas_cache_image_entry_surface_alloc(im->cache, im, im->w, im->h);
         im->flags.loaded = 0;
      }
-
 #ifdef BUILD_ASYNC_PRELOAD
-   if (preload)
-     _evas_cache_image_async_end(im);
+   if (preload) _evas_cache_image_async_end(im);
 #endif
 }
 
 EAPI void
 evas_cache_image_unload_data(Image_Entry *im)
 {
-   Evas_Cache_Image *cache;
-
-   assert(im);
-   assert(im->cache);
-   cache = im->cache;
-
    if (im->flags.in_progress) return;
-
    evas_cache_image_preload_cancel(im, NULL);
-
 #ifdef BUILD_ASYNC_PRELOAD
    LKL(im->lock_cancel);
    if (LKT(im->lock) != 0) /* can't get image lock - busy async load */
@@ -1431,18 +1188,16 @@ evas_cache_image_unload_data(Image_Entry *im)
         return;
      }
    LKU(im->lock_cancel);
-//   LKL(im->lock);
 #endif
-   if ((!im->flags.loaded) || (!im->file) ||
-       (!im->info.module) || (im->flags.dirty))
+   if ((!im->flags.loaded) || (!im->file) || (!im->info.module) || 
+       (im->flags.dirty))
      {
 #ifdef BUILD_ASYNC_PRELOAD
         LKU(im->lock);
 #endif
        return;
      }
-   cache->func.destructor(im);
-
+   im->cache->func.destructor(im);
 #ifdef BUILD_ASYNC_PRELOAD
    LKU(im->lock);
 #endif
@@ -1470,7 +1225,6 @@ evas_cache_image_unload_all(Evas_Cache_Image *cache)
 EAPI Eina_Bool
 evas_cache_image_is_loaded(Image_Entry *im)
 {
-  assert(im); 
   if (im->flags.loaded) return EINA_TRUE;
   return EINA_FALSE;
 }
@@ -1481,20 +1235,14 @@ evas_cache_image_preload_data(Image_Entry *im, const void *target)
 #ifdef BUILD_ASYNC_PRELOAD
    RGBA_Image *img = (RGBA_Image *)im;
    
-   assert(im);
-   assert(im->cache);
-
    if ((im->flags.loaded) && (img->image.data))
      {
        evas_object_inform_call_image_preloaded((Evas_Object *)target);
        return;
      }
    im->flags.loaded = 0;
-
    if (!_evas_cache_image_entry_preload_add(im, target))
-     {
         evas_object_inform_call_image_preloaded((Evas_Object *)target);
-     }
 #else
    evas_cache_image_load_data(im);
    evas_object_inform_call_image_preloaded((Evas_Object *)target);
@@ -1505,9 +1253,6 @@ EAPI void
 evas_cache_image_preload_cancel(Image_Entry *im, const void *target)
 {
 #ifdef BUILD_ASYNC_PRELOAD
-   assert(im);
-   assert(im->cache);
-
    if (!target) return;
    _evas_cache_image_entry_preload_remove(im, target);
 #else
@@ -1515,12 +1260,55 @@ evas_cache_image_preload_cancel(Image_Entry *im, const void *target)
 #endif
 }
 
+#ifdef CACHEDUMP
+static int total = 0;
+
+static void
+_dump_img(Image_Entry *im, const char *type)
+{
+   total += im->cache->func.mem_size_get(im);
+   printf("%s: %4i: %4ib, %4ix%4i alloc[%4ix%4i] [%s] [%s]\n",
+          type,
+          im->references,
+          im->cache->func.mem_size_get(im),
+          im->w, im->h, im->allocated.w, im->allocated.h,
+          im->file, im->key);
+}
+
+static Eina_Bool
+_dump_cache_active(__UNUSED__ const Eina_Hash *hash, __UNUSED__ const void *key, void *data, void *fdata __UNUSED__)
+{
+   Image_Entry *im = data;
+   _dump_img(im, "ACTIVE");
+   return EINA_TRUE;
+}
+
+static void
+_dump_cache(Evas_Cache_Image *cache)
+{
+   Image_Entry *im;
+   
+   printf("--CACHE DUMP----------------------------------------------------\n");
+   printf("cache: %ikb / %ikb\n",
+          cache->usage / 1024,
+          cache->limit / 1024);
+   printf("................................................................\n");
+   total = 0;
+   EINA_INLIST_FOREACH(cache->lru_nodata, im)
+      _dump_img(im, "NODATA");
+   EINA_INLIST_FOREACH(cache->lru, im)
+      _dump_img(im, "DATA  ");
+   printf("tot: %i\n"
+          "usg: %i\n",
+          total,
+          cache->usage);
+   eina_hash_foreach(cache->activ, _dump_cache_active, NULL);
+}
+#endif
+
 EAPI int
 evas_cache_image_flush(Evas_Cache_Image *cache)
 {
-   assert(cache);
-   assert(cache->usage >= 0);
-
 #ifdef CACHEDUMP
   _dump_cache(cache);
 #endif  
@@ -1539,10 +1327,8 @@ evas_cache_image_flush(Evas_Cache_Image *cache)
         Image_Entry *im;
 
         im = (Image_Entry *) cache->lru_nodata->last;
-        _evas_cache_image_remove_lru_nodata(cache, im);
-
+        _evas_cache_image_lru_nodata_del(im);
         cache->func.surface_delete(im);
-
         im->flags.loaded = 0;
      }
 
@@ -1556,7 +1342,6 @@ evas_cache_image_empty(Evas_Cache_Image *cache)
 
    im = _evas_cache_image_entry_new(cache, NULL, NULL, NULL, NULL, NULL, NULL);
    if (!im) return NULL;
-
 #ifdef EVAS_FRAME_QUEUING
    LKL(im->lock_references);
 #endif
@@ -1570,59 +1355,33 @@ evas_cache_image_empty(Evas_Cache_Image *cache)
 EAPI void
 evas_cache_image_colorspace(Image_Entry *im, int cspace)
 {
-   Evas_Cache_Image *cache;
-
-   assert(im);
-   assert(im->cache);
-
-   cache = im->cache;
-
    if (im->space == cspace) return;
-
    im->space = cspace;
-   cache->func.color_space(im, cspace);
+   im->cache->func.color_space(im, cspace);
 }
 
 EAPI void *
 evas_cache_private_from_image_entry_get(Image_Entry *im)
 {
-   Evas_Cache_Image *cache;
-
-   assert(im);
-   assert(im->cache);
-
-   cache = im->cache;
-
-   return (void*) cache->data;
+   return (void *)im->cache->data;
 }
 
 EAPI void *
 evas_cache_private_get(Evas_Cache_Image *cache)
 {
-   assert(cache);
-
    return cache->data;
 }
 
 EAPI void
 evas_cache_private_set(Evas_Cache_Image *cache, const void *data)
 {
-   assert(cache);
-
    cache->data = (void *)data;
 }
 
 EAPI DATA32 *
 evas_cache_image_pixels(Image_Entry *im)
 {
-   Evas_Cache_Image *cache;
-
-   assert(im);
-   assert(im->cache);
-
-   cache = im->cache;
-
-   return cache->func.surface_pixels(im);
+   return im->cache->func.surface_pixels(im);
 }
 
 EAPI void
index 9287185..2e76f7c 100644 (file)
@@ -172,6 +172,20 @@ _evas_common_rgba_image_delete(Image_Entry *ie)
 #ifdef EVAS_CSERVE
    if (ie->data1) evas_cserve_image_free(ie);
 #endif   
+/*
+ * FIXME: This doesn't seem to be needed... But I'm not sure why.
+ *      -- nash
+     {
+        Filtered_Image *fi;
+        
+        EINA_LIST_FREE(im->filtered, fi)
+          {
+             free(fi->key);
+             _evas_common_rgba_image_delete((Image_Entry *)(fi->image));
+             free(fi);
+          }
+     }
+*/
    free(im);
 }
 
@@ -355,11 +369,12 @@ static int
 _evas_common_rgba_image_ram_usage(Image_Entry *ie)
 {
    RGBA_Image   *im = (RGBA_Image *) ie;
-   int size = 0;
+   int size = sizeof(struct _RGBA_Image);
+   
+   if (ie->cache_key) size += strlen(ie->cache_key);
+   if (ie->file) size += strlen(ie->file);
+   if (ie->key) size += strlen(ie->key);
 
-//   ram += sizeof(struct _RGBA_Image);
-//   if (im->info.real_file) ram += strlen(im->info.real_file);
-//   if (im->info.comment) ram += strlen(im->info.comment);
    if (im->image.data)
      {
 #ifdef EVAS_CSERVE
index eb5e9c7..08f91f2 100644 (file)
@@ -527,10 +527,13 @@ struct _Image_Entry_Flags
    Eina_Bool in_progress  : 1;
    Eina_Bool dirty        : 1;
    Eina_Bool activ        : 1;
+   
    Eina_Bool need_data    : 1;
    Eina_Bool lru_nodata   : 1;
    Eina_Bool cached       : 1;
    Eina_Bool alpha        : 1;
+   
+   Eina_Bool lru          : 1;
    Eina_Bool alpha_sparse : 1;
 #ifdef BUILD_ASYNC_PRELOAD
    Eina_Bool preload_done : 1;