summaryrefslogtreecommitdiff
path: root/src/modules/evas/engines/gl_common/evas_gl_shader.c
diff options
context:
space:
mode:
authorHermet Park <hermetpark@gmail.com>2018-11-27 11:25:13 +0900
committerHermet Park <hermetpark@gmail.com>2018-11-27 11:25:13 +0900
commitc71a561997f257b8b6e45a798e77c9a843834060 (patch)
treecac9a612d4e77c4746d4bd56b72d87e789e8e7d1 /src/modules/evas/engines/gl_common/evas_gl_shader.c
parentc9d20d488b7c62f70dd4c05807f854fca76d3fdd (diff)
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
Diffstat (limited to '')
-rw-r--r--src/modules/evas/engines/gl_common/evas_gl_shader.c22
1 files changed, 17 insertions, 5 deletions
diff --git a/src/modules/evas/engines/gl_common/evas_gl_shader.c b/src/modules/evas/engines/gl_common/evas_gl_shader.c
index e6c7a7b8de..a4dd632896 100644
--- a/src/modules/evas/engines/gl_common/evas_gl_shader.c
+++ b/src/modules/evas/engines/gl_common/evas_gl_shader.c
@@ -174,13 +174,21 @@ _evas_gl_common_shader_program_binary_load(Eet_File *ef, unsigned int flags)
174 } 174 }
175 175
176 p = calloc(1, sizeof(*p)); 176 p = calloc(1, sizeof(*p));
177
178 GLuint curr_prog = 0;
179 glGetIntegerv(GL_CURRENT_PROGRAM, (GLint *)&curr_prog);
180
177 p->flags = flags; 181 p->flags = flags;
178 p->prog = prg; 182 p->prog = prg;
179 p->reset = EINA_TRUE; 183 p->reset = EINA_TRUE;
180 p->bin_saved = EINA_TRUE; 184 p->bin_saved = EINA_TRUE;
185
186 glUseProgram(prg);
181 p->uniform.mvp = glGetUniformLocation(prg, "mvp"); 187 p->uniform.mvp = glGetUniformLocation(prg, "mvp");
182 p->uniform.rotation_id = glGetUniformLocation(prg, "rotation_id"); 188 p->uniform.rotation_id = glGetUniformLocation(prg, "rotation_id");
183 evas_gl_common_shader_textures_bind(p); 189 evas_gl_common_shader_textures_bind(p, EINA_FALSE);
190
191 glUseProgram(curr_prog);
184 192
185finish: 193finish:
186 if (vtx) glDeleteShader(vtx); 194 if (vtx) glDeleteShader(vtx);
@@ -598,7 +606,7 @@ evas_gl_common_shader_generate_and_compile(Evas_GL_Shared *shared, unsigned int
598 shared->needs_shaders_flush = 1; 606 shared->needs_shaders_flush = 1;
599 p->uniform.mvp = glGetUniformLocation(p->prog, "mvp"); 607 p->uniform.mvp = glGetUniformLocation(p->prog, "mvp");
600 p->uniform.rotation_id = glGetUniformLocation(p->prog, "rotation_id"); 608 p->uniform.rotation_id = glGetUniformLocation(p->prog, "rotation_id");
601 evas_gl_common_shader_textures_bind(p); 609 evas_gl_common_shader_textures_bind(p, EINA_TRUE);
602 eina_hash_add(shared->shaders_hash, &flags, p); 610 eina_hash_add(shared->shaders_hash, &flags, p);
603 } 611 }
604 else WRN("Failed to compile a shader (flags: %08x)", flags); 612 else WRN("Failed to compile a shader (flags: %08x)", flags);
@@ -654,7 +662,7 @@ evas_gl_common_shader_program_init(Evas_GL_Shared *shared)
654 p = _evas_gl_common_shader_program_binary_load(shared->shaders_cache, autoload[i]); 662 p = _evas_gl_common_shader_program_binary_load(shared->shaders_cache, autoload[i]);
655 if (p) 663 if (p)
656 { 664 {
657 evas_gl_common_shader_textures_bind(p); 665 evas_gl_common_shader_textures_bind(p, EINA_TRUE);
658 eina_hash_add(shared->shaders_hash, &autoload[i], p); 666 eina_hash_add(shared->shaders_hash, &autoload[i], p);
659 } 667 }
660 } 668 }
@@ -878,7 +886,7 @@ end:
878} 886}
879 887
880void 888void
881evas_gl_common_shader_textures_bind(Evas_GL_Program *p) 889evas_gl_common_shader_textures_bind(Evas_GL_Program *p, Eina_Bool prog_recover)
882{ 890{
883 struct { 891 struct {
884 const char *name; 892 const char *name;
@@ -935,6 +943,9 @@ evas_gl_common_shader_textures_bind(Evas_GL_Program *p)
935 943
936 if (hastex) 944 if (hastex)
937 { 945 {
946 GLuint curr_prog = 0;
947 if (prog_recover) glGetIntegerv(GL_CURRENT_PROGRAM, (GLint *)&curr_prog);
948
938 glUseProgram(p->prog); // is this necessary?? 949 glUseProgram(p->prog); // is this necessary??
939 for (i = 0; textures[i].name; i++) 950 for (i = 0; textures[i].name; i++)
940 { 951 {
@@ -947,6 +958,7 @@ evas_gl_common_shader_textures_bind(Evas_GL_Program *p)
947 } 958 }
948 glUniform1i(loc, p->tex_count++); 959 glUniform1i(loc, p->tex_count++);
949 } 960 }
961 if (prog_recover) glUseProgram(curr_prog);
950 } 962 }
951} 963}
952 964
@@ -981,7 +993,7 @@ evas_gl_common_shader_program_get(Evas_Engine_GL_Context *gc,
981 p = _evas_gl_common_shader_program_binary_load(gc->shared->shaders_cache, flags); 993 p = _evas_gl_common_shader_program_binary_load(gc->shared->shaders_cache, flags);
982 if (p) 994 if (p)
983 { 995 {
984 evas_gl_common_shader_textures_bind(p); 996 evas_gl_common_shader_textures_bind(p, EINA_TRUE);
985 eina_hash_add(gc->shared->shaders_hash, &flags, p); 997 eina_hash_add(gc->shared->shaders_hash, &flags, p);
986 goto end; 998 goto end;
987 } 999 }