xenocara/xserver/hw/xfree86/xaa/xaaCpyPlane.c

211 lines
5.0 KiB
C
Raw Normal View History

2006-11-26 11:13:41 -07:00
/*
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 < 8) {
offset = 0;
} else if(TmpBitPlane < 16) {
offset = 1;
mask >>= 8;
} else if(TmpBitPlane < 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 = xalloc(height * pitch)))
goto ALLOC_FAILED;
bzero(data, height * pitch);
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);
}