modules/evas/engines/gl_common/shader/yuy2_frag.shd \
modules/evas/engines/gl_common/shader/yuy2_nomul_frag.shd \
modules/evas/engines/gl_common/shader/yuy2_nomul_vert.shd \
-modules/evas/engines/gl_common/shader/yuy2_vert.shd
+modules/evas/engines/gl_common/shader/yuy2_vert.shd \
+modules/evas/engines/gl_common/shader/img_mask_frag.shd \
+modules/evas/engines/gl_common/shader/img_mask_vert.shd \
+modules/evas/engines/gl_common/shader/img_mask_nomul_frag.shd \
+modules/evas/engines/gl_common/shader/img_mask_nomul_vert.shd \
+$(NULL)
EXTRA_DIST += \
modules/evas/engines/gl_common/shader/gen_shaders.sh \
Eina_Bool smooth,
Eina_Bool tex_only,
Evas_Colorspace cspace);
+void evas_gl_common_context_masked_image_push(Evas_Engine_GL_Context *gc,
+ Evas_GL_Texture *tex,
+ Evas_GL_Texture *mask_tex,
+ double sx, double sy,
+ double sw, double sh,
+ int x, int y, int w, int h,
+ int mx, int my, int mw, int mh,
+ int r, int g, int b, int a,
+ Eina_Bool smooth, Eina_Bool tex_only);
int evas_gl_common_shader_program_init(Evas_GL_Shared *shared);
void evas_gl_common_shader_program_init_done(void);
SHADER_TEXTURE_ADD(shared, RGB_A_PAIR_NOMUL, tex);
SHADER_TEXTURE_ADD(shared, RGB_A_PAIR_NOMUL, texa);
+ SHADER_TEXTURE_ADD(shared, IMG_MASK, tex);
+ SHADER_TEXTURE_ADD(shared, IMG_MASK, texa);
+ SHADER_TEXTURE_ADD(shared, IMG_MASK_NOMUL, tex);
+ SHADER_TEXTURE_ADD(shared, IMG_MASK_NOMUL, texa);
+
if (gc->state.current.cur_prog == PRG_INVALID)
glUseProgram(shared->shader[0].prog);
else glUseProgram(gc->state.current.cur_prog);
}
}
+void
+evas_gl_common_context_masked_image_push(Evas_Engine_GL_Context *gc,
+ Evas_GL_Texture *tex,
+ Evas_GL_Texture *mask_tex,
+ double sx, double sy,
+ double sw, double sh,
+ int x, int y, int w, int h,
+ int mx, int my, int mw, int mh,
+ int r, int g, int b, int a,
+ Eina_Bool smooth, Eina_Bool tex_only)
+{
+ // FIXME: How to implement support for yuv, rgb_a_pair & map stuff?
+ // NOTE: If image (tex) has no alpha this is very similar to RGB+A pair
+
+ // FIXME: Optimize for image vs. texture?
+ (void)tex_only;
+
+ int pnum, nv, nc, nu, na, i;
+ GLfloat tx1, tx2, ty1, ty2, t2x1, t2x2, t2y1, t2y2;
+ GLuint prog;
+ int pn;
+
+ // TODO: Big IF here (image type, etc --> needs tons of new shaders!)
+ prog = gc->shared->shader[evas_gl_common_shader_choice
+ (0, NULL, r, g, b, a, SHADER_IMG_MASK_NOMUL, SHADER_IMG_MASK)].prog;
+
+ pn = _evas_gl_common_context_push(RTYPE_IMAGE,
+ gc, tex,
+ prog,
+ x, y, w, h,
+ EINA_TRUE,
+ smooth,
+ EINA_FALSE, 0, 0, 0, 0);
+
+ gc->pipe[pn].region.type = RTYPE_IMAGE;
+ gc->pipe[pn].shader.cur_tex = tex->pt->texture;
+ gc->pipe[pn].shader.cur_texa = mask_tex->pt->texture;
+ gc->pipe[pn].shader.cur_prog = prog;
+ gc->pipe[pn].shader.smooth = smooth;
+ gc->pipe[pn].shader.blend = EINA_TRUE;
+ 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 = EINA_TRUE;
+ // if nomul... dont need this
+ gc->pipe[pn].array.use_color = EINA_TRUE;
+ gc->pipe[pn].array.use_texuv = EINA_TRUE;
+ gc->pipe[pn].array.use_texuv2 = EINA_FALSE;
+ gc->pipe[pn].array.use_texuv3 = EINA_FALSE;
+ gc->pipe[pn].array.use_texa = EINA_TRUE;
+ gc->pipe[pn].array.use_texsam = EINA_FALSE;
+
+ pipe_region_expand(gc, pn, x, y, w, h);
+
+ pnum = gc->pipe[pn].array.num;
+ nv = pnum * 3; nc = pnum * 4; nu = pnum * 2; na = pnum * 2;
+ gc->pipe[pn].array.num += 6;
+ array_alloc(gc, pn);
+
+ tx1 = (tex->x + sx) / (double)tex->pt->w;
+ ty1 = (tex->y + sy) / (double)tex->pt->h;
+ tx2 = (tex->x + sx + sw) / (double)tex->pt->w;
+ ty2 = (tex->y + sy + sh) / (double)tex->pt->h;
+
+ t2x1 = (mask_tex->x + mx) / (double)mask_tex->pt->w;
+ t2y1 = (mask_tex->y + my) / (double)mask_tex->pt->h;
+ t2x2 = (mask_tex->x + mx + mw) / (double)mask_tex->pt->w;
+ t2y2 = (mask_tex->y + my + mh) / (double)mask_tex->pt->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_TEXA(pn, t2x1, t2y1);
+ PUSH_TEXA(pn, t2x2, t2y1);
+ PUSH_TEXA(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_TEXA(pn, t2x2, t2y1);
+ PUSH_TEXA(pn, t2x2, t2y2);
+ PUSH_TEXA(pn, t2x1, t2y2);
+
+ for (i = 0; i < 6; i++)
+ {
+ PUSH_COLOR(pn, r, g, b, a);
+ }
+}
+
EAPI void
evas_gl_common_context_flush(Evas_Engine_GL_Context *gc)
{
glDisableVertexAttribArray(SHAD_TEXUV);
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
}
-
if (gc->pipe[i].array.use_texa)
{
glEnableVertexAttribArray(SHAD_TEXA);
else
{
glDisableVertexAttribArray(SHAD_TEXA);
+
}
if (gc->pipe[i].array.use_texsam)
{
int dx, int dy, int dw, int dh,
int sx, int sy, int sw, int sh,
int cx, int cy, int cw, int ch,
- int r, int g, int b, int a, Eina_Bool smooth,
+ int r, int g, int b, int a,
+ Evas_GL_Image *mask, int mask_x, int mask_y,
+ Eina_Bool smooth,
Eina_Bool yuv, Eina_Bool yuy2, Eina_Bool nv12,
Eina_Bool rgb_a_pair)
{
+ double mx, my, mw, mh, mmx, mmy, mmw, mmh;
double ssx, ssy, ssw, ssh;
int nx, ny, nw, nh;
cx, cy, cw, ch);
if ((nw < 1) || (nh < 1)) return;
if (!im->tex) return;
+
if ((nx == dx) && (ny == dy) && (nw == dw) && (nh == dh))
{
- if (yuv)
+ /* Apply mask on image */
+ if (mask)
+ {
+ // FIXME/TODO: support for yuv, yuy2, nv12, rgb_a with masks
+ mx = mask_x; my = mask_y; mw = mask->w; mh = mask->h;
+ RECTS_CLIP_TO_RECT(mx, my, mw, mh, cx, cy, cw, ch);
+ RECTS_CLIP_TO_RECT(mx, my, mw, mh, dx, dy, dw, dh);
+
+ mmx = (double)(mx - mask_x) + ((double)(mw * (nx - dx)) / (double)(dw));
+ mmy = (double)(my - mask_y) + ((double)(mh * (ny - dy)) / (double)(dh));
+ mmw = ((double)mw * (double)(nw)) / (double)(dw);
+ mmh = ((double)mh * (double)(nh)) / (double)(dh);
+
+ evas_gl_common_context_masked_image_push(gc, im->tex, mask->tex,
+ sx, sy, sw, sh,
+ dx, dy, dw, dh,
+ mmx, mmy, mmw, mmh,
+ r, g, b, a,
+ smooth, im->tex_only);
+ }
+ else if (yuv)
evas_gl_common_context_yuv_push(gc,
im->tex,
sx, sy, sw, sh,
ssw = ((double)sw * (double)(nw)) / (double)(dw);
ssh = ((double)sh * (double)(nh)) / (double)(dh);
- if (yuv)
+ /* Apply mask on image */
+ if (mask)
+ {
+ // FIXME/TODO: support for yuv, yuy2, nv12, rgb_a with masks
+ mx = mask_x; my = mask_y; mw = mask->w; mh = mask->h;
+ RECTS_CLIP_TO_RECT(mx, my, mw, mh, cx, cy, cw, ch);
+ RECTS_CLIP_TO_RECT(mx, my, mw, mh, dx, dy, dw, dh);
+
+ mmx = (double)(mx - mask_x) + ((double)(mw * (nx - dx)) / (double)(dw));
+ mmy = (double)(my - mask_y) + ((double)(mh * (ny - dy)) / (double)(dh));
+ mmw = ((double)mw * (double)(nw)) / (double)(dw);
+ mmh = ((double)mh * (double)(nh)) / (double)(dh);
+
+ evas_gl_common_context_masked_image_push(gc, im->tex, mask->tex,
+ ssx, ssy, ssw, ssh,
+ nx, ny, nw, nh,
+ mmx, mmy, mmw, mmh,
+ r, g, b, a,
+ smooth, im->tex_only);
+ }
+ else if (yuv)
evas_gl_common_context_yuv_push(gc,
im->tex,
ssx, ssy, ssw, ssh,
Eina_Bool yuy2 = EINA_FALSE;
Eina_Bool nv12 = EINA_FALSE;
Eina_Bool rgb_a_pair = EINA_FALSE;
+ Evas_GL_Image *mask;
+ int mask_x, mask_y;
if (sw < 1) sw = 1;
if (sh < 1) sh = 1;
r = g = b = a = 255;
}
+ // Prepare mask image, if there is one
+ mask = dc->clip.mask;
+ mask_x = dc->clip.mask_x;
+ mask_y = dc->clip.mask_y;
+ if (mask)
+ {
+ evas_gl_common_image_update(gc, im);
+ if (!mask->tex)
+ {
+ ERR("Failed to apply mask image");
+ mask = NULL;
+ mask_x = 0;
+ mask_y = 0;
+ }
+ }
+
evas_gl_common_image_update(gc, im);
if (!im->tex)
{
((gc->shared->info.tune.cutout.max > 0) &&
(gc->dc->cutout.active > gc->shared->info.tune.cutout.max)))
{
- if (gc->dc->clip.use)
+ if (mask)
+ {
+ _evas_gl_common_image_push(gc, im,
+ dx, dy, dw, dh,
+ sx, sy, sw, sh,
+ gc->dc->clip.x, gc->dc->clip.y,
+ gc->dc->clip.w, gc->dc->clip.h,
+ r, g, b, a,
+ mask, mask_x, mask_y,
+ smooth,
+ yuv, yuy2, nv12, rgb_a_pair);
+ }
+ else if (gc->dc->clip.use)
{
_evas_gl_common_image_push(gc, im,
dx, dy, dw, dh,
sx, sy, sw, sh,
gc->dc->clip.x, gc->dc->clip.y,
gc->dc->clip.w, gc->dc->clip.h,
- r, g, b, a, smooth,
+ r, g, b, a,
+ mask, mask_x, mask_y,
+ smooth,
yuv, yuy2, nv12, rgb_a_pair);
}
else
dx, dy, dw, dh,
sx, sy, sw, sh,
dx, dy, dw, dh,
- r, g, b, a, smooth,
+ r, g, b, a,
+ mask, mask_x, mask_y,
+ smooth,
yuv, yuy2, nv12, rgb_a_pair);
}
return;
dx, dy, dw, dh,
sx, sy, sw, sh,
rct->x, rct->y, rct->w, rct->h,
- r, g, b, a, smooth,
+ r, g, b, a,
+ mask, mask_x, mask_y,
+ smooth,
yuv, yuy2, nv12, rgb_a_pair);
}
evas_common_draw_context_cutouts_free(_evas_gl_common_cutout_rects);
SHADER_YUV,
SHADER_YUY2_NOMUL,
SHADER_YUY2,
+ SHADER_IMG_MASK,
+ SHADER_IMG_MASK_NOMUL,
SHADER_LAST
} Evas_GL_Shader;
NULL, 0
};
+/* Source: modules/evas/engines/gl_common/shader/img_mask_frag.shd */
+static const char img_mask_frag_glsl[] =
+ "#ifdef GL_ES\n"
+ "#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
+ "precision highp float;\n"
+ "#else\n"
+ "precision mediump float;\n"
+ "#endif\n"
+ "#endif\n"
+ "uniform sampler2D tex;\n"
+ "uniform sampler2D texa;\n"
+ "varying vec4 col;\n"
+ "varying vec2 coord_c;\n"
+ "varying vec2 coord_a;\n"
+ "void main()\n"
+ "{\n"
+ " gl_FragColor.rgb = col.rgb * texture2D(tex, coord_c.xy).rgb * texture2D(texa, coord_a).g;\n"
+ " gl_FragColor.a = col.a * texture2D(tex, coord_c.xy).a * texture2D(texa, coord_a).g;\n"
+ "}\n";
+Evas_GL_Program_Source shader_img_mask_frag_src =
+{
+ img_mask_frag_glsl,
+ NULL, 0
+};
+
+/* Source: modules/evas/engines/gl_common/shader/img_mask_vert.shd */
+static const char img_mask_vert_glsl[] =
+ "#ifdef GL_ES\n"
+ "precision highp float;\n"
+ "#endif\n"
+ "attribute vec4 vertex;\n"
+ "attribute vec4 color;\n"
+ "attribute vec2 tex_coord;\n"
+ "attribute vec2 tex_coorda;\n"
+ "uniform mat4 mvp;\n"
+ "varying vec4 col;\n"
+ "varying vec2 coord_c;\n"
+ "varying vec2 coord_a;\n"
+ "void main()\n"
+ "{\n"
+ " gl_Position = mvp * vertex;\n"
+ " col = color;\n"
+ " coord_c = tex_coord;\n"
+ " coord_a = tex_coorda;\n"
+ "}\n";
+Evas_GL_Program_Source shader_img_mask_vert_src =
+{
+ img_mask_vert_glsl,
+ NULL, 0
+};
+
+/* Source: modules/evas/engines/gl_common/shader/img_mask_nomul_frag.shd */
+static const char img_mask_nomul_frag_glsl[] =
+ "#ifdef GL_ES\n"
+ "#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
+ "precision highp float;\n"
+ "#else\n"
+ "precision mediump float;\n"
+ "#endif\n"
+ "#endif\n"
+ "uniform sampler2D tex;\n"
+ "uniform sampler2D texa;\n"
+ "varying vec2 coord_c;\n"
+ "varying vec2 coord_a;\n"
+ "void main()\n"
+ "{\n"
+ " gl_FragColor.rgb = texture2D(tex, coord_c.xy).rgb * texture2D(texa, coord_a).g;\n"
+ " gl_FragColor.a = texture2D(tex, coord_c.xy).a * texture2D(texa, coord_a).g;\n"
+ "}\n";
+Evas_GL_Program_Source shader_img_mask_nomul_frag_src =
+{
+ img_mask_nomul_frag_glsl,
+ NULL, 0
+};
+
+/* Source: modules/evas/engines/gl_common/shader/img_mask_nomul_vert.shd */
+static const char img_mask_nomul_vert_glsl[] =
+ "#ifdef GL_ES\n"
+ "precision highp float;\n"
+ "#endif\n"
+ "attribute vec4 vertex;\n"
+ "attribute vec2 tex_coord;\n"
+ "attribute vec2 tex_coorda;\n"
+ "uniform mat4 mvp;\n"
+ "varying vec2 coord_c;\n"
+ "varying vec2 coord_a;\n"
+ "void main()\n"
+ "{\n"
+ " gl_Position = mvp * vertex;\n"
+ " coord_c = tex_coord;\n"
+ " coord_a = tex_coorda;\n"
+ "}\n";
+Evas_GL_Program_Source shader_img_mask_nomul_vert_src =
+{
+ img_mask_nomul_vert_glsl,
+ NULL, 0
+};
+
static const struct {
Evas_GL_Shader id;
Evas_GL_Program_Source *vert;
{ SHADER_YUV, &(shader_yuv_vert_src), &(shader_yuv_frag_src), "yuv" },
{ SHADER_YUY2_NOMUL, &(shader_yuy2_nomul_vert_src), &(shader_yuy2_nomul_frag_src), "yuy2_nomul" },
{ SHADER_YUY2, &(shader_yuy2_vert_src), &(shader_yuy2_frag_src), "yuy2" },
+ { SHADER_IMG_MASK, &(shader_img_mask_vert_src), &(shader_img_mask_frag_src), "img_mask" },
+ { SHADER_IMG_MASK_NOMUL, &(shader_img_mask_nomul_vert_src), &(shader_img_mask_nomul_frag_src), "img_mask_nomul" },
};
--- /dev/null
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#endif
+uniform sampler2D tex;
+uniform sampler2D texa;
+varying vec4 col;
+varying vec2 coord_c;
+varying vec2 coord_a;
+void main()
+{
+ gl_FragColor.rgb = col.rgb * texture2D(tex, coord_c.xy).rgb * texture2D(texa, coord_a).g;
+ gl_FragColor.a = col.a * texture2D(tex, coord_c.xy).a * texture2D(texa, coord_a).g;
+}
+
--- /dev/null
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#endif
+uniform sampler2D tex;
+uniform sampler2D texa;
+varying vec2 coord_c;
+varying vec2 coord_a;
+void main()
+{
+ gl_FragColor.rgb = texture2D(tex, coord_c.xy).rgb * texture2D(texa, coord_a).g;
+ gl_FragColor.a = texture2D(tex, coord_c.xy).a * texture2D(texa, coord_a).g;
+}
+
--- /dev/null
+#ifdef GL_ES
+precision highp float;
+#endif
+attribute vec4 vertex;
+attribute vec2 tex_coord;
+attribute vec2 tex_coorda;
+uniform mat4 mvp;
+varying vec2 coord_c;
+varying vec2 coord_a;
+void main()
+{
+ gl_Position = mvp * vertex;
+ coord_c = tex_coord;
+ coord_a = tex_coorda;
+}
+
--- /dev/null
+#ifdef GL_ES
+precision highp float;
+#endif
+attribute vec4 vertex;
+attribute vec4 color;
+attribute vec2 tex_coord;
+attribute vec2 tex_coorda;
+uniform mat4 mvp;
+varying vec4 col;
+varying vec2 coord_c;
+varying vec2 coord_a;
+void main()
+{
+ gl_Position = mvp * vertex;
+ col = color;
+ coord_c = tex_coord;
+ coord_a = tex_coorda;
+}
+