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
[email protected]
https://lists.sourceforge.net/lists/listinfo/enlightenment-cvs