summaryrefslogtreecommitdiff
path: root/src/modules/evas/engines/software_generic/filters
diff options
context:
space:
mode:
authorJean-Philippe Andre <jp.andre@samsung.com>2017-01-17 21:09:18 +0900
committerJean-Philippe Andre <jp.andre@samsung.com>2017-04-14 11:26:42 +0900
commit46542ea74884675fcdae77a05b88e3d1cfa62e86 (patch)
tree6584ec7822c516067f8b8d140ed79079e9f9b53a /src/modules/evas/engines/software_generic/filters
parent1b95d22c2c48f5ba23268dd917fa75524102ef7a (diff)
evas filters: Move transform to software generic (7/8)
Diffstat (limited to 'src/modules/evas/engines/software_generic/filters')
-rw-r--r--src/modules/evas/engines/software_generic/filters/evas_engine_filter.h1
-rw-r--r--src/modules/evas/engines/software_generic/filters/evas_filter_transform.c132
2 files changed, 133 insertions, 0 deletions
diff --git a/src/modules/evas/engines/software_generic/filters/evas_engine_filter.h b/src/modules/evas/engines/software_generic/filters/evas_engine_filter.h
index 31a326cc50..2ae3618d4f 100644
--- a/src/modules/evas/engines/software_generic/filters/evas_engine_filter.h
+++ b/src/modules/evas/engines/software_generic/filters/evas_engine_filter.h
@@ -10,5 +10,6 @@ Evas_Filter_Apply_Func eng_filter_curve_func_get(Evas_Filter_Command *cmd);
10Evas_Filter_Apply_Func eng_filter_displace_func_get(Evas_Filter_Command *cmd); 10Evas_Filter_Apply_Func eng_filter_displace_func_get(Evas_Filter_Command *cmd);
11Evas_Filter_Apply_Func eng_filter_fill_func_get(Evas_Filter_Command *cmd); 11Evas_Filter_Apply_Func eng_filter_fill_func_get(Evas_Filter_Command *cmd);
12Evas_Filter_Apply_Func eng_filter_mask_func_get(Evas_Filter_Command *cmd); 12Evas_Filter_Apply_Func eng_filter_mask_func_get(Evas_Filter_Command *cmd);
13Evas_Filter_Apply_Func eng_filter_transform_func_get(Evas_Filter_Command *cmd);
13 14
14#endif // EVAS_ENGINE_FILTER_H 15#endif // EVAS_ENGINE_FILTER_H
diff --git a/src/modules/evas/engines/software_generic/filters/evas_filter_transform.c b/src/modules/evas/engines/software_generic/filters/evas_filter_transform.c
new file mode 100644
index 0000000000..31354e8560
--- /dev/null
+++ b/src/modules/evas/engines/software_generic/filters/evas_filter_transform.c
@@ -0,0 +1,132 @@
1#include "evas_engine_filter.h"
2
3/* Apply geometrical transformations to a buffer.
4 *
5 * This filter is a very simplistic at the moment, future improvements require
6 * more options to the API.
7 */
8
9static Eina_Bool
10_vflip_cpu(Evas_Filter_Command *cmd)
11{
12 unsigned int src_len, src_stride, dst_len, dst_stride;
13 uint8_t *in, *out = NULL;
14 int w, h, sy, dy, oy, center, t, b, objh;
15 Efl_Gfx_Colorspace cspace = cmd->output->alpha_only ? E_ALPHA : E_ARGB;
16 int s0, s1, d0, d1;
17 Eina_Bool ret = 0;
18
19 if (!cmd->draw.A && (cmd->draw.rop == EFL_GFX_RENDER_OP_BLEND))
20 return EINA_TRUE;
21
22 w = cmd->input->w;
23 h = cmd->input->h;
24 in = _buffer_map_all(cmd->input->buffer, &src_len, E_READ, cspace, &src_stride);
25 out = _buffer_map_all(cmd->output->buffer, &dst_len,
26 E_WRITE | ECTOR_BUFFER_ACCESS_FLAG_COW,
27 cspace, &dst_stride);
28
29 EINA_SAFETY_ON_FALSE_GOTO(cmd->output->w == w, end);
30 EINA_SAFETY_ON_FALSE_GOTO(cmd->output->h == h, end);
31 EINA_SAFETY_ON_FALSE_GOTO(src_stride <= dst_stride, end);
32 EINA_SAFETY_ON_NULL_GOTO(in, end);
33 EINA_SAFETY_ON_NULL_GOTO(out, end);
34 EINA_SAFETY_ON_FALSE_GOTO(in != out, end);
35
36 oy = cmd->draw.oy;
37 t = cmd->ctx->padt;
38 b = cmd->ctx->padb;
39 objh = h - t - b;
40 center = t + objh / 2 + oy;
41
42 if (oy >= 0)
43 {
44 s1 = d0 = center + (objh / 2) + oy;
45 s0 = d1 = center - (objh / 2) - oy;
46 }
47 else
48 {
49 s1 = d0 = center + (objh / 2) - oy;
50 s0 = d1 = center - (objh / 2) + oy;
51 }
52
53 /* avoid crashes */
54 d0 = CLAMP(0, d0, h - 1);
55 d1 = CLAMP(0, d1, h - 1);
56 s0 = CLAMP(0, s0, h - 1);
57 s1 = CLAMP(0, s1, h - 1);
58
59 if (cmd->input->buffer == cmd->output->buffer)
60 {
61 /* flip a single buffer --> override its own contents */
62 for (sy = s0, dy = d0; (dy >= d1) && (sy <= s1); sy++, dy--)
63 {
64 uint8_t* src = in + src_stride * sy;
65 uint8_t* dst = out + dst_stride * dy;
66
67 memcpy(dst, src, src_stride);
68 }
69 }
70 else if (cspace == E_ALPHA)
71 {
72 /* blend onto a target (alpha -> alpha) */
73 Draw_Func_Alpha func = efl_draw_alpha_func_get(cmd->draw.rop, EINA_FALSE);
74 EINA_SAFETY_ON_NULL_GOTO(func, end);
75
76 for (sy = s0, dy = d0; (dy >= d1) && (sy <= s1); sy++, dy--)
77 {
78 uint8_t* src = in + src_stride * sy;
79 uint8_t* dst = out + dst_stride * dy;
80
81 func(dst, src, w);
82 }
83 }
84 else
85 {
86 /* blend onto a target (rgba -> rgba) */
87 uint32_t color = ARGB_JOIN(cmd->draw.A, cmd->draw.R, cmd->draw.G, cmd->draw.B);
88 RGBA_Comp_Func func;
89
90 func = efl_draw_func_span_get(cmd->draw.rop, color, EINA_TRUE);
91 EINA_SAFETY_ON_NULL_GOTO(func, end);
92
93 for (sy = s0, dy = d0; (dy >= d1) && (sy <= s1); sy++, dy--)
94 {
95 uint32_t* src = (uint32_t *) (in + src_stride * sy);
96 uint32_t* dst = (uint32_t *) (out + dst_stride * dy);
97
98 func(dst, src, w, color, 255);
99 }
100 }
101
102 /* fill out outer areas */
103 if (cmd->draw.rop == EFL_GFX_RENDER_OP_COPY)
104 {
105 if (d1 > 0)
106 memset(out, 0, dst_stride * d1);
107 if (d0 < (h - 1))
108 memset(out + dst_stride * d0, 0, dst_stride * (h - d0 - 1));
109 }
110
111 ret = EINA_TRUE;
112
113end:
114 ector_buffer_unmap(cmd->input->buffer, in, src_len);
115 ector_buffer_unmap(cmd->output->buffer, out, dst_len);
116 return ret;
117}
118
119Evas_Filter_Apply_Func
120eng_filter_transform_func_get(Evas_Filter_Command *cmd)
121{
122 EINA_SAFETY_ON_NULL_RETURN_VAL(cmd, NULL);
123
124 switch (cmd->transform.flags)
125 {
126 case EVAS_FILTER_TRANSFORM_VFLIP:
127 return _vflip_cpu;
128 default:
129 CRI("Unknown transform flag %d", (int) cmd->transform.flags);
130 return NULL;
131 }
132}