Index: src/glx/x11/glxext.c =================================================================== RCS file: /cvs/mesa/Mesa/src/glx/x11/glxext.c,v retrieving revision 1.26 diff -u -d -r1.26 glxext.c --- src/glx/x11/glxext.c 4 Oct 2006 16:22:24 -0000 1.26 +++ src/glx/x11/glxext.c 5 Oct 2006 23:16:34 -0000 @@ -1485,6 +1485,11 @@ GLXDrawable draw, GLXDrawable read, xGLXMakeCurrentReply * reply ) { + Bool ret; + + + LockDisplay(dpy); + if ( draw == read ) { xGLXMakeCurrentReq *req; @@ -1531,7 +1536,12 @@ } } - return _XReply(dpy, (xReply*) reply, 0, False); + ret = _XReply(dpy, (xReply*) reply, 0, False); + + UnlockDisplay(dpy); + SyncHandle(); + + return ret; } @@ -1562,143 +1572,74 @@ GLXDrawable read, GLXContext gc) { xGLXMakeCurrentReply reply; - GLXContext oldGC; - CARD8 opcode, oldOpcode; - Bool sentRequestToOldDpy = False; - Bool bindReturnValue = True; + const GLXContext oldGC = __glXGetCurrentContext(); + const CARD8 opcode = __glXSetupForCommand(dpy); + const CARD8 oldOpcode = ((gc == oldGC) || (oldGC == &dummyContext)) + ? opcode : __glXSetupForCommand(oldGC->currentDpy); + Bool bindReturnValue; - 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)) { + if (!opcode || !oldOpcode) { return GL_FALSE; } - oldGC = __glXGetCurrentContext(); - oldOpcode = (gc == oldGC) ? opcode : __glXSetupForCommand(oldGC->currentDpy); - if (!oldOpcode) { + /* 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; } - 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 { + bindReturnValue = (gc->driContext.private) + ? BindContextWrapper(dpy, gc, draw, read) + : False; + } else #endif - /* Send a glXMakeCurrent request to bind the new context. */ - LockDisplay(dpy); + { + const GLXContextID old_context_tag = + (dpy != oldGC->currentDpy) ? None : oldGC->currentContextTag; + /* Send a glXMakeCurrent request to bind the new context. */ bindReturnValue = SendMakeCurrentRequest( dpy, opcode, gc ? gc->xid : None, - oldGC->currentContextTag, + old_context_tag, draw, read, &reply ); - UnlockDisplay(dpy); -#ifdef GLX_DIRECT_RENDERING } -#endif if (!bindReturnValue) { - /* The make current failed. */ - if (gc && !gc->isDirect) { - SyncHandle(); - } + return False; + } + + if ((dpy != oldGC->currentDpy || (gc && gc->isDirect)) && + !oldGC->isDirect && oldGC != &dummyContext) { + xGLXMakeCurrentReply dummy_reply; + + /* 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. + */ + (void) SendMakeCurrentRequest(oldGC->currentDpy, oldOpcode, None, + oldGC->currentContextTag, None, None, + & dummy_reply); + } #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; + /* Unbind the old direct rendering context */ + if (oldGC->isDirect && oldGC->driContext.private) { + (void) UnbindContextWrapper(oldGC); } +#endif + + /* Update our notion of what is current */ __glXLock();