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