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;
617 tx1 = ty1 = tx2 = ty2 = 0;
619 for (i = 0; i < 4; ++i)
621 pixman_fixed_48_16_t tx, ty;
624 v.vector[0] = (i & 0x01)? x1 : x2;
625 v.vector[1] = (i & 0x02)? y1 : y2;
626 v.vector[2] = pixman_fixed_1;
628 if (!pixman_transform_point (transform, &v))
631 tx = (pixman_fixed_48_16_t)v.vector[0];
632 ty = (pixman_fixed_48_16_t)v.vector[1];
655 /* Expand the source area by a tiny bit so account of different rounding that
656 * may happen during sampling. Note that (8 * pixman_fixed_e) is very far from
657 * 0.5 so this won't cause the area computed to be overly pessimistic.
659 tx1 += x_off - 8 * pixman_fixed_e;
660 ty1 += y_off - 8 * pixman_fixed_e;
661 tx2 += x_off + width + 8 * pixman_fixed_e;
662 ty2 += y_off + height + 8 * pixman_fixed_e;
664 if (tx1 < pixman_min_fixed_48_16 || tx1 > pixman_max_fixed_48_16 ||
665 ty1 < pixman_min_fixed_48_16 || ty1 > pixman_max_fixed_48_16 ||
666 tx2 < pixman_min_fixed_48_16 || tx2 > pixman_max_fixed_48_16 ||
667 ty2 < pixman_min_fixed_48_16 || ty2 > pixman_max_fixed_48_16)
673 extents->x1 = pixman_fixed_to_int (tx1);
674 extents->y1 = pixman_fixed_to_int (ty1);
675 extents->x2 = pixman_fixed_to_int (tx2) + 1;
676 extents->y2 = pixman_fixed_to_int (ty2) + 1;
682 #define IS_16BIT(x) (((x) >= INT16_MIN) && ((x) <= INT16_MAX))
685 analyze_extent (pixman_image_t *image, int x, int y,
686 const pixman_box32_t *extents, uint32_t *flags)
688 pixman_transform_t *transform;
689 pixman_fixed_t *params;
690 pixman_fixed_t x_off, y_off;
691 pixman_fixed_t width, height;
694 *flags |= FAST_PATH_COVERS_CLIP;
698 transform = image->common.transform;
699 if (image->common.type == BITS)
701 /* During repeat mode calculations we might convert the
702 * width/height of an image to fixed 16.16, so we need
703 * them to be smaller than 16 bits.
705 if (image->bits.width >= 0x7fff || image->bits.height >= 0x7fff)
708 if (image->common.repeat == PIXMAN_REPEAT_NONE &&
709 (x > extents->x1 || y > extents->y1 ||
710 x + image->bits.width < extents->x2 ||
711 y + image->bits.height < extents->y2))
713 (*flags) &= ~FAST_PATH_COVERS_CLIP;
717 /* Some compositing functions walk one step
718 * outside the destination rectangle, so we
719 * check here that the expanded-by-one source
720 * extents in destination space fits in 16 bits
722 if (!IS_16BIT (extents->x1 - x - 1) ||
723 !IS_16BIT (extents->y1 - y - 1) ||
724 !IS_16BIT (extents->x2 - x + 1) ||
725 !IS_16BIT (extents->y2 - y + 1))
730 if (image->common.type == BITS)
732 switch (image->common.filter)
734 case PIXMAN_FILTER_CONVOLUTION:
735 params = image->common.filter_params;
736 x_off = - pixman_fixed_e - ((params[0] - pixman_fixed_1) >> 1);
737 y_off = - pixman_fixed_e - ((params[1] - pixman_fixed_1) >> 1);
742 case PIXMAN_FILTER_GOOD:
743 case PIXMAN_FILTER_BEST:
744 case PIXMAN_FILTER_BILINEAR:
745 x_off = - pixman_fixed_1 / 2;
746 y_off = - pixman_fixed_1 / 2;
747 width = pixman_fixed_1;
748 height = pixman_fixed_1;
751 case PIXMAN_FILTER_FAST:
752 case PIXMAN_FILTER_NEAREST:
753 x_off = - pixman_fixed_e;
754 y_off = - pixman_fixed_e;
771 /* Check that the extents expanded by one don't overflow. This ensures that
772 * compositing functions can simply walk the source space using 16.16 variables
773 * without worrying about overflow.
775 ex.x1 = extents->x1 - 1;
776 ex.y1 = extents->y1 - 1;
777 ex.x2 = extents->x2 + 1;
778 ex.y2 = extents->y2 + 1;
780 if (!compute_sample_extents (transform, &ex, x, y, x_off, y_off, width, height))
783 if (image->type == BITS)
785 /* Check whether the non-expanded, transformed extent is entirely within
786 * the source image, and set the FAST_PATH_SAMPLES_COVER_CLIP if it is.
789 if (compute_sample_extents (transform, &ex, x, y, x_off, y_off, width, height))
791 if (ex.x1 >= 0 && ex.y1 >= 0 && ex.x2 <= image->bits.width && ex.y2 <= image->bits.height)
792 *flags |= FAST_PATH_SAMPLES_COVER_CLIP;
800 * Work around GCC bug causing crashes in Mozilla with SSE2
802 * When using -msse, gcc generates movdqa instructions assuming that
803 * the stack is 16 byte aligned. Unfortunately some applications, such
804 * as Mozilla and Mono, end up aligning the stack to 4 bytes, which
805 * causes the movdqa instructions to fail.
807 * The __force_align_arg_pointer__ makes gcc generate a prologue that
808 * realigns the stack pointer to 16 bytes.
810 * On x86-64 this is not necessary because the standard ABI already
811 * calls for a 16 byte aligned stack.
813 * See https://bugs.freedesktop.org/show_bug.cgi?id=15693
815 #if defined (USE_SSE2) && defined(__GNUC__) && !defined(__x86_64__) && !defined(__amd64__)
816 __attribute__((__force_align_arg_pointer__))
819 pixman_image_composite32 (pixman_op_t op,
820 pixman_image_t * src,
821 pixman_image_t * mask,
822 pixman_image_t * dest,
832 pixman_format_code_t src_format, mask_format, dest_format;
833 uint32_t src_flags, mask_flags, dest_flags;
834 pixman_region32_t region;
835 pixman_box32_t *extents;
839 int mask_dx, mask_dy;
841 int dest_dx, dest_dy;
842 pixman_bool_t need_workaround;
843 pixman_implementation_t *imp;
844 pixman_composite_func_t func;
846 _pixman_image_validate (src);
848 _pixman_image_validate (mask);
849 _pixman_image_validate (dest);
851 src_format = src->common.extended_format_code;
852 src_flags = src->common.flags;
856 mask_format = mask->common.extended_format_code;
857 mask_flags = mask->common.flags;
861 mask_format = PIXMAN_null;
862 mask_flags = FAST_PATH_IS_OPAQUE;
865 dest_format = dest->common.extended_format_code;
866 dest_flags = dest->common.flags;
868 /* Check for pixbufs */
869 if ((mask_format == PIXMAN_a8r8g8b8 || mask_format == PIXMAN_a8b8g8r8) &&
870 (src->type == BITS && src->bits.bits == mask->bits.bits) &&
871 (src->common.repeat == mask->common.repeat) &&
872 (src_x == mask_x && src_y == mask_y))
874 if (src_format == PIXMAN_x8b8g8r8)
875 src_format = mask_format = PIXMAN_pixbuf;
876 else if (src_format == PIXMAN_x8r8g8b8)
877 src_format = mask_format = PIXMAN_rpixbuf;
880 /* Check for workaround */
881 need_workaround = (src_flags | mask_flags | dest_flags) & FAST_PATH_NEEDS_WORKAROUND;
885 apply_workaround (src, &src_x, &src_y, &src_bits, &src_dx, &src_dy);
886 apply_workaround (mask, &mask_x, &mask_y, &mask_bits, &mask_dx, &mask_dy);
887 apply_workaround (dest, &dest_x, &dest_y, &dest_bits, &dest_dx, &dest_dy);
890 pixman_region32_init (®ion);
892 if (!pixman_compute_composite_region32 (
893 ®ion, src, mask, dest,
894 src_x, src_y, mask_x, mask_y, dest_x, dest_y, width, height))
899 extents = pixman_region32_extents (®ion);
901 if (!analyze_extent (src, dest_x - src_x, dest_y - src_y, extents, &src_flags))
904 if (!analyze_extent (mask, dest_x - mask_x, dest_y - mask_y, extents, &mask_flags))
907 /* If the clip is within the source samples, and the samples are opaque,
908 * then the source is effectively opaque.
910 #define BOTH (FAST_PATH_SAMPLES_OPAQUE | FAST_PATH_SAMPLES_COVER_CLIP)
912 if ((src_flags & BOTH) == BOTH)
913 src_flags |= FAST_PATH_IS_OPAQUE;
915 if ((mask_flags & BOTH) == BOTH)
916 mask_flags |= FAST_PATH_IS_OPAQUE;
919 * Check if we can replace our operator by a simpler one
920 * if the src or dest are opaque. The output operator should be
921 * mathematically equivalent to the source.
923 op = optimize_operator (op, src_flags, mask_flags, dest_flags);
924 if (op == PIXMAN_OP_DST)
927 if (lookup_composite_function (op,
928 src_format, src_flags,
929 mask_format, mask_flags,
930 dest_format, dest_flags,
933 walk_region_internal (imp, op,
935 src_x, src_y, mask_x, mask_y,
938 (src_flags & FAST_PATH_SIMPLE_REPEAT),
939 (mask_flags & FAST_PATH_SIMPLE_REPEAT),
946 unapply_workaround (src, src_bits, src_dx, src_dy);
947 unapply_workaround (mask, mask_bits, mask_dx, mask_dy);
948 unapply_workaround (dest, dest_bits, dest_dx, dest_dy);
951 pixman_region32_fini (®ion);
955 pixman_image_composite (pixman_op_t op,
956 pixman_image_t * src,
957 pixman_image_t * mask,
958 pixman_image_t * dest,
968 pixman_image_composite32 (op, src, mask, dest, src_x, src_y,
969 mask_x, mask_y, dest_x, dest_y, width, height);
972 PIXMAN_EXPORT pixman_bool_t
973 pixman_blt (uint32_t *src_bits,
986 return _pixman_implementation_blt (get_implementation(),
987 src_bits, dst_bits, src_stride, dst_stride,
994 PIXMAN_EXPORT pixman_bool_t
995 pixman_fill (uint32_t *bits,
1004 return _pixman_implementation_fill (
1005 get_implementation(), bits, stride, bpp, x, y, width, height, xor);
1009 color_to_uint32 (const pixman_color_t *color)
1012 (color->alpha >> 8 << 24) |
1013 (color->red >> 8 << 16) |
1014 (color->green & 0xff00) |
1018 static pixman_bool_t
1019 color_to_pixel (pixman_color_t * color,
1021 pixman_format_code_t format)
1023 uint32_t c = color_to_uint32 (color);
1025 if (!(format == PIXMAN_a8r8g8b8 ||
1026 format == PIXMAN_x8r8g8b8 ||
1027 format == PIXMAN_a8b8g8r8 ||
1028 format == PIXMAN_x8b8g8r8 ||
1029 format == PIXMAN_b8g8r8a8 ||
1030 format == PIXMAN_b8g8r8x8 ||
1031 format == PIXMAN_r5g6b5 ||
1032 format == PIXMAN_b5g6r5 ||
1033 format == PIXMAN_a8))
1038 if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_ABGR)
1040 c = ((c & 0xff000000) >> 0) |
1041 ((c & 0x00ff0000) >> 16) |
1042 ((c & 0x0000ff00) >> 0) |
1043 ((c & 0x000000ff) << 16);
1045 if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_BGRA)
1047 c = ((c & 0xff000000) >> 24) |
1048 ((c & 0x00ff0000) >> 8) |
1049 ((c & 0x0000ff00) << 8) |
1050 ((c & 0x000000ff) << 24);
1053 if (format == PIXMAN_a8)
1055 else if (format == PIXMAN_r5g6b5 ||
1056 format == PIXMAN_b5g6r5)
1057 c = CONVERT_8888_TO_0565 (c);
1060 printf ("color: %x %x %x %x\n", color->alpha, color->red, color->green, color->blue);
1061 printf ("pixel: %x\n", c);
1068 PIXMAN_EXPORT pixman_bool_t
1069 pixman_image_fill_rectangles (pixman_op_t op,
1070 pixman_image_t * dest,
1071 pixman_color_t * color,
1073 const pixman_rectangle16_t *rects)
1075 pixman_box32_t stack_boxes[6];
1076 pixman_box32_t *boxes;
1077 pixman_bool_t result;
1082 boxes = pixman_malloc_ab (sizeof (pixman_box32_t), n_rects);
1088 boxes = stack_boxes;
1091 for (i = 0; i < n_rects; ++i)
1093 boxes[i].x1 = rects[i].x;
1094 boxes[i].y1 = rects[i].y;
1095 boxes[i].x2 = boxes[i].x1 + rects[i].width;
1096 boxes[i].y2 = boxes[i].y1 + rects[i].height;
1099 result = pixman_image_fill_boxes (op, dest, color, n_rects, boxes);
1101 if (boxes != stack_boxes)
1107 PIXMAN_EXPORT pixman_bool_t
1108 pixman_image_fill_boxes (pixman_op_t op,
1109 pixman_image_t * dest,
1110 pixman_color_t * color,
1112 const pixman_box32_t *boxes)
1114 pixman_image_t *solid;
1118 _pixman_image_validate (dest);
1120 if (color->alpha == 0xffff)
1122 if (op == PIXMAN_OP_OVER)
1126 if (op == PIXMAN_OP_CLEAR)
1138 if (op == PIXMAN_OP_SRC)
1142 if (color_to_pixel (color, &pixel, dest->bits.format))
1144 pixman_region32_t fill_region;
1146 pixman_box32_t *rects;
1148 if (!pixman_region32_init_rects (&fill_region, boxes, n_boxes))
1151 if (dest->common.have_clip_region)
1153 if (!pixman_region32_intersect (&fill_region,
1155 &dest->common.clip_region))
1159 rects = pixman_region32_rectangles (&fill_region, &n_rects);
1160 for (j = 0; j < n_rects; ++j)
1162 const pixman_box32_t *rect = &(rects[j]);
1163 pixman_fill (dest->bits.bits, dest->bits.rowstride, PIXMAN_FORMAT_BPP (dest->bits.format),
1164 rect->x1, rect->y1, rect->x2 - rect->x1, rect->y2 - rect->y1,
1168 pixman_region32_fini (&fill_region);
1173 solid = pixman_image_create_solid_fill (color);
1177 for (i = 0; i < n_boxes; ++i)
1179 const pixman_box32_t *box = &(boxes[i]);
1181 pixman_image_composite32 (op, solid, NULL, dest,
1184 box->x2 - box->x1, box->y2 - box->y1);
1187 pixman_image_unref (solid);
1195 * Returns the version of the pixman library encoded in a single
1196 * integer as per %PIXMAN_VERSION_ENCODE. The encoding ensures that
1197 * later versions compare greater than earlier versions.
1199 * A run-time comparison to check that pixman's version is greater than
1200 * or equal to version X.Y.Z could be performed as follows:
1202 * <informalexample><programlisting>
1203 * if (pixman_version() >= PIXMAN_VERSION_ENCODE(X,Y,Z)) {...}
1204 * </programlisting></informalexample>
1206 * See also pixman_version_string() as well as the compile-time
1207 * equivalents %PIXMAN_VERSION and %PIXMAN_VERSION_STRING.
1209 * Return value: the encoded version.
1212 pixman_version (void)
1214 return PIXMAN_VERSION;
1218 * pixman_version_string:
1220 * Returns the version of the pixman library as a human-readable string
1221 * of the form "X.Y.Z".
1223 * See also pixman_version() as well as the compile-time equivalents
1224 * %PIXMAN_VERSION_STRING and %PIXMAN_VERSION.
1226 * Return value: a string containing the version.
1228 PIXMAN_EXPORT const char*
1229 pixman_version_string (void)
1231 return PIXMAN_VERSION_STRING;
1235 * pixman_format_supported_source:
1236 * @format: A pixman_format_code_t format
1238 * Return value: whether the provided format code is a supported
1239 * format for a pixman surface used as a source in
1242 * Currently, all pixman_format_code_t values are supported.
1244 PIXMAN_EXPORT pixman_bool_t
1245 pixman_format_supported_source (pixman_format_code_t format)
1249 /* 32 bpp formats */
1250 case PIXMAN_a2b10g10r10:
1251 case PIXMAN_x2b10g10r10:
1252 case PIXMAN_a2r10g10b10:
1253 case PIXMAN_x2r10g10b10:
1254 case PIXMAN_a8r8g8b8:
1255 case PIXMAN_x8r8g8b8:
1256 case PIXMAN_a8b8g8r8:
1257 case PIXMAN_x8b8g8r8:
1258 case PIXMAN_b8g8r8a8:
1259 case PIXMAN_b8g8r8x8:
1264 case PIXMAN_x14r6g6b6:
1265 /* 16 bpp formats */
1266 case PIXMAN_a1r5g5b5:
1267 case PIXMAN_x1r5g5b5:
1268 case PIXMAN_a1b5g5r5:
1269 case PIXMAN_x1b5g5r5:
1270 case PIXMAN_a4r4g4b4:
1271 case PIXMAN_x4r4g4b4:
1272 case PIXMAN_a4b4g4r4:
1273 case PIXMAN_x4b4g4r4:
1278 case PIXMAN_a2r2g2b2:
1279 case PIXMAN_a2b2g2r2:
1283 /* Collides with PIXMAN_c8
1286 /* Collides with PIXMAN_g8
1293 case PIXMAN_a1r1g1b1:
1294 case PIXMAN_a1b1g1r1:
1311 * pixman_format_supported_destination:
1312 * @format: A pixman_format_code_t format
1314 * Return value: whether the provided format code is a supported
1315 * format for a pixman surface used as a destination in
1318 * Currently, all pixman_format_code_t values are supported
1319 * except for the YUV formats.
1321 PIXMAN_EXPORT pixman_bool_t
1322 pixman_format_supported_destination (pixman_format_code_t format)
1324 /* YUV formats cannot be written to at the moment */
1325 if (format == PIXMAN_yuy2 || format == PIXMAN_yv12)
1328 return pixman_format_supported_source (format);
1331 PIXMAN_EXPORT pixman_bool_t
1332 pixman_compute_composite_region (pixman_region16_t * region,
1333 pixman_image_t * src_image,
1334 pixman_image_t * mask_image,
1335 pixman_image_t * dst_image,
1345 pixman_region32_t r32;
1346 pixman_bool_t retval;
1348 pixman_region32_init (&r32);
1350 retval = pixman_compute_composite_region32 (
1351 &r32, src_image, mask_image, dst_image,
1352 src_x, src_y, mask_x, mask_y, dest_x, dest_y,
1357 if (!pixman_region16_copy_from_region32 (region, &r32))
1361 pixman_region32_fini (&r32);