summaryrefslogtreecommitdiffstats
path: root/src/mesa/pipe/xlib
diff options
context:
space:
mode:
authorBrian <[email protected]>2007-11-01 11:23:50 -0600
committerBrian <[email protected]>2007-11-01 11:23:50 -0600
commita33308898666e89f2443e7eb4f1d09ae792b620a (patch)
tree6e2c184924ad1e6ebce5658e6cfa219ef5cce022 /src/mesa/pipe/xlib
parent0d6608ee6855e5605efc3bd9fec51ada59e208d9 (diff)
implement get/put_tile() for xlib driver
Diffstat (limited to 'src/mesa/pipe/xlib')
-rw-r--r--src/mesa/pipe/xlib/xm_surface.c119
1 files changed, 119 insertions, 0 deletions
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);
+ }
}