summaryrefslogtreecommitdiff
path: root/src/mesa/pipe/xlib/xm_surface.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/pipe/xlib/xm_surface.c')
-rw-r--r--src/mesa/pipe/xlib/xm_surface.c730
1 files changed, 0 insertions, 730 deletions
diff --git a/src/mesa/pipe/xlib/xm_surface.c b/src/mesa/pipe/xlib/xm_surface.c
deleted file mode 100644
index 43e5050747..0000000000
--- a/src/mesa/pipe/xlib/xm_surface.c
+++ /dev/null
@@ -1,730 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version: 7.1
- *
- * Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-
-/**
- * \file xm_surface.c
- * Code to allow the softpipe code to write to X windows/buffers.
- * This is a bit of a hack for now. We've basically got two different
- * abstractions for color buffers: gl_renderbuffer and pipe_surface.
- * They'll need to get merged someday...
- * For now, they're separate things that point to each other.
- */
-
-
-#include "GL/xmesa.h"
-#include "glxheader.h"
-#include "xmesaP.h"
-#include "main/context.h"
-#include "main/imports.h"
-#include "main/macros.h"
-
-#include "pipe/p_context.h"
-#include "pipe/p_defines.h"
-#include "pipe/p_winsys.h"
-#include "pipe/softpipe/sp_context.h"
-#include "pipe/softpipe/sp_clear.h"
-#include "pipe/softpipe/sp_tile_cache.h"
-#include "pipe/softpipe/sp_surface.h"
-#include "state_tracker/st_context.h"
-
-
-/*
- * Dithering kernels and lookup tables.
- */
-
-const int xmesa_kernel8[DITH_DY * DITH_DX] = {
- 0 * MAXC, 8 * MAXC, 2 * MAXC, 10 * MAXC,
- 12 * MAXC, 4 * MAXC, 14 * MAXC, 6 * MAXC,
- 3 * MAXC, 11 * MAXC, 1 * MAXC, 9 * MAXC,
- 15 * MAXC, 7 * MAXC, 13 * MAXC, 5 * MAXC,
-};
-
-const int xmesa_kernel1[16] = {
- 0*47, 9*47, 4*47, 12*47, /* 47 = (255*3)/16 */
- 6*47, 2*47, 14*47, 8*47,
- 10*47, 1*47, 5*47, 11*47,
- 7*47, 13*47, 3*47, 15*47
-};
-
-
-
-#define CLIP_TILE \
- do { \
- if (x >= ps->width) \
- return; \
- if (y >= ps->height) \
- return; \
- if (x + w > ps->width) \
- w = ps->width - x; \
- if (y + h > ps->height) \
- h = ps->height -y; \
- } while(0)
-
-
-
-/*
- * The following functions are used to trap XGetImage() calls which
- * generate BadMatch errors if the drawable isn't mapped.
- */
-
-#ifndef XFree86Server
-static int caught_xgetimage_error = 0;
-static int (*old_xerror_handler)( XMesaDisplay *dpy, XErrorEvent *ev );
-static unsigned long xgetimage_serial;
-
-/*
- * This is the error handler which will be called if XGetImage fails.
- */
-static int xgetimage_error_handler( XMesaDisplay *dpy, XErrorEvent *ev )
-{
- if (ev->serial==xgetimage_serial && ev->error_code==BadMatch) {
- /* caught the expected error */
- caught_xgetimage_error = 0;
- }
- else {
- /* call the original X error handler, if any. otherwise ignore */
- if (old_xerror_handler) {
- (*old_xerror_handler)( dpy, ev );
- }
- }
- return 0;
-}
-
-
-/*
- * Call this right before XGetImage to setup error trap.
- */
-static void catch_xgetimage_errors( XMesaDisplay *dpy )
-{
- xgetimage_serial = NextRequest( dpy );
- old_xerror_handler = XSetErrorHandler( xgetimage_error_handler );
- caught_xgetimage_error = 0;
-}
-
-
-/*
- * Call this right after XGetImage to check if an error occured.
- */
-static int check_xgetimage_errors( void )
-{
- /* restore old handler */
- (void) XSetErrorHandler( old_xerror_handler );
- /* return 0=no error, 1=error caught */
- return caught_xgetimage_error;
-}
-#endif
-
-
-/**
- * Wrapper for XGetImage() that catches BadMatch errors that can occur
- * when the window is unmapped or the x/y/w/h extend beyond the window
- * bounds.
- * If build into xserver, wrap the internal GetImage method.
- */
-static XMesaImage *
-xget_image(XMesaDisplay *dpy, Drawable d, int x, int y, uint w, uint h)
-{
-#ifdef XFree86Server
- uint bpp = 4; /* XXX fix this */
- XMesaImage *ximage = (XMesaImage *) malloc(sizeof(XMesaImage));
- if (ximage) {
- ximage->data = malloc(width * height * bpp);
- }
- (*dpy->GetImage)(d, x, y, w, h, ZPixmap, ~0L, (pointer)ximage->data);
- ximage->width = w;
- ximage->height = h;
- ximage->bytes_per_row = w * bpp;
- return ximage;
-#else
- int error;
- XMesaImage *ximage;
- catch_xgetimage_errors(dpy);
- ximage = XGetImage(dpy, d, x, y, w, h, AllPlanes, ZPixmap);
- error = check_xgetimage_errors();
- return ximage;
-#endif
-}
-
-
-
-/**
- * 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)
-{
- const uint w0 = w;
- 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;
- }
-
- CLIP_TILE;
-
- if (!xms->ximage) {
- /* XImage = pixmap data */
- assert(xms->drawable);
- ximage = xget_image(xms->display, xms->drawable, x, y, w, h);
- if (!ximage)
- return;
- x = y = 0;
- }
- else {
- ximage = xms->ximage;
- }
-
- /* this could be optimized/simplified */
- switch (ps->format) {
- case PIPE_FORMAT_U_A8_R8_G8_B8:
- if (!dst_stride) {
- dst_stride = w0 * 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 = w0 * 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)
-{
- const uint w0 = w;
- 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;
- }
-
- CLIP_TILE;
-
- if (xms->ximage) {
- /* put to ximage */
- ximage = xms->ximage;
- char *dst;
- int i;
-
- /* this could be optimized/simplified */
- switch (ps->format) {
- case PIPE_FORMAT_U_A8_R8_G8_B8:
- if (!src_stride) {
- src_stride = w0 * 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 = w0 * 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);
- }
-}
-
-
-void
-xmesa_get_tile_rgba(struct pipe_context *pipe, struct pipe_surface *ps,
- uint x, uint y, uint w, uint h, float *pixels)
-{
- const uint w0 = w;
- struct xmesa_surface *xms = xmesa_surface(ps);
- XMesaImage *ximage = NULL;
- float *pRow = pixels;
- uint i, j;
-
- if (!xms->drawable && !xms->ximage) {
- /* not an X surface */
- softpipe_get_tile_rgba(pipe, ps, x, y, w, h, pixels);
- return;
- }
-
- CLIP_TILE;
-
- if (!xms->ximage) {
- /* XImage = pixmap data */
- assert(xms->drawable);
- ximage = xget_image(xms->display, xms->drawable, x, y, w, h);
- if (!ximage)
- return;
- x = y = 0;
- }
- else {
- ximage = xms->ximage;
- }
-
- switch (ps->format) {
- case PIPE_FORMAT_U_A8_R8_G8_B8:
- {
- 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 >> 16) & 0xff);
- ubyte g = ((pix >> 8) & 0xff);
- ubyte b = ( pix & 0xff);
- ubyte a = ((pix >> 24) & 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
- = (ushort *) (ximage->data + y * ximage->bytes_per_line + x * 2);
- for (i = 0; i < h; i++) {
- float *p = pRow;
- for (j = 0; j < w; j++) {
- uint pix = src[j];
- ubyte r = (pix >> 8) | ((pix >> 13) & 0x7);
- ubyte g = (pix >> 3) | ((pix >> 9) & 0x3);
- ubyte b = ((pix & 0x1f) << 3) | ((pix >> 2) & 0x3);
- p[0] = UBYTE_TO_FLOAT(r);
- p[1] = UBYTE_TO_FLOAT(g);
- p[2] = UBYTE_TO_FLOAT(b);
- p[3] = 1.0;
- p += 4;
- }
- src += ximage->width;
- pRow += 4 * w0;
- }
- }
- break;
- default:
- assert(0);
- }
-
- if (!xms->ximage) {
- XMesaDestroyImage(ximage);
- }
-}
-
-
-void
-xmesa_put_tile_rgba(struct pipe_context *pipe, struct pipe_surface *ps,
- uint x, uint y, uint w, uint h, const float *pixels)
-{
- const uint x0 = x, y0 = y, w0 = w;
- struct xmesa_surface *xms = xmesa_surface(ps);
- XMesaImage *ximage;
- uint i, j;
-
- if (!xms->drawable && !xms->ximage) {
- /* not an X surface */
- softpipe_put_tile_rgba(pipe, ps, x, y, w, h, pixels);
- return;
- }
-
- CLIP_TILE;
-
- 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);
- 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_8A8R8G8B(r, g, b, a);
- p += 4;
- }
- dst += ximage->width;
- pRow += 4 * w0;
- }
- }
- break;
- case PIPE_FORMAT_U_R5_G6_B5:
- {
- ushort *dst =
- (ushort *) (ximage->data + y * ximage->bytes_per_line + x * 2);
- const float *pRow = pixels;
- for (i = 0; i < h; i++) {
- const float *p = pRow;
- 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;
- pRow += 4 * w0;
- }
- }
- break;
-
- default:
- assert(0);
- }
-
- 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);
- }
-}
-
-
-static void
-clear_pixmap_surface(struct pipe_context *pipe, struct pipe_surface *ps,
- uint value)
-{
- struct xmesa_surface *xms = xmesa_surface(ps);
- assert(xms);
- assert(xms->display);
- assert(xms->drawable);
- assert(xms->gc);
- XMesaSetForeground( xms->display, xms->gc, value );
- XMesaFillRectangle( xms->display, xms->drawable, xms->gc,
- 0, 0, ps->width, ps->height);
-}
-
-static void
-clear_nbit_ximage_surface(struct pipe_context *pipe, struct pipe_surface *ps,
- uint value)
-{
- struct xmesa_surface *xms = xmesa_surface(ps);
- int width = xms->surface.width;
- int height = xms->surface.height;
- int i, j;
- for (j = 0; j < height; j++) {
- for (i = 0; i < width; i++) {
- XMesaPutPixel(xms->ximage, i, j, value);
- }
- }
-}
-
-static void
-clear_8bit_ximage_surface(struct pipe_context *pipe, struct pipe_surface *ps,
- uint value)
-{
- struct xmesa_surface *xms = xmesa_surface(ps);
- memset(xms->ximage->data,
- value,
- xms->ximage->bytes_per_line * xms->ximage->height);
-}
-
-static void
-clear_16bit_ximage_surface(struct pipe_context *pipe, struct pipe_surface *ps,
- uint value)
-{
- struct xmesa_surface *xms = xmesa_surface(ps);
- const int n = xms->ximage->width * xms->ximage->height;
- ushort *dst = (ushort *) xms->ximage->data;
- int i;
- for (i = 0; i < n; i++) {
- dst[i] = value;
- }
-}
-
-
-/* Optimized code provided by Nozomi Ytow <noz@xfree86.org> */
-static void
-clear_24bit_ximage_surface(struct pipe_context *pipe, struct pipe_surface *ps,
- uint value)
-{
- struct xmesa_surface *xms = xmesa_surface(ps);
- const ubyte r = (value ) & 0xff;
- const ubyte g = (value >> 8) & 0xff;
- const ubyte b = (value >> 16) & 0xff;
-
- if (r == g && g == b) {
- /* same value for all three components (gray) */
- memset(xms->ximage->data, r,
- xms->ximage->bytes_per_line * xms->ximage->height);
- }
- else {
- /* non-gray clear color */
- const int n = xms->ximage->width * xms->ximage->height;
- int i;
- bgr_t *ptr3 = (bgr_t *) xms->ximage->data;
- for (i = 0; i < n; i++) {
- ptr3->r = r;
- ptr3->g = g;
- ptr3->b = b;
- ptr3++;
- }
- }
-}
-
-static void
-clear_32bit_ximage_surface(struct pipe_context *pipe, struct pipe_surface *ps,
- uint value)
-{
- struct xmesa_surface *xms = xmesa_surface(ps);
-
- if (value == 0) {
- /* common case */
- memset(xms->ximage->data, value,
- xms->ximage->bytes_per_line * xms->ximage->height);
- }
- else {
- const int n = xms->ximage->width * xms->ximage->height;
- uint *dst = (uint *) xms->ximage->data;
- int i;
- for (i = 0; i < n; i++)
- dst[i] = value;
- }
-}
-
-
-
-
-/**
- * Called to create a pipe_surface for each X renderbuffer.
- * Note: this is being used instead of pipe->surface_alloc() since we
- * have special/unique quad read/write functions for X.
- */
-struct pipe_surface *
-xmesa_new_color_surface(struct pipe_winsys *winsys, GLuint pipeFormat)
-{
- struct xmesa_surface *xms = CALLOC_STRUCT(xmesa_surface);
-
- assert(pipeFormat);
-
- xms->surface.format = pipeFormat;
- xms->surface.refcount = 1;
- xms->surface.winsys = winsys;
-
- /* Note, the region we allocate doesn't actually have any storage
- * since we're drawing into an XImage or Pixmap.
- * The region's size will get set in the xmesa_alloc_front/back_storage()
- * functions.
- */
- xms->surface.region = winsys->region_alloc(winsys, 1, 1, 1, 0x0);
-
- return &xms->surface;
-}
-
-
-/**
- * Called via pipe->surface_alloc() to create new surfaces (textures,
- * renderbuffers, etc.
- */
-struct pipe_surface *
-xmesa_surface_alloc(struct pipe_context *pipe, GLuint pipeFormat)
-{
- struct xmesa_surface *xms = CALLOC_STRUCT(xmesa_surface);
-
- assert(pipe);
- assert(pipeFormat);
-
- xms->surface.format = pipeFormat;
- xms->surface.refcount = 1;
- xms->surface.winsys = pipe->winsys;
-
- return &xms->surface;
-}
-
-
-/**
- * Called via pipe->clear() to clear entire surface to a certain value.
- * If the surface is not an X pixmap or XImage, pass the call to
- * softpipe_clear().
- */
-void
-xmesa_clear(struct pipe_context *pipe, struct pipe_surface *ps, uint value)
-{
- struct xmesa_surface *xms = xmesa_surface(ps);
-
- /* XXX actually, we should just discard any cached tiles from this
- * surface since we don't want to accidentally re-use them after clearing.
- */
- pipe->flush(pipe, 0);
-
- {
- struct softpipe_context *sp = softpipe_context(pipe);
- if (ps == sp_tile_cache_get_surface(sp->cbuf_cache[0])) {
- float clear[4];
- clear[0] = 0.2; /* XXX hack */
- clear[1] = 0.2;
- clear[2] = 0.2;
- clear[3] = 0.2;
- sp_tile_cache_clear(sp->cbuf_cache[0], clear);
- }
- }
-
-#if 1
- (void) clear_8bit_ximage_surface;
- (void) clear_24bit_ximage_surface;
-#endif
-
- if (xms->ximage) {
- /* back color buffer */
- switch (xms->surface.format) {
- case PIPE_FORMAT_U_R5_G6_B5:
- clear_16bit_ximage_surface(pipe, ps, value);
- break;
- case PIPE_FORMAT_U_A8_R8_G8_B8:
- clear_32bit_ximage_surface(pipe, ps, value);
- break;
- default:
- clear_nbit_ximage_surface(pipe, ps, value);
- break;
- }
- }
- else if (xms->drawable) {
- /* front color buffer */
- clear_pixmap_surface(pipe, ps, value);
- }
- else {
- /* other kind of buffer */
- softpipe_clear(pipe, ps, value);
- }
-}
-
-
-/** XXX unfinished sketch... */
-struct pipe_surface *
-xmesa_create_front_surface(XMesaVisual vis, Window win)
-{
- struct xmesa_surface *xms = CALLOC_STRUCT(xmesa_surface);
- if (!xms) {
- return NULL;
- }
-
- xms->display = vis->display;
- xms->drawable = win;
-
- xms->surface.format = PIPE_FORMAT_U_A8_R8_G8_B8;
- xms->surface.refcount = 1;
-#if 0
- xms->surface.region = pipe->winsys->region_alloc(pipe->winsys,
- 1, 0, 0, 0x0);
-#endif
- return &xms->surface;
-}
-