summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean-Philippe Andre <jp.andre@samsung.com>2015-12-09 10:45:53 +0900
committerJean-Philippe Andre <jp.andre@samsung.com>2016-01-05 15:43:44 +0900
commit57902fffd3653ee3640185c7f637889af1a9a80a (patch)
treeec25f7a1e3a72da4f34f3b2f2cd17777f338115a
parente3af2783ff0921bf914d3edf0f0cd6253da27b8d (diff)
Evas filters: Use Ector.Buffer instead of RGBA_Image
This is a major refactoring of the evas filters submodule. Use Ector.Buffer and the map/unmap methods instead of directly accessing image buffers with RGBA_Image. RGBA_Image is still used under the hood, for two reasons: - Required for the final output (blend onto Evas itself) - Required for the scaling routines FIXME: - Breaks proxy support (ie. all kind of texturing). - This breaks filters support for the GL engine.
-rw-r--r--src/lib/evas/canvas/evas_filter_mixin.c3
-rw-r--r--src/lib/evas/filters/evas_filter.c247
-rw-r--r--src/lib/evas/filters/evas_filter_blend.c304
-rw-r--r--src/lib/evas/filters/evas_filter_blur.c310
-rw-r--r--src/lib/evas/filters/evas_filter_bump.c60
-rw-r--r--src/lib/evas/filters/evas_filter_curve.c72
-rw-r--r--src/lib/evas/filters/evas_filter_displace.c104
-rw-r--r--src/lib/evas/filters/evas_filter_fill.c29
-rw-r--r--src/lib/evas/filters/evas_filter_mask.c314
-rw-r--r--src/lib/evas/filters/evas_filter_private.h18
-rw-r--r--src/lib/evas/filters/evas_filter_transform.c49
-rw-r--r--src/lib/evas/filters/evas_filter_utils.c81
-rw-r--r--src/lib/evas/include/evas_filter.h1
-rw-r--r--src/lib/evas/include/evas_private.h3
-rw-r--r--src/modules/evas/engines/gl_generic/evas_engine.c20
-rw-r--r--src/modules/evas/engines/software_generic/evas_ector_software_buffer.c2
-rw-r--r--src/modules/evas/engines/software_generic/evas_engine.c19
17 files changed, 712 insertions, 924 deletions
diff --git a/src/lib/evas/canvas/evas_filter_mixin.c b/src/lib/evas/canvas/evas_filter_mixin.c
index e93fa703e2..8c5c8ae9c7 100644
--- a/src/lib/evas/canvas/evas_filter_mixin.c
+++ b/src/lib/evas/canvas/evas_filter_mixin.c
@@ -242,7 +242,8 @@ evas_filter_object_render(Eo *eo_obj, Evas_Object_Protected_Data *obj,
242 242
243 // Request rendering from the object itself (child class) 243 // Request rendering from the object itself (child class)
244 evas_filter_program_padding_get(pd->data->chain, &l, &r, &t, &b); 244 evas_filter_program_padding_get(pd->data->chain, &l, &r, &t, &b);
245 eo_do(eo_obj, evas_filter_input_render(filter, drawctx, l, r, t, b, do_async)); 245 eo_do(eo_obj, ok = evas_filter_input_render(filter, drawctx, l, r, t, b, do_async));
246 if (!ok) ERR("Filter input render failed.");
246 247
247 ENFN->context_free(ENDT, drawctx); 248 ENFN->context_free(ENDT, drawctx);
248 249
diff --git a/src/lib/evas/filters/evas_filter.c b/src/lib/evas/filters/evas_filter.c
index 6aa18902cd..148a032176 100644
--- a/src/lib/evas/filters/evas_filter.c
+++ b/src/lib/evas/filters/evas_filter.c
@@ -21,25 +21,28 @@
21#endif 21#endif
22 22
23#include "evas_filter_private.h" 23#include "evas_filter_private.h"
24#include <Ector.h>
25#include <software/Ector_Software.h>
26#include "evas_ector_buffer.eo.h"
24 27
25#define _assert(a) if (!(a)) CRI("Failed on %s", #a); 28#define _assert(a) if (!(a)) CRI("Failed on %s", #a);
26 29
27static void _buffer_free(Evas_Filter_Buffer *fb); 30static void _buffer_free(Evas_Filter_Buffer *fb);
28static void _command_del(Evas_Filter_Context *ctx, Evas_Filter_Command *cmd); 31static void _command_del(Evas_Filter_Context *ctx, Evas_Filter_Command *cmd);
29static RGBA_Image *_rgba_image_alloc(Evas_Filter_Buffer const *fb, void *data); 32static Ector_Buffer* _ector_buffer_create(Evas_Filter_Buffer const *fb, void *data);
30 33
31#define DRAW_COLOR_SET(r, g, b, a) do { cmd->draw.R = r; cmd->draw.G = g; cmd->draw.B = b; cmd->draw.A = a; } while (0) 34#define DRAW_COLOR_SET(r, g, b, a) do { cmd->draw.R = r; cmd->draw.G = g; cmd->draw.B = b; cmd->draw.A = a; } while (0)
32#define DRAW_CLIP_SET(_x, _y, _w, _h) do { cmd->draw.clip.x = _x; cmd->draw.clip.y = _y; cmd->draw.clip.w = _w; cmd->draw.clip.h = _h; } while (0) 35#define DRAW_CLIP_SET(_x, _y, _w, _h) do { cmd->draw.clip.x = _x; cmd->draw.clip.y = _y; cmd->draw.clip.w = _w; cmd->draw.clip.h = _h; } while (0)
33#define DRAW_FILL_SET(fmode) do { cmd->draw.fillmode = fmode; } while (0) 36#define DRAW_FILL_SET(fmode) do { cmd->draw.fillmode = fmode; } while (0)
34 37
35typedef struct _Evas_Filter_Thread_Command Evas_Filter_Thread_Command; 38static inline void *
36struct _Evas_Filter_Thread_Command 39_evas_image_get(Ector_Buffer *buf)
37{ 40{
38 Evas_Filter_Context *ctx; 41 void *image = NULL;
39 RGBA_Image *src, *mask, *dst; 42 if (!buf) return NULL;
40 Evas_Filter_Apply_Func func; 43 eo_do(buf, evas_ector_buffer_engine_image_get(NULL, &image));
41}; 44 return image;
42 45}
43 46
44/* Main functions */ 47/* Main functions */
45 48
@@ -67,6 +70,11 @@ evas_filter_context_new(Evas_Public_Data *evas, Eina_Bool async)
67 * better and implement filters direcly with shaders. 70 * better and implement filters direcly with shaders.
68 */ 71 */
69 ctx->gl_engine = (evas->engine.func->gl_surface_read_pixels != NULL); 72 ctx->gl_engine = (evas->engine.func->gl_surface_read_pixels != NULL);
73 if (ctx->gl_engine)
74 {
75 // FIXME!!!
76 CRI("gl support not implemented");
77 }
70 return ctx; 78 return ctx;
71} 79}
72 80
@@ -93,44 +101,21 @@ evas_filter_context_clear(Evas_Filter_Context *ctx)
93} 101}
94 102
95static void 103static void
96_backing_free(Evas_Filter_Context *ctx, RGBA_Image *im)
97{
98 if (!im) return;
99
100 if (!ctx->gl_engine)
101 {
102 if (!ctx->async)
103 ENFN->image_free(ENDT, im);
104 else
105 evas_unref_queue_image_put(ctx->evas, &im->cache_entry);
106 }
107 else
108 {
109#ifdef EVAS_CSERVE2
110 if (evas_cserve2_use_get())
111 evas_cache2_image_close(&im->cache_entry);
112 else
113#endif
114 evas_cache_image_drop(&im->cache_entry);
115 }
116}
117
118static void
119_filter_buffer_backing_free(Evas_Filter_Buffer *fb) 104_filter_buffer_backing_free(Evas_Filter_Buffer *fb)
120{ 105{
121 if (!fb) return; 106 if (!fb || !fb->buffer) return;
122 107 eo_del(fb->buffer);
123 _backing_free(fb->ctx, fb->backing); 108 fb->buffer = NULL;
124 if (fb->glimage)
125 fb->ENFN->image_free(fb->ENDT, fb->glimage);
126 fb->backing = NULL;
127 fb->glimage = NULL;
128} 109}
129 110
130/* GL engine stuff: read-back from texture */ 111/* GL engine stuff: read-back from texture */
131static Eina_Bool 112static Eina_Bool
132_filter_buffer_glimage_pixels_read(Evas_Filter_Buffer *fb, void *glimage) 113_filter_buffer_glimage_pixels_read(Evas_Filter_Buffer *fb EINA_UNUSED, void *glimage EINA_UNUSED)
133{ 114{
115 CRI("not implemented");
116 return 0;
117
118#if 0
134 Eina_Bool ok; 119 Eina_Bool ok;
135 120
136 EINA_SAFETY_ON_NULL_RETURN_VAL(fb, EINA_FALSE); 121 EINA_SAFETY_ON_NULL_RETURN_VAL(fb, EINA_FALSE);
@@ -143,8 +128,8 @@ _filter_buffer_glimage_pixels_read(Evas_Filter_Buffer *fb, void *glimage)
143 EINA_SAFETY_ON_NULL_RETURN_VAL(fb->ENFN->gl_surface_read_pixels, EINA_FALSE); 128 EINA_SAFETY_ON_NULL_RETURN_VAL(fb->ENFN->gl_surface_read_pixels, EINA_FALSE);
144 EINA_SAFETY_ON_NULL_RETURN_VAL(fb->ENFN->gl_surface_unlock, EINA_FALSE); 129 EINA_SAFETY_ON_NULL_RETURN_VAL(fb->ENFN->gl_surface_unlock, EINA_FALSE);
145 130
146 fb->backing = _rgba_image_alloc(fb, NULL); 131 fb->buffer = _ector_buffer_create(fb, NULL);
147 EINA_SAFETY_ON_NULL_RETURN_VAL(fb->backing, EINA_FALSE); 132 EINA_SAFETY_ON_NULL_RETURN_VAL(fb->buffer, EINA_FALSE);
148 133
149 ok = fb->ENFN->gl_surface_lock(fb->ENDT, glimage); 134 ok = fb->ENFN->gl_surface_lock(fb->ENDT, glimage);
150 if (!ok) 135 if (!ok)
@@ -163,13 +148,18 @@ _filter_buffer_glimage_pixels_read(Evas_Filter_Buffer *fb, void *glimage)
163 148
164 ok &= fb->ENFN->gl_surface_unlock(fb->ENDT, glimage); 149 ok &= fb->ENFN->gl_surface_unlock(fb->ENDT, glimage);
165 return ok; 150 return ok;
151#endif
166} 152}
167 153
168/** @hidden private render proxy objects */ 154/** @hidden private render proxy objects */
169void 155void
170evas_filter_context_proxy_render_all(Evas_Filter_Context *ctx, Eo *eo_obj, 156evas_filter_context_proxy_render_all(Evas_Filter_Context *ctx EINA_UNUSED, Eo *eo_obj EINA_UNUSED,
171 Eina_Bool do_async) 157 Eina_Bool do_async EINA_UNUSED)
172{ 158{
159 CRI("not implemented");
160 return;
161
162#if 0
173 Evas_Object_Protected_Data *source; 163 Evas_Object_Protected_Data *source;
174 Evas_Object_Protected_Data *obj; 164 Evas_Object_Protected_Data *obj;
175 Evas_Filter_Buffer *fb; 165 Evas_Filter_Buffer *fb;
@@ -208,6 +198,7 @@ evas_filter_context_proxy_render_all(Evas_Filter_Context *ctx, Eo *eo_obj,
208 fb->alpha_only = EINA_FALSE; 198 fb->alpha_only = EINA_FALSE;
209 XDBG("Source has dimensions %dx%d (buffer %d)", fb->w, fb->h, fb->id); 199 XDBG("Source has dimensions %dx%d (buffer %d)", fb->w, fb->h, fb->id);
210 } 200 }
201#endif
211} 202}
212 203
213void 204void
@@ -257,63 +248,43 @@ _buffer_new(Evas_Filter_Context *ctx, int w, int h, Eina_Bool alpha_only)
257 return fb; 248 return fb;
258} 249}
259 250
260static RGBA_Image * 251static Ector_Buffer *
261_rgba_image_alloc(Evas_Filter_Buffer const *fb, void *data) 252_ector_buffer_create(Evas_Filter_Buffer const *fb, void *data)
262{ 253{
263 Evas_Colorspace cspace; 254 Evas_Colorspace cspace;
264 RGBA_Image *image; 255 Image_Entry *ie;
265 size_t sz; 256
257 // FIXME: We still rely on evas image structs (scaling and target render)
258 // This should be fixed by implementing full support in ector
259 // Note: dropped support for cserve2, that was not needed anyway
260
261 cspace = fb->alpha_only ? E_ALPHA : E_ARGB;
262#if 0
263 // ideal code
264 return fb->ENFN->ector_buffer_new(fb->ENDT, fb->ctx->evas->evas,
265 data, fb->w, fb->h, 0,
266 cspace, EINA_TRUE, 0, 0, 0, 0,
267 ECTOR_BUFFER_FLAG_CPU_READABLE |
268 ECTOR_BUFFER_FLAG_CPU_WRITABLE);
269#endif
266 270
267 cspace = fb->alpha_only ? EVAS_COLORSPACE_GRY8 : EVAS_COLORSPACE_ARGB8888; 271 if (data)
268 if (!fb->ctx->gl_engine)
269 { 272 {
270 if (!data) 273 // no copy
271 { 274 ie = evas_cache_image_data(evas_common_image_cache_get(), fb->w, fb->h,
272 image = fb->ENFN->image_new_from_copied_data 275 data, EINA_TRUE, cspace);
273 (fb->ENDT, fb->w, fb->h, NULL, EINA_TRUE, cspace); 276 if (!ie) return NULL;
274 }
275 else
276 {
277 image = fb->ENFN->image_new_from_data
278 (fb->ENDT, fb->w, fb->h, data, EINA_TRUE, cspace);
279 }
280 } 277 }
281 else 278 else
282 { 279 {
283 // FIXME: Directly calling the alloc functions since we want to use sw surfaces. 280 // alloc buffer
284 281 ie = evas_cache_image_copied_data(evas_common_image_cache_get(), fb->w, fb->h,
285 if (!data) 282 NULL, EINA_TRUE, cspace);
286 { 283 if (!ie) return NULL;
287#ifdef EVAS_CSERVE2 284 data = ((RGBA_Image *) ie)->image.data;
288 if (evas_cserve2_use_get()) 285 memset(data, 0, fb->w * fb->h * (fb->alpha_only ? 1 : 4));
289 image = (RGBA_Image *) evas_cache2_image_copied_data
290 (evas_common_image_cache2_get(), fb->w, fb->h, NULL, EINA_TRUE, cspace);
291 else
292#endif
293 image = (RGBA_Image *) evas_cache_image_copied_data
294 (evas_common_image_cache_get(), fb->w, fb->h, NULL, EINA_TRUE, cspace);
295 }
296 else
297 {
298#ifdef EVAS_CSERVE2
299 if (evas_cserve2_use_get())
300 image = (RGBA_Image *) evas_cache2_image_data
301 (evas_common_image_cache2_get(), fb->w, fb->h, data, EINA_TRUE, cspace);
302 else
303#endif
304 image = (RGBA_Image *) evas_cache_image_data
305 (evas_common_image_cache_get(), fb->w, fb->h, data, EINA_TRUE, cspace);
306 }
307 } 286 }
308 if (!image) return NULL; 287 return fb->ENFN->ector_buffer_wrap(fb->ENDT, fb->ctx->evas->evas, ie);
309
310 if (fb->alpha_only)
311 sz = image->cache_entry.w * image->cache_entry.h * sizeof(DATA8);
312 else
313 sz = image->cache_entry.w * image->cache_entry.h * sizeof(DATA32);
314 if (!data) memset(image->image.data, 0, sz);
315
316 return image;
317} 288}
318 289
319Eina_Bool 290Eina_Bool
@@ -404,7 +375,7 @@ evas_filter_context_buffers_allocate_all(Evas_Filter_Context *ctx)
404 375
405 EINA_LIST_FOREACH(ctx->buffers, li, fb) 376 EINA_LIST_FOREACH(ctx->buffers, li, fb)
406 { 377 {
407 if (fb->backing || fb->source || fb->glimage) 378 if (fb->buffer || fb->source || fb->glimage)
408 continue; 379 continue;
409 380
410 if (!fb->w && !fb->h) 381 if (!fb->w && !fb->h)
@@ -413,10 +384,10 @@ evas_filter_context_buffers_allocate_all(Evas_Filter_Context *ctx)
413 continue; 384 continue;
414 } 385 }
415 386
416 fb->backing = _rgba_image_alloc(fb, NULL); 387 fb->buffer = _ector_buffer_create(fb, NULL);
417 XDBG("Allocating buffer #%d of size %ux%u %s", 388 XDBG("Allocated buffer #%d of size %ux%u %s: %p",
418 fb->id, fb->w, fb->h, fb->alpha_only ? "alpha" : "rgba"); 389 fb->id, fb->w, fb->h, fb->alpha_only ? "alpha" : "rgba", fb->buffer);
419 if (!fb->backing) goto alloc_fail; 390 if (!fb->buffer) goto alloc_fail;
420 } 391 }
421 392
422 return EINA_TRUE; 393 return EINA_TRUE;
@@ -457,35 +428,29 @@ _filter_buffer_data_set(Evas_Filter_Context *ctx, int bufid, void *data,
457 if (w <= 0 || h <= 0) 428 if (w <= 0 || h <= 0)
458 return EINA_FALSE; 429 return EINA_FALSE;
459 430
460 EINA_SAFETY_ON_FALSE_RETURN_VAL(fb->backing == NULL, EINA_FALSE); 431 EINA_SAFETY_ON_FALSE_RETURN_VAL(fb->buffer == NULL, EINA_FALSE);
461 // TODO: Check input parameters? 432 // TODO: Check input parameters?
462 fb->alpha_only = alpha_only; 433 fb->alpha_only = alpha_only;
463 fb->w = w; 434 fb->w = w;
464 fb->h = h; 435 fb->h = h;
465 436
466 fb->backing = _rgba_image_alloc(fb, data); 437 fb->buffer = _ector_buffer_create(fb, data);
467 return (fb->backing != NULL); 438 return (fb->buffer != NULL);
468} 439}
469 440
470int 441static int
471evas_filter_buffer_image_new(Evas_Filter_Context *ctx, void *image) 442_filter_buffer_new_from_evas_surface(Evas_Filter_Context *ctx, void *image)
472{ 443{
473 Evas_Filter_Buffer *fb; 444 Evas_Filter_Buffer *fb;
474 445
475 EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, -1); 446 EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, -1);
476 447
477 image = ENFN->image_ref(ENDT, image);
478 EINA_SAFETY_ON_NULL_RETURN_VAL(image, -1);
479
480 fb = calloc(1, sizeof(Evas_Filter_Buffer)); 448 fb = calloc(1, sizeof(Evas_Filter_Buffer));
481 if (!fb) return -1; 449 if (!fb) return -1;
482 450
483 fb->id = ++(ctx->last_buffer_id); 451 fb->id = ++(ctx->last_buffer_id);
484 fb->ctx = ctx; 452 fb->ctx = ctx;
485 if (!ctx->gl_engine) 453 fb->buffer = ENFN->ector_buffer_wrap(ENDT, ctx->evas->evas, image);
486 fb->backing = image;
487 else
488 fb->glimage = image;
489 ENFN->image_size_get(ENDT, image, &fb->w, &fb->h); 454 ENFN->image_size_get(ENDT, image, &fb->w, &fb->h);
490 fb->alpha_only = (ENFN->image_colorspace_get(ENDT, image) 455 fb->alpha_only = (ENFN->image_colorspace_get(ENDT, image)
491 == EVAS_COLORSPACE_GRY8); 456 == EVAS_COLORSPACE_GRY8);
@@ -544,12 +509,12 @@ _filter_buffer_get(Evas_Filter_Context *ctx, int bufid)
544void * 509void *
545evas_filter_buffer_backing_get(Evas_Filter_Context *ctx, int bufid) 510evas_filter_buffer_backing_get(Evas_Filter_Context *ctx, int bufid)
546{ 511{
547 Evas_Filter_Buffer *buffer; 512 Evas_Filter_Buffer *fb;
548 513
549 buffer = _filter_buffer_get(ctx, bufid); 514 fb = _filter_buffer_get(ctx, bufid);
550 if (!buffer) return NULL; 515 if (!fb) return NULL;
551 516
552 return buffer->backing; 517 return _evas_image_get(fb->buffer);
553} 518}
554 519
555void * 520void *
@@ -557,15 +522,10 @@ evas_filter_buffer_backing_steal(Evas_Filter_Context *ctx, int bufid)
557{ 522{
558 Evas_Filter_Buffer *fb; 523 Evas_Filter_Buffer *fb;
559 524
560 EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, NULL);
561
562 fb = _filter_buffer_get(ctx, bufid); 525 fb = _filter_buffer_get(ctx, bufid);
563 if (!fb) return NULL; 526 if (!fb) return NULL;
564 527
565 if (ctx->gl_engine) 528 return fb->ENFN->image_ref(fb->ENDT, _evas_image_get(fb->buffer));
566 return fb->ENFN->image_ref(fb->ENDT, fb->glimage);
567 else
568 return fb->ENFN->image_ref(fb->ENDT, fb->backing);
569} 529}
570 530
571Eina_Bool 531Eina_Bool
@@ -577,11 +537,11 @@ evas_filter_buffer_backing_release(Evas_Filter_Context *ctx,
577 537
578 if (ctx->async) 538 if (ctx->async)
579 evas_unref_queue_image_put(ctx->evas, stolen_buffer); 539 evas_unref_queue_image_put(ctx->evas, stolen_buffer);
580 else if (ctx->gl_engine)
581 ctx->post_run.buffers_to_free =
582 eina_list_append(ctx->post_run.buffers_to_free, stolen_buffer);
583 else 540 else
584 _backing_free(ctx, stolen_buffer); 541 {
542 ctx->post_run.buffers_to_free =
543 eina_list_append(ctx->post_run.buffers_to_free, stolen_buffer);
544 }
585 545
586 return EINA_TRUE; 546 return EINA_TRUE;
587} 547}
@@ -1345,12 +1305,6 @@ evas_filter_command_transform_add(Evas_Filter_Context *ctx,
1345 return -1; 1305 return -1;
1346 } 1306 }
1347 1307
1348 if (in->alpha_only != out->alpha_only)
1349 {
1350 CRI("Incompatible buffer formats");
1351 return -1;
1352 }
1353
1354 cmd = _command_new(ctx, EVAS_FILTER_MODE_TRANSFORM, in, NULL, out); 1308 cmd = _command_new(ctx, EVAS_FILTER_MODE_TRANSFORM, in, NULL, out);
1355 if (!cmd) return -1; 1309 if (!cmd) return -1;
1356 1310
@@ -1372,7 +1326,7 @@ evas_filter_target_set(Evas_Filter_Context *ctx, void *draw_context,
1372 1326
1373 EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, EINA_FALSE); 1327 EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, EINA_FALSE);
1374 1328
1375 ctx->target.bufid = evas_filter_buffer_image_new(ctx, surface); 1329 ctx->target.bufid = _filter_buffer_new_from_evas_surface(ctx, surface);
1376 ctx->target.x = x; 1330 ctx->target.x = x;
1377 ctx->target.y = y; 1331 ctx->target.y = y;
1378 ctx->target.clip_use = ENFN->context_clip_get 1332 ctx->target.clip_use = ENFN->context_clip_get
@@ -1391,6 +1345,7 @@ evas_filter_target_set(Evas_Filter_Context *ctx, void *draw_context,
1391 ctx->evas->engine.func->image_free(ctx->evas->engine.data.output, ctx->target.mask); 1345 ctx->evas->engine.func->image_free(ctx->evas->engine.data.output, ctx->target.mask);
1392 ctx->target.mask = mask; 1346 ctx->target.mask = mask;
1393 1347
1348#if 0
1394 if (ctx->gl_engine) 1349 if (ctx->gl_engine)
1395 { 1350 {
1396 // Since GL has sync rendering, draw_context is safe to keep around 1351 // Since GL has sync rendering, draw_context is safe to keep around
@@ -1410,6 +1365,7 @@ evas_filter_target_set(Evas_Filter_Context *ctx, void *draw_context,
1410 XDBG("Set target as #%d (%p) and output #%d (%p, gl %p)", 1365 XDBG("Set target as #%d (%p) and output #%d (%p, gl %p)",
1411 ctx->target.bufid, surface, fb->id, fb->backing, fb->glimage); 1366 ctx->target.bufid, surface, fb->id, fb->backing, fb->glimage);
1412 } 1367 }
1368#endif
1413 1369
1414 return EINA_TRUE; 1370 return EINA_TRUE;
1415} 1371}
@@ -1418,7 +1374,7 @@ static Eina_Bool
1418_filter_target_render(Evas_Filter_Context *ctx) 1374_filter_target_render(Evas_Filter_Context *ctx)
1419{ 1375{
1420 Evas_Filter_Buffer *src, *dst; 1376 Evas_Filter_Buffer *src, *dst;
1421 void *drawctx, *image, *surface; 1377 void *drawctx, *image = NULL, *surface = NULL;
1422 int cx, cy, cw, ch; 1378 int cx, cy, cw, ch;
1423 Eina_Bool use_clip = EINA_FALSE; 1379 Eina_Bool use_clip = EINA_FALSE;
1424 1380
@@ -1429,13 +1385,8 @@ _filter_target_render(Evas_Filter_Context *ctx)
1429 EINA_SAFETY_ON_NULL_RETURN_VAL(src, EINA_FALSE); 1385 EINA_SAFETY_ON_NULL_RETURN_VAL(src, EINA_FALSE);
1430 EINA_SAFETY_ON_NULL_RETURN_VAL(dst, EINA_FALSE); 1386 EINA_SAFETY_ON_NULL_RETURN_VAL(dst, EINA_FALSE);
1431 1387
1432 if (!ctx->gl_engine) 1388#if 0
1433 { 1389 if (ctx->gl_engine)
1434 drawctx = ENFN->context_new(ENDT);
1435 surface = dst->backing;
1436 image = src->backing;
1437 }
1438 else
1439 { 1390 {
1440 drawctx = ctx->target.context; 1391 drawctx = ctx->target.context;
1441 surface = dst->glimage; 1392 surface = dst->glimage;
@@ -1456,9 +1407,18 @@ _filter_target_render(Evas_Filter_Context *ctx)
1456 } 1407 }
1457 image = src->glimage; 1408 image = src->glimage;
1458 } 1409 }
1410 else
1411#endif
1412 {
1413 drawctx = ENFN->context_new(ENDT);
1414 image = _evas_image_get(src->buffer);
1415 surface = _evas_image_get(dst->buffer);
1416 }
1459 EINA_SAFETY_ON_NULL_RETURN_VAL(image, EINA_FALSE); 1417 EINA_SAFETY_ON_NULL_RETURN_VAL(image, EINA_FALSE);
1460 EINA_SAFETY_ON_NULL_RETURN_VAL(surface, EINA_FALSE); 1418 EINA_SAFETY_ON_NULL_RETURN_VAL(surface, EINA_FALSE);
1461 1419
1420 // FIXME: Use ector buffer RENDERER here
1421
1462 if (ctx->target.clip_use) 1422 if (ctx->target.clip_use)
1463 { 1423 {
1464 use_clip = ENFN->context_clip_get(ENDT, drawctx, &cx, &cy, &cw, &ch); 1424 use_clip = ENFN->context_clip_get(ENDT, drawctx, &cx, &cy, &cw, &ch);
@@ -1511,12 +1471,10 @@ evas_filter_font_draw(Evas_Filter_Context *ctx, void *draw_context, int bufid,
1511{ 1471{
1512 Eina_Bool async_unref; 1472 Eina_Bool async_unref;
1513 Evas_Filter_Buffer *fb; 1473 Evas_Filter_Buffer *fb;
1514 void *surface; 1474 void *surface = NULL;
1515 1475
1516 fb = _filter_buffer_get(ctx, bufid); 1476 fb = _filter_buffer_get(ctx, bufid);
1517 if (!fb) return EINA_FALSE; 1477 surface = _evas_image_get(fb->buffer);
1518
1519 surface = fb->backing;
1520 if (!surface) return EINA_FALSE; 1478 if (!surface) return EINA_FALSE;
1521 1479
1522 if (!ctx->gl_engine) 1480 if (!ctx->gl_engine)
@@ -1771,10 +1729,7 @@ end:
1771 DEBUG_TIME_END(); 1729 DEBUG_TIME_END();
1772 1730
1773 EINA_LIST_FREE(ctx->post_run.buffers_to_free, buffer) 1731 EINA_LIST_FREE(ctx->post_run.buffers_to_free, buffer)
1774 { 1732 ENFN->image_free(ENDT, buffer);
1775 if (ctx->gl_engine)
1776 ENFN->image_free(ENDT, buffer);
1777 }
1778 1733
1779 return ok; 1734 return ok;
1780} 1735}
diff --git a/src/lib/evas/filters/evas_filter_blend.c b/src/lib/evas/filters/evas_filter_blend.c
index 0c7c5481f2..153e568a96 100644
--- a/src/lib/evas/filters/evas_filter_blend.c
+++ b/src/lib/evas/filters/evas_filter_blend.c
@@ -1,33 +1,37 @@
1#include "evas_filter.h" 1#include "evas_filter.h"
2#include "evas_filter_private.h" 2#include "evas_filter_private.h"
3#include "evas_blend_private.h" 3#include "evas_blend_private.h"
4#include "ector_buffer.h"
4#include "draw.h" 5#include "draw.h"
5 6
7// FIXME: This should all be based on ector renderer
8
6// Use a better formula than R+G+B for rgba to alpha conversion (RGB to YCbCr) 9// Use a better formula than R+G+B for rgba to alpha conversion (RGB to YCbCr)
7#define RGBA2ALPHA_WEIGHTED 1 10#define RGBA2ALPHA_WEIGHTED 1
8 11
9typedef Eina_Bool (*image_draw_func) (void *data, void *context, 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_Bool do_async); 12typedef Eina_Bool (*draw_func) (void *data, void *context, const void *src_map, unsigned int src_stride, void *dst_map, unsigned int dst_stride, 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_Bool do_async);
10static Eina_Bool _mapped_blend(void *data, void *drawctx, void *in, void *out, Evas_Filter_Fill_Mode fillmode, int sx, int sy, int sw, int sh, int dx, int dy, int dw, int dh, image_draw_func image_draw); 13static Eina_Bool _mapped_blend(void *data, void *drawctx, const void *src_map, unsigned int src_stride, void *dst_map, unsigned int dst_stride, Evas_Filter_Fill_Mode fillmode, int sx, int sy, int sw, int sh, int dx, int dy, int dw, int dh, draw_func image_draw);
11 14
12struct Filter_Blend_Draw_Context 15struct Filter_Blend_Draw_Context
13{ 16{
14 Efl_Gfx_Render_Op rop; 17 Efl_Gfx_Render_Op rop;
15 DATA32 color; 18 uint32_t color;
16}; 19};
17 20
21#define LINELEN(stride, ptr) (stride / (sizeof(*ptr)))
22
18static Eina_Bool 23static Eina_Bool
19_image_draw_cpu_alpha2alpha(void *data EINA_UNUSED, void *context, 24_image_draw_cpu_alpha2alpha(void *data EINA_UNUSED, void *context,
20 void *surface, void *image, 25 const void *src_map, unsigned int src_stride,
26 void *dst_map, unsigned int dst_stride,
21 int src_x, int src_y, int src_w, int src_h, 27 int src_x, int src_y, int src_w, int src_h,
22 int dst_x, int dst_y, int dst_w, int dst_h, 28 int dst_x, int dst_y, int dst_w, int dst_h,
23 int smooth EINA_UNUSED, 29 int smooth EINA_UNUSED,
24 Eina_Bool do_async EINA_UNUSED) 30 Eina_Bool do_async EINA_UNUSED)
25{ 31{
26 struct Filter_Blend_Draw_Context *dc = context; 32 struct Filter_Blend_Draw_Context *dc = context;
27 RGBA_Image *src = image; 33 const uint8_t *srcdata = src_map;
28 RGBA_Image *dst = surface; 34 uint8_t *dstdata = dst_map;
29 DATA8* srcdata = src->image.data8;
30 DATA8* dstdata = dst->image.data8;
31 Alpha_Gfx_Func func; 35 Alpha_Gfx_Func func;
32 int y, sw, dw; 36 int y, sw, dw;
33 37
@@ -36,8 +40,8 @@ _image_draw_cpu_alpha2alpha(void *data EINA_UNUSED, void *context,
36 func = efl_draw_alpha_func_get(dc->rop, EINA_FALSE); 40 func = efl_draw_alpha_func_get(dc->rop, EINA_FALSE);
37 EINA_SAFETY_ON_NULL_RETURN_VAL(func, EINA_FALSE); 41 EINA_SAFETY_ON_NULL_RETURN_VAL(func, EINA_FALSE);
38 42
39 sw = src->cache_entry.w; 43 sw = LINELEN(src_stride, srcdata);
40 dw = dst->cache_entry.w; 44 dw = LINELEN(dst_stride, dstdata);
41 45
42 srcdata += src_y * sw; 46 srcdata += src_y * sw;
43 dstdata += dst_y * dw; 47 dstdata += dst_y * dw;
@@ -53,28 +57,26 @@ _image_draw_cpu_alpha2alpha(void *data EINA_UNUSED, void *context,
53 57
54static Eina_Bool 58static Eina_Bool
55_image_draw_cpu_alpha2rgba(void *data EINA_UNUSED, void *context, 59_image_draw_cpu_alpha2rgba(void *data EINA_UNUSED, void *context,
56 void *surface, void *image, 60 const void *src_map, unsigned int src_stride,
61 void *dst_map, unsigned int dst_stride,
57 int src_x, int src_y, int src_w, int src_h, 62 int src_x, int src_y, int src_w, int src_h,
58 int dst_x, int dst_y, int dst_w, int dst_h, 63 int dst_x, int dst_y, int dst_w, int dst_h,
59 int smooth EINA_UNUSED, 64 int smooth EINA_UNUSED,
60 Eina_Bool do_async EINA_UNUSED) 65 Eina_Bool do_async EINA_UNUSED)
61{ 66{
62 struct Filter_Blend_Draw_Context *dc = context; 67 struct Filter_Blend_Draw_Context *dc = context;
63 RGBA_Image *src = image; 68 uint8_t *srcdata = (uint8_t *) src_map;
64 RGBA_Image *dst = surface; 69 uint32_t *dstdata = dst_map;
65 DATA8* srcdata = src->image.data8;
66 DATA32* dstdata = dst->image.data;
67 RGBA_Gfx_Func func; 70 RGBA_Gfx_Func func;
68 int y, sw, dw; 71 int y, sw, dw;
69 72
70 EINA_SAFETY_ON_FALSE_RETURN_VAL((src_w == dst_w) && (src_h == dst_h), EINA_FALSE); 73 EINA_SAFETY_ON_FALSE_RETURN_VAL((src_w == dst_w) && (src_h == dst_h), EINA_FALSE);
71 74
72 func = evas_common_gfx_func_composite_mask_color_span_get 75 func = evas_common_gfx_func_composite_mask_color_span_get(dc->color, 1, 1, _gfx_to_evas_render_op(dc->rop));
73 (dc->color, dst->cache_entry.flags.alpha, 1, dc->rop);
74 EINA_SAFETY_ON_NULL_RETURN_VAL(func, EINA_FALSE); 76 EINA_SAFETY_ON_NULL_RETURN_VAL(func, EINA_FALSE);
75 77
76 sw = src->cache_entry.w; 78 sw = LINELEN(src_stride, srcdata);
77 dw = dst->cache_entry.w; 79 dw = LINELEN(dst_stride, dstdata);
78 80
79 srcdata += src_y * sw; 81 srcdata += src_y * sw;
80 dstdata += dst_y * dw; 82 dstdata += dst_y * dw;
@@ -89,76 +91,56 @@ _image_draw_cpu_alpha2rgba(void *data EINA_UNUSED, void *context,
89} 91}
90 92
91static Eina_Bool 93static Eina_Bool
92_filter_blend_cpu_generic_do(Evas_Filter_Command *cmd, 94_image_draw_cpu_rgba2rgba(void *data EINA_UNUSED, void *context,
93 image_draw_func image_draw) 95 const void *src_map, unsigned int src_stride,
96 void *dst_map, unsigned int dst_stride,
97 int src_x, int src_y, int src_w, int src_h,
98 int dst_x, int dst_y, int dst_w, int dst_h,
99 int smooth EINA_UNUSED,
100 Eina_Bool do_async EINA_UNUSED)
94{ 101{
95 RGBA_Image *in, *out; 102 struct Filter_Blend_Draw_Context *dc = context;
96 int sw, sh, dx, dy, dw, dh, sx, sy; 103 uint32_t *srcdata = (uint32_t *) src_map;
97 struct Filter_Blend_Draw_Context dc; 104 uint32_t *dstdata = dst_map;
98 105 RGBA_Gfx_Func func;
99 in = cmd->input->backing; 106 int y, sw, dw;
100 out = cmd->output->backing;
101 EINA_SAFETY_ON_NULL_RETURN_VAL(in, EINA_FALSE);
102 EINA_SAFETY_ON_NULL_RETURN_VAL(out, EINA_FALSE);
103 EINA_SAFETY_ON_NULL_RETURN_VAL(in->image.data8, EINA_FALSE);
104 EINA_SAFETY_ON_NULL_RETURN_VAL(out->image.data8, EINA_FALSE);
105
106 sx = 0;
107 sy = 0;
108 sw = in->cache_entry.w;
109 sh = in->cache_entry.h;
110 107
111 dx = cmd->draw.ox; 108 EINA_SAFETY_ON_FALSE_RETURN_VAL((src_w == dst_w) && (src_h == dst_h), EINA_FALSE);
112 dy = cmd->draw.oy;
113 dw = out->cache_entry.w;
114 dh = out->cache_entry.h;
115 109
116 if ((dw <= 0) || (dh <= 0) || (sw <= 0) || (sh <= 0)) 110 if (!dc->color)
117 return EINA_TRUE; 111 return EINA_TRUE;
112 else if (dc->color == 0xFFFFFFFF)
113 func = evas_common_gfx_func_composite_pixel_span_get(1, 0, 1, 1, _gfx_to_evas_render_op(dc->rop));
114 else
115 func = evas_common_gfx_func_composite_pixel_color_span_get(1, 0, dc->color, 1, 1, _gfx_to_evas_render_op(dc->rop));
116 EINA_SAFETY_ON_NULL_RETURN_VAL(func, EINA_FALSE);
118 117
119 // Stretch if necessary. 118 sw = LINELEN(src_stride, srcdata);
120 119 dw = LINELEN(dst_stride, dstdata);
121 /* NOTE: As of 2014/03/11, this will happen only with RGBA buffers, since
122 * only proxy sources may be scaled. So, we don't need an alpha scaling
123 * algorithm just now.
124 */
125 120
126 if ((sw != dw || sh != dh) && (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_XY)) 121 srcdata += src_y * sw;
122 dstdata += dst_y * dw;
123 for (y = src_h; y; y--)
127 { 124 {
128 Evas_Filter_Buffer *fb; 125 func(srcdata + src_x, NULL, dc->color, dstdata + dst_x, src_w);
129 126 srcdata += sw;
130 if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_X) 127 dstdata += dw;
131 sw = dw;
132 if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_Y)
133 sh = dh;
134
135 BUFFERS_LOCK();
136 fb = evas_filter_buffer_scaled_get(cmd->ctx, cmd->input, sw, sh);
137 BUFFERS_UNLOCK();
138
139 EINA_SAFETY_ON_NULL_RETURN_VAL(fb, EINA_FALSE);
140 fb->locked = EINA_FALSE;
141 in = fb->backing;
142 } 128 }
143 129
144 dc.rop = cmd->draw.rop; 130 return EINA_TRUE;
145 dc.color = ARGB_JOIN(cmd->draw.A, cmd->draw.R, cmd->draw.G, cmd->draw.B);
146 return _mapped_blend(cmd->ENDT, &dc, in, out, cmd->draw.fillmode,
147 sx, sy, sw, sh, dx, dy, dw, dh, image_draw);
148} 131}
149 132
150static Eina_Bool 133static Eina_Bool
151_image_draw_cpu_rgba2alpha(void *data EINA_UNUSED, void *context EINA_UNUSED, 134_image_draw_cpu_rgba2alpha(void *data EINA_UNUSED, void *context EINA_UNUSED,
152 void *surface, void *image, 135 const void *src_map, unsigned int src_stride,
136 void *dst_map, unsigned int dst_stride,
153 int src_x, int src_y, int src_w, int src_h, 137 int src_x, int src_y, int src_w, int src_h,
154 int dst_x, int dst_y, int dst_w, int dst_h, 138 int dst_x, int dst_y, int dst_w, int dst_h,
155 int smooth EINA_UNUSED, 139 int smooth EINA_UNUSED,
156 Eina_Bool do_async EINA_UNUSED) 140 Eina_Bool do_async EINA_UNUSED)
157{ 141{
158 RGBA_Image *src = image; 142 uint32_t *srcdata = (uint32_t *) src_map;
159 RGBA_Image *dst = surface; 143 uint8_t *dstdata = dst_map;
160 DATA32* srcdata = src->image.data;
161 DATA8* dstdata = dst->image.data8;
162 int x, y, sw, dw; 144 int x, y, sw, dw;
163#if RGBA2ALPHA_WEIGHTED 145#if RGBA2ALPHA_WEIGHTED
164 const int WR = 299; 146 const int WR = 299;
@@ -173,15 +155,15 @@ _image_draw_cpu_rgba2alpha(void *data EINA_UNUSED, void *context EINA_UNUSED,
173 155
174 EINA_SAFETY_ON_FALSE_RETURN_VAL((src_w == dst_w) && (src_h == dst_h), EINA_FALSE); 156 EINA_SAFETY_ON_FALSE_RETURN_VAL((src_w == dst_w) && (src_h == dst_h), EINA_FALSE);
175 157
176 sw = src->cache_entry.w; 158 sw = LINELEN(src_stride, srcdata);
177 dw = dst->cache_entry.w; 159 dw = LINELEN(dst_stride, dstdata);
178 160
179 srcdata += src_y * sw; 161 srcdata += src_y * sw;
180 dstdata += dst_y * dw; 162 dstdata += dst_y * dw;
181 for (y = src_h; y; y--) 163 for (y = src_h; y; y--)
182 { 164 {
183 DATA32 *s = srcdata + src_x; 165 uint32_t *s = srcdata + src_x;
184 DATA8 *d = dstdata + dst_x; 166 uint8_t *d = dstdata + dst_x;
185 for (x = src_w; x; x--, d++, s++) 167 for (x = src_w; x; x--, d++, s++)
186 *d = DIVIDE((R_VAL(s) * WR) + (G_VAL(s) * WG) + (B_VAL(s) * WB)); 168 *d = DIVIDE((R_VAL(s) * WR) + (G_VAL(s) * WG) + (B_VAL(s) * WB));
187 srcdata += sw; 169 srcdata += sw;
@@ -192,44 +174,63 @@ _image_draw_cpu_rgba2alpha(void *data EINA_UNUSED, void *context EINA_UNUSED,
192} 174}
193 175
194static Eina_Bool 176static Eina_Bool
195_image_draw_cpu_rgba2rgba(void *data EINA_UNUSED, void *context, 177_filter_blend_cpu_generic_do(Evas_Filter_Command *cmd, draw_func image_draw)
196 void *surface, void *image,
197 int src_x, int src_y, int src_w, int src_h,
198 int dst_x, int dst_y, int dst_w, int dst_h,
199 int smooth EINA_UNUSED,
200 Eina_Bool do_async EINA_UNUSED)
201{ 178{
202 struct Filter_Blend_Draw_Context *dc = context; 179 unsigned int src_len, src_stride, dst_len, dst_stride;
203 RGBA_Image *src = image; 180 int sw, sh, dx, dy, dw, dh, sx, sy;
204 RGBA_Image *dst = surface; 181 struct Filter_Blend_Draw_Context dc;
205 DATA32* srcdata = src->image.data; 182 Eina_Bool ret = EINA_FALSE;
206 DATA32* dstdata = dst->image.data; 183 Evas_Filter_Buffer *src_fb;
207 RGBA_Gfx_Func func; 184 void *src, *dst;
208 int y, sw, dw;
209 185
210 EINA_SAFETY_ON_FALSE_RETURN_VAL((src_w == dst_w) && (src_h == dst_h), EINA_FALSE); 186 sx = 0;
187 sy = 0;
188 eo_do(cmd->input->buffer, ector_buffer_size_get(&sw, &sh));
211 189
212 if (!dc->color) 190 dx = cmd->draw.ox;
191 dy = cmd->draw.oy;
192 eo_do(cmd->output->buffer, ector_buffer_size_get(&dw, &dh));
193
194 if ((dw <= 0) || (dh <= 0) || (sw <= 0) || (sh <= 0))
213 return EINA_TRUE; 195 return EINA_TRUE;
214 else if (dc->color == 0xFFFFFFFF)
215 func = evas_common_gfx_func_composite_pixel_span_get(src->cache_entry.flags.alpha, src->cache_entry.flags.alpha_sparse, dst->cache_entry.flags.alpha, 1, dc->rop);
216 else
217 func = evas_common_gfx_func_composite_pixel_color_span_get(src->cache_entry.flags.alpha, src->cache_entry.flags.alpha_sparse, dc->color, dst->cache_entry.flags.alpha, 1, dc->rop);
218 EINA_SAFETY_ON_NULL_RETURN_VAL(func, EINA_FALSE);
219 196
220 sw = src->cache_entry.w; 197 // Stretch if necessary.
221 dw = dst->cache_entry.w;
222 198
223 srcdata += src_y * sw; 199 /* NOTE: As of 2014/03/11, this will happen only with RGBA buffers, since
224 dstdata += dst_y * dw; 200 * only proxy sources may be scaled. So, we don't need an alpha scaling
225 for (y = src_h; y; y--) 201 * algorithm just now.
202 */
203
204 if ((sw != dw || sh != dh) && (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_XY))
226 { 205 {
227 func(srcdata + src_x, NULL, dc->color, dstdata + dst_x, src_w); 206
228 srcdata += sw; 207 if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_X)
229 dstdata += dw; 208 sw = dw;
209 if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_Y)
210 sh = dh;
211
212 BUFFERS_LOCK();
213 src_fb = evas_filter_buffer_scaled_get(cmd->ctx, cmd->input, sw, sh);
214 BUFFERS_UNLOCK();
215
216 EINA_SAFETY_ON_NULL_GOTO(src_fb, end);
217 src_fb->locked = EINA_FALSE;
230 } 218 }
219 else src_fb = cmd->input;
231 220
232 return EINA_TRUE; 221 src = _buffer_map_all(src_fb->buffer, &src_len, E_READ, src_fb->alpha_only ? E_ALPHA : E_ARGB, &src_stride);
222 dst = _buffer_map_all(cmd->output->buffer, &dst_len, E_WRITE, cmd->output->alpha_only ? E_ALPHA : E_ARGB, &dst_stride);
223
224 dc.rop = cmd->draw.rop;
225 dc.color = ARGB_JOIN(cmd->draw.A, cmd->draw.R, cmd->draw.G, cmd->draw.B);
226
227 ret = _mapped_blend(cmd->ENDT, &dc, src, src_stride, dst, dst_stride, cmd->draw.fillmode,
228 sx, sy, sw, sh, dx, dy, dw, dh, image_draw);
229
230end:
231 eo_do(src_fb->buffer, ector_buffer_unmap(src, src_len));
232 eo_do(cmd->output->buffer, ector_buffer_unmap(dst, dst_len));
233 return ret;
233} 234}
234 235
235static Eina_Bool 236static Eina_Bool
@@ -239,7 +240,7 @@ _filter_blend_cpu_alpha(Evas_Filter_Command *cmd)
239} 240}
240 241
241static Eina_Bool 242static Eina_Bool
242_filter_blend_cpu_mask_rgba(Evas_Filter_Command *cmd) 243_filter_blend_cpu_alpha2rgba(Evas_Filter_Command *cmd)
243{ 244{
244 return _filter_blend_cpu_generic_do(cmd, _image_draw_cpu_alpha2rgba); 245 return _filter_blend_cpu_generic_do(cmd, _image_draw_cpu_alpha2rgba);
245} 246}
@@ -253,73 +254,19 @@ _filter_blend_cpu_rgba2alpha(Evas_Filter_Command *cmd)
253static Eina_Bool 254static Eina_Bool
254_filter_blend_cpu_rgba(Evas_Filter_Command *cmd) 255_filter_blend_cpu_rgba(Evas_Filter_Command *cmd)
255{ 256{
256 RGBA_Image *in, *out; 257 return _filter_blend_cpu_generic_do(cmd, _image_draw_cpu_rgba2rgba);
257 RGBA_Draw_Context *drawctx;
258 int sw, sh, dx, dy, dw, dh, sx, sy;
259 Eina_Bool ret;
260
261 in = cmd->input->backing;
262 out = cmd->output->backing;
263 EINA_SAFETY_ON_NULL_RETURN_VAL(in, EINA_FALSE);
264 EINA_SAFETY_ON_NULL_RETURN_VAL(out, EINA_FALSE);
265 EINA_SAFETY_ON_NULL_RETURN_VAL(in->image.data, EINA_FALSE);
266 EINA_SAFETY_ON_NULL_RETURN_VAL(out->image.data, EINA_FALSE);
267
268 if (cmd->ctx->gl_engine)
269 return _filter_blend_cpu_generic_do(cmd, _image_draw_cpu_rgba2rgba);
270
271 sx = 0;
272 sy = 0;
273 sw = in->cache_entry.w;
274 sh = in->cache_entry.h;
275
276 dx = cmd->draw.ox;
277 dy = cmd->draw.oy;
278 dw = out->cache_entry.w;
279 dh = out->cache_entry.h;
280
281 if ((dw <= 0) || (dh <= 0) || (sw <= 0) || (sh <= 0))
282 return EINA_TRUE;
283
284 drawctx = cmd->ENFN->context_new(cmd->ENDT);
285 cmd->ENFN->context_color_set(cmd->ENDT, drawctx, 255, 255, 255, 255);
286 if ((cmd->draw.R != 255) || (cmd->draw.G != 255) || (cmd->draw.B != 255) || (cmd->draw.A != 255))
287 cmd->ENFN->context_multiplier_set(cmd->ENDT, drawctx, cmd->draw.R, cmd->draw.G, cmd->draw.B, cmd->draw.A);
288 else
289 cmd->ENFN->context_multiplier_unset(cmd->ENDT, drawctx);
290 cmd->ENFN->context_render_op_set(cmd->ENDT, drawctx, _gfx_to_evas_render_op(cmd->draw.rop));
291
292 if (cmd->draw.clip_use)
293 {
294 cmd->ENFN->context_clip_set(cmd->ENDT, drawctx,
295 cmd->draw.clip.x, cmd->draw.clip.y,
296 cmd->draw.clip.w, cmd->draw.clip.h);
297 cmd->ENFN->context_clip_clip(cmd->ENDT, drawctx, 0, 0,
298 out->cache_entry.w, out->cache_entry.h);
299 }
300 else
301 {
302 cmd->ENFN->context_clip_set(cmd->ENDT, drawctx, 0, 0,
303 out->cache_entry.w, out->cache_entry.h);
304 }
305
306 ret = _mapped_blend(cmd->ENDT, drawctx, in, out, cmd->draw.fillmode,
307 sx, sy, sw, sh, dx, dy, dw, dh,
308 cmd->ENFN->image_draw);
309
310 cmd->ENFN->context_free(cmd->ENDT, drawctx);
311 return ret;
312} 258}
313 259
314static Eina_Bool 260static Eina_Bool
315_mapped_blend(void *data, void *drawctx, 261_mapped_blend(void *data, void *drawctx,
316 void *in, void *out, 262 const void *src_map, unsigned int src_stride,
263 void *dst_map, unsigned int dst_stride,
317 Evas_Filter_Fill_Mode fillmode, 264 Evas_Filter_Fill_Mode fillmode,
318 int sx, int sy, 265 int sx, int sy,
319 int sw, int sh, 266 int sw, int sh,
320 int dx, int dy, 267 int dx, int dy,
321 int dw, int dh, 268 int dw, int dh,
322 image_draw_func image_draw) 269 draw_func image_draw)
323{ 270{
324 int right = 0, bottom = 0, left = 0, top = 0; 271 int right = 0, bottom = 0, left = 0, top = 0;
325 int row, col, rows, cols; 272 int row, col, rows, cols;
@@ -336,7 +283,8 @@ _mapped_blend(void *data, void *drawctx,
336 XDBG("blend: %d,%d,%d,%d --> %d,%d,%d,%d (from %dx%d to %dx%d +%d,%d)", 283 XDBG("blend: %d,%d,%d,%d --> %d,%d,%d,%d (from %dx%d to %dx%d +%d,%d)",
337 0, 0, sw, sh, dx, dy, cols, rows, sw, sh, dw, dh, dx, dy); 284 0, 0, sw, sh, dx, dy, cols, rows, sw, sh, dw, dh, dx, dy);
338 } 285 }
339 image_draw(data, drawctx, out, in, 286 image_draw(data, drawctx,
287 src_map, src_stride, dst_map, dst_stride,
340 sx, sy, cols, rows, // src 288 sx, sy, cols, rows, // src
341 dx, dy, cols, rows, // dst 289 dx, dy, cols, rows, // dst
342 EINA_TRUE, // smooth 290 EINA_TRUE, // smooth
@@ -477,7 +425,8 @@ _mapped_blend(void *data, void *drawctx,
477 dst_x, dst_y, dst_w, dst_h, 425 dst_x, dst_y, dst_w, dst_h,
478 sw, sh, dw, dh); 426 sw, sh, dw, dh);
479 } 427 }
480 image_draw(data, drawctx, out, in, 428 image_draw(data, drawctx,
429 src_map, src_stride, dst_map, dst_stride,
481 src_x, src_y, src_w, src_h, 430 src_x, src_y, src_w, src_h,
482 dst_x, dst_y, dst_w, dst_h, 431 dst_x, dst_y, dst_w, dst_h,
483 EINA_TRUE, EINA_FALSE); 432 EINA_TRUE, EINA_FALSE);
@@ -493,27 +442,18 @@ evas_filter_blend_cpu_func_get(Evas_Filter_Command *cmd)
493 EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output, NULL); 442 EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output, NULL);
494 EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input, NULL); 443 EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input, NULL);
495 444
496 if (!cmd->ctx->gl_engine || !cmd->output->glimage || cmd->output->backing) 445 if (cmd->input->alpha_only)
497 { 446 {
498 if (cmd->input->alpha_only) 447 if (cmd->output->alpha_only)
499 { 448 return _filter_blend_cpu_alpha;
500 if (cmd->output->alpha_only)
501 return _filter_blend_cpu_alpha;
502 else
503 return _filter_blend_cpu_mask_rgba;
504 }
505 else 449 else
506 { 450 return _filter_blend_cpu_alpha2rgba;
507 if (cmd->output->alpha_only)
508 return _filter_blend_cpu_rgba2alpha;
509 else
510 return _filter_blend_cpu_rgba;
511 }
512 } 451 }
513 else 452 else
514 { 453 {
515 CRI("Can't render to GL image for the moment!"); 454 if (cmd->output->alpha_only)
516 //return _filter_blend_opengl_generic; 455 return _filter_blend_cpu_rgba2alpha;
517 return NULL; 456 else
457 return _filter_blend_cpu_rgba;
518 } 458 }
519} 459}
diff --git a/src/lib/evas/filters/evas_filter_blur.c b/src/lib/evas/filters/evas_filter_blur.c
index fd444cc45b..9cf851faec 100644
--- a/src/lib/evas/filters/evas_filter_blur.c
+++ b/src/lib/evas/filters/evas_filter_blur.c
@@ -4,6 +4,8 @@
4#include <math.h> 4#include <math.h>
5#include <time.h> 5#include <time.h>
6 6
7// FIXME: Add proper stride support
8
7static int 9static int
8_box_blur_auto_radius(int *radii, int r) 10_box_blur_auto_radius(int *radii, int r)
9{ 11{
@@ -45,7 +47,7 @@ _box_blur_auto_radius(int *radii, int r)
45#endif 47#endif
46 48
47static void 49static void
48_box_blur_horiz_rgba(DATA32 *src, DATA32 *dst, int* radii, int w, int h) 50_box_blur_horiz_rgba(uint32_t *src, uint32_t *dst, int* radii, int w, int h)
49{ 51{
50 DEBUG_TIME_BEGIN(); 52 DEBUG_TIME_BEGIN();
51 53
@@ -77,7 +79,7 @@ end:
77} 79}
78 80
79static void 81static void
80_box_blur_vert_rgba(DATA32 *src, DATA32 *dst, int* radii, int w, int h) 82_box_blur_vert_rgba(uint32_t *src, uint32_t *dst, int* radii, int w, int h)
81{ 83{
82 DEBUG_TIME_BEGIN(); 84 DEBUG_TIME_BEGIN();
83 85
@@ -108,64 +110,6 @@ end:
108 DEBUG_TIME_END(); 110 DEBUG_TIME_END();
109} 111}
110 112
111static Eina_Bool
112_box_blur_horiz_apply_rgba(Evas_Filter_Command *cmd)
113{
114 RGBA_Image *in, *out;
115 int radii[7] = {0};
116 unsigned int r;
117
118 EINA_SAFETY_ON_NULL_RETURN_VAL(cmd, EINA_FALSE);
119 EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input->backing, EINA_FALSE);
120 EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output->backing, EINA_FALSE);
121
122 r = abs(cmd->blur.dx);
123 in = cmd->input->backing;
124 out = cmd->output->backing;
125
126 if (cmd->blur.auto_count)
127 _box_blur_auto_radius(radii, r);
128 else for (int k = 0; k < cmd->blur.count; k++)
129 radii[k] = r;
130
131 EINA_SAFETY_ON_NULL_RETURN_VAL(in->image.data, EINA_FALSE);
132 EINA_SAFETY_ON_NULL_RETURN_VAL(out->image.data, EINA_FALSE);
133
134 _box_blur_horiz_rgba(in->image.data, out->image.data, radii,
135 in->cache_entry.w, in->cache_entry.h);
136
137 return EINA_TRUE;
138}
139
140static Eina_Bool
141_box_blur_vert_apply_rgba(Evas_Filter_Command *cmd)
142{
143 RGBA_Image *in, *out;
144 int radii[7] = {0};
145 unsigned int r;
146
147 EINA_SAFETY_ON_NULL_RETURN_VAL(cmd, EINA_FALSE);
148 EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input->backing, EINA_FALSE);
149 EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output->backing, EINA_FALSE);
150
151 r = abs(cmd->blur.dy);
152 in = cmd->input->backing;
153 out = cmd->output->backing;
154
155 if (cmd->blur.auto_count)
156 _box_blur_auto_radius(radii, r);
157 else for (int k = 0; k < cmd->blur.count; k++)
158 radii[k] = r;
159
160 EINA_SAFETY_ON_NULL_RETURN_VAL(in->image.data, EINA_FALSE);
161 EINA_SAFETY_ON_NULL_RETURN_VAL(out->image.data, EINA_FALSE);
162
163 _box_blur_vert_rgba(in->image.data, out->image.data, radii,
164 in->cache_entry.w, in->cache_entry.h);
165
166 return EINA_TRUE;
167}
168
169#include "./blur/blur_box_alpha_.c" 113#include "./blur/blur_box_alpha_.c"
170#ifdef BUILD_MMX 114#ifdef BUILD_MMX
171#include "./blur/blur_box_alpha_i386.c" 115#include "./blur/blur_box_alpha_i386.c"
@@ -178,7 +122,7 @@ _box_blur_vert_apply_rgba(Evas_Filter_Command *cmd)
178#endif 122#endif
179 123
180static void 124static void
181_box_blur_horiz_alpha(DATA8 *src, DATA8 *dst, int* radii, int w, int h) 125_box_blur_horiz_alpha(const DATA8 *src, DATA8 *dst, int* radii, int w, int h)
182{ 126{
183 DEBUG_TIME_BEGIN(); 127 DEBUG_TIME_BEGIN();
184 128
@@ -210,7 +154,7 @@ end:
210} 154}
211 155
212static void 156static void
213_box_blur_vert_alpha(DATA8 *src, DATA8 *dst, int* radii, int w, int h) 157_box_blur_vert_alpha(const DATA8 *src, DATA8 *dst, int* radii, int w, int h)
214{ 158{
215 DEBUG_TIME_BEGIN(); 159 DEBUG_TIME_BEGIN();
216 160
@@ -242,61 +186,70 @@ end:
242} 186}
243 187
244static Eina_Bool 188static Eina_Bool
245_box_blur_horiz_apply_alpha(Evas_Filter_Command *cmd) 189_box_blur_apply(Evas_Filter_Command *cmd, Eina_Bool vert, Eina_Bool rgba)
246{ 190{
247 RGBA_Image *in, *out; 191 unsigned int src_len, src_stride, dst_len, dst_stride;
192 Eina_Bool ret = EINA_TRUE;
248 int radii[7] = {0}; 193 int radii[7] = {0};
249 unsigned int r; 194 unsigned int r;
195 void *src, *dst;
250 196
251 EINA_SAFETY_ON_NULL_RETURN_VAL(cmd, EINA_FALSE); 197 r = abs(vert ? cmd->blur.dy : cmd->blur.dx);
252 EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input->backing, EINA_FALSE); 198 src = _buffer_map_all(cmd->input->buffer, &src_len, E_READ, rgba ? E_ARGB : E_ALPHA, &src_stride);
253 EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output->backing, EINA_FALSE); 199 dst = _buffer_map_all(cmd->output->buffer, &dst_len, E_WRITE, rgba ? E_ARGB : E_ALPHA, &dst_stride);
254
255 r = abs(cmd->blur.dx);
256 in = cmd->input->backing;
257 out = cmd->output->backing;
258 200
259 if (cmd->blur.auto_count) 201 if (cmd->blur.auto_count)
260 _box_blur_auto_radius(radii, r); 202 _box_blur_auto_radius(radii, r);
261 else for (int k = 0; k < cmd->blur.count; k++) 203 else for (int k = 0; k < cmd->blur.count; k++)
262 radii[k] = r; 204 radii[k] = r;
263 205
264 EINA_SAFETY_ON_NULL_RETURN_VAL(in->image.data8, EINA_FALSE); 206 if (src && dst)
265 EINA_SAFETY_ON_NULL_RETURN_VAL(out->image.data8, EINA_FALSE); 207 {
208 if (rgba)
209 {
210 if (!vert)
211 _box_blur_horiz_rgba(src, dst, radii, cmd->input->w, cmd->input->h);
212 else
213 _box_blur_vert_rgba(src, dst, radii, cmd->input->w, cmd->input->h);
214 }
215 else
216 {
217 if (!vert)
218 _box_blur_horiz_alpha(src, dst, radii, cmd->input->w, cmd->input->h);
219 else
220 _box_blur_vert_alpha(src, dst, radii, cmd->input->w, cmd->input->h);
221 }
222 }
223 else ret = EINA_FALSE;
266 224
267 _box_blur_horiz_alpha(in->image.data8, out->image.data8, radii, 225 eo_do(cmd->input->buffer, ector_buffer_unmap(src, src_len));
268 in->cache_entry.w, in->cache_entry.h); 226 eo_do(cmd->output->buffer, ector_buffer_unmap(dst, dst_len));
269 227
270 return EINA_TRUE; 228 return ret;
271} 229}
272 230
273static Eina_Bool 231static Eina_Bool
274_box_blur_vert_apply_alpha(Evas_Filter_Command *cmd) 232_box_blur_horiz_apply_alpha(Evas_Filter_Command *cmd)
275{ 233{
276 RGBA_Image *in, *out; 234 return _box_blur_apply(cmd, 0, 0);
277 int radii[7] = {0}; 235}
278 unsigned int r;
279
280 EINA_SAFETY_ON_NULL_RETURN_VAL(cmd, EINA_FALSE);
281 EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input->backing, EINA_FALSE);
282 EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output->backing, EINA_FALSE);
283
284 r = abs(cmd->blur.dy);
285 in = cmd->input->backing;
286 out = cmd->output->backing;
287
288 if (cmd->blur.auto_count)
289 _box_blur_auto_radius(radii, r);
290 else for (int k = 0; k < cmd->blur.count; k++)
291 radii[k] = r;
292 236
293 EINA_SAFETY_ON_NULL_RETURN_VAL(in->image.data8, EINA_FALSE); 237static Eina_Bool
294 EINA_SAFETY_ON_NULL_RETURN_VAL(out->image.data8, EINA_FALSE); 238_box_blur_vert_apply_alpha(Evas_Filter_Command *cmd)
239{
240 return _box_blur_apply(cmd, 1, 0);
241}
295 242
296 _box_blur_vert_alpha(in->image.data8, out->image.data8, radii, 243static Eina_Bool
297 in->cache_entry.w, in->cache_entry.h); 244_box_blur_horiz_apply_rgba(Evas_Filter_Command *cmd)
245{
246 return _box_blur_apply(cmd, 0, 1);
247}
298 248
299 return EINA_TRUE; 249static Eina_Bool
250_box_blur_vert_apply_rgba(Evas_Filter_Command *cmd)
251{
252 return _box_blur_apply(cmd, 1, 1);
300} 253}
301 254
302/* Gaussian blur */ 255/* Gaussian blur */
@@ -342,165 +295,86 @@ _sin_blur_weights_get(int *weights, int *pow2_divider, int radius)
342#define STEP 1 295#define STEP 1
343#include "./blur/blur_gaussian_alpha_.c" 296#include "./blur/blur_gaussian_alpha_.c"
344 297
345static void
346_gaussian_blur_horiz_alpha(const DATA8 *src, DATA8 *dst, int radius, int w, int h)
347{
348 int *weights;
349 int pow2_div = 0;
350
351 weights = alloca((2 * radius + 1) * sizeof(int));
352 _sin_blur_weights_get(weights, &pow2_div, radius);
353
354 DEBUG_TIME_BEGIN();
355 _gaussian_blur_horiz_alpha_step(src, dst, radius, w, h, w, weights, pow2_div);
356 DEBUG_TIME_END();
357}
358
359// Step size is w (row by row), loops = w, so STEP = 'loops' 298// Step size is w (row by row), loops = w, so STEP = 'loops'
360#define FUNCTION_NAME _gaussian_blur_vert_alpha_step 299#define FUNCTION_NAME _gaussian_blur_vert_alpha_step
361#define STEP loops 300#define STEP loops
362#include "./blur/blur_gaussian_alpha_.c" 301#include "./blur/blur_gaussian_alpha_.c"
363 302
364static void
365_gaussian_blur_vert_alpha(const DATA8 *src, DATA8 *dst, int radius, int w, int h)
366{
367 int *weights;
368 int pow2_div = 0;
369
370 weights = alloca((2 * radius + 1) * sizeof(int));
371 _sin_blur_weights_get(weights, &pow2_div, radius);
372
373 DEBUG_TIME_BEGIN();
374 _gaussian_blur_vert_alpha_step(src, dst, radius, h, w, 1, weights, pow2_div);
375 DEBUG_TIME_END();
376}
377
378#define FUNCTION_NAME _gaussian_blur_horiz_rgba_step 303#define FUNCTION_NAME _gaussian_blur_horiz_rgba_step
379#define STEP 1 304#define STEP 1
380#include "./blur/blur_gaussian_rgba_.c" 305#include "./blur/blur_gaussian_rgba_.c"
381 306
382static void
383_gaussian_blur_horiz_rgba(DATA32 *src, DATA32 *dst, int radius, int w, int h)
384{
385 int *weights;
386 int pow2_div = 0;
387
388 weights = alloca((2 * radius + 1) * sizeof(int));
389 _sin_blur_weights_get(weights, &pow2_div, radius);
390
391 DEBUG_TIME_BEGIN();
392 _gaussian_blur_horiz_rgba_step(src, dst, radius, w, h, w, weights, pow2_div);
393 DEBUG_TIME_END();
394}
395
396#define FUNCTION_NAME _gaussian_blur_vert_rgba_step 307#define FUNCTION_NAME _gaussian_blur_vert_rgba_step
397#define STEP loops 308#define STEP loops
398#include "./blur/blur_gaussian_rgba_.c" 309#include "./blur/blur_gaussian_rgba_.c"
399 310
400static void 311static Eina_Bool
401_gaussian_blur_vert_rgba(DATA32 *src, DATA32 *dst, int radius, int w, int h) 312_gaussian_blur_apply(Evas_Filter_Command *cmd, Eina_Bool vert, Eina_Bool rgba)
402{ 313{
314 unsigned int src_len, src_stride, dst_len, dst_stride, radius;
315 Eina_Bool ret = EINA_TRUE;
316 int pow2_div = 0, w, h;
317 void *src, *dst;
403 int *weights; 318 int *weights;
404 int pow2_div = 0; 319
320 radius = abs(vert ? cmd->blur.dy : cmd->blur.dx);
321 src = _buffer_map_all(cmd->input->buffer, &src_len, E_READ, rgba ? E_ARGB : E_ALPHA, &src_stride);
322 dst = _buffer_map_all(cmd->output->buffer, &dst_len, E_WRITE, rgba ? E_ARGB : E_ALPHA, &dst_stride);
323 w = cmd->input->w;
324 h = cmd->input->h;
405 325
406 weights = alloca((2 * radius + 1) * sizeof(int)); 326 weights = alloca((2 * radius + 1) * sizeof(int));
407 _sin_blur_weights_get(weights, &pow2_div, radius); 327 _sin_blur_weights_get(weights, &pow2_div, radius);
408 328
409 DEBUG_TIME_BEGIN(); 329 if (src && dst)
410 _gaussian_blur_vert_rgba_step(src, dst, radius, h, w, 1, weights, pow2_div); 330 {
411 DEBUG_TIME_END(); 331 DEBUG_TIME_BEGIN();
332 if (rgba)
333 {
334 if (!vert)
335 _gaussian_blur_horiz_rgba_step(src, dst, radius, w, h, w, weights, pow2_div);
336 else
337 _gaussian_blur_vert_rgba_step(src, dst, radius, h, w, 1, weights, pow2_div);
338 }
339 else
340 {
341 if (!vert)
342 _gaussian_blur_horiz_alpha_step(src, dst, radius, w, h, w, weights, pow2_div);
343 else
344 _gaussian_blur_vert_alpha_step(src, dst, radius, h, w, 1, weights, pow2_div);
345 }
346 DEBUG_TIME_END();
347 }
348 else ret = EINA_FALSE;
349
350 eo_do(cmd->input->buffer, ector_buffer_unmap(src, src_len));
351 eo_do(cmd->output->buffer, ector_buffer_unmap(dst, dst_len));
352
353 return ret;
412} 354}
413 355
414static Eina_Bool 356static Eina_Bool
415_gaussian_blur_horiz_apply_alpha(Evas_Filter_Command *cmd) 357_gaussian_blur_horiz_apply_alpha(Evas_Filter_Command *cmd)
416{ 358{
417 RGBA_Image *in, *out; 359 return _gaussian_blur_apply(cmd, 0, 0);
418 unsigned int r;
419
420 EINA_SAFETY_ON_NULL_RETURN_VAL(cmd, EINA_FALSE);
421 EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input->backing, EINA_FALSE);
422 EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output->backing, EINA_FALSE);
423
424 r = abs(cmd->blur.dx);
425 in = cmd->input->backing;
426 out = cmd->output->backing;
427
428 EINA_SAFETY_ON_NULL_RETURN_VAL(in->image.data8, EINA_FALSE);
429 EINA_SAFETY_ON_NULL_RETURN_VAL(out->image.data8, EINA_FALSE);
430
431 _gaussian_blur_horiz_alpha(in->image.data8, out->image.data8, r,
432 in->cache_entry.w, in->cache_entry.h);
433
434 return EINA_TRUE;
435} 360}
436 361
437static Eina_Bool 362static Eina_Bool
438_gaussian_blur_vert_apply_alpha(Evas_Filter_Command *cmd) 363_gaussian_blur_vert_apply_alpha(Evas_Filter_Command *cmd)
439{ 364{
440 RGBA_Image *in, *out; 365 return _gaussian_blur_apply(cmd, 1, 0);
441 unsigned int r;
442
443 EINA_SAFETY_ON_NULL_RETURN_VAL(cmd, EINA_FALSE);
444 EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input->backing, EINA_FALSE);
445 EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output->backing, EINA_FALSE);
446
447 r = abs(cmd->blur.dy);
448 in = cmd->input->backing;
449 out = cmd->output->backing;
450
451 EINA_SAFETY_ON_NULL_RETURN_VAL(in->image.data8, EINA_FALSE);
452 EINA_SAFETY_ON_NULL_RETURN_VAL(out->image.data8, EINA_FALSE);
453
454 _gaussian_blur_vert_alpha(in->image.data8, out->image.data8, r,
455 in->cache_entry.w, in->cache_entry.h);
456
457 return EINA_TRUE;
458} 366}
459 367
460static Eina_Bool 368static Eina_Bool
461_gaussian_blur_horiz_apply_rgba(Evas_Filter_Command *cmd) 369_gaussian_blur_horiz_apply_rgba(Evas_Filter_Command *cmd)
462{ 370{
463 RGBA_Image *in, *out; 371 return _gaussian_blur_apply(cmd, 0, 1);
464 unsigned int r;
465
466 EINA_SAFETY_ON_NULL_RETURN_VAL(cmd, EINA_FALSE);
467 EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input->backing, EINA_FALSE);
468 EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output->backing, EINA_FALSE);
469
470 r = abs(cmd->blur.dx);
471 in = cmd->input->backing;
472 out = cmd->output->backing;
473
474 EINA_SAFETY_ON_NULL_RETURN_VAL(in->image.data, EINA_FALSE);
475 EINA_SAFETY_ON_NULL_RETURN_VAL(out->image.data, EINA_FALSE);
476
477 _gaussian_blur_horiz_rgba(in->image.data, out->image.data, r,
478 in->cache_entry.w, in->cache_entry.h);
479
480 return EINA_TRUE;
481} 372}
482 373
483static Eina_Bool 374static Eina_Bool
484_gaussian_blur_vert_apply_rgba(Evas_Filter_Command *cmd) 375_gaussian_blur_vert_apply_rgba(Evas_Filter_Command *cmd)
485{ 376{
486 RGBA_Image *in, *out; 377 return _gaussian_blur_apply(cmd, 1, 1);
487 unsigned int r;
488
489 EINA_SAFETY_ON_NULL_RETURN_VAL(cmd, EINA_FALSE);
490 EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input->backing, EINA_FALSE);
491 EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output->backing, EINA_FALSE);
492
493 r = abs(cmd->blur.dy);
494 in = cmd->input->backing;
495 out = cmd->output->backing;
496
497 EINA_SAFETY_ON_NULL_RETURN_VAL(in->image.data, EINA_FALSE);
498 EINA_SAFETY_ON_NULL_RETURN_VAL(out->image.data, EINA_FALSE);
499
500 _gaussian_blur_vert_rgba(in->image.data, out->image.data, r,
501 in->cache_entry.w, in->cache_entry.h);
502
503 return EINA_TRUE;
504} 378}
505 379
506/* Main entry point */ 380/* Main entry point */
diff --git a/src/lib/evas/filters/evas_filter_bump.c b/src/lib/evas/filters/evas_filter_bump.c
index 6155e6549d..e93f1adda6 100644
--- a/src/lib/evas/filters/evas_filter_bump.c
+++ b/src/lib/evas/filters/evas_filter_bump.c
@@ -50,7 +50,7 @@ evas_filter_bump_map_cpu_func_get(Evas_Filter_Command *cmd)
50} 50}
51 51
52static void 52static void
53_phong_alpha_generate(DATA8 *phong, DATA8 dark, DATA8 color, DATA8 white, 53_phong_alpha_generate(uint8_t *phong, uint8_t dark, uint8_t color, uint8_t white,
54 float sf) 54 float sf)
55{ 55{
56 int x, y; 56 int x, y;
@@ -100,22 +100,23 @@ _phong_alpha_generate(DATA8 *phong, DATA8 dark, DATA8 color, DATA8 white,
100static Eina_Bool 100static Eina_Bool
101_bump_map_cpu_alpha_alpha(Evas_Filter_Command *cmd) 101_bump_map_cpu_alpha_alpha(Evas_Filter_Command *cmd)
102{ 102{
103 DATA8 *src, *map, *dst, *map_y1, *map_y2; 103 uint8_t *src_map, *map_map, *dst_map;
104 DATA8 dark, color, white; 104 uint8_t *src, *map, *dst, *map_y1, *map_y2;
105 DATA8 *phong; 105 uint8_t dark, color, white;
106 uint8_t *phong = NULL;
107 Eina_Bool ret = EINA_FALSE;
106 int x, y, w, h, lx, ly; 108 int x, y, w, h, lx, ly;
109 unsigned int ss, ms, ds, slen, dlen, mlen;
107 float xyangle, zangle, sf, lxy; 110 float xyangle, zangle, sf, lxy;
108 111
109 w = cmd->input->w; 112 w = cmd->input->w;
110 h = cmd->input->h; 113 h = cmd->input->h;
111 EINA_SAFETY_ON_FALSE_RETURN_VAL(w > 2 && h > 2, EINA_FALSE); 114 EINA_SAFETY_ON_FALSE_RETURN_VAL(w > 2 && h > 2, EINA_FALSE);
112 115
113 src = ((RGBA_Image *) cmd->input->backing)->image.data8; 116 src_map = src = _buffer_map_all(cmd->input->buffer, &slen, E_READ, E_ALPHA, &ss);
114 map = ((RGBA_Image *) cmd->mask->backing)->image.data8; 117 map_map = map = _buffer_map_all(cmd->mask->buffer, &mlen, E_READ, E_ALPHA, &ms);
115 dst = ((RGBA_Image *) cmd->output->backing)->image.data8; 118 dst_map = dst = _buffer_map_all(cmd->output->buffer, &dlen, E_WRITE, E_ALPHA, &ds);
116 EINA_SAFETY_ON_NULL_RETURN_VAL(src, EINA_FALSE); 119 EINA_SAFETY_ON_FALSE_GOTO(src && dst && map, end);
117 EINA_SAFETY_ON_NULL_RETURN_VAL(map, EINA_FALSE);
118 EINA_SAFETY_ON_NULL_RETURN_VAL(dst, EINA_FALSE);
119 120
120 xyangle = cmd->bump.xyangle; 121 xyangle = cmd->bump.xyangle;
121 zangle = cmd->bump.zangle; 122 zangle = cmd->bump.zangle;
@@ -150,7 +151,7 @@ _bump_map_cpu_alpha_alpha(Evas_Filter_Command *cmd)
150 151
151 // Generate light table 152 // Generate light table
152 phong = malloc(256 * 256 * sizeof(*phong)); 153 phong = malloc(256 * 256 * sizeof(*phong));
153 EINA_SAFETY_ON_NULL_RETURN_VAL(phong, EINA_FALSE); 154 EINA_SAFETY_ON_NULL_GOTO(phong, end);
154 _phong_alpha_generate(phong, dark, color, white, sf); 155 _phong_alpha_generate(phong, dark, color, white, sf);
155 156
156 for (y = 0; y < h; y++) 157 for (y = 0; y < h; y++)
@@ -228,31 +229,36 @@ _bump_map_cpu_alpha_alpha(Evas_Filter_Command *cmd)
228 src++; 229 src++;
229 } 230 }
230 231
232 ret = EINA_TRUE;
233
234end:
235 eo_do(cmd->input->buffer, ector_buffer_unmap(src_map, slen));
236 eo_do(cmd->mask->buffer, ector_buffer_unmap(map_map, mlen));
237 eo_do(cmd->output->buffer, ector_buffer_unmap(dst_map, dlen));
231 free(phong); 238 free(phong);
232 return EINA_TRUE; 239 return ret;
233} 240}
234 241
235static Eina_Bool 242static Eina_Bool
236_bump_map_cpu_alpha_rgba(Evas_Filter_Command *cmd) 243_bump_map_cpu_alpha_rgba(Evas_Filter_Command *cmd)
237{ 244{
238 DATA8 *src, *map, *map_y1, *map_y2; 245 uint8_t *src_map, *map_map;
239 DATA32 *dst; 246 uint8_t *src, *map, *map_y1, *map_y2;
240 DATA32 dark, color, white, col; 247 uint32_t *dst, *dst_map;
241 //DATA32 *phong; 248 uint32_t dark, color, white, col;
242 Eina_Bool compensate; 249 Eina_Bool compensate, ret = EINA_FALSE;
243 int x, y, w, h, lx, ly, lz, gz, NL, diffusion, gzlz, gz2; 250 int x, y, w, h, lx, ly, lz, gz, NL, diffusion, gzlz, gz2;
251 unsigned int ss, ms, ds, slen, dlen, mlen;
244 double xyangle, zangle, sf, lxy, elevation; 252 double xyangle, zangle, sf, lxy, elevation;
245 253
246 w = cmd->input->w; 254 w = cmd->input->w;
247 h = cmd->input->h; 255 h = cmd->input->h;
248 EINA_SAFETY_ON_FALSE_RETURN_VAL(w > 2 && h > 2, EINA_FALSE); 256 EINA_SAFETY_ON_FALSE_RETURN_VAL(w > 2 && h > 2, EINA_FALSE);
249 257
250 src = ((RGBA_Image *) cmd->input->backing)->image.data8; 258 src_map = src = _buffer_map_all(cmd->input->buffer, &slen, E_READ, E_ALPHA, &ss);
251 map = ((RGBA_Image *) cmd->mask->backing)->image.data8; 259 map_map = map = _buffer_map_all(cmd->mask->buffer, &mlen, E_READ, E_ALPHA, &ms);
252 dst = ((RGBA_Image *) cmd->output->backing)->image.data; 260 dst_map = dst = (uint32_t *) _buffer_map_all(cmd->output->buffer, &dlen, E_WRITE, E_ARGB, &ds);
253 EINA_SAFETY_ON_NULL_RETURN_VAL(src, EINA_FALSE); 261 EINA_SAFETY_ON_FALSE_GOTO(src && dst && map, end);
254 EINA_SAFETY_ON_NULL_RETURN_VAL(map, EINA_FALSE);
255 EINA_SAFETY_ON_NULL_RETURN_VAL(dst, EINA_FALSE);
256 262
257 xyangle = cmd->bump.xyangle; 263 xyangle = cmd->bump.xyangle;
258 zangle = cmd->bump.zangle; 264 zangle = cmd->bump.zangle;
@@ -403,7 +409,13 @@ _bump_map_cpu_alpha_rgba(Evas_Filter_Command *cmd)
403 } 409 }
404 } 410 }
405 411
406 return EINA_TRUE; 412 ret = EINA_TRUE;
413
414end:
415 eo_do(cmd->input->buffer, ector_buffer_unmap(src_map, slen));
416 eo_do(cmd->mask->buffer, ector_buffer_unmap(map_map, mlen));
417 eo_do(cmd->output->buffer, ector_buffer_unmap(dst_map, dlen));
418 return ret;
407} 419}
408 420
409static Eina_Bool 421static Eina_Bool
diff --git a/src/lib/evas/filters/evas_filter_curve.c b/src/lib/evas/filters/evas_filter_curve.c
index 0a9d761fc6..9950121ec3 100644
--- a/src/lib/evas/filters/evas_filter_curve.c
+++ b/src/lib/evas/filters/evas_filter_curve.c
@@ -5,23 +5,23 @@
5static Eina_Bool 5static Eina_Bool
6_filter_curve_cpu_rgba(Evas_Filter_Command *cmd) 6_filter_curve_cpu_rgba(Evas_Filter_Command *cmd)
7{ 7{
8 RGBA_Image *in, *out; 8 unsigned int src_len, src_stride, dst_len, dst_stride;
9 DATA32 *src, *dst, *d, *s; 9 void *src_map = NULL, *dst_map;
10 DATA8 *curve; 10 Eina_Bool ret = EINA_FALSE;
11 uint32_t *src, *dst, *d, *s;
12 uint8_t *curve;
11 int k, offset = -1, len; 13 int k, offset = -1, len;
12 14
13#define C_VAL(p) (((DATA8 *)(p))[offset]) 15#define C_VAL(p) (((uint8_t *)(p))[offset])
16
17 // FIXME: support src_stride != dst_stride
18 // Note: potentially mapping the same region twice (read then write)
19 src_map = src = _buffer_map_all(cmd->input->buffer, &src_len, E_READ, E_ARGB, &src_stride);
20 dst_map = dst = _buffer_map_all(cmd->output->buffer, &dst_len, E_WRITE, E_ARGB, &dst_stride);
21 EINA_SAFETY_ON_FALSE_GOTO(src && dst && (src_len == dst_len), end);
14 22
15 in = cmd->input->backing;
16 out = cmd->output->backing;
17 EINA_SAFETY_ON_NULL_RETURN_VAL(in, EINA_FALSE);
18 EINA_SAFETY_ON_NULL_RETURN_VAL(out, EINA_FALSE);
19 src = in->image.data;
20 dst = out->image.data;
21 EINA_SAFETY_ON_NULL_RETURN_VAL(src, EINA_FALSE);
22 EINA_SAFETY_ON_NULL_RETURN_VAL(dst, EINA_FALSE);
23 curve = cmd->curve.data; 23 curve = cmd->curve.data;
24 len = in->cache_entry.w * in->cache_entry.h; 24 len = dst_len / sizeof(uint32_t);
25 25
26 switch (cmd->curve.channel) 26 switch (cmd->curve.channel)
27 { 27 {
@@ -38,11 +38,11 @@ _filter_curve_cpu_rgba(Evas_Filter_Command *cmd)
38 case EVAS_FILTER_CHANNEL_RGB: break; 38 case EVAS_FILTER_CHANNEL_RGB: break;
39 default: 39 default:
40 ERR("Invalid color channel %d", (int) cmd->curve.channel); 40 ERR("Invalid color channel %d", (int) cmd->curve.channel);
41 return EINA_FALSE; 41 goto end;
42 } 42 }
43 43
44 if (src != dst) 44 if (src != dst)
45 memcpy(dst, src, len * sizeof(DATA32)); 45 memcpy(dst, src, dst_len);
46 evas_data_argb_unpremul(dst, len); 46 evas_data_argb_unpremul(dst, len);
47 47
48 // One channel (R, G or B) 48 // One channel (R, G or B)
@@ -82,31 +82,39 @@ _filter_curve_cpu_rgba(Evas_Filter_Command *cmd)
82 82
83premul: 83premul:
84 evas_data_argb_premul(dst, len); 84 evas_data_argb_premul(dst, len);
85 return EINA_TRUE; 85 ret = EINA_TRUE;
86
87end:
88 eo_do(cmd->input->buffer, ector_buffer_unmap(src_map, src_len));
89 eo_do(cmd->output->buffer, ector_buffer_unmap(dst_map, dst_len));
90 return ret;
86} 91}
87 92
88static Eina_Bool 93static Eina_Bool
89_filter_curve_cpu_alpha(Evas_Filter_Command *cmd) 94_filter_curve_cpu_alpha(Evas_Filter_Command *cmd)
90{ 95{
91 RGBA_Image *in, *out; 96 unsigned int src_len, src_stride, dst_len, dst_stride;
92 DATA8 *src, *dst; 97 uint8_t *src, *dst, *curve;
93 DATA8 *curve; 98 void *src_map, *dst_map;
99 Eina_Bool ret = EINA_FALSE;
94 int k; 100 int k;
95 101
96 in = cmd->input->backing; 102 // FIXME: support src_stride != dst_stride
97 out = cmd->output->backing; 103 // Note: potentially mapping the same region twice (read then write)
98 EINA_SAFETY_ON_NULL_RETURN_VAL(in, EINA_FALSE); 104 src_map = src = _buffer_map_all(cmd->input->buffer, &src_len, E_READ, E_ALPHA, &src_stride);
99 EINA_SAFETY_ON_NULL_RETURN_VAL(out, EINA_FALSE); 105 dst_map = dst = _buffer_map_all(cmd->output->buffer, &dst_len, E_WRITE, E_ALPHA, &dst_stride);
100 src = in->image.data8; 106 EINA_SAFETY_ON_FALSE_GOTO(src && dst && (src_len == dst_len), end);
101 dst = out->image.data8;
102 EINA_SAFETY_ON_NULL_RETURN_VAL(src, EINA_FALSE);
103 EINA_SAFETY_ON_NULL_RETURN_VAL(dst, EINA_FALSE);
104 curve = cmd->curve.data; 107 curve = cmd->curve.data;
105 108
106 for (k = in->cache_entry.w * in->cache_entry.h; k; k--) 109 for (k = src_len; k; k--)
107 *dst++ = curve[*src++]; 110 *dst++ = curve[*src++];
108 111
109 return EINA_TRUE; 112 ret = EINA_TRUE;
113
114end:
115 eo_do(cmd->input->buffer, ector_buffer_unmap(src_map, src_len));
116 eo_do(cmd->output->buffer, ector_buffer_unmap(dst_map, dst_len));
117 return ret;
110} 118}
111 119
112Evas_Filter_Apply_Func 120Evas_Filter_Apply_Func
@@ -124,6 +132,8 @@ evas_filter_curve_cpu_func_get(Evas_Filter_Command *cmd)
124 if (cmd->input->alpha_only && cmd->output->alpha_only) 132 if (cmd->input->alpha_only && cmd->output->alpha_only)
125 return _filter_curve_cpu_alpha; 133 return _filter_curve_cpu_alpha;
126 134
127 CRI("Incompatible image formats"); 135 // Rely on ector buffer's implicit conversion. not great but the command
128 return NULL; 136 // doesn't make much sense (curve requires same channel count).
137 WRN("Incompatible image formats");
138 return _filter_curve_cpu_rgba;
129} 139}
diff --git a/src/lib/evas/filters/evas_filter_displace.c b/src/lib/evas/filters/evas_filter_displace.c
index 3a1829c03f..1513a919da 100644
--- a/src/lib/evas/filters/evas_filter_displace.c
+++ b/src/lib/evas/filters/evas_filter_displace.c
@@ -3,22 +3,24 @@
3 3
4static void 4static void
5_filter_displace_cpu_alpha_do(int w, int h, int map_w, int map_h, int intensity, 5_filter_displace_cpu_alpha_do(int w, int h, int map_w, int map_h, int intensity,
6 DATA8 *src, DATA8 *dst, DATA32 *map_start, 6 uint8_t *src, uint8_t *dst, uint32_t *map_start,
7 Eina_Bool stretch, Eina_Bool smooth, 7 Eina_Bool stretch, Eina_Bool smooth,
8 Eina_Bool blend) 8 Eina_Bool blend)
9{ 9{
10 int x, y, map_x, map_y; 10 int x, y, map_x, map_y;
11 const int dx = RED; 11 const int dx = RED;
12 const int dy = GREEN; 12 const int dy = GREEN;
13 DATA8 *map; 13 uint8_t *map;
14
15 // FIXME: Add stride support
14 16
15 for (y = 0, map_y = 0; y < h; y++, map_y++) 17 for (y = 0, map_y = 0; y < h; y++, map_y++)
16 { 18 {
17 if (map_y >= map_h) map_y = 0; 19 if (map_y >= map_h) map_y = 0;
18 map = (DATA8 *) (map_start + map_y * map_w); 20 map = (uint8_t *) (map_start + map_y * map_w);
19 21
20 for (x = 0, map_x = 0; x < w; 22 for (x = 0, map_x = 0; x < w;
21 x++, dst++, src++, map_x++, map += sizeof(DATA32)) 23 x++, dst++, src++, map_x++, map += sizeof(uint32_t))
22 { 24 {
23 int offx = 0, offy = 0, offx_dec = 0, offy_dec = 0, val = 0; 25 int offx = 0, offy = 0, offx_dec = 0, offy_dec = 0, val = 0;
24 Eina_Bool out = 0; 26 Eina_Bool out = 0;
@@ -27,7 +29,7 @@ _filter_displace_cpu_alpha_do(int w, int h, int map_w, int map_h, int intensity,
27 if (map_x >= map_w) 29 if (map_x >= map_w)
28 { 30 {
29 map_x = 0; 31 map_x = 0;
30 map = (DATA8 *) (map_start + map_y * map_w); 32 map = (uint8_t *) (map_start + map_y * map_w);
31 } 33 }
32 34
33 // x 35 // x
@@ -76,7 +78,7 @@ _filter_displace_cpu_alpha_do(int w, int h, int map_w, int map_h, int intensity,
76 78
77static void 79static void
78_filter_displace_cpu_rgba_do(int w, int h, int map_w, int map_h, int intensity, 80_filter_displace_cpu_rgba_do(int w, int h, int map_w, int map_h, int intensity,
79 DATA32 *src, DATA32 *dst, DATA32 *map_start, 81 uint32_t *src, uint32_t *dst, uint32_t *map_start,
80 Eina_Bool stretch, Eina_Bool smooth, 82 Eina_Bool stretch, Eina_Bool smooth,
81 Eina_Bool blend) 83 Eina_Bool blend)
82{ 84{
@@ -84,25 +86,25 @@ _filter_displace_cpu_rgba_do(int w, int h, int map_w, int map_h, int intensity,
84 const int dx = RED; 86 const int dx = RED;
85 const int dy = GREEN; 87 const int dy = GREEN;
86 Eina_Bool unpremul = EINA_FALSE; 88 Eina_Bool unpremul = EINA_FALSE;
87 DATA8 *map; 89 uint8_t *map;
88 90
89 for (y = 0, map_y = 0; y < h; y++, map_y++) 91 for (y = 0, map_y = 0; y < h; y++, map_y++)
90 { 92 {
91 if (map_y >= map_h) map_y = 0; 93 if (map_y >= map_h) map_y = 0;
92 map = (DATA8 *) (map_start + map_y * map_w); 94 map = (uint8_t *) (map_start + map_y * map_w);
93 95
94 for (x = 0, map_x = 0; x < w; 96 for (x = 0, map_x = 0; x < w;
95 x++, dst++, src++, map_x++, map += sizeof(DATA32)) 97 x++, dst++, src++, map_x++, map += sizeof(uint32_t))
96 { 98 {
97 int offx = 0, offy = 0, offx_dec = 0, offy_dec = 0, val = 0; 99 int offx = 0, offy = 0, offx_dec = 0, offy_dec = 0, val = 0;
98 DATA32 col = 0; 100 uint32_t col = 0;
99 Eina_Bool out = 0; 101 Eina_Bool out = 0;
100 102
101 // wrap (x) 103 // wrap (x)
102 if (map_x >= map_w) 104 if (map_x >= map_w)
103 { 105 {
104 map_x = 0; 106 map_x = 0;
105 map = (DATA8 *) (map_start + map_y * map_w); 107 map = (uint8_t *) (map_start + map_y * map_w);
106 } 108 }
107 109
108 if (!map[ALPHA]) continue; 110 if (!map[ALPHA]) continue;
@@ -134,7 +136,7 @@ _filter_displace_cpu_rgba_do(int w, int h, int map_w, int map_h, int intensity,
134 else 136 else
135 { 137 {
136 int R, G, B, A; 138 int R, G, B, A;
137 DATA32 s00, s01, s10, s11; // indexes represent x,y 139 uint32_t s00, s01, s10, s11; // indexes represent x,y
138 int mul00, mul01, mul10, mul11; 140 int mul00, mul01, mul10, mul11;
139 141
140 mul00 = (128 - offx_dec) * (128 - offy_dec); 142 mul00 = (128 - offx_dec) * (128 - offy_dec);
@@ -172,7 +174,7 @@ _filter_displace_cpu_rgba_do(int w, int h, int map_w, int map_h, int intensity,
172 174
173 if (blend) 175 if (blend)
174 { 176 {
175 DATA32 a = 256 - ALPHA_OF(col); 177 uint32_t a = 256 - ALPHA_OF(col);
176 *dst = col + MUL_256(a, *dst); 178 *dst = col + MUL_256(a, *dst);
177 } 179 }
178 else 180 else
@@ -193,26 +195,21 @@ _filter_displace_cpu_rgba_do(int w, int h, int map_w, int map_h, int intensity,
193static Eina_Bool 195static Eina_Bool
194_filter_displace_cpu_alpha(Evas_Filter_Command *cmd) 196_filter_displace_cpu_alpha(Evas_Filter_Command *cmd)
195{ 197{
198 unsigned int src_len, src_stride, map_len, map_stride, dst_len, dst_stride;
196 int w, h, map_w, map_h, intensity; 199 int w, h, map_w, map_h, intensity;
197 DATA8 *dst, *src; 200 uint8_t *dst, *src;
198 DATA32 *map_start; 201 uint32_t *map_start;
199 Eina_Bool stretch, smooth, blend; 202 Eina_Bool stretch, smooth, blend;
203 Evas_Filter_Buffer *map_fb;
204 Eina_Bool ret = EINA_FALSE;
200 205
201 w = cmd->input->w; 206 w = cmd->input->w;
202 h = cmd->input->h; 207 h = cmd->input->h;
203 EINA_SAFETY_ON_FALSE_RETURN_VAL(w == cmd->output->w, EINA_FALSE); 208 EINA_SAFETY_ON_FALSE_RETURN_VAL(w == cmd->output->w, EINA_FALSE);
204 EINA_SAFETY_ON_FALSE_RETURN_VAL(h == cmd->output->h, EINA_FALSE); 209 EINA_SAFETY_ON_FALSE_RETURN_VAL(h == cmd->output->h, EINA_FALSE);
205 EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input->backing, EINA_FALSE);
206 EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->mask->backing, EINA_FALSE);
207 EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output->backing, EINA_FALSE);
208
209 src = ((RGBA_Image *) cmd->input->backing)->image.data8;
210 map_start = ((RGBA_Image *) cmd->mask->backing)->image.data;
211 dst = ((RGBA_Image *) cmd->output->backing)->image.data8;
212 EINA_SAFETY_ON_NULL_RETURN_VAL(src, EINA_FALSE);
213 EINA_SAFETY_ON_NULL_RETURN_VAL(map_start, EINA_FALSE);
214 EINA_SAFETY_ON_NULL_RETURN_VAL(dst, EINA_FALSE);
215 210
211 src = _buffer_map_all(cmd->input->buffer, &src_len, E_READ, E_ALPHA, &src_stride);
212 dst = _buffer_map_all(cmd->output->buffer, &dst_len, E_READ, E_ALPHA, &dst_stride);
216 stretch = cmd->displacement.flags & EVAS_FILTER_DISPLACE_STRETCH; 213 stretch = cmd->displacement.flags & EVAS_FILTER_DISPLACE_STRETCH;
217 smooth = cmd->displacement.flags & EVAS_FILTER_DISPLACE_LINEAR; 214 smooth = cmd->displacement.flags & EVAS_FILTER_DISPLACE_LINEAR;
218 map_w = cmd->mask->w; 215 map_w = cmd->mask->w;
@@ -223,26 +220,32 @@ _filter_displace_cpu_alpha(Evas_Filter_Command *cmd)
223 // Stretch if necessary. 220 // Stretch if necessary.
224 if ((map_w != w || map_h != h) && (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_XY)) 221 if ((map_w != w || map_h != h) && (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_XY))
225 { 222 {
226 Evas_Filter_Buffer *fb;
227
228 if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_X) 223 if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_X)
229 map_w = w; 224 map_w = w;
230 if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_Y) 225 if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_Y)
231 map_h = h; 226 map_h = h;
232 227
233 BUFFERS_LOCK(); 228 BUFFERS_LOCK();
234 fb = evas_filter_buffer_scaled_get(cmd->ctx, cmd->mask, map_w, map_h); 229 map_fb = evas_filter_buffer_scaled_get(cmd->ctx, cmd->mask, map_w, map_h);
235 BUFFERS_UNLOCK(); 230 BUFFERS_UNLOCK();
236 231
237 EINA_SAFETY_ON_NULL_RETURN_VAL(fb, EINA_FALSE); 232 EINA_SAFETY_ON_NULL_RETURN_VAL(map_fb, EINA_FALSE);
238 fb->locked = EINA_FALSE; 233 map_fb->locked = EINA_FALSE;
239 map_start = ((RGBA_Image *) fb->backing)->image.data;
240 } 234 }
235 else map_fb = cmd->mask;
236
237 map_start = (uint32_t *) _buffer_map_all(map_fb->buffer, &map_len, E_READ, E_ARGB, &map_stride);
238 EINA_SAFETY_ON_FALSE_GOTO(src && dst && map_start, end);
241 239
242 _filter_displace_cpu_alpha_do(w, h, map_w, map_h, intensity, 240 _filter_displace_cpu_alpha_do(w, h, map_w, map_h, intensity,
243 src, dst, map_start, stretch, smooth, blend); 241 src, dst, map_start, stretch, smooth, blend);
244 242
245 return EINA_TRUE; 243 ret = EINA_TRUE;
244end:
245 eo_do(cmd->input->buffer, ector_buffer_unmap(src, src_len));
246 eo_do(cmd->output->buffer, ector_buffer_unmap(dst, dst_len));
247 eo_do(map_fb->buffer, ector_buffer_unmap(map_start, map_len));
248 return ret;
246} 249}
247 250
248/** 251/**
@@ -254,25 +257,20 @@ _filter_displace_cpu_alpha(Evas_Filter_Command *cmd)
254static Eina_Bool 257static Eina_Bool
255_filter_displace_cpu_rgba(Evas_Filter_Command *cmd) 258_filter_displace_cpu_rgba(Evas_Filter_Command *cmd)
256{ 259{
260 unsigned int src_len, src_stride, map_len, map_stride, dst_len, dst_stride;
257 int w, h, map_w, map_h, intensity; 261 int w, h, map_w, map_h, intensity;
258 DATA32 *dst, *src, *map_start; 262 uint32_t *dst, *src, *map_start;
259 Eina_Bool stretch, smooth, blend; 263 Eina_Bool stretch, smooth, blend;
264 Evas_Filter_Buffer *map_fb;
265 Eina_Bool ret = EINA_FALSE;
260 266
261 w = cmd->input->w; 267 w = cmd->input->w;
262 h = cmd->input->h; 268 h = cmd->input->h;
263 EINA_SAFETY_ON_FALSE_RETURN_VAL(w == cmd->output->w, EINA_FALSE); 269 EINA_SAFETY_ON_FALSE_RETURN_VAL(w == cmd->output->w, EINA_FALSE);
264 EINA_SAFETY_ON_FALSE_RETURN_VAL(h == cmd->output->h, EINA_FALSE); 270 EINA_SAFETY_ON_FALSE_RETURN_VAL(h == cmd->output->h, EINA_FALSE);
265 EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input->backing, EINA_FALSE);
266 EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->mask->backing, EINA_FALSE);
267 EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output->backing, EINA_FALSE);
268
269 src = ((RGBA_Image *) cmd->input->backing)->image.data;
270 map_start = ((RGBA_Image *) cmd->mask->backing)->image.data;
271 dst = ((RGBA_Image *) cmd->output->backing)->image.data;
272 EINA_SAFETY_ON_NULL_RETURN_VAL(src, EINA_FALSE);
273 EINA_SAFETY_ON_NULL_RETURN_VAL(map_start, EINA_FALSE);
274 EINA_SAFETY_ON_NULL_RETURN_VAL(dst, EINA_FALSE);
275 271
272 src = _buffer_map_all(cmd->input->buffer, &src_len, E_READ, E_ARGB, &src_stride);
273 dst = _buffer_map_all(cmd->output->buffer, &dst_len, E_READ, E_ARGB, &dst_stride);
276 stretch = cmd->displacement.flags & EVAS_FILTER_DISPLACE_STRETCH; 274 stretch = cmd->displacement.flags & EVAS_FILTER_DISPLACE_STRETCH;
277 smooth = cmd->displacement.flags & EVAS_FILTER_DISPLACE_LINEAR; 275 smooth = cmd->displacement.flags & EVAS_FILTER_DISPLACE_LINEAR;
278 map_w = cmd->mask->w; 276 map_w = cmd->mask->w;
@@ -283,26 +281,32 @@ _filter_displace_cpu_rgba(Evas_Filter_Command *cmd)
283 // Stretch if necessary. 281 // Stretch if necessary.
284 if ((map_w != w || map_h != h) && (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_XY)) 282 if ((map_w != w || map_h != h) && (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_XY))
285 { 283 {
286 Evas_Filter_Buffer *fb;
287
288 if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_X) 284 if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_X)
289 map_w = w; 285 map_w = w;
290 if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_Y) 286 if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_Y)
291 map_h = h; 287 map_h = h;
292 288
293 BUFFERS_LOCK(); 289 BUFFERS_LOCK();
294 fb = evas_filter_buffer_scaled_get(cmd->ctx, cmd->mask, map_w, map_h); 290 map_fb = evas_filter_buffer_scaled_get(cmd->ctx, cmd->mask, map_w, map_h);
295 BUFFERS_UNLOCK(); 291 BUFFERS_UNLOCK();
296 292
297 EINA_SAFETY_ON_NULL_RETURN_VAL(fb, EINA_FALSE); 293 EINA_SAFETY_ON_NULL_RETURN_VAL(map_fb, EINA_FALSE);
298 fb->locked = EINA_FALSE; 294 map_fb->locked = EINA_FALSE;
299 map_start = ((RGBA_Image *) fb->backing)->image.data;
300 } 295 }
296 else map_fb = cmd->mask;
297
298 map_start = (uint32_t *) _buffer_map_all(map_fb->buffer, &map_len, E_READ, E_ARGB, &map_stride);
299 EINA_SAFETY_ON_FALSE_GOTO(src && dst && map_start, end);
301 300
302 _filter_displace_cpu_rgba_do(w, h, map_w, map_h, intensity, 301 _filter_displace_cpu_rgba_do(w, h, map_w, map_h, intensity,
303 src, dst, map_start, stretch, smooth, blend); 302 src, dst, map_start, stretch, smooth, blend);
304 303
305 return EINA_TRUE; 304 ret = EINA_TRUE;
305end:
306 eo_do(cmd->input->buffer, ector_buffer_unmap(src, src_len));
307 eo_do(cmd->output->buffer, ector_buffer_unmap(dst, dst_len));
308 eo_do(map_fb->buffer, ector_buffer_unmap(map_start, map_len));
309 return ret;
306} 310}
307 311
308Evas_Filter_Apply_Func 312Evas_Filter_Apply_Func
diff --git a/src/lib/evas/filters/evas_filter_fill.c b/src/lib/evas/filters/evas_filter_fill.c
index 52932333e0..e7090d9913 100644
--- a/src/lib/evas/filters/evas_filter_fill.c
+++ b/src/lib/evas/filters/evas_filter_fill.c
@@ -1,14 +1,17 @@
1#include "evas_filter_private.h" 1#include "evas_filter_private.h"
2#include "draw.h"
2 3
3static Eina_Bool 4static Eina_Bool
4_fill_cpu(Evas_Filter_Command *cmd) 5_fill_cpu(Evas_Filter_Command *cmd)
5{ 6{
6 Evas_Filter_Buffer *fb = cmd->output; 7 Evas_Filter_Buffer *fb = cmd->output;
7 int step = fb->alpha_only ? sizeof(DATA8) : sizeof(DATA32); 8 int step = fb->alpha_only ? sizeof(uint8_t) : sizeof(uint32_t);
8 int x = MAX(0, cmd->draw.clip.x); 9 int x = MAX(0, cmd->draw.clip.x);
9 int y = MAX(0, cmd->draw.clip.y); 10 int y = MAX(0, cmd->draw.clip.y);
10 DATA8 *ptr = ((RGBA_Image *) fb->backing)->image.data8; 11 uint32_t color = ARGB_JOIN(cmd->draw.A, cmd->draw.R, cmd->draw.G, cmd->draw.B);
11 int w, h, k, j; 12 unsigned int stride, len;
13 int w, h, k;
14 uint8_t *ptr;
12 15
13 if (!cmd->draw.clip_mode_lrtb) 16 if (!cmd->draw.clip_mode_lrtb)
14 { 17 {
@@ -29,30 +32,28 @@ _fill_cpu(Evas_Filter_Command *cmd)
29 h = CLAMP(0, fb->h - y - cmd->draw.clip.b, fb->h - y); 32 h = CLAMP(0, fb->h - y - cmd->draw.clip.b, fb->h - y);
30 } 33 }
31 34
32 ptr += y * step * fb->w; 35 ptr = _buffer_map_all(fb->buffer, &len, E_WRITE, fb->alpha_only ? E_ALPHA : E_ARGB, &stride);
33 if ((fb->alpha_only) 36 if (!ptr) return EINA_FALSE;
34 || (!cmd->draw.R && !cmd->draw.G && !cmd->draw.B && !cmd->draw.A) 37
35 || ((cmd->draw.R == 0xff) && (cmd->draw.G == 0xff) 38 ptr += y * stride;
36 && (cmd->draw.B == 0xff) && (cmd->draw.A == 0xff))) 39 if (fb->alpha_only)
37 { 40 {
38 for (k = 0; k < h; k++) 41 for (k = 0; k < h; k++)
39 { 42 {
40 memset(ptr + (x * step), cmd->draw.A, step * w); 43 memset(ptr + (x * step), cmd->draw.A, step * w);
41 ptr += step * fb->w; 44 ptr += stride;
42 } 45 }
43 } 46 }
44 else 47 else
45 { 48 {
46 DATA32 *dst = ((DATA32 *) ptr) + x;
47 DATA32 color = ARGB_JOIN(cmd->draw.A, cmd->draw.R, cmd->draw.G, cmd->draw.B);
48 for (k = 0; k < h; k++) 49 for (k = 0; k < h; k++)
49 { 50 {
50 for (j = 0; j < w; j++) 51 uint32_t *dst = ((uint32_t *) (ptr + (y + k) * stride)) + x;
51 *dst++ = color; 52 draw_memset32(dst, color, w);
52 dst += fb->w - w;
53 } 53 }
54 } 54 }
55 55
56 eo_do(fb->buffer, ector_buffer_unmap(ptr, len));
56 return EINA_TRUE; 57 return EINA_TRUE;
57} 58}
58 59
diff --git a/src/lib/evas/filters/evas_filter_mask.c b/src/lib/evas/filters/evas_filter_mask.c
index 135d0dfbe9..d8d6ddabe7 100644
--- a/src/lib/evas/filters/evas_filter_mask.c
+++ b/src/lib/evas/filters/evas_filter_mask.c
@@ -18,11 +18,11 @@ evas_filter_mask_cpu_func_get(Evas_Filter_Command *cmd)
18 EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input, NULL); 18 EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input, NULL);
19 EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output, NULL); 19 EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output, NULL);
20 EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->mask, NULL); 20 EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->mask, NULL);
21 21 EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input->buffer, NULL);
22 EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input->backing, NULL); 22 EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output->buffer, NULL);
23 EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output->backing, NULL); 23 EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->mask->buffer, NULL);
24 EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->mask->backing, NULL); 24 EINA_SAFETY_ON_FALSE_RETURN_VAL((cmd->input->w > 0) && (cmd->input->h > 0), NULL);
25 25 EINA_SAFETY_ON_FALSE_RETURN_VAL((cmd->mask->w > 0) && (cmd->mask->h > 0), NULL);
26 EINA_SAFETY_ON_FALSE_RETURN_VAL(cmd->input->w == cmd->output->w, NULL); 26 EINA_SAFETY_ON_FALSE_RETURN_VAL(cmd->input->w == cmd->output->w, NULL);
27 EINA_SAFETY_ON_FALSE_RETURN_VAL(cmd->input->h == cmd->output->h, NULL); 27 EINA_SAFETY_ON_FALSE_RETURN_VAL(cmd->input->h == cmd->output->h, NULL);
28 28
@@ -53,12 +53,14 @@ evas_filter_mask_cpu_func_get(Evas_Filter_Command *cmd)
53static Eina_Bool 53static Eina_Bool
54_mask_cpu_alpha_alpha_alpha(Evas_Filter_Command *cmd) 54_mask_cpu_alpha_alpha_alpha(Evas_Filter_Command *cmd)
55{ 55{
56 Alpha_Gfx_Func func; 56 unsigned int src_len, src_stride, msk_len, msk_stride, dst_len, dst_stride;
57 RGBA_Image *in, *out, *mask;
58 DATA8 *src, *dst, *msk;
59 Efl_Gfx_Render_Op render_op = cmd->draw.rop; 57 Efl_Gfx_Render_Op render_op = cmd->draw.rop;
58 Evas_Filter_Buffer *msk_fb;
59 Alpha_Gfx_Func func;
60 uint8_t *src_map = NULL, *dst, *dst_map = NULL, *msk, *msk_map = NULL;
60 int w, h, mw, mh, x, y, my; 61 int w, h, mw, mh, x, y, my;
61 int stepsize, stepcount, step; 62 int stepsize, stepcount, step;
63 Eina_Bool ret = EINA_FALSE;
62 64
63 /* Mechanism: 65 /* Mechanism:
64 * 1. Stretch mask as requested in fillmode 66 * 1. Stretch mask as requested in fillmode
@@ -68,56 +70,57 @@ _mask_cpu_alpha_alpha_alpha(Evas_Filter_Command *cmd)
68 * FIXME: Could probably be optimized into a single op :) 70 * FIXME: Could probably be optimized into a single op :)
69 */ 71 */
70 72
71 in = (RGBA_Image *) cmd->input->backing;
72 out = (RGBA_Image *) cmd->output->backing;
73 mask = (RGBA_Image *) cmd->mask->backing;
74
75 w = cmd->input->w; 73 w = cmd->input->w;
76 h = cmd->input->h; 74 h = cmd->input->h;
77 mw = cmd->mask->w; 75 mw = cmd->mask->w;
78 mh = cmd->mask->h; 76 mh = cmd->mask->h;
79 src = in->image.data8;
80 dst = out->image.data8;
81
82 EINA_SAFETY_ON_FALSE_RETURN_VAL((w > 0) && (mw > 0), EINA_FALSE);
83
84 stepsize = MIN(mw, w); 77 stepsize = MIN(mw, w);
85 stepcount = w / stepsize; 78 stepcount = w / stepsize;
86 79
87 // Stretch if necessary. 80 // Stretch if necessary.
88 if ((mw != w || mh != h) && (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_XY)) 81 if ((mw != w || mh != h) && (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_XY))
89 { 82 {
90 Evas_Filter_Buffer *fb;
91
92 if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_X) 83 if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_X)
93 mw = w; 84 mw = w;
94 if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_Y) 85 if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_Y)
95 mh = h; 86 mh = h;
96 87
97 BUFFERS_LOCK(); 88 BUFFERS_LOCK();
98 fb = evas_filter_buffer_scaled_get(cmd->ctx, cmd->mask, mw, mh); 89 msk_fb = evas_filter_buffer_scaled_get(cmd->ctx, cmd->mask, mw, mh);
99 BUFFERS_UNLOCK(); 90 BUFFERS_UNLOCK();
100 91
101 EINA_SAFETY_ON_NULL_RETURN_VAL(fb, EINA_FALSE); 92 EINA_SAFETY_ON_NULL_RETURN_VAL(msk_fb, EINA_FALSE);
102 fb->locked = EINA_FALSE; 93 msk_fb->locked = EINA_FALSE;
103 mask = fb->backing;
104 } 94 }
95 else msk_fb = cmd->mask;
105 96
106 msk = mask->image.data8; 97 msk_map = msk = _buffer_map_all(msk_fb->buffer, &msk_len, E_READ, E_ALPHA, &msk_stride);
98 dst_map = dst = _buffer_map_all(cmd->output->buffer, &dst_len, E_WRITE, E_ALPHA, &dst_stride);
99 EINA_SAFETY_ON_FALSE_GOTO(dst_map && msk_map, end);
107 100
108 // First pass: copy to dest 101 // First pass: copy to dest
109 if (src != dst) 102 if (cmd->input->buffer != cmd->output->buffer)
110 memcpy(dst, src, w * h * sizeof(DATA8)); 103 {
104 src_map = _buffer_map_all(cmd->input->buffer, &src_len, E_READ, E_ALPHA, &src_stride);
105 EINA_SAFETY_ON_FALSE_GOTO(src_map, end);
106 if (dst_stride == src_stride)
107 memcpy(dst_map, src_map, dst_stride * h * sizeof(uint8_t));
108 else
109 {
110 for (y = 0; y < h; y++)
111 memcpy(dst_map + (y * dst_stride), src_map + (y * src_stride),
112 MIN(dst_stride, src_stride) * h * sizeof(uint8_t));
113 }
114 }
111 115
112 // Second pass: apply render op 116 // Second pass: apply render op
113 func = efl_draw_alpha_func_get(render_op, EINA_FALSE); 117 func = efl_draw_alpha_func_get(render_op, EINA_FALSE);
114 for (y = 0, my = 0; y < h; y++, my++, msk += mw) 118 for (y = 0, my = 0; y < h; y++, my++)
115 { 119 {
116 if (my >= mh) 120 if (my >= mh) my = 0;
117 { 121
118 my = 0; 122 msk = msk_map + (my * msk_stride);
119 msk = mask->image.data8; 123 dst = dst_map + (y * dst_stride);
120 }
121 124
122 for (step = 0; step < stepcount; step++, dst += stepsize) 125 for (step = 0; step < stepcount; step++, dst += stepsize)
123 func(msk, dst, stepsize); 126 func(msk, dst, stepsize);
@@ -126,11 +129,16 @@ _mask_cpu_alpha_alpha_alpha(Evas_Filter_Command *cmd)
126 if (x < w) 129 if (x < w)
127 { 130 {
128 func(msk, dst, w - x); 131 func(msk, dst, w - x);
129 dst += w - x;
130 } 132 }
131 } 133 }
132 134
133 return EINA_TRUE; 135 ret = EINA_TRUE;
136
137end:
138 eo_do(cmd->input->buffer, ector_buffer_unmap(src_map, src_len));
139 eo_do(msk_fb->buffer, ector_buffer_unmap(msk_map, msk_len));
140 eo_do(cmd->output->buffer, ector_buffer_unmap(dst_map, dst_len));
141 return ret;
134} 142}
135 143
136static Eina_Bool 144static Eina_Bool
@@ -161,14 +169,16 @@ _mask_cpu_rgba_alpha_rgba(Evas_Filter_Command *cmd)
161static Eina_Bool 169static Eina_Bool
162_mask_cpu_alpha_rgba_rgba(Evas_Filter_Command *cmd) 170_mask_cpu_alpha_rgba_rgba(Evas_Filter_Command *cmd)
163{ 171{
164 RGBA_Gfx_Func func1, func2; 172 unsigned int src_len, src_stride, msk_len, msk_stride, dst_len, dst_stride;
165 RGBA_Image *in, *out, *mask;
166 DATA8 *src;
167 DATA32 *dst, *msk, *span;
168 Efl_Gfx_Render_Op op = cmd->draw.rop; 173 Efl_Gfx_Render_Op op = cmd->draw.rop;
169 int w, h, mw, mh, y, my, r; 174 Evas_Filter_Buffer *msk_fb;
175 RGBA_Gfx_Func func1, func2;
176 uint8_t *src, *src_map = NULL, *msk_map = NULL, *dst_map = NULL;
177 uint32_t *dst, *msk, *span;
178 int w, h, mw, mh, x, y, my;
170 int stepsize, stepcount, step; 179 int stepsize, stepcount, step;
171 DATA32 color2; 180 Eina_Bool ret = EINA_FALSE;
181 uint32_t color;
172 182
173 /* Mechanism: 183 /* Mechanism:
174 * 1. Stretch mask as requested in fillmode 184 * 1. Stretch mask as requested in fillmode
@@ -178,94 +188,88 @@ _mask_cpu_alpha_rgba_rgba(Evas_Filter_Command *cmd)
178 * FIXME: Could probably be optimized into a single op :) 188 * FIXME: Could probably be optimized into a single op :)
179 */ 189 */
180 190
181 in = (RGBA_Image *) cmd->input->backing;
182 out = (RGBA_Image *) cmd->output->backing;
183 mask = (RGBA_Image *) cmd->mask->backing;
184
185 w = cmd->input->w; 191 w = cmd->input->w;
186 h = cmd->input->h; 192 h = cmd->input->h;
187 mw = cmd->mask->w; 193 mw = cmd->mask->w;
188 mh = cmd->mask->h; 194 mh = cmd->mask->h;
189 src = in->image.data8; 195 color = ARGB_JOIN(cmd->draw.A, cmd->draw.R, cmd->draw.G, cmd->draw.B);
190 dst = out->image.data; 196 stepsize = MIN(mw, w);
197 stepcount = w / stepsize;
198 span = alloca(stepsize * sizeof(uint32_t));
191 199
192 // Stretch if necessary. 200 // Stretch if necessary.
193 if ((mw != w || mh != h) && (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_XY)) 201 if ((mw != w || mh != h) && (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_XY))
194 { 202 {
195 Evas_Filter_Buffer *fb;
196
197 if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_X) 203 if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_X)
198 mw = w; 204 mw = w;
199 if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_Y) 205 if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_Y)
200 mh = h; 206 mh = h;
201 207
202 BUFFERS_LOCK(); 208 BUFFERS_LOCK();
203 fb = evas_filter_buffer_scaled_get(cmd->ctx, cmd->mask, mw, mh); 209 msk_fb = evas_filter_buffer_scaled_get(cmd->ctx, cmd->mask, mw, mh);
204 BUFFERS_UNLOCK(); 210 BUFFERS_UNLOCK();
205 211
206 EINA_SAFETY_ON_NULL_RETURN_VAL(fb, EINA_FALSE); 212 EINA_SAFETY_ON_NULL_RETURN_VAL(msk_fb, EINA_FALSE);
207 fb->locked = EINA_FALSE; 213 msk_fb->locked = EINA_FALSE;
208 mask = fb->backing;
209 } 214 }
215 else msk_fb = cmd->mask;
210 216
211 color2 = ARGB_JOIN(cmd->draw.A, cmd->draw.R, cmd->draw.G, cmd->draw.B); 217 src_map = _buffer_map_all(cmd->input->buffer, &src_len, E_WRITE, E_ALPHA, &src_stride);
212 msk = mask->image.data; 218 msk_map = _buffer_map_all(msk_fb->buffer, &msk_len, E_READ, E_ARGB, &msk_stride);
219 dst_map = _buffer_map_all(cmd->output->buffer, &dst_len, E_WRITE, E_ARGB, &dst_stride);
220 EINA_SAFETY_ON_FALSE_GOTO(src_map && dst_map && msk_map, end);
213 221
214 EINA_SAFETY_ON_NULL_RETURN_VAL(src, EINA_FALSE); 222 func1 = evas_common_gfx_func_composite_pixel_mask_span_get(1, 0, 1, 1, EVAS_RENDER_COPY);
215 EINA_SAFETY_ON_NULL_RETURN_VAL(dst, EINA_FALSE); 223 func2 = evas_common_gfx_func_composite_pixel_color_span_get(1, 0, color, 1, 1, _gfx_to_evas_render_op(op));
216 EINA_SAFETY_ON_NULL_RETURN_VAL(msk, EINA_FALSE);
217 EINA_SAFETY_ON_FALSE_RETURN_VAL((w > 0) && (mw > 0), EINA_FALSE);
218
219 stepsize = MIN(mw, w);
220 stepcount = w / stepsize;
221 span = malloc(stepsize * sizeof(DATA32));
222
223 func1 = evas_common_gfx_func_composite_pixel_mask_span_get(mask->cache_entry.flags.alpha, mask->cache_entry.flags.alpha_sparse, out->cache_entry.flags.alpha, 1, EVAS_RENDER_COPY);
224 func2 = evas_common_gfx_func_composite_pixel_color_span_get(mask->cache_entry.flags.alpha, mask->cache_entry.flags.alpha_sparse, color2, out->cache_entry.flags.alpha, 1, _gfx_to_evas_render_op(op));
225 224
226 // Apply mask using Gfx functions 225 // Apply mask using Gfx functions
227 for (y = 0, my = 0; y < h; y++, my++, msk += mw) 226 for (y = 0, my = 0; y < h; y++, my++)
228 { 227 {
229 if (my >= mh) 228 if (my >= mh) my = 0;
230 { 229
231 my = 0; 230 src = src_map + (y * src_stride);
232 msk = mask->image.data; 231 msk = (uint32_t *) (msk_map + (my * msk_stride));
233 } 232 dst = (uint32_t *) (dst_map + (y * dst_stride));
234 233
235 for (step = 0; step < stepcount; step++, dst += stepsize, src += stepsize) 234 for (step = 0; step < stepcount; step++, dst += stepsize, src += stepsize)
236 { 235 {
237 memset(span, 0, stepsize * sizeof(DATA32)); 236 memset(span, 0, stepsize * sizeof(uint32_t));
238 func1(msk, src, 0, span, stepsize); 237 func1(msk, src, 0, span, stepsize);
239 func2(span, NULL, color2, dst, stepsize); 238 func2(span, NULL, color, dst, stepsize);
240 } 239 }
241 240
242 r = w - (stepsize * stepcount); 241 x = stepsize * stepcount;
243 if (r > 0) 242 if (x < w)
244 { 243 {
245 memset(span, 0, r * sizeof(DATA32)); 244 memset(span, 0, (w - x) * sizeof(uint32_t));
246 func1(msk, src, 0, span, r); 245 func1(msk, src, 0, span, w - x);
247 func2(span, NULL, color2, dst, r); 246 func2(span, NULL, color, dst, w - x);
248 dst += r;
249 src += r;
250 } 247 }
251 } 248 }
252 249
253 free(span); 250 ret = EINA_TRUE;
254 return EINA_TRUE; 251
252end:
253 eo_do(cmd->input->buffer, ector_buffer_unmap(src_map, src_len));
254 eo_do(msk_fb->buffer, ector_buffer_unmap(msk_map, msk_len));
255 eo_do(cmd->output->buffer, ector_buffer_unmap(dst_map, dst_len));
256 return ret;
255} 257}
256 258
257static Eina_Bool 259static Eina_Bool
258_mask_cpu_alpha_alpha_rgba(Evas_Filter_Command *cmd) 260_mask_cpu_alpha_alpha_rgba(Evas_Filter_Command *cmd)
259{ 261{
262 unsigned int src_len, src_stride, msk_len, msk_stride, dst_len, dst_stride;
263 uint8_t *src, *msk, *span, *src_map = NULL, *msk_map = NULL, *dst_map = NULL;
264 Evas_Filter_Buffer *msk_fb;
260 RGBA_Gfx_Func func; 265 RGBA_Gfx_Func func;
261 Alpha_Gfx_Func span_func; 266 Alpha_Gfx_Func span_func;
262 RGBA_Image *in, *out, *mask; 267 uint32_t *dst;
263 DATA8 *src, *msk, *span; 268 uint32_t color;
264 DATA32 *dst;
265 DATA32 color;
266 Efl_Gfx_Render_Op op = cmd->draw.rop; 269 Efl_Gfx_Render_Op op = cmd->draw.rop;
267 int w, h, mw, mh, y, my, r; 270 int w, h, mw, mh, x, y, my;
268 int stepsize, stepcount, step; 271 int stepsize, stepcount, step;
272 Eina_Bool ret = EINA_FALSE;
269 273
270 /* Mechanism: 274 /* Mechanism:
271 * 1. Copy mask to span buffer (1 line) 275 * 1. Copy mask to span buffer (1 line)
@@ -275,155 +279,147 @@ _mask_cpu_alpha_alpha_rgba(Evas_Filter_Command *cmd)
275 * FIXME: Could probably be optimized into a single op :) 279 * FIXME: Could probably be optimized into a single op :)
276 */ 280 */
277 281
278 in = (RGBA_Image *) cmd->input->backing;
279 out = (RGBA_Image *) cmd->output->backing;
280 mask = (RGBA_Image *) cmd->mask->backing;
281
282 w = cmd->input->w; 282 w = cmd->input->w;
283 h = cmd->input->h; 283 h = cmd->input->h;
284 mw = cmd->mask->w; 284 mw = cmd->mask->w;
285 mh = cmd->mask->h; 285 mh = cmd->mask->h;
286 src = in->image.data8;
287 dst = out->image.data;
288 color = ARGB_JOIN(cmd->draw.A, cmd->draw.R, cmd->draw.G, cmd->draw.B); 286 color = ARGB_JOIN(cmd->draw.A, cmd->draw.R, cmd->draw.G, cmd->draw.B);
289 287 stepsize = MIN(mw, w);
290 EINA_SAFETY_ON_FALSE_RETURN_VAL((w > 0) && (mw > 0), EINA_FALSE); 288 stepcount = w / stepsize;
289 span = alloca(stepsize * sizeof(uint32_t));
291 290
292 // Stretch if necessary. 291 // Stretch if necessary.
293 if ((mw != w || mh != h) && (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_XY)) 292 if ((mw != w || mh != h) && (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_XY))
294 { 293 {
295 Evas_Filter_Buffer *fb;
296
297 if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_X) 294 if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_X)
298 mw = w; 295 mw = w;
299 if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_Y) 296 if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_Y)
300 mh = h; 297 mh = h;
301 298
302 BUFFERS_LOCK(); 299 BUFFERS_LOCK();
303 fb = evas_filter_buffer_scaled_get(cmd->ctx, cmd->mask, mw, mh); 300 msk_fb = evas_filter_buffer_scaled_get(cmd->ctx, cmd->mask, mw, mh);
304 BUFFERS_UNLOCK(); 301 BUFFERS_UNLOCK();
305 302
306 EINA_SAFETY_ON_NULL_RETURN_VAL(fb, EINA_FALSE); 303 EINA_SAFETY_ON_NULL_RETURN_VAL(msk_fb, EINA_FALSE);
307 fb->locked = EINA_FALSE; 304 msk_fb->locked = EINA_FALSE;
308 mask = fb->backing;
309 } 305 }
306 else msk_fb = cmd->mask;
310 307
311 msk = mask->image.data8; 308 src_map = _buffer_map_all(cmd->input->buffer, &src_len, E_WRITE, E_ALPHA, &src_stride);
312 stepsize = MIN(mw, w); 309 msk_map = _buffer_map_all(msk_fb->buffer, &msk_len, E_READ, E_ARGB, &msk_stride);
313 stepcount = w / stepsize; 310 dst_map = _buffer_map_all(cmd->output->buffer, &dst_len, E_WRITE, E_ARGB, &dst_stride);
314 span = malloc(stepsize * sizeof(DATA8)); 311 EINA_SAFETY_ON_FALSE_GOTO(src_map && dst_map && msk_map, end);
315 312
316 func = evas_common_gfx_func_composite_mask_color_span_get(color, out->cache_entry.flags.alpha, 1, _gfx_to_evas_render_op(op)); 313 func = evas_common_gfx_func_composite_mask_color_span_get(color, 1, 1, _gfx_to_evas_render_op(op));
317 span_func = efl_draw_alpha_func_get(cmd->draw.rop, EINA_TRUE); 314 span_func = efl_draw_alpha_func_get(cmd->draw.rop, EINA_TRUE);
318 315
319 for (y = 0, my = 0; y < h; y++, my++, msk += mw) 316 for (y = 0, my = 0; y < h; y++, my++, msk += mw)
320 { 317 {
321 if (my >= mh) 318 if (my >= mh) my = 0;
322 { 319
323 my = 0; 320 src = src_map + (y * src_stride);
324 msk = mask->image.data8; 321 msk = msk_map + (my * msk_stride);
325 } 322 dst = (uint32_t *) (dst_map + (y * dst_stride));
326 323
327 for (step = 0; step < stepcount; step++, dst += stepsize, src += stepsize) 324 for (step = 0; step < stepcount; step++, dst += stepsize, src += stepsize)
328 { 325 {
329 memcpy(span, msk, stepsize * sizeof(DATA8)); 326 memcpy(span, msk, stepsize * sizeof(uint8_t));
330 span_func(src, span, stepsize); 327 span_func(src, span, stepsize);
331 func(NULL, span, color, dst, stepsize); 328 func(NULL, span, color, dst, stepsize);
332 } 329 }
333 330
334 r = w - (stepsize * stepcount); 331 x = stepsize * stepcount;
335 if (r > 0) 332 if (x < w)
336 { 333 {
337 memcpy(span, msk, r * sizeof(DATA8)); 334 memcpy(span, msk, (w - x) * sizeof(uint8_t));
338 span_func(src, span, r); 335 span_func(src, span, w - x);
339 func(NULL, span, color, dst, r); 336 func(NULL, span, color, dst, w -x);
340 dst += r;
341 src += r;
342 } 337 }
343 } 338 }
344 339
345 free(span); 340 ret = EINA_TRUE;
346 return EINA_TRUE; 341
342end:
343 eo_do(cmd->input->buffer, ector_buffer_unmap(src_map, src_len));
344 eo_do(msk_fb->buffer, ector_buffer_unmap(msk_map, msk_len));
345 eo_do(cmd->output->buffer, ector_buffer_unmap(dst_map, dst_len));
346 return ret;
347} 347}
348 348
349static Eina_Bool 349static Eina_Bool
350_mask_cpu_rgba_rgba_rgba(Evas_Filter_Command *cmd) 350_mask_cpu_rgba_rgba_rgba(Evas_Filter_Command *cmd)
351{ 351{
352 unsigned int src_len, src_stride, msk_len, msk_stride, dst_len, dst_stride;
353 uint8_t *src_map = NULL, *msk_map = NULL, *dst_map = NULL;
352 Draw_Func_ARGB_Mix3 func; 354 Draw_Func_ARGB_Mix3 func;
353 RGBA_Image *in, *out, *mask; 355 Evas_Filter_Buffer *msk_fb;
354 DATA32 *dst, *msk, *src; 356 uint32_t *dst, *msk, *src;
355 int w, h, mw, mh, y, my, r; 357 int w, h, mw, mh, x, y, my;
356 int stepsize, stepcount, step; 358 int stepsize, stepcount, step;
357 DATA32 color; 359 Eina_Bool ret = EINA_FALSE;
360 uint32_t color;
358 361
359 /* Mechanism: 362 /* Mechanism:
360 * 1. Stretch mask as requested in fillmode 363 * 1. Stretch mask as requested in fillmode
361 * 2. Mix 3 colors 364 * 2. Mix 3 colors
362 */ 365 */
363 366
364 in = (RGBA_Image *) cmd->input->backing;
365 out = (RGBA_Image *) cmd->output->backing;
366 mask = (RGBA_Image *) cmd->mask->backing;
367
368 w = cmd->input->w; 367 w = cmd->input->w;
369 h = cmd->input->h; 368 h = cmd->input->h;
370 mw = cmd->mask->w; 369 mw = cmd->mask->w;
371 mh = cmd->mask->h; 370 mh = cmd->mask->h;
372 src = in->image.data; 371 color = ARGB_JOIN(cmd->draw.A, cmd->draw.R, cmd->draw.G, cmd->draw.B);
373 dst = out->image.data; 372 stepsize = MIN(mw, w);
373 stepcount = w / stepsize;
374 374
375 // Stretch if necessary. 375 // Stretch if necessary.
376 if ((mw != w || mh != h) && (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_XY)) 376 if ((mw != w || mh != h) && (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_XY))
377 { 377 {
378 Evas_Filter_Buffer *fb;
379
380 if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_X) 378 if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_X)
381 mw = w; 379 mw = w;
382 if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_Y) 380 if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_Y)
383 mh = h; 381 mh = h;
384 382
385 BUFFERS_LOCK(); 383 BUFFERS_LOCK();
386 fb = evas_filter_buffer_scaled_get(cmd->ctx, cmd->mask, mw, mh); 384 msk_fb = evas_filter_buffer_scaled_get(cmd->ctx, cmd->mask, mw, mh);
387 BUFFERS_UNLOCK(); 385 BUFFERS_UNLOCK();
388 386
389 EINA_SAFETY_ON_NULL_RETURN_VAL(fb, EINA_FALSE); 387 EINA_SAFETY_ON_NULL_RETURN_VAL(msk_fb, EINA_FALSE);
390 fb->locked = EINA_FALSE; 388 msk_fb->locked = EINA_FALSE;
391 mask = fb->backing;
392 } 389 }
390 else msk_fb = cmd->mask;
393 391
394 color = ARGB_JOIN(cmd->draw.A, cmd->draw.R, cmd->draw.G, cmd->draw.B); 392 src_map = _buffer_map_all(cmd->input->buffer, &src_len, E_WRITE, E_ARGB, &src_stride);
395 msk = mask->image.data; 393 msk_map = _buffer_map_all(msk_fb->buffer, &msk_len, E_READ, E_ARGB, &msk_stride);
396 394 dst_map = _buffer_map_all(cmd->output->buffer, &dst_len, E_WRITE, E_ARGB, &dst_stride);
397 EINA_SAFETY_ON_NULL_RETURN_VAL(src, EINA_FALSE); 395 EINA_SAFETY_ON_FALSE_GOTO(src_map && dst_map && msk_map, end);
398 EINA_SAFETY_ON_NULL_RETURN_VAL(dst, EINA_FALSE);
399 EINA_SAFETY_ON_NULL_RETURN_VAL(msk, EINA_FALSE);
400 EINA_SAFETY_ON_FALSE_RETURN_VAL((w > 0) && (mw > 0), EINA_FALSE);
401
402 stepsize = MIN(mw, w);
403 stepcount = w / stepsize;
404 396
405 func = efl_draw_func_argb_mix3_get(cmd->draw.rop, color); 397 func = efl_draw_func_argb_mix3_get(cmd->draw.rop, color);
406 398
407 // Apply mask using Gfx functions 399 // Apply mask using Gfx functions
408 for (y = 0, my = 0; y < h; y++, my++, msk += mw) 400 for (y = 0, my = 0; y < h; y++, my++)
409 { 401 {
410 if (my >= mh) 402 if (my >= mh) my = 0;
411 { 403
412 my = 0; 404 src = (uint32_t *) (src_map + (y * src_stride));
413 msk = mask->image.data; 405 msk = (uint32_t *) (msk_map + (my * msk_stride));
414 } 406 dst = (uint32_t *) (dst_map + (y * dst_stride));
415 407
416 for (step = 0; step < stepcount; step++, dst += stepsize, src += stepsize) 408 for (step = 0; step < stepcount; step++, dst += stepsize, src += stepsize)
417 func(dst, src, msk, stepsize, color); 409 func(dst, src, msk, stepsize, color);
418 410
419 r = w - (stepsize * stepcount); 411 x = stepsize * stepcount;
420 if (r > 0) 412 if (x < w)
421 { 413 {
422 func(dst, src, msk, r, color); 414 func(dst, src, msk, w - x, color);
423 dst += r;
424 src += r;
425 } 415 }
426 } 416 }
427 417
428 return EINA_TRUE; 418 ret = EINA_TRUE;
419
420end:
421 eo_do(cmd->input->buffer, ector_buffer_unmap(src_map, src_len));
422 eo_do(msk_fb->buffer, ector_buffer_unmap(msk_map, msk_len));
423 eo_do(cmd->output->buffer, ector_buffer_unmap(dst_map, dst_len));
424 return ret;
429} 425}
diff --git a/src/lib/evas/filters/evas_filter_private.h b/src/lib/evas/filters/evas_filter_private.h
index 02dd977d34..f3d7118be0 100644
--- a/src/lib/evas/filters/evas_filter_private.h
+++ b/src/lib/evas/filters/evas_filter_private.h
@@ -230,7 +230,7 @@ struct _Evas_Filter_Buffer
230 230
231 Evas_Object *source; 231 Evas_Object *source;
232 Eina_Stringshare *source_name; 232 Eina_Stringshare *source_name;
233 RGBA_Image *backing; 233 Ector_Generic_Buffer *buffer;
234 void *glimage; 234 void *glimage;
235 int w, h; 235 int w, h;
236 236
@@ -275,4 +275,20 @@ int evas_filter_smallest_pow2_larger_than(int val);
275 275
276void evas_filter_parser_shutdown(void); 276void evas_filter_parser_shutdown(void);
277 277
278#define E_READ ECTOR_BUFFER_ACCESS_FLAG_READ
279#define E_WRITE ECTOR_BUFFER_ACCESS_FLAG_WRITE
280#define E_ALPHA EFL_GFX_COLORSPACE_GRY8
281#define E_ARGB EFL_GFX_COLORSPACE_ARGB8888
282
283static inline void *
284_buffer_map_all(Ector_Buffer *buf, unsigned int *len, Ector_Buffer_Access_Flag mode, Efl_Gfx_Colorspace cspace, unsigned int *stride)
285{
286 void *ret = NULL;
287 int w, h;
288 if (!buf) return NULL;
289 eo_do(buf, ector_buffer_size_get(&w, &h);
290 ret = ector_buffer_map(len, mode, 0, 0, w, h, cspace, stride));
291 return ret;
292}
293
278#endif // EVAS_FILTER_PRIVATE_H 294#endif // EVAS_FILTER_PRIVATE_H
diff --git a/src/lib/evas/filters/evas_filter_transform.c b/src/lib/evas/filters/evas_filter_transform.c
index 3deda12c89..fd05d5c7fa 100644
--- a/src/lib/evas/filters/evas_filter_transform.c
+++ b/src/lib/evas/filters/evas_filter_transform.c
@@ -10,27 +10,22 @@
10static Eina_Bool 10static Eina_Bool
11_vflip_cpu(Evas_Filter_Command *cmd) 11_vflip_cpu(Evas_Filter_Command *cmd)
12{ 12{
13 size_t datasize, stride; 13 unsigned int src_len, src_stride, dst_len, dst_stride;
14 DATA8 *in, *out, *span = NULL; 14 uint8_t *in, *out = NULL, *span = NULL;
15 int w, h, sy, dy, oy, center, t, b, objh; 15 int w, h, sy, dy, oy, center, t, b, objh;
16 int s0, s1, d0, d1; 16 int s0, s1, d0, d1;
17 17 Eina_Bool ret = 0;
18 EINA_SAFETY_ON_NULL_RETURN_VAL(cmd, EINA_FALSE);
19 EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input, EINA_FALSE);
20 EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output, EINA_FALSE);
21 EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input->backing, EINA_FALSE);
22 EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output->backing, EINA_FALSE);
23 18
24 w = cmd->input->w; 19 w = cmd->input->w;
25 h = cmd->input->h; 20 h = cmd->input->h;
26 EINA_SAFETY_ON_FALSE_RETURN_VAL(cmd->output->w == w, EINA_FALSE); 21 in = _buffer_map_all(cmd->input->buffer, &src_len, E_READ, cmd->output->alpha_only ? E_ALPHA : E_ARGB, &src_stride);
27 EINA_SAFETY_ON_FALSE_RETURN_VAL(cmd->output->h == h, EINA_FALSE); 22 if (cmd->input->buffer != cmd->output->buffer)
28 EINA_SAFETY_ON_FALSE_RETURN_VAL(cmd->output->alpha_only == cmd->input->alpha_only, EINA_FALSE); 23 out = _buffer_map_all(cmd->output->buffer, &dst_len, E_WRITE, cmd->output->alpha_only ? E_ALPHA : E_ARGB, &dst_stride);
29 24
30 in = ((RGBA_Image *) cmd->input->backing)->image.data8; 25 EINA_SAFETY_ON_FALSE_GOTO(cmd->output->w == w, end);
31 out = ((RGBA_Image *) cmd->output->backing)->image.data8; 26 EINA_SAFETY_ON_FALSE_GOTO(cmd->output->h == h, end);
32 datasize = cmd->input->alpha_only ? sizeof(DATA8) : sizeof(DATA32); 27 EINA_SAFETY_ON_FALSE_GOTO(src_stride <= dst_stride, end);
33 stride = w * datasize; 28 EINA_SAFETY_ON_FALSE_GOTO(cmd->output->alpha_only == cmd->input->alpha_only, end);
34 29
35 oy = cmd->draw.oy; 30 oy = cmd->draw.oy;
36 t = cmd->ctx->padt; 31 t = cmd->ctx->padt;
@@ -53,28 +48,32 @@ _vflip_cpu(Evas_Filter_Command *cmd)
53 48
54 if (in == out) 49 if (in == out)
55 { 50 {
56 span = malloc(stride); 51 span = alloca(src_stride);
57 if (!span) return EINA_FALSE; 52 if (!span) goto end;
58 } 53 }
59 54
60 for (sy = s0, dy = d0; (dy >= d1) && (sy <= s1); sy++, dy--) 55 for (sy = s0, dy = d0; (dy >= d1) && (sy <= s1); sy++, dy--)
61 { 56 {
62 DATA8* src = in + stride * sy; 57 uint8_t* src = in + src_stride * sy;
63 DATA8* dst = out + stride * dy; 58 uint8_t* dst = out + dst_stride * dy;
64 59
65 if (in == out) 60 if (in == out)
66 { 61 {
67 if (src == dst) break; 62 if (src == dst) break;
68 memcpy(span, dst, stride); 63 memcpy(span, dst, src_stride);
69 memcpy(dst, src, stride); 64 memcpy(dst, src, src_stride);
70 memcpy(src, span, stride); 65 memcpy(src, span, src_stride);
71 if (sy >= center) break; 66 if (sy >= center) break;
72 } 67 }
73 else 68 else
74 memcpy(dst, src, stride); 69 memcpy(dst, src, src_stride);
75 } 70 }
76 free(span); 71 ret = EINA_TRUE;
77 return EINA_TRUE; 72
73end:
74 eo_do(cmd->input->buffer, ector_buffer_unmap(in, src_len));
75 if (in != out) eo_do(cmd->output->buffer, ector_buffer_unmap(out, dst_len));
76 return ret;
78} 77}
79 78
80Evas_Filter_Apply_Func 79Evas_Filter_Apply_Func
diff --git a/src/lib/evas/filters/evas_filter_utils.c b/src/lib/evas/filters/evas_filter_utils.c
index c643c67a5f..8bb98d5bf5 100644
--- a/src/lib/evas/filters/evas_filter_utils.c
+++ b/src/lib/evas/filters/evas_filter_utils.c
@@ -8,76 +8,35 @@ evas_filter_buffer_scaled_get(Evas_Filter_Context *ctx,
8 unsigned w, unsigned h) 8 unsigned w, unsigned h)
9{ 9{
10 Evas_Filter_Buffer *fb; 10 Evas_Filter_Buffer *fb;
11 Image_Entry *dstdata = NULL; 11 RGBA_Image *dstim, *srcim;
12 Image_Entry *srcdata; 12 RGBA_Draw_Context dc;
13 void *drawctx; 13 Eina_Bool ok;
14 14
15 srcdata = evas_filter_buffer_backing_get(ctx, src->id); 15 // only for RGBA
16 EINA_SAFETY_ON_NULL_RETURN_VAL(srcdata, NULL); 16 EINA_SAFETY_ON_FALSE_RETURN_VAL(!src->alpha_only, NULL);
17 17
18 if (src->alpha_only) 18 srcim = evas_filter_buffer_backing_get(ctx, src->id);
19 { 19 EINA_SAFETY_ON_NULL_RETURN_VAL(srcim, NULL);
20 // There is no supporting function in Evas for alpha scaling...
21 // but guess what? There is also no use case in the filters :)
22 CRI("Alpha buffer scaling is not supported");
23 return NULL;
24 }
25 20
26 fb = evas_filter_temporary_buffer_get(ctx, w, h, src->alpha_only); 21 fb = evas_filter_temporary_buffer_get(ctx, w, h, src->alpha_only);
27 if (!fb) return NULL; 22 EINA_SAFETY_ON_NULL_RETURN_VAL(fb, NULL);
28 23
29 dstdata = evas_filter_buffer_backing_get(ctx, fb->id); 24 dstim = evas_filter_buffer_backing_get(ctx, fb->id);
30 if (!dstdata) 25 EINA_SAFETY_ON_NULL_RETURN_VAL(dstim, NULL);
31 { 26 EINA_SAFETY_ON_FALSE_RETURN_VAL((dstim->cache_entry.w == w) &&
32 CRI("No backing found for buffer %d", fb->id); 27 (dstim->cache_entry.h == h), NULL);
33 return NULL;
34 }
35 28
36 if ((dstdata->w != w) || (dstdata->h != h)) 29 memset(&dc, 0, sizeof(dc));
37 { 30 dc.sli.h = 1;
38 CRI("Buffer size mismatch: got %dx%d requested %dx%d", 31 dc.render_op = EVAS_RENDER_COPY;
39 dstdata->w, dstdata->h, w, h);
40 return NULL;
41 }
42 32
43 if (ctx->gl_engine) 33 ok = evas_common_scale_rgba_in_to_out_clip_smooth
44 { 34 (srcim, dstim, &dc, 0, 0, src->w, src->h, 0, 0, w, h);
45 RGBA_Image *s = (RGBA_Image *) srcdata;
46 RGBA_Image *d = (RGBA_Image *) dstdata;
47 EINA_SAFETY_ON_NULL_RETURN_VAL(s->image.data, NULL);
48 EINA_SAFETY_ON_NULL_RETURN_VAL(d->image.data, NULL);
49 35
50 if (src->w == (int) w && src->h == (int) h) 36 if (!ok)
51 memcpy(d->image.data, s->image.data, w * h * 4);
52 else
53 {
54 Eina_Bool ok;
55 RGBA_Draw_Context dc;
56
57 memset(&dc, 0, sizeof(dc));
58 dc.sli.h = 1;
59 dc.render_op = EVAS_RENDER_COPY;
60
61 ok = evas_common_scale_rgba_in_to_out_clip_smooth
62 (s, d, &dc, 0, 0, src->w, src->h, 0, 0, w, h);
63 if (!ok)
64 {
65 ERR("RGBA Image scaling failed.");
66 return NULL;
67 }
68 }
69 }
70 else
71 { 37 {
72 drawctx = ENFN->context_new(ENDT); 38 ERR("RGBA Image scaling failed.");
73 ENFN->context_color_set(ENDT, drawctx, 255, 255, 255, 255); 39 return NULL;
74 ENFN->context_render_op_set(ENDT, drawctx, EVAS_RENDER_COPY);
75 ENFN->image_draw(ENDT, drawctx, dstdata, srcdata,
76 0, 0, src->w, src->h, // src
77 0, 0, w, h, // dst
78 EINA_TRUE, // smooth
79 EINA_FALSE); // Not async
80 ENFN->context_free(ENDT, drawctx);
81 } 40 }
82 41
83 return fb; 42 return fb;
diff --git a/src/lib/evas/include/evas_filter.h b/src/lib/evas/include/evas_filter.h
index f1cbffb31c..bb7a32d287 100644
--- a/src/lib/evas/include/evas_filter.h
+++ b/src/lib/evas/include/evas_filter.h
@@ -143,7 +143,6 @@ void evas_filter_context_post_run_callback_set(Evas_Filter_C
143Eina_Bool evas_filter_context_buffers_allocate_all(Evas_Filter_Context *ctx); 143Eina_Bool evas_filter_context_buffers_allocate_all(Evas_Filter_Context *ctx);
144 144
145int evas_filter_buffer_empty_new(Evas_Filter_Context *ctx, Eina_Bool alpha_only); 145int evas_filter_buffer_empty_new(Evas_Filter_Context *ctx, Eina_Bool alpha_only);
146int evas_filter_buffer_image_new(Evas_Filter_Context *ctx, void *image);
147void *evas_filter_buffer_backing_get(Evas_Filter_Context *ctx, int bufid); 146void *evas_filter_buffer_backing_get(Evas_Filter_Context *ctx, int bufid);
148void *evas_filter_buffer_backing_steal(Evas_Filter_Context *ctx, int bufid); 147void *evas_filter_buffer_backing_steal(Evas_Filter_Context *ctx, int bufid);
149Eina_Bool evas_filter_buffer_backing_release(Evas_Filter_Context *ctx, void *stolen_buffer); 148Eina_Bool evas_filter_buffer_backing_release(Evas_Filter_Context *ctx, void *stolen_buffer);
diff --git a/src/lib/evas/include/evas_private.h b/src/lib/evas/include/evas_private.h
index 854d99d7db..8ca3c2b7f1 100644
--- a/src/lib/evas/include/evas_private.h
+++ b/src/lib/evas/include/evas_private.h
@@ -1450,7 +1450,8 @@ struct _Evas_Func
1450 1450
1451 Ector_Surface *(*ector_create) (void *data); 1451 Ector_Surface *(*ector_create) (void *data);
1452 void (*ector_destroy) (void *data, Ector_Surface *surface); 1452 void (*ector_destroy) (void *data, Ector_Surface *surface);
1453 Ector_Buffer *(*ector_buffer_new) (void *data, Evas *e, void *engine_image); // free it with eo_del 1453 Ector_Buffer *(*ector_buffer_wrap) (void *data, Evas *e, void *engine_image);
1454 Ector_Buffer *(*ector_buffer_new) (void *data, Evas *e, void *pixels, int width, int height, int stride, Efl_Gfx_Colorspace cspace, Eina_Bool writeable, int l, int r, int t, int b, Ector_Buffer_Flag flags);
1454 void (*ector_begin) (void *data, void *context, Ector_Surface *ector, void *surface, void *engine_data, int x, int y, Eina_Bool do_async); 1455 void (*ector_begin) (void *data, void *context, Ector_Surface *ector, void *surface, void *engine_data, int x, int y, Eina_Bool do_async);
1455 void (*ector_renderer_draw) (void *data, void *context, void *surface, void *engine_data, Ector_Renderer *r, Eina_Array *clips, Eina_Bool do_async); 1456 void (*ector_renderer_draw) (void *data, void *context, void *surface, void *engine_data, Ector_Renderer *r, Eina_Array *clips, Eina_Bool do_async);
1456 void (*ector_end) (void *data, void *context, Ector_Surface *ector, void *surface, void *engine_data, Eina_Bool do_async); 1457 void (*ector_end) (void *data, void *context, Ector_Surface *ector, void *surface, void *engine_data, Eina_Bool do_async);
diff --git a/src/modules/evas/engines/gl_generic/evas_engine.c b/src/modules/evas/engines/gl_generic/evas_engine.c
index 0a9e0bcaa6..78a73f41d1 100644
--- a/src/modules/evas/engines/gl_generic/evas_engine.c
+++ b/src/modules/evas/engines/gl_generic/evas_engine.c
@@ -2465,17 +2465,20 @@ eng_ector_destroy(void *data EINA_UNUSED, Ector_Surface *ector)
2465} 2465}
2466 2466
2467static Ector_Buffer * 2467static Ector_Buffer *
2468eng_ector_buffer_new(void *data EINA_UNUSED, Evas *e, void *engine_image) 2468eng_ector_buffer_wrap(void *data EINA_UNUSED, Evas *e, void *engine_image)
2469{ 2469{
2470 Evas_GL_Image *im = engine_image;
2471 Ector_Buffer *buf = NULL;
2472
2473 if (!im) return NULL;
2474
2475#warning FIXME: implement me 2470#warning FIXME: implement me
2476 (void) e; 2471 return NULL;
2472}
2477 2473
2478 return buf; 2474static Ector_Buffer *
2475eng_ector_buffer_new(void *data EINA_UNUSED, Evas *e, void *pixels,
2476 int width, int height, int stride,
2477 Efl_Gfx_Colorspace cspace, Eina_Bool writeable,
2478 int l, int r, int t, int b, Ector_Buffer_Flag flags)
2479{
2480#warning FIXME: implement me
2481 return NULL;
2479} 2482}
2480 2483
2481static Efl_Gfx_Render_Op 2484static Efl_Gfx_Render_Op
@@ -2836,6 +2839,7 @@ module_open(Evas_Module *em)
2836 2839
2837 ORD(ector_create); 2840 ORD(ector_create);
2838 ORD(ector_destroy); 2841 ORD(ector_destroy);
2842 ORD(ector_buffer_wrap);
2839 ORD(ector_buffer_new); 2843 ORD(ector_buffer_new);
2840 ORD(ector_begin); 2844 ORD(ector_begin);
2841 ORD(ector_renderer_draw); 2845 ORD(ector_renderer_draw);
diff --git a/src/modules/evas/engines/software_generic/evas_ector_software_buffer.c b/src/modules/evas/engines/software_generic/evas_ector_software_buffer.c
index 3d45862653..44ebf8fbd3 100644
--- a/src/modules/evas/engines/software_generic/evas_ector_software_buffer.c
+++ b/src/modules/evas/engines/software_generic/evas_ector_software_buffer.c
@@ -49,7 +49,7 @@ _evas_ector_software_buffer_evas_ector_buffer_engine_image_set(Eo *obj, Evas_Ect
49 49
50 eo_do(obj, ector_buffer_pixels_set(im->image.data, 50 eo_do(obj, ector_buffer_pixels_set(im->image.data,
51 im->cache_entry.w, im->cache_entry.h, 0, 51 im->cache_entry.w, im->cache_entry.h, 0,
52 _evas_to_gfx_render_op(im->cache_entry.space), 52 im->cache_entry.space,
53 EINA_TRUE, 0, 0, 0, 0)); 53 EINA_TRUE, 0, 0, 0, 0));
54} 54}
55 55
diff --git a/src/modules/evas/engines/software_generic/evas_engine.c b/src/modules/evas/engines/software_generic/evas_engine.c
index 22967ad14d..a32c7e60c6 100644
--- a/src/modules/evas/engines/software_generic/evas_engine.c
+++ b/src/modules/evas/engines/software_generic/evas_engine.c
@@ -3758,7 +3758,7 @@ eng_ector_destroy(void *data EINA_UNUSED, Ector_Surface *ector)
3758} 3758}
3759 3759
3760static Ector_Buffer * 3760static Ector_Buffer *
3761eng_ector_buffer_new(void *data EINA_UNUSED, Evas *e, void *engine_image) 3761eng_ector_buffer_wrap(void *data EINA_UNUSED, Evas *e, void *engine_image)
3762{ 3762{
3763 Image_Entry *ie = engine_image; 3763 Image_Entry *ie = engine_image;
3764 Ector_Buffer *buf = NULL; 3764 Ector_Buffer *buf = NULL;
@@ -3771,6 +3771,22 @@ eng_ector_buffer_new(void *data EINA_UNUSED, Evas *e, void *engine_image)
3771 return buf; 3771 return buf;
3772} 3772}
3773 3773
3774static Ector_Buffer *
3775eng_ector_buffer_new(void *data EINA_UNUSED, Evas *e, void *pixels,
3776 int width, int height, int stride,
3777 Efl_Gfx_Colorspace cspace, Eina_Bool writeable,
3778 int l, int r, int t, int b,
3779 Ector_Buffer_Flag flags EINA_UNUSED)
3780{
3781 Ector_Buffer *buf = NULL;
3782
3783 buf = eo_add(ECTOR_SOFTWARE_BUFFER_CLASS, e,
3784 ector_buffer_pixels_set(pixels, width, height, stride, cspace,
3785 writeable, l, r, t, b));
3786
3787 return buf;
3788}
3789
3774static Efl_Gfx_Render_Op 3790static Efl_Gfx_Render_Op
3775_evas_render_op_to_ector_rop(Evas_Render_Op op) 3791_evas_render_op_to_ector_rop(Evas_Render_Op op)
3776{ 3792{
@@ -4182,6 +4198,7 @@ static Evas_Func func =
4182 NULL, // eng_texture_image_get 4198 NULL, // eng_texture_image_get
4183 eng_ector_create, 4199 eng_ector_create,
4184 eng_ector_destroy, 4200 eng_ector_destroy,
4201 eng_ector_buffer_wrap,
4185 eng_ector_buffer_new, 4202 eng_ector_buffer_new,
4186 eng_ector_begin, 4203 eng_ector_begin,
4187 eng_ector_renderer_draw, 4204 eng_ector_renderer_draw,