2 * Copyright © 2009 ARM Ltd, Movial Creative Technologies Oy
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.
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
23 * Author: Ian Rickards (ian.rickards@arm.com)
24 * Author: Jonathan Morton (jonathan.morton@movial.com)
25 * Author: Markku Vire (markku.vire@movial.com)
34 #include "pixman-private.h"
36 #define BIND_SRC_NULL_DST(name, src_type, src_cnt, dst_type, dst_cnt) \
38 pixman_composite_##name##_asm_neon (int32_t w, \
43 int32_t src_stride); \
46 neon_composite_##name (pixman_implementation_t *imp, \
48 pixman_image_t * src_image, \
49 pixman_image_t * mask_image, \
50 pixman_image_t * dst_image, \
62 int32_t dst_stride, src_stride; \
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); \
69 pixman_composite_##name##_asm_neon (width, height, \
70 dst_line, dst_stride, \
71 src_line, src_stride); \
74 #define BIND_N_MASK_DST(name, mask_type, mask_cnt, dst_type, dst_cnt) \
76 pixman_composite_##name##_asm_neon (int32_t w, \
83 int32_t mask_stride); \
86 neon_composite_##name (pixman_implementation_t *imp, \
88 pixman_image_t * src_image, \
89 pixman_image_t * mask_image, \
90 pixman_image_t * dst_image, \
100 dst_type *dst_line; \
101 mask_type *mask_line; \
102 int32_t dst_stride, mask_stride; \
105 src = _pixman_image_get_solid (src_image, dst_image->bits.format); \
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); \
115 pixman_composite_##name##_asm_neon (width, height, \
116 dst_line, dst_stride, \
118 mask_line, mask_stride); \
121 #define BIND_SRC_N_DST(name, src_type, src_cnt, dst_type, dst_cnt) \
123 pixman_composite_##name##_asm_neon (int32_t w, \
126 int32_t dst_stride, \
128 int32_t src_stride, \
132 neon_composite_##name (pixman_implementation_t *imp, \
134 pixman_image_t * src_image, \
135 pixman_image_t * mask_image, \
136 pixman_image_t * dst_image, \
146 dst_type *dst_line; \
147 src_type *src_line; \
148 int32_t dst_stride, src_stride; \
151 mask = _pixman_image_get_solid (mask_image, dst_image->bits.format);\
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); \
161 pixman_composite_##name##_asm_neon (width, height, \
162 dst_line, dst_stride, \
163 src_line, src_stride, \
167 #define BIND_SRC_MASK_DST(name, src_type, src_cnt, mask_type, mask_cnt, \
170 pixman_composite_##name##_asm_neon (int32_t w, \
173 int32_t dst_stride, \
175 int32_t src_stride, \
177 int32_t mask_stride); \
180 neon_composite_##name (pixman_implementation_t *imp, \
182 pixman_image_t * src_image, \
183 pixman_image_t * mask_image, \
184 pixman_image_t * dst_image, \
194 dst_type *dst_line; \
195 src_type *src_line; \
196 mask_type *mask_line; \
197 int32_t dst_stride, src_stride, mask_stride; \
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); \
206 pixman_composite_##name##_asm_neon (width, height, \
207 dst_line, dst_stride, \
208 src_line, src_stride, \
209 mask_line, mask_stride); \
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 BIND_SRC_NULL_DST(add_8888_8888, uint32_t, 1, uint32_t, 1)
220 BIND_SRC_NULL_DST(over_8888_0565, uint32_t, 1, uint16_t, 1)
221 BIND_SRC_NULL_DST(over_8888_8888, uint32_t, 1, uint32_t, 1)
223 BIND_N_MASK_DST(over_n_8_0565, uint8_t, 1, uint16_t, 1)
224 BIND_N_MASK_DST(over_n_8_8888, uint8_t, 1, uint32_t, 1)
225 BIND_N_MASK_DST(add_n_8_8, uint8_t, 1, uint8_t, 1)
227 BIND_SRC_N_DST(over_8888_n_8888, uint32_t, 1, uint32_t, 1)
229 BIND_SRC_MASK_DST(add_8_8_8, uint8_t, 1, uint8_t, 1, uint8_t, 1)
230 BIND_SRC_MASK_DST(add_8888_8888_8888, uint32_t, 1, uint32_t, 1, uint32_t, 1)
231 BIND_SRC_MASK_DST(over_8888_8_8888, uint32_t, 1, uint8_t, 1, uint32_t, 1)
232 BIND_SRC_MASK_DST(over_8888_8888_8888, uint32_t, 1, uint32_t, 1, uint32_t, 1)
235 pixman_composite_src_n_8_asm_neon (int32_t w,
242 pixman_composite_src_n_0565_asm_neon (int32_t w,
249 pixman_composite_src_n_8888_asm_neon (int32_t w,
256 pixman_fill_neon (uint32_t *bits,
265 /* stride is always multiple of 32bit units in pixman */
266 uint32_t byte_stride = stride * sizeof(uint32_t);
271 pixman_composite_src_n_8_asm_neon (
274 (uint8_t *)(((char *) bits) + y * byte_stride + x),
279 pixman_composite_src_n_0565_asm_neon (
282 (uint16_t *)(((char *) bits) + y * byte_stride + x * 2),
287 pixman_composite_src_n_8888_asm_neon (
290 (uint32_t *)(((char *) bits) + y * byte_stride + x * 4),
300 pixman_blt_neon (uint32_t *src_bits,
313 if (src_bpp != dst_bpp)
319 pixman_composite_src_0565_0565_asm_neon (
321 (uint16_t *)(((char *) dst_bits) +
322 dst_y * dst_stride * 4 + dst_x * 2), dst_stride * 2,
323 (uint16_t *)(((char *) src_bits) +
324 src_y * src_stride * 4 + src_x * 2), src_stride * 2);
327 pixman_composite_src_8888_8888_asm_neon (
329 (uint32_t *)(((char *) dst_bits) +
330 dst_y * dst_stride * 4 + dst_x * 4), dst_stride,
331 (uint32_t *)(((char *) src_bits) +
332 src_y * src_stride * 4 + src_x * 4), src_stride);
339 static const pixman_fast_path_t arm_neon_fast_path_array[] =
341 { PIXMAN_OP_SRC, PIXMAN_r5g6b5, PIXMAN_null, PIXMAN_r5g6b5, neon_composite_src_0565_0565 },
342 { PIXMAN_OP_SRC, PIXMAN_b5g6r5, PIXMAN_null, PIXMAN_b5g6r5, neon_composite_src_0565_0565 },
343 { PIXMAN_OP_SRC, PIXMAN_a8r8g8b8, PIXMAN_null, PIXMAN_r5g6b5, neon_composite_src_8888_0565 },
344 { PIXMAN_OP_SRC, PIXMAN_x8r8g8b8, PIXMAN_null, PIXMAN_r5g6b5, neon_composite_src_8888_0565 },
345 { PIXMAN_OP_SRC, PIXMAN_a8b8g8r8, PIXMAN_null, PIXMAN_b5g6r5, neon_composite_src_8888_0565 },
346 { PIXMAN_OP_SRC, PIXMAN_x8b8g8r8, PIXMAN_null, PIXMAN_b5g6r5, neon_composite_src_8888_0565 },
347 { PIXMAN_OP_SRC, PIXMAN_a8r8g8b8, PIXMAN_null, PIXMAN_x8r8g8b8, neon_composite_src_8888_8888 },
348 { PIXMAN_OP_SRC, PIXMAN_x8r8g8b8, PIXMAN_null, PIXMAN_x8r8g8b8, neon_composite_src_8888_8888 },
349 { PIXMAN_OP_SRC, PIXMAN_a8b8g8r8, PIXMAN_null, PIXMAN_x8b8g8r8, neon_composite_src_8888_8888 },
350 { PIXMAN_OP_SRC, PIXMAN_x8b8g8r8, PIXMAN_null, PIXMAN_x8b8g8r8, neon_composite_src_8888_8888 },
351 { PIXMAN_OP_SRC, PIXMAN_r8g8b8, PIXMAN_null, PIXMAN_r8g8b8, neon_composite_src_0888_0888 },
352 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8, PIXMAN_r5g6b5, neon_composite_over_n_8_0565 },
353 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8, PIXMAN_b5g6r5, neon_composite_over_n_8_0565 },
354 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8, PIXMAN_a8r8g8b8, neon_composite_over_n_8_8888 },
355 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8, PIXMAN_x8r8g8b8, neon_composite_over_n_8_8888 },
356 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8, PIXMAN_a8b8g8r8, neon_composite_over_n_8_8888 },
357 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8, PIXMAN_x8b8g8r8, neon_composite_over_n_8_8888 },
358 { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_solid, PIXMAN_a8r8g8b8, neon_composite_over_8888_n_8888 },
359 { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_solid, PIXMAN_x8r8g8b8, neon_composite_over_8888_n_8888 },
360 { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_a8, PIXMAN_a8r8g8b8, neon_composite_over_8888_8_8888 },
361 { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_a8, PIXMAN_x8r8g8b8, neon_composite_over_8888_8_8888 },
362 { PIXMAN_OP_OVER, PIXMAN_a8b8g8r8, PIXMAN_a8, PIXMAN_a8b8g8r8, neon_composite_over_8888_8_8888 },
363 { PIXMAN_OP_OVER, PIXMAN_a8b8g8r8, PIXMAN_a8, PIXMAN_x8b8g8r8, neon_composite_over_8888_8_8888 },
364 { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_a8r8g8b8, PIXMAN_a8r8g8b8, neon_composite_over_8888_8888_8888 },
365 { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_null, PIXMAN_r5g6b5, neon_composite_over_8888_0565 },
366 { PIXMAN_OP_OVER, PIXMAN_a8b8g8r8, PIXMAN_null, PIXMAN_b5g6r5, neon_composite_over_8888_0565 },
367 { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_null, PIXMAN_a8r8g8b8, neon_composite_over_8888_8888 },
368 { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_null, PIXMAN_x8r8g8b8, neon_composite_over_8888_8888 },
369 { PIXMAN_OP_OVER, PIXMAN_a8b8g8r8, PIXMAN_null, PIXMAN_a8b8g8r8, neon_composite_over_8888_8888 },
370 { PIXMAN_OP_OVER, PIXMAN_a8b8g8r8, PIXMAN_null, PIXMAN_x8b8g8r8, neon_composite_over_8888_8888 },
371 { PIXMAN_OP_ADD, PIXMAN_solid, PIXMAN_a8, PIXMAN_a8, neon_composite_add_n_8_8 },
372 { PIXMAN_OP_ADD, PIXMAN_a8, PIXMAN_a8, PIXMAN_a8, neon_composite_add_8_8_8 },
373 { PIXMAN_OP_ADD, PIXMAN_a8r8g8b8, PIXMAN_a8r8g8b8, PIXMAN_a8r8g8b8, neon_composite_add_8888_8888_8888 },
374 { PIXMAN_OP_ADD, PIXMAN_a8, PIXMAN_null, PIXMAN_a8, neon_composite_add_8000_8000 },
375 { PIXMAN_OP_ADD, PIXMAN_a8r8g8b8, PIXMAN_null, PIXMAN_a8r8g8b8, neon_composite_add_8888_8888 },
376 { PIXMAN_OP_ADD, PIXMAN_a8b8g8r8, PIXMAN_null, PIXMAN_a8b8g8r8, neon_composite_add_8888_8888 },
380 const pixman_fast_path_t *const arm_neon_fast_paths = arm_neon_fast_path_array;
383 arm_neon_composite (pixman_implementation_t *imp,
385 pixman_image_t * src,
386 pixman_image_t * mask,
387 pixman_image_t * dest,
397 if (_pixman_run_fast_path (arm_neon_fast_paths, imp,
407 _pixman_implementation_composite (imp->delegate, op,
416 arm_neon_blt (pixman_implementation_t *imp,
430 if (!pixman_blt_neon (
431 src_bits, dst_bits, src_stride, dst_stride, src_bpp, dst_bpp,
432 src_x, src_y, dst_x, dst_y, width, height))
435 return _pixman_implementation_blt (
437 src_bits, dst_bits, src_stride, dst_stride, src_bpp, dst_bpp,
438 src_x, src_y, dst_x, dst_y, width, height);
445 arm_neon_fill (pixman_implementation_t *imp,
455 if (pixman_fill_neon (bits, stride, bpp, x, y, width, height, xor))
458 return _pixman_implementation_fill (
459 imp->delegate, bits, stride, bpp, x, y, width, height, xor);
462 pixman_implementation_t *
463 _pixman_implementation_create_arm_neon (void)
465 pixman_implementation_t *general = _pixman_implementation_create_fast_path ();
466 pixman_implementation_t *imp = _pixman_implementation_create (general);
468 imp->composite = arm_neon_composite;
469 imp->blt = arm_neon_blt;
470 imp->fill = arm_neon_fill;