forked from enlightenment/efl
ector_software_rasterizer: Implement mask blending function.
Summary: Add Mask blend function(Add, Substract, Intersect, Difference) this blending function only use mask blending case. Test Plan: N/A Reviewers: Hermet Reviewed By: Hermet Subscribers: cedric, kimcinoo, #reviewers, smohanty, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D8509
This commit is contained in:
parent
04a41a3712
commit
83d5ea1a42
|
@ -11,8 +11,23 @@
|
||||||
|
|
||||||
#include "draw.h"
|
#include "draw.h"
|
||||||
|
|
||||||
|
//FIXME: This enum add temporarily to help understanding of additional code
|
||||||
|
//related to masking in prepare_mask.
|
||||||
|
//This needs to be formally declared through the eo class.
|
||||||
|
typedef enum _EFL_CANVAS_VG_NODE_BLEND_TYPE
|
||||||
|
{
|
||||||
|
EFL_CANVAS_VG_NODE_BLEND_TYPE_NONE = 0,
|
||||||
|
EFL_CANVAS_VG_NODE_BLEND_TYPE_ALPHA,
|
||||||
|
EFL_CANVAS_VG_NODE_BLEND_TYPE_ALPHA_INV,
|
||||||
|
EFL_CANVAS_VG_NODE_BLEND_TYPE_MASK_ADD,
|
||||||
|
EFL_CANVAS_VG_NODE_BLEND_TYPE_MASK_SUBSTRACT,
|
||||||
|
EFL_CANVAS_VG_NODE_BLEND_TYPE_MASK_INTERSECT,
|
||||||
|
EFL_CANVAS_VG_NODE_BLEND_TYPE_MASK_DIFFERENCE
|
||||||
|
}EFL_CANVAS_VG_NODE_BLEND_TYPE;
|
||||||
|
//
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_blend_color_argb(int count, const SW_FT_Span *spans, void *user_data)
|
_blend_argb(int count, const SW_FT_Span *spans, void *user_data)
|
||||||
{
|
{
|
||||||
Span_Data *sd = user_data;
|
Span_Data *sd = user_data;
|
||||||
uint32_t color, *buffer, *target;
|
uint32_t color, *buffer, *target;
|
||||||
|
@ -34,7 +49,7 @@ _blend_color_argb(int count, const SW_FT_Span *spans, void *user_data)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_blend_color_argb_with_maskA(int count, const SW_FT_Span *spans, void *user_data)
|
_blend_alpha(int count, const SW_FT_Span *spans, void *user_data)
|
||||||
{
|
{
|
||||||
Span_Data *sd = user_data;
|
Span_Data *sd = user_data;
|
||||||
const int pix_stride = sd->raster_buffer->stride / 4;
|
const int pix_stride = sd->raster_buffer->stride / 4;
|
||||||
|
@ -77,7 +92,7 @@ _blend_color_argb_with_maskA(int count, const SW_FT_Span *spans, void *user_data
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_blend_color_argb_with_maskInvA(int count, const SW_FT_Span *spans, void *user_data)
|
_blend_alpha_inv(int count, const SW_FT_Span *spans, void *user_data)
|
||||||
{
|
{
|
||||||
Span_Data *sd = user_data;
|
Span_Data *sd = user_data;
|
||||||
const int pix_stride = sd->raster_buffer->stride / 4;
|
const int pix_stride = sd->raster_buffer->stride / 4;
|
||||||
|
@ -120,6 +135,122 @@ _blend_color_argb_with_maskInvA(int count, const SW_FT_Span *spans, void *user_d
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_blend_mask_add(int count, const SW_FT_Span *spans, void *user_data)
|
||||||
|
{
|
||||||
|
Span_Data *sd = user_data;
|
||||||
|
Ector_Software_Buffer_Base_Data *mask = sd->mask;
|
||||||
|
|
||||||
|
uint32_t color = DRAW_MUL4_SYM(sd->color, sd->mul_col);
|
||||||
|
RGBA_Comp_Func_Solid comp_func = efl_draw_func_solid_span_get(sd->op, color);
|
||||||
|
uint32_t *mbuffer = mask->pixels.u32;
|
||||||
|
|
||||||
|
while (count--)
|
||||||
|
{
|
||||||
|
uint32_t *ttarget = alloca(sizeof(uint32_t) * spans->len);
|
||||||
|
memset(ttarget, 0x00, sizeof(uint32_t) * spans->len);
|
||||||
|
uint32_t *mtarget = mbuffer + ((mask->generic->w * spans->y) + spans->x);
|
||||||
|
comp_func(ttarget, spans->len, color, spans->coverage);
|
||||||
|
for (int i = 0; i < spans->len; i++)
|
||||||
|
{
|
||||||
|
double adst = A_VAL(&mtarget[i]) == 0 ? 0 : (double)(A_VAL(&mtarget[i])) / (double)255;
|
||||||
|
double asrc = A_VAL(&ttarget[i]) == 0 ? 0 : (double)(A_VAL(&ttarget[i])) / (double)255;
|
||||||
|
uint32_t aout = (int)(((adst * (1 - asrc)) + asrc) * 255);
|
||||||
|
mtarget[i] = (aout<<24) + (0x00FFFFFF & mtarget[i]);
|
||||||
|
}
|
||||||
|
++spans;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_blend_mask_sub(int count, const SW_FT_Span *spans, void *user_data)
|
||||||
|
{
|
||||||
|
Span_Data *sd = user_data;
|
||||||
|
Ector_Software_Buffer_Base_Data *mask = sd->mask;
|
||||||
|
|
||||||
|
uint32_t color = DRAW_MUL4_SYM(sd->color, sd->mul_col);
|
||||||
|
RGBA_Comp_Func_Solid comp_func = efl_draw_func_solid_span_get(sd->op, color);
|
||||||
|
uint32_t *mtarget = mask->pixels.u32;
|
||||||
|
|
||||||
|
int tsize = sd->raster_buffer->generic->w * sd->raster_buffer->generic->h;
|
||||||
|
uint32_t *tbuffer = alloca(sizeof(uint32_t) * tsize);
|
||||||
|
memset(tbuffer, 0x00, sizeof(uint32_t) * tsize);
|
||||||
|
|
||||||
|
while (count--)
|
||||||
|
{
|
||||||
|
uint32_t *ttarget = tbuffer + ((mask->generic->w * spans->y) + spans->x);
|
||||||
|
comp_func(ttarget, spans->len, color, spans->coverage);
|
||||||
|
++spans;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 0; i < tsize; i++)
|
||||||
|
{
|
||||||
|
double adst = A_VAL(&mtarget[i]) == 0 ? 0 : (double)(A_VAL(&mtarget[i])) / (double)255;
|
||||||
|
double asrc = A_VAL(&tbuffer[i]) == 0 ? 0 : (double)(A_VAL(&tbuffer[i])) / (double)255;
|
||||||
|
uint32_t aout = (int)((adst * (1 - asrc)) * 255);
|
||||||
|
mtarget[i] = (aout<<24) + (0x00FFFFFF & mtarget[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
_blend_mask_ins(int count, const SW_FT_Span *spans, void *user_data)
|
||||||
|
{
|
||||||
|
Span_Data *sd = user_data;
|
||||||
|
Ector_Software_Buffer_Base_Data *mask = sd->mask;
|
||||||
|
|
||||||
|
uint32_t color = DRAW_MUL4_SYM(sd->color, sd->mul_col);
|
||||||
|
RGBA_Comp_Func_Solid comp_func = efl_draw_func_solid_span_get(sd->op, color);
|
||||||
|
uint32_t *mtarget = mask->pixels.u32;
|
||||||
|
|
||||||
|
int tsize = sd->raster_buffer->generic->w * sd->raster_buffer->generic->h;
|
||||||
|
uint32_t *tbuffer = alloca(sizeof(uint32_t) * tsize);
|
||||||
|
memset(tbuffer, 0x00, sizeof(uint32_t) * tsize);
|
||||||
|
|
||||||
|
while (count--)
|
||||||
|
{
|
||||||
|
uint32_t *ttarget = tbuffer + ((mask->generic->w * spans->y) + spans->x);
|
||||||
|
comp_func(ttarget, spans->len, color, spans->coverage);
|
||||||
|
++spans;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 0; i < tsize; i++)
|
||||||
|
{
|
||||||
|
double adst = A_VAL(&mtarget[i]) == 0 ? 0 : (double)(A_VAL(&mtarget[i])) / (double)255;
|
||||||
|
double asrc = A_VAL(&tbuffer[i]) == 0 ? 0 : (double)(A_VAL(&tbuffer[i])) / (double)255;
|
||||||
|
uint32_t aout = (int)((adst * asrc) * 255);
|
||||||
|
mtarget[i] = (aout<<24) + (0x00FFFFFF & mtarget[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
_blend_mask_diff(int count, const SW_FT_Span *spans, void *user_data)
|
||||||
|
{
|
||||||
|
Span_Data *sd = user_data;
|
||||||
|
Ector_Software_Buffer_Base_Data *mask = sd->mask;
|
||||||
|
|
||||||
|
uint32_t color = DRAW_MUL4_SYM(sd->color, sd->mul_col);
|
||||||
|
RGBA_Comp_Func_Solid comp_func = efl_draw_func_solid_span_get(sd->op, color);
|
||||||
|
uint32_t *mbuffer = mask->pixels.u32;
|
||||||
|
|
||||||
|
while (count--)
|
||||||
|
{
|
||||||
|
uint32_t *ttarget = alloca(sizeof(uint32_t) * spans->len);
|
||||||
|
memset(ttarget, 0x00, sizeof(uint32_t) * spans->len);
|
||||||
|
uint32_t *mtarget = mbuffer + ((mask->generic->w * spans->y) + spans->x);
|
||||||
|
comp_func(ttarget, spans->len, color, spans->coverage);
|
||||||
|
for (int i = 0; i < spans->len; i++)
|
||||||
|
{
|
||||||
|
double adst = A_VAL(&mtarget[i]) == 0 ? 0 : (double)(A_VAL(&mtarget[i])) / (double)255;
|
||||||
|
double asrc = A_VAL(&ttarget[i]) == 0 ? 0 : (double)(A_VAL(&ttarget[i])) / (double)255;
|
||||||
|
uint32_t aout = (int)((((1 - adst) * asrc) + ((1 - asrc) * adst)) * 255);
|
||||||
|
mtarget[i] = (aout<<24) + (0x00FFFFFF & mtarget[i]);
|
||||||
|
}
|
||||||
|
++spans;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#define BLEND_GRADIENT_BUFFER_SIZE 2048
|
#define BLEND_GRADIENT_BUFFER_SIZE 2048
|
||||||
|
|
||||||
typedef void (*src_fetch) (unsigned int *buffer, Span_Data *data, int y, int x, int length);
|
typedef void (*src_fetch) (unsigned int *buffer, Span_Data *data, int y, int x, int length);
|
||||||
|
@ -362,14 +493,32 @@ _adjust_span_fill_methods(Span_Data *spdata)
|
||||||
case Solid:
|
case Solid:
|
||||||
{
|
{
|
||||||
if (spdata->mask)
|
if (spdata->mask)
|
||||||
{
|
{
|
||||||
if (spdata->mask_op == 2)
|
switch (spdata->mask_op)
|
||||||
spdata->unclipped_blend = &_blend_color_argb_with_maskInvA;
|
{
|
||||||
else
|
default:
|
||||||
spdata->unclipped_blend = &_blend_color_argb_with_maskA;
|
case EFL_CANVAS_VG_NODE_BLEND_TYPE_ALPHA:
|
||||||
}
|
spdata->unclipped_blend = &_blend_alpha;
|
||||||
|
break;
|
||||||
|
case EFL_CANVAS_VG_NODE_BLEND_TYPE_ALPHA_INV:
|
||||||
|
spdata->unclipped_blend = &_blend_alpha_inv;
|
||||||
|
break;
|
||||||
|
case EFL_CANVAS_VG_NODE_BLEND_TYPE_MASK_ADD:
|
||||||
|
spdata->unclipped_blend = &_blend_mask_add;
|
||||||
|
break;
|
||||||
|
case EFL_CANVAS_VG_NODE_BLEND_TYPE_MASK_SUBSTRACT:
|
||||||
|
spdata->unclipped_blend = &_blend_mask_sub;
|
||||||
|
break;
|
||||||
|
case EFL_CANVAS_VG_NODE_BLEND_TYPE_MASK_INTERSECT:
|
||||||
|
spdata->unclipped_blend = &_blend_mask_ins;
|
||||||
|
break;
|
||||||
|
case EFL_CANVAS_VG_NODE_BLEND_TYPE_MASK_DIFFERENCE:
|
||||||
|
spdata->unclipped_blend = &_blend_mask_diff;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
spdata->unclipped_blend = &_blend_color_argb;
|
spdata->unclipped_blend = &_blend_argb;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case LinearGradient:
|
case LinearGradient:
|
||||||
|
@ -378,6 +527,10 @@ _adjust_span_fill_methods(Span_Data *spdata)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//FIXME: Mask and mask case is not use clipping.
|
||||||
|
if (spdata->mask_op >= EFL_CANVAS_VG_NODE_BLEND_TYPE_MASK_ADD)
|
||||||
|
spdata->clip.enabled = EINA_FALSE;
|
||||||
|
|
||||||
// Clipping Function
|
// Clipping Function
|
||||||
if (spdata->clip.enabled)
|
if (spdata->clip.enabled)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue