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/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_frag.shd \
modules/evas/engines/gl_common/shader/rgb_a_pair_mask_vert.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) $(NULL)
EXTRA_DIST += \ 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); int r, int g, int b, int a);
void evas_gl_common_context_rectangle_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 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, void evas_gl_common_context_image_push(Evas_Engine_GL_Context *gc,
Evas_GL_Texture *tex, Evas_GL_Texture *tex,
double sx, double sy, double sw, double sh, 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, tex);
SHADER_TEXTURE_ADD(shared, FONT_MASK, texm); SHADER_TEXTURE_ADD(shared, FONT_MASK, texm);
SHADER_TEXTURE_ADD(shared, RECT_MASK, texm);
if (gc->state.current.cur_prog == PRG_INVALID) if (gc->state.current.cur_prog == PRG_INVALID)
glUseProgram(shared->shader[0].prog); glUseProgram(shared->shader[0].prog);
else glUseProgram(gc->state.current.cur_prog); else glUseProgram(gc->state.current.cur_prog);
@ -1569,15 +1571,25 @@ evas_gl_common_context_line_push(Evas_Engine_GL_Context *gc,
void void
evas_gl_common_context_rectangle_push(Evas_Engine_GL_Context *gc, evas_gl_common_context_rectangle_push(Evas_Engine_GL_Context *gc,
int x, int y, int w, int h, 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; Eina_Bool blend = EINA_FALSE;
GLuint prog = gc->shared->shader[SHADER_RECT].prog; GLuint prog = gc->shared->shader[SHADER_RECT].prog;
GLuint mtexid = 0;
int pn = 0; int pn = 0;
if (!(gc->dc->render_op == EVAS_RENDER_COPY) && (a < 255)) if (!(gc->dc->render_op == EVAS_RENDER_COPY) && (a < 255))
blend = EINA_TRUE; blend = EINA_TRUE;
if (mtex)
{
blend = EINA_TRUE;
mtexid = mtex->pt->texture;
prog = gc->shared->shader[SHADER_RECT_MASK].prog;
}
again: again:
vertex_array_size_check(gc, gc->state.top_pipe, 6); vertex_array_size_check(gc, gc->state.top_pipe, 6);
pn = gc->state.top_pipe; pn = gc->state.top_pipe;
@ -1586,6 +1598,7 @@ again:
{ {
gc->pipe[pn].region.type = RTYPE_RECT; gc->pipe[pn].region.type = RTYPE_RECT;
gc->pipe[pn].shader.cur_tex = 0; 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.cur_prog = prog;
gc->pipe[pn].shader.blend = blend; gc->pipe[pn].shader.blend = blend;
gc->pipe[pn].shader.render_op = gc->dc->render_op; 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_texuv3 = 0;
gc->pipe[pn].array.use_texa = 0; gc->pipe[pn].array.use_texa = 0;
gc->pipe[pn].array.use_texsam = 0; gc->pipe[pn].array.use_texsam = 0;
gc->pipe[pn].array.use_texm = 0; gc->pipe[pn].array.use_texm = !!mtex;
} }
else else
{ {
@ -1612,6 +1625,7 @@ again:
{ {
if ((gc->pipe[i].region.type == RTYPE_RECT) if ((gc->pipe[i].region.type == RTYPE_RECT)
&& (gc->pipe[i].shader.cur_tex == 0) && (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.cur_prog == prog)
&& (gc->pipe[i].shader.blend == blend) && (gc->pipe[i].shader.blend == blend)
&& (gc->pipe[i].shader.render_op == gc->dc->render_op) && (gc->pipe[i].shader.render_op == gc->dc->render_op)
@ -1635,6 +1649,7 @@ again:
gc->state.top_pipe = pn; gc->state.top_pipe = pn;
gc->pipe[pn].region.type = RTYPE_RECT; gc->pipe[pn].region.type = RTYPE_RECT;
gc->pipe[pn].shader.cur_tex = 0; 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.cur_prog = prog;
gc->pipe[pn].shader.blend = blend; gc->pipe[pn].shader.blend = blend;
gc->pipe[pn].shader.render_op = gc->dc->render_op; 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_texuv3 = 0;
gc->pipe[pn].array.use_texa = 0; gc->pipe[pn].array.use_texa = 0;
gc->pipe[pn].array.use_texsam = 0; gc->pipe[pn].array.use_texsam = 0;
gc->pipe[pn].array.use_texm = 0; gc->pipe[pn].array.use_texm = !!mtex;
} }
} }
#else #else
if ((gc->pipe[pn].shader.cur_tex != 0) 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.cur_prog != prog)
|| (gc->pipe[pn].shader.blend != blend) || (gc->pipe[pn].shader.blend != blend)
|| (gc->pipe[pn].shader.render_op != gc->dc->render_op) || (gc->pipe[pn].shader.render_op != gc->dc->render_op)
@ -1665,6 +1681,7 @@ again:
shader_array_flush(gc); shader_array_flush(gc);
pn = gc->state.top_pipe; pn = gc->state.top_pipe;
gc->pipe[pn].shader.cur_tex = 0; 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.cur_prog = prog;
gc->pipe[pn].shader.blend = blend; gc->pipe[pn].shader.blend = blend;
gc->pipe[pn].shader.render_op = gc->dc->render_op; 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_texuv3 = 0;
gc->pipe[pn].array.use_texa = 0; gc->pipe[pn].array.use_texa = 0;
gc->pipe[pn].array.use_texsam = 0; gc->pipe[pn].array.use_texsam = 0;
gc->pipe[pn].array.use_texm = 0; gc->pipe[pn].array.use_texm = !!mtex;
#endif #endif
pipe_region_expand(gc, pn, x, y, w, h); 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 + w, y + h, 0);
PUSH_VERTEX(pn, x , 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); PUSH_6_COLORS(pn, r, g, b, a);
} }
@ -3175,7 +3194,7 @@ shader_array_flush(Evas_Engine_GL_Context *gc)
} }
else else
{ {
GLint MASK_TEXTURE = GL_TEXTURE1; GLint MASK_TEXTURE = GL_TEXTURE0;
if (gc->pipe[i].array.use_texuv) 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, glVertexAttribPointer(SHAD_TEXUV, 2, GL_FLOAT, GL_FALSE, 0,
(void *)texuv_ptr); (void *)texuv_ptr);
GLERR(__FUNCTION__, __FILE__, __LINE__, ""); GLERR(__FUNCTION__, __FILE__, __LINE__, "");
MASK_TEXTURE += 1;
} }
else 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; Evas_GL_Polygon_Point *pt;
Eina_Inlist *spans; Eina_Inlist *spans;
// TODO: Implement masking support (not very important right now)
/* save out clip info */ /* 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; 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; y = span->y;
w = span->w; w = span->w;
h = 1; 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 else
@ -290,7 +294,9 @@ evas_gl_common_poly_draw(Evas_Engine_GL_Context *gc, Evas_GL_Polygon *poly, int
h = 1; h = 1;
RECTS_CLIP_TO_RECT(x, y, w, h, r->x, r->y, r->w, r->h); RECTS_CLIP_TO_RECT(x, y, w, h, r->x, r->y, r->w, r->h);
if ((w > 0) && (h > 0)) 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; Cutout_Rect *r;
int c, cx, cy, cw, ch, cr, cg, cb, ca, i; 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 ((w <= 0) || (h <= 0)) return;
if (!(RECTS_INTERSECT(x, y, w, h, 0, 0, gc->w, gc->h))) 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); 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) 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 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; r = _evas_gl_common_cutout_rects->rects + i;
if ((r->w > 0) && (r->h > 0)) 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); evas_common_draw_context_cutouts_free(_evas_gl_common_cutout_rects);

View File

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

View File

@ -2656,6 +2656,51 @@ Evas_GL_Program_Source shader_rgb_a_pair_mask_vert_src =
NULL, 0 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 { static const struct {
Evas_GL_Shader id; Evas_GL_Shader id;
Evas_GL_Program_Source *vert; 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_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_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_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;
}