evas/gl_common: Reset mvp matrix only for shaders that are being used
authorDongyeon Kim <dy5.kim@samsung.com>
Wed, 27 May 2015 00:11:23 +0000 (09:11 +0900)
committerJean-Philippe Andre <jp.andre@samsung.com>
Wed, 3 Jun 2015 02:30:22 +0000 (11:30 +0900)
Summary:
Evas has quite a number of shaders, and resetting the projection matrix
for all shaders takes some time, which is an overhead when target surface
is continuously being changed (ie. when using proxy).
So here we reset the projection matrix for shaders that are actually used.

src/modules/evas/engines/gl_common/evas_gl_common.h
src/modules/evas/engines/gl_common/evas_gl_context.c

index 877842a..3ee8c5b 100644 (file)
@@ -343,6 +343,7 @@ struct _Evas_GL_Program
    GLuint vert, frag, prog;
 
    int tex_count;
+   Eina_Bool reset;
 };
 
 struct _Evas_GL_Program_Source
@@ -444,6 +445,7 @@ struct _Evas_GL_Shared
    // persp map
    int foc, z0, px, py;
    int ax, ay;
+   GLfloat proj[16];
 };
 
 typedef enum _Shader_Sampling Shader_Sampling;
@@ -492,7 +494,7 @@ struct _Evas_Engine_GL_Context
    struct {
       int                top_pipe;
       struct {
-         Evas_GL_Shader  id; // debug info
+         Evas_GL_Shader  id;
          GLuint          cur_prog;
          GLuint          cur_tex, cur_texu, cur_texv, cur_texa, cur_texm;
          int             render_op;
@@ -520,7 +522,7 @@ struct _Evas_Engine_GL_Context
          Eina_Bool       active : 1;
       } clip;
       struct {
-         Evas_GL_Shader  id; // debug info
+         Evas_GL_Shader  id;
          Evas_GL_Image  *surface;
          GLuint          cur_prog;
          GLuint          cur_tex, cur_texu, cur_texv, cur_texa, cur_texm;
index eed625b..9a1ef99 100644 (file)
@@ -482,7 +482,6 @@ _evas_gl_common_version_check(int *gles_ver)
 static void
 _evas_gl_common_viewport_set(Evas_Engine_GL_Context *gc)
 {
-   GLfloat proj[16];
    unsigned int i;
    int w = 1, h = 1, m = 1, rot = 1, foc = 0;
 
@@ -539,14 +538,14 @@ _evas_gl_common_viewport_set(Evas_Engine_GL_Context *gc)
            glViewport(0, 0, h, w);
         // std matrix
         if (m == 1)
-           matrix_ortho(proj,
+           matrix_ortho(gc->shared->proj,
                         0, w, 0, h,
                         -1000000.0, 1000000.0,
                         rot, w, h,
                         1, 1.0);
         // v flipped matrix for render-to-texture
         else
-           matrix_ortho(proj,
+           matrix_ortho(gc->shared->proj,
                         0, w, h, 0,
                         -1000000.0, 1000000.0,
                         rot, w, h,
@@ -602,12 +601,12 @@ _evas_gl_common_viewport_set(Evas_Engine_GL_Context *gc)
         else
            glViewport(-2 * vy, -2 * vx, vh, vw);
         if (m == 1)
-           matrix_ortho(proj, 0, vw, 0, vh,
+           matrix_ortho(gc->shared->proj, 0, vw, 0, vh,
                         -1000000.0, 1000000.0,
                         rot, vw, vh,
                         foc, 0.0);
         else
-           matrix_ortho(proj, 0, vw, vh, 0,
+           matrix_ortho(gc->shared->proj, 0, vw, vh, 0,
                         -1000000.0, 1000000.0,
                         rot, vw, vh,
                         foc, 0.0);
@@ -617,13 +616,20 @@ _evas_gl_common_viewport_set(Evas_Engine_GL_Context *gc)
 
    for (i = 0; i < SHADER_LAST; ++i)
      {
-        glUseProgram(gc->shared->shader[i].prog);
-        glUniformMatrix4fv(glGetUniformLocation(gc->shared->shader[i].prog, "mvp"), 1, GL_FALSE, proj);
+        gc->shared->shader[i].reset = EINA_TRUE;
      }
 
    if (gc->state.current.cur_prog == PRG_INVALID)
-      glUseProgram(gc->shared->shader[0].prog);
-   else glUseProgram(gc->state.current.cur_prog);
+     {
+        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.cur_prog);
+        glUniformMatrix4fv(glGetUniformLocation(gc->state.current.cur_prog, "mvp"), 1, GL_FALSE, gc->shared->proj);
+     }
 }
 
 EAPI Evas_Engine_GL_Context *
@@ -3044,6 +3050,11 @@ shader_array_flush(Evas_Engine_GL_Context *gc)
         if (gc->pipe[i].shader.cur_prog != gc->state.current.cur_prog)
           {
              glUseProgram(gc->pipe[i].shader.cur_prog);
+             if (gc->shared->shader[gc->pipe[i].shader.id].reset)
+               {
+                  glUniformMatrix4fv(glGetUniformLocation(gc->pipe[i].shader.cur_prog, "mvp"), 1, GL_FALSE, gc->shared->proj);
+                  gc->shared->shader[gc->pipe[i].shader.id].reset = EINA_FALSE;
+               }
           }
 
         if (gc->pipe[i].shader.cur_tex != gc->state.current.cur_tex)