diff options
author | Brian <[email protected]> | 2007-11-01 12:08:01 -0600 |
---|---|---|
committer | Brian <[email protected]> | 2007-11-01 12:08:01 -0600 |
commit | ba0b1bdc332295743874c2e1fa3a2fc0528c70ac (patch) | |
tree | 5876aa5aae572d7fa9bb39d059c49c2d4bb81a05 | |
parent | a33308898666e89f2443e7eb4f1d09ae792b620a (diff) |
reimplement xmesa_put_tile_rgba() w/out span funcs
-rw-r--r-- | src/mesa/pipe/xlib/xm_surface.c | 99 |
1 files changed, 78 insertions, 21 deletions
diff --git a/src/mesa/pipe/xlib/xm_surface.c b/src/mesa/pipe/xlib/xm_surface.c index 94fc2cae68b..9ca67574892 100644 --- a/src/mesa/pipe/xlib/xm_surface.c +++ b/src/mesa/pipe/xlib/xm_surface.c @@ -248,34 +248,91 @@ void xmesa_put_tile_rgba(struct pipe_context *pipe, struct pipe_surface *ps, uint x, uint y, uint w, uint h, const float *p) { + const uint x0 = x, y0 = y; struct xmesa_surface *xms = xmesa_surface(ps); - struct xmesa_renderbuffer *xrb = xms->xrb; + XMesaImage *ximage; + uint i, j; - if (xrb) { - /* this is a front/back color buffer */ - GLubyte tmp[MAX_WIDTH * 4]; - GLuint i, j; - uint w0 = w; - GET_CURRENT_CONTEXT(ctx); - CLIP_TILE; - FLIP(y); - for (i = 0; i < h; i++) { - for (j = 0; j < w * 4; j++) { - UNCLAMPED_FLOAT_TO_UBYTE(tmp[j], p[j]); + CLIP_TILE; + + if (!xms->drawable && !xms->ximage) { + /* not an X surface */ + softpipe_put_tile_rgba(pipe, ps, x, y, w, h, p); + return; + } + + if (!xms->ximage) { + /* create temp XImage */ + char *data = (char *) malloc(w * h * 4); +#ifdef XFree86Server + ximage = XMesaCreateImage(GET_VISUAL_DEPTH(v), w, h, data); +#else + XVisualInfo *visinfo = xms->xrb->Parent->xm_visual->visinfo; + ximage = XCreateImage(xms->display, + visinfo->visual, + visinfo->depth, + ZPixmap, 0, /* format, offset */ + data, /* data */ + w, h, /* width, height */ + 32, /* bitmap_pad */ + 0); /* bytes_per_line */ +#endif + x = y = 0; + } + else { + ximage = xms->ximage; + } + + /* convert floats to ximage's format */ + switch (ps->format) { + case PIPE_FORMAT_U_A8_R8_G8_B8: + { + uint *dst + = (uint *) (ximage->data + y * ximage->bytes_per_line + x * 4); + for (i = 0; i < h; i++) { + 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_8A8R8G8B(r, g, b, a); + p += 4; + } + dst += ximage->width; } - xrb->St.Base.PutRow(ctx, &xrb->St.Base, w, x, y - i, tmp, NULL); - p += w0 * 4; } -#if 0 /* debug: flush */ + break; + case PIPE_FORMAT_U_R5_G6_B5: { - XMesaContext xm = XMESA_CONTEXT(ctx); - XSync(xm->display, 0); + ushort *dst = + (ushort *) (ximage->data + y * ximage->bytes_per_line + x * 2); + for (i = 0; i < h; i++) { + for (j = 0; j < w; j++) { + ubyte r, g, b; + UNCLAMPED_FLOAT_TO_UBYTE(r, p[0]); + UNCLAMPED_FLOAT_TO_UBYTE(g, p[1]); + UNCLAMPED_FLOAT_TO_UBYTE(b, p[2]); + dst[j] = PACK_5R6G5B(r, g, b); + p += 4; + } + dst += ximage->width; + } } -#endif + break; + + default: + assert(0); } - else { - /* other softpipe surface */ - softpipe_put_tile_rgba(pipe, ps, x, y, w, h, p); + + if (!xms->ximage) { + /* send XImage data to pixmap */ + XPutImage(xms->display, xms->drawable, xms->gc, + ximage, 0, 0, x0, y0, w, h); + /* clean-up */ + free(ximage->data); + ximage->data = NULL; + XMesaDestroyImage(ximage); } } |