summaryrefslogtreecommitdiff
path: root/exa/exa_unaccel.c
diff options
context:
space:
mode:
Diffstat (limited to 'exa/exa_unaccel.c')
-rw-r--r--exa/exa_unaccel.c35
1 files changed, 26 insertions, 9 deletions
diff --git a/exa/exa_unaccel.c b/exa/exa_unaccel.c
index 708d1eac6..a94648b47 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);
- pixmaps[0].as_dst = FALSE;
- pixmaps[0].as_src = TRUE;
- pixmaps[0].pPix = pPixmap;
- exaDoMigration (pixmaps, 1, FALSE);
+ fb = pExaPixmap->sys_ptr;
+
+ /* Try to avoid framebuffer readbacks */
+ if (exaPixmapIsOffscreen(pPixmap) &&
+ miPointInRegion(DamageRegion(pExaPixmap->pDamage), 0, 0, &box))
+ {
+ need_finish = TRUE;
+ pixmaps[0].as_dst = FALSE;
+ pixmaps[0].as_src = TRUE;
+ pixmaps[0].pPix = pPixmap;
+ exaDoMigration (pixmaps, 1, FALSE);
+ exaPrepareAccess(&pPixmap->drawable, EXA_PREPARE_SRC);
+ fb = pPixmap->devPrivate.ptr;
+ }
- 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;
}