Add src, mask, and dest flags to the composite args struct.
[profile/ivi/pixman.git] / pixman / pixman.c
1 /* -*- Mode: c; c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t; -*- */
2 /*
3  * Copyright © 2000 SuSE, Inc.
4  * Copyright © 2007 Red Hat, Inc.
5  *
6  * Permission to use, copy, modify, distribute, and sell this software and its
7  * documentation for any purpose is hereby granted without fee, provided that
8  * the above copyright notice appear in all copies and that both that
9  * copyright notice and this permission notice appear in supporting
10  * documentation, and that the name of SuSE not be used in advertising or
11  * publicity pertaining to distribution of the software without specific,
12  * written prior permission.  SuSE makes no representations about the
13  * suitability of this software for any purpose.  It is provided "as is"
14  * without express or implied warranty.
15  *
16  * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
18  * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
20  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
21  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22  *
23  * Author:  Keith Packard, SuSE, Inc.
24  */
25
26 #ifdef HAVE_CONFIG_H
27 #include <config.h>
28 #endif
29 #include "pixman-private.h"
30
31 #include <stdlib.h>
32
33 static pixman_implementation_t *global_implementation;
34
35 #ifdef TOOLCHAIN_SUPPORTS_ATTRIBUTE_CONSTRUCTOR
36 static void __attribute__((constructor))
37 pixman_constructor (void)
38 {
39     global_implementation = _pixman_choose_implementation ();
40 }
41 #endif
42
43 static force_inline pixman_implementation_t *
44 get_implementation (void)
45 {
46 #ifndef TOOLCHAIN_SUPPORTS_ATTRIBUTE_CONSTRUCTOR
47     if (!global_implementation)
48         global_implementation = _pixman_choose_implementation ();
49 #endif
50     return global_implementation;
51 }
52
53 typedef struct operator_info_t operator_info_t;
54
55 struct operator_info_t
56 {
57     uint8_t     opaque_info[4];
58 };
59
60 #define PACK(neither, src, dest, both)                  \
61     {{      (uint8_t)PIXMAN_OP_ ## neither,             \
62             (uint8_t)PIXMAN_OP_ ## src,                 \
63             (uint8_t)PIXMAN_OP_ ## dest,                \
64             (uint8_t)PIXMAN_OP_ ## both         }}
65
66 static const operator_info_t operator_table[] =
67 {
68     /*    Neither Opaque         Src Opaque             Dst Opaque             Both Opaque */
69     PACK (CLEAR,                 CLEAR,                 CLEAR,                 CLEAR),
70     PACK (SRC,                   SRC,                   SRC,                   SRC),
71     PACK (DST,                   DST,                   DST,                   DST),
72     PACK (OVER,                  SRC,                   OVER,                  SRC),
73     PACK (OVER_REVERSE,          OVER_REVERSE,          DST,                   DST),
74     PACK (IN,                    IN,                    SRC,                   SRC),
75     PACK (IN_REVERSE,            DST,                   IN_REVERSE,            DST),
76     PACK (OUT,                   OUT,                   CLEAR,                 CLEAR),
77     PACK (OUT_REVERSE,           CLEAR,                 OUT_REVERSE,           CLEAR),
78     PACK (ATOP,                  IN,                    OVER,                  SRC),
79     PACK (ATOP_REVERSE,          OVER_REVERSE,          IN_REVERSE,            DST),
80     PACK (XOR,                   OUT,                   OUT_REVERSE,           CLEAR),
81     PACK (ADD,                   ADD,                   ADD,                   ADD),
82     PACK (SATURATE,              OVER_REVERSE,          DST,                   DST),
83
84     {{ 0 /* 0x0e */ }},
85     {{ 0 /* 0x0f */ }},
86
87     PACK (CLEAR,                 CLEAR,                 CLEAR,                 CLEAR),
88     PACK (SRC,                   SRC,                   SRC,                   SRC),
89     PACK (DST,                   DST,                   DST,                   DST),
90     PACK (DISJOINT_OVER,         DISJOINT_OVER,         DISJOINT_OVER,         DISJOINT_OVER),
91     PACK (DISJOINT_OVER_REVERSE, DISJOINT_OVER_REVERSE, DISJOINT_OVER_REVERSE, DISJOINT_OVER_REVERSE),
92     PACK (DISJOINT_IN,           DISJOINT_IN,           DISJOINT_IN,           DISJOINT_IN),
93     PACK (DISJOINT_IN_REVERSE,   DISJOINT_IN_REVERSE,   DISJOINT_IN_REVERSE,   DISJOINT_IN_REVERSE),
94     PACK (DISJOINT_OUT,          DISJOINT_OUT,          DISJOINT_OUT,          DISJOINT_OUT),
95     PACK (DISJOINT_OUT_REVERSE,  DISJOINT_OUT_REVERSE,  DISJOINT_OUT_REVERSE,  DISJOINT_OUT_REVERSE),
96     PACK (DISJOINT_ATOP,         DISJOINT_ATOP,         DISJOINT_ATOP,         DISJOINT_ATOP),
97     PACK (DISJOINT_ATOP_REVERSE, DISJOINT_ATOP_REVERSE, DISJOINT_ATOP_REVERSE, DISJOINT_ATOP_REVERSE),
98     PACK (DISJOINT_XOR,          DISJOINT_XOR,          DISJOINT_XOR,          DISJOINT_XOR),
99
100     {{ 0 /* 0x1c */ }},
101     {{ 0 /* 0x1d */ }},
102     {{ 0 /* 0x1e */ }},
103     {{ 0 /* 0x1f */ }},
104
105     PACK (CLEAR,                 CLEAR,                 CLEAR,                 CLEAR),
106     PACK (SRC,                   SRC,                   SRC,                   SRC),
107     PACK (DST,                   DST,                   DST,                   DST),
108     PACK (CONJOINT_OVER,         CONJOINT_OVER,         CONJOINT_OVER,         CONJOINT_OVER),
109     PACK (CONJOINT_OVER_REVERSE, CONJOINT_OVER_REVERSE, CONJOINT_OVER_REVERSE, CONJOINT_OVER_REVERSE),
110     PACK (CONJOINT_IN,           CONJOINT_IN,           CONJOINT_IN,           CONJOINT_IN),
111     PACK (CONJOINT_IN_REVERSE,   CONJOINT_IN_REVERSE,   CONJOINT_IN_REVERSE,   CONJOINT_IN_REVERSE),
112     PACK (CONJOINT_OUT,          CONJOINT_OUT,          CONJOINT_OUT,          CONJOINT_OUT),
113     PACK (CONJOINT_OUT_REVERSE,  CONJOINT_OUT_REVERSE,  CONJOINT_OUT_REVERSE,  CONJOINT_OUT_REVERSE),
114     PACK (CONJOINT_ATOP,         CONJOINT_ATOP,         CONJOINT_ATOP,         CONJOINT_ATOP),
115     PACK (CONJOINT_ATOP_REVERSE, CONJOINT_ATOP_REVERSE, CONJOINT_ATOP_REVERSE, CONJOINT_ATOP_REVERSE),
116     PACK (CONJOINT_XOR,          CONJOINT_XOR,          CONJOINT_XOR,          CONJOINT_XOR),
117
118     {{ 0 /* 0x2c */ }},
119     {{ 0 /* 0x2d */ }},
120     {{ 0 /* 0x2e */ }},
121     {{ 0 /* 0x2f */ }},
122
123     PACK (MULTIPLY,              MULTIPLY,              MULTIPLY,              MULTIPLY),
124     PACK (SCREEN,                SCREEN,                SCREEN,                SCREEN),
125     PACK (OVERLAY,               OVERLAY,               OVERLAY,               OVERLAY),
126     PACK (DARKEN,                DARKEN,                DARKEN,                DARKEN),
127     PACK (LIGHTEN,               LIGHTEN,               LIGHTEN,               LIGHTEN),
128     PACK (COLOR_DODGE,           COLOR_DODGE,           COLOR_DODGE,           COLOR_DODGE),
129     PACK (COLOR_BURN,            COLOR_BURN,            COLOR_BURN,            COLOR_BURN),
130     PACK (HARD_LIGHT,            HARD_LIGHT,            HARD_LIGHT,            HARD_LIGHT),
131     PACK (SOFT_LIGHT,            SOFT_LIGHT,            SOFT_LIGHT,            SOFT_LIGHT),
132     PACK (DIFFERENCE,            DIFFERENCE,            DIFFERENCE,            DIFFERENCE),
133     PACK (EXCLUSION,             EXCLUSION,             EXCLUSION,             EXCLUSION),
134     PACK (HSL_HUE,               HSL_HUE,               HSL_HUE,               HSL_HUE),
135     PACK (HSL_SATURATION,        HSL_SATURATION,        HSL_SATURATION,        HSL_SATURATION),
136     PACK (HSL_COLOR,             HSL_COLOR,             HSL_COLOR,             HSL_COLOR),
137     PACK (HSL_LUMINOSITY,        HSL_LUMINOSITY,        HSL_LUMINOSITY,        HSL_LUMINOSITY),
138 };
139
140 /*
141  * Optimize the current operator based on opacity of source or destination
142  * The output operator should be mathematically equivalent to the source.
143  */
144 static pixman_op_t
145 optimize_operator (pixman_op_t     op,
146                    uint32_t        src_flags,
147                    uint32_t        mask_flags,
148                    uint32_t        dst_flags)
149 {
150     pixman_bool_t is_source_opaque, is_dest_opaque;
151
152 #define OPAQUE_SHIFT 13
153     
154     COMPILE_TIME_ASSERT (FAST_PATH_IS_OPAQUE == (1 << OPAQUE_SHIFT));
155     
156     is_dest_opaque = (dst_flags & FAST_PATH_IS_OPAQUE);
157     is_source_opaque = ((src_flags & mask_flags) & FAST_PATH_IS_OPAQUE);
158
159     is_dest_opaque >>= OPAQUE_SHIFT - 1;
160     is_source_opaque >>= OPAQUE_SHIFT;
161
162     return operator_table[op].opaque_info[is_dest_opaque | is_source_opaque];
163 }
164
165 /*
166  * Computing composite region
167  */
168 static inline pixman_bool_t
169 clip_general_image (pixman_region32_t * region,
170                     pixman_region32_t * clip,
171                     int                 dx,
172                     int                 dy)
173 {
174     if (pixman_region32_n_rects (region) == 1 &&
175         pixman_region32_n_rects (clip) == 1)
176     {
177         pixman_box32_t *  rbox = pixman_region32_rectangles (region, NULL);
178         pixman_box32_t *  cbox = pixman_region32_rectangles (clip, NULL);
179         int v;
180
181         if (rbox->x1 < (v = cbox->x1 + dx))
182             rbox->x1 = v;
183         if (rbox->x2 > (v = cbox->x2 + dx))
184             rbox->x2 = v;
185         if (rbox->y1 < (v = cbox->y1 + dy))
186             rbox->y1 = v;
187         if (rbox->y2 > (v = cbox->y2 + dy))
188             rbox->y2 = v;
189         if (rbox->x1 >= rbox->x2 || rbox->y1 >= rbox->y2)
190         {
191             pixman_region32_init (region);
192             return FALSE;
193         }
194     }
195     else if (!pixman_region32_not_empty (clip))
196     {
197         return FALSE;
198     }
199     else
200     {
201         if (dx || dy)
202             pixman_region32_translate (region, -dx, -dy);
203
204         if (!pixman_region32_intersect (region, region, clip))
205             return FALSE;
206
207         if (dx || dy)
208             pixman_region32_translate (region, dx, dy);
209     }
210
211     return pixman_region32_not_empty (region);
212 }
213
214 static inline pixman_bool_t
215 clip_source_image (pixman_region32_t * region,
216                    pixman_image_t *    image,
217                    int                 dx,
218                    int                 dy)
219 {
220     /* Source clips are ignored, unless they are explicitly turned on
221      * and the clip in question was set by an X client. (Because if
222      * the clip was not set by a client, then it is a hierarchy
223      * clip and those should always be ignored for sources).
224      */
225     if (!image->common.clip_sources || !image->common.client_clip)
226         return TRUE;
227
228     return clip_general_image (region,
229                                &image->common.clip_region,
230                                dx, dy);
231 }
232
233 /*
234  * returns FALSE if the final region is empty.  Indistinguishable from
235  * an allocation failure, but rendering ignores those anyways.
236  */
237 static pixman_bool_t
238 pixman_compute_composite_region32 (pixman_region32_t * region,
239                                    pixman_image_t *    src_image,
240                                    pixman_image_t *    mask_image,
241                                    pixman_image_t *    dest_image,
242                                    int32_t             src_x,
243                                    int32_t             src_y,
244                                    int32_t             mask_x,
245                                    int32_t             mask_y,
246                                    int32_t             dest_x,
247                                    int32_t             dest_y,
248                                    int32_t             width,
249                                    int32_t             height)
250 {
251     region->extents.x1 = dest_x;
252     region->extents.x2 = dest_x + width;
253     region->extents.y1 = dest_y;
254     region->extents.y2 = dest_y + height;
255
256     region->extents.x1 = MAX (region->extents.x1, 0);
257     region->extents.y1 = MAX (region->extents.y1, 0);
258     region->extents.x2 = MIN (region->extents.x2, dest_image->bits.width);
259     region->extents.y2 = MIN (region->extents.y2, dest_image->bits.height);
260
261     region->data = 0;
262
263     /* Check for empty operation */
264     if (region->extents.x1 >= region->extents.x2 ||
265         region->extents.y1 >= region->extents.y2)
266     {
267         region->extents.x1 = 0;
268         region->extents.x2 = 0;
269         region->extents.y1 = 0;
270         region->extents.y2 = 0;
271         return FALSE;
272     }
273
274     if (dest_image->common.have_clip_region)
275     {
276         if (!clip_general_image (region, &dest_image->common.clip_region, 0, 0))
277             return FALSE;
278     }
279
280     if (dest_image->common.alpha_map)
281     {
282         if (!pixman_region32_intersect_rect (region, region,
283                                              dest_image->common.alpha_origin_x,
284                                              dest_image->common.alpha_origin_y,
285                                              dest_image->common.alpha_map->width,
286                                              dest_image->common.alpha_map->height))
287         {
288             return FALSE;
289         }
290         if (!pixman_region32_not_empty (region))
291             return FALSE;
292         if (dest_image->common.alpha_map->common.have_clip_region)
293         {
294             if (!clip_general_image (region, &dest_image->common.alpha_map->common.clip_region,
295                                      -dest_image->common.alpha_origin_x,
296                                      -dest_image->common.alpha_origin_y))
297             {
298                 return FALSE;
299             }
300         }
301     }
302
303     /* clip against src */
304     if (src_image->common.have_clip_region)
305     {
306         if (!clip_source_image (region, src_image, dest_x - src_x, dest_y - src_y))
307             return FALSE;
308     }
309     if (src_image->common.alpha_map && src_image->common.alpha_map->common.have_clip_region)
310     {
311         if (!clip_source_image (region, (pixman_image_t *)src_image->common.alpha_map,
312                                 dest_x - (src_x - src_image->common.alpha_origin_x),
313                                 dest_y - (src_y - src_image->common.alpha_origin_y)))
314         {
315             return FALSE;
316         }
317     }
318     /* clip against mask */
319     if (mask_image && mask_image->common.have_clip_region)
320     {
321         if (!clip_source_image (region, mask_image, dest_x - mask_x, dest_y - mask_y))
322             return FALSE;
323
324         if (mask_image->common.alpha_map && mask_image->common.alpha_map->common.have_clip_region)
325         {
326             if (!clip_source_image (region, (pixman_image_t *)mask_image->common.alpha_map,
327                                     dest_x - (mask_x - mask_image->common.alpha_origin_x),
328                                     dest_y - (mask_y - mask_image->common.alpha_origin_y)))
329             {
330                 return FALSE;
331             }
332         }
333     }
334
335     return TRUE;
336 }
337
338 #define N_CACHED_FAST_PATHS 8
339
340 typedef struct
341 {
342     struct
343     {
344         pixman_implementation_t *       imp;
345         pixman_fast_path_t              fast_path;
346     } cache [N_CACHED_FAST_PATHS];
347 } cache_t;
348
349 PIXMAN_DEFINE_THREAD_LOCAL (cache_t, fast_path_cache);
350
351 static force_inline pixman_bool_t
352 lookup_composite_function (pixman_op_t                  op,
353                            pixman_format_code_t         src_format,
354                            uint32_t                     src_flags,
355                            pixman_format_code_t         mask_format,
356                            uint32_t                     mask_flags,
357                            pixman_format_code_t         dest_format,
358                            uint32_t                     dest_flags,
359                            pixman_implementation_t    **out_imp,
360                            pixman_composite_func_t     *out_func)
361 {
362     pixman_implementation_t *imp;
363     cache_t *cache;
364     int i;
365
366     /* Check cache for fast paths */
367     cache = PIXMAN_GET_THREAD_LOCAL (fast_path_cache);
368
369     for (i = 0; i < N_CACHED_FAST_PATHS; ++i)
370     {
371         const pixman_fast_path_t *info = &(cache->cache[i].fast_path);
372
373         /* Note that we check for equality here, not whether
374          * the cached fast path matches. This is to prevent
375          * us from selecting an overly general fast path
376          * when a more specific one would work.
377          */
378         if (info->op == op                      &&
379             info->src_format == src_format      &&
380             info->mask_format == mask_format    &&
381             info->dest_format == dest_format    &&
382             info->src_flags == src_flags        &&
383             info->mask_flags == mask_flags      &&
384             info->dest_flags == dest_flags      &&
385             info->func)
386         {
387             *out_imp = cache->cache[i].imp;
388             *out_func = cache->cache[i].fast_path.func;
389
390             goto update_cache;
391         }
392     }
393
394     for (imp = get_implementation (); imp != NULL; imp = imp->delegate)
395     {
396         const pixman_fast_path_t *info = imp->fast_paths;
397
398         while (info->op != PIXMAN_OP_NONE)
399         {
400             if ((info->op == op || info->op == PIXMAN_OP_any)           &&
401                 /* Formats */
402                 ((info->src_format == src_format) ||
403                  (info->src_format == PIXMAN_any))                      &&
404                 ((info->mask_format == mask_format) ||
405                  (info->mask_format == PIXMAN_any))                     &&
406                 ((info->dest_format == dest_format) ||
407                  (info->dest_format == PIXMAN_any))                     &&
408                 /* Flags */
409                 (info->src_flags & src_flags) == info->src_flags        &&
410                 (info->mask_flags & mask_flags) == info->mask_flags     &&
411                 (info->dest_flags & dest_flags) == info->dest_flags)
412             {
413                 *out_imp = imp;
414                 *out_func = info->func;
415
416                 /* Set i to the last spot in the cache so that the
417                  * move-to-front code below will work
418                  */
419                 i = N_CACHED_FAST_PATHS - 1;
420
421                 goto update_cache;
422             }
423
424             ++info;
425         }
426     }
427     return FALSE;
428
429 update_cache:
430     if (i)
431     {
432         while (i--)
433             cache->cache[i + 1] = cache->cache[i];
434
435         cache->cache[0].imp = *out_imp;
436         cache->cache[0].fast_path.op = op;
437         cache->cache[0].fast_path.src_format = src_format;
438         cache->cache[0].fast_path.src_flags = src_flags;
439         cache->cache[0].fast_path.mask_format = mask_format;
440         cache->cache[0].fast_path.mask_flags = mask_flags;
441         cache->cache[0].fast_path.dest_format = dest_format;
442         cache->cache[0].fast_path.dest_flags = dest_flags;
443         cache->cache[0].fast_path.func = *out_func;
444     }
445
446     return TRUE;
447 }
448
449 typedef struct
450 {
451     pixman_fixed_48_16_t        x1;
452     pixman_fixed_48_16_t        y1;
453     pixman_fixed_48_16_t        x2;
454     pixman_fixed_48_16_t        y2;
455 } box_48_16_t;
456
457 static pixman_bool_t
458 compute_transformed_extents (pixman_transform_t *transform,
459                              const pixman_box32_t *extents,
460                              box_48_16_t *transformed)
461 {
462     pixman_fixed_48_16_t tx1, ty1, tx2, ty2;
463     pixman_fixed_t x1, y1, x2, y2;
464     int i;
465
466     x1 = pixman_int_to_fixed (extents->x1) + pixman_fixed_1 / 2;
467     y1 = pixman_int_to_fixed (extents->y1) + pixman_fixed_1 / 2;
468     x2 = pixman_int_to_fixed (extents->x2) - pixman_fixed_1 / 2;
469     y2 = pixman_int_to_fixed (extents->y2) - pixman_fixed_1 / 2;
470
471     if (!transform)
472     {
473         transformed->x1 = x1;
474         transformed->y1 = y1;
475         transformed->x2 = x2;
476         transformed->y2 = y2;
477
478         return TRUE;
479     }
480
481     tx1 = ty1 = INT64_MAX;
482     tx2 = ty2 = INT64_MIN;
483
484     for (i = 0; i < 4; ++i)
485     {
486         pixman_fixed_48_16_t tx, ty;
487         pixman_vector_t v;
488
489         v.vector[0] = (i & 0x01)? x1 : x2;
490         v.vector[1] = (i & 0x02)? y1 : y2;
491         v.vector[2] = pixman_fixed_1;
492
493         if (!pixman_transform_point (transform, &v))
494             return FALSE;
495
496         tx = (pixman_fixed_48_16_t)v.vector[0];
497         ty = (pixman_fixed_48_16_t)v.vector[1];
498
499         if (tx < tx1)
500             tx1 = tx;
501         if (ty < ty1)
502             ty1 = ty;
503         if (tx > tx2)
504             tx2 = tx;
505         if (ty > ty2)
506             ty2 = ty;
507     }
508
509     transformed->x1 = tx1;
510     transformed->y1 = ty1;
511     transformed->x2 = tx2;
512     transformed->y2 = ty2;
513
514     return TRUE;
515 }
516
517 #define IS_16BIT(x) (((x) >= INT16_MIN) && ((x) <= INT16_MAX))
518 #define ABS(f)      (((f) < 0)?  (-(f)) : (f))
519 #define IS_16_16(f) (((f) >= pixman_min_fixed_48_16 && ((f) <= pixman_max_fixed_48_16)))
520
521 static pixman_bool_t
522 analyze_extent (pixman_image_t       *image,
523                 const pixman_box32_t *extents,
524                 uint32_t             *flags)
525 {
526     pixman_transform_t *transform;
527     pixman_fixed_t x_off, y_off;
528     pixman_fixed_t width, height;
529     pixman_fixed_t *params;
530     box_48_16_t transformed;
531     pixman_box32_t exp_extents;
532
533     if (!image)
534         return TRUE;
535
536     /* Some compositing functions walk one step
537      * outside the destination rectangle, so we
538      * check here that the expanded-by-one source
539      * extents in destination space fits in 16 bits
540      */
541     if (!IS_16BIT (extents->x1 - 1)             ||
542         !IS_16BIT (extents->y1 - 1)             ||
543         !IS_16BIT (extents->x2 + 1)             ||
544         !IS_16BIT (extents->y2 + 1))
545     {
546         return FALSE;
547     }
548
549     transform = image->common.transform;
550     if (image->common.type == BITS)
551     {
552         /* During repeat mode calculations we might convert the
553          * width/height of an image to fixed 16.16, so we need
554          * them to be smaller than 16 bits.
555          */
556         if (image->bits.width >= 0x7fff || image->bits.height >= 0x7fff)
557             return FALSE;
558
559         if ((image->common.flags & FAST_PATH_ID_TRANSFORM) == FAST_PATH_ID_TRANSFORM &&
560             extents->x1 >= 0 &&
561             extents->y1 >= 0 &&
562             extents->x2 <= image->bits.width &&
563             extents->y2 <= image->bits.height)
564         {
565             *flags |= FAST_PATH_SAMPLES_COVER_CLIP_NEAREST;
566             return TRUE;
567         }
568
569         switch (image->common.filter)
570         {
571         case PIXMAN_FILTER_CONVOLUTION:
572             params = image->common.filter_params;
573             x_off = - pixman_fixed_e - ((params[0] - pixman_fixed_1) >> 1);
574             y_off = - pixman_fixed_e - ((params[1] - pixman_fixed_1) >> 1);
575             width = params[0];
576             height = params[1];
577             break;
578
579         case PIXMAN_FILTER_GOOD:
580         case PIXMAN_FILTER_BEST:
581         case PIXMAN_FILTER_BILINEAR:
582             x_off = - pixman_fixed_1 / 2;
583             y_off = - pixman_fixed_1 / 2;
584             width = pixman_fixed_1;
585             height = pixman_fixed_1;
586             break;
587
588         case PIXMAN_FILTER_FAST:
589         case PIXMAN_FILTER_NEAREST:
590             x_off = - pixman_fixed_e;
591             y_off = - pixman_fixed_e;
592             width = 0;
593             height = 0;
594             break;
595
596         default:
597             return FALSE;
598         }
599     }
600     else
601     {
602         x_off = 0;
603         y_off = 0;
604         width = 0;
605         height = 0;
606     }
607
608     if (!compute_transformed_extents (transform, extents, &transformed))
609         return FALSE;
610
611     /* Expand the source area by a tiny bit so account of different rounding that
612      * may happen during sampling. Note that (8 * pixman_fixed_e) is very far from
613      * 0.5 so this won't cause the area computed to be overly pessimistic.
614      */
615     transformed.x1 -= 8 * pixman_fixed_e;
616     transformed.y1 -= 8 * pixman_fixed_e;
617     transformed.x2 += 8 * pixman_fixed_e;
618     transformed.y2 += 8 * pixman_fixed_e;
619
620     if (image->common.type == BITS)
621     {
622         if (pixman_fixed_to_int (transformed.x1) >= 0                   &&
623             pixman_fixed_to_int (transformed.y1) >= 0                   &&
624             pixman_fixed_to_int (transformed.x2) < image->bits.width    &&
625             pixman_fixed_to_int (transformed.y2) < image->bits.height)
626         {
627             *flags |= FAST_PATH_SAMPLES_COVER_CLIP_NEAREST;
628         }
629
630         if (pixman_fixed_to_int (transformed.x1 - pixman_fixed_1 / 2) >= 0                &&
631             pixman_fixed_to_int (transformed.y1 - pixman_fixed_1 / 2) >= 0                &&
632             pixman_fixed_to_int (transformed.x2 + pixman_fixed_1 / 2) < image->bits.width &&
633             pixman_fixed_to_int (transformed.y2 + pixman_fixed_1 / 2) < image->bits.height)
634         {
635             *flags |= FAST_PATH_SAMPLES_COVER_CLIP_BILINEAR;
636         }
637     }
638
639     /* Check we don't overflow when the destination extents are expanded by one.
640      * This ensures that compositing functions can simply walk the source space
641      * using 16.16 variables without worrying about overflow.
642      */
643     exp_extents = *extents;
644     exp_extents.x1 -= 1;
645     exp_extents.y1 -= 1;
646     exp_extents.x2 += 1;
647     exp_extents.y2 += 1;
648
649     if (!compute_transformed_extents (transform, &exp_extents, &transformed))
650         return FALSE;
651     
652     if (!IS_16_16 (transformed.x1 + x_off - 8 * pixman_fixed_e) ||
653         !IS_16_16 (transformed.y1 + y_off - 8 * pixman_fixed_e) ||
654         !IS_16_16 (transformed.x2 + x_off + 8 * pixman_fixed_e + width) ||
655         !IS_16_16 (transformed.y2 + y_off + 8 * pixman_fixed_e + height))
656     {
657         return FALSE;
658     }
659
660     return TRUE;
661 }
662
663 /*
664  * Work around GCC bug causing crashes in Mozilla with SSE2
665  *
666  * When using -msse, gcc generates movdqa instructions assuming that
667  * the stack is 16 byte aligned. Unfortunately some applications, such
668  * as Mozilla and Mono, end up aligning the stack to 4 bytes, which
669  * causes the movdqa instructions to fail.
670  *
671  * The __force_align_arg_pointer__ makes gcc generate a prologue that
672  * realigns the stack pointer to 16 bytes.
673  *
674  * On x86-64 this is not necessary because the standard ABI already
675  * calls for a 16 byte aligned stack.
676  *
677  * See https://bugs.freedesktop.org/show_bug.cgi?id=15693
678  */
679 #if defined (USE_SSE2) && defined(__GNUC__) && !defined(__x86_64__) && !defined(__amd64__)
680 __attribute__((__force_align_arg_pointer__))
681 #endif
682 PIXMAN_EXPORT void
683 pixman_image_composite32 (pixman_op_t      op,
684                           pixman_image_t * src,
685                           pixman_image_t * mask,
686                           pixman_image_t * dest,
687                           int32_t          src_x,
688                           int32_t          src_y,
689                           int32_t          mask_x,
690                           int32_t          mask_y,
691                           int32_t          dest_x,
692                           int32_t          dest_y,
693                           int32_t          width,
694                           int32_t          height)
695 {
696     pixman_format_code_t src_format, mask_format, dest_format;
697     uint32_t src_flags, mask_flags, dest_flags;
698     pixman_region32_t region;
699     pixman_box32_t extents;
700     pixman_implementation_t *imp;
701     pixman_composite_func_t func;
702
703     _pixman_image_validate (src);
704     if (mask)
705         _pixman_image_validate (mask);
706     _pixman_image_validate (dest);
707
708     src_format = src->common.extended_format_code;
709     src_flags = src->common.flags;
710
711     if (mask)
712     {
713         mask_format = mask->common.extended_format_code;
714         mask_flags = mask->common.flags;
715     }
716     else
717     {
718         mask_format = PIXMAN_null;
719         mask_flags = FAST_PATH_IS_OPAQUE;
720     }
721
722     dest_format = dest->common.extended_format_code;
723     dest_flags = dest->common.flags;
724
725     /* Check for pixbufs */
726     if ((mask_format == PIXMAN_a8r8g8b8 || mask_format == PIXMAN_a8b8g8r8) &&
727         (src->type == BITS && src->bits.bits == mask->bits.bits)           &&
728         (src->common.repeat == mask->common.repeat)                        &&
729         (src_x == mask_x && src_y == mask_y))
730     {
731         if (src_format == PIXMAN_x8b8g8r8)
732             src_format = mask_format = PIXMAN_pixbuf;
733         else if (src_format == PIXMAN_x8r8g8b8)
734             src_format = mask_format = PIXMAN_rpixbuf;
735     }
736
737     pixman_region32_init (&region);
738
739     if (!pixman_compute_composite_region32 (
740             &region, src, mask, dest,
741             src_x, src_y, mask_x, mask_y, dest_x, dest_y, width, height))
742     {
743         goto out;
744     }
745
746     extents = *pixman_region32_extents (&region);
747
748     extents.x1 -= dest_x - src_x;
749     extents.y1 -= dest_y - src_y;
750     extents.x2 -= dest_x - src_x;
751     extents.y2 -= dest_y - src_y;
752
753     if (!analyze_extent (src, &extents, &src_flags))
754         goto out;
755
756     extents.x1 -= src_x - mask_x;
757     extents.y1 -= src_y - mask_y;
758     extents.x2 -= src_x - mask_x;
759     extents.y2 -= src_y - mask_y;
760
761     if (!analyze_extent (mask, &extents, &mask_flags))
762         goto out;
763
764     /* If the clip is within the source samples, and the samples are
765      * opaque, then the source is effectively opaque.
766      */
767 #define NEAREST_OPAQUE  (FAST_PATH_SAMPLES_OPAQUE |                     \
768                          FAST_PATH_NEAREST_FILTER |                     \
769                          FAST_PATH_SAMPLES_COVER_CLIP_NEAREST)
770 #define BILINEAR_OPAQUE (FAST_PATH_SAMPLES_OPAQUE |                     \
771                          FAST_PATH_BILINEAR_FILTER |                    \
772                          FAST_PATH_SAMPLES_COVER_CLIP_BILINEAR)
773
774     if ((src_flags & NEAREST_OPAQUE) == NEAREST_OPAQUE ||
775         (src_flags & BILINEAR_OPAQUE) == BILINEAR_OPAQUE)
776     {
777         src_flags |= FAST_PATH_IS_OPAQUE;
778     }
779
780     if ((mask_flags & NEAREST_OPAQUE) == NEAREST_OPAQUE ||
781         (mask_flags & BILINEAR_OPAQUE) == BILINEAR_OPAQUE)
782     {
783         mask_flags |= FAST_PATH_IS_OPAQUE;
784     }
785
786     /*
787      * Check if we can replace our operator by a simpler one
788      * if the src or dest are opaque. The output operator should be
789      * mathematically equivalent to the source.
790      */
791     op = optimize_operator (op, src_flags, mask_flags, dest_flags);
792
793     if (lookup_composite_function (op,
794                                    src_format, src_flags,
795                                    mask_format, mask_flags,
796                                    dest_format, dest_flags,
797                                    &imp, &func))
798     {
799         pixman_composite_info_t info;
800         const pixman_box32_t *pbox;
801         int n;
802
803         info.op = op;
804         info.src_image = src;
805         info.mask_image = mask;
806         info.dest_image = dest;
807         info.src_flags = src_flags;
808         info.mask_flags = mask_flags;
809         info.dest_flags = dest_flags;
810
811         pbox = pixman_region32_rectangles (&region, &n);
812
813         while (n--)
814         {
815             info.src_x = pbox->x1 + src_x - dest_x;
816             info.src_y = pbox->y1 + src_y - dest_y;
817             info.mask_x = pbox->x1 + mask_x - dest_x;
818             info.mask_y = pbox->y1 + mask_y - dest_y;
819             info.dest_x = pbox->x1;
820             info.dest_y = pbox->y1;
821             info.width = pbox->x2 - pbox->x1;
822             info.height = pbox->y2 - pbox->y1;
823
824             func (imp, &info);
825
826             pbox++;
827         }
828     }
829
830 out:
831     pixman_region32_fini (&region);
832 }
833
834 PIXMAN_EXPORT void
835 pixman_image_composite (pixman_op_t      op,
836                         pixman_image_t * src,
837                         pixman_image_t * mask,
838                         pixman_image_t * dest,
839                         int16_t          src_x,
840                         int16_t          src_y,
841                         int16_t          mask_x,
842                         int16_t          mask_y,
843                         int16_t          dest_x,
844                         int16_t          dest_y,
845                         uint16_t         width,
846                         uint16_t         height)
847 {
848     pixman_image_composite32 (op, src, mask, dest, src_x, src_y, 
849                               mask_x, mask_y, dest_x, dest_y, width, height);
850 }
851
852 PIXMAN_EXPORT pixman_bool_t
853 pixman_blt (uint32_t *src_bits,
854             uint32_t *dst_bits,
855             int       src_stride,
856             int       dst_stride,
857             int       src_bpp,
858             int       dst_bpp,
859             int       src_x,
860             int       src_y,
861             int       dest_x,
862             int       dest_y,
863             int       width,
864             int       height)
865 {
866     return _pixman_implementation_blt (get_implementation(),
867                                        src_bits, dst_bits, src_stride, dst_stride,
868                                        src_bpp, dst_bpp,
869                                        src_x, src_y,
870                                        dest_x, dest_y,
871                                        width, height);
872 }
873
874 PIXMAN_EXPORT pixman_bool_t
875 pixman_fill (uint32_t *bits,
876              int       stride,
877              int       bpp,
878              int       x,
879              int       y,
880              int       width,
881              int       height,
882              uint32_t xor)
883 {
884     return _pixman_implementation_fill (
885         get_implementation(), bits, stride, bpp, x, y, width, height, xor);
886 }
887
888 static uint32_t
889 color_to_uint32 (const pixman_color_t *color)
890 {
891     return
892         (color->alpha >> 8 << 24) |
893         (color->red >> 8 << 16) |
894         (color->green & 0xff00) |
895         (color->blue >> 8);
896 }
897
898 static pixman_bool_t
899 color_to_pixel (pixman_color_t *     color,
900                 uint32_t *           pixel,
901                 pixman_format_code_t format)
902 {
903     uint32_t c = color_to_uint32 (color);
904
905     if (!(format == PIXMAN_a8r8g8b8     ||
906           format == PIXMAN_x8r8g8b8     ||
907           format == PIXMAN_a8b8g8r8     ||
908           format == PIXMAN_x8b8g8r8     ||
909           format == PIXMAN_b8g8r8a8     ||
910           format == PIXMAN_b8g8r8x8     ||
911           format == PIXMAN_r8g8b8a8     ||
912           format == PIXMAN_r8g8b8x8     ||
913           format == PIXMAN_r5g6b5       ||
914           format == PIXMAN_b5g6r5       ||
915           format == PIXMAN_a8           ||
916           format == PIXMAN_a1))
917     {
918         return FALSE;
919     }
920
921     if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_ABGR)
922     {
923         c = ((c & 0xff000000) >>  0) |
924             ((c & 0x00ff0000) >> 16) |
925             ((c & 0x0000ff00) >>  0) |
926             ((c & 0x000000ff) << 16);
927     }
928     if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_BGRA)
929     {
930         c = ((c & 0xff000000) >> 24) |
931             ((c & 0x00ff0000) >>  8) |
932             ((c & 0x0000ff00) <<  8) |
933             ((c & 0x000000ff) << 24);
934     }
935     if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_RGBA)
936         c = ((c & 0xff000000) >> 24) | (c << 8);
937
938     if (format == PIXMAN_a1)
939         c = c >> 31;
940     else if (format == PIXMAN_a8)
941         c = c >> 24;
942     else if (format == PIXMAN_r5g6b5 ||
943              format == PIXMAN_b5g6r5)
944         c = CONVERT_8888_TO_0565 (c);
945
946 #if 0
947     printf ("color: %x %x %x %x\n", color->alpha, color->red, color->green, color->blue);
948     printf ("pixel: %x\n", c);
949 #endif
950
951     *pixel = c;
952     return TRUE;
953 }
954
955 PIXMAN_EXPORT pixman_bool_t
956 pixman_image_fill_rectangles (pixman_op_t                 op,
957                               pixman_image_t *            dest,
958                               pixman_color_t *            color,
959                               int                         n_rects,
960                               const pixman_rectangle16_t *rects)
961 {
962     pixman_box32_t stack_boxes[6];
963     pixman_box32_t *boxes;
964     pixman_bool_t result;
965     int i;
966
967     if (n_rects > 6)
968     {
969         boxes = pixman_malloc_ab (sizeof (pixman_box32_t), n_rects);
970         if (boxes == NULL)
971             return FALSE;
972     }
973     else
974     {
975         boxes = stack_boxes;
976     }
977
978     for (i = 0; i < n_rects; ++i)
979     {
980         boxes[i].x1 = rects[i].x;
981         boxes[i].y1 = rects[i].y;
982         boxes[i].x2 = boxes[i].x1 + rects[i].width;
983         boxes[i].y2 = boxes[i].y1 + rects[i].height;
984     }
985
986     result = pixman_image_fill_boxes (op, dest, color, n_rects, boxes);
987
988     if (boxes != stack_boxes)
989         free (boxes);
990     
991     return result;
992 }
993
994 PIXMAN_EXPORT pixman_bool_t
995 pixman_image_fill_boxes (pixman_op_t           op,
996                          pixman_image_t *      dest,
997                          pixman_color_t *      color,
998                          int                   n_boxes,
999                          const pixman_box32_t *boxes)
1000 {
1001     pixman_image_t *solid;
1002     pixman_color_t c;
1003     int i;
1004
1005     _pixman_image_validate (dest);
1006     
1007     if (color->alpha == 0xffff)
1008     {
1009         if (op == PIXMAN_OP_OVER)
1010             op = PIXMAN_OP_SRC;
1011     }
1012
1013     if (op == PIXMAN_OP_CLEAR)
1014     {
1015         c.red = 0;
1016         c.green = 0;
1017         c.blue = 0;
1018         c.alpha = 0;
1019
1020         color = &c;
1021
1022         op = PIXMAN_OP_SRC;
1023     }
1024
1025     if (op == PIXMAN_OP_SRC)
1026     {
1027         uint32_t pixel;
1028
1029         if (color_to_pixel (color, &pixel, dest->bits.format))
1030         {
1031             pixman_region32_t fill_region;
1032             int n_rects, j;
1033             pixman_box32_t *rects;
1034
1035             if (!pixman_region32_init_rects (&fill_region, boxes, n_boxes))
1036                 return FALSE;
1037
1038             if (dest->common.have_clip_region)
1039             {
1040                 if (!pixman_region32_intersect (&fill_region,
1041                                                 &fill_region,
1042                                                 &dest->common.clip_region))
1043                     return FALSE;
1044             }
1045
1046             rects = pixman_region32_rectangles (&fill_region, &n_rects);
1047             for (j = 0; j < n_rects; ++j)
1048             {
1049                 const pixman_box32_t *rect = &(rects[j]);
1050                 pixman_fill (dest->bits.bits, dest->bits.rowstride, PIXMAN_FORMAT_BPP (dest->bits.format),
1051                              rect->x1, rect->y1, rect->x2 - rect->x1, rect->y2 - rect->y1,
1052                              pixel);
1053             }
1054
1055             pixman_region32_fini (&fill_region);
1056             return TRUE;
1057         }
1058     }
1059
1060     solid = pixman_image_create_solid_fill (color);
1061     if (!solid)
1062         return FALSE;
1063
1064     for (i = 0; i < n_boxes; ++i)
1065     {
1066         const pixman_box32_t *box = &(boxes[i]);
1067
1068         pixman_image_composite32 (op, solid, NULL, dest,
1069                                   0, 0, 0, 0,
1070                                   box->x1, box->y1,
1071                                   box->x2 - box->x1, box->y2 - box->y1);
1072     }
1073
1074     pixman_image_unref (solid);
1075
1076     return TRUE;
1077 }
1078
1079 /**
1080  * pixman_version:
1081  *
1082  * Returns the version of the pixman library encoded in a single
1083  * integer as per %PIXMAN_VERSION_ENCODE. The encoding ensures that
1084  * later versions compare greater than earlier versions.
1085  *
1086  * A run-time comparison to check that pixman's version is greater than
1087  * or equal to version X.Y.Z could be performed as follows:
1088  *
1089  * <informalexample><programlisting>
1090  * if (pixman_version() >= PIXMAN_VERSION_ENCODE(X,Y,Z)) {...}
1091  * </programlisting></informalexample>
1092  *
1093  * See also pixman_version_string() as well as the compile-time
1094  * equivalents %PIXMAN_VERSION and %PIXMAN_VERSION_STRING.
1095  *
1096  * Return value: the encoded version.
1097  **/
1098 PIXMAN_EXPORT int
1099 pixman_version (void)
1100 {
1101     return PIXMAN_VERSION;
1102 }
1103
1104 /**
1105  * pixman_version_string:
1106  *
1107  * Returns the version of the pixman library as a human-readable string
1108  * of the form "X.Y.Z".
1109  *
1110  * See also pixman_version() as well as the compile-time equivalents
1111  * %PIXMAN_VERSION_STRING and %PIXMAN_VERSION.
1112  *
1113  * Return value: a string containing the version.
1114  **/
1115 PIXMAN_EXPORT const char*
1116 pixman_version_string (void)
1117 {
1118     return PIXMAN_VERSION_STRING;
1119 }
1120
1121 /**
1122  * pixman_format_supported_source:
1123  * @format: A pixman_format_code_t format
1124  *
1125  * Return value: whether the provided format code is a supported
1126  * format for a pixman surface used as a source in
1127  * rendering.
1128  *
1129  * Currently, all pixman_format_code_t values are supported.
1130  **/
1131 PIXMAN_EXPORT pixman_bool_t
1132 pixman_format_supported_source (pixman_format_code_t format)
1133 {
1134     switch (format)
1135     {
1136     /* 32 bpp formats */
1137     case PIXMAN_a2b10g10r10:
1138     case PIXMAN_x2b10g10r10:
1139     case PIXMAN_a2r10g10b10:
1140     case PIXMAN_x2r10g10b10:
1141     case PIXMAN_a8r8g8b8:
1142     case PIXMAN_x8r8g8b8:
1143     case PIXMAN_a8b8g8r8:
1144     case PIXMAN_x8b8g8r8:
1145     case PIXMAN_b8g8r8a8:
1146     case PIXMAN_b8g8r8x8:
1147     case PIXMAN_r8g8b8a8:
1148     case PIXMAN_r8g8b8x8:
1149     case PIXMAN_r8g8b8:
1150     case PIXMAN_b8g8r8:
1151     case PIXMAN_r5g6b5:
1152     case PIXMAN_b5g6r5:
1153     case PIXMAN_x14r6g6b6:
1154     /* 16 bpp formats */
1155     case PIXMAN_a1r5g5b5:
1156     case PIXMAN_x1r5g5b5:
1157     case PIXMAN_a1b5g5r5:
1158     case PIXMAN_x1b5g5r5:
1159     case PIXMAN_a4r4g4b4:
1160     case PIXMAN_x4r4g4b4:
1161     case PIXMAN_a4b4g4r4:
1162     case PIXMAN_x4b4g4r4:
1163     /* 8bpp formats */
1164     case PIXMAN_a8:
1165     case PIXMAN_r3g3b2:
1166     case PIXMAN_b2g3r3:
1167     case PIXMAN_a2r2g2b2:
1168     case PIXMAN_a2b2g2r2:
1169     case PIXMAN_c8:
1170     case PIXMAN_g8:
1171     case PIXMAN_x4a4:
1172     /* Collides with PIXMAN_c8
1173        case PIXMAN_x4c4:
1174      */
1175     /* Collides with PIXMAN_g8
1176        case PIXMAN_x4g4:
1177      */
1178     /* 4bpp formats */
1179     case PIXMAN_a4:
1180     case PIXMAN_r1g2b1:
1181     case PIXMAN_b1g2r1:
1182     case PIXMAN_a1r1g1b1:
1183     case PIXMAN_a1b1g1r1:
1184     case PIXMAN_c4:
1185     case PIXMAN_g4:
1186     /* 1bpp formats */
1187     case PIXMAN_a1:
1188     case PIXMAN_g1:
1189     /* YUV formats */
1190     case PIXMAN_yuy2:
1191     case PIXMAN_yv12:
1192         return TRUE;
1193
1194     default:
1195         return FALSE;
1196     }
1197 }
1198
1199 /**
1200  * pixman_format_supported_destination:
1201  * @format: A pixman_format_code_t format
1202  *
1203  * Return value: whether the provided format code is a supported
1204  * format for a pixman surface used as a destination in
1205  * rendering.
1206  *
1207  * Currently, all pixman_format_code_t values are supported
1208  * except for the YUV formats.
1209  **/
1210 PIXMAN_EXPORT pixman_bool_t
1211 pixman_format_supported_destination (pixman_format_code_t format)
1212 {
1213     /* YUV formats cannot be written to at the moment */
1214     if (format == PIXMAN_yuy2 || format == PIXMAN_yv12)
1215         return FALSE;
1216
1217     return pixman_format_supported_source (format);
1218 }
1219
1220 PIXMAN_EXPORT pixman_bool_t
1221 pixman_compute_composite_region (pixman_region16_t * region,
1222                                  pixman_image_t *    src_image,
1223                                  pixman_image_t *    mask_image,
1224                                  pixman_image_t *    dest_image,
1225                                  int16_t             src_x,
1226                                  int16_t             src_y,
1227                                  int16_t             mask_x,
1228                                  int16_t             mask_y,
1229                                  int16_t             dest_x,
1230                                  int16_t             dest_y,
1231                                  uint16_t            width,
1232                                  uint16_t            height)
1233 {
1234     pixman_region32_t r32;
1235     pixman_bool_t retval;
1236
1237     pixman_region32_init (&r32);
1238
1239     retval = pixman_compute_composite_region32 (
1240         &r32, src_image, mask_image, dest_image,
1241         src_x, src_y, mask_x, mask_y, dest_x, dest_y,
1242         width, height);
1243
1244     if (retval)
1245     {
1246         if (!pixman_region16_copy_from_region32 (region, &r32))
1247             retval = FALSE;
1248     }
1249
1250     pixman_region32_fini (&r32);
1251     return retval;
1252 }