From 96fd3df59a161957876bfd7a49992e5a2130370c Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Thu, 2 Apr 2009 11:00:41 +0200 Subject: [PATCH] glx: MakeCurrent fixes. 1) If MakeContextCurrent is called with (NULL, None, None), Don't send the request to the X server if the current context is direct. 2) Return BadMatch in some error cases according to the glx spec. 3) If MakeContextCurrent is called for a context which is current in another thread, return BadAccess according to the glx spec. Signed-off-by: Thomas Hellstrom --- src/glx/x11/glxclient.h | 5 +++++ src/glx/x11/glxcurrent.c | 48 ++++++++++++++++++++++++++++++++-------- 2 files changed, 44 insertions(+), 9 deletions(-) diff --git a/src/glx/x11/glxclient.h b/src/glx/x11/glxclient.h index fa3ec26e60a..bf68d0f8910 100644 --- a/src/glx/x11/glxclient.h +++ b/src/glx/x11/glxclient.h @@ -426,6 +426,11 @@ struct __GLXcontextRec { int server_minor; /**< Minor version number. */ /*@}*/ + /** + * Thread ID we're currently current in. Zero if none. + */ + unsigned long thread_id; + char gl_extension_bits[ __GL_EXT_BYTES ]; }; diff --git a/src/glx/x11/glxcurrent.c b/src/glx/x11/glxcurrent.c index 4d0a7c65eba..01f42332413 100644 --- a/src/glx/x11/glxcurrent.c +++ b/src/glx/x11/glxcurrent.c @@ -339,6 +339,20 @@ FetchDRIDrawable(Display * dpy, GLXDrawable glxDrawable, GLXContext gc) } #endif /* GLX_DIRECT_RENDERING */ +static void +__glXGenerateError(Display *dpy, GLXContext gc, XID resource, + BYTE errorCode, CARD16 minorCode) +{ + xError error; + + error.errorCode = errorCode; + error.resourceID = resource; + error.sequenceNumber = dpy->request; + error.type = X_Error; + error.majorCode = gc->majorOpcode; + error.minorCode = minorCode; + _XError(dpy, &error); +} /** * Make a particular context current. @@ -369,8 +383,26 @@ MakeContextCurrent(Display * dpy, GLXDrawable draw, return GL_FALSE; } + if (gc == NULL && (draw != None || read != None)) { + __glXGenerateError(dpy, gc, (draw != None) ? draw : read, + BadMatch, X_GLXMakeContextCurrent); + return False; + } + if (gc != NULL && (draw == None || read == None)) { + __glXGenerateError(dpy, gc, 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; + } + #ifdef GLX_DIRECT_RENDERING /* Bind the direct rendering context to the drawable */ if (gc && gc->driContext) { @@ -378,21 +410,17 @@ MakeContextCurrent(Display * dpy, GLXDrawable draw, __GLXDRIdrawable *pread = FetchDRIDrawable(dpy, read, gc); if ((pdraw == NULL) || (pread == NULL)) { - xError error; - - error.errorCode = GLXBadDrawable; - error.resourceID = (pdraw == NULL) ? draw : read; - error.sequenceNumber = dpy->request; - error.type = X_Error; - error.majorCode = gc->majorOpcode; - error.minorCode = X_GLXMakeContextCurrent; - _XError(dpy, &error); + __glXGenerateError(dpy, gc, (pdraw == NULL) ? draw : read, + GLXBadDrawable, X_GLXMakeContextCurrent); return False; } bindReturnValue = (gc->driContext->bindContext) (gc->driContext, pdraw, pread); } + else if (!gc && oldGC && oldGC->driContext) { + bindReturnValue = True; + } else #endif { @@ -453,6 +481,7 @@ MakeContextCurrent(Display * dpy, GLXDrawable draw, oldGC->currentDrawable = None; oldGC->currentReadable = None; oldGC->currentContextTag = 0; + oldGC->thread_id = 0; if (oldGC->xid == None) { /* We are switching away from a context that was @@ -477,6 +506,7 @@ MakeContextCurrent(Display * dpy, GLXDrawable draw, gc->currentDpy = dpy; gc->currentDrawable = draw; gc->currentReadable = read; + gc->thread_id = _glthread_GetID(); #ifdef GLX_DIRECT_RENDERING if (!gc->driContext) { -- 2.30.2