summaryrefslogtreecommitdiff
path: root/src/lib/evas/vg/evas_vg_cache.c
diff options
context:
space:
mode:
authorHermet Park <hermetpark@gmail.com>2019-06-21 17:32:37 +0900
committerHermet Park <hermetpark@gmail.com>2019-06-21 17:35:48 +0900
commit625e11f584fa00c6a2adc160ed20d96f3763d130 (patch)
tree77ad5b58d58583fdea7e5f9ab76d272fb35bf410 /src/lib/evas/vg/evas_vg_cache.c
parent23af6ec640c4166aa912f8d6be1e3b78b0780913 (diff)
evas vector: support lottie animation as using json loader.
Summary: This patch extends efl_canvas_vg_object class to implement efl_gfx_frame_controller to suppor any playable animation on it. Plus, vector object takes care of lottie animation by using json loader. it's caching mechanism is changed to cache only static frame, not all frames. vg_cache supports json loader and make it animation request properly. This feature has been stabilized enough, it's using in Samsung Galaxy Watch active product, proved its stability enough. Depends on {D8940} Co-authored-by: JunsuChoi <jsuya.choi@samsung.com> Reviewers: #committers, jsuya Subscribers: cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D8941
Diffstat (limited to 'src/lib/evas/vg/evas_vg_cache.c')
-rw-r--r--src/lib/evas/vg/evas_vg_cache.c125
1 files changed, 104 insertions, 21 deletions
diff --git a/src/lib/evas/vg/evas_vg_cache.c b/src/lib/evas/vg/evas_vg_cache.c
index 534dca2748..dd85349ee9 100644
--- a/src/lib/evas/vg/evas_vg_cache.c
+++ b/src/lib/evas/vg/evas_vg_cache.c
@@ -35,7 +35,7 @@ static const struct ext_loader_s loaders[] =
35 35
36static const char *loaders_name[] = 36static const char *loaders_name[] =
37{ /* in order of most likely needed */ 37{ /* in order of most likely needed */
38 "eet", "svg" 38 "eet", "json", "svg"
39}; 39};
40 40
41static const struct ext_saver_s savers[] = 41static const struct ext_saver_s savers[] =
@@ -153,19 +153,26 @@ _evas_cache_vg_entry_free_cb(void *data)
153 153
154 if (vg_entry->vfd->ref <= 0) 154 if (vg_entry->vfd->ref <= 0)
155 { 155 {
156 Eina_Strbuf *hash_key = eina_strbuf_new(); 156 if (vg_entry->vfd->no_share)
157 eina_strbuf_append_printf(hash_key, "%s/%s", 157 vg_entry->vfd->loader->file_close(vg_entry->vfd);
158 eina_file_filename_get(vg_entry->file), 158 else
159 vg_entry->key); 159 {
160 if (!eina_hash_del(vg_cache->vfd_hash, eina_strbuf_string_get(hash_key), vg_entry->vfd)) 160 Eina_Strbuf *hash_key = eina_strbuf_new();
161 ERR("Failed to delete vfd = (%p) from hash", vg_entry->vfd); 161 eina_strbuf_append_printf(hash_key, "%s/%s",
162 eina_strbuf_free(hash_key); 162 eina_file_filename_get(vg_entry->file),
163 vg_entry->key);
164 if (!eina_hash_del(vg_cache->vfd_hash, eina_strbuf_string_get(hash_key), vg_entry->vfd))
165 ERR("Failed to delete vfd = (%p) from hash", vg_entry->vfd);
166 eina_strbuf_free(hash_key);
167 }
163 } 168 }
164 } 169 }
165 170
166 eina_stringshare_del(vg_entry->key); 171 eina_stringshare_del(vg_entry->key);
167 free(vg_entry->hash_key); 172 free(vg_entry->hash_key);
168 efl_unref(vg_entry->root); 173 efl_unref(vg_entry->root[0]);
174 efl_unref(vg_entry->root[1]);
175 efl_unref(vg_entry->root[2]);
169 free(vg_entry); 176 free(vg_entry);
170} 177}
171 178
@@ -195,9 +202,37 @@ _vg_file_save(Vg_File_Data *vfd, const char *file, const char *key, const Efl_Fi
195} 202}
196 203
197static Efl_VG* 204static Efl_VG*
198_cached_root_get(Vg_Cache_Entry *vg_entry) 205_cached_root_get(Vg_Cache_Entry *vg_entry, unsigned int frame_num)
199{ 206{
200 return vg_entry->root; 207 Vg_File_Data *vfd = vg_entry->vfd;
208
209 //Case 1: Animatable
210 if (vfd->anim_data)
211 {
212 //Start frame
213 if (vg_entry->root[1] && frame_num == 0)
214 {
215 return vg_entry->root[1];
216 }
217 //End frame
218 else if (vg_entry->root[2] && (frame_num == (vfd->anim_data->frame_cnt - 1)))
219 {
220 return vg_entry->root[2];
221 }
222 //Current frame
223 else if (vg_entry->root[0] && (frame_num == (vfd->anim_data->frame_num)))
224 {
225 return vg_entry->root[0];
226 }
227 }
228 //Case 2: Static
229 else
230 {
231 if (vg_entry->root[0])
232 return vg_entry->root[0];
233 }
234
235 return NULL;
201} 236}
202 237
203static void 238static void
@@ -214,12 +249,34 @@ _caching_root_update(Vg_Cache_Entry *vg_entry)
214 /* TODO: Yet trivial but still we may have a better solution to 249 /* TODO: Yet trivial but still we may have a better solution to
215 avoid this unnecessary copy. If the ector surface key is not 250 avoid this unnecessary copy. If the ector surface key is not
216 to this root pointer. */ 251 to this root pointer. */
217 vg_entry->root = efl_duplicate(vfd->root); 252 vg_entry->root[0] = efl_duplicate(vfd->root);
218 } 253 }
219 else if (vg_entry->root != vfd->root) 254 else if (vg_entry->root[0] != vfd->root)
220 { 255 {
221 if (vg_entry->root) efl_unref(vg_entry->root); 256 if (vg_entry->root[0]) efl_unref(vg_entry->root[0]);
222 vg_entry->root = efl_ref(vfd->root); 257 vg_entry->root[0] = efl_ref(vfd->root);
258 }
259
260 //Animatable?
261 if (!vfd->anim_data) return;
262
263 //Start frame
264 if (vfd->anim_data->frame_num == 0)
265 {
266 if (vg_entry->root[1] != vfd->root)
267 {
268 if (vg_entry->root[1]) efl_unref(vg_entry->root[1]);
269 vg_entry->root[1] = efl_ref(vfd->root);
270 }
271 }
272 //End frame
273 else if (vfd->anim_data->frame_num == (vfd->anim_data->frame_cnt - 1))
274 {
275 if (vg_entry->root[2] != vfd->root)
276 {
277 if (vg_entry->root[2]) efl_unref(vg_entry->root[2]);
278 vg_entry->root[2] = efl_ref(vfd->root);
279 }
223 } 280 }
224} 281}
225 282
@@ -294,11 +351,12 @@ evas_cache_vg_file_open(const Eina_File *file, const char *key)
294 hash_key = eina_strbuf_new(); 351 hash_key = eina_strbuf_new();
295 eina_strbuf_append_printf(hash_key, "%s/%s", eina_file_filename_get(file), key); 352 eina_strbuf_append_printf(hash_key, "%s/%s", eina_file_filename_get(file), key);
296 vfd = eina_hash_find(vg_cache->vfd_hash, eina_strbuf_string_get(hash_key)); 353 vfd = eina_hash_find(vg_cache->vfd_hash, eina_strbuf_string_get(hash_key));
297 if (!vfd) 354 if (!vfd || vfd->no_share)
298 { 355 {
299 vfd = _vg_load_from_file(file, key); 356 vfd = _vg_load_from_file(file, key);
300 //File exists. 357 //File exists.
301 if (vfd) eina_hash_add(vg_cache->vfd_hash, eina_strbuf_string_get(hash_key), vfd); 358 if (vfd && !vfd->no_share)
359 eina_hash_add(vg_cache->vfd_hash, eina_strbuf_string_get(hash_key), vfd);
302 } 360 }
303 eina_strbuf_free(hash_key); 361 eina_strbuf_free(hash_key);
304 return vfd; 362 return vfd;
@@ -356,8 +414,24 @@ evas_cache_vg_entry_create(const Eina_File *file,
356 return vg_entry; 414 return vg_entry;
357} 415}
358 416
417double
418evas_cache_vg_anim_duration_get(const Vg_Cache_Entry* vg_entry)
419{
420 if (!vg_entry->vfd->anim_data) return 0;
421 return vg_entry->vfd->anim_data->duration;
422}
423
424unsigned int
425evas_cache_vg_anim_frame_count_get(const Vg_Cache_Entry* vg_entry)
426{
427 if (!vg_entry) return 0;
428 Vg_File_Data *vfd = vg_entry->vfd;
429 if (!vfd || !vfd->anim_data) return 0;
430 return vfd->anim_data->frame_cnt;
431}
432
359Efl_VG* 433Efl_VG*
360evas_cache_vg_tree_get(Vg_Cache_Entry *vg_entry) 434evas_cache_vg_tree_get(Vg_Cache_Entry *vg_entry, unsigned int frame_num)
361{ 435{
362 if (!vg_entry) return NULL; 436 if (!vg_entry) return NULL;
363 if ((vg_entry->w < 1) || (vg_entry->h < 1)) return NULL; 437 if ((vg_entry->w < 1) || (vg_entry->h < 1)) return NULL;
@@ -365,7 +439,7 @@ evas_cache_vg_tree_get(Vg_Cache_Entry *vg_entry)
365 Vg_File_Data *vfd = vg_entry->vfd; 439 Vg_File_Data *vfd = vg_entry->vfd;
366 if (!vfd) return NULL; 440 if (!vfd) return NULL;
367 441
368 Efl_VG *root = _cached_root_get(vg_entry); 442 Efl_VG *root = _cached_root_get(vg_entry, frame_num);
369 if (root) return root; 443 if (root) return root;
370 444
371 if (!vfd->static_viewbox) 445 if (!vfd->static_viewbox)
@@ -374,13 +448,15 @@ evas_cache_vg_tree_get(Vg_Cache_Entry *vg_entry)
374 vfd->view_box.h = vg_entry->h; 448 vfd->view_box.h = vg_entry->h;
375 } 449 }
376 450
451 if (vfd->anim_data) vfd->anim_data->frame_num = frame_num;
452
377 if (!vfd->loader->file_data(vfd)) return NULL; 453 if (!vfd->loader->file_data(vfd)) return NULL;
378 454
379 _caching_root_update(vg_entry); 455 _caching_root_update(vg_entry);
380 456
381 _local_transform(vg_entry->root, vg_entry->w, vg_entry->h, vfd); 457 _local_transform(vg_entry->root[0], vg_entry->w, vg_entry->h, vfd);
382 458
383 return vg_entry->root; 459 return vg_entry->root[0];
384} 460}
385 461
386void 462void
@@ -393,6 +469,13 @@ evas_cache_vg_entry_del(Vg_Cache_Entry *vg_entry)
393 ERR("Failed to delete vg_entry = (%p) from hash", vg_entry); 469 ERR("Failed to delete vg_entry = (%p) from hash", vg_entry);
394} 470}
395 471
472Eina_Size2D
473evas_cache_vg_entry_default_size_get(const Vg_Cache_Entry *vg_entry)
474{
475 if (!vg_entry) return EINA_SIZE2D(0, 0);
476 return EINA_SIZE2D(vg_entry->vfd->w, vg_entry->vfd->h);
477}
478
396Eina_Bool 479Eina_Bool
397evas_cache_vg_entry_file_save(Vg_Cache_Entry *vg_entry, const char *file, const char *key, const Efl_File_Save_Info *info) 480evas_cache_vg_entry_file_save(Vg_Cache_Entry *vg_entry, const char *file, const char *key, const Efl_File_Save_Info *info)
398{ 481{