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_Buffer *in, Evas_Filter_Buffer *out,
Evas_Filter_Blur_Type type, Evas_Filter_Blur_Type type,
int rx, int ry, int ox, int oy, int count, 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_Command *cmd = NULL;
Evas_Filter_Buffer *dx_in, *dx_out, *dy_in, *dy_out, *tmp = 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.pad_y = pad_y;
cmd->draw.scale.factor_x = down_x; cmd->draw.scale.factor_x = down_x;
cmd->draw.scale.factor_y = down_y; cmd->draw.scale.factor_y = down_y;
cmd->draw.alphaonly = alphaonly;
dx_in = tmp; dx_in = tmp;
tmp = evas_filter_temporary_buffer_get(ctx, ww, hh, in->alpha_only, EINA_TRUE); 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.type = type;
cmd->blur.dx = dx; cmd->blur.dx = dx;
cmd->blur.count = count; cmd->blur.count = count;
cmd->draw.alphaonly = alphaonly;
} }
if (dy) if (dy)
@ -837,6 +839,7 @@ evas_filter_command_blur_add_gl(Evas_Filter_Context *ctx,
cmd->blur.type = type; cmd->blur.type = type;
cmd->blur.dy = dy; cmd->blur.dy = dy;
cmd->blur.count = count; cmd->blur.count = count;
cmd->draw.alphaonly = alphaonly;
} }
EINA_SAFETY_ON_NULL_RETURN_VAL(cmd, NULL); 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.pad_y = pad_y;
cmd->draw.scale.factor_x = down_x; cmd->draw.scale.factor_x = down_x;
cmd->draw.scale.factor_y = down_y; cmd->draw.scale.factor_y = down_y;
cmd->draw.alphaonly = alphaonly;
} }
cmd->draw.ox = ox; 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 *
evas_filter_command_blur_add(Evas_Filter_Context *ctx, void *drawctx, evas_filter_command_blur_add(Evas_Filter_Context *ctx, void *drawctx,
int inbuf, int outbuf, Evas_Filter_Blur_Type type, 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 *in = NULL, *out = NULL, *tmp = NULL, *in_dy = NULL;
Evas_Filter_Buffer *out_dy = NULL, *out_dx = 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) if (!dx && !dy)
{ {
XDBG("Changing 0px blur into simple blend"); 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); 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)) 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): // Note (SW engine):
// The basic blur operation overrides the pixels in the target buffer, // 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); if (dy) ENFN->context_color_set(ENC, drawctx, 255, 255, 255, 255);
cmd = evas_filter_command_blur_add(ctx, drawctx, inbuf, tmp_out, 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; if (!cmd) goto fail;
cmd->blur.auto_count = EINA_TRUE; cmd->blur.auto_count = EINA_TRUE;
if (dy) ENFN->context_color_set(ENC, drawctx, R, G, B, A); 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)) if (dx && (inbuf == outbuf))
ENFN->context_render_op_set(ENC, drawctx, EVAS_RENDER_COPY); ENFN->context_render_op_set(ENC, drawctx, EVAS_RENDER_COPY);
cmd = evas_filter_command_blur_add(ctx, drawctx, tmp_in, outbuf, 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)) if (dx && (inbuf == outbuf))
ENFN->context_render_op_set(ENC, drawctx, render_op); ENFN->context_render_op_set(ENC, drawctx, render_op);
if (!cmd) goto fail; 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); XDBG("Add extra blend %d -> %d", blendbuf->id, out->id);
blendcmd = evas_filter_command_blend_add(ctx, drawctx, blendcmd = evas_filter_command_blend_add(ctx, drawctx,
blendbuf->id, out->id, ox, oy, blendbuf->id, out->id, ox, oy,
EVAS_FILTER_FILL_MODE_NONE); EVAS_FILTER_FILL_MODE_NONE,
alphaonly);
if (!blendcmd) goto fail; if (!blendcmd) goto fail;
ox = oy = 0; 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); ENFN->context_render_op_set(ENC, drawctx, EVAS_RENDER_COPY);
copycmd = evas_filter_command_blend_add(ctx, drawctx, copycmd = evas_filter_command_blend_add(ctx, drawctx,
copybuf->id, out->id, ox, oy, 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_color_set(ENC, drawctx, R, G, B, A);
ENFN->context_render_op_set(ENC, drawctx, render_op); ENFN->context_render_op_set(ENC, drawctx, render_op);
if (!copycmd) goto fail; if (!copycmd) goto fail;
@ -1178,7 +1188,8 @@ fail:
Evas_Filter_Command * Evas_Filter_Command *
evas_filter_command_blend_add(Evas_Filter_Context *ctx, void *drawctx, evas_filter_command_blend_add(Evas_Filter_Context *ctx, void *drawctx,
int inbuf, int outbuf, int ox, int oy, 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_Command *cmd;
Evas_Filter_Buffer *in, *out; 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.ox = ox;
cmd->draw.oy = oy; cmd->draw.oy = oy;
cmd->draw.rop = copy ? EFL_GFX_RENDER_OP_COPY : EFL_GFX_RENDER_OP_BLEND; cmd->draw.rop = copy ? EFL_GFX_RENDER_OP_COPY : EFL_GFX_RENDER_OP_BLEND;
cmd->draw.alphaonly = alphaonly;
cmd->draw.clip_use = cmd->draw.clip_use =
ENFN->context_clip_get(ENC, drawctx, !!ENFN->context_clip_get(ENC, drawctx,
&cmd->draw.clip.x, &cmd->draw.clip.y, &cmd->draw.clip.x, &cmd->draw.clip.y,
&cmd->draw.clip.w, &cmd->draw.clip.h); &cmd->draw.clip.w, &cmd->draw.clip.h);
XDBG("Add %s %d -> %d: offset %d,%d, color: %d,%d,%d,%d", 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); 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 *
evas_filter_command_grow_add(Evas_Filter_Context *ctx, void *draw_context, 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_Command *blurcmd, *threshcmd, *blendcmd;
Evas_Filter_Buffer *tmp = NULL, *in, *out; 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) if (!radius)
{ {
XDBG("Changing 0px grow into simple blend"); 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); 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, blurcmd = evas_filter_command_blur_add(ctx, draw_context, inbuf, growbuf,
EVAS_FILTER_BLUR_DEFAULT, EVAS_FILTER_BLUR_DEFAULT,
abs(radius), abs(radius), 0, 0, 0); abs(radius), abs(radius), 0, 0, 0,
alphaonly);
if (!blurcmd) return NULL; if (!blurcmd) return NULL;
if (diam > 255) diam = 255; 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, blendcmd = evas_filter_command_blend_add(ctx, draw_context, tmp->id,
outbuf, 0, 0, outbuf, 0, 0,
EVAS_FILTER_FILL_MODE_NONE); EVAS_FILTER_FILL_MODE_NONE,
alphaonly);
if (!blendcmd) if (!blendcmd)
{ {
_command_del(ctx, threshcmd); _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_Buffer *in, *out, *map, *tmp = NULL, *disp_out;
Evas_Filter_Command *cmd = NULL; Evas_Filter_Command *cmd = NULL;
Eina_Bool alphaonly = EINA_FALSE;
EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, NULL); EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, NULL);
EINA_SAFETY_ON_FALSE_RETURN_VAL(intensity >= 0, 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, fillcmd = evas_filter_command_blend_add(ctx, draw_context, disp_out->id,
out->id, 0, 0, out->id, 0, 0,
EVAS_FILTER_FILL_MODE_NONE); EVAS_FILTER_FILL_MODE_NONE,
alphaonly);
if (!fillcmd) goto fail; if (!fillcmd) goto fail;
} }

View File

@ -462,6 +462,23 @@ _instruction_param_geti(Evas_Filter_Instruction *instr, const char *name,
return -1; 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 static double
_instruction_param_getd(Evas_Filter_Instruction *instr, const char *name, _instruction_param_getd(Evas_Filter_Instruction *instr, const char *name,
Eina_Bool *isset) 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 draw the buffer in this color. If both buffers are RGBA, this will
have no effect. have no effect.
@param fillmode Map the input onto the whole surface of the output by stretching or @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. 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_seq_add(instr, "oy", VT_INT, 0);
_instruction_param_name_add(instr, "color", VT_COLOR, 0xFFFFFFFF); _instruction_param_name_add(instr, "color", VT_COLOR, 0xFFFFFFFF);
_instruction_param_name_add(instr, "fillmode", VT_STRING, "none"); _instruction_param_name_add(instr, "fillmode", VT_STRING, "none");
_instruction_param_name_add(instr, "alphaonly", VT_BOOL, EINA_FALSE);
return EINA_TRUE; 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, "src", VT_BUFFER, _buffer_get(pgm, "input"));
_instruction_param_name_add(instr, "dst", VT_BUFFER, _buffer_get(pgm, "output")); _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, "count", VT_INT, 0);
_instruction_param_name_add(instr, "alphaonly", VT_BOOL, EINA_FALSE);
return EINA_TRUE; 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, "smooth", VT_BOOL, EINA_TRUE);
_instruction_param_name_add(instr, "src", VT_BUFFER, _buffer_get(pgm, "input")); _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, "dst", VT_BUFFER, _buffer_get(pgm, "output"));
_instruction_param_name_add(instr, "alphaonly", VT_BOOL, EINA_FALSE);
return EINA_TRUE; return EINA_TRUE;
} }
@ -3045,6 +3068,7 @@ _instr2cmd_blend(Evas_Filter_Context *ctx,
Buffer *src, *dst; Buffer *src, *dst;
Evas_Filter_Fill_Mode fillmode; Evas_Filter_Fill_Mode fillmode;
int ox, oy, A, R, G, B; int ox, oy, A, R, G, B;
Eina_Bool alphaonly;
ox = _instruction_param_geti(instr, "ox", NULL); ox = _instruction_param_geti(instr, "ox", NULL);
oy = _instruction_param_geti(instr, "oy", NULL); oy = _instruction_param_geti(instr, "oy", NULL);
@ -3052,11 +3076,13 @@ _instr2cmd_blend(Evas_Filter_Context *ctx,
fillmode = _fill_mode_get(instr); fillmode = _fill_mode_get(instr);
src = _instruction_param_getbuf(instr, "src", NULL); src = _instruction_param_getbuf(instr, "src", NULL);
dst = _instruction_param_getbuf(instr, "dst", NULL); dst = _instruction_param_getbuf(instr, "dst", NULL);
alphaonly = _instruction_param_getb(instr, "alphaonly", NULL);
INSTR_PARAM_CHECK(src); INSTR_PARAM_CHECK(src);
INSTR_PARAM_CHECK(dst); INSTR_PARAM_CHECK(dst);
if (isset) SETCOLOR(color); 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(); if (isset) RESETCOLOR();
return cmd; return cmd;
@ -3073,6 +3099,7 @@ _instr2cmd_blur(Evas_Filter_Context *ctx,
DATA32 color; DATA32 color;
Buffer *src, *dst; Buffer *src, *dst;
int ox, oy, rx, ry, A, R, G, B, count; int ox, oy, rx, ry, A, R, G, B, count;
Eina_Bool alphaonly;
ox = _instruction_param_geti(instr, "ox", NULL); ox = _instruction_param_geti(instr, "ox", NULL);
oy = _instruction_param_geti(instr, "oy", 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); count = _instruction_param_geti(instr, "count", &cntset);
src = _instruction_param_getbuf(instr, "src", NULL); src = _instruction_param_getbuf(instr, "src", NULL);
dst = _instruction_param_getbuf(instr, "dst", NULL); dst = _instruction_param_getbuf(instr, "dst", NULL);
alphaonly = _instruction_param_getb(instr, "alphaonly", NULL);
INSTR_PARAM_CHECK(src); INSTR_PARAM_CHECK(src);
INSTR_PARAM_CHECK(dst); INSTR_PARAM_CHECK(dst);
@ -3116,7 +3144,7 @@ _instr2cmd_blur(Evas_Filter_Context *ctx,
if (!yset) ry = rx; if (!yset) ry = rx;
if (colorset) SETCOLOR(color); if (colorset) SETCOLOR(color);
cmd = evas_filter_command_blur_add(ctx, dc, src->cid, dst->cid, type, 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(); if (colorset) RESETCOLOR();
return cmd; return cmd;
@ -3235,16 +3263,18 @@ _instr2cmd_grow(Evas_Filter_Context *ctx,
Evas_Filter_Command *cmd; Evas_Filter_Command *cmd;
Buffer *src, *dst; Buffer *src, *dst;
Eina_Bool smooth; Eina_Bool smooth;
Eina_Bool alphaonly;
int radius; int radius;
src = _instruction_param_getbuf(instr, "src", NULL); src = _instruction_param_getbuf(instr, "src", NULL);
dst = _instruction_param_getbuf(instr, "dst", NULL); dst = _instruction_param_getbuf(instr, "dst", NULL);
radius = _instruction_param_geti(instr, "radius", 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(src);
INSTR_PARAM_CHECK(dst); 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; if (cmd) cmd->draw.need_temp_buffer = EINA_TRUE;
return cmd; return cmd;

View File

@ -242,6 +242,7 @@ struct _Evas_Filter_Command
Eina_Bool down; Eina_Bool down;
} scale; } scale;
Evas_Filter_Fill_Mode fillmode; Evas_Filter_Fill_Mode fillmode;
Eina_Bool alphaonly : 1;
Eina_Bool clip_use : 1; Eina_Bool clip_use : 1;
Eina_Bool clip_mode_lrtb : 1; Eina_Bool clip_mode_lrtb : 1;
Eina_Bool need_temp_buffer : 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 ox X offset in the destination buffer
* @param oy Y 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 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 * @return Filter command ID or -1 in case of error
* @internal * @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 * @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 ox X offset in the destination buffer
* @param oy Y 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 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 * @return Filter command ID or -1 in case of error
* @internal * @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 * @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 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 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 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 * @return Filter command ID or -1 in case of error
* @internal * @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 * @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, Evas_GL_Texture *mtex, int mx, int my, int mw, int mh,
Eina_Bool mask_smooth, Eina_Bool mask_color, Eina_Bool mask_smooth, Eina_Bool mask_color,
int r, int g, int b, int a, 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, void evas_gl_common_context_font_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,
@ -667,13 +667,16 @@ void evas_gl_common_context_image_map_push(Evas_Engine_GL_Context *g
Evas_Colorspace cspace); Evas_Colorspace cspace);
// Gfx Filters // 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, 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); 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, 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); 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, 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, 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); int evas_gl_common_shader_program_init(Evas_GL_Shared *shared);
void evas_gl_common_shader_program_shutdown(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 *tex, Eina_Bool tex_only,
Evas_GL_Texture *mtex, Eina_Bool mask_smooth, Evas_GL_Texture *mtex, Eina_Bool mask_smooth,
Eina_Bool mask_color, int mw, int mh, Eina_Bool mask_color, int mw, int mh,
Eina_Bool alphaonly,
Shader_Sampling *psam, int *pnomul, Shader_Sampling *psam, int *pnomul,
Shader_Sampling *pmasksam); Shader_Sampling *pmasksam);
void evas_gl_common_shader_textures_bind(Evas_GL_Program *p); 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, 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, 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, pn = _evas_gl_common_context_push(SHD_LINE,
gc, NULL, mtex, 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, 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, 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, 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, Evas_GL_Texture *mtex, int mx, int my, int mw, int mh,
Eina_Bool mask_smooth, Eina_Bool mask_color, Eina_Bool mask_smooth, Eina_Bool mask_color,
int r, int g, int b, int a, 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; 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, prog = evas_gl_common_shader_program_get(gc, shd_in, NULL, 0, r, g, b, a,
sw, sh, w, h, smooth, tex, tex_only, sw, sh, w, h, smooth, tex, tex_only,
mtex, mask_smooth, mask_color, mw, mh, mtex, mask_smooth, mask_color, mw, mh,
&sam, &nomul, &masksam); alphaonly, &sam, &nomul, &masksam);
if (tex->ptt) 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, 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, sw, sh, w, h, EINA_FALSE, tex, EINA_FALSE,
mtex, mask_smooth, mask_color, mw, mh, mtex, mask_smooth, mask_color, mw, mh,
NULL, NULL, &masksam); EINA_FALSE, NULL, NULL, &masksam);
pn = _evas_gl_common_context_push(SHD_FONT, pn = _evas_gl_common_context_push(SHD_FONT,
gc, tex, mtex, 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, prog = evas_gl_common_shader_program_get(gc, SHD_YUV, NULL, 0, r, g, b, a,
w, h, w, h, smooth, tex, 0, w, h, w, h, smooth, tex, 0,
mtex, mask_smooth, mask_color, mw, mh, mtex, mask_smooth, mask_color, mw, mh,
NULL, &nomul, &masksam); EINA_FALSE, NULL, &nomul, &masksam);
pn = _evas_gl_common_context_push(SHD_YUV, pn = _evas_gl_common_context_push(SHD_YUV,
gc, tex, mtex, 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, prog = evas_gl_common_shader_program_get(gc, SHD_YUV_709, NULL, 0, r, g, b, a,
w, h, w, h, smooth, tex, 0, w, h, w, h, smooth, tex, 0,
mtex, mask_smooth, mask_color, mw, mh, mtex, mask_smooth, mask_color, mw, mh,
NULL, &nomul, &masksam); EINA_FALSE, NULL, &nomul, &masksam);
pn = _evas_gl_common_context_push(SHD_YUV_709, pn = _evas_gl_common_context_push(SHD_YUV_709,
gc, tex, mtex, 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, prog = evas_gl_common_shader_program_get(gc, SHD_YUY2, NULL, 0, r, g, b, a,
sw, sh, w, h, smooth, tex, 0, sw, sh, w, h, smooth, tex, 0,
mtex, mask_smooth, mask_color, mw, mh, mtex, mask_smooth, mask_color, mw, mh,
NULL, &nomul, &masksam); EINA_FALSE, NULL, &nomul, &masksam);
pn = _evas_gl_common_context_push(SHD_YUY2, pn = _evas_gl_common_context_push(SHD_YUY2,
gc, tex, mtex, 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, prog = evas_gl_common_shader_program_get(gc, SHD_NV12, NULL, 0, r, g, b, a,
sw, sh, w, h, smooth, tex, 0, sw, sh, w, h, smooth, tex, 0,
mtex, mask_smooth, mask_color, mw, mh, mtex, mask_smooth, mask_color, mw, mh,
NULL, &nomul, &masksam); EINA_FALSE, NULL, &nomul, &masksam);
pn = _evas_gl_common_context_push(SHD_NV12, pn = _evas_gl_common_context_push(SHD_NV12,
gc, tex, mtex, 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, 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, sw, sh, w, h, smooth, tex, 0,
mtex, mask_smooth, mask_color, mw, mh, 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, pn = _evas_gl_common_context_push(SHD_RGB_A_PAIR,
gc, tex, mtex, 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, prog = evas_gl_common_shader_program_get(gc, type, p, npoints, r, g, b, a,
w, h, w, h, smooth, tex, tex_only, w, h, w, h, smooth, tex, tex_only,
mtex, mask_smooth, mask_color, mw, mh, mtex, mask_smooth, mask_color, mw, mh,
NULL, &nomul, &masksam); EINA_FALSE, NULL, &nomul, &masksam);
x = w = (p[0].x >> FP); x = w = (p[0].x >> FP);
y = h = (p[0].y >> 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, 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, w, h, w, h, smooth, tex, EINA_FALSE,
NULL, EINA_FALSE, EINA_FALSE, 0, 0, NULL, EINA_FALSE, EINA_FALSE, 0, 0,
&sam, &nomul, NULL); EINA_FALSE, &sam, &nomul, NULL);
_filter_data_flush(gc, prog); _filter_data_flush(gc, prog);
pn = _evas_gl_common_context_push(SHD_FILTER_DISPLACE, gc, tex, NULL, 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, 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, w, h, w, h, smooth, tex, EINA_FALSE,
NULL, EINA_FALSE, EINA_FALSE, 0, 0, NULL, EINA_FALSE, EINA_FALSE, 0, 0,
&sam, &nomul, NULL); EINA_FALSE, &sam, &nomul, NULL);
_filter_data_flush(gc, prog); _filter_data_flush(gc, prog);
pn = _evas_gl_common_context_push(SHD_FILTER_CURVE, gc, tex, NULL, 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); 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 void
evas_gl_common_filter_blur_push(Evas_Engine_GL_Context *gc, evas_gl_common_filter_blur_push(Evas_Engine_GL_Context *gc,
Evas_GL_Texture *tex, 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, double dx, double dy, double dw, double dh,
const double * const weights, const double * const weights,
const double * const offsets, int count, 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; double ox1, oy1, ox2, oy2, ox3, oy3, ox4, oy4, pw, ph, texlen;
GLfloat tx1, ty1, tx2, ty2, tx3, ty3, tx4, ty4; 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, prog = evas_gl_common_shader_program_get(gc, type, NULL, 0, r, g, b, a,
sw, sh, dw, dh, smooth, tex, EINA_FALSE, sw, sh, dw, dh, smooth, tex, EINA_FALSE,
NULL, EINA_FALSE, EINA_FALSE, 0, 0, NULL, EINA_FALSE, EINA_FALSE, 0, 0,
NULL, &nomul, NULL); alphaonly, NULL, &nomul, NULL);
_filter_data_flush(gc, prog); _filter_data_flush(gc, prog);
EINA_SAFETY_ON_NULL_RETURN(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, dx, dy, dw, dh,
mtex, mx, my, mw, mh, mask_smooth, mask_color, mtex, mx, my, mw, mh, mask_smooth, mask_color,
r, g, b, a, r, g, b, a,
smooth, im->tex_only); smooth, im->tex_only, EINA_FALSE);
return; return;
} }
@ -1377,11 +1377,14 @@ _evas_gl_common_image_push(Evas_Engine_GL_Context *gc, Evas_GL_Image *im,
nx, ny, nw, nh, nx, ny, nw, nh,
mtex, mx, my, mw, mh, mask_smooth, mask_color, mtex, mx, my, mw, mh, mask_smooth, mask_color,
r, g, b, a, r, g, b, a,
smooth, im->tex_only); smooth, im->tex_only, EINA_FALSE);
} }
void 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; RGBA_Draw_Context *dc;
int r, g, b, a; 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) if (dc->mul.use)
{ {
a = (dc->mul.col >> 24) & 0xff; a = (dc->mul.col >> 24) & 0xff;
r = (dc->mul.col >> 16) & 0xff; r = (dc->mul.col >> 16) & 0xff;
g = (dc->mul.col >> 8 ) & 0xff; g = (dc->mul.col >> 8 ) & 0xff;
b = (dc->mul.col ) & 0xff; b = (dc->mul.col ) & 0xff;
} }
else else
{ {

View File

@ -44,8 +44,9 @@ typedef enum {
SHADER_FLAG_FILTER_CURVE = (1 << 22), SHADER_FLAG_FILTER_CURVE = (1 << 22),
SHADER_FLAG_FILTER_BLUR = (1 << 23), SHADER_FLAG_FILTER_BLUR = (1 << 23),
SHADER_FLAG_FILTER_DIR_Y = (1 << 24), SHADER_FLAG_FILTER_DIR_Y = (1 << 24),
SHADER_FLAG_FILTER_ALPHA_ONLY = (1 << 25),
} Shader_Flag; } Shader_Flag;
#define SHADER_FLAG_COUNT 25 #define SHADER_FLAG_COUNT 26
static const char *_shader_flags[SHADER_FLAG_COUNT] = { static const char *_shader_flags[SHADER_FLAG_COUNT] = {
"TEX", "TEX",
@ -73,6 +74,7 @@ static const char *_shader_flags[SHADER_FLAG_COUNT] = {
"FILTER_CURVE", "FILTER_CURVE",
"FILTER_BLUR", "FILTER_BLUR",
"FILTER_DIR_Y", "FILTER_DIR_Y",
"ALPHA_ONLY",
}; };
static Eina_Bool compiler_released = EINA_FALSE; 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 *tex, Eina_Bool tex_only,
Evas_GL_Texture *mtex, Eina_Bool mask_smooth, Evas_GL_Texture *mtex, Eina_Bool mask_smooth,
Eina_Bool mask_color, int mw, int mh, Eina_Bool mask_color, int mw, int mh,
Eina_Bool alphaonly,
Shader_Sampling *psam, int *pnomul, Shader_Sampling *pmasksam) Shader_Sampling *psam, int *pnomul, Shader_Sampling *pmasksam)
{ {
Shader_Sampling sam = SHD_SAM11, masksam = SHD_SAM11; 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; return 0;
} }
if (alphaonly)
flags |= SHADER_FLAG_FILTER_ALPHA_ONLY;
// color mul // color mul
if ((a == 255) && (r == 255) && (g == 255) && (b == 255)) 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 *tex, Eina_Bool tex_only,
Evas_GL_Texture *mtex, Eina_Bool mask_smooth, Evas_GL_Texture *mtex, Eina_Bool mask_smooth,
Eina_Bool mask_color, int mw, int mh, Eina_Bool mask_color, int mw, int mh,
Eina_Bool alphaonly,
Shader_Sampling *psam, int *pnomul, Shader_Sampling *psam, int *pnomul,
Shader_Sampling *pmasksam) 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, 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, sw, sh, w, h, smooth, tex, tex_only,
mtex, mask_smooth, mask_color, mw, mh, mtex, mask_smooth, mask_color, mw, mh,
psam, pnomul, pmasksam); alphaonly, psam, pnomul, pmasksam);
p = eina_hash_find(gc->shared->shaders_hash, &flags); p = eina_hash_find(gc->shared->shaders_hash, &flags);
if (!p) 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" " texture2D(tex_filter, vec2(c.b / old_alpha, 0.0)).b * new_alpha,\n"
" new_alpha);\n" " new_alpha);\n"
"#endif\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" "#ifndef SHD_FILTER_BLUR\n"
" gl_FragColor =\n" " gl_FragColor =\n"
" c\n" " c\n"

View File

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

View File

@ -6,7 +6,8 @@ _mapped_blend(Evas_Engine_GL_Context *gc,
Evas_GL_Image *image, Evas_GL_Image *image,
Evas_Filter_Fill_Mode fillmode, Evas_Filter_Fill_Mode fillmode,
int sx, int sy, int sw, int sh, 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 right = 0, bottom = 0, left = 0, top = 0;
int row, col, rows, cols; int row, col, rows, cols;
@ -15,7 +16,7 @@ _mapped_blend(Evas_Engine_GL_Context *gc,
if (fillmode == EVAS_FILTER_FILL_MODE_NONE) 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); 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; return EINA_TRUE;
} }
@ -148,8 +149,8 @@ _mapped_blend(Evas_Engine_GL_Context *gc,
"(src %dx%d, dst %dx%d)", "(src %dx%d, dst %dx%d)",
col, row, src_x, src_y, src_w, src_h, col, row, src_x, src_y, src_w, src_h,
dst_x, dst_y, dst_w, dst_h, sw, sh, dw, dh); 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, 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, EINA_TRUE); dst_x, dst_y, dst_w, dst_h, alphaonly);
} }
} }
return ret; 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); 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, EINA_FALSE);
EINA_SAFETY_ON_NULL_RETURN_VAL(image->tex, EINA_FALSE);
surface = evas_ector_buffer_render_image_get(cmd->output->buffer); surface = evas_ector_buffer_render_image_get(cmd->output->buffer);
EINA_SAFETY_ON_NULL_RETURN_VAL(surface, EINA_FALSE); 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); cmd->output->id, cmd->output->buffer);
_mapped_blend(gc, image, cmd->draw.fillmode, _mapped_blend(gc, image, cmd->draw.fillmode,
src_x, src_y, src_w, src_h, 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); evas_common_draw_context_free(gc->dc);
gc->dc = dc_save; 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); ssh = ((double)sh * (double)(nh)) / (double)(dh);
evas_gl_common_filter_blur_push(gc, image->tex, ssx, ssy, ssw, ssh, dx, dy, dw, 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); 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_x = x;
gc->dc->clip.mask_y = y; 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); 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); 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); 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; Efl_Gfx_Render_Op rop;
uint32_t color; uint32_t color;
}; Eina_Bool alphaonly;
} Filter_Blend_Draw_Context;
#define LINELEN(stride, ptr) (stride / (sizeof(*ptr))) #define LINELEN(stride, ptr) (stride / (sizeof(*ptr)))
@ -25,7 +26,7 @@ _image_draw_cpu_alpha_alpha(void *context,
int smooth EINA_UNUSED, int smooth EINA_UNUSED,
Eina_Bool do_async 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; const uint8_t *srcdata = src_map;
uint8_t *dstdata = dst_map; uint8_t *dstdata = dst_map;
Draw_Func_Alpha func; Draw_Func_Alpha func;
@ -60,7 +61,7 @@ _image_draw_cpu_alpha_rgba(void *context,
int smooth EINA_UNUSED, int smooth EINA_UNUSED,
Eina_Bool do_async 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; uint8_t *srcdata = (uint8_t *) src_map;
uint32_t *dstdata = dst_map; uint32_t *dstdata = dst_map;
RGBA_Comp_Func_Mask func; RGBA_Comp_Func_Mask func;
@ -95,7 +96,7 @@ _image_draw_cpu_rgba_rgba(void *context,
int smooth EINA_UNUSED, int smooth EINA_UNUSED,
Eina_Bool do_async 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 *srcdata = (uint32_t *) src_map;
uint32_t *dstdata = dst_map; uint32_t *dstdata = dst_map;
RGBA_Comp_Func func; RGBA_Comp_Func func;
@ -125,7 +126,7 @@ _image_draw_cpu_rgba_rgba(void *context,
} }
static Eina_Bool 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, const void *src_map, unsigned int src_stride,
void *dst_map, unsigned int dst_stride, void *dst_map, unsigned int dst_stride,
int src_x, int src_y, int src_w, int src_h, 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, int smooth EINA_UNUSED,
Eina_Bool do_async 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; uint32_t *srcdata = (uint32_t *) src_map;
uint8_t *dstdata = dst_map; uint8_t *dstdata = dst_map;
int x, y, sw, dw; int x, y, sw, dw;
@ -156,14 +159,30 @@ _image_draw_cpu_rgba_alpha(void *context EINA_UNUSED,
srcdata += src_y * sw; srcdata += src_y * sw;
dstdata += dst_y * dw; dstdata += dst_y * dw;
for (y = src_h; y; y--)
if (!alphaonly)
{ {
uint32_t *s = srcdata + src_x; for (y = src_h; y; y--)
uint8_t *d = dstdata + dst_x; {
for (x = src_w; x; x--, d++, s++) uint32_t *s = srcdata + src_x;
*d = DIVIDE((R_VAL(s) * WR) + (G_VAL(s) * WG) + (B_VAL(s) * WB)); uint8_t *d = dstdata + dst_x;
srcdata += sw; for (x = src_w; x; x--, d++, s++)
dstdata += dw; *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; 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; unsigned int src_len, src_stride, dst_len, dst_stride;
int sw, sh, dx, dy, dw, dh, sx, sy; 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; Eina_Bool ret = EINA_FALSE;
Evas_Filter_Buffer *src_fb; Evas_Filter_Buffer *src_fb;
void *src = NULL, *dst = NULL; 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); EINA_SAFETY_ON_FALSE_GOTO(src && dst, end);
dc.rop = cmd->draw.rop; 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); 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, ret = _mapped_blend(&dc, src, src_stride, dst, dst_stride, cmd->draw.fillmode,