From 1675d05f911fbd569efb5248674aa71cb755c75b Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 8 Mar 2010 16:20:09 +0000 Subject: winsys/xlib: remove dependency on glx/x11 state tracker Introduce xlib_drawable struct, pass this down to winsys instead of having it use the internal data structures from glx/x11 --- src/gallium/include/state_tracker/xlib_sw_winsys.h | 25 ++++++ src/gallium/state_trackers/glx/xlib/glx_api.c | 2 +- src/gallium/state_trackers/glx/xlib/xm_api.c | 91 ++++------------------ src/gallium/state_trackers/glx/xlib/xm_api.h | 18 +---- src/gallium/state_trackers/glx/xlib/xm_winsys.h | 7 +- src/gallium/winsys/xlib/xlib_llvmpipe.c | 8 +- src/gallium/winsys/xlib/xlib_softpipe.c | 4 +- src/gallium/winsys/xlib/xlib_sw_winsys.c | 81 +++++++++++-------- 8 files changed, 103 insertions(+), 133 deletions(-) create mode 100644 src/gallium/include/state_tracker/xlib_sw_winsys.h diff --git a/src/gallium/include/state_tracker/xlib_sw_winsys.h b/src/gallium/include/state_tracker/xlib_sw_winsys.h new file mode 100644 index 0000000000..71d39b9cdb --- /dev/null +++ b/src/gallium/include/state_tracker/xlib_sw_winsys.h @@ -0,0 +1,25 @@ +#ifndef XLIB_SW_WINSYS_H +#define XLIB_SW_WINSYS_H + +#include "state_tracker/sw_winsys.h" +#include + +struct sw_winsys *xlib_create_sw_winsys( Display *display ); + +/* This is what the xlib software winsys expects to find in the + * "private" field of flush_frontbuffers(). Xlib-based state trackers + * somehow need to know this. + */ +struct xlib_drawable { + Visual *visual; + int depth; + Drawable drawable; + GC gc; /* temporary? */ +}; + +void +xlib_sw_display(struct xlib_drawable *xm_buffer, + struct sw_displaytarget *dt); + + +#endif diff --git a/src/gallium/state_trackers/glx/xlib/glx_api.c b/src/gallium/state_trackers/glx/xlib/glx_api.c index 08bf624b5c..2454585850 100644 --- a/src/gallium/state_trackers/glx/xlib/glx_api.c +++ b/src/gallium/state_trackers/glx/xlib/glx_api.c @@ -689,7 +689,7 @@ choose_visual( Display *dpy, int screen, const int *list, GLboolean fbConfig ) int desiredVisualID = -1; int numAux = 0; - xmesa_init(); + xmesa_init( dpy ); parselist = list; diff --git a/src/gallium/state_trackers/glx/xlib/xm_api.c b/src/gallium/state_trackers/glx/xlib/xm_api.c index 217bdeff75..d878740ab1 100644 --- a/src/gallium/state_trackers/glx/xlib/xm_api.c +++ b/src/gallium/state_trackers/glx/xlib/xm_api.c @@ -35,10 +35,6 @@ * corner of the window. Therefore, most drawing functions in this * file have to flip Y coordinates. * - * Define USE_XSHM in the Makefile with -DUSE_XSHM if you want to compile - * in support for the MIT Shared Memory extension. If enabled, when you - * use an Ximage for the back buffer in double buffered mode, the "swap" - * operation will be faster. You must also link with -lXext. * * Byte swapping: If the Mesa host and the X display use a different * byte order then there's some trickiness to be aware of when using @@ -111,41 +107,6 @@ static int host_byte_order( void ) } -/** - * Check if the X Shared Memory extension is available. - * Return: 0 = not available - * 1 = shared XImage support available - * 2 = shared Pixmap support available also - */ -int xmesa_check_for_xshm( Display *display ) -{ -#if defined(USE_XSHM) - int major, minor, ignore; - Bool pixmaps; - - if (getenv("SP_NO_RAST")) - return 0; - - if (getenv("MESA_NOSHM")) { - return 0; - } - - if (XQueryExtension( display, "MIT-SHM", &ignore, &ignore, &ignore )) { - if (XShmQueryVersion( display, &major, &minor, &pixmaps )==True) { - return (pixmaps==True) ? 2 : 1; - } - else { - return 0; - } - } - else { - return 0; - } -#else - /* No XSHM support */ - return 0; -#endif -} /** @@ -242,7 +203,7 @@ xmesa_get_window_size(Display *dpy, XMesaBuffer b, pipe_mutex_lock(_xmesa_lock); XSync(b->xm_visual->display, 0); /* added for Chromium */ - stat = get_drawable_size(dpy, b->drawable, width, height); + stat = get_drawable_size(dpy, b->ws.drawable, width, height); pipe_mutex_unlock(_xmesa_lock); if (!stat) { @@ -397,7 +358,9 @@ create_xmesa_buffer(Drawable d, BufferType type, if (!b) return NULL; - b->drawable = d; + b->ws.drawable = d; + b->ws.visual = vis->visinfo->visual; + b->ws.depth = vis->visinfo->depth; b->xm_visual = vis; b->type = type; @@ -422,18 +385,6 @@ create_xmesa_buffer(Drawable d, BufferType type, (void *) b); fb = &b->stfb->Base; - /* - * Create scratch XImage for xmesa_display_surface() - */ - b->tempImage = XCreateImage(vis->display, - vis->visinfo->visual, - vis->visinfo->depth, - ZPixmap, 0, /* format, offset */ - NULL, /* data */ - 0, 0, /* size */ - 32, /* bitmap_pad */ - 0); /* bytes_per_line */ - /* GLX_EXT_texture_from_pixmap */ b->TextureTarget = 0; b->TextureFormat = GLX_TEXTURE_FORMAT_NONE_EXT; @@ -490,15 +441,12 @@ xmesa_free_buffer(XMesaBuffer buffer) /* Since the X window for the XMesaBuffer is going away, we don't * want to dereference this pointer in the future. */ - b->drawable = 0; - - buffer->tempImage->data = NULL; - XDestroyImage(buffer->tempImage); + b->ws.drawable = 0; /* Unreference. If count = zero we'll really delete the buffer */ _mesa_reference_framebuffer(&fb, NULL); - XFreeGC(b->xm_visual->display, b->gc); + XFreeGC(b->xm_visual->display, b->ws.gc); free(buffer); @@ -578,17 +526,12 @@ initialize_visual_and_buffer(XMesaVisual v, XMesaBuffer b, if (b && window) { /* these should have been set in create_xmesa_buffer */ - ASSERT(b->drawable == window); + ASSERT(b->ws.drawable == window); - /* Setup for single/double buffering */ - if (v->mesa_visual.doubleBufferMode) { - /* Double buffered */ - b->shm = xmesa_check_for_xshm( v->display ); - } /* X11 graphics context */ - b->gc = XCreateGC( v->display, window, 0, NULL ); - XSetFunction( v->display, b->gc, GXcopy ); + b->ws.gc = XCreateGC( v->display, window, 0, NULL ); + XSetFunction( v->display, b->ws.gc, GXcopy ); } return GL_TRUE; @@ -673,7 +616,7 @@ XMesaVisual XMesaCreateVisual( Display *display, XMesaVisual v; GLint red_bits, green_bits, blue_bits, alpha_bits; - xmesa_init(); + xmesa_init( display ); /* For debugging only */ if (_mesa_getenv("MESA_XSYNC")) { @@ -773,12 +716,12 @@ void XMesaDestroyVisual( XMesaVisual v ) * Do one-time initializations. */ void -xmesa_init(void) +xmesa_init( Display *display ) { static GLboolean firstTime = GL_TRUE; if (firstTime) { pipe_mutex_init(_xmesa_lock); - _screen = driver.create_pipe_screen(); + _screen = driver.create_pipe_screen( display ); screen = trace_screen_create( _screen ); firstTime = GL_FALSE; } @@ -800,7 +743,7 @@ XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list ) GLcontext *mesaCtx; uint pf; - xmesa_init(); + xmesa_init( v->display ); /* Note: the XMesaContext contains a Mesa GLcontext struct (inheritance) */ c = (XMesaContext) CALLOC_STRUCT(xmesa_context); @@ -1155,7 +1098,7 @@ void XMesaSwapBuffers( XMesaBuffer b ) frontLeftSurf = surf; } - driver.display_surface(b, frontLeftSurf); + driver.display_surface(&b->ws, frontLeftSurf); } xmesa_check_and_update_buffer_size(NULL, b); @@ -1203,7 +1146,7 @@ XMesaBuffer XMesaFindBuffer( Display *dpy, Drawable d ) { XMesaBuffer b; for (b = XMesaBufferList; b; b = b->Next) { - if (b->drawable == d && b->xm_visual->display == dpy) { + if (b->ws.drawable == d && b->xm_visual->display == dpy) { return b; } } @@ -1237,10 +1180,10 @@ void XMesaGarbageCollect( void ) next = b->Next; if (b->xm_visual && b->xm_visual->display && - b->drawable && + b->ws.drawable && b->type == WINDOW) { XSync(b->xm_visual->display, False); - if (!window_exists( b->xm_visual->display, b->drawable )) { + if (!window_exists( b->xm_visual->display, b->ws.drawable )) { /* found a dead window, free the ancillary info */ XMesaDestroyBuffer( b ); } diff --git a/src/gallium/state_trackers/glx/xlib/xm_api.h b/src/gallium/state_trackers/glx/xlib/xm_api.h index 004cb260dc..de47064b41 100644 --- a/src/gallium/state_trackers/glx/xlib/xm_api.h +++ b/src/gallium/state_trackers/glx/xlib/xm_api.h @@ -62,15 +62,11 @@ and create a window, you must do the following to use the X/Mesa interface: #include "state_tracker/st_public.h" #include "os/os_thread.h" +#include "state_tracker/xlib_sw_winsys.h" # include # include # include -# ifdef USE_XSHM /* was SHM */ -# include -# include -# include -# endif typedef struct xmesa_buffer *XMesaBuffer; typedef struct xmesa_context *XMesaContext; @@ -316,6 +312,7 @@ typedef enum { */ struct xmesa_buffer { struct st_framebuffer *stfb; + struct xlib_drawable ws; GLboolean wasCurrent; /* was ever the current buffer? */ XMesaVisual xm_visual; /* the X/Mesa visual */ @@ -329,13 +326,6 @@ struct xmesa_buffer { XImage *tempImage; unsigned long selectedEvents;/* for pbuffers only */ - GLuint shm; /* X Shared Memory extension status: */ - /* 0 = not available */ - /* 1 = XImage support available */ - /* 2 = Pixmap support available too */ -#if defined(USE_XSHM) - XShmSegmentInfo shminfo; -#endif GC gc; /* scratch GC for span, line, tri drawing */ @@ -367,7 +357,7 @@ xmesa_buffer(GLframebuffer *fb) extern void -xmesa_init(void); +xmesa_init(Display *dpy); extern void xmesa_delete_framebuffer(struct gl_framebuffer *fb); @@ -397,8 +387,6 @@ xmesa_buffer_height(XMesaBuffer b) return b->stfb->Base.Height; } -extern int -xmesa_check_for_xshm(Display *display); #endif diff --git a/src/gallium/state_trackers/glx/xlib/xm_winsys.h b/src/gallium/state_trackers/glx/xlib/xm_winsys.h index 4bd5b5c8d3..fc4444bee0 100644 --- a/src/gallium/state_trackers/glx/xlib/xm_winsys.h +++ b/src/gallium/state_trackers/glx/xlib/xm_winsys.h @@ -32,14 +32,15 @@ struct pipe_context; struct pipe_screen; struct pipe_surface; -struct xmesa_buffer; +struct xlib_drawable; +#include struct xm_driver { - struct pipe_screen *(*create_pipe_screen)( void ); + struct pipe_screen *(*create_pipe_screen)( Display *display ); - void (*display_surface)( struct xmesa_buffer *, + void (*display_surface)( struct xlib_drawable *, struct pipe_surface * ); }; diff --git a/src/gallium/winsys/xlib/xlib_llvmpipe.c b/src/gallium/winsys/xlib/xlib_llvmpipe.c index cb559f9080..ceefc1624c 100644 --- a/src/gallium/winsys/xlib/xlib_llvmpipe.c +++ b/src/gallium/winsys/xlib/xlib_llvmpipe.c @@ -42,16 +42,16 @@ #include "llvmpipe/lp_texture.h" #include "llvmpipe/lp_screen.h" -#include "state_tracker/sw_winsys.h" +#include "state_tracker/xlib_sw_winsys.h" #include "util/u_debug.h" static struct pipe_screen * -xlib_create_llvmpipe_screen( void ) +xlib_create_llvmpipe_screen( Display *display ) { struct sw_winsys *winsys; struct pipe_screen *screen; - winsys = xlib_create_sw_winsys(); + winsys = xlib_create_sw_winsys( display ); if (winsys == NULL) return NULL; @@ -70,7 +70,7 @@ fail: static void -xlib_llvmpipe_display_surface(struct xmesa_buffer *xm_buffer, +xlib_llvmpipe_display_surface(struct xlib_drawable *xm_buffer, struct pipe_surface *surf) { struct llvmpipe_texture *texture = llvmpipe_texture(surf->texture); diff --git a/src/gallium/winsys/xlib/xlib_softpipe.c b/src/gallium/winsys/xlib/xlib_softpipe.c index 47fec4313b..9d665c3d83 100644 --- a/src/gallium/winsys/xlib/xlib_softpipe.c +++ b/src/gallium/winsys/xlib/xlib_softpipe.c @@ -34,12 +34,12 @@ #include "util/u_debug.h" static struct pipe_screen * -xlib_create_softpipe_screen( void ) +xlib_create_softpipe_screen( Display *display ) { struct sw_winsys *winsys; struct pipe_screen *screen; - winsys = xlib_create_sw_winsys(); + winsys = xlib_create_sw_winsys( display ); if (winsys == NULL) return NULL; diff --git a/src/gallium/winsys/xlib/xlib_sw_winsys.c b/src/gallium/winsys/xlib/xlib_sw_winsys.c index e4b02ba093..21649a0b1f 100644 --- a/src/gallium/winsys/xlib/xlib_sw_winsys.c +++ b/src/gallium/winsys/xlib/xlib_sw_winsys.c @@ -46,10 +46,17 @@ #include "util/u_math.h" #include "util/u_memory.h" -#include "state_tracker/sw_winsys.h" +#include "state_tracker/xlib_sw_winsys.h" #include "xlib.h" +#include +#include +#include +#include +#include +#include + /** * Subclass of pipe_buffer for Xlib winsys. * Low-level OS/window system memory buffer @@ -64,21 +71,25 @@ struct xm_displaytarget void *data; void *mapped; + Display *display; + Visual *visual; XImage *tempImage; -#ifdef USE_XSHM - int shm; + XShmSegmentInfo shminfo; -#endif + int shm; }; /** * Subclass of sw_winsys for Xlib winsys */ -struct xmesa_sw_winsys +struct xlib_sw_winsys { struct sw_winsys base; -/* struct xmesa_visual *xm_visual; */ + + + + Display *display; }; @@ -136,8 +147,8 @@ static char *alloc_shm(struct xm_displaytarget *buf, unsigned size) * Allocate a shared memory XImage back buffer for the given XMesaBuffer. */ static void -alloc_shm_ximage(struct xm_displaytarget *xm_buffer, - struct xmesa_buffer *xmb, +alloc_shm_ximage(struct xm_displaytarget *xm_dt, + struct xlib_drawable *xmb, unsigned width, unsigned height) { /* @@ -148,15 +159,15 @@ alloc_shm_ximage(struct xm_displaytarget *xm_buffer, */ int (*old_handler)(Display *, XErrorEvent *); - xm_buffer->tempImage = XShmCreateImage(xmb->xm_visual->display, - xmb->xm_visual->visinfo->visual, - xmb->xm_visual->visinfo->depth, - ZPixmap, - NULL, - &xm_buffer->shminfo, - width, height); - if (xm_buffer->tempImage == NULL) { - xm_buffer->shm = 0; + xm_dt->tempImage = XShmCreateImage(xm_dt->display, + xmb->visual, + xmb->depth, + ZPixmap, + NULL, + &xm_dt->shminfo, + width, height); + if (xm_dt->tempImage == NULL) { + xm_dt->shm = 0; return; } @@ -164,21 +175,21 @@ alloc_shm_ximage(struct xm_displaytarget *xm_buffer, mesaXErrorFlag = 0; old_handler = XSetErrorHandler(mesaHandleXError); /* This may trigger the X protocol error we're ready to catch: */ - XShmAttach(xmb->xm_visual->display, &xm_buffer->shminfo); - XSync(xmb->xm_visual->display, False); + XShmAttach(xm_dt->display, &xm_dt->shminfo); + XSync(xm_dt->display, False); if (mesaXErrorFlag) { /* we are on a remote display, this error is normal, don't print it */ - XFlush(xmb->xm_visual->display); + XFlush(xm_dt->display); mesaXErrorFlag = 0; - XDestroyImage(xm_buffer->tempImage); - xm_buffer->tempImage = NULL; - xm_buffer->shm = 0; + XDestroyImage(xm_dt->tempImage); + xm_dt->tempImage = NULL; + xm_dt->shm = 0; (void) XSetErrorHandler(old_handler); return; } - xm_buffer->shm = 1; + xm_dt->shm = 1; } #endif /* USE_XSHM */ @@ -239,7 +250,7 @@ xm_displaytarget_destroy(struct sw_winsys *ws, * by the XMesaBuffer. */ void -xlib_sw_display(struct xmesa_buffer *xm_buffer, +xlib_sw_display(struct xlib_drawable *xlib_drawable, struct sw_displaytarget *dt) { XImage *ximage; @@ -262,7 +273,8 @@ xlib_sw_display(struct xmesa_buffer *xm_buffer, { assert(util_format_get_blockwidth(xm_dt->format) == 1); assert(util_format_get_blockheight(xm_dt->format) == 1); - alloc_shm_ximage(xm_dt, xm_buffer, + alloc_shm_ximage(xm_dt, + xlib_drawable, xm_dt->stride / util_format_get_blocksize(xm_dt->format), xm_dt->height); } @@ -271,7 +283,7 @@ xlib_sw_display(struct xmesa_buffer *xm_buffer, ximage->data = xm_dt->data; /* _debug_printf("XSHM\n"); */ - XShmPutImage(xm_buffer->xm_visual->display, xm_buffer->drawable, xm_buffer->gc, + XShmPutImage(xm_dt->display, xlib_drawable->drawable, xlib_drawable->gc, ximage, 0, 0, 0, 0, xm_dt->width, xm_dt->height, False); } else @@ -291,7 +303,7 @@ xlib_sw_display(struct xmesa_buffer *xm_buffer, ximage->bytes_per_line = xm_dt->stride; /* _debug_printf("XPUT\n"); */ - XPutImage(xm_buffer->xm_visual->display, xm_buffer->drawable, xm_buffer->gc, + XPutImage(xm_dt->display, xlib_drawable->drawable, xlib_drawable->gc, ximage, 0, 0, 0, 0, xm_dt->width, xm_dt->height); } } @@ -305,9 +317,8 @@ xm_displaytarget_display(struct sw_winsys *ws, struct sw_displaytarget *dt, void *context_private) { - XMesaContext xmctx = (XMesaContext) context_private; - struct xmesa_buffer *xm_buffer = xmctx->xm_buffer; - xm_sw_display(xm_buffer, dt); + struct xlib_drawable *xlib_drawable = (struct xlib_drawable *)context_private; + xlib_sw_display(xlib_drawable, dt); } @@ -325,6 +336,7 @@ xm_displaytarget_create(struct sw_winsys *winsys, if(!xm_dt) goto no_xm_dt; + xm_dt->display = ((struct xlib_sw_winsys *)winsys)->display; xm_dt->format = format; xm_dt->width = width; xm_dt->height = height; @@ -370,14 +382,15 @@ xm_destroy( struct sw_winsys *ws ) struct sw_winsys * -xlib_create_sw_winsys( void ) +xlib_create_sw_winsys( Display *display ) { - struct xmesa_sw_winsys *ws; + struct xlib_sw_winsys *ws; - ws = CALLOC_STRUCT(xmesa_sw_winsys); + ws = CALLOC_STRUCT(xlib_sw_winsys); if (!ws) return NULL; + ws->display = display; ws->base.destroy = xm_destroy; ws->base.is_displaytarget_format_supported = xm_is_displaytarget_format_supported; -- cgit v1.2.3