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; GLint ok = 0; 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 1 // TODO: 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"); glGetProgramiv(p->prog, GL_LINK_STATUS, &ok); GLERR(__FUNCTION__, __FILE__, __LINE__, ""); if (!ok) { gl_compile_link_error(p->prog, "load a program object"); ERR("Abort load of program (%s)", pname); goto finish; } res = 1; finish: if (formats) free(formats); if (data) free(data); if ((!res) && (p->prog)) { glDeleteProgram(p->prog); p->prog = 0; } return res; }
static Evas_GL_Program * _evas_gl_common_shader_program_binary_load(Eet_File *ef, unsigned int flags) { int num = 0, length = 0; int *formats = NULL; void *data = NULL; char pname[32]; GLint ok = 0, prg, vtx = GL_NONE, frg = GL_NONE; Evas_GL_Program *p = NULL; Eina_Bool direct = 1; if (!ef || !glsym_glProgramBinary) return NULL; sprintf(pname, SHADER_PROG_NAME_FMT, flags); data = (void *) eet_read_direct(ef, pname, &length); if (!data) { data = eet_read(ef, pname, &length); direct = 0; } 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; prg = glCreateProgram(); #if 1 // TODO: invalid rendering error occurs when attempting to use a // glProgramBinary. in order to render correctly we should create a dummy // vertex shader. vtx = glCreateShader(GL_VERTEX_SHADER); glAttachShader(prg, vtx); frg = glCreateShader(GL_FRAGMENT_SHADER); glAttachShader(prg, frg); #endif glsym_glProgramBinary(prg, formats[0], data, length); _attributes_bind(prg); glGetProgramiv(prg, GL_LINK_STATUS, &ok); if (!ok) { gl_compile_link_error(prg, "load a program object", EINA_FALSE); ERR("Abort load of program (%s)", pname); glDeleteProgram(prg); goto finish; } p = calloc(1, sizeof(*p)); p->flags = flags; p->prog = prg; p->reset = EINA_TRUE; p->bin_saved = EINA_TRUE; p->uniform.mvp = glGetUniformLocation(prg, "mvp"); p->uniform.rotation_id = glGetUniformLocation(prg, "rotation_id"); evas_gl_common_shader_textures_bind(p); finish: if (vtx) glDeleteShader(vtx); if (frg) glDeleteShader(frg); free(formats); if (!direct) free(data); return p; }