evas vg: improve caching methods for better precise behaviors.

Previously, json file data won't be shared between instances.
Now, objects can share the json data if they use the same file resource.
This commit is contained in:
Hermet Park 2019-11-18 11:48:40 +09:00
parent 98a3dcd94e
commit 618bce8038
5 changed files with 41 additions and 57 deletions

View File

@ -524,7 +524,6 @@ _render_to_buffer(Evas_Object_Protected_Data *obj, Efl_Canvas_Vg_Object_Data *pd
{ {
//Use root as a cache key. //Use root as a cache key.
ENFN->ector_surface_cache_set(engine, root, buffer); ENFN->ector_surface_cache_set(engine, root, buffer);
pd->cached_frame_idx = pd->frame_idx;
} }
return buffer; return buffer;
@ -566,7 +565,6 @@ _cache_vg_entry_render(Evas_Object_Protected_Data *obj,
Vg_Cache_Entry *vg_entry = pd->vg_entry; Vg_Cache_Entry *vg_entry = pd->vg_entry;
Efl_VG *root; Efl_VG *root;
Eina_Position2D offset = {0, 0}; //Offset after keeping aspect ratio. Eina_Position2D offset = {0, 0}; //Offset after keeping aspect ratio.
Eina_Bool drop_cache = EINA_FALSE;
void *buffer = NULL; void *buffer = NULL;
evas_cache_vg_entry_value_provider_update(pd->vg_entry, efl_key_data_get(obj->object, "_vg_value_providers")); evas_cache_vg_entry_value_provider_update(pd->vg_entry, efl_key_data_get(obj->object, "_vg_value_providers"));
@ -603,7 +601,10 @@ _cache_vg_entry_render(Evas_Object_Protected_Data *obj,
//Size is changed, cached data is invalid. //Size is changed, cached data is invalid.
if ((size.w != vg_entry->w) || (size.h != vg_entry->h)) if ((size.w != vg_entry->w) || (size.h != vg_entry->h))
{ {
drop_cache = EINA_TRUE; //if the size doesn't match, drop previous cache surfaces.
ENFN->ector_surface_cache_drop(engine, (void *) vg_entry->root[1]);
ENFN->ector_surface_cache_drop(engine, (void *) vg_entry->root[2]);
vg_entry = evas_cache_vg_entry_resize(vg_entry, size.w, size.h); vg_entry = evas_cache_vg_entry_resize(vg_entry, size.w, size.h);
evas_cache_vg_entry_del(pd->vg_entry); evas_cache_vg_entry_del(pd->vg_entry);
pd->vg_entry = vg_entry; pd->vg_entry = vg_entry;
@ -623,20 +624,12 @@ _cache_vg_entry_render(Evas_Object_Protected_Data *obj,
if (cacheable) if (cacheable)
{ {
//if the size doesn't match, drop previous cache surface.
if (drop_cache)
ENFN->ector_surface_cache_drop(engine, (void *) root);
//Cache Hit! //Cache Hit!
else if (pd->frame_idx == pd->cached_frame_idx)
buffer = ENFN->ector_surface_cache_get(engine, (void *) root); buffer = ENFN->ector_surface_cache_get(engine, (void *) root);
//Drop invalid one.
else
ENFN->ector_surface_cache_drop(engine, (void *) root);
} }
if (!buffer) if (!buffer)
buffer = _render_to_buffer(obj, pd, engine, root, w, h, NULL, buffer = _render_to_buffer(obj, pd, engine, root, w, h, NULL, do_async, cacheable);
do_async, cacheable);
else else
//cache reference was increased when we get the cache. //cache reference was increased when we get the cache.
ENFN->ector_surface_cache_drop(engine, (void *) root); ENFN->ector_surface_cache_drop(engine, (void *) root);

View File

@ -52,7 +52,6 @@ struct _Efl_Canvas_Vg_Object_Data
double align_x, align_y; double align_x, align_y;
Efl_Canvas_Vg_Fill_Mode fill_mode; Efl_Canvas_Vg_Fill_Mode fill_mode;
int frame_idx; int frame_idx;
int cached_frame_idx;
Eina_Bool changed : 1; Eina_Bool changed : 1;
}; };

View File

@ -1561,7 +1561,6 @@ struct _Vg_File_Data
void *loader_data; //loader specific local data void *loader_data; //loader specific local data
Eina_Bool no_share : 1; //Shareable VFD through multiple file open requests.
Eina_Bool static_viewbox: 1; Eina_Bool static_viewbox: 1;
Eina_Bool preserve_aspect : 1; //Used in SVG Eina_Bool preserve_aspect : 1; //Used in SVG
}; };

View File

@ -83,7 +83,9 @@ _vg_load_from_file(const Eina_File *file, const char *key)
if (em) if (em)
{ {
loader = em->functions; loader = em->functions;
{
vfd = loader->file_open((Eina_File *) file, key, &error); vfd = loader->file_open((Eina_File *) file, key, &error);
}
if (vfd) if (vfd)
{ {
vfd->loader = loader; vfd->loader = loader;
@ -152,10 +154,6 @@ _evas_cache_vg_entry_free_cb(void *data)
vg_entry->vfd->ref--; vg_entry->vfd->ref--;
if (vg_entry->vfd->ref <= 0) if (vg_entry->vfd->ref <= 0)
{
if (vg_entry->vfd->no_share)
vg_entry->vfd->loader->file_close(vg_entry->vfd);
else
{ {
Eina_Strbuf *hash_key = eina_strbuf_new(); Eina_Strbuf *hash_key = eina_strbuf_new();
eina_strbuf_append_printf(hash_key, "%s/%s", eina_strbuf_append_printf(hash_key, "%s/%s",
@ -166,7 +164,6 @@ _evas_cache_vg_entry_free_cb(void *data)
eina_strbuf_free(hash_key); eina_strbuf_free(hash_key);
} }
} }
}
eina_stringshare_del(vg_entry->key); eina_stringshare_del(vg_entry->key);
free(vg_entry->hash_key); free(vg_entry->hash_key);
@ -235,7 +232,7 @@ _cached_root_get(Vg_Cache_Entry *vg_entry, unsigned int frame_num)
return NULL; return NULL;
} }
static void static Efl_VG *
_caching_root_update(Vg_Cache_Entry *vg_entry) _caching_root_update(Vg_Cache_Entry *vg_entry)
{ {
Vg_File_Data *vfd = vg_entry->vfd; Vg_File_Data *vfd = vg_entry->vfd;
@ -251,33 +248,31 @@ _caching_root_update(Vg_Cache_Entry *vg_entry)
to this root pointer. */ to this root pointer. */
vg_entry->root[0] = efl_duplicate(vfd->root); vg_entry->root[0] = efl_duplicate(vfd->root);
} }
else if (vg_entry->root[0] != vfd->root) else
{ {
if (vg_entry->root[0]) efl_unref(vg_entry->root[0]); if (vg_entry->root[0]) efl_unref(vg_entry->root[0]);
vg_entry->root[0] = efl_ref(vfd->root); vg_entry->root[0] = efl_duplicate(vfd->root);
}
//Animatable? //Animatable?
if (!vfd->anim_data) return; if (vfd->anim_data)
{
//Start frame //Start frame
if (vfd->anim_data->frame_num == 0) if (vfd->anim_data->frame_num == 0)
{
if (vg_entry->root[1] != vfd->root)
{ {
if (vg_entry->root[1]) efl_unref(vg_entry->root[1]); if (vg_entry->root[1]) efl_unref(vg_entry->root[1]);
vg_entry->root[1] = efl_ref(vfd->root); vg_entry->root[1] = efl_duplicate(vfd->root);
} return vg_entry->root[1];
} }
//End frame //End frame
else if (vfd->anim_data->frame_num == (vfd->anim_data->frame_cnt - 1)) else if (vfd->anim_data->frame_num == (vfd->anim_data->frame_cnt - 1))
{
if (vg_entry->root[2] != vfd->root)
{ {
if (vg_entry->root[2]) efl_unref(vg_entry->root[2]); if (vg_entry->root[2]) efl_unref(vg_entry->root[2]);
vg_entry->root[2] = efl_ref(vfd->root); vg_entry->root[2] = efl_duplicate(vfd->root);
return vg_entry->root[2];
} }
} }
}
return vg_entry->root[0];
} }
static void static void
@ -351,12 +346,11 @@ evas_cache_vg_file_open(const Eina_File *file, const char *key)
hash_key = eina_strbuf_new(); hash_key = eina_strbuf_new();
eina_strbuf_append_printf(hash_key, "%s/%s", eina_file_filename_get(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)); vfd = eina_hash_find(vg_cache->vfd_hash, eina_strbuf_string_get(hash_key));
if (!vfd || vfd->no_share) if (!vfd)
{ {
vfd = _vg_load_from_file(file, key); vfd = _vg_load_from_file(file, key);
//File exists. //File exists.
if (vfd && !vfd->no_share) if (vfd) eina_hash_add(vg_cache->vfd_hash, eina_strbuf_string_get(hash_key), vfd);
eina_hash_add(vg_cache->vfd_hash, eina_strbuf_string_get(hash_key), vfd);
} }
eina_strbuf_free(hash_key); eina_strbuf_free(hash_key);
return vfd; return vfd;
@ -507,11 +501,11 @@ evas_cache_vg_tree_get(Vg_Cache_Entry *vg_entry, unsigned int frame_num)
if (!vfd->loader->file_data(vfd)) return NULL; if (!vfd->loader->file_data(vfd)) return NULL;
_caching_root_update(vg_entry); root = _caching_root_update(vg_entry);
_local_transform(vg_entry->root[0], vg_entry->w, vg_entry->h, vfd); _local_transform(root, vg_entry->w, vg_entry->h, vfd);
return vg_entry->root[0]; return root;
} }
void void

View File

@ -103,7 +103,6 @@ evas_vg_load_file_open_json(Eina_File *file,
vfd->h = (int) h; vfd->h = (int) h;
vfd->loader_data = (void *) lot_anim; vfd->loader_data = (void *) lot_anim;
vfd->no_share = EINA_TRUE;
return vfd; return vfd;