ARM: minor source formatting changes
[profile/ivi/pixman.git] / pixman / pixman-arm-neon.c
1 /*
2  * Copyright © 2009 ARM Ltd, Movial Creative Technologies Oy
3  *
4  * Permission to use, copy, modify, distribute, and sell this software and its
5  * documentation for any purpose is hereby granted without fee, provided that
6  * the above copyright notice appear in all copies and that both that
7  * copyright notice and this permission notice appear in supporting
8  * documentation, and that the name of ARM Ltd not be used in
9  * advertising or publicity pertaining to distribution of the software without
10  * specific, written prior permission.  ARM Ltd makes no
11  * representations about the suitability of this software for any purpose.  It
12  * is provided "as is" without express or implied warranty.
13  *
14  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
15  * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
16  * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
17  * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
18  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
19  * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
20  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
21  * SOFTWARE.
22  *
23  * Author:  Ian Rickards (ian.rickards@arm.com)
24  * Author:  Jonathan Morton (jonathan.morton@movial.com)
25  * Author:  Markku Vire (markku.vire@movial.com)
26  *
27  */
28
29 #ifdef HAVE_CONFIG_H
30 #include <config.h>
31 #endif
32
33 #include <string.h>
34 #include "pixman-private.h"
35
36 #define BIND_SRC_NULL_DST(name, src_type, src_cnt, dst_type, dst_cnt)   \
37 void                                                                    \
38 pixman_composite_##name##_asm_neon (int32_t   w,                        \
39                                     int32_t   h,                        \
40                                     dst_type *dst,                      \
41                                     int32_t   dst_stride,               \
42                                     src_type *src,                      \
43                                     int32_t   src_stride);              \
44                                                                         \
45 static void                                                             \
46 neon_composite_##name (pixman_implementation_t *imp,                    \
47                        pixman_op_t              op,                     \
48                        pixman_image_t *         src_image,              \
49                        pixman_image_t *         mask_image,             \
50                        pixman_image_t *         dst_image,              \
51                        int32_t                  src_x,                  \
52                        int32_t                  src_y,                  \
53                        int32_t                  mask_x,                 \
54                        int32_t                  mask_y,                 \
55                        int32_t                  dest_x,                 \
56                        int32_t                  dest_y,                 \
57                        int32_t                  width,                  \
58                        int32_t                  height)                 \
59 {                                                                       \
60     dst_type *dst_line;                                                 \
61     src_type *src_line;                                                 \
62     int32_t dst_stride, src_stride;                                     \
63                                                                         \
64     PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, src_type,           \
65                            src_stride, src_line, src_cnt);              \
66     PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, dst_type,         \
67                            dst_stride, dst_line, dst_cnt);              \
68                                                                         \
69     pixman_composite_##name##_asm_neon (width, height,                  \
70                                         dst_line, dst_stride,           \
71                                         src_line, src_stride);          \
72 }
73
74 #define BIND_N_MASK_DST(name, mask_type, mask_cnt, dst_type, dst_cnt)   \
75 void                                                                    \
76 pixman_composite_##name##_asm_neon (int32_t    w,                       \
77                                     int32_t    h,                       \
78                                     dst_type  *dst,                     \
79                                     int32_t    dst_stride,              \
80                                     uint32_t   src,                     \
81                                     int32_t    unused,                  \
82                                     mask_type *mask,                    \
83                                     int32_t    mask_stride);            \
84                                                                         \
85 static void                                                             \
86 neon_composite_##name (pixman_implementation_t *imp,                    \
87                        pixman_op_t              op,                     \
88                        pixman_image_t *         src_image,              \
89                        pixman_image_t *         mask_image,             \
90                        pixman_image_t *         dst_image,              \
91                        int32_t                  src_x,                  \
92                        int32_t                  src_y,                  \
93                        int32_t                  mask_x,                 \
94                        int32_t                  mask_y,                 \
95                        int32_t                  dest_x,                 \
96                        int32_t                  dest_y,                 \
97                        int32_t                  width,                  \
98                        int32_t                  height)                 \
99 {                                                                       \
100     dst_type  *dst_line;                                                \
101     mask_type *mask_line;                                               \
102     int32_t    dst_stride, mask_stride;                                 \
103     uint32_t   src;                                                     \
104                                                                         \
105     src = _pixman_image_get_solid (src_image, dst_image->bits.format);  \
106                                                                         \
107     if (src == 0)                                                       \
108         return;                                                         \
109                                                                         \
110     PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, dst_type,         \
111                            dst_stride, dst_line, dst_cnt);              \
112     PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, mask_type,       \
113                            mask_stride, mask_line, mask_cnt);           \
114                                                                         \
115     pixman_composite_##name##_asm_neon (width, height,                  \
116                                         dst_line, dst_stride,           \
117                                         src, 0,                         \
118                                         mask_line, mask_stride);        \
119 }
120
121 #define BIND_SRC_N_DST(name, src_type, src_cnt, dst_type, dst_cnt)      \
122 void                                                                    \
123 pixman_composite_##name##_asm_neon (int32_t    w,                       \
124                                     int32_t    h,                       \
125                                     dst_type  *dst,                     \
126                                     int32_t    dst_stride,              \
127                                     src_type  *src,                     \
128                                     int32_t    src_stride,              \
129                                     uint32_t   mask);                   \
130                                                                         \
131 static void                                                             \
132 neon_composite_##name (pixman_implementation_t *imp,                    \
133                        pixman_op_t              op,                     \
134                        pixman_image_t *         src_image,              \
135                        pixman_image_t *         mask_image,             \
136                        pixman_image_t *         dst_image,              \
137                        int32_t                  src_x,                  \
138                        int32_t                  src_y,                  \
139                        int32_t                  mask_x,                 \
140                        int32_t                  mask_y,                 \
141                        int32_t                  dest_x,                 \
142                        int32_t                  dest_y,                 \
143                        int32_t                  width,                  \
144                        int32_t                  height)                 \
145 {                                                                       \
146     dst_type  *dst_line;                                                \
147     src_type  *src_line;                                                \
148     int32_t    dst_stride, src_stride;                                  \
149     uint32_t   mask;                                                    \
150                                                                         \
151     mask = _pixman_image_get_solid (mask_image, dst_image->bits.format);\
152                                                                         \
153     if (mask == 0)                                                      \
154         return;                                                         \
155                                                                         \
156     PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, dst_type,         \
157                            dst_stride, dst_line, dst_cnt);              \
158     PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, src_type,           \
159                            src_stride, src_line, src_cnt);              \
160                                                                         \
161     pixman_composite_##name##_asm_neon (width, height,                  \
162                                         dst_line, dst_stride,           \
163                                         src_line, src_stride,           \
164                                         mask);                          \
165 }
166
167 #define BIND_SRC_MASK_DST(name, src_type, src_cnt, mask_type, mask_cnt, \
168                           dst_type, dst_cnt)                            \
169 void                                                                    \
170 pixman_composite_##name##_asm_neon (int32_t    w,                       \
171                                     int32_t    h,                       \
172                                     dst_type  *dst,                     \
173                                     int32_t    dst_stride,              \
174                                     src_type  *src,                     \
175                                     int32_t    src_stride,              \
176                                     mask_type *mask,                    \
177                                     int32_t    mask_stride);            \
178                                                                         \
179 static void                                                             \
180 neon_composite_##name (pixman_implementation_t *imp,                    \
181                        pixman_op_t              op,                     \
182                        pixman_image_t *         src_image,              \
183                        pixman_image_t *         mask_image,             \
184                        pixman_image_t *         dst_image,              \
185                        int32_t                  src_x,                  \
186                        int32_t                  src_y,                  \
187                        int32_t                  mask_x,                 \
188                        int32_t                  mask_y,                 \
189                        int32_t                  dest_x,                 \
190                        int32_t                  dest_y,                 \
191                        int32_t                  width,                  \
192                        int32_t                  height)                 \
193 {                                                                       \
194     dst_type  *dst_line;                                                \
195     src_type  *src_line;                                                \
196     mask_type *mask_line;                                               \
197     int32_t    dst_stride, src_stride, mask_stride;                     \
198                                                                         \
199     PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, dst_type,         \
200                            dst_stride, dst_line, dst_cnt);              \
201     PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, src_type,           \
202                            src_stride, src_line, src_cnt);              \
203     PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, mask_type,       \
204                            mask_stride, mask_line, mask_cnt);           \
205                                                                         \
206     pixman_composite_##name##_asm_neon (width, height,                  \
207                                         dst_line, dst_stride,           \
208                                         src_line, src_stride,           \
209                                         mask_line, mask_stride);        \
210 }
211
212
213 BIND_SRC_NULL_DST(src_8888_8888, uint32_t, 1, uint32_t, 1)
214 BIND_SRC_NULL_DST(src_0565_0565, uint16_t, 1, uint16_t, 1)
215 BIND_SRC_NULL_DST(src_0888_0888, uint8_t, 3, uint8_t, 3)
216 BIND_SRC_NULL_DST(src_8888_0565, uint32_t, 1, uint16_t, 1)
217 BIND_SRC_NULL_DST(add_8000_8000, uint8_t, 1, uint8_t, 1)
218
219 BIND_SRC_NULL_DST(over_8888_0565, uint32_t, 1, uint16_t, 1)
220 BIND_SRC_NULL_DST(over_8888_8888, uint32_t, 1, uint32_t, 1)
221
222 BIND_N_MASK_DST(over_n_8_0565, uint8_t, 1, uint16_t, 1)
223 BIND_N_MASK_DST(over_n_8_8888, uint8_t, 1, uint32_t, 1)
224 BIND_N_MASK_DST(add_n_8_8, uint8_t, 1, uint8_t, 1)
225
226 BIND_SRC_N_DST(over_8888_n_8888, uint32_t, 1, uint32_t, 1)
227
228 BIND_SRC_MASK_DST(add_8_8_8, uint8_t, 1, uint8_t, 1, uint8_t, 1)
229
230 void
231 pixman_composite_src_n_8_asm_neon (int32_t   w,
232                                    int32_t   h,
233                                    uint8_t  *dst,
234                                    int32_t   dst_stride,
235                                    uint8_t   src);
236
237 void
238 pixman_composite_src_n_0565_asm_neon (int32_t   w,
239                                       int32_t   h,
240                                       uint16_t *dst,
241                                       int32_t   dst_stride,
242                                       uint16_t  src);
243
244 void
245 pixman_composite_src_n_8888_asm_neon (int32_t   w,
246                                       int32_t   h,
247                                       uint32_t *dst,
248                                       int32_t   dst_stride,
249                                       uint32_t  src);
250
251 static pixman_bool_t
252 pixman_fill_neon (uint32_t *bits,
253                   int       stride,
254                   int       bpp,
255                   int       x,
256                   int       y,
257                   int       width,
258                   int       height,
259                   uint32_t  _xor)
260 {
261     /* stride is always multiple of 32bit units in pixman */
262     uint32_t byte_stride = stride * sizeof(uint32_t);
263
264     switch (bpp)
265     {
266     case 8:
267         pixman_composite_src_n_8_asm_neon (
268                 width,
269                 height,
270                 (uint8_t *)(((char *) bits) + y * byte_stride + x),
271                 byte_stride,
272                 _xor & 0xff);
273         return TRUE;
274     case 16:
275         pixman_composite_src_n_0565_asm_neon (
276                 width,
277                 height,
278                 (uint16_t *)(((char *) bits) + y * byte_stride + x * 2),
279                 byte_stride / 2,
280                 _xor & 0xffff);
281         return TRUE;
282     case 32:
283         pixman_composite_src_n_8888_asm_neon (
284                 width,
285                 height,
286                 (uint32_t *)(((char *) bits) + y * byte_stride + x * 4),
287                 byte_stride / 4,
288                 _xor);
289         return TRUE;
290     default:
291         return FALSE;
292     }
293 }
294
295 static pixman_bool_t
296 pixman_blt_neon (uint32_t *src_bits,
297                  uint32_t *dst_bits,
298                  int       src_stride,
299                  int       dst_stride,
300                  int       src_bpp,
301                  int       dst_bpp,
302                  int       src_x,
303                  int       src_y,
304                  int       dst_x,
305                  int       dst_y,
306                  int       width,
307                  int       height)
308 {
309     if (src_bpp != dst_bpp)
310         return FALSE;
311
312     switch (src_bpp)
313     {
314     case 16:
315         pixman_composite_src_0565_0565_asm_neon (
316                 width, height,
317                 (uint16_t *)(((char *) dst_bits) +
318                 dst_y * dst_stride * 4 + dst_x * 2), dst_stride * 2,
319                 (uint16_t *)(((char *) src_bits) +
320                 src_y * src_stride * 4 + src_x * 2), src_stride * 2);
321         return TRUE;
322     case 32:
323         pixman_composite_src_8888_8888_asm_neon (
324                 width, height,
325                 (uint32_t *)(((char *) dst_bits) +
326                 dst_y * dst_stride * 4 + dst_x * 4), dst_stride,
327                 (uint32_t *)(((char *) src_bits) +
328                 src_y * src_stride * 4 + src_x * 4), src_stride);
329         return TRUE;
330     default:
331         return FALSE;
332     }
333 }
334
335 static const pixman_fast_path_t arm_neon_fast_path_array[] =
336 {
337     { PIXMAN_OP_SRC,  PIXMAN_r5g6b5,   PIXMAN_null,     PIXMAN_r5g6b5,   neon_composite_src_0565_0565    },
338     { PIXMAN_OP_SRC,  PIXMAN_b5g6r5,   PIXMAN_null,     PIXMAN_b5g6r5,   neon_composite_src_0565_0565    },
339     { PIXMAN_OP_SRC,  PIXMAN_a8r8g8b8, PIXMAN_null,     PIXMAN_r5g6b5,   neon_composite_src_8888_0565    },
340     { PIXMAN_OP_SRC,  PIXMAN_x8r8g8b8, PIXMAN_null,     PIXMAN_r5g6b5,   neon_composite_src_8888_0565    },
341     { PIXMAN_OP_SRC,  PIXMAN_a8b8g8r8, PIXMAN_null,     PIXMAN_b5g6r5,   neon_composite_src_8888_0565    },
342     { PIXMAN_OP_SRC,  PIXMAN_x8b8g8r8, PIXMAN_null,     PIXMAN_b5g6r5,   neon_composite_src_8888_0565    },
343     { PIXMAN_OP_SRC,  PIXMAN_a8r8g8b8, PIXMAN_null,     PIXMAN_x8r8g8b8, neon_composite_src_8888_8888    },
344     { PIXMAN_OP_SRC,  PIXMAN_x8r8g8b8, PIXMAN_null,     PIXMAN_x8r8g8b8, neon_composite_src_8888_8888    },
345     { PIXMAN_OP_SRC,  PIXMAN_a8b8g8r8, PIXMAN_null,     PIXMAN_x8b8g8r8, neon_composite_src_8888_8888    },
346     { PIXMAN_OP_SRC,  PIXMAN_x8b8g8r8, PIXMAN_null,     PIXMAN_x8b8g8r8, neon_composite_src_8888_8888    },
347     { PIXMAN_OP_SRC,  PIXMAN_r8g8b8,   PIXMAN_null,     PIXMAN_r8g8b8,   neon_composite_src_0888_0888    },
348     { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8,       PIXMAN_r5g6b5,   neon_composite_over_n_8_0565    },
349     { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8,       PIXMAN_b5g6r5,   neon_composite_over_n_8_0565    },
350     { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8,       PIXMAN_a8r8g8b8, neon_composite_over_n_8_8888    },
351     { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8,       PIXMAN_x8r8g8b8, neon_composite_over_n_8_8888    },
352     { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8,       PIXMAN_a8b8g8r8, neon_composite_over_n_8_8888    },
353     { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8,       PIXMAN_x8b8g8r8, neon_composite_over_n_8_8888    },
354     { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_solid,    PIXMAN_a8r8g8b8, neon_composite_over_8888_n_8888 },
355     { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_solid,    PIXMAN_x8r8g8b8, neon_composite_over_8888_n_8888 },
356     { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_null,     PIXMAN_r5g6b5,   neon_composite_over_8888_0565   },
357     { PIXMAN_OP_OVER, PIXMAN_a8b8g8r8, PIXMAN_null,     PIXMAN_b5g6r5,   neon_composite_over_8888_0565   },
358     { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_null,     PIXMAN_a8r8g8b8, neon_composite_over_8888_8888   },
359     { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_null,     PIXMAN_x8r8g8b8, neon_composite_over_8888_8888   },
360     { PIXMAN_OP_OVER, PIXMAN_a8b8g8r8, PIXMAN_null,     PIXMAN_a8b8g8r8, neon_composite_over_8888_8888   },
361     { PIXMAN_OP_OVER, PIXMAN_a8b8g8r8, PIXMAN_null,     PIXMAN_x8b8g8r8, neon_composite_over_8888_8888   },
362     { PIXMAN_OP_ADD,  PIXMAN_solid,    PIXMAN_a8,       PIXMAN_a8,       neon_composite_add_n_8_8        },
363     { PIXMAN_OP_ADD,  PIXMAN_a8,       PIXMAN_a8,       PIXMAN_a8,       neon_composite_add_8_8_8        },
364     { PIXMAN_OP_ADD,  PIXMAN_a8,       PIXMAN_null,     PIXMAN_a8,       neon_composite_add_8000_8000    },
365     { PIXMAN_OP_NONE },
366 };
367
368 const pixman_fast_path_t *const arm_neon_fast_paths = arm_neon_fast_path_array;
369
370 static void
371 arm_neon_composite (pixman_implementation_t *imp,
372                     pixman_op_t              op,
373                     pixman_image_t *         src,
374                     pixman_image_t *         mask,
375                     pixman_image_t *         dest,
376                     int32_t                  src_x,
377                     int32_t                  src_y,
378                     int32_t                  mask_x,
379                     int32_t                  mask_y,
380                     int32_t                  dest_x,
381                     int32_t                  dest_y,
382                     int32_t                  width,
383                     int32_t                  height)
384 {
385     if (_pixman_run_fast_path (arm_neon_fast_paths, imp,
386                                op, src, mask, dest,
387                                src_x, src_y,
388                                mask_x, mask_y,
389                                dest_x, dest_y,
390                                width, height))
391     {
392         return;
393     }
394
395     _pixman_implementation_composite (imp->delegate, op,
396                                       src, mask, dest,
397                                       src_x, src_y,
398                                       mask_x, mask_y,
399                                       dest_x, dest_y,
400                                       width, height);
401 }
402
403 static pixman_bool_t
404 arm_neon_blt (pixman_implementation_t *imp,
405               uint32_t *               src_bits,
406               uint32_t *               dst_bits,
407               int                      src_stride,
408               int                      dst_stride,
409               int                      src_bpp,
410               int                      dst_bpp,
411               int                      src_x,
412               int                      src_y,
413               int                      dst_x,
414               int                      dst_y,
415               int                      width,
416               int                      height)
417 {
418     if (!pixman_blt_neon (
419             src_bits, dst_bits, src_stride, dst_stride, src_bpp, dst_bpp,
420             src_x, src_y, dst_x, dst_y, width, height))
421
422     {
423         return _pixman_implementation_blt (
424             imp->delegate,
425             src_bits, dst_bits, src_stride, dst_stride, src_bpp, dst_bpp,
426             src_x, src_y, dst_x, dst_y, width, height);
427     }
428
429     return TRUE;
430 }
431
432 static pixman_bool_t
433 arm_neon_fill (pixman_implementation_t *imp,
434                uint32_t *               bits,
435                int                      stride,
436                int                      bpp,
437                int                      x,
438                int                      y,
439                int                      width,
440                int                      height,
441                uint32_t xor)
442 {
443     if (pixman_fill_neon (bits, stride, bpp, x, y, width, height, xor))
444         return TRUE;
445
446     return _pixman_implementation_fill (
447         imp->delegate, bits, stride, bpp, x, y, width, height, xor);
448 }
449
450 pixman_implementation_t *
451 _pixman_implementation_create_arm_neon (void)
452 {
453     pixman_implementation_t *general = _pixman_implementation_create_fast_path ();
454     pixman_implementation_t *imp = _pixman_implementation_create (general);
455
456     imp->composite = arm_neon_composite;
457     imp->blt = arm_neon_blt;
458     imp->fill = arm_neon_fill;
459
460     return imp;
461 }