From 9df0a6dd9c43be0ee5c300e161a20b2f98acef2d Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 5 Dec 2007 14:51:08 -0700 Subject: [PATCH] added B8G8R8A8 support and improved pixel format selection when doing remote display to X server of different endianness. --- src/mesa/pipe/xlib/xm_api.c | 10 +++++--- src/mesa/pipe/xlib/xm_buffer.c | 30 ++++++++++++++++++++++-- src/mesa/pipe/xlib/xm_surface.c | 51 +++++++++++++++++++++++++++++++++++++++-- src/mesa/pipe/xlib/xmesaP.h | 6 ++++- 4 files changed, 89 insertions(+), 8 deletions(-) diff --git a/src/mesa/pipe/xlib/xm_api.c b/src/mesa/pipe/xlib/xm_api.c index e456ea2..f87d72d 100644 --- a/src/mesa/pipe/xlib/xm_api.c +++ b/src/mesa/pipe/xlib/xm_api.c @@ -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; diff --git a/src/mesa/pipe/xlib/xm_buffer.c b/src/mesa/pipe/xlib/xm_buffer.c index 71a2003..449e901 100644 --- a/src/mesa/pipe/xlib/xm_buffer.c +++ b/src/mesa/pipe/xlib/xm_buffer.c @@ -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; diff --git a/src/mesa/pipe/xlib/xm_surface.c b/src/mesa/pipe/xlib/xm_surface.c index 2394563..58ca2e7 100644 --- a/src/mesa/pipe/xlib/xm_surface.c +++ b/src/mesa/pipe/xlib/xm_surface.c @@ -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: diff --git a/src/mesa/pipe/xlib/xmesaP.h b/src/mesa/pipe/xlib/xmesaP.h index ba0ccdb..a067dfd 100644 --- a/src/mesa/pipe/xlib/xmesaP.h +++ b/src/mesa/pipe/xlib/xmesaP.h @@ -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 -- 2.7.4