summaryrefslogtreecommitdiff
path: root/exa
diff options
context:
space:
mode:
authorAdam Jackson <ajax@benzedrine.nwnk.net>2007-07-27 13:10:39 -0400
committerAdam Jackson <ajax@benzedrine.nwnk.net>2007-07-27 13:10:39 -0400
commit486fd4145aed93093d1f1655de40c0a8582bb8b1 (patch)
tree4f51744f0eacd580ceefdcc72344c23dcdfbf390 /exa
parent50cb6c7e4419e067c1f080d1de940811d21fc725 (diff)
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.
Diffstat (limited to 'exa')
-rw-r--r--exa/exa_unaccel.c37
1 files changed, 27 insertions, 10 deletions
diff --git a/exa/exa_unaccel.c b/exa/exa_unaccel.c
index 708d1eac6..b67ea6389 100644
--- a/exa/exa_unaccel.c
+++ b/exa/exa_unaccel.c
@@ -369,31 +369,48 @@ ExaCheckComposite (CARD8 op,
/**
* 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.
+ *
+ * XXX This really belongs in fb, so it can be aware of tiling and etc.
*/
CARD32
exaGetPixmapFirstPixel (PixmapPtr pPixmap)
{
CARD32 pixel;
+ void *fb;
+ Bool need_finish = FALSE;
+ BoxRec box;
ExaMigrationRec pixmaps[1];
+ ExaPixmapPriv (pPixmap);
+
+ /* Try to avoid framebuffer readbacks */
+ if (exaPixmapIsOffscreen(pPixmap)) {
+ if (!miPointInRegion(DamageRegion(pExaPixmap->pDamage), 0, 0, &box)) {
+ 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);
+ }
+ }
- pixmaps[0].as_dst = FALSE;
- pixmaps[0].as_src = TRUE;
- pixmaps[0].pPix = pPixmap;
- exaDoMigration (pixmaps, 1, FALSE);
-
- exaPrepareAccess(&pPixmap->drawable, EXA_PREPARE_SRC);
switch (pPixmap->drawable.bitsPerPixel) {
case 32:
- pixel = *(CARD32 *)(pPixmap->devPrivate.ptr);
+ pixel = *(CARD32 *)fb;
break;
case 16:
- pixel = *(CARD16 *)(pPixmap->devPrivate.ptr);
+ pixel = *(CARD16 *)fb;
break;
default:
- pixel = *(CARD8 *)(pPixmap->devPrivate.ptr);
+ pixel = *(CARD8 *)fb;
break;
}
- exaFinishAccess(&pPixmap->drawable, EXA_PREPARE_SRC);
+
+ if (need_finish)
+ exaFinishAccess(&pPixmap->drawable, EXA_PREPARE_SRC);
return pixel;
}