forked from enlightenment/efl
evas filters: Fix blur logic and GL buffer handling
This corrects two things: - the blur filter high-level logic, that lead to reusing some temporary buffers which contained garbage; - the versatile gl buffer implementation so that it now properly switches between the RGBA_Image and the FBO content (yes, this is insanely slow and inefficient... but it works and that was the only point).
This commit is contained in:
parent
2ef8d6f39a
commit
92dfe1831c
|
@ -341,7 +341,6 @@ evas_filter_buffer_empty_new(Evas_Filter_Context *ctx, Eina_Bool alpha_only)
|
|||
fb = _buffer_empty_new(ctx, 0, 0, alpha_only, EINA_FALSE);
|
||||
if (!fb) return -1;
|
||||
|
||||
XDBG("Created context buffer %d %s", fb->id, alpha_only ? "alpha" : "rgba");
|
||||
return fb->id;
|
||||
}
|
||||
|
||||
|
@ -403,7 +402,7 @@ evas_filter_buffer_backing_steal(Evas_Filter_Context *ctx, int bufid)
|
|||
fb = _filter_buffer_get(ctx, bufid);
|
||||
if (!fb) return NULL;
|
||||
|
||||
return evas_ector_buffer_drawable_image_get(fb->buffer, EINA_TRUE);
|
||||
return evas_ector_buffer_drawable_image_get(fb->buffer);
|
||||
}
|
||||
|
||||
Eina_Bool
|
||||
|
@ -434,6 +433,7 @@ _command_new(Evas_Filter_Context *ctx, Evas_Filter_Mode mode,
|
|||
cmd->input = input;
|
||||
cmd->mask = mask;
|
||||
cmd->output = output;
|
||||
if (output) output->dirty = EINA_TRUE;
|
||||
|
||||
ctx->commands = eina_inlist_append(ctx->commands, EINA_INLIST_GET(cmd));
|
||||
return cmd;
|
||||
|
@ -454,19 +454,20 @@ _command_del(Evas_Filter_Context *ctx, Evas_Filter_Command *cmd)
|
|||
|
||||
Evas_Filter_Buffer *
|
||||
evas_filter_temporary_buffer_get(Evas_Filter_Context *ctx, int w, int h,
|
||||
Eina_Bool alpha_only)
|
||||
Eina_Bool alpha_only, Eina_Bool clean)
|
||||
{
|
||||
Evas_Filter_Buffer *buf = NULL;
|
||||
Evas_Filter_Buffer *fb = NULL;
|
||||
Eina_List *l;
|
||||
|
||||
EINA_LIST_FOREACH(ctx->buffers, l, buf)
|
||||
EINA_LIST_FOREACH(ctx->buffers, l, fb)
|
||||
{
|
||||
if (buf->transient && !buf->locked && (buf->alpha_only == alpha_only))
|
||||
if (fb->transient && !fb->locked && (fb->alpha_only == alpha_only)
|
||||
&& (!clean || !fb->dirty))
|
||||
{
|
||||
if ((!w || (w == buf->w)) && (!h || (h == buf->h)))
|
||||
if ((!w || (w == fb->w)) && (!h || (h == fb->h)))
|
||||
{
|
||||
buf->locked = EINA_TRUE;
|
||||
return buf;
|
||||
fb->locked = EINA_TRUE;
|
||||
return fb;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -477,10 +478,11 @@ evas_filter_temporary_buffer_get(Evas_Filter_Context *ctx, int w, int h,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
buf = _buffer_empty_new(ctx, w, h, alpha_only, EINA_TRUE);
|
||||
buf->locked = EINA_TRUE;
|
||||
fb = _buffer_empty_new(ctx, w, h, alpha_only, EINA_TRUE);
|
||||
fb->locked = EINA_TRUE;
|
||||
XDBG("Created temporary buffer %d %s", fb->id, alpha_only ? "alpha" : "rgba");
|
||||
|
||||
return buf;
|
||||
return fb;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -522,7 +524,9 @@ evas_filter_command_fill_add(Evas_Filter_Context *ctx, void *draw_context,
|
|||
|
||||
XDBG("Add fill %d with color(%d,%d,%d,%d)", buf->id, R, G, B, A);
|
||||
|
||||
buf->dirty = EINA_TRUE;
|
||||
if (!R && !G && !B && !A)
|
||||
buf->dirty = EINA_FALSE;
|
||||
|
||||
return cmd;
|
||||
}
|
||||
|
||||
|
@ -533,10 +537,16 @@ evas_filter_command_blur_add(Evas_Filter_Context *ctx, void *drawctx,
|
|||
{
|
||||
Evas_Filter_Buffer *in = NULL, *out = NULL, *tmp = NULL, *in_dy = NULL;
|
||||
Evas_Filter_Buffer *out_dy = NULL, *out_dx = NULL;
|
||||
Evas_Filter_Buffer *copybuf = NULL, *blur_out = NULL;
|
||||
Eina_Bool copy_back = EINA_FALSE, blend = EINA_FALSE;
|
||||
Evas_Filter_Buffer *copybuf = NULL, *blendbuf = NULL;
|
||||
Evas_Filter_Command *cmd = NULL;
|
||||
int R, G, B, A; DATA32 color;
|
||||
int R, G, B, A, render_op;
|
||||
Eina_Bool override;
|
||||
DATA32 color;
|
||||
|
||||
// Note (SW engine):
|
||||
// The basic blur operation overrides the pixels in the target buffer,
|
||||
// only supports one direction (X or Y) and no offset. As a consequence
|
||||
// most cases require intermediate work buffers.
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, NULL);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(drawctx, NULL);
|
||||
|
@ -555,20 +565,19 @@ evas_filter_command_blur_add(Evas_Filter_Context *ctx, void *drawctx,
|
|||
out = _filter_buffer_get(ctx, outbuf);
|
||||
EINA_SAFETY_ON_FALSE_GOTO(out, fail);
|
||||
|
||||
if (!in->alpha_only && out->alpha_only)
|
||||
DBG("Different color formats, implicit conversion may be slow");
|
||||
|
||||
if (in == out) out->dirty = EINA_FALSE;
|
||||
blend = (out->dirty && !out->transient);
|
||||
|
||||
ENFN->context_color_get(ENDT, drawctx, &R, &G, &B, &A);
|
||||
color = ARGB_JOIN(A, R, G, B);
|
||||
if (!color)
|
||||
{
|
||||
DBG("Blur with transparent color. Nothing to do.");
|
||||
/* FIXME: return skip; */
|
||||
return _command_new(ctx, EVAS_FILTER_MODE_SKIP, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
render_op = ENFN->context_render_op_get(ENDT, drawctx);
|
||||
override = (render_op == EVAS_RENDER_COPY);
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case EVAS_FILTER_BLUR_GAUSSIAN:
|
||||
|
@ -580,48 +589,47 @@ evas_filter_command_blur_add(Evas_Filter_Context *ctx, void *drawctx,
|
|||
break;
|
||||
|
||||
case EVAS_FILTER_BLUR_DEFAULT:
|
||||
|
||||
/* In DEFAULT mode we cheat, depending on the size of the kernel:
|
||||
* For 1px to 2px, use true Gaussian blur.
|
||||
* For 3px to 6px, use two Box blurs.
|
||||
* For more than 6px, use three Box blurs.
|
||||
* This will give both nicer and MUCH faster results than Gaussian.
|
||||
*
|
||||
* NOTE: When implementing blur with GL shaders, other tricks will be
|
||||
* needed, of course!
|
||||
*/
|
||||
{
|
||||
const Eina_Bool alpha = in->alpha_only;
|
||||
/* In DEFAULT mode we cheat, depending on the size of the kernel:
|
||||
* For 1px to 2px, use true Gaussian blur.
|
||||
* For 3px to 6px, use two Box blurs.
|
||||
* For more than 6px, use three Box blurs.
|
||||
* This will give both nicer and MUCH faster results than Gaussian.
|
||||
*
|
||||
* NOTE: This step should be avoided in GL.
|
||||
*/
|
||||
|
||||
int tmp_out = outbuf;
|
||||
int tmp_in = inbuf;
|
||||
int tmp_ox = ox;
|
||||
int tmp_oy = oy;
|
||||
|
||||
// For 2D blur: create intermediate buffer
|
||||
if (dx && dy)
|
||||
{
|
||||
tmp = evas_filter_temporary_buffer_get(ctx, 0, 0, alpha);
|
||||
tmp = evas_filter_temporary_buffer_get(ctx, 0, 0, in->alpha_only, 1);
|
||||
if (!tmp) goto fail;
|
||||
tmp_in = tmp_out = tmp->id;
|
||||
tmp_ox = tmp_oy = 0;
|
||||
}
|
||||
|
||||
// X box blur
|
||||
if (dx)
|
||||
{
|
||||
if (dx <= 2)
|
||||
type = EVAS_FILTER_BLUR_GAUSSIAN;
|
||||
else
|
||||
type = EVAS_FILTER_BLUR_BOX;
|
||||
type = EVAS_FILTER_BLUR_BOX;
|
||||
|
||||
if (dy && (color != 0xFFFFFFFF))
|
||||
ENFN->context_color_set(ENDT, drawctx, 255, 255, 255, 255);
|
||||
if (dy) ENFN->context_color_set(ENDT, drawctx, 255, 255, 255, 255);
|
||||
cmd = evas_filter_command_blur_add(ctx, drawctx, inbuf, tmp_out,
|
||||
type, dx, 0, tmp_ox, tmp_oy, 0);
|
||||
if (!cmd) goto fail;
|
||||
cmd->blur.auto_count = EINA_TRUE;
|
||||
if (dy && (color != 0xFFFFFFFF))
|
||||
ENFN->context_color_set(ENDT, drawctx, R, G, B, A);
|
||||
if (dy) ENFN->context_color_set(ENDT, drawctx, R, G, B, A);
|
||||
}
|
||||
|
||||
// Y box blur
|
||||
if (dy)
|
||||
{
|
||||
if (dy <= 2)
|
||||
|
@ -629,51 +637,39 @@ evas_filter_command_blur_add(Evas_Filter_Context *ctx, void *drawctx,
|
|||
else
|
||||
type = EVAS_FILTER_BLUR_BOX;
|
||||
|
||||
if (dx && (inbuf == outbuf))
|
||||
ENFN->context_render_op_set(ENDT, drawctx, EVAS_RENDER_COPY);
|
||||
cmd = evas_filter_command_blur_add(ctx, drawctx, tmp_in, outbuf,
|
||||
type, 0, dy, ox, oy, 0);
|
||||
if (dx && (inbuf == outbuf))
|
||||
ENFN->context_render_op_set(ENDT, drawctx, render_op);
|
||||
if (!cmd) goto fail;
|
||||
cmd->blur.auto_count = EINA_TRUE;
|
||||
}
|
||||
|
||||
return cmd;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
CRI("Not implemented yet!");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if ((blend || (in->alpha_only && !out->alpha_only)) ||
|
||||
(!blend && !in->alpha_only && !out->alpha_only && (color != 0xFFFFFFFF)) ||
|
||||
(!in->alpha_only && out->alpha_only))
|
||||
{
|
||||
XDBG("Adding extra blending step %d --> %d (%s --> %s)", in->id, out->id,
|
||||
in->alpha_only ? "Alpha" : "RGBA",
|
||||
out->alpha_only ? "Alpha" : "RGBA");
|
||||
Eina_Bool wasl = in->locked;
|
||||
in->locked = 1;
|
||||
blur_out = evas_filter_temporary_buffer_get(ctx, 0, 0, in->alpha_only);
|
||||
in->locked = wasl;
|
||||
if (!blur_out) goto fail;
|
||||
blend = EINA_TRUE;
|
||||
}
|
||||
else
|
||||
blur_out = out;
|
||||
|
||||
// For 2D blur: create intermediate buffer between X and Y passes
|
||||
if (dx && dy)
|
||||
{
|
||||
tmp = evas_filter_temporary_buffer_get(ctx, 0, 0, in->alpha_only);
|
||||
if (!tmp) goto fail;
|
||||
|
||||
if (!blend && (ox || oy))
|
||||
// If there's an offset: create intermediate buffer before offset blend
|
||||
if (ox || oy)
|
||||
{
|
||||
copybuf = evas_filter_temporary_buffer_get(ctx, 0, 0, in->alpha_only);
|
||||
copybuf = evas_filter_temporary_buffer_get(ctx, 0, 0, in->alpha_only, 0);
|
||||
if (!copybuf) goto fail;
|
||||
copy_back = EINA_TRUE;
|
||||
}
|
||||
|
||||
if (in == blur_out)
|
||||
// Intermediate buffer between X and Y passes
|
||||
tmp = evas_filter_temporary_buffer_get(ctx, 0, 0, in->alpha_only, 0);
|
||||
if (!tmp) goto fail;
|
||||
|
||||
if (in == out)
|
||||
{
|
||||
// IN = OUT and 2-D blur. IN -blur-> TMP -blur-> IN.
|
||||
out_dx = tmp;
|
||||
|
@ -685,43 +681,80 @@ evas_filter_command_blur_add(Evas_Filter_Context *ctx, void *drawctx,
|
|||
// IN != OUT and 2-D blur. IN -blur-> TMP -blur-> OUT.
|
||||
out_dx = tmp;
|
||||
in_dy = tmp;
|
||||
out_dy = copybuf ? copybuf : blur_out;
|
||||
out_dy = copybuf ? copybuf : out;
|
||||
}
|
||||
}
|
||||
else if (dx)
|
||||
{
|
||||
if ((in == blur_out) || ox || oy)
|
||||
// X blur only
|
||||
if (in == out)
|
||||
{
|
||||
// IN = OUT and 1-D blur. IN -blur-> TMP -copy-> IN.
|
||||
tmp = evas_filter_temporary_buffer_get(ctx, 0, 0, in->alpha_only);
|
||||
tmp = evas_filter_temporary_buffer_get(ctx, 0, 0, in->alpha_only, 0);
|
||||
if (!tmp) goto fail;
|
||||
copy_back = EINA_TRUE;
|
||||
copybuf = tmp;
|
||||
out_dx = tmp;
|
||||
}
|
||||
else if (ox || oy || (color != 0xFFFFFFFF))
|
||||
{
|
||||
// IN != OUT and 1-D blur. IN -blur-> TMP -blend-> OUT.
|
||||
tmp = evas_filter_temporary_buffer_get(ctx, 0, 0, in->alpha_only, 0);
|
||||
if (!tmp) goto fail;
|
||||
blendbuf = tmp;
|
||||
out_dx = tmp;
|
||||
}
|
||||
else if (out->dirty)
|
||||
{
|
||||
// IN != OUT and 1-D blur. IN -blur-> TMP -blend-> OUT.
|
||||
tmp = evas_filter_temporary_buffer_get(ctx, 0, 0, in->alpha_only, 0);
|
||||
if (!tmp) goto fail;
|
||||
blendbuf = tmp;
|
||||
out_dx = tmp;
|
||||
}
|
||||
else
|
||||
{
|
||||
// IN != OUT and 1-D blur. IN -blur-> OUT.
|
||||
out_dx = blur_out;
|
||||
out_dx = out;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((in == blur_out) || ox || oy)
|
||||
// Y blur only
|
||||
if (in == out)
|
||||
{
|
||||
// IN = OUT and 1-D blur. IN -blur-> TMP -copy-> IN.
|
||||
tmp = evas_filter_temporary_buffer_get(ctx, 0, 0, in->alpha_only);
|
||||
tmp = evas_filter_temporary_buffer_get(ctx, 0, 0, in->alpha_only, 0);
|
||||
if (!tmp) goto fail;
|
||||
copy_back = EINA_TRUE;
|
||||
copybuf = tmp;
|
||||
in_dy = in;
|
||||
out_dy = tmp;
|
||||
}
|
||||
else if (ox || oy || (color != 0xFFFFFFFF))
|
||||
{
|
||||
// IN != OUT and 1-D blur. IN -blur-> TMP -blend-> IN.
|
||||
tmp = evas_filter_temporary_buffer_get(ctx, 0, 0, in->alpha_only, 0);
|
||||
if (!tmp) goto fail;
|
||||
if (override)
|
||||
copybuf = tmp;
|
||||
else
|
||||
blendbuf = tmp;
|
||||
in_dy = in;
|
||||
out_dy = tmp;
|
||||
}
|
||||
else if (out->dirty && !override)
|
||||
{
|
||||
// IN != OUT and 1-D blur. IN -blur-> TMP -blend-> OUT.
|
||||
tmp = evas_filter_temporary_buffer_get(ctx, 0, 0, in->alpha_only, 0);
|
||||
if (!tmp) goto fail;
|
||||
blendbuf = tmp;
|
||||
in_dy = in;
|
||||
out_dy = tmp;
|
||||
}
|
||||
else
|
||||
{
|
||||
// IN != OUT and 1-D blur. IN -blur-> OUT.
|
||||
in_dy = in;
|
||||
out_dy = blur_out;
|
||||
out_dy = out;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -734,8 +767,7 @@ evas_filter_command_blur_add(Evas_Filter_Context *ctx, void *drawctx,
|
|||
cmd->blur.dx = dx;
|
||||
cmd->blur.dy = 0;
|
||||
cmd->blur.count = count;
|
||||
if (!dy && !blend)
|
||||
DRAW_COLOR_SET(R, G, B, A);
|
||||
if (!dy) DRAW_COLOR_SET(R, G, B, A);
|
||||
}
|
||||
|
||||
if (dy)
|
||||
|
@ -747,38 +779,36 @@ evas_filter_command_blur_add(Evas_Filter_Context *ctx, void *drawctx,
|
|||
cmd->blur.dx = 0;
|
||||
cmd->blur.dy = dy;
|
||||
cmd->blur.count = count;
|
||||
if (!blend)
|
||||
DRAW_COLOR_SET(R, G, B, A);
|
||||
DRAW_COLOR_SET(R, G, B, A);
|
||||
}
|
||||
|
||||
if (copy_back)
|
||||
if (blendbuf)
|
||||
{
|
||||
Evas_Filter_Command *blendcmd;
|
||||
|
||||
XDBG("Add extra blend %d -> %d", blendbuf->id, out->id);
|
||||
blendcmd = evas_filter_command_blend_add(ctx, drawctx,
|
||||
blendbuf->id, out->id, ox, oy,
|
||||
EVAS_FILTER_FILL_MODE_NONE);
|
||||
if (!blendcmd) goto fail;
|
||||
ox = oy = 0;
|
||||
}
|
||||
else if (copybuf)
|
||||
{
|
||||
Evas_Filter_Command *copycmd;
|
||||
int render_op;
|
||||
|
||||
if (!cmd) goto fail;
|
||||
XDBG("Add copy %d -> %d", copybuf->id, blur_out->id);
|
||||
XDBG("Add extra copy %d -> %d: offset: %d,%d", copybuf->id, out->id, ox, oy);
|
||||
ENFN->context_color_set(ENDT, drawctx, 255, 255, 255, 255);
|
||||
render_op = ENFN->context_render_op_get(ENDT, drawctx);
|
||||
ENFN->context_render_op_set(ENDT, drawctx, EVAS_RENDER_COPY);
|
||||
copycmd = evas_filter_command_blend_add(ctx, drawctx, copybuf->id, blur_out->id, ox, oy, EVAS_FILTER_FILL_MODE_NONE);
|
||||
copycmd = evas_filter_command_blend_add(ctx, drawctx,
|
||||
copybuf->id, out->id, ox, oy,
|
||||
EVAS_FILTER_FILL_MODE_NONE);
|
||||
ENFN->context_color_set(ENDT, drawctx, R, G, B, A);
|
||||
ENFN->context_render_op_set(ENDT, drawctx, render_op);
|
||||
if (!copycmd) goto fail;
|
||||
ox = oy = 0;
|
||||
}
|
||||
|
||||
if (blend)
|
||||
{
|
||||
Evas_Filter_Command *blendcmd;
|
||||
|
||||
XDBG("Add blend %d (%s) -> %d (%s)",
|
||||
blur_out->id, blur_out->alpha_only ? "Alpha" : "RGBA",
|
||||
out->id, out->alpha_only ? "Alpha" : "RGBA");
|
||||
blendcmd = evas_filter_command_blend_add(ctx, drawctx, blur_out->id, out->id, ox, oy, EVAS_FILTER_FILL_MODE_NONE);
|
||||
if (!blendcmd) goto fail;
|
||||
}
|
||||
|
||||
out->dirty = EINA_TRUE;
|
||||
_filter_buffer_unlock_all(ctx);
|
||||
return cmd;
|
||||
|
@ -796,6 +826,7 @@ evas_filter_command_blend_add(Evas_Filter_Context *ctx, void *drawctx,
|
|||
{
|
||||
Evas_Filter_Command *cmd;
|
||||
Evas_Filter_Buffer *in, *out;
|
||||
Eina_Bool copy;
|
||||
int R, G, B, A;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, NULL);
|
||||
|
@ -823,18 +854,24 @@ evas_filter_command_blend_add(Evas_Filter_Context *ctx, void *drawctx,
|
|||
cmd = _command_new(ctx, EVAS_FILTER_MODE_BLEND, in, NULL, out);
|
||||
if (!cmd) return NULL;
|
||||
|
||||
if (ENFN->context_render_op_get(ENDT, drawctx) == EVAS_RENDER_COPY)
|
||||
copy = EINA_TRUE;
|
||||
else
|
||||
copy = EINA_FALSE;
|
||||
|
||||
ENFN->context_color_get(ENDT, drawctx, &R, &G, &B, &A);
|
||||
DRAW_COLOR_SET(R, G, B, A);
|
||||
DRAW_FILL_SET(fillmode);
|
||||
cmd->draw.ox = ox;
|
||||
cmd->draw.oy = oy;
|
||||
cmd->draw.rop = _evas_to_gfx_render_op(ENFN->context_render_op_get(ENDT, drawctx));
|
||||
cmd->draw.rop = copy ? EFL_GFX_RENDER_OP_COPY : EFL_GFX_RENDER_OP_BLEND;
|
||||
cmd->draw.clip_use =
|
||||
ENFN->context_clip_get(ENDT, drawctx,
|
||||
&cmd->draw.clip.x, &cmd->draw.clip.y,
|
||||
&cmd->draw.clip.w, &cmd->draw.clip.h);
|
||||
|
||||
XDBG("Add blend %d -> %d", in->id, out->id);
|
||||
XDBG("Add %s %d -> %d: offset %d,%d, color: %d,%d,%d,%d",
|
||||
copy ? "copy" : "blend", in->id, out->id, ox, oy, R, G, B, A);
|
||||
if (cmd->draw.clip_use)
|
||||
XDBG("Draw clip: %d,%d,%d,%d", cmd->draw.clip.x, cmd->draw.clip.y,
|
||||
cmd->draw.clip.w, cmd->draw.clip.h);
|
||||
|
@ -864,9 +901,12 @@ evas_filter_command_grow_add(Evas_Filter_Context *ctx, void *draw_context,
|
|||
in = _filter_buffer_get(ctx, inbuf);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(in, NULL);
|
||||
|
||||
if (inbuf != outbuf)
|
||||
out = _filter_buffer_get(ctx, outbuf);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(out, NULL);
|
||||
|
||||
if ((inbuf != outbuf) && out->dirty)
|
||||
{
|
||||
tmp = evas_filter_temporary_buffer_get(ctx, in->w, in->h, in->alpha_only);
|
||||
tmp = evas_filter_temporary_buffer_get(ctx, in->w, in->h, in->alpha_only, 1);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(tmp, NULL);
|
||||
growbuf = tmp->id;
|
||||
}
|
||||
|
@ -901,16 +941,6 @@ evas_filter_command_grow_add(Evas_Filter_Context *ctx, void *draw_context,
|
|||
memset(curve + end, 255, 256 - end);
|
||||
}
|
||||
|
||||
out = _filter_buffer_get(ctx, growbuf);
|
||||
if (!out) return NULL;
|
||||
out->dirty = EINA_TRUE;
|
||||
if (growbuf != outbuf)
|
||||
{
|
||||
out = _filter_buffer_get(ctx, growbuf);
|
||||
if (!out) return NULL;
|
||||
out->dirty = EINA_TRUE;
|
||||
}
|
||||
|
||||
threshcmd = evas_filter_command_curve_add(ctx, draw_context, growbuf, growbuf,
|
||||
curve, EVAS_FILTER_CHANNEL_ALPHA);
|
||||
if (!threshcmd)
|
||||
|
@ -973,7 +1003,6 @@ evas_filter_command_curve_add(Evas_Filter_Context *ctx,
|
|||
cmd->curve.data = copy;
|
||||
cmd->curve.channel = channel;
|
||||
|
||||
out->dirty = EINA_TRUE;
|
||||
return cmd;
|
||||
}
|
||||
|
||||
|
@ -1009,7 +1038,7 @@ evas_filter_command_displacement_map_add(Evas_Filter_Context *ctx,
|
|||
|
||||
if (in == out)
|
||||
{
|
||||
tmp = evas_filter_temporary_buffer_get(ctx, in->w, in->h, in->alpha_only);
|
||||
tmp = evas_filter_temporary_buffer_get(ctx, in->w, in->h, in->alpha_only, 1);
|
||||
if (!tmp) return NULL;
|
||||
disp_out = tmp;
|
||||
}
|
||||
|
@ -1033,8 +1062,6 @@ evas_filter_command_displacement_map_add(Evas_Filter_Context *ctx,
|
|||
if (!fillcmd) goto fail;
|
||||
}
|
||||
|
||||
out->dirty = EINA_TRUE;
|
||||
|
||||
_filter_buffer_unlock_all(ctx);
|
||||
return cmd;
|
||||
|
||||
|
@ -1072,7 +1099,6 @@ evas_filter_command_mask_add(Evas_Filter_Context *ctx, void *draw_context,
|
|||
cmd->draw.rop = render_op;
|
||||
DRAW_COLOR_SET(R, G, B, A);
|
||||
DRAW_FILL_SET(fillmode);
|
||||
out->dirty = EINA_TRUE;
|
||||
|
||||
return cmd;
|
||||
}
|
||||
|
@ -1122,7 +1148,6 @@ evas_filter_command_bump_map_add(Evas_Filter_Context *ctx,
|
|||
cmd->bump.white = white;
|
||||
cmd->bump.elevation = elevation;
|
||||
cmd->bump.compensate = !!(flags & EVAS_FILTER_BUMP_COMPENSATE);
|
||||
out->dirty = EINA_TRUE;
|
||||
|
||||
return cmd;
|
||||
}
|
||||
|
@ -1160,8 +1185,6 @@ evas_filter_command_transform_add(Evas_Filter_Context *ctx,
|
|||
else
|
||||
cmd->draw.rop = EFL_GFX_RENDER_OP_BLEND;
|
||||
|
||||
out->dirty = EINA_TRUE;
|
||||
|
||||
return cmd;
|
||||
}
|
||||
|
||||
|
@ -1211,7 +1234,7 @@ _filter_target_render(Evas_Filter_Context *ctx)
|
|||
src = _filter_buffer_get(ctx, EVAS_FILTER_BUFFER_OUTPUT_ID);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(src, EINA_FALSE);
|
||||
|
||||
image = evas_ector_buffer_drawable_image_get(src->buffer, EINA_FALSE);
|
||||
image = evas_ector_buffer_drawable_image_get(src->buffer);
|
||||
EINA_SAFETY_ON_NULL_GOTO(image, fail);
|
||||
|
||||
// FIXME: Use ector buffer RENDERER here
|
||||
|
@ -1272,7 +1295,7 @@ evas_filter_font_draw(Evas_Filter_Context *ctx, void *draw_context, int bufid,
|
|||
fb = _filter_buffer_get(ctx, bufid);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(fb, EINA_FALSE);
|
||||
|
||||
surface = evas_ector_buffer_render_image_get(fb->buffer, EINA_FALSE);
|
||||
surface = evas_ector_buffer_render_image_get(fb->buffer);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(surface, EINA_FALSE);
|
||||
|
||||
// Copied from evas_font_draw_async_check
|
||||
|
@ -1306,7 +1329,7 @@ evas_filter_image_draw(Evas_Filter_Context *ctx, void *draw_context, int bufid,
|
|||
fb = _filter_buffer_get(ctx, bufid);
|
||||
if (!fb) return EINA_FALSE;
|
||||
|
||||
surface = evas_ector_buffer_render_image_get(fb->buffer, EINA_FALSE);
|
||||
surface = evas_ector_buffer_render_image_get(fb->buffer);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(surface, EINA_FALSE);
|
||||
|
||||
ENFN->image_size_get(ENDT, image, &dw, &dh);
|
||||
|
@ -1391,6 +1414,7 @@ _filter_name_get(int mode)
|
|||
#define FNAME(a) case EVAS_FILTER_MODE_ ## a: return "EVAS_FILTER_MODE_" #a
|
||||
switch (mode)
|
||||
{
|
||||
FNAME(SKIP);
|
||||
FNAME(BLEND);
|
||||
FNAME(BLUR);
|
||||
FNAME(CURVE);
|
||||
|
@ -1409,6 +1433,9 @@ _filter_command_run(Evas_Filter_Command *cmd)
|
|||
{
|
||||
Evas_Filter_Support support = EVAS_FILTER_SUPPORT_NONE;
|
||||
|
||||
if (cmd->mode == EVAS_FILTER_MODE_SKIP)
|
||||
return EINA_TRUE;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output, EINA_FALSE);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input, EINA_FALSE);
|
||||
|
||||
|
|
|
@ -2861,6 +2861,8 @@ _buffers_update(Evas_Filter_Context *ctx, Evas_Filter_Program *pgm)
|
|||
pgm->changed = EINA_TRUE;
|
||||
buf->w = fb->w = source->cur->geometry.w;
|
||||
buf->h = fb->h = source->cur->geometry.h;
|
||||
XDBG("Created proxy buffer %d %s '%s'", fb->id,
|
||||
buf->alpha ? "alpha" : "rgba", buf->name);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2870,6 +2872,8 @@ _buffers_update(Evas_Filter_Context *ctx, Evas_Filter_Program *pgm)
|
|||
fb = _filter_buffer_get(ctx, buf->cid);
|
||||
fb->w = buf->w = pgm->state.w;
|
||||
fb->h = buf->h = pgm->state.h;
|
||||
XDBG("Created context buffer %d %s '%s'", fb->id,
|
||||
buf->alpha ? "alpha" : "rgba", buf->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -266,7 +266,7 @@ void evas_filter_context_source_set(Evas_Filter_Context *ctx
|
|||
void _clip_to_target(int *sx, int *sy, int sw, int sh, int ox, int oy, int dw, int dh, int *dx, int *dy, int *rows, int *cols);
|
||||
Eina_Bool evas_filter_buffer_alloc(Evas_Filter_Buffer *fb, int w, int h);
|
||||
Evas_Filter_Buffer *_filter_buffer_get(Evas_Filter_Context *ctx, int bufid);
|
||||
Evas_Filter_Buffer *evas_filter_temporary_buffer_get(Evas_Filter_Context *ctx, int w, int h, Eina_Bool alpha_only);
|
||||
Evas_Filter_Buffer *evas_filter_temporary_buffer_get(Evas_Filter_Context *ctx, int w, int h, Eina_Bool alpha_only, Eina_Bool clean);
|
||||
Evas_Filter_Buffer *evas_filter_buffer_scaled_get(Evas_Filter_Context *ctx, Evas_Filter_Buffer *src, unsigned w, unsigned h);
|
||||
Eina_Bool evas_filter_interpolate(DATA8* output /* 256 values */, int *points /* 256 values */, Evas_Filter_Interpolation_Mode mode);
|
||||
int evas_filter_smallest_pow2_larger_than(int val);
|
||||
|
|
|
@ -19,7 +19,7 @@ evas_filter_buffer_scaled_get(Evas_Filter_Context *ctx,
|
|||
DEBUG_TIME_BEGIN();
|
||||
|
||||
// Get destination buffer
|
||||
dst = evas_filter_temporary_buffer_get(ctx, w, h, src->alpha_only);
|
||||
dst = evas_filter_temporary_buffer_get(ctx, w, h, src->alpha_only, 0);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(dst, NULL);
|
||||
|
||||
// Map input and output
|
||||
|
|
|
@ -19,16 +19,10 @@ interface Evas.Ector.Buffer
|
|||
}
|
||||
drawable_image_get {
|
||||
[[Fetch an engine image from this ector buffer as a drawable.]]
|
||||
params {
|
||||
@in update: bool; [[$true to update the data to the remote image.]]
|
||||
}
|
||||
return: void_ptr; [[The engine image (RGBA_Image or Evas_GL_Image).]]
|
||||
}
|
||||
render_image_get {
|
||||
[[Fetch an engine image from this ector buffer as a render target.]]
|
||||
params {
|
||||
@in update: bool; [[$true to update the data to the remote image.]]
|
||||
}
|
||||
return: void_ptr; [[The engine image (RGBA_Image or Evas_GL_Image).]]
|
||||
}
|
||||
engine_image_release {
|
||||
|
|
|
@ -55,6 +55,7 @@ typedef void (* Evas_Filter_Cb) (Evas_Filter_Context *ctx, void *data, Eina_Bool
|
|||
/** @internal */
|
||||
enum _Evas_Filter_Mode
|
||||
{
|
||||
EVAS_FILTER_MODE_SKIP, /**< No operation */
|
||||
EVAS_FILTER_MODE_BLEND, /**< Blend with current context render_op */
|
||||
EVAS_FILTER_MODE_BLUR, /**< @see Evas_Filter_Blur_Type */
|
||||
EVAS_FILTER_MODE_CURVE, /**< Apply color curve */
|
||||
|
|
|
@ -689,6 +689,7 @@ void evas_gl_common_image_update(Evas_Engine_GL_Context *gc, Evas_G
|
|||
void evas_gl_common_image_map_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im, int npoints, RGBA_Map_Point *p, int smooth, int level);
|
||||
void evas_gl_common_image_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im, int sx, int sy, int sw, int sh, int dx, int dy, int dw, int dh, int smooth);
|
||||
Evas_GL_Image *evas_gl_common_image_surface_update(Evas_Engine_GL_Context *gc, Evas_GL_Image *im);
|
||||
Evas_GL_Image *evas_gl_common_image_surface_detach(Evas_Engine_GL_Context *gc, Evas_GL_Image *im);
|
||||
|
||||
void *evas_gl_font_texture_new(void *gc, RGBA_Font_Glyph *fg);
|
||||
void evas_gl_font_texture_free(void *);
|
||||
|
|
|
@ -1100,6 +1100,17 @@ fail:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
Evas_GL_Image *
|
||||
evas_gl_common_image_surface_detach(Evas_Engine_GL_Context *gc EINA_UNUSED, Evas_GL_Image *im)
|
||||
{
|
||||
if (!im || !im->im) return im;
|
||||
|
||||
evas_cache_image_drop(&im->im->cache_entry);
|
||||
im->im = NULL;
|
||||
|
||||
return im;
|
||||
}
|
||||
|
||||
void
|
||||
evas_gl_common_image_map_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im,
|
||||
int npoints, RGBA_Map_Point *p, int smooth, int level EINA_UNUSED)
|
||||
|
|
|
@ -23,6 +23,8 @@
|
|||
typedef struct _Ector_GL_Buffer_Map Ector_GL_Buffer_Map;
|
||||
typedef struct _Evas_Ector_GL_Buffer_Data Evas_Ector_GL_Buffer_Data;
|
||||
|
||||
static int _map_id = 0;
|
||||
|
||||
struct _Ector_GL_Buffer_Map
|
||||
{
|
||||
EINA_INLIST;
|
||||
|
@ -30,6 +32,7 @@ struct _Ector_GL_Buffer_Map
|
|||
unsigned int base_size; // in bytes
|
||||
unsigned int x, y, w, h;
|
||||
void *image_data, *base_data;
|
||||
int map_id;
|
||||
size_t length;
|
||||
Efl_Gfx_Colorspace cspace;
|
||||
Evas_GL_Image *im;
|
||||
|
@ -41,7 +44,7 @@ struct _Evas_Ector_GL_Buffer_Data
|
|||
{
|
||||
Evas_Public_Data *evas;
|
||||
Evas_GL_Image *glim;
|
||||
Eina_Bool alpha_only;
|
||||
Eina_Bool alpha_only, was_render;
|
||||
Ector_GL_Buffer_Map *maps;
|
||||
};
|
||||
|
||||
|
@ -55,6 +58,20 @@ struct _Evas_Ector_GL_Buffer_Data
|
|||
|
||||
#define fail(fmt, ...) do { ERR(fmt, ##__VA_ARGS__); goto on_fail; } while (0)
|
||||
|
||||
#if 0
|
||||
static inline void
|
||||
_mapped_image_dump(Eo *buf, Evas_GL_Image *im, const char *fmt, int id)
|
||||
{
|
||||
if (!im || !im->im) return;
|
||||
evas_common_save_image_to_file(im->im, eina_slstr_printf("/tmp/dump/%s_%02d_buf_%p_im_%p.png", fmt, id, buf, im),
|
||||
NULL, 100, 9, NULL);
|
||||
}
|
||||
|
||||
#define MAP_DUMP(_im, _fmt) _mapped_image_dump(obj, _im, _fmt, map->map_id)
|
||||
#else
|
||||
#define MAP_DUMP(...)
|
||||
#endif
|
||||
|
||||
/* FIXME: Conversion routines don't belong here */
|
||||
static inline void
|
||||
_pixels_argb_to_gry8_convert(uint8_t *dst, const uint32_t *src, int len)
|
||||
|
@ -120,23 +137,14 @@ on_fail:
|
|||
pd->glim = NULL;
|
||||
}
|
||||
|
||||
EOLIAN static void *
|
||||
_evas_ector_gl_buffer_evas_ector_buffer_drawable_image_get(Eo *obj EINA_UNUSED,
|
||||
Evas_Ector_GL_Buffer_Data *pd,
|
||||
Eina_Bool update)
|
||||
static inline void *
|
||||
_image_get(Evas_Ector_GL_Buffer_Data *pd, Eina_Bool render)
|
||||
{
|
||||
Render_Engine_GL_Generic *re = pd->evas->engine.data.output;
|
||||
Evas_Engine_GL_Context *gc;
|
||||
|
||||
if (pd->maps != NULL)
|
||||
fail("Image is currently mapped!");
|
||||
|
||||
evas_gl_common_image_ref(pd->glim);
|
||||
if (!update) return pd->glim;
|
||||
|
||||
gc = re->window_gl_context_get(re->software.ob);
|
||||
evas_gl_common_image_update(gc, pd->glim);
|
||||
|
||||
if (render) pd->was_render = EINA_TRUE;
|
||||
return pd->glim;
|
||||
|
||||
on_fail:
|
||||
|
@ -144,26 +152,17 @@ on_fail:
|
|||
}
|
||||
|
||||
EOLIAN static void *
|
||||
_evas_ector_gl_buffer_evas_ector_buffer_render_image_get(Eo *obj EINA_UNUSED,
|
||||
Evas_Ector_GL_Buffer_Data *pd,
|
||||
Eina_Bool update)
|
||||
_evas_ector_gl_buffer_evas_ector_buffer_drawable_image_get(Eo *obj EINA_UNUSED,
|
||||
Evas_Ector_GL_Buffer_Data *pd)
|
||||
{
|
||||
Render_Engine_GL_Generic *re = pd->evas->engine.data.output;
|
||||
Evas_Engine_GL_Context *gc;
|
||||
return _image_get(pd, EINA_FALSE);
|
||||
}
|
||||
|
||||
if (pd->maps != NULL)
|
||||
fail("Image is currently mapped!");
|
||||
|
||||
evas_gl_common_image_ref(pd->glim);
|
||||
if (!update) return pd->glim;
|
||||
|
||||
gc = re->window_gl_context_get(re->software.ob);
|
||||
evas_gl_common_image_update(gc, pd->glim);
|
||||
|
||||
return pd->glim;
|
||||
|
||||
on_fail:
|
||||
return NULL;
|
||||
EOLIAN static void *
|
||||
_evas_ector_gl_buffer_evas_ector_buffer_render_image_get(Eo *obj EINA_UNUSED,
|
||||
Evas_Ector_GL_Buffer_Data *pd)
|
||||
{
|
||||
return _image_get(pd, EINA_TRUE);
|
||||
}
|
||||
|
||||
EOLIAN static Eina_Bool
|
||||
|
@ -174,6 +173,14 @@ _evas_ector_gl_buffer_evas_ector_buffer_engine_image_release(Eo *obj EINA_UNUSED
|
|||
EINA_SAFETY_ON_NULL_RETURN_VAL(image, EINA_FALSE);
|
||||
EINA_SAFETY_ON_FALSE_RETURN_VAL(pd->glim == image, EINA_FALSE);
|
||||
|
||||
if (pd->was_render)
|
||||
{
|
||||
Render_Engine_GL_Generic *re = pd->evas->engine.data.output;
|
||||
Evas_Engine_GL_Context *gc;
|
||||
|
||||
gc = re->window_gl_context_get(re->software.ob);
|
||||
pd->glim = evas_gl_common_image_surface_detach(gc, pd->glim);
|
||||
}
|
||||
evas_gl_common_image_free(pd->glim);
|
||||
|
||||
return EINA_TRUE;
|
||||
|
@ -270,12 +277,15 @@ _evas_ector_gl_buffer_ector_buffer_map(Eo *obj EINA_UNUSED, Evas_Ector_GL_Buffer
|
|||
pxs = 4;
|
||||
}
|
||||
|
||||
map->map_id = ++_map_id;
|
||||
map->base_size = len * pxs;
|
||||
map->length = (W * h + w - W) * pxs;
|
||||
if (stride) *stride = W * pxs;
|
||||
if (length) *length = map->length;
|
||||
|
||||
EINA_INLIST_PREPEND(pd->maps, map);;
|
||||
MAP_DUMP(im, "in");
|
||||
|
||||
EINA_INLIST_PREPEND(pd->maps, map);
|
||||
return map->ptr;
|
||||
|
||||
on_fail:
|
||||
|
@ -311,20 +321,28 @@ _evas_ector_gl_buffer_ector_buffer_unmap(Eo *obj EINA_UNUSED, Evas_Ector_GL_Buff
|
|||
|
||||
if (map->im)
|
||||
{
|
||||
MAP_DUMP(map->im, "out_w_free");
|
||||
pd->glim = evas_gl_common_image_surface_update(gc, map->im);
|
||||
evas_gl_common_image_free(old_glim);
|
||||
}
|
||||
else
|
||||
{
|
||||
MAP_DUMP(old_glim, "out_w_nofree");
|
||||
pd->glim = evas_gl_common_image_surface_update(gc, old_glim);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (map->im)
|
||||
ENFN->image_free(ENDT, map->im);
|
||||
{
|
||||
MAP_DUMP(map->im, "out_ro_free");
|
||||
ENFN->image_free(ENDT, map->im);
|
||||
}
|
||||
else
|
||||
ENFN->image_data_put(ENDT, pd->glim, map->image_data);
|
||||
{
|
||||
MAP_DUMP(pd->glim, "out_ro_nofree");
|
||||
ENFN->image_data_put(ENDT, pd->glim, map->image_data);
|
||||
}
|
||||
}
|
||||
if (map->allocated)
|
||||
free(map->base_data);
|
||||
|
|
|
@ -82,8 +82,7 @@ _evas_ector_gl_image_buffer_evas_ector_buffer_engine_image_set(Eo *obj, Evas_Ect
|
|||
|
||||
EOLIAN static void *
|
||||
_evas_ector_gl_image_buffer_evas_ector_buffer_drawable_image_get(Eo *obj EINA_UNUSED,
|
||||
Evas_Ector_GL_Image_Buffer_Data *pd,
|
||||
Eina_Bool update EINA_UNUSED)
|
||||
Evas_Ector_GL_Image_Buffer_Data *pd)
|
||||
{
|
||||
evas_gl_common_image_ref(pd->glim);
|
||||
return pd->glim;
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
|
||||
#define EVAS_GL_UPDATE_TILE_SIZE 16
|
||||
|
||||
static int _evas_engine_GL_log_dom = -1;
|
||||
int _evas_engine_GL_log_dom = -1;
|
||||
|
||||
#undef ERR
|
||||
#undef DBG
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
#include "evas_ector_buffer.eo.h"
|
||||
#include "../Evas_Engine_GL_Generic.h"
|
||||
|
||||
extern int _evas_engine_GL_log_dom;
|
||||
|
||||
typedef Eina_Bool (* GL_Filter_Apply_Func) (Render_Engine_GL_Generic *re, Evas_Filter_Command *cmd);
|
||||
GL_Filter_Apply_Func gl_filter_blend_func_get(Evas_Filter_Command *cmd);
|
||||
//Software_Filter_Func gl_filter_blur_func_get(Evas_Filter_Command *cmd);
|
||||
|
@ -16,4 +18,15 @@ GL_Filter_Apply_Func gl_filter_blend_func_get(Evas_Filter_Command *cmd);
|
|||
//Software_Filter_Func gl_filter_mask_func_get(Evas_Filter_Command *cmd);
|
||||
//Software_Filter_Func gl_filter_transform_func_get(Evas_Filter_Command *cmd);
|
||||
|
||||
#undef DBG
|
||||
#undef INF
|
||||
#undef WRN
|
||||
#undef ERR
|
||||
#undef CRI
|
||||
#define DBG(...) EINA_LOG_DOM_DBG(_evas_engine_GL_log_dom, __VA_ARGS__)
|
||||
#define INF(...) EINA_LOG_DOM_INFO(_evas_engine_GL_log_dom, __VA_ARGS__)
|
||||
#define WRN(...) EINA_LOG_DOM_WARN(_evas_engine_GL_log_dom, __VA_ARGS__)
|
||||
#define ERR(...) EINA_LOG_DOM_ERR(_evas_engine_GL_log_dom, __VA_ARGS__)
|
||||
#define CRI(...) EINA_LOG_DOM_CRIT(_evas_engine_GL_log_dom, __VA_ARGS__)
|
||||
|
||||
#endif // GL_ENGINE_FILTER_H
|
||||
|
|
|
@ -1,5 +1,162 @@
|
|||
#include "gl_engine_filter.h"
|
||||
|
||||
// Copied logic from SW engine
|
||||
static Eina_Bool
|
||||
_mapped_blend(Evas_Engine_GL_Context *gc,
|
||||
Evas_GL_Image *image,
|
||||
Evas_Filter_Fill_Mode fillmode,
|
||||
int sx, int sy, int sw, int sh,
|
||||
int dx, int dy, int dw, int dh)
|
||||
{
|
||||
int right = 0, bottom = 0, left = 0, top = 0;
|
||||
int row, col, rows, cols;
|
||||
Eina_Bool ret = EINA_TRUE;
|
||||
|
||||
EINA_SAFETY_ON_FALSE_RETURN_VAL((sx == 0) && (sy == 0), EINA_FALSE);
|
||||
|
||||
if (fillmode == EVAS_FILTER_FILL_MODE_NONE)
|
||||
{
|
||||
DBG("blend: %d,%d,%d,%d --> %d,%d,%d,%d", sx, sy, sw, sh, dx, dy, sw, sh);
|
||||
evas_gl_common_image_draw(gc, image, sx, sy, sw, sh, dx, dy, sw, sh, EINA_TRUE);
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
if (fillmode & EVAS_FILTER_FILL_MODE_REPEAT_X)
|
||||
{
|
||||
if (dx > 0) left = dx % sw;
|
||||
else if (dx < 0) left = sw + (dx % sw);
|
||||
cols = (dw /*- left*/) / sw;
|
||||
if (left > 0)
|
||||
right = dw - (sw * (cols - 1)) - left;
|
||||
else
|
||||
right = dw - (sw * cols);
|
||||
dx = 0;
|
||||
}
|
||||
else if (fillmode & EVAS_FILTER_FILL_MODE_STRETCH_X)
|
||||
{
|
||||
cols = 0;
|
||||
dx = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// FIXME: Probably wrong if dx != 0
|
||||
cols = 0;
|
||||
dw -= dx;
|
||||
}
|
||||
|
||||
if (fillmode & EVAS_FILTER_FILL_MODE_REPEAT_Y)
|
||||
{
|
||||
if (dy > 0) top = dy % sh;
|
||||
else if (dy < 0) top = sh + (dy % sh);
|
||||
rows = (dh /*- top*/) / sh;
|
||||
if (top > 0)
|
||||
bottom = dh - (sh * (rows - 1)) - top;
|
||||
else
|
||||
bottom = dh - (sh * rows);
|
||||
dy = 0;
|
||||
}
|
||||
else if (fillmode & EVAS_FILTER_FILL_MODE_STRETCH_Y)
|
||||
{
|
||||
rows = 0;
|
||||
dy = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// FIXME: Probably wrong if dy != 0
|
||||
rows = 0;
|
||||
dh -= dy;
|
||||
}
|
||||
|
||||
if (top > 0) row = -1;
|
||||
else row = 0;
|
||||
for (; row <= rows; row++)
|
||||
{
|
||||
int src_x, src_y, src_w, src_h;
|
||||
int dst_x, dst_y, dst_w, dst_h;
|
||||
|
||||
if (row == -1 && top > 0)
|
||||
{
|
||||
// repeat only
|
||||
src_h = top;
|
||||
src_y = sh - top;
|
||||
dst_y = dy;
|
||||
dst_h = src_h;
|
||||
}
|
||||
else if (row == rows && bottom > 0)
|
||||
{
|
||||
// repeat only
|
||||
src_h = bottom;
|
||||
src_y = 0;
|
||||
dst_y = top + dy + row * sh;
|
||||
dst_h = src_h;
|
||||
}
|
||||
else
|
||||
{
|
||||
src_y = 0;
|
||||
if (fillmode & EVAS_FILTER_FILL_MODE_STRETCH_Y)
|
||||
{
|
||||
src_h = sh;
|
||||
dst_h = dh;
|
||||
dst_y = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
dst_y = top + dy + row * sh;
|
||||
src_h = MIN(dh - dst_y, sh);
|
||||
dst_h = src_h;
|
||||
}
|
||||
}
|
||||
if (src_h <= 0 || dst_h <= 0) break;
|
||||
|
||||
if (left > 0) col = -1;
|
||||
else col = 0;
|
||||
for (; col <= cols; col++)
|
||||
{
|
||||
if (col == -1 && left > 0)
|
||||
{
|
||||
// repeat only
|
||||
src_w = left;
|
||||
src_x = sw - left;
|
||||
dst_x = dx;
|
||||
dst_w = src_w;
|
||||
}
|
||||
else if (col == cols && right > 0)
|
||||
{
|
||||
// repeat only
|
||||
src_w = right;
|
||||
src_x = 0;
|
||||
dst_x = left + dx + col * sw;
|
||||
dst_w = src_w;
|
||||
}
|
||||
else
|
||||
{
|
||||
src_x = 0;
|
||||
if (fillmode & EVAS_FILTER_FILL_MODE_STRETCH_X)
|
||||
{
|
||||
src_w = sw;
|
||||
dst_w = dw;
|
||||
dst_x = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
dst_x = left + dx + col * sw;
|
||||
src_w = MIN(dw - dst_x, sw);
|
||||
dst_w = src_w;
|
||||
}
|
||||
}
|
||||
if (src_w <= 0 || dst_w <= 0) break;
|
||||
|
||||
DBG("blend: [%d,%d] %d,%d,%dx%d --> %d,%d,%dx%d "
|
||||
"(src %dx%d, dst %dx%d)",
|
||||
col, row, src_x, src_y, src_w, src_h,
|
||||
dst_x, dst_y, dst_w, dst_h, sw, sh, dw, dh);
|
||||
evas_gl_common_image_draw(gc, image, src_x, src_y, src_w, src_h,
|
||||
dst_x, dst_y, dst_w, dst_h, EINA_TRUE);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_gl_filter_blend(Render_Engine_GL_Generic *re, Evas_Filter_Command *cmd)
|
||||
{
|
||||
|
@ -10,12 +167,12 @@ _gl_filter_blend(Render_Engine_GL_Generic *re, Evas_Filter_Command *cmd)
|
|||
re->window_use(re->software.ob);
|
||||
gc = re->window_gl_context_get(re->software.ob);
|
||||
|
||||
image = evas_ector_buffer_drawable_image_get(cmd->input->buffer, EINA_TRUE);
|
||||
image = evas_ector_buffer_drawable_image_get(cmd->input->buffer);
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(image, EINA_FALSE);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(image->tex, EINA_FALSE);
|
||||
|
||||
surface = evas_ector_buffer_render_image_get(cmd->output->buffer, EINA_FALSE);
|
||||
surface = evas_ector_buffer_render_image_get(cmd->output->buffer);
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(surface, EINA_FALSE);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(surface->tex, EINA_FALSE);
|
||||
|
@ -23,15 +180,15 @@ _gl_filter_blend(Render_Engine_GL_Generic *re, Evas_Filter_Command *cmd)
|
|||
EINA_SAFETY_ON_FALSE_RETURN_VAL(surface->tex->pt->fb != 0, EINA_FALSE);
|
||||
evas_gl_common_context_target_surface_set(gc, surface);
|
||||
|
||||
// TODO: mapped render iteration
|
||||
|
||||
dc_save = gc->dc;
|
||||
gc->dc = evas_common_draw_context_new();
|
||||
evas_common_draw_context_set_multiplier(gc->dc, cmd->draw.R, cmd->draw.G, cmd->draw.B, cmd->draw.A);
|
||||
gc->dc->render_op = _gfx_to_evas_render_op(cmd->draw.rop);
|
||||
|
||||
evas_gl_common_image_draw(gc, image, 0, 0, image->w, image->h,
|
||||
cmd->draw.ox, cmd->draw.oy, image->w, image->h,
|
||||
EINA_TRUE);
|
||||
DBG("blend %d @%p -> %d @%p", cmd->input->id, cmd->input->buffer,
|
||||
cmd->output->id, cmd->output->buffer);
|
||||
_mapped_blend(gc, image, cmd->draw.fillmode, 0, 0, image->w, image->h,
|
||||
cmd->draw.ox, cmd->draw.oy, cmd->output->w, cmd->output->h);
|
||||
|
||||
evas_common_draw_context_free(gc->dc);
|
||||
gc->dc = dc_save;
|
||||
|
|
|
@ -39,8 +39,7 @@ _evas_ector_software_buffer_evas_ector_buffer_engine_image_set(Eo *obj, Evas_Ect
|
|||
|
||||
EOLIAN static void *
|
||||
_evas_ector_software_buffer_evas_ector_buffer_drawable_image_get(Eo *obj EINA_UNUSED,
|
||||
Evas_Ector_Software_Buffer_Data *pd,
|
||||
Eina_Bool update EINA_UNUSED)
|
||||
Evas_Ector_Software_Buffer_Data *pd)
|
||||
{
|
||||
evas_cache_image_ref(&pd->image->cache_entry);
|
||||
return pd->image;
|
||||
|
@ -48,8 +47,7 @@ _evas_ector_software_buffer_evas_ector_buffer_drawable_image_get(Eo *obj EINA_UN
|
|||
|
||||
EOLIAN static void *
|
||||
_evas_ector_software_buffer_evas_ector_buffer_render_image_get(Eo *obj EINA_UNUSED,
|
||||
Evas_Ector_Software_Buffer_Data *pd,
|
||||
Eina_Bool update EINA_UNUSED)
|
||||
Evas_Ector_Software_Buffer_Data *pd)
|
||||
{
|
||||
evas_cache_image_ref(&pd->image->cache_entry);
|
||||
return pd->image;
|
||||
|
|
|
@ -208,7 +208,7 @@ _filter_displace_cpu_alpha(Evas_Filter_Command *cmd)
|
|||
EINA_SAFETY_ON_FALSE_RETURN_VAL(h == cmd->output->h, EINA_FALSE);
|
||||
|
||||
src = _buffer_map_all(cmd->input->buffer, &src_len, E_READ, E_ALPHA, &src_stride);
|
||||
dst = _buffer_map_all(cmd->output->buffer, &dst_len, E_READ, E_ALPHA, &dst_stride);
|
||||
dst = _buffer_map_all(cmd->output->buffer, &dst_len, E_READ | E_WRITE, E_ALPHA, &dst_stride);
|
||||
stretch = cmd->displacement.flags & EVAS_FILTER_DISPLACE_STRETCH;
|
||||
smooth = cmd->displacement.flags & EVAS_FILTER_DISPLACE_LINEAR;
|
||||
map_w = cmd->mask->w;
|
||||
|
|
|
@ -16,9 +16,6 @@ eng_filter_mask_func_get(Evas_Filter_Command *cmd)
|
|||
EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input, NULL);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output, NULL);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->mask, NULL);
|
||||
//EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input->buffer, NULL);
|
||||
//EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output->buffer, NULL);
|
||||
//EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->mask->buffer, NULL);
|
||||
EINA_SAFETY_ON_FALSE_RETURN_VAL((cmd->input->w > 0) && (cmd->input->h > 0), NULL);
|
||||
EINA_SAFETY_ON_FALSE_RETURN_VAL((cmd->mask->w > 0) && (cmd->mask->h > 0), NULL);
|
||||
EINA_SAFETY_ON_FALSE_RETURN_VAL(cmd->input->w == cmd->output->w, NULL);
|
||||
|
|
Loading…
Reference in New Issue