From d8332441009f2f34c92140ce7b61460402d5fe96 Mon Sep 17 00:00:00 2001 From: Cedric Bail Date: Wed, 8 May 2013 15:37:37 +0900 Subject: [PATCH] evas: add infrastructure to open from Eina_File. --- src/lib/evas/Evas_Eo.h | 15 ++ src/lib/evas/Evas_Legacy.h | 17 ++ src/lib/evas/cache/evas_cache.h | 19 +- src/lib/evas/cache/evas_cache_image.c | 258 +++++++++++++++------ src/lib/evas/canvas/evas_object_image.c | 176 +++++++++----- src/lib/evas/common/evas_image.h | 1 + src/lib/evas/common/evas_image_load.c | 50 ++-- src/lib/evas/common/evas_image_main.c | 32 ++- src/lib/evas/include/evas_common.h | 1 + src/lib/evas/include/evas_private.h | 1 + src/modules/evas/engines/gl_cocoa/evas_engine.c | 12 + .../evas/engines/gl_common/evas_gl_common.h | 1 + src/modules/evas/engines/gl_common/evas_gl_image.c | 36 ++- src/modules/evas/engines/gl_sdl/evas_engine.c | 10 + src/modules/evas/engines/gl_x11/evas_engine.c | 12 + .../evas/engines/software_generic/evas_engine.c | 21 ++ 16 files changed, 493 insertions(+), 169 deletions(-) diff --git a/src/lib/evas/Evas_Eo.h b/src/lib/evas/Evas_Eo.h index 83c6540..8345981 100644 --- a/src/lib/evas/Evas_Eo.h +++ b/src/lib/evas/Evas_Eo.h @@ -5474,6 +5474,7 @@ enum { EVAS_OBJ_IMAGE_SUB_ID_MEMFILE_SET, EVAS_OBJ_IMAGE_SUB_ID_FILE_SET, + EVAS_OBJ_IMAGE_SUB_ID_MMAP_SET, EVAS_OBJ_IMAGE_SUB_ID_FILE_GET, EVAS_OBJ_IMAGE_SUB_ID_SOURCE_SET, EVAS_OBJ_IMAGE_SUB_ID_SOURCE_GET, @@ -5584,6 +5585,20 @@ enum #define evas_obj_image_file_set(file, key) EVAS_OBJ_IMAGE_ID(EVAS_OBJ_IMAGE_SUB_ID_FILE_SET), EO_TYPECHECK(const char *, file), EO_TYPECHECK(const char*, key) /** + * @def evas_obj_image_mmap_set + * @since 1.8 + * + * Set the source mmaped file from where an image object must fetch the real + * image data (it may be any Eina_File). + * + * @param[in] file in + * @param[in] key in + * + * @see evas_obj_image_file_set + */ +#define evas_obj_image_mmap_set(f, key) EVAS_OBJ_IMAGE_ID(EVAS_OBJ_IMAGE_SUB_ID_MMAP_SET), EO_TYPECHECK(Eina_File *, f), EO_TYPECHECK(const char*, key) + +/** * @def evas_obj_image_file_get * @since 1.8 * diff --git a/src/lib/evas/Evas_Legacy.h b/src/lib/evas/Evas_Legacy.h index fd69a83..8456900 100644 --- a/src/lib/evas/Evas_Legacy.h +++ b/src/lib/evas/Evas_Legacy.h @@ -3913,6 +3913,23 @@ EAPI void evas_object_image_memfile_set(Evas_Object *ob EAPI void evas_object_image_file_set(Evas_Object *obj, const char *file, const char *key) EINA_ARG_NONNULL(1); /** + * Set the source mmaped file from where an image object must fetch the real + * image data (it must be an Eina_File). + * + * @param obj The given image object. + * @param f The mmaped file + * @param key The image key in @p file (if its an Eet one), or @c + * NULL, otherwise. + * + * If the file supports multiple data stored in it (as Eet files do), + * you can specify the key to be used as the index of the image in + * this file. + * + * @since 1.8 + */ +EAPI void evas_object_image_mmap_set(Evas_Object *eo_obj, Eina_File *f, const char *key); + +/** * Retrieve the source file from where an image object is to fetch the * real image data (it may be an Eet file, besides pure image ones). * diff --git a/src/lib/evas/cache/evas_cache.h b/src/lib/evas/cache/evas_cache.h index 8fca866..b7756ae 100644 --- a/src/lib/evas/cache/evas_cache.h +++ b/src/lib/evas/cache/evas_cache.h @@ -55,6 +55,12 @@ struct _Evas_Cache_Image Eina_Inlist *lru_nodata; Eina_Hash *inactiv; Eina_Hash *activ; + + Eina_Hash *mmap_activ; + Eina_Hash *mmap_inactiv; + Eina_Inlist *mmap_lru; + Eina_Inlist *mmap_lru_nodata; + void *data; int usage; @@ -90,14 +96,14 @@ struct _Evas_Cache_Engine_Image { Evas_Cache_Engine_Image_Func func; - Eina_Inlist* dirty; + Eina_Inlist *dirty; - Eina_Hash* activ; - Eina_Hash* inactiv; - Eina_Inlist* lru; + Eina_Hash *activ; + Eina_Hash *inactiv; + Eina_Inlist *lru; - Evas_Cache_Image* parent; - Evas_Cache_Engine_Image* brother; + Evas_Cache_Image *parent; + Evas_Cache_Engine_Image *brother; int usage; int limit; @@ -114,6 +120,7 @@ extern "C" { EAPI Evas_Cache_Image* evas_cache_image_init(const Evas_Cache_Image_Func *cb); EAPI void evas_cache_image_shutdown(Evas_Cache_Image *cache); EAPI Image_Entry* evas_cache_image_request(Evas_Cache_Image *cache, const char *file, const char *key, Evas_Image_Load_Opts *lo, int *error); +EAPI Image_Entry* evas_cache_image_mmap_request(Evas_Cache_Image *cache, Eina_File *f, const char *key, Evas_Image_Load_Opts *lo, int *error); EAPI void evas_cache_image_ref(Image_Entry *im); EAPI void evas_cache_image_drop(Image_Entry *im); EAPI void evas_cache_image_data_not_needed(Image_Entry *im); diff --git a/src/lib/evas/cache/evas_cache_image.c b/src/lib/evas/cache/evas_cache_image.c index 6765f6b..1dc13d9 100644 --- a/src/lib/evas/cache/evas_cache_image.c +++ b/src/lib/evas/cache/evas_cache_image.c @@ -72,7 +72,7 @@ _evas_cache_image_dirty_del(Image_Entry *im) if (!im->flags.dirty) return; im->flags.dirty = 0; im->flags.cached = 0; - im->cache->dirty = eina_inlist_remove(im->cache->dirty, EINA_INLIST_GET(im)); + im->cache->dirty = eina_inlist_remove(im->cache->dirty, EINA_INLIST_GET(im)); } static void @@ -85,7 +85,10 @@ _evas_cache_image_activ_add(Image_Entry *im) if (!im->cache_key) return; im->flags.activ = 1; im->flags.cached = 1; - eina_hash_direct_add(im->cache->activ, im->cache_key, im); + if (im->flags.given_mmap) + eina_hash_direct_add(im->cache->mmap_activ, im->cache_key, im); + else + eina_hash_direct_add(im->cache->activ, im->cache_key, im); } static void @@ -95,7 +98,10 @@ _evas_cache_image_activ_del(Image_Entry *im) if (!im->cache_key) return; im->flags.activ = 0; im->flags.cached = 0; - eina_hash_del(im->cache->activ, im->cache_key, im); + if (im->flags.given_mmap) + eina_hash_del(im->cache->mmap_activ, im->cache_key, im); + else + eina_hash_del(im->cache->activ, im->cache_key, im); } static void @@ -108,8 +114,16 @@ _evas_cache_image_lru_add(Image_Entry *im) if (!im->cache_key) return; im->flags.lru = 1; im->flags.cached = 1; - eina_hash_direct_add(im->cache->inactiv, im->cache_key, im); - im->cache->lru = eina_inlist_prepend(im->cache->lru, EINA_INLIST_GET(im)); + if (im->flags.given_mmap) + { + eina_hash_direct_add(im->cache->mmap_inactiv, im->cache_key, im); + im->cache->mmap_lru = eina_inlist_prepend(im->cache->mmap_lru, EINA_INLIST_GET(im)); + } + else + { + 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); } @@ -120,8 +134,16 @@ _evas_cache_image_lru_del(Image_Entry *im) if (!im->cache_key) return; im->flags.lru = 0; im->flags.cached = 0; - eina_hash_del(im->cache->inactiv, im->cache_key, im); - im->cache->lru = eina_inlist_remove(im->cache->lru, EINA_INLIST_GET(im)); + if (im->flags.given_mmap) + { + eina_hash_del(im->cache->mmap_inactiv, im->cache_key, im); + im->cache->mmap_lru = eina_inlist_remove(im->cache->mmap_lru, EINA_INLIST_GET(im)); + } + else + { + 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); } @@ -134,7 +156,10 @@ _evas_cache_image_lru_nodata_add(Image_Entry *im) _evas_cache_image_lru_del(im); im->flags.lru = 1; im->flags.cached = 1; - im->cache->lru_nodata = eina_inlist_prepend(im->cache->lru_nodata, EINA_INLIST_GET(im)); + if (im->flags.given_mmap) + im->cache->mmap_lru_nodata = eina_inlist_prepend(im->cache->mmap_lru_nodata, EINA_INLIST_GET(im)); + else + im->cache->lru_nodata = eina_inlist_prepend(im->cache->lru_nodata, EINA_INLIST_GET(im)); } static void @@ -143,7 +168,10 @@ _evas_cache_image_lru_nodata_del(Image_Entry *im) if (!im->flags.lru_nodata) return; im->flags.lru = 0; im->flags.cached = 0; - im->cache->lru_nodata = eina_inlist_remove(im->cache->lru_nodata, EINA_INLIST_GET(im)); + if (im->flags.given_mmap) + im->cache->mmap_lru_nodata = eina_inlist_remove(im->cache->mmap_lru_nodata, EINA_INLIST_GET(im)); + else + im->cache->lru_nodata = eina_inlist_remove(im->cache->lru_nodata, EINA_INLIST_GET(im)); } static void @@ -213,6 +241,7 @@ static Image_Entry * _evas_cache_image_entry_new(Evas_Cache_Image *cache, const char *hkey, Image_Timestamp *tstamp, + Eina_File *f, const char *file, const char *key, Evas_Image_Load_Opts *lo, @@ -233,6 +262,9 @@ _evas_cache_image_entry_new(Evas_Cache_Image *cache, ie->w = -1; ie->h = -1; ie->scale = 1; + ie->f = f; + ie->loader_data = NULL; + if (ie->f) ie->flags.given_mmap = EINA_TRUE; if (file) ie->file = eina_stringshare_add(file); if (key) ie->key = eina_stringshare_add(key); if (tstamp) ie->tstamp = *tstamp; @@ -242,7 +274,7 @@ _evas_cache_image_entry_new(Evas_Cache_Image *cache, LKI(ie->lock_cancel); if (lo) ie->load_opts = *lo; - if (ie->file) + if (ie->file || ie->f) { *error = cache->func.constructor(ie); if (*error != EVAS_LOAD_ERROR_NONE) @@ -485,6 +517,8 @@ evas_cache_image_init(const Evas_Cache_Image_Func *cb) cache->func = *cb; cache->inactiv = eina_hash_string_superfast_new(NULL); cache->activ = eina_hash_string_superfast_new(NULL); + cache->mmap_activ = eina_hash_string_superfast_new(NULL); + cache->mmap_inactiv = eina_hash_string_superfast_new(NULL); cache->references = 1; return cache; } @@ -534,6 +568,9 @@ evas_cache_image_shutdown(Evas_Cache_Image *cache) } delete_list = NULL; eina_hash_foreach(cache->activ, _evas_cache_image_free_cb, &delete_list); + eina_hash_foreach(cache->mmap_activ, _evas_cache_image_free_cb, &delete_list); + eina_hash_foreach(cache->inactiv, _evas_cache_image_free_cb, &delete_list); + eina_hash_foreach(cache->mmap_inactiv, _evas_cache_image_free_cb, &delete_list); while (delete_list) { _evas_cache_image_entry_delete(cache, eina_list_data_get(delete_list)); @@ -553,6 +590,8 @@ evas_cache_image_shutdown(Evas_Cache_Image *cache) } eina_hash_free(cache->activ); eina_hash_free(cache->inactiv); + eina_hash_free(cache->mmap_activ); + eina_hash_free(cache->mmap_inactiv); free(cache); if (--_evas_cache_mutex_init == 0) @@ -563,6 +602,140 @@ evas_cache_image_shutdown(Evas_Cache_Image *cache) } } +static const Evas_Image_Load_Opts prevent = { + { 0, 0, 0, 0 }, + { + 0, 0, 0, 0, + 0, 0, + 0, + 0 + }, + 0.0, + 0, 0, + 0, + 0, + + EINA_FALSE +}; + +static size_t +_evas_cache_image_loadopts_append(char *hkey, Evas_Image_Load_Opts **plo) +{ + Evas_Image_Load_Opts *lo = *plo; + size_t offset = 0; + + if ((!lo) || + (lo && + (lo->scale_down_by == 0) && + (lo->dpi == 0.0) && + ((lo->w == 0) || (lo->h == 0)) && + ((lo->region.w == 0) || (lo->region.h == 0)) && + (lo->orientation == 0) + )) + { + *plo = (Evas_Image_Load_Opts*) &prevent; + } + else + { + memcpy(hkey, "//@/", 4); + offset += 4; + offset += eina_convert_xtoa(lo->scale_down_by, hkey + offset); + hkey[offset] = '/'; + offset += 1; + offset += eina_convert_dtoa(lo->dpi, hkey + offset); + hkey[offset] = '/'; + offset += 1; + offset += eina_convert_xtoa(lo->w, hkey + offset); + hkey[offset] = 'x'; + offset += 1; + offset += eina_convert_xtoa(lo->h, hkey + offset); + hkey[offset] = '/'; + offset += 1; + offset += eina_convert_xtoa(lo->region.x, hkey + offset); + hkey[offset] = '+'; + offset += 1; + offset += eina_convert_xtoa(lo->region.y, hkey + offset); + hkey[offset] = '.'; + offset += 1; + offset += eina_convert_xtoa(lo->region.w, hkey + offset); + hkey[offset] = 'x'; + offset += 1; + offset += eina_convert_xtoa(lo->region.h, hkey + offset); + + if (lo->orientation) + { + hkey[offset] = '/'; + offset += 1; + hkey[offset] = 'o'; + offset += 1; + } + } + hkey[offset] = '\0'; + + return offset; +} + +EAPI Image_Entry * +evas_cache_image_mmap_request(Evas_Cache_Image *cache, + Eina_File *f, const char *key, + Evas_Image_Load_Opts *lo, int *error) +{ + const char *hexcode = "0123456789abcdef"; + const char *ckey = "(null)"; + char *hkey; + char *pf; + Image_Entry *im; + size_t size; + size_t file_length; + size_t key_length; + unsigned int i; + + // FIXME: In the long term we should certainly merge both mmap and filename path + // by just using the mmap path. But for the time being, let's just have two path + // as it is unlikely to really have an impact on real world application + if ((!f) || (!f && !key)) + { + *error = EVAS_LOAD_ERROR_GENERIC; + return NULL; + } + + /* generate hkey from file+key+load opts */ + file_length = sizeof (Eina_File*) * 2; + key_length = key ? strlen(key) : 6; + size = file_length + key_length + 132; + hkey = alloca(sizeof (char) * size); + pf = (char*) &f; + for (size = 0, i = 0; i < sizeof (Eina_File*); i++) + { + hkey[size++] = hexcode[(pf[i] & 0xF0) >> 4]; + hkey[size++] = hexcode[(pf[i] & 0x0F)]; + } + memcpy(hkey + size, "//://", 5); + size += 5; + if (key) ckey = key; + memcpy(hkey + size, ckey, key_length); + size += key_length; + size += _evas_cache_image_loadopts_append(hkey + size, &lo); + + + /* find image by key in active mmap hash */ + im = eina_hash_find(cache->mmap_activ, hkey); + if (im) goto on_ok; + + /* find image by key in inactive/lru hash */ + im = eina_hash_find(cache->mmap_inactiv, hkey); + if (im) goto on_ok; + + im = _evas_cache_image_entry_new(cache, hkey, NULL, f, NULL, key, lo, error); + if (!im) return NULL; + + on_ok: + *error = EVAS_LOAD_ERROR_NONE; + im->references++; + return im; +} + + EAPI Image_Entry * evas_cache_image_request(Evas_Cache_Image *cache, const char *file, const char *key, Evas_Image_Load_Opts *lo, int *error) @@ -570,7 +743,6 @@ evas_cache_image_request(Evas_Cache_Image *cache, const char *file, const char *ckey = "(null)"; char *hkey; Image_Entry *im; - Evas_Image_Load_Opts prevent; size_t size; int stat_done = 0, stat_failed = 0; size_t file_length; @@ -584,8 +756,6 @@ evas_cache_image_request(Evas_Cache_Image *cache, const char *file, return NULL; } - memset(&prevent, 0, sizeof prevent); - /* generate hkey from file+key+load opts */ file_length = strlen(file); key_length = key ? strlen(key) : 6; @@ -598,53 +768,7 @@ evas_cache_image_request(Evas_Cache_Image *cache, const char *file, if (key) ckey = key; memcpy(hkey + size, ckey, key_length); size += key_length; - if ((!lo) || - (lo && - (lo->scale_down_by == 0) && - (lo->dpi == 0.0) && - ((lo->w == 0) || (lo->h == 0)) && - ((lo->region.w == 0) || (lo->region.h == 0)) && - (lo->orientation == 0) - )) - { - lo = &prevent; - } - 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); - - if (lo->orientation) - { - hkey[size] = '/'; - size += 1; - hkey[size] = 'o'; - size += 1; - } - } - hkey[size] = '\0'; + size += _evas_cache_image_loadopts_append(hkey + size, &lo); /* find image by key in active hash */ im = eina_hash_find(cache->activ, hkey); @@ -707,7 +831,7 @@ evas_cache_image_request(Evas_Cache_Image *cache, const char *file, if (stat(file, &st) < 0) goto on_stat_error; } _timestamp_build(&tstamp, &st); - im = _evas_cache_image_entry_new(cache, hkey, &tstamp, file, key, + im = _evas_cache_image_entry_new(cache, hkey, &tstamp, NULL, file, key, lo, error); if (!im) goto on_stat_error; if (cache->func.debug) cache->func.debug("request", im); @@ -866,7 +990,7 @@ evas_cache_image_copied_data(Evas_Cache_Image *cache, (cspace == EVAS_COLORSPACE_YCBCR422601_PL)) w &= ~0x1; - im = _evas_cache_image_entry_new(cache, NULL, NULL, NULL, NULL, NULL, NULL); + im = _evas_cache_image_entry_new(cache, NULL, NULL, NULL, NULL, NULL, NULL, NULL); if (!im) return NULL; im->space = cspace; im->flags.alpha = alpha; @@ -892,7 +1016,7 @@ evas_cache_image_data(Evas_Cache_Image *cache, unsigned int w, unsigned int h, D (cspace == EVAS_COLORSPACE_YCBCR422601_PL)) w &= ~0x1; - im = _evas_cache_image_entry_new(cache, NULL, NULL, NULL, NULL, NULL, NULL); + im = _evas_cache_image_entry_new(cache, NULL, NULL, NULL, NULL, NULL, NULL, NULL); if (!im) return NULL; im->w = w; im->h = h; @@ -936,7 +1060,7 @@ evas_cache_image_size_set(Image_Entry *im, unsigned int w, unsigned int h) if ((im->w == w) && (im->h == h)) return im; cache = im->cache; - im2 = _evas_cache_image_entry_new(cache, NULL, NULL, NULL, NULL, NULL, &error); + im2 = _evas_cache_image_entry_new(cache, NULL, NULL, NULL, NULL, NULL, NULL, &error); if (!im2) goto on_error; im2->flags.alpha = im->flags.alpha; @@ -1021,7 +1145,7 @@ evas_cache_image_unload_data(Image_Entry *im) } LKU(im->lock_cancel); - if ((!im->flags.loaded) || (!im->file) || (!im->info.module) || + if ((!im->flags.loaded) || (!im->file && !im->f) || (!im->info.module) || (im->flags.dirty)) { LKU(im->lock); @@ -1091,7 +1215,7 @@ _dump_img(Image_Entry *im, const char *type) im->references, im->cache->func.mem_size_get(im), im->w, im->h, im->allocated.w, im->allocated.h, - im->file, im->key); + im->f ? eina_file_filename_get(im->f) : im->file, im->key); } static Eina_Bool @@ -1159,7 +1283,7 @@ evas_cache_image_empty(Evas_Cache_Image *cache) { Image_Entry *im; - im = _evas_cache_image_entry_new(cache, NULL, NULL, NULL, NULL, NULL, NULL); + im = _evas_cache_image_entry_new(cache, NULL, NULL, NULL, NULL, NULL, NULL, NULL); if (!im) return NULL; im->references = 1; return im; diff --git a/src/lib/evas/canvas/evas_object_image.c b/src/lib/evas/canvas/evas_object_image.c index 3bc4cef..864d5f2 100644 --- a/src/lib/evas/canvas/evas_object_image.c +++ b/src/lib/evas/canvas/evas_object_image.c @@ -85,6 +85,7 @@ struct _Evas_Object_Image_State Evas_Map *defmap; const char *file; const char *key; + Eina_File *f; int frame; int spread; @@ -196,7 +197,7 @@ static const Evas_Object_Image_State default_state = { { 0, 0, 0 }, // image { 1.0, 0, 0, 0, 0, 1 }, // border - NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, 0, EVAS_TEXTURE_REPEAT, EVAS_COLORSPACE_ARGB8888, @@ -483,51 +484,18 @@ _image_memfile_set(Eo *eo_obj, void *_pd, va_list *list) } } -EAPI void -evas_object_image_file_set(Evas_Object *eo_obj, const char *file, const char *key) -{ - MAGIC_CHECK(eo_obj, Evas_Object, MAGIC_OBJ); - return; - MAGIC_CHECK_END(); - eo_do(eo_obj, evas_obj_image_file_set(file, key)); -} - static void -_image_file_set(Eo *eo_obj, void *_pd, va_list *list) +_image_init_set(Eina_File *f, const char *file, const char *key, + Eo *eo_obj, Evas_Object_Protected_Data *obj, Evas_Object_Image *o, + Evas_Image_Load_Opts *lo) { - Evas_Object_Protected_Data *obj = eo_data_scope_get(eo_obj, EVAS_OBJ_CLASS); - Evas_Object_Image *o = _pd; - Evas_Image_Load_Opts lo; - Eina_Bool resize_call = EINA_FALSE; - - const char *file = va_arg(*list, const char*); - const char *key = va_arg(*list, const char*); - - if ((o->pixels->tmpf) && (file != o->pixels->tmpf)) _cleanup_tmpf(eo_obj); - if ((o->cur->file) && (file) && (!strcmp(o->cur->file, file))) - { - if ((!o->cur->key) && (!key)) - return; - if ((o->cur->key) && (key) && (!strcmp(o->cur->key, key))) - return; - } - /* - * WTF? why cancel a null image preload? this is just silly (tm) - if (!o->engine_data) - obj->layer->evas->engine.func->image_data_preload_cancel(obj->layer->evas->engine.data.output, - o->engine_data, - eo_obj); - */ if (o->cur->source) _proxy_unset(eo_obj, obj, o); EINA_COW_IMAGE_STATE_WRITE_BEGIN(o, state_write) { - if (o->cur->file) eina_stringshare_del(state_write->file); - if (o->cur->key) eina_stringshare_del(o->cur->key); - if (file) state_write->file = eina_stringshare_add(file); - else state_write->file = NULL; - if (key) state_write->key = eina_stringshare_add(key); - else state_write->key = NULL; + eina_stringshare_replace(&state_write->file, file); + eina_stringshare_replace(&state_write->key, key); + state_write->f = f; } EINA_COW_IMAGE_STATE_WRITE_END(o, state_write); @@ -535,9 +503,10 @@ _image_file_set(Eo *eo_obj, void *_pd, va_list *list) { state_write->file = NULL; state_write->key = NULL; + state_write->f = NULL; } EINA_COW_WRITE_END(evas_object_image_state_cow, o->prev, state_write); - + if (o->engine_data) { if (o->preloading) @@ -548,28 +517,30 @@ _image_file_set(Eo *eo_obj, void *_pd, va_list *list) obj->layer->evas->engine.func->image_free(obj->layer->evas->engine.data.output, o->engine_data); } o->load_error = EVAS_LOAD_ERROR_NONE; - lo.scale_down_by = o->load_opts->scale_down_by; - lo.dpi = o->load_opts->dpi; - lo.w = o->load_opts->w; - lo.h = o->load_opts->h; - lo.region.x = o->load_opts->region.x; - lo.region.y = o->load_opts->region.y; - lo.region.w = o->load_opts->region.w; - lo.region.h = o->load_opts->region.h; - lo.scale_load.src_x = o->load_opts->scale_load.src_x; - lo.scale_load.src_y = o->load_opts->scale_load.src_y; - lo.scale_load.src_w = o->load_opts->scale_load.src_w; - lo.scale_load.src_h = o->load_opts->scale_load.src_h; - lo.scale_load.dst_w = o->load_opts->scale_load.dst_w; - lo.scale_load.dst_h = o->load_opts->scale_load.dst_h; - lo.scale_load.smooth = o->load_opts->scale_load.smooth; - lo.scale_load.scale_hint = o->load_opts->scale_load.scale_hint; - lo.orientation = o->load_opts->orientation; - o->engine_data = obj->layer->evas->engine.func->image_load(obj->layer->evas->engine.data.output, - o->cur->file, - o->cur->key, - &o->load_error, - &lo); + lo->scale_down_by = o->load_opts->scale_down_by; + lo->dpi = o->load_opts->dpi; + lo->w = o->load_opts->w; + lo->h = o->load_opts->h; + lo->region.x = o->load_opts->region.x; + lo->region.y = o->load_opts->region.y; + lo->region.w = o->load_opts->region.w; + lo->region.h = o->load_opts->region.h; + lo->scale_load.src_x = o->load_opts->scale_load.src_x; + lo->scale_load.src_y = o->load_opts->scale_load.src_y; + lo->scale_load.src_w = o->load_opts->scale_load.src_w; + lo->scale_load.src_h = o->load_opts->scale_load.src_h; + lo->scale_load.dst_w = o->load_opts->scale_load.dst_w; + lo->scale_load.dst_h = o->load_opts->scale_load.dst_h; + lo->scale_load.smooth = o->load_opts->scale_load.smooth; + lo->scale_load.scale_hint = o->load_opts->scale_load.scale_hint; + lo->orientation = o->load_opts->orientation; +} + +static void +_image_done_set(Eo *eo_obj, Evas_Object_Protected_Data *obj, Evas_Object_Image *o) +{ + Eina_Bool resize_call = EINA_FALSE; + if (o->engine_data) { int w, h; @@ -620,6 +591,83 @@ _image_file_set(Eo *eo_obj, void *_pd, va_list *list) } EAPI void +evas_object_image_mmap_set(Evas_Object *eo_obj, Eina_File *f, const char *key) +{ + eo_do(eo_obj, evas_obj_image_mmap_set(f, key)); +} + +static void +_image_mmap_set(Eo *eo_obj, void *_pd, va_list *list) +{ + Evas_Object_Protected_Data *obj = eo_data_scope_get(eo_obj, EVAS_OBJ_CLASS); + Evas_Object_Image *o = _pd; + Evas_Image_Load_Opts lo; + + Eina_File *f = va_arg(*list, Eina_File *); + const char *key = va_arg(*list, const char*); + + if (o->pixels->tmpf) _cleanup_tmpf(eo_obj); + if (o->cur->f == f) + { + if ((!o->cur->key) && (!key)) + return; + if ((o->cur->key) && (key) && (!strcmp(o->cur->key, key))) + return; + } + + _image_init_set(f, NULL, key, eo_obj, obj, o, &lo); + o->engine_data = obj->layer->evas->engine.func->image_mmap(obj->layer->evas->engine.data.output, + o->cur->f, + o->cur->key, + &o->load_error, + &lo); + _image_done_set(eo_obj, obj, o); +} + +EAPI void +evas_object_image_file_set(Evas_Object *eo_obj, const char *file, const char *key) +{ + MAGIC_CHECK(eo_obj, Evas_Object, MAGIC_OBJ); + return; + MAGIC_CHECK_END(); + eo_do(eo_obj, evas_obj_image_file_set(file, key)); +} + +static void +_image_file_set(Eo *eo_obj, void *_pd, va_list *list) +{ + Evas_Object_Protected_Data *obj = eo_data_scope_get(eo_obj, EVAS_OBJ_CLASS); + Evas_Object_Image *o = _pd; + Evas_Image_Load_Opts lo; + + const char *file = va_arg(*list, const char*); + const char *key = va_arg(*list, const char*); + + if ((o->pixels->tmpf) && (file != o->pixels->tmpf)) _cleanup_tmpf(eo_obj); + if ((o->cur->file) && (file) && (!strcmp(o->cur->file, file))) + { + if ((!o->cur->key) && (!key)) + return; + if ((o->cur->key) && (key) && (!strcmp(o->cur->key, key))) + return; + } + /* + * WTF? why cancel a null image preload? this is just silly (tm) + if (!o->engine_data) + obj->layer->evas->engine.func->image_data_preload_cancel(obj->layer->evas->engine.data.output, + o->engine_data, + eo_obj); + */ + _image_init_set(NULL, file, key, eo_obj, obj, o, &lo); + o->engine_data = obj->layer->evas->engine.func->image_load(obj->layer->evas->engine.data.output, + o->cur->file, + o->cur->key, + &o->load_error, + &lo); + _image_done_set(eo_obj, obj, o); +} + +EAPI void evas_object_image_file_get(const Evas_Object *eo_obj, const char **file, const char **key) { MAGIC_CHECK(eo_obj, Evas_Object, MAGIC_OBJ); @@ -5146,6 +5194,7 @@ _class_constructor(Eo_Class *klass) EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_DBG_INFO_GET), _dbg_info_get), EO_OP_FUNC(EVAS_OBJ_IMAGE_ID(EVAS_OBJ_IMAGE_SUB_ID_MEMFILE_SET), _image_memfile_set), EO_OP_FUNC(EVAS_OBJ_IMAGE_ID(EVAS_OBJ_IMAGE_SUB_ID_FILE_SET), _image_file_set), + EO_OP_FUNC(EVAS_OBJ_IMAGE_ID(EVAS_OBJ_IMAGE_SUB_ID_MMAP_SET), _image_mmap_set), EO_OP_FUNC(EVAS_OBJ_IMAGE_ID(EVAS_OBJ_IMAGE_SUB_ID_FILE_GET), _image_file_get), EO_OP_FUNC(EVAS_OBJ_IMAGE_ID(EVAS_OBJ_IMAGE_SUB_ID_SOURCE_SET), _image_source_set), EO_OP_FUNC(EVAS_OBJ_IMAGE_ID(EVAS_OBJ_IMAGE_SUB_ID_SOURCE_GET), _image_source_get), @@ -5224,6 +5273,7 @@ _class_constructor(Eo_Class *klass) static const Eo_Op_Description op_desc[] = { EO_OP_DESCRIPTION(EVAS_OBJ_IMAGE_SUB_ID_MEMFILE_SET, "Sets the data for an image from memory to be loaded"), EO_OP_DESCRIPTION(EVAS_OBJ_IMAGE_SUB_ID_FILE_SET, "Set the source file from where an image object must fetch the real"), + EO_OP_DESCRIPTION(EVAS_OBJ_IMAGE_SUB_ID_MMAP_SET, "Set the source mmaped file from where an image object must fetch the real"), EO_OP_DESCRIPTION(EVAS_OBJ_IMAGE_SUB_ID_FILE_GET, "Retrieve the source file from where an image object is to fetch the"), EO_OP_DESCRIPTION(EVAS_OBJ_IMAGE_SUB_ID_SOURCE_SET, "Set the source object on an image object to used as a @b proxy."), EO_OP_DESCRIPTION(EVAS_OBJ_IMAGE_SUB_ID_SOURCE_GET, "Get the current source object of an image object."), diff --git a/src/lib/evas/common/evas_image.h b/src/lib/evas/common/evas_image.h index 79f1a29..3ea2f22 100644 --- a/src/lib/evas/common/evas_image.h +++ b/src/lib/evas/common/evas_image.h @@ -33,6 +33,7 @@ EAPI void evas_common_image_alpha_line_buffer_release (RGBA_Image * EAPI void evas_common_image_alpha_line_buffer_free (RGBA_Image *im); EAPI RGBA_Image *evas_common_load_image_from_file (const char *file, const char *key, Evas_Image_Load_Opts *lo, int *error); +EAPI RGBA_Image *evas_common_load_image_from_mmap (Eina_File *f, const char *key, Evas_Image_Load_Opts *lo, int *error); EAPI int evas_common_save_image_to_file (RGBA_Image *im, const char *file, const char *key, int quality, int compress); EAPI void evas_common_rgba_image_scalecache_init(Image_Entry *ie); diff --git a/src/lib/evas/common/evas_image_load.c b/src/lib/evas/common/evas_image_load.c index a505bc9..cb03c7a 100644 --- a/src/lib/evas/common/evas_image_load.c +++ b/src/lib/evas/common/evas_image_load.c @@ -150,8 +150,17 @@ _evas_image_file_header(Evas_Module *em, Image_Entry *ie, int *error) if (evas_image_load_func) { Evas_Image_Property property; + const char *file; - if (!ie->f) ie->f = eina_file_open(ie->file, EINA_FALSE); + if (!ie->f) + { + ie->f = eina_file_open(ie->file, EINA_FALSE); + file = ie->file; + } + else + { + file = eina_file_filename_get(ie->f); + } if (!ie->f) { *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST; @@ -173,7 +182,7 @@ _evas_image_file_header(Evas_Module *em, Image_Entry *ie, int *error) (*error == EVAS_LOAD_ERROR_NONE)) { DBG("loaded file head using module '%s' (%p): %s", - em->definition->name, em, ie->file); + em->definition->name, em, file); ie->w = property.w; ie->h = property.h; @@ -189,7 +198,7 @@ _evas_image_file_header(Evas_Module *em, Image_Entry *ie, int *error) evas_module_unload(em); INF("failed to load file head using module '%s' (%p): " "%s (%s)", - em->definition->name, em, ie->file, evas_load_error_str(*error)); + em->definition->name, em, file, evas_load_error_str(*error)); } } else @@ -221,8 +230,8 @@ EAPI int evas_common_load_rgba_image_module_from_file(Image_Entry *ie) { const char *loader = NULL, *end; + const char *file; Evas_Module *em; - struct stat st; unsigned int i; int len, ret = EVAS_LOAD_ERROR_NONE; struct evas_image_foreach_loader_data fdata; @@ -240,14 +249,27 @@ evas_common_load_rgba_image_module_from_file(Image_Entry *ie) // } } #endif - if (stat(ie->file, &st) != 0 || S_ISDIR(st.st_mode)) + if (ie->f) { - DBG("trying to open directory '%s' !", ie->file); - return EVAS_LOAD_ERROR_DOES_NOT_EXIST; + len = strlen(eina_file_filename_get(ie->f)); + end = eina_file_filename_get(ie->f) + len; + file = eina_file_filename_get(ie->f); + } + else + { + struct stat st; + + if (stat(ie->file, &st) != 0 || S_ISDIR(st.st_mode)) + { + DBG("trying to open directory '%s' !", ie->file); + return EVAS_LOAD_ERROR_DOES_NOT_EXIST; + } + + len = strlen(ie->file); + end = ie->file + len; + file = ie->file; } - len = strlen(ie->file); - end = ie->file + len; for (i = 0; i < (sizeof (loaders) / sizeof(struct ext_loader_s)); i++) { int len2 = strlen(loaders[i].extension); @@ -256,7 +278,7 @@ evas_common_load_rgba_image_module_from_file(Image_Entry *ie) { loader = loaders[i].loader; DBG("known loader '%s' handles extension '%s' of file '%s'", - loader, end - len2, ie->file); + loader, end - len2, file); break; } } @@ -296,10 +318,10 @@ evas_common_load_rgba_image_module_from_file(Image_Entry *ie) DBG("could not find module '%s'", loaders_name[i]); } - INF("exhausted all means to load image '%s'", ie->file); + INF("exhausted all means to load image '%s'", file); return EVAS_LOAD_ERROR_UNKNOWN_FORMAT; - end: + end: if (ret != EVAS_LOAD_ERROR_NONE) { @@ -313,7 +335,7 @@ evas_common_load_rgba_image_module_from_file(Image_Entry *ie) WRN("loader '%s' (version %d) " "handled file '%s', key '%s' with errors: %s", modname ? modname : "", modversion, - ie->file, ie->key ? ie->key : "", + file, ie->key ? ie->key : "", evas_load_error_str(ret)); goto end; } @@ -321,7 +343,7 @@ evas_common_load_rgba_image_module_from_file(Image_Entry *ie) DBG("loader '%s' used for file %s", (em && em->definition && em->definition->name) ? em->definition->name : "", - ie->file); + file); ie->info.module = (void*) em; ie->info.loader = (void*) em ? em->functions : NULL; diff --git a/src/lib/evas/common/evas_image_main.c b/src/lib/evas/common/evas_image_main.c index 8a7e21f..3d9972a 100644 --- a/src/lib/evas/common/evas_image_main.c +++ b/src/lib/evas/common/evas_image_main.c @@ -187,6 +187,15 @@ _evas_common_rgba_image_delete(Image_Entry *ie) #ifdef BUILD_PIPE_RENDER evas_common_pipe_free(im); #endif + if (ie->loader_data) + { + Evas_Image_Load_Func *evas_image_load_func = NULL; + + evas_image_load_func = ie->info.loader; + if (evas_image_load_func) + evas_image_load_func->file_close(ie->loader_data); + ie->loader_data = NULL; + } evas_common_rgba_image_scalecache_shutdown(&im->cache_entry); if (ie->info.module) evas_module_unref((Evas_Module *)ie->info.module); /* memset the image to 0x99 because i recently saw a segv where an @@ -217,15 +226,7 @@ _evas_common_rgba_image_delete(Image_Entry *ie) } } } - if (ie->loader_data) - { - Evas_Image_Load_Func *evas_image_load_func = NULL; - - evas_image_load_func = ie->info.loader; - if (evas_image_load_func) - evas_image_load_func->file_close(ie->loader_data); - } - if (ie->f) eina_file_close(ie->f); + if (ie->f && !ie->flags.given_mmap) eina_file_close(ie->f); free(im); } @@ -269,7 +270,7 @@ evas_common_rgba_image_unload(Image_Entry *ie) if (!ie->flags.loaded) return; if ((!ie->info.module) && (!ie->data1)) return; - if (!ie->file) return; + if (!ie->file && !ie->f) return; if (ie->references > 0) return; ie->flags.loaded = 0; @@ -765,6 +766,17 @@ evas_common_load_image_from_file(const char *file, const char *key, Evas_Image_L return (RGBA_Image *) evas_cache_image_request(eci, file, key, lo, error); } +EAPI RGBA_Image * +evas_common_load_image_from_mmap(Eina_File *f, const char *key, Evas_Image_Load_Opts *lo, int *error) +{ + if (!f) + { + *error = EVAS_LOAD_ERROR_GENERIC; + return NULL; + } + return (RGBA_Image *) evas_cache_image_mmap_request(eci, f, key, lo, error); +} + EAPI void evas_common_image_cache_free(void) { diff --git a/src/lib/evas/include/evas_common.h b/src/lib/evas/include/evas_common.h index 03a2777..4d930dd 100644 --- a/src/lib/evas/include/evas_common.h +++ b/src/lib/evas/include/evas_common.h @@ -513,6 +513,7 @@ struct _Image_Entry_Flags Eina_Bool pending : 1; Eina_Bool rotated : 1; Eina_Bool unload_cancel : 1; + Eina_Bool given_mmap : 1; }; struct _Image_Entry_Frame diff --git a/src/lib/evas/include/evas_private.h b/src/lib/evas/include/evas_private.h index 82a0211..01a556e 100644 --- a/src/lib/evas/include/evas_private.h +++ b/src/lib/evas/include/evas_private.h @@ -795,6 +795,7 @@ struct _Evas_Func void (*polygon_draw) (void *data, void *context, void *surface, void *polygon, int x, int y, Eina_Bool do_async); void *(*image_load) (void *data, const char *file, const char *key, int *error, Evas_Image_Load_Opts *lo); + void *(*image_mmap) (void *data, Eina_File *f, const char *key, int *error, Evas_Image_Load_Opts *lo); void *(*image_new_from_data) (void *data, int w, int h, DATA32 *image_data, int alpha, int cspace); void *(*image_new_from_copied_data) (void *data, int w, int h, DATA32 *image_data, int alpha, int cspace); void (*image_free) (void *data, void *image); diff --git a/src/modules/evas/engines/gl_cocoa/evas_engine.c b/src/modules/evas/engines/gl_cocoa/evas_engine.c index 3614888..b5fc778 100644 --- a/src/modules/evas/engines/gl_cocoa/evas_engine.c +++ b/src/modules/evas/engines/gl_cocoa/evas_engine.c @@ -585,6 +585,17 @@ eng_image_load(void *data, const char *file, const char *key, int *error, Evas_I } static void * +eng_image_mmap(void *data, Eina_File *f, const char *key, int *error, Evas_Image_Load_Opts *lo) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + *error = EVAS_LOAD_ERROR_NONE; + eng_window_use(re->win); + return evas_gl_common_image_mmap(re->win->gl_context, f, key, lo, error); +} + +static void * eng_image_new_from_data(void *data, int w, int h, DATA32 *image_data, int alpha, int cspace) { Render_Engine *re; @@ -1372,6 +1383,7 @@ module_open(Evas_Module *em) ORD(polygon_draw); ORD(image_load); + ORD(image_mmap); ORD(image_new_from_data); ORD(image_new_from_copied_data); ORD(image_free); diff --git a/src/modules/evas/engines/gl_common/evas_gl_common.h b/src/modules/evas/engines/gl_common/evas_gl_common.h index e760320..452ab28 100644 --- a/src/modules/evas/engines/gl_common/evas_gl_common.h +++ b/src/modules/evas/engines/gl_common/evas_gl_common.h @@ -655,6 +655,7 @@ void evas_gl_common_image_all_unload(Evas_Engine_GL_Context *gc); void evas_gl_common_image_ref(Evas_GL_Image *im); void evas_gl_common_image_unref(Evas_GL_Image *im); Evas_GL_Image *evas_gl_common_image_load(Evas_Engine_GL_Context *gc, const char *file, const char *key, Evas_Image_Load_Opts *lo, int *error); +Evas_GL_Image *evas_gl_common_image_mmap(Evas_Engine_GL_Context *gc, Eina_File *f, const char *key, Evas_Image_Load_Opts *lo, int *error); Evas_GL_Image *evas_gl_common_image_new_from_data(Evas_Engine_GL_Context *gc, unsigned int w, unsigned int h, DATA32 *data, int alpha, int cspace); Evas_GL_Image *evas_gl_common_image_new_from_copied_data(Evas_Engine_GL_Context *gc, unsigned int w, unsigned int h, DATA32 *data, int alpha, int cspace); Evas_GL_Image *evas_gl_common_image_new(Evas_Engine_GL_Context *gc, unsigned int w, unsigned int h, int alpha, int cspace); diff --git a/src/modules/evas/engines/gl_common/evas_gl_image.c b/src/modules/evas/engines/gl_common/evas_gl_image.c index b605b75..a8036ad 100644 --- a/src/modules/evas/engines/gl_common/evas_gl_image.c +++ b/src/modules/evas/engines/gl_common/evas_gl_image.c @@ -96,15 +96,11 @@ evas_gl_common_image_unref(Evas_GL_Image *im) } } -Evas_GL_Image * -evas_gl_common_image_load(Evas_Engine_GL_Context *gc, const char *file, const char *key, Evas_Image_Load_Opts *lo, int *error) +static Evas_GL_Image * +_evas_gl_common_image(Evas_Engine_GL_Context *gc, RGBA_Image *im_im, Evas_Image_Load_Opts *lo, int *error) { - Evas_GL_Image *im; - RGBA_Image *im_im; - Eina_List *l; - - im_im = evas_common_load_image_from_file(file, key, lo, error); - if (!im_im) return NULL; + Evas_GL_Image *im; + Eina_List *l; /* i'd LOVe to do this, but we can't because we load to load header * to get image size to know if its too big or not! so this disallows @@ -151,7 +147,29 @@ evas_gl_common_image_load(Evas_Engine_GL_Context *gc, const char *file, const ch im->h = im->im->cache_entry.h; if (lo) im->load_opts = *lo; gc->shared->images = eina_list_prepend(gc->shared->images, im); - return im; + return im; +} + +Evas_GL_Image * +evas_gl_common_image_load(Evas_Engine_GL_Context *gc, const char *file, const char *key, Evas_Image_Load_Opts *lo, int *error) +{ + RGBA_Image *im_im; + + im_im = evas_common_load_image_from_file(file, key, lo, error); + if (!im_im) return NULL; + + return _evas_gl_common_image(gc, im_im, lo, error); +} + +Evas_GL_Image * +evas_gl_common_image_mmap(Evas_Engine_GL_Context *gc, Eina_File *f, const char *key, Evas_Image_Load_Opts *lo, int *error) +{ + RGBA_Image *im_im; + + im_im = evas_common_load_image_from_mmap(f, key, lo, error); + if (!im_im) return NULL; + + return _evas_gl_common_image(gc, im_im, lo, error); } Evas_GL_Image * diff --git a/src/modules/evas/engines/gl_sdl/evas_engine.c b/src/modules/evas/engines/gl_sdl/evas_engine.c index 18813ee..f055306 100644 --- a/src/modules/evas/engines/gl_sdl/evas_engine.c +++ b/src/modules/evas/engines/gl_sdl/evas_engine.c @@ -486,6 +486,15 @@ eng_image_load(void *data, const char *file, const char *key, int *error, Evas_I } static void * +eng_image_mmap(void *data, Eina_File *f, const char *key, int *error, Evas_Image_Load_Opts *lo) +{ + Render_Engine *re = data; + + *error = EVAS_LOAD_ERROR_NONE; + return evas_gl_common_image_mmap(re->gl_context, f, key, lo, error); +} + +static void * eng_image_new_from_data(void *data, int w, int h, DATA32 *image_data, int alpha, int cspace) { Render_Engine *re = data; @@ -916,6 +925,7 @@ module_open(Evas_Module *em) ORD(polygon_draw); ORD(image_load); + ORD(image_mmap); ORD(image_new_from_data); ORD(image_new_from_copied_data); ORD(image_free); diff --git a/src/modules/evas/engines/gl_x11/evas_engine.c b/src/modules/evas/engines/gl_x11/evas_engine.c index 21f7315..8f374e4 100644 --- a/src/modules/evas/engines/gl_x11/evas_engine.c +++ b/src/modules/evas/engines/gl_x11/evas_engine.c @@ -2438,6 +2438,17 @@ eng_image_load(void *data, const char *file, const char *key, int *error, Evas_I } static void * +eng_image_mmap(void *data, Eina_File *f, const char *key, int *error, Evas_Image_Load_Opts *lo) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + *error = EVAS_LOAD_ERROR_NONE; + eng_window_use(re->win); + return evas_gl_common_image_mmap(re->win->gl_context, f, key, lo, error); +} + +static void * eng_image_new_from_data(void *data, int w, int h, DATA32 *image_data, int alpha, int cspace) { Render_Engine *re; @@ -3335,6 +3346,7 @@ module_open(Evas_Module *em) ORD(polygon_draw); ORD(image_load); + ORD(image_mmap); ORD(image_new_from_data); ORD(image_new_from_copied_data); ORD(image_free); diff --git a/src/modules/evas/engines/software_generic/evas_engine.c b/src/modules/evas/engines/software_generic/evas_engine.c index 45aae29..3e36dd0 100644 --- a/src/modules/evas/engines/software_generic/evas_engine.c +++ b/src/modules/evas/engines/software_generic/evas_engine.c @@ -958,6 +958,26 @@ eng_image_load(void *data EINA_UNUSED, const char *file, const char *key, int *e } static void * +eng_image_mmap(void *data EINA_UNUSED, Eina_File *f, const char *key, int *error, Evas_Image_Load_Opts *lo) +{ + *error = EVAS_LOAD_ERROR_NONE; +#ifdef EVAS_CSERVE2 + // FIXME: Need to pass fd to make that useful, so just get the filename for now. + if (evas_cserve2_use_get()) + { + Image_Entry *ie; + ie = evas_cache2_image_open(evas_common_image_cache2_get(), + eina_file_filename_get(f), key, lo, error); + if (ie) + evas_cache2_image_open_wait(ie); + + return ie; + } +#endif + return evas_common_load_image_from_mmap(f, key, lo, error); +} + +static void * eng_image_new_from_data(void *data EINA_UNUSED, int w, int h, DATA32 *image_data, int alpha, int cspace) { #ifdef EVAS_CSERVE2 @@ -2568,6 +2588,7 @@ static Evas_Func func = eng_polygon_draw, /* image draw funcs */ eng_image_load, + eng_image_mmap, eng_image_new_from_data, eng_image_new_from_copied_data, eng_image_free, -- 2.7.4