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.
33 #include "pixman-private.h"
34 #include "pixman-mmx.h"
35 #include "pixman-vmx.h"
36 #include "pixman-sse.h"
38 #define FbFullMask(n) ((n) == 32 ? (uint32_t)-1 : ((((uint32_t) 1) << n) - 1))
42 #define READ(img,x) (*(x))
43 #define WRITE(img,ptr,v) ((*(ptr)) = (v))
45 typedef void (* CompositeFunc) (pixman_op_t,
46 pixman_image_t *, pixman_image_t *, pixman_image_t *,
47 int16_t, int16_t, int16_t, int16_t, int16_t, int16_t,
51 fbOver (uint32_t x, uint32_t y)
53 uint16_t a = ~x >> 24;
57 m = FbOverU(x,y,0,a,t);
58 n = FbOverU(x,y,8,a,t);
59 o = FbOverU(x,y,16,a,t);
60 p = FbOverU(x,y,24,a,t);
65 fbOver24 (uint32_t x, uint32_t y)
67 uint16_t a = ~x >> 24;
71 m = FbOverU(x,y,0,a,t);
72 n = FbOverU(x,y,8,a,t);
73 o = FbOverU(x,y,16,a,t);
78 fbIn (uint32_t x, uint8_t y)
98 fbCompositeOver_x888x8x8888 (pixman_op_t op,
99 pixman_image_t * pSrc,
100 pixman_image_t * pMask,
101 pixman_image_t * pDst,
111 uint32_t *src, *srcLine;
112 uint32_t *dst, *dstLine;
113 uint8_t *mask, *maskLine;
114 int srcStride, maskStride, dstStride;
119 fbComposeGetStart (pDst, xDst, yDst, uint32_t, dstStride, dstLine, 1);
120 fbComposeGetStart (pMask, xMask, yMask, uint8_t, maskStride, maskLine, 1);
121 fbComposeGetStart (pSrc, xSrc, ySrc, uint32_t, srcStride, srcLine, 1);
126 srcLine += srcStride;
128 dstLine += dstStride;
130 maskLine += maskStride;
135 m = READ(pMask, mask++);
138 s = READ(pSrc, src) | 0xff000000;
145 WRITE(pDst, dst, fbOver (d, READ(pDst, dst)));
155 fbCompositeSolidMaskIn_nx8x8 (pixman_op_t op,
156 pixman_image_t *iSrc,
157 pixman_image_t *iMask,
158 pixman_image_t *iDst,
169 uint8_t *dstLine, *dst, dstMask;
170 uint8_t *maskLine, *mask, m;
171 int dstStride, maskStride;
175 fbComposeGetSolid(iSrc, src, iDst->bits.format);
177 dstMask = FbFullMask (PIXMAN_FORMAT_DEPTH (iDst->bits.format));
180 fbComposeGetStart (iDst, xDst, yDst, uint8_t, dstStride, dstLine, 1);
181 fbComposeGetStart (iMask, xMask, yMask, uint8_t, maskStride, maskLine, 1);
187 dstLine += dstStride;
189 maskLine += maskStride;
201 *dst = FbIntMult(m, *dst, t);
212 dstLine += dstStride;
214 maskLine += maskStride;
220 m = FbIntMult(m, srca, t);
227 *dst = FbIntMult(m, *dst, t);
237 fbCompositeSrcIn_8x8 (pixman_op_t op,
238 pixman_image_t *iSrc,
239 pixman_image_t *iMask,
240 pixman_image_t *iDst,
250 uint8_t *dstLine, *dst;
251 uint8_t *srcLine, *src;
252 int dstStride, srcStride;
257 fbComposeGetStart (iSrc, xSrc, ySrc, uint8_t, srcStride, srcLine, 1);
258 fbComposeGetStart (iDst, xDst, yDst, uint8_t, dstStride, dstLine, 1);
263 dstLine += dstStride;
265 srcLine += srcStride;
277 *dst = FbIntMult(s, *dst, t);
285 fbCompositeSolidMask_nx8x8888 (pixman_op_t op,
286 pixman_image_t * pSrc,
287 pixman_image_t * pMask,
288 pixman_image_t * pDst,
299 uint32_t *dstLine, *dst, d, dstMask;
300 uint8_t *maskLine, *mask, m;
301 int dstStride, maskStride;
304 fbComposeGetSolid(pSrc, src, pDst->bits.format);
306 dstMask = FbFullMask (PIXMAN_FORMAT_DEPTH (pDst->bits.format));
311 fbComposeGetStart (pDst, xDst, yDst, uint32_t, dstStride, dstLine, 1);
312 fbComposeGetStart (pMask, xMask, yMask, uint8_t, maskStride, maskLine, 1);
317 dstLine += dstStride;
319 maskLine += maskStride;
324 m = READ(pMask, mask++);
328 WRITE(pDst, dst, src & dstMask);
330 WRITE(pDst, dst, fbOver (src, READ(pDst, dst)) & dstMask);
335 WRITE(pDst, dst, fbOver (d, READ(pDst, dst)) & dstMask);
343 fbCompositeSolidMask_nx8888x8888C (pixman_op_t op,
344 pixman_image_t * pSrc,
345 pixman_image_t * pMask,
346 pixman_image_t * pDst,
357 uint32_t *dstLine, *dst, d, dstMask;
358 uint32_t *maskLine, *mask, ma;
359 int dstStride, maskStride;
363 fbComposeGetSolid(pSrc, src, pDst->bits.format);
365 dstMask = FbFullMask (PIXMAN_FORMAT_DEPTH (pDst->bits.format));
370 fbComposeGetStart (pDst, xDst, yDst, uint32_t, dstStride, dstLine, 1);
371 fbComposeGetStart (pMask, xMask, yMask, uint32_t, maskStride, maskLine, 1);
376 dstLine += dstStride;
378 maskLine += maskStride;
383 ma = READ(pMask, mask++);
384 if (ma == 0xffffffff)
387 WRITE(pDst, dst, src & dstMask);
389 WRITE(pDst, dst, fbOver (src, READ(pDst, dst)) & dstMask);
394 #define FbInOverC(src,srca,msk,dst,i,result) { \
395 uint16_t __a = FbGet8(msk,i); \
396 uint32_t __t, __ta; \
398 __t = FbIntMult (FbGet8(src,i), __a,__i); \
399 __ta = (uint8_t) ~FbIntMult (srca, __a,__i); \
400 __t = __t + FbIntMult(FbGet8(dst,i),__ta,__i); \
401 __t = (uint32_t) (uint8_t) (__t | (-(__t >> 8))); \
402 result = __t << (i); \
404 FbInOverC (src, srca, ma, d, 0, m);
405 FbInOverC (src, srca, ma, d, 8, n);
406 FbInOverC (src, srca, ma, d, 16, o);
407 FbInOverC (src, srca, ma, d, 24, p);
408 WRITE(pDst, dst, m|n|o|p);
416 fbCompositeSolidMask_nx8x0888 (pixman_op_t op,
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 fbComposeGetSolid(pSrc, src, 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;
455 m = READ(pMask, mask++);
462 d = Fetch24(pDst, dst);
463 d = fbOver24 (src, d);
465 Store24(pDst, dst,d);
469 d = fbOver24 (fbIn(src,m), Fetch24(pDst, dst));
470 Store24(pDst, dst, d);
478 fbCompositeSolidMask_nx8x0565 (pixman_op_t op,
479 pixman_image_t * pSrc,
480 pixman_image_t * pMask,
481 pixman_image_t * pDst,
492 uint16_t *dstLine, *dst;
494 uint8_t *maskLine, *mask, m;
495 int dstStride, maskStride;
498 fbComposeGetSolid(pSrc, src, pDst->bits.format);
504 fbComposeGetStart (pDst, xDst, yDst, uint16_t, dstStride, dstLine, 1);
505 fbComposeGetStart (pMask, xMask, yMask, uint8_t, maskStride, maskLine, 1);
510 dstLine += dstStride;
512 maskLine += maskStride;
517 m = READ(pMask, mask++);
525 d = fbOver24 (src, cvt0565to0888(d));
527 WRITE(pDst, dst, cvt8888to0565(d));
532 d = fbOver24 (fbIn(src,m), cvt0565to0888(d));
533 WRITE(pDst, dst, cvt8888to0565(d));
541 fbCompositeSolidMask_nx8888x0565C (pixman_op_t op,
542 pixman_image_t * pSrc,
543 pixman_image_t * pMask,
544 pixman_image_t * pDst,
556 uint16_t *dstLine, *dst;
558 uint32_t *maskLine, *mask, ma;
559 int dstStride, maskStride;
563 fbComposeGetSolid(pSrc, src, pDst->bits.format);
569 src16 = cvt8888to0565(src);
571 fbComposeGetStart (pDst, xDst, yDst, uint16_t, dstStride, dstLine, 1);
572 fbComposeGetStart (pMask, xMask, yMask, uint32_t, maskStride, maskLine, 1);
577 dstLine += dstStride;
579 maskLine += maskStride;
584 ma = READ(pMask, mask++);
585 if (ma == 0xffffffff)
589 WRITE(pDst, dst, src16);
594 d = fbOver24 (src, cvt0565to0888(d));
595 WRITE(pDst, dst, cvt8888to0565(d));
601 d = cvt0565to0888(d);
602 FbInOverC (src, srca, ma, d, 0, m);
603 FbInOverC (src, srca, ma, d, 8, n);
604 FbInOverC (src, srca, ma, d, 16, o);
606 WRITE(pDst, dst, cvt8888to0565(d));
614 fbCompositeSrc_8888x8888 (pixman_op_t op,
615 pixman_image_t * pSrc,
616 pixman_image_t * pMask,
617 pixman_image_t * pDst,
627 uint32_t *dstLine, *dst, dstMask;
628 uint32_t *srcLine, *src, s;
629 int dstStride, srcStride;
633 fbComposeGetStart (pDst, xDst, yDst, uint32_t, dstStride, dstLine, 1);
634 fbComposeGetStart (pSrc, xSrc, ySrc, uint32_t, srcStride, srcLine, 1);
636 dstMask = FbFullMask (PIXMAN_FORMAT_DEPTH (pDst->bits.format));
641 dstLine += dstStride;
643 srcLine += srcStride;
648 s = READ(pSrc, src++);
651 WRITE(pDst, dst, s & dstMask);
653 WRITE(pDst, dst, fbOver (s, READ(pDst, dst)) & dstMask);
660 fbCompositeSrc_8888x0888 (pixman_op_t op,
661 pixman_image_t * pSrc,
662 pixman_image_t * pMask,
663 pixman_image_t * pDst,
673 uint8_t *dstLine, *dst;
675 uint32_t *srcLine, *src, s;
677 int dstStride, srcStride;
680 fbComposeGetStart (pDst, xDst, yDst, uint8_t, dstStride, dstLine, 3);
681 fbComposeGetStart (pSrc, xSrc, ySrc, uint32_t, srcStride, srcLine, 1);
686 dstLine += dstStride;
688 srcLine += srcStride;
693 s = READ(pSrc, src++);
700 d = fbOver24 (s, Fetch24(pDst, dst));
701 Store24(pDst, dst, d);
709 fbCompositeSrc_8888x0565 (pixman_op_t op,
710 pixman_image_t * pSrc,
711 pixman_image_t * pMask,
712 pixman_image_t * pDst,
722 uint16_t *dstLine, *dst;
724 uint32_t *srcLine, *src, s;
726 int dstStride, srcStride;
729 fbComposeGetStart (pSrc, xSrc, ySrc, uint32_t, srcStride, srcLine, 1);
730 fbComposeGetStart (pDst, xDst, yDst, uint16_t, dstStride, dstLine, 1);
735 dstLine += dstStride;
737 srcLine += srcStride;
742 s = READ(pSrc, src++);
751 d = fbOver24 (s, cvt0565to0888(d));
753 WRITE(pDst, dst, cvt8888to0565(d));
761 fbCompositeSrcAdd_8000x8000 (pixman_op_t op,
762 pixman_image_t * pSrc,
763 pixman_image_t * pMask,
764 pixman_image_t * pDst,
774 uint8_t *dstLine, *dst;
775 uint8_t *srcLine, *src;
776 int dstStride, srcStride;
781 fbComposeGetStart (pSrc, xSrc, ySrc, uint8_t, srcStride, srcLine, 1);
782 fbComposeGetStart (pDst, xDst, yDst, uint8_t, dstStride, dstLine, 1);
787 dstLine += dstStride;
789 srcLine += srcStride;
794 s = READ(pSrc, src++);
801 s = t | (0 - (t >> 8));
811 fbCompositeSrcAdd_8888x8888 (pixman_op_t op,
812 pixman_image_t * pSrc,
813 pixman_image_t * pMask,
814 pixman_image_t * pDst,
824 uint32_t *dstLine, *dst;
825 uint32_t *srcLine, *src;
826 int dstStride, srcStride;
832 fbComposeGetStart (pSrc, xSrc, ySrc, uint32_t, srcStride, srcLine, 1);
833 fbComposeGetStart (pDst, xDst, yDst, uint32_t, dstStride, dstLine, 1);
838 dstLine += dstStride;
840 srcLine += srcStride;
845 s = READ(pSrc, src++);
868 fbCompositeSrcAdd_8888x8x8 (pixman_op_t op,
869 pixman_image_t * pSrc,
870 pixman_image_t * pMask,
871 pixman_image_t * pDst,
881 uint8_t *dstLine, *dst;
882 uint8_t *maskLine, *mask;
883 int dstStride, maskStride;
888 fbComposeGetStart (pDst, xDst, yDst, uint8_t, dstStride, dstLine, 1);
889 fbComposeGetStart (pMask, xMask, yMask, uint8_t, maskStride, maskLine, 1);
890 fbComposeGetSolid (pSrc, src, pDst->bits.format);
896 dstLine += dstStride;
898 maskLine += maskStride;
908 a = READ(pMask, mask++);
911 m = FbInU (sa, 0, a, tmp);
912 r = FbAdd (m, d, 0, tmp);
914 WRITE(pDst, dst++, r);
920 fbCompositeSrcAdd_1000x1000 (pixman_op_t op,
921 pixman_image_t * pSrc,
922 pixman_image_t * pMask,
923 pixman_image_t * pDst,
936 uint32_t *dstBits, *srcBits;
937 int dstStride, srcStride;
939 int dstXoff, dstYoff;
940 int srcXoff, srcYoff;
942 fbGetDrawable(pSrc->pDrawable, srcBits, srcStride, srcBpp, srcXoff, srcYoff);
944 fbGetDrawable(pDst->pDrawable, dstBits, dstStride, dstBpp, dstXoff, dstYoff);
946 fbBlt (srcBits + srcStride * (ySrc + srcYoff),
950 dstBits + dstStride * (yDst + dstYoff),
968 fbCompositeSolidMask_nx1xn (pixman_op_t op,
969 pixman_image_t * pSrc,
970 pixman_image_t * pMask,
971 pixman_image_t * pDst,
985 int dstStride, maskStride;
987 int dstXoff, dstYoff;
988 int maskXoff, maskYoff;
991 fbComposeGetSolid(pSrc, src, pDst->bits.format);
992 fbGetStipDrawable (pMask->pDrawable, maskBits, maskStride, maskBpp, maskXoff, maskYoff);
993 fbGetDrawable (pDst->pDrawable, dstBits, dstStride, dstBpp, dstXoff, dstYoff);
1001 src = cvt8888to0565(src);
1005 src = fbReplicatePixel (src, dstBpp);
1007 fbBltOne (maskBits + maskStride * (yMask + maskYoff),
1011 dstBits + dstStride * (yDst + dstYoff),
1013 (xDst + dstXoff) * dstBpp,
1028 * Apply a constant alpha value in an over computation
1031 fbCompositeSrcSrc_nxn (pixman_op_t op,
1032 pixman_image_t * pSrc,
1033 pixman_image_t * pMask,
1034 pixman_image_t * pDst,
1049 fbCompositeSrcSrc_nxn (pixman_op_t op,
1050 pixman_image_t * pSrc,
1051 pixman_image_t * pMask,
1052 pixman_image_t * pDst,
1066 int dstStride, srcStride;
1067 int srcXoff, srcYoff;
1068 int dstXoff, dstYoff;
1071 pixman_bool_t reverse = FALSE;
1072 pixman_bool_t upsidedown = FALSE;
1074 fbGetDrawable(pSrc->pDrawable,src,srcStride,srcBpp,srcXoff,srcYoff);
1075 fbGetDrawable(pDst->pDrawable,dst,dstStride,dstBpp,dstXoff,dstYoff);
1077 fbBlt (src + (ySrc + srcYoff) * srcStride,
1079 (xSrc + srcXoff) * srcBpp,
1081 dst + (yDst + dstYoff) * dstStride,
1083 (xDst + dstXoff) * dstBpp,
1098 pixman_image_composite_rect (pixman_op_t op,
1099 pixman_image_t *src,
1100 pixman_image_t *mask,
1101 pixman_image_t *dest,
1111 fbCompositeSolidFill (pixman_op_t op,
1112 pixman_image_t * pSrc,
1113 pixman_image_t * pMask,
1114 pixman_image_t * pDst,
1126 fbComposeGetSolid(pSrc, src, pDst->bits.format);
1128 if (pDst->bits.format == PIXMAN_a8)
1130 else if (pDst->bits.format == PIXMAN_r5g6b5 ||
1131 pDst->bits.format == PIXMAN_b5g6r5)
1132 src = cvt8888to0565 (src);
1134 pixman_fill (pDst->bits.bits, pDst->bits.rowstride,
1135 PIXMAN_FORMAT_BPP (pDst->bits.format),
1142 fbCompositeSrc_8888xx888 (pixman_op_t op,
1143 pixman_image_t * pSrc,
1144 pixman_image_t * pMask,
1145 pixman_image_t * pDst,
1157 int dstStride, srcStride;
1158 uint32_t n_bytes = width * sizeof (uint32_t);
1160 fbComposeGetStart (pSrc, xSrc, ySrc, uint32_t, srcStride, src, 1);
1161 fbComposeGetStart (pDst, xDst, yDst, uint32_t, dstStride, dst, 1);
1165 memcpy (dst, src, n_bytes);
1173 pixman_walk_composite_region (pixman_op_t op,
1174 pixman_image_t * pSrc,
1175 pixman_image_t * pMask,
1176 pixman_image_t * pDst,
1185 pixman_bool_t srcRepeat,
1186 pixman_bool_t maskRepeat,
1187 CompositeFunc compositeRect)
1190 const pixman_box32_t *pbox;
1191 int w, h, w_this, h_this;
1192 int x_msk, y_msk, x_src, y_src, x_dst, y_dst;
1193 pixman_region32_t reg;
1194 pixman_region32_t *region;
1196 pixman_region32_init (®);
1197 if (!pixman_compute_composite_region32 (®, pSrc, pMask, pDst,
1198 xSrc, ySrc, xMask, yMask, xDst, yDst, width, height))
1205 pbox = pixman_region32_rectangles (region, &n);
1208 h = pbox->y2 - pbox->y1;
1209 y_src = pbox->y1 - yDst + ySrc;
1210 y_msk = pbox->y1 - yDst + yMask;
1215 w = pbox->x2 - pbox->x1;
1216 x_src = pbox->x1 - xDst + xSrc;
1217 x_msk = pbox->x1 - xDst + xMask;
1221 y_msk = MOD (y_msk, pMask->bits.height);
1222 if (h_this > pMask->bits.height - y_msk)
1223 h_this = pMask->bits.height - y_msk;
1227 y_src = MOD (y_src, pSrc->bits.height);
1228 if (h_this > pSrc->bits.height - y_src)
1229 h_this = pSrc->bits.height - y_src;
1236 x_msk = MOD (x_msk, pMask->bits.width);
1237 if (w_this > pMask->bits.width - x_msk)
1238 w_this = pMask->bits.width - x_msk;
1242 x_src = MOD (x_src, pSrc->bits.width);
1243 if (w_this > pSrc->bits.width - x_src)
1244 w_this = pSrc->bits.width - x_src;
1246 (*compositeRect) (op, pSrc, pMask, pDst,
1247 x_src, y_src, x_msk, y_msk, x_dst, y_dst,
1261 pixman_region32_fini (®);
1265 pixman_image_composite_rect (pixman_op_t op,
1266 pixman_image_t *src,
1267 pixman_image_t *mask,
1268 pixman_image_t *dest,
1278 FbComposeData compose_data;
1280 return_if_fail (src != NULL);
1281 return_if_fail (dest != NULL);
1283 compose_data.op = op;
1284 compose_data.src = src;
1285 compose_data.mask = mask;
1286 compose_data.dest = dest;
1287 compose_data.xSrc = src_x;
1288 compose_data.ySrc = src_y;
1289 compose_data.xMask = mask_x;
1290 compose_data.yMask = mask_y;
1291 compose_data.xDest = dest_x;
1292 compose_data.yDest = dest_y;
1293 compose_data.width = width;
1294 compose_data.height = height;
1296 pixman_composite_rect_general (&compose_data);
1299 /* These "formats" both have depth 0, so they
1300 * will never clash with any real ones
1302 #define PIXMAN_null PIXMAN_FORMAT(0,0,0,0,0,0)
1303 #define PIXMAN_solid PIXMAN_FORMAT(0,1,0,0,0,0)
1305 #define NEED_COMPONENT_ALPHA (1 << 0)
1306 #define NEED_PIXBUF (1 << 1)
1307 #define NEED_SOLID_MASK (1 << 2)
1312 pixman_format_code_t src_format;
1313 pixman_format_code_t mask_format;
1314 pixman_format_code_t dest_format;
1320 static const FastPathInfo mmx_fast_paths[] =
1322 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8, PIXMAN_r5g6b5, fbCompositeSolidMask_nx8x0565mmx, 0 },
1323 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8, PIXMAN_b5g6r5, fbCompositeSolidMask_nx8x0565mmx, 0 },
1324 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8, PIXMAN_a8r8g8b8, fbCompositeSolidMask_nx8x8888mmx, 0 },
1325 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8, PIXMAN_x8r8g8b8, fbCompositeSolidMask_nx8x8888mmx, 0 },
1326 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8, PIXMAN_a8b8g8r8, fbCompositeSolidMask_nx8x8888mmx, 0 },
1327 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8, PIXMAN_x8b8g8r8, fbCompositeSolidMask_nx8x8888mmx, 0 },
1328 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8r8g8b8, PIXMAN_a8r8g8b8, fbCompositeSolidMask_nx8888x8888Cmmx, NEED_COMPONENT_ALPHA },
1329 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8r8g8b8, PIXMAN_x8r8g8b8, fbCompositeSolidMask_nx8888x8888Cmmx, NEED_COMPONENT_ALPHA },
1330 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8r8g8b8, PIXMAN_r5g6b5, fbCompositeSolidMask_nx8888x0565Cmmx, NEED_COMPONENT_ALPHA },
1331 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8b8g8r8, PIXMAN_a8b8g8r8, fbCompositeSolidMask_nx8888x8888Cmmx, NEED_COMPONENT_ALPHA },
1332 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8b8g8r8, PIXMAN_x8b8g8r8, fbCompositeSolidMask_nx8888x8888Cmmx, NEED_COMPONENT_ALPHA },
1333 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8b8g8r8, PIXMAN_b5g6r5, fbCompositeSolidMask_nx8888x0565Cmmx, NEED_COMPONENT_ALPHA },
1334 { PIXMAN_OP_OVER, PIXMAN_x8b8g8r8, PIXMAN_a8r8g8b8, PIXMAN_a8r8g8b8, fbCompositeSrc_8888RevNPx8888mmx, NEED_PIXBUF },
1335 { PIXMAN_OP_OVER, PIXMAN_x8b8g8r8, PIXMAN_a8b8g8r8, PIXMAN_a8r8g8b8, fbCompositeSrc_8888RevNPx8888mmx, NEED_PIXBUF },
1336 { PIXMAN_OP_OVER, PIXMAN_x8b8g8r8, PIXMAN_a8r8g8b8, PIXMAN_x8r8g8b8, fbCompositeSrc_8888RevNPx8888mmx, NEED_PIXBUF },
1337 { PIXMAN_OP_OVER, PIXMAN_x8b8g8r8, PIXMAN_a8b8g8r8, PIXMAN_x8r8g8b8, fbCompositeSrc_8888RevNPx8888mmx, NEED_PIXBUF },
1338 { PIXMAN_OP_OVER, PIXMAN_x8b8g8r8, PIXMAN_a8r8g8b8, PIXMAN_r5g6b5, fbCompositeSrc_8888RevNPx0565mmx, NEED_PIXBUF },
1339 { PIXMAN_OP_OVER, PIXMAN_x8b8g8r8, PIXMAN_a8b8g8r8, PIXMAN_r5g6b5, fbCompositeSrc_8888RevNPx0565mmx, NEED_PIXBUF },
1340 { PIXMAN_OP_OVER, PIXMAN_x8r8g8b8, PIXMAN_a8r8g8b8, PIXMAN_a8b8g8r8, fbCompositeSrc_8888RevNPx8888mmx, NEED_PIXBUF },
1341 { PIXMAN_OP_OVER, PIXMAN_x8r8g8b8, PIXMAN_a8b8g8r8, PIXMAN_a8b8g8r8, fbCompositeSrc_8888RevNPx8888mmx, NEED_PIXBUF },
1342 { PIXMAN_OP_OVER, PIXMAN_x8r8g8b8, PIXMAN_a8r8g8b8, PIXMAN_x8b8g8r8, fbCompositeSrc_8888RevNPx8888mmx, NEED_PIXBUF },
1343 { PIXMAN_OP_OVER, PIXMAN_x8r8g8b8, PIXMAN_a8b8g8r8, PIXMAN_x8b8g8r8, fbCompositeSrc_8888RevNPx8888mmx, NEED_PIXBUF },
1344 { PIXMAN_OP_OVER, PIXMAN_x8r8g8b8, PIXMAN_a8r8g8b8, PIXMAN_b5g6r5, fbCompositeSrc_8888RevNPx0565mmx, NEED_PIXBUF },
1345 { PIXMAN_OP_OVER, PIXMAN_x8r8g8b8, PIXMAN_a8b8g8r8, PIXMAN_b5g6r5, fbCompositeSrc_8888RevNPx0565mmx, NEED_PIXBUF },
1346 { PIXMAN_OP_OVER, PIXMAN_x8r8g8b8, PIXMAN_a8, PIXMAN_a8r8g8b8, fbCompositeSrc_x888xnx8888mmx, NEED_SOLID_MASK },
1347 { PIXMAN_OP_OVER, PIXMAN_x8r8g8b8, PIXMAN_a8, PIXMAN_x8r8g8b8, fbCompositeSrc_x888xnx8888mmx, NEED_SOLID_MASK },
1348 { PIXMAN_OP_OVER, PIXMAN_x8b8g8r8, PIXMAN_a8, PIXMAN_a8b8g8r8, fbCompositeSrc_x888xnx8888mmx, NEED_SOLID_MASK },
1349 { PIXMAN_OP_OVER, PIXMAN_x8b8g8r8, PIXMAN_a8, PIXMAN_x8b8g8r8, fbCompositeSrc_x888xnx8888mmx, NEED_SOLID_MASK },
1350 { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_a8, PIXMAN_a8r8g8b8, fbCompositeSrc_8888x8x8888mmx, NEED_SOLID_MASK },
1351 { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_a8, PIXMAN_x8r8g8b8, fbCompositeSrc_8888x8x8888mmx, NEED_SOLID_MASK },
1352 { PIXMAN_OP_OVER, PIXMAN_a8b8g8r8, PIXMAN_a8, PIXMAN_a8b8g8r8, fbCompositeSrc_8888x8x8888mmx, NEED_SOLID_MASK },
1353 { PIXMAN_OP_OVER, PIXMAN_a8b8g8r8, PIXMAN_a8, PIXMAN_x8b8g8r8, fbCompositeSrc_8888x8x8888mmx, NEED_SOLID_MASK },
1355 /* FIXME: This code is commented out since it's apparently not actually faster than the generic code. */
1356 { PIXMAN_OP_OVER, PIXMAN_x8r8g8b8, PIXMAN_a8, PIXMAN_x8r8g8b8, fbCompositeOver_x888x8x8888mmx, 0 },
1357 { PIXMAN_OP_OVER, PIXMAN_x8r8g8b8, PIXMAN_a8, PIXMAN_a8r8g8b8, fbCompositeOver_x888x8x8888mmx, 0 },
1358 { PIXMAN_OP_OVER, PIXMAN_x8b8r8g8, PIXMAN_a8, PIXMAN_x8b8g8r8, fbCompositeOver_x888x8x8888mmx, 0 },
1359 { PIXMAN_OP_OVER, PIXMAN_x8b8r8g8, PIXMAN_a8, PIXMAN_a8r8g8b8, fbCompositeOver_x888x8x8888mmx, 0 },
1361 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_null, PIXMAN_a8r8g8b8, fbCompositeSolid_nx8888mmx, 0 },
1362 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_null, PIXMAN_x8r8g8b8, fbCompositeSolid_nx8888mmx, 0 },
1363 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_null, PIXMAN_r5g6b5, fbCompositeSolid_nx0565mmx, 0 },
1364 { PIXMAN_OP_OVER, PIXMAN_x8r8g8b8, PIXMAN_null, PIXMAN_x8r8g8b8, fbCompositeCopyAreammx, 0 },
1365 { PIXMAN_OP_OVER, PIXMAN_x8b8g8r8, PIXMAN_null, PIXMAN_x8b8g8r8, fbCompositeCopyAreammx, 0 },
1366 { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_null, PIXMAN_a8r8g8b8, fbCompositeSrc_8888x8888mmx, 0 },
1367 { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_null, PIXMAN_x8r8g8b8, fbCompositeSrc_8888x8888mmx, 0 },
1368 { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_null, PIXMAN_r5g6b5, fbCompositeSrc_8888x0565mmx, 0 },
1369 { PIXMAN_OP_OVER, PIXMAN_a8b8g8r8, PIXMAN_null, PIXMAN_a8b8g8r8, fbCompositeSrc_8888x8888mmx, 0 },
1370 { PIXMAN_OP_OVER, PIXMAN_a8b8g8r8, PIXMAN_null, PIXMAN_x8b8g8r8, fbCompositeSrc_8888x8888mmx, 0 },
1371 { PIXMAN_OP_OVER, PIXMAN_a8b8g8r8, PIXMAN_null, PIXMAN_b5g6r5, fbCompositeSrc_8888x0565mmx, 0 },
1373 { PIXMAN_OP_ADD, PIXMAN_a8r8g8b8, PIXMAN_null, PIXMAN_a8r8g8b8, fbCompositeSrcAdd_8888x8888mmx, 0 },
1374 { PIXMAN_OP_ADD, PIXMAN_a8b8g8r8, PIXMAN_null, PIXMAN_a8b8g8r8, fbCompositeSrcAdd_8888x8888mmx, 0 },
1375 { PIXMAN_OP_ADD, PIXMAN_a8, PIXMAN_null, PIXMAN_a8, fbCompositeSrcAdd_8000x8000mmx, 0 },
1376 { PIXMAN_OP_ADD, PIXMAN_solid, PIXMAN_a8, PIXMAN_a8, fbCompositeSrcAdd_8888x8x8mmx, 0 },
1377 { PIXMAN_OP_SRC, PIXMAN_solid, PIXMAN_a8, PIXMAN_a8r8g8b8, fbCompositeSolidMaskSrc_nx8x8888mmx, 0 },
1378 { PIXMAN_OP_SRC, PIXMAN_solid, PIXMAN_a8, PIXMAN_x8r8g8b8, fbCompositeSolidMaskSrc_nx8x8888mmx, 0 },
1379 { PIXMAN_OP_SRC, PIXMAN_solid, PIXMAN_a8, PIXMAN_a8b8g8r8, fbCompositeSolidMaskSrc_nx8x8888mmx, 0 },
1380 { PIXMAN_OP_SRC, PIXMAN_solid, PIXMAN_a8, PIXMAN_x8b8g8r8, fbCompositeSolidMaskSrc_nx8x8888mmx, 0 },
1382 { PIXMAN_OP_SRC, PIXMAN_a8r8g8b8, PIXMAN_null, PIXMAN_a8r8g8b8, fbCompositeCopyAreammx, 0 },
1383 { PIXMAN_OP_SRC, PIXMAN_a8b8g8r8, PIXMAN_null, PIXMAN_a8b8g8r8, fbCompositeCopyAreammx, 0 },
1384 { PIXMAN_OP_SRC, PIXMAN_a8r8g8b8, PIXMAN_null, PIXMAN_x8r8g8b8, fbCompositeCopyAreammx, 0 },
1385 { PIXMAN_OP_SRC, PIXMAN_a8b8g8r8, PIXMAN_null, PIXMAN_x8b8g8r8, fbCompositeCopyAreammx, 0 },
1386 { PIXMAN_OP_SRC, PIXMAN_x8r8g8b8, PIXMAN_null, PIXMAN_x8r8g8b8, fbCompositeCopyAreammx, 0 },
1387 { PIXMAN_OP_SRC, PIXMAN_x8b8g8r8, PIXMAN_null, PIXMAN_x8b8g8r8, fbCompositeCopyAreammx, 0 },
1388 { PIXMAN_OP_SRC, PIXMAN_r5g6b5, PIXMAN_null, PIXMAN_r5g6b5, fbCompositeCopyAreammx, 0 },
1389 { PIXMAN_OP_SRC, PIXMAN_b5g6r5, PIXMAN_null, PIXMAN_b5g6r5, fbCompositeCopyAreammx, 0 },
1390 { PIXMAN_OP_IN, PIXMAN_a8, PIXMAN_null, PIXMAN_a8, fbCompositeIn_8x8mmx, 0 },
1391 { PIXMAN_OP_IN, PIXMAN_solid, PIXMAN_a8, PIXMAN_a8, fbCompositeIn_nx8x8mmx, 0 },
1397 static const FastPathInfo sse_fast_paths[] =
1399 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8, PIXMAN_r5g6b5, fbCompositeSolidMask_nx8x0565sse2, 0 },
1400 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8, PIXMAN_b5g6r5, fbCompositeSolidMask_nx8x0565sse2, 0 },
1401 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_null, PIXMAN_a8r8g8b8, fbCompositeSolid_nx8888sse2, 0 },
1402 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_null, PIXMAN_x8r8g8b8, fbCompositeSolid_nx8888sse2, 0 },
1403 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_null, PIXMAN_r5g6b5, fbCompositeSolid_nx0565sse2, 0 },
1404 { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_null, PIXMAN_a8r8g8b8, fbCompositeSrc_8888x8888sse2, 0 },
1405 { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_null, PIXMAN_x8r8g8b8, fbCompositeSrc_8888x8888sse2, 0 },
1406 { PIXMAN_OP_OVER, PIXMAN_a8b8g8r8, PIXMAN_null, PIXMAN_a8b8g8r8, fbCompositeSrc_8888x8888sse2, 0 },
1407 { PIXMAN_OP_OVER, PIXMAN_a8b8g8r8, PIXMAN_null, PIXMAN_x8b8g8r8, fbCompositeSrc_8888x8888sse2, 0 },
1408 { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_null, PIXMAN_r5g6b5, fbCompositeSrc_8888x0565sse2, 0 },
1409 { PIXMAN_OP_OVER, PIXMAN_a8b8g8r8, PIXMAN_null, PIXMAN_b5g6r5, fbCompositeSrc_8888x0565sse2, 0 },
1410 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8, PIXMAN_a8r8g8b8, fbCompositeSolidMask_nx8x8888sse2, 0 },
1411 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8, PIXMAN_x8r8g8b8, fbCompositeSolidMask_nx8x8888sse2, 0 },
1412 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8, PIXMAN_a8b8g8r8, fbCompositeSolidMask_nx8x8888sse2, 0 },
1413 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8, PIXMAN_x8b8g8r8, fbCompositeSolidMask_nx8x8888sse2, 0 },
1415 /* FIXME: This code are buggy in MMX version, now the bug was translated to SSE2 version */
1416 { PIXMAN_OP_OVER, PIXMAN_x8r8g8b8, PIXMAN_a8, PIXMAN_x8r8g8b8, fbCompositeOver_x888x8x8888sse2, 0 },
1417 { PIXMAN_OP_OVER, PIXMAN_x8r8g8b8, PIXMAN_a8, PIXMAN_a8r8g8b8, fbCompositeOver_x888x8x8888sse2, 0 },
1418 { PIXMAN_OP_OVER, PIXMAN_x8b8g8r8, PIXMAN_a8, PIXMAN_x8b8g8r8, fbCompositeOver_x888x8x8888sse2, 0 },
1419 { PIXMAN_OP_OVER, PIXMAN_x8b8g8r8, PIXMAN_a8, PIXMAN_a8r8g8b8, fbCompositeOver_x888x8x8888sse2, 0 },
1421 { PIXMAN_OP_OVER, PIXMAN_x8r8g8b8, PIXMAN_a8, PIXMAN_a8r8g8b8, fbCompositeSrc_x888xnx8888sse2, NEED_SOLID_MASK },
1422 { PIXMAN_OP_OVER, PIXMAN_x8r8g8b8, PIXMAN_a8, PIXMAN_x8r8g8b8, fbCompositeSrc_x888xnx8888sse2, NEED_SOLID_MASK },
1423 { PIXMAN_OP_OVER, PIXMAN_x8b8g8r8, PIXMAN_a8, PIXMAN_a8b8g8r8, fbCompositeSrc_x888xnx8888sse2, NEED_SOLID_MASK },
1424 { PIXMAN_OP_OVER, PIXMAN_x8b8g8r8, PIXMAN_a8, PIXMAN_x8b8g8r8, fbCompositeSrc_x888xnx8888sse2, NEED_SOLID_MASK },
1425 { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_a8, PIXMAN_a8r8g8b8, fbCompositeSrc_8888x8x8888sse2, NEED_SOLID_MASK },
1426 { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_a8, PIXMAN_x8r8g8b8, fbCompositeSrc_8888x8x8888sse2, NEED_SOLID_MASK },
1427 { PIXMAN_OP_OVER, PIXMAN_a8b8g8r8, PIXMAN_a8, PIXMAN_a8b8g8r8, fbCompositeSrc_8888x8x8888sse2, NEED_SOLID_MASK },
1428 { PIXMAN_OP_OVER, PIXMAN_a8b8g8r8, PIXMAN_a8, PIXMAN_x8b8g8r8, fbCompositeSrc_8888x8x8888sse2, NEED_SOLID_MASK },
1429 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8r8g8b8, PIXMAN_a8r8g8b8, fbCompositeSolidMask_nx8888x8888Csse2, NEED_COMPONENT_ALPHA },
1430 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8r8g8b8, PIXMAN_x8r8g8b8, fbCompositeSolidMask_nx8888x8888Csse2, NEED_COMPONENT_ALPHA },
1431 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8b8g8r8, PIXMAN_a8b8g8r8, fbCompositeSolidMask_nx8888x8888Csse2, NEED_COMPONENT_ALPHA },
1432 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8b8g8r8, PIXMAN_x8b8g8r8, fbCompositeSolidMask_nx8888x8888Csse2, NEED_COMPONENT_ALPHA },
1433 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8r8g8b8, PIXMAN_r5g6b5, fbCompositeSolidMask_nx8888x0565Csse2, NEED_COMPONENT_ALPHA },
1434 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8b8g8r8, PIXMAN_b5g6r5, fbCompositeSolidMask_nx8888x0565Csse2, NEED_COMPONENT_ALPHA },
1435 { PIXMAN_OP_OVER, PIXMAN_x8b8g8r8, PIXMAN_a8r8g8b8, PIXMAN_a8r8g8b8, fbCompositeSrc_8888RevNPx8888sse2, NEED_PIXBUF },
1436 { PIXMAN_OP_OVER, PIXMAN_x8b8g8r8, PIXMAN_a8b8g8r8, PIXMAN_a8r8g8b8, fbCompositeSrc_8888RevNPx8888sse2, NEED_PIXBUF },
1437 { PIXMAN_OP_OVER, PIXMAN_x8b8g8r8, PIXMAN_a8r8g8b8, PIXMAN_x8r8g8b8, fbCompositeSrc_8888RevNPx8888sse2, NEED_PIXBUF },
1438 { PIXMAN_OP_OVER, PIXMAN_x8b8g8r8, PIXMAN_a8b8g8r8, PIXMAN_x8r8g8b8, fbCompositeSrc_8888RevNPx8888sse2, NEED_PIXBUF },
1439 { PIXMAN_OP_OVER, PIXMAN_x8r8g8b8, PIXMAN_a8r8g8b8, PIXMAN_a8b8g8r8, fbCompositeSrc_8888RevNPx8888sse2, NEED_PIXBUF },
1440 { PIXMAN_OP_OVER, PIXMAN_x8r8g8b8, PIXMAN_a8b8g8r8, PIXMAN_a8b8g8r8, fbCompositeSrc_8888RevNPx8888sse2, NEED_PIXBUF },
1441 { PIXMAN_OP_OVER, PIXMAN_x8r8g8b8, PIXMAN_a8r8g8b8, PIXMAN_x8b8g8r8, fbCompositeSrc_8888RevNPx8888sse2, NEED_PIXBUF },
1442 { PIXMAN_OP_OVER, PIXMAN_x8r8g8b8, PIXMAN_a8b8g8r8, PIXMAN_x8b8g8r8, fbCompositeSrc_8888RevNPx8888sse2, NEED_PIXBUF },
1443 { PIXMAN_OP_OVER, PIXMAN_x8b8g8r8, PIXMAN_a8r8g8b8, PIXMAN_r5g6b5, fbCompositeSrc_8888RevNPx0565sse2, NEED_PIXBUF },
1444 { PIXMAN_OP_OVER, PIXMAN_x8b8g8r8, PIXMAN_a8b8g8r8, PIXMAN_r5g6b5, fbCompositeSrc_8888RevNPx0565sse2, NEED_PIXBUF },
1445 { PIXMAN_OP_OVER, PIXMAN_x8r8g8b8, PIXMAN_a8r8g8b8, PIXMAN_b5g6r5, fbCompositeSrc_8888RevNPx0565sse2, NEED_PIXBUF },
1446 { PIXMAN_OP_OVER, PIXMAN_x8r8g8b8, PIXMAN_a8b8g8r8, PIXMAN_b5g6r5, fbCompositeSrc_8888RevNPx0565sse2, NEED_PIXBUF },
1448 /* FIXME: This code is commented out since it's apparently not actually faster than the generic code */
1449 { PIXMAN_OP_OVER, PIXMAN_x8r8g8b8, PIXMAN_null, PIXMAN_x8r8g8b8, fbCompositeCopyAreasse2, 0 },
1450 { PIXMAN_OP_OVER, PIXMAN_x8b8g8r8, PIXMAN_null, PIXMAN_x8b8g8r8, fbCompositeCopyAreasse2, 0 },
1453 { PIXMAN_OP_ADD, PIXMAN_a8, PIXMAN_null, PIXMAN_a8, fbCompositeSrcAdd_8000x8000sse2, 0 },
1454 { PIXMAN_OP_ADD, PIXMAN_a8r8g8b8, PIXMAN_null, PIXMAN_a8r8g8b8, fbCompositeSrcAdd_8888x8888sse2, 0 },
1455 { PIXMAN_OP_ADD, PIXMAN_a8b8g8r8, PIXMAN_null, PIXMAN_a8b8g8r8, fbCompositeSrcAdd_8888x8888sse2, 0 },
1456 { PIXMAN_OP_ADD, PIXMAN_solid, PIXMAN_a8, PIXMAN_a8, fbCompositeSrcAdd_8888x8x8sse2, 0 },
1458 { PIXMAN_OP_SRC, PIXMAN_solid, PIXMAN_a8, PIXMAN_a8r8g8b8, fbCompositeSolidMaskSrc_nx8x8888sse2, 0 },
1459 { PIXMAN_OP_SRC, PIXMAN_solid, PIXMAN_a8, PIXMAN_x8r8g8b8, fbCompositeSolidMaskSrc_nx8x8888sse2, 0 },
1460 { PIXMAN_OP_SRC, PIXMAN_solid, PIXMAN_a8, PIXMAN_a8b8g8r8, fbCompositeSolidMaskSrc_nx8x8888sse2, 0 },
1461 { PIXMAN_OP_SRC, PIXMAN_solid, PIXMAN_a8, PIXMAN_x8b8g8r8, fbCompositeSolidMaskSrc_nx8x8888sse2, 0 },
1464 /* FIXME: This code is commented out since it's apparently not actually faster than the generic code */
1465 { PIXMAN_OP_SRC, PIXMAN_a8r8g8b8, PIXMAN_null, PIXMAN_a8r8g8b8, fbCompositeCopyAreasse2, 0 },
1466 { PIXMAN_OP_SRC, PIXMAN_a8b8g8r8, PIXMAN_null, PIXMAN_a8b8g8r8, fbCompositeCopyAreasse2, 0 },
1467 { PIXMAN_OP_SRC, PIXMAN_x8r8g8b8, PIXMAN_null, PIXMAN_x8r8g8b8, fbCompositeCopyAreasse2, 0 },
1468 { PIXMAN_OP_SRC, PIXMAN_x8b8g8r8, PIXMAN_null, PIXMAN_x8b8g8r8, fbCompositeCopyAreasse2, 0 },
1469 { PIXMAN_OP_SRC, PIXMAN_r5g6b5, PIXMAN_null, PIXMAN_r5g6b5, fbCompositeCopyAreasse2, 0 },
1470 { PIXMAN_OP_SRC, PIXMAN_b5g6r5, PIXMAN_null, PIXMAN_b5g6r5, fbCompositeCopyAreasse2, 0 },
1473 { PIXMAN_OP_IN, PIXMAN_a8, PIXMAN_null, PIXMAN_a8, fbCompositeIn_8x8sse2, 0 },
1474 { PIXMAN_OP_IN, PIXMAN_solid, PIXMAN_a8, PIXMAN_a8, fbCompositeIn_nx8x8sse2, 0 },
1481 static const FastPathInfo vmx_fast_paths[] =
1488 static const FastPathInfo c_fast_paths[] =
1490 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8, PIXMAN_r5g6b5, fbCompositeSolidMask_nx8x0565, 0 },
1491 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8, PIXMAN_b5g6r5, fbCompositeSolidMask_nx8x0565, 0 },
1492 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8, PIXMAN_r8g8b8, fbCompositeSolidMask_nx8x0888, 0 },
1493 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8, PIXMAN_b8g8r8, fbCompositeSolidMask_nx8x0888, 0 },
1494 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8, PIXMAN_a8r8g8b8, fbCompositeSolidMask_nx8x8888, 0 },
1495 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8, PIXMAN_x8r8g8b8, fbCompositeSolidMask_nx8x8888, 0 },
1496 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8, PIXMAN_a8b8g8r8, fbCompositeSolidMask_nx8x8888, 0 },
1497 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8, PIXMAN_x8b8g8r8, fbCompositeSolidMask_nx8x8888, 0 },
1498 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8r8g8b8, PIXMAN_a8r8g8b8, fbCompositeSolidMask_nx8888x8888C, NEED_COMPONENT_ALPHA },
1499 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8r8g8b8, PIXMAN_x8r8g8b8, fbCompositeSolidMask_nx8888x8888C, NEED_COMPONENT_ALPHA },
1500 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8r8g8b8, PIXMAN_r5g6b5, fbCompositeSolidMask_nx8888x0565C, NEED_COMPONENT_ALPHA },
1501 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8b8g8r8, PIXMAN_a8b8g8r8, fbCompositeSolidMask_nx8888x8888C, NEED_COMPONENT_ALPHA },
1502 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8b8g8r8, PIXMAN_x8b8g8r8, fbCompositeSolidMask_nx8888x8888C, NEED_COMPONENT_ALPHA },
1503 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8b8g8r8, PIXMAN_b5g6r5, fbCompositeSolidMask_nx8888x0565C, NEED_COMPONENT_ALPHA },
1505 /* FIXME: This code is commented out since it's apparently not actually faster than the generic code */
1506 { PIXMAN_OP_OVER, PIXMAN_x8r8g8b8, PIXMAN_a8, PIXMAN_x8r8g8b8, fbCompositeOver_x888x8x8888, 0 },
1507 { PIXMAN_OP_OVER, PIXMAN_x8r8g8b8, PIXMAN_a8, PIXMAN_a8r8g8b8, fbCompositeOver_x888x8x8888, 0 },
1508 { PIXMAN_OP_OVER, PIXMAN_x8b8r8g8, PIXMAN_a8, PIXMAN_x8b8g8r8, fbCompositeOver_x888x8x8888, 0 },
1509 { PIXMAN_OP_OVER, PIXMAN_x8b8r8g8, PIXMAN_a8, PIXMAN_a8r8g8b8, fbCompositeOver_x888x8x8888, 0 },
1511 { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_null, PIXMAN_a8r8g8b8, fbCompositeSrc_8888x8888, 0 },
1512 { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_null, PIXMAN_x8r8g8b8, fbCompositeSrc_8888x8888, 0 },
1513 { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_null, PIXMAN_r5g6b5, fbCompositeSrc_8888x0565, 0 },
1514 { PIXMAN_OP_OVER, PIXMAN_a8b8g8r8, PIXMAN_null, PIXMAN_a8b8g8r8, fbCompositeSrc_8888x8888, 0 },
1515 { PIXMAN_OP_OVER, PIXMAN_a8b8g8r8, PIXMAN_null, PIXMAN_x8b8g8r8, fbCompositeSrc_8888x8888, 0 },
1516 { PIXMAN_OP_OVER, PIXMAN_a8b8g8r8, PIXMAN_null, PIXMAN_b5g6r5, fbCompositeSrc_8888x0565, 0 },
1519 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a1, PIXMAN_r5g6b5, fbCompositeSolidMask_nx1xn, 0 },
1520 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a1, PIXMAN_b5g6r5, fbCompositeSolidMask_nx1xn, 0 },
1521 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a1, PIXMAN_r8g8b8, fbCompositeSolidMask_nx1xn, 0 },
1522 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a1, PIXMAN_b8g8r8, fbCompositeSolidMask_nx1xn, 0 },
1523 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a1, PIXMAN_a8r8g8b8, fbCompositeSolidMask_nx1xn, 0 },
1524 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a1, PIXMAN_a8b8g8r8, fbCompositeSolidMask_nx1xn, 0 },
1525 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a1, PIXMAN_x8r8g8b8, fbCompositeSolidMask_nx1xn, 0 },
1526 { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a1, PIXMAN_x8b8g8r8, fbCompositeSolidMask_nx1xn, 0 },
1528 { PIXMAN_OP_ADD, PIXMAN_a8r8g8b8, PIXMAN_null, PIXMAN_a8r8g8b8, fbCompositeSrcAdd_8888x8888, 0 },
1529 { PIXMAN_OP_ADD, PIXMAN_a8b8g8r8, PIXMAN_null, PIXMAN_a8b8g8r8, fbCompositeSrcAdd_8888x8888, 0 },
1530 { PIXMAN_OP_ADD, PIXMAN_a8, PIXMAN_null, PIXMAN_a8, fbCompositeSrcAdd_8000x8000, 0 },
1533 { PIXMAN_OP_ADD, PIXMAN_a1, PIXMAN_null, PIXMAN_a1, fbCompositeSrcAdd_1000x1000, 0 },
1535 { PIXMAN_OP_ADD, PIXMAN_solid, PIXMAN_a8, PIXMAN_a8, fbCompositeSrcAdd_8888x8x8, 0 },
1536 { PIXMAN_OP_SRC, PIXMAN_solid, PIXMAN_null, PIXMAN_a8r8g8b8, fbCompositeSolidFill, 0 },
1537 { PIXMAN_OP_SRC, PIXMAN_solid, PIXMAN_null, PIXMAN_x8r8g8b8, fbCompositeSolidFill, 0 },
1538 { PIXMAN_OP_SRC, PIXMAN_solid, PIXMAN_null, PIXMAN_a8b8g8r8, fbCompositeSolidFill, 0 },
1539 { PIXMAN_OP_SRC, PIXMAN_solid, PIXMAN_null, PIXMAN_x8b8g8r8, fbCompositeSolidFill, 0 },
1540 { PIXMAN_OP_SRC, PIXMAN_solid, PIXMAN_null, PIXMAN_a8, fbCompositeSolidFill, 0 },
1541 { PIXMAN_OP_SRC, PIXMAN_solid, PIXMAN_null, PIXMAN_r5g6b5, fbCompositeSolidFill, 0 },
1542 { PIXMAN_OP_SRC, PIXMAN_a8r8g8b8, PIXMAN_null, PIXMAN_x8r8g8b8, fbCompositeSrc_8888xx888, 0 },
1543 { PIXMAN_OP_SRC, PIXMAN_x8r8g8b8, PIXMAN_null, PIXMAN_x8r8g8b8, fbCompositeSrc_8888xx888, 0 },
1544 { PIXMAN_OP_SRC, PIXMAN_a8b8g8r8, PIXMAN_null, PIXMAN_x8b8g8r8, fbCompositeSrc_8888xx888, 0 },
1545 { PIXMAN_OP_SRC, PIXMAN_x8b8g8r8, PIXMAN_null, PIXMAN_x8b8g8r8, fbCompositeSrc_8888xx888, 0 },
1548 { PIXMAN_OP_SRC, PIXMAN_a8r8g8b8, PIXMAN_null, PIXMAN_a8r8g8b8, fbCompositeSrcSrc_nxn, 0 },
1549 { PIXMAN_OP_SRC, PIXMAN_a8b8g8r8, PIXMAN_null, PIXMAN_a8b8g8r8, fbCompositeSrcSrc_nxn, 0 },
1550 { PIXMAN_OP_SRC, PIXMAN_x8r8g8b8, PIXMAN_null, PIXMAN_x8r8g8b8, fbCompositeSrcSrc_nxn, 0 },
1551 { PIXMAN_OP_SRC, PIXMAN_x8b8g8r8, PIXMAN_null, PIXMAN_x8b8g8r8, fbCompositeSrcSrc_nxn, 0 },
1552 { PIXMAN_OP_SRC, PIXMAN_r5g6b5, PIXMAN_null, PIXMAN_r5g6b5, fbCompositeSrcSrc_nxn, 0 },
1553 { PIXMAN_OP_SRC, PIXMAN_b5g6r5, PIXMAN_null, PIXMAN_b5g6r5, fbCompositeSrcSrc_nxn, 0 },
1555 { PIXMAN_OP_IN, PIXMAN_a8, PIXMAN_null, PIXMAN_a8, fbCompositeSrcIn_8x8, 0 },
1556 { PIXMAN_OP_IN, PIXMAN_solid, PIXMAN_a8, PIXMAN_a8, fbCompositeSolidMaskIn_nx8x8, 0 },
1560 static pixman_bool_t
1561 mask_is_solid (pixman_image_t *mask)
1563 if (mask->type == SOLID)
1566 if (mask->type == BITS &&
1567 mask->common.repeat == PIXMAN_REPEAT_NORMAL &&
1568 mask->bits.width == 1 &&
1569 mask->bits.height == 1)
1577 static const FastPathInfo *
1578 get_fast_path (const FastPathInfo *fast_paths,
1580 pixman_image_t *pSrc,
1581 pixman_image_t *pMask,
1582 pixman_image_t *pDst,
1583 pixman_bool_t is_pixbuf)
1585 const FastPathInfo *info;
1587 for (info = fast_paths; info->op != PIXMAN_OP_NONE; info++)
1589 pixman_bool_t valid_src = FALSE;
1590 pixman_bool_t valid_mask = FALSE;
1595 if ((info->src_format == PIXMAN_solid && pixman_image_can_get_solid (pSrc)) ||
1596 (pSrc->type == BITS && info->src_format == pSrc->bits.format))
1604 if ((info->mask_format == PIXMAN_null && !pMask) ||
1605 (pMask && pMask->type == BITS && info->mask_format == pMask->bits.format))
1609 if (info->flags & NEED_SOLID_MASK)
1611 if (!pMask || !mask_is_solid (pMask))
1615 if (info->flags & NEED_COMPONENT_ALPHA)
1617 if (!pMask || !pMask->common.component_alpha)
1625 if (info->dest_format != pDst->bits.format)
1628 if ((info->flags & NEED_PIXBUF) && !is_pixbuf)
1638 * Operator optimizations based on source or destination opacity
1643 pixman_op_t opSrcDstOpaque;
1644 pixman_op_t opSrcOpaque;
1645 pixman_op_t opDstOpaque;
1646 } OptimizedOperatorInfo;
1648 static const OptimizedOperatorInfo optimized_operators[] =
1650 /* Input Operator SRC&DST Opaque SRC Opaque DST Opaque */
1651 { PIXMAN_OP_OVER, PIXMAN_OP_SRC, PIXMAN_OP_SRC, PIXMAN_OP_OVER },
1652 { PIXMAN_OP_OVER_REVERSE, PIXMAN_OP_DST, PIXMAN_OP_OVER_REVERSE, PIXMAN_OP_DST },
1653 { PIXMAN_OP_IN, PIXMAN_OP_SRC, PIXMAN_OP_IN, PIXMAN_OP_SRC },
1654 { PIXMAN_OP_IN_REVERSE, PIXMAN_OP_DST, PIXMAN_OP_DST, PIXMAN_OP_IN_REVERSE },
1655 { PIXMAN_OP_OUT, PIXMAN_OP_CLEAR, PIXMAN_OP_OUT, PIXMAN_OP_CLEAR },
1656 { PIXMAN_OP_OUT_REVERSE, PIXMAN_OP_CLEAR, PIXMAN_OP_CLEAR, PIXMAN_OP_OUT_REVERSE },
1657 { PIXMAN_OP_ATOP, PIXMAN_OP_SRC, PIXMAN_OP_IN, PIXMAN_OP_OVER },
1658 { PIXMAN_OP_ATOP_REVERSE, PIXMAN_OP_DST, PIXMAN_OP_OVER_REVERSE, PIXMAN_OP_IN_REVERSE },
1659 { PIXMAN_OP_XOR, PIXMAN_OP_CLEAR, PIXMAN_OP_OUT, PIXMAN_OP_OUT_REVERSE },
1660 { PIXMAN_OP_SATURATE, PIXMAN_OP_DST, PIXMAN_OP_OVER_REVERSE, PIXMAN_OP_DST },
1665 * Check if the current operator could be optimized
1667 static const OptimizedOperatorInfo*
1668 pixman_operator_can_be_optimized(pixman_op_t op)
1670 const OptimizedOperatorInfo *info;
1672 for (info = optimized_operators; info->op != PIXMAN_OP_NONE; info++)
1681 * Optimize the current operator based on opacity of source or destination
1682 * The output operator should be mathematically equivalent to the source.
1685 pixman_optimize_operator(pixman_op_t op, pixman_image_t *pSrc, pixman_image_t *pMask, pixman_image_t *pDst )
1687 pixman_bool_t is_source_opaque;
1688 pixman_bool_t is_dest_opaque;
1689 const OptimizedOperatorInfo *info = pixman_operator_can_be_optimized(op);
1694 is_source_opaque = pixman_image_is_opaque(pSrc);
1695 is_dest_opaque = pixman_image_is_opaque(pDst);
1697 if(is_source_opaque == FALSE && is_dest_opaque == FALSE)
1700 if(is_source_opaque && is_dest_opaque)
1701 return info->opSrcDstOpaque;
1702 else if(is_source_opaque)
1703 return info->opSrcOpaque;
1704 else if(is_dest_opaque)
1705 return info->opDstOpaque;
1711 #if defined(USE_SSE2) && defined (__GNUC__)
1714 * Work around GCC bug causing crashes in Mozilla with SSE2
1716 * When using SSE2 intrinsics, gcc assumes that the stack is 16 byte
1717 * aligned. Unfortunately some code, such as Mozilla and Mono contain
1718 * code that aligns the stack to 4 bytes.
1720 * The __force_align_arg_pointer__ makes gcc generate a prologue that
1721 * realigns the stack pointer to 16 bytes.
1723 * See https://bugs.freedesktop.org/show_bug.cgi?id=15693
1726 __attribute__((__force_align_arg_pointer__))
1729 pixman_image_composite (pixman_op_t op,
1730 pixman_image_t * pSrc,
1731 pixman_image_t * pMask,
1732 pixman_image_t * pDst,
1742 pixman_bool_t srcRepeat = pSrc->type == BITS && pSrc->common.repeat == PIXMAN_REPEAT_NORMAL;
1743 pixman_bool_t maskRepeat = FALSE;
1744 pixman_bool_t srcTransform = pSrc->common.transform != NULL;
1745 pixman_bool_t maskTransform = FALSE;
1746 pixman_bool_t srcAlphaMap = pSrc->common.alpha_map != NULL;
1747 pixman_bool_t maskAlphaMap = FALSE;
1748 pixman_bool_t dstAlphaMap = pDst->common.alpha_map != NULL;
1749 CompositeFunc func = NULL;
1752 fbComposeSetupMMX();
1756 fbComposeSetupVMX();
1760 fbComposeSetupSSE();
1763 if (srcRepeat && srcTransform &&
1764 pSrc->bits.width == 1 &&
1765 pSrc->bits.height == 1)
1767 srcTransform = FALSE;
1770 if (pMask && pMask->type == BITS)
1772 maskRepeat = pMask->common.repeat == PIXMAN_REPEAT_NORMAL;
1774 maskTransform = pMask->common.transform != 0;
1775 if (pMask->common.filter == PIXMAN_FILTER_CONVOLUTION)
1776 maskTransform = TRUE;
1778 maskAlphaMap = pMask->common.alpha_map != 0;
1780 if (maskRepeat && maskTransform &&
1781 pMask->bits.width == 1 &&
1782 pMask->bits.height == 1)
1784 maskTransform = FALSE;
1789 * Check if we can replace our operator by a simpler one if the src or dest are opaque
1790 * The output operator should be mathematically equivalent to the source.
1792 op = pixman_optimize_operator(op, pSrc, pMask, pDst);
1793 if(op == PIXMAN_OP_DST)
1796 if ((pSrc->type == BITS || pixman_image_can_get_solid (pSrc)) && (!pMask || pMask->type == BITS)
1797 && !srcTransform && !maskTransform
1798 && !maskAlphaMap && !srcAlphaMap && !dstAlphaMap
1799 && (pSrc->common.filter != PIXMAN_FILTER_CONVOLUTION)
1800 && (pSrc->common.repeat != PIXMAN_REPEAT_PAD)
1801 && (!pMask || (pMask->common.filter != PIXMAN_FILTER_CONVOLUTION && pMask->common.repeat != PIXMAN_REPEAT_PAD))
1802 && !pSrc->common.read_func && !pSrc->common.write_func
1803 && !(pMask && pMask->common.read_func) && !(pMask && pMask->common.write_func)
1804 && !pDst->common.read_func && !pDst->common.write_func)
1806 const FastPathInfo *info;
1807 pixman_bool_t pixbuf;
1810 pSrc && pSrc->type == BITS &&
1811 pMask && pMask->type == BITS &&
1812 pSrc->bits.bits == pMask->bits.bits &&
1815 !pMask->common.component_alpha &&
1820 if (pixman_have_sse ())
1821 info = get_fast_path (sse_fast_paths, op, pSrc, pMask, pDst, pixbuf);
1825 if (!info && pixman_have_mmx())
1826 info = get_fast_path (mmx_fast_paths, op, pSrc, pMask, pDst, pixbuf);
1831 if (!info && pixman_have_vmx())
1832 info = get_fast_path (vmx_fast_paths, op, pSrc, pMask, pDst, pixbuf);
1835 info = get_fast_path (c_fast_paths, op, pSrc, pMask, pDst, pixbuf);
1841 if (info->src_format == PIXMAN_solid)
1844 if (info->mask_format == PIXMAN_solid ||
1845 info->flags & NEED_SOLID_MASK)
1853 pSrc->bits.width == 1 &&
1854 pSrc->bits.height == 1) ||
1856 pMask->bits.width == 1 &&
1857 pMask->bits.height == 1))
1859 /* If src or mask are repeating 1x1 images and srcRepeat or
1860 * maskRepeat are still TRUE, it means the fast path we
1861 * selected does not actually handle repeating images.
1863 * So rather than call the "fast path" with a zillion
1864 * 1x1 requests, we just use the general code (which does
1865 * do something sensible with 1x1 repeating images).
1872 func = pixman_image_composite_rect;
1874 /* CompositeGeneral optimizes 1x1 repeating images itself */
1875 if (pSrc->type == BITS &&
1876 pSrc->bits.width == 1 && pSrc->bits.height == 1)
1881 if (pMask && pMask->type == BITS &&
1882 pMask->bits.width == 1 && pMask->bits.height == 1)
1887 /* if we are transforming, repeats are handled in fbFetchTransformed */
1895 pixman_walk_composite_region (op, pSrc, pMask, pDst, xSrc, ySrc,
1896 xMask, yMask, xDst, yDst, width, height,
1897 srcRepeat, maskRepeat, func);
1902 /* The CPU detection code needs to be in a file not compiled with
1903 * "-maltivec -mabi=altivec", as gcc would try to save vector register
1904 * across function calls causing SIGILL on cpus without Altivec/vmx.
1906 static pixman_bool_t initialized = FALSE;
1907 static volatile pixman_bool_t have_vmx = TRUE;
1910 #include <sys/sysctl.h>
1912 pixman_bool_t pixman_have_vmx (void) {
1914 size_t length = sizeof(have_vmx);
1916 sysctlbyname("hw.optional.altivec", &have_vmx, &length, NULL, 0);
1917 if(error) have_vmx = FALSE;
1926 static void vmx_test(int sig, siginfo_t *si, void *unused) {
1930 pixman_bool_t pixman_have_vmx (void) {
1931 struct sigaction sa, osa;
1933 sa.sa_flags = SA_SIGINFO;
1934 sigemptyset(&sa.sa_mask);
1935 sa.sa_sigaction = vmx_test;
1936 sigaction(SIGILL, &sa, &osa);
1937 asm volatile ( "vor 0, 0, 0" );
1938 sigaction(SIGILL, &osa, NULL);
1943 #endif /* __APPLE__ */
1944 #endif /* USE_VMX */
1947 /* The CPU detection code needs to be in a file not compiled with
1948 * "-mmmx -msse", as gcc would generate CMOV instructions otherwise
1949 * that would lead to SIGILL instructions on old CPUs that don't have
1952 #if !defined(__amd64__) && !defined(__x86_64__)
1955 #include <sys/auxv.h>
1961 MMX_Extensions = 0x2,
1967 static unsigned int detectCPUFeatures(void) {
1968 unsigned int features = 0;
1969 unsigned int result = 0;
1972 if (getisax(&result, 1)) {
1973 if (result & AV_386_CMOV)
1975 if (result & AV_386_MMX)
1977 if (result & AV_386_AMD_MMX)
1978 features |= MMX_Extensions;
1979 if (result & AV_386_SSE)
1981 if (result & AV_386_SSE2)
1987 int vendor0 = 0, vendor1, vendor2;
1993 /* see p. 118 of amd64 instruction set manual Vol3 */
1994 /* We need to be careful about the handling of %ebx and
1995 * %esp here. We can't declare either one as clobbered
1996 * since they are special registers (%ebx is the "PIC
1997 * register" holding an offset to global data, %esp the
1998 * stack pointer), so we need to make sure they have their
1999 * original values when we access the output operands.
2003 "mov %%eax, %%ecx\n"
2004 "xor $0x00200000, %%eax\n"
2010 "xor %%ecx, %%eax\n"
2013 "mov $0x00000000, %%eax\n"
2016 "mov %%ebx, %%eax\n"
2021 "mov $0x00000001, %%eax\n"
2032 : "%eax", "%ecx", "%edx"
2035 #elif defined (_MSC_VER)
2065 memmove (vendor+0, &vendor0, 4);
2066 memmove (vendor+4, &vendor1, 4);
2067 memmove (vendor+8, &vendor2, 4);
2070 # error unsupported compiler
2075 /* result now contains the standard feature bits */
2076 if (result & (1 << 15))
2078 if (result & (1 << 23))
2080 if (result & (1 << 25))
2082 if (result & (1 << 26))
2084 if ((features & MMX) && !(features & SSE) &&
2085 (strcmp(vendor, "AuthenticAMD") == 0 ||
2086 strcmp(vendor, "Geode by NSC") == 0)) {
2087 /* check for AMD MMX extensions */
2089 __asm__("push %%ebx\n"
2090 "mov $0x80000000, %%eax\n"
2092 "xor %%edx, %%edx\n"
2095 "mov $0x80000001, %%eax\n"
2102 : "%eax", "%ecx", "%edx"
2104 #elif defined _MSC_VER
2119 if (result & (1<<22))
2120 features |= MMX_Extensions;
2123 #endif /* HAVE_GETISAX */
2129 pixman_have_mmx (void)
2131 static pixman_bool_t initialized = FALSE;
2132 static pixman_bool_t mmx_present;
2136 unsigned int features = detectCPUFeatures();
2137 mmx_present = (features & (MMX|MMX_Extensions)) == (MMX|MMX_Extensions);
2146 pixman_have_sse (void)
2148 static pixman_bool_t initialized = FALSE;
2149 static pixman_bool_t sse_present;
2153 unsigned int features = detectCPUFeatures();
2154 sse_present = (features & (MMX|MMX_Extensions|SSE|SSE2)) == (MMX|MMX_Extensions|SSE|SSE2);
2162 #endif /* __amd64__ */