Evas masking: Add rectangle masking for GL

This commit is contained in:
Jean-Philippe Andre 2014-12-02 15:19:10 +09:00
parent 61b847d47a
commit 44387b60a3
9 changed files with 130 additions and 10 deletions

View File

@ -699,6 +699,8 @@ modules/evas/engines/gl_common/shader/yuy2_mask_frag.shd \
modules/evas/engines/gl_common/shader/yuy2_mask_vert.shd \
modules/evas/engines/gl_common/shader/rgb_a_pair_mask_frag.shd \
modules/evas/engines/gl_common/shader/rgb_a_pair_mask_vert.shd \
modules/evas/engines/gl_common/shader/rect_mask_frag.shd \
modules/evas/engines/gl_common/shader/rect_mask_vert.shd \
$(NULL)
EXTRA_DIST += \

View File

@ -720,7 +720,8 @@ void evas_gl_common_context_line_push(Evas_Engine_GL_Context *gc,
int r, int g, int b, int a);
void evas_gl_common_context_rectangle_push(Evas_Engine_GL_Context *gc,
int x, int y, int w, int h,
int r, int g, int b, int a);
int r, int g, int b, int a,
Evas_GL_Texture *mtex, int mx, int my, int mw, int mh);
void evas_gl_common_context_image_push(Evas_Engine_GL_Context *gc,
Evas_GL_Texture *tex,
double sx, double sy, double sw, double sh,

View File

@ -883,6 +883,8 @@ evas_gl_common_context_new(void)
SHADER_TEXTURE_ADD(shared, FONT_MASK, tex);
SHADER_TEXTURE_ADD(shared, FONT_MASK, texm);
SHADER_TEXTURE_ADD(shared, RECT_MASK, texm);
if (gc->state.current.cur_prog == PRG_INVALID)
glUseProgram(shared->shader[0].prog);
else glUseProgram(gc->state.current.cur_prog);
@ -1569,15 +1571,25 @@ evas_gl_common_context_line_push(Evas_Engine_GL_Context *gc,
void
evas_gl_common_context_rectangle_push(Evas_Engine_GL_Context *gc,
int x, int y, int w, int h,
int r, int g, int b, int a)
int r, int g, int b, int a,
Evas_GL_Texture *mtex,
int mx, int my, int mw, int mh)
{
Eina_Bool blend = EINA_FALSE;
GLuint prog = gc->shared->shader[SHADER_RECT].prog;
GLuint mtexid = 0;
int pn = 0;
if (!(gc->dc->render_op == EVAS_RENDER_COPY) && (a < 255))
blend = EINA_TRUE;
if (mtex)
{
blend = EINA_TRUE;
mtexid = mtex->pt->texture;
prog = gc->shared->shader[SHADER_RECT_MASK].prog;
}
again:
vertex_array_size_check(gc, gc->state.top_pipe, 6);
pn = gc->state.top_pipe;
@ -1586,6 +1598,7 @@ again:
{
gc->pipe[pn].region.type = RTYPE_RECT;
gc->pipe[pn].shader.cur_tex = 0;
gc->pipe[pn].shader.cur_texm = mtexid;
gc->pipe[pn].shader.cur_prog = prog;
gc->pipe[pn].shader.blend = blend;
gc->pipe[pn].shader.render_op = gc->dc->render_op;
@ -1602,7 +1615,7 @@ again:
gc->pipe[pn].array.use_texuv3 = 0;
gc->pipe[pn].array.use_texa = 0;
gc->pipe[pn].array.use_texsam = 0;
gc->pipe[pn].array.use_texm = 0;
gc->pipe[pn].array.use_texm = !!mtex;
}
else
{
@ -1612,6 +1625,7 @@ again:
{
if ((gc->pipe[i].region.type == RTYPE_RECT)
&& (gc->pipe[i].shader.cur_tex == 0)
&& (gc->pipe[i].shader.cur_texm == mtexid)
&& (gc->pipe[i].shader.cur_prog == prog)
&& (gc->pipe[i].shader.blend == blend)
&& (gc->pipe[i].shader.render_op == gc->dc->render_op)
@ -1635,6 +1649,7 @@ again:
gc->state.top_pipe = pn;
gc->pipe[pn].region.type = RTYPE_RECT;
gc->pipe[pn].shader.cur_tex = 0;
gc->pipe[pn].shader.cur_texm = mtexid;
gc->pipe[pn].shader.cur_prog = prog;
gc->pipe[pn].shader.blend = blend;
gc->pipe[pn].shader.render_op = gc->dc->render_op;
@ -1651,11 +1666,12 @@ again:
gc->pipe[pn].array.use_texuv3 = 0;
gc->pipe[pn].array.use_texa = 0;
gc->pipe[pn].array.use_texsam = 0;
gc->pipe[pn].array.use_texm = 0;
gc->pipe[pn].array.use_texm = !!mtex;
}
}
#else
if ((gc->pipe[pn].shader.cur_tex != 0)
|| (gc->pipe[pn].shader.cur_texm != mtexid)
|| (gc->pipe[pn].shader.cur_prog != prog)
|| (gc->pipe[pn].shader.blend != blend)
|| (gc->pipe[pn].shader.render_op != gc->dc->render_op)
@ -1665,6 +1681,7 @@ again:
shader_array_flush(gc);
pn = gc->state.top_pipe;
gc->pipe[pn].shader.cur_tex = 0;
gc->pipe[pn].shader.cur_texm = mtexid;
gc->pipe[pn].shader.cur_prog = prog;
gc->pipe[pn].shader.blend = blend;
gc->pipe[pn].shader.render_op = gc->dc->render_op;
@ -1684,7 +1701,7 @@ again:
gc->pipe[pn].array.use_texuv3 = 0;
gc->pipe[pn].array.use_texa = 0;
gc->pipe[pn].array.use_texsam = 0;
gc->pipe[pn].array.use_texm = 0;
gc->pipe[pn].array.use_texm = !!mtex;
#endif
pipe_region_expand(gc, pn, x, y, w, h);
@ -1698,6 +1715,8 @@ again:
PUSH_VERTEX(pn, x + w, y + h, 0);
PUSH_VERTEX(pn, x , y + h, 0);
PUSH_MASK(pn, mtex, mx, my, mw, mh);
PUSH_6_COLORS(pn, r, g, b, a);
}
@ -3175,7 +3194,7 @@ shader_array_flush(Evas_Engine_GL_Context *gc)
}
else
{
GLint MASK_TEXTURE = GL_TEXTURE1;
GLint MASK_TEXTURE = GL_TEXTURE0;
if (gc->pipe[i].array.use_texuv)
{
@ -3184,6 +3203,8 @@ shader_array_flush(Evas_Engine_GL_Context *gc)
glVertexAttribPointer(SHAD_TEXUV, 2, GL_FLOAT, GL_FALSE, 0,
(void *)texuv_ptr);
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
MASK_TEXTURE += 1;
}
else
{

View File

@ -139,6 +139,8 @@ evas_gl_common_poly_draw(Evas_Engine_GL_Context *gc, Evas_GL_Polygon *poly, int
Evas_GL_Polygon_Point *pt;
Eina_Inlist *spans;
// TODO: Implement masking support (not very important right now)
/* save out clip info */
c = gc->dc->clip.use; cx = gc->dc->clip.x; cy = gc->dc->clip.y; cw = gc->dc->clip.w; ch = gc->dc->clip.h;
@ -268,7 +270,9 @@ evas_gl_common_poly_draw(Evas_Engine_GL_Context *gc, Evas_GL_Polygon *poly, int
y = span->y;
w = span->w;
h = 1;
evas_gl_common_context_rectangle_push(gc, x, y, w, h, cr, cg, cb, ca);
evas_gl_common_context_rectangle_push(gc, x, y, w, h,
cr, cg, cb, ca,
NULL, 0, 0, 0, 0);
}
}
else
@ -290,7 +294,9 @@ evas_gl_common_poly_draw(Evas_Engine_GL_Context *gc, Evas_GL_Polygon *poly, int
h = 1;
RECTS_CLIP_TO_RECT(x, y, w, h, r->x, r->y, r->w, r->h);
if ((w > 0) && (h > 0))
evas_gl_common_context_rectangle_push(gc, x, y, w, h, cr, cg, cb, ca);
evas_gl_common_context_rectangle_push(gc, x, y, w, h,
cr, cg, cb, ca,
NULL, 0, 0, 0, 0);
}
}
}

View File

@ -5,6 +5,8 @@ evas_gl_common_rect_draw(Evas_Engine_GL_Context *gc, int x, int y, int w, int h)
{
Cutout_Rect *r;
int c, cx, cy, cw, ch, cr, cg, cb, ca, i;
double mx = 0, my = 0, mw = 0, mh = 0;
Evas_GL_Texture *mtex = NULL;
if ((w <= 0) || (h <= 0)) return;
if (!(RECTS_INTERSECT(x, y, w, h, 0, 0, gc->w, gc->h))) return;
@ -26,9 +28,21 @@ evas_gl_common_rect_draw(Evas_Engine_GL_Context *gc, int x, int y, int w, int h)
gc->dc->clip.w, gc->dc->clip.h);
}
if (gc->dc->clip.mask)
{
Evas_GL_Image *mask = gc->dc->clip.mask;
mx = gc->dc->clip.mask_x; mw = mask->w;
my = gc->dc->clip.mask_y; mh = mask->h;
RECTS_CLIP_TO_RECT(mx, my, mw, mh, cx, cy, cw, ch);
mx -= gc->dc->clip.mask_x;
my -= gc->dc->clip.mask_y;
mtex = mask->tex;
}
if (!gc->dc->cutout.rects)
{
evas_gl_common_context_rectangle_push(gc, x, y, w, h, cr, cg, cb, ca);
evas_gl_common_context_rectangle_push(gc, x, y, w, h, cr, cg, cb, ca, mtex, mx, my, mw, mh);
}
else
{
@ -42,7 +56,7 @@ evas_gl_common_rect_draw(Evas_Engine_GL_Context *gc, int x, int y, int w, int h)
r = _evas_gl_common_cutout_rects->rects + i;
if ((r->w > 0) && (r->h > 0))
{
evas_gl_common_context_rectangle_push(gc, r->x, r->y, r->w, r->h, cr, cg, cb, ca);
evas_gl_common_context_rectangle_push(gc, r->x, r->y, r->w, r->h, cr, cg, cb, ca, mtex, mx, my, mw, mh);
}
}
evas_common_draw_context_cutouts_free(_evas_gl_common_cutout_rects);

View File

@ -53,5 +53,6 @@ typedef enum {
SHADER_NV12_MASK,
SHADER_YUY2_MASK,
SHADER_RGB_A_PAIR_MASK,
SHADER_RECT_MASK,
SHADER_LAST
} Evas_GL_Shader;

View File

@ -2656,6 +2656,51 @@ Evas_GL_Program_Source shader_rgb_a_pair_mask_vert_src =
NULL, 0
};
/* Source: modules/evas/engines/gl_common/shader/rect_mask_frag.shd */
static const char const rect_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 texm;\n"
"varying vec4 col;\n"
"varying vec4 coord_m;\n"
"void main()\n"
"{\n"
" gl_FragColor = texture2D(texm, coord_m.xy).a * col;\n"
"}\n";
Evas_GL_Program_Source shader_rect_mask_frag_src =
{
rect_mask_frag_glsl,
NULL, 0
};
/* Source: modules/evas/engines/gl_common/shader/rect_mask_vert.shd */
static const char const rect_mask_vert_glsl[] =
"#ifdef GL_ES\n"
"precision highp float;\n"
"#endif\n"
"attribute vec4 vertex;\n"
"attribute vec4 color;\n"
"attribute vec4 tex_coordm;\n"
"uniform mat4 mvp;\n"
"varying vec4 col;\n"
"varying vec4 coord_m;\n"
"void main()\n"
"{\n"
" gl_Position = mvp * vertex;\n"
" col = color;\n"
" coord_m = tex_coordm;\n"
"}\n";
Evas_GL_Program_Source shader_rect_mask_vert_src =
{
rect_mask_vert_glsl,
NULL, 0
};
static const struct {
Evas_GL_Shader id;
Evas_GL_Program_Source *vert;
@ -2713,5 +2758,6 @@ static const struct {
{ SHADER_NV12_MASK, &(shader_nv12_mask_vert_src), &(shader_nv12_mask_frag_src), "nv12_mask" },
{ SHADER_YUY2_MASK, &(shader_yuy2_mask_vert_src), &(shader_yuy2_mask_frag_src), "yuy2_mask" },
{ SHADER_RGB_A_PAIR_MASK, &(shader_rgb_a_pair_mask_vert_src), &(shader_rgb_a_pair_mask_frag_src), "rgb_a_pair_mask" },
{ SHADER_RECT_MASK, &(shader_rect_mask_vert_src), &(shader_rect_mask_frag_src), "rect_mask" },
};

View File

@ -0,0 +1,14 @@
#ifdef GL_ES
#ifdef GL_FRAGMENT_PRECISION_HIGH
precision highp float;
#else
precision mediump float;
#endif
#endif
uniform sampler2D texm;
varying vec4 col;
varying vec4 coord_m;
void main()
{
gl_FragColor = texture2D(texm, coord_m.xy).a * col;
}

View File

@ -0,0 +1,15 @@
#ifdef GL_ES
precision highp float;
#endif
attribute vec4 vertex;
attribute vec4 color;
attribute vec4 tex_coordm;
uniform mat4 mvp;
varying vec4 col;
varying vec4 coord_m;
void main()
{
gl_Position = mvp * vertex;
col = color;
coord_m = tex_coordm;
}