1 /* -*- Mode: c; c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t; -*- */
3 * Copyright © 2000 SuSE, Inc.
4 * Copyright © 2007 Red Hat, Inc.
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.
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.
23 * Author: Keith Packard, SuSE, Inc.
29 #include "pixman-private.h"
33 static pixman_implementation_t *global_implementation;
35 #ifdef TOOLCHAIN_SUPPORTS_ATTRIBUTE_CONSTRUCTOR
36 static void __attribute__((constructor))
37 pixman_constructor (void)
39 global_implementation = _pixman_choose_implementation ();
43 static force_inline pixman_implementation_t *
44 get_implementation (void)
46 #ifndef TOOLCHAIN_SUPPORTS_ATTRIBUTE_CONSTRUCTOR
47 if (!global_implementation)
48 global_implementation = _pixman_choose_implementation ();
50 return global_implementation;
53 typedef struct operator_info_t operator_info_t;
55 struct operator_info_t
57 uint8_t opaque_info[4];
60 #define PACK(neither, src, dest, both) \
61 {{ (uint8_t)PIXMAN_OP_ ## neither, \
62 (uint8_t)PIXMAN_OP_ ## src, \
63 (uint8_t)PIXMAN_OP_ ## dest, \
64 (uint8_t)PIXMAN_OP_ ## both }}
66 static const operator_info_t operator_table[] =
68 /* Neither Opaque Src Opaque Dst Opaque Both Opaque */
69 PACK (CLEAR, CLEAR, CLEAR, CLEAR),
70 PACK (SRC, SRC, SRC, SRC),
71 PACK (DST, DST, DST, DST),
72 PACK (OVER, SRC, OVER, SRC),
73 PACK (OVER_REVERSE, OVER_REVERSE, DST, DST),
74 PACK (IN, IN, SRC, SRC),
75 PACK (IN_REVERSE, DST, IN_REVERSE, DST),
76 PACK (OUT, OUT, CLEAR, CLEAR),
77 PACK (OUT_REVERSE, CLEAR, OUT_REVERSE, CLEAR),
78 PACK (ATOP, IN, OVER, SRC),
79 PACK (ATOP_REVERSE, OVER_REVERSE, IN_REVERSE, DST),
80 PACK (XOR, OUT, OUT_REVERSE, CLEAR),
81 PACK (ADD, ADD, ADD, ADD),
82 PACK (SATURATE, OVER_REVERSE, DST, DST),
87 PACK (CLEAR, CLEAR, CLEAR, CLEAR),
88 PACK (SRC, SRC, SRC, SRC),
89 PACK (DST, DST, DST, DST),
90 PACK (DISJOINT_OVER, DISJOINT_OVER, DISJOINT_OVER, DISJOINT_OVER),
91 PACK (DISJOINT_OVER_REVERSE, DISJOINT_OVER_REVERSE, DISJOINT_OVER_REVERSE, DISJOINT_OVER_REVERSE),
92 PACK (DISJOINT_IN, DISJOINT_IN, DISJOINT_IN, DISJOINT_IN),
93 PACK (DISJOINT_IN_REVERSE, DISJOINT_IN_REVERSE, DISJOINT_IN_REVERSE, DISJOINT_IN_REVERSE),
94 PACK (DISJOINT_OUT, DISJOINT_OUT, DISJOINT_OUT, DISJOINT_OUT),
95 PACK (DISJOINT_OUT_REVERSE, DISJOINT_OUT_REVERSE, DISJOINT_OUT_REVERSE, DISJOINT_OUT_REVERSE),
96 PACK (DISJOINT_ATOP, DISJOINT_ATOP, DISJOINT_ATOP, DISJOINT_ATOP),
97 PACK (DISJOINT_ATOP_REVERSE, DISJOINT_ATOP_REVERSE, DISJOINT_ATOP_REVERSE, DISJOINT_ATOP_REVERSE),
98 PACK (DISJOINT_XOR, DISJOINT_XOR, DISJOINT_XOR, DISJOINT_XOR),
105 PACK (CLEAR, CLEAR, CLEAR, CLEAR),
106 PACK (SRC, SRC, SRC, SRC),
107 PACK (DST, DST, DST, DST),
108 PACK (CONJOINT_OVER, CONJOINT_OVER, CONJOINT_OVER, CONJOINT_OVER),
109 PACK (CONJOINT_OVER_REVERSE, CONJOINT_OVER_REVERSE, CONJOINT_OVER_REVERSE, CONJOINT_OVER_REVERSE),
110 PACK (CONJOINT_IN, CONJOINT_IN, CONJOINT_IN, CONJOINT_IN),
111 PACK (CONJOINT_IN_REVERSE, CONJOINT_IN_REVERSE, CONJOINT_IN_REVERSE, CONJOINT_IN_REVERSE),
112 PACK (CONJOINT_OUT, CONJOINT_OUT, CONJOINT_OUT, CONJOINT_OUT),
113 PACK (CONJOINT_OUT_REVERSE, CONJOINT_OUT_REVERSE, CONJOINT_OUT_REVERSE, CONJOINT_OUT_REVERSE),
114 PACK (CONJOINT_ATOP, CONJOINT_ATOP, CONJOINT_ATOP, CONJOINT_ATOP),
115 PACK (CONJOINT_ATOP_REVERSE, CONJOINT_ATOP_REVERSE, CONJOINT_ATOP_REVERSE, CONJOINT_ATOP_REVERSE),
116 PACK (CONJOINT_XOR, CONJOINT_XOR, CONJOINT_XOR, CONJOINT_XOR),
123 PACK (MULTIPLY, MULTIPLY, MULTIPLY, MULTIPLY),
124 PACK (SCREEN, SCREEN, SCREEN, SCREEN),
125 PACK (OVERLAY, OVERLAY, OVERLAY, OVERLAY),
126 PACK (DARKEN, DARKEN, DARKEN, DARKEN),
127 PACK (LIGHTEN, LIGHTEN, LIGHTEN, LIGHTEN),
128 PACK (COLOR_DODGE, COLOR_DODGE, COLOR_DODGE, COLOR_DODGE),
129 PACK (COLOR_BURN, COLOR_BURN, COLOR_BURN, COLOR_BURN),
130 PACK (HARD_LIGHT, HARD_LIGHT, HARD_LIGHT, HARD_LIGHT),
131 PACK (SOFT_LIGHT, SOFT_LIGHT, SOFT_LIGHT, SOFT_LIGHT),
132 PACK (DIFFERENCE, DIFFERENCE, DIFFERENCE, DIFFERENCE),
133 PACK (EXCLUSION, EXCLUSION, EXCLUSION, EXCLUSION),
134 PACK (HSL_HUE, HSL_HUE, HSL_HUE, HSL_HUE),
135 PACK (HSL_SATURATION, HSL_SATURATION, HSL_SATURATION, HSL_SATURATION),
136 PACK (HSL_COLOR, HSL_COLOR, HSL_COLOR, HSL_COLOR),
137 PACK (HSL_LUMINOSITY, HSL_LUMINOSITY, HSL_LUMINOSITY, HSL_LUMINOSITY),
141 * Optimize the current operator based on opacity of source or destination
142 * The output operator should be mathematically equivalent to the source.
145 optimize_operator (pixman_op_t op,
150 pixman_bool_t is_source_opaque, is_dest_opaque;
152 #define OPAQUE_SHIFT 13
154 COMPILE_TIME_ASSERT (FAST_PATH_IS_OPAQUE == (1 << OPAQUE_SHIFT));
156 is_dest_opaque = (dst_flags & FAST_PATH_IS_OPAQUE);
157 is_source_opaque = ((src_flags & mask_flags) & FAST_PATH_IS_OPAQUE);
159 is_dest_opaque >>= OPAQUE_SHIFT - 1;
160 is_source_opaque >>= OPAQUE_SHIFT;
162 return operator_table[op].opaque_info[is_dest_opaque | is_source_opaque];
166 * Computing composite region
168 static inline pixman_bool_t
169 clip_general_image (pixman_region32_t * region,
170 pixman_region32_t * clip,
174 if (pixman_region32_n_rects (region) == 1 &&
175 pixman_region32_n_rects (clip) == 1)
177 pixman_box32_t * rbox = pixman_region32_rectangles (region, NULL);
178 pixman_box32_t * cbox = pixman_region32_rectangles (clip, NULL);
181 if (rbox->x1 < (v = cbox->x1 + dx))
183 if (rbox->x2 > (v = cbox->x2 + dx))
185 if (rbox->y1 < (v = cbox->y1 + dy))
187 if (rbox->y2 > (v = cbox->y2 + dy))
189 if (rbox->x1 >= rbox->x2 || rbox->y1 >= rbox->y2)
191 pixman_region32_init (region);
195 else if (!pixman_region32_not_empty (clip))
202 pixman_region32_translate (region, -dx, -dy);
204 if (!pixman_region32_intersect (region, region, clip))
208 pixman_region32_translate (region, dx, dy);
211 return pixman_region32_not_empty (region);
214 static inline pixman_bool_t
215 clip_source_image (pixman_region32_t * region,
216 pixman_image_t * image,
220 /* Source clips are ignored, unless they are explicitly turned on
221 * and the clip in question was set by an X client. (Because if
222 * the clip was not set by a client, then it is a hierarchy
223 * clip and those should always be ignored for sources).
225 if (!image->common.clip_sources || !image->common.client_clip)
228 return clip_general_image (region,
229 &image->common.clip_region,
234 * returns FALSE if the final region is empty. Indistinguishable from
235 * an allocation failure, but rendering ignores those anyways.
238 pixman_compute_composite_region32 (pixman_region32_t * region,
239 pixman_image_t * src_image,
240 pixman_image_t * mask_image,
241 pixman_image_t * dest_image,
251 region->extents.x1 = dest_x;
252 region->extents.x2 = dest_x + width;
253 region->extents.y1 = dest_y;
254 region->extents.y2 = dest_y + height;
256 region->extents.x1 = MAX (region->extents.x1, 0);
257 region->extents.y1 = MAX (region->extents.y1, 0);
258 region->extents.x2 = MIN (region->extents.x2, dest_image->bits.width);
259 region->extents.y2 = MIN (region->extents.y2, dest_image->bits.height);
263 /* Check for empty operation */
264 if (region->extents.x1 >= region->extents.x2 ||
265 region->extents.y1 >= region->extents.y2)
267 region->extents.x1 = 0;
268 region->extents.x2 = 0;
269 region->extents.y1 = 0;
270 region->extents.y2 = 0;
274 if (dest_image->common.have_clip_region)
276 if (!clip_general_image (region, &dest_image->common.clip_region, 0, 0))
280 if (dest_image->common.alpha_map)
282 if (!pixman_region32_intersect_rect (region, region,
283 dest_image->common.alpha_origin_x,
284 dest_image->common.alpha_origin_y,
285 dest_image->common.alpha_map->width,
286 dest_image->common.alpha_map->height))
290 if (!pixman_region32_not_empty (region))
292 if (dest_image->common.alpha_map->common.have_clip_region)
294 if (!clip_general_image (region, &dest_image->common.alpha_map->common.clip_region,
295 -dest_image->common.alpha_origin_x,
296 -dest_image->common.alpha_origin_y))
303 /* clip against src */
304 if (src_image->common.have_clip_region)
306 if (!clip_source_image (region, src_image, dest_x - src_x, dest_y - src_y))
309 if (src_image->common.alpha_map && src_image->common.alpha_map->common.have_clip_region)
311 if (!clip_source_image (region, (pixman_image_t *)src_image->common.alpha_map,
312 dest_x - (src_x - src_image->common.alpha_origin_x),
313 dest_y - (src_y - src_image->common.alpha_origin_y)))
318 /* clip against mask */
319 if (mask_image && mask_image->common.have_clip_region)
321 if (!clip_source_image (region, mask_image, dest_x - mask_x, dest_y - mask_y))
324 if (mask_image->common.alpha_map && mask_image->common.alpha_map->common.have_clip_region)
326 if (!clip_source_image (region, (pixman_image_t *)mask_image->common.alpha_map,
327 dest_x - (mask_x - mask_image->common.alpha_origin_x),
328 dest_y - (mask_y - mask_image->common.alpha_origin_y)))
338 #define N_CACHED_FAST_PATHS 8
344 pixman_implementation_t * imp;
345 pixman_fast_path_t fast_path;
346 } cache [N_CACHED_FAST_PATHS];
349 PIXMAN_DEFINE_THREAD_LOCAL (cache_t, fast_path_cache);
351 static force_inline pixman_bool_t
352 lookup_composite_function (pixman_op_t op,
353 pixman_format_code_t src_format,
355 pixman_format_code_t mask_format,
357 pixman_format_code_t dest_format,
359 pixman_implementation_t **out_imp,
360 pixman_composite_func_t *out_func)
362 pixman_implementation_t *imp;
366 /* Check cache for fast paths */
367 cache = PIXMAN_GET_THREAD_LOCAL (fast_path_cache);
369 for (i = 0; i < N_CACHED_FAST_PATHS; ++i)
371 const pixman_fast_path_t *info = &(cache->cache[i].fast_path);
373 /* Note that we check for equality here, not whether
374 * the cached fast path matches. This is to prevent
375 * us from selecting an overly general fast path
376 * when a more specific one would work.
378 if (info->op == op &&
379 info->src_format == src_format &&
380 info->mask_format == mask_format &&
381 info->dest_format == dest_format &&
382 info->src_flags == src_flags &&
383 info->mask_flags == mask_flags &&
384 info->dest_flags == dest_flags &&
387 *out_imp = cache->cache[i].imp;
388 *out_func = cache->cache[i].fast_path.func;
394 for (imp = get_implementation (); imp != NULL; imp = imp->delegate)
396 const pixman_fast_path_t *info = imp->fast_paths;
398 while (info->op != PIXMAN_OP_NONE)
400 if ((info->op == op || info->op == PIXMAN_OP_any) &&
402 ((info->src_format == src_format) ||
403 (info->src_format == PIXMAN_any)) &&
404 ((info->mask_format == mask_format) ||
405 (info->mask_format == PIXMAN_any)) &&
406 ((info->dest_format == dest_format) ||
407 (info->dest_format == PIXMAN_any)) &&
409 (info->src_flags & src_flags) == info->src_flags &&
410 (info->mask_flags & mask_flags) == info->mask_flags &&
411 (info->dest_flags & dest_flags) == info->dest_flags)
414 *out_func = info->func;
416 /* Set i to the last spot in the cache so that the
417 * move-to-front code below will work
419 i = N_CACHED_FAST_PATHS - 1;
433 cache->cache[i + 1] = cache->cache[i];
435 cache->cache[0].imp = *out_imp;
436 cache->cache[0].fast_path.op = op;
437 cache->cache[0].fast_path.src_format = src_format;
438 cache->cache[0].fast_path.src_flags = src_flags;
439 cache->cache[0].fast_path.mask_format = mask_format;
440 cache->cache[0].fast_path.mask_flags = mask_flags;
441 cache->cache[0].fast_path.dest_format = dest_format;
442 cache->cache[0].fast_path.dest_flags = dest_flags;
443 cache->cache[0].fast_path.func = *out_func;
450 compute_sample_extents (pixman_transform_t *transform,
451 pixman_box32_t *extents,
452 pixman_fixed_t x_off, pixman_fixed_t y_off,
453 pixman_fixed_t width, pixman_fixed_t height)
455 pixman_fixed_t x1, y1, x2, y2;
456 pixman_fixed_48_16_t tx1, ty1, tx2, ty2;
458 /* We have checked earlier that (extents->x1 - x) etc. fit in a pixman_fixed_t */
459 x1 = (pixman_fixed_48_16_t)pixman_int_to_fixed (extents->x1) + pixman_fixed_1 / 2;
460 y1 = (pixman_fixed_48_16_t)pixman_int_to_fixed (extents->y1) + pixman_fixed_1 / 2;
461 x2 = (pixman_fixed_48_16_t)pixman_int_to_fixed (extents->x2) - pixman_fixed_1 / 2;
462 y2 = (pixman_fixed_48_16_t)pixman_int_to_fixed (extents->y2) - pixman_fixed_1 / 2;
466 tx1 = (pixman_fixed_48_16_t)x1;
467 ty1 = (pixman_fixed_48_16_t)y1;
468 tx2 = (pixman_fixed_48_16_t)x2;
469 ty2 = (pixman_fixed_48_16_t)y2;
476 tx1 = ty1 = tx2 = ty2 = 0;
478 for (i = 0; i < 4; ++i)
480 pixman_fixed_48_16_t tx, ty;
483 v.vector[0] = (i & 0x01)? x1 : x2;
484 v.vector[1] = (i & 0x02)? y1 : y2;
485 v.vector[2] = pixman_fixed_1;
487 if (!pixman_transform_point (transform, &v))
490 tx = (pixman_fixed_48_16_t)v.vector[0];
491 ty = (pixman_fixed_48_16_t)v.vector[1];
514 /* Expand the source area by a tiny bit so account of different rounding that
515 * may happen during sampling. Note that (8 * pixman_fixed_e) is very far from
516 * 0.5 so this won't cause the area computed to be overly pessimistic.
518 tx1 += x_off - 8 * pixman_fixed_e;
519 ty1 += y_off - 8 * pixman_fixed_e;
520 tx2 += x_off + width + 8 * pixman_fixed_e;
521 ty2 += y_off + height + 8 * pixman_fixed_e;
523 if (tx1 < pixman_min_fixed_48_16 || tx1 > pixman_max_fixed_48_16 ||
524 ty1 < pixman_min_fixed_48_16 || ty1 > pixman_max_fixed_48_16 ||
525 tx2 < pixman_min_fixed_48_16 || tx2 > pixman_max_fixed_48_16 ||
526 ty2 < pixman_min_fixed_48_16 || ty2 > pixman_max_fixed_48_16)
532 extents->x1 = pixman_fixed_to_int (tx1);
533 extents->y1 = pixman_fixed_to_int (ty1);
534 extents->x2 = pixman_fixed_to_int (tx2) + 1;
535 extents->y2 = pixman_fixed_to_int (ty2) + 1;
541 #define IS_16BIT(x) (((x) >= INT16_MIN) && ((x) <= INT16_MAX))
544 analyze_extent (pixman_image_t *image,
545 const pixman_box32_t *extents,
548 pixman_transform_t *transform;
549 pixman_fixed_t *params;
550 pixman_fixed_t x_off, y_off;
551 pixman_fixed_t width, height;
557 /* Some compositing functions walk one step
558 * outside the destination rectangle, so we
559 * check here that the expanded-by-one source
560 * extents in destination space fits in 16 bits
562 if (!IS_16BIT (extents->x1 - 1) ||
563 !IS_16BIT (extents->y1 - 1) ||
564 !IS_16BIT (extents->x2 + 1) ||
565 !IS_16BIT (extents->y2 + 1))
570 transform = image->common.transform;
571 if (image->common.type == BITS)
573 /* During repeat mode calculations we might convert the
574 * width/height of an image to fixed 16.16, so we need
575 * them to be smaller than 16 bits.
577 if (image->bits.width >= 0x7fff || image->bits.height >= 0x7fff)
580 #define ID_AND_NEAREST (FAST_PATH_ID_TRANSFORM | FAST_PATH_NEAREST_FILTER)
582 if ((image->common.flags & ID_AND_NEAREST) == ID_AND_NEAREST &&
585 extents->x2 <= image->bits.width &&
586 extents->y2 <= image->bits.height)
588 *flags |= FAST_PATH_SAMPLES_COVER_CLIP;
592 switch (image->common.filter)
594 case PIXMAN_FILTER_CONVOLUTION:
595 params = image->common.filter_params;
596 x_off = - pixman_fixed_e - ((params[0] - pixman_fixed_1) >> 1);
597 y_off = - pixman_fixed_e - ((params[1] - pixman_fixed_1) >> 1);
602 case PIXMAN_FILTER_GOOD:
603 case PIXMAN_FILTER_BEST:
604 case PIXMAN_FILTER_BILINEAR:
605 x_off = - pixman_fixed_1 / 2;
606 y_off = - pixman_fixed_1 / 2;
607 width = pixman_fixed_1;
608 height = pixman_fixed_1;
611 case PIXMAN_FILTER_FAST:
612 case PIXMAN_FILTER_NEAREST:
613 x_off = - pixman_fixed_e;
614 y_off = - pixman_fixed_e;
623 /* Check whether the non-expanded, transformed extent is entirely within
624 * the source image, and set the FAST_PATH_SAMPLES_COVER_CLIP if it is.
627 if (compute_sample_extents (transform, &ex, x_off, y_off, width, height) &&
628 ex.x1 >= 0 && ex.y1 >= 0 &&
629 ex.x2 <= image->bits.width && ex.y2 <= image->bits.height)
631 *flags |= FAST_PATH_SAMPLES_COVER_CLIP;
642 /* Check that the extents expanded by one don't overflow. This ensures that
643 * compositing functions can simply walk the source space using 16.16
644 * variables without worrying about overflow.
646 ex.x1 = extents->x1 - 1;
647 ex.y1 = extents->y1 - 1;
648 ex.x2 = extents->x2 + 1;
649 ex.y2 = extents->y2 + 1;
651 if (!compute_sample_extents (transform, &ex, x_off, y_off, width, height))
658 * Work around GCC bug causing crashes in Mozilla with SSE2
660 * When using -msse, gcc generates movdqa instructions assuming that
661 * the stack is 16 byte aligned. Unfortunately some applications, such
662 * as Mozilla and Mono, end up aligning the stack to 4 bytes, which
663 * causes the movdqa instructions to fail.
665 * The __force_align_arg_pointer__ makes gcc generate a prologue that
666 * realigns the stack pointer to 16 bytes.
668 * On x86-64 this is not necessary because the standard ABI already
669 * calls for a 16 byte aligned stack.
671 * See https://bugs.freedesktop.org/show_bug.cgi?id=15693
673 #if defined (USE_SSE2) && defined(__GNUC__) && !defined(__x86_64__) && !defined(__amd64__)
674 __attribute__((__force_align_arg_pointer__))
677 pixman_image_composite32 (pixman_op_t op,
678 pixman_image_t * src,
679 pixman_image_t * mask,
680 pixman_image_t * dest,
690 pixman_format_code_t src_format, mask_format, dest_format;
691 uint32_t src_flags, mask_flags, dest_flags;
692 pixman_region32_t region;
693 pixman_box32_t extents;
694 pixman_implementation_t *imp;
695 pixman_composite_func_t func;
697 _pixman_image_validate (src);
699 _pixman_image_validate (mask);
700 _pixman_image_validate (dest);
702 src_format = src->common.extended_format_code;
703 src_flags = src->common.flags;
707 mask_format = mask->common.extended_format_code;
708 mask_flags = mask->common.flags;
712 mask_format = PIXMAN_null;
713 mask_flags = FAST_PATH_IS_OPAQUE;
716 dest_format = dest->common.extended_format_code;
717 dest_flags = dest->common.flags;
719 /* Check for pixbufs */
720 if ((mask_format == PIXMAN_a8r8g8b8 || mask_format == PIXMAN_a8b8g8r8) &&
721 (src->type == BITS && src->bits.bits == mask->bits.bits) &&
722 (src->common.repeat == mask->common.repeat) &&
723 (src_x == mask_x && src_y == mask_y))
725 if (src_format == PIXMAN_x8b8g8r8)
726 src_format = mask_format = PIXMAN_pixbuf;
727 else if (src_format == PIXMAN_x8r8g8b8)
728 src_format = mask_format = PIXMAN_rpixbuf;
731 pixman_region32_init (®ion);
733 if (!pixman_compute_composite_region32 (
734 ®ion, src, mask, dest,
735 src_x, src_y, mask_x, mask_y, dest_x, dest_y, width, height))
740 extents = *pixman_region32_extents (®ion);
742 extents.x1 -= dest_x - src_x;
743 extents.y1 -= dest_y - src_y;
744 extents.x2 -= dest_x - src_x;
745 extents.y2 -= dest_y - src_y;
747 if (!analyze_extent (src, &extents, &src_flags))
750 extents.x1 -= src_x - mask_x;
751 extents.y1 -= src_y - mask_y;
752 extents.x2 -= src_x - mask_x;
753 extents.y2 -= src_y - mask_y;
755 if (!analyze_extent (mask, &extents, &mask_flags))
758 /* If the clip is within the source samples, and the samples are opaque,
759 * then the source is effectively opaque.
761 #define BOTH (FAST_PATH_SAMPLES_OPAQUE | FAST_PATH_SAMPLES_COVER_CLIP)
763 if ((src_flags & BOTH) == BOTH)
764 src_flags |= FAST_PATH_IS_OPAQUE;
766 if ((mask_flags & BOTH) == BOTH)
767 mask_flags |= FAST_PATH_IS_OPAQUE;
770 * Check if we can replace our operator by a simpler one
771 * if the src or dest are opaque. The output operator should be
772 * mathematically equivalent to the source.
774 op = optimize_operator (op, src_flags, mask_flags, dest_flags);
776 if (lookup_composite_function (op,
777 src_format, src_flags,
778 mask_format, mask_flags,
779 dest_format, dest_flags,
782 pixman_composite_info_t info;
783 const pixman_box32_t *pbox;
787 info.src_image = src;
788 info.mask_image = mask;
789 info.dest_image = dest;
791 pbox = pixman_region32_rectangles (®ion, &n);
795 info.src_x = pbox->x1 + src_x - dest_x;
796 info.src_y = pbox->y1 + src_y - dest_y;
797 info.mask_x = pbox->x1 + mask_x - dest_x;
798 info.mask_y = pbox->y1 + mask_y - dest_y;
799 info.dest_x = pbox->x1;
800 info.dest_y = pbox->y1;
801 info.width = pbox->x2 - pbox->x1;
802 info.height = pbox->y2 - pbox->y1;
811 pixman_region32_fini (®ion);
815 pixman_image_composite (pixman_op_t op,
816 pixman_image_t * src,
817 pixman_image_t * mask,
818 pixman_image_t * dest,
828 pixman_image_composite32 (op, src, mask, dest, src_x, src_y,
829 mask_x, mask_y, dest_x, dest_y, width, height);
832 PIXMAN_EXPORT pixman_bool_t
833 pixman_blt (uint32_t *src_bits,
846 return _pixman_implementation_blt (get_implementation(),
847 src_bits, dst_bits, src_stride, dst_stride,
854 PIXMAN_EXPORT pixman_bool_t
855 pixman_fill (uint32_t *bits,
864 return _pixman_implementation_fill (
865 get_implementation(), bits, stride, bpp, x, y, width, height, xor);
869 color_to_uint32 (const pixman_color_t *color)
872 (color->alpha >> 8 << 24) |
873 (color->red >> 8 << 16) |
874 (color->green & 0xff00) |
879 color_to_pixel (pixman_color_t * color,
881 pixman_format_code_t format)
883 uint32_t c = color_to_uint32 (color);
885 if (!(format == PIXMAN_a8r8g8b8 ||
886 format == PIXMAN_x8r8g8b8 ||
887 format == PIXMAN_a8b8g8r8 ||
888 format == PIXMAN_x8b8g8r8 ||
889 format == PIXMAN_b8g8r8a8 ||
890 format == PIXMAN_b8g8r8x8 ||
891 format == PIXMAN_r8g8b8a8 ||
892 format == PIXMAN_r8g8b8x8 ||
893 format == PIXMAN_r5g6b5 ||
894 format == PIXMAN_b5g6r5 ||
895 format == PIXMAN_a8 ||
896 format == PIXMAN_a1))
901 if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_ABGR)
903 c = ((c & 0xff000000) >> 0) |
904 ((c & 0x00ff0000) >> 16) |
905 ((c & 0x0000ff00) >> 0) |
906 ((c & 0x000000ff) << 16);
908 if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_BGRA)
910 c = ((c & 0xff000000) >> 24) |
911 ((c & 0x00ff0000) >> 8) |
912 ((c & 0x0000ff00) << 8) |
913 ((c & 0x000000ff) << 24);
915 if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_RGBA)
916 c = ((c & 0xff000000) >> 24) | (c << 8);
918 if (format == PIXMAN_a1)
920 else if (format == PIXMAN_a8)
922 else if (format == PIXMAN_r5g6b5 ||
923 format == PIXMAN_b5g6r5)
924 c = CONVERT_8888_TO_0565 (c);
927 printf ("color: %x %x %x %x\n", color->alpha, color->red, color->green, color->blue);
928 printf ("pixel: %x\n", c);
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,
940 const pixman_rectangle16_t *rects)
942 pixman_box32_t stack_boxes[6];
943 pixman_box32_t *boxes;
944 pixman_bool_t result;
949 boxes = pixman_malloc_ab (sizeof (pixman_box32_t), n_rects);
958 for (i = 0; i < n_rects; ++i)
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;
966 result = pixman_image_fill_boxes (op, dest, color, n_rects, boxes);
968 if (boxes != stack_boxes)
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,
979 const pixman_box32_t *boxes)
981 pixman_image_t *solid;
985 _pixman_image_validate (dest);
987 if (color->alpha == 0xffff)
989 if (op == PIXMAN_OP_OVER)
993 if (op == PIXMAN_OP_CLEAR)
1005 if (op == PIXMAN_OP_SRC)
1009 if (color_to_pixel (color, &pixel, dest->bits.format))
1011 pixman_region32_t fill_region;
1013 pixman_box32_t *rects;
1015 if (!pixman_region32_init_rects (&fill_region, boxes, n_boxes))
1018 if (dest->common.have_clip_region)
1020 if (!pixman_region32_intersect (&fill_region,
1022 &dest->common.clip_region))
1026 rects = pixman_region32_rectangles (&fill_region, &n_rects);
1027 for (j = 0; j < n_rects; ++j)
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,
1035 pixman_region32_fini (&fill_region);
1040 solid = pixman_image_create_solid_fill (color);
1044 for (i = 0; i < n_boxes; ++i)
1046 const pixman_box32_t *box = &(boxes[i]);
1048 pixman_image_composite32 (op, solid, NULL, dest,
1051 box->x2 - box->x1, box->y2 - box->y1);
1054 pixman_image_unref (solid);
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.
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:
1069 * <informalexample><programlisting>
1070 * if (pixman_version() >= PIXMAN_VERSION_ENCODE(X,Y,Z)) {...}
1071 * </programlisting></informalexample>
1073 * See also pixman_version_string() as well as the compile-time
1074 * equivalents %PIXMAN_VERSION and %PIXMAN_VERSION_STRING.
1076 * Return value: the encoded version.
1079 pixman_version (void)
1081 return PIXMAN_VERSION;
1085 * pixman_version_string:
1087 * Returns the version of the pixman library as a human-readable string
1088 * of the form "X.Y.Z".
1090 * See also pixman_version() as well as the compile-time equivalents
1091 * %PIXMAN_VERSION_STRING and %PIXMAN_VERSION.
1093 * Return value: a string containing the version.
1095 PIXMAN_EXPORT const char*
1096 pixman_version_string (void)
1098 return PIXMAN_VERSION_STRING;
1102 * pixman_format_supported_source:
1103 * @format: A pixman_format_code_t format
1105 * Return value: whether the provided format code is a supported
1106 * format for a pixman surface used as a source in
1109 * Currently, all pixman_format_code_t values are supported.
1111 PIXMAN_EXPORT pixman_bool_t
1112 pixman_format_supported_source (pixman_format_code_t format)
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_r8g8b8a8:
1128 case PIXMAN_r8g8b8x8:
1133 case PIXMAN_x14r6g6b6:
1134 /* 16 bpp formats */
1135 case PIXMAN_a1r5g5b5:
1136 case PIXMAN_x1r5g5b5:
1137 case PIXMAN_a1b5g5r5:
1138 case PIXMAN_x1b5g5r5:
1139 case PIXMAN_a4r4g4b4:
1140 case PIXMAN_x4r4g4b4:
1141 case PIXMAN_a4b4g4r4:
1142 case PIXMAN_x4b4g4r4:
1147 case PIXMAN_a2r2g2b2:
1148 case PIXMAN_a2b2g2r2:
1152 /* Collides with PIXMAN_c8
1155 /* Collides with PIXMAN_g8
1162 case PIXMAN_a1r1g1b1:
1163 case PIXMAN_a1b1g1r1:
1180 * pixman_format_supported_destination:
1181 * @format: A pixman_format_code_t format
1183 * Return value: whether the provided format code is a supported
1184 * format for a pixman surface used as a destination in
1187 * Currently, all pixman_format_code_t values are supported
1188 * except for the YUV formats.
1190 PIXMAN_EXPORT pixman_bool_t
1191 pixman_format_supported_destination (pixman_format_code_t format)
1193 /* YUV formats cannot be written to at the moment */
1194 if (format == PIXMAN_yuy2 || format == PIXMAN_yv12)
1197 return pixman_format_supported_source (format);
1200 PIXMAN_EXPORT pixman_bool_t
1201 pixman_compute_composite_region (pixman_region16_t * region,
1202 pixman_image_t * src_image,
1203 pixman_image_t * mask_image,
1204 pixman_image_t * dest_image,
1214 pixman_region32_t r32;
1215 pixman_bool_t retval;
1217 pixman_region32_init (&r32);
1219 retval = pixman_compute_composite_region32 (
1220 &r32, src_image, mask_image, dest_image,
1221 src_x, src_y, mask_x, mask_y, dest_x, dest_y,
1226 if (!pixman_region16_copy_from_region32 (region, &r32))
1230 pixman_region32_fini (&r32);