Evas: Add support for Alpha buffers
authorJean-Philippe Andre <jp.andre@samsung.com>
Mon, 9 Dec 2013 05:46:12 +0000 (14:46 +0900)
committerJean-Philippe Andre <jp.andre@samsung.com>
Fri, 7 Feb 2014 06:38:42 +0000 (15:38 +0900)
Evas is an RGBA only engine, BUT we also use some alpha masks,
especially in the font rendering pipeline.
This commit adds basic support for alpha buffer operations
(blend and copy).

RGBA_Image can then point to either alpha-only data, if
its colorspace is grey.

src/Makefile_Evas.am
src/lib/evas/common/evas_alpha_main.c [new file with mode: 0644]
src/lib/evas/common/evas_blend_private.h
src/lib/evas/common/evas_image_data.c
src/lib/evas/include/evas_common_private.h

index c94e54e..f74a737 100644 (file)
@@ -127,6 +127,7 @@ lib/evas/common/evas_op_add_main_.c \
 lib/evas/common/evas_op_sub_main_.c \
 lib/evas/common/evas_op_mask_main_.c \
 lib/evas/common/evas_op_mul_main_.c \
+lib/evas/common/evas_alpha_main.c \
 lib/evas/common/evas_blend_main.c \
 lib/evas/common/evas_blit_main.c \
 lib/evas/common/evas_convert_color.c \
diff --git a/src/lib/evas/common/evas_alpha_main.c b/src/lib/evas/common/evas_alpha_main.c
new file mode 100644 (file)
index 0000000..6bd654c
--- /dev/null
@@ -0,0 +1,90 @@
+#include "evas_common_private.h"
+#include "evas_blend_private.h"
+
+/** default op: d = d*(1-sa) + s */
+static void
+_alpha_func_blend(DATA8 *src, DATA8 *dst, int len)
+{
+   int k;
+
+   EINA_SAFETY_ON_NULL_RETURN(src);
+   EINA_SAFETY_ON_NULL_RETURN(dst);
+
+   for (k = len; k; k--)
+     {
+        int val = (*dst * (255 - *src)) / 255 + *src;
+        *dst++ = val;
+        src++;
+     }
+}
+
+/** d = s */
+static void
+_alpha_func_copy(DATA8 *src, DATA8 *dst, int len)
+{
+   EINA_SAFETY_ON_NULL_RETURN(src);
+   EINA_SAFETY_ON_NULL_RETURN(dst);
+
+   memcpy(dst, src, len);
+}
+
+/** d = d*s */
+static void
+_alpha_func_mul(DATA8 *src, DATA8 *dst, int len)
+{
+   int k;
+
+   EINA_SAFETY_ON_NULL_RETURN(src);
+   EINA_SAFETY_ON_NULL_RETURN(dst);
+
+   for (k = len; k; k--)
+     {
+        int val = (*dst * *src) / 255;
+        *dst++ = val;
+        src++;
+     }
+}
+
+
+#if 0
+// Reference ops. In case of alpha, s == sa.
+EVAS_RENDER_BLEND = 0, /**< default op: d = d*(1-sa) + s */
+EVAS_RENDER_BLEND_REL = 1, /**< d = d*(1 - sa) + s*da */
+EVAS_RENDER_COPY = 2, /**< d = s */
+EVAS_RENDER_COPY_REL = 3, /**< d = s*da */
+EVAS_RENDER_ADD = 4, /* d = d + s */
+EVAS_RENDER_ADD_REL = 5, /**< d = d + s*da */
+EVAS_RENDER_SUB = 6, /**< d = d - s */
+EVAS_RENDER_SUB_REL = 7, /* d = d - s*da */
+EVAS_RENDER_TINT = 8, /**< d = d*s + d*(1 - sa) + s*(1 - da) */
+EVAS_RENDER_TINT_REL = 9, /**< d = d*(1 - sa + s) */
+EVAS_RENDER_MASK = 10, /**< d = d*sa */
+EVAS_RENDER_MUL = 11, /**< d = d*s */
+#endif
+
+Alpha_Gfx_Func
+evas_common_alpha_func_get(int op)
+{
+   INF("Requesting alpha function with OP %d", op);
+   switch (op)
+     {
+      case EVAS_RENDER_BLEND:
+        return _alpha_func_blend;
+//      case EVAS_RENDER_BLEND_REL:
+      case EVAS_RENDER_COPY:
+        return _alpha_func_copy;
+//      case EVAS_RENDER_COPY_REL:
+//      case EVAS_RENDER_ADD:
+//      case EVAS_RENDER_ADD_REL:
+//      case EVAS_RENDER_SUB:
+//      case EVAS_RENDER_SUB_REL:
+//      case EVAS_RENDER_TINT:
+//      case EVAS_RENDER_TINT_REL:
+      case EVAS_RENDER_MASK:
+      case EVAS_RENDER_MUL:
+        return _alpha_func_mul;
+      default:
+        ERR("Not implemented yet.");
+        return NULL;
+     }
+}
index 1d14951..0029198 100644 (file)
@@ -27,5 +27,8 @@ RGBA_Gfx_Pt_Func     evas_common_gfx_func_composite_pixel_color_pt_get   (Image_
 RGBA_Gfx_Pt_Func     evas_common_gfx_func_composite_mask_color_pt_get    (DATA32 col, RGBA_Image *dst, int op);
 RGBA_Gfx_Pt_Func     evas_common_gfx_func_composite_pixel_mask_pt_get    (Image_Entry_Flags src_flags, RGBA_Image *dst, int op);
 
+/* Alpha/mask functions */
+Alpha_Gfx_Func       evas_common_alpha_func_get (int op);
+
 
 #endif /* _EVAS_BLEND_PRIVATE_H */
index fe80832..8971867 100644 (file)
@@ -33,6 +33,13 @@ evas_common_rgba_image_from_data(Image_Entry* ie_dst, int w, int h, DATA32 *imag
        dst->cs.data = image_data;
        dst->cs.no_free = 1;
        break;
+      case EVAS_COLORSPACE_GRY8:
+        dst->cache_entry.w = w;
+        dst->cache_entry.h = h;
+        dst->mask.data = (DATA8 *) image_data;
+        dst->mask.no_free = 1;
+        dst->cache_entry.flags.alpha = 1;
+        break;
       default:
        abort();
        break;
@@ -65,6 +72,11 @@ evas_common_rgba_image_from_copied_data(Image_Entry* ie_dst, int w, int h, DATA3
          if (image_data && (dst->cs.data))
            memcpy(dst->cs.data,  image_data, dst->cache_entry.h * sizeof(unsigned char*) * 2);
          break;
+      case EVAS_COLORSPACE_GRY8:
+        dst->cache_entry.flags.alpha = 1;
+        if (image_data)
+          memcpy(dst->mask.data, image_data, w * h * sizeof(DATA8));
+        break;
       default:
          abort();
          break;
@@ -104,17 +116,25 @@ int
 evas_common_rgba_image_colorspace_set(Image_Entry* ie_dst, int cspace)
 {
    RGBA_Image   *dst = (RGBA_Image *) ie_dst;
+   Eina_Bool change = (dst->cache_entry.space != cspace);
 
    switch (cspace)
      {
       case EVAS_COLORSPACE_ARGB8888:
+      case EVAS_COLORSPACE_GRY8:
        if (dst->cs.data)
          {
             if (!dst->cs.no_free) free(dst->cs.data);
             dst->cs.data = NULL;
             dst->cs.no_free = 0;
          }
-       break;
+        if (change && dst->image.data)
+          {
+             if (!dst->image.no_free) free(dst->image.data);
+             dst->image.data = NULL;
+             dst->image.no_free = 0;
+          }
+        break;
       case EVAS_COLORSPACE_YCBCR422P601_PL:
       case EVAS_COLORSPACE_YCBCR422P709_PL:
       case EVAS_COLORSPACE_YCBCR422601_PL:
@@ -136,7 +156,7 @@ evas_common_rgba_image_colorspace_set(Image_Entry* ie_dst, int cspace)
          }
        dst->cs.data = calloc(1, dst->cache_entry.h * sizeof(unsigned char *) * 2);
        dst->cs.no_free = 0;
-       break;
+        break;
       default:
        abort();
        break;
index e75cd93..83c0272 100644 (file)
@@ -424,7 +424,7 @@ typedef void (*RGBA_Gfx_Pt_Func) (DATA32 src, DATA8 mask, DATA32 col, DATA32 *ds
 typedef void (*Gfx_Func_Copy)    (DATA32 *src, DATA32 *dst, int len);
 
 typedef void (*Gfx_Func_Convert) (DATA32 *src, DATA8 *dst, int src_jump, int dst_jump, int w, int h, int dith_x, int dith_y, DATA8 *pal);
-
+typedef void (*Alpha_Gfx_Func)   (DATA8 *src, DATA8 *dst, int len);
 
 typedef void (*Evas_Render_Done_Cb)(void *);
 
@@ -801,11 +801,20 @@ struct _RGBA_Image
       Eina_Bool          dirty : 1;
    } cs;
 
-   /* RGBA stuff */
-   struct {
-      DATA32            *data;
-      Eina_Bool          no_free : 1;
-   } image;
+   union
+   {
+      /* RGBA stuff */
+      struct {
+         DATA32            *data;
+         Eina_Bool          no_free : 1;
+      } image;
+
+      /* Alpha Mask stuff */
+      struct {
+         DATA8             *data;
+         Eina_Bool          no_free : 1;
+      } mask;
+   };
 
    struct {
       SLK(lock);