Accumulate graphics exposures incrementally in PanoramiXCopyArea/Plane.

This fuses two loops in each function, eliminating an intermediate
MAXSCREENS-sized array from each.

Aside from being more efficient, I believe this is equivalent to the
previous implementation, since
- each per-screen GC has the graphicsExposures flag set the same way,
  and
- the REGION_* macros ignore their screen argument.

Signed-off-by: Jamey Sharp <jamey@minilop.net>
Reviewed-by: Keith Packard <keithp@keithp.com>
Reviewed-by: Tiago Vignatti <tiago.vignatti@nokia.com>
Tested-by: Tiago Vignatti <tiago.vignatti@nokia.com> (i686 GNU/Linux)
This commit is contained in:
Jamey Sharp 2010-04-23 19:33:49 -07:00
parent a7c7ebe4b3
commit f114f54986

View File

@ -1084,10 +1084,12 @@ int PanoramiXCopyArea(ClientPtr client)
} else { } else {
DrawablePtr pDst = NULL, pSrc = NULL; DrawablePtr pDst = NULL, pSrc = NULL;
GCPtr pGC = NULL; GCPtr pGC = NULL;
RegionPtr pRgn[MAXSCREENS]; RegionRec totalReg;
int rc; int rc;
REGION_NULL(unusedScreen, &totalReg);
FOR_NSCREENS_BACKWARD(j) { FOR_NSCREENS_BACKWARD(j) {
RegionPtr pRgn;
stuff->dstDrawable = dst->info[j].id; stuff->dstDrawable = dst->info[j].id;
stuff->srcDrawable = src->info[j].id; stuff->srcDrawable = src->info[j].id;
stuff->gc = gc->info[j].id; stuff->gc = gc->info[j].id;
@ -1116,37 +1118,30 @@ int PanoramiXCopyArea(ClientPtr client)
} else } else
pSrc = pDst; pSrc = pDst;
pRgn[j] = (*pGC->ops->CopyArea)(pSrc, pDst, pGC, pRgn = (*pGC->ops->CopyArea)(pSrc, pDst, pGC,
stuff->srcX, stuff->srcY, stuff->srcX, stuff->srcY,
stuff->width, stuff->height, stuff->width, stuff->height,
stuff->dstX, stuff->dstY); stuff->dstX, stuff->dstY);
if(pGC->graphicsExposures && pRgn) {
if(dstShared) { if(srcIsRoot) {
while(j--) pRgn[j] = NULL; REGION_TRANSLATE(unusedScreen, pRgn,
break; screenInfo.screens[j]->x, screenInfo.screens[j]->y);
}
REGION_APPEND(unusedScreen, &totalReg, pRgn);
REGION_DESTROY(unusedScreen, pRgn);
} }
if(dstShared)
break;
} }
if(pGC->graphicsExposures) { if(pGC->graphicsExposures) {
ScreenPtr pScreen = pDst->pScreen; ScreenPtr pScreen = pDst->pScreen;
RegionRec totalReg;
Bool overlap; Bool overlap;
REGION_VALIDATE(unusedScreen, &totalReg, &overlap);
REGION_NULL(pScreen, &totalReg);
FOR_NSCREENS_BACKWARD(j) {
if(pRgn[j]) {
if(srcIsRoot) {
REGION_TRANSLATE(pScreen, pRgn[j],
screenInfo.screens[j]->x, screenInfo.screens[j]->y);
}
REGION_APPEND(pScreen, &totalReg, pRgn[j]);
REGION_DESTROY(pScreen, pRgn[j]);
}
}
REGION_VALIDATE(pScreen, &totalReg, &overlap);
(*pScreen->SendGraphicsExpose)( (*pScreen->SendGraphicsExpose)(
client, &totalReg, stuff->dstDrawable, X_CopyArea, 0); client, &totalReg, stuff->dstDrawable, X_CopyArea, 0);
REGION_UNINIT(pScreen, &totalReg); REGION_UNINIT(unusedScreen, &totalReg);
} }
} }
@ -1163,7 +1158,7 @@ int PanoramiXCopyPlane(ClientPtr client)
Bool srcShared, dstShared; Bool srcShared, dstShared;
DrawablePtr psrcDraw, pdstDraw = NULL; DrawablePtr psrcDraw, pdstDraw = NULL;
GCPtr pGC = NULL; GCPtr pGC = NULL;
RegionPtr pRgn[MAXSCREENS]; RegionRec totalReg;
REQUEST(xCopyPlaneReq); REQUEST(xCopyPlaneReq);
REQUEST_SIZE_MATCH(xCopyPlaneReq); REQUEST_SIZE_MATCH(xCopyPlaneReq);
@ -1198,7 +1193,9 @@ int PanoramiXCopyPlane(ClientPtr client)
srcx = stuff->srcX; srcy = stuff->srcY; srcx = stuff->srcX; srcy = stuff->srcY;
dstx = stuff->dstX; dsty = stuff->dstY; dstx = stuff->dstX; dsty = stuff->dstY;
REGION_NULL(unusedScreen, &totalReg);
FOR_NSCREENS_BACKWARD(j) { FOR_NSCREENS_BACKWARD(j) {
RegionPtr pRgn;
stuff->dstDrawable = dst->info[j].id; stuff->dstDrawable = dst->info[j].id;
stuff->srcDrawable = src->info[j].id; stuff->srcDrawable = src->info[j].id;
stuff->gc = gc->info[j].id; stuff->gc = gc->info[j].id;
@ -1231,33 +1228,26 @@ int PanoramiXCopyPlane(ClientPtr client)
return(BadValue); return(BadValue);
} }
pRgn[j] = (*pGC->ops->CopyPlane)(psrcDraw, pdstDraw, pGC, pRgn = (*pGC->ops->CopyPlane)(psrcDraw, pdstDraw, pGC,
stuff->srcX, stuff->srcY, stuff->srcX, stuff->srcY,
stuff->width, stuff->height, stuff->width, stuff->height,
stuff->dstX, stuff->dstY, stuff->bitPlane); stuff->dstX, stuff->dstY, stuff->bitPlane);
if(pGC->graphicsExposures && pRgn) {
if(dstShared) { REGION_APPEND(unusedScreen, &totalReg, pRgn);
while(j--) pRgn[j] = NULL; REGION_DESTROY(unusedScreen, pRgn);
break;
} }
if(dstShared)
break;
} }
if(pGC->graphicsExposures) { if(pGC->graphicsExposures) {
ScreenPtr pScreen = pdstDraw->pScreen; ScreenPtr pScreen = pdstDraw->pScreen;
RegionRec totalReg;
Bool overlap; Bool overlap;
REGION_VALIDATE(unusedScreen, &totalReg, &overlap);
REGION_NULL(pScreen, &totalReg);
FOR_NSCREENS_BACKWARD(j) {
if(pRgn[j]) {
REGION_APPEND(pScreen, &totalReg, pRgn[j]);
REGION_DESTROY(pScreen, pRgn[j]);
}
}
REGION_VALIDATE(pScreen, &totalReg, &overlap);
(*pScreen->SendGraphicsExpose)( (*pScreen->SendGraphicsExpose)(
client, &totalReg, stuff->dstDrawable, X_CopyPlane, 0); client, &totalReg, stuff->dstDrawable, X_CopyPlane, 0);
REGION_UNINIT(pScreen, &totalReg); REGION_UNINIT(unusedScreen, &totalReg);
} }
return Success; return Success;