From cc2e84d5d62bcb87d84c6517420b0e34024cd649 Mon Sep 17 00:00:00 2001 From: raster Date: Thu, 21 Apr 2011 06:24:27 +0000 Subject: [PATCH] fix some nasty image cache issues i've found like double-frees, leaks etc. etc. in corner-cases. it also re-factors the image cache code to be much more manageable and understandable with cache/list management doing the right thing in the internal calls. git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/evas@58779 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33 --- src/lib/cache/evas_cache_image.c | 859 ++++++++++++++------------------------- src/lib/include/evas_common.h | 3 + 2 files changed, 314 insertions(+), 548 deletions(-) diff --git a/src/lib/cache/evas_cache_image.c b/src/lib/cache/evas_cache_image.c index 662a579..e8e83dc 100644 --- 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 @@ -37,70 +39,38 @@ static pthread_cond_t cond_wakeup = PTHREAD_COND_INITIALIZER; static void _evas_cache_image_entry_preload_remove(Image_Entry *ie, const void *target); #endif -#define FREESTRC(Var) \ - if (Var) \ - { \ - 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 +#define FREESTRC(Var) \ + if (Var) \ + { \ + eina_stringshare_del(Var); \ + Var = NULL; \ + } -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) { - im->flags.cached = 1; + if (im->flags.dirty) return; + _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); @@ -109,165 +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. */ - im->cache_key = key; - if (key) - { - im->flags.cached = 1; - im->flags.activ = 1; - im->flags.lru_nodata = 0; - im->flags.dirty = 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 - { - _evas_cache_image_make_dirty(cache, im); - } } static void -_evas_cache_image_make_inactiv(Evas_Cache_Image *cache, - Image_Entry *im, const char *key) +_evas_cache_image_activ_add(Image_Entry *im) { - if (im->cache_key) - { - im->flags.activ = 0; - im->flags.dirty = 0; - im->flags.cached = 1; + 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(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_direct_add(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_activ_del(Image_Entry *im) { - if (im->flags.lru_nodata) - { - im->flags.lru_nodata = 0; + if (!im->flags.activ) return; + if (!im->cache_key) return; + im->flags.activ = 0; + im->flags.cached = 0; #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_del(im->cache->activ, im->cache_key, 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_add(Image_Entry *im) { - im->flags.need_data = 0; - im->flags.lru_nodata = 1; + 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_prepend(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_remove_activ(Evas_Cache_Image *cache, Image_Entry *ie) +_evas_cache_image_lru_del(Image_Entry *im) { - if (ie->flags.cached) - { - if (ie->flags.activ) - { + 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 - eina_hash_del(cache->activ, ie->cache_key, ie); + 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 - _evas_cache_image_remove_lru_nodata(cache, ie); - } - else - { +} + +static void +_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 - 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_prepend(im->cache->lru_nodata, EINA_INLIST_GET(im)); #ifdef EVAS_FRAME_QUEUING - LKU(cache->lock); + LKU(im->cache->lock); +#endif +} + +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(im->cache->lock); +#endif + im->cache->lru_nodata = eina_inlist_remove(im->cache->lru_nodata, EINA_INLIST_GET(im)); +#ifdef EVAS_FRAME_QUEUING + 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 @@ -277,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); } @@ -289,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; @@ -322,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) @@ -330,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) @@ -386,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; } @@ -398,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; @@ -417,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 @@ -448,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) @@ -475,27 +396,25 @@ _evas_cache_image_async_heavy(void *data) current->flags.preload_done = 0; } LKU(current->lock_cancel); - LKU(current->lock); } static void _evas_cache_image_async_end(void *data) { - Image_Entry *ie = (Image_Entry *) data; + Image_Entry *ie = (Image_Entry *)data; Evas_Cache_Target *tmp; 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); } } @@ -504,31 +423,23 @@ static void _evas_cache_image_async_cancel(void *data) { Evas_Cache_Image *cache = NULL; - Image_Entry *ie = (Image_Entry *) data; - + Image_Entry *ie = (Image_Entry *)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 @@ -543,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; } @@ -577,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; } @@ -590,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); } } @@ -611,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 @@ -648,41 +551,25 @@ 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; + 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; } @@ -692,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 @@ -705,7 +590,6 @@ evas_cache_image_shutdown(Evas_Cache_Image *cache) #endif return; } - #ifdef BUILD_ASYNC_PRELOAD EINA_LIST_FREE(cache->preload, im) { @@ -713,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; + im = (Image_Entry *)cache->lru; _evas_cache_image_entry_delete(cache, im); } - while (cache->lru_nodata) { - im = (Image_Entry *) 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; + 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)); @@ -750,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; @@ -783,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) && @@ -816,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 @@ -885,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 @@ -916,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; @@ -930,24 +785,20 @@ 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; #ifdef EVAS_FRAME_QUEUING 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: @@ -979,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 @@ -1022,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); } } @@ -1035,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 @@ -1047,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 * @@ -1061,38 +903,32 @@ 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)) { #ifdef EVAS_FRAME_QUEUING - LKL(im->lock_references); + LKL(im->lock_references); #endif - references = im->references; + references = im->references; #ifdef EVAS_FRAME_QUEUING - LKU(im->lock_references); + LKU(im->lock_references); #endif - #ifndef EVAS_CSERVE -// if ref 1 also copy if using shared cache as its read-only + // if ref 1 also copy if using shared cache as its read-only if (references == 1) im_dirty = im; else #endif { int error; - + im_dirty = - evas_cache_image_copied_data(cache, im->w, im->h, - evas_cache_image_pixels(im), - im->flags.alpha, im->space); + 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 @@ -1100,22 +936,17 @@ 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); - + cache->func.dirty_region(im_dirty, x, y, w, h); return im_dirty; - on_error: +on_error: if (im_dirty) _evas_cache_image_entry_delete(cache, im_dirty); evas_cache_image_drop(im); return NULL; @@ -1128,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); @@ -1142,65 +970,53 @@ 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, - evas_cache_image_pixels(im), - im->flags.alpha, - im->space); + 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); + LKL(im_dirty->lock_references); #endif im_dirty->references = 1; #ifdef EVAS_FRAME_QUEUING - LKU(im_dirty->lock_references); + LKU(im_dirty->lock_references); #endif - evas_cache_image_drop(im); } - return im_dirty; - on_error: +on_error: if (im_dirty) _evas_cache_image_entry_delete(cache, im_dirty); evas_cache_image_drop(im); return NULL; } 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; - + 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); @@ -1213,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; } @@ -1224,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; - + 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); @@ -1247,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; } @@ -1338,86 +1127,58 @@ 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); } - + 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 */ @@ -1427,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 @@ -1466,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; } @@ -1477,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); - } + 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); @@ -1501,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 @@ -1511,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 @@ -1525,20 +1317,18 @@ evas_cache_image_flush(Evas_Cache_Image *cache) while ((cache->lru) && (cache->limit < (unsigned int)cache->usage)) { Image_Entry *im; - + im = (Image_Entry *)cache->lru->last; _evas_cache_image_entry_delete(cache, im); } - + while ((cache->lru_nodata) && (cache->limit < (unsigned int)cache->usage)) { 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; } @@ -1552,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 @@ -1566,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/include/evas_common.h b/src/lib/include/evas_common.h index 9562427..74077d8 100644 --- a/src/lib/include/evas_common.h +++ b/src/lib/include/evas_common.h @@ -537,10 +537,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