evas/vg: added support for engine surface cache.

This commit is contained in:
subhransu mohanty 2017-11-09 10:31:12 +09:00 committed by Jean-Philippe Andre
parent d4a2b2025b
commit aacf277c3a
8 changed files with 108 additions and 66 deletions

View File

@ -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_items_ref(Image_Entry *ie, Eina_Array *ret);
void evas_common_rgba_image_scalecache_item_unref(Image_Entry *ie); 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 #ifdef __cplusplus

View File

@ -1070,13 +1070,14 @@ eng_canvas_alpha_get(void *data)
} }
static void static void
eng_output_dump(void *engine EINA_UNUSED, void *data) eng_output_dump(void *engine, void *data)
{ {
Render_Engine *re; Render_Engine *re;
Render_Engine_GL_Generic *e = engine;
re = (Render_Engine *)data; re = (Render_Engine *)data;
if (!re) return; if (!re) return;
generic_cache_dump(e->software.surface_cache);
evas_common_image_image_all_unload(); evas_common_image_image_all_unload();
evas_common_font_font_all_unload(); evas_common_font_font_all_unload();
glsym_evas_gl_common_image_all_unload(eng_get_ob(re)->gl_context); glsym_evas_gl_common_image_all_unload(eng_get_ob(re)->gl_context);

View File

@ -152,6 +152,8 @@ egl_display_get(Render_Engine_GL_Generic *engine)
} }
#endif #endif
void eng_image_free(void *engine, void *image);
static void * static void *
eng_engine_new(void) eng_engine_new(void)
{ {
@ -159,6 +161,7 @@ eng_engine_new(void)
engine = calloc(1, sizeof (Render_Engine_GL_Generic)); engine = calloc(1, sizeof (Render_Engine_GL_Generic));
if (!engine) return NULL; if (!engine) return NULL;
engine->software.surface_cache = generic_cache_new(engine, eng_image_free);
return engine; return engine;
} }
@ -169,6 +172,8 @@ eng_engine_free(void *engine)
Render_Engine_GL_Generic *e = engine; Render_Engine_GL_Generic *e = engine;
Render_Output_GL_Generic *output; Render_Output_GL_Generic *output;
generic_cache_destroy(e->software.surface_cache);
EINA_LIST_FREE(e->software.outputs, output) EINA_LIST_FREE(e->software.outputs, output)
ERR("Output %p not properly cleaned before engine destruction.", output); ERR("Output %p not properly cleaned before engine destruction.", output);
free(e); free(e);

View File

@ -316,11 +316,13 @@ eng_output_free(void *engine, void *data)
} }
static void static void
eng_output_dump(void *engine EINA_UNUSED, void *data) eng_output_dump(void *engine, void *data)
{ {
Render_Engine *re; Render_Engine *re;
Render_Engine_GL_Generic *e = engine;
re = (Render_Engine *)data; re = (Render_Engine *)data;
generic_cache_dump(e->software.surface_cache);
evas_common_image_image_all_unload(); evas_common_image_image_all_unload();
evas_common_font_font_all_unload(); evas_common_font_font_all_unload();
glsym_evas_gl_common_image_all_unload(re->generic.software.ob->gl_context); glsym_evas_gl_common_image_all_unload(re->generic.software.ob->gl_context);
@ -339,7 +341,6 @@ gl_symbols(void)
#define LINK2GENERIC(sym) \ #define LINK2GENERIC(sym) \
glsym_##sym = dlsym(RTLD_DEFAULT, #sym); glsym_##sym = dlsym(RTLD_DEFAULT, #sym);
LINK2GENERIC(evas_gl_symbols); LINK2GENERIC(evas_gl_symbols);
LINK2GENERIC(evas_gl_common_context_new); LINK2GENERIC(evas_gl_common_context_new);
LINK2GENERIC(evas_gl_common_context_free); LINK2GENERIC(evas_gl_common_context_free);

View File

@ -1846,11 +1846,13 @@ eng_canvas_alpha_get(void *engine)
} }
static void static void
eng_output_dump(void *engine EINA_UNUSED, void *data) eng_output_dump(void *engine, void *data)
{ {
Render_Engine *re = data; Render_Engine *re = data;
Render_Engine_GL_Generic *e = engine;
eng_window_use(eng_get_ob(re)); eng_window_use(eng_get_ob(re));
generic_cache_dump(e->software.surface_cache);
evas_common_image_image_all_unload(); evas_common_image_image_all_unload();
evas_common_font_font_all_unload(); evas_common_font_font_all_unload();
glsym_evas_gl_common_image_all_unload(eng_get_ob(re)->gl_context); glsym_evas_gl_common_image_all_unload(eng_get_ob(re)->gl_context);

View File

@ -83,7 +83,7 @@ struct _Render_Output_Software_Generic
struct _Render_Engine_Software_Generic struct _Render_Engine_Software_Generic
{ {
Eina_List *outputs; Eina_List *outputs;
Generic_Cache *surface_cache;
struct { struct {
int w, h; int w, h;
Eina_Bool strict; Eina_Bool strict;

View File

@ -93,7 +93,7 @@ struct _Render_Engine_GL_Surface
int depth_bits; int depth_bits;
int stencil_bits; int stencil_bits;
// Data // Data
void *buffer; void *buffer;
Render_Engine_GL_Context *current_ctx; 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; return surface;
} }
#endif #endif
surface = evas_cache_image_copied_data(evas_common_image_cache_get(), surface = evas_cache_image_copied_data(evas_common_image_cache_get(),
w, h, NULL, alpha, w, h, NULL, alpha,
EVAS_COLORSPACE_ARGB8888); EVAS_COLORSPACE_ARGB8888);
if (!surface) return NULL; if (!surface) return NULL;
evas_cache_image_pixels(surface); evas_cache_image_pixels(surface);
@ -3436,7 +3436,7 @@ static int
eng_image_load_error_get(void *data EINA_UNUSED, void *image) eng_image_load_error_get(void *data EINA_UNUSED, void *image)
{ {
RGBA_Image *im; RGBA_Image *im;
if (!image) return EVAS_LOAD_ERROR_NONE; if (!image) return EVAS_LOAD_ERROR_NONE;
im = image; im = image;
return im->cache_entry.load_error; 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; sfc->depth_bits = 0;
break; break;
} }
// Stencil Bits // Stencil Bits
switch (cfg->stencil_bits) switch (cfg->stencil_bits)
{ {
@ -3722,7 +3722,7 @@ eng_gl_make_current(void *data EINA_UNUSED, void *surface, void *context)
// Call MakeCurrent // 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); sfc->w, sfc->h);
if (ret == GL_FALSE) 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->type = EVAS_NATIVE_SURFACE_EVASGL;
ns->version = EVAS_NATIVE_SURFACE_VERSION; ns->version = EVAS_NATIVE_SURFACE_VERSION;
ns->data.evasgl.surface = sfc->buffer; ns->data.evasgl.surface = sfc->buffer;
return 1; return 1;
#else #else
(void) surface; (void) surface;
@ -3859,6 +3859,8 @@ eng_engine_new(void)
engine = calloc(1, sizeof (Render_Engine_Software_Generic)); engine = calloc(1, sizeof (Render_Engine_Software_Generic));
if (!engine) return NULL; if (!engine) return NULL;
engine->surface_cache = generic_cache_new(engine, eng_image_free);
return engine; return engine;
} }
@ -3868,6 +3870,8 @@ eng_engine_free(void *engine)
Render_Engine_Software_Generic *e = engine; Render_Engine_Software_Generic *e = engine;
Render_Output_Software_Generic *output; Render_Output_Software_Generic *output;
generic_cache_destroy(e->surface_cache);
EINA_LIST_FREE(e->outputs, output) EINA_LIST_FREE(e->outputs, output)
ERR("Output %p not properly cleaned before engine destruction.", 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 // Wrapped GL APIs to handle desktop compatibility
// Stripping precision code from GLES shader for 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 * static const char *
opengl_strtok(const char *s, int *n, char **saveptr, char *prevbuf) 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 (prevbuf) free(prevbuf);
if (s) if (s)
*saveptr = (char *)s; *saveptr = (char *)s;
else else
{ {
if (!(*saveptr) || !(*n)) if (!(*saveptr) || !(*n))
return NULL; return NULL;
s = *saveptr; 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)--; s++, (*n)--;
} }
while (*n > 1 && s[1] != '\n' && s[1] != '\r'); while (*n > 1 && s[1] != '\n' && s[1] != '\r');
} }
else if (s[1] == '*') else if (s[1] == '*')
{ {
do do
{ {
s++, (*n)--; s++, (*n)--;
} }
while (*n > 2 && (s[1] != '*' || s[2] != '/')); while (*n > 2 && (s[1] != '*' || s[2] != '/'));
s++, (*n)--; s++, (*n)--;
} }
@ -5423,26 +5427,26 @@ opengl_strtok(const char *s, int *n, char **saveptr, char *prevbuf)
ret = malloc(retlen + 1); ret = malloc(retlen + 1);
p = ret; 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--; start++, retlen--;
} }
while (retlen > 1 && start[1] != '\n' && start[1] != '\r'); while (retlen > 1 && start[1] != '\n' && start[1] != '\r');
start++, retlen--; start++, retlen--;
continue; continue;
} }
else if (start[1] == '*') else if (start[1] == '*')
{ {
do do
{ {
start++, retlen--; start++, retlen--;
} }
while (retlen > 2 && (start[1] != '*' || start[2] != '/')); while (retlen > 2 && (start[1] != '*' || start[2] != '/'));
start += 3, retlen -= 3; start += 3, retlen -= 3;
continue; continue;
@ -5453,7 +5457,7 @@ opengl_strtok(const char *s, int *n, char **saveptr, char *prevbuf)
*p = 0; *p = 0;
return ret; return ret;
} }
static char * static char *
patch_gles_shader(const char *source, int length, int *patched_len) 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; if (!patched) return NULL;
p = (char *)opengl_strtok(source, &length, &saveptr, 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; continue;
} }
else if (!strncmp(p, "precision", 9)) else if (!strncmp(p, "precision", 9))
{ {
while ((p = (char *)opengl_strtok(0, &length, &saveptr, p)) && !strchr(p, ';')); 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)"); p = strdup("(gl_MaxVertexUniformComponents / 4)");
} }
else if (!strncmp(p, "gl_MaxFragmentUniformVectors", 28)) else if (!strncmp(p, "gl_MaxFragmentUniformVectors", 28))
{ {
free(p); free(p);
p = strdup("(gl_MaxFragmentUniformComponents / 4)"); p = strdup("(gl_MaxFragmentUniformComponents / 4)");
} }
else if (!strncmp(p, "gl_MaxVaryingVectors", 20)) else if (!strncmp(p, "gl_MaxVaryingVectors", 20))
{ {
free(p); free(p);
p = strdup("(gl_MaxVaryingFloats / 4)"); p = strdup("(gl_MaxVaryingFloats / 4)");
} }
int new_len = strlen(p); int new_len = strlen(p);
if (*patched_len + new_len > patched_size) if (*patched_len + new_len > patched_size)
{ {
char *tmp; char *tmp;
@ -5517,18 +5521,18 @@ patch_gles_shader(const char *source, int length, int *patched_len)
memcpy(patched + *patched_len, p, new_len); memcpy(patched + *patched_len, p, new_len);
*patched_len += new_len; *patched_len += new_len;
} }
} }
patched[*patched_len] = 0; patched[*patched_len] = 0;
/* check that we don't leave dummy preprocessor lines */ /* check that we don't leave dummy preprocessor lines */
for (sp = patched; *sp;) for (sp = patched; *sp;)
{ {
for (; *sp == ' ' || *sp == '\t'; sp++); for (; *sp == ' ' || *sp == '\t'; sp++);
if (!strncmp(sp, "#define", 7)) if (!strncmp(sp, "#define", 7))
{ {
for (p = sp + 7; *p == ' ' || *p == '\t'; p++); for (p = sp + 7; *p == ' ' || *p == '\t'; p++);
if (*p == '\n' || *p == '\r' || *p == '/') if (*p == '\n' || *p == '\r' || *p == '/')
{ {
memset(sp, 0x20, 7); 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(s, 0, count * sizeof(char*));
memset(l, 0, count * sizeof(GLint)); 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]; len = length[i];
if (len < 0) if (len < 0)
len = string[i] ? strlen(string[i]) : 0; len = string[i] ? strlen(string[i]) : 0;
} }
else else
len = string[i] ? strlen(string[i]) : 0; len = string[i] ? strlen(string[i]) : 0;
if (string[i]) if (string[i])
{ {
s[i] = patch_gles_shader(string[i], len, &l[i]); s[i] = patch_gles_shader(string[i], len, &l[i]);
if (!s[i]) if (!s[i])
{ {
while(i) while(i)
free(s[--i]); free(s[--i]);
@ -5574,8 +5578,8 @@ evgl_glShaderSource(GLuint shader, GLsizei count, const char* const* string, con
DBG("Patching Shader Failed."); DBG("Patching Shader Failed.");
return; return;
} }
} }
else else
{ {
s[i] = NULL; s[i] = NULL;
l[i] = 0; l[i] = 0;
@ -5694,7 +5698,7 @@ override_gl_apis(Evas_GL_API *api)
ORD(glCheckFramebufferStatus); ORD(glCheckFramebufferStatus);
ORD(glClear); ORD(glClear);
ORD(glClearColor); ORD(glClearColor);
ORD(glClearDepthf); ORD(glClearDepthf);
ORD(glClearStencil); ORD(glClearStencil);
ORD(glColorMask); ORD(glColorMask);
ORD(glCompileShader); ORD(glCompileShader);
@ -5713,7 +5717,7 @@ override_gl_apis(Evas_GL_API *api)
ORD(glDeleteTextures); ORD(glDeleteTextures);
ORD(glDepthFunc); ORD(glDepthFunc);
ORD(glDepthMask); ORD(glDepthMask);
ORD(glDepthRangef); ORD(glDepthRangef);
ORD(glDetachShader); ORD(glDetachShader);
ORD(glDisable); ORD(glDisable);
ORD(glDisableVertexAttribArray); ORD(glDisableVertexAttribArray);
@ -5746,7 +5750,7 @@ override_gl_apis(Evas_GL_API *api)
ORD(glGetRenderbufferParameteriv); ORD(glGetRenderbufferParameteriv);
ORD(glGetShaderiv); ORD(glGetShaderiv);
ORD(glGetShaderInfoLog); ORD(glGetShaderInfoLog);
ORD(glGetShaderPrecisionFormat); ORD(glGetShaderPrecisionFormat);
ORD(glGetShaderSource); ORD(glGetShaderSource);
ORD(glGetTexParameterfv); ORD(glGetTexParameterfv);
ORD(glGetTexParameteriv); ORD(glGetTexParameteriv);
@ -5769,11 +5773,11 @@ override_gl_apis(Evas_GL_API *api)
ORD(glPixelStorei); ORD(glPixelStorei);
ORD(glPolygonOffset); ORD(glPolygonOffset);
ORD(glReadPixels); ORD(glReadPixels);
ORD(glReleaseShaderCompiler); ORD(glReleaseShaderCompiler);
ORD(glRenderbufferStorage); ORD(glRenderbufferStorage);
ORD(glSampleCoverage); ORD(glSampleCoverage);
ORD(glScissor); ORD(glScissor);
ORD(glShaderBinary); ORD(glShaderBinary);
ORD(glShaderSource); ORD(glShaderSource);
ORD(glStencilFunc); ORD(glStencilFunc);
ORD(glStencilFuncSeparate); ORD(glStencilFuncSeparate);
@ -5846,7 +5850,7 @@ gl_lib_init(void)
// Current ctx & sfc stuff // Current ctx & sfc stuff
if (!_tls_check()) return 0; if (!_tls_check()) return 0;
// dlopen OSMesa // dlopen OSMesa
gl_lib_handle = dlopen("libOSMesa.so.9", RTLD_NOW); 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.8", RTLD_NOW);
if (!gl_lib_handle) gl_lib_handle = dlopen("libOSMesa.so.7", RTLD_NOW); if (!gl_lib_handle) gl_lib_handle = dlopen("libOSMesa.so.7", RTLD_NOW);

View File

@ -748,9 +748,10 @@ eng_output_dump(void *engine EINA_UNUSED, void *data)
{ {
Outbuf *ob; Outbuf *ob;
Render_Engine *re; Render_Engine *re;
Render_Engine_GL_Generic *e = engine;
if (!(re = (Render_Engine *)data)) return; if (!(re = (Render_Engine *)data)) return;
generic_cache_dump(e->software.surface_cache);
evas_common_image_image_all_unload(); evas_common_image_image_all_unload();
evas_common_font_font_all_unload(); evas_common_font_font_all_unload();
ob = eng_get_ob(re); ob = eng_get_ob(re);