summaryrefslogtreecommitdiff
path: root/fb
diff options
context:
space:
mode:
Diffstat (limited to 'fb')
-rw-r--r--fb/fb.h17
-rw-r--r--fb/fballpriv.c12
-rw-r--r--fb/fbcompose.c136
-rw-r--r--fb/fbedge.c134
-rw-r--r--fb/fbedgeimp.h134
-rw-r--r--fb/fbfill.c6
-rw-r--r--fb/fbgc.c2
-rw-r--r--fb/fbglyph.c2
-rw-r--r--fb/fboverlay.c11
-rw-r--r--fb/fboverlay.h7
-rw-r--r--fb/fbpict.c290
-rw-r--r--fb/fbpict.h103
-rw-r--r--fb/fbpixmap.c5
-rw-r--r--fb/fbscreen.c6
-rw-r--r--fb/fbsolid.c1
-rw-r--r--fb/fbtrap.c1495
-rw-r--r--fb/fbwindow.c19
17 files changed, 848 insertions, 1532 deletions
diff --git a/fb/fb.h b/fb/fb.h
index 9eb27eab2..0f24303f8 100644
--- a/fb/fb.h
+++ b/fb/fb.h
@@ -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,
diff --git a/fb/fbgc.c b/fb/fbgc.c
index a3d1b0bc6..f854afc78 100644
--- a/fb/fbgc.c
+++ b/fb/fbgc.c
@@ -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);