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