evas: add infrastructure to open from Eina_File.
authorCedric Bail <cedric.bail@samsung.com>
Wed, 8 May 2013 06:37:37 +0000 (15:37 +0900)
committerCedric Bail <cedric.bail@samsung.com>
Wed, 8 May 2013 09:17:00 +0000 (18:17 +0900)
16 files changed:
src/lib/evas/Evas_Eo.h
src/lib/evas/Evas_Legacy.h
src/lib/evas/cache/evas_cache.h
src/lib/evas/cache/evas_cache_image.c
src/lib/evas/canvas/evas_object_image.c
src/lib/evas/common/evas_image.h
src/lib/evas/common/evas_image_load.c
src/lib/evas/common/evas_image_main.c
src/lib/evas/include/evas_common.h
src/lib/evas/include/evas_private.h
src/modules/evas/engines/gl_cocoa/evas_engine.c
src/modules/evas/engines/gl_common/evas_gl_common.h
src/modules/evas/engines/gl_common/evas_gl_image.c
src/modules/evas/engines/gl_sdl/evas_engine.c
src/modules/evas/engines/gl_x11/evas_engine.c
src/modules/evas/engines/software_generic/evas_engine.c

index 83c6540..8345981 100644 (file)
@@ -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
  *
index fd69a83..8456900 100644 (file)
@@ -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).
  *
index 8fca866..b7756ae 100644 (file)
@@ -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);
index 6765f6b..1dc13d9 100644 (file)
@@ -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;
index 3bc4cef..864d5f2 100644 (file)
@@ -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."),
index 79f1a29..3ea2f22 100644 (file)
@@ -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);
index a505bc9..cb03c7a 100644 (file)
@@ -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 : "<UNKNOWN>", 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 : "<UNKNOWN>",
-       ie->file);
+       file);
 
    ie->info.module = (void*) em;
    ie->info.loader = (void*) em ? em->functions : NULL;
index 8a7e21f..3d9972a 100644 (file)
@@ -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)
 {
index 03a2777..4d930dd 100644 (file)
@@ -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
index 82a0211..01a556e 100644 (file)
@@ -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);
index 3614888..b5fc778 100644 (file)
@@ -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);
index e760320..452ab28 100644 (file)
@@ -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);
index b605b75..a8036ad 100644 (file)
@@ -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 *
index 18813ee..f055306 100644 (file)
@@ -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);
index 21f7315..8f374e4 100644 (file)
@@ -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);
index 45aae29..3e36dd0 100644 (file)
@@ -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,