Evas masking: Fix masking of maps in GL

This completes the transition to auto-scaled mask images when
using the GL engine. Now the shaders do the work on-the-fly of
resizing the mask.
This commit is contained in:
Jean-Philippe Andre 2015-02-26 20:42:45 +09:00
parent fab0d7f9d3
commit 0da6278af8
10 changed files with 90 additions and 100 deletions

View File

@ -754,7 +754,7 @@ void evas_gl_common_context_image_map_push(Evas_Engine_GL_Context *g
int npoints,
RGBA_Map_Point *p,
int clip, int cx, int cy, int cw, int ch,
Evas_GL_Texture *mtex, int mx, int my, int mw, int mh, int mdx, int mdy, int mdw, int mdh,
Evas_GL_Texture *mtex, int mx, int my, int mw, int mh, Eina_Bool mask_smooth,
int r, int g, int b, int a,
Eina_Bool smooth,
Eina_Bool tex_only,

View File

@ -2404,8 +2404,7 @@ evas_gl_common_context_image_map_push(Evas_Engine_GL_Context *gc,
int npoints,
RGBA_Map_Point *p,
int clip, int cx, int cy, int cw, int ch,
Evas_GL_Texture *mtex, int mx, int my, int mw, int mh,
int mdx, int mdy, int mdw, int mdh,
Evas_GL_Texture *mtex, int mx, int my, int mw, int mh, Eina_Bool mask_smooth,
int r, int g, int b, int a,
Eina_Bool smooth, Eina_Bool tex_only,
Evas_Colorspace cspace)
@ -2606,7 +2605,7 @@ evas_gl_common_context_image_map_push(Evas_Engine_GL_Context *gc,
gc->pipe[pn].array.use_texm = !!mtex;
gc->pipe[pn].array.use_texa = !!mtex;
gc->pipe[pn].array.use_texsam = gc->pipe[pn].array.use_texm;
gc->pipe[pn].array.mask_smooth = EINA_FALSE;
gc->pipe[pn].array.mask_smooth = mask_smooth;
pipe_region_expand(gc, pn, x, y, w, h);
PIPE_GROW(gc, pn, 6);
@ -2668,12 +2667,8 @@ evas_gl_common_context_image_map_push(Evas_Engine_GL_Context *gc,
if (mtex)
{
GLfloat glmdx = 0.f, glmdy = 0.f, glmdw = 1.f, glmdh = 1.f, yinv = -1.f;
GLfloat gw = gc->w, gh = gc->h;
// Note: I couldn't write any test case where it was necessary
// to know the mask position in its texture. Thus these unused vars.
(void) mx; (void) my; (void) mw; (void) mh;
double glmx, glmy, glmw, glmh, yinv = -1.f;
double gw = gc->w, gh = gc->h;
if (!((gc->pipe[0].shader.surface == gc->def_surface) ||
(!gc->pipe[0].shader.surface)))
@ -2682,40 +2677,47 @@ evas_gl_common_context_image_map_push(Evas_Engine_GL_Context *gc,
gh = gc->pipe[0].shader.surface->h;
yinv = 1.f;
}
if (!gw || !gh || !mw || !mh || !mtex->pt->w || !mtex->pt->h)
goto mask_error;
if (gw) glmdx = (GLfloat) mdx / (GLfloat) gw;
if (gh) glmdy = (GLfloat) mdy / (GLfloat) gh;
if (mdw) glmdw = (GLfloat) gw / (GLfloat) mdw;
if (mdh) glmdh = (GLfloat) gh / (GLfloat) mdh;
// vertex shader: tex_m = (X,Y) * tex_coordm + tex_sample
// tex_coordm
glmx = (double)((mtex->x * mw) - (mtex->w * mx)) / (double)(mw * mtex->pt->w);
glmy = (double)((mtex->y * mh) - (mtex->h * my)) / (double)(mh * mtex->pt->h);
PUSH_TEXM(pn, glmx, glmy);
PUSH_TEXM(pn, glmx, glmy);
PUSH_TEXM(pn, glmx, glmy);
PUSH_TEXM(pn, glmx, glmy);
PUSH_TEXM(pn, glmx, glmy);
PUSH_TEXM(pn, glmx, glmy);
// tex_coordm: mask x,y (on canvas)
PUSH_TEXM(pn, glmdx, glmdy);
PUSH_TEXM(pn, glmdx, glmdy);
PUSH_TEXM(pn, glmdx, glmdy);
PUSH_TEXM(pn, glmdx, glmdy);
PUSH_TEXM(pn, glmdx, glmdy);
PUSH_TEXM(pn, glmdx, glmdy);
// tex_sample
glmw = (double)(gw * mtex->w) / (double)(mw * mtex->pt->w);
glmh = (double)(gh * mtex->h) / (double)(mh * mtex->pt->h);
PUSH_TEXSAM(pn, glmw, glmh);
PUSH_TEXSAM(pn, glmw, glmh);
PUSH_TEXSAM(pn, glmw, glmh);
PUSH_TEXSAM(pn, glmw, glmh);
PUSH_TEXSAM(pn, glmw, glmh);
PUSH_TEXSAM(pn, glmw, glmh);
// tex_sample: mask 1/w, 1/h
PUSH_TEXSAM(pn, glmdw, glmdh);
PUSH_TEXSAM(pn, glmdw, glmdh);
PUSH_TEXSAM(pn, glmdw, glmdh);
PUSH_TEXSAM(pn, glmdw, glmdh);
PUSH_TEXSAM(pn, glmdw, glmdh);
PUSH_TEXSAM(pn, glmdw, glmdh);
// tex_coorda: Y-invert flag
PUSH_TEXA(pn, 1.0, yinv);
PUSH_TEXA(pn, 1.0, yinv);
PUSH_TEXA(pn, 1.0, yinv);
PUSH_TEXA(pn, 1.0, yinv);
PUSH_TEXA(pn, 1.0, yinv);
PUSH_TEXA(pn, 1.0, yinv);
// tex_coorda: mask Y-invert flag
PUSH_TEXA(pn, 1.f, yinv);
PUSH_TEXA(pn, 1.f, yinv);
PUSH_TEXA(pn, 1.f, yinv);
PUSH_TEXA(pn, 1.f, yinv);
PUSH_TEXA(pn, 1.f, yinv);
PUSH_TEXA(pn, 1.f, yinv);
//DBG("Orig %d,%d - %dx%d --> %f,%f - %f x %f", mdx, mdy, mdw, mdh,
// glmdx, glmdy, glmdw, glmdh);
/*
DBG("Map mask: %d,%d %dx%d --> %f , %f - %f x %f @ %f %f [gc %dx%d, tex %d,%d %dx%d, pt %dx%d]",
mx, my, mw, mh,
glmx, glmy, glmw, glmh, 1.0, yinv,
gc->w, gc->h, mtex->x, mtex->y, mtex->w, mtex->h, mtex->pt->w, mtex->pt->h);
*/
}
mask_error:
if (!flat)
{
shader_array_flush(gc);

View File

@ -923,9 +923,11 @@ void
evas_gl_common_image_map_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im,
int npoints, RGBA_Map_Point *p, int smooth, int level EINA_UNUSED)
{
int mmx = 0, mmy = 0, mmw = 0, mmh = 0, mdx = 0, mdy = 0, mdw = 0, mdh = 0;
Evas_GL_Texture *mtex = NULL;
RGBA_Draw_Context *dc;
int mx = 0, my = 0, mw = 0, mh = 0;
RGBA_Draw_Context *dc = gc->dc;
Eina_Bool mask_smooth = EINA_FALSE;
Evas_GL_Image *mask = dc->clip.mask;
Evas_GL_Texture *mtex = mask ? mask->tex : NULL;
int r, g, b, a;
int c, cx, cy, cw, ch;
@ -951,30 +953,32 @@ evas_gl_common_image_map_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im,
if (!im->tex) return;
im->tex->im = im;
if (dc->clip.mask)
if (mtex && mtex->pt && mtex->pt->w && mtex->pt->h)
{
Evas_GL_Image *mask = dc->clip.mask;
double mx, my, mw, mh;
mdx = mx = dc->clip.mask_x;
mdy = my = dc->clip.mask_y;
mdw = mw = mask->w;
mdh = mh = mask->h;
if (c) 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 = mx - dc->clip.mask_x;
mmy = my - dc->clip.mask_y;
mmw = mw;
mmh = mh;
mtex = mask->tex;
// TODO: implement support for scaled masks
//if (mask->scaled.origin)
//mask_smooth = mask->scaled.smooth;
// canvas coords
mx = dc->clip.mask_x;
my = dc->clip.mask_y;
if (mask->scaled.origin)
{
mw = mask->scaled.w;
mh = mask->scaled.h;
//scalex = mask->w / (double)mask->scaled.w;
//scaley = mask->h / (double)mask->scaled.h;
mask_smooth = mask->scaled.smooth;
}
else
{
mw = mask->w;
mh = mask->h;
}
//if (c) RECTS_CLIP_TO_RECT(mx, my, mw, mh, cx, cy, cw, ch);
//mx = mx - dc->clip.mask_x;
//my = my - dc->clip.mask_y;
}
evas_gl_common_context_image_map_push(gc, im->tex, npoints, p,
c, cx, cy, cw, ch,
mtex, mmx, mmy, mmw, mmh, mdx, mdy, mdw, mdh,
mtex, mx, my, mw, mh, mask_smooth,
r, g, b, a, smooth, im->tex_only,
im->cs.space);
}

View File

@ -2715,7 +2715,6 @@ static const char const map_mask_frag_glsl[] =
"varying vec4 col;\n"
"void main()\n"
"{\n"
" // FIXME: Use mask coordinates within its texture\n"
" // FIXME: Fix Mach band effect using proper 4-point color interpolation\n"
" gl_FragColor = texture2D(tex, tex_c).bgra * texture2D(texm, tex_m).a * col;\n"
"}\n";
@ -2741,10 +2740,9 @@ static const char const map_mask_vert_glsl[] =
" tex_c = tex_coord;\n"
" col = color;\n"
" // tex_coorda contains the Y-invert flag\n"
" // tex_coordm contains the X,Y position of the mask\n"
" // tex_sample contains the W,H size of the mask (inverted)\n"
" vec4 mask_Position = mvp * vertex * vec4(tex_coorda.x * 0.5, tex_coorda.y * 0.5, 0.5, 0.5) + vec4(0.5, 0.5, 0, 0);\n"
" tex_m = vec2(mask_Position.xy - tex_coordm) * tex_sample;\n"
" // position on screen in [0..1] range of current pixel\n"
" vec4 mask_Position = mvp * vertex * vec4(0.5, sign(tex_coorda.y) * 0.5, 0.5, 0.5) + vec4(0.5, 0.5, 0, 0);\n"
" tex_m = mask_Position.xy * tex_sample + tex_coordm;\n"
"}\n";
Evas_GL_Program_Source shader_map_mask_vert_src =
{
@ -2787,10 +2785,9 @@ static const char const map_mask_nomul_vert_glsl[] =
" gl_Position = mvp * vertex;\n"
" tex_c = tex_coord;\n"
" // tex_coorda contains the Y-invert flag\n"
" // tex_coordm contains the X,Y position of the mask\n"
" // tex_sample contains the W,H size of the mask (inverted)\n"
" vec4 mask_Position = mvp * vertex * vec4(tex_coorda.x * 0.5, tex_coorda.y * 0.5, 0.5, 0.5) + vec4(0.5, 0.5, 0, 0);\n"
" tex_m = vec2(mask_Position.xy - tex_coordm) * tex_sample;\n"
" // position on screen in [0..1] range of current pixel\n"
" vec4 mask_Position = mvp * vertex * vec4(0.5, sign(tex_coorda.y) * 0.5, 0.5, 0.5) + vec4(0.5, 0.5, 0, 0);\n"
" tex_m = mask_Position.xy * tex_sample + tex_coordm;\n"
"}\n";
Evas_GL_Program_Source shader_map_mask_nomul_vert_src =
{
@ -2812,7 +2809,6 @@ static const char const map_mask_bgra_frag_glsl[] =
"varying vec4 col;\n"
"void main()\n"
"{\n"
" // FIXME: Use mask coordinates within its texture\n"
" // FIXME: Fix Mach band effect using proper 4-point color interpolation\n"
" gl_FragColor = texture2D(tex, tex_c) * texture2D(texm, tex_m).a * col;\n"
"}\n";
@ -2838,10 +2834,9 @@ static const char const map_mask_bgra_vert_glsl[] =
" tex_c = tex_coord;\n"
" col = color;\n"
" // tex_coorda contains the Y-invert flag\n"
" // tex_coordm contains the X,Y position of the mask\n"
" // tex_sample contains the W,H size of the mask (inverted)\n"
" vec4 mask_Position = mvp * vertex * vec4(tex_coorda.x * 0.5, tex_coorda.y * 0.5, 0.5, 0.5) + vec4(0.5, 0.5, 0, 0);\n"
" tex_m = vec2(mask_Position.xy - tex_coordm) * tex_sample;\n"
" // position on screen in [0..1] range of current pixel\n"
" vec4 mask_Position = mvp * vertex * vec4(0.5, sign(tex_coorda.y) * 0.5, 0.5, 0.5) + vec4(0.5, 0.5, 0, 0);\n"
" tex_m = mask_Position.xy * tex_sample + tex_coordm;\n"
"}\n";
Evas_GL_Program_Source shader_map_mask_bgra_vert_src =
{
@ -2884,10 +2879,9 @@ static const char const map_mask_bgra_nomul_vert_glsl[] =
" gl_Position = mvp * vertex;\n"
" tex_c = tex_coord;\n"
" // tex_coorda contains the Y-invert flag\n"
" // tex_coordm contains the X,Y position of the mask\n"
" // tex_sample contains the W,H size of the mask (inverted)\n"
" vec4 mask_Position = mvp * vertex * vec4(tex_coorda.x * 0.5, tex_coorda.y * 0.5, 0.5, 0.5) + vec4(0.5, 0.5, 0, 0);\n"
" tex_m = vec2(mask_Position.xy - tex_coordm) * tex_sample;\n"
" // position on screen in [0..1] range of current pixel\n"
" vec4 mask_Position = mvp * vertex * vec4(0.5, sign(tex_coorda.y) * 0.5, 0.5, 0.5) + vec4(0.5, 0.5, 0, 0);\n"
" tex_m = mask_Position.xy * tex_sample + tex_coordm;\n"
"}\n";
Evas_GL_Program_Source shader_map_mask_bgra_nomul_vert_src =
{

View File

@ -10,7 +10,6 @@ varying vec2 tex_c, tex_m;
varying vec4 col;
void main()
{
// FIXME: Use mask coordinates within its texture
// FIXME: Fix Mach band effect using proper 4-point color interpolation
gl_FragColor = texture2D(tex, tex_c) * texture2D(texm, tex_m).a * col;
}

View File

@ -11,9 +11,7 @@ void main()
tex_c = tex_coord;
// tex_coorda contains the Y-invert flag
// tex_coordm contains the X,Y position of the mask
// tex_sample contains the W,H size of the mask (inverted)
vec4 mask_Position = mvp * vertex * vec4(tex_coorda.x * 0.5, tex_coorda.y * 0.5, 0.5, 0.5) + vec4(0.5, 0.5, 0, 0);
tex_m = vec2(mask_Position.xy - tex_coordm) * tex_sample;
// position on screen in [0..1] range of current pixel
vec4 mask_Position = mvp * vertex * vec4(0.5, sign(tex_coorda.y) * 0.5, 0.5, 0.5) + vec4(0.5, 0.5, 0, 0);
tex_m = mask_Position.xy * tex_sample + tex_coordm;
}

View File

@ -13,9 +13,7 @@ void main()
col = color;
// tex_coorda contains the Y-invert flag
// tex_coordm contains the X,Y position of the mask
// tex_sample contains the W,H size of the mask (inverted)
vec4 mask_Position = mvp * vertex * vec4(tex_coorda.x * 0.5, tex_coorda.y * 0.5, 0.5, 0.5) + vec4(0.5, 0.5, 0, 0);
tex_m = vec2(mask_Position.xy - tex_coordm) * tex_sample;
// position on screen in [0..1] range of current pixel
vec4 mask_Position = mvp * vertex * vec4(0.5, sign(tex_coorda.y) * 0.5, 0.5, 0.5) + vec4(0.5, 0.5, 0, 0);
tex_m = mask_Position.xy * tex_sample + tex_coordm;
}

View File

@ -10,7 +10,6 @@ varying vec2 tex_c, tex_m;
varying vec4 col;
void main()
{
// FIXME: Use mask coordinates within its texture
// FIXME: Fix Mach band effect using proper 4-point color interpolation
gl_FragColor = texture2D(tex, tex_c).bgra * texture2D(texm, tex_m).a * col;
}

View File

@ -11,9 +11,7 @@ void main()
tex_c = tex_coord;
// tex_coorda contains the Y-invert flag
// tex_coordm contains the X,Y position of the mask
// tex_sample contains the W,H size of the mask (inverted)
vec4 mask_Position = mvp * vertex * vec4(tex_coorda.x * 0.5, tex_coorda.y * 0.5, 0.5, 0.5) + vec4(0.5, 0.5, 0, 0);
tex_m = vec2(mask_Position.xy - tex_coordm) * tex_sample;
// position on screen in [0..1] range of current pixel
vec4 mask_Position = mvp * vertex * vec4(0.5, sign(tex_coorda.y) * 0.5, 0.5, 0.5) + vec4(0.5, 0.5, 0, 0);
tex_m = mask_Position.xy * tex_sample + tex_coordm;
}

View File

@ -13,9 +13,7 @@ void main()
col = color;
// tex_coorda contains the Y-invert flag
// tex_coordm contains the X,Y position of the mask
// tex_sample contains the W,H size of the mask (inverted)
vec4 mask_Position = mvp * vertex * vec4(tex_coorda.x * 0.5, tex_coorda.y * 0.5, 0.5, 0.5) + vec4(0.5, 0.5, 0, 0);
tex_m = vec2(mask_Position.xy - tex_coordm) * tex_sample;
// position on screen in [0..1] range of current pixel
vec4 mask_Position = mvp * vertex * vec4(0.5, sign(tex_coorda.y) * 0.5, 0.5, 0.5) + vec4(0.5, 0.5, 0, 0);
tex_m = mask_Position.xy * tex_sample + tex_coordm;
}