Do not include unused headers
[profile/ivi/pixman.git] / pixman / pixman-general.c
1 /*
2  * Copyright © 2009 Red Hat, Inc.
3  * Copyright © 2000 SuSE, Inc.
4  * Copyright © 2007 Red Hat, Inc.
5  * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
6  *             2005 Lars Knoll & Zack Rusin, Trolltech
7  *             2008 Aaron Plattner, NVIDIA Corporation
8  *
9  * Permission to use, copy, modify, distribute, and sell this software and its
10  * documentation for any purpose is hereby granted without fee, provided that
11  * the above copyright notice appear in all copies and that both that
12  * copyright notice and this permission notice appear in supporting
13  * documentation, and that the name of Red Hat not be used in advertising or
14  * publicity pertaining to distribution of the software without specific,
15  * written prior permission.  Red Hat makes no representations about the
16  * suitability of this software for any purpose.  It is provided "as is"
17  * without express or implied warranty.
18  *
19  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
20  * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
21  * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
22  * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
23  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
24  * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
25  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
26  * SOFTWARE.
27  */
28 #ifdef HAVE_CONFIG_H
29 #include <config.h>
30 #endif
31 #include <stdlib.h>
32 #include <string.h>
33 #include <math.h>
34 #include <limits.h>
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <string.h>
38 #include "pixman-private.h"
39
40 static void
41 general_src_iter_init (pixman_implementation_t *imp,
42                        pixman_iter_t *iter,
43                        pixman_image_t *image,
44                        int x, int y, int width, int height,
45                        uint8_t *buffer, iter_flags_t flags)
46 {
47     iter->image = image;
48     iter->x = x;
49     iter->y = y;
50     iter->width = width;
51     iter->buffer = (uint32_t *)buffer;
52
53     if (image->type == SOLID)
54     {
55         _pixman_solid_fill_iter_init (
56             image, iter, x, y, width, height, buffer, flags);
57     }
58     else if (image->type == LINEAR)
59     {
60         _pixman_linear_gradient_iter_init (
61             image, iter, x, y, width, height, buffer, flags);
62     }
63     else if (image->type == RADIAL)
64     {
65         _pixman_radial_gradient_iter_init (
66             image, iter, x, y, width, height, buffer, flags);
67     }
68     else if (image->type == CONICAL)
69     {
70         _pixman_conical_gradient_iter_init (
71             image, iter, x, y, width, height, buffer, flags);
72     }
73     else if (image->type == BITS)
74     {
75         _pixman_bits_image_src_iter_init (
76             image, iter, x, y, width, height, buffer, flags);
77     }
78     else
79     {
80         _pixman_log_error (FUNC, "Pixman bug: unknown image type\n");
81     }
82 }
83
84 static void
85 general_dest_iter_init (pixman_implementation_t *imp,
86                         pixman_iter_t *iter,
87                         pixman_image_t *image,
88                         int x, int y, int width, int height,
89                         uint8_t *buffer, iter_flags_t flags)
90 {
91     iter->image = image;
92     iter->x = x;
93     iter->y = y;
94     iter->width = width;
95     iter->buffer = (uint32_t *)buffer;
96
97     if (image->type == BITS)
98     {
99         _pixman_bits_image_dest_iter_init (
100             image, iter, x, y, width, height, buffer, flags);
101     }
102     else
103     {
104         _pixman_log_error (FUNC, "Trying to write to a non-writable image");
105     }
106 }
107
108 typedef struct op_info_t op_info_t;
109 struct op_info_t
110 {
111     uint8_t src, dst;
112 };
113
114 #define ITER_IGNORE_BOTH                                                \
115     (ITER_IGNORE_ALPHA | ITER_IGNORE_RGB | ITER_LOCALIZED_ALPHA)
116
117 static const op_info_t op_flags[PIXMAN_N_OPERATORS] =
118 {
119     /* Src                   Dst                   */
120     { ITER_IGNORE_BOTH,      ITER_IGNORE_BOTH      }, /* CLEAR */
121     { ITER_LOCALIZED_ALPHA,  ITER_IGNORE_BOTH      }, /* SRC */
122     { ITER_IGNORE_BOTH,      ITER_LOCALIZED_ALPHA  }, /* DST */
123     { 0,                     ITER_LOCALIZED_ALPHA  }, /* OVER */
124     { ITER_LOCALIZED_ALPHA,  0                     }, /* OVER_REVERSE */
125     { ITER_LOCALIZED_ALPHA,  ITER_IGNORE_RGB       }, /* IN */
126     { ITER_IGNORE_RGB,       ITER_LOCALIZED_ALPHA  }, /* IN_REVERSE */
127     { ITER_LOCALIZED_ALPHA,  ITER_IGNORE_RGB       }, /* OUT */
128     { ITER_IGNORE_RGB,       ITER_LOCALIZED_ALPHA  }, /* OUT_REVERSE */
129     { 0,                     0                     }, /* ATOP */
130     { 0,                     0                     }, /* ATOP_REVERSE */
131     { 0,                     0                     }, /* XOR */
132     { ITER_LOCALIZED_ALPHA,  ITER_LOCALIZED_ALPHA  }, /* ADD */
133     { 0,                     0                     }, /* SATURATE */
134 };
135
136 #define SCANLINE_BUFFER_LENGTH 8192
137
138 static void
139 general_composite_rect  (pixman_implementation_t *imp,
140                          pixman_op_t              op,
141                          pixman_image_t *         src,
142                          pixman_image_t *         mask,
143                          pixman_image_t *         dest,
144                          int32_t                  src_x,
145                          int32_t                  src_y,
146                          int32_t                  mask_x,
147                          int32_t                  mask_y,
148                          int32_t                  dest_x,
149                          int32_t                  dest_y,
150                          int32_t                  width,
151                          int32_t                  height)
152 {
153     uint64_t stack_scanline_buffer[(SCANLINE_BUFFER_LENGTH * 3 + 7) / 8];
154     uint8_t *scanline_buffer = (uint8_t *) stack_scanline_buffer;
155     uint8_t *src_buffer, *mask_buffer, *dest_buffer;
156     pixman_iter_t src_iter, mask_iter, dest_iter;
157     pixman_combine_32_func_t compose;
158     pixman_bool_t component_alpha;
159     iter_flags_t narrow, src_flags;
160     int Bpp;
161     int i;
162
163     if ((src->common.flags & FAST_PATH_NARROW_FORMAT)           &&
164         (!mask || mask->common.flags & FAST_PATH_NARROW_FORMAT) &&
165         (dest->common.flags & FAST_PATH_NARROW_FORMAT))
166     {
167         narrow = ITER_NARROW;
168         Bpp = 4;
169     }
170     else
171     {
172         narrow = 0;
173         Bpp = 8;
174     }
175
176     if (width * Bpp > SCANLINE_BUFFER_LENGTH)
177     {
178         scanline_buffer = pixman_malloc_abc (width, 3, Bpp);
179
180         if (!scanline_buffer)
181             return;
182     }
183
184     src_buffer = scanline_buffer;
185     mask_buffer = src_buffer + width * Bpp;
186     dest_buffer = mask_buffer + width * Bpp;
187
188     /* src iter */
189     src_flags = narrow | op_flags[op].src;
190
191     _pixman_implementation_src_iter_init (imp->toplevel, &src_iter, src,
192                                           src_x, src_y, width, height,
193                                           src_buffer, src_flags);
194
195     /* mask iter */
196     if ((src_flags & (ITER_IGNORE_ALPHA | ITER_IGNORE_RGB)) ==
197         (ITER_IGNORE_ALPHA | ITER_IGNORE_RGB))
198     {
199         /* If it doesn't matter what the source is, then it doesn't matter
200          * what the mask is
201          */
202         mask = NULL;
203     }
204
205     component_alpha =
206         mask                            &&
207         mask->common.type == BITS       &&
208         mask->common.component_alpha    &&
209         PIXMAN_FORMAT_RGB (mask->bits.format);
210
211     _pixman_implementation_src_iter_init (
212         imp->toplevel, &mask_iter, mask, mask_x, mask_y, width, height,
213         mask_buffer, narrow | (component_alpha? 0 : ITER_IGNORE_RGB));
214
215     /* dest iter */
216     _pixman_implementation_dest_iter_init (imp->toplevel, &dest_iter, dest,
217                                            dest_x, dest_y, width, height,
218                                            dest_buffer,
219                                            narrow | op_flags[op].dst);
220
221     if (narrow)
222     {
223         if (component_alpha)
224             compose = _pixman_implementation_combine_32_ca;
225         else
226             compose = _pixman_implementation_combine_32;
227     }
228     else
229     {
230         if (component_alpha)
231             compose = (pixman_combine_32_func_t)_pixman_implementation_combine_64_ca;
232         else
233             compose = (pixman_combine_32_func_t)_pixman_implementation_combine_64;
234     }
235
236     if (!compose)
237         return;
238
239     for (i = 0; i < height; ++i)
240     {
241         uint32_t *s, *m, *d;
242
243         m = mask_iter.get_scanline (&mask_iter, NULL);
244         s = src_iter.get_scanline (&src_iter, m);
245         d = dest_iter.get_scanline (&dest_iter, NULL);
246
247         compose (imp->toplevel, op, d, s, m, width);
248
249         dest_iter.write_back (&dest_iter);
250     }
251
252     if (scanline_buffer != (uint8_t *) stack_scanline_buffer)
253         free (scanline_buffer);
254 }
255
256 static const pixman_fast_path_t general_fast_path[] =
257 {
258     { PIXMAN_OP_any, PIXMAN_any, 0, PIXMAN_any, 0, PIXMAN_any, 0, general_composite_rect },
259     { PIXMAN_OP_NONE }
260 };
261
262 static pixman_bool_t
263 general_blt (pixman_implementation_t *imp,
264              uint32_t *               src_bits,
265              uint32_t *               dst_bits,
266              int                      src_stride,
267              int                      dst_stride,
268              int                      src_bpp,
269              int                      dst_bpp,
270              int                      src_x,
271              int                      src_y,
272              int                      dst_x,
273              int                      dst_y,
274              int                      width,
275              int                      height)
276 {
277     /* We can't blit unless we have sse2 or mmx */
278
279     return FALSE;
280 }
281
282 static pixman_bool_t
283 general_fill (pixman_implementation_t *imp,
284               uint32_t *               bits,
285               int                      stride,
286               int                      bpp,
287               int                      x,
288               int                      y,
289               int                      width,
290               int                      height,
291               uint32_t xor)
292 {
293     return FALSE;
294 }
295
296 pixman_implementation_t *
297 _pixman_implementation_create_general (void)
298 {
299     pixman_implementation_t *imp = _pixman_implementation_create (NULL, general_fast_path);
300
301     _pixman_setup_combiner_functions_32 (imp);
302     _pixman_setup_combiner_functions_64 (imp);
303
304     imp->blt = general_blt;
305     imp->fill = general_fill;
306     imp->src_iter_init = general_src_iter_init;
307     imp->dest_iter_init = general_dest_iter_init;
308
309     return imp;
310 }
311