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.
ENFN->ector_surface_cache_set(engine, root, buffer);
pd->cached_frame_idx = pd->frame_idx;
}
return buffer;
@ -566,7 +565,6 @@ _cache_vg_entry_render(Evas_Object_Protected_Data *obj,
Vg_Cache_Entry *vg_entry = pd->vg_entry;
Efl_VG *root;
Eina_Position2D offset = {0, 0}; //Offset after keeping aspect ratio.
Eina_Bool drop_cache = EINA_FALSE;
void *buffer = NULL;
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.
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);
evas_cache_vg_entry_del(pd->vg_entry);
pd->vg_entry = vg_entry;
@ -623,20 +624,12 @@ _cache_vg_entry_render(Evas_Object_Protected_Data *obj,
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!
else if (pd->frame_idx == pd->cached_frame_idx)
buffer = ENFN->ector_surface_cache_get(engine, (void *) root);
//Drop invalid one.
else
ENFN->ector_surface_cache_drop(engine, (void *) root);
buffer = ENFN->ector_surface_cache_get(engine, (void *) root);
}
if (!buffer)
buffer = _render_to_buffer(obj, pd, engine, root, w, h, NULL,
do_async, cacheable);
buffer = _render_to_buffer(obj, pd, engine, root, w, h, NULL, do_async, cacheable);
else
//cache reference was increased when we get the cache.
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;
Efl_Canvas_Vg_Fill_Mode fill_mode;
int frame_idx;
int cached_frame_idx;
Eina_Bool changed : 1;
};

View File

@ -1561,7 +1561,6 @@ struct _Vg_File_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 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)
{
loader = em->functions;
vfd = loader->file_open((Eina_File *) file, key, &error);
{
vfd = loader->file_open((Eina_File *) file, key, &error);
}
if (vfd)
{
vfd->loader = loader;
@ -153,18 +155,13 @@ _evas_cache_vg_entry_free_cb(void *data)
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_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_Strbuf *hash_key = eina_strbuf_new();
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);
}
}
@ -235,7 +232,7 @@ _cached_root_get(Vg_Cache_Entry *vg_entry, unsigned int frame_num)
return NULL;
}
static void
static Efl_VG *
_caching_root_update(Vg_Cache_Entry *vg_entry)
{
Vg_File_Data *vfd = vg_entry->vfd;
@ -251,33 +248,31 @@ _caching_root_update(Vg_Cache_Entry *vg_entry)
to this root pointer. */
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]);
vg_entry->root[0] = efl_ref(vfd->root);
}
vg_entry->root[0] = efl_duplicate(vfd->root);
//Animatable?
if (!vfd->anim_data) return;
//Start frame
if (vfd->anim_data->frame_num == 0)
{
if (vg_entry->root[1] != vfd->root)
//Animatable?
if (vfd->anim_data)
{
if (vg_entry->root[1]) efl_unref(vg_entry->root[1]);
vg_entry->root[1] = efl_ref(vfd->root);
}
}
//End frame
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]);
vg_entry->root[2] = efl_ref(vfd->root);
//Start frame
if (vfd->anim_data->frame_num == 0)
{
if (vg_entry->root[1]) efl_unref(vg_entry->root[1]);
vg_entry->root[1] = efl_duplicate(vfd->root);
return vg_entry->root[1];
}
//End frame
else if (vfd->anim_data->frame_num == (vfd->anim_data->frame_cnt - 1))
{
if (vg_entry->root[2]) efl_unref(vg_entry->root[2]);
vg_entry->root[2] = efl_duplicate(vfd->root);
return vg_entry->root[2];
}
}
}
return vg_entry->root[0];
}
static void
@ -351,12 +346,11 @@ evas_cache_vg_file_open(const Eina_File *file, const char *key)
hash_key = eina_strbuf_new();
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->no_share)
if (!vfd)
{
vfd = _vg_load_from_file(file, key);
//File exists.
if (vfd && !vfd->no_share)
eina_hash_add(vg_cache->vfd_hash, eina_strbuf_string_get(hash_key), vfd);
if (vfd) eina_hash_add(vg_cache->vfd_hash, eina_strbuf_string_get(hash_key), vfd);
}
eina_strbuf_free(hash_key);
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;
_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

View File

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