evas: and now MT12 gain Open GL support.
authorcedric <cedric@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Sun, 4 Sep 2011 21:15:04 +0000 (21:15 +0000)
committercedric <cedric@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Sun, 4 Sep 2011 21:15:04 +0000 (21:15 +0000)
git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/evas@63174 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/nv12_frag.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/nv12_nomul_frag.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/nv12_nomul_vert.h
src/modules/engines/gl_common/shader/nv12_vert.h

index 9c7d5b3..bfb81a1 100644 (file)
@@ -255,7 +255,7 @@ struct _Evas_GL_Shared
 #define RTYPE_MAP   5 /* need to merge with image */
 #define RTYPE_IMASK 6
 #define RTYPE_YUY2  7
-
+#define RTYPE_NV12  8
 
 struct _Evas_Engine_GL_Context
 {
index 31bcc97..14ba4c0 100644 (file)
@@ -1936,6 +1936,100 @@ 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_texu = tex->ptuv->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 = 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,
index 1c3d64c..07eba7b 100644 (file)
@@ -266,6 +266,9 @@ evas_gl_common_image_new(Evas_Engine_GL_Context *gc, unsigned int w, unsigned in
        break;
       case EVAS_COLORSPACE_YCBCR422P601_PL:
       case EVAS_COLORSPACE_YCBCR422P709_PL:
+      case EVAS_COLORSPACE_YCBCR422601_PL:
+      case EVAS_COLORSPACE_YCBCR420NV12601_PL:
+      case EVAS_COLORSPACE_YCBCR420TM12601_PL:
 //        if (im->tex) evas_gl_common_texture_free(im->tex);
        im->tex = NULL;
        im->cs.no_free = 0;
@@ -625,8 +628,6 @@ evas_gl_common_image_map_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im,
    RGBA_Draw_Context *dc;
    int r, g, b, a;
    int c, cx, cy, cw, ch;
-   Eina_Bool yuv = 0;
-   Eina_Bool yuy2 = 0;
 
    dc = gc->dc;
    if (dc->mul.use)
@@ -668,6 +669,7 @@ evas_gl_common_image_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im, int sx,
    int i;
    int yuv = 0;
    int yuy2 = 0;
+   int nv12 = 0;
 
    if (sw < 1) sw = 1;
    if (sh < 1) sh = 1;
@@ -702,6 +704,9 @@ evas_gl_common_image_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im, int sx,
      yuv = 1;
    if (im->cs.space == EVAS_COLORSPACE_YCBCR422601_PL)
      yuy2 = 1;
+   if ((im->cs.space == EVAS_COLORSPACE_YCBCR420NV12601_PL) ||
+       (im->cs.space == EVAS_COLORSPACE_YCBCR420TM12601_PL))
+     nv12 = 1;
 
    im->tex->im = im;
    if (imm) imm->tex->im = imm;
@@ -735,6 +740,13 @@ evas_gl_common_image_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im, int sx,
                                                     dx, dy, dw, dh,
                                                     r, g, b, a,
                                                     smooth);
+                  else if (nv12)
+                    evas_gl_common_context_nv12_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,
@@ -785,6 +797,13 @@ evas_gl_common_image_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im, int sx,
                                                nx, ny, nw, nh,
                                                r, g, b, a,
                                                smooth);
+             else if (nv12)
+               evas_gl_common_context_nv12_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,
@@ -809,6 +828,13 @@ evas_gl_common_image_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im, int sx,
                                                dx, dy, dw, dh,
                                                r, g, b, a,
                                                smooth);
+             else if (nv12)
+               evas_gl_common_context_nv12_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,
@@ -855,6 +881,13 @@ evas_gl_common_image_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im, int sx,
                                                dx, dy, dw, dh,
                                                r, g, b, a,
                                                smooth);
+             else if (nv12)
+               evas_gl_common_context_nv12_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,
@@ -882,6 +915,13 @@ evas_gl_common_image_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im, int sx,
                                           nx, ny, nw, nh,
                                           r, g, b, a,
                                           smooth);
+        else if (nv12)
+          evas_gl_common_context_nv12_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,
index 5f05c00..6666ac5 100644 (file)
@@ -239,6 +239,46 @@ Evas_GL_Program_Source shader_nv12_vert_src =
 #endif
 };
 
+#if defined (GLES_VARIETY_S3C6410)
+const unsigned int nv12_nomul_frag_bin[] =
+{
+# include "shader/nv12_nomul_frag_bin_s3c6410.h"
+};
+#endif
+
+const char nv12_frag_glsl[] =
+#include "shader/nv12_frag.h"
+  ;
+Evas_GL_Program_Source shader_nv12_frag_src =
+{
+   nv12_frag_glsl,
+#if defined (GLES_VARIETY_S3C6410)
+     nv12_frag_bin, sizeof(nv12_frag_bin)
+#else
+     NULL, 0
+#endif
+};
+
+#if defined (GLES_VARIETY_S3C6410)
+const unsigned int nv12_nomul_frag_bin[] =
+{
+# include "shader/nv12_nomul_frag_bin_s3c6410.h"
+};
+#endif
+
+const char nv12_nomul_frag_glsl[] =
+#include "shader/nv12_nomul_frag.h"
+  ;
+Evas_GL_Program_Source shader_nv12_nomul_frag_src =
+{
+   nv12_nomul_frag_glsl,
+#if defined (GLES_VARIETY_S3C6410)
+     nv12_nomul_frag_bin, sizeof(nv12_nomul_frag_bin)
+#else
+     NULL, 0
+#endif
+};
+
 /////////////////////////////////////////////
 #if defined (GLES_VARIETY_S3C6410)
 const unsigned int yuv_nomul_frag_bin[] =
@@ -1068,8 +1108,8 @@ static const struct {
   SHADER_SOURCE_LINE(YUV_NOMUL, yuv_nomul),
   SHADER_SOURCE_LINE(YUY2, yuy2),
   SHADER_SOURCE_LINE(YUY2_NOMUL, yuy2_nomul),
-  { SHADER_NV12, &(shader_nv12_vert_src), &(shader_yuy2_frag_src), "nv12" },
-  { SHADER_NV12_NOMUL, &(shader_nv12_nomul_vert_src), &(shader_yuy2_nomul_frag_src), "nv12_nomul" },
+  SHADER_SOURCE_LINE(NV12, nv12),
+  SHADER_SOURCE_LINE(NV12_NOMUL, nv12_nomul),
   SHADER_SOURCE_LINE(TEX, tex),
   SHADER_SOURCE_LINE(TEX_NOMUL, tex_nomul),
    /* Most of the filters use the image fragment shader */
index ff38a6d..71ce0f4 100644 (file)
@@ -1067,7 +1067,9 @@ evas_gl_common_texture_yuv_update(Evas_GL_Texture *tex, DATA8 **rows, unsigned i
 static Evas_GL_Texture *
 _evas_gl_common_texture_y2uv_new(Evas_Engine_GL_Context *gc,
                                 unsigned int yw, unsigned int yh,
-                                unsigned int uvw, unsigned int uvh)
+                                unsigned int uvw, unsigned int uvh,
+                                 GLenum y_ifmt, GLenum y_fmt,
+                                 GLenum uv_ifmt, GLenum uv_fmt)
 {
    Evas_GL_Texture *tex;
 
@@ -1076,7 +1078,7 @@ _evas_gl_common_texture_y2uv_new(Evas_Engine_GL_Context *gc,
 
    tex->gc = gc;
    tex->references = 1;
-   tex->pt = _pool_tex_new(gc, yw + 1, yh  + 1, lum_alpha_ifmt, lum_alpha_fmt);
+   tex->pt = _pool_tex_new(gc, yw + 1, yh  + 1, y_ifmt, y_fmt);
    if (!tex->pt)
      {
         free(tex);
@@ -1086,7 +1088,7 @@ _evas_gl_common_texture_y2uv_new(Evas_Engine_GL_Context *gc,
    tex->pt->slot = -1;
    tex->pt->fslot = -1;
    tex->pt->whole = 1;
-   tex->ptuv = _pool_tex_new(gc, uvw + 1, uvh  + 1, rgba8_ifmt, rgba8_fmt);
+   tex->ptuv = _pool_tex_new(gc, uvw + 1, uvh  + 1, uv_ifmt, uv_fmt);
    if (!tex->ptuv)
      {
         pt_unref(tex->pt);
@@ -1113,7 +1115,7 @@ evas_gl_common_texture_yuy2_new(Evas_Engine_GL_Context *gc, DATA8 **rows, unsign
 {
    Evas_GL_Texture *tex;
 
-   tex = _evas_gl_common_texture_y2uv_new(gc, w, h, w / 2, h);
+   tex = _evas_gl_common_texture_y2uv_new(gc, w, h, w / 2, h, lum_alpha_ifmt, lum_alpha_fmt, rgba8_ifmt, rgba8_fmt);
    evas_gl_common_texture_yuy2_update(tex, rows, w, h);
    return tex;
 }
@@ -1123,7 +1125,7 @@ evas_gl_common_texture_nv12_new(Evas_Engine_GL_Context *gc, DATA8 **rows, unsign
 {
    Evas_GL_Texture *tex;
 
-   tex = _evas_gl_common_texture_y2uv_new(gc, w, h, w / 2, h / 2);
+   tex = _evas_gl_common_texture_y2uv_new(gc, w, h, w / 2, h / 2, alpha_ifmt, alpha_fmt, lum_alpha_ifmt, lum_alpha_fmt);
    evas_gl_common_texture_nv12_update(tex, rows, w, h);
    return tex;
 }
@@ -1133,7 +1135,7 @@ evas_gl_common_texture_nv12tiled_new(Evas_Engine_GL_Context *gc, DATA8 **rows, u
 {
    Evas_GL_Texture *tex;
 
-   tex = _evas_gl_common_texture_y2uv_new(gc, w, h, w / 2, h / 2);
+   tex = _evas_gl_common_texture_y2uv_new(gc, w, h, w / 2, h / 2, alpha_ifmt, alpha_fmt, lum_alpha_ifmt, lum_alpha_fmt);
    evas_gl_common_texture_nv12tiled_update(tex, rows, w, h);
    return tex;
 }
@@ -1227,7 +1229,104 @@ evas_gl_common_texture_nv12_update(Evas_GL_Texture *tex, DATA8 **rows, unsigned
 void
 evas_gl_common_texture_nv12tiled_update(Evas_GL_Texture *tex, DATA8 **rows, unsigned int w, unsigned int h)
 {
+   unsigned int mb_x, mb_y, mb_w, mb_h;
+   unsigned int base_h;
+
    if (!tex->pt) return;
-   // FIXME: not done yet
-   abort();
+
+   glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   glBindTexture(GL_TEXTURE_2D, tex->pt->texture);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+
+   mb_w = w / 64;
+   mb_h = h / 32;
+
+   /* Iterate each Y macroblock like we do in evas_convert_yuv.c */
+   for (mb_y = 0; mb_y < (mb_h >> 1); mb_y++)
+     {
+        int step = 2;
+        int offset = 0;
+        int x = 0;
+        int rmb_x = 0;
+        int ry[2];
+
+        ry[0] = mb_y * 2 * 32;
+        ry[1] = ry[0] + 32;
+
+        for (mb_x = 0; mb_x < mb_w * 2; mb_x++, rmb_x += 64 * 32)
+          {
+             _tex_sub_2d(x, ry[offset], 64, 32, tex->pt->format, tex->pt->dataformat, rows[mb_y] + rmb_x);
+
+             step++;
+             if ((step & 0x3) == 0)
+               {
+                  offset = 1 - offset;
+                  x -= 64;
+               }
+             else
+               {
+                  x += 64;
+               }
+          }
+     }
+
+   if (mb_h & 0x1)
+     {
+        int rmb_x = 0;
+        int x = 0;
+        int ry;
+
+        ry = mb_y * 2 * 32;
+
+        for (mb_x = 0; mb_x < mb_w; mb_x++, x += 64, rmb_x += 64 * 32)
+          _tex_sub_2d(x, ry, 64, 32, tex->pt->format, tex->pt->dataformat, rows[mb_y] + rmb_x);
+     }
+
+   glBindTexture(GL_TEXTURE_2D, tex->ptuv->texture);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+
+   /* Iterate each UV macroblock like we do in evas_convert_yuv.c */
+   base_h = (mb_h >> 1) + (mb_h & 0x1);
+   for (mb_y = 0; mb_y < (mb_h >> 2); mb_y++)
+     {
+        int step = 2;
+        int offset = 0;
+        int x = 0;
+        int rmb_x = 0;
+        int ry[2];
+
+        ry[0] = mb_y * 2 * 32;
+        ry[1] = ry[0] + 32;
+
+        for (mb_x = 0; mb_x < mb_w * 2; mb_x++, rmb_x += 64 * 32)
+          {
+             _tex_sub_2d(x, ry[offset], 32, 32,
+                         tex->ptuv->format, tex->ptuv->dataformat,
+                         rows[mb_y + base_h] + rmb_x);
+
+             step++;
+             if ((step & 0x3) == 0)
+               {
+                  offset = 1 - offset;
+                  x -= 32;
+               }
+             else
+               {
+                  x += 32;
+               }
+          }
+     }
+
+   if (mb_h & 0x1)
+     {
+        int rmb_x = 0;
+        int x = 0;
+        int ry;
+
+        ry = mb_y * 2 * 32;
+
+        for (mb_x = 0; mb_x < mb_w; mb_x++, x += 32, rmb_x += 64 * 32)
+          _tex_sub_2d(x, ry, 64, 32, tex->ptuv->format, tex->ptuv->dataformat, rows[mb_y + base_h] + rmb_x);
+     }
 }
diff --git a/src/modules/engines/gl_common/shader/nv12_frag.h b/src/modules/engines/gl_common/shader/nv12_frag.h
new file mode 100644 (file)
index 0000000..2a13b87
--- /dev/null
@@ -0,0 +1,27 @@
+"#ifdef GL_ES\n"
+"precision mediump float;\n"
+"#endif\n"
+"uniform sampler2D tex, texuv;\n"
+"varying vec4 col;\n"
+"varying vec2 tex_c, tex_cuv;\n"
+"void main()\n"
+"{\n"
+"  float y,u,v,vmu,r,g,b;\n"
+"  y=texture2D(tex,tex_c).a;\n"
+"  u=texture2D(texuv,tex_cuv).g;\n"
+"  v=texture2D(texuv,tex_cuv).a;\n"
+
+"  u=u-0.5;\n"
+"  v=v-0.5;\n"
+"  vmu=v*0.813+u*0.391;\n"
+"  u=u*2.018;\n"
+"  v=v*1.596;\n"
+"  y=(y-0.062)*1.164;\n"
+
+"  r=y+v;\n"
+"  g=y-vmu;\n"
+"  b=y+u;\n"
+
+"  gl_FragColor=vec4(r,g,b,1.0) * col;\n"
+"}\n"
+
diff --git a/src/modules/engines/gl_common/shader/nv12_nomul_frag.h b/src/modules/engines/gl_common/shader/nv12_nomul_frag.h
new file mode 100644 (file)
index 0000000..e17c211
--- /dev/null
@@ -0,0 +1,26 @@
+"#ifdef GL_ES\n"
+"precision mediump float;\n"
+"#endif\n"
+"uniform sampler2D tex, texuv;\n"
+"varying vec2 tex_c, tex_cuv;\n"
+"void main()\n"
+"{\n"
+"  float y,u,v,vmu,r,g,b;\n"
+"  y=texture2D(tex,tex_c).a;\n"
+"  u=texture2D(texuv,tex_cuv).g;\n"
+"  v=texture2D(texuv,tex_cuv).a;\n"
+
+"  u=u-0.5;\n"
+"  v=v-0.5;\n"
+"  vmu=v*0.813+u*0.391;\n"
+"  u=u*2.018;\n"
+"  v=v*1.596;\n"
+"  y=(y-0.062)*1.164;\n"
+
+"  r=y+v;\n"
+"  g=y-vmu;\n"
+"  b=y+u;\n"
+
+"  gl_FragColor=vec4(r,g,b,1.0);\n"
+"}\n"
+
index 3227065..21304c2 100644 (file)
@@ -10,5 +10,5 @@
 "{\n"
 "   gl_Position = mvp * vertex;\n"
 "   tex_c = tex_coord;\n"
-"   tex_cuv = tex_coord2;\n"
+"   tex_cuv = tex_coord2 * 0.5;\n"
 "}\n"
index 0cb908e..6b3fea7 100644 (file)
@@ -12,5 +12,5 @@
 "   gl_Position = mvp * vertex;\n"
 "   col = color;\n"
 "   tex_c = tex_coord;\n"
-"   tex_cuv = tex_coord2;\n"
+"   tex_cuv = tex_coord2 * 0.5;\n"
 "}\n"