From aacf277c3affcc68806020c1f9e7a44829e1bb74 Mon Sep 17 00:00:00 2001 From: subhransu mohanty Date: Thu, 9 Nov 2017 10:31:12 +0900 Subject: [PATCH] evas/vg: added support for engine surface cache. --- src/lib/evas/include/evas_common_private.h | 28 ++++ src/modules/evas/engines/gl_drm/evas_engine.c | 5 +- .../evas/engines/gl_generic/evas_engine.c | 5 + src/modules/evas/engines/gl_sdl/evas_engine.c | 5 +- src/modules/evas/engines/gl_x11/evas_engine.c | 4 +- .../Evas_Engine_Software_Generic.h | 2 +- .../engines/software_generic/evas_engine.c | 122 +++++++++--------- .../evas/engines/wayland_egl/evas_engine.c | 3 +- 8 files changed, 108 insertions(+), 66 deletions(-) diff --git a/src/lib/evas/include/evas_common_private.h b/src/lib/evas/include/evas_common_private.h index 4f731d4e79..6518b16f93 100644 --- a/src/lib/evas/include/evas_common_private.h +++ b/src/lib/evas/include/evas_common_private.h @@ -1174,6 +1174,34 @@ typedef enum _Evas_Render_Mode void evas_common_rgba_image_scalecache_items_ref(Image_Entry *ie, Eina_Array *ret); void evas_common_rgba_image_scalecache_item_unref(Image_Entry *ie); +// Generic Cache +typedef struct _Generic_Cache Generic_Cache; +typedef struct _Generic_Cache_Entry Generic_Cache_Entry; + +struct _Generic_Cache_Entry +{ + void *key; // pointer + void *data; // engine image + int ref; +}; + +typedef void (*Generic_Cache_Free)(void *user_data, void *data); + +struct _Generic_Cache +{ + Eina_Hash *hash; + Eina_List *lru_list; + void *user_data; + Generic_Cache_Free free_func; +}; + +EAPI Generic_Cache* generic_cache_new(void *user_data, Generic_Cache_Free func); +EAPI void generic_cache_destroy(Generic_Cache *cache); +EAPI void generic_cache_dump(Generic_Cache *cache); +EAPI void generic_cache_data_set(Generic_Cache *cache, void *key, void *data); +EAPI void *generic_cache_data_get(Generic_Cache *cache, void *key); +EAPI void generic_cache_data_drop(Generic_Cache *cache, void *key); + /*****************************************************************************/ #ifdef __cplusplus diff --git a/src/modules/evas/engines/gl_drm/evas_engine.c b/src/modules/evas/engines/gl_drm/evas_engine.c index e1a36940cc..fd219bbd9b 100644 --- a/src/modules/evas/engines/gl_drm/evas_engine.c +++ b/src/modules/evas/engines/gl_drm/evas_engine.c @@ -1070,13 +1070,14 @@ eng_canvas_alpha_get(void *data) } static void -eng_output_dump(void *engine EINA_UNUSED, void *data) +eng_output_dump(void *engine, void *data) { Render_Engine *re; + Render_Engine_GL_Generic *e = engine; re = (Render_Engine *)data; if (!re) return; - + generic_cache_dump(e->software.surface_cache); 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 a6b229a5c6..62f1a38290 100644 --- a/src/modules/evas/engines/gl_generic/evas_engine.c +++ b/src/modules/evas/engines/gl_generic/evas_engine.c @@ -152,6 +152,8 @@ egl_display_get(Render_Engine_GL_Generic *engine) } #endif +void eng_image_free(void *engine, void *image); + static void * eng_engine_new(void) { @@ -159,6 +161,7 @@ eng_engine_new(void) engine = calloc(1, sizeof (Render_Engine_GL_Generic)); if (!engine) return NULL; + engine->software.surface_cache = generic_cache_new(engine, eng_image_free); return engine; } @@ -169,6 +172,8 @@ eng_engine_free(void *engine) Render_Engine_GL_Generic *e = engine; Render_Output_GL_Generic *output; + generic_cache_destroy(e->software.surface_cache); + EINA_LIST_FREE(e->software.outputs, output) ERR("Output %p not properly cleaned before engine destruction.", output); free(e); diff --git a/src/modules/evas/engines/gl_sdl/evas_engine.c b/src/modules/evas/engines/gl_sdl/evas_engine.c index bf6ba6540c..8a00b1196b 100644 --- a/src/modules/evas/engines/gl_sdl/evas_engine.c +++ b/src/modules/evas/engines/gl_sdl/evas_engine.c @@ -316,11 +316,13 @@ eng_output_free(void *engine, void *data) } static void -eng_output_dump(void *engine EINA_UNUSED, void *data) +eng_output_dump(void *engine, void *data) { Render_Engine *re; + Render_Engine_GL_Generic *e = engine; re = (Render_Engine *)data; + generic_cache_dump(e->software.surface_cache); 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); @@ -339,7 +341,6 @@ gl_symbols(void) #define LINK2GENERIC(sym) \ glsym_##sym = dlsym(RTLD_DEFAULT, #sym); - LINK2GENERIC(evas_gl_symbols); LINK2GENERIC(evas_gl_common_context_new); LINK2GENERIC(evas_gl_common_context_free); diff --git a/src/modules/evas/engines/gl_x11/evas_engine.c b/src/modules/evas/engines/gl_x11/evas_engine.c index 583e036ba2..eb55c7720a 100644 --- a/src/modules/evas/engines/gl_x11/evas_engine.c +++ b/src/modules/evas/engines/gl_x11/evas_engine.c @@ -1846,11 +1846,13 @@ eng_canvas_alpha_get(void *engine) } static void -eng_output_dump(void *engine EINA_UNUSED, void *data) +eng_output_dump(void *engine, void *data) { Render_Engine *re = data; + Render_Engine_GL_Generic *e = engine; eng_window_use(eng_get_ob(re)); + generic_cache_dump(e->software.surface_cache); 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/software_generic/Evas_Engine_Software_Generic.h b/src/modules/evas/engines/software_generic/Evas_Engine_Software_Generic.h index 48ab0614d3..52918cce34 100644 --- a/src/modules/evas/engines/software_generic/Evas_Engine_Software_Generic.h +++ b/src/modules/evas/engines/software_generic/Evas_Engine_Software_Generic.h @@ -83,7 +83,7 @@ struct _Render_Output_Software_Generic struct _Render_Engine_Software_Generic { Eina_List *outputs; - + Generic_Cache *surface_cache; struct { int w, h; Eina_Bool strict; diff --git a/src/modules/evas/engines/software_generic/evas_engine.c b/src/modules/evas/engines/software_generic/evas_engine.c index 356c979328..8dfafc2d7d 100644 --- a/src/modules/evas/engines/software_generic/evas_engine.c +++ b/src/modules/evas/engines/software_generic/evas_engine.c @@ -93,7 +93,7 @@ struct _Render_Engine_GL_Surface int depth_bits; int stencil_bits; - // Data + // Data void *buffer; Render_Engine_GL_Context *current_ctx; @@ -2896,8 +2896,8 @@ eng_image_map_surface_new(void *data EINA_UNUSED, int w, int h, int alpha) return surface; } #endif - surface = evas_cache_image_copied_data(evas_common_image_cache_get(), - w, h, NULL, alpha, + surface = evas_cache_image_copied_data(evas_common_image_cache_get(), + w, h, NULL, alpha, EVAS_COLORSPACE_ARGB8888); if (!surface) return NULL; evas_cache_image_pixels(surface); @@ -3436,7 +3436,7 @@ static int eng_image_load_error_get(void *data EINA_UNUSED, void *image) { RGBA_Image *im; - + if (!image) return EVAS_LOAD_ERROR_NONE; im = image; return im->cache_entry.load_error; @@ -3520,7 +3520,7 @@ eng_gl_surface_create(void *data EINA_UNUSED, void *config, int w, int h) sfc->depth_bits = 0; break; } - + // Stencil Bits switch (cfg->stencil_bits) { @@ -3722,7 +3722,7 @@ eng_gl_make_current(void *data EINA_UNUSED, void *surface, void *context) // Call MakeCurrent - ret = _sym_OSMesaMakeCurrent(ctx->context, sfc->buffer, GL_UNSIGNED_BYTE, + ret = _sym_OSMesaMakeCurrent(ctx->context, sfc->buffer, GL_UNSIGNED_BYTE, sfc->w, sfc->h); if (ret == GL_FALSE) @@ -3783,7 +3783,7 @@ eng_gl_native_surface_get(void *data EINA_UNUSED, void *surface, void *native_su ns->type = EVAS_NATIVE_SURFACE_EVASGL; ns->version = EVAS_NATIVE_SURFACE_VERSION; ns->data.evasgl.surface = sfc->buffer; - + return 1; #else (void) surface; @@ -3859,6 +3859,8 @@ eng_engine_new(void) engine = calloc(1, sizeof (Render_Engine_Software_Generic)); if (!engine) return NULL; + engine->surface_cache = generic_cache_new(engine, eng_image_free); + return engine; } @@ -3868,6 +3870,8 @@ eng_engine_free(void *engine) Render_Engine_Software_Generic *e = engine; Render_Output_Software_Generic *output; + generic_cache_destroy(e->surface_cache); + EINA_LIST_FREE(e->outputs, output) ERR("Output %p not properly cleaned before engine destruction.", output); @@ -5368,7 +5372,7 @@ gl_sym_init(void) // Wrapped GL APIs to handle desktop compatibility // Stripping precision code from GLES shader for desktop compatibility -// Code adopted from Meego GL code. Temporary Fix. +// Code adopted from Meego GL code. Temporary Fix. static const char * opengl_strtok(const char *s, int *n, char **saveptr, char *prevbuf) { @@ -5380,33 +5384,33 @@ opengl_strtok(const char *s, int *n, char **saveptr, char *prevbuf) if (prevbuf) free(prevbuf); - if (s) + if (s) *saveptr = (char *)s; - else + else { if (!(*saveptr) || !(*n)) return NULL; s = *saveptr; } - for (; *n && strchr(delim, *s); s++, (*n)--) + for (; *n && strchr(delim, *s); s++, (*n)--) { - if (*s == '/' && *n > 1) + if (*s == '/' && *n > 1) { - if (s[1] == '/') + if (s[1] == '/') { - do + do { s++, (*n)--; - } + } while (*n > 1 && s[1] != '\n' && s[1] != '\r'); - } - else if (s[1] == '*') + } + else if (s[1] == '*') { - do + do { s++, (*n)--; - } + } while (*n > 2 && (s[1] != '*' || s[2] != '/')); s++, (*n)--; } @@ -5423,26 +5427,26 @@ opengl_strtok(const char *s, int *n, char **saveptr, char *prevbuf) ret = malloc(retlen + 1); p = ret; - while (retlen > 0) + while (retlen > 0) { - if (*start == '/' && retlen > 1) + if (*start == '/' && retlen > 1) { - if (start[1] == '/') + if (start[1] == '/') { - do + do { start++, retlen--; - } + } while (retlen > 1 && start[1] != '\n' && start[1] != '\r'); start++, retlen--; continue; - } - else if (start[1] == '*') + } + else if (start[1] == '*') { - do + do { start++, retlen--; - } + } while (retlen > 2 && (start[1] != '*' || start[2] != '/')); start += 3, retlen -= 3; continue; @@ -5453,7 +5457,7 @@ opengl_strtok(const char *s, int *n, char **saveptr, char *prevbuf) *p = 0; return ret; -} +} static char * patch_gles_shader(const char *source, int length, int *patched_len) @@ -5471,36 +5475,36 @@ patch_gles_shader(const char *source, int length, int *patched_len) if (!patched) return NULL; p = (char *)opengl_strtok(source, &length, &saveptr, NULL); - for (; p; p = (char *)opengl_strtok(0, &length, &saveptr, p)) + for (; p; p = (char *)opengl_strtok(0, &length, &saveptr, p)) { - if (!strncmp(p, "lowp", 4) || !strncmp(p, "mediump", 7) || !strncmp(p, "highp", 5)) + if (!strncmp(p, "lowp", 4) || !strncmp(p, "mediump", 7) || !strncmp(p, "highp", 5)) { continue; - } - else if (!strncmp(p, "precision", 9)) + } + else if (!strncmp(p, "precision", 9)) { while ((p = (char *)opengl_strtok(0, &length, &saveptr, p)) && !strchr(p, ';')); - } - else + } + else { - if (!strncmp(p, "gl_MaxVertexUniformVectors", 26)) + if (!strncmp(p, "gl_MaxVertexUniformVectors", 26)) { - free(p); + free(p); p = strdup("(gl_MaxVertexUniformComponents / 4)"); - } - else if (!strncmp(p, "gl_MaxFragmentUniformVectors", 28)) + } + else if (!strncmp(p, "gl_MaxFragmentUniformVectors", 28)) { free(p); p = strdup("(gl_MaxFragmentUniformComponents / 4)"); - } - else if (!strncmp(p, "gl_MaxVaryingVectors", 20)) + } + else if (!strncmp(p, "gl_MaxVaryingVectors", 20)) { free(p); p = strdup("(gl_MaxVaryingFloats / 4)"); } int new_len = strlen(p); - if (*patched_len + new_len > patched_size) + if (*patched_len + new_len > patched_size) { char *tmp; @@ -5517,18 +5521,18 @@ patch_gles_shader(const char *source, int length, int *patched_len) memcpy(patched + *patched_len, p, new_len); *patched_len += new_len; - } + } } patched[*patched_len] = 0; /* check that we don't leave dummy preprocessor lines */ - for (sp = patched; *sp;) + for (sp = patched; *sp;) { for (; *sp == ' ' || *sp == '\t'; sp++); - if (!strncmp(sp, "#define", 7)) + if (!strncmp(sp, "#define", 7)) { for (p = sp + 7; *p == ' ' || *p == '\t'; p++); - if (*p == '\n' || *p == '\r' || *p == '/') + if (*p == '\n' || *p == '\r' || *p == '/') { memset(sp, 0x20, 7); } @@ -5550,21 +5554,21 @@ evgl_glShaderSource(GLuint shader, GLsizei count, const char* const* string, con memset(s, 0, count * sizeof(char*)); memset(l, 0, count * sizeof(GLint)); - for (i = 0; i < count; ++i) + for (i = 0; i < count; ++i) { - if (length) + if (length) { len = length[i]; - if (len < 0) + if (len < 0) len = string[i] ? strlen(string[i]) : 0; } else len = string[i] ? strlen(string[i]) : 0; - if (string[i]) + if (string[i]) { s[i] = patch_gles_shader(string[i], len, &l[i]); - if (!s[i]) + if (!s[i]) { while(i) free(s[--i]); @@ -5574,8 +5578,8 @@ evgl_glShaderSource(GLuint shader, GLsizei count, const char* const* string, con DBG("Patching Shader Failed."); return; } - } - else + } + else { s[i] = NULL; l[i] = 0; @@ -5694,7 +5698,7 @@ override_gl_apis(Evas_GL_API *api) ORD(glCheckFramebufferStatus); ORD(glClear); ORD(glClearColor); - ORD(glClearDepthf); + ORD(glClearDepthf); ORD(glClearStencil); ORD(glColorMask); ORD(glCompileShader); @@ -5713,7 +5717,7 @@ override_gl_apis(Evas_GL_API *api) ORD(glDeleteTextures); ORD(glDepthFunc); ORD(glDepthMask); - ORD(glDepthRangef); + ORD(glDepthRangef); ORD(glDetachShader); ORD(glDisable); ORD(glDisableVertexAttribArray); @@ -5746,7 +5750,7 @@ override_gl_apis(Evas_GL_API *api) ORD(glGetRenderbufferParameteriv); ORD(glGetShaderiv); ORD(glGetShaderInfoLog); - ORD(glGetShaderPrecisionFormat); + ORD(glGetShaderPrecisionFormat); ORD(glGetShaderSource); ORD(glGetTexParameterfv); ORD(glGetTexParameteriv); @@ -5769,11 +5773,11 @@ override_gl_apis(Evas_GL_API *api) ORD(glPixelStorei); ORD(glPolygonOffset); ORD(glReadPixels); - ORD(glReleaseShaderCompiler); + ORD(glReleaseShaderCompiler); ORD(glRenderbufferStorage); ORD(glSampleCoverage); ORD(glScissor); - ORD(glShaderBinary); + ORD(glShaderBinary); ORD(glShaderSource); ORD(glStencilFunc); ORD(glStencilFuncSeparate); @@ -5846,7 +5850,7 @@ gl_lib_init(void) // Current ctx & sfc stuff if (!_tls_check()) return 0; - // dlopen OSMesa + // dlopen OSMesa gl_lib_handle = dlopen("libOSMesa.so.9", RTLD_NOW); if (!gl_lib_handle) gl_lib_handle = dlopen("libOSMesa.so.8", RTLD_NOW); if (!gl_lib_handle) gl_lib_handle = dlopen("libOSMesa.so.7", RTLD_NOW); diff --git a/src/modules/evas/engines/wayland_egl/evas_engine.c b/src/modules/evas/engines/wayland_egl/evas_engine.c index 4db2ad59db..560f54c136 100644 --- a/src/modules/evas/engines/wayland_egl/evas_engine.c +++ b/src/modules/evas/engines/wayland_egl/evas_engine.c @@ -748,9 +748,10 @@ eng_output_dump(void *engine EINA_UNUSED, void *data) { Outbuf *ob; Render_Engine *re; + Render_Engine_GL_Generic *e = engine; if (!(re = (Render_Engine *)data)) return; - + generic_cache_dump(e->software.surface_cache); evas_common_image_image_all_unload(); evas_common_font_font_all_unload(); ob = eng_get_ob(re);