[Intel-gfx] [PATCH] uxa: handle uxa_prepare_access failure

Keith Packard keithp at keithp.com
Tue Dec 16 00:57:40 CET 2008


uxa_prepare_access may fail to map the pixmap into user space. Recover from
this without crashing.

Signed-off-by: Keith Packard <keithp at keithp.com>
---
 uxa/uxa-accel.c   |   30 ++++---
 uxa/uxa-priv.h    |    6 +-
 uxa/uxa-render.c  |   37 +++++----
 uxa/uxa-unaccel.c |  236 +++++++++++++++++++++++++++++++----------------------
 uxa/uxa.c         |   47 +++++++----
 5 files changed, 208 insertions(+), 148 deletions(-)

diff --git a/uxa/uxa-accel.c b/uxa/uxa-accel.c
index b25a8fa..f42e0e2 100644
--- a/uxa/uxa-accel.c
+++ b/uxa/uxa-accel.c
@@ -188,7 +188,8 @@ uxa_do_put_image (DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y,
 	    int	dstXoff, dstYoff;
 
 	    if (!access_prepared) {
-		uxa_prepare_access(pDrawable, UXA_ACCESS_RW);
+		if (!uxa_prepare_access(pDrawable, UXA_ACCESS_RW))
+		    return FALSE;
 		access_prepared = TRUE;
 	    }
 
@@ -237,7 +238,8 @@ uxa_do_shm_put_image(DrawablePtr pDrawable, GCPtr pGC, int depth,
 	if (!pPixmap)
 	    return FALSE;
 
-        uxa_prepare_access (pDrawable, UXA_ACCESS_RW);
+        if (!uxa_prepare_access (pDrawable, UXA_ACCESS_RW))
+	    return FALSE;
 	fbCopyArea((DrawablePtr)pPixmap, pDrawable, pGC, sx, sy, sw, sh, dx, dy);
 	uxa_finish_access(pDrawable);
 
@@ -262,7 +264,8 @@ uxa_shm_put_image(DrawablePtr pDrawable, GCPtr pGC, int depth, unsigned int form
 {
     if (!uxa_do_shm_put_image(pDrawable, pGC, depth, format, w, h, sx, sy, sw, sh,
 			      dx, dy, data)) {
-	uxa_prepare_access (pDrawable, UXA_ACCESS_RW);
+	if (!uxa_prepare_access (pDrawable, UXA_ACCESS_RW))
+	    return;
 	fbShmPutImage(pDrawable, pGC, depth, format, w, h, sx, sy, sw, sh, dx, dy,
 		      data);
 	uxa_finish_access(pDrawable);
@@ -468,12 +471,14 @@ fallback:
     UXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrcDrawable, pDstDrawable,
 		  uxa_drawable_location(pSrcDrawable),
 		  uxa_drawable_location(pDstDrawable)));
-    uxa_prepare_access (pDstDrawable, UXA_ACCESS_RW);
-    uxa_prepare_access (pSrcDrawable, UXA_ACCESS_RO);
-    fbCopyNtoN (pSrcDrawable, pDstDrawable, pGC, pbox, nbox, dx, dy, reverse,
-		upsidedown, bitplane, closure);
-    uxa_finish_access (pSrcDrawable);
-    uxa_finish_access (pDstDrawable);
+    if (uxa_prepare_access (pDstDrawable, UXA_ACCESS_RW)) {
+	if (uxa_prepare_access (pSrcDrawable, UXA_ACCESS_RO)) {
+	    fbCopyNtoN (pSrcDrawable, pDstDrawable, pGC, pbox, nbox, dx, dy,
+			reverse, upsidedown, bitplane, closure);
+	    uxa_finish_access (pSrcDrawable);
+	}
+	uxa_finish_access (pDstDrawable);
+    }
 }
 
 RegionPtr
@@ -1024,9 +1029,10 @@ fallback:
     UXA_FALLBACK(("from %p (%c)\n", pDrawable,
 		  uxa_drawable_location(pDrawable)));
 
-    uxa_prepare_access (pDrawable, UXA_ACCESS_RO);
-    fbGetImage (pDrawable, x, y, w, h, format, planeMask, d);
-    uxa_finish_access (pDrawable);
+    if (uxa_prepare_access (pDrawable, UXA_ACCESS_RO)) {
+	fbGetImage (pDrawable, x, y, w, h, format, planeMask, d);
+	uxa_finish_access (pDrawable);
+    }
 
    return;
 }
diff --git a/uxa/uxa-priv.h b/uxa/uxa-priv.h
index 0f9cfbf..f4b3cee 100644
--- a/uxa/uxa-priv.h
+++ b/uxa/uxa-priv.h
@@ -182,14 +182,14 @@ typedef struct {
   */
 void exaDDXDriverInit (ScreenPtr pScreen);
 
-void
+Bool
 uxa_prepare_access_window(WindowPtr pWin);
 
 void
 uxa_finish_access_window(WindowPtr pWin);
 
 /* uxa-unaccel.c */
-void
+Bool
 uxa_prepare_access_gc(GCPtr pGC);
 
 void
@@ -351,7 +351,7 @@ uxa_check_composite (CARD8      op,
 #endif
 
 /* uxa.c */
-void
+Bool
 uxa_prepare_access(DrawablePtr pDrawable, uxa_access_t access);
 
 void
diff --git a/uxa/uxa-render.c b/uxa/uxa-render.c
index b2d3297..13635f8 100644
--- a/uxa/uxa-render.c
+++ b/uxa/uxa-render.c
@@ -889,12 +889,12 @@ uxa_trapezoids (CARD8 op, PicturePtr pSrc, PicturePtr pDst,
 	xoff += pDraw->x;
 	yoff += pDraw->y;
 
-	uxa_prepare_access(pDraw, UXA_ACCESS_RW);
-
-	for (; ntrap; ntrap--, traps++)
-	    (*ps->RasterizeTrapezoid) (pDst, traps, 0, 0);
-
-	uxa_finish_access(pDraw);
+	if (uxa_prepare_access(pDraw, UXA_ACCESS_RW))
+	{
+	    for (; ntrap; ntrap--, traps++)
+		(*ps->RasterizeTrapezoid) (pDst, traps, 0, 0);
+	    uxa_finish_access(pDraw);
+	}
     }
     else if (maskFormat)
     {
@@ -911,11 +911,12 @@ uxa_trapezoids (CARD8 op, PicturePtr pSrc, PicturePtr pDst,
 	if (!pPicture)
 	    return;
 
-	uxa_prepare_access(pPicture->pDrawable, UXA_ACCESS_RW);
-	for (; ntrap; ntrap--, traps++)
-	    (*ps->RasterizeTrapezoid) (pPicture, traps,
-				       -bounds.x1, -bounds.y1);
-	uxa_finish_access(pPicture->pDrawable);
+	if (uxa_prepare_access(pPicture->pDrawable, UXA_ACCESS_RW)) {
+	    for (; ntrap; ntrap--, traps++)
+		(*ps->RasterizeTrapezoid) (pPicture, traps,
+					   -bounds.x1, -bounds.y1);
+	    uxa_finish_access(pPicture->pDrawable);
+	}
 
 	xRel = bounds.x1 + xSrc - xDst;
 	yRel = bounds.y1 + ySrc - yDst;
@@ -972,9 +973,10 @@ uxa_triangles (CARD8 op, PicturePtr pSrc, PicturePtr pDst,
     if (direct)
     {
 	DrawablePtr pDraw = pDst->pDrawable;
-	uxa_prepare_access(pDraw, UXA_ACCESS_RW);
-	(*ps->AddTriangles) (pDst, 0, 0, ntri, tris);
-	uxa_finish_access(pDraw);
+	if (uxa_prepare_access(pDraw, UXA_ACCESS_RW)) {
+	    (*ps->AddTriangles) (pDst, 0, 0, ntri, tris);
+	    uxa_finish_access(pDraw);
+	}
     }
     else if (maskFormat)
     {
@@ -991,9 +993,10 @@ uxa_triangles (CARD8 op, PicturePtr pSrc, PicturePtr pDst,
 	if (!pPicture)
 	    return;
 
-	uxa_prepare_access(pPicture->pDrawable, UXA_ACCESS_RW);
-	(*ps->AddTriangles) (pPicture, -bounds.x1, -bounds.y1, ntri, tris);
-	uxa_finish_access(pPicture->pDrawable);
+	if (uxa_prepare_access(pPicture->pDrawable, UXA_ACCESS_RW)) {
+	    (*ps->AddTriangles) (pPicture, -bounds.x1, -bounds.y1, ntri, tris);
+	    uxa_finish_access(pPicture->pDrawable);
+	}
 	
 	xRel = bounds.x1 + xSrc - xDst;
 	yRel = bounds.y1 + ySrc - yDst;
diff --git a/uxa/uxa-unaccel.c b/uxa/uxa-unaccel.c
index 01c1322..aba12e8 100644
--- a/uxa/uxa-unaccel.c
+++ b/uxa/uxa-unaccel.c
@@ -41,13 +41,19 @@
  * 1bpp and never in fb, so we don't worry about them.
  * We should worry about them for completeness sake and going forward.
  */
-void
+Bool
 uxa_prepare_access_gc(GCPtr pGC)
 {
     if (pGC->stipple)
-        uxa_prepare_access(&pGC->stipple->drawable, UXA_ACCESS_RO);
+        if (!uxa_prepare_access(&pGC->stipple->drawable, UXA_ACCESS_RO))
+	    return FALSE;
     if (pGC->fillStyle == FillTiled)
-	uxa_prepare_access(&pGC->tile.pixmap->drawable, UXA_ACCESS_RO);
+	if (!uxa_prepare_access(&pGC->tile.pixmap->drawable, UXA_ACCESS_RO)) {
+	    if (pGC->stipple)
+		uxa_finish_access(&pGC->stipple->drawable);
+	    return FALSE;
+	}
+    return TRUE;
 }
 
 /**
@@ -75,11 +81,13 @@ uxa_check_fill_spans (DrawablePtr pDrawable, GCPtr pGC, int nspans,
 		   DDXPointPtr ppt, int *pwidth, int fSorted)
 {
     UXA_FALLBACK(("to %p (%c)\n", pDrawable, uxa_drawable_location(pDrawable)));
-    uxa_prepare_access (pDrawable, UXA_ACCESS_RW);
-    uxa_prepare_access_gc (pGC);
-    fbFillSpans (pDrawable, pGC, nspans, ppt, pwidth, fSorted);
-    uxa_finish_access_gc (pGC);
-    uxa_finish_access (pDrawable);
+    if (uxa_prepare_access (pDrawable, UXA_ACCESS_RW)) {
+	if (uxa_prepare_access_gc (pGC)) {
+	    fbFillSpans (pDrawable, pGC, nspans, ppt, pwidth, fSorted);
+	    uxa_finish_access_gc (pGC);
+	}
+	uxa_finish_access (pDrawable);
+    }
 }
 
 void
@@ -87,9 +95,10 @@ uxa_check_set_spans (DrawablePtr pDrawable, GCPtr pGC, char *psrc,
 		 DDXPointPtr ppt, int *pwidth, int nspans, int fSorted)
 {
     UXA_FALLBACK(("to %p (%c)\n", pDrawable, uxa_drawable_location(pDrawable)));
-    uxa_prepare_access (pDrawable, UXA_ACCESS_RW);
-    fbSetSpans (pDrawable, pGC, psrc, ppt, pwidth, nspans, fSorted);
-    uxa_finish_access (pDrawable);
+    if (uxa_prepare_access (pDrawable, UXA_ACCESS_RW)) {
+	fbSetSpans (pDrawable, pGC, psrc, ppt, pwidth, nspans, fSorted);
+	uxa_finish_access (pDrawable);
+    }
 }
 
 void
@@ -98,25 +107,27 @@ uxa_check_put_image (DrawablePtr pDrawable, GCPtr pGC, int depth,
 		 char *bits)
 {
     UXA_FALLBACK(("to %p (%c)\n", pDrawable, uxa_drawable_location(pDrawable)));
-    uxa_prepare_access (pDrawable, UXA_ACCESS_RW);
-    fbPutImage (pDrawable, pGC, depth, x, y, w, h, leftPad, format, bits);
-    uxa_finish_access (pDrawable);
+    if (uxa_prepare_access (pDrawable, UXA_ACCESS_RW)) {
+	fbPutImage (pDrawable, pGC, depth, x, y, w, h, leftPad, format, bits);
+	uxa_finish_access (pDrawable);
+    }
 }
 
 RegionPtr
 uxa_check_copy_area (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
-		 int srcx, int srcy, int w, int h, int dstx, int dsty)
+		     int srcx, int srcy, int w, int h, int dstx, int dsty)
 {
-    RegionPtr ret;
+    RegionPtr ret = NULL;
 
     UXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrc, pDst,
 		  uxa_drawable_location(pSrc), uxa_drawable_location(pDst)));
-    uxa_prepare_access (pDst, UXA_ACCESS_RW);
-    uxa_prepare_access (pSrc, UXA_ACCESS_RO);
-    ret = fbCopyArea (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty);
-    uxa_finish_access (pSrc);
-    uxa_finish_access (pDst);
-
+    if (uxa_prepare_access (pDst, UXA_ACCESS_RW)) {
+	if (uxa_prepare_access (pSrc, UXA_ACCESS_RO)) {
+	    ret = fbCopyArea (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty);
+	    uxa_finish_access (pSrc);
+	}
+	uxa_finish_access (pDst);
+    }
     return ret;
 }
 
@@ -125,17 +136,18 @@ uxa_check_copy_plane (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
 		  int srcx, int srcy, int w, int h, int dstx, int dsty,
 		  unsigned long bitPlane)
 {
-    RegionPtr ret;
+    RegionPtr ret = NULL;
 
     UXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrc, pDst,
 		  uxa_drawable_location(pSrc), uxa_drawable_location(pDst)));
-    uxa_prepare_access (pDst, UXA_ACCESS_RW);
-    uxa_prepare_access (pSrc, UXA_ACCESS_RO);
-    ret = fbCopyPlane (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty,
-		       bitPlane);
-    uxa_finish_access (pSrc);
-    uxa_finish_access (pDst);
-
+    if (uxa_prepare_access (pDst, UXA_ACCESS_RW)) {
+	if (uxa_prepare_access (pSrc, UXA_ACCESS_RO)) {
+	    ret = fbCopyPlane (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty,
+			       bitPlane);
+	    uxa_finish_access (pSrc);
+	}
+	uxa_finish_access (pDst);
+    }
     return ret;
 }
 
@@ -144,9 +156,10 @@ uxa_check_poly_point (DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
 		  DDXPointPtr pptInit)
 {
     UXA_FALLBACK(("to %p (%c)\n", pDrawable, uxa_drawable_location(pDrawable)));
-    uxa_prepare_access (pDrawable, UXA_ACCESS_RW);
-    fbPolyPoint (pDrawable, pGC, mode, npt, pptInit);
-    uxa_finish_access (pDrawable);
+    if (uxa_prepare_access (pDrawable, UXA_ACCESS_RW)) {
+	fbPolyPoint (pDrawable, pGC, mode, npt, pptInit);
+	uxa_finish_access (pDrawable);
+    }
 }
 
 void
@@ -158,11 +171,13 @@ uxa_check_poly_lines (DrawablePtr pDrawable, GCPtr pGC,
 		  pGC->lineWidth, mode, npt));
 
     if (pGC->lineWidth == 0) {
-	uxa_prepare_access (pDrawable, UXA_ACCESS_RW);
-	uxa_prepare_access_gc (pGC);
-	fbPolyLine (pDrawable, pGC, mode, npt, ppt);
-	uxa_finish_access_gc (pGC);
-	uxa_finish_access (pDrawable);
+	if (uxa_prepare_access (pDrawable, UXA_ACCESS_RW)) {
+	    if (uxa_prepare_access_gc (pGC)) {
+		fbPolyLine (pDrawable, pGC, mode, npt, ppt);
+		uxa_finish_access_gc (pGC);
+	    }
+	    uxa_finish_access (pDrawable);
+	}
 	return;
     }
     /* fb calls mi functions in the lineWidth != 0 case. */
@@ -176,11 +191,13 @@ uxa_check_poly_segment (DrawablePtr pDrawable, GCPtr pGC,
     UXA_FALLBACK(("to %p (%c) width %d, count %d\n", pDrawable,
 		  uxa_drawable_location(pDrawable), pGC->lineWidth, nsegInit));
     if (pGC->lineWidth == 0) {
-	uxa_prepare_access (pDrawable, UXA_ACCESS_RW);
-	uxa_prepare_access_gc (pGC);
-	fbPolySegment (pDrawable, pGC, nsegInit, pSegInit);
-	uxa_finish_access_gc (pGC);
-	uxa_finish_access (pDrawable);
+	if (uxa_prepare_access (pDrawable, UXA_ACCESS_RW)) {
+	    if (uxa_prepare_access_gc (pGC)) {
+		fbPolySegment (pDrawable, pGC, nsegInit, pSegInit);
+		uxa_finish_access_gc (pGC);
+	    }
+	    uxa_finish_access (pDrawable);
+	}
 	return;
     }
     /* fb calls mi functions in the lineWidth != 0 case. */
@@ -200,11 +217,13 @@ uxa_check_poly_arc (DrawablePtr pDrawable, GCPtr pGC,
 #if 0
     if (pGC->lineWidth == 0)
     {
-	uxa_prepare_access (pDrawable, UXA_ACCESS_RW);
-	uxa_prepare_access_gc (pGC);
-	fbPolyArc (pDrawable, pGC, narcs, pArcs);
-	uxa_finish_access_gc (pGC);
-	uxa_finish_access (pDrawable);
+	if (uxa_prepare_access (pDrawable, UXA_ACCESS_RW)) {
+	    if (uxa_prepare_access_gc (pGC)) {
+		fbPolyArc (pDrawable, pGC, narcs, pArcs);
+		uxa_finish_access_gc (pGC);
+	    }
+	    uxa_finish_access (pDrawable);
+	}
 	return;
     }
 #endif
@@ -217,11 +236,13 @@ uxa_check_poly_fill_rect (DrawablePtr pDrawable, GCPtr pGC,
 {
     UXA_FALLBACK(("to %p (%c)\n", pDrawable, uxa_drawable_location(pDrawable)));
 
-    uxa_prepare_access (pDrawable, UXA_ACCESS_RW);
-    uxa_prepare_access_gc (pGC);
-    fbPolyFillRect (pDrawable, pGC, nrect, prect);
-    uxa_finish_access_gc (pGC);
-    uxa_finish_access (pDrawable);
+    if (uxa_prepare_access (pDrawable, UXA_ACCESS_RW)) {
+	if (uxa_prepare_access_gc (pGC)) {
+	    fbPolyFillRect (pDrawable, pGC, nrect, prect);
+	    uxa_finish_access_gc (pGC);
+	}
+	uxa_finish_access (pDrawable);
+    }
 }
 
 void
@@ -231,11 +252,13 @@ uxa_check_image_glyph_blt (DrawablePtr pDrawable, GCPtr pGC,
 {
     UXA_FALLBACK(("to %p (%c)\n", pDrawable,
 		  uxa_drawable_location(pDrawable)));
-    uxa_prepare_access (pDrawable, UXA_ACCESS_RW);
-    uxa_prepare_access_gc (pGC);
-    fbImageGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
-    uxa_finish_access_gc (pGC);
-    uxa_finish_access (pDrawable);
+    if (uxa_prepare_access (pDrawable, UXA_ACCESS_RW)) {
+	if (uxa_prepare_access_gc (pGC)) {
+	    fbImageGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
+	    uxa_finish_access_gc (pGC);
+	}
+	uxa_finish_access (pDrawable);
+    }
 }
 
 void
@@ -245,11 +268,13 @@ uxa_check_poly_glyph_blt (DrawablePtr pDrawable, GCPtr pGC,
 {
     UXA_FALLBACK(("to %p (%c), style %d alu %d\n", pDrawable,
 		  uxa_drawable_location(pDrawable), pGC->fillStyle, pGC->alu));
-    uxa_prepare_access (pDrawable, UXA_ACCESS_RW);
-    uxa_prepare_access_gc (pGC);
-    fbPolyGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
-    uxa_finish_access_gc (pGC);
-    uxa_finish_access (pDrawable);
+    if (uxa_prepare_access (pDrawable, UXA_ACCESS_RW)) {
+	if (uxa_prepare_access_gc (pGC)) {
+	    fbPolyGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
+	    uxa_finish_access_gc (pGC);
+	}
+	uxa_finish_access (pDrawable);
+    }
 }
 
 void
@@ -260,13 +285,16 @@ uxa_check_push_pixels (GCPtr pGC, PixmapPtr pBitmap,
     UXA_FALLBACK(("from %p to %p (%c,%c)\n", pBitmap, pDrawable,
 		  uxa_drawable_location(&pBitmap->drawable),
 		  uxa_drawable_location(pDrawable)));
-    uxa_prepare_access (pDrawable, UXA_ACCESS_RW);
-    uxa_prepare_access (&pBitmap->drawable, UXA_ACCESS_RO);
-    uxa_prepare_access_gc (pGC);
-    fbPushPixels (pGC, pBitmap, pDrawable, w, h, x, y);
-    uxa_finish_access_gc (pGC);
-    uxa_finish_access (&pBitmap->drawable);
-    uxa_finish_access (pDrawable);
+    if (uxa_prepare_access (pDrawable, UXA_ACCESS_RW)) {
+	if (uxa_prepare_access (&pBitmap->drawable, UXA_ACCESS_RO)) {
+	    if (uxa_prepare_access_gc (pGC)) {
+		fbPushPixels (pGC, pBitmap, pDrawable, w, h, x, y);
+		uxa_finish_access_gc (pGC);
+	    }
+	    uxa_finish_access (&pBitmap->drawable);
+	}
+	uxa_finish_access (pDrawable);
+    }
 }
 
 void
@@ -278,9 +306,10 @@ uxa_check_get_spans (DrawablePtr pDrawable,
 		 char *pdstStart)
 {
     UXA_FALLBACK(("from %p (%c)\n", pDrawable, uxa_drawable_location(pDrawable)));
-    uxa_prepare_access (pDrawable, UXA_ACCESS_RO);
-    fbGetSpans (pDrawable, wMax, ppt, pwidth, nspans, pdstStart);
-    uxa_finish_access (pDrawable);
+    if (uxa_prepare_access (pDrawable, UXA_ACCESS_RO)) {
+	fbGetSpans (pDrawable, wMax, ppt, pwidth, nspans, pdstStart);
+	uxa_finish_access (pDrawable);
+    }
 }
 
 void
@@ -300,28 +329,34 @@ uxa_check_composite (CARD8      op,
     UXA_FALLBACK(("from picts %p/%p to pict %p\n",
 		 pSrc, pMask, pDst));
 
-    uxa_prepare_access (pDst->pDrawable, UXA_ACCESS_RW);
-    if (pSrc->pDrawable != NULL)
-	uxa_prepare_access (pSrc->pDrawable, UXA_ACCESS_RO);
-    if (pMask && pMask->pDrawable != NULL)
-	uxa_prepare_access (pMask->pDrawable, UXA_ACCESS_RO);
-    fbComposite (op,
-                 pSrc,
-                 pMask,
-                 pDst,
-                 xSrc,
-                 ySrc,
-                 xMask,
-                 yMask,
-                 xDst,
-                 yDst,
-                 width,
-                 height);
-    if (pMask && pMask->pDrawable != NULL)
-	uxa_finish_access (pMask->pDrawable);
-    if (pSrc->pDrawable != NULL)
-	uxa_finish_access (pSrc->pDrawable);
-    uxa_finish_access (pDst->pDrawable);
+    if (uxa_prepare_access (pDst->pDrawable, UXA_ACCESS_RW))
+    {
+	if (pSrc->pDrawable == NULL ||
+	    uxa_prepare_access (pSrc->pDrawable, UXA_ACCESS_RO))
+	{
+	    if (!pMask || pMask->pDrawable == NULL ||
+		uxa_prepare_access (pMask->pDrawable, UXA_ACCESS_RO))
+	    {
+		fbComposite (op,
+			     pSrc,
+			     pMask,
+			     pDst,
+			     xSrc,
+			     ySrc,
+			     xMask,
+			     yMask,
+			     xDst,
+			     yDst,
+			     width,
+			     height);
+		if (pMask && pMask->pDrawable != NULL)
+		    uxa_finish_access (pMask->pDrawable);
+	    }
+	    if (pSrc->pDrawable != NULL)
+		uxa_finish_access (pSrc->pDrawable);
+	}
+	uxa_finish_access (pDst->pDrawable);
+    }
 }
 
 void
@@ -333,9 +368,10 @@ uxa_check_add_traps (PicturePtr	pPicture,
 {
     UXA_FALLBACK(("to pict %p (%c)\n",
 		  uxa_drawable_location(pPicture->pDrawable)));
-    uxa_prepare_access(pPicture->pDrawable, UXA_ACCESS_RW);
-    fbAddTraps (pPicture, x_off, y_off, ntrap, traps);
-    uxa_finish_access(pPicture->pDrawable);
+    if (uxa_prepare_access(pPicture->pDrawable, UXA_ACCESS_RW)) {
+	fbAddTraps (pPicture, x_off, y_off, ntrap, traps);
+	uxa_finish_access(pPicture->pDrawable);
+    }
 }
 
 /**
@@ -350,7 +386,9 @@ uxa_get_pixmap_first_pixel (PixmapPtr pPixmap)
     CARD32 pixel;
     void *fb;
 
-    uxa_prepare_access (&pPixmap->drawable, UXA_ACCESS_RO);
+    if (!uxa_prepare_access (&pPixmap->drawable, UXA_ACCESS_RO))
+	return 0;
+
     fb = pPixmap->devPrivate.ptr;
 
     switch (pPixmap->drawable.bitsPerPixel) {
diff --git a/uxa/uxa.c b/uxa/uxa.c
index 5b6f537..c341f04 100644
--- a/uxa/uxa.c
+++ b/uxa/uxa.c
@@ -140,7 +140,7 @@ uxa_get_offscreen_pixmap (DrawablePtr drawable, int *xp, int *yp)
  * It deals with waiting for synchronization with the card, determining if
  * PrepareAccess() is necessary, and working around PrepareAccess() failure.
  */
-void
+Bool
 uxa_prepare_access(DrawablePtr pDrawable, uxa_access_t access)
 {
     ScreenPtr	    pScreen = pDrawable->pScreen;
@@ -149,10 +149,11 @@ uxa_prepare_access(DrawablePtr pDrawable, uxa_access_t access)
     Bool	    offscreen = uxa_pixmap_is_offscreen(pPixmap);
 
     if (!offscreen)
-	return;
+	return TRUE;
 
     if (uxa_screen->info->prepare_access)
-	(*uxa_screen->info->prepare_access) (pPixmap, access);
+	return (*uxa_screen->info->prepare_access) (pPixmap, access);
+    return TRUE;
 }
 
 /**
@@ -209,10 +210,11 @@ uxa_validate_gc (GCPtr pGC, unsigned long changes, DrawablePtr pDrawable)
 		 * allocated pixmap.  This isn't a problem yet, since we don't
 		 * put pixmaps in FB until at least one accelerated UXA op.
 		 */
-		uxa_prepare_access(&pOldTile->drawable, UXA_ACCESS_RO);
-		pNewTile = fb24_32ReformatTile (pOldTile,
-						pDrawable->bitsPerPixel);
-		uxa_finish_access(&pOldTile->drawable);
+		if (uxa_prepare_access(&pOldTile->drawable, UXA_ACCESS_RO)) {
+		    pNewTile = fb24_32ReformatTile (pOldTile,
+						    pDrawable->bitsPerPixel);
+		    uxa_finish_access(&pOldTile->drawable);
+		}
 	    }
 	    if (pNewTile)
 	    {
@@ -227,9 +229,10 @@ uxa_validate_gc (GCPtr pGC, unsigned long changes, DrawablePtr pDrawable)
 	if (!pGC->tileIsPixel && FbEvenTile (pGC->tile.pixmap->drawable.width *
 					     pDrawable->bitsPerPixel))
 	{
-	    uxa_prepare_access(&pGC->tile.pixmap->drawable, UXA_ACCESS_RW);
-	    fbPadPixmap (pGC->tile.pixmap);
-	    uxa_finish_access(&pGC->tile.pixmap->drawable);
+	    if (uxa_prepare_access(&pGC->tile.pixmap->drawable, UXA_ACCESS_RW)) {
+		fbPadPixmap (pGC->tile.pixmap);
+		uxa_finish_access(&pGC->tile.pixmap->drawable);
+	    }
 	}
 	/* Mask out the GCTile change notification, now that we've done FB's
 	 * job for it.
@@ -269,14 +272,22 @@ uxa_create_gc (GCPtr pGC)
     return TRUE;
 }
 
-void
+Bool
 uxa_prepare_access_window(WindowPtr pWin)
 {
-    if (pWin->backgroundState == BackgroundPixmap) 
-        uxa_prepare_access(&pWin->background.pixmap->drawable, UXA_ACCESS_RO);
+    if (pWin->backgroundState == BackgroundPixmap) {
+        if (!uxa_prepare_access(&pWin->background.pixmap->drawable, UXA_ACCESS_RO))
+	    return FALSE;
+    }
 
-    if (pWin->borderIsPixel == FALSE)
-        uxa_prepare_access(&pWin->border.pixmap->drawable, UXA_ACCESS_RO);
+    if (pWin->borderIsPixel == FALSE) {
+        if (!uxa_prepare_access(&pWin->border.pixmap->drawable, UXA_ACCESS_RO)) {
+	    if (pWin->backgroundState == BackgroundPixmap)
+		uxa_finish_access(&pWin->background.pixmap->drawable);
+	    return FALSE;
+	}
+    }
+    return TRUE;
 }
 
 void
@@ -294,7 +305,8 @@ uxa_change_window_attributes(WindowPtr pWin, unsigned long mask)
 {
     Bool ret;
 
-    uxa_prepare_access_window(pWin);
+    if (!uxa_prepare_access_window(pWin))
+	return FALSE;
     ret = fbChangeWindowAttributes(pWin, mask);
     uxa_finish_access_window(pWin);
     return ret;
@@ -304,7 +316,8 @@ static RegionPtr
 uxa_bitmap_to_region(PixmapPtr pPix)
 {
   RegionPtr ret;
-  uxa_prepare_access(&pPix->drawable, UXA_ACCESS_RO);
+  if (!uxa_prepare_access(&pPix->drawable, UXA_ACCESS_RO))
+    return NULL;
   ret = fbPixmapToRegion(pPix);
   uxa_finish_access(&pPix->drawable);
   return ret;
-- 
1.5.6.5




More information about the Intel-gfx mailing list