diff options
Diffstat (limited to 'xorg-server/hw/xfree86/xaa/xaaCpyArea.c')
-rw-r--r-- | xorg-server/hw/xfree86/xaa/xaaCpyArea.c | 774 |
1 files changed, 387 insertions, 387 deletions
diff --git a/xorg-server/hw/xfree86/xaa/xaaCpyArea.c b/xorg-server/hw/xfree86/xaa/xaaCpyArea.c index 6a898cd5f..eefd8d38d 100644 --- a/xorg-server/hw/xfree86/xaa/xaaCpyArea.c +++ b/xorg-server/hw/xfree86/xaa/xaaCpyArea.c @@ -1,387 +1,387 @@ - -#ifdef HAVE_XORG_CONFIG_H -#include <xorg-config.h> -#endif - -#include "misc.h" -#include "xf86.h" -#include "xf86_OSproc.h" - -#include <X11/X.h> -#include "scrnintstr.h" -#include "xf86str.h" -#include "xaa.h" -#include "xaalocal.h" -#include "migc.h" -#include "gcstruct.h" -#include "pixmapstr.h" - -/* - Written mostly by Harm Hanemaayer (H.Hanemaayer@inter.nl.net). - */ - - -RegionPtr -XAACopyArea( - DrawablePtr pSrcDrawable, - DrawablePtr pDstDrawable, - GC *pGC, - int srcx, int srcy, - int width, int height, - int dstx, int dsty ) -{ - XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC); - - if(pDstDrawable->type == DRAWABLE_WINDOW) { - if((pSrcDrawable->type == DRAWABLE_WINDOW) || - IS_OFFSCREEN_PIXMAP(pSrcDrawable)){ - if(infoRec->ScreenToScreenBitBlt && - CHECK_ROP(pGC,infoRec->ScreenToScreenBitBltFlags) && - CHECK_ROPSRC(pGC,infoRec->ScreenToScreenBitBltFlags) && - CHECK_PLANEMASK(pGC,infoRec->ScreenToScreenBitBltFlags)) - return (XAABitBlt( pSrcDrawable, pDstDrawable, - pGC, srcx, srcy, width, height, dstx, dsty, - XAADoBitBlt, 0L)); - } else { - if(infoRec->WritePixmap && - ((pDstDrawable->bitsPerPixel == pSrcDrawable->bitsPerPixel) || - ((pDstDrawable->bitsPerPixel == 24) && - (pSrcDrawable->bitsPerPixel == 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)) - return (XAABitBlt( pSrcDrawable, pDstDrawable, - pGC, srcx, srcy, width, height, dstx, dsty, - XAADoImageWrite, 0L)); - } - } else if(IS_OFFSCREEN_PIXMAP(pDstDrawable)){ - if((pSrcDrawable->type == DRAWABLE_WINDOW) || - IS_OFFSCREEN_PIXMAP(pSrcDrawable)){ - if(infoRec->ScreenToScreenBitBlt && - CHECK_ROP(pGC,infoRec->ScreenToScreenBitBltFlags) && - CHECK_ROPSRC(pGC,infoRec->ScreenToScreenBitBltFlags) && - CHECK_PLANEMASK(pGC,infoRec->ScreenToScreenBitBltFlags)) - return (XAABitBlt( pSrcDrawable, pDstDrawable, - pGC, srcx, srcy, width, height, dstx, dsty, - XAADoBitBlt, 0L)); - } - } - - return (XAAFallbackOps.CopyArea(pSrcDrawable, pDstDrawable, pGC, - srcx, srcy, width, height, dstx, dsty)); -} - - -void -XAADoBitBlt( - DrawablePtr pSrc, - DrawablePtr pDst, - GC *pGC, - RegionPtr prgnDst, - DDXPointPtr pptSrc ) -{ - int nbox, careful; - BoxPtr pbox, pboxTmp, pboxNext, pboxBase, pboxNew1, pboxNew2; - DDXPointPtr pptTmp, pptNew1, pptNew2; - int xdir, ydir; - XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC); - - /* XXX we have to err on the side of safety when both are windows, - * because we don't know if IncludeInferiors is being used. - */ - careful = ((pSrc == pDst) || - ((pSrc->type == DRAWABLE_WINDOW) && - (pDst->type == DRAWABLE_WINDOW))); - - pbox = REGION_RECTS(prgnDst); - nbox = REGION_NUM_RECTS(prgnDst); - - pboxNew1 = NULL; - pptNew1 = NULL; - pboxNew2 = NULL; - pptNew2 = NULL; - if (careful && (pptSrc->y < pbox->y1)) { - /* walk source botttom to top */ - ydir = -1; - - if (nbox > 1) { - /* keep ordering in each band, reverse order of bands */ - pboxNew1 = (BoxPtr)xalloc(sizeof(BoxRec) * nbox); - if(!pboxNew1) - return; - pptNew1 = (DDXPointPtr)xalloc(sizeof(DDXPointRec) * nbox); - if(!pptNew1) { - xfree(pboxNew1); - return; - } - pboxBase = pboxNext = pbox+nbox-1; - while (pboxBase >= pbox) { - while ((pboxNext >= pbox) && - (pboxBase->y1 == pboxNext->y1)) - pboxNext--; - pboxTmp = pboxNext+1; - pptTmp = pptSrc + (pboxTmp - pbox); - while (pboxTmp <= pboxBase) { - *pboxNew1++ = *pboxTmp++; - *pptNew1++ = *pptTmp++; - } - pboxBase = pboxNext; - } - pboxNew1 -= nbox; - pbox = pboxNew1; - pptNew1 -= nbox; - pptSrc = pptNew1; - } - } else { - /* walk source top to bottom */ - ydir = 1; - } - - if (careful && (pptSrc->x < pbox->x1)) { - /* walk source right to left */ - xdir = -1; - - if (nbox > 1) { - /* reverse order of rects in each band */ - pboxNew2 = (BoxPtr)xalloc(sizeof(BoxRec) * nbox); - pptNew2 = (DDXPointPtr)xalloc(sizeof(DDXPointRec) * nbox); - if(!pboxNew2 || !pptNew2) { - if (pptNew2) xfree(pptNew2); - if (pboxNew2) xfree(pboxNew2); - if (pboxNew1) { - xfree(pptNew1); - xfree(pboxNew1); - } - return; - } - pboxBase = pboxNext = pbox; - while (pboxBase < pbox+nbox) { - while ((pboxNext < pbox+nbox) && - (pboxNext->y1 == pboxBase->y1)) - pboxNext++; - pboxTmp = pboxNext; - pptTmp = pptSrc + (pboxTmp - pbox); - while (pboxTmp != pboxBase) { - *pboxNew2++ = *--pboxTmp; - *pptNew2++ = *--pptTmp; - } - pboxBase = pboxNext; - } - pboxNew2 -= nbox; - pbox = pboxNew2; - pptNew2 -= nbox; - pptSrc = pptNew2; - } - } else { - /* walk source left to right */ - xdir = 1; - } - - (*infoRec->ScreenToScreenBitBlt)(infoRec->pScrn, nbox, pptSrc, pbox, - xdir, ydir, pGC->alu, pGC->planemask); - - if (pboxNew2) { - xfree(pptNew2); - xfree(pboxNew2); - } - if (pboxNew1) { - xfree(pptNew1); - xfree(pboxNew1); - } - -} - -void -XAADoImageWrite( - DrawablePtr pSrc, - DrawablePtr pDst, - GC *pGC, - RegionPtr prgnDst, - DDXPointPtr pptSrc ) -{ - int srcwidth; - unsigned char* psrcBase; /* start of image */ - unsigned char* srcPntr; /* index into the image */ - BoxPtr pbox = REGION_RECTS(prgnDst); - int nbox = REGION_NUM_RECTS(prgnDst); - XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC); - int Bpp = pSrc->bitsPerPixel >> 3; - - psrcBase = (unsigned char *)((PixmapPtr)pSrc)->devPrivate.ptr; - srcwidth = (int)((PixmapPtr)pSrc)->devKind; - - for(; nbox; pbox++, pptSrc++, nbox--) { - srcPntr = psrcBase + (pptSrc->y * srcwidth) + (pptSrc->x * Bpp); - - (*infoRec->WritePixmap)(infoRec->pScrn, pbox->x1, pbox->y1, - pbox->x2 - pbox->x1, pbox->y2 - pbox->y1, srcPntr, srcwidth, - pGC->alu, pGC->planemask, -1, pSrc->bitsPerPixel, pSrc->depth); - } -} - - -void -XAADoImageRead( - DrawablePtr pSrc, - DrawablePtr pDst, - GC *pGC, - RegionPtr prgnDst, - DDXPointPtr pptSrc ) -{ - int dstwidth; - unsigned char* pdstBase; /* start of image */ - unsigned char* dstPntr; /* index into the image */ - BoxPtr pbox = REGION_RECTS(prgnDst); - int nbox = REGION_NUM_RECTS(prgnDst); - XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC); - int Bpp = pSrc->bitsPerPixel >> 3; /* wouldn't get here unless both - src and dst have same bpp */ - - pdstBase = (unsigned char *)((PixmapPtr)pDst)->devPrivate.ptr; - dstwidth = (int)((PixmapPtr)pDst)->devKind; - - for(; nbox; pbox++, pptSrc++, nbox--) { - dstPntr = pdstBase + (pbox->y1 * dstwidth) + (pbox->x1 * Bpp); - - (*infoRec->ReadPixmap)(infoRec->pScrn, pptSrc->x, pptSrc->y, - pbox->x2 - pbox->x1, pbox->y2 - pbox->y1, dstPntr, dstwidth, - pSrc->bitsPerPixel, pSrc->depth); - } -} - - -void -XAAScreenToScreenBitBlt( - ScrnInfoPtr pScrn, - int nbox, - DDXPointPtr pptSrc, - BoxPtr pbox, - int xdir, int ydir, - int alu, - unsigned int planemask ) -{ - XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn); - int dirsetup; - - if ((!(infoRec->CopyAreaFlags & ONLY_TWO_BITBLT_DIRECTIONS) - || (xdir == ydir)) && - (!(infoRec->CopyAreaFlags & ONLY_LEFT_TO_RIGHT_BITBLT) - || (xdir == 1))) { - (*infoRec->SetupForScreenToScreenCopy)(pScrn, - xdir, ydir, alu, planemask, -1); - for (; nbox; pbox++, pptSrc++, nbox--) - (*infoRec->SubsequentScreenToScreenCopy)(pScrn,pptSrc->x, pptSrc->y, - pbox->x1, pbox->y1, pbox->x2 - pbox->x1, pbox->y2 - pbox->y1); - SET_SYNC_FLAG(infoRec); - return; - } - - if (infoRec->CopyAreaFlags & ONLY_LEFT_TO_RIGHT_BITBLT) { - /* - * This is the case of a chip that only supports xdir = 1, - * with ydir = 1 or ydir = -1, but we have xdir = -1. - */ - (*infoRec->SetupForScreenToScreenCopy)(pScrn, - 1, ydir, alu, planemask, -1); - for (; nbox; pbox++, pptSrc++, nbox--) - if (pptSrc->y != pbox->y1 || pptSrc->x >= pbox->x1) - /* No problem. Do a xdir = 1 blit instead. */ - (*infoRec->SubsequentScreenToScreenCopy)(pScrn, - pptSrc->x, pptSrc->y, pbox->x1, pbox->y1, - pbox->x2 - pbox->x1, pbox->y2 - pbox->y1); - else - { - /* - * This is the difficult case. Needs striping into - * non-overlapping horizontal chunks. - */ - int stripeWidth, w, fullStripes, extra, i; - stripeWidth = 16; - w = pbox->x2 - pbox->x1; - if (pbox->x1 - pptSrc->x < stripeWidth) - stripeWidth = pbox->x1 - pptSrc->x; - fullStripes = w / stripeWidth; - extra = w % stripeWidth; - - /* First, take care of the little bit on the far right */ - if (extra) - (*infoRec->SubsequentScreenToScreenCopy)(pScrn, - pptSrc->x + fullStripes * stripeWidth, pptSrc->y, - pbox->x1 + fullStripes * stripeWidth, pbox->y1, - extra, pbox->y2 - pbox->y1); - - /* Now, take care of the rest of the blit */ - for (i = fullStripes - 1; i >= 0; i--) - (*infoRec->SubsequentScreenToScreenCopy)(pScrn, - pptSrc->x + i * stripeWidth, pptSrc->y, - pbox->x1 + i * stripeWidth, pbox->y1, - stripeWidth, pbox->y2 - pbox->y1); - } - SET_SYNC_FLAG(infoRec); - return; - } - - /* - * Now the case of a chip that only supports xdir = ydir = 1 or - * xdir = ydir = -1, but we have xdir != ydir. - */ - dirsetup = 0; /* No direction set up yet. */ - for (; nbox; pbox++, pptSrc++, nbox--) { - if (xdir == 1 && pptSrc->y != pbox->y1) { - /* Do a xdir = ydir = -1 blit instead. */ - if (dirsetup != -1) { - (*infoRec->SetupForScreenToScreenCopy)(pScrn, - -1, -1, alu, planemask, -1); - dirsetup = -1; - } - (*infoRec->SubsequentScreenToScreenCopy)(pScrn,pptSrc->x, pptSrc->y, - pbox->x1, pbox->y1, pbox->x2 - pbox->x1, pbox->y2 - pbox->y1); - } - else if (xdir == -1 && pptSrc->y != pbox->y1) { - /* Do a xdir = ydir = 1 blit instead. */ - if (dirsetup != 1) { - (*infoRec->SetupForScreenToScreenCopy)(pScrn, - 1, 1, alu, planemask, -1); - dirsetup = 1; - } - (*infoRec->SubsequentScreenToScreenCopy)(pScrn,pptSrc->x, pptSrc->y, - pbox->x1, pbox->y1, pbox->x2 - pbox->x1, pbox->y2 - pbox->y1); - } - else - if (xdir == 1) { - /* - * xdir = 1, ydir = -1. - * Perform line-by-line xdir = ydir = 1 blits, going up. - */ - int i; - if (dirsetup != 1) { - (*infoRec->SetupForScreenToScreenCopy)(pScrn, - 1, 1, alu, planemask, -1); - dirsetup = 1; - } - for (i = pbox->y2 - pbox->y1 - 1; i >= 0; i--) - (*infoRec->SubsequentScreenToScreenCopy)(pScrn, - pptSrc->x, pptSrc->y + i, pbox->x1, pbox->y1 + i, - pbox->x2 - pbox->x1, 1); - } - else { - /* - * xdir = -1, ydir = 1. - * Perform line-by-line xdir = ydir = -1 blits, going down. - */ - int i; - if (dirsetup != -1) { - (*infoRec->SetupForScreenToScreenCopy)(pScrn, - -1, -1, alu, planemask, -1); - dirsetup = -1; - } - for (i = 0; i < pbox->y2 - pbox->y1; i++) - (*infoRec->SubsequentScreenToScreenCopy)(pScrn, - pptSrc->x, pptSrc->y + i, pbox->x1, pbox->y1 + i, - pbox->x2 - pbox->x1, 1); - } - } /* next box */ - SET_SYNC_FLAG(infoRec); -} +
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_OSproc.h"
+
+#include <X11/X.h>
+#include "scrnintstr.h"
+#include "xf86str.h"
+#include "xaa.h"
+#include "xaalocal.h"
+#include "migc.h"
+#include "gcstruct.h"
+#include "pixmapstr.h"
+
+/*
+ Written mostly by Harm Hanemaayer (H.Hanemaayer@inter.nl.net).
+ */
+
+
+RegionPtr
+XAACopyArea(
+ DrawablePtr pSrcDrawable,
+ DrawablePtr pDstDrawable,
+ GC *pGC,
+ int srcx, int srcy,
+ int width, int height,
+ int dstx, int dsty )
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+
+ if(pDstDrawable->type == DRAWABLE_WINDOW) {
+ if((pSrcDrawable->type == DRAWABLE_WINDOW) ||
+ IS_OFFSCREEN_PIXMAP(pSrcDrawable)){
+ if(infoRec->ScreenToScreenBitBlt &&
+ CHECK_ROP(pGC,infoRec->ScreenToScreenBitBltFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->ScreenToScreenBitBltFlags) &&
+ CHECK_PLANEMASK(pGC,infoRec->ScreenToScreenBitBltFlags))
+ return (XAABitBlt( pSrcDrawable, pDstDrawable,
+ pGC, srcx, srcy, width, height, dstx, dsty,
+ XAADoBitBlt, 0L));
+ } else {
+ if(infoRec->WritePixmap &&
+ ((pDstDrawable->bitsPerPixel == pSrcDrawable->bitsPerPixel) ||
+ ((pDstDrawable->bitsPerPixel == 24) &&
+ (pSrcDrawable->bitsPerPixel == 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))
+ return (XAABitBlt( pSrcDrawable, pDstDrawable,
+ pGC, srcx, srcy, width, height, dstx, dsty,
+ XAADoImageWrite, 0L));
+ }
+ } else if(IS_OFFSCREEN_PIXMAP(pDstDrawable)){
+ if((pSrcDrawable->type == DRAWABLE_WINDOW) ||
+ IS_OFFSCREEN_PIXMAP(pSrcDrawable)){
+ if(infoRec->ScreenToScreenBitBlt &&
+ CHECK_ROP(pGC,infoRec->ScreenToScreenBitBltFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->ScreenToScreenBitBltFlags) &&
+ CHECK_PLANEMASK(pGC,infoRec->ScreenToScreenBitBltFlags))
+ return (XAABitBlt( pSrcDrawable, pDstDrawable,
+ pGC, srcx, srcy, width, height, dstx, dsty,
+ XAADoBitBlt, 0L));
+ }
+ }
+
+ return (XAAFallbackOps.CopyArea(pSrcDrawable, pDstDrawable, pGC,
+ srcx, srcy, width, height, dstx, dsty));
+}
+
+
+void
+XAADoBitBlt(
+ DrawablePtr pSrc,
+ DrawablePtr pDst,
+ GC *pGC,
+ RegionPtr prgnDst,
+ DDXPointPtr pptSrc )
+{
+ int nbox, careful;
+ BoxPtr pbox, pboxTmp, pboxNext, pboxBase, pboxNew1, pboxNew2;
+ DDXPointPtr pptTmp, pptNew1, pptNew2;
+ int xdir, ydir;
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+
+ /* XXX we have to err on the side of safety when both are windows,
+ * because we don't know if IncludeInferiors is being used.
+ */
+ careful = ((pSrc == pDst) ||
+ ((pSrc->type == DRAWABLE_WINDOW) &&
+ (pDst->type == DRAWABLE_WINDOW)));
+
+ pbox = REGION_RECTS(prgnDst);
+ nbox = REGION_NUM_RECTS(prgnDst);
+
+ pboxNew1 = NULL;
+ pptNew1 = NULL;
+ pboxNew2 = NULL;
+ pptNew2 = NULL;
+ if (careful && (pptSrc->y < pbox->y1)) {
+ /* walk source botttom to top */
+ ydir = -1;
+
+ if (nbox > 1) {
+ /* keep ordering in each band, reverse order of bands */
+ pboxNew1 = (BoxPtr)malloc(sizeof(BoxRec) * nbox);
+ if(!pboxNew1)
+ return;
+ pptNew1 = (DDXPointPtr)malloc(sizeof(DDXPointRec) * nbox);
+ if(!pptNew1) {
+ free(pboxNew1);
+ return;
+ }
+ pboxBase = pboxNext = pbox+nbox-1;
+ while (pboxBase >= pbox) {
+ while ((pboxNext >= pbox) &&
+ (pboxBase->y1 == pboxNext->y1))
+ pboxNext--;
+ pboxTmp = pboxNext+1;
+ pptTmp = pptSrc + (pboxTmp - pbox);
+ while (pboxTmp <= pboxBase) {
+ *pboxNew1++ = *pboxTmp++;
+ *pptNew1++ = *pptTmp++;
+ }
+ pboxBase = pboxNext;
+ }
+ pboxNew1 -= nbox;
+ pbox = pboxNew1;
+ pptNew1 -= nbox;
+ pptSrc = pptNew1;
+ }
+ } else {
+ /* walk source top to bottom */
+ ydir = 1;
+ }
+
+ if (careful && (pptSrc->x < pbox->x1)) {
+ /* walk source right to left */
+ xdir = -1;
+
+ if (nbox > 1) {
+ /* reverse order of rects in each band */
+ pboxNew2 = (BoxPtr)malloc(sizeof(BoxRec) * nbox);
+ pptNew2 = (DDXPointPtr)malloc(sizeof(DDXPointRec) * nbox);
+ if(!pboxNew2 || !pptNew2) {
+ if (pptNew2) free(pptNew2);
+ if (pboxNew2) free(pboxNew2);
+ if (pboxNew1) {
+ free(pptNew1);
+ free(pboxNew1);
+ }
+ return;
+ }
+ pboxBase = pboxNext = pbox;
+ while (pboxBase < pbox+nbox) {
+ while ((pboxNext < pbox+nbox) &&
+ (pboxNext->y1 == pboxBase->y1))
+ pboxNext++;
+ pboxTmp = pboxNext;
+ pptTmp = pptSrc + (pboxTmp - pbox);
+ while (pboxTmp != pboxBase) {
+ *pboxNew2++ = *--pboxTmp;
+ *pptNew2++ = *--pptTmp;
+ }
+ pboxBase = pboxNext;
+ }
+ pboxNew2 -= nbox;
+ pbox = pboxNew2;
+ pptNew2 -= nbox;
+ pptSrc = pptNew2;
+ }
+ } else {
+ /* walk source left to right */
+ xdir = 1;
+ }
+
+ (*infoRec->ScreenToScreenBitBlt)(infoRec->pScrn, nbox, pptSrc, pbox,
+ xdir, ydir, pGC->alu, pGC->planemask);
+
+ if (pboxNew2) {
+ free(pptNew2);
+ free(pboxNew2);
+ }
+ if (pboxNew1) {
+ free(pptNew1);
+ free(pboxNew1);
+ }
+
+}
+
+void
+XAADoImageWrite(
+ DrawablePtr pSrc,
+ DrawablePtr pDst,
+ GC *pGC,
+ RegionPtr prgnDst,
+ DDXPointPtr pptSrc )
+{
+ int srcwidth;
+ unsigned char* psrcBase; /* start of image */
+ unsigned char* srcPntr; /* index into the image */
+ BoxPtr pbox = REGION_RECTS(prgnDst);
+ int nbox = REGION_NUM_RECTS(prgnDst);
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ int Bpp = pSrc->bitsPerPixel >> 3;
+
+ psrcBase = (unsigned char *)((PixmapPtr)pSrc)->devPrivate.ptr;
+ srcwidth = (int)((PixmapPtr)pSrc)->devKind;
+
+ for(; nbox; pbox++, pptSrc++, nbox--) {
+ srcPntr = psrcBase + (pptSrc->y * srcwidth) + (pptSrc->x * Bpp);
+
+ (*infoRec->WritePixmap)(infoRec->pScrn, pbox->x1, pbox->y1,
+ pbox->x2 - pbox->x1, pbox->y2 - pbox->y1, srcPntr, srcwidth,
+ pGC->alu, pGC->planemask, -1, pSrc->bitsPerPixel, pSrc->depth);
+ }
+}
+
+
+void
+XAADoImageRead(
+ DrawablePtr pSrc,
+ DrawablePtr pDst,
+ GC *pGC,
+ RegionPtr prgnDst,
+ DDXPointPtr pptSrc )
+{
+ int dstwidth;
+ unsigned char* pdstBase; /* start of image */
+ unsigned char* dstPntr; /* index into the image */
+ BoxPtr pbox = REGION_RECTS(prgnDst);
+ int nbox = REGION_NUM_RECTS(prgnDst);
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ int Bpp = pSrc->bitsPerPixel >> 3; /* wouldn't get here unless both
+ src and dst have same bpp */
+
+ pdstBase = (unsigned char *)((PixmapPtr)pDst)->devPrivate.ptr;
+ dstwidth = (int)((PixmapPtr)pDst)->devKind;
+
+ for(; nbox; pbox++, pptSrc++, nbox--) {
+ dstPntr = pdstBase + (pbox->y1 * dstwidth) + (pbox->x1 * Bpp);
+
+ (*infoRec->ReadPixmap)(infoRec->pScrn, pptSrc->x, pptSrc->y,
+ pbox->x2 - pbox->x1, pbox->y2 - pbox->y1, dstPntr, dstwidth,
+ pSrc->bitsPerPixel, pSrc->depth);
+ }
+}
+
+
+void
+XAAScreenToScreenBitBlt(
+ ScrnInfoPtr pScrn,
+ int nbox,
+ DDXPointPtr pptSrc,
+ BoxPtr pbox,
+ int xdir, int ydir,
+ int alu,
+ unsigned int planemask )
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ int dirsetup;
+
+ if ((!(infoRec->CopyAreaFlags & ONLY_TWO_BITBLT_DIRECTIONS)
+ || (xdir == ydir)) &&
+ (!(infoRec->CopyAreaFlags & ONLY_LEFT_TO_RIGHT_BITBLT)
+ || (xdir == 1))) {
+ (*infoRec->SetupForScreenToScreenCopy)(pScrn,
+ xdir, ydir, alu, planemask, -1);
+ for (; nbox; pbox++, pptSrc++, nbox--)
+ (*infoRec->SubsequentScreenToScreenCopy)(pScrn,pptSrc->x, pptSrc->y,
+ pbox->x1, pbox->y1, pbox->x2 - pbox->x1, pbox->y2 - pbox->y1);
+ SET_SYNC_FLAG(infoRec);
+ return;
+ }
+
+ if (infoRec->CopyAreaFlags & ONLY_LEFT_TO_RIGHT_BITBLT) {
+ /*
+ * This is the case of a chip that only supports xdir = 1,
+ * with ydir = 1 or ydir = -1, but we have xdir = -1.
+ */
+ (*infoRec->SetupForScreenToScreenCopy)(pScrn,
+ 1, ydir, alu, planemask, -1);
+ for (; nbox; pbox++, pptSrc++, nbox--)
+ if (pptSrc->y != pbox->y1 || pptSrc->x >= pbox->x1)
+ /* No problem. Do a xdir = 1 blit instead. */
+ (*infoRec->SubsequentScreenToScreenCopy)(pScrn,
+ pptSrc->x, pptSrc->y, pbox->x1, pbox->y1,
+ pbox->x2 - pbox->x1, pbox->y2 - pbox->y1);
+ else
+ {
+ /*
+ * This is the difficult case. Needs striping into
+ * non-overlapping horizontal chunks.
+ */
+ int stripeWidth, w, fullStripes, extra, i;
+ stripeWidth = 16;
+ w = pbox->x2 - pbox->x1;
+ if (pbox->x1 - pptSrc->x < stripeWidth)
+ stripeWidth = pbox->x1 - pptSrc->x;
+ fullStripes = w / stripeWidth;
+ extra = w % stripeWidth;
+
+ /* First, take care of the little bit on the far right */
+ if (extra)
+ (*infoRec->SubsequentScreenToScreenCopy)(pScrn,
+ pptSrc->x + fullStripes * stripeWidth, pptSrc->y,
+ pbox->x1 + fullStripes * stripeWidth, pbox->y1,
+ extra, pbox->y2 - pbox->y1);
+
+ /* Now, take care of the rest of the blit */
+ for (i = fullStripes - 1; i >= 0; i--)
+ (*infoRec->SubsequentScreenToScreenCopy)(pScrn,
+ pptSrc->x + i * stripeWidth, pptSrc->y,
+ pbox->x1 + i * stripeWidth, pbox->y1,
+ stripeWidth, pbox->y2 - pbox->y1);
+ }
+ SET_SYNC_FLAG(infoRec);
+ return;
+ }
+
+ /*
+ * Now the case of a chip that only supports xdir = ydir = 1 or
+ * xdir = ydir = -1, but we have xdir != ydir.
+ */
+ dirsetup = 0; /* No direction set up yet. */
+ for (; nbox; pbox++, pptSrc++, nbox--) {
+ if (xdir == 1 && pptSrc->y != pbox->y1) {
+ /* Do a xdir = ydir = -1 blit instead. */
+ if (dirsetup != -1) {
+ (*infoRec->SetupForScreenToScreenCopy)(pScrn,
+ -1, -1, alu, planemask, -1);
+ dirsetup = -1;
+ }
+ (*infoRec->SubsequentScreenToScreenCopy)(pScrn,pptSrc->x, pptSrc->y,
+ pbox->x1, pbox->y1, pbox->x2 - pbox->x1, pbox->y2 - pbox->y1);
+ }
+ else if (xdir == -1 && pptSrc->y != pbox->y1) {
+ /* Do a xdir = ydir = 1 blit instead. */
+ if (dirsetup != 1) {
+ (*infoRec->SetupForScreenToScreenCopy)(pScrn,
+ 1, 1, alu, planemask, -1);
+ dirsetup = 1;
+ }
+ (*infoRec->SubsequentScreenToScreenCopy)(pScrn,pptSrc->x, pptSrc->y,
+ pbox->x1, pbox->y1, pbox->x2 - pbox->x1, pbox->y2 - pbox->y1);
+ }
+ else
+ if (xdir == 1) {
+ /*
+ * xdir = 1, ydir = -1.
+ * Perform line-by-line xdir = ydir = 1 blits, going up.
+ */
+ int i;
+ if (dirsetup != 1) {
+ (*infoRec->SetupForScreenToScreenCopy)(pScrn,
+ 1, 1, alu, planemask, -1);
+ dirsetup = 1;
+ }
+ for (i = pbox->y2 - pbox->y1 - 1; i >= 0; i--)
+ (*infoRec->SubsequentScreenToScreenCopy)(pScrn,
+ pptSrc->x, pptSrc->y + i, pbox->x1, pbox->y1 + i,
+ pbox->x2 - pbox->x1, 1);
+ }
+ else {
+ /*
+ * xdir = -1, ydir = 1.
+ * Perform line-by-line xdir = ydir = -1 blits, going down.
+ */
+ int i;
+ if (dirsetup != -1) {
+ (*infoRec->SetupForScreenToScreenCopy)(pScrn,
+ -1, -1, alu, planemask, -1);
+ dirsetup = -1;
+ }
+ for (i = 0; i < pbox->y2 - pbox->y1; i++)
+ (*infoRec->SubsequentScreenToScreenCopy)(pScrn,
+ pptSrc->x, pptSrc->y + i, pbox->x1, pbox->y1 + i,
+ pbox->x2 - pbox->x1, 1);
+ }
+ } /* next box */
+ SET_SYNC_FLAG(infoRec);
+}
|