forked from enlightenment/efl
Evas: Add support for Alpha buffers
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.
This commit is contained in:
parent
71c7d0e9ad
commit
d8301fae6e
|
@ -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 \
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue