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 force_inline pixman_implementation_t *
34 get_implementation (void)
36 static pixman_implementation_t *global_implementation;
38 if (!global_implementation)
39 global_implementation = _pixman_choose_implementation ();
41 return global_implementation;
44 typedef struct operator_info_t operator_info_t;
46 struct operator_info_t
48 uint8_t opaque_info[4];
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 }}
57 static const operator_info_t operator_table[] =
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),
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),
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),
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),
132 * Optimize the current operator based on opacity of source or destination
133 * The output operator should be mathematically equivalent to the source.
136 optimize_operator (pixman_op_t op,
141 pixman_bool_t is_source_opaque, is_dest_opaque;
143 #define OPAQUE_SHIFT 13
145 COMPILE_TIME_ASSERT (FAST_PATH_IS_OPAQUE == (1 << OPAQUE_SHIFT));
147 is_dest_opaque = (dst_flags & FAST_PATH_IS_OPAQUE);
148 is_source_opaque = ((src_flags & mask_flags) & FAST_PATH_IS_OPAQUE);
150 is_dest_opaque >>= OPAQUE_SHIFT - 1;
151 is_source_opaque >>= OPAQUE_SHIFT;
153 return operator_table[op].opaque_info[is_dest_opaque | is_source_opaque];
157 apply_workaround (pixman_image_t *image,
160 uint32_t ** save_bits,
164 if (image && (image->common.flags & FAST_PATH_NEEDS_WORKAROUND))
166 /* Some X servers generate images that point to the
167 * wrong place in memory, but then set the clip region
168 * to point to the right place. Because of an old bug
169 * in pixman, this would actually work.
171 * Here we try and undo the damage
173 int bpp = PIXMAN_FORMAT_BPP (image->bits.format) / 8;
174 pixman_box32_t *extents;
178 extents = pixman_region32_extents (&(image->common.clip_region));
182 *save_bits = image->bits.bits;
186 pixman_region32_translate (&(image->common.clip_region), -dx, -dy);
188 t = (uint8_t *)image->bits.bits;
189 t += dy * image->bits.rowstride * 4 + dx * bpp;
190 image->bits.bits = (uint32_t *)t;
198 unapply_workaround (pixman_image_t *image, uint32_t *bits, int dx, int dy)
200 if (image && (image->common.flags & FAST_PATH_NEEDS_WORKAROUND))
202 image->bits.bits = bits;
203 pixman_region32_translate (&image->common.clip_region, dx, dy);
208 * Computing composite region
210 static inline pixman_bool_t
211 clip_general_image (pixman_region32_t * region,
212 pixman_region32_t * clip,
216 if (pixman_region32_n_rects (region) == 1 &&
217 pixman_region32_n_rects (clip) == 1)
219 pixman_box32_t * rbox = pixman_region32_rectangles (region, NULL);
220 pixman_box32_t * cbox = pixman_region32_rectangles (clip, NULL);
223 if (rbox->x1 < (v = cbox->x1 + dx))
225 if (rbox->x2 > (v = cbox->x2 + dx))
227 if (rbox->y1 < (v = cbox->y1 + dy))
229 if (rbox->y2 > (v = cbox->y2 + dy))
231 if (rbox->x1 >= rbox->x2 || rbox->y1 >= rbox->y2)
233 pixman_region32_init (region);
237 else if (!pixman_region32_not_empty (clip))
244 pixman_region32_translate (region, -dx, -dy);
246 if (!pixman_region32_intersect (region, region, clip))
250 pixman_region32_translate (region, dx, dy);
253 return pixman_region32_not_empty (region);
256 static inline pixman_bool_t
257 clip_source_image (pixman_region32_t * region,
258 pixman_image_t * image,
262 /* Source clips are ignored, unless they are explicitly turned on
263 * and the clip in question was set by an X client. (Because if
264 * the clip was not set by a client, then it is a hierarchy
265 * clip and those should always be ignored for sources).
267 if (!image->common.clip_sources || !image->common.client_clip)
270 return clip_general_image (region,
271 &image->common.clip_region,
276 * returns FALSE if the final region is empty. Indistinguishable from
277 * an allocation failure, but rendering ignores those anyways.
280 pixman_compute_composite_region32 (pixman_region32_t * region,
281 pixman_image_t * src_image,
282 pixman_image_t * mask_image,
283 pixman_image_t * dst_image,
293 region->extents.x1 = dest_x;
294 region->extents.x2 = dest_x + width;
295 region->extents.y1 = dest_y;
296 region->extents.y2 = dest_y + height;
298 region->extents.x1 = MAX (region->extents.x1, 0);
299 region->extents.y1 = MAX (region->extents.y1, 0);
300 region->extents.x2 = MIN (region->extents.x2, dst_image->bits.width);
301 region->extents.y2 = MIN (region->extents.y2, dst_image->bits.height);
305 /* Check for empty operation */
306 if (region->extents.x1 >= region->extents.x2 ||
307 region->extents.y1 >= region->extents.y2)
312 if (dst_image->common.have_clip_region)
314 if (!clip_general_image (region, &dst_image->common.clip_region, 0, 0))
318 if (dst_image->common.alpha_map && dst_image->common.alpha_map->common.have_clip_region)
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))
328 /* clip against src */
329 if (src_image->common.have_clip_region)
331 if (!clip_source_image (region, src_image, dest_x - src_x, dest_y - src_y))
334 if (src_image->common.alpha_map && src_image->common.alpha_map->common.have_clip_region)
336 if (!clip_source_image (region, (pixman_image_t *)src_image->common.alpha_map,
337 dest_x - (src_x - src_image->common.alpha_origin_x),
338 dest_y - (src_y - src_image->common.alpha_origin_y)))
343 /* clip against mask */
344 if (mask_image && mask_image->common.have_clip_region)
346 if (!clip_source_image (region, mask_image, dest_x - mask_x, dest_y - mask_y))
349 if (mask_image->common.alpha_map && mask_image->common.alpha_map->common.have_clip_region)
351 if (!clip_source_image (region, (pixman_image_t *)mask_image->common.alpha_map,
352 dest_x - (mask_x - mask_image->common.alpha_origin_x),
353 dest_y - (mask_y - mask_image->common.alpha_origin_y)))
364 walk_region_internal (pixman_implementation_t *imp,
366 pixman_image_t * src_image,
367 pixman_image_t * mask_image,
368 pixman_image_t * dst_image,
377 pixman_bool_t src_repeat,
378 pixman_bool_t mask_repeat,
379 pixman_region32_t * region,
380 pixman_composite_func_t composite_rect)
382 int w, h, w_this, h_this;
383 int x_msk, y_msk, x_src, y_src, x_dst, y_dst;
384 int src_dy = src_y - dest_y;
385 int src_dx = src_x - dest_x;
386 int mask_dy = mask_y - dest_y;
387 int mask_dx = mask_x - dest_x;
388 const pixman_box32_t *pbox;
391 pbox = pixman_region32_rectangles (region, &n);
393 /* Fast path for non-repeating sources */
394 if (!src_repeat && !mask_repeat)
398 (*composite_rect) (imp, op,
399 src_image, mask_image, dst_image,
407 pbox->y2 - pbox->y1);
417 h = pbox->y2 - pbox->y1;
418 y_src = pbox->y1 + src_dy;
419 y_msk = pbox->y1 + mask_dy;
425 w = pbox->x2 - pbox->x1;
426 x_src = pbox->x1 + src_dx;
427 x_msk = pbox->x1 + mask_dx;
432 y_msk = MOD (y_msk, mask_image->bits.height);
433 if (h_this > mask_image->bits.height - y_msk)
434 h_this = mask_image->bits.height - y_msk;
439 y_src = MOD (y_src, src_image->bits.height);
440 if (h_this > src_image->bits.height - y_src)
441 h_this = src_image->bits.height - y_src;
450 x_msk = MOD (x_msk, mask_image->bits.width);
451 if (w_this > mask_image->bits.width - x_msk)
452 w_this = mask_image->bits.width - x_msk;
457 x_src = MOD (x_src, src_image->bits.width);
458 if (w_this > src_image->bits.width - x_src)
459 w_this = src_image->bits.width - x_src;
462 (*composite_rect) (imp, op,
463 src_image, mask_image, dst_image,
464 x_src, y_src, x_msk, y_msk, x_dst, y_dst,
483 #define N_CACHED_FAST_PATHS 8
489 pixman_implementation_t * imp;
490 pixman_fast_path_t fast_path;
491 } cache [N_CACHED_FAST_PATHS];
494 PIXMAN_DEFINE_THREAD_LOCAL (cache_t, fast_path_cache);
496 static force_inline pixman_bool_t
497 lookup_composite_function (pixman_op_t op,
498 pixman_format_code_t src_format,
500 pixman_format_code_t mask_format,
502 pixman_format_code_t dest_format,
504 pixman_implementation_t **out_imp,
505 pixman_composite_func_t *out_func)
507 pixman_implementation_t *imp;
511 /* Check cache for fast paths */
512 cache = PIXMAN_GET_THREAD_LOCAL (fast_path_cache);
514 for (i = 0; i < N_CACHED_FAST_PATHS; ++i)
516 const pixman_fast_path_t *info = &(cache->cache[i].fast_path);
518 /* Note that we check for equality here, not whether
519 * the cached fast path matches. This is to prevent
520 * us from selecting an overly general fast path
521 * when a more specific one would work.
523 if (info->op == op &&
524 info->src_format == src_format &&
525 info->mask_format == mask_format &&
526 info->dest_format == dest_format &&
527 info->src_flags == src_flags &&
528 info->mask_flags == mask_flags &&
529 info->dest_flags == dest_flags &&
532 *out_imp = cache->cache[i].imp;
533 *out_func = cache->cache[i].fast_path.func;
539 for (imp = get_implementation (); imp != NULL; imp = imp->delegate)
541 const pixman_fast_path_t *info = imp->fast_paths;
543 while (info->op != PIXMAN_OP_NONE)
545 if ((info->op == op || info->op == PIXMAN_OP_any) &&
547 ((info->src_format == src_format) ||
548 (info->src_format == PIXMAN_any)) &&
549 ((info->mask_format == mask_format) ||
550 (info->mask_format == PIXMAN_any)) &&
551 ((info->dest_format == dest_format) ||
552 (info->dest_format == PIXMAN_any)) &&
554 (info->src_flags & src_flags) == info->src_flags &&
555 (info->mask_flags & mask_flags) == info->mask_flags &&
556 (info->dest_flags & dest_flags) == info->dest_flags)
559 *out_func = info->func;
561 /* Set i to the last spot in the cache so that the
562 * move-to-front code below will work
564 i = N_CACHED_FAST_PATHS - 1;
578 cache->cache[i + 1] = cache->cache[i];
580 cache->cache[0].imp = *out_imp;
581 cache->cache[0].fast_path.op = op;
582 cache->cache[0].fast_path.src_format = src_format;
583 cache->cache[0].fast_path.src_flags = src_flags;
584 cache->cache[0].fast_path.mask_format = mask_format;
585 cache->cache[0].fast_path.mask_flags = mask_flags;
586 cache->cache[0].fast_path.dest_format = dest_format;
587 cache->cache[0].fast_path.dest_flags = dest_flags;
588 cache->cache[0].fast_path.func = *out_func;
595 compute_sample_extents (pixman_transform_t *transform,
596 pixman_box32_t *extents, int x, int y,
597 pixman_fixed_t x_off, pixman_fixed_t y_off,
598 pixman_fixed_t width, pixman_fixed_t height)
600 pixman_fixed_t x1, y1, x2, y2;
601 pixman_fixed_48_16_t tx1, ty1, tx2, ty2;
603 /* We have checked earlier that (extents->x1 - x) etc. fit in a pixman_fixed_t */
604 x1 = (pixman_fixed_48_16_t)pixman_int_to_fixed (extents->x1 - x) + pixman_fixed_1 / 2;
605 y1 = (pixman_fixed_48_16_t)pixman_int_to_fixed (extents->y1 - y) + pixman_fixed_1 / 2;
606 x2 = (pixman_fixed_48_16_t)pixman_int_to_fixed (extents->x2 - x) - pixman_fixed_1 / 2;
607 y2 = (pixman_fixed_48_16_t)pixman_int_to_fixed (extents->y2 - y) - pixman_fixed_1 / 2;
611 tx1 = (pixman_fixed_48_16_t)x1;
612 ty1 = (pixman_fixed_48_16_t)y1;
613 tx2 = (pixman_fixed_48_16_t)x2;
614 ty2 = (pixman_fixed_48_16_t)y2;
621 tx1 = ty1 = tx2 = ty2 = 0;
623 for (i = 0; i < 4; ++i)
625 pixman_fixed_48_16_t tx, ty;
628 v.vector[0] = (i & 0x01)? x1 : x2;
629 v.vector[1] = (i & 0x02)? y1 : y2;
630 v.vector[2] = pixman_fixed_1;
632 if (!pixman_transform_point (transform, &v))
635 tx = (pixman_fixed_48_16_t)v.vector[0];
636 ty = (pixman_fixed_48_16_t)v.vector[1];
659 /* Expand the source area by a tiny bit so account of different rounding that
660 * may happen during sampling. Note that (8 * pixman_fixed_e) is very far from
661 * 0.5 so this won't cause the area computed to be overly pessimistic.
663 tx1 += x_off - 8 * pixman_fixed_e;
664 ty1 += y_off - 8 * pixman_fixed_e;
665 tx2 += x_off + width + 8 * pixman_fixed_e;
666 ty2 += y_off + height + 8 * pixman_fixed_e;
668 if (tx1 < pixman_min_fixed_48_16 || tx1 > pixman_max_fixed_48_16 ||
669 ty1 < pixman_min_fixed_48_16 || ty1 > pixman_max_fixed_48_16 ||
670 tx2 < pixman_min_fixed_48_16 || tx2 > pixman_max_fixed_48_16 ||
671 ty2 < pixman_min_fixed_48_16 || ty2 > pixman_max_fixed_48_16)
677 extents->x1 = pixman_fixed_to_int (tx1);
678 extents->y1 = pixman_fixed_to_int (ty1);
679 extents->x2 = pixman_fixed_to_int (tx2) + 1;
680 extents->y2 = pixman_fixed_to_int (ty2) + 1;
686 #define IS_16BIT(x) (((x) >= INT16_MIN) && ((x) <= INT16_MAX))
689 analyze_extent (pixman_image_t *image, int x, int y,
690 const pixman_box32_t *extents, uint32_t *flags)
692 pixman_transform_t *transform;
693 pixman_fixed_t *params;
694 pixman_fixed_t x_off, y_off;
695 pixman_fixed_t width, height;
698 *flags |= FAST_PATH_COVERS_CLIP;
702 transform = image->common.transform;
703 if (image->common.type == BITS)
705 /* During repeat mode calculations we might convert the
706 * width/height of an image to fixed 16.16, so we need
707 * them to be smaller than 16 bits.
709 if (image->bits.width >= 0x7fff || image->bits.height >= 0x7fff)
712 if (image->common.repeat == PIXMAN_REPEAT_NONE &&
713 (x > extents->x1 || y > extents->y1 ||
714 x + image->bits.width < extents->x2 ||
715 y + image->bits.height < extents->y2))
717 (*flags) &= ~FAST_PATH_COVERS_CLIP;
721 /* Some compositing functions walk one step
722 * outside the destination rectangle, so we
723 * check here that the expanded-by-one source
724 * extents in destination space fits in 16 bits
726 if (!IS_16BIT (extents->x1 - x - 1) ||
727 !IS_16BIT (extents->y1 - y - 1) ||
728 !IS_16BIT (extents->x2 - x + 1) ||
729 !IS_16BIT (extents->y2 - y + 1))
734 if (image->common.type == BITS)
736 switch (image->common.filter)
738 case PIXMAN_FILTER_CONVOLUTION:
739 params = image->common.filter_params;
740 x_off = - pixman_fixed_e - ((params[0] - pixman_fixed_1) >> 1);
741 y_off = - pixman_fixed_e - ((params[1] - pixman_fixed_1) >> 1);
746 case PIXMAN_FILTER_GOOD:
747 case PIXMAN_FILTER_BEST:
748 case PIXMAN_FILTER_BILINEAR:
749 x_off = - pixman_fixed_1 / 2;
750 y_off = - pixman_fixed_1 / 2;
751 width = pixman_fixed_1;
752 height = pixman_fixed_1;
755 case PIXMAN_FILTER_FAST:
756 case PIXMAN_FILTER_NEAREST:
757 x_off = - pixman_fixed_e;
758 y_off = - pixman_fixed_e;
775 /* Check that the extents expanded by one don't overflow. This ensures that
776 * compositing functions can simply walk the source space using 16.16 variables
777 * without worrying about overflow.
779 ex.x1 = extents->x1 - 1;
780 ex.y1 = extents->y1 - 1;
781 ex.x2 = extents->x2 + 1;
782 ex.y2 = extents->y2 + 1;
784 if (!compute_sample_extents (transform, &ex, x, y, x_off, y_off, width, height))
787 if (image->type == BITS)
789 /* Check whether the non-expanded, transformed extent is entirely within
790 * the source image, and set the FAST_PATH_SAMPLES_COVER_CLIP if it is.
793 if (compute_sample_extents (transform, &ex, x, y, x_off, y_off, width, height))
795 if (ex.x1 >= 0 && ex.y1 >= 0 && ex.x2 <= image->bits.width && ex.y2 <= image->bits.height)
796 *flags |= FAST_PATH_SAMPLES_COVER_CLIP;
804 * Work around GCC bug causing crashes in Mozilla with SSE2
806 * When using -msse, gcc generates movdqa instructions assuming that
807 * the stack is 16 byte aligned. Unfortunately some applications, such
808 * as Mozilla and Mono, end up aligning the stack to 4 bytes, which
809 * causes the movdqa instructions to fail.
811 * The __force_align_arg_pointer__ makes gcc generate a prologue that
812 * realigns the stack pointer to 16 bytes.
814 * On x86-64 this is not necessary because the standard ABI already
815 * calls for a 16 byte aligned stack.
817 * See https://bugs.freedesktop.org/show_bug.cgi?id=15693
819 #if defined (USE_SSE2) && defined(__GNUC__) && !defined(__x86_64__) && !defined(__amd64__)
820 __attribute__((__force_align_arg_pointer__))
823 pixman_image_composite32 (pixman_op_t op,
824 pixman_image_t * src,
825 pixman_image_t * mask,
826 pixman_image_t * dest,
836 pixman_format_code_t src_format, mask_format, dest_format;
837 uint32_t src_flags, mask_flags, dest_flags;
838 pixman_region32_t region;
839 pixman_box32_t *extents;
843 int mask_dx, mask_dy;
845 int dest_dx, dest_dy;
846 pixman_bool_t need_workaround;
847 pixman_implementation_t *imp;
848 pixman_composite_func_t func;
850 _pixman_image_validate (src);
852 _pixman_image_validate (mask);
853 _pixman_image_validate (dest);
855 src_format = src->common.extended_format_code;
856 src_flags = src->common.flags;
860 mask_format = mask->common.extended_format_code;
861 mask_flags = mask->common.flags;
865 mask_format = PIXMAN_null;
866 mask_flags = FAST_PATH_IS_OPAQUE;
869 dest_format = dest->common.extended_format_code;
870 dest_flags = dest->common.flags;
872 /* Check for pixbufs */
873 if ((mask_format == PIXMAN_a8r8g8b8 || mask_format == PIXMAN_a8b8g8r8) &&
874 (src->type == BITS && src->bits.bits == mask->bits.bits) &&
875 (src->common.repeat == mask->common.repeat) &&
876 (src_x == mask_x && src_y == mask_y))
878 if (src_format == PIXMAN_x8b8g8r8)
879 src_format = mask_format = PIXMAN_pixbuf;
880 else if (src_format == PIXMAN_x8r8g8b8)
881 src_format = mask_format = PIXMAN_rpixbuf;
884 /* Check for workaround */
885 need_workaround = (src_flags | mask_flags | dest_flags) & FAST_PATH_NEEDS_WORKAROUND;
889 apply_workaround (src, &src_x, &src_y, &src_bits, &src_dx, &src_dy);
890 apply_workaround (mask, &mask_x, &mask_y, &mask_bits, &mask_dx, &mask_dy);
891 apply_workaround (dest, &dest_x, &dest_y, &dest_bits, &dest_dx, &dest_dy);
894 pixman_region32_init (®ion);
896 if (!pixman_compute_composite_region32 (
897 ®ion, src, mask, dest,
898 src_x, src_y, mask_x, mask_y, dest_x, dest_y, width, height))
903 extents = pixman_region32_extents (®ion);
905 if (!analyze_extent (src, dest_x - src_x, dest_y - src_y, extents, &src_flags))
908 if (!analyze_extent (mask, dest_x - mask_x, dest_y - mask_y, extents, &mask_flags))
911 /* If the clip is within the source samples, and the samples are opaque,
912 * then the source is effectively opaque.
914 #define BOTH (FAST_PATH_SAMPLES_OPAQUE | FAST_PATH_SAMPLES_COVER_CLIP)
916 if ((src_flags & BOTH) == BOTH)
917 src_flags |= FAST_PATH_IS_OPAQUE;
919 if ((mask_flags & BOTH) == BOTH)
920 mask_flags |= FAST_PATH_IS_OPAQUE;
923 * Check if we can replace our operator by a simpler one
924 * if the src or dest are opaque. The output operator should be
925 * mathematically equivalent to the source.
927 op = optimize_operator (op, src_flags, mask_flags, dest_flags);
928 if (op == PIXMAN_OP_DST)
931 if (lookup_composite_function (op,
932 src_format, src_flags,
933 mask_format, mask_flags,
934 dest_format, dest_flags,
937 walk_region_internal (imp, op,
939 src_x, src_y, mask_x, mask_y,
942 (src_flags & FAST_PATH_SIMPLE_REPEAT),
943 (mask_flags & FAST_PATH_SIMPLE_REPEAT),
950 unapply_workaround (src, src_bits, src_dx, src_dy);
951 unapply_workaround (mask, mask_bits, mask_dx, mask_dy);
952 unapply_workaround (dest, dest_bits, dest_dx, dest_dy);
955 pixman_region32_fini (®ion);
959 pixman_image_composite (pixman_op_t op,
960 pixman_image_t * src,
961 pixman_image_t * mask,
962 pixman_image_t * dest,
972 pixman_image_composite32 (op, src, mask, dest, src_x, src_y,
973 mask_x, mask_y, dest_x, dest_y, width, height);
976 PIXMAN_EXPORT pixman_bool_t
977 pixman_blt (uint32_t *src_bits,
990 return _pixman_implementation_blt (get_implementation(),
991 src_bits, dst_bits, src_stride, dst_stride,
998 PIXMAN_EXPORT pixman_bool_t
999 pixman_fill (uint32_t *bits,
1008 return _pixman_implementation_fill (
1009 get_implementation(), bits, stride, bpp, x, y, width, height, xor);
1013 color_to_uint32 (const pixman_color_t *color)
1016 (color->alpha >> 8 << 24) |
1017 (color->red >> 8 << 16) |
1018 (color->green & 0xff00) |
1022 static pixman_bool_t
1023 color_to_pixel (pixman_color_t * color,
1025 pixman_format_code_t format)
1027 uint32_t c = color_to_uint32 (color);
1029 if (!(format == PIXMAN_a8r8g8b8 ||
1030 format == PIXMAN_x8r8g8b8 ||
1031 format == PIXMAN_a8b8g8r8 ||
1032 format == PIXMAN_x8b8g8r8 ||
1033 format == PIXMAN_b8g8r8a8 ||
1034 format == PIXMAN_b8g8r8x8 ||
1035 format == PIXMAN_r5g6b5 ||
1036 format == PIXMAN_b5g6r5 ||
1037 format == PIXMAN_a8))
1042 if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_ABGR)
1044 c = ((c & 0xff000000) >> 0) |
1045 ((c & 0x00ff0000) >> 16) |
1046 ((c & 0x0000ff00) >> 0) |
1047 ((c & 0x000000ff) << 16);
1049 if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_BGRA)
1051 c = ((c & 0xff000000) >> 24) |
1052 ((c & 0x00ff0000) >> 8) |
1053 ((c & 0x0000ff00) << 8) |
1054 ((c & 0x000000ff) << 24);
1057 if (format == PIXMAN_a8)
1059 else if (format == PIXMAN_r5g6b5 ||
1060 format == PIXMAN_b5g6r5)
1061 c = CONVERT_8888_TO_0565 (c);
1064 printf ("color: %x %x %x %x\n", color->alpha, color->red, color->green, color->blue);
1065 printf ("pixel: %x\n", c);
1072 PIXMAN_EXPORT pixman_bool_t
1073 pixman_image_fill_rectangles (pixman_op_t op,
1074 pixman_image_t * dest,
1075 pixman_color_t * color,
1077 const pixman_rectangle16_t *rects)
1079 pixman_box32_t stack_boxes[6];
1080 pixman_box32_t *boxes;
1081 pixman_bool_t result;
1086 boxes = pixman_malloc_ab (sizeof (pixman_box32_t), n_rects);
1092 boxes = stack_boxes;
1095 for (i = 0; i < n_rects; ++i)
1097 boxes[i].x1 = rects[i].x;
1098 boxes[i].y1 = rects[i].y;
1099 boxes[i].x2 = boxes[i].x1 + rects[i].width;
1100 boxes[i].y2 = boxes[i].y1 + rects[i].height;
1103 result = pixman_image_fill_boxes (op, dest, color, n_rects, boxes);
1105 if (boxes != stack_boxes)
1111 PIXMAN_EXPORT pixman_bool_t
1112 pixman_image_fill_boxes (pixman_op_t op,
1113 pixman_image_t * dest,
1114 pixman_color_t * color,
1116 const pixman_box32_t *boxes)
1118 pixman_image_t *solid;
1122 _pixman_image_validate (dest);
1124 if (color->alpha == 0xffff)
1126 if (op == PIXMAN_OP_OVER)
1130 if (op == PIXMAN_OP_CLEAR)
1142 if (op == PIXMAN_OP_SRC)
1146 if (color_to_pixel (color, &pixel, dest->bits.format))
1148 pixman_region32_t fill_region;
1150 pixman_box32_t *rects;
1152 if (!pixman_region32_init_rects (&fill_region, boxes, n_boxes))
1155 if (dest->common.have_clip_region)
1157 if (!pixman_region32_intersect (&fill_region,
1159 &dest->common.clip_region))
1163 rects = pixman_region32_rectangles (&fill_region, &n_rects);
1164 for (j = 0; j < n_rects; ++j)
1166 const pixman_box32_t *rect = &(rects[j]);
1167 pixman_fill (dest->bits.bits, dest->bits.rowstride, PIXMAN_FORMAT_BPP (dest->bits.format),
1168 rect->x1, rect->y1, rect->x2 - rect->x1, rect->y2 - rect->y1,
1172 pixman_region32_fini (&fill_region);
1177 solid = pixman_image_create_solid_fill (color);
1181 for (i = 0; i < n_boxes; ++i)
1183 const pixman_box32_t *box = &(boxes[i]);
1185 pixman_image_composite32 (op, solid, NULL, dest,
1188 box->x2 - box->x1, box->y2 - box->y1);
1191 pixman_image_unref (solid);
1199 * Returns the version of the pixman library encoded in a single
1200 * integer as per %PIXMAN_VERSION_ENCODE. The encoding ensures that
1201 * later versions compare greater than earlier versions.
1203 * A run-time comparison to check that pixman's version is greater than
1204 * or equal to version X.Y.Z could be performed as follows:
1206 * <informalexample><programlisting>
1207 * if (pixman_version() >= PIXMAN_VERSION_ENCODE(X,Y,Z)) {...}
1208 * </programlisting></informalexample>
1210 * See also pixman_version_string() as well as the compile-time
1211 * equivalents %PIXMAN_VERSION and %PIXMAN_VERSION_STRING.
1213 * Return value: the encoded version.
1216 pixman_version (void)
1218 return PIXMAN_VERSION;
1222 * pixman_version_string:
1224 * Returns the version of the pixman library as a human-readable string
1225 * of the form "X.Y.Z".
1227 * See also pixman_version() as well as the compile-time equivalents
1228 * %PIXMAN_VERSION_STRING and %PIXMAN_VERSION.
1230 * Return value: a string containing the version.
1232 PIXMAN_EXPORT const char*
1233 pixman_version_string (void)
1235 return PIXMAN_VERSION_STRING;
1239 * pixman_format_supported_source:
1240 * @format: A pixman_format_code_t format
1242 * Return value: whether the provided format code is a supported
1243 * format for a pixman surface used as a source in
1246 * Currently, all pixman_format_code_t values are supported.
1248 PIXMAN_EXPORT pixman_bool_t
1249 pixman_format_supported_source (pixman_format_code_t format)
1253 /* 32 bpp formats */
1254 case PIXMAN_a2b10g10r10:
1255 case PIXMAN_x2b10g10r10:
1256 case PIXMAN_a2r10g10b10:
1257 case PIXMAN_x2r10g10b10:
1258 case PIXMAN_a8r8g8b8:
1259 case PIXMAN_x8r8g8b8:
1260 case PIXMAN_a8b8g8r8:
1261 case PIXMAN_x8b8g8r8:
1262 case PIXMAN_b8g8r8a8:
1263 case PIXMAN_b8g8r8x8:
1268 case PIXMAN_x14r6g6b6:
1269 /* 16 bpp formats */
1270 case PIXMAN_a1r5g5b5:
1271 case PIXMAN_x1r5g5b5:
1272 case PIXMAN_a1b5g5r5:
1273 case PIXMAN_x1b5g5r5:
1274 case PIXMAN_a4r4g4b4:
1275 case PIXMAN_x4r4g4b4:
1276 case PIXMAN_a4b4g4r4:
1277 case PIXMAN_x4b4g4r4:
1282 case PIXMAN_a2r2g2b2:
1283 case PIXMAN_a2b2g2r2:
1287 /* Collides with PIXMAN_c8
1290 /* Collides with PIXMAN_g8
1297 case PIXMAN_a1r1g1b1:
1298 case PIXMAN_a1b1g1r1:
1315 * pixman_format_supported_destination:
1316 * @format: A pixman_format_code_t format
1318 * Return value: whether the provided format code is a supported
1319 * format for a pixman surface used as a destination in
1322 * Currently, all pixman_format_code_t values are supported
1323 * except for the YUV formats.
1325 PIXMAN_EXPORT pixman_bool_t
1326 pixman_format_supported_destination (pixman_format_code_t format)
1328 /* YUV formats cannot be written to at the moment */
1329 if (format == PIXMAN_yuy2 || format == PIXMAN_yv12)
1332 return pixman_format_supported_source (format);
1335 PIXMAN_EXPORT pixman_bool_t
1336 pixman_compute_composite_region (pixman_region16_t * region,
1337 pixman_image_t * src_image,
1338 pixman_image_t * mask_image,
1339 pixman_image_t * dst_image,
1349 pixman_region32_t r32;
1350 pixman_bool_t retval;
1352 pixman_region32_init (&r32);
1354 retval = pixman_compute_composite_region32 (
1355 &r32, src_image, mask_image, dst_image,
1356 src_x, src_y, mask_x, mask_y, dest_x, dest_y,
1361 if (!pixman_region16_copy_from_region32 (region, &r32))
1365 pixman_region32_fini (&r32);