summaryrefslogtreecommitdiff
path: root/src/lib/ector/software/ector_software_gradient.c
diff options
context:
space:
mode:
authorSubhransu Mohanty <sub.mohanty@samsung.com>2015-08-17 15:55:18 +0900
committerCedric BAIL <cedric@osg.samsung.com>2015-08-19 15:11:58 +0200
commitf3201e9ab97d135b38cdcd02d854784c1954194f (patch)
tree7b147e128c32fabc979468cc1a51ac0bdcbbc28c /src/lib/ector/software/ector_software_gradient.c
parentbed8325e3c2632782c01d21d008b09be7b8b3a3e (diff)
ector: add SSE2 support for gradient filling in software backend.
Signed-off-by: Cedric BAIL <cedric@osg.samsung.com>
Diffstat (limited to 'src/lib/ector/software/ector_software_gradient.c')
-rw-r--r--src/lib/ector/software/ector_software_gradient.c395
1 files changed, 306 insertions, 89 deletions
diff --git a/src/lib/ector/software/ector_software_gradient.c b/src/lib/ector/software/ector_software_gradient.c
index 36829899cb..d6ad207553 100644
--- a/src/lib/ector/software/ector_software_gradient.c
+++ b/src/lib/ector/software/ector_software_gradient.c
@@ -1,51 +1,53 @@
1#ifdef HAVE_CONFIG_H 1#ifdef HAVE_CONFIG_H
2# include "config.h" 2#include "config.h"
3#endif 3#endif
4 4
5//Remove
6#include <assert.h> 5#include <assert.h>
7
8#include <math.h> 6#include <math.h>
9#include <float.h>
10 7
11#include <Eina.h>
12#include <Ector.h>
13#include <software/Ector_Software.h> 8#include <software/Ector_Software.h>
14 9
15#include "ector_private.h" 10#include "ector_private.h"
16#include "ector_software_private.h" 11#include "ector_software_private.h"
17#include "ector_blend_private.h" 12#include "ector_drawhelper_private.h"
18 13
19 14
20#define GRADIENT_STOPTABLE_SIZE 1024 15#define GRADIENT_STOPTABLE_SIZE 1024
21#define FIXPT_BITS 8 16#define FIXPT_BITS 8
22#define FIXPT_SIZE (1<<FIXPT_BITS) 17#define FIXPT_SIZE (1<<FIXPT_BITS)
23 18
19typedef void (*Radial_Helper_Func)(uint *buffer, int length, Ector_Renderer_Software_Gradient_Data *g_data,
20 float det, float delta_det, float delta_delta_det, float b, float delta_b);
21
22typedef void (*Linear_Helper_Func)(uint *buffer, int length, Ector_Renderer_Software_Gradient_Data *g_data,
23 int t_fixed, int inc_fixed);
24
25Radial_Helper_Func radial_helper;
26Linear_Helper_Func linear_helper;
24 27
25static inline int 28static inline int
26_gradient_clamp(const Ector_Renderer_Software_Gradient_Data *data, int ipos) 29_gradient_clamp(const Ector_Renderer_Software_Gradient_Data *data, int ipos)
27{ 30{
28 if (data->gd->s == EFL_GFX_GRADIENT_SPREAD_REPEAT) 31 int limit;
29 { 32 if (data->gd->s == EFL_GFX_GRADIENT_SPREAD_REPEAT)
30 ipos = ipos % GRADIENT_STOPTABLE_SIZE; 33 {
31 ipos = ipos < 0 ? GRADIENT_STOPTABLE_SIZE + ipos : ipos; 34 ipos = ipos % GRADIENT_STOPTABLE_SIZE;
32 } 35 ipos = ipos < 0 ? GRADIENT_STOPTABLE_SIZE + ipos : ipos;
33 else if (data->gd->s == EFL_GFX_GRADIENT_SPREAD_REFLECT) 36 }
34 { 37 else if (data->gd->s == EFL_GFX_GRADIENT_SPREAD_REFLECT)
35 const int limit = GRADIENT_STOPTABLE_SIZE * 2; 38 {
36 ipos = ipos % limit; 39 limit = GRADIENT_STOPTABLE_SIZE * 2;
37 ipos = ipos < 0 ? limit + ipos : ipos; 40 ipos = ipos % limit;
38 ipos = ipos >= GRADIENT_STOPTABLE_SIZE ? limit - 1 - ipos : ipos; 41 ipos = ipos < 0 ? limit + ipos : ipos;
39 } 42 ipos = ipos >= GRADIENT_STOPTABLE_SIZE ? limit - 1 - ipos : ipos;
40 else 43 }
41 { 44 else
42 if (ipos < 0) 45 {
43 ipos = 0; 46 if (ipos < 0) ipos = 0;
44 else if (ipos >= GRADIENT_STOPTABLE_SIZE) 47 else if (ipos >= GRADIENT_STOPTABLE_SIZE)
45 ipos = GRADIENT_STOPTABLE_SIZE-1; 48 ipos = GRADIENT_STOPTABLE_SIZE-1;
46 } 49 }
47 50 return ipos;
48 return ipos;
49} 51}
50 52
51 53
@@ -63,12 +65,213 @@ _gradient_pixel(const Ector_Renderer_Software_Gradient_Data *data, float pos)
63 return data->color_table[_gradient_clamp(data, ipos)]; 65 return data->color_table[_gradient_clamp(data, ipos)];
64} 66}
65 67
68
69#ifdef BUILD_SSE3
70#include <immintrin.h>
71
72#define GRADIENT_STOPTABLE_SIZE_SHIFT 10
73typedef union{ __m128i v; int i[4];}vec4_i;
74typedef union{ __m128 v; float f[4];}vec4_f;
75
76#define FETCH_CLAMP_INIT_F \
77 __m128 v_min = _mm_set1_ps(0.0f); \
78 __m128 v_max = _mm_set1_ps((float)(GRADIENT_STOPTABLE_SIZE-1)); \
79 __m128 v_halff = _mm_set1_ps(0.5f); \
80 __m128i v_repeat_mask = _mm_set1_epi32(~((uint)(0xffffff) << GRADIENT_STOPTABLE_SIZE_SHIFT)); \
81 __m128i v_reflect_mask = _mm_set1_epi32(~((uint)(0xffffff) << (GRADIENT_STOPTABLE_SIZE_SHIFT+1))); \
82 __m128i v_reflect_limit = _mm_set1_epi32(2 * GRADIENT_STOPTABLE_SIZE - 1);
83
84#define FETCH_CLAMP_REPEAT_F \
85 vec4_i index_vec; \
86 index_vec.v = _mm_and_si128(v_repeat_mask, _mm_cvttps_epi32(v_index));
87
88#define FETCH_CLAMP_REFLECT_F \
89 vec4_i index_vec; \
90 __m128i v_index_i = _mm_and_si128(v_reflect_mask, _mm_cvttps_epi32(v_index)); \
91 __m128i v_index_i_inv = _mm_sub_epi32(v_reflect_limit, v_index_i); \
92 index_vec.v = _mm_min_epi16(v_index_i, v_index_i_inv);
93
94#define FETCH_CLAMP_PAD_F \
95 vec4_i index_vec; \
96 index_vec.v = _mm_cvttps_epi32(_mm_min_ps(v_max, _mm_max_ps(v_min, v_index)));
97
98
99#define FETCH_EPILOGUE_CPY \
100 *buffer++ = g_data->color_table[index_vec.i[0]]; \
101 *buffer++ = g_data->color_table[index_vec.i[1]]; \
102 *buffer++ = g_data->color_table[index_vec.i[2]]; \
103 *buffer++ = g_data->color_table[index_vec.i[3]]; \
104}
105
106static void
107loop_break(unsigned int *buffer, int length, int *lprealign, int *lby4 , int *lremaining)
108{
109 int l1=0,l2=0,l3=0;
110 while ((int)buffer & 0xF)
111 buffer++ , l1++;
112
113 if(length <= l1)
114 l1 = length;
115 else
116 {
117 l3 = (length - l1)%4;
118 l2 = length - l1 - l3 ;
119 }
120 *lprealign = l1;
121 *lby4 = l2;
122 *lremaining = l3;
123}
124
125static void
126_radial_helper_sse3(uint *buffer, int length, Ector_Renderer_Software_Gradient_Data *g_data,
127 float det, float delta_det, float delta_delta_det, float b, float delta_b)
128{
129 int lprealign, lby4, lremaining, i;
130 loop_break(buffer, length, &lprealign, &lby4, &lremaining);
131 // prealign loop
132 for (i = 0 ; i < lprealign ; i++)
133 {
134 *buffer++ = _gradient_pixel(g_data, sqrt(det) - b);
135 det += delta_det;
136 delta_det += delta_delta_det;
137 b += delta_b;
138 }
139
140 // lby4 16byte align loop
141 vec4_f det_vec;
142 vec4_f delta_det4_vec;
143 vec4_f b_vec;
144
145 for (i = 0; i < 4; ++i)
146 {
147 det_vec.f[i] = det;
148 delta_det4_vec.f[i] = 4 * delta_det;
149 b_vec.f[i] = b;
150
151 det += delta_det;
152 delta_det += delta_delta_det;
153 b += delta_b;
154 }
155
156 __m128 v_delta_delta_det16 = _mm_set1_ps(16 * delta_delta_det);
157 __m128 v_delta_delta_det6 = _mm_set1_ps(6 * delta_delta_det);
158 __m128 v_delta_b4 = _mm_set1_ps(4 * delta_b);
159
160#define FETCH_RADIAL_PROLOGUE \
161 for (i = 0 ; i < lby4 ; i+=4) { \
162 __m128 v_index_local = _mm_sub_ps(_mm_sqrt_ps(det_vec.v), b_vec.v); \
163 __m128 v_index = _mm_add_ps(_mm_mul_ps(v_index_local, v_max), v_halff); \
164 det_vec.v = _mm_add_ps(_mm_add_ps(det_vec.v, delta_det4_vec.v), v_delta_delta_det6); \
165 delta_det4_vec.v = _mm_add_ps(delta_det4_vec.v, v_delta_delta_det16); \
166 b_vec.v = _mm_add_ps(b_vec.v, v_delta_b4);
167
168
169#define FETCH_RADIAL_LOOP(FETCH_CLAMP) \
170 FETCH_RADIAL_PROLOGUE \
171 FETCH_CLAMP \
172 FETCH_EPILOGUE_CPY
173
174 FETCH_CLAMP_INIT_F
175 switch (g_data->gd->s)
176 {
177 case EFL_GFX_GRADIENT_SPREAD_REPEAT:
178 FETCH_RADIAL_LOOP(FETCH_CLAMP_REPEAT_F)
179 break;
180 case EFL_GFX_GRADIENT_SPREAD_REFLECT:
181 FETCH_RADIAL_LOOP( FETCH_CLAMP_REFLECT_F)
182 break;
183 default:
184 FETCH_RADIAL_LOOP(FETCH_CLAMP_PAD_F)
185 break;
186 }
187
188 // remaining loop
189 for (i = 0 ; i < lremaining ; i++)
190 *buffer++ = _gradient_pixel(g_data, sqrt(det_vec.f[i]) - b_vec.f[i]);
191}
192
193static void
194_linear_helper_sse3(uint *buffer, int length, Ector_Renderer_Software_Gradient_Data *g_data, int t, int inc)
195{
196 int lprealign, lby4, lremaining, i;
197 loop_break(buffer, length, &lprealign, &lby4, &lremaining);
198 // prealign loop
199 for (i = 0 ; i < lprealign ; i++)
200 {
201 *buffer++ = _gradient_pixel_fixed(g_data, t);
202 t += inc;
203 }
204
205 // lby4 16byte align loop
206 vec4_i t_vec;
207 for (i = 0; i < 4; ++i)
208 {
209 t_vec.i[i] = t;
210 t += inc;
211 }
212
213 __m128i v_inc = _mm_set1_epi32(4 * inc);
214 __m128i v_fxtpt_size = _mm_set1_epi32(FIXPT_SIZE * 0.5);
215
216 __m128i v_min = _mm_set1_epi32(0);
217 __m128i v_max = _mm_set1_epi32((GRADIENT_STOPTABLE_SIZE-1));
218
219 __m128i v_repeat_mask = _mm_set1_epi32(~((uint)(0xffffff) << GRADIENT_STOPTABLE_SIZE_SHIFT));
220 __m128i v_reflect_mask = _mm_set1_epi32(~((uint)(0xffffff) << (GRADIENT_STOPTABLE_SIZE_SHIFT+1)));
221
222 __m128i v_reflect_limit = _mm_set1_epi32(2 * GRADIENT_STOPTABLE_SIZE - 1);
223
224#define FETCH_LINEAR_LOOP_PROLOGUE \
225 for (i = 0 ; i < lby4 ; i+=4) { \
226 vec4_i index_vec;\
227 __m128i v_index;\
228 v_index = _mm_srai_epi32(_mm_add_epi32(t_vec.v, v_fxtpt_size), FIXPT_BITS); \
229 t_vec.v = _mm_add_epi32(t_vec.v, v_inc);
230
231#define FETCH_LINEAR_LOOP_CLAMP_REPEAT \
232 index_vec.v = _mm_and_si128(v_repeat_mask, v_index);
233
234#define FETCH_LINEAR_LOOP_CLAMP_REFLECT \
235 __m128i v_index_i = _mm_and_si128(v_reflect_mask, v_index); \
236 __m128i v_index_i_inv = _mm_sub_epi32(v_reflect_limit, v_index_i); \
237 index_vec.v = _mm_min_epi16(v_index_i, v_index_i_inv);
238
239#define FETCH_LINEAR_LOOP_CLAMP_PAD \
240 index_vec.v = _mm_min_epi16(v_max, _mm_max_epi16(v_min, v_index));
241
242
243
244#define FETCH_LINEAR_LOOP(FETCH_LINEAR_LOOP_CLAMP) \
245 FETCH_LINEAR_LOOP_PROLOGUE \
246 FETCH_LINEAR_LOOP_CLAMP \
247 FETCH_EPILOGUE_CPY
248
249 switch (g_data->gd->s)
250 {
251 case EFL_GFX_GRADIENT_SPREAD_REPEAT:
252 FETCH_LINEAR_LOOP(FETCH_LINEAR_LOOP_CLAMP_REPEAT)
253 break;
254 case EFL_GFX_GRADIENT_SPREAD_REFLECT:
255 FETCH_LINEAR_LOOP(FETCH_LINEAR_LOOP_CLAMP_REFLECT)
256 break;
257 default:
258 FETCH_LINEAR_LOOP(FETCH_LINEAR_LOOP_CLAMP_PAD)
259 break;
260 }
261
262 // remaining loop
263 for (i = 0 ; i < lremaining ; i++)
264 *buffer++ = _gradient_pixel_fixed(g_data, t_vec.i[i]);
265}
266
267#endif
268
66typedef double (*BLEND_FUNC)(double progress); 269typedef double (*BLEND_FUNC)(double progress);
67 270
68static double 271static double
69_ease_linear(double t) 272_ease_linear(double t)
70{ 273{
71 return t; 274 return t;
72} 275}
73 276
74static Eina_Bool 277static Eina_Bool
@@ -144,14 +347,25 @@ destroy_color_table(Ector_Renderer_Software_Gradient_Data *gdata)
144 } 347 }
145} 348}
146 349
350inline static void
351_linear_helper_generic(uint *buffer, int length, Ector_Renderer_Software_Gradient_Data *g_data,
352 int t_fixed, int inc_fixed)
353{
354 int i;
355 for (i = 0 ; i < length ; i++)
356 {
357 *buffer++ = _gradient_pixel_fixed(g_data, t_fixed);
358 t_fixed += inc_fixed;
359 }
360}
147 361
148void 362void
149fetch_linear_gradient(uint *buffer, Span_Data *data, int y, int x, int length) 363fetch_linear_gradient(uint *buffer, Span_Data *data, int y, int x, int length)
150{ 364{
151 Ector_Renderer_Software_Gradient_Data *g_data = data->gradient; 365 Ector_Renderer_Software_Gradient_Data *g_data = data->gradient;
152 float t, inc; 366 float t, inc, rx=0, ry=0;
153 float rx=0, ry=0; 367 uint *end;
154 368 int t_fixed, inc_fixed;
155 if (g_data->linear.l == 0) 369 if (g_data->linear.l == 0)
156 { 370 {
157 t = inc = 0; 371 t = inc = 0;
@@ -167,10 +381,10 @@ fetch_linear_gradient(uint *buffer, Span_Data *data, int y, int x, int length)
167 inc *= (GRADIENT_STOPTABLE_SIZE - 1); 381 inc *= (GRADIENT_STOPTABLE_SIZE - 1);
168 } 382 }
169 383
170 uint *end = buffer + length; 384 end = buffer + length;
171 if (inc > (float)(-1e-5) && inc < (float)(1e-5)) 385 if (inc > (float)(-1e-5) && inc < (float)(1e-5))
172 { 386 {
173 _ector_memfill(buffer, _gradient_pixel_fixed(g_data, (int)(t * FIXPT_SIZE)), length); 387 _ector_memfill(buffer, length, _gradient_pixel_fixed(g_data, (int)(t * FIXPT_SIZE)));
174 } 388 }
175 else 389 else
176 { 390 {
@@ -178,95 +392,98 @@ fetch_linear_gradient(uint *buffer, Span_Data *data, int y, int x, int length)
178 t+inc*length > (float)(INT_MIN >> (FIXPT_BITS + 1))) 392 t+inc*length > (float)(INT_MIN >> (FIXPT_BITS + 1)))
179 { 393 {
180 // we can use fixed point math 394 // we can use fixed point math
181 int t_fixed = (int)(t * FIXPT_SIZE); 395 t_fixed = (int)(t * FIXPT_SIZE);
182 int inc_fixed = (int)(inc * FIXPT_SIZE); 396 inc_fixed = (int)(inc * FIXPT_SIZE);
183 // #ifdef BUILD_SSE3 397 linear_helper(buffer, length, g_data, t_fixed, inc_fixed);
184 // if (evas_common_cpu_has_feature(CPU_FEATURE_SSE3)) {
185 // _fetch_linear_sse3(buffer, length, g_data, t_fixed, inc_fixed);
186 // } else
187 // #endif
188 {
189 while (buffer < end)
190 {
191 *buffer++ = _gradient_pixel_fixed(g_data, t_fixed);
192 t_fixed += inc_fixed;
193 }
194 }
195 } 398 }
196 else 399 else
197 { 400 {
198 // we have to fall back to float math 401 // we have to fall back to float math
199 while (buffer < end) { 402 while (buffer < end)
200 *buffer++ = _gradient_pixel(g_data, t/GRADIENT_STOPTABLE_SIZE); 403 {
201 t += inc; 404 *buffer++ = _gradient_pixel(g_data, t/GRADIENT_STOPTABLE_SIZE);
202 } 405 t += inc;
406 }
203 } 407 }
204 } 408 }
205} 409}
206 410
207static void 411
412
413inline static void
208_radial_helper_generic(uint *buffer, int length, Ector_Renderer_Software_Gradient_Data *g_data, float det, 414_radial_helper_generic(uint *buffer, int length, Ector_Renderer_Software_Gradient_Data *g_data, float det,
209 float delta_det, float delta_delta_det, float b, float delta_b) 415 float delta_det, float delta_delta_det, float b, float delta_b)
210{ 416{
211 for (int i = 0 ; i < length ; i++) 417 int i;
212 { 418 for (i = 0 ; i < length ; i++)
213 *buffer++ = _gradient_pixel(g_data, sqrt(det) - b); 419 {
214 det += delta_det; 420 *buffer++ = _gradient_pixel(g_data, sqrt(det) - b);
215 delta_det += delta_delta_det; 421 det += delta_det;
216 b += delta_b; 422 delta_det += delta_delta_det;
217 } 423 b += delta_b;
424 }
218} 425}
219 426
220void 427void
221fetch_radial_gradient(uint *buffer, Span_Data *data, int y, int x, int length) 428fetch_radial_gradient(uint *buffer, Span_Data *data, int y, int x, int length)
222{ 429{
223 Ector_Renderer_Software_Gradient_Data *g_data = data->gradient; 430 Ector_Renderer_Software_Gradient_Data *g_data = data->gradient;
224 431 float rx, ry, inv_a, delta_rx, delta_ry, b, delta_b, b_delta_b, delta_b_delta_b,
432 bb, delta_bb, rxrxryry, delta_rxrxryry, rx_plus_ry, delta_rx_plus_ry, det,
433 delta_det, delta_delta_det;
225 // avoid division by zero 434 // avoid division by zero
226 if (fabsf(g_data->radial.a) <= 0.00001f) 435 if (fabsf(g_data->radial.a) <= 0.00001f)
227 { 436 {
228 _ector_memfill(buffer, 0, length); 437 _ector_memfill(buffer, length, 0);
229 return; 438 return;
230 } 439 }
231 440
232 float rx = data->inv.xy * (y + (float)0.5) + data->inv.xz + data->inv.xx * (x + (float)0.5); 441 rx = data->inv.xy * (y + (float)0.5) + data->inv.xz + data->inv.xx * (x + (float)0.5);
233 float ry = data->inv.yy * (y + (float)0.5) + data->inv.yz + data->inv.yx * (x + (float)0.5); 442 ry = data->inv.yy * (y + (float)0.5) + data->inv.yz + data->inv.yx * (x + (float)0.5);
234 443
235 rx -= g_data->radial.fx; 444 rx -= g_data->radial.fx;
236 ry -= g_data->radial.fy; 445 ry -= g_data->radial.fy;
237 446
238 float inv_a = 1 / (float)(2 * g_data->radial.a); 447 inv_a = 1 / (float)(2 * g_data->radial.a);
239 448
240 const float delta_rx = data->inv.xx; 449 delta_rx = data->inv.xx;
241 const float delta_ry = data->inv.yx; 450 delta_ry = data->inv.yx;
242 451
243 float b = 2*(g_data->radial.dr*g_data->radial.fradius + rx * g_data->radial.dx + ry * g_data->radial.dy); 452 b = 2*(g_data->radial.dr*g_data->radial.fradius + rx * g_data->radial.dx + ry * g_data->radial.dy);
244 float delta_b = 2*(delta_rx * g_data->radial.dx + delta_ry * g_data->radial.dy); 453 delta_b = 2*(delta_rx * g_data->radial.dx + delta_ry * g_data->radial.dy);
245 const float b_delta_b = 2 * b * delta_b; 454 b_delta_b = 2 * b * delta_b;
246 const float delta_b_delta_b = 2 * delta_b * delta_b; 455 delta_b_delta_b = 2 * delta_b * delta_b;
247 456
248 const float bb = b * b; 457 bb = b * b;
249 const float delta_bb = delta_b * delta_b; 458 delta_bb = delta_b * delta_b;
250 b *= inv_a; 459 b *= inv_a;
251 delta_b *= inv_a; 460 delta_b *= inv_a;
252 461
253 const float rxrxryry = rx * rx + ry * ry; 462 rxrxryry = rx * rx + ry * ry;
254 const float delta_rxrxryry = delta_rx * delta_rx + delta_ry * delta_ry; 463 delta_rxrxryry = delta_rx * delta_rx + delta_ry * delta_ry;
255 const float rx_plus_ry = 2*(rx * delta_rx + ry * delta_ry); 464 rx_plus_ry = 2*(rx * delta_rx + ry * delta_ry);
256 const float delta_rx_plus_ry = 2 * delta_rxrxryry; 465 delta_rx_plus_ry = 2 * delta_rxrxryry;
257 466
258 inv_a *= inv_a; 467 inv_a *= inv_a;
259 468
260 float det = (bb - 4 * g_data->radial.a * (g_data->radial.sqrfr - rxrxryry)) * inv_a; 469 det = (bb - 4 * g_data->radial.a * (g_data->radial.sqrfr - rxrxryry)) * inv_a;
261 float delta_det = (b_delta_b + delta_bb + 4 * g_data->radial.a * (rx_plus_ry + delta_rxrxryry)) * inv_a; 470 delta_det = (b_delta_b + delta_bb + 4 * g_data->radial.a * (rx_plus_ry + delta_rxrxryry)) * inv_a;
262 const float delta_delta_det = (delta_b_delta_b + 4 * g_data->radial.a * delta_rx_plus_ry) * inv_a; 471 delta_delta_det = (delta_b_delta_b + 4 * g_data->radial.a * delta_rx_plus_ry) * inv_a;
263 472
264 // #ifdef BUILD_SSE3 473 radial_helper(buffer, length, g_data, det, delta_det, delta_delta_det, b, delta_b);
265 // if (evas_common_cpu_has_feature(CPU_FEATURE_SSE3)) { 474}
266 // _radial_helper_sse3(buffer, length, g_data, det, delta_det, delta_delta_det, b, delta_b); 475
267 // } else 476
268 // #endif 477void
269 { // generic fallback 478init_drawhelper_gradient()
270 _radial_helper_generic(buffer, length, g_data, det, delta_det, delta_delta_det, b, delta_b); 479{
271 } 480 radial_helper = _radial_helper_generic;
481 linear_helper = _linear_helper_generic;
482 #ifdef BUILD_SSE3
483 if (eina_cpu_features_get() & EINA_CPU_SSE3)
484 {
485 radial_helper = _radial_helper_sse3;
486 linear_helper = _linear_helper_sse3;
487 }
488 #endif
272} 489}