summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBrian <brian.paul@tungstengraphics.com>2007-12-05 14:51:08 -0700
committerBrian <brian.paul@tungstengraphics.com>2007-12-05 14:51:08 -0700
commit9df0a6dd9c43be0ee5c300e161a20b2f98acef2d (patch)
treeab87f53f9cd2716db23f5078351409e738c9f862 /src
parent04516cfcaf15589768c973231d8c317e851a78cb (diff)
added B8G8R8A8 support and improved pixel format selection when doing remote display to X server of different endianness.
Diffstat (limited to 'src')
-rw-r--r--src/mesa/pipe/xlib/xm_api.c10
-rw-r--r--src/mesa/pipe/xlib/xm_buffer.c30
-rw-r--r--src/mesa/pipe/xlib/xm_surface.c51
-rw-r--r--src/mesa/pipe/xlib/xmesaP.h6
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 e456ea2fd4..f87d72d0c8 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 71a2003e6d..449e90184b 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 2394563095..58ca2e7fb3 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 ba0ccdbcec..a067dfd3e3 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