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.
* 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_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 */
/**

View 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;

View 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 :*/

View 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 */

View 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

View 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 */

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

View 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);

View 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)
switch (cspace)
{
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;
}
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_TEX_NOMUL].prog;
else
prog = gc->shared->shader[SHADER_TEX].prog;
}
else
prog = gc->shared->shader[SHADER_TEX].prog;
prog = gc->shared->shader[evas_gl_common_shader_choice(npoints, p, r, g, b, a,
SHADER_IMG_NOMUL,
SHADER_IMG)].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);
@ -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]],

View 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

View File

@ -200,6 +200,45 @@ Evas_GL_Program_Source shader_yuy2_nomul_vert_src =
#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)
const unsigned int yuv_nomul_frag_bin[] =
@ -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 */

View 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,38 +1102,50 @@ 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
#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;
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]);
}
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
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();
}

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_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)

View 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)

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_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)