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
32 fbOver (uint32_t src, uint32_t dest)
34 // dest = (dest * (255 - alpha)) / 255 + src
35 uint32_t a = ~src >> 24; // 255 - alpha == 255 + (~alpha + 1) == ~alpha
36 FbByteMulAdd(dest, a, src);
42 fbOver24 (uint32_t x, uint32_t y)
44 uint16_t a = ~x >> 24;
48 m = FbOverU(x,y,0,a,t);
49 n = FbOverU(x,y,8,a,t);
50 o = FbOverU(x,y,16,a,t);
55 fbIn (uint32_t x, uint8_t y)
75 fbCompositeOver_x888x8x8888 (pixman_implementation_t *imp,
77 pixman_image_t * pSrc,
78 pixman_image_t * pMask,
79 pixman_image_t * pDst,
89 uint32_t *src, *srcLine;
90 uint32_t *dst, *dstLine;
91 uint8_t *mask, *maskLine;
92 int srcStride, maskStride, dstStride;
97 fbComposeGetStart (pDst, xDst, yDst, uint32_t, dstStride, dstLine, 1);
98 fbComposeGetStart (pMask, xMask, yMask, uint8_t, maskStride, maskLine, 1);
99 fbComposeGetStart (pSrc, xSrc, ySrc, uint32_t, srcStride, srcLine, 1);
104 srcLine += srcStride;
106 dstLine += dstStride;
108 maskLine += maskStride;
116 s = *src | 0xff000000;
123 *dst = fbOver (d, *dst);
133 fbCompositeSolidMaskIn_nx8x8 (pixman_implementation_t *imp,
135 pixman_image_t *iSrc,
136 pixman_image_t *iMask,
137 pixman_image_t *iDst,
148 uint8_t *dstLine, *dst;
149 uint8_t *maskLine, *mask, m;
150 int dstStride, maskStride;
154 src = _pixman_image_get_solid(iSrc, iDst->bits.format);
158 fbComposeGetStart (iDst, xDst, yDst, uint8_t, dstStride, dstLine, 1);
159 fbComposeGetStart (iMask, xMask, yMask, uint8_t, maskStride, maskLine, 1);
165 dstLine += dstStride;
167 maskLine += maskStride;
179 *dst = FbIntMult(m, *dst, t);
190 dstLine += dstStride;
192 maskLine += maskStride;
198 m = FbIntMult(m, srca, t);
205 *dst = FbIntMult(m, *dst, t);
215 fbCompositeSrcIn_8x8 (pixman_implementation_t *imp,
217 pixman_image_t *iSrc,
218 pixman_image_t *iMask,
219 pixman_image_t *iDst,
229 uint8_t *dstLine, *dst;
230 uint8_t *srcLine, *src;
231 int dstStride, srcStride;
236 fbComposeGetStart (iSrc, xSrc, ySrc, uint8_t, srcStride, srcLine, 1);
237 fbComposeGetStart (iDst, xDst, yDst, uint8_t, dstStride, dstLine, 1);
242 dstLine += dstStride;
244 srcLine += srcStride;
256 *dst = FbIntMult(s, *dst, t);
264 fbCompositeSolidMask_nx8x8888 (pixman_implementation_t *imp,
266 pixman_image_t * pSrc,
267 pixman_image_t * pMask,
268 pixman_image_t * pDst,
279 uint32_t *dstLine, *dst, d;
280 uint8_t *maskLine, *mask, m;
281 int dstStride, maskStride;
284 src = _pixman_image_get_solid(pSrc, pDst->bits.format);
290 fbComposeGetStart (pDst, xDst, yDst, uint32_t, dstStride, dstLine, 1);
291 fbComposeGetStart (pMask, xMask, yMask, uint8_t, maskStride, maskLine, 1);
296 dstLine += dstStride;
298 maskLine += maskStride;
309 *dst = fbOver (src, *dst);
314 *dst = fbOver (d, *dst);
322 fbCompositeSolidMask_nx8888x8888C (pixman_implementation_t *imp,
324 pixman_image_t * pSrc,
325 pixman_image_t * pMask,
326 pixman_image_t * pDst,
337 uint32_t *dstLine, *dst, d;
338 uint32_t *maskLine, *mask, ma;
339 int dstStride, maskStride;
343 src = _pixman_image_get_solid(pSrc, pDst->bits.format);
349 fbComposeGetStart (pDst, xDst, yDst, uint32_t, dstStride, dstLine, 1);
350 fbComposeGetStart (pMask, xMask, yMask, uint32_t, maskStride, maskLine, 1);
355 dstLine += dstStride;
357 maskLine += maskStride;
363 if (ma == 0xffffffff)
368 *dst = fbOver (src, *dst);
373 #define FbInOverC(src,srca,msk,dst,i,result) { \
374 uint16_t __a = FbGet8(msk,i); \
375 uint32_t __t, __ta; \
377 __t = FbIntMult (FbGet8(src,i), __a,__i); \
378 __ta = (uint8_t) ~FbIntMult (srca, __a,__i); \
379 __t = __t + FbIntMult(FbGet8(dst,i),__ta,__i); \
380 __t = (uint32_t) (uint8_t) (__t | (-(__t >> 8))); \
381 result = __t << (i); \
383 FbInOverC (src, srca, ma, d, 0, m);
384 FbInOverC (src, srca, ma, d, 8, n);
385 FbInOverC (src, srca, ma, d, 16, o);
386 FbInOverC (src, srca, ma, d, 24, p);
395 fbCompositeSolidMask_nx8x0888 (pixman_implementation_t *imp,
397 pixman_image_t * pSrc,
398 pixman_image_t * pMask,
399 pixman_image_t * pDst,
410 uint8_t *dstLine, *dst;
412 uint8_t *maskLine, *mask, m;
413 int dstStride, maskStride;
416 src = _pixman_image_get_solid(pSrc, pDst->bits.format);
422 fbComposeGetStart (pDst, xDst, yDst, uint8_t, dstStride, dstLine, 3);
423 fbComposeGetStart (pMask, xMask, yMask, uint8_t, maskStride, maskLine, 1);
428 dstLine += dstStride;
430 maskLine += maskStride;
442 d = Fetch24(pDst, dst);
443 d = fbOver24 (src, d);
445 Store24(pDst, dst,d);
449 d = fbOver24 (fbIn(src,m), Fetch24(pDst, dst));
450 Store24(pDst, dst, d);
458 fbCompositeSolidMask_nx8x0565 (pixman_implementation_t *imp,
460 pixman_image_t * pSrc,
461 pixman_image_t * pMask,
462 pixman_image_t * pDst,
473 uint16_t *dstLine, *dst;
475 uint8_t *maskLine, *mask, m;
476 int dstStride, maskStride;
479 src = _pixman_image_get_solid(pSrc, pDst->bits.format);
485 fbComposeGetStart (pDst, xDst, yDst, uint16_t, dstStride, dstLine, 1);
486 fbComposeGetStart (pMask, xMask, yMask, uint8_t, maskStride, maskLine, 1);
491 dstLine += dstStride;
493 maskLine += maskStride;
506 d = fbOver24 (src, cvt0565to0888(d));
508 *dst = cvt8888to0565(d);
513 d = fbOver24 (fbIn(src,m), cvt0565to0888(d));
514 *dst = cvt8888to0565(d);
522 fbCompositeSolidMask_nx8888x0565C (pixman_implementation_t *imp,
524 pixman_image_t * pSrc,
525 pixman_image_t * pMask,
526 pixman_image_t * pDst,
538 uint16_t *dstLine, *dst;
540 uint32_t *maskLine, *mask, ma;
541 int dstStride, maskStride;
545 src = _pixman_image_get_solid(pSrc, pDst->bits.format);
551 src16 = cvt8888to0565(src);
553 fbComposeGetStart (pDst, xDst, yDst, uint16_t, dstStride, dstLine, 1);
554 fbComposeGetStart (pMask, xMask, yMask, uint32_t, maskStride, maskLine, 1);
559 dstLine += dstStride;
561 maskLine += maskStride;
567 if (ma == 0xffffffff)
576 d = fbOver24 (src, cvt0565to0888(d));
577 *dst = cvt8888to0565(d);
583 d = cvt0565to0888(d);
584 FbInOverC (src, srca, ma, d, 0, m);
585 FbInOverC (src, srca, ma, d, 8, n);
586 FbInOverC (src, srca, ma, d, 16, o);
588 *dst = cvt8888to0565(d);
596 fbCompositeSrc_8888x8888 (pixman_implementation_t *imp,
598 pixman_image_t * pSrc,
599 pixman_image_t * pMask,
600 pixman_image_t * pDst,
610 uint32_t *dstLine, *dst;
611 uint32_t *srcLine, *src, s;
612 int dstStride, srcStride;
616 fbComposeGetStart (pDst, xDst, yDst, uint32_t, dstStride, dstLine, 1);
617 fbComposeGetStart (pSrc, xSrc, ySrc, uint32_t, srcStride, srcLine, 1);
622 dstLine += dstStride;
624 srcLine += srcStride;
634 *dst = fbOver (s, *dst);
641 fbCompositeSrc_8888x0888 (pixman_implementation_t *imp,
643 pixman_image_t * pSrc,
644 pixman_image_t * pMask,
645 pixman_image_t * pDst,
655 uint8_t *dstLine, *dst;
657 uint32_t *srcLine, *src, s;
659 int dstStride, srcStride;
662 fbComposeGetStart (pDst, xDst, yDst, uint8_t, dstStride, dstLine, 3);
663 fbComposeGetStart (pSrc, xSrc, ySrc, uint32_t, srcStride, srcLine, 1);
668 dstLine += dstStride;
670 srcLine += srcStride;
682 d = fbOver24 (s, Fetch24(pDst, dst));
683 Store24(pDst, dst, d);
691 fbCompositeSrc_8888x0565 (pixman_implementation_t *imp,
693 pixman_image_t * pSrc,
694 pixman_image_t * pMask,
695 pixman_image_t * pDst,
705 uint16_t *dstLine, *dst;
707 uint32_t *srcLine, *src, s;
709 int dstStride, srcStride;
712 fbComposeGetStart (pSrc, xSrc, ySrc, uint32_t, srcStride, srcLine, 1);
713 fbComposeGetStart (pDst, xDst, yDst, uint16_t, dstStride, dstLine, 1);
718 dstLine += dstStride;
720 srcLine += srcStride;
734 d = fbOver24 (s, cvt0565to0888(d));
736 *dst = cvt8888to0565(d);
744 fbCompositeSrc_x888x0565 (pixman_implementation_t *imp,
746 pixman_image_t * pSrc,
747 pixman_image_t * pMask,
748 pixman_image_t * pDst,
758 uint16_t *dstLine, *dst;
759 uint32_t *srcLine, *src, s;
760 int dstStride, srcStride;
763 fbComposeGetStart (pSrc, xSrc, ySrc, uint32_t, srcStride, srcLine, 1);
764 fbComposeGetStart (pDst, xDst, yDst, uint16_t, dstStride, dstLine, 1);
769 dstLine += dstStride;
771 srcLine += srcStride;
777 *dst = cvt8888to0565(s);
784 fbCompositeSrcAdd_8000x8000 (pixman_implementation_t *imp,
786 pixman_image_t * pSrc,
787 pixman_image_t * pMask,
788 pixman_image_t * pDst,
798 uint8_t *dstLine, *dst;
799 uint8_t *srcLine, *src;
800 int dstStride, srcStride;
805 fbComposeGetStart (pSrc, xSrc, ySrc, uint8_t, srcStride, srcLine, 1);
806 fbComposeGetStart (pDst, xDst, yDst, uint8_t, dstStride, dstLine, 1);
811 dstLine += dstStride;
813 srcLine += srcStride;
825 s = t | (0 - (t >> 8));
835 fbCompositeSrcAdd_8888x8888 (pixman_implementation_t *imp,
837 pixman_image_t * pSrc,
838 pixman_image_t * pMask,
839 pixman_image_t * pDst,
849 uint32_t *dstLine, *dst;
850 uint32_t *srcLine, *src;
851 int dstStride, srcStride;
857 fbComposeGetStart (pSrc, xSrc, ySrc, uint32_t, srcStride, srcLine, 1);
858 fbComposeGetStart (pDst, xDst, yDst, uint32_t, dstStride, dstLine, 1);
863 dstLine += dstStride;
865 srcLine += srcStride;
893 fbCompositeSrcAdd_8888x8x8 (pixman_implementation_t *imp,
895 pixman_image_t * pSrc,
896 pixman_image_t * pMask,
897 pixman_image_t * pDst,
907 uint8_t *dstLine, *dst;
908 uint8_t *maskLine, *mask;
909 int dstStride, maskStride;
914 fbComposeGetStart (pDst, xDst, yDst, uint8_t, dstStride, dstLine, 1);
915 fbComposeGetStart (pMask, xMask, yMask, uint8_t, maskStride, maskLine, 1);
916 src = _pixman_image_get_solid (pSrc, pDst->bits.format);
922 dstLine += dstStride;
924 maskLine += maskStride;
937 m = FbInU (sa, 0, a, tmp);
938 r = FbAdd (m, d, 0, tmp);
950 fbCompositeSolidFill (pixman_implementation_t *imp,
952 pixman_image_t * pSrc,
953 pixman_image_t * pMask,
954 pixman_image_t * pDst,
966 src = _pixman_image_get_solid(pSrc, pDst->bits.format);
968 if (pDst->bits.format == PIXMAN_a8)
970 else if (pDst->bits.format == PIXMAN_r5g6b5 ||
971 pDst->bits.format == PIXMAN_b5g6r5)
972 src = cvt8888to0565 (src);
974 pixman_fill (pDst->bits.bits, pDst->bits.rowstride,
975 PIXMAN_FORMAT_BPP (pDst->bits.format),
982 fbCompositeSrc_8888xx888 (pixman_implementation_t *imp,
984 pixman_image_t * pSrc,
985 pixman_image_t * pMask,
986 pixman_image_t * pDst,
998 int dstStride, srcStride;
999 uint32_t n_bytes = width * sizeof (uint32_t);
1001 fbComposeGetStart (pSrc, xSrc, ySrc, uint32_t, srcStride, src, 1);
1002 fbComposeGetStart (pDst, xDst, yDst, uint32_t, dstStride, dst, 1);
1006 memcpy (dst, src, n_bytes);
1013 static const pixman_fast_path_t c_fast_paths[] =
1015 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8, PIXMAN_r5g6b5, fbCompositeSolidMask_nx8x0565, 0 },
1016 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8, PIXMAN_b5g6r5, fbCompositeSolidMask_nx8x0565, 0 },
1017 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8, PIXMAN_r8g8b8, fbCompositeSolidMask_nx8x0888, 0 },
1018 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8, PIXMAN_b8g8r8, fbCompositeSolidMask_nx8x0888, 0 },
1019 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8, PIXMAN_a8r8g8b8, fbCompositeSolidMask_nx8x8888, 0 },
1020 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8, PIXMAN_x8r8g8b8, fbCompositeSolidMask_nx8x8888, 0 },
1021 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8, PIXMAN_a8b8g8r8, fbCompositeSolidMask_nx8x8888, 0 },
1022 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8, PIXMAN_x8b8g8r8, fbCompositeSolidMask_nx8x8888, 0 },
1023 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8r8g8b8, PIXMAN_a8r8g8b8, fbCompositeSolidMask_nx8888x8888C, NEED_COMPONENT_ALPHA },
1024 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8r8g8b8, PIXMAN_x8r8g8b8, fbCompositeSolidMask_nx8888x8888C, NEED_COMPONENT_ALPHA },
1025 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8r8g8b8, PIXMAN_r5g6b5, fbCompositeSolidMask_nx8888x0565C, NEED_COMPONENT_ALPHA },
1026 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8b8g8r8, PIXMAN_a8b8g8r8, fbCompositeSolidMask_nx8888x8888C, NEED_COMPONENT_ALPHA },
1027 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8b8g8r8, PIXMAN_x8b8g8r8, fbCompositeSolidMask_nx8888x8888C, NEED_COMPONENT_ALPHA },
1028 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8b8g8r8, PIXMAN_b5g6r5, fbCompositeSolidMask_nx8888x0565C, NEED_COMPONENT_ALPHA },
1029 { PIXMAN_OP_OVER, PIXMAN_x8r8g8b8, PIXMAN_a8, PIXMAN_x8r8g8b8, fbCompositeOver_x888x8x8888, 0 },
1030 { PIXMAN_OP_OVER, PIXMAN_x8r8g8b8, PIXMAN_a8, PIXMAN_a8r8g8b8, fbCompositeOver_x888x8x8888, 0 },
1031 { PIXMAN_OP_OVER, PIXMAN_x8b8g8r8, PIXMAN_a8, PIXMAN_x8b8g8r8, fbCompositeOver_x888x8x8888, 0 },
1032 { PIXMAN_OP_OVER, PIXMAN_x8b8g8r8, PIXMAN_a8, PIXMAN_a8b8g8r8, fbCompositeOver_x888x8x8888, 0 },
1033 { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_null, PIXMAN_a8r8g8b8, fbCompositeSrc_8888x8888, 0 },
1034 { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_null, PIXMAN_x8r8g8b8, fbCompositeSrc_8888x8888, 0 },
1035 { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_null, PIXMAN_r5g6b5, fbCompositeSrc_8888x0565, 0 },
1036 { PIXMAN_OP_OVER, PIXMAN_a8b8g8r8, PIXMAN_null, PIXMAN_a8b8g8r8, fbCompositeSrc_8888x8888, 0 },
1037 { PIXMAN_OP_OVER, PIXMAN_a8b8g8r8, PIXMAN_null, PIXMAN_x8b8g8r8, fbCompositeSrc_8888x8888, 0 },
1038 { PIXMAN_OP_OVER, PIXMAN_a8b8g8r8, PIXMAN_null, PIXMAN_b5g6r5, fbCompositeSrc_8888x0565, 0 },
1039 { PIXMAN_OP_ADD, PIXMAN_a8r8g8b8, PIXMAN_null, PIXMAN_a8r8g8b8, fbCompositeSrcAdd_8888x8888, 0 },
1040 { PIXMAN_OP_ADD, PIXMAN_a8b8g8r8, PIXMAN_null, PIXMAN_a8b8g8r8, fbCompositeSrcAdd_8888x8888, 0 },
1041 { PIXMAN_OP_ADD, PIXMAN_a8, PIXMAN_null, PIXMAN_a8, fbCompositeSrcAdd_8000x8000, 0 },
1042 { PIXMAN_OP_ADD, PIXMAN_solid, PIXMAN_a8, PIXMAN_a8, fbCompositeSrcAdd_8888x8x8, 0 },
1043 { PIXMAN_OP_SRC, PIXMAN_solid, PIXMAN_null, PIXMAN_a8r8g8b8, fbCompositeSolidFill, 0 },
1044 { PIXMAN_OP_SRC, PIXMAN_solid, PIXMAN_null, PIXMAN_x8r8g8b8, fbCompositeSolidFill, 0 },
1045 { PIXMAN_OP_SRC, PIXMAN_solid, PIXMAN_null, PIXMAN_a8b8g8r8, fbCompositeSolidFill, 0 },
1046 { PIXMAN_OP_SRC, PIXMAN_solid, PIXMAN_null, PIXMAN_x8b8g8r8, fbCompositeSolidFill, 0 },
1047 { PIXMAN_OP_SRC, PIXMAN_solid, PIXMAN_null, PIXMAN_a8, fbCompositeSolidFill, 0 },
1048 { PIXMAN_OP_SRC, PIXMAN_solid, PIXMAN_null, PIXMAN_r5g6b5, fbCompositeSolidFill, 0 },
1049 { PIXMAN_OP_SRC, PIXMAN_a8r8g8b8, PIXMAN_null, PIXMAN_x8r8g8b8, fbCompositeSrc_8888xx888, 0 },
1050 { PIXMAN_OP_SRC, PIXMAN_x8r8g8b8, PIXMAN_null, PIXMAN_x8r8g8b8, fbCompositeSrc_8888xx888, 0 },
1051 { PIXMAN_OP_SRC, PIXMAN_a8b8g8r8, PIXMAN_null, PIXMAN_x8b8g8r8, fbCompositeSrc_8888xx888, 0 },
1052 { PIXMAN_OP_SRC, PIXMAN_x8b8g8r8, PIXMAN_null, PIXMAN_x8b8g8r8, fbCompositeSrc_8888xx888, 0 },
1053 { PIXMAN_OP_SRC, PIXMAN_a8r8g8b8, PIXMAN_null, PIXMAN_r5g6b5, fbCompositeSrc_x888x0565, 0 },
1054 { PIXMAN_OP_SRC, PIXMAN_x8r8g8b8, PIXMAN_null, PIXMAN_r5g6b5, fbCompositeSrc_x888x0565, 0 },
1055 { PIXMAN_OP_SRC, PIXMAN_a8b8g8r8, PIXMAN_null, PIXMAN_b5g6r5, fbCompositeSrc_x888x0565, 0 },
1056 { PIXMAN_OP_SRC, PIXMAN_x8b8g8r8, PIXMAN_null, PIXMAN_b5g6r5, fbCompositeSrc_x888x0565, 0 },
1057 { PIXMAN_OP_IN, PIXMAN_a8, PIXMAN_null, PIXMAN_a8, fbCompositeSrcIn_8x8, 0 },
1058 { PIXMAN_OP_IN, PIXMAN_solid, PIXMAN_a8, PIXMAN_a8, fbCompositeSolidMaskIn_nx8x8, 0 },
1063 fbCompositeSrcScaleNearest (pixman_implementation_t *imp,
1065 pixman_image_t *pSrc,
1066 pixman_image_t *pMask,
1067 pixman_image_t *pDst,
1079 int dstStride, srcStride;
1083 fbComposeGetStart (pDst, xDst, yDst, uint32_t, dstStride, dst, 1);
1084 /* pass in 0 instead of xSrc and ySrc because xSrc and ySrc need to be
1085 * transformed from destination space to source space */
1086 fbComposeGetStart (pSrc, 0, 0, uint32_t, srcStride, src, 1);
1088 /* reference point is the center of the pixel */
1089 v.vector[0] = pixman_int_to_fixed(xSrc) + pixman_fixed_1 / 2;
1090 v.vector[1] = pixman_int_to_fixed(ySrc) + pixman_fixed_1 / 2;
1091 v.vector[2] = pixman_fixed_1;
1093 if (!pixman_transform_point_3d (pSrc->common.transform, &v))
1096 /* Round down to closest integer, ensuring that 0.5 rounds to 0, not 1 */
1097 v.vector[0] -= pixman_fixed_e;
1098 v.vector[1] -= pixman_fixed_e;
1100 for (j = 0; j < height; j++) {
1101 pixman_fixed_t vx = v.vector[0];
1102 pixman_fixed_t vy = v.vector[1];
1103 for (i = 0; i < width; ++i) {
1104 pixman_bool_t inside_bounds;
1110 /* apply the repeat function */
1111 switch (pSrc->common.repeat) {
1112 case PIXMAN_REPEAT_NORMAL:
1113 x = MOD (x, pSrc->bits.width);
1114 y = MOD (y, pSrc->bits.height);
1115 inside_bounds = TRUE;
1118 case PIXMAN_REPEAT_PAD:
1119 x = CLIP (x, 0, pSrc->bits.width-1);
1120 y = CLIP (y, 0, pSrc->bits.height-1);
1121 inside_bounds = TRUE;
1124 case PIXMAN_REPEAT_REFLECT:
1125 x = MOD (x, pSrc->bits.width * 2);
1126 if (x >= pSrc->bits.width)
1127 x = pSrc->bits.width * 2 - x - 1;
1128 y = MOD (y, pSrc->bits.height * 2);
1129 if (y >= pSrc->bits.height)
1130 y = pSrc->bits.height * 2 - y - 1;
1131 inside_bounds = TRUE;
1134 case PIXMAN_REPEAT_NONE:
1136 inside_bounds = (x >= 0 && x < pSrc->bits.width && y >= 0 && y < pSrc->bits.height);
1140 if (inside_bounds) {
1141 //XXX: we should move this multiplication out of the loop
1142 result = *(src + y * srcStride + x);
1146 *(dst + i) = result;
1148 /* adjust the x location by a unit vector in the x direction:
1149 * this is equivalent to transforming x+1 of the destination point to source space */
1150 vx += pSrc->common.transform->matrix[0][0];
1152 /* adjust the y location by a unit vector in the y direction
1153 * this is equivalent to transforming y+1 of the destination point to source space */
1154 v.vector[1] += pSrc->common.transform->matrix[1][1];
1160 fast_path_composite (pixman_implementation_t *imp,
1162 pixman_image_t *src,
1163 pixman_image_t *mask,
1164 pixman_image_t *dest,
1174 if (src->type == BITS
1175 && src->common.transform
1177 && op == PIXMAN_OP_SRC
1178 && !src->common.alpha_map && !dest->common.alpha_map
1179 && (src->common.filter == PIXMAN_FILTER_NEAREST)
1180 && PIXMAN_FORMAT_BPP(dest->bits.format) == 32
1181 && src->bits.format == dest->bits.format
1182 && !src->common.read_func && !src->common.write_func
1183 && !dest->common.read_func && !dest->common.write_func)
1185 /* ensure that the transform matrix only has a scale */
1186 if (src->common.transform->matrix[0][1] == 0 &&
1187 src->common.transform->matrix[1][0] == 0 &&
1188 src->common.transform->matrix[2][0] == 0 &&
1189 src->common.transform->matrix[2][1] == 0 &&
1190 src->common.transform->matrix[2][2] == pixman_fixed_1)
1192 _pixman_walk_composite_region (imp, op,
1198 fbCompositeSrcScaleNearest);
1203 if (_pixman_run_fast_path (c_fast_paths, imp,
1204 op, src, mask, dest,
1213 _pixman_implementation_composite (imp->delegate, op,
1222 pixman_fill8 (uint32_t *bits,
1230 int byte_stride = stride * (int) sizeof (uint32_t);
1231 uint8_t *dst = (uint8_t *) bits;
1232 uint8_t v = xor & 0xff;
1235 dst = dst + y * byte_stride + x;
1239 for (i = 0; i < width; ++i)
1247 pixman_fill16 (uint32_t *bits,
1255 int short_stride = (stride * (int) sizeof (uint32_t)) / (int) sizeof (uint16_t);
1256 uint16_t *dst = (uint16_t *)bits;
1257 uint16_t v = xor & 0xffff;
1260 dst = dst + y * short_stride + x;
1264 for (i = 0; i < width; ++i)
1267 dst += short_stride;
1272 pixman_fill32 (uint32_t *bits,
1282 bits = bits + y * stride + x;
1286 for (i = 0; i < width; ++i)
1293 static pixman_bool_t
1294 fast_path_fill (pixman_implementation_t *imp,
1307 pixman_fill8 (bits, stride, x, y, width, height, xor);
1311 pixman_fill16 (bits, stride, x, y, width, height, xor);
1315 pixman_fill32 (bits, stride, x, y, width, height, xor);
1319 return _pixman_implementation_fill (
1320 imp->delegate, bits, stride, bpp, x, y, width, height, xor);
1327 pixman_implementation_t *
1328 _pixman_implementation_create_fast_path (void)
1330 pixman_implementation_t *general = _pixman_implementation_create_general ();
1331 pixman_implementation_t *imp = _pixman_implementation_create (general);
1333 imp->composite = fast_path_composite;
1334 imp->fill = fast_path_fill;