forked from enlightenment/efl
evas filter: make curve work for every
Summary: If an input buffer and an output buffer for the curve filter are same, it reads and writes to the same texture which behavior is not defined. I could not find good reference for this, but following could be a reference. https://stackoverflow.com/questions/11410292/opengl-read-and-write-to-the-same-texture The texture gets 0 color value as a result. So the curve filter does not work. This patch makes the curve filter use different input and output buffer. Test Plan: This attached file could explain what 'read and write to the same texture' is. {F3724537} Reviewers: Hermet, jpeg, jsuya Reviewed By: Hermet Subscribers: cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D9085
This commit is contained in:
parent
f8a1fa470c
commit
e71c9ad00b
|
@ -1264,13 +1264,13 @@ evas_filter_command_grow_add(Evas_Filter_Context *ctx, void *draw_context,
|
|||
int inbuf, int outbuf, int radius, Eina_Bool smooth,
|
||||
Eina_Bool alphaonly)
|
||||
{
|
||||
Evas_Filter_Command *blurcmd, *threshcmd, *blendcmd;
|
||||
Evas_Filter_Buffer *tmp = NULL, *in, *out;
|
||||
Evas_Filter_Command *blurcmd = NULL, *threshcmd = NULL, *blendcmd;
|
||||
Evas_Filter_Buffer *tmp, *in, *out;
|
||||
int diam = abs(radius) * 2 + 1;
|
||||
DATA8 curve[256] = {0};
|
||||
int tmin = 0, growbuf;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, NULL);
|
||||
EINA_SAFETY_ON_NULL_GOTO(ctx, fail);
|
||||
|
||||
if (!radius)
|
||||
{
|
||||
|
@ -1280,15 +1280,15 @@ 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);
|
||||
EINA_SAFETY_ON_NULL_GOTO(in, fail);
|
||||
|
||||
out = _filter_buffer_get(ctx, outbuf);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(out, NULL);
|
||||
EINA_SAFETY_ON_NULL_GOTO(out, fail);
|
||||
|
||||
if ((inbuf != outbuf) && out->dirty)
|
||||
{
|
||||
tmp = evas_filter_temporary_buffer_get(ctx, in->w, in->h, in->alpha_only, 1);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(tmp, NULL);
|
||||
EINA_SAFETY_ON_NULL_GOTO(tmp, fail);
|
||||
growbuf = tmp->id;
|
||||
}
|
||||
else
|
||||
|
@ -1298,7 +1298,7 @@ evas_filter_command_grow_add(Evas_Filter_Context *ctx, void *draw_context,
|
|||
EVAS_FILTER_BLUR_DEFAULT,
|
||||
abs(radius), abs(radius), 0, 0, 0,
|
||||
alphaonly);
|
||||
if (!blurcmd) return NULL;
|
||||
EINA_SAFETY_ON_NULL_GOTO(blurcmd, fail);
|
||||
|
||||
if (diam > 255) diam = 255;
|
||||
if (radius > 0)
|
||||
|
@ -1323,29 +1323,29 @@ evas_filter_command_grow_add(Evas_Filter_Context *ctx, void *draw_context,
|
|||
memset(curve + end, 255, 256 - end);
|
||||
}
|
||||
|
||||
threshcmd = evas_filter_command_curve_add(ctx, draw_context, growbuf, growbuf,
|
||||
curve, EVAS_FILTER_CHANNEL_ALPHA);
|
||||
if (!threshcmd)
|
||||
{
|
||||
_command_del(ctx, blurcmd);
|
||||
return NULL;
|
||||
}
|
||||
/* Use a temp buffer here. Becuase curve_add is using a temp buffer as well
|
||||
if inbuf and outbuf are same and doing blend_add. Then grow_add will do
|
||||
blend_add twice. Using a temp buffer will save a calling blend_add */
|
||||
tmp = evas_filter_temporary_buffer_get(ctx, in->w, in->h, in->alpha_only, 1);
|
||||
EINA_SAFETY_ON_NULL_GOTO(tmp, fail);
|
||||
|
||||
if (tmp)
|
||||
{
|
||||
blendcmd = evas_filter_command_blend_add(ctx, draw_context, tmp->id,
|
||||
outbuf, 0, 0,
|
||||
EVAS_FILTER_FILL_MODE_NONE,
|
||||
alphaonly);
|
||||
if (!blendcmd)
|
||||
{
|
||||
_command_del(ctx, threshcmd);
|
||||
_command_del(ctx, blurcmd);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
threshcmd = evas_filter_command_curve_add(ctx, draw_context, growbuf, tmp->id,
|
||||
curve, EVAS_FILTER_CHANNEL_ALPHA);
|
||||
EINA_SAFETY_ON_NULL_GOTO(threshcmd, fail);
|
||||
|
||||
blendcmd = evas_filter_command_blend_add(ctx, draw_context, tmp->id,
|
||||
outbuf, 0, 0,
|
||||
EVAS_FILTER_FILL_MODE_NONE,
|
||||
alphaonly);
|
||||
EINA_SAFETY_ON_NULL_GOTO(blendcmd, fail);
|
||||
|
||||
return blurcmd;
|
||||
|
||||
fail:
|
||||
ERR("Failed to add grow");
|
||||
if (threshcmd) _command_del(ctx, threshcmd);
|
||||
if (blurcmd) _command_del(ctx, blurcmd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Evas_Filter_Command *
|
||||
|
@ -1354,8 +1354,8 @@ evas_filter_command_curve_add(Evas_Filter_Context *ctx,
|
|||
int inbuf, int outbuf, DATA8 *curve,
|
||||
Evas_Filter_Channel channel)
|
||||
{
|
||||
Evas_Filter_Command *cmd;
|
||||
Evas_Filter_Buffer *in, *out;
|
||||
Evas_Filter_Command *cmd, *blendcmd;
|
||||
Evas_Filter_Buffer *in, *out, *tmp = NULL, *curve_out;
|
||||
DATA8 *copy;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, NULL);
|
||||
|
@ -1370,12 +1370,20 @@ evas_filter_command_curve_add(Evas_Filter_Context *ctx,
|
|||
WRN("Incompatible formats for color curves, implicit conversion will be "
|
||||
"slow and may not produce the desired output.");
|
||||
|
||||
XDBG("Add curve %d -> %d", in->id, out->id);
|
||||
if (in == out)
|
||||
{
|
||||
tmp = evas_filter_temporary_buffer_get(ctx, in->w, in->h, in->alpha_only, 1);
|
||||
if (!tmp) return NULL;
|
||||
curve_out = tmp;
|
||||
}
|
||||
else curve_out = out;
|
||||
|
||||
XDBG("Add curve %d -> %d", in->id, curve_out->id);
|
||||
|
||||
copy = malloc(256 * sizeof(DATA8));
|
||||
if (!copy) return NULL;
|
||||
|
||||
cmd = _command_new(ctx, EVAS_FILTER_MODE_CURVE, in, NULL, out);
|
||||
cmd = _command_new(ctx, EVAS_FILTER_MODE_CURVE, in, NULL, curve_out);
|
||||
if (!cmd)
|
||||
{
|
||||
_free(copy);
|
||||
|
@ -1389,6 +1397,19 @@ evas_filter_command_curve_add(Evas_Filter_Context *ctx,
|
|||
else
|
||||
cmd->curve.channel = channel;
|
||||
|
||||
if (tmp)
|
||||
{
|
||||
blendcmd = evas_filter_command_blend_add(ctx, draw_context, curve_out->id,
|
||||
out->id, 0, 0,
|
||||
EVAS_FILTER_FILL_MODE_NONE,
|
||||
out->alpha_only);
|
||||
if (!blendcmd)
|
||||
{
|
||||
_command_del(ctx, cmd);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return cmd;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue