Move iterator initialization to the respective image files
[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 #include "pixman-combine32.h"
40 #include "pixman-private.h"
41
42 static uint32_t *
43 src_get_scanline_null (pixman_iter_t *iter, const uint32_t *mask)
44 {
45     return NULL;
46 }
47
48 static void
49 src_iter_init (pixman_implementation_t *imp,
50                pixman_iter_t *iter,
51                pixman_image_t *image,
52                int x, int y, int width, int height,
53                uint8_t *buffer, iter_flags_t flags)
54 {
55     iter->image = image;
56     iter->x = x;
57     iter->y = y;
58     iter->width = width;
59     iter->buffer = (uint32_t *)buffer;
60
61     if (!image)
62     {
63         iter->get_scanline = src_get_scanline_null;
64     }
65     else if (image->type == SOLID)
66     {
67         _pixman_solid_fill_iter_init (
68             image, iter, x, y, width, height, buffer, flags);
69     }
70     else if (image->type == LINEAR)
71     {
72         _pixman_linear_gradient_iter_init (
73             image, iter, x, y, width, height, buffer, flags);
74     }
75     else if (image->type == RADIAL)
76     {
77         _pixman_radial_gradient_iter_init (
78             image, iter, x, y, width, height, buffer, flags);
79     }
80     else if (image->type == CONICAL)
81     {
82         _pixman_conical_gradient_iter_init (
83             image, iter, x, y, width, height, buffer, flags);
84     }
85     else if (image->type == BITS)
86     {
87         _pixman_bits_image_src_iter_init (
88             image, iter, x, y, width, height, buffer, flags);
89     }
90     else
91     {
92         _pixman_log_error (FUNC, "Pixman bug: unknown image type\n");
93     }
94 }
95
96 static void
97 dest_iter_init (pixman_implementation_t *imp,
98                 pixman_iter_t *iter,
99                 pixman_image_t *image,
100                 int x, int y, int width, int height,
101                 uint8_t *buffer, iter_flags_t flags)
102 {
103     iter->image = image;
104     iter->x = x;
105     iter->y = y;
106     iter->width = width;
107     iter->buffer = (uint32_t *)buffer;
108
109     if (image->type == BITS)
110     {
111         _pixman_bits_image_dest_iter_init (
112             image, iter, x, y, width, height, buffer, flags);
113     }
114     else
115     {
116         _pixman_log_error (FUNC, "Trying to write to a non-writable image");
117     }
118 }
119
120 #define SCANLINE_BUFFER_LENGTH 8192
121
122 static void
123 general_composite_rect  (pixman_implementation_t *imp,
124                          pixman_op_t              op,
125                          pixman_image_t *         src,
126                          pixman_image_t *         mask,
127                          pixman_image_t *         dest,
128                          int32_t                  src_x,
129                          int32_t                  src_y,
130                          int32_t                  mask_x,
131                          int32_t                  mask_y,
132                          int32_t                  dest_x,
133                          int32_t                  dest_y,
134                          int32_t                  width,
135                          int32_t                  height)
136 {
137     uint64_t stack_scanline_buffer[(SCANLINE_BUFFER_LENGTH * 3 + 7) / 8];
138     uint8_t *scanline_buffer = (uint8_t *) stack_scanline_buffer;
139     uint8_t *src_buffer, *mask_buffer, *dest_buffer;
140     pixman_iter_t src_iter, mask_iter, dest_iter;
141     pixman_combine_32_func_t compose;
142     pixman_bool_t component_alpha;
143     iter_flags_t narrow;
144     int Bpp;
145     int i;
146
147     if ((src->common.flags & FAST_PATH_NARROW_FORMAT)           &&
148         (!mask || mask->common.flags & FAST_PATH_NARROW_FORMAT) &&
149         (dest->common.flags & FAST_PATH_NARROW_FORMAT))
150     {
151         narrow = ITER_NARROW;
152         Bpp = 4;
153     }
154     else
155     {
156         narrow = 0;
157         Bpp = 8;
158     }
159
160     if (width * Bpp > SCANLINE_BUFFER_LENGTH)
161     {
162         scanline_buffer = pixman_malloc_abc (width, 3, Bpp);
163
164         if (!scanline_buffer)
165             return;
166     }
167
168     src_buffer = scanline_buffer;
169     mask_buffer = src_buffer + width * Bpp;
170     dest_buffer = mask_buffer + width * Bpp;
171
172     src_iter_init (imp->toplevel, &src_iter, src,
173                    src_x, src_y, width, height,
174                    src_buffer, narrow);
175
176     src_iter_init (imp->toplevel, &mask_iter, mask,
177                    mask_x, mask_y, width, height,
178                    mask_buffer, narrow);
179
180     dest_iter_init (imp->toplevel, &dest_iter, dest,
181                     dest_x, dest_y, width, height,
182                     dest_buffer, narrow);
183
184     component_alpha =
185         mask                            &&
186         mask->common.type == BITS       &&
187         mask->common.component_alpha    &&
188         PIXMAN_FORMAT_RGB (mask->bits.format);
189
190     if (narrow)
191     {
192         if (component_alpha)
193             compose = _pixman_implementation_combine_32_ca;
194         else
195             compose = _pixman_implementation_combine_32;
196     }
197     else
198     {
199         if (component_alpha)
200             compose = (pixman_combine_32_func_t)_pixman_implementation_combine_64_ca;
201         else
202             compose = (pixman_combine_32_func_t)_pixman_implementation_combine_64;
203     }
204
205     if (!compose)
206         return;
207
208     for (i = 0; i < height; ++i)
209     {
210         uint32_t *s, *m, *d;
211
212         m = mask_iter.get_scanline (&mask_iter, NULL);
213         s = src_iter.get_scanline (&src_iter, m);
214         d = dest_iter.get_scanline (&dest_iter, NULL);
215
216         compose (imp->toplevel, op, d, s, m, width);
217
218         dest_iter.write_back (&dest_iter);
219     }
220
221     if (scanline_buffer != (uint8_t *) stack_scanline_buffer)
222         free (scanline_buffer);
223 }
224
225 static const pixman_fast_path_t general_fast_path[] =
226 {
227     { PIXMAN_OP_any, PIXMAN_any, 0, PIXMAN_any, 0, PIXMAN_any, 0, general_composite_rect },
228     { PIXMAN_OP_NONE }
229 };
230
231 static pixman_bool_t
232 general_blt (pixman_implementation_t *imp,
233              uint32_t *               src_bits,
234              uint32_t *               dst_bits,
235              int                      src_stride,
236              int                      dst_stride,
237              int                      src_bpp,
238              int                      dst_bpp,
239              int                      src_x,
240              int                      src_y,
241              int                      dst_x,
242              int                      dst_y,
243              int                      width,
244              int                      height)
245 {
246     /* We can't blit unless we have sse2 or mmx */
247
248     return FALSE;
249 }
250
251 static pixman_bool_t
252 general_fill (pixman_implementation_t *imp,
253               uint32_t *               bits,
254               int                      stride,
255               int                      bpp,
256               int                      x,
257               int                      y,
258               int                      width,
259               int                      height,
260               uint32_t xor)
261 {
262     return FALSE;
263 }
264
265 pixman_implementation_t *
266 _pixman_implementation_create_general (void)
267 {
268     pixman_implementation_t *imp = _pixman_implementation_create (NULL, general_fast_path);
269
270     _pixman_setup_combiner_functions_32 (imp);
271     _pixman_setup_combiner_functions_64 (imp);
272
273     imp->blt = general_blt;
274     imp->fill = general_fill;
275
276     return imp;
277 }
278