EXA: exaGetImage improvements.

Use the new migration infrastructure to cache FB bits we need in the system
copy, for the benefit of repeated calls.
This commit is contained in:
Michel Dänzer 2007-08-30 13:54:18 +02:00
parent aa2ed73e0e
commit ea92ea4156
3 changed files with 37 additions and 33 deletions

View File

@ -1247,22 +1247,43 @@ exaPaintWindow(WindowPtr pWin, RegionPtr pRegion, int what)
* Accelerates GetImage for solid ZPixmap downloads from framebuffer memory.
*
* This is probably the only case we actually care about. The rest fall through
* to migration and ExaCheckGetImage, which hopefully will result in migration
* pushing the pixmap out of framebuffer.
* to migration and fbGetImage, which hopefully will result in migration pushing
* the pixmap out of framebuffer.
*/
void
exaGetImage (DrawablePtr pDrawable, int x, int y, int w, int h,
unsigned int format, unsigned long planeMask, char *d)
{
ExaScreenPriv (pDrawable->pScreen);
ExaMigrationRec pixmaps[1];
BoxRec Box;
RegionRec Reg;
PixmapPtr pPix;
int xoff, yoff;
Bool ok;
if (pExaScr->swappedOut || (w == 1 && h == 1))
if (pExaScr->swappedOut)
goto fallback;
if (pExaScr->info->DownloadFromScreen == NULL)
pixmaps[0].as_dst = FALSE;
pixmaps[0].as_src = TRUE;
pixmaps[0].pPix = pPix = exaGetDrawablePixmap (pDrawable);
pixmaps[0].pReg = &Reg;
exaGetDrawableDeltas (pDrawable, pPix, &xoff, &yoff);
Box.x1 = pDrawable->y + x + xoff;
Box.y1 = pDrawable->y + y + yoff;
Box.x2 = Box.x1 + w;
Box.y2 = Box.y1 + h;
REGION_INIT(pScreen, &Reg, &Box, 1);
exaDoMigration(pixmaps, 1, FALSE);
pPix = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff);
if (pPix == NULL || pExaScr->info->DownloadFromScreen == NULL)
goto fallback;
/* Only cover the ZPixmap, solid copy case. */
@ -1275,20 +1296,22 @@ exaGetImage (DrawablePtr pDrawable, int x, int y, int w, int h,
if (pDrawable->bitsPerPixel < 8)
goto fallback;
pPix = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff);
if (pPix == NULL)
goto fallback;
xoff += pDrawable->x;
yoff += pDrawable->y;
ok = pExaScr->info->DownloadFromScreen(pPix, x + xoff, y + yoff, w, h, d,
ok = pExaScr->info->DownloadFromScreen(pPix, pDrawable->x + x + xoff,
pDrawable->y + y + yoff, w, h, d,
PixmapBytePad(w, pDrawable->depth));
if (ok) {
exaWaitSync(pDrawable->pScreen);
return;
goto out;
}
fallback:
ExaCheckGetImage (pDrawable, x, y, w, h, format, planeMask, d);
EXA_FALLBACK(("from %p (%c)\n", pDrawable,
exaDrawableLocation(pDrawable)));
exaPrepareAccessReg (pDrawable, EXA_PREPARE_SRC, &Reg);
fbGetImage (pDrawable, x, y, w, h, format, planeMask, d);
exaFinishAccess (pDrawable, EXA_PREPARE_SRC);
out:
REGION_UNINIT(pScreen, &Reg);
}

View File

@ -264,12 +264,6 @@ ExaCheckPushPixels (GCPtr pGC, PixmapPtr pBitmap,
DrawablePtr pDrawable,
int w, int h, int x, int y);
void
ExaCheckGetImage (DrawablePtr pDrawable,
int x, int y, int w, int h,
unsigned int format, unsigned long planeMask,
char *d);
void
ExaCheckGetSpans (DrawablePtr pDrawable,
int wMax,

View File

@ -264,19 +264,6 @@ ExaCheckPushPixels (GCPtr pGC, PixmapPtr pBitmap,
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
}
void
ExaCheckGetImage (DrawablePtr pDrawable,
int x, int y, int w, int h,
unsigned int format, unsigned long planeMask,
char *d)
{
EXA_FALLBACK(("from %p (%c)\n", pDrawable,
exaDrawableLocation(pDrawable)));
exaPrepareAccess (pDrawable, EXA_PREPARE_SRC);
fbGetImage (pDrawable, x, y, w, h, format, planeMask, d);
exaFinishAccess (pDrawable, EXA_PREPARE_SRC);
}
void
ExaCheckGetSpans (DrawablePtr pDrawable,
int wMax,