Convert CamelCase names to underscore_names.
[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 #include <config.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <math.h>
32 #include <limits.h>
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36 #include "pixman-private.h"
37 #include "pixman-combine32.h"
38 #include "pixman-private.h"
39
40 #define SCANLINE_BUFFER_LENGTH 8192
41
42 static void
43 general_composite_rect  (pixman_implementation_t *imp,
44                          pixman_op_t              op,
45                          pixman_image_t          *src,
46                          pixman_image_t          *mask,
47                          pixman_image_t          *dest,
48                          int32_t                  src_x,
49                          int32_t                  src_y,
50                          int32_t                  mask_x,
51                          int32_t                  mask_y,
52                          int32_t                  dest_x,
53                          int32_t                  dest_y,
54                          int32_t                  width,
55                          int32_t                  height)
56 {
57     uint8_t stack_scanline_buffer[SCANLINE_BUFFER_LENGTH * 3];
58     const pixman_format_code_t src_format = src->type == BITS ? src->bits.format : 0;
59     const pixman_format_code_t mask_format = mask && mask->type == BITS ? mask->bits.format : 0;
60     const pixman_format_code_t dest_format = dest->type == BITS ? dest->bits.format : 0;
61     const int src_wide = PIXMAN_FORMAT_IS_WIDE(src_format);
62     const int mask_wide = mask && PIXMAN_FORMAT_IS_WIDE(mask_format);
63     const int dest_wide = PIXMAN_FORMAT_IS_WIDE(dest_format);
64     const int wide = src_wide || mask_wide || dest_wide;
65     const int Bpp = wide ? 8 : 4;
66     uint8_t *scanline_buffer = stack_scanline_buffer;
67     uint8_t *src_buffer, *mask_buffer, *dest_buffer;
68     fetch_scanline_t fetch_src = NULL, fetch_mask = NULL, fetch_dest = NULL;
69     pixman_combine_32_func_t compose;
70     store_scanline_t store;
71     source_pict_class_t src_class, mask_class;
72     pixman_bool_t component_alpha;
73     uint32_t *bits;
74     int32_t stride;
75     int i;
76     
77     if (width * Bpp > SCANLINE_BUFFER_LENGTH)
78     {
79         scanline_buffer = pixman_malloc_abc (width, 3, Bpp);
80         
81         if (!scanline_buffer)
82             return;
83     }
84     
85     src_buffer = scanline_buffer;
86     mask_buffer = src_buffer + width * Bpp;
87     dest_buffer = mask_buffer + width * Bpp;
88     
89     src_class = _pixman_image_classify (src,
90                                        src_x, src_y,
91                                        width, height);
92     
93     mask_class = SOURCE_IMAGE_CLASS_UNKNOWN;
94     if (mask)
95     {
96         mask_class = _pixman_image_classify (mask,
97                                             src_x, src_y,
98                                             width, height);
99     }
100     
101     if (op == PIXMAN_OP_CLEAR)
102         fetch_src = NULL;
103     else if (wide)
104         fetch_src = _pixman_image_get_scanline_64;
105     else
106         fetch_src = _pixman_image_get_scanline_32;
107     
108     if (!mask || op == PIXMAN_OP_CLEAR)
109         fetch_mask = NULL;
110     else if (wide)
111         fetch_mask = _pixman_image_get_scanline_64;
112     else
113         fetch_mask = _pixman_image_get_scanline_32;
114     
115     if (op == PIXMAN_OP_CLEAR || op == PIXMAN_OP_SRC)
116         fetch_dest = NULL;
117     else if (wide)
118         fetch_dest = _pixman_image_get_scanline_64;
119     else
120         fetch_dest = _pixman_image_get_scanline_32;
121
122     if (wide)
123         store = _pixman_image_store_scanline_64;
124     else
125         store = _pixman_image_store_scanline_32;
126
127     /* Skip the store step and composite directly into the
128      * destination if the output format of the compose func matches
129      * the destination format.
130      */
131     if (!wide &&
132         !dest->common.alpha_map &&
133         !dest->common.write_func && 
134         (op == PIXMAN_OP_ADD || op == PIXMAN_OP_OVER) &&
135         (dest->bits.format == PIXMAN_a8r8g8b8 ||
136          dest->bits.format == PIXMAN_x8r8g8b8))
137     {
138         store = NULL;
139     }
140     
141     if (!store)
142     {
143         bits = dest->bits.bits;
144         stride = dest->bits.rowstride;
145     }
146     else
147     {
148         bits = NULL;
149         stride = 0;
150     }
151     
152     component_alpha =
153         fetch_src                       &&
154         fetch_mask                      &&
155         mask                            &&
156         mask->common.type == BITS       &&
157         mask->common.component_alpha    &&
158         PIXMAN_FORMAT_RGB (mask->bits.format);
159     
160     if (wide)
161     {
162         if (component_alpha)
163             compose = (pixman_combine_32_func_t)_pixman_implementation_combine_64_ca;
164         else
165             compose = (pixman_combine_32_func_t)_pixman_implementation_combine_64;
166     }
167     else
168     {
169         if (component_alpha)
170             compose = _pixman_implementation_combine_32_ca;
171         else
172             compose = _pixman_implementation_combine_32;
173     }
174     
175     if (!compose)
176         return;
177     
178     if (!fetch_mask)
179         mask_buffer = NULL;
180     
181     for (i = 0; i < height; ++i)
182     {
183         /* fill first half of scanline with source */
184         if (fetch_src)
185         {
186             if (fetch_mask)
187             {
188                 /* fetch mask before source so that fetching of
189                    source can be optimized */
190                 fetch_mask (mask, mask_x, mask_y + i,
191                            width, (void *)mask_buffer, 0, 0);
192                 
193                 if (mask_class == SOURCE_IMAGE_CLASS_HORIZONTAL)
194                     fetch_mask = NULL;
195             }
196             
197             if (src_class == SOURCE_IMAGE_CLASS_HORIZONTAL)
198             {
199                 fetch_src (src, src_x, src_y + i,
200                           width, (void *)src_buffer, 0, 0);
201                 fetch_src = NULL;
202             }
203             else
204             {
205                 fetch_src (src, src_x, src_y + i,
206                           width, (void *)src_buffer, (void *)mask_buffer,
207                           0xffffffff);
208             }
209         }
210         else if (fetch_mask)
211         {
212             fetch_mask (mask, mask_x, mask_y + i,
213                        width, (void *)mask_buffer, 0, 0);
214         }
215         
216         if (store)
217         {
218             /* fill dest into second half of scanline */
219             if (fetch_dest)
220                 fetch_dest (dest, dest_x, dest_y + i,
221                            width, (void *)dest_buffer, 0, 0);
222             
223             /* blend */
224             compose (imp->toplevel, op, (void *)dest_buffer, (void *)src_buffer, (void *)mask_buffer, width);
225             
226             /* write back */
227             store (&(dest->bits), dest_x, dest_y + i, width,
228                    (void *)dest_buffer);
229         }
230         else
231         {
232             /* blend */
233             compose (imp->toplevel, op, bits + (dest_y + i) * stride +
234                      dest_x,
235                      (void *)src_buffer, (void *)mask_buffer, width);
236         }
237     }
238     
239     if (scanline_buffer != stack_scanline_buffer)
240         free (scanline_buffer);
241 }
242
243 static void
244 general_composite (pixman_implementation_t *    imp,
245                    pixman_op_t                  op,
246                    pixman_image_t *             src,
247                    pixman_image_t *             mask,
248                    pixman_image_t *             dest,
249                    int32_t                      src_x,
250                    int32_t                      src_y,
251                    int32_t                      mask_x,
252                    int32_t                      mask_y,
253                    int32_t                      dest_x,
254                    int32_t                      dest_y,
255                    int32_t                      width,
256                    int32_t                      height)
257 {
258     _pixman_walk_composite_region (imp, op, src, mask, dest, src_x, src_y,
259                                    mask_x, mask_y, dest_x, dest_y, width, height,
260                                    general_composite_rect);
261 }
262
263 static pixman_bool_t
264 general_blt (pixman_implementation_t *imp,
265              uint32_t *src_bits,
266              uint32_t *dst_bits,
267              int src_stride,
268              int dst_stride,
269              int src_bpp,
270              int dst_bpp,
271              int src_x, int src_y,
272              int dst_x, int dst_y,
273              int width, int height)
274 {
275     /* We can't blit unless we have sse2 or mmx */
276     
277     return FALSE;
278 }
279
280 static pixman_bool_t
281 general_fill (pixman_implementation_t *imp,
282               uint32_t *bits,
283               int stride,
284               int bpp,
285               int x,
286               int y,
287               int width,
288               int height,
289               uint32_t xor)
290 {
291     return FALSE;
292 }
293
294 pixman_implementation_t *
295 _pixman_implementation_create_general (void)
296 {
297     pixman_implementation_t *imp = _pixman_implementation_create (NULL);
298
299     _pixman_setup_combiner_functions_32 (imp);
300     _pixman_setup_combiner_functions_64 (imp);
301     
302     imp->composite = general_composite;
303     imp->blt = general_blt;
304     imp->fill = general_fill;
305     
306     return imp;
307 }