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;
144 is_source_opaque = ((src_flags & mask_flags) & FAST_PATH_IS_OPAQUE) != 0;
145 is_dest_opaque = (dst_flags & FAST_PATH_IS_OPAQUE) != 0;
147 opaqueness = ((is_dest_opaque << 1) | is_source_opaque);
149 return operator_table[op].opaque_info[opaqueness];
153 apply_workaround (pixman_image_t *image,
156 uint32_t ** save_bits,
160 if (image && (image->common.flags & FAST_PATH_NEEDS_WORKAROUND))
162 /* Some X servers generate images that point to the
163 * wrong place in memory, but then set the clip region
164 * to point to the right place. Because of an old bug
165 * in pixman, this would actually work.
167 * Here we try and undo the damage
169 int bpp = PIXMAN_FORMAT_BPP (image->bits.format) / 8;
170 pixman_box32_t *extents;
174 extents = pixman_region32_extents (&(image->common.clip_region));
178 *save_bits = image->bits.bits;
182 pixman_region32_translate (&(image->common.clip_region), -dx, -dy);
184 t = (uint8_t *)image->bits.bits;
185 t += dy * image->bits.rowstride * 4 + dx * bpp;
186 image->bits.bits = (uint32_t *)t;
194 unapply_workaround (pixman_image_t *image, uint32_t *bits, int dx, int dy)
196 if (image && (image->common.flags & FAST_PATH_NEEDS_WORKAROUND))
198 image->bits.bits = bits;
199 pixman_region32_translate (&image->common.clip_region, dx, dy);
204 * Computing composite region
206 static inline pixman_bool_t
207 clip_general_image (pixman_region32_t * region,
208 pixman_region32_t * clip,
212 if (pixman_region32_n_rects (region) == 1 &&
213 pixman_region32_n_rects (clip) == 1)
215 pixman_box32_t * rbox = pixman_region32_rectangles (region, NULL);
216 pixman_box32_t * cbox = pixman_region32_rectangles (clip, NULL);
219 if (rbox->x1 < (v = cbox->x1 + dx))
221 if (rbox->x2 > (v = cbox->x2 + dx))
223 if (rbox->y1 < (v = cbox->y1 + dy))
225 if (rbox->y2 > (v = cbox->y2 + dy))
227 if (rbox->x1 >= rbox->x2 || rbox->y1 >= rbox->y2)
229 pixman_region32_init (region);
233 else if (!pixman_region32_not_empty (clip))
240 pixman_region32_translate (region, -dx, -dy);
242 if (!pixman_region32_intersect (region, region, clip))
246 pixman_region32_translate (region, dx, dy);
249 return pixman_region32_not_empty (region);
252 static inline pixman_bool_t
253 clip_source_image (pixman_region32_t * region,
254 pixman_image_t * image,
258 /* Source clips are ignored, unless they are explicitly turned on
259 * and the clip in question was set by an X client. (Because if
260 * the clip was not set by a client, then it is a hierarchy
261 * clip and those should always be ignored for sources).
263 if (!image->common.clip_sources || !image->common.client_clip)
266 return clip_general_image (region,
267 &image->common.clip_region,
272 * returns FALSE if the final region is empty. Indistinguishable from
273 * an allocation failure, but rendering ignores those anyways.
276 pixman_compute_composite_region32 (pixman_region32_t * region,
277 pixman_image_t * src_image,
278 pixman_image_t * mask_image,
279 pixman_image_t * dst_image,
289 region->extents.x1 = dest_x;
290 region->extents.x2 = dest_x + width;
291 region->extents.y1 = dest_y;
292 region->extents.y2 = dest_y + height;
294 region->extents.x1 = MAX (region->extents.x1, 0);
295 region->extents.y1 = MAX (region->extents.y1, 0);
296 region->extents.x2 = MIN (region->extents.x2, dst_image->bits.width);
297 region->extents.y2 = MIN (region->extents.y2, dst_image->bits.height);
301 /* Check for empty operation */
302 if (region->extents.x1 >= region->extents.x2 ||
303 region->extents.y1 >= region->extents.y2)
305 pixman_region32_init (region);
309 if (dst_image->common.have_clip_region)
311 if (!clip_general_image (region, &dst_image->common.clip_region, 0, 0))
313 pixman_region32_fini (region);
318 if (dst_image->common.alpha_map && dst_image->common.alpha_map->common.have_clip_region)
320 if (!clip_general_image (region, &dst_image->common.alpha_map->common.clip_region,
321 -dst_image->common.alpha_origin_x,
322 -dst_image->common.alpha_origin_y))
324 pixman_region32_fini (region);
329 /* clip against src */
330 if (src_image->common.have_clip_region)
332 if (!clip_source_image (region, src_image, dest_x - src_x, dest_y - src_y))
334 pixman_region32_fini (region);
338 if (src_image->common.alpha_map && src_image->common.alpha_map->common.have_clip_region)
340 if (!clip_source_image (region, (pixman_image_t *)src_image->common.alpha_map,
341 dest_x - (src_x - src_image->common.alpha_origin_x),
342 dest_y - (src_y - src_image->common.alpha_origin_y)))
344 pixman_region32_fini (region);
348 /* clip against mask */
349 if (mask_image && mask_image->common.have_clip_region)
351 if (!clip_source_image (region, mask_image, dest_x - mask_x, dest_y - mask_y))
353 pixman_region32_fini (region);
356 if (mask_image->common.alpha_map && mask_image->common.alpha_map->common.have_clip_region)
358 if (!clip_source_image (region, (pixman_image_t *)mask_image->common.alpha_map,
359 dest_x - (mask_x - mask_image->common.alpha_origin_x),
360 dest_y - (mask_y - mask_image->common.alpha_origin_y)))
362 pixman_region32_fini (region);
372 walk_region_internal (pixman_implementation_t *imp,
374 pixman_image_t * src_image,
375 pixman_image_t * mask_image,
376 pixman_image_t * dst_image,
385 pixman_bool_t src_repeat,
386 pixman_bool_t mask_repeat,
387 pixman_region32_t * region,
388 pixman_composite_func_t composite_rect)
390 int w, h, w_this, h_this;
391 int x_msk, y_msk, x_src, y_src, x_dst, y_dst;
392 int src_dy = src_y - dest_y;
393 int src_dx = src_x - dest_x;
394 int mask_dy = mask_y - dest_y;
395 int mask_dx = mask_x - dest_x;
396 const pixman_box32_t *pbox;
399 pbox = pixman_region32_rectangles (region, &n);
401 /* Fast path for non-repeating sources */
402 if (!src_repeat && !mask_repeat)
406 (*composite_rect) (imp, op,
407 src_image, mask_image, dst_image,
415 pbox->y2 - pbox->y1);
425 h = pbox->y2 - pbox->y1;
426 y_src = pbox->y1 + src_dy;
427 y_msk = pbox->y1 + mask_dy;
433 w = pbox->x2 - pbox->x1;
434 x_src = pbox->x1 + src_dx;
435 x_msk = pbox->x1 + mask_dx;
440 y_msk = MOD (y_msk, mask_image->bits.height);
441 if (h_this > mask_image->bits.height - y_msk)
442 h_this = mask_image->bits.height - y_msk;
447 y_src = MOD (y_src, src_image->bits.height);
448 if (h_this > src_image->bits.height - y_src)
449 h_this = src_image->bits.height - y_src;
458 x_msk = MOD (x_msk, mask_image->bits.width);
459 if (w_this > mask_image->bits.width - x_msk)
460 w_this = mask_image->bits.width - x_msk;
465 x_src = MOD (x_src, src_image->bits.width);
466 if (w_this > src_image->bits.width - x_src)
467 w_this = src_image->bits.width - x_src;
470 (*composite_rect) (imp, op,
471 src_image, mask_image, dst_image,
472 x_src, y_src, x_msk, y_msk, x_dst, y_dst,
491 #define N_CACHED_FAST_PATHS 8
497 pixman_implementation_t * imp;
498 pixman_fast_path_t fast_path;
499 } cache [N_CACHED_FAST_PATHS];
502 PIXMAN_DEFINE_THREAD_LOCAL (cache_t, fast_path_cache);
504 static force_inline void
505 lookup_composite_function (pixman_op_t op,
506 pixman_format_code_t src_format,
508 pixman_format_code_t mask_format,
510 pixman_format_code_t dest_format,
512 pixman_implementation_t **out_imp,
513 pixman_composite_func_t *out_func)
515 pixman_implementation_t *imp;
519 /* Check cache for fast paths */
520 cache = PIXMAN_GET_THREAD_LOCAL (fast_path_cache);
522 for (i = 0; i < N_CACHED_FAST_PATHS; ++i)
524 const pixman_fast_path_t *info = &(cache->cache[i].fast_path);
526 /* Note that we check for equality here, not whether
527 * the cached fast path matches. This is to prevent
528 * us from selecting an overly general fast path
529 * when a more specific one would work.
531 if (info->op == op &&
532 info->src_format == src_format &&
533 info->mask_format == mask_format &&
534 info->dest_format == dest_format &&
535 info->src_flags == src_flags &&
536 info->mask_flags == mask_flags &&
537 info->dest_flags == dest_flags &&
540 *out_imp = cache->cache[i].imp;
541 *out_func = cache->cache[i].fast_path.func;
547 for (imp = get_implementation (); imp != NULL; imp = imp->delegate)
549 const pixman_fast_path_t *info = imp->fast_paths;
551 while (info->op != PIXMAN_OP_NONE)
553 if ((info->op == op || info->op == PIXMAN_OP_any) &&
555 ((info->src_format == src_format) ||
556 (info->src_format == PIXMAN_any)) &&
557 ((info->mask_format == mask_format) ||
558 (info->mask_format == PIXMAN_any)) &&
559 ((info->dest_format == dest_format) ||
560 (info->dest_format == PIXMAN_any)) &&
562 (info->src_flags & src_flags) == info->src_flags &&
563 (info->mask_flags & mask_flags) == info->mask_flags &&
564 (info->dest_flags & dest_flags) == info->dest_flags)
567 *out_func = info->func;
569 /* Set i to the last spot in the cache so that the
570 * move-to-front code below will work
572 i = N_CACHED_FAST_PATHS - 1;
586 cache->cache[i + 1] = cache->cache[i];
588 cache->cache[0].imp = *out_imp;
589 cache->cache[0].fast_path.op = op;
590 cache->cache[0].fast_path.src_format = src_format;
591 cache->cache[0].fast_path.src_flags = src_flags;
592 cache->cache[0].fast_path.mask_format = mask_format;
593 cache->cache[0].fast_path.mask_flags = mask_flags;
594 cache->cache[0].fast_path.dest_format = dest_format;
595 cache->cache[0].fast_path.dest_flags = dest_flags;
596 cache->cache[0].fast_path.func = *out_func;
601 compute_sample_extents (pixman_transform_t *transform,
602 pixman_box32_t *extents, int x, int y,
603 pixman_fixed_t x_off, pixman_fixed_t y_off,
604 pixman_fixed_t width, pixman_fixed_t height)
606 pixman_fixed_t x1, y1, x2, y2;
607 pixman_fixed_48_16_t tx1, ty1, tx2, ty2;
609 /* We have checked earlier that (extents->x1 - x) etc. fit in a pixman_fixed_t */
610 x1 = (pixman_fixed_48_16_t)pixman_int_to_fixed (extents->x1 - x) + pixman_fixed_1 / 2;
611 y1 = (pixman_fixed_48_16_t)pixman_int_to_fixed (extents->y1 - y) + pixman_fixed_1 / 2;
612 x2 = (pixman_fixed_48_16_t)pixman_int_to_fixed (extents->x2 - x) - pixman_fixed_1 / 2;
613 y2 = (pixman_fixed_48_16_t)pixman_int_to_fixed (extents->y2 - y) - pixman_fixed_1 / 2;
617 tx1 = (pixman_fixed_48_16_t)x1;
618 ty1 = (pixman_fixed_48_16_t)y1;
619 tx2 = (pixman_fixed_48_16_t)x2;
620 ty2 = (pixman_fixed_48_16_t)y2;
626 for (i = 0; i < 4; ++i)
628 pixman_fixed_48_16_t tx, ty;
631 v.vector[0] = (i & 0x01)? x1 : x2;
632 v.vector[1] = (i & 0x02)? y1 : y2;
633 v.vector[2] = pixman_fixed_1;
635 if (!pixman_transform_point (transform, &v))
638 tx = (pixman_fixed_48_16_t)v.vector[0];
639 ty = (pixman_fixed_48_16_t)v.vector[1];
662 /* Expand the source area by a tiny bit so account of different rounding that
663 * may happen during sampling. Note that (8 * pixman_fixed_e) is very far from
664 * 0.5 so this won't cause the area computed to be overly pessimistic.
666 tx1 += x_off - 8 * pixman_fixed_e;
667 ty1 += y_off - 8 * pixman_fixed_e;
668 tx2 += x_off + width + 8 * pixman_fixed_e;
669 ty2 += y_off + height + 8 * pixman_fixed_e;
671 if (tx1 < pixman_min_fixed_48_16 || tx1 > pixman_max_fixed_48_16 ||
672 ty1 < pixman_min_fixed_48_16 || ty1 > pixman_max_fixed_48_16 ||
673 tx2 < pixman_min_fixed_48_16 || tx2 > pixman_max_fixed_48_16 ||
674 ty2 < pixman_min_fixed_48_16 || ty2 > pixman_max_fixed_48_16)
680 extents->x1 = pixman_fixed_to_int (tx1);
681 extents->y1 = pixman_fixed_to_int (ty1);
682 extents->x2 = pixman_fixed_to_int (tx2) + 1;
683 extents->y2 = pixman_fixed_to_int (ty2) + 1;
689 #define IS_16BIT(x) (((x) >= INT16_MIN) && ((x) <= INT16_MAX))
692 analyze_extent (pixman_image_t *image, int x, int y,
693 const pixman_box32_t *extents, uint32_t *flags)
695 pixman_transform_t *transform;
696 pixman_fixed_t *params;
697 pixman_fixed_t x_off, y_off;
698 pixman_fixed_t width, height;
701 *flags |= FAST_PATH_COVERS_CLIP;
705 transform = image->common.transform;
706 if (image->common.type == BITS)
708 /* During repeat mode calculations we might convert the
709 * width/height of an image to fixed 16.16, so we need
710 * them to be smaller than 16 bits.
712 if (image->bits.width >= 0x7fff || image->bits.height >= 0x7fff)
715 if (image->common.repeat == PIXMAN_REPEAT_NONE &&
716 (x > extents->x1 || y > extents->y1 ||
717 x + image->bits.width < extents->x2 ||
718 y + image->bits.height < extents->y2))
720 (*flags) &= ~FAST_PATH_COVERS_CLIP;
724 /* Some compositing functions walk one step
725 * outside the destination rectangle, so we
726 * check here that the expanded-by-one source
727 * extents in destination space fits in 16 bits
729 if (!IS_16BIT (extents->x1 - x - 1) ||
730 !IS_16BIT (extents->y1 - y - 1) ||
731 !IS_16BIT (extents->x2 - x + 1) ||
732 !IS_16BIT (extents->y2 - y + 1))
737 if (image->common.type == BITS)
739 switch (image->common.filter)
741 case PIXMAN_FILTER_CONVOLUTION:
742 params = image->common.filter_params;
743 x_off = - pixman_fixed_e - ((params[0] - pixman_fixed_1) >> 1);
744 y_off = - pixman_fixed_e - ((params[1] - pixman_fixed_1) >> 1);
749 case PIXMAN_FILTER_GOOD:
750 case PIXMAN_FILTER_BEST:
751 case PIXMAN_FILTER_BILINEAR:
752 x_off = - pixman_fixed_1 / 2;
753 y_off = - pixman_fixed_1 / 2;
754 width = pixman_fixed_1;
755 height = pixman_fixed_1;
758 case PIXMAN_FILTER_FAST:
759 case PIXMAN_FILTER_NEAREST:
760 x_off = - pixman_fixed_e;
761 y_off = - pixman_fixed_e;
778 /* Check that the extents expanded by one don't overflow. This ensures that
779 * compositing functions can simply walk the source space using 16.16 variables
780 * without worrying about overflow.
782 ex.x1 = extents->x1 - 1;
783 ex.y1 = extents->y1 - 1;
784 ex.x2 = extents->x2 + 1;
785 ex.y2 = extents->y2 + 1;
787 if (!compute_sample_extents (transform, &ex, x, y, x_off, y_off, width, height))
790 if (image->type == BITS)
792 /* Check whether the non-expanded, transformed extent is entirely within
793 * the source image, and set the FAST_PATH_SAMPLES_COVER_CLIP if it is.
796 if (compute_sample_extents (transform, &ex, x, y, x_off, y_off, width, height))
798 if (ex.x1 >= 0 && ex.y1 >= 0 && ex.x2 <= image->bits.width && ex.y2 <= image->bits.height)
799 *flags |= FAST_PATH_SAMPLES_COVER_CLIP;
807 do_composite (pixman_op_t op,
809 pixman_image_t *mask,
810 pixman_image_t *dest,
820 pixman_format_code_t src_format, mask_format, dest_format;
821 uint32_t src_flags, mask_flags, dest_flags;
822 pixman_region32_t region;
823 pixman_box32_t *extents;
827 int mask_dx, mask_dy;
829 int dest_dx, dest_dy;
830 pixman_bool_t need_workaround;
831 pixman_implementation_t *imp;
832 pixman_composite_func_t func;
834 src_format = src->common.extended_format_code;
835 src_flags = src->common.flags;
839 mask_format = mask->common.extended_format_code;
840 mask_flags = mask->common.flags;
844 mask_format = PIXMAN_null;
845 mask_flags = FAST_PATH_IS_OPAQUE;
848 dest_format = dest->common.extended_format_code;
849 dest_flags = dest->common.flags;
851 /* Check for pixbufs */
852 if ((mask_format == PIXMAN_a8r8g8b8 || mask_format == PIXMAN_a8b8g8r8) &&
853 (src->type == BITS && src->bits.bits == mask->bits.bits) &&
854 (src->common.repeat == mask->common.repeat) &&
855 (src_x == mask_x && src_y == mask_y))
857 if (src_format == PIXMAN_x8b8g8r8)
858 src_format = mask_format = PIXMAN_pixbuf;
859 else if (src_format == PIXMAN_x8r8g8b8)
860 src_format = mask_format = PIXMAN_rpixbuf;
863 /* Check for workaround */
864 need_workaround = (src_flags | mask_flags | dest_flags) & FAST_PATH_NEEDS_WORKAROUND;
868 apply_workaround (src, &src_x, &src_y, &src_bits, &src_dx, &src_dy);
869 apply_workaround (mask, &mask_x, &mask_y, &mask_bits, &mask_dx, &mask_dy);
870 apply_workaround (dest, &dest_x, &dest_y, &dest_bits, &dest_dx, &dest_dy);
873 pixman_region32_init (®ion);
875 if (!pixman_compute_composite_region32 (
876 ®ion, src, mask, dest,
877 src_x, src_y, mask_x, mask_y, dest_x, dest_y, width, height))
882 extents = pixman_region32_extents (®ion);
884 if (!analyze_extent (src, dest_x - src_x, dest_y - src_y, extents, &src_flags))
887 if (!analyze_extent (mask, dest_x - mask_x, dest_y - mask_y, extents, &mask_flags))
890 /* If the clip is within the source samples, and the samples are opaque,
891 * then the source is effectively opaque.
893 #define BOTH (FAST_PATH_SAMPLES_OPAQUE | FAST_PATH_SAMPLES_COVER_CLIP)
895 if ((src_flags & BOTH) == BOTH)
896 src_flags |= FAST_PATH_IS_OPAQUE;
898 if ((mask_flags & BOTH) == BOTH)
899 mask_flags |= FAST_PATH_IS_OPAQUE;
902 * Check if we can replace our operator by a simpler one
903 * if the src or dest are opaque. The output operator should be
904 * mathematically equivalent to the source.
906 op = optimize_operator (op, src_flags, mask_flags, dest_flags);
907 if (op == PIXMAN_OP_DST)
910 lookup_composite_function (op,
911 src_format, src_flags,
912 mask_format, mask_flags,
913 dest_format, dest_flags,
916 walk_region_internal (imp, op,
918 src_x, src_y, mask_x, mask_y,
921 (src_flags & FAST_PATH_SIMPLE_REPEAT),
922 (mask_flags & FAST_PATH_SIMPLE_REPEAT),
928 unapply_workaround (src, src_bits, src_dx, src_dy);
929 unapply_workaround (mask, mask_bits, mask_dx, mask_dy);
930 unapply_workaround (dest, dest_bits, dest_dx, dest_dy);
933 pixman_region32_fini (®ion);
937 pixman_image_composite (pixman_op_t op,
938 pixman_image_t * src,
939 pixman_image_t * mask,
940 pixman_image_t * dest,
950 pixman_image_composite32 (op, src, mask, dest, src_x, src_y,
951 mask_x, mask_y, dest_x, dest_y, width, height);
955 * Work around GCC bug causing crashes in Mozilla with SSE2
957 * When using -msse, gcc generates movdqa instructions assuming that
958 * the stack is 16 byte aligned. Unfortunately some applications, such
959 * as Mozilla and Mono, end up aligning the stack to 4 bytes, which
960 * causes the movdqa instructions to fail.
962 * The __force_align_arg_pointer__ makes gcc generate a prologue that
963 * realigns the stack pointer to 16 bytes.
965 * On x86-64 this is not necessary because the standard ABI already
966 * calls for a 16 byte aligned stack.
968 * See https://bugs.freedesktop.org/show_bug.cgi?id=15693
970 #if defined (USE_SSE2) && defined(__GNUC__) && !defined(__x86_64__) && !defined(__amd64__)
971 __attribute__((__force_align_arg_pointer__))
974 pixman_image_composite32 (pixman_op_t op,
975 pixman_image_t * src,
976 pixman_image_t * mask,
977 pixman_image_t * dest,
987 _pixman_image_validate (src);
989 _pixman_image_validate (mask);
990 _pixman_image_validate (dest);
1000 PIXMAN_EXPORT pixman_bool_t
1001 pixman_blt (uint32_t *src_bits,
1014 return _pixman_implementation_blt (get_implementation(),
1015 src_bits, dst_bits, src_stride, dst_stride,
1022 PIXMAN_EXPORT pixman_bool_t
1023 pixman_fill (uint32_t *bits,
1032 return _pixman_implementation_fill (
1033 get_implementation(), bits, stride, bpp, x, y, width, height, xor);
1037 color_to_uint32 (const pixman_color_t *color)
1040 (color->alpha >> 8 << 24) |
1041 (color->red >> 8 << 16) |
1042 (color->green & 0xff00) |
1046 static pixman_bool_t
1047 color_to_pixel (pixman_color_t * color,
1049 pixman_format_code_t format)
1051 uint32_t c = color_to_uint32 (color);
1053 if (!(format == PIXMAN_a8r8g8b8 ||
1054 format == PIXMAN_x8r8g8b8 ||
1055 format == PIXMAN_a8b8g8r8 ||
1056 format == PIXMAN_x8b8g8r8 ||
1057 format == PIXMAN_b8g8r8a8 ||
1058 format == PIXMAN_b8g8r8x8 ||
1059 format == PIXMAN_r5g6b5 ||
1060 format == PIXMAN_b5g6r5 ||
1061 format == PIXMAN_a8))
1066 if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_ABGR)
1068 c = ((c & 0xff000000) >> 0) |
1069 ((c & 0x00ff0000) >> 16) |
1070 ((c & 0x0000ff00) >> 0) |
1071 ((c & 0x000000ff) << 16);
1073 if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_BGRA)
1075 c = ((c & 0xff000000) >> 24) |
1076 ((c & 0x00ff0000) >> 8) |
1077 ((c & 0x0000ff00) << 8) |
1078 ((c & 0x000000ff) << 24);
1081 if (format == PIXMAN_a8)
1083 else if (format == PIXMAN_r5g6b5 ||
1084 format == PIXMAN_b5g6r5)
1085 c = CONVERT_8888_TO_0565 (c);
1088 printf ("color: %x %x %x %x\n", color->alpha, color->red, color->green, color->blue);
1089 printf ("pixel: %x\n", c);
1096 PIXMAN_EXPORT pixman_bool_t
1097 pixman_image_fill_rectangles (pixman_op_t op,
1098 pixman_image_t * dest,
1099 pixman_color_t * color,
1101 const pixman_rectangle16_t *rects)
1103 pixman_box32_t stack_boxes[6];
1104 pixman_box32_t *boxes;
1105 pixman_bool_t result;
1110 boxes = pixman_malloc_ab (sizeof (pixman_box32_t), n_rects);
1116 boxes = stack_boxes;
1119 for (i = 0; i < n_rects; ++i)
1121 boxes[i].x1 = rects[i].x;
1122 boxes[i].y1 = rects[i].y;
1123 boxes[i].x2 = boxes[i].x1 + rects[i].width;
1124 boxes[i].y2 = boxes[i].y1 + rects[i].height;
1127 result = pixman_image_fill_boxes (op, dest, color, n_rects, boxes);
1129 if (boxes != stack_boxes)
1135 PIXMAN_EXPORT pixman_bool_t
1136 pixman_image_fill_boxes (pixman_op_t op,
1137 pixman_image_t * dest,
1138 pixman_color_t * color,
1140 const pixman_box32_t *boxes)
1142 pixman_image_t *solid;
1146 _pixman_image_validate (dest);
1148 if (color->alpha == 0xffff)
1150 if (op == PIXMAN_OP_OVER)
1154 if (op == PIXMAN_OP_CLEAR)
1166 if (op == PIXMAN_OP_SRC)
1170 if (color_to_pixel (color, &pixel, dest->bits.format))
1172 pixman_region32_t fill_region;
1174 pixman_box32_t *rects;
1176 if (!pixman_region32_init_rects (&fill_region, boxes, n_boxes))
1179 if (dest->common.have_clip_region)
1181 if (!pixman_region32_intersect (&fill_region,
1183 &dest->common.clip_region))
1187 rects = pixman_region32_rectangles (&fill_region, &n_rects);
1188 for (j = 0; j < n_rects; ++j)
1190 const pixman_box32_t *rect = &(rects[j]);
1191 pixman_fill (dest->bits.bits, dest->bits.rowstride, PIXMAN_FORMAT_BPP (dest->bits.format),
1192 rect->x1, rect->y1, rect->x2 - rect->x1, rect->y2 - rect->y1,
1196 pixman_region32_fini (&fill_region);
1201 solid = pixman_image_create_solid_fill (color);
1205 for (i = 0; i < n_boxes; ++i)
1207 const pixman_box32_t *box = &(boxes[i]);
1209 pixman_image_composite32 (op, solid, NULL, dest,
1212 box->x2 - box->x1, box->y2 - box->y1);
1215 pixman_image_unref (solid);
1223 * Returns the version of the pixman library encoded in a single
1224 * integer as per %PIXMAN_VERSION_ENCODE. The encoding ensures that
1225 * later versions compare greater than earlier versions.
1227 * A run-time comparison to check that pixman's version is greater than
1228 * or equal to version X.Y.Z could be performed as follows:
1230 * <informalexample><programlisting>
1231 * if (pixman_version() >= PIXMAN_VERSION_ENCODE(X,Y,Z)) {...}
1232 * </programlisting></informalexample>
1234 * See also pixman_version_string() as well as the compile-time
1235 * equivalents %PIXMAN_VERSION and %PIXMAN_VERSION_STRING.
1237 * Return value: the encoded version.
1240 pixman_version (void)
1242 return PIXMAN_VERSION;
1246 * pixman_version_string:
1248 * Returns the version of the pixman library as a human-readable string
1249 * of the form "X.Y.Z".
1251 * See also pixman_version() as well as the compile-time equivalents
1252 * %PIXMAN_VERSION_STRING and %PIXMAN_VERSION.
1254 * Return value: a string containing the version.
1256 PIXMAN_EXPORT const char*
1257 pixman_version_string (void)
1259 return PIXMAN_VERSION_STRING;
1263 * pixman_format_supported_source:
1264 * @format: A pixman_format_code_t format
1266 * Return value: whether the provided format code is a supported
1267 * format for a pixman surface used as a source in
1270 * Currently, all pixman_format_code_t values are supported.
1272 PIXMAN_EXPORT pixman_bool_t
1273 pixman_format_supported_source (pixman_format_code_t format)
1277 /* 32 bpp formats */
1278 case PIXMAN_a2b10g10r10:
1279 case PIXMAN_x2b10g10r10:
1280 case PIXMAN_a2r10g10b10:
1281 case PIXMAN_x2r10g10b10:
1282 case PIXMAN_a8r8g8b8:
1283 case PIXMAN_x8r8g8b8:
1284 case PIXMAN_a8b8g8r8:
1285 case PIXMAN_x8b8g8r8:
1286 case PIXMAN_b8g8r8a8:
1287 case PIXMAN_b8g8r8x8:
1292 case PIXMAN_x14r6g6b6:
1293 /* 16 bpp formats */
1294 case PIXMAN_a1r5g5b5:
1295 case PIXMAN_x1r5g5b5:
1296 case PIXMAN_a1b5g5r5:
1297 case PIXMAN_x1b5g5r5:
1298 case PIXMAN_a4r4g4b4:
1299 case PIXMAN_x4r4g4b4:
1300 case PIXMAN_a4b4g4r4:
1301 case PIXMAN_x4b4g4r4:
1306 case PIXMAN_a2r2g2b2:
1307 case PIXMAN_a2b2g2r2:
1311 /* Collides with PIXMAN_c8
1314 /* Collides with PIXMAN_g8
1321 case PIXMAN_a1r1g1b1:
1322 case PIXMAN_a1b1g1r1:
1339 * pixman_format_supported_destination:
1340 * @format: A pixman_format_code_t format
1342 * Return value: whether the provided format code is a supported
1343 * format for a pixman surface used as a destination in
1346 * Currently, all pixman_format_code_t values are supported
1347 * except for the YUV formats.
1349 PIXMAN_EXPORT pixman_bool_t
1350 pixman_format_supported_destination (pixman_format_code_t format)
1352 /* YUV formats cannot be written to at the moment */
1353 if (format == PIXMAN_yuy2 || format == PIXMAN_yv12)
1356 return pixman_format_supported_source (format);
1359 PIXMAN_EXPORT pixman_bool_t
1360 pixman_compute_composite_region (pixman_region16_t * region,
1361 pixman_image_t * src_image,
1362 pixman_image_t * mask_image,
1363 pixman_image_t * dst_image,
1373 pixman_region32_t r32;
1374 pixman_bool_t retval;
1376 pixman_region32_init (&r32);
1378 retval = pixman_compute_composite_region32 (
1379 &r32, src_image, mask_image, dst_image,
1380 src_x, src_y, mask_x, mask_y, dest_x, dest_y,
1385 if (!pixman_region16_copy_from_region32 (region, &r32))
1389 pixman_region32_fini (&r32);