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)
309 region->extents.x1 = 0;
310 region->extents.x2 = 0;
311 region->extents.y1 = 0;
312 region->extents.y2 = 0;
316 if (dst_image->common.have_clip_region)
318 if (!clip_general_image (region, &dst_image->common.clip_region, 0, 0))
322 if (dst_image->common.alpha_map)
324 if (!pixman_region32_intersect_rect (region, region,
325 dst_image->common.alpha_origin_x,
326 dst_image->common.alpha_origin_y,
327 dst_image->common.alpha_map->width,
328 dst_image->common.alpha_map->height))
332 if (!pixman_region32_not_empty (region))
334 if (dst_image->common.alpha_map->common.have_clip_region)
336 if (!clip_general_image (region, &dst_image->common.alpha_map->common.clip_region,
337 -dst_image->common.alpha_origin_x,
338 -dst_image->common.alpha_origin_y))
345 /* clip against src */
346 if (src_image->common.have_clip_region)
348 if (!clip_source_image (region, src_image, dest_x - src_x, dest_y - src_y))
351 if (src_image->common.alpha_map && src_image->common.alpha_map->common.have_clip_region)
353 if (!clip_source_image (region, (pixman_image_t *)src_image->common.alpha_map,
354 dest_x - (src_x - src_image->common.alpha_origin_x),
355 dest_y - (src_y - src_image->common.alpha_origin_y)))
360 /* clip against mask */
361 if (mask_image && mask_image->common.have_clip_region)
363 if (!clip_source_image (region, mask_image, dest_x - mask_x, dest_y - mask_y))
366 if (mask_image->common.alpha_map && mask_image->common.alpha_map->common.have_clip_region)
368 if (!clip_source_image (region, (pixman_image_t *)mask_image->common.alpha_map,
369 dest_x - (mask_x - mask_image->common.alpha_origin_x),
370 dest_y - (mask_y - mask_image->common.alpha_origin_y)))
381 walk_region_internal (pixman_implementation_t *imp,
383 pixman_image_t * src_image,
384 pixman_image_t * mask_image,
385 pixman_image_t * dst_image,
394 pixman_bool_t src_repeat,
395 pixman_bool_t mask_repeat,
396 pixman_region32_t * region,
397 pixman_composite_func_t composite_rect)
399 int w, h, w_this, h_this;
400 int x_msk, y_msk, x_src, y_src, x_dst, y_dst;
401 int src_dy = src_y - dest_y;
402 int src_dx = src_x - dest_x;
403 int mask_dy = mask_y - dest_y;
404 int mask_dx = mask_x - dest_x;
405 const pixman_box32_t *pbox;
408 pbox = pixman_region32_rectangles (region, &n);
410 /* Fast path for non-repeating sources */
411 if (!src_repeat && !mask_repeat)
415 (*composite_rect) (imp, op,
416 src_image, mask_image, dst_image,
424 pbox->y2 - pbox->y1);
434 h = pbox->y2 - pbox->y1;
435 y_src = pbox->y1 + src_dy;
436 y_msk = pbox->y1 + mask_dy;
442 w = pbox->x2 - pbox->x1;
443 x_src = pbox->x1 + src_dx;
444 x_msk = pbox->x1 + mask_dx;
449 y_msk = MOD (y_msk, mask_image->bits.height);
450 if (h_this > mask_image->bits.height - y_msk)
451 h_this = mask_image->bits.height - y_msk;
456 y_src = MOD (y_src, src_image->bits.height);
457 if (h_this > src_image->bits.height - y_src)
458 h_this = src_image->bits.height - y_src;
467 x_msk = MOD (x_msk, mask_image->bits.width);
468 if (w_this > mask_image->bits.width - x_msk)
469 w_this = mask_image->bits.width - x_msk;
474 x_src = MOD (x_src, src_image->bits.width);
475 if (w_this > src_image->bits.width - x_src)
476 w_this = src_image->bits.width - x_src;
479 (*composite_rect) (imp, op,
480 src_image, mask_image, dst_image,
481 x_src, y_src, x_msk, y_msk, x_dst, y_dst,
500 #define N_CACHED_FAST_PATHS 8
506 pixman_implementation_t * imp;
507 pixman_fast_path_t fast_path;
508 } cache [N_CACHED_FAST_PATHS];
511 PIXMAN_DEFINE_THREAD_LOCAL (cache_t, fast_path_cache);
513 static force_inline pixman_bool_t
514 lookup_composite_function (pixman_op_t op,
515 pixman_format_code_t src_format,
517 pixman_format_code_t mask_format,
519 pixman_format_code_t dest_format,
521 pixman_implementation_t **out_imp,
522 pixman_composite_func_t *out_func)
524 pixman_implementation_t *imp;
528 /* Check cache for fast paths */
529 cache = PIXMAN_GET_THREAD_LOCAL (fast_path_cache);
531 for (i = 0; i < N_CACHED_FAST_PATHS; ++i)
533 const pixman_fast_path_t *info = &(cache->cache[i].fast_path);
535 /* Note that we check for equality here, not whether
536 * the cached fast path matches. This is to prevent
537 * us from selecting an overly general fast path
538 * when a more specific one would work.
540 if (info->op == op &&
541 info->src_format == src_format &&
542 info->mask_format == mask_format &&
543 info->dest_format == dest_format &&
544 info->src_flags == src_flags &&
545 info->mask_flags == mask_flags &&
546 info->dest_flags == dest_flags &&
549 *out_imp = cache->cache[i].imp;
550 *out_func = cache->cache[i].fast_path.func;
556 for (imp = get_implementation (); imp != NULL; imp = imp->delegate)
558 const pixman_fast_path_t *info = imp->fast_paths;
560 while (info->op != PIXMAN_OP_NONE)
562 if ((info->op == op || info->op == PIXMAN_OP_any) &&
564 ((info->src_format == src_format) ||
565 (info->src_format == PIXMAN_any)) &&
566 ((info->mask_format == mask_format) ||
567 (info->mask_format == PIXMAN_any)) &&
568 ((info->dest_format == dest_format) ||
569 (info->dest_format == PIXMAN_any)) &&
571 (info->src_flags & src_flags) == info->src_flags &&
572 (info->mask_flags & mask_flags) == info->mask_flags &&
573 (info->dest_flags & dest_flags) == info->dest_flags)
576 *out_func = info->func;
578 /* Set i to the last spot in the cache so that the
579 * move-to-front code below will work
581 i = N_CACHED_FAST_PATHS - 1;
595 cache->cache[i + 1] = cache->cache[i];
597 cache->cache[0].imp = *out_imp;
598 cache->cache[0].fast_path.op = op;
599 cache->cache[0].fast_path.src_format = src_format;
600 cache->cache[0].fast_path.src_flags = src_flags;
601 cache->cache[0].fast_path.mask_format = mask_format;
602 cache->cache[0].fast_path.mask_flags = mask_flags;
603 cache->cache[0].fast_path.dest_format = dest_format;
604 cache->cache[0].fast_path.dest_flags = dest_flags;
605 cache->cache[0].fast_path.func = *out_func;
612 compute_sample_extents (pixman_transform_t *transform,
613 pixman_box32_t *extents, int x, int y,
614 pixman_fixed_t x_off, pixman_fixed_t y_off,
615 pixman_fixed_t width, pixman_fixed_t height)
617 pixman_fixed_t x1, y1, x2, y2;
618 pixman_fixed_48_16_t tx1, ty1, tx2, ty2;
620 /* We have checked earlier that (extents->x1 - x) etc. fit in a pixman_fixed_t */
621 x1 = (pixman_fixed_48_16_t)pixman_int_to_fixed (extents->x1 - x) + pixman_fixed_1 / 2;
622 y1 = (pixman_fixed_48_16_t)pixman_int_to_fixed (extents->y1 - y) + pixman_fixed_1 / 2;
623 x2 = (pixman_fixed_48_16_t)pixman_int_to_fixed (extents->x2 - x) - pixman_fixed_1 / 2;
624 y2 = (pixman_fixed_48_16_t)pixman_int_to_fixed (extents->y2 - y) - pixman_fixed_1 / 2;
628 tx1 = (pixman_fixed_48_16_t)x1;
629 ty1 = (pixman_fixed_48_16_t)y1;
630 tx2 = (pixman_fixed_48_16_t)x2;
631 ty2 = (pixman_fixed_48_16_t)y2;
638 tx1 = ty1 = tx2 = ty2 = 0;
640 for (i = 0; i < 4; ++i)
642 pixman_fixed_48_16_t tx, ty;
645 v.vector[0] = (i & 0x01)? x1 : x2;
646 v.vector[1] = (i & 0x02)? y1 : y2;
647 v.vector[2] = pixman_fixed_1;
649 if (!pixman_transform_point (transform, &v))
652 tx = (pixman_fixed_48_16_t)v.vector[0];
653 ty = (pixman_fixed_48_16_t)v.vector[1];
676 /* Expand the source area by a tiny bit so account of different rounding that
677 * may happen during sampling. Note that (8 * pixman_fixed_e) is very far from
678 * 0.5 so this won't cause the area computed to be overly pessimistic.
680 tx1 += x_off - 8 * pixman_fixed_e;
681 ty1 += y_off - 8 * pixman_fixed_e;
682 tx2 += x_off + width + 8 * pixman_fixed_e;
683 ty2 += y_off + height + 8 * pixman_fixed_e;
685 if (tx1 < pixman_min_fixed_48_16 || tx1 > pixman_max_fixed_48_16 ||
686 ty1 < pixman_min_fixed_48_16 || ty1 > pixman_max_fixed_48_16 ||
687 tx2 < pixman_min_fixed_48_16 || tx2 > pixman_max_fixed_48_16 ||
688 ty2 < pixman_min_fixed_48_16 || ty2 > pixman_max_fixed_48_16)
694 extents->x1 = pixman_fixed_to_int (tx1);
695 extents->y1 = pixman_fixed_to_int (ty1);
696 extents->x2 = pixman_fixed_to_int (tx2) + 1;
697 extents->y2 = pixman_fixed_to_int (ty2) + 1;
703 #define IS_16BIT(x) (((x) >= INT16_MIN) && ((x) <= INT16_MAX))
706 analyze_extent (pixman_image_t *image, int x, int y,
707 const pixman_box32_t *extents, uint32_t *flags)
709 pixman_transform_t *transform;
710 pixman_fixed_t *params;
711 pixman_fixed_t x_off, y_off;
712 pixman_fixed_t width, height;
718 /* Some compositing functions walk one step
719 * outside the destination rectangle, so we
720 * check here that the expanded-by-one source
721 * extents in destination space fits in 16 bits
723 if (!IS_16BIT (extents->x1 - x - 1) ||
724 !IS_16BIT (extents->y1 - y - 1) ||
725 !IS_16BIT (extents->x2 - x + 1) ||
726 !IS_16BIT (extents->y2 - y + 1))
731 transform = image->common.transform;
732 if (image->common.type == BITS)
734 /* During repeat mode calculations we might convert the
735 * width/height of an image to fixed 16.16, so we need
736 * them to be smaller than 16 bits.
738 if (image->bits.width >= 0x7fff || image->bits.height >= 0x7fff)
741 #define ID_AND_NEAREST (FAST_PATH_ID_TRANSFORM | FAST_PATH_NEAREST_FILTER)
743 if ((image->common.flags & ID_AND_NEAREST) == ID_AND_NEAREST &&
744 extents->x1 - x >= 0 &&
745 extents->y1 - y >= 0 &&
746 extents->x2 - x <= image->bits.width &&
747 extents->y2 - y <= image->bits.height)
749 *flags |= FAST_PATH_SAMPLES_COVER_CLIP;
753 switch (image->common.filter)
755 case PIXMAN_FILTER_CONVOLUTION:
756 params = image->common.filter_params;
757 x_off = - pixman_fixed_e - ((params[0] - pixman_fixed_1) >> 1);
758 y_off = - pixman_fixed_e - ((params[1] - pixman_fixed_1) >> 1);
763 case PIXMAN_FILTER_GOOD:
764 case PIXMAN_FILTER_BEST:
765 case PIXMAN_FILTER_BILINEAR:
766 x_off = - pixman_fixed_1 / 2;
767 y_off = - pixman_fixed_1 / 2;
768 width = pixman_fixed_1;
769 height = pixman_fixed_1;
772 case PIXMAN_FILTER_FAST:
773 case PIXMAN_FILTER_NEAREST:
774 x_off = - pixman_fixed_e;
775 y_off = - pixman_fixed_e;
784 /* Check whether the non-expanded, transformed extent is entirely within
785 * the source image, and set the FAST_PATH_SAMPLES_COVER_CLIP if it is.
788 if (compute_sample_extents (transform, &ex, x, y, x_off, y_off, width, height) &&
789 ex.x1 >= 0 && ex.y1 >= 0 &&
790 ex.x2 <= image->bits.width && ex.y2 <= image->bits.height)
792 *flags |= FAST_PATH_SAMPLES_COVER_CLIP;
803 /* Check that the extents expanded by one don't overflow. This ensures that
804 * compositing functions can simply walk the source space using 16.16
805 * variables without worrying about overflow.
807 ex.x1 = extents->x1 - 1;
808 ex.y1 = extents->y1 - 1;
809 ex.x2 = extents->x2 + 1;
810 ex.y2 = extents->y2 + 1;
812 if (!compute_sample_extents (transform, &ex, x, y, x_off, y_off, width, height))
819 * Work around GCC bug causing crashes in Mozilla with SSE2
821 * When using -msse, gcc generates movdqa instructions assuming that
822 * the stack is 16 byte aligned. Unfortunately some applications, such
823 * as Mozilla and Mono, end up aligning the stack to 4 bytes, which
824 * causes the movdqa instructions to fail.
826 * The __force_align_arg_pointer__ makes gcc generate a prologue that
827 * realigns the stack pointer to 16 bytes.
829 * On x86-64 this is not necessary because the standard ABI already
830 * calls for a 16 byte aligned stack.
832 * See https://bugs.freedesktop.org/show_bug.cgi?id=15693
834 #if defined (USE_SSE2) && defined(__GNUC__) && !defined(__x86_64__) && !defined(__amd64__)
835 __attribute__((__force_align_arg_pointer__))
838 pixman_image_composite32 (pixman_op_t op,
839 pixman_image_t * src,
840 pixman_image_t * mask,
841 pixman_image_t * dest,
851 pixman_format_code_t src_format, mask_format, dest_format;
852 uint32_t src_flags, mask_flags, dest_flags;
853 pixman_region32_t region;
854 pixman_box32_t *extents;
858 int mask_dx, mask_dy;
860 int dest_dx, dest_dy;
861 pixman_bool_t need_workaround;
862 pixman_implementation_t *imp;
863 pixman_composite_func_t func;
865 _pixman_image_validate (src);
867 _pixman_image_validate (mask);
868 _pixman_image_validate (dest);
870 src_format = src->common.extended_format_code;
871 src_flags = src->common.flags;
875 mask_format = mask->common.extended_format_code;
876 mask_flags = mask->common.flags;
880 mask_format = PIXMAN_null;
881 mask_flags = FAST_PATH_IS_OPAQUE;
884 dest_format = dest->common.extended_format_code;
885 dest_flags = dest->common.flags;
887 /* Check for pixbufs */
888 if ((mask_format == PIXMAN_a8r8g8b8 || mask_format == PIXMAN_a8b8g8r8) &&
889 (src->type == BITS && src->bits.bits == mask->bits.bits) &&
890 (src->common.repeat == mask->common.repeat) &&
891 (src_x == mask_x && src_y == mask_y))
893 if (src_format == PIXMAN_x8b8g8r8)
894 src_format = mask_format = PIXMAN_pixbuf;
895 else if (src_format == PIXMAN_x8r8g8b8)
896 src_format = mask_format = PIXMAN_rpixbuf;
899 /* Check for workaround */
900 need_workaround = (src_flags | mask_flags | dest_flags) & FAST_PATH_NEEDS_WORKAROUND;
904 apply_workaround (src, &src_x, &src_y, &src_bits, &src_dx, &src_dy);
905 apply_workaround (mask, &mask_x, &mask_y, &mask_bits, &mask_dx, &mask_dy);
906 apply_workaround (dest, &dest_x, &dest_y, &dest_bits, &dest_dx, &dest_dy);
909 pixman_region32_init (®ion);
911 if (!pixman_compute_composite_region32 (
912 ®ion, src, mask, dest,
913 src_x, src_y, mask_x, mask_y, dest_x, dest_y, width, height))
918 extents = pixman_region32_extents (®ion);
920 if (!analyze_extent (src, dest_x - src_x, dest_y - src_y, extents, &src_flags))
923 if (!analyze_extent (mask, dest_x - mask_x, dest_y - mask_y, extents, &mask_flags))
926 /* If the clip is within the source samples, and the samples are opaque,
927 * then the source is effectively opaque.
929 #define BOTH (FAST_PATH_SAMPLES_OPAQUE | FAST_PATH_SAMPLES_COVER_CLIP)
931 if ((src_flags & BOTH) == BOTH)
932 src_flags |= FAST_PATH_IS_OPAQUE;
934 if ((mask_flags & BOTH) == BOTH)
935 mask_flags |= FAST_PATH_IS_OPAQUE;
938 * Check if we can replace our operator by a simpler one
939 * if the src or dest are opaque. The output operator should be
940 * mathematically equivalent to the source.
942 op = optimize_operator (op, src_flags, mask_flags, dest_flags);
943 if (op == PIXMAN_OP_DST)
946 if (lookup_composite_function (op,
947 src_format, src_flags,
948 mask_format, mask_flags,
949 dest_format, dest_flags,
952 walk_region_internal (imp, op,
954 src_x, src_y, mask_x, mask_y,
957 (src_flags & FAST_PATH_SIMPLE_REPEAT),
958 (mask_flags & FAST_PATH_SIMPLE_REPEAT),
965 unapply_workaround (src, src_bits, src_dx, src_dy);
966 unapply_workaround (mask, mask_bits, mask_dx, mask_dy);
967 unapply_workaround (dest, dest_bits, dest_dx, dest_dy);
970 pixman_region32_fini (®ion);
974 pixman_image_composite (pixman_op_t op,
975 pixman_image_t * src,
976 pixman_image_t * mask,
977 pixman_image_t * dest,
987 pixman_image_composite32 (op, src, mask, dest, src_x, src_y,
988 mask_x, mask_y, dest_x, dest_y, width, height);
991 PIXMAN_EXPORT pixman_bool_t
992 pixman_blt (uint32_t *src_bits,
1005 return _pixman_implementation_blt (get_implementation(),
1006 src_bits, dst_bits, src_stride, dst_stride,
1013 PIXMAN_EXPORT pixman_bool_t
1014 pixman_fill (uint32_t *bits,
1023 return _pixman_implementation_fill (
1024 get_implementation(), bits, stride, bpp, x, y, width, height, xor);
1028 color_to_uint32 (const pixman_color_t *color)
1031 (color->alpha >> 8 << 24) |
1032 (color->red >> 8 << 16) |
1033 (color->green & 0xff00) |
1037 static pixman_bool_t
1038 color_to_pixel (pixman_color_t * color,
1040 pixman_format_code_t format)
1042 uint32_t c = color_to_uint32 (color);
1044 if (!(format == PIXMAN_a8r8g8b8 ||
1045 format == PIXMAN_x8r8g8b8 ||
1046 format == PIXMAN_a8b8g8r8 ||
1047 format == PIXMAN_x8b8g8r8 ||
1048 format == PIXMAN_b8g8r8a8 ||
1049 format == PIXMAN_b8g8r8x8 ||
1050 format == PIXMAN_r5g6b5 ||
1051 format == PIXMAN_b5g6r5 ||
1052 format == PIXMAN_a8))
1057 if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_ABGR)
1059 c = ((c & 0xff000000) >> 0) |
1060 ((c & 0x00ff0000) >> 16) |
1061 ((c & 0x0000ff00) >> 0) |
1062 ((c & 0x000000ff) << 16);
1064 if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_BGRA)
1066 c = ((c & 0xff000000) >> 24) |
1067 ((c & 0x00ff0000) >> 8) |
1068 ((c & 0x0000ff00) << 8) |
1069 ((c & 0x000000ff) << 24);
1072 if (format == PIXMAN_a8)
1074 else if (format == PIXMAN_r5g6b5 ||
1075 format == PIXMAN_b5g6r5)
1076 c = CONVERT_8888_TO_0565 (c);
1079 printf ("color: %x %x %x %x\n", color->alpha, color->red, color->green, color->blue);
1080 printf ("pixel: %x\n", c);
1087 PIXMAN_EXPORT pixman_bool_t
1088 pixman_image_fill_rectangles (pixman_op_t op,
1089 pixman_image_t * dest,
1090 pixman_color_t * color,
1092 const pixman_rectangle16_t *rects)
1094 pixman_box32_t stack_boxes[6];
1095 pixman_box32_t *boxes;
1096 pixman_bool_t result;
1101 boxes = pixman_malloc_ab (sizeof (pixman_box32_t), n_rects);
1107 boxes = stack_boxes;
1110 for (i = 0; i < n_rects; ++i)
1112 boxes[i].x1 = rects[i].x;
1113 boxes[i].y1 = rects[i].y;
1114 boxes[i].x2 = boxes[i].x1 + rects[i].width;
1115 boxes[i].y2 = boxes[i].y1 + rects[i].height;
1118 result = pixman_image_fill_boxes (op, dest, color, n_rects, boxes);
1120 if (boxes != stack_boxes)
1126 PIXMAN_EXPORT pixman_bool_t
1127 pixman_image_fill_boxes (pixman_op_t op,
1128 pixman_image_t * dest,
1129 pixman_color_t * color,
1131 const pixman_box32_t *boxes)
1133 pixman_image_t *solid;
1137 _pixman_image_validate (dest);
1139 if (color->alpha == 0xffff)
1141 if (op == PIXMAN_OP_OVER)
1145 if (op == PIXMAN_OP_CLEAR)
1157 if (op == PIXMAN_OP_SRC)
1161 if (color_to_pixel (color, &pixel, dest->bits.format))
1163 pixman_region32_t fill_region;
1165 pixman_box32_t *rects;
1167 if (!pixman_region32_init_rects (&fill_region, boxes, n_boxes))
1170 if (dest->common.have_clip_region)
1172 if (!pixman_region32_intersect (&fill_region,
1174 &dest->common.clip_region))
1178 rects = pixman_region32_rectangles (&fill_region, &n_rects);
1179 for (j = 0; j < n_rects; ++j)
1181 const pixman_box32_t *rect = &(rects[j]);
1182 pixman_fill (dest->bits.bits, dest->bits.rowstride, PIXMAN_FORMAT_BPP (dest->bits.format),
1183 rect->x1, rect->y1, rect->x2 - rect->x1, rect->y2 - rect->y1,
1187 pixman_region32_fini (&fill_region);
1192 solid = pixman_image_create_solid_fill (color);
1196 for (i = 0; i < n_boxes; ++i)
1198 const pixman_box32_t *box = &(boxes[i]);
1200 pixman_image_composite32 (op, solid, NULL, dest,
1203 box->x2 - box->x1, box->y2 - box->y1);
1206 pixman_image_unref (solid);
1214 * Returns the version of the pixman library encoded in a single
1215 * integer as per %PIXMAN_VERSION_ENCODE. The encoding ensures that
1216 * later versions compare greater than earlier versions.
1218 * A run-time comparison to check that pixman's version is greater than
1219 * or equal to version X.Y.Z could be performed as follows:
1221 * <informalexample><programlisting>
1222 * if (pixman_version() >= PIXMAN_VERSION_ENCODE(X,Y,Z)) {...}
1223 * </programlisting></informalexample>
1225 * See also pixman_version_string() as well as the compile-time
1226 * equivalents %PIXMAN_VERSION and %PIXMAN_VERSION_STRING.
1228 * Return value: the encoded version.
1231 pixman_version (void)
1233 return PIXMAN_VERSION;
1237 * pixman_version_string:
1239 * Returns the version of the pixman library as a human-readable string
1240 * of the form "X.Y.Z".
1242 * See also pixman_version() as well as the compile-time equivalents
1243 * %PIXMAN_VERSION_STRING and %PIXMAN_VERSION.
1245 * Return value: a string containing the version.
1247 PIXMAN_EXPORT const char*
1248 pixman_version_string (void)
1250 return PIXMAN_VERSION_STRING;
1254 * pixman_format_supported_source:
1255 * @format: A pixman_format_code_t format
1257 * Return value: whether the provided format code is a supported
1258 * format for a pixman surface used as a source in
1261 * Currently, all pixman_format_code_t values are supported.
1263 PIXMAN_EXPORT pixman_bool_t
1264 pixman_format_supported_source (pixman_format_code_t format)
1268 /* 32 bpp formats */
1269 case PIXMAN_a2b10g10r10:
1270 case PIXMAN_x2b10g10r10:
1271 case PIXMAN_a2r10g10b10:
1272 case PIXMAN_x2r10g10b10:
1273 case PIXMAN_a8r8g8b8:
1274 case PIXMAN_x8r8g8b8:
1275 case PIXMAN_a8b8g8r8:
1276 case PIXMAN_x8b8g8r8:
1277 case PIXMAN_b8g8r8a8:
1278 case PIXMAN_b8g8r8x8:
1283 case PIXMAN_x14r6g6b6:
1284 /* 16 bpp formats */
1285 case PIXMAN_a1r5g5b5:
1286 case PIXMAN_x1r5g5b5:
1287 case PIXMAN_a1b5g5r5:
1288 case PIXMAN_x1b5g5r5:
1289 case PIXMAN_a4r4g4b4:
1290 case PIXMAN_x4r4g4b4:
1291 case PIXMAN_a4b4g4r4:
1292 case PIXMAN_x4b4g4r4:
1297 case PIXMAN_a2r2g2b2:
1298 case PIXMAN_a2b2g2r2:
1302 /* Collides with PIXMAN_c8
1305 /* Collides with PIXMAN_g8
1312 case PIXMAN_a1r1g1b1:
1313 case PIXMAN_a1b1g1r1:
1330 * pixman_format_supported_destination:
1331 * @format: A pixman_format_code_t format
1333 * Return value: whether the provided format code is a supported
1334 * format for a pixman surface used as a destination in
1337 * Currently, all pixman_format_code_t values are supported
1338 * except for the YUV formats.
1340 PIXMAN_EXPORT pixman_bool_t
1341 pixman_format_supported_destination (pixman_format_code_t format)
1343 /* YUV formats cannot be written to at the moment */
1344 if (format == PIXMAN_yuy2 || format == PIXMAN_yv12)
1347 return pixman_format_supported_source (format);
1350 PIXMAN_EXPORT pixman_bool_t
1351 pixman_compute_composite_region (pixman_region16_t * region,
1352 pixman_image_t * src_image,
1353 pixman_image_t * mask_image,
1354 pixman_image_t * dst_image,
1364 pixman_region32_t r32;
1365 pixman_bool_t retval;
1367 pixman_region32_init (&r32);
1369 retval = pixman_compute_composite_region32 (
1370 &r32, src_image, mask_image, dst_image,
1371 src_x, src_y, mask_x, mask_y, dest_x, dest_y,
1376 if (!pixman_region16_copy_from_region32 (region, &r32))
1380 pixman_region32_fini (&r32);