apple: Change from XExtDisplayInfo to struct glx_display
[mesa.git] / src / glx / glxcurrent.c
index 98f66c22898203f88009683c75e6f5c795e4c0a1..1f845ce65e18f07db1af00574dc92c2b8af052de 100644 (file)
@@ -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,50 +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) {
+      __glXUnlock();
+      return True;
    }
 
-   if (oldGC != &dummyContext && oldGC != gc) {
-      oldGC->vtable->unbind(oldGC, gc);
-      oldGC->currentDpy = 0;
-      oldGC->currentDrawable = None;
-      oldGC->currentReadable = None;
-      oldGC->thread_id = 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.
-         */
-        oldGC->vtable->destroy(oldGC);
+   if (oldGC != &dummyContext) {
+      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) {
-      ret = gc->vtable->bind(gc, oldGC, draw, read);
-      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();
    }
 
+   __glXUnlock();
+
    if (ret) {
-      __glXGenerateError(dpy, gc, None, ret, X_GLXMakeContextCurrent);
+      __glXGenerateError(dpy, None, ret, X_GLXMakeContextCurrent);
       return GL_FALSE;
    }