diff --git a/src/lib/evas/filters/evas_filter.c b/src/lib/evas/filters/evas_filter.c index c83b5e35b0..135d20b2bc 100644 --- a/src/lib/evas/filters/evas_filter.c +++ b/src/lib/evas/filters/evas_filter.c @@ -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; } diff --git a/src/lib/evas/filters/evas_filter_parser.c b/src/lib/evas/filters/evas_filter_parser.c index e916b2efc7..08b91e5255 100644 --- a/src/lib/evas/filters/evas_filter_parser.c +++ b/src/lib/evas/filters/evas_filter_parser.c @@ -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; diff --git a/src/lib/evas/filters/evas_filter_private.h b/src/lib/evas/filters/evas_filter_private.h index 698b034b59..4ea6e0a66a 100644 --- a/src/lib/evas/filters/evas_filter_private.h +++ b/src/lib/evas/filters/evas_filter_private.h @@ -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; diff --git a/src/lib/evas/include/evas_filter.h b/src/lib/evas/include/evas_filter.h index 82b3ed6ce7..c6618d35d6 100644 --- a/src/lib/evas/include/evas_filter.h +++ b/src/lib/evas/include/evas_filter.h @@ -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 diff --git a/src/modules/evas/engines/gl_common/evas_gl_common.h b/src/modules/evas/engines/gl_common/evas_gl_common.h index 1b2625d4ae..508c757dde 100644 --- a/src/modules/evas/engines/gl_common/evas_gl_common.h +++ b/src/modules/evas/engines/gl_common/evas_gl_common.h @@ -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); diff --git a/src/modules/evas/engines/gl_common/evas_gl_context.c b/src/modules/evas/engines/gl_common/evas_gl_context.c index 317363e3b8..cb1e3ad649 100644 --- a/src/modules/evas/engines/gl_common/evas_gl_context.c +++ b/src/modules/evas/engines/gl_common/evas_gl_context.c @@ -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); diff --git a/src/modules/evas/engines/gl_common/evas_gl_image.c b/src/modules/evas/engines/gl_common/evas_gl_image.c index 58d0f806cb..87f2a20a6b 100644 --- a/src/modules/evas/engines/gl_common/evas_gl_image.c +++ b/src/modules/evas/engines/gl_common/evas_gl_image.c @@ -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 { diff --git a/src/modules/evas/engines/gl_common/evas_gl_shader.c b/src/modules/evas/engines/gl_common/evas_gl_shader.c index c09625fbee..5aa0803741 100644 --- a/src/modules/evas/engines/gl_common/evas_gl_shader.c +++ b/src/modules/evas/engines/gl_common/evas_gl_shader.c @@ -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) { diff --git a/src/modules/evas/engines/gl_common/shader/evas_gl_shaders.x b/src/modules/evas/engines/gl_common/shader/evas_gl_shaders.x index 13e20b8e0b..2b071f2316 100644 --- a/src/modules/evas/engines/gl_common/shader/evas_gl_shaders.x +++ b/src/modules/evas/engines/gl_common/shader/evas_gl_shaders.x @@ -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" diff --git a/src/modules/evas/engines/gl_common/shader/fragment.glsl b/src/modules/evas/engines/gl_common/shader/fragment.glsl index 999b893560..89f306062a 100644 --- a/src/modules/evas/engines/gl_common/shader/fragment.glsl +++ b/src/modules/evas/engines/gl_common/shader/fragment.glsl @@ -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 = diff --git a/src/modules/evas/engines/gl_generic/filters/gl_filter_blend.c b/src/modules/evas/engines/gl_generic/filters/gl_filter_blend.c index 768b35005d..19591d4340 100644 --- a/src/modules/evas/engines/gl_generic/filters/gl_filter_blend.c +++ b/src/modules/evas/engines/gl_generic/filters/gl_filter_blend.c @@ -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; diff --git a/src/modules/evas/engines/gl_generic/filters/gl_filter_blur.c b/src/modules/evas/engines/gl_generic/filters/gl_filter_blur.c index 82a757a8c9..21b78198e1 100644 --- a/src/modules/evas/engines/gl_generic/filters/gl_filter_blur.c +++ b/src/modules/evas/engines/gl_generic/filters/gl_filter_blur.c @@ -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); diff --git a/src/modules/evas/engines/gl_generic/filters/gl_filter_mask.c b/src/modules/evas/engines/gl_generic/filters/gl_filter_mask.c index 39e0bc7696..755dedb04a 100644 --- a/src/modules/evas/engines/gl_generic/filters/gl_filter_mask.c +++ b/src/modules/evas/engines/gl_generic/filters/gl_filter_mask.c @@ -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); diff --git a/src/modules/evas/engines/software_generic/filters/evas_filter_blend.c b/src/modules/evas/engines/software_generic/filters/evas_filter_blend.c index 5573010b9f..12745c4037 100644 --- a/src/modules/evas/engines/software_generic/filters/evas_filter_blend.c +++ b/src/modules/evas/engines/software_generic/filters/evas_filter_blend.c @@ -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,