From: Jiyoun Park <jy0703.park@samsung.com>

Subject: [E-devel] [Patch] Evas gl shader use binary shader

I make patch related with evas gl binary shader.
 
The concept of binary shader is  compile shader only once.
 
Some people want to use binary shader because of performance issue.
 
In current evas gl engine, every application have to compile shader each
time. 

But I modify code , so only first running application need compile shader.

Other application use already compiled shader(binary shader)

 
The binary shader is made under HOME/.evas/gl_common_shaders directory. 

Binary shader is created according to GL vendor,GL renderer, GL version and
Module_arch.

The basic flow is
 
1.     First running application which use gl engine check binary shader
directory, but it can't find binary shader. 
2.     After compiling shader, It saves compiled shaders..
3.     Other application checks shader directory, it can use binary
shaders.
 
In mobile target, using binary shader, I can save 150ms. (that time, there
is 11 shaders).

If there is more shaders and more applications, this flow maybe save more
total time. 

(the above is now in, changelog coming, with change to using ~/.cache,
some formatting fixes, make ity do the desktop gl one right with the
retrievable hint parameter ont he program etc. - doesn't break desktop
gl at least. yay. a,so fixes to mke it compile at all).



SVN revision: 59167
This commit is contained in:
Jiyoun Park 2011-05-04 06:15:00 +00:00 committed by Carsten Haitzler
parent cc9bc35e59
commit 56111d2b69
6 changed files with 565 additions and 147 deletions

View File

@ -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

View File

@ -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 = \

View File

@ -12,6 +12,7 @@
#include <math.h>
#include <sys/time.h>
#include <unistd.h>
#include <Eet.h>
#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);

View File

@ -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__, "");

View File

@ -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);
}

View File

@ -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