[PATCH 02/12] glx: Move the GLX variable caching what GL context is current to dix.
Eric Anholt
eric at anholt.net
Fri Apr 18 11:40:00 PDT 2014
GLX is trying to track whether the context it wants is current, to
avoid the glFlush() (and the rest of the overhead) that occurs on all
MakeCurrent calls. However, its cache can be incorrect now that
glamor exists. This is a step toward getting glamor to coordinate
with GLX.
Signed-off-by: Eric Anholt <eric at anholt.net>
---
dix/dixutils.c | 25 +++++++++++++++++++++++++
glx/glxcmds.c | 11 +++++------
glx/glxext.c | 26 +++++++-------------------
glx/glxserver.h | 1 -
include/dix.h | 2 ++
5 files changed, 39 insertions(+), 26 deletions(-)
diff --git a/dix/dixutils.c b/dix/dixutils.c
index 5de74c8..cdd370b 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 187e426..a451d2b 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 c9b8cc5..85fd219 100644
--- a/glx/glxext.c
+++ b/glx/glxext.c
@@ -48,12 +48,6 @@
#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.
*/
RESTYPE __glXContextRes;
@@ -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 3f2ae35..a324b29 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 8371df0..f42e236 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 */
--
1.9.2
More information about the xorg-devel
mailing list