From aba16a567a2066465f7f2f9c2076c17deee57775 Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Tue, 11 Sep 2018 20:49:17 +0900 Subject: [PATCH] evas json: support efl_canvas_vg_file_mmap_set() - #11 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 | 150 ++++++++++++++++++--- src/lib/evas/canvas/efl_canvas_vg.eo | 2 +- src/lib/evas/canvas/evas_vg_private.h | 12 +- src/lib/evas/include/evas_private.h | 2 +- src/lib/evas/vg/evas_vg_cache.c | 53 +++++--- src/modules/evas/vg_loaders/eet/evas_vg_load_eet.c | 6 +- .../evas/vg_loaders/json/evas_vg_load_json.c | 20 ++- src/modules/evas/vg_loaders/svg/evas_vg_load_svg.c | 19 +-- 8 files changed, 197 insertions(+), 67 deletions(-) diff --git a/src/lib/evas/canvas/efl_canvas_vg.c b/src/lib/evas/canvas/efl_canvas_vg.c index cc9bb63..aa6474d 100644 --- a/src/lib/evas/canvas/efl_canvas_vg.c +++ b/src/lib/evas/canvas/efl_canvas_vg.c @@ -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; } diff --git a/src/lib/evas/canvas/efl_canvas_vg.eo b/src/lib/evas/canvas/efl_canvas_vg.eo index 370bf76..9424231 100644 --- a/src/lib/evas/canvas/efl_canvas_vg.eo +++ b/src/lib/evas/canvas/efl_canvas_vg.eo @@ -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; } diff --git a/src/lib/evas/canvas/evas_vg_private.h b/src/lib/evas/canvas/evas_vg_private.h index 32ac8db..4095920 100644 --- a/src/lib/evas/canvas/evas_vg_private.h +++ b/src/lib/evas/canvas/evas_vg_private.h @@ -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); diff --git a/src/lib/evas/include/evas_private.h b/src/lib/evas/include/evas_private.h index 90f0ca39..e296bcd 100755 --- a/src/lib/evas/include/evas_private.h +++ b/src/lib/evas/include/evas_private.h @@ -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); }; diff --git a/src/lib/evas/vg/evas_vg_cache.c b/src/lib/evas/vg/evas_vg_cache.c index 180c816..ab1d4ee 100644 --- a/src/lib/evas/vg/evas_vg_cache.c +++ b/src/lib/evas/vg/evas_vg_cache.c @@ -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) { diff --git a/src/modules/evas/vg_loaders/eet/evas_vg_load_eet.c b/src/modules/evas/vg_loaders/eet/evas_vg_load_eet.c index 3b83b2f..4f40819 100644 --- a/src/modules/evas/vg_loaders/eet/evas_vg_load_eet.c +++ b/src/modules/evas/vg_loaders/eet/evas_vg_load_eet.c @@ -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; diff --git a/src/modules/evas/vg_loaders/json/evas_vg_load_json.c b/src/modules/evas/vg_loaders/json/evas_vg_load_json.c index 1222180..3025645 100644 --- a/src/modules/evas/vg_loaders/json/evas_vg_load_json.c +++ b/src/modules/evas/vg_loaders/json/evas_vg_load_json.c @@ -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"); diff --git a/src/modules/evas/vg_loaders/svg/evas_vg_load_svg.c b/src/modules/evas/vg_loaders/svg/evas_vg_load_svg.c index 66719d3..2f69336 100644 --- a/src/modules/evas/vg_loaders/svg/evas_vg_load_svg.c +++ b/src/modules/evas/vg_loaders/svg/evas_vg_load_svg.c @@ -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); } -- 2.7.4