yuv support is back now.
authorraster <raster@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Sat, 10 Oct 2009 13:24:15 +0000 (13:24 +0000)
committerraster <raster@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Sat, 10 Oct 2009 13:24:15 +0000 (13:24 +0000)
git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/evas@43000 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

src/modules/engines/gl_common/evas_gl_common.h
src/modules/engines/gl_common/evas_gl_context.c
src/modules/engines/gl_common/evas_gl_image.c
src/modules/engines/gl_common/evas_gl_shader.c
src/modules/engines/gl_common/evas_gl_texture.c
src/modules/engines/gl_common/shader/compile-s3c6410.sh
src/modules/engines/gl_common/shader/compile-sgx.sh
src/modules/engines/gl_common/shader/yuv_frag.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/yuv_frag.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/yuv_vert.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/yuv_vert.shd [new file with mode: 0644]

index 8fca477..1202034 100644 (file)
@@ -41,6 +41,8 @@
 #define SHAD_VERTEX 0
 #define SHAD_COLOR  1
 #define SHAD_TEXUV  2
+#define SHAD_TEXUV2 3
+#define SHAD_TEXUV3 4
 
 typedef struct _Evas_GL_Program                      Evas_GL_Program;
 typedef struct _Evas_GL_Program_Source               Evas_GL_Program_Source;
@@ -49,14 +51,13 @@ typedef struct _Evas_GL_Texture_Pool                 Evas_GL_Texture_Pool;
 typedef struct _Evas_GL_Texture                      Evas_GL_Texture;
 typedef struct _Evas_GL_Image                        Evas_GL_Image;
 typedef struct _Evas_GL_Font_Texture                 Evas_GL_Font_Texture;
-
-
-
+/*
 typedef struct _Evas_GL_Polygon                      Evas_GL_Polygon;
 typedef struct _Evas_GL_Polygon_Point                Evas_GL_Polygon_Point;
 typedef struct _Evas_GL_Gradient                     Evas_GL_Gradient;
 typedef struct _Evas_GL_Font_Texture_Pool            Evas_GL_Font_Texture_Pool;
 typedef struct _Evas_GL_Font_Texture_Pool_Allocation Evas_GL_Font_Texture_Pool_Allocation;
+*/
 
 struct _Evas_GL_Program
 {
@@ -96,9 +97,15 @@ struct _Evas_GL_Context
    struct {
       Evas_GL_Program rect, img, font, yuv;
       GLuint          cur_prog;
-      GLuint          cur_tex;
+      GLuint          cur_tex, cur_texu, cur_texv;
       Eina_Bool       smooth : 1;
       Eina_Bool       blend : 1;
+      struct {
+         GLuint          cur_prog;
+         GLuint          cur_tex, cur_texum, cur_texv;
+         Eina_Bool       smooth : 1;
+         Eina_Bool       blend : 1;
+      } current;
    } shader;
    struct {
       int num;
@@ -106,6 +113,8 @@ struct _Evas_GL_Context
       GLint   *vertex;
       GLfloat *color;
       GLfloat *texuv;
+      GLfloat *texuv2;
+      GLfloat *texuv3;
    } array;
    struct {
       Eina_Bool size : 1;
@@ -128,7 +137,7 @@ struct _Evas_GL_Texture_Pool
 struct _Evas_GL_Texture
 {
    Evas_GL_Context *gc;
-   Evas_GL_Texture_Pool *pt;
+   Evas_GL_Texture_Pool *pt, *ptu, *ptv;
    int              x, y, w, h;
    int              references;
 };
@@ -153,12 +162,7 @@ struct _Evas_GL_Font_Texture
 {
    Evas_GL_Texture *tex;
 };
-
-
-
-
-
-
+/*
 struct _Evas_GL_Polygon
 {
    Eina_List *points;
@@ -186,6 +190,7 @@ struct _Evas_GL_Font_Texture_Pool
    GLuint           texture;
    unsigned char    rectangle : 1;
 };
+*/
 
 extern Evas_GL_Program_Source shader_rect_frag_src;
 extern Evas_GL_Program_Source shader_rect_vert_src;
@@ -193,6 +198,8 @@ extern Evas_GL_Program_Source shader_img_frag_src;
 extern Evas_GL_Program_Source shader_img_vert_src;
 extern Evas_GL_Program_Source shader_font_frag_src;
 extern Evas_GL_Program_Source shader_font_vert_src;
+extern Evas_GL_Program_Source shader_yuv_frag_src;
+extern Evas_GL_Program_Source shader_yuv_vert_src;
 
 void glerr(const char *file, const char *func, int line, const char *op);
  
@@ -215,6 +222,12 @@ void              evas_gl_common_context_font_push(Evas_GL_Context *gc,
                                                    double sx, double sy, double sw, double sh,
                                                    int x, int y, int w, int h,
                                                    int r, int g, int b, int a);
+void             evas_gl_common_context_yuv_push(Evas_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);
 void              evas_gl_common_context_flush(Evas_GL_Context *gc);
 
 void              evas_gl_common_shader_program_init(Evas_GL_Program *p,
@@ -228,7 +241,9 @@ void              evas_gl_common_texture_update(Evas_GL_Texture *tex, RGBA_Image
 void              evas_gl_common_texture_free(Evas_GL_Texture *tex);
 Evas_GL_Texture  *evas_gl_common_texture_alpha_new(Evas_GL_Context *gc, DATA8 *pixels, int w, int h, int fh);
 void              evas_gl_common_texture_alpha_update(Evas_GL_Texture *tex, DATA8 *pixels, int w, int h, int fh);
-    
+Evas_GL_Texture  *evas_gl_common_texture_yuv_new(Evas_GL_Context *gc, DATA8 **rows, int w, int h);
+void              evas_gl_common_texture_yuv_update(Evas_GL_Texture *tex, DATA8 **rows, int w, int h);
+
 Evas_GL_Image    *evas_gl_common_image_load(Evas_GL_Context *gc, const char *file, const char *key, Evas_Image_Load_Opts *lo);
 Evas_GL_Image    *evas_gl_common_image_new_from_data(Evas_GL_Context *gc, int w, int h, DATA32 *data, int alpha, int cspace);
 Evas_GL_Image    *evas_gl_common_image_new_from_copied_data(Evas_GL_Context *gc, int w, int h, DATA32 *data, int alpha, int cspace);
@@ -260,7 +275,7 @@ void              evas_gl_font_texture_draw(Evas_GL_Context *gc, void *surface,
 
 
 
-
+/*
 Evas_GL_Polygon  *evas_gl_common_poly_point_add(Evas_GL_Polygon *poly, int x, int y);
 Evas_GL_Polygon  *evas_gl_common_poly_points_clear(Evas_GL_Polygon *poly);
 
@@ -289,17 +304,6 @@ void              evas_gl_common_swap_rect(Evas_GL_Context *gc, int x, int y, in
 
 void              evas_gl_common_line_draw(Evas_GL_Context *gc, int x1, int y1, int x2, int y2);
 void              evas_gl_common_poly_draw(Evas_GL_Context *gc, Evas_GL_Polygon *poly);
-
-
-/* FIXME:
- *
- * for images:
- * speculative cache for textures too
- * texture mesh support
- *
- * for text/fonts:
- * need to not render to a texture each time.... this is sloooooow.
- * but its a "bootstrap" for just right now.
- */
+*/
 
 #endif
index 480f5f1..c23f78a 100644 (file)
@@ -98,6 +98,10 @@ evas_gl_common_context_new(void)
         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 16);
 #endif
         
+        glEnableVertexAttribArray(SHAD_VERTEX);
+        glEnableVertexAttribArray(SHAD_COLOR);
+        glEnableVertexAttribArray(SHAD_TEXUV);
+        
         evas_gl_common_shader_program_init(&(gc->shader.rect), 
                                            &(shader_rect_vert_src), 
                                            &(shader_rect_frag_src));
@@ -107,6 +111,13 @@ evas_gl_common_context_new(void)
         evas_gl_common_shader_program_init(&(gc->shader.font),
                                            &(shader_font_vert_src), 
                                            &(shader_font_frag_src));
+        evas_gl_common_shader_program_init(&(gc->shader.yuv),
+                                           &(shader_yuv_vert_src), 
+                                           &(shader_yuv_frag_src));
+        glUseProgram(gc->shader.yuv.prog);
+        glUniform1i(glGetUniformLocation(gc->shader.yuv.prog, "tex"), 0);
+        glUniform1i(glGetUniformLocation(gc->shader.yuv.prog, "texu"), 1);
+        glUniform1i(glGetUniformLocation(gc->shader.yuv.prog, "texv"), 2);
         _evas_gl_common_viewport_set(gc);
         gc->checked = 1;
      }
@@ -155,23 +166,33 @@ evas_gl_common_context_resize(Evas_GL_Context *gc, int w, int h)
 #define PUSH_TEXUV(u, v) \
    gc->array.texuv[nu++] = u; \
    gc->array.texuv[nu++] = v
+#define PUSH_TEXUV2(u, v) \
+   gc->array.texuv2[nu2++] = u; \
+   gc->array.texuv2[nu2++] = v
+#define PUSH_TEXUV3(u, v) \
+   gc->array.texuv3[nu3++] = u; \
+   gc->array.texuv3[nu3++] = v
 #define COLOR_FLOAT(r, g, b, a, fr, fg, fb, fa) \
    fr = ((GLfloat)(r)) / 255.0; \
    fg = ((GLfloat)(g)) / 255.0; \
    fb = ((GLfloat)(b)) / 255.0; \
    fa = ((GLfloat)(a)) / 255.0
 
-static void
+static inline void
 _evas_gl_common_context_array_alloc(Evas_GL_Context *gc)
 {
    if (gc->array.num <= gc->array.alloc) return;
-   gc->array.alloc += 1024;
+   gc->array.alloc += 6 * 1024;
    gc->array.vertex = realloc(gc->array.vertex,
                               gc->array.alloc * sizeof(GLint) * 3);
    gc->array.color  = realloc(gc->array.color,
                               gc->array.alloc * sizeof(GLfloat) * 4);
    gc->array.texuv  = realloc(gc->array.texuv,
                               gc->array.alloc * sizeof(GLfloat) * 2);
+   gc->array.texuv2  = realloc(gc->array.texuv2,
+                               gc->array.alloc * sizeof(GLfloat) * 2);
+   gc->array.texuv3  = realloc(gc->array.texuv3,
+                               gc->array.alloc * sizeof(GLfloat) * 2);
 }
 
 void
@@ -337,6 +358,90 @@ evas_gl_common_context_font_push(Evas_GL_Context *gc,
 }
 
 void
+evas_gl_common_context_yuv_push(Evas_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 rr, gg, bb, aa, tx1, tx2, ty1, ty2, t2x1, t2x2, t2y1, t2y2;
+   Eina_Bool blend = 0;
+
+   if (a < 255) blend = 1;
+   
+   if ((gc->shader.cur_tex != tex->pt->texture)
+       || (gc->shader.cur_prog != gc->shader.yuv.prog)
+       || (gc->shader.smooth != smooth)
+       || (gc->shader.blend != blend)
+       )
+     {
+        shader_array_flush(gc);
+        gc->shader.cur_tex = tex->pt->texture;
+        gc->shader.cur_texu = tex->ptu->texture;
+        gc->shader.cur_texv = tex->ptv->texture;
+        gc->shader.cur_prog = gc->shader.yuv.prog;
+        gc->shader.smooth = smooth;
+        gc->shader.blend = blend;
+     }
+   
+   pnum = gc->array.num;
+   nv = pnum * 3; nc = pnum * 4; nu = pnum * 2; 
+   nu2 = pnum * 2; nu3 = pnum * 2; nt = pnum * 4;
+   gc->array.num += 6;
+   _evas_gl_common_context_array_alloc(gc);
+
+   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->ptu->w;
+   t2y1 = (sy) / (double)tex->ptu->h;
+   t2x2 = (sx + sw) / (double)tex->ptu->w;
+   t2y2 = (sy + sh) / (double)tex->ptu->h;
+   
+   PUSH_VERTEX(x    , y    , 0);
+   PUSH_VERTEX(x + w, y    , 0);
+   PUSH_VERTEX(x    , y + h, 0);
+   
+   PUSH_TEXUV(tx1, ty1);
+   PUSH_TEXUV(tx2, ty1);
+   PUSH_TEXUV(tx1, ty2);
+   
+   PUSH_TEXUV2(t2x1, t2y1);
+   PUSH_TEXUV2(t2x2, t2y1);
+   PUSH_TEXUV2(t2x1, t2y2);
+   
+   PUSH_TEXUV3(t2x1, t2y1);
+   PUSH_TEXUV3(t2x2, t2y1);
+   PUSH_TEXUV3(t2x1, t2y2);
+   
+   PUSH_VERTEX(x + w, y    , 0);
+   PUSH_VERTEX(x + w, y + h, 0);
+   PUSH_VERTEX(x    , y + h, 0);
+   
+   PUSH_TEXUV(tx2, ty1);
+   PUSH_TEXUV(tx2, ty2);
+   PUSH_TEXUV(tx1, ty2);
+
+   PUSH_TEXUV2(t2x2, t2y1);
+   PUSH_TEXUV2(t2x2, t2y2);
+   PUSH_TEXUV2(t2x1, t2y2);
+
+   PUSH_TEXUV3(t2x2, t2y1);
+   PUSH_TEXUV3(t2x2, t2y2);
+   PUSH_TEXUV3(t2x1, t2y2);
+
+   COLOR_FLOAT(r, g, b, a, rr, gg, bb, aa);
+   for (i = 0; i < 6; i++)
+     {
+        PUSH_COLOR(rr, gg, bb, aa);
+     }
+}
+
+void
 evas_gl_common_context_flush(Evas_GL_Context *gc)
 {
    shader_array_flush(gc);
@@ -349,58 +454,80 @@ shader_array_flush(Evas_GL_Context *gc)
    if (gc->array.num <= 0) return;
 
 //   fprintf(stderr, "  flush array %i\n", gc->array.num);
-   glUseProgram(gc->shader.cur_prog);
-  
-   if (gc->shader.cur_tex)
+   if (gc->shader.cur_prog != gc->shader.current.cur_prog)
+     glUseProgram(gc->shader.cur_prog);
+
+   if (gc->shader.cur_tex != gc->shader.current.cur_tex)
      {
         glBindTexture(GL_TEXTURE_2D, gc->shader.cur_tex);
      }
-   else
+   if (gc->shader.blend != gc->shader.current.blend)
      {
-        glBindTexture(GL_TEXTURE_2D, gc->shader.cur_tex);
+        if (gc->shader.blend)
+          glEnable(GL_BLEND);
+        else 
+          glDisable(GL_BLEND);
      }
-   if (gc->shader.blend)
-     glEnable(GL_BLEND);
-   else 
-     glDisable(GL_BLEND);
-   if (gc->shader.smooth)
+   if (gc->shader.smooth != gc->shader.current.smooth)
      {
+        if (gc->shader.smooth)
+          {
 #ifdef GL_TEXTURE_MAX_ANISOTROPY_EXT
-        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 16);
+             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 16);
 #endif
-        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-     }
-   else
-     {
+             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+          }
+        else
+          {
 #ifdef GL_TEXTURE_MAX_ANISOTROPY_EXT
-        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1);
+             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1);
 #endif
-        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+          }
      }
-   
-   glEnableVertexAttribArray(SHAD_VERTEX);
+
    glVertexAttribPointer(SHAD_VERTEX, 3, GL_INT, GL_FALSE, 0, gc->array.vertex);
-   
-   glEnableVertexAttribArray(SHAD_COLOR);
    glVertexAttribPointer(SHAD_COLOR, 4, GL_FLOAT, GL_FALSE, 0, gc->array.color);
-   
-   glEnableVertexAttribArray(SHAD_TEXUV);
    glVertexAttribPointer(SHAD_TEXUV, 2, GL_FLOAT, GL_FALSE, 0, gc->array.texuv);
+   if ((gc->array.texuv2) && (gc->array.texuv3))
+     {
+        glEnableVertexAttribArray(SHAD_TEXUV2);
+        glEnableVertexAttribArray(SHAD_TEXUV3);
+        glVertexAttribPointer(SHAD_TEXUV2, 2, GL_FLOAT, GL_FALSE, 0, gc->array.texuv2);
+        glVertexAttribPointer(SHAD_TEXUV3, 2, GL_FLOAT, GL_FALSE, 0, gc->array.texuv3);
+        glActiveTexture(GL_TEXTURE0);
+        glBindTexture(GL_TEXTURE_2D, gc->shader.cur_tex);
+        glActiveTexture(GL_TEXTURE1);
+        glBindTexture(GL_TEXTURE_2D, gc->shader.cur_texu);
+        glActiveTexture(GL_TEXTURE2);
+        glBindTexture(GL_TEXTURE_2D, gc->shader.cur_texv);
+     }
+   else
+     {
+        glDisableVertexAttribArray(SHAD_TEXUV2);
+        glDisableVertexAttribArray(SHAD_TEXUV3);
+     }
    
    glDrawArrays(GL_TRIANGLES, 0, gc->array.num);
-   
-   gc->shader.cur_prog = 0;
-   gc->shader.cur_tex = 0;
+
+   gc->shader.current.cur_prog = gc->shader.cur_prog;
+   gc->shader.current.cur_tex = gc->shader.cur_tex;
+   gc->shader.current.blend = gc->shader.blend;
+   gc->shader.current.smooth = gc->shader.smooth;
    
    free(gc->array.vertex);
    free(gc->array.color);
    free(gc->array.texuv);
+   free(gc->array.texuv2);
+   free(gc->array.texuv3);
    
    gc->array.vertex = NULL;
    gc->array.color = NULL;
    gc->array.texuv = NULL;
+   gc->array.texuv2 = NULL;
+   gc->array.texuv3 = NULL;
    
    gc->array.num = 0;
    gc->array.alloc = 0;
@@ -455,4 +582,7 @@ _evas_gl_common_viewport_set(Evas_GL_Context *gc)
    glUseProgram(gc->shader.font.prog);
    glUniformMatrix4fv(glGetUniformLocation(gc->shader.font.prog, "mvp"), 1,
                       GL_FALSE, proj);
+   glUseProgram(gc->shader.yuv.prog);
+   glUniformMatrix4fv(glGetUniformLocation(gc->shader.yuv.prog, "mvp"), 1,
+                      GL_FALSE, proj);
 }
index 435f5d0..f1b12a1 100644 (file)
@@ -195,6 +195,7 @@ evas_gl_common_image_draw(Evas_GL_Context *gc, Evas_GL_Image *im, int sx, int sy
    Cutout_Rect  *rct;
    int c, cx, cy, cw, ch;
    int i;
+   int yuv = 0;
    
    if (sw < 1) sw = 1;
    if (sh < 1) sh = 1;
@@ -210,7 +211,7 @@ evas_gl_common_image_draw(Evas_GL_Context *gc, Evas_GL_Image *im, int sx, int sy
      {
        r = g = b = a = 255;
      }
-   
+/*   
    if ((im->cs.space == EVAS_COLORSPACE_YCBCR422P601_PL) ||
        (im->cs.space == EVAS_COLORSPACE_YCBCR422P709_PL))
      {
@@ -230,6 +231,7 @@ evas_gl_common_image_draw(Evas_GL_Context *gc, Evas_GL_Image *im, int sx, int sy
         space = EVAS_COLORSPACE_ARGB8888;
      }
    else
+ */
      space = im->cs.space;
    
    switch (space)
@@ -243,10 +245,27 @@ evas_gl_common_image_draw(Evas_GL_Context *gc, Evas_GL_Image *im, int sx, int sy
          }
        if (!im->tex)
          im->tex = evas_gl_common_texture_new(gc, im->im);
+        if (!im->tex) return;
        break;
       case EVAS_COLORSPACE_YCBCR422P601_PL:
       case EVAS_COLORSPACE_YCBCR422P709_PL:
-       break;
+        if ((im->tex) && (im->dirty))
+          {
+             evas_gl_common_texture_yuv_update(im->tex, im->cs.data,
+                                               im->im->cache_entry.w, 
+                                               im->im->cache_entry.h);
+             im->dirty = 0;
+          }
+        if ((!im->tex) && (im->cs.data) && (*((unsigned char **)im->cs.data)))
+          {
+             im->tex = evas_gl_common_texture_yuv_new(gc, im->cs.data,
+                                                      im->im->cache_entry.w, 
+                                                      im->im->cache_entry.h);
+             im->dirty = 0;
+          }
+        yuv = 1;
+        if (!im->tex) return;
+        break;
       default:
         printf("unhandled img format\n");
        break;
@@ -267,12 +286,20 @@ evas_gl_common_image_draw(Evas_GL_Context *gc, Evas_GL_Image *im, int sx, int sy
              if ((nw < 1) || (nh < 1)) return;
              if ((nx == dx) && (ny == dy) && (nw == dw) && (nh == dh))
                {
-                  evas_gl_common_context_image_push(gc,
+                  if (yuv)
+                    evas_gl_common_context_yuv_push(gc,
                                                     im->tex,
                                                     sx, sy, sw, sh,
                                                     dx, dy, dw, dh,
                                                     r, g, b, a,
                                                     smooth);
+                  else
+                    evas_gl_common_context_image_push(gc,
+                                                      im->tex,
+                                                      sx, sy, sw, sh,
+                                                      dx, dy, dw, dh,
+                                                      r, g, b, a,
+                                                      smooth);
                   return;
                }
              
@@ -280,21 +307,37 @@ evas_gl_common_image_draw(Evas_GL_Context *gc, Evas_GL_Image *im, int sx, int sy
              ssy = (double)sy + ((double)(sh * (ny - dy)) / (double)(dh));
              ssw = ((double)sw * (double)(nw)) / (double)(dw);
              ssh = ((double)sh * (double)(nh)) / (double)(dh);
-             evas_gl_common_context_image_push(gc,
+             if (yuv)
+               evas_gl_common_context_yuv_push(gc,
                                                im->tex,
                                                ssx, ssy, ssw, ssh,
                                                nx, ny, nw, nh,
                                                r, g, b, a,
                                                smooth);
+             else
+               evas_gl_common_context_image_push(gc,
+                                                 im->tex,
+                                                 ssx, ssy, ssw, ssh,
+                                                 nx, ny, nw, nh,
+                                                 r, g, b, a,
+                                                 smooth);
           }
         else
           {
-             evas_gl_common_context_image_push(gc,
+             if (yuv)
+               evas_gl_common_context_yuv_push(gc,
                                                im->tex,
                                                sx, sy, sw, sh,
                                                dx, dy, dw, dh,
                                                r, g, b, a,
                                                smooth);
+             else
+               evas_gl_common_context_image_push(gc,
+                                                 im->tex,
+                                                 sx, sy, sw, sh,
+                                                 dx, dy, dw, dh,
+                                                 r, g, b, a,
+                                                 smooth);
           }
         return;
      }
@@ -320,24 +363,40 @@ evas_gl_common_image_draw(Evas_GL_Context *gc, Evas_GL_Image *im, int sx, int sy
         if ((nw < 1) || (nh < 1)) continue;
         if ((nx == dx) && (ny == dy) && (nw == dw) && (nh == dh))
           {
-             evas_gl_common_context_image_push(gc,
-                                               im->tex,
-                                               sx, sy, sw, sh,
-                                               dx, dy, dw, dh,
+             if (yuv)
+               evas_gl_common_context_yuv_push(gc,
+                                                 im->tex,
+                                                 sx, sy, sw, sh,
+                                                 dx, dy, dw, dh,
                                                r, g, b, a,
-                                               smooth);
+                                                 smooth);
+             else
+               evas_gl_common_context_image_push(gc,
+                                                 im->tex,
+                                                 sx, sy, sw, sh,
+                                                 dx, dy, dw, dh,
+                                                 r, g, b, a,
+                                                 smooth);
              continue;
           }
         ssx = (double)sx + ((double)(sw * (nx - dx)) / (double)(dw));
         ssy = (double)sy + ((double)(sh * (ny - dy)) / (double)(dh));
         ssw = ((double)sw * (double)(nw)) / (double)(dw);
         ssh = ((double)sh * (double)(nh)) / (double)(dh);
-        evas_gl_common_context_image_push(gc,
+        if (yuv)
+          evas_gl_common_context_yuv_push(gc,
                                           im->tex,
                                           ssx, ssy, ssw, ssh,
                                           nx, ny, nw, nh,
                                           r, g, b, a,
                                           smooth);
+        else
+          evas_gl_common_context_image_push(gc,
+                                            im->tex,
+                                            ssx, ssy, ssw, ssh,
+                                            nx, ny, nw, nh,
+                                            r, g, b, a,
+                                            smooth);
      }
    evas_common_draw_context_apply_clear_cutouts(rects);
    /* restore clip info */
index e45341a..ca7f121 100644 (file)
@@ -120,6 +120,46 @@ Evas_GL_Program_Source shader_font_vert_src =
 #endif     
 };
 
+/////////////////////////////////////////////
+#if defined (GLES_VARIETY_S3C6410)
+const unsigned int yuv_frag_bin[] =
+{
+# include "shader/yuv_frag_bin.h"
+};
+#endif
+
+const char yuv_frag_glsl[] =
+#include "shader/yuv_frag.h"
+  ;
+Evas_GL_Program_Source shader_yuv_frag_src =
+{
+   yuv_frag_glsl,
+#if defined (GLES_VARIETY_S3C6410)
+     yuv_frag_bin, sizeof(yuv_frag_bin_end)
+#else     
+     NULL, 0
+#endif     
+};
+
+#if defined (GLES_VARIETY_S3C6410)
+const unsigned int yuv_frag_bin[] =
+{
+# include "shader/yuv_vert_bin.h"
+};
+#endif
+const char yuv_vert_glsl[] =
+#include "shader/yuv_vert.h"
+  ;
+Evas_GL_Program_Source shader_yuv_vert_src =
+{
+   yuv_vert_glsl,
+#if defined (GLES_VARIETY_S3C6410)
+     yuv_vert_bin, sizeof(yuv_vert_bin)
+#else     
+     NULL, 0
+#endif     
+};
+
 
 
 
@@ -174,6 +214,8 @@ evas_gl_common_shader_program_init(Evas_GL_Program *p,
    glBindAttribLocation(p->prog, SHAD_VERTEX, "vertex");
    glBindAttribLocation(p->prog, SHAD_COLOR, "color");
    glBindAttribLocation(p->prog, SHAD_TEXUV, "tex_coord");
+   glBindAttribLocation(p->prog, SHAD_TEXUV2, "tex_coord2");
+   glBindAttribLocation(p->prog, SHAD_TEXUV3, "tex_coord3");
    
    glLinkProgram(p->prog);
    glGetProgramiv(p->prog, GL_LINK_STATUS, &ok);
index 484c14d..3b80cc0 100644 (file)
@@ -44,6 +44,8 @@ _tex_format_index(GLuint format)
         return 1;
      case GL_ALPHA:
         return 2;
+     case GL_LUMINANCE:
+        return 3;
      default:
         break;
      }
@@ -68,7 +70,7 @@ _pool_tex_new(Evas_GL_Context *gc, int w, int h, GLuint format)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0,
-                format, GL_UNSIGNED_BYTE, NULL);
+                format, GL_UNSIGNED_BYTE/* fixme - pass this in */, NULL);
    glBindTexture(GL_TEXTURE_2D, gc->shader.cur_tex);
    return pt;
 }
@@ -204,7 +206,7 @@ evas_gl_common_texture_new(Evas_GL_Context *gc, RGBA_Image *im)
 void
 evas_gl_common_texture_update(Evas_GL_Texture *tex, RGBA_Image *im)
 {
-#ifdef defined(GL_UNSIGNED_INT_8_8_8_8_REV) && defined(GL_BGRA)
+#if defined(GL_UNSIGNED_INT_8_8_8_8_REV) && defined(GL_BGRA)
 #define COLOR_FORMAT GL_RGBA   
 #define PIXEL_FORMAT GL_UNSIGNED_BYTE
 // FIXME: need to change shader for this to work
@@ -215,6 +217,7 @@ evas_gl_common_texture_update(Evas_GL_Texture *tex, RGBA_Image *im)
 #define PIXEL_FORMAT GL_UNSIGNED_BYTE
 #endif   
    glBindTexture(GL_TEXTURE_2D, tex->pt->texture);
+   glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
    glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
    //  +-+
    //  +-+
@@ -338,6 +341,7 @@ void
 evas_gl_common_texture_alpha_update(Evas_GL_Texture *tex, DATA8 *pixels, int w, int h, int fh)
 {
    glBindTexture(GL_TEXTURE_2D, tex->pt->texture);
+   glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
    glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
    glTexSubImage2D(GL_TEXTURE_2D, 0,
                   tex->x, tex->y, w, h,
@@ -348,3 +352,72 @@ evas_gl_common_texture_alpha_update(Evas_GL_Texture *tex, DATA8 *pixels, int w,
         glBindTexture(GL_TEXTURE_2D, tex->gc->shader.cur_tex);
      }
 }
+
+Evas_GL_Texture *
+evas_gl_common_texture_yuv_new(Evas_GL_Context *gc, DATA8 **rows, int w, int h)
+{
+   Evas_GL_Texture *tex;
+   Eina_List *l_after = NULL;
+   int u = 0, v = 0;
+
+   tex = calloc(1, sizeof(Evas_GL_Texture));
+   if (!tex) return NULL;
+   
+   tex->gc = gc;
+   tex->references = 1;
+   tex->pt = _pool_tex_new(gc, w + 1, h  + 1, GL_LUMINANCE);
+   gc->tex.whole = eina_list_prepend(gc->tex.whole, tex->pt);
+   tex->pt->slot = -1;
+   tex->pt->fslot = -1;
+   tex->pt->whole = 1;
+   tex->ptu = _pool_tex_new(gc, (w / 2) + 1, (h / 2)  + 1, GL_LUMINANCE);
+   gc->tex.whole = eina_list_prepend(gc->tex.whole, tex->ptu);
+   tex->ptu->slot = -1;
+   tex->ptu->fslot = -1;
+   tex->ptu->whole = 1;
+   tex->ptv = _pool_tex_new(gc, (w / 2) + 1, (h / 2)  + 1, GL_LUMINANCE);
+   gc->tex.whole = eina_list_prepend(gc->tex.whole, tex->ptv);
+   tex->ptv->slot = -1;
+   tex->ptv->fslot = -1;
+   tex->ptv->whole = 1;
+   tex->x = 0;
+   tex->y = 0;
+   tex->w = w;
+   tex->h = h;
+   tex->pt->allocations = eina_list_prepend(tex->pt->allocations, tex);
+   tex->ptu->allocations = eina_list_prepend(tex->ptu->allocations, tex);
+   tex->ptv->allocations = eina_list_prepend(tex->ptv->allocations, tex);
+   tex->pt->references++;
+   tex->ptu->references++;
+   tex->ptv->references++;
+   evas_gl_common_texture_yuv_update(tex, rows, w, h);
+   return tex;
+}
+
+void
+evas_gl_common_texture_yuv_update(Evas_GL_Texture *tex, DATA8 **rows, int w, int h)
+{
+   glPixelStorei(GL_UNPACK_ROW_LENGTH, rows[1] - rows[0]);
+   glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+   glBindTexture(GL_TEXTURE_2D, tex->pt->texture);
+   glTexSubImage2D(GL_TEXTURE_2D, 0,
+                  0, 0, w, h,
+                   GL_LUMINANCE, GL_UNSIGNED_BYTE,
+                  rows[0]);
+   glBindTexture(GL_TEXTURE_2D, tex->ptu->texture);
+   glPixelStorei(GL_UNPACK_ROW_LENGTH, rows[h + 1] - rows[h]);
+   glTexSubImage2D(GL_TEXTURE_2D, 0,
+                  0, 0, w / 2, h / 2,
+                   GL_LUMINANCE, GL_UNSIGNED_BYTE,
+                  rows[h]);
+   glBindTexture(GL_TEXTURE_2D, tex->ptv->texture);
+   glPixelStorei(GL_UNPACK_ROW_LENGTH, rows[h + (h / 2) + 1] - rows[h + (h / 2)]);
+   glTexSubImage2D(GL_TEXTURE_2D, 0,
+                  0, 0, w / 2, h / 2,
+                   GL_LUMINANCE, GL_UNSIGNED_BYTE,
+                  rows[h + (h / 2)]);
+   if (tex->pt->texture != tex->gc->shader.cur_tex)
+     {
+        glBindTexture(GL_TEXTURE_2D, tex->gc->shader.cur_tex);
+     }
+}
diff --git a/src/modules/engines/gl_common/shader/yuv_frag.h b/src/modules/engines/gl_common/shader/yuv_frag.h
new file mode 100644 (file)
index 0000000..cc3f1e5
--- /dev/null
@@ -0,0 +1,19 @@
+"uniform sampler2D tex, texu, texv;\n"
+"varying vec4 col;\n"
+"varying vec2 tex_c;\n"
+"varying vec2 tex_c2;\n"
+"varying vec2 tex_c3;\n"
+"void main()\n"
+"{\n"
+"   float r, g, b, y, u, v;\n"
+"   y = texture2D(tex, tex_c.xy).r;\n"
+"   u = texture2D(texu, tex_c2.xy).r;\n"
+"   v = texture2D(texv, tex_c3.xy).r;\n"
+"   y = (y - 0.0625) * 1.164;\n"
+"   u = u - 0.5;\n"
+"   v = v - 0.5;\n"
+"   r = y + (1.402   * v);\n"
+"   g = y - (0.34414 * u) - (0.71414 * v);\n"
+"   b = y + (1.772   * u);\n"
+"   gl_FragColor = vec4(r, g, b, 1.0) * col;\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/yuv_frag.shd b/src/modules/engines/gl_common/shader/yuv_frag.shd
new file mode 100644 (file)
index 0000000..612470e
--- /dev/null
@@ -0,0 +1,19 @@
+uniform sampler2D tex, texu, texv;
+varying vec4 col;
+varying vec2 tex_c;
+varying vec2 tex_c2;
+varying vec2 tex_c3;
+void main()
+{
+   float r, g, b, y, u, v;
+   y = texture2D(tex, tex_c.xy).r;
+   u = texture2D(texu, tex_c2.xy).r;
+   v = texture2D(texv, tex_c3.xy).r;
+   y = (y - 0.0625) * 1.164;
+   u = u - 0.5;
+   v = v - 0.5;
+   r = y + (1.402   * v);
+   g = y - (0.34414 * u) - (0.71414 * v);
+   b = y + (1.772   * u);
+   gl_FragColor = vec4(r, g, b, 1.0) * col;
+}
diff --git a/src/modules/engines/gl_common/shader/yuv_vert.h b/src/modules/engines/gl_common/shader/yuv_vert.h
new file mode 100644 (file)
index 0000000..be803cd
--- /dev/null
@@ -0,0 +1,16 @@
+"attribute vec4 vertex;\n"
+"attribute vec4 color;\n"
+"attribute vec2 tex_coord;\n"
+"attribute vec2 tex_coord2;\n"
+"attribute vec2 tex_coord3;\n"
+"uniform mat4 mvp;\n"
+"varying vec4 col;\n"
+"varying vec4 tex_c;\n"
+"void main()\n"
+"{\n"
+"   gl_Position = mvp * vertex;\n"
+"   col = color;\n"
+"   tex_c = tex_coord;\n"
+"   tex_c2 = tex_coord2;\n"
+"   tex_c3 = tex_coord3;\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/yuv_vert.shd b/src/modules/engines/gl_common/shader/yuv_vert.shd
new file mode 100644 (file)
index 0000000..60a969b
--- /dev/null
@@ -0,0 +1,16 @@
+attribute vec4 vertex;
+attribute vec4 color;
+attribute vec2 tex_coord;
+attribute vec2 tex_coord2;
+attribute vec2 tex_coord3;
+uniform mat4 mvp;
+varying vec4 col;
+varying vec4 tex_c;
+void main()
+{
+   gl_Position = mvp * vertex;
+   col = color;
+   tex_c = tex_coord;
+   tex_c2 = tex_coord2;
+   tex_c3 = tex_coord3;
+}