forked from enlightenment/efl
Evas filters: Implement repeat and stretch for rgba to alpha
Use the mapped rendering to implement repeat and stretch with rgba to alpha buffers blending. If stretch is required, it will add one more (expensive) scaling step.
This commit is contained in:
parent
2d071a2cd4
commit
1c9865a8ae
|
@ -32,6 +32,21 @@ _filter_blend_cpu_alpha(Evas_Filter_Command *cmd)
|
|||
DATA8 *maskdata, *dstdata;
|
||||
int sw, sh, dw, dh, ox, oy, sx = 0, sy = 0, dx = 0, dy = 0, rows, cols, y;
|
||||
|
||||
/*
|
||||
* NOTE: Alpha to alpha blending does not support stretching operations
|
||||
* yet, because we don't have any scaling functions for alpha buffers.
|
||||
* Also, I'm not going to implement it by converting to RGBA either.
|
||||
*/
|
||||
if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_XY)
|
||||
{
|
||||
CRI("Alpha to alpha blending does not support stretch");
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
// TODO: Call _mapped_blend_cpu to implement repeat fill mode.
|
||||
if (cmd->draw.fillmode != EVAS_FILTER_FILL_MODE_NONE)
|
||||
ERR("Fill modes are not implemented for Alpha --> RGBA");
|
||||
|
||||
func = evas_common_alpha_func_get(cmd->draw.render_op);
|
||||
if (!func)
|
||||
return EINA_FALSE;
|
||||
|
@ -306,6 +321,10 @@ _filter_blend_cpu_mask_rgba(Evas_Filter_Command *cmd)
|
|||
if (!evas_filter_buffer_alloc(cmd->output, cmd->output->w, cmd->output->h))
|
||||
return EINA_FALSE;
|
||||
|
||||
// TODO: Call _mapped_blend_cpu to implement repeat fill mode.
|
||||
if (cmd->draw.fillmode != EVAS_FILTER_FILL_MODE_NONE)
|
||||
ERR("Fill modes are not implemented for Alpha --> RGBA");
|
||||
|
||||
in = cmd->input->backing;
|
||||
out = cmd->output->backing;
|
||||
sw = in->cache_entry.w;
|
||||
|
@ -348,50 +367,94 @@ _filter_blend_cpu_mask_rgba(Evas_Filter_Command *cmd)
|
|||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_image_draw_cpu_rgba2alpha(void *data EINA_UNUSED, void *context EINA_UNUSED,
|
||||
void *surface, void *image,
|
||||
int src_x, int src_y, int src_w, int src_h,
|
||||
int dst_x, int dst_y, int dst_w, int dst_h,
|
||||
int smooth EINA_UNUSED,
|
||||
Eina_Bool do_async EINA_UNUSED)
|
||||
{
|
||||
RGBA_Image *src = image;
|
||||
RGBA_Image *dst = surface;
|
||||
DATA32* srcdata = src->image.data;
|
||||
DATA8* dstdata = dst->mask.data;
|
||||
int x, y, sw, dw;
|
||||
DEFINE_DIVIDER(3);
|
||||
|
||||
EINA_SAFETY_ON_FALSE_RETURN_VAL((src_w == dst_w) && (src_h == dst_h), EINA_FALSE);
|
||||
|
||||
sw = src->cache_entry.w;
|
||||
dw = dst->cache_entry.w;
|
||||
|
||||
srcdata += src_y * sw;
|
||||
dstdata += dst_y * dw;
|
||||
for (y = src_h; y; y--)
|
||||
{
|
||||
DATA32 *s = srcdata + src_x;
|
||||
DATA8 *d = dstdata + dst_x;
|
||||
for (x = src_w; x; x--, d++, s++)
|
||||
{
|
||||
// TODO: Add weights like in YUV <--> RGB?
|
||||
*d = DIVIDE(R_VAL(s) + G_VAL(s) + B_VAL(s));
|
||||
}
|
||||
srcdata += sw;
|
||||
dstdata += dw;
|
||||
}
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_filter_blend_cpu_rgba2alpha(Evas_Filter_Command *cmd)
|
||||
{
|
||||
RGBA_Image *in, *out;
|
||||
DATA8 *dstdata;
|
||||
DATA32 *srcdata;
|
||||
int sw, sh, dw, dh, ox, oy, sx = 0, sy = 0, dx = 0, dy = 0, rows, cols, y, x;
|
||||
DEFINE_DIVIDER(3);
|
||||
int sw, sh, dx, dy, dw, dh, sx, sy;
|
||||
|
||||
if (!evas_filter_buffer_alloc(cmd->output, cmd->output->w, cmd->output->h))
|
||||
return EINA_FALSE;
|
||||
|
||||
in = cmd->input->backing;
|
||||
out = cmd->output->backing;
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(in, EINA_FALSE);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(out, EINA_FALSE);
|
||||
|
||||
sx = 0;
|
||||
sy = 0;
|
||||
sw = in->cache_entry.w;
|
||||
sh = in->cache_entry.h;
|
||||
|
||||
dw = out->cache_entry.w;
|
||||
dh = out->cache_entry.h;
|
||||
ox = cmd->draw.ox;
|
||||
oy = cmd->draw.oy;
|
||||
srcdata = in->image.data;
|
||||
dstdata = out->mask.data;
|
||||
dx = cmd->draw.ox;
|
||||
dy = cmd->draw.oy;
|
||||
|
||||
_clip_to_target(&sx, &sy, sw, sh, ox, oy, dw, dh, &dx, &dy, &rows, &cols);
|
||||
// FIXME/TODO: Clip to context clip
|
||||
|
||||
if (cols <= 0 || rows <= 0)
|
||||
if ((dw <= 0) || (dh <= 0) || (sw <= 0) || (sh <= 0))
|
||||
return EINA_TRUE;
|
||||
|
||||
srcdata += sy * sw;
|
||||
dstdata += dy * dw;
|
||||
for (y = rows; y; y--)
|
||||
// Stretch if necessary.
|
||||
if ((sw != dw || sh != dh) && (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_XY))
|
||||
{
|
||||
DATA32 *s = srcdata + sx;
|
||||
DATA8 *d = dstdata + dx;
|
||||
for (x = cols; x; x--, d++, s++)
|
||||
{
|
||||
// TODO: Add weights?
|
||||
*d = DIVIDE(R_VAL(s) + G_VAL(s) + B_VAL(s));
|
||||
}
|
||||
srcdata += sw;
|
||||
dstdata += dw;
|
||||
Evas_Filter_Buffer *fb;
|
||||
|
||||
if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_X)
|
||||
sw = dw;
|
||||
if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_Y)
|
||||
sh = dh;
|
||||
|
||||
BUFFERS_LOCK();
|
||||
fb = evas_filter_buffer_scaled_get(cmd->ctx, cmd->input, sw, sh);
|
||||
BUFFERS_UNLOCK();
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(fb, EINA_FALSE);
|
||||
fb->locked = EINA_FALSE;
|
||||
in = fb->backing;
|
||||
}
|
||||
|
||||
_mapped_blend_cpu(cmd->ENDT, NULL, in, out, cmd->draw.fillmode,
|
||||
sx, sy, sw, sh, dx, dy, dw, dh,
|
||||
_image_draw_cpu_rgba2alpha);
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue