From a33308898666e89f2443e7eb4f1d09ae792b620a Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 1 Nov 2007 11:23:50 -0600 Subject: [PATCH] implement get/put_tile() for xlib driver --- src/mesa/pipe/softpipe/sp_surface.c | 10 +-- src/mesa/pipe/softpipe/sp_surface.h | 9 +++ src/mesa/pipe/xlib/xm_surface.c | 119 ++++++++++++++++++++++++++++ 3 files changed, 132 insertions(+), 6 deletions(-) diff --git a/src/mesa/pipe/softpipe/sp_surface.c b/src/mesa/pipe/softpipe/sp_surface.c index 3aa72ef569b..ccaf38de3e4 100644 --- a/src/mesa/pipe/softpipe/sp_surface.c +++ b/src/mesa/pipe/softpipe/sp_surface.c @@ -502,9 +502,8 @@ softpipe_get_tex_surface(struct pipe_context *pipe, /** * Move raw block of pixels from surface to user memory. */ -static void -softpipe_get_tile(struct pipe_context *pipe, - struct pipe_surface *ps, +void +softpipe_get_tile(struct pipe_context *pipe, struct pipe_surface *ps, uint x, uint y, uint w, uint h, void *p, int dst_stride) { @@ -535,9 +534,8 @@ softpipe_get_tile(struct pipe_context *pipe, /** * Move raw block of pixels from user memory to surface. */ -static void -softpipe_put_tile(struct pipe_context *pipe, - struct pipe_surface *ps, +void +softpipe_put_tile(struct pipe_context *pipe, struct pipe_surface *ps, uint x, uint y, uint w, uint h, const void *p, int src_stride) { diff --git a/src/mesa/pipe/softpipe/sp_surface.h b/src/mesa/pipe/softpipe/sp_surface.h index 7e08ce7a2b3..cf87e1a92ce 100644 --- a/src/mesa/pipe/softpipe/sp_surface.h +++ b/src/mesa/pipe/softpipe/sp_surface.h @@ -45,6 +45,15 @@ softpipe_get_tex_surface(struct pipe_context *pipe, unsigned face, unsigned level, unsigned zslice); +extern void +softpipe_get_tile(struct pipe_context *pipe, struct pipe_surface *ps, + uint x, uint y, uint w, uint h, void *p, int dst_stride); + +extern void +softpipe_put_tile(struct pipe_context *pipe, struct pipe_surface *ps, + uint x, uint y, uint w, uint h, + const void *p, int src_stride); + extern void softpipe_get_tile_rgba(struct pipe_context *pipe, struct pipe_surface *ps, diff --git a/src/mesa/pipe/xlib/xm_surface.c b/src/mesa/pipe/xlib/xm_surface.c index a5e0f794945..94fc2cae68b 100644 --- a/src/mesa/pipe/xlib/xm_surface.c +++ b/src/mesa/pipe/xlib/xm_surface.c @@ -70,19 +70,138 @@ xmesa_rb(struct pipe_surface *ps) #define FLIP(Y) Y = xrb->St.Base.Height - (Y) - 1; +/** + * Return raw pixels from pixmap or XImage. + */ void xmesa_get_tile(struct pipe_context *pipe, struct pipe_surface *ps, uint x, uint y, uint w, uint h, void *p, int dst_stride) { + struct xmesa_surface *xms = xmesa_surface(ps); + XMesaImage *ximage = NULL; + ubyte *dst = (ubyte *) p; + uint i; + + if (!xms->drawable && !xms->ximage) { + /* not an X surface */ + softpipe_get_tile(pipe, ps, x, y, w, h, p, dst_stride); + return; + } + + if (!xms->ximage) { + /* XImage = pixmap data */ + assert(xms->drawable); + ximage = XGetImage(xms->display, xms->drawable, x, y, w, h, + AllPlanes, ZPixmap); + x = y = 0; + } + else { + ximage = xms->ximage; + } + + switch (ps->format) { + case PIPE_FORMAT_U_A8_R8_G8_B8: + if (!dst_stride) { + dst_stride = w * 4; + } + for (i = 0; i < h; i++) { + memcpy(dst, ximage->data + y * ximage->bytes_per_line + x * 4, 4 * w); + dst += dst_stride; + } + break; + case PIPE_FORMAT_U_R5_G6_B5: + if (!dst_stride) { + dst_stride = w * 2; + } + for (i = 0; i < h; i++) { + memcpy(dst, ximage->data + y * ximage->bytes_per_line + x * 2, 4 * 2); + dst += dst_stride; + } + break; + default: + assert(0); + } + if (!xms->ximage) { + XMesaDestroyImage(ximage); + } } +/** + * Put raw pixels into pixmap or XImage. + */ void xmesa_put_tile(struct pipe_context *pipe, struct pipe_surface *ps, uint x, uint y, uint w, uint h, const void *p, int src_stride) { + struct xmesa_surface *xms = xmesa_surface(ps); + const ubyte *src = (const ubyte *) p; + XMesaImage *ximage; + if (!xms->drawable && !xms->ximage) { + /* not an X surface */ + softpipe_put_tile(pipe, ps, x, y, w, h, p, src_stride); + return; + } + + if (xms->ximage) { + /* put to ximage */ + ximage = xms->ximage; + char *dst; + int i; + + switch (ps->format) { + case PIPE_FORMAT_U_A8_R8_G8_B8: + if (!src_stride) { + src_stride = w * 4; + } + dst = ximage->data + y * ximage->bytes_per_line + x * 4; + for (i = 0; i < h; i++) { + memcpy(dst, src, w * 4); + dst += ximage->bytes_per_line; + src += src_stride; + } + break; + case PIPE_FORMAT_U_R5_G6_B5: + if (!src_stride) { + src_stride = w * 2; + } + dst = ximage->data + y * ximage->bytes_per_line + x * 2; + for (i = 0; i < h; i++) { + memcpy(dst, src, w * 2); + dst += ximage->bytes_per_line; + src += src_stride; + } + break; + default: + assert(0); + } + } + else { + /* put to pixmap/window */ + /* Create temp XImage for data */ +#ifdef XFree86Server + ximage = XMesaCreateImage(GET_VISUAL_DEPTH(v), w, h, p); +#else + XVisualInfo *visinfo = xms->xrb->Parent->xm_visual->visinfo; + ximage = XCreateImage(xms->display, + visinfo->visual, + visinfo->depth, + ZPixmap, 0, /* format, offset */ + (char *) p, /* data */ + w, h, /* width, height */ + 32, /* bitmap_pad */ + 0); /* bytes_per_line */ +#endif + + /* send XImage data to pixmap */ + XPutImage(xms->display, xms->drawable, xms->gc, + ximage, 0, 0, x, y, w, h); + /* clean-up */ + ximage->data = NULL; /* prevents freeing user data at 'p' */ + XMesaDestroyImage(ximage); + } } -- 2.30.2