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