2 * Copyright © 2000 SuSE, Inc.
3 * Copyright © 1999 Keith Packard
5 * Permission to use, copy, modify, distribute, and sell this software and its
6 * documentation for any purpose is hereby granted without fee, provided that
7 * the above copyright notice appear in all copies and that both that
8 * copyright notice and this permission notice appear in supporting
9 * documentation, and that the name of SuSE not be used in advertising or
10 * publicity pertaining to distribution of the software without specific,
11 * written prior permission. SuSE makes no representations about the
12 * suitability of this software for any purpose. It is provided "as is"
13 * without express or implied warranty.
15 * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
17 * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
18 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
19 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
20 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22 * Author: Keith Packard, SuSE, Inc.
31 #include "pixman-private.h"
34 * Computing composite region
36 #define BOUND(v) (int16_t) ((v) < INT16_MIN ? INT16_MIN : (v) > INT16_MAX ? INT16_MAX : (v))
38 static inline pixman_bool_t
39 miClipPictureReg (pixman_region32_t * pRegion,
40 pixman_region32_t * pClip,
44 if (pixman_region32_n_rects(pRegion) == 1 &&
45 pixman_region32_n_rects(pClip) == 1)
47 pixman_box32_t * pRbox = pixman_region32_rectangles(pRegion, NULL);
48 pixman_box32_t * pCbox = pixman_region32_rectangles(pClip, NULL);
51 if (pRbox->x1 < (v = pCbox->x1 + dx))
53 if (pRbox->x2 > (v = pCbox->x2 + dx))
55 if (pRbox->y1 < (v = pCbox->y1 + dy))
57 if (pRbox->y2 > (v = pCbox->y2 + dy))
59 if (pRbox->x1 >= pRbox->x2 ||
60 pRbox->y1 >= pRbox->y2)
62 pixman_region32_init (pRegion);
65 else if (!pixman_region32_not_empty (pClip))
72 pixman_region32_translate (pRegion, -dx, -dy);
73 if (!pixman_region32_intersect (pRegion, pRegion, pClip))
76 pixman_region32_translate(pRegion, dx, dy);
78 return pixman_region32_not_empty(pRegion);
82 static inline pixman_bool_t
83 miClipPictureSrc (pixman_region32_t * pRegion,
84 pixman_image_t * pPicture,
88 /* Source clips are ignored, unless they are explicitly turned on
89 * and the clip in question was set by an X client
91 if (!pPicture->common.clip_sources || !pPicture->common.client_clip)
94 return miClipPictureReg (pRegion,
95 &pPicture->common.clip_region,
100 * returns FALSE if the final region is empty. Indistinguishable from
101 * an allocation failure, but rendering ignores those anyways.
104 pixman_compute_composite_region32 (pixman_region32_t * pRegion,
105 pixman_image_t * pSrc,
106 pixman_image_t * pMask,
107 pixman_image_t * pDst,
119 pRegion->extents.x1 = xDst;
121 pRegion->extents.x2 = BOUND(v);
122 pRegion->extents.y1 = yDst;
124 pRegion->extents.y2 = BOUND(v);
126 pRegion->extents.x1 = MAX (pRegion->extents.x1, 0);
127 pRegion->extents.y1 = MAX (pRegion->extents.y1, 0);
129 /* Some X servers rely on an old bug, where pixman would just believe the
130 * set clip_region and not clip against the destination geometry. So,
131 * since only X servers set "source clip", we only clip against destination
132 * geometry when that is set.
134 if (!pDst->common.clip_sources)
136 pRegion->extents.x2 = MIN (pRegion->extents.x2, pDst->bits.width);
137 pRegion->extents.y2 = MIN (pRegion->extents.y2, pDst->bits.height);
142 /* Check for empty operation */
143 if (pRegion->extents.x1 >= pRegion->extents.x2 ||
144 pRegion->extents.y1 >= pRegion->extents.y2)
146 pixman_region32_init (pRegion);
150 if (pDst->common.have_clip_region)
152 if (!miClipPictureReg (pRegion, &pDst->common.clip_region, 0, 0))
154 pixman_region32_fini (pRegion);
159 if (pDst->common.alpha_map && pDst->common.alpha_map->common.have_clip_region)
161 if (!miClipPictureReg (pRegion, &pDst->common.alpha_map->common.clip_region,
162 -pDst->common.alpha_origin.x,
163 -pDst->common.alpha_origin.y))
165 pixman_region32_fini (pRegion);
170 /* clip against src */
171 if (pSrc->common.have_clip_region)
173 if (!miClipPictureSrc (pRegion, pSrc, xDst - xSrc, yDst - ySrc))
175 pixman_region32_fini (pRegion);
179 if (pSrc->common.alpha_map && pSrc->common.alpha_map->common.have_clip_region)
181 if (!miClipPictureSrc (pRegion, (pixman_image_t *)pSrc->common.alpha_map,
182 xDst - (xSrc - pSrc->common.alpha_origin.x),
183 yDst - (ySrc - pSrc->common.alpha_origin.y)))
185 pixman_region32_fini (pRegion);
189 /* clip against mask */
190 if (pMask && pMask->common.have_clip_region)
192 if (!miClipPictureSrc (pRegion, pMask, xDst - xMask, yDst - yMask))
194 pixman_region32_fini (pRegion);
197 if (pMask->common.alpha_map && pMask->common.alpha_map->common.have_clip_region)
199 if (!miClipPictureSrc (pRegion, (pixman_image_t *)pMask->common.alpha_map,
200 xDst - (xMask - pMask->common.alpha_origin.x),
201 yDst - (yMask - pMask->common.alpha_origin.y)))
203 pixman_region32_fini (pRegion);
212 PIXMAN_EXPORT pixman_bool_t
213 pixman_compute_composite_region (pixman_region16_t * pRegion,
214 pixman_image_t * pSrc,
215 pixman_image_t * pMask,
216 pixman_image_t * pDst,
226 pixman_region32_t r32;
227 pixman_bool_t retval;
229 pixman_region32_init (&r32);
231 retval = pixman_compute_composite_region32 (&r32, pSrc, pMask, pDst,
232 xSrc, ySrc, xMask, yMask, xDst, yDst,
237 if (!pixman_region16_copy_from_region32 (pRegion, &r32))
241 pixman_region32_fini (&r32);
246 pixman_multiply_overflows_int (unsigned int a,
249 return a >= INT32_MAX / b;
253 pixman_addition_overflows_int (unsigned int a,
256 return a > INT32_MAX - b;
260 pixman_malloc_ab(unsigned int a,
263 if (a >= INT32_MAX / b)
266 return malloc (a * b);
270 pixman_malloc_abc (unsigned int a,
274 if (a >= INT32_MAX / b)
276 else if (a * b >= INT32_MAX / c)
279 return malloc (a * b * c);
283 * Helper routine to expand a color component from 0 < n <= 8 bits to 16 bits by
286 static inline uint64_t
287 expand16(const uint8_t val, int nbits)
289 // Start out with the high bit of val in the high bit of result.
290 uint16_t result = (uint16_t)val << (16 - nbits);
295 // Copy the bits in result, doubling the number of bits each time, until we
298 result |= result >> nbits;
306 * This function expands images from ARGB8 format to ARGB16. To preserve
307 * precision, it needs to know the original source format. For example, if the
308 * source was PIXMAN_x1r5g5b5 and the red component contained bits 12345, then
309 * the expanded value is 12345123. To correctly expand this to 16 bits, it
310 * should be 1234512345123451 and not 1234512312345123.
313 pixman_expand(uint64_t *dst, const uint32_t *src,
314 pixman_format_code_t format, int width)
317 * Determine the sizes of each component and the masks and shifts required
318 * to extract them from the source pixel.
320 const int a_size = PIXMAN_FORMAT_A(format),
321 r_size = PIXMAN_FORMAT_R(format),
322 g_size = PIXMAN_FORMAT_G(format),
323 b_size = PIXMAN_FORMAT_B(format);
324 const int a_shift = 32 - a_size,
325 r_shift = 24 - r_size,
326 g_shift = 16 - g_size,
327 b_shift = 8 - b_size;
328 const uint8_t a_mask = ~(~0 << a_size),
329 r_mask = ~(~0 << r_size),
330 g_mask = ~(~0 << g_size),
331 b_mask = ~(~0 << b_size);
334 /* Start at the end so that we can do the expansion in place when src == dst */
335 for (i = width - 1; i >= 0; i--)
337 const uint32_t pixel = src[i];
338 // Extract the components.
339 const uint8_t a = (pixel >> a_shift) & a_mask,
340 r = (pixel >> r_shift) & r_mask,
341 g = (pixel >> g_shift) & g_mask,
342 b = (pixel >> b_shift) & b_mask;
343 const uint64_t a16 = a_size ? expand16(a, a_size) : 0xffff,
344 r16 = expand16(r, r_size),
345 g16 = expand16(g, g_size),
346 b16 = expand16(b, b_size);
348 dst[i] = a16 << 48 | r16 << 32 | g16 << 16 | b16;
353 * Contracting is easier than expanding. We just need to truncate the
357 pixman_contract(uint32_t *dst, const uint64_t *src, int width)
361 /* Start at the beginning so that we can do the contraction in place when
363 for (i = 0; i < width; i++)
365 const uint8_t a = src[i] >> 56,
369 dst[i] = a << 24 | r << 16 | g << 8 | b;
374 walk_region_internal (pixman_implementation_t *imp,
376 pixman_image_t * pSrc,
377 pixman_image_t * pMask,
378 pixman_image_t * pDst,
387 pixman_bool_t srcRepeat,
388 pixman_bool_t maskRepeat,
389 pixman_region32_t *region,
390 pixman_composite_func_t compositeRect)
393 const pixman_box32_t *pbox;
394 int w, h, w_this, h_this;
395 int x_msk, y_msk, x_src, y_src, x_dst, y_dst;
397 pbox = pixman_region32_rectangles (region, &n);
400 h = pbox->y2 - pbox->y1;
401 y_src = pbox->y1 - yDst + ySrc;
402 y_msk = pbox->y1 - yDst + yMask;
407 w = pbox->x2 - pbox->x1;
408 x_src = pbox->x1 - xDst + xSrc;
409 x_msk = pbox->x1 - xDst + xMask;
414 y_msk = MOD (y_msk, pMask->bits.height);
415 if (h_this > pMask->bits.height - y_msk)
416 h_this = pMask->bits.height - y_msk;
420 y_src = MOD (y_src, pSrc->bits.height);
421 if (h_this > pSrc->bits.height - y_src)
422 h_this = pSrc->bits.height - y_src;
429 x_msk = MOD (x_msk, pMask->bits.width);
430 if (w_this > pMask->bits.width - x_msk)
431 w_this = pMask->bits.width - x_msk;
435 x_src = MOD (x_src, pSrc->bits.width);
436 if (w_this > pSrc->bits.width - x_src)
437 w_this = pSrc->bits.width - x_src;
439 (*compositeRect) (imp,
440 op, pSrc, pMask, pDst,
441 x_src, y_src, x_msk, y_msk, x_dst, y_dst,
458 _pixman_walk_composite_region (pixman_implementation_t *imp,
460 pixman_image_t * pSrc,
461 pixman_image_t * pMask,
462 pixman_image_t * pDst,
471 pixman_composite_func_t compositeRect)
473 pixman_region32_t region;
475 pixman_region32_init (®ion);
477 if (pixman_compute_composite_region32 (
478 ®ion, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask, xDst, yDst, width, height))
480 walk_region_internal (imp, op,
482 xSrc, ySrc, xMask, yMask, xDst, yDst,
483 width, height, FALSE, FALSE,
488 pixman_region32_fini (®ion);
493 mask_is_solid (pixman_image_t *mask)
495 if (mask->type == SOLID)
498 if (mask->type == BITS &&
499 mask->common.repeat == PIXMAN_REPEAT_NORMAL &&
500 mask->bits.width == 1 &&
501 mask->bits.height == 1)
509 static const pixman_fast_path_t *
510 get_fast_path (const pixman_fast_path_t *fast_paths,
512 pixman_image_t *pSrc,
513 pixman_image_t *pMask,
514 pixman_image_t *pDst,
515 pixman_bool_t is_pixbuf)
517 const pixman_fast_path_t *info;
519 for (info = fast_paths; info->op != PIXMAN_OP_NONE; info++)
521 pixman_bool_t valid_src = FALSE;
522 pixman_bool_t valid_mask = FALSE;
527 if ((info->src_format == PIXMAN_solid && pixman_image_is_solid (pSrc)) ||
528 (pSrc->type == BITS && info->src_format == pSrc->bits.format))
536 if ((info->mask_format == PIXMAN_null && !pMask) ||
537 (pMask && pMask->type == BITS && info->mask_format == pMask->bits.format))
541 if (info->flags & NEED_SOLID_MASK)
543 if (!pMask || !mask_is_solid (pMask))
547 if (info->flags & NEED_COMPONENT_ALPHA)
549 if (!pMask || !pMask->common.component_alpha)
557 if (info->dest_format != pDst->bits.format)
560 if ((info->flags & NEED_PIXBUF) && !is_pixbuf)
569 static inline pixman_bool_t
570 image_covers (pixman_image_t *image, pixman_box32_t *extents)
572 if (image->common.type == BITS && image->common.repeat == PIXMAN_REPEAT_NONE)
574 if (extents->x1 < 0 || extents->y1 < 0 ||
575 extents->x2 >= image->bits.width ||
576 extents->y2 >= image->bits.height)
586 _pixman_run_fast_path (const pixman_fast_path_t *paths,
587 pixman_implementation_t *imp,
590 pixman_image_t *mask,
591 pixman_image_t *dest,
601 pixman_composite_func_t func = NULL;
602 pixman_bool_t src_repeat = src->common.repeat == PIXMAN_REPEAT_NORMAL;
603 pixman_bool_t mask_repeat = mask && mask->common.repeat == PIXMAN_REPEAT_NORMAL;
604 pixman_bool_t result;
606 if ((src->type == BITS || pixman_image_is_solid (src)) &&
607 (!mask || mask->type == BITS)
608 && !src->common.transform && !(mask && mask->common.transform)
609 && !(mask && mask->common.alpha_map) && !src->common.alpha_map && !dest->common.alpha_map
610 && (src->common.filter != PIXMAN_FILTER_CONVOLUTION)
611 && (src->common.repeat != PIXMAN_REPEAT_PAD)
612 && (src->common.repeat != PIXMAN_REPEAT_REFLECT)
613 && (!mask || (mask->common.filter != PIXMAN_FILTER_CONVOLUTION &&
614 mask->common.repeat != PIXMAN_REPEAT_PAD &&
615 mask->common.repeat != PIXMAN_REPEAT_REFLECT))
616 && !src->common.read_func && !src->common.write_func
617 && !(mask && mask->common.read_func)
618 && !(mask && mask->common.write_func)
619 && !dest->common.read_func
620 && !dest->common.write_func)
622 const pixman_fast_path_t *info;
623 pixman_bool_t pixbuf;
626 src && src->type == BITS &&
627 mask && mask->type == BITS &&
628 src->bits.bits == mask->bits.bits &&
631 !mask->common.component_alpha &&
634 info = get_fast_path (paths, op, src, mask, dest, pixbuf);
640 if (info->src_format == PIXMAN_solid)
643 if (info->mask_format == PIXMAN_solid || info->flags & NEED_SOLID_MASK)
647 src->bits.width == 1 &&
648 src->bits.height == 1) ||
650 mask->bits.width == 1 &&
651 mask->bits.height == 1))
653 /* If src or mask are repeating 1x1 images and src_repeat or
654 * mask_repeat are still TRUE, it means the fast path we
655 * selected does not actually handle repeating images.
657 * So rather than call the "fast path" with a zillion
658 * 1x1 requests, we just fall back to the general code (which
659 * does do something sensible with 1x1 repeating images).
670 pixman_region32_t region;
671 pixman_region32_init (®ion);
673 if (pixman_compute_composite_region32 (
674 ®ion, src, mask, dest, src_x, src_y, mask_x, mask_y, dest_x, dest_y, width, height))
676 pixman_box32_t *extents = pixman_region32_extents (®ion);
678 if (image_covers (src, extents) &&
679 (!mask || image_covers (mask, extents)))
681 walk_region_internal (imp, op,
683 src_x, src_y, mask_x, mask_y,
686 src_repeat, mask_repeat,
694 pixman_region32_fini (®ion);