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 pixman_implementation_t *imp;
35 typedef struct operator_info_t operator_info_t;
37 struct operator_info_t
39 uint8_t opaque_info[4];
42 #define PACK(neither, src, dest, both) \
43 {{ (uint8_t)PIXMAN_OP_ ## neither, \
44 (uint8_t)PIXMAN_OP_ ## src, \
45 (uint8_t)PIXMAN_OP_ ## dest, \
46 (uint8_t)PIXMAN_OP_ ## both }}
48 static const operator_info_t operator_table[] =
50 /* Neither Opaque Src Opaque Dst Opaque Both Opaque */
51 PACK (CLEAR, CLEAR, CLEAR, CLEAR),
52 PACK (SRC, SRC, SRC, SRC),
53 PACK (DST, DST, DST, DST),
54 PACK (OVER, SRC, OVER, SRC),
55 PACK (OVER_REVERSE, OVER_REVERSE, DST, DST),
56 PACK (IN, IN, SRC, SRC),
57 PACK (IN_REVERSE, DST, IN_REVERSE, DST),
58 PACK (OUT, OUT, CLEAR, CLEAR),
59 PACK (OUT_REVERSE, CLEAR, OUT_REVERSE, CLEAR),
60 PACK (ATOP, IN, OVER, SRC),
61 PACK (ATOP_REVERSE, OVER_REVERSE, IN_REVERSE, DST),
62 PACK (XOR, OUT, OUT_REVERSE, CLEAR),
63 PACK (ADD, ADD, ADD, ADD),
64 PACK (SATURATE, OVER_REVERSE, DST, DST),
69 PACK (CLEAR, CLEAR, CLEAR, CLEAR),
70 PACK (SRC, SRC, SRC, SRC),
71 PACK (DST, DST, DST, DST),
72 PACK (DISJOINT_OVER, DISJOINT_OVER, DISJOINT_OVER, DISJOINT_OVER),
73 PACK (DISJOINT_OVER_REVERSE, DISJOINT_OVER_REVERSE, DISJOINT_OVER_REVERSE, DISJOINT_OVER_REVERSE),
74 PACK (DISJOINT_IN, DISJOINT_IN, DISJOINT_IN, DISJOINT_IN),
75 PACK (DISJOINT_IN_REVERSE, DISJOINT_IN_REVERSE, DISJOINT_IN_REVERSE, DISJOINT_IN_REVERSE),
76 PACK (DISJOINT_OUT, DISJOINT_OUT, DISJOINT_OUT, DISJOINT_OUT),
77 PACK (DISJOINT_OUT_REVERSE, DISJOINT_OUT_REVERSE, DISJOINT_OUT_REVERSE, DISJOINT_OUT_REVERSE),
78 PACK (DISJOINT_ATOP, DISJOINT_ATOP, DISJOINT_ATOP, DISJOINT_ATOP),
79 PACK (DISJOINT_ATOP_REVERSE, DISJOINT_ATOP_REVERSE, DISJOINT_ATOP_REVERSE, DISJOINT_ATOP_REVERSE),
80 PACK (DISJOINT_XOR, DISJOINT_XOR, DISJOINT_XOR, DISJOINT_XOR),
87 PACK (CLEAR, CLEAR, CLEAR, CLEAR),
88 PACK (SRC, SRC, SRC, SRC),
89 PACK (DST, DST, DST, DST),
90 PACK (CONJOINT_OVER, CONJOINT_OVER, CONJOINT_OVER, CONJOINT_OVER),
91 PACK (CONJOINT_OVER_REVERSE, CONJOINT_OVER_REVERSE, CONJOINT_OVER_REVERSE, CONJOINT_OVER_REVERSE),
92 PACK (CONJOINT_IN, CONJOINT_IN, CONJOINT_IN, CONJOINT_IN),
93 PACK (CONJOINT_IN_REVERSE, CONJOINT_IN_REVERSE, CONJOINT_IN_REVERSE, CONJOINT_IN_REVERSE),
94 PACK (CONJOINT_OUT, CONJOINT_OUT, CONJOINT_OUT, CONJOINT_OUT),
95 PACK (CONJOINT_OUT_REVERSE, CONJOINT_OUT_REVERSE, CONJOINT_OUT_REVERSE, CONJOINT_OUT_REVERSE),
96 PACK (CONJOINT_ATOP, CONJOINT_ATOP, CONJOINT_ATOP, CONJOINT_ATOP),
97 PACK (CONJOINT_ATOP_REVERSE, CONJOINT_ATOP_REVERSE, CONJOINT_ATOP_REVERSE, CONJOINT_ATOP_REVERSE),
98 PACK (CONJOINT_XOR, CONJOINT_XOR, CONJOINT_XOR, CONJOINT_XOR),
105 PACK (MULTIPLY, MULTIPLY, MULTIPLY, MULTIPLY),
106 PACK (SCREEN, SCREEN, SCREEN, SCREEN),
107 PACK (OVERLAY, OVERLAY, OVERLAY, OVERLAY),
108 PACK (DARKEN, DARKEN, DARKEN, DARKEN),
109 PACK (LIGHTEN, LIGHTEN, LIGHTEN, LIGHTEN),
110 PACK (COLOR_DODGE, COLOR_DODGE, COLOR_DODGE, COLOR_DODGE),
111 PACK (COLOR_BURN, COLOR_BURN, COLOR_BURN, COLOR_BURN),
112 PACK (HARD_LIGHT, HARD_LIGHT, HARD_LIGHT, HARD_LIGHT),
113 PACK (SOFT_LIGHT, SOFT_LIGHT, SOFT_LIGHT, SOFT_LIGHT),
114 PACK (DIFFERENCE, DIFFERENCE, DIFFERENCE, DIFFERENCE),
115 PACK (EXCLUSION, EXCLUSION, EXCLUSION, EXCLUSION),
116 PACK (HSL_HUE, HSL_HUE, HSL_HUE, HSL_HUE),
117 PACK (HSL_SATURATION, HSL_SATURATION, HSL_SATURATION, HSL_SATURATION),
118 PACK (HSL_COLOR, HSL_COLOR, HSL_COLOR, HSL_COLOR),
119 PACK (HSL_LUMINOSITY, HSL_LUMINOSITY, HSL_LUMINOSITY, HSL_LUMINOSITY),
123 * Optimize the current operator based on opacity of source or destination
124 * The output operator should be mathematically equivalent to the source.
127 optimize_operator (pixman_op_t op,
132 pixman_bool_t is_source_opaque, is_dest_opaque;
135 is_source_opaque = ((src_flags & mask_flags) & FAST_PATH_IS_OPAQUE) != 0;
136 is_dest_opaque = (dst_flags & FAST_PATH_IS_OPAQUE) != 0;
138 opaqueness = ((is_dest_opaque << 1) | is_source_opaque);
140 return operator_table[op].opaque_info[opaqueness];
144 apply_workaround (pixman_image_t *image,
147 uint32_t ** save_bits,
151 if (image && (image->common.flags & FAST_PATH_NEEDS_WORKAROUND))
153 /* Some X servers generate images that point to the
154 * wrong place in memory, but then set the clip region
155 * to point to the right place. Because of an old bug
156 * in pixman, this would actually work.
158 * Here we try and undo the damage
160 int bpp = PIXMAN_FORMAT_BPP (image->bits.format) / 8;
161 pixman_box32_t *extents;
165 extents = pixman_region32_extents (&(image->common.clip_region));
169 *save_bits = image->bits.bits;
173 pixman_region32_translate (&(image->common.clip_region), -dx, -dy);
175 t = (uint8_t *)image->bits.bits;
176 t += dy * image->bits.rowstride * 4 + dx * bpp;
177 image->bits.bits = (uint32_t *)t;
185 unapply_workaround (pixman_image_t *image, uint32_t *bits, int dx, int dy)
187 if (image && (image->common.flags & FAST_PATH_NEEDS_WORKAROUND))
189 image->bits.bits = bits;
190 pixman_region32_translate (&image->common.clip_region, dx, dy);
195 * Computing composite region
197 static inline pixman_bool_t
198 clip_general_image (pixman_region32_t * region,
199 pixman_region32_t * clip,
203 if (pixman_region32_n_rects (region) == 1 &&
204 pixman_region32_n_rects (clip) == 1)
206 pixman_box32_t * rbox = pixman_region32_rectangles (region, NULL);
207 pixman_box32_t * cbox = pixman_region32_rectangles (clip, NULL);
210 if (rbox->x1 < (v = cbox->x1 + dx))
212 if (rbox->x2 > (v = cbox->x2 + dx))
214 if (rbox->y1 < (v = cbox->y1 + dy))
216 if (rbox->y2 > (v = cbox->y2 + dy))
218 if (rbox->x1 >= rbox->x2 || rbox->y1 >= rbox->y2)
220 pixman_region32_init (region);
224 else if (!pixman_region32_not_empty (clip))
231 pixman_region32_translate (region, -dx, -dy);
233 if (!pixman_region32_intersect (region, region, clip))
237 pixman_region32_translate (region, dx, dy);
240 return pixman_region32_not_empty (region);
243 static inline pixman_bool_t
244 clip_source_image (pixman_region32_t * region,
245 pixman_image_t * image,
249 /* Source clips are ignored, unless they are explicitly turned on
250 * and the clip in question was set by an X client. (Because if
251 * the clip was not set by a client, then it is a hierarchy
252 * clip and those should always be ignored for sources).
254 if (!image->common.clip_sources || !image->common.client_clip)
257 return clip_general_image (region,
258 &image->common.clip_region,
263 * returns FALSE if the final region is empty. Indistinguishable from
264 * an allocation failure, but rendering ignores those anyways.
267 pixman_compute_composite_region32 (pixman_region32_t * region,
268 pixman_image_t * src_image,
269 pixman_image_t * mask_image,
270 pixman_image_t * dst_image,
280 region->extents.x1 = dest_x;
281 region->extents.x2 = dest_x + width;
282 region->extents.y1 = dest_y;
283 region->extents.y2 = dest_y + height;
285 region->extents.x1 = MAX (region->extents.x1, 0);
286 region->extents.y1 = MAX (region->extents.y1, 0);
287 region->extents.x2 = MIN (region->extents.x2, dst_image->bits.width);
288 region->extents.y2 = MIN (region->extents.y2, dst_image->bits.height);
292 /* Check for empty operation */
293 if (region->extents.x1 >= region->extents.x2 ||
294 region->extents.y1 >= region->extents.y2)
296 pixman_region32_init (region);
300 if (dst_image->common.have_clip_region)
302 if (!clip_general_image (region, &dst_image->common.clip_region, 0, 0))
304 pixman_region32_fini (region);
309 if (dst_image->common.alpha_map && dst_image->common.alpha_map->common.have_clip_region)
311 if (!clip_general_image (region, &dst_image->common.alpha_map->common.clip_region,
312 -dst_image->common.alpha_origin_x,
313 -dst_image->common.alpha_origin_y))
315 pixman_region32_fini (region);
320 /* clip against src */
321 if (src_image->common.have_clip_region)
323 if (!clip_source_image (region, src_image, dest_x - src_x, dest_y - src_y))
325 pixman_region32_fini (region);
329 if (src_image->common.alpha_map && src_image->common.alpha_map->common.have_clip_region)
331 if (!clip_source_image (region, (pixman_image_t *)src_image->common.alpha_map,
332 dest_x - (src_x - src_image->common.alpha_origin_x),
333 dest_y - (src_y - src_image->common.alpha_origin_y)))
335 pixman_region32_fini (region);
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))
344 pixman_region32_fini (region);
347 if (mask_image->common.alpha_map && mask_image->common.alpha_map->common.have_clip_region)
349 if (!clip_source_image (region, (pixman_image_t *)mask_image->common.alpha_map,
350 dest_x - (mask_x - mask_image->common.alpha_origin_x),
351 dest_y - (mask_y - mask_image->common.alpha_origin_y)))
353 pixman_region32_fini (region);
363 walk_region_internal (pixman_implementation_t *imp,
365 pixman_image_t * src_image,
366 pixman_image_t * mask_image,
367 pixman_image_t * dst_image,
376 pixman_bool_t src_repeat,
377 pixman_bool_t mask_repeat,
378 pixman_region32_t * region,
379 pixman_composite_func_t composite_rect)
381 int w, h, w_this, h_this;
382 int x_msk, y_msk, x_src, y_src, x_dst, y_dst;
383 int src_dy = src_y - dest_y;
384 int src_dx = src_x - dest_x;
385 int mask_dy = mask_y - dest_y;
386 int mask_dx = mask_x - dest_x;
387 const pixman_box32_t *pbox;
390 pbox = pixman_region32_rectangles (region, &n);
392 /* Fast path for non-repeating sources */
393 if (!src_repeat && !mask_repeat)
397 (*composite_rect) (imp, op,
398 src_image, mask_image, dst_image,
406 pbox->y2 - pbox->y1);
416 h = pbox->y2 - pbox->y1;
417 y_src = pbox->y1 + src_dy;
418 y_msk = pbox->y1 + mask_dy;
424 w = pbox->x2 - pbox->x1;
425 x_src = pbox->x1 + src_dx;
426 x_msk = pbox->x1 + mask_dx;
431 y_msk = MOD (y_msk, mask_image->bits.height);
432 if (h_this > mask_image->bits.height - y_msk)
433 h_this = mask_image->bits.height - y_msk;
438 y_src = MOD (y_src, src_image->bits.height);
439 if (h_this > src_image->bits.height - y_src)
440 h_this = src_image->bits.height - y_src;
449 x_msk = MOD (x_msk, mask_image->bits.width);
450 if (w_this > mask_image->bits.width - x_msk)
451 w_this = mask_image->bits.width - x_msk;
456 x_src = MOD (x_src, src_image->bits.width);
457 if (w_this > src_image->bits.width - x_src)
458 w_this = src_image->bits.width - x_src;
461 (*composite_rect) (imp, op,
462 src_image, mask_image, dst_image,
463 x_src, y_src, x_msk, y_msk, x_dst, y_dst,
482 #define IS_16BIT(x) (((x) >= INT16_MIN) && ((x) <= INT16_MAX))
484 static force_inline uint32_t
485 compute_src_extents_flags (pixman_image_t *image,
486 pixman_box32_t *extents,
490 pixman_box16_t extents16;
493 flags = FAST_PATH_COVERS_CLIP;
495 if (image->common.type != BITS)
498 if (image->common.repeat == PIXMAN_REPEAT_NONE &&
499 (x > extents->x1 || y > extents->y1 ||
500 x + image->bits.width < extents->x2 ||
501 y + image->bits.height < extents->y2))
503 flags &= ~FAST_PATH_COVERS_CLIP;
506 if (IS_16BIT (extents->x1 - x) &&
507 IS_16BIT (extents->y1 - y) &&
508 IS_16BIT (extents->x2 - x) &&
509 IS_16BIT (extents->y2 - y))
511 extents16.x1 = extents->x1 - x;
512 extents16.y1 = extents->y1 - y;
513 extents16.x2 = extents->x2 - x;
514 extents16.y2 = extents->y2 - y;
516 if (!image->common.transform ||
517 pixman_transform_bounds (image->common.transform, &extents16))
519 if (extents16.x1 >= 0 && extents16.y1 >= 0 &&
520 extents16.x2 <= image->bits.width &&
521 extents16.y2 <= image->bits.height)
523 flags |= FAST_PATH_SAMPLES_COVER_CLIP;
528 if (IS_16BIT (extents->x1 - x - 1) &&
529 IS_16BIT (extents->y1 - y - 1) &&
530 IS_16BIT (extents->x2 - x + 1) &&
531 IS_16BIT (extents->y2 - y + 1))
533 extents16.x1 = extents->x1 - x - 1;
534 extents16.y1 = extents->y1 - y - 1;
535 extents16.x2 = extents->x2 - x + 1;
536 extents16.y2 = extents->y2 - y + 1;
538 if (/* src space expanded by one in dest space fits in 16 bit */
539 (!image->common.transform ||
540 pixman_transform_bounds (image->common.transform, &extents16)) &&
541 /* And src image size can be used as 16.16 fixed point */
542 image->bits.width < 0x7fff &&
543 image->bits.height < 0x7fff)
545 /* Then we're "16bit safe" */
546 flags |= FAST_PATH_16BIT_SAFE;
553 #define N_CACHED_FAST_PATHS 8
557 pixman_fast_path_t cache [N_CACHED_FAST_PATHS];
560 PIXMAN_DEFINE_THREAD_LOCAL (cache_t, fast_path_cache);
563 do_composite (pixman_implementation_t *imp,
566 pixman_image_t *mask,
567 pixman_image_t *dest,
577 pixman_format_code_t src_format, mask_format, dest_format;
578 uint32_t src_flags, mask_flags, dest_flags;
579 pixman_region32_t region;
580 pixman_box32_t *extents;
584 int mask_dx, mask_dy;
586 int dest_dx, dest_dy;
587 pixman_bool_t need_workaround;
588 const pixman_fast_path_t *info;
592 src_format = src->common.extended_format_code;
593 src_flags = src->common.flags;
597 mask_format = mask->common.extended_format_code;
598 mask_flags = mask->common.flags;
602 mask_format = PIXMAN_null;
603 mask_flags = FAST_PATH_IS_OPAQUE;
606 dest_format = dest->common.extended_format_code;
607 dest_flags = dest->common.flags;
609 /* Check for pixbufs */
610 if ((mask_format == PIXMAN_a8r8g8b8 || mask_format == PIXMAN_a8b8g8r8) &&
611 (src->type == BITS && src->bits.bits == mask->bits.bits) &&
612 (src->common.repeat == mask->common.repeat) &&
613 (src_x == mask_x && src_y == mask_y))
615 if (src_format == PIXMAN_x8b8g8r8)
616 src_format = mask_format = PIXMAN_pixbuf;
617 else if (src_format == PIXMAN_x8r8g8b8)
618 src_format = mask_format = PIXMAN_rpixbuf;
621 /* Check for workaround */
622 need_workaround = (src_flags | mask_flags | dest_flags) & FAST_PATH_NEEDS_WORKAROUND;
626 apply_workaround (src, &src_x, &src_y, &src_bits, &src_dx, &src_dy);
627 apply_workaround (mask, &mask_x, &mask_y, &mask_bits, &mask_dx, &mask_dy);
628 apply_workaround (dest, &dest_x, &dest_y, &dest_bits, &dest_dx, &dest_dy);
631 pixman_region32_init (®ion);
633 if (!pixman_compute_composite_region32 (
634 ®ion, src, mask, dest,
635 src_x, src_y, mask_x, mask_y, dest_x, dest_y, width, height))
640 extents = pixman_region32_extents (®ion);
642 src_flags |= compute_src_extents_flags (src, extents, dest_x - src_x, dest_y - src_y);
645 mask_flags |= compute_src_extents_flags (mask, extents, dest_x - mask_x, dest_y - mask_y);
648 * Check if we can replace our operator by a simpler one
649 * if the src or dest are opaque. The output operator should be
650 * mathematically equivalent to the source.
652 op = optimize_operator (op, src_flags, mask_flags, dest_flags);
653 if (op == PIXMAN_OP_DST)
656 /* Check cache for fast paths */
657 cache = PIXMAN_GET_THREAD_LOCAL (fast_path_cache);
659 for (i = 0; i < N_CACHED_FAST_PATHS; ++i)
661 info = &(cache->cache[i]);
663 /* Note that we check for equality here, not whether
664 * the cached fast path matches. This is to prevent
665 * us from selecting an overly general fast path
666 * when a more specific one would work.
668 if (info->op == op &&
669 info->src_format == src_format &&
670 info->mask_format == mask_format &&
671 info->dest_format == dest_format &&
672 info->src_flags == src_flags &&
673 info->mask_flags == mask_flags &&
674 info->dest_flags == dest_flags &&
683 info = imp->fast_paths;
685 while (info->op != PIXMAN_OP_NONE)
687 if ((info->op == op || info->op == PIXMAN_OP_any) &&
689 ((info->src_format == src_format) ||
690 (info->src_format == PIXMAN_any)) &&
691 ((info->mask_format == mask_format) ||
692 (info->mask_format == PIXMAN_any)) &&
693 ((info->dest_format == dest_format) ||
694 (info->dest_format == PIXMAN_any)) &&
696 (info->src_flags & src_flags) == info->src_flags &&
697 (info->mask_flags & mask_flags) == info->mask_flags &&
698 (info->dest_flags & dest_flags) == info->dest_flags)
700 /* Set i to the last spot in the cache so that the
701 * move-to-front code below will work
703 i = N_CACHED_FAST_PATHS - 1;
714 /* We didn't find a compositing routine. This should not happen, but if
715 * it somehow does, just exit rather than crash.
720 walk_region_internal (imp, op,
722 src_x, src_y, mask_x, mask_y,
725 (src_flags & FAST_PATH_SIMPLE_REPEAT),
726 (mask_flags & FAST_PATH_SIMPLE_REPEAT),
727 ®ion, info->func);
731 /* Make a copy of info->func, because info->func may change when
732 * we update the cache.
734 pixman_composite_func_t func = info->func;
737 cache->cache[i + 1] = cache->cache[i];
739 cache->cache[0].op = op;
740 cache->cache[0].src_format = src_format;
741 cache->cache[0].src_flags = src_flags;
742 cache->cache[0].mask_format = mask_format;
743 cache->cache[0].mask_flags = mask_flags;
744 cache->cache[0].dest_format = dest_format;
745 cache->cache[0].dest_flags = dest_flags;
746 cache->cache[0].func = func;
752 unapply_workaround (src, src_bits, src_dx, src_dy);
753 unapply_workaround (mask, mask_bits, mask_dx, mask_dy);
754 unapply_workaround (dest, dest_bits, dest_dx, dest_dy);
757 pixman_region32_fini (®ion);
761 pixman_image_composite (pixman_op_t op,
762 pixman_image_t * src,
763 pixman_image_t * mask,
764 pixman_image_t * dest,
774 pixman_image_composite32 (op, src, mask, dest, src_x, src_y,
775 mask_x, mask_y, dest_x, dest_y, width, height);
779 * Work around GCC bug causing crashes in Mozilla with SSE2
781 * When using -msse, gcc generates movdqa instructions assuming that
782 * the stack is 16 byte aligned. Unfortunately some applications, such
783 * as Mozilla and Mono, end up aligning the stack to 4 bytes, which
784 * causes the movdqa instructions to fail.
786 * The __force_align_arg_pointer__ makes gcc generate a prologue that
787 * realigns the stack pointer to 16 bytes.
789 * On x86-64 this is not necessary because the standard ABI already
790 * calls for a 16 byte aligned stack.
792 * See https://bugs.freedesktop.org/show_bug.cgi?id=15693
794 #if defined (USE_SSE2) && defined(__GNUC__) && !defined(__x86_64__) && !defined(__amd64__)
795 __attribute__((__force_align_arg_pointer__))
798 pixman_image_composite32 (pixman_op_t op,
799 pixman_image_t * src,
800 pixman_image_t * mask,
801 pixman_image_t * dest,
811 _pixman_image_validate (src);
813 _pixman_image_validate (mask);
814 _pixman_image_validate (dest);
817 imp = _pixman_choose_implementation ();
819 do_composite (imp, op,
827 PIXMAN_EXPORT pixman_bool_t
828 pixman_blt (uint32_t *src_bits,
842 imp = _pixman_choose_implementation ();
844 return _pixman_implementation_blt (imp, src_bits, dst_bits, src_stride, dst_stride,
851 PIXMAN_EXPORT pixman_bool_t
852 pixman_fill (uint32_t *bits,
862 imp = _pixman_choose_implementation ();
864 return _pixman_implementation_fill (imp, bits, stride, bpp, x, y, width, height, xor);
868 color_to_uint32 (const pixman_color_t *color)
871 (color->alpha >> 8 << 24) |
872 (color->red >> 8 << 16) |
873 (color->green & 0xff00) |
878 color_to_pixel (pixman_color_t * color,
880 pixman_format_code_t format)
882 uint32_t c = color_to_uint32 (color);
884 if (!(format == PIXMAN_a8r8g8b8 ||
885 format == PIXMAN_x8r8g8b8 ||
886 format == PIXMAN_a8b8g8r8 ||
887 format == PIXMAN_x8b8g8r8 ||
888 format == PIXMAN_b8g8r8a8 ||
889 format == PIXMAN_b8g8r8x8 ||
890 format == PIXMAN_r5g6b5 ||
891 format == PIXMAN_b5g6r5 ||
892 format == PIXMAN_a8))
897 if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_ABGR)
899 c = ((c & 0xff000000) >> 0) |
900 ((c & 0x00ff0000) >> 16) |
901 ((c & 0x0000ff00) >> 0) |
902 ((c & 0x000000ff) << 16);
904 if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_BGRA)
906 c = ((c & 0xff000000) >> 24) |
907 ((c & 0x00ff0000) >> 8) |
908 ((c & 0x0000ff00) << 8) |
909 ((c & 0x000000ff) << 24);
912 if (format == PIXMAN_a8)
914 else if (format == PIXMAN_r5g6b5 ||
915 format == PIXMAN_b5g6r5)
916 c = CONVERT_8888_TO_0565 (c);
919 printf ("color: %x %x %x %x\n", color->alpha, color->red, color->green, color->blue);
920 printf ("pixel: %x\n", c);
927 PIXMAN_EXPORT pixman_bool_t
928 pixman_image_fill_rectangles (pixman_op_t op,
929 pixman_image_t * dest,
930 pixman_color_t * color,
932 const pixman_rectangle16_t *rects)
934 pixman_box32_t stack_boxes[6];
935 pixman_box32_t *boxes;
936 pixman_bool_t result;
941 boxes = pixman_malloc_ab (sizeof (pixman_box32_t), n_rects);
950 for (i = 0; i < n_rects; ++i)
952 boxes[i].x1 = rects[i].x;
953 boxes[i].y1 = rects[i].y;
954 boxes[i].x2 = boxes[i].x1 + rects[i].width;
955 boxes[i].y2 = boxes[i].y1 + rects[i].height;
958 result = pixman_image_fill_boxes (op, dest, color, n_rects, boxes);
960 if (boxes != stack_boxes)
966 PIXMAN_EXPORT pixman_bool_t
967 pixman_image_fill_boxes (pixman_op_t op,
968 pixman_image_t * dest,
969 pixman_color_t * color,
971 const pixman_box32_t *boxes)
973 pixman_image_t *solid;
977 _pixman_image_validate (dest);
979 if (color->alpha == 0xffff)
981 if (op == PIXMAN_OP_OVER)
985 if (op == PIXMAN_OP_CLEAR)
997 if (op == PIXMAN_OP_SRC)
1001 if (color_to_pixel (color, &pixel, dest->bits.format))
1003 pixman_region32_t fill_region;
1005 pixman_box32_t *rects;
1007 if (!pixman_region32_init_rects (&fill_region, boxes, n_boxes))
1010 if (dest->common.have_clip_region)
1012 if (!pixman_region32_intersect (&fill_region,
1014 &dest->common.clip_region))
1018 rects = pixman_region32_rectangles (&fill_region, &n_rects);
1019 for (j = 0; j < n_rects; ++j)
1021 const pixman_box32_t *rect = &(rects[j]);
1022 pixman_fill (dest->bits.bits, dest->bits.rowstride, PIXMAN_FORMAT_BPP (dest->bits.format),
1023 rect->x1, rect->y1, rect->x2 - rect->x1, rect->y2 - rect->y1,
1027 pixman_region32_fini (&fill_region);
1032 solid = pixman_image_create_solid_fill (color);
1036 for (i = 0; i < n_boxes; ++i)
1038 const pixman_box32_t *box = &(boxes[i]);
1040 pixman_image_composite32 (op, solid, NULL, dest,
1043 box->x2 - box->x1, box->y2 - box->y1);
1046 pixman_image_unref (solid);
1054 * Returns the version of the pixman library encoded in a single
1055 * integer as per %PIXMAN_VERSION_ENCODE. The encoding ensures that
1056 * later versions compare greater than earlier versions.
1058 * A run-time comparison to check that pixman's version is greater than
1059 * or equal to version X.Y.Z could be performed as follows:
1061 * <informalexample><programlisting>
1062 * if (pixman_version() >= PIXMAN_VERSION_ENCODE(X,Y,Z)) {...}
1063 * </programlisting></informalexample>
1065 * See also pixman_version_string() as well as the compile-time
1066 * equivalents %PIXMAN_VERSION and %PIXMAN_VERSION_STRING.
1068 * Return value: the encoded version.
1071 pixman_version (void)
1073 return PIXMAN_VERSION;
1077 * pixman_version_string:
1079 * Returns the version of the pixman library as a human-readable string
1080 * of the form "X.Y.Z".
1082 * See also pixman_version() as well as the compile-time equivalents
1083 * %PIXMAN_VERSION_STRING and %PIXMAN_VERSION.
1085 * Return value: a string containing the version.
1087 PIXMAN_EXPORT const char*
1088 pixman_version_string (void)
1090 return PIXMAN_VERSION_STRING;
1094 * pixman_format_supported_source:
1095 * @format: A pixman_format_code_t format
1097 * Return value: whether the provided format code is a supported
1098 * format for a pixman surface used as a source in
1101 * Currently, all pixman_format_code_t values are supported.
1103 PIXMAN_EXPORT pixman_bool_t
1104 pixman_format_supported_source (pixman_format_code_t format)
1108 /* 32 bpp formats */
1109 case PIXMAN_a2b10g10r10:
1110 case PIXMAN_x2b10g10r10:
1111 case PIXMAN_a2r10g10b10:
1112 case PIXMAN_x2r10g10b10:
1113 case PIXMAN_a8r8g8b8:
1114 case PIXMAN_x8r8g8b8:
1115 case PIXMAN_a8b8g8r8:
1116 case PIXMAN_x8b8g8r8:
1117 case PIXMAN_b8g8r8a8:
1118 case PIXMAN_b8g8r8x8:
1123 /* 16 bpp formats */
1124 case PIXMAN_a1r5g5b5:
1125 case PIXMAN_x1r5g5b5:
1126 case PIXMAN_a1b5g5r5:
1127 case PIXMAN_x1b5g5r5:
1128 case PIXMAN_a4r4g4b4:
1129 case PIXMAN_x4r4g4b4:
1130 case PIXMAN_a4b4g4r4:
1131 case PIXMAN_x4b4g4r4:
1136 case PIXMAN_a2r2g2b2:
1137 case PIXMAN_a2b2g2r2:
1141 /* Collides with PIXMAN_c8
1144 /* Collides with PIXMAN_g8
1151 case PIXMAN_a1r1g1b1:
1152 case PIXMAN_a1b1g1r1:
1169 * pixman_format_supported_destination:
1170 * @format: A pixman_format_code_t format
1172 * Return value: whether the provided format code is a supported
1173 * format for a pixman surface used as a destination in
1176 * Currently, all pixman_format_code_t values are supported
1177 * except for the YUV formats.
1179 PIXMAN_EXPORT pixman_bool_t
1180 pixman_format_supported_destination (pixman_format_code_t format)
1182 /* YUV formats cannot be written to at the moment */
1183 if (format == PIXMAN_yuy2 || format == PIXMAN_yv12)
1186 return pixman_format_supported_source (format);
1189 PIXMAN_EXPORT pixman_bool_t
1190 pixman_compute_composite_region (pixman_region16_t * region,
1191 pixman_image_t * src_image,
1192 pixman_image_t * mask_image,
1193 pixman_image_t * dst_image,
1203 pixman_region32_t r32;
1204 pixman_bool_t retval;
1206 pixman_region32_init (&r32);
1208 retval = pixman_compute_composite_region32 (
1209 &r32, src_image, mask_image, dst_image,
1210 src_x, src_y, mask_x, mask_y, dest_x, dest_y,
1215 if (!pixman_region16_copy_from_region32 (region, &r32))
1219 pixman_region32_fini (&r32);