[PATCH 2/4] Have FreePixmap call screen hooks, not the other way around.

Jamey Sharp jamey at minilop.net
Fri Sep 17 09:01:43 PDT 2010


In the process, move reference counting into FreePixmap instead of
doing it inconsistently in the various screen hooks.

Commit by Jamey Sharp and Josh Triplett.

Signed-off-by: Jamey Sharp <jamey at minilop.net>
Signed-off-by: Josh Triplett <josh at joshtriplett.org>
---
 Xext/saver.c                |    4 +-
 Xext/shm.c                  |   29 ++++++++-----------
 Xext/xvmain.c               |   10 ++----
 composite/compalloc.c       |    2 +-
 composite/compwindow.c      |    3 +-
 dbe/midbe.c                 |   24 ++++-----------
 dix/dispatch.c              |    6 ++--
 dix/gc.c                    |   20 ++++++------
 dix/glyphcurs.c             |    4 +-
 dix/pixmap.c                |    7 +++-
 dix/window.c                |   18 ++++++------
 doc/xml/Xserver-spec.xml    |   12 ++++----
 exa/exa_classic.c           |   45 ++++++++++++-----------------
 exa/exa_driver.c            |   23 +++++----------
 exa/exa_glyphs.c            |    8 ++--
 exa/exa_mixed.c             |   33 ++++++++-------------
 exa/exa_offscreen.c         |    2 +-
 exa/exa_priv.h              |    6 ++--
 exa/exa_render.c            |    4 +-
 fb/fb.h                     |    2 +-
 fb/fbgc.c                   |    4 +-
 fb/fboverlay.c              |    2 +-
 fb/fbpixmap.c               |    6 +---
 fb/fbwindow.c               |    4 +-
 hw/dmx/dmxpixmap.c          |   11 +------
 hw/dmx/dmxpixmap.h          |    2 +-
 hw/dmx/glxProxy/glxext.c    |    4 +-
 hw/xfree86/common/xf86DGA.c |    4 +-
 hw/xfree86/xaa/xaaInit.c    |   65 ++++++++++++++++++++-----------------------
 hw/xnest/Pixmap.c           |    6 +---
 hw/xnest/XNPixmap.h         |    2 +-
 include/scrnintstr.h        |    2 +-
 mi/miarc.c                  |    4 +-
 mi/mibitblt.c               |    6 ++--
 mi/midispcur.c              |   14 ++++----
 mi/migc.c                   |    2 +-
 mi/miglblt.c                |    6 ++--
 mi/miscrinit.c              |    3 +-
 miext/damage/damage.c       |   20 +++++--------
 miext/shadow/shadow.c       |    4 +-
 render/glyph.c              |    4 +-
 render/mipict.c             |    4 +-
 render/mirect.c             |    2 +-
 render/mitrap.c             |    4 +-
 render/picture.c            |    2 +-
 render/render.c             |    4 +-
 46 files changed, 196 insertions(+), 257 deletions(-)

diff --git a/Xext/saver.c b/Xext/saver.c
index 6d91ddf..eac1a71 100644
--- a/Xext/saver.c
+++ b/Xext/saver.c
@@ -379,9 +379,9 @@ FreeAttrs (ScreenSaverAttrPtr pAttr)
     CursorPtr	    pCursor;
 
     if ((pPixmap = pAttr->pBackgroundPixmap) != 0)
-	(*pPixmap->drawable.pScreen->DestroyPixmap)(pPixmap);
+	FreePixmap(pPixmap);
     if ((pPixmap = pAttr->pBorderPixmap) != 0)
-	(*pPixmap->drawable.pScreen->DestroyPixmap)(pPixmap);
+	FreePixmap(pPixmap);
     if ((pCursor = pAttr->pCursor) != 0)
 	FreeCursor (pCursor, (Cursor) 0);
 }
diff --git a/Xext/shm.c b/Xext/shm.c
index 28e1130..2e8468c 100644
--- a/Xext/shm.c
+++ b/Xext/shm.c
@@ -118,7 +118,7 @@ static void SShmCompletionEvent(
     xShmCompletionEvent * /* to */
     );
 
-static Bool ShmDestroyPixmap (PixmapPtr pPixmap);
+static void ShmDestroyPixmap (PixmapPtr pPixmap);
 
 static DISPATCH_PROC(ProcShmAttach);
 static DISPATCH_PROC(ProcShmCreatePixmap);
@@ -321,26 +321,21 @@ ShmRegisterFuncs(ScreenPtr pScreen, ShmFuncsPtr funcs)
     ShmInitScreenPriv(pScreen)->shmFuncs = funcs;
 }
 
-static Bool
+static void
 ShmDestroyPixmap (PixmapPtr pPixmap)
 {
     ScreenPtr	    pScreen = pPixmap->drawable.pScreen;
     ShmScrPrivateRec *screen_priv = ShmGetScreenPriv(pScreen);
-    Bool	    ret;
-    if (pPixmap->refcnt == 1)
-    {
-	ShmDescPtr  shmdesc;
-	shmdesc = (ShmDescPtr)dixLookupPrivate(&pPixmap->devPrivates,
-					       shmPixmapPrivateKey);
-	if (shmdesc)
-	    ShmDetachSegment ((pointer) shmdesc, pPixmap->drawable.id);
-    }
-    
+    ShmDescPtr  shmdesc;
+    shmdesc = (ShmDescPtr)dixLookupPrivate(&pPixmap->devPrivates,
+                                           shmPixmapPrivateKey);
+    if (shmdesc)
+        ShmDetachSegment ((pointer) shmdesc, pPixmap->drawable.id);
+
     pScreen->DestroyPixmap = screen_priv->destroyPixmap;
-    ret = (*pScreen->DestroyPixmap) (pPixmap);
+    (*pScreen->DestroyPixmap) (pPixmap);
     screen_priv->destroyPixmap = pScreen->DestroyPixmap;
     pScreen->DestroyPixmap = ShmDestroyPixmap;
-    return ret;
 }
 
 void
@@ -577,7 +572,7 @@ doShmPutImage(DrawablePtr dst, GCPtr pGC,
 	else
 	    (void)(*pGC->pScreen->ops->CopyArea)(&pPixmap->drawable, dst, pGC, 0, 0, sw, sh,
 					dx, dy);
-	(*pPixmap->drawable.pScreen->DestroyPixmap)(pPixmap);
+	FreePixmap(pPixmap);
     }
 }
 
@@ -1078,7 +1073,7 @@ fbShmCreatePixmap (ScreenPtr pScreen,
 
     if (!(*pScreen->ModifyPixmapHeader)(pPixmap, width, height, depth,
 	    BitsPerPixel(depth), PixmapBytePad(width, depth), (pointer)addr)) {
-	(*pScreen->DestroyPixmap)(pPixmap);
+	FreePixmap(pPixmap);
 	return NullPixmap;
     }
     return pPixmap;
@@ -1151,7 +1146,7 @@ CreatePmap:
 	rc = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, RT_PIXMAP,
 		      pMap, RT_NONE, NULL, DixCreateAccess);
 	if (rc != Success) {
-	    pDraw->pScreen->DestroyPixmap(pMap);
+	    FreePixmap(pMap);
 	    return rc;
 	}
 	dixSetPrivate(&pMap->devPrivates, shmPixmapPrivateKey, shmdesc);
diff --git a/Xext/xvmain.c b/Xext/xvmain.c
index 12b4c51..88c181f 100644
--- a/Xext/xvmain.c
+++ b/Xext/xvmain.c
@@ -131,7 +131,7 @@ static void WriteSwappedPortNotifyEvent(xvEvent *, xvEvent *);
 static Bool CreateResourceTypes(void);
 
 static Bool XvCloseScreen(int, ScreenPtr);
-static Bool XvDestroyPixmap(PixmapPtr);
+static void XvDestroyPixmap(PixmapPtr);
 static Bool XvDestroyWindow(WindowPtr);
 static void XvResetProc(ExtensionEntry*);
 static int XvdiDestroyGrab(pointer, XID);
@@ -343,10 +343,9 @@ XvGetRTPort(void)
   return XvRTPort;
 }
 
-static Bool
+static void
 XvDestroyPixmap(PixmapPtr pPix)
 {
-  Bool status;
   ScreenPtr pScreen;
   XvScreenPtr pxvs;
   XvAdaptorPtr pa;
@@ -386,12 +385,9 @@ XvDestroyPixmap(PixmapPtr pPix)
       pa++;
     }
   
-  status = (* pScreen->DestroyPixmap)(pPix);
+  (* pScreen->DestroyPixmap)(pPix);
 
   SCREEN_EPILOGUE(pScreen, DestroyPixmap, XvDestroyPixmap);
-
-  return status;
-
 }
 
 static Bool
diff --git a/composite/compalloc.c b/composite/compalloc.c
index 0785676..4e2018f 100644
--- a/composite/compalloc.c
+++ b/composite/compalloc.c
@@ -604,7 +604,7 @@ compFreePixmap (WindowPtr pWin)
     pParentPixmap = (*pScreen->GetWindowPixmap) (pWin->parent);
     pWin->redirectDraw = RedirectDrawNone;
     compSetPixmap (pWin, pParentPixmap);
-    (*pScreen->DestroyPixmap) (pRedirectPixmap);
+    FreePixmap(pRedirectPixmap);
 }
 
 /*
diff --git a/composite/compwindow.c b/composite/compwindow.c
index 0d0cfa1..d86839b 100644
--- a/composite/compwindow.c
+++ b/composite/compwindow.c
@@ -336,13 +336,12 @@ compImplicitRedirect (WindowPtr pWin, WindowPtr pParent)
 
 static void compFreeOldPixmap(WindowPtr pWin)
 {
-    ScreenPtr		pScreen = pWin->drawable.pScreen;
     if (pWin->redirectDraw != RedirectDrawNone)
     {
 	CompWindowPtr	cw = GetCompWindow (pWin);
 	if (cw->pOldPixmap)
 	{
-	    (*pScreen->DestroyPixmap) (cw->pOldPixmap);
+	    FreePixmap(cw->pOldPixmap);
 	    cw->pOldPixmap = NullPixmap;
 	}
     }
diff --git a/dbe/midbe.c b/dbe/midbe.c
index 9b16aea..a5c2e4a 100644
--- a/dbe/midbe.c
+++ b/dbe/midbe.c
@@ -184,7 +184,7 @@ miDbeAllocBackBufferName(WindowPtr pWin, XID bufId, int swapAction)
                                      pDbeWindowPriv->height,
                                      pWin->drawable.depth, 0)))
         {
-            (*pScreen->DestroyPixmap)(pDbeWindowPrivPriv->pFrontBuffer); 
+            FreePixmap(pDbeWindowPrivPriv->pFrontBuffer);
             return BadAlloc;
         }
 
@@ -478,15 +478,9 @@ miDbeWinPrivDelete(DbeWindowPrivPtr pDbeWindowPriv, XID bufId)
 
     /* Destroy the front and back pixmaps. */
     if (pDbeWindowPrivPriv->pFrontBuffer)
-    {
-        (*pDbeWindowPriv->pWindow->drawable.pScreen->DestroyPixmap)(
-            pDbeWindowPrivPriv->pFrontBuffer);
-    }
+        FreePixmap(pDbeWindowPrivPriv->pFrontBuffer);
     if (pDbeWindowPrivPriv->pBackBuffer)
-    {
-        (*pDbeWindowPriv->pWindow->drawable.pScreen->DestroyPixmap)(
-            pDbeWindowPrivPriv->pBackBuffer);
-    }
+        FreePixmap(pDbeWindowPrivPriv->pBackBuffer);
 
 } /* miDbeWinPrivDelete() */
 
@@ -652,14 +646,10 @@ miDbePositionWindow(WindowPtr pWin, int x, int y)
         /* We failed at creating 1 or 2 of the pixmaps. */
 
         if (pFrontBuffer)
-        {
-	    (*pScreen->DestroyPixmap)(pFrontBuffer);
-        }
+            FreePixmap(pFrontBuffer);
 
         if (pBackBuffer)
-        {
-	    (*pScreen->DestroyPixmap)(pBackBuffer);
-        }
+            FreePixmap(pBackBuffer);
 
         /* Destroy all buffers for this window. */
         while (pDbeWindowPriv)
@@ -719,8 +709,8 @@ miDbePositionWindow(WindowPtr pWin, int x, int y)
          * pixmaps.
          */
 
-	(*pScreen->DestroyPixmap)(pDbeWindowPrivPriv->pFrontBuffer);
-	(*pScreen->DestroyPixmap)(pDbeWindowPrivPriv->pBackBuffer);
+        FreePixmap(pDbeWindowPrivPriv->pFrontBuffer);
+        FreePixmap(pDbeWindowPrivPriv->pBackBuffer);
 
         pDbeWindowPrivPriv->pFrontBuffer = pFrontBuffer;
         pDbeWindowPrivPriv->pBackBuffer  = pBackBuffer;
diff --git a/dix/dispatch.c b/dix/dispatch.c
index 30aa415..5032393 100644
--- a/dix/dispatch.c
+++ b/dix/dispatch.c
@@ -1358,8 +1358,8 @@ ProcListFontsWithInfo(ClientPtr client)
 int
 dixDestroyPixmap(pointer value, XID pid)
 {
-    PixmapPtr pPixmap = (PixmapPtr)value;
-    return (*pPixmap->drawable.pScreen->DestroyPixmap)(pPixmap);
+    FreePixmap(value);
+    return TRUE;
 }
 
 int
@@ -1423,7 +1423,7 @@ CreatePmap:
 	rc = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, RT_PIXMAP,
 		      pMap, RT_NONE, NULL, DixCreateAccess);
 	if (rc != Success) {
-	    (*pDraw->pScreen->DestroyPixmap)(pMap);
+	    FreePixmap(pMap);
 	    return rc;
 	}
 	if (AddResource(stuff->pid, RT_PIXMAP, (pointer)pMap))
diff --git a/dix/gc.c b/dix/gc.c
index 10fa2e6..9d433c8 100644
--- a/dix/gc.c
+++ b/dix/gc.c
@@ -258,7 +258,7 @@ ChangeGC(ClientPtr client, GC *pGC, BITS32 mask, ChangeGCValPtr pUnion)
 		{
 		    pPixmap->refcnt++;
 		    if (!pGC->tileIsPixel)
-			(* pGC->pScreen->DestroyPixmap)(pGC->tile.pixmap);
+			FreePixmap(pGC->tile.pixmap);
 		    pGC->tileIsPixel = FALSE;
 		    pGC->tile.pixmap = pPixmap;
 		}
@@ -274,7 +274,7 @@ ChangeGC(ClientPtr client, GC *pGC, BITS32 mask, ChangeGCValPtr pUnion)
 		{
 		    pPixmap->refcnt++;
 		    if (pGC->stipple)
-			(* pGC->pScreen->DestroyPixmap)(pGC->stipple);
+			FreePixmap(pGC->stipple);
 		    pGC->stipple = pPixmap;
 		}
 		break;
@@ -581,7 +581,7 @@ CreateDefaultTile (GCPtr pGC)
     if (!pTile || !pgcScratch)
     {
 	if (pTile)
-	    (*pTile->drawable.pScreen->DestroyPixmap)(pTile);
+	    FreePixmap(pTile);
 	if (pgcScratch)
 	    FreeScratchGC(pgcScratch);
 	return FALSE;
@@ -662,7 +662,7 @@ CopyGC(GC *pgcSrc, GC *pgcDst, BITS32 mask)
 			break;
 		    }
 		    if (!pgcDst->tileIsPixel)
-			(* pgcDst->pScreen->DestroyPixmap)(pgcDst->tile.pixmap);
+			FreePixmap(pgcDst->tile.pixmap);
 		    pgcDst->tileIsPixel = pgcSrc->tileIsPixel;
 		    pgcDst->tile = pgcSrc->tile;
 		    if (!pgcDst->tileIsPixel)
@@ -674,7 +674,7 @@ CopyGC(GC *pgcSrc, GC *pgcDst, BITS32 mask)
 		    if (pgcDst->stipple == pgcSrc->stipple)
 			break;
 		    if (pgcDst->stipple)
-			(* pgcDst->pScreen->DestroyPixmap)(pgcDst->stipple);
+			FreePixmap(pgcDst->stipple);
 		    pgcDst->stipple = pgcSrc->stipple;
 		    if (pgcDst->stipple)
 			pgcDst->stipple->refcnt ++;
@@ -774,9 +774,9 @@ FreeGC(pointer value, XID gid)
     DestroyClip(pGC);
 
     if (!pGC->tileIsPixel)
-	(* pGC->pScreen->DestroyPixmap)(pGC->tile.pixmap);
+	FreePixmap(pGC->tile.pixmap);
     if (pGC->stipple)
-	(* pGC->pScreen->DestroyPixmap)(pGC->stipple);
+	FreePixmap(pGC->stipple);
 
     (*pGC->pScreen->funcs->DestroyGC) (pGC);
     if (pGC->dash != DefaultDash)
@@ -924,7 +924,7 @@ CreateDefaultStipple(int screenNum)
     pgcScratch = GetScratchGC(1, pScreen);
     if (!pgcScratch)
     {
-	(*pScreen->DestroyPixmap)(pScreen->PixmapPerDepth[0]);
+	FreePixmap(pScreen->PixmapPerDepth[0]);
 	return FALSE;
     }
     (void)ChangeGC(NullClient, pgcScratch, GCFunction|GCForeground|GCFillStyle, tmpval);
@@ -943,7 +943,7 @@ void
 FreeDefaultStipple(int screenNum)
 {
     ScreenPtr pScreen = screenInfo.screens[screenNum];
-    (*pScreen->DestroyPixmap)(pScreen->PixmapPerDepth[0]);
+    FreePixmap(pScreen->PixmapPerDepth[0]);
 }
 
 int
@@ -1098,7 +1098,7 @@ ChangeClip(GCPtr pGC, int type, pointer pvalue, int nrects)
     {
 	/* convert the pixmap to a region */
 	pGC->clientClip = BitmapToRegion(pGC->pScreen, (PixmapPtr) pvalue);
-	(*pGC->pScreen->DestroyPixmap) (pvalue);
+	FreePixmap(pvalue);
     }
     else if (type == CT_REGION)
     {
diff --git a/dix/glyphcurs.c b/dix/glyphcurs.c
index 40710ed..d9b641d 100644
--- a/dix/glyphcurs.c
+++ b/dix/glyphcurs.c
@@ -102,7 +102,7 @@ ServerBitsFromGlyph(FontPtr pfont, unsigned ch, CursorMetricPtr cm, unsigned cha
     if (!ppix || !pGC)
     {
 	if (ppix)
-	    (*pScreen->DestroyPixmap)(ppix);
+	    FreePixmap(ppix);
 	if (pGC)
 	    FreeScratchGC(pGC);
 	free(pbits);
@@ -132,7 +132,7 @@ ServerBitsFromGlyph(FontPtr pfont, unsigned ch, CursorMetricPtr cm, unsigned cha
 			 XYPixmap, 1, pbits);
     *ppbits = (unsigned char *)pbits;
     FreeScratchGC(pGC);
-    (*pScreen->DestroyPixmap)(ppix);
+    FreePixmap(ppix);
     return Success;
 }
 
diff --git a/dix/pixmap.c b/dix/pixmap.c
index cbb5e7f..a0f7a39 100644
--- a/dix/pixmap.c
+++ b/dix/pixmap.c
@@ -65,7 +65,7 @@ GetScratchPixmapHeader(ScreenPtr pScreen, int width, int height, int depth,
 	if ((*pScreen->ModifyPixmapHeader)(pPixmap, width, height, depth,
 					   bitsPerPixel, devKind, pPixData))
 	    return pPixmap;
-	(*pScreen->DestroyPixmap)(pPixmap);
+	FreePixmap(pPixmap);
     }
     return NullPixmap;
 }
@@ -81,7 +81,7 @@ FreeScratchPixmapHeader(PixmapPtr pPixmap)
 
 	pPixmap->devPrivate.ptr = NULL; /* lest ddx chases bad ptr */
 	if (pScreen->pScratchPixmap)
-	    (*pScreen->DestroyPixmap)(pPixmap);
+	    FreePixmap(pPixmap);
 	else
 	    pScreen->pScratchPixmap = pPixmap;
     }
@@ -132,6 +132,9 @@ AllocatePixmap(ScreenPtr pScreen, int pixDataSize)
 void
 FreePixmap(PixmapPtr pPixmap)
 {
+    if(--pPixmap->refcnt)
+	return;
+    (*pPixmap->drawable.pScreen->DestroyPixmap) (pPixmap);
     dixFiniPrivates(pPixmap, PRIVATE_PIXMAP);
     free(pPixmap);
 }
diff --git a/dix/window.c b/dix/window.c
index e2337e0..0af1f0c 100644
--- a/dix/window.c
+++ b/dix/window.c
@@ -826,9 +826,9 @@ FreeWindowResources(WindowPtr pWin)
     if (wInputShape (pWin))
 	RegionDestroy(wInputShape (pWin));
     if (pWin->borderIsPixel == FALSE)
-	(*pScreen->DestroyPixmap)(pWin->border.pixmap);
+	FreePixmap(pWin->border.pixmap);
     if (pWin->backgroundState == BackgroundPixmap)
-	(*pScreen->DestroyPixmap)(pWin->background.pixmap);
+	FreePixmap(pWin->background.pixmap);
 
     DeleteAllWindowProperties(pWin);
     /* We SHOULD check for an error value here XXX */
@@ -998,7 +998,7 @@ ChangeWindowAttributes(WindowPtr pWin, Mask vmask, XID *vlist, ClientPtr client)
 	    if (pixID == None)
 	    {
 		if (pWin->backgroundState == BackgroundPixmap)
-		    (*pScreen->DestroyPixmap)(pWin->background.pixmap);
+		    FreePixmap(pWin->background.pixmap);
 		if (!pWin->parent)
 		    MakeRootTile(pWin);
 		else {
@@ -1015,7 +1015,7 @@ ChangeWindowAttributes(WindowPtr pWin, Mask vmask, XID *vlist, ClientPtr client)
 		    goto PatchUp;
 		}
 		if (pWin->backgroundState == BackgroundPixmap)
-		    (*pScreen->DestroyPixmap)(pWin->background.pixmap);
+		    FreePixmap(pWin->background.pixmap);
 		if (!pWin->parent)
 		    MakeRootTile(pWin);
 		else
@@ -1037,7 +1037,7 @@ ChangeWindowAttributes(WindowPtr pWin, Mask vmask, XID *vlist, ClientPtr client)
 			goto PatchUp;
 		    }
 		    if (pWin->backgroundState == BackgroundPixmap)
-			(*pScreen->DestroyPixmap)(pWin->background.pixmap);
+			FreePixmap(pWin->background.pixmap);
 		    pWin->backgroundState = BackgroundPixmap;
 		    pWin->background.pixmap = pPixmap;
 		    pPixmap->refcnt++;
@@ -1054,7 +1054,7 @@ ChangeWindowAttributes(WindowPtr pWin, Mask vmask, XID *vlist, ClientPtr client)
 	    if (pWin->backgroundState == ParentRelative)
 		borderRelative = TRUE;
 	    if (pWin->backgroundState == BackgroundPixmap)
-		(*pScreen->DestroyPixmap)(pWin->background.pixmap);
+		FreePixmap(pWin->background.pixmap);
 	    pWin->backgroundState = BackgroundPixel;
 	    pWin->background.pixel = (CARD32 ) *pVlist;
 		   /* background pixel overrides background pixmap,
@@ -1075,7 +1075,7 @@ ChangeWindowAttributes(WindowPtr pWin, Mask vmask, XID *vlist, ClientPtr client)
 		}
 		if (pWin->parent->borderIsPixel == TRUE) {
 		    if (pWin->borderIsPixel == FALSE)
-			(*pScreen->DestroyPixmap)(pWin->border.pixmap);
+			FreePixmap(pWin->border.pixmap);
 		    pWin->border = pWin->parent->border;
 		    pWin->borderIsPixel = TRUE;
 		    index2 = CWBorderPixel;
@@ -1097,7 +1097,7 @@ ChangeWindowAttributes(WindowPtr pWin, Mask vmask, XID *vlist, ClientPtr client)
 		    goto PatchUp;
 		}
 		if (pWin->borderIsPixel == FALSE)
-		    (*pScreen->DestroyPixmap)(pWin->border.pixmap);
+		    FreePixmap(pWin->border.pixmap);
 		pWin->borderIsPixel = FALSE;
 		pWin->border.pixmap = pPixmap;
 		pPixmap->refcnt++;
@@ -1111,7 +1111,7 @@ ChangeWindowAttributes(WindowPtr pWin, Mask vmask, XID *vlist, ClientPtr client)
 	    break;
 	  case CWBorderPixel:
 	    if (pWin->borderIsPixel == FALSE)
-		(*pScreen->DestroyPixmap)(pWin->border.pixmap);
+		FreePixmap(pWin->border.pixmap);
 	    pWin->borderIsPixel = TRUE;
 	    pWin->border.pixel = (CARD32) *pVlist;
 		    /* border pixel overrides border pixmap,
diff --git a/doc/xml/Xserver-spec.xml b/doc/xml/Xserver-spec.xml
index 2a82e09..f52202e 100644
--- a/doc/xml/Xserver-spec.xml
+++ b/doc/xml/Xserver-spec.xml
@@ -3187,15 +3187,15 @@ See Xserver/fb/fbpixmap.c for the sample server implementation.</para>
 <para>
 <blockquote><programlisting>
 
-	Bool pScreen->DestroyPixmap(pPixmap)
+	void pScreen->DestroyPixmap(pPixmap)
 		PixmapPtr pPixmap;
 
 </programlisting></blockquote>
-This ScreenRec procedure must "destroy" a pixmap.
-It should decrement the reference count and, if zero, it
-must deallocate the PixmapRec and all attached devPrivate blocks.
-If successful, it returns TRUE.
-See Xserver/fb/fbpixmap.c for the sample server implementation.</para>
+This ScreenRec procedure must "destroy" a pixmap. It must clean up
+screen private data. It will only be called when the pixmap's reference
+count has dropped to zero, and after the screen hooks return the pixmap
+will be free'd. See Xserver/fb/fbpixmap.c for the sample server
+implementation.</para>
 <para>
 <blockquote><programlisting>
 
diff --git a/exa/exa_classic.c b/exa/exa_classic.c
index 169ce3a..028b617 100644
--- a/exa/exa_classic.c
+++ b/exa/exa_classic.c
@@ -98,7 +98,7 @@ exaCreatePixmap_classic(ScreenPtr pScreen, int w, int h, int depth,
 
     if (pExaPixmap->fb_pitch > 131071) {
 	swap(pExaScr, pScreen, DestroyPixmap);
-	pScreen->DestroyPixmap (pPixmap);
+	FreePixmap(pPixmap);
 	swap(pExaScr, pScreen, DestroyPixmap);
 	return NULL;
     }
@@ -110,7 +110,7 @@ exaCreatePixmap_classic(ScreenPtr pScreen, int w, int h, int depth,
 
     if (pExaPixmap->pDamage == NULL) {
 	swap(pExaScr, pScreen, DestroyPixmap);
-	pScreen->DestroyPixmap (pPixmap);
+	FreePixmap(pPixmap);
 	swap(pExaScr, pScreen, DestroyPixmap);
 	return NULL;
     }
@@ -210,40 +210,33 @@ exaModifyPixmapHeader_classic(PixmapPtr pPixmap, int width, int height, int dept
     return ret;
 }
 
-Bool
+void
 exaDestroyPixmap_classic (PixmapPtr pPixmap)
 {
     ScreenPtr	pScreen = pPixmap->drawable.pScreen;
     ExaScreenPriv(pScreen);
-    Bool ret;
+    ExaPixmapPriv(pPixmap);
+
+    exaDestroyPixmap(pPixmap);
 
-    if (pPixmap->refcnt == 1)
+    if (pExaPixmap->area)
     {
-	ExaPixmapPriv (pPixmap);
-
-	exaDestroyPixmap(pPixmap);
-
-	if (pExaPixmap->area)
-	{
-	    DBG_PIXMAP(("-- 0x%p (0x%x) (%dx%d)\n",
-                        (void*)pPixmap->drawable.id,
-			 ExaGetPixmapPriv(pPixmap)->area->offset,
-			 pPixmap->drawable.width,
-			 pPixmap->drawable.height));
-	    /* Free the offscreen area */
-	    exaOffscreenFree (pPixmap->drawable.pScreen, pExaPixmap->area);
-	    pPixmap->devPrivate.ptr = pExaPixmap->sys_ptr;
-	    pPixmap->devKind = pExaPixmap->sys_pitch;
-	}
-	RegionUninit(&pExaPixmap->validSys);
-	RegionUninit(&pExaPixmap->validFB);
+        DBG_PIXMAP(("-- 0x%p (0x%x) (%dx%d)\n",
+                    (void*)pPixmap->drawable.id,
+                     ExaGetPixmapPriv(pPixmap)->area->offset,
+                     pPixmap->drawable.width,
+                     pPixmap->drawable.height));
+        /* Free the offscreen area */
+        exaOffscreenFree (pPixmap->drawable.pScreen, pExaPixmap->area);
+        pPixmap->devPrivate.ptr = pExaPixmap->sys_ptr;
+        pPixmap->devKind = pExaPixmap->sys_pitch;
     }
+    RegionUninit(&pExaPixmap->validSys);
+    RegionUninit(&pExaPixmap->validFB);
 
     swap(pExaScr, pScreen, DestroyPixmap);
-    ret = pScreen->DestroyPixmap (pPixmap);
+    pScreen->DestroyPixmap (pPixmap);
     swap(pExaScr, pScreen, DestroyPixmap);
-
-    return ret;
 }
 
 Bool
diff --git a/exa/exa_driver.c b/exa/exa_driver.c
index a913cfb..92b9a53 100644
--- a/exa/exa_driver.c
+++ b/exa/exa_driver.c
@@ -96,7 +96,7 @@ exaCreatePixmap_driver(ScreenPtr pScreen, int w, int h, int depth,
 
     if (!pExaPixmap->driverPriv) {
 	swap(pExaScr, pScreen, DestroyPixmap);
-	pScreen->DestroyPixmap (pPixmap);
+	FreePixmap(pPixmap);
 	swap(pExaScr, pScreen, DestroyPixmap);
 	return NULL;
     }
@@ -182,29 +182,22 @@ out:
     return ret;
 }
 
-Bool
+void
 exaDestroyPixmap_driver (PixmapPtr pPixmap)
 {
     ScreenPtr	pScreen = pPixmap->drawable.pScreen;
     ExaScreenPriv(pScreen);
-    Bool ret;
+    ExaPixmapPriv(pPixmap);
 
-    if (pPixmap->refcnt == 1)
-    {
-	ExaPixmapPriv (pPixmap);
+    exaDestroyPixmap(pPixmap);
 
-	exaDestroyPixmap(pPixmap);
-
-	if (pExaPixmap->driverPriv)
-	    pExaScr->info->DestroyPixmap(pScreen, pExaPixmap->driverPriv);
-	pExaPixmap->driverPriv = NULL;
-    }
+    if (pExaPixmap->driverPriv)
+        pExaScr->info->DestroyPixmap(pScreen, pExaPixmap->driverPriv);
+    pExaPixmap->driverPriv = NULL;
 
     swap(pExaScr, pScreen, DestroyPixmap);
-    ret = pScreen->DestroyPixmap (pPixmap);
+    pScreen->DestroyPixmap (pPixmap);
     swap(pExaScr, pScreen, DestroyPixmap);
-
-    return ret;
 }
 
 Bool
diff --git a/exa/exa_glyphs.c b/exa/exa_glyphs.c
index 9ba70e3..6989d1d 100644
--- a/exa/exa_glyphs.c
+++ b/exa/exa_glyphs.c
@@ -194,7 +194,7 @@ exaRealizeGlyphCaches(ScreenPtr    pScreen,
 			     CPComponentAlpha, &component_alpha, serverClient,
 			     &error);
 
-    (*pScreen->DestroyPixmap) (pPixmap); /* picture holds a refcount */
+    FreePixmap(pPixmap); /* picture holds a refcount */
 
     if (!pPicture)
 	return FALSE;
@@ -749,7 +749,7 @@ exaGlyphs (CARD8 	 op,
 	{
 	    PictFormatPtr argbFormat;
 
-	    (*pScreen->DestroyPixmap) (pMaskPixmap);
+	    FreePixmap(pMaskPixmap);
 
 	    if (!pMask)
 		return;
@@ -772,7 +772,7 @@ exaGlyphs (CARD8 	 op,
 	    pMask = CreatePicture (0, &pMaskPixmap->drawable, maskFormat, 0, 0,
 				   serverClient, &error);
 	    if (!pMask) {
-		(*pScreen->DestroyPixmap) (pMaskPixmap);
+		FreePixmap(pMaskPixmap);
 		return;
 	    }
 	}
@@ -858,6 +858,6 @@ exaGlyphs (CARD8 	 op,
 			  x, y,
 			  width, height);
 	FreePicture ((pointer) pMask, (XID) 0);
-	(*pScreen->DestroyPixmap) (pMaskPixmap);
+	FreePixmap(pMaskPixmap);
     }
 }
diff --git a/exa/exa_mixed.c b/exa/exa_mixed.c
index ef20eb5..874fe3f 100644
--- a/exa/exa_mixed.c
+++ b/exa/exa_mixed.c
@@ -234,38 +234,31 @@ out:
     return ret;
 }
 
-Bool
+void
 exaDestroyPixmap_mixed(PixmapPtr pPixmap)
 {
     ScreenPtr	pScreen = pPixmap->drawable.pScreen;
     ExaScreenPriv(pScreen);
-    Bool ret;
-
-    if (pPixmap->refcnt == 1)
-    {
-	ExaPixmapPriv (pPixmap);
+    ExaPixmapPriv(pPixmap);
 
-	exaDestroyPixmap(pPixmap);
+    exaDestroyPixmap(pPixmap);
 
-	if (pExaScr->deferred_mixed_pixmap == pPixmap)
-	    pExaScr->deferred_mixed_pixmap = NULL;
+    if (pExaScr->deferred_mixed_pixmap == pPixmap)
+        pExaScr->deferred_mixed_pixmap = NULL;
 
-	if (pExaPixmap->driverPriv)
-	    pExaScr->info->DestroyPixmap(pScreen, pExaPixmap->driverPriv);
-	pExaPixmap->driverPriv = NULL;
+    if (pExaPixmap->driverPriv)
+        pExaScr->info->DestroyPixmap(pScreen, pExaPixmap->driverPriv);
+    pExaPixmap->driverPriv = NULL;
 
-	if (pExaPixmap->pDamage) {
-	    free(pExaPixmap->sys_ptr);
-	    pExaPixmap->sys_ptr = NULL;
-	    pExaPixmap->pDamage = NULL;
-	}
+    if (pExaPixmap->pDamage) {
+        free(pExaPixmap->sys_ptr);
+        pExaPixmap->sys_ptr = NULL;
+        pExaPixmap->pDamage = NULL;
     }
 
     swap(pExaScr, pScreen, DestroyPixmap);
-    ret = pScreen->DestroyPixmap (pPixmap);
+    pScreen->DestroyPixmap (pPixmap);
     swap(pExaScr, pScreen, DestroyPixmap);
-
-    return ret;
 }
 
 Bool
diff --git a/exa/exa_offscreen.c b/exa/exa_offscreen.c
index 5abe3b8..a65eca1 100644
--- a/exa/exa_offscreen.c
+++ b/exa/exa_offscreen.c
@@ -632,7 +632,7 @@ ExaOffscreenDefragment (ScreenPtr pScreen)
     pDstPix->drawable.depth = 0;
     pDstPix->drawable.bitsPerPixel = 0;
 
-    (*pScreen->DestroyPixmap) (pDstPix);
+    FreePixmap(pDstPix);
 
     if (area->state == ExaOffscreenAvail && area->size > largest_size)
 	return area;
diff --git a/exa/exa_priv.h b/exa/exa_priv.h
index 5f736cd..b4a90f2 100644
--- a/exa/exa_priv.h
+++ b/exa/exa_priv.h
@@ -583,7 +583,7 @@ Bool
 exaModifyPixmapHeader_classic(PixmapPtr pPixmap, int width, int height, int depth,
 		      int bitsPerPixel, int devKind, pointer pPixData);
 
-Bool
+void
 exaDestroyPixmap_classic (PixmapPtr pPixmap);
 
 Bool
@@ -598,7 +598,7 @@ Bool
 exaModifyPixmapHeader_driver(PixmapPtr pPixmap, int width, int height, int depth,
 		      int bitsPerPixel, int devKind, pointer pPixData);
 
-Bool
+void
 exaDestroyPixmap_driver (PixmapPtr pPixmap);
 
 Bool
@@ -613,7 +613,7 @@ Bool
 exaModifyPixmapHeader_mixed(PixmapPtr pPixmap, int width, int height, int depth,
 		      int bitsPerPixel, int devKind, pointer pPixData);
 
-Bool
+void
 exaDestroyPixmap_mixed(PixmapPtr pPixmap);
 
 Bool
diff --git a/exa/exa_render.c b/exa/exa_render.c
index 6f2af8a..6251362 100644
--- a/exa/exa_render.c
+++ b/exa/exa_render.c
@@ -1112,7 +1112,7 @@ exaCreateAlphaPicture (ScreenPtr     pScreen,
     pGC = GetScratchGC (pPixmap->drawable.depth, pScreen);
     if (!pGC)
     {
-	(*pScreen->DestroyPixmap) (pPixmap);
+	FreePixmap(pPixmap);
 	return 0;
     }
     ValidateGC (&pPixmap->drawable, pGC);
@@ -1125,7 +1125,7 @@ exaCreateAlphaPicture (ScreenPtr     pScreen,
     FreeScratchGC (pGC);
     pPicture = CreatePicture (0, &pPixmap->drawable, pPictFormat,
 			      0, 0, serverClient, &error);
-    (*pScreen->DestroyPixmap) (pPixmap);
+    FreePixmap(pPixmap);
     return pPicture;
 }
 
diff --git a/fb/fb.h b/fb/fb.h
index c290ebf..bba998b 100644
--- a/fb/fb.h
+++ b/fb/fb.h
@@ -1631,7 +1631,7 @@ extern _X_EXPORT PixmapPtr
 fbCreatePixmap (ScreenPtr pScreen, int width, int height, int depth,
 		unsigned usage_hint);
 
-extern _X_EXPORT Bool
+extern _X_EXPORT void
 fbDestroyPixmap (PixmapPtr pPixmap);
 
 extern _X_EXPORT RegionPtr
diff --git a/fb/fbgc.c b/fb/fbgc.c
index 26f7eee..93270da 100644
--- a/fb/fbgc.c
+++ b/fb/fbgc.c
@@ -206,7 +206,7 @@ fbValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable)
     }
     if ((changes & GCTile) && fbGetRotatedPixmap(pGC))
     {
-	(*pGC->pScreen->DestroyPixmap) (fbGetRotatedPixmap(pGC));
+	FreePixmap(fbGetRotatedPixmap(pGC));
 	fbGetRotatedPixmap(pGC) = 0;
     }
 	
@@ -221,7 +221,7 @@ fbValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable)
 	    if (!pNewTile || pNewTile ->drawable.bitsPerPixel != pDrawable->bitsPerPixel)
 	    {
 		if (pNewTile)
-		    (*pGC->pScreen->DestroyPixmap) (pNewTile);
+		    FreePixmap(pNewTile);
 		pNewTile = fb24_32ReformatTile (pOldTile, pDrawable->bitsPerPixel);
 	    }
 	    if (pNewTile)
diff --git a/fb/fboverlay.c b/fb/fboverlay.c
index 7fca89c..309a2d2 100644
--- a/fb/fboverlay.c
+++ b/fb/fboverlay.c
@@ -91,7 +91,7 @@ fbOverlayCloseScreen (int iScreen, ScreenPtr pScreen)
 
     for (i = 0; i < pScrPriv->nlayers; i++)
     {
-	(*pScreen->DestroyPixmap)(pScrPriv->layer[i].u.run.pixmap);
+	FreePixmap(pScrPriv->layer[i].u.run.pixmap);
 	RegionUninit(&pScrPriv->layer[i].u.run.region);
     }
     return TRUE;
diff --git a/fb/fbpixmap.c b/fb/fbpixmap.c
index 41b12ce..0a3b76a 100644
--- a/fb/fbpixmap.c
+++ b/fb/fbpixmap.c
@@ -96,13 +96,9 @@ fbCreatePixmap (ScreenPtr pScreen, int width, int height, int depth,
     return fbCreatePixmapBpp (pScreen, width, height, depth, bpp, usage_hint);
 }
 
-Bool
+void
 fbDestroyPixmap (PixmapPtr pPixmap)
 {
-    if(--pPixmap->refcnt)
-	return TRUE;
-    FreePixmap(pPixmap);
-    return TRUE;
 }
 
 #define ADDRECT(reg,r,fr,rx1,ry1,rx2,ry2)			\
diff --git a/fb/fbwindow.c b/fb/fbwindow.c
index bb0384d..8f79ec7 100644
--- a/fb/fbwindow.c
+++ b/fb/fbwindow.c
@@ -165,7 +165,7 @@ fbChangeWindowAttributes(WindowPtr pWin, unsigned long mask)
 					       pWin->drawable.bitsPerPixel);
 		if (pPixmap)
 		{
-		    (*pWin->drawable.pScreen->DestroyPixmap) (pWin->background.pixmap);
+		    FreePixmap(pWin->background.pixmap);
 		    pWin->background.pixmap = pPixmap;
 		}
 	    }
@@ -188,7 +188,7 @@ fbChangeWindowAttributes(WindowPtr pWin, unsigned long mask)
 					       pWin->drawable.bitsPerPixel);
 		if (pPixmap)
 		{
-		    (*pWin->drawable.pScreen->DestroyPixmap) (pWin->border.pixmap);
+		    FreePixmap(pWin->border.pixmap);
 		    pWin->border.pixmap = pPixmap;
 		}
 	    }
diff --git a/hw/dmx/dmxpixmap.c b/hw/dmx/dmxpixmap.c
index 81b7115..19f3ac7 100644
--- a/hw/dmx/dmxpixmap.c
+++ b/hw/dmx/dmxpixmap.c
@@ -151,19 +151,15 @@ Bool dmxBEFreePixmap(PixmapPtr pPixmap)
 }
 
 /** Destroy the pixmap pointed to by \a pPixmap. */
-Bool dmxDestroyPixmap(PixmapPtr pPixmap)
+void dmxDestroyPixmap(PixmapPtr pPixmap)
 {
     ScreenPtr      pScreen = pPixmap->drawable.pScreen;
     DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
-    Bool           ret = TRUE;
 
 #if 0
     DMX_UNWRAP(DestroyPixmap, dmxScreen, pScreen);
 #endif
 
-    if (--pPixmap->refcnt)
-	return TRUE;
-
     /* Destroy pixmap on back-end server */
     if (dmxScreen->beDisplay) {
 	if (dmxBEFreePixmap(pPixmap)) {
@@ -174,15 +170,12 @@ Bool dmxDestroyPixmap(PixmapPtr pPixmap)
 	    dmxSync(dmxScreen, FALSE);
 	}
     }
-    FreePixmap(pPixmap);
 
 #if 0
     if (pScreen->DestroyPixmap)
-	ret = pScreen->DestroyPixmap(pPixmap);
+	pScreen->DestroyPixmap(pPixmap);
     DMX_WRAP(DestroyPixmap, dmxDestroyPixmap, dmxScreen, pScreen);
 #endif
-
-    return ret;
 }
 
 /** Create and return a region based on the pixmap pointed to by \a
diff --git a/hw/dmx/dmxpixmap.h b/hw/dmx/dmxpixmap.h
index 59da788..0bb19c3 100644
--- a/hw/dmx/dmxpixmap.h
+++ b/hw/dmx/dmxpixmap.h
@@ -51,7 +51,7 @@ extern Bool      dmxInitPixmap(ScreenPtr pScreen);
 extern PixmapPtr dmxCreatePixmap(ScreenPtr pScreen,
 				 int width, int height, int depth,
 				 unsigned usage_hint);
-extern Bool      dmxDestroyPixmap(PixmapPtr pPixmap);
+extern void      dmxDestroyPixmap(PixmapPtr pPixmap);
 extern RegionPtr dmxBitmapToRegion(PixmapPtr pPixmap);
 
 extern void      dmxBECreatePixmap(PixmapPtr pPixmap);
diff --git a/hw/dmx/glxProxy/glxext.c b/hw/dmx/glxProxy/glxext.c
index a8fc0a8..122d137 100644
--- a/hw/dmx/glxProxy/glxext.c
+++ b/hw/dmx/glxProxy/glxext.c
@@ -163,10 +163,10 @@ void __glXFreeGLXPixmap( __GLXpixmap *pGlxPixmap )
        PixmapPtr pPixmap = (PixmapPtr) pGlxPixmap->pDraw;
 
 	/*
-	** The DestroyPixmap routine should decrement the refcount and free
+	** The FreePixmap routine decrements the refcount and frees
 	** only if it's zero.
 	*/
-	(*pGlxPixmap->pScreen->DestroyPixmap)(pPixmap);
+	FreePixmap(pPixmap);
 	free(pGlxPixmap->be_xids);
 	free(pGlxPixmap);
     }
diff --git a/hw/xfree86/common/xf86DGA.c b/hw/xfree86/common/xf86DGA.c
index c468c60..bc80366 100644
--- a/hw/xfree86/common/xf86DGA.c
+++ b/hw/xfree86/common/xf86DGA.c
@@ -362,7 +362,7 @@ xf86SetDGAMode(
 		if(oldPix->drawable.id)
 		    FreeResource(oldPix->drawable.id, RT_NONE);
 		else
-		    (*pScreen->DestroyPixmap)(oldPix);
+		    FreePixmap(oldPix);
 	    }
 	    free(pScreenPriv->current);
 	    pScreenPriv->current = NULL;
@@ -423,7 +423,7 @@ xf86SetDGAMode(
 	    if(oldPix->drawable.id)
 		FreeResource(oldPix->drawable.id, RT_NONE);
 	    else
-		(*pScreen->DestroyPixmap)(oldPix);
+		FreePixmap(oldPix);
 	}
 	free(pScreenPriv->current);
 	pScreenPriv->current = NULL;
diff --git a/hw/xfree86/xaa/xaaInit.c b/hw/xfree86/xaa/xaaInit.c
index 2cd7edb..f535670 100644
--- a/hw/xfree86/xaa/xaaInit.c
+++ b/hw/xfree86/xaa/xaaInit.c
@@ -35,7 +35,7 @@ static void XAAGetSpans(DrawablePtr pDrawable, int wMax, DDXPointPtr ppt,
 			int *pwidth, int nspans, char *pdstStart);
 static PixmapPtr XAACreatePixmap(ScreenPtr pScreen, int w, int h, int depth,
 				 unsigned usage_hint);
-static Bool XAADestroyPixmap(PixmapPtr pPixmap);
+static void XAADestroyPixmap(PixmapPtr pPixmap);
 static Bool XAAEnterVT (int index, int flags);
 static void XAALeaveVT (int index, int flags);
 static int  XAASetDGAMode(int index, int num, DGADevicePtr devRet);
@@ -310,7 +310,7 @@ XAAPixmapBPP (ScreenPtr pScreen, int depth)
     bpp = pPix->drawable.bitsPerPixel;
     destroyPixmap = pScreen->DestroyPixmap;
     XAA_SCREEN_PROLOGUE (pScreen, DestroyPixmap);
-    (*pScreen->DestroyPixmap) (pPix);
+    FreePixmap(pPix);
     XAA_SCREEN_EPILOGUE (pScreen, DestroyPixmap, destroyPixmap);
     return bpp;
 }
@@ -429,50 +429,45 @@ BAILOUT:
     return pPix;
 }
 
-static Bool 
+static void
 XAADestroyPixmap(PixmapPtr pPix)
 {
     ScreenPtr pScreen = pPix->drawable.pScreen;
     XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
     XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pPix);
-    Bool ret;
 
-    if(pPix->refcnt == 1) {
-        if(pPriv->flags & OFFSCREEN) {
-	    if(pPriv->flags & DGA_PIXMAP)
-	        free(pPriv->offscreenArea);
-            else {
-	        FBAreaPtr area = pPriv->offscreenArea;
-		PixmapLinkPtr pLink = infoRec->OffscreenPixmaps;
-	        PixmapLinkPtr prev = NULL;
-
-		while(pLink->pPix != pPix) {
-		    prev = pLink;
-		    pLink = pLink->next;
-		}
-
-	        if(prev) prev->next = pLink->next;
-		else infoRec->OffscreenPixmaps = pLink->next;
-
-	        if(!area) area = pLink->area;
-
-	        xf86FreeOffscreenArea(area);
-	        pPriv->offscreenArea = NULL;
-	        free(pLink);
-	    } 
+    if(pPriv->flags & OFFSCREEN) {
+        if(pPriv->flags & DGA_PIXMAP)
+            free(pPriv->offscreenArea);
+        else {
+            FBAreaPtr area = pPriv->offscreenArea;
+            PixmapLinkPtr pLink = infoRec->OffscreenPixmaps;
+            PixmapLinkPtr prev = NULL;
+
+            while(pLink->pPix != pPix) {
+                prev = pLink;
+                pLink = pLink->next;
+            }
+
+            if(prev) prev->next = pLink->next;
+            else infoRec->OffscreenPixmaps = pLink->next;
+
+            if(!area) area = pLink->area;
+
+            xf86FreeOffscreenArea(area);
+            pPriv->offscreenArea = NULL;
+            free(pLink);
         }
+    }
 
-        if(pPriv->freeData) { /* pixmaps that were once in video ram */
-	    free(pPix->devPrivate.ptr);
-	    pPix->devPrivate.ptr = NULL;
-	}
+    if(pPriv->freeData) { /* pixmaps that were once in video ram */
+        free(pPix->devPrivate.ptr);
+        pPix->devPrivate.ptr = NULL;
     }
     
     XAA_SCREEN_PROLOGUE (pScreen, DestroyPixmap);
-    ret = (*pScreen->DestroyPixmap) (pPix);
+    (*pScreen->DestroyPixmap) (pPix);
     XAA_SCREEN_EPILOGUE (pScreen, DestroyPixmap, XAADestroyPixmap);
- 
-    return ret;
 }
 
 static Bool
diff --git a/hw/xnest/Pixmap.c b/hw/xnest/Pixmap.c
index 3a92ffd..b99e97d 100644
--- a/hw/xnest/Pixmap.c
+++ b/hw/xnest/Pixmap.c
@@ -69,14 +69,10 @@ xnestCreatePixmap(ScreenPtr pScreen, int width, int height, int depth,
   return pPixmap;
 }
 
-Bool
+void
 xnestDestroyPixmap(PixmapPtr pPixmap)
 {
-  if(--pPixmap->refcnt)
-    return TRUE;
   XFreePixmap(xnestDisplay, xnestPixmap(pPixmap));
-  FreePixmap(pPixmap);
-  return TRUE;
 }
 
 RegionPtr
diff --git a/hw/xnest/XNPixmap.h b/hw/xnest/XNPixmap.h
index aa671ed..5816cef 100644
--- a/hw/xnest/XNPixmap.h
+++ b/hw/xnest/XNPixmap.h
@@ -31,7 +31,7 @@ typedef struct {
 
 PixmapPtr xnestCreatePixmap(ScreenPtr pScreen, int width, int height,
 			    int depth, unsigned usage_hint);
-Bool xnestDestroyPixmap(PixmapPtr pPixmap);
+void xnestDestroyPixmap(PixmapPtr pPixmap);
 RegionPtr xnestPixmapToRegion(PixmapPtr pPixmap);
 
 #endif /* XNESTPIXMAP_H */
diff --git a/include/scrnintstr.h b/include/scrnintstr.h
index 8e0318d..ade7c37 100644
--- a/include/scrnintstr.h
+++ b/include/scrnintstr.h
@@ -210,7 +210,7 @@ typedef    PixmapPtr (* CreatePixmapProcPtr)(
 	int /*depth*/,
 	unsigned /*usage_hint*/);
 
-typedef    Bool (* DestroyPixmapProcPtr)(
+typedef    void (* DestroyPixmapProcPtr)(
 	PixmapPtr /*pPixmap*/);
 
 typedef    void (* SaveDoomedAreasProcPtr)(
diff --git a/mi/miarc.c b/mi/miarc.c
index 2f5497e..ed6f1e0 100644
--- a/mi/miarc.c
+++ b/mi/miarc.c
@@ -1073,7 +1073,7 @@ miPolyArc(DrawablePtr pDraw, GCPtr pGC, int narcs, xArc *parcs)
 	if (!polyArcs)
 	{
 	    if (fTricky) {
-		(*pDraw->pScreen->DestroyPixmap) ((PixmapPtr)pDrawTo);
+		FreePixmap ((PixmapPtr)pDrawTo);
 		FreeScratchGC (pGCTo);
 	    }
 	    return;
@@ -1164,7 +1164,7 @@ miPolyArc(DrawablePtr pDraw, GCPtr pGC, int narcs, xArc *parcs)
 
 	if(fTricky)
 	{
-	    (*pGCTo->pScreen->DestroyPixmap)((PixmapPtr)pDrawTo);
+	    FreePixmap((PixmapPtr)pDrawTo);
 	    FreeScratchGC(pGCTo);
 	}
     }
diff --git a/mi/mibitblt.c b/mi/mibitblt.c
index b93f339..69af6f4 100644
--- a/mi/mibitblt.c
+++ b/mi/mibitblt.c
@@ -418,7 +418,7 @@ miOpqStipDrawable(DrawablePtr pDraw, GCPtr pGC, RegionPtr prgnSrc,
     pGCT = GetScratchGC(1, pDraw->pScreen);
     if (!pGCT)
     {
-	(*pDraw->pScreen->DestroyPixmap)(pPixmap);
+	FreePixmap(pPixmap);
 	return;
     }
     /* First set the whole pixmap to 0 */
@@ -528,7 +528,7 @@ miOpqStipDrawable(DrawablePtr pDraw, GCPtr pGC, RegionPtr prgnSrc,
 
     ValidateGC(pDraw, pGC);
     FreeScratchGC(pGCT);
-    (*pDraw->pScreen->DestroyPixmap)(pPixmap);
+    FreePixmap(pPixmap);
 
 }
 
@@ -700,7 +700,7 @@ miGetImage( DrawablePtr pDraw, int sx, int sy, int w, int h,
 	}
 	if (pPixmap)
 	{
-	    (*pGC->pScreen->DestroyPixmap)(pPixmap);
+	    FreePixmap(pPixmap);
 	    FreeScratchGC(pGC);
 	}
     }
diff --git a/mi/midispcur.c b/mi/midispcur.c
index c47486c..6c2e051 100644
--- a/mi/midispcur.c
+++ b/mi/midispcur.c
@@ -225,7 +225,7 @@ miDCRealize (ScreenPtr pScreen, CursorPtr pCursor)
 	pGC = GetScratchGC (32, pScreen);
 	if (!pGC)
 	{
-	    (*pScreen->DestroyPixmap) (pPixmap);
+	    FreePixmap(pPixmap);
 	    free((pointer) pPriv);
 	    return NULL;
 	}
@@ -237,7 +237,7 @@ miDCRealize (ScreenPtr pScreen, CursorPtr pCursor)
 	FreeScratchGC (pGC);
 	pPriv->pPicture = CreatePicture (0, &pPixmap->drawable,
 					pFormat, 0, 0, serverClient, &error);
-        (*pScreen->DestroyPixmap) (pPixmap);
+        FreePixmap(pPixmap);
 	if (!pPriv->pPicture)
 	{
 	    free((pointer) pPriv);
@@ -257,7 +257,7 @@ miDCRealize (ScreenPtr pScreen, CursorPtr pCursor)
     pPriv->maskBits =  (*pScreen->CreatePixmap) (pScreen, pCursor->bits->width, pCursor->bits->height, 1, 0);
     if (!pPriv->maskBits)
     {
-	(*pScreen->DestroyPixmap) (pPriv->sourceBits);
+	FreePixmap(pPriv->sourceBits);
 	free((pointer) pPriv);
 	return NULL;
     }
@@ -310,9 +310,9 @@ miDCUnrealizeCursor (ScreenPtr pScreen, CursorPtr pCursor)
     if (pPriv && (pCursor->bits->refcnt <= 1))
     {
 	if (pPriv->sourceBits)
-	    (*pScreen->DestroyPixmap) (pPriv->sourceBits);
+	    FreePixmap(pPriv->sourceBits);
 	if (pPriv->maskBits)
-	    (*pScreen->DestroyPixmap) (pPriv->maskBits);
+	    FreePixmap(pPriv->maskBits);
 #ifdef ARGB_CURSOR
 	if (pPriv->pPicture)
 	    FreePicture (pPriv->pPicture, 0);
@@ -463,7 +463,7 @@ miDCSaveUnderCursor (DeviceIntPtr pDev, ScreenPtr pScreen,
     if (!pSave || pSave->drawable.width < w || pSave->drawable.height < h)
     {
 	if (pSave)
-	    (*pScreen->DestroyPixmap) (pSave);
+	    FreePixmap(pSave);
 	pBuffer->pSave = pSave =
 		(*pScreen->CreatePixmap) (pScreen, w, h, pScreen->rootDepth, 0);
 	if (!pSave)
@@ -586,7 +586,7 @@ miDCDeviceCleanup(DeviceIntPtr pDev, ScreenPtr pScreen)
                  * free it again here. */
 #endif
 
-                if (pBuffer->pSave) (*pScreen->DestroyPixmap)(pBuffer->pSave);
+                if (pBuffer->pSave) FreePixmap(pBuffer->pSave);
 
                 free(pBuffer);
                 dixSetPrivate(&pDev->devPrivates, miDCDeviceKey(pScreen), NULL);
diff --git a/mi/migc.c b/mi/migc.c
index bf9cf5a..f83208a 100644
--- a/mi/migc.c
+++ b/mi/migc.c
@@ -48,7 +48,7 @@ void
 miDestroyGC(GCPtr pGC)
 {
     if (pGC->pRotatedPixmap)
-	(*pGC->pScreen->DestroyPixmap) (pGC->pRotatedPixmap);
+	FreePixmap(pGC->pRotatedPixmap);
     if (pGC->freeCompClip)
 	RegionDestroy(pGC->pCompositeClip);
 }
diff --git a/mi/miglblt.c b/mi/miglblt.c
index 9247f37..118f4ff 100644
--- a/mi/miglblt.c
+++ b/mi/miglblt.c
@@ -130,7 +130,7 @@ miPolyGlyphBlt(
     pGCtmp = GetScratchGC(1, pDrawable->pScreen);
     if (!pGCtmp)
     {
-	(*pDrawable->pScreen->DestroyPixmap)(pPixmap);
+	FreePixmap(pPixmap);
 	return;
     }
 
@@ -144,7 +144,7 @@ miPolyGlyphBlt(
     pbits = malloc(height*nbyLine);
     if (!pbits)
     {
-	(*pDrawable->pScreen->DestroyPixmap)(pPixmap);
+	FreePixmap(pPixmap);
 	FreeScratchGC(pGCtmp);
         return;
     }
@@ -189,7 +189,7 @@ miPolyGlyphBlt(
 	}
 	x += pci->metrics.characterWidth;
     }
-    (*pDrawable->pScreen->DestroyPixmap)(pPixmap);
+    FreePixmap(pPixmap);
     free(pbits);
     FreeScratchGC(pGCtmp);
 }
diff --git a/mi/miscrinit.c b/mi/miscrinit.c
index 661ecb2..a2392b7 100644
--- a/mi/miscrinit.c
+++ b/mi/miscrinit.c
@@ -122,7 +122,8 @@ miModifyPixmapHeader(PixmapPtr pPixmap, int width, int height, int depth,
 static Bool
 miCloseScreen (int iScreen, ScreenPtr pScreen)
 {
-    return ((*pScreen->DestroyPixmap)((PixmapPtr)pScreen->devPrivate));
+    FreePixmap(pScreen->devPrivate);
+    return TRUE;
 }
 
 /* With the introduction of pixmap privates, the "screen pixmap" can no
diff --git a/miext/damage/damage.c b/miext/damage/damage.c
index 18c1b45..890a138 100644
--- a/miext/damage/damage.c
+++ b/miext/damage/damage.c
@@ -1584,28 +1584,24 @@ damageInsertDamage (DamagePtr *pPrev, DamagePtr pDamage)
     *pPrev = pDamage;
 }
 
-static Bool
+static void
 damageDestroyPixmap (PixmapPtr pPixmap)
 {
     ScreenPtr	pScreen = pPixmap->drawable.pScreen;
     damageScrPriv(pScreen);
+    DamagePtr	*pPrev = getPixmapDamageRef (pPixmap);
+    DamagePtr	pDamage;
 
-    if (pPixmap->refcnt == 1)
+    while ((pDamage = *pPrev))
     {
-	DamagePtr	*pPrev = getPixmapDamageRef (pPixmap);
-	DamagePtr	pDamage;
-
-	while ((pDamage = *pPrev))
-	{
-	    damageRemoveDamage (pPrev, pDamage);
-	    if (!pDamage->isWindow)
-		DamageDestroy (pDamage);
-	}
+        damageRemoveDamage (pPrev, pDamage);
+        if (!pDamage->isWindow)
+            DamageDestroy (pDamage);
     }
+
     unwrap (pScrPriv, pScreen, DestroyPixmap);
     (*pScreen->DestroyPixmap) (pPixmap);
     wrap (pScrPriv, pScreen, DestroyPixmap, damageDestroyPixmap);
-    return TRUE;
 }
 
 static void
diff --git a/miext/shadow/shadow.c b/miext/shadow/shadow.c
index cb1b299..9303f97 100644
--- a/miext/shadow/shadow.c
+++ b/miext/shadow/shadow.c
@@ -106,7 +106,7 @@ shadowCloseScreen(int i, ScreenPtr pScreen)
     RegionUninit(&pBuf->damage); /* bc */
 #endif
     if (pBuf->pPixmap)
-	pScreen->DestroyPixmap(pBuf->pPixmap);
+	FreePixmap(pBuf->pPixmap);
     free(pBuf);
     return pScreen->CloseScreen(i, pScreen);
 }
@@ -242,7 +242,7 @@ shadowInit(ScreenPtr pScreen, ShadowUpdateProc update, ShadowWindowProc window)
 	return FALSE;
     
     if (!shadowSetup(pScreen)) {
-	pScreen->DestroyPixmap(pPixmap);
+	FreePixmap(pPixmap);
 	return FALSE;
     }
 
diff --git a/render/glyph.c b/render/glyph.c
index 98d97e3..9439543 100644
--- a/render/glyph.c
+++ b/render/glyph.c
@@ -663,7 +663,7 @@ miGlyphs (CARD8		op,
 			       serverClient, &error);
 	if (!pMask)
 	{
-	    (*pScreen->DestroyPixmap) (pMaskPixmap);
+	    FreePixmap(pMaskPixmap);
 	    return;
 	}
 	pGC = GetScratchGC (pMaskPixmap->drawable.depth, pScreen);
@@ -743,6 +743,6 @@ miGlyphs (CARD8		op,
 			  x, y,
 			  width, height);
 	FreePicture ((pointer) pMask, (XID) 0);
-	(*pScreen->DestroyPixmap) (pMaskPixmap);
+	FreePixmap(pMaskPixmap);
     }
 }
diff --git a/render/mipict.c b/render/mipict.c
index b5b8970..29e5d8a 100644
--- a/render/mipict.c
+++ b/render/mipict.c
@@ -57,7 +57,7 @@ miDestroyPictureClip (PicturePtr pPicture)
     case CT_NONE:
 	return;
     case CT_PIXMAP:
-	(*pPicture->pDrawable->pScreen->DestroyPixmap) ((PixmapPtr) (pPicture->clientClip));
+	FreePixmap((PixmapPtr) (pPicture->clientClip));
 	break;
     default:
 	/*
@@ -89,7 +89,7 @@ miChangePictureClip (PicturePtr    pPicture,
 	if (!clientClip)
 	    return BadAlloc;
 	clientClipType = CT_REGION;
-	(*pScreen->DestroyPixmap) ((PixmapPtr) value);
+	FreePixmap(value);
 	break;
     case CT_REGION:
 	clientClip = value;
diff --git a/render/mirect.c b/render/mirect.c
index ad5a65b..6f74a76 100644
--- a/render/mirect.c
+++ b/render/mirect.c
@@ -177,7 +177,7 @@ miCompositeRects (CARD8		op,
 bail4:
 	FreeScratchGC (pGC);
 bail3:
-	(*pScreen->DestroyPixmap) (pPixmap);
+	FreePixmap(pPixmap);
 bail2:
 bail1:
 	;
diff --git a/render/mitrap.c b/render/mitrap.c
index 3ef5e11..df1df01 100644
--- a/render/mitrap.c
+++ b/render/mitrap.c
@@ -67,7 +67,7 @@ miCreateAlphaPicture (ScreenPtr	    pScreen,
     pGC = GetScratchGC (pPixmap->drawable.depth, pScreen);
     if (!pGC)
     {
-	(*pScreen->DestroyPixmap) (pPixmap);
+	FreePixmap(pPixmap);
 	return 0;
     }
     ValidateGC (&pPixmap->drawable, pGC);
@@ -79,7 +79,7 @@ miCreateAlphaPicture (ScreenPtr	    pScreen,
     FreeScratchGC (pGC);
     pPicture = CreatePicture (0, &pPixmap->drawable, pPictFormat,
 			      0, 0, serverClient, &error);
-    (*pScreen->DestroyPixmap) (pPixmap);
+    FreePixmap(pPixmap);
     return pPicture;
 }
 
diff --git a/render/picture.c b/render/picture.c
index 7fda6b9..beb1c80 100644
--- a/render/picture.c
+++ b/render/picture.c
@@ -1562,7 +1562,7 @@ FreePicture (pointer	value,
             }
             else if (pPicture->pDrawable->type == DRAWABLE_PIXMAP)
             {
-                (*pScreen->DestroyPixmap) ((PixmapPtr)pPicture->pDrawable);
+                FreePixmap((PixmapPtr)pPicture->pDrawable);
             }
         }
 	dixFreeObjectWithPrivates(pPicture, PRIVATE_PICTURE);
diff --git a/render/render.c b/render/render.c
index 051e82a..67854b0 100644
--- a/render/render.c
+++ b/render/render.c
@@ -1173,7 +1173,7 @@ ProcRenderAddGlyphs (ClientPtr client)
 
 		/* The picture takes a reference to the pixmap, so we
 		   drop ours. */
-		(pScreen->DestroyPixmap) (pDstPix);
+		FreePixmap(pDstPix);
 		pDstPix = NULL;
 
 		if (! pDst)
@@ -1598,7 +1598,7 @@ ProcRenderCreateCursor (ClientPtr client)
 	    free(mskbits);
 	    return error;
 	}
-	(*pScreen->DestroyPixmap) (pPixmap);
+	FreePixmap(pPixmap);
 	CompositePicture (PictOpSrc,
 			  pSrc, 0, pPicture,
 			  0, 0, 0, 0, 0, 0, width, height);
-- 
1.7.0



More information about the xorg-devel mailing list