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)
308 if (dst_image->common.have_clip_region)
310 if (!clip_general_image (region, &dst_image->common.clip_region, 0, 0))
314 if (dst_image->common.alpha_map && dst_image->common.alpha_map->common.have_clip_region)
316 if (!clip_general_image (region, &dst_image->common.alpha_map->common.clip_region,
317 -dst_image->common.alpha_origin_x,
318 -dst_image->common.alpha_origin_y))
324 /* clip against src */
325 if (src_image->common.have_clip_region)
327 if (!clip_source_image (region, src_image, dest_x - src_x, dest_y - src_y))
330 if (src_image->common.alpha_map && src_image->common.alpha_map->common.have_clip_region)
332 if (!clip_source_image (region, (pixman_image_t *)src_image->common.alpha_map,
333 dest_x - (src_x - src_image->common.alpha_origin_x),
334 dest_y - (src_y - src_image->common.alpha_origin_y)))
339 /* clip against mask */
340 if (mask_image && mask_image->common.have_clip_region)
342 if (!clip_source_image (region, mask_image, dest_x - mask_x, dest_y - mask_y))
345 if (mask_image->common.alpha_map && mask_image->common.alpha_map->common.have_clip_region)
347 if (!clip_source_image (region, (pixman_image_t *)mask_image->common.alpha_map,
348 dest_x - (mask_x - mask_image->common.alpha_origin_x),
349 dest_y - (mask_y - mask_image->common.alpha_origin_y)))
360 walk_region_internal (pixman_implementation_t *imp,
362 pixman_image_t * src_image,
363 pixman_image_t * mask_image,
364 pixman_image_t * dst_image,
373 pixman_bool_t src_repeat,
374 pixman_bool_t mask_repeat,
375 pixman_region32_t * region,
376 pixman_composite_func_t composite_rect)
378 int w, h, w_this, h_this;
379 int x_msk, y_msk, x_src, y_src, x_dst, y_dst;
380 int src_dy = src_y - dest_y;
381 int src_dx = src_x - dest_x;
382 int mask_dy = mask_y - dest_y;
383 int mask_dx = mask_x - dest_x;
384 const pixman_box32_t *pbox;
387 pbox = pixman_region32_rectangles (region, &n);
389 /* Fast path for non-repeating sources */
390 if (!src_repeat && !mask_repeat)
394 (*composite_rect) (imp, op,
395 src_image, mask_image, dst_image,
403 pbox->y2 - pbox->y1);
413 h = pbox->y2 - pbox->y1;
414 y_src = pbox->y1 + src_dy;
415 y_msk = pbox->y1 + mask_dy;
421 w = pbox->x2 - pbox->x1;
422 x_src = pbox->x1 + src_dx;
423 x_msk = pbox->x1 + mask_dx;
428 y_msk = MOD (y_msk, mask_image->bits.height);
429 if (h_this > mask_image->bits.height - y_msk)
430 h_this = mask_image->bits.height - y_msk;
435 y_src = MOD (y_src, src_image->bits.height);
436 if (h_this > src_image->bits.height - y_src)
437 h_this = src_image->bits.height - y_src;
446 x_msk = MOD (x_msk, mask_image->bits.width);
447 if (w_this > mask_image->bits.width - x_msk)
448 w_this = mask_image->bits.width - x_msk;
453 x_src = MOD (x_src, src_image->bits.width);
454 if (w_this > src_image->bits.width - x_src)
455 w_this = src_image->bits.width - x_src;
458 (*composite_rect) (imp, op,
459 src_image, mask_image, dst_image,
460 x_src, y_src, x_msk, y_msk, x_dst, y_dst,
479 #define N_CACHED_FAST_PATHS 8
485 pixman_implementation_t * imp;
486 pixman_fast_path_t fast_path;
487 } cache [N_CACHED_FAST_PATHS];
490 PIXMAN_DEFINE_THREAD_LOCAL (cache_t, fast_path_cache);
492 static force_inline pixman_bool_t
493 lookup_composite_function (pixman_op_t op,
494 pixman_format_code_t src_format,
496 pixman_format_code_t mask_format,
498 pixman_format_code_t dest_format,
500 pixman_implementation_t **out_imp,
501 pixman_composite_func_t *out_func)
503 pixman_implementation_t *imp;
507 /* Check cache for fast paths */
508 cache = PIXMAN_GET_THREAD_LOCAL (fast_path_cache);
510 for (i = 0; i < N_CACHED_FAST_PATHS; ++i)
512 const pixman_fast_path_t *info = &(cache->cache[i].fast_path);
514 /* Note that we check for equality here, not whether
515 * the cached fast path matches. This is to prevent
516 * us from selecting an overly general fast path
517 * when a more specific one would work.
519 if (info->op == op &&
520 info->src_format == src_format &&
521 info->mask_format == mask_format &&
522 info->dest_format == dest_format &&
523 info->src_flags == src_flags &&
524 info->mask_flags == mask_flags &&
525 info->dest_flags == dest_flags &&
528 *out_imp = cache->cache[i].imp;
529 *out_func = cache->cache[i].fast_path.func;
535 for (imp = get_implementation (); imp != NULL; imp = imp->delegate)
537 const pixman_fast_path_t *info = imp->fast_paths;
539 while (info->op != PIXMAN_OP_NONE)
541 if ((info->op == op || info->op == PIXMAN_OP_any) &&
543 ((info->src_format == src_format) ||
544 (info->src_format == PIXMAN_any)) &&
545 ((info->mask_format == mask_format) ||
546 (info->mask_format == PIXMAN_any)) &&
547 ((info->dest_format == dest_format) ||
548 (info->dest_format == PIXMAN_any)) &&
550 (info->src_flags & src_flags) == info->src_flags &&
551 (info->mask_flags & mask_flags) == info->mask_flags &&
552 (info->dest_flags & dest_flags) == info->dest_flags)
555 *out_func = info->func;
557 /* Set i to the last spot in the cache so that the
558 * move-to-front code below will work
560 i = N_CACHED_FAST_PATHS - 1;
574 cache->cache[i + 1] = cache->cache[i];
576 cache->cache[0].imp = *out_imp;
577 cache->cache[0].fast_path.op = op;
578 cache->cache[0].fast_path.src_format = src_format;
579 cache->cache[0].fast_path.src_flags = src_flags;
580 cache->cache[0].fast_path.mask_format = mask_format;
581 cache->cache[0].fast_path.mask_flags = mask_flags;
582 cache->cache[0].fast_path.dest_format = dest_format;
583 cache->cache[0].fast_path.dest_flags = dest_flags;
584 cache->cache[0].fast_path.func = *out_func;
591 compute_sample_extents (pixman_transform_t *transform,
592 pixman_box32_t *extents, int x, int y,
593 pixman_fixed_t x_off, pixman_fixed_t y_off,
594 pixman_fixed_t width, pixman_fixed_t height)
596 pixman_fixed_t x1, y1, x2, y2;
597 pixman_fixed_48_16_t tx1, ty1, tx2, ty2;
599 /* We have checked earlier that (extents->x1 - x) etc. fit in a pixman_fixed_t */
600 x1 = (pixman_fixed_48_16_t)pixman_int_to_fixed (extents->x1 - x) + pixman_fixed_1 / 2;
601 y1 = (pixman_fixed_48_16_t)pixman_int_to_fixed (extents->y1 - y) + pixman_fixed_1 / 2;
602 x2 = (pixman_fixed_48_16_t)pixman_int_to_fixed (extents->x2 - x) - pixman_fixed_1 / 2;
603 y2 = (pixman_fixed_48_16_t)pixman_int_to_fixed (extents->y2 - y) - pixman_fixed_1 / 2;
607 tx1 = (pixman_fixed_48_16_t)x1;
608 ty1 = (pixman_fixed_48_16_t)y1;
609 tx2 = (pixman_fixed_48_16_t)x2;
610 ty2 = (pixman_fixed_48_16_t)y2;
616 for (i = 0; i < 4; ++i)
618 pixman_fixed_48_16_t tx, ty;
621 v.vector[0] = (i & 0x01)? x1 : x2;
622 v.vector[1] = (i & 0x02)? y1 : y2;
623 v.vector[2] = pixman_fixed_1;
625 if (!pixman_transform_point (transform, &v))
628 tx = (pixman_fixed_48_16_t)v.vector[0];
629 ty = (pixman_fixed_48_16_t)v.vector[1];
652 /* Expand the source area by a tiny bit so account of different rounding that
653 * may happen during sampling. Note that (8 * pixman_fixed_e) is very far from
654 * 0.5 so this won't cause the area computed to be overly pessimistic.
656 tx1 += x_off - 8 * pixman_fixed_e;
657 ty1 += y_off - 8 * pixman_fixed_e;
658 tx2 += x_off + width + 8 * pixman_fixed_e;
659 ty2 += y_off + height + 8 * pixman_fixed_e;
661 if (tx1 < pixman_min_fixed_48_16 || tx1 > pixman_max_fixed_48_16 ||
662 ty1 < pixman_min_fixed_48_16 || ty1 > pixman_max_fixed_48_16 ||
663 tx2 < pixman_min_fixed_48_16 || tx2 > pixman_max_fixed_48_16 ||
664 ty2 < pixman_min_fixed_48_16 || ty2 > pixman_max_fixed_48_16)
670 extents->x1 = pixman_fixed_to_int (tx1);
671 extents->y1 = pixman_fixed_to_int (ty1);
672 extents->x2 = pixman_fixed_to_int (tx2) + 1;
673 extents->y2 = pixman_fixed_to_int (ty2) + 1;
679 #define IS_16BIT(x) (((x) >= INT16_MIN) && ((x) <= INT16_MAX))
682 analyze_extent (pixman_image_t *image, int x, int y,
683 const pixman_box32_t *extents, uint32_t *flags)
685 pixman_transform_t *transform;
686 pixman_fixed_t *params;
687 pixman_fixed_t x_off, y_off;
688 pixman_fixed_t width, height;
691 *flags |= FAST_PATH_COVERS_CLIP;
695 transform = image->common.transform;
696 if (image->common.type == BITS)
698 /* During repeat mode calculations we might convert the
699 * width/height of an image to fixed 16.16, so we need
700 * them to be smaller than 16 bits.
702 if (image->bits.width >= 0x7fff || image->bits.height >= 0x7fff)
705 if (image->common.repeat == PIXMAN_REPEAT_NONE &&
706 (x > extents->x1 || y > extents->y1 ||
707 x + image->bits.width < extents->x2 ||
708 y + image->bits.height < extents->y2))
710 (*flags) &= ~FAST_PATH_COVERS_CLIP;
714 /* Some compositing functions walk one step
715 * outside the destination rectangle, so we
716 * check here that the expanded-by-one source
717 * extents in destination space fits in 16 bits
719 if (!IS_16BIT (extents->x1 - x - 1) ||
720 !IS_16BIT (extents->y1 - y - 1) ||
721 !IS_16BIT (extents->x2 - x + 1) ||
722 !IS_16BIT (extents->y2 - y + 1))
727 if (image->common.type == BITS)
729 switch (image->common.filter)
731 case PIXMAN_FILTER_CONVOLUTION:
732 params = image->common.filter_params;
733 x_off = - pixman_fixed_e - ((params[0] - pixman_fixed_1) >> 1);
734 y_off = - pixman_fixed_e - ((params[1] - pixman_fixed_1) >> 1);
739 case PIXMAN_FILTER_GOOD:
740 case PIXMAN_FILTER_BEST:
741 case PIXMAN_FILTER_BILINEAR:
742 x_off = - pixman_fixed_1 / 2;
743 y_off = - pixman_fixed_1 / 2;
744 width = pixman_fixed_1;
745 height = pixman_fixed_1;
748 case PIXMAN_FILTER_FAST:
749 case PIXMAN_FILTER_NEAREST:
750 x_off = - pixman_fixed_e;
751 y_off = - pixman_fixed_e;
768 /* Check that the extents expanded by one don't overflow. This ensures that
769 * compositing functions can simply walk the source space using 16.16 variables
770 * without worrying about overflow.
772 ex.x1 = extents->x1 - 1;
773 ex.y1 = extents->y1 - 1;
774 ex.x2 = extents->x2 + 1;
775 ex.y2 = extents->y2 + 1;
777 if (!compute_sample_extents (transform, &ex, x, y, x_off, y_off, width, height))
780 if (image->type == BITS)
782 /* Check whether the non-expanded, transformed extent is entirely within
783 * the source image, and set the FAST_PATH_SAMPLES_COVER_CLIP if it is.
786 if (compute_sample_extents (transform, &ex, x, y, x_off, y_off, width, height))
788 if (ex.x1 >= 0 && ex.y1 >= 0 && ex.x2 <= image->bits.width && ex.y2 <= image->bits.height)
789 *flags |= FAST_PATH_SAMPLES_COVER_CLIP;
797 * Work around GCC bug causing crashes in Mozilla with SSE2
799 * When using -msse, gcc generates movdqa instructions assuming that
800 * the stack is 16 byte aligned. Unfortunately some applications, such
801 * as Mozilla and Mono, end up aligning the stack to 4 bytes, which
802 * causes the movdqa instructions to fail.
804 * The __force_align_arg_pointer__ makes gcc generate a prologue that
805 * realigns the stack pointer to 16 bytes.
807 * On x86-64 this is not necessary because the standard ABI already
808 * calls for a 16 byte aligned stack.
810 * See https://bugs.freedesktop.org/show_bug.cgi?id=15693
812 #if defined (USE_SSE2) && defined(__GNUC__) && !defined(__x86_64__) && !defined(__amd64__)
813 __attribute__((__force_align_arg_pointer__))
816 pixman_image_composite32 (pixman_op_t op,
817 pixman_image_t * src,
818 pixman_image_t * mask,
819 pixman_image_t * dest,
829 pixman_format_code_t src_format, mask_format, dest_format;
830 uint32_t src_flags, mask_flags, dest_flags;
831 pixman_region32_t region;
832 pixman_box32_t *extents;
836 int mask_dx, mask_dy;
838 int dest_dx, dest_dy;
839 pixman_bool_t need_workaround;
840 pixman_implementation_t *imp;
841 pixman_composite_func_t func;
843 _pixman_image_validate (src);
845 _pixman_image_validate (mask);
846 _pixman_image_validate (dest);
848 src_format = src->common.extended_format_code;
849 src_flags = src->common.flags;
853 mask_format = mask->common.extended_format_code;
854 mask_flags = mask->common.flags;
858 mask_format = PIXMAN_null;
859 mask_flags = FAST_PATH_IS_OPAQUE;
862 dest_format = dest->common.extended_format_code;
863 dest_flags = dest->common.flags;
865 /* Check for pixbufs */
866 if ((mask_format == PIXMAN_a8r8g8b8 || mask_format == PIXMAN_a8b8g8r8) &&
867 (src->type == BITS && src->bits.bits == mask->bits.bits) &&
868 (src->common.repeat == mask->common.repeat) &&
869 (src_x == mask_x && src_y == mask_y))
871 if (src_format == PIXMAN_x8b8g8r8)
872 src_format = mask_format = PIXMAN_pixbuf;
873 else if (src_format == PIXMAN_x8r8g8b8)
874 src_format = mask_format = PIXMAN_rpixbuf;
877 /* Check for workaround */
878 need_workaround = (src_flags | mask_flags | dest_flags) & FAST_PATH_NEEDS_WORKAROUND;
882 apply_workaround (src, &src_x, &src_y, &src_bits, &src_dx, &src_dy);
883 apply_workaround (mask, &mask_x, &mask_y, &mask_bits, &mask_dx, &mask_dy);
884 apply_workaround (dest, &dest_x, &dest_y, &dest_bits, &dest_dx, &dest_dy);
887 pixman_region32_init (®ion);
889 if (!pixman_compute_composite_region32 (
890 ®ion, src, mask, dest,
891 src_x, src_y, mask_x, mask_y, dest_x, dest_y, width, height))
896 extents = pixman_region32_extents (®ion);
898 if (!analyze_extent (src, dest_x - src_x, dest_y - src_y, extents, &src_flags))
901 if (!analyze_extent (mask, dest_x - mask_x, dest_y - mask_y, extents, &mask_flags))
904 /* If the clip is within the source samples, and the samples are opaque,
905 * then the source is effectively opaque.
907 #define BOTH (FAST_PATH_SAMPLES_OPAQUE | FAST_PATH_SAMPLES_COVER_CLIP)
909 if ((src_flags & BOTH) == BOTH)
910 src_flags |= FAST_PATH_IS_OPAQUE;
912 if ((mask_flags & BOTH) == BOTH)
913 mask_flags |= FAST_PATH_IS_OPAQUE;
916 * Check if we can replace our operator by a simpler one
917 * if the src or dest are opaque. The output operator should be
918 * mathematically equivalent to the source.
920 op = optimize_operator (op, src_flags, mask_flags, dest_flags);
921 if (op == PIXMAN_OP_DST)
924 if (lookup_composite_function (op,
925 src_format, src_flags,
926 mask_format, mask_flags,
927 dest_format, dest_flags,
930 walk_region_internal (imp, op,
932 src_x, src_y, mask_x, mask_y,
935 (src_flags & FAST_PATH_SIMPLE_REPEAT),
936 (mask_flags & FAST_PATH_SIMPLE_REPEAT),
943 unapply_workaround (src, src_bits, src_dx, src_dy);
944 unapply_workaround (mask, mask_bits, mask_dx, mask_dy);
945 unapply_workaround (dest, dest_bits, dest_dx, dest_dy);
948 pixman_region32_fini (®ion);
952 pixman_image_composite (pixman_op_t op,
953 pixman_image_t * src,
954 pixman_image_t * mask,
955 pixman_image_t * dest,
965 pixman_image_composite32 (op, src, mask, dest, src_x, src_y,
966 mask_x, mask_y, dest_x, dest_y, width, height);
969 PIXMAN_EXPORT pixman_bool_t
970 pixman_blt (uint32_t *src_bits,
983 return _pixman_implementation_blt (get_implementation(),
984 src_bits, dst_bits, src_stride, dst_stride,
991 PIXMAN_EXPORT pixman_bool_t
992 pixman_fill (uint32_t *bits,
1001 return _pixman_implementation_fill (
1002 get_implementation(), bits, stride, bpp, x, y, width, height, xor);
1006 color_to_uint32 (const pixman_color_t *color)
1009 (color->alpha >> 8 << 24) |
1010 (color->red >> 8 << 16) |
1011 (color->green & 0xff00) |
1015 static pixman_bool_t
1016 color_to_pixel (pixman_color_t * color,
1018 pixman_format_code_t format)
1020 uint32_t c = color_to_uint32 (color);
1022 if (!(format == PIXMAN_a8r8g8b8 ||
1023 format == PIXMAN_x8r8g8b8 ||
1024 format == PIXMAN_a8b8g8r8 ||
1025 format == PIXMAN_x8b8g8r8 ||
1026 format == PIXMAN_b8g8r8a8 ||
1027 format == PIXMAN_b8g8r8x8 ||
1028 format == PIXMAN_r5g6b5 ||
1029 format == PIXMAN_b5g6r5 ||
1030 format == PIXMAN_a8))
1035 if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_ABGR)
1037 c = ((c & 0xff000000) >> 0) |
1038 ((c & 0x00ff0000) >> 16) |
1039 ((c & 0x0000ff00) >> 0) |
1040 ((c & 0x000000ff) << 16);
1042 if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_BGRA)
1044 c = ((c & 0xff000000) >> 24) |
1045 ((c & 0x00ff0000) >> 8) |
1046 ((c & 0x0000ff00) << 8) |
1047 ((c & 0x000000ff) << 24);
1050 if (format == PIXMAN_a8)
1052 else if (format == PIXMAN_r5g6b5 ||
1053 format == PIXMAN_b5g6r5)
1054 c = CONVERT_8888_TO_0565 (c);
1057 printf ("color: %x %x %x %x\n", color->alpha, color->red, color->green, color->blue);
1058 printf ("pixel: %x\n", c);
1065 PIXMAN_EXPORT pixman_bool_t
1066 pixman_image_fill_rectangles (pixman_op_t op,
1067 pixman_image_t * dest,
1068 pixman_color_t * color,
1070 const pixman_rectangle16_t *rects)
1072 pixman_box32_t stack_boxes[6];
1073 pixman_box32_t *boxes;
1074 pixman_bool_t result;
1079 boxes = pixman_malloc_ab (sizeof (pixman_box32_t), n_rects);
1085 boxes = stack_boxes;
1088 for (i = 0; i < n_rects; ++i)
1090 boxes[i].x1 = rects[i].x;
1091 boxes[i].y1 = rects[i].y;
1092 boxes[i].x2 = boxes[i].x1 + rects[i].width;
1093 boxes[i].y2 = boxes[i].y1 + rects[i].height;
1096 result = pixman_image_fill_boxes (op, dest, color, n_rects, boxes);
1098 if (boxes != stack_boxes)
1104 PIXMAN_EXPORT pixman_bool_t
1105 pixman_image_fill_boxes (pixman_op_t op,
1106 pixman_image_t * dest,
1107 pixman_color_t * color,
1109 const pixman_box32_t *boxes)
1111 pixman_image_t *solid;
1115 _pixman_image_validate (dest);
1117 if (color->alpha == 0xffff)
1119 if (op == PIXMAN_OP_OVER)
1123 if (op == PIXMAN_OP_CLEAR)
1135 if (op == PIXMAN_OP_SRC)
1139 if (color_to_pixel (color, &pixel, dest->bits.format))
1141 pixman_region32_t fill_region;
1143 pixman_box32_t *rects;
1145 if (!pixman_region32_init_rects (&fill_region, boxes, n_boxes))
1148 if (dest->common.have_clip_region)
1150 if (!pixman_region32_intersect (&fill_region,
1152 &dest->common.clip_region))
1156 rects = pixman_region32_rectangles (&fill_region, &n_rects);
1157 for (j = 0; j < n_rects; ++j)
1159 const pixman_box32_t *rect = &(rects[j]);
1160 pixman_fill (dest->bits.bits, dest->bits.rowstride, PIXMAN_FORMAT_BPP (dest->bits.format),
1161 rect->x1, rect->y1, rect->x2 - rect->x1, rect->y2 - rect->y1,
1165 pixman_region32_fini (&fill_region);
1170 solid = pixman_image_create_solid_fill (color);
1174 for (i = 0; i < n_boxes; ++i)
1176 const pixman_box32_t *box = &(boxes[i]);
1178 pixman_image_composite32 (op, solid, NULL, dest,
1181 box->x2 - box->x1, box->y2 - box->y1);
1184 pixman_image_unref (solid);
1192 * Returns the version of the pixman library encoded in a single
1193 * integer as per %PIXMAN_VERSION_ENCODE. The encoding ensures that
1194 * later versions compare greater than earlier versions.
1196 * A run-time comparison to check that pixman's version is greater than
1197 * or equal to version X.Y.Z could be performed as follows:
1199 * <informalexample><programlisting>
1200 * if (pixman_version() >= PIXMAN_VERSION_ENCODE(X,Y,Z)) {...}
1201 * </programlisting></informalexample>
1203 * See also pixman_version_string() as well as the compile-time
1204 * equivalents %PIXMAN_VERSION and %PIXMAN_VERSION_STRING.
1206 * Return value: the encoded version.
1209 pixman_version (void)
1211 return PIXMAN_VERSION;
1215 * pixman_version_string:
1217 * Returns the version of the pixman library as a human-readable string
1218 * of the form "X.Y.Z".
1220 * See also pixman_version() as well as the compile-time equivalents
1221 * %PIXMAN_VERSION_STRING and %PIXMAN_VERSION.
1223 * Return value: a string containing the version.
1225 PIXMAN_EXPORT const char*
1226 pixman_version_string (void)
1228 return PIXMAN_VERSION_STRING;
1232 * pixman_format_supported_source:
1233 * @format: A pixman_format_code_t format
1235 * Return value: whether the provided format code is a supported
1236 * format for a pixman surface used as a source in
1239 * Currently, all pixman_format_code_t values are supported.
1241 PIXMAN_EXPORT pixman_bool_t
1242 pixman_format_supported_source (pixman_format_code_t format)
1246 /* 32 bpp formats */
1247 case PIXMAN_a2b10g10r10:
1248 case PIXMAN_x2b10g10r10:
1249 case PIXMAN_a2r10g10b10:
1250 case PIXMAN_x2r10g10b10:
1251 case PIXMAN_a8r8g8b8:
1252 case PIXMAN_x8r8g8b8:
1253 case PIXMAN_a8b8g8r8:
1254 case PIXMAN_x8b8g8r8:
1255 case PIXMAN_b8g8r8a8:
1256 case PIXMAN_b8g8r8x8:
1261 case PIXMAN_x14r6g6b6:
1262 /* 16 bpp formats */
1263 case PIXMAN_a1r5g5b5:
1264 case PIXMAN_x1r5g5b5:
1265 case PIXMAN_a1b5g5r5:
1266 case PIXMAN_x1b5g5r5:
1267 case PIXMAN_a4r4g4b4:
1268 case PIXMAN_x4r4g4b4:
1269 case PIXMAN_a4b4g4r4:
1270 case PIXMAN_x4b4g4r4:
1275 case PIXMAN_a2r2g2b2:
1276 case PIXMAN_a2b2g2r2:
1280 /* Collides with PIXMAN_c8
1283 /* Collides with PIXMAN_g8
1290 case PIXMAN_a1r1g1b1:
1291 case PIXMAN_a1b1g1r1:
1308 * pixman_format_supported_destination:
1309 * @format: A pixman_format_code_t format
1311 * Return value: whether the provided format code is a supported
1312 * format for a pixman surface used as a destination in
1315 * Currently, all pixman_format_code_t values are supported
1316 * except for the YUV formats.
1318 PIXMAN_EXPORT pixman_bool_t
1319 pixman_format_supported_destination (pixman_format_code_t format)
1321 /* YUV formats cannot be written to at the moment */
1322 if (format == PIXMAN_yuy2 || format == PIXMAN_yv12)
1325 return pixman_format_supported_source (format);
1328 PIXMAN_EXPORT pixman_bool_t
1329 pixman_compute_composite_region (pixman_region16_t * region,
1330 pixman_image_t * src_image,
1331 pixman_image_t * mask_image,
1332 pixman_image_t * dst_image,
1342 pixman_region32_t r32;
1343 pixman_bool_t retval;
1345 pixman_region32_init (&r32);
1347 retval = pixman_compute_composite_region32 (
1348 &r32, src_image, mask_image, dst_image,
1349 src_x, src_y, mask_x, mask_y, dest_x, dest_y,
1354 if (!pixman_region16_copy_from_region32 (region, &r32))
1358 pixman_region32_fini (&r32);