forked from enlightenment/efl
Evas masking: Font masking for GL
This commit is contained in:
parent
124ab102b7
commit
1fac1dcf57
|
@ -599,6 +599,8 @@ modules/evas/engines/gl_common/evas_gl_3d_shader.c
|
|||
GL_SHADERS_GEN = \
|
||||
modules/evas/engines/gl_common/shader/font_frag.shd \
|
||||
modules/evas/engines/gl_common/shader/font_vert.shd \
|
||||
modules/evas/engines/gl_common/shader/font_mask_frag.shd \
|
||||
modules/evas/engines/gl_common/shader/font_mask_vert.shd \
|
||||
modules/evas/engines/gl_common/shader/img_12_bgra_frag.shd \
|
||||
modules/evas/engines/gl_common/shader/img_12_bgra_nomul_frag.shd \
|
||||
modules/evas/engines/gl_common/shader/img_12_bgra_nomul_vert.shd \
|
||||
|
|
|
@ -729,6 +729,13 @@ void evas_gl_common_context_font_push(Evas_Engine_GL_Context *gc,
|
|||
double sx, double sy, double sw, double sh,
|
||||
int x, int y, int w, int h,
|
||||
int r, int g, int b, int a);
|
||||
void evas_gl_common_context_masked_font_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,
|
||||
Evas_GL_Texture *texa,
|
||||
int mx, int my, int mw, int mh);
|
||||
void evas_gl_common_context_yuv_push(Evas_Engine_GL_Context *gc,
|
||||
Evas_GL_Texture *tex,
|
||||
double sx, double sy, double sw, double sh,
|
||||
|
|
|
@ -856,6 +856,9 @@ evas_gl_common_context_new(void)
|
|||
SHADER_TEXTURE_ADD(shared, IMG_MASK_NOMUL, tex);
|
||||
SHADER_TEXTURE_ADD(shared, IMG_MASK_NOMUL, texa);
|
||||
|
||||
SHADER_TEXTURE_ADD(shared, FONT_MASK, tex);
|
||||
SHADER_TEXTURE_ADD(shared, FONT_MASK, texa);
|
||||
|
||||
if (gc->state.current.cur_prog == PRG_INVALID)
|
||||
glUseProgram(shared->shader[0].prog);
|
||||
else glUseProgram(gc->state.current.cur_prog);
|
||||
|
@ -1899,6 +1902,106 @@ evas_gl_common_context_image_push(Evas_Engine_GL_Context *gc,
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
evas_gl_common_context_masked_font_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,
|
||||
Evas_GL_Texture *texa,
|
||||
int mx, int my, int mw, int mh)
|
||||
{
|
||||
int pnum, nv, nc, nu, na, i;
|
||||
GLfloat tx1, tx2, ty1, ty2, t2x1, t2x2, t2y1, t2y2;
|
||||
GLuint prog = gc->shared->shader[SHADER_FONT_MASK].prog;
|
||||
int pn = 0;
|
||||
|
||||
pn = _evas_gl_common_context_push(RTYPE_FONT,
|
||||
gc, tex,
|
||||
prog,
|
||||
x, y, w, h,
|
||||
1,
|
||||
0,
|
||||
0, 0, 0, 0, 0);
|
||||
|
||||
gc->pipe[pn].region.type = RTYPE_FONT;
|
||||
gc->pipe[pn].shader.cur_tex = tex->pt->texture;
|
||||
gc->pipe[pn].shader.cur_texa = texa->pt->texture;
|
||||
gc->pipe[pn].shader.cur_prog = prog;
|
||||
gc->pipe[pn].shader.smooth = 0;
|
||||
gc->pipe[pn].shader.blend = 1;
|
||||
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 = 0;
|
||||
gc->pipe[pn].array.use_texuv3 = 0;
|
||||
gc->pipe[pn].array.use_texa = 1; //
|
||||
gc->pipe[pn].array.use_texsam = 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; na = pnum * 2;
|
||||
gc->pipe[pn].array.num += 6;
|
||||
array_alloc(gc, pn);
|
||||
|
||||
if (sw == 0.0)
|
||||
{
|
||||
tx1 = tex->sx1;
|
||||
ty1 = tex->sy1;
|
||||
tx2 = tex->sx2;
|
||||
ty2 = tex->sy2;
|
||||
}
|
||||
else
|
||||
{
|
||||
tx1 = ((double)(tex->x) + sx) / (double)tex->pt->w;
|
||||
ty1 = ((double)(tex->y) + sy) / (double)tex->pt->h;
|
||||
tx2 = ((double)(tex->x) + sx + sw) / (double)tex->pt->w;
|
||||
ty2 = ((double)(tex->y) + sy + sh) / (double)tex->pt->h;
|
||||
}
|
||||
|
||||
t2x1 = (texa->x + mx) / (double)texa->pt->w;
|
||||
t2y1 = (texa->y + my) / (double)texa->pt->h;
|
||||
t2x2 = (texa->x + mx + mw) / (double)texa->pt->w;
|
||||
t2y2 = (texa->y + my + mh) / (double)texa->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);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
evas_gl_common_context_font_push(Evas_Engine_GL_Context *gc,
|
||||
Evas_GL_Texture *tex,
|
||||
|
|
|
@ -68,6 +68,7 @@ evas_gl_font_texture_draw(void *context, void *surface EINA_UNUSED, void *draw_c
|
|||
int c, cx, cy, cw, ch;
|
||||
int i;
|
||||
int sx, sy, sw, sh;
|
||||
double mx, my, mw, mh, mmx, mmy, mmw, mmh;
|
||||
|
||||
if (dc != gc->dc) return;
|
||||
tex = fg->ext_dat;
|
||||
|
@ -78,6 +79,42 @@ evas_gl_font_texture_draw(void *context, void *surface EINA_UNUSED, void *draw_c
|
|||
g = (dc->col.col >> 8 ) & 0xff;
|
||||
b = (dc->col.col ) & 0xff;
|
||||
sx = 0; sy = 0; sw = tex->w, sh = tex->h;
|
||||
|
||||
if (gc->dc->clip.mask && (sw > 0) && (sh > 0))
|
||||
{
|
||||
// FIXME: This code path does not handle half the stuff the other path does...
|
||||
Evas_GL_Image *mask = gc->dc->clip.mask;
|
||||
int nx, ny, nw, nh, dx, dy, dw, dh;
|
||||
|
||||
nx = x; ny = y; nw = tex->w; nh = tex->h;
|
||||
RECTS_CLIP_TO_RECT(nx, ny, nw, nh,
|
||||
gc->dc->clip.x, gc->dc->clip.y,
|
||||
gc->dc->clip.w, gc->dc->clip.h);
|
||||
if ((nw < 1) || (nh < 1)) return;
|
||||
|
||||
ssx = (double)sx + ((double)(sw * (nx - x)) / (double)(tex->w));
|
||||
ssy = (double)sy + ((double)(sh * (ny - y)) / (double)(tex->h));
|
||||
ssw = ((double)sw * (double)(nw)) / (double)(tex->w);
|
||||
ssh = ((double)sh * (double)(nh)) / (double)(tex->h);
|
||||
|
||||
dx = x; dy = y; dw = sw; dh = sh;
|
||||
mx = gc->dc->clip.mask_x; my = gc->dc->clip.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 - gc->dc->clip.mask_x) + ((double)(mw * (nx - dx)) / (double)(dw));
|
||||
mmy = (double)(my - gc->dc->clip.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_font_push(gc, tex,
|
||||
ssx, ssy, ssw, ssh,
|
||||
nx, ny, nw, nh,
|
||||
r, g, b, a,
|
||||
mask->tex, mmx, mmy, mmw, mmh);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((!gc->dc->cutout.rects) ||
|
||||
((gc->shared->info.tune.cutout.max > 0) &&
|
||||
(gc->dc->cutout.active > gc->shared->info.tune.cutout.max)))
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
typedef enum {
|
||||
SHADER_FONT,
|
||||
SHADER_FONT_MASK,
|
||||
SHADER_IMG_12_BGRA_NOMUL,
|
||||
SHADER_IMG_12_BGRA,
|
||||
SHADER_IMG_12_NOMUL,
|
||||
|
|
|
@ -48,6 +48,56 @@ Evas_GL_Program_Source shader_font_vert_src =
|
|||
NULL, 0
|
||||
};
|
||||
|
||||
/* Source: modules/evas/engines/gl_common/shader/font_mask_frag.shd */
|
||||
static const char const font_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 tex_c;\n"
|
||||
"varying vec2 tex_a;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" gl_FragColor = texture2D(tex, tex_c.xy).aaaa * texture2D(texa, tex_a.xy).aaaa * col;\n"
|
||||
"}\n";
|
||||
Evas_GL_Program_Source shader_font_mask_frag_src =
|
||||
{
|
||||
font_mask_frag_glsl,
|
||||
NULL, 0
|
||||
};
|
||||
|
||||
/* Source: modules/evas/engines/gl_common/shader/font_mask_vert.shd */
|
||||
static const char const font_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 tex_c;\n"
|
||||
"varying vec2 tex_a;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" gl_Position = mvp * vertex;\n"
|
||||
" col = color;\n"
|
||||
" tex_c = tex_coord;\n"
|
||||
" tex_a = tex_coorda;\n"
|
||||
"}\n";
|
||||
Evas_GL_Program_Source shader_font_mask_vert_src =
|
||||
{
|
||||
font_mask_vert_glsl,
|
||||
NULL, 0
|
||||
};
|
||||
|
||||
/* Source: modules/evas/engines/gl_common/shader/img_12_bgra_frag.shd */
|
||||
static const char const img_12_bgra_frag_glsl[] =
|
||||
"#ifdef GL_ES\n"
|
||||
|
@ -2182,7 +2232,7 @@ Evas_GL_Program_Source shader_yuy2_vert_src =
|
|||
};
|
||||
|
||||
/* Source: modules/evas/engines/gl_common/shader/img_mask_frag.shd */
|
||||
static const char img_mask_frag_glsl[] =
|
||||
static const char const img_mask_frag_glsl[] =
|
||||
"#ifdef GL_ES\n"
|
||||
"#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
|
||||
"precision highp float;\n"
|
||||
|
@ -2207,7 +2257,7 @@ Evas_GL_Program_Source shader_img_mask_frag_src =
|
|||
};
|
||||
|
||||
/* Source: modules/evas/engines/gl_common/shader/img_mask_vert.shd */
|
||||
static const char img_mask_vert_glsl[] =
|
||||
static const char const img_mask_vert_glsl[] =
|
||||
"#ifdef GL_ES\n"
|
||||
"precision highp float;\n"
|
||||
"#endif\n"
|
||||
|
@ -2233,7 +2283,7 @@ Evas_GL_Program_Source shader_img_mask_vert_src =
|
|||
};
|
||||
|
||||
/* Source: modules/evas/engines/gl_common/shader/img_mask_nomul_frag.shd */
|
||||
static const char img_mask_nomul_frag_glsl[] =
|
||||
static const char const img_mask_nomul_frag_glsl[] =
|
||||
"#ifdef GL_ES\n"
|
||||
"#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
|
||||
"precision highp float;\n"
|
||||
|
@ -2257,7 +2307,7 @@ Evas_GL_Program_Source shader_img_mask_nomul_frag_src =
|
|||
};
|
||||
|
||||
/* Source: modules/evas/engines/gl_common/shader/img_mask_nomul_vert.shd */
|
||||
static const char img_mask_nomul_vert_glsl[] =
|
||||
static const char const img_mask_nomul_vert_glsl[] =
|
||||
"#ifdef GL_ES\n"
|
||||
"precision highp float;\n"
|
||||
"#endif\n"
|
||||
|
@ -2286,6 +2336,7 @@ static const struct {
|
|||
const char *name;
|
||||
} _shaders_source[] = {
|
||||
{ SHADER_FONT, &(shader_font_vert_src), &(shader_font_frag_src), "font" },
|
||||
{ SHADER_FONT_MASK, &(shader_font_mask_vert_src), &(shader_font_mask_frag_src), "font_mask" },
|
||||
{ SHADER_IMG_12_BGRA_NOMUL, &(shader_img_12_bgra_nomul_vert_src), &(shader_img_12_bgra_nomul_frag_src), "img_12_bgra_nomul" },
|
||||
{ SHADER_IMG_12_BGRA, &(shader_img_12_bgra_vert_src), &(shader_img_12_bgra_frag_src), "img_12_bgra" },
|
||||
{ SHADER_IMG_12_NOMUL, &(shader_img_12_nomul_vert_src), &(shader_img_12_nomul_frag_src), "img_12_nomul" },
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
#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 tex_c;
|
||||
varying vec2 tex_a;
|
||||
void main()
|
||||
{
|
||||
gl_FragColor = texture2D(tex, tex_c.xy).aaaa * texture2D(texa, tex_a.xy).aaaa * col;
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
#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 tex_c;
|
||||
varying vec2 tex_a;
|
||||
void main()
|
||||
{
|
||||
gl_Position = mvp * vertex;
|
||||
col = color;
|
||||
tex_c = tex_coord;
|
||||
tex_a = tex_coorda;
|
||||
}
|
||||
|
|
@ -1695,6 +1695,60 @@ eng_context_flush(void *data)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
eng_context_clip_image_unset(void *data EINA_UNUSED, void *context)
|
||||
{
|
||||
RGBA_Draw_Context *ctx = context;
|
||||
Evas_GL_Image *im = ctx->clip.mask;
|
||||
|
||||
if (im && im->im)
|
||||
{
|
||||
#ifdef EVAS_CSERVE2
|
||||
if (evas_cserve2_use_get())
|
||||
evas_cache2_image_close(&im->im->cache_entry);
|
||||
else
|
||||
#endif
|
||||
evas_cache_image_drop(&im->im->cache_entry);
|
||||
// Is the above code safe? Hmmm...
|
||||
//evas_unref_queue_image_put(EVAS???, &ctx->clip.ie->cache_entry);
|
||||
}
|
||||
ctx->clip.mask = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
eng_context_clip_image_set(void *data EINA_UNUSED, void *context, void *surface, int x, int y)
|
||||
{
|
||||
RGBA_Draw_Context *ctx = context;
|
||||
Evas_GL_Image *im = surface;
|
||||
|
||||
if (ctx->clip.mask && ctx->clip.mask != surface)
|
||||
eng_context_clip_image_unset(data, context);
|
||||
|
||||
ctx->clip.mask = surface;
|
||||
ctx->clip.mask_x = x;
|
||||
ctx->clip.mask_y = y;
|
||||
|
||||
if (im && im->im)
|
||||
{
|
||||
#ifdef EVAS_CSERVE2
|
||||
if (evas_cserve2_use_get())
|
||||
evas_cache2_image_ref(&im->im->cache_entry);
|
||||
else
|
||||
#endif
|
||||
evas_cache_image_ref(&im->im->cache_entry);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
eng_context_clip_image_get(void *data EINA_UNUSED, void *context, void **ie, int *x, int *y)
|
||||
{
|
||||
RGBA_Draw_Context *ctx = context;
|
||||
|
||||
if (ie) *ie = ctx->clip.mask;
|
||||
if (x) *x = ctx->clip.mask_x;
|
||||
if (y) *y = ctx->clip.mask_y;
|
||||
}
|
||||
|
||||
static void
|
||||
eng_context_3d_use(void *data)
|
||||
{
|
||||
|
@ -1885,6 +1939,10 @@ module_open(Evas_Module *em)
|
|||
func = pfunc;
|
||||
/* now to override methods */
|
||||
#define ORD(f) EVAS_API_OVERRIDE(f, &func, eng_)
|
||||
ORD(context_clip_image_set);
|
||||
ORD(context_clip_image_unset);
|
||||
ORD(context_clip_image_get);
|
||||
|
||||
ORD(rectangle_draw);
|
||||
ORD(line_draw);
|
||||
ORD(polygon_point_add);
|
||||
|
|
Loading…
Reference in New Issue