Hi,

I encountered a bug testing radeon-rewrite with Compiz (both with and without 
KMS), where the X server crashed due to essentially a double-free of a 
DRIdrawable: The bound drawable was freed, but the state duplicate in 
radeon_dri_mirror didn't get updated to reflect that.

The attached patch removes the state duplication, which fixes the crash for me 
and hopefully will help avoid similar bugs in the future.

I'm only skeptical because I'm a bit surprised that nobody else has seen this 
bug. Any feedback on the patch?

cu,
Nicolai
From 73c816fa3148c8390ae32d5978688d6e1204a11d Mon Sep 17 00:00:00 2001
From: =?utf-8?q?Nicolai=20H=C3=A4hnle?= <nhaeh...@gmail.com>
Date: Sun, 24 May 2009 14:55:51 +0200
Subject: [PATCH] radeon: Remove drawable & readable from radeon_dri_mirror
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 8bit

The duplication of state data caused a crash due to double-free on destruction
of context, because a variable wasn't correctly null'ed out.

Signed-off-by: Nicolai Hähnle <nhaeh...@gmail.com>
---
 src/mesa/drivers/dri/r300/r300_ioctl.c             |   16 +++---
 src/mesa/drivers/dri/r300/r300_state.c             |   18 +++---
 src/mesa/drivers/dri/radeon/radeon_common.c        |   63 +++++++++----------
 .../drivers/dri/radeon/radeon_common_context.c     |   66 ++++++++------------
 .../drivers/dri/radeon/radeon_common_context.h     |   27 ++++----
 src/mesa/drivers/dri/radeon/radeon_lock.c          |    8 +-
 6 files changed, 94 insertions(+), 104 deletions(-)

diff --git a/src/mesa/drivers/dri/r300/r300_ioctl.c b/src/mesa/drivers/dri/r300/r300_ioctl.c
index 6766eb3..104079b 100644
--- a/src/mesa/drivers/dri/r300/r300_ioctl.c
+++ b/src/mesa/drivers/dri/r300/r300_ioctl.c
@@ -79,7 +79,7 @@ static void r300ClearBuffer(r300ContextPtr r300, int flags,
 {
 	BATCH_LOCALS(&r300->radeon);
 	GLcontext *ctx = r300->radeon.glCtx;
-	__DRIdrawablePrivate *dPriv = r300->radeon.dri.drawable;
+	__DRIdrawablePrivate *dPriv = radeon_get_drawable(&r300->radeon);
 	GLuint cbpitch = 0;
 	r300ContextPtr rmesa = r300;
 
@@ -200,7 +200,7 @@ static void r300ClearBuffer(r300ContextPtr r300, int flags,
 		OUT_BATCH_FLOAT32(ctx->Color.ClearColor[2]);
 		OUT_BATCH_FLOAT32(ctx->Color.ClearColor[3]);
 	}
-	
+
 	r300EmitCacheFlush(rmesa);
 	cp_wait(&r300->radeon, R300_WAIT_3D | R300_WAIT_3D_CLEAN);
 
@@ -213,7 +213,7 @@ static void r300EmitClearState(GLcontext * ctx)
 {
 	r300ContextPtr r300 = R300_CONTEXT(ctx);
 	BATCH_LOCALS(&r300->radeon);
-	__DRIdrawablePrivate *dPriv = r300->radeon.dri.drawable;
+	__DRIdrawablePrivate *dPriv = radeon_get_drawable(&r300->radeon);
 	int i;
 	int has_tcl;
 	int is_r500 = 0;
@@ -447,7 +447,7 @@ static void r300EmitClearState(GLcontext * ctx)
 			R500_ALU_RGBA_G_SWIZ_0 |
 			R500_ALU_RGBA_B_SWIZ_0 |
 			R500_ALU_RGBA_A_SWIZ_0;
-		
+
 		r500fp.cmd[7] = 0;
 		emit_r500fp(ctx, &r500fp);
 	}
@@ -541,9 +541,9 @@ static void r300EmitClearState(GLcontext * ctx)
 }
 
 static void r300KernelClear(GLcontext *ctx, GLuint flags)
-{	  	
+{
 	r300ContextPtr r300 = R300_CONTEXT(ctx);
-	__DRIdrawablePrivate *dPriv = r300->radeon.dri.drawable;
+	__DRIdrawablePrivate *dPriv = radeon_get_drawable(&r300->radeon);
 	struct radeon_framebuffer *rfb = dPriv->driverPrivate;
 	struct radeon_renderbuffer *rrb;
 	struct radeon_renderbuffer *rrbd;
@@ -565,7 +565,7 @@ static void r300KernelClear(GLcontext *ctx, GLuint flags)
 		r300ClearBuffer(r300, CLEARBUFFER_COLOR, rrb, NULL);
 		bits = 0;
 	}
-		
+
 	if (flags & BUFFER_BIT_FRONT_LEFT) {
 		rrb = radeon_get_renderbuffer(&rfb->base, BUFFER_FRONT_LEFT);
 		r300ClearBuffer(r300, bits | CLEARBUFFER_COLOR, rrb, rrbd);
@@ -590,7 +590,7 @@ static void r300KernelClear(GLcontext *ctx, GLuint flags)
 static void r300Clear(GLcontext * ctx, GLbitfield mask)
 {
 	r300ContextPtr r300 = R300_CONTEXT(ctx);
-	__DRIdrawablePrivate *dPriv = r300->radeon.dri.drawable;
+	__DRIdrawablePrivate *dPriv = radeon_get_drawable(&r300->radeon);
 	const GLuint colorMask = *((GLuint *) & ctx->Color.ColorMask);
 	GLbitfield swrast_mask = 0, tri_mask = 0;
 	int i;
diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c
index efbe5ca..582e8c2 100644
--- a/src/mesa/drivers/dri/r300/r300_state.c
+++ b/src/mesa/drivers/dri/r300/r300_state.c
@@ -967,7 +967,7 @@ static void r300StencilOpSeparate(GLcontext * ctx, GLenum face,
 static void r300UpdateWindow(GLcontext * ctx)
 {
 	r300ContextPtr rmesa = R300_CONTEXT(ctx);
-	__DRIdrawablePrivate *dPriv = rmesa->radeon.dri.drawable;
+	__DRIdrawablePrivate *dPriv = radeon_get_drawable(&rmesa->radeon);
 	GLfloat xoffset = dPriv ? (GLfloat) dPriv->x : 0;
 	GLfloat yoffset = dPriv ? (GLfloat) dPriv->y + dPriv->h : 0;
 	const GLfloat *v = ctx->Viewport._WindowMap.m;
@@ -1020,7 +1020,7 @@ static void r300DepthRange(GLcontext * ctx, GLclampd nearval, GLclampd farval)
 void r300UpdateViewportOffset(GLcontext * ctx)
 {
 	r300ContextPtr rmesa = R300_CONTEXT(ctx);
-	__DRIdrawablePrivate *dPriv = ((radeonContextPtr) rmesa)->dri.drawable;
+	__DRIdrawablePrivate *dPriv = radeon_get_drawable(&rmesa->radeon);
 	GLfloat xoffset = (GLfloat) dPriv->x;
 	GLfloat yoffset = (GLfloat) dPriv->y + dPriv->h;
 	const GLfloat *v = ctx->Viewport._WindowMap.m;
@@ -1052,12 +1052,14 @@ r300FetchStateParameter(GLcontext * ctx,
 	switch (state[0]) {
 	case STATE_INTERNAL:
 		switch (state[1]) {
-		case STATE_R300_WINDOW_DIMENSION:
-			value[0] = r300->radeon.dri.drawable->w * 0.5f;	/* width*0.5 */
-			value[1] = r300->radeon.dri.drawable->h * 0.5f;	/* height*0.5 */
-			value[2] = 0.5F;	/* for moving range [-1 1] -> [0 1] */
-			value[3] = 1.0F;	/* not used */
-			break;
+		case STATE_R300_WINDOW_DIMENSION: {
+				__DRIdrawablePrivate * drawable = radeon_get_drawable(&r300->radeon);
+				value[0] = drawable->w * 0.5f;	/* width*0.5 */
+				value[1] = drawable->h * 0.5f;	/* height*0.5 */
+				value[2] = 0.5F;	/* for moving range [-1 1] -> [0 1] */
+				value[3] = 1.0F;	/* not used */
+				break;
+			}
 
 		case STATE_R300_TEXRECT_FACTOR:{
 				struct gl_texture_object *t =
diff --git a/src/mesa/drivers/dri/radeon/radeon_common.c b/src/mesa/drivers/dri/radeon/radeon_common.c
index 76e884d..e2e0ba0 100644
--- a/src/mesa/drivers/dri/radeon/radeon_common.c
+++ b/src/mesa/drivers/dri/radeon/radeon_common.c
@@ -153,7 +153,7 @@ void radeon_get_cliprects(radeonContextPtr radeon,
 			  unsigned int *num_cliprects,
 			  int *x_off, int *y_off)
 {
-	__DRIdrawablePrivate *dPriv = radeon->dri.drawable;
+	__DRIdrawablePrivate *dPriv = radeon_get_drawable(radeon);
 	struct radeon_framebuffer *rfb = dPriv->driverPrivate;
 
 	if (radeon->constant_cliprect) {
@@ -185,15 +185,15 @@ void radeon_get_cliprects(radeonContextPtr radeon,
  */
 void radeonSetCliprects(radeonContextPtr radeon)
 {
-	__DRIdrawablePrivate *const drawable = radeon->dri.drawable;
-	__DRIdrawablePrivate *const readable = radeon->dri.readable;
+	__DRIdrawablePrivate *const drawable = radeon_get_drawable(radeon);
+	__DRIdrawablePrivate *const readable = radeon_get_readable(radeon);
 	struct radeon_framebuffer *const draw_rfb = drawable->driverPrivate;
 	struct radeon_framebuffer *const read_rfb = readable->driverPrivate;
 	int x_off, y_off;
 
 	radeon_get_cliprects(radeon, &radeon->pClipRects,
 			     &radeon->numClipRects, &x_off, &y_off);
-	
+
 	if ((draw_rfb->base.Width != drawable->w) ||
 	    (draw_rfb->base.Height != drawable->h)) {
 		_mesa_resize_framebuffer(radeon->glCtx, &draw_rfb->base,
@@ -221,9 +221,9 @@ void radeonUpdateScissor( GLcontext *ctx )
 {
 	radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
 
-	if ( rmesa->dri.drawable ) {
-		__DRIdrawablePrivate *dPriv = rmesa->dri.drawable;
-      
+	if ( radeon_get_drawable(rmesa) ) {
+		__DRIdrawablePrivate *dPriv = radeon_get_drawable(rmesa);
+
 		int x = ctx->Scissor.X;
 		int y = dPriv->h - ctx->Scissor.Y - ctx->Scissor.Height;
 		int w = ctx->Scissor.X + ctx->Scissor.Width - 1;
@@ -425,11 +425,11 @@ void radeonCopyBuffer( __DRIdrawablePrivate *dPriv,
 	radeonContextPtr rmesa;
 	struct radeon_framebuffer *rfb;
 	GLint nbox, i, ret;
-   
+
 	assert(dPriv);
 	assert(dPriv->driContextPriv);
 	assert(dPriv->driContextPriv->driverPrivate);
-   
+
 	rmesa = (radeonContextPtr) dPriv->driContextPriv->driverPrivate;
 
 	LOCK_HARDWARE(rmesa);
@@ -506,7 +506,7 @@ static int radeonScheduleSwap(__DRIdrawablePrivate *dPriv, GLboolean *missed_tar
 
 	UNLOCK_HARDWARE(rmesa);
 	driWaitForVBlank(dPriv, missed_target);
-	
+
 	return 0;
 }
 
@@ -540,7 +540,7 @@ static GLboolean radeonPageFlip( __DRIdrawablePrivate *dPriv )
 	radeon->sarea->nbox = 1;
 
 	ret = drmCommandNone( radeon->dri.fd, DRM_RADEON_FLIP );
-	
+
 	UNLOCK_HARDWARE(radeon);
 
 	if ( ret ) {
@@ -638,7 +638,7 @@ void radeon_draw_buffer(GLcontext *ctx, struct gl_framebuffer *fb)
 	struct radeon_renderbuffer *rrbDepth = NULL, *rrbStencil = NULL,
 		*rrbColor = NULL;
 	uint32_t offset = 0;
-       
+
 
 	if (!fb) {
 		/* this can happen during the initial context initialization */
@@ -650,7 +650,7 @@ void radeon_draw_buffer(GLcontext *ctx, struct gl_framebuffer *fb)
 		radeon->vtbl.fallback(ctx, RADEON_FALLBACK_DRAW_BUFFER, GL_TRUE);
 		return;
 	}
-		
+
 	/* Do this here, note core Mesa, since this function is called from
 	 * many places within the driver.
 	 */
@@ -737,7 +737,7 @@ void radeon_draw_buffer(GLcontext *ctx, struct gl_framebuffer *fb)
 		ctx->Driver.FrontFace(ctx, ctx->Polygon.FrontFace);
 	else
 		ctx->NewState |= _NEW_POLYGON;
-	
+
 	/*
 	 * Update depth test state
 	 */
@@ -751,7 +751,7 @@ void radeon_draw_buffer(GLcontext *ctx, struct gl_framebuffer *fb)
 	} else {
 		ctx->NewState |= (_NEW_DEPTH | _NEW_STENCIL);
 	}
-	
+
 	_mesa_reference_renderbuffer(&radeon->state.depth.rb, &rrbDepth->base);
 	_mesa_reference_renderbuffer(&radeon->state.color.rb, &rrbColor->base);
 	radeon->state.color.draw_offset = offset;
@@ -762,7 +762,7 @@ void radeon_draw_buffer(GLcontext *ctx, struct gl_framebuffer *fb)
 		ctx->Driver.Viewport(ctx, ctx->Viewport.X, ctx->Viewport.Y,
 				     ctx->Viewport.Width, ctx->Viewport.Height);
 	} else {
-	
+
 	}
 #endif
 	ctx->NewState |= _NEW_VIEWPORT;
@@ -814,7 +814,7 @@ void radeonDrawBuffer( GLcontext *ctx, GLenum mode )
 				radeon->dri.context->driDrawablePriv);
       }
 	}
-	
+
 	radeon_draw_buffer(ctx, ctx->DrawBuffer);
 }
 
@@ -836,7 +836,7 @@ void radeonReadBuffer( GLcontext *ctx, GLenum mode )
  */
 void radeonUpdatePageFlipping(radeonContextPtr radeon)
 {
-	struct radeon_framebuffer *rfb = radeon->dri.drawable->driverPrivate;
+	struct radeon_framebuffer *rfb = radeon_get_drawable(radeon)->driverPrivate;
 
 	rfb->pf_active = radeon->sarea->pfState;
 	rfb->pf_current_page = radeon->sarea->pfCurrentPage;
@@ -869,7 +869,6 @@ void radeon_viewport(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei he
 
 	old_viewport = ctx->Driver.Viewport;
 	ctx->Driver.Viewport = NULL;
-	radeon->dri.drawable = driContext->driDrawablePriv;
 	radeon_window_moved(radeon);
 	radeon_draw_buffer(ctx, radeon->glCtx->DrawBuffer);
 	ctx->Driver.Viewport = old_viewport;
@@ -962,7 +961,7 @@ static INLINE void radeonEmitAtoms(radeonContextPtr radeon, GLboolean dirty)
 			}
 		}
 	}
-   
+
 	COMMIT_BATCH();
 }
 
@@ -1032,7 +1031,7 @@ void radeonEmitState(radeonContextPtr radeon)
 	if (!radeon->cmdbuf.cs->cdw) {
 		if (RADEON_DEBUG & DEBUG_STATE)
 			fprintf(stderr, "Begin reemit state\n");
-		
+
 		radeonEmitAtoms(radeon, GL_FALSE);
 	}
 
@@ -1064,7 +1063,7 @@ void radeonFlush(GLcontext *ctx)
 		radeon->dma.flush( ctx );
 
 	radeonEmitState(radeon);
-   
+
 	if (radeon->cmdbuf.cs->cdw)
 		rcommonFlushCmdBuf(radeon, __FUNCTION__);
 
@@ -1073,8 +1072,8 @@ void radeonFlush(GLcontext *ctx)
 
 		if (screen->dri2.loader && (screen->dri2.loader->base.version >= 2)
 			&& (screen->dri2.loader->flushFrontBuffer != NULL)) {
-			(*screen->dri2.loader->flushFrontBuffer)(radeon->dri.drawable,
-						  radeon->dri.drawable->loaderPrivate);
+			__DRIdrawablePrivate * drawable = radeon_get_drawable(radeon);
+			(*screen->dri2.loader->flushFrontBuffer)(drawable, drawable->loaderPrivate);
 
 			/* Only clear the dirty bit if front-buffer rendering is no longer
 			 * enabled.  This is done so that the dirty bit can only be set in
@@ -1161,7 +1160,7 @@ int rcommonFlushCmdBuf(radeonContextPtr rmesa, const char *caller)
 	int ret;
 
 	radeonReleaseDmaRegion(rmesa);
-	
+
 	LOCK_HARDWARE(rmesa);
 	ret = rcommonFlushCmdBufLocked(rmesa, caller);
 	UNLOCK_HARDWARE(rmesa);
@@ -1223,7 +1222,7 @@ void rcommonInitCmdBuf(radeonContextPtr rmesa)
 	rmesa->cmdbuf.cs = radeon_cs_create(rmesa->cmdbuf.csm, size);
 	assert(rmesa->cmdbuf.cs != NULL);
 	rmesa->cmdbuf.size = size;
-	
+
 	if (!rmesa->radeonScreen->kernel_mm) {
 		radeon_cs_set_limit(rmesa->cmdbuf.cs, RADEON_GEM_DOMAIN_VRAM, rmesa->radeonScreen->texSize[0]);
 		radeon_cs_set_limit(rmesa->cmdbuf.cs, RADEON_GEM_DOMAIN_GTT, rmesa->radeonScreen->gartTextures.size);
@@ -1334,7 +1333,7 @@ void radeon_clear_tris(GLcontext *ctx, GLbitfield mask)
    unsigned int saved_active_texture;
 
    assert((mask & ~(TRI_CLEAR_COLOR_BITS | BUFFER_BIT_DEPTH |
-		    BUFFER_BIT_STENCIL)) == 0);   
+		    BUFFER_BIT_STENCIL)) == 0);
 
    _mesa_PushAttrib(GL_COLOR_BUFFER_BIT |
 		    GL_CURRENT_BIT |
@@ -1346,7 +1345,7 @@ void radeon_clear_tris(GLcontext *ctx, GLbitfield mask)
 		    GL_CURRENT_BIT);
    _mesa_PushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);
    saved_active_texture = ctx->Texture.CurrentUnit;
-  
+
   /* Disable existing GL state we don't want to apply to a clear. */
    _mesa_Disable(GL_ALPHA_TEST);
    _mesa_Disable(GL_BLEND);
@@ -1375,10 +1374,10 @@ void radeon_clear_tris(GLcontext *ctx, GLbitfield mask)
       saved_shader_program = ctx->Shader.CurrentProgram->Name;
       _mesa_UseProgramObjectARB(0);
    }
-   
+
    if (ctx->Texture._EnabledUnits != 0) {
       int i;
-      
+
       for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
 	 _mesa_ActiveTextureARB(GL_TEXTURE0 + i);
 	 _mesa_Disable(GL_TEXTURE_1D);
@@ -1394,14 +1393,14 @@ void radeon_clear_tris(GLcontext *ctx, GLbitfield mask)
 	 }
       }
    }
-  
+
 #if FEATURE_ARB_vertex_buffer_object
    _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
    _mesa_BindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
 #endif
 
    radeon_meta_set_passthrough_transform(rmesa);
-   
+
    for (i = 0; i < 4; i++) {
       color[i][0] = ctx->Color.ClearColor[0];
       color[i][1] = ctx->Color.ClearColor[1];
diff --git a/src/mesa/drivers/dri/radeon/radeon_common_context.c b/src/mesa/drivers/dri/radeon/radeon_common_context.c
index 622bb98..e996798 100644
--- a/src/mesa/drivers/dri/radeon/radeon_common_context.c
+++ b/src/mesa/drivers/dri/radeon/radeon_common_context.c
@@ -147,8 +147,6 @@ GLboolean radeonInitContext(radeonContextPtr radeon,
 	/* DRI fields */
 	radeon->dri.context = driContextPriv;
 	radeon->dri.screen = sPriv;
-	radeon->dri.drawable = NULL;
-	radeon->dri.readable = NULL;
 	radeon->dri.hwContext = driContextPriv->hHWContext;
 	radeon->dri.hwLock = &sPriv->pSAREA->lock;
 	radeon->dri.fd = sPriv->fd;
@@ -171,7 +169,7 @@ GLboolean radeonInitContext(radeonContextPtr radeon,
 			"IRQ's not enabled, falling back to %s: %d %d\n",
 			radeon->do_usleeps ? "usleeps" : "busy waits",
 			fthrottle_mode, radeon->radeonScreen->irq);
-	
+
         radeon->texture_depth = driQueryOptioni (&radeon->optionCache,
 					        "texture_depth");
         if (radeon->texture_depth == DRI_CONF_TEXTURE_DEPTH_FB)
@@ -217,7 +215,7 @@ void radeonDestroyContext(__DRIcontextPrivate *driContextPriv )
 		radeon_firevertices(radeon);
 		_mesa_make_current(NULL, NULL, NULL);
 	}
-	
+
 	assert(radeon);
 	if (radeon) {
 
@@ -233,14 +231,11 @@ void radeonDestroyContext(__DRIcontextPrivate *driContextPriv )
 		_tnl_DestroyContext( radeon->glCtx );
 		_vbo_DestroyContext( radeon->glCtx );
 		_swrast_DestroyContext( radeon->glCtx );
-	
-		radeonDestroyBuffer(radeon->dri.drawable);
-		radeonDestroyBuffer(radeon->dri.readable);
 
 		/* free atom list */
 		/* free the Mesa context */
 		_mesa_destroy_context(radeon->glCtx);
-		
+
 		/* _mesa_destroy_context() might result in calls to functions that
 		 * depend on the DriverCtx, so don't set it to NULL before.
 		 *
@@ -248,7 +243,7 @@ void radeonDestroyContext(__DRIcontextPrivate *driContextPriv )
 		 */
 		/* free the option cache */
 		driDestroyOptionCache(&radeon->optionCache);
-		
+
 		rcommonDestroyCmdBuf(radeon);
 
 		radeon_destroy_atom_list(radeon);
@@ -346,12 +341,12 @@ radeon_make_renderbuffer_current(radeonContextPtr radeon,
 	int size = 4096*4096*4;
 	/* if radeon->fake */
 	struct radeon_renderbuffer *rb;
-	
+
 	if (radeon->radeonScreen->kernel_mm) {
 		radeon_make_kernel_renderbuffer_current(radeon, draw);
 		return;
 	}
-			
+
 
 	if ((rb = (void *)draw->base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer)) {
 		if (!rb->bo) {
@@ -440,7 +435,7 @@ radeon_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable)
 
 	if (RADEON_DEBUG & DEBUG_DRI)
 	    fprintf(stderr, "enter %s, drawable %p\n", __func__, drawable);
-	
+
 	draw = drawable->driverPrivate;
 	screen = context->driScreenPriv;
 	radeon = (radeonContextPtr) context->driverPrivate;
@@ -493,7 +488,7 @@ radeon_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable)
 			attachments[i++] = __DRI_BUFFER_DEPTH;
 		if (radeon_get_renderbuffer(&draw->base, BUFFER_STENCIL))
 			attachments[i++] = __DRI_BUFFER_STENCIL;
-	
+
 		buffers = (*screen->dri2.loader->getBuffers)(drawable,
 								 &drawable->w,
 								 &drawable->h,
@@ -591,7 +586,7 @@ radeon_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable)
 
 				fprintf(stderr, "failed to attach %s %d\n",
 					regname, buffers[i].name);
-				
+
 			}
 		}
 
@@ -648,7 +643,7 @@ GLboolean radeonMakeCurrent(__DRIcontextPrivate * driContextPriv,
 	drfb = driDrawPriv->driverPrivate;
 	readfb = driReadPriv->driverPrivate;
 
-	if (driContextPriv->driScreenPriv->dri2.enabled) {    
+	if (driContextPriv->driScreenPriv->dri2.enabled) {
 		radeon_update_renderbuffers(driContextPriv, driDrawPriv);
 		if (driDrawPriv != driReadPriv)
 			radeon_update_renderbuffers(driContextPriv, driReadPriv);
@@ -664,9 +659,6 @@ GLboolean radeonMakeCurrent(__DRIcontextPrivate * driContextPriv,
 	if (RADEON_DEBUG & DEBUG_DRI)
 	     fprintf(stderr, "%s ctx %p dfb %p rfb %p\n", __FUNCTION__, radeon->glCtx, drfb, readfb);
 
-	if (radeon->dri.readable != driReadPriv)
-		radeon->dri.readable = driReadPriv;
-
 	driUpdateFramebufferSize(radeon->glCtx, driDrawPriv);
 	if (driReadPriv != driDrawPriv)
 		driUpdateFramebufferSize(radeon->glCtx, driReadPriv);
@@ -676,29 +668,25 @@ GLboolean radeonMakeCurrent(__DRIcontextPrivate * driContextPriv,
 	_mesa_update_state(radeon->glCtx);
 
 	if (radeon->glCtx->DrawBuffer == &drfb->base) {
-
-		if (radeon->dri.drawable != driDrawPriv) {
-			if (driDrawPriv->swap_interval == (unsigned)-1) {
-				int i;
-				driDrawPriv->vblFlags =
-					(radeon->radeonScreen->irq != 0)
-					? driGetDefaultVBlankFlags(&radeon->
-								   optionCache)
-					: VBLANK_FLAG_NO_IRQ;
-				    
-				driDrawableInitVBlank(driDrawPriv);
-				drfb->vbl_waited = driDrawPriv->vblSeq;
-
-				for (i = 0; i < 2; i++) {
-					if (drfb->color_rb[i])
-						drfb->color_rb[i]->vbl_pending = driDrawPriv->vblSeq;
-				}
-				    
+		if (driDrawPriv->swap_interval == (unsigned)-1) {
+			int i;
+			driDrawPriv->vblFlags =
+				(radeon->radeonScreen->irq != 0)
+				? driGetDefaultVBlankFlags(&radeon->
+							   optionCache)
+				: VBLANK_FLAG_NO_IRQ;
+
+			driDrawableInitVBlank(driDrawPriv);
+			drfb->vbl_waited = driDrawPriv->vblSeq;
+
+			for (i = 0; i < 2; i++) {
+				if (drfb->color_rb[i])
+					drfb->color_rb[i]->vbl_pending = driDrawPriv->vblSeq;
 			}
-			radeon->dri.drawable = driDrawPriv;
-			
-			radeon_window_moved(radeon);
+
 		}
+
+		radeon_window_moved(radeon);
 		radeon_draw_buffer(radeon->glCtx, &drfb->base);
 	}
 
diff --git a/src/mesa/drivers/dri/radeon/radeon_common_context.h b/src/mesa/drivers/dri/radeon/radeon_common_context.h
index af05f4a..e995062 100644
--- a/src/mesa/drivers/dri/radeon/radeon_common_context.h
+++ b/src/mesa/drivers/dri/radeon/radeon_common_context.h
@@ -117,7 +117,7 @@ struct radeon_framebuffer
 
 };
 
- 
+
 struct radeon_colorbuffer_state {
 	GLuint clear;
 	int roundEnable;
@@ -346,16 +346,6 @@ struct radeon_dri_mirror {
 	__DRIcontextPrivate *context;	/* DRI context */
 	__DRIscreenPrivate *screen;	/* DRI screen */
 
-   /**
-    * DRI drawable bound to this context for drawing.
-    */
-	__DRIdrawablePrivate *drawable;
-
-   /**
-    * DRI drawable bound to this context for reading.
-    */
-	__DRIdrawablePrivate *readable;
-
 	drm_context_t hwContext;
 	drm_hw_lock_t *hwLock;
 	int fd;
@@ -416,7 +406,7 @@ struct radeon_cmdbuf {
 struct radeon_context {
    GLcontext *glCtx;
    radeonScreenPtr radeonScreen;	/* Screen private DRI data */
-  
+
    /* Texture object bookkeeping
     */
    int                   texture_depth;
@@ -458,7 +448,7 @@ struct radeon_context {
    driOptionCache optionCache;
 
    struct radeon_cmdbuf cmdbuf;
-	
+
   drm_clip_rect_t fboRect;
   GLboolean constant_cliprect; /* use for FBO or DRI2 rendering */
   GLboolean front_cliprects;
@@ -507,6 +497,17 @@ struct radeon_context {
 
 #define RADEON_CONTEXT(glctx) ((radeonContextPtr)(ctx->DriverCtx))
 
+static inline __DRIdrawablePrivate* radeon_get_drawable(radeonContextPtr radeon)
+{
+	return radeon->dri.context->driDrawablePriv;
+}
+
+static inline __DRIdrawablePrivate* radeon_get_readable(radeonContextPtr radeon)
+{
+	return radeon->dri.context->driReadablePriv;
+}
+
+
 /**
  * This function takes a float and packs it into a uint32_t
  */
diff --git a/src/mesa/drivers/dri/radeon/radeon_lock.c b/src/mesa/drivers/dri/radeon/radeon_lock.c
index fe19218..5774f7e 100644
--- a/src/mesa/drivers/dri/radeon/radeon_lock.c
+++ b/src/mesa/drivers/dri/radeon/radeon_lock.c
@@ -58,8 +58,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  */
 void radeonGetLock(radeonContextPtr rmesa, GLuint flags)
 {
-	__DRIdrawablePrivate *const drawable = rmesa->dri.drawable;
-	__DRIdrawablePrivate *const readable = rmesa->dri.readable;
+	__DRIdrawablePrivate *const drawable = radeon_get_drawable(rmesa);
+	__DRIdrawablePrivate *const readable = radeon_get_readable(rmesa);
 	__DRIscreenPrivate *sPriv = rmesa->dri.screen;
 
 	assert(drawable != NULL);
@@ -95,8 +95,8 @@ void radeon_lock_hardware(radeonContextPtr radeon)
 	struct radeon_framebuffer *rfb = NULL;
 	struct radeon_renderbuffer *rrb = NULL;
 
-	if (radeon->dri.drawable) {
-		rfb = radeon->dri.drawable->driverPrivate;
+	if (radeon_get_drawable(radeon)) {
+		rfb = radeon_get_drawable(radeon)->driverPrivate;
 
 		if (rfb)
 			rrb = radeon_get_renderbuffer(&rfb->base,
-- 
1.6.0.4

------------------------------------------------------------------------------
Register Now for Creativity and Technology (CaT), June 3rd, NYC. CaT
is a gathering of tech-side developers & brand creativity professionals. Meet
the minds behind Google Creative Lab, Visual Complexity, Processing, & 
iPhoneDevCamp asthey present alongside digital heavyweights like Barbarian
Group, R/GA, & Big Spaceship. http://www.creativitycat.com 
--
_______________________________________________
Dri-devel mailing list
Dri-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/dri-devel

Reply via email to