[PATCH] EXA: Minimize dixLookupPrivate() calls.

Michel Dänzer michel at daenzer.net
Tue Feb 24 01:41:34 PST 2009


From: Michel Dänzer <daenzer at vmware.com>

Only do it as high up as possible and pass down the EXA private pointers.

Signed-off-by: Michel Dänzer <daenzer at vmware.com>
---
 exa/exa.c           |  141 +++++++++++++---------
 exa/exa_accel.c     |  216 +++++++++++++++++++----------------
 exa/exa_glyphs.c    |   82 ++++++++-----
 exa/exa_migration.c |  143 +++++++++++------------
 exa/exa_offscreen.c |   31 ++---
 exa/exa_priv.h      |  210 ++++++++++++++++++----------------
 exa/exa_render.c    |  233 ++++++++++++++++++++++---------------
 exa/exa_unaccel.c   |  320 +++++++++++++++++++++++++++++----------------------
 8 files changed, 765 insertions(+), 611 deletions(-)

diff --git a/exa/exa.c b/exa/exa.c
index 61c3245..9975904 100644
--- a/exa/exa.c
+++ b/exa/exa.c
@@ -49,10 +49,8 @@ static ShmFuncs exaShmFuncs = { NULL, NULL };
 #endif
 
 static _X_INLINE void*
-ExaGetPixmapAddress(PixmapPtr p)
+ExaGetPixmapAddress(ExaPixmapPrivPtr pExaPixmap)
 {
-    ExaPixmapPriv(p);
-
     if (pExaPixmap->offscreen && pExaPixmap->fb_ptr)
 	return pExaPixmap->fb_ptr;
     else
@@ -73,8 +71,9 @@ unsigned long
 exaGetPixmapOffset(PixmapPtr pPix)
 {
     ExaScreenPriv (pPix->drawable.pScreen);
+    ExaPixmapPriv(pPix);
 
-    return (CARD8 *)ExaGetPixmapAddress(pPix) - pExaScr->info->memoryBase;
+    return (CARD8 *)ExaGetPixmapAddress(pExaPixmap) - pExaScr->info->memoryBase;
 }
 
 void *
@@ -158,8 +157,9 @@ exaGetDrawableDeltas (DrawablePtr pDrawable, PixmapPtr pPixmap,
  * optimizations in pixmap migration when no changes have occurred.
  */
 void
-exaPixmapDirty (PixmapPtr pPix, int x1, int y1, int x2, int y2)
+exaPixmapDirty(ExaPixmapPrivPtr pExaPixmap, int x1, int y1, int x2, int y2)
 {
+    PixmapPtr pPix = pExaPixmap->pPixmap;
     BoxRec box;
     RegionRec region;
 
@@ -180,7 +180,7 @@ exaPixmapDirty (PixmapPtr pPix, int x1, int y1, int x2, int y2)
 static Bool
 exaDestroyPixmap (PixmapPtr pPixmap)
 {
-    ScreenPtr	pScreen = pPixmap->drawable.pScreen;
+    ScreenPtr pScreen = pPixmap->drawable.pScreen;
     ExaScreenPriv(pScreen);
     Bool ret;
 
@@ -197,16 +197,16 @@ exaDestroyPixmap (PixmapPtr pPixmap)
 	{
 	    DBG_PIXMAP(("-- 0x%p (0x%x) (%dx%d)\n",
                         (void*)pPixmap->drawable.id,
-			 ExaGetPixmapPriv(pPixmap)->area->offset,
+			 pExaPixmap->area->offset,
 			 pPixmap->drawable.width,
 			 pPixmap->drawable.height));
 	    /* Free the offscreen area */
-	    exaOffscreenFree (pPixmap->drawable.pScreen, pExaPixmap->area);
+	    exaOffscreenFree (pScreen, pExaPixmap->area);
 	    pPixmap->devPrivate.ptr = pExaPixmap->sys_ptr;
 	    pPixmap->devKind = pExaPixmap->sys_pitch;
 	}
-	REGION_UNINIT(pPixmap->drawable.pScreen, &pExaPixmap->validSys);
-	REGION_UNINIT(pPixmap->drawable.pScreen, &pExaPixmap->validFB);
+	REGION_UNINIT(pScreen, &pExaPixmap->validSys);
+	REGION_UNINIT(pScreen, &pExaPixmap->validFB);
     }
 
     swap(pExaScr, pScreen, DestroyPixmap);
@@ -300,6 +300,7 @@ exaCreatePixmap(ScreenPtr pScreen, int w, int h, int depth,
         return NULL;
 
     pExaPixmap = ExaGetPixmapPriv(pPixmap);
+    pExaPixmap->pPixmap = pPixmap;
     pExaPixmap->driverPriv = NULL;
 
     bpp = pPixmap->drawable.bitsPerPixel;
@@ -463,18 +464,16 @@ exaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height, int depth,
  * @return TRUE if the given drawable is in framebuffer memory.
  */
 Bool
-exaPixmapIsOffscreen(PixmapPtr p)
+exaPixmapIsOffscreen(ExaScreenPrivPtr pExaScr, ExaPixmapPrivPtr pExaPixmap)
 {
-    ScreenPtr	pScreen = p->drawable.pScreen;
-    ExaScreenPriv(pScreen);
-    ExaPixmapPriv(p);
+    PixmapPtr p = pExaPixmap->pPixmap;
     void *save_ptr;
     Bool ret;
 
     save_ptr = p->devPrivate.ptr;
 
     if (!save_ptr && pExaPixmap && !(pExaScr->info->flags & EXA_HANDLES_PIXMAPS))
-	p->devPrivate.ptr = ExaGetPixmapAddress(p);
+	p->devPrivate.ptr = ExaGetPixmapAddress(pExaPixmap);
 
     if (pExaScr->info->PixmapIsOffscreen)
 	ret = pExaScr->info->PixmapIsOffscreen(p);
@@ -494,7 +493,8 @@ exaPixmapIsOffscreen(PixmapPtr p)
 Bool
 exaDrawableIsOffscreen (DrawablePtr pDrawable)
 {
-    return exaPixmapIsOffscreen (exaGetDrawablePixmap (pDrawable));
+    return exaPixmapIsOffscreen(ExaGetScreenPriv (pDrawable->pScreen),
+				ExaGetPixmapPriv (exaGetDrawablePixmap (pDrawable)));
 }
 
 /**
@@ -502,41 +502,41 @@ exaDrawableIsOffscreen (DrawablePtr pDrawable)
  * coordinates to make them address the same bits in the backing drawable.
  */
 PixmapPtr
-exaGetOffscreenPixmap (DrawablePtr pDrawable, int *xp, int *yp)
+exaGetOffscreenPixmap(ExaScreenPrivPtr pExaScr, DrawablePtr pDrawable,
+		      ExaPixmapPrivPtr pExaPixmap, int *xp, int *yp)
 {
-    PixmapPtr	pPixmap = exaGetDrawablePixmap (pDrawable);
+    PixmapPtr pPixmap = pExaPixmap->pPixmap;
 
     exaGetDrawableDeltas (pDrawable, pPixmap, xp, yp);
 
-    if (exaPixmapIsOffscreen (pPixmap))
+    if (exaPixmapIsOffscreen(pExaScr, pExaPixmap))
 	return pPixmap;
     else
 	return NULL;
 }
 
 void
-ExaDoPrepareAccess(DrawablePtr pDrawable, int index)
+ExaDoPrepareAccess(ExaScreenPrivPtr pExaScr, DrawablePtr pDrawable,
+		   ExaPixmapPrivPtr pExaPixmap, int index)
 {
-    ScreenPtr	    pScreen = pDrawable->pScreen;
-    ExaScreenPriv  (pScreen);
-    PixmapPtr	    pPixmap = exaGetDrawablePixmap (pDrawable);
-    Bool	    offscreen = exaPixmapIsOffscreen(pPixmap);
+    ScreenPtr	    pScreen = pExaScr->pScreen;
+    PixmapPtr	    pPixmap = pExaPixmap->pPixmap;
+    Bool	    offscreen = exaPixmapIsOffscreen(pExaScr, pExaPixmap);
 
     /* Unhide pixmap pointer */
     if (pPixmap->devPrivate.ptr == NULL && !(pExaScr->info->flags & EXA_HANDLES_PIXMAPS)) {
-	pPixmap->devPrivate.ptr = ExaGetPixmapAddress(pPixmap);
+	pPixmap->devPrivate.ptr = ExaGetPixmapAddress(pExaPixmap);
     }
 
     if (!offscreen)
 	return;
 
-    exaWaitSync (pDrawable->pScreen);
+    exaWaitSync (pScreen);
 
     if (pExaScr->info->PrepareAccess == NULL)
 	return;
 
     if (!(*pExaScr->info->PrepareAccess) (pPixmap, index)) {
-	ExaPixmapPriv (pPixmap);
 	if (pExaPixmap->score == EXA_PIXMAP_SCORE_PINNED)
 	    FatalError("Driver failed PrepareAccess on a pinned pixmap\n");
 	exaMoveOutPixmap (pPixmap);
@@ -544,18 +544,20 @@ ExaDoPrepareAccess(DrawablePtr pDrawable, int index)
 }
 
 void
-exaPrepareAccessReg(DrawablePtr pDrawable, int index, RegionPtr pReg)
+exaPrepareAccessReg(ExaScreenPrivPtr pExaScr, DrawablePtr pDrawable,
+		    ExaPixmapPrivPtr pExaPixmap, int index, RegionPtr pReg)
 {
     ExaMigrationRec pixmaps[1];
 
     pixmaps[0].as_dst = index == EXA_PREPARE_DEST;
     pixmaps[0].as_src = index != EXA_PREPARE_DEST;
-    pixmaps[0].pPix = exaGetDrawablePixmap (pDrawable);
+    pixmaps[0].pExaScr = pExaScr;
+    pixmaps[0].pExaPix = pExaPixmap;
     pixmaps[0].pReg = pReg;
 
     exaDoMigration(pixmaps, 1, FALSE);
 
-    ExaDoPrepareAccess(pDrawable, index);
+    ExaDoPrepareAccess(pExaScr, pDrawable, pExaPixmap, index);
 }
 
 /**
@@ -565,9 +567,10 @@ exaPrepareAccessReg(DrawablePtr pDrawable, int index, RegionPtr pReg)
  * PrepareAccess() is necessary, and working around PrepareAccess() failure.
  */
 void
-exaPrepareAccess(DrawablePtr pDrawable, int index)
+exaPrepareAccess(ExaScreenPrivPtr pExaScr, DrawablePtr pDrawable,
+		 ExaPixmapPrivPtr pExaPixmap, int index)
 {
-    exaPrepareAccessReg(pDrawable, index, NULL);
+    exaPrepareAccessReg(pExaScr, pDrawable, pExaPixmap, index, NULL);
 }
 
 /**
@@ -576,12 +579,10 @@ exaPrepareAccess(DrawablePtr pDrawable, int index)
  * It deals with calling the driver's FinishAccess() only if necessary.
  */
 void
-exaFinishAccess(DrawablePtr pDrawable, int index)
+exaFinishAccess(ExaScreenPrivPtr pExaScr, DrawablePtr pDrawable,
+		ExaPixmapPrivPtr pExaPixmap, int index)
 {
-    ScreenPtr	    pScreen = pDrawable->pScreen;
-    ExaScreenPriv  (pScreen);
-    PixmapPtr	    pPixmap = exaGetDrawablePixmap (pDrawable);
-    ExaPixmapPriv  (pPixmap);
+    PixmapPtr pPixmap = pExaPixmap->pPixmap;
 
     /* Rehide pixmap pointer if we're doing that. */
     if (pExaPixmap && !(pExaScr->info->flags & EXA_HANDLES_PIXMAPS)) {
@@ -591,7 +592,7 @@ exaFinishAccess(DrawablePtr pDrawable, int index)
     if (pExaScr->info->FinishAccess == NULL)
 	return;
 
-    if (!exaPixmapIsOffscreen (pPixmap))
+    if (!exaPixmapIsOffscreen (pExaScr, pExaPixmap))
 	return;
 
     (*pExaScr->info->FinishAccess) (pPixmap, index);
@@ -651,11 +652,12 @@ const GCFuncs exaGCFuncs = {
  */
 static PixmapPtr
 exaCreatePixmapWithPrepare(ScreenPtr pScreen, int w, int h, int depth,
-		unsigned usage_hint)
+			   unsigned usage_hint)
 {
     PixmapPtr pPixmap;
     ExaMigrationRec pixmaps[1];
     ExaScreenPriv(pScreen);
+    ExaPixmapPrivPtr pExaPixmap;
 
     /* This swaps between this function and the real upper layer function.
      * Normally this would swap to the fb layer pointer, this is a very special case.
@@ -671,12 +673,13 @@ exaCreatePixmapWithPrepare(ScreenPtr pScreen, int w, int h, int depth,
     /* SRC is taken by tile, and MASK by stipple. */
     pixmaps[0].as_dst = 0;
     pixmaps[0].as_src = 1;
-    pixmaps[0].pPix = exaGetDrawablePixmap (&pPixmap->drawable);
+    pixmaps[0].pExaPix = pExaPixmap = ExaGetPixmapPriv(pPixmap);
     pixmaps[0].pReg = NULL;
 
     exaDoMigration(pixmaps, 1, FALSE);
 
-    ExaDoPrepareAccess(&pPixmap->drawable, EXA_PREPARE_DEST);
+    ExaDoPrepareAccess(pExaScr, &pPixmap->drawable, pExaPixmap,
+		       EXA_PREPARE_DEST);
 
     return pPixmap;
 }
@@ -694,6 +697,7 @@ exaValidateGC(GCPtr pGC,
     ExaScreenPriv(pScreen);
     CreatePixmapProcPtr old_ptr = NULL;
     PixmapPtr pTile = NULL;
+    ExaPixmapPrivPtr pExaStipplePix = NULL, pExaTilePix = NULL;
     EXA_GC_PROLOGUE(pGC);
 
     /* save the "fb" pointer. */
@@ -718,17 +722,26 @@ exaValidateGC(GCPtr pGC,
 	}
     }
 
-    if (pGC->stipple)
-        exaPrepareAccess(&pGC->stipple->drawable, EXA_PREPARE_MASK);
-    if (pTile)
-	exaPrepareAccess(&pTile->drawable, EXA_PREPARE_SRC);
+    if (pGC->stipple) {
+	pExaStipplePix = ExaGetPixmapPriv(pGC->stipple);
+        exaPrepareAccess(pExaScr, &pGC->stipple->drawable, pExaStipplePix,
+			 EXA_PREPARE_MASK);
+    }
+
+    if (pTile) {
+	pExaTilePix = ExaGetPixmapPriv(pTile);
+	exaPrepareAccess(pExaScr, &pTile->drawable, pExaTilePix,
+			 EXA_PREPARE_SRC);
+    }
 
     (*pGC->funcs->ValidateGC)(pGC, changes, pDrawable);
 
     if (pTile)
-	exaFinishAccess(&pTile->drawable, EXA_PREPARE_SRC);
+	exaFinishAccess(pExaScr, &pTile->drawable, pExaTilePix,
+			EXA_PREPARE_SRC);
     if (pGC->stipple)
-        exaFinishAccess(&pGC->stipple->drawable, EXA_PREPARE_MASK);
+        exaFinishAccess(pExaScr, &pGC->stipple->drawable, pExaStipplePix,
+			EXA_PREPARE_MASK);
 
     /* switch back to the normal upper layer. */
     unwrap(pExaScr, pScreen, CreatePixmap);
@@ -736,7 +749,8 @@ exaValidateGC(GCPtr pGC,
     pExaScr->SavedCreatePixmap = old_ptr;
 
     if (pGC->fillStyle == FillTiled && pTile != pGC->tile.pixmap)
-	exaFinishAccess(&pGC->tile.pixmap->drawable, EXA_PREPARE_DEST);
+	exaFinishAccess(pExaScr, &pGC->tile.pixmap->drawable,
+			ExaGetPixmapPriv(pGC->tile.pixmap), EXA_PREPARE_DEST);
     
     EXA_GC_EPILOGUE(pGC);
 }
@@ -824,22 +838,31 @@ exaChangeWindowAttributes(WindowPtr pWin, unsigned long mask)
     Bool ret;
     ScreenPtr pScreen = pWin->drawable.pScreen;
     ExaScreenPriv(pScreen);
+    ExaPixmapPrivPtr pExaBGPix = NULL, pExaBorderPix = NULL;
 
-    if ((mask & CWBackPixmap) && pWin->backgroundState == BackgroundPixmap) 
-        exaPrepareAccess(&pWin->background.pixmap->drawable, EXA_PREPARE_SRC);
+    if ((mask & CWBackPixmap) && pWin->backgroundState == BackgroundPixmap) {
+	pExaBGPix = ExaGetPixmapPriv(pWin->background.pixmap);
+        exaPrepareAccess(pExaScr, &pWin->background.pixmap->drawable,
+			 pExaBGPix, EXA_PREPARE_SRC);
+    }
 
-    if ((mask & CWBorderPixmap) && pWin->borderIsPixel == FALSE)
-        exaPrepareAccess(&pWin->border.pixmap->drawable, EXA_PREPARE_MASK);
+    if ((mask & CWBorderPixmap) && pWin->borderIsPixel == FALSE) {
+	pExaBorderPix = ExaGetPixmapPriv(pWin->border.pixmap);
+        exaPrepareAccess(pExaScr, &pWin->border.pixmap->drawable,
+			 pExaBorderPix, EXA_PREPARE_MASK);
+    }
 
     swap(pExaScr, pScreen, ChangeWindowAttributes);
     ret = pScreen->ChangeWindowAttributes(pWin, mask);
     swap(pExaScr, pScreen, ChangeWindowAttributes);
 
     if ((mask & CWBorderPixmap) && pWin->borderIsPixel == FALSE)
-        exaFinishAccess(&pWin->border.pixmap->drawable, EXA_PREPARE_MASK);
+        exaFinishAccess(pExaScr, &pWin->border.pixmap->drawable,
+			pExaBorderPix, EXA_PREPARE_MASK);
 
     if ((mask & CWBackPixmap) && pWin->backgroundState == BackgroundPixmap) 
-        exaFinishAccess(&pWin->background.pixmap->drawable, EXA_PREPARE_SRC);
+        exaFinishAccess(pExaScr, &pWin->background.pixmap->drawable,
+			pExaBGPix, EXA_PREPARE_SRC);
 
     return ret;
 }
@@ -850,12 +873,13 @@ exaBitmapToRegion(PixmapPtr pPix)
     RegionPtr ret;
     ScreenPtr pScreen = pPix->drawable.pScreen;
     ExaScreenPriv(pScreen);
+    ExaPixmapPriv(pPix);
 
-    exaPrepareAccess(&pPix->drawable, EXA_PREPARE_SRC);
+    exaPrepareAccess(pExaScr, &pPix->drawable, pExaPixmap, EXA_PREPARE_SRC);
     swap(pExaScr, pScreen, BitmapToRegion);
     ret = pScreen->BitmapToRegion(pPix);
     swap(pExaScr, pScreen, BitmapToRegion);
-    exaFinishAccess(&pPix->drawable, EXA_PREPARE_SRC);
+    exaFinishAccess(pExaScr, &pPix->drawable, pExaPixmap, EXA_PREPARE_SRC);
 
     return ret;
 }
@@ -911,7 +935,7 @@ ExaBlockHandler(int screenNum, pointer blockData, pointer pTimeout,
     wrap(pExaScr, pScreen, BlockHandler, ExaBlockHandler);
 
     pExaScr->defragTimer = TimerSet(pExaScr->defragTimer, 0, 100,
-				    ExaDefragTimerCallback, pScreen);
+				    ExaDefragTimerCallback, pExaScr);
 }
 
 static void
@@ -1095,6 +1119,7 @@ exaDriverInit (ScreenPtr		pScreen,
     }
 
     pExaScr->info = pScreenInfo;
+    pExaScr->pScreen = pScreen;
 
     dixSetPrivate(&pScreen->devPrivates, exaScreenPrivateKey, pExaScr);
 
@@ -1176,7 +1201,7 @@ exaDriverInit (ScreenPtr		pScreen,
 	DBG_PIXMAP(("============== %ld < %ld\n", pExaScr->info->offScreenBase,
 		    pExaScr->info->memorySize));
 	if (pExaScr->info->offScreenBase < pExaScr->info->memorySize) {
-	    if (!exaOffscreenInit (pScreen)) {
+	    if (!exaOffscreenInit(pExaScr)) {
 		LogMessage(X_WARNING, "EXA(%d): Offscreen pixmap setup failed\n",
 			   pScreen->myNum);
 		return FALSE;
diff --git a/exa/exa_accel.c b/exa/exa_accel.c
index b1ab2d1..8b3ccbf 100644
--- a/exa/exa_accel.c
+++ b/exa/exa_accel.c
@@ -54,26 +54,30 @@ exaFillSpans(DrawablePtr pDrawable, GCPtr pGC, int n,
 
     pixmaps[0].as_dst = TRUE;
     pixmaps[0].as_src = FALSE;
-    pixmaps[0].pPix = pPixmap;
+    pixmaps[0].pExaScr = pExaScr;
+    pixmaps[0].pExaPix = pExaPixmap;
     pixmaps[0].pReg = NULL;
 
     if (pExaScr->swappedOut ||
 	pGC->fillStyle != FillSolid ||
 	pExaPixmap->accel_blocked)
     {
-	ExaCheckFillSpans (pDrawable, pGC, n, ppt, pwidth, fSorted);
+	ExaCheckFillSpans(pExaScr, pDrawable, pExaPixmap, pGC, n, ppt, pwidth,
+			  fSorted);
 	return;
     } else {
 	exaDoMigration (pixmaps, 1, TRUE);
     }
 
-    if (!(pPixmap = exaGetOffscreenPixmap (pDrawable, &off_x, &off_y)) ||
+    if (!(pPixmap = exaGetOffscreenPixmap(pExaScr, pDrawable, pExaPixmap,
+					  &off_x, &off_y)) ||
 	!(*pExaScr->info->PrepareSolid) (pPixmap,
 					 pGC->alu,
 					 pGC->planemask,
 					 pGC->fgPixel))
     {
-	ExaCheckFillSpans (pDrawable, pGC, n, ppt, pwidth, fSorted);
+	ExaCheckFillSpans(pExaScr, pDrawable, pExaPixmap, pGC, n, ppt, pwidth,
+			  fSorted);
 	return;
     }
 
@@ -137,18 +141,16 @@ exaFillSpans(DrawablePtr pDrawable, GCPtr pGC, int n,
 }
 
 static Bool
-exaDoPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y,
-	       int w, int h, int format, char *bits, int src_stride)
+exaDoPutImage(ExaScreenPrivPtr pExaScr, DrawablePtr pDrawable,
+	      ExaPixmapPrivPtr pExaPixmap, GCPtr pGC, int depth, int x, int y,
+	      int w, int h, int format, char *bits, int src_stride)
 {
-    ExaScreenPriv (pDrawable->pScreen);
-    PixmapPtr pPix = exaGetDrawablePixmap (pDrawable);
-    ExaPixmapPriv(pPix);
+    PixmapPtr pPix = pExaPixmap->pPixmap;
     RegionPtr pClip;
     BoxPtr pbox;
     int nbox;
     int xoff, yoff;
     int bpp = pDrawable->bitsPerPixel;
-    Bool access_prepared = FALSE;
     Bool ret = TRUE;
 
     if (pExaPixmap->accel_blocked)
@@ -170,13 +172,14 @@ exaDoPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y,
 
  	pixmaps[0].as_dst = TRUE;
 	pixmaps[0].as_src = FALSE;
-	pixmaps[0].pPix = pPix;
+	pixmaps[0].pExaScr = pExaScr;
+	pixmaps[0].pExaPix = pExaPixmap;
 	pixmaps[0].pReg = DamagePendingRegion(pExaPixmap->pDamage);
 
 	exaDoMigration (pixmaps, 1, TRUE);
     }
 
-    pPix = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff);
+    pPix = exaGetOffscreenPixmap(pExaScr, pDrawable, pExaPixmap, &xoff, &yoff);
 
     if (!pPix || !pExaScr->info->UploadToScreen)
 	return FALSE;
@@ -220,10 +223,7 @@ exaDoPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y,
 	}
     }
 
-    if (access_prepared)
-	exaFinishAccess(pDrawable, EXA_PREPARE_DEST);
-    else
-	exaMarkSync(pDrawable->pScreen);
+    exaMarkSync(pDrawable->pScreen);
 
     return ret;
 }
@@ -232,24 +232,30 @@ static void
 exaPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y,
 	     int w, int h, int leftPad, int format, char *bits)
 {
-    if (!exaDoPutImage(pDrawable, pGC, depth, x, y, w, h, format, bits,
-		       PixmapBytePad(w, pDrawable->depth)))
-	ExaCheckPutImage(pDrawable, pGC, depth, x, y, w, h, leftPad, format,
-			 bits);
+    ExaScreenPriv(pDrawable->pScreen);
+    ExaPixmapPriv(exaGetDrawablePixmap(pDrawable));
+
+    if (!exaDoPutImage(pExaScr, pDrawable, pExaPixmap, pGC, depth, x, y, w, h,
+		       format, bits, PixmapBytePad(w, pDrawable->depth)))
+	ExaCheckPutImage(pExaScr, pDrawable, pExaPixmap, pGC, depth, x, y, w, h,
+			 leftPad, format, bits);
 }
 
 static Bool inline
-exaCopyNtoNTwoDir (DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable,
-		   GCPtr pGC, BoxPtr pbox, int nbox, int dx, int dy)
+exaCopyNtoNTwoDir (ExaScreenPrivPtr pExaScr, DrawablePtr pSrcDrawable,
+		   ExaPixmapPrivPtr pExaSrcPix, DrawablePtr pDstDrawable,
+		   ExaPixmapPrivPtr pExaDstPix, GCPtr pGC, BoxPtr pbox,
+		   int nbox, int dx, int dy)
 {
-    ExaScreenPriv (pDstDrawable->pScreen);
     PixmapPtr pSrcPixmap, pDstPixmap;
     int src_off_x, src_off_y, dst_off_x, dst_off_y;
     int dirsetup;
 
     /* Need to get both pixmaps to call the driver routines */
-    pSrcPixmap = exaGetOffscreenPixmap (pSrcDrawable, &src_off_x, &src_off_y);
-    pDstPixmap = exaGetOffscreenPixmap (pDstDrawable, &dst_off_x, &dst_off_y);
+    pSrcPixmap = exaGetOffscreenPixmap(pExaScr, pSrcDrawable, pExaSrcPix,
+				       &src_off_x, &src_off_y);
+    pDstPixmap = exaGetOffscreenPixmap(pExaScr, pDstDrawable, pExaDstPix,
+				       &dst_off_x, &dst_off_y);
     if (!pSrcPixmap || !pDstPixmap)
 	return FALSE;
 
@@ -360,19 +366,12 @@ exaCopyNtoNTwoDir (DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable,
 }
 
 Bool
-exaHWCopyNtoN (DrawablePtr    pSrcDrawable,
-	     DrawablePtr    pDstDrawable,
-	     GCPtr	    pGC,
-	     BoxPtr	    pbox,
-	     int	    nbox,
-	     int	    dx,
-	     int	    dy,
-	     Bool	    reverse,
-	     Bool	    upsidedown)
+exaHWCopyNtoN(ExaScreenPrivPtr pExaScr, DrawablePtr pSrcDrawable,
+	      ExaPixmapPrivPtr pSrcExaPixmap, DrawablePtr pDstDrawable,
+	      ExaPixmapPrivPtr pDstExaPixmap, GCPtr pGC, BoxPtr pbox, int nbox,
+	      int dx, int dy, Bool reverse, Bool upsidedown)
 {
-    ExaScreenPriv (pDstDrawable->pScreen);
     PixmapPtr pSrcPixmap, pDstPixmap;
-    ExaPixmapPrivPtr pSrcExaPixmap, pDstExaPixmap;
     int	    src_off_x, src_off_y;
     int	    dst_off_x, dst_off_y;
     ExaMigrationRec pixmaps[2];
@@ -384,8 +383,8 @@ exaHWCopyNtoN (DrawablePtr    pSrcDrawable,
     if (nbox == 0)
 	return TRUE;
 
-    pSrcPixmap = exaGetDrawablePixmap (pSrcDrawable);
-    pDstPixmap = exaGetDrawablePixmap (pDstDrawable);
+    pSrcPixmap = pSrcExaPixmap->pPixmap;
+    pDstPixmap = pDstExaPixmap->pPixmap;
 
     exaGetDrawableDeltas (pSrcDrawable, pSrcPixmap, &src_off_x, &src_off_y);
     exaGetDrawableDeltas (pDstDrawable, pDstPixmap, &dst_off_x, &dst_off_y);
@@ -416,16 +415,15 @@ exaHWCopyNtoN (DrawablePtr    pSrcDrawable,
 
     pixmaps[0].as_dst = TRUE;
     pixmaps[0].as_src = FALSE;
-    pixmaps[0].pPix = pDstPixmap;
+    pixmaps[0].pExaScr = pExaScr;
+    pixmaps[0].pExaPix = pDstExaPixmap;
     pixmaps[0].pReg = dstregion;
     pixmaps[1].as_dst = FALSE;
     pixmaps[1].as_src = TRUE;
-    pixmaps[1].pPix = pSrcPixmap;
+    pixmaps[1].pExaScr = pExaScr;
+    pixmaps[1].pExaPix = pSrcExaPixmap;
     pixmaps[1].pReg = srcregion;
 
-    pSrcExaPixmap = ExaGetPixmapPriv (pSrcPixmap);
-    pDstExaPixmap = ExaGetPixmapPriv (pDstPixmap);
-
     /* Check whether the accelerator can use this pixmap.
      * If the pitch of the pixmaps is out of range, there's nothing
      * we can do but fall back to software rendering.
@@ -460,14 +458,15 @@ exaHWCopyNtoN (DrawablePtr    pSrcDrawable,
     /* Mixed directions must be handled specially if the card is lame */
     if ((pExaScr->info->flags & EXA_TWO_BITBLT_DIRECTIONS) &&
 	reverse != upsidedown) {
-	if (exaCopyNtoNTwoDir(pSrcDrawable, pDstDrawable, pGC, pbox, nbox,
-			       dx, dy))
+	if (exaCopyNtoNTwoDir(pExaScr, pSrcDrawable, pSrcExaPixmap,
+			      pDstDrawable, pDstExaPixmap, pGC, pbox, nbox, dx,
+			      dy))
 	    goto out;
 	goto fallback;
     }
 
-    if (!exaPixmapIsOffscreen(pSrcPixmap) ||
-	!exaPixmapIsOffscreen(pDstPixmap) ||
+    if (!exaPixmapIsOffscreen(pExaScr, pSrcExaPixmap) ||
+	!exaPixmapIsOffscreen(pExaScr, pDstExaPixmap) ||
 	!(*pExaScr->info->PrepareCopy) (pSrcPixmap, pDstPixmap, reverse ? -1 : 1,
 					upsidedown ? -1 : 1,
 					pGC ? pGC->alu : GXcopy,
@@ -520,11 +519,16 @@ exaCopyNtoN (DrawablePtr    pSrcDrawable,
 	     void	    *closure)
 {
     ExaScreenPriv(pDstDrawable->pScreen);
+    ExaPixmapPrivPtr pExaDstPix =
+	ExaGetPixmapPriv(exaGetDrawablePixmap(pDstDrawable));
+    ExaPixmapPrivPtr pExaSrcPix =
+	ExaGetPixmapPriv(exaGetDrawablePixmap(pSrcDrawable));
 
     if (pExaScr->fallback_flags & EXA_FALLBACK_COPYWINDOW)
 	return;
 
-    if (exaHWCopyNtoN(pSrcDrawable, pDstDrawable, pGC, pbox, nbox, dx, dy, reverse, upsidedown))
+    if (exaHWCopyNtoN(pExaScr, pSrcDrawable, pExaSrcPix, pDstDrawable,
+		      pExaDstPix, pGC, pbox, nbox, dx, dy, reverse, upsidedown))
 	return;
 
     /* This is a CopyWindow, it's cleaner to fallback at the original call. */
@@ -534,7 +538,9 @@ exaCopyNtoN (DrawablePtr    pSrcDrawable,
     }
 
     /* fallback */
-    ExaCheckCopyNtoN(pSrcDrawable, pDstDrawable, pGC, pbox, nbox, dx, dy, reverse, upsidedown, bitplane, closure);
+    ExaCheckCopyNtoN(pExaScr, pSrcDrawable, pExaSrcPix, pDstDrawable,
+		     pExaDstPix, pGC, pbox, nbox, dx, dy, reverse, upsidedown,
+		     bitplane, closure);
 }
 
 RegionPtr
@@ -544,8 +550,11 @@ exaCopyArea(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC,
     ExaScreenPriv (pDstDrawable->pScreen);
 
     if (pExaScr->swappedOut) {
-        return  ExaCheckCopyArea(pSrcDrawable, pDstDrawable, pGC,
-                                 srcx, srcy, width, height, dstx, dsty);
+        return ExaCheckCopyArea(pExaScr, pSrcDrawable,
+				ExaGetPixmapPriv(exaGetDrawablePixmap(pSrcDrawable)),
+				pDstDrawable,
+				ExaGetPixmapPriv(exaGetDrawablePixmap(pDstDrawable)),
+				pGC, srcx, srcy, width, height, dstx, dsty);
     }
 
     return  miDoCopy (pSrcDrawable, pDstDrawable, pGC,
@@ -564,7 +573,9 @@ exaPolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
      * points.
      */
     if (pGC->fillStyle != FillSolid) {
-	ExaCheckPolyPoint(pDrawable, pGC, mode, npt, ppt);
+	ExaCheckPolyPoint(ExaGetScreenPriv(pDrawable->pScreen), pDrawable,
+			  ExaGetPixmapPriv(exaGetDrawablePixmap(pDrawable)), pGC,
+			  mode, npt, ppt);
 	return;
     }
 
@@ -592,6 +603,8 @@ static void
 exaPolylines(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
 	     DDXPointPtr ppt)
 {
+    ExaScreenPriv(pDrawable->pScreen);
+    ExaPixmapPriv(exaGetDrawablePixmap(pDrawable));
     xRectangle *prect;
     int x1, x2, y1, y2;
     int i;
@@ -599,7 +612,7 @@ exaPolylines(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
     /* Don't try to do wide lines or non-solid fill style. */
     if (pGC->lineWidth != 0 || pGC->lineStyle != LineSolid ||
 	pGC->fillStyle != FillSolid) {
-	ExaCheckPolylines(pDrawable, pGC, mode, npt, ppt);
+	ExaCheckPolylines(pExaScr, pDrawable, pExaPixmap, pGC, mode, npt, ppt);
 	return;
     }
 
@@ -618,7 +631,8 @@ exaPolylines(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
 
 	if (x1 != x2 && y1 != y2) {
 	    xfree(prect);
-	    ExaCheckPolylines(pDrawable, pGC, mode, npt, ppt);
+	    ExaCheckPolylines(pExaScr, pDrawable, pExaPixmap, pGC, mode, npt,
+			      ppt);
 	    return;
 	}
 
@@ -653,6 +667,8 @@ static void
 exaPolySegment (DrawablePtr pDrawable, GCPtr pGC, int nseg,
 		xSegment *pSeg)
 {
+    ExaScreenPriv(pDrawable->pScreen);
+    ExaPixmapPriv(exaGetDrawablePixmap(pDrawable));
     xRectangle *prect;
     int i;
 
@@ -660,14 +676,15 @@ exaPolySegment (DrawablePtr pDrawable, GCPtr pGC, int nseg,
     if (pGC->lineWidth != 0 || pGC->lineStyle != LineSolid ||
 	pGC->fillStyle != FillSolid)
     {
-	ExaCheckPolySegment(pDrawable, pGC, nseg, pSeg);
+	ExaCheckPolySegment(pExaScr, pDrawable, pExaPixmap, pGC, nseg, pSeg);
 	return;
     }
 
     /* If we have any non-horizontal/vertical, fall back. */
     for (i = 0; i < nseg; i++) {
 	if (pSeg[i].x1 != pSeg[i].x2 && pSeg[i].y1 != pSeg[i].y2) {
-	    ExaCheckPolySegment(pDrawable, pGC, nseg, pSeg);
+	    ExaCheckPolySegment(pExaScr, pDrawable, pExaPixmap, pGC, nseg,
+				pSeg);
 	    return;
 	}
     }
@@ -701,8 +718,9 @@ exaPolySegment (DrawablePtr pDrawable, GCPtr pGC, int nseg,
     xfree(prect);
 }
 
-static Bool exaFillRegionSolid (DrawablePtr pDrawable, RegionPtr pRegion,
-				Pixel pixel, CARD32 planemask, CARD32 alu);
+static Bool exaFillRegionSolid(ExaScreenPrivPtr pExaScr, DrawablePtr pDrawable,
+			       ExaPixmapPrivPtr pExaPixmap, RegionPtr pRegion,
+			       Pixel pixel, CARD32 planemask, CARD32 alu);
 
 static void
 exaPolyFillRect(DrawablePtr pDrawable,
@@ -735,7 +753,8 @@ exaPolyFillRect(DrawablePtr pDrawable,
 
     pixmaps[0].as_dst = TRUE;
     pixmaps[0].as_src = FALSE;
-    pixmaps[0].pPix = pPixmap;
+    pixmaps[0].pExaScr = pExaScr;
+    pixmaps[0].pExaPix = pExaPixmap;
     pixmaps[0].pReg = NULL;
 
     exaGetDrawableDeltas(pDrawable, pPixmap, &xoff, &yoff);
@@ -753,12 +772,14 @@ exaPolyFillRect(DrawablePtr pDrawable,
 	 pGC->alu == GXnoop || pGC->alu == GXcopyInverted ||
 	 pGC->alu == GXset)) {
 	if (((pGC->fillStyle == FillSolid || pGC->tileIsPixel) &&
-	     exaFillRegionSolid(pDrawable, pReg, pGC->fillStyle == FillSolid ?
-				pGC->fgPixel : pGC->tile.pixel,	pGC->planemask,
-				pGC->alu)) ||
+	     exaFillRegionSolid(pExaScr, pDrawable, pExaPixmap, pReg,
+				pGC->fillStyle == FillSolid ? pGC->fgPixel :
+				pGC->tile.pixel, pGC->planemask, pGC->alu)) ||
 	    (pGC->fillStyle == FillTiled && !pGC->tileIsPixel &&
-	     exaFillRegionTiled(pDrawable, pReg, pGC->tile.pixmap, &pGC->patOrg,
-				pGC->planemask, pGC->alu))) {
+	     exaFillRegionTiled(pExaScr, pDrawable, pExaPixmap, pReg,
+				pGC->tile.pixmap,
+				ExaGetPixmapPriv(pGC->tile.pixmap),
+				&pGC->patOrg, pGC->planemask, pGC->alu))) {
 	    goto out;
 	}
     }
@@ -771,14 +792,14 @@ exaPolyFillRect(DrawablePtr pDrawable,
 
     exaDoMigration (pixmaps, 1, TRUE);
 
-    if (!exaPixmapIsOffscreen (pPixmap) ||
+    if (!exaPixmapIsOffscreen (pExaScr, pExaPixmap) ||
 	!(*pExaScr->info->PrepareSolid) (pPixmap,
 					 pGC->alu,
 					 pGC->planemask,
 					 pGC->fgPixel))
     {
 fallback:
-	ExaCheckPolyFillRect (pDrawable, pGC, nrect, prect);
+	ExaCheckPolyFillRect(pExaScr, pDrawable, pExaPixmap, pGC, nrect, prect);
 	goto out;
     }
 
@@ -915,27 +936,25 @@ exaCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
     if (pExaScr->fallback_flags & EXA_FALLBACK_COPYWINDOW) {
 	pExaScr->fallback_flags &= ~EXA_FALLBACK_COPYWINDOW;
 	REGION_TRANSLATE(pWin->drawable.pScreen, prgnSrc, dx, dy);
-	ExaCheckCopyWindow(pWin, ptOldOrg, prgnSrc);
+	ExaCheckCopyWindow(pExaScr, pWin, ExaGetPixmapPriv(pPixmap), ptOldOrg,
+			   prgnSrc);
     }
 }
 
 static Bool
-exaFillRegionSolid (DrawablePtr	pDrawable,
-		    RegionPtr	pRegion,
-		    Pixel	pixel,
-		    CARD32	planemask,
-		    CARD32	alu)
+exaFillRegionSolid(ExaScreenPrivPtr pExaScr, DrawablePtr pDrawable,
+		   ExaPixmapPrivPtr pExaPixmap, RegionPtr pRegion, Pixel pixel,
+		   CARD32 planemask, CARD32 alu)
 {
-    ExaScreenPriv(pDrawable->pScreen);
-    PixmapPtr pPixmap = exaGetDrawablePixmap (pDrawable);
-    ExaPixmapPriv (pPixmap);
+    PixmapPtr pPixmap = pExaPixmap->pPixmap;
     int xoff, yoff;
     ExaMigrationRec pixmaps[1];
     Bool ret = FALSE;
 
     pixmaps[0].as_dst = TRUE;
     pixmaps[0].as_src = FALSE;
-    pixmaps[0].pPix = pPixmap;
+    pixmaps[0].pExaScr = pExaScr;
+    pixmaps[0].pExaPix = pExaPixmap;
     pixmaps[0].pReg = exaGCReadsDestination(pDrawable, planemask, FillSolid,
 					    alu) ? NULL : pRegion;
 
@@ -949,7 +968,7 @@ exaFillRegionSolid (DrawablePtr	pDrawable,
 	exaDoMigration (pixmaps, 1, TRUE);
     }
 
-    if (exaPixmapIsOffscreen (pPixmap) &&
+    if (exaPixmapIsOffscreen (pExaScr, pExaPixmap) &&
 	(*pExaScr->info->PrepareSolid) (pPixmap, alu, planemask, pixel))
     {
 	int nbox;
@@ -970,8 +989,6 @@ exaFillRegionSolid (DrawablePtr	pDrawable,
 	if (!(pExaScr->info->flags & EXA_HANDLES_PIXMAPS) &&
 	    pDrawable->width == 1 && pDrawable->height == 1 &&
 	    pDrawable->bitsPerPixel != 24) {
-	    ExaPixmapPriv(pPixmap);
-
 	    switch (pDrawable->bitsPerPixel) {
 	    case 32:
 		*(CARD32*)pExaPixmap->sys_ptr = pixel;
@@ -1000,17 +1017,12 @@ out:
  * Based on fbFillRegionTiled(), fbTile().
  */
 Bool
-exaFillRegionTiled (DrawablePtr	pDrawable,
-		    RegionPtr	pRegion,
-		    PixmapPtr	pTile,
-		    DDXPointPtr pPatOrg,
-		    CARD32	planemask,
-		    CARD32	alu)
+exaFillRegionTiled(ExaScreenPrivPtr pExaScr, DrawablePtr pDrawable,
+		   ExaPixmapPrivPtr pExaPixmap, RegionPtr pRegion,
+		   PixmapPtr pTile, ExaPixmapPrivPtr pTileExaPixmap,
+		   DDXPointPtr pPatOrg, CARD32 planemask, CARD32 alu)
 {
-    ExaScreenPriv(pDrawable->pScreen);
-    PixmapPtr pPixmap;
-    ExaPixmapPrivPtr pExaPixmap;
-    ExaPixmapPrivPtr pTileExaPixmap = ExaGetPixmapPriv(pTile);
+    PixmapPtr pPixmap = pExaPixmap->pPixmap;
     int xoff, yoff;
     int tileWidth, tileHeight;
     ExaMigrationRec pixmaps[2];
@@ -1026,22 +1038,22 @@ exaFillRegionTiled (DrawablePtr	pDrawable,
      * FillRegionSolid, saving numerous copies.
      */
     if (tileWidth == 1 && tileHeight == 1)
-	return exaFillRegionSolid(pDrawable, pRegion,
+	return exaFillRegionSolid(pExaScr, pDrawable, pExaPixmap, pRegion,
 				  exaGetPixmapFirstPixel (pTile), planemask,
 				  alu);
 
     pixmaps[0].as_dst = TRUE;
     pixmaps[0].as_src = FALSE;
-    pixmaps[0].pPix = pPixmap = exaGetDrawablePixmap (pDrawable);
+    pixmaps[0].pExaScr = pExaScr;
+    pixmaps[0].pExaPix = pExaPixmap;
     pixmaps[0].pReg = exaGCReadsDestination(pDrawable, planemask, FillTiled,
 					    alu) ? NULL : pRegion;
     pixmaps[1].as_dst = FALSE;
     pixmaps[1].as_src = TRUE;
-    pixmaps[1].pPix = pTile;
+    pixmaps[1].pExaScr = pExaScr;
+    pixmaps[1].pExaPix = pTileExaPixmap;
     pixmaps[1].pReg = NULL;
 
-    pExaPixmap = ExaGetPixmapPriv (pPixmap);
-
     if (pExaPixmap->accel_blocked || pTileExaPixmap->accel_blocked)
     {
 	return FALSE;
@@ -1049,9 +1061,10 @@ exaFillRegionTiled (DrawablePtr	pDrawable,
 	exaDoMigration (pixmaps, 2, TRUE);
     }
 
-    pPixmap = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff);
+    pPixmap = exaGetOffscreenPixmap(pExaScr, pDrawable, pExaPixmap,
+				    &xoff, &yoff);
 
-    if (!pPixmap || !exaPixmapIsOffscreen(pTile))
+    if (!pPixmap || !exaPixmapIsOffscreen(pExaScr, pTileExaPixmap))
 	return FALSE;
 
     if ((*pExaScr->info->PrepareCopy) (pTile, pPixmap, 1, 1, alu, planemask))
@@ -1187,13 +1200,15 @@ exaGetImage (DrawablePtr pDrawable, int x, int y, int w, int h,
     ExaMigrationRec pixmaps[1];
     BoxRec Box;
     RegionRec Reg;
-    PixmapPtr pPix;
+    PixmapPtr pPix = exaGetDrawablePixmap (pDrawable);
+    ExaPixmapPriv(pPix);
     int xoff, yoff;
     Bool ok;
 
     pixmaps[0].as_dst = FALSE;
     pixmaps[0].as_src = TRUE;
-    pixmaps[0].pPix = pPix = exaGetDrawablePixmap (pDrawable);
+    pixmaps[0].pExaScr = pExaScr;
+    pixmaps[0].pExaPix = pExaPixmap;
     pixmaps[0].pReg = &Reg;
 
     exaGetDrawableDeltas (pDrawable, pPix, &xoff, &yoff);
@@ -1210,7 +1225,7 @@ exaGetImage (DrawablePtr pDrawable, int x, int y, int w, int h,
 
     exaDoMigration(pixmaps, 1, FALSE);
 
-    pPix = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff);
+    pPix = exaGetOffscreenPixmap(pExaScr, pDrawable, pExaPixmap, &xoff, &yoff);
 
     if (pPix == NULL || pExaScr->info->DownloadFromScreen == NULL)
 	goto fallback;
@@ -1234,7 +1249,8 @@ exaGetImage (DrawablePtr pDrawable, int x, int y, int w, int h,
     }
 
 fallback:
-    ExaCheckGetImage(pDrawable, x, y, w, h, format, planeMask, d);
+    ExaCheckGetImage(pExaScr, pDrawable, pExaPixmap, x, y, w, h, format,
+		     planeMask, d);
 
 out:
     REGION_UNINIT(pScreen, &Reg);
diff --git a/exa/exa_glyphs.c b/exa/exa_glyphs.c
index 918fd85..81f22d1 100644
--- a/exa/exa_glyphs.c
+++ b/exa/exa_glyphs.c
@@ -69,6 +69,7 @@
 
 typedef struct {
     PicturePtr mask;
+    ExaPixmapPrivPtr examask;
     ExaCompositeRectRec rects[GLYPH_BUFFER_SIZE];
     int count;
 } ExaGlyphBuffer, *ExaGlyphBufferPtr;
@@ -214,6 +215,7 @@ exaRealizeGlyphCaches(ScreenPtr    pScreen,
 	    continue;
 
 	cache->picture = pPicture;
+	cache->exapix = ExaGetPixmapPriv((PixmapPtr)pPicture->pDrawable);
 	cache->picture->refcnt++;
 	cache->hashEntries = xalloc(sizeof(int) * cache->hashSize);
 	cache->glyphs = xalloc(sizeof(ExaCachedGlyphRec) * cache->size);
@@ -358,24 +360,25 @@ exaGlyphCacheHashRemove(ExaGlyphCachePtr cache,
  * glyphs that we'll never use again.
  */
 static Bool
-exaGlyphCacheUploadGlyph(ScreenPtr         pScreen,
+exaGlyphCacheUploadGlyph(ExaScreenPrivPtr  pExaScr,
 			 ExaGlyphCachePtr  cache,
 			 int               pos,
 			 GlyphPtr          pGlyph)
 {
-    ExaScreenPriv(pScreen);
+    ScreenPtr pScreen = pExaScr->pScreen;
     PicturePtr pGlyphPicture = GlyphPicture(pGlyph)[pScreen->myNum];
     PixmapPtr pGlyphPixmap = (PixmapPtr)pGlyphPicture->pDrawable;
-    ExaPixmapPriv(pGlyphPixmap);
-    PixmapPtr pCachePixmap = (PixmapPtr)cache->picture->pDrawable;
+    ExaPixmapPrivPtr pExaGlyphPixmap = ExaGetPixmapPriv(pGlyphPixmap);
+    ExaPixmapPrivPtr pExaCachePixmap = cache->exapix;
+    PixmapPtr pCachePixmap = pExaCachePixmap->pPixmap;
     ExaMigrationRec pixmaps[1];
 
-    if (!pExaScr->info->UploadToScreen || pExaScr->swappedOut || pExaPixmap->accel_blocked)
+    if (!pExaScr->info->UploadToScreen || pExaScr->swappedOut || pExaGlyphPixmap->accel_blocked)
 	return FALSE;
 
     /* If the glyph pixmap is already uploaded, no point in doing
      * things this way */
-    if (exaPixmapIsOffscreen(pGlyphPixmap))
+    if (exaPixmapIsOffscreen(pExaScr, pExaGlyphPixmap))
 	return FALSE;
 
     /* UploadToScreen only works if bpp match */
@@ -385,11 +388,12 @@ exaGlyphCacheUploadGlyph(ScreenPtr         pScreen,
     /* cache pixmap must be offscreen. */
     pixmaps[0].as_dst = TRUE;
     pixmaps[0].as_src = FALSE;
-    pixmaps[0].pPix = pCachePixmap;
+    pixmaps[0].pExaScr = pExaScr;
+    pixmaps[0].pExaPix = pExaCachePixmap;
     pixmaps[0].pReg = NULL;
     exaDoMigration (pixmaps, 1, TRUE);
 
-    if (!exaPixmapIsOffscreen(pCachePixmap))
+    if (!exaPixmapIsOffscreen(pExaScr, pExaCachePixmap))
 	return FALSE;
 
     /* CACHE_{X,Y} are in pixmap coordinates, no need for cache{X,Y}off */
@@ -398,12 +402,12 @@ exaGlyphCacheUploadGlyph(ScreenPtr         pScreen,
 				       CACHE_Y(pos),
 				       pGlyph->info.width,
 				       pGlyph->info.height,
-				       (char *)pExaPixmap->sys_ptr,
-				       pExaPixmap->sys_pitch))
+				       (char *)pExaGlyphPixmap->sys_ptr,
+				       pExaGlyphPixmap->sys_pitch))
 	return FALSE;
 
     /* This pixmap should never be bound to a window, so no need to offset coordinates. */
-    exaPixmapDirty (pCachePixmap,
+    exaPixmapDirty (pExaCachePixmap,
 		    CACHE_X(pos),
 		    CACHE_Y(pos),
 		    CACHE_X(pos) + pGlyph->info.width,
@@ -413,7 +417,7 @@ exaGlyphCacheUploadGlyph(ScreenPtr         pScreen,
 }
 
 static ExaGlyphCacheResult
-exaGlyphCacheBufferGlyph(ScreenPtr         pScreen,
+exaGlyphCacheBufferGlyph(ExaScreenPrivPtr  pExaScr,
 			 ExaGlyphCachePtr  cache,
 			 ExaGlyphBufferPtr buffer,
 			 GlyphPtr          pGlyph,
@@ -426,6 +430,7 @@ exaGlyphCacheBufferGlyph(ScreenPtr         pScreen,
 			 INT16             xDst,
 			 INT16             yDst)
 {
+    ScreenPtr pScreen = pExaScr->pScreen;
     ExaCompositeRectPtr rect;
     int pos;
     
@@ -488,7 +493,7 @@ exaGlyphCacheBufferGlyph(ScreenPtr         pScreen,
 	 * we can't do it with UploadToScreen (because the glyph is
 	 * offscreen, etc), we fall back to CompositePicture.
 	 */
-	if (!exaGlyphCacheUploadGlyph(pScreen, cache, pos, pGlyph)) {
+	if (!exaGlyphCacheUploadGlyph(pExaScr, cache, pos, pGlyph)) {
 	    CompositePicture (PictOpSrc,
 			      GlyphPicture(pGlyph)[pScreen->myNum],
 			      None,
@@ -504,6 +509,7 @@ exaGlyphCacheBufferGlyph(ScreenPtr         pScreen,
     }
 
     buffer->mask = cache->picture;
+    buffer->examask = cache->exapix;
 	    
     rect = &buffer->rects[buffer->count];
 
@@ -537,7 +543,7 @@ exaGlyphCacheBufferGlyph(ScreenPtr         pScreen,
 #undef CACHE_Y
 
 static ExaGlyphCacheResult
-exaBufferGlyph(ScreenPtr         pScreen,
+exaBufferGlyph(ExaScreenPrivPtr  pExaScr,
 	       ExaGlyphBufferPtr buffer,
 	       GlyphPtr          pGlyph,
 	       PicturePtr        pSrc,
@@ -549,7 +555,7 @@ exaBufferGlyph(ScreenPtr         pScreen,
 	       INT16             xDst,
 	       INT16             yDst)
 {
-    ExaScreenPriv(pScreen);
+    ScreenPtr pScreen = pExaScr->pScreen;
     unsigned int format = (GlyphPicture(pGlyph)[pScreen->myNum])->format;
     int width = pGlyph->info.width;
     int height = pGlyph->info.height;
@@ -569,7 +575,7 @@ exaBufferGlyph(ScreenPtr         pScreen,
 	if (format == cache->format &&
 	    width <= cache->glyphWidth &&
 	    height <= cache->glyphHeight) {
-	    ExaGlyphCacheResult result = exaGlyphCacheBufferGlyph(pScreen,
+	    ExaGlyphCacheResult result = exaGlyphCacheBufferGlyph(pExaScr,
 								  &pExaScr->glyphCaches[i],
 								  buffer,
 								  pGlyph,
@@ -595,6 +601,7 @@ exaBufferGlyph(ScreenPtr         pScreen,
 	return ExaGlyphNeedFlush;
 
     buffer->mask = mask;
+    buffer->examask = ExaGetPixmapPriv((PixmapPtr)mask->pDrawable);
 
     rect = &buffer->rects[buffer->count];
     rect->xSrc = xSrc;
@@ -612,23 +619,28 @@ exaBufferGlyph(ScreenPtr         pScreen,
 }
 
 static void
-exaGlyphsToMask(PicturePtr        pMask,
+exaGlyphsToMask(ExaScreenPrivPtr  pExaScr,
+		PicturePtr        pMask,
+		ExaPixmapPrivPtr  pExaMask,
 		ExaGlyphBufferPtr buffer)
 {
-    exaCompositeRects(PictOpAdd, buffer->mask, NULL, pMask,
-		      buffer->count, buffer->rects);
+    exaCompositeRects(pExaScr, PictOpAdd, buffer->mask, buffer->examask, NULL,
+		      NULL, pMask, pExaMask, buffer->count, buffer->rects);
     
     buffer->count = 0;
     buffer->mask = NULL;
 }
 
 static void
-exaGlyphsToDst(PicturePtr	 pSrc,
+exaGlyphsToDst(ExaScreenPrivPtr	 pExaScr,
+	       PicturePtr	 pSrc,
+	       ExaPixmapPrivPtr  pExaSrc,
 	       PicturePtr	 pDst,
+	       ExaPixmapPrivPtr  pExaDst,
 	       ExaGlyphBufferPtr buffer)
 {
-    exaCompositeRects(PictOpOver, pSrc, buffer->mask, pDst, buffer->count,
-		      buffer->rects);
+    exaCompositeRects(pExaScr, PictOpOver, pSrc, pExaSrc, buffer->mask,
+		      buffer->examask, pDst, pExaDst, buffer->count, buffer->rects);
     
     buffer->count = 0;
     buffer->mask = NULL;
@@ -701,7 +713,9 @@ exaGlyphs (CARD8 	 op,
     PicturePtr	pPicture;
     PixmapPtr   pMaskPixmap = 0;
     PicturePtr  pMask = NULL;
+    ExaPixmapPrivPtr pExaSrc, pExaMask = NULL, pExaDst;
     ScreenPtr   pScreen = pDst->pDrawable->pScreen;
+    ExaScreenPriv(pScreen);
     int		width = 0, height = 0;
     int		x, y;
     int		xDst = list->xOff, yDst = list->yOff;
@@ -745,6 +759,9 @@ exaGlyphs (CARD8 	 op,
 	    (*pScreen->DestroyPixmap) (pMaskPixmap);
 	    return;
 	}
+
+	pExaMask = ExaGetPixmapPriv(pMaskPixmap);
+
 	pGC = GetScratchGC (pMaskPixmap->drawable.depth, pScreen);
 	ValidateGC (&pMaskPixmap->drawable, pGC);
 	rect.x = 0;
@@ -761,6 +778,10 @@ exaGlyphs (CARD8 	 op,
 	x = 0;
 	y = 0;
     }
+
+    pExaDst = ExaGetPixmapPriv(exaGetDrawablePixmap(pDst->pDrawable));
+    pExaSrc = ExaGetPixmapPriv(exaGetDrawablePixmap(pSrc->pDrawable));
+
     buffer.count = 0;
     buffer.mask = NULL;
     while (nlist--)
@@ -777,23 +798,24 @@ exaGlyphs (CARD8 	 op,
 	    {
 		if (maskFormat)
 		{
-		    if (exaBufferGlyph(pScreen, &buffer, glyph, NULL, pMask,
+		    if (exaBufferGlyph(pExaScr, &buffer, glyph, NULL, pMask,
 				       0, 0, 0, 0, x, y) == ExaGlyphNeedFlush)
 		    {
-			exaGlyphsToMask(pMask, &buffer);
-			exaBufferGlyph(pScreen, &buffer, glyph, NULL, pMask,
+			exaGlyphsToMask(pExaScr, pMask, pExaMask, &buffer);
+			exaBufferGlyph(pExaScr, &buffer, glyph, NULL, pMask,
 				       0, 0, 0, 0, x, y);
 		    }
 		}
 		else
 		{
-		    if (exaBufferGlyph(pScreen, &buffer, glyph, pSrc, pDst,
+		    if (exaBufferGlyph(pExaScr, &buffer, glyph, pSrc, pDst,
 				       xSrc + x - xDst, ySrc + y - yDst,
 				       x, y, x + extents.x1, y + extents.y1)
 			== ExaGlyphNeedFlush)
 		    {
-			exaGlyphsToDst(pSrc, pDst, &buffer);
-			exaBufferGlyph(pScreen, &buffer, glyph, pSrc, pDst,
+			exaGlyphsToDst(pExaScr, pSrc, pExaSrc, pDst, pExaDst,
+				       &buffer);
+			exaBufferGlyph(pExaScr, &buffer, glyph, pSrc, pDst,
 				       xSrc + x - xDst, ySrc + y - yDst,
 				       x, y, x + extents.x1, y + extents.y1);
 		    }
@@ -808,9 +830,9 @@ exaGlyphs (CARD8 	 op,
     
     if (buffer.count) {
         if (maskFormat)
-	    exaGlyphsToMask(pMask, &buffer);
+	    exaGlyphsToMask(pExaScr, pMask, pExaMask, &buffer);
         else
-	    exaGlyphsToDst(pSrc, pDst, &buffer);
+	    exaGlyphsToDst(pExaScr, pSrc, pExaSrc, pDst, pExaDst, &buffer);
     }
 
     if (maskFormat)
diff --git a/exa/exa_migration.c b/exa/exa_migration.c
index 9d0eda0..e5097cf 100644
--- a/exa/exa_migration.c
+++ b/exa/exa_migration.c
@@ -48,10 +48,8 @@
  * pinned).
  */
 static Bool
-exaPixmapIsPinned (PixmapPtr pPix)
+exaPixmapIsPinned (ExaPixmapPrivPtr pExaPixmap)
 {
-    ExaPixmapPriv (pPix);
-
     return pExaPixmap == NULL || pExaPixmap->score == EXA_PIXMAP_SCORE_PINNED;
 }
 
@@ -82,10 +80,8 @@ exaMemcpyBox (PixmapPtr pPixmap, BoxPtr pbox, CARD8 *src, int src_pitch,
  * dirtiness.
  */
 static Bool
-exaPixmapIsDirty (PixmapPtr pPix)
+exaPixmapIsDirty (ExaPixmapPrivPtr pExaPixmap)
 {
-    ExaPixmapPriv (pPix);
-
     return pExaPixmap == NULL ||
 	REGION_NOTEMPTY (pScreen, DamageRegion(pExaPixmap->pDamage)) ||
 	!REGION_EQUAL(pScreen, &pExaPixmap->validSys, &pExaPixmap->validFB);
@@ -99,11 +95,9 @@ exaPixmapIsDirty (PixmapPtr pPix)
  * Only valid if using a migration scheme that tracks score.
  */
 static Bool
-exaPixmapShouldBeInFB (PixmapPtr pPix)
+exaPixmapShouldBeInFB (ExaPixmapPrivPtr pExaPixmap)
 {
-    ExaPixmapPriv (pPix);
-
-    if (exaPixmapIsPinned (pPix))
+    if (exaPixmapIsPinned (pExaPixmap))
 	return TRUE;
 
     return pExaPixmap->score >= 0;
@@ -120,8 +114,9 @@ exaCopyDirty(ExaMigrationPtr migrate, RegionPtr pValidDst, RegionPtr pValidSrc,
 	     CARD8 *fallback_dst, int fallback_srcpitch, int fallback_dstpitch,
 	     int fallback_index, void (*sync) (ScreenPtr pScreen))
 {
-    PixmapPtr pPixmap = migrate->pPix;
-    ExaPixmapPriv (pPixmap);
+    ExaScreenPrivPtr pExaScr = migrate->pExaScr;
+    ExaPixmapPrivPtr pExaPixmap = migrate->pExaPix;
+    PixmapPtr pPixmap = pExaPixmap->pPixmap;
     RegionPtr damage = DamageRegion (pExaPixmap->pDamage);
     RegionRec CopyReg;
     Bool save_offscreen;
@@ -132,7 +127,7 @@ exaCopyDirty(ExaMigrationPtr migrate, RegionPtr pValidDst, RegionPtr pValidSrc,
     Bool need_sync = FALSE;
 
     /* Damaged bits are valid in current copy but invalid in other one */
-    if (exaPixmapIsOffscreen(pPixmap)) {
+    if (exaPixmapIsOffscreen(pExaScr, pExaPixmap)) {
 	REGION_UNION(pScreen, &pExaPixmap->validFB, &pExaPixmap->validFB,
 		     damage);
 	REGION_SUBTRACT(pScreen, &pExaPixmap->validSys, &pExaPixmap->validSys,
@@ -237,7 +232,8 @@ exaCopyDirty(ExaMigrationPtr migrate, RegionPtr pValidDst, RegionPtr pValidSrc,
 				    pExaPixmap->sys_pitch))
 	{
 	    if (!access_prepared) {
-		ExaDoPrepareAccess(&pPixmap->drawable, fallback_index);
+		ExaDoPrepareAccess(pExaScr, &pPixmap->drawable, pExaPixmap,
+				   fallback_index);
 		access_prepared = TRUE;
 	    }
 	    exaMemcpyBox (pPixmap, pBox,
@@ -250,7 +246,8 @@ exaCopyDirty(ExaMigrationPtr migrate, RegionPtr pValidDst, RegionPtr pValidSrc,
     }
 
     if (access_prepared)
-	exaFinishAccess(&pPixmap->drawable, fallback_index);
+	exaFinishAccess(pExaScr, &pPixmap->drawable, pExaPixmap,
+			fallback_index);
     else if (need_sync && sync)
 	sync (pPixmap->drawable.pScreen);
 
@@ -278,12 +275,10 @@ exaCopyDirty(ExaMigrationPtr migrate, RegionPtr pValidDst, RegionPtr pValidSrc,
 static void
 exaCopyDirtyToSys (ExaMigrationPtr migrate)
 {
-    PixmapPtr pPixmap = migrate->pPix;
-    ExaScreenPriv (pPixmap->drawable.pScreen);
-    ExaPixmapPriv (pPixmap);
+    ExaPixmapPrivPtr pExaPixmap = migrate->pExaPix;
 
     exaCopyDirty(migrate, &pExaPixmap->validSys, &pExaPixmap->validFB,
-		 pExaScr->info->DownloadFromScreen, pExaPixmap->fb_ptr,
+		 migrate->pExaScr->info->DownloadFromScreen, pExaPixmap->fb_ptr,
 		 pExaPixmap->sys_ptr, pExaPixmap->fb_pitch,
 		 pExaPixmap->sys_pitch, EXA_PREPARE_SRC, exaWaitSync);
 }
@@ -296,12 +291,10 @@ exaCopyDirtyToSys (ExaMigrationPtr migrate)
 static void
 exaCopyDirtyToFb (ExaMigrationPtr migrate)
 {
-    PixmapPtr pPixmap = migrate->pPix;
-    ExaScreenPriv (pPixmap->drawable.pScreen);
-    ExaPixmapPriv (pPixmap);
+    ExaPixmapPrivPtr pExaPixmap = migrate->pExaPix;
 
     exaCopyDirty(migrate, &pExaPixmap->validFB, &pExaPixmap->validSys,
-		 pExaScr->info->UploadToScreen, pExaPixmap->sys_ptr,
+		 migrate->pExaScr->info->UploadToScreen, pExaPixmap->sys_ptr,
 		 pExaPixmap->fb_ptr, pExaPixmap->sys_pitch,
 		 pExaPixmap->fb_pitch, EXA_PREPARE_DEST, NULL);
 }
@@ -324,17 +317,16 @@ exaCopyDirtyToFb (ExaMigrationPtr migrate)
 static void
 exaDoMoveInPixmap (ExaMigrationPtr migrate)
 {
-    PixmapPtr pPixmap = migrate->pPix;
-    ScreenPtr pScreen = pPixmap->drawable.pScreen;
-    ExaScreenPriv (pScreen);
-    ExaPixmapPriv (pPixmap);
+    ExaScreenPrivPtr pExaScr = migrate->pExaScr;
+    ExaPixmapPrivPtr pExaPixmap = migrate->pExaPix;
+    PixmapPtr pPixmap = pExaPixmap->pPixmap;
 
     /* If we're VT-switched away, no touching card memory allowed. */
     if (pExaScr->swappedOut)
 	return;
 
     /* If we're not allowed to move, then fail. */
-    if (exaPixmapIsPinned(pPixmap))
+    if (exaPixmapIsPinned(pExaPixmap))
 	return;
 
     /* Don't migrate in pixmaps which are less than 8bpp.  This avoids a lot of
@@ -349,7 +341,7 @@ exaDoMoveInPixmap (ExaMigrationPtr migrate)
 
     if (pExaPixmap->area == NULL) {
 	pExaPixmap->area =
-	    exaOffscreenAlloc (pScreen, pExaPixmap->fb_size,
+	    exaOffscreenAlloc (pExaScr->pScreen, pExaPixmap->fb_size,
 			       pExaScr->info->pixmapOffsetAlign, FALSE,
                                exaPixmapSave, (pointer) pPixmap);
 	if (pExaPixmap->area == NULL)
@@ -361,7 +353,7 @@ exaDoMoveInPixmap (ExaMigrationPtr migrate)
 
     exaCopyDirtyToFb (migrate);
 
-    if (exaPixmapIsOffscreen(pPixmap))
+    if (exaPixmapIsOffscreen(pExaScr, pExaPixmap))
 	return;
 
     DBG_MIGRATE (("-> %p (0x%x) (%dx%d) (%c)\n", pPixmap,
@@ -369,7 +361,7 @@ exaDoMoveInPixmap (ExaMigrationPtr migrate)
                    ExaGetPixmapPriv(pPixmap)->area->offset : 0),
 		  pPixmap->drawable.width,
 		  pPixmap->drawable.height,
-		  exaPixmapIsDirty(pPixmap) ? 'd' : 'c'));
+		  exaPixmapIsDirty(pExaPixmap) ? 'd' : 'c'));
 
     pExaPixmap->offscreen = TRUE;
 
@@ -383,7 +375,8 @@ exaMoveInPixmap (PixmapPtr pPixmap)
     static ExaMigrationRec migrate = { .as_dst = FALSE, .as_src = TRUE,
 				       .pReg = NULL };
 
-    migrate.pPix = pPixmap;
+    migrate.pExaScr = ExaGetScreenPriv(pPixmap->drawable.pScreen);
+    migrate.pExaPix = ExaGetPixmapPriv(pPixmap);
     exaDoMoveInPixmap (&migrate);
 }
 
@@ -394,22 +387,21 @@ exaMoveInPixmap (PixmapPtr pPixmap)
 static void
 exaDoMoveOutPixmap (ExaMigrationPtr migrate)
 {
-    PixmapPtr pPixmap = migrate->pPix;
-    ExaPixmapPriv (pPixmap);
+    ExaPixmapPrivPtr pExaPixmap = migrate->pExaPix;
+    PixmapPtr pPixmap = pExaPixmap->pPixmap;
 
-    if (!pExaPixmap->area || exaPixmapIsPinned(pPixmap))
+    if (!pExaPixmap->area || exaPixmapIsPinned(pExaPixmap))
 	return;
 
     exaCopyDirtyToSys (migrate);
 
-    if (exaPixmapIsOffscreen(pPixmap)) {
+    if (exaPixmapIsOffscreen(migrate->pExaScr, pExaPixmap)) {
 
 	DBG_MIGRATE (("<- %p (%p) (%dx%d) (%c)\n", pPixmap,
-		      (void*)(ExaGetPixmapPriv(pPixmap)->area ?
-			      ExaGetPixmapPriv(pPixmap)->area->offset : 0),
+		      (void*)(pExaPixmap->area ? pExaPixmap->area->offset : 0),
 		      pPixmap->drawable.width,
 		      pPixmap->drawable.height,
-		      exaPixmapIsDirty(pPixmap) ? 'd' : 'c'));
+		      exaPixmapIsDirty(pExaPixmap) ? 'd' : 'c'));
 
 	pExaPixmap->offscreen = FALSE;
 
@@ -424,7 +416,8 @@ exaMoveOutPixmap (PixmapPtr pPixmap)
     static ExaMigrationRec migrate = { .as_dst = FALSE, .as_src = TRUE,
 				       .pReg = NULL };
 
-    migrate.pPix = pPixmap;
+    migrate.pExaScr = ExaGetScreenPriv(pPixmap->drawable.pScreen);
+    migrate.pExaPix = ExaGetPixmapPriv(pPixmap);
     exaDoMoveOutPixmap (&migrate);
 }
 
@@ -457,13 +450,13 @@ exaPixmapSave (ScreenPtr pScreen, ExaOffscreenArea *area)
 static void
 exaMigrateTowardFb (ExaMigrationPtr migrate)
 {
-    PixmapPtr pPixmap = migrate->pPix;
-    ExaPixmapPriv (pPixmap);
+    ExaScreenPrivPtr pExaScr = migrate->pExaScr;
+    ExaPixmapPrivPtr pExaPixmap = migrate->pExaPix;
 
     if (pExaPixmap == NULL) {
 	DBG_MIGRATE(("UseScreen: ignoring exa-uncontrolled pixmap %p (%s)\n",
-		     (pointer)pPixmap,
-		     exaPixmapIsOffscreen(pPixmap) ? "s" : "m"));
+		     (pointer)pExaPixmap->pPixmap,
+		     exaPixmapIsOffscreen(pExaScr, pExaPixmap) ? "s" : "m"));
 	return;
     }
 
@@ -485,14 +478,14 @@ exaMigrateTowardFb (ExaMigrationPtr migrate)
 	pExaPixmap->score++;
 
     if (pExaPixmap->score >= EXA_PIXMAP_SCORE_MOVE_IN &&
-	!exaPixmapIsOffscreen(pPixmap))
+	!exaPixmapIsOffscreen(pExaScr, pExaPixmap))
     {
 	exaDoMoveInPixmap(migrate);
     }
 
-    if (exaPixmapIsOffscreen(pPixmap)) {
+    if (exaPixmapIsOffscreen(pExaScr, pExaPixmap)) {
 	exaCopyDirtyToFb (migrate);
-	ExaOffscreenMarkUsed (pPixmap);
+	ExaOffscreenMarkUsed (pExaPixmap->pPixmap);
     } else
 	exaCopyDirtyToSys (migrate);
 }
@@ -504,13 +497,13 @@ exaMigrateTowardFb (ExaMigrationPtr migrate)
 static void
 exaMigrateTowardSys (ExaMigrationPtr migrate)
 {
-    PixmapPtr pPixmap = migrate->pPix;
-    ExaPixmapPriv (pPixmap);
+    ExaScreenPrivPtr pExaScr = migrate->pExaScr;
+    ExaPixmapPrivPtr pExaPixmap = migrate->pExaPix;
 
     if (pExaPixmap == NULL) {
 	DBG_MIGRATE(("UseMem: ignoring exa-uncontrolled pixmap %p (%s)\n",
-		     (pointer)pPixmap,
-		     exaPixmapIsOffscreen(pPixmap) ? "s" : "m"));
+		     (pointer)pExaPixmap->pPixmap,
+		     exaPixmapIsOffscreen(pExaScr, pExaPixmap) ? "s" : "m"));
 	return;
     }
 
@@ -528,9 +521,9 @@ exaMigrateTowardSys (ExaMigrationPtr migrate)
     if (pExaPixmap->score <= EXA_PIXMAP_SCORE_MOVE_OUT && pExaPixmap->area)
 	exaDoMoveOutPixmap(migrate);
 
-    if (exaPixmapIsOffscreen(pPixmap)) {
+    if (exaPixmapIsOffscreen(pExaScr, pExaPixmap)) {
 	exaCopyDirtyToFb (migrate);
-	ExaOffscreenMarkUsed (pPixmap);
+	ExaOffscreenMarkUsed (pExaPixmap->pPixmap);
     } else
 	exaCopyDirtyToSys (migrate);
 }
@@ -540,16 +533,16 @@ exaMigrateTowardSys (ExaMigrationPtr migrate)
  * asserts that both of them are the same.
  */
 static Bool
-exaAssertNotDirty (PixmapPtr pPixmap)
+exaAssertNotDirty (ExaScreenPrivPtr pExaScr, ExaPixmapPrivPtr pExaPixmap)
 {
-    ExaPixmapPriv (pPixmap);
+    PixmapPtr pPixmap = pExaPixmap->pPixmap;
     CARD8 *dst, *src;
     RegionRec ValidReg;
     int dst_pitch, src_pitch, cpp, y, nbox;
     BoxPtr pBox;
     Bool ret = TRUE;
 
-    if (exaPixmapIsPinned(pPixmap) || pExaPixmap->area == NULL)
+    if (exaPixmapIsPinned(pExaPixmap) || pExaPixmap->area == NULL)
 	return ret;
 
     REGION_NULL(pScreen, &ValidReg);
@@ -566,7 +559,8 @@ exaAssertNotDirty (PixmapPtr pPixmap)
     src_pitch = pExaPixmap->fb_pitch;
     cpp = pPixmap->drawable.bitsPerPixel / 8;
 
-    ExaDoPrepareAccess(&pPixmap->drawable, EXA_PREPARE_SRC);
+    ExaDoPrepareAccess(pExaScr, &pPixmap->drawable, pExaPixmap,
+		       EXA_PREPARE_SRC);
     while (nbox--) {
 	    int rowbytes;
 
@@ -586,13 +580,13 @@ exaAssertNotDirty (PixmapPtr pPixmap)
 		 y++, src += src_pitch, dst += dst_pitch) {
 		if (memcmp(dst, src, rowbytes) != 0) {
 		    ret = FALSE;
-		    exaPixmapDirty(pPixmap, pBox->x1, pBox->y1, pBox->x2,
+		    exaPixmapDirty(pExaPixmap, pBox->x1, pBox->y1, pBox->x2,
 				   pBox->y2);
 		    break;
 		}
 	    }
     }
-    exaFinishAccess(&pPixmap->drawable, EXA_PREPARE_SRC);
+    exaFinishAccess(pExaScr, &pPixmap->drawable, pExaPixmap, EXA_PREPARE_SRC);
 
 out:
     REGION_UNINIT(pScreen, &ValidReg);
@@ -607,8 +601,7 @@ out:
 void
 exaDoMigration (ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel)
 {
-    ScreenPtr pScreen = pixmaps[0].pPix->drawable.pScreen;
-    ExaScreenPriv(pScreen);
+    ExaScreenPrivPtr pExaScr = pixmaps[0].pExaScr;
     int i, j;
 
     if (pExaScr->info->flags & EXA_HANDLES_PIXMAPS)
@@ -623,8 +616,8 @@ exaDoMigration (ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel)
      */
     if (pExaScr->checkDirtyCorrectness) {
 	for (i = 0; i < npixmaps; i++) {
-	    if (!exaPixmapIsDirty (pixmaps[i].pPix) &&
-		!exaAssertNotDirty (pixmaps[i].pPix))
+	    if (!exaPixmapIsDirty (pixmaps[i].pExaPix) &&
+		!exaAssertNotDirty (pExaScr, pixmaps[i].pExaPix))
 		ErrorF("%s: Pixmap %d dirty but not marked as such!\n", __func__, i);
 	}
     }
@@ -632,12 +625,12 @@ exaDoMigration (ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel)
      * accelerate.
      */
     for (i = 0; i < npixmaps; i++) {
-	if (exaPixmapIsPinned (pixmaps[i].pPix) &&
-	    !exaPixmapIsOffscreen (pixmaps[i].pPix))
+	if (exaPixmapIsPinned (pixmaps[i].pExaPix) &&
+	    !exaPixmapIsOffscreen (pExaScr, pixmaps[i].pExaPix))
 	{
-	    EXA_FALLBACK(("Pixmap %p (%dx%d) pinned in sys\n", pixmaps[i].pPix,
-		      pixmaps[i].pPix->drawable.width,
-		      pixmaps[i].pPix->drawable.height));
+	    EXA_FALLBACK(("Pixmap %p (%dx%d) pinned in sys\n", pixmaps[i].pExaPix,
+		      pixmaps[i].pExaPix->pPixmap->drawable.width,
+		      pixmaps[i].pExaPix->pPixmap->drawable.height));
 	    can_accel = FALSE;
 	    break;
 	}
@@ -648,11 +641,11 @@ exaDoMigration (ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel)
 	 * become newly dirtied, take the unaccelerated route.
 	 */
 	for (i = 0; i < npixmaps; i++) {
-	    if (pixmaps[i].as_dst && !exaPixmapShouldBeInFB (pixmaps[i].pPix) &&
-		!exaPixmapIsDirty (pixmaps[i].pPix))
+	    if (pixmaps[i].as_dst && !exaPixmapShouldBeInFB (pixmaps[i].pExaPix) &&
+		!exaPixmapIsDirty (pixmaps[i].pExaPix))
 	    {
 		for (i = 0; i < npixmaps; i++) {
-		    if (!exaPixmapIsDirty (pixmaps[i].pPix))
+		    if (!exaPixmapIsDirty (pixmaps[i].pExaPix))
 			exaDoMoveOutPixmap (pixmaps + i);
 		}
 		return;
@@ -665,7 +658,7 @@ exaDoMigration (ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel)
 	if (!can_accel) {
 	    for (i = 0; i < npixmaps; i++) {
 		exaMigrateTowardSys (pixmaps + i);
-		if (!exaPixmapIsDirty (pixmaps[i].pPix))
+		if (!exaPixmapIsDirty (pixmaps[i].pExaPix))
 		    exaDoMoveOutPixmap (pixmaps + i);
 	    }
 	    return;
@@ -695,7 +688,7 @@ exaDoMigration (ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel)
 	}
 
 	for (i = 0; i < npixmaps; i++) {
-	    if (exaPixmapIsOffscreen(pixmaps[i].pPix)) {
+	    if (exaPixmapIsOffscreen(pExaScr, pixmaps[i].pExaPix)) {
 		/* Found one in FB, so move all to FB. */
 		for (j = 0; j < npixmaps; j++)
 		    exaMigrateTowardFb(pixmaps + i);
@@ -724,14 +717,14 @@ exaDoMigration (ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel)
 
 	/* If we couldn't fit everything in, abort */
 	for (i = 0; i < npixmaps; i++) {
-	    if (!exaPixmapIsOffscreen(pixmaps[i].pPix)) {
+	    if (!exaPixmapIsOffscreen(pExaScr, pixmaps[i].pExaPix)) {
 		return;
 	    }
 	}
 
 	/* Yay, everything's offscreen, mark memory as used */
 	for (i = 0; i < npixmaps; i++) {
-	    ExaOffscreenMarkUsed (pixmaps[i].pPix);
+	    ExaOffscreenMarkUsed (pixmaps[i].pExaPix->pPixmap);
 	}
     }
 }
diff --git a/exa/exa_offscreen.c b/exa/exa_offscreen.c
index 95d5e43..d28031e 100644
--- a/exa/exa_offscreen.c
+++ b/exa/exa_offscreen.c
@@ -40,9 +40,8 @@
 
 #if DEBUG_OFFSCREEN
 static void
-ExaOffscreenValidate (ScreenPtr pScreen)
+ExaOffscreenValidate (ExaScreenPrivPtr pExaScr)
 {
-    ExaScreenPriv (pScreen);
     ExaOffscreenArea *prev = 0, *area;
 
     assert (pExaScr->info->offScreenAreas->base_offset == 
@@ -221,7 +220,7 @@ exaOffscreenAlloc (ScreenPtr pScreen, int size, int align,
     }
 
     if (!area && free_total >= size) {
-	area = ExaOffscreenDefragment(pScreen);
+	area = ExaOffscreenDefragment(pExaScr);
 
 	if (area) {
 	    /* adjust size to match alignment requirement */
@@ -322,11 +321,9 @@ exaOffscreenAlloc (ScreenPtr pScreen, int size, int align,
 
 /** Ejects all pixmaps managed by EXA. */
 static void
-ExaOffscreenEjectPixmaps (ScreenPtr pScreen)
+ExaOffscreenEjectPixmaps (ExaScreenPrivPtr pExaScr)
 {
-    ExaScreenPriv (pScreen);
-
-    ExaOffscreenValidate (pScreen);
+    ExaOffscreenValidate (pExaScr);
     /* loop until a single free area spans the space */
     for (;;)
     {
@@ -338,15 +335,15 @@ ExaOffscreenEjectPixmaps (ScreenPtr pScreen)
 	    if (area->state == ExaOffscreenRemovable &&
 		area->save == exaPixmapSave)
 	    {
-		(void) ExaOffscreenKickOut (pScreen, area);
-		ExaOffscreenValidate (pScreen);
+		(void) ExaOffscreenKickOut (pExaScr->pScreen, area);
+		ExaOffscreenValidate (pExaScr);
 		break;
 	    }
 	}
 	if (area == NULL)
 	    break;
     }
-    ExaOffscreenValidate (pScreen);
+    ExaOffscreenValidate (pExaScr);
 }
 
 /**
@@ -365,7 +362,7 @@ exaEnableDisableFBAccess (int index, Bool enable)
     ExaScreenPriv (pScreen);
 
     if (!enable && pExaScr->disableFbCount++ == 0) {
-	ExaOffscreenEjectPixmaps (pScreen);
+	ExaOffscreenEjectPixmaps(pExaScr);
 	pExaScr->swappedOut = TRUE;
     }
     
@@ -461,9 +458,9 @@ ExaOffscreenMarkUsed (PixmapPtr pPixmap)
  * beginning (when there are no pinned allocations).
  */
 _X_HIDDEN ExaOffscreenArea*
-ExaOffscreenDefragment (ScreenPtr pScreen)
+ExaOffscreenDefragment (ExaScreenPrivPtr pExaScr)
 {
-    ExaScreenPriv (pScreen);
+    ScreenPtr pScreen = pExaScr->pScreen;
     ExaOffscreenArea *area, *largest_available = NULL;
     int largest_size = 0;
     PixmapPtr pDstPix;
@@ -633,9 +630,8 @@ ExaOffscreenDefragment (ScreenPtr pScreen)
  * the screen, if any offscreen memory is available.
  */
 Bool
-exaOffscreenInit (ScreenPtr pScreen)
+exaOffscreenInit (ExaScreenPrivPtr pExaScr)
 {
-    ExaScreenPriv (pScreen);
     ExaOffscreenArea *area;
 
     /* Allocate a big free area */
@@ -659,15 +655,14 @@ exaOffscreenInit (ScreenPtr pScreen)
     pExaScr->info->offScreenAreas = area;
     pExaScr->offScreenCounter = 1;
 
-    ExaOffscreenValidate (pScreen);
+    ExaOffscreenValidate (pExaScr);
 
     return TRUE;
 }
 
 void
-ExaOffscreenFini (ScreenPtr pScreen)
+ExaOffscreenFini (ExaScreenPrivPtr pExaScr)
 {
-    ExaScreenPriv (pScreen);
     ExaOffscreenArea *area;
 
     /* just free all of the area records */
diff --git a/exa/exa_priv.h b/exa/exa_priv.h
index 3bfdcda..34e6d95 100644
--- a/exa/exa_priv.h
+++ b/exa/exa_priv.h
@@ -96,6 +96,47 @@ enum ExaMigrationHeuristic {
 };
 
 typedef struct {
+    PixmapPtr	    pPixmap;
+    ExaOffscreenArea *area;
+    int		    score;	/**< score for the move-in vs move-out heuristic */
+    Bool	    offscreen;
+
+    CARD8	    *sys_ptr;	/**< pointer to pixmap data in system memory */
+    int		    sys_pitch;	/**< pitch of pixmap in system memory */
+
+    CARD8	    *fb_ptr;	/**< pointer to pixmap data in framebuffer memory */
+    int		    fb_pitch;	/**< pitch of pixmap in framebuffer memory */
+    unsigned int    fb_size;	/**< size of pixmap in framebuffer memory */
+
+    /**
+     * Holds information about whether this pixmap can be used for
+     * acceleration (== 0) or not (> 0).
+     *
+     * Contains a OR'ed combination of the following values:
+     * EXA_RANGE_PITCH - set if the pixmap's pitch is out of range
+     * EXA_RANGE_WIDTH - set if the pixmap's width is out of range
+     * EXA_RANGE_HEIGHT - set if the pixmap's height is out of range
+     */
+    unsigned int    accel_blocked;
+
+    /**
+     * The damage record contains the areas of the pixmap's current location
+     * (framebuffer or system) that have been damaged compared to the other
+     * location.
+     */
+    DamagePtr	    pDamage;
+    /**
+     * The valid regions mark the valid bits (at least, as they're derived from
+     * damage, which may be overreported) of a pixmap's system and FB copies.
+     */
+    RegionRec	    validSys, validFB;
+    /**
+     * Driver private storage per EXA pixmap
+     */
+    void *driverPriv;
+} ExaPixmapPrivRec, *ExaPixmapPrivPtr;
+
+typedef struct {
     unsigned char sha1[20];
 } ExaCachedGlyphRec, *ExaCachedGlyphPtr;
 
@@ -120,6 +161,7 @@ typedef struct {
     int glyphCount; /* Current number of glyphs */
     
     PicturePtr picture;   /* Where the glyphs of the cache are stored */
+    ExaPixmapPrivPtr exapix; /* Pointer to EXA private data of the corresponding pixmap */
     int yOffset;          /* y location within the picture where the cache starts */
     int columns;          /* Number of columns the glyphs are layed out in */
     int evictionPosition; /* Next random position to evict a glyph */
@@ -133,6 +175,7 @@ typedef struct {
 typedef void (*EnableDisableFBAccessProcPtr)(int, Bool);
 typedef struct {
     ExaDriverPtr info;
+    ScreenPtr 			 pScreen;
     ScreenBlockHandlerProcPtr	 SavedBlockHandler;
     ScreenWakeupHandlerProcPtr	 SavedWakeupHandler;
     CreateGCProcPtr 		 SavedCreateGC;
@@ -239,46 +282,6 @@ extern DevPrivateKey exaGCPrivateKey;
 #define EXA_RANGE_HEIGHT (1 << 2)
 
 typedef struct {
-    ExaOffscreenArea *area;
-    int		    score;	/**< score for the move-in vs move-out heuristic */
-    Bool	    offscreen;
-
-    CARD8	    *sys_ptr;	/**< pointer to pixmap data in system memory */
-    int		    sys_pitch;	/**< pitch of pixmap in system memory */
-
-    CARD8	    *fb_ptr;	/**< pointer to pixmap data in framebuffer memory */
-    int		    fb_pitch;	/**< pitch of pixmap in framebuffer memory */
-    unsigned int    fb_size;	/**< size of pixmap in framebuffer memory */
-
-    /**
-     * Holds information about whether this pixmap can be used for
-     * acceleration (== 0) or not (> 0).
-     *
-     * Contains a OR'ed combination of the following values:
-     * EXA_RANGE_PITCH - set if the pixmap's pitch is out of range
-     * EXA_RANGE_WIDTH - set if the pixmap's width is out of range
-     * EXA_RANGE_HEIGHT - set if the pixmap's height is out of range
-     */
-    unsigned int    accel_blocked;
-
-    /**
-     * The damage record contains the areas of the pixmap's current location
-     * (framebuffer or system) that have been damaged compared to the other
-     * location.
-     */
-    DamagePtr	    pDamage;
-    /**
-     * The valid regions mark the valid bits (at least, as they're derived from
-     * damage, which may be overreported) of a pixmap's system and FB copies.
-     */
-    RegionRec	    validSys, validFB;
-    /**
-     * Driver private storage per EXA pixmap
-     */
-    void *driverPriv;
-} ExaPixmapPrivRec, *ExaPixmapPrivPtr;
-
-typedef struct {
     /* GC values from the layer below. */
     GCOps *Savedops;
     GCFuncs *Savedfuncs;
@@ -287,7 +290,8 @@ typedef struct {
 typedef struct _ExaMigrationRec {
     Bool as_dst;
     Bool as_src;
-    PixmapPtr pPix;
+    ExaScreenPrivPtr pExaScr;
+    ExaPixmapPrivPtr pExaPix;
     RegionPtr pReg;
 } ExaMigrationRec, *ExaMigrationPtr;
 
@@ -311,32 +315,37 @@ void exaDDXDriverInit (ScreenPtr pScreen);
 
 /* exa_unaccel.c */
 void
-exaPrepareAccessGC(GCPtr pGC);
+exaPrepareAccessGC(ExaScreenPrivPtr pExaScr, GCPtr pGC);
 
 void
-exaFinishAccessGC(GCPtr pGC);
+exaFinishAccessGC(ExaScreenPrivPtr pExaScr, GCPtr pGC);
 
 void
-ExaCheckFillSpans  (DrawablePtr pDrawable, GCPtr pGC, int nspans,
-		   DDXPointPtr ppt, int *pwidth, int fSorted);
+ExaCheckFillSpans(ExaScreenPrivPtr pExaScr, DrawablePtr pDrawable,
+		  ExaPixmapPrivPtr pExaPixmap, GCPtr pGC, int nspans,
+		  DDXPointPtr ppt, int *pwidth, int fSorted);
 
 void
 ExaCheckSetSpans (DrawablePtr pDrawable, GCPtr pGC, char *psrc,
 		 DDXPointPtr ppt, int *pwidth, int nspans, int fSorted);
 
 void
-ExaCheckPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth,
-		 int x, int y, int w, int h, int leftPad, int format,
-		 char *bits);
+ExaCheckPutImage(ExaScreenPrivPtr pExaScr, DrawablePtr pDrawable,
+		 ExaPixmapPrivPtr pExaPixmap, GCPtr pGC, int depth, int x, int y,
+		 int w, int h, int leftPad, int format, char *bits);
 
 void
-ExaCheckCopyNtoN (DrawablePtr pSrc, DrawablePtr pDst,  GCPtr pGC,
-	     BoxPtr	pbox, int nbox, int dx, int dy, Bool	reverse, 
-	     Bool upsidedown, Pixel bitplane, void *closure);
+ExaCheckCopyNtoN(ExaScreenPrivPtr pExaScr, DrawablePtr pSrc,
+		 ExaPixmapPrivPtr pExaSrcPix, DrawablePtr pDst,
+		 ExaPixmapPrivPtr pExaDstPix, GCPtr pGC, BoxPtr pbox, int nbox,
+		 int dx, int dy, Bool reverse, Bool upsidedown, Pixel bitplane,
+		 void *closure);
 
 RegionPtr
-ExaCheckCopyArea (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
-		 int srcx, int srcy, int w, int h, int dstx, int dsty);
+ExaCheckCopyArea(ExaScreenPrivPtr pExaScr, DrawablePtr pSrc,
+		 ExaPixmapPrivPtr pExaSrcPix, DrawablePtr pDst,
+		 ExaPixmapPrivPtr pExaDstPix, GCPtr pGC, int srcx, int srcy,
+		 int w, int h, int dstx, int dsty);
 
 RegionPtr
 ExaCheckCopyPlane (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
@@ -344,24 +353,28 @@ ExaCheckCopyPlane (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
 		  unsigned long bitPlane);
 
 void
-ExaCheckPolyPoint (DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
+ExaCheckPolyPoint(ExaScreenPrivPtr pExaScr, DrawablePtr pDrawable,
+		  ExaPixmapPrivPtr pExaPixmap, GCPtr pGC, int mode, int npt,
 		  DDXPointPtr pptInit);
 
 void
-ExaCheckPolylines (DrawablePtr pDrawable, GCPtr pGC,
-		  int mode, int npt, DDXPointPtr ppt);
+ExaCheckPolylines(ExaScreenPrivPtr pExaScr, DrawablePtr pDrawable,
+		  ExaPixmapPrivPtr pExaPixmap, GCPtr pGC, int mode, int npt,
+		  DDXPointPtr ppt);
 
 void
-ExaCheckPolySegment (DrawablePtr pDrawable, GCPtr pGC,
-		    int nsegInit, xSegment *pSegInit);
+ExaCheckPolySegment(ExaScreenPrivPtr pExaScr, DrawablePtr pDrawable,
+		    ExaPixmapPrivPtr pExaPixmap, GCPtr pGC, int nsegInit,
+		    xSegment *pSegInit);
 
 void
 ExaCheckPolyArc (DrawablePtr pDrawable, GCPtr pGC,
 		int narcs, xArc *pArcs);
 
 void
-ExaCheckPolyFillRect (DrawablePtr pDrawable, GCPtr pGC,
-		     int nrect, xRectangle *prect);
+ExaCheckPolyFillRect(ExaScreenPrivPtr pExaScr, DrawablePtr pDrawable,
+		     ExaPixmapPrivPtr pExaPixmap, GCPtr pGC, int nrect,
+		     xRectangle *prect);
 
 void
 ExaCheckImageGlyphBlt (DrawablePtr pDrawable, GCPtr pGC,
@@ -379,11 +392,14 @@ ExaCheckPushPixels (GCPtr pGC, PixmapPtr pBitmap,
 		   int w, int h, int x, int y);
 
 void
-ExaCheckCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc);
+ExaCheckCopyWindow(ExaScreenPrivPtr pExaScr, WindowPtr pWin,
+		   ExaPixmapPrivPtr pExaPixmap, DDXPointRec ptOldOrg,
+		   RegionPtr prgnSrc);
 
 void
-ExaCheckGetImage(DrawablePtr pDrawable, int x, int y, int w, int h,
-		unsigned int format, unsigned long planeMask, char *d);
+ExaCheckGetImage(ExaScreenPrivPtr pExaScr, DrawablePtr pDrawable,
+		 ExaPixmapPrivPtr pExaPixmap, int x, int y, int w, int h,
+		 unsigned int format, unsigned long planeMask, char *d);
 
 void
 ExaCheckGetSpans (DrawablePtr pDrawable,
@@ -415,8 +431,10 @@ void
 exaCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc);
 
 Bool
-exaFillRegionTiled (DrawablePtr	pDrawable, RegionPtr pRegion, PixmapPtr pTile,
-		    DDXPointPtr pPatOrg, CARD32 planemask, CARD32 alu);
+exaFillRegionTiled(ExaScreenPrivPtr pExaScr, DrawablePtr pDrawable,
+		   ExaPixmapPrivPtr pExaPixmap, RegionPtr pRegion,
+		   PixmapPtr pTile, ExaPixmapPrivPtr pTileExaPixmap,
+		   DDXPointPtr pPatOrg, CARD32 planemask, CARD32 alu);
 
 void
 exaGetImage (DrawablePtr pDrawable, int x, int y, int w, int h,
@@ -426,55 +444,54 @@ extern const GCOps exaOps;
 
 #ifdef RENDER
 void
-ExaCheckComposite (CARD8      op,
-		  PicturePtr pSrc,
-		  PicturePtr pMask,
-		  PicturePtr pDst,
-		  INT16      xSrc,
-		  INT16      ySrc,
-		  INT16      xMask,
-		  INT16      yMask,
-		  INT16      xDst,
-		  INT16      yDst,
-		  CARD16     width,
-		  CARD16     height);
+ExaCheckComposite(ExaScreenPrivPtr pExaScr, CARD8 op, PicturePtr pSrc,
+		  ExaPixmapPrivPtr pExaSrcPix, PicturePtr pMask,
+		  ExaPixmapPrivPtr pExaMaskPix, PicturePtr pDst,
+		  ExaPixmapPrivPtr pExaDstPix, INT16 xSrc, INT16 ySrc,
+		  INT16 xMask, INT16 yMask, INT16 xDst, INT16 yDst,
+		  CARD16 width, CARD16 height);
 #endif
 
 /* exa_offscreen.c */
 ExaOffscreenArea*
-ExaOffscreenDefragment (ScreenPtr pScreen);
+ExaOffscreenDefragment(ExaScreenPrivPtr pExaScr);
 
 Bool
-exaOffscreenInit(ScreenPtr pScreen);
+exaOffscreenInit(ExaScreenPrivPtr pExaScr);
 
 void
-ExaOffscreenFini (ScreenPtr pScreen);
+ExaOffscreenFini(ExaScreenPrivPtr pExaScr);
 
 /* exa.c */
 void
-ExaDoPrepareAccess(DrawablePtr pDrawable, int index);
+ExaDoPrepareAccess(ExaScreenPrivPtr pExaScr, DrawablePtr pDrawable,
+		   ExaPixmapPrivPtr pExaPixmap, int index);
 
 void
-exaPrepareAccessReg(DrawablePtr pDrawable, int index, RegionPtr pReg);
+exaPrepareAccessReg(ExaScreenPrivPtr pExaScr, DrawablePtr pDrawable,
+		    ExaPixmapPrivPtr pExaPixmap, int index, RegionPtr pReg);
 
 void
-exaPrepareAccess(DrawablePtr pDrawable, int index);
+exaPrepareAccess(ExaScreenPrivPtr pExaScr, DrawablePtr pDrawable,
+		 ExaPixmapPrivPtr pExaPixmap, int index);
 
 void
-exaFinishAccess(DrawablePtr pDrawable, int index);
+exaFinishAccess(ExaScreenPrivPtr pExaScr, DrawablePtr pDrawable,
+		ExaPixmapPrivPtr pExaPixmap, int index);
 
 void
-exaPixmapDirty(PixmapPtr pPix, int x1, int y1, int x2, int y2);
+exaPixmapDirty(ExaPixmapPrivPtr pExaPixmap, int x1, int y1, int x2, int y2);
 
 void
 exaGetDrawableDeltas (DrawablePtr pDrawable, PixmapPtr pPixmap,
 		      int *xp, int *yp);
 
 Bool
-exaPixmapIsOffscreen(PixmapPtr p);
+exaPixmapIsOffscreen(ExaScreenPrivPtr pExaScr, ExaPixmapPrivPtr pExaPixmap);
 
 PixmapPtr
-exaGetOffscreenPixmap (DrawablePtr pDrawable, int *xp, int *yp);
+exaGetOffscreenPixmap(ExaScreenPrivPtr pExaScr, DrawablePtr pDrawable,
+		      ExaPixmapPrivPtr pExaPixmap, int *xp, int *yp);
 
 PixmapPtr
 exaGetDrawablePixmap(DrawablePtr pDrawable);
@@ -484,15 +501,10 @@ exaCopyArea(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC,
 	    int srcx, int srcy, int width, int height, int dstx, int dsty);
 
 Bool
-exaHWCopyNtoN (DrawablePtr    pSrcDrawable,
-	     DrawablePtr    pDstDrawable,
-	     GCPtr	    pGC,
-	     BoxPtr	    pbox,
-	     int	    nbox,
-	     int	    dx,
-	     int	    dy,
-	     Bool	    reverse,
-	     Bool	    upsidedown);
+exaHWCopyNtoN(ExaScreenPrivPtr pExaScr, DrawablePtr pSrcDrawable,
+	      ExaPixmapPrivPtr pExaSrcPix, DrawablePtr pDstDrawable,
+	      ExaPixmapPrivPtr pExaDstPix, GCPtr pGC, BoxPtr pbox, int nbox,
+	      int dx, int dy, Bool reverse, Bool upsidedown);
 
 void
 exaCopyNtoN (DrawablePtr    pSrcDrawable,
@@ -528,10 +540,14 @@ exaComposite(CARD8	op,
 	     CARD16	height);
 
 void
-exaCompositeRects(CARD8	              op,
+exaCompositeRects(ExaScreenPrivPtr    pExaScr,
+		  CARD8	              op,
 		  PicturePtr	      Src,
+		  ExaPixmapPrivPtr    pSrcExaPix,
 		  PicturePtr	      pMask,
+		  ExaPixmapPrivPtr    pMaskExaPix,
 		  PicturePtr	      pDst,
+		  ExaPixmapPrivPtr    pDstExaPix,
 		  int                 nrect,
 		  ExaCompositeRectPtr rects);
 
diff --git a/exa/exa_render.c b/exa/exa_render.c
index d53f13b..81e8c1e 100644
--- a/exa/exa_render.c
+++ b/exa/exa_render.c
@@ -71,7 +71,8 @@ static void exaCompositeFallbackPictDesc(PicturePtr pict, char *string, int n)
 	break;
     }
 
-    loc = exaGetOffscreenPixmap(pict->pDrawable, &temp, &temp) ? 's' : 'm';
+    loc = exaPixmapIsOffscreen(pExaScr,
+	ExaGetPixmapPriv(exaGetDrawablePixmap(pict->pDrawable))) ? 's' : 'm';
 
     snprintf(size, 20, "%dx%d%s", pict->pDrawable->width,
 	     pict->pDrawable->height, pict->repeat ?
@@ -235,8 +236,11 @@ exaGetRGBAFromPixel(CARD32	pixel,
 }
 
 static int
-exaTryDriverSolidFill(PicturePtr	pSrc,
+exaTryDriverSolidFill(ExaScreenPrivPtr	pExaScr,
+		      PicturePtr	pSrc,
+		      ExaPixmapPrivPtr	pSrcExaPix,
 		      PicturePtr	pDst,
+		      ExaPixmapPrivPtr	pDstExaPix,
 		      INT16		xSrc,
 		      INT16		ySrc,
 		      INT16		xDst,
@@ -244,22 +248,17 @@ exaTryDriverSolidFill(PicturePtr	pSrc,
 		      CARD16		width,
 		      CARD16		height)
 {
-    ExaScreenPriv (pDst->pDrawable->pScreen);
     RegionRec region;
     BoxPtr pbox;
     int nbox;
     int dst_off_x, dst_off_y;
     PixmapPtr pSrcPix, pDstPix;
-    ExaPixmapPrivPtr pSrcExaPix, pDstExaPix;
     CARD32 pixel;
     CARD16 red, green, blue, alpha;
     ExaMigrationRec pixmaps[1];
 
-    pDstPix = exaGetDrawablePixmap (pDst->pDrawable);
-    pSrcPix = exaGetDrawablePixmap (pSrc->pDrawable);
-
-    pSrcExaPix = ExaGetPixmapPriv(pSrcPix);
-    pDstExaPix = ExaGetPixmapPriv(pDstPix);
+    pDstPix = pDstExaPix->pPixmap;
+    pSrcPix = pSrcExaPix->pPixmap;
 
     /* Check whether the accelerator can use these pixmaps.
      */
@@ -286,11 +285,12 @@ exaTryDriverSolidFill(PicturePtr	pSrc,
 
     pixmaps[0].as_dst = TRUE;
     pixmaps[0].as_src = FALSE;
-    pixmaps[0].pPix = pDstPix;
+    pixmaps[0].pExaScr = pExaScr;
+    pixmaps[0].pExaPix = pDstExaPix;
     pixmaps[0].pReg = &region;
     exaDoMigration(pixmaps, 1, TRUE);
 
-    if (!exaPixmapIsOffscreen(pDstPix)) {
+    if (!exaPixmapIsOffscreen(pExaScr, pDstExaPix)) {
 	REGION_UNINIT(pDst->pDrawable->pScreen, &region);
 	return 0;
     }
@@ -332,32 +332,30 @@ exaTryDriverSolidFill(PicturePtr	pSrc,
 }
 
 static int
-exaTryDriverCompositeRects(CARD8	       op,
+exaTryDriverCompositeRects(ExaScreenPrivPtr    pExaScr,
+			   CARD8	       op,
 			   PicturePtr	       pSrc,
+			   ExaPixmapPrivPtr    pSrcExaPix,
 			   PicturePtr	       pMask,
+			   ExaPixmapPrivPtr    pMaskExaPix,
 			   PicturePtr	       pDst,
+			   ExaPixmapPrivPtr    pDstExaPix,
 			   int                 nrect,
 			   ExaCompositeRectPtr rects)
 {
-    ExaScreenPriv (pDst->pDrawable->pScreen);
     int src_off_x, src_off_y, mask_off_x, mask_off_y, dst_off_x, dst_off_y;
     PixmapPtr pSrcPix, pMaskPix = NULL, pDstPix;
-    ExaPixmapPrivPtr pSrcExaPix, pMaskExaPix = NULL, pDstExaPix;
     ExaMigrationRec pixmaps[3];
 
     if (!pExaScr->info->PrepareComposite)
 	return -1;
 
-    pSrcPix = exaGetDrawablePixmap(pSrc->pDrawable);
-    pSrcExaPix = ExaGetPixmapPriv(pSrcPix);
+    pSrcPix = pSrcExaPix->pPixmap;
 
-    if (pMask) {
-	pMaskPix = exaGetDrawablePixmap(pMask->pDrawable);
-	pMaskExaPix = ExaGetPixmapPriv(pMaskPix);
-    }
+    if (pMaskExaPix)
+	pMaskPix = pMaskExaPix->pPixmap;
 
-    pDstPix = exaGetDrawablePixmap(pDst->pDrawable);
-    pDstExaPix = ExaGetPixmapPriv(pDstPix);
+    pDstPix = pDstExaPix->pPixmap;
 
     /* Check whether the accelerator can use these pixmaps.
      * FIXME: If it cannot, use temporary pixmaps so that the drawing
@@ -377,31 +375,37 @@ exaTryDriverCompositeRects(CARD8	       op,
     
     pixmaps[0].as_dst = TRUE;
     pixmaps[0].as_src = exaOpReadsDestination(op);
-    pixmaps[0].pPix = pDstPix;
+    pixmaps[0].pExaScr = pExaScr;
+    pixmaps[0].pExaPix = pDstExaPix;
     pixmaps[0].pReg = NULL;
     pixmaps[1].as_dst = FALSE;
     pixmaps[1].as_src = TRUE;
-    pixmaps[1].pPix = pSrcPix;
+    pixmaps[1].pExaScr = pExaScr;
+    pixmaps[1].pExaPix = pSrcExaPix;
     pixmaps[1].pReg = NULL;
     if (pMask) {
 	pixmaps[2].as_dst = FALSE;
 	pixmaps[2].as_src = TRUE;
-	pixmaps[2].pPix = pMaskPix;
+	pixmaps[2].pExaScr = pExaScr;
+	pixmaps[2].pExaPix = pMaskExaPix;
 	pixmaps[2].pReg = NULL;
 	exaDoMigration(pixmaps, 3, TRUE);
     } else
 	exaDoMigration(pixmaps, 2, TRUE);
 
-    pDstPix = exaGetOffscreenPixmap (pDst->pDrawable, &dst_off_x, &dst_off_y);
+    pDstPix = exaGetOffscreenPixmap(pExaScr, pDst->pDrawable, pDstExaPix,
+				    &dst_off_x, &dst_off_y);
     if (!pDstPix)
 	return 0;
     
-    pSrcPix = exaGetOffscreenPixmap (pSrc->pDrawable, &src_off_x, &src_off_y);
+    pSrcPix = exaGetOffscreenPixmap(pExaScr, pSrc->pDrawable, pSrcExaPix,
+				    &src_off_x, &src_off_y);
     if (!pSrcPix)
 	return 0;
 
     if (pMask) {
-	pMaskPix = exaGetOffscreenPixmap (pMask->pDrawable, &mask_off_x, &mask_off_y);
+	pMaskPix = exaGetOffscreenPixmap(pExaScr, pMask->pDrawable, pMaskExaPix,
+					 &mask_off_x, &mask_off_y);
 
 	if (!pMaskPix)
 	    return 0;
@@ -473,16 +477,17 @@ exaTryDriverCompositeRects(CARD8	       op,
  * software.
  */
 void
-exaCompositeRects(CARD8	              op,
+exaCompositeRects(ExaScreenPrivPtr    pExaScr,
+		  CARD8	              op,
 		  PicturePtr	      pSrc,
+		  ExaPixmapPrivPtr    pExaSrcPix,
 		  PicturePtr	      pMask,
+		  ExaPixmapPrivPtr    pExaMaskPix,
 		  PicturePtr	      pDst,
+		  ExaPixmapPrivPtr    pExaDstPix,
 		  int                 nrect,
 		  ExaCompositeRectPtr rects)
 {
-    ExaScreenPriv (pDst->pDrawable->pScreen);
-    PixmapPtr pPixmap = exaGetDrawablePixmap(pDst->pDrawable);
-    ExaPixmapPriv(pPixmap);
     int n;
     ExaCompositeRectPtr r;
     int ret;
@@ -490,7 +495,7 @@ exaCompositeRects(CARD8	              op,
     /* If we get a mask, that means we're rendering to the exaGlyphs
      * destination directly, so the damage layer takes care of this.
      */
-    if (!pMask && pExaPixmap->pDamage) {
+    if (!pMask && pExaDstPix->pDamage) {
 	RegionRec region;
 	int x1 = MAXSHORT;
 	int y1 = MAXSHORT;
@@ -551,7 +556,9 @@ exaCompositeRects(CARD8	              op,
 	ValidatePicture (pMask);
     ValidatePicture (pDst);
 
-    ret = exaTryDriverCompositeRects(op, pSrc, pMask, pDst, nrect, rects);
+    ret = exaTryDriverCompositeRects(pExaScr, op, pSrc, pExaSrcPix, pMask,
+				     pExaMaskPix, pDst, pExaDstPix, nrect,
+				     rects);
 
     if (ret != 1) {
 	if (ret == -1 && op == PictOpOver && pMask && pMask->componentAlpha &&
@@ -559,12 +566,14 @@ exaCompositeRects(CARD8	              op,
 	     ((*pExaScr->info->CheckComposite)(PictOpOutReverse, pSrc, pMask,
 					       pDst) &&
 	      (*pExaScr->info->CheckComposite)(PictOpAdd, pSrc, pMask, pDst)))) {
-	    ret = exaTryDriverCompositeRects(PictOpOutReverse, pSrc, pMask,
-					     pDst, nrect, rects);
+	    ret = exaTryDriverCompositeRects(pExaScr, PictOpOutReverse, pSrc,
+					     pExaSrcPix, pMask, pExaMaskPix,
+					     pDst, pExaDstPix, nrect, rects);
 	    if (ret == 1) {
 		op = PictOpAdd;
-		ret = exaTryDriverCompositeRects(op, pSrc, pMask, pDst, nrect,
-						 rects);
+		ret = exaTryDriverCompositeRects(pExaScr, op, pSrc, pExaSrcPix,
+						 pMask, pExaMaskPix, pDst,
+						 pExaDstPix, nrect, rects);
 	    }
 	}
 
@@ -572,11 +581,12 @@ exaCompositeRects(CARD8	              op,
 	    n = nrect;
 	    r = rects;
 	    while (n--) {
-		ExaCheckComposite (op, pSrc, pMask, pDst,
-				   r->xSrc, r->ySrc,
-				   r->xMask, r->yMask,
-				   r->xDst, r->yDst,
-				   r->width, r->height);
+		ExaCheckComposite(pExaScr, op, pSrc, pExaSrcPix, pMask,
+				  pExaMaskPix, pDst, pExaDstPix,
+				  r->xSrc, r->ySrc,
+				  r->xMask, r->yMask,
+				  r->xDst, r->yDst,
+				  r->width, r->height);
 		r++;
 	    }
 	}
@@ -584,7 +594,7 @@ exaCompositeRects(CARD8	              op,
     
     /************************************************************/
 
-    if (!pMask && pExaPixmap->pDamage) {
+    if (!pMask && pExaDstPix->pDamage) {
 	/* Now we have to flush the damage out from pendingDamage => damage 
 	 * Calling DamageRegionProcessPending has that effect.
 	 */
@@ -594,10 +604,14 @@ exaCompositeRects(CARD8	              op,
 }
 
 static int
-exaTryDriverComposite(CARD8		op,
+exaTryDriverComposite(ExaScreenPrivPtr	pExaScr,
+		      CARD8		op,
 		      PicturePtr	pSrc,
+		      ExaPixmapPrivPtr	pSrcExaPix,
 		      PicturePtr	pMask,
+		      ExaPixmapPrivPtr	pMaskExaPix,
 		      PicturePtr	pDst,
+		      ExaPixmapPrivPtr	pDstExaPix,
 		      INT16		xSrc,
 		      INT16		ySrc,
 		      INT16		xMask,
@@ -607,24 +621,18 @@ exaTryDriverComposite(CARD8		op,
 		      CARD16		width,
 		      CARD16		height)
 {
-    ExaScreenPriv (pDst->pDrawable->pScreen);
     RegionRec region;
     BoxPtr pbox;
     int nbox;
     int src_off_x, src_off_y, mask_off_x, mask_off_y, dst_off_x, dst_off_y;
     PixmapPtr pSrcPix, pMaskPix = NULL, pDstPix;
-    ExaPixmapPrivPtr pSrcExaPix, pMaskExaPix = NULL, pDstExaPix;
     ExaMigrationRec pixmaps[3];
 
-    pSrcPix = exaGetDrawablePixmap(pSrc->pDrawable);
-    pSrcExaPix = ExaGetPixmapPriv(pSrcPix);
-
-    pDstPix = exaGetDrawablePixmap(pDst->pDrawable);
-    pDstExaPix = ExaGetPixmapPriv(pDstPix);
+    pSrcPix = pSrcExaPix->pPixmap;
+    pDstPix = pDstExaPix->pPixmap;
 
     if (pMask) {
-	pMaskPix = exaGetDrawablePixmap(pMask->pDrawable);
-        pMaskExaPix = ExaGetPixmapPriv(pMaskPix);
+	pMaskPix = pMaskExaPix->pPixmap;
     }
 
     /* Check whether the accelerator can use these pixmaps.
@@ -666,28 +674,32 @@ exaTryDriverComposite(CARD8		op,
 
     pixmaps[0].as_dst = TRUE;
     pixmaps[0].as_src = exaOpReadsDestination(op);
-    pixmaps[0].pPix = pDstPix;
+    pixmaps[0].pExaScr = pExaScr;
+    pixmaps[0].pExaPix = pDstExaPix;
     pixmaps[0].pReg = pixmaps[0].as_src ? NULL : &region;
     pixmaps[1].as_dst = FALSE;
     pixmaps[1].as_src = TRUE;
-    pixmaps[1].pPix = pSrcPix;
+    pixmaps[1].pExaScr = pExaScr;
+    pixmaps[1].pExaPix = pSrcExaPix;
     pixmaps[1].pReg = NULL;
     if (pMask) {
 	pixmaps[2].as_dst = FALSE;
 	pixmaps[2].as_src = TRUE;
-	pixmaps[2].pPix = pMaskPix;
+	pixmaps[2].pExaScr = pExaScr;
+	pixmaps[2].pExaPix = pMaskExaPix;
 	pixmaps[2].pReg = NULL;
 	exaDoMigration(pixmaps, 3, TRUE);
     } else {
 	exaDoMigration(pixmaps, 2, TRUE);
     }
 
-    pSrcPix = exaGetOffscreenPixmap (pSrc->pDrawable, &src_off_x, &src_off_y);
+    pSrcPix = exaGetOffscreenPixmap(pExaScr, pSrc->pDrawable, pSrcExaPix,
+				    &src_off_x, &src_off_y);
     if (pMask)
-	pMaskPix = exaGetOffscreenPixmap (pMask->pDrawable, &mask_off_x,
-					  &mask_off_y);
+	pMaskPix = exaGetOffscreenPixmap(pExaScr, pMask->pDrawable, pMaskExaPix,
+					 &mask_off_x, &mask_off_y);
 
-    if (!exaPixmapIsOffscreen(pDstPix)) {
+    if (!exaPixmapIsOffscreen(pExaScr, pDstExaPix)) {
 	REGION_UNINIT(pDst->pDrawable->pScreen, &region);
 	return 0;
     }
@@ -783,7 +795,8 @@ exaTryDriverComposite(CARD8		op,
  */
 
 static int
-exaTryMagicTwoPassCompositeHelper(CARD8 op,
+exaTryMagicTwoPassCompositeHelper(ExaScreenPrivPtr pExaScr,
+				  CARD8 op,
 				  PicturePtr pSrc,
 				  PicturePtr pMask,
 				  PicturePtr pDst,
@@ -796,8 +809,6 @@ exaTryMagicTwoPassCompositeHelper(CARD8 op,
 				  CARD16 width,
 				  CARD16 height)
 {
-    ExaScreenPriv (pDst->pDrawable->pScreen);
-
     assert(op == PictOpOver);
 
     if (pExaScr->info->CheckComposite &&
@@ -838,11 +849,20 @@ exaComposite(CARD8	op,
 	     CARD16	height)
 {
     ExaScreenPriv (pDst->pDrawable->pScreen);
+    ExaPixmapPrivPtr pExaDstPix, pExaSrcPix = NULL, pExaMaskPix = NULL;
     int ret = -1;
     Bool saveSrcRepeat = pSrc->repeat;
     Bool saveMaskRepeat = pMask ? pMask->repeat : 0;
     RegionRec region;
 
+    pExaDstPix = ExaGetPixmapPriv(exaGetDrawablePixmap(pDst->pDrawable));
+
+    if (pSrc->pDrawable)
+	pExaSrcPix = ExaGetPixmapPriv(exaGetDrawablePixmap(pSrc->pDrawable));
+
+    if (pMask && pMask->pDrawable)
+	pExaMaskPix = ExaGetPixmapPriv(exaGetDrawablePixmap(pMask->pDrawable));
+
     /* We currently don't support acceleration of gradients, or other pictures
      * with a NULL pDrawable.
      */
@@ -872,8 +892,9 @@ exaComposite(CARD8	op,
 		pSrc->pDrawable->height == 1 &&
 		pSrc->repeat)
 	    {
-		ret = exaTryDriverSolidFill(pSrc, pDst, xSrc, ySrc, xDst, yDst,
-					    width, height);
+		ret = exaTryDriverSolidFill(pExaScr, pSrc, pExaSrcPix, pDst,
+					    pExaDstPix, xSrc, ySrc,
+					    xDst, yDst, width, height);
 		if (ret == 1)
 		    goto done;
 	    }
@@ -892,9 +913,11 @@ exaComposite(CARD8	op,
 					       yDst, width, height))
 		    goto done;
 
-		ret = exaHWCopyNtoN(pSrc->pDrawable, pDst->pDrawable, NULL,
-			     REGION_RECTS(&region), REGION_NUM_RECTS(&region),
-			     xSrc - xDst, ySrc - yDst, FALSE, FALSE);
+		ret = exaHWCopyNtoN(pExaScr, pSrc->pDrawable, pExaSrcPix,
+				    pDst->pDrawable, pExaDstPix, NULL,
+				    REGION_RECTS(&region),
+				    REGION_NUM_RECTS(&region),
+				    xSrc - xDst, ySrc - yDst, FALSE, FALSE);
 		REGION_UNINIT(pDst->pDrawable->pScreen, &region);
 
 		/* Reset values to their original values. */
@@ -919,9 +942,11 @@ exaComposite(CARD8	op,
 		if (pExaScr->info->PrepareComposite && !pSrc->alphaMap &&
 		    !pDst->alphaMap)
 		{
-		    ret = exaTryDriverComposite(op, pSrc, pMask, pDst, xSrc,
-						ySrc, xMask, yMask, xDst, yDst,
-						width, height);
+		    ret = exaTryDriverComposite(pExaScr, op, pSrc, pExaSrcPix,
+						pMask, pExaMaskPix, pDst,
+						pExaDstPix, xSrc, ySrc, xMask,
+						yMask, xDst, yDst, width,
+						height);
 		    if (ret == 1)
 			goto done;
 		}
@@ -942,9 +967,10 @@ exaComposite(CARD8	op,
 		patOrg.x = xDst - xSrc;
 		patOrg.y = yDst - ySrc;
 
-		ret = exaFillRegionTiled(pDst->pDrawable, &region,
-					 (PixmapPtr)pSrc->pDrawable,
-					 &patOrg, FB_ALLONES, GXcopy);
+		ret = exaFillRegionTiled(pExaScr, pDst->pDrawable, pExaDstPix,
+					 &region, (PixmapPtr)pSrc->pDrawable,
+					 pExaSrcPix, &patOrg, FB_ALLONES,
+					 GXcopy);
 
 		REGION_UNINIT(pDst->pDrawable->pScreen, &region);
 
@@ -971,8 +997,9 @@ exaComposite(CARD8	op,
     {
 	Bool isSrcSolid;
 
-	ret = exaTryDriverComposite(op, pSrc, pMask, pDst, xSrc, ySrc, xMask,
-				    yMask, xDst, yDst, width, height);
+	ret = exaTryDriverComposite(pExaScr, op, pSrc, pExaSrcPix, pMask,
+				    pExaMaskPix, pDst, pExaDstPix, xSrc, ySrc,
+				    xMask, yMask, xDst, yDst, width, height);
 	if (ret == 1)
 	    goto done;
 
@@ -989,8 +1016,8 @@ exaComposite(CARD8	op,
 	 */
 	if (ret == -1 && op == PictOpOver && pMask &&
 	    (pMask->componentAlpha || isSrcSolid)) {
-	    ret = exaTryMagicTwoPassCompositeHelper(op, pSrc, pMask, pDst,
-						    xSrc, ySrc,
+	    ret = exaTryMagicTwoPassCompositeHelper(pExaScr, op, pSrc, pMask,
+						    pDst, xSrc, ySrc,
 						    xMask, yMask, xDst, yDst,
 						    width, height);
 	    if (ret == 1)
@@ -1003,8 +1030,9 @@ fallback:
     exaPrintCompositeFallback (op, pSrc, pMask, pDst);
 #endif
 
-    ExaCheckComposite (op, pSrc, pMask, pDst, xSrc, ySrc,
-		      xMask, yMask, xDst, yDst, width, height);
+    ExaCheckComposite(pExaScr, op, pSrc, pExaSrcPix, pMask, pExaMaskPix, pDst,
+		      pExaDstPix, xSrc, ySrc, xMask, yMask, xDst, yDst, width,
+		      height);
 
 done:
     pSrc->repeat = saveSrcRepeat;
@@ -1021,13 +1049,12 @@ done:
  * See the comments about exaTrapezoids and exaTriangles.
  */
 static PicturePtr
-exaCreateAlphaPicture (ScreenPtr     pScreen,
-                       PicturePtr    pDst,
-                       PictFormatPtr pPictFormat,
-                       CARD16        width,
-                       CARD16        height)
+exaCreateAlphaPicture(ExaScreenPrivPtr pExaScr, PicturePtr pDst,
+		      PictFormatPtr pPictFormat, CARD16 width, CARD16 height)
 {
+    ScreenPtr	    pScreen = pExaScr->pScreen;
     PixmapPtr	    pPixmap;
+    ExaPixmapPrivPtr pExaPixmap;
     PicturePtr	    pPicture;
     GCPtr	    pGC;
     int		    error;
@@ -1056,13 +1083,15 @@ exaCreateAlphaPicture (ScreenPtr     pScreen,
 	(*pScreen->DestroyPixmap) (pPixmap);
 	return 0;
     }
+    pExaPixmap = ExaGetPixmapPriv(pPixmap);
     ValidateGC (&pPixmap->drawable, pGC);
     rect.x = 0;
     rect.y = 0;
     rect.width = width;
     rect.height = height;
-    ExaCheckPolyFillRect (&pPixmap->drawable, pGC, 1, &rect);
-    exaPixmapDirty (pPixmap, 0, 0, width, height);
+    ExaCheckPolyFillRect(pExaScr, &pPixmap->drawable, pExaPixmap,
+			 pGC, 1, &rect);
+    exaPixmapDirty(pExaPixmap, 0, 0, width, height);
     FreeScratchGC (pGC);
     pPicture = CreatePicture (0, &pPixmap->drawable, pPictFormat,
 			      0, 0, serverClient, &error);
@@ -1089,11 +1118,13 @@ exaTrapezoids (CARD8 op, PicturePtr pSrc, PicturePtr pDst,
                int ntrap, xTrapezoid *traps)
 {
     ScreenPtr		pScreen = pDst->pDrawable->pScreen;
+    ExaScreenPriv(pScreen);
     PictureScreenPtr    ps = GetPictureScreen(pScreen);
     BoxRec		bounds;
 
     if (maskFormat) {
 	PicturePtr	pPicture;
+	ExaPixmapPrivPtr pExaPixmap;
 	INT16		xDst, yDst;
 	INT16		xRel, yRel;
 
@@ -1105,17 +1136,21 @@ exaTrapezoids (CARD8 op, PicturePtr pSrc, PicturePtr pDst,
 	xDst = traps[0].left.p1.x >> 16;
 	yDst = traps[0].left.p1.y >> 16;
 
-	pPicture = exaCreateAlphaPicture (pScreen, pDst, maskFormat,
-	                                  bounds.x2 - bounds.x1,
-	                                  bounds.y2 - bounds.y1);
+	pPicture = exaCreateAlphaPicture(pExaScr, pDst, maskFormat,
+					 bounds.x2 - bounds.x1,
+					 bounds.y2 - bounds.y1);
 	if (!pPicture)
 	    return;
 
-	exaPrepareAccess(pPicture->pDrawable, EXA_PREPARE_DEST);
+	pExaPixmap = ExaGetPixmapPriv((PixmapPtr)pPicture->pDrawable);
+
+	exaPrepareAccess(pExaScr, pPicture->pDrawable, pExaPixmap,
+			 EXA_PREPARE_DEST);
 	for (; ntrap; ntrap--, traps++)
 	    (*ps->RasterizeTrapezoid) (pPicture, traps,
 				       -bounds.x1, -bounds.y1);
-	exaFinishAccess(pPicture->pDrawable, EXA_PREPARE_DEST);
+	exaFinishAccess(pExaScr, pPicture->pDrawable, pExaPixmap,
+			EXA_PREPARE_DEST);
 
 	xRel = bounds.x1 + xSrc - xDst;
 	yRel = bounds.y1 + ySrc - yDst;
@@ -1153,11 +1188,13 @@ exaTriangles (CARD8 op, PicturePtr pSrc, PicturePtr pDst,
 	      int ntri, xTriangle *tris)
 {
     ScreenPtr		pScreen = pDst->pDrawable->pScreen;
+    ExaScreenPriv(pScreen);
     PictureScreenPtr    ps = GetPictureScreen(pScreen);
     BoxRec		bounds;
 
     if (maskFormat) {
 	PicturePtr	pPicture;
+	ExaPixmapPrivPtr pExaPixmap;
 	INT16		xDst, yDst;
 	INT16		xRel, yRel;
 
@@ -1169,15 +1206,19 @@ exaTriangles (CARD8 op, PicturePtr pSrc, PicturePtr pDst,
 	xDst = tris[0].p1.x >> 16;
 	yDst = tris[0].p1.y >> 16;
 
-	pPicture = exaCreateAlphaPicture (pScreen, pDst, maskFormat,
+	pPicture = exaCreateAlphaPicture(pExaScr, pDst, maskFormat,
 					  bounds.x2 - bounds.x1,
 					  bounds.y2 - bounds.y1);
 	if (!pPicture)
 	    return;
 
-	exaPrepareAccess(pPicture->pDrawable, EXA_PREPARE_DEST);
+	pExaPixmap = ExaGetPixmapPriv((PixmapPtr)pPicture->pDrawable);
+
+	exaPrepareAccess(pExaScr, pPicture->pDrawable, pExaPixmap,
+			 EXA_PREPARE_DEST);
 	(*ps->AddTriangles) (pPicture, -bounds.x1, -bounds.y1, ntri, tris);
-	exaFinishAccess(pPicture->pDrawable, EXA_PREPARE_DEST);
+	exaFinishAccess(pExaScr, pPicture->pDrawable, pExaPixmap,
+			EXA_PREPARE_DEST);
 
 	xRel = bounds.x1 + xSrc - xDst;
 	yRel = bounds.y1 + ySrc - yDst;
diff --git a/exa/exa_unaccel.c b/exa/exa_unaccel.c
index 0c4319f..0024304 100644
--- a/exa/exa_unaccel.c
+++ b/exa/exa_unaccel.c
@@ -42,24 +42,28 @@
  * We should worry about them for completeness sake and going forward.
  */
 void
-exaPrepareAccessGC(GCPtr pGC)
+exaPrepareAccessGC(ExaScreenPrivPtr pExaScr, GCPtr pGC)
 {
     if (pGC->stipple)
-        exaPrepareAccess(&pGC->stipple->drawable, EXA_PREPARE_MASK);
+        exaPrepareAccess(pExaScr, &pGC->stipple->drawable,
+			 ExaGetPixmapPriv(pGC->stipple), EXA_PREPARE_MASK);
     if (pGC->fillStyle == FillTiled)
-	exaPrepareAccess(&pGC->tile.pixmap->drawable, EXA_PREPARE_SRC);
+	exaPrepareAccess(pExaScr, &pGC->tile.pixmap->drawable,
+			 ExaGetPixmapPriv(pGC->tile.pixmap), EXA_PREPARE_SRC);
 }
 
 /**
  * Finishes access to the tile in the GC, if used.
  */
 void
-exaFinishAccessGC(GCPtr pGC)
+exaFinishAccessGC(ExaScreenPrivPtr pExaScr, GCPtr pGC)
 {
     if (pGC->fillStyle == FillTiled)
-	exaFinishAccess(&pGC->tile.pixmap->drawable, EXA_PREPARE_SRC);
+	exaFinishAccess(pExaScr, &pGC->tile.pixmap->drawable,
+			ExaGetPixmapPriv(pGC->tile.pixmap), EXA_PREPARE_SRC);
     if (pGC->stipple)
-        exaFinishAccess(&pGC->stipple->drawable, EXA_PREPARE_MASK);
+        exaFinishAccess(pExaScr, &pGC->stipple->drawable,
+			ExaGetPixmapPriv(pGC->stipple), EXA_PREPARE_MASK);
 }
 
 #if DEBUG_TRACE_FALL
@@ -71,86 +75,91 @@ exaDrawableLocation(DrawablePtr pDrawable)
 #endif /* DEBUG_TRACE_FALL */
 
 void
-ExaCheckFillSpans (DrawablePtr pDrawable, GCPtr pGC, int nspans,
-		   DDXPointPtr ppt, int *pwidth, int fSorted)
+ExaCheckFillSpans(ExaScreenPrivPtr pExaScr, DrawablePtr pDrawable,
+		  ExaPixmapPrivPtr pExaPixmap, GCPtr pGC, int nspans,
+		  DDXPointPtr ppt, int *pwidth, int fSorted)
 {
     EXA_GC_PROLOGUE(pGC);
     EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
-    exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
-    exaPrepareAccessGC (pGC);
+    exaPrepareAccess (pExaScr, pDrawable, pExaPixmap, EXA_PREPARE_DEST);
+    exaPrepareAccessGC (pExaScr, pGC);
     pGC->ops->FillSpans (pDrawable, pGC, nspans, ppt, pwidth, fSorted);
-    exaFinishAccessGC (pGC);
-    exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
+    exaFinishAccessGC (pExaScr, pGC);
+    exaFinishAccess (pExaScr, pDrawable, pExaPixmap, EXA_PREPARE_DEST);
     EXA_GC_EPILOGUE(pGC);
 }
 
 void
-ExaCheckSetSpans (DrawablePtr pDrawable, GCPtr pGC, char *psrc,
-		 DDXPointPtr ppt, int *pwidth, int nspans, int fSorted)
+ExaCheckSetSpans (DrawablePtr pDrawable, GCPtr pGC, char *psrc, DDXPointPtr ppt,
+		  int *pwidth, int nspans, int fSorted)
 {
+    ExaScreenPriv(pDrawable->pScreen);
+    ExaPixmapPriv(exaGetDrawablePixmap(pDrawable));
     EXA_GC_PROLOGUE(pGC);
     EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
-    exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
+    exaPrepareAccess (pExaScr, pDrawable, pExaPixmap, EXA_PREPARE_DEST);
     pGC->ops->SetSpans (pDrawable, pGC, psrc, ppt, pwidth, nspans, fSorted);
-    exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
+    exaFinishAccess (pExaScr, pDrawable, pExaPixmap, EXA_PREPARE_DEST);
     EXA_GC_EPILOGUE(pGC);
 }
 
 void
-ExaCheckPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth,
-		 int x, int y, int w, int h, int leftPad, int format,
-		 char *bits)
+ExaCheckPutImage(ExaScreenPrivPtr pExaScr, DrawablePtr pDrawable,
+		 ExaPixmapPrivPtr pExaPixmap, GCPtr pGC, int depth, int x, int y,
+		 int w, int h, int leftPad, int format, char *bits)
 {
-    ExaPixmapPriv(exaGetDrawablePixmap(pDrawable));
-
     EXA_GC_PROLOGUE(pGC);
     EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
     if (exaGCReadsDestination(pDrawable, pGC->planemask, pGC->fillStyle,
 			      pGC->alu))
-	exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
+	exaPrepareAccess (pExaScr, pDrawable, pExaPixmap, EXA_PREPARE_DEST);
     else
-	exaPrepareAccessReg (pDrawable, EXA_PREPARE_DEST, pExaPixmap->pDamage ?
+	exaPrepareAccessReg(pExaScr, pDrawable, pExaPixmap, EXA_PREPARE_DEST, pExaPixmap->pDamage ?
 			     DamagePendingRegion(pExaPixmap->pDamage) : NULL);
     pGC->ops->PutImage (pDrawable, pGC, depth, x, y, w, h, leftPad, format, bits);
-    exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
+    exaFinishAccess (pExaScr, pDrawable, pExaPixmap, EXA_PREPARE_DEST);
     EXA_GC_EPILOGUE(pGC);
 }
 
 void
-ExaCheckCopyNtoN (DrawablePtr pSrc, DrawablePtr pDst,  GCPtr pGC,
-	     BoxPtr	pbox, int nbox, int dx, int dy, Bool	reverse, 
-	     Bool upsidedown, Pixel bitplane, void *closure)
+ExaCheckCopyNtoN(ExaScreenPrivPtr pExaScr, DrawablePtr pSrc,
+		 ExaPixmapPrivPtr pExaSrcPix, DrawablePtr pDst,
+		 ExaPixmapPrivPtr pExaDstPix, GCPtr pGC, BoxPtr pbox, int nbox,
+		 int dx, int dy, Bool reverse, Bool upsidedown, Pixel bitplane,
+		 void *closure)
 {
     EXA_GC_PROLOGUE(pGC);
     EXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrc, pDst,
 		  exaDrawableLocation(pSrc), exaDrawableLocation(pDst)));
-    exaPrepareAccess (pDst, EXA_PREPARE_DEST);
-    exaPrepareAccess (pSrc, EXA_PREPARE_SRC);
+    exaPrepareAccess (pExaScr, pDst, pExaDstPix, EXA_PREPARE_DEST);
+    exaPrepareAccess (pExaScr, pSrc, pExaSrcPix, EXA_PREPARE_SRC);
     /* This will eventually call fbCopyNtoN, with some calculation overhead. */
     while (nbox--) {
 	pGC->ops->CopyArea (pSrc, pDst, pGC, pbox->x1 - pSrc->x + dx, pbox->y1 - pSrc->y + dy, 
 			pbox->x2 - pbox->x1, pbox->y2 - pbox->y1, pbox->x1 - pDst->x, pbox->y1 - pDst->y);
 	pbox++;
     }
-    exaFinishAccess (pSrc, EXA_PREPARE_SRC);
-    exaFinishAccess (pDst, EXA_PREPARE_DEST);
+    exaFinishAccess (pExaScr, pSrc, pExaSrcPix, EXA_PREPARE_SRC);
+    exaFinishAccess (pExaScr, pDst, pExaDstPix, EXA_PREPARE_DEST);
     EXA_GC_EPILOGUE(pGC);
 }
 
 RegionPtr
-ExaCheckCopyArea (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
-		 int srcx, int srcy, int w, int h, int dstx, int dsty)
+ExaCheckCopyArea(ExaScreenPrivPtr pExaScr, DrawablePtr pSrc,
+		 ExaPixmapPrivPtr pExaSrcPix, DrawablePtr pDst,
+		 ExaPixmapPrivPtr pExaDstPix, GCPtr pGC, int srcx, int srcy,
+		 int w, int h, int dstx, int dsty)
 {
     RegionPtr ret;
 
     EXA_GC_PROLOGUE(pGC);
     EXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrc, pDst,
 		  exaDrawableLocation(pSrc), exaDrawableLocation(pDst)));
-    exaPrepareAccess (pDst, EXA_PREPARE_DEST);
-    exaPrepareAccess (pSrc, EXA_PREPARE_SRC);
+    exaPrepareAccess (pExaScr, pDst, pExaDstPix, EXA_PREPARE_DEST);
+    exaPrepareAccess (pExaScr, pSrc, pExaSrcPix, EXA_PREPARE_SRC);
     ret = pGC->ops->CopyArea (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty);
-    exaFinishAccess (pSrc, EXA_PREPARE_SRC);
-    exaFinishAccess (pDst, EXA_PREPARE_DEST);
+    exaFinishAccess (pExaScr, pSrc, pExaSrcPix, EXA_PREPARE_SRC);
+    exaFinishAccess (pExaScr, pDst, pExaDstPix, EXA_PREPARE_DEST);
     EXA_GC_EPILOGUE(pGC);
 
     return ret;
@@ -161,64 +170,70 @@ ExaCheckCopyPlane (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
 		  int srcx, int srcy, int w, int h, int dstx, int dsty,
 		  unsigned long bitPlane)
 {
+    ExaScreenPriv(pDst->pScreen);
+    ExaPixmapPrivPtr pExaDstPix = ExaGetPixmapPriv((exaGetDrawablePixmap(pDst)));
+    ExaPixmapPrivPtr pExaSrcPix = ExaGetPixmapPriv((exaGetDrawablePixmap(pSrc)));
     RegionPtr ret;
 
     EXA_GC_PROLOGUE(pGC);
     EXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrc, pDst,
 		  exaDrawableLocation(pSrc), exaDrawableLocation(pDst)));
-    exaPrepareAccess (pDst, EXA_PREPARE_DEST);
-    exaPrepareAccess (pSrc, EXA_PREPARE_SRC);
+    exaPrepareAccess (pExaScr, pDst, pExaDstPix, EXA_PREPARE_DEST);
+    exaPrepareAccess (pExaScr, pSrc, pExaSrcPix, EXA_PREPARE_SRC);
     ret = pGC->ops->CopyPlane (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty,
 		       bitPlane);
-    exaFinishAccess (pSrc, EXA_PREPARE_SRC);
-    exaFinishAccess (pDst, EXA_PREPARE_DEST);
+    exaFinishAccess (pExaScr, pSrc, pExaSrcPix, EXA_PREPARE_SRC);
+    exaFinishAccess (pExaScr, pDst, pExaDstPix, EXA_PREPARE_DEST);
     EXA_GC_EPILOGUE(pGC);
 
     return ret;
 }
 
 void
-ExaCheckPolyPoint (DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
+ExaCheckPolyPoint(ExaScreenPrivPtr pExaScr, DrawablePtr pDrawable,
+		  ExaPixmapPrivPtr pExaPixmap, GCPtr pGC, int mode, int npt,
 		  DDXPointPtr pptInit)
 {
     EXA_GC_PROLOGUE(pGC);
     EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
-    exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
+    exaPrepareAccess (pExaScr, pDrawable, pExaPixmap, EXA_PREPARE_DEST);
     pGC->ops->PolyPoint (pDrawable, pGC, mode, npt, pptInit);
-    exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
+    exaFinishAccess (pExaScr, pDrawable, pExaPixmap, EXA_PREPARE_DEST);
     EXA_GC_EPILOGUE(pGC);
 }
 
 void
-ExaCheckPolylines (DrawablePtr pDrawable, GCPtr pGC,
-		  int mode, int npt, DDXPointPtr ppt)
+ExaCheckPolylines(ExaScreenPrivPtr pExaScr, DrawablePtr pDrawable,
+		  ExaPixmapPrivPtr pExaPixmap, GCPtr pGC, int mode, int npt,
+		  DDXPointPtr ppt)
 {
     EXA_GC_PROLOGUE(pGC);
     EXA_FALLBACK(("to %p (%c), width %d, mode %d, count %d\n",
 		  pDrawable, exaDrawableLocation(pDrawable),
 		  pGC->lineWidth, mode, npt));
 
-    exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
-    exaPrepareAccessGC (pGC);
+    exaPrepareAccess (pExaScr, pDrawable, pExaPixmap, EXA_PREPARE_DEST);
+    exaPrepareAccessGC (pExaScr, pGC);
     pGC->ops->Polylines (pDrawable, pGC, mode, npt, ppt);
-    exaFinishAccessGC (pGC);
-    exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
+    exaFinishAccessGC (pExaScr, pGC);
+    exaFinishAccess (pExaScr, pDrawable, pExaPixmap, EXA_PREPARE_DEST);
     EXA_GC_EPILOGUE(pGC);
 }
 
 void
-ExaCheckPolySegment (DrawablePtr pDrawable, GCPtr pGC,
-		    int nsegInit, xSegment *pSegInit)
+ExaCheckPolySegment(ExaScreenPrivPtr pExaScr, DrawablePtr pDrawable,
+		    ExaPixmapPrivPtr pExaPixmap, GCPtr pGC, int nsegInit,
+		    xSegment *pSegInit)
 {
     EXA_GC_PROLOGUE(pGC);
     EXA_FALLBACK(("to %p (%c) width %d, count %d\n", pDrawable,
 		  exaDrawableLocation(pDrawable), pGC->lineWidth, nsegInit));
 
-    exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
-    exaPrepareAccessGC (pGC);
+    exaPrepareAccess (pExaScr, pDrawable, pExaPixmap, EXA_PREPARE_DEST);
+    exaPrepareAccessGC (pExaScr, pGC);
     pGC->ops->PolySegment (pDrawable, pGC, nsegInit, pSegInit);
-    exaFinishAccessGC (pGC);
-    exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
+    exaFinishAccessGC (pExaScr, pGC);
+    exaFinishAccess (pExaScr, pDrawable, pExaPixmap, EXA_PREPARE_DEST);
     EXA_GC_EPILOGUE(pGC);
 }
 
@@ -226,29 +241,32 @@ void
 ExaCheckPolyArc (DrawablePtr pDrawable, GCPtr pGC,
 		int narcs, xArc *pArcs)
 {
+    ExaScreenPriv(pDrawable->pScreen);
+    ExaPixmapPriv(exaGetDrawablePixmap(pDrawable));
     EXA_GC_PROLOGUE(pGC);
     EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
 
-    exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
-    exaPrepareAccessGC (pGC);
+    exaPrepareAccess (pExaScr, pDrawable, pExaPixmap, EXA_PREPARE_DEST);
+    exaPrepareAccessGC (pExaScr, pGC);
     pGC->ops->PolyArc (pDrawable, pGC, narcs, pArcs);
-    exaFinishAccessGC (pGC);
-    exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
+    exaFinishAccessGC (pExaScr, pGC);
+    exaFinishAccess (pExaScr, pDrawable, pExaPixmap, EXA_PREPARE_DEST);
     EXA_GC_EPILOGUE(pGC);
 }
 
 void
-ExaCheckPolyFillRect (DrawablePtr pDrawable, GCPtr pGC,
-		     int nrect, xRectangle *prect)
+ExaCheckPolyFillRect(ExaScreenPrivPtr pExaScr, DrawablePtr pDrawable,
+		     ExaPixmapPrivPtr pExaPixmap, GCPtr pGC, int nrect,
+		     xRectangle *prect)
 {
     EXA_GC_PROLOGUE(pGC);
     EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
 
-    exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
-    exaPrepareAccessGC (pGC);
+    exaPrepareAccess (pExaScr, pDrawable, pExaPixmap, EXA_PREPARE_DEST);
+    exaPrepareAccessGC (pExaScr, pGC);
     pGC->ops->PolyFillRect (pDrawable, pGC, nrect, prect);
-    exaFinishAccessGC (pGC);
-    exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
+    exaFinishAccessGC (pExaScr, pGC);
+    exaFinishAccess (pExaScr, pDrawable, pExaPixmap, EXA_PREPARE_DEST);
     EXA_GC_EPILOGUE(pGC);
 }
 
@@ -257,14 +275,16 @@ ExaCheckImageGlyphBlt (DrawablePtr pDrawable, GCPtr pGC,
 		      int x, int y, unsigned int nglyph,
 		      CharInfoPtr *ppci, pointer pglyphBase)
 {
+    ExaScreenPriv(pDrawable->pScreen);
+    ExaPixmapPriv(exaGetDrawablePixmap(pDrawable));
     EXA_GC_PROLOGUE(pGC);
     EXA_FALLBACK(("to %p (%c)\n", pDrawable,
 		  exaDrawableLocation(pDrawable)));
-    exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
-    exaPrepareAccessGC (pGC);
+    exaPrepareAccess (pExaScr, pDrawable, pExaPixmap, EXA_PREPARE_DEST);
+    exaPrepareAccessGC (pExaScr, pGC);
     pGC->ops->ImageGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
-    exaFinishAccessGC (pGC);
-    exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
+    exaFinishAccessGC (pExaScr, pGC);
+    exaFinishAccess (pExaScr, pDrawable, pExaPixmap, EXA_PREPARE_DEST);
     EXA_GC_EPILOGUE(pGC);
 }
 
@@ -273,14 +293,16 @@ ExaCheckPolyGlyphBlt (DrawablePtr pDrawable, GCPtr pGC,
 		     int x, int y, unsigned int nglyph,
 		     CharInfoPtr *ppci, pointer pglyphBase)
 {
+    ExaScreenPriv(pDrawable->pScreen);
+    ExaPixmapPriv(exaGetDrawablePixmap(pDrawable));
     EXA_GC_PROLOGUE(pGC);
     EXA_FALLBACK(("to %p (%c), style %d alu %d\n", pDrawable,
 		  exaDrawableLocation(pDrawable), pGC->fillStyle, pGC->alu));
-    exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
-    exaPrepareAccessGC (pGC);
+    exaPrepareAccess (pExaScr, pDrawable, pExaPixmap, EXA_PREPARE_DEST);
+    exaPrepareAccessGC (pExaScr, pGC);
     pGC->ops->PolyGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
-    exaFinishAccessGC (pGC);
-    exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
+    exaFinishAccessGC (pExaScr, pGC);
+    exaFinishAccess (pExaScr, pDrawable, pExaPixmap, EXA_PREPARE_DEST);
     EXA_GC_EPILOGUE(pGC);
 }
 
@@ -289,46 +311,50 @@ ExaCheckPushPixels (GCPtr pGC, PixmapPtr pBitmap,
 		   DrawablePtr pDrawable,
 		   int w, int h, int x, int y)
 {
+    ExaScreenPriv(pDrawable->pScreen);
+    ExaPixmapPrivPtr pExaDstPix = ExaGetPixmapPriv((exaGetDrawablePixmap(pDrawable)));
+    ExaPixmapPrivPtr pExaSrcPix = ExaGetPixmapPriv(pBitmap);
     EXA_GC_PROLOGUE(pGC);
     EXA_FALLBACK(("from %p to %p (%c,%c)\n", pBitmap, pDrawable,
 		  exaDrawableLocation(&pBitmap->drawable),
 		  exaDrawableLocation(pDrawable)));
-    exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
-    exaPrepareAccess (&pBitmap->drawable, EXA_PREPARE_SRC);
-    exaPrepareAccessGC (pGC);
+    exaPrepareAccess (pExaScr, pDrawable, pExaDstPix, EXA_PREPARE_DEST);
+    exaPrepareAccess (pExaScr, &pBitmap->drawable, pExaSrcPix, EXA_PREPARE_SRC);
+    exaPrepareAccessGC (pExaScr, pGC);
     pGC->ops->PushPixels (pGC, pBitmap, pDrawable, w, h, x, y);
-    exaFinishAccessGC (pGC);
-    exaFinishAccess (&pBitmap->drawable, EXA_PREPARE_SRC);
-    exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
+    exaFinishAccessGC (pExaScr, pGC);
+    exaFinishAccess (pExaScr, &pBitmap->drawable, pExaSrcPix, EXA_PREPARE_SRC);
+    exaFinishAccess (pExaScr, pDrawable, pExaDstPix, EXA_PREPARE_DEST);
     EXA_GC_EPILOGUE(pGC);
 }
 
 void
-ExaCheckCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
+ExaCheckCopyWindow(ExaScreenPrivPtr pExaScr, WindowPtr pWin,
+		   ExaPixmapPrivPtr pExaPixmap, DDXPointRec ptOldOrg,
+		   RegionPtr prgnSrc)
 {
     DrawablePtr pDrawable = &pWin->drawable;
     ScreenPtr pScreen = pDrawable->pScreen;
-    ExaScreenPriv(pScreen);
     EXA_FALLBACK(("from %p\n", pWin));
 
     /* being both src and dest, src is safest. */
-    exaPrepareAccess(pDrawable, EXA_PREPARE_SRC);
+    exaPrepareAccess(pExaScr, pDrawable, pExaPixmap, EXA_PREPARE_SRC);
     swap(pExaScr, pScreen, CopyWindow);
     pScreen->CopyWindow (pWin, ptOldOrg, prgnSrc);
     swap(pExaScr, pScreen, CopyWindow);
-    exaFinishAccess (pDrawable, EXA_PREPARE_SRC);
+    exaFinishAccess (pExaScr, pDrawable, pExaPixmap, EXA_PREPARE_SRC);
 }
 
 void
-ExaCheckGetImage(DrawablePtr pDrawable, int x, int y, int w, int h,
-		unsigned int format, unsigned long planeMask, char *d)
+ExaCheckGetImage(ExaScreenPrivPtr pExaScr, DrawablePtr pDrawable,
+		 ExaPixmapPrivPtr pExaPixmap, int x, int y, int w, int h,
+		 unsigned int format, unsigned long planeMask, char *d)
 {
     BoxRec Box;
     RegionRec Reg;
     int xoff, yoff;
     ScreenPtr pScreen = pDrawable->pScreen;
-    PixmapPtr pPix = exaGetDrawablePixmap (pDrawable);
-    ExaScreenPriv(pScreen);
+    PixmapPtr pPix = pExaPixmap->pPixmap;
 
     EXA_FALLBACK(("from %p (%c)\n", pDrawable,
 		  exaDrawableLocation(pDrawable)));
@@ -342,11 +368,11 @@ ExaCheckGetImage(DrawablePtr pDrawable, int x, int y, int w, int h,
 
     REGION_INIT(pScreen, &Reg, &Box, 1);
 
-    exaPrepareAccessReg (pDrawable, EXA_PREPARE_SRC, &Reg);
+    exaPrepareAccessReg(pExaScr, pDrawable, pExaPixmap, EXA_PREPARE_SRC, &Reg);
     swap(pExaScr, pScreen, GetImage);
     pScreen->GetImage (pDrawable, x, y, w, h, format, planeMask, d);
     swap(pExaScr, pScreen, GetImage);
-    exaFinishAccess (pDrawable, EXA_PREPARE_SRC);
+    exaFinishAccess (pExaScr, pDrawable, pExaPixmap, EXA_PREPARE_SRC);
 }
 
 void
@@ -358,35 +384,29 @@ ExaCheckGetSpans (DrawablePtr pDrawable,
 		 char *pdstStart)
 {
     ScreenPtr pScreen = pDrawable->pScreen;
+    ExaPixmapPriv(exaGetDrawablePixmap(pDrawable));
     ExaScreenPriv(pScreen);
-
     EXA_FALLBACK(("from %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
-    exaPrepareAccess (pDrawable, EXA_PREPARE_SRC);
+    exaPrepareAccess (pExaScr, pDrawable, pExaPixmap, EXA_PREPARE_SRC);
     swap(pExaScr, pScreen, GetSpans);
     pScreen->GetSpans (pDrawable, wMax, ppt, pwidth, nspans, pdstStart);
     swap(pExaScr, pScreen, GetSpans);
-    exaFinishAccess (pDrawable, EXA_PREPARE_SRC);
+    exaFinishAccess (pExaScr, pDrawable, pExaPixmap, EXA_PREPARE_SRC);
 }
 
 void
-ExaCheckComposite (CARD8      op,
-                   PicturePtr pSrc,
-                   PicturePtr pMask,
-                   PicturePtr pDst,
-                   INT16      xSrc,
-                   INT16      ySrc,
-                   INT16      xMask,
-                   INT16      yMask,
-                   INT16      xDst,
-                   INT16      yDst,
-                   CARD16     width,
-                   CARD16     height)
+ExaCheckComposite(ExaScreenPrivPtr pExaScr, CARD8 op, PicturePtr pSrc,
+		  ExaPixmapPrivPtr pExaSrcPix, PicturePtr pMask,
+		  ExaPixmapPrivPtr pExaMaskPix, PicturePtr pDst,
+		  ExaPixmapPrivPtr pExaDstPix, INT16 xSrc, INT16 ySrc,
+		  INT16 xMask, INT16 yMask, INT16 xDst, INT16 yDst,
+		  CARD16 width, CARD16 height)
 {
     ScreenPtr pScreen = pDst->pDrawable->pScreen;
 #ifdef RENDER
     PictureScreenPtr	ps = GetPictureScreen(pScreen);
 #endif /* RENDER */
-    ExaScreenPriv(pScreen);
+    ExaPixmapPrivPtr pExaDstAlphaPix = NULL, pExaMaskAlphaPix = NULL, pExaSrcAlphaPix = NULL;
     RegionRec region;
     int xoff, yoff;
 
@@ -398,35 +418,53 @@ ExaCheckComposite (CARD8      op,
 				       width, height))
 	    return;
 
-	exaGetDrawableDeltas (pDst->pDrawable,
-			      exaGetDrawablePixmap(pDst->pDrawable),
-			      &xoff, &yoff);
+	exaGetDrawableDeltas(pDst->pDrawable, pExaDstPix->pPixmap, &xoff, &yoff);
 
 	REGION_TRANSLATE(pScreen, &region, xoff, yoff);
 
-	exaPrepareAccessReg (pDst->pDrawable, EXA_PREPARE_DEST, &region);
+	exaPrepareAccessReg(pExaScr, pDst->pDrawable, pExaDstPix,
+			    EXA_PREPARE_DEST, &region);
 
-	if (pDst->alphaMap && pDst->alphaMap->pDrawable)
-	    exaPrepareAccessReg(pDst->alphaMap->pDrawable, EXA_PREPARE_AUX0,
-				&region);
+	if (pDst->alphaMap && pDst->alphaMap->pDrawable) {
+	    /* The RENDER spec doesn't allow windows for separate alpha maps */
+	    pExaDstAlphaPix =
+		ExaGetPixmapPriv((PixmapPtr)pDst->alphaMap->pDrawable);
+	    exaPrepareAccessReg(pExaScr, pDst->alphaMap->pDrawable,
+				pExaDstAlphaPix, EXA_PREPARE_AUX0, &region);
+	}
     } else {
-	exaPrepareAccess (pDst->pDrawable, EXA_PREPARE_DEST);
-
-	if (pDst->alphaMap && pDst->alphaMap->pDrawable)
-	    exaPrepareAccess(pDst->alphaMap->pDrawable, EXA_PREPARE_AUX0);
+	exaPrepareAccess (pExaScr, pDst->pDrawable, pExaDstPix,
+			  EXA_PREPARE_DEST);
+
+	if (pDst->alphaMap && pDst->alphaMap->pDrawable) {
+	    pExaDstAlphaPix =
+		ExaGetPixmapPriv((PixmapPtr)pDst->alphaMap->pDrawable);
+	    exaPrepareAccess(pExaScr, pDst->alphaMap->pDrawable,
+			     pExaDstAlphaPix, EXA_PREPARE_AUX0);
+	}
     }
 
     EXA_FALLBACK(("from picts %p/%p to pict %p\n",
 		 pSrc, pMask, pDst));
 
     if (pSrc->pDrawable != NULL)
-	exaPrepareAccess (pSrc->pDrawable, EXA_PREPARE_SRC);
-    if (pSrc->alphaMap && pSrc->alphaMap->pDrawable)
-	exaPrepareAccess(pSrc->alphaMap->pDrawable, EXA_PREPARE_AUX2);
+	exaPrepareAccess (pExaScr, pSrc->pDrawable, pExaSrcPix,
+			  EXA_PREPARE_SRC);
+    if (pSrc->alphaMap && pSrc->alphaMap->pDrawable) {
+	pExaSrcAlphaPix =
+	    ExaGetPixmapPriv((PixmapPtr)pSrc->alphaMap->pDrawable);
+	exaPrepareAccess(pExaScr, pSrc->alphaMap->pDrawable, pExaSrcAlphaPix,
+			 EXA_PREPARE_AUX2);
+    }
     if (pMask && pMask->pDrawable != NULL)
-	exaPrepareAccess (pMask->pDrawable, EXA_PREPARE_MASK);
-    if (pMask && pMask->alphaMap && pMask->alphaMap->pDrawable)
-	exaPrepareAccess(pMask->alphaMap->pDrawable, EXA_PREPARE_AUX1);
+	exaPrepareAccess (pExaScr, pMask->pDrawable, pExaMaskPix,
+			  EXA_PREPARE_MASK);
+    if (pMask && pMask->alphaMap && pMask->alphaMap->pDrawable) {
+	pExaMaskAlphaPix =
+	    ExaGetPixmapPriv((PixmapPtr)pMask->alphaMap->pDrawable);
+	exaPrepareAccess(pExaScr, pMask->alphaMap->pDrawable, pExaMaskPix,
+			 EXA_PREPARE_AUX1);
+    }
 #ifdef RENDER
     swap(pExaScr, ps, Composite);
     ps->Composite (op,
@@ -444,16 +482,21 @@ ExaCheckComposite (CARD8      op,
     swap(pExaScr, ps, Composite);
 #endif /* RENDER */
     if (pMask && pMask->pDrawable != NULL)
-	exaFinishAccess (pMask->pDrawable, EXA_PREPARE_MASK);
-    if (pMask && pMask->alphaMap && pMask->alphaMap->pDrawable)
-	exaFinishAccess(pMask->alphaMap->pDrawable, EXA_PREPARE_AUX1);
+	exaFinishAccess(pExaScr, pMask->pDrawable, pExaMaskPix,
+			EXA_PREPARE_MASK);
+    if (pExaMaskAlphaPix)
+	exaFinishAccess(pExaScr, pMask->alphaMap->pDrawable, pExaMaskPix,
+			EXA_PREPARE_AUX1);
     if (pSrc->pDrawable != NULL)
-	exaFinishAccess (pSrc->pDrawable, EXA_PREPARE_SRC);
-    if (pSrc->alphaMap && pSrc->alphaMap->pDrawable)
-	exaFinishAccess(pSrc->alphaMap->pDrawable, EXA_PREPARE_AUX2);
-    exaFinishAccess (pDst->pDrawable, EXA_PREPARE_DEST);
-    if (pDst->alphaMap && pDst->alphaMap->pDrawable)
-	exaFinishAccess(pDst->alphaMap->pDrawable, EXA_PREPARE_AUX0);
+	exaFinishAccess (pExaScr, pSrc->pDrawable, pExaSrcPix,
+			 EXA_PREPARE_SRC);
+    if (pExaSrcAlphaPix)
+	exaFinishAccess(pExaScr, pSrc->alphaMap->pDrawable, pExaSrcPix,
+			EXA_PREPARE_AUX2);
+    exaFinishAccess (pExaScr, pDst->pDrawable, pExaDstPix, EXA_PREPARE_DEST);
+    if (pExaDstAlphaPix)
+	exaFinishAccess(pExaScr, pDst->alphaMap->pDrawable, pExaDstPix,
+			EXA_PREPARE_AUX0);
 
     REGION_UNINIT(pScreen, &region);
 }
@@ -466,6 +509,7 @@ ExaCheckAddTraps (PicturePtr	pPicture,
 		  xTrap		*traps)
 {
     ScreenPtr pScreen = pPicture->pDrawable->pScreen;
+    ExaPixmapPriv(exaGetDrawablePixmap(pPicture->pDrawable));
 #ifdef RENDER
     PictureScreenPtr	ps = GetPictureScreen(pScreen);
 #endif /* RENDER */
@@ -473,13 +517,13 @@ ExaCheckAddTraps (PicturePtr	pPicture,
 
     EXA_FALLBACK(("to pict %p (%c)\n",
 		  exaDrawableLocation(pPicture->pDrawable)));
-    exaPrepareAccess(pPicture->pDrawable, EXA_PREPARE_DEST);
+    exaPrepareAccess(pExaScr, pPicture->pDrawable, pExaPixmap, EXA_PREPARE_DEST);
 #ifdef RENDER
     swap(pExaScr, ps, AddTraps);
     ps->AddTraps (pPicture, x_off, y_off, ntrap, traps);
     swap(pExaScr, ps, AddTraps);
 #endif /* RENDER */
-    exaFinishAccess(pPicture->pDrawable, EXA_PREPARE_DEST);
+    exaFinishAccess(pExaScr, pPicture->pDrawable, pExaPixmap, EXA_PREPARE_DEST);
 }
 
 /**
@@ -491,6 +535,7 @@ ExaCheckAddTraps (PicturePtr	pPicture,
 CARD32
 exaGetPixmapFirstPixel (PixmapPtr pPixmap)
 {
+    ExaScreenPriv(pPixmap->drawable.pScreen);
     CARD32 pixel;
     void *fb;
     Bool need_finish = FALSE;
@@ -501,7 +546,7 @@ exaGetPixmapFirstPixel (PixmapPtr pPixmap)
 	!miPointInRegion(&pExaPixmap->validSys, 0, 0,  &box);
     Bool damaged = pExaPixmap->pDamage &&
  	miPointInRegion(DamageRegion(pExaPixmap->pDamage), 0, 0, &box);
-    Bool offscreen = exaPixmapIsOffscreen(pPixmap);
+    Bool offscreen = exaPixmapIsOffscreen(pExaScr, pExaPixmap);
 
     fb = pExaPixmap->sys_ptr;
 
@@ -517,7 +562,8 @@ exaGetPixmapFirstPixel (PixmapPtr pPixmap)
 
 	need_finish = TRUE;
 
-	exaPrepareAccessReg(&pPixmap->drawable, EXA_PREPARE_SRC, &migration);
+	exaPrepareAccessReg(pExaScr, &pPixmap->drawable, pExaPixmap, EXA_PREPARE_SRC,
+			    &migration);
 	fb = pPixmap->devPrivate.ptr;
     }
 
@@ -534,7 +580,7 @@ exaGetPixmapFirstPixel (PixmapPtr pPixmap)
     }
 
     if (need_finish) {
-	exaFinishAccess(&pPixmap->drawable, EXA_PREPARE_SRC);
+	exaFinishAccess(pExaScr, &pPixmap->drawable, pExaPixmap, EXA_PREPARE_SRC);
 	REGION_UNINIT(pScreen, &migration);
     }
 
-- 
1.6.2.rc1



More information about the xorg-devel mailing list