From: Subhransu Mohanty Date: Wed, 19 Oct 2016 10:52:27 +0000 (+0900) Subject: evas/engine: refactor the ector surface caching for gl backend X-Git-Tag: submit/tizen/20161101.043805~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F81%2F94481%2F4;p=platform%2Fupstream%2Fefl.git evas/engine: refactor the ector surface caching for gl backend Change-Id: I14c0b5ac0940471479e35e01b2542ddd13a0c69d --- diff --git a/src/Makefile_Evas.am b/src/Makefile_Evas.am index c513e7f..356c765 100755 --- a/src/Makefile_Evas.am +++ b/src/Makefile_Evas.am @@ -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) diff --git a/src/lib/evas/canvas/evas_object_vg.c b/src/lib/evas/canvas/evas_object_vg.c index a885103..ba08f13 100644 --- a/src/lib/evas/canvas/evas_object_vg.c +++ b/src/lib/evas/canvas/evas_object_vg.c @@ -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 diff --git a/src/modules/evas/engines/gl_common/evas_gl_common.h b/src/modules/evas/engines/gl_common/evas_gl_common.h index 76539d5..9c1e9d8 100644 --- a/src/modules/evas/engines/gl_common/evas_gl_common.h +++ b/src/modules/evas/engines/gl_common/evas_gl_common.h @@ -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 index 0000000..6375b1f --- /dev/null +++ b/src/modules/evas/engines/gl_common/evas_gl_surface_cache.c @@ -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; +} + diff --git a/src/modules/evas/engines/gl_drm/evas_engine.c b/src/modules/evas/engines/gl_drm/evas_engine.c index 59a49d4..5f9ea18 100644 --- a/src/modules/evas/engines/gl_drm/evas_engine.c +++ b/src/modules/evas/engines/gl_drm/evas_engine.c @@ -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); diff --git a/src/modules/evas/engines/gl_generic/evas_engine.c b/src/modules/evas/engines/gl_generic/evas_engine.c index e83ed3a..d31db2a 100644 --- a/src/modules/evas/engines/gl_generic/evas_engine.c +++ b/src/modules/evas/engines/gl_generic/evas_engine.c @@ -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; diff --git a/src/modules/evas/engines/gl_sdl/evas_engine.c b/src/modules/evas/engines/gl_sdl/evas_engine.c index 98962fe..8c2e856 100755 --- a/src/modules/evas/engines/gl_sdl/evas_engine.c +++ b/src/modules/evas/engines/gl_sdl/evas_engine.c @@ -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); diff --git a/src/modules/evas/engines/gl_tbm/evas_engine.c b/src/modules/evas/engines/gl_tbm/evas_engine.c index 7a2e176..1d77570 100755 --- a/src/modules/evas/engines/gl_tbm/evas_engine.c +++ b/src/modules/evas/engines/gl_tbm/evas_engine.c @@ -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); diff --git a/src/modules/evas/engines/gl_x11/evas_engine.c b/src/modules/evas/engines/gl_x11/evas_engine.c index 5d86624..89771fa 100644 --- a/src/modules/evas/engines/gl_x11/evas_engine.c +++ b/src/modules/evas/engines/gl_x11/evas_engine.c @@ -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); diff --git a/src/modules/evas/engines/wayland_egl/evas_engine.c b/src/modules/evas/engines/wayland_egl/evas_engine.c index 050b3b7..f901bf9 100755 --- a/src/modules/evas/engines/wayland_egl/evas_engine.c +++ b/src/modules/evas/engines/wayland_egl/evas_engine.c @@ -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);