summaryrefslogtreecommitdiff
path: root/src/lib/evas
diff options
context:
space:
mode:
authorJean-Philippe Andre <jp.andre@samsung.com>2017-01-17 16:13:35 +0900
committerJean-Philippe Andre <jp.andre@samsung.com>2017-04-14 11:26:42 +0900
commit0740010a061d15a4ecaa00dc21c10301e0af4847 (patch)
treeecd597c41438ca03a1f85cfb5a09bfbcffe6d094 /src/lib/evas
parentf370ea803b977c245f173bae1b3b904e9bb68e38 (diff)
evas filters: Move blend to software_generic (1/8)
This is an attempt at refactoring the filters code so I can later implement GL support. This patch adds a few extra changes to remove avoid calling functions of libevas from the software engine: use the draw functions from static_libs/draw rather than evas_common APIs.
Diffstat (limited to 'src/lib/evas')
-rw-r--r--src/lib/evas/common/evas_font_compress.c4
-rw-r--r--src/lib/evas/filters/evas_filter.c78
-rw-r--r--src/lib/evas/filters/evas_filter_blend.c460
-rw-r--r--src/lib/evas/filters/evas_filter_mask.c12
-rw-r--r--src/lib/evas/filters/evas_filter_private.h13
-rw-r--r--src/lib/evas/filters/evas_filter_transform.c4
-rw-r--r--src/lib/evas/include/evas_filter.h1
-rw-r--r--src/lib/evas/include/evas_private.h6
8 files changed, 74 insertions, 504 deletions
diff --git a/src/lib/evas/common/evas_font_compress.c b/src/lib/evas/common/evas_font_compress.c
index e923e17251..3a0e90c64f 100644
--- a/src/lib/evas/common/evas_font_compress.c
+++ b/src/lib/evas/common/evas_font_compress.c
@@ -508,8 +508,8 @@ evas_common_font_glyph_draw(RGBA_Font_Glyph *fg,
508 // FIXME: Font draw not optimized for Alpha targets! SLOW! 508 // FIXME: Font draw not optimized for Alpha targets! SLOW!
509 // This is not pretty :) 509 // This is not pretty :)
510 510
511 Alpha_Gfx_Func func;
512 DATA8 *src8, *dst8; 511 DATA8 *src8, *dst8;
512 Draw_Func_Alpha func;
513 int row; 513 int row;
514 514
515 if (EINA_UNLIKELY(x < 0)) 515 if (EINA_UNLIKELY(x < 0))
@@ -534,7 +534,7 @@ evas_common_font_glyph_draw(RGBA_Font_Glyph *fg,
534 { 534 {
535 DATA8 *d = dst8 + ((row - y1) * dst_pitch); 535 DATA8 *d = dst8 + ((row - y1) * dst_pitch);
536 DATA8 *s = src8 + (row * w) + x1; 536 DATA8 *s = src8 + (row * w) + x1;
537 func(s, d, x2 - x1); 537 func(d, s, x2 - x1);
538 } 538 }
539 free(src8); 539 free(src8);
540 } 540 }
diff --git a/src/lib/evas/filters/evas_filter.c b/src/lib/evas/filters/evas_filter.c
index 9438a4e98a..5ff5a7b6ca 100644
--- a/src/lib/evas/filters/evas_filter.c
+++ b/src/lib/evas/filters/evas_filter.c
@@ -61,6 +61,7 @@ evas_filter_context_new(Evas_Public_Data *evas, Eina_Bool async, void *user_data
61 ctx->evas = evas; 61 ctx->evas = evas;
62 ctx->async = async; 62 ctx->async = async;
63 ctx->user_data = user_data; 63 ctx->user_data = user_data;
64 ctx->buffer_scaled_get = &evas_filter_buffer_scaled_get;
64 65
65 return ctx; 66 return ctx;
66} 67}
@@ -1489,8 +1490,19 @@ _filter_name_get(int mode)
1489#endif 1490#endif
1490 1491
1491static Eina_Bool 1492static Eina_Bool
1493_engine_gfx_filter_func(Evas_Filter_Command *cmd)
1494{
1495 // This should be temporary porting code, when moving filter implementations
1496 // from here to the engine. Ideally the filters should be in ector though.
1497
1498 EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->ENFN->gfx_filter_process, EINA_FALSE);
1499 return cmd->ENFN->gfx_filter_process(cmd->ENDT, cmd);
1500}
1501
1502static Eina_Bool
1492_filter_command_run(Evas_Filter_Command *cmd) 1503_filter_command_run(Evas_Filter_Command *cmd)
1493{ 1504{
1505 Evas_Filter_Support support = EVAS_FILTER_SUPPORT_NONE;
1494 Evas_Filter_Apply_Func func = NULL; 1506 Evas_Filter_Apply_Func func = NULL;
1495 1507
1496 EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output, EINA_FALSE); 1508 EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output, EINA_FALSE);
@@ -1515,41 +1527,43 @@ _filter_command_run(Evas_Filter_Command *cmd)
1515 return EINA_FALSE; 1527 return EINA_FALSE;
1516 } 1528 }
1517 1529
1518 //func = cmd->ENFN->filter_command_func_get(cmd); 1530 if (cmd->ENFN->gfx_filter_supports)
1519 // FIXME: Must call engine function, not CPU directly. 1531 support = cmd->ENFN->gfx_filter_supports(cmd->ENDT, cmd);
1520 1532
1521 switch (cmd->mode) 1533 if (support != EVAS_FILTER_SUPPORT_NONE)
1522 { 1534 {
1523 case EVAS_FILTER_MODE_BLEND: 1535 func = &_engine_gfx_filter_func;
1524 func = evas_filter_blend_cpu_func_get(cmd); 1536 }
1525 break; 1537 else
1526 case EVAS_FILTER_MODE_BLUR: 1538 {
1527 func = evas_filter_blur_cpu_func_get(cmd); 1539 switch (cmd->mode)
1528 break; 1540 {
1529 case EVAS_FILTER_MODE_CURVE: 1541 case EVAS_FILTER_MODE_BLUR:
1530 func = evas_filter_curve_cpu_func_get(cmd); 1542 func = evas_filter_blur_cpu_func_get(cmd);
1531 break; 1543 break;
1532 case EVAS_FILTER_MODE_DISPLACE: 1544 case EVAS_FILTER_MODE_CURVE:
1533 func = evas_filter_displace_cpu_func_get(cmd); 1545 func = evas_filter_curve_cpu_func_get(cmd);
1534 break; 1546 break;
1535 case EVAS_FILTER_MODE_FILL: 1547 case EVAS_FILTER_MODE_DISPLACE:
1536 func = evas_filter_fill_cpu_func_get(cmd); 1548 func = evas_filter_displace_cpu_func_get(cmd);
1537 break; 1549 break;
1538 case EVAS_FILTER_MODE_MASK: 1550 case EVAS_FILTER_MODE_FILL:
1539 func = evas_filter_mask_cpu_func_get(cmd); 1551 func = evas_filter_fill_cpu_func_get(cmd);
1540 break; 1552 break;
1541 case EVAS_FILTER_MODE_BUMP: 1553 case EVAS_FILTER_MODE_MASK:
1542 func = evas_filter_bump_map_cpu_func_get(cmd); 1554 func = evas_filter_mask_cpu_func_get(cmd);
1543 break; 1555 break;
1544 case EVAS_FILTER_MODE_TRANSFORM: 1556 case EVAS_FILTER_MODE_BUMP:
1545 func = evas_filter_transform_cpu_func_get(cmd); 1557 func = evas_filter_bump_map_cpu_func_get(cmd);
1546 break; 1558 break;
1547 default: 1559 case EVAS_FILTER_MODE_TRANSFORM:
1548 CRI("Invalid filter mode."); 1560 func = evas_filter_transform_cpu_func_get(cmd);
1549 break; 1561 break;
1562 default:
1563 CRI("Invalid filter mode.");
1564 break;
1565 }
1550 } 1566 }
1551
1552 // END OF FIXME
1553 1567
1554 if (!func) 1568 if (!func)
1555 { 1569 {
diff --git a/src/lib/evas/filters/evas_filter_blend.c b/src/lib/evas/filters/evas_filter_blend.c
deleted file mode 100644
index a8191e693d..0000000000
--- a/src/lib/evas/filters/evas_filter_blend.c
+++ /dev/null
@@ -1,460 +0,0 @@
1#include "evas_filter.h"
2#include "evas_filter_private.h"
3#include "evas_blend_private.h"
4#include "ector_buffer.h"
5#include "draw.h"
6
7// FIXME: This should all be based on ector renderer
8
9// Use a better formula than R+G+B for rgba to alpha conversion (RGB to YCbCr)
10#define RGBA2ALPHA_WEIGHTED 1
11
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);
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);
14
15struct Filter_Blend_Draw_Context
16{
17 Efl_Gfx_Render_Op rop;
18 uint32_t color;
19};
20
21#define LINELEN(stride, ptr) (stride / (sizeof(*ptr)))
22
23static Eina_Bool
24_image_draw_cpu_alpha_alpha(void *data EINA_UNUSED, void *context,
25 const void *src_map, unsigned int src_stride,
26 void *dst_map, unsigned int dst_stride,
27 int src_x, int src_y, int src_w, int src_h,
28 int dst_x, int dst_y, int dst_w, int dst_h,
29 int smooth EINA_UNUSED,
30 Eina_Bool do_async EINA_UNUSED)
31{
32 struct Filter_Blend_Draw_Context *dc = context;
33 const uint8_t *srcdata = src_map;
34 uint8_t *dstdata = dst_map;
35 Alpha_Gfx_Func func;
36 int y, sw, dw;
37
38 EINA_SAFETY_ON_FALSE_RETURN_VAL((src_w == dst_w) && (src_h == dst_h), EINA_FALSE);
39
40 func = efl_draw_alpha_func_get(dc->rop, EINA_FALSE);
41 EINA_SAFETY_ON_NULL_RETURN_VAL(func, EINA_FALSE);
42
43 sw = LINELEN(src_stride, srcdata);
44 dw = LINELEN(dst_stride, dstdata);
45
46 srcdata += src_y * sw;
47 dstdata += dst_y * dw;
48 for (y = src_h; y; y--)
49 {
50 func((uint8_t *) srcdata + src_x, dstdata + dst_x, src_w);
51 srcdata += sw;
52 dstdata += dw;
53 }
54
55 return EINA_TRUE;
56}
57
58static Eina_Bool
59_image_draw_cpu_alpha_rgba(void *data EINA_UNUSED, void *context,
60 const void *src_map, unsigned int src_stride,
61 void *dst_map, unsigned int dst_stride,
62 int src_x, int src_y, int src_w, int src_h,
63 int dst_x, int dst_y, int dst_w, int dst_h,
64 int smooth EINA_UNUSED,
65 Eina_Bool do_async EINA_UNUSED)
66{
67 struct Filter_Blend_Draw_Context *dc = context;
68 uint8_t *srcdata = (uint8_t *) src_map;
69 uint32_t *dstdata = dst_map;
70 RGBA_Gfx_Func func;
71 int y, sw, dw;
72
73 EINA_SAFETY_ON_FALSE_RETURN_VAL((src_w == dst_w) && (src_h == dst_h), EINA_FALSE);
74
75 func = evas_common_gfx_func_composite_mask_color_span_get(dc->color, 1, 1, _gfx_to_evas_render_op(dc->rop));
76 EINA_SAFETY_ON_NULL_RETURN_VAL(func, EINA_FALSE);
77
78 sw = LINELEN(src_stride, srcdata);
79 dw = LINELEN(dst_stride, dstdata);
80
81 srcdata += src_y * sw;
82 dstdata += dst_y * dw;
83 for (y = src_h; y; y--)
84 {
85 func(NULL, srcdata + src_x, dc->color, dstdata + dst_x, src_w);
86 srcdata += sw;
87 dstdata += dw;
88 }
89
90 return EINA_TRUE;
91}
92
93static Eina_Bool
94_image_draw_cpu_rgba_rgba(void *data EINA_UNUSED, void *context,
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)
101{
102 struct Filter_Blend_Draw_Context *dc = context;
103 uint32_t *srcdata = (uint32_t *) src_map;
104 uint32_t *dstdata = dst_map;
105 RGBA_Gfx_Func func;
106 int y, sw, dw;
107
108 EINA_SAFETY_ON_FALSE_RETURN_VAL((src_w == dst_w) && (src_h == dst_h), EINA_FALSE);
109
110 if (!dc->color)
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);
117
118 sw = LINELEN(src_stride, srcdata);
119 dw = LINELEN(dst_stride, dstdata);
120
121 srcdata += src_y * sw;
122 dstdata += dst_y * dw;
123 for (y = src_h; y; y--)
124 {
125 func(srcdata + src_x, NULL, dc->color, dstdata + dst_x, src_w);
126 srcdata += sw;
127 dstdata += dw;
128 }
129
130 return EINA_TRUE;
131}
132
133static Eina_Bool
134_image_draw_cpu_rgba_alpha(void *data EINA_UNUSED, void *context EINA_UNUSED,
135 const void *src_map, unsigned int src_stride,
136 void *dst_map, unsigned int dst_stride,
137 int src_x, int src_y, int src_w, int src_h,
138 int dst_x, int dst_y, int dst_w, int dst_h,
139 int smooth EINA_UNUSED,
140 Eina_Bool do_async EINA_UNUSED)
141{
142 uint32_t *srcdata = (uint32_t *) src_map;
143 uint8_t *dstdata = dst_map;
144 int x, y, sw, dw;
145#if RGBA2ALPHA_WEIGHTED
146 const int WR = 299;
147 const int WG = 587;
148 const int WB = 114;
149#else
150 const int WR = 1;
151 const int WG = 1;
152 const int WB = 1;
153#endif
154 DEFINE_DIVIDER(WR + WG + WB);
155
156 EINA_SAFETY_ON_FALSE_RETURN_VAL((src_w == dst_w) && (src_h == dst_h), EINA_FALSE);
157
158 sw = LINELEN(src_stride, srcdata);
159 dw = LINELEN(dst_stride, dstdata);
160
161 srcdata += src_y * sw;
162 dstdata += dst_y * dw;
163 for (y = src_h; y; y--)
164 {
165 uint32_t *s = srcdata + src_x;
166 uint8_t *d = dstdata + dst_x;
167 for (x = src_w; x; x--, d++, s++)
168 *d = DIVIDE((R_VAL(s) * WR) + (G_VAL(s) * WG) + (B_VAL(s) * WB));
169 srcdata += sw;
170 dstdata += dw;
171 }
172
173 return EINA_TRUE;
174}
175
176static Eina_Bool
177_filter_blend_cpu_generic_do(Evas_Filter_Command *cmd, draw_func image_draw)
178{
179 unsigned int src_len, src_stride, dst_len, dst_stride;
180 int sw, sh, dx, dy, dw, dh, sx, sy;
181 struct Filter_Blend_Draw_Context dc;
182 Eina_Bool ret = EINA_FALSE;
183 Evas_Filter_Buffer *src_fb;
184 void *src = NULL, *dst = NULL;
185
186 sx = 0;
187 sy = 0;
188 ector_buffer_size_get(cmd->input->buffer, &sw, &sh);
189
190 dx = cmd->draw.ox;
191 dy = cmd->draw.oy;
192 ector_buffer_size_get(cmd->output->buffer, &dw, &dh);
193
194 if ((dw <= 0) || (dh <= 0) || (sw <= 0) || (sh <= 0))
195 return EINA_TRUE;
196
197 // Stretch if necessary.
198
199 /* NOTE: As of 2014/03/11, this will happen only with RGBA buffers, since
200 * only proxy sources may be scaled. So, we don't need an alpha scaling
201 * algorithm just now.
202 */
203
204 if ((sw != dw || sh != dh) && (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_XY))
205 {
206
207 if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_X)
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;
218 }
219 else src_fb = cmd->input;
220
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 EINA_SAFETY_ON_FALSE_GOTO(src && dst, end);
224
225 dc.rop = cmd->draw.rop;
226 dc.color = ARGB_JOIN(cmd->draw.A, cmd->draw.R, cmd->draw.G, cmd->draw.B);
227
228 ret = _mapped_blend(cmd->ENDT, &dc, src, src_stride, dst, dst_stride, cmd->draw.fillmode,
229 sx, sy, sw, sh, dx, dy, dw, dh, image_draw);
230
231end:
232 if (src) ector_buffer_unmap(src_fb->buffer, src, src_len);
233 if (dst) ector_buffer_unmap(cmd->output->buffer, dst, dst_len);
234 return ret;
235}
236
237static Eina_Bool
238_filter_blend_cpu_alpha(Evas_Filter_Command *cmd)
239{
240 return _filter_blend_cpu_generic_do(cmd, _image_draw_cpu_alpha_alpha);
241}
242
243static Eina_Bool
244_filter_blend_cpu_alpha_rgba(Evas_Filter_Command *cmd)
245{
246 return _filter_blend_cpu_generic_do(cmd, _image_draw_cpu_alpha_rgba);
247}
248
249static Eina_Bool
250_filter_blend_cpu_rgba_alpha(Evas_Filter_Command *cmd)
251{
252 return _filter_blend_cpu_generic_do(cmd, _image_draw_cpu_rgba_alpha);
253}
254
255static Eina_Bool
256_filter_blend_cpu_rgba(Evas_Filter_Command *cmd)
257{
258 return _filter_blend_cpu_generic_do(cmd, _image_draw_cpu_rgba_rgba);
259}
260
261static Eina_Bool
262_mapped_blend(void *data, void *drawctx,
263 const void *src_map, unsigned int src_stride,
264 void *dst_map, unsigned int dst_stride,
265 Evas_Filter_Fill_Mode fillmode,
266 int sx, int sy,
267 int sw, int sh,
268 int dx, int dy,
269 int dw, int dh,
270 draw_func image_draw)
271{
272 int right = 0, bottom = 0, left = 0, top = 0;
273 int row, col, rows, cols;
274 Eina_Bool ret = EINA_TRUE;
275 Eina_Bool debug = eina_log_domain_level_check(_evas_filter_log_dom, 6);
276
277 EINA_SAFETY_ON_FALSE_RETURN_VAL((sx == 0) && (sy == 0), EINA_FALSE);
278
279 if (fillmode == EVAS_FILTER_FILL_MODE_NONE)
280 {
281 _clip_to_target(&sx, &sy, sw, sh, dx, dy, dw, dh, &dx, &dy, &rows, &cols);
282 if (debug)
283 {
284 XDBG("blend: %d,%d,%d,%d --> %d,%d,%d,%d (from %dx%d to %dx%d +%d,%d)",
285 0, 0, sw, sh, dx, dy, cols, rows, sw, sh, dw, dh, dx, dy);
286 }
287 image_draw(data, drawctx,
288 src_map, src_stride, dst_map, dst_stride,
289 sx, sy, cols, rows, // src
290 dx, dy, cols, rows, // dst
291 EINA_TRUE, // smooth
292 EINA_FALSE); // Not async
293 return EINA_TRUE;
294 }
295
296 if (fillmode & EVAS_FILTER_FILL_MODE_REPEAT_X)
297 {
298 if (dx > 0) left = dx % sw;
299 else if (dx < 0) left = sw + (dx % sw);
300 cols = (dw /*- left*/) / sw;
301 if (left > 0)
302 right = dw - (sw * (cols - 1)) - left;
303 else
304 right = dw - (sw * cols);
305 dx = 0;
306 }
307 else if (fillmode & EVAS_FILTER_FILL_MODE_STRETCH_X)
308 {
309 cols = 0;
310 dx = 0;
311 }
312 else
313 {
314 // FIXME: Probably wrong if dx != 0
315 cols = 0;
316 dw -= dx;
317 }
318
319 if (fillmode & EVAS_FILTER_FILL_MODE_REPEAT_Y)
320 {
321 if (dy > 0) top = dy % sh;
322 else if (dy < 0) top = sh + (dy % sh);
323 rows = (dh /*- top*/) / sh;
324 if (top > 0)
325 bottom = dh - (sh * (rows - 1)) - top;
326 else
327 bottom = dh - (sh * rows);
328 dy = 0;
329 }
330 else if (fillmode & EVAS_FILTER_FILL_MODE_STRETCH_Y)
331 {
332 rows = 0;
333 dy = 0;
334 }
335 else
336 {
337 // FIXME: Probably wrong if dy != 0
338 rows = 0;
339 dh -= dy;
340 }
341
342 if (top > 0) row = -1;
343 else row = 0;
344 for (; row <= rows; row++)
345 {
346 int src_x, src_y, src_w, src_h;
347 int dst_x, dst_y, dst_w, dst_h;
348
349 if (row == -1 && top > 0)
350 {
351 // repeat only
352 src_h = top;
353 src_y = sh - top;
354 dst_y = dy;
355 dst_h = src_h;
356 }
357 else if (row == rows && bottom > 0)
358 {
359 // repeat only
360 src_h = bottom;
361 src_y = 0;
362 dst_y = top + dy + row * sh;
363 dst_h = src_h;
364 }
365 else
366 {
367 src_y = 0;
368 if (fillmode & EVAS_FILTER_FILL_MODE_STRETCH_Y)
369 {
370 src_h = sh;
371 dst_h = dh;
372 dst_y = 0;
373 }
374 else
375 {
376 dst_y = top + dy + row * sh;
377 src_h = MIN(dh - dst_y, sh);
378 dst_h = src_h;
379 }
380 }
381 if (src_h <= 0 || dst_h <= 0) break;
382
383 if (left > 0) col = -1;
384 else col = 0;
385 for (; col <= cols; col++)
386 {
387 if (col == -1 && left > 0)
388 {
389 // repeat only
390 src_w = left;
391 src_x = sw - left;
392 dst_x = dx;
393 dst_w = src_w;
394 }
395 else if (col == cols && right > 0)
396 {
397 // repeat only
398 src_w = right;
399 src_x = 0;
400 dst_x = left + dx + col * sw;
401 dst_w = src_w;
402 }
403 else
404 {
405 src_x = 0;
406 if (fillmode & EVAS_FILTER_FILL_MODE_STRETCH_X)
407 {
408 src_w = sw;
409 dst_w = dw;
410 dst_x = 0;
411 }
412 else
413 {
414 dst_x = left + dx + col * sw;
415 src_w = MIN(dw - dst_x, sw);
416 dst_w = src_w;
417 }
418 }
419 if (src_w <= 0 || dst_w <= 0) break;
420
421 if (debug)
422 {
423 XDBG("blend: [%d,%d] %d,%d,%dx%d --> %d,%d,%dx%d "
424 "(src %dx%d, dst %dx%d)",
425 col, row, src_x, src_y, src_w, src_h,
426 dst_x, dst_y, dst_w, dst_h,
427 sw, sh, dw, dh);
428 }
429 image_draw(data, drawctx,
430 src_map, src_stride, dst_map, dst_stride,
431 src_x, src_y, src_w, src_h,
432 dst_x, dst_y, dst_w, dst_h,
433 EINA_TRUE, EINA_FALSE);
434 }
435 }
436 return ret;
437}
438
439Evas_Filter_Apply_Func
440evas_filter_blend_cpu_func_get(Evas_Filter_Command *cmd)
441{
442 EINA_SAFETY_ON_NULL_RETURN_VAL(cmd, NULL);
443 EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output, NULL);
444 EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input, NULL);
445
446 if (cmd->input->alpha_only)
447 {
448 if (cmd->output->alpha_only)
449 return _filter_blend_cpu_alpha;
450 else
451 return _filter_blend_cpu_alpha_rgba;
452 }
453 else
454 {
455 if (cmd->output->alpha_only)
456 return _filter_blend_cpu_rgba_alpha;
457 else
458 return _filter_blend_cpu_rgba;
459 }
460}
diff --git a/src/lib/evas/filters/evas_filter_mask.c b/src/lib/evas/filters/evas_filter_mask.c
index c13493cbf2..230cb3269c 100644
--- a/src/lib/evas/filters/evas_filter_mask.c
+++ b/src/lib/evas/filters/evas_filter_mask.c
@@ -67,7 +67,7 @@ _mask_cpu_alpha_alpha_alpha(Evas_Filter_Command *cmd)
67 unsigned int src_len = 0, src_stride, msk_len = 0, msk_stride, dst_len = 0, dst_stride; 67 unsigned int src_len = 0, src_stride, msk_len = 0, msk_stride, dst_len = 0, dst_stride;
68 Efl_Gfx_Render_Op render_op = cmd->draw.rop; 68 Efl_Gfx_Render_Op render_op = cmd->draw.rop;
69 Evas_Filter_Buffer *msk_fb; 69 Evas_Filter_Buffer *msk_fb;
70 Alpha_Gfx_Func func; 70 Draw_Func_Alpha func;
71 uint8_t *src_map = NULL, *dst, *dst_map = NULL, *msk, *msk_map = NULL; 71 uint8_t *src_map = NULL, *dst, *dst_map = NULL, *msk, *msk_map = NULL;
72 int w, h, mw, mh, x, y, my; 72 int w, h, mw, mh, x, y, my;
73 int stepsize, stepcount, step; 73 int stepsize, stepcount, step;
@@ -134,12 +134,12 @@ _mask_cpu_alpha_alpha_alpha(Evas_Filter_Command *cmd)
134 dst = dst_map + (y * dst_stride); 134 dst = dst_map + (y * dst_stride);
135 135
136 for (step = 0; step < stepcount; step++, dst += stepsize) 136 for (step = 0; step < stepcount; step++, dst += stepsize)
137 func(msk, dst, stepsize); 137 func(dst, msk, stepsize);
138 138
139 x = stepsize * stepcount; 139 x = stepsize * stepcount;
140 if (x < w) 140 if (x < w)
141 { 141 {
142 func(msk, dst, w - x); 142 func(dst, msk, w - x);
143 } 143 }
144 } 144 }
145 145
@@ -274,7 +274,7 @@ _mask_cpu_alpha_alpha_rgba(Evas_Filter_Command *cmd)
274 uint8_t *src, *msk, *span, *src_map = NULL, *msk_map = NULL, *dst_map = NULL; 274 uint8_t *src, *msk, *span, *src_map = NULL, *msk_map = NULL, *dst_map = NULL;
275 Evas_Filter_Buffer *msk_fb; 275 Evas_Filter_Buffer *msk_fb;
276 RGBA_Gfx_Func func; 276 RGBA_Gfx_Func func;
277 Alpha_Gfx_Func span_func; 277 Draw_Func_Alpha span_func;
278 uint32_t *dst; 278 uint32_t *dst;
279 uint32_t color; 279 uint32_t color;
280 Efl_Gfx_Render_Op op = cmd->draw.rop; 280 Efl_Gfx_Render_Op op = cmd->draw.rop;
@@ -335,7 +335,7 @@ _mask_cpu_alpha_alpha_rgba(Evas_Filter_Command *cmd)
335 for (step = 0; step < stepcount; step++, dst += stepsize, src += stepsize) 335 for (step = 0; step < stepcount; step++, dst += stepsize, src += stepsize)
336 { 336 {
337 memcpy(span, msk, stepsize * sizeof(uint8_t)); 337 memcpy(span, msk, stepsize * sizeof(uint8_t));
338 span_func(src, span, stepsize); 338 span_func(span, src, stepsize);
339 func(NULL, span, color, dst, stepsize); 339 func(NULL, span, color, dst, stepsize);
340 } 340 }
341 341
@@ -343,7 +343,7 @@ _mask_cpu_alpha_alpha_rgba(Evas_Filter_Command *cmd)
343 if (x < w) 343 if (x < w)
344 { 344 {
345 memcpy(span, msk, (w - x) * sizeof(uint8_t)); 345 memcpy(span, msk, (w - x) * sizeof(uint8_t));
346 span_func(src, span, w - x); 346 span_func(span, src, w - x);
347 func(NULL, span, color, dst, w -x); 347 func(NULL, span, color, dst, w -x);
348 } 348 }
349 } 349 }
diff --git a/src/lib/evas/filters/evas_filter_private.h b/src/lib/evas/filters/evas_filter_private.h
index c9be59e3a6..f659daa5eb 100644
--- a/src/lib/evas/filters/evas_filter_private.h
+++ b/src/lib/evas/filters/evas_filter_private.h
@@ -109,6 +109,8 @@ extern int _evas_filter_log_dom;
109 109
110typedef enum _Evas_Filter_Interpolation_Mode Evas_Filter_Interpolation_Mode; 110typedef enum _Evas_Filter_Interpolation_Mode Evas_Filter_Interpolation_Mode;
111 111
112typedef Evas_Filter_Buffer * (*evas_filter_buffer_scaled_get_func)(Evas_Filter_Context *ctx, Evas_Filter_Buffer *src, unsigned w, unsigned h);
113
112struct _Evas_Filter_Context 114struct _Evas_Filter_Context
113{ 115{
114 Evas_Public_Data *evas; 116 Evas_Public_Data *evas;
@@ -118,6 +120,9 @@ struct _Evas_Filter_Context
118 int last_command_id; 120 int last_command_id;
119 void *user_data; // used by textblock 121 void *user_data; // used by textblock
120 122
123 // ugly hack (dlsym fail)
124 evas_filter_buffer_scaled_get_func buffer_scaled_get;
125
121 // Variables changing at each run 126 // Variables changing at each run
122 int w, h; // Dimensions of the input/output buffers 127 int w, h; // Dimensions of the input/output buffers
123 int padl, padt, padr, padb; // Padding in the current input/output buffers 128 int padl, padt, padr, padb; // Padding in the current input/output buffers
@@ -245,11 +250,17 @@ enum _Evas_Filter_Interpolation_Mode
245 EVAS_FILTER_INTERPOLATION_MODE_LINEAR 250 EVAS_FILTER_INTERPOLATION_MODE_LINEAR
246}; 251};
247 252
253enum _Evas_Filter_Support
254{
255 EVAS_FILTER_SUPPORT_NONE = 0,
256 EVAS_FILTER_SUPPORT_CPU,
257 EVAS_FILTER_SUPPORT_GL
258};
259
248void evas_filter_context_clear(Evas_Filter_Context *ctx); 260void evas_filter_context_clear(Evas_Filter_Context *ctx);
249void evas_filter_context_source_set(Evas_Filter_Context *ctx, Evas_Object *eo_proxy, Evas_Object *eo_source, int bufid, Eina_Stringshare *name); 261void evas_filter_context_source_set(Evas_Filter_Context *ctx, Evas_Object *eo_proxy, Evas_Object *eo_source, int bufid, Eina_Stringshare *name);
250 262
251/* FIXME: CPU filters entry points. Move these to the Evas Engine itself. */ 263/* FIXME: CPU filters entry points. Move these to the Evas Engine itself. */
252Evas_Filter_Apply_Func evas_filter_blend_cpu_func_get(Evas_Filter_Command *cmd);
253Evas_Filter_Apply_Func evas_filter_blur_cpu_func_get(Evas_Filter_Command *cmd); 264Evas_Filter_Apply_Func evas_filter_blur_cpu_func_get(Evas_Filter_Command *cmd);
254Evas_Filter_Apply_Func evas_filter_bump_map_cpu_func_get(Evas_Filter_Command *cmd); 265Evas_Filter_Apply_Func evas_filter_bump_map_cpu_func_get(Evas_Filter_Command *cmd);
255Evas_Filter_Apply_Func evas_filter_curve_cpu_func_get(Evas_Filter_Command *cmd); 266Evas_Filter_Apply_Func evas_filter_curve_cpu_func_get(Evas_Filter_Command *cmd);
diff --git a/src/lib/evas/filters/evas_filter_transform.c b/src/lib/evas/filters/evas_filter_transform.c
index 0cc3b2d966..db90147970 100644
--- a/src/lib/evas/filters/evas_filter_transform.c
+++ b/src/lib/evas/filters/evas_filter_transform.c
@@ -72,7 +72,7 @@ _vflip_cpu(Evas_Filter_Command *cmd)
72 else if (cspace == E_ALPHA) 72 else if (cspace == E_ALPHA)
73 { 73 {
74 /* blend onto a target (alpha -> alpha) */ 74 /* blend onto a target (alpha -> alpha) */
75 Alpha_Gfx_Func func = efl_draw_alpha_func_get(cmd->draw.rop, EINA_FALSE); 75 Draw_Func_Alpha func = efl_draw_alpha_func_get(cmd->draw.rop, EINA_FALSE);
76 EINA_SAFETY_ON_NULL_GOTO(func, end); 76 EINA_SAFETY_ON_NULL_GOTO(func, end);
77 77
78 for (sy = s0, dy = d0; (dy >= d1) && (sy <= s1); sy++, dy--) 78 for (sy = s0, dy = d0; (dy >= d1) && (sy <= s1); sy++, dy--)
@@ -80,7 +80,7 @@ _vflip_cpu(Evas_Filter_Command *cmd)
80 uint8_t* src = in + src_stride * sy; 80 uint8_t* src = in + src_stride * sy;
81 uint8_t* dst = out + dst_stride * dy; 81 uint8_t* dst = out + dst_stride * dy;
82 82
83 func(src, dst, w); 83 func(dst, src, w);
84 } 84 }
85 } 85 }
86 else 86 else
diff --git a/src/lib/evas/include/evas_filter.h b/src/lib/evas/include/evas_filter.h
index c8962c434d..0c87af23f4 100644
--- a/src/lib/evas/include/evas_filter.h
+++ b/src/lib/evas/include/evas_filter.h
@@ -33,7 +33,6 @@
33#endif /* ! _WIN32 */ 33#endif /* ! _WIN32 */
34 34
35typedef struct _Evas_Filter_Context Evas_Filter_Context; 35typedef struct _Evas_Filter_Context Evas_Filter_Context;
36typedef struct _Evas_Filter_Command Evas_Filter_Command;
37typedef struct _Evas_Filter_Instruction Evas_Filter_Instruction; 36typedef struct _Evas_Filter_Instruction Evas_Filter_Instruction;
38typedef struct _Evas_Filter_Buffer Evas_Filter_Buffer; 37typedef struct _Evas_Filter_Buffer Evas_Filter_Buffer;
39typedef struct _Evas_Filter_Proxy_Binding Evas_Filter_Proxy_Binding; 38typedef struct _Evas_Filter_Proxy_Binding Evas_Filter_Proxy_Binding;
diff --git a/src/lib/evas/include/evas_private.h b/src/lib/evas/include/evas_private.h
index 4491af676a..4d6f608ac8 100644
--- a/src/lib/evas/include/evas_private.h
+++ b/src/lib/evas/include/evas_private.h
@@ -91,10 +91,13 @@ typedef struct _Evas_Smart_Data Evas_Smart_Data;
91typedef struct _Evas_Object_Protected_State Evas_Object_Protected_State; 91typedef struct _Evas_Object_Protected_State Evas_Object_Protected_State;
92typedef struct _Evas_Object_Protected_Data Evas_Object_Protected_Data; 92typedef struct _Evas_Object_Protected_Data Evas_Object_Protected_Data;
93 93
94/* gfx filters typedef only */
94typedef struct _Evas_Filter_Program Evas_Filter_Program; 95typedef struct _Evas_Filter_Program Evas_Filter_Program;
95typedef struct _Evas_Object_Filter_Data Evas_Object_Filter_Data; 96typedef struct _Evas_Object_Filter_Data Evas_Object_Filter_Data;
96typedef struct _Evas_Filter_Data_Binding Evas_Filter_Data_Binding; 97typedef struct _Evas_Filter_Data_Binding Evas_Filter_Data_Binding;
97typedef struct _Evas_Pointer_Data Evas_Pointer_Data; 98typedef struct _Evas_Pointer_Data Evas_Pointer_Data;
99typedef struct _Evas_Filter_Command Evas_Filter_Command;
100typedef enum _Evas_Filter_Support Evas_Filter_Support;
98 101
99// 3D stuff 102// 3D stuff
100 103
@@ -1576,6 +1579,9 @@ struct _Evas_Func
1576 void (*ector_end) (void *data, void *context, Ector_Surface *ector, void *surface, void *engine_data, Eina_Bool do_async); 1579 void (*ector_end) (void *data, void *context, Ector_Surface *ector, void *surface, void *engine_data, Eina_Bool do_async);
1577 void* (*ector_new) (void *data, void *context, Ector_Surface *ector, void *surface); 1580 void* (*ector_new) (void *data, void *context, Ector_Surface *ector, void *surface);
1578 void (*ector_free) (void *engine_data); 1581 void (*ector_free) (void *engine_data);
1582
1583 Evas_Filter_Support (*gfx_filter_supports) (void *data, Evas_Filter_Command *cmd);
1584 Eina_Bool (*gfx_filter_process) (void *data, Evas_Filter_Command *cmd);
1579}; 1585};
1580 1586
1581struct _Evas_Image_Save_Func 1587struct _Evas_Image_Save_Func