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 transform = image->common.transform;
728 if (image->common.type == BITS)
730 /* During repeat mode calculations we might convert the
731 * width/height of an image to fixed 16.16, so we need
732 * them to be smaller than 16 bits.
734 if (image->bits.width >= 0x7fff || image->bits.height >= 0x7fff)
737 #define ID_AND_NEAREST (FAST_PATH_ID_TRANSFORM | FAST_PATH_NEAREST_FILTER)
739 if ((image->common.flags & ID_AND_NEAREST) == ID_AND_NEAREST &&
740 extents->x1 - x >= 0 &&
741 extents->y1 - y >= 0 &&
742 extents->x2 - x <= image->bits.width &&
743 extents->y2 - y <= image->bits.height)
745 *flags |= (FAST_PATH_SAMPLES_COVER_CLIP | FAST_PATH_COVERS_CLIP);
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;
780 /* Check whether the non-expanded, transformed extent is entirely within
781 * the source image, and set the FAST_PATH_SAMPLES_COVER_CLIP if it is.
784 if (compute_sample_extents (transform, &ex, x, y, x_off, y_off, width, height) &&
785 ex.x1 >= 0 && ex.y1 >= 0 &&
786 ex.x2 <= image->bits.width && ex.y2 <= image->bits.height)
788 *flags |= (FAST_PATH_SAMPLES_COVER_CLIP | FAST_PATH_COVERS_CLIP);
799 /* Check that the extents expanded by one don't overflow. This ensures that
800 * compositing functions can simply walk the source space using 16.16
801 * variables without worrying about overflow.
803 ex.x1 = extents->x1 - 1;
804 ex.y1 = extents->y1 - 1;
805 ex.x2 = extents->x2 + 1;
806 ex.y2 = extents->y2 + 1;
808 if (!compute_sample_extents (transform, &ex, x, y, x_off, y_off, width, height))
815 * Work around GCC bug causing crashes in Mozilla with SSE2
817 * When using -msse, gcc generates movdqa instructions assuming that
818 * the stack is 16 byte aligned. Unfortunately some applications, such
819 * as Mozilla and Mono, end up aligning the stack to 4 bytes, which
820 * causes the movdqa instructions to fail.
822 * The __force_align_arg_pointer__ makes gcc generate a prologue that
823 * realigns the stack pointer to 16 bytes.
825 * On x86-64 this is not necessary because the standard ABI already
826 * calls for a 16 byte aligned stack.
828 * See https://bugs.freedesktop.org/show_bug.cgi?id=15693
830 #if defined (USE_SSE2) && defined(__GNUC__) && !defined(__x86_64__) && !defined(__amd64__)
831 __attribute__((__force_align_arg_pointer__))
834 pixman_image_composite32 (pixman_op_t op,
835 pixman_image_t * src,
836 pixman_image_t * mask,
837 pixman_image_t * dest,
847 pixman_format_code_t src_format, mask_format, dest_format;
848 uint32_t src_flags, mask_flags, dest_flags;
849 pixman_region32_t region;
850 pixman_box32_t *extents;
854 int mask_dx, mask_dy;
856 int dest_dx, dest_dy;
857 pixman_bool_t need_workaround;
858 pixman_implementation_t *imp;
859 pixman_composite_func_t func;
861 _pixman_image_validate (src);
863 _pixman_image_validate (mask);
864 _pixman_image_validate (dest);
866 src_format = src->common.extended_format_code;
867 src_flags = src->common.flags;
871 mask_format = mask->common.extended_format_code;
872 mask_flags = mask->common.flags;
876 mask_format = PIXMAN_null;
877 mask_flags = FAST_PATH_IS_OPAQUE;
880 dest_format = dest->common.extended_format_code;
881 dest_flags = dest->common.flags;
883 /* Check for pixbufs */
884 if ((mask_format == PIXMAN_a8r8g8b8 || mask_format == PIXMAN_a8b8g8r8) &&
885 (src->type == BITS && src->bits.bits == mask->bits.bits) &&
886 (src->common.repeat == mask->common.repeat) &&
887 (src_x == mask_x && src_y == mask_y))
889 if (src_format == PIXMAN_x8b8g8r8)
890 src_format = mask_format = PIXMAN_pixbuf;
891 else if (src_format == PIXMAN_x8r8g8b8)
892 src_format = mask_format = PIXMAN_rpixbuf;
895 /* Check for workaround */
896 need_workaround = (src_flags | mask_flags | dest_flags) & FAST_PATH_NEEDS_WORKAROUND;
900 apply_workaround (src, &src_x, &src_y, &src_bits, &src_dx, &src_dy);
901 apply_workaround (mask, &mask_x, &mask_y, &mask_bits, &mask_dx, &mask_dy);
902 apply_workaround (dest, &dest_x, &dest_y, &dest_bits, &dest_dx, &dest_dy);
905 pixman_region32_init (®ion);
907 if (!pixman_compute_composite_region32 (
908 ®ion, src, mask, dest,
909 src_x, src_y, mask_x, mask_y, dest_x, dest_y, width, height))
914 extents = pixman_region32_extents (®ion);
916 if (!analyze_extent (src, dest_x - src_x, dest_y - src_y, extents, &src_flags))
919 if (!analyze_extent (mask, dest_x - mask_x, dest_y - mask_y, extents, &mask_flags))
922 /* If the clip is within the source samples, and the samples are opaque,
923 * then the source is effectively opaque.
925 #define BOTH (FAST_PATH_SAMPLES_OPAQUE | FAST_PATH_SAMPLES_COVER_CLIP)
927 if ((src_flags & BOTH) == BOTH)
928 src_flags |= FAST_PATH_IS_OPAQUE;
930 if ((mask_flags & BOTH) == BOTH)
931 mask_flags |= FAST_PATH_IS_OPAQUE;
934 * Check if we can replace our operator by a simpler one
935 * if the src or dest are opaque. The output operator should be
936 * mathematically equivalent to the source.
938 op = optimize_operator (op, src_flags, mask_flags, dest_flags);
939 if (op == PIXMAN_OP_DST)
942 if (lookup_composite_function (op,
943 src_format, src_flags,
944 mask_format, mask_flags,
945 dest_format, dest_flags,
948 walk_region_internal (imp, op,
950 src_x, src_y, mask_x, mask_y,
953 (src_flags & FAST_PATH_SIMPLE_REPEAT),
954 (mask_flags & FAST_PATH_SIMPLE_REPEAT),
961 unapply_workaround (src, src_bits, src_dx, src_dy);
962 unapply_workaround (mask, mask_bits, mask_dx, mask_dy);
963 unapply_workaround (dest, dest_bits, dest_dx, dest_dy);
966 pixman_region32_fini (®ion);
970 pixman_image_composite (pixman_op_t op,
971 pixman_image_t * src,
972 pixman_image_t * mask,
973 pixman_image_t * dest,
983 pixman_image_composite32 (op, src, mask, dest, src_x, src_y,
984 mask_x, mask_y, dest_x, dest_y, width, height);
987 PIXMAN_EXPORT pixman_bool_t
988 pixman_blt (uint32_t *src_bits,
1001 return _pixman_implementation_blt (get_implementation(),
1002 src_bits, dst_bits, src_stride, dst_stride,
1009 PIXMAN_EXPORT pixman_bool_t
1010 pixman_fill (uint32_t *bits,
1019 return _pixman_implementation_fill (
1020 get_implementation(), bits, stride, bpp, x, y, width, height, xor);
1024 color_to_uint32 (const pixman_color_t *color)
1027 (color->alpha >> 8 << 24) |
1028 (color->red >> 8 << 16) |
1029 (color->green & 0xff00) |
1033 static pixman_bool_t
1034 color_to_pixel (pixman_color_t * color,
1036 pixman_format_code_t format)
1038 uint32_t c = color_to_uint32 (color);
1040 if (!(format == PIXMAN_a8r8g8b8 ||
1041 format == PIXMAN_x8r8g8b8 ||
1042 format == PIXMAN_a8b8g8r8 ||
1043 format == PIXMAN_x8b8g8r8 ||
1044 format == PIXMAN_b8g8r8a8 ||
1045 format == PIXMAN_b8g8r8x8 ||
1046 format == PIXMAN_r5g6b5 ||
1047 format == PIXMAN_b5g6r5 ||
1048 format == PIXMAN_a8))
1053 if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_ABGR)
1055 c = ((c & 0xff000000) >> 0) |
1056 ((c & 0x00ff0000) >> 16) |
1057 ((c & 0x0000ff00) >> 0) |
1058 ((c & 0x000000ff) << 16);
1060 if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_BGRA)
1062 c = ((c & 0xff000000) >> 24) |
1063 ((c & 0x00ff0000) >> 8) |
1064 ((c & 0x0000ff00) << 8) |
1065 ((c & 0x000000ff) << 24);
1068 if (format == PIXMAN_a8)
1070 else if (format == PIXMAN_r5g6b5 ||
1071 format == PIXMAN_b5g6r5)
1072 c = CONVERT_8888_TO_0565 (c);
1075 printf ("color: %x %x %x %x\n", color->alpha, color->red, color->green, color->blue);
1076 printf ("pixel: %x\n", c);
1083 PIXMAN_EXPORT pixman_bool_t
1084 pixman_image_fill_rectangles (pixman_op_t op,
1085 pixman_image_t * dest,
1086 pixman_color_t * color,
1088 const pixman_rectangle16_t *rects)
1090 pixman_box32_t stack_boxes[6];
1091 pixman_box32_t *boxes;
1092 pixman_bool_t result;
1097 boxes = pixman_malloc_ab (sizeof (pixman_box32_t), n_rects);
1103 boxes = stack_boxes;
1106 for (i = 0; i < n_rects; ++i)
1108 boxes[i].x1 = rects[i].x;
1109 boxes[i].y1 = rects[i].y;
1110 boxes[i].x2 = boxes[i].x1 + rects[i].width;
1111 boxes[i].y2 = boxes[i].y1 + rects[i].height;
1114 result = pixman_image_fill_boxes (op, dest, color, n_rects, boxes);
1116 if (boxes != stack_boxes)
1122 PIXMAN_EXPORT pixman_bool_t
1123 pixman_image_fill_boxes (pixman_op_t op,
1124 pixman_image_t * dest,
1125 pixman_color_t * color,
1127 const pixman_box32_t *boxes)
1129 pixman_image_t *solid;
1133 _pixman_image_validate (dest);
1135 if (color->alpha == 0xffff)
1137 if (op == PIXMAN_OP_OVER)
1141 if (op == PIXMAN_OP_CLEAR)
1153 if (op == PIXMAN_OP_SRC)
1157 if (color_to_pixel (color, &pixel, dest->bits.format))
1159 pixman_region32_t fill_region;
1161 pixman_box32_t *rects;
1163 if (!pixman_region32_init_rects (&fill_region, boxes, n_boxes))
1166 if (dest->common.have_clip_region)
1168 if (!pixman_region32_intersect (&fill_region,
1170 &dest->common.clip_region))
1174 rects = pixman_region32_rectangles (&fill_region, &n_rects);
1175 for (j = 0; j < n_rects; ++j)
1177 const pixman_box32_t *rect = &(rects[j]);
1178 pixman_fill (dest->bits.bits, dest->bits.rowstride, PIXMAN_FORMAT_BPP (dest->bits.format),
1179 rect->x1, rect->y1, rect->x2 - rect->x1, rect->y2 - rect->y1,
1183 pixman_region32_fini (&fill_region);
1188 solid = pixman_image_create_solid_fill (color);
1192 for (i = 0; i < n_boxes; ++i)
1194 const pixman_box32_t *box = &(boxes[i]);
1196 pixman_image_composite32 (op, solid, NULL, dest,
1199 box->x2 - box->x1, box->y2 - box->y1);
1202 pixman_image_unref (solid);
1210 * Returns the version of the pixman library encoded in a single
1211 * integer as per %PIXMAN_VERSION_ENCODE. The encoding ensures that
1212 * later versions compare greater than earlier versions.
1214 * A run-time comparison to check that pixman's version is greater than
1215 * or equal to version X.Y.Z could be performed as follows:
1217 * <informalexample><programlisting>
1218 * if (pixman_version() >= PIXMAN_VERSION_ENCODE(X,Y,Z)) {...}
1219 * </programlisting></informalexample>
1221 * See also pixman_version_string() as well as the compile-time
1222 * equivalents %PIXMAN_VERSION and %PIXMAN_VERSION_STRING.
1224 * Return value: the encoded version.
1227 pixman_version (void)
1229 return PIXMAN_VERSION;
1233 * pixman_version_string:
1235 * Returns the version of the pixman library as a human-readable string
1236 * of the form "X.Y.Z".
1238 * See also pixman_version() as well as the compile-time equivalents
1239 * %PIXMAN_VERSION_STRING and %PIXMAN_VERSION.
1241 * Return value: a string containing the version.
1243 PIXMAN_EXPORT const char*
1244 pixman_version_string (void)
1246 return PIXMAN_VERSION_STRING;
1250 * pixman_format_supported_source:
1251 * @format: A pixman_format_code_t format
1253 * Return value: whether the provided format code is a supported
1254 * format for a pixman surface used as a source in
1257 * Currently, all pixman_format_code_t values are supported.
1259 PIXMAN_EXPORT pixman_bool_t
1260 pixman_format_supported_source (pixman_format_code_t format)
1264 /* 32 bpp formats */
1265 case PIXMAN_a2b10g10r10:
1266 case PIXMAN_x2b10g10r10:
1267 case PIXMAN_a2r10g10b10:
1268 case PIXMAN_x2r10g10b10:
1269 case PIXMAN_a8r8g8b8:
1270 case PIXMAN_x8r8g8b8:
1271 case PIXMAN_a8b8g8r8:
1272 case PIXMAN_x8b8g8r8:
1273 case PIXMAN_b8g8r8a8:
1274 case PIXMAN_b8g8r8x8:
1279 case PIXMAN_x14r6g6b6:
1280 /* 16 bpp formats */
1281 case PIXMAN_a1r5g5b5:
1282 case PIXMAN_x1r5g5b5:
1283 case PIXMAN_a1b5g5r5:
1284 case PIXMAN_x1b5g5r5:
1285 case PIXMAN_a4r4g4b4:
1286 case PIXMAN_x4r4g4b4:
1287 case PIXMAN_a4b4g4r4:
1288 case PIXMAN_x4b4g4r4:
1293 case PIXMAN_a2r2g2b2:
1294 case PIXMAN_a2b2g2r2:
1298 /* Collides with PIXMAN_c8
1301 /* Collides with PIXMAN_g8
1308 case PIXMAN_a1r1g1b1:
1309 case PIXMAN_a1b1g1r1:
1326 * pixman_format_supported_destination:
1327 * @format: A pixman_format_code_t format
1329 * Return value: whether the provided format code is a supported
1330 * format for a pixman surface used as a destination in
1333 * Currently, all pixman_format_code_t values are supported
1334 * except for the YUV formats.
1336 PIXMAN_EXPORT pixman_bool_t
1337 pixman_format_supported_destination (pixman_format_code_t format)
1339 /* YUV formats cannot be written to at the moment */
1340 if (format == PIXMAN_yuy2 || format == PIXMAN_yv12)
1343 return pixman_format_supported_source (format);
1346 PIXMAN_EXPORT pixman_bool_t
1347 pixman_compute_composite_region (pixman_region16_t * region,
1348 pixman_image_t * src_image,
1349 pixman_image_t * mask_image,
1350 pixman_image_t * dst_image,
1360 pixman_region32_t r32;
1361 pixman_bool_t retval;
1363 pixman_region32_init (&r32);
1365 retval = pixman_compute_composite_region32 (
1366 &r32, src_image, mask_image, dst_image,
1367 src_x, src_y, mask_x, mask_y, dest_x, dest_y,
1372 if (!pixman_region16_copy_from_region32 (region, &r32))
1376 pixman_region32_fini (&r32);