diff --git a/dix/dixutils.c b/dix/dixutils.c index 5de74c8b4..cdd370bd6 100644 --- a/dix/dixutils.c +++ b/dix/dixutils.c @@ -866,3 +866,28 @@ InitCallbackManager(void) { DeleteCallbackManager(); } + +/** + * Coordinates the global GL context used by modules in the X Server + * doing rendering with OpenGL. + * + * When setting a GL context (glXMakeCurrent() or eglMakeCurrent()), + * there is an expensive implied glFlush() required by the GLX and EGL + * APIs, so modules don't want to have to do it on every request. But + * the individual modules using GL also don't know about each other, + * so they have to coordinate who owns the current context. + * + * When you're about to do a MakeCurrent, you should set this variable + * to your context's address, and you can skip MakeCurrent if it's + * already set to yours. + * + * When you're about to do a DestroyContext, you should set this to + * NULL if it's set to your context. + * + * When you're about to do an unbindContext on a DRI driver, you + * should set this to NULL. Despite the unbindContext interface + * sounding like it only unbinds the passed in context, it actually + * unconditionally clears the dispatch table even if the given + * context wasn't current. + */ +void *lastGLContext = NULL; diff --git a/glx/glxcmds.c b/glx/glxcmds.c index 187e42665..a451d2b43 100644 --- a/glx/glxcmds.c +++ b/glx/glxcmds.c @@ -188,7 +188,7 @@ validGlxDrawable(ClientPtr client, XID id, int type, int access_mode, void __glXContextDestroy(__GLXcontext * context) { - __glXFlushContextCache(); + lastGLContext = NULL; } static void @@ -434,9 +434,8 @@ static void StopUsingContext(__GLXcontext * glxc) { if (glxc) { - if (glxc == __glXLastContext) { - /* Tell server GL library */ - __glXLastContext = 0; + if (glxc == lastGLContext) { + lastGLContext = NULL; } glxc->currentClient = NULL; if (!glxc->idExists) { @@ -448,7 +447,7 @@ StopUsingContext(__GLXcontext * glxc) static void StartUsingContext(__GLXclientState * cl, __GLXcontext * glxc) { - __glXLastContext = glxc; + lastGLContext = glxc; glxc->currentClient = cl->client; } @@ -627,7 +626,7 @@ DoMakeCurrent(__GLXclientState * cl, if (!(*prevglxc->loseCurrent) (prevglxc)) { return __glXError(GLXBadContext); } - __glXFlushContextCache(); + lastGLContext = NULL; if (!prevglxc->isDirect) { prevglxc->drawPriv = NULL; prevglxc->readPriv = NULL; diff --git a/glx/glxext.c b/glx/glxext.c index c9b8cc5b3..85fd219df 100644 --- a/glx/glxext.c +++ b/glx/glxext.c @@ -47,12 +47,6 @@ #include "indirect_table.h" #include "indirect_util.h" -/* -** The last context used by the server. It is the context that is current -** from the server's perspective. -*/ -__GLXcontext *__glXLastContext; - /* ** X resources. */ @@ -79,7 +73,7 @@ static int __glXDispatch(ClientPtr); static void ResetExtension(ExtensionEntry * extEntry) { - __glXFlushContextCache(); + lastGLContext = NULL; } /* @@ -141,8 +135,8 @@ DrawableGone(__GLXdrawable * glxPriv, XID xid) (c->drawPriv == glxPriv || c->readPriv == glxPriv)) { /* just force a re-bind the next time through */ (*c->loseCurrent) (c); - if (c == __glXLastContext) - __glXFlushContextCache(); + if (c == lastGLContext) + lastGLContext = NULL; } if (c->drawPriv == glxPriv) c->drawPriv = NULL; @@ -203,8 +197,8 @@ __glXFreeContext(__GLXcontext * cx) free(cx->feedbackBuf); free(cx->selectBuf); - if (cx == __glXLastContext) { - __glXFlushContextCache(); + if (cx == lastGLContext) { + lastGLContext = NULL; } /* We can get here through both regular dispatching from @@ -406,12 +400,6 @@ GlxExtensionInit(void) /************************************************************************/ -void -__glXFlushContextCache(void) -{ - __glXLastContext = 0; -} - /* ** Make a context the current one for the GL (in this implementation, there ** is only one instance of the GL, and we use it to serve all GL clients by @@ -449,7 +437,7 @@ __glXForceCurrent(__GLXclientState * cl, GLXContextTag tag, int *error) if (cx->wait && (*cx->wait) (cx, cl, error)) return NULL; - if (cx == __glXLastContext) { + if (cx == lastGLContext) { /* No need to re-bind */ return cx; } @@ -463,7 +451,7 @@ __glXForceCurrent(__GLXclientState * cl, GLXContextTag tag, int *error) return 0; } } - __glXLastContext = cx; + lastGLContext = cx; return cx; } diff --git a/glx/glxserver.h b/glx/glxserver.h index 3f2ae3593..a324b290f 100644 --- a/glx/glxserver.h +++ b/glx/glxserver.h @@ -84,7 +84,6 @@ void __glXScreenInitVisuals(__GLXscreen * screen); /* ** The last context used (from the server's persective) is cached. */ -extern __GLXcontext *__glXLastContext; extern __GLXcontext *__glXForceCurrent(__GLXclientState *, GLXContextTag, int *); diff --git a/include/dix.h b/include/dix.h index 8371df072..f42e23655 100644 --- a/include/dix.h +++ b/include/dix.h @@ -608,4 +608,6 @@ CorePointerProc(DeviceIntPtr dev, int what); extern _X_HIDDEN int CoreKeyboardProc(DeviceIntPtr dev, int what); +extern _X_EXPORT void *lastGLContext; + #endif /* DIX_H */