1706f2543Smrg 2706f2543Smrg/* 3706f2543Smrg This is a lighter version of cfbBitBlt. We calculate the boxes 4706f2543Smrg when accelerating pixmap->screen and screen->screen copies. 5706f2543Smrg We also pass the GC to the doBitBlt function so that it has access 6706f2543Smrg to the fg and bg so CopyPlane can use this. 7706f2543Smrg*/ 8706f2543Smrg 9706f2543Smrg#ifdef HAVE_XORG_CONFIG_H 10706f2543Smrg#include <xorg-config.h> 11706f2543Smrg#endif 12706f2543Smrg 13706f2543Smrg#include "misc.h" 14706f2543Smrg#include "xf86.h" 15706f2543Smrg#include "xf86_OSproc.h" 16706f2543Smrg 17706f2543Smrg#include <X11/X.h> 18706f2543Smrg#include "mi.h" 19706f2543Smrg#include "pixmapstr.h" 20706f2543Smrg#include "gcstruct.h" 21706f2543Smrg#include "windowstr.h" 22706f2543Smrg#include "xaalocal.h" 23706f2543Smrg 24706f2543Smrg 25706f2543SmrgRegionPtr 26706f2543SmrgXAABitBlt( 27706f2543Smrg DrawablePtr pSrcDrawable, 28706f2543Smrg DrawablePtr pDstDrawable, 29706f2543Smrg GC *pGC, 30706f2543Smrg int srcx, int srcy, 31706f2543Smrg int width, int height, 32706f2543Smrg int dstx, int dsty, 33706f2543Smrg void (*doBitBlt)(DrawablePtr, DrawablePtr, GCPtr, RegionPtr, DDXPointPtr), 34706f2543Smrg unsigned long bitPlane ) 35706f2543Smrg{ 36706f2543Smrg 37706f2543Smrg RegionPtr prgnSrcClip = NULL; /* may be a new region, or just a copy */ 38706f2543Smrg RegionPtr prgnExposed; 39706f2543Smrg Bool freeSrcClip = FALSE; 40706f2543Smrg RegionRec rgnDst; 41706f2543Smrg DDXPointPtr pptSrc, ppt; 42706f2543Smrg DDXPointRec origDest; 43706f2543Smrg BoxPtr pbox; 44706f2543Smrg BoxRec fastBox; 45706f2543Smrg int i, dx, dy, numRects; 46706f2543Smrg xRectangle origSource; 47706f2543Smrg int fastClip = 0; /* for fast clipping with pixmap source */ 48706f2543Smrg int fastExpose = 0; /* for fast exposures with pixmap source */ 49706f2543Smrg 50706f2543Smrg origSource.x = srcx; 51706f2543Smrg origSource.y = srcy; 52706f2543Smrg origSource.width = width; 53706f2543Smrg origSource.height = height; 54706f2543Smrg origDest.x = dstx; 55706f2543Smrg origDest.y = dsty; 56706f2543Smrg 57706f2543Smrg if (pSrcDrawable->pScreen->SourceValidate) { 58706f2543Smrg (*pSrcDrawable->pScreen->SourceValidate) ( 59706f2543Smrg pSrcDrawable, srcx, srcy, width, height, 60706f2543Smrg pGC->subWindowMode); 61706f2543Smrg } 62706f2543Smrg 63706f2543Smrg srcx += pSrcDrawable->x; 64706f2543Smrg srcy += pSrcDrawable->y; 65706f2543Smrg 66706f2543Smrg /* clip the source */ 67706f2543Smrg if (pSrcDrawable->type == DRAWABLE_PIXMAP) { 68706f2543Smrg if ((pSrcDrawable == pDstDrawable) && (pGC->clientClipType == CT_NONE)) 69706f2543Smrg prgnSrcClip = pGC->pCompositeClip; 70706f2543Smrg else 71706f2543Smrg fastClip = 1; 72706f2543Smrg } else { /* Window */ 73706f2543Smrg if (pGC->subWindowMode == IncludeInferiors) { 74706f2543Smrg if (!((WindowPtr) pSrcDrawable)->parent) { 75706f2543Smrg /* 76706f2543Smrg * special case bitblt from root window in 77706f2543Smrg * IncludeInferiors mode; just like from a pixmap 78706f2543Smrg */ 79706f2543Smrg fastClip = 1; 80706f2543Smrg } else if ((pSrcDrawable == pDstDrawable) && 81706f2543Smrg (pGC->clientClipType == CT_NONE)) { 82706f2543Smrg prgnSrcClip = pGC->pCompositeClip; 83706f2543Smrg } else { 84706f2543Smrg prgnSrcClip = NotClippedByChildren((WindowPtr)pSrcDrawable); 85706f2543Smrg freeSrcClip = TRUE; 86706f2543Smrg } 87706f2543Smrg } else { 88706f2543Smrg prgnSrcClip = &((WindowPtr)pSrcDrawable)->clipList; 89706f2543Smrg } 90706f2543Smrg } 91706f2543Smrg 92706f2543Smrg fastBox.x1 = srcx; 93706f2543Smrg fastBox.y1 = srcy; 94706f2543Smrg fastBox.x2 = srcx + width; 95706f2543Smrg fastBox.y2 = srcy + height; 96706f2543Smrg 97706f2543Smrg /* Don't create a source region if we are doing a fast clip */ 98706f2543Smrg if (fastClip) { 99706f2543Smrg fastExpose = 1; 100706f2543Smrg /* 101706f2543Smrg * clip the source; if regions extend beyond the source size, 102706f2543Smrg * make sure exposure events get sent 103706f2543Smrg */ 104706f2543Smrg if (fastBox.x1 < pSrcDrawable->x) { 105706f2543Smrg fastBox.x1 = pSrcDrawable->x; 106706f2543Smrg fastExpose = 0; 107706f2543Smrg } 108706f2543Smrg if (fastBox.y1 < pSrcDrawable->y) { 109706f2543Smrg fastBox.y1 = pSrcDrawable->y; 110706f2543Smrg fastExpose = 0; 111706f2543Smrg } 112706f2543Smrg if (fastBox.x2 > pSrcDrawable->x + (int) pSrcDrawable->width) { 113706f2543Smrg fastBox.x2 = pSrcDrawable->x + (int) pSrcDrawable->width; 114706f2543Smrg fastExpose = 0; 115706f2543Smrg } 116706f2543Smrg if (fastBox.y2 > pSrcDrawable->y + (int) pSrcDrawable->height) { 117706f2543Smrg fastBox.y2 = pSrcDrawable->y + (int) pSrcDrawable->height; 118706f2543Smrg fastExpose = 0; 119706f2543Smrg } 120706f2543Smrg } else { 121706f2543Smrg RegionInit(&rgnDst, &fastBox, 1); 122706f2543Smrg RegionIntersect(&rgnDst, &rgnDst, prgnSrcClip); 123706f2543Smrg } 124706f2543Smrg 125706f2543Smrg dstx += pDstDrawable->x; 126706f2543Smrg dsty += pDstDrawable->y; 127706f2543Smrg 128706f2543Smrg if (pDstDrawable->type == DRAWABLE_WINDOW) { 129706f2543Smrg if (!((WindowPtr)pDstDrawable)->realized) { 130706f2543Smrg if (!fastClip) 131706f2543Smrg RegionUninit(&rgnDst); 132706f2543Smrg if (freeSrcClip) 133706f2543Smrg RegionDestroy(prgnSrcClip); 134706f2543Smrg return NULL; 135706f2543Smrg } 136706f2543Smrg } 137706f2543Smrg 138706f2543Smrg dx = srcx - dstx; 139706f2543Smrg dy = srcy - dsty; 140706f2543Smrg 141706f2543Smrg /* Translate and clip the dst to the destination composite clip */ 142706f2543Smrg if (fastClip) { 143706f2543Smrg RegionPtr cclip; 144706f2543Smrg 145706f2543Smrg /* Translate the region directly */ 146706f2543Smrg fastBox.x1 -= dx; 147706f2543Smrg fastBox.x2 -= dx; 148706f2543Smrg fastBox.y1 -= dy; 149706f2543Smrg fastBox.y2 -= dy; 150706f2543Smrg 151706f2543Smrg /* If the destination composite clip is one rectangle we can 152706f2543Smrg do the clip directly. Otherwise we have to create a full 153706f2543Smrg blown region and call intersect */ 154706f2543Smrg 155706f2543Smrg cclip = pGC->pCompositeClip; 156706f2543Smrg if (RegionNumRects(cclip) == 1) { 157706f2543Smrg BoxPtr pBox = RegionRects(cclip); 158706f2543Smrg 159706f2543Smrg if (fastBox.x1 < pBox->x1) fastBox.x1 = pBox->x1; 160706f2543Smrg if (fastBox.x2 > pBox->x2) fastBox.x2 = pBox->x2; 161706f2543Smrg if (fastBox.y1 < pBox->y1) fastBox.y1 = pBox->y1; 162706f2543Smrg if (fastBox.y2 > pBox->y2) fastBox.y2 = pBox->y2; 163706f2543Smrg 164706f2543Smrg /* Check to see if the region is empty */ 165706f2543Smrg if (fastBox.x1 >= fastBox.x2 || fastBox.y1 >= fastBox.y2) { 166706f2543Smrg RegionNull(&rgnDst); 167706f2543Smrg } else { 168706f2543Smrg RegionInit(&rgnDst, &fastBox, 1); 169706f2543Smrg } 170706f2543Smrg } else { 171706f2543Smrg /* We must turn off fastClip now, since we must create 172706f2543Smrg a full blown region. It is intersected with the 173706f2543Smrg composite clip below. */ 174706f2543Smrg fastClip = 0; 175706f2543Smrg RegionInit(&rgnDst, &fastBox,1); 176706f2543Smrg } 177706f2543Smrg } else { 178706f2543Smrg RegionTranslate(&rgnDst, -dx, -dy); 179706f2543Smrg } 180706f2543Smrg 181706f2543Smrg if (!fastClip) { 182706f2543Smrg RegionIntersect(&rgnDst, &rgnDst, 183706f2543Smrg pGC->pCompositeClip); 184706f2543Smrg } 185706f2543Smrg 186706f2543Smrg /* Do bit blitting */ 187706f2543Smrg numRects = RegionNumRects(&rgnDst); 188706f2543Smrg if (numRects && width && height) { 189706f2543Smrg if(!(pptSrc = (DDXPointPtr)malloc(numRects * 190706f2543Smrg sizeof(DDXPointRec)))) { 191706f2543Smrg RegionUninit(&rgnDst); 192706f2543Smrg if (freeSrcClip) 193706f2543Smrg RegionDestroy(prgnSrcClip); 194706f2543Smrg return NULL; 195706f2543Smrg } 196706f2543Smrg pbox = RegionRects(&rgnDst); 197706f2543Smrg ppt = pptSrc; 198706f2543Smrg for (i = numRects; --i >= 0; pbox++, ppt++) { 199706f2543Smrg ppt->x = pbox->x1 + dx; 200706f2543Smrg ppt->y = pbox->y1 + dy; 201706f2543Smrg } 202706f2543Smrg 203706f2543Smrg (*doBitBlt) (pSrcDrawable, pDstDrawable, pGC, &rgnDst, pptSrc); 204706f2543Smrg free(pptSrc); 205706f2543Smrg } 206706f2543Smrg 207706f2543Smrg prgnExposed = NULL; 208706f2543Smrg if (pGC->fExpose) { 209706f2543Smrg /* Pixmap sources generate a NoExposed (we return NULL to do this) */ 210706f2543Smrg if (!fastExpose) 211706f2543Smrg prgnExposed = miHandleExposures(pSrcDrawable, pDstDrawable, pGC, 212706f2543Smrg origSource.x, origSource.y, 213706f2543Smrg (int)origSource.width, 214706f2543Smrg (int)origSource.height, 215706f2543Smrg origDest.x, origDest.y, bitPlane); 216706f2543Smrg } 217706f2543Smrg RegionUninit(&rgnDst); 218706f2543Smrg if (freeSrcClip) 219706f2543Smrg RegionDestroy(prgnSrcClip); 220706f2543Smrg return prgnExposed; 221706f2543Smrg} 222