diff -u -x CVS -x '*.o' -x Makefile -x 'depend*' a/glxclient.h b/glxclient.h --- a/glxclient.h 2005-10-01 13:42:36.000000000 +0300 +++ b/glxclient.h 2005-10-01 13:55:31.000000000 +0300 @@ -532,8 +532,6 @@ #endif }; -void __glXFreeContext(__GLXcontext*); - extern GLubyte *__glXFlushRenderBuffer(__GLXcontext*, GLubyte*); extern void __glXSendLargeChunk(__GLXcontext *gc, GLint requestNumber, @@ -576,6 +574,10 @@ #endif /* defined( USE_XTHREADS ) || defined( PTHREADS ) */ +extern void __glXSetCurrentContextNull(Display *dpy); + +extern void __glXFreeContext(__GLXcontext*); + /* ** Global lock for all threads in this address space using the GLX diff -u -x CVS -x '*.o' -x Makefile -x 'depend*' a/glxext.c b/glxext.c --- a/glxext.c 2005-10-01 13:47:14.000000000 +0300 +++ b/glxext.c 2005-10-01 13:57:00.000000000 +0300 @@ -47,7 +47,6 @@ #include "glxclient.h" #include #include -#include "indirect_init.h" #include "glapi.h" #include "glxextensions.h" #include "glcontextmodes.h" @@ -96,168 +95,12 @@ #define INIT_MESA_SPARC #endif -static Bool MakeContextCurrent(Display *dpy, GLXDrawable draw, - GLXDrawable read, GLXContext gc); - -/* -** We setup some dummy structures here so that the API can be used -** even if no context is current. -*/ - -static GLubyte dummyBuffer[__GLX_BUFFER_LIMIT_SIZE]; - -/* -** Dummy context used by small commands when there is no current context. -** All the -** gl and glx entry points are designed to operate as nop's when using -** the dummy context structure. -*/ -static __GLXcontext dummyContext = { - &dummyBuffer[0], - &dummyBuffer[0], - &dummyBuffer[0], - &dummyBuffer[__GLX_BUFFER_LIMIT_SIZE], - sizeof(dummyBuffer), -}; - - -/* -** All indirect rendering contexts will share the same indirect dispatch table. -*/ -static __GLapi *IndirectAPI = NULL; - - -/* - * Current context management and locking - */ - -#if defined( USE_XTHREADS ) - -/* thread safe */ -static GLboolean TSDinitialized = GL_FALSE; -static xthread_key_t ContextTSD; - -__GLXcontext *__glXGetCurrentContext(void) -{ - if (!TSDinitialized) { - xthread_key_create(&ContextTSD, NULL); - TSDinitialized = GL_TRUE; - return &dummyContext; - } - else { - void *p; - xthread_get_specific(ContextTSD, &p); - if (!p) - return &dummyContext; - else - return (__GLXcontext *) p; - } -} - -void __glXSetCurrentContext(__GLXcontext *c) -{ - if (!TSDinitialized) { - xthread_key_create(&ContextTSD, NULL); - TSDinitialized = GL_TRUE; - } - xthread_set_specific(ContextTSD, c); -} - - -/* Used by the __glXLock() and __glXUnlock() macros */ -xmutex_rec __glXmutex; - -#elif defined( PTHREADS ) - -pthread_mutex_t __glXmutex = PTHREAD_MUTEX_INITIALIZER; - -# if defined( GLX_USE_TLS ) - -/** - * Per-thread GLX context pointer. - * - * \c __glXSetCurrentContext is written is such a way that this pointer can - * \b never be \c NULL. This is important! Because of this - * \c __glXGetCurrentContext can be implemented as trivial macro. - */ -__thread void * __glX_tls_Context __attribute__((tls_model("initial-exec"))) - = &dummyContext; - -void __glXSetCurrentContext( __GLXcontext * c ) -{ - __glX_tls_Context = (c != NULL) ? c : &dummyContext; -} - -# else - -static pthread_once_t once_control = PTHREAD_ONCE_INIT; - -/** - * Per-thread data key. - * - * Once \c init_thread_data has been called, the per-thread data key will - * take a value of \c NULL. As each new thread is created the default - * value, in that thread, will be \c NULL. - */ -static pthread_key_t ContextTSD; - -/** - * Initialize the per-thread data key. - * - * This function is called \b exactly once per-process (not per-thread!) to - * initialize the per-thread data key. This is ideally done using the - * \c pthread_once mechanism. - */ -static void init_thread_data( void ) -{ - if ( pthread_key_create( & ContextTSD, NULL ) != 0 ) { - perror( "pthread_key_create" ); - exit( -1 ); - } -} - -void __glXSetCurrentContext( __GLXcontext * c ) -{ - pthread_once( & once_control, init_thread_data ); - pthread_setspecific( ContextTSD, c ); -} - -__GLXcontext * __glXGetCurrentContext( void ) -{ - void * v; - - pthread_once( & once_control, init_thread_data ); - - v = pthread_getspecific( ContextTSD ); - return (v == NULL) ? & dummyContext : (__GLXcontext *) v; -} - -# endif /* defined( GLX_USE_TLS ) */ - -#elif defined( THREADS ) - -#error Unknown threading method specified. - -#else - -/* not thread safe */ -__GLXcontext *__glXcurrentContext = &dummyContext; - -#endif - - /* ** You can set this cell to 1 to force the gl drawing stuff to be ** one command per packet */ int __glXDebug = 0; -/* -** forward prototype declarations -*/ -int __glXCloseDisplay(Display *dpy, XExtCodes *codes); - - /************************************************************************/ /* Extension required boiler plate */ @@ -277,19 +120,9 @@ "GLXUnsupportedPrivateRequest", }; -int __glXCloseDisplay(Display *dpy, XExtCodes *codes) +static int __glXCloseDisplay(Display *dpy, XExtCodes *codes) { - GLXContext gc; - - gc = __glXGetCurrentContext(); - if (dpy == gc->currentDpy) { - __glXSetCurrentContext(&dummyContext); -#ifdef GLX_DIRECT_RENDERING - _glapi_set_dispatch(NULL); /* no-op functions */ -#endif - __glXFreeContext(gc); - } - + __glXSetCurrentContextNull(dpy); return XextRemoveDisplay(__glXExtensionInfo, dpy); } @@ -368,15 +201,6 @@ Xfree((char*)priv->serverGLXversion); priv->serverGLXversion = 0x0; /* to protect against double free's */ } - -#if 0 /* GLX_DIRECT_RENDERING */ - /* Free the direct rendering per display data */ - if (priv->driDisplay.private) - (*priv->driDisplay.destroyDisplay)(priv->dpy, - priv->driDisplay.private); - priv->driDisplay.private = NULL; -#endif - Xfree((char*) priv); return 0; } @@ -1085,26 +909,6 @@ /************************************************************************/ -GLXContext glXGetCurrentContext(void) -{ - GLXContext cx = __glXGetCurrentContext(); - - if (cx == &dummyContext) { - return NULL; - } else { - return cx; - } -} - -GLXDrawable glXGetCurrentDrawable(void) -{ - GLXContext gc = __glXGetCurrentContext(); - return gc->currentDrawable; -} - - -/************************************************************************/ - #ifdef GLX_DIRECT_RENDERING /* Return the DRI per screen structure */ __DRIscreen *__glXFindDRIScreen(__DRInativeDisplay *dpy, int scrn) @@ -1130,347 +934,6 @@ } #endif -/************************************************************************/ - -static Bool SendMakeCurrentRequest( Display *dpy, CARD8 opcode, - GLXContextID gc, GLXContextTag old_gc, GLXDrawable draw, GLXDrawable read, - xGLXMakeCurrentReply * reply ); - -/** - * Sends a GLX protocol message to the specified display to make the context - * and the drawables current. - * - * \param dpy Display to send the message to. - * \param opcode Major opcode value for the display. - * \param gc_id Context tag for the context to be made current. - * \param draw Drawable ID for the "draw" drawable. - * \param read Drawable ID for the "read" drawable. - * \param reply Space to store the X-server's reply. - * - * \warning - * This function assumes that \c dpy is locked with \c LockDisplay on entry. - */ -static Bool SendMakeCurrentRequest( Display *dpy, CARD8 opcode, - GLXContextID gc_id, GLXContextTag gc_tag, - GLXDrawable draw, GLXDrawable read, - xGLXMakeCurrentReply * reply ) -{ - if ( draw == read ) { - xGLXMakeCurrentReq *req; - - GetReq(GLXMakeCurrent,req); - req->reqType = opcode; - req->glxCode = X_GLXMakeCurrent; - req->drawable = draw; - req->context = gc_id; - req->oldContextTag = gc_tag; - } - else { - __GLXdisplayPrivate *priv = __glXInitialize(dpy); - - /* If the server can support the GLX 1.3 version, we should - * perfer that. Not only that, some servers support GLX 1.3 but - * not the SGI extension. - */ - - if ( (priv->majorVersion > 1) || (priv->minorVersion >= 3) ) { - xGLXMakeContextCurrentReq *req; - - GetReq(GLXMakeContextCurrent,req); - req->reqType = opcode; - req->glxCode = X_GLXMakeContextCurrent; - req->drawable = draw; - req->readdrawable = read; - req->context = gc_id; - req->oldContextTag = gc_tag; - } - else { - xGLXVendorPrivateWithReplyReq *vpreq; - xGLXMakeCurrentReadSGIReq *req; - - GetReqExtra(GLXVendorPrivateWithReply, - sz_xGLXMakeCurrentReadSGIReq-sz_xGLXVendorPrivateWithReplyReq,vpreq); - req = (xGLXMakeCurrentReadSGIReq *)vpreq; - req->reqType = opcode; - req->glxCode = X_GLXVendorPrivateWithReply; - req->vendorCode = X_GLXvop_MakeCurrentReadSGI; - req->drawable = draw; - req->readable = read; - req->context = gc_id; - req->oldContextTag = gc_tag; - } - } - - return _XReply(dpy, (xReply*) reply, 0, False); -} - - -#ifdef GLX_DIRECT_RENDERING -static Bool BindContextWrapper( Display *dpy, GLXContext gc, - GLXDrawable draw, GLXDrawable read ) -{ - return (*gc->driContext.bindContext)(dpy, gc->screen, draw, read, - & gc->driContext); -} - - -static Bool UnbindContextWrapper( GLXContext gc ) -{ - return (*gc->driContext.unbindContext)(gc->currentDpy, gc->screen, - gc->currentDrawable, - gc->currentReadable, - & gc->driContext ); -} -#endif /* GLX_DIRECT_RENDERING */ - - -/* -** Make a particular context current. -** NOTE: this is in this file so that it can access dummyContext. -*/ -USED static Bool MakeContextCurrent(Display *dpy, GLXDrawable draw, - GLXDrawable read, GLXContext gc) -{ - xGLXMakeCurrentReply reply; - GLXContext oldGC; - CARD8 opcode, oldOpcode; - Bool sentRequestToOldDpy = False; - Bool bindReturnValue = True; - - opcode = __glXSetupForCommand(dpy); - if (!opcode) { - return GL_FALSE; - } - - /* - ** Make sure that the new context has a nonzero ID. In the request, - ** a zero context ID is used only to mean that we bind to no current - ** context. - */ - if ((gc != NULL) && (gc->xid == None)) { - return GL_FALSE; - } - - oldGC = __glXGetCurrentContext(); - oldOpcode = (gc == oldGC) ? opcode : __glXSetupForCommand(dpy); - if (!oldOpcode) { - return GL_FALSE; - } - - if ((dpy != oldGC->currentDpy || (gc && gc->isDirect)) && - !oldGC->isDirect && oldGC != &dummyContext) { - /* - ** We are either switching from one dpy to another and have to - ** send a request to the previous dpy to unbind the previous - ** context, or we are switching away from a indirect context to - ** a direct context and have to send a request to the dpy to - ** unbind the previous context. - */ - sentRequestToOldDpy = True; - LockDisplay(oldGC->currentDpy); - if ( ! SendMakeCurrentRequest( oldGC->currentDpy, oldOpcode, None, - oldGC->currentContextTag, None, None, - &reply ) ) { - /* The make current failed. Just return GL_FALSE. */ - UnlockDisplay(oldGC->currentDpy); - SyncHandle(); - return GL_FALSE; - } - - oldGC->currentContextTag = 0; - } - - _glapi_check_multithread(); - -#ifdef GLX_DIRECT_RENDERING - /* Unbind the old direct rendering context */ - if (oldGC->isDirect) { - if (oldGC->driContext.private) { - if (! UnbindContextWrapper( oldGC )) { - /* The make current failed. Just return GL_FALSE. */ - return GL_FALSE; - } - } - oldGC->currentContextTag = 0; - } - - /* Bind the direct rendering context to the drawable */ - if (gc && gc->isDirect) { - if (gc->driContext.private) { - bindReturnValue = BindContextWrapper( dpy, gc, draw, read ); - } - } else { -#endif - /* Send a glXMakeCurrent request to bind the new context. */ - LockDisplay(dpy); - - bindReturnValue = SendMakeCurrentRequest( dpy, opcode, - gc ? gc->xid : None, - oldGC->currentContextTag, - draw, read, &reply ); - UnlockDisplay(dpy); -#ifdef GLX_DIRECT_RENDERING - } -#endif - - - if (!bindReturnValue) { - /* The make current failed. */ - if (gc && !gc->isDirect) { - SyncHandle(); - } - -#ifdef GLX_DIRECT_RENDERING - /* If the old context was direct rendering, then re-bind to it. */ - if (oldGC->isDirect) { - if (oldGC->driContext.private) { - if (! BindContextWrapper( oldGC->currentDpy, oldGC, - oldGC->currentDrawable, - oldGC->currentReadable )) { - /* - ** The request failed; this cannot happen with the - ** current API. If in the future the API is - ** extended to allow context sharing between - ** clients, then this may fail (because another - ** client may have grabbed the context); in that - ** case, we cannot undo the previous request, and - ** cannot adhere to the "no-op" behavior. - */ - } - } - } else -#endif - /* - ** If we had just sent a request to a previous dpy, we have to - ** undo that request (because if a command fails, it should act - ** like a no-op) by making current to the previous context and - ** drawable. - */ - if (sentRequestToOldDpy) { - if ( !SendMakeCurrentRequest( oldGC->currentDpy, oldOpcode, - oldGC->xid, 0, - oldGC->currentDrawable, - oldGC->currentReadable, &reply ) ) { - UnlockDisplay(oldGC->currentDpy); - SyncHandle(); - /* - ** The request failed; this cannot happen with the - ** current API. If in the future the API is extended to - ** allow context sharing between clients, then this may - ** fail (because another client may have grabbed the - ** context); in that case, we cannot undo the previous - ** request, and cannot adhere to the "no-op" behavior. - */ - } - else { - UnlockDisplay(oldGC->currentDpy); - } - oldGC->currentContextTag = reply.contextTag; - } - return GL_FALSE; - } - - /* Update our notion of what is current */ - __glXLock(); - if (gc == oldGC) { - /* - ** Even though the contexts are the same the drawable might have - ** changed. Note that gc cannot be the dummy, and that oldGC - ** cannot be NULL, therefore if they are the same, gc is not - ** NULL and not the dummy. - */ - gc->currentDrawable = draw; - gc->currentReadable = read; - } else { - if (oldGC != &dummyContext) { - /* Old current context is no longer current to anybody */ - oldGC->currentDpy = 0; - oldGC->currentDrawable = None; - oldGC->currentReadable = None; - oldGC->currentContextTag = 0; - - if (oldGC->xid == None) { - /* - ** We are switching away from a context that was - ** previously destroyed, so we need to free the memory - ** for the old handle. - */ -#ifdef GLX_DIRECT_RENDERING - /* Destroy the old direct rendering context */ - if (oldGC->isDirect) { - if (oldGC->driContext.private) { - (*oldGC->driContext.destroyContext) - (dpy, oldGC->screen, oldGC->driContext.private); - oldGC->driContext.private = NULL; - } - } -#endif - __glXFreeContext(oldGC); - } - } - if (gc) { - __glXSetCurrentContext(gc); -#ifdef GLX_DIRECT_RENDERING - if (!gc->isDirect) { - if (!IndirectAPI) - IndirectAPI = __glXNewIndirectAPI(); - _glapi_set_dispatch(IndirectAPI); -# ifdef GLX_USE_APPLEGL - do { - extern void XAppleDRIUseIndirectDispatch(void); - XAppleDRIUseIndirectDispatch(); - } while (0); -# endif - } -#else - /* if not direct rendering, always need indirect dispatch */ - if (!IndirectAPI) - IndirectAPI = __glXNewIndirectAPI(); - _glapi_set_dispatch(IndirectAPI); -#endif - gc->currentDpy = dpy; - gc->currentDrawable = draw; - gc->currentReadable = read; - - if ( ! gc->isDirect ) { - __GLXattribute * state = (__GLXattribute *)(gc->client_state_private); - - gc->currentContextTag = reply.contextTag; - if ( state->array_state == NULL ) { - (void) glGetString( GL_EXTENSIONS ); - (void) glGetString( GL_VERSION ); - __glXInitVertexArrayState(gc); - } - } - else { - gc->currentContextTag = -1; - } - } else { - __glXSetCurrentContext(&dummyContext); -#ifdef GLX_DIRECT_RENDERING - _glapi_set_dispatch(NULL); /* no-op functions */ -#endif - } - } - __glXUnlock(); - return GL_TRUE; -} - - -PUBLIC Bool glXMakeCurrent(Display *dpy, GLXDrawable draw, GLXContext gc) -{ - return MakeContextCurrent( dpy, draw, draw, gc ); -} - -PUBLIC GLX_ALIAS(Bool, glXMakeCurrentReadSGI, - (Display *dpy, GLXDrawable d, GLXDrawable r, GLXContext ctx), - (dpy, d, r, ctx), MakeContextCurrent) - -PUBLIC GLX_ALIAS(Bool, glXMakeContextCurrent, - (Display *dpy, GLXDrawable d, GLXDrawable r, GLXContext ctx), - (dpy, d, r, ctx), MakeContextCurrent) - - #ifdef DEBUG void __glXDumpDrawBuffer(__GLXcontext *ctx) {