evas: add YUY2 shader to GL engine.

TODO: add NV12 and NV12T to evas.


SVN revision: 62721
This commit is contained in:
Cedric BAIL 2011-08-23 15:13:40 +00:00
parent 428c512599
commit 7ae4bd0f31
12 changed files with 633 additions and 17 deletions

View File

@ -82,7 +82,11 @@ shader/filter_greyscale_bgra_nomul.h \
shader/filter_blur.h \
shader/filter_blur_nomul.h \
shader/filter_blur_bgra.h \
shader/filter_blur_bgra_nomul.h
shader/filter_blur_bgra_nomul.h \
shader/yuy2_frag.h \
shader/yuy2_vert.h \
shader/yuy2_nomul_frag.h \
shader/yuy2_nomul_vert.h
libevas_engine_gl_common_la_LIBADD = @EINA_LIBS@ @GL_EET_LIBS@ @evas_engine_gl_common_libs@ @dlopen_libs@
endif

View File

@ -208,6 +208,7 @@ struct _Evas_GL_Shared
Evas_GL_Program img_bgra, img_bgra_nomul;
Evas_GL_Program img_mask;
Evas_GL_Program yuv, yuv_nomul;
Evas_GL_Program yuy2, yuy2_nomul;
Evas_GL_Program tex, tex_nomul;
Evas_GL_Program filter_invert, filter_invert_nomul;
@ -237,7 +238,7 @@ struct _Evas_GL_Shared
#define RTYPE_YUV 4
#define RTYPE_MAP 5 /* need to merge with image */
#define RTYPE_IMASK 6
#define RTYPE_YUY2 7
struct _Evas_Engine_GL_Context
@ -255,7 +256,7 @@ struct _Evas_Engine_GL_Context
int top_pipe;
struct {
GLuint cur_prog;
GLuint cur_tex, cur_texu, cur_texv;
GLuint cur_tex, cur_texu, cur_texv;
GLuint cur_texm, cur_texmu, cur_texmv;
int render_op;
int cx, cy, cw, ch;
@ -345,7 +346,7 @@ struct _Evas_GL_Texture
{
Evas_Engine_GL_Context *gc;
Evas_GL_Image *im;
Evas_GL_Texture_Pool *pt, *ptu, *ptv;
Evas_GL_Texture_Pool *pt, *ptu, *ptv, *ptuv;
int x, y, w, h;
double sx1, sy1, sx2, sy2;
int references;
@ -430,6 +431,11 @@ extern Evas_GL_Program_Source shader_yuv_vert_src;
extern Evas_GL_Program_Source shader_yuv_nomul_frag_src;
extern Evas_GL_Program_Source shader_yuv_nomul_vert_src;
extern Evas_GL_Program_Source shader_yuy2_frag_src;
extern Evas_GL_Program_Source shader_yuy2_vert_src;
extern Evas_GL_Program_Source shader_yuy2_nomul_frag_src;
extern Evas_GL_Program_Source shader_yuy2_nomul_vert_src;
extern Evas_GL_Program_Source shader_tex_frag_src;
extern Evas_GL_Program_Source shader_tex_vert_src;
extern Evas_GL_Program_Source shader_tex_nomul_frag_src;
@ -499,6 +505,12 @@ void evas_gl_common_context_yuv_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_yuy2_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,
@ -507,7 +519,8 @@ 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 yuv,
Eina_Bool yuy2);
void evas_gl_common_context_flush(Evas_Engine_GL_Context *gc);
int evas_gl_common_shader_program_init(Evas_GL_Shared *shared);
@ -527,6 +540,8 @@ Evas_GL_Texture *evas_gl_common_texture_alpha_new(Evas_Engine_GL_Context *gc, D
void evas_gl_common_texture_alpha_update(Evas_GL_Texture *tex, DATA8 *pixels, unsigned int w, unsigned int h, int fh);
Evas_GL_Texture *evas_gl_common_texture_yuv_new(Evas_Engine_GL_Context *gc, 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);
void evas_gl_common_texture_yuy2_update(Evas_GL_Texture *tex, DATA8 **rows, unsigned int w, unsigned int h);
void evas_gl_common_image_all_unload(Evas_Engine_GL_Context *gc);

View File

@ -467,6 +467,17 @@ _evas_gl_common_viewport_set(Evas_Engine_GL_Context *gc)
GL_FALSE, proj);
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
glUseProgram(gc->shared->shader.yuy2.prog);
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
glUniformMatrix4fv(glGetUniformLocation(gc->shared->shader.yuy2.prog, "mvp"), 1,
GL_FALSE, proj);
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
glUseProgram(gc->shared->shader.yuy2_nomul.prog);
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
glUniformMatrix4fv(glGetUniformLocation(gc->shared->shader.yuy2_nomul.prog, "mvp"), 1,
GL_FALSE, proj);
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
glUseProgram(gc->shared->shader.tex.prog);
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
glUniformMatrix4fv(glGetUniformLocation(gc->shared->shader.tex.prog, "mvp"), 1,
@ -820,6 +831,13 @@ evas_gl_common_context_new(void)
glUniform1i(glGetUniformLocation(shared->shader.yuv.prog, "texv"), 2);
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
glUseProgram(shared->shader.yuy2.prog);
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
glUniform1i(glGetUniformLocation(shared->shader.yuy2.prog, "tex"), 0);
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
glUniform1i(glGetUniformLocation(shared->shader.yuy2.prog, "texuv"), 1);
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
glUseProgram(shared->shader.yuv_nomul.prog);
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
glUniform1i(glGetUniformLocation(shared->shader.yuv_nomul.prog, "tex"), 0);
@ -829,6 +847,13 @@ evas_gl_common_context_new(void)
glUniform1i(glGetUniformLocation(shared->shader.yuv_nomul.prog, "texv"), 2);
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
glUseProgram(shared->shader.yuy2_nomul.prog);
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
glUniform1i(glGetUniformLocation(shared->shader.yuy2_nomul.prog, "tex"), 0);
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
glUniform1i(glGetUniformLocation(shared->shader.yuy2_nomul.prog, "texuv"), 1);
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
glUseProgram(shared->shader.img_mask.prog);
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
glUniform1i(glGetUniformLocation(shared->shader.img_mask.prog, "tex"), 0);
@ -903,6 +928,8 @@ evas_gl_common_context_free(Evas_Engine_GL_Context *gc)
evas_gl_common_shader_program_shutdown(&(gc->shared->shader.img_mask));
evas_gl_common_shader_program_shutdown(&(gc->shared->shader.yuv));
evas_gl_common_shader_program_shutdown(&(gc->shared->shader.yuv_nomul));
evas_gl_common_shader_program_shutdown(&(gc->shared->shader.yuy2));
evas_gl_common_shader_program_shutdown(&(gc->shared->shader.yuy2_nomul));
evas_gl_common_shader_program_shutdown(&(gc->shared->shader.tex));
evas_gl_common_shader_program_shutdown(&(gc->shared->shader.tex_nomul));
@ -2276,6 +2303,182 @@ again:
}
}
void
evas_gl_common_context_yuy2_push(Evas_Engine_GL_Context *gc,
Evas_GL_Texture *tex,
double sx, double sy, double sw, double sh,
int x, int y, int w, int h,
int r, int g, int b, int a,
Eina_Bool smooth)
{
int pnum, nv, nc, nu, nu2, nu3, nt, i;
GLfloat tx1, tx2, ty1, ty2, t2x1, t2x2, t2y1, t2y2;
Eina_Bool blend = 0;
GLuint prog = gc->shared->shader.yuy2.prog;
int pn = 0;
if (a < 255) blend = 1;
if ((a == 255) && (r == 255) && (g == 255) && (b == 255))
prog = gc->shared->shader.yuy2_nomul.prog;
else
prog = gc->shared->shader.yuy2.prog;
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_YUY2;
gc->pipe[pn].shader.cur_tex = tex->pt->texture;
gc->pipe[pn].shader.cur_texu = tex->ptuv->texture;
gc->pipe[pn].shader.cur_prog = prog;
gc->pipe[pn].shader.smooth = smooth;
gc->pipe[pn].shader.blend = blend;
gc->pipe[pn].shader.render_op = gc->dc->render_op;
gc->pipe[pn].shader.clip = 0;
gc->pipe[pn].shader.cx = 0;
gc->pipe[pn].shader.cy = 0;
gc->pipe[pn].shader.cw = 0;
gc->pipe[pn].shader.ch = 0;
gc->pipe[pn].array.line = 0;
gc->pipe[pn].array.use_vertex = 1;
gc->pipe[pn].array.use_color = 1;
gc->pipe[pn].array.use_texuv = 1;
gc->pipe[pn].array.use_texuv2 = 1;
gc->pipe[pn].array.use_texuv3 = 0;
}
else
{
int found = 0;
for (i = pn; i >= 0; i--)
{
if ((gc->pipe[i].region.type == RTYPE_YUY2)
&& (gc->pipe[i].shader.cur_tex == tex->pt->texture)
&& (gc->pipe[i].shader.cur_prog == gc->shared->shader.font.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_YUY2;
gc->pipe[pn].shader.cur_tex = tex->pt->texture;
gc->pipe[pn].shader.cur_texu = tex->ptuv->texture;
gc->pipe[pn].shader.cur_prog = prog;
gc->pipe[pn].shader.smooth = smooth;
gc->pipe[pn].shader.blend = blend;
gc->pipe[pn].shader.render_op = gc->dc->render_op;
gc->pipe[pn].shader.clip = 0;
gc->pipe[pn].shader.cx = 0;
gc->pipe[pn].shader.cy = 0;
gc->pipe[pn].shader.cw = 0;
gc->pipe[pn].shader.ch = 0;
gc->pipe[pn].array.line = 0;
gc->pipe[pn].array.use_vertex = 1;
gc->pipe[pn].array.use_color = 1;
gc->pipe[pn].array.use_texuv = 1;
gc->pipe[pn].array.use_texuv2 = 1;
gc->pipe[pn].array.use_texuv3 = 0;
}
}
#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_texu = tex->ptuv->texture;
gc->pipe[pn].shader.cur_prog = prog;
gc->pipe[pn].shader.smooth = smooth;
gc->pipe[pn].shader.blend = blend;
gc->pipe[pn].shader.render_op = gc->dc->render_op;
gc->pipe[pn].shader.clip = 0;
gc->pipe[pn].shader.cx = 0;
gc->pipe[pn].shader.cy = 0;
gc->pipe[pn].shader.cw = 0;
gc->pipe[pn].shader.ch = 0;
}
gc->pipe[pn].region.type = RTYPE_YUY2;
gc->pipe[pn].array.line = 0;
gc->pipe[pn].array.use_vertex = 1;
gc->pipe[pn].array.use_color = 1;
gc->pipe[pn].array.use_texuv = 1;
gc->pipe[pn].array.use_texuv2 = 1;
gc->pipe[pn].array.use_texuv3 = 0;
#endif
pipe_region_expand(gc, pn, x, y, w, h);
pnum = gc->pipe[pn].array.num;
nv = pnum * 3; nc = pnum * 4; nu = pnum * 2;
nu2 = pnum * 2; nu3 = pnum * 2; nt = pnum * 4;
gc->pipe[pn].array.num += 6;
array_alloc(gc, pn);
tx1 = (sx) / (double)tex->pt->w;
ty1 = (sy) / (double)tex->pt->h;
tx2 = (sx + sw) / (double)tex->pt->w;
ty2 = (sy + sh) / (double)tex->pt->h;
t2x1 = sx / (double)tex->ptuv->w;
t2y1 = sy / (double)tex->ptuv->h;
t2x2 = (sx + sw) / (double)tex->ptuv->w;
t2y2 = (sy + sh) / (double)tex->ptuv->h;
PUSH_VERTEX(pn, x , y , 0);
PUSH_VERTEX(pn, x + w, y , 0);
PUSH_VERTEX(pn, x , y + h, 0);
PUSH_TEXUV(pn, tx1, ty1);
PUSH_TEXUV(pn, tx2, ty1);
PUSH_TEXUV(pn, tx1, ty2);
PUSH_TEXUV2(pn, t2x1, t2y1);
PUSH_TEXUV2(pn, t2x2, t2y1);
PUSH_TEXUV2(pn, t2x1, t2y2);
PUSH_VERTEX(pn, x + w, y , 0);
PUSH_VERTEX(pn, x + w, y + h, 0);
PUSH_VERTEX(pn, x , y + h, 0);
PUSH_TEXUV(pn, tx2, ty1);
PUSH_TEXUV(pn, tx2, ty2);
PUSH_TEXUV(pn, tx1, ty2);
PUSH_TEXUV2(pn, t2x2, t2y1);
PUSH_TEXUV2(pn, t2x2, t2y2);
PUSH_TEXUV2(pn, t2x1, t2y2);
for (i = 0; i < 6; i++)
{
PUSH_COLOR(pn, r, g, b, a);
}
}
void
evas_gl_common_context_image_map_push(Evas_Engine_GL_Context *gc,
Evas_GL_Texture *tex,
@ -2284,7 +2487,8 @@ evas_gl_common_context_image_map_push(Evas_Engine_GL_Context *gc,
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 yuv,
Eina_Bool yuy2)
{
int pnum, nv, nc, nu, nu2, nu3, nt, i;
const int points[6] = { 0, 1, 2, 0, 2, 3 };
@ -2331,6 +2535,20 @@ evas_gl_common_context_image_map_push(Evas_Engine_GL_Context *gc,
else
prog = gc->shared->shader.yuv.prog;
}
else if (yuy2)
{
prog = gc->shared->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.yuy2_nomul.prog;
else
prog = gc->shared->shader.yuy2.prog;
}
else
prog = gc->shared->shader.yuy2.prog;
}
else
{
if (tex_only)
@ -2412,6 +2630,11 @@ evas_gl_common_context_image_map_push(Evas_Engine_GL_Context *gc,
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 (yuy2)
{
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;
@ -2451,6 +2674,10 @@ again:
gc->pipe[pn].shader.cur_texu = tex->ptu->texture;
gc->pipe[pn].shader.cur_texv = tex->ptv->texture;
}
else if (yuy2)
{
gc->pipe[pn].shader.cur_texu = tex->ptuv->texture;
}
gc->pipe[pn].shader.cur_prog = prog;
gc->pipe[pn].shader.smooth = smooth;
gc->pipe[pn].shader.blend = blend;
@ -2469,6 +2696,11 @@ again:
gc->pipe[pn].array.use_texuv2 = 1;
gc->pipe[pn].array.use_texuv3 = 1;
}
else if (yuy2)
{
gc->pipe[pn].array.use_texuv2 = 1;
gc->pipe[pn].array.use_texuv3 = 0;
}
else
{
gc->pipe[pn].array.use_texuv2 = 0;
@ -2516,6 +2748,10 @@ again:
gc->pipe[pn].shader.cur_texu = tex->ptu->texture;
gc->pipe[pn].shader.cur_texv = tex->ptv->texture;
}
else if (yuy2)
{
gc->pipe[pn].shader.cur_texu = tex->ptuv->texture;
}
gc->pipe[pn].shader.cur_prog = prog;
gc->pipe[pn].shader.smooth = smooth;
gc->pipe[pn].shader.blend = blend;
@ -2534,6 +2770,11 @@ again:
gc->pipe[pn].array.use_texuv2 = 1;
gc->pipe[pn].array.use_texuv3 = 1;
}
else if (yuy2)
{
gc->pipe[pn].array.use_texuv2 = 1;
gc->pipe[pn].array.use_texuv3 = 0;
}
else
{
gc->pipe[pn].array.use_texuv2 = 0;
@ -2576,6 +2817,7 @@ again:
{
shader_array_flush(gc);
gc->pipe[pn].shader.cur_tex = tex->pt->texture;
if (yuy2) gc->pipe[pn].shader.cur_texu = tex->ptuv->texture;
gc->pipe[pn].shader.cur_prog = prog;
gc->pipe[pn].shader.smooth = smooth;
gc->pipe[pn].shader.blend = blend;
@ -2613,6 +2855,11 @@ again:
gc->pipe[pn].array.use_texuv2 = 1;
gc->pipe[pn].array.use_texuv3 = 1;
}
else if (yuy2)
{
gc->pipe[pn].array.use_texuv2 = 1;
gc->pipe[pn].array.use_texuv3 = 0;
}
else
{
gc->pipe[pn].array.use_texuv2 = 0;
@ -2633,7 +2880,7 @@ again:
for (i = 0; i < 4; i++)
{
ty[i] = 1.0 - ty[i];
if (yuv)
if (yuv || yuy2)
t2y[i] = 1.0 - t2y[i];
}
}
@ -2669,6 +2916,12 @@ again:
t2x[points[i]],
t2y[points[i]]);
}
else if (yuy2)
{
PUSH_TEXUV2(pn,
t2x[points[i]],
t2y[points[i]]);
}
PUSH_COLOR(pn,
R_VAL(&cl),

View File

@ -561,9 +561,26 @@ evas_gl_common_image_update(Evas_Engine_GL_Context *gc, Evas_GL_Image *im)
}
if (!im->tex) return;
break;
case EVAS_COLORSPACE_YCBCR422601_PL:
if ((im->tex) && (im->dirty))
{
evas_gl_common_texture_yuy2_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_yuy2_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;
ERR("unhandled img format colorspace=%d", im->cs.space);
break;
}
}
@ -575,6 +592,7 @@ evas_gl_common_image_map_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im,
int r, g, b, a;
int c, cx, cy, cw, ch;
Eina_Bool yuv = 0;
Eina_Bool yuy2 = 0;
dc = gc->dc;
if (dc->mul.use)
@ -598,10 +616,12 @@ evas_gl_common_image_map_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *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);
yuv, yuy2);
}
void
@ -617,6 +637,7 @@ evas_gl_common_image_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im, int sx,
int c, cx, cy, cw, ch;
int i;
int yuv = 0;
int yuy2 = 0;
if (sw < 1) sw = 1;
if (sh < 1) sh = 1;
@ -649,6 +670,8 @@ evas_gl_common_image_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im, int sx,
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;
im->tex->im = im;
if (imm) imm->tex->im = imm;
@ -675,7 +698,15 @@ evas_gl_common_image_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im, int sx,
dx, dy, dw, dh,
r, g, b, a,
smooth);
else if (yuy2)
evas_gl_common_context_yuy2_push(gc,
im->tex,
sx, sy, sw, sh,
dx, dy, dw, dh,
r, g, b, a,
smooth);
else
evas_gl_common_context_image_push(gc,
im->tex,
sx, sy, sw, sh,
@ -717,6 +748,13 @@ evas_gl_common_image_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im, int sx,
nx, ny, nw, nh,
r, g, b, a,
smooth);
else if (yuy2)
evas_gl_common_context_yuy2_push(gc,
im->tex,
ssx, ssy, ssw, ssh,
nx, ny, nw, nh,
r, g, b, a,
smooth);
else
evas_gl_common_context_image_push(gc,
im->tex,
@ -734,6 +772,13 @@ evas_gl_common_image_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im, int sx,
dx, dy, dw, dh,
r, g, b, a,
smooth);
else if (yuy2)
evas_gl_common_context_yuy2_push(gc,
im->tex,
sx, sy, sw, sh,
dx, dy, dw, dh,
r, g, b, a,
smooth);
else
evas_gl_common_context_image_push(gc,
im->tex,
@ -773,6 +818,13 @@ evas_gl_common_image_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im, int sx,
dx, dy, dw, dh,
r, g, b, a,
smooth);
else if (yuy2)
evas_gl_common_context_yuy2_push(gc,
im->tex,
sx, sy, sw, sh,
dx, dy, dw, dh,
r, g, b, a,
smooth);
else
evas_gl_common_context_image_push(gc,
im->tex,
@ -793,6 +845,13 @@ evas_gl_common_image_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im, int sx,
nx, ny, nw, nh,
r, g, b, a,
smooth);
else if (yuy2)
evas_gl_common_context_yuy2_push(gc,
im->tex,
ssx, ssy, ssw, ssh,
nx, ny, nw, nh,
r, g, b, a,
smooth);
else
evas_gl_common_context_image_push(gc,
im->tex,

View File

@ -120,6 +120,86 @@ Evas_GL_Program_Source shader_yuv_vert_src =
#endif
};
/////////////////////////////////////////////
#if defined (GLES_VARIETY_S3C6410)
const unsigned int yuy2_frag_bin[] =
{
# include "shader/yuy2_frag_bin_s3c6410.h"
};
#endif
const char yuy2_frag_glsl[] =
#include "shader/yuy2_frag.h"
;
Evas_GL_Program_Source shader_yuy2_frag_src =
{
yuy2_frag_glsl,
#if defined (GLES_VARIETY_S3C6410)
yuy2_frag_bin, sizeof(yuy2_frag_bin)
#else
NULL, 0
#endif
};
#if defined (GLES_VARIETY_S3C6410)
const unsigned int yuy2_vert_bin[] =
{
# include "shader/yuy2_vert_bin_s3c6410.h"
};
#endif
const char yuy2_vert_glsl[] =
#include "shader/yuy2_vert.h"
;
Evas_GL_Program_Source shader_yuy2_vert_src =
{
yuy2_vert_glsl,
#if defined (GLES_VARIETY_S3C6410)
yuy2_vert_bin, sizeof(yuy2_vert_bin)
#else
NULL, 0
#endif
};
/////////////////////////////////////////////
#if defined (GLES_VARIETY_S3C6410)
const unsigned int yuy2_nomul_frag_bin[] =
{
# include "shader/yuy2_nomul_frag_bin_s3c6410.h"
};
#endif
const char yuy2_nomul_frag_glsl[] =
#include "shader/yuy2_nomul_frag.h"
;
Evas_GL_Program_Source shader_yuy2_nomul_frag_src =
{
yuy2_nomul_frag_glsl,
#if defined (GLES_VARIETY_S3C6410)
yuy2_nomul_frag_bin, sizeof(yuy2_nomul_frag_bin)
#else
NULL, 0
#endif
};
#if defined (GLES_VARIETY_S3C6410)
const unsigned int yuy2_nomul_vert_bin[] =
{
# include "shader/yuy2_nomul_vert_bin_s3c6410.h"
};
#endif
const char yuy2_nomul_vert_glsl[] =
#include "shader/yuy2_nomul_vert.h"
;
Evas_GL_Program_Source shader_yuy2_nomul_vert_src =
{
yuy2_nomul_vert_glsl,
#if defined (GLES_VARIETY_S3C6410)
yuy2_nomul_vert_bin, sizeof(yuy2_nomul_vert_bin)
#else
NULL, 0
#endif
};
/////////////////////////////////////////////
#if defined (GLES_VARIETY_S3C6410)
const unsigned int yuv_nomul_frag_bin[] =
@ -969,6 +1049,14 @@ _evas_gl_common_shader_source_init(Evas_GL_Shared *shared)
&(shader_yuv_vert_src),
&(shader_yuv_frag_src),
"yuv")) return 0;
if (!_evas_gl_common_shader_program_source_init(&(shared->shader.yuy2),
&(shader_yuy2_vert_src),
&(shader_yuy2_frag_src),
"yuy2")) return 0;
if (!_evas_gl_common_shader_program_source_init(&(shared->shader.yuy2_nomul),
&(shader_yuy2_nomul_vert_src),
&(shader_yuy2_nomul_frag_src),
"yuy2_nomul")) return 0;
if (!_evas_gl_common_shader_program_source_init(&(shared->shader.yuv_nomul),
&(shader_yuv_nomul_vert_src),
&(shader_yuv_nomul_frag_src),
@ -1077,7 +1165,9 @@ _evas_gl_common_shader_binary_init(Evas_GL_Shared *shared)
if (!_evas_gl_common_shader_program_binary_init(&(shared->shader.tex), "tex", et)) goto error;
if (!_evas_gl_common_shader_program_binary_init(&(shared->shader.tex_nomul),"tex_nomul", et)) goto error;
if (!_evas_gl_common_shader_program_binary_init(&(shared->shader.yuv), "yuv", et)) goto error;
if (!_evas_gl_common_shader_program_binary_init(&(shared->shader.yuy2), "yuy2", et)) goto error;
if (!_evas_gl_common_shader_program_binary_init(&(shared->shader.yuv_nomul), "yuv_nomul", et)) goto error;
if (!_evas_gl_common_shader_program_binary_init(&(shared->shader.yuy2_nomul), "yuy2_nomul", et)) goto error;
/* Most of the filters use the image fragment shader */
if (!_evas_gl_common_shader_program_binary_init(&(shared->shader.filter_invert), "filter_invert", et)) goto error;
@ -1151,7 +1241,9 @@ _evas_gl_common_shader_binary_save(Evas_GL_Shared *shared)
if (!_evas_gl_common_shader_program_binary_save(&(shared->shader.tex), "tex", et)) goto error;
if (!_evas_gl_common_shader_program_binary_save(&(shared->shader.tex_nomul),"tex_nomul", et)) goto error;
if (!_evas_gl_common_shader_program_binary_save(&(shared->shader.yuv), "yuv", et)) goto error;
if (!_evas_gl_common_shader_program_binary_save(&(shared->shader.yuy2), "yuy2", et)) goto error;
if (!_evas_gl_common_shader_program_binary_save(&(shared->shader.yuv_nomul), "yuv_nomul", et)) goto error;
if (!_evas_gl_common_shader_program_binary_save(&(shared->shader.yuy2_nomul), "yuy2_nomul", et)) goto error;
/* Most of the filters use the image fragment shader */
if (!_evas_gl_common_shader_program_binary_save(&(shared->shader.filter_invert), "filter_invert", et)) goto error;
if (!_evas_gl_common_shader_program_binary_save(&(shared->shader.filter_invert_nomul), "filter_invert_nomul", et)) goto error;

View File

@ -22,10 +22,14 @@ static const GLenum bgr_fmt = GL_BGRA;
static const GLenum bgr_ifmt = GL_RGB;
# endif
#endif
static const GLenum alpha_fmt = GL_ALPHA;
static const GLenum alpha_ifmt = GL_ALPHA;
static const GLenum lum_fmt = GL_LUMINANCE;
static const GLenum lum_ifmt = GL_LUMINANCE;
static const GLenum alpha_fmt = GL_ALPHA;
static const GLenum alpha_ifmt = GL_ALPHA;
static const GLenum lum_fmt = GL_LUMINANCE;
static const GLenum lum_ifmt = GL_LUMINANCE;
static const GLenum lum_alpha_fmt = GL_LUMINANCE_ALPHA;
static const GLenum lum_alpha_ifmt = GL_LUMINANCE_ALPHA;
static const GLenum rgba8_ifmt = GL_RGBA8;
static const GLenum rgba8_fmt = GL_BGRA;
static struct {
struct {
@ -344,7 +348,10 @@ _pool_tex_render_new(Evas_Engine_GL_Context *gc, int w, int h, int intformat, in
pt->h = h;
pt->intformat = intformat;
pt->format = format;
pt->dataformat = GL_UNSIGNED_BYTE;
if (intformat == rgba8_ifmt && format == rgba8_fmt)
pt->dataformat = GL_UNSIGNED_INT_8_8_8_8_REV;
else
pt->dataformat = GL_UNSIGNED_BYTE;
pt->render = 1;
pt->references = 0;
#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
@ -1081,3 +1088,100 @@ evas_gl_common_texture_yuv_update(Evas_GL_Texture *tex, DATA8 **rows, unsigned i
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
}
}
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 = calloc(1, sizeof(Evas_GL_Texture));
if (!tex) return NULL;
tex->gc = gc;
tex->references = 1;
tex->pt = _pool_tex_new(gc, w + 1, h + 1, lum_alpha_ifmt, lum_alpha_fmt);
if (!tex->pt)
{
free(tex);
return NULL;
}
gc->shared->tex.whole = eina_list_prepend(gc->shared->tex.whole, tex->pt);
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);
if (!tex->ptuv)
{
pt_unref(tex->pt);
free(tex);
return NULL;
}
gc->shared->tex.whole = eina_list_prepend(gc->shared->tex.whole, tex->ptuv);
tex->ptuv->slot = -1;
tex->ptuv->fslot = -1;
tex->ptuv->whole = 1;
tex->x = 0;
tex->y = 0;
tex->w = w;
tex->h = h;
tex->pt->allocations = eina_list_prepend(tex->pt->allocations, tex);
tex->ptuv->allocations = eina_list_prepend(tex->ptuv->allocations, tex);
tex->pt->references++;
tex->ptuv->references++;
evas_gl_common_texture_yuy2_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);
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
glBindTexture(GL_TEXTURE_2D, tex->pt->texture);
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
if ((rows[1] - rows[0]) == (int)w * 4)
_tex_sub_2d(0, 0, w, h, tex->pt->format, tex->pt->dataformat, rows[0]);
else
{
for (y = 0; y < h; y++)
_tex_sub_2d(0, y, w, 1, tex->pt->format, tex->pt->dataformat, rows[y]);
}
glBindTexture(GL_TEXTURE_2D, tex->ptuv->texture);
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
if ((rows[1] - rows[0]) == (int)(w * 2))
_tex_sub_2d(0, 0, w / 2, h, tex->ptuv->format, tex->ptuv->dataformat, rows[0]);
else
{
for (y = 0; y < h; y++)
_tex_sub_2d(0, y, w / 2, 1, tex->ptuv->format, tex->ptuv->dataformat, rows[y]);
}
#endif
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__, "");
}
}

View File

@ -0,0 +1,26 @@
"#ifdef GL_ES\n"
"precision mediump float;\n"
"#endif\n"
"uniform sampler2D tex, texuv;\n"
"varying vec4 col;\n"
"varying vec2 tex_c, tex_cuv;\n"
"void main()\n"
"{\n"
" float y,u,v,vmu,r,g,b;\n"
" y=texture2D(tex,tex_c).r;\n"
" u=texture2D(texuv,tex_cuv).g;\n"
" v=texture2D(texuv,tex_cuv).a;\n"
" u=u-0.5;\n"
" v=v-0.5;\n"
" vmu=v*0.813+u*0.391;\n"
" u=u*2.018;\n"
" v=v*1.596;\n"
" r=y+v;\n"
" g=y-vmu;\n"
" b=y+u;\n"
" gl_FragColor=vec4(r,g,b,1.0) * col;\n"
"}\n"

View File

@ -0,0 +1,26 @@
"#ifdef GL_ES\n"
"precision mediump float;\n"
"#endif\n"
"uniform sampler2D tex, texuv;\n"
"varying vec2 tex_c, tex_cuv;\n"
"void main()\n"
"{\n"
" float y,u,v,vmu,r,g,b;\n"
" y=texture2D(tex,tex_c).r;\n"
" u=texture2D(texuv,tex_cuv).g;\n"
" v=texture2D(texuv,tex_cuv).a;\n"
" u=u-0.5;\n"
" v=v-0.5;\n"
" vmu=v*0.813+u*0.391;\n"
" u=u*2.018;\n"
" v=v*1.596;\n"
" y=(y-0.062)*1.164;\n"
" r=y+v;\n"
" g=y-vmu;\n"
" b=y+u;\n"
" gl_FragColor=vec4(r,g,b,1.0);\n"
"}\n"

View File

@ -0,0 +1,13 @@
"#ifdef GL_ES\n"
"precision mediump float;\n"
"#endif\n"
"attribute vec4 vertex;\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 = vec2(tex_coord2.x * 0.5, tex_coord2.y);\n"
"}\n"

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 = vec2(tex_coord2.x * 0.5, tex_coord2.y);\n"
"}\n"

View File

@ -467,6 +467,7 @@ eng_image_colorspace_set(void *data, void *image, int cspace)
break;
case EVAS_COLORSPACE_YCBCR422P601_PL:
case EVAS_COLORSPACE_YCBCR422P709_PL:
case EVAS_COLORSPACE_YCBCR422601_PL:
if (im->tex) evas_gl_common_texture_free(im->tex);
im->tex = NULL;
if (im->cs.data)
@ -599,7 +600,8 @@ eng_image_size_set(void *data, void *image, int w, int h)
}
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_YCBCR422P709_PL) ||
(eng_image_colorspace_get(data, image) == EVAS_COLORSPACE_YCBCR422601_PL))
w &= ~0x1;
if ((im_old) && (im_old->im->cache_entry.w == w) && (im_old->im->cache_entry.h == h))
return image;
@ -686,6 +688,7 @@ eng_image_data_get(void *data, void *image, int to_write, DATA32 **image_data, i
break;
case EVAS_COLORSPACE_YCBCR422P601_PL:
case EVAS_COLORSPACE_YCBCR422P709_PL:
case EVAS_COLORSPACE_YCBCR422601_PL:
*image_data = im->cs.data;
break;
default:
@ -725,6 +728,7 @@ eng_image_data_put(void *data, void *image, DATA32 *image_data)
break;
case EVAS_COLORSPACE_YCBCR422P601_PL:
case EVAS_COLORSPACE_YCBCR422P709_PL:
case EVAS_COLORSPACE_YCBCR422601_PL:
if (image_data != im->cs.data)
{
if (im->cs.data)

View File

@ -1061,6 +1061,7 @@ eng_image_colorspace_set(void *data, void *image, int cspace)
break;
case EVAS_COLORSPACE_YCBCR422P601_PL:
case EVAS_COLORSPACE_YCBCR422P709_PL:
case EVAS_COLORSPACE_YCBCR422601_PL:
if (im->tex) evas_gl_common_texture_free(im->tex);
im->tex = NULL;
if (im->cs.data)
@ -1705,7 +1706,8 @@ eng_image_size_set(void *data, void *image, int w, int h)
}
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_YCBCR422P709_PL) ||
(eng_image_colorspace_get(data, image) == EVAS_COLORSPACE_YCBCR422601_PL))
w &= ~0x1;
if ((im_old) &&
((int)im_old->im->cache_entry.w == w) &&
@ -1826,6 +1828,7 @@ eng_image_data_get(void *data, void *image, int to_write, DATA32 **image_data, i
break;
case EVAS_COLORSPACE_YCBCR422P601_PL:
case EVAS_COLORSPACE_YCBCR422P709_PL:
case EVAS_COLORSPACE_YCBCR422601_PL:
*image_data = im->cs.data;
break;
default:
@ -1891,6 +1894,7 @@ eng_image_data_put(void *data, void *image, DATA32 *image_data)
break;
case EVAS_COLORSPACE_YCBCR422P601_PL:
case EVAS_COLORSPACE_YCBCR422P709_PL:
case EVAS_COLORSPACE_YCBCR422601_PL:
if (image_data != im->cs.data)
{
if (im->cs.data)