#ifdef HAVE_CONFIG_H #include <config.h> #endif #include <string.h> #include "pixman-private.h" #include "pixman-combine.h" /* * There are two ways of handling alpha -- either as a single unified value or * a separate value for each component, hence each macro must have two * versions. The unified alpha version has a 'U' at the end of the name, * the component version has a 'C'. Similarly, functions which deal with * this difference will have two versions using the same convention. */ /* * Combine src and mask */ FASTCALL static void pixman_fbCombineMaskU (comp4_t *src, const comp4_t *mask, int width) { int i; for (i = 0; i < width; ++i) { comp4_t a = *(mask + i) >> A_SHIFT; comp4_t s = *(src + i); FbByteMul(s, a); *(src + i) = s; } } /* * All of the composing functions */ FASTCALL static void fbCombineClear (comp4_t *dest, const comp4_t *src, int width) { memset(dest, 0, width*sizeof(comp4_t)); } FASTCALL static void fbCombineSrcU (comp4_t *dest, const comp4_t *src, int width) { memcpy(dest, src, width*sizeof(comp4_t)); } /* if the Src is opaque, call fbCombineSrcU */ FASTCALL static void fbCombineOverU (comp4_t *dest, const comp4_t *src, int width) { int i; for (i = 0; i < width; ++i) { comp4_t s = *(src + i); comp4_t d = *(dest + i); comp4_t ia = Alpha(~s); FbByteMulAdd(d, ia, s); *(dest + i) = d; } } /* if the Dst is opaque, this is a noop */ FASTCALL static void fbCombineOverReverseU (comp4_t *dest, const comp4_t *src, int width) { int i; for (i = 0; i < width; ++i) { comp4_t s = *(src + i); comp4_t d = *(dest + i); comp4_t ia = Alpha(~*(dest + i)); FbByteMulAdd(s, ia, d); *(dest + i) = s; } } /* if the Dst is opaque, call fbCombineSrcU */ FASTCALL static void fbCombineInU (comp4_t *dest, const comp4_t *src, int width) { int i; for (i = 0; i < width; ++i) { comp4_t s = *(src + i); comp4_t a = Alpha(*(dest + i)); FbByteMul(s, a); *(dest + i) = s; } } /* if the Src is opaque, this is a noop */ FASTCALL static void fbCombineInReverseU (comp4_t *dest, const comp4_t *src, int width) { int i; for (i = 0; i < width; ++i) { comp4_t d = *(dest + i); comp4_t a = Alpha(*(src + i)); FbByteMul(d, a); *(dest + i) = d; } } /* if the Dst is opaque, call fbCombineClear */ FASTCALL static void fbCombineOutU (comp4_t *dest, const comp4_t *src, int width) { int i; for (i = 0; i < width; ++i) { comp4_t s = *(src + i); comp4_t a = Alpha(~*(dest + i)); FbByteMul(s, a); *(dest + i) = s; } } /* if the Src is opaque, call fbCombineClear */ FASTCALL static void fbCombineOutReverseU (comp4_t *dest, const comp4_t *src, int width) { int i; for (i = 0; i < width; ++i) { comp4_t d = *(dest + i); comp4_t a = Alpha(~*(src + i)); FbByteMul(d, a); *(dest + i) = d; } } /* if the Src is opaque, call fbCombineInU */ /* if the Dst is opaque, call fbCombineOverU */ /* if both the Src and Dst are opaque, call fbCombineSrcU */ FASTCALL static void fbCombineAtopU (comp4_t *dest, const comp4_t *src, int width) { int i; for (i = 0; i < width; ++i) { comp4_t s = *(src + i); comp4_t d = *(dest + i); comp4_t dest_a = Alpha(d); comp4_t src_ia = Alpha(~s); FbByteAddMul(s, dest_a, d, src_ia); *(dest + i) = s; } } /* if the Src is opaque, call fbCombineOverReverseU */ /* if the Dst is opaque, call fbCombineInReverseU */ /* if both the Src and Dst are opaque, call fbCombineDstU */ FASTCALL static void fbCombineAtopReverseU (comp4_t *dest, const comp4_t *src, int width) { int i; for (i = 0; i < width; ++i) { comp4_t s = *(src + i); comp4_t d = *(dest + i); comp4_t src_a = Alpha(s); comp4_t dest_ia = Alpha(~d); FbByteAddMul(s, dest_ia, d, src_a); *(dest + i) = s; } } /* if the Src is opaque, call fbCombineOverU */ /* if the Dst is opaque, call fbCombineOverReverseU */ /* if both the Src and Dst are opaque, call fbCombineClear */ FASTCALL static void fbCombineXorU (comp4_t *dest, const comp4_t *src, int width) { int i; for (i = 0; i < width; ++i) { comp4_t s = *(src + i); comp4_t d = *(dest + i); comp4_t src_ia = Alpha(~s); comp4_t dest_ia = Alpha(~d); FbByteAddMul(s, dest_ia, d, src_ia); *(dest + i) = s; } } FASTCALL static void fbCombineAddU (comp4_t *dest, const comp4_t *src, int width) { int i; for (i = 0; i < width; ++i) { comp4_t s = *(src + i); comp4_t d = *(dest + i); FbByteAdd(d, s); *(dest + i) = d; } } /* if the Src is opaque, call fbCombineAddU */ /* if the Dst is opaque, call fbCombineAddU */ /* if both the Src and Dst are opaque, call fbCombineAddU */ FASTCALL static void fbCombineSaturateU (comp4_t *dest, const comp4_t *src, int width) { int i; for (i = 0; i < width; ++i) { comp4_t s = *(src + i); comp4_t d = *(dest + i); comp2_t sa, da; sa = s >> A_SHIFT; da = ~d >> A_SHIFT; if (sa > da) { sa = IntDiv(da, sa); FbByteMul(s, sa); }; FbByteAdd(d, s); *(dest + i) = d; } } /* * All of the disjoint composing functions The four entries in the first column indicate what source contributions come from each of the four areas of the picture -- areas covered by neither A nor B, areas covered only by A, areas covered only by B and finally areas covered by both A and B. Disjoint Conjoint Fa Fb Fa Fb (0,0,0,0) 0 0 0 0 (0,A,0,A) 1 0 1 0 (0,0,B,B) 0 1 0 1 (0,A,B,A) 1 min((1-a)/b,1) 1 max(1-a/b,0) (0,A,B,B) min((1-b)/a,1) 1 max(1-b/a,0) 1 (0,0,0,A) max(1-(1-b)/a,0) 0 min(1,b/a) 0 (0,0,0,B) 0 max(1-(1-a)/b,0) 0 min(a/b,1) (0,A,0,0) min(1,(1-b)/a) 0 max(1-b/a,0) 0 (0,0,B,0) 0 min(1,(1-a)/b) 0 max(1-a/b,0) (0,0,B,A) max(1-(1-b)/a,0) min(1,(1-a)/b) min(1,b/a) max(1-a/b,0) (0,A,0,B) min(1,(1-b)/a) max(1-(1-a)/b,0) max(1-b/a,0) min(1,a/b) (0,A,B,0) min(1,(1-b)/a) min(1,(1-a)/b) max(1-b/a,0) max(1-a/b,0) */ #define CombineAOut 1 #define CombineAIn 2 #define CombineBOut 4 #define CombineBIn 8 #define CombineClear 0 #define CombineA (CombineAOut|CombineAIn) #define CombineB (CombineBOut|CombineBIn) #define CombineAOver (CombineAOut|CombineBOut|CombineAIn) #define CombineBOver (CombineAOut|CombineBOut|CombineBIn) #define CombineAAtop (CombineBOut|CombineAIn) #define CombineBAtop (CombineAOut|CombineBIn) #define CombineXor (CombineAOut|CombineBOut) /* portion covered by a but not b */ FASTCALL static comp1_t fbCombineDisjointOutPart (comp1_t a, comp1_t b) { /* min (1, (1-b) / a) */ b = ~b; /* 1 - b */ if (b >= a) /* 1 - b >= a -> (1-b)/a >= 1 */ return MASK; /* 1 */ return IntDiv(b,a); /* (1-b) / a */ } /* portion covered by both a and b */ FASTCALL static comp1_t fbCombineDisjointInPart (comp1_t a, comp1_t b) { /* max (1-(1-b)/a,0) */ /* = - min ((1-b)/a - 1, 0) */ /* = 1 - min (1, (1-b)/a) */ b = ~b; /* 1 - b */ if (b >= a) /* 1 - b >= a -> (1-b)/a >= 1 */ return 0; /* 1 - 1 */ return ~IntDiv(b,a); /* 1 - (1-b) / a */ } /* portion covered by a but not b */ FASTCALL static comp1_t fbCombineConjointOutPart (comp1_t a, comp1_t b) { /* max (1-b/a,0) */ /* = 1-min(b/a,1) */ /* min (1, (1-b) / a) */ if (b >= a) /* b >= a -> b/a >= 1 */ return 0x00; /* 0 */ return ~IntDiv(b,a); /* 1 - b/a */ } /* portion covered by both a and b */ FASTCALL static comp1_t fbCombineConjointInPart (comp1_t a, comp1_t b) { /* min (1,b/a) */ if (b >= a) /* b >= a -> b/a >= 1 */ return MASK; /* 1 */ return IntDiv(b,a); /* b/a */ } FASTCALL static void fbCombineDisjointGeneralU (comp4_t *dest, const comp4_t *src, int width, comp1_t combine) { int i; for (i = 0; i < width; ++i) { comp4_t s = *(src + i); comp4_t d = *(dest + i); comp4_t m,n,o,p; comp2_t Fa, Fb, t, u, v; comp1_t sa = s >> A_SHIFT; comp1_t da = d >> A_SHIFT; switch (combine & CombineA) { default: Fa = 0; break; case CombineAOut: Fa = fbCombineDisjointOutPart (sa, da); break; case CombineAIn: Fa = fbCombineDisjointInPart (sa, da); break; case CombineA: Fa = MASK; break; } switch (combine & CombineB) { default: Fb = 0; break; case CombineBOut: Fb = fbCombineDisjointOutPart (da, sa); break; case CombineBIn: Fb = fbCombineDisjointInPart (da, sa); break; case CombineB: Fb = MASK; break; } m = FbGen (s,d,0,Fa,Fb,t, u, v); n = FbGen (s,d,G_SHIFT,Fa,Fb,t, u, v); o = FbGen (s,d,B_SHIFT,Fa,Fb,t, u, v); p = FbGen (s,d,A_SHIFT,Fa,Fb,t, u, v); s = m|n|o|p; *(dest + i) = s; } } FASTCALL static void fbCombineDisjointOverU (comp4_t *dest, const comp4_t *src, int width) { int i; for (i = 0; i < width; ++i) { comp4_t s = *(src + i); comp2_t a = s >> A_SHIFT; if (a != 0x00) { if (a != MASK) { comp4_t d = *(dest + i); a = fbCombineDisjointOutPart (d >> A_SHIFT, a); FbByteMulAdd(d, a, s); s = d; } *(dest + i) = s; } } } FASTCALL static void fbCombineDisjointInU (comp4_t *dest, const comp4_t *src, int width) { fbCombineDisjointGeneralU (dest, src, width, CombineAIn); } FASTCALL static void fbCombineDisjointInReverseU (comp4_t *dest, const comp4_t *src, int width) { fbCombineDisjointGeneralU (dest, src, width, CombineBIn); } FASTCALL static void fbCombineDisjointOutU (comp4_t *dest, const comp4_t *src, int width) { fbCombineDisjointGeneralU (dest, src, width, CombineAOut); } FASTCALL static void fbCombineDisjointOutReverseU (comp4_t *dest, const comp4_t *src, int width) { fbCombineDisjointGeneralU (dest, src, width, CombineBOut); } FASTCALL static void fbCombineDisjointAtopU (comp4_t *dest, const comp4_t *src, int width) { fbCombineDisjointGeneralU (dest, src, width, CombineAAtop); } FASTCALL static void fbCombineDisjointAtopReverseU (comp4_t *dest, const comp4_t *src, int width) { fbCombineDisjointGeneralU (dest, src, width, CombineBAtop); } FASTCALL static void fbCombineDisjointXorU (comp4_t *dest, const comp4_t *src, int width) { fbCombineDisjointGeneralU (dest, src, width, CombineXor); } FASTCALL static void fbCombineConjointGeneralU (comp4_t *dest, const comp4_t *src, int width, comp1_t combine) { int i; for (i = 0; i < width; ++i) { comp4_t s = *(src + i); comp4_t d = *(dest + i); comp4_t m,n,o,p; comp2_t Fa, Fb, t, u, v; comp1_t sa = s >> A_SHIFT; comp1_t da = d >> A_SHIFT; switch (combine & CombineA) { default: Fa = 0; break; case CombineAOut: Fa = fbCombineConjointOutPart (sa, da); break; case CombineAIn: Fa = fbCombineConjointInPart (sa, da); break; case CombineA: Fa = MASK; break; } switch (combine & CombineB) { default: Fb = 0; break; case CombineBOut: Fb = fbCombineConjointOutPart (da, sa); break; case CombineBIn: Fb = fbCombineConjointInPart (da, sa); break; case CombineB: Fb = MASK; break; } m = FbGen (s,d,0,Fa,Fb,t, u, v); n = FbGen (s,d,G_SHIFT,Fa,Fb,t, u, v); o = FbGen (s,d,B_SHIFT,Fa,Fb,t, u, v); p = FbGen (s,d,A_SHIFT,Fa,Fb,t, u, v); s = m|n|o|p; *(dest + i) = s; } } FASTCALL static void fbCombineConjointOverU (comp4_t *dest, const comp4_t *src, int width) { fbCombineConjointGeneralU (dest, src, width, CombineAOver); } FASTCALL static void fbCombineConjointOverReverseU (comp4_t *dest, const comp4_t *src, int width) { fbCombineConjointGeneralU (dest, src, width, CombineBOver); } FASTCALL static void fbCombineConjointInU (comp4_t *dest, const comp4_t *src, int width) { fbCombineConjointGeneralU (dest, src, width, CombineAIn); } FASTCALL static void fbCombineConjointInReverseU (comp4_t *dest, const comp4_t *src, int width) { fbCombineConjointGeneralU (dest, src, width, CombineBIn); } FASTCALL static void fbCombineConjointOutU (comp4_t *dest, const comp4_t *src, int width) { fbCombineConjointGeneralU (dest, src, width, CombineAOut); } FASTCALL static void fbCombineConjointOutReverseU (comp4_t *dest, const comp4_t *src, int width) { fbCombineConjointGeneralU (dest, src, width, CombineBOut); } FASTCALL static void fbCombineConjointAtopU (comp4_t *dest, const comp4_t *src, int width) { fbCombineConjointGeneralU (dest, src, width, CombineAAtop); } FASTCALL static void fbCombineConjointAtopReverseU (comp4_t *dest, const comp4_t *src, int width) { fbCombineConjointGeneralU (dest, src, width, CombineBAtop); } FASTCALL static void fbCombineConjointXorU (comp4_t *dest, const comp4_t *src, int width) { fbCombineConjointGeneralU (dest, src, width, CombineXor); } /********************************************************************************/ /*************************** Per Channel functions ******************************/ /********************************************************************************/ FASTCALL static void fbCombineMaskC (comp4_t *src, comp4_t *mask) { comp4_t a = *mask; comp4_t x; comp2_t xa; if (!a) { *(src) = 0; return; } x = *(src); if (a == ~0) { x = x >> A_SHIFT; x |= x << G_SHIFT; x |= x << B_SHIFT; *(mask) = x; return; } xa = x >> A_SHIFT; FbByteMulC(x, a); *(src) = x; FbByteMul(a, xa); *(mask) = a; } FASTCALL static void fbCombineMaskValueC (comp4_t *src, const comp4_t *mask) { comp4_t a = *mask; comp4_t x; if (!a) { *(src) = 0; return; } if (a == ~0) return; x = *(src); FbByteMulC(x, a); *(src) =x; } FASTCALL static void fbCombineMaskAlphaC (const comp4_t *src, comp4_t *mask) { comp4_t a = *(mask); comp4_t x; if (!a) return; x = *(src) >> A_SHIFT; if (x == MASK) return; if (a == ~0) { x = x >> A_SHIFT; x |= x << G_SHIFT; x |= x << B_SHIFT; *(mask) = x; return; } FbByteMul(a, x); *(mask) = a; } FASTCALL static void fbCombineClearC (comp4_t *dest, comp4_t *src, comp4_t *mask, int width) { memset(dest, 0, width*sizeof(comp4_t)); } FASTCALL static void fbCombineSrcC (comp4_t *dest, comp4_t *src, comp4_t *mask, int width) { int i; for (i = 0; i < width; ++i) { comp4_t s = *(src + i); comp4_t m = *(mask + i); fbCombineMaskValueC (&s, &m); *(dest) = s; } } FASTCALL static void fbCombineOverC (comp4_t *dest, comp4_t *src, comp4_t *mask, int width) { int i; for (i = 0; i < width; ++i) { comp4_t s = *(src + i); comp4_t m = *(mask + i); comp4_t a; fbCombineMaskC (&s, &m); a = ~m; if (a != ~0) { if (a) { comp4_t d = *(dest + i); FbByteMulAddC(d, a, s); s = d; } *(dest + i) = s; } } } FASTCALL static void fbCombineOverReverseC (comp4_t *dest, comp4_t *src, comp4_t *mask, int width) { int i; for (i = 0; i < width; ++i) { comp4_t d = *(dest + i); comp4_t a = ~d >> A_SHIFT; if (a) { comp4_t s = *(src + i); comp4_t m = *(mask + i); fbCombineMaskValueC (&s, &m); if (a != MASK) { FbByteMulAdd(s, a, d); } *(dest + i) = s; } } } FASTCALL static void fbCombineInC (comp4_t *dest, comp4_t *src, comp4_t *mask, int width) { int i; for (i = 0; i < width; ++i) { comp4_t d = *(dest + i); comp2_t a = d >> A_SHIFT; comp4_t s = 0; if (a) { comp4_t m = *(mask + i); s = *(src + i); fbCombineMaskValueC (&s, &m); if (a != MASK) { FbByteMul(s, a); } } *(dest + i) = s; } } FASTCALL static void fbCombineInReverseC (comp4_t *dest, comp4_t *src, comp4_t *mask, int width) { int i; for (i = 0; i < width; ++i) { comp4_t s = *(src + i); comp4_t m = *(mask + i); comp4_t a; fbCombineMaskAlphaC (&s, &m); a = m; if (a != ~0) { comp4_t d = 0; if (a) { d = *(dest + i); FbByteMulC(d, a); } *(dest + i) = d; } } } FASTCALL static void fbCombineOutC (comp4_t *dest, comp4_t *src, comp4_t *mask, int width) { int i; for (i = 0; i < width; ++i) { comp4_t d = *(dest + i); comp2_t a = ~d >> A_SHIFT; comp4_t s = 0; if (a) { comp4_t m = *(mask + i); s = *(src + i); fbCombineMaskValueC (&s, &m); if (a != MASK) { FbByteMul(s, a); } } *(dest + i) = s; } } FASTCALL static void fbCombineOutReverseC (comp4_t *dest, comp4_t *src, comp4_t *mask, int width) { int i; for (i = 0; i < width; ++i) { comp4_t s = *(src + i); comp4_t m = *(mask + i); comp4_t a; fbCombineMaskAlphaC (&s, &m); a = ~m; if (a != ~0) { comp4_t d = 0; if (a) { d = *(dest + i); FbByteMulC(d, a); } *(dest + i) = d; } } } FASTCALL static void fbCombineAtopC (comp4_t *dest, comp4_t *src, comp4_t *mask, int width) { int i; for (i = 0; i < width; ++i) { comp4_t d = *(dest + i); comp4_t s = *(src + i); comp4_t m = *(mask + i); comp4_t ad; comp2_t as = d >> A_SHIFT; fbCombineMaskC (&s, &m); ad = ~m; FbByteAddMulC(d, ad, s, as); *(dest + i) = d; } } FASTCALL static void fbCombineAtopReverseC (comp4_t *dest, comp4_t *src, comp4_t *mask, int width) { int i; for (i = 0; i < width; ++i) { comp4_t d = *(dest + i); comp4_t s = *(src + i); comp4_t m = *(mask + i); comp4_t ad; comp2_t as = ~d >> A_SHIFT; fbCombineMaskC (&s, &m); ad = m; FbByteAddMulC(d, ad, s, as); *(dest + i) = d; } } FASTCALL static void fbCombineXorC (comp4_t *dest, comp4_t *src, comp4_t *mask, int width) { int i; for (i = 0; i < width; ++i) { comp4_t d = *(dest + i); comp4_t s = *(src + i); comp4_t m = *(mask + i); comp4_t ad; comp2_t as = ~d >> A_SHIFT; fbCombineMaskC (&s, &m); ad = ~m; FbByteAddMulC(d, ad, s, as); *(dest + i) = d; } } FASTCALL static void fbCombineAddC (comp4_t *dest, comp4_t *src, comp4_t *mask, int width) { int i; for (i = 0; i < width; ++i) { comp4_t s = *(src + i); comp4_t m = *(mask + i); comp4_t d = *(dest + i); fbCombineMaskValueC (&s, &m); FbByteAdd(d, s); *(dest + i) = d; } } FASTCALL static void fbCombineSaturateC (comp4_t *dest, comp4_t *src, comp4_t *mask, int width) { int i; for (i = 0; i < width; ++i) { comp4_t s, d; comp2_t sa, sr, sg, sb, da; comp2_t t, u, v; comp4_t m,n,o,p; d = *(dest + i); s = *(src + i); m = *(mask + i); fbCombineMaskC (&s, &m); sa = (m >> A_SHIFT); sr = (m >> B_SHIFT) & MASK; sg = (m >> G_SHIFT) & MASK; sb = m & MASK; da = ~d >> A_SHIFT; if (sb <= da) m = Add(s,d,0,t); else m = FbGen (s, d, 0, (da << G_SHIFT) / sb, MASK, t, u, v); if (sg <= da) n = Add(s,d,G_SHIFT,t); else n = FbGen (s, d, G_SHIFT, (da << G_SHIFT) / sg, MASK, t, u, v); if (sr <= da) o = Add(s,d,B_SHIFT,t); else o = FbGen (s, d, B_SHIFT, (da << G_SHIFT) / sr, MASK, t, u, v); if (sa <= da) p = Add(s,d,A_SHIFT,t); else p = FbGen (s, d, A_SHIFT, (da << G_SHIFT) / sa, MASK, t, u, v); *(dest + i) = m|n|o|p; } } FASTCALL static void fbCombineDisjointGeneralC (comp4_t *dest, comp4_t *src, comp4_t *mask, int width, comp1_t combine) { int i; for (i = 0; i < width; ++i) { comp4_t s, d; comp4_t m,n,o,p; comp4_t Fa, Fb; comp2_t t, u, v; comp4_t sa; comp1_t da; s = *(src + i); m = *(mask + i); d = *(dest + i); da = d >> A_SHIFT; fbCombineMaskC (&s, &m); sa = m; switch (combine & CombineA) { default: Fa = 0; break; case CombineAOut: m = (comp4_t)fbCombineDisjointOutPart ((comp1_t) (sa >> 0), da); n = (comp4_t)fbCombineDisjointOutPart ((comp1_t) (sa >> G_SHIFT), da) << G_SHIFT; o = (comp4_t)fbCombineDisjointOutPart ((comp1_t) (sa >> B_SHIFT), da) << B_SHIFT; p = (comp4_t)fbCombineDisjointOutPart ((comp1_t) (sa >> A_SHIFT), da) << A_SHIFT; Fa = m|n|o|p; break; case CombineAIn: m = (comp4_t)fbCombineDisjointInPart ((comp1_t) (sa >> 0), da); n = (comp4_t)fbCombineDisjointInPart ((comp1_t) (sa >> G_SHIFT), da) << G_SHIFT; o = (comp4_t)fbCombineDisjointInPart ((comp1_t) (sa >> B_SHIFT), da) << B_SHIFT; p = (comp4_t)fbCombineDisjointInPart ((comp1_t) (sa >> A_SHIFT), da) << A_SHIFT; Fa = m|n|o|p; break; case CombineA: Fa = ~0; break; } switch (combine & CombineB) { default: Fb = 0; break; case CombineBOut: m = (comp4_t)fbCombineDisjointOutPart (da, (comp1_t) (sa >> 0)); n = (comp4_t)fbCombineDisjointOutPart (da, (comp1_t) (sa >> G_SHIFT)) << G_SHIFT; o = (comp4_t)fbCombineDisjointOutPart (da, (comp1_t) (sa >> B_SHIFT)) << B_SHIFT; p = (comp4_t)fbCombineDisjointOutPart (da, (comp1_t) (sa >> A_SHIFT)) << A_SHIFT; Fb = m|n|o|p; break; case CombineBIn: m = (comp4_t)fbCombineDisjointInPart (da, (comp1_t) (sa >> 0)); n = (comp4_t)fbCombineDisjointInPart (da, (comp1_t) (sa >> G_SHIFT)) << G_SHIFT; o = (comp4_t)fbCombineDisjointInPart (da, (comp1_t) (sa >> B_SHIFT)) << B_SHIFT; p = (comp4_t)fbCombineDisjointInPart (da, (comp1_t) (sa >> A_SHIFT)) << A_SHIFT; Fb = m|n|o|p; break; case CombineB: Fb = ~0; break; } m = FbGen (s,d,0,GetComp(Fa,0),GetComp(Fb,0),t, u, v); n = FbGen (s,d,G_SHIFT,GetComp(Fa,G_SHIFT),GetComp(Fb,G_SHIFT),t, u, v); o = FbGen (s,d,B_SHIFT,GetComp(Fa,B_SHIFT),GetComp(Fb,B_SHIFT),t, u, v); p = FbGen (s,d,A_SHIFT,GetComp(Fa,A_SHIFT),GetComp(Fb,A_SHIFT),t, u, v); s = m|n|o|p; *(dest + i) = s; } } FASTCALL static void fbCombineDisjointOverC (comp4_t *dest, comp4_t *src, comp4_t *mask, int width) { fbCombineDisjointGeneralC (dest, src, mask, width, CombineAOver); } FASTCALL static void fbCombineDisjointInC (comp4_t *dest, comp4_t *src, comp4_t *mask, int width) { fbCombineDisjointGeneralC (dest, src, mask, width, CombineAIn); } FASTCALL static void fbCombineDisjointInReverseC (comp4_t *dest, comp4_t *src, comp4_t *mask, int width) { fbCombineDisjointGeneralC (dest, src, mask, width, CombineBIn); } FASTCALL static void fbCombineDisjointOutC (comp4_t *dest, comp4_t *src, comp4_t *mask, int width) { fbCombineDisjointGeneralC (dest, src, mask, width, CombineAOut); } FASTCALL static void fbCombineDisjointOutReverseC (comp4_t *dest, comp4_t *src, comp4_t *mask, int width) { fbCombineDisjointGeneralC (dest, src, mask, width, CombineBOut); } FASTCALL static void fbCombineDisjointAtopC (comp4_t *dest, comp4_t *src, comp4_t *mask, int width) { fbCombineDisjointGeneralC (dest, src, mask, width, CombineAAtop); } FASTCALL static void fbCombineDisjointAtopReverseC (comp4_t *dest, comp4_t *src, comp4_t *mask, int width) { fbCombineDisjointGeneralC (dest, src, mask, width, CombineBAtop); } FASTCALL static void fbCombineDisjointXorC (comp4_t *dest, comp4_t *src, comp4_t *mask, int width) { fbCombineDisjointGeneralC (dest, src, mask, width, CombineXor); } FASTCALL static void fbCombineConjointGeneralC (comp4_t *dest, comp4_t *src, comp4_t *mask, int width, comp1_t combine) { int i; for (i = 0; i < width; ++i) { comp4_t s, d; comp4_t m,n,o,p; comp4_t Fa, Fb; comp2_t t, u, v; comp4_t sa; comp1_t da; s = *(src + i); m = *(mask + i); d = *(dest + i); da = d >> A_SHIFT; fbCombineMaskC (&s, &m); sa = m; switch (combine & CombineA) { default: Fa = 0; break; case CombineAOut: m = (comp4_t)fbCombineConjointOutPart ((comp1_t) (sa >> 0), da); n = (comp4_t)fbCombineConjointOutPart ((comp1_t) (sa >> G_SHIFT), da) << G_SHIFT; o = (comp4_t)fbCombineConjointOutPart ((comp1_t) (sa >> B_SHIFT), da) << B_SHIFT; p = (comp4_t)fbCombineConjointOutPart ((comp1_t) (sa >> A_SHIFT), da) << A_SHIFT; Fa = m|n|o|p; break; case CombineAIn: m = (comp4_t)fbCombineConjointInPart ((comp1_t) (sa >> 0), da); n = (comp4_t)fbCombineConjointInPart ((comp1_t) (sa >> G_SHIFT), da) << G_SHIFT; o = (comp4_t)fbCombineConjointInPart ((comp1_t) (sa >> B_SHIFT), da) << B_SHIFT; p = (comp4_t)fbCombineConjointInPart ((comp1_t) (sa >> A_SHIFT), da) << A_SHIFT; Fa = m|n|o|p; break; case CombineA: Fa = ~0; break; } switch (combine & CombineB) { default: Fb = 0; break; case CombineBOut: m = (comp4_t)fbCombineConjointOutPart (da, (comp1_t) (sa >> 0)); n = (comp4_t)fbCombineConjointOutPart (da, (comp1_t) (sa >> G_SHIFT)) << G_SHIFT; o = (comp4_t)fbCombineConjointOutPart (da, (comp1_t) (sa >> B_SHIFT)) << B_SHIFT; p = (comp4_t)fbCombineConjointOutPart (da, (comp1_t) (sa >> A_SHIFT)) << A_SHIFT; Fb = m|n|o|p; break; case CombineBIn: m = (comp4_t)fbCombineConjointInPart (da, (comp1_t) (sa >> 0)); n = (comp4_t)fbCombineConjointInPart (da, (comp1_t) (sa >> G_SHIFT)) << G_SHIFT; o = (comp4_t)fbCombineConjointInPart (da, (comp1_t) (sa >> B_SHIFT)) << B_SHIFT; p = (comp4_t)fbCombineConjointInPart (da, (comp1_t) (sa >> A_SHIFT)) << A_SHIFT; Fb = m|n|o|p; break; case CombineB: Fb = ~0; break; } m = FbGen (s,d,0,GetComp(Fa,0),GetComp(Fb,0),t, u, v); n = FbGen (s,d,G_SHIFT,GetComp(Fa,G_SHIFT),GetComp(Fb,G_SHIFT),t, u, v); o = FbGen (s,d,B_SHIFT,GetComp(Fa,B_SHIFT),GetComp(Fb,B_SHIFT),t, u, v); p = FbGen (s,d,A_SHIFT,GetComp(Fa,A_SHIFT),GetComp(Fb,A_SHIFT),t, u, v); s = m|n|o|p; *(dest + i) = s; } } FASTCALL static void fbCombineConjointOverC (comp4_t *dest, comp4_t *src, comp4_t *mask, int width) { fbCombineConjointGeneralC (dest, src, mask, width, CombineAOver); } FASTCALL static void fbCombineConjointOverReverseC (comp4_t *dest, comp4_t *src, comp4_t *mask, int width) { fbCombineConjointGeneralC (dest, src, mask, width, CombineBOver); } FASTCALL static void fbCombineConjointInC (comp4_t *dest, comp4_t *src, comp4_t *mask, int width) { fbCombineConjointGeneralC (dest, src, mask, width, CombineAIn); } FASTCALL static void fbCombineConjointInReverseC (comp4_t *dest, comp4_t *src, comp4_t *mask, int width) { fbCombineConjointGeneralC (dest, src, mask, width, CombineBIn); } FASTCALL static void fbCombineConjointOutC (comp4_t *dest, comp4_t *src, comp4_t *mask, int width) { fbCombineConjointGeneralC (dest, src, mask, width, CombineAOut); } FASTCALL static void fbCombineConjointOutReverseC (comp4_t *dest, comp4_t *src, comp4_t *mask, int width) { fbCombineConjointGeneralC (dest, src, mask, width, CombineBOut); } FASTCALL static void fbCombineConjointAtopC (comp4_t *dest, comp4_t *src, comp4_t *mask, int width) { fbCombineConjointGeneralC (dest, src, mask, width, CombineAAtop); } FASTCALL static void fbCombineConjointAtopReverseC (comp4_t *dest, comp4_t *src, comp4_t *mask, int width) { fbCombineConjointGeneralC (dest, src, mask, width, CombineBAtop); } FASTCALL static void fbCombineConjointXorC (comp4_t *dest, comp4_t *src, comp4_t *mask, int width) { fbCombineConjointGeneralC (dest, src, mask, width, CombineXor); } static CombineFuncU pixman_fbCombineFuncU[] = { fbCombineClear, fbCombineSrcU, NULL, /* CombineDst */ fbCombineOverU, fbCombineOverReverseU, fbCombineInU, fbCombineInReverseU, fbCombineOutU, fbCombineOutReverseU, fbCombineAtopU, fbCombineAtopReverseU, fbCombineXorU, fbCombineAddU, fbCombineSaturateU, NULL, NULL, fbCombineClear, fbCombineSrcU, NULL, /* CombineDst */ fbCombineDisjointOverU, fbCombineSaturateU, /* DisjointOverReverse */ fbCombineDisjointInU, fbCombineDisjointInReverseU, fbCombineDisjointOutU, fbCombineDisjointOutReverseU, fbCombineDisjointAtopU, fbCombineDisjointAtopReverseU, fbCombineDisjointXorU, NULL, NULL, NULL, NULL, fbCombineClear, fbCombineSrcU, NULL, /* CombineDst */ fbCombineConjointOverU, fbCombineConjointOverReverseU, fbCombineConjointInU, fbCombineConjointInReverseU, fbCombineConjointOutU, fbCombineConjointOutReverseU, fbCombineConjointAtopU, fbCombineConjointAtopReverseU, fbCombineConjointXorU, }; static CombineFuncC pixman_fbCombineFuncC[] = { fbCombineClearC, fbCombineSrcC, NULL, /* Dest */ fbCombineOverC, fbCombineOverReverseC, fbCombineInC, fbCombineInReverseC, fbCombineOutC, fbCombineOutReverseC, fbCombineAtopC, fbCombineAtopReverseC, fbCombineXorC, fbCombineAddC, fbCombineSaturateC, NULL, NULL, fbCombineClearC, /* 0x10 */ fbCombineSrcC, NULL, /* Dest */ fbCombineDisjointOverC, fbCombineSaturateC, /* DisjointOverReverse */ fbCombineDisjointInC, fbCombineDisjointInReverseC, fbCombineDisjointOutC, fbCombineDisjointOutReverseC, fbCombineDisjointAtopC, fbCombineDisjointAtopReverseC, fbCombineDisjointXorC, /* 0x1b */ NULL, NULL, NULL, NULL, fbCombineClearC, fbCombineSrcC, NULL, /* Dest */ fbCombineConjointOverC, fbCombineConjointOverReverseC, fbCombineConjointInC, fbCombineConjointInReverseC, fbCombineConjointOutC, fbCombineConjointOutReverseC, fbCombineConjointAtopC, fbCombineConjointAtopReverseC, fbCombineConjointXorC, }; FbComposeFunctions pixman_composeFunctions = { pixman_fbCombineFuncU, pixman_fbCombineFuncC, pixman_fbCombineMaskU };