From 09ff5f419ec102e65dc37cabf53d9854c6da978e Mon Sep 17 00:00:00 2001 From: Jean-Philippe Andre Date: Tue, 17 Jan 2017 19:33:50 +0900 Subject: [PATCH] evas filters: Move mask to software generic (2/8) --- src/Makefile_Evas.am | 2 +- src/lib/evas/filters/evas_filter.c | 5 +- src/lib/evas/filters/evas_filter_private.h | 1 - .../evas/engines/software_generic/evas_engine.c | 8 +-- .../engines/software_generic/evas_engine_filter.h | 1 + .../software_generic}/filters/evas_filter_mask.c | 76 +++++++++++++--------- 6 files changed, 53 insertions(+), 40 deletions(-) rename src/{lib/evas => modules/evas/engines/software_generic}/filters/evas_filter_mask.c (86%) diff --git a/src/Makefile_Evas.am b/src/Makefile_Evas.am index bb037ff..00b8791 100644 --- a/src/Makefile_Evas.am +++ b/src/Makefile_Evas.am @@ -597,7 +597,6 @@ lib/evas/filters/evas_filter_bump.c \ lib/evas/filters/evas_filter_curve.c \ lib/evas/filters/evas_filter_displace.c \ lib/evas/filters/evas_filter_fill.c \ -lib/evas/filters/evas_filter_mask.c \ lib/evas/filters/evas_filter_parser.c \ lib/evas/filters/evas_filter_transform.c \ lib/evas/filters/evas_filter_utils.c \ @@ -618,6 +617,7 @@ lib/evas/filters/blur/blur_box_rgba_neon.c GFX_FILTER_SW_FILES = \ modules/evas/engines/software_generic/evas_engine_filter.h \ modules/evas/engines/software_generic/filters/evas_filter_blend.c \ +modules/evas/engines/software_generic/filters/evas_filter_mask.c \ $(NULL) ### Engine Ector stuff diff --git a/src/lib/evas/filters/evas_filter.c b/src/lib/evas/filters/evas_filter.c index 5ff5a7b..04188d5 100644 --- a/src/lib/evas/filters/evas_filter.c +++ b/src/lib/evas/filters/evas_filter.c @@ -1550,9 +1550,6 @@ _filter_command_run(Evas_Filter_Command *cmd) case EVAS_FILTER_MODE_FILL: func = evas_filter_fill_cpu_func_get(cmd); break; - case EVAS_FILTER_MODE_MASK: - func = evas_filter_mask_cpu_func_get(cmd); - break; case EVAS_FILTER_MODE_BUMP: func = evas_filter_bump_map_cpu_func_get(cmd); break; @@ -1567,7 +1564,7 @@ _filter_command_run(Evas_Filter_Command *cmd) if (!func) { - ERR("No function to process this filter!"); + ERR("No function to process this filter (mode %d)", cmd->mode); return EINA_FALSE; } diff --git a/src/lib/evas/filters/evas_filter_private.h b/src/lib/evas/filters/evas_filter_private.h index f659daa..d81bc9a 100644 --- a/src/lib/evas/filters/evas_filter_private.h +++ b/src/lib/evas/filters/evas_filter_private.h @@ -266,7 +266,6 @@ Evas_Filter_Apply_Func evas_filter_bump_map_cpu_func_get(Evas_Filter_Command * Evas_Filter_Apply_Func evas_filter_curve_cpu_func_get(Evas_Filter_Command *cmd); Evas_Filter_Apply_Func evas_filter_displace_cpu_func_get(Evas_Filter_Command *cmd); Evas_Filter_Apply_Func evas_filter_fill_cpu_func_get(Evas_Filter_Command *cmd); -Evas_Filter_Apply_Func evas_filter_mask_cpu_func_get(Evas_Filter_Command *cmd); Evas_Filter_Apply_Func evas_filter_transform_cpu_func_get(Evas_Filter_Command *cmd); /* Utility functions */ diff --git a/src/modules/evas/engines/software_generic/evas_engine.c b/src/modules/evas/engines/software_generic/evas_engine.c index 37fa1b9..281340a 100644 --- a/src/modules/evas/engines/software_generic/evas_engine.c +++ b/src/modules/evas/engines/software_generic/evas_engine.c @@ -4627,11 +4627,9 @@ _gfx_filter_func_get(Evas_Filter_Command *cmd) switch (cmd->mode) { - case EVAS_FILTER_MODE_BLEND: - func = eng_filter_blend_func_get(cmd); - break; - default: - return NULL; + case EVAS_FILTER_MODE_BLEND: func = eng_filter_blend_func_get(cmd); break; + case EVAS_FILTER_MODE_MASK: func = eng_filter_mask_func_get(cmd); break; + default: return NULL; } return func; diff --git a/src/modules/evas/engines/software_generic/evas_engine_filter.h b/src/modules/evas/engines/software_generic/evas_engine_filter.h index 2b2c81d..3971a6b 100644 --- a/src/modules/evas/engines/software_generic/evas_engine_filter.h +++ b/src/modules/evas/engines/software_generic/evas_engine_filter.h @@ -4,5 +4,6 @@ #include "evas_filter_private.h" Evas_Filter_Apply_Func eng_filter_blend_func_get(Evas_Filter_Command *cmd); +Evas_Filter_Apply_Func eng_filter_mask_func_get(Evas_Filter_Command *cmd); #endif // EVAS_ENGINE_FILTER_H diff --git a/src/lib/evas/filters/evas_filter_mask.c b/src/modules/evas/engines/software_generic/filters/evas_filter_mask.c similarity index 86% rename from src/lib/evas/filters/evas_filter_mask.c rename to src/modules/evas/engines/software_generic/filters/evas_filter_mask.c index 230cb32..18acf8c 100644 --- a/src/lib/evas/filters/evas_filter_mask.c +++ b/src/modules/evas/engines/software_generic/filters/evas_filter_mask.c @@ -1,7 +1,6 @@ /* Implementation of some masking functions for the software engine */ -#include "evas_filter_private.h" -#include "evas_blend_private.h" +#include "../evas_engine_filter.h" #include "draw.h" // Naming convention: _func_engine_incolor_maskcolor_outcolor() @@ -12,7 +11,7 @@ static Eina_Bool _mask_cpu_rgba_alpha_rgba(Evas_Filter_Command *cmd); static Eina_Bool _mask_cpu_rgba_rgba_rgba(Evas_Filter_Command *cmd); Evas_Filter_Apply_Func -evas_filter_mask_cpu_func_get(Evas_Filter_Command *cmd) +eng_filter_mask_func_get(Evas_Filter_Command *cmd) { EINA_SAFETY_ON_NULL_RETURN_VAL(cmd, NULL); EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input, NULL); @@ -30,7 +29,7 @@ evas_filter_mask_cpu_func_get(Evas_Filter_Command *cmd) { if (cmd->output->alpha_only) { - if (cmd->mask->alpha_only) + if (!cmd->mask->alpha_only) { DBG("Input and output are Alpha but mask is RGBA. This is not " "optimal (implicit conversion and loss of color)."); @@ -91,13 +90,15 @@ _mask_cpu_alpha_alpha_alpha(Evas_Filter_Command *cmd) // Stretch if necessary. if ((mw != w || mh != h) && (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_XY)) { + EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->ctx->buffer_scaled_get, EINA_FALSE); + if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_X) mw = w; if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_Y) mh = h; BUFFERS_LOCK(); - msk_fb = evas_filter_buffer_scaled_get(cmd->ctx, cmd->mask, mw, mh); + msk_fb = cmd->ctx->buffer_scaled_get(cmd->ctx, cmd->mask, mw, mh); BUFFERS_UNLOCK(); EINA_SAFETY_ON_NULL_RETURN_VAL(msk_fb, EINA_FALSE); @@ -183,7 +184,8 @@ _mask_cpu_alpha_rgba_rgba(Evas_Filter_Command *cmd) unsigned int src_len, src_stride, msk_len, msk_stride, dst_len, dst_stride; Efl_Gfx_Render_Op op = cmd->draw.rop; Evas_Filter_Buffer *msk_fb; - RGBA_Gfx_Func func1, func2; + RGBA_Comp_Func_Mask func1; + Draw_Func_ARGB_Mix3 func2; uint8_t *src, *src_map = NULL, *msk_map = NULL, *dst_map = NULL; uint32_t *dst, *msk, *span; int w, h, mw, mh, x, y, my; @@ -193,8 +195,8 @@ _mask_cpu_alpha_rgba_rgba(Evas_Filter_Command *cmd) /* Mechanism: * 1. Stretch mask as requested in fillmode - * 2. Render mask to span using input as mask - * 3. Render span into destination + * 2. Render input to span using (using "mask" function) + * 3. Mix 3 RGBA images together into dest: span, mask, dest * * FIXME: Could probably be optimized into a single op :) */ @@ -211,13 +213,15 @@ _mask_cpu_alpha_rgba_rgba(Evas_Filter_Command *cmd) // Stretch if necessary. if ((mw != w || mh != h) && (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_XY)) { + EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->ctx->buffer_scaled_get, EINA_FALSE); + if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_X) mw = w; if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_Y) mh = h; BUFFERS_LOCK(); - msk_fb = evas_filter_buffer_scaled_get(cmd->ctx, cmd->mask, mw, mh); + msk_fb = cmd->ctx->buffer_scaled_get(cmd->ctx, cmd->mask, mw, mh); BUFFERS_UNLOCK(); EINA_SAFETY_ON_NULL_RETURN_VAL(msk_fb, EINA_FALSE); @@ -230,31 +234,36 @@ _mask_cpu_alpha_rgba_rgba(Evas_Filter_Command *cmd) dst_map = _buffer_map_all(cmd->output->buffer, &dst_len, E_WRITE, E_ARGB, &dst_stride); EINA_SAFETY_ON_FALSE_GOTO(src_map && dst_map && msk_map, end); - func1 = evas_common_gfx_func_composite_pixel_mask_span_get(1, 0, 1, 1, EVAS_RENDER_COPY); - func2 = evas_common_gfx_func_composite_pixel_color_span_get(1, 0, color, 1, 1, _gfx_to_evas_render_op(op)); + func1 = efl_draw_func_mask_span_get(op, 0xFFFFFFFF); + func2 = efl_draw_func_argb_mix3_get(op, color); + EINA_SAFETY_ON_FALSE_GOTO(func1 && func2, end); // Apply mask using Gfx functions for (y = 0, my = 0; y < h; y++, my++) { + int len; + if (my >= mh) my = 0; + len = stepsize; src = src_map + (y * src_stride); msk = (uint32_t *) (msk_map + (my * msk_stride)); dst = (uint32_t *) (dst_map + (y * dst_stride)); for (step = 0; step < stepcount; step++, dst += stepsize, src += stepsize) { - memset(span, 0, stepsize * sizeof(uint32_t)); - func1(msk, src, 0, span, stepsize); - func2(span, NULL, color, dst, stepsize); + memset(span, 0, len * sizeof(uint32_t)); + func1(span, src, len, 0xFFFFFFFF); + func2(dst, span, msk, len, color); } x = stepsize * stepcount; if (x < w) { - memset(span, 0, (w - x) * sizeof(uint32_t)); - func1(msk, src, 0, span, w - x); - func2(span, NULL, color, dst, w - x); + len = w - x; + memset(span, 0, len * sizeof(uint32_t)); + func1(span, src, len, 0xFFFFFFFF); + func2(dst, span, msk, len, color); } } @@ -273,8 +282,8 @@ _mask_cpu_alpha_alpha_rgba(Evas_Filter_Command *cmd) unsigned int src_len, src_stride, msk_len, msk_stride, dst_len, dst_stride; uint8_t *src, *msk, *span, *src_map = NULL, *msk_map = NULL, *dst_map = NULL; Evas_Filter_Buffer *msk_fb; - RGBA_Gfx_Func func; - Draw_Func_Alpha span_func; + Draw_Func_Alpha func1; + RGBA_Comp_Func_Mask func2; uint32_t *dst; uint32_t color; Efl_Gfx_Render_Op op = cmd->draw.rop; @@ -302,13 +311,15 @@ _mask_cpu_alpha_alpha_rgba(Evas_Filter_Command *cmd) // Stretch if necessary. if ((mw != w || mh != h) && (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_XY)) { + EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->ctx->buffer_scaled_get, EINA_FALSE); + if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_X) mw = w; if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_Y) mh = h; BUFFERS_LOCK(); - msk_fb = evas_filter_buffer_scaled_get(cmd->ctx, cmd->mask, mw, mh); + msk_fb = cmd->ctx->buffer_scaled_get(cmd->ctx, cmd->mask, mw, mh); BUFFERS_UNLOCK(); EINA_SAFETY_ON_NULL_RETURN_VAL(msk_fb, EINA_FALSE); @@ -321,30 +332,35 @@ _mask_cpu_alpha_alpha_rgba(Evas_Filter_Command *cmd) dst_map = _buffer_map_all(cmd->output->buffer, &dst_len, E_WRITE, E_ARGB, &dst_stride); EINA_SAFETY_ON_FALSE_GOTO(src_map && dst_map && msk_map, end); - func = evas_common_gfx_func_composite_mask_color_span_get(color, 1, 1, _gfx_to_evas_render_op(op)); - span_func = efl_draw_alpha_func_get(cmd->draw.rop, EINA_TRUE); + func1 = efl_draw_alpha_func_get(op, EINA_TRUE); + func2 = efl_draw_func_mask_span_get(op, color); + EINA_SAFETY_ON_FALSE_GOTO(func1 && func2, end); for (y = 0, my = 0; y < h; y++, my++) { + int len; + if (my >= mh) my = 0; + len = stepsize; src = src_map + (y * src_stride); msk = msk_map + (my * msk_stride); dst = (uint32_t *) (dst_map + (y * dst_stride)); for (step = 0; step < stepcount; step++, dst += stepsize, src += stepsize) { - memcpy(span, msk, stepsize * sizeof(uint8_t)); - span_func(span, src, stepsize); - func(NULL, span, color, dst, stepsize); + memcpy(span, msk, len * sizeof(uint8_t)); + func1(span, src, len); + func2(dst, span, len, color); } x = stepsize * stepcount; if (x < w) { - memcpy(span, msk, (w - x) * sizeof(uint8_t)); - span_func(span, src, w - x); - func(NULL, span, color, dst, w -x); + len = w - x; + memcpy(span, msk, len * sizeof(uint8_t)); + func1(span, src, len); + func2(dst, span, len, color); } } @@ -386,13 +402,15 @@ _mask_cpu_rgba_rgba_rgba(Evas_Filter_Command *cmd) // Stretch if necessary. if ((mw != w || mh != h) && (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_XY)) { + EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->ctx->buffer_scaled_get, EINA_FALSE); + if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_X) mw = w; if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_Y) mh = h; BUFFERS_LOCK(); - msk_fb = evas_filter_buffer_scaled_get(cmd->ctx, cmd->mask, mw, mh); + msk_fb = cmd->ctx->buffer_scaled_get(cmd->ctx, cmd->mask, mw, mh); BUFFERS_UNLOCK(); EINA_SAFETY_ON_NULL_RETURN_VAL(msk_fb, EINA_FALSE); -- 2.7.4