[Xquartz-changes] xserver: Branch 'master' - 14 commits

Jeremy Huddleston jeremyhu at freedesktop.org
Mon Nov 30 10:49:11 PST 2009


 Xext/geext.c                         |    9 -
 Xi/xiproperty.c                      |    2 
 configure.ac                         |    8 -
 dix/devices.c                        |    2 
 dix/ptrveloc.c                       |   64 +++++++++---
 doc/Xserver.man.pre                  |    4 
 exa/exa.c                            |  184 ++++++++++-------------------------
 exa/exa.h                            |    6 -
 exa/exa_accel.c                      |   50 ++++++---
 exa/exa_classic.c                    |   22 ++--
 exa/exa_driver.c                     |   19 ++-
 exa/exa_glyphs.c                     |   59 +++++------
 exa/exa_migration_classic.c          |   40 +++----
 exa/exa_migration_mixed.c            |   47 +++-----
 exa/exa_mixed.c                      |   24 +++-
 exa/exa_offscreen.c                  |   37 +------
 exa/exa_priv.h                       |   29 +++--
 exa/exa_render.c                     |    6 -
 exa/exa_unaccel.c                    |   73 +++++++------
 fb/fbpict.c                          |    6 -
 hw/xfree86/doc/man/Xorg.man.pre      |    2 
 hw/xfree86/doc/man/xorg.conf.man.pre |   12 +-
 include/ptrveloc.h                   |    3 
 include/site.h                       |    2 
 test/input.c                         |   54 ++++++++++
 25 files changed, 411 insertions(+), 353 deletions(-)

New commits:
commit 66a9616d645f5a23225251d197e00b94c79274f6
Author: Michel Dänzer <daenzer at vmware.com>
Date:   Mon Nov 30 13:17:53 2009 +0100

    fb: Don't crash if copy_drawable() returns NULL.
    
    Fixes http://bugs.freedesktop.org/show_bug.cgi?id=24634 .
    
    Signed-off-by: Michel Dänzer <daenzer at vmware.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/fb/fbpict.c b/fb/fbpict.c
index 2fbef15..7ae3ec5 100644
--- a/fb/fbpict.c
+++ b/fb/fbpict.c
@@ -329,9 +329,11 @@ create_bits_picture (PicturePtr pict,
     pixman_image_t *image;
     DrawablePtr drawable;
 
-    if (is_src && pict->pDrawable->type == DRAWABLE_WINDOW)
+    if (is_src && pict->pDrawable->type == DRAWABLE_WINDOW) {
 	drawable = copy_drawable (pict->pDrawable);
-    else
+	if (!drawable)
+	    return NULL;
+    } else
 	drawable = pict->pDrawable;
     
     fbGetDrawable (drawable, bits, stride, bpp, xoff, yoff);
commit 8754db77d8169e5ea506a963cebee1a651bcf094
Author: Michel Dänzer <daenzer at vmware.com>
Date:   Mon Nov 30 13:17:52 2009 +0100

    EXA: Don't defragment offscreen memory at allocation time.
    
    Fixes http://bugs.freedesktop.org/show_bug.cgi?id=24300 .
    
    Offscreen memory allocation can occur from various places, and apparently
    doing defragmentation from at least some of them can confuse some driver
    acceleration code.
    
    There's still the regular background defragmentation in the WakeupHandler,
    which should manage to keep fragmentation at a reasonable level.
    
    Signed-off-by: Michel Dänzer <daenzer at vmware.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/exa/exa_offscreen.c b/exa/exa_offscreen.c
index acdf439..e3a9ab2 100644
--- a/exa/exa_offscreen.c
+++ b/exa/exa_offscreen.c
@@ -169,7 +169,7 @@ exaOffscreenAlloc (ScreenPtr pScreen, int size, int align,
 {
     ExaOffscreenArea *area;
     ExaScreenPriv (pScreen);
-    int real_size = 0, free_total = 0, largest_avail = 0;
+    int real_size = 0, largest_avail = 0;
 #if DEBUG_OFFSCREEN
     static int number = 0;
     ErrorF("================= ============ allocating a new pixmap %d\n", ++number);
@@ -208,33 +208,10 @@ exaOffscreenAlloc (ScreenPtr pScreen, int size, int align,
 	if (real_size <= area->size)
 	    break;
 
-	free_total += area->size;
-
 	if (area->size > largest_avail)
 	    largest_avail = area->size;
     }
 
-    if (!area && free_total >= size) {
-	CARD32 now = GetTimeInMillis();
-
-	/* Don't defragment more than once per second, to avoid adding more
-	 * overhead than we're trying to prevent
-	 */
-	if (abs((INT32) (now - pExaScr->lastDefragment)) > 1000) {
-	    area = ExaOffscreenDefragment(pScreen);
-	    pExaScr->lastDefragment = now;
-
-	    if (area) {
-		/* adjust size to match alignment requirement */
-		real_size = size + (area->base_offset + area->size - size) % align;
-
-		/* does it fit? */
-		if (real_size > area->size)
-		    area = NULL;
-	    }
-	}
-    }
-
     if (!area)
     {
 	area = exaFindAreaToEvict(pExaScr, size, align);
commit 0e555a1033e5deed1db8582ca075455a6a2d4228
Author: Michel Dänzer <daenzer at vmware.com>
Date:   Mon Nov 30 13:17:51 2009 +0100

    Revert "EXA: Accumulate arbitrary number of glyphs without flushing."
    
    This reverts commit c11678cc189551f2a01eaa7a63969c16950739b4.
    
    Not sure what I was thinking, turns out alloca() of a size derived from client
    input is a bad idea.
    
    Signed-off-by: Michel Dänzer <daenzer at vmware.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/exa/exa_glyphs.c b/exa/exa_glyphs.c
index 4bc80eb..fd14e9b 100644
--- a/exa/exa_glyphs.c
+++ b/exa/exa_glyphs.c
@@ -62,10 +62,15 @@
  */
 #define CACHE_PICTURE_WIDTH 1024
 
+/* Maximum number of glyphs we buffer on the stack before flushing
+ * rendering to the mask or destination surface.
+ */
+#define GLYPH_BUFFER_SIZE 256
+
 typedef struct {
     PicturePtr mask;
+    ExaCompositeRectRec rects[GLYPH_BUFFER_SIZE];
     int count;
-    ExaCompositeRectRec rects[0];
 } ExaGlyphBuffer, *ExaGlyphBufferPtr;
 
 typedef enum {
@@ -552,13 +557,16 @@ exaBufferGlyph(ScreenPtr         pScreen,
 	       INT16             yDst)
 {
     ExaScreenPriv(pScreen);
-    PicturePtr mask = GlyphPicture(pGlyph)[pScreen->myNum];
-    unsigned int format = mask->format;
+    unsigned int format = (GlyphPicture(pGlyph)[pScreen->myNum])->format;
     int width = pGlyph->info.width;
     int height = pGlyph->info.height;
     ExaCompositeRectPtr rect;
+    PicturePtr mask;
     int i;
 
+    if (buffer->count == GLYPH_BUFFER_SIZE)
+	return ExaGlyphNeedFlush;
+
     if (PICT_FORMAT_BPP(format) == 1)
 	format = PICT_a8;
     
@@ -589,6 +597,7 @@ exaBufferGlyph(ScreenPtr         pScreen,
 
     /* Couldn't find the glyph in the cache, use the glyph picture directly */
 
+    mask = GlyphPicture(pGlyph)[pScreen->myNum];
     if (buffer->mask && buffer->mask != mask)
 	return ExaGlyphNeedFlush;
 
@@ -702,18 +711,12 @@ exaGlyphs (CARD8 	 op,
     int		width = 0, height = 0;
     int		x, y;
     int		first_xOff = list->xOff, first_yOff = list->yOff;
-    int		i, n;
+    int		n;
     GlyphPtr	glyph;
     int		error;
     BoxRec	extents = {0, 0, 0, 0};
     CARD32	component_alpha;
-    ExaGlyphBufferPtr buffer;
-
-    for (i = 0, n = 0; i < nlist; i++)
-	n += list[i].len;
-    buffer = alloca(sizeof(ExaGlyphBuffer) + n * sizeof(ExaCompositeRectRec));
-    if (!buffer)
-	return;
+    ExaGlyphBuffer buffer;
 
     if (maskFormat)
     {
@@ -793,8 +796,8 @@ exaGlyphs (CARD8 	 op,
 	x = 0;
 	y = 0;
     }
-    buffer->count = 0;
-    buffer->mask = NULL;
+    buffer.count = 0;
+    buffer.mask = NULL;
     while (nlist--)
     {
 	x += list->xOff;
@@ -809,23 +812,23 @@ exaGlyphs (CARD8 	 op,
 		/* pGlyph->info.{x,y} compensate for empty space in the glyph. */
 		if (maskFormat)
 		{
-		    if (exaBufferGlyph(pScreen, buffer, glyph, NULL, pMask,
+		    if (exaBufferGlyph(pScreen, &buffer, glyph, NULL, pMask,
 				       0, 0, 0, 0, x - glyph->info.x, y - glyph->info.y) == ExaGlyphNeedFlush)
 		    {
-			exaGlyphsToMask(pMask, buffer);
-			exaBufferGlyph(pScreen, buffer, glyph, NULL, pMask,
+			exaGlyphsToMask(pMask, &buffer);
+			exaBufferGlyph(pScreen, &buffer, glyph, NULL, pMask,
 				       0, 0, 0, 0, x - glyph->info.x, y - glyph->info.y);
 		    }
 		}
 		else
 		{
-		    if (exaBufferGlyph(pScreen, buffer, glyph, pSrc, pDst,
+		    if (exaBufferGlyph(pScreen, &buffer, glyph, pSrc, pDst,
 				       xSrc + (x - glyph->info.x) - first_xOff, ySrc + (y - glyph->info.y) - first_yOff,
 				       0, 0, x - glyph->info.x, y - glyph->info.y)
 			== ExaGlyphNeedFlush)
 		    {
-			exaGlyphsToDst(pSrc, pDst, buffer);
-			exaBufferGlyph(pScreen, buffer, glyph, pSrc, pDst,
+			exaGlyphsToDst(pSrc, pDst, &buffer);
+			exaBufferGlyph(pScreen, &buffer, glyph, pSrc, pDst,
 				       xSrc + (x - glyph->info.x) - first_xOff, ySrc + (y - glyph->info.y) - first_yOff,
 				       0, 0, x - glyph->info.x, y - glyph->info.y);
 		    }
@@ -838,11 +841,11 @@ exaGlyphs (CARD8 	 op,
 	list++;
     }
     
-    if (buffer->count) {
+    if (buffer.count) {
         if (maskFormat)
-	    exaGlyphsToMask(pMask, buffer);
+	    exaGlyphsToMask(pMask, &buffer);
         else
-	    exaGlyphsToDst(pSrc, pDst, buffer);
+	    exaGlyphsToDst(pSrc, pDst, &buffer);
     }
 
     if (maskFormat)
commit 99d88ef69d5f7dbf99ca605eceb92f42230a89f4
Author: Maarten Maathuis <madman2003 at gmail.com>
Date:   Sat Nov 28 10:34:45 2009 +0100

    exa: a few small pitch related changes
    
    - Setting pitch before exaCopyDirty* is not needed.
    
    Signed-off-by: Maarten Maathuis <madman2003 at gmail.com>
    Acked-by: Michel Dänzer <michel at daenzer.net>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/exa/exa.c b/exa/exa.c
index 023288c..16f39f6 100644
--- a/exa/exa.c
+++ b/exa/exa.c
@@ -323,10 +323,17 @@ ExaDoPrepareAccess(PixmapPtr pPixmap, int index)
 
     has_gpu_copy = exaPixmapHasGpuCopy(pPixmap);
 
-    if (has_gpu_copy && pExaPixmap->fb_ptr)
+    if (has_gpu_copy) {
+	/* This can be NULL, but the driver prepareAccess call should
+	 * take care of that. */
 	pPixmap->devPrivate.ptr = pExaPixmap->fb_ptr;
-    else
+	pPixmap->devKind = pExaPixmap->fb_pitch;
+    } else {
+	/* For mixed pixmaps this can be NULL, but that will be fixed
+	 * later in exaPrepareAccessReg_mixed(). */
 	pPixmap->devPrivate.ptr = pExaPixmap->sys_ptr;
+	pPixmap->devKind = pExaPixmap->sys_pitch;
+    }
 
     /* Store so we can handle repeated / nested calls. */
     pExaScr->access[index].pixmap = pPixmap;
diff --git a/exa/exa_migration_mixed.c b/exa/exa_migration_mixed.c
index a7fdf63..ee32b21 100644
--- a/exa/exa_migration_mixed.c
+++ b/exa/exa_migration_mixed.c
@@ -101,7 +101,6 @@ exaDoMigration_mixed(ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel)
 	if (pExaPixmap->pDamage && exaPixmapHasGpuCopy(pPixmap)) {
 	    ExaScreenPriv(pPixmap->drawable.pScreen);
 
-	    pPixmap->devKind = pExaPixmap->fb_pitch;
 	    exaCopyDirtyToFb(pixmaps + i);
 
 	    if (pExaScr->deferred_mixed_pixmap == pPixmap)
@@ -109,6 +108,10 @@ exaDoMigration_mixed(ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel)
 	}
 
 	pExaPixmap->use_gpu_copy = exaPixmapHasGpuCopy(pPixmap);
+	if (pExaPixmap->use_gpu_copy)
+	    pPixmap->devKind = pExaPixmap->fb_pitch;
+	else
+	    pPixmap->devKind = pExaPixmap->sys_pitch;
     }
 }
 
@@ -183,17 +186,14 @@ exaPrepareAccessReg_mixed(PixmapPtr pPixmap, int index, RegionPtr pReg)
 		    pixmaps[0].as_src = TRUE;
 		    pixmaps[0].pReg = NULL;
 		}
-		pPixmap->devKind = pExaPixmap->fb_pitch;
 		exaCopyDirtyToSys(pixmaps);
 	    }
 
 	    if (as_dst)
 		exaPixmapDirty(pPixmap, 0, 0, pPixmap->drawable.width,
 			       pPixmap->drawable.height);
-	} else if (has_gpu_copy) {
-	    pPixmap->devKind = pExaPixmap->fb_pitch;
+	} else if (has_gpu_copy)
 	    exaCopyDirtyToSys(pixmaps);
-	}
 
 	pPixmap->devPrivate.ptr = pExaPixmap->sys_ptr;
 	pPixmap->devKind = pExaPixmap->sys_pitch;
@@ -222,7 +222,6 @@ void exaFinishAccess_mixed(PixmapPtr pPixmap, int index)
 		pExaScr->deferred_mixed_pixmap != pPixmap)
 		exaMoveInPixmap_mixed(pExaScr->deferred_mixed_pixmap);
 	    pExaScr->deferred_mixed_pixmap = pPixmap;
-	    pPixmap->devKind = pExaPixmap->fb_pitch;
 	} else
 	    exaMoveInPixmap_mixed(pPixmap);
     }
commit a54c23fe647cb4d610d871094193ae5959606008
Author: Maarten Maathuis <madman2003 at gmail.com>
Date:   Sat Nov 28 10:34:44 2009 +0100

    exa: s/PixmapIsOffscreen/PixmapHasGpuCopy and s/pExaPixmap->offscreen/pExaPixmap->use_gpu_copy
    
    - Fixup some variable names as well.
    
    Signed-off-by: Maarten Maathuis <madman2003 at gmail.com>
    Acked-by: Michel Dänzer <michel at daenzer.net>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/exa/exa.c b/exa/exa.c
index ed28431..023288c 100644
--- a/exa/exa.c
+++ b/exa/exa.c
@@ -233,19 +233,19 @@ exaPixmapIsPinned (PixmapPtr pPix)
 }
 
 /**
- * exaPixmapIsOffscreen() is used to determine if a pixmap is in offscreen
+ * exaPixmapHasGpuCopy() is used to determine if a pixmap is in offscreen
  * memory, meaning that acceleration could probably be done to it, and that it
  * will need to be wrapped by PrepareAccess()/FinishAccess() when accessing it
  * with the CPU.
  *
  * Note that except for UploadToScreen()/DownloadFromScreen() (which explicitly
  * deal with moving pixmaps in and out of system memory), EXA will give drivers
- * pixmaps as arguments for which exaPixmapIsOffscreen() is TRUE.
+ * pixmaps as arguments for which exaPixmapHasGpuCopy() is TRUE.
  *
  * @return TRUE if the given drawable is in framebuffer memory.
  */
 Bool
-exaPixmapIsOffscreen(PixmapPtr pPixmap)
+exaPixmapHasGpuCopy(PixmapPtr pPixmap)
 {
     ScreenPtr	pScreen = pPixmap->drawable.pScreen;
     ExaScreenPriv(pScreen);
@@ -253,16 +253,16 @@ exaPixmapIsOffscreen(PixmapPtr pPixmap)
     if (!(pExaScr->info->flags & EXA_OFFSCREEN_PIXMAPS))
 	return FALSE;
 
-    return (*pExaScr->pixmap_is_offscreen)(pPixmap);
+    return (*pExaScr->pixmap_has_gpu_copy)(pPixmap);
 }
 
 /**
- * exaDrawableIsOffscreen() is a convenience wrapper for exaPixmapIsOffscreen().
+ * exaDrawableIsOffscreen() is a convenience wrapper for exaPixmapHasGpuCopy().
  */
 Bool
 exaDrawableIsOffscreen (DrawablePtr pDrawable)
 {
-    return exaPixmapIsOffscreen (exaGetDrawablePixmap (pDrawable));
+    return exaPixmapHasGpuCopy (exaGetDrawablePixmap (pDrawable));
 }
 
 /**
@@ -276,7 +276,7 @@ exaGetOffscreenPixmap (DrawablePtr pDrawable, int *xp, int *yp)
 
     exaGetDrawableDeltas (pDrawable, pPixmap, xp, yp);
 
-    if (exaPixmapIsOffscreen (pPixmap))
+    if (exaPixmapHasGpuCopy (pPixmap))
 	return pPixmap;
     else
 	return NULL;
@@ -291,7 +291,7 @@ ExaDoPrepareAccess(PixmapPtr pPixmap, int index)
     ScreenPtr pScreen = pPixmap->drawable.pScreen;
     ExaScreenPriv (pScreen);
     ExaPixmapPriv(pPixmap);
-    Bool offscreen;
+    Bool has_gpu_copy;
     int i;
 
     if (!(pExaScr->info->flags & EXA_OFFSCREEN_PIXMAPS))
@@ -321,9 +321,9 @@ ExaDoPrepareAccess(PixmapPtr pPixmap, int index)
 			     pPixmap->devPrivate.ptr));
     }
 
-    offscreen = exaPixmapIsOffscreen(pPixmap);
+    has_gpu_copy = exaPixmapHasGpuCopy(pPixmap);
 
-    if (offscreen && pExaPixmap->fb_ptr)
+    if (has_gpu_copy && pExaPixmap->fb_ptr)
 	pPixmap->devPrivate.ptr = pExaPixmap->fb_ptr;
     else
 	pPixmap->devPrivate.ptr = pExaPixmap->sys_ptr;
@@ -332,7 +332,7 @@ ExaDoPrepareAccess(PixmapPtr pPixmap, int index)
     pExaScr->access[index].pixmap = pPixmap;
     pExaScr->access[index].count = 1;
 
-    if (!offscreen)
+    if (!has_gpu_copy)
 	return FALSE;
 
     exaWaitSync (pScreen);
@@ -420,7 +420,7 @@ exaFinishAccess(DrawablePtr pDrawable, int index)
     if (pExaScr->finish_access)
 	pExaScr->finish_access(pPixmap, index);
 
-    if (!pExaScr->info->FinishAccess || !exaPixmapIsOffscreen(pPixmap))
+    if (!pExaScr->info->FinishAccess || !exaPixmapHasGpuCopy(pPixmap))
 	return;
 
     if (i >= EXA_PREPARE_AUX_DEST &&
@@ -969,7 +969,7 @@ exaDriverInit (ScreenPtr		pScreen,
 		wrap(pExaScr, pScreen, DestroyPixmap, exaDestroyPixmap_mixed);
 		wrap(pExaScr, pScreen, ModifyPixmapHeader, exaModifyPixmapHeader_mixed);
 		pExaScr->do_migration = exaDoMigration_mixed;
-		pExaScr->pixmap_is_offscreen = exaPixmapIsOffscreen_mixed;
+		pExaScr->pixmap_has_gpu_copy = exaPixmapHasGpuCopy_mixed;
 		pExaScr->do_move_in_pixmap = exaMoveInPixmap_mixed;
 		pExaScr->do_move_out_pixmap = NULL;
 		pExaScr->prepare_access_reg = exaPrepareAccessReg_mixed;
@@ -979,7 +979,7 @@ exaDriverInit (ScreenPtr		pScreen,
 		wrap(pExaScr, pScreen, DestroyPixmap, exaDestroyPixmap_driver);
 		wrap(pExaScr, pScreen, ModifyPixmapHeader, exaModifyPixmapHeader_driver);
 		pExaScr->do_migration = NULL;
-		pExaScr->pixmap_is_offscreen = exaPixmapIsOffscreen_driver;
+		pExaScr->pixmap_has_gpu_copy = exaPixmapHasGpuCopy_driver;
 		pExaScr->do_move_in_pixmap = NULL;
 		pExaScr->do_move_out_pixmap = NULL;
 		pExaScr->prepare_access_reg = NULL;
@@ -990,7 +990,7 @@ exaDriverInit (ScreenPtr		pScreen,
 	    wrap(pExaScr, pScreen, DestroyPixmap, exaDestroyPixmap_classic);
 	    wrap(pExaScr, pScreen, ModifyPixmapHeader, exaModifyPixmapHeader_classic);
 	    pExaScr->do_migration = exaDoMigration_classic;
-	    pExaScr->pixmap_is_offscreen = exaPixmapIsOffscreen_classic;
+	    pExaScr->pixmap_has_gpu_copy = exaPixmapHasGpuCopy_classic;
 	    pExaScr->do_move_in_pixmap = exaMoveInPixmap_classic;
 	    pExaScr->do_move_out_pixmap = exaMoveOutPixmap_classic;
 	    pExaScr->prepare_access_reg = exaPrepareAccessReg_classic;
diff --git a/exa/exa.h b/exa/exa.h
index 4b39473..8c93d15 100644
--- a/exa/exa.h
+++ b/exa/exa.h
@@ -624,13 +624,13 @@ typedef struct _ExaDriver {
 
     /**
      * PixmapIsOffscreen() is an optional driver replacement to
-     * exaPixmapIsOffscreen(). Set to NULL if you want the standard behaviour
-     * of exaPixmapIsOffscreen().
+     * exaPixmapHasGpuCopy(). Set to NULL if you want the standard behaviour
+     * of exaPixmapHasGpuCopy().
      *
      * @param pPix the pixmap
      * @return TRUE if the given drawable is in framebuffer memory.
      *
-     * exaPixmapIsOffscreen() is used to determine if a pixmap is in offscreen
+     * exaPixmapHasGpuCopy() is used to determine if a pixmap is in offscreen
      * memory, meaning that acceleration could probably be done to it, and that it
      * will need to be wrapped by PrepareAccess()/FinishAccess() when accessing it
      * with the CPU.
diff --git a/exa/exa_accel.c b/exa/exa_accel.c
index 3de7307..1d88acb 100644
--- a/exa/exa_accel.c
+++ b/exa/exa_accel.c
@@ -482,9 +482,9 @@ exaHWCopyNtoN (DrawablePtr    pSrcDrawable,
 	goto fallback;
     }
 
-    if (exaPixmapIsOffscreen(pDstPixmap)) {
+    if (exaPixmapHasGpuCopy(pDstPixmap)) {
 	/* Normal blitting. */
-	if (exaPixmapIsOffscreen(pSrcPixmap)) {
+	if (exaPixmapHasGpuCopy(pSrcPixmap)) {
 	    if (!(*pExaScr->info->PrepareCopy) (pSrcPixmap, pDstPixmap, reverse ? -1 : 1,
 						upsidedown ? -1 : 1,
 						pGC ? pGC->alu : GXcopy,
@@ -840,7 +840,7 @@ exaPolyFillRect(DrawablePtr pDrawable,
 	exaDoMigration (pixmaps, 1, TRUE);
     }
 
-    if (!exaPixmapIsOffscreen (pPixmap) ||
+    if (!exaPixmapHasGpuCopy (pPixmap) ||
 	!(*pExaScr->info->PrepareSolid) (pPixmap,
 					 pGC->alu,
 					 pGC->planemask,
@@ -1022,7 +1022,7 @@ exaFillRegionSolid (DrawablePtr	pDrawable, RegionPtr pRegion, Pixel pixel,
 	exaDoMigration (pixmaps, 1, TRUE);
     }
 
-    if (exaPixmapIsOffscreen (pPixmap) &&
+    if (exaPixmapHasGpuCopy (pPixmap) &&
 	(*pExaScr->info->PrepareSolid) (pPixmap, alu, planemask, pixel))
     {
 	int nbox;
@@ -1125,7 +1125,7 @@ exaFillRegionTiled (DrawablePtr pDrawable, RegionPtr pRegion, PixmapPtr pTile,
 
     pPixmap = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff);
 
-    if (!pPixmap || !exaPixmapIsOffscreen(pTile))
+    if (!pPixmap || !exaPixmapHasGpuCopy(pTile))
 	return FALSE;
 
     if ((*pExaScr->info->PrepareCopy) (pTile, pPixmap, 1, 1, alu, planemask))
diff --git a/exa/exa_classic.c b/exa/exa_classic.c
index 12f3987..c31e2d4 100644
--- a/exa/exa_classic.c
+++ b/exa/exa_classic.c
@@ -38,7 +38,7 @@ ExaGetPixmapAddress(PixmapPtr p)
 {
     ExaPixmapPriv(p);
 
-    if (pExaPixmap->offscreen && pExaPixmap->fb_ptr)
+    if (pExaPixmap->use_gpu_copy && pExaPixmap->fb_ptr)
 	return pExaPixmap->fb_ptr;
     else
 	return pExaPixmap->sys_ptr;
@@ -90,7 +90,7 @@ exaCreatePixmap_classic(ScreenPtr pScreen, int w, int h, int depth,
     pExaPixmap->sys_pitch = pPixmap->devKind;
 
     pPixmap->devPrivate.ptr = NULL;
-    pExaPixmap->offscreen = FALSE;
+    pExaPixmap->use_gpu_copy = FALSE;
 
     pExaPixmap->fb_ptr = NULL;
     exaSetFbPitch(pExaScr, pExaPixmap, w, h, bpp);
@@ -168,7 +168,7 @@ exaModifyPixmapHeader_classic(PixmapPtr pPixmap, int width, int height, int dept
 
 	/* Classic EXA:
 	 * - Framebuffer.
-	 * - Scratch pixmap with offscreen memory.
+	 * - Scratch pixmap with gpu memory.
 	 */
 	if (pExaScr->info->memoryBase && pPixData) {
 	    if ((CARD8 *)pPixData >= pExaScr->info->memoryBase &&
@@ -176,7 +176,7 @@ exaModifyPixmapHeader_classic(PixmapPtr pPixmap, int width, int height, int dept
 				pExaScr->info->memorySize) {
 		pExaPixmap->fb_ptr = pPixData;
 		pExaPixmap->fb_pitch = devKind;
-		pExaPixmap->offscreen = TRUE;
+		pExaPixmap->use_gpu_copy = TRUE;
 	    }
 	}
 
@@ -189,7 +189,7 @@ exaModifyPixmapHeader_classic(PixmapPtr pPixmap, int width, int height, int dept
         }
 
 	/* Pixmaps subject to ModifyPixmapHeader will be pinned to system or
-	 * offscreen memory, so there's no need to track damage.
+	 * gpu memory, so there's no need to track damage.
 	 */
 	if (pExaPixmap->pDamage) {
 	    DamageUnregister(&pPixmap->drawable, pExaPixmap->pDamage);
@@ -248,7 +248,7 @@ exaDestroyPixmap_classic (PixmapPtr pPixmap)
 }
 
 Bool
-exaPixmapIsOffscreen_classic(PixmapPtr pPixmap)
+exaPixmapHasGpuCopy_classic(PixmapPtr pPixmap)
 {
     ScreenPtr pScreen = pPixmap->drawable.pScreen;
     ExaScreenPriv(pScreen);
@@ -260,7 +260,7 @@ exaPixmapIsOffscreen_classic(PixmapPtr pPixmap)
 	ret = pExaScr->info->PixmapIsOffscreen(pPixmap);
 	pPixmap->devPrivate.ptr = NULL;
     } else
-	ret = (pExaPixmap->offscreen && pExaPixmap->fb_ptr);
+	ret = (pExaPixmap->use_gpu_copy && pExaPixmap->fb_ptr);
 
     return ret;
 }
diff --git a/exa/exa_driver.c b/exa/exa_driver.c
index f55c300..dcf1a98 100644
--- a/exa/exa_driver.c
+++ b/exa/exa_driver.c
@@ -71,8 +71,8 @@ exaCreatePixmap_driver(ScreenPtr pScreen, int w, int h, int depth,
 
     bpp = pPixmap->drawable.bitsPerPixel;
 
-    /* Set this before driver hooks, to allow for !offscreen pixmaps.
-     * !offscreen pixmaps have a valid pointer at all times.
+    /* Set this before driver hooks, to allow for driver pixmaps without gpu
+     * memory to back it. These pixmaps have a valid pointer at all times.
      */
     pPixmap->devPrivate.ptr = NULL;
 
@@ -157,8 +157,9 @@ exaModifyPixmapHeader_driver(PixmapPtr pPixmap, int width, int height, int depth
 	ret = pExaScr->info->ModifyPixmapHeader(pPixmap, width, height, depth,
 						bitsPerPixel, devKind, pPixData);
 	/* For EXA_HANDLES_PIXMAPS, we set pPixData to NULL.
-	 * If pPixmap->devPrivate.ptr is non-NULL, then we've got a non-offscreen pixmap.
-	 * We need to store the pointer, because PrepareAccess won't be called.
+	 * If pPixmap->devPrivate.ptr is non-NULL, then we've got a
+	 * !has_gpu_copy pixmap. We need to store the pointer,
+	 * because PrepareAccess won't be called.
 	 */
 	if (!pPixData && pPixmap->devPrivate.ptr && pPixmap->devKind) {
 	    pExaPixmap->sys_ptr = pPixmap->devPrivate.ptr;
@@ -208,7 +209,7 @@ exaDestroyPixmap_driver (PixmapPtr pPixmap)
 }
 
 Bool
-exaPixmapIsOffscreen_driver(PixmapPtr pPixmap)
+exaPixmapHasGpuCopy_driver(PixmapPtr pPixmap)
 {
     ScreenPtr pScreen = pPixmap->drawable.pScreen;
     ExaScreenPriv(pScreen);
diff --git a/exa/exa_glyphs.c b/exa/exa_glyphs.c
index 5a37004..4bc80eb 100644
--- a/exa/exa_glyphs.c
+++ b/exa/exa_glyphs.c
@@ -347,11 +347,11 @@ exaGlyphCacheHashRemove(ExaGlyphCachePtr cache,
 
 /* The most efficient thing to way to upload the glyph to the screen
  * is to use the UploadToScreen() driver hook; this allows us to
- * pipeline glyph uploads and to avoid creating offscreen pixmaps for
+ * pipeline glyph uploads and to avoid creating gpu backed pixmaps for
  * glyphs that we'll never use again.
  *
- * If we can't do it with UploadToScreen (because the glyph is offscreen, etc),
- * we fall back to CompositePicture.
+ * If we can't do it with UploadToScreen (because the glyph has a gpu copy,
+ * etc), we fall back to CompositePicture.
  *
  * We need to damage the cache pixmap manually in either case because the damage
  * layer unwrapped the picture screen before calling exaGlyphs.
@@ -374,7 +374,7 @@ exaGlyphCacheUploadGlyph(ScreenPtr         pScreen,
 
     /* If the glyph pixmap is already uploaded, no point in doing
      * things this way */
-    if (exaPixmapIsOffscreen(pGlyphPixmap))
+    if (exaPixmapHasGpuCopy(pGlyphPixmap))
 	goto composite;
 
     /* UploadToScreen only works if bpp match */
@@ -384,7 +384,7 @@ exaGlyphCacheUploadGlyph(ScreenPtr         pScreen,
     if (pExaScr->do_migration) {
 	ExaMigrationRec pixmaps[1];
 
-	/* cache pixmap must be offscreen. */
+	/* cache pixmap must have a gpu copy. */
 	pixmaps[0].as_dst = TRUE;
 	pixmaps[0].as_src = FALSE;
 	pixmaps[0].pPix = pCachePixmap;
@@ -392,7 +392,7 @@ exaGlyphCacheUploadGlyph(ScreenPtr         pScreen,
 	exaDoMigration (pixmaps, 1, TRUE);
     }
 
-    if (!exaPixmapIsOffscreen(pCachePixmap))
+    if (!exaPixmapHasGpuCopy(pCachePixmap))
 	goto composite;
 
     /* x,y are in pixmap coordinates, no need for cache{X,Y}off */
diff --git a/exa/exa_migration_classic.c b/exa/exa_migration_classic.c
index 6d7b9f5..95189be 100644
--- a/exa/exa_migration_classic.c
+++ b/exa/exa_migration_classic.c
@@ -111,7 +111,7 @@ exaCopyDirty(ExaMigrationPtr migrate, RegionPtr pValidDst, RegionPtr pValidSrc,
     ExaPixmapPriv (pPixmap);
     RegionPtr damage = DamageRegion (pExaPixmap->pDamage);
     RegionRec CopyReg;
-    Bool save_offscreen;
+    Bool save_use_gpu_copy;
     int save_pitch;
     BoxPtr pBox;
     int nbox;
@@ -119,7 +119,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 (pExaPixmap->offscreen) {
+    if (pExaPixmap->use_gpu_copy) {
 	REGION_UNION(pScreen, &pExaPixmap->validFB, &pExaPixmap->validFB,
 		     damage);
 	REGION_SUBTRACT(pScreen, &pExaPixmap->validSys, &pExaPixmap->validSys,
@@ -200,9 +200,9 @@ exaCopyDirty(ExaMigrationPtr migrate, RegionPtr pValidDst, RegionPtr pValidSrc,
     pBox = REGION_RECTS(&CopyReg);
     nbox = REGION_NUM_RECTS(&CopyReg);
 
-    save_offscreen = pExaPixmap->offscreen;
+    save_use_gpu_copy = pExaPixmap->use_gpu_copy;
     save_pitch = pPixmap->devKind;
-    pExaPixmap->offscreen = TRUE;
+    pExaPixmap->use_gpu_copy = TRUE;
     pPixmap->devKind = pExaPixmap->fb_pitch;
 
     while (nbox--) {
@@ -242,7 +242,7 @@ exaCopyDirty(ExaMigrationPtr migrate, RegionPtr pValidDst, RegionPtr pValidSrc,
 	pBox++;
     }
 
-    pExaPixmap->offscreen = save_offscreen;
+    pExaPixmap->use_gpu_copy = save_use_gpu_copy;
     pPixmap->devKind = save_pitch;
 
     /* Try to prevent source valid region from growing too many rects by
@@ -351,7 +351,7 @@ exaDoMoveInPixmap (ExaMigrationPtr migrate)
 
     exaCopyDirtyToFb (migrate);
 
-    if (exaPixmapIsOffscreen(pPixmap))
+    if (exaPixmapHasGpuCopy(pPixmap))
 	return;
 
     DBG_MIGRATE (("-> %p (0x%x) (%dx%d) (%c)\n", pPixmap,
@@ -361,7 +361,7 @@ exaDoMoveInPixmap (ExaMigrationPtr migrate)
 		  pPixmap->drawable.height,
 		  exaPixmapIsDirty(pPixmap) ? 'd' : 'c'));
 
-    pExaPixmap->offscreen = TRUE;
+    pExaPixmap->use_gpu_copy = TRUE;
 
     pPixmap->devKind = pExaPixmap->fb_pitch;
     pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
@@ -392,7 +392,7 @@ exaDoMoveOutPixmap (ExaMigrationPtr migrate)
 
     exaCopyDirtyToSys (migrate);
 
-    if (exaPixmapIsOffscreen(pPixmap)) {
+    if (exaPixmapHasGpuCopy(pPixmap)) {
 
 	DBG_MIGRATE (("<- %p (%p) (%dx%d) (%c)\n", pPixmap,
 		      (void*)(ExaGetPixmapPriv(pPixmap)->area ?
@@ -401,7 +401,7 @@ exaDoMoveOutPixmap (ExaMigrationPtr migrate)
 		      pPixmap->drawable.height,
 		      exaPixmapIsDirty(pPixmap) ? 'd' : 'c'));
 
-	pExaPixmap->offscreen = FALSE;
+	pExaPixmap->use_gpu_copy = FALSE;
 
 	pPixmap->devKind = pExaPixmap->sys_pitch;
 	pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
@@ -468,12 +468,12 @@ exaMigrateTowardFb (ExaMigrationPtr migrate)
 	pExaPixmap->score++;
 
     if (pExaPixmap->score >= EXA_PIXMAP_SCORE_MOVE_IN &&
-	!exaPixmapIsOffscreen(pPixmap))
+	!exaPixmapHasGpuCopy(pPixmap))
     {
 	exaDoMoveInPixmap(migrate);
     }
 
-    if (exaPixmapIsOffscreen(pPixmap)) {
+    if (exaPixmapHasGpuCopy(pPixmap)) {
 	exaCopyDirtyToFb (migrate);
 	ExaOffscreenMarkUsed (pPixmap);
     } else
@@ -504,7 +504,7 @@ exaMigrateTowardSys (ExaMigrationPtr migrate)
     if (pExaPixmap->score <= EXA_PIXMAP_SCORE_MOVE_OUT && pExaPixmap->area)
 	exaDoMoveOutPixmap(migrate);
 
-    if (exaPixmapIsOffscreen(pPixmap)) {
+    if (exaPixmapHasGpuCopy(pPixmap)) {
 	exaCopyDirtyToFb (migrate);
 	ExaOffscreenMarkUsed (pPixmap);
     } else
@@ -523,7 +523,7 @@ exaAssertNotDirty (PixmapPtr pPixmap)
     RegionRec ValidReg;
     int dst_pitch, src_pitch, cpp, y, nbox, save_pitch;
     BoxPtr pBox;
-    Bool ret = TRUE, save_offscreen;
+    Bool ret = TRUE, save_use_gpu_copy;
 
     if (exaPixmapIsPinned(pPixmap) || pExaPixmap->area == NULL)
 	return ret;
@@ -542,9 +542,9 @@ exaAssertNotDirty (PixmapPtr pPixmap)
     src_pitch = pExaPixmap->fb_pitch;
     cpp = pPixmap->drawable.bitsPerPixel / 8;
 
-    save_offscreen = pExaPixmap->offscreen;
+    save_use_gpu_copy = pExaPixmap->use_gpu_copy;
     save_pitch = pPixmap->devKind;
-    pExaPixmap->offscreen = TRUE;
+    pExaPixmap->use_gpu_copy = TRUE;
     pPixmap->devKind = pExaPixmap->fb_pitch;
 
     if (!ExaDoPrepareAccess(pPixmap, EXA_PREPARE_SRC))
@@ -579,7 +579,7 @@ exaAssertNotDirty (PixmapPtr pPixmap)
 skip:
     exaFinishAccess(&pPixmap->drawable, EXA_PREPARE_SRC);
 
-    pExaPixmap->offscreen = save_offscreen;
+    pExaPixmap->use_gpu_copy = save_use_gpu_copy;
     pPixmap->devKind = save_pitch;
 
 out:
@@ -618,7 +618,7 @@ exaDoMigration_classic (ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel)
      */
     for (i = 0; i < npixmaps; i++) {
 	if (exaPixmapIsPinned (pixmaps[i].pPix) &&
-	    !exaPixmapIsOffscreen (pixmaps[i].pPix))
+	    !exaPixmapHasGpuCopy (pixmaps[i].pPix))
 	{
 	    EXA_FALLBACK(("Pixmap %p (%dx%d) pinned in sys\n", pixmaps[i].pPix,
 		      pixmaps[i].pPix->drawable.width,
@@ -680,7 +680,7 @@ exaDoMigration_classic (ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel)
 	}
 
 	for (i = 0; i < npixmaps; i++) {
-	    if (exaPixmapIsOffscreen(pixmaps[i].pPix)) {
+	    if (exaPixmapHasGpuCopy(pixmaps[i].pPix)) {
 		/* Found one in FB, so move all to FB. */
 		for (j = 0; j < npixmaps; j++)
 		    exaMigrateTowardFb(pixmaps + i);
@@ -709,12 +709,12 @@ exaDoMigration_classic (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 (!exaPixmapHasGpuCopy(pixmaps[i].pPix)) {
 		return;
 	    }
 	}
 
-	/* Yay, everything's offscreen, mark memory as used */
+	/* Yay, everything has a gpu copy, mark memory as used */
 	for (i = 0; i < npixmaps; i++) {
 	    ExaOffscreenMarkUsed (pixmaps[i].pPix);
 	}
diff --git a/exa/exa_migration_mixed.c b/exa/exa_migration_mixed.c
index ea6f878..a7fdf63 100644
--- a/exa/exa_migration_mixed.c
+++ b/exa/exa_migration_mixed.c
@@ -80,7 +80,7 @@ exaDoMigration_mixed(ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel)
      */
     for (i = 0; i < npixmaps; i++) {
 	if (exaPixmapIsPinned (pixmaps[i].pPix) &&
-	    !exaPixmapIsOffscreen (pixmaps[i].pPix))
+	    !exaPixmapHasGpuCopy (pixmaps[i].pPix))
 	{
 	    can_accel = FALSE;
 	    break;
@@ -98,7 +98,7 @@ exaDoMigration_mixed(ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel)
 	if (!pExaPixmap->driverPriv)
 	    exaCreateDriverPixmap_mixed(pPixmap);
 
-	if (pExaPixmap->pDamage && exaPixmapIsOffscreen(pPixmap)) {
+	if (pExaPixmap->pDamage && exaPixmapHasGpuCopy(pPixmap)) {
 	    ExaScreenPriv(pPixmap->drawable.pScreen);
 
 	    pPixmap->devKind = pExaPixmap->fb_pitch;
@@ -108,7 +108,7 @@ exaDoMigration_mixed(ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel)
 		pExaScr->deferred_mixed_pixmap = NULL;
 	}
 
-	pExaPixmap->offscreen = exaPixmapIsOffscreen(pPixmap);
+	pExaPixmap->use_gpu_copy = exaPixmapHasGpuCopy(pPixmap);
     }
 }
 
@@ -135,7 +135,7 @@ exaPrepareAccessReg_mixed(PixmapPtr pPixmap, int index, RegionPtr pReg)
 {
     if (!ExaDoPrepareAccess(pPixmap, index)) {
 	ExaPixmapPriv(pPixmap);
-	Bool is_offscreen = exaPixmapIsOffscreen(pPixmap);
+	Bool has_gpu_copy = exaPixmapHasGpuCopy(pPixmap);
 	ExaMigrationRec pixmaps[1];
 
 	/* Do we need to allocate our system buffer? */
@@ -157,7 +157,8 @@ exaPrepareAccessReg_mixed(PixmapPtr pPixmap, int index, RegionPtr pReg)
 	pixmaps[0].pPix = pPixmap;
 	pixmaps[0].pReg = pReg;
 
-	if (!pExaPixmap->pDamage && (is_offscreen || !exaPixmapIsPinned(pPixmap))) {
+	if (!pExaPixmap->pDamage &&
+		(has_gpu_copy || !exaPixmapIsPinned(pPixmap))) {
 	    Bool as_dst = pixmaps[0].as_dst;
 
 	    /* Set up damage tracking */
@@ -170,7 +171,7 @@ exaPrepareAccessReg_mixed(PixmapPtr pPixmap, int index, RegionPtr pReg)
 	    /* This is used by exa to optimize migration. */
 	    DamageSetReportAfterOp(pExaPixmap->pDamage, TRUE);
 
-	    if (is_offscreen) {
+	    if (has_gpu_copy) {
 		exaPixmapDirty(pPixmap, 0, 0, pPixmap->drawable.width,
 			       pPixmap->drawable.height);
 
@@ -189,14 +190,14 @@ exaPrepareAccessReg_mixed(PixmapPtr pPixmap, int index, RegionPtr pReg)
 	    if (as_dst)
 		exaPixmapDirty(pPixmap, 0, 0, pPixmap->drawable.width,
 			       pPixmap->drawable.height);
-	} else if (is_offscreen) {
+	} else if (has_gpu_copy) {
 	    pPixmap->devKind = pExaPixmap->fb_pitch;
 	    exaCopyDirtyToSys(pixmaps);
 	}
 
 	pPixmap->devPrivate.ptr = pExaPixmap->sys_ptr;
 	pPixmap->devKind = pExaPixmap->sys_pitch;
-	pExaPixmap->offscreen = FALSE;
+	pExaPixmap->use_gpu_copy = FALSE;
     }
 }
 
@@ -210,8 +211,8 @@ void exaFinishAccess_mixed(PixmapPtr pPixmap, int index)
 {
     ExaPixmapPriv(pPixmap);
 
-    if (pExaPixmap->pDamage && !pExaPixmap->offscreen &&
-	    exaPixmapIsOffscreen(pPixmap)){
+    if (pExaPixmap->pDamage && !pExaPixmap->use_gpu_copy &&
+	    exaPixmapHasGpuCopy(pPixmap)) {
 	DamageRegionProcessPending(&pPixmap->drawable);
 
 	if (index == EXA_PREPARE_DEST || index == EXA_PREPARE_AUX_DEST) {
diff --git a/exa/exa_mixed.c b/exa/exa_mixed.c
index bbbf1af..764c7dd 100644
--- a/exa/exa_mixed.c
+++ b/exa/exa_mixed.c
@@ -93,9 +93,9 @@ exaCreatePixmap_mixed(ScreenPtr pScreen, int w, int h, int depth,
     /* A scratch pixmap will become a driver pixmap right away. */
     if (!w || !h) {
 	exaCreateDriverPixmap_mixed(pPixmap);
-	pExaPixmap->offscreen = exaPixmapIsOffscreen(pPixmap);
+	pExaPixmap->use_gpu_copy = exaPixmapHasGpuCopy(pPixmap);
     } else
-	pExaPixmap->offscreen = FALSE;
+	pExaPixmap->use_gpu_copy = FALSE;
 
     /* During a fallback we must prepare access. */
     if (pExaScr->fallback_counter)
@@ -111,7 +111,7 @@ exaModifyPixmapHeader_mixed(PixmapPtr pPixmap, int width, int height, int depth,
     ScreenPtr pScreen = pPixmap->drawable.pScreen;
     ExaScreenPrivPtr pExaScr;
     ExaPixmapPrivPtr pExaPixmap;
-    Bool ret, is_offscreen;
+    Bool ret, has_gpu_copy;
 
     if (!pPixmap)
         return FALSE;
@@ -131,7 +131,7 @@ exaModifyPixmapHeader_mixed(PixmapPtr pPixmap, int width, int height, int depth,
 	    pExaPixmap->driverPriv = NULL;
 	}
 
-	pExaPixmap->offscreen = FALSE;
+	pExaPixmap->use_gpu_copy = FALSE;
 	pExaPixmap->score = EXA_PIXMAP_SCORE_PINNED;
     }
 
@@ -145,8 +145,8 @@ exaModifyPixmapHeader_mixed(PixmapPtr pPixmap, int width, int height, int depth,
         }
     }
 
-    is_offscreen = exaPixmapIsOffscreen(pPixmap);
-    if (is_offscreen) {
+    has_gpu_copy = exaPixmapHasGpuCopy(pPixmap);
+    if (has_gpu_copy) {
 	pPixmap->devPrivate.ptr = pExaPixmap->fb_ptr;
 	pPixmap->devKind = pExaPixmap->fb_pitch;
     } else {
@@ -168,7 +168,7 @@ exaModifyPixmapHeader_mixed(PixmapPtr pPixmap, int width, int height, int depth,
     swap(pExaScr, pScreen, ModifyPixmapHeader);
 
 out:
-    if (is_offscreen) {
+    if (has_gpu_copy) {
 	pExaPixmap->fb_ptr = pPixmap->devPrivate.ptr;
 	pExaPixmap->fb_pitch = pPixmap->devKind;
     } else {
@@ -219,7 +219,7 @@ exaDestroyPixmap_mixed(PixmapPtr pPixmap)
 }
 
 Bool
-exaPixmapIsOffscreen_mixed(PixmapPtr pPixmap)
+exaPixmapHasGpuCopy_mixed(PixmapPtr pPixmap)
 {
     ScreenPtr pScreen = pPixmap->drawable.pScreen;
     ExaScreenPriv(pScreen);
diff --git a/exa/exa_offscreen.c b/exa/exa_offscreen.c
index eb53b2a..acdf439 100644
--- a/exa/exa_offscreen.c
+++ b/exa/exa_offscreen.c
@@ -522,7 +522,7 @@ ExaOffscreenDefragment (ScreenPtr pScreen)
 	return NULL;
 
     pExaDstPix = ExaGetPixmapPriv (pDstPix);
-    pExaDstPix->offscreen = TRUE;
+    pExaDstPix->use_gpu_copy = TRUE;
 
     for (area = pExaScr->info->offScreenAreas->prev;
 	 area != pExaScr->info->offScreenAreas;
@@ -531,7 +531,7 @@ ExaOffscreenDefragment (ScreenPtr pScreen)
 	ExaOffscreenArea *prev = area->prev;
 	PixmapPtr pSrcPix;
 	ExaPixmapPrivPtr pExaSrcPix;
-	Bool save_offscreen;
+	Bool save_use_gpu_copy;
 	int save_pitch;
 
 	if (area->state != ExaOffscreenAvail ||
@@ -576,10 +576,10 @@ ExaOffscreenDefragment (ScreenPtr pScreen)
 	    continue;
 	}
 
-	save_offscreen = pExaSrcPix->offscreen;
+	save_use_gpu_copy = pExaSrcPix->use_gpu_copy;
 	save_pitch = pSrcPix->devKind;
 
-	pExaSrcPix->offscreen = TRUE;
+	pExaSrcPix->use_gpu_copy = TRUE;
 	pSrcPix->devKind = pExaSrcPix->fb_pitch;
 
 	pDstPix->drawable.width = pSrcPix->drawable.width;
@@ -589,7 +589,7 @@ ExaOffscreenDefragment (ScreenPtr pScreen)
 	pDstPix->drawable.bitsPerPixel = pSrcPix->drawable.bitsPerPixel;
 
 	if (!pExaScr->info->PrepareCopy (pSrcPix, pDstPix, -1, -1, GXcopy, ~0)) {
-	    pExaSrcPix->offscreen = save_offscreen;
+	    pExaSrcPix->use_gpu_copy = save_use_gpu_copy;
 	    pSrcPix->devKind = save_pitch;
 	    area = prev;
 	    continue;
@@ -646,7 +646,7 @@ ExaOffscreenDefragment (ScreenPtr pScreen)
 #endif
 
 	pExaSrcPix->fb_ptr = pExaDstPix->fb_ptr;
-	pExaSrcPix->offscreen = save_offscreen;
+	pExaSrcPix->use_gpu_copy = save_use_gpu_copy;
 	pSrcPix->devKind = save_pitch;
     }
 
diff --git a/exa/exa_priv.h b/exa/exa_priv.h
index 5764bb4..69c0d24 100644
--- a/exa/exa_priv.h
+++ b/exa/exa_priv.h
@@ -173,7 +173,7 @@ typedef struct {
     AddTrapsProcPtr		 SavedAddTraps;
 #endif
     void (*do_migration) (ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel);
-    Bool (*pixmap_is_offscreen) (PixmapPtr pPixmap);
+    Bool (*pixmap_has_gpu_copy) (PixmapPtr pPixmap);
     void (*do_move_in_pixmap) (PixmapPtr pPixmap);
     void (*do_move_out_pixmap) (PixmapPtr pPixmap);
     void (*prepare_access_reg)(PixmapPtr pPixmap, int index, RegionPtr pReg);
@@ -283,7 +283,7 @@ extern DevPrivateKey exaGCPrivateKey;
 typedef struct {
     ExaOffscreenArea *area;
     int		    score;	/**< score for the move-in vs move-out heuristic */
-    Bool	    offscreen;
+    Bool	    use_gpu_copy;
 
     CARD8	    *sys_ptr;	/**< pointer to pixmap data in system memory */
     int		    sys_pitch;	/**< pitch of pixmap in system memory */
@@ -539,7 +539,7 @@ exaGetDrawableDeltas (DrawablePtr pDrawable, PixmapPtr pPixmap,
 		      int *xp, int *yp);
 
 Bool
-exaPixmapIsOffscreen(PixmapPtr p);
+exaPixmapHasGpuCopy(PixmapPtr p);
 
 PixmapPtr
 exaGetOffscreenPixmap (DrawablePtr pDrawable, int *xp, int *yp);
@@ -576,7 +576,7 @@ Bool
 exaDestroyPixmap_classic (PixmapPtr pPixmap);
 
 Bool
-exaPixmapIsOffscreen_classic(PixmapPtr pPixmap);
+exaPixmapHasGpuCopy_classic(PixmapPtr pPixmap);
 
 /* exa_driver.c */
 PixmapPtr
@@ -591,7 +591,7 @@ Bool
 exaDestroyPixmap_driver (PixmapPtr pPixmap);
 
 Bool
-exaPixmapIsOffscreen_driver(PixmapPtr pPixmap);
+exaPixmapHasGpuCopy_driver(PixmapPtr pPixmap);
 
 /* exa_mixed.c */
 PixmapPtr
@@ -606,7 +606,7 @@ Bool
 exaDestroyPixmap_mixed(PixmapPtr pPixmap);
 
 Bool
-exaPixmapIsOffscreen_mixed(PixmapPtr pPixmap);
+exaPixmapHasGpuCopy_mixed(PixmapPtr pPixmap);
 
 /* exa_migration_mixed.c */
 void
diff --git a/exa/exa_render.c b/exa/exa_render.c
index db355d6..1b68e1c 100644
--- a/exa/exa_render.c
+++ b/exa/exa_render.c
@@ -320,7 +320,7 @@ exaTryDriverSolidFill(PicturePtr	pSrc,
 	exaDoMigration(pixmaps, 1, TRUE);
     }
 
-    if (!exaPixmapIsOffscreen(pDstPix)) {
+    if (!exaPixmapHasGpuCopy(pDstPix)) {
 	REGION_UNINIT(pDst->pDrawable->pScreen, &region);
 	return 0;
     }
@@ -540,7 +540,7 @@ exaCompositeRects(CARD8	              op,
 	/* We have to manage the damage ourselves, since CompositeRects isn't
 	 * something in the screen that can be managed by the damage extension,
 	 * and EXA depends on damage to track what needs to be migrated between
-	 * offscreen and onscreen.
+	 * the gpu and the cpu.
 	 */
 
 	/* Compute the overall extents of the composited region - we're making
@@ -752,7 +752,7 @@ exaTryDriverComposite(CARD8		op,
 	}
     }
 
-    if (!exaPixmapIsOffscreen(pDstPix)) {
+    if (!exaPixmapHasGpuCopy(pDstPix)) {
 	REGION_UNINIT(pDst->pDrawable->pScreen, &region);
 	return 0;
     }
commit 342f3689d17256c92cbfee079d24501d27aa1153
Author: Maarten Maathuis <madman2003 at gmail.com>
Date:   Sat Nov 28 10:34:43 2009 +0100

    exa: handle pixmap create/destroy in lower layers
    
    - Pixmaps that are created during a fallback are automatically prepared access.
    - During the fallback accelerated ops are blocked to prevent new/scratch gc's
      from triggering accelerated ops on mapped pixmaps.
    - A few cases of incorrect wrapping (on the top level pointer instead of
      between damage and (w)fb) have been removed.
    
    Signed-off-by: Maarten Maathuis <madman2003 at gmail.com>
    Acked-by: Michel Dänzer <michel at daenzer.net>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/exa/exa.c b/exa/exa.c
index 46e9182..ed28431 100644
--- a/exa/exa.c
+++ b/exa/exa.c
@@ -480,57 +480,6 @@ const GCFuncs exaGCFuncs = {
     exaCopyClip
 };
 
-/*
- * This wrapper exists to allow fbValidateGC to work.
- * Note that we no longer assume newly created pixmaps to be in normal ram.
- * This assumption is certainly not garuanteed with driver allocated pixmaps.
- */
-static PixmapPtr
-exaCreatePixmapWithPrepare(ScreenPtr pScreen, int w, int h, int depth,
-		unsigned usage_hint)
-{
-    PixmapPtr pPixmap;
-    ExaScreenPriv(pScreen);
-
-    /* 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.
-     */
-    swap(pExaScr, pScreen, CreatePixmap);
-    pPixmap = pScreen->CreatePixmap(pScreen, w, h, depth, usage_hint);
-    swap(pExaScr, pScreen, CreatePixmap);
-
-    if (!pPixmap)
-	return NULL;
-
-    /* Note the usage of ExaDoPrepareAccess, this allowed because:
-     * The pixmap is new, so not offscreen in the classic exa case.
-     * For EXA_HANDLES_PIXMAPS the driver will handle whatever is needed.
-     * We want to signal that the pixmaps will be used as destination.
-     */
-    ExaDoPrepareAccess(pPixmap, EXA_PREPARE_AUX_DEST);
-
-    return pPixmap;
-}
-
-static Bool
-exaDestroyPixmapWithFinish(PixmapPtr pPixmap)
-{
-    ScreenPtr pScreen = pPixmap->drawable.pScreen;
-    ExaScreenPriv(pScreen);
-    Bool ret;
-
-    exaFinishAccess(&pPixmap->drawable, EXA_PREPARE_AUX_DEST);
-
-    /* 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.
-     */
-    swap(pExaScr, pScreen, DestroyPixmap);
-    ret = pScreen->DestroyPixmap(pPixmap);
-    swap(pExaScr, pScreen, DestroyPixmap);
-
-    return ret;
-}
-
 static void
 exaValidateGC(GCPtr pGC,
 		unsigned long changes,
@@ -542,20 +491,9 @@ exaValidateGC(GCPtr pGC,
 
     ScreenPtr pScreen = pDrawable->pScreen;
     ExaScreenPriv(pScreen);
-    CreatePixmapProcPtr old_ptr = NULL;
-    DestroyPixmapProcPtr old_ptr2 = NULL;
+    ExaGCPriv(pGC);
     PixmapPtr pTile = NULL;
-    EXA_GC_PROLOGUE(pGC);
-
-    /* save the "fb" pointer. */
-    old_ptr = pExaScr->SavedCreatePixmap;
-    /* create a new upper layer pointer. */
-    wrap(pExaScr, pScreen, CreatePixmap, exaCreatePixmapWithPrepare);
-
-    /* save the "fb" pointer. */
-    old_ptr2 = pExaScr->SavedDestroyPixmap;
-    /* create a new upper layer pointer. */
-    wrap(pExaScr, pScreen, DestroyPixmap, exaDestroyPixmapWithFinish);
+    Bool finish_current_tile = FALSE;
 
     /* Either of these conditions is enough to trigger access to a tile pixmap. */
     /* With pGC->tileIsPixel == 1, you run the risk of dereferencing an invalid tile pixmap pointer. */
@@ -569,8 +507,10 @@ exaValidateGC(GCPtr pGC,
 	 */
 	if (pTile && pTile->drawable.depth != pDrawable->depth && !(changes & GCTile)) {
 	    PixmapPtr pRotatedTile = fbGetRotatedPixmap(pGC);
-	    if (pRotatedTile->drawable.depth == pDrawable->depth)
+	    if (pRotatedTile && pRotatedTile->drawable.depth == pDrawable->depth)
 		pTile = pRotatedTile;
+	    else
+		finish_current_tile = TRUE; /* CreatePixmap will be called. */
 	}
     }
 
@@ -579,42 +519,39 @@ exaValidateGC(GCPtr pGC,
     if (pTile)
 	exaPrepareAccess(&pTile->drawable, EXA_PREPARE_SRC);
 
+    /* Calls to Create/DestroyPixmap have to be identified as special. */
+    pExaScr->fallback_counter++;
+    swap(pExaGC, pGC, funcs);
     (*pGC->funcs->ValidateGC)(pGC, changes, pDrawable);
+    swap(pExaGC, pGC, funcs);
+    pExaScr->fallback_counter--;
 
     if (pTile)
 	exaFinishAccess(&pTile->drawable, EXA_PREPARE_SRC);
+    if (finish_current_tile && pGC->tile.pixmap)
+	exaFinishAccess(&pGC->tile.pixmap->drawable, EXA_PREPARE_AUX_DEST);
     if (pGC->stipple)
-        exaFinishAccess(&pGC->stipple->drawable, EXA_PREPARE_MASK);
-
-    /* switch back to the normal upper layer. */
-    unwrap(pExaScr, pScreen, CreatePixmap);
-    /* restore copy of fb layer pointer. */
-    pExaScr->SavedCreatePixmap = old_ptr;
-
-    /* switch back to the normal upper layer. */
-    unwrap(pExaScr, pScreen, DestroyPixmap);
-    /* restore copy of fb layer pointer. */
-    pExaScr->SavedDestroyPixmap = old_ptr2;
-
-    EXA_GC_EPILOGUE(pGC);
+	exaFinishAccess(&pGC->stipple->drawable, EXA_PREPARE_MASK);
 }
 
 /* Is exaPrepareAccessGC() needed? */
 static void
 exaDestroyGC(GCPtr pGC)
 {
-    EXA_GC_PROLOGUE (pGC);
+    ExaGCPriv(pGC);
+    swap(pExaGC, pGC, funcs);
     (*pGC->funcs->DestroyGC)(pGC);
-    EXA_GC_EPILOGUE (pGC);
+    swap(pExaGC, pGC, funcs);
 }
 
 static void
 exaChangeGC (GCPtr pGC,
 		unsigned long mask)
 {
-    EXA_GC_PROLOGUE (pGC);
+    ExaGCPriv(pGC);
+    swap(pExaGC, pGC, funcs);
     (*pGC->funcs->ChangeGC) (pGC, mask);
-    EXA_GC_EPILOGUE (pGC);
+    swap(pExaGC, pGC, funcs);
 }
 
 static void
@@ -622,9 +559,10 @@ exaCopyGC (GCPtr pGCSrc,
 	      unsigned long mask,
 	      GCPtr	 pGCDst)
 {
-    EXA_GC_PROLOGUE (pGCDst);
+    ExaGCPriv(pGCDst);
+    swap(pExaGC, pGCDst, funcs);
     (*pGCDst->funcs->CopyGC) (pGCSrc, mask, pGCDst);
-    EXA_GC_EPILOGUE (pGCDst);
+    swap(pExaGC, pGCDst, funcs);
 }
 
 static void
@@ -633,25 +571,28 @@ exaChangeClip (GCPtr pGC,
 		pointer pvalue,
 		int nrects)
 {
-    EXA_GC_PROLOGUE (pGC);
+    ExaGCPriv(pGC);
+    swap(pExaGC, pGC, funcs);
     (*pGC->funcs->ChangeClip) (pGC, type, pvalue, nrects);
-    EXA_GC_EPILOGUE (pGC);
+    swap(pExaGC, pGC, funcs);
 }
 
 static void
 exaCopyClip(GCPtr pGCDst, GCPtr pGCSrc)
 {
-    EXA_GC_PROLOGUE (pGCDst);
+    ExaGCPriv(pGCDst);
+    swap(pExaGC, pGCDst, funcs);
     (*pGCDst->funcs->CopyClip)(pGCDst, pGCSrc);
-    EXA_GC_EPILOGUE (pGCDst);
+    swap(pExaGC, pGCDst, funcs);
 }
 
 static void
 exaDestroyClip(GCPtr pGC)
 {
-    EXA_GC_PROLOGUE (pGC);
+    ExaGCPriv(pGC);
+    swap(pExaGC, pGC, funcs);
     (*pGC->funcs->DestroyClip)(pGC);
-    EXA_GC_EPILOGUE (pGC);
+    swap(pExaGC, pGC, funcs);
 }
 
 /**
@@ -682,18 +623,6 @@ exaChangeWindowAttributes(WindowPtr pWin, unsigned long mask)
     Bool ret;
     ScreenPtr pScreen = pWin->drawable.pScreen;
     ExaScreenPriv(pScreen);
-    CreatePixmapProcPtr old_ptr = NULL;
-    DestroyPixmapProcPtr old_ptr2 = NULL;
-
-    /* save the "fb" pointer. */
-    old_ptr = pExaScr->SavedCreatePixmap;
-    /* create a new upper layer pointer. */
-    wrap(pExaScr, pScreen, CreatePixmap, exaCreatePixmapWithPrepare);
-
-    /* save the "fb" pointer. */
-    old_ptr2 = pExaScr->SavedDestroyPixmap;
-    /* create a new upper layer pointer. */
-    wrap(pExaScr, pScreen, DestroyPixmap, exaDestroyPixmapWithFinish);
 
     if ((mask & CWBackPixmap) && pWin->backgroundState == BackgroundPixmap) 
 	exaPrepareAccess(&pWin->background.pixmap->drawable, EXA_PREPARE_SRC);
@@ -701,25 +630,17 @@ exaChangeWindowAttributes(WindowPtr pWin, unsigned long mask)
     if ((mask & CWBorderPixmap) && pWin->borderIsPixel == FALSE)
 	exaPrepareAccess(&pWin->border.pixmap->drawable, EXA_PREPARE_MASK);
 
+    pExaScr->fallback_counter++;
     swap(pExaScr, pScreen, ChangeWindowAttributes);
     ret = pScreen->ChangeWindowAttributes(pWin, mask);
     swap(pExaScr, pScreen, ChangeWindowAttributes);
+    pExaScr->fallback_counter--;
 
     if ((mask & CWBackPixmap) && pWin->backgroundState == BackgroundPixmap) 
 	exaFinishAccess(&pWin->background.pixmap->drawable, EXA_PREPARE_SRC);
     if ((mask & CWBorderPixmap) && pWin->borderIsPixel == FALSE)
 	exaFinishAccess(&pWin->border.pixmap->drawable, EXA_PREPARE_MASK);
 
-    /* switch back to the normal upper layer. */
-    unwrap(pExaScr, pScreen, CreatePixmap);
-    /* restore copy of fb layer pointer. */
-    pExaScr->SavedCreatePixmap = old_ptr;
-
-    /* switch back to the normal upper layer. */
-    unwrap(pExaScr, pScreen, DestroyPixmap);
-    /* restore copy of fb layer pointer. */
-    pExaScr->SavedDestroyPixmap = old_ptr2;
-
     return ret;
 }
 
diff --git a/exa/exa_accel.c b/exa/exa_accel.c
index cbff7f3..3de7307 100644
--- a/exa/exa_accel.c
+++ b/exa/exa_accel.c
@@ -51,7 +51,8 @@ exaFillSpans(DrawablePtr pDrawable, GCPtr pGC, int n,
     int		    partX1, partX2;
     int		    off_x, off_y;
 
-    if (pExaScr->swappedOut ||
+    if (pExaScr->fallback_counter ||
+	pExaScr->swappedOut ||
 	pGC->fillStyle != FillSolid ||
 	pExaPixmap->accel_blocked)
     {
@@ -153,7 +154,7 @@ exaDoPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y,
     int bpp = pDrawable->bitsPerPixel;
     Bool ret = TRUE;
 
-    if (pExaPixmap->accel_blocked || !pExaScr->info->UploadToScreen)
+    if (pExaScr->fallback_counter || pExaPixmap->accel_blocked || !pExaScr->info->UploadToScreen)
 	return FALSE;
 
     /* Don't bother with under 8bpp, XYPixmaps. */
@@ -574,7 +575,8 @@ exaCopyNtoN (DrawablePtr    pSrcDrawable,
 {
     ExaScreenPriv(pDstDrawable->pScreen);
 
-    if (pExaScr->fallback_flags & EXA_FALLBACK_COPYWINDOW)
+    if (pExaScr->fallback_counter ||
+	    (pExaScr->fallback_flags & EXA_FALLBACK_COPYWINDOW))
 	return;
 
     if (exaHWCopyNtoN(pSrcDrawable, pDstDrawable, pGC, pbox, nbox, dx, dy, reverse, upsidedown))
@@ -596,7 +598,7 @@ exaCopyArea(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC,
 {
     ExaScreenPriv (pDstDrawable->pScreen);
 
-    if (pExaScr->swappedOut) {
+    if (pExaScr->fallback_counter || pExaScr->swappedOut) {
         return  ExaCheckCopyArea(pSrcDrawable, pDstDrawable, pGC,
                                  srcx, srcy, width, height, dstx, dsty);
     }
@@ -610,13 +612,14 @@ static void
 exaPolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
 	     DDXPointPtr ppt)
 {
+    ExaScreenPriv (pDrawable->pScreen);
     int i;
     xRectangle *prect;
 
     /* If we can't reuse the current GC as is, don't bother accelerating the
      * points.
      */
-    if (pGC->fillStyle != FillSolid) {
+    if (pExaScr->fallback_counter || pGC->fillStyle != FillSolid) {
 	ExaCheckPolyPoint(pDrawable, pGC, mode, npt, ppt);
 	return;
     }
@@ -645,10 +648,16 @@ static void
 exaPolylines(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
 	     DDXPointPtr ppt)
 {
+    ExaScreenPriv (pDrawable->pScreen);
     xRectangle *prect;
     int x1, x2, y1, y2;
     int i;
 
+    if (pExaScr->fallback_counter) {
+	ExaCheckPolylines(pDrawable, pGC, mode, npt, ppt);
+	return;
+    }
+
     /* Don't try to do wide lines or non-solid fill style. */
     if (pGC->lineWidth != 0 || pGC->lineStyle != LineSolid ||
 	pGC->fillStyle != FillSolid) {
@@ -706,12 +715,13 @@ static void
 exaPolySegment (DrawablePtr pDrawable, GCPtr pGC, int nseg,
 		xSegment *pSeg)
 {
+    ExaScreenPriv (pDrawable->pScreen);
     xRectangle *prect;
     int i;
 
     /* Don't try to do wide lines or non-solid fill style. */
-    if (pGC->lineWidth != 0 || pGC->lineStyle != LineSolid ||
-	pGC->fillStyle != FillSolid)
+    if (pExaScr->fallback_counter || pGC->lineWidth != 0 ||
+	pGC->lineStyle != LineSolid || pGC->fillStyle != FillSolid)
     {
 	ExaCheckPolySegment(pDrawable, pGC, nseg, pSeg);
 	return;
@@ -788,7 +798,8 @@ exaPolyFillRect(DrawablePtr pDrawable,
 
     exaGetDrawableDeltas(pDrawable, pPixmap, &xoff, &yoff);
 
-    if (pExaScr->swappedOut || pExaPixmap->accel_blocked)
+    if (pExaScr->fallback_counter || pExaScr->swappedOut ||
+	    pExaPixmap->accel_blocked)
     {
 	goto fallback;
     }
@@ -962,12 +973,18 @@ exaCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
 			  -pPixmap->screen_x, -pPixmap->screen_y);
 #endif
 
+    if (pExaScr->fallback_counter) {
+	pExaScr->fallback_flags |= EXA_FALLBACK_COPYWINDOW;
+	goto fallback;
+    }
+
     pExaScr->fallback_flags |= EXA_ACCEL_COPYWINDOW;
     miCopyRegion (&pPixmap->drawable, &pPixmap->drawable,
 		  NULL,
 		  &rgnDst, dx, dy, exaCopyNtoN, 0, NULL);
     pExaScr->fallback_flags &= ~EXA_ACCEL_COPYWINDOW;
 
+fallback:
     REGION_UNINIT(pWin->drawable.pScreen, &rgnDst);
 
     if (pExaScr->fallback_flags & EXA_FALLBACK_COPYWINDOW) {
@@ -990,7 +1007,7 @@ exaFillRegionSolid (DrawablePtr	pDrawable, RegionPtr pRegion, Pixel pixel,
     exaGetDrawableDeltas(pDrawable, pPixmap, &xoff, &yoff);
     REGION_TRANSLATE(pScreen, pRegion, xoff, yoff);
 
-    if (pExaPixmap->accel_blocked)
+    if (pExaScr->fallback_counter || pExaPixmap->accel_blocked)
 	goto out;
 
     if (pExaScr->do_migration) {
@@ -1086,7 +1103,8 @@ exaFillRegionTiled (DrawablePtr pDrawable, RegionPtr pRegion, PixmapPtr pTile,
     pPixmap = exaGetDrawablePixmap (pDrawable);
     pExaPixmap = ExaGetPixmapPriv (pPixmap);
 
-    if (pExaPixmap->accel_blocked || pTileExaPixmap->accel_blocked)
+    if (pExaScr->fallback_counter || pExaPixmap->accel_blocked ||
+	    pTileExaPixmap->accel_blocked)
 	return FALSE;
 
     if (pExaScr->do_migration) {
@@ -1244,7 +1262,7 @@ exaGetImage (DrawablePtr pDrawable, int x, int y, int w, int h,
     int xoff, yoff;
     Bool ok;
 
-    if (pExaScr->swappedOut)
+    if (pExaScr->fallback_counter || pExaScr->swappedOut)
 	goto fallback;
 
     exaGetDrawableDeltas (pDrawable, pPix, &xoff, &yoff);
diff --git a/exa/exa_classic.c b/exa/exa_classic.c
index 1eff570..12f3987 100644
--- a/exa/exa_classic.c
+++ b/exa/exa_classic.c
@@ -137,6 +137,10 @@ exaCreatePixmap_classic(ScreenPtr pScreen, int w, int h, int depth,
     exaSetAccelBlock(pExaScr, pExaPixmap,
                      w, h, bpp);
 
+    /* During a fallback we must prepare access. */
+    if (pExaScr->fallback_counter)
+	exaPrepareAccess(&pPixmap->drawable, EXA_PREPARE_AUX_DEST);
+
     return pPixmap;
 }
 
@@ -216,6 +220,10 @@ exaDestroyPixmap_classic (PixmapPtr pPixmap)
     {
 	ExaPixmapPriv (pPixmap);
 
+	/* During a fallback we must finish access, but we don't know the index. */
+	if (pExaScr->fallback_counter)
+	    exaFinishAccess(&pPixmap->drawable, -1);
+
 	if (pExaPixmap->area)
 	{
 	    DBG_PIXMAP(("-- 0x%p (0x%x) (%dx%d)\n",
diff --git a/exa/exa_driver.c b/exa/exa_driver.c
index a9165a1..f55c300 100644
--- a/exa/exa_driver.c
+++ b/exa/exa_driver.c
@@ -115,6 +115,10 @@ exaCreatePixmap_driver(ScreenPtr pScreen, int w, int h, int depth,
     exaSetAccelBlock(pExaScr, pExaPixmap,
                      w, h, bpp);
 
+    /* During a fallback we must prepare access. */
+    if (pExaScr->fallback_counter)
+	exaPrepareAccess(&pPixmap->drawable, EXA_PREPARE_AUX_DEST);
+
     return pPixmap;
 }
 
@@ -187,6 +191,10 @@ exaDestroyPixmap_driver (PixmapPtr pPixmap)
     {
 	ExaPixmapPriv (pPixmap);
 
+	/* During a fallback we must finish access, but we don't know the index. */
+	if (pExaScr->fallback_counter)
+	    exaFinishAccess(&pPixmap->drawable, -1);
+
 	if (pExaPixmap->driverPriv)
 	    pExaScr->info->DestroyPixmap(pScreen, pExaPixmap->driverPriv);
 	pExaPixmap->driverPriv = NULL;
diff --git a/exa/exa_mixed.c b/exa/exa_mixed.c
index b29ee35..bbbf1af 100644
--- a/exa/exa_mixed.c
+++ b/exa/exa_mixed.c
@@ -97,6 +97,10 @@ exaCreatePixmap_mixed(ScreenPtr pScreen, int w, int h, int depth,
     } else
 	pExaPixmap->offscreen = FALSE;
 
+    /* During a fallback we must prepare access. */
+    if (pExaScr->fallback_counter)
+	exaPrepareAccess(&pPixmap->drawable, EXA_PREPARE_AUX_DEST);
+
     return pPixmap;
 }
 
@@ -188,6 +192,10 @@ exaDestroyPixmap_mixed(PixmapPtr pPixmap)
     {
 	ExaPixmapPriv (pPixmap);
 
+	/* During a fallback we must finish access, but we don't know the index. */
+	if (pExaScr->fallback_counter)
+	    exaFinishAccess(&pPixmap->drawable, -1);
+
 	if (pExaScr->deferred_mixed_pixmap == pPixmap)
 	    pExaScr->deferred_mixed_pixmap = NULL;
 
diff --git a/exa/exa_priv.h b/exa/exa_priv.h
index 5b056da..5764bb4 100644
--- a/exa/exa_priv.h
+++ b/exa/exa_priv.h
@@ -198,6 +198,7 @@ typedef struct {
 
     /* Holds information on fallbacks that cannot be relayed otherwise. */
     unsigned int fallback_flags;
+    unsigned int fallback_counter;
 
     ExaGlyphCacheRec             glyphCaches[EXA_NUM_GLYPH_CACHES];
 } ExaScreenPrivRec, *ExaScreenPrivPtr;
@@ -241,13 +242,21 @@ extern DevPrivateKey exaGCPrivateKey;
     real->mem = tmp; \
 }
 
-#define EXA_GC_PROLOGUE(_gc_) \
+#define EXA_PRE_FALLBACK(_screen_) \
+    ExaScreenPriv(_screen_); \
+    pExaScr->fallback_counter++;
+
+#define EXA_POST_FALLBACK(_screen_) \
+    pExaScr->fallback_counter--;
+
+#define EXA_PRE_FALLBACK_GC(_gc_) \
+    ExaScreenPriv(_gc_->pScreen); \
     ExaGCPriv(_gc_); \
-    swap(pExaGC, _gc_, funcs); \
+    pExaScr->fallback_counter++; \
     swap(pExaGC, _gc_, ops);
 
-#define EXA_GC_EPILOGUE(_gc_) \
-    swap(pExaGC, _gc_, funcs); \
+#define EXA_POST_FALLBACK_GC(_gc_) \
+    pExaScr->fallback_counter--; \
     swap(pExaGC, _gc_, ops);
 
 /** Align an offset to an arbitrary alignment */
diff --git a/exa/exa_unaccel.c b/exa/exa_unaccel.c
index c8f0172..9bc765a 100644
--- a/exa/exa_unaccel.c
+++ b/exa/exa_unaccel.c
@@ -74,26 +74,26 @@ void
 ExaCheckFillSpans (DrawablePtr pDrawable, GCPtr pGC, int nspans,
 		   DDXPointPtr ppt, int *pwidth, int fSorted)
 {
-    EXA_GC_PROLOGUE(pGC);
+    EXA_PRE_FALLBACK_GC(pGC);
     EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
     exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
     exaPrepareAccessGC (pGC);
     pGC->ops->FillSpans (pDrawable, pGC, nspans, ppt, pwidth, fSorted);
     exaFinishAccessGC (pGC);
     exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
-    EXA_GC_EPILOGUE(pGC);
+    EXA_POST_FALLBACK_GC(pGC);
 }
 
 void
 ExaCheckSetSpans (DrawablePtr pDrawable, GCPtr pGC, char *psrc,
 		 DDXPointPtr ppt, int *pwidth, int nspans, int fSorted)
 {
-    EXA_GC_PROLOGUE(pGC);
+    EXA_PRE_FALLBACK_GC(pGC);
     EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
     exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
     pGC->ops->SetSpans (pDrawable, pGC, psrc, ppt, pwidth, nspans, fSorted);
     exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
-    EXA_GC_EPILOGUE(pGC);
+    EXA_POST_FALLBACK_GC(pGC);
 }
 
 void
@@ -103,9 +103,8 @@ ExaCheckPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth,
 {
     PixmapPtr pPixmap = exaGetDrawablePixmap(pDrawable);
     ExaPixmapPriv(pPixmap);
-    ExaScreenPriv(pDrawable->pScreen);
 
-    EXA_GC_PROLOGUE(pGC);
+    EXA_PRE_FALLBACK_GC(pGC);
     EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
     if (!pExaScr->prepare_access_reg || !pExaPixmap->pDamage ||
 	exaGCReadsDestination(pDrawable, pGC->planemask, pGC->fillStyle,
@@ -116,7 +115,7 @@ ExaCheckPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth,
 				    DamagePendingRegion(pExaPixmap->pDamage));
     pGC->ops->PutImage (pDrawable, pGC, depth, x, y, w, h, leftPad, format, bits);
     exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
-    EXA_GC_EPILOGUE(pGC);
+    EXA_POST_FALLBACK_GC(pGC);
 }
 
 void
@@ -124,7 +123,7 @@ ExaCheckCopyNtoN (DrawablePtr pSrc, DrawablePtr pDst,  GCPtr pGC,
 	     BoxPtr	pbox, int nbox, int dx, int dy, Bool	reverse, 
 	     Bool upsidedown, Pixel bitplane, void *closure)
 {
-    EXA_GC_PROLOGUE(pGC);
+    EXA_PRE_FALLBACK_GC(pGC);
     EXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrc, pDst,
 		  exaDrawableLocation(pSrc), exaDrawableLocation(pDst)));
     exaPrepareAccess (pDst, EXA_PREPARE_DEST);
@@ -137,7 +136,7 @@ ExaCheckCopyNtoN (DrawablePtr pSrc, DrawablePtr pDst,  GCPtr pGC,
     }
     exaFinishAccess (pSrc, EXA_PREPARE_SRC);
     exaFinishAccess (pDst, EXA_PREPARE_DEST);
-    EXA_GC_EPILOGUE(pGC);
+    EXA_POST_FALLBACK_GC(pGC);
 }
 
 RegionPtr
@@ -146,7 +145,7 @@ ExaCheckCopyArea (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
 {
     RegionPtr ret;
 
-    EXA_GC_PROLOGUE(pGC);
+    EXA_PRE_FALLBACK_GC(pGC);
     EXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrc, pDst,
 		  exaDrawableLocation(pSrc), exaDrawableLocation(pDst)));
     exaPrepareAccess (pDst, EXA_PREPARE_DEST);
@@ -154,7 +153,7 @@ ExaCheckCopyArea (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
     ret = pGC->ops->CopyArea (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty);
     exaFinishAccess (pSrc, EXA_PREPARE_SRC);
     exaFinishAccess (pDst, EXA_PREPARE_DEST);
-    EXA_GC_EPILOGUE(pGC);
+    EXA_POST_FALLBACK_GC(pGC);
 
     return ret;
 }
@@ -166,7 +165,7 @@ ExaCheckCopyPlane (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
 {
     RegionPtr ret;
 
-    EXA_GC_PROLOGUE(pGC);
+    EXA_PRE_FALLBACK_GC(pGC);
     EXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrc, pDst,
 		  exaDrawableLocation(pSrc), exaDrawableLocation(pDst)));
     exaPrepareAccess (pDst, EXA_PREPARE_DEST);
@@ -175,7 +174,7 @@ ExaCheckCopyPlane (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
 		       bitPlane);
     exaFinishAccess (pSrc, EXA_PREPARE_SRC);
     exaFinishAccess (pDst, EXA_PREPARE_DEST);
-    EXA_GC_EPILOGUE(pGC);
+    EXA_POST_FALLBACK_GC(pGC);
 
     return ret;
 }
@@ -184,19 +183,19 @@ void
 ExaCheckPolyPoint (DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
 		  DDXPointPtr pptInit)
 {
-    EXA_GC_PROLOGUE(pGC);
+    EXA_PRE_FALLBACK_GC(pGC);
     EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
     exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
     pGC->ops->PolyPoint (pDrawable, pGC, mode, npt, pptInit);
     exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
-    EXA_GC_EPILOGUE(pGC);
+    EXA_POST_FALLBACK_GC(pGC);
 }
 
 void
 ExaCheckPolylines (DrawablePtr pDrawable, GCPtr pGC,
 		  int mode, int npt, DDXPointPtr ppt)
 {
-    EXA_GC_PROLOGUE(pGC);
+    EXA_PRE_FALLBACK_GC(pGC);
     EXA_FALLBACK(("to %p (%c), width %d, mode %d, count %d\n",
 		  pDrawable, exaDrawableLocation(pDrawable),
 		  pGC->lineWidth, mode, npt));
@@ -206,14 +205,14 @@ ExaCheckPolylines (DrawablePtr pDrawable, GCPtr pGC,
     pGC->ops->Polylines (pDrawable, pGC, mode, npt, ppt);
     exaFinishAccessGC (pGC);
     exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
-    EXA_GC_EPILOGUE(pGC);
+    EXA_POST_FALLBACK_GC(pGC);
 }
 
 void
 ExaCheckPolySegment (DrawablePtr pDrawable, GCPtr pGC,
 		    int nsegInit, xSegment *pSegInit)
 {
-    EXA_GC_PROLOGUE(pGC);
+    EXA_PRE_FALLBACK_GC(pGC);
     EXA_FALLBACK(("to %p (%c) width %d, count %d\n", pDrawable,
 		  exaDrawableLocation(pDrawable), pGC->lineWidth, nsegInit));
 
@@ -222,14 +221,14 @@ ExaCheckPolySegment (DrawablePtr pDrawable, GCPtr pGC,
     pGC->ops->PolySegment (pDrawable, pGC, nsegInit, pSegInit);
     exaFinishAccessGC (pGC);
     exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
-    EXA_GC_EPILOGUE(pGC);
+    EXA_POST_FALLBACK_GC(pGC);
 }
 
 void
 ExaCheckPolyArc (DrawablePtr pDrawable, GCPtr pGC,
 		int narcs, xArc *pArcs)
 {
-    EXA_GC_PROLOGUE(pGC);
+    EXA_PRE_FALLBACK_GC(pGC);
     EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
 
     exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
@@ -237,14 +236,14 @@ ExaCheckPolyArc (DrawablePtr pDrawable, GCPtr pGC,
     pGC->ops->PolyArc (pDrawable, pGC, narcs, pArcs);
     exaFinishAccessGC (pGC);
     exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
-    EXA_GC_EPILOGUE(pGC);
+    EXA_POST_FALLBACK_GC(pGC);
 }
 
 void
 ExaCheckPolyFillRect (DrawablePtr pDrawable, GCPtr pGC,
 		     int nrect, xRectangle *prect)
 {
-    EXA_GC_PROLOGUE(pGC);
+    EXA_PRE_FALLBACK_GC(pGC);
     EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
 
     exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
@@ -252,7 +251,7 @@ ExaCheckPolyFillRect (DrawablePtr pDrawable, GCPtr pGC,
     pGC->ops->PolyFillRect (pDrawable, pGC, nrect, prect);
     exaFinishAccessGC (pGC);
     exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
-    EXA_GC_EPILOGUE(pGC);
+    EXA_POST_FALLBACK_GC(pGC);
 }
 
 void
@@ -260,7 +259,7 @@ ExaCheckImageGlyphBlt (DrawablePtr pDrawable, GCPtr pGC,
 		      int x, int y, unsigned int nglyph,
 		      CharInfoPtr *ppci, pointer pglyphBase)
 {
-    EXA_GC_PROLOGUE(pGC);
+    EXA_PRE_FALLBACK_GC(pGC);
     EXA_FALLBACK(("to %p (%c)\n", pDrawable,
 		  exaDrawableLocation(pDrawable)));
     exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
@@ -268,7 +267,7 @@ ExaCheckImageGlyphBlt (DrawablePtr pDrawable, GCPtr pGC,
     pGC->ops->ImageGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
     exaFinishAccessGC (pGC);
     exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
-    EXA_GC_EPILOGUE(pGC);
+    EXA_POST_FALLBACK_GC(pGC);
 }
 
 void
@@ -276,7 +275,7 @@ ExaCheckPolyGlyphBlt (DrawablePtr pDrawable, GCPtr pGC,
 		     int x, int y, unsigned int nglyph,
 		     CharInfoPtr *ppci, pointer pglyphBase)
 {
-    EXA_GC_PROLOGUE(pGC);
+    EXA_PRE_FALLBACK_GC(pGC);
     EXA_FALLBACK(("to %p (%c), style %d alu %d\n", pDrawable,
 		  exaDrawableLocation(pDrawable), pGC->fillStyle, pGC->alu));
     exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
@@ -284,7 +283,7 @@ ExaCheckPolyGlyphBlt (DrawablePtr pDrawable, GCPtr pGC,
     pGC->ops->PolyGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
     exaFinishAccessGC (pGC);
     exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
-    EXA_GC_EPILOGUE(pGC);
+    EXA_POST_FALLBACK_GC(pGC);
 }
 
 void
@@ -292,7 +291,7 @@ ExaCheckPushPixels (GCPtr pGC, PixmapPtr pBitmap,
 		   DrawablePtr pDrawable,
 		   int w, int h, int x, int y)
 {
-    EXA_GC_PROLOGUE(pGC);
+    EXA_PRE_FALLBACK_GC(pGC);
     EXA_FALLBACK(("from %p to %p (%c,%c)\n", pBitmap, pDrawable,
 		  exaDrawableLocation(&pBitmap->drawable),
 		  exaDrawableLocation(pDrawable)));
@@ -303,7 +302,7 @@ ExaCheckPushPixels (GCPtr pGC, PixmapPtr pBitmap,
     exaFinishAccessGC (pGC);
     exaFinishAccess (&pBitmap->drawable, EXA_PREPARE_SRC);
     exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
-    EXA_GC_EPILOGUE(pGC);
+    EXA_POST_FALLBACK_GC(pGC);
 }
 
 void
@@ -311,7 +310,7 @@ ExaCheckCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
 {
     DrawablePtr pDrawable = &pWin->drawable;
     ScreenPtr pScreen = pDrawable->pScreen;
-    ExaScreenPriv(pScreen);
+    EXA_PRE_FALLBACK(pScreen);
     EXA_FALLBACK(("from %p\n", pWin));
 
     /* being both src and dest, src is safest. */
@@ -320,6 +319,7 @@ ExaCheckCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
     pScreen->CopyWindow (pWin, ptOldOrg, prgnSrc);
     swap(pExaScr, pScreen, CopyWindow);
     exaFinishAccess (pDrawable, EXA_PREPARE_SRC);
+    EXA_POST_FALLBACK(pScreen);
 }
 
 void
@@ -328,8 +328,7 @@ ExaCheckGetImage(DrawablePtr pDrawable, int x, int y, int w, int h,
 {
     ScreenPtr pScreen = pDrawable->pScreen;
     PixmapPtr pPix = exaGetDrawablePixmap (pDrawable);
-    ExaScreenPriv(pScreen);
-
+    EXA_PRE_FALLBACK(pScreen);
     EXA_FALLBACK(("from %p (%c)\n", pDrawable,
 		  exaDrawableLocation(pDrawable)));
 
@@ -355,6 +354,7 @@ ExaCheckGetImage(DrawablePtr pDrawable, int x, int y, int w, int h,
     pScreen->GetImage (pDrawable, x, y, w, h, format, planeMask, d);
     swap(pExaScr, pScreen, GetImage);
     exaFinishAccess (pDrawable, EXA_PREPARE_SRC);
+    EXA_POST_FALLBACK(pScreen);
 }
 
 void
@@ -366,14 +366,15 @@ ExaCheckGetSpans (DrawablePtr pDrawable,
 		 char *pdstStart)
 {
     ScreenPtr pScreen = pDrawable->pScreen;
-    ExaScreenPriv(pScreen);
 
+    EXA_PRE_FALLBACK(pScreen);
     EXA_FALLBACK(("from %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
     exaPrepareAccess (pDrawable, EXA_PREPARE_SRC);
     swap(pExaScr, pScreen, GetSpans);
     pScreen->GetSpans (pDrawable, wMax, ppt, pwidth, nspans, pdstStart);
     swap(pExaScr, pScreen, GetSpans);
     exaFinishAccess (pDrawable, EXA_PREPARE_SRC);
+    EXA_POST_FALLBACK(pScreen);
 }
 
 void
@@ -394,9 +395,9 @@ ExaCheckComposite (CARD8      op,
 #ifdef RENDER
     PictureScreenPtr	ps = GetPictureScreen(pScreen);
 #endif /* RENDER */
-    ExaScreenPriv(pScreen);
     RegionRec region;
     int xoff, yoff;
+    EXA_PRE_FALLBACK(pScreen);
 
     REGION_NULL(pScreen, &region);
 
@@ -471,6 +472,7 @@ skip:
 	exaFinishAccess(pMask->alphaMap->pDrawable, EXA_PREPARE_AUX_MASK);
 
     REGION_UNINIT(pScreen, &region);
+    EXA_POST_FALLBACK(pScreen);
 }
 
 void
@@ -484,7 +486,7 @@ ExaCheckAddTraps (PicturePtr	pPicture,
 #ifdef RENDER
     PictureScreenPtr	ps = GetPictureScreen(pScreen);
 #endif /* RENDER */
-    ExaScreenPriv(pScreen);
+    EXA_PRE_FALLBACK(pScreen);
 
     EXA_FALLBACK(("to pict %p (%c)\n",
 		  exaDrawableLocation(pPicture->pDrawable)));
@@ -495,6 +497,7 @@ ExaCheckAddTraps (PicturePtr	pPicture,
     swap(pExaScr, ps, AddTraps);
 #endif /* RENDER */
     exaFinishAccess(pPicture->pDrawable, EXA_PREPARE_DEST);
+    EXA_POST_FALLBACK(pScreen);
 }
 
 /**
commit b54bc14ce0ae38c4863794bc3096ca86cdb23908
Author: Ingmar Vanhassel <ingmar at exherbo.org>
Date:   Wed Nov 25 20:31:48 2009 +0100

    Update man-pages for new default font paths
    
    Signed-off-by: Ingmar Vanhassel <ingmar at exherbo.org>
    Reviewed-by: Alan Coopersmith <alan.coopersmith at sun.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/doc/Xserver.man.pre b/doc/Xserver.man.pre
index 6154191..8144c8a 100644
--- a/doc/Xserver.man.pre
+++ b/doc/Xserver.man.pre
@@ -551,10 +551,10 @@ the following font path:
 .I /etc/X\fBn\fP.hosts
 Initial access control list for display number \fBn\fP
 .TP 30
-.IR __projectroot__/lib/X11/fonts/misc , __projectroot__/lib/X11/fonts/75dpi , __projectroot__/lib/X11/fonts/100dpi
+.IR __datadir__/fonts/X11/misc , __datadir__/fonts/X11/75dpi , __datadir__/fonts/X11/100dpi
 Bitmap font directories
 .TP 30
-.IR __projectroot__/lib/X11/fonts/TTF , __projectroot__/lib/X11/fonts/Type1
+.IR __datadir__/fonts/X11/TTF , __datadir__/fonts/X11/Type1
 Outline font directories
 .TP 30
 .I /tmp/.X11-unix/X\fBn\fP
diff --git a/hw/xfree86/doc/man/Xorg.man.pre b/hw/xfree86/doc/man/Xorg.man.pre
index 2f9ff98..fe32800 100644
--- a/hw/xfree86/doc/man/Xorg.man.pre
+++ b/hw/xfree86/doc/man/Xorg.man.pre
@@ -525,7 +525,7 @@ Header files.
 .B __projectroot__/lib/\(**
 Libraries.
 .TP 30
-.B __projectroot__/lib/X11/fonts/\(**
+.B __datadir__/fonts/X11/\(**
 Fonts.
 .TP 30
 .B __projectroot__/share/X11/XErrorDB
diff --git a/hw/xfree86/doc/man/xorg.conf.man.pre b/hw/xfree86/doc/man/xorg.conf.man.pre
index e3c897b..ace041c 100644
--- a/hw/xfree86/doc/man/xorg.conf.man.pre
+++ b/hw/xfree86/doc/man/xorg.conf.man.pre
@@ -356,12 +356,12 @@ font path elements (which can be set inside a catalogue directory):
 .PP
 .RS 4
 .nf
-.I __projectroot__/lib/X11/fonts/misc/
-.I __projectroot__/lib/X11/fonts/TTF/
-.I __projectroot__/lib/X11/fonts/OTF/
-.I __projectroot__/lib/X11/fonts/Type1/
-.I __projectroot__/lib/X11/fonts/100dpi/
-.I __projectroot__/lib/X11/fonts/75dpi/
+.I __datadir__/fonts/X11/misc/
+.I __datadir__/fonts/X11/TTF/
+.I __datadir__/fonts/X11/OTF/
+.I __datadir__/fonts/X11/Type1/
+.I __datadir__/fonts/X11/100dpi/
+.I __datadir__/fonts/X11/75dpi/
 .fi
 .RE
 .PP
commit c0367028ac02b3ccfbc245863dc6b7295a4014d6
Author: Ingmar Vanhassel <ingmar at exherbo.org>
Date:   Wed Nov 25 20:31:47 2009 +0100

    Update COMPILEDDEFAULTFONTPATH to match the new default font path
    
    Signed-off-by: Ingmar Vanhassel <ingmar at exherbo.org>
    Reviewed-by: Alan Coopersmith <alan.coopersmith at sun.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/include/site.h b/include/site.h
index c07cbbf..b134212 100644
--- a/include/site.h
+++ b/include/site.h
@@ -73,7 +73,7 @@ SOFTWARE.
  * DO NOT CHANGE THESE VALUES OR THE DIX IMAKEFILE!
  */
 #ifndef COMPILEDDEFAULTFONTPATH
-#define COMPILEDDEFAULTFONTPATH	"/usr/lib/X11/fonts/misc/"
+#define COMPILEDDEFAULTFONTPATH	"/usr/share/fonts/X11/misc/"
 #endif
 
 /*
commit 0e6cee853d8e5bef3274e632ef034d37f14674a9
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Nov 18 14:39:25 2009 +1000

    dix: clean up accel old scheme data when switching schemes.
    
    InitValuatorClassDeviceStruct always initializes with the default profile.
    The default profile allocs data and adds a few properties which become
    obsolete if the profile is changed lateron by the driver.
    
    The property handlers are stored in the device's devPrivates and cleaned up.
    Ideally, the property handler ID's could be stored somewhere more obvious,
    but that seems to require breaking the ABI.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Acked-by: Simon Thum <simon.thum at gmx.de>

diff --git a/dix/devices.c b/dix/devices.c
index 395e19a..3634eec 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -1235,6 +1235,8 @@ InitPointerAccelerationScheme(DeviceIntPtr dev,
     if(-1 == i)
         return FALSE;
 
+    if (val->accelScheme.AccelCleanupProc)
+        val->accelScheme.AccelCleanupProc(dev);
 
     /* init scheme-specific data */
     switch(scheme){
diff --git a/dix/ptrveloc.c b/dix/ptrveloc.c
index 37c8e51..6fb9e21 100644
--- a/dix/ptrveloc.c
+++ b/dix/ptrveloc.c
@@ -83,6 +83,9 @@ GetAccelerationProfile(DeviceVelocityPtr vel, int profile_num);
 /* some int which is not a profile number */
 #define PROFILE_UNINITIALIZE (-100)
 
+/* number of properties for predictable acceleration */
+#define NPROPS_PREDICTABLE_ACCEL 4
+
 /**
  * Init struct so it should match the average case
  */
@@ -128,6 +131,7 @@ AccelerationDefaultCleanup(DeviceIntPtr dev)
         FreeVelocityData(dev->valuator->accelScheme.accelData);
         xfree(dev->valuator->accelScheme.accelData);
         dev->valuator->accelScheme.accelData = NULL;
+        DeletePredictableAccelerationProperties(dev);
     }
 }
 
@@ -169,7 +173,7 @@ AccelSetProfileProperty(DeviceIntPtr dev, Atom atom,
     return Success;
 }
 
-static void
+static long
 AccelInitProfileProperty(DeviceIntPtr dev, DeviceVelocityPtr vel)
 {
     int profile = vel->statistics.profile_number;
@@ -178,7 +182,7 @@ AccelInitProfileProperty(DeviceIntPtr dev, DeviceVelocityPtr vel)
     XIChangeDeviceProperty(dev, prop_profile_number, XA_INTEGER, 32,
                            PropModeReplace, 1, &profile, FALSE);
     XISetDevicePropertyDeletable(dev, prop_profile_number, FALSE);
-    XIRegisterPropertyHandler(dev, AccelSetProfileProperty, NULL, NULL);
+    return XIRegisterPropertyHandler(dev, AccelSetProfileProperty, NULL, NULL);
 }
 
 /**
@@ -214,7 +218,7 @@ AccelSetDecelProperty(DeviceIntPtr dev, Atom atom,
     return Success;
 }
 
-static void
+static long
 AccelInitDecelProperty(DeviceIntPtr dev, DeviceVelocityPtr vel)
 {
     float fval = 1.0/vel->const_acceleration;
@@ -223,7 +227,7 @@ AccelInitDecelProperty(DeviceIntPtr dev, DeviceVelocityPtr vel)
                            XIGetKnownProperty(XATOM_FLOAT), 32,
                            PropModeReplace, 1, &fval, FALSE);
     XISetDevicePropertyDeletable(dev, prop_const_decel, FALSE);
-    XIRegisterPropertyHandler(dev, AccelSetDecelProperty, NULL, NULL);
+    return XIRegisterPropertyHandler(dev, AccelSetDecelProperty, NULL, NULL);
 }
 
 
@@ -260,7 +264,7 @@ AccelSetAdaptDecelProperty(DeviceIntPtr dev, Atom atom,
     return Success;
 }
 
-static void
+static long
 AccelInitAdaptDecelProperty(DeviceIntPtr dev, DeviceVelocityPtr vel)
 {
     float fval = 1.0/vel->min_acceleration;
@@ -269,7 +273,7 @@ AccelInitAdaptDecelProperty(DeviceIntPtr dev, DeviceVelocityPtr vel)
     XIChangeDeviceProperty(dev, prop_adapt_decel, XIGetKnownProperty(XATOM_FLOAT), 32,
                            PropModeReplace, 1, &fval, FALSE);
     XISetDevicePropertyDeletable(dev, prop_adapt_decel, FALSE);
-    XIRegisterPropertyHandler(dev, AccelSetAdaptDecelProperty, NULL, NULL);
+    return XIRegisterPropertyHandler(dev, AccelSetAdaptDecelProperty, NULL, NULL);
 }
 
 
@@ -307,7 +311,7 @@ AccelSetScaleProperty(DeviceIntPtr dev, Atom atom,
     return Success;
 }
 
-static void
+static long
 AccelInitScaleProperty(DeviceIntPtr dev, DeviceVelocityPtr vel)
 {
     float fval = vel->corr_mul;
@@ -316,21 +320,57 @@ AccelInitScaleProperty(DeviceIntPtr dev, DeviceVelocityPtr vel)
     XIChangeDeviceProperty(dev, prop_velo_scale, XIGetKnownProperty(XATOM_FLOAT), 32,
                            PropModeReplace, 1, &fval, FALSE);
     XISetDevicePropertyDeletable(dev, prop_velo_scale, FALSE);
-    XIRegisterPropertyHandler(dev, AccelSetScaleProperty, NULL, NULL);
+    return XIRegisterPropertyHandler(dev, AccelSetScaleProperty, NULL, NULL);
 }
 
+static int AccelPropHandlerPrivateKeyIndex;
+DevPrivateKey AccelPropHandlerPrivateKey = &AccelPropHandlerPrivateKeyIndex;
+
 BOOL
 InitializePredictableAccelerationProperties(DeviceIntPtr dev)
 {
     DeviceVelocityPtr  vel = GetDevicePredictableAccelData(dev);
+    long *prop_handlers;
 
     if(!vel)
 	return FALSE;
+    prop_handlers = xalloc(NPROPS_PREDICTABLE_ACCEL * sizeof(long));
+
+    prop_handlers[0] = AccelInitProfileProperty(dev, vel);
+    prop_handlers[1] = AccelInitDecelProperty(dev, vel);
+    prop_handlers[2] = AccelInitAdaptDecelProperty(dev, vel);
+    prop_handlers[3] = AccelInitScaleProperty(dev, vel);
+
+    dixSetPrivate(&dev->devPrivates, AccelPropHandlerPrivateKey,
+                  prop_handlers);
+
+    return TRUE;
+}
+
+BOOL
+DeletePredictableAccelerationProperties(DeviceIntPtr dev)
+{
+    Atom prop;
+    long *prop_handlers;
+    int i;
+
+    prop = XIGetKnownProperty(ACCEL_PROP_VELOCITY_SCALING);
+    XIDeleteDeviceProperty(dev, prop, FALSE);
+    prop = XIGetKnownProperty(ACCEL_PROP_ADAPTIVE_DECELERATION);
+    XIDeleteDeviceProperty(dev, prop, FALSE);
+    prop = XIGetKnownProperty(ACCEL_PROP_CONSTANT_DECELERATION);
+    XIDeleteDeviceProperty(dev, prop, FALSE);
+    prop = XIGetKnownProperty(ACCEL_PROP_PROFILE_NUMBER);
+    XIDeleteDeviceProperty(dev, prop, FALSE);
+
+    prop_handlers = dixLookupPrivate(&dev->devPrivates,
+                                     AccelPropHandlerPrivateKey);
+    dixSetPrivate(&dev->devPrivates, AccelPropHandlerPrivateKey, NULL);
+
+    for (i = 0; prop_handlers && i < NPROPS_PREDICTABLE_ACCEL; i++)
+        XIUnregisterPropertyHandler(dev, prop_handlers[i]);
+    xfree(prop_handlers);
 
-    AccelInitProfileProperty(dev, vel);
-    AccelInitDecelProperty(dev, vel);
-    AccelInitAdaptDecelProperty(dev, vel);
-    AccelInitScaleProperty(dev, vel);
     return TRUE;
 }
 
diff --git a/include/ptrveloc.h b/include/ptrveloc.h
index fa2156b..2a4b40b 100644
--- a/include/ptrveloc.h
+++ b/include/ptrveloc.h
@@ -109,6 +109,9 @@ FreeVelocityData(DeviceVelocityPtr vel);
 extern _X_INTERNAL BOOL
 InitializePredictableAccelerationProperties(DeviceIntPtr dev);
 
+extern _X_INTERNAL BOOL
+DeletePredictableAccelerationProperties(DeviceIntPtr dev);
+
 extern _X_EXPORT int
 SetAccelerationProfile(DeviceVelocityPtr vel, int profile_num);
 
commit 1b127ab8429616adf9ec31ba4d8bdd9af6e104a9
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Tue Nov 24 15:31:48 2009 +1000

    Xi: when deleting all properties, reset property handler to NULL.
    
    Trying to unregister property handlers during the device closure process
    leads to invalid memory accesses.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/Xi/xiproperty.c b/Xi/xiproperty.c
index 4821857..ecb326e 100644
--- a/Xi/xiproperty.c
+++ b/Xi/xiproperty.c
@@ -630,6 +630,8 @@ XIDeleteAllDeviceProperties (DeviceIntPtr device)
         xfree(curr_handler);
         curr_handler = next_handler;
     }
+
+    device->properties.handlers = NULL;
 }
 
 
diff --git a/test/input.c b/test/input.c
index 71e1504..2de55bc 100644
--- a/test/input.c
+++ b/test/input.c
@@ -716,6 +716,59 @@ static void include_byte_padding_macros(void)
 
 }
 
+static void xi_unregister_handlers(void)
+{
+    DeviceIntRec dev;
+    int handler;
+
+    memset(&dev, 0, sizeof(dev));
+
+    handler = XIRegisterPropertyHandler(&dev, NULL, NULL, NULL);
+    g_assert(handler == 1);
+    handler = XIRegisterPropertyHandler(&dev, NULL, NULL, NULL);
+    g_assert(handler == 2);
+    handler = XIRegisterPropertyHandler(&dev, NULL, NULL, NULL);
+    g_assert(handler == 3);
+
+    g_test_message("Unlinking from front.");
+
+    XIUnregisterPropertyHandler(&dev, 4); /* NOOP */
+    g_assert(dev.properties.handlers->id == 3);
+    XIUnregisterPropertyHandler(&dev, 3);
+    g_assert(dev.properties.handlers->id == 2);
+    XIUnregisterPropertyHandler(&dev, 2);
+    g_assert(dev.properties.handlers->id == 1);
+    XIUnregisterPropertyHandler(&dev, 1);
+    g_assert(dev.properties.handlers == NULL);
+
+    handler = XIRegisterPropertyHandler(&dev, NULL, NULL, NULL);
+    g_assert(handler == 4);
+    handler = XIRegisterPropertyHandler(&dev, NULL, NULL, NULL);
+    g_assert(handler == 5);
+    handler = XIRegisterPropertyHandler(&dev, NULL, NULL, NULL);
+    g_assert(handler == 6);
+    XIUnregisterPropertyHandler(&dev, 3); /* NOOP */
+    g_assert(dev.properties.handlers->next->next->next == NULL);
+    XIUnregisterPropertyHandler(&dev, 4);
+    g_assert(dev.properties.handlers->next->next == NULL);
+    XIUnregisterPropertyHandler(&dev, 5);
+    g_assert(dev.properties.handlers->next == NULL);
+    XIUnregisterPropertyHandler(&dev, 6);
+    g_assert(dev.properties.handlers == NULL);
+
+    handler = XIRegisterPropertyHandler(&dev, NULL, NULL, NULL);
+    g_assert(handler == 7);
+    handler = XIRegisterPropertyHandler(&dev, NULL, NULL, NULL);
+    g_assert(handler == 8);
+    handler = XIRegisterPropertyHandler(&dev, NULL, NULL, NULL);
+    g_assert(handler == 9);
+
+    XIDeleteAllDeviceProperties(&dev);
+    g_assert(dev.properties.handlers == NULL);
+    XIUnregisterPropertyHandler(&dev, 7); /* NOOP */
+
+}
+
 int main(int argc, char** argv)
 {
     g_test_init(&argc, &argv,NULL);
@@ -727,6 +780,7 @@ int main(int argc, char** argv)
     g_test_add_func("/dix/input/xi2-struct-sizes", xi2_struct_sizes);
     g_test_add_func("/dix/input/grab_matching", dix_grab_matching);
     g_test_add_func("/include/byte_padding_macros", include_byte_padding_macros);
+    g_test_add_func("/Xi/xiproperty/register-unregister", xi_unregister_handlers);
 
     return g_test_run();
 }
commit 8806375ed72a3cd465fe0a49ead079a334accd6b
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Tue Nov 17 09:25:47 2009 +1000

    Move xdmxconfig modules into DMX conditionals (#25102)
    
    xdmxconfig requires additional modules not checked for if Xdmx build is set
    to auto (the default). This may lead to build errors if the Xdmx modules are
    installed, but not the extra ones required for xdmxconfig.
    
    X.Org Bug 25102 <http://bugs.freedesktop.org/show_bug.cgi?id=25102>
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Remi Cardona <remi at gentoo.org>
    Acked-by: Julien Cristau <jcristau at debian.org>

diff --git a/configure.ac b/configure.ac
index 4c3b3f8..fcd8875 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1881,10 +1881,11 @@ AM_CONDITIONAL(XQUARTZ_SPARKLE, [test "x$XQUARTZ_SPARKLE" != "xno"])
 AM_CONDITIONAL(STANDALONE_XPBPROXY, [test "x$STANDALONE_XPBPROXY" = xyes])
 
 dnl DMX DDX
-
 PKG_CHECK_MODULES([DMXMODULES],
     [xmuu $LIBXEXT x11 xrender xfixes xfont $LIBXI $DMXPROTO xau $XDMCP_MODULES],
-    [have_dmx=yes], [have_dmx=no])
+    PKG_CHECK_MODULES([XDMXCONFIG_DEP], [xaw7 xmu xt xpm x11], [have_dmx=yes],
+                      [have_dmx=no]),
+    [have_dmx=no])
 AC_MSG_CHECKING([whether to build Xdmx DDX])
 if test "x$DMX" = xauto; then
 	DMX="$have_dmx"
@@ -1917,7 +1918,6 @@ dnl USB sources in DMX require <linux/input.h>
 dnl Linux sources in DMX require <linux/keyboard.h>
 	AC_CHECK_HEADER([linux/keyboard.h], DMX_BUILD_LNX="yes",
 			DMX_BUILD_LNX="no")
-	PKG_CHECK_MODULES([XDMXCONFIG_DEP], [xaw7 xmu xt xpm x11])
 	AC_SUBST(XDMXCONFIG_DEP_CFLAGS)
 	AC_SUBST(XDMXCONFIG_DEP_LIBS)
 	PKG_CHECK_MODULES([DMXEXAMPLES_DEP], [$LIBDMX $LIBXEXT x11])
commit a2adda7ab3defd953cf0f48f5372efb037786a9e
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Nov 19 16:35:55 2009 +1000

    Revert "Move xdmxconfig modules into DMX conditionals (#25102)"
    
    New package dependency unnecessarily links in a few libraries that Xdmx
    doesn't need. This can be fixed more elegantly.
    
    This reverts commit 0ef15ca9d2d9c78c79a2771c550563bc6931b365.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/configure.ac b/configure.ac
index 6f8441c..4c3b3f8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1881,9 +1881,9 @@ AM_CONDITIONAL(XQUARTZ_SPARKLE, [test "x$XQUARTZ_SPARKLE" != "xno"])
 AM_CONDITIONAL(STANDALONE_XPBPROXY, [test "x$STANDALONE_XPBPROXY" = xyes])
 
 dnl DMX DDX
-XDMXCONFIG_MODULES="xaw7 xmu xt xpm x11"
+
 PKG_CHECK_MODULES([DMXMODULES],
-    [xmuu $LIBXEXT x11 xrender xfixes xfont $LIBXI $DMXPROTO xau $XDMCP_MODULES $XDMXCONFIG_MODULES],
+    [xmuu $LIBXEXT x11 xrender xfixes xfont $LIBXI $DMXPROTO xau $XDMCP_MODULES],
     [have_dmx=yes], [have_dmx=no])
 AC_MSG_CHECKING([whether to build Xdmx DDX])
 if test "x$DMX" = xauto; then
@@ -1917,7 +1917,7 @@ dnl USB sources in DMX require <linux/input.h>
 dnl Linux sources in DMX require <linux/keyboard.h>
 	AC_CHECK_HEADER([linux/keyboard.h], DMX_BUILD_LNX="yes",
 			DMX_BUILD_LNX="no")
-	PKG_CHECK_MODULES([XDMXCONFIG_DEP], [$XDMXCONFIG_MODULES])
+	PKG_CHECK_MODULES([XDMXCONFIG_DEP], [xaw7 xmu xt xpm x11])
 	AC_SUBST(XDMXCONFIG_DEP_CFLAGS)
 	AC_SUBST(XDMXCONFIG_DEP_LIBS)
 	PKG_CHECK_MODULES([DMXEXAMPLES_DEP], [$LIBDMX $LIBXEXT x11])
commit eb967ca36cfe0409972ac987a74d498cd6f6bafb
Author: Rami Ylimaki <ext-rami.ylimaki at nokia.com>
Date:   Tue Nov 17 17:13:43 2009 +0200

    Xext: Fix a memory leak on GE client disconnect.
    
    Add a call to dixRequestPrivate to inform dixFreePrivates that memory
    allocated in GEClientCallback should be released when client
    disconnects. Otherwise there is a leak of sizeof(GEClientInfoRec) for
    every client connect/disconnect.
    
    Also remove the explicit allocation and let GEGetClient /
    dixLookupPrivate do it. This makes GEClientCallback similar to the
    other extension callbacks.
    
    Signed-off-by: Rami Ylimaki <ext-rami.ylimaki at nokia.com>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xext/geext.c b/Xext/geext.c
index 6fad4ae..2ba0ca8 100644
--- a/Xext/geext.c
+++ b/Xext/geext.c
@@ -168,12 +168,6 @@ GEClientCallback(CallbackListPtr *list,
     ClientPtr		pClient = clientinfo->client;
     GEClientInfoPtr     pGEClient = GEGetClient(pClient);
 
-    if (pGEClient == NULL)
-    {
-        pGEClient = xcalloc(1, sizeof(GEClientInfoRec));
-        dixSetPrivate(&pClient->devPrivates, GEClientPrivateKey, pGEClient);
-    }
-
     pGEClient->major_version = 0;
     pGEClient->minor_version = 0;
 }
@@ -222,6 +216,9 @@ GEExtensionInit(void)
 {
     ExtensionEntry *extEntry;
 
+    if (!dixRequestPrivate(GEClientPrivateKey, sizeof(GEClientInfoRec)))
+        FatalError("GEExtensionInit: GE private request failed.\n");
+
     if(!AddCallback(&ClientStateCallback, GEClientCallback, 0))
     {
         FatalError("GEExtensionInit: register client callback failed.\n");
commit 55f60e192318132157d3dfdd6732f141bd9dc352
Author: Maarten Maathuis <madman2003 at gmail.com>
Date:   Mon Nov 23 22:17:43 2009 +0100

    Revert "exa/mixed: be more thorough about setting fb_pitch when needed"
    
    This reverts commit d4fc245115eb2cb323e06a82f9dd52518d9b6a16.
    
    - This is causing crashes/problems for some.
    
    Acked-by: Michel Dänzer <michel at daenzer.net>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/exa/exa_migration_mixed.c b/exa/exa_migration_mixed.c
index 121a4ad..ea6f878 100644
--- a/exa/exa_migration_mixed.c
+++ b/exa/exa_migration_mixed.c
@@ -98,17 +98,14 @@ exaDoMigration_mixed(ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel)
 	if (!pExaPixmap->driverPriv)
 	    exaCreateDriverPixmap_mixed(pPixmap);
 
-	if (exaPixmapIsOffscreen(pPixmap)) {
-	    pPixmap->devKind = pExaPixmap->fb_pitch;
-
-	    if (pExaPixmap->pDamage) {
-		ExaScreenPriv(pPixmap->drawable.pScreen);
+	if (pExaPixmap->pDamage && exaPixmapIsOffscreen(pPixmap)) {
+	    ExaScreenPriv(pPixmap->drawable.pScreen);
 
-		exaCopyDirtyToFb(pixmaps + i);
+	    pPixmap->devKind = pExaPixmap->fb_pitch;
+	    exaCopyDirtyToFb(pixmaps + i);
 
-		if (pExaScr->deferred_mixed_pixmap == pPixmap)
-		    pExaScr->deferred_mixed_pixmap = NULL;
-	    }
+	    if (pExaScr->deferred_mixed_pixmap == pPixmap)
+		pExaScr->deferred_mixed_pixmap = NULL;
 	}
 
 	pExaPixmap->offscreen = exaPixmapIsOffscreen(pPixmap);
@@ -136,9 +133,8 @@ exaMoveInPixmap_mixed(PixmapPtr pPixmap)
 void
 exaPrepareAccessReg_mixed(PixmapPtr pPixmap, int index, RegionPtr pReg)
 {
-    ExaPixmapPriv(pPixmap);
-
     if (!ExaDoPrepareAccess(pPixmap, index)) {
+	ExaPixmapPriv(pPixmap);
 	Bool is_offscreen = exaPixmapIsOffscreen(pPixmap);
 	ExaMigrationRec pixmaps[1];
 
@@ -201,8 +197,7 @@ exaPrepareAccessReg_mixed(PixmapPtr pPixmap, int index, RegionPtr pReg)
 	pPixmap->devPrivate.ptr = pExaPixmap->sys_ptr;
 	pPixmap->devKind = pExaPixmap->sys_pitch;
 	pExaPixmap->offscreen = FALSE;
-    } else
-	pPixmap->devKind = pExaPixmap->fb_pitch;
+    }
 }
 
 /* Move back results of software rendering on system memory copy of mixed driver


More information about the Xquartz-changes mailing list