xf86-video-intel: Branch 'framebuffer-resize' - 2 commits - src/i830_batchbuffer.c src/i830_exa.c src/i830_memory.c src/i965_render.c src/i965_video.c uxa/uxa-accel.c uxa/uxa.c uxa/uxa-priv.h uxa/uxa-render.c uxa/uxa-unaccel.c

Keith Packard keithp at kemper.freedesktop.org
Tue Jan 6 09:36:07 PST 2009


 src/i830_batchbuffer.c |    4 
 src/i830_exa.c         |   32 +-----
 src/i830_memory.c      |    5 -
 src/i965_render.c      |   22 +++-
 src/i965_video.c       |  168 +++++++++++++++++++++++-----------
 uxa/uxa-accel.c        |   30 +++---
 uxa/uxa-priv.h         |    6 -
 uxa/uxa-render.c       |   37 ++++---
 uxa/uxa-unaccel.c      |  236 ++++++++++++++++++++++++++++---------------------
 uxa/uxa.c              |   47 ++++++---
 10 files changed, 349 insertions(+), 238 deletions(-)

New commits:
commit 6cc1c8c74c4cd24c16b7a5e28dd02af9a59c8228
Author: Keith Packard <keithp at keithp.com>
Date:   Sun Dec 14 21:05:22 2008 -0800

    Another patch bomb. bo_reuse, bo_map failures and tiling
    
    Adds bo_map failure handling to 965 render and 965 video.
    Moves code to reset tile parameters to libdrm where it belongs.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/src/i830_batchbuffer.c b/src/i830_batchbuffer.c
index 13d939e..b1c8a8d 100644
--- a/src/i830_batchbuffer.c
+++ b/src/i830_batchbuffer.c
@@ -112,7 +112,9 @@ intel_next_batch(ScrnInfoPtr pScrn)
     else
 	pI830->batch_bo = dri_bo_alloc(pI830->bufmgr, "batch", 4096 * 4, 4096);
 
-    dri_bo_map(pI830->batch_bo, 1);
+    if (dri_bo_map(pI830->batch_bo, 1) != 0)
+	FatalError("Failed to map batchbuffer: %s\n", strerror(errno));
+
     pI830->batch_used = 0;
     pI830->batch_ptr = pI830->batch_bo->virtual;
 }
diff --git a/src/i830_exa.c b/src/i830_exa.c
index 9615798..cb9d858 100644
--- a/src/i830_exa.c
+++ b/src/i830_exa.c
@@ -263,26 +263,6 @@ I830EXADoneSolid(PixmapPtr pPixmap)
 #endif
 }
 
-static void
-check_tiling(PixmapPtr pixmap)
-{
-    ScreenPtr screen = pixmap->drawable.pScreen;
-    ScrnInfoPtr scrn = xf86Screens[screen->myNum];
-    I830Ptr i830 = I830PTR(scrn);
-    dri_bo *bo = i830_get_pixmap_bo(pixmap);
-    uint32_t tiling_mode = 0, swizzle_mode = 0;
-
-    if (!bo)
-	return;
-    drm_intel_bo_get_tiling(bo, &tiling_mode, &swizzle_mode);
-    if (tiling_mode != I915_TILING_NONE && bo != i830->front_buffer->bo) {
-	xf86DrvMsg(scrn->scrnIndex, X_ERROR,
-		   "non-front buffer is tiled pixmap 0x%x bo 0x%lx\n",
-		   (unsigned int) pixmap->drawable.id,
-		   bo->offset);
-    }
-}
-
 /**
  * TODO:
  *   - support planemask using FULL_BLT_CMD?
@@ -294,8 +274,6 @@ I830EXAPrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir,
     ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum];
     I830Ptr pI830 = I830PTR(pScrn);
 
-    check_tiling(pSrcPixmap);
-    check_tiling(pDstPixmap);
     if (!EXA_PM_IS_SOLID(&pSrcPixmap->drawable, planemask))
 	I830FALLBACK("planemask is not solid");
 
@@ -897,6 +875,7 @@ i830_uxa_create_pixmap (ScreenPtr screen, int w, int h, int depth, unsigned usag
     dri_bo *bo;
     int stride;
     PixmapPtr pixmap;
+    uint32_t bo_tiling, bo_swizzle;
     
     if (w > 32767 || h > 32767)
 	return NullPixmap;
@@ -914,7 +893,8 @@ i830_uxa_create_pixmap (ScreenPtr screen, int w, int h, int depth, unsigned usag
 	    fbDestroyPixmap (pixmap);
 	    return NullPixmap;
 	}
-	
+	drm_intel_bo_get_tiling(bo, &bo_tiling, &bo_swizzle);
+	assert (bo_tiling == TILE_NONE);
 	screen->ModifyPixmapHeader (pixmap, w, h, 0, 0, stride, NULL);
     
 	i830_uxa_set_pixmap_bo (pixmap, bo);
diff --git a/src/i830_memory.c b/src/i830_memory.c
index a6eff14..45aa109 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -271,11 +271,6 @@ i830_free_memory(ScrnInfoPtr pScrn, i830_memory *mem)
 #ifdef XF86DRI
     if (mem->bo != NULL) {
 	I830Ptr pI830 = I830PTR(pScrn);
-	if (mem->tiling != TILE_NONE) {
-	    uint32_t bo_tiling_mode = I915_TILING_NONE;
-	    dri_bo_set_tiling(mem->bo, &bo_tiling_mode);
-	}
-
 	dri_bo_unreference (mem->bo);
 	if (pI830->bo_list == mem) {
 	    pI830->bo_list = mem->next;
diff --git a/src/i965_render.c b/src/i965_render.c
index df3814f..6ef35e0 100644
--- a/src/i965_render.c
+++ b/src/i965_render.c
@@ -1068,7 +1068,13 @@ _emit_batch_header_for_composite_internal (ScrnInfoPtr pScrn, Bool check_twice)
     surface_state_bo = dri_bo_alloc (pI830->bufmgr, "surface_state",
 				     3 * sizeof (brw_surface_state_padded),
 				     4096);
-    dri_bo_map (surface_state_bo, 1);
+    if (dri_bo_map (surface_state_bo, 1) != 0) {
+	dri_bo_unreference (surface_state_bo);
+	dri_bo_unreference (render_state->vertex_buffer_bo);
+	render_state->vertex_buffer_bo = NULL;
+
+	return FALSE;
+    }
     /* Set up the state buffer for the destination surface */
     i965_set_picture_surface_state(surface_state_bo, 0,
 				   pDstPicture, pDst, TRUE);
@@ -1086,7 +1092,15 @@ _emit_batch_header_for_composite_internal (ScrnInfoPtr pScrn, Bool check_twice)
     /* Set up the binding table of surface indices to surface state. */
     binding_table_bo = dri_bo_alloc (pI830->bufmgr, "binding_table",
 				     3 * sizeof (uint32_t), 4096);
-    dri_bo_map (binding_table_bo, 1);
+    if (dri_bo_map (binding_table_bo, 1) != 0) {
+	dri_bo_unreference(binding_table_bo);
+	dri_bo_unreference(surface_state_bo);
+	dri_bo_unreference (render_state->vertex_buffer_bo);
+	render_state->vertex_buffer_bo = NULL;
+
+	return FALSE;
+    }
+
     binding_table = binding_table_bo->virtual;
     binding_table[0] = 0 * sizeof (brw_surface_state_padded) + surface_state_bo->offset;
     dri_bo_emit_reloc (binding_table_bo, I915_GEM_DOMAIN_INSTRUCTION, 0,
@@ -1498,7 +1512,9 @@ i965_composite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY,
 	_emit_batch_header_for_composite (pScrn);
 
     /* Map the vertex_buffer buffer object so we can write to it. */
-    dri_bo_map (render_state->vertex_buffer_bo, 1);
+    if (dri_bo_map (render_state->vertex_buffer_bo, 1) != 0)
+	return;		/* XXX what else to do here? */
+
     vb = render_state->vertex_buffer_bo->virtual;
 
     i = render_state->vb_offset;
diff --git a/src/i965_video.c b/src/i965_video.c
index 7e84ae0..e9f5ced 100644
--- a/src/i965_video.c
+++ b/src/i965_video.c
@@ -343,6 +343,25 @@ intel_emit_reloc(drm_intel_bo *bo, uint32_t offset,
     return target_bo->offset + target_offset;
 }
 
+static int
+intel_alloc_and_map(I830Ptr i830, char *name, int size,
+		    drm_intel_bo **bop, void *virtualp)
+{
+    drm_intel_bo    *bo;
+
+    bo = drm_intel_bo_alloc(i830->bufmgr, name, size, 4096);
+    if (!bo)
+	return -1;
+    if (drm_intel_bo_map(bo, TRUE) != 0) {
+	drm_intel_bo_unreference(bo);
+	return -1;
+    }
+    *bop = bo;
+    *(void **) virtualp = bo->virtual;
+    memset (bo->virtual, 0, size);
+    return 0;
+}
+
 static drm_intel_bo *
 i965_create_dst_surface_state(ScrnInfoPtr scrn,
 			      PixmapPtr pixmap)
@@ -352,13 +371,10 @@ i965_create_dst_surface_state(ScrnInfoPtr scrn,
     drm_intel_bo *pixmap_bo = i830_get_pixmap_bo(pixmap);
     drm_intel_bo *surf_bo;
 
-    surf_bo = drm_intel_bo_alloc(pI830->bufmgr,
-				    "textured video surface state",
-				    4096, 4096);
-    drm_intel_bo_map(surf_bo, TRUE);
-    dest_surf_state = surf_bo->virtual;
+    if (intel_alloc_and_map(pI830, "textured video surface state", 4096,
+			    &surf_bo, &dest_surf_state) != 0)
+	return NULL;
 
-    memset(dest_surf_state, 0, sizeof(*dest_surf_state));
     dest_surf_state->ss0.surface_type = BRW_SURFACE_2D;
     dest_surf_state->ss0.data_return_format = BRW_SURFACERETURNFORMAT_FLOAT32;
     if (pI830->cpp == 2) {
@@ -408,14 +424,11 @@ i965_create_src_surface_state(ScrnInfoPtr scrn,
     drm_intel_bo *surface_bo;
     struct brw_surface_state *src_surf_state;
 
-    surface_bo = drm_intel_bo_alloc(pI830->bufmgr,
-				    "textured video surface state",
-				    4096, 4096);
-    drm_intel_bo_map(surface_bo, TRUE);
-    src_surf_state = surface_bo->virtual;
+    if (intel_alloc_and_map(pI830, "textured video surface state", 4096,
+			    &surface_bo, &src_surf_state) != 0)
+	return NULL;
 
     /* Set up the source surface state buffer */
-    memset(src_surf_state, 0, sizeof(struct brw_surface_state));
     src_surf_state->ss0.surface_type = BRW_SURFACE_2D;
     src_surf_state->ss0.surface_format = src_surf_format;
     src_surf_state->ss0.writedisable_alpha = 0;
@@ -449,11 +462,9 @@ i965_create_binding_table(ScrnInfoPtr scrn, drm_intel_bo **surf_bos, int n_surf)
 
     /* Set up a binding table for our surfaces.  Only the PS will use it */
 
-    bind_bo = drm_intel_bo_alloc(pI830->bufmgr,
-				 "textured video binding table",
-				 4096, 4096);
-    drm_intel_bo_map(bind_bo, TRUE);
-    binding_table = bind_bo->virtual;
+    if (intel_alloc_and_map(pI830, "textured video binding table", 4096,
+			    &bind_bo, &binding_table) != 0)
+	return NULL;
 
     for (i = 0; i < n_surf; i++)
 	binding_table[i] = intel_emit_reloc(bind_bo, i * sizeof(uint32_t),
@@ -471,13 +482,9 @@ i965_create_sampler_state(ScrnInfoPtr scrn)
     drm_intel_bo *sampler_bo;
     struct brw_sampler_state *sampler_state;
 
-    sampler_bo = drm_intel_bo_alloc(pI830->bufmgr,
-				    "textured video sampler state",
-				    4096, 4096);
-    drm_intel_bo_map(sampler_bo, TRUE);
-    sampler_state = sampler_bo->virtual;
-
-    memset(sampler_state, 0, sizeof(struct brw_sampler_state));
+    if (intel_alloc_and_map(pI830, "textured video sampler state", 4096,
+			    &sampler_bo, &sampler_state) != 0)
+	return NULL;
 
     sampler_state->ss0.min_filter = BRW_MAPFILTER_LINEAR;
     sampler_state->ss0.mag_filter = BRW_MAPFILTER_LINEAR;
@@ -496,13 +503,11 @@ i965_create_vs_state(ScrnInfoPtr scrn)
     drm_intel_bo *vs_bo;
     struct brw_vs_unit_state *vs_state;
 
-    vs_bo = drm_intel_bo_alloc(pI830->bufmgr, "textured video vs state",
-			       4096, 4096);
-    drm_intel_bo_map(vs_bo, TRUE);
-    vs_state = vs_bo->virtual;
+    if (intel_alloc_and_map(pI830, "textured video vs state", 4096,
+			    &vs_bo, &vs_state) != 0)
+	return NULL;
 
     /* Set up the vertex shader to be disabled (passthrough) */
-    memset(vs_state, 0, sizeof(*vs_state));
     vs_state->thread4.nr_urb_entries = URB_VS_ENTRIES;
     vs_state->thread4.urb_entry_allocation_size = URB_VS_ENTRY_SIZE - 1;
     vs_state->vs6.vs_enable = 0;
@@ -521,6 +526,9 @@ i965_create_program(ScrnInfoPtr scrn, const uint32_t *program,
 
     prog_bo = drm_intel_bo_alloc(pI830->bufmgr, "textured video program",
 				 program_size, 4096);
+    if (!prog_bo)
+	return NULL;
+
     drm_intel_bo_subdata(prog_bo, 0, program_size, program);
 
     return prog_bo;
@@ -536,16 +544,20 @@ i965_create_sf_state(ScrnInfoPtr scrn)
     kernel_bo = i965_create_program(scrn, &sf_kernel_static[0][0],
 				    sizeof(sf_kernel_static));
 
-    sf_bo = drm_intel_bo_alloc(pI830->bufmgr, "textured video sf state",
-			       4096, 4096);
-    drm_intel_bo_map(sf_bo, TRUE);
-    sf_state = sf_bo->virtual;
+    if (!kernel_bo)
+	return NULL;
+
+    if (intel_alloc_and_map(pI830, "textured video sf state", 4096,
+			    &sf_bo, &sf_state) != 0)
+    {
+	drm_intel_bo_unreference(kernel_bo);
+	return NULL;
+    }
 
     /* Set up the SF kernel to do coord interp: for each attribute,
      * calculate dA/dx and dA/dy.  Hand these interpolation coefficients
      * back to SF which then hands pixels off to WM.
      */
-    memset(sf_state, 0, sizeof(*sf_state));
     sf_state->thread0.grf_reg_count = BRW_GRF_BLOCKS(SF_KERNEL_NUM_GRF);
     sf_state->thread0.kernel_start_pointer =
 	intel_emit_reloc(sf_bo, offsetof(struct brw_sf_unit_state, thread0),
@@ -595,13 +607,15 @@ i965_create_wm_state(ScrnInfoPtr scrn, drm_intel_bo *sampler_bo, Bool is_packed)
 	kernel_bo = i965_create_program(scrn, &ps_kernel_planar_static[0][0],
 					sizeof(ps_kernel_planar_static));
     }
+    if (!kernel_bo)
+	return NULL;
 
-    wm_bo = drm_intel_bo_alloc(pI830->bufmgr, "textured video wm state",
-			       4096, 4096);
-    drm_intel_bo_map(wm_bo, TRUE);
-    wm_state = wm_bo->virtual;
+    if (intel_alloc_and_map(pI830, "textured video wm state", sizeof (*wm_state),
+			    &wm_bo, &wm_state)) {
+	drm_intel_bo_unreference(kernel_bo);
+	return NULL;
+    }
 
-    memset(wm_state, 0, sizeof (*wm_state));
     wm_state->thread0.grf_reg_count = BRW_GRF_BLOCKS(PS_KERNEL_NUM_GRF);
     wm_state->thread0.kernel_start_pointer =
 	intel_emit_reloc(wm_bo, offsetof(struct brw_wm_unit_state, thread0),
@@ -647,12 +661,10 @@ i965_create_cc_vp_state(ScrnInfoPtr scrn)
     drm_intel_bo *cc_vp_bo;
     struct brw_cc_viewport *cc_viewport;
 
-    cc_vp_bo = drm_intel_bo_alloc(pI830->bufmgr, "textured video cc viewport",
-				  4096, 4096);
-    drm_intel_bo_map(cc_vp_bo, TRUE);
-    cc_viewport = cc_vp_bo->virtual;
+    if (intel_alloc_and_map(pI830, "textured video cc viewport", 4096,
+			    &cc_vp_bo, &cc_viewport) != 0)
+	return NULL;
 
-    memset (cc_viewport, 0, sizeof (*cc_viewport));
     cc_viewport->min_depth = -1.e35;
     cc_viewport->max_depth = 1.e35;
 
@@ -668,11 +680,14 @@ i965_create_cc_state(ScrnInfoPtr scrn)
     struct brw_cc_unit_state *cc_state;
 
     cc_vp_bo = i965_create_cc_vp_state(scrn);
+    if (!cc_vp_bo)
+	return NULL;
 
-    cc_bo = drm_intel_bo_alloc(pI830->bufmgr, "textured video cc state",
-			       4096, 4096);
-    drm_intel_bo_map(cc_bo, TRUE);
-    cc_state = cc_bo->virtual;
+    if (intel_alloc_and_map(pI830, "textured video cc state", sizeof(*cc_state),
+			    &cc_bo, &cc_state) != 0) {
+	drm_intel_bo_unreference(cc_vp_bo);
+	return NULL;
+    }
 
     /* Color calculator state */
     memset(cc_state, 0, sizeof(*cc_state));
@@ -809,44 +824,84 @@ I965DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id,
 
     /* Upload kernels */
     surf_bos[0] = i965_create_dst_surface_state(pScrn, pPixmap);
+    if (!surf_bos[0])
+	return;
 
     for (src_surf = 0; src_surf < n_src_surf; src_surf++) {
-	surf_bos[src_surf + 1] =
+	drm_intel_bo *surf_bo =
 	    i965_create_src_surface_state(pScrn,
 					  src_surf_base[src_surf],
 					  src_width[src_surf],
 					  src_height[src_surf],
 					  src_pitch[src_surf],
 					  src_surf_format);
+	if (!surf_bo) {
+	    int	q;
+	    for(q = 0; q < src_surf + 1; q++)
+		drm_intel_bo_unreference(surf_bos[q]);
+	    return;
+	}
+	surf_bos[src_surf + 1] = surf_bo;
     }
     bind_bo = i965_create_binding_table(pScrn, surf_bos, n_src_surf + 1);
     for (i = 0; i < n_src_surf + 1; i++) {
 	drm_intel_bo_unreference(surf_bos[i]);
 	surf_bos[i] = NULL;
     }
+    if (!bind_bo)
+	return;
 
     if (pI830->video.gen4_sampler_bo == NULL)
 	pI830->video.gen4_sampler_bo = i965_create_sampler_state(pScrn);
-    if (pI830->video.gen4_sip_kernel_bo == NULL)
+    if (pI830->video.gen4_sip_kernel_bo == NULL) {
 	pI830->video.gen4_sip_kernel_bo =
 	    i965_create_program(pScrn, &sip_kernel_static[0][0],
 				sizeof(sip_kernel_static));
+	if (!pI830->video.gen4_sip_kernel_bo) {
+	    drm_intel_bo_unreference(bind_bo);
+	    return;
+	}
+    }
 
-    if (pI830->video.gen4_vs_bo == NULL)
+    if (pI830->video.gen4_vs_bo == NULL) {
 	pI830->video.gen4_vs_bo = i965_create_vs_state(pScrn);
-    if (pI830->video.gen4_sf_bo == NULL)
+	if (!pI830->video.gen4_vs_bo) {
+	    drm_intel_bo_unreference(bind_bo);
+	    return;
+	}
+    }
+    if (pI830->video.gen4_sf_bo == NULL) {
 	pI830->video.gen4_sf_bo = i965_create_sf_state(pScrn);
+	if (!pI830->video.gen4_sf_bo) {
+	    drm_intel_bo_unreference(bind_bo);
+	    return;
+	}
+    }
     if (pI830->video.gen4_wm_packed_bo == NULL) {
 	pI830->video.gen4_wm_packed_bo =
 	    i965_create_wm_state(pScrn, pI830->video.gen4_sampler_bo, TRUE);
+	if (!pI830->video.gen4_wm_packed_bo) {
+	    drm_intel_bo_unreference(bind_bo);
+	    return;
+	}
     }
+
     if (pI830->video.gen4_wm_planar_bo == NULL) {
 	pI830->video.gen4_wm_planar_bo =
 	    i965_create_wm_state(pScrn, pI830->video.gen4_sampler_bo, FALSE);
+	if (!pI830->video.gen4_wm_planar_bo) {
+	    drm_intel_bo_unreference(bind_bo);
+	    return;
+	}
     }
 
-    if (pI830->video.gen4_cc_bo == NULL)
+    if (pI830->video.gen4_cc_bo == NULL) {
 	pI830->video.gen4_cc_bo = i965_create_cc_state(pScrn);
+	if (!pI830->video.gen4_cc_bo) {
+	    drm_intel_bo_unreference(bind_bo);
+	    return;
+	}
+    }
 
     {
 	BEGIN_BATCH(2);
@@ -1033,11 +1088,10 @@ I965DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id,
 
 	pbox++;
 
-	vb_bo = drm_intel_bo_alloc(pI830->bufmgr, "textured video vb",
-				   4096, 4096);
-	drm_intel_bo_map(vb_bo, TRUE);
+	if (intel_alloc_and_map(pI830, "textured video vb", 4096,
+				&vb_bo, &vb) != 0)
+	    break;
 
-	vb = vb_bo->virtual;
 	i = 0;
 	vb[i++] = (box_x2 - dxo) * src_scale_x;
 	vb[i++] = (box_y2 - dyo) * src_scale_y;
commit c3dbd49bb242f8d56a0ad076fa0b7ab68728c763
Author: Keith Packard <keithp at keithp.com>
Date:   Sat Dec 13 14:51:48 2008 -0800

    Check and deal with drm_bo_map failure
    
    If drm_bo_map fails, then there will be no virtual address for a pixmap
    leading to a segfault when the server tries to access the pixels.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/src/i830_exa.c b/src/i830_exa.c
index d10e72e..9615798 100644
--- a/src/i830_exa.c
+++ b/src/i830_exa.c
@@ -37,6 +37,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "i810_reg.h"
 #include "i915_drm.h"
 #include <string.h>
+#include <errno.h>
 
 #define ALWAYS_SYNC		0
 #define ALWAYS_FLUSH		0
@@ -839,8 +840,11 @@ i830_uxa_prepare_access (PixmapPtr pixmap, uxa_access_t access)
 
 	    pixmap->devPrivate.ptr = pI830->FbBase + bo->offset;
 	} else {
-	    if (dri_bo_map (bo, access == UXA_ACCESS_RW) != 0)
+	    if (dri_bo_map (bo, access == UXA_ACCESS_RW) != 0) {
+		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+			   "dri_bo_map failed %d\n", errno);
 		return FALSE;
+	    }
 
 	    pixmap->devPrivate.ptr = bo->virtual;
 	}
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;


More information about the xorg-commit mailing list