added B8G8R8A8 support and improved pixel format selection when doing remote display...
authorBrian <brian.paul@tungstengraphics.com>
Wed, 5 Dec 2007 21:51:08 +0000 (14:51 -0700)
committerBrian <brian.paul@tungstengraphics.com>
Wed, 5 Dec 2007 21:51:08 +0000 (14:51 -0700)
src/mesa/pipe/xlib/xm_api.c
src/mesa/pipe/xlib/xm_buffer.c
src/mesa/pipe/xlib/xm_surface.c
src/mesa/pipe/xlib/xmesaP.h

index e456ea2..f87d72d 100644 (file)
@@ -329,7 +329,7 @@ create_xmesa_buffer(XMesaDrawable d, BufferType type,
    /*
     * Front renderbuffer
     */
-   b->frontxrb = xmesa_create_renderbuffer(winsys, 0, &vis->mesa_visual, GL_FALSE);
+   b->frontxrb = xmesa_create_renderbuffer(winsys, 0, vis, GL_FALSE);
    if (!b->frontxrb) {
       _mesa_free(b);
       return NULL;
@@ -343,7 +343,7 @@ create_xmesa_buffer(XMesaDrawable d, BufferType type,
     * Back renderbuffer
     */
    if (vis->mesa_visual.doubleBufferMode) {
-      b->backxrb = xmesa_create_renderbuffer(winsys, 0, &vis->mesa_visual, GL_TRUE);
+      b->backxrb = xmesa_create_renderbuffer(winsys, 0, vis, GL_TRUE);
       if (!b->backxrb) {
          /* XXX free front xrb too */
          _mesa_free(b);
@@ -365,7 +365,11 @@ create_xmesa_buffer(XMesaDrawable d, BufferType type,
       /* Visual has alpha, but pixel format doesn't support it.
        * We'll use an alpha renderbuffer wrapper.
        */
-      b->swAlpha = GL_TRUE;
+#if 0
+      b->swAlpha = GL_TRUE; /* don't do any renderbuffer wrapping */
+#else
+      b->swAlpha = GL_FALSE;
+#endif
    }
    else {
       b->swAlpha = GL_FALSE;
index 71a2003..449e901 100644 (file)
@@ -163,6 +163,16 @@ alloc_back_shm_ximage(XMesaBuffer b, GLuint width, GLuint height)
 #endif
 
 
+/**
+ * \return LSBFirst or MSBFirst
+ */
+static int host_byte_order( void )
+{
+   int i = 1;
+   char *cptr = (char *) &i;
+   return (*cptr==1) ? LSBFirst : MSBFirst;
+}
+
 
 /**
  * Setup an off-screen pixmap or Ximage to use as the back buffer.
@@ -377,9 +387,11 @@ xmesa_alloc_back_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
  */
 struct xmesa_renderbuffer *
 xmesa_create_renderbuffer(struct pipe_winsys *winsys,
-                          GLuint name, const GLvisual *visual,
+                          GLuint name, XMesaVisual xmvis,
                           GLboolean backBuffer)
 {
+   const GLvisual *visual = &xmvis->mesa_visual;
+   int byteOrder = ImageByteOrder(xmvis->display); /* LSBFirst or MSBFirst */
    struct xmesa_renderbuffer *xrb = CALLOC_STRUCT(xmesa_renderbuffer);
    if (xrb) {
       GLuint name = 0;
@@ -402,7 +414,21 @@ xmesa_create_renderbuffer(struct pipe_winsys *winsys,
          xrb->St.Base.GreenBits = visual->greenBits;
          xrb->St.Base.BlueBits = visual->blueBits;
          xrb->St.Base.AlphaBits = visual->alphaBits;
-         pipeFormat = PIPE_FORMAT_U_A8_R8_G8_B8;
+         if (visual->redMask   == 0xff0000 &&
+             visual->greenMask == 0x00ff00 &&
+             visual->blueMask  == 0x0000ff) {
+            if (host_byte_order() != byteOrder) {
+               pipeFormat = PIPE_FORMAT_U_B8_G8_R8_A8;
+               /*printf("Using format B8_G8_R8_A8 (LE dpy)\n");*/
+            }
+            else {
+               pipeFormat = PIPE_FORMAT_U_A8_R8_G8_B8;
+               /*printf("Using format A8_R8_G8_B8 (BE dpy)\n");*/
+            }
+         }
+         else {
+            assert(0);
+         }
       }
       else {
          xrb->St.Base.InternalFormat = GL_COLOR_INDEX;
index 2394563..58ca2e7 100644 (file)
@@ -256,7 +256,7 @@ xmesa_put_tile(struct pipe_context *pipe, struct pipe_surface *ps,
       /* put to ximage */
       ximage = xms->ximage;
       char *dst;
-      int i;
+      uint i;
 
       /* this could be optimized/simplified */
       switch (ps->format) {
@@ -353,7 +353,7 @@ xmesa_get_tile_rgba(struct pipe_context *pipe, struct pipe_surface *ps,
             for (j = 0; j < w; j++) {
                uint pix = src[j];
                ubyte r = ((pix >> 16) & 0xff);
-               ubyte g = ((pix >> 8)  & 0xff);
+               ubyte g = ((pix >>  8) & 0xff);
                ubyte b = ( pix        & 0xff);
                ubyte a = ((pix >> 24) & 0xff);
                p[0] = UBYTE_TO_FLOAT(r);
@@ -367,6 +367,29 @@ xmesa_get_tile_rgba(struct pipe_context *pipe, struct pipe_surface *ps,
          }
       }
       break;
+   case PIPE_FORMAT_U_B8_G8_R8_A8:
+      {
+         const uint *src
+            = (uint *) (ximage->data + y * ximage->bytes_per_line + x * 4);
+         for (i = 0; i < h; i++) {
+            float *p = pRow;
+            for (j = 0; j < w; j++) {
+               uint pix = src[j];
+               ubyte r = ((pix >>  8) & 0xff);
+               ubyte g = ((pix >> 16) & 0xff);
+               ubyte b = ((pix >> 24) & 0xff);
+               ubyte a = ( pix        & 0xff);
+               p[0] = UBYTE_TO_FLOAT(r);
+               p[1] = UBYTE_TO_FLOAT(g);
+               p[2] = UBYTE_TO_FLOAT(b);
+               p[3] = UBYTE_TO_FLOAT(a);
+               p += 4;
+            }
+            src += ximage->width;
+            pRow += 4 * w0;
+         }
+      }
+      break;
    case PIPE_FORMAT_U_R5_G6_B5:
       {
          ushort *src
@@ -390,6 +413,7 @@ xmesa_get_tile_rgba(struct pipe_context *pipe, struct pipe_surface *ps,
       }
       break;
    default:
+      fprintf(stderr, "Bad format in xmesa_get_tile_rgba()\n");
       assert(0);
    }
 
@@ -461,6 +485,27 @@ xmesa_put_tile_rgba(struct pipe_context *pipe, struct pipe_surface *ps,
          }
       }
       break;
+   case PIPE_FORMAT_U_B8_G8_R8_A8:
+      {
+         uint *dst
+            = (uint *) (ximage->data + y * ximage->bytes_per_line + x * 4);
+         const float *pRow = pixels;
+         for (i = 0; i < h; i++) {
+            const float *p = pRow;
+            for (j = 0; j < w; j++) {
+               ubyte r, g, b, a;
+               UNCLAMPED_FLOAT_TO_UBYTE(r, p[0]);
+               UNCLAMPED_FLOAT_TO_UBYTE(g, p[1]);
+               UNCLAMPED_FLOAT_TO_UBYTE(b, p[2]);
+               UNCLAMPED_FLOAT_TO_UBYTE(a, p[3]);
+               dst[j] = PACK_8B8G8R8A(r, g, b, a);
+               p += 4;
+            }
+            dst += ximage->width;
+            pRow += 4 * w0;
+         }
+      }
+      break;
    case PIPE_FORMAT_U_R5_G6_B5:
       {
          ushort *dst =
@@ -483,6 +528,7 @@ xmesa_put_tile_rgba(struct pipe_context *pipe, struct pipe_surface *ps,
       break;
       
    default:
+      fprintf(stderr, "Bad format in xmesa_put_tile_rgba()\n");
       assert(0);
    }
 
@@ -689,6 +735,7 @@ xmesa_clear(struct pipe_context *pipe, struct pipe_surface *ps, uint value)
          clear_16bit_ximage_surface(pipe, ps, value);
          break;
       case PIPE_FORMAT_U_A8_R8_G8_B8:
+      case PIPE_FORMAT_U_B8_G8_R8_A8:
          clear_32bit_ximage_surface(pipe, ps, value);
          break;
       default:
index ba0ccdb..a067dfd 100644 (file)
@@ -286,6 +286,10 @@ struct xmesa_buffer {
  */
 #define PACK_8B8G8R( R, G, B )   ( ((B) << 16) | ((G) << 8) | (R) )
 
+#define PACK_8B8G8R8A( R, G, B, A ) \
+        ( ((B) << 24) | ((G) << 16) | ((R) << 8) | (A) )
+
+
 
 
 /**
@@ -448,7 +452,7 @@ extern const int xmesa_kernel1[16];
 
 extern struct xmesa_renderbuffer *
 xmesa_create_renderbuffer(struct pipe_winsys *winsys,
-                          GLuint name, const GLvisual *visual,
+                          GLuint name, XMesaVisual xmvis,
                           GLboolean backBuffer);
 
 extern void