mmx: add add_0565_0565
[profile/ivi/pixman.git] / pixman / pixman-mips-dspr2.c
1 /*
2  * Copyright (c) 2012
3  *      MIPS Technologies, Inc., California.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of the MIPS Technologies, Inc., nor the names of its
14  *    contributors may be used to endorse or promote products derived from
15  *    this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  *
29  * Author:  Nemanja Lukic (nlukic@mips.com)
30  */
31
32 #ifdef HAVE_CONFIG_H
33 #include <config.h>
34 #endif
35
36 #include "pixman-private.h"
37 #include "pixman-mips-dspr2.h"
38
39 PIXMAN_MIPS_BIND_FAST_PATH_SRC_DST (0, src_x888_8888,
40                                     uint32_t, 1, uint32_t, 1)
41 PIXMAN_MIPS_BIND_FAST_PATH_SRC_DST (0, src_8888_0565,
42                                     uint32_t, 1, uint16_t, 1)
43 PIXMAN_MIPS_BIND_FAST_PATH_SRC_DST (0, src_0565_8888,
44                                     uint16_t, 1, uint32_t, 1)
45 PIXMAN_MIPS_BIND_FAST_PATH_SRC_DST (DO_FAST_MEMCPY, src_0565_0565,
46                                     uint16_t, 1, uint16_t, 1)
47 PIXMAN_MIPS_BIND_FAST_PATH_SRC_DST (DO_FAST_MEMCPY, src_8888_8888,
48                                     uint32_t, 1, uint32_t, 1)
49 PIXMAN_MIPS_BIND_FAST_PATH_SRC_DST (DO_FAST_MEMCPY, src_0888_0888,
50                                     uint8_t, 3, uint8_t, 3)
51
52 PIXMAN_MIPS_BIND_FAST_PATH_N_MASK_DST (SKIP_ZERO_SRC, over_n_8888_8888_ca,
53                                        uint32_t, 1, uint32_t, 1)
54 PIXMAN_MIPS_BIND_FAST_PATH_N_MASK_DST (SKIP_ZERO_SRC, over_n_8888_0565_ca,
55                                        uint32_t, 1, uint16_t, 1)
56 PIXMAN_MIPS_BIND_FAST_PATH_N_MASK_DST (SKIP_ZERO_SRC, over_n_8_8888,
57                                        uint8_t, 1, uint32_t, 1)
58 PIXMAN_MIPS_BIND_FAST_PATH_N_MASK_DST (SKIP_ZERO_SRC, over_n_8_0565,
59                                        uint8_t, 1, uint16_t, 1)
60
61 PIXMAN_MIPS_BIND_SCALED_BILINEAR_SRC_A8_DST (SKIP_ZERO_SRC, 8888_8_8888, OVER,
62                                              uint32_t, uint32_t)
63
64 static pixman_bool_t
65 pixman_fill_mips (uint32_t *bits,
66                   int       stride,
67                   int       bpp,
68                   int       x,
69                   int       y,
70                   int       width,
71                   int       height,
72                   uint32_t  _xor)
73 {
74     uint8_t *byte_line;
75     uint32_t byte_width;
76     switch (bpp)
77     {
78     case 16:
79         stride = stride * (int) sizeof (uint32_t) / 2;
80         byte_line = (uint8_t *)(((uint16_t *)bits) + stride * y + x);
81         byte_width = width * 2;
82         stride *= 2;
83
84         while (height--)
85         {
86             uint8_t *dst = byte_line;
87             byte_line += stride;
88             pixman_fill_buff16_mips (dst, byte_width, _xor & 0xffff);
89         }
90         return TRUE;
91     case 32:
92         stride = stride * (int) sizeof (uint32_t) / 4;
93         byte_line = (uint8_t *)(((uint32_t *)bits) + stride * y + x);
94         byte_width = width * 4;
95         stride *= 4;
96
97         while (height--)
98         {
99             uint8_t *dst = byte_line;
100             byte_line += stride;
101             pixman_fill_buff32_mips (dst, byte_width, _xor);
102         }
103         return TRUE;
104     default:
105         return FALSE;
106     }
107 }
108
109 static pixman_bool_t
110 pixman_blt_mips (uint32_t *src_bits,
111                  uint32_t *dst_bits,
112                  int       src_stride,
113                  int       dst_stride,
114                  int       src_bpp,
115                  int       dst_bpp,
116                  int       src_x,
117                  int       src_y,
118                  int       dest_x,
119                  int       dest_y,
120                  int       width,
121                  int       height)
122 {
123     if (src_bpp != dst_bpp)
124         return FALSE;
125
126     uint8_t *src_bytes;
127     uint8_t *dst_bytes;
128     uint32_t byte_width;
129
130     switch (src_bpp)
131     {
132     case 16:
133         src_stride = src_stride * (int) sizeof (uint32_t) / 2;
134         dst_stride = dst_stride * (int) sizeof (uint32_t) / 2;
135         src_bytes =(uint8_t *)(((uint16_t *)src_bits)
136                                           + src_stride * (src_y) + (src_x));
137         dst_bytes = (uint8_t *)(((uint16_t *)dst_bits)
138                                            + dst_stride * (dest_y) + (dest_x));
139         byte_width = width * 2;
140         src_stride *= 2;
141         dst_stride *= 2;
142
143         while (height--)
144         {
145             uint8_t *src = src_bytes;
146             uint8_t *dst = dst_bytes;
147             src_bytes += src_stride;
148             dst_bytes += dst_stride;
149             pixman_mips_fast_memcpy (dst, src, byte_width);
150         }
151         return TRUE;
152     case 32:
153         src_stride = src_stride * (int) sizeof (uint32_t) / 4;
154         dst_stride = dst_stride * (int) sizeof (uint32_t) / 4;
155         src_bytes = (uint8_t *)(((uint32_t *)src_bits)
156                                            + src_stride * (src_y) + (src_x));
157         dst_bytes = (uint8_t *)(((uint32_t *)dst_bits)
158                                            + dst_stride * (dest_y) + (dest_x));
159         byte_width = width * 4;
160         src_stride *= 4;
161         dst_stride *= 4;
162
163         while (height--)
164         {
165             uint8_t *src = src_bytes;
166             uint8_t *dst = dst_bytes;
167             src_bytes += src_stride;
168             dst_bytes += dst_stride;
169             pixman_mips_fast_memcpy (dst, src, byte_width);
170         }
171         return TRUE;
172     default:
173         return FALSE;
174     }
175 }
176
177 static const pixman_fast_path_t mips_dspr2_fast_paths[] =
178 {
179     PIXMAN_STD_FAST_PATH (SRC, r5g6b5,   null, r5g6b5,   mips_composite_src_0565_0565),
180     PIXMAN_STD_FAST_PATH (SRC, b5g6r5,   null, b5g6r5,   mips_composite_src_0565_0565),
181     PIXMAN_STD_FAST_PATH (SRC, a8r8g8b8, null, r5g6b5,   mips_composite_src_8888_0565),
182     PIXMAN_STD_FAST_PATH (SRC, x8r8g8b8, null, r5g6b5,   mips_composite_src_8888_0565),
183     PIXMAN_STD_FAST_PATH (SRC, a8b8g8r8, null, b5g6r5,   mips_composite_src_8888_0565),
184     PIXMAN_STD_FAST_PATH (SRC, x8b8g8r8, null, b5g6r5,   mips_composite_src_8888_0565),
185     PIXMAN_STD_FAST_PATH (SRC, r5g6b5,   null, a8r8g8b8, mips_composite_src_0565_8888),
186     PIXMAN_STD_FAST_PATH (SRC, r5g6b5,   null, x8r8g8b8, mips_composite_src_0565_8888),
187     PIXMAN_STD_FAST_PATH (SRC, b5g6r5,   null, a8b8g8r8, mips_composite_src_0565_8888),
188     PIXMAN_STD_FAST_PATH (SRC, b5g6r5,   null, x8b8g8r8, mips_composite_src_0565_8888),
189     PIXMAN_STD_FAST_PATH (SRC, a8r8g8b8, null, x8r8g8b8, mips_composite_src_8888_8888),
190     PIXMAN_STD_FAST_PATH (SRC, x8r8g8b8, null, x8r8g8b8, mips_composite_src_8888_8888),
191     PIXMAN_STD_FAST_PATH (SRC, a8b8g8r8, null, x8b8g8r8, mips_composite_src_8888_8888),
192     PIXMAN_STD_FAST_PATH (SRC, x8b8g8r8, null, x8b8g8r8, mips_composite_src_8888_8888),
193     PIXMAN_STD_FAST_PATH (SRC, a8r8g8b8, null, a8r8g8b8, mips_composite_src_8888_8888),
194     PIXMAN_STD_FAST_PATH (SRC, a8b8g8r8, null, a8b8g8r8, mips_composite_src_8888_8888),
195     PIXMAN_STD_FAST_PATH (SRC, x8r8g8b8, null, a8r8g8b8, mips_composite_src_x888_8888),
196     PIXMAN_STD_FAST_PATH (SRC, x8b8g8r8, null, a8b8g8r8, mips_composite_src_x888_8888),
197     PIXMAN_STD_FAST_PATH (SRC, r8g8b8,   null, r8g8b8,   mips_composite_src_0888_0888),
198
199     PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8r8g8b8, a8r8g8b8, mips_composite_over_n_8888_8888_ca),
200     PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8r8g8b8, x8r8g8b8, mips_composite_over_n_8888_8888_ca),
201     PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8b8g8r8, a8b8g8r8, mips_composite_over_n_8888_8888_ca),
202     PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8b8g8r8, x8b8g8r8, mips_composite_over_n_8888_8888_ca),
203     PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8r8g8b8, r5g6b5,   mips_composite_over_n_8888_0565_ca),
204     PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8b8g8r8, b5g6r5,   mips_composite_over_n_8888_0565_ca),
205     PIXMAN_STD_FAST_PATH (OVER, solid,    a8,       a8r8g8b8, mips_composite_over_n_8_8888),
206     PIXMAN_STD_FAST_PATH (OVER, solid,    a8,       x8r8g8b8, mips_composite_over_n_8_8888),
207     PIXMAN_STD_FAST_PATH (OVER, solid,    a8,       a8b8g8r8, mips_composite_over_n_8_8888),
208     PIXMAN_STD_FAST_PATH (OVER, solid,    a8,       x8b8g8r8, mips_composite_over_n_8_8888),
209     PIXMAN_STD_FAST_PATH (OVER, solid,    a8,       r5g6b5,   mips_composite_over_n_8_0565),
210     PIXMAN_STD_FAST_PATH (OVER, solid,    a8,       b5g6r5,   mips_composite_over_n_8_0565),
211
212     SIMPLE_BILINEAR_A8_MASK_FAST_PATH (OVER, a8r8g8b8, a8r8g8b8, mips_8888_8_8888),
213     SIMPLE_BILINEAR_A8_MASK_FAST_PATH (OVER, a8r8g8b8, x8r8g8b8, mips_8888_8_8888),
214
215     { PIXMAN_OP_NONE },
216 };
217
218 static pixman_bool_t
219 mips_dspr2_blt (pixman_implementation_t *imp,
220                 uint32_t *               src_bits,
221                 uint32_t *               dst_bits,
222                 int                      src_stride,
223                 int                      dst_stride,
224                 int                      src_bpp,
225                 int                      dst_bpp,
226                 int                      src_x,
227                 int                      src_y,
228                 int                      dest_x,
229                 int                      dest_y,
230                 int                      width,
231                 int                      height)
232 {
233     if (!pixman_blt_mips (
234             src_bits, dst_bits, src_stride, dst_stride, src_bpp, dst_bpp,
235             src_x, src_y, dest_x, dest_y, width, height))
236
237     {
238         return _pixman_implementation_blt (
239             imp->delegate,
240             src_bits, dst_bits, src_stride, dst_stride, src_bpp, dst_bpp,
241             src_x, src_y, dest_x, dest_y, width, height);
242     }
243
244     return TRUE;
245 }
246
247 static pixman_bool_t
248 mips_dspr2_fill (pixman_implementation_t *imp,
249                  uint32_t *               bits,
250                  int                      stride,
251                  int                      bpp,
252                  int                      x,
253                  int                      y,
254                  int                      width,
255                  int                      height,
256                  uint32_t xor)
257 {
258     if (pixman_fill_mips (bits, stride, bpp, x, y, width, height, xor))
259         return TRUE;
260
261     return _pixman_implementation_fill (
262         imp->delegate, bits, stride, bpp, x, y, width, height, xor);
263 }
264
265 pixman_implementation_t *
266 _pixman_implementation_create_mips_dspr2 (pixman_implementation_t *fallback)
267 {
268     pixman_implementation_t *imp =
269         _pixman_implementation_create (fallback, mips_dspr2_fast_paths);
270
271     imp->blt = mips_dspr2_blt;
272     imp->fill = mips_dspr2_fill;
273
274     return imp;
275 }