summaryrefslogtreecommitdiffstats
path: root/src/glx/indirect_glx.c
diff options
context:
space:
mode:
authorAdam Jackson <[email protected]>2019-09-26 11:07:42 -0400
committerAdam Jackson <[email protected]>2019-09-26 11:07:42 -0400
commit8b6d3f2c782b1e6559b49f106f24d2d586f0d71d (patch)
tree4a4f8f74559142a341108197b55b443050040da9 /src/glx/indirect_glx.c
parenta14e3b43be17997ab67a362addddab44ac856869 (diff)
Revert "glx: Lift sending the MakeCurrent request to top-level code"
Apparently this provokes crashes elsewhere in code unrelated to MakeCurrent. I hate GLX so very very much. This reverts commit 999c2aed8826f403b071f52b040ce25b56d35f9d. Gitlab: https://gitlab.freedesktop.org/mesa/mesa/issues/1207
Diffstat (limited to 'src/glx/indirect_glx.c')
-rw-r--r--src/glx/indirect_glx.c140
1 files changed, 117 insertions, 23 deletions
diff --git a/src/glx/indirect_glx.c b/src/glx/indirect_glx.c
index c23db139165..f370daf8bb6 100644
--- a/src/glx/indirect_glx.c
+++ b/src/glx/indirect_glx.c
@@ -61,41 +61,135 @@ indirect_destroy_context(struct glx_context *gc)
free((char *) gc);
}
+static Bool
+SendMakeCurrentRequest(Display * dpy, GLXContextID gc_id,
+ GLXContextTag gc_tag, GLXDrawable draw,
+ GLXDrawable read, GLXContextTag *out_tag)
+{
+ xGLXMakeCurrentReply reply;
+ Bool ret;
+ int opcode = __glXSetupForCommand(dpy);
+
+ LockDisplay(dpy);
+
+ if (draw == read) {
+ xGLXMakeCurrentReq *req;
+
+ GetReq(GLXMakeCurrent, req);
+ req->reqType = opcode;
+ req->glxCode = X_GLXMakeCurrent;
+ req->drawable = draw;
+ req->context = gc_id;
+ req->oldContextTag = gc_tag;
+ }
+ else {
+ struct glx_display *priv = __glXInitialize(dpy);
+
+ /* If the server can support the GLX 1.3 version, we should
+ * perfer that. Not only that, some servers support GLX 1.3 but
+ * not the SGI extension.
+ */
+
+ if ((priv->majorVersion > 1) || (priv->minorVersion >= 3)) {
+ xGLXMakeContextCurrentReq *req;
+
+ GetReq(GLXMakeContextCurrent, req);
+ req->reqType = opcode;
+ req->glxCode = X_GLXMakeContextCurrent;
+ req->drawable = draw;
+ req->readdrawable = read;
+ req->context = gc_id;
+ req->oldContextTag = gc_tag;
+ }
+ else {
+ xGLXVendorPrivateWithReplyReq *vpreq;
+ xGLXMakeCurrentReadSGIReq *req;
+
+ GetReqExtra(GLXVendorPrivateWithReply,
+ sz_xGLXMakeCurrentReadSGIReq -
+ sz_xGLXVendorPrivateWithReplyReq, vpreq);
+ req = (xGLXMakeCurrentReadSGIReq *) vpreq;
+ req->reqType = opcode;
+ req->glxCode = X_GLXVendorPrivateWithReply;
+ req->vendorCode = X_GLXvop_MakeCurrentReadSGI;
+ req->drawable = draw;
+ req->readable = read;
+ req->context = gc_id;
+ req->oldContextTag = gc_tag;
+ }
+ }
+
+ ret = _XReply(dpy, (xReply *) &reply, 0, False);
+
+ if (out_tag)
+ *out_tag = reply.contextTag;
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+
+ return ret;
+}
+
static int
indirect_bind_context(struct glx_context *gc, struct glx_context *old,
GLXDrawable draw, GLXDrawable read)
{
- __GLXattribute *state = gc->client_state_private;
-
- if (!IndirectAPI)
- IndirectAPI = __glXNewIndirectAPI();
- _glapi_set_dispatch(IndirectAPI);
-
- /* The indirect vertex array state must to be initialised after we
- * have setup the context, as it needs to query server attributes.
- *
- * At the point this is called gc->currentDpy is not initialized
- * nor is the thread's current context actually set. Hence the
- * cleverness before the GetString calls.
- */
- if (state && state->array_state == NULL) {
- gc->currentDpy = gc->psc->dpy;
- __glXSetCurrentContext(gc);
- __glXSetCurrentContext(gc);
- __indirect_glGetString(GL_EXTENSIONS);
- __indirect_glGetString(GL_VERSION);
- __glXInitVertexArrayState(gc);
+ GLXContextTag tag;
+ Display *dpy = gc->psc->dpy;
+ Bool sent;
+
+ if (old != &dummyContext && !old->isDirect && old->psc->dpy == dpy) {
+ tag = old->currentContextTag;
+ old->currentContextTag = 0;
+ } else {
+ tag = 0;
}
- if (state != NULL && state->array_state != NULL)
- return Success;
+ sent = SendMakeCurrentRequest(dpy, gc->xid, tag, draw, read,
+ &gc->currentContextTag);
+
+ if (sent) {
+ if (!IndirectAPI)
+ IndirectAPI = __glXNewIndirectAPI();
+ _glapi_set_dispatch(IndirectAPI);
+
+ /* The indirect vertex array state must to be initialised after we
+ * have setup the context, as it needs to query server attributes.
+ *
+ * At the point this is called gc->currentDpy is not initialized
+ * nor is the thread's current context actually set. Hence the
+ * cleverness before the GetString calls.
+ */
+ __GLXattribute *state = gc->client_state_private;
+ if (state && state->array_state == NULL) {
+ gc->currentDpy = gc->psc->dpy;
+ __glXSetCurrentContext(gc);
+ __indirect_glGetString(GL_EXTENSIONS);
+ __indirect_glGetString(GL_VERSION);
+ __glXInitVertexArrayState(gc);
+ }
+ }
- return BadAlloc;
+ return !sent;
}
static void
indirect_unbind_context(struct glx_context *gc, struct glx_context *new)
{
+ Display *dpy = gc->psc->dpy;
+
+ if (gc == new)
+ return;
+
+ /* We are either switching to no context, away from an indirect
+ * context to a direct context or from one dpy to another and have
+ * to send a request to the dpy to unbind the previous context.
+ */
+ if (!new || new->isDirect || new->psc->dpy != dpy) {
+ SendMakeCurrentRequest(dpy, None, gc->currentContextTag, None, None,
+ NULL);
+ gc->currentContextTag = 0;
+ }
}
static void