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)
320 if (!pixman_region32_intersect_rect (region, region,
321 dst_image->common.alpha_origin_x,
322 dst_image->common.alpha_origin_y,
323 dst_image->common.alpha_map->width,
324 dst_image->common.alpha_map->height))
328 if (!pixman_region32_not_empty (region))
330 if (dst_image->common.alpha_map->common.have_clip_region)
332 if (!clip_general_image (region, &dst_image->common.alpha_map->common.clip_region,
333 -dst_image->common.alpha_origin_x,
334 -dst_image->common.alpha_origin_y))
341 /* clip against src */
342 if (src_image->common.have_clip_region)
344 if (!clip_source_image (region, src_image, dest_x - src_x, dest_y - src_y))
347 if (src_image->common.alpha_map && src_image->common.alpha_map->common.have_clip_region)
349 if (!clip_source_image (region, (pixman_image_t *)src_image->common.alpha_map,
350 dest_x - (src_x - src_image->common.alpha_origin_x),
351 dest_y - (src_y - src_image->common.alpha_origin_y)))
356 /* clip against mask */
357 if (mask_image && mask_image->common.have_clip_region)
359 if (!clip_source_image (region, mask_image, dest_x - mask_x, dest_y - mask_y))
362 if (mask_image->common.alpha_map && mask_image->common.alpha_map->common.have_clip_region)
364 if (!clip_source_image (region, (pixman_image_t *)mask_image->common.alpha_map,
365 dest_x - (mask_x - mask_image->common.alpha_origin_x),
366 dest_y - (mask_y - mask_image->common.alpha_origin_y)))
377 walk_region_internal (pixman_implementation_t *imp,
379 pixman_image_t * src_image,
380 pixman_image_t * mask_image,
381 pixman_image_t * dst_image,
390 pixman_bool_t src_repeat,
391 pixman_bool_t mask_repeat,
392 pixman_region32_t * region,
393 pixman_composite_func_t composite_rect)
395 int w, h, w_this, h_this;
396 int x_msk, y_msk, x_src, y_src, x_dst, y_dst;
397 int src_dy = src_y - dest_y;
398 int src_dx = src_x - dest_x;
399 int mask_dy = mask_y - dest_y;
400 int mask_dx = mask_x - dest_x;
401 const pixman_box32_t *pbox;
404 pbox = pixman_region32_rectangles (region, &n);
406 /* Fast path for non-repeating sources */
407 if (!src_repeat && !mask_repeat)
411 (*composite_rect) (imp, op,
412 src_image, mask_image, dst_image,
420 pbox->y2 - pbox->y1);
430 h = pbox->y2 - pbox->y1;
431 y_src = pbox->y1 + src_dy;
432 y_msk = pbox->y1 + mask_dy;
438 w = pbox->x2 - pbox->x1;
439 x_src = pbox->x1 + src_dx;
440 x_msk = pbox->x1 + mask_dx;
445 y_msk = MOD (y_msk, mask_image->bits.height);
446 if (h_this > mask_image->bits.height - y_msk)
447 h_this = mask_image->bits.height - y_msk;
452 y_src = MOD (y_src, src_image->bits.height);
453 if (h_this > src_image->bits.height - y_src)
454 h_this = src_image->bits.height - y_src;
463 x_msk = MOD (x_msk, mask_image->bits.width);
464 if (w_this > mask_image->bits.width - x_msk)
465 w_this = mask_image->bits.width - x_msk;
470 x_src = MOD (x_src, src_image->bits.width);
471 if (w_this > src_image->bits.width - x_src)
472 w_this = src_image->bits.width - x_src;
475 (*composite_rect) (imp, op,
476 src_image, mask_image, dst_image,
477 x_src, y_src, x_msk, y_msk, x_dst, y_dst,
496 #define N_CACHED_FAST_PATHS 8
502 pixman_implementation_t * imp;
503 pixman_fast_path_t fast_path;
504 } cache [N_CACHED_FAST_PATHS];
507 PIXMAN_DEFINE_THREAD_LOCAL (cache_t, fast_path_cache);
509 static force_inline pixman_bool_t
510 lookup_composite_function (pixman_op_t op,
511 pixman_format_code_t src_format,
513 pixman_format_code_t mask_format,
515 pixman_format_code_t dest_format,
517 pixman_implementation_t **out_imp,
518 pixman_composite_func_t *out_func)
520 pixman_implementation_t *imp;
524 /* Check cache for fast paths */
525 cache = PIXMAN_GET_THREAD_LOCAL (fast_path_cache);
527 for (i = 0; i < N_CACHED_FAST_PATHS; ++i)
529 const pixman_fast_path_t *info = &(cache->cache[i].fast_path);
531 /* Note that we check for equality here, not whether
532 * the cached fast path matches. This is to prevent
533 * us from selecting an overly general fast path
534 * when a more specific one would work.
536 if (info->op == op &&
537 info->src_format == src_format &&
538 info->mask_format == mask_format &&
539 info->dest_format == dest_format &&
540 info->src_flags == src_flags &&
541 info->mask_flags == mask_flags &&
542 info->dest_flags == dest_flags &&
545 *out_imp = cache->cache[i].imp;
546 *out_func = cache->cache[i].fast_path.func;
552 for (imp = get_implementation (); imp != NULL; imp = imp->delegate)
554 const pixman_fast_path_t *info = imp->fast_paths;
556 while (info->op != PIXMAN_OP_NONE)
558 if ((info->op == op || info->op == PIXMAN_OP_any) &&
560 ((info->src_format == src_format) ||
561 (info->src_format == PIXMAN_any)) &&
562 ((info->mask_format == mask_format) ||
563 (info->mask_format == PIXMAN_any)) &&
564 ((info->dest_format == dest_format) ||
565 (info->dest_format == PIXMAN_any)) &&
567 (info->src_flags & src_flags) == info->src_flags &&
568 (info->mask_flags & mask_flags) == info->mask_flags &&
569 (info->dest_flags & dest_flags) == info->dest_flags)
572 *out_func = info->func;
574 /* Set i to the last spot in the cache so that the
575 * move-to-front code below will work
577 i = N_CACHED_FAST_PATHS - 1;
591 cache->cache[i + 1] = cache->cache[i];
593 cache->cache[0].imp = *out_imp;
594 cache->cache[0].fast_path.op = op;
595 cache->cache[0].fast_path.src_format = src_format;
596 cache->cache[0].fast_path.src_flags = src_flags;
597 cache->cache[0].fast_path.mask_format = mask_format;
598 cache->cache[0].fast_path.mask_flags = mask_flags;
599 cache->cache[0].fast_path.dest_format = dest_format;
600 cache->cache[0].fast_path.dest_flags = dest_flags;
601 cache->cache[0].fast_path.func = *out_func;
608 compute_sample_extents (pixman_transform_t *transform,
609 pixman_box32_t *extents, int x, int y,
610 pixman_fixed_t x_off, pixman_fixed_t y_off,
611 pixman_fixed_t width, pixman_fixed_t height)
613 pixman_fixed_t x1, y1, x2, y2;
614 pixman_fixed_48_16_t tx1, ty1, tx2, ty2;
616 /* We have checked earlier that (extents->x1 - x) etc. fit in a pixman_fixed_t */
617 x1 = (pixman_fixed_48_16_t)pixman_int_to_fixed (extents->x1 - x) + pixman_fixed_1 / 2;
618 y1 = (pixman_fixed_48_16_t)pixman_int_to_fixed (extents->y1 - y) + pixman_fixed_1 / 2;
619 x2 = (pixman_fixed_48_16_t)pixman_int_to_fixed (extents->x2 - x) - pixman_fixed_1 / 2;
620 y2 = (pixman_fixed_48_16_t)pixman_int_to_fixed (extents->y2 - y) - pixman_fixed_1 / 2;
624 tx1 = (pixman_fixed_48_16_t)x1;
625 ty1 = (pixman_fixed_48_16_t)y1;
626 tx2 = (pixman_fixed_48_16_t)x2;
627 ty2 = (pixman_fixed_48_16_t)y2;
634 tx1 = ty1 = tx2 = ty2 = 0;
636 for (i = 0; i < 4; ++i)
638 pixman_fixed_48_16_t tx, ty;
641 v.vector[0] = (i & 0x01)? x1 : x2;
642 v.vector[1] = (i & 0x02)? y1 : y2;
643 v.vector[2] = pixman_fixed_1;
645 if (!pixman_transform_point (transform, &v))
648 tx = (pixman_fixed_48_16_t)v.vector[0];
649 ty = (pixman_fixed_48_16_t)v.vector[1];
672 /* Expand the source area by a tiny bit so account of different rounding that
673 * may happen during sampling. Note that (8 * pixman_fixed_e) is very far from
674 * 0.5 so this won't cause the area computed to be overly pessimistic.
676 tx1 += x_off - 8 * pixman_fixed_e;
677 ty1 += y_off - 8 * pixman_fixed_e;
678 tx2 += x_off + width + 8 * pixman_fixed_e;
679 ty2 += y_off + height + 8 * pixman_fixed_e;
681 if (tx1 < pixman_min_fixed_48_16 || tx1 > pixman_max_fixed_48_16 ||
682 ty1 < pixman_min_fixed_48_16 || ty1 > pixman_max_fixed_48_16 ||
683 tx2 < pixman_min_fixed_48_16 || tx2 > pixman_max_fixed_48_16 ||
684 ty2 < pixman_min_fixed_48_16 || ty2 > pixman_max_fixed_48_16)
690 extents->x1 = pixman_fixed_to_int (tx1);
691 extents->y1 = pixman_fixed_to_int (ty1);
692 extents->x2 = pixman_fixed_to_int (tx2) + 1;
693 extents->y2 = pixman_fixed_to_int (ty2) + 1;
699 #define IS_16BIT(x) (((x) >= INT16_MIN) && ((x) <= INT16_MAX))
702 analyze_extent (pixman_image_t *image, int x, int y,
703 const pixman_box32_t *extents, uint32_t *flags)
705 pixman_transform_t *transform;
706 pixman_fixed_t *params;
707 pixman_fixed_t x_off, y_off;
708 pixman_fixed_t width, height;
714 /* Some compositing functions walk one step
715 * outside the destination rectangle, so we
716 * check here that the expanded-by-one source
717 * extents in destination space fits in 16 bits
719 if (!IS_16BIT (extents->x1 - x - 1) ||
720 !IS_16BIT (extents->y1 - y - 1) ||
721 !IS_16BIT (extents->x2 - x + 1) ||
722 !IS_16BIT (extents->y2 - y + 1))
727 if (image->common.type == BITS)
729 /* During repeat mode calculations we might convert the
730 * width/height of an image to fixed 16.16, so we need
731 * them to be smaller than 16 bits.
733 if (image->bits.width >= 0x7fff || image->bits.height >= 0x7fff)
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
777 * variables 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 transform = image->common.transform;
786 if (!compute_sample_extents (transform, &ex, x, y, x_off, y_off, width, height))
789 if (image->type == BITS)
791 /* Check whether the non-expanded, transformed extent is entirely within
792 * the source image, and set the FAST_PATH_SAMPLES_COVER_CLIP if it is.
795 if (compute_sample_extents (transform, &ex, x, y, x_off, y_off, width, height))
797 if (ex.x1 >= 0 && ex.y1 >= 0 && ex.x2 <= image->bits.width && ex.y2 <= image->bits.height)
798 *flags |= (FAST_PATH_SAMPLES_COVER_CLIP | FAST_PATH_COVERS_CLIP);
806 * Work around GCC bug causing crashes in Mozilla with SSE2
808 * When using -msse, gcc generates movdqa instructions assuming that
809 * the stack is 16 byte aligned. Unfortunately some applications, such
810 * as Mozilla and Mono, end up aligning the stack to 4 bytes, which
811 * causes the movdqa instructions to fail.
813 * The __force_align_arg_pointer__ makes gcc generate a prologue that
814 * realigns the stack pointer to 16 bytes.
816 * On x86-64 this is not necessary because the standard ABI already
817 * calls for a 16 byte aligned stack.
819 * See https://bugs.freedesktop.org/show_bug.cgi?id=15693
821 #if defined (USE_SSE2) && defined(__GNUC__) && !defined(__x86_64__) && !defined(__amd64__)
822 __attribute__((__force_align_arg_pointer__))
825 pixman_image_composite32 (pixman_op_t op,
826 pixman_image_t * src,
827 pixman_image_t * mask,
828 pixman_image_t * dest,
838 pixman_format_code_t src_format, mask_format, dest_format;
839 uint32_t src_flags, mask_flags, dest_flags;
840 pixman_region32_t region;
841 pixman_box32_t *extents;
845 int mask_dx, mask_dy;
847 int dest_dx, dest_dy;
848 pixman_bool_t need_workaround;
849 pixman_implementation_t *imp;
850 pixman_composite_func_t func;
852 _pixman_image_validate (src);
854 _pixman_image_validate (mask);
855 _pixman_image_validate (dest);
857 src_format = src->common.extended_format_code;
858 src_flags = src->common.flags;
862 mask_format = mask->common.extended_format_code;
863 mask_flags = mask->common.flags;
867 mask_format = PIXMAN_null;
868 mask_flags = FAST_PATH_IS_OPAQUE;
871 dest_format = dest->common.extended_format_code;
872 dest_flags = dest->common.flags;
874 /* Check for pixbufs */
875 if ((mask_format == PIXMAN_a8r8g8b8 || mask_format == PIXMAN_a8b8g8r8) &&
876 (src->type == BITS && src->bits.bits == mask->bits.bits) &&
877 (src->common.repeat == mask->common.repeat) &&
878 (src_x == mask_x && src_y == mask_y))
880 if (src_format == PIXMAN_x8b8g8r8)
881 src_format = mask_format = PIXMAN_pixbuf;
882 else if (src_format == PIXMAN_x8r8g8b8)
883 src_format = mask_format = PIXMAN_rpixbuf;
886 /* Check for workaround */
887 need_workaround = (src_flags | mask_flags | dest_flags) & FAST_PATH_NEEDS_WORKAROUND;
891 apply_workaround (src, &src_x, &src_y, &src_bits, &src_dx, &src_dy);
892 apply_workaround (mask, &mask_x, &mask_y, &mask_bits, &mask_dx, &mask_dy);
893 apply_workaround (dest, &dest_x, &dest_y, &dest_bits, &dest_dx, &dest_dy);
896 pixman_region32_init (®ion);
898 if (!pixman_compute_composite_region32 (
899 ®ion, src, mask, dest,
900 src_x, src_y, mask_x, mask_y, dest_x, dest_y, width, height))
905 extents = pixman_region32_extents (®ion);
907 if (!analyze_extent (src, dest_x - src_x, dest_y - src_y, extents, &src_flags))
910 if (!analyze_extent (mask, dest_x - mask_x, dest_y - mask_y, extents, &mask_flags))
913 /* If the clip is within the source samples, and the samples are opaque,
914 * then the source is effectively opaque.
916 #define BOTH (FAST_PATH_SAMPLES_OPAQUE | FAST_PATH_SAMPLES_COVER_CLIP)
918 if ((src_flags & BOTH) == BOTH)
919 src_flags |= FAST_PATH_IS_OPAQUE;
921 if ((mask_flags & BOTH) == BOTH)
922 mask_flags |= FAST_PATH_IS_OPAQUE;
925 * Check if we can replace our operator by a simpler one
926 * if the src or dest are opaque. The output operator should be
927 * mathematically equivalent to the source.
929 op = optimize_operator (op, src_flags, mask_flags, dest_flags);
930 if (op == PIXMAN_OP_DST)
933 if (lookup_composite_function (op,
934 src_format, src_flags,
935 mask_format, mask_flags,
936 dest_format, dest_flags,
939 walk_region_internal (imp, op,
941 src_x, src_y, mask_x, mask_y,
944 (src_flags & FAST_PATH_SIMPLE_REPEAT),
945 (mask_flags & FAST_PATH_SIMPLE_REPEAT),
952 unapply_workaround (src, src_bits, src_dx, src_dy);
953 unapply_workaround (mask, mask_bits, mask_dx, mask_dy);
954 unapply_workaround (dest, dest_bits, dest_dx, dest_dy);
957 pixman_region32_fini (®ion);
961 pixman_image_composite (pixman_op_t op,
962 pixman_image_t * src,
963 pixman_image_t * mask,
964 pixman_image_t * dest,
974 pixman_image_composite32 (op, src, mask, dest, src_x, src_y,
975 mask_x, mask_y, dest_x, dest_y, width, height);
978 PIXMAN_EXPORT pixman_bool_t
979 pixman_blt (uint32_t *src_bits,
992 return _pixman_implementation_blt (get_implementation(),
993 src_bits, dst_bits, src_stride, dst_stride,
1000 PIXMAN_EXPORT pixman_bool_t
1001 pixman_fill (uint32_t *bits,
1010 return _pixman_implementation_fill (
1011 get_implementation(), bits, stride, bpp, x, y, width, height, xor);
1015 color_to_uint32 (const pixman_color_t *color)
1018 (color->alpha >> 8 << 24) |
1019 (color->red >> 8 << 16) |
1020 (color->green & 0xff00) |
1024 static pixman_bool_t
1025 color_to_pixel (pixman_color_t * color,
1027 pixman_format_code_t format)
1029 uint32_t c = color_to_uint32 (color);
1031 if (!(format == PIXMAN_a8r8g8b8 ||
1032 format == PIXMAN_x8r8g8b8 ||
1033 format == PIXMAN_a8b8g8r8 ||
1034 format == PIXMAN_x8b8g8r8 ||
1035 format == PIXMAN_b8g8r8a8 ||
1036 format == PIXMAN_b8g8r8x8 ||
1037 format == PIXMAN_r5g6b5 ||
1038 format == PIXMAN_b5g6r5 ||
1039 format == PIXMAN_a8))
1044 if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_ABGR)
1046 c = ((c & 0xff000000) >> 0) |
1047 ((c & 0x00ff0000) >> 16) |
1048 ((c & 0x0000ff00) >> 0) |
1049 ((c & 0x000000ff) << 16);
1051 if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_BGRA)
1053 c = ((c & 0xff000000) >> 24) |
1054 ((c & 0x00ff0000) >> 8) |
1055 ((c & 0x0000ff00) << 8) |
1056 ((c & 0x000000ff) << 24);
1059 if (format == PIXMAN_a8)
1061 else if (format == PIXMAN_r5g6b5 ||
1062 format == PIXMAN_b5g6r5)
1063 c = CONVERT_8888_TO_0565 (c);
1066 printf ("color: %x %x %x %x\n", color->alpha, color->red, color->green, color->blue);
1067 printf ("pixel: %x\n", c);
1074 PIXMAN_EXPORT pixman_bool_t
1075 pixman_image_fill_rectangles (pixman_op_t op,
1076 pixman_image_t * dest,
1077 pixman_color_t * color,
1079 const pixman_rectangle16_t *rects)
1081 pixman_box32_t stack_boxes[6];
1082 pixman_box32_t *boxes;
1083 pixman_bool_t result;
1088 boxes = pixman_malloc_ab (sizeof (pixman_box32_t), n_rects);
1094 boxes = stack_boxes;
1097 for (i = 0; i < n_rects; ++i)
1099 boxes[i].x1 = rects[i].x;
1100 boxes[i].y1 = rects[i].y;
1101 boxes[i].x2 = boxes[i].x1 + rects[i].width;
1102 boxes[i].y2 = boxes[i].y1 + rects[i].height;
1105 result = pixman_image_fill_boxes (op, dest, color, n_rects, boxes);
1107 if (boxes != stack_boxes)
1113 PIXMAN_EXPORT pixman_bool_t
1114 pixman_image_fill_boxes (pixman_op_t op,
1115 pixman_image_t * dest,
1116 pixman_color_t * color,
1118 const pixman_box32_t *boxes)
1120 pixman_image_t *solid;
1124 _pixman_image_validate (dest);
1126 if (color->alpha == 0xffff)
1128 if (op == PIXMAN_OP_OVER)
1132 if (op == PIXMAN_OP_CLEAR)
1144 if (op == PIXMAN_OP_SRC)
1148 if (color_to_pixel (color, &pixel, dest->bits.format))
1150 pixman_region32_t fill_region;
1152 pixman_box32_t *rects;
1154 if (!pixman_region32_init_rects (&fill_region, boxes, n_boxes))
1157 if (dest->common.have_clip_region)
1159 if (!pixman_region32_intersect (&fill_region,
1161 &dest->common.clip_region))
1165 rects = pixman_region32_rectangles (&fill_region, &n_rects);
1166 for (j = 0; j < n_rects; ++j)
1168 const pixman_box32_t *rect = &(rects[j]);
1169 pixman_fill (dest->bits.bits, dest->bits.rowstride, PIXMAN_FORMAT_BPP (dest->bits.format),
1170 rect->x1, rect->y1, rect->x2 - rect->x1, rect->y2 - rect->y1,
1174 pixman_region32_fini (&fill_region);
1179 solid = pixman_image_create_solid_fill (color);
1183 for (i = 0; i < n_boxes; ++i)
1185 const pixman_box32_t *box = &(boxes[i]);
1187 pixman_image_composite32 (op, solid, NULL, dest,
1190 box->x2 - box->x1, box->y2 - box->y1);
1193 pixman_image_unref (solid);
1201 * Returns the version of the pixman library encoded in a single
1202 * integer as per %PIXMAN_VERSION_ENCODE. The encoding ensures that
1203 * later versions compare greater than earlier versions.
1205 * A run-time comparison to check that pixman's version is greater than
1206 * or equal to version X.Y.Z could be performed as follows:
1208 * <informalexample><programlisting>
1209 * if (pixman_version() >= PIXMAN_VERSION_ENCODE(X,Y,Z)) {...}
1210 * </programlisting></informalexample>
1212 * See also pixman_version_string() as well as the compile-time
1213 * equivalents %PIXMAN_VERSION and %PIXMAN_VERSION_STRING.
1215 * Return value: the encoded version.
1218 pixman_version (void)
1220 return PIXMAN_VERSION;
1224 * pixman_version_string:
1226 * Returns the version of the pixman library as a human-readable string
1227 * of the form "X.Y.Z".
1229 * See also pixman_version() as well as the compile-time equivalents
1230 * %PIXMAN_VERSION_STRING and %PIXMAN_VERSION.
1232 * Return value: a string containing the version.
1234 PIXMAN_EXPORT const char*
1235 pixman_version_string (void)
1237 return PIXMAN_VERSION_STRING;
1241 * pixman_format_supported_source:
1242 * @format: A pixman_format_code_t format
1244 * Return value: whether the provided format code is a supported
1245 * format for a pixman surface used as a source in
1248 * Currently, all pixman_format_code_t values are supported.
1250 PIXMAN_EXPORT pixman_bool_t
1251 pixman_format_supported_source (pixman_format_code_t format)
1255 /* 32 bpp formats */
1256 case PIXMAN_a2b10g10r10:
1257 case PIXMAN_x2b10g10r10:
1258 case PIXMAN_a2r10g10b10:
1259 case PIXMAN_x2r10g10b10:
1260 case PIXMAN_a8r8g8b8:
1261 case PIXMAN_x8r8g8b8:
1262 case PIXMAN_a8b8g8r8:
1263 case PIXMAN_x8b8g8r8:
1264 case PIXMAN_b8g8r8a8:
1265 case PIXMAN_b8g8r8x8:
1270 case PIXMAN_x14r6g6b6:
1271 /* 16 bpp formats */
1272 case PIXMAN_a1r5g5b5:
1273 case PIXMAN_x1r5g5b5:
1274 case PIXMAN_a1b5g5r5:
1275 case PIXMAN_x1b5g5r5:
1276 case PIXMAN_a4r4g4b4:
1277 case PIXMAN_x4r4g4b4:
1278 case PIXMAN_a4b4g4r4:
1279 case PIXMAN_x4b4g4r4:
1284 case PIXMAN_a2r2g2b2:
1285 case PIXMAN_a2b2g2r2:
1289 /* Collides with PIXMAN_c8
1292 /* Collides with PIXMAN_g8
1299 case PIXMAN_a1r1g1b1:
1300 case PIXMAN_a1b1g1r1:
1317 * pixman_format_supported_destination:
1318 * @format: A pixman_format_code_t format
1320 * Return value: whether the provided format code is a supported
1321 * format for a pixman surface used as a destination in
1324 * Currently, all pixman_format_code_t values are supported
1325 * except for the YUV formats.
1327 PIXMAN_EXPORT pixman_bool_t
1328 pixman_format_supported_destination (pixman_format_code_t format)
1330 /* YUV formats cannot be written to at the moment */
1331 if (format == PIXMAN_yuy2 || format == PIXMAN_yv12)
1334 return pixman_format_supported_source (format);
1337 PIXMAN_EXPORT pixman_bool_t
1338 pixman_compute_composite_region (pixman_region16_t * region,
1339 pixman_image_t * src_image,
1340 pixman_image_t * mask_image,
1341 pixman_image_t * dst_image,
1351 pixman_region32_t r32;
1352 pixman_bool_t retval;
1354 pixman_region32_init (&r32);
1356 retval = pixman_compute_composite_region32 (
1357 &r32, src_image, mask_image, dst_image,
1358 src_x, src_y, mask_x, mask_y, dest_x, dest_y,
1363 if (!pixman_region16_copy_from_region32 (region, &r32))
1367 pixman_region32_fini (&r32);