exaGetPixmapFirstPixel: avoid framebuffer readbacks if possible.

If the pixel in framebuffer memory isn't modified since we uploaded it, we
can just read from the system memory copy, wihch avoids both a readback and
an accelerator stall.

In principle this function is still wrong, and all the framebuffer pixel
access should be going through (w)fb so we can get pixel layout corrections.
This commit is contained in:
Adam Jackson 2007-07-27 13:10:39 -04:00
parent 50cb6c7e44
commit 486fd4145a

View File

@ -369,31 +369,48 @@ ExaCheckComposite (CARD8 op,
/** /**
* Gets the 0,0 pixel of a pixmap. Used for doing solid fills of tiled pixmaps * Gets the 0,0 pixel of a pixmap. Used for doing solid fills of tiled pixmaps
* that happen to be 1x1. Pixmap must be at least 8bpp. * that happen to be 1x1. Pixmap must be at least 8bpp.
*
* XXX This really belongs in fb, so it can be aware of tiling and etc.
*/ */
CARD32 CARD32
exaGetPixmapFirstPixel (PixmapPtr pPixmap) exaGetPixmapFirstPixel (PixmapPtr pPixmap)
{ {
CARD32 pixel; CARD32 pixel;
void *fb;
Bool need_finish = FALSE;
BoxRec box;
ExaMigrationRec pixmaps[1]; ExaMigrationRec pixmaps[1];
ExaPixmapPriv (pPixmap);
pixmaps[0].as_dst = FALSE; /* Try to avoid framebuffer readbacks */
pixmaps[0].as_src = TRUE; if (exaPixmapIsOffscreen(pPixmap)) {
pixmaps[0].pPix = pPixmap; if (!miPointInRegion(DamageRegion(pExaPixmap->pDamage), 0, 0, &box)) {
exaDoMigration (pixmaps, 1, FALSE); fb = pExaPixmap->sys_ptr;
} else {
need_finish = TRUE;
fb = pPixmap->devPrivate.ptr;
pixmaps[0].as_dst = FALSE;
pixmaps[0].as_src = TRUE;
pixmaps[0].pPix = pPixmap;
exaDoMigration (pixmaps, 1, FALSE);
exaPrepareAccess(&pPixmap->drawable, EXA_PREPARE_SRC);
}
}
exaPrepareAccess(&pPixmap->drawable, EXA_PREPARE_SRC);
switch (pPixmap->drawable.bitsPerPixel) { switch (pPixmap->drawable.bitsPerPixel) {
case 32: case 32:
pixel = *(CARD32 *)(pPixmap->devPrivate.ptr); pixel = *(CARD32 *)fb;
break; break;
case 16: case 16:
pixel = *(CARD16 *)(pPixmap->devPrivate.ptr); pixel = *(CARD16 *)fb;
break; break;
default: default:
pixel = *(CARD8 *)(pPixmap->devPrivate.ptr); pixel = *(CARD8 *)fb;
break; break;
} }
exaFinishAccess(&pPixmap->drawable, EXA_PREPARE_SRC);
if (need_finish)
exaFinishAccess(&pPixmap->drawable, EXA_PREPARE_SRC);
return pixel; return pixel;
} }