diff --git a/src/modules/evas/engines/gl_common/evas_gl_common.h b/src/modules/evas/engines/gl_common/evas_gl_common.h index 23eddef590..d044c16575 100644 --- a/src/modules/evas/engines/gl_common/evas_gl_common.h +++ b/src/modules/evas/engines/gl_common/evas_gl_common.h @@ -103,6 +103,9 @@ typedef Eina_Bool (*evas_gl_make_current_cb)(void *engine_data, void *doit); struct _Evas_GL_Program { unsigned int flags, hitcount, tex_count; + struct { + GLuint mvp, rotation_id; + } uniform; GLuint prog; Eina_Bool reset : 1; diff --git a/src/modules/evas/engines/gl_common/evas_gl_context.c b/src/modules/evas/engines/gl_common/evas_gl_context.c index a13b8b58e5..df2cad24d9 100644 --- a/src/modules/evas/engines/gl_common/evas_gl_context.c +++ b/src/modules/evas/engines/gl_common/evas_gl_context.c @@ -726,17 +726,11 @@ _evas_gl_common_viewport_set(Evas_Engine_GL_Context *gc) eina_iterator_free(it); if (gc->state.current.prog != PRG_INVALID) - /* { - glUseProgram(gc->shared->shader[0].prog); - glUniformMatrix4fv(glGetUniformLocation(gc->shared->shader[0].prog, "mvp"), 1, GL_FALSE, gc->shared->proj); - gc->shared->shader[0].reset = EINA_FALSE; - } - else - */ - { - glUseProgram(gc->state.current.prog->prog); - glUniformMatrix4fv(glGetUniformLocation(gc->state.current.prog->prog, "mvp"), 1, GL_FALSE, gc->shared->proj); + prog = gc->state.current.prog; + glUseProgram(prog->prog); + glUniform1i(prog->uniform.rotation_id, gc->rot / 90); + glUniformMatrix4fv(prog->uniform.mvp, 1, GL_FALSE, gc->shared->proj); } } @@ -1442,9 +1436,20 @@ _push_mask(Evas_Engine_GL_Context *gc, const int pn, int nm, Evas_GL_Texture *mt if (!gw || !gh || !mw || !mh || !mtex->pt->w || !mtex->pt->h) return EINA_FALSE; - /* vertex shader: - * vec4 mask_Position = mvp * vertex * vec4(0.5, sign(mask_coord.w) * 0.5, 0.5, 0.5) + vec4(0.5, 0.5, 0, 0); - * tex_m = mask_Position.xy * abs(mask_coord.zw) + mask_coord.xy; + /* Vertex shader: + * + * INPUTS: + * vec4 mask_coord = vec4(glmx, glmy, glmw, glmh); + * int rotation_id = gc->rot / 90; + * + * CODE: + * vec4 mask_Position = mvp * vertex * vec4(0.5, sign(mask_coord.w) * 0.5, 0.5, 0.5) + vec4(0.5, 0.5, 0, 0); + * vec2 pos[4]; // no ctor-style init because of GLSL-ES (version 100) + * pos[0] = vec2(mask_Position.xy); + * pos[1] = vec2(1.0 - mask_Position.y, mask_Position.x); + * pos[2] = vec2(1.0 - mask_Position.xy); + * pos[3] = vec2(mask_Position.y, 1.0 - mask_Position.x); + * tex_m = pos[rotation_id].xy * abs(mask_coord.zw) + mask_coord.xy; */ glmx = (double)((mtex->x * mw) - (mtex->w * mx)) / (double)(mw * mtex->pt->w); glmy = (double)((mtex->y * mh) - (mtex->h * my)) / (double)(mh * mtex->pt->h); @@ -1465,13 +1470,6 @@ _push_mask(Evas_Engine_GL_Context *gc, const int pn, int nm, Evas_GL_Texture *mt PUSH_MASKSAM(pn, samx, samy, cnt); } - /* - DBG("%d,%d %dx%d --> %f , %f - %f x %f [gc %dx%d, tex %d,%d %dx%d, pt %dx%d]", - mx, my, mw, mh, - glmx, glmy, glmw, glmh, - gc->w, gc->h, mtex->x, mtex->y, mtex->w, mtex->h, mtex->pt->w, mtex->pt->h); - */ - return EINA_TRUE; } @@ -3032,7 +3030,8 @@ shader_array_flush(Evas_Engine_GL_Context *gc) glUseProgram(prog->prog); if (prog->reset) { - glUniformMatrix4fv(glGetUniformLocation(prog->prog, "mvp"), 1, GL_FALSE, gc->shared->proj); + glUniform1i(prog->uniform.rotation_id, gc->rot / 90); + glUniformMatrix4fv(prog->uniform.mvp, 1, GL_FALSE, gc->shared->proj); prog->reset = EINA_FALSE; } } 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 291beada04..d80d77976f 100644 --- a/src/modules/evas/engines/gl_common/evas_gl_shader.c +++ b/src/modules/evas/engines/gl_common/evas_gl_shader.c @@ -160,6 +160,8 @@ _evas_gl_common_shader_program_binary_load(Eet_File *ef, unsigned int 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: @@ -566,6 +568,8 @@ evas_gl_common_shader_generate_and_compile(Evas_GL_Shared *shared, unsigned int if (p) { 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); eina_hash_add(shared->shaders_hash, &flags, p); } diff --git a/src/modules/evas/engines/gl_common/shader/evas_gl_shaders.x b/src/modules/evas/engines/gl_common/shader/evas_gl_shaders.x index 558531a50b..195ed19bb6 100644 --- a/src/modules/evas/engines/gl_common/shader/evas_gl_shaders.x +++ b/src/modules/evas/engines/gl_common/shader/evas_gl_shaders.x @@ -155,7 +155,7 @@ static const char fragment_glsl[] = " * col\n" "#endif\n" "#ifdef SHD_MASK\n" - " * ma\n" + " * ma\n" "#endif\n" "#ifdef SHD_TEXA\n" " * texture2D(texa, tex_a).r\n" @@ -174,6 +174,8 @@ static const char vertex_glsl[] = "#endif\n" "attribute vec4 vertex;\n" "uniform mat4 mvp;\n" + "/* Window rotation by id 0,1,2,3 (represents 0,90,180,270) */\n" + "uniform int rotation_id;\n" "/* All except nomul */\n" "#ifndef SHD_NOMUL\n" "attribute vec4 color;\n" @@ -278,8 +280,13 @@ static const char vertex_glsl[] = "#ifdef SHD_MASK\n" " // mask_coord.w contains the Y-invert flag\n" " // position on screen in [0..1] range of current pixel\n" - " vec4 mask_Position = mvp * vertex * vec4(0.5, sign(mask_coord.w) * 0.5, 0.5, 0.5) + vec4(0.5, 0.5, 0, 0);\n" - " tex_m = mask_Position.xy * abs(mask_coord.zw) + mask_coord.xy;\n" + " vec4 window_Position = mvp * vertex * vec4(0.5, sign(mask_coord.w) * 0.5, 0.5, 0.5) + vec4(0.5, 0.5, 0, 0);\n" + " vec2 pos[4];\n" + " pos[0] = vec2(window_Position.xy);\n" + " pos[1] = vec2(1.0 - window_Position.y, window_Position.x);\n" + " pos[2] = vec2(1.0 - window_Position.xy);\n" + " pos[3] = vec2(window_Position.y, 1.0 - window_Position.x);\n" + " tex_m = pos[rotation_id] * abs(mask_coord.zw) + mask_coord.xy;\n" "#endif\n" "}\n"; diff --git a/src/modules/evas/engines/gl_common/shader/fragment.glsl b/src/modules/evas/engines/gl_common/shader/fragment.glsl index b534961300..c20dc71fc7 100644 --- a/src/modules/evas/engines/gl_common/shader/fragment.glsl +++ b/src/modules/evas/engines/gl_common/shader/fragment.glsl @@ -158,7 +158,7 @@ void main() * col #endif #ifdef SHD_MASK - * ma + * ma #endif #ifdef SHD_TEXA * texture2D(texa, tex_a).r diff --git a/src/modules/evas/engines/gl_common/shader/vertex.glsl b/src/modules/evas/engines/gl_common/shader/vertex.glsl index d67eb0684e..0e951167b1 100644 --- a/src/modules/evas/engines/gl_common/shader/vertex.glsl +++ b/src/modules/evas/engines/gl_common/shader/vertex.glsl @@ -9,6 +9,9 @@ VERTEX_SHADER attribute vec4 vertex; uniform mat4 mvp; +/* Window rotation by id 0,1,2,3 (represents 0,90,180,270) */ +uniform int rotation_id; + /* All except nomul */ #ifndef SHD_NOMUL attribute vec4 color; @@ -130,8 +133,13 @@ void main() #ifdef SHD_MASK // mask_coord.w contains the Y-invert flag // position on screen in [0..1] range of current pixel - vec4 mask_Position = mvp * vertex * vec4(0.5, sign(mask_coord.w) * 0.5, 0.5, 0.5) + vec4(0.5, 0.5, 0, 0); - tex_m = mask_Position.xy * abs(mask_coord.zw) + mask_coord.xy; + vec4 window_Position = mvp * vertex * vec4(0.5, sign(mask_coord.w) * 0.5, 0.5, 0.5) + vec4(0.5, 0.5, 0, 0); + vec2 pos[4]; + pos[0] = vec2(window_Position.xy); + pos[1] = vec2(1.0 - window_Position.y, window_Position.x); + pos[2] = vec2(1.0 - window_Position.xy); + pos[3] = vec2(window_Position.y, 1.0 - window_Position.x); + tex_m = pos[rotation_id] * abs(mask_coord.zw) + mask_coord.xy; #endif }