2dc138922b
This is a combination of a huge mechanical patch and a few small fixups required to finish the job. They were reviewed separately, but because the server does not build without both pieces, I've merged them together at this time. The mechanical changes were performed by running the included 'fix-region' script over the whole tree: $ git ls-files | grep -v '^fix-' | xargs ./fix-region And then, the white space errors in the resulting patch were fixed using the provided fix-patch-whitespace script. $ sh ./fix-patch-whitespace Thanks to Jamey Sharp for the mighty fine sed-generating sed script. The hand-done changes involve removing functions from dix/region.c that duplicate inline functions in include/regionstr.h, along with their declarations in regionstr.h, mi.h and mispans.h. Reviewed-by: Jamey Sharp <jamey@minilop.net> Signed-off-by: Keith Packard <keithp@keithp.com>
522 lines
13 KiB
C
522 lines
13 KiB
C
|
|
#ifdef HAVE_XORG_CONFIG_H
|
|
#include <xorg-config.h>
|
|
#endif
|
|
|
|
#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"
|
|
|
|
void XAAMoveDWORDS_FixedBase(
|
|
register CARD32* dest,
|
|
register CARD32* src,
|
|
register int dwords )
|
|
{
|
|
while(dwords & ~0x03) {
|
|
*dest = *src;
|
|
*dest = *(src + 1);
|
|
*dest = *(src + 2);
|
|
*dest = *(src + 3);
|
|
dwords -= 4;
|
|
src += 4;
|
|
}
|
|
|
|
if(!dwords) return;
|
|
*dest = *src;
|
|
if(dwords == 1) return;
|
|
*dest = *(src + 1);
|
|
if(dwords == 2) return;
|
|
*dest = *(src + 2);
|
|
}
|
|
|
|
void XAAMoveDWORDS(
|
|
register CARD32* dest,
|
|
register CARD32* src,
|
|
register int dwords )
|
|
{
|
|
while(dwords & ~0x03) {
|
|
*dest = *src;
|
|
*(dest + 1) = *(src + 1);
|
|
*(dest + 2) = *(src + 2);
|
|
*(dest + 3) = *(src + 3);
|
|
src += 4;
|
|
dest += 4;
|
|
dwords -= 4;
|
|
}
|
|
if(!dwords) return;
|
|
*dest = *src;
|
|
if(dwords == 1) return;
|
|
*(dest + 1) = *(src + 1);
|
|
if(dwords == 2) return;
|
|
*(dest + 2) = *(src + 2);
|
|
}
|
|
|
|
void XAAMoveDWORDS_FixedSrc(
|
|
register CARD32* dest,
|
|
register CARD32* src,
|
|
register int dwords )
|
|
{
|
|
while(dwords & ~0x03) {
|
|
*dest = *src;
|
|
*(dest + 1) = *src;
|
|
*(dest + 2) = *src;
|
|
*(dest + 3) = *src;
|
|
dest += 4;
|
|
dwords -= 4;
|
|
}
|
|
if(!dwords) return;
|
|
*dest = *src;
|
|
if(dwords == 1) return;
|
|
*(dest + 1) = *src;
|
|
if(dwords == 2) return;
|
|
*(dest + 2) = *src;
|
|
}
|
|
|
|
static void
|
|
XAAWritePixmap32To24(
|
|
ScrnInfoPtr pScrn,
|
|
int x, int y, int w, int h,
|
|
unsigned char *srcInit,
|
|
int srcwidth, /* bytes */
|
|
int rop,
|
|
unsigned int planemask,
|
|
int trans
|
|
){
|
|
XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
|
|
int count, dwords = bytes_to_int32(w * 3);
|
|
CARD32 *src, *dst;
|
|
Bool PlusOne = FALSE;
|
|
|
|
if((infoRec->ImageWriteFlags & CPU_TRANSFER_PAD_QWORD) &&
|
|
((dwords * h) & 0x01)) {
|
|
PlusOne = TRUE;
|
|
}
|
|
|
|
(*infoRec->SetupForImageWrite)(pScrn, rop, planemask, trans, 24, 24);
|
|
(*infoRec->SubsequentImageWriteRect)(pScrn, x, y, w, h, 0);
|
|
|
|
if(dwords > infoRec->ImageWriteRange) {
|
|
dst = (CARD32*)infoRec->ImageWriteBase;
|
|
while(h--) {
|
|
src = (CARD32*)srcInit;
|
|
count = w;
|
|
|
|
while(count >= 4) {
|
|
*dst = (src[0] & 0x00ffffff) | (src[1] << 24);
|
|
*dst = ((src[1] >> 8) & 0x0000ffff) | (src[2] << 16);
|
|
*dst = ((src[2] >> 16) & 0x000000ff) | (src[3] << 8);
|
|
src += 4;
|
|
count -= 4;
|
|
}
|
|
switch(count) {
|
|
case 0: break;
|
|
case 1: *dst = src[0];
|
|
break;
|
|
case 2: *dst = (src[0] & 0x00ffffff) | (src[1] << 24);
|
|
*dst = src[1] >> 8;
|
|
break;
|
|
default: *dst = (src[0] & 0x00ffffff) | (src[1] << 24);
|
|
*dst = ((src[1] >> 8) & 0x0000ffff) | (src[2] << 16);
|
|
*dst = src[2] >> 16;
|
|
break;
|
|
}
|
|
srcInit += srcwidth;
|
|
}
|
|
} else {
|
|
while(h--) {
|
|
dst = (CARD32*)infoRec->ImageWriteBase;
|
|
src = (CARD32*)srcInit;
|
|
count = w;
|
|
|
|
while(count >= 4) {
|
|
dst[0] = (src[0] & 0x00ffffff) | (src[1] << 24);
|
|
dst[1] = ((src[1] >> 8) & 0x0000ffff) | (src[2] << 16);
|
|
dst[2] = ((src[2] >> 16) & 0x000000ff) | (src[3] << 8);
|
|
dst += 3;
|
|
src += 4;
|
|
count -= 4;
|
|
}
|
|
switch(count) {
|
|
case 0: break;
|
|
case 1: dst[0] = src[0];
|
|
break;
|
|
case 2: dst[0] = (src[0] & 0x00ffffff) | (src[1] << 24);
|
|
dst[1] = src[1] >> 8;
|
|
break;
|
|
default: dst[0] = (src[0] & 0x00ffffff) | (src[1] << 24);
|
|
dst[1] = ((src[1] >> 8) & 0x0000ffff) | (src[2] << 16);
|
|
dst[2] = src[2] >> 16;
|
|
break;
|
|
}
|
|
srcInit += srcwidth;
|
|
}
|
|
}
|
|
|
|
if(PlusOne) {
|
|
CARD32* base = (CARD32*)infoRec->ImageWriteBase;
|
|
*base = 0x00000000;
|
|
}
|
|
|
|
if(infoRec->ImageWriteFlags & SYNC_AFTER_IMAGE_WRITE)
|
|
(*infoRec->Sync)(pScrn);
|
|
else SET_SYNC_FLAG(infoRec);
|
|
|
|
}
|
|
|
|
void
|
|
XAAWritePixmap (
|
|
ScrnInfoPtr pScrn,
|
|
int x, int y, int w, int h,
|
|
unsigned char *src,
|
|
int srcwidth, /* bytes */
|
|
int rop,
|
|
unsigned int planemask,
|
|
int trans,
|
|
int bpp, int depth
|
|
){
|
|
XAAInfoRecPtr infoRec;
|
|
int dwords, skipleft, Bpp;
|
|
Bool beCareful, PlusOne;
|
|
|
|
if((bpp == 32) && (pScrn->bitsPerPixel == 24)) {
|
|
XAAWritePixmap32To24(pScrn, x, y, w, h, src, srcwidth,
|
|
rop, planemask, trans);
|
|
return;
|
|
}
|
|
|
|
infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
|
|
beCareful = PlusOne = FALSE;
|
|
Bpp = bpp >> 3;
|
|
|
|
if((skipleft = (long)src & 0x03L)) {
|
|
if(!(infoRec->ImageWriteFlags & LEFT_EDGE_CLIPPING)) {
|
|
skipleft = 0;
|
|
beCareful = TRUE;
|
|
goto BAD_ALIGNMENT;
|
|
}
|
|
|
|
if(Bpp == 3)
|
|
skipleft = 4 - skipleft;
|
|
else
|
|
skipleft /= Bpp;
|
|
|
|
if((x < skipleft) && !(infoRec->ImageWriteFlags &
|
|
LEFT_EDGE_CLIPPING_NEGATIVE_X)) {
|
|
skipleft = 0;
|
|
beCareful = TRUE;
|
|
goto BAD_ALIGNMENT;
|
|
}
|
|
|
|
x -= skipleft;
|
|
w += skipleft;
|
|
|
|
if(Bpp == 3)
|
|
src -= 3 * skipleft;
|
|
else /* is this Alpha friendly ? */
|
|
src = (unsigned char*)((long)src & ~0x03L);
|
|
}
|
|
|
|
BAD_ALIGNMENT:
|
|
|
|
dwords = bytes_to_int32(w * Bpp);
|
|
|
|
if((infoRec->ImageWriteFlags & CPU_TRANSFER_PAD_QWORD) &&
|
|
((dwords * h) & 0x01)) {
|
|
PlusOne = TRUE;
|
|
}
|
|
|
|
|
|
(*infoRec->SetupForImageWrite)(pScrn, rop, planemask, trans, bpp, depth);
|
|
(*infoRec->SubsequentImageWriteRect)(pScrn, x, y, w, h, skipleft);
|
|
|
|
if(beCareful) {
|
|
/* in cases with bad alignment we have to be careful not
|
|
to read beyond the end of the source */
|
|
if(((x * Bpp) + (dwords << 2)) > srcwidth) h--;
|
|
else beCareful = FALSE;
|
|
}
|
|
|
|
if(dwords > infoRec->ImageWriteRange) {
|
|
while(h--) {
|
|
XAAMoveDWORDS_FixedBase((CARD32*)infoRec->ImageWriteBase,
|
|
(CARD32*)src, dwords);
|
|
src += srcwidth;
|
|
}
|
|
if(beCareful) {
|
|
int shift = ((long)src & 0x03L) << 3;
|
|
if(--dwords)
|
|
XAAMoveDWORDS_FixedBase((CARD32*)infoRec->ImageWriteBase,
|
|
(CARD32*)src, dwords);
|
|
src = (unsigned char*)((long)(src + (dwords << 2)) & ~0x03L);
|
|
*((CARD32*)infoRec->ImageWriteBase) = *((CARD32*)src) >> shift;
|
|
}
|
|
} else {
|
|
if(srcwidth == (dwords << 2)) {
|
|
int decrement = infoRec->ImageWriteRange/dwords;
|
|
|
|
while(h > decrement) {
|
|
XAAMoveDWORDS((CARD32*)infoRec->ImageWriteBase,
|
|
(CARD32*)src, dwords * decrement);
|
|
src += (srcwidth * decrement);
|
|
h -= decrement;
|
|
}
|
|
if(h) {
|
|
XAAMoveDWORDS((CARD32*)infoRec->ImageWriteBase,
|
|
(CARD32*)src, dwords * h);
|
|
if(beCareful) src += (srcwidth * h);
|
|
}
|
|
} else {
|
|
while(h--) {
|
|
XAAMoveDWORDS((CARD32*)infoRec->ImageWriteBase,
|
|
(CARD32*)src, dwords);
|
|
src += srcwidth;
|
|
}
|
|
}
|
|
|
|
if(beCareful) {
|
|
int shift = ((long)src & 0x03L) << 3;
|
|
if(--dwords)
|
|
XAAMoveDWORDS((CARD32*)infoRec->ImageWriteBase,
|
|
(CARD32*)src, dwords);
|
|
src = (unsigned char*)((long)(src + (dwords << 2)) & ~0x03L);
|
|
|
|
((CARD32*)infoRec->ImageWriteBase)[dwords] =
|
|
*((CARD32*)src) >> shift;
|
|
}
|
|
}
|
|
|
|
if(PlusOne) {
|
|
CARD32* base = (CARD32*)infoRec->ImageWriteBase;
|
|
*base = 0x00000000;
|
|
}
|
|
|
|
if(infoRec->ImageWriteFlags & SYNC_AFTER_IMAGE_WRITE)
|
|
(*infoRec->Sync)(pScrn);
|
|
else SET_SYNC_FLAG(infoRec);
|
|
}
|
|
|
|
|
|
void
|
|
XAAWritePixmapScanline (
|
|
ScrnInfoPtr pScrn,
|
|
int x, int y, int w, int h,
|
|
unsigned char *src,
|
|
int srcwidth, /* bytes */
|
|
int rop,
|
|
unsigned int planemask,
|
|
int trans,
|
|
int bpp, int depth
|
|
){
|
|
XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
|
|
int dwords, skipleft, bufferNo = 0, Bpp = bpp >> 3;
|
|
Bool beCareful = FALSE;
|
|
CARD32* base;
|
|
|
|
if((skipleft = (long)src & 0x03L)) {
|
|
if(!(infoRec->ScanlineImageWriteFlags & LEFT_EDGE_CLIPPING)) {
|
|
skipleft = 0;
|
|
beCareful = TRUE;
|
|
goto BAD_ALIGNMENT;
|
|
}
|
|
|
|
if(Bpp == 3)
|
|
skipleft = 4 - skipleft;
|
|
else
|
|
skipleft /= Bpp;
|
|
|
|
if((x < skipleft) && !(infoRec->ScanlineImageWriteFlags &
|
|
LEFT_EDGE_CLIPPING_NEGATIVE_X)) {
|
|
skipleft = 0;
|
|
beCareful = TRUE;
|
|
goto BAD_ALIGNMENT;
|
|
}
|
|
|
|
x -= skipleft;
|
|
w += skipleft;
|
|
|
|
if(Bpp == 3)
|
|
src -= 3 * skipleft;
|
|
else
|
|
src = (unsigned char*)((long)src & ~0x03L);
|
|
}
|
|
|
|
BAD_ALIGNMENT:
|
|
|
|
dwords = bytes_to_int32(w * Bpp);
|
|
|
|
(*infoRec->SetupForScanlineImageWrite)(
|
|
pScrn, rop, planemask, trans, bpp, depth);
|
|
(*infoRec->SubsequentScanlineImageWriteRect)(pScrn, x, y, w, h, skipleft);
|
|
|
|
if(beCareful) {
|
|
/* in cases with bad alignment we have to be careful not
|
|
to read beyond the end of the source */
|
|
if(((x * Bpp) + (dwords << 2)) > srcwidth) h--;
|
|
else beCareful = FALSE;
|
|
}
|
|
|
|
while(h--) {
|
|
base = (CARD32*)infoRec->ScanlineImageWriteBuffers[bufferNo];
|
|
XAAMoveDWORDS(base, (CARD32*)src, dwords);
|
|
(*infoRec->SubsequentImageWriteScanline)(pScrn, bufferNo++);
|
|
src += srcwidth;
|
|
if(bufferNo >= infoRec->NumScanlineImageWriteBuffers)
|
|
bufferNo = 0;
|
|
}
|
|
|
|
if(beCareful) {
|
|
int shift = ((long)src & 0x03L) << 3;
|
|
base = (CARD32*)infoRec->ScanlineImageWriteBuffers[bufferNo];
|
|
if(--dwords)
|
|
XAAMoveDWORDS(base,(CARD32*)src, dwords);
|
|
src = (unsigned char*)((long)(src + (dwords << 2)) & ~0x03L);
|
|
|
|
base[dwords] = *((CARD32*)src) >> shift;
|
|
(*infoRec->SubsequentImageWriteScanline)(pScrn, bufferNo);
|
|
}
|
|
|
|
SET_SYNC_FLAG(infoRec);
|
|
}
|
|
|
|
|
|
void
|
|
XAAPutImage(
|
|
DrawablePtr pDraw,
|
|
GCPtr pGC,
|
|
int depth,
|
|
int x,
|
|
int y,
|
|
int w,
|
|
int h,
|
|
int leftPad,
|
|
int format,
|
|
char *pImage
|
|
){
|
|
XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
|
|
int bpp = BitsPerPixel(depth);
|
|
Bool depthBug = FALSE;
|
|
if(!w || !h) return;
|
|
|
|
if(!RegionNumRects(pGC->pCompositeClip))
|
|
return;
|
|
|
|
depthBug = XAA_DEPTH_BUG(pGC);
|
|
|
|
if(((format == ZPixmap) && infoRec->WritePixmap &&
|
|
((pDraw->bitsPerPixel == bpp) ||
|
|
((pDraw->bitsPerPixel == 24) && (bpp == 32) &&
|
|
(infoRec->WritePixmapFlags & CONVERT_32BPP_TO_24BPP))) &&
|
|
CHECK_ROP(pGC,infoRec->WritePixmapFlags) &&
|
|
CHECK_ROPSRC(pGC,infoRec->WritePixmapFlags) &&
|
|
CHECK_PLANEMASK(pGC,infoRec->WritePixmapFlags) &&
|
|
CHECK_NO_GXCOPY(pGC,infoRec->WritePixmapFlags)) ||
|
|
((format == XYBitmap) && !depthBug && infoRec->WriteBitmap &&
|
|
CHECK_ROP(pGC,infoRec->WriteBitmapFlags) &&
|
|
CHECK_ROPSRC(pGC,infoRec->WriteBitmapFlags) &&
|
|
CHECK_PLANEMASK(pGC,infoRec->WriteBitmapFlags) &&
|
|
CHECK_COLORS(pGC,infoRec->WriteBitmapFlags) &&
|
|
!(infoRec->WriteBitmapFlags & TRANSPARENCY_ONLY)) ||
|
|
((format == XYPixmap) && !depthBug && infoRec->WriteBitmap &&
|
|
CHECK_ROP(pGC,infoRec->WriteBitmapFlags) &&
|
|
CHECK_ROPSRC(pGC,infoRec->WriteBitmapFlags) &&
|
|
!(infoRec->WriteBitmapFlags & NO_PLANEMASK) &&
|
|
!(infoRec->WriteBitmapFlags & TRANSPARENCY_ONLY))){
|
|
|
|
int MaxBoxes = RegionNumRects(pGC->pCompositeClip);
|
|
BoxPtr pbox, pClipBoxes;
|
|
int nboxes, srcx, srcy, srcwidth;
|
|
xRectangle TheRect;
|
|
|
|
TheRect.x = pDraw->x + x;
|
|
TheRect.y = pDraw->y + y;
|
|
TheRect.width = w;
|
|
TheRect.height = h;
|
|
|
|
if(MaxBoxes > (infoRec->PreAllocSize/sizeof(BoxRec))) {
|
|
pClipBoxes = malloc(MaxBoxes * sizeof(BoxRec));
|
|
if(!pClipBoxes) return;
|
|
} else pClipBoxes = (BoxPtr)infoRec->PreAllocMem;
|
|
|
|
nboxes = XAAGetRectClipBoxes(pGC, pClipBoxes, 1, &TheRect);
|
|
pbox = pClipBoxes;
|
|
|
|
if(format == XYBitmap) {
|
|
srcwidth = BitmapBytePad(leftPad + w);
|
|
while(nboxes--) {
|
|
srcx = pbox->x1 - TheRect.x + leftPad;
|
|
srcy = pbox->y1 - TheRect.y;
|
|
(*infoRec->WriteBitmap)(infoRec->pScrn, pbox->x1, pbox->y1,
|
|
pbox->x2 - pbox->x1, pbox->y2 - pbox->y1,
|
|
(unsigned char*)pImage +
|
|
(srcwidth * srcy) + ((srcx >> 5) << 2),
|
|
srcwidth, srcx & 31, pGC->fgPixel, pGC->bgPixel,
|
|
pGC->alu, pGC->planemask);
|
|
pbox++;
|
|
}
|
|
} else if(format == ZPixmap) {
|
|
int Bpp = bpp >> 3;
|
|
srcwidth = PixmapBytePad(leftPad + w, depth);
|
|
while(nboxes--) {
|
|
srcx = pbox->x1 - TheRect.x + leftPad;
|
|
srcy = pbox->y1 - TheRect.y;
|
|
(*infoRec->WritePixmap)(infoRec->pScrn, pbox->x1, pbox->y1,
|
|
pbox->x2 - pbox->x1, pbox->y2 - pbox->y1,
|
|
(unsigned char*)pImage +
|
|
(srcwidth * srcy) + (srcx * Bpp),
|
|
srcwidth, pGC->alu, pGC->planemask, -1,
|
|
Bpp << 3, depth);
|
|
pbox++;
|
|
}
|
|
} else { /* XYPixmap */
|
|
int depth = pGC->depth;
|
|
int numBox, increment;
|
|
unsigned long i, mask;
|
|
BoxPtr pntBox;
|
|
|
|
srcwidth = BitmapBytePad(w + leftPad);
|
|
increment = h * srcwidth;
|
|
i = 1 << (depth - 1);
|
|
mask = ~0;
|
|
|
|
if((infoRec->pScrn->overlayFlags & OVERLAY_8_32_PLANAR) &&
|
|
(pGC->depth == 8)){
|
|
i = 0x80000000; mask = 0xff000000;
|
|
}
|
|
|
|
for(; i & mask; i >>= 1, pImage += increment) {
|
|
if(i & pGC->planemask) {
|
|
pntBox = pbox;
|
|
numBox = nboxes;
|
|
while(numBox--) {
|
|
srcx = pntBox->x1 - TheRect.x + leftPad;
|
|
srcy = pntBox->y1 - TheRect.y;
|
|
(*infoRec->WriteBitmap)(infoRec->pScrn,
|
|
pntBox->x1, pntBox->y1,
|
|
pntBox->x2 - pntBox->x1,
|
|
pntBox->y2 - pntBox->y1,
|
|
(unsigned char*)pImage +
|
|
(srcwidth * srcy) + ((srcx >> 5) << 2),
|
|
srcwidth, srcx & 31, ~0, 0, pGC->alu, i);
|
|
pntBox++;
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
if(pClipBoxes != (BoxPtr)infoRec->PreAllocMem)
|
|
free(pClipBoxes);
|
|
} else
|
|
XAAFallbackOps.PutImage(pDraw, pGC, depth, x, y, w, h, leftPad,
|
|
format, pImage);
|
|
}
|