diff options
author | Kaleb Keithley <kaleb@freedesktop.org> | 2003-11-14 16:49:22 +0000 |
---|---|---|
committer | Kaleb Keithley <kaleb@freedesktop.org> | 2003-11-14 16:49:22 +0000 |
commit | d568221710959cf7d783e6ff0fb80fb43a231124 (patch) | |
tree | 8d6f039393294c6ffac8533639afdebe5d68bfc1 /cfb/cfbbitblt.c | |
parent | 9508a382f8a9f241dab097d921b6d290c1c3a776 (diff) |
XFree86 4.3.0.1
Diffstat (limited to 'cfb/cfbbitblt.c')
-rw-r--r-- | cfb/cfbbitblt.c | 465 |
1 files changed, 437 insertions, 28 deletions
diff --git a/cfb/cfbbitblt.c b/cfb/cfbbitblt.c index 3afe4eb81..595d68c66 100644 --- a/cfb/cfbbitblt.c +++ b/cfb/cfbbitblt.c @@ -2,6 +2,8 @@ * cfb copy area */ +/* $XFree86: xc/programs/Xserver/cfb/cfbbitblt.c,v 1.14 2001/12/14 19:59:21 dawes Exp $ */ + /* Copyright 1989, 1998 The Open Group @@ -39,6 +41,7 @@ Author: Keith Packard #include "scrnintstr.h" #include "pixmapstr.h" #include "regionstr.h" +#include "mi.h" #include "cfb.h" #include "cfbmskbits.h" #include "cfb8bit.h" @@ -46,6 +49,25 @@ Author: Keith Packard #define MFB_CONSTS_ONLY #include "maskbits.h" +#if PSZ == 8 +#define cfbCopyPlane1toN cfbCopyPlane1to8 +#define cfbCopyPlaneNto1 cfbCopyPlane8to1 +#else +static unsigned int FgPixel, BgPixel; +# if PSZ == 16 +#define cfbCopyPlane1toN cfbCopyPlane1to16 +#define cfbCopyPlaneNto1 cfbCopyPlane16to1 +# endif +# if PSZ == 24 +#define cfbCopyPlane1toN cfbCopyPlane1to24 +#define cfbCopyPlaneNto1 cfbCopyPlane24to1 +# endif +# if PSZ == 32 +#define cfbCopyPlane1toN cfbCopyPlane1to32 +#define cfbCopyPlaneNto1 cfbCopyPlane32to1 +# endif +#endif + RegionPtr cfbBitBlt (pSrcDrawable, pDstDrawable, pGC, srcx, srcy, width, height, dstx, dsty, doBitBlt, bitPlane) @@ -58,7 +80,7 @@ cfbBitBlt (pSrcDrawable, pDstDrawable, void (*doBitBlt)(); unsigned long bitPlane; { - RegionPtr prgnSrcClip; /* may be a new region, or just a copy */ + RegionPtr prgnSrcClip = NULL; /* may be a new region, or just a copy */ Bool freeSrcClip = FALSE; RegionPtr prgnExposed; @@ -110,7 +132,13 @@ cfbBitBlt (pSrcDrawable, pDstDrawable, { if (pGC->subWindowMode == IncludeInferiors) { - if (!((WindowPtr) pSrcDrawable)->parent) + /* + * XFree86 DDX empties the border clip when the + * VT is inactive + */ + if (!((WindowPtr) pSrcDrawable)->parent && + REGION_NOTEMPTY (pSrcDrawable->pScreen, + &((WindowPtr) pSrcDrawable)->borderClip)) { /* * special case bitblt from root window in @@ -279,7 +307,7 @@ cfbBitBlt (pSrcDrawable, pDstDrawable, } prgnExposed = NULL; - if ( cfbGetGCPrivate(pGC)->fExpose) + if (pGC->fExpose) { extern RegionPtr miHandleExposures(); @@ -376,22 +404,22 @@ cfbCopyPlane1to8 (pSrcDrawable, pDstDrawable, rop, prgnDst, pptSrc, planemask, b int width, height; /* in pixels, unpadded, of box being copied */ int xoffSrc; /* bit # in leftmost word of row from which copying starts */ int xoffDst; /* byte # in leftmost word of row from which copying starts */ - unsigned long *psrcBase, *pdstBase; /* start of drawable's pixel data */ + CfbBits *psrcBase, *pdstBase; /* start of drawable's pixel data */ int widthSrc; /* # of groups of 32 pixels (1 bit/pixel) in src bitmap*/ int widthDst; /* # of groups of 4 pixels (8 bits/pixel) in dst */ - unsigned long *psrcLine, *pdstLine; /* steps a row at a time thru src/dst; + CfbBits *psrcLine, *pdstLine; /* steps a row at a time thru src/dst; * may point into middle of row */ - register unsigned long *psrc, *pdst; /* steps within the row */ - register unsigned long bits, tmp; /* bits from source */ + register CfbBits *psrc, *pdst; /* steps within the row */ + register CfbBits bits, tmp; /* bits from source */ register int leftShift; register int rightShift; - unsigned long startmask; /* left edge pixel mask */ - unsigned long endmask; /* right edge pixel mask */ + CfbBits startmask; /* left edge pixel mask */ + CfbBits endmask; /* right edge pixel mask */ register int nlMiddle; /* number of words in middle of the row to draw */ register int nl; - int firstoff; - int secondoff; - unsigned long src; + int firstoff = 0; + int secondoff = 0; + CfbBits src; int nbox; /* number of boxes in region to copy */ BoxPtr pbox; /* steps thru boxes in region */ int pixelsRemainingOnRightEdge; /* # pixels to be drawn on a row after @@ -529,11 +557,11 @@ cfbCopyPlane1to8 (pSrcDrawable, pDstDrawable, rop, prgnDst, pptSrc, planemask, b # define FirstStep(c) c = BitLeft (c, 8); #else /* 0x3c is 0xf << 2 (4 bits, long word) */ -# define StoreBits(o,c) StorePixels(pdst,o,*((unsigned long *)\ +# define StoreBits(o,c) StorePixels(pdst,o,*((CfbBits *)\ (((char *) cfb8Pixels) + (c & 0x3c)))) # define StoreRopBits(o,c) StoreRopPixels(pdst,o, \ - *((unsigned long *) (((char *) cfb8StippleAnd) + (c & 0x3c))), \ - *((unsigned long *) (((char *) cfb8StippleXor) + (c & 0x3c)))) + *((CfbBits *) (((char *) cfb8StippleAnd) + (c & 0x3c))), \ + *((CfbBits *) (((char *) cfb8StippleXor) + (c & 0x3c)))) # define FirstStep(c) c = BitLeft (c, 2); #endif /* PGSZ */ #endif /* BITMAP_BIT_ORDER */ @@ -662,10 +690,379 @@ cfbCopyPlane1to8 (pSrcDrawable, pDstDrawable, rop, prgnDst, pptSrc, planemask, b } /* end iteration over region boxes */ } +#else /* PSZ == 8 */ + +#define mfbmaskbits(x, w, startmask, endmask, nlw) \ + startmask = starttab[(x)&0x1f]; \ + endmask = endtab[((x)+(w)) & 0x1f]; \ + if (startmask) \ + nlw = (((w) - (32 - ((x)&0x1f))) >> 5); \ + else \ + nlw = (w) >> 5; + +#define mfbmaskpartialbits(x, w, mask) \ + mask = partmasks[(x)&0x1f][(w)&0x1f]; + +#define LeftMost 0 +#define StepBit(bit, inc) ((bit) += (inc)) + + +#define GetBits(psrc, nBits, curBit, bitPos, bits) {\ + bits = 0; \ + while (nBits--) \ + { \ + bits |= ((*psrc++ >> bitPos) & 1) << curBit; \ + StepBit (curBit, 1); \ + } \ +} + +/******************************************************************/ + +void +#if PSZ == 16 +cfbCopyPlane1to16 (pSrcDrawable, pDstDrawable, rop, prgnDst, pptSrc, + planemask, bitPlane) +#endif +#if PSZ == 24 +cfbCopyPlane1to24 (pSrcDrawable, pDstDrawable, rop, prgnDst, pptSrc, + planemask, bitPlane) +#endif +#if PSZ == 32 +cfbCopyPlane1to32 (pSrcDrawable, pDstDrawable, rop, prgnDst, pptSrc, + planemask, bitPlane) +#endif + DrawablePtr pSrcDrawable; + DrawablePtr pDstDrawable; + int rop; + unsigned long planemask; + RegionPtr prgnDst; + DDXPointPtr pptSrc; + unsigned long bitPlane; +{ + int srcx, srcy, dstx, dsty; + int width, height; + int xoffSrc; + CfbBits *psrcBase, *pdstBase; + int widthSrc, widthDst; + unsigned int *psrcLine; + register unsigned int *psrc; +#if PSZ == 16 + unsigned short *pdstLine; + register unsigned short *pdst; +#endif +#if PSZ == 32 + unsigned int *pdstLine; + register unsigned int *pdst; +#endif +#if PSZ == 24 + unsigned char *pdstLine; + register unsigned char *pdst; +#endif + register unsigned int bits, tmp; + register unsigned int fgpixel, bgpixel; + register unsigned int src; +#if PSZ == 24 + register unsigned int dst; +#endif + register int leftShift, rightShift; + register int i, nl; + int nbox; + BoxPtr pbox; + int result; + +#if PSZ == 16 + unsigned int doublet[4]; /* Pixel values for 16bpp expansion. */ +#endif +#if PSZ == 32 + unsigned int doublet[8]; /* Pixel values for 32bpp expansion */ +#endif + + fgpixel = FgPixel & planemask; + bgpixel = BgPixel & planemask; + +#if PSZ == 16 + if (rop == GXcopy && (planemask & PMSK) == PMSK) { + doublet[0] = bgpixel | (bgpixel << 16); + doublet[1] = fgpixel | (bgpixel << 16); + doublet[2] = bgpixel | (fgpixel << 16); + doublet[3] = fgpixel | (fgpixel << 16); + } +#endif +#if PSZ == 32 + if (rop == GXcopy && (planemask & PMSK) == PMSK) { + doublet[0] = bgpixel; doublet[1] = bgpixel; + doublet[2] = fgpixel; doublet[3] = bgpixel; + doublet[4] = bgpixel; doublet[5] = fgpixel; + doublet[6] = fgpixel; doublet[7] = fgpixel; + } +#endif + + /* must explicitly ask for "int" widths, as code below expects it */ + /* on some machines (Alpha), "long" and "int" are not the same size */ + cfbGetTypedWidthAndPointer (pSrcDrawable, widthSrc, psrcBase, int, CfbBits) + cfbGetTypedWidthAndPointer (pDstDrawable, widthDst, pdstBase, int, CfbBits) + +#if PSZ == 16 + widthDst <<= 1; +#endif +#if PSZ == 24 + widthDst <<= 2; +#endif + + nbox = REGION_NUM_RECTS(prgnDst); + pbox = REGION_RECTS(prgnDst); + + while (nbox--) + { + dstx = pbox->x1; + dsty = pbox->y1; + srcx = pptSrc->x; + srcy = pptSrc->y; + width = pbox->x2 - pbox->x1; + height = pbox->y2 - pbox->y1; + pbox++; + pptSrc++; + psrcLine = (unsigned int *)psrcBase + srcy * widthSrc + (srcx >> 5); +#if PSZ == 16 + pdstLine = (unsigned short *)pdstBase + dsty * widthDst + dstx; +#endif +#if PSZ == 24 + pdstLine = (unsigned char *)pdstBase + dsty * widthDst + dstx * 3; +#endif +#if PSZ == 32 + pdstLine = (unsigned int *)pdstBase + dsty * widthDst + dstx; +#endif + xoffSrc = srcx & 0x1f; + + /* + * compute constants for the first four bits to be + * copied. This avoids troubles with partial first + * writes, and difficult shift computation + */ + leftShift = xoffSrc; + rightShift = 32 - leftShift; + + if (rop == GXcopy && (planemask & PMSK) == PMSK) + { + while (height--) + { + psrc = psrcLine; + pdst = pdstLine; + psrcLine += widthSrc; + pdstLine += widthDst; + bits = *psrc++; + nl = width; + while (nl >= 32) + { + tmp = BitLeft(bits, leftShift); + bits = *psrc++; + if (rightShift != 32) + tmp |= BitRight(bits, rightShift); + i = 0; +#if PSZ == 16 + /* + * I've thrown in some optimization to at least write + * some aligned 32-bit words instead of 16-bit shorts. + */ + if ((unsigned long)psrc & 2) { + /* Write unaligned 16-bit word at left edge. */ + if (tmp & 0x01) + *pdst = fgpixel; + else + *pdst = bgpixel; + pdst++; + i++; + } + while (i <= 24) + { + unsigned tmpbits = tmp >> i; + *(unsigned int *)pdst = doublet[tmpbits & 0x03]; + *(unsigned int *)(pdst + 2) = + doublet[(tmpbits >> 2) & 0x03]; + *(unsigned int *)(pdst + 4) = + doublet[(tmpbits >> 4) & 0x03]; + *(unsigned int *)(pdst + 6) = + doublet[(tmpbits >> 6) & 0x03]; + pdst += 8; /* Advance four 32-bit words. */ + i += 8; + } + while (i <= 30) + { + *(unsigned int *)pdst = + doublet[(tmp >> i) & 0x03]; + pdst += 2; /* Advance one 32-bit word. */ + i += 2; + } + if (i == 31) { + if ((tmp >> 31) & 0x01) + *pdst = fgpixel; + else + *pdst = bgpixel; + pdst++; + } +#endif +#if PSZ == 24 + while (i < 32) { + if ((tmp >> i) & 0x01) { + *pdst = fgpixel; + *(pdst + 1) = fgpixel >> 8; + *(pdst + 2) = fgpixel >> 16; + } + else { + *pdst = bgpixel; + *(pdst + 1) = bgpixel >> 8; + *(pdst + 2) = bgpixel >> 16; + } + pdst += 3; + i++; + } +#endif +#if PSZ == 32 + while (i <= 28) { + int pair; + pair = (tmp >> i) & 0x03; + *pdst = doublet[pair * 2]; + *(pdst + 1) = doublet[pair * 2 + 1]; + pair = (tmp >> (i + 2)) & 0x03; + *(pdst + 2) = doublet[pair * 2]; + *(pdst + 3) = doublet[pair * 2 + 1]; + pdst += 4; + i += 4; + } + while (i < 32) { + *pdst = ((tmp >> i) & 0x01) ? fgpixel : bgpixel; + pdst++; + i++; + } #endif + nl -= 32; + } + + if (nl) + { + tmp = BitLeft(bits, leftShift); + /* + * better condition needed -- mustn't run + * off the end of the source... + */ + if (rightShift != 32) + { + bits = *psrc++; + tmp |= BitRight (bits, rightShift); + } + i = 32; + while (nl--) + { + --i; +#if PSZ == 24 + if ((tmp >> (31 - i)) & 0x01) { + *pdst = fgpixel; + *(pdst + 1) = fgpixel >> 8; + *(pdst + 2) = fgpixel >> 16; + } + else { + *pdst = bgpixel; + *(pdst + 1) = bgpixel >> 8; + *(pdst + 2) = bgpixel >> 16; + } + pdst += 3; +#else + *pdst = ((tmp >> (31 - i)) & 0x01) ? fgpixel : bgpixel; + pdst++; +#endif + } + } + } + } + else + { + while (height--) + { + psrc = psrcLine; + pdst = pdstLine; + psrcLine += widthSrc; + pdstLine += widthDst; + bits = *psrc++; + nl = width; + while (nl >= 32) + { + tmp = BitLeft(bits, leftShift); + bits = *psrc++; + if (rightShift != 32) + tmp |= BitRight(bits, rightShift); + i = 32; + while (i--) + { + src = ((tmp >> (31 - i)) & 0x01) ? fgpixel : bgpixel; +#if PSZ == 24 + dst = *pdst; + dst |= (*(pdst + 1)) << 8; + dst |= (*(pdst + 2)) << 16; + DoRop (result, rop, src, dst); + *pdst = (dst & ~planemask) | + (result & planemask); + *(pdst+1) = ((dst & ~planemask) >> 8) | + ((result & planemask) >> 8); + *(pdst+2) = ((dst & ~planemask) >> 16) | + ((result & planemask) >> 16); + pdst += 3; +#else + DoRop (result, rop, src, *pdst); + + *pdst = (*pdst & ~planemask) | + (result & planemask); + pdst++; +#endif + } + nl -= 32; + } + + if (nl) + { + tmp = BitLeft(bits, leftShift); + /* + * better condition needed -- mustn't run + * off the end of the source... + */ + if (rightShift != 32) + { + bits = *psrc++; + tmp |= BitRight (bits, rightShift); + } + i = 32; + while (nl--) + { + --i; + src = ((tmp >> (31 - i)) & 0x01) ? fgpixel : bgpixel; +#if PSZ == 24 + dst = *pdst; + dst |= (*(pdst + 1)) << 8; + dst |= (*(pdst + 2)) << 16; + DoRop (result, rop, src, dst); + *pdst = (dst & ~planemask) | + (result & planemask); + *(pdst+1) = ((dst & ~planemask) >> 8) | + ((result & planemask) >> 8); + *(pdst+2) = ((dst & ~planemask) >> 16) | + ((result & planemask) >> 16); + pdst += 3; +#else + DoRop (result, rop, src, *pdst); + + *pdst = (*pdst & ~planemask) | + (result & planemask); + pdst++; +#endif + } + } + } + } + } +} + +#endif /* PSZ == 8 */ /* shared among all different cfb depths through linker magic */ -RegionPtr (*cfbPuntCopyPlane)(); RegionPtr cfbCopyPlane(pSrcDrawable, pDstDrawable, pGC, srcx, srcy, width, height, dstx, dsty, bitPlane) @@ -678,19 +1075,24 @@ RegionPtr cfbCopyPlane(pSrcDrawable, pDstDrawable, unsigned long bitPlane; { RegionPtr ret; - extern RegionPtr miHandleExposures(); - void (*doBitBlt)(); -#if PSZ == 8 +#if IMAGE_BYTE_ORDER == LSBFirst + + void (*doBitBlt)(); - if (pSrcDrawable->bitsPerPixel == 1 && pDstDrawable->bitsPerPixel == 8) + if (pSrcDrawable->bitsPerPixel == 1 && pDstDrawable->bitsPerPixel == PSZ) { if (bitPlane == 1) { - doBitBlt = cfbCopyPlane1to8; + doBitBlt = cfbCopyPlane1toN; +#if PSZ == 8 cfb8CheckOpaqueStipple (pGC->alu, pGC->fgPixel, pGC->bgPixel, pGC->planemask); +#else + FgPixel = pGC->fgPixel; + BgPixel = pGC->bgPixel; +#endif ret = cfbBitBlt (pSrcDrawable, pDstDrawable, pGC, srcx, srcy, width, height, dstx, dsty, doBitBlt, bitPlane); } @@ -698,7 +1100,7 @@ RegionPtr cfbCopyPlane(pSrcDrawable, pDstDrawable, ret = miHandleExposures (pSrcDrawable, pDstDrawable, pGC, srcx, srcy, width, height, dstx, dsty, bitPlane); } - else if (pSrcDrawable->bitsPerPixel == 8 && pDstDrawable->bitsPerPixel == 1) + else if (pSrcDrawable->bitsPerPixel == PSZ && pDstDrawable->bitsPerPixel == 1) { extern int InverseAlu[16]; int oldalu; @@ -710,10 +1112,10 @@ RegionPtr cfbCopyPlane(pSrcDrawable, pDstDrawable, pGC->alu = mfbReduceRop(pGC->alu, pGC->fgPixel); ret = cfbBitBlt (pSrcDrawable, pDstDrawable, pGC, srcx, srcy, width, height, dstx, dsty, - cfbCopyPlane8to1, bitPlane); + cfbCopyPlaneNto1, bitPlane); pGC->alu = oldalu; } - else if (pSrcDrawable->bitsPerPixel == 8 && pDstDrawable->bitsPerPixel == 8) + else if (pSrcDrawable->bitsPerPixel == PSZ && pDstDrawable->bitsPerPixel == PSZ) { PixmapPtr pBitmap; ScreenPtr pScreen = pSrcDrawable->pScreen; @@ -729,7 +1131,7 @@ RegionPtr cfbCopyPlane(pSrcDrawable, pDstDrawable, return NULL; } /* - * don't need to set pGC->fgPixel,bgPixel as copyPlane8to1 + * don't need to set pGC->fgPixel,bgPixel as copyPlaneNto1 * ignores pixel values, expecting the rop to "do the * right thing", which GXcopy will. */ @@ -737,13 +1139,18 @@ RegionPtr cfbCopyPlane(pSrcDrawable, pDstDrawable, /* no exposures here, scratch GC's don't get graphics expose */ (void) cfbBitBlt (pSrcDrawable, (DrawablePtr) pBitmap, pGC1, srcx, srcy, width, height, 0, 0, - cfbCopyPlane8to1, bitPlane); + cfbCopyPlaneNto1, bitPlane); +#if PSZ == 8 cfb8CheckOpaqueStipple (pGC->alu, pGC->fgPixel, pGC->bgPixel, pGC->planemask); +#else + FgPixel = pGC->fgPixel; + BgPixel = pGC->bgPixel; +#endif /* no exposures here, copy bits from inside a pixmap */ (void) cfbBitBlt ((DrawablePtr) pBitmap, pDstDrawable, pGC, - 0, 0, width, height, dstx, dsty, cfbCopyPlane1to8, 1); + 0, 0, width, height, dstx, dsty, cfbCopyPlane1toN, 1); FreeScratchGC (pGC1); (*pScreen->DestroyPixmap) (pBitmap); /* compute resultant exposures */ @@ -753,7 +1160,9 @@ RegionPtr cfbCopyPlane(pSrcDrawable, pDstDrawable, } else #endif - ret = (*cfbPuntCopyPlane) (pSrcDrawable, pDstDrawable, + ret = miCopyPlane (pSrcDrawable, pDstDrawable, pGC, srcx, srcy, width, height, dstx, dsty, bitPlane); return ret; } + + |