evas filters: Move mask to software generic (2/8)

This commit is contained in:
Jean-Philippe Andre 2017-01-17 19:33:50 +09:00
parent 0740010a06
commit 09ff5f419e
6 changed files with 53 additions and 40 deletions

View File

@ -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

View File

@ -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;
}

View File

@ -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 */

View File

@ -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;

View File

@ -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

View File

@ -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);