From f5d7de90ebb43e1be49d8f6edc545ccaa4a2bd64 Mon Sep 17 00:00:00 2001 From: cedric Date: Sun, 4 Sep 2011 21:15:04 +0000 Subject: [PATCH] evas: and now MT12 gain Open GL support. git-svn-id: http://svn.enlightenment.org/svn/e/trunk/evas@63174 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33 --- src/modules/engines/gl_common/evas_gl_common.h | 2 +- src/modules/engines/gl_common/evas_gl_context.c | 94 +++++++++++++++++ src/modules/engines/gl_common/evas_gl_image.c | 44 +++++++- src/modules/engines/gl_common/evas_gl_shader.c | 44 +++++++- src/modules/engines/gl_common/evas_gl_texture.c | 115 +++++++++++++++++++-- src/modules/engines/gl_common/shader/nv12_frag.h | 27 +++++ .../engines/gl_common/shader/nv12_nomul_frag.h | 26 +++++ .../engines/gl_common/shader/nv12_nomul_vert.h | 2 +- src/modules/engines/gl_common/shader/nv12_vert.h | 2 +- 9 files changed, 341 insertions(+), 15 deletions(-) create mode 100644 src/modules/engines/gl_common/shader/nv12_frag.h create mode 100644 src/modules/engines/gl_common/shader/nv12_nomul_frag.h diff --git a/src/modules/engines/gl_common/evas_gl_common.h b/src/modules/engines/gl_common/evas_gl_common.h index 9c7d5b3..bfb81a1 100644 --- a/src/modules/engines/gl_common/evas_gl_common.h +++ b/src/modules/engines/gl_common/evas_gl_common.h @@ -255,7 +255,7 @@ struct _Evas_GL_Shared #define RTYPE_MAP 5 /* need to merge with image */ #define RTYPE_IMASK 6 #define RTYPE_YUY2 7 - +#define RTYPE_NV12 8 struct _Evas_Engine_GL_Context { diff --git a/src/modules/engines/gl_common/evas_gl_context.c b/src/modules/engines/gl_common/evas_gl_context.c index 31bcc97..14ba4c0 100644 --- a/src/modules/engines/gl_common/evas_gl_context.c +++ b/src/modules/engines/gl_common/evas_gl_context.c @@ -1936,6 +1936,100 @@ evas_gl_common_context_yuy2_push(Evas_Engine_GL_Context *gc, } void +evas_gl_common_context_nv12_push(Evas_Engine_GL_Context *gc, + Evas_GL_Texture *tex, + double sx, double sy, double sw, double sh, + int x, int y, int w, int h, + int r, int g, int b, int a, + Eina_Bool smooth) +{ + int pnum, nv, nc, nu, nu2, nu3, nt, i; + GLfloat tx1, tx2, ty1, ty2, t2x1, t2x2, t2y1, t2y2; + Eina_Bool blend = 0; + GLuint prog; + int pn = 0; + + if (a < 255) blend = 1; + + prog = gc->shared->shader[evas_gl_common_shader_choice(0, NULL, r, g, b, a, + SHADER_NV12_NOMUL, SHADER_NV12)].prog; + + pn = _evas_gl_common_context_push(RTYPE_NV12, + gc, tex, NULL, + prog, + x, y, w, h, + blend, + smooth, + 0, 0, 0, 0, 0); + + gc->pipe[pn].region.type = RTYPE_NV12; + gc->pipe[pn].shader.cur_tex = tex->pt->texture; + gc->pipe[pn].shader.cur_texu = tex->ptuv->texture; + gc->pipe[pn].shader.cur_prog = prog; + gc->pipe[pn].shader.smooth = smooth; + gc->pipe[pn].shader.blend = blend; + gc->pipe[pn].shader.render_op = gc->dc->render_op; + gc->pipe[pn].shader.clip = 0; + gc->pipe[pn].shader.cx = 0; + gc->pipe[pn].shader.cy = 0; + gc->pipe[pn].shader.cw = 0; + gc->pipe[pn].shader.ch = 0; + gc->pipe[pn].array.line = 0; + gc->pipe[pn].array.use_vertex = 1; + gc->pipe[pn].array.use_color = 1; + gc->pipe[pn].array.use_texuv = 1; + gc->pipe[pn].array.use_texuv2 = 1; + gc->pipe[pn].array.use_texuv3 = 0; + + pipe_region_expand(gc, pn, x, y, w, h); + + pnum = gc->pipe[pn].array.num; + nv = pnum * 3; nc = pnum * 4; nu = pnum * 2; + nu2 = pnum * 2; nu3 = pnum * 2; nt = pnum * 4; + gc->pipe[pn].array.num += 6; + array_alloc(gc, pn); + + tx1 = (sx) / (double)tex->pt->w; + ty1 = (sy) / (double)tex->pt->h; + tx2 = (sx + sw) / (double)tex->pt->w; + ty2 = (sy + sh) / (double)tex->pt->h; + + t2x1 = sx / (double)tex->ptuv->w; + t2y1 = sy / (double)tex->ptuv->h; + t2x2 = (sx + sw) / (double)tex->ptuv->w; + t2y2 = (sy + sh) / (double)tex->ptuv->h; + + PUSH_VERTEX(pn, x , y , 0); + PUSH_VERTEX(pn, x + w, y , 0); + PUSH_VERTEX(pn, x , y + h, 0); + + PUSH_TEXUV(pn, tx1, ty1); + PUSH_TEXUV(pn, tx2, ty1); + PUSH_TEXUV(pn, tx1, ty2); + + PUSH_TEXUV2(pn, t2x1, t2y1); + PUSH_TEXUV2(pn, t2x2, t2y1); + PUSH_TEXUV2(pn, t2x1, t2y2); + + PUSH_VERTEX(pn, x + w, y , 0); + PUSH_VERTEX(pn, x + w, y + h, 0); + PUSH_VERTEX(pn, x , y + h, 0); + + PUSH_TEXUV(pn, tx2, ty1); + PUSH_TEXUV(pn, tx2, ty2); + PUSH_TEXUV(pn, tx1, ty2); + + PUSH_TEXUV2(pn, t2x2, t2y1); + PUSH_TEXUV2(pn, t2x2, t2y2); + PUSH_TEXUV2(pn, t2x1, t2y2); + + for (i = 0; i < 6; i++) + { + PUSH_COLOR(pn, r, g, b, a); + } +} + +void evas_gl_common_context_image_map_push(Evas_Engine_GL_Context *gc, Evas_GL_Texture *tex, int npoints, diff --git a/src/modules/engines/gl_common/evas_gl_image.c b/src/modules/engines/gl_common/evas_gl_image.c index 1c3d64c..07eba7b 100644 --- a/src/modules/engines/gl_common/evas_gl_image.c +++ b/src/modules/engines/gl_common/evas_gl_image.c @@ -266,6 +266,9 @@ evas_gl_common_image_new(Evas_Engine_GL_Context *gc, unsigned int w, unsigned in break; case EVAS_COLORSPACE_YCBCR422P601_PL: case EVAS_COLORSPACE_YCBCR422P709_PL: + case EVAS_COLORSPACE_YCBCR422601_PL: + case EVAS_COLORSPACE_YCBCR420NV12601_PL: + case EVAS_COLORSPACE_YCBCR420TM12601_PL: // if (im->tex) evas_gl_common_texture_free(im->tex); im->tex = NULL; im->cs.no_free = 0; @@ -625,8 +628,6 @@ evas_gl_common_image_map_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im, RGBA_Draw_Context *dc; int r, g, b, a; int c, cx, cy, cw, ch; - Eina_Bool yuv = 0; - Eina_Bool yuy2 = 0; dc = gc->dc; if (dc->mul.use) @@ -668,6 +669,7 @@ evas_gl_common_image_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im, int sx, int i; int yuv = 0; int yuy2 = 0; + int nv12 = 0; if (sw < 1) sw = 1; if (sh < 1) sh = 1; @@ -702,6 +704,9 @@ evas_gl_common_image_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im, int sx, yuv = 1; if (im->cs.space == EVAS_COLORSPACE_YCBCR422601_PL) yuy2 = 1; + if ((im->cs.space == EVAS_COLORSPACE_YCBCR420NV12601_PL) || + (im->cs.space == EVAS_COLORSPACE_YCBCR420TM12601_PL)) + nv12 = 1; im->tex->im = im; if (imm) imm->tex->im = imm; @@ -735,6 +740,13 @@ evas_gl_common_image_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im, int sx, dx, dy, dw, dh, r, g, b, a, smooth); + else if (nv12) + evas_gl_common_context_nv12_push(gc, + im->tex, + sx, sy, sw, sh, + dx, dy, dw, dh, + r, g, b, a, + smooth); else evas_gl_common_context_image_push(gc, @@ -785,6 +797,13 @@ evas_gl_common_image_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im, int sx, nx, ny, nw, nh, r, g, b, a, smooth); + else if (nv12) + evas_gl_common_context_nv12_push(gc, + im->tex, + ssx, ssy, ssw, ssh, + nx, ny, nw, nh, + r, g, b, a, + smooth); else evas_gl_common_context_image_push(gc, im->tex, @@ -809,6 +828,13 @@ evas_gl_common_image_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im, int sx, dx, dy, dw, dh, r, g, b, a, smooth); + else if (nv12) + evas_gl_common_context_nv12_push(gc, + im->tex, + sx, sy, sw, sh, + dx, dy, dw, dh, + r, g, b, a, + smooth); else evas_gl_common_context_image_push(gc, im->tex, @@ -855,6 +881,13 @@ evas_gl_common_image_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im, int sx, dx, dy, dw, dh, r, g, b, a, smooth); + else if (nv12) + evas_gl_common_context_nv12_push(gc, + im->tex, + sx, sy, sw, sh, + dx, dy, dw, dh, + r, g, b, a, + smooth); else evas_gl_common_context_image_push(gc, im->tex, @@ -882,6 +915,13 @@ evas_gl_common_image_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im, int sx, nx, ny, nw, nh, r, g, b, a, smooth); + else if (nv12) + evas_gl_common_context_nv12_push(gc, + im->tex, + ssx, ssy, ssw, ssh, + nx, ny, nw, nh, + r, g, b, a, + smooth); else evas_gl_common_context_image_push(gc, im->tex, diff --git a/src/modules/engines/gl_common/evas_gl_shader.c b/src/modules/engines/gl_common/evas_gl_shader.c index 5f05c00..6666ac5 100644 --- a/src/modules/engines/gl_common/evas_gl_shader.c +++ b/src/modules/engines/gl_common/evas_gl_shader.c @@ -239,6 +239,46 @@ Evas_GL_Program_Source shader_nv12_vert_src = #endif }; +#if defined (GLES_VARIETY_S3C6410) +const unsigned int nv12_nomul_frag_bin[] = +{ +# include "shader/nv12_nomul_frag_bin_s3c6410.h" +}; +#endif + +const char nv12_frag_glsl[] = +#include "shader/nv12_frag.h" + ; +Evas_GL_Program_Source shader_nv12_frag_src = +{ + nv12_frag_glsl, +#if defined (GLES_VARIETY_S3C6410) + nv12_frag_bin, sizeof(nv12_frag_bin) +#else + NULL, 0 +#endif +}; + +#if defined (GLES_VARIETY_S3C6410) +const unsigned int nv12_nomul_frag_bin[] = +{ +# include "shader/nv12_nomul_frag_bin_s3c6410.h" +}; +#endif + +const char nv12_nomul_frag_glsl[] = +#include "shader/nv12_nomul_frag.h" + ; +Evas_GL_Program_Source shader_nv12_nomul_frag_src = +{ + nv12_nomul_frag_glsl, +#if defined (GLES_VARIETY_S3C6410) + nv12_nomul_frag_bin, sizeof(nv12_nomul_frag_bin) +#else + NULL, 0 +#endif +}; + ///////////////////////////////////////////// #if defined (GLES_VARIETY_S3C6410) const unsigned int yuv_nomul_frag_bin[] = @@ -1068,8 +1108,8 @@ static const struct { SHADER_SOURCE_LINE(YUV_NOMUL, yuv_nomul), SHADER_SOURCE_LINE(YUY2, yuy2), SHADER_SOURCE_LINE(YUY2_NOMUL, yuy2_nomul), - { SHADER_NV12, &(shader_nv12_vert_src), &(shader_yuy2_frag_src), "nv12" }, - { SHADER_NV12_NOMUL, &(shader_nv12_nomul_vert_src), &(shader_yuy2_nomul_frag_src), "nv12_nomul" }, + SHADER_SOURCE_LINE(NV12, nv12), + SHADER_SOURCE_LINE(NV12_NOMUL, nv12_nomul), SHADER_SOURCE_LINE(TEX, tex), SHADER_SOURCE_LINE(TEX_NOMUL, tex_nomul), /* Most of the filters use the image fragment shader */ diff --git a/src/modules/engines/gl_common/evas_gl_texture.c b/src/modules/engines/gl_common/evas_gl_texture.c index ff38a6d..71ce0f4 100644 --- a/src/modules/engines/gl_common/evas_gl_texture.c +++ b/src/modules/engines/gl_common/evas_gl_texture.c @@ -1067,7 +1067,9 @@ evas_gl_common_texture_yuv_update(Evas_GL_Texture *tex, DATA8 **rows, unsigned i static Evas_GL_Texture * _evas_gl_common_texture_y2uv_new(Evas_Engine_GL_Context *gc, unsigned int yw, unsigned int yh, - unsigned int uvw, unsigned int uvh) + unsigned int uvw, unsigned int uvh, + GLenum y_ifmt, GLenum y_fmt, + GLenum uv_ifmt, GLenum uv_fmt) { Evas_GL_Texture *tex; @@ -1076,7 +1078,7 @@ _evas_gl_common_texture_y2uv_new(Evas_Engine_GL_Context *gc, tex->gc = gc; tex->references = 1; - tex->pt = _pool_tex_new(gc, yw + 1, yh + 1, lum_alpha_ifmt, lum_alpha_fmt); + tex->pt = _pool_tex_new(gc, yw + 1, yh + 1, y_ifmt, y_fmt); if (!tex->pt) { free(tex); @@ -1086,7 +1088,7 @@ _evas_gl_common_texture_y2uv_new(Evas_Engine_GL_Context *gc, tex->pt->slot = -1; tex->pt->fslot = -1; tex->pt->whole = 1; - tex->ptuv = _pool_tex_new(gc, uvw + 1, uvh + 1, rgba8_ifmt, rgba8_fmt); + tex->ptuv = _pool_tex_new(gc, uvw + 1, uvh + 1, uv_ifmt, uv_fmt); if (!tex->ptuv) { pt_unref(tex->pt); @@ -1113,7 +1115,7 @@ evas_gl_common_texture_yuy2_new(Evas_Engine_GL_Context *gc, DATA8 **rows, unsign { Evas_GL_Texture *tex; - tex = _evas_gl_common_texture_y2uv_new(gc, w, h, w / 2, h); + tex = _evas_gl_common_texture_y2uv_new(gc, w, h, w / 2, h, lum_alpha_ifmt, lum_alpha_fmt, rgba8_ifmt, rgba8_fmt); evas_gl_common_texture_yuy2_update(tex, rows, w, h); return tex; } @@ -1123,7 +1125,7 @@ evas_gl_common_texture_nv12_new(Evas_Engine_GL_Context *gc, DATA8 **rows, unsign { Evas_GL_Texture *tex; - tex = _evas_gl_common_texture_y2uv_new(gc, w, h, w / 2, h / 2); + tex = _evas_gl_common_texture_y2uv_new(gc, w, h, w / 2, h / 2, alpha_ifmt, alpha_fmt, lum_alpha_ifmt, lum_alpha_fmt); evas_gl_common_texture_nv12_update(tex, rows, w, h); return tex; } @@ -1133,7 +1135,7 @@ evas_gl_common_texture_nv12tiled_new(Evas_Engine_GL_Context *gc, DATA8 **rows, u { Evas_GL_Texture *tex; - tex = _evas_gl_common_texture_y2uv_new(gc, w, h, w / 2, h / 2); + tex = _evas_gl_common_texture_y2uv_new(gc, w, h, w / 2, h / 2, alpha_ifmt, alpha_fmt, lum_alpha_ifmt, lum_alpha_fmt); evas_gl_common_texture_nv12tiled_update(tex, rows, w, h); return tex; } @@ -1227,7 +1229,104 @@ evas_gl_common_texture_nv12_update(Evas_GL_Texture *tex, DATA8 **rows, unsigned void evas_gl_common_texture_nv12tiled_update(Evas_GL_Texture *tex, DATA8 **rows, unsigned int w, unsigned int h) { + unsigned int mb_x, mb_y, mb_w, mb_h; + unsigned int base_h; + if (!tex->pt) return; - // FIXME: not done yet - abort(); + + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + glBindTexture(GL_TEXTURE_2D, tex->pt->texture); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + + mb_w = w / 64; + mb_h = h / 32; + + /* Iterate each Y macroblock like we do in evas_convert_yuv.c */ + for (mb_y = 0; mb_y < (mb_h >> 1); mb_y++) + { + int step = 2; + int offset = 0; + int x = 0; + int rmb_x = 0; + int ry[2]; + + ry[0] = mb_y * 2 * 32; + ry[1] = ry[0] + 32; + + for (mb_x = 0; mb_x < mb_w * 2; mb_x++, rmb_x += 64 * 32) + { + _tex_sub_2d(x, ry[offset], 64, 32, tex->pt->format, tex->pt->dataformat, rows[mb_y] + rmb_x); + + step++; + if ((step & 0x3) == 0) + { + offset = 1 - offset; + x -= 64; + } + else + { + x += 64; + } + } + } + + if (mb_h & 0x1) + { + int rmb_x = 0; + int x = 0; + int ry; + + ry = mb_y * 2 * 32; + + for (mb_x = 0; mb_x < mb_w; mb_x++, x += 64, rmb_x += 64 * 32) + _tex_sub_2d(x, ry, 64, 32, tex->pt->format, tex->pt->dataformat, rows[mb_y] + rmb_x); + } + + glBindTexture(GL_TEXTURE_2D, tex->ptuv->texture); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + + /* Iterate each UV macroblock like we do in evas_convert_yuv.c */ + base_h = (mb_h >> 1) + (mb_h & 0x1); + for (mb_y = 0; mb_y < (mb_h >> 2); mb_y++) + { + int step = 2; + int offset = 0; + int x = 0; + int rmb_x = 0; + int ry[2]; + + ry[0] = mb_y * 2 * 32; + ry[1] = ry[0] + 32; + + for (mb_x = 0; mb_x < mb_w * 2; mb_x++, rmb_x += 64 * 32) + { + _tex_sub_2d(x, ry[offset], 32, 32, + tex->ptuv->format, tex->ptuv->dataformat, + rows[mb_y + base_h] + rmb_x); + + step++; + if ((step & 0x3) == 0) + { + offset = 1 - offset; + x -= 32; + } + else + { + x += 32; + } + } + } + + if (mb_h & 0x1) + { + int rmb_x = 0; + int x = 0; + int ry; + + ry = mb_y * 2 * 32; + + for (mb_x = 0; mb_x < mb_w; mb_x++, x += 32, rmb_x += 64 * 32) + _tex_sub_2d(x, ry, 64, 32, tex->ptuv->format, tex->ptuv->dataformat, rows[mb_y + base_h] + rmb_x); + } } diff --git a/src/modules/engines/gl_common/shader/nv12_frag.h b/src/modules/engines/gl_common/shader/nv12_frag.h new file mode 100644 index 0000000..2a13b87 --- /dev/null +++ b/src/modules/engines/gl_common/shader/nv12_frag.h @@ -0,0 +1,27 @@ +"#ifdef GL_ES\n" +"precision mediump float;\n" +"#endif\n" +"uniform sampler2D tex, texuv;\n" +"varying vec4 col;\n" +"varying vec2 tex_c, tex_cuv;\n" +"void main()\n" +"{\n" +" float y,u,v,vmu,r,g,b;\n" +" y=texture2D(tex,tex_c).a;\n" +" u=texture2D(texuv,tex_cuv).g;\n" +" v=texture2D(texuv,tex_cuv).a;\n" + +" u=u-0.5;\n" +" v=v-0.5;\n" +" vmu=v*0.813+u*0.391;\n" +" u=u*2.018;\n" +" v=v*1.596;\n" +" y=(y-0.062)*1.164;\n" + +" r=y+v;\n" +" g=y-vmu;\n" +" b=y+u;\n" + +" gl_FragColor=vec4(r,g,b,1.0) * col;\n" +"}\n" + diff --git a/src/modules/engines/gl_common/shader/nv12_nomul_frag.h b/src/modules/engines/gl_common/shader/nv12_nomul_frag.h new file mode 100644 index 0000000..e17c211 --- /dev/null +++ b/src/modules/engines/gl_common/shader/nv12_nomul_frag.h @@ -0,0 +1,26 @@ +"#ifdef GL_ES\n" +"precision mediump float;\n" +"#endif\n" +"uniform sampler2D tex, texuv;\n" +"varying vec2 tex_c, tex_cuv;\n" +"void main()\n" +"{\n" +" float y,u,v,vmu,r,g,b;\n" +" y=texture2D(tex,tex_c).a;\n" +" u=texture2D(texuv,tex_cuv).g;\n" +" v=texture2D(texuv,tex_cuv).a;\n" + +" u=u-0.5;\n" +" v=v-0.5;\n" +" vmu=v*0.813+u*0.391;\n" +" u=u*2.018;\n" +" v=v*1.596;\n" +" y=(y-0.062)*1.164;\n" + +" r=y+v;\n" +" g=y-vmu;\n" +" b=y+u;\n" + +" gl_FragColor=vec4(r,g,b,1.0);\n" +"}\n" + diff --git a/src/modules/engines/gl_common/shader/nv12_nomul_vert.h b/src/modules/engines/gl_common/shader/nv12_nomul_vert.h index 3227065..21304c2 100644 --- a/src/modules/engines/gl_common/shader/nv12_nomul_vert.h +++ b/src/modules/engines/gl_common/shader/nv12_nomul_vert.h @@ -10,5 +10,5 @@ "{\n" " gl_Position = mvp * vertex;\n" " tex_c = tex_coord;\n" -" tex_cuv = tex_coord2;\n" +" tex_cuv = tex_coord2 * 0.5;\n" "}\n" diff --git a/src/modules/engines/gl_common/shader/nv12_vert.h b/src/modules/engines/gl_common/shader/nv12_vert.h index 0cb908e..6b3fea7 100644 --- a/src/modules/engines/gl_common/shader/nv12_vert.h +++ b/src/modules/engines/gl_common/shader/nv12_vert.h @@ -12,5 +12,5 @@ " gl_Position = mvp * vertex;\n" " col = color;\n" " tex_c = tex_coord;\n" -" tex_cuv = tex_coord2;\n" +" tex_cuv = tex_coord2 * 0.5;\n" "}\n" -- 2.7.4