diff --git a/src/lib/evas/cache/evas_cache_image.c b/src/lib/evas/cache/evas_cache_image.c index 2d93e7107b..9b450531aa 100644 --- a/src/lib/evas/cache/evas_cache_image.c +++ b/src/lib/evas/cache/evas_cache_image.c @@ -307,7 +307,7 @@ _evas_cache_image_entry_surface_alloc__locked(Evas_Cache_Image *cache, unsigned int hmin) { if ((ie->allocated.w == wmin) && (ie->allocated.h == hmin)) return; - if (cache->func.surface_alloc(ie, wmin, hmin)) + if ((cache->func.surface_alloc(ie, wmin, hmin)) || (ie->load_failed)) { wmin = 0; hmin = 0; @@ -418,6 +418,7 @@ _evas_cache_image_async_end(void *data) ie->flags.preload_pending = 0; LKU(wakeup); + evas_cache_image_ref(ie); while ((tmp = ie->targets)) { ie->targets = (Evas_Cache_Target *) @@ -439,6 +440,7 @@ _evas_cache_image_async_end(void *data) EINA_LIST_FREE(ie->tasks, task) if (task != &dummy_task) free(task); + evas_cache_image_drop(ie); } static void @@ -821,16 +823,29 @@ evas_cache_image_mmap_request(Evas_Cache_Image *cache, /* find image by key in active mmap hash */ im = eina_hash_find(cache->mmap_activ, hkey); - if (im) goto on_ok; + if ((im) && (!im->load_failed)) goto on_ok; + else if ((im) && (im->load_failed)) + { + _evas_cache_image_dirty_add(im); + im = NULL; + } /* find image by key in inactive/lru hash */ im = eina_hash_find(cache->mmap_inactiv, hkey); - if (im) + if ((im) && (!im->load_failed)) { _evas_cache_image_lru_del(im); _evas_cache_image_activ_add(im); goto on_ok; } + else if ((im) && (im->load_failed)) + { + /* as active cache find - if we match in lru and its invalid, dirty */ + _evas_cache_image_dirty_add(im); + /* this image never used, so it have to be deleted */ + _evas_cache_image_entry_delete(cache, im); + im = NULL; + } im = _evas_cache_image_entry_new(cache, hkey, NULL, f, NULL, key, lo, error); if (!im) return NULL; @@ -882,7 +897,7 @@ evas_cache_image_request(Evas_Cache_Image *cache, const char *file, /* find image by key in active hash */ im = eina_hash_find(cache->activ, hkey); - if (im) + if ((im) && (!im->load_failed)) { int ok = 1; @@ -905,10 +920,15 @@ evas_cache_image_request(Evas_Cache_Image *cache, const char *file, _evas_cache_image_dirty_add(im); im = NULL; } + else if ((im) && (im->load_failed)) + { + _evas_cache_image_dirty_add(im); + im = NULL; + } /* find image by key in inactive/lru hash */ im = eina_hash_find(cache->inactiv, hkey); - if (im) + if ((im) && (!im->load_failed)) { int ok = 1; @@ -940,6 +960,14 @@ evas_cache_image_request(Evas_Cache_Image *cache, const char *file, _evas_cache_image_entry_delete(cache, im); im = NULL; } + else if ((im) && (im->load_failed)) + { + /* as active cache find - if we match in lru and its invalid, dirty */ + _evas_cache_image_dirty_add(im); + /* this image never used, so it have to be deleted */ + _evas_cache_image_entry_delete(cache, im); + im = NULL; + } if (stat_failed) goto on_stat_error; if (!skip) @@ -1012,7 +1040,7 @@ evas_cache_image_drop(Image_Entry *im) _evas_cache_image_entry_preload_remove(im, NULL); return; } - if (im->flags.dirty) + if ((im->flags.dirty) || (im->load_failed)) { _evas_cache_image_entry_delete(cache, im); return; @@ -1420,6 +1448,7 @@ evas_cache_image_flush(Evas_Cache_Image *cache) Image_Entry *im; im = (Image_Entry *)cache->lru->last; + if (!im) im = (Image_Entry *)cache->lru; _evas_cache_image_entry_delete(cache, im); } @@ -1427,7 +1456,8 @@ evas_cache_image_flush(Evas_Cache_Image *cache) { Image_Entry *im; - im = (Image_Entry *) cache->lru_nodata->last; + im = (Image_Entry *)cache->lru_nodata->last; + if (!im) im = (Image_Entry *)cache->lru_nodata; _evas_cache_image_lru_nodata_del(im); cache->func.surface_delete(im); im->flags.loaded = 0; diff --git a/src/lib/evas/common/evas_image_load.c b/src/lib/evas/common/evas_image_load.c index c1bfde7c9b..b27bae2c00 100644 --- a/src/lib/evas/common/evas_image_load.c +++ b/src/lib/evas/common/evas_image_load.c @@ -383,7 +383,7 @@ end: ie->info.module = em; ie->info.loader = em->functions; - evas_module_ref(ie->info.module); + if (em) evas_module_ref(em); return ret; } @@ -419,7 +419,11 @@ evas_common_load_rgba_image_data_from_file(Image_Entry *ie) CRI("This function shouldn't be called anymore!"); #endif - if (!ie->info.module) return EVAS_LOAD_ERROR_GENERIC; + if (!ie->info.module) + { + ie->load_failed = 1; + return EVAS_LOAD_ERROR_GENERIC; + } evas_image_load_func = ie->info.loader; evas_module_use(ie->info.module); @@ -431,20 +435,20 @@ evas_common_load_rgba_image_data_from_file(Image_Entry *ie) if (_evas_image_file_header(em, ie, &ret)) { em = NULL; - for (i = 0; i < sizeof(loaders_name) / sizeof (char *); i++) + if (!ie->load_opts.skip_head) { - em = evas_module_find_type(EVAS_MODULE_TYPE_IMAGE_LOADER, - loaders_name[i]); - if (em) + for (i = 0; i < sizeof(loaders_name) / sizeof (char *); i++) { - if (!ie->load_opts.skip_head) + em = evas_module_find_type + (EVAS_MODULE_TYPE_IMAGE_LOADER, loaders_name[i]); + if (em) { if (!_evas_image_file_header(em, ie, &ret)) goto end; } + else DBG("could not find module '%s'", loaders_name[i]); + em = NULL; } - else DBG("could not find module '%s'", loaders_name[i]); - em = NULL; } } end: @@ -455,7 +459,11 @@ end: ie->info.module = em; } } - if ((!ie->f) || (!ie->info.module)) return EVAS_LOAD_ERROR_DOES_NOT_EXIST; + if ((!ie->f) || (!ie->info.module)) + { + ie->load_failed = 1; + return EVAS_LOAD_ERROR_DOES_NOT_EXIST; + } if ((ie->file) && (stat(ie->file, &st) == 0)) _timestamp_build(&(ie->tstamp), &st); @@ -477,7 +485,11 @@ end: property.borders.b = ie->borders.b; pixels = evas_cache_image_pixels(ie); - if (!pixels) return EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED; + if (!pixels) + { + ie->load_failed = 1; + return EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED; + } evas_image_load_func->file_data(ie->loader_data, &property, pixels, &ret); diff --git a/src/lib/evas/include/evas_common_private.h b/src/lib/evas/include/evas_common_private.h index 09a39402b8..d52dec5fb3 100644 --- a/src/lib/evas/include/evas_common_private.h +++ b/src/lib/evas/include/evas_common_private.h @@ -617,6 +617,8 @@ struct _Image_Entry { EINA_INLIST; + int magic; + Evas_Cache_Image *cache; #ifdef EVAS_CSERVE2 Evas_Cache2 *cache2; @@ -650,6 +652,7 @@ struct _Image_Entry unsigned char scale; unsigned char need_unload : 1; + unsigned char load_failed : 1; struct {