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.
28 #include "pixman-private.h"
29 #include "pixman-combine32.h"
31 static force_inline uint32_t
34 if (((unsigned long)a) & 1)
36 #ifdef WORDS_BIGENDIAN
37 return (*a << 16) | (*(uint16_t *)(a + 1));
39 return *a | (*(uint16_t *)(a + 1) << 8);
44 #ifdef WORDS_BIGENDIAN
45 return (*(uint16_t *)a << 8) | *(a + 2);
47 return *(uint16_t *)a | (*(a + 2) << 16);
52 static force_inline void
53 Store24 (uint8_t *a, uint32_t v)
55 if (((unsigned long)a) & 1)
57 #ifdef WORDS_BIGENDIAN
58 *a = (uint8_t) (v >> 16);
59 *(uint16_t *)(a + 1) = (uint16_t) (v);
62 *(uint16_t *)(a + 1) = (uint16_t) (v >> 8);
67 #ifdef WORDS_BIGENDIAN
68 *(uint16_t *)a = (uint16_t)(v >> 8);
69 *(a + 2) = (uint8_t)v;
71 *(uint16_t *)a = (uint16_t)v;
72 *(a + 2) = (uint8_t)(v >> 16);
77 static force_inline uint32_t
78 fbOver (uint32_t src, uint32_t dest)
80 uint32_t a = ~src >> 24;
82 FbByteMulAdd(dest, a, src);
88 fbIn (uint32_t x, uint8_t y)
103 fbCompositeOver_x888x8x8888 (pixman_implementation_t *imp,
105 pixman_image_t * pSrc,
106 pixman_image_t * pMask,
107 pixman_image_t * pDst,
117 uint32_t *src, *srcLine;
118 uint32_t *dst, *dstLine;
119 uint8_t *mask, *maskLine;
120 int srcStride, maskStride, dstStride;
125 fbComposeGetStart (pDst, xDst, yDst, uint32_t, dstStride, dstLine, 1);
126 fbComposeGetStart (pMask, xMask, yMask, uint8_t, maskStride, maskLine, 1);
127 fbComposeGetStart (pSrc, xSrc, ySrc, uint32_t, srcStride, srcLine, 1);
132 srcLine += srcStride;
134 dstLine += dstStride;
136 maskLine += maskStride;
144 s = *src | 0xff000000;
151 *dst = fbOver (d, *dst);
161 fbCompositeSolidMaskIn_nx8x8 (pixman_implementation_t *imp,
163 pixman_image_t *iSrc,
164 pixman_image_t *iMask,
165 pixman_image_t *iDst,
176 uint8_t *dstLine, *dst;
177 uint8_t *maskLine, *mask, m;
178 int dstStride, maskStride;
182 src = _pixman_image_get_solid(iSrc, iDst->bits.format);
186 fbComposeGetStart (iDst, xDst, yDst, uint8_t, dstStride, dstLine, 1);
187 fbComposeGetStart (iMask, xMask, yMask, uint8_t, maskStride, maskLine, 1);
193 dstLine += dstStride;
195 maskLine += maskStride;
207 *dst = IntMult(m, *dst, t);
218 dstLine += dstStride;
220 maskLine += maskStride;
226 m = IntMult(m, srca, t);
233 *dst = IntMult(m, *dst, t);
243 fbCompositeSrcIn_8x8 (pixman_implementation_t *imp,
245 pixman_image_t *iSrc,
246 pixman_image_t *iMask,
247 pixman_image_t *iDst,
257 uint8_t *dstLine, *dst;
258 uint8_t *srcLine, *src;
259 int dstStride, srcStride;
264 fbComposeGetStart (iSrc, xSrc, ySrc, uint8_t, srcStride, srcLine, 1);
265 fbComposeGetStart (iDst, xDst, yDst, uint8_t, dstStride, dstLine, 1);
270 dstLine += dstStride;
272 srcLine += srcStride;
284 *dst = IntMult(s, *dst, t);
292 fbCompositeSolidMask_nx8x8888 (pixman_implementation_t *imp,
294 pixman_image_t * pSrc,
295 pixman_image_t * pMask,
296 pixman_image_t * pDst,
307 uint32_t *dstLine, *dst, d;
308 uint8_t *maskLine, *mask, m;
309 int dstStride, maskStride;
312 src = _pixman_image_get_solid(pSrc, pDst->bits.format);
318 fbComposeGetStart (pDst, xDst, yDst, uint32_t, dstStride, dstLine, 1);
319 fbComposeGetStart (pMask, xMask, yMask, uint8_t, maskStride, maskLine, 1);
324 dstLine += dstStride;
326 maskLine += maskStride;
337 *dst = fbOver (src, *dst);
342 *dst = fbOver (d, *dst);
350 fbCompositeSolidMask_nx8888x8888C (pixman_implementation_t *imp,
352 pixman_image_t * pSrc,
353 pixman_image_t * pMask,
354 pixman_image_t * pDst,
365 uint32_t *dstLine, *dst, d;
366 uint32_t *maskLine, *mask, ma;
367 int dstStride, maskStride;
370 src = _pixman_image_get_solid(pSrc, pDst->bits.format);
376 fbComposeGetStart (pDst, xDst, yDst, uint32_t, dstStride, dstLine, 1);
377 fbComposeGetStart (pMask, xMask, yMask, uint32_t, maskStride, maskLine, 1);
382 dstLine += dstStride;
384 maskLine += maskStride;
390 if (ma == 0xffffffff)
395 *dst = fbOver (src, *dst);
401 FbByteMulC (src, ma);
402 FbByteMul (ma, srca);
404 FbByteMulAddC (d, ma, src);
415 fbCompositeSolidMask_nx8x0888 (pixman_implementation_t *imp,
417 pixman_image_t * pSrc,
418 pixman_image_t * pMask,
419 pixman_image_t * pDst,
430 uint8_t *dstLine, *dst;
432 uint8_t *maskLine, *mask, m;
433 int dstStride, maskStride;
436 src = _pixman_image_get_solid(pSrc, pDst->bits.format);
442 fbComposeGetStart (pDst, xDst, yDst, uint8_t, dstStride, dstLine, 3);
443 fbComposeGetStart (pMask, xMask, yMask, uint8_t, maskStride, maskLine, 1);
448 dstLine += dstStride;
450 maskLine += maskStride;
469 d = fbOver (fbIn(src,m), Fetch24(dst));
478 fbCompositeSolidMask_nx8x0565 (pixman_implementation_t *imp,
480 pixman_image_t * pSrc,
481 pixman_image_t * pMask,
482 pixman_image_t * pDst,
493 uint16_t *dstLine, *dst;
495 uint8_t *maskLine, *mask, m;
496 int dstStride, maskStride;
499 src = _pixman_image_get_solid(pSrc, pDst->bits.format);
505 fbComposeGetStart (pDst, xDst, yDst, uint16_t, dstStride, dstLine, 1);
506 fbComposeGetStart (pMask, xMask, yMask, uint8_t, maskStride, maskLine, 1);
511 dstLine += dstStride;
513 maskLine += maskStride;
526 d = fbOver (src, cvt0565to0888(d));
528 *dst = cvt8888to0565(d);
533 d = fbOver (fbIn(src,m), cvt0565to0888(d));
534 *dst = cvt8888to0565(d);
542 fbCompositeSolidMask_nx8888x0565C (pixman_implementation_t *imp,
544 pixman_image_t * pSrc,
545 pixman_image_t * pMask,
546 pixman_image_t * pDst,
558 uint16_t *dstLine, *dst;
560 uint32_t *maskLine, *mask, ma;
561 int dstStride, maskStride;
564 src = _pixman_image_get_solid(pSrc, pDst->bits.format);
570 src16 = cvt8888to0565(src);
572 fbComposeGetStart (pDst, xDst, yDst, uint16_t, dstStride, dstLine, 1);
573 fbComposeGetStart (pMask, xMask, yMask, uint32_t, maskStride, maskLine, 1);
578 dstLine += dstStride;
580 maskLine += maskStride;
586 if (ma == 0xffffffff)
595 d = fbOver (src, cvt0565to0888(d));
596 *dst = cvt8888to0565(d);
602 d = cvt0565to0888(d);
604 FbByteMulC (src, ma);
605 FbByteMul (ma, srca);
607 FbByteMulAddC (d, ma, src);
609 *dst = cvt8888to0565(d);
617 fbCompositeSrc_8888x8888 (pixman_implementation_t *imp,
619 pixman_image_t * pSrc,
620 pixman_image_t * pMask,
621 pixman_image_t * pDst,
631 uint32_t *dstLine, *dst;
632 uint32_t *srcLine, *src, s;
633 int dstStride, srcStride;
637 fbComposeGetStart (pDst, xDst, yDst, uint32_t, dstStride, dstLine, 1);
638 fbComposeGetStart (pSrc, xSrc, ySrc, uint32_t, srcStride, srcLine, 1);
643 dstLine += dstStride;
645 srcLine += srcStride;
655 *dst = fbOver (s, *dst);
662 fbCompositeSrc_8888x0888 (pixman_implementation_t *imp,
664 pixman_image_t * pSrc,
665 pixman_image_t * pMask,
666 pixman_image_t * pDst,
676 uint8_t *dstLine, *dst;
678 uint32_t *srcLine, *src, s;
680 int dstStride, srcStride;
683 fbComposeGetStart (pDst, xDst, yDst, uint8_t, dstStride, dstLine, 3);
684 fbComposeGetStart (pSrc, xSrc, ySrc, uint32_t, srcStride, srcLine, 1);
689 dstLine += dstStride;
691 srcLine += srcStride;
703 d = fbOver (s, Fetch24(dst));
713 fbCompositeSrc_8888x0565 (pixman_implementation_t *imp,
715 pixman_image_t * pSrc,
716 pixman_image_t * pMask,
717 pixman_image_t * pDst,
727 uint16_t *dstLine, *dst;
729 uint32_t *srcLine, *src, s;
731 int dstStride, srcStride;
734 fbComposeGetStart (pSrc, xSrc, ySrc, uint32_t, srcStride, srcLine, 1);
735 fbComposeGetStart (pDst, xDst, yDst, uint16_t, dstStride, dstLine, 1);
740 dstLine += dstStride;
742 srcLine += srcStride;
756 d = fbOver (s, cvt0565to0888(d));
758 *dst = cvt8888to0565(d);
766 fbCompositeSrc_x888x0565 (pixman_implementation_t *imp,
768 pixman_image_t * pSrc,
769 pixman_image_t * pMask,
770 pixman_image_t * pDst,
780 uint16_t *dstLine, *dst;
781 uint32_t *srcLine, *src, s;
782 int dstStride, srcStride;
785 fbComposeGetStart (pSrc, xSrc, ySrc, uint32_t, srcStride, srcLine, 1);
786 fbComposeGetStart (pDst, xDst, yDst, uint16_t, dstStride, dstLine, 1);
791 dstLine += dstStride;
793 srcLine += srcStride;
799 *dst = cvt8888to0565(s);
806 fbCompositeSrcAdd_8000x8000 (pixman_implementation_t *imp,
808 pixman_image_t * pSrc,
809 pixman_image_t * pMask,
810 pixman_image_t * pDst,
820 uint8_t *dstLine, *dst;
821 uint8_t *srcLine, *src;
822 int dstStride, srcStride;
827 fbComposeGetStart (pSrc, xSrc, ySrc, uint8_t, srcStride, srcLine, 1);
828 fbComposeGetStart (pDst, xDst, yDst, uint8_t, dstStride, dstLine, 1);
833 dstLine += dstStride;
835 srcLine += srcStride;
847 s = t | (0 - (t >> 8));
857 fbCompositeSrcAdd_8888x8888 (pixman_implementation_t *imp,
859 pixman_image_t * pSrc,
860 pixman_image_t * pMask,
861 pixman_image_t * pDst,
871 uint32_t *dstLine, *dst;
872 uint32_t *srcLine, *src;
873 int dstStride, srcStride;
877 fbComposeGetStart (pSrc, xSrc, ySrc, uint32_t, srcStride, srcLine, 1);
878 fbComposeGetStart (pDst, xDst, yDst, uint32_t, dstStride, dstLine, 1);
883 dstLine += dstStride;
885 srcLine += srcStride;
907 fbCompositeSrcAdd_8888x8x8 (pixman_implementation_t *imp,
909 pixman_image_t * pSrc,
910 pixman_image_t * pMask,
911 pixman_image_t * pDst,
921 uint8_t *dstLine, *dst;
922 uint8_t *maskLine, *mask;
923 int dstStride, maskStride;
928 fbComposeGetStart (pDst, xDst, yDst, uint8_t, dstStride, dstLine, 1);
929 fbComposeGetStart (pMask, xMask, yMask, uint8_t, maskStride, maskLine, 1);
930 src = _pixman_image_get_solid (pSrc, pDst->bits.format);
936 dstLine += dstStride;
938 maskLine += maskStride;
951 m = IntMult (sa, a, tmp);
952 r = IntAdd (m, d, tmp);
964 fbCompositeSolidFill (pixman_implementation_t *imp,
966 pixman_image_t * pSrc,
967 pixman_image_t * pMask,
968 pixman_image_t * pDst,
980 src = _pixman_image_get_solid(pSrc, pDst->bits.format);
982 if (pDst->bits.format == PIXMAN_a8)
984 else if (pDst->bits.format == PIXMAN_r5g6b5 ||
985 pDst->bits.format == PIXMAN_b5g6r5)
986 src = cvt8888to0565 (src);
988 pixman_fill (pDst->bits.bits, pDst->bits.rowstride,
989 PIXMAN_FORMAT_BPP (pDst->bits.format),
996 fbCompositeSrc_8888xx888 (pixman_implementation_t *imp,
998 pixman_image_t * pSrc,
999 pixman_image_t * pMask,
1000 pixman_image_t * pDst,
1012 int dstStride, srcStride;
1013 uint32_t n_bytes = width * sizeof (uint32_t);
1015 fbComposeGetStart (pSrc, xSrc, ySrc, uint32_t, srcStride, src, 1);
1016 fbComposeGetStart (pDst, xDst, yDst, uint32_t, dstStride, dst, 1);
1020 memcpy (dst, src, n_bytes);
1027 static const pixman_fast_path_t c_fast_paths[] =
1029 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8, PIXMAN_r5g6b5, fbCompositeSolidMask_nx8x0565, 0 },
1030 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8, PIXMAN_b5g6r5, fbCompositeSolidMask_nx8x0565, 0 },
1031 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8, PIXMAN_r8g8b8, fbCompositeSolidMask_nx8x0888, 0 },
1032 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8, PIXMAN_b8g8r8, fbCompositeSolidMask_nx8x0888, 0 },
1033 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8, PIXMAN_a8r8g8b8, fbCompositeSolidMask_nx8x8888, 0 },
1034 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8, PIXMAN_x8r8g8b8, fbCompositeSolidMask_nx8x8888, 0 },
1035 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8, PIXMAN_a8b8g8r8, fbCompositeSolidMask_nx8x8888, 0 },
1036 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8, PIXMAN_x8b8g8r8, fbCompositeSolidMask_nx8x8888, 0 },
1037 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8r8g8b8, PIXMAN_a8r8g8b8, fbCompositeSolidMask_nx8888x8888C, NEED_COMPONENT_ALPHA },
1038 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8r8g8b8, PIXMAN_x8r8g8b8, fbCompositeSolidMask_nx8888x8888C, NEED_COMPONENT_ALPHA },
1039 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8r8g8b8, PIXMAN_r5g6b5, fbCompositeSolidMask_nx8888x0565C, NEED_COMPONENT_ALPHA },
1040 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8b8g8r8, PIXMAN_a8b8g8r8, fbCompositeSolidMask_nx8888x8888C, NEED_COMPONENT_ALPHA },
1041 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8b8g8r8, PIXMAN_x8b8g8r8, fbCompositeSolidMask_nx8888x8888C, NEED_COMPONENT_ALPHA },
1042 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8b8g8r8, PIXMAN_b5g6r5, fbCompositeSolidMask_nx8888x0565C, NEED_COMPONENT_ALPHA },
1043 { PIXMAN_OP_OVER, PIXMAN_x8r8g8b8, PIXMAN_a8, PIXMAN_x8r8g8b8, fbCompositeOver_x888x8x8888, 0 },
1044 { PIXMAN_OP_OVER, PIXMAN_x8r8g8b8, PIXMAN_a8, PIXMAN_a8r8g8b8, fbCompositeOver_x888x8x8888, 0 },
1045 { PIXMAN_OP_OVER, PIXMAN_x8b8g8r8, PIXMAN_a8, PIXMAN_x8b8g8r8, fbCompositeOver_x888x8x8888, 0 },
1046 { PIXMAN_OP_OVER, PIXMAN_x8b8g8r8, PIXMAN_a8, PIXMAN_a8b8g8r8, fbCompositeOver_x888x8x8888, 0 },
1047 { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_null, PIXMAN_a8r8g8b8, fbCompositeSrc_8888x8888, 0 },
1048 { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_null, PIXMAN_x8r8g8b8, fbCompositeSrc_8888x8888, 0 },
1049 { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_null, PIXMAN_r5g6b5, fbCompositeSrc_8888x0565, 0 },
1050 { PIXMAN_OP_OVER, PIXMAN_a8b8g8r8, PIXMAN_null, PIXMAN_a8b8g8r8, fbCompositeSrc_8888x8888, 0 },
1051 { PIXMAN_OP_OVER, PIXMAN_a8b8g8r8, PIXMAN_null, PIXMAN_x8b8g8r8, fbCompositeSrc_8888x8888, 0 },
1052 { PIXMAN_OP_OVER, PIXMAN_a8b8g8r8, PIXMAN_null, PIXMAN_b5g6r5, fbCompositeSrc_8888x0565, 0 },
1053 { PIXMAN_OP_ADD, PIXMAN_a8r8g8b8, PIXMAN_null, PIXMAN_a8r8g8b8, fbCompositeSrcAdd_8888x8888, 0 },
1054 { PIXMAN_OP_ADD, PIXMAN_a8b8g8r8, PIXMAN_null, PIXMAN_a8b8g8r8, fbCompositeSrcAdd_8888x8888, 0 },
1055 { PIXMAN_OP_ADD, PIXMAN_a8, PIXMAN_null, PIXMAN_a8, fbCompositeSrcAdd_8000x8000, 0 },
1056 { PIXMAN_OP_ADD, PIXMAN_solid, PIXMAN_a8, PIXMAN_a8, fbCompositeSrcAdd_8888x8x8, 0 },
1057 { PIXMAN_OP_SRC, PIXMAN_solid, PIXMAN_null, PIXMAN_a8r8g8b8, fbCompositeSolidFill, 0 },
1058 { PIXMAN_OP_SRC, PIXMAN_solid, PIXMAN_null, PIXMAN_x8r8g8b8, fbCompositeSolidFill, 0 },
1059 { PIXMAN_OP_SRC, PIXMAN_solid, PIXMAN_null, PIXMAN_a8b8g8r8, fbCompositeSolidFill, 0 },
1060 { PIXMAN_OP_SRC, PIXMAN_solid, PIXMAN_null, PIXMAN_x8b8g8r8, fbCompositeSolidFill, 0 },
1061 { PIXMAN_OP_SRC, PIXMAN_solid, PIXMAN_null, PIXMAN_a8, fbCompositeSolidFill, 0 },
1062 { PIXMAN_OP_SRC, PIXMAN_solid, PIXMAN_null, PIXMAN_r5g6b5, fbCompositeSolidFill, 0 },
1063 { PIXMAN_OP_SRC, PIXMAN_a8r8g8b8, PIXMAN_null, PIXMAN_x8r8g8b8, fbCompositeSrc_8888xx888, 0 },
1064 { PIXMAN_OP_SRC, PIXMAN_x8r8g8b8, PIXMAN_null, PIXMAN_x8r8g8b8, fbCompositeSrc_8888xx888, 0 },
1065 { PIXMAN_OP_SRC, PIXMAN_a8b8g8r8, PIXMAN_null, PIXMAN_x8b8g8r8, fbCompositeSrc_8888xx888, 0 },
1066 { PIXMAN_OP_SRC, PIXMAN_x8b8g8r8, PIXMAN_null, PIXMAN_x8b8g8r8, fbCompositeSrc_8888xx888, 0 },
1067 { PIXMAN_OP_SRC, PIXMAN_a8r8g8b8, PIXMAN_null, PIXMAN_r5g6b5, fbCompositeSrc_x888x0565, 0 },
1068 { PIXMAN_OP_SRC, PIXMAN_x8r8g8b8, PIXMAN_null, PIXMAN_r5g6b5, fbCompositeSrc_x888x0565, 0 },
1069 { PIXMAN_OP_SRC, PIXMAN_a8b8g8r8, PIXMAN_null, PIXMAN_b5g6r5, fbCompositeSrc_x888x0565, 0 },
1070 { PIXMAN_OP_SRC, PIXMAN_x8b8g8r8, PIXMAN_null, PIXMAN_b5g6r5, fbCompositeSrc_x888x0565, 0 },
1071 { PIXMAN_OP_IN, PIXMAN_a8, PIXMAN_null, PIXMAN_a8, fbCompositeSrcIn_8x8, 0 },
1072 { PIXMAN_OP_IN, PIXMAN_solid, PIXMAN_a8, PIXMAN_a8, fbCompositeSolidMaskIn_nx8x8, 0 },
1077 fbCompositeSrcScaleNearest (pixman_implementation_t *imp,
1079 pixman_image_t *pSrc,
1080 pixman_image_t *pMask,
1081 pixman_image_t *pDst,
1093 int dstStride, srcStride;
1097 fbComposeGetStart (pDst, xDst, yDst, uint32_t, dstStride, dst, 1);
1098 /* pass in 0 instead of xSrc and ySrc because xSrc and ySrc need to be
1099 * transformed from destination space to source space */
1100 fbComposeGetStart (pSrc, 0, 0, uint32_t, srcStride, src, 1);
1102 /* reference point is the center of the pixel */
1103 v.vector[0] = pixman_int_to_fixed(xSrc) + pixman_fixed_1 / 2;
1104 v.vector[1] = pixman_int_to_fixed(ySrc) + pixman_fixed_1 / 2;
1105 v.vector[2] = pixman_fixed_1;
1107 if (!pixman_transform_point_3d (pSrc->common.transform, &v))
1110 /* Round down to closest integer, ensuring that 0.5 rounds to 0, not 1 */
1111 v.vector[0] -= pixman_fixed_e;
1112 v.vector[1] -= pixman_fixed_e;
1114 for (j = 0; j < height; j++) {
1115 pixman_fixed_t vx = v.vector[0];
1116 pixman_fixed_t vy = v.vector[1];
1117 for (i = 0; i < width; ++i) {
1118 pixman_bool_t inside_bounds;
1124 /* apply the repeat function */
1125 switch (pSrc->common.repeat) {
1126 case PIXMAN_REPEAT_NORMAL:
1127 x = MOD (x, pSrc->bits.width);
1128 y = MOD (y, pSrc->bits.height);
1129 inside_bounds = TRUE;
1132 case PIXMAN_REPEAT_PAD:
1133 x = CLIP (x, 0, pSrc->bits.width-1);
1134 y = CLIP (y, 0, pSrc->bits.height-1);
1135 inside_bounds = TRUE;
1138 case PIXMAN_REPEAT_REFLECT:
1139 x = MOD (x, pSrc->bits.width * 2);
1140 if (x >= pSrc->bits.width)
1141 x = pSrc->bits.width * 2 - x - 1;
1142 y = MOD (y, pSrc->bits.height * 2);
1143 if (y >= pSrc->bits.height)
1144 y = pSrc->bits.height * 2 - y - 1;
1145 inside_bounds = TRUE;
1148 case PIXMAN_REPEAT_NONE:
1150 inside_bounds = (x >= 0 && x < pSrc->bits.width && y >= 0 && y < pSrc->bits.height);
1154 if (inside_bounds) {
1155 //XXX: we should move this multiplication out of the loop
1156 result = *(src + y * srcStride + x);
1160 *(dst + i) = result;
1162 /* adjust the x location by a unit vector in the x direction:
1163 * this is equivalent to transforming x+1 of the destination point to source space */
1164 vx += pSrc->common.transform->matrix[0][0];
1166 /* adjust the y location by a unit vector in the y direction
1167 * this is equivalent to transforming y+1 of the destination point to source space */
1168 v.vector[1] += pSrc->common.transform->matrix[1][1];
1174 fast_path_composite (pixman_implementation_t *imp,
1176 pixman_image_t *src,
1177 pixman_image_t *mask,
1178 pixman_image_t *dest,
1188 if (src->type == BITS
1189 && src->common.transform
1191 && op == PIXMAN_OP_SRC
1192 && !src->common.alpha_map && !dest->common.alpha_map
1193 && (src->common.filter == PIXMAN_FILTER_NEAREST)
1194 && PIXMAN_FORMAT_BPP(dest->bits.format) == 32
1195 && src->bits.format == dest->bits.format
1196 && !src->common.read_func && !src->common.write_func
1197 && !dest->common.read_func && !dest->common.write_func)
1199 /* ensure that the transform matrix only has a scale */
1200 if (src->common.transform->matrix[0][1] == 0 &&
1201 src->common.transform->matrix[1][0] == 0 &&
1202 src->common.transform->matrix[2][0] == 0 &&
1203 src->common.transform->matrix[2][1] == 0 &&
1204 src->common.transform->matrix[2][2] == pixman_fixed_1)
1206 _pixman_walk_composite_region (imp, op,
1212 fbCompositeSrcScaleNearest);
1217 if (_pixman_run_fast_path (c_fast_paths, imp,
1218 op, src, mask, dest,
1227 _pixman_implementation_composite (imp->delegate, op,
1236 pixman_fill8 (uint32_t *bits,
1244 int byte_stride = stride * (int) sizeof (uint32_t);
1245 uint8_t *dst = (uint8_t *) bits;
1246 uint8_t v = xor & 0xff;
1249 dst = dst + y * byte_stride + x;
1253 for (i = 0; i < width; ++i)
1261 pixman_fill16 (uint32_t *bits,
1269 int short_stride = (stride * (int) sizeof (uint32_t)) / (int) sizeof (uint16_t);
1270 uint16_t *dst = (uint16_t *)bits;
1271 uint16_t v = xor & 0xffff;
1274 dst = dst + y * short_stride + x;
1278 for (i = 0; i < width; ++i)
1281 dst += short_stride;
1286 pixman_fill32 (uint32_t *bits,
1296 bits = bits + y * stride + x;
1300 for (i = 0; i < width; ++i)
1307 static pixman_bool_t
1308 fast_path_fill (pixman_implementation_t *imp,
1321 pixman_fill8 (bits, stride, x, y, width, height, xor);
1325 pixman_fill16 (bits, stride, x, y, width, height, xor);
1329 pixman_fill32 (bits, stride, x, y, width, height, xor);
1333 return _pixman_implementation_fill (
1334 imp->delegate, bits, stride, bpp, x, y, width, height, xor);
1341 pixman_implementation_t *
1342 _pixman_implementation_create_fast_path (void)
1344 pixman_implementation_t *general = _pixman_implementation_create_general ();
1345 pixman_implementation_t *imp = _pixman_implementation_create (general);
1347 imp->composite = fast_path_composite;
1348 imp->fill = fast_path_fill;