pixman-arm-simd.c revision 1176bdada62cabc6ec4b0308a930e83b679d5d36
1/*
2 * Copyright © 2008 Mozilla Corporation
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 Mozilla Corporation not be used in
9 * advertising or publicity pertaining to distribution of the software without
10 * specific, written prior permission.  Mozilla Corporation 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:  Jeff Muizelaar (jeff@infidigm.net)
24 *
25 */
26#ifdef HAVE_CONFIG_H
27#include <config.h>
28#endif
29
30#include "pixman-private.h"
31#include "pixman-arm-common.h"
32#include "pixman-inlines.h"
33
34PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (armv6, src_8888_8888,
35		                   uint32_t, 1, uint32_t, 1)
36PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (armv6, src_x888_8888,
37                                   uint32_t, 1, uint32_t, 1)
38PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (armv6, src_0565_0565,
39                                   uint16_t, 1, uint16_t, 1)
40PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (armv6, src_8_8,
41                                   uint8_t, 1, uint8_t, 1)
42PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (armv6, src_0565_8888,
43                                   uint16_t, 1, uint32_t, 1)
44
45PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (armv6, add_8_8,
46                                   uint8_t, 1, uint8_t, 1)
47PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (armv6, over_8888_8888,
48                                   uint32_t, 1, uint32_t, 1)
49
50PIXMAN_ARM_BIND_FAST_PATH_SRC_N_DST (SKIP_ZERO_MASK, armv6, over_8888_n_8888,
51                                     uint32_t, 1, uint32_t, 1)
52
53PIXMAN_ARM_BIND_FAST_PATH_N_MASK_DST (SKIP_ZERO_SRC, armv6, over_n_8_8888,
54                                      uint8_t, 1, uint32_t, 1)
55
56PIXMAN_ARM_BIND_SCALED_NEAREST_SRC_DST (armv6, 0565_0565, SRC,
57                                        uint16_t, uint16_t)
58PIXMAN_ARM_BIND_SCALED_NEAREST_SRC_DST (armv6, 8888_8888, SRC,
59                                        uint32_t, uint32_t)
60
61void
62pixman_composite_src_n_8888_asm_armv6 (int32_t   w,
63                                       int32_t   h,
64                                       uint32_t *dst,
65                                       int32_t   dst_stride,
66                                       uint32_t  src);
67
68void
69pixman_composite_src_n_0565_asm_armv6 (int32_t   w,
70                                       int32_t   h,
71                                       uint16_t *dst,
72                                       int32_t   dst_stride,
73                                       uint16_t  src);
74
75void
76pixman_composite_src_n_8_asm_armv6 (int32_t   w,
77                                    int32_t   h,
78                                    uint8_t  *dst,
79                                    int32_t   dst_stride,
80                                    uint8_t  src);
81
82static pixman_bool_t
83arm_simd_fill (pixman_implementation_t *imp,
84               uint32_t *               bits,
85               int                      stride, /* in 32-bit words */
86               int                      bpp,
87               int                      x,
88               int                      y,
89               int                      width,
90               int                      height,
91               uint32_t                 _xor)
92{
93    /* stride is always multiple of 32bit units in pixman */
94    uint32_t byte_stride = stride * sizeof(uint32_t);
95
96    switch (bpp)
97    {
98    case 8:
99	pixman_composite_src_n_8_asm_armv6 (
100		width,
101		height,
102		(uint8_t *)(((char *) bits) + y * byte_stride + x),
103		byte_stride,
104		_xor & 0xff);
105	return TRUE;
106    case 16:
107	pixman_composite_src_n_0565_asm_armv6 (
108		width,
109		height,
110		(uint16_t *)(((char *) bits) + y * byte_stride + x * 2),
111		byte_stride / 2,
112		_xor & 0xffff);
113	return TRUE;
114    case 32:
115	pixman_composite_src_n_8888_asm_armv6 (
116		width,
117		height,
118		(uint32_t *)(((char *) bits) + y * byte_stride + x * 4),
119		byte_stride / 4,
120		_xor);
121	return TRUE;
122    default:
123	return FALSE;
124    }
125}
126
127static pixman_bool_t
128arm_simd_blt (pixman_implementation_t *imp,
129              uint32_t *               src_bits,
130              uint32_t *               dst_bits,
131              int                      src_stride, /* in 32-bit words */
132              int                      dst_stride, /* in 32-bit words */
133              int                      src_bpp,
134              int                      dst_bpp,
135              int                      src_x,
136              int                      src_y,
137              int                      dest_x,
138              int                      dest_y,
139              int                      width,
140              int                      height)
141{
142    if (src_bpp != dst_bpp)
143	return FALSE;
144
145    switch (src_bpp)
146    {
147    case 8:
148        pixman_composite_src_8_8_asm_armv6 (
149                width, height,
150                (uint8_t *)(((char *) dst_bits) +
151                dest_y * dst_stride * 4 + dest_x * 1), dst_stride * 4,
152                (uint8_t *)(((char *) src_bits) +
153                src_y * src_stride * 4 + src_x * 1), src_stride * 4);
154        return TRUE;
155    case 16:
156	pixman_composite_src_0565_0565_asm_armv6 (
157		width, height,
158		(uint16_t *)(((char *) dst_bits) +
159		dest_y * dst_stride * 4 + dest_x * 2), dst_stride * 2,
160		(uint16_t *)(((char *) src_bits) +
161		src_y * src_stride * 4 + src_x * 2), src_stride * 2);
162	return TRUE;
163    case 32:
164	pixman_composite_src_8888_8888_asm_armv6 (
165		width, height,
166		(uint32_t *)(((char *) dst_bits) +
167		dest_y * dst_stride * 4 + dest_x * 4), dst_stride,
168		(uint32_t *)(((char *) src_bits) +
169		src_y * src_stride * 4 + src_x * 4), src_stride);
170	return TRUE;
171    default:
172	return FALSE;
173    }
174}
175
176static const pixman_fast_path_t arm_simd_fast_paths[] =
177{
178    PIXMAN_STD_FAST_PATH (SRC, a8r8g8b8, null, a8r8g8b8, armv6_composite_src_8888_8888),
179    PIXMAN_STD_FAST_PATH (SRC, a8b8g8r8, null, a8b8g8r8, armv6_composite_src_8888_8888),
180    PIXMAN_STD_FAST_PATH (SRC, a8r8g8b8, null, x8r8g8b8, armv6_composite_src_8888_8888),
181    PIXMAN_STD_FAST_PATH (SRC, a8b8g8r8, null, x8b8g8r8, armv6_composite_src_8888_8888),
182    PIXMAN_STD_FAST_PATH (SRC, x8r8g8b8, null, x8r8g8b8, armv6_composite_src_8888_8888),
183    PIXMAN_STD_FAST_PATH (SRC, x8b8g8r8, null, x8b8g8r8, armv6_composite_src_8888_8888),
184
185    PIXMAN_STD_FAST_PATH (SRC, x8b8g8r8, null, a8b8g8r8, armv6_composite_src_x888_8888),
186    PIXMAN_STD_FAST_PATH (SRC, x8r8g8b8, null, a8r8g8b8, armv6_composite_src_x888_8888),
187
188    PIXMAN_STD_FAST_PATH (SRC, r5g6b5, null, r5g6b5, armv6_composite_src_0565_0565),
189    PIXMAN_STD_FAST_PATH (SRC, b5g6r5, null, b5g6r5, armv6_composite_src_0565_0565),
190    PIXMAN_STD_FAST_PATH (SRC, a1r5g5b5, null, a1r5g5b5, armv6_composite_src_0565_0565),
191    PIXMAN_STD_FAST_PATH (SRC, a1b5g5r5, null, a1b5g5r5, armv6_composite_src_0565_0565),
192    PIXMAN_STD_FAST_PATH (SRC, a1r5g5b5, null, x1r5g5b5, armv6_composite_src_0565_0565),
193    PIXMAN_STD_FAST_PATH (SRC, a1b5g5r5, null, x1b5g5r5, armv6_composite_src_0565_0565),
194    PIXMAN_STD_FAST_PATH (SRC, x1r5g5b5, null, x1r5g5b5, armv6_composite_src_0565_0565),
195    PIXMAN_STD_FAST_PATH (SRC, x1b5g5r5, null, x1b5g5r5, armv6_composite_src_0565_0565),
196    PIXMAN_STD_FAST_PATH (SRC, a4r4g4b4, null, a4r4g4b4, armv6_composite_src_0565_0565),
197    PIXMAN_STD_FAST_PATH (SRC, a4b4g4r4, null, a4b4g4r4, armv6_composite_src_0565_0565),
198    PIXMAN_STD_FAST_PATH (SRC, a4r4g4b4, null, x4r4g4b4, armv6_composite_src_0565_0565),
199    PIXMAN_STD_FAST_PATH (SRC, a4b4g4r4, null, x4b4g4r4, armv6_composite_src_0565_0565),
200    PIXMAN_STD_FAST_PATH (SRC, x4r4g4b4, null, x4r4g4b4, armv6_composite_src_0565_0565),
201    PIXMAN_STD_FAST_PATH (SRC, x4b4g4r4, null, x4b4g4r4, armv6_composite_src_0565_0565),
202
203    PIXMAN_STD_FAST_PATH (SRC, a8, null, a8, armv6_composite_src_8_8),
204    PIXMAN_STD_FAST_PATH (SRC, r3g3b2, null, r3g3b2, armv6_composite_src_8_8),
205    PIXMAN_STD_FAST_PATH (SRC, b2g3r3, null, b2g3r3, armv6_composite_src_8_8),
206    PIXMAN_STD_FAST_PATH (SRC, a2r2g2b2, null, a2r2g2b2, armv6_composite_src_8_8),
207    PIXMAN_STD_FAST_PATH (SRC, a2b2g2r2, null, a2b2g2r2, armv6_composite_src_8_8),
208    PIXMAN_STD_FAST_PATH (SRC, c8, null, c8, armv6_composite_src_8_8),
209    PIXMAN_STD_FAST_PATH (SRC, g8, null, g8, armv6_composite_src_8_8),
210    PIXMAN_STD_FAST_PATH (SRC, x4a4, null, x4a4, armv6_composite_src_8_8),
211    PIXMAN_STD_FAST_PATH (SRC, x4c4, null, x4c4, armv6_composite_src_8_8),
212    PIXMAN_STD_FAST_PATH (SRC, x4g4, null, x4g4, armv6_composite_src_8_8),
213
214    PIXMAN_STD_FAST_PATH (SRC, r5g6b5, null, a8r8g8b8, armv6_composite_src_0565_8888),
215    PIXMAN_STD_FAST_PATH (SRC, r5g6b5, null, x8r8g8b8, armv6_composite_src_0565_8888),
216    PIXMAN_STD_FAST_PATH (SRC, b5g6r5, null, a8b8g8r8, armv6_composite_src_0565_8888),
217    PIXMAN_STD_FAST_PATH (SRC, b5g6r5, null, x8b8g8r8, armv6_composite_src_0565_8888),
218
219    PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, null, a8r8g8b8, armv6_composite_over_8888_8888),
220    PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, null, x8r8g8b8, armv6_composite_over_8888_8888),
221    PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, null, a8b8g8r8, armv6_composite_over_8888_8888),
222    PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, null, x8b8g8r8, armv6_composite_over_8888_8888),
223    PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, solid, a8r8g8b8, armv6_composite_over_8888_n_8888),
224    PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, solid, x8r8g8b8, armv6_composite_over_8888_n_8888),
225    PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, solid, a8b8g8r8, armv6_composite_over_8888_n_8888),
226    PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, solid, x8b8g8r8, armv6_composite_over_8888_n_8888),
227
228    PIXMAN_STD_FAST_PATH (ADD, a8, null, a8, armv6_composite_add_8_8),
229
230    PIXMAN_STD_FAST_PATH (OVER, solid, a8, a8r8g8b8, armv6_composite_over_n_8_8888),
231    PIXMAN_STD_FAST_PATH (OVER, solid, a8, x8r8g8b8, armv6_composite_over_n_8_8888),
232    PIXMAN_STD_FAST_PATH (OVER, solid, a8, a8b8g8r8, armv6_composite_over_n_8_8888),
233    PIXMAN_STD_FAST_PATH (OVER, solid, a8, x8b8g8r8, armv6_composite_over_n_8_8888),
234
235    PIXMAN_ARM_SIMPLE_NEAREST_FAST_PATH (SRC, r5g6b5, r5g6b5, armv6_0565_0565),
236    PIXMAN_ARM_SIMPLE_NEAREST_FAST_PATH (SRC, b5g6r5, b5g6r5, armv6_0565_0565),
237
238    PIXMAN_ARM_SIMPLE_NEAREST_FAST_PATH (SRC, a8r8g8b8, a8r8g8b8, armv6_8888_8888),
239    PIXMAN_ARM_SIMPLE_NEAREST_FAST_PATH (SRC, a8r8g8b8, x8r8g8b8, armv6_8888_8888),
240    PIXMAN_ARM_SIMPLE_NEAREST_FAST_PATH (SRC, x8r8g8b8, x8r8g8b8, armv6_8888_8888),
241    PIXMAN_ARM_SIMPLE_NEAREST_FAST_PATH (SRC, a8b8g8r8, a8b8g8r8, armv6_8888_8888),
242    PIXMAN_ARM_SIMPLE_NEAREST_FAST_PATH (SRC, a8b8g8r8, x8b8g8r8, armv6_8888_8888),
243    PIXMAN_ARM_SIMPLE_NEAREST_FAST_PATH (SRC, x8b8g8r8, x8b8g8r8, armv6_8888_8888),
244
245    { PIXMAN_OP_NONE },
246};
247
248pixman_implementation_t *
249_pixman_implementation_create_arm_simd (pixman_implementation_t *fallback)
250{
251    pixman_implementation_t *imp = _pixman_implementation_create (fallback, arm_simd_fast_paths);
252
253    imp->blt = arm_simd_blt;
254    imp->fill = arm_simd_fill;
255
256    return imp;
257}
258