mesa: Branch 'master'

Brian Paul brianp at kemper.freedesktop.org
Sat Mar 24 00:01:39 UTC 2007


 src/mesa/drivers/x11/xm_api.c |   12 +++++++-----
 src/mesa/drivers/x11/xmesaP.h |    1 +
 src/mesa/main/renderbuffer.c  |   32 ++++++++++++++++++++++++++++++++
 src/mesa/main/renderbuffer.h  |    3 +++
 4 files changed, 43 insertions(+), 5 deletions(-)

New commits:
diff-tree 8e1c3bd0b4c599bae5b64cd51cec1d74266f30fb (from 654a3084398c5ab3ac1491bcdc5703221a268d03)
Author: Brian <brian at yutani.localnet.net>
Date:   Fri Mar 23 18:01:31 2007 -0600

    Implement alpha buffer copy for SwapBuffers().
    
    Nicolai writes:
    When the pixmap pixel format has no alpha channel, the x11 driver
    (software rendering) adds a wrapped alpha channel on request.
    
    During SwapBuffers, this alpha channel is not copied from back to
    front, which means that the front buffer doesn't really contain the
    contents that the back buffer previously contained.
    
    A subsequent glReadPixels from the front buffer will return an
    incorrect result. The following patch attempts to fix this.

diff --git a/src/mesa/drivers/x11/xm_api.c b/src/mesa/drivers/x11/xm_api.c
index b513dc8..24b19d8 100644
--- a/src/mesa/drivers/x11/xm_api.c
+++ b/src/mesa/drivers/x11/xm_api.c
@@ -363,7 +363,6 @@ static XMesaBuffer
 create_xmesa_buffer(XMesaDrawable d, BufferType type,
                     XMesaVisual vis, XMesaColormap cmap)
 {
-   GLboolean swAlpha;
    XMesaBuffer b;
 
    ASSERT(type == WINDOW || type == PIXMAP || type == PBUFFER);
@@ -421,10 +420,10 @@ create_xmesa_buffer(XMesaDrawable d, Buf
       /* Visual has alpha, but pixel format doesn't support it.
        * We'll use an alpha renderbuffer wrapper.
        */
-      swAlpha = GL_TRUE;
+      b->swAlpha = GL_TRUE;
    }
    else {
-      swAlpha = GL_FALSE;
+      b->swAlpha = GL_FALSE;
    }
 
    /*
@@ -435,9 +434,9 @@ create_xmesa_buffer(XMesaDrawable d, Buf
                                 vis->mesa_visual.haveDepthBuffer,
                                 vis->mesa_visual.haveStencilBuffer,
                                 vis->mesa_visual.haveAccumBuffer,
-                                swAlpha,
+                                b->swAlpha,
                                 vis->mesa_visual.numAuxBuffers > 0 );
-   
+
    /* insert buffer into linked list */
    b->Next = XMesaBufferList;
    XMesaBufferList = b;
@@ -2211,6 +2210,9 @@ void XMesaSwapBuffers( XMesaBuffer b )
 		      );
          /*_glthread_UNLOCK_MUTEX(_xmesa_lock);*/
       }
+
+      if (b->swAlpha)
+         _mesa_copy_soft_alpha_renderbuffers(ctx, &b->mesa_buffer);
    }
 #if !defined(XFree86Server)
    XSync( b->xm_visual->display, False );
diff --git a/src/mesa/drivers/x11/xmesaP.h b/src/mesa/drivers/x11/xmesaP.h
index 5516031..85cb6b6 100644
--- a/src/mesa/drivers/x11/xmesaP.h
+++ b/src/mesa/drivers/x11/xmesaP.h
@@ -224,6 +224,7 @@ struct xmesa_buffer {
    GLint db_mode;		/* 0 = single buffered */
 				/* BACK_PIXMAP = use Pixmap for back buffer */
 				/* BACK_XIMAGE = use XImage for back buffer */
+   GLboolean swAlpha;
 
    GLuint shm;			/* X Shared Memory extension status:	*/
 				/*    0 = not available			*/
diff --git a/src/mesa/main/renderbuffer.c b/src/mesa/main/renderbuffer.c
index e387c42..ded0063 100644
--- a/src/mesa/main/renderbuffer.c
+++ b/src/mesa/main/renderbuffer.c
@@ -1435,6 +1435,17 @@ put_mono_values_alpha8(GLcontext *ctx, s
 }
 
 
+static void
+copy_buffer_alpha8(struct gl_renderbuffer* dst, struct gl_renderbuffer* src)
+{
+   ASSERT(dst->_ActualFormat == GL_ALPHA8);
+   ASSERT(src->_ActualFormat == GL_ALPHA8);
+   ASSERT(dst->Width == src->Width);
+   ASSERT(dst->Height == src->Height);
+
+   _mesa_memcpy(dst->Data, src->Data, dst->Width * dst->Height * sizeof(GLubyte));
+}
+
 
 /**********************************************************************/
 /**********************************************************************/
@@ -1766,6 +1777,27 @@ _mesa_add_alpha_renderbuffers(GLcontext 
 
 
 /**
+ * For framebuffers that use a software alpha channel wrapper
+ * created by _mesa_add_alpha_renderbuffer or _mesa_add_soft_renderbuffers,
+ * copy the back buffer alpha channel into the front buffer alpha channel.
+ */
+void
+_mesa_copy_soft_alpha_renderbuffers(GLcontext *ctx, struct gl_framebuffer *fb)
+{
+   if (fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer &&
+       fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer)
+      copy_buffer_alpha8(fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer,
+                         fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer);
+
+
+   if (fb->Attachment[BUFFER_FRONT_RIGHT].Renderbuffer &&
+       fb->Attachment[BUFFER_BACK_RIGHT].Renderbuffer)
+      copy_buffer_alpha8(fb->Attachment[BUFFER_FRONT_RIGHT].Renderbuffer,
+                         fb->Attachment[BUFFER_BACK_RIGHT].Renderbuffer);
+}
+
+
+/**
  * Add a software-based depth renderbuffer to the given framebuffer.
  * This is a helper routine for device drivers when creating a
  * window system framebuffer (not a user-created render/framebuffer).
diff --git a/src/mesa/main/renderbuffer.h b/src/mesa/main/renderbuffer.h
index e1a0a55..e5f1147 100644
--- a/src/mesa/main/renderbuffer.h
+++ b/src/mesa/main/renderbuffer.h
@@ -64,6 +64,9 @@ _mesa_add_alpha_renderbuffers(GLcontext 
                               GLboolean frontLeft, GLboolean backLeft,
                               GLboolean frontRight, GLboolean backRight);
 
+extern void
+_mesa_copy_soft_alpha_renderbuffers(GLcontext *ctx, struct gl_framebuffer *fb);
+
 extern GLboolean
 _mesa_add_depth_renderbuffer(GLcontext *ctx, struct gl_framebuffer *fb,
                              GLuint depthBits);



More information about the mesa-commit mailing list