diff --git a/legacy/evas/m4/evas_check_engine.m4 b/legacy/evas/m4/evas_check_engine.m4 index b1f60c7e3a..b968602b93 100644 --- a/legacy/evas/m4/evas_check_engine.m4 +++ b/legacy/evas/m4/evas_check_engine.m4 @@ -113,16 +113,19 @@ if test "x$gl_flavor_gles" = "xyes" ; then fi if test "x${have_dep}" = "xyes" ; then - if test "x$2" = "xyes" ; then - x_libs="${x_libs} -lX11 -lXext -lXrender" - else - x_dir=${x_dir:-/usr/X11R6} - x_cflags=${x_cflags:--I${x_includes:-$x_dir/include}} - x_libs="${x_libs:--L${x_libraries:-$x_dir/lib}} -lX11 -lXext -lXrender" - fi + PKG_CHECK_MODULES([GL_EET], [eet >= 1.4.0], [have_dep="yes"], [have_dep="no"]) + if test "x${have_dep}" = "xyes" ; then + if test "x$2" = "xyes" ; then + x_libs="${x_libs} -lX11 -lXext -lXrender" + else + x_dir=${x_dir:-/usr/X11R6} + x_cflags=${x_cflags:--I${x_includes:-$x_dir/include}} + x_libs="${x_libs:--L${x_libraries:-$x_dir/lib}} -lX11 -lXext -lXrender" + fi evas_engine_[]$1[]_cflags="-I/usr/include ${x_cflags}" evas_engine_[]$1[]_libs="${x_libs} -lGL $gl_pt_lib" evas_engine_gl_common_libs="-lGL $gl_pt_lib" + fi else if test "x$2" = "xyes" ; then x_libs="${x_libs} -lX11 -lXext -lXrender" @@ -147,13 +150,16 @@ else if test "x${have_egl}" = "xyes" ; then AC_CHECK_LIB(GLESv2, glTexImage2D, [have_glesv2="yes"], , -lEGL ${x_libs} -lm $gl_pt_lib) if test "x${have_glesv2}" = "xyes" ; then - evas_engine_[]$1[]_cflags="${x_cflags}" - evas_engine_[]$1[]_libs="${x_libs} -lGLESv2 -lEGL -lm $gl_pt_lib" - evas_engine_gl_common_libs="-lGLESv2 -lm $gl_pt_lib" - have_dep="yes" - gl_flavor_gles="no" - AC_DEFINE(GLES_VARIETY_SGX, 1, [Imagination SGX GLES2 support]) - gles_variety_sgx="yes" + PKG_CHECK_MODULES([GL_EET], [eet >= 1.4.0], [have_dep="yes"], [have_dep="no"]) + if test "x${have_dep}" = "xyes" ; then + evas_engine_[]$1[]_cflags="${x_cflags}" + evas_engine_[]$1[]_libs="${x_libs} -lGLESv2 -lEGL -lm $gl_pt_lib" + evas_engine_gl_common_libs="-lGLESv2 -lm $gl_pt_lib" + have_dep="yes" + gl_flavor_gles="no" + AC_DEFINE(GLES_VARIETY_SGX, 1, [Imagination SGX GLES2 support]) + gles_variety_sgx="yes" + fi fi fi fi diff --git a/legacy/evas/src/modules/engines/gl_common/Makefile.am b/legacy/evas/src/modules/engines/gl_common/Makefile.am index ac74f132f0..2bc7c9566d 100644 --- a/legacy/evas/src/modules/engines/gl_common/Makefile.am +++ b/legacy/evas/src/modules/engines/gl_common/Makefile.am @@ -7,6 +7,7 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/lib/include \ @FREETYPE_CFLAGS@ \ @PIXMAN_CFLAGS@ \ +@GL_EET_CFLAGS@ \ @EINA_CFLAGS@ if BUILD_ENGINE_GL_COMMON @@ -81,9 +82,7 @@ shader/filter_blur_nomul.h \ shader/filter_blur_bgra.h \ shader/filter_blur_bgra_nomul.h - - -libevas_engine_gl_common_la_LIBADD = @EINA_LIBS@ @evas_engine_gl_common_libs@ @dlopen_libs@ +libevas_engine_gl_common_la_LIBADD = @EINA_LIBS@ @GL_EET_LIBS@ @evas_engine_gl_common_libs@ @dlopen_libs@ endif EXTRA_DIST = \ diff --git a/legacy/evas/src/modules/engines/gl_common/evas_gl_common.h b/legacy/evas/src/modules/engines/gl_common/evas_gl_common.h index 8474a7e01a..fb3b9d7a45 100644 --- a/legacy/evas/src/modules/engines/gl_common/evas_gl_common.h +++ b/legacy/evas/src/modules/engines/gl_common/evas_gl_common.h @@ -12,6 +12,7 @@ #include #include #include +#include #define GL_GLEXT_PROTOTYPES @@ -87,6 +88,18 @@ #ifndef EGL_MAP_GL_TEXTURE_STRIDE_IN_BYTES_SEC # define EGL_MAP_GL_TEXTURE_STRIDE_IN_BYTES_SEC 0x3208 #endif +#ifndef GL_PROGRAM_BINARY_LENGTH +# define GL_PROGRAM_BINARY_LENGTH 0x8741 +#endif +#ifndef GL_NUM_PROGRAM_BINARY_FORMATS +# define GL_NUM_PROGRAM_BINARY_FORMATS 0x87FE +#endif +#ifndef GL_PROGRAM_BINARY_FORMATS +# define GL_PROGRAM_BINARY_FORMATS 0x87FF +#endif +#ifndef GL_PROGRAM_BINARY_RETRIEVABLE_HINT +# define GL_PROGRAM_BINARY_RETRIEVABLE_HINT 0x8257 +#endif #define SHAD_VERTEX 0 #define SHAD_COLOR 1 @@ -134,6 +147,7 @@ struct _Evas_GL_Shared Eina_Bool tex_npo2 : 1; Eina_Bool tex_rect : 1; Eina_Bool sec_image_map : 1; + Eina_Bool bin_program : 1; // tuning params - per gpu/cpu combo? #define MAX_CUTOUT 512 #define DEF_CUTOUT 512 @@ -497,10 +511,7 @@ void evas_gl_common_context_image_map_push(Evas_Engine_GL_Context *g Eina_Bool yuv); void evas_gl_common_context_flush(Evas_Engine_GL_Context *gc); -int evas_gl_common_shader_program_init(Evas_GL_Program *p, - Evas_GL_Program_Source *vert, - Evas_GL_Program_Source *frag, - const char *name); +int evas_gl_common_shader_program_init(Evas_GL_Shared *shared); void evas_gl_common_shader_program_init_done(void); void evas_gl_common_shader_program_shutdown(Evas_GL_Program *p); @@ -559,6 +570,9 @@ extern void (*glsym_glGenFramebuffers) (GLsizei a, GLuint *b); extern void (*glsym_glBindFramebuffer) (GLenum a, GLuint b); extern void (*glsym_glFramebufferTexture2D) (GLenum a, GLenum b, GLenum c, GLuint d, GLint e); extern void (*glsym_glDeleteFramebuffers) (GLsizei a, const GLuint *b); +extern void (*glsym_glGetProgramBinary) (GLuint a, GLsizei b, GLsizei *c, GLenum *d, void *e); +extern void (*glsym_glProgramBinary) (GLuint a, GLenum b, const void *c, GLint d); +extern void (*glsym_glProgramParameteri) (GLuint a, GLuint b, GLint d); #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX) extern void *(*secsym_eglCreateImage) (void *a, void *b, GLenum c, void *d, const int *e); diff --git a/legacy/evas/src/modules/engines/gl_common/evas_gl_context.c b/legacy/evas/src/modules/engines/gl_common/evas_gl_context.c index 83ec9cf6ad..639277fd5d 100644 --- a/legacy/evas/src/modules/engines/gl_common/evas_gl_context.c +++ b/legacy/evas/src/modules/engines/gl_common/evas_gl_context.c @@ -11,6 +11,9 @@ void (*glsym_glGenFramebuffers) (GLsizei a, GLuint *b) = NULL; void (*glsym_glBindFramebuffer) (GLenum a, GLuint b) = NULL; void (*glsym_glFramebufferTexture2D) (GLenum a, GLenum b, GLenum c, GLuint d, GLint e) = NULL; void (*glsym_glDeleteFramebuffers) (GLsizei a, const GLuint *b) = NULL; +void (*glsym_glGetProgramBinary) (GLuint a, GLsizei b, GLsizei *c, GLenum *d, void *e) = NULL; +void (*glsym_glProgramBinary) (GLuint a, GLenum b, const void *c, GLint d) = NULL; +void (*glsym_glProgramParameteri) (GLuint a, GLuint b, GLint d) = NULL; #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX) // just used for finding symbols :) @@ -71,6 +74,19 @@ gl_symbols(void) FINDSYM(glsym_glDeleteFramebuffers, "glDeleteFramebuffersARB", glsym_func_void); FALLBAK(glsym_glDeleteFramebuffers, glsym_func_void); + FINDSYM(glsym_glGetProgramBinary, "glGetProgramBinary", glsym_func_void); + FINDSYM(glsym_glGetProgramBinary, "glGetProgramBinaryEXT", glsym_func_void); + FINDSYM(glsym_glGetProgramBinary, "glGetProgramBinaryARB", glsym_func_void); + FINDSYM(glsym_glGetProgramBinary, "glGetProgramBinaryOES", glsym_func_void); + + FINDSYM(glsym_glProgramBinary, "glProgramBinary", glsym_func_void); + FINDSYM(glsym_glProgramBinary, "glProgramBinaryEXT", glsym_func_void); + FINDSYM(glsym_glProgramBinary, "glProgramBinaryARB", glsym_func_void); + + FINDSYM(glsym_glProgramParameteri, "glProgramParameteri", glsym_func_void); + FINDSYM(glsym_glProgramParameteri, "glProgramParameteriEXT", glsym_func_void); + FINDSYM(glsym_glProgramParameteri, "glProgramParameteriARB", glsym_func_void); + #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX) #undef FINDSYM #define FINDSYM(dst, sym, typ) \ @@ -97,6 +113,24 @@ gl_symbols(void) FINDSYM(secsym_eglDestroyImage, "eglDestroyImageARB", secsym_func_uint); FINDSYM(secsym_eglDestroyImage, "eglDestroyImageKHR", secsym_func_uint); + FINDSYM(glsym_glGetProgramBinary, "glGetProgramBinary", glsym_func_void); + FINDSYM(glsym_glGetProgramBinary, "glGetProgramBinaryEXT", glsym_func_void); + FINDSYM(glsym_glGetProgramBinary, "glGetProgramBinaryARB", glsym_func_void); + FINDSYM(glsym_glGetProgramBinary, "glGetProgramBinaryOES", glsym_func_void); + FINDSYM(glsym_glGetProgramBinary, "glGetProgramBinaryKHR", glsym_func_void); + + FINDSYM(glsym_glProgramBinary, "glProgramBinary", glsym_func_void); + FINDSYM(glsym_glProgramBinary, "glProgramBinaryEXT", glsym_func_void); + FINDSYM(glsym_glProgramBinary, "glProgramBinaryARB", glsym_func_void); + FINDSYM(glsym_glProgramBinary, "glProgramBinaryOES", glsym_func_void); + FINDSYM(glsym_glProgramBinary, "glProgramBinaryKHR", glsym_func_void); + + FINDSYM(glsym_glProgramParameteri, "glProgramParameteri", glsym_func_void); + FINDSYM(glsym_glProgramParameteri, "glProgramParameteriEXT", glsym_func_void); + FINDSYM(glsym_glProgramParameteri, "glProgramParameteriARB", glsym_func_void); + FINDSYM(glsym_glProgramParameteri, "glProgramParameteriOES", glsym_func_void); + FINDSYM(glsym_glProgramParameteri, "glProgramParameteriKHR", glsym_func_void); + FINDSYM(secsym_glEGLImageTargetTexture2DOES, "glEGLImageTargetTexture2DOES", glsym_func_void); FINDSYM(secsym_eglMapImageSEC, "eglMapImageSEC", secsym_func_void_ptr); @@ -607,6 +641,9 @@ evas_gl_common_context_new(void) (strstr((char *)ext, "GL_EXT_texture_rectangle")) || (strstr((char *)ext, "GL_ARB_texture_rectangle"))) shared->info.tex_rect = 1; + if ((strstr((char *)ext, "GL_ARB_get_program_binary")) || + (strstr((char *)ext, "GL_OES_get_program_binary"))) + shared->info.bin_program = 1; #ifdef GL_TEXTURE_MAX_ANISOTROPY_EXT if ((strstr((char *)ext, "GL_EXT_texture_filter_anisotropic"))) glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, @@ -765,122 +802,7 @@ evas_gl_common_context_new(void) glEnableVertexAttribArray(SHAD_COLOR); GLERR(__FUNCTION__, __FILE__, __LINE__, ""); - if (!evas_gl_common_shader_program_init(&(shared->shader.rect), - &(shader_rect_vert_src), - &(shader_rect_frag_src), - "rect")) goto error; - if (!evas_gl_common_shader_program_init(&(shared->shader.font), - &(shader_font_vert_src), - &(shader_font_frag_src), - "font")) goto error; - if (!evas_gl_common_shader_program_init(&(shared->shader.img), - &(shader_img_vert_src), - &(shader_img_frag_src), - "img")) goto error; - if (!evas_gl_common_shader_program_init(&(shared->shader.img_nomul), - &(shader_img_nomul_vert_src), - &(shader_img_nomul_frag_src), - "img_nomul")) goto error; - if (!evas_gl_common_shader_program_init(&(shared->shader.img_bgra), - &(shader_img_bgra_vert_src), - &(shader_img_bgra_frag_src), - "img_bgra")) goto error; - if (!evas_gl_common_shader_program_init(&(shared->shader.img_bgra_nomul), - &(shader_img_bgra_nomul_vert_src), - &(shader_img_bgra_nomul_frag_src), - "img_bgra_nomul")) goto error; - if (!evas_gl_common_shader_program_init(&(shared->shader.img_mask), - &(shader_img_mask_vert_src), - &(shader_img_mask_frag_src), - "img_mask")) goto error; - if (!evas_gl_common_shader_program_init(&(shared->shader.tex), - &(shader_tex_vert_src), - &(shader_tex_frag_src), - "tex")) goto error; - if (!evas_gl_common_shader_program_init(&(shared->shader.tex_nomul), - &(shader_tex_nomul_vert_src), - &(shader_tex_nomul_frag_src), - "tex_nomul")) goto error; - if (!evas_gl_common_shader_program_init(&(shared->shader.yuv), - &(shader_yuv_vert_src), - &(shader_yuv_frag_src), - "yuv")) goto error; - if (!evas_gl_common_shader_program_init(&(shared->shader.yuv_nomul), - &(shader_yuv_nomul_vert_src), - &(shader_yuv_nomul_frag_src), - "yuv_nomul")) goto error; - - /* Most of the filters use the image fragment shader */ - if (!evas_gl_common_shader_program_init(&(shared->shader.filter_invert), - &(shader_img_vert_src), - &(shader_filter_invert_frag_src), - "filter_invert")) goto error; - if (!evas_gl_common_shader_program_init(&(shared->shader.filter_invert_nomul), - &(shader_img_vert_src), - &(shader_filter_invert_nomul_frag_src), - "filter_invert_nomul")) goto error; - if (!evas_gl_common_shader_program_init(&(shared->shader.filter_invert_bgra), - &(shader_img_vert_src), - &(shader_filter_invert_bgra_frag_src), - "filter_invert_bgra")) goto error; - if (!evas_gl_common_shader_program_init(&(shared->shader.filter_invert_bgra_nomul), - &(shader_img_vert_src), - &(shader_filter_invert_bgra_nomul_frag_src), - "filter_invert_bgra_nomul")) goto error; - - if (!evas_gl_common_shader_program_init(&(shared->shader.filter_sepia), - &(shader_img_vert_src), - &(shader_filter_sepia_frag_src), - "filter_sepia")) goto error; - if (!evas_gl_common_shader_program_init(&(shared->shader.filter_sepia_nomul), - &(shader_img_vert_src), - &(shader_filter_sepia_nomul_frag_src), - "filter_sepia_nomul")) goto error; - if (!evas_gl_common_shader_program_init(&(shared->shader.filter_sepia_bgra), - &(shader_img_vert_src), - &(shader_filter_sepia_bgra_frag_src), - "filter_sepia_bgra")) goto error; - if (!evas_gl_common_shader_program_init(&(shared->shader.filter_sepia_bgra_nomul), - &(shader_img_vert_src), - &(shader_filter_sepia_bgra_nomul_frag_src), - "filter_sepia_bgra_nomul")) goto error; - - if (!evas_gl_common_shader_program_init(&(shared->shader.filter_greyscale), - &(shader_img_vert_src), - &(shader_filter_greyscale_frag_src), - "filter_greyscale")) goto error; - if (!evas_gl_common_shader_program_init(&(shared->shader.filter_greyscale_nomul), - &(shader_img_vert_src), - &(shader_filter_greyscale_nomul_frag_src), - "filter_greyscale_nomul")) goto error; - if (!evas_gl_common_shader_program_init(&(shared->shader.filter_greyscale_bgra), - &(shader_img_vert_src), - &(shader_filter_greyscale_bgra_frag_src), - "filter_greyscale_bgra")) goto error; - if (!evas_gl_common_shader_program_init(&(shared->shader.filter_greyscale_bgra_nomul), - &(shader_img_vert_src), - &(shader_filter_greyscale_bgra_nomul_frag_src), - "filter_greyscale_bgra_nomul")) goto error; -#if 0 - if (!evas_gl_common_shader_program_init(&(shared->shader.filter_blur), - &(shader_filter_blur_vert_src), - &(shader_filter_blur_frag_src), - "filter_blur")) goto error; - if (!evas_gl_common_shader_program_init(&(shared->shader.filter_blur_nomul), - &(shader_filter_blur_vert_src), - &(shader_filter_blur_nomul_frag_src), - "filter_blur_nomul")) goto error; - if (!evas_gl_common_shader_program_init(&(shared->shader.filter_blur_bgra), - &(shader_filter_blur_vert_src), - &(shader_filter_blur_bgra_frag_src), - "filter_blur_bgra")) goto error; - if (!evas_gl_common_shader_program_init(&(shared->shader.filter_blur_bgra_nomul), - &(shader_filter_blur_vert_src), - &(shader_filter_blur_bgra_nomul_frag_src), - "filter_blur_bgra_nomul")) goto error; -#endif - - + if (!evas_gl_common_shader_program_init(shared)) goto error; glUseProgram(shared->shader.yuv.prog); GLERR(__FUNCTION__, __FILE__, __LINE__, ""); diff --git a/legacy/evas/src/modules/engines/gl_common/evas_gl_shader.c b/legacy/evas/src/modules/engines/gl_common/evas_gl_shader.c index 2a5c69e542..d1c0a72015 100644 --- a/legacy/evas/src/modules/engines/gl_common/evas_gl_shader.c +++ b/legacy/evas/src/modules/engines/gl_common/evas_gl_shader.c @@ -637,14 +637,210 @@ gl_compile_link_error(GLuint target, const char *action) } } -int -evas_gl_common_shader_program_init(Evas_GL_Program *p, - Evas_GL_Program_Source *vert, - Evas_GL_Program_Source *frag, - const char *name) +static mode_t default_mode = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH; + +static Eina_Bool +_evas_gl_shader_file_is_dir(const char *file) +{ + struct stat st; + + if (stat(file, &st) < 0) return EINA_FALSE; + if (S_ISDIR(st.st_mode)) return EINA_TRUE; + return EINA_FALSE; +} + +static Eina_Bool +_evas_gl_shader_file_mkdir(const char *dir) +{ + /* evas gl shader only call this function when the dir is not exist */ + if (mkdir(dir, default_mode) < 0) return EINA_FALSE; + return EINA_TRUE; +} + +static Eina_Bool +_evas_gl_shader_file_exists(const char *file) +{ + struct stat st; + if (!file) return EINA_FALSE; + if (stat(file, &st) < 0) return EINA_FALSE; + + return EINA_TRUE; +} + +static inline Eina_Bool +_evas_gl_shader_file_mkpath_if_not_exists(const char *path) +{ + struct stat st; + + if (stat(path, &st) < 0) + return _evas_gl_shader_file_mkdir(path); + else if (!S_ISDIR(st.st_mode)) + return EINA_FALSE; + else + return EINA_TRUE; +} + +static Eina_Bool +_evas_gl_shader_file_mkpath(const char *path) +{ + char ss[PATH_MAX]; + unsigned int i; + + if (_evas_gl_shader_file_is_dir(path)) return EINA_TRUE; + + for (i = 0; path[i]; ss[i] = path[i], i++) + { + if (i == sizeof(ss) - 1) return EINA_FALSE; + if ((path[i] == '/') && (i > 0)) + { + ss[i] = 0; + if (!_evas_gl_shader_file_mkpath_if_not_exists(ss)) + return EINA_FALSE; + } + } + ss[i] = 0; + return _evas_gl_shader_file_mkpath_if_not_exists(ss); +} + +static int +_evas_gl_shader_dir_check(char *bin_shader_dir, int num) +{ + char *home = NULL; + char *subdir = ".cache/evas_gl_common_shaders"; + + home = getenv("HOME"); + if ((!home) || (!home[0])) return 0; + + snprintf(bin_shader_dir, num, "%s/%s", home, subdir); + return _evas_gl_shader_file_exists(bin_shader_dir); +} + +static int +_evas_gl_shader_file_check(const char *bin_shader_dir, char *bin_shader_file, int dir_num) +{ + char before_name[PATH_MAX]; + char after_name[PATH_MAX]; + int new_path_len = 0; + int i = 0, j = 0; + + char *vendor = NULL; + char *driver = NULL; + char *version = NULL; + + vendor = (char *)glGetString(GL_VENDOR); + driver = (char *)glGetString(GL_RENDERER); + version = (char *)glGetString(GL_VERSION); + + new_path_len = snprintf(before_name, sizeof(before_name), "%s::%s::%s::%s::binary_shader.eet", vendor, version, driver, MODULE_ARCH); + + /* remove '/' from file name */ + for (i = 0; i < new_path_len; i++) + { + if (before_name[i] != '/') + { + after_name[j] = before_name[i]; + j++; + } + } + after_name[j] = 0; + + snprintf(bin_shader_file, dir_num, "%s/%s", bin_shader_dir, after_name); + + return _evas_gl_shader_file_exists(bin_shader_file); +} + +static int +_evas_gl_common_shader_program_binary_init(Evas_GL_Program *p, + const char *pname, + Eet_File *ef) +{ + int res = 0, num = 0, length = 0; + int *formats = NULL; + void *data = NULL; + + if (!ef) return res; + + data = eet_read(ef, pname, &length); + if ((!data) || (length <= 0)) goto finish; + + glGetIntegerv(GL_NUM_PROGRAM_BINARY_FORMATS, &num); + if (num <= 0) goto finish; + + formats = calloc(num, sizeof(int)); + if (!formats) goto finish; + + glGetIntegerv(GL_PROGRAM_BINARY_FORMATS, formats); + if (!formats[0]) goto finish; + + p->prog = glCreateProgram(); + +#if 0 + // TOOD: invalid rendering error occurs when attempting to use a glProgramBinary. + // in order to render correctly we should create a dummy vertex shader. + p->vert = glCreateShader(GL_VERTEX_SHADER); + glAttachShader(p->prog, p->vert); + p->frag = glCreateShader(GL_FRAGMENT_SHADER); + glAttachShader(p->prog, p->frag); +#endif + glsym_glProgramBinary(p->prog, formats[0], data, length); + + glBindAttribLocation(p->prog, SHAD_VERTEX, "vertex"); + glBindAttribLocation(p->prog, SHAD_COLOR, "color"); + glBindAttribLocation(p->prog, SHAD_TEXUV, "tex_coord"); + glBindAttribLocation(p->prog, SHAD_TEXUV2, "tex_coord2"); + glBindAttribLocation(p->prog, SHAD_TEXUV3, "tex_coord3"); + glBindAttribLocation(p->prog, SHAD_TEXM, "tex_coordm"); + res = 1; + +finish: + if (formats) free(formats); + if (data) free(data); + if ((!res) && (p->prog)) + { + glDeleteProgram(p->prog); + p->prog = 0; + } + return res; +} + +static int +_evas_gl_common_shader_program_binary_save(Evas_GL_Program *p, + const char *pname, + Eet_File *ef) +{ + void* data = NULL; + GLenum format; + int length = 0; + + if (!glsym_glGetProgramBinary) return 0; + + glGetProgramiv(p->prog, GL_PROGRAM_BINARY_LENGTH, &length); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + if (length <= 0) return 0; + + data = malloc(length); + if (!data) return 0; + + glsym_glGetProgramBinary(p->prog, length, NULL, &format, data); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + + if (eet_write(ef, pname, data, length, 0) < 0) + { + if (data) free(data); + return 0; + } + if (data) free(data); + return 1; +} + +static int +_evas_gl_common_shader_program_source_init(Evas_GL_Program *p, + Evas_GL_Program_Source *vert, + Evas_GL_Program_Source *frag, + const char *name) { GLint ok; - + p->vert = glCreateShader(GL_VERTEX_SHADER); p->frag = glCreateShader(GL_FRAGMENT_SHADER); #if defined (GLES_VARIETY_S3C6410) @@ -683,6 +879,12 @@ evas_gl_common_shader_program_init(Evas_GL_Program *p, } #endif p->prog = glCreateProgram(); +#if defined(GLES_VARIETY_S3C6410) || defined(GLES_VARIETY_SGX) +#else + if ((glsym_glGetProgramBinary) && (glsym_glProgramParameteri)) + glsym_glProgramParameteri(p->prog, GL_PROGRAM_BINARY_RETRIEVABLE_HINT, + GL_TRUE); +#endif glAttachShader(p->prog, p->vert); GLERR(__FUNCTION__, __FILE__, __LINE__, ""); glAttachShader(p->prog, p->frag); @@ -716,6 +918,280 @@ evas_gl_common_shader_program_init(Evas_GL_Program *p, return 1; } +static int +_evas_gl_common_shader_source_init(Evas_GL_Shared *shared) +{ + if (!_evas_gl_common_shader_program_source_init(&(shared->shader.rect), + &(shader_rect_vert_src), + &(shader_rect_frag_src), + "rect")) return 0; + if (!_evas_gl_common_shader_program_source_init(&(shared->shader.font), + &(shader_font_vert_src), + &(shader_font_frag_src), + "font")) return 0; + if (!_evas_gl_common_shader_program_source_init(&(shared->shader.img), + &(shader_img_vert_src), + &(shader_img_frag_src), + "img")) return 0; + if (!_evas_gl_common_shader_program_source_init(&(shared->shader.img_nomul), + &(shader_img_nomul_vert_src), + &(shader_img_nomul_frag_src), + "img_nomul")) return 0; + if (!_evas_gl_common_shader_program_source_init(&(shared->shader.img_bgra), + &(shader_img_bgra_vert_src), + &(shader_img_bgra_frag_src), + "img_bgra")) return 0; + if (!_evas_gl_common_shader_program_source_init(&(shared->shader.img_bgra_nomul), + &(shader_img_bgra_nomul_vert_src), + &(shader_img_bgra_nomul_frag_src), + "img_bgra_nomul")) return 0; + if (!_evas_gl_common_shader_program_source_init(&(shared->shader.img_mask), + &(shader_img_mask_vert_src), + &(shader_img_mask_frag_src), + "img_mask")) return 0; + if (!_evas_gl_common_shader_program_source_init(&(shared->shader.tex), + &(shader_tex_vert_src), + &(shader_tex_frag_src), + "tex")) return 0; + if (!_evas_gl_common_shader_program_source_init(&(shared->shader.tex_nomul), + &(shader_tex_nomul_vert_src), + &(shader_tex_nomul_frag_src), + "tex_nomul")) return 0; + if (!_evas_gl_common_shader_program_source_init(&(shared->shader.yuv), + &(shader_yuv_vert_src), + &(shader_yuv_frag_src), + "yuv")) return 0; + if (!_evas_gl_common_shader_program_source_init(&(shared->shader.yuv_nomul), + &(shader_yuv_nomul_vert_src), + &(shader_yuv_nomul_frag_src), + "yuv_nomul")) return 0; + + /* Most of the filters use the image fragment shader */ + if (!_evas_gl_common_shader_program_source_init(&(shared->shader.filter_invert), + &(shader_img_vert_src), + &(shader_filter_invert_frag_src), + "filter_invert")) return 0; + if (!_evas_gl_common_shader_program_source_init(&(shared->shader.filter_invert_nomul), + &(shader_img_vert_src), + &(shader_filter_invert_nomul_frag_src), + "filter_invert_nomul")) return 0; + if (!_evas_gl_common_shader_program_source_init(&(shared->shader.filter_invert_bgra), + &(shader_img_vert_src), + &(shader_filter_invert_bgra_frag_src), + "filter_invert_bgra")) return 0; + if (!_evas_gl_common_shader_program_source_init(&(shared->shader.filter_invert_bgra_nomul), + &(shader_img_vert_src), + &(shader_filter_invert_bgra_nomul_frag_src), + "filter_invert_bgra_nomul")) return 0; + + if (!_evas_gl_common_shader_program_source_init(&(shared->shader.filter_sepia), + &(shader_img_vert_src), + &(shader_filter_sepia_frag_src), + "filter_sepia")) return 0; + if (!_evas_gl_common_shader_program_source_init(&(shared->shader.filter_sepia_nomul), + &(shader_img_vert_src), + &(shader_filter_sepia_nomul_frag_src), + "filter_sepia_nomul")) return 0; + if (!_evas_gl_common_shader_program_source_init(&(shared->shader.filter_sepia_bgra), + &(shader_img_vert_src), + &(shader_filter_sepia_bgra_frag_src), + "filter_sepia_bgra")) return 0; + if (!_evas_gl_common_shader_program_source_init(&(shared->shader.filter_sepia_bgra_nomul), + &(shader_img_vert_src), + &(shader_filter_sepia_bgra_nomul_frag_src), + "filter_sepia_bgra_nomul")) return 0; + + if (!_evas_gl_common_shader_program_source_init(&(shared->shader.filter_greyscale), + &(shader_img_vert_src), + &(shader_filter_greyscale_frag_src), + "filter_greyscale")) return 0; + if (!_evas_gl_common_shader_program_source_init(&(shared->shader.filter_greyscale_nomul), + &(shader_img_vert_src), + &(shader_filter_greyscale_nomul_frag_src), + "filter_greyscale_nomul")) return 0; + if (!_evas_gl_common_shader_program_source_init(&(shared->shader.filter_greyscale_bgra), + &(shader_img_vert_src), + &(shader_filter_greyscale_bgra_frag_src), + "filter_greyscale_bgra")) return 0; + if (!_evas_gl_common_shader_program_source_init(&(shared->shader.filter_greyscale_bgra_nomul), + &(shader_img_vert_src), + &(shader_filter_greyscale_bgra_nomul_frag_src), + "filter_greyscale_bgra_nomul")) return 0; +#if 0 + if (!_evas_gl_common_shader_program_source_init(&(shared->shader.filter_blur), + &(shader_filter_blur_vert_src), + &(shader_filter_blur_frag_src), + "filter_blur")) return 0; + if (!_evas_gl_common_shader_program_source_init(&(shared->shader.filter_blur_nomul), + &(shader_filter_blur_vert_src), + &(shader_filter_blur_nomul_frag_src), + "filter_blur_nomul")) return 0; + if (!_evas_gl_common_shader_program_source_init(&(shared->shader.filter_blur_bgra), + &(shader_filter_blur_vert_src), + &(shader_filter_blur_bgra_frag_src), + "filter_blur_bgra")) return 0; + if (!_evas_gl_common_shader_program_source_init(&(shared->shader.filter_blur_bgra_nomul), + &(shader_filter_blur_vert_src), + &(shader_filter_blur_bgra_nomul_frag_src), + "filter_blur_bgra_nomul")) return 0; +#endif + + return 1; +} + +static int +_evas_gl_common_shader_binary_init(Evas_GL_Shared *shared) +{ + /* check eet */ + Eet_File *et = NULL; + + char bin_dir_path[PATH_MAX]; + char bin_file_path[PATH_MAX]; + + if (!_evas_gl_shader_dir_check(bin_dir_path, sizeof(bin_dir_path))) + return 0; + + if (!_evas_gl_shader_file_check(bin_dir_path, bin_file_path, + sizeof(bin_dir_path))) + return 0; + + /* use eet */ + if (!eet_init()) return 0; + et = eet_open(bin_file_path, EET_FILE_MODE_READ); + if (!et) goto error; + + if (!_evas_gl_common_shader_program_binary_init(&(shared->shader.rect), "rect", et)) goto error; + if (!_evas_gl_common_shader_program_binary_init(&(shared->shader.font), "font", et)) goto error; + if (!_evas_gl_common_shader_program_binary_init(&(shared->shader.img), "img", et)) goto error; + if (!_evas_gl_common_shader_program_binary_init(&(shared->shader.img_nomul), "img_nomul", et)) goto error; + if (!_evas_gl_common_shader_program_binary_init(&(shared->shader.img_bgra), "img_bgra", et)) goto error; + if (!_evas_gl_common_shader_program_binary_init(&(shared->shader.img_bgra_nomul), "img_bgra_nomul", et)) goto error; + if (!_evas_gl_common_shader_program_binary_init(&(shared->shader.img_mask), "img_mask", et)) goto error; + if (!_evas_gl_common_shader_program_binary_init(&(shared->shader.tex), "tex", et)) goto error; + if (!_evas_gl_common_shader_program_binary_init(&(shared->shader.tex_nomul),"tex_nomul", et)) goto error; + if (!_evas_gl_common_shader_program_binary_init(&(shared->shader.yuv), "yuv", et)) goto error; + if (!_evas_gl_common_shader_program_binary_init(&(shared->shader.yuv_nomul), "yuv_nomul", et)) goto error; + + /* Most of the filters use the image fragment shader */ + if (!_evas_gl_common_shader_program_binary_init(&(shared->shader.filter_invert), "filter_invert", et)) goto error; + if (!_evas_gl_common_shader_program_binary_init(&(shared->shader.filter_invert_nomul), "filter_invert_nomul", et)) goto error; + if (!_evas_gl_common_shader_program_binary_init(&(shared->shader.filter_invert_bgra), "filter_invert_bgra", et)) goto error; + if (!_evas_gl_common_shader_program_binary_init(&(shared->shader.filter_invert_bgra_nomul), "filter_invert_bgra_nomul", et)) goto error; + + if (!_evas_gl_common_shader_program_binary_init(&(shared->shader.filter_sepia), "filter_sepia", et)) goto error; + if (!_evas_gl_common_shader_program_binary_init(&(shared->shader.filter_sepia_nomul), "filter_sepia_nomul", et)) goto error; + if (!_evas_gl_common_shader_program_binary_init(&(shared->shader.filter_sepia_bgra), "filter_sepia_bgra", et)) goto error; + if (!_evas_gl_common_shader_program_binary_init(&(shared->shader.filter_sepia_bgra_nomul), "filter_sepia_bgra_nomul", et)) goto error; + + if (!_evas_gl_common_shader_program_binary_init(&(shared->shader.filter_greyscale), "filter_greyscale", et)) goto error; + if (!_evas_gl_common_shader_program_binary_init(&(shared->shader.filter_greyscale_nomul), "filter_greyscale_nomul", et)) goto error; + if (!_evas_gl_common_shader_program_binary_init(&(shared->shader.filter_greyscale_bgra), "filter_greyscale_bgra", et)) goto error; + if (!_evas_gl_common_shader_program_binary_init(&(shared->shader.filter_greyscale_bgra_nomul), "filter_greyscale_bgra_nomul", et)) goto error; +#if 0 + if (!_evas_gl_common_shader_program_binary_init(&(shared->shader.filter_blur), "filter_blur", et)) goto error; + if (!_evas_gl_common_shader_program_binary_init(&(shared->shader.filter_blur_nomul), "filter_blur_nomul", et)) goto error; + if (!_evas_gl_common_shader_program_binary_init(&(shared->shader.filter_blur_bgra), "filter_blur_bgra", et)) goto error; + if (!_evas_gl_common_shader_program_binary_init(&(shared->shader.filter_blur_bgra_nomul), "filter_blur_bgra_nomul", et)) goto error; +#endif + + if (et) eet_close(et); + eet_shutdown(); + return 1; + +error: + if (et) eet_close(et); + eet_shutdown(); + return 0; +} + +static int +_evas_gl_common_shader_binary_save(Evas_GL_Shared *shared) +{ + /* check eet */ + Eet_File *et = NULL; //check eet file + int tmpfd; + int res = 0; + char bin_dir_path[PATH_MAX]; + char bin_file_path[PATH_MAX]; + char tmp_file[PATH_MAX]; + + if (!_evas_gl_shader_dir_check(bin_dir_path, sizeof(bin_dir_path))) + res = _evas_gl_shader_file_mkpath(bin_dir_path); + if (!res) return 0; /* we can't make directory */ + + _evas_gl_shader_file_check(bin_dir_path, bin_file_path, + sizeof(bin_dir_path)); + + /* use mkstemp for writing */ + snprintf(tmp_file, sizeof(tmp_file), "%s.XXXXXX", bin_file_path); + tmpfd = mkstemp(tmp_file); + if (tmpfd < 0) goto error; + close(tmpfd); + + /* use eet */ + if (!eet_init()) goto error; + + et = eet_open(tmp_file, EET_FILE_MODE_WRITE); + if (!et) goto error; + + if (!_evas_gl_common_shader_program_binary_save(&(shared->shader.rect), "rect", et)) goto error; + if (!_evas_gl_common_shader_program_binary_save(&(shared->shader.font), "font", et)) goto error; + if (!_evas_gl_common_shader_program_binary_save(&(shared->shader.img), "img", et)) goto error; + if (!_evas_gl_common_shader_program_binary_save(&(shared->shader.img_nomul), "img_nomul", et)) goto error; + if (!_evas_gl_common_shader_program_binary_save(&(shared->shader.img_bgra), "img_bgra", et)) goto error; + if (!_evas_gl_common_shader_program_binary_save(&(shared->shader.img_bgra_nomul), "img_bgra_nomul", et)) goto error; + if (!_evas_gl_common_shader_program_binary_save(&(shared->shader.img_mask), "img_mask", et)) goto error; + if (!_evas_gl_common_shader_program_binary_save(&(shared->shader.tex), "tex", et)) goto error; + if (!_evas_gl_common_shader_program_binary_save(&(shared->shader.tex_nomul),"tex_nomul", et)) goto error; + if (!_evas_gl_common_shader_program_binary_save(&(shared->shader.yuv), "yuv", et)) goto error; + if (!_evas_gl_common_shader_program_binary_save(&(shared->shader.yuv_nomul), "yuv_nomul", et)) goto error; + /* Most of the filters use the image fragment shader */ + if (!_evas_gl_common_shader_program_binary_save(&(shared->shader.filter_invert), "filter_invert", et)) goto error; + if (!_evas_gl_common_shader_program_binary_save(&(shared->shader.filter_invert_nomul), "filter_invert_nomul", et)) goto error; + if (!_evas_gl_common_shader_program_binary_save(&(shared->shader.filter_invert_bgra), "filter_invert_bgra", et)) goto error; + if (!_evas_gl_common_shader_program_binary_save(&(shared->shader.filter_invert_bgra_nomul), "filter_invert_bgra_nomul", et)) goto error; + + if (!_evas_gl_common_shader_program_binary_save(&(shared->shader.filter_sepia), "filter_sepia", et)) goto error; + if (!_evas_gl_common_shader_program_binary_save(&(shared->shader.filter_sepia_nomul), "filter_sepia_nomul", et)) goto error; + if (!_evas_gl_common_shader_program_binary_save(&(shared->shader.filter_sepia_bgra), "filter_sepia_bgra", et)) goto error; + if (!_evas_gl_common_shader_program_binary_save(&(shared->shader.filter_sepia_bgra_nomul), "filter_sepia_bgra_nomul", et)) goto error; + + if (!_evas_gl_common_shader_program_binary_save(&(shared->shader.filter_greyscale), "filter_greyscale", et)) goto error; + if (!_evas_gl_common_shader_program_binary_save(&(shared->shader.filter_greyscale_nomul), "filter_greyscale_nomul", et)) goto error; + if (!_evas_gl_common_shader_program_binary_save(&(shared->shader.filter_greyscale_bgra), "filter_greyscale_bgra", et)) goto error; + if (!_evas_gl_common_shader_program_binary_save(&(shared->shader.filter_greyscale_bgra_nomul), "filter_greyscale_bgra_nomul", et)) goto error; +#if 0 + if (!_evas_gl_common_shader_program_binary_save(&(shared->shader.filter_blur), "filter_blur", et)) goto error; + if (!_evas_gl_common_shader_program_binary_save(&(shared->shader.filter_blur_nomul), "filter_blur_nomul", et)) goto error; + if (!_evas_gl_common_shader_program_binary_save(&(shared->shader.filter_blur_bgra), "filter_blur_bgra", et)) goto error; + if (!_evas_gl_common_shader_program_binary_save(&(shared->shader.filter_blur_bgra_nomul), "filter_blur_bgra_nomul", et)) goto error; +#endif + + if (eet_close(et) != EET_ERROR_NONE) goto error; + if (rename(tmp_file,bin_file_path) < 0) goto error; + eet_shutdown(); + return 1; + +error: + if (et) eet_close(et); + if (_evas_gl_shader_file_exists(tmp_file)) unlink(tmp_file); + eet_shutdown(); + return 0; +} + +int +evas_gl_common_shader_program_init(Evas_GL_Shared *shared) +{ + // gl support binary shader and get env of binary shader path + if (shared->info.bin_program && _evas_gl_common_shader_binary_init(shared)) return 1; + /* compile all shader.*/ + if (!_evas_gl_common_shader_source_init(shared)) return 0; + /* sucess compile all shader. if gl support binary shader, we need to save */ + if (shared->info.bin_program) _evas_gl_common_shader_binary_save(shared); + + return 1; +} + void evas_gl_common_shader_program_init_done(void) { @@ -727,7 +1203,7 @@ evas_gl_common_shader_program_init_done(void) void evas_gl_common_shader_program_shutdown(Evas_GL_Program *p) { - glDeleteShader(p->vert); - glDeleteShader(p->frag); - glDeleteProgram(p->prog); + if (p->vert) glDeleteShader(p->vert); + if (p->frag) glDeleteShader(p->frag); + if (p->prog) glDeleteProgram(p->prog); } diff --git a/legacy/evas/src/modules/engines/gl_x11/Makefile.am b/legacy/evas/src/modules/engines/gl_x11/Makefile.am index 3701a0dd05..ee5bf04877 100644 --- a/legacy/evas/src/modules/engines/gl_x11/Makefile.am +++ b/legacy/evas/src/modules/engines/gl_x11/Makefile.am @@ -9,6 +9,7 @@ AM_CPPFLAGS = \ @FREETYPE_CFLAGS@ \ @PIXMAN_CFLAGS@ \ @EINA_CFLAGS@ \ +@GL_EET_CFLAGS@ \ @evas_engine_gl_x11_cflags@ if BUILD_ENGINE_GL_X11 @@ -29,7 +30,7 @@ pkgdir = $(libdir)/evas/modules/engines/gl_x11/$(MODULE_ARCH) pkg_LTLIBRARIES = module.la module_la_SOURCES = $(GL_X11_SOURCES) -module_la_LIBADD = @EINA_LIBS@ $(GL_X11_LIBADD) $(top_builddir)/src/lib/libevas.la @dlopen_libs@ +module_la_LIBADD = @EINA_LIBS@ @GL_EET_LIBS@ $(GL_X11_LIBADD) $(top_builddir)/src/lib/libevas.la @dlopen_libs@ module_la_LDFLAGS = -module -avoid-version module_la_LIBTOOLFLAGS = --tag=disable-static