Evas filters: Implement all rgba mask operation
authorJean-Philippe Andre <jp.andre@samsung.com>
Wed, 22 Jan 2014 00:41:44 +0000 (09:41 +0900)
committerJean-Philippe Andre <jp.andre@samsung.com>
Fri, 7 Feb 2014 08:33:17 +0000 (17:33 +0900)
RGBA + RGBA blended to an RGBA target.
Uses existing infrastructure to combine all buffers together.

src/lib/evas/filters/evas_filter_mask.c
src/lib/evas/filters/evas_filter_parser.c

index 4f7f224..7158881 100644 (file)
@@ -12,7 +12,7 @@ static Eina_Bool _mask_cpu_alpha_alpha_alpha(Evas_Filter_Command *cmd);
 static Eina_Bool _mask_cpu_alpha_rgba_rgba(Evas_Filter_Command *cmd);
 static Eina_Bool _mask_cpu_alpha_alpha_rgba(Evas_Filter_Command *cmd);
 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)
@@ -43,7 +43,7 @@ evas_filter_mask_cpu_func_get(Evas_Filter_Command *cmd)
         if (cmd->mask->alpha_only && !cmd->output->alpha_only)
           return _mask_cpu_rgba_alpha_rgba;
         else if (!cmd->mask->alpha_only && !cmd->output->alpha_only)
-          return evas_filter_blend_cpu_func_get(cmd); // Check this. Merge?
+          return _mask_cpu_rgba_rgba_rgba;
      }
 
    CRI("If input or mask is RGBA, then output must also be RGBA: %s [%s] %s",
@@ -348,3 +348,50 @@ _mask_cpu_alpha_alpha_rgba(Evas_Filter_Command *cmd)
    free(span);
    return EINA_TRUE;
 }
+
+static Eina_Bool
+_mask_cpu_rgba_rgba_rgba(Evas_Filter_Command *cmd)
+{
+   Evas_Filter_Command fake_cmd;
+   Evas_Filter_Apply_Func blend;
+   Evas_Filter_Buffer *fb;
+   int w, h;
+
+   fake_cmd = *cmd;
+   w = cmd->input->w;
+   h = cmd->input->h;
+
+   /* Blend 2 rgba images into rgba destination.
+    * Mechanism:
+    * 1. Copy input to temp (COPY)
+    * 2. Blend mask to temp (MUL)
+    * 3. Blend temp to output (render_op)
+    */
+
+   // Copy
+   BUFFERS_LOCK();
+   fb = evas_filter_buffer_scaled_get(cmd->ctx, cmd->input, w, h);
+   BUFFERS_UNLOCK();
+   EINA_SAFETY_ON_NULL_RETURN_VAL(fb, EINA_FALSE);
+   fb->locked = EINA_TRUE;
+
+   // Mask --> Temp
+   fake_cmd.input = cmd->mask;
+   fake_cmd.mask = NULL;
+   fake_cmd.output = fb;
+   fake_cmd.draw.render_op = EVAS_RENDER_MUL;
+   blend = evas_filter_blend_cpu_func_get(&fake_cmd);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(blend, EINA_FALSE);
+   blend(&fake_cmd);
+
+   // Temp --> Output
+   fake_cmd.draw.render_op = EVAS_RENDER_BLEND;
+   fake_cmd.input = fb;
+   fake_cmd.output = cmd->output;
+   blend = evas_filter_blend_cpu_func_get(&fake_cmd);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(blend, EINA_FALSE);
+   blend(&fake_cmd);
+
+   fb->locked = EINA_FALSE;
+   return EINA_TRUE;
+}
index cdec16e..90175c0 100644 (file)
@@ -45,6 +45,8 @@ static struct
    { "repeat_y", EVAS_FILTER_FILL_MODE_REPEAT_Y },
    { "repeat_x_stretch_y", EVAS_FILTER_FILL_MODE_REPEAT_X_STRETCH_Y },
    { "repeat_y_stretch_x", EVAS_FILTER_FILL_MODE_REPEAT_Y_STRETCH_X },
+   { "stretch_y_repeat_x", EVAS_FILTER_FILL_MODE_REPEAT_X_STRETCH_Y },
+   { "stretch_x_repeat_y", EVAS_FILTER_FILL_MODE_REPEAT_Y_STRETCH_X },
    { "repeat", EVAS_FILTER_FILL_MODE_REPEAT_XY }, // alias
    { "repeat_xy", EVAS_FILTER_FILL_MODE_REPEAT_XY },
    { "stretch", EVAS_FILTER_FILL_MODE_STRETCH_XY }, // alias