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