Hide the global implementation variable behind a force_inline function.
[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     pixman_fast_path_t cache [N_CACHED_FAST_PATHS];
567 } cache_t;
568
569 PIXMAN_DEFINE_THREAD_LOCAL (cache_t, fast_path_cache);
570
571 static void
572 do_composite (pixman_implementation_t *imp,
573               pixman_op_t              op,
574               pixman_image_t          *src,
575               pixman_image_t          *mask,
576               pixman_image_t          *dest,
577               int                      src_x,
578               int                      src_y,
579               int                      mask_x,
580               int                      mask_y,
581               int                      dest_x,
582               int                      dest_y,
583               int                      width,
584               int                      height)
585 {
586     pixman_format_code_t src_format, mask_format, dest_format;
587     uint32_t src_flags, mask_flags, dest_flags;
588     pixman_region32_t region;
589     pixman_box32_t *extents;
590     uint32_t *src_bits;
591     int src_dx, src_dy;
592     uint32_t *mask_bits;
593     int mask_dx, mask_dy;
594     uint32_t *dest_bits;
595     int dest_dx, dest_dy;
596     pixman_bool_t need_workaround;
597     const pixman_fast_path_t *info;
598     cache_t *cache;
599     int i;
600
601     src_format = src->common.extended_format_code;
602     src_flags = src->common.flags;
603
604     if (mask)
605     {
606         mask_format = mask->common.extended_format_code;
607         mask_flags = mask->common.flags;
608     }
609     else
610     {
611         mask_format = PIXMAN_null;
612         mask_flags = FAST_PATH_IS_OPAQUE;
613     }
614
615     dest_format = dest->common.extended_format_code;
616     dest_flags = dest->common.flags;
617
618     /* Check for pixbufs */
619     if ((mask_format == PIXMAN_a8r8g8b8 || mask_format == PIXMAN_a8b8g8r8) &&
620         (src->type == BITS && src->bits.bits == mask->bits.bits)           &&
621         (src->common.repeat == mask->common.repeat)                        &&
622         (src_x == mask_x && src_y == mask_y))
623     {
624         if (src_format == PIXMAN_x8b8g8r8)
625             src_format = mask_format = PIXMAN_pixbuf;
626         else if (src_format == PIXMAN_x8r8g8b8)
627             src_format = mask_format = PIXMAN_rpixbuf;
628     }
629
630     /* Check for workaround */
631     need_workaround = (src_flags | mask_flags | dest_flags) & FAST_PATH_NEEDS_WORKAROUND;
632
633     if (need_workaround)
634     {
635         apply_workaround (src, &src_x, &src_y, &src_bits, &src_dx, &src_dy);
636         apply_workaround (mask, &mask_x, &mask_y, &mask_bits, &mask_dx, &mask_dy);
637         apply_workaround (dest, &dest_x, &dest_y, &dest_bits, &dest_dx, &dest_dy);
638     }
639
640     pixman_region32_init (&region);
641     
642     if (!pixman_compute_composite_region32 (
643             &region, src, mask, dest,
644             src_x, src_y, mask_x, mask_y, dest_x, dest_y, width, height))
645     {
646         return;
647     }
648     
649     extents = pixman_region32_extents (&region);
650     
651     src_flags |= compute_src_extents_flags (src, extents, dest_x - src_x, dest_y - src_y);
652
653     if (mask)
654         mask_flags |= compute_src_extents_flags (mask, extents, dest_x - mask_x, dest_y - mask_y);
655
656     /*
657      * Check if we can replace our operator by a simpler one
658      * if the src or dest are opaque. The output operator should be
659      * mathematically equivalent to the source.
660      */
661     op = optimize_operator (op, src_flags, mask_flags, dest_flags);
662     if (op == PIXMAN_OP_DST)
663         return;
664
665     /* Check cache for fast paths */
666     cache = PIXMAN_GET_THREAD_LOCAL (fast_path_cache);
667
668     for (i = 0; i < N_CACHED_FAST_PATHS; ++i)
669     {
670         info = &(cache->cache[i]);
671
672         /* Note that we check for equality here, not whether
673          * the cached fast path matches. This is to prevent
674          * us from selecting an overly general fast path
675          * when a more specific one would work.
676          */
677         if (info->op == op                      &&
678             info->src_format == src_format      &&
679             info->mask_format == mask_format    &&
680             info->dest_format == dest_format    &&
681             info->src_flags == src_flags        &&
682             info->mask_flags == mask_flags      &&
683             info->dest_flags == dest_flags      &&
684             info->func)
685         {
686             goto found;
687         }
688     }
689
690     while (imp)
691     {
692         info = imp->fast_paths;
693
694         while (info->op != PIXMAN_OP_NONE)
695         {
696             if ((info->op == op || info->op == PIXMAN_OP_any)           &&
697                 /* Formats */
698                 ((info->src_format == src_format) ||
699                  (info->src_format == PIXMAN_any))                      &&
700                 ((info->mask_format == mask_format) ||
701                  (info->mask_format == PIXMAN_any))                     &&
702                 ((info->dest_format == dest_format) ||
703                  (info->dest_format == PIXMAN_any))                     &&
704                 /* Flags */
705                 (info->src_flags & src_flags) == info->src_flags        &&
706                 (info->mask_flags & mask_flags) == info->mask_flags     &&
707                 (info->dest_flags & dest_flags) == info->dest_flags)
708             {
709                 /* Set i to the last spot in the cache so that the
710                  * move-to-front code below will work
711                  */
712                 i = N_CACHED_FAST_PATHS - 1;
713
714                 goto found;
715             }
716
717             ++info;
718         }
719
720         imp = imp->delegate;
721     }
722
723     /* We didn't find a compositing routine. This should not happen, but if
724      * it somehow does, just exit rather than crash.
725      */
726     goto out;
727
728 found:
729     walk_region_internal (imp, op,
730                           src, mask, dest,
731                           src_x, src_y, mask_x, mask_y,
732                           dest_x, dest_y,
733                           width, height,
734                           (src_flags & FAST_PATH_SIMPLE_REPEAT),
735                           (mask_flags & FAST_PATH_SIMPLE_REPEAT),
736                           &region, info->func);
737
738     if (i)
739     {
740         /* Make a copy of info->func, because info->func may change when
741          * we update the cache.
742          */
743         pixman_composite_func_t func = info->func;
744         
745         while (i--)
746             cache->cache[i + 1] = cache->cache[i];
747
748         cache->cache[0].op = op;
749         cache->cache[0].src_format = src_format;
750         cache->cache[0].src_flags = src_flags;
751         cache->cache[0].mask_format = mask_format;
752         cache->cache[0].mask_flags = mask_flags;
753         cache->cache[0].dest_format = dest_format;
754         cache->cache[0].dest_flags = dest_flags;
755         cache->cache[0].func = func;
756     }
757
758 out:
759     if (need_workaround)
760     {
761         unapply_workaround (src, src_bits, src_dx, src_dy);
762         unapply_workaround (mask, mask_bits, mask_dx, mask_dy);
763         unapply_workaround (dest, dest_bits, dest_dx, dest_dy);
764     }
765
766     pixman_region32_fini (&region);
767 }
768
769 PIXMAN_EXPORT void
770 pixman_image_composite (pixman_op_t      op,
771                         pixman_image_t * src,
772                         pixman_image_t * mask,
773                         pixman_image_t * dest,
774                         int16_t          src_x,
775                         int16_t          src_y,
776                         int16_t          mask_x,
777                         int16_t          mask_y,
778                         int16_t          dest_x,
779                         int16_t          dest_y,
780                         uint16_t         width,
781                         uint16_t         height)
782 {
783     pixman_image_composite32 (op, src, mask, dest, src_x, src_y, 
784                               mask_x, mask_y, dest_x, dest_y, width, height);
785 }
786
787 /*
788  * Work around GCC bug causing crashes in Mozilla with SSE2
789  *
790  * When using -msse, gcc generates movdqa instructions assuming that
791  * the stack is 16 byte aligned. Unfortunately some applications, such
792  * as Mozilla and Mono, end up aligning the stack to 4 bytes, which
793  * causes the movdqa instructions to fail.
794  *
795  * The __force_align_arg_pointer__ makes gcc generate a prologue that
796  * realigns the stack pointer to 16 bytes.
797  *
798  * On x86-64 this is not necessary because the standard ABI already
799  * calls for a 16 byte aligned stack.
800  *
801  * See https://bugs.freedesktop.org/show_bug.cgi?id=15693
802  */
803 #if defined (USE_SSE2) && defined(__GNUC__) && !defined(__x86_64__) && !defined(__amd64__)
804 __attribute__((__force_align_arg_pointer__))
805 #endif
806 PIXMAN_EXPORT void
807 pixman_image_composite32 (pixman_op_t      op,
808                           pixman_image_t * src,
809                           pixman_image_t * mask,
810                           pixman_image_t * dest,
811                           int32_t          src_x,
812                           int32_t          src_y,
813                           int32_t          mask_x,
814                           int32_t          mask_y,
815                           int32_t          dest_x,
816                           int32_t          dest_y,
817                           int32_t          width,
818                           int32_t          height)
819 {
820     _pixman_image_validate (src);
821     if (mask)
822         _pixman_image_validate (mask);
823     _pixman_image_validate (dest);
824
825     do_composite (get_implementation(), op,
826                   src, mask, dest,
827                   src_x, src_y,
828                   mask_x, mask_y,
829                   dest_x, dest_y,
830                   width, height);
831 }
832
833 PIXMAN_EXPORT pixman_bool_t
834 pixman_blt (uint32_t *src_bits,
835             uint32_t *dst_bits,
836             int       src_stride,
837             int       dst_stride,
838             int       src_bpp,
839             int       dst_bpp,
840             int       src_x,
841             int       src_y,
842             int       dst_x,
843             int       dst_y,
844             int       width,
845             int       height)
846 {
847     return _pixman_implementation_blt (get_implementation(),
848                                        src_bits, dst_bits, src_stride, dst_stride,
849                                        src_bpp, dst_bpp,
850                                        src_x, src_y,
851                                        dst_x, dst_y,
852                                        width, height);
853 }
854
855 PIXMAN_EXPORT pixman_bool_t
856 pixman_fill (uint32_t *bits,
857              int       stride,
858              int       bpp,
859              int       x,
860              int       y,
861              int       width,
862              int       height,
863              uint32_t xor)
864 {
865     return _pixman_implementation_fill (
866         get_implementation(), bits, stride, bpp, x, y, width, height, xor);
867 }
868
869 static uint32_t
870 color_to_uint32 (const pixman_color_t *color)
871 {
872     return
873         (color->alpha >> 8 << 24) |
874         (color->red >> 8 << 16) |
875         (color->green & 0xff00) |
876         (color->blue >> 8);
877 }
878
879 static pixman_bool_t
880 color_to_pixel (pixman_color_t *     color,
881                 uint32_t *           pixel,
882                 pixman_format_code_t format)
883 {
884     uint32_t c = color_to_uint32 (color);
885
886     if (!(format == PIXMAN_a8r8g8b8     ||
887           format == PIXMAN_x8r8g8b8     ||
888           format == PIXMAN_a8b8g8r8     ||
889           format == PIXMAN_x8b8g8r8     ||
890           format == PIXMAN_b8g8r8a8     ||
891           format == PIXMAN_b8g8r8x8     ||
892           format == PIXMAN_r5g6b5       ||
893           format == PIXMAN_b5g6r5       ||
894           format == PIXMAN_a8))
895     {
896         return FALSE;
897     }
898
899     if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_ABGR)
900     {
901         c = ((c & 0xff000000) >>  0) |
902             ((c & 0x00ff0000) >> 16) |
903             ((c & 0x0000ff00) >>  0) |
904             ((c & 0x000000ff) << 16);
905     }
906     if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_BGRA)
907     {
908         c = ((c & 0xff000000) >> 24) |
909             ((c & 0x00ff0000) >>  8) |
910             ((c & 0x0000ff00) <<  8) |
911             ((c & 0x000000ff) << 24);
912     }
913
914     if (format == PIXMAN_a8)
915         c = c >> 24;
916     else if (format == PIXMAN_r5g6b5 ||
917              format == PIXMAN_b5g6r5)
918         c = CONVERT_8888_TO_0565 (c);
919
920 #if 0
921     printf ("color: %x %x %x %x\n", color->alpha, color->red, color->green, color->blue);
922     printf ("pixel: %x\n", c);
923 #endif
924
925     *pixel = c;
926     return TRUE;
927 }
928
929 PIXMAN_EXPORT pixman_bool_t
930 pixman_image_fill_rectangles (pixman_op_t                 op,
931                               pixman_image_t *            dest,
932                               pixman_color_t *            color,
933                               int                         n_rects,
934                               const pixman_rectangle16_t *rects)
935 {
936     pixman_box32_t stack_boxes[6];
937     pixman_box32_t *boxes;
938     pixman_bool_t result;
939     int i;
940
941     if (n_rects > 6)
942     {
943         boxes = pixman_malloc_ab (sizeof (pixman_box32_t), n_rects);
944         if (boxes == NULL)
945             return FALSE;
946     }
947     else
948     {
949         boxes = stack_boxes;
950     }
951
952     for (i = 0; i < n_rects; ++i)
953     {
954         boxes[i].x1 = rects[i].x;
955         boxes[i].y1 = rects[i].y;
956         boxes[i].x2 = boxes[i].x1 + rects[i].width;
957         boxes[i].y2 = boxes[i].y1 + rects[i].height;
958     }
959
960     result = pixman_image_fill_boxes (op, dest, color, n_rects, boxes);
961
962     if (boxes != stack_boxes)
963         free (boxes);
964     
965     return result;
966 }
967
968 PIXMAN_EXPORT pixman_bool_t
969 pixman_image_fill_boxes (pixman_op_t           op,
970                          pixman_image_t *      dest,
971                          pixman_color_t *      color,
972                          int                   n_boxes,
973                          const pixman_box32_t *boxes)
974 {
975     pixman_image_t *solid;
976     pixman_color_t c;
977     int i;
978
979     _pixman_image_validate (dest);
980     
981     if (color->alpha == 0xffff)
982     {
983         if (op == PIXMAN_OP_OVER)
984             op = PIXMAN_OP_SRC;
985     }
986
987     if (op == PIXMAN_OP_CLEAR)
988     {
989         c.red = 0;
990         c.green = 0;
991         c.blue = 0;
992         c.alpha = 0;
993
994         color = &c;
995
996         op = PIXMAN_OP_SRC;
997     }
998
999     if (op == PIXMAN_OP_SRC)
1000     {
1001         uint32_t pixel;
1002
1003         if (color_to_pixel (color, &pixel, dest->bits.format))
1004         {
1005             pixman_region32_t fill_region;
1006             int n_rects, j;
1007             pixman_box32_t *rects;
1008
1009             if (!pixman_region32_init_rects (&fill_region, boxes, n_boxes))
1010                 return FALSE;
1011
1012             if (dest->common.have_clip_region)
1013             {
1014                 if (!pixman_region32_intersect (&fill_region,
1015                                                 &fill_region,
1016                                                 &dest->common.clip_region))
1017                     return FALSE;
1018             }
1019
1020             rects = pixman_region32_rectangles (&fill_region, &n_rects);
1021             for (j = 0; j < n_rects; ++j)
1022             {
1023                 const pixman_box32_t *rect = &(rects[j]);
1024                 pixman_fill (dest->bits.bits, dest->bits.rowstride, PIXMAN_FORMAT_BPP (dest->bits.format),
1025                              rect->x1, rect->y1, rect->x2 - rect->x1, rect->y2 - rect->y1,
1026                              pixel);
1027             }
1028
1029             pixman_region32_fini (&fill_region);
1030             return TRUE;
1031         }
1032     }
1033
1034     solid = pixman_image_create_solid_fill (color);
1035     if (!solid)
1036         return FALSE;
1037
1038     for (i = 0; i < n_boxes; ++i)
1039     {
1040         const pixman_box32_t *box = &(boxes[i]);
1041
1042         pixman_image_composite32 (op, solid, NULL, dest,
1043                                   0, 0, 0, 0,
1044                                   box->x1, box->y1,
1045                                   box->x2 - box->x1, box->y2 - box->y1);
1046     }
1047
1048     pixman_image_unref (solid);
1049
1050     return TRUE;
1051 }
1052
1053 /**
1054  * pixman_version:
1055  *
1056  * Returns the version of the pixman library encoded in a single
1057  * integer as per %PIXMAN_VERSION_ENCODE. The encoding ensures that
1058  * later versions compare greater than earlier versions.
1059  *
1060  * A run-time comparison to check that pixman's version is greater than
1061  * or equal to version X.Y.Z could be performed as follows:
1062  *
1063  * <informalexample><programlisting>
1064  * if (pixman_version() >= PIXMAN_VERSION_ENCODE(X,Y,Z)) {...}
1065  * </programlisting></informalexample>
1066  *
1067  * See also pixman_version_string() as well as the compile-time
1068  * equivalents %PIXMAN_VERSION and %PIXMAN_VERSION_STRING.
1069  *
1070  * Return value: the encoded version.
1071  **/
1072 PIXMAN_EXPORT int
1073 pixman_version (void)
1074 {
1075     return PIXMAN_VERSION;
1076 }
1077
1078 /**
1079  * pixman_version_string:
1080  *
1081  * Returns the version of the pixman library as a human-readable string
1082  * of the form "X.Y.Z".
1083  *
1084  * See also pixman_version() as well as the compile-time equivalents
1085  * %PIXMAN_VERSION_STRING and %PIXMAN_VERSION.
1086  *
1087  * Return value: a string containing the version.
1088  **/
1089 PIXMAN_EXPORT const char*
1090 pixman_version_string (void)
1091 {
1092     return PIXMAN_VERSION_STRING;
1093 }
1094
1095 /**
1096  * pixman_format_supported_source:
1097  * @format: A pixman_format_code_t format
1098  *
1099  * Return value: whether the provided format code is a supported
1100  * format for a pixman surface used as a source in
1101  * rendering.
1102  *
1103  * Currently, all pixman_format_code_t values are supported.
1104  **/
1105 PIXMAN_EXPORT pixman_bool_t
1106 pixman_format_supported_source (pixman_format_code_t format)
1107 {
1108     switch (format)
1109     {
1110     /* 32 bpp formats */
1111     case PIXMAN_a2b10g10r10:
1112     case PIXMAN_x2b10g10r10:
1113     case PIXMAN_a2r10g10b10:
1114     case PIXMAN_x2r10g10b10:
1115     case PIXMAN_a8r8g8b8:
1116     case PIXMAN_x8r8g8b8:
1117     case PIXMAN_a8b8g8r8:
1118     case PIXMAN_x8b8g8r8:
1119     case PIXMAN_b8g8r8a8:
1120     case PIXMAN_b8g8r8x8:
1121     case PIXMAN_r8g8b8:
1122     case PIXMAN_b8g8r8:
1123     case PIXMAN_r5g6b5:
1124     case PIXMAN_b5g6r5:
1125     /* 16 bpp formats */
1126     case PIXMAN_a1r5g5b5:
1127     case PIXMAN_x1r5g5b5:
1128     case PIXMAN_a1b5g5r5:
1129     case PIXMAN_x1b5g5r5:
1130     case PIXMAN_a4r4g4b4:
1131     case PIXMAN_x4r4g4b4:
1132     case PIXMAN_a4b4g4r4:
1133     case PIXMAN_x4b4g4r4:
1134     /* 8bpp formats */
1135     case PIXMAN_a8:
1136     case PIXMAN_r3g3b2:
1137     case PIXMAN_b2g3r3:
1138     case PIXMAN_a2r2g2b2:
1139     case PIXMAN_a2b2g2r2:
1140     case PIXMAN_c8:
1141     case PIXMAN_g8:
1142     case PIXMAN_x4a4:
1143     /* Collides with PIXMAN_c8
1144        case PIXMAN_x4c4:
1145      */
1146     /* Collides with PIXMAN_g8
1147        case PIXMAN_x4g4:
1148      */
1149     /* 4bpp formats */
1150     case PIXMAN_a4:
1151     case PIXMAN_r1g2b1:
1152     case PIXMAN_b1g2r1:
1153     case PIXMAN_a1r1g1b1:
1154     case PIXMAN_a1b1g1r1:
1155     case PIXMAN_c4:
1156     case PIXMAN_g4:
1157     /* 1bpp formats */
1158     case PIXMAN_a1:
1159     case PIXMAN_g1:
1160     /* YUV formats */
1161     case PIXMAN_yuy2:
1162     case PIXMAN_yv12:
1163         return TRUE;
1164
1165     default:
1166         return FALSE;
1167     }
1168 }
1169
1170 /**
1171  * pixman_format_supported_destination:
1172  * @format: A pixman_format_code_t format
1173  *
1174  * Return value: whether the provided format code is a supported
1175  * format for a pixman surface used as a destination in
1176  * rendering.
1177  *
1178  * Currently, all pixman_format_code_t values are supported
1179  * except for the YUV formats.
1180  **/
1181 PIXMAN_EXPORT pixman_bool_t
1182 pixman_format_supported_destination (pixman_format_code_t format)
1183 {
1184     /* YUV formats cannot be written to at the moment */
1185     if (format == PIXMAN_yuy2 || format == PIXMAN_yv12)
1186         return FALSE;
1187
1188     return pixman_format_supported_source (format);
1189 }
1190
1191 PIXMAN_EXPORT pixman_bool_t
1192 pixman_compute_composite_region (pixman_region16_t * region,
1193                                  pixman_image_t *    src_image,
1194                                  pixman_image_t *    mask_image,
1195                                  pixman_image_t *    dst_image,
1196                                  int16_t             src_x,
1197                                  int16_t             src_y,
1198                                  int16_t             mask_x,
1199                                  int16_t             mask_y,
1200                                  int16_t             dest_x,
1201                                  int16_t             dest_y,
1202                                  uint16_t            width,
1203                                  uint16_t            height)
1204 {
1205     pixman_region32_t r32;
1206     pixman_bool_t retval;
1207
1208     pixman_region32_init (&r32);
1209
1210     retval = pixman_compute_composite_region32 (
1211         &r32, src_image, mask_image, dst_image,
1212         src_x, src_y, mask_x, mask_y, dest_x, dest_y,
1213         width, height);
1214
1215     if (retval)
1216     {
1217         if (!pixman_region16_copy_from_region32 (region, &r32))
1218             retval = FALSE;
1219     }
1220
1221     pixman_region32_fini (&r32);
1222     return retval;
1223 }