evas: add NV12 and MT12 colorspace.
authorcedric <cedric@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Mon, 29 Aug 2011 20:56:48 +0000 (20:56 +0000)
committercedric <cedric@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Mon, 29 Aug 2011 20:56:48 +0000 (20:56 +0000)
MT12 is has documented in Linux videodev documentation
a 64 * 32 macro block tiled colorspace format used on
Samsung hardware.

git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/evas@62967 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

24 files changed:
ChangeLog
src/lib/Evas.h
src/lib/canvas/evas_object_image.c
src/lib/engines/common/evas_convert_colorspace.c
src/lib/engines/common/evas_convert_colorspace.h
src/lib/engines/common/evas_convert_yuv.c
src/lib/engines/common/evas_convert_yuv.h
src/lib/engines/common/evas_image_main.c
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_nomul_vert.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/nv12_nomul_vert.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/nv12_vert.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/nv12_vert.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/yuy2_frag.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/yuy2_nomul_frag.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/yuy2_nomul_vert.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/yuy2_vert.shd [new file with mode: 0644]
src/modules/engines/gl_sdl/evas_engine.c
src/modules/engines/gl_x11/evas_engine.c
src/modules/engines/software_generic/evas_engine.c

index 494fbba..30d7a93 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
 
        * Fix evas_object_image_data_convert.
        * Add YUV 601 input format to evas_object_image_data_convert.
+
+2011-08-29  Cedric Bail
+
+       * Add colorspaces NV12 and MT12 (64 * 32 macro block tiled
+       format, see Linux videodev documentation for more information).
index 1db88d5..4cc8584 100644 (file)
@@ -510,7 +510,9 @@ typedef enum _Evas_Colorspace
    EVAS_COLORSPACE_YCBCR422P709_PL,/**< YCbCr 4:2:2 Planar, ITU.BT-709 specifications. The data pointed to is just an array of row pointer, pointing to the Y rows, then the Cb, then Cr rows */
    EVAS_COLORSPACE_RGB565_A5P, /**< 16bit rgb565 + Alpha plane at end - 5 bits of the 8 being used per alpha byte */
    EVAS_COLORSPACE_GRY8, /**< 8bit grayscale */
-   EVAS_COLORSPACE_YCBCR422601_PL /**<  YCbCr 4:2:2, ITU.BT-601 specifications. The data poitned to is just an array of row pointer, pointing to line of Y,Cb,Y,Cr bytes */
+   EVAS_COLORSPACE_YCBCR422601_PL, /**<  YCbCr 4:2:2, ITU.BT-601 specifications. The data poitned to is just an array of row pointer, pointing to line of Y,Cb,Y,Cr bytes */
+   EVAS_COLORSPACE_YCBCR420NV12601_PL, /**< YCbCr 4:2:0, ITU.BT-601 specification. The data pointed to is just an array of row pointer, pointing to the Y rows, then the Cb,Cr rows. */
+   EVAS_COLORSPACE_YCBCR420TM12601_PL, /**< YCbCr 4:2:0, ITU.BT-601 specification. The data pointed to is just an array of tiled row pointer, pointing to the Y rows, then the Cb,Cr rows. */
 } Evas_Colorspace; /**< Colorspaces for pixel data supported by Evas */
 
 /**
index 937a0c4..4b68e0c 100644 (file)
@@ -3644,6 +3644,18 @@ evas_object_image_data_convert_internal(Evas_Object_Image *o, void *data, Evas_C
                                                     o->cur.image.h,
                                                     to_cspace);
           break;
+        case EVAS_COLORSPACE_YCBCR420NV12601_PL:
+          out = evas_common_convert_yuv_420_601_to(data,
+                                                   o->cur.image.w,
+                                                   o->cur.image.h,
+                                                   to_cspace);
+          break;
+        case EVAS_COLORSPACE_YCBCR420TM12601_PL:
+          out = evas_common_convert_yuv_420T_601_to(data,
+                                                   o->cur.image.w,
+                                                   o->cur.image.h,
+                                                   to_cspace);
+          break;
        default:
            fprintf(stderr, "unknow colorspace: %i\n", o->cur.cspace);
          break;
index 6ee1560..013c2e7 100644 (file)
@@ -140,5 +140,47 @@ evas_common_convert_yuv_422P_601_to(void *data, int w, int h, Evas_Colorspace cs
    return NULL;
 }
 
+EAPI void *
+evas_common_convert_yuv_420_601_to(void *data, int w, int h, Evas_Colorspace cspace)
+{
+   switch (cspace)
+     {
+      case EVAS_COLORSPACE_ARGB8888:
+        {
+           void *dst;
+
+           dst = malloc(sizeof (unsigned int) * w * h);
+           if (!dst) return NULL;
+
+           evas_common_convert_yuv_420_601_rgba(data, dst, w, h);
+           break;
+        }
+      default:
+         break;
+     }
+   return NULL;
+}
+
+EAPI void *
+evas_common_convert_yuv_420T_601_to(void *data, int w, int h, Evas_Colorspace cspace)
+{
+   switch (cspace)
+     {
+      case EVAS_COLORSPACE_ARGB8888:
+        {
+           void *dst;
+
+           dst = malloc(sizeof (unsigned int) * w * h);
+           if (!dst) return NULL;
+
+           evas_common_convert_yuv_420_601_rgba(data, dst, w, h);
+           break;
+        }
+      default:
+         break;
+     }
+   return NULL;
+}
+
 
 /* vim:set ts=8 sw=3 sts=3 expandtab cino=>5n-2f0^-2{2(0W1st0 :*/
index 16ec4e5..f3bec78 100644 (file)
@@ -2,9 +2,11 @@
 #define _EVAS_CONVERT_COLORSPACE_H
 
 
-EAPI void *evas_common_convert_argb8888_to                         (void *data, int w, int h, int stride, Eina_Bool has_alpha, Evas_Colorspace cspace);
-EAPI void *evas_common_convert_rgb565_a5p_to                       (void *data, int w, int h, int stride, Eina_Bool has_alpha, Evas_Colorspace cspace);
-EAPI void *evas_common_convert_yuv_422P_601_to                     (void *data, int w, int h, Evas_Colorspace cspace);
-EAPI void *evas_common_convert_yuv_422_601_to                      (void *data, int w, int h, Evas_Colorspace cspace);
+EAPI void *evas_common_convert_argb8888_to    (void *data, int w, int h, int stride, Eina_Bool has_alpha, Evas_Colorspace cspace);
+EAPI void *evas_common_convert_rgb565_a5p_to  (void *data, int w, int h, int stride, Eina_Bool has_alpha, Evas_Colorspace cspace);
+EAPI void *evas_common_convert_yuv_422P_601_to(void *data, int w, int h, Evas_Colorspace cspace);
+EAPI void *evas_common_convert_yuv_422_601_to (void *data, int w, int h, Evas_Colorspace cspace);
+EAPI void *evas_common_convert_yuv_420_601_to (void *data, int w, int h, Evas_Colorspace cspace);
+EAPI void *evas_common_convert_yuv_420T_601_to(void *data, int w, int h, Evas_Colorspace cspace);
 
 #endif /* _EVAS_CONVERT_COLORSPACE_H */
index b832149..94b00ba 100644 (file)
@@ -26,6 +26,8 @@ static void _evas_yv12torgb_diz    (unsigned char **yuv, unsigned char *rgb, int
 #endif
 static void _evas_yv12torgb_raster (unsigned char **yuv, unsigned char *rgb, int w, int h);
 static void _evas_yuy2torgb_raster (unsigned char **yuv, unsigned char *rgb, int w, int h);
+static void _evas_nv12torgb_raster (unsigned char **yuv, unsigned char *rgb, int w, int h);
+static void _evas_nv12tiledtorgb_raster(unsigned char **yuv, unsigned char *rgb, int w, int h);
 
 #define CRV    104595
 #define CBU    132251
@@ -898,6 +900,26 @@ evas_common_convert_yuv_422_601_rgba(DATA8 **src, DATA8 *dst, int w, int h)
 #endif
 }
 
+void
+evas_common_convert_yuv_420_601_rgba(DATA8 **src, DATA8 *dst, int w, int h)
+{
+#ifdef BUILD_C
+   if (!initted) _evas_yuv_init();
+   initted = 1;
+   _evas_nv12torgb_raster(src, dst, w, h);
+#endif
+}
+
+void
+evas_common_convert_yuv_420T_601_rgba(DATA8 **src, DATA8 *dst, int w, int h)
+{
+#ifdef BUILD_C
+   if (initted) _evas_yuv_init();
+   initted = 1;
+   _evas_nv12tiledtorgb_raster(src, dst, w, h);
+#endif
+}
+
 static void
 _evas_yuy2torgb_raster(unsigned char **yuv, unsigned char *rgb, int w, int h)
 {
@@ -953,5 +975,204 @@ _evas_yuy2torgb_raster(unsigned char **yuv, unsigned char *rgb, int w, int h)
 #endif
 }
 
+#ifdef BUILD_C
+static inline void
+_evas_yuv2rgb_420_raster(unsigned char *yp1, unsigned char *yp2, unsigned char *up, unsigned char *vp,
+                         unsigned char *dp1, unsigned char *dp2)
+{
+   int y, u, v;
+   int vmu;
+
+   /* collect u & v for 4 pixels block */
+   u = *up;
+   v = *vp;
+
+   /* save lookups */
+   vmu = _v813[v] + _v391[u];
+   u = _v2018[u];
+   v = _v1596[v];
+
+   /* do the top 2 pixels of the 2x2 block which shared u & v */
+   /* yuv to rgb */
+   y = _v1164[*yp1];
+   *((DATA32 *) dp1) = 0xff000000 + RGB_JOIN(LUT_CLIP(y + v), LUT_CLIP(y - vmu), LUT_CLIP(y + u));
+
+   dp1 += 4; yp1++;
+
+   /* yuv to rgb */
+   y = _v1164[*yp1];
+   *((DATA32 *) dp1) = 0xff000000 + RGB_JOIN(LUT_CLIP(y + v), LUT_CLIP(y - vmu), LUT_CLIP(y + u));
+
+   /* do the bottom 2 pixels of the 2x2 block which shared u & v */
+   /* yuv to rgb */
+   y = _v1164[*yp2];
+   *((DATA32 *) dp2) = 0xff000000 + RGB_JOIN(LUT_CLIP(y + v), LUT_CLIP(y - vmu), LUT_CLIP(y + u));
+
+   dp2 += 4; yp2++;
+
+   /* yuv to rgb */
+   y = _v1164[*yp2];
+   *((DATA32 *) dp2) = 0xff000000 + RGB_JOIN(LUT_CLIP(y + v), LUT_CLIP(y - vmu), LUT_CLIP(y + u));
+}
+#endif
+
+static void
+_evas_nv12tiledtorgb_raster(unsigned char **yuv, unsigned char *rgb, int w, int h)
+{
+#ifdef BUILD_C
+
+#define HANDLE_MACROBLOCK(YP1, YP2, UP, VP, DP1, DP2)                   \
+   {                                                                    \
+     int i;                                                             \
+     int j;                                                             \
+                                                                        \
+     for (i = 0; i < 32; i += 2)                                        \
+       {                                                                \
+          for (j = 0; j < 64; j += 2)                                   \
+            {                                                           \
+               _evas_yuv2rgb_420_raster(YP1, YP2, UP, VP, DP1, DP2);    \
+                                                                        \
+               /* the previous call just rendered 2 pixels per lines */ \
+               DP1 += 8; DP2 += 8;                                      \
+                                                                        \
+               /* and took for that 2 lines with 2 Y, 1 U and 1 V. Don't forget U & V are in the same plane */ \
+               YP1 += 2; YP2 += 2; UP += 2; VP += 2;                    \
+            }                                                           \
+                                                                        \
+          DP1 += sizeof (int) * w;                                      \
+          DP2 += sizeof (int) * w;                                      \
+          YP1 += 64;                                                    \
+          YP2 += 64;                                                    \
+       }                                                                \
+   }
+
+   /* One macro block is 32 lines of Y and 16 lines of UV */
+   int mb_x, mb_y, mb_w, mb_h;
+
+   /* Idea iterate over each macroblock and convert each of them using _evas_nv12torgb_raster */
+
+   /* The layout of the macroblock order in RGB non tiled space : */
+   /* --------------------------------------------------- */
+   /* | 0  | 1  | 6  | 7  | 8  | 9  | 14 | 15 | 16 | 17 | */
+   /* --------------------------------------------------- */
+   /* | 2  | 3  | 4  | 5  | 10 | 11 | 12 | 13 | 18 | 19 | */
+   /* --------------------------------------------------- */
+   /* | 20 | 21 | 26 | 27 | 28 | 29 | 34 | 35 | 36 | 37 | */
+   /* --------------------------------------------------- */
+   /* | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 38 | 39 | */
+   /* --------------------------------------------------- */
+   /* | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | */
+   /* --------------------------------------------------- */
+
+   /* the number of macroblock should be a multiple of 64x32 */
+   mb_w = w / 64;
+   mb_h = h / 32;
+
+   /* In this format we linearize macroblock on two line to form a Z and it's invert */
+   for (mb_y = 0; mb_y < (mb_h / 2); ++mb_y)
+     {
+        int step = 1;
+        int offset = 0;
+        int x = 0;
+
+        for (mb_x = 0; mb_x < (mb_w * 2); ++mb_x)
+          {
+             unsigned char *yp1, *yp2, *up, *vp;
+             unsigned char *dp1, *dp2;
+
+             step++;
+
+             if (step % 4 == 0)
+               {
+                  x -= 2;
+                  offset = 1 - offset;
+               }
+             else
+               {
+                  x++;
+               }
+
+             /* Y mb addr = yuv[mb_y] + mb_x */
+             /* UV mb addr = yuv[mb_y + mb_h / 2] + mb_x / 2*/
+             /* visual addr = rgb + x * 64 + (mb_y + offset) * 2 * 32 * w */
+
+             dp1 = rgb + x * 64 + (mb_y + offset) * 2 * 32 * w;
+             dp2 = dp1 + sizeof (int) * w;
+
+             yp1 = yuv[mb_y] + mb_x * 64;
+             yp2 = yp1 + 64;
+
+             up = yuv[mb_y + mb_h / 2] + mb_x * 64; /* UV plane is two time less bigger in pixel count, but it old two bytes each times */
+             vp = up + 1;
+
+             HANDLE_MACROBLOCK(yp1, yp2, up, vp, dp1, dp2);
+          }
+     }
+
+   if (mb_h % 2)
+     {
+        mb_y++;
+        int x = 0;
+
+        for (mb_x = 0; mb_x < mb_w; ++mb_x, ++x)
+          {
+             unsigned char *yp1, *yp2, *up, *vp;
+             unsigned char *dp1, *dp2;
+
+             dp1 = rgb + x * 64 + mb_y * 2 * 32 *w;
+             dp2 = dp1 + sizeof (int) * w;
+
+             yp1 = yuv[mb_y] + mb_x * 64;
+             yp2 = yp1 + 64;
+
+             up = yuv[mb_y + mb_h / 2] + mb_x * 64;
+             vp = up + 1;
+
+             HANDLE_MACROBLOCK(yp1, yp2, up, vp, dp1, dp2);
+          }
+     }
+#endif
+}
+
+static void
+_evas_nv12torgb_raster(unsigned char **yuv, unsigned char *rgb, int w, int h)
+{
+#ifdef BUILD_C
+   int xx, yy;
+   unsigned char *yp1, *yp2, *up, *vp;
+   unsigned char *dp1;
+   unsigned char *dp2;
+
+   dp1 = rgb;
+   dp2 = dp1 + sizeof (int) * w;
+
+   for (yy = 0; yy < h; yy++)
+     {
+        yp1 = yuv[yy++];
+        yp2 = yuv[yy];
+
+        up = yuv[h + (yy >> 1)];
+        vp = up + 1;
+
+        for (xx = 0; xx < w; xx += 2)
+          {
+             _evas_yuv2rgb_420_raster(yp1, yp2, up, vp, dp1, dp2);
+
+             /* the previous call just rendered 2 pixels per lines */
+             dp1 += 8; dp2 += 8;
+
+             /* and took for that 2 lines with 2 Y, 1 U and 1 V. Don't forget U & V are in the same plane */
+             yp1 += 2; yp2 += 2; up += 2; vp += 2;
+          }
+
+        /* jump one line */
+        dp1 += sizeof (int) * w;
+        dp2 += sizeof (int) * w;
+        yp1 += w;
+        yp2 += w;
+     }
+#endif
+}
+
 #endif
 
index 12b4f78..b598807 100644 (file)
@@ -1,9 +1,9 @@
 #ifndef _EVAS_CONVERT_YUV_H
 #define _EVAS_CONVERT_YUV_H
 
-
-EAPI void evas_common_convert_yuv_420p_601_rgba                     (DATA8 **src, DATA8 *dst, int w, int h);
-EAPI void evas_common_convert_yuv_422_601_rgba(DATA8 **src, DATA8 *dst, int w, int h);
-
+EAPI void evas_common_convert_yuv_420p_601_rgba     (DATA8 **src, DATA8 *dst, int w, int h);
+EAPI void evas_common_convert_yuv_422_601_rgba      (DATA8 **src, DATA8 *dst, int w, int h);
+EAPI void evas_common_convert_yuv_420_601_rgba      (DATA8 **src, DATA8 *dst, int w, int h);
+EAPI void evas_common_convert_yuv_420T_601_rgba     (DATA8 **src, DATA8 *dst, int w, int h);
 
 #endif /* _EVAS_CONVERT_YUV_H */
index 122bd86..d4d847c 100644 (file)
@@ -610,6 +610,20 @@ evas_common_image_colorspace_normalize(RGBA_Image *im)
                                                im->cache_entry.w, im->cache_entry.h);
 #endif
         break;
+      case EVAS_COLORSPACE_YCBCR420NV12601_PL:
+#ifdef BUILD_CONVERT_YUV
+        if ((im->image.data) && (*((unsigned char **)im->cs.data)))
+          evas_common_convert_yuv_420_601_rgba(im->cs.data, (DATA8*) im->image.data,
+                                               im->cache_entry.w, im->cache_entry.h);
+#endif
+        break;
+      case EVAS_COLORSPACE_YCBCR420TM12601_PL:
+#ifdef BUILD_CONVERT_YUV
+        if ((im->image.data) && (*((unsigned char **)im->cs.data)))
+          evas_common_convert_yuv_420T_601_rgba(im->cs.data, (DATA8*) im->image.data,
+                                                im->cache_entry.w, im->cache_entry.h);
+#endif
+         break;
       default:
        break;
      }
index 64adfa5..9c7d5b3 100644 (file)
@@ -130,6 +130,8 @@ typedef enum {
   SHADER_YUV_NOMUL,
   SHADER_YUY2,
   SHADER_YUY2_NOMUL,
+  SHADER_NV12,
+  SHADER_NV12_NOMUL,
   SHADER_TEX,
   SHADER_TEX_NOMUL,
   SHADER_FILTER_INVERT,
@@ -525,6 +527,12 @@ void             evas_gl_common_context_yuy2_push(Evas_Engine_GL_Context *gc,
                                                  int x, int y, int w, int h,
                                                  int r, int g, int b, int a,
                                                  Eina_Bool smooth);
+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);
 void             evas_gl_common_context_image_map_push(Evas_Engine_GL_Context *gc,
                                                        Evas_GL_Texture *tex,
                                                        int npoints,
@@ -533,8 +541,7 @@ void             evas_gl_common_context_image_map_push(Evas_Engine_GL_Context *g
                                                        int r, int g, int b, int a,
                                                        Eina_Bool smooth,
                                                        Eina_Bool tex_only,
-                                                       Eina_Bool yuv,
-                                                      Eina_Bool yuy2);
+                                                      Evas_Colorspace cspace);
 void              evas_gl_common_context_flush(Evas_Engine_GL_Context *gc);
 
 int               evas_gl_common_shader_program_init(Evas_GL_Shared *shared);
@@ -556,6 +563,10 @@ Evas_GL_Texture  *evas_gl_common_texture_yuv_new(Evas_Engine_GL_Context *gc, DAT
 void              evas_gl_common_texture_yuv_update(Evas_GL_Texture *tex, DATA8 **rows, unsigned int w, unsigned int h);
 Evas_GL_Texture  *evas_gl_common_texture_yuy2_new(Evas_Engine_GL_Context *gc, DATA8 **rows, unsigned int w, unsigned int h);
 void              evas_gl_common_texture_yuy2_update(Evas_GL_Texture *tex, DATA8 **rows, unsigned int w, unsigned int h);
+Evas_GL_Texture  *evas_gl_common_texture_nv12_new(Evas_Engine_GL_Context *gc, DATA8 **rows, unsigned int w, unsigned int h);
+void              evas_gl_common_texture_nv12_update(Evas_GL_Texture *tex, DATA8 **row, unsigned int w, unsigned int h);
+Evas_GL_Texture  *evas_gl_common_texture_nv12tiled_new(Evas_Engine_GL_Context *gc, DATA8 **rows, unsigned int w, unsigned int h);
+void              evas_gl_common_texture_nv12tiled_update(Evas_GL_Texture *tex, DATA8 **row, unsigned int w, unsigned int h);
 
 void              evas_gl_common_image_all_unload(Evas_Engine_GL_Context *gc);
 
index 4bba403..31bcc97 100644 (file)
@@ -687,6 +687,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,6 +697,9 @@ 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);
 
@@ -1084,6 +1090,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,
+                            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,
@@ -1408,34 +1432,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_NOMUL, SHADER_IMG)].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 +1558,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 +1749,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 +1852,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,
@@ -2049,9 +1942,8 @@ evas_gl_common_context_image_map_push(Evas_Engine_GL_Context *gc,
                                       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 +1952,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,94 +1978,56 @@ 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_NOMUL, SHADER_IMG)].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);
@@ -2188,11 +2044,16 @@ evas_gl_common_context_image_map_push(Evas_Engine_GL_Context *gc,
         py = (p[points[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;
@@ -2230,12 +2091,12 @@ evas_gl_common_context_image_map_push(Evas_Engine_GL_Context *gc,
 
    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_texv = tex->ptv->texture;
      }
-   else if (yuy2)
+   else if (uvtexture)
      {
        gc->pipe[pn].shader.cur_texu = tex->ptuv->texture;
      }
@@ -2252,8 +2113,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 +2129,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 +2156,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 +2165,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]],
index a7b5b6b..1c3d64c 100644 (file)
@@ -578,6 +578,40 @@ evas_gl_common_image_update(Evas_Engine_GL_Context *gc, Evas_GL_Image *im)
           }
         if (!im->tex) return;
         break;
+      case EVAS_COLORSPACE_YCBCR420NV12601_PL:
+        if ((im->tex) && (im->dirty))
+          {
+             evas_gl_common_texture_nv12_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_nv12_new(gc, im->cs.data,
+                                                       im->im->cache_entry.w,
+                                                       im->im->cache_entry.h);
+             im->dirty = 0;
+          }
+        if (!im->tex) return;
+        break;
+      case EVAS_COLORSPACE_YCBCR420TM12601_PL:
+        if ((im->tex) && (im->dirty))
+          {
+             evas_gl_common_texture_nv12tiled_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_nv12tiled_new(gc, im->cs.data,
+                                                            im->im->cache_entry.w,
+                                                            im->im->cache_entry.h);
+             im->dirty = 0;
+          }
+        if (!im->tex) return;
+        break;
       default:
         ERR("unhandled img format colorspace=%d", im->cs.space);
         break;
@@ -613,15 +647,11 @@ evas_gl_common_image_map_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im,
    cx = gc->dc->clip.x; cy = gc->dc->clip.y;
    cw = gc->dc->clip.w; ch = gc->dc->clip.h;
    im->tex->im = im;
-   if ((im->cs.space == EVAS_COLORSPACE_YCBCR422P601_PL) ||
-       (im->cs.space == EVAS_COLORSPACE_YCBCR422P709_PL))
-      yuv = 1;
-   if (im->cs.space == EVAS_COLORSPACE_YCBCR422601_PL)
-      yuy2 = 1;
+
    evas_gl_common_context_image_map_push(gc, im->tex, npoints, p,
                                          c, cx, cy, cw, ch,
                                          r, g, b, a, smooth, im->tex_only,
-                                         yuv, yuy2);
+                                         im->cs.space);
 }
 
 void
index 239f209..5f05c00 100644 (file)
@@ -202,6 +202,45 @@ Evas_GL_Program_Source shader_yuy2_nomul_vert_src =
 
 /////////////////////////////////////////////
 #if defined (GLES_VARIETY_S3C6410)
+const unsigned int nv12_nomul_vert_bin[] =
+{
+# include "shader/nv12_nomul_vert_bin_s3c6410.h"
+};
+#endif
+const char nv12_nomul_vert_glsl[] =
+#include "shader/nv12_nomul_vert.h"
+  ;
+Evas_GL_Program_Source shader_nv12_nomul_vert_src =
+{
+   nv12_nomul_vert_glsl,
+#if defined (GLES_VARIETY_S3C6410)
+     nv12_nomul_vert_bin, sizeof(nv12_nomul_vert_bin)
+#else
+     NULL, 0
+#endif
+};
+
+#if defined (GLES_VARIETY_S3C6410)
+const unsigned int nv12_vert_bin[] =
+{
+# include "shader/nv12_vert_bin_s3c6410.h"
+};
+#endif
+const char nv12_vert_glsl[] =
+#include "shader/nv12_vert.h"
+  ;
+Evas_GL_Program_Source shader_nv12_vert_src =
+{
+   nv12_vert_glsl,
+#if defined (GLES_VARIETY_S3C6410)
+     nv12_vert_bin, sizeof(nv12_vert_bin)
+#else
+     NULL, 0
+#endif
+};
+
+/////////////////////////////////////////////
+#if defined (GLES_VARIETY_S3C6410)
 const unsigned int yuv_nomul_frag_bin[] =
 {
 # include "shader/yuv_nomul_frag_bin_s3c6410.h"
@@ -1029,6 +1068,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(TEX, tex),
   SHADER_SOURCE_LINE(TEX_NOMUL, tex_nomul),
    /* Most of the filters use the image fragment shader */
index e92b141..95c720e 100644 (file)
@@ -1067,8 +1067,10 @@ evas_gl_common_texture_yuv_update(Evas_GL_Texture *tex, DATA8 **rows, unsigned i
      }
 }
 
-Evas_GL_Texture *
-evas_gl_common_texture_yuy2_new(Evas_Engine_GL_Context *gc, DATA8 **rows, unsigned int w, unsigned int h)
+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)
 {
    Evas_GL_Texture *tex;
 
@@ -1077,7 +1079,7 @@ evas_gl_common_texture_yuy2_new(Evas_Engine_GL_Context *gc, DATA8 **rows, unsign
 
    tex->gc = gc;
    tex->references = 1;
-   tex->pt = _pool_tex_new(gc, w + 1, h  + 1, lum_alpha_ifmt, lum_alpha_fmt);
+   tex->pt = _pool_tex_new(gc, yw + 1, yh  + 1, lum_alpha_ifmt, lum_alpha_fmt);
    if (!tex->pt)
      {
         free(tex);
@@ -1087,7 +1089,7 @@ evas_gl_common_texture_yuy2_new(Evas_Engine_GL_Context *gc, DATA8 **rows, unsign
    tex->pt->slot = -1;
    tex->pt->fslot = -1;
    tex->pt->whole = 1;
-   tex->ptuv = _pool_tex_new(gc, (w / 2) + 1, h  + 1, rgba8_ifmt, rgba8_fmt);
+   tex->ptuv = _pool_tex_new(gc, uvw + 1, uvh  + 1, rgba8_ifmt, rgba8_fmt);
    if (!tex->ptuv)
      {
         pt_unref(tex->pt);
@@ -1100,22 +1102,86 @@ evas_gl_common_texture_yuy2_new(Evas_Engine_GL_Context *gc, DATA8 **rows, unsign
    tex->ptuv->whole = 1;
    tex->x = 0;
    tex->y = 0;
-   tex->w = w;
-   tex->h = h;
+   tex->w = yw;
+   tex->h = yh;
    tex->pt->allocations = eina_list_prepend(tex->pt->allocations, tex);
    tex->ptuv->allocations = eina_list_prepend(tex->ptuv->allocations, tex);
    tex->pt->references++;
    tex->ptuv->references++;
+   return tex;
+}
+
+Evas_GL_Texture *
+evas_gl_common_texture_yuy2_new(Evas_Engine_GL_Context *gc, DATA8 **rows, unsigned int w, unsigned int h)
+{
+   Evas_GL_Texture *tex;
+
+   tex = _evas_gl_common_texture_y2uv_new(gc, w, h, w / 2, h);
    evas_gl_common_texture_yuy2_update(tex, rows, w, h);
    return tex;
 }
 
+Evas_GL_Texture *
+evas_gl_common_texture_nv12_new(Evas_Engine_GL_Context *gc, DATA8 **rows, unsigned int w, unsigned int h)
+{
+   Evas_GL_Texture *tex;
+
+   tex = _evas_gl_common_texture_y2uv_new(gc, w, h, w / 2, h / 2);
+   evas_gl_common_texture_nv12_update(tex, rows, w, h);
+   return tex;
+}
+
+Evas_GL_Texture *
+evas_gl_common_texture_nv12tiled_new(Evas_Engine_GL_Context *gc, DATA8 **rows, unsigned int w, unsigned int h)
+{
+   Evas_GL_Texture *tex;
+
+   tex = _evas_gl_common_texture_y2uv_new(gc, w, h, w / 2, h / 2);
+   evas_gl_common_texture_nv12tiled_update(tex, rows, w, h);
+   return tex;
+}
+
 void
 evas_gl_common_texture_yuy2_update(Evas_GL_Texture *tex, DATA8 **rows, unsigned int w, unsigned int h)
 {
    if (!tex->pt) return;
    // FIXME: works on lowest size 4 pixel high buffers. must also be multiple of 2
-#undef GL_UNPACK_ROW_LENGTH
+   unsigned int y;
+
+   glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   glBindTexture(GL_TEXTURE_2D, tex->pt->texture);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   if ((rows[1] - rows[0]) == (int)w * 4)
+     _tex_sub_2d(0, 0, w, h, tex->pt->format, tex->pt->dataformat, rows[0]);
+   else
+     {
+        for (y = 0; y < h; y++)
+          _tex_sub_2d(0, y, w, 1, tex->pt->format, tex->pt->dataformat, rows[y]);
+     }
+
+   glBindTexture(GL_TEXTURE_2D, tex->ptuv->texture);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   if ((rows[1] - rows[0]) == (int)(w * 2))
+     _tex_sub_2d(0, 0, w / 2, h, tex->ptuv->format, tex->ptuv->dataformat, rows[0]);
+   else
+     {
+        for (y = 0; y < h; y++)
+          _tex_sub_2d(0, y, w / 2, 1, tex->ptuv->format, tex->ptuv->dataformat, rows[y]);
+     }
+
+   if (tex->pt->texture != tex->gc->pipe[0].shader.cur_tex)
+     {
+        glBindTexture(GL_TEXTURE_2D, tex->gc->pipe[0].shader.cur_tex);
+        GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+     }
+}
+
+void
+evas_gl_common_texture_nv12_update(Evas_GL_Texture *tex, DATA8 **rows, unsigned int w, unsigned int h)
+{
+   if (!tex->pt) return;
+   // FIXME: works on lowest size 4 pixel high buffers. must also be multiple of 2
 #ifdef GL_UNPACK_ROW_LENGTH
    glPixelStorei(GL_UNPACK_ROW_LENGTH, rows[1] - rows[0]);
    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
@@ -1123,14 +1189,12 @@ evas_gl_common_texture_yuy2_update(Evas_GL_Texture *tex, DATA8 **rows, unsigned
    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
    glBindTexture(GL_TEXTURE_2D, tex->pt->texture);
    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-   fprintf(stderr, "rows: %p\n", rows[0]);
-   fprintf(stderr, "rows end: %p\n", rows[h - 1] + (rows[1] - rows[0]));
    _tex_sub_2d(0, 0, w, h, tex->pt->format, tex->pt->dataformat, rows[0]);
    glBindTexture(GL_TEXTURE_2D, tex->ptuv->texture);
    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-   glPixelStorei(GL_UNPACK_ROW_LENGTH, rows[1] - rows[0]);
+   glPixelStorei(GL_UNPACK_ROW_LENGTH, rows[h + 1] - rows[h]);
    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-   _tex_sub_2d(0, 0, w / 2, h, tex->ptuv->format, tex->ptuv->dataformat, rows[0]);
+   _tex_sub_2d(0, 0, w / 2, h / 2, tex->ptuv->format, tex->ptuv->dataformat, rows[h]);
 #else
    unsigned int y;
 
@@ -1138,7 +1202,7 @@ evas_gl_common_texture_yuy2_update(Evas_GL_Texture *tex, DATA8 **rows, unsigned
    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
    glBindTexture(GL_TEXTURE_2D, tex->pt->texture);
    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-   if ((rows[1] - rows[0]) == (int)w * 4)
+   if ((rows[1] - rows[0]) == (int)w)
      _tex_sub_2d(0, 0, w, h, tex->pt->format, tex->pt->dataformat, rows[0]);
    else
      {
@@ -1148,14 +1212,13 @@ evas_gl_common_texture_yuy2_update(Evas_GL_Texture *tex, DATA8 **rows, unsigned
 
    glBindTexture(GL_TEXTURE_2D, tex->ptuv->texture);
    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-   if ((rows[1] - rows[0]) == (int)(w * 2))
-     _tex_sub_2d(0, 0, w / 2, h, tex->ptuv->format, tex->ptuv->dataformat, rows[0]);
+   if ((rows[h + 1] - rows[h]) == (int)(w / 2))
+     _tex_sub_2d(0, 0, w / 2, h / 2, tex->ptuv->format, tex->ptuv->dataformat, rows[h]);
    else
      {
-        for (y = 0; y < h; y++)
-          _tex_sub_2d(0, y, w / 2, 1, tex->ptuv->format, tex->ptuv->dataformat, rows[y]);
+        for (y = 0; y < (h / 2); y++)
+          _tex_sub_2d(0, y, w / 2, 1, tex->ptuv->format, tex->ptuv->dataformat, rows[h + y]);
      }
-
 #endif
    if (tex->pt->texture != tex->gc->pipe[0].shader.cur_tex)
      {
@@ -1163,3 +1226,11 @@ evas_gl_common_texture_yuy2_update(Evas_GL_Texture *tex, DATA8 **rows, unsigned
         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
      }
 }
+
+void
+evas_gl_common_texture_nv12tiled_update(Evas_GL_Texture *tex, DATA8 **rows, unsigned int w, unsigned int h)
+{
+   if (!tex->pt) return;
+   // FIXME: not done yet
+   abort();
+}
diff --git a/src/modules/engines/gl_common/shader/nv12_nomul_vert.h b/src/modules/engines/gl_common/shader/nv12_nomul_vert.h
new file mode 100644 (file)
index 0000000..3227065
--- /dev/null
@@ -0,0 +1,14 @@
+"#ifdef GL_ES\n"
+"precision mediump float;\n"
+"#endif\n"
+"attribute vec4 vertex;\n"
+"attribute vec4 color;\n"
+"attribute vec2 tex_coord, tex_coord2;\n"
+"uniform mat4 mvp;\n"
+"varying vec2 tex_c, tex_cuv;\n"
+"void main()\n"
+"{\n"
+"   gl_Position = mvp * vertex;\n"
+"   tex_c = tex_coord;\n"
+"   tex_cuv = tex_coord2;\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/nv12_nomul_vert.shd b/src/modules/engines/gl_common/shader/nv12_nomul_vert.shd
new file mode 100644 (file)
index 0000000..e2412ad
--- /dev/null
@@ -0,0 +1,14 @@
+#ifdef GL_ES
+precision mediump float;
+#endif
+attribute vec4 vertex;
+attribute vec4 color;
+attribute vec2 tex_coord, tex_coord2;
+uniform mat4 mvp;
+varying vec2 tex_y, tex_cuv;
+void main()
+{
+   gl_Position = mvp * vertex;
+   tex_y = tex_coord;
+   tex_cuv = tex_coord2;
+}
diff --git a/src/modules/engines/gl_common/shader/nv12_vert.h b/src/modules/engines/gl_common/shader/nv12_vert.h
new file mode 100644 (file)
index 0000000..0cb908e
--- /dev/null
@@ -0,0 +1,16 @@
+"#ifdef GL_ES\n"
+"precision mediump float;\n"
+"#endif\n"
+"attribute vec4 vertex;\n"
+"attribute vec4 color;\n"
+"attribute vec2 tex_coord, tex_coord2;\n"
+"uniform mat4 mvp;\n"
+"varying vec4 col;\n"
+"varying vec2 tex_c, tex_cuv;\n"
+"void main()\n"
+"{\n"
+"   gl_Position = mvp * vertex;\n"
+"   col = color;\n"
+"   tex_c = tex_coord;\n"
+"   tex_cuv = tex_coord2;\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/nv12_vert.shd b/src/modules/engines/gl_common/shader/nv12_vert.shd
new file mode 100644 (file)
index 0000000..76eb533
--- /dev/null
@@ -0,0 +1,16 @@
+#ifdef GL_ES
+precision mediump float;
+#endif
+attribute vec4 vertex;
+attribute vec4 color;
+attribute vec2 tex_coord, tex_coord2;
+uniform mat4 mvp;
+varying vec4 col;
+varying vec2 tex_y, tex_cuv;
+void main()
+{
+   gl_Position = mvp * vertex;
+   col = color;
+   tex_y = tex_coord;
+   tex_cuv = tex_coord2;
+}
diff --git a/src/modules/engines/gl_common/shader/yuy2_frag.shd b/src/modules/engines/gl_common/shader/yuy2_frag.shd
new file mode 100644 (file)
index 0000000..64cd911
--- /dev/null
@@ -0,0 +1,26 @@
+#ifdef GL_ES
+precision mediump float;
+#endif
+uniform sampler2D tex, texuv;
+varying vec4 col;
+varying vec2 tex_c, tex_cuv;
+void main()
+{
+  float y,u,v,vmu,r,g,b;
+  y=texture2D(tex,tex_c).r;
+  u=texture2D(texuv,tex_cuv).g;
+  v=texture2D(texuv,tex_cuv).a;
+
+  u=u-0.5;
+  v=v-0.5;
+  vmu=v*0.813+u*0.391;
+  u=u*2.018;
+  v=v*1.596;
+
+  r=y+v;
+  g=y-vmu;
+  b=y+u;
+
+  gl_FragColor=vec4(r,g,b,1.0) * col;
+}
+
diff --git a/src/modules/engines/gl_common/shader/yuy2_nomul_frag.shd b/src/modules/engines/gl_common/shader/yuy2_nomul_frag.shd
new file mode 100644 (file)
index 0000000..2a8d2ed
--- /dev/null
@@ -0,0 +1,26 @@
+#ifdef GL_ES
+precision mediump float;
+#endif
+uniform sampler2D tex, texuv;
+varying vec2 tex_c, tex_cuv;
+void main()
+{
+  float y,u,v,vmu,r,g,b;
+  y=texture2D(tex,tex_c).r;
+  u=texture2D(texuv,tex_cuv).g;
+  v=texture2D(texuv,tex_cuv).a;
+
+  u=u-0.5;
+  v=v-0.5;
+  vmu=v*0.813+u*0.391;
+  u=u*2.018;
+  v=v*1.596;
+  y=(y-0.062)*1.164;
+
+  r=y+v;
+  g=y-vmu;
+  b=y+u;
+
+  gl_FragColor=vec4(r,g,b,1.0);
+}
+
diff --git a/src/modules/engines/gl_common/shader/yuy2_nomul_vert.shd b/src/modules/engines/gl_common/shader/yuy2_nomul_vert.shd
new file mode 100644 (file)
index 0000000..ee3fd89
--- /dev/null
@@ -0,0 +1,13 @@
+#ifdef GL_ES
+precision mediump float;
+#endif
+attribute vec4 vertex;
+attribute vec2 tex_coord, tex_coord2;
+uniform mat4 mvp;
+varying vec2 tex_c, tex_cuv;
+void main()
+{
+   gl_Position = mvp * vertex;
+   tex_c = tex_coord;
+   tex_cuv = vec2(tex_coord2.x * 0.5, tex_coord2.y);
+}
diff --git a/src/modules/engines/gl_common/shader/yuy2_vert.shd b/src/modules/engines/gl_common/shader/yuy2_vert.shd
new file mode 100644 (file)
index 0000000..879e15c
--- /dev/null
@@ -0,0 +1,16 @@
+#ifdef GL_ES
+precision mediump float;
+#endif
+attribute vec4 vertex;
+attribute vec4 color;
+attribute vec2 tex_coord, tex_coord2;
+uniform mat4 mvp;
+varying vec4 col;
+varying vec2 tex_c, tex_cuv;
+void main()
+{
+   gl_Position = mvp * vertex;
+   col = color;
+   tex_c = tex_coord;
+   tex_cuv = vec2(tex_coord2.x * 0.5, tex_coord2.y);
+}
index 3134270..332438a 100644 (file)
@@ -468,6 +468,8 @@ eng_image_colorspace_set(void *data, void *image, int cspace)
       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;
        if (im->cs.data)
@@ -599,10 +601,18 @@ eng_image_size_set(void *data, void *image, int w, int h)
         return image;
      }
    im_old = image;
-   if ((eng_image_colorspace_get(data, image) == EVAS_COLORSPACE_YCBCR422P601_PL) ||
-       (eng_image_colorspace_get(data, image) == EVAS_COLORSPACE_YCBCR422P709_PL) ||
-       (eng_image_colorspace_get(data, image) == EVAS_COLORSPACE_YCBCR422601_PL))
-     w &= ~0x1;
+
+   switch (eng_image_colorspace_get(data, image))
+     {
+      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:
+         w &= ~0x1;
+         break;
+     }
+
    if ((im_old) && (im_old->im->cache_entry.w == w) && (im_old->im->cache_entry.h == h))
      return image;
    if (im_old)
@@ -689,6 +699,8 @@ eng_image_data_get(void *data, void *image, int to_write, DATA32 **image_data, i
       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:
        *image_data = im->cs.data;
        break;
       default:
@@ -729,6 +741,8 @@ eng_image_data_put(void *data, void *image, DATA32 *image_data)
       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 (image_data != im->cs.data)
          {
             if (im->cs.data)
index d440c23..16a7643 100644 (file)
@@ -1065,6 +1065,8 @@ eng_image_colorspace_set(void *data, void *image, int cspace)
       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;
        if (im->cs.data)
@@ -1708,10 +1710,18 @@ eng_image_size_set(void *data, void *image, int w, int h)
         return image;
      }
    im_old = image;
-   if ((eng_image_colorspace_get(data, image) == EVAS_COLORSPACE_YCBCR422P601_PL) ||
-       (eng_image_colorspace_get(data, image) == EVAS_COLORSPACE_YCBCR422P709_PL) ||
-       (eng_image_colorspace_get(data, image) == EVAS_COLORSPACE_YCBCR422601_PL))
-     w &= ~0x1;
+
+   switch (eng_image_colorspace_get(data, image))
+     {
+      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:
+         w &= ~0x1;
+         break;
+     }
+
    if ((im_old) &&
        ((int)im_old->im->cache_entry.w == w) &&
        ((int)im_old->im->cache_entry.h == h))
@@ -1842,6 +1852,8 @@ eng_image_data_get(void *data, void *image, int to_write, DATA32 **image_data, i
       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:
        *image_data = im->cs.data;
        break;
       default:
@@ -1908,6 +1920,8 @@ eng_image_data_put(void *data, void *image, DATA32 *image_data)
       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 (image_data != im->cs.data)
          {
             if (im->cs.data)
index 9663665..ceed58a 100644 (file)
@@ -434,6 +434,8 @@ eng_image_data_get(void *data __UNUSED__, void *image, int to_write, DATA32 **im
       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:
        *image_data = im->cs.data;
         break;
       default:
@@ -470,6 +472,8 @@ eng_image_data_put(void *data, void *image, DATA32 *image_data)
       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 (image_data != im->cs.data)
          {
             if (im->cs.data)