Enlightenment CVS committal

Author  : raster
Project : e17
Module  : libs/evas

Dir     : e17/libs/evas/src/lib/cache


Modified Files:
        evas_cache_engine_image.c evas_cache_image.c 


Log Message:


cedric's cache changes patch

===================================================================
RCS file: /cvs/e/e17/libs/evas/src/lib/cache/evas_cache_engine_image.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -3 -r1.5 -r1.6
--- evas_cache_engine_image.c   14 Mar 2008 16:49:47 -0000      1.5
+++ evas_cache_engine_image.c   12 Apr 2008 00:32:25 -0000      1.6
@@ -3,6 +3,144 @@
 #include "evas_common.h"
 #include "evas_private.h"
 
+static void
+_evas_cache_engine_image_make_dirty(Evas_Cache_Engine_Image *cache,
+                                    Engine_Image_Entry *eim)
+{
+   eim->flags.cached = 1;
+   eim->flags.dirty = 1;
+   eim->flags.loaded = 1;
+   eim->flags.activ = 0;
+   cache->dirty = evas_object_list_prepend(cache->dirty, eim);
+}
+
+static void
+_evas_cache_engine_image_make_active(Evas_Cache_Engine_Image *cache,
+                                     Engine_Image_Entry *eim,
+                                     const char *key)
+{
+   eim->flags.cached = 1;
+   eim->flags.activ = 1;
+   eim->flags.dirty = 0;
+   cache->activ = evas_hash_add(cache->activ, key, eim);
+}
+
+static void
+_evas_cache_engine_image_make_inactive(Evas_Cache_Engine_Image *cache,
+                                       Engine_Image_Entry *eim,
+                                       const char *key)
+{
+   eim->flags.cached = 1;
+   eim->flags.dirty = 0;
+   eim->flags.activ = 0;
+   cache->inactiv = evas_hash_add(cache->inactiv, key, eim);
+   cache->lru = evas_object_list_prepend(cache->lru, eim);
+   cache->usage += cache->func.mem_size_get(eim);
+}
+
+static void
+_evas_cache_engine_image_remove_activ(Evas_Cache_Engine_Image *cache,
+                                      Engine_Image_Entry *eim)
+{
+   if (eim->flags.cached)
+     {
+        if (eim->flags.dirty)
+          {
+             cache->dirty = evas_object_list_remove(cache->dirty, eim);
+          }
+        else
+          if (eim->flags.activ)
+            {
+               cache->activ = evas_hash_del(cache->activ, eim->cache_key, eim);
+            }
+          else
+            {
+               cache->usage -= cache->func.mem_size_get(eim);
+               cache->inactiv = evas_hash_del(cache->inactiv, eim->cache_key, 
eim);
+               cache->lru = evas_object_list_remove(cache->lru, eim);
+            }
+        eim->flags.cached = 0;
+        eim->flags.dirty = 0;
+        eim->flags.activ = 0;
+     }
+}
+
+static Engine_Image_Entry *
+_evas_cache_engine_image_alloc(Evas_Cache_Engine_Image *cache,
+                               Image_Entry *ie,
+                               const char *hkey)
+{
+   Engine_Image_Entry   *eim;
+
+   assert(cache);
+
+   if (cache->func.alloc)
+     eim = cache->func.alloc();
+   else
+     eim = malloc(sizeof (Engine_Image_Entry));
+
+   if (!eim) goto on_error;
+   memset(eim, 0, sizeof (Engine_Image_Entry));
+
+   eim->cache = cache;
+   if (ie)
+     {
+        eim->w = ie->w;
+        eim->h = ie->h;
+        eim->src = ie;
+        eim->flags.need_parent = 1;
+     }
+   else
+     {
+        eim->w = -1;
+        eim->h = -1;
+        eim->flags.need_parent = 0;
+        eim->src = NULL;
+     }
+
+   eim->flags.cached = 0;
+   eim->references = 0;
+   eim->cache_key = hkey;
+
+   if (hkey)
+     _evas_cache_engine_image_make_active(cache, eim, hkey);
+   else
+     _evas_cache_engine_image_make_dirty(cache, eim);
+
+   return eim;
+
+ on_error:
+   if (eim)
+     evas_cache_engine_image_drop(eim);
+   evas_stringshare_del(hkey);
+   evas_cache_image_drop(ie);
+   return NULL;
+}
+
+static void
+_evas_cache_engine_image_dealloc(Evas_Cache_Engine_Image *cache, 
Engine_Image_Entry *eim)
+{
+   Image_Entry   *im;
+
+   if (cache->func.debug) cache->func.debug("delete", eim);
+
+   _evas_cache_engine_image_remove_activ(cache, eim);
+
+   im = eim->src;
+   cache->func.destructor(eim);
+   if (im) evas_cache_image_drop(im);
+
+   if (cache->func.delete)
+     {
+        cache->func.delete(eim);
+     }
+   else
+     {
+        memset(eim, 0, sizeof (Engine_Image_Entry));
+        free(eim);
+     }
+}
+
 EAPI int
 evas_cache_engine_image_usage_get(Evas_Cache_Engine_Image *cache)
 {
@@ -42,11 +180,57 @@
    new->usage = 0;
 
    new->dirty = NULL;
+   new->lru = NULL;
    new->activ = NULL;
+   new->inactiv = NULL;
 
    new->parent = parent;
    parent->references++;
 
+   new->brother = NULL;
+
+   return new;
+}
+
+EAPI Evas_Cache_Engine_Image *
+evas_cache_engine_image_dup(const Evas_Cache_Engine_Image_Func *cb, 
Evas_Cache_Engine_Image *brother)
+{
+   Evas_Cache_Engine_Image     *new;
+
+   new = malloc(sizeof (Evas_Cache_Engine_Image));
+   if (!new)
+     return NULL;
+
+   new->func = brother->func;
+
+#define ORD(Func) if (cb->Func) new->func.Func = cb->Func;
+
+   ORD(key);
+   ORD(constructor);
+   ORD(destructor);
+   ORD(dirty_region);
+   ORD(dirty);
+   ORD(size_set);
+   ORD(update_data);
+   ORD(load);
+   ORD(mem_size_get);
+   ORD(debug);
+
+#undef ORD
+
+   new->limit = -1;
+   new->usage = 0;
+   new->references = 1;
+
+   new->dirty = NULL;
+   new->activ = NULL;
+
+   new->parent = brother->parent;
+   new->parent->references++;
+
+   new->brother = brother;
+   brother->references++;
+
    return new;
 }
 
@@ -54,130 +238,126 @@
 _evas_cache_engine_image_free_cb(const Evas_Hash *hash, const char *key, void 
*data, void *fdata)
 {
    Evas_Cache_Engine_Image     *cache = fdata;
-   RGBA_Engine_Image           *eim = data;
-   RGBA_Image                  *im;
+   Engine_Image_Entry           *eim = data;
 
-   if (cache->func.debug)
-     cache->func.debug("shutdown-engine-activ", eim);
+   _evas_cache_engine_image_dealloc(cache, eim);
 
-   evas_stringshare_del(eim->cache_key);
-   eim->cache_key = NULL;
+   return 1;
+}
 
-   im = eim->src;
-   cache->func.destructor(eim);
-   if (im) evas_cache_image_drop(im);
-   free(eim);
+EAPI void
+evas_cache_engine_image_flush(Evas_Cache_Engine_Image *cache)
+{
+   assert(cache != NULL);
 
-   return 1;
+   while ((cache->lru) && (cache->limit < cache->usage))
+     {
+        Engine_Image_Entry      *eim;
+
+        eim = (Engine_Image_Entry *) cache->lru->last;
+        _evas_cache_engine_image_dealloc(cache, eim);
+     }
 }
 
 EAPI void
 evas_cache_engine_image_shutdown(Evas_Cache_Engine_Image *cache)
 {
-   RGBA_Engine_Image   *eim;
-   RGBA_Image          *im;
+   Engine_Image_Entry   *eim;
 
    assert(cache != NULL);
 
+   if (cache->func.debug) cache->func.debug("shutdown-engine", NULL);
+
+   evas_hash_foreach(cache->inactiv, _evas_cache_engine_image_free_cb, cache);
+   evas_hash_free(cache->inactiv);
+
    /* This is mad, I am about to destroy image still alive, but we need to 
prevent leak. */
    while (cache->dirty)
      {
-        eim = (RGBA_Engine_Image *) cache->dirty;
-        im = eim->src;
-
-        cache->dirty = evas_object_list_remove(cache->dirty, eim);
-
-        if (cache->func.debug)
-          cache->func.debug("shutdown-engine-dirty", eim);
-        cache->func.destructor(eim);
-        if (im) evas_cache_image_drop(im);
-        free(eim);
+        eim = (Engine_Image_Entry *) cache->dirty;
+        _evas_cache_engine_image_dealloc(cache, eim);
      }
 
    evas_hash_foreach(cache->activ, _evas_cache_engine_image_free_cb, cache);
    evas_hash_free(cache->activ);
+
+   evas_cache_image_shutdown(cache->parent);
+   if (cache->brother)
+     evas_cache_engine_image_shutdown(cache->brother);
+   free(cache);
 }
 
-EAPI RGBA_Engine_Image *
-evas_cache_engine_image_request(Evas_Cache_Engine_Image *cache, const char 
*file, const char *key,
+EAPI Engine_Image_Entry *
+evas_cache_engine_image_request(Evas_Cache_Engine_Image *cache,
+                                const char *file, const char *key,
                                 RGBA_Image_Loadopts *lo, void *data, int 
*error)
 {
-   RGBA_Engine_Image   *eim;
-   RGBA_Image          *im;
+   Engine_Image_Entry   *eim;
+   Image_Entry          *im;
    const char          *ekey;
 
    assert(cache != NULL);
 
+   *error = -1;
+
+   ekey = NULL;
+   eim = NULL;
+
    im = evas_cache_image_request(cache->parent, file, key, lo, error);
    if (!im)
-     {
-        *error = -1;
-        return NULL;
-     }
+     goto on_error;
 
    if (cache->func.key)
      ekey = cache->func.key(im, file, key, lo, data);
    else
      ekey = evas_stringshare_add(im->cache_key);
    if (!ekey)
+     goto on_error;
+
+   eim = evas_hash_find(cache->activ, ekey);
+   if (eim)
      {
-        *error = -1;
         evas_cache_image_drop(im);
-        return NULL;
+        goto on_ok;
      }
 
-   eim = evas_hash_find(cache->activ, ekey);
-   if (eim) goto on_ok;
-
-   eim = malloc(sizeof(RGBA_Engine_Image));
-   if (!eim) goto on_error;
+   eim = evas_hash_find(cache->inactiv, ekey);
+   if (eim)
+     {
+        _evas_cache_engine_image_remove_activ(cache, eim);
+        _evas_cache_engine_image_make_active(cache, eim, ekey);
+        evas_cache_image_drop(im);
+        goto on_ok;
+     }
 
-   eim->src = im;
-   eim->engine_data = NULL;
-   eim->flags.dirty = 0;
-   eim->flags.loaded = 0;
-   eim->cache = cache;
-   eim->cache_key = ekey;
-   eim->references = 0;
+   eim = _evas_cache_engine_image_alloc(cache, im, ekey);
+   if (!eim) return NULL;
 
    *error = cache->func.constructor(eim, data);
+   if (*error != 0) goto on_error;
    if (cache->func.debug)
      cache->func.debug("constructor-engine", eim);
 
-   if (*error != 0) goto on_error;
-
-   cache->activ = evas_hash_add(cache->activ, ekey, eim);
-   cache->usage += strlen(eim->cache_key) + 1 + cache->func.mem_size_get(eim);
-
   on_ok:
    eim->references++;
    return eim;
 
   on_error:
-   evas_cache_image_drop(im);
-   evas_stringshare_del(ekey);
-   if (eim) free(eim);
-   return NULL;
-}
-
-static void
-_evas_cache_engine_image_free(Evas_Cache_Engine_Image *cache, 
RGBA_Engine_Image *eim)
-{
-   int                     size;
-
-   size = cache->func.mem_size_get(eim);
-   cache->usage -= size;
+   if (!eim)
+     {
+        if (im) evas_cache_image_drop(im);
+        if (ekey) evas_stringshare_del(ekey);
+     }
+   else
+     {
+        _evas_cache_engine_image_dealloc(cache, eim);
+     }
 
-   if (cache->func.debug)
-     cache->func.debug("drop-engine", eim);
-   cache->func.destructor(eim);
-   if (eim->src) evas_cache_image_drop(eim->src);
-   if (eim->cache_key) evas_stringshare_del(eim->cache_key);
-   free(eim);
+   return NULL;
 }
 
 EAPI void
-evas_cache_engine_image_drop(RGBA_Engine_Image *eim)
+evas_cache_engine_image_drop(Engine_Image_Entry *eim)
 {
    Evas_Cache_Engine_Image     *cache;
 
@@ -189,28 +369,27 @@
 
    if (eim->flags.dirty)
      {
-        cache->dirty = evas_object_list_remove(cache->dirty, eim);
-
-        _evas_cache_engine_image_free(cache, eim);
+        _evas_cache_engine_image_dealloc(cache, eim);
         return ;
      }
 
    if (eim->references == 0)
      {
-        cache->activ = evas_hash_del(cache->activ, eim->cache_key, eim);
-
-        _evas_cache_engine_image_free(cache, eim);
+        _evas_cache_engine_image_remove_activ(cache, eim);
+        _evas_cache_engine_image_make_inactive(cache, eim, eim->cache_key);
+        evas_cache_engine_image_flush(cache);
         return ;
      }
 }
 
-EAPI RGBA_Engine_Image *
-evas_cache_engine_image_dirty(RGBA_Engine_Image *eim, int x, int y, int w, int 
h)
+EAPI Engine_Image_Entry *
+evas_cache_engine_image_dirty(Engine_Image_Entry *eim, int x, int y, int w, 
int h)
 {
-   RGBA_Engine_Image           *eim_dirty = eim;
-   RGBA_Image                  *im;
-   RGBA_Image                  *im_dirty;
-   Evas_Cache_Engine_Image     *cache;
+   Engine_Image_Entry           *eim_dirty = eim;
+   Image_Entry                  *im_dirty = NULL;
+   Image_Entry                  *im;
+   Evas_Cache_Engine_Image      *cache;
+   unsigned char                 alloc_eim;
 
    assert(eim);
    assert(eim->cache);
@@ -218,56 +397,56 @@
    cache = eim->cache;
    if (!(eim->flags.dirty))
      {
-        im = eim->src;
-        im_dirty = evas_cache_image_dirty(im, x, y, w, h);
+        alloc_eim = 0;
 
-        /* If im == im_dirty, this meens that we have only one reference to 
the eim. */
-        if (im != im_dirty)
+        if (eim->flags.need_parent == 1)
           {
-             if (eim->references == 1)
-               {
-                  const char   *hkey;
-
-                  hkey = eim->cache_key;
-                  cache->activ = evas_hash_del(cache->activ, hkey, eim);
+             im = eim->src;
+             im_dirty = evas_cache_image_dirty(im, x, y, w, h);
 
-                  cache->usage -= strlen(hkey) + 1;
-
-                  evas_stringshare_del(hkey);
-
-                  eim_dirty = eim;
-                  eim_dirty->src = im_dirty;
-               }
-             else
+             /* If im == im_dirty, this meens that we have only one reference 
to the eim. */
+             if (im != im_dirty)
                {
-                  int           error;
-
-                  eim_dirty = malloc(sizeof(RGBA_Engine_Image));
-                  if (!eim_dirty) goto on_error;
-
-                  eim_dirty->src = im_dirty;
-                  eim_dirty->engine_data = NULL;
-                  eim_dirty->flags.dirty = 1;
-                  eim_dirty->flags.loaded = 1;
-                  eim_dirty->cache = cache;
-                  eim_dirty->cache_key = NULL;
-                  eim_dirty->references = 1;
+                  if (eim->references == 1)
+                    {
+                       _evas_cache_engine_image_remove_activ(cache, eim);
+                       _evas_cache_engine_image_make_dirty(cache, eim);
+
+                       eim->src = im_dirty;
+                    }
+                  else
+                    alloc_eim = 1;
+               }
+          }
+        else
+          if (eim->references > 1)
+            {
+               alloc_eim = 1;
+            }
+          else
+            {
+               _evas_cache_engine_image_remove_activ(cache, eim_dirty);
+               _evas_cache_engine_image_make_dirty(cache, eim_dirty);
+            }
 
-                  error = cache->func.dirty(eim_dirty, eim);
-                  if (cache->func.debug)
-                    cache->func.debug("dirty-engine", eim_dirty);
+        if (alloc_eim == 1)
+          {
+             int           error;
 
-                  if (error != 0) goto on_error;
+             eim_dirty = _evas_cache_engine_image_alloc(cache, im_dirty, NULL);
+             if (!eim_dirty) goto on_error;
 
-                  cache->usage += cache->func.mem_size_get(eim_dirty);
+             eim_dirty->w = eim->w;
+             eim_dirty->h = eim->h;
+             eim_dirty->references = 1;
 
-                  evas_cache_engine_image_drop(eim);
-               }
+             error = cache->func.dirty(eim_dirty, eim);
+             if (cache->func.debug)
+               cache->func.debug("dirty-engine", eim_dirty);
 
-             eim_dirty->cache_key = NULL;
-             eim_dirty->flags.dirty = 1;
+             if (error != 0) goto on_error;
 
-             cache->dirty = evas_object_list_prepend(cache->dirty, eim_dirty);
+             evas_cache_engine_image_drop(eim);
           }
      }
 
@@ -280,7 +459,7 @@
 
   on_error:
    if (eim) evas_cache_engine_image_drop(eim);
-   if (eim_dirty)
+   if (eim_dirty && eim_dirty != eim)
      evas_cache_engine_image_drop(eim_dirty);
    else
      if (im_dirty) evas_cache_image_drop(im_dirty);
@@ -288,21 +467,43 @@
    return NULL;
 }
 
-static RGBA_Engine_Image *
-_evas_cache_engine_image_push_dirty(Evas_Cache_Engine_Image *cache, RGBA_Image 
*im, void *engine_data)
+EAPI Engine_Image_Entry *
+evas_cache_engine_image_alone(Engine_Image_Entry *eim, void *data)
+{
+   Evas_Cache_Engine_Image      *cache;
+   Image_Entry                  *im;
+
+
+   assert(eim);
+   assert(eim->cache);
+
+   cache = eim->cache;
+   im = evas_cache_image_alone(eim->src);
+   if (im != eim->src)
+     {
+        eim = _evas_cache_engine_image_alloc(cache, im, NULL);
+        if (!eim) goto on_error;
+
+        eim->references = 1;
+
+        if (cache->func.constructor(eim, data)) goto on_error;
+     }
+   /* FIXME */
+   return eim;
+
+ on_error:
+   evas_cache_image_drop(im);
+   return NULL;
+}
+
+static Engine_Image_Entry *
+_evas_cache_engine_image_push_dirty(Evas_Cache_Engine_Image *cache, 
Image_Entry *im, void *engine_data)
 {
-   RGBA_Engine_Image    *eim;
+   Engine_Image_Entry    *eim;
    int                  error;
 
-   eim = malloc(sizeof(RGBA_Engine_Image));
+   eim = _evas_cache_engine_image_alloc(cache, im, NULL);
    if (!eim) goto on_error;
-
-   eim->src = im;
-   eim->engine_data = NULL;
-   eim->flags.dirty = 1;
-   eim->flags.loaded = 1;
-   eim->cache = cache;
-   eim->cache_key = NULL;
    eim->references = 1;
 
    error = cache->func.update_data(eim, engine_data);
@@ -310,22 +511,18 @@
      cache->func.debug("dirty-update_data-engine", eim);
    if (error != 0) goto on_error;
 
-   cache->dirty = evas_object_list_prepend(cache->dirty, eim);
-
    return eim;
 
   on_error:
    if (eim)
      evas_cache_engine_image_drop(eim);
-   else
-     evas_cache_image_drop(im);
    return NULL;
 }
 
-EAPI RGBA_Engine_Image *
+EAPI Engine_Image_Entry *
 evas_cache_engine_image_copied_data(Evas_Cache_Engine_Image *cache, int w, int 
h, DATA32 *image_data, int alpha, int cspace, void *engine_data)
 {
-   RGBA_Image           *im;
+   Image_Entry           *im;
 
    assert(cache);
 
@@ -334,10 +531,10 @@
    return _evas_cache_engine_image_push_dirty(cache, im, engine_data);
 }
 
-EAPI RGBA_Engine_Image *
+EAPI Engine_Image_Entry *
 evas_cache_engine_image_data(Evas_Cache_Engine_Image *cache, int w, int h, 
DATA32 *image_data, int alpha, int cspace, void *engine_data)
 {
-   RGBA_Image           *im;
+   Image_Entry           *im;
 
    assert(cache);
 
@@ -346,64 +543,48 @@
    return _evas_cache_engine_image_push_dirty(cache, im, engine_data);
 }
 
-EAPI RGBA_Engine_Image *
-evas_cache_engine_image_size_set(RGBA_Engine_Image *eim, int w, int h)
+EAPI Engine_Image_Entry *
+evas_cache_engine_image_size_set(Engine_Image_Entry *eim, int w, int h)
 {
-   Evas_Cache_Engine_Image     *cache;
-   RGBA_Engine_Image           *new;
-   RGBA_Image                  *im;
-   int                          error;
+   Evas_Cache_Engine_Image      *cache;
+   Engine_Image_Entry           *new;
+   Image_Entry                  *im;
+   const char                   *hkey;
+   int                           error;
 
    assert(eim);
-   assert(eim->src);
    assert(eim->cache);
    assert(eim->references > 0);
 
-   if (eim->src->image->w == w
-       && eim->src->image->h == h)
-     return eim;
-
+   im = NULL;
    cache = eim->cache;
 
-   im = evas_cache_image_size_set(eim->src, w, h);
-   /* Good idea to call update_data ? */
-   if (im == eim->src) return eim;
-   eim->src = NULL;
+   if (eim->flags.need_parent == 1)
+     {
+        assert(eim->src);
+
+        if (eim->src->w == w
+            && eim->src->h == h)
+          return eim;
+
+        im = evas_cache_image_size_set(eim->src, w, h);
+        /* FIXME: Good idea to call update_data ? */
+        if (im == eim->src) return eim;
+        eim->src = NULL;
+     }
+
+   hkey = (eim->references > 1 ) ? evas_stringshare_add(eim->cache_key) : NULL;
 
-   new = malloc(sizeof(RGBA_Engine_Image));
+   new = _evas_cache_engine_image_alloc(cache, im, hkey);
    if (!new) goto on_error;
 
-   new->src = im;
-   new->engine_data = NULL;
-   new->flags = eim->flags;
-   new->flags.loaded = 1;
-   new->cache = cache;
-   new->cache_key = NULL;
+   new->w = w;
+   new->h = h;
    new->references = 1;
 
    error = cache->func.size_set(new, eim);
    if (error) goto on_error;
 
-   assert(new->engine_data != eim->engine_data);
-
-   cache->usage += cache->func.mem_size_get(new);
-
-   if (new->flags.dirty || eim->references > 1)
-     {
-        new->flags.dirty = 1;
-        cache->dirty = evas_object_list_prepend(cache->dirty, new);
-     }
-   else
-     {
-        const char *cache_key = NULL;
-
-        cache_key = eim->cache_key ? evas_stringshare_add(eim->cache_key) : 
NULL;
-        new->cache_key = cache_key;
-
-        cache->activ = evas_hash_add(cache->activ, cache_key, new);
-        cache->usage += strlen(new->cache_key) + 1;
-     }
-
    evas_cache_engine_image_drop(eim);
    return new;
 
@@ -419,10 +600,10 @@
 }
 
 EAPI void
-evas_cache_engine_image_load_data(RGBA_Engine_Image *eim)
+evas_cache_engine_image_load_data(Engine_Image_Entry *eim)
 {
    Evas_Cache_Engine_Image     *cache;
-   int                          size;
+   int                          size = 0;
 
    assert(eim);
    assert(eim->src);
@@ -430,37 +611,35 @@
 
    if (eim->flags.loaded) return ;
 
-   evas_cache_image_load_data(eim->src);
+   if (eim->src)
+     evas_cache_image_load_data(eim->src);
 
    cache = eim->cache;
    if (cache->func.debug)
      cache->func.debug("load-engine", eim);
 
-   size = cache->func.mem_size_get(eim);
+   if (eim->flags.dirty)
+     size = cache->func.mem_size_get(eim);
    cache = eim->cache;
    cache->func.load(eim, eim->src);
-   cache->usage += cache->func.mem_size_get(eim) - size;
+   if (eim->flags.dirty)
+     cache->usage += cache->func.mem_size_get(eim) - size;
 
    eim->flags.loaded = 1;
 }
 
-EAPI RGBA_Engine_Image *
+EAPI Engine_Image_Entry *
 evas_cache_engine_image_engine(Evas_Cache_Engine_Image *cache, void 
*engine_data)
 {
-   RGBA_Engine_Image   *eim;
-   int                  error;
+   Engine_Image_Entry   *eim;
+   Image_Entry          *ie;
+   int                   error;
 
-   eim = malloc(sizeof(RGBA_Engine_Image));
-   if (!eim) goto on_error;
-
-   eim->src = evas_cache_image_empty(cache->parent);
-   if (!eim->src) goto on_error;
+   ie = evas_cache_image_empty(cache->parent);
+   if (!ie) return NULL;
 
-   eim->engine_data = NULL;
-   eim->flags.dirty = 1;
-   eim->flags.loaded = 1;
-   eim->cache = cache;
-   eim->cache_key = NULL;
+   eim = _evas_cache_engine_image_alloc(cache, ie, NULL);
+   if (!eim) goto on_error;
    eim->references = 1;
 
    error = cache->func.update_data(eim, engine_data);
@@ -469,18 +648,23 @@
 
    if (error != 0) goto on_error;
 
-   cache->dirty = evas_object_list_prepend(cache->dirty, eim);
-
    return eim;
 
   on_error:
-   if (eim)
-     evas_cache_engine_image_drop(eim);
+   if (!eim)
+     {
+        if (ie)
+          evas_cache_image_drop(ie);
+     }
+   else
+     {
+        evas_cache_engine_image_drop(eim);
+     }
    return NULL;
 }
 
 EAPI void
-evas_cache_engine_image_colorspace(RGBA_Engine_Image *eim, int cspace, void 
*engine_data)
+evas_cache_engine_image_colorspace(Engine_Image_Entry *eim, int cspace, void 
*engine_data)
 {
    Evas_Cache_Engine_Image     *cache = eim->cache;
 
@@ -493,3 +677,12 @@
      cache->func.debug("cosntructor-colorspace-engine", eim);
 }
 
+EAPI void
+evas_cache_engine_parent_not_needed(Engine_Image_Entry *eim)
+{
+   assert(eim);
+   assert(eim->cache);
+
+   eim->flags.need_parent = 0;
+   evas_cache_image_data_not_needed(eim->src);
+}
===================================================================
RCS file: /cvs/e/e17/libs/evas/src/lib/cache/evas_cache_image.c,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -3 -r1.13 -r1.14
--- evas_cache_image.c  14 Mar 2008 16:49:47 -0000      1.13
+++ evas_cache_image.c  12 Apr 2008 00:32:25 -0000      1.14
@@ -4,6 +4,221 @@
 #include "evas_common.h"
 #include "evas_private.h"
 
+#define FREESTRC(Var)              \
+  if (Var)                         \
+    {                              \
+       evas_stringshare_del(Var);  \
+       Var = NULL;                 \
+    }
+
+static void
+_evas_cache_image_make_dirty(Evas_Cache_Image *cache,
+                             Image_Entry *im)
+{
+   im->flags.cached = 1;
+   im->flags.dirty = 1;
+   im->flags.activ = 0;
+   im->flags.lru_nodata = 0;
+   cache->dirty = evas_object_list_prepend(cache->dirty, im);
+
+   if (im->cache_key)
+     {
+        evas_stringshare_del(im->cache_key);
+        im->cache_key = NULL;
+     }
+}
+
+static void
+_evas_cache_image_make_activ(Evas_Cache_Image *cache,
+                             Image_Entry *im,
+                             const char *key)
+{
+   im->cache_key = key;
+   if (key != NULL)
+     {
+        im->flags.cached = 1;
+        im->flags.activ = 1;
+        im->flags.lru_nodata = 0;
+        im->flags.dirty = 0;
+        cache->activ = evas_hash_direct_add(cache->activ, key, im);
+     }
+   else
+     {
+        _evas_cache_image_make_dirty(cache, im);
+     }
+}
+
+static void
+_evas_cache_image_make_inactiv(Evas_Cache_Image *cache,
+                               Image_Entry *im,
+                               const char *key)
+{
+   im->flags.activ = 0;
+   im->flags.dirty = 0;
+   im->flags.cached = 1;
+   cache->inactiv = evas_hash_direct_add(cache->inactiv, key, im);
+   cache->lru = evas_object_list_prepend(cache->lru, im);
+   cache->usage += cache->func.mem_size_get(im);
+}
+
+static void
+_evas_cache_image_remove_lru_nodata(Evas_Cache_Image *cache,
+                                    Image_Entry *im)
+{
+   if (im->flags.lru_nodata)
+     {
+        im->flags.lru_nodata = 0;
+        cache->lru_nodata = evas_object_list_remove(cache->lru_nodata, im);
+        cache->usage -= cache->func.mem_size_get(im);
+     }
+}
+
+static void
+_evas_cache_image_activ_lru_nodata(Evas_Cache_Image *cache,
+                                   Image_Entry *im)
+{
+   im->flags.need_data = 0;
+   im->flags.lru_nodata = 1;
+   cache->lru_nodata = evas_object_list_prepend(cache->lru_nodata, im);
+   cache->usage += cache->func.mem_size_get(im);
+}
+
+static void
+_evas_cache_image_remove_activ(Evas_Cache_Image *cache,
+                               Image_Entry *ie)
+{
+   if (ie->flags.cached)
+     {
+        if (ie->flags.activ)
+          {
+             cache->activ = evas_hash_del(cache->activ, ie->cache_key, ie);
+             _evas_cache_image_remove_lru_nodata(cache, ie);
+          }
+        else
+          {
+             if (ie->flags.dirty)
+               {
+                  cache->dirty = evas_object_list_remove(cache->dirty, ie);
+               }
+             else
+               {
+                  cache->inactiv = evas_hash_del(cache->inactiv, 
ie->cache_key, ie);
+                  cache->lru = evas_object_list_remove(cache->lru, ie);
+                  cache->usage -= cache->func.mem_size_get(ie);
+               }
+          }
+        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);
+
+   cache->func.destructor(ie);
+
+   _evas_cache_image_remove_activ(cache, ie);
+
+   if (ie->cache_key)
+     {
+        evas_stringshare_del(ie->cache_key);
+        ie->cache_key = NULL;
+     }
+
+   FREESTRC(ie->file);
+   FREESTRC(ie->key);
+
+   cache->func.surface_delete(ie);
+   cache->func.delete(ie);
+}
+
+static Image_Entry *
+_evas_cache_image_entry_new(Evas_Cache_Image *cache,
+                            const char *hkey,
+                            time_t timestamp,
+                            const char *file,
+                            const char *key,
+                            RGBA_Image_Loadopts *lo,
+                            int *error)
+{
+   Image_Entry  *ie;
+   const char   *cache_key;
+
+   ie = cache->func.alloc();
+   if (!ie)
+     return NULL;
+
+   cache_key = hkey ? evas_stringshare_add(hkey) : NULL;
+
+   ie->flags.loaded = 0;
+   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->references = 0;
+   ie->cache = cache;
+
+   ie->file = file ? evas_stringshare_add(file) : NULL;
+   ie->key = key ? evas_stringshare_add(key) : NULL;
+
+   ie->timestamp = timestamp;
+   ie->laststat = time(NULL);
+
+   ie->load_opts.scale_down_by = 0;
+   ie->load_opts.dpi = 0;
+   ie->load_opts.w = 0;
+   ie->load_opts.h = 0;
+   ie->scale = 1;
+
+   if (lo)
+     ie->load_opts = *lo;
+
+   ie->references = 0;
+   if (file)
+     {
+        *error = cache->func.constructor(ie);
+        if (*error != 0)
+          {
+             _evas_cache_image_entry_delete(cache, ie);
+             return NULL;
+          }
+     }
+   if (cache->func.debug)
+     cache->func.debug("build", ie);
+
+   return ie;
+}
+
+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;
+   if (cache->func.surface_alloc(ie, wmin, hmin))
+     {
+        wmin = 0;
+        hmin = 0;
+     }
+   ie->w = wmin;
+   ie->h = hmin;
+}
+
 EAPI int
 evas_cache_image_usage_get(Evas_Cache_Image *cache)
 {
@@ -45,6 +260,7 @@
 
    new->dirty = NULL;
    new->lru = NULL;
+   new->lru_nodata = NULL;
    new->inactiv = NULL;
    new->activ = NULL;
 
@@ -57,26 +273,17 @@
 _evas_cache_image_free_cb(const Evas_Hash *hash, const char *key, void *data, 
void *fdata)
 {
    Evas_Cache_Image    *cache = fdata;
-   RGBA_Image          *im = data;
-
-   if (cache->func.debug)
-     cache->func.debug("shutdown-activ", im);
+   Image_Entry         *im = data;
 
-   if (im->cache_key)
-     {
-       evas_stringshare_del(im->cache_key);
-       im->cache_key = NULL;
-     }
+   _evas_cache_image_entry_delete(cache, im);
 
-   cache->func.destructor(im);
-   evas_common_image_delete(im);
    return 1;
 }
 
 EAPI void
 evas_cache_image_shutdown(Evas_Cache_Image *cache)
 {
-   RGBA_Image  *im;
+   Image_Entry  *im;
 
    assert(cache != NULL);
    cache->references--;
@@ -86,31 +293,21 @@
 
    while (cache->lru)
      {
-        im = (RGBA_Image *) cache->lru;
-        cache->lru = evas_object_list_remove(cache->lru, im);
-
-       if (im->cache_key)
-         {
-            evas_stringshare_del(im->cache_key);
-            im->cache_key = NULL;
-         }
+        im = (Image_Entry *) cache->lru;
+        _evas_cache_image_entry_delete(cache, im);
+     }
 
-        if (cache->func.debug)
-          cache->func.debug("shutdown-lru", im);
-        cache->func.destructor(im);
-        evas_common_image_delete(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 = (RGBA_Image *) cache->dirty;
-        cache->dirty = evas_object_list_remove(cache->dirty, im);
-
-        if (cache->func.debug)
-          cache->func.debug("shutdown-dirty", im);
-        cache->func.destructor(im);
-        evas_common_image_delete(im);
+        im = (Image_Entry *) cache->dirty;
+        _evas_cache_image_entry_delete(cache, im);
      }
 
    evas_hash_foreach(cache->activ, _evas_cache_image_free_cb, cache);
@@ -120,14 +317,17 @@
    free(cache);
 }
 
-EAPI RGBA_Image *
+#define STAT_GAP 2
+
+EAPI Image_Entry *
 evas_cache_image_request(Evas_Cache_Image *cache, const char *file, const char 
*key, RGBA_Image_Loadopts *lo, int *error)
 {
    const char           *format;
    char                 *hkey;
-   RGBA_Image           *im;
+   Image_Entry          *im;
    Evas_Image_Load_Opts  prevent;
    int                   size;
+   int                   stat_done = 0;
    struct stat           st;
 
    assert(cache != NULL);
@@ -157,106 +357,86 @@
    hkey = alloca(sizeof (char) * size);
    snprintf(hkey, size, format, file, key, lo->scale_down_by, lo->dpi, lo->w, 
lo->h);
 
-   if (stat(file, &st) < 0)
-     {
-       im = evas_hash_find(cache->inactiv, hkey);
-       if (im)
-         {
-            cache->lru = evas_object_list_remove(cache->lru, im);
-            cache->inactiv = evas_hash_del(cache->inactiv, im->cache_key, im);
-//          printf("IMG %p %ix%i %s SUB %i\n",
-//                 im, im->image->w, im->image->h, im->cache_key,
-//                 cache->func.mem_size_get(im));
-            cache->usage -= cache->func.mem_size_get(im);
-            if (im->cache_key)
-              {
-                 evas_stringshare_del(im->cache_key);
-                 im->cache_key = NULL;
-              }
-            cache->func.destructor(im);
-            evas_common_image_delete(im);
-         }
-       return NULL;
-     }
-
    im = evas_hash_find(cache->activ, hkey);
    if (im)
      {
-       if (st.st_mtime == im->timestamp)
-         goto on_ok;
+        time_t  t;
+        int     ok;
+
+        ok = 1;
+        t = time(NULL);
+
+        if ((t - im->laststat) > STAT_GAP)
+          {
+             stat_done = 1;
+             if (stat(file, &st) < 0) goto on_error;
+
+             im->laststat = t;
+             if (st.st_mtime != im->timestamp) ok = 0;
+          }
+        if (ok) goto on_ok;
      }
 
    im = evas_hash_find(cache->inactiv, hkey);
    if (im)
      {
-       if (st.st_mtime == im->timestamp)
-         {
-            cache->lru = evas_object_list_remove(cache->lru, im);
-            cache->inactiv = evas_hash_del(cache->inactiv, im->cache_key, im);
-            cache->activ = evas_hash_direct_add(cache->activ, im->cache_key, 
im);
-//          printf("IMG %p %ix%i %s SUB %i\n",
-//                 im, im->image->w, im->image->h, im->cache_key,
-//                 cache->func.mem_size_get(im));
-            cache->usage -= cache->func.mem_size_get(im);
-            goto on_ok;
-         }
-       else
-         {
-            cache->lru = evas_object_list_remove(cache->lru, im);
-            cache->inactiv = evas_hash_del(cache->inactiv, im->cache_key, im);
-//          printf("IMG %p %ix%i %s SUB %i\n",
-//                 im, im->image->w, im->image->h, im->cache_key,
-//                 cache->func.mem_size_get(im));
-            cache->usage -= cache->func.mem_size_get(im);
-            if (im->cache_key)
-              {
-                 evas_stringshare_del(im->cache_key);
-                 im->cache_key = NULL;
-              }
-            cache->func.destructor(im);
-            evas_common_image_delete(im);
-         }
-     }
+        int     ok;
 
-   im = evas_common_image_new();
-   if (!im)
-     {
-        *error = -1;
-        return NULL;
-     }
+        ok = 1;
+        if (!stat_done)
+          {
+             time_t  t;
 
-   im->timestamp = st.st_mtime;
-   im->laststat = time(NULL);
+             t = time(NULL);
+             if ((t - im->laststat) > STAT_GAP)
+               {
+                  stat_done = 1;
+                  if (stat(file, &st) < 0) goto on_error;
+
+                  im->laststat = t;
+                  if (st.st_mtime != im->timestamp) ok = 0;
+               }
+          }
+        else
+          if (st.st_mtime != im->timestamp) ok = 0;
 
-   if (lo) im->load_opts = *lo;
+        if (ok)
+          {
+             _evas_cache_image_remove_activ(cache, im);
+             _evas_cache_image_make_activ(cache, im, im->cache_key);
+             goto on_ok;
+          }
 
-   im->info.file = (char *) evas_stringshare_add(file);
-   if (key) im->info.key = (char *) evas_stringshare_add(key);
+        _evas_cache_image_entry_delete(cache, im);
+     }
 
-   *error = cache->func.constructor(im);
-   if (*error != 0)
+   if (!stat_done)
      {
-        evas_common_image_delete(im);
-        return NULL;
+        if (stat(file, &st) < 0) return NULL;
      }
 
+   im = _evas_cache_image_entry_new(cache, hkey, st.st_mtime, file, key, lo, 
error);
+   if (!im)
+     return NULL;
+
    if (cache->func.debug)
      cache->func.debug("request", im);
 
-   im->references = 0;
-   im->cache_key = evas_stringshare_add(hkey);
-   im->cache = cache;
-   
-   cache->activ = evas_hash_direct_add(cache->activ, im->cache_key, im);
-   
-   on_ok:
+ on_ok:
    *error = 0;
    im->references++;
+   if (im->references > 1 && im->flags.lru_nodata)
+     _evas_cache_image_remove_lru_nodata(cache, im);
+
    return im;
+
+ on_error:
+   _evas_cache_image_entry_delete(cache, im);
+   return NULL;
 }
 
 EAPI void
-evas_cache_image_drop(RGBA_Image *im)
+evas_cache_image_drop(Image_Entry *im)
 {
    Evas_Cache_Image    *cache;
 
@@ -266,72 +446,59 @@
    im->references--;
    cache = im->cache;
 
-//   if (im->cache_key) printf("DROP %s -> ref = %i\n", im->cache_key, 
im->references);
-   if ((im->flags & RGBA_IMAGE_IS_DIRTY) == RGBA_IMAGE_IS_DIRTY)
+   if (im->flags.dirty)
      {
-//     printf("IMG %p %ix%i %s SUB %i\n",
-//            im, im->image->w, im->image->h, im->cache_key,
-//            cache->func.mem_size_get(im));
-//// don't decrement cache usage - unless we remove from the lru       
-//        cache->usage -= cache->func.mem_size_get(im);
-//     if (im->cache_key) printf("IM-- %s, cache = %i\n", im->cache_key, 
cache->usage);
-        cache->dirty = evas_object_list_remove(cache->dirty, im);
-        if (cache->func.debug)
-          cache->func.debug("drop", im);
-
-        cache->func.destructor(im);
-        evas_common_image_delete(im);
-
+        _evas_cache_image_entry_delete(cache, im);
         return ;
      }
 
    if (im->references == 0)
      {
-        cache->activ = evas_hash_del(cache->activ, im->cache_key, im);
-        cache->inactiv = evas_hash_direct_add(cache->inactiv, im->cache_key, 
im);
-        cache->lru = evas_object_list_prepend(cache->lru, im);
-
-//     printf("IMG %p %ix%i %s ADD %i\n",
-//            im, im->image->w, im->image->h, im->cache_key,
-//            cache->func.mem_size_get(im));
-       cache->usage += cache->func.mem_size_get(im);
-//     printf("FLUSH!\n");
+        _evas_cache_image_remove_activ(cache, im);
+        _evas_cache_image_make_inactiv(cache, im, im->cache_key);
        evas_cache_image_flush(cache);
      }
 }
 
-EAPI RGBA_Image *
-evas_cache_image_dirty(RGBA_Image *im, int x, int y, int w, int h)
+EAPI void
+evas_cache_image_data_not_needed(Image_Entry *im)
 {
-   RGBA_Image          *im_dirty = im;
    Evas_Cache_Image    *cache;
 
    assert(im);
    assert(im->cache);
 
    cache = im->cache;
-   if (!(im->flags & RGBA_IMAGE_IS_DIRTY))
+
+   if (im->references > 1) return ;
+   if (im->flags.dirty || !im->flags.need_data) return ;
+
+   _evas_cache_image_activ_lru_nodata(cache, im);
+}
+
+EAPI Image_Entry *
+evas_cache_image_dirty(Image_Entry *im, int x, int y, int w, int h)
+{
+   Image_Entry          *im_dirty = im;
+   Evas_Cache_Image     *cache;
+
+   assert(im);
+   assert(im->cache);
+
+   cache = im->cache;
+   if (!(im->flags.dirty))
      {
         if (im->references == 1)
           {
-            if (im->cache_key)
-              {
-                 cache->activ = evas_hash_del(cache->activ, im->cache_key, im);
-                 evas_stringshare_del(im->cache_key);
-                 im->cache_key = NULL;
-              }
+             _evas_cache_image_remove_activ(cache, im);
              im_dirty = im;
           }
         else
           {
              int        error;
 
-             im_dirty = evas_common_image_new();
+             im_dirty = _evas_cache_image_entry_new(cache, NULL, 
im->timestamp, im->file, im->key, &im->load_opts, &error);
              if (!im_dirty) goto on_error;
-             im_dirty->image = evas_common_image_surface_new(im);
-             if (!im_dirty->image) goto on_error;
-             im_dirty->image->w = w;
-             im_dirty->image->h = h;
 
              if (cache->func.debug)
                cache->func.debug("dirty-src", im);
@@ -341,34 +508,32 @@
 
              if (error != 0) goto on_error;
 
-             im_dirty->cache = cache;
              im_dirty->references = 1;
 
              evas_cache_image_drop(im);
           }
 
-        im_dirty->flags |= RGBA_IMAGE_IS_DIRTY;
-        cache->dirty = evas_object_list_prepend(cache->dirty, im_dirty);
+        _evas_cache_image_make_dirty(cache, 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:
-   if (im_dirty) evas_common_image_delete(im_dirty);
+
+ on_error:
+   if (im_dirty) _evas_cache_image_entry_delete(cache, im_dirty);
    evas_cache_image_drop(im);
    return NULL;
 }
 
-EAPI RGBA_Image *
-evas_cache_image_alone(RGBA_Image *im)
+EAPI Image_Entry *
+evas_cache_image_alone(Image_Entry *im)
 {
-   RGBA_Image          *im_dirty = im;
-   Evas_Cache_Image    *cache;
+   Evas_Cache_Image     *cache;
+   Image_Entry          *im_dirty = im;
 
    assert(im);
    assert(im->cache);
@@ -376,28 +541,18 @@
    cache = im->cache;
    if (im->references == 1)
      {
-        if (!(im->flags & RGBA_IMAGE_IS_DIRTY))
+        if (!(im->flags.dirty))
           {
-             if (im->cache_key)
-              {
-                 cache->activ = evas_hash_del(cache->activ, im->cache_key, im);
-                 evas_stringshare_del(im->cache_key);
-                 im->cache_key = NULL;
-              }
-             im->flags |= RGBA_IMAGE_IS_DIRTY;
-             cache->dirty = evas_object_list_prepend(cache->dirty, im);
+             _evas_cache_image_remove_activ(cache, im);
+             _evas_cache_image_make_dirty(cache, im);
           }
      }
    else
      {
         int     error;
 
-        im_dirty = evas_common_image_new();
+        im_dirty = _evas_cache_image_entry_new(cache, NULL, im->timestamp, 
im->file, im->key, &im->load_opts, &error);
         if (!im_dirty) goto on_error;
-        im_dirty->image = evas_common_image_surface_new(im);
-        if (!im_dirty->image) goto on_error;
-        im_dirty->image->w = im->image->w;
-        im_dirty->image->h = im->image->h;
 
         if (cache->func.debug)
           cache->func.debug("dirty-src", im);
@@ -407,46 +562,23 @@
 
         if (error != 0) goto on_error;
 
-       if (im_dirty->cache_key)
-         {
-            evas_stringshare_del(im_dirty->cache_key);
-            im_dirty->cache_key = NULL;
-         }
-        im_dirty->flags |= RGBA_IMAGE_IS_DIRTY;
         im_dirty->references = 1;
 
-        cache->dirty = evas_object_list_prepend(cache->dirty, im_dirty);
-
         evas_cache_image_drop(im);
      }
 
    return im_dirty;
    
    on_error:
-   if (im_dirty) evas_common_image_delete(im_dirty);
+   if (im_dirty) _evas_cache_image_entry_delete(cache, im_dirty);
    evas_cache_image_drop(im);
    return NULL;
 }
 
-static RGBA_Image *
-_evas_cache_image_push_dirty(Evas_Cache_Image *cache, RGBA_Image *im)
-{
-   cache->dirty = evas_object_list_prepend(cache->dirty, im);
-
-   im->flags |= RGBA_IMAGE_IS_DIRTY;
-   if (im->cache_key)
-     {
-       evas_stringshare_del(im->cache_key);
-       im->cache_key = NULL;
-     }
-   im->cache = cache;
-   return im;
-}
-
-EAPI RGBA_Image *
+EAPI Image_Entry *
 evas_cache_image_copied_data(Evas_Cache_Image *cache, int w, int h, DATA32 
*image_data, int alpha, int cspace)
 {
-   RGBA_Image  *im;
+   Image_Entry  *im;
 
    assert(cache);
 
@@ -454,122 +586,132 @@
        (cspace == EVAS_COLORSPACE_YCBCR422P709_PL))
      w &= ~0x1;
 
-   im = evas_common_image_create(w, h);
+   im = _evas_cache_image_entry_new(cache, NULL, 0, NULL, NULL, NULL, NULL);
    if (!im) return NULL;
+   im->space = cspace;
+
+   _evas_cache_image_entry_surface_alloc(cache, im, w, h);
 
    if (cache->func.copied_data(im, w, h, image_data, alpha, cspace) != 0)
      {
-        evas_common_image_delete(im);
+        _evas_cache_image_entry_delete(cache, im);
         return NULL;
      }
+   im->references = 1;
 
-   return _evas_cache_image_push_dirty(cache, im);
+   if (cache->func.debug)
+     cache->func.debug("copied-data", im);
+   return im;
 }
 
-EAPI RGBA_Image *
+EAPI Image_Entry *
 evas_cache_image_data(Evas_Cache_Image *cache, int w, int h, DATA32 
*image_data, int alpha, int cspace)
 {
-   RGBA_Image  *im;
+   Image_Entry  *im;
 
    assert(cache);
 
-   im = evas_common_image_new();
-   if (!im) return NULL;
-   im->image = evas_common_image_surface_new(im);
-   if (!im->image)
-     {
-        evas_common_image_delete(im);
-        return NULL;
-     }
+   im = _evas_cache_image_entry_new(cache, NULL, 0, NULL, NULL, NULL, NULL);
+   im->w = w;
+   im->h = h;
 
    if (cache->func.data(im, w, h, image_data, alpha, cspace) != 0)
      {
-        evas_common_image_delete(im);
+        _evas_cache_image_entry_delete(cache, im);
         return NULL;
      }
+   im->references = 1;
+
+   if (cache->func.debug)
+     cache->func.debug("data", im);
+   return im;
+}
+
+EAPI void
+evas_cache_image_surface_alloc(Image_Entry *im, int w, int h)
+{
+   Evas_Cache_Image     *cache;
 
-   return _evas_cache_image_push_dirty(cache, im);
+   assert(im);
+   assert(im->cache);
+
+   cache = im->cache;
+
+   _evas_cache_image_entry_surface_alloc(cache, im, w, h);
+
+   if (cache->func.debug)
+     cache->func.debug("surface-alloc", im);
 }
 
-EAPI RGBA_Image *
-evas_cache_image_size_set(RGBA_Image *im, int w, int h)
+EAPI Image_Entry *
+evas_cache_image_size_set(Image_Entry *im, int w, int h)
 {
    Evas_Cache_Image    *cache;
-   RGBA_Image          *new;
+   Image_Entry         *new;
    int                  error;
 
    assert(im);
-   assert(im->image);
    assert(im->cache);
    assert(im->references > 0);
 
-   if ((im->image->w == w) && (im->image->h == h))
+   if ((im->w == w) && (im->h == h))
      return im;
 
    cache = im->cache;
 
-   new = evas_common_image_new();
+   new = _evas_cache_image_entry_new(cache, NULL, 0, NULL, NULL, NULL, &error);
    if (!new) goto on_error;
-   new->image = evas_common_image_surface_new(im);
-   if (!new->image) goto on_error;
-   new->image->w = w;
-   new->image->h = h;
 
-   if (cache->func.debug)
-     cache->func.debug("size_set-in", im);
-   error = cache->func.size_set(new, im, w, h);
-   if (cache->func.debug)
-     cache->func.debug("size_set-out", new);
+   _evas_cache_image_entry_surface_alloc(cache, new, w, h);
 
-   if (error != 0) goto on_error;
+   new->space = im->space;
+   new->load_opts = im->load_opts;
 
-   new->cache = cache;
-   new->cache_key = NULL;
+   error = cache->func.size_set(new, im, w, h);
+   if (error != 0) goto on_error;
 
    new->references = 1;
-//   cache->usage += cache->func.mem_size_get(new);
-
-   if (((im->flags & RGBA_IMAGE_IS_DIRTY) == RGBA_IMAGE_IS_DIRTY)
-       || (im->references > 1))
-     {
-        new->flags |= RGBA_IMAGE_IS_DIRTY;
-        cache->dirty = evas_object_list_prepend(cache->dirty, new);
-     }
-   else
-     {
-        new->cache_key = im->cache_key ? evas_stringshare_add(im->cache_key) : 
NULL;
-        cache->activ = evas_hash_direct_add(cache->activ, new->cache_key, new);
-     }
 
    evas_cache_image_drop(im);
-   
+
+   if (cache->func.debug)
+     cache->func.debug("size_set", new);
+
    return new;
-   
-   on_error:
-   if (new) evas_common_image_delete(new);
+
+ on_error:
+   if (new) _evas_cache_image_entry_delete(cache, new);
    evas_cache_image_drop(im);
    return NULL;
 }
 
 EAPI void
-evas_cache_image_load_data(RGBA_Image *im)
+evas_cache_image_load_data(Image_Entry *im)
 {
    Evas_Cache_Image    *cache;
+   int                  error;
 
    assert(im);
-   assert(im->image);
    assert(im->cache);
 
-   if ((im->flags & RGBA_IMAGE_LOADED) == RGBA_IMAGE_LOADED) return ;
-   
+   if (im->flags.loaded) return ;
+
    cache = im->cache;
+
+   error = cache->func.load(im);
+
    if (cache->func.debug)
      cache->func.debug("load", im);
 
-   cache->func.load(im);
-   im->flags |= RGBA_IMAGE_LOADED;
+   if (error)
+     {
+        _evas_cache_image_entry_surface_alloc(cache, im, im->w, im->h);
+        im->flags.loaded = 0;
+
+        return ;
+     }
 
-   assert(im->image->data);
+   im->flags.loaded = 1;
 }
 
 EAPI int
@@ -583,58 +725,53 @@
 
    while ((cache->lru) && (cache->limit < cache->usage))
      {
-        RGBA_Image     *im;
+        Image_Entry     *im;
 
-        im = (RGBA_Image *) cache->lru->last;
-        cache->lru = evas_object_list_remove(cache->lru, im);
-        cache->inactiv = evas_hash_del(cache->inactiv, im->cache_key, im);
-//     printf("IMG %p %ix%i %s SUB %i\n",
-//            im, im->image->w, im->image->h, im->cache_key,
-//            cache->func.mem_size_get(im));
-        cache->usage -= cache->func.mem_size_get(im);
+        im = (Image_Entry *) cache->lru->last;
+        _evas_cache_image_entry_delete(cache, im);
+     }
+
+   while ((cache->lru_nodata) && (cache->limit < cache->usage))
+     {
+        Image_Entry     *im;
+
+        im = (Image_Entry *) cache->lru_nodata->last;
+        _evas_cache_image_remove_lru_nodata(cache, im);
+
+        cache->func.surface_delete(im);
 
-       if (im->cache_key)
-         {
-            evas_stringshare_del(im->cache_key);
-            im->cache_key = NULL;
-         }
-//     printf("DEL IMG FROM CACHE\n");
-        cache->func.destructor(im);
-        evas_common_image_delete(im);
+        im->flags.loaded = 0;
      }
+
    return cache->usage;
 }
 
-EAPI RGBA_Image *
+EAPI Image_Entry *
 evas_cache_image_empty(Evas_Cache_Image *cache)
 {
-   RGBA_Image  *new;
+   Image_Entry  *new;
 
-   new = evas_common_image_new();
-   if (!new) goto on_error;
-   new->image = evas_common_image_surface_new(new);
-   if (!new->image) goto on_error;
+   new = _evas_cache_image_entry_new(cache, NULL, 0, NULL, NULL, NULL, NULL);
+   if (!new) return NULL;
 
-   new->cache = cache;
    new->references = 1;
 
-   new->cache_key = NULL;
-   new->flags |= RGBA_IMAGE_IS_DIRTY;
-
-   cache->dirty = evas_object_list_prepend(cache->dirty, new);
-
    return new;
-
-  on_error:
-   if (new) evas_common_image_delete(new);
-   return NULL;
 }
 
 EAPI void
-evas_cache_image_colorspace(RGBA_Image *im, int cspace)
+evas_cache_image_colorspace(Image_Entry *im, int cspace)
 {
+   Evas_Cache_Image    *cache;
+
+   assert(im);
+   assert(im->cache);
+
+   cache = im->cache;
+
    if (!im) return ;
-   if (im->cs.space == cspace) return ;
+   if (im->space == cspace) return ;
 
-   evas_common_image_colorspace_set(im, cspace);
+   im->space = cspace;
+   cache->func.color_space(im, cspace);
 }



-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference 
Don't miss this year's exciting event. There's still time to save $100. 
Use priority code J8TL2D2. 
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone
_______________________________________________
enlightenment-cvs mailing list
enlightenment-cvs@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/enlightenment-cvs

Reply via email to