evas: add NV12 and MT12 colorspace.

MT12 is has documented in Linux videodev documentation
a 64 * 32 macro block tiled colorspace format used on
Samsung hardware.


SVN revision: 62967
This commit is contained in:
Cedric BAIL 2011-08-29 20:56:48 +00:00
parent 93ded6d380
commit 26ee52dd61
24 changed files with 793 additions and 308 deletions

View File

@ -470,3 +470,8 @@
* Fix evas_object_image_data_convert. * Fix evas_object_image_data_convert.
* Add YUV 601 input format to 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).

View 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_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_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_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 */ } Evas_Colorspace; /**< Colorspaces for pixel data supported by Evas */
/** /**

View File

@ -3644,6 +3644,18 @@ evas_object_image_data_convert_internal(Evas_Object_Image *o, void *data, Evas_C
o->cur.image.h, o->cur.image.h,
to_cspace); to_cspace);
break; 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: default:
fprintf(stderr, "unknow colorspace: %i\n", o->cur.cspace); fprintf(stderr, "unknow colorspace: %i\n", o->cur.cspace);
break; break;

View File

@ -140,5 +140,47 @@ evas_common_convert_yuv_422P_601_to(void *data, int w, int h, Evas_Colorspace cs
return NULL; 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 :*/ /* vim:set ts=8 sw=3 sts=3 expandtab cino=>5n-2f0^-2{2(0W1st0 :*/

View File

@ -2,9 +2,11 @@
#define _EVAS_CONVERT_COLORSPACE_H #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_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_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_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_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 */ #endif /* _EVAS_CONVERT_COLORSPACE_H */

View File

@ -26,6 +26,8 @@ static void _evas_yv12torgb_diz (unsigned char **yuv, unsigned char *rgb, int
#endif #endif
static void _evas_yv12torgb_raster (unsigned char **yuv, unsigned char *rgb, int w, int h); 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_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 CRV 104595
#define CBU 132251 #define CBU 132251
@ -898,6 +900,26 @@ evas_common_convert_yuv_422_601_rgba(DATA8 **src, DATA8 *dst, int w, int h)
#endif #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 static void
_evas_yuy2torgb_raster(unsigned char **yuv, unsigned char *rgb, int w, int h) _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 #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 #endif

View File

@ -1,9 +1,9 @@
#ifndef _EVAS_CONVERT_YUV_H #ifndef _EVAS_CONVERT_YUV_H
#define _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_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_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 */ #endif /* _EVAS_CONVERT_YUV_H */

View File

@ -610,6 +610,20 @@ evas_common_image_colorspace_normalize(RGBA_Image *im)
im->cache_entry.w, im->cache_entry.h); im->cache_entry.w, im->cache_entry.h);
#endif #endif
break; 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: default:
break; break;
} }

View File

@ -130,6 +130,8 @@ typedef enum {
SHADER_YUV_NOMUL, SHADER_YUV_NOMUL,
SHADER_YUY2, SHADER_YUY2,
SHADER_YUY2_NOMUL, SHADER_YUY2_NOMUL,
SHADER_NV12,
SHADER_NV12_NOMUL,
SHADER_TEX, SHADER_TEX,
SHADER_TEX_NOMUL, SHADER_TEX_NOMUL,
SHADER_FILTER_INVERT, 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 x, int y, int w, int h,
int r, int g, int b, int a, int r, int g, int b, int a,
Eina_Bool smooth); 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, void evas_gl_common_context_image_map_push(Evas_Engine_GL_Context *gc,
Evas_GL_Texture *tex, Evas_GL_Texture *tex,
int npoints, 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, int r, int g, int b, int a,
Eina_Bool smooth, Eina_Bool smooth,
Eina_Bool tex_only, Eina_Bool tex_only,
Eina_Bool yuv, Evas_Colorspace cspace);
Eina_Bool yuy2);
void evas_gl_common_context_flush(Evas_Engine_GL_Context *gc); void evas_gl_common_context_flush(Evas_Engine_GL_Context *gc);
int evas_gl_common_shader_program_init(Evas_GL_Shared *shared); 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); 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); 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); 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); void evas_gl_common_image_all_unload(Evas_Engine_GL_Context *gc);

View File

@ -687,6 +687,9 @@ evas_gl_common_context_new(void)
SHADER_TEXTURE_ADD(shared, YUY2, tex); SHADER_TEXTURE_ADD(shared, YUY2, tex);
SHADER_TEXTURE_ADD(shared, YUY2, texuv); 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, tex);
SHADER_TEXTURE_ADD(shared, YUV_NOMUL, texu); SHADER_TEXTURE_ADD(shared, YUV_NOMUL, texu);
SHADER_TEXTURE_ADD(shared, YUV_NOMUL, texv); 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, tex);
SHADER_TEXTURE_ADD(shared, YUY2_NOMUL, texuv); 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, tex);
SHADER_TEXTURE_ADD(shared, IMG_MASK, texm); 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; 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 static int
_evas_gl_common_context_push(int rtype, _evas_gl_common_context_push(int rtype,
Evas_Engine_GL_Context *gc, 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 (tex->pt->dyn.img)
{ {
if ((a == 255) && (r == 255) && (g == 255) && (b == 255)) prog = gc->shared->shader[evas_gl_common_shader_choice(0, NULL, r, g, b, a,
prog = gc->shared->shader[SHADER_IMG_NOMUL].prog; SHADER_IMG_NOMUL, SHADER_IMG)].prog;
else
prog = gc->shared->shader[SHADER_IMG].prog;
} }
else else
{ {
if ((a == 255) && (r == 255) && (g == 255) && (b == 255)) prog = gc->shared->shader[evas_gl_common_shader_choice(0, NULL, r, g, b, a,
prog = gc->shared->shader[SHADER_TEX_NOMUL].prog; SHADER_TEX_NOMUL, SHADER_TEX)].prog;
else
prog = gc->shared->shader[SHADER_TEX].prog;
} }
} }
else else
{ {
if (tex->gc->shared->info.bgra) if (tex->gc->shared->info.bgra)
{ {
if ((a == 255) && (r == 255) && (g == 255) && (b == 255)) prog = gc->shared->shader[evas_gl_common_shader_choice(0, NULL, r, g, b, a,
prog = gc->shared->shader[SHADER_IMG_BGRA_NOMUL].prog; SHADER_IMG_BGRA_NOMUL, SHADER_IMG_BGRA)].prog;
else
prog = gc->shared->shader[SHADER_IMG_BGRA].prog;
} }
else else
{ {
if ((a == 255) && (r == 255) && (g == 255) && (b == 255)) prog = gc->shared->shader[evas_gl_common_shader_choice(0, NULL, r, g, b, a,
prog = gc->shared->shader[SHADER_IMG_NOMUL].prog; SHADER_IMG_NOMUL, SHADER_IMG)].prog;
else
prog = gc->shared->shader[SHADER_IMG].prog;
} }
} }
@ -1542,153 +1558,34 @@ evas_gl_common_context_image_mask_push(Evas_Engine_GL_Context *gc,
} }
#endif #endif
again: pn = _evas_gl_common_context_push(RTYPE_IMASK,
vertex_array_size_check(gc, gc->state.top_pipe, 6); gc, tex, texm,
pn = gc->state.top_pipe; prog,
#ifdef GLPIPES x, y, w, h,
if ((pn == 0) && (gc->pipe[pn].array.num == 0)) blend,
{ smooth,
gc->pipe[pn].region.type = RTYPE_IMASK; 0, 0, 0, 0, 0);
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;
}
}
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.line = 0;
gc->pipe[pn].array.use_vertex = 1; gc->pipe[pn].array.use_vertex = 1;
// if nomul... dont need this
gc->pipe[pn].array.use_color = 1; gc->pipe[pn].array.use_color = 1;
gc->pipe[pn].array.use_texuv = 1; gc->pipe[pn].array.use_texuv = 1;
gc->pipe[pn].array.use_texuv2 = 0; gc->pipe[pn].array.use_texuv2 = 0;
gc->pipe[pn].array.use_texuv3 = 0; gc->pipe[pn].array.use_texuv3 = 0;
gc->pipe[pn].array.use_texm = 1; gc->pipe[pn].array.use_texm = 1;
#endif
pipe_region_expand(gc, pn, x, y, w, h); 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; int pnum, nv, nc, nu, nu2, nu3, nt, i;
GLfloat tx1, tx2, ty1, ty2, t2x1, t2x2, t2y1, t2y2; GLfloat tx1, tx2, ty1, ty2, t2x1, t2x2, t2y1, t2y2;
Eina_Bool blend = 0; Eina_Bool blend = 0;
GLuint prog = gc->shared->shader[SHADER_YUV].prog; GLuint prog;
int pn = 0; int pn = 0;
if (a < 255) blend = 1; if (a < 255) blend = 1;
if ((a == 255) && (r == 255) && (g == 255) && (b == 255)) prog = gc->shared->shader[evas_gl_common_shader_choice(0, NULL, r, g, b, a,
prog = gc->shared->shader[SHADER_YUV_NOMUL].prog; SHADER_YUV_NOMUL, SHADER_YUV)].prog;
else
prog = gc->shared->shader[SHADER_YUV].prog;
pn = _evas_gl_common_context_push(RTYPE_YUV, pn = _evas_gl_common_context_push(RTYPE_YUV,
gc, tex, NULL, 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; int pnum, nv, nc, nu, nu2, nu3, nt, i;
GLfloat tx1, tx2, ty1, ty2, t2x1, t2x2, t2y1, t2y2; GLfloat tx1, tx2, ty1, ty2, t2x1, t2x2, t2y1, t2y2;
Eina_Bool blend = 0; Eina_Bool blend = 0;
GLuint prog = gc->shared->shader[SHADER_YUY2].prog; GLuint prog;
int pn = 0; int pn = 0;
if (a < 255) blend = 1; if (a < 255) blend = 1;
if ((a == 255) && (r == 255) && (g == 255) && (b == 255)) prog = gc->shared->shader[evas_gl_common_shader_choice(0, NULL, r, g, b, a,
prog = gc->shared->shader[SHADER_YUY2_NOMUL].prog; SHADER_YUY2_NOMUL, SHADER_YUY2)].prog;
else
prog = gc->shared->shader[SHADER_YUY2].prog;
pn = _evas_gl_common_context_push(RTYPE_YUY2, pn = _evas_gl_common_context_push(RTYPE_YUY2,
gc, tex, NULL, gc, tex, NULL,
@ -2049,9 +1942,8 @@ evas_gl_common_context_image_map_push(Evas_Engine_GL_Context *gc,
RGBA_Map_Point *p, RGBA_Map_Point *p,
int clip, int cx, int cy, int cw, int ch, int clip, int cx, int cy, int cw, int ch,
int r, int g, int b, int a, int r, int g, int b, int a,
Eina_Bool smooth, Eina_Bool tex_only, Eina_Bool smooth, Eina_Bool tex_only,
Eina_Bool yuv, Evas_Colorspace cspace)
Eina_Bool yuy2)
{ {
int pnum, nv, nc, nu, nu2, nu3, nt, i; int pnum, nv, nc, nu, nu2, nu3, nt, i;
const int points[6] = { 0, 1, 2, 0, 2, 3 }; 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; Eina_Bool blend = 1;
DATA32 cmul; DATA32 cmul;
GLuint prog = gc->shared->shader[SHADER_IMG].prog; GLuint prog = gc->shared->shader[SHADER_IMG].prog;
Eina_Bool utexture = EINA_FALSE;
Eina_Bool uvtexture = EINA_FALSE;
int pn = 0; int pn = 0;
int flat = 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 (p[0].foc <= 0) flat = 1;
} }
if (yuv)
switch (cspace)
{ {
prog = gc->shared->shader[SHADER_YUV].prog; case EVAS_COLORSPACE_YCBCR422P601_PL:
if ((a == 255) && (r == 255) && (g == 255) && (b == 255)) case EVAS_COLORSPACE_YCBCR422P709_PL:
{ prog = gc->shared->shader[evas_gl_common_shader_choice(npoints, p, r, g, b, a,
if ((p[0].col == 0xffffffff) && (p[1].col == 0xffffffff) && SHADER_YUV_NOMUL, SHADER_YUV)].prog;
(p[2].col == 0xffffffff) && (p[3].col == 0xffffffff)) utexture = EINA_TRUE;
prog = gc->shared->shader[SHADER_YUV_NOMUL].prog; break;
else case EVAS_COLORSPACE_YCBCR422601_PL:
prog = gc->shared->shader[SHADER_YUV].prog; prog = gc->shared->shader[evas_gl_common_shader_choice(npoints, p, r, g, b, a,
} SHADER_YUY2_NOMUL, SHADER_YUY2)].prog;
else uvtexture = EINA_TRUE;
prog = gc->shared->shader[SHADER_YUV].prog; break;
} case EVAS_COLORSPACE_YCBCR420NV12601_PL:
else if (yuy2) case EVAS_COLORSPACE_YCBCR420TM12601_PL:
{ prog = gc->shared->shader[evas_gl_common_shader_choice(npoints, p, r, g, b, a,
prog = gc->shared->shader[SHADER_YUY2].prog; SHADER_NV12_NOMUL, SHADER_NV12)].prog;
if ((a == 255) && (r == 255) && (g == 255) && (b == 255)) uvtexture = EINA_TRUE;
{ break;
if ((p[0].col == 0xffffffff) && (p[1].col == 0xffffffff) &&
(p[2].col == 0xffffffff) && (p[3].col == 0xffffffff)) default:
prog = gc->shared->shader[SHADER_YUY2_NOMUL].prog; if (tex_only)
else {
prog = gc->shared->shader[SHADER_YUY2].prog; if (tex->pt->dyn.img)
} {
else prog = gc->shared->shader[evas_gl_common_shader_choice(npoints, p, r, g, b, a,
prog = gc->shared->shader[SHADER_YUY2].prog; SHADER_IMG_NOMUL, SHADER_IMG)].prog;
} }
else else
{ {
if (tex_only) prog = gc->shared->shader[evas_gl_common_shader_choice(npoints, p, r, g, b, a,
{ SHADER_TEX_NOMUL, SHADER_TEX)].prog;
if (tex->pt->dyn.img) }
{ }
if ((a == 255) && (r == 255) && (g == 255) && (b == 255)) else
{ {
if ((p[0].col == 0xffffffff) && (p[1].col == 0xffffffff) && if (tex->gc->shared->info.bgra)
(p[2].col == 0xffffffff) && (p[3].col == 0xffffffff)) {
prog = gc->shared->shader[SHADER_IMG_NOMUL].prog; prog = gc->shared->shader[evas_gl_common_shader_choice(npoints, p, r, g, b, a,
else SHADER_IMG_BGRA_NOMUL,
prog = gc->shared->shader[SHADER_IMG].prog; SHADER_IMG_BGRA)].prog;
} }
else
prog = gc->shared->shader[SHADER_IMG].prog;
}
else else
{ {
if ((a == 255) && (r == 255) && (g == 255) && (b == 255)) prog = gc->shared->shader[evas_gl_common_shader_choice(npoints, p, r, g, b, a,
{ SHADER_IMG_NOMUL,
if ((p[0].col == 0xffffffff) && (p[1].col == 0xffffffff) && SHADER_IMG)].prog;
(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;
}
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;
}
}
} }
x = w = (p[points[0]].x >> FP); 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); py = (p[points[i]].y >> FP);
if (py < y) y = py; if (py < y) y = py;
else if (py > h) h = py; else if (py > h) h = py;
if (yuv || yuy2) if (utexture)
{ {
t2x[i] = ((((double)p[i].u / 2) / FP1)) / (double)tex->ptu->w; t2x[i] = ((((double)p[i].u / 2) / FP1)) / (double)tex->ptu->w;
t2y[i] = ((((double)p[i].v / 2) / FP1)) / (double)tex->ptu->h; 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; w = w - x;
h = h - y; 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].region.type = RTYPE_MAP;
gc->pipe[pn].shader.cur_tex = tex->pt->texture; gc->pipe[pn].shader.cur_tex = tex->pt->texture;
if (yuv) if (utexture)
{ {
gc->pipe[pn].shader.cur_texu = tex->ptu->texture; gc->pipe[pn].shader.cur_texu = tex->ptu->texture;
gc->pipe[pn].shader.cur_texv = tex->ptv->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; 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_vertex = 1;
gc->pipe[pn].array.use_color = 1; gc->pipe[pn].array.use_color = 1;
gc->pipe[pn].array.use_texuv = 1; gc->pipe[pn].array.use_texuv = 1;
gc->pipe[pn].array.use_texuv2 = (yuv || yuy2) ? 1 : 0; gc->pipe[pn].array.use_texuv2 = (utexture || uvtexture) ? 1 : 0;
gc->pipe[pn].array.use_texuv3 = (yuv) ? 1 : 0; gc->pipe[pn].array.use_texuv3 = (utexture) ? 1 : 0;
pipe_region_expand(gc, pn, x, y, w, h); 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++) for (i = 0; i < 4; i++)
{ {
ty[i] = 1.0 - ty[i]; ty[i] = 1.0 - ty[i];
if (yuv || yuy2) if (utexture || uvtexture)
t2y[i] = 1.0 - t2y[i]; 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, PUSH_TEXUV(pn,
tx[points[i]], tx[points[i]],
ty[points[i]]); ty[points[i]]);
if (yuv) if (utexture)
{ {
PUSH_TEXUV2(pn, PUSH_TEXUV2(pn,
t2x[points[i]], t2x[points[i]],
@ -2304,7 +2165,7 @@ evas_gl_common_context_image_map_push(Evas_Engine_GL_Context *gc,
t2x[points[i]], t2x[points[i]],
t2y[points[i]]); t2y[points[i]]);
} }
else if (yuy2) else if (uvtexture)
{ {
PUSH_TEXUV2(pn, PUSH_TEXUV2(pn,
t2x[points[i]], t2x[points[i]],

View File

@ -578,6 +578,40 @@ evas_gl_common_image_update(Evas_Engine_GL_Context *gc, Evas_GL_Image *im)
} }
if (!im->tex) return; if (!im->tex) return;
break; 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: default:
ERR("unhandled img format colorspace=%d", im->cs.space); ERR("unhandled img format colorspace=%d", im->cs.space);
break; 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; cx = gc->dc->clip.x; cy = gc->dc->clip.y;
cw = gc->dc->clip.w; ch = gc->dc->clip.h; cw = gc->dc->clip.w; ch = gc->dc->clip.h;
im->tex->im = im; 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, evas_gl_common_context_image_map_push(gc, im->tex, npoints, p,
c, cx, cy, cw, ch, c, cx, cy, cw, ch,
r, g, b, a, smooth, im->tex_only, r, g, b, a, smooth, im->tex_only,
yuv, yuy2); im->cs.space);
} }
void void

View File

@ -200,6 +200,45 @@ Evas_GL_Program_Source shader_yuy2_nomul_vert_src =
#endif #endif
}; };
/////////////////////////////////////////////
#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) #if defined (GLES_VARIETY_S3C6410)
const unsigned int yuv_nomul_frag_bin[] = const unsigned int yuv_nomul_frag_bin[] =
@ -1029,6 +1068,8 @@ static const struct {
SHADER_SOURCE_LINE(YUV_NOMUL, yuv_nomul), SHADER_SOURCE_LINE(YUV_NOMUL, yuv_nomul),
SHADER_SOURCE_LINE(YUY2, yuy2), SHADER_SOURCE_LINE(YUY2, yuy2),
SHADER_SOURCE_LINE(YUY2_NOMUL, yuy2_nomul), 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, tex),
SHADER_SOURCE_LINE(TEX_NOMUL, tex_nomul), SHADER_SOURCE_LINE(TEX_NOMUL, tex_nomul),
/* Most of the filters use the image fragment shader */ /* Most of the filters use the image fragment shader */

View File

@ -1067,8 +1067,10 @@ evas_gl_common_texture_yuv_update(Evas_GL_Texture *tex, DATA8 **rows, unsigned i
} }
} }
Evas_GL_Texture * static Evas_GL_Texture *
evas_gl_common_texture_yuy2_new(Evas_Engine_GL_Context *gc, DATA8 **rows, unsigned int w, unsigned int h) _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; 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->gc = gc;
tex->references = 1; 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) if (!tex->pt)
{ {
free(tex); 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->slot = -1;
tex->pt->fslot = -1; tex->pt->fslot = -1;
tex->pt->whole = 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) if (!tex->ptuv)
{ {
pt_unref(tex->pt); pt_unref(tex->pt);
@ -1100,38 +1102,50 @@ evas_gl_common_texture_yuy2_new(Evas_Engine_GL_Context *gc, DATA8 **rows, unsign
tex->ptuv->whole = 1; tex->ptuv->whole = 1;
tex->x = 0; tex->x = 0;
tex->y = 0; tex->y = 0;
tex->w = w; tex->w = yw;
tex->h = h; tex->h = yh;
tex->pt->allocations = eina_list_prepend(tex->pt->allocations, tex); tex->pt->allocations = eina_list_prepend(tex->pt->allocations, tex);
tex->ptuv->allocations = eina_list_prepend(tex->ptuv->allocations, tex); tex->ptuv->allocations = eina_list_prepend(tex->ptuv->allocations, tex);
tex->pt->references++; tex->pt->references++;
tex->ptuv->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); evas_gl_common_texture_yuy2_update(tex, rows, w, h);
return tex; 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 void
evas_gl_common_texture_yuy2_update(Evas_GL_Texture *tex, DATA8 **rows, unsigned int w, unsigned int h) evas_gl_common_texture_yuy2_update(Evas_GL_Texture *tex, DATA8 **rows, unsigned int w, unsigned int h)
{ {
if (!tex->pt) return; if (!tex->pt) return;
// FIXME: works on lowest size 4 pixel high buffers. must also be multiple of 2 // FIXME: works on lowest size 4 pixel high buffers. must also be multiple of 2
#undef GL_UNPACK_ROW_LENGTH
#ifdef GL_UNPACK_ROW_LENGTH
glPixelStorei(GL_UNPACK_ROW_LENGTH, rows[1] - rows[0]);
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
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]);
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
_tex_sub_2d(0, 0, w / 2, h, tex->ptuv->format, tex->ptuv->dataformat, rows[0]);
#else
unsigned int y; unsigned int y;
glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
@ -1156,6 +1170,55 @@ evas_gl_common_texture_yuy2_update(Evas_GL_Texture *tex, DATA8 **rows, unsigned
_tex_sub_2d(0, y, w / 2, 1, tex->ptuv->format, tex->ptuv->dataformat, rows[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__, "");
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
glBindTexture(GL_TEXTURE_2D, tex->pt->texture);
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
_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[h + 1] - rows[h]);
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
_tex_sub_2d(0, 0, w / 2, h / 2, tex->ptuv->format, tex->ptuv->dataformat, rows[h]);
#else
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)
_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[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 / 2); y++)
_tex_sub_2d(0, y, w / 2, 1, tex->ptuv->format, tex->ptuv->dataformat, rows[h + y]);
}
#endif #endif
if (tex->pt->texture != tex->gc->pipe[0].shader.cur_tex) 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__, ""); 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();
}

View File

@ -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"

View File

@ -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;
}

View File

@ -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"

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -468,6 +468,8 @@ eng_image_colorspace_set(void *data, void *image, int cspace)
case EVAS_COLORSPACE_YCBCR422P601_PL: case EVAS_COLORSPACE_YCBCR422P601_PL:
case EVAS_COLORSPACE_YCBCR422P709_PL: case EVAS_COLORSPACE_YCBCR422P709_PL:
case EVAS_COLORSPACE_YCBCR422601_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); if (im->tex) evas_gl_common_texture_free(im->tex);
im->tex = NULL; im->tex = NULL;
if (im->cs.data) if (im->cs.data)
@ -599,10 +601,18 @@ eng_image_size_set(void *data, void *image, int w, int h)
return image; return image;
} }
im_old = 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) || switch (eng_image_colorspace_get(data, image))
(eng_image_colorspace_get(data, image) == EVAS_COLORSPACE_YCBCR422601_PL)) {
w &= ~0x1; 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)) if ((im_old) && (im_old->im->cache_entry.w == w) && (im_old->im->cache_entry.h == h))
return image; return image;
if (im_old) 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_YCBCR422P601_PL:
case EVAS_COLORSPACE_YCBCR422P709_PL: case EVAS_COLORSPACE_YCBCR422P709_PL:
case EVAS_COLORSPACE_YCBCR422601_PL: case EVAS_COLORSPACE_YCBCR422601_PL:
case EVAS_COLORSPACE_YCBCR420NV12601_PL:
case EVAS_COLORSPACE_YCBCR420TM12601_PL:
*image_data = im->cs.data; *image_data = im->cs.data;
break; break;
default: default:
@ -729,6 +741,8 @@ eng_image_data_put(void *data, void *image, DATA32 *image_data)
case EVAS_COLORSPACE_YCBCR422P601_PL: case EVAS_COLORSPACE_YCBCR422P601_PL:
case EVAS_COLORSPACE_YCBCR422P709_PL: case EVAS_COLORSPACE_YCBCR422P709_PL:
case EVAS_COLORSPACE_YCBCR422601_PL: case EVAS_COLORSPACE_YCBCR422601_PL:
case EVAS_COLORSPACE_YCBCR420NV12601_PL:
case EVAS_COLORSPACE_YCBCR420TM12601_PL:
if (image_data != im->cs.data) if (image_data != im->cs.data)
{ {
if (im->cs.data) if (im->cs.data)

View File

@ -1065,6 +1065,8 @@ eng_image_colorspace_set(void *data, void *image, int cspace)
case EVAS_COLORSPACE_YCBCR422P601_PL: case EVAS_COLORSPACE_YCBCR422P601_PL:
case EVAS_COLORSPACE_YCBCR422P709_PL: case EVAS_COLORSPACE_YCBCR422P709_PL:
case EVAS_COLORSPACE_YCBCR422601_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); if (im->tex) evas_gl_common_texture_free(im->tex);
im->tex = NULL; im->tex = NULL;
if (im->cs.data) if (im->cs.data)
@ -1708,10 +1710,18 @@ eng_image_size_set(void *data, void *image, int w, int h)
return image; return image;
} }
im_old = 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) || switch (eng_image_colorspace_get(data, image))
(eng_image_colorspace_get(data, image) == EVAS_COLORSPACE_YCBCR422601_PL)) {
w &= ~0x1; 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) && if ((im_old) &&
((int)im_old->im->cache_entry.w == w) && ((int)im_old->im->cache_entry.w == w) &&
((int)im_old->im->cache_entry.h == h)) ((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_YCBCR422P601_PL:
case EVAS_COLORSPACE_YCBCR422P709_PL: case EVAS_COLORSPACE_YCBCR422P709_PL:
case EVAS_COLORSPACE_YCBCR422601_PL: case EVAS_COLORSPACE_YCBCR422601_PL:
case EVAS_COLORSPACE_YCBCR420NV12601_PL:
case EVAS_COLORSPACE_YCBCR420TM12601_PL:
*image_data = im->cs.data; *image_data = im->cs.data;
break; break;
default: default:
@ -1908,6 +1920,8 @@ eng_image_data_put(void *data, void *image, DATA32 *image_data)
case EVAS_COLORSPACE_YCBCR422P601_PL: case EVAS_COLORSPACE_YCBCR422P601_PL:
case EVAS_COLORSPACE_YCBCR422P709_PL: case EVAS_COLORSPACE_YCBCR422P709_PL:
case EVAS_COLORSPACE_YCBCR422601_PL: case EVAS_COLORSPACE_YCBCR422601_PL:
case EVAS_COLORSPACE_YCBCR420NV12601_PL:
case EVAS_COLORSPACE_YCBCR420TM12601_PL:
if (image_data != im->cs.data) if (image_data != im->cs.data)
{ {
if (im->cs.data) if (im->cs.data)

View 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_YCBCR422P601_PL:
case EVAS_COLORSPACE_YCBCR422P709_PL: case EVAS_COLORSPACE_YCBCR422P709_PL:
case EVAS_COLORSPACE_YCBCR422601_PL: case EVAS_COLORSPACE_YCBCR422601_PL:
case EVAS_COLORSPACE_YCBCR420NV12601_PL:
case EVAS_COLORSPACE_YCBCR420TM12601_PL:
*image_data = im->cs.data; *image_data = im->cs.data;
break; break;
default: default:
@ -470,6 +472,8 @@ eng_image_data_put(void *data, void *image, DATA32 *image_data)
case EVAS_COLORSPACE_YCBCR422P601_PL: case EVAS_COLORSPACE_YCBCR422P601_PL:
case EVAS_COLORSPACE_YCBCR422P709_PL: case EVAS_COLORSPACE_YCBCR422P709_PL:
case EVAS_COLORSPACE_YCBCR422601_PL: case EVAS_COLORSPACE_YCBCR422601_PL:
case EVAS_COLORSPACE_YCBCR420NV12601_PL:
case EVAS_COLORSPACE_YCBCR420TM12601_PL:
if (image_data != im->cs.data) if (image_data != im->cs.data)
{ {
if (im->cs.data) if (im->cs.data)