diff options
Diffstat (limited to 'src/glx/glxcurrent.c')
-rw-r--r-- | src/glx/glxcurrent.c | 65 |
1 files changed, 38 insertions, 27 deletions
diff --git a/src/glx/glxcurrent.c b/src/glx/glxcurrent.c index 36317383544..1f845ce65e1 100644 --- a/src/glx/glxcurrent.c +++ b/src/glx/glxcurrent.c @@ -189,7 +189,7 @@ glXGetCurrentDrawable(void) } static void -__glXGenerateError(Display * dpy, struct glx_context *gc, XID resource, +__glXGenerateError(Display * dpy, XID resource, BYTE errorCode, CARD16 minorCode) { xError error; @@ -198,7 +198,7 @@ __glXGenerateError(Display * dpy, struct glx_context *gc, XID resource, error.resourceID = resource; error.sequenceNumber = dpy->request; error.type = X_Error; - error.majorCode = gc->majorOpcode; + error.majorCode = __glXSetupForCommand(dpy); error.minorCode = minorCode; _XError(dpy, &error); } @@ -216,6 +216,16 @@ MakeContextCurrent(Display * dpy, GLXDrawable draw, struct glx_context *oldGC = __glXGetCurrentContext(); int ret = Success; + /* XXX: If this is left out, then libGL ends up not having this + * symbol, and drivers using it fail to load. Compare the + * implementation of this symbol to _glapi_noop_enable_warnings(), + * though, which gets into the library despite no callers, the same + * prototypes, and the same compile flags to the files containing + * them. Moving the definition to glapi_nop.c gets it into the + * library, though. + */ + (void)_glthread_GetID(); + /* 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. @@ -225,55 +235,56 @@ MakeContextCurrent(Display * dpy, GLXDrawable draw, } if (gc == NULL && (draw != None || read != None)) { - __glXGenerateError(dpy, gc, (draw != None) ? draw : read, + __glXGenerateError(dpy, (draw != None) ? draw : read, BadMatch, X_GLXMakeContextCurrent); return False; } if (gc != NULL && (draw == None || read == None)) { - __glXGenerateError(dpy, gc, None, BadMatch, X_GLXMakeContextCurrent); + __glXGenerateError(dpy, None, BadMatch, X_GLXMakeContextCurrent); return False; } _glapi_check_multithread(); - if (gc != NULL && gc->thread_id != 0 && gc->thread_id != _glthread_GetID()) { - __glXGenerateError(dpy, gc, gc->xid, - BadAccess, X_GLXMakeContextCurrent); - return False; - } - + __glXLock(); if (oldGC == gc && - gc->currentDrawable == draw && gc->currentReadable == read) + gc->currentDrawable == draw && gc->currentReadable == read) { + __glXUnlock(); return True; + } if (oldGC != &dummyContext) { - oldGC->vtable->unbind(oldGC, gc); - oldGC->currentDpy = 0; - oldGC->currentDrawable = None; - oldGC->currentReadable = None; - oldGC->thread_id = 0; + if (--oldGC->thread_refcount == 0) { + oldGC->vtable->unbind(oldGC, gc); + oldGC->currentDpy = 0; + oldGC->currentDrawable = None; + oldGC->currentReadable = None; + + if (oldGC->xid == None && oldGC != gc) { + /* We are switching away from a context that was + * previously destroyed, so we need to free the memory + * for the old handle. */ + oldGC->vtable->destroy(oldGC); + } + } } if (gc) { - gc->currentDpy = dpy; - gc->currentDrawable = draw; - gc->currentReadable = read; - gc->thread_id = _glthread_GetID(); + if (gc->thread_refcount++ == 0) { + gc->currentDpy = dpy; + gc->currentDrawable = draw; + gc->currentReadable = read; + } __glXSetCurrentContext(gc); ret = gc->vtable->bind(gc, oldGC, draw, read); } else { __glXSetCurrentContextNull(); } - if (oldGC != &dummyContext && oldGC->xid == None && oldGC != gc) { - /* We are switching away from a context that was - * previously destroyed, so we need to free the memory - * for the old handle. */ - oldGC->vtable->destroy(oldGC); - } + __glXUnlock(); if (ret) { - __glXGenerateError(dpy, gc, None, ret, X_GLXMakeContextCurrent); + __glXGenerateError(dpy, None, ret, X_GLXMakeContextCurrent); return GL_FALSE; } |