evas filters: Move mask to software generic (2/8)
authorJean-Philippe Andre <jp.andre@samsung.com>
Tue, 17 Jan 2017 10:33:50 +0000 (19:33 +0900)
committerJean-Philippe Andre <jp.andre@samsung.com>
Fri, 14 Apr 2017 02:26:42 +0000 (11:26 +0900)
src/Makefile_Evas.am
src/lib/evas/filters/evas_filter.c
src/lib/evas/filters/evas_filter_private.h
src/modules/evas/engines/software_generic/evas_engine.c
src/modules/evas/engines/software_generic/evas_engine_filter.h
src/modules/evas/engines/software_generic/filters/evas_filter_mask.c [moved from src/lib/evas/filters/evas_filter_mask.c with 86% similarity]

index bb037ff..00b8791 100644 (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
index 5ff5a7b..04188d5 100644 (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;
      }
 
index f659daa..d81bc9a 100644 (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 */
index 37fa1b9..281340a 100644 (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;
index 2b2c81d..3971a6b 100644 (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
@@ -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);