forked from enlightenment/efl
evas gl: recover current program state.
Summary: When we meets a new shader program in shape_context_push(), it loads a shader binary, if it is necessary, create a new program for the shader. In this step, the current program state could changed to this new one. But still our gl context by shader_flush() could keep the previous program for next shader flush. But it doens't know current program was changed by dropping by. Here is a simple scenario: 1. evas_gl_common_context_image_push(): This image requires Program A. it calls evas_gl_common_context_push() internally. then shader_array_flush() instantly. It stores the current context including shader program(Program A) 2. evas_gl_common_context_xxx_push(): call evas_gl_common_shader_program_get(). xxx draws first time, it loads a new shader program. Now this changed the current program to a new instant one. ... 3. shader_array_flush(): draw image which requires Prorgam A (No.1). Unfortunately, stored context is same to this. So, it skips some gl context setting including shader program. @fix Reviewers: #committers Subscribers: cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D7309
This commit is contained in:
parent
c9d20d488b
commit
c71a561997
|
@ -695,7 +695,7 @@ Evas_GL_Program *evas_gl_common_shader_program_get(Evas_Engine_GL_Context *gc,
|
|||
Eina_Bool alphaonly,
|
||||
Shader_Sampling *psam, int *pnomul,
|
||||
Shader_Sampling *pmasksam);
|
||||
void evas_gl_common_shader_textures_bind(Evas_GL_Program *p);
|
||||
void evas_gl_common_shader_textures_bind(Evas_GL_Program *p, Eina_Bool recover_prog);
|
||||
|
||||
Eina_Bool evas_gl_common_file_cache_is_dir(const char *file);
|
||||
Eina_Bool evas_gl_common_file_cache_mkdir(const char *dir);
|
||||
|
|
|
@ -174,13 +174,21 @@ _evas_gl_common_shader_program_binary_load(Eet_File *ef, unsigned int flags)
|
|||
}
|
||||
|
||||
p = calloc(1, sizeof(*p));
|
||||
|
||||
GLuint curr_prog = 0;
|
||||
glGetIntegerv(GL_CURRENT_PROGRAM, (GLint *)&curr_prog);
|
||||
|
||||
p->flags = flags;
|
||||
p->prog = prg;
|
||||
p->reset = EINA_TRUE;
|
||||
p->bin_saved = EINA_TRUE;
|
||||
|
||||
glUseProgram(prg);
|
||||
p->uniform.mvp = glGetUniformLocation(prg, "mvp");
|
||||
p->uniform.rotation_id = glGetUniformLocation(prg, "rotation_id");
|
||||
evas_gl_common_shader_textures_bind(p);
|
||||
evas_gl_common_shader_textures_bind(p, EINA_FALSE);
|
||||
|
||||
glUseProgram(curr_prog);
|
||||
|
||||
finish:
|
||||
if (vtx) glDeleteShader(vtx);
|
||||
|
@ -598,7 +606,7 @@ evas_gl_common_shader_generate_and_compile(Evas_GL_Shared *shared, unsigned int
|
|||
shared->needs_shaders_flush = 1;
|
||||
p->uniform.mvp = glGetUniformLocation(p->prog, "mvp");
|
||||
p->uniform.rotation_id = glGetUniformLocation(p->prog, "rotation_id");
|
||||
evas_gl_common_shader_textures_bind(p);
|
||||
evas_gl_common_shader_textures_bind(p, EINA_TRUE);
|
||||
eina_hash_add(shared->shaders_hash, &flags, p);
|
||||
}
|
||||
else WRN("Failed to compile a shader (flags: %08x)", flags);
|
||||
|
@ -654,7 +662,7 @@ evas_gl_common_shader_program_init(Evas_GL_Shared *shared)
|
|||
p = _evas_gl_common_shader_program_binary_load(shared->shaders_cache, autoload[i]);
|
||||
if (p)
|
||||
{
|
||||
evas_gl_common_shader_textures_bind(p);
|
||||
evas_gl_common_shader_textures_bind(p, EINA_TRUE);
|
||||
eina_hash_add(shared->shaders_hash, &autoload[i], p);
|
||||
}
|
||||
}
|
||||
|
@ -878,7 +886,7 @@ end:
|
|||
}
|
||||
|
||||
void
|
||||
evas_gl_common_shader_textures_bind(Evas_GL_Program *p)
|
||||
evas_gl_common_shader_textures_bind(Evas_GL_Program *p, Eina_Bool prog_recover)
|
||||
{
|
||||
struct {
|
||||
const char *name;
|
||||
|
@ -935,6 +943,9 @@ evas_gl_common_shader_textures_bind(Evas_GL_Program *p)
|
|||
|
||||
if (hastex)
|
||||
{
|
||||
GLuint curr_prog = 0;
|
||||
if (prog_recover) glGetIntegerv(GL_CURRENT_PROGRAM, (GLint *)&curr_prog);
|
||||
|
||||
glUseProgram(p->prog); // is this necessary??
|
||||
for (i = 0; textures[i].name; i++)
|
||||
{
|
||||
|
@ -947,6 +958,7 @@ evas_gl_common_shader_textures_bind(Evas_GL_Program *p)
|
|||
}
|
||||
glUniform1i(loc, p->tex_count++);
|
||||
}
|
||||
if (prog_recover) glUseProgram(curr_prog);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -981,7 +993,7 @@ evas_gl_common_shader_program_get(Evas_Engine_GL_Context *gc,
|
|||
p = _evas_gl_common_shader_program_binary_load(gc->shared->shaders_cache, flags);
|
||||
if (p)
|
||||
{
|
||||
evas_gl_common_shader_textures_bind(p);
|
||||
evas_gl_common_shader_textures_bind(p, EINA_TRUE);
|
||||
eina_hash_add(gc->shared->shaders_hash, &flags, p);
|
||||
goto end;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue