Evas filters: fix random cases of 'dancing text'

In some situations, text with filters would be rendered in an invalid
position (somewhere too high).
I am not entirely sure of the reason why the original code with BLEND
doesn't work, but this new version is simpler as GL and SW have more
similar behaviours:

- render text to our 'output' buffer
- draw this buffer as an image onto the set target

Thanks zmike for reporting the issue.
And thanks A LOT for using the filters :D

@fix

Signed-off-by: Jean-Philippe Andre <jp.andre@samsung.com>
This commit is contained in:
Jean-Philippe ANDRE 2014-03-02 18:39:08 +09:00 committed by Jean-Philippe Andre
parent 83746e5629
commit 6d4dd3f194
2 changed files with 48 additions and 31 deletions

View File

@ -1421,25 +1421,20 @@ evas_filter_target_set(Evas_Filter_Context *ctx, void *draw_context,
{
EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, EINA_FALSE);
if (!ctx->gl_engine)
{
ctx->target.bufid = evas_filter_buffer_image_new(ctx, surface);
evas_filter_command_blend_add(ctx, draw_context,
EVAS_FILTER_BUFFER_OUTPUT_ID,
ctx->target.bufid,
x, y, EVAS_FILTER_FILL_MODE_NONE);
}
else
ctx->target.bufid = evas_filter_buffer_image_new(ctx, surface);
ctx->target.x = x;
ctx->target.y = y;
ctx->target.clip_use = ENFN->context_clip_get
(ENDT, draw_context, &ctx->target.cx, &ctx->target.cy,
&ctx->target.cw, &ctx->target.ch);
if (ctx->gl_engine)
{
// Since GL has sync rendering, draw_context is safe to keep around
Evas_Filter_Buffer *target, *image;
RGBA_Image *im;
ctx->target.bufid = evas_filter_buffer_image_new(ctx, surface);
ctx->target.context = draw_context;
ctx->target.x = x;
ctx->target.y = y;
target = _filter_buffer_get(ctx, ctx->target.bufid);
target->glimage = target->backing;
target->backing = NULL;
@ -1457,32 +1452,52 @@ static Eina_Bool
_filter_target_render(Evas_Filter_Context *ctx)
{
Evas_Filter_Buffer *src, *dst;
Eina_Bool ok;
void *drawctx, *image, *surface;
int cx, cy, cw, ch;
Eina_Bool use_clip = EINA_FALSE;
/* FIXME: This is some hackish hook to send the final buffer on the screen
* Only used for OpenGL now, since evas_filter_target_set() adds a blend
* command in case of pure software rendering.
*/
if (!ctx->gl_engine) return EINA_FALSE;
EINA_SAFETY_ON_FALSE_RETURN_VAL(ctx->target.bufid, EINA_FALSE);
src = _filter_buffer_get(ctx, EVAS_FILTER_BUFFER_OUTPUT_ID);
if (!src) return EINA_FALSE;
dst = _filter_buffer_get(ctx, ctx->target.bufid);
if (!dst) return EINA_FALSE;
EINA_SAFETY_ON_NULL_RETURN_VAL(src, EINA_FALSE);
EINA_SAFETY_ON_NULL_RETURN_VAL(dst, EINA_FALSE);
EINA_SAFETY_ON_NULL_RETURN_VAL(src->glimage, EINA_FALSE);
EINA_SAFETY_ON_NULL_RETURN_VAL(dst->glimage, EINA_FALSE);
if (!ctx->gl_engine)
{
drawctx = ENFN->context_new(ENDT);
surface = dst->backing;
image = src->backing;
}
else
{
drawctx = ctx->target.context;
surface = dst->glimage;
image = src->glimage;
}
EINA_SAFETY_ON_NULL_RETURN_VAL(image, EINA_FALSE);
EINA_SAFETY_ON_NULL_RETURN_VAL(surface, EINA_FALSE);
ok = ENFN->image_draw(ENDT, ctx->target.context,
dst->glimage, src->glimage,
0, 0, src->w, src->h,
ctx->target.x, ctx->target.y, src->w, src->h,
EINA_TRUE, EINA_FALSE);
if (ctx->target.clip_use)
{
use_clip = ENFN->context_clip_get(ENDT, drawctx, &cx, &cy, &cw, &ch);
ENFN->context_clip_set(ENDT, drawctx, ctx->target.cx, ctx->target.cy,
ctx->target.cw, ctx->target.ch);
}
return ok;
ENFN->image_draw(ENDT, drawctx, surface, image,
0, 0, src->w, src->h,
ctx->target.x, ctx->target.y, src->w, src->h,
EINA_TRUE, EINA_FALSE);
if (!ctx->gl_engine)
ENFN->context_free(ENDT, drawctx);
else if (use_clip)
ENFN->context_clip_set(ENDT, drawctx, cx, cy, cw, ch);
else
ENFN->context_clip_unset(ENDT, drawctx);
return EINA_TRUE;
}

View File

@ -63,6 +63,8 @@ struct _Evas_Filter_Context
int bufid;
void *context;
int x, y;
int cx, cy, cw, ch; // clip
Eina_Bool clip_use : 1;
} target;
Eina_Bool async : 1;