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 
34 PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (armv6, src_8888_8888,
35 		                   uint32_t, 1, uint32_t, 1)
36 PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (armv6, src_x888_8888,
37                                    uint32_t, 1, uint32_t, 1)
38 PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (armv6, src_0565_0565,
39                                    uint16_t, 1, uint16_t, 1)
40 PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (armv6, src_8_8,
41                                    uint8_t, 1, uint8_t, 1)
42 PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (armv6, src_0565_8888,
43                                    uint16_t, 1, uint32_t, 1)
44 PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (armv6, src_x888_0565,
45                                    uint32_t, 1, uint16_t, 1)
46 
47 PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (armv6, add_8_8,
48                                    uint8_t, 1, uint8_t, 1)
49 PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (armv6, over_8888_8888,
50                                    uint32_t, 1, uint32_t, 1)
51 PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (armv6, in_reverse_8888_8888,
52                                    uint32_t, 1, uint32_t, 1)
53 
54 PIXMAN_ARM_BIND_FAST_PATH_N_DST (SKIP_ZERO_SRC, armv6, over_n_8888,
55                                  uint32_t, 1)
56 PIXMAN_ARM_BIND_FAST_PATH_N_DST (0, armv6, over_reverse_n_8888,
57                                  uint32_t, 1)
58 
59 PIXMAN_ARM_BIND_FAST_PATH_SRC_N_DST (SKIP_ZERO_MASK, armv6, over_8888_n_8888,
60                                      uint32_t, 1, uint32_t, 1)
61 
62 PIXMAN_ARM_BIND_FAST_PATH_N_MASK_DST (SKIP_ZERO_SRC, armv6, over_n_8_8888,
63                                       uint8_t, 1, uint32_t, 1)
64 
65 PIXMAN_ARM_BIND_FAST_PATH_N_MASK_DST (SKIP_ZERO_SRC, armv6, over_n_8888_8888_ca,
66                                       uint32_t, 1, uint32_t, 1)
67 
68 PIXMAN_ARM_BIND_SCALED_NEAREST_SRC_DST (armv6, 0565_0565, SRC,
69                                         uint16_t, uint16_t)
70 PIXMAN_ARM_BIND_SCALED_NEAREST_SRC_DST (armv6, 8888_8888, SRC,
71                                         uint32_t, uint32_t)
72 
73 void
74 pixman_composite_src_n_8888_asm_armv6 (int32_t   w,
75                                        int32_t   h,
76                                        uint32_t *dst,
77                                        int32_t   dst_stride,
78                                        uint32_t  src);
79 
80 void
81 pixman_composite_src_n_0565_asm_armv6 (int32_t   w,
82                                        int32_t   h,
83                                        uint16_t *dst,
84                                        int32_t   dst_stride,
85                                        uint16_t  src);
86 
87 void
88 pixman_composite_src_n_8_asm_armv6 (int32_t   w,
89                                     int32_t   h,
90                                     uint8_t  *dst,
91                                     int32_t   dst_stride,
92                                     uint8_t  src);
93 
94 static pixman_bool_t
arm_simd_fill(pixman_implementation_t * imp,uint32_t * bits,int stride,int bpp,int x,int y,int width,int height,uint32_t _xor)95 arm_simd_fill (pixman_implementation_t *imp,
96                uint32_t *               bits,
97                int                      stride, /* in 32-bit words */
98                int                      bpp,
99                int                      x,
100                int                      y,
101                int                      width,
102                int                      height,
103                uint32_t                 _xor)
104 {
105     /* stride is always multiple of 32bit units in pixman */
106     uint32_t byte_stride = stride * sizeof(uint32_t);
107 
108     switch (bpp)
109     {
110     case 8:
111 	pixman_composite_src_n_8_asm_armv6 (
112 		width,
113 		height,
114 		(uint8_t *)(((char *) bits) + y * byte_stride + x),
115 		byte_stride,
116 		_xor & 0xff);
117 	return TRUE;
118     case 16:
119 	pixman_composite_src_n_0565_asm_armv6 (
120 		width,
121 		height,
122 		(uint16_t *)(((char *) bits) + y * byte_stride + x * 2),
123 		byte_stride / 2,
124 		_xor & 0xffff);
125 	return TRUE;
126     case 32:
127 	pixman_composite_src_n_8888_asm_armv6 (
128 		width,
129 		height,
130 		(uint32_t *)(((char *) bits) + y * byte_stride + x * 4),
131 		byte_stride / 4,
132 		_xor);
133 	return TRUE;
134     default:
135 	return FALSE;
136     }
137 }
138 
139 static pixman_bool_t
arm_simd_blt(pixman_implementation_t * imp,uint32_t * src_bits,uint32_t * dst_bits,int src_stride,int dst_stride,int src_bpp,int dst_bpp,int src_x,int src_y,int dest_x,int dest_y,int width,int height)140 arm_simd_blt (pixman_implementation_t *imp,
141               uint32_t *               src_bits,
142               uint32_t *               dst_bits,
143               int                      src_stride, /* in 32-bit words */
144               int                      dst_stride, /* in 32-bit words */
145               int                      src_bpp,
146               int                      dst_bpp,
147               int                      src_x,
148               int                      src_y,
149               int                      dest_x,
150               int                      dest_y,
151               int                      width,
152               int                      height)
153 {
154     if (src_bpp != dst_bpp)
155 	return FALSE;
156 
157     switch (src_bpp)
158     {
159     case 8:
160         pixman_composite_src_8_8_asm_armv6 (
161                 width, height,
162                 (uint8_t *)(((char *) dst_bits) +
163                 dest_y * dst_stride * 4 + dest_x * 1), dst_stride * 4,
164                 (uint8_t *)(((char *) src_bits) +
165                 src_y * src_stride * 4 + src_x * 1), src_stride * 4);
166         return TRUE;
167     case 16:
168 	pixman_composite_src_0565_0565_asm_armv6 (
169 		width, height,
170 		(uint16_t *)(((char *) dst_bits) +
171 		dest_y * dst_stride * 4 + dest_x * 2), dst_stride * 2,
172 		(uint16_t *)(((char *) src_bits) +
173 		src_y * src_stride * 4 + src_x * 2), src_stride * 2);
174 	return TRUE;
175     case 32:
176 	pixman_composite_src_8888_8888_asm_armv6 (
177 		width, height,
178 		(uint32_t *)(((char *) dst_bits) +
179 		dest_y * dst_stride * 4 + dest_x * 4), dst_stride,
180 		(uint32_t *)(((char *) src_bits) +
181 		src_y * src_stride * 4 + src_x * 4), src_stride);
182 	return TRUE;
183     default:
184 	return FALSE;
185     }
186 }
187 
188 static const pixman_fast_path_t arm_simd_fast_paths[] =
189 {
190     PIXMAN_STD_FAST_PATH (SRC, a8r8g8b8, null, a8r8g8b8, armv6_composite_src_8888_8888),
191     PIXMAN_STD_FAST_PATH (SRC, a8b8g8r8, null, a8b8g8r8, armv6_composite_src_8888_8888),
192     PIXMAN_STD_FAST_PATH (SRC, a8r8g8b8, null, x8r8g8b8, armv6_composite_src_8888_8888),
193     PIXMAN_STD_FAST_PATH (SRC, a8b8g8r8, null, x8b8g8r8, armv6_composite_src_8888_8888),
194     PIXMAN_STD_FAST_PATH (SRC, x8r8g8b8, null, x8r8g8b8, armv6_composite_src_8888_8888),
195     PIXMAN_STD_FAST_PATH (SRC, x8b8g8r8, null, x8b8g8r8, armv6_composite_src_8888_8888),
196 
197     PIXMAN_STD_FAST_PATH (SRC, x8b8g8r8, null, a8b8g8r8, armv6_composite_src_x888_8888),
198     PIXMAN_STD_FAST_PATH (SRC, x8r8g8b8, null, a8r8g8b8, armv6_composite_src_x888_8888),
199 
200     PIXMAN_STD_FAST_PATH (SRC, r5g6b5, null, r5g6b5, armv6_composite_src_0565_0565),
201     PIXMAN_STD_FAST_PATH (SRC, b5g6r5, null, b5g6r5, armv6_composite_src_0565_0565),
202     PIXMAN_STD_FAST_PATH (SRC, a1r5g5b5, null, a1r5g5b5, armv6_composite_src_0565_0565),
203     PIXMAN_STD_FAST_PATH (SRC, a1b5g5r5, null, a1b5g5r5, armv6_composite_src_0565_0565),
204     PIXMAN_STD_FAST_PATH (SRC, a1r5g5b5, null, x1r5g5b5, armv6_composite_src_0565_0565),
205     PIXMAN_STD_FAST_PATH (SRC, a1b5g5r5, null, x1b5g5r5, armv6_composite_src_0565_0565),
206     PIXMAN_STD_FAST_PATH (SRC, x1r5g5b5, null, x1r5g5b5, armv6_composite_src_0565_0565),
207     PIXMAN_STD_FAST_PATH (SRC, x1b5g5r5, null, x1b5g5r5, armv6_composite_src_0565_0565),
208     PIXMAN_STD_FAST_PATH (SRC, a4r4g4b4, null, a4r4g4b4, armv6_composite_src_0565_0565),
209     PIXMAN_STD_FAST_PATH (SRC, a4b4g4r4, null, a4b4g4r4, armv6_composite_src_0565_0565),
210     PIXMAN_STD_FAST_PATH (SRC, a4r4g4b4, null, x4r4g4b4, armv6_composite_src_0565_0565),
211     PIXMAN_STD_FAST_PATH (SRC, a4b4g4r4, null, x4b4g4r4, armv6_composite_src_0565_0565),
212     PIXMAN_STD_FAST_PATH (SRC, x4r4g4b4, null, x4r4g4b4, armv6_composite_src_0565_0565),
213     PIXMAN_STD_FAST_PATH (SRC, x4b4g4r4, null, x4b4g4r4, armv6_composite_src_0565_0565),
214 
215     PIXMAN_STD_FAST_PATH (SRC, a8, null, a8, armv6_composite_src_8_8),
216     PIXMAN_STD_FAST_PATH (SRC, r3g3b2, null, r3g3b2, armv6_composite_src_8_8),
217     PIXMAN_STD_FAST_PATH (SRC, b2g3r3, null, b2g3r3, armv6_composite_src_8_8),
218     PIXMAN_STD_FAST_PATH (SRC, a2r2g2b2, null, a2r2g2b2, armv6_composite_src_8_8),
219     PIXMAN_STD_FAST_PATH (SRC, a2b2g2r2, null, a2b2g2r2, armv6_composite_src_8_8),
220     PIXMAN_STD_FAST_PATH (SRC, c8, null, c8, armv6_composite_src_8_8),
221     PIXMAN_STD_FAST_PATH (SRC, g8, null, g8, armv6_composite_src_8_8),
222     PIXMAN_STD_FAST_PATH (SRC, x4a4, null, x4a4, armv6_composite_src_8_8),
223     PIXMAN_STD_FAST_PATH (SRC, x4c4, null, x4c4, armv6_composite_src_8_8),
224     PIXMAN_STD_FAST_PATH (SRC, x4g4, null, x4g4, armv6_composite_src_8_8),
225 
226     PIXMAN_STD_FAST_PATH (SRC, r5g6b5, null, a8r8g8b8, armv6_composite_src_0565_8888),
227     PIXMAN_STD_FAST_PATH (SRC, r5g6b5, null, x8r8g8b8, armv6_composite_src_0565_8888),
228     PIXMAN_STD_FAST_PATH (SRC, b5g6r5, null, a8b8g8r8, armv6_composite_src_0565_8888),
229     PIXMAN_STD_FAST_PATH (SRC, b5g6r5, null, x8b8g8r8, armv6_composite_src_0565_8888),
230 
231     PIXMAN_STD_FAST_PATH (SRC, a8r8g8b8, null, r5g6b5, armv6_composite_src_x888_0565),
232     PIXMAN_STD_FAST_PATH (SRC, x8r8g8b8, null, r5g6b5, armv6_composite_src_x888_0565),
233     PIXMAN_STD_FAST_PATH (SRC, a8b8g8r8, null, b5g6r5, armv6_composite_src_x888_0565),
234     PIXMAN_STD_FAST_PATH (SRC, x8b8g8r8, null, b5g6r5, armv6_composite_src_x888_0565),
235 
236     PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, null, a8r8g8b8, armv6_composite_over_8888_8888),
237     PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, null, x8r8g8b8, armv6_composite_over_8888_8888),
238     PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, null, a8b8g8r8, armv6_composite_over_8888_8888),
239     PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, null, x8b8g8r8, armv6_composite_over_8888_8888),
240     PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, solid, a8r8g8b8, armv6_composite_over_8888_n_8888),
241     PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, solid, x8r8g8b8, armv6_composite_over_8888_n_8888),
242     PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, solid, a8b8g8r8, armv6_composite_over_8888_n_8888),
243     PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, solid, x8b8g8r8, armv6_composite_over_8888_n_8888),
244 
245     PIXMAN_STD_FAST_PATH (OVER, solid, null, a8r8g8b8, armv6_composite_over_n_8888),
246     PIXMAN_STD_FAST_PATH (OVER, solid, null, x8r8g8b8, armv6_composite_over_n_8888),
247     PIXMAN_STD_FAST_PATH (OVER, solid, null, a8b8g8r8, armv6_composite_over_n_8888),
248     PIXMAN_STD_FAST_PATH (OVER, solid, null, x8b8g8r8, armv6_composite_over_n_8888),
249     PIXMAN_STD_FAST_PATH (OVER_REVERSE, solid, null, a8r8g8b8, armv6_composite_over_reverse_n_8888),
250     PIXMAN_STD_FAST_PATH (OVER_REVERSE, solid, null, a8b8g8r8, armv6_composite_over_reverse_n_8888),
251 
252     PIXMAN_STD_FAST_PATH (ADD, a8, null, a8, armv6_composite_add_8_8),
253 
254     PIXMAN_STD_FAST_PATH (OVER, solid, a8, a8r8g8b8, armv6_composite_over_n_8_8888),
255     PIXMAN_STD_FAST_PATH (OVER, solid, a8, x8r8g8b8, armv6_composite_over_n_8_8888),
256     PIXMAN_STD_FAST_PATH (OVER, solid, a8, a8b8g8r8, armv6_composite_over_n_8_8888),
257     PIXMAN_STD_FAST_PATH (OVER, solid, a8, x8b8g8r8, armv6_composite_over_n_8_8888),
258 
259     PIXMAN_STD_FAST_PATH (IN_REVERSE, a8r8g8b8, null, a8r8g8b8, armv6_composite_in_reverse_8888_8888),
260     PIXMAN_STD_FAST_PATH (IN_REVERSE, a8r8g8b8, null, x8r8g8b8, armv6_composite_in_reverse_8888_8888),
261     PIXMAN_STD_FAST_PATH (IN_REVERSE, a8b8g8r8, null, a8b8g8r8, armv6_composite_in_reverse_8888_8888),
262     PIXMAN_STD_FAST_PATH (IN_REVERSE, a8b8g8r8, null, x8b8g8r8, armv6_composite_in_reverse_8888_8888),
263 
264     PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8r8g8b8, a8r8g8b8, armv6_composite_over_n_8888_8888_ca),
265     PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8r8g8b8, x8r8g8b8, armv6_composite_over_n_8888_8888_ca),
266     PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8b8g8r8, a8b8g8r8, armv6_composite_over_n_8888_8888_ca),
267     PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8b8g8r8, x8b8g8r8, armv6_composite_over_n_8888_8888_ca),
268 
269     SIMPLE_NEAREST_FAST_PATH (SRC, r5g6b5, r5g6b5, armv6_0565_0565),
270     SIMPLE_NEAREST_FAST_PATH (SRC, b5g6r5, b5g6r5, armv6_0565_0565),
271 
272     SIMPLE_NEAREST_FAST_PATH (SRC, a8r8g8b8, a8r8g8b8, armv6_8888_8888),
273     SIMPLE_NEAREST_FAST_PATH (SRC, a8r8g8b8, x8r8g8b8, armv6_8888_8888),
274     SIMPLE_NEAREST_FAST_PATH (SRC, x8r8g8b8, x8r8g8b8, armv6_8888_8888),
275     SIMPLE_NEAREST_FAST_PATH (SRC, a8b8g8r8, a8b8g8r8, armv6_8888_8888),
276     SIMPLE_NEAREST_FAST_PATH (SRC, a8b8g8r8, x8b8g8r8, armv6_8888_8888),
277     SIMPLE_NEAREST_FAST_PATH (SRC, x8b8g8r8, x8b8g8r8, armv6_8888_8888),
278 
279     { PIXMAN_OP_NONE },
280 };
281 
282 pixman_implementation_t *
_pixman_implementation_create_arm_simd(pixman_implementation_t * fallback)283 _pixman_implementation_create_arm_simd (pixman_implementation_t *fallback)
284 {
285     pixman_implementation_t *imp = _pixman_implementation_create (fallback, arm_simd_fast_paths);
286 
287     imp->blt = arm_simd_blt;
288     imp->fill = arm_simd_fill;
289 
290     return imp;
291 }
292