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;
711 *flags |= FAST_PATH_COVERS_CLIP;
715 transform = image->common.transform;
716 if (image->common.type == BITS)
718 /* During repeat mode calculations we might convert the
719 * width/height of an image to fixed 16.16, so we need
720 * them to be smaller than 16 bits.
722 if (image->bits.width >= 0x7fff || image->bits.height >= 0x7fff)
725 if (image->common.repeat == PIXMAN_REPEAT_NONE &&
726 (x > extents->x1 || y > extents->y1 ||
727 x + image->bits.width < extents->x2 ||
728 y + image->bits.height < extents->y2))
730 (*flags) &= ~FAST_PATH_COVERS_CLIP;
734 /* Some compositing functions walk one step
735 * outside the destination rectangle, so we
736 * check here that the expanded-by-one source
737 * extents in destination space fits in 16 bits
739 if (!IS_16BIT (extents->x1 - x - 1) ||
740 !IS_16BIT (extents->y1 - y - 1) ||
741 !IS_16BIT (extents->x2 - x + 1) ||
742 !IS_16BIT (extents->y2 - y + 1))
747 if (image->common.type == BITS)
749 switch (image->common.filter)
751 case PIXMAN_FILTER_CONVOLUTION:
752 params = image->common.filter_params;
753 x_off = - pixman_fixed_e - ((params[0] - pixman_fixed_1) >> 1);
754 y_off = - pixman_fixed_e - ((params[1] - pixman_fixed_1) >> 1);
759 case PIXMAN_FILTER_GOOD:
760 case PIXMAN_FILTER_BEST:
761 case PIXMAN_FILTER_BILINEAR:
762 x_off = - pixman_fixed_1 / 2;
763 y_off = - pixman_fixed_1 / 2;
764 width = pixman_fixed_1;
765 height = pixman_fixed_1;
768 case PIXMAN_FILTER_FAST:
769 case PIXMAN_FILTER_NEAREST:
770 x_off = - pixman_fixed_e;
771 y_off = - pixman_fixed_e;
788 /* Check that the extents expanded by one don't overflow. This ensures that
789 * compositing functions can simply walk the source space using 16.16 variables
790 * without worrying about overflow.
792 ex.x1 = extents->x1 - 1;
793 ex.y1 = extents->y1 - 1;
794 ex.x2 = extents->x2 + 1;
795 ex.y2 = extents->y2 + 1;
797 if (!compute_sample_extents (transform, &ex, x, y, x_off, y_off, width, height))
800 if (image->type == BITS)
802 /* Check whether the non-expanded, transformed extent is entirely within
803 * the source image, and set the FAST_PATH_SAMPLES_COVER_CLIP if it is.
806 if (compute_sample_extents (transform, &ex, x, y, x_off, y_off, width, height))
808 if (ex.x1 >= 0 && ex.y1 >= 0 && ex.x2 <= image->bits.width && ex.y2 <= image->bits.height)
809 *flags |= FAST_PATH_SAMPLES_COVER_CLIP;
817 * Work around GCC bug causing crashes in Mozilla with SSE2
819 * When using -msse, gcc generates movdqa instructions assuming that
820 * the stack is 16 byte aligned. Unfortunately some applications, such
821 * as Mozilla and Mono, end up aligning the stack to 4 bytes, which
822 * causes the movdqa instructions to fail.
824 * The __force_align_arg_pointer__ makes gcc generate a prologue that
825 * realigns the stack pointer to 16 bytes.
827 * On x86-64 this is not necessary because the standard ABI already
828 * calls for a 16 byte aligned stack.
830 * See https://bugs.freedesktop.org/show_bug.cgi?id=15693
832 #if defined (USE_SSE2) && defined(__GNUC__) && !defined(__x86_64__) && !defined(__amd64__)
833 __attribute__((__force_align_arg_pointer__))
836 pixman_image_composite32 (pixman_op_t op,
837 pixman_image_t * src,
838 pixman_image_t * mask,
839 pixman_image_t * dest,
849 pixman_format_code_t src_format, mask_format, dest_format;
850 uint32_t src_flags, mask_flags, dest_flags;
851 pixman_region32_t region;
852 pixman_box32_t *extents;
856 int mask_dx, mask_dy;
858 int dest_dx, dest_dy;
859 pixman_bool_t need_workaround;
860 pixman_implementation_t *imp;
861 pixman_composite_func_t func;
863 _pixman_image_validate (src);
865 _pixman_image_validate (mask);
866 _pixman_image_validate (dest);
868 src_format = src->common.extended_format_code;
869 src_flags = src->common.flags;
873 mask_format = mask->common.extended_format_code;
874 mask_flags = mask->common.flags;
878 mask_format = PIXMAN_null;
879 mask_flags = FAST_PATH_IS_OPAQUE;
882 dest_format = dest->common.extended_format_code;
883 dest_flags = dest->common.flags;
885 /* Check for pixbufs */
886 if ((mask_format == PIXMAN_a8r8g8b8 || mask_format == PIXMAN_a8b8g8r8) &&
887 (src->type == BITS && src->bits.bits == mask->bits.bits) &&
888 (src->common.repeat == mask->common.repeat) &&
889 (src_x == mask_x && src_y == mask_y))
891 if (src_format == PIXMAN_x8b8g8r8)
892 src_format = mask_format = PIXMAN_pixbuf;
893 else if (src_format == PIXMAN_x8r8g8b8)
894 src_format = mask_format = PIXMAN_rpixbuf;
897 /* Check for workaround */
898 need_workaround = (src_flags | mask_flags | dest_flags) & FAST_PATH_NEEDS_WORKAROUND;
902 apply_workaround (src, &src_x, &src_y, &src_bits, &src_dx, &src_dy);
903 apply_workaround (mask, &mask_x, &mask_y, &mask_bits, &mask_dx, &mask_dy);
904 apply_workaround (dest, &dest_x, &dest_y, &dest_bits, &dest_dx, &dest_dy);
907 pixman_region32_init (®ion);
909 if (!pixman_compute_composite_region32 (
910 ®ion, src, mask, dest,
911 src_x, src_y, mask_x, mask_y, dest_x, dest_y, width, height))
916 extents = pixman_region32_extents (®ion);
918 if (!analyze_extent (src, dest_x - src_x, dest_y - src_y, extents, &src_flags))
921 if (!analyze_extent (mask, dest_x - mask_x, dest_y - mask_y, extents, &mask_flags))
924 /* If the clip is within the source samples, and the samples are opaque,
925 * then the source is effectively opaque.
927 #define BOTH (FAST_PATH_SAMPLES_OPAQUE | FAST_PATH_SAMPLES_COVER_CLIP)
929 if ((src_flags & BOTH) == BOTH)
930 src_flags |= FAST_PATH_IS_OPAQUE;
932 if ((mask_flags & BOTH) == BOTH)
933 mask_flags |= FAST_PATH_IS_OPAQUE;
936 * Check if we can replace our operator by a simpler one
937 * if the src or dest are opaque. The output operator should be
938 * mathematically equivalent to the source.
940 op = optimize_operator (op, src_flags, mask_flags, dest_flags);
941 if (op == PIXMAN_OP_DST)
944 if (lookup_composite_function (op,
945 src_format, src_flags,
946 mask_format, mask_flags,
947 dest_format, dest_flags,
950 walk_region_internal (imp, op,
952 src_x, src_y, mask_x, mask_y,
955 (src_flags & FAST_PATH_SIMPLE_REPEAT),
956 (mask_flags & FAST_PATH_SIMPLE_REPEAT),
963 unapply_workaround (src, src_bits, src_dx, src_dy);
964 unapply_workaround (mask, mask_bits, mask_dx, mask_dy);
965 unapply_workaround (dest, dest_bits, dest_dx, dest_dy);
968 pixman_region32_fini (®ion);
972 pixman_image_composite (pixman_op_t op,
973 pixman_image_t * src,
974 pixman_image_t * mask,
975 pixman_image_t * dest,
985 pixman_image_composite32 (op, src, mask, dest, src_x, src_y,
986 mask_x, mask_y, dest_x, dest_y, width, height);
989 PIXMAN_EXPORT pixman_bool_t
990 pixman_blt (uint32_t *src_bits,
1003 return _pixman_implementation_blt (get_implementation(),
1004 src_bits, dst_bits, src_stride, dst_stride,
1011 PIXMAN_EXPORT pixman_bool_t
1012 pixman_fill (uint32_t *bits,
1021 return _pixman_implementation_fill (
1022 get_implementation(), bits, stride, bpp, x, y, width, height, xor);
1026 color_to_uint32 (const pixman_color_t *color)
1029 (color->alpha >> 8 << 24) |
1030 (color->red >> 8 << 16) |
1031 (color->green & 0xff00) |
1035 static pixman_bool_t
1036 color_to_pixel (pixman_color_t * color,
1038 pixman_format_code_t format)
1040 uint32_t c = color_to_uint32 (color);
1042 if (!(format == PIXMAN_a8r8g8b8 ||
1043 format == PIXMAN_x8r8g8b8 ||
1044 format == PIXMAN_a8b8g8r8 ||
1045 format == PIXMAN_x8b8g8r8 ||
1046 format == PIXMAN_b8g8r8a8 ||
1047 format == PIXMAN_b8g8r8x8 ||
1048 format == PIXMAN_r5g6b5 ||
1049 format == PIXMAN_b5g6r5 ||
1050 format == PIXMAN_a8))
1055 if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_ABGR)
1057 c = ((c & 0xff000000) >> 0) |
1058 ((c & 0x00ff0000) >> 16) |
1059 ((c & 0x0000ff00) >> 0) |
1060 ((c & 0x000000ff) << 16);
1062 if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_BGRA)
1064 c = ((c & 0xff000000) >> 24) |
1065 ((c & 0x00ff0000) >> 8) |
1066 ((c & 0x0000ff00) << 8) |
1067 ((c & 0x000000ff) << 24);
1070 if (format == PIXMAN_a8)
1072 else if (format == PIXMAN_r5g6b5 ||
1073 format == PIXMAN_b5g6r5)
1074 c = CONVERT_8888_TO_0565 (c);
1077 printf ("color: %x %x %x %x\n", color->alpha, color->red, color->green, color->blue);
1078 printf ("pixel: %x\n", c);
1085 PIXMAN_EXPORT pixman_bool_t
1086 pixman_image_fill_rectangles (pixman_op_t op,
1087 pixman_image_t * dest,
1088 pixman_color_t * color,
1090 const pixman_rectangle16_t *rects)
1092 pixman_box32_t stack_boxes[6];
1093 pixman_box32_t *boxes;
1094 pixman_bool_t result;
1099 boxes = pixman_malloc_ab (sizeof (pixman_box32_t), n_rects);
1105 boxes = stack_boxes;
1108 for (i = 0; i < n_rects; ++i)
1110 boxes[i].x1 = rects[i].x;
1111 boxes[i].y1 = rects[i].y;
1112 boxes[i].x2 = boxes[i].x1 + rects[i].width;
1113 boxes[i].y2 = boxes[i].y1 + rects[i].height;
1116 result = pixman_image_fill_boxes (op, dest, color, n_rects, boxes);
1118 if (boxes != stack_boxes)
1124 PIXMAN_EXPORT pixman_bool_t
1125 pixman_image_fill_boxes (pixman_op_t op,
1126 pixman_image_t * dest,
1127 pixman_color_t * color,
1129 const pixman_box32_t *boxes)
1131 pixman_image_t *solid;
1135 _pixman_image_validate (dest);
1137 if (color->alpha == 0xffff)
1139 if (op == PIXMAN_OP_OVER)
1143 if (op == PIXMAN_OP_CLEAR)
1155 if (op == PIXMAN_OP_SRC)
1159 if (color_to_pixel (color, &pixel, dest->bits.format))
1161 pixman_region32_t fill_region;
1163 pixman_box32_t *rects;
1165 if (!pixman_region32_init_rects (&fill_region, boxes, n_boxes))
1168 if (dest->common.have_clip_region)
1170 if (!pixman_region32_intersect (&fill_region,
1172 &dest->common.clip_region))
1176 rects = pixman_region32_rectangles (&fill_region, &n_rects);
1177 for (j = 0; j < n_rects; ++j)
1179 const pixman_box32_t *rect = &(rects[j]);
1180 pixman_fill (dest->bits.bits, dest->bits.rowstride, PIXMAN_FORMAT_BPP (dest->bits.format),
1181 rect->x1, rect->y1, rect->x2 - rect->x1, rect->y2 - rect->y1,
1185 pixman_region32_fini (&fill_region);
1190 solid = pixman_image_create_solid_fill (color);
1194 for (i = 0; i < n_boxes; ++i)
1196 const pixman_box32_t *box = &(boxes[i]);
1198 pixman_image_composite32 (op, solid, NULL, dest,
1201 box->x2 - box->x1, box->y2 - box->y1);
1204 pixman_image_unref (solid);
1212 * Returns the version of the pixman library encoded in a single
1213 * integer as per %PIXMAN_VERSION_ENCODE. The encoding ensures that
1214 * later versions compare greater than earlier versions.
1216 * A run-time comparison to check that pixman's version is greater than
1217 * or equal to version X.Y.Z could be performed as follows:
1219 * <informalexample><programlisting>
1220 * if (pixman_version() >= PIXMAN_VERSION_ENCODE(X,Y,Z)) {...}
1221 * </programlisting></informalexample>
1223 * See also pixman_version_string() as well as the compile-time
1224 * equivalents %PIXMAN_VERSION and %PIXMAN_VERSION_STRING.
1226 * Return value: the encoded version.
1229 pixman_version (void)
1231 return PIXMAN_VERSION;
1235 * pixman_version_string:
1237 * Returns the version of the pixman library as a human-readable string
1238 * of the form "X.Y.Z".
1240 * See also pixman_version() as well as the compile-time equivalents
1241 * %PIXMAN_VERSION_STRING and %PIXMAN_VERSION.
1243 * Return value: a string containing the version.
1245 PIXMAN_EXPORT const char*
1246 pixman_version_string (void)
1248 return PIXMAN_VERSION_STRING;
1252 * pixman_format_supported_source:
1253 * @format: A pixman_format_code_t format
1255 * Return value: whether the provided format code is a supported
1256 * format for a pixman surface used as a source in
1259 * Currently, all pixman_format_code_t values are supported.
1261 PIXMAN_EXPORT pixman_bool_t
1262 pixman_format_supported_source (pixman_format_code_t format)
1266 /* 32 bpp formats */
1267 case PIXMAN_a2b10g10r10:
1268 case PIXMAN_x2b10g10r10:
1269 case PIXMAN_a2r10g10b10:
1270 case PIXMAN_x2r10g10b10:
1271 case PIXMAN_a8r8g8b8:
1272 case PIXMAN_x8r8g8b8:
1273 case PIXMAN_a8b8g8r8:
1274 case PIXMAN_x8b8g8r8:
1275 case PIXMAN_b8g8r8a8:
1276 case PIXMAN_b8g8r8x8:
1281 case PIXMAN_x14r6g6b6:
1282 /* 16 bpp formats */
1283 case PIXMAN_a1r5g5b5:
1284 case PIXMAN_x1r5g5b5:
1285 case PIXMAN_a1b5g5r5:
1286 case PIXMAN_x1b5g5r5:
1287 case PIXMAN_a4r4g4b4:
1288 case PIXMAN_x4r4g4b4:
1289 case PIXMAN_a4b4g4r4:
1290 case PIXMAN_x4b4g4r4:
1295 case PIXMAN_a2r2g2b2:
1296 case PIXMAN_a2b2g2r2:
1300 /* Collides with PIXMAN_c8
1303 /* Collides with PIXMAN_g8
1310 case PIXMAN_a1r1g1b1:
1311 case PIXMAN_a1b1g1r1:
1328 * pixman_format_supported_destination:
1329 * @format: A pixman_format_code_t format
1331 * Return value: whether the provided format code is a supported
1332 * format for a pixman surface used as a destination in
1335 * Currently, all pixman_format_code_t values are supported
1336 * except for the YUV formats.
1338 PIXMAN_EXPORT pixman_bool_t
1339 pixman_format_supported_destination (pixman_format_code_t format)
1341 /* YUV formats cannot be written to at the moment */
1342 if (format == PIXMAN_yuy2 || format == PIXMAN_yv12)
1345 return pixman_format_supported_source (format);
1348 PIXMAN_EXPORT pixman_bool_t
1349 pixman_compute_composite_region (pixman_region16_t * region,
1350 pixman_image_t * src_image,
1351 pixman_image_t * mask_image,
1352 pixman_image_t * dst_image,
1362 pixman_region32_t r32;
1363 pixman_bool_t retval;
1365 pixman_region32_init (&r32);
1367 retval = pixman_compute_composite_region32 (
1368 &r32, src_image, mask_image, dst_image,
1369 src_x, src_y, mask_x, mask_y, dest_x, dest_y,
1374 if (!pixman_region16_copy_from_region32 (region, &r32))
1378 pixman_region32_fini (&r32);