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_##name##_asm_neon (int32_t w, \
43 int32_t src_stride); \
46 neon_##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_##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_##name##_asm_neon (int32_t w, \
83 int32_t mask_stride); \
86 neon_##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_##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_##name##_asm_neon (int32_t w, \
126 int32_t dst_stride, \
128 int32_t src_stride, \
132 neon_##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_##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_##name##_asm_neon (int32_t w, \
173 int32_t dst_stride, \
175 int32_t src_stride, \
177 int32_t mask_stride); \
180 neon_##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_##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(composite_src_8888_8888, uint32_t, 1, uint32_t, 1)
214 BIND_SRC_NULL_DST(composite_src_0565_0565, uint16_t, 1, uint16_t, 1)
215 BIND_SRC_NULL_DST(composite_src_0888_0888, uint8_t, 3, uint8_t, 3)
216 BIND_SRC_NULL_DST(composite_src_8888_0565, uint32_t, 1, uint16_t, 1)
217 BIND_SRC_NULL_DST(composite_add_8000_8000, uint8_t, 1, uint8_t, 1)
219 BIND_SRC_NULL_DST(composite_over_8888_0565, uint32_t, 1, uint16_t, 1)
220 BIND_SRC_NULL_DST(composite_over_8888_8888, uint32_t, 1, uint32_t, 1)
222 BIND_N_MASK_DST(composite_over_n_8_0565, uint8_t, 1, uint16_t, 1)
223 BIND_N_MASK_DST(composite_over_n_8_8888, uint8_t, 1, uint32_t, 1)
224 BIND_N_MASK_DST(composite_add_n_8_8, uint8_t, 1, uint8_t, 1)
226 BIND_SRC_N_DST(composite_over_8888_n_8888, uint32_t, 1, uint32_t, 1)
228 BIND_SRC_MASK_DST(composite_add_8_8_8, uint8_t, 1, uint8_t, 1, uint8_t, 1)
231 pixman_composite_src_n_8_asm_neon (int32_t w,
238 pixman_composite_src_n_0565_asm_neon (int32_t w,
245 pixman_composite_src_n_8888_asm_neon (int32_t w,
252 pixman_fill_neon (uint32_t *bits,
261 /* stride is always multiple of 32bit units in pixman */
262 uint32_t byte_stride = stride * sizeof(uint32_t);
267 pixman_composite_src_n_8_asm_neon (
270 (uint8_t *)(((char *) bits) + y * byte_stride + x),
275 pixman_composite_src_n_0565_asm_neon (
278 (uint16_t *)(((char *) bits) + y * byte_stride + x * 2),
283 pixman_composite_src_n_8888_asm_neon (
286 (uint32_t *)(((char *) bits) + y * byte_stride + x * 4),
295 static const pixman_fast_path_t arm_neon_fast_path_array[] =
297 { PIXMAN_OP_SRC, PIXMAN_r5g6b5, PIXMAN_null, PIXMAN_r5g6b5, neon_composite_src_0565_0565, 0 },
298 { PIXMAN_OP_SRC, PIXMAN_b5g6r5, PIXMAN_null, PIXMAN_b5g6r5, neon_composite_src_0565_0565, 0 },
299 { PIXMAN_OP_SRC, PIXMAN_a8r8g8b8, PIXMAN_null, PIXMAN_r5g6b5, neon_composite_src_8888_0565, 0 },
300 { PIXMAN_OP_SRC, PIXMAN_x8r8g8b8, PIXMAN_null, PIXMAN_r5g6b5, neon_composite_src_8888_0565, 0 },
301 { PIXMAN_OP_SRC, PIXMAN_a8b8g8r8, PIXMAN_null, PIXMAN_b5g6r5, neon_composite_src_8888_0565, 0 },
302 { PIXMAN_OP_SRC, PIXMAN_x8b8g8r8, PIXMAN_null, PIXMAN_b5g6r5, neon_composite_src_8888_0565, 0 },
303 { PIXMAN_OP_SRC, PIXMAN_a8r8g8b8, PIXMAN_null, PIXMAN_x8r8g8b8, neon_composite_src_8888_8888, 0 },
304 { PIXMAN_OP_SRC, PIXMAN_x8r8g8b8, PIXMAN_null, PIXMAN_x8r8g8b8, neon_composite_src_8888_8888, 0 },
305 { PIXMAN_OP_SRC, PIXMAN_a8b8g8r8, PIXMAN_null, PIXMAN_x8b8g8r8, neon_composite_src_8888_8888, 0 },
306 { PIXMAN_OP_SRC, PIXMAN_x8b8g8r8, PIXMAN_null, PIXMAN_x8b8g8r8, neon_composite_src_8888_8888, 0 },
307 { PIXMAN_OP_SRC, PIXMAN_r8g8b8, PIXMAN_null, PIXMAN_r8g8b8, neon_composite_src_0888_0888, 0 },
308 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8, PIXMAN_r5g6b5, neon_composite_over_n_8_0565, 0 },
309 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8, PIXMAN_b5g6r5, neon_composite_over_n_8_0565, 0 },
310 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8, PIXMAN_a8r8g8b8, neon_composite_over_n_8_8888, 0 },
311 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8, PIXMAN_x8r8g8b8, neon_composite_over_n_8_8888, 0 },
312 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8, PIXMAN_a8b8g8r8, neon_composite_over_n_8_8888, 0 },
313 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8, PIXMAN_x8b8g8r8, neon_composite_over_n_8_8888, 0 },
314 { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_a8, PIXMAN_a8r8g8b8, neon_composite_over_8888_n_8888, NEED_SOLID_MASK },
315 { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_a8, PIXMAN_x8r8g8b8, neon_composite_over_8888_n_8888, NEED_SOLID_MASK },
316 { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_null, PIXMAN_r5g6b5, neon_composite_over_8888_0565, 0 },
317 { PIXMAN_OP_OVER, PIXMAN_a8b8g8r8, PIXMAN_null, PIXMAN_b5g6r5, neon_composite_over_8888_0565, 0 },
321 const pixman_fast_path_t *const arm_neon_fast_paths = arm_neon_fast_path_array;
324 arm_neon_composite (pixman_implementation_t *imp,
326 pixman_image_t * src,
327 pixman_image_t * mask,
328 pixman_image_t * dest,
338 if (_pixman_run_fast_path (arm_neon_fast_paths, imp,
348 _pixman_implementation_composite (imp->delegate, op,
357 arm_neon_fill (pixman_implementation_t *imp,
367 if (pixman_fill_neon (bits, stride, bpp, x, y, width, height, xor))
370 return _pixman_implementation_fill (
371 imp->delegate, bits, stride, bpp, x, y, width, height, xor);
374 pixman_implementation_t *
375 _pixman_implementation_create_arm_neon (void)
377 pixman_implementation_t *general = _pixman_implementation_create_fast_path ();
378 pixman_implementation_t *imp = _pixman_implementation_create (general);
380 imp->composite = arm_neon_composite;
381 imp->fill = arm_neon_fill;