evas filters: Add "alphaonly" flag for blend and blur

This is very useful to specify precisely which kind of RGBA -> Alpha
conversion you want. If all you wanted was the alpha layer to use as a
mask, set this flag to true.

@feature
This commit is contained in:
Jean-Philippe Andre 2017-12-14 17:22:09 +09:00
parent 8bb03d8170
commit 88bfba1fdd
14 changed files with 194 additions and 71 deletions

View File

@ -734,7 +734,7 @@ evas_filter_command_blur_add_gl(Evas_Filter_Context *ctx,
Evas_Filter_Buffer *in, Evas_Filter_Buffer *out,
Evas_Filter_Blur_Type type,
int rx, int ry, int ox, int oy, int count,
int R, int G, int B, int A)
int R, int G, int B, int A, Eina_Bool alphaonly)
{
Evas_Filter_Command *cmd = NULL;
Evas_Filter_Buffer *dx_in, *dx_out, *dy_in, *dy_out, *tmp = NULL;
@ -798,6 +798,7 @@ evas_filter_command_blur_add_gl(Evas_Filter_Context *ctx,
cmd->draw.scale.pad_y = pad_y;
cmd->draw.scale.factor_x = down_x;
cmd->draw.scale.factor_y = down_y;
cmd->draw.alphaonly = alphaonly;
dx_in = tmp;
tmp = evas_filter_temporary_buffer_get(ctx, ww, hh, in->alpha_only, EINA_TRUE);
@ -827,6 +828,7 @@ evas_filter_command_blur_add_gl(Evas_Filter_Context *ctx,
cmd->blur.type = type;
cmd->blur.dx = dx;
cmd->blur.count = count;
cmd->draw.alphaonly = alphaonly;
}
if (dy)
@ -837,6 +839,7 @@ evas_filter_command_blur_add_gl(Evas_Filter_Context *ctx,
cmd->blur.type = type;
cmd->blur.dy = dy;
cmd->blur.count = count;
cmd->draw.alphaonly = alphaonly;
}
EINA_SAFETY_ON_NULL_RETURN_VAL(cmd, NULL);
@ -852,6 +855,7 @@ evas_filter_command_blur_add_gl(Evas_Filter_Context *ctx,
cmd->draw.scale.pad_y = pad_y;
cmd->draw.scale.factor_x = down_x;
cmd->draw.scale.factor_y = down_y;
cmd->draw.alphaonly = alphaonly;
}
cmd->draw.ox = ox;
@ -886,7 +890,8 @@ _blur_support_gl(Evas_Filter_Context *ctx, Evas_Filter_Buffer *in, Evas_Filter_B
Evas_Filter_Command *
evas_filter_command_blur_add(Evas_Filter_Context *ctx, void *drawctx,
int inbuf, int outbuf, Evas_Filter_Blur_Type type,
int dx, int dy, int ox, int oy, int count)
int dx, int dy, int ox, int oy, int count,
Eina_Bool alphaonly)
{
Evas_Filter_Buffer *in = NULL, *out = NULL, *tmp = NULL, *in_dy = NULL;
Evas_Filter_Buffer *out_dy = NULL, *out_dx = NULL;
@ -904,7 +909,7 @@ evas_filter_command_blur_add(Evas_Filter_Context *ctx, void *drawctx,
if (!dx && !dy)
{
XDBG("Changing 0px blur into simple blend");
return evas_filter_command_blend_add(ctx, drawctx, inbuf, outbuf, ox, oy, EVAS_FILTER_FILL_MODE_NONE);
return evas_filter_command_blend_add(ctx, drawctx, inbuf, outbuf, ox, oy, EVAS_FILTER_FILL_MODE_NONE, alphaonly);
}
in = _filter_buffer_get(ctx, inbuf);
@ -922,7 +927,8 @@ evas_filter_command_blur_add(Evas_Filter_Context *ctx, void *drawctx,
}
if (_blur_support_gl(ctx, in, out))
return evas_filter_command_blur_add_gl(ctx, in, out, type, dx, dy, ox, oy, count, R, G, B, A);
return evas_filter_command_blur_add_gl(ctx, in, out, type, dx, dy, ox, oy,
count, R, G, B, A, alphaonly);
// Note (SW engine):
// The basic blur operation overrides the pixels in the target buffer,
@ -979,7 +985,8 @@ evas_filter_command_blur_add(Evas_Filter_Context *ctx, void *drawctx,
if (dy) ENFN->context_color_set(ENC, drawctx, 255, 255, 255, 255);
cmd = evas_filter_command_blur_add(ctx, drawctx, inbuf, tmp_out,
type, dx, 0, tmp_ox, tmp_oy, 0);
type, dx, 0, tmp_ox, tmp_oy, 0,
alphaonly);
if (!cmd) goto fail;
cmd->blur.auto_count = EINA_TRUE;
if (dy) ENFN->context_color_set(ENC, drawctx, R, G, B, A);
@ -996,7 +1003,8 @@ evas_filter_command_blur_add(Evas_Filter_Context *ctx, void *drawctx,
if (dx && (inbuf == outbuf))
ENFN->context_render_op_set(ENC, drawctx, EVAS_RENDER_COPY);
cmd = evas_filter_command_blur_add(ctx, drawctx, tmp_in, outbuf,
type, 0, dy, ox, oy, 0);
type, 0, dy, ox, oy, 0,
alphaonly);
if (dx && (inbuf == outbuf))
ENFN->context_render_op_set(ENC, drawctx, render_op);
if (!cmd) goto fail;
@ -1145,7 +1153,8 @@ evas_filter_command_blur_add(Evas_Filter_Context *ctx, void *drawctx,
XDBG("Add extra blend %d -> %d", blendbuf->id, out->id);
blendcmd = evas_filter_command_blend_add(ctx, drawctx,
blendbuf->id, out->id, ox, oy,
EVAS_FILTER_FILL_MODE_NONE);
EVAS_FILTER_FILL_MODE_NONE,
alphaonly);
if (!blendcmd) goto fail;
ox = oy = 0;
}
@ -1158,7 +1167,8 @@ evas_filter_command_blur_add(Evas_Filter_Context *ctx, void *drawctx,
ENFN->context_render_op_set(ENC, drawctx, EVAS_RENDER_COPY);
copycmd = evas_filter_command_blend_add(ctx, drawctx,
copybuf->id, out->id, ox, oy,
EVAS_FILTER_FILL_MODE_NONE);
EVAS_FILTER_FILL_MODE_NONE,
alphaonly);
ENFN->context_color_set(ENC, drawctx, R, G, B, A);
ENFN->context_render_op_set(ENC, drawctx, render_op);
if (!copycmd) goto fail;
@ -1178,7 +1188,8 @@ fail:
Evas_Filter_Command *
evas_filter_command_blend_add(Evas_Filter_Context *ctx, void *drawctx,
int inbuf, int outbuf, int ox, int oy,
Evas_Filter_Fill_Mode fillmode)
Evas_Filter_Fill_Mode fillmode,
Eina_Bool alphaonly)
{
Evas_Filter_Command *cmd;
Evas_Filter_Buffer *in, *out;
@ -1221,10 +1232,11 @@ evas_filter_command_blend_add(Evas_Filter_Context *ctx, void *drawctx,
cmd->draw.ox = ox;
cmd->draw.oy = oy;
cmd->draw.rop = copy ? EFL_GFX_RENDER_OP_COPY : EFL_GFX_RENDER_OP_BLEND;
cmd->draw.alphaonly = alphaonly;
cmd->draw.clip_use =
ENFN->context_clip_get(ENC, drawctx,
&cmd->draw.clip.x, &cmd->draw.clip.y,
&cmd->draw.clip.w, &cmd->draw.clip.h);
!!ENFN->context_clip_get(ENC, drawctx,
&cmd->draw.clip.x, &cmd->draw.clip.y,
&cmd->draw.clip.w, &cmd->draw.clip.h);
XDBG("Add %s %d -> %d: offset %d,%d, color: %d,%d,%d,%d",
copy ? "copy" : "blend", in->id, out->id, ox, oy, R, G, B, A);
@ -1238,7 +1250,8 @@ evas_filter_command_blend_add(Evas_Filter_Context *ctx, void *drawctx,
Evas_Filter_Command *
evas_filter_command_grow_add(Evas_Filter_Context *ctx, void *draw_context,
int inbuf, int outbuf, int radius, Eina_Bool smooth)
int inbuf, int outbuf, int radius, Eina_Bool smooth,
Eina_Bool alphaonly)
{
Evas_Filter_Command *blurcmd, *threshcmd, *blendcmd;
Evas_Filter_Buffer *tmp = NULL, *in, *out;
@ -1251,7 +1264,8 @@ evas_filter_command_grow_add(Evas_Filter_Context *ctx, void *draw_context,
if (!radius)
{
XDBG("Changing 0px grow into simple blend");
return evas_filter_command_blend_add(ctx, draw_context, inbuf, outbuf, 0, 0, EVAS_FILTER_FILL_MODE_NONE);
return evas_filter_command_blend_add(ctx, draw_context, inbuf, outbuf, 0, 0,
EVAS_FILTER_FILL_MODE_NONE, alphaonly);
}
in = _filter_buffer_get(ctx, inbuf);
@ -1271,7 +1285,8 @@ evas_filter_command_grow_add(Evas_Filter_Context *ctx, void *draw_context,
blurcmd = evas_filter_command_blur_add(ctx, draw_context, inbuf, growbuf,
EVAS_FILTER_BLUR_DEFAULT,
abs(radius), abs(radius), 0, 0, 0);
abs(radius), abs(radius), 0, 0, 0,
alphaonly);
if (!blurcmd) return NULL;
if (diam > 255) diam = 255;
@ -1309,7 +1324,8 @@ evas_filter_command_grow_add(Evas_Filter_Context *ctx, void *draw_context,
{
blendcmd = evas_filter_command_blend_add(ctx, draw_context, tmp->id,
outbuf, 0, 0,
EVAS_FILTER_FILL_MODE_NONE);
EVAS_FILTER_FILL_MODE_NONE,
alphaonly);
if (!blendcmd)
{
_command_del(ctx, threshcmd);
@ -1375,6 +1391,7 @@ evas_filter_command_displacement_map_add(Evas_Filter_Context *ctx,
{
Evas_Filter_Buffer *in, *out, *map, *tmp = NULL, *disp_out;
Evas_Filter_Command *cmd = NULL;
Eina_Bool alphaonly = EINA_FALSE;
EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, NULL);
EINA_SAFETY_ON_FALSE_RETURN_VAL(intensity >= 0, NULL);
@ -1417,7 +1434,8 @@ evas_filter_command_displacement_map_add(Evas_Filter_Context *ctx,
fillcmd = evas_filter_command_blend_add(ctx, draw_context, disp_out->id,
out->id, 0, 0,
EVAS_FILTER_FILL_MODE_NONE);
EVAS_FILTER_FILL_MODE_NONE,
alphaonly);
if (!fillcmd) goto fail;
}

View File

@ -462,6 +462,23 @@ _instruction_param_geti(Evas_Filter_Instruction *instr, const char *name,
return -1;
}
static Eina_Bool
_instruction_param_getb(Evas_Filter_Instruction *instr, const char *name,
Eina_Bool *isset)
{
Instruction_Param *param;
EINA_INLIST_FOREACH(instr->params, param)
if (!strcasecmp(name, param->name))
{
if (isset) *isset = param->set;
return param->value.b;
}
if (isset) *isset = EINA_FALSE;
return EINA_FALSE;
}
static double
_instruction_param_getd(Evas_Filter_Instruction *instr, const char *name,
Eina_Bool *isset)
@ -970,7 +987,10 @@ _blend_padding_update(Evas_Filter_Program *pgm EINA_UNUSED,
draw the buffer in this color. If both buffers are RGBA, this will
have no effect.
@param fillmode Map the input onto the whole surface of the output by stretching or
repeating it. See @ref evasfilter_fillmode "fillmodes".
repeating it. See @ref evasfilter_fillmode "fillmodes".
@param alphaonly If true, this means all RGBA->Alpha conversions discard the
RGB components entirely, and only use the Alpha channel.
False by default, which means RGB is used as Grey color level.
If @a src is an alpha buffer and @a dst is an RGBA buffer, then the @a color option should be set.
@ -998,6 +1018,7 @@ _blend_instruction_prepare(Evas_Filter_Program *pgm, Evas_Filter_Instruction *in
_instruction_param_seq_add(instr, "oy", VT_INT, 0);
_instruction_param_name_add(instr, "color", VT_COLOR, 0xFFFFFFFF);
_instruction_param_name_add(instr, "fillmode", VT_STRING, "none");
_instruction_param_name_add(instr, "alphaonly", VT_BOOL, EINA_FALSE);
return EINA_TRUE;
}
@ -1122,6 +1143,7 @@ _blur_instruction_prepare(Evas_Filter_Program *pgm, Evas_Filter_Instruction *ins
_instruction_param_name_add(instr, "src", VT_BUFFER, _buffer_get(pgm, "input"));
_instruction_param_name_add(instr, "dst", VT_BUFFER, _buffer_get(pgm, "output"));
_instruction_param_name_add(instr, "count", VT_INT, 0);
_instruction_param_name_add(instr, "alphaonly", VT_BOOL, EINA_FALSE);
return EINA_TRUE;
}
@ -1618,6 +1640,7 @@ _grow_instruction_prepare(Evas_Filter_Program *pgm, Evas_Filter_Instruction *ins
_instruction_param_name_add(instr, "smooth", VT_BOOL, EINA_TRUE);
_instruction_param_name_add(instr, "src", VT_BUFFER, _buffer_get(pgm, "input"));
_instruction_param_name_add(instr, "dst", VT_BUFFER, _buffer_get(pgm, "output"));
_instruction_param_name_add(instr, "alphaonly", VT_BOOL, EINA_FALSE);
return EINA_TRUE;
}
@ -3045,6 +3068,7 @@ _instr2cmd_blend(Evas_Filter_Context *ctx,
Buffer *src, *dst;
Evas_Filter_Fill_Mode fillmode;
int ox, oy, A, R, G, B;
Eina_Bool alphaonly;
ox = _instruction_param_geti(instr, "ox", NULL);
oy = _instruction_param_geti(instr, "oy", NULL);
@ -3052,11 +3076,13 @@ _instr2cmd_blend(Evas_Filter_Context *ctx,
fillmode = _fill_mode_get(instr);
src = _instruction_param_getbuf(instr, "src", NULL);
dst = _instruction_param_getbuf(instr, "dst", NULL);
alphaonly = _instruction_param_getb(instr, "alphaonly", NULL);
INSTR_PARAM_CHECK(src);
INSTR_PARAM_CHECK(dst);
if (isset) SETCOLOR(color);
cmd = evas_filter_command_blend_add(ctx, dc, src->cid, dst->cid, ox, oy, fillmode);
cmd = evas_filter_command_blend_add(ctx, dc, src->cid, dst->cid,
ox, oy, fillmode, alphaonly);
if (isset) RESETCOLOR();
return cmd;
@ -3073,6 +3099,7 @@ _instr2cmd_blur(Evas_Filter_Context *ctx,
DATA32 color;
Buffer *src, *dst;
int ox, oy, rx, ry, A, R, G, B, count;
Eina_Bool alphaonly;
ox = _instruction_param_geti(instr, "ox", NULL);
oy = _instruction_param_geti(instr, "oy", NULL);
@ -3083,6 +3110,7 @@ _instr2cmd_blur(Evas_Filter_Context *ctx,
count = _instruction_param_geti(instr, "count", &cntset);
src = _instruction_param_getbuf(instr, "src", NULL);
dst = _instruction_param_getbuf(instr, "dst", NULL);
alphaonly = _instruction_param_getb(instr, "alphaonly", NULL);
INSTR_PARAM_CHECK(src);
INSTR_PARAM_CHECK(dst);
@ -3116,7 +3144,7 @@ _instr2cmd_blur(Evas_Filter_Context *ctx,
if (!yset) ry = rx;
if (colorset) SETCOLOR(color);
cmd = evas_filter_command_blur_add(ctx, dc, src->cid, dst->cid, type,
rx, ry, ox, oy, count);
rx, ry, ox, oy, count, alphaonly);
if (colorset) RESETCOLOR();
return cmd;
@ -3235,16 +3263,18 @@ _instr2cmd_grow(Evas_Filter_Context *ctx,
Evas_Filter_Command *cmd;
Buffer *src, *dst;
Eina_Bool smooth;
Eina_Bool alphaonly;
int radius;
src = _instruction_param_getbuf(instr, "src", NULL);
dst = _instruction_param_getbuf(instr, "dst", NULL);
radius = _instruction_param_geti(instr, "radius", NULL);
smooth = _instruction_param_geti(instr, "smooth", NULL);
smooth = _instruction_param_getb(instr, "smooth", NULL);
alphaonly = _instruction_param_getb(instr, "alphaonly", NULL);
INSTR_PARAM_CHECK(src);
INSTR_PARAM_CHECK(dst);
cmd = evas_filter_command_grow_add(ctx, dc, src->cid, dst->cid, radius, smooth);
cmd = evas_filter_command_grow_add(ctx, dc, src->cid, dst->cid, radius, smooth, alphaonly);
if (cmd) cmd->draw.need_temp_buffer = EINA_TRUE;
return cmd;

View File

@ -242,6 +242,7 @@ struct _Evas_Filter_Command
Eina_Bool down;
} scale;
Evas_Filter_Fill_Mode fillmode;
Eina_Bool alphaonly : 1;
Eina_Bool clip_use : 1;
Eina_Bool clip_mode_lrtb : 1;
Eina_Bool need_temp_buffer : 1;

View File

@ -180,10 +180,11 @@ void _evas_filter_source_hash_free_cb(void *data);
* @param ox X offset in the destination buffer
* @param oy Y offset in the destination buffer
* @param fillmode Specifies whether to repeat or stretch the input onto its destination, and on which axes
* @param alphaonly If true, discard RGB during RGBA -> Alpha conversions.
* @return Filter command ID or -1 in case of error
* @internal
*/
Evas_Filter_Command *evas_filter_command_blend_add(Evas_Filter_Context *ctx, void *draw_context, int inbuf, int outbuf, int ox, int oy, Evas_Filter_Fill_Mode fillmode);
Evas_Filter_Command *evas_filter_command_blend_add(Evas_Filter_Context *ctx, void *draw_context, int inbuf, int outbuf, int ox, int oy, Evas_Filter_Fill_Mode fillmode, Eina_Bool alphaonly);
/**
* @brief Apply a blur effect on a buffer
@ -197,10 +198,11 @@ Evas_Filter_Command *evas_filter_command_blend_add(Evas_Filter_Context *ctx,
* @param ox X offset in the destination buffer
* @param oy Y offset in the destination buffer
* @param count Number of times to repeat the operation (used for smooth fast blurs with box blur)
* @param alphaonly If true, discard RGB during RGBA -> Alpha conversions.
* @return Filter command ID or -1 in case of error
* @internal
*/
Evas_Filter_Command *evas_filter_command_blur_add(Evas_Filter_Context *ctx, void *draw_context, int inbuf, int outbuf, Evas_Filter_Blur_Type type, int dx, int dy, int ox, int oy, int count);
Evas_Filter_Command *evas_filter_command_blur_add(Evas_Filter_Context *ctx, void *draw_context, int inbuf, int outbuf, Evas_Filter_Blur_Type type, int dx, int dy, int ox, int oy, int count, Eina_Bool alphaonly);
/**
* @brief Fill a buffer with the current color
@ -234,10 +236,11 @@ Evas_Filter_Command *evas_filter_command_curve_add(Evas_Filter_Context *ctx,
* @param outbuf Destination buffer: ALPHA or RGBA (note: must be RGBA if inbuf is RGBA)
* @param radius Number of pixels to grow by. If negative, shrink instead of grow
* @param smooth Use smooth blur and curve for grow (default: true)
* @param alphaonly If true, discard RGB during RGBA -> Alpha conversions.
* @return Filter command ID or -1 in case of error
* @internal
*/
Evas_Filter_Command *evas_filter_command_grow_add(Evas_Filter_Context *ctx, void *draw_context, int inbuf, int outbuf, int radius, Eina_Bool smooth);
Evas_Filter_Command *evas_filter_command_grow_add(Evas_Filter_Context *ctx, void *draw_context, int inbuf, int outbuf, int radius, Eina_Bool smooth, Eina_Bool alphaonly);
/**
* @brief Apply a displacement map to a buffer. This will move pixels from the source to the destination based on pixel per pixel offset, as defined in the displacement map

View File

@ -606,7 +606,7 @@ void evas_gl_common_context_image_push(Evas_Engine_GL_Context *gc,
Evas_GL_Texture *mtex, int mx, int my, int mw, int mh,
Eina_Bool mask_smooth, Eina_Bool mask_color,
int r, int g, int b, int a,
Eina_Bool smooth, Eina_Bool tex_only);
Eina_Bool smooth, Eina_Bool tex_only, Eina_Bool alphaonly);
void evas_gl_common_context_font_push(Evas_Engine_GL_Context *gc,
Evas_GL_Texture *tex,
double sx, double sy, double sw, double sh,
@ -667,13 +667,16 @@ void evas_gl_common_context_image_map_push(Evas_Engine_GL_Context *g
Evas_Colorspace cspace);
// Gfx Filters
void evas_gl_common_filter_blend_push(Evas_Engine_GL_Context *gc, Evas_GL_Texture *tex,
double sx, double sy, double sw, double sh, double dx,
double dy, double dw, double dh, Eina_Bool alphaonly);
void evas_gl_common_filter_displace_push(Evas_Engine_GL_Context *gc, Evas_GL_Texture *tex, Evas_GL_Texture *map_tex,
int x, int y, int w, int h, double dx, double dy, Eina_Bool nearest);
void evas_gl_common_filter_curve_push(Evas_Engine_GL_Context *gc, Evas_GL_Texture *tex,
int x, int y, int w, int h, const uint8_t *points, int channel);
void evas_gl_common_filter_blur_push(Evas_Engine_GL_Context *gc, Evas_GL_Texture *tex, double sx, double sy, double sw, double sh,
double dx, double dy, double dw, double dh, const double * const values, const double * const offsets, int count, double radius,
Eina_Bool horiz);
Eina_Bool horiz, Eina_Bool alphaonly);
int evas_gl_common_shader_program_init(Evas_GL_Shared *shared);
void evas_gl_common_shader_program_shutdown(Evas_GL_Shared *shared);
@ -687,6 +690,7 @@ Evas_GL_Program *evas_gl_common_shader_program_get(Evas_Engine_GL_Context *gc,
Evas_GL_Texture *tex, Eina_Bool tex_only,
Evas_GL_Texture *mtex, Eina_Bool mask_smooth,
Eina_Bool mask_color, int mw, int mh,
Eina_Bool alphaonly,
Shader_Sampling *psam, int *pnomul,
Shader_Sampling *pmasksam);
void evas_gl_common_shader_textures_bind(Evas_GL_Program *p);

View File

@ -1951,7 +1951,8 @@ evas_gl_common_context_line_push(Evas_Engine_GL_Context *gc,
prog = evas_gl_common_shader_program_get(gc, SHD_LINE, NULL, 0, r, g, b, a,
0, 0, 0, 0, EINA_FALSE, NULL, EINA_FALSE,
mtex, mask_smooth, mask_color, mw, mh, NULL, NULL, &masksam);
mtex, mask_smooth, mask_color, mw, mh,
EINA_FALSE, NULL, NULL, &masksam);
pn = _evas_gl_common_context_push(SHD_LINE,
gc, NULL, mtex,
@ -2015,7 +2016,8 @@ evas_gl_common_context_rectangle_push(Evas_Engine_GL_Context *gc,
prog = evas_gl_common_shader_program_get(gc, SHD_RECT, NULL, 0, r, g, b, a,
0, 0, 0, 0, EINA_FALSE, NULL, EINA_FALSE,
mtex, mask_smooth, mask_color, mw, mh, NULL, NULL, &masksam);
mtex, mask_smooth, mask_color, mw, mh,
EINA_FALSE, NULL, NULL, &masksam);
pn = _evas_gl_common_context_push(SHD_RECT,
@ -2177,7 +2179,8 @@ evas_gl_common_context_image_push(Evas_Engine_GL_Context *gc,
Evas_GL_Texture *mtex, int mx, int my, int mw, int mh,
Eina_Bool mask_smooth, Eina_Bool mask_color,
int r, int g, int b, int a,
Eina_Bool smooth, Eina_Bool tex_only)
Eina_Bool smooth, Eina_Bool tex_only,
Eina_Bool alphaonly)
{
Evas_GL_Texture_Pool *pt;
@ -2213,7 +2216,7 @@ evas_gl_common_context_image_push(Evas_Engine_GL_Context *gc,
prog = evas_gl_common_shader_program_get(gc, shd_in, NULL, 0, r, g, b, a,
sw, sh, w, h, smooth, tex, tex_only,
mtex, mask_smooth, mask_color, mw, mh,
&sam, &nomul, &masksam);
alphaonly, &sam, &nomul, &masksam);
if (tex->ptt)
{
@ -2435,7 +2438,7 @@ evas_gl_common_context_font_push(Evas_Engine_GL_Context *gc,
prog = evas_gl_common_shader_program_get(gc, SHD_FONT, NULL, 0, r, g, b, a,
sw, sh, w, h, EINA_FALSE, tex, EINA_FALSE,
mtex, mask_smooth, mask_color, mw, mh,
NULL, NULL, &masksam);
EINA_FALSE, NULL, NULL, &masksam);
pn = _evas_gl_common_context_push(SHD_FONT,
gc, tex, mtex,
@ -2515,7 +2518,7 @@ evas_gl_common_context_yuv_push(Evas_Engine_GL_Context *gc,
prog = evas_gl_common_shader_program_get(gc, SHD_YUV, NULL, 0, r, g, b, a,
w, h, w, h, smooth, tex, 0,
mtex, mask_smooth, mask_color, mw, mh,
NULL, &nomul, &masksam);
EINA_FALSE, NULL, &nomul, &masksam);
pn = _evas_gl_common_context_push(SHD_YUV,
gc, tex, mtex,
@ -2595,7 +2598,7 @@ evas_gl_common_context_yuv_709_push(Evas_Engine_GL_Context *gc,
prog = evas_gl_common_shader_program_get(gc, SHD_YUV_709, NULL, 0, r, g, b, a,
w, h, w, h, smooth, tex, 0,
mtex, mask_smooth, mask_color, mw, mh,
NULL, &nomul, &masksam);
EINA_FALSE, NULL, &nomul, &masksam);
pn = _evas_gl_common_context_push(SHD_YUV_709,
gc, tex, mtex,
@ -2675,7 +2678,7 @@ evas_gl_common_context_yuy2_push(Evas_Engine_GL_Context *gc,
prog = evas_gl_common_shader_program_get(gc, SHD_YUY2, NULL, 0, r, g, b, a,
sw, sh, w, h, smooth, tex, 0,
mtex, mask_smooth, mask_color, mw, mh,
NULL, &nomul, &masksam);
EINA_FALSE, NULL, &nomul, &masksam);
pn = _evas_gl_common_context_push(SHD_YUY2,
gc, tex, mtex,
@ -2753,7 +2756,7 @@ evas_gl_common_context_nv12_push(Evas_Engine_GL_Context *gc,
prog = evas_gl_common_shader_program_get(gc, SHD_NV12, NULL, 0, r, g, b, a,
sw, sh, w, h, smooth, tex, 0,
mtex, mask_smooth, mask_color, mw, mh,
NULL, &nomul, &masksam);
EINA_FALSE, NULL, &nomul, &masksam);
pn = _evas_gl_common_context_push(SHD_NV12,
gc, tex, mtex,
@ -2838,7 +2841,7 @@ evas_gl_common_context_rgb_a_pair_push(Evas_Engine_GL_Context *gc,
prog = evas_gl_common_shader_program_get(gc, SHD_RGB_A_PAIR, NULL, 0, r, g, b, a,
sw, sh, w, h, smooth, tex, 0,
mtex, mask_smooth, mask_color, mw, mh,
NULL, &nomul, &masksam);
EINA_FALSE, NULL, &nomul, &masksam);
pn = _evas_gl_common_context_push(SHD_RGB_A_PAIR,
gc, tex, mtex,
@ -2969,7 +2972,7 @@ evas_gl_common_context_image_map_push(Evas_Engine_GL_Context *gc,
prog = evas_gl_common_shader_program_get(gc, type, p, npoints, r, g, b, a,
w, h, w, h, smooth, tex, tex_only,
mtex, mask_smooth, mask_color, mw, mh,
NULL, &nomul, &masksam);
EINA_FALSE, NULL, &nomul, &masksam);
x = w = (p[0].x >> FP);
y = h = (p[0].y >> FP);
@ -3230,7 +3233,7 @@ evas_gl_common_filter_displace_push(Evas_Engine_GL_Context *gc,
prog = evas_gl_common_shader_program_get(gc, SHD_FILTER_DISPLACE, NULL, 0, r, g, b, a,
w, h, w, h, smooth, tex, EINA_FALSE,
NULL, EINA_FALSE, EINA_FALSE, 0, 0,
&sam, &nomul, NULL);
EINA_FALSE, &sam, &nomul, NULL);
_filter_data_flush(gc, prog);
pn = _evas_gl_common_context_push(SHD_FILTER_DISPLACE, gc, tex, NULL, prog,
@ -3349,7 +3352,7 @@ evas_gl_common_filter_curve_push(Evas_Engine_GL_Context *gc,
prog = evas_gl_common_shader_program_get(gc, SHD_FILTER_CURVE, NULL, 0, r, g, b, a,
w, h, w, h, smooth, tex, EINA_FALSE,
NULL, EINA_FALSE, EINA_FALSE, 0, 0,
&sam, &nomul, NULL);
EINA_FALSE, &sam, &nomul, NULL);
_filter_data_flush(gc, prog);
pn = _evas_gl_common_context_push(SHD_FILTER_CURVE, gc, tex, NULL, prog,
@ -3474,6 +3477,28 @@ evas_gl_common_filter_curve_push(Evas_Engine_GL_Context *gc,
PUSH_6_COLORS(pn, r, g, b, a);
}
void
evas_gl_common_filter_blend_push(Evas_Engine_GL_Context *gc,
Evas_GL_Texture *tex,
double sx, double sy, double sw, double sh,
double dx, double dy, double dw, double dh,
Eina_Bool alphaonly)
{
int r, g, b, a;
r = R_VAL(&gc->dc->mul.col);
g = G_VAL(&gc->dc->mul.col);
b = B_VAL(&gc->dc->mul.col);
a = A_VAL(&gc->dc->mul.col);
if (alphaonly)
r = g = b = a;
evas_gl_common_context_image_push(gc, tex, sx, sy, sw, sh, dx, dy, dw, dh,
NULL, 0, 0, 0, 0, EINA_FALSE, EINA_FALSE,
r, g, b, a, EINA_TRUE, EINA_FALSE,
alphaonly);
}
void
evas_gl_common_filter_blur_push(Evas_Engine_GL_Context *gc,
Evas_GL_Texture *tex,
@ -3481,7 +3506,7 @@ evas_gl_common_filter_blur_push(Evas_Engine_GL_Context *gc,
double dx, double dy, double dw, double dh,
const double * const weights,
const double * const offsets, int count,
double radius, Eina_Bool horiz)
double radius, Eina_Bool horiz, Eina_Bool alphaonly)
{
double ox1, oy1, ox2, oy2, ox3, oy3, ox4, oy4, pw, ph, texlen;
GLfloat tx1, ty1, tx2, ty2, tx3, ty3, tx4, ty4;
@ -3505,7 +3530,7 @@ evas_gl_common_filter_blur_push(Evas_Engine_GL_Context *gc,
prog = evas_gl_common_shader_program_get(gc, type, NULL, 0, r, g, b, a,
sw, sh, dw, dh, smooth, tex, EINA_FALSE,
NULL, EINA_FALSE, EINA_FALSE, 0, 0,
NULL, &nomul, NULL);
alphaonly, NULL, &nomul, NULL);
_filter_data_flush(gc, prog);
EINA_SAFETY_ON_NULL_RETURN(prog);

View File

@ -1321,7 +1321,7 @@ _evas_gl_common_image_push(Evas_Engine_GL_Context *gc, Evas_GL_Image *im,
dx, dy, dw, dh,
mtex, mx, my, mw, mh, mask_smooth, mask_color,
r, g, b, a,
smooth, im->tex_only);
smooth, im->tex_only, EINA_FALSE);
return;
}
@ -1377,11 +1377,14 @@ _evas_gl_common_image_push(Evas_Engine_GL_Context *gc, Evas_GL_Image *im,
nx, ny, nw, nh,
mtex, mx, my, mw, mh, mask_smooth, mask_color,
r, g, b, a,
smooth, im->tex_only);
smooth, im->tex_only, EINA_FALSE);
}
void
evas_gl_common_image_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im, int sx, int sy, int sw, int sh, int dx, int dy, int dw, int dh, int smooth)
evas_gl_common_image_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im,
int sx, int sy, int sw, int sh,
int dx, int dy, int dw, int dh,
int smooth)
{
RGBA_Draw_Context *dc;
int r, g, b, a;
@ -1401,9 +1404,9 @@ evas_gl_common_image_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im, int sx,
if (dc->mul.use)
{
a = (dc->mul.col >> 24) & 0xff;
r = (dc->mul.col >> 16) & 0xff;
g = (dc->mul.col >> 8 ) & 0xff;
b = (dc->mul.col ) & 0xff;
r = (dc->mul.col >> 16) & 0xff;
g = (dc->mul.col >> 8 ) & 0xff;
b = (dc->mul.col ) & 0xff;
}
else
{

View File

@ -44,8 +44,9 @@ typedef enum {
SHADER_FLAG_FILTER_CURVE = (1 << 22),
SHADER_FLAG_FILTER_BLUR = (1 << 23),
SHADER_FLAG_FILTER_DIR_Y = (1 << 24),
SHADER_FLAG_FILTER_ALPHA_ONLY = (1 << 25),
} Shader_Flag;
#define SHADER_FLAG_COUNT 25
#define SHADER_FLAG_COUNT 26
static const char *_shader_flags[SHADER_FLAG_COUNT] = {
"TEX",
@ -73,6 +74,7 @@ static const char *_shader_flags[SHADER_FLAG_COUNT] = {
"FILTER_CURVE",
"FILTER_BLUR",
"FILTER_DIR_Y",
"ALPHA_ONLY",
};
static Eina_Bool compiler_released = EINA_FALSE;
@ -734,6 +736,7 @@ evas_gl_common_shader_flags_get(Evas_GL_Shared *shared, Shader_Type type,
Evas_GL_Texture *tex, Eina_Bool tex_only,
Evas_GL_Texture *mtex, Eina_Bool mask_smooth,
Eina_Bool mask_color, int mw, int mh,
Eina_Bool alphaonly,
Shader_Sampling *psam, int *pnomul, Shader_Sampling *pmasksam)
{
Shader_Sampling sam = SHD_SAM11, masksam = SHD_SAM11;
@ -818,6 +821,9 @@ evas_gl_common_shader_flags_get(Evas_GL_Shared *shared, Shader_Type type,
return 0;
}
if (alphaonly)
flags |= SHADER_FLAG_FILTER_ALPHA_ONLY;
// color mul
if ((a == 255) && (r == 255) && (g == 255) && (b == 255))
{
@ -953,6 +959,7 @@ evas_gl_common_shader_program_get(Evas_Engine_GL_Context *gc,
Evas_GL_Texture *tex, Eina_Bool tex_only,
Evas_GL_Texture *mtex, Eina_Bool mask_smooth,
Eina_Bool mask_color, int mw, int mh,
Eina_Bool alphaonly,
Shader_Sampling *psam, int *pnomul,
Shader_Sampling *pmasksam)
{
@ -962,7 +969,7 @@ evas_gl_common_shader_program_get(Evas_Engine_GL_Context *gc,
flags = evas_gl_common_shader_flags_get(gc->shared, type, map_points, npoints, r, g, b, a,
sw, sh, w, h, smooth, tex, tex_only,
mtex, mask_smooth, mask_color, mw, mh,
psam, pnomul, pmasksam);
alphaonly, psam, pnomul, pmasksam);
p = eina_hash_find(gc->shared->shaders_hash, &flags);
if (!p)
{

View File

@ -211,6 +211,9 @@ static const char fragment_glsl[] =
" texture2D(tex_filter, vec2(c.b / old_alpha, 0.0)).b * new_alpha,\n"
" new_alpha);\n"
"#endif\n"
"#ifdef SHD_ALPHA_ONLY\n"
" c = vec4(c.a, c.a, c.a, c.a);\n"
"#endif\n"
"#ifndef SHD_FILTER_BLUR\n"
" gl_FragColor =\n"
" c\n"

View File

@ -226,6 +226,10 @@ vec4 fetch_pixel(float ox, float oy)
new_alpha);
#endif
#ifdef SHD_ALPHA_ONLY
c = vec4(c.a, c.a, c.a, c.a);
#endif
#ifndef SHD_FILTER_BLUR
gl_FragColor =

View File

@ -6,7 +6,8 @@ _mapped_blend(Evas_Engine_GL_Context *gc,
Evas_GL_Image *image,
Evas_Filter_Fill_Mode fillmode,
int sx, int sy, int sw, int sh,
int dx, int dy, int dw, int dh)
int dx, int dy, int dw, int dh,
Eina_Bool alphaonly)
{
int right = 0, bottom = 0, left = 0, top = 0;
int row, col, rows, cols;
@ -15,7 +16,7 @@ _mapped_blend(Evas_Engine_GL_Context *gc,
if (fillmode == EVAS_FILTER_FILL_MODE_NONE)
{
DBG("blend: %d,%d,%d,%d --> %d,%d,%d,%d", sx, sy, sw, sh, dx, dy, sw, sh);
evas_gl_common_image_draw(gc, image, sx, sy, sw, sh, dx, dy, sw, sh, EINA_TRUE);
evas_gl_common_filter_blend_push(gc, image->tex, sx, sy, sw, sh, dx, dy, sw, sh, alphaonly);
return EINA_TRUE;
}
@ -148,8 +149,8 @@ _mapped_blend(Evas_Engine_GL_Context *gc,
"(src %dx%d, dst %dx%d)",
col, row, src_x, src_y, src_w, src_h,
dst_x, dst_y, dst_w, dst_h, sw, sh, dw, dh);
evas_gl_common_image_draw(gc, image, src_x, src_y, src_w, src_h,
dst_x, dst_y, dst_w, dst_h, EINA_TRUE);
evas_gl_common_filter_blend_push(gc, image->tex, src_x, src_y, src_w, src_h,
dst_x, dst_y, dst_w, dst_h, alphaonly);
}
}
return ret;
@ -169,6 +170,7 @@ _gl_filter_blend(Render_Engine_GL_Generic *re, Evas_Filter_Command *cmd)
image = evas_ector_buffer_drawable_image_get(cmd->input->buffer);
EINA_SAFETY_ON_NULL_RETURN_VAL(image, EINA_FALSE);
EINA_SAFETY_ON_NULL_RETURN_VAL(image->tex, EINA_FALSE);
surface = evas_ector_buffer_render_image_get(cmd->output->buffer);
EINA_SAFETY_ON_NULL_RETURN_VAL(surface, EINA_FALSE);
@ -232,7 +234,8 @@ _gl_filter_blend(Render_Engine_GL_Generic *re, Evas_Filter_Command *cmd)
cmd->output->id, cmd->output->buffer);
_mapped_blend(gc, image, cmd->draw.fillmode,
src_x, src_y, src_w, src_h,
dst_x, dst_y, dst_w, dst_h);
dst_x, dst_y, dst_w, dst_h,
cmd->draw.alphaonly);
evas_common_draw_context_free(gc->dc);
gc->dc = dc_save;

View File

@ -248,7 +248,8 @@ _gl_filter_blur(Render_Engine_GL_Generic *re, Evas_Filter_Command *cmd)
ssh = ((double)sh * (double)(nh)) / (double)(dh);
evas_gl_common_filter_blur_push(gc, image->tex, ssx, ssy, ssw, ssh, dx, dy, dw, dh,
weights, offsets, count, radius, horiz);
weights, offsets, count, radius, horiz,
cmd->draw.alphaonly);
}
free(weights);

View File

@ -50,7 +50,8 @@ _gl_filter_mask(Render_Engine_GL_Generic *re, Evas_Filter_Command *cmd)
gc->dc->clip.mask_x = x;
gc->dc->clip.mask_y = y;
evas_gl_common_image_draw(gc, image, x, y, sw, sh, x, y, sw, sh, EINA_TRUE);
evas_gl_common_filter_blend_push(gc, image->tex, x, y, sw, sh, x, y, sw, sh,
cmd->draw.alphaonly);
}
evas_gl_common_image_free(use_mask);

View File

@ -8,11 +8,12 @@
typedef Eina_Bool (*draw_func) (void *context, const void *src_map, unsigned int src_stride, void *dst_map, unsigned int dst_stride, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int dst_w, int dst_h, int smooth, Eina_Bool do_async);
static Eina_Bool _mapped_blend(void *drawctx, const void *src_map, unsigned int src_stride, void *dst_map, unsigned int dst_stride, Evas_Filter_Fill_Mode fillmode, int sx, int sy, int sw, int sh, int dx, int dy, int dw, int dh, draw_func image_draw);
struct Filter_Blend_Draw_Context
typedef struct _Filter_Blend_Draw_Context
{
Efl_Gfx_Render_Op rop;
uint32_t color;
};
Eina_Bool alphaonly;
} Filter_Blend_Draw_Context;
#define LINELEN(stride, ptr) (stride / (sizeof(*ptr)))
@ -25,7 +26,7 @@ _image_draw_cpu_alpha_alpha(void *context,
int smooth EINA_UNUSED,
Eina_Bool do_async EINA_UNUSED)
{
struct Filter_Blend_Draw_Context *dc = context;
Filter_Blend_Draw_Context *dc = context;
const uint8_t *srcdata = src_map;
uint8_t *dstdata = dst_map;
Draw_Func_Alpha func;
@ -60,7 +61,7 @@ _image_draw_cpu_alpha_rgba(void *context,
int smooth EINA_UNUSED,
Eina_Bool do_async EINA_UNUSED)
{
struct Filter_Blend_Draw_Context *dc = context;
Filter_Blend_Draw_Context *dc = context;
uint8_t *srcdata = (uint8_t *) src_map;
uint32_t *dstdata = dst_map;
RGBA_Comp_Func_Mask func;
@ -95,7 +96,7 @@ _image_draw_cpu_rgba_rgba(void *context,
int smooth EINA_UNUSED,
Eina_Bool do_async EINA_UNUSED)
{
struct Filter_Blend_Draw_Context *dc = context;
Filter_Blend_Draw_Context *dc = context;
uint32_t *srcdata = (uint32_t *) src_map;
uint32_t *dstdata = dst_map;
RGBA_Comp_Func func;
@ -125,7 +126,7 @@ _image_draw_cpu_rgba_rgba(void *context,
}
static Eina_Bool
_image_draw_cpu_rgba_alpha(void *context EINA_UNUSED,
_image_draw_cpu_rgba_alpha(void *context,
const void *src_map, unsigned int src_stride,
void *dst_map, unsigned int dst_stride,
int src_x, int src_y, int src_w, int src_h,
@ -133,6 +134,8 @@ _image_draw_cpu_rgba_alpha(void *context EINA_UNUSED,
int smooth EINA_UNUSED,
Eina_Bool do_async EINA_UNUSED)
{
Filter_Blend_Draw_Context *dc = context;
Eina_Bool alphaonly = dc && dc->alphaonly;
uint32_t *srcdata = (uint32_t *) src_map;
uint8_t *dstdata = dst_map;
int x, y, sw, dw;
@ -156,14 +159,30 @@ _image_draw_cpu_rgba_alpha(void *context EINA_UNUSED,
srcdata += src_y * sw;
dstdata += dst_y * dw;
for (y = src_h; y; y--)
if (!alphaonly)
{
uint32_t *s = srcdata + src_x;
uint8_t *d = dstdata + dst_x;
for (x = src_w; x; x--, d++, s++)
*d = DIVIDE((R_VAL(s) * WR) + (G_VAL(s) * WG) + (B_VAL(s) * WB));
srcdata += sw;
dstdata += dw;
for (y = src_h; y; y--)
{
uint32_t *s = srcdata + src_x;
uint8_t *d = dstdata + dst_x;
for (x = src_w; x; x--, d++, s++)
*d = (uint8_t) DIVIDE((R_VAL(s) * WR) + (G_VAL(s) * WG) + (B_VAL(s) * WB));
srcdata += sw;
dstdata += dw;
}
}
else
{
for (y = src_h; y; y--)
{
uint32_t *s = srcdata + src_x;
uint8_t *d = dstdata + dst_x;
for (x = src_w; x; x--, d++, s++)
*d = A_VAL(s);
srcdata += sw;
dstdata += dw;
}
}
return EINA_TRUE;
@ -174,7 +193,7 @@ _filter_blend_cpu_generic_do(Evas_Filter_Command *cmd, draw_func image_draw)
{
unsigned int src_len, src_stride, dst_len, dst_stride;
int sw, sh, dx, dy, dw, dh, sx, sy;
struct Filter_Blend_Draw_Context dc;
Filter_Blend_Draw_Context dc;
Eina_Bool ret = EINA_FALSE;
Evas_Filter_Buffer *src_fb;
void *src = NULL, *dst = NULL;
@ -220,6 +239,7 @@ _filter_blend_cpu_generic_do(Evas_Filter_Command *cmd, draw_func image_draw)
EINA_SAFETY_ON_FALSE_GOTO(src && dst, end);
dc.rop = cmd->draw.rop;
dc.alphaonly = cmd->draw.alphaonly;
dc.color = ARGB_JOIN(cmd->draw.A, cmd->draw.R, cmd->draw.G, cmd->draw.B);
ret = _mapped_blend(&dc, src, src_stride, dst, dst_stride, cmd->draw.fillmode,