1 /* -*- Mode: c; c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t; -*- */
3 * Copyright © 2000 SuSE, Inc.
4 * Copyright © 2007 Red Hat, Inc.
6 * Permission to use, copy, modify, distribute, and sell this software and its
7 * documentation for any purpose is hereby granted without fee, provided that
8 * the above copyright notice appear in all copies and that both that
9 * copyright notice and this permission notice appear in supporting
10 * documentation, and that the name of SuSE not be used in advertising or
11 * publicity pertaining to distribution of the software without specific,
12 * written prior permission. SuSE makes no representations about the
13 * suitability of this software for any purpose. It is provided "as is"
14 * without express or implied warranty.
16 * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
18 * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
20 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
21 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23 * Author: Keith Packard, SuSE, Inc.
29 #include "pixman-private.h"
33 static force_inline pixman_implementation_t *
34 get_implementation (void)
36 static pixman_implementation_t *global_implementation;
38 if (!global_implementation)
39 global_implementation = _pixman_choose_implementation ();
41 return global_implementation;
44 typedef struct operator_info_t operator_info_t;
46 struct operator_info_t
48 uint8_t opaque_info[4];
51 #define PACK(neither, src, dest, both) \
52 {{ (uint8_t)PIXMAN_OP_ ## neither, \
53 (uint8_t)PIXMAN_OP_ ## src, \
54 (uint8_t)PIXMAN_OP_ ## dest, \
55 (uint8_t)PIXMAN_OP_ ## both }}
57 static const operator_info_t operator_table[] =
59 /* Neither Opaque Src Opaque Dst Opaque Both Opaque */
60 PACK (CLEAR, CLEAR, CLEAR, CLEAR),
61 PACK (SRC, SRC, SRC, SRC),
62 PACK (DST, DST, DST, DST),
63 PACK (OVER, SRC, OVER, SRC),
64 PACK (OVER_REVERSE, OVER_REVERSE, DST, DST),
65 PACK (IN, IN, SRC, SRC),
66 PACK (IN_REVERSE, DST, IN_REVERSE, DST),
67 PACK (OUT, OUT, CLEAR, CLEAR),
68 PACK (OUT_REVERSE, CLEAR, OUT_REVERSE, CLEAR),
69 PACK (ATOP, IN, OVER, SRC),
70 PACK (ATOP_REVERSE, OVER_REVERSE, IN_REVERSE, DST),
71 PACK (XOR, OUT, OUT_REVERSE, CLEAR),
72 PACK (ADD, ADD, ADD, ADD),
73 PACK (SATURATE, OVER_REVERSE, DST, DST),
78 PACK (CLEAR, CLEAR, CLEAR, CLEAR),
79 PACK (SRC, SRC, SRC, SRC),
80 PACK (DST, DST, DST, DST),
81 PACK (DISJOINT_OVER, DISJOINT_OVER, DISJOINT_OVER, DISJOINT_OVER),
82 PACK (DISJOINT_OVER_REVERSE, DISJOINT_OVER_REVERSE, DISJOINT_OVER_REVERSE, DISJOINT_OVER_REVERSE),
83 PACK (DISJOINT_IN, DISJOINT_IN, DISJOINT_IN, DISJOINT_IN),
84 PACK (DISJOINT_IN_REVERSE, DISJOINT_IN_REVERSE, DISJOINT_IN_REVERSE, DISJOINT_IN_REVERSE),
85 PACK (DISJOINT_OUT, DISJOINT_OUT, DISJOINT_OUT, DISJOINT_OUT),
86 PACK (DISJOINT_OUT_REVERSE, DISJOINT_OUT_REVERSE, DISJOINT_OUT_REVERSE, DISJOINT_OUT_REVERSE),
87 PACK (DISJOINT_ATOP, DISJOINT_ATOP, DISJOINT_ATOP, DISJOINT_ATOP),
88 PACK (DISJOINT_ATOP_REVERSE, DISJOINT_ATOP_REVERSE, DISJOINT_ATOP_REVERSE, DISJOINT_ATOP_REVERSE),
89 PACK (DISJOINT_XOR, DISJOINT_XOR, DISJOINT_XOR, DISJOINT_XOR),
96 PACK (CLEAR, CLEAR, CLEAR, CLEAR),
97 PACK (SRC, SRC, SRC, SRC),
98 PACK (DST, DST, DST, DST),
99 PACK (CONJOINT_OVER, CONJOINT_OVER, CONJOINT_OVER, CONJOINT_OVER),
100 PACK (CONJOINT_OVER_REVERSE, CONJOINT_OVER_REVERSE, CONJOINT_OVER_REVERSE, CONJOINT_OVER_REVERSE),
101 PACK (CONJOINT_IN, CONJOINT_IN, CONJOINT_IN, CONJOINT_IN),
102 PACK (CONJOINT_IN_REVERSE, CONJOINT_IN_REVERSE, CONJOINT_IN_REVERSE, CONJOINT_IN_REVERSE),
103 PACK (CONJOINT_OUT, CONJOINT_OUT, CONJOINT_OUT, CONJOINT_OUT),
104 PACK (CONJOINT_OUT_REVERSE, CONJOINT_OUT_REVERSE, CONJOINT_OUT_REVERSE, CONJOINT_OUT_REVERSE),
105 PACK (CONJOINT_ATOP, CONJOINT_ATOP, CONJOINT_ATOP, CONJOINT_ATOP),
106 PACK (CONJOINT_ATOP_REVERSE, CONJOINT_ATOP_REVERSE, CONJOINT_ATOP_REVERSE, CONJOINT_ATOP_REVERSE),
107 PACK (CONJOINT_XOR, CONJOINT_XOR, CONJOINT_XOR, CONJOINT_XOR),
114 PACK (MULTIPLY, MULTIPLY, MULTIPLY, MULTIPLY),
115 PACK (SCREEN, SCREEN, SCREEN, SCREEN),
116 PACK (OVERLAY, OVERLAY, OVERLAY, OVERLAY),
117 PACK (DARKEN, DARKEN, DARKEN, DARKEN),
118 PACK (LIGHTEN, LIGHTEN, LIGHTEN, LIGHTEN),
119 PACK (COLOR_DODGE, COLOR_DODGE, COLOR_DODGE, COLOR_DODGE),
120 PACK (COLOR_BURN, COLOR_BURN, COLOR_BURN, COLOR_BURN),
121 PACK (HARD_LIGHT, HARD_LIGHT, HARD_LIGHT, HARD_LIGHT),
122 PACK (SOFT_LIGHT, SOFT_LIGHT, SOFT_LIGHT, SOFT_LIGHT),
123 PACK (DIFFERENCE, DIFFERENCE, DIFFERENCE, DIFFERENCE),
124 PACK (EXCLUSION, EXCLUSION, EXCLUSION, EXCLUSION),
125 PACK (HSL_HUE, HSL_HUE, HSL_HUE, HSL_HUE),
126 PACK (HSL_SATURATION, HSL_SATURATION, HSL_SATURATION, HSL_SATURATION),
127 PACK (HSL_COLOR, HSL_COLOR, HSL_COLOR, HSL_COLOR),
128 PACK (HSL_LUMINOSITY, HSL_LUMINOSITY, HSL_LUMINOSITY, HSL_LUMINOSITY),
132 * Optimize the current operator based on opacity of source or destination
133 * The output operator should be mathematically equivalent to the source.
136 optimize_operator (pixman_op_t op,
141 pixman_bool_t is_source_opaque, is_dest_opaque;
143 #define OPAQUE_SHIFT 13
145 COMPILE_TIME_ASSERT (FAST_PATH_IS_OPAQUE == (1 << OPAQUE_SHIFT));
147 is_dest_opaque = (dst_flags & FAST_PATH_IS_OPAQUE);
148 is_source_opaque = ((src_flags & mask_flags) & FAST_PATH_IS_OPAQUE);
150 is_dest_opaque >>= OPAQUE_SHIFT - 1;
151 is_source_opaque >>= OPAQUE_SHIFT;
153 return operator_table[op].opaque_info[is_dest_opaque | is_source_opaque];
157 * Computing composite region
159 static inline pixman_bool_t
160 clip_general_image (pixman_region32_t * region,
161 pixman_region32_t * clip,
165 if (pixman_region32_n_rects (region) == 1 &&
166 pixman_region32_n_rects (clip) == 1)
168 pixman_box32_t * rbox = pixman_region32_rectangles (region, NULL);
169 pixman_box32_t * cbox = pixman_region32_rectangles (clip, NULL);
172 if (rbox->x1 < (v = cbox->x1 + dx))
174 if (rbox->x2 > (v = cbox->x2 + dx))
176 if (rbox->y1 < (v = cbox->y1 + dy))
178 if (rbox->y2 > (v = cbox->y2 + dy))
180 if (rbox->x1 >= rbox->x2 || rbox->y1 >= rbox->y2)
182 pixman_region32_init (region);
186 else if (!pixman_region32_not_empty (clip))
193 pixman_region32_translate (region, -dx, -dy);
195 if (!pixman_region32_intersect (region, region, clip))
199 pixman_region32_translate (region, dx, dy);
202 return pixman_region32_not_empty (region);
205 static inline pixman_bool_t
206 clip_source_image (pixman_region32_t * region,
207 pixman_image_t * image,
211 /* Source clips are ignored, unless they are explicitly turned on
212 * and the clip in question was set by an X client. (Because if
213 * the clip was not set by a client, then it is a hierarchy
214 * clip and those should always be ignored for sources).
216 if (!image->common.clip_sources || !image->common.client_clip)
219 return clip_general_image (region,
220 &image->common.clip_region,
225 * returns FALSE if the final region is empty. Indistinguishable from
226 * an allocation failure, but rendering ignores those anyways.
229 pixman_compute_composite_region32 (pixman_region32_t * region,
230 pixman_image_t * src_image,
231 pixman_image_t * mask_image,
232 pixman_image_t * dst_image,
242 region->extents.x1 = dest_x;
243 region->extents.x2 = dest_x + width;
244 region->extents.y1 = dest_y;
245 region->extents.y2 = dest_y + height;
247 region->extents.x1 = MAX (region->extents.x1, 0);
248 region->extents.y1 = MAX (region->extents.y1, 0);
249 region->extents.x2 = MIN (region->extents.x2, dst_image->bits.width);
250 region->extents.y2 = MIN (region->extents.y2, dst_image->bits.height);
254 /* Check for empty operation */
255 if (region->extents.x1 >= region->extents.x2 ||
256 region->extents.y1 >= region->extents.y2)
258 region->extents.x1 = 0;
259 region->extents.x2 = 0;
260 region->extents.y1 = 0;
261 region->extents.y2 = 0;
265 if (dst_image->common.have_clip_region)
267 if (!clip_general_image (region, &dst_image->common.clip_region, 0, 0))
271 if (dst_image->common.alpha_map)
273 if (!pixman_region32_intersect_rect (region, region,
274 dst_image->common.alpha_origin_x,
275 dst_image->common.alpha_origin_y,
276 dst_image->common.alpha_map->width,
277 dst_image->common.alpha_map->height))
281 if (!pixman_region32_not_empty (region))
283 if (dst_image->common.alpha_map->common.have_clip_region)
285 if (!clip_general_image (region, &dst_image->common.alpha_map->common.clip_region,
286 -dst_image->common.alpha_origin_x,
287 -dst_image->common.alpha_origin_y))
294 /* clip against src */
295 if (src_image->common.have_clip_region)
297 if (!clip_source_image (region, src_image, dest_x - src_x, dest_y - src_y))
300 if (src_image->common.alpha_map && src_image->common.alpha_map->common.have_clip_region)
302 if (!clip_source_image (region, (pixman_image_t *)src_image->common.alpha_map,
303 dest_x - (src_x - src_image->common.alpha_origin_x),
304 dest_y - (src_y - src_image->common.alpha_origin_y)))
309 /* clip against mask */
310 if (mask_image && mask_image->common.have_clip_region)
312 if (!clip_source_image (region, mask_image, dest_x - mask_x, dest_y - mask_y))
315 if (mask_image->common.alpha_map && mask_image->common.alpha_map->common.have_clip_region)
317 if (!clip_source_image (region, (pixman_image_t *)mask_image->common.alpha_map,
318 dest_x - (mask_x - mask_image->common.alpha_origin_x),
319 dest_y - (mask_y - mask_image->common.alpha_origin_y)))
329 #define N_CACHED_FAST_PATHS 8
335 pixman_implementation_t * imp;
336 pixman_fast_path_t fast_path;
337 } cache [N_CACHED_FAST_PATHS];
340 PIXMAN_DEFINE_THREAD_LOCAL (cache_t, fast_path_cache);
342 static force_inline pixman_bool_t
343 lookup_composite_function (pixman_op_t op,
344 pixman_format_code_t src_format,
346 pixman_format_code_t mask_format,
348 pixman_format_code_t dest_format,
350 pixman_implementation_t **out_imp,
351 pixman_composite_func_t *out_func)
353 pixman_implementation_t *imp;
357 /* Check cache for fast paths */
358 cache = PIXMAN_GET_THREAD_LOCAL (fast_path_cache);
360 for (i = 0; i < N_CACHED_FAST_PATHS; ++i)
362 const pixman_fast_path_t *info = &(cache->cache[i].fast_path);
364 /* Note that we check for equality here, not whether
365 * the cached fast path matches. This is to prevent
366 * us from selecting an overly general fast path
367 * when a more specific one would work.
369 if (info->op == op &&
370 info->src_format == src_format &&
371 info->mask_format == mask_format &&
372 info->dest_format == dest_format &&
373 info->src_flags == src_flags &&
374 info->mask_flags == mask_flags &&
375 info->dest_flags == dest_flags &&
378 *out_imp = cache->cache[i].imp;
379 *out_func = cache->cache[i].fast_path.func;
385 for (imp = get_implementation (); imp != NULL; imp = imp->delegate)
387 const pixman_fast_path_t *info = imp->fast_paths;
389 while (info->op != PIXMAN_OP_NONE)
391 if ((info->op == op || info->op == PIXMAN_OP_any) &&
393 ((info->src_format == src_format) ||
394 (info->src_format == PIXMAN_any)) &&
395 ((info->mask_format == mask_format) ||
396 (info->mask_format == PIXMAN_any)) &&
397 ((info->dest_format == dest_format) ||
398 (info->dest_format == PIXMAN_any)) &&
400 (info->src_flags & src_flags) == info->src_flags &&
401 (info->mask_flags & mask_flags) == info->mask_flags &&
402 (info->dest_flags & dest_flags) == info->dest_flags)
405 *out_func = info->func;
407 /* Set i to the last spot in the cache so that the
408 * move-to-front code below will work
410 i = N_CACHED_FAST_PATHS - 1;
424 cache->cache[i + 1] = cache->cache[i];
426 cache->cache[0].imp = *out_imp;
427 cache->cache[0].fast_path.op = op;
428 cache->cache[0].fast_path.src_format = src_format;
429 cache->cache[0].fast_path.src_flags = src_flags;
430 cache->cache[0].fast_path.mask_format = mask_format;
431 cache->cache[0].fast_path.mask_flags = mask_flags;
432 cache->cache[0].fast_path.dest_format = dest_format;
433 cache->cache[0].fast_path.dest_flags = dest_flags;
434 cache->cache[0].fast_path.func = *out_func;
441 compute_sample_extents (pixman_transform_t *transform,
442 pixman_box32_t *extents, int x, int y,
443 pixman_fixed_t x_off, pixman_fixed_t y_off,
444 pixman_fixed_t width, pixman_fixed_t height)
446 pixman_fixed_t x1, y1, x2, y2;
447 pixman_fixed_48_16_t tx1, ty1, tx2, ty2;
449 /* We have checked earlier that (extents->x1 - x) etc. fit in a pixman_fixed_t */
450 x1 = (pixman_fixed_48_16_t)pixman_int_to_fixed (extents->x1 - x) + pixman_fixed_1 / 2;
451 y1 = (pixman_fixed_48_16_t)pixman_int_to_fixed (extents->y1 - y) + pixman_fixed_1 / 2;
452 x2 = (pixman_fixed_48_16_t)pixman_int_to_fixed (extents->x2 - x) - pixman_fixed_1 / 2;
453 y2 = (pixman_fixed_48_16_t)pixman_int_to_fixed (extents->y2 - y) - pixman_fixed_1 / 2;
457 tx1 = (pixman_fixed_48_16_t)x1;
458 ty1 = (pixman_fixed_48_16_t)y1;
459 tx2 = (pixman_fixed_48_16_t)x2;
460 ty2 = (pixman_fixed_48_16_t)y2;
467 tx1 = ty1 = tx2 = ty2 = 0;
469 for (i = 0; i < 4; ++i)
471 pixman_fixed_48_16_t tx, ty;
474 v.vector[0] = (i & 0x01)? x1 : x2;
475 v.vector[1] = (i & 0x02)? y1 : y2;
476 v.vector[2] = pixman_fixed_1;
478 if (!pixman_transform_point (transform, &v))
481 tx = (pixman_fixed_48_16_t)v.vector[0];
482 ty = (pixman_fixed_48_16_t)v.vector[1];
505 /* Expand the source area by a tiny bit so account of different rounding that
506 * may happen during sampling. Note that (8 * pixman_fixed_e) is very far from
507 * 0.5 so this won't cause the area computed to be overly pessimistic.
509 tx1 += x_off - 8 * pixman_fixed_e;
510 ty1 += y_off - 8 * pixman_fixed_e;
511 tx2 += x_off + width + 8 * pixman_fixed_e;
512 ty2 += y_off + height + 8 * pixman_fixed_e;
514 if (tx1 < pixman_min_fixed_48_16 || tx1 > pixman_max_fixed_48_16 ||
515 ty1 < pixman_min_fixed_48_16 || ty1 > pixman_max_fixed_48_16 ||
516 tx2 < pixman_min_fixed_48_16 || tx2 > pixman_max_fixed_48_16 ||
517 ty2 < pixman_min_fixed_48_16 || ty2 > pixman_max_fixed_48_16)
523 extents->x1 = pixman_fixed_to_int (tx1);
524 extents->y1 = pixman_fixed_to_int (ty1);
525 extents->x2 = pixman_fixed_to_int (tx2) + 1;
526 extents->y2 = pixman_fixed_to_int (ty2) + 1;
532 #define IS_16BIT(x) (((x) >= INT16_MIN) && ((x) <= INT16_MAX))
535 analyze_extent (pixman_image_t *image, int x, int y,
536 const pixman_box32_t *extents, uint32_t *flags)
538 pixman_transform_t *transform;
539 pixman_fixed_t *params;
540 pixman_fixed_t x_off, y_off;
541 pixman_fixed_t width, height;
547 /* Some compositing functions walk one step
548 * outside the destination rectangle, so we
549 * check here that the expanded-by-one source
550 * extents in destination space fits in 16 bits
552 if (!IS_16BIT (extents->x1 - x - 1) ||
553 !IS_16BIT (extents->y1 - y - 1) ||
554 !IS_16BIT (extents->x2 - x + 1) ||
555 !IS_16BIT (extents->y2 - y + 1))
560 transform = image->common.transform;
561 if (image->common.type == BITS)
563 /* During repeat mode calculations we might convert the
564 * width/height of an image to fixed 16.16, so we need
565 * them to be smaller than 16 bits.
567 if (image->bits.width >= 0x7fff || image->bits.height >= 0x7fff)
570 #define ID_AND_NEAREST (FAST_PATH_ID_TRANSFORM | FAST_PATH_NEAREST_FILTER)
572 if ((image->common.flags & ID_AND_NEAREST) == ID_AND_NEAREST &&
573 extents->x1 - x >= 0 &&
574 extents->y1 - y >= 0 &&
575 extents->x2 - x <= image->bits.width &&
576 extents->y2 - y <= image->bits.height)
578 *flags |= FAST_PATH_SAMPLES_COVER_CLIP;
582 switch (image->common.filter)
584 case PIXMAN_FILTER_CONVOLUTION:
585 params = image->common.filter_params;
586 x_off = - pixman_fixed_e - ((params[0] - pixman_fixed_1) >> 1);
587 y_off = - pixman_fixed_e - ((params[1] - pixman_fixed_1) >> 1);
592 case PIXMAN_FILTER_GOOD:
593 case PIXMAN_FILTER_BEST:
594 case PIXMAN_FILTER_BILINEAR:
595 x_off = - pixman_fixed_1 / 2;
596 y_off = - pixman_fixed_1 / 2;
597 width = pixman_fixed_1;
598 height = pixman_fixed_1;
601 case PIXMAN_FILTER_FAST:
602 case PIXMAN_FILTER_NEAREST:
603 x_off = - pixman_fixed_e;
604 y_off = - pixman_fixed_e;
613 /* Check whether the non-expanded, transformed extent is entirely within
614 * the source image, and set the FAST_PATH_SAMPLES_COVER_CLIP if it is.
617 if (compute_sample_extents (transform, &ex, x, y, x_off, y_off, width, height) &&
618 ex.x1 >= 0 && ex.y1 >= 0 &&
619 ex.x2 <= image->bits.width && ex.y2 <= image->bits.height)
621 *flags |= FAST_PATH_SAMPLES_COVER_CLIP;
632 /* Check that the extents expanded by one don't overflow. This ensures that
633 * compositing functions can simply walk the source space using 16.16
634 * variables without worrying about overflow.
636 ex.x1 = extents->x1 - 1;
637 ex.y1 = extents->y1 - 1;
638 ex.x2 = extents->x2 + 1;
639 ex.y2 = extents->y2 + 1;
641 if (!compute_sample_extents (transform, &ex, x, y, x_off, y_off, width, height))
648 * Work around GCC bug causing crashes in Mozilla with SSE2
650 * When using -msse, gcc generates movdqa instructions assuming that
651 * the stack is 16 byte aligned. Unfortunately some applications, such
652 * as Mozilla and Mono, end up aligning the stack to 4 bytes, which
653 * causes the movdqa instructions to fail.
655 * The __force_align_arg_pointer__ makes gcc generate a prologue that
656 * realigns the stack pointer to 16 bytes.
658 * On x86-64 this is not necessary because the standard ABI already
659 * calls for a 16 byte aligned stack.
661 * See https://bugs.freedesktop.org/show_bug.cgi?id=15693
663 #if defined (USE_SSE2) && defined(__GNUC__) && !defined(__x86_64__) && !defined(__amd64__)
664 __attribute__((__force_align_arg_pointer__))
667 pixman_image_composite32 (pixman_op_t op,
668 pixman_image_t * src,
669 pixman_image_t * mask,
670 pixman_image_t * dest,
680 pixman_format_code_t src_format, mask_format, dest_format;
681 uint32_t src_flags, mask_flags, dest_flags;
682 pixman_region32_t region;
683 pixman_box32_t *extents;
684 pixman_implementation_t *imp;
685 pixman_composite_func_t func;
687 _pixman_image_validate (src);
689 _pixman_image_validate (mask);
690 _pixman_image_validate (dest);
692 src_format = src->common.extended_format_code;
693 src_flags = src->common.flags;
697 mask_format = mask->common.extended_format_code;
698 mask_flags = mask->common.flags;
702 mask_format = PIXMAN_null;
703 mask_flags = FAST_PATH_IS_OPAQUE;
706 dest_format = dest->common.extended_format_code;
707 dest_flags = dest->common.flags;
709 /* Check for pixbufs */
710 if ((mask_format == PIXMAN_a8r8g8b8 || mask_format == PIXMAN_a8b8g8r8) &&
711 (src->type == BITS && src->bits.bits == mask->bits.bits) &&
712 (src->common.repeat == mask->common.repeat) &&
713 (src_x == mask_x && src_y == mask_y))
715 if (src_format == PIXMAN_x8b8g8r8)
716 src_format = mask_format = PIXMAN_pixbuf;
717 else if (src_format == PIXMAN_x8r8g8b8)
718 src_format = mask_format = PIXMAN_rpixbuf;
721 pixman_region32_init (®ion);
723 if (!pixman_compute_composite_region32 (
724 ®ion, src, mask, dest,
725 src_x, src_y, mask_x, mask_y, dest_x, dest_y, width, height))
730 extents = pixman_region32_extents (®ion);
732 if (!analyze_extent (src, dest_x - src_x, dest_y - src_y, extents, &src_flags))
735 if (!analyze_extent (mask, dest_x - mask_x, dest_y - mask_y, extents, &mask_flags))
738 /* If the clip is within the source samples, and the samples are opaque,
739 * then the source is effectively opaque.
741 #define BOTH (FAST_PATH_SAMPLES_OPAQUE | FAST_PATH_SAMPLES_COVER_CLIP)
743 if ((src_flags & BOTH) == BOTH)
744 src_flags |= FAST_PATH_IS_OPAQUE;
746 if ((mask_flags & BOTH) == BOTH)
747 mask_flags |= FAST_PATH_IS_OPAQUE;
750 * Check if we can replace our operator by a simpler one
751 * if the src or dest are opaque. The output operator should be
752 * mathematically equivalent to the source.
754 op = optimize_operator (op, src_flags, mask_flags, dest_flags);
755 if (op == PIXMAN_OP_DST)
758 if (lookup_composite_function (op,
759 src_format, src_flags,
760 mask_format, mask_flags,
761 dest_format, dest_flags,
764 const pixman_box32_t *pbox;
767 pbox = pixman_region32_rectangles (®ion, &n);
773 pbox->x1 + src_x - dest_x,
774 pbox->y1 + src_y - dest_y,
775 pbox->x1 + mask_x - dest_x,
776 pbox->y1 + mask_y - dest_y,
780 pbox->y2 - pbox->y1);
787 pixman_region32_fini (®ion);
791 pixman_image_composite (pixman_op_t op,
792 pixman_image_t * src,
793 pixman_image_t * mask,
794 pixman_image_t * dest,
804 pixman_image_composite32 (op, src, mask, dest, src_x, src_y,
805 mask_x, mask_y, dest_x, dest_y, width, height);
808 PIXMAN_EXPORT pixman_bool_t
809 pixman_blt (uint32_t *src_bits,
822 return _pixman_implementation_blt (get_implementation(),
823 src_bits, dst_bits, src_stride, dst_stride,
830 PIXMAN_EXPORT pixman_bool_t
831 pixman_fill (uint32_t *bits,
840 return _pixman_implementation_fill (
841 get_implementation(), bits, stride, bpp, x, y, width, height, xor);
845 color_to_uint32 (const pixman_color_t *color)
848 (color->alpha >> 8 << 24) |
849 (color->red >> 8 << 16) |
850 (color->green & 0xff00) |
855 color_to_pixel (pixman_color_t * color,
857 pixman_format_code_t format)
859 uint32_t c = color_to_uint32 (color);
861 if (!(format == PIXMAN_a8r8g8b8 ||
862 format == PIXMAN_x8r8g8b8 ||
863 format == PIXMAN_a8b8g8r8 ||
864 format == PIXMAN_x8b8g8r8 ||
865 format == PIXMAN_b8g8r8a8 ||
866 format == PIXMAN_b8g8r8x8 ||
867 format == PIXMAN_r5g6b5 ||
868 format == PIXMAN_b5g6r5 ||
869 format == PIXMAN_a8))
874 if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_ABGR)
876 c = ((c & 0xff000000) >> 0) |
877 ((c & 0x00ff0000) >> 16) |
878 ((c & 0x0000ff00) >> 0) |
879 ((c & 0x000000ff) << 16);
881 if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_BGRA)
883 c = ((c & 0xff000000) >> 24) |
884 ((c & 0x00ff0000) >> 8) |
885 ((c & 0x0000ff00) << 8) |
886 ((c & 0x000000ff) << 24);
889 if (format == PIXMAN_a8)
891 else if (format == PIXMAN_r5g6b5 ||
892 format == PIXMAN_b5g6r5)
893 c = CONVERT_8888_TO_0565 (c);
896 printf ("color: %x %x %x %x\n", color->alpha, color->red, color->green, color->blue);
897 printf ("pixel: %x\n", c);
904 PIXMAN_EXPORT pixman_bool_t
905 pixman_image_fill_rectangles (pixman_op_t op,
906 pixman_image_t * dest,
907 pixman_color_t * color,
909 const pixman_rectangle16_t *rects)
911 pixman_box32_t stack_boxes[6];
912 pixman_box32_t *boxes;
913 pixman_bool_t result;
918 boxes = pixman_malloc_ab (sizeof (pixman_box32_t), n_rects);
927 for (i = 0; i < n_rects; ++i)
929 boxes[i].x1 = rects[i].x;
930 boxes[i].y1 = rects[i].y;
931 boxes[i].x2 = boxes[i].x1 + rects[i].width;
932 boxes[i].y2 = boxes[i].y1 + rects[i].height;
935 result = pixman_image_fill_boxes (op, dest, color, n_rects, boxes);
937 if (boxes != stack_boxes)
943 PIXMAN_EXPORT pixman_bool_t
944 pixman_image_fill_boxes (pixman_op_t op,
945 pixman_image_t * dest,
946 pixman_color_t * color,
948 const pixman_box32_t *boxes)
950 pixman_image_t *solid;
954 _pixman_image_validate (dest);
956 if (color->alpha == 0xffff)
958 if (op == PIXMAN_OP_OVER)
962 if (op == PIXMAN_OP_CLEAR)
974 if (op == PIXMAN_OP_SRC)
978 if (color_to_pixel (color, &pixel, dest->bits.format))
980 pixman_region32_t fill_region;
982 pixman_box32_t *rects;
984 if (!pixman_region32_init_rects (&fill_region, boxes, n_boxes))
987 if (dest->common.have_clip_region)
989 if (!pixman_region32_intersect (&fill_region,
991 &dest->common.clip_region))
995 rects = pixman_region32_rectangles (&fill_region, &n_rects);
996 for (j = 0; j < n_rects; ++j)
998 const pixman_box32_t *rect = &(rects[j]);
999 pixman_fill (dest->bits.bits, dest->bits.rowstride, PIXMAN_FORMAT_BPP (dest->bits.format),
1000 rect->x1, rect->y1, rect->x2 - rect->x1, rect->y2 - rect->y1,
1004 pixman_region32_fini (&fill_region);
1009 solid = pixman_image_create_solid_fill (color);
1013 for (i = 0; i < n_boxes; ++i)
1015 const pixman_box32_t *box = &(boxes[i]);
1017 pixman_image_composite32 (op, solid, NULL, dest,
1020 box->x2 - box->x1, box->y2 - box->y1);
1023 pixman_image_unref (solid);
1031 * Returns the version of the pixman library encoded in a single
1032 * integer as per %PIXMAN_VERSION_ENCODE. The encoding ensures that
1033 * later versions compare greater than earlier versions.
1035 * A run-time comparison to check that pixman's version is greater than
1036 * or equal to version X.Y.Z could be performed as follows:
1038 * <informalexample><programlisting>
1039 * if (pixman_version() >= PIXMAN_VERSION_ENCODE(X,Y,Z)) {...}
1040 * </programlisting></informalexample>
1042 * See also pixman_version_string() as well as the compile-time
1043 * equivalents %PIXMAN_VERSION and %PIXMAN_VERSION_STRING.
1045 * Return value: the encoded version.
1048 pixman_version (void)
1050 return PIXMAN_VERSION;
1054 * pixman_version_string:
1056 * Returns the version of the pixman library as a human-readable string
1057 * of the form "X.Y.Z".
1059 * See also pixman_version() as well as the compile-time equivalents
1060 * %PIXMAN_VERSION_STRING and %PIXMAN_VERSION.
1062 * Return value: a string containing the version.
1064 PIXMAN_EXPORT const char*
1065 pixman_version_string (void)
1067 return PIXMAN_VERSION_STRING;
1071 * pixman_format_supported_source:
1072 * @format: A pixman_format_code_t format
1074 * Return value: whether the provided format code is a supported
1075 * format for a pixman surface used as a source in
1078 * Currently, all pixman_format_code_t values are supported.
1080 PIXMAN_EXPORT pixman_bool_t
1081 pixman_format_supported_source (pixman_format_code_t format)
1085 /* 32 bpp formats */
1086 case PIXMAN_a2b10g10r10:
1087 case PIXMAN_x2b10g10r10:
1088 case PIXMAN_a2r10g10b10:
1089 case PIXMAN_x2r10g10b10:
1090 case PIXMAN_a8r8g8b8:
1091 case PIXMAN_x8r8g8b8:
1092 case PIXMAN_a8b8g8r8:
1093 case PIXMAN_x8b8g8r8:
1094 case PIXMAN_b8g8r8a8:
1095 case PIXMAN_b8g8r8x8:
1100 case PIXMAN_x14r6g6b6:
1101 /* 16 bpp formats */
1102 case PIXMAN_a1r5g5b5:
1103 case PIXMAN_x1r5g5b5:
1104 case PIXMAN_a1b5g5r5:
1105 case PIXMAN_x1b5g5r5:
1106 case PIXMAN_a4r4g4b4:
1107 case PIXMAN_x4r4g4b4:
1108 case PIXMAN_a4b4g4r4:
1109 case PIXMAN_x4b4g4r4:
1114 case PIXMAN_a2r2g2b2:
1115 case PIXMAN_a2b2g2r2:
1119 /* Collides with PIXMAN_c8
1122 /* Collides with PIXMAN_g8
1129 case PIXMAN_a1r1g1b1:
1130 case PIXMAN_a1b1g1r1:
1147 * pixman_format_supported_destination:
1148 * @format: A pixman_format_code_t format
1150 * Return value: whether the provided format code is a supported
1151 * format for a pixman surface used as a destination in
1154 * Currently, all pixman_format_code_t values are supported
1155 * except for the YUV formats.
1157 PIXMAN_EXPORT pixman_bool_t
1158 pixman_format_supported_destination (pixman_format_code_t format)
1160 /* YUV formats cannot be written to at the moment */
1161 if (format == PIXMAN_yuy2 || format == PIXMAN_yv12)
1164 return pixman_format_supported_source (format);
1167 PIXMAN_EXPORT pixman_bool_t
1168 pixman_compute_composite_region (pixman_region16_t * region,
1169 pixman_image_t * src_image,
1170 pixman_image_t * mask_image,
1171 pixman_image_t * dst_image,
1181 pixman_region32_t r32;
1182 pixman_bool_t retval;
1184 pixman_region32_init (&r32);
1186 retval = pixman_compute_composite_region32 (
1187 &r32, src_image, mask_image, dst_image,
1188 src_x, src_y, mask_x, mask_y, dest_x, dest_y,
1193 if (!pixman_region16_copy_from_region32 (region, &r32))
1197 pixman_region32_fini (&r32);