summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Hellstrom <thellstrom-at-vmware-dot-com>2009-04-02 11:00:41 +0200
committerThomas Hellstrom <thellstrom-at-vmware-dot-com>2009-04-02 11:33:20 +0200
commit96fd3df59a161957876bfd7a49992e5a2130370c (patch)
treee9fa2479b5bf78f847cb6762d21f5b5583cbd780
parent8e753d04045a82062ac34d3b2622eb9dba8af374 (diff)
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 <thellstrom-at-vmware-dot-com>
-rw-r--r--src/glx/x11/glxclient.h5
-rw-r--r--src/glx/x11/glxcurrent.c48
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) {