Bug #2986: Add acceleration of GetImage using DownloadFromScreen for the

ZPixmap, planeMask ~= FB_ALLONES, bitsPerPixel >= 8 case. I'm pretty
    convinced that this is the only case that we care about at all. Tested
    with xwd -root and xwd on a gnome-terminal, in a composited environment
    or not.
This commit is contained in:
Eric Anholt 2006-03-29 22:25:17 +00:00
parent 4bb5ab0b44
commit e799dd68e2
3 changed files with 63 additions and 2 deletions

View File

@ -1,3 +1,13 @@
2006-03-29 Eric Anholt <anholt@FreeBSD.org>
* exa/exa_accel.c: (exaGetImage):
* exa/exa_priv.h:
Bug #2986: Add acceleration of GetImage using DownloadFromScreen for the
ZPixmap, planeMask ~= FB_ALLONES, bitsPerPixel >= 8 case. I'm pretty
convinced that this is the only case that we care about at all. Tested
with xwd -root and xwd on a gnome-terminal, in a composited environment
or not.
2006-03-29 Eric Anholt <anholt@FreeBSD.org> 2006-03-29 Eric Anholt <anholt@FreeBSD.org>
* hw/kdrive/ephyr/ephyr_draw.c: (ephyrDownloadFromScreen), * hw/kdrive/ephyr/ephyr_draw.c: (ephyrDownloadFromScreen),

View File

@ -947,15 +947,58 @@ exaPaintWindow(WindowPtr pWin, RegionPtr pRegion, int what)
} }
/** /**
* GetImage isn't accelerated yet, but performs migration so that we'll * Accelerates GetImage for solid ZPixmap downloads from framebuffer memory.
* hopefully avoid the read-from-framebuffer cost. *
* 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.
*/ */
void void
exaGetImage (DrawablePtr pDrawable, int x, int y, int w, int h, exaGetImage (DrawablePtr pDrawable, int x, int y, int w, int h,
unsigned int format, unsigned long planeMask, char *d) unsigned int format, unsigned long planeMask, char *d)
{ {
ExaScreenPriv (pDrawable->pScreen);
ExaMigrationRec pixmaps[1]; ExaMigrationRec pixmaps[1];
PixmapPtr pPix;
int xoff, yoff;
Bool ok;
if (pExaScr->swappedOut || pExaScr->info->DownloadFromScreen == NULL)
goto fallback;
/* Only cover the ZPixmap, solid copy case. */
if (format != ZPixmap || !EXA_PM_IS_SOLID(pDrawable, planeMask))
goto fallback;
/* Only try to handle the 8bpp and up cases, since we don't want to think
* about <8bpp.
*/
if (pDrawable->bitsPerPixel < 8)
goto fallback;
/* Migrate, but assume that we could accelerate the download. It is up to
* the migration scheme to ensure that this case doesn't result in bad
* moving of pixmaps.
*/
pixmaps[0].as_dst = FALSE;
pixmaps[0].as_src = TRUE;
pixmaps[0].pPix = exaGetDrawablePixmap (pDrawable);
exaDoMigration (pixmaps, 1, TRUE);
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,
PixmapBytePad(pDrawable, w));
if (ok) {
exaWaitSync(pDrawable->pScreen);
return;
}
fallback:
pixmaps[0].as_dst = FALSE; pixmaps[0].as_dst = FALSE;
pixmaps[0].as_src = TRUE; pixmaps[0].as_src = TRUE;
pixmaps[0].pPix = exaGetDrawablePixmap (pDrawable); pixmaps[0].pPix = exaGetDrawablePixmap (pDrawable);

View File

@ -129,6 +129,14 @@ extern int exaPixmapPrivateIndex;
/** Align an offset to a power-of-two alignment */ /** Align an offset to a power-of-two alignment */
#define EXA_ALIGN2(offset, align) (((offset) + (align) - 1) & ~((align) - 1)) #define EXA_ALIGN2(offset, align) (((offset) + (align) - 1) & ~((align) - 1))
/**
* Returns TRUE if the given planemask covers all the significant bits in the
* pixel values for pDrawable.
*/
#define EXA_PM_IS_SOLID(_pDrawable, _pm) \
(((_pm) & ((1 << (_pDrawable)->bitsPerPixel) - 1)) == \
((1 << (_pDrawable)->bitsPerPixel) - 1))
#define EXA_PIXMAP_SCORE_MOVE_IN 10 #define EXA_PIXMAP_SCORE_MOVE_IN 10
#define EXA_PIXMAP_SCORE_MAX 20 #define EXA_PIXMAP_SCORE_MAX 20
#define EXA_PIXMAP_SCORE_MOVE_OUT -10 #define EXA_PIXMAP_SCORE_MOVE_OUT -10