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