diff options
author | Adam Jackson <[email protected]> | 2019-09-26 11:07:42 -0400 |
---|---|---|
committer | Adam Jackson <[email protected]> | 2019-09-26 11:07:42 -0400 |
commit | 8b6d3f2c782b1e6559b49f106f24d2d586f0d71d (patch) | |
tree | 4a4f8f74559142a341108197b55b443050040da9 /src/glx/indirect_glx.c | |
parent | a14e3b43be17997ab67a362addddab44ac856869 (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.c | 140 |
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 |