i don't believe that we forgot that desktopgl has an unload for shader
[profile/ivi/evas.git] / src / modules / engines / gl_common / evas_gl_context.c
index 4bba403..31cb602 100644 (file)
@@ -1,5 +1,12 @@
 #include "evas_gl_private.h"
 
+#ifdef HAVE_DLSYM
+# include <dlfcn.h>      /* dlopen,dlclose,etc */
+#else
+# error gl_common should not get compiled if dlsym is not found on the system!
+#endif
+
+#define PRG_INVALID 0xffffffff
 #define GLPIPES 1
 
 static int sym_done = 0;
@@ -14,6 +21,7 @@ void (*glsym_glDeleteFramebuffers)   (GLsizei a, const GLuint *b) = NULL;
 void (*glsym_glGetProgramBinary)     (GLuint a, GLsizei b, GLsizei *c, GLenum *d, void *e) = NULL;
 void (*glsym_glProgramBinary)        (GLuint a, GLenum b, const void *c, GLint d) = NULL;
 void (*glsym_glProgramParameteri)    (GLuint a, GLuint b, GLint d) = NULL;
+void (*glsym_glReleaseShaderCompiler)(void) = NULL;
 
 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
 // just used for finding symbols :)
@@ -47,11 +55,11 @@ gl_symbols(void)
    if (sym_done) return;
    sym_done = 1;
 
-#ifdef _EVAS_ENGINE_SDL_H
-# define FINDSYM(dst, sym, typ) if (!dst) dst = (typ)SDL_GL_GetProcAddress(sym)
-#else
-# define FINDSYM(dst, sym, typ) if (!dst) dst = (typ)dlsym(RTLD_DEFAULT, sym)
-#endif
+   /* FIXME: If using the SDL engine, we should use SDL_GL_GetProcAddress
+    * instead of dlsym
+    * if (!dst) dst = (typ)SDL_GL_GetProcAddress(sym)
+    */
+#define FINDSYM(dst, sym, typ) if (!dst) dst = (typ)dlsym(RTLD_DEFAULT, sym)
 #define FALLBAK(dst, typ) if (!dst) dst = (typ)sym_missing;
 
    FINDSYM(glsym_glGenFramebuffers, "glGenFramebuffers", glsym_func_void);
@@ -87,6 +95,10 @@ gl_symbols(void)
    FINDSYM(glsym_glProgramParameteri, "glProgramParameteriEXT", glsym_func_void);
    FINDSYM(glsym_glProgramParameteri, "glProgramParameteriARB", glsym_func_void);
 
+   FINDSYM(glsym_glReleaseShaderCompiler, "glReleaseShaderCompiler", glsym_func_void);
+   FINDSYM(glsym_glReleaseShaderCompiler, "glReleaseShaderCompilerEXT", glsym_func_void);
+   FINDSYM(glsym_glReleaseShaderCompiler, "glReleaseShaderCompilerARB", glsym_func_void);
+
 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
 #undef FINDSYM
 #define FINDSYM(dst, sym, typ) \
@@ -454,7 +466,9 @@ _evas_gl_common_viewport_set(Evas_Engine_GL_Context *gc)
         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
      }
 
-   glUseProgram(gc->pipe[0].shader.cur_prog);
+   if (gc->state.current.cur_prog == PRG_INVALID)
+      glUseProgram(gc->shared->shader[0].prog);
+   else glUseProgram(gc->state.current.cur_prog);
    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
 }
 
@@ -687,6 +701,9 @@ evas_gl_common_context_new(void)
         SHADER_TEXTURE_ADD(shared, YUY2, tex);
         SHADER_TEXTURE_ADD(shared, YUY2, texuv);
 
+        SHADER_TEXTURE_ADD(shared, NV12, tex);
+        SHADER_TEXTURE_ADD(shared, NV12, texuv);
+
         SHADER_TEXTURE_ADD(shared, YUV_NOMUL, tex);
         SHADER_TEXTURE_ADD(shared, YUV_NOMUL, texu);
         SHADER_TEXTURE_ADD(shared, YUV_NOMUL, texv);
@@ -694,10 +711,15 @@ evas_gl_common_context_new(void)
         SHADER_TEXTURE_ADD(shared, YUY2_NOMUL, tex);
         SHADER_TEXTURE_ADD(shared, YUY2_NOMUL, texuv);
 
+        SHADER_TEXTURE_ADD(shared, NV12_NOMUL, tex);
+        SHADER_TEXTURE_ADD(shared, NV12_NOMUL, texuv);
+
         SHADER_TEXTURE_ADD(shared, IMG_MASK, tex);
         SHADER_TEXTURE_ADD(shared, IMG_MASK, texm);
 
-        glUseProgram(gc->pipe[0].shader.cur_prog);
+        if (gc->state.current.cur_prog == PRG_INVALID)
+           glUseProgram(gc->shared->shader[0].prog);
+        else glUseProgram(gc->state.current.cur_prog);
         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
 
         evas_gl_common_shader_program_init_done();
@@ -885,7 +907,9 @@ evas_gl_common_context_newframe(Evas_Engine_GL_Context *gc)
    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
    glEnableVertexAttribArray(SHAD_COLOR);
    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-   glUseProgram(gc->pipe[0].shader.cur_prog);
+   if (gc->state.current.cur_prog == PRG_INVALID)
+      glUseProgram(gc->shared->shader[0].prog);
+   else glUseProgram(gc->state.current.cur_prog);
    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
 
    glActiveTexture(GL_TEXTURE0);
@@ -916,7 +940,7 @@ evas_gl_common_context_target_surface_set(Evas_Engine_GL_Context *gc,
 
    evas_gl_common_context_flush(gc);
 
-   gc->state.current.cur_prog = -1;
+   gc->state.current.cur_prog = PRG_INVALID;
    gc->state.current.cur_tex = -1;
    gc->state.current.cur_texu = -1;
    gc->state.current.cur_texv = -1;
@@ -1084,6 +1108,24 @@ vertex_array_size_check(Evas_Engine_GL_Context *gc, int pn, int n)
    return 1;
 }
 
+static inline Evas_GL_Shader
+evas_gl_common_shader_choice(int npoints __UNUSED__,
+                            RGBA_Map_Point *p,
+                            int r, int g, int b, int a,
+                            Evas_GL_Shader nomul,
+                            Evas_GL_Shader mul)
+{
+  if ((a == 255) && (r == 255) && (g == 255) && (b == 255))
+    {
+       if (!p) return nomul;
+
+       if ((p[0].col == 0xffffffff) && (p[1].col == 0xffffffff) &&
+           (p[2].col == 0xffffffff) && (p[3].col == 0xffffffff))
+         return nomul;
+    }
+  return mul;
+}
+
 static int
 _evas_gl_common_context_push(int rtype,
                              Evas_Engine_GL_Context *gc,
@@ -1253,9 +1295,11 @@ evas_gl_common_context_rectangle_push(Evas_Engine_GL_Context *gc,
        Evas_GL_Image *im;
        im = (void *)dc->mask.mask;
        evas_gl_common_context_font_push(gc, im->tex,
-                               x - dc->mask.x,y - dc->mask.y,
-                               dc->mask.w,dc->mask.h,
-                               x,y,w,h,r,g,b,a);
+                                         x - dc->mask.x,
+                                         y - dc->mask.y,
+                                         dc->mask.w, dc->mask.h,
+                                         x, y, w, h,
+                                         r, g, b, a);
        return;
      }
 
@@ -1408,34 +1452,26 @@ evas_gl_common_context_image_push(Evas_Engine_GL_Context *gc,
      {
         if (tex->pt->dyn.img)
           {
-             if ((a == 255) && (r == 255) && (g == 255) && (b == 255))
-                prog = gc->shared->shader[SHADER_IMG_NOMUL].prog;
-             else
-                prog = gc->shared->shader[SHADER_IMG].prog;
+             prog = gc->shared->shader[evas_gl_common_shader_choice(0, NULL, r, g, b, a,
+                                                                    SHADER_IMG_BGRA_NOMUL, SHADER_IMG_BGRA)].prog;
           }
         else
           {
-             if ((a == 255) && (r == 255) && (g == 255) && (b == 255))
-                prog = gc->shared->shader[SHADER_TEX_NOMUL].prog;
-             else
-                prog = gc->shared->shader[SHADER_TEX].prog;
+             prog = gc->shared->shader[evas_gl_common_shader_choice(0, NULL, r, g, b, a,
+                                                                    SHADER_TEX_NOMUL, SHADER_TEX)].prog;
           }
      }
    else
      {
         if (tex->gc->shared->info.bgra)
           {
-             if ((a == 255) && (r == 255) && (g == 255) && (b == 255))
-               prog = gc->shared->shader[SHADER_IMG_BGRA_NOMUL].prog;
-             else
-               prog = gc->shared->shader[SHADER_IMG_BGRA].prog;
+             prog = gc->shared->shader[evas_gl_common_shader_choice(0, NULL, r, g, b, a,
+                                                                    SHADER_IMG_BGRA_NOMUL, SHADER_IMG_BGRA)].prog;
           }
         else
           {
-             if ((a == 255) && (r == 255) && (g == 255) && (b == 255))
-               prog = gc->shared->shader[SHADER_IMG_NOMUL].prog;
-             else
-               prog = gc->shared->shader[SHADER_IMG].prog;
+             prog = gc->shared->shader[evas_gl_common_shader_choice(0, NULL, r, g, b, a,
+                                                                    SHADER_IMG_NOMUL, SHADER_IMG)].prog;
           }
      }
 
@@ -1542,153 +1578,34 @@ evas_gl_common_context_image_mask_push(Evas_Engine_GL_Context *gc,
    }
 #endif
 
-again:
-   vertex_array_size_check(gc, gc->state.top_pipe, 6);
-   pn = gc->state.top_pipe;
-#ifdef GLPIPES
-   if ((pn == 0) && (gc->pipe[pn].array.num == 0))
-     {
-        gc->pipe[pn].region.type = RTYPE_IMASK;
-        gc->pipe[pn].shader.cur_tex = tex->pt->texture;
-        gc->pipe[pn].shader.cur_texm = texm->pt->texture;
-        gc->pipe[pn].shader.cur_prog = prog;
-        gc->pipe[pn].shader.smooth = smooth;
-        gc->pipe[pn].shader.blend = blend;
-        gc->pipe[pn].shader.render_op = gc->dc->render_op;
-        gc->pipe[pn].shader.clip = 0;
-        gc->pipe[pn].shader.cx = 0;
-        gc->pipe[pn].shader.cy = 0;
-        gc->pipe[pn].shader.cw = 0;
-        gc->pipe[pn].shader.ch = 0;
-        gc->pipe[pn].array.line = 0;
-        gc->pipe[pn].array.use_vertex = 1;
-        // if nomul... dont need this
-        gc->pipe[pn].array.use_color = 1;
-        gc->pipe[pn].array.use_texuv = 1;
-        gc->pipe[pn].array.use_texuv2 = 0;
-        gc->pipe[pn].array.use_texuv3 = 0;
-        gc->pipe[pn].array.use_texm = 1;
-     }
-   else
-     {
-        int found = 0;
-
-        for (i = pn; i >= 0; i--)
-          {
-             if ((gc->pipe[i].region.type == RTYPE_IMASK)
-                 && (gc->pipe[i].shader.cur_tex == tex->pt->texture)
-                 && (gc->pipe[i].shader.cur_texm == texm->pt->texture)
-                 && (gc->pipe[i].shader.cur_prog == prog)
-                 && (gc->pipe[i].shader.smooth == smooth)
-                 && (gc->pipe[i].shader.blend == blend)
-                 && (gc->pipe[i].shader.render_op == gc->dc->render_op)
-                 && (gc->pipe[i].shader.clip == 0)
-                )
-               {
-                  found = 1;
-                  pn = i;
-                  break;
-               }
-             if (pipe_region_intersects(gc, i, x, y, w, h)) break;
-          }
-        if (!found)
-          {
-             pn = gc->state.top_pipe + 1;
-             if (pn >= gc->shared->info.tune.pipes.max)
-               {
-                  shader_array_flush(gc);
-                  goto again;
-               }
-             gc->state.top_pipe = pn;
-             gc->pipe[pn].region.type = RTYPE_IMASK;
-             gc->pipe[pn].shader.cur_tex = tex->pt->texture;
-             gc->pipe[pn].shader.cur_texm = texm->pt->texture;
-             gc->pipe[pn].shader.cur_prog = prog;
-             gc->pipe[pn].shader.smooth = smooth;
-             gc->pipe[pn].shader.blend = blend;
-             gc->pipe[pn].shader.render_op = gc->dc->render_op;
-             gc->pipe[pn].shader.clip = 0;
-             gc->pipe[pn].shader.cx = 0;
-             gc->pipe[pn].shader.cy = 0;
-             gc->pipe[pn].shader.cw = 0;
-             gc->pipe[pn].shader.ch = 0;
-             gc->pipe[pn].array.line = 0;
-             gc->pipe[pn].array.use_vertex = 1;
-             gc->pipe[pn].array.use_color = 1;
-             gc->pipe[pn].array.use_texuv = 1;
-             gc->pipe[pn].array.use_texuv2 = 0;
-             gc->pipe[pn].array.use_texuv3 = 0;
-            gc->pipe[pn].array.use_texm = 1;
-
-         }
-     }
-   if ((tex->im) && (tex->im->native.data))
-     {
-        if (gc->pipe[pn].array.im != tex->im)
-          {
-             shader_array_flush(gc);
-             pn = gc->state.top_pipe;
-             gc->pipe[pn].array.im = tex->im;
-             goto again;
-          }
-     }
-   if (tex->pt->dyn.img)
-     {
-        if (gc->pipe[pn].array.im != tex->im)
-          {
-             shader_array_flush(gc);
-             pn = gc->state.top_pipe;
-             gc->pipe[pn].array.im = tex->im;
-             goto again;
-          }
-     }
-#else
-   if ((gc->pipe[pn].shader.cur_tex != tex->pt->texture)
-       || (gc->pipe[pn].shader.cur_prog != prog)
-       || (gc->pipe[pn].shader.smooth != smooth)
-       || (gc->pipe[pn].shader.blend != blend)
-       || (gc->pipe[pn].shader.render_op != gc->dc->render_op)
-       || (gc->pipe[pn].shader.clip != 0)
-       )
-     {
-        shader_array_flush(gc);
-        gc->pipe[pn].shader.cur_tex = tex->pt->texture;
-        gc->pipe[pn].shader.cur_texm = texm->pt->texture;
-        gc->pipe[pn].shader.cur_prog = prog;
-        gc->pipe[pn].shader.smooth = smooth;
-        gc->pipe[pn].shader.blend = blend;
-        gc->pipe[pn].shader.render_op = gc->dc->render_op;
-        gc->pipe[pn].shader.clip = 0;
-        gc->pipe[pn].shader.cx = 0;
-        gc->pipe[pn].shader.cy = 0;
-        gc->pipe[pn].shader.cw = 0;
-        gc->pipe[pn].shader.ch = 0;
-     }
-   if ((tex->im) && (tex->im->native.data))
-     {
-        if (gc->pipe[pn].array.im != tex->im)
-          {
-             shader_array_flush(gc);
-             gc->pipe[pn].array.im = tex->im;
-          }
-     }
-   if (tex->pt->dyn.img)
-     {
-        if (gc->pipe[pn].array.im != tex->im)
-          {
-             shader_array_flush(gc);
-             gc->pipe[pn].array.im = tex->im;
-          }
-     }
+   pn = _evas_gl_common_context_push(RTYPE_IMASK,
+                                     gc, tex, texm,
+                                     prog,
+                                     x, y, w, h,
+                                     blend,
+                                     smooth,
+                                     0, 0, 0, 0, 0);
 
+   gc->pipe[pn].region.type = RTYPE_IMASK;
+   gc->pipe[pn].shader.cur_tex = tex->pt->texture;
+   gc->pipe[pn].shader.cur_texm = texm->pt->texture;
+   gc->pipe[pn].shader.cur_prog = prog;
+   gc->pipe[pn].shader.smooth = smooth;
+   gc->pipe[pn].shader.blend = blend;
+   gc->pipe[pn].shader.render_op = gc->dc->render_op;
+   gc->pipe[pn].shader.clip = 0;
+   gc->pipe[pn].shader.cx = 0;
+   gc->pipe[pn].shader.cy = 0;
+   gc->pipe[pn].shader.cw = 0;
+   gc->pipe[pn].shader.ch = 0;
    gc->pipe[pn].array.line = 0;
    gc->pipe[pn].array.use_vertex = 1;
+   // if nomul... dont need this
    gc->pipe[pn].array.use_color = 1;
    gc->pipe[pn].array.use_texuv = 1;
    gc->pipe[pn].array.use_texuv2 = 0;
    gc->pipe[pn].array.use_texuv3 = 0;
    gc->pipe[pn].array.use_texm = 1;
-#endif
 
    pipe_region_expand(gc, pn, x, y, w, h);
 
@@ -1852,15 +1769,13 @@ evas_gl_common_context_yuv_push(Evas_Engine_GL_Context *gc,
    int pnum, nv, nc, nu, nu2, nu3, nt, i;
    GLfloat tx1, tx2, ty1, ty2, t2x1, t2x2, t2y1, t2y2;
    Eina_Bool blend = 0;
-   GLuint prog = gc->shared->shader[SHADER_YUV].prog;
+   GLuint prog;
    int pn = 0;
 
    if (a < 255) blend = 1;
 
-   if ((a == 255) && (r == 255) && (g == 255) && (b == 255))
-     prog = gc->shared->shader[SHADER_YUV_NOMUL].prog;
-   else
-     prog = gc->shared->shader[SHADER_YUV].prog;
+   prog = gc->shared->shader[evas_gl_common_shader_choice(0, NULL, r, g, b, a,
+                                                          SHADER_YUV_NOMUL, SHADER_YUV)].prog;
 
    pn = _evas_gl_common_context_push(RTYPE_YUV,
                                     gc, tex, NULL,
@@ -1957,15 +1872,13 @@ evas_gl_common_context_yuy2_push(Evas_Engine_GL_Context *gc,
    int pnum, nv, nc, nu, nu2, nu3, nt, i;
    GLfloat tx1, tx2, ty1, ty2, t2x1, t2x2, t2y1, t2y2;
    Eina_Bool blend = 0;
-   GLuint prog = gc->shared->shader[SHADER_YUY2].prog;
+   GLuint prog;
    int pn = 0;
 
    if (a < 255) blend = 1;
 
-   if ((a == 255) && (r == 255) && (g == 255) && (b == 255))
-     prog = gc->shared->shader[SHADER_YUY2_NOMUL].prog;
-   else
-     prog = gc->shared->shader[SHADER_YUY2].prog;
+   prog = gc->shared->shader[evas_gl_common_shader_choice(0, NULL, r, g, b, a,
+                                                          SHADER_YUY2_NOMUL, SHADER_YUY2)].prog;
 
    pn = _evas_gl_common_context_push(RTYPE_YUY2,
                                     gc, tex, NULL,
@@ -2043,15 +1956,110 @@ evas_gl_common_context_yuy2_push(Evas_Engine_GL_Context *gc,
 }
 
 void
+evas_gl_common_context_nv12_push(Evas_Engine_GL_Context *gc,
+                                Evas_GL_Texture *tex,
+                                double sx, double sy, double sw, double sh,
+                                int x, int y, int w, int h,
+                                int r, int g, int b, int a,
+                                Eina_Bool smooth)
+{
+   int pnum, nv, nc, nu, nu2, nu3, nt, i;
+   GLfloat tx1, tx2, ty1, ty2, t2x1, t2x2, t2y1, t2y2;
+   Eina_Bool blend = 0;
+   GLuint prog;
+   int pn = 0;
+
+   if (a < 255) blend = 1;
+
+   prog = gc->shared->shader[evas_gl_common_shader_choice(0, NULL, r, g, b, a,
+                                                          SHADER_NV12_NOMUL, SHADER_NV12)].prog;
+
+   pn = _evas_gl_common_context_push(RTYPE_NV12,
+                                    gc, tex, NULL,
+                                    prog,
+                                    x, y, w, h,
+                                    blend,
+                                    smooth,
+                                    0, 0, 0, 0, 0);
+
+   gc->pipe[pn].region.type = RTYPE_NV12;
+   gc->pipe[pn].shader.cur_tex = tex->pt->texture;
+   gc->pipe[pn].shader.cur_tex_dyn = tex->pt->dyn.img;
+   gc->pipe[pn].shader.cur_texu = tex->ptuv->texture;
+   gc->pipe[pn].shader.cur_texu_dyn = tex->ptuv->dyn.img;
+   gc->pipe[pn].shader.cur_prog = prog;
+   gc->pipe[pn].shader.smooth = smooth;
+   gc->pipe[pn].shader.blend = blend;
+   gc->pipe[pn].shader.render_op = gc->dc->render_op;
+   gc->pipe[pn].shader.clip = 0;
+   gc->pipe[pn].shader.cx = 0;
+   gc->pipe[pn].shader.cy = 0;
+   gc->pipe[pn].shader.cw = 0;
+   gc->pipe[pn].shader.ch = 0;
+   gc->pipe[pn].array.line = 0;
+   gc->pipe[pn].array.use_vertex = 1;
+   gc->pipe[pn].array.use_color = 1;
+   gc->pipe[pn].array.use_texuv = 1;
+   gc->pipe[pn].array.use_texuv2 = 1;
+   gc->pipe[pn].array.use_texuv3 = 0;
+
+   pipe_region_expand(gc, pn, x, y, w, h);
+
+   pnum = gc->pipe[pn].array.num;
+   nv = pnum * 3; nc = pnum * 4; nu = pnum * 2;
+   nu2 = pnum * 2; nu3 = pnum * 2; nt = pnum * 4;
+   gc->pipe[pn].array.num += 6;
+   array_alloc(gc, pn);
+
+   tx1 = (sx) / (double)tex->pt->w;
+   ty1 = (sy) / (double)tex->pt->h;
+   tx2 = (sx + sw) / (double)tex->pt->w;
+   ty2 = (sy + sh) / (double)tex->pt->h;
+
+   t2x1 = sx / (double)tex->ptuv->w;
+   t2y1 = sy / (double)tex->ptuv->h;
+   t2x2 = (sx + sw) / (double)tex->ptuv->w;
+   t2y2 = (sy + sh) / (double)tex->ptuv->h;
+
+   PUSH_VERTEX(pn, x    , y    , 0);
+   PUSH_VERTEX(pn, x + w, y    , 0);
+   PUSH_VERTEX(pn, x    , y + h, 0);
+
+   PUSH_TEXUV(pn, tx1, ty1);
+   PUSH_TEXUV(pn, tx2, ty1);
+   PUSH_TEXUV(pn, tx1, ty2);
+
+   PUSH_TEXUV2(pn, t2x1, t2y1);
+   PUSH_TEXUV2(pn, t2x2, t2y1);
+   PUSH_TEXUV2(pn, t2x1, t2y2);
+
+   PUSH_VERTEX(pn, x + w, y    , 0);
+   PUSH_VERTEX(pn, x + w, y + h, 0);
+   PUSH_VERTEX(pn, x    , y + h, 0);
+
+   PUSH_TEXUV(pn, tx2, ty1);
+   PUSH_TEXUV(pn, tx2, ty2);
+   PUSH_TEXUV(pn, tx1, ty2);
+
+   PUSH_TEXUV2(pn, t2x2, t2y1);
+   PUSH_TEXUV2(pn, t2x2, t2y2);
+   PUSH_TEXUV2(pn, t2x1, t2y2);
+
+   for (i = 0; i < 6; i++)
+     {
+        PUSH_COLOR(pn, r, g, b, a);
+     }
+}
+
+void
 evas_gl_common_context_image_map_push(Evas_Engine_GL_Context *gc,
                                       Evas_GL_Texture *tex,
                                       int npoints,
                                       RGBA_Map_Point *p,
                                       int clip, int cx, int cy, int cw, int ch,
                                       int r, int g, int b, int a,
-                                      Eina_Bool smooth, Eina_Bool tex_only,
-                                      Eina_Bool yuv,
-                                     Eina_Bool yuy2)
+                                     Eina_Bool smooth, Eina_Bool tex_only,
+                                     Evas_Colorspace cspace)
 {
    int pnum, nv, nc, nu, nu2, nu3, nt, i;
    const int points[6] = { 0, 1, 2, 0, 2, 3 };
@@ -2060,6 +2068,8 @@ evas_gl_common_context_image_map_push(Evas_Engine_GL_Context *gc,
    Eina_Bool blend = 1;
    DATA32 cmul;
    GLuint prog = gc->shared->shader[SHADER_IMG].prog;
+   Eina_Bool utexture = EINA_FALSE;
+   Eina_Bool uvtexture = EINA_FALSE;
    int pn = 0;
    int flat = 0;
 
@@ -2084,115 +2094,82 @@ evas_gl_common_context_image_map_push(Evas_Engine_GL_Context *gc,
      {
         if (p[0].foc <= 0) flat = 1;
      }
-   if (yuv)
-     {
-        prog = gc->shared->shader[SHADER_YUV].prog;
-        if ((a == 255) && (r == 255) && (g == 255) && (b == 255))
-          {
-             if ((p[0].col == 0xffffffff) && (p[1].col == 0xffffffff) &&
-                 (p[2].col == 0xffffffff) && (p[3].col == 0xffffffff))
-                prog = gc->shared->shader[SHADER_YUV_NOMUL].prog;
-             else
-                prog = gc->shared->shader[SHADER_YUV].prog;
-          }
-        else
-           prog = gc->shared->shader[SHADER_YUV].prog;
-     }
-   else if (yuy2)
-     {
-        prog = gc->shared->shader[SHADER_YUY2].prog;
-        if ((a == 255) && (r == 255) && (g == 255) && (b == 255))
-          {
-             if ((p[0].col == 0xffffffff) && (p[1].col == 0xffffffff) &&
-                 (p[2].col == 0xffffffff) && (p[3].col == 0xffffffff))
-                prog = gc->shared->shader[SHADER_YUY2_NOMUL].prog;
-             else
-                prog = gc->shared->shader[SHADER_YUY2].prog;
-          }
-        else
-           prog = gc->shared->shader[SHADER_YUY2].prog;
-     }
-   else
-     {
-        if (tex_only)
-          {
-             if (tex->pt->dyn.img)
-               {
-                  if ((a == 255) && (r == 255) && (g == 255) && (b == 255))
-                    {
-                       if ((p[0].col == 0xffffffff) && (p[1].col == 0xffffffff) &&
-                           (p[2].col == 0xffffffff) && (p[3].col == 0xffffffff))
-                          prog = gc->shared->shader[SHADER_IMG_NOMUL].prog;
-                       else
-                          prog = gc->shared->shader[SHADER_IMG].prog;
-                    }
-                  else
-                     prog = gc->shared->shader[SHADER_IMG].prog;
-               }
-             else
-               {
-                  if ((a == 255) && (r == 255) && (g == 255) && (b == 255))
-                    {
-                       if ((p[0].col == 0xffffffff) && (p[1].col == 0xffffffff) &&
-                           (p[2].col == 0xffffffff) && (p[3].col == 0xffffffff))
-                          prog = gc->shared->shader[SHADER_TEX_NOMUL].prog;
-                       else
-                          prog = gc->shared->shader[SHADER_TEX].prog;
-                    }
-                  else
-                     prog = gc->shared->shader[SHADER_TEX].prog;
-               }
-          }
-        else
-          {
-             if (tex->gc->shared->info.bgra)
-               {
-                  if ((a == 255) && (r == 255) && (g == 255) && (b == 255))
-                    {
-                       if ((p[0].col == 0xffffffff) && (p[1].col == 0xffffffff) &&
-                           (p[2].col == 0xffffffff) && (p[3].col == 0xffffffff))
-                          prog = gc->shared->shader[SHADER_IMG_BGRA_NOMUL].prog;
-                       else
-                          prog = gc->shared->shader[SHADER_IMG_BGRA].prog;
-                    }
-                  else
-                     prog = gc->shared->shader[SHADER_IMG_BGRA].prog;
-               }
+
+   switch (cspace)
+     {
+      case EVAS_COLORSPACE_YCBCR422P601_PL:
+      case EVAS_COLORSPACE_YCBCR422P709_PL:
+         prog = gc->shared->shader[evas_gl_common_shader_choice(npoints, p, r, g, b, a,
+                                                                SHADER_YUV_NOMUL, SHADER_YUV)].prog;
+         utexture = EINA_TRUE;
+         break;
+      case EVAS_COLORSPACE_YCBCR422601_PL:
+         prog = gc->shared->shader[evas_gl_common_shader_choice(npoints, p, r, g, b, a,
+                                                                SHADER_YUY2_NOMUL, SHADER_YUY2)].prog;
+         uvtexture = EINA_TRUE;
+         break;
+      case EVAS_COLORSPACE_YCBCR420NV12601_PL:
+      case EVAS_COLORSPACE_YCBCR420TM12601_PL:
+         prog = gc->shared->shader[evas_gl_common_shader_choice(npoints, p, r, g, b, a,
+                                                                SHADER_NV12_NOMUL, SHADER_NV12)].prog;
+         uvtexture = EINA_TRUE;
+         break;
+
+      default:
+         if (tex_only)
+           {
+              if (tex->pt->dyn.img)
+                {
+                   prog = gc->shared->shader[evas_gl_common_shader_choice(npoints, p, r, g, b, a,
+                                                                          SHADER_IMG_BGRA_NOMUL, SHADER_IMG_BGRA)].prog;
+                }
+              else
+                {
+                   prog = gc->shared->shader[evas_gl_common_shader_choice(npoints, p, r, g, b, a,
+                                                                          SHADER_TEX_NOMUL, SHADER_TEX)].prog;
+                }
+           }
+         else
+           {
+              if (tex->gc->shared->info.bgra)
+                {
+                   prog = gc->shared->shader[evas_gl_common_shader_choice(npoints, p, r, g, b, a,
+                                                                          SHADER_IMG_BGRA_NOMUL,
+                                                                          SHADER_IMG_BGRA)].prog;
+                }
              else
                {
-                  if ((a == 255) && (r == 255) && (g == 255) && (b == 255))
-                    {
-                       if ((p[0].col == 0xffffffff) && (p[1].col == 0xffffffff) &&
-                           (p[2].col == 0xffffffff) && (p[3].col == 0xffffffff))
-                         prog = gc->shared->shader[SHADER_IMG_NOMUL].prog;
-                       else
-                          prog = gc->shared->shader[SHADER_IMG].prog;
-                    }
-                  else
-                     prog = gc->shared->shader[SHADER_IMG].prog;
+                  prog = gc->shared->shader[evas_gl_common_shader_choice(npoints, p, r, g, b, a,
+                                                                         SHADER_IMG_NOMUL,
+                                                                         SHADER_IMG)].prog;
                }
-          }
+           }
      }
 
-   x = w = (p[points[0]].x >> FP);
-   y = h = (p[points[0]].y >> FP);
+   x = w = (p[0].x >> FP);
+   y = h = (p[0].y >> FP);
    for (i = 0; i < 4; i++)
      {
         tx[i] = ((double)(tex->x) + (((double)p[i].u) / FP1)) /
           (double)tex->pt->w;
         ty[i] = ((double)(tex->y) + (((double)p[i].v) / FP1)) /
           (double)tex->pt->h;
-        px = (p[points[i]].x >> FP);
+        px = (p[i].x >> FP);
         if      (px < x) x = px;
         else if (px > w) w = px;
-        py = (p[points[i]].y >> FP);
+        py = (p[i].y >> FP);
         if      (py < y) y = py;
         else if (py > h) h = py;
-        if (yuv || yuy2)
+        if (utexture)
           {
              t2x[i] = ((((double)p[i].u / 2) / FP1)) / (double)tex->ptu->w;
              t2y[i] = ((((double)p[i].v / 2) / FP1)) / (double)tex->ptu->h;
           }
+        else if (uvtexture)
+          {
+             t2x[i] = ((((double)p[i].u / 2) / FP1)) / (double)tex->ptuv->w;
+             t2y[i] = ((((double)p[i].v / 2) / FP1)) / (double)tex->ptuv->h;
+          }
      }
    w = w - x;
    h = h - y;
@@ -2227,17 +2204,19 @@ evas_gl_common_context_image_map_push(Evas_Engine_GL_Context *gc,
                                     blend,
                                     smooth,
                                     clip, cx, cy, cw, ch);
-
    gc->pipe[pn].region.type = RTYPE_MAP;
    gc->pipe[pn].shader.cur_tex = tex->pt->texture;
-   if (yuv)
+   if (utexture)
      {
        gc->pipe[pn].shader.cur_texu = tex->ptu->texture;
+       gc->pipe[pn].shader.cur_texu_dyn = tex->ptu->dyn.img;
        gc->pipe[pn].shader.cur_texv = tex->ptv->texture;
+       gc->pipe[pn].shader.cur_texv_dyn = tex->ptv->dyn.img;
      }
-   else if (yuy2)
+   else if (uvtexture)
      {
        gc->pipe[pn].shader.cur_texu = tex->ptuv->texture;
+       gc->pipe[pn].shader.cur_texu_dyn = tex->ptuv->dyn.img;
      }
    gc->pipe[pn].shader.cur_prog = prog;
    gc->pipe[pn].shader.smooth = smooth;
@@ -2252,8 +2231,8 @@ evas_gl_common_context_image_map_push(Evas_Engine_GL_Context *gc,
    gc->pipe[pn].array.use_vertex = 1;
    gc->pipe[pn].array.use_color = 1;
    gc->pipe[pn].array.use_texuv = 1;
-   gc->pipe[pn].array.use_texuv2 = (yuv || yuy2) ? 1 : 0;
-   gc->pipe[pn].array.use_texuv3 = (yuv) ? 1 : 0;
+   gc->pipe[pn].array.use_texuv2 = (utexture || uvtexture) ? 1 : 0;
+   gc->pipe[pn].array.use_texuv3 = (utexture) ? 1 : 0;
 
    pipe_region_expand(gc, pn, x, y, w, h);
 
@@ -2268,7 +2247,7 @@ evas_gl_common_context_image_map_push(Evas_Engine_GL_Context *gc,
         for (i = 0; i < 4; i++)
           {
              ty[i] = 1.0 - ty[i];
-             if (yuv || yuy2)
+             if (utexture || uvtexture)
                 t2y[i] = 1.0 - t2y[i];
           }
      }
@@ -2295,7 +2274,7 @@ evas_gl_common_context_image_map_push(Evas_Engine_GL_Context *gc,
         PUSH_TEXUV(pn,
                    tx[points[i]],
                    ty[points[i]]);
-        if (yuv)
+        if (utexture)
           {
              PUSH_TEXUV2(pn,
                          t2x[points[i]],
@@ -2304,7 +2283,7 @@ evas_gl_common_context_image_map_push(Evas_Engine_GL_Context *gc,
                          t2x[points[i]],
                          t2y[points[i]]);
           }
-        else if (yuy2)
+        else if (uvtexture)
           {
              PUSH_TEXUV2(pn,
                          t2x[points[i]],
@@ -2611,14 +2590,24 @@ shader_array_flush(Evas_Engine_GL_Context *gc)
                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
                   glVertexAttribPointer(SHAD_TEXUV3, 2, GL_FLOAT, GL_FALSE, 0, gc->pipe[i].array.texuv3);
                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+
                   glActiveTexture(GL_TEXTURE1);
                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
                   glBindTexture(GL_TEXTURE_2D, gc->pipe[i].shader.cur_texu);
                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
+                  if (gc->pipe[i].shader.cur_texu_dyn)
+                   secsym_glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, gc->pipe[i].shader.cur_texu_dyn);
+#endif
+                  
                   glActiveTexture(GL_TEXTURE2);
                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
                   glBindTexture(GL_TEXTURE_2D, gc->pipe[i].shader.cur_texv);
                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
+                 if (gc->pipe[i].shader.cur_texv_dyn)
+                   secsym_glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, gc->pipe[i].shader.cur_texv_dyn);
+#endif
                   glActiveTexture(GL_TEXTURE0);
                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
                }
@@ -2628,9 +2617,15 @@ shader_array_flush(Evas_Engine_GL_Context *gc)
                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
                   glVertexAttribPointer(SHAD_TEXUV2, 2, GL_FLOAT, GL_FALSE, 0, gc->pipe[i].array.texuv2);
                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+
                   glActiveTexture(GL_TEXTURE1);
                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
                   glBindTexture(GL_TEXTURE_2D, gc->pipe[i].shader.cur_texu);
+                  GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
+                 if (gc->pipe[i].shader.cur_texu_dyn)
+                   secsym_glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, gc->pipe[i].shader.cur_texu_dyn);
+#endif
                   glActiveTexture(GL_TEXTURE0);
                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
                }
@@ -2672,14 +2667,14 @@ shader_array_flush(Evas_Engine_GL_Context *gc)
 
         gc->state.current.cur_prog  = gc->pipe[i].shader.cur_prog;
         gc->state.current.cur_tex   = gc->pipe[i].shader.cur_tex;
-        gc->state.current.blend     = gc->pipe[i].shader.blend;
-        gc->state.current.smooth    = gc->pipe[i].shader.smooth;
         gc->state.current.render_op = gc->pipe[i].shader.render_op;
-        gc->state.current.clip      = gc->pipe[i].shader.clip;
         gc->state.current.cx        = gc->pipe[i].shader.cx;
         gc->state.current.cy        = gc->pipe[i].shader.cy;
         gc->state.current.cw        = gc->pipe[i].shader.cw;
         gc->state.current.ch        = gc->pipe[i].shader.ch;
+        gc->state.current.smooth    = gc->pipe[i].shader.smooth;
+        gc->state.current.blend     = gc->pipe[i].shader.blend;
+        gc->state.current.clip      = gc->pipe[i].shader.clip;
 
         if (gc->pipe[i].array.vertex) free(gc->pipe[i].array.vertex);
         if (gc->pipe[i].array.color) free(gc->pipe[i].array.color);