summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShinwoo Kim <cinoo.kim@samsung.com>2019-06-19 10:28:34 +0900
committerHermet Park <hermetpark@gmail.com>2019-06-19 10:28:34 +0900
commite71c9ad00b9038e09fd1e40584c24c32c73d41cf (patch)
tree1addd5f18758e05e0d6793bb0229406823b42f7f
parentf8a1fa470c16eef3d8f5806097a156cecc7c0144 (diff)
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
-rw-r--r--src/lib/evas/filters/evas_filter.c81
1 files changed, 51 insertions, 30 deletions
diff --git a/src/lib/evas/filters/evas_filter.c b/src/lib/evas/filters/evas_filter.c
index 39806843f2..332f6dbb27 100644
--- a/src/lib/evas/filters/evas_filter.c
+++ b/src/lib/evas/filters/evas_filter.c
@@ -1264,13 +1264,13 @@ evas_filter_command_grow_add(Evas_Filter_Context *ctx, void *draw_context,
1264 int inbuf, int outbuf, int radius, Eina_Bool smooth, 1264 int inbuf, int outbuf, int radius, Eina_Bool smooth,
1265 Eina_Bool alphaonly) 1265 Eina_Bool alphaonly)
1266{ 1266{
1267 Evas_Filter_Command *blurcmd, *threshcmd, *blendcmd; 1267 Evas_Filter_Command *blurcmd = NULL, *threshcmd = NULL, *blendcmd;
1268 Evas_Filter_Buffer *tmp = NULL, *in, *out; 1268 Evas_Filter_Buffer *tmp, *in, *out;
1269 int diam = abs(radius) * 2 + 1; 1269 int diam = abs(radius) * 2 + 1;
1270 DATA8 curve[256] = {0}; 1270 DATA8 curve[256] = {0};
1271 int tmin = 0, growbuf; 1271 int tmin = 0, growbuf;
1272 1272
1273 EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, NULL); 1273 EINA_SAFETY_ON_NULL_GOTO(ctx, fail);
1274 1274
1275 if (!radius) 1275 if (!radius)
1276 { 1276 {
@@ -1280,15 +1280,15 @@ evas_filter_command_grow_add(Evas_Filter_Context *ctx, void *draw_context,
1280 } 1280 }
1281 1281
1282 in = _filter_buffer_get(ctx, inbuf); 1282 in = _filter_buffer_get(ctx, inbuf);
1283 EINA_SAFETY_ON_NULL_RETURN_VAL(in, NULL); 1283 EINA_SAFETY_ON_NULL_GOTO(in, fail);
1284 1284
1285 out = _filter_buffer_get(ctx, outbuf); 1285 out = _filter_buffer_get(ctx, outbuf);
1286 EINA_SAFETY_ON_NULL_RETURN_VAL(out, NULL); 1286 EINA_SAFETY_ON_NULL_GOTO(out, fail);
1287 1287
1288 if ((inbuf != outbuf) && out->dirty) 1288 if ((inbuf != outbuf) && out->dirty)
1289 { 1289 {
1290 tmp = evas_filter_temporary_buffer_get(ctx, in->w, in->h, in->alpha_only, 1); 1290 tmp = evas_filter_temporary_buffer_get(ctx, in->w, in->h, in->alpha_only, 1);
1291 EINA_SAFETY_ON_NULL_RETURN_VAL(tmp, NULL); 1291 EINA_SAFETY_ON_NULL_GOTO(tmp, fail);
1292 growbuf = tmp->id; 1292 growbuf = tmp->id;
1293 } 1293 }
1294 else 1294 else
@@ -1298,7 +1298,7 @@ evas_filter_command_grow_add(Evas_Filter_Context *ctx, void *draw_context,
1298 EVAS_FILTER_BLUR_DEFAULT, 1298 EVAS_FILTER_BLUR_DEFAULT,
1299 abs(radius), abs(radius), 0, 0, 0, 1299 abs(radius), abs(radius), 0, 0, 0,
1300 alphaonly); 1300 alphaonly);
1301 if (!blurcmd) return NULL; 1301 EINA_SAFETY_ON_NULL_GOTO(blurcmd, fail);
1302 1302
1303 if (diam > 255) diam = 255; 1303 if (diam > 255) diam = 255;
1304 if (radius > 0) 1304 if (radius > 0)
@@ -1323,29 +1323,29 @@ evas_filter_command_grow_add(Evas_Filter_Context *ctx, void *draw_context,
1323 memset(curve + end, 255, 256 - end); 1323 memset(curve + end, 255, 256 - end);
1324 } 1324 }
1325 1325
1326 threshcmd = evas_filter_command_curve_add(ctx, draw_context, growbuf, growbuf, 1326 /* Use a temp buffer here. Becuase curve_add is using a temp buffer as well
1327 if inbuf and outbuf are same and doing blend_add. Then grow_add will do
1328 blend_add twice. Using a temp buffer will save a calling blend_add */
1329 tmp = evas_filter_temporary_buffer_get(ctx, in->w, in->h, in->alpha_only, 1);
1330 EINA_SAFETY_ON_NULL_GOTO(tmp, fail);
1331
1332 threshcmd = evas_filter_command_curve_add(ctx, draw_context, growbuf, tmp->id,
1327 curve, EVAS_FILTER_CHANNEL_ALPHA); 1333 curve, EVAS_FILTER_CHANNEL_ALPHA);
1328 if (!threshcmd) 1334 EINA_SAFETY_ON_NULL_GOTO(threshcmd, fail);
1329 {
1330 _command_del(ctx, blurcmd);
1331 return NULL;
1332 }
1333 1335
1334 if (tmp) 1336 blendcmd = evas_filter_command_blend_add(ctx, draw_context, tmp->id,
1335 { 1337 outbuf, 0, 0,
1336 blendcmd = evas_filter_command_blend_add(ctx, draw_context, tmp->id, 1338 EVAS_FILTER_FILL_MODE_NONE,
1337 outbuf, 0, 0, 1339 alphaonly);
1338 EVAS_FILTER_FILL_MODE_NONE, 1340 EINA_SAFETY_ON_NULL_GOTO(blendcmd, fail);
1339 alphaonly);
1340 if (!blendcmd)
1341 {
1342 _command_del(ctx, threshcmd);
1343 _command_del(ctx, blurcmd);
1344 return NULL;
1345 }
1346 }
1347 1341
1348 return blurcmd; 1342 return blurcmd;
1343
1344fail:
1345 ERR("Failed to add grow");
1346 if (threshcmd) _command_del(ctx, threshcmd);
1347 if (blurcmd) _command_del(ctx, blurcmd);
1348 return NULL;
1349} 1349}
1350 1350
1351Evas_Filter_Command * 1351Evas_Filter_Command *
@@ -1354,8 +1354,8 @@ evas_filter_command_curve_add(Evas_Filter_Context *ctx,
1354 int inbuf, int outbuf, DATA8 *curve, 1354 int inbuf, int outbuf, DATA8 *curve,
1355 Evas_Filter_Channel channel) 1355 Evas_Filter_Channel channel)
1356{ 1356{
1357 Evas_Filter_Command *cmd; 1357 Evas_Filter_Command *cmd, *blendcmd;
1358 Evas_Filter_Buffer *in, *out; 1358 Evas_Filter_Buffer *in, *out, *tmp = NULL, *curve_out;
1359 DATA8 *copy; 1359 DATA8 *copy;
1360 1360
1361 EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, NULL); 1361 EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, NULL);
@@ -1370,12 +1370,20 @@ evas_filter_command_curve_add(Evas_Filter_Context *ctx,
1370 WRN("Incompatible formats for color curves, implicit conversion will be " 1370 WRN("Incompatible formats for color curves, implicit conversion will be "
1371 "slow and may not produce the desired output."); 1371 "slow and may not produce the desired output.");
1372 1372
1373 XDBG("Add curve %d -> %d", in->id, out->id); 1373 if (in == out)
1374 {
1375 tmp = evas_filter_temporary_buffer_get(ctx, in->w, in->h, in->alpha_only, 1);
1376 if (!tmp) return NULL;
1377 curve_out = tmp;
1378 }
1379 else curve_out = out;
1380
1381 XDBG("Add curve %d -> %d", in->id, curve_out->id);
1374 1382
1375 copy = malloc(256 * sizeof(DATA8)); 1383 copy = malloc(256 * sizeof(DATA8));
1376 if (!copy) return NULL; 1384 if (!copy) return NULL;
1377 1385
1378 cmd = _command_new(ctx, EVAS_FILTER_MODE_CURVE, in, NULL, out); 1386 cmd = _command_new(ctx, EVAS_FILTER_MODE_CURVE, in, NULL, curve_out);
1379 if (!cmd) 1387 if (!cmd)
1380 { 1388 {
1381 _free(copy); 1389 _free(copy);
@@ -1389,6 +1397,19 @@ evas_filter_command_curve_add(Evas_Filter_Context *ctx,
1389 else 1397 else
1390 cmd->curve.channel = channel; 1398 cmd->curve.channel = channel;
1391 1399
1400 if (tmp)
1401 {
1402 blendcmd = evas_filter_command_blend_add(ctx, draw_context, curve_out->id,
1403 out->id, 0, 0,
1404 EVAS_FILTER_FILL_MODE_NONE,
1405 out->alpha_only);
1406 if (!blendcmd)
1407 {
1408 _command_del(ctx, cmd);
1409 return NULL;
1410 }
1411 }
1412
1392 return cmd; 1413 return cmd;
1393} 1414}
1394 1415