diff options
Diffstat (limited to 'fb')
-rw-r--r-- | fb/fb.h | 17 | ||||
-rw-r--r-- | fb/fballpriv.c | 12 | ||||
-rw-r--r-- | fb/fbcompose.c | 136 | ||||
-rw-r--r-- | fb/fbedge.c | 134 | ||||
-rw-r--r-- | fb/fbedgeimp.h | 134 | ||||
-rw-r--r-- | fb/fbfill.c | 6 | ||||
-rw-r--r-- | fb/fbgc.c | 2 | ||||
-rw-r--r-- | fb/fbglyph.c | 2 | ||||
-rw-r--r-- | fb/fboverlay.c | 11 | ||||
-rw-r--r-- | fb/fboverlay.h | 7 | ||||
-rw-r--r-- | fb/fbpict.c | 290 | ||||
-rw-r--r-- | fb/fbpict.h | 103 | ||||
-rw-r--r-- | fb/fbpixmap.c | 5 | ||||
-rw-r--r-- | fb/fbscreen.c | 6 | ||||
-rw-r--r-- | fb/fbsolid.c | 1 | ||||
-rw-r--r-- | fb/fbtrap.c | 1495 | ||||
-rw-r--r-- | fb/fbwindow.c | 19 |
17 files changed, 848 insertions, 1532 deletions
@@ -22,6 +22,8 @@ * PERFORMANCE OF THIS SOFTWARE. */ +/* $XdotOrg: xc/programs/Xserver/fb/fb.h,v 1.6 2004/08/11 21:14:17 kem Exp $ */ + #ifndef _FB_H_ #define _FB_H_ @@ -103,9 +105,10 @@ typedef unsigned __int64 FbBits; # else # if defined(__alpha__) || defined(__alpha) || \ defined(ia64) || defined(__ia64__) || \ - defined(__sparc64__) || \ + defined(__sparc64__) || defined(_LP64) || \ defined(__s390x__) || \ defined(amd64) || defined (__amd64__) || \ + defined (__powerpc64__) || \ (defined(sgi) && (_MIPS_SZLONG == 64)) typedef unsigned long FbBits; # else @@ -562,9 +565,13 @@ extern void fbSetBits (FbStip *bits, int stride, FbStip data); } \ } +/* XXX fb*PrivateIndex should be static, but it breaks the ABI */ + extern int fbGCPrivateIndex; +extern int fbGetGCPrivateIndex(void); #ifndef FB_NO_WINDOW_PIXMAPS extern int fbWinPrivateIndex; +extern int fbGetWinPrivateIndex(void); #endif extern const GCOps fbGCOps; extern const GCFuncs fbGCFuncs; @@ -575,6 +582,7 @@ extern const GCFuncs fbGCFuncs; #endif #ifdef FB_OLD_SCREEN +# define FB_OLD_MISCREENINIT /* miScreenInit requires 14 args, not 13 */ extern WindowPtr *WindowTable; #endif @@ -584,6 +592,7 @@ extern WindowPtr *WindowTable; #ifdef FB_SCREEN_PRIVATE extern int fbScreenPrivateIndex; +extern int fbGetScreenPrivateIndex(void); /* private field of a screen */ typedef struct { @@ -592,7 +601,7 @@ typedef struct { } FbScreenPrivRec, *FbScreenPrivPtr; #define fbGetScreenPrivate(pScreen) ((FbScreenPrivPtr) \ - (pScreen)->devPrivates[fbScreenPrivateIndex].ptr) + (pScreen)->devPrivates[fbGetScreenPrivateIndex()].ptr) #endif /* private field of GC */ @@ -616,7 +625,7 @@ typedef struct { } FbGCPrivRec, *FbGCPrivPtr; #define fbGetGCPrivate(pGC) ((FbGCPrivPtr)\ - (pGC)->devPrivates[fbGCPrivateIndex].ptr) + (pGC)->devPrivates[fbGetGCPrivateIndex()].ptr) #ifdef FB_OLD_GC #define fbGetCompositeClip(pGC) (fbGetGCPrivate(pGC)->pCompositeClip) @@ -635,7 +644,7 @@ typedef struct { #define fbGetWindowPixmap(d) fbGetScreenPixmap(((DrawablePtr) (d))->pScreen) #else #define fbGetWindowPixmap(pWin) ((PixmapPtr)\ - ((WindowPtr) (pWin))->devPrivates[fbWinPrivateIndex].ptr) + ((WindowPtr) (pWin))->devPrivates[fbGetWinPrivateIndex()].ptr) #endif #if defined(__DARWIN__)||defined(__CYGWIN__) diff --git a/fb/fballpriv.c b/fb/fballpriv.c index e7fcfd45b..29e98ae9f 100644 --- a/fb/fballpriv.c +++ b/fb/fballpriv.c @@ -27,10 +27,22 @@ #ifdef FB_SCREEN_PRIVATE int fbScreenPrivateIndex; +int fbGetScreenPrivateIndex(void) +{ + return fbScreenPrivateIndex; +} #endif int fbGCPrivateIndex; +int fbGetGCPrivateIndex(void) +{ + return fbGCPrivateIndex; +} #ifndef FB_NO_WINDOW_PIXMAPS int fbWinPrivateIndex; +int fbGetWinPrivateIndex(void) +{ + return fbWinPrivateIndex; +} #endif int fbGeneration; diff --git a/fb/fbcompose.c b/fb/fbcompose.c index e374de692..181a85f4f 100644 --- a/fb/fbcompose.c +++ b/fb/fbcompose.c @@ -1,5 +1,5 @@ /* - * $XdotOrg: xc/programs/Xserver/fb/fbcompose.c,v 1.1.4.2.4.2 2004/03/04 20:16:09 kaleb Exp $ + * $XdotOrg: xc/programs/Xserver/fb/fbcompose.c,v 1.3 2004/05/12 01:49:46 anholt Exp $ * $XFree86: xc/programs/Xserver/fb/fbcompose.c,v 1.17tsi Exp $ * * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc. @@ -191,15 +191,15 @@ fbCombineMaskAlphaC (FbCompositeOperand *src, a = (*msk->fetcha) (msk); if (!a) return 0; - - x = (*src->fetcha) (src); - if (a == 0xffffffff) - return x; - - m = FbInC(x,0,a,t); - n = FbInC(x,8,a,t); - o = FbInC(x,16,a,t); - p = FbInC(x,24,a,t); + + x = (*src->fetch) (src) >> 24; + if (x == 0xff) + return a; + + m = FbInU(a,0,x,t); + n = FbInU(a,8,x,t); + o = FbInU(a,16,x,t); + p = FbInU(a,24,x,t); return m|n|o|p; } @@ -608,7 +608,7 @@ fbCombineAtopC (FbCompositeOperand *src, cs = fbCombineMaskC (src, msk); d = (*dst->fetch) (dst); s = cs.value; - ad = cs.alpha; + ad = ~cs.alpha; as = d >> 24; m = FbGen(s,d,0,as,FbGet8(ad,0),t,u,v); n = FbGen(s,d,8,as,FbGet8(ad,8),t,u,v); @@ -698,10 +698,10 @@ fbCombineXorC (FbCompositeOperand *src, s = cs.value; ad = ~cs.alpha; as = ~d >> 24; - m = FbGen(s,d,0,as,ad,t,u,v); - n = FbGen(s,d,8,as,ad,t,u,v); - o = FbGen(s,d,16,as,ad,t,u,v); - p = FbGen(s,d,24,as,ad,t,u,v); + m = FbGen(s,d,0,as,FbGet8(ad,0),t,u,v); + n = FbGen(s,d,8,as,FbGet8(ad,8),t,u,v); + o = FbGen(s,d,16,as,FbGet8(ad,16),t,u,v); + p = FbGen(s,d,24,as,FbGet8(ad,24),t,u,v); (*dst->store) (dst, m|n|o|p); } @@ -763,10 +763,9 @@ fbCombineSaturateU (FbCompositeOperand *src, FbCompositeOperand *dst) { CARD32 s = fbCombineMaskU (src, msk), d; -#if 0 CARD16 sa, da; CARD16 ad, as; - CARD16 t; + CARD16 t, u, v; CARD32 m,n,o,p; d = (*dst->fetch) (dst); @@ -789,16 +788,6 @@ fbCombineSaturateU (FbCompositeOperand *src, p = FbGen(s,d,24,as,ad,t,u,v); } (*dst->store) (dst, m|n|o|p); -#else - if ((s >> 24) == 0xff) - (*dst->store) (dst, s); - else - { - d = (*dst->fetch) (dst); - if ((s >> 24) > (d >> 24)) - (*dst->store) (dst, s); - } -#endif } void @@ -831,7 +820,7 @@ fbCombineSaturateC (FbCompositeOperand *src, else n = FbGen (s, d, 8, (da << 8) / sg, 0xff, t, u, v); - if (sr < da) + if (sr <= da) o = FbAdd(s,d,16,t); else o = FbGen (s, d, 16, (da << 8) / sr, 0xff, t, u, v); @@ -972,8 +961,8 @@ fbCombineDisjointGeneralC (FbCompositeOperand *src, FbCompSrc cs; CARD32 s, d; CARD32 m,n,o,p; - CARD32 Fa; - CARD16 Fb, t, u, v; + CARD32 Fa, Fb; + CARD16 t, u, v; CARD32 sa; CARD8 da; @@ -996,10 +985,10 @@ fbCombineDisjointGeneralC (FbCompositeOperand *src, Fa = m|n|o|p; break; case CombineAIn: - m = fbCombineDisjointOutPart ((CARD8) (sa >> 0), da); - n = fbCombineDisjointOutPart ((CARD8) (sa >> 8), da) << 8; - o = fbCombineDisjointOutPart ((CARD8) (sa >> 16), da) << 16; - p = fbCombineDisjointOutPart ((CARD8) (sa >> 24), da) << 24; + m = fbCombineDisjointInPart ((CARD8) (sa >> 0), da); + n = fbCombineDisjointInPart ((CARD8) (sa >> 8), da) << 8; + o = fbCombineDisjointInPart ((CARD8) (sa >> 16), da) << 16; + p = fbCombineDisjointInPart ((CARD8) (sa >> 24), da) << 24; Fa = m|n|o|p; break; case CombineA: @@ -1012,19 +1001,27 @@ fbCombineDisjointGeneralC (FbCompositeOperand *src, Fb = 0; break; case CombineBOut: - Fb = fbCombineDisjointOutPart (da, sa); + m = fbCombineDisjointOutPart (da, (CARD8) (sa >> 0)); + n = fbCombineDisjointOutPart (da, (CARD8) (sa >> 8)) << 8; + o = fbCombineDisjointOutPart (da, (CARD8) (sa >> 16)) << 16; + p = fbCombineDisjointOutPart (da, (CARD8) (sa >> 24)) << 24; + Fb = m|n|o|p; break; case CombineBIn: - Fb = fbCombineDisjointInPart (da, sa); + m = fbCombineDisjointInPart (da, (CARD8) (sa >> 0)); + n = fbCombineDisjointInPart (da, (CARD8) (sa >> 8)) << 8; + o = fbCombineDisjointInPart (da, (CARD8) (sa >> 16)) << 16; + p = fbCombineDisjointInPart (da, (CARD8) (sa >> 24)) << 24; + Fb = m|n|o|p; break; case CombineB: - Fb = 0xff; + Fb = 0xffffffff; break; } - m = FbGen (s,d,0,FbGet8(Fa,0),Fb,t,u,v); - n = FbGen (s,d,8,FbGet8(Fa,8),Fb,t,u,v); - o = FbGen (s,d,16,FbGet8(Fa,16),Fb,t,u,v); - p = FbGen (s,d,24,FbGet8(Fa,24),Fb,t,u,v); + m = FbGen (s,d,0,FbGet8(Fa,0),FbGet8(Fb,0),t,u,v); + n = FbGen (s,d,8,FbGet8(Fa,8),FbGet8(Fb,8),t,u,v); + o = FbGen (s,d,16,FbGet8(Fa,16),FbGet8(Fb,16),t,u,v); + p = FbGen (s,d,24,FbGet8(Fa,24),FbGet8(Fb,24),t,u,v); s = m|n|o|p; (*dst->store) (dst, s); } @@ -1065,21 +1062,6 @@ fbCombineDisjointOverC (FbCompositeOperand *src, fbCombineDisjointGeneralC (src, msk, dst, CombineAOver); } -void -fbCombineDisjointOverReverseU (FbCompositeOperand *src, - FbCompositeOperand *msk, - FbCompositeOperand *dst) -{ - fbCombineDisjointGeneralU (src, msk, dst, CombineBOver); -} - -void -fbCombineDisjointOverReverseC (FbCompositeOperand *src, - FbCompositeOperand *msk, - FbCompositeOperand *dst) -{ - fbCombineDisjointGeneralC (src, msk, dst, CombineBOver); -} void fbCombineDisjointInU (FbCompositeOperand *src, @@ -1281,8 +1263,8 @@ fbCombineConjointGeneralC (FbCompositeOperand *src, FbCompSrc cs; CARD32 s, d; CARD32 m,n,o,p; - CARD32 Fa; - CARD16 Fb, t, u, v; + CARD32 Fa, Fb; + CARD16 t, u, v; CARD32 sa; CARD8 da; @@ -1305,10 +1287,10 @@ fbCombineConjointGeneralC (FbCompositeOperand *src, Fa = m|n|o|p; break; case CombineAIn: - m = fbCombineConjointOutPart ((CARD8) (sa >> 0), da); - n = fbCombineConjointOutPart ((CARD8) (sa >> 8), da) << 8; - o = fbCombineConjointOutPart ((CARD8) (sa >> 16), da) << 16; - p = fbCombineConjointOutPart ((CARD8) (sa >> 24), da) << 24; + m = fbCombineConjointInPart ((CARD8) (sa >> 0), da); + n = fbCombineConjointInPart ((CARD8) (sa >> 8), da) << 8; + o = fbCombineConjointInPart ((CARD8) (sa >> 16), da) << 16; + p = fbCombineConjointInPart ((CARD8) (sa >> 24), da) << 24; Fa = m|n|o|p; break; case CombineA: @@ -1321,19 +1303,27 @@ fbCombineConjointGeneralC (FbCompositeOperand *src, Fb = 0; break; case CombineBOut: - Fb = fbCombineConjointOutPart (da, sa); + m = fbCombineConjointOutPart (da, (CARD8) (sa >> 0)); + n = fbCombineConjointOutPart (da, (CARD8) (sa >> 8)) << 8; + o = fbCombineConjointOutPart (da, (CARD8) (sa >> 16)) << 16; + p = fbCombineConjointOutPart (da, (CARD8) (sa >> 24)) << 24; + Fb = m|n|o|p; break; case CombineBIn: - Fb = fbCombineConjointInPart (da, sa); + m = fbCombineConjointInPart (da, (CARD8) (sa >> 0)); + n = fbCombineConjointInPart (da, (CARD8) (sa >> 8)) << 8; + o = fbCombineConjointInPart (da, (CARD8) (sa >> 16)) << 16; + p = fbCombineConjointInPart (da, (CARD8) (sa >> 24)) << 24; + Fb = m|n|o|p; break; case CombineB: - Fb = 0xff; + Fb = 0xffffffff; break; } - m = FbGen (s,d,0,FbGet8(Fa,0),Fb,t,u,v); - n = FbGen (s,d,8,FbGet8(Fa,8),Fb,t,u,v); - o = FbGen (s,d,16,FbGet8(Fa,16),Fb,t,u,v); - p = FbGen (s,d,24,FbGet8(Fa,24),Fb,t,u,v); + m = FbGen (s,d,0,FbGet8(Fa,0),FbGet8(Fb,0),t,u,v); + n = FbGen (s,d,8,FbGet8(Fa,8),FbGet8(Fb,8),t,u,v); + o = FbGen (s,d,16,FbGet8(Fa,16),FbGet8(Fb,16),t,u,v); + p = FbGen (s,d,24,FbGet8(Fa,24),FbGet8(Fb,24),t,u,v); s = m|n|o|p; (*dst->store) (dst, s); } @@ -1519,14 +1509,14 @@ FbCombineFunc fbCombineFuncU[] = { fbCombineAtopReverseU, fbCombineXorU, fbCombineAddU, - fbCombineDisjointOverU, /* Saturate */ + fbCombineSaturateU, 0, 0, fbCombineClear, fbCombineSrcU, fbCombineDst, fbCombineDisjointOverU, - fbCombineDisjointOverReverseU, + fbCombineSaturateU, /* DisjointOverReverse */ fbCombineDisjointInU, fbCombineDisjointInReverseU, fbCombineDisjointOutU, @@ -1566,14 +1556,14 @@ FbCombineFunc fbCombineFuncC[] = { fbCombineAtopReverseC, fbCombineXorC, fbCombineAddC, - fbCombineDisjointOverC, /* Saturate */ + fbCombineSaturateC, 0, 0, fbCombineClear, /* 0x10 */ fbCombineSrcC, fbCombineDst, fbCombineDisjointOverC, - fbCombineDisjointOverReverseC, + fbCombineSaturateC, /* DisjointOverReverse */ fbCombineDisjointInC, fbCombineDisjointInReverseC, fbCombineDisjointOutC, diff --git a/fb/fbedge.c b/fb/fbedge.c new file mode 100644 index 000000000..7a383020b --- /dev/null +++ b/fb/fbedge.c @@ -0,0 +1,134 @@ +/* + * $Id$ + * + * Copyright © 2004 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Keith Packard not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Keith Packard makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include "fb.h" + +#ifdef RENDER + +#include "picturestr.h" +#include "mipict.h" +#include "renderedge.h" +#include "fbpict.h" + +/* + * 8 bit alpha + */ + +#define N_BITS 8 +#define rasterizeEdges fbRasterizeEdges8 + +#define DefineAlpha(line,x) \ + CARD8 *__ap = (CARD8 *) line + (x) + +#define StepAlpha __ap++ + +#define AddAlpha(a) { \ + CARD16 __a = a + *__ap; \ + *__ap = ((CARD8) ((__a) | (0 - ((__a) >> 8)))); \ +} + +#include "fbedgeimp.h" + +#undef AddAlpha +#undef StepAlpha +#undef DefineAlpha +#undef rasterizeEdges +#undef N_BITS + +/* + * 4 bit alpha + */ + +#define N_BITS 4 +#define rasterizeEdges fbRasterizeEdges4 + +#if BITMAP_BIT_ORDER == LSBFirst +#define Shift4(o) ((o) << 2) +#else +#define Shift4(o) ((1-(o)) << 2) +#endif + +#define Get4(x,o) (((x) >> Shift4(o)) & 0xf) +#define Put4(x,o,v) (((x) & ~(0xf << Shift4(o))) | (((v) & 0xf) << Shift4(o))) + +#define DefineAlpha(line,x) \ + CARD8 *__ap = (CARD8 *) line + ((x) >> 1); \ + int __ao = (x) & 1 + +#define StepAlpha ((__ap += __ao), (__ao ^= 1)) + +#define AddAlpha(a) { \ + CARD8 __o = *__ap; \ + CARD8 __a = (a) + Get4(__o, __ao); \ + *__ap = Put4 (__o, __ao, __a | (0 - ((__a) >> 4))); \ +} + +#include "fbedgeimp.h" + +#undef AddAlpha +#undef StepAlpha +#undef DefineAlpha +#undef rasterizeEdges +#undef N_BITS + + +/* + * 1 bit alpha + */ + +#define N_BITS 1 +#define rasterizeEdges fbRasterizeEdges1 + +#include "fbedgeimp.h" + +#undef rasterizeEdges +#undef N_BITS + +void +fbRasterizeEdges (FbBits *buf, + int bpp, + int width, + int stride, + RenderEdge *l, + RenderEdge *r, + xFixed t, + xFixed b) +{ + switch (bpp) { + case 1: + fbRasterizeEdges1 (buf, width, stride, l, r, t, b); + break; + case 4: + fbRasterizeEdges4 (buf, width, stride, l, r, t, b); + break; + case 8: + fbRasterizeEdges8 (buf, width, stride, l, r, t, b); + break; + } +} + +#endif /* RENDER */ diff --git a/fb/fbedgeimp.h b/fb/fbedgeimp.h new file mode 100644 index 000000000..4a91adc19 --- /dev/null +++ b/fb/fbedgeimp.h @@ -0,0 +1,134 @@ +/* + * $Id$ + * + * Copyright © 2004 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Keith Packard not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Keith Packard makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef rasterizeSpan +#endif + +static void +rasterizeEdges (FbBits *buf, + int width, + int stride, + RenderEdge *l, + RenderEdge *r, + xFixed t, + xFixed b) +{ + xFixed y = t; + FbBits *line; + + line = buf + xFixedToInt (y) * stride; + + for (;;) + { + xFixed lx, rx; + int lxi, rxi; + + /* clip X */ + lx = l->x; + if (lx < 0) + lx = 0; + rx = r->x; + if (xFixedToInt (rx) >= width) + rx = IntToxFixed (width); + + /* Skip empty (or backwards) sections */ + if (rx > lx) + { + + /* Find pixel bounds for span */ + lxi = xFixedToInt (lx); + rxi = xFixedToInt (rx); + +#if N_BITS == 1 + { + FbBits *a = line; + FbBits startmask, endmask; + int nmiddle; + int width = rxi - lxi; + int x = lxi; + + a += x >> FB_SHIFT; + x &= FB_MASK; + + FbMaskBits (x, width, startmask, nmiddle, endmask); + if (startmask) + *a++ |= startmask; + while (nmiddle--) + *a++ = FB_ALLONES; + if (endmask) + *a |= endmask; + } +#else + { + DefineAlpha(line,lxi); + int lxs, rxs; + + /* Sample coverage for edge pixels */ + lxs = RenderSamplesX (lx, N_BITS); + rxs = RenderSamplesX (rx, N_BITS); + + /* Add coverage across row */ + if (lxi == rxi) + { + AddAlpha (rxs - lxs); + } + else + { + int xi; + + AddAlpha (N_X_FRAC(N_BITS) - lxs); + StepAlpha; + for (xi = lxi + 1; xi < rxi; xi++) + { + AddAlpha (N_X_FRAC(N_BITS)); + StepAlpha; + } + AddAlpha (rxs); + } + } +#endif + } + + if (y == b) + break; + +#if N_BITS > 1 + if (xFixedFrac (y) != Y_FRAC_LAST(N_BITS)) + { + RenderEdgeStepSmall (l); + RenderEdgeStepSmall (r); + y += STEP_Y_SMALL(N_BITS); + } + else +#endif + { + RenderEdgeStepBig (l); + RenderEdgeStepBig (r); + y += STEP_Y_BIG(N_BITS); + line += stride; + } + } +} + +#undef rasterizeSpan diff --git a/fb/fbfill.c b/fb/fbfill.c index d03bc6461..f5842c252 100644 --- a/fb/fbfill.c +++ b/fb/fbfill.c @@ -24,6 +24,7 @@ /* $XFree86: xc/programs/Xserver/fb/fbfill.c,v 1.5 2003/01/29 00:43:33 torrey Exp $ */ #include "fb.h" +#include "fbmmx.h" void fbFill (DrawablePtr pDrawable, @@ -43,6 +44,11 @@ fbFill (DrawablePtr pDrawable, switch (pGC->fillStyle) { case FillSolid: +#ifdef USE_GCC34_MMX + if (!pPriv->and && fbHaveMMX()) + if (fbSolidFillmmx (pDrawable, x, y, width, height, pPriv->xor)) + return; +#endif fbSolid (dst + (y + dstYoff) * dstStride, dstStride, (x + dstXoff) * dstBpp, @@ -21,7 +21,7 @@ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ -/* $XdotOrg: xc/programs/Xserver/fb/fbgc.c,v 1.1.4.1.4.2 2004/03/04 20:16:09 kaleb Exp $ */ +/* $XdotOrg: xc/programs/Xserver/fb/fbgc.c,v 1.2 2004/04/23 19:05:14 eich Exp $ */ /* $XFree86: xc/programs/Xserver/fb/fbgc.c,v 1.14 2003/12/18 15:22:32 alanh Exp $ */ #include "fb.h" diff --git a/fb/fbglyph.c b/fb/fbglyph.c index 1e13f76d1..128abc4bf 100644 --- a/fb/fbglyph.c +++ b/fb/fbglyph.c @@ -1,5 +1,5 @@ /* - * $XdotOrg: xc/programs/Xserver/fb/fbglyph.c,v 1.1.4.1.4.2 2004/03/04 20:16:09 kaleb Exp $ + * $XdotOrg: xc/programs/Xserver/fb/fbglyph.c,v 1.2 2004/04/23 19:05:14 eich Exp $ * $XFree86: xc/programs/Xserver/fb/fbglyph.c,v 1.12tsi Exp $ * * Copyright © 1998 Keith Packard diff --git a/fb/fboverlay.c b/fb/fboverlay.c index 28068db83..e9ac14eda 100644 --- a/fb/fboverlay.c +++ b/fb/fboverlay.c @@ -1,5 +1,5 @@ /* - * $XFree86: xc/programs/Xserver/fb/fboverlay.c,v 1.6tsi Exp $ + * $XFree86: xc/programs/Xserver/fb/fboverlay.c,v 1.7 2003/11/10 18:21:47 tsi Exp $ * * Copyright © 2000 SuSE, Inc. * @@ -23,12 +23,19 @@ * Author: Keith Packard, SuSE, Inc. */ +/* $XdotOrg: xc/programs/Xserver/fb/fboverlay.c,v 1.4 2004/07/30 20:30:51 ajax Exp $ */ + #include "fb.h" #include "fboverlay.h" int fbOverlayGeneration; int fbOverlayScreenPrivateIndex = -1; +int fbOverlayGetScreenPrivateIndex(void) +{ + return fbOverlayScreenPrivateIndex; +} + /* * Replace this if you want something supporting * multiple overlays with the same depth @@ -402,7 +409,7 @@ fbOverlayFinishScreenInit(ScreenPtr pScreen, if (! miScreenInit(pScreen, 0, xsize, ysize, dpix, dpiy, 0, depth1, ndepths, depths, defaultVisual, nvisuals, visuals -#ifdef FB_OLD_SCREEN +#ifdef FB_OLD_MISCREENINIT , (miBSFuncPtr) 0 #endif )) diff --git a/fb/fboverlay.h b/fb/fboverlay.h index 72891ece3..aecb3856f 100644 --- a/fb/fboverlay.h +++ b/fb/fboverlay.h @@ -27,7 +27,8 @@ #define _FBOVERLAY_H_ extern int fbOverlayGeneration; -extern int fbOverlayScreenPrivateIndex; +extern int fbOverlayScreenPrivateIndex; /* XXX should be static */ +extern int fbOverlayGetScreenPrivateIndex(void); #ifndef FB_OVERLAY_MAX #define FB_OVERLAY_MAX 2 @@ -58,8 +59,8 @@ typedef struct _fbOverlayScrPriv { } FbOverlayScrPrivRec, *FbOverlayScrPrivPtr; #define fbOverlayGetScrPriv(s) \ - ((fbOverlayScreenPrivateIndex != -1) ? \ - (s)->devPrivates[fbOverlayScreenPrivateIndex].ptr : NULL) + ((fbOverlayGetScreenPrivateIndex() != -1) ? \ + (s)->devPrivates[fbOverlayGetScreenPrivateIndex()].ptr : NULL) Bool fbOverlayCreateWindow(WindowPtr pWin); diff --git a/fb/fbpict.c b/fb/fbpict.c index 533f08d01..ff638e5ce 100644 --- a/fb/fbpict.c +++ b/fb/fbpict.c @@ -30,34 +30,8 @@ #include "picturestr.h" #include "mipict.h" #include "fbpict.h" +#include "fbmmx.h" -#define cvt8888to0565(s) ((((s) >> 3) & 0x001f) | \ - (((s) >> 5) & 0x07e0) | \ - (((s) >> 8) & 0xf800)) -#define cvt0565to8888(s) (((((s) << 3) & 0xf8) | (((s) >> 2) & 0x7)) | \ - ((((s) << 5) & 0xfc00) | (((s) >> 1) & 0x300)) | \ - ((((s) << 8) & 0xf80000) | (((s) << 3) & 0x70000))) - -#if IMAGE_BYTE_ORDER == MSBFirst -#define Fetch24(a) ((unsigned long) (a) & 1 ? \ - ((*(a) << 16) | *((CARD16 *) ((a)+1))) : \ - ((*((CARD16 *) (a)) << 8) | *((a)+2))) -#define Store24(a,v) ((unsigned long) (a) & 1 ? \ - ((*(a) = (CARD8) ((v) >> 16)), \ - (*((CARD16 *) ((a)+1)) = (CARD16) (v))) : \ - ((*((CARD16 *) (a)) = (CARD16) ((v) >> 8)), \ - (*((a)+2) = (CARD8) (v)))) -#else -#define Fetch24(a) ((unsigned long) (a) & 1 ? \ - ((*(a)) | (*((CARD16 *) ((a)+1)) << 8)) : \ - ((*((CARD16 *) (a))) | (*((a)+2) << 16))) -#define Store24(a,v) ((unsigned long) (a) & 1 ? \ - ((*(a) = (CARD8) (v)), \ - (*((CARD16 *) ((a)+1)) = (CARD16) ((v) >> 8))) : \ - ((*((CARD16 *) (a)) = (CARD16) (v)),\ - (*((a)+2) = (CARD8) ((v) >> 16)))) -#endif - CARD32 fbOver (CARD32 x, CARD32 y) { @@ -99,43 +73,6 @@ fbIn (CARD32 x, CARD8 y) return m|n|o|p; } -#define fbComposeGetSolid(pict, bits) { \ - FbBits *__bits__; \ - FbStride __stride__; \ - int __bpp__; \ - int __xoff__,__yoff__; \ -\ - fbGetDrawable((pict)->pDrawable,__bits__,__stride__,__bpp__,__xoff__,__yoff__); \ - switch (__bpp__) { \ - case 32: \ - (bits) = *(CARD32 *) __bits__; \ - break; \ - case 24: \ - (bits) = Fetch24 ((CARD8 *) __bits__); \ - break; \ - case 16: \ - (bits) = *(CARD16 *) __bits__; \ - (bits) = cvt0565to8888(bits); \ - break; \ - default: \ - return; \ - } \ - /* manage missing src alpha */ \ - if ((pict)->pFormat->direct.alphaMask == 0) \ - (bits) |= 0xff000000; \ -} - -#define fbComposeGetStart(pict,x,y,type,stride,line,mul) {\ - FbBits *__bits__; \ - FbStride __stride__; \ - int __bpp__; \ - int __xoff__,__yoff__; \ -\ - fbGetDrawable((pict)->pDrawable,__bits__,__stride__,__bpp__,__xoff__,__yoff__); \ - (stride) = __stride__ * sizeof (FbBits) / sizeof (type); \ - (line) = ((type *) __bits__) + (stride) * ((y) - __yoff__) + (mul) * ((x) - __xoff__); \ -} - /* * Naming convention: * @@ -168,7 +105,7 @@ fbCompositeSolidMask_nx8x8888 (CARD8 op, srca = src >> 24; if (src == 0) return; - + fbComposeGetStart (pDst, xDst, yDst, CARD32, dstStride, dstLine, 1); fbComposeGetStart (pMask, xMask, yMask, CARD8, maskStride, maskLine, 1); @@ -940,7 +877,12 @@ fbComposite (CARD8 op, switch (pDst->format) { case PICT_r5g6b5: case PICT_b5g6r5: - func = fbCompositeSolidMask_nx8x0565; +#ifdef USE_GCC34_MMX + if (fbHaveMMX()) + func = fbCompositeSolidMask_nx8x0565mmx; + else +#endif + func = fbCompositeSolidMask_nx8x0565; break; case PICT_r8g8b8: case PICT_b8g8r8: @@ -950,7 +892,12 @@ fbComposite (CARD8 op, case PICT_x8r8g8b8: case PICT_a8b8g8r8: case PICT_x8b8g8r8: - func = fbCompositeSolidMask_nx8x8888; +#ifdef USE_GCC34_MMX + if (fbHaveMMX()) + func = fbCompositeSolidMask_nx8x8888mmx; + else +#endif + func = fbCompositeSolidMask_nx8x8888; break; } break; @@ -959,10 +906,20 @@ fbComposite (CARD8 op, switch (pDst->format) { case PICT_a8r8g8b8: case PICT_x8r8g8b8: - func = fbCompositeSolidMask_nx8888x8888C; +#ifdef USE_GCC34_MMX + if (fbHaveMMX()) + func = fbCompositeSolidMask_nx8888x8888Cmmx; + else +#endif + func = fbCompositeSolidMask_nx8888x8888C; break; case PICT_r5g6b5: - func = fbCompositeSolidMask_nx8888x0565C; +#ifdef USE_GCC34_MMX + if (fbHaveMMX()) + func = fbCompositeSolidMask_nx8888x0565Cmmx; + else +#endif + func = fbCompositeSolidMask_nx8888x0565C; break; } } @@ -972,10 +929,20 @@ fbComposite (CARD8 op, switch (pDst->format) { case PICT_a8b8g8r8: case PICT_x8b8g8r8: - func = fbCompositeSolidMask_nx8888x8888C; +#ifdef USE_GCC34_MMX + if (fbHaveMMX()) + func = fbCompositeSolidMask_nx8888x8888Cmmx; + else +#endif + func = fbCompositeSolidMask_nx8888x8888C; break; case PICT_b5g6r5: - func = fbCompositeSolidMask_nx8888x0565C; +#ifdef USE_GCC34_MMX + if (fbHaveMMX()) + func = fbCompositeSolidMask_nx8888x0565Cmmx; + else +#endif + func = fbCompositeSolidMask_nx8888x0565C; break; } } @@ -993,57 +960,145 @@ fbComposite (CARD8 op, func = fbCompositeSolidMask_nx1xn; break; } + break; + } + } + } + else /* has mask and non-repeating source */ + { + if (pSrc->pDrawable == pMask->pDrawable && + xSrc == xMask && ySrc == yMask && + !pMask->componentAlpha) + { + switch (pSrc->format) { + case PICT_x8b8g8r8: + switch (pMask->format) { + case PICT_a8r8g8b8: + case PICT_a8b8g8r8: + switch (pDst->format) { + case PICT_a8r8g8b8: + case PICT_x8r8g8b8: +#ifdef USE_GCC34_MMX + if (fbHaveMMX()) + func = fbCompositeSrc_8888RevNPx8888mmx; +#endif + break; + case PICT_r5g6b5: +#ifdef USE_GCC34_MMX + if (fbHaveMMX()) + func = fbCompositeSrc_8888RevNPx0565mmx; +#endif + break; + } + break; + } + break; + case PICT_x8r8g8b8: + switch (pMask->format) { + case PICT_a8r8g8b8: + case PICT_a8b8g8r8: + switch (pDst->format) { + case PICT_a8b8g8r8: + case PICT_x8b8g8r8: +#ifdef USE_GCC34_MMX + if (fbHaveMMX()) + func = fbCompositeSrc_8888RevNPx8888mmx; +#endif + break; + case PICT_r5g6b5: +#ifdef USE_GCC34_MMX + if (fbHaveMMX()) + func = fbCompositeSrc_8888RevNPx0565mmx; +#endif + break; + } + break; + } + break; } + break; } } } else { - switch (pSrc->format) { - case PICT_a8r8g8b8: - case PICT_x8r8g8b8: - switch (pDst->format) { + if (srcRepeat && + pSrc->pDrawable->width == 1 && + pSrc->pDrawable->height == 1) + { + /* no mask and repeating source */ + switch (pSrc->format) { case PICT_a8r8g8b8: - case PICT_x8r8g8b8: - func = fbCompositeSrc_8888x8888; - break; - case PICT_r8g8b8: - func = fbCompositeSrc_8888x0888; - break; - case PICT_r5g6b5: - func = fbCompositeSrc_8888x0565; + switch (pDst->format) { + case PICT_a8r8g8b8: + case PICT_x8r8g8b8: +#ifdef USE_GCC34_MMX + if (fbHaveMMX()) + { + srcRepeat = FALSE; + func = fbCompositeSolid_nx8888mmx; + } +#endif + break; + case PICT_r5g6b5: +#ifdef USE_GCC34_MMX + if (fbHaveMMX()) + { + srcRepeat = FALSE; + func = fbCompositeSolid_nx0565mmx; + } +#endif + break; + } break; } - break; - case PICT_a8b8g8r8: - case PICT_x8b8g8r8: - switch (pDst->format) { - case PICT_a8b8g8r8: - case PICT_x8b8g8r8: - func = fbCompositeSrc_8888x8888; - break; - case PICT_b8g8r8: - func = fbCompositeSrc_8888x0888; + } + else + { + switch (pSrc->format) { + case PICT_a8r8g8b8: + switch (pDst->format) { + case PICT_a8r8g8b8: + case PICT_x8r8g8b8: + func = fbCompositeSrc_8888x8888; + break; + case PICT_r8g8b8: + func = fbCompositeSrc_8888x0888; + break; + case PICT_r5g6b5: + func = fbCompositeSrc_8888x0565; + break; + } break; - case PICT_b5g6r5: - func = fbCompositeSrc_8888x0565; + case PICT_a8b8g8r8: + switch (pDst->format) { + case PICT_a8b8g8r8: + case PICT_x8b8g8r8: + func = fbCompositeSrc_8888x8888; + break; + case PICT_b8g8r8: + func = fbCompositeSrc_8888x0888; + break; + case PICT_b5g6r5: + func = fbCompositeSrc_8888x0565; + break; + } break; - } - break; - case PICT_r5g6b5: - switch (pDst->format) { case PICT_r5g6b5: - func = fbCompositeSrc_0565x0565; + switch (pDst->format) { + case PICT_r5g6b5: + func = fbCompositeSrc_0565x0565; + break; + } break; - } - break; - case PICT_b5g6r5: - switch (pDst->format) { case PICT_b5g6r5: - func = fbCompositeSrc_0565x0565; + switch (pDst->format) { + case PICT_b5g6r5: + func = fbCompositeSrc_0565x0565; + break; + } break; } - break; } } break; @@ -1054,21 +1109,36 @@ fbComposite (CARD8 op, case PICT_a8r8g8b8: switch (pDst->format) { case PICT_a8r8g8b8: - func = fbCompositeSrcAdd_8888x8888; +#ifdef USE_GCC34_MMX + if (fbHaveMMX()) + func = fbCompositeSrcAdd_8888x8888mmx; + else +#endif + func = fbCompositeSrcAdd_8888x8888; break; } break; case PICT_a8b8g8r8: switch (pDst->format) { case PICT_a8b8g8r8: - func = fbCompositeSrcAdd_8888x8888; +#ifdef USE_GCC34_MMX + if (fbHaveMMX()) + func = fbCompositeSrcAdd_8888x8888mmx; + else +#endif + func = fbCompositeSrcAdd_8888x8888; break; } break; case PICT_a8: switch (pDst->format) { case PICT_a8: - func = fbCompositeSrcAdd_8000x8000; +#ifdef USE_GCC34_MMX + if (fbHaveMMX()) + func = fbCompositeSrcAdd_8000x8000mmx; + else +#endif + func = fbCompositeSrcAdd_8000x8000; break; } break; @@ -1160,6 +1230,8 @@ fbPictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats) ps->Glyphs = miGlyphs; ps->CompositeRects = miCompositeRects; ps->RasterizeTrapezoid = fbRasterizeTrapezoid; + ps->AddTraps = fbAddTraps; + ps->AddTriangles = fbAddTriangles; #endif /* RENDER */ diff --git a/fb/fbpict.h b/fb/fbpict.h index 9ecc7a909..82f722c41 100644 --- a/fb/fbpict.h +++ b/fb/fbpict.h @@ -25,6 +25,8 @@ #ifndef _FBPICT_H_ #define _FBPICT_H_ +#include "renderedge.h" + #define FbIntMult(a,b,t) ( (t) = (a) * (b) + 0x80, ( ( ( (t)>>8 ) + (t) )>>8 ) ) #define FbIntDiv(a,b) (((CARD16) (a) * 255) / (b)) @@ -70,6 +72,70 @@ typedef void (*CompositeFunc) (CARD8 op, CARD16 width, CARD16 height); +#define fbComposeGetSolid(pict, bits) { \ + FbBits *__bits__; \ + FbStride __stride__; \ + int __bpp__; \ + int __xoff__,__yoff__; \ +\ + fbGetDrawable((pict)->pDrawable,__bits__,__stride__,__bpp__,__xoff__,__yoff__); \ + switch (__bpp__) { \ + case 32: \ + (bits) = *(CARD32 *) __bits__; \ + break; \ + case 24: \ + (bits) = Fetch24 ((CARD8 *) __bits__); \ + break; \ + case 16: \ + (bits) = *(CARD16 *) __bits__; \ + (bits) = cvt0565to8888(bits); \ + break; \ + default: \ + return; \ + } \ + /* manage missing src alpha */ \ + if ((pict)->pFormat->direct.alphaMask == 0) \ + (bits) |= 0xff000000; \ +} + +#define fbComposeGetStart(pict,x,y,type,stride,line,mul) {\ + FbBits *__bits__; \ + FbStride __stride__; \ + int __bpp__; \ + int __xoff__,__yoff__; \ +\ + fbGetDrawable((pict)->pDrawable,__bits__,__stride__,__bpp__,__xoff__,__yoff__); \ + (stride) = __stride__ * sizeof (FbBits) / sizeof (type); \ + (line) = ((type *) __bits__) + (stride) * ((y) - __yoff__) + (mul) * ((x) - __xoff__); \ +} +#define cvt8888to0565(s) ((((s) >> 3) & 0x001f) | \ + (((s) >> 5) & 0x07e0) | \ + (((s) >> 8) & 0xf800)) +#define cvt0565to8888(s) (((((s) << 3) & 0xf8) | (((s) >> 2) & 0x7)) | \ + ((((s) << 5) & 0xfc00) | (((s) >> 1) & 0x300)) | \ + ((((s) << 8) & 0xf80000) | (((s) << 3) & 0x70000))) + +#if IMAGE_BYTE_ORDER == MSBFirst +#define Fetch24(a) ((unsigned long) (a) & 1 ? \ + ((*(a) << 16) | *((CARD16 *) ((a)+1))) : \ + ((*((CARD16 *) (a)) << 8) | *((a)+2))) +#define Store24(a,v) ((unsigned long) (a) & 1 ? \ + ((*(a) = (CARD8) ((v) >> 16)), \ + (*((CARD16 *) ((a)+1)) = (CARD16) (v))) : \ + ((*((CARD16 *) (a)) = (CARD16) ((v) >> 8)), \ + (*((a)+2) = (CARD8) (v)))) +#else +#define Fetch24(a) ((unsigned long) (a) & 1 ? \ + ((*(a)) | (*((CARD16 *) ((a)+1)) << 8)) : \ + ((*((CARD16 *) (a))) | (*((a)+2) << 16))) +#define Store24(a,v) ((unsigned long) (a) & 1 ? \ + ((*(a) = (CARD8) (v)), \ + (*((CARD16 *) ((a)+1)) = (CARD16) ((v) >> 8))) : \ + ((*((CARD16 *) (a)) = (CARD16) (v)),\ + (*((a)+2) = (CARD8) ((v) >> 16)))) +#endif + + typedef struct _FbCompositeOperand FbCompositeOperand; typedef CARD32 (*FbCompositeFetch)(FbCompositeOperand *op); @@ -333,15 +399,8 @@ fbCombineDisjointOverC (FbCompositeOperand *src, FbCompositeOperand *msk, FbCompositeOperand *dst); -void -fbCombineDisjointOverReverseU (FbCompositeOperand *src, - FbCompositeOperand *msk, - FbCompositeOperand *dst); - -void -fbCombineDisjointOverReverseC (FbCompositeOperand *src, - FbCompositeOperand *msk, - FbCompositeOperand *dst); +#define fbCombineDisjointOverReverseU fbCombineSaturateU +#define fbCombineDisjointOverReverseC fbCombineSaturateC void fbCombineDisjointInU (FbCompositeOperand *src, @@ -760,6 +819,17 @@ fbCompositeGeneral (CARD8 op, CARD16 height); +/* fbedge.c */ +void +fbRasterizeEdges (FbBits *buf, + int bpp, + int width, + int stride, + RenderEdge *l, + RenderEdge *r, + xFixed t, + xFixed b); + /* fbpict.c */ CARD32 fbOver (CARD32 x, CARD32 y); @@ -967,10 +1037,25 @@ fbComposite (CARD8 op, CARD16 height); /* fbtrap.c */ + +void +fbAddTraps (PicturePtr pPicture, + INT16 xOff, + INT16 yOff, + int ntrap, + xTrap *traps); + void fbRasterizeTrapezoid (PicturePtr alpha, xTrapezoid *trap, int x_off, int y_off); +void +fbAddTriangles (PicturePtr pPicture, + INT16 xOff, + INT16 yOff, + int ntri, + xTriangle *tris); + #endif /* _FBPICT_H_ */ diff --git a/fb/fbpixmap.c b/fb/fbpixmap.c index e47999dbb..e3abf2b4c 100644 --- a/fb/fbpixmap.c +++ b/fb/fbpixmap.c @@ -73,6 +73,11 @@ fbCreatePixmapBpp (ScreenPtr pScreen, int width, int height, int depth, int bpp) fbInitializeDrawable (&pPixmap->drawable); #endif +#ifdef COMPOSITE + pPixmap->screen_x = 0; + pPixmap->screen_y = 0; +#endif + return pPixmap; } diff --git a/fb/fbscreen.c b/fb/fbscreen.c index 2a46b00be..8815c69e6 100644 --- a/fb/fbscreen.c +++ b/fb/fbscreen.c @@ -1,4 +1,4 @@ -/* +/* $XdotOrg: xc/programs/Xserver/fb/fbscreen.c,v 1.3 2004/05/16 05:08:39 alanc Exp $ * Id: fbscreen.c,v 1.1 1999/11/02 03:54:45 keithp Exp $ * * Copyright © 1998 Keith Packard @@ -21,7 +21,7 @@ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ -/* $XFree86: xc/programs/Xserver/fb/fbscreen.c,v 1.11 2000/09/03 05:09:47 keithp Exp $ */ +/* $XFree86: xc/programs/Xserver/fb/fbscreen.c,v 1.13 2001/05/29 04:54:09 keithp Exp $ */ #include "fb.h" @@ -229,7 +229,7 @@ fbFinishScreenInit(ScreenPtr pScreen, if (! miScreenInit(pScreen, pbits, xsize, ysize, dpix, dpiy, width, rootdepth, ndepths, depths, defaultVisual, nvisuals, visuals -#ifdef FB_OLD_SCREEN +#ifdef FB_OLD_MISCREENINIT , (miBSFuncPtr) 0 #endif )) diff --git a/fb/fbsolid.c b/fb/fbsolid.c index a325da0c2..4b7ff1936 100644 --- a/fb/fbsolid.c +++ b/fb/fbsolid.c @@ -49,7 +49,6 @@ fbSolid (FbBits *dst, return; } #endif - dst += dstX >> FB_SHIFT; dstX &= FB_MASK; FbMaskBitsBytes(dstX, width, and == 0, startmask, startbyte, diff --git a/fb/fbtrap.c b/fb/fbtrap.c index 8fcd2b5cc..09bff0bfd 100644 --- a/fb/fbtrap.c +++ b/fb/fbtrap.c @@ -1,30 +1,26 @@ /* - * $XFree86: xc/programs/Xserver/fb/fbtrap.c,v 1.9 2002/09/26 02:56:48 keithp Exp $ + * $Id$ * - * Copyright © 2000 University of Southern California + * Copyright © 2004 Keith Packard * - * Permission to use, copy, modify, distribute, and sell this software - * and its documentation for any purpose is hereby granted without - * fee, provided that the above copyright notice appear in all copies - * and that both that copyright notice and this permission notice - * appear in supporting documentation, and that the name of University - * of Southern California not be used in advertising or publicity - * pertaining to distribution of the software without specific, - * written prior permission. University of Southern California makes - * no representations about the suitability of this software for any - * purpose. It is provided "as is" without express or implied - * warranty. + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Keith Packard not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Keith Packard makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. * - * University of Southern California DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE BE LIABLE FOR - * ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - * - * Author: Carl Worth, USC, Information Sciences Institute */ + * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ #include "fb.h" @@ -32,1351 +28,208 @@ #include "picturestr.h" #include "mipict.h" +#include "renderedge.h" #include "fbpict.h" -#ifdef DEBUG -#include <stdio.h> -#include <assert.h> - -#define ASSERT(e) assert(e) - -#endif - -#ifndef ASSERT -#define ASSERT(e) -#endif - -#define MAX(a, b) ((a) > (b) ? (a) : (b)) -#define MIN(a, b) ((a) < (b) ? (a) : (b)) - -#define MAX_AREA 0x80000000 - -/* - * A RationalPoint is an exact position along one of the trapezoid - * edges represented by an approximate position (x,y) and two error - * terms (ex_dy, ey_dx). The error in X is multiplied by the Y - * dimension of the line while the error in Y is multiplied by the - * X dimension of the line, allowing an exact measurement of the - * distance from (x,y) to the line. - * - * Generally, while walking an edge, one of ex_dy/ey_dx will be zero - * indicating that the position error is held in the other. - */ -typedef struct { - xFixed x; - xFixed ex_dy; - xFixed y; - xFixed ey_dx; -} RationalPoint; - -/* - * Edges are walked both horizontally and vertically - * They are walked vertically to get to a particular row - * of pixels, and then walked horizontally within that row - * to compute pixel coverage. - * - * Edges are always walked from top to bottom and from - * left to right. This means that for lines moving leftwards - * from top to bottom, the left to right walking actually moves - * backwards along the line with respect to the top to bottom - * walking. - */ - -/* - * A RationalRow represents the two positions where - * an edge intersects a row of pixels. This is used - * to walk an edge vertically - */ - -typedef struct { - RationalPoint top; /* intersection at top of row */ - RationalPoint bottom; /* intersection at bottom of row */ - RationalPoint pixel_top; /* intersection at top of pixel */ -} RationalRow; - -/* - * A RationalCol represents the two positions where - * an edge intersects a column of pixels - */ - -typedef struct { - RationalPoint left; /* intersection at left of column */ - RationalPoint right; /* intersection at right of column */ -} RationalCol; - -/* - Here are some thoughts on line walking: - - Conditions: c2.x - c1.x = 1 - r2.y - r1.y = 1 - - A B C D E F G H - c1\ c1 c2 /c2 -r1 r1 |\ \ r1 r1 / r1/| r1 r1 -\-+---+ \-+---+ +-\-+ +\--+ +--/+ +-/-+ +---+-/ +---+-/ - \| | `.c1 | |r1\| | \ | | / | |/ | | .' | |/ -c1\ | |`-.|c2 | \c2 | | | | | | c1/ | c1|,_/|c2 | /c2 - |\ | | `. | |\ | \ | | / | /| | ./ | | /| - +-\-+ +---+-\ +---+-\ +--\+ +/--+ /-+---+ /-+---+ +-/-+ - r2\| r2 r2 r2\ /r2 r2 r2 |/r2 - \c2 c2 c1 c1/ - - Bottom Right Right Bottom Top Top Right Right - -State transitions: - -A -> C, D E -> E, F -B -> A, B F -> G, H -C -> A, B G -> G, H -D -> C, D H -> E, F - -*/ - -/* - * Values for PixelWalk.depart. Top and Bottom can have the same value - * as only one mode is possible given a line of either positive or - * negative slope. These mark the departure edge while walking - * rightwards across columns. - */ - -typedef enum _departure { - DepartTop = 0, /* edge exits top of pixel */ - DepartBottom = 0, /* edge exits bottom of pixel */ - DepartRight = 1 /* edge exits right edge of pixel */ -} Departure; - -/* - * PixelWalk - * - * This structure holds state to walk a single edge down the trapezoid. - * - * The edge is walked twice -- once by rows and once by columns. - * The two intersections of the pixel by the edge are then set - * from either the row or column position, depending on which edge - * is intersected. - * - * Note that for lines moving left, walking by rows moves down the - * line (increasing y) while walking by columns moves up the line - * (decreasing y). - */ -typedef struct { - xFixed dx; - xFixed ey_thresh; - xFixed dy; - xFixed ex_thresh; - - Departure depart; - - /* slope */ - xFixed m; - xFixed em_dx; - xFixed y_correct; - xFixed ey_correct; - - /* Inverse slope. Does this have a standard symbol? */ - xFixed p; - xFixed ep_dy; - xFixed x_correct; - xFixed ex_correct; - - /* Trapezoid bottom, used to limit walking to the last row */ - xFixed bottom; - - /* - * Current edge positions along pixel rows and columns - */ - RationalRow row; - RationalCol col; - - /* - * The three pixel intersection points, copied from the appropriate - * row or column position above - */ - RationalPoint p_pixel_top; - RationalPoint p_trap_top; - RationalPoint p_trap_bottom; -} PixelWalk; - -#if 0 -#ifdef GCC -#define INLINE inline -#endif -#endif - -#ifndef INLINE -#define INLINE -#endif - -/* - * Step 'pt' vertically to 'newy'. - */ -static INLINE void -pixelWalkMovePointToRow (PixelWalk *pw, RationalPoint *pt, xFixed newy) +void +fbAddTraps (PicturePtr pPicture, + INT16 x_off, + INT16 y_off, + int ntrap, + xTrap *traps) { - xFixed_32_32 oex; - xFixed xoff; - - /* X error of old X position and new Y position */ - oex = (xFixed_32_32) pw->dx * (newy - pt->y) - pt->ey_dx + pt->ex_dy; + FbBits *buf; + int bpp; + int width; + int stride; + int height; + int pxoff, pyoff; + + xFixed x_off_fixed; + xFixed y_off_fixed; + RenderEdge l, r; + xFixed t, b; - /* amount to step X by */ - xoff = oex / pw->dy; + fbGetDrawable (pPicture->pDrawable, buf, stride, bpp, pxoff, pyoff); - /* step X */ - pt->x = pt->x + xoff; + width = pPicture->pDrawable->width; + height = pPicture->pDrawable->height; + x_off += pxoff; + y_off += pyoff; - /* set new X error value for new X position and new Y positition */ - pt->ex_dy = oex - (xFixed_32_32) pw->dy * xoff; + x_off_fixed = IntToxFixed(y_off); + y_off_fixed = IntToxFixed(y_off); - /* set new Y position, set Y error to zero */ - pt->y = newy; - pt->ey_dx = 0; -} - -/* - * Step 'pt' horizontally to 'newx' - */ -static INLINE void -pixelWalkMovePointToCol (PixelWalk *pw, RationalPoint *pt, xFixed newx) -{ - xFixed_32_32 oey; - xFixed yoff; - - /* Special case vertical lines to arbitrary y */ - if (pw->dx == 0) + while (ntrap--) { - pt->x = newx; - pt->ex_dy = 0; - pt->y = 0; - pt->ey_dx = 0; - } - else - { - /* Y error of old Y position and new X position */ - oey = (xFixed_32_32) pw->dy * (newx - pt->x) - pt->ex_dy + pt->ey_dx; - - /* amount to step Y by */ - yoff = oey / pw->dx; - - /* step Y */ - pt->y = pt->y + yoff; - - /* set new Y error value for new Y position and new X position */ - pt->ey_dx = oey - (xFixed_32_32) pw->dx * yoff; - - /* set new X position, set X error to zero */ - pt->x = newx; - pt->ex_dy = 0; - } -} - -/* - * Step the 'row' element of 'pw' vertically - * (increasing y) by one whole pixel - */ -static INLINE void -pixelWalkStepRow (PixelWalk *pw) -{ - xFixed y_next = xFixedFloor (pw->row.bottom.y) + xFixed1; + t = traps->top.y + y_off_fixed; + if (t < 0) + t = 0; + t = RenderSampleCeilY (t, bpp); - if (y_next > pw->bottom) - y_next = pw->bottom; - - /* pw.row.top.y < pw.row.bottom.y */ - pw->row.top = pw->row.bottom; - - if (y_next - pw->row.bottom.y == xFixed1) - { - pw->row.pixel_top = pw->row.bottom; - pw->row.bottom.y += xFixed1; - pw->row.bottom.x += pw->p; - pw->row.bottom.ex_dy += pw->ep_dy; - if (abs (pw->row.bottom.ex_dy) > pw->ex_thresh) - { - pw->row.bottom.x += pw->x_correct; - pw->row.bottom.ex_dy += pw->ex_correct; - } - } - else - { - pixelWalkMovePointToRow (pw, &pw->row.pixel_top, - xFixedCeil (y_next) - xFixed1); - pixelWalkMovePointToRow (pw, &pw->row.bottom, y_next); - } -} - -/* - * Step the 'col' element of 'pw' horizontally - * (increasing x) by one whole pixel - */ -static INLINE void -pixelWalkStepCol (PixelWalk *pw) -{ - /* pw.col.p1.x < pw.col.p2.x */ - /* - * Copy the current right point into the left point - */ - pw->col.left = pw->col.right; - - /* - * Now incrementally walk across the pixel - */ - pw->col.right.x += xFixed1; - pw->col.right.y += pw->m; - pw->col.right.ey_dx += pw->em_dx; - if (pw->col.right.ey_dx > pw->ey_thresh) - { - pw->col.right.y += pw->y_correct; - pw->col.right.ey_dx += pw->ey_correct; - } -} -/* - * Walk to the nearest edge of the next pixel, filling in both p1 and - * p2 as necessary from either the row or col intersections. - * - * The "next" pixel is defined to be the next pixel intersected by the - * line with pixels visited in raster scan order, (for the benefit of - * cache performance). For lines with positive slope it is easy to - * achieve raster scan order by simply calling StepCol for each pixel - * in a given scanline, then calling StepRow once at the end of each - * scanline. - * - * However, for lines of negative slope where the magnitude of dx is - * greater than dy, a little more work needs to be done. The pixels of - * a particular scanline will be visited by succesive calls to StepCol - * as before. This will effectively step "up" the line as we scan from - * left to right. But, the call to StepRow at the end of the scan line - * will step "down" the line and the column information will be - * invalid at that point. - * - * For now, I fix up the column of all negative slope lines by calling - * MovePointToCol at the end of each scanline. However, this is an - * extremely expensive operation since it involves a 64-bit multiply - * and a 64-bit divide. It would be much better, (at least as long as - * abs(dx) is not much greater than dy), to instead step the col - * backwards as many times as necessary. Or even better, we could - * simply restore col to the position it began at when we started the - * scanline, then simply step it backwards once. That would give a - * performance benefit for lines with slope of any magnitude. - */ - -static INLINE void -pixelWalkNextPixel (PixelWalk *pw) -{ - if (pw->dx < 0) - { - /* - * left moving lines - * - * Check which pixel edge we're departing from - * - * Remember that in this case (dx < 0), the 'row' element of 'pw' - * walks down the line while 'col' walks up - */ - if (pw->depart == DepartTop) - { - /* - * The edge departs the row at this pixel, the - * next time it gets used will be for the next row - * - * Step down one row and then recompute the - * column values to start the next row of - * pixels - */ - pixelWalkStepRow(pw); - /* - * Set column exit pixel - */ - pixelWalkMovePointToCol(pw, &pw->col.right, xFixedFloor(pw->row.bottom.x)); - /* - * This moves the exit pixel to the entry pixel - * and computes the next exit pixel - */ - pixelWalkStepCol(pw); - /* - * The first pixel on the next row will always - * be entered from below, set the lower - * intersection of this edge with that pixel - */ - pw->p_trap_bottom = pw->row.bottom; - } - else /* pw->depart == DepartRight */ - { - /* - * easy case -- just move right one pixel - */ - pixelWalkStepCol(pw); - /* - * Set the lower intersection of the edge with the - * pixel -- that's just where the edge entered - * the pixel from the left - */ - pw->p_trap_bottom = pw->col.left; - } - /* - * Now compute which edge the pixel - * is departing from - */ - if (pw->row.top.x <= pw->col.right.x) - { - /* - * row intersection is left of column intersection, - * that means the edge hits the top of the pixel - * before it hits the right edge - */ - pw->p_trap_top = pw->row.top; - pw->depart = DepartTop; - /* - * Further check to see whether the edge - * leaves the right or top edge of the - * whole pixel - */ - if (pw->row.pixel_top.x <= pw->col.right.x) - pw->p_pixel_top = pw->row.pixel_top; - else - pw->p_pixel_top = pw->col.right; - } - else - { - /* - * Row intersection is right of colum intersection, - * that means the edge hits the right edge of the - * pixel first - */ - pw->p_trap_top = pw->col.right; - pw->p_pixel_top = pw->col.right; - pw->depart = DepartRight; - } - } - else - { - /* - * right moving lines - * - * Check which edge we're departing from - * - * In the dx >= 0 case, the row and col elements both - * walk downwards - */ - if (pw->depart == DepartBottom) - { - /* - * The edge departs the row at this pixel, - * the next time it gets used will be for the - * next row - * - * Step down one row and (maybe) over one - * column to prepare for the next row - */ - if (pw->row.bottom.x == pw->col.right.x) - { - /* - * right through the corner of the pixel, - * adjust the column - */ - pixelWalkStepCol(pw); - } - pixelWalkStepRow(pw); - /* - * Set the upper intersection of the edge with - * the pixel, the first pixel on the next - * row is always entered from the top - */ - pw->p_trap_top = pw->row.top; - pw->p_pixel_top = pw->row.pixel_top; - } - else /* pw->depart == DepartRight */ - { - /* - * Easy case -- move right one - * pixel - */ - pixelWalkStepCol(pw); - /* - * Set the upper intersection of the edge - * with the pixel, that's along the left - * edge of the pixel - */ - pw->p_trap_top = pw->col.left; - pw->p_pixel_top = pw->col.left; - } - /* - * Now compute the exit edge and the - * lower intersection of the edge with the pixel - */ - if (pw->row.bottom.x <= pw->col.right.x) - { - /* - * Hit the place where the edge leaves - * the pixel, the lower intersection is - * where the edge hits the bottom - */ - pw->p_trap_bottom = pw->row.bottom; - pw->depart = DepartBottom; - } - else - { - /* - * The edge goes through the - * next pixel on the row, - * the lower intersection is where the - * edge hits the right side of the pixel - */ - pw->p_trap_bottom = pw->col.right; - pw->depart = DepartRight; - } - } -} - -/* - * Compute the first pixel intersection points - * and the departure type from that pixel - */ -static void -pixelWalkFirstPixel (PixelWalk *pw) -{ - if (pw->dx < 0) - { - if (pw->row.top.x <= pw->col.right.x) - { - /* - * leaving through the top. - * upper position is the upper point of - * the 'row' element - */ - pw->depart = DepartTop; - pw->p_trap_top = pw->row.top; - /* - * further check for pixel top - */ - if (pw->row.pixel_top.x <= pw->col.right.x) - pw->p_pixel_top = pw->row.pixel_top; - else - pw->p_pixel_top = pw->col.right; - } - else - { - /* - * leaving through the right side - * upper position is the right point of - * the 'col' element - */ - pw->depart = DepartRight; - pw->p_trap_top = pw->col.right; - pw->p_pixel_top = pw->col.right; - } - /* - * Now find the lower pixel intersection point - */ - if (pw->row.bottom.x >= pw->col.left.x) - /* - * entering through bottom, - * lower position is the bottom point of - * the 'row' element - */ - pw->p_trap_bottom = pw->row.bottom; - else - /* - * entering through left side, - * lower position is the left point of - * the 'col' element - */ - pw->p_trap_bottom = pw->col.left; - } - else - { - if (pw->row.bottom.x <= pw->col.right.x) - { - /* - * leaving through the bottom (or corner). - * lower position is the lower point of - * the 'row' element - */ - pw->depart = DepartBottom; - pw->p_trap_bottom = pw->row.bottom; - } - else - { - /* - * leaving through the right side - * lower position is the right point of - * the 'col' element - */ - pw->depart = DepartRight; - pw->p_trap_bottom = pw->col.right; - } - /* - * Now find the upper pixel intersection point - */ - if (pw->row.top.x >= pw->col.left.x) - { - /* - * entering through the top (or corner), - * upper position is the top point - * of the 'row' element - */ - pw->p_trap_top = pw->row.top; - /* - * further check for pixel entry - */ - if (pw->row.pixel_top.x >= pw->col.left.x) - pw->p_pixel_top = pw->row.pixel_top; - else - pw->p_pixel_top = pw->col.left; - } - else - { - /* - * entering through the left side, - * upper position is the left point of - * the 'col' element - */ - pw->p_trap_top = pw->col.left; - pw->p_pixel_top = pw->col.left; + b = traps->bot.y + y_off_fixed; + if (xFixedToInt (b) >= height) + b = IntToxFixed (height) - 1; + b = RenderSampleFloorY (b, bpp); + + if (b >= t) + { + /* initialize edge walkers */ + RenderEdgeInit (&l, bpp, t, + traps->top.l + x_off_fixed, + traps->top.y + y_off_fixed, + traps->bot.l + x_off_fixed, + traps->bot.y + y_off_fixed); + + RenderEdgeInit (&r, bpp, t, + traps->top.r + x_off_fixed, + traps->top.y + y_off_fixed, + traps->bot.r + x_off_fixed, + traps->bot.y + y_off_fixed); + + fbRasterizeEdges (buf, bpp, width, stride, &l, &r, t, b); } + traps++; } } -static void -pixelWalkInit (PixelWalk *pw, xLineFixed *line, xFixed top_y, xFixed bottom_y) +void +fbRasterizeTrapezoid (PicturePtr pPicture, + xTrapezoid *trap, + int x_off, + int y_off) { - xFixed_32_32 dy_inc, dx_inc; - xFixed next_y; - xFixed left_x; - xPointFixed *top, *bot; - - next_y = xFixedFloor (top_y) + xFixed1; - if (next_y > bottom_y) - next_y = bottom_y; - - /* - * Orient lines top down - */ - if (line->p1.y < line->p2.y) - { - top = &line->p1; - bot = &line->p2; - } - else - { - top = &line->p2; - bot = &line->p1; - } - - pw->dx = bot->x - top->x; - pw->ey_thresh = abs(pw->dx >> 1); - pw->dy = bot->y - top->y; - pw->ex_thresh = pw->dy >> 1; - - /* - * Set step values for walking lines - */ - if (pw->dx < 0) - { - pw->x_correct = -1; - pw->ex_correct = pw->dy; - pw->y_correct = -1; - pw->ey_correct = pw->dx; - } - else - { - pw->x_correct = 1; - pw->ex_correct = -pw->dy; - pw->y_correct = 1; - pw->ey_correct = -pw->dx; - } - - pw->bottom = bottom_y; - - /* - * Compute Bresenham values for walking edges incrementally - */ - dy_inc = (xFixed_32_32) xFixed1 * pw->dy; /* > 0 */ - if (pw->dx != 0) - { - pw->m = dy_inc / pw->dx; /* sign(dx) */ - pw->em_dx = dy_inc - (xFixed_32_32) pw->m * pw->dx; /* > 0 */ - } - else - { - /* Vertical line. Setting these to zero prevents us from - having to put any conditions in pixelWalkStepCol. */ - pw->m = 0; - pw->em_dx = 0; - } - - dx_inc = (xFixed_32_32) xFixed1 * (xFixed_32_32) pw->dx; /* sign(dx) */ - pw->p = dx_inc / pw->dy; /* sign(dx) */ - pw->ep_dy = dx_inc - (xFixed_32_32) pw->p * pw->dy; /* sign(dx) */ - - /* - * Initialize 'row' for walking down rows - */ - pw->row.bottom.x = top->x; - pw->row.bottom.ex_dy = 0; - pw->row.bottom.y = top->y; - pw->row.bottom.ey_dx = 0; - - /* - * Initialize 'pixel_top' to be on the line for - * the first step - */ - pw->row.pixel_top = pw->row.bottom; - /* - * Move to the pixel above the 'top_y' coordinate, - * first setting 'bottom' and then using StepRow - * which moves that to 'top' and computes the next 'bottom' - */ - pixelWalkMovePointToRow(pw, &pw->row.bottom, top_y); - pixelWalkStepRow(pw); - - /* - * Initialize 'col' for walking across columns - */ - pw->col.right.x = top->x; - pw->col.right.ex_dy = 0; - pw->col.right.y = top->y; - pw->col.right.ey_dx = 0; - - /* - * First set the column to the left most - * pixel hit by the row - */ - if (pw->dx < 0) - left_x = pw->row.bottom.x; - else - left_x = pw->row.top.x; + FbBits *buf; + int bpp; + int width; + int stride; + int height; + int pxoff, pyoff; + + xFixed x_off_fixed; + xFixed y_off_fixed; + RenderEdge l, r; + xFixed t, b; - pixelWalkMovePointToCol(pw, &pw->col.right, xFixedFloor (left_x)); - pixelWalkStepCol(pw); - - /* - * Compute first pixel intersections and the - * first departure state - */ - pixelWalkFirstPixel (pw); -} - -#define RoundShift(a,b) (((a) + (1 << ((b) - 1))) >> (b)) -#define MaxAlpha(depth) ((1 << (depth)) - 1) - -#define AreaAlpha(area, depth) (RoundShift (RoundShift (area, depth) * \ - MaxAlpha (depth), \ - (31 - depth))) - -/* - Pixel coverage from the upper-left corner bounded by one horizontal - bottom line (bottom) and one line defined by two points, (x1,y1) and - (x2,y2), which intersect the pixel. y1 must be less than y2. There - are 8 cases yielding the following area calculations: - - A B C D E F G H -+---+ +---+ +-1-+ +1--+ +--1+ +-1-+ +---+ +---+ -| | 1 | | \| | \ | | / | |/ | | 1 | | -1 | |`-.| | 2 | | | | | | 2 | |,_/| | 1 -|\ | | 2 | | | \ | | / | | | 2 | | /| -+-2-+ +---+ +---+ +--2+ +2--+ +---+ +---+ +-2-+ - -A: (1/2 * x2 * (y2 - y1)) -B: (1/2 * x2 * (y2 - y1)) + (bottom - y2) * x2 -C: (1/2 * (x1 + x2) * y2 ) + (bottom - y2) * x2 -D: (1/2 * (x1 + x2) * y2 ) -E: (1/2 * (x1 + x2) * y2 ) -F: (1/2 * x1 * y2 ) -G: (1/2 * x1 * (y2 - y1)) + x1 * y1 -H: (1/2 * (x1 + x2) * (y2 - y1)) + x1 * y1 - -The union of these calculations is valid for all cases. Namely: - - (1/2 * (x1 + x2) * (y2 - y1)) + (bottom - y2) * x2 + x1 * y1 - -An exercise for later would perhaps be to optimize the calculations -for some of the cases above. Specifically, it's possible to eliminate -multiplications by zero in several cases, leaving a maximum of two -multiplies per pixel calculation. (This is even more promising now -that the higher level code actually computes the exact same 8 cases -as part of its pixel walking). - -But, for now, I just want to get something working correctly even if -slower. So, we'll use the non-optimized general equation. - -*/ - -/* 1.16 * 1.16 -> 1.31 */ -#define AREA_MULT(w, h) ( (xFixed_1_31) (((((xFixed_1_16)w)*((xFixed_1_16)h) + 1) >> 1) | (((xFixed_1_16)w)&((xFixed_1_16)h)&0x10000) << 15)) - -/* (1.16 + 1.16) / 2 -> 1.16 */ -#define WIDTH_AVG(x1,x2) (((x1) + (x2) + 1) >> 1) - -#define SubPixelArea(x1, y1, x2, y2, bottom) \ -(xFixed_1_31) ( \ - AREA_MULT((x1), (y1)) \ - + AREA_MULT(WIDTH_AVG((x1), (x2)), (y2) - (y1))\ - + AREA_MULT((x2), (bottom) - (y2)) \ -) + fbGetDrawable (pPicture->pDrawable, buf, stride, bpp, pxoff, pyoff); -/* -static xFixed_1_31 -SubPixelArea (xFixed_1_16 x1, - xFixed_1_16 y1, - xFixed_1_16 x2, - xFixed_1_16 y2, - xFixed_1_16 bottom) -{ - xFixed_1_16 x_trap; - xFixed_1_16 h_top, h_trap, h_bot; - xFixed_1_31 area; - - x_trap = WIDTH_AVG(x1,x2); - h_top = y1; - h_trap = (y2 - y1); - h_bot = (bottom - y2); + width = pPicture->pDrawable->width; + height = pPicture->pDrawable->height; + x_off += pxoff; + y_off += pyoff; - area = AREA_MULT(x1, h_top) + - AREA_MULT(x_trap, h_trap) + - AREA_MULT(x2, h_bot); - - return area; -} -*/ - -#define SubPixelAlpha(x1, y1, x2, y2, bottom, depth) \ -( \ - AreaAlpha( \ - SubPixelArea((x1), (y1), (x2), (y2), (bottom)), \ - (depth) \ - ) \ -) - -/* -static int -SubPixelAlpha (xFixed_1_16 x1, - xFixed_1_16 y1, - xFixed_1_16 x2, - xFixed_1_16 y2, - xFixed_1_16 bottom, - int depth) -{ - xFixed_1_31 area; - - area = SubPixelArea(x1, y1, x2, y2, bottom); + x_off_fixed = IntToxFixed(x_off); + y_off_fixed = IntToxFixed(y_off); + t = trap->top + y_off_fixed; + if (t < 0) + t = 0; + t = RenderSampleCeilY (t, bpp); + + b = trap->bottom + y_off_fixed; + if (xFixedToInt (b) >= height) + b = IntToxFixed (height) - 1; + b = RenderSampleFloorY (b, bpp); - return AreaAlpha(area, depth); + if (b >= t) + { + /* initialize edge walkers */ + RenderLineFixedEdgeInit (&l, bpp, t, &trap->left, x_off, y_off); + RenderLineFixedEdgeInit (&r, bpp, t, &trap->right, x_off, y_off); + + fbRasterizeEdges (buf, bpp, width, stride, &l, &r, t, b); + } } -*/ - -/* Alpha of a pixel above a given horizontal line */ -#define AlphaAbove(pixel_y, line_y, depth) \ -( \ - AreaAlpha(AREA_MULT((line_y) - (pixel_y), xFixed1), depth) \ -) static int -RectAlpha(xFixed pixel_y, xFixed top, xFixed bottom, int depth) +_GreaterY (xPointFixed *a, xPointFixed *b) { - if (depth == 1) - return top == pixel_y ? 1 : 0; - else - return (AlphaAbove (pixel_y, bottom, depth) - - AlphaAbove (pixel_y, top, depth)); + if (a->y == b->y) + return a->x > b->x; + return a->y > b->y; } - /* - * Pixel coverage from the left edge bounded by one horizontal lines, - * (top and bottom), as well as one PixelWalk line. + * Note that the definition of this function is a bit odd because + * of the X coordinate space (y increasing downwards). */ static int -AlphaAboveLeft(RationalPoint *upper, - RationalPoint *lower, - xFixed bottom, - xFixed pixel_x, - xFixed pixel_y, - int depth) +_Clockwise (xPointFixed *ref, xPointFixed *a, xPointFixed *b) { - return SubPixelAlpha(upper->x - pixel_x, - upper->y - pixel_y, - lower->x - pixel_x, - lower->y - pixel_y, - bottom - pixel_y, - depth); -} - -/* - Pixel coverage from the left edge bounded by two horizontal lines, - (top and bottom), as well as one line two points, p1 and p2, which - intersect the pixel. The following condition must be true: + xPointFixed ad, bd; - p2.y > p1.y -*/ - -/* - lr - |\ - +--|-\-------+ - | a| b\ | - =======|===\========== top - | c| d \ | - =======|=====\======== bot - | | \ | - +--|-------\-+ + ad.x = a->x - ref->x; + ad.y = a->y - ref->y; + bd.x = b->x - ref->x; + bd.y = b->y - ref->y; - alpha(d) = alpha(cd) - alpha(c) = alpha(abcd) - alpha(ab) - (alpha(ac) - alpha(c)) - - alpha(d) = pixelalpha(top, bot, right) - pixelalpha(top, bot, left) - - pixelalpha(top, bot, line) = subpixelalpha(bot, line) - subpixelalpha(top, line) -*/ - -static int -PixelAlpha(xFixed pixel_x, - xFixed pixel_y, - xFixed top, - xFixed bottom, - PixelWalk *pw, - int depth) -{ - int alpha; - -#ifdef DEBUG - fprintf(stderr, "alpha (%f, %f) - (%f, %f) = ", - (double) pw->p1.x / (1 << 16), - (double) pw->p1.y / (1 << 16), - (double) pw->p2.x / (1 << 16), - (double) pw->p2.y / (1 << 16)); - fflush(stderr); -#endif - - /* - * Sharp polygons are different, alpha is 1 if the - * area includes the pixel origin, else zero, in - * the above figure, only 'a' has alpha 1 - */ - if (depth == 1) - { - alpha = 0; - if (top == pixel_y && pw->p_pixel_top.x != pixel_x) - alpha = 1; - } - else - { - alpha = (AlphaAboveLeft(&pw->p_pixel_top, &pw->p_trap_bottom, - bottom, pixel_x, pixel_y, depth) - - AlphaAboveLeft(&pw->p_pixel_top, &pw->p_trap_top, - top, pixel_x, pixel_y, depth)); - } - -#ifdef DEBUG - fprintf(stderr, "0x%x => %f\n", - alpha, - (double) alpha / ((1 << depth) -1 )); - fflush(stderr); -#endif - - return alpha; + return ((xFixed_32_32) bd.y * ad.x - (xFixed_32_32) ad.y * bd.x) < 0; } -#define INCREMENT_X_AND_PIXEL \ -{ \ - pixel_x += xFixed1; \ - (*mask.over) (&mask); \ -} - -/* XXX: What do we really want this prototype to look like? Do we want - separate versions for 1, 4, 8, and 16-bit alpha? */ - -#define saturateAdd(t, a, b) (((t) = (a) + (b)), \ - ((CARD8) ((t) | (0 - ((t) >> 8))))) - -#define addAlpha(mask, depth, alpha, temp) (\ - (*(mask)->store) ((mask), (alpha == (1 << depth) - 1) ? \ - 0xff000000 : \ - (saturateAdd (temp, \ - alpha << (8 - depth), \ - (*(mask)->fetch) (mask) >> 24) << 24)) \ -) - +/* FIXME -- this could be made more efficient */ void -fbRasterizeTrapezoid (PicturePtr pMask, - xTrapezoid *pTrap, - int x_off, - int y_off) +fbAddTriangles (PicturePtr pPicture, + INT16 x_off, + INT16 y_off, + int ntri, + xTriangle *tris) { - xTrapezoid trap = *pTrap; - int alpha, temp; - - FbCompositeOperand mask; + xPointFixed *top, *left, *right, *tmp; + xTrapezoid trap; - int depth = pMask->pDrawable->depth; - int max_alpha = (1 << depth) - 1; - int buf_width = pMask->pDrawable->width; - - xFixed x_off_fixed = IntToxFixed(x_off); - xFixed y_off_fixed = IntToxFixed(y_off); - xFixed buf_width_fixed = IntToxFixed(buf_width); - - PixelWalk left, right; - xFixed pixel_x, pixel_y; - xFixed first_right_x; - xFixed y, y_next; - - /* trap.left and trap.right must be non-horizontal */ - if (trap.left.p1.y == trap.left.p2.y - || trap.right.p1.y == trap.right.p2.y) { - return; - } - - trap.top += y_off_fixed; - trap.bottom += y_off_fixed; - trap.left.p1.x += x_off_fixed; - trap.left.p1.y += y_off_fixed; - trap.left.p2.x += x_off_fixed; - trap.left.p2.y += y_off_fixed; - trap.right.p1.x += x_off_fixed; - trap.right.p1.y += y_off_fixed; - trap.right.p2.x += x_off_fixed; - trap.right.p2.y += y_off_fixed; - -#ifdef DEBUG - fprintf(stderr, "(top, bottom) = (%f, %f)\n", - (double) trap.top / (1 << 16), - (double) trap.bottom / (1 << 16)); -#endif - - pixelWalkInit(&left, &trap.left, trap.top, trap.bottom); - pixelWalkInit(&right, &trap.right, trap.top, trap.bottom); - - /* XXX: I'd still like to optimize this loop for top and - bottom. Only the first row intersects top and only the last - row, (which could also be the first row), intersects bottom. So - we could eliminate some unnecessary calculations from all other - rows. Unfortunately, I haven't found an easy way to do it - without bloating the text, (eg. unrolling a couple iterations - of the loop). So, for sake of maintenance, I'm putting off this - optimization at least until this code is more stable.. */ - - if (!fbBuildCompositeOperand (pMask, &mask, 0, xFixedToInt (trap.top), FALSE, FALSE)) - return; - - for (y = trap.top; y < trap.bottom; y = y_next) + for (; ntri; ntri--, tris++) { - pixel_y = xFixedFloor (y); - y_next = pixel_y + xFixed1; - if (y_next > trap.bottom) - y_next = trap.bottom; - - ASSERT (left.row.top.y == y); - ASSERT (left.row.bottom.y == y_next); - ASSERT (right.row.top.y == y); - ASSERT (right.row.bottom.y == y_next); - - pixel_x = xFixedFloor(left.col.left.x); + top = &tris->p1; + left = &tris->p2; + right = &tris->p3; + if (_GreaterY (top, left)) { + tmp = left; left = top; top = tmp; + } + if (_GreaterY (top, right)) { + tmp = right; right = top; top = tmp; + } + if (_Clockwise (top, right, left)) { + tmp = right; right = left; left = tmp; + } /* - * Walk pixels on this row that are left of the - * first possibly lit pixel + * Two cases: * - * pixelWalkNextPixel will change .row.top.y - * when the last pixel covered by the edge - * is passed + * + + + * / \ / \ + * / \ / \ + * / + + \ + * / -- -- \ + * / -- -- \ + * / --- --- \ + * +-- --+ */ - - first_right_x = xFixedFloor(right.col.left.x); - while (right.row.top.y == y && first_right_x < pixel_x) - { - /* these are empty */ - pixelWalkNextPixel (&right); - /* step over */ - first_right_x += xFixed1; - } - - (*mask.set) (&mask, xFixedToInt (pixel_x), xFixedToInt (y)); - /* - * Walk pixels on this row intersected by only trap.left - * - */ - while (left.row.top.y == y && pixel_x < first_right_x) - { - alpha = (RectAlpha (pixel_y, y, y_next, depth) - - PixelAlpha(pixel_x, pixel_y, y, y_next, &left, depth)); - - if (alpha > 0) - { - if (0 <= pixel_x && pixel_x < buf_width_fixed) - addAlpha (&mask, depth, alpha, temp); - } - - /* - * Step right - */ - pixelWalkNextPixel(&left); - INCREMENT_X_AND_PIXEL; - } - - /* - * Either pixels are covered by both edges or - * there are fully covered pixels on this row - */ - if (pixel_x == first_right_x) - { - /* - * Now walk the pixels on this row intersected - * by both edges - */ - while (left.row.top.y == y && right.row.top.y == y) - { - alpha = (PixelAlpha(pixel_x, pixel_y, y, y_next, &right, depth) - - PixelAlpha(pixel_x, pixel_y, y, y_next, &left, depth)); - if (alpha > 0) - { - ASSERT (0 <= alpha && alpha <= max_alpha); - if (0 <= pixel_x && pixel_x < buf_width_fixed) - addAlpha (&mask, depth, alpha, temp); - } - pixelWalkNextPixel(&left); - pixelWalkNextPixel(&right); - INCREMENT_X_AND_PIXEL; - } - /* - * If the right edge is now left of the left edge, - * the left edge will end up only partially walked, - * walk it the rest of the way - */ - while (left.row.top.y == y) - pixelWalkNextPixel(&left); - } + trap.top = top->y; + trap.left.p1 = *top; + trap.left.p2 = *left; + trap.right.p1 = *top; + trap.right.p2 = *right; + if (right->y < left->y) + trap.bottom = right->y; else + trap.bottom = left->y; + fbRasterizeTrapezoid (pPicture, &trap, x_off, y_off); + if (right->y < left->y) { - /* - * Fully covered pixels simply saturate - */ - alpha = RectAlpha (pixel_y, y, y_next, depth); - if (alpha == max_alpha) - { - while (pixel_x < first_right_x) - { - if (0 <= pixel_x && pixel_x < buf_width_fixed) - (*mask.store) (&mask, 0xff000000); - INCREMENT_X_AND_PIXEL; - } - } - else - { - while (pixel_x < first_right_x) - { - ASSERT (0 <= alpha && alpha <= max_alpha); - if (0 <= pixel_x && pixel_x < buf_width_fixed) - addAlpha (&mask, depth, alpha, temp); - INCREMENT_X_AND_PIXEL; - } - } + trap.top = right->y; + trap.bottom = left->y; + trap.right.p1 = *right; + trap.right.p2 = *left; } - - /* - * Finally, pixels intersected only by trap.right - */ - while (right.row.top.y == y) + else { - alpha = PixelAlpha(pixel_x, pixel_y, y, y_next, &right, depth); - if (alpha > 0) - { - if (0 <= pixel_x && pixel_x < buf_width_fixed) - addAlpha (&mask, depth, alpha, temp); - } - pixelWalkNextPixel(&right); - INCREMENT_X_AND_PIXEL; - } - } -} - -/* Some notes on walking while keeping track of errors in both dimensions: - -That's really pretty easy. Your bresenham should be walking sub-pixel -coordinates rather than pixel coordinates. Now you can calculate the -sub-pixel Y coordinate for any arbitrary sub-pixel X coordinate (or vice -versa). - - ey: y error term (distance from current Y sub-pixel to line) * dx - ex: x error term (distance from current X sub-pixel to line) * dy - dx: difference of X coordinates for line endpoints - dy: difference of Y coordinates for line endpoints - x: current fixed-point X coordinate - y: current fixed-point Y coordinate - -One of ey or ex will always be zero, depending on whether the distance to -the line was measured horizontally or vertically. - -In moving from x, y to x1, y1: - - (x1 + e1x/dy) - (x + ex/dy) dx - --------------------------- = -- - (y1 + e1y/dx) - (y + ey/dx) dy - - (x1dy + e1x) - (xdy + ex) = (y1dx + e1y) - (ydx + ey) - - dy(x1 - x) + (e1x - ex) = dx(y1-y) + (e1y - ey) - -So, if you know y1 and want to know x1: - - Set e1y to zero and compute the error from x: - - oex = dx(y1 - y) - ey + ex - - Compute the number of whole pixels to get close to the line: - - wx = oex / dy - - Set x1: - - Now compute the e1x: - - e1x = oex - wx * dy - -A similar operation moves to a known y1. Note that this computation (in -general) requires 64 bit arithmetic. I suggest just using the available -64 bit datatype for now, we can optimize the common cases with a few -conditionals. There's some cpp code in fb/fb.h that selects a 64 bit type -for machines that XFree86 builds on; there aren't any machines missing a -64 bit datatype that I know of. -*/ - -/* Here's a large-step Bresenham for jogging my memory. - -void large_bresenham_x_major(x1, y1, x2, y2, x_inc) -{ - int x, y, dx, dy, m; - int em_dx, ey_dx; - - dx = x2 - x1; - dy = y2 - y1; - - m = (x_inc * dy) / dx; - em_dx = (x_inc * dy) - m * dx; - - x = x1; - y = y1; - ey = 0; - - set(x,y); - - while (x < x2) { - x += x_inc; - y += m; - ey_dx += em_dx; - if (ey_dx > dx_2) { - y++; - ey_dx -= dx; + trap.top = left->y; + trap.bottom = right->y; + trap.left.p1 = *left; + trap.left.p2 = *right; } - set(x,y); + fbRasterizeTrapezoid (pPicture, &trap, x_off, y_off); } } -*/ - -/* Here are the latest, simplified equations for computing trapezoid - coverage of a pixel: - - alpha_from_area(A) = round(2**depth-1 * A) - - alpha(o) = 2**depth-1 - - alpha(a) = alpha_from_area(area(a)) - - alpha(ab) = alpha_from_area(area(ab)) - - alpha(b) = alpha(ab) - alpha (a) - - alpha(abc) = alpha_from_area(area(abc)) - - alpha(c) = alpha(abc) - alpha(ab) - - alpha(ad) = alpha_from_area(area(ad)) - - alpha (d) = alpha(ad) - alpha (a) - - alpha (abde) = alpha_from_area(area(abde)) - - alpha (de) = alpha (abde) - alpha (ab) - - alpha (e) = alpha (de) - alpha (d) - - alpha (abcdef) = alpha_from_area(area(abcdef)) - - alpha (def) = alpha (abcdef) - alpha (abc) - - alpha (f) = alpha (def) - alpha (de) - - alpha (adg) = alpha_from_area(area(adg)) - - alpha (g) = alpha (adg) - alpha (ad) - - alpha (abdegh) = alpha_from_area(area(abdegh)) - - alpha (gh) = alpha (abdegh) - alpha (abde) - - alpha (h) = alpha (gh) - alpha (g) - - alpha (abcdefghi) = alpha_from_area(area(abcdefghi)) = - alpha_from_area(area(o)) = alpha_from_area(1) = alpha(o) - - alpha (ghi) = alpha (abcdefghi) - alpha (abcdef) - - alpha (i) = alpha (ghi) - alpha (gh) -*/ - -/* Latest thoughts from Keith on implementing area/alpha computations: - -*** 1.16 * 1.16 -> 1.31 *** -#define AREA_MULT(w,h) ((w)&(h) == 0x10000 ? 0x80000000 : (((w)*(h) + 1) >> 1) - -*** (1.16 + 1.16) / 2 -> 1.16 *** -#define WIDTH_AVG(x1,x2) (((x1) + (x2) + 1) >> 1) - -xFixed_1_31 -SubpixelArea (xFixed_1_16 x1, - xFixed_1_16 x2, - xFixed_1_16 y1, - xFixed_1_16 y2, - xFixed_1_16 bottom) - { - xFixed_1_16 x_trap; - xFixed_1_16 h_top, h_trap, h_bot; - xFixed_1_31 area; - - x_trap = WIDTH_AVG(x1,x2); - h_top = y1; - h_trap = (y2 - y1); - h_bot = (bottom - y2); - - area = AREA_MULT(x1, h_top) + - AREA_MULT(x_trap, h_trap) + - AREA_MULT(x2, h_bot); - - return area; - } - -To convert this xFixed_1_31 value to alpha using 32 bit arithmetic: - -int -AreaAlpha (xFixed_1_31 area, int depth) - { - return ((area >> bits) * ((1 << depth) - 1)) >> (31 - depth); - } - -Avoiding the branch bubble in the AREA_MULT could be done with either: - -area = (w * h + 1) >> 1; -area |= ((area - 1) & 0x80000000); - -or - #define AREA_MULT(w,h) ((((w)*(h) + 1) >> 1) | ((w)&(h)&0x10000) << 15) - -depending on your preference, the first takes one less operation but -can't be expressed as a macro; the second takes a large constant which may -require an additional instruction on some processors. The differences -will be swamped by the cost of the multiply. - -*/ - #endif /* RENDER */ diff --git a/fb/fbwindow.c b/fb/fbwindow.c index ebf35bba8..9e70d56e1 100644 --- a/fb/fbwindow.c +++ b/fb/fbwindow.c @@ -1,4 +1,4 @@ -/* $XdotOrg: xc/programs/Xserver/fb/fbwindow.c,v 1.1.4.3.2.2 2004/03/04 17:47:28 eich Exp $ */ +/* $XdotOrg: xc/programs/Xserver/fb/fbwindow.c,v 1.4 2004/08/13 08:16:14 keithp Exp $ */ /* * Id: fbwindow.c,v 1.1 1999/11/02 03:54:45 keithp Exp $ * @@ -122,9 +122,12 @@ fbCopyWindow(WindowPtr pWin, { RegionRec rgnDst; int dx, dy; - WindowPtr pwinRoot; - - pwinRoot = WindowTable[pWin->drawable.pScreen->myNum]; +#ifdef COMPOSITE + PixmapPtr pPixmap = fbGetWindowPixmap (pWin); + DrawablePtr pDrawable = &pPixmap->drawable; +#else + DrawablePtr pDrawable = &WindowTable[pWin->drawable.pScreen->myNum]->drawable; +#endif dx = ptOldOrg.x - pWin->drawable.x; dy = ptOldOrg.y - pWin->drawable.y; @@ -134,7 +137,13 @@ fbCopyWindow(WindowPtr pWin, REGION_INTERSECT(pWin->drawable.pScreen, &rgnDst, &pWin->borderClip, prgnSrc); - fbCopyRegion ((DrawablePtr)pwinRoot, (DrawablePtr)pwinRoot, +#ifdef COMPOSITE + if (pPixmap->screen_x || pPixmap->screen_y) + REGION_TRANSLATE (pWin->drawable.pScreen, &rgnDst, + -pPixmap->screen_x, -pPixmap->screen_y); +#endif + + fbCopyRegion (pDrawable, pDrawable, 0, &rgnDst, dx, dy, fbCopyWindowProc, 0, 0); |