Strength reduce certain conjoint/disjoint to their normal counterparts.
[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 *imp;
34
35 #define PACK(a, b, c, d)                        \
36     (((uint8_t)PIXMAN_OP_ ## a <<  0)   |       \
37      ((uint8_t)PIXMAN_OP_ ## b <<  8)   |       \
38      ((uint8_t)PIXMAN_OP_ ## c << 16)   |       \
39      ((uint8_t)PIXMAN_OP_ ## d << 24))
40
41 static const uint32_t operator_table[] =
42 {
43     /*    Neither Opaque         Src Opaque             Dst Opaque             Both Opaque */
44     PACK (CLEAR,                 CLEAR,                 CLEAR,                 CLEAR),
45     PACK (SRC,                   SRC,                   SRC,                   SRC),
46     PACK (DST,                   DST,                   DST,                   DST),
47     PACK (OVER,                  SRC,                   OVER,                  SRC),
48     PACK (OVER_REVERSE,          OVER_REVERSE,          DST,                   DST),
49     PACK (IN,                    IN,                    SRC,                   SRC),
50     PACK (IN_REVERSE,            DST,                   IN_REVERSE,            DST),
51     PACK (OUT,                   OUT,                   CLEAR,                 CLEAR),
52     PACK (OUT_REVERSE,           CLEAR,                 OUT_REVERSE,           CLEAR),
53     PACK (ATOP,                  IN,                    OVER,                  SRC),
54     PACK (ATOP_REVERSE,          OVER_REVERSE,          IN_REVERSE,            DST),
55     PACK (XOR,                   OUT,                   OUT_REVERSE,           CLEAR),
56     PACK (ADD,                   ADD,                   ADD,                   ADD),
57     PACK (SATURATE,              OVER_REVERSE,          DST,                   DST),
58
59     0 /* 0x0e */,
60     0 /* 0x0f */,
61
62     PACK (CLEAR,                 CLEAR,                 CLEAR,                 CLEAR),
63     PACK (SRC,                   SRC,                   SRC,                   SRC),
64     PACK (DST,                   DST,                   DST,                   DST),
65     PACK (DISJOINT_OVER,         DISJOINT_OVER,         DISJOINT_OVER,         DISJOINT_OVER),
66     PACK (DISJOINT_OVER_REVERSE, DISJOINT_OVER_REVERSE, DISJOINT_OVER_REVERSE, DISJOINT_OVER_REVERSE),
67     PACK (DISJOINT_IN,           DISJOINT_IN,           DISJOINT_IN,           DISJOINT_IN),
68     PACK (DISJOINT_IN_REVERSE,   DISJOINT_IN_REVERSE,   DISJOINT_IN_REVERSE,   DISJOINT_IN_REVERSE),
69     PACK (DISJOINT_OUT,          DISJOINT_OUT,          DISJOINT_OUT,          DISJOINT_OUT),
70     PACK (DISJOINT_OUT_REVERSE,  DISJOINT_OUT_REVERSE,  DISJOINT_OUT_REVERSE,  DISJOINT_OUT_REVERSE),
71     PACK (DISJOINT_ATOP,         DISJOINT_ATOP,         DISJOINT_ATOP,         DISJOINT_ATOP),
72     PACK (DISJOINT_ATOP_REVERSE, DISJOINT_ATOP_REVERSE, DISJOINT_ATOP_REVERSE, DISJOINT_ATOP_REVERSE),
73     PACK (DISJOINT_XOR,          DISJOINT_XOR,          DISJOINT_XOR,          DISJOINT_XOR),
74
75     0 /* 0x1c */,
76     0 /* 0x1d */,
77     0 /* 0x1e */,
78     0 /* 0x1f */,
79
80     PACK (CLEAR,                 CLEAR,                 CLEAR,                 CLEAR),
81     PACK (SRC,                   SRC,                   SRC,                   SRC),
82     PACK (DST,                   DST,                   DST,                   DST),
83     PACK (CONJOINT_OVER,         CONJOINT_OVER,         CONJOINT_OVER,         CONJOINT_OVER),
84     PACK (CONJOINT_OVER_REVERSE, CONJOINT_OVER_REVERSE, CONJOINT_OVER_REVERSE, CONJOINT_OVER_REVERSE),
85     PACK (CONJOINT_IN,           CONJOINT_IN,           CONJOINT_IN,           CONJOINT_IN),
86     PACK (CONJOINT_IN_REVERSE,   CONJOINT_IN_REVERSE,   CONJOINT_IN_REVERSE,   CONJOINT_IN_REVERSE),
87     PACK (CONJOINT_OUT,          CONJOINT_OUT,          CONJOINT_OUT,          CONJOINT_OUT),
88     PACK (CONJOINT_OUT_REVERSE,  CONJOINT_OUT_REVERSE,  CONJOINT_OUT_REVERSE,  CONJOINT_OUT_REVERSE),
89     PACK (CONJOINT_ATOP,         CONJOINT_ATOP,         CONJOINT_ATOP,         CONJOINT_ATOP),
90     PACK (CONJOINT_ATOP_REVERSE, CONJOINT_ATOP_REVERSE, CONJOINT_ATOP_REVERSE, CONJOINT_ATOP_REVERSE),
91     PACK (CONJOINT_XOR,          CONJOINT_XOR,          CONJOINT_XOR,          CONJOINT_XOR),
92
93     0 /* 0x2c */,
94     0 /* 0x2d */,
95     0 /* 0x2e */,
96     0 /* 0x2f */,
97
98     PACK (MULTIPLY,              MULTIPLY,              MULTIPLY,              MULTIPLY),
99     PACK (SCREEN,                SCREEN,                SCREEN,                SCREEN),
100     PACK (OVERLAY,               OVERLAY,               OVERLAY,               OVERLAY),
101     PACK (DARKEN,                DARKEN,                DARKEN,                DARKEN),
102     PACK (LIGHTEN,               LIGHTEN,               LIGHTEN,               LIGHTEN),
103     PACK (COLOR_DODGE,           COLOR_DODGE,           COLOR_DODGE,           COLOR_DODGE),
104     PACK (COLOR_BURN,            COLOR_BURN,            COLOR_BURN,            COLOR_BURN),
105     PACK (HARD_LIGHT,            HARD_LIGHT,            HARD_LIGHT,            HARD_LIGHT),
106     PACK (SOFT_LIGHT,            SOFT_LIGHT,            SOFT_LIGHT,            SOFT_LIGHT),
107     PACK (DIFFERENCE,            DIFFERENCE,            DIFFERENCE,            DIFFERENCE),
108     PACK (EXCLUSION,             EXCLUSION,             EXCLUSION,             EXCLUSION),
109     PACK (HSL_HUE,               HSL_HUE,               HSL_HUE,               HSL_HUE),
110     PACK (HSL_SATURATION,        HSL_SATURATION,        HSL_SATURATION,        HSL_SATURATION),
111     PACK (HSL_COLOR,             HSL_COLOR,             HSL_COLOR,             HSL_COLOR),
112     PACK (HSL_LUMINOSITY,        HSL_LUMINOSITY,        HSL_LUMINOSITY,        HSL_LUMINOSITY),
113
114     0
115 };
116
117 /*
118  * Optimize the current operator based on opacity of source or destination
119  * The output operator should be mathematically equivalent to the source.
120  */
121 static pixman_op_t
122 optimize_operator (pixman_op_t     op,
123                    uint32_t        src_flags,
124                    uint32_t        mask_flags,
125                    uint32_t        dst_flags)
126 {
127     pixman_bool_t is_source_opaque, is_dest_opaque;
128     int shift;
129
130     is_source_opaque = ((src_flags & mask_flags) & FAST_PATH_IS_OPAQUE) != 0;
131     is_dest_opaque = (dst_flags & FAST_PATH_IS_OPAQUE) != 0;
132
133     shift = 8 * ((is_dest_opaque << 1) | is_source_opaque);
134
135     return (operator_table[op] >> shift) & 0xff;
136 }
137
138 static void
139 apply_workaround (pixman_image_t *image,
140                   int32_t *       x,
141                   int32_t *       y,
142                   uint32_t **     save_bits,
143                   int *           save_dx,
144                   int *           save_dy)
145 {
146     if (image && (image->common.flags & FAST_PATH_NEEDS_WORKAROUND))
147     {
148         /* Some X servers generate images that point to the
149          * wrong place in memory, but then set the clip region
150          * to point to the right place. Because of an old bug
151          * in pixman, this would actually work.
152          *
153          * Here we try and undo the damage
154          */
155         int bpp = PIXMAN_FORMAT_BPP (image->bits.format) / 8;
156         pixman_box32_t *extents;
157         uint8_t *t;
158         int dx, dy;
159         
160         extents = pixman_region32_extents (&(image->common.clip_region));
161         dx = extents->x1;
162         dy = extents->y1;
163         
164         *save_bits = image->bits.bits;
165         
166         *x -= dx;
167         *y -= dy;
168         pixman_region32_translate (&(image->common.clip_region), -dx, -dy);
169         
170         t = (uint8_t *)image->bits.bits;
171         t += dy * image->bits.rowstride * 4 + dx * bpp;
172         image->bits.bits = (uint32_t *)t;
173         
174         *save_dx = dx;
175         *save_dy = dy;
176     }
177 }
178
179 static void
180 unapply_workaround (pixman_image_t *image, uint32_t *bits, int dx, int dy)
181 {
182     if (image && (image->common.flags & FAST_PATH_NEEDS_WORKAROUND))
183     {
184         image->bits.bits = bits;
185         pixman_region32_translate (&image->common.clip_region, dx, dy);
186     }
187 }
188
189 /*
190  * Computing composite region
191  */
192 static inline pixman_bool_t
193 clip_general_image (pixman_region32_t * region,
194                     pixman_region32_t * clip,
195                     int                 dx,
196                     int                 dy)
197 {
198     if (pixman_region32_n_rects (region) == 1 &&
199         pixman_region32_n_rects (clip) == 1)
200     {
201         pixman_box32_t *  rbox = pixman_region32_rectangles (region, NULL);
202         pixman_box32_t *  cbox = pixman_region32_rectangles (clip, NULL);
203         int v;
204
205         if (rbox->x1 < (v = cbox->x1 + dx))
206             rbox->x1 = v;
207         if (rbox->x2 > (v = cbox->x2 + dx))
208             rbox->x2 = v;
209         if (rbox->y1 < (v = cbox->y1 + dy))
210             rbox->y1 = v;
211         if (rbox->y2 > (v = cbox->y2 + dy))
212             rbox->y2 = v;
213         if (rbox->x1 >= rbox->x2 || rbox->y1 >= rbox->y2)
214         {
215             pixman_region32_init (region);
216             return FALSE;
217         }
218     }
219     else if (!pixman_region32_not_empty (clip))
220     {
221         return FALSE;
222     }
223     else
224     {
225         if (dx || dy)
226             pixman_region32_translate (region, -dx, -dy);
227
228         if (!pixman_region32_intersect (region, region, clip))
229             return FALSE;
230
231         if (dx || dy)
232             pixman_region32_translate (region, dx, dy);
233     }
234
235     return pixman_region32_not_empty (region);
236 }
237
238 static inline pixman_bool_t
239 clip_source_image (pixman_region32_t * region,
240                    pixman_image_t *    image,
241                    int                 dx,
242                    int                 dy)
243 {
244     /* Source clips are ignored, unless they are explicitly turned on
245      * and the clip in question was set by an X client. (Because if
246      * the clip was not set by a client, then it is a hierarchy
247      * clip and those should always be ignored for sources).
248      */
249     if (!image->common.clip_sources || !image->common.client_clip)
250         return TRUE;
251
252     return clip_general_image (region,
253                                &image->common.clip_region,
254                                dx, dy);
255 }
256
257 /*
258  * returns FALSE if the final region is empty.  Indistinguishable from
259  * an allocation failure, but rendering ignores those anyways.
260  */
261 static pixman_bool_t
262 pixman_compute_composite_region32 (pixman_region32_t * region,
263                                    pixman_image_t *    src_image,
264                                    pixman_image_t *    mask_image,
265                                    pixman_image_t *    dst_image,
266                                    int32_t             src_x,
267                                    int32_t             src_y,
268                                    int32_t             mask_x,
269                                    int32_t             mask_y,
270                                    int32_t             dest_x,
271                                    int32_t             dest_y,
272                                    int32_t             width,
273                                    int32_t             height)
274 {
275     region->extents.x1 = dest_x;
276     region->extents.x2 = dest_x + width;
277     region->extents.y1 = dest_y;
278     region->extents.y2 = dest_y + height;
279
280     region->extents.x1 = MAX (region->extents.x1, 0);
281     region->extents.y1 = MAX (region->extents.y1, 0);
282     region->extents.x2 = MIN (region->extents.x2, dst_image->bits.width);
283     region->extents.y2 = MIN (region->extents.y2, dst_image->bits.height);
284
285     region->data = 0;
286
287     /* Check for empty operation */
288     if (region->extents.x1 >= region->extents.x2 ||
289         region->extents.y1 >= region->extents.y2)
290     {
291         pixman_region32_init (region);
292         return FALSE;
293     }
294
295     if (dst_image->common.have_clip_region)
296     {
297         if (!clip_general_image (region, &dst_image->common.clip_region, 0, 0))
298         {
299             pixman_region32_fini (region);
300             return FALSE;
301         }
302     }
303
304     if (dst_image->common.alpha_map && dst_image->common.alpha_map->common.have_clip_region)
305     {
306         if (!clip_general_image (region, &dst_image->common.alpha_map->common.clip_region,
307                                  -dst_image->common.alpha_origin_x,
308                                  -dst_image->common.alpha_origin_y))
309         {
310             pixman_region32_fini (region);
311             return FALSE;
312         }
313     }
314
315     /* clip against src */
316     if (src_image->common.have_clip_region)
317     {
318         if (!clip_source_image (region, src_image, dest_x - src_x, dest_y - src_y))
319         {
320             pixman_region32_fini (region);
321             return FALSE;
322         }
323     }
324     if (src_image->common.alpha_map && src_image->common.alpha_map->common.have_clip_region)
325     {
326         if (!clip_source_image (region, (pixman_image_t *)src_image->common.alpha_map,
327                                 dest_x - (src_x - src_image->common.alpha_origin_x),
328                                 dest_y - (src_y - src_image->common.alpha_origin_y)))
329         {
330             pixman_region32_fini (region);
331             return FALSE;
332         }
333     }
334     /* clip against mask */
335     if (mask_image && mask_image->common.have_clip_region)
336     {
337         if (!clip_source_image (region, mask_image, dest_x - mask_x, dest_y - mask_y))
338         {
339             pixman_region32_fini (region);
340             return FALSE;
341         }
342         if (mask_image->common.alpha_map && mask_image->common.alpha_map->common.have_clip_region)
343         {
344             if (!clip_source_image (region, (pixman_image_t *)mask_image->common.alpha_map,
345                                     dest_x - (mask_x - mask_image->common.alpha_origin_x),
346                                     dest_y - (mask_y - mask_image->common.alpha_origin_y)))
347             {
348                 pixman_region32_fini (region);
349                 return FALSE;
350             }
351         }
352     }
353
354     return TRUE;
355 }
356
357 static void
358 walk_region_internal (pixman_implementation_t *imp,
359                       pixman_op_t              op,
360                       pixman_image_t *         src_image,
361                       pixman_image_t *         mask_image,
362                       pixman_image_t *         dst_image,
363                       int32_t                  src_x,
364                       int32_t                  src_y,
365                       int32_t                  mask_x,
366                       int32_t                  mask_y,
367                       int32_t                  dest_x,
368                       int32_t                  dest_y,
369                       int32_t                  width,
370                       int32_t                  height,
371                       pixman_bool_t            src_repeat,
372                       pixman_bool_t            mask_repeat,
373                       pixman_region32_t *      region,
374                       pixman_composite_func_t  composite_rect)
375 {
376     int w, h, w_this, h_this;
377     int x_msk, y_msk, x_src, y_src, x_dst, y_dst;
378     int src_dy = src_y - dest_y;
379     int src_dx = src_x - dest_x;
380     int mask_dy = mask_y - dest_y;
381     int mask_dx = mask_x - dest_x;
382     const pixman_box32_t *pbox;
383     int n;
384
385     pbox = pixman_region32_rectangles (region, &n);
386
387     /* Fast path for non-repeating sources */
388     if (!src_repeat && !mask_repeat)
389     {
390        while (n--)
391        {
392            (*composite_rect) (imp, op,
393                               src_image, mask_image, dst_image,
394                               pbox->x1 + src_dx,
395                               pbox->y1 + src_dy,
396                               pbox->x1 + mask_dx,
397                               pbox->y1 + mask_dy,
398                               pbox->x1,
399                               pbox->y1,
400                               pbox->x2 - pbox->x1,
401                               pbox->y2 - pbox->y1);
402            
403            pbox++;
404        }
405
406        return;
407     }
408     
409     while (n--)
410     {
411         h = pbox->y2 - pbox->y1;
412         y_src = pbox->y1 + src_dy;
413         y_msk = pbox->y1 + mask_dy;
414         y_dst = pbox->y1;
415
416         while (h)
417         {
418             h_this = h;
419             w = pbox->x2 - pbox->x1;
420             x_src = pbox->x1 + src_dx;
421             x_msk = pbox->x1 + mask_dx;
422             x_dst = pbox->x1;
423
424             if (mask_repeat)
425             {
426                 y_msk = MOD (y_msk, mask_image->bits.height);
427                 if (h_this > mask_image->bits.height - y_msk)
428                     h_this = mask_image->bits.height - y_msk;
429             }
430
431             if (src_repeat)
432             {
433                 y_src = MOD (y_src, src_image->bits.height);
434                 if (h_this > src_image->bits.height - y_src)
435                     h_this = src_image->bits.height - y_src;
436             }
437
438             while (w)
439             {
440                 w_this = w;
441
442                 if (mask_repeat)
443                 {
444                     x_msk = MOD (x_msk, mask_image->bits.width);
445                     if (w_this > mask_image->bits.width - x_msk)
446                         w_this = mask_image->bits.width - x_msk;
447                 }
448
449                 if (src_repeat)
450                 {
451                     x_src = MOD (x_src, src_image->bits.width);
452                     if (w_this > src_image->bits.width - x_src)
453                         w_this = src_image->bits.width - x_src;
454                 }
455
456                 (*composite_rect) (imp, op,
457                                    src_image, mask_image, dst_image,
458                                    x_src, y_src, x_msk, y_msk, x_dst, y_dst,
459                                    w_this, h_this);
460                 w -= w_this;
461
462                 x_src += w_this;
463                 x_msk += w_this;
464                 x_dst += w_this;
465             }
466
467             h -= h_this;
468             y_src += h_this;
469             y_msk += h_this;
470             y_dst += h_this;
471         }
472
473         pbox++;
474     }
475 }
476
477 static force_inline pixman_bool_t
478 image_covers (pixman_image_t *image,
479               pixman_box32_t *extents,
480               int             x,
481               int             y)
482 {
483     if (image->common.type == BITS &&
484         image->common.repeat == PIXMAN_REPEAT_NONE)
485     {
486         if (x > extents->x1 || y > extents->y1 ||
487             x + image->bits.width < extents->x2 ||
488             y + image->bits.height < extents->y2)
489         {
490             return FALSE;
491         }
492     }
493
494     return TRUE;
495 }
496
497 static void
498 do_composite (pixman_implementation_t *imp,
499               pixman_op_t              op,
500               pixman_image_t          *src,
501               pixman_image_t          *mask,
502               pixman_image_t          *dest,
503               int                      src_x,
504               int                      src_y,
505               int                      mask_x,
506               int                      mask_y,
507               int                      dest_x,
508               int                      dest_y,
509               int                      width,
510               int                      height)
511 {
512 #define N_CACHED_FAST_PATHS 8
513     static THREAD_LOCAL pixman_fast_path_t tls_cache[N_CACHED_FAST_PATHS];
514     pixman_format_code_t src_format, mask_format, dest_format;
515     uint32_t src_flags, mask_flags, dest_flags;
516     pixman_region32_t region;
517     pixman_box32_t *extents;
518     uint32_t *src_bits;
519     int src_dx, src_dy;
520     uint32_t *mask_bits;
521     int mask_dx, mask_dy;
522     uint32_t *dest_bits;
523     int dest_dx, dest_dy;
524     pixman_bool_t need_workaround;
525     pixman_fast_path_t *cache;
526     const pixman_fast_path_t *info;
527     int i;
528
529     src_format = src->common.extended_format_code;
530     src_flags = src->common.flags;
531
532     if (mask)
533     {
534         mask_format = mask->common.extended_format_code;
535         mask_flags = mask->common.flags;
536     }
537     else
538     {
539         mask_format = PIXMAN_null;
540         mask_flags = FAST_PATH_IS_OPAQUE;
541     }
542
543     dest_format = dest->common.extended_format_code;
544     dest_flags = dest->common.flags;
545
546     /* Check for pixbufs */
547     if ((mask_format == PIXMAN_a8r8g8b8 || mask_format == PIXMAN_a8b8g8r8) &&
548         (src->type == BITS && src->bits.bits == mask->bits.bits)           &&
549         (src->common.repeat == mask->common.repeat)                        &&
550         (src_x == mask_x && src_y == mask_y))
551     {
552         if (src_format == PIXMAN_x8b8g8r8)
553             src_format = mask_format = PIXMAN_pixbuf;
554         else if (src_format == PIXMAN_x8r8g8b8)
555             src_format = mask_format = PIXMAN_rpixbuf;
556     }
557
558     /* Check for workaround */
559     need_workaround = (src_flags | mask_flags | dest_flags) & FAST_PATH_NEEDS_WORKAROUND;
560
561     if (need_workaround)
562     {
563         apply_workaround (src, &src_x, &src_y, &src_bits, &src_dx, &src_dy);
564         apply_workaround (mask, &mask_x, &mask_y, &mask_bits, &mask_dx, &mask_dy);
565         apply_workaround (dest, &dest_x, &dest_y, &dest_bits, &dest_dx, &dest_dy);
566     }
567
568     pixman_region32_init (&region);
569     
570     if (!pixman_compute_composite_region32 (
571             &region, src, mask, dest,
572             src_x, src_y, mask_x, mask_y, dest_x, dest_y, width, height))
573     {
574         return;
575     }
576     
577     extents = pixman_region32_extents (&region);
578     
579     if (image_covers (src, extents, dest_x - src_x, dest_y - src_y))
580         src_flags |= FAST_PATH_COVERS_CLIP;
581     
582     if (mask && image_covers (mask, extents, dest_x - mask_x, dest_y - mask_y))
583         mask_flags |= FAST_PATH_COVERS_CLIP;
584
585     /*
586      * Check if we can replace our operator by a simpler one
587      * if the src or dest are opaque. The output operator should be
588      * mathematically equivalent to the source.
589      */
590     op = optimize_operator (op, src_flags, mask_flags, dest_flags);
591     if (op == PIXMAN_OP_DST)
592         return;
593
594     /* Check cache for fast paths */
595     cache = tls_cache;
596
597     for (i = 0; i < N_CACHED_FAST_PATHS; ++i)
598     {
599         info = &(cache[i]);
600
601         /* Note that we check for equality here, not whether
602          * the cached fast path matches. This is to prevent
603          * us from selecting an overly general fast path
604          * when a more specific one would work.
605          */
606         if (info->op == op                      &&
607             info->src_format == src_format      &&
608             info->mask_format == mask_format    &&
609             info->dest_format == dest_format    &&
610             info->src_flags == src_flags        &&
611             info->mask_flags == mask_flags      &&
612             info->dest_flags == dest_flags      &&
613             info->func)
614         {
615             goto found;
616         }
617     }
618
619     while (imp)
620     {
621         info = imp->fast_paths;
622
623         while (info->op != PIXMAN_OP_NONE)
624         {
625             if ((info->op == op || info->op == PIXMAN_OP_any)           &&
626                 /* Formats */
627                 ((info->src_format == src_format) ||
628                  (info->src_format == PIXMAN_any))                      &&
629                 ((info->mask_format == mask_format) ||
630                  (info->mask_format == PIXMAN_any))                     &&
631                 ((info->dest_format == dest_format) ||
632                  (info->dest_format == PIXMAN_any))                     &&
633                 /* Flags */
634                 (info->src_flags & src_flags) == info->src_flags        &&
635                 (info->mask_flags & mask_flags) == info->mask_flags     &&
636                 (info->dest_flags & dest_flags) == info->dest_flags)
637             {
638                 /* Set i to the last spot in the cache so that the
639                  * move-to-front code below will work
640                  */
641                 i = N_CACHED_FAST_PATHS - 1;
642
643                 goto found;
644             }
645
646             ++info;
647         }
648
649         imp = imp->delegate;
650     }
651
652     /* We didn't find a compositing routine. This should not happen, but if
653      * it somehow does, just exit rather than crash.
654      */
655     goto out;
656
657 found:
658     walk_region_internal (imp, op,
659                           src, mask, dest,
660                           src_x, src_y, mask_x, mask_y,
661                           dest_x, dest_y,
662                           width, height,
663                           (src_flags & FAST_PATH_SIMPLE_REPEAT),
664                           (mask_flags & FAST_PATH_SIMPLE_REPEAT),
665                           &region, info->func);
666
667     if (i)
668     {
669         /* Make a copy of info->func, because info->func may change when
670          * we update the cache.
671          */
672         pixman_composite_func_t func = info->func;
673         
674         while (i--)
675             cache[i + 1] = cache[i];
676
677         cache[0].op = op;
678         cache[0].src_format = src_format;
679         cache[0].src_flags = src_flags;
680         cache[0].mask_format = mask_format;
681         cache[0].mask_flags = mask_flags;
682         cache[0].dest_format = dest_format;
683         cache[0].dest_flags = dest_flags;
684         cache[0].func = func;
685     }
686
687 out:
688     if (need_workaround)
689     {
690         unapply_workaround (src, src_bits, src_dx, src_dy);
691         unapply_workaround (mask, mask_bits, mask_dx, mask_dy);
692         unapply_workaround (dest, dest_bits, dest_dx, dest_dy);
693     }
694
695     pixman_region32_fini (&region);
696 }
697
698 PIXMAN_EXPORT void
699 pixman_image_composite (pixman_op_t      op,
700                         pixman_image_t * src,
701                         pixman_image_t * mask,
702                         pixman_image_t * dest,
703                         int16_t          src_x,
704                         int16_t          src_y,
705                         int16_t          mask_x,
706                         int16_t          mask_y,
707                         int16_t          dest_x,
708                         int16_t          dest_y,
709                         uint16_t         width,
710                         uint16_t         height)
711 {
712     pixman_image_composite32 (op, src, mask, dest, src_x, src_y, 
713                               mask_x, mask_y, dest_x, dest_y, width, height);
714 }
715
716 /*
717  * Work around GCC bug causing crashes in Mozilla with SSE2
718  *
719  * When using -msse, gcc generates movdqa instructions assuming that
720  * the stack is 16 byte aligned. Unfortunately some applications, such
721  * as Mozilla and Mono, end up aligning the stack to 4 bytes, which
722  * causes the movdqa instructions to fail.
723  *
724  * The __force_align_arg_pointer__ makes gcc generate a prologue that
725  * realigns the stack pointer to 16 bytes.
726  *
727  * On x86-64 this is not necessary because the standard ABI already
728  * calls for a 16 byte aligned stack.
729  *
730  * See https://bugs.freedesktop.org/show_bug.cgi?id=15693
731  */
732 #if defined (USE_SSE2) && defined(__GNUC__) && !defined(__x86_64__) && !defined(__amd64__)
733 __attribute__((__force_align_arg_pointer__))
734 #endif
735 PIXMAN_EXPORT void
736 pixman_image_composite32 (pixman_op_t      op,
737                           pixman_image_t * src,
738                           pixman_image_t * mask,
739                           pixman_image_t * dest,
740                           int32_t          src_x,
741                           int32_t          src_y,
742                           int32_t          mask_x,
743                           int32_t          mask_y,
744                           int32_t          dest_x,
745                           int32_t          dest_y,
746                           int32_t          width,
747                           int32_t          height)
748 {
749     _pixman_image_validate (src);
750     if (mask)
751         _pixman_image_validate (mask);
752     _pixman_image_validate (dest);
753
754     if (!imp)
755         imp = _pixman_choose_implementation ();
756
757     do_composite (imp, op,
758                   src, mask, dest,
759                   src_x, src_y,
760                   mask_x, mask_y,
761                   dest_x, dest_y,
762                   width, height);
763 }
764
765 PIXMAN_EXPORT pixman_bool_t
766 pixman_blt (uint32_t *src_bits,
767             uint32_t *dst_bits,
768             int       src_stride,
769             int       dst_stride,
770             int       src_bpp,
771             int       dst_bpp,
772             int       src_x,
773             int       src_y,
774             int       dst_x,
775             int       dst_y,
776             int       width,
777             int       height)
778 {
779     if (!imp)
780         imp = _pixman_choose_implementation ();
781
782     return _pixman_implementation_blt (imp, src_bits, dst_bits, src_stride, dst_stride,
783                                        src_bpp, dst_bpp,
784                                        src_x, src_y,
785                                        dst_x, dst_y,
786                                        width, height);
787 }
788
789 PIXMAN_EXPORT pixman_bool_t
790 pixman_fill (uint32_t *bits,
791              int       stride,
792              int       bpp,
793              int       x,
794              int       y,
795              int       width,
796              int       height,
797              uint32_t xor)
798 {
799     if (!imp)
800         imp = _pixman_choose_implementation ();
801
802     return _pixman_implementation_fill (imp, bits, stride, bpp, x, y, width, height, xor);
803 }
804
805 static uint32_t
806 color_to_uint32 (const pixman_color_t *color)
807 {
808     return
809         (color->alpha >> 8 << 24) |
810         (color->red >> 8 << 16) |
811         (color->green & 0xff00) |
812         (color->blue >> 8);
813 }
814
815 static pixman_bool_t
816 color_to_pixel (pixman_color_t *     color,
817                 uint32_t *           pixel,
818                 pixman_format_code_t format)
819 {
820     uint32_t c = color_to_uint32 (color);
821
822     if (!(format == PIXMAN_a8r8g8b8     ||
823           format == PIXMAN_x8r8g8b8     ||
824           format == PIXMAN_a8b8g8r8     ||
825           format == PIXMAN_x8b8g8r8     ||
826           format == PIXMAN_b8g8r8a8     ||
827           format == PIXMAN_b8g8r8x8     ||
828           format == PIXMAN_r5g6b5       ||
829           format == PIXMAN_b5g6r5       ||
830           format == PIXMAN_a8))
831     {
832         return FALSE;
833     }
834
835     if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_ABGR)
836     {
837         c = ((c & 0xff000000) >>  0) |
838             ((c & 0x00ff0000) >> 16) |
839             ((c & 0x0000ff00) >>  0) |
840             ((c & 0x000000ff) << 16);
841     }
842     if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_BGRA)
843     {
844         c = ((c & 0xff000000) >> 24) |
845             ((c & 0x00ff0000) >>  8) |
846             ((c & 0x0000ff00) <<  8) |
847             ((c & 0x000000ff) << 24);
848     }
849
850     if (format == PIXMAN_a8)
851         c = c >> 24;
852     else if (format == PIXMAN_r5g6b5 ||
853              format == PIXMAN_b5g6r5)
854         c = CONVERT_8888_TO_0565 (c);
855
856 #if 0
857     printf ("color: %x %x %x %x\n", color->alpha, color->red, color->green, color->blue);
858     printf ("pixel: %x\n", c);
859 #endif
860
861     *pixel = c;
862     return TRUE;
863 }
864
865 PIXMAN_EXPORT pixman_bool_t
866 pixman_image_fill_rectangles (pixman_op_t                 op,
867                               pixman_image_t *            dest,
868                               pixman_color_t *            color,
869                               int                         n_rects,
870                               const pixman_rectangle16_t *rects)
871 {
872     pixman_box32_t stack_boxes[6];
873     pixman_box32_t *boxes;
874     pixman_bool_t result;
875     int i;
876
877     if (n_rects > 6)
878     {
879         boxes = pixman_malloc_ab (sizeof (pixman_box32_t), n_rects);
880         if (boxes == NULL)
881             return FALSE;
882     }
883     else
884     {
885         boxes = stack_boxes;
886     }
887
888     for (i = 0; i < n_rects; ++i)
889     {
890         boxes[i].x1 = rects[i].x;
891         boxes[i].y1 = rects[i].y;
892         boxes[i].x2 = boxes[i].x1 + rects[i].width;
893         boxes[i].y2 = boxes[i].y1 + rects[i].height;
894     }
895
896     result = pixman_image_fill_boxes (op, dest, color, n_rects, boxes);
897
898     if (boxes != stack_boxes)
899         free (boxes);
900     
901     return result;
902 }
903
904 PIXMAN_EXPORT pixman_bool_t
905 pixman_image_fill_boxes (pixman_op_t           op,
906                          pixman_image_t *      dest,
907                          pixman_color_t *      color,
908                          int                   n_boxes,
909                          const pixman_box32_t *boxes)
910 {
911     pixman_image_t *solid;
912     pixman_color_t c;
913     int i;
914
915     _pixman_image_validate (dest);
916     
917     if (color->alpha == 0xffff)
918     {
919         if (op == PIXMAN_OP_OVER)
920             op = PIXMAN_OP_SRC;
921     }
922
923     if (op == PIXMAN_OP_CLEAR)
924     {
925         c.red = 0;
926         c.green = 0;
927         c.blue = 0;
928         c.alpha = 0;
929
930         color = &c;
931
932         op = PIXMAN_OP_SRC;
933     }
934
935     if (op == PIXMAN_OP_SRC)
936     {
937         uint32_t pixel;
938
939         if (color_to_pixel (color, &pixel, dest->bits.format))
940         {
941             pixman_region32_t fill_region;
942             int n_rects, j;
943             pixman_box32_t *rects;
944
945             if (!pixman_region32_init_rects (&fill_region, boxes, n_boxes))
946                 return FALSE;
947
948             if (dest->common.have_clip_region)
949             {
950                 if (!pixman_region32_intersect (&fill_region,
951                                                 &fill_region,
952                                                 &dest->common.clip_region))
953                     return FALSE;
954             }
955
956             rects = pixman_region32_rectangles (&fill_region, &n_rects);
957             for (j = 0; j < n_rects; ++j)
958             {
959                 const pixman_box32_t *rect = &(rects[j]);
960                 pixman_fill (dest->bits.bits, dest->bits.rowstride, PIXMAN_FORMAT_BPP (dest->bits.format),
961                              rect->x1, rect->y1, rect->x2 - rect->x1, rect->y2 - rect->y1,
962                              pixel);
963             }
964
965             pixman_region32_fini (&fill_region);
966             return TRUE;
967         }
968     }
969
970     solid = pixman_image_create_solid_fill (color);
971     if (!solid)
972         return FALSE;
973
974     for (i = 0; i < n_boxes; ++i)
975     {
976         const pixman_box32_t *box = &(boxes[i]);
977
978         pixman_image_composite32 (op, solid, NULL, dest,
979                                   0, 0, 0, 0,
980                                   box->x1, box->y1,
981                                   box->x2 - box->x1, box->y2 - box->y1);
982     }
983
984     pixman_image_unref (solid);
985
986     return TRUE;
987 }
988
989 /**
990  * pixman_version:
991  *
992  * Returns the version of the pixman library encoded in a single
993  * integer as per %PIXMAN_VERSION_ENCODE. The encoding ensures that
994  * later versions compare greater than earlier versions.
995  *
996  * A run-time comparison to check that pixman's version is greater than
997  * or equal to version X.Y.Z could be performed as follows:
998  *
999  * <informalexample><programlisting>
1000  * if (pixman_version() >= PIXMAN_VERSION_ENCODE(X,Y,Z)) {...}
1001  * </programlisting></informalexample>
1002  *
1003  * See also pixman_version_string() as well as the compile-time
1004  * equivalents %PIXMAN_VERSION and %PIXMAN_VERSION_STRING.
1005  *
1006  * Return value: the encoded version.
1007  **/
1008 PIXMAN_EXPORT int
1009 pixman_version (void)
1010 {
1011     return PIXMAN_VERSION;
1012 }
1013
1014 /**
1015  * pixman_version_string:
1016  *
1017  * Returns the version of the pixman library as a human-readable string
1018  * of the form "X.Y.Z".
1019  *
1020  * See also pixman_version() as well as the compile-time equivalents
1021  * %PIXMAN_VERSION_STRING and %PIXMAN_VERSION.
1022  *
1023  * Return value: a string containing the version.
1024  **/
1025 PIXMAN_EXPORT const char*
1026 pixman_version_string (void)
1027 {
1028     return PIXMAN_VERSION_STRING;
1029 }
1030
1031 /**
1032  * pixman_format_supported_source:
1033  * @format: A pixman_format_code_t format
1034  *
1035  * Return value: whether the provided format code is a supported
1036  * format for a pixman surface used as a source in
1037  * rendering.
1038  *
1039  * Currently, all pixman_format_code_t values are supported.
1040  **/
1041 PIXMAN_EXPORT pixman_bool_t
1042 pixman_format_supported_source (pixman_format_code_t format)
1043 {
1044     switch (format)
1045     {
1046     /* 32 bpp formats */
1047     case PIXMAN_a2b10g10r10:
1048     case PIXMAN_x2b10g10r10:
1049     case PIXMAN_a2r10g10b10:
1050     case PIXMAN_x2r10g10b10:
1051     case PIXMAN_a8r8g8b8:
1052     case PIXMAN_x8r8g8b8:
1053     case PIXMAN_a8b8g8r8:
1054     case PIXMAN_x8b8g8r8:
1055     case PIXMAN_b8g8r8a8:
1056     case PIXMAN_b8g8r8x8:
1057     case PIXMAN_r8g8b8:
1058     case PIXMAN_b8g8r8:
1059     case PIXMAN_r5g6b5:
1060     case PIXMAN_b5g6r5:
1061     /* 16 bpp formats */
1062     case PIXMAN_a1r5g5b5:
1063     case PIXMAN_x1r5g5b5:
1064     case PIXMAN_a1b5g5r5:
1065     case PIXMAN_x1b5g5r5:
1066     case PIXMAN_a4r4g4b4:
1067     case PIXMAN_x4r4g4b4:
1068     case PIXMAN_a4b4g4r4:
1069     case PIXMAN_x4b4g4r4:
1070     /* 8bpp formats */
1071     case PIXMAN_a8:
1072     case PIXMAN_r3g3b2:
1073     case PIXMAN_b2g3r3:
1074     case PIXMAN_a2r2g2b2:
1075     case PIXMAN_a2b2g2r2:
1076     case PIXMAN_c8:
1077     case PIXMAN_g8:
1078     case PIXMAN_x4a4:
1079     /* Collides with PIXMAN_c8
1080        case PIXMAN_x4c4:
1081      */
1082     /* Collides with PIXMAN_g8
1083        case PIXMAN_x4g4:
1084      */
1085     /* 4bpp formats */
1086     case PIXMAN_a4:
1087     case PIXMAN_r1g2b1:
1088     case PIXMAN_b1g2r1:
1089     case PIXMAN_a1r1g1b1:
1090     case PIXMAN_a1b1g1r1:
1091     case PIXMAN_c4:
1092     case PIXMAN_g4:
1093     /* 1bpp formats */
1094     case PIXMAN_a1:
1095     case PIXMAN_g1:
1096     /* YUV formats */
1097     case PIXMAN_yuy2:
1098     case PIXMAN_yv12:
1099         return TRUE;
1100
1101     default:
1102         return FALSE;
1103     }
1104 }
1105
1106 /**
1107  * pixman_format_supported_destination:
1108  * @format: A pixman_format_code_t format
1109  *
1110  * Return value: whether the provided format code is a supported
1111  * format for a pixman surface used as a destination in
1112  * rendering.
1113  *
1114  * Currently, all pixman_format_code_t values are supported
1115  * except for the YUV formats.
1116  **/
1117 PIXMAN_EXPORT pixman_bool_t
1118 pixman_format_supported_destination (pixman_format_code_t format)
1119 {
1120     /* YUV formats cannot be written to at the moment */
1121     if (format == PIXMAN_yuy2 || format == PIXMAN_yv12)
1122         return FALSE;
1123
1124     return pixman_format_supported_source (format);
1125 }
1126
1127 PIXMAN_EXPORT pixman_bool_t
1128 pixman_compute_composite_region (pixman_region16_t * region,
1129                                  pixman_image_t *    src_image,
1130                                  pixman_image_t *    mask_image,
1131                                  pixman_image_t *    dst_image,
1132                                  int16_t             src_x,
1133                                  int16_t             src_y,
1134                                  int16_t             mask_x,
1135                                  int16_t             mask_y,
1136                                  int16_t             dest_x,
1137                                  int16_t             dest_y,
1138                                  uint16_t            width,
1139                                  uint16_t            height)
1140 {
1141     pixman_region32_t r32;
1142     pixman_bool_t retval;
1143
1144     pixman_region32_init (&r32);
1145
1146     retval = pixman_compute_composite_region32 (
1147         &r32, src_image, mask_image, dst_image,
1148         src_x, src_y, mask_x, mask_y, dest_x, dest_y,
1149         width, height);
1150
1151     if (retval)
1152     {
1153         if (!pixman_region16_copy_from_region32 (region, &r32))
1154             retval = FALSE;
1155     }
1156
1157     pixman_region32_fini (&r32);
1158     return retval;
1159 }