move around - flatter.
[profile/ivi/evas.git] / src / lib / engines / common / evas_blit_main.c
1 /*
2  * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
3  */
4
5 #include "evas_common.h"
6
7 #if defined BUILD_MMX || defined BUILD_SSE
8 #include "evas_mmx.h"
9 #endif
10
11 #define ALIGN_FIX
12
13 static void evas_common_copy_pixels_c        (DATA32 *src, DATA32 *dst, int len);
14 static void evas_common_copy_pixels_mmx      (DATA32 *src, DATA32 *dst, int len);
15 static void evas_common_copy_pixels_mmx2     (DATA32 *src, DATA32 *dst, int len);
16 static void evas_common_copy_pixels_sse/*NB*/ (DATA32 *src, DATA32 *dst, int len);
17
18 static void evas_common_copy_pixels_rev_c           (DATA32 *src, DATA32 *dst, int len);
19 static void evas_common_copy_pixels_rev_mmx         (DATA32 *src, DATA32 *dst, int len);
20 static void evas_common_copy_pixels_rev_sse/*NB*/ (DATA32 *src, DATA32 *dst, int len);
21
22 static void evas_common_copy_rev_pixels_c           (DATA32 *src, DATA32 *dst, int len);
23
24
25 EAPI void
26 evas_common_blit_init(void)
27 {
28 }
29
30 EAPI void
31 evas_common_blit_rectangle(const RGBA_Image *src, RGBA_Image *dst, int src_x, int src_y, int w, int h, int dst_x, int dst_y)
32 {
33    int y;
34    Gfx_Func_Copy func;
35    DATA32 *src_ptr, *dst_ptr;
36
37    /* clip clip clip */
38    if (w <= 0) return;
39    if (src_x + w > src->cache_entry.w) w = src->cache_entry.w - src_x;
40    if (w <= 0) return;
41    if (src_x < 0)
42      {
43         dst_x -= src_x;
44         w += src_x;
45         src_x = 0;
46      }
47    if (w <= 0) return;
48
49    if (h <= 0) return;
50    if (src_y + h > src->cache_entry.h) h = src->cache_entry.h - src_y;
51    if (h <= 0) return;
52    if (src_y < 0)
53      {
54         dst_y -= src_y;
55         h += src_y;
56         src_y = 0;
57      }
58    if (h <= 0) return;
59
60    if (w <= 0) return;
61    if (dst_x + w > dst->cache_entry.w) w = dst->cache_entry.w - dst_x;
62    if (w <= 0) return;
63    if (dst_x < 0)
64      {
65         src_x -= dst_x;
66         w += dst_x;
67         dst_x = 0;
68      }
69    if (w <= 0) return;
70
71    if (h <= 0) return;
72    if (dst_y + h > dst->cache_entry.h) h = dst->cache_entry.h - dst_y;
73    if (h <= 0) return;
74    if (dst_y < 0)
75      {
76         src_y -= dst_y;
77         h += dst_y;
78         dst_y = 0;
79      }
80    if (h <= 0) return;
81
82    if (dst == src)
83      {
84         /* src after dst - go forward */
85         if (((src_y * src->cache_entry.w) + src_x) > ((dst_y * dst->cache_entry.w) + dst_x))
86           {
87              func = evas_common_draw_func_copy_get(w, 0);
88              for (y = 0; y < h; y++)
89                {
90                   src_ptr = src->image.data + ((y + src_y) * src->cache_entry.w) + src_x;
91                   dst_ptr = dst->image.data + ((y + dst_y) * dst->cache_entry.w) + dst_x;
92                   func(src_ptr, dst_ptr, w);
93                }
94           }
95         /* reverse */
96         else
97           {
98              func = evas_common_draw_func_copy_get(w, 1);
99              for (y = h - 1; y >= 0; y--)
100                {
101                   src_ptr = src->image.data + ((y + src_y) * src->cache_entry.w) + src_x;
102                   dst_ptr = dst->image.data + ((y + dst_y) * dst->cache_entry.w) + dst_x;
103                   func(src_ptr, dst_ptr, w);
104                }
105           }
106      }
107    else
108      {
109         func = evas_common_draw_func_copy_get(w, 0);
110         for (y = 0; y < h; y++)
111           {
112              src_ptr = src->image.data + ((y + src_y) * src->cache_entry.w) + src_x;
113              dst_ptr = dst->image.data + ((y + dst_y) * dst->cache_entry.w) + dst_x;
114              func(src_ptr, dst_ptr, w);
115           }
116      }
117 }
118
119
120 /****************************************************************************/
121
122 static void
123 evas_common_copy_rev_pixels_c(DATA32 *src, DATA32 *dst, int len)
124 {
125    DATA32 *dst_end = dst + len;
126
127    src += len - 1;
128    while (dst < dst_end)
129         *dst++ = *src--;
130 }
131
132 #ifdef BUILD_C
133 static void
134 evas_common_copy_pixels_c(DATA32 *src, DATA32 *dst, int len)
135 {
136    DATA32 *dst_end = dst + len;
137
138    while (dst < dst_end)
139         *dst++ = *src++;
140 }
141 #endif
142
143 #ifdef BUILD_MMX
144 static void
145 evas_common_copy_pixels_mmx(DATA32 *src, DATA32 *dst, int len)
146 {
147    DATA32 *dst_end, *dst_end_pre;
148 #ifdef ALIGN_FIX
149    intptr_t src_align;
150    intptr_t dst_align;
151
152    src_align = (intptr_t)src & 0x3f; /* 64 byte alignment */
153    dst_align = (intptr_t)dst & 0x3f; /* 64 byte alignment */
154
155    if ((src_align != dst_align) ||
156        ((src_align & 0x3) != 0))
157      {
158 #ifdef BUILD_C
159         evas_common_copy_pixels_c(src, dst, len);
160         return;
161      }
162 #endif
163
164    while ((src_align > 0) && (len > 0))
165      {
166         *dst++ = *src++;
167         len--;
168         src_align -= sizeof(DATA32);
169      }
170 #endif /* ALIGN_FIX */
171
172    dst_end = dst + len;
173    dst_end_pre = dst + ((len / 16) * 16);
174
175    while (dst < dst_end_pre)
176      {
177         MOVE_16DWORDS_MMX(src, dst);
178         src += 16;
179         dst += 16;
180      }
181    while (dst < dst_end)
182         *dst++ = *src++;
183 }
184 #endif
185
186 #ifdef BUILD_MMX
187 static void
188 evas_common_copy_pixels_mmx2(DATA32 *src, DATA32 *dst, int len)
189 {
190    DATA32 *dst_end, *dst_end_pre;
191 #ifdef ALIGN_FIX
192    intptr_t src_align;
193    intptr_t dst_align;
194
195    src_align = (intptr_t)src & 0x3f; /* 64 byte alignment */
196    dst_align = (intptr_t)dst & 0x3f; /* 64 byte alignment */
197
198    if ((src_align != dst_align) ||
199        ((src_align & 0x3) != 0))
200      {
201 #ifdef BUILD_C
202         evas_common_copy_pixels_c(src, dst, len);
203 #endif
204         return;
205      }
206
207    while ((src_align > 0) && (len > 0))
208      {
209         *dst++ = *src++;
210         len--;
211         src_align -= sizeof(DATA32);
212      }
213 #endif
214
215    dst_end = dst + len;
216    dst_end_pre = dst + ((len / 16) * 16);
217
218    while (dst < dst_end_pre)
219      {
220         MOVE_16DWORDS_MMX(src, dst);
221         src += 16;
222         dst += 16;
223      }
224    while (dst < dst_end)
225         *dst++ = *src++;
226 }
227 #endif
228
229 #ifdef BUILD_SSE
230 static void
231 evas_common_copy_pixels_sse(DATA32 *src, DATA32 *dst, int len)
232 {
233    DATA32 *src_ptr, *dst_ptr, *dst_end_ptr;
234
235    dst_end_ptr = dst + len;
236    dst_end_ptr -= 15;
237    src_ptr = src;
238    dst_ptr = dst;
239    while (dst_ptr < dst_end_ptr)
240      {
241         MOVE_16DWORDS_MMX2(src_ptr, dst_ptr);
242         src_ptr+=16;
243         dst_ptr+=16;
244      }
245    dst_end_ptr = dst + len;
246    while (dst_ptr < dst_end_ptr)
247      {
248         *dst_ptr = *src_ptr;
249         src_ptr++;
250         dst_ptr++;
251      }
252 #if 0
253 #ifdef ALIGN_FIX
254    int src_align;
255    int dst_align;
256
257    src_align = (int)src & 0x3f; /* 64 byte alignment */
258    dst_align = (int)dst & 0x3f; /* 64 byte alignment */
259
260    if ((src_align != dst_align) ||
261        ((src_align & 0x3) != 0))
262      {
263 #ifdef BUILD_C
264         evas_common_copy_pixels_c(src, dst, len);
265 #endif
266         return;
267      }
268
269    while ((src_align > 0) && (len > 0))
270      {
271         *dst = *src;
272         dst++;
273         src++;
274         len--;
275         src_align -= sizeof(DATA32);
276      }
277 #endif /* ALIGN_FIX */
278
279    src_ptr = src;
280    dst_ptr = dst;
281    dst_end_ptr = dst + len;
282    dst_end_ptr_pre = dst + ((len / 16) * 16);
283
284    while (dst_ptr < dst_end_ptr_pre)
285      {
286         prefetch(&src_ptr[16]);
287         MOVE_16DWORDS_MMX(src_ptr, dst_ptr);
288         src_ptr+=16;
289         dst_ptr+=16;
290      }
291    while (dst_ptr < dst_end_ptr)
292      {
293         *dst_ptr = *src_ptr;
294         src_ptr++;
295         dst_ptr++;
296      }
297 #endif
298 }
299 #endif
300
301 /****************************************************************************/
302
303 #ifdef BUILD_C
304 static void
305 evas_common_copy_pixels_rev_c(DATA32 *src, DATA32 *dst, int len)
306 {
307    DATA32 *dst_end;
308
309    src = src + len - 1;
310    dst_end = dst - 1;
311    dst = dst + len - 1;
312
313    while (dst > dst_end)
314         *dst-- = *src--;
315 }
316 #endif
317
318 #ifdef BUILD_MMX
319 static void
320 evas_common_copy_pixels_rev_mmx(DATA32 *src, DATA32 *dst, int len)
321 {
322    DATA32 *dst_end, *dst_end_pre;
323
324    if (len >= 16)
325      {
326         src = src + len - 16;
327         dst_end = dst;
328         dst_end_pre = dst + len - ((len / 16) * 16);
329         dst = dst + len - 16;
330
331         while (dst >= dst_end_pre)
332           {
333              MOVE_16DWORDS_MMX(src, dst);
334              src -= 16;
335              dst -= 16;
336           }
337         src += 15;
338         dst += 15;
339         while (dst >= dst_end)
340              *dst-- = *src--;
341      }
342    else
343      {
344         src = src + len - 1;
345         dst_end = dst - 1;
346         dst = dst + len - 1;
347         while (dst > dst_end)
348              *dst-- = *src--;
349      }
350 }
351 #endif
352
353 #ifdef BUILD_SSE
354 static void
355 evas_common_copy_pixels_rev_sse(DATA32 *src, DATA32 *dst, int len)
356 {
357    DATA32 *src_ptr, *dst_ptr, *dst_end_ptr, *dst_end_ptr_pre;
358
359    src_ptr = src + len - 16;
360    dst_ptr = dst + len - 16;
361    dst_end_ptr = dst;
362    dst_end_ptr_pre = dst + len - ((len / 16) * 16);
363
364    if (len >= 16)
365      {
366         while (dst_ptr >= dst_end_ptr_pre)
367           {
368              prefetch(&src_ptr[-16]);
369              MOVE_10DWORDS_MMX(src_ptr, dst_ptr);
370              src_ptr -= 16;
371              dst_ptr -= 16;
372           }
373         src_ptr += 15;
374         dst_ptr += 15;
375         while (dst_ptr >= dst_end_ptr)
376           {
377              *dst_ptr = *src_ptr;
378              src_ptr--;
379              dst_ptr--;
380           }
381      }
382    else
383      {
384         src_ptr = src + len - 1;
385         dst_ptr = dst + len - 1;
386         while (dst_ptr >= dst_end_ptr)
387           {
388              *dst_ptr = *src_ptr;
389              src_ptr--;
390              dst_ptr--;
391           }
392      }
393 }
394 #endif
395
396
397 Gfx_Func_Copy
398 evas_common_draw_func_copy_get(int pixels, int reverse)
399 {
400    if (reverse == -1)
401         return evas_common_copy_rev_pixels_c;
402    if (reverse)
403      {
404 #ifdef  BUILD_SSE
405         if (evas_common_cpu_has_feature(CPU_FEATURE_SSE) && (pixels > 256 * 256))
406           return evas_common_copy_pixels_rev_sse;
407 #endif
408 #ifdef BUILD_MMX
409 # ifdef BUILD_SSE
410         else
411 # endif
412           if (evas_common_cpu_has_feature(CPU_FEATURE_MMX))
413             return evas_common_copy_pixels_rev_mmx;
414 #endif
415 #ifdef BUILD_C
416 # ifdef BUILD_MMX
417         else
418 # endif
419           return evas_common_copy_pixels_rev_c;
420 #endif
421      }
422    else
423      {
424 #if 1
425
426 # ifdef BUILD_MMX
427 # ifdef BUILD_C
428              if (evas_common_cpu_has_feature(CPU_FEATURE_MMX2))
429 # endif
430                return evas_common_copy_pixels_mmx2;
431 # ifdef BUILD_SSE
432              else
433 # endif
434 #endif
435 #ifdef BUILD_SSE
436 # ifdef BUILD_C
437                if (evas_common_cpu_has_feature(CPU_FEATURE_SSE) && (pixels > 64 * 64))
438 # endif
439                  return evas_common_copy_pixels_sse;
440 # ifdef BUILD_MMX
441              else
442 # endif
443 #endif
444 #ifdef BUILD_MMX
445 # ifdef BUILD_C
446                if (evas_common_cpu_has_feature(CPU_FEATURE_MMX))
447 # endif
448                  return evas_common_copy_pixels_mmx;
449 # ifdef BUILD_C
450              else
451 # endif
452 #endif
453 #ifdef BUILD_C
454                return evas_common_copy_pixels_c;
455 #endif
456
457 #else
458
459 # ifdef BUILD_SSE
460              if (evas_common_cpu_has_feature(CPU_FEATURE_SSE) && (pixels > 256 * 256))
461                return evas_common_copy_pixels_sse;
462 # ifdef BUILD_MMX
463              else
464 # endif
465 #endif
466 #ifdef BUILD_MMX
467 # ifdef BUILD_C
468                if (evas_common_cpu_has_feature(CPU_FEATURE_MMX2))
469 # endif
470                  return evas_common_copy_pixels_mmx2;
471 # ifdef BUILD_C
472                else if (evas_common_cpu_has_feature(CPU_FEATURE_MMX))
473 # endif
474                  return evas_common_copy_pixels_mmx;
475 # ifdef BUILD_C
476              else
477 # endif
478 #endif
479 #ifdef BUILD_C
480                return evas_common_copy_pixels_c;
481 #endif
482
483 #endif
484      }
485 #ifdef BUILD_C
486    return evas_common_copy_pixels_c;
487 #else
488    return NULL;
489 #endif
490    pixels = 0;
491 }