evas json: support efl_canvas_vg_file_mmap_set() - #11 63/189163/1
authorHermet Park <hermetpark@gmail.com>
Tue, 11 Sep 2018 11:49:17 +0000 (20:49 +0900)
committerHermet Park <hermetpark@gmail.com>
Fri, 14 Sep 2018 02:28:46 +0000 (11:28 +0900)
example)
...
Eina_File *file = eina_file_virtualize(NULL, data, strlen(data), EINA_TRUE);
eina_file_mmap_set(vg, file, key);
...
eina_file_close(file);

@feature

Change-Id: I4ccfa1dc46f274e0d4838b5dccee58126802743a

src/lib/evas/canvas/efl_canvas_vg.c
src/lib/evas/canvas/efl_canvas_vg.eo
src/lib/evas/canvas/evas_vg_private.h
src/lib/evas/include/evas_private.h
src/lib/evas/vg/evas_vg_cache.c
src/modules/evas/vg_loaders/eet/evas_vg_load_eet.c
src/modules/evas/vg_loaders/json/evas_vg_load_json.c
src/modules/evas/vg_loaders/svg/evas_vg_load_svg.c

index cc9bb63..aa6474d 100644 (file)
@@ -254,18 +254,24 @@ _efl_canvas_vg_viewbox_align_get(const Eo *obj EINA_UNUSED, Efl_Canvas_Vg_Data *
    if (align_y) *align_y = pd->align_y;
 }
 
-EOLIAN static Eina_Bool
-_efl_canvas_vg_efl_file_file_set(Eo *eo_obj, Efl_Canvas_Vg_Data *pd, const char *file, const char *key)
+static Eina_Bool
+_vg_file_mmap_set(Eo *eo_obj, Efl_Canvas_Vg_Data *pd, const Eina_File *file, const char *key, Eina_Bool mmap)
 {
    Vg_Cache_Entry *old_entry;
    Evas_Object_Protected_Data *obj;
 
-   if (!file) return EINA_FALSE;
-
    obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
+
    old_entry = pd->vg_entry;
-   pd->vg_entry = evas_cache_vg_entry_create(file, key, obj->cur->geometry.w, obj->cur->geometry.h);
-//   if (pd->vg_entry != old_entry) evas_object_change(eo_obj, obj);
+
+   if (file)
+     pd->vg_entry = evas_cache_vg_entry_create(file, key,
+                                               obj->cur->geometry.w,
+                                               obj->cur->geometry.h,
+                                               mmap);
+   else
+     pd->vg_entry = NULL;
+
    evas_object_change(eo_obj, obj);
    evas_cache_vg_entry_del(old_entry);
 
@@ -273,15 +279,104 @@ _efl_canvas_vg_efl_file_file_set(Eo *eo_obj, Efl_Canvas_Vg_Data *pd, const char
 }
 
 EOLIAN static void
-_efl_canvas_vg_efl_file_file_get(const Eo *obj EINA_UNUSED, Efl_Canvas_Vg_Data *pd, const char **file, const char **key)
+_efl_canvas_vg_efl_file_mmap_get(const Eo *eo_obj EINA_UNUSED,
+                                 Efl_Canvas_Vg_Data *pd,
+                                 const Eina_File **file, const char **key)
 {
-   *file = NULL;
-   *key = NULL;
+   if (file) *file = NULL;
+   if (key) *key = NULL;
 
    if (pd->vg_entry)
      {
         if (file) *file = pd->vg_entry->file;
-        if (key)  *key = pd->vg_entry->key;
+        if (key) *key = pd->vg_entry->key;
+     }
+}
+
+EOLIAN static Eina_Bool
+_efl_canvas_vg_efl_file_mmap_set(Eo *eo_obj, Efl_Canvas_Vg_Data *pd, const Eina_File *file, const char *key)
+{
+   if (!file)
+     {
+        Evas_Object_Protected_Data *obj;
+        obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
+        evas_cache_vg_entry_del(pd->vg_entry);
+        evas_object_change(eo_obj, obj);
+        eina_file_close(pd->file);
+        eina_stringshare_del(pd->key);
+        pd->vg_entry = NULL;
+        pd->file = NULL;
+        pd->key = NULL;
+        return EINA_TRUE;
+     }
+   if (pd->file == file)
+     {
+        if (!pd->key && !key) return EINA_FALSE;
+        else if (pd->key && key)
+          {
+             if (!strcmp(pd->key, key)) return EINA_FALSE;
+          }
+     }
+   if (pd->file != file)
+     {
+        eina_file_close(pd->file);
+        pd->file = eina_file_dup(file);
+     }
+   return _vg_file_mmap_set(eo_obj, pd, file, key, EINA_TRUE);
+}
+
+EOLIAN static Eina_Bool
+_efl_canvas_vg_efl_file_file_set(Eo *eo_obj, Efl_Canvas_Vg_Data *pd, const char *file, const char *key)
+{
+   if (!file)
+     {
+        Evas_Object_Protected_Data *obj;
+        obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
+        evas_cache_vg_entry_del(pd->vg_entry);
+        evas_object_change(eo_obj, obj);
+        eina_file_close(pd->file);
+        eina_stringshare_del(pd->key);
+        pd->vg_entry = NULL;
+        pd->file = NULL;
+        pd->key = NULL;
+        return EINA_TRUE;
+     }
+   if (!pd->file) pd->file = eina_file_open(file, EINA_FALSE);
+   else
+     {
+        const char *filename = eina_file_filename_get(pd->file);
+        if (filename)
+          {
+             if (strcmp(filename, file))
+               {
+                  eina_file_close(pd->file);
+                  pd->file = eina_file_open(file, EINA_FALSE);
+               }
+             else
+               {
+                  if (!pd->key && !key) return EINA_FALSE;
+                  else if (pd->key && key)
+                    {
+                       if (!strcmp(pd->key, key)) return EINA_FALSE;
+                    }
+               }
+          }
+     }
+
+   Eina_Bool ret = _vg_file_mmap_set(eo_obj, pd, pd->file, key, EINA_FALSE);
+   return ret;
+}
+
+EOLIAN static void
+_efl_canvas_vg_efl_file_file_get(const Eo *obj EINA_UNUSED, Efl_Canvas_Vg_Data *pd, const char **file, const char **key)
+{
+   if (file) *file = NULL;
+   if (key) *key = NULL;
+
+   if (pd->vg_entry)
+     {
+        if (file) *file = eina_file_filename_get(pd->vg_entry->file);
+        if (key) *key = pd->vg_entry->key;
      }
 }
 
@@ -289,22 +384,22 @@ EOLIAN static Eina_Bool
 _efl_canvas_vg_efl_file_save(const Eo *obj, Efl_Canvas_Vg_Data *pd, const char *file, const char *key, const char *flags)
 {
    Vg_File_Data tmp = {};
-   Vg_File_Data *info = &tmp;
+   Vg_File_Data *vfd = &tmp;
 
-   if (pd->vg_entry && pd->vg_entry->file)
+   if (pd->vg_entry)
      {
         //TODO: Necessary file open?
-        info = evas_cache_vg_file_open(pd->vg_entry->file, pd->vg_entry->key);
+        vfd = evas_cache_vg_file_open(pd->vg_entry->file, pd->vg_entry->key, EINA_FALSE);
      }
    else
      {
-        info->view_box.x = 0;
-        info->view_box.y = 0;
-        evas_object_geometry_get(obj, NULL, NULL, &info->view_box.w, &info->view_box.h);
-        info->root = pd->root;
-        info->preserve_aspect = EINA_FALSE;
+        vfd->view_box.x = 0;
+        vfd->view_box.y = 0;
+        evas_object_geometry_get(obj, NULL, NULL, &vfd->view_box.w, &vfd->view_box.h);
+        vfd->root = pd->root;
+        vfd->preserve_aspect = EINA_FALSE;
      }
-   return evas_cache_vg_file_save(info, file, key, flags);
+   return evas_cache_vg_file_save(vfd, file, key, flags);
 }
 
 static void
@@ -330,9 +425,20 @@ _efl_canvas_vg_efl_object_destructor(Eo *eo_obj, Efl_Canvas_Vg_Data *pd)
 
    if (pd->user_entry) free(pd->user_entry);
    pd->user_entry = NULL;
-
    evas_cache_vg_entry_del(pd->vg_entry);
 
+   //Close files after deleting entry.
+   if (pd->file)
+     {
+        eina_file_close(pd->file);
+        pd->file = NULL;
+     }
+   if (pd->key)
+     {
+        eina_stringshare_del(pd->key);
+        pd->key = NULL;
+     }
+
    efl_destructor(efl_super(eo_obj, MY_CLASS));
 }
 
@@ -376,6 +482,8 @@ _evas_vg_render(Evas_Object_Protected_Data *obj, Efl_Canvas_Vg_Data *pd,
                 void *engine, void *output, void *context, void *surface, Efl_VG *n,
                 Eina_Array *clips, Eina_Bool do_async)
 {
+   if (!pd->file) return;
+
    if (efl_isa(n, EFL_CANVAS_VG_CONTAINER_CLASS))
      {
         Efl_Canvas_Vg_Container_Data *vc;
@@ -492,7 +600,7 @@ _cache_vg_entry_render(Evas_Object_Protected_Data *obj,
    if ((vg_entry->w != w) ||
        (vg_entry->h != h))
      {
-         vg_entry = evas_cache_vg_entry_create(vg_entry->file, vg_entry->key, w, h);
+         vg_entry = evas_cache_vg_entry_resize(vg_entry, w, h);
          evas_cache_vg_entry_del(pd->vg_entry);
          pd->vg_entry = vg_entry;
      }
index 370bf76..9424231 100644 (file)
@@ -73,7 +73,7 @@ class Efl.Canvas.Vg (Efl.Canvas.Object, Efl.File, Efl.Gfx.Image_Animation_Contro
       Efl.Object.constructor;
       Efl.Object.finalize;
       Efl.Object.destructor;
-      // FIXME: Implement mmap only (also fix cache keys)
+      Efl.File.mmap { get; set; }
       Efl.File.file { get; set; }
       Efl.File.save;
       Efl.Gfx.Image_Animation_Controller.animated { get; }
index 32ac8db..4095920 100644 (file)
@@ -19,13 +19,15 @@ typedef struct _Vg_Cache
 typedef struct _Vg_Cache_Entry
 {
    char                 *hash_key;
-   Eina_Stringshare     *file;
+   const Eina_File      *file;
    Eina_Stringshare     *key;
    int                   w;
    int                   h;
    Efl_VG               *root;
    int                   ref;
    Vg_File_Data         *vfd;
+
+   Eina_Bool             mmap : 1;
 } Vg_Cache_Entry;
 
 // holds the vg tree info set by the user
@@ -49,7 +51,8 @@ struct _Efl_Canvas_Vg_Data
    double                     align_x, align_y;
    Efl_Canvas_Vg_Fill_Mode    fill_mode;
    int                        frame_index;
-
+   Eina_File                 *file;
+   Eina_Stringshare          *key;
 
    Eina_Bool                  changed : 1;
 };
@@ -104,10 +107,11 @@ struct _Efl_Canvas_Vg_Interpolation
 
 void                        evas_cache_vg_init(void);
 void                        evas_cache_vg_shutdown(void);
-Vg_Cache_Entry*  evas_cache_vg_entry_create(const char *file, const char *key, int w, int h);
+Vg_Cache_Entry*             evas_cache_vg_entry_resize(Vg_Cache_Entry *entry, int w, int h);
+Vg_Cache_Entry*             evas_cache_vg_entry_create(const Eina_File *file, const char *key, int w, int h, Eina_Bool mmap);
 Efl_VG*                     evas_cache_vg_tree_get(Vg_Cache_Entry *vg_entry, unsigned int frame_num);
 void                        evas_cache_vg_entry_del(Vg_Cache_Entry *vg_entry);
-Vg_File_Data *              evas_cache_vg_file_open(const char *file, const char *key);
+Vg_File_Data *              evas_cache_vg_file_open(const Eina_File *file, const char *key, Eina_Bool mmap);
 Eina_Bool                   evas_cache_vg_file_save(Vg_File_Data *vfd, const char *file, const char *key, const char *flags);
 double                      evas_cache_vg_anim_duration_get(const Vg_Cache_Entry *vg_entry);
 unsigned int                evas_cache_vg_anim_frame_count_get(const Vg_Cache_Entry *vg_entry);
index 90f0ca3..e296bcd 100755 (executable)
@@ -1548,7 +1548,7 @@ struct _Vg_File_Data
 
 struct _Evas_Vg_Load_Func
 {
-   Vg_File_Data *(*file_open) (const char *file, const char *key, int *error);
+   Vg_File_Data *(*file_open) (Eina_File *file, const char *key, Eina_Bool mmap, int *error);
    Eina_Bool (*file_close) (Vg_File_Data *vfd);
    Eina_Bool (*file_data) (Vg_File_Data *vfd);
 };
index 180c816..ab1d4ee 100644 (file)
@@ -70,20 +70,25 @@ _find_loader_module(const char *file)
 }
 
 static Vg_File_Data *
-_vg_load_from_file(const char *file, const char *key)
+_vg_load_from_file(const Eina_File *file, const char *key, Eina_Bool mmap)
 {
-   Evas_Module      *em;
+   Evas_Module       *em;
    Evas_Vg_Load_Func *loader;
    int                error = EVAS_LOAD_ERROR_GENERIC;
-   Vg_File_Data          *vfd;
+   Vg_File_Data      *vfd;
    unsigned int i;
-   em = _find_loader_module(file);
+
+   const char *file_name = eina_file_filename_get(file);
+   em = _find_loader_module(file_name);
    if (em)
      {
         loader = em->functions;
-        vfd = loader->file_open(file, key, &error);
-        vfd->loader = loader;
-        return vfd;
+        vfd = loader->file_open((Eina_File *) file, key, mmap, &error);
+        if (vfd)
+          {
+             vfd->loader = loader;
+             return vfd;
+          }
      }
    else
      {
@@ -93,7 +98,7 @@ _vg_load_from_file(const char *file, const char *key)
              if (em)
                {
                   loader = em->functions;
-                  vfd = loader->file_open(file, key, &error);
+                  vfd = loader->file_open((Eina_File *) file, key, mmap, &error);
                   if (vfd)
                     {
                        vfd->loader = loader;
@@ -102,7 +107,7 @@ _vg_load_from_file(const char *file, const char *key)
                }
           }
      }
-   WRN("Exhausted all means to load vector file = %s", file);
+   WRN("Exhausted all means to load vector file = %s", file_name);
    return NULL;
 }
 
@@ -149,14 +154,15 @@ _evas_cache_vg_entry_free_cb(void *data)
         if (vg_entry->vfd->ref <= 0)
           {
              Eina_Strbuf *hash_key = eina_strbuf_new();
-             eina_strbuf_append_printf(hash_key, "%s/%s", vg_entry->file, vg_entry->key);
+             eina_strbuf_append_printf(hash_key, "%s/%s",
+                                       eina_file_filename_get(vg_entry->file),
+                                       vg_entry->key);
              if (!eina_hash_del(vg_cache->vfd_hash, eina_strbuf_string_get(hash_key), vg_entry->vfd))
                ERR("Failed to delete vfd = (%p) from hash", vg_entry->vfd);
              eina_strbuf_free(hash_key);
           }
      }
 
-   eina_stringshare_del(vg_entry->file);
    eina_stringshare_del(vg_entry->key);
    free(vg_entry->hash_key);
    efl_unref(vg_entry->root);
@@ -223,17 +229,17 @@ _apply_transformation(Efl_VG *root, double w, double h, Vg_File_Data *vg_data)
 }
 
 Vg_File_Data *
-evas_cache_vg_file_open(const char *file, const char *key)
+evas_cache_vg_file_open(const Eina_File *file, const char *key, Eina_Bool mmap)
 {
    Vg_File_Data *vfd;
    Eina_Strbuf *hash_key;
 
    hash_key = eina_strbuf_new();
-   eina_strbuf_append_printf(hash_key, "%s/%s", file, key);
+   eina_strbuf_append_printf(hash_key, "%s/%s", eina_file_filename_get(file), key);
    vfd = eina_hash_find(vg_cache->vfd_hash, eina_strbuf_string_get(hash_key));
    if (!vfd)
      {
-        vfd = _vg_load_from_file(file, key);
+        vfd = _vg_load_from_file(file, key, mmap);
         //File is exists.
         if (vfd) eina_hash_add(vg_cache->vfd_hash, eina_strbuf_string_get(hash_key), vfd);
      }
@@ -242,9 +248,16 @@ evas_cache_vg_file_open(const char *file, const char *key)
 }
 
 Vg_Cache_Entry*
-evas_cache_vg_entry_create(const char *file,
+evas_cache_vg_entry_resize(Vg_Cache_Entry *vg_entry, int w, int h)
+{
+   return evas_cache_vg_entry_create(vg_entry->file, vg_entry->key, w, h, vg_entry->mmap);
+}
+
+Vg_Cache_Entry*
+evas_cache_vg_entry_create(const Eina_File *file,
                            const char *key,
-                           int w, int h)
+                           int w, int h,
+                           Eina_Bool mmap)
 {
    Vg_Cache_Entry* vg_entry;
    Eina_Strbuf *hash_key;
@@ -254,23 +267,23 @@ evas_cache_vg_entry_create(const char *file,
    //TODO: zero-sized entry is useless. how to skip it?
 
    hash_key = eina_strbuf_new();
-   eina_strbuf_append_printf(hash_key, "%s/%s/%d/%d",
-                             file, key, w, h);
+   eina_strbuf_append_printf(hash_key, "%p/%s/%d/%d", file, key, w, h);
    vg_entry = eina_hash_find(vg_cache->vg_entry_hash, eina_strbuf_string_get(hash_key));
    if (!vg_entry)
      {
         vg_entry = calloc(1, sizeof(Vg_Cache_Entry));
-        vg_entry->file = eina_stringshare_add(file);
+        vg_entry->file = file;
         vg_entry->key = eina_stringshare_add(key);
         vg_entry->w = w;
         vg_entry->h = h;
         vg_entry->hash_key = eina_strbuf_string_steal(hash_key);
+        vg_entry->mmap = mmap;
         eina_hash_direct_add(vg_cache->vg_entry_hash, vg_entry->hash_key, vg_entry);
      }
    eina_strbuf_free(hash_key);
    vg_entry->ref++;
 
-   vg_entry->vfd = evas_cache_vg_file_open(file, key);
+   vg_entry->vfd = evas_cache_vg_file_open(file, key, mmap);
    //No File??
    if (!vg_entry->vfd)
      {
index 3b83b2f..4f40819 100644 (file)
@@ -13,13 +13,11 @@ static int _evas_vg_loader_eet_log_dom = -1;
 #define INF(...) EINA_LOG_DOM_INFO(_evas_vg_loader_eet_log_dom, __VA_ARGS__)
 
 static Vg_File_Data*
-evas_vg_load_file_open_eet(const char *file, const char *key, int *error EINA_UNUSED)
+evas_vg_load_file_open_eet(Eina_File *file, const char *key, Eina_Bool mmap EINA_UNUSED, int *error EINA_UNUSED)
 {
    Eet_Data_Descriptor *svg_node_eet;
    Svg_Node *node;
-   Eet_File *ef;
-
-   ef = eet_open(file, EET_FILE_MODE_READ);
+   Eet_File *ef = eet_mmap(file);
    if (!ef)
      {
         *error = EVAS_LOAD_ERROR_CORRUPT_FILE;
index 1222180..3025645 100644 (file)
@@ -33,14 +33,28 @@ evas_vg_load_file_data_json(Vg_File_Data *vfd)
 }
 
 static Vg_File_Data*
-evas_vg_load_file_open_json(const char *file,
-                            const char *key EINA_UNUSED,
+evas_vg_load_file_open_json(Eina_File *file,
+                            const char *key,
+                            Eina_Bool mmap,
                             int *error EINA_UNUSED)
 {
    Vg_File_Data *vfd = calloc(1, sizeof(Vg_File_Data));
    if (!vfd) return NULL;
 
-   Lottie_Animation *lot_anim = lottie_animation_from_file(file);
+   Lottie_Animation *lot_anim = NULL;
+
+   if (mmap)
+     {
+        const char *data = (const char*) eina_file_map_all(file, EINA_FILE_SEQUENTIAL);
+        if (!data) goto err;
+        lot_anim = lottie_animation_from_data(data, key ? key:eina_file_filename_get(file));
+        eina_file_map_free(file, (void *) data);
+     }
+   else
+     {
+        lot_anim = lottie_animation_from_file(eina_file_filename_get(file));
+     }
+
    if (!lot_anim)
      {
         ERR("Failed lottie_animation_from_file");
index 66719d3..2f69336 100644 (file)
@@ -2338,8 +2338,9 @@ evas_vg_load_file_close_svg(Vg_File_Data *vfd EINA_UNUSED)
 }
 
 static Vg_File_Data*
-evas_vg_load_file_open_svg(const char *file,
+evas_vg_load_file_open_svg(Eina_File *file,
                            const char *key EINA_UNUSED,
+                           Eina_Bool mmap EINA_UNUSED,
                            int *error EINA_UNUSED)
 {
    Evas_SVG_Loader loader = {
@@ -2348,18 +2349,10 @@ evas_vg_load_file_open_svg(const char *file,
    const char   *content;
    unsigned int  length;
    Svg_Node     *defs;
-   Eina_File    *f;
-
-   f = eina_file_open(file, EINA_FALSE);
-   if (!f)
-     {
-        *error = EVAS_LOAD_ERROR_CORRUPT_FILE;
-        return NULL;
-     }
 
    loader.svg_parse = calloc(1, sizeof(Evas_SVG_Parser));
-   length = eina_file_size_get(f);
-   content = eina_file_map_all(f, EINA_FILE_SEQUENTIAL);
+   length = eina_file_size_get(file);
+   content = eina_file_map_all(file, EINA_FILE_SEQUENTIAL);
    if (content)
      {
        loader.stack = eina_array_new(8);
@@ -2367,7 +2360,7 @@ evas_vg_load_file_open_svg(const char *file,
                                  _evas_svg_loader_parser, &loader);
 
        eina_array_free(loader.stack);
-       eina_file_map_free(f, (void*) content);
+       eina_file_map_free(file, (void*) content);
      }
 
    if (loader.doc)
@@ -2384,7 +2377,7 @@ evas_vg_load_file_open_svg(const char *file,
         *error = EVAS_LOAD_ERROR_GENERIC;
      }
    free(loader.svg_parse);
-   eina_file_close(f);
+
    return vg_common_svg_create_vg_node(loader.doc);
 }