evas/engine: refactor the ector surface caching for gl backend 81/94481/4
authorSubhransu Mohanty <sub.mohanty@samsung.com>
Wed, 19 Oct 2016 10:52:27 +0000 (19:52 +0900)
committerGerrit Code Review <gerrit@review.vlan103.tizen.org>
Mon, 31 Oct 2016 10:53:29 +0000 (03:53 -0700)
Change-Id: I14c0b5ac0940471479e35e01b2542ddd13a0c69d

src/Makefile_Evas.am
src/lib/evas/canvas/evas_object_vg.c
src/modules/evas/engines/gl_common/evas_gl_common.h
src/modules/evas/engines/gl_common/evas_gl_surface_cache.c [new file with mode: 0644]
src/modules/evas/engines/gl_drm/evas_engine.c
src/modules/evas/engines/gl_generic/evas_engine.c
src/modules/evas/engines/gl_sdl/evas_engine.c
src/modules/evas/engines/gl_tbm/evas_engine.c
src/modules/evas/engines/gl_x11/evas_engine.c
src/modules/evas/engines/wayland_egl/evas_engine.c

index c513e7f..356c765 100755 (executable)
@@ -700,6 +700,7 @@ modules/evas/engines/gl_common/evas_gl_api_def.h \
 modules/evas/engines/gl_common/evas_gl_api_gles1.c \
 modules/evas/engines/gl_common/evas_gl_api_gles3_def.h \
 modules/evas/engines/gl_common/evas_gl_api_ext.c \
+modules/evas/engines/gl_common/evas_gl_surface_cache.c \
 modules/evas/engines/gl_common/shader/evas_gl_shaders.x \
 modules/evas/engines/gl_common/shader_3d/evas_gl_3d_shaders.x \
 $(NULL)
index a885103..ba08f13 100644 (file)
@@ -226,12 +226,12 @@ _svg_data_render(Evas_Object_Protected_Data *obj,
                  int x, int y, Eina_Bool do_async)
 {
    Svg_Entry *svg = vd->svg;
-   Efl_VG *root;
+   Efl_VG *root, *dupe_root;
    void *buffer;
    Ector_Surface *ector;
    RGBA_Draw_Context *ct;
    Eina_Bool async_unref;
-   Eina_Bool error = EINA_FALSE;
+   Eina_Bool error = EINA_FALSE, created = EINA_FALSE;
 
    // if the size changed in between path set and the draw call;
    if (!(svg->w == obj->cur->geometry.w &&
@@ -251,9 +251,10 @@ _svg_data_render(Evas_Object_Protected_Data *obj,
         // manual render the vg tree
         ector = evas_ector_get(obj->layer->evas);
         if (!ector) return;
-
+        dupe_root = evas_vg_container_add(NULL);
+        evas_vg_node_dup(dupe_root, root);
         //1. render pre
-        _evas_vg_render_pre(root, ector, NULL);
+        _evas_vg_render_pre(dupe_root, ector, NULL);
         // 2. create surface
         buffer = obj->layer->evas->engine.func->ector_surface_create(output,
                                                                      NULL,
@@ -273,13 +274,14 @@ _svg_data_render(Evas_Object_Protected_Data *obj,
                                                    do_async);
         _evas_vg_render(obj, vd,
                         output, ct, buffer,
-                        root, NULL,
+                        dupe_root, NULL,
                         do_async);
         obj->layer->evas->engine.func->image_dirty_region(output, buffer, 0, 0, 0, 0);
         obj->layer->evas->engine.func->ector_end(output, ct, ector, buffer, do_async);
 
-        obj->layer->evas->engine.func->ector_surface_cache_set(output, root, buffer);
         evas_common_draw_context_free(ct);
+        eo_del(dupe_root);
+        created = EINA_TRUE;
      }
    // draw the buffer as image to canvas
 
@@ -293,6 +295,9 @@ _svg_data_render(Evas_Object_Protected_Data *obj,
         evas_cache_image_ref((Image_Entry *)buffer);
         evas_unref_queue_image_put(obj->layer->evas, buffer);
      }
+
+   if (created)
+     obj->layer->evas->engine.func->ector_surface_cache_set(output, root, buffer);
 }
 
 static void
index 76539d5..9c1e9d8 100644 (file)
@@ -525,6 +525,10 @@ EAPI void         evas_gl_common_error_set(void *data, int error_enum);
 EAPI int          evas_gl_common_error_get(void *data);
 EAPI void        *evas_gl_common_current_context_get(void);
 
+void              evas_gl_common_surface_cache_set(void *key, void *surface);
+void             *evas_gl_common_surface_cache_get(void *key);
+EAPI void         evas_gl_common_surface_cache_dump(void);
+
 typedef int (*Evas_GL_Preload)(void);
 typedef void (*Evas_GL_Common_Image_Call)(Evas_GL_Image *im);
 typedef void (*Evas_GL_Common_Context_Call)(Evas_Engine_GL_Context *gc);
diff --git a/src/modules/evas/engines/gl_common/evas_gl_surface_cache.c b/src/modules/evas/engines/gl_common/evas_gl_surface_cache.c
new file mode 100644 (file)
index 0000000..6375b1f
--- /dev/null
@@ -0,0 +1,76 @@
+#include "evas_gl_private.h"
+
+static Ector_Surface_Cache *surface_cache = NULL;
+
+static void
+evas_gl_common_surface_cache_init(void)
+{
+   if (!surface_cache)
+     {
+        surface_cache = calloc(1, sizeof(Ector_Surface_Cache));
+        surface_cache->surface_hash = eina_hash_int32_new(NULL);
+     }
+}
+
+EAPI void
+evas_gl_common_surface_cache_dump(void)
+{
+   Ector_Surface_Data *data;
+   if (surface_cache)
+     {
+        eina_hash_free(surface_cache->surface_hash);
+        EINA_LIST_FREE(surface_cache->lru_list, data)
+          {
+             evas_gl_common_image_free(data->surface);
+             free(data);
+          }
+        free(surface_cache);
+        surface_cache = NULL;
+     }
+}
+
+void
+evas_gl_common_surface_cache_set(void *key, void *surface)
+{
+   Ector_Surface_Data *surface_data = NULL;
+   int count;
+   evas_gl_common_surface_cache_init();
+   surface_data = calloc(1, sizeof(Ector_Surface_Data));
+   surface_data->key = key;
+   surface_data->surface = surface;
+   eina_hash_add(surface_cache->surface_hash, &key, surface_data);
+   surface_cache->lru_list = eina_list_prepend(surface_cache->lru_list, surface_data);
+   count = eina_list_count(surface_cache->lru_list);
+   if (count > 50)
+   {
+      surface_data = eina_list_data_get(eina_list_last(surface_cache->lru_list));
+      eina_hash_del(surface_cache->surface_hash, &surface_data->key, surface_data);
+      surface_cache->lru_list = eina_list_remove_list(surface_cache->lru_list, eina_list_last(surface_cache->lru_list));
+      evas_gl_common_image_free(surface_data->surface);
+      free(surface_data);
+   }
+}
+
+void *
+evas_gl_common_surface_cache_get(void *key)
+{
+   Ector_Surface_Data *surface_data = NULL, *lru_data;
+   Eina_List *l;
+
+   evas_gl_common_surface_cache_init();
+   surface_data =  eina_hash_find(surface_cache->surface_hash, &key);
+   if (surface_data)
+     {
+        EINA_LIST_FOREACH(surface_cache->lru_list, l, lru_data)
+          {
+            if (lru_data == surface_data)
+              {
+                 surface_cache->lru_list = eina_list_promote_list(surface_cache->lru_list, l);
+                 break;
+              }
+          }
+        return surface_data->surface;
+     }
+   return NULL;
+}
+
index 59a49d4..5f9ea18 100644 (file)
@@ -78,6 +78,8 @@ unsigned int (*glsym_eglUnbindWaylandDisplayWL)(EGLDisplay dpy, struct wl_displa
 unsigned int (*glsym_eglQueryWaylandBufferWL)(EGLDisplay a, struct wl_resource *b, EGLint c, EGLint *d) = NULL;
 unsigned int (*glsym_eglSetDamageRegionKHR)(EGLDisplay a, EGLSurface b, EGLint *c, EGLint d) = NULL;
 
+void (*glsym_evas_gl_common_surface_cache_dump)(void) = NULL;
+
 /* local function prototypes */
 static void gl_symbols(void);
 static void gl_extn_veto(Render_Engine *re);
@@ -169,6 +171,7 @@ gl_symbols(void)
    glsym_##sym = dlsym(RTLD_DEFAULT, #sym);
 
    // Get function pointer to evas_gl_common that is now provided through the link of GL_Generic.
+   LINK2GENERIC(evas_gl_common_surface_cache_dump);
    LINK2GENERIC(evas_gl_common_image_all_unload);
    LINK2GENERIC(evas_gl_common_image_ref);
    LINK2GENERIC(evas_gl_common_image_unref);
@@ -1095,7 +1098,7 @@ eng_output_dump(void *data)
 
    re = (Render_Engine *)data;
    if (!re) return;
-
+   glsym_evas_gl_common_surface_cache_dump();
    evas_common_image_image_all_unload();
    evas_common_font_font_all_unload();
    glsym_evas_gl_common_image_all_unload(eng_get_ob(re)->gl_context);
index e83ed3a..d31db2a 100644 (file)
@@ -2559,80 +2559,16 @@ eng_ector_surface_create(void *data, void *surface, int width, int height, Eina_
    return surface;
 }
 
-static Ector_Surface_Cache *surface_cache = NULL;
-
-static void 
-_ector_surface_cache_init(void)
-{
-   if (!surface_cache)
-     {
-        surface_cache = calloc(1, sizeof(Ector_Surface_Cache));
-        surface_cache->surface_hash = eina_hash_int32_new(NULL);
-     }
-}
-
-// static void 
-// _ector_surface_cache_dump(void)
-// {
-//    Ector_Surface_Data *data;
-
-//    if (surface_cache)
-//      {
-//         eina_hash_free(surface_cache->surface_hash);
-//         EINA_LIST_FREE(surface_cache->lru_list, data)
-//           {
-//              evas_gl_common_image_free(data->surface);
-//              free(data);
-//           }
-//         free(surface_cache);
-//         surface_cache = NULL;
-//      }
-// }
-
 static void
 eng_ector_surface_cache_set(void *data, void *key, void *surface)
 {
-   Ector_Surface_Data *surface_data = NULL;
-   int count;
-
-   _ector_surface_cache_init();
-   surface_data = calloc(1, sizeof(Ector_Surface_Data));
-   surface_data->key = key;
-   surface_data->surface = surface;
-   eina_hash_add(surface_cache->surface_hash, &key, surface_data);
-   surface_cache->lru_list = eina_list_prepend(surface_cache->lru_list, surface_data);
-   count = eina_list_count(surface_cache->lru_list);
-   if (count > 100)
-   {
-      surface_data = eina_list_data_get(eina_list_last(surface_cache->lru_list));
-      eina_hash_del(surface_cache->surface_hash, &surface_data->key, surface_data);
-      surface_cache->lru_list = eina_list_remove_list(surface_cache->lru_list, eina_list_last(surface_cache->lru_list));
-      evas_gl_common_image_free(surface_data->surface);
-      free(surface_data);
-   }
+   evas_gl_common_surface_cache_set(key, surface);
 }
 
 static void *
 eng_ector_surface_cache_get(void *data EINA_UNUSED, void *key)
 {
-   Ector_Surface_Data *surface_data = NULL, *lru_data;
-   Eina_List *l;
-
-   _ector_surface_cache_init();
-   surface_data =  eina_hash_find(surface_cache->surface_hash, &key);
-   if (surface_data) 
-     {
-        EINA_LIST_FOREACH(surface_cache->lru_list, l, lru_data)
-          {
-            if (lru_data == surface_data)
-              {
-                 surface_cache->lru_list = eina_list_promote_list(surface_cache->lru_list, l);
-                 break;
-              }
-          }
-        return surface_data->surface;
-     }
-   return NULL;
+   return evas_gl_common_surface_cache_get(key);
 }
 
 static Evas_Func func, pfunc;
index 98962fe..8c2e856 100755 (executable)
@@ -15,6 +15,8 @@ Evas_GL_Common_Context_Resize_Call glsym_evas_gl_common_context_resize = NULL;
 Evas_GL_Preload_Render_Call glsym_evas_gl_preload_render_lock = NULL;
 Evas_Gl_Symbols glsym_evas_gl_symbols = NULL;
 
+void (*glsym_evas_gl_common_surface_cache_dump)(void) = NULL;
+
 static Outbuf *_sdl_output_setup(int w, int h, int fullscreen, int noframe, Evas_Engine_Info_GL_SDL *info);
 
 int _evas_engine_GL_SDL_log_dom = -1;
@@ -354,6 +356,7 @@ eng_output_dump(void *data)
    Render_Engine *re;
 
    re = (Render_Engine *)data;
+   glsym_evas_gl_common_surface_cache_dump();
    evas_common_image_image_all_unload();
    evas_common_font_font_all_unload();
    glsym_evas_gl_common_image_all_unload(re->generic.software.ob->gl_context);
@@ -370,7 +373,7 @@ gl_symbols(void)
 {
 #define LINK2GENERIC(sym)                       \
    glsym_##sym = dlsym(RTLD_DEFAULT, #sym);
-
+   LINK2GENERIC(evas_gl_common_surface_cache_dump);
    LINK2GENERIC(evas_gl_symbols);
    LINK2GENERIC(evas_gl_common_context_new);
    LINK2GENERIC(evas_gl_common_context_free);
index 7a2e176..1d77570 100755 (executable)
@@ -79,6 +79,8 @@ unsigned int (*glsym_eglSwapBuffersWithDamage) (EGLDisplay a, void *b, const EGL
 unsigned int (*glsym_eglSetDamageRegionKHR) (EGLDisplay a, EGLSurface b, EGLint *c, EGLint d) = NULL;
 unsigned int (*glsym_eglQueryWaylandBufferWL)(EGLDisplay a, struct wl_resource *b, EGLint c, EGLint *d) = NULL;
 
+void (*glsym_evas_gl_common_surface_cache_dump)(void) = NULL;
+
 /* local variables */
 static Eina_Bool initted = EINA_FALSE;
 static int gl_wins = 0;
@@ -115,6 +117,7 @@ gl_symbols(void)
    glsym_##sym = dlsym(RTLD_DEFAULT, #sym);
 
    // Get function pointer to evas_gl_common now provided through GL_Generic.
+   LINK2GENERIC(evas_gl_common_surface_cache_dump);
    LINK2GENERIC(evas_gl_common_image_all_unload);
    LINK2GENERIC(evas_gl_common_image_ref);
    LINK2GENERIC(evas_gl_common_image_unref);
@@ -1157,7 +1160,7 @@ eng_output_dump(void *data)
    Render_Engine *re;
 
    if (!(re = (Render_Engine *)data)) return;
-
+   glsym_evas_gl_common_surface_cache_dump();
    evas_common_image_image_all_unload();
    evas_common_font_font_all_unload();
    glsym_evas_gl_common_image_all_unload(eng_get_ob(re)->gl_context);
index 5d86624..89771fa 100644 (file)
@@ -105,6 +105,8 @@ void     (*glsym_glXReleaseBuffersMESA)   (Display *a, XID b) = NULL;
 
 #endif
 
+void (*glsym_evas_gl_common_surface_cache_dump)(void) = NULL;
+
 static inline Outbuf *
 eng_get_ob(Render_Engine *re)
 {
@@ -1205,6 +1207,7 @@ gl_symbols(void)
    if (!glsym_##sym) ERR("Could not find function '%s'", #sym);
 
    // Get function pointer to evas_gl_common that is now provided through the link of GL_Generic.
+   LINK2GENERIC(evas_gl_common_surface_cache_dump);
    LINK2GENERIC(evas_gl_common_image_all_unload);
    LINK2GENERIC(evas_gl_common_image_ref);
    LINK2GENERIC(evas_gl_common_image_unref);
@@ -1882,6 +1885,7 @@ eng_output_dump(void *data)
    Render_Engine *re;
 
    re = (Render_Engine *)data;
+   glsym_evas_gl_common_surface_cache_dump();
    evas_common_image_image_all_unload();
    evas_common_font_font_all_unload();
    glsym_evas_gl_common_image_all_unload(eng_get_ob(re)->gl_context);
index 050b3b7..f901bf9 100755 (executable)
@@ -89,6 +89,8 @@ unsigned int (*glsym_eglSwapBuffersWithDamage) (EGLDisplay a, void *b, const EGL
 unsigned int (*glsym_eglSetDamageRegionKHR) (EGLDisplay a, EGLSurface b, EGLint *c, EGLint d) = NULL;
 unsigned int (*glsym_eglQueryWaylandBufferWL)(EGLDisplay a, struct wl_resource *b, EGLint c, EGLint *d) = NULL;
 
+void (*glsym_evas_gl_common_surface_cache_dump)(void) = NULL;
+
 /* local variables */
 static Eina_Bool initted = EINA_FALSE;
 static int gl_wins = 0;
@@ -125,6 +127,7 @@ gl_symbols(void)
    glsym_##sym = dlsym(RTLD_DEFAULT, #sym);
 
    // Get function pointer to evas_gl_common now provided through GL_Generic.
+   LINK2GENERIC(evas_gl_common_surface_cache_dump);
    LINK2GENERIC(evas_gl_common_image_all_unload);
    LINK2GENERIC(evas_gl_common_image_ref);
    LINK2GENERIC(evas_gl_common_image_unref);
@@ -1125,7 +1128,7 @@ eng_output_dump(void *data)
    Render_Engine *re;
 
    if (!(re = (Render_Engine *)data)) return;
-
+   glsym_evas_gl_common_surface_cache_dump();
    evas_common_image_image_all_unload();
    evas_common_font_font_all_unload();
    glsym_evas_gl_common_image_all_unload(eng_get_ob(re)->gl_context);