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