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