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