/* A CopyPlane function that handles bitmap->screen copies and sends anything else to the Fallback. Also, a PushPixels for solid fill styles. Written by Mark Vojkovich (markv@valinux.com) */ #ifdef HAVE_XORG_CONFIG_H #include <xorg-config.h> #endif #include <string.h> #include "misc.h" #include "xf86.h" #include "xf86_OSproc.h" #include "servermd.h" #include <X11/X.h> #include "scrnintstr.h" #include "mi.h" #include "pixmapstr.h" #include "xf86str.h" #include "xaa.h" #include "xaalocal.h" #include "xaawrap.h" static void XAACopyPlane1toNColorExpand(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, RegionPtr rgnDst, DDXPointPtr pptSrc); static void XAACopyPlaneNtoNColorExpand(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, RegionPtr rgnDst, DDXPointPtr pptSrc); static unsigned long TmpBitPlane; RegionPtr XAACopyPlaneColorExpansion( DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, int srcx, int srcy, int width, int height, int dstx, int dsty, unsigned long bitPlane ){ if((pSrc->type == DRAWABLE_PIXMAP) && !XAA_DEPTH_BUG(pGC)) { if(pSrc->bitsPerPixel == 1) { return(XAABitBlt(pSrc, pDst, pGC, srcx, srcy, width, height, dstx, dsty, XAACopyPlane1toNColorExpand, bitPlane)); } else if(bitPlane < (1 << pDst->depth)){ TmpBitPlane = bitPlane; return(XAABitBlt(pSrc, pDst, pGC, srcx, srcy, width, height, dstx, dsty, XAACopyPlaneNtoNColorExpand, bitPlane)); } } return (XAAFallbackOps.CopyPlane(pSrc, pDst, pGC, srcx, srcy, width, height, dstx, dsty, bitPlane)); } static void XAACopyPlane1toNColorExpand( DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, RegionPtr rgnDst, DDXPointPtr pptSrc ) { XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC); BoxPtr pbox = REGION_RECTS(rgnDst); int numrects = REGION_NUM_RECTS(rgnDst); unsigned char *src = ((PixmapPtr)pSrc)->devPrivate.ptr; int srcwidth = ((PixmapPtr)pSrc)->devKind; while(numrects--) { (*infoRec->WriteBitmap)(infoRec->pScrn, pbox->x1, pbox->y1, pbox->x2 - pbox->x1, pbox->y2 - pbox->y1, src + (srcwidth * pptSrc->y) + ((pptSrc->x >> 5) << 2), srcwidth, pptSrc->x & 31, pGC->fgPixel, pGC->bgPixel, pGC->alu, pGC->planemask); pbox++; pptSrc++; } } static void XAACopyPlaneNtoNColorExpand( DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, RegionPtr rgnDst, DDXPointPtr pptSrc ){ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC); BoxPtr pbox = REGION_RECTS(rgnDst); int numrects = REGION_NUM_RECTS(rgnDst); unsigned char *src = ((PixmapPtr)pSrc)->devPrivate.ptr; unsigned char *data, *srcPtr, *dataPtr; int srcwidth = ((PixmapPtr)pSrc)->devKind; int pitch, width, height, h, i, index, offset; int Bpp = pSrc->bitsPerPixel >> 3; unsigned long mask = TmpBitPlane; if(TmpBitPlane < (1 << 8)) { offset = 0; } else if(TmpBitPlane < (1 << 16)) { offset = 1; mask >>= 8; } else if(TmpBitPlane < (1 << 24)) { offset = 2; mask >>= 16; } else { offset = 3; mask >>= 24; } if(IS_OFFSCREEN_PIXMAP(pSrc)) SYNC_CHECK(pSrc); while(numrects--) { width = pbox->x2 - pbox->x1; h = height = pbox->y2 - pbox->y1; pitch = BitmapBytePad(width); if(!(data = xcalloc(height, pitch))) goto ALLOC_FAILED; dataPtr = data; srcPtr = ((pptSrc->y) * srcwidth) + src + ((pptSrc->x) * Bpp) + offset; while(h--) { for(i = index = 0; i < width; i++, index += Bpp) { if(mask & srcPtr[index]) dataPtr[i >> 3] |= (1 << (i & 7)); } dataPtr += pitch; srcPtr += srcwidth; } (*infoRec->WriteBitmap)(infoRec->pScrn, pbox->x1, pbox->y1, width, height, data, pitch, 0, pGC->fgPixel, pGC->bgPixel, pGC->alu, pGC->planemask); xfree(data); ALLOC_FAILED: pbox++; pptSrc++; } } void XAAPushPixelsSolidColorExpansion( GCPtr pGC, PixmapPtr pBitMap, DrawablePtr pDraw, int dx, int dy, int xOrg, int yOrg ) { XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC); int MaxBoxes = REGION_NUM_RECTS(pGC->pCompositeClip); BoxPtr pbox, pClipBoxes; int nboxes, srcx, srcy; xRectangle TheRect; unsigned char *src = pBitMap->devPrivate.ptr; int srcwidth = pBitMap->devKind; if(!REGION_NUM_RECTS(pGC->pCompositeClip)) return; TheRect.x = xOrg; TheRect.y = yOrg; TheRect.width = dx; TheRect.height = dy; if(MaxBoxes > (infoRec->PreAllocSize/sizeof(BoxRec))) { pClipBoxes = xalloc(MaxBoxes * sizeof(BoxRec)); if(!pClipBoxes) return; } else pClipBoxes = (BoxPtr)infoRec->PreAllocMem; nboxes = XAAGetRectClipBoxes(pGC, pClipBoxes, 1, &TheRect); pbox = pClipBoxes; while(nboxes--) { srcx = pbox->x1 - xOrg; srcy = pbox->y1 - yOrg; (*infoRec->WriteBitmap)(infoRec->pScrn, pbox->x1, pbox->y1, pbox->x2 - pbox->x1, pbox->y2 - pbox->y1, src + (srcwidth * srcy) + ((srcx >> 5) << 2), srcwidth, srcx & 31, pGC->fgPixel, -1, pGC->alu, pGC->planemask); pbox++; } if(pClipBoxes != (BoxPtr)infoRec->PreAllocMem) xfree(pClipBoxes); }