evas vg: don't overfull cache size. 21/191021/2
authorHermet Park <hermetpark@gmail.com>
Wed, 10 Oct 2018 12:18:01 +0000 (21:18 +0900)
committerHermet Park <chuneon.park@samsung.com>
Mon, 15 Oct 2018 08:19:23 +0000 (08:19 +0000)
Vg Animation requests a lot of frame surfaces.
On animatation, Previously cache key is not correct,
all vg frames would cached even repeated.

By storing cache key, we do hit cache properly
And let LRU Cache mechanism work over LRU_CACHE_LIMIT.

Change-Id: I066e33597c258109579bd9604c542c6941d2749c

src/lib/evas/canvas/efl_canvas_vg.c
src/lib/evas/canvas/evas_vg_private.h
src/lib/evas/common/evas_common_generic_cache.c

index 677da84..9164c21 100644 (file)
@@ -175,7 +175,7 @@ _efl_canvas_vg_root_node_set(Eo *obj, Efl_Canvas_Vg_Data *pd, Efl_VG *root_node)
         // drop any surface cache attached to it.
         Evas_Object_Protected_Data *eobj = efl_data_scope_get(obj, EFL_CANVAS_OBJECT_CLASS);
         eobj->layer->evas->engine.func->ector_surface_cache_drop(_evas_engine_context(eobj->layer->evas),
-                                                                 pd->user_entry);
+                                                                 pd->cache_key);
         free(pd->user_entry);
         pd->user_entry = NULL;
      }
@@ -567,7 +567,10 @@ _render_to_buffer(Evas_Object_Protected_Data *obj, Efl_Canvas_Vg_Data *pd,
    evas_common_draw_context_free(context);
 
    if (buffer_created)
-     obj->layer->evas->engine.func->ector_surface_cache_set(engine, key, buffer);
+     {
+        pd->cache_key = key;
+        obj->layer->evas->engine.func->ector_surface_cache_set(engine, key, buffer);
+     }
 
    return buffer;
 }
@@ -614,7 +617,7 @@ _cache_vg_entry_render(Evas_Object_Protected_Data *obj,
      }
    root = evas_cache_vg_tree_get(vg_entry, pd->frame_index);
    if (!root) return;
-   buffer = obj->layer->evas->engine.func->ector_surface_cache_get(engine, root);
+   buffer = obj->layer->evas->engine.func->ector_surface_cache_get(engine, pd->cache_key);
 
    // if the buffer is not created yet
    if (!buffer)
@@ -629,7 +632,7 @@ _cache_vg_entry_render(Evas_Object_Protected_Data *obj,
                                    do_async);
      }
    else
-     obj->layer->evas->engine.func->ector_surface_cache_drop(engine, root);
+     obj->layer->evas->engine.func->ector_surface_cache_drop(engine, pd->cache_key);
 
    _render_buffer_to_screen(obj,
                             engine, output, context, surface,
@@ -647,7 +650,7 @@ _user_vg_entry_render(Evas_Object_Protected_Data *obj,
    Vg_User_Entry *user_entry = pd->user_entry;
    void *buffer;
 
-   // if the size dosen't match
+   //if the size dosen't match
    if ((user_entry->w != w ) ||
        (user_entry->h != h))
      {
@@ -656,8 +659,9 @@ _user_vg_entry_render(Evas_Object_Protected_Data *obj,
          user_entry->h = h;
          pd->user_entry = user_entry;
      }
-   // if the buffer is not created yet
-   buffer = obj->layer->evas->engine.func->ector_surface_cache_get(engine, user_entry);
+
+   //if the buffer is not created yet
+   buffer = obj->layer->evas->engine.func->ector_surface_cache_get(engine, pd->cache_key);
    if (!buffer)
      {
         // render to the buffer
@@ -680,7 +684,7 @@ _user_vg_entry_render(Evas_Object_Protected_Data *obj,
                                      user_entry,
                                      buffer,
                                      do_async);
-        obj->layer->evas->engine.func->ector_surface_cache_drop(engine, user_entry);
+        obj->layer->evas->engine.func->ector_surface_cache_drop(engine, pd->cache_key);
      }
 
    _render_buffer_to_screen(obj,
@@ -952,9 +956,10 @@ _efl_canvas_vg_efl_gfx_image_animation_controller_animated_frame_set(Eo *eo_obj,
                                                                      int frame_index)
 {
    //TODO: Validate frame_index range
-
    if (pd->frame_index == frame_index) return EINA_TRUE;
 
+   //Image is changed, drop previous cached image.
+   pd->cache_key = NULL;
    pd->frame_index = frame_index;
    pd->changed = EINA_TRUE;
    evas_object_change(eo_obj, efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS));
index 4095920..94e7eee 100644 (file)
@@ -53,6 +53,7 @@ struct _Efl_Canvas_Vg_Data
    int                        frame_index;
    Eina_File                 *file;
    Eina_Stringshare          *key;
+   void                      *cache_key; // store ector surface cache key
 
    Eina_Bool                  changed : 1;
 };
index 55bcf72..807ed9b 100644 (file)
@@ -1,5 +1,7 @@
 #include "evas_common_private.h"
 
+#define LRU_CACHE_LIMIT 50
+
 EAPI Generic_Cache*
 generic_cache_new(void *user_data, Generic_Cache_Free func)
 {
@@ -46,11 +48,9 @@ generic_cache_data_set(Generic_Cache *cache, void *key, void *surface)
    eina_hash_add(cache->hash, &key, entry);
    cache->lru_list = eina_list_prepend(cache->lru_list, entry);
    count = eina_list_count(cache->lru_list);
-   if (count > 50)
+   if (count > LRU_CACHE_LIMIT)
    {
       entry = eina_list_data_get(eina_list_last(cache->lru_list));
-      // if its still being ref.
-      if (entry->ref) return;
       eina_hash_del(cache->hash, &entry->key, entry);
       cache->lru_list = eina_list_remove_list(cache->lru_list, eina_list_last(cache->lru_list));
       cache->free_func(cache->user_data, entry->data);
@@ -67,9 +67,9 @@ generic_cache_data_get(Generic_Cache *cache, void *key)
    entry =  eina_hash_find(cache->hash, &key);
    if (entry)
      {
-        // update the ref
-        entry->ref += 1;
-        // promote in lru
+        ++entry->ref;
+
+        //promote in lru
         EINA_LIST_FOREACH(cache->lru_list, l, lru_data)
           {
             if (lru_data == entry)
@@ -91,9 +91,8 @@ generic_cache_data_drop(Generic_Cache *cache, void *key)
    entry =  eina_hash_find(cache->hash, &key);
    if (entry)
      {
-        entry->ref -= 1;
-        // if its still being ref.
-        if (entry->ref) return;
+        if (--entry->ref > 0) return;
+
         eina_hash_del(cache->hash, &entry->key, entry);
         // find and remove from lru list
         cache->lru_list = eina_list_remove(cache->lru_list, entry);