Commit fc9b3b26 authored by Adam Jackson's avatar Adam Jackson 🎧 Committed by Marge Bot
Browse files

Revert "glx: Lift sending the MakeCurrent request to top-level code"

This provokes crashes in Cinnamon for some reason that I haven't
diagnosed yet.

This reverts commit 80b67a3b.

Fixes: 80b67a3b glx: Lift sending the MakeCurrent request to top-level code
Closes: #4639

Acked-by: default avatarMarek Olšák <marek.olsak@amd.com>
Part-of: <!10260>
parent d148540e
glx@glx-make-current,Crash
glx@glx-multi-window-single-context,Fail
glx@glx-multithread-buffer,Fail glx@glx-multithread-buffer,Fail
glx@glx-swap-pixmap-bad,Fail glx@glx-swap-pixmap-bad,Fail
glx@glx-visuals-depth -pixmap,Crash glx@glx-visuals-depth -pixmap,Crash
......
...@@ -4,6 +4,7 @@ spec@egl_ext_device_base@conformance,Crash ...@@ -4,6 +4,7 @@ spec@egl_ext_device_base@conformance,Crash
spec@egl_khr_wait_sync@conformance,Crash spec@egl_khr_wait_sync@conformance,Crash
glx@glx-copy-sub-buffer samples=2,Crash glx@glx-copy-sub-buffer samples=2,Crash
glx@glx-copy-sub-buffer samples=4,Crash glx@glx-copy-sub-buffer samples=4,Crash
glx@glx-make-current,Crash
glx@glx-multithread-buffer,Fail glx@glx-multithread-buffer,Fail
glx@glx-multithread-texture,Timeout glx@glx-multithread-texture,Timeout
glx@glx-swap-pixmap-bad,Fail glx@glx-swap-pixmap-bad,Fail
......
shaders@glsl-vs-loop shaders@glsl-vs-loop
spec@arb_framebuffer_srgb@blit renderbuffer srgb single_sampled enabled clear spec@arb_framebuffer_srgb@blit renderbuffer srgb single_sampled enabled clear
glx@glx-multi-window-single-context
glx@glx_arb_sync_control@timing glx@glx_arb_sync_control@timing
spec@egl_chromium_sync_control@conformance spec@egl_chromium_sync_control@conformance
fast_color_clear@fcc-read-after-clear copy rb,Fail fast_color_clear@fcc-read-after-clear copy rb,Fail
fast_color_clear@fcc-read-after-clear copy tex,Fail fast_color_clear@fcc-read-after-clear copy tex,Fail
glx@glx-make-current,Crash
glx@glx-multi-window-single-context,Fail
glx@glx-query-drawable-glx_fbconfig_id-window,Fail
glx@glx-swap-pixmap-bad,Fail glx@glx-swap-pixmap-bad,Fail
glx@glx-visuals-depth -pixmap,Crash glx@glx-visuals-depth -pixmap,Crash
glx@glx-visuals-stencil -pixmap,Crash glx@glx-visuals-stencil -pixmap,Crash
......
glx@glx_arb_sync_control@timing -fullscreen -msc-delta 1,Fail glx@glx_arb_sync_control@timing -fullscreen -msc-delta 1,Fail
glx@glx_arb_sync_control@timing -waitformsc -msc-delta 2,Fail glx@glx_arb_sync_control@timing -waitformsc -msc-delta 2,Fail
glx@glx-copy-sub-buffer samples=2,Fail glx@glx-copy-sub-buffer samples=2,Fail
glx@glx-make-current,Crash
glx@glx-multi-window-single-context,Fail
glx@glx-query-drawable-glx_fbconfig_id-window,Fail
glx@glx-swap-pixmap-bad,Fail glx@glx-swap-pixmap-bad,Fail
glx@glx-visuals-depth -pixmap,Crash glx@glx-visuals-depth -pixmap,Crash
glx@glx-visuals-stencil -pixmap,Crash glx@glx-visuals-stencil -pixmap,Crash
......
...@@ -9,11 +9,14 @@ glx/glx-copy-sub-buffer samples=32: skip ...@@ -9,11 +9,14 @@ glx/glx-copy-sub-buffer samples=32: skip
glx/glx-copy-sub-buffer samples=4: fail glx/glx-copy-sub-buffer samples=4: fail
glx/glx-copy-sub-buffer samples=6: skip glx/glx-copy-sub-buffer samples=6: skip
glx/glx-copy-sub-buffer samples=8: skip glx/glx-copy-sub-buffer samples=8: skip
glx/glx-make-current: fail
glx/glx-multi-window-single-context: fail
glx/glx-multithread-makecurrent-1: skip glx/glx-multithread-makecurrent-1: skip
glx/glx-multithread-makecurrent-2: skip glx/glx-multithread-makecurrent-2: skip
glx/glx-multithread-makecurrent-3: skip glx/glx-multithread-makecurrent-3: skip
glx/glx-multithread-makecurrent-4: skip glx/glx-multithread-makecurrent-4: skip
glx/glx-multithread-texture: fail glx/glx-multithread-texture: fail
glx/glx-query-drawable-glx_fbconfig_id-window: fail
glx/glx-swap-copy: fail glx/glx-swap-copy: fail
glx/glx-swap-event_async: skip glx/glx-swap-event_async: skip
glx/glx-swap-event_event: skip glx/glx-swap-event_event: skip
......
...@@ -10,11 +10,14 @@ glx/glx-copy-sub-buffer samples=32: skip ...@@ -10,11 +10,14 @@ glx/glx-copy-sub-buffer samples=32: skip
glx/glx-copy-sub-buffer samples=4: skip glx/glx-copy-sub-buffer samples=4: skip
glx/glx-copy-sub-buffer samples=6: skip glx/glx-copy-sub-buffer samples=6: skip
glx/glx-copy-sub-buffer samples=8: skip glx/glx-copy-sub-buffer samples=8: skip
glx/glx-make-current: fail
glx/glx-multi-context-front: fail glx/glx-multi-context-front: fail
glx/glx-multi-window-single-context: fail
glx/glx-multithread-makecurrent-1: skip glx/glx-multithread-makecurrent-1: skip
glx/glx-multithread-makecurrent-2: skip glx/glx-multithread-makecurrent-2: skip
glx/glx-multithread-makecurrent-3: skip glx/glx-multithread-makecurrent-3: skip
glx/glx-multithread-makecurrent-4: skip glx/glx-multithread-makecurrent-4: skip
glx/glx-query-drawable-glx_fbconfig_id-window: fail
glx/glx-swap-copy: fail glx/glx-swap-copy: fail
glx/glx-swap-event_async: skip glx/glx-swap-event_async: skip
glx/glx-swap-event_event: skip glx/glx-swap-event_event: skip
......
...@@ -2,6 +2,7 @@ glx@extension string sanity,Fail ...@@ -2,6 +2,7 @@ glx@extension string sanity,Fail
glx@glx-copy-sub-buffer,Fail glx@glx-copy-sub-buffer,Fail
glx@glx-copy-sub-buffer samples=2,Fail glx@glx-copy-sub-buffer samples=2,Fail
glx@glx-copy-sub-buffer samples=4,Fail glx@glx-copy-sub-buffer samples=4,Fail
glx@glx-multi-window-single-context,Fail
glx@glx-multithread-buffer,Fail glx@glx-multithread-buffer,Fail
glx@glx-multithread-texture,Fail glx@glx-multithread-texture,Fail
glx@glx-swap-copy,Fail glx@glx-swap-copy,Fail
...@@ -11,6 +12,7 @@ glx@glx-visuals-depth,Crash ...@@ -11,6 +12,7 @@ glx@glx-visuals-depth,Crash
glx@glx-visuals-depth -pixmap,Crash glx@glx-visuals-depth -pixmap,Crash
glx@glx-visuals-stencil,Crash glx@glx-visuals-stencil,Crash
glx@glx-visuals-stencil -pixmap,Crash glx@glx-visuals-stencil -pixmap,Crash
glx@glx-query-drawable-glx_fbconfig_id-window,Fail
glx@glx_arb_create_context_es2_profile@invalid opengl es version,Fail glx@glx_arb_create_context_es2_profile@invalid opengl es version,Fail
glx@glx_ext_import_context@free context,Fail glx@glx_ext_import_context@free context,Fail
glx@glx_ext_import_context@get context id,Fail glx@glx_ext_import_context@get context id,Fail
......
...@@ -165,100 +165,17 @@ glXGetCurrentDrawable(void) ...@@ -165,100 +165,17 @@ glXGetCurrentDrawable(void)
return gc->currentDrawable; return gc->currentDrawable;
} }
static Bool /**
SendMakeCurrentRequest(Display * dpy, GLXContextID gc_id, * Make a particular context current.
GLXContextTag gc_tag, GLXDrawable draw, *
GLXDrawable read, GLXContextTag *out_tag) * \note This is in this file so that it can access dummyContext.
{ */
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 ((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 (ret == 1)
*out_tag = reply.contextTag;
UnlockDisplay(dpy);
SyncHandle();
return ret;
}
static void
SetGC(struct glx_context *gc, Display *dpy, GLXDrawable draw, GLXDrawable read)
{
gc->currentDpy = dpy;
gc->currentDrawable = draw;
gc->currentReadable = read;
}
static Bool
should_send(Display *dpy, struct glx_context *gc)
{
/* always send for indirect contexts */
if (!gc->isDirect)
return 1;
/* don't send for broken servers. */
if (VendorRelease(dpy) < 12006000 || VendorRelease(dpy) >= 40000000)
return 0;
return 1;
}
static Bool static Bool
MakeContextCurrent(Display * dpy, GLXDrawable draw, MakeContextCurrent(Display * dpy, GLXDrawable draw,
GLXDrawable read, GLXContext gc_user) GLXDrawable read, GLXContext gc_user)
{ {
struct glx_context *gc = (struct glx_context *) gc_user; struct glx_context *gc = (struct glx_context *) gc_user;
struct glx_context *oldGC = __glXGetCurrentContext(); struct glx_context *oldGC = __glXGetCurrentContext();
Bool ret = GL_FALSE;
/* Make sure that the new context has a nonzero ID. In the request, /* 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 * a zero context ID is used only to mean that we bind to no current
...@@ -269,97 +186,66 @@ MakeContextCurrent(Display * dpy, GLXDrawable draw, ...@@ -269,97 +186,66 @@ MakeContextCurrent(Display * dpy, GLXDrawable draw,
} }
_glapi_check_multithread(); _glapi_check_multithread();
__glXLock();
__glXLock();
if (oldGC == gc && if (oldGC == gc &&
gc->currentDrawable == draw && gc->currentDrawable == draw && gc->currentReadable == read) {
gc->currentReadable == read) { __glXUnlock();
/* Same context and drawables: no op, just return */ return True;
ret = GL_TRUE;
} }
else if (oldGC == gc) { /* can't have only one be 0 */
/* Same context and new drawables: update drawable bindings */ if (!!draw != !!read) {
if (should_send(dpy, gc)) { __glXUnlock();
if (!SendMakeCurrentRequest(dpy, gc->xid, gc->currentContextTag, __glXSendError(dpy, BadMatch, None, X_GLXMakeContextCurrent, True);
draw, read, &gc->currentContextTag)) { return False;
goto out; }
}
if (oldGC != &dummyContext) {
if (--oldGC->thread_refcount == 0) {
oldGC->vtable->unbind(oldGC, gc);
oldGC->currentDpy = 0;
} }
}
if (gc->vtable->bind(gc, gc, draw, read) != Success) { if (gc) {
/* Attempt to bind the context. We do this before mucking with
* gc and __glXSetCurrentContext to properly handle our state in
* case of an error.
*
* If an error occurs, set the Null context since we've already
* blown away our old context. The caller is responsible for
* figuring out how to handle setting a valid context.
*/
if (gc->vtable->bind(gc, oldGC, draw, read) != Success) {
__glXSetCurrentContextNull(); __glXSetCurrentContextNull();
goto out; __glXUnlock();
__glXSendError(dpy, GLXBadContext, None, X_GLXMakeContextCurrent,
False);
return GL_FALSE;
} }
}
else { if (gc->thread_refcount == 0) {
/* Different contexts: release the old, bind the new */ gc->currentDpy = dpy;
GLXContextTag oldTag = oldGC->currentContextTag; gc->currentDrawable = draw;
gc->currentReadable = read;
if (oldGC != &dummyContext) {
if (--oldGC->thread_refcount == 0) {
if (oldGC->xid != None &&
should_send(dpy, oldGC) &&
!SendMakeCurrentRequest(dpy, None, oldTag, None, None,
&oldGC->currentContextTag)) {
goto out;
}
oldGC->vtable->unbind(oldGC, gc);
if (oldGC->xid == None) {
/* destroyed context, free it */
oldGC->vtable->destroy(oldGC);
oldTag = 0;
} else {
SetGC(oldGC, NULL, None, None);
oldTag = oldGC->currentContextTag;
}
}
} }
gc->thread_refcount++;
__glXSetCurrentContext(gc);
} else {
__glXSetCurrentContextNull(); __glXSetCurrentContextNull();
}
if (gc) { if (oldGC->thread_refcount == 0 && oldGC != &dummyContext && oldGC->xid == None) {
/* /* We are switching away from a context that was
* MESA_multithread_makecurrent makes this complicated. We need to * previously destroyed, so we need to free the memory
* send the request if the new context is * for the old handle. */
* oldGC->vtable->destroy(oldGC);
* a) indirect (may be current to another client), or
* b) (direct and) newly being made current, or
* c) (direct and) being bound to new drawables
*/
Bool new_drawables = gc->currentReadable != read ||
gc->currentDrawable != draw;
if (should_send(dpy, gc)) {
if (!gc->isDirect || !gc->thread_refcount || new_drawables) {
if (!SendMakeCurrentRequest(dpy, gc->xid, oldTag, draw, read,
&gc->currentContextTag)) {
goto out;
}
}
}
if (gc->vtable->bind(gc, oldGC, draw, read) != Success) {
__glXSendError(dpy, GLXBadContext, None, X_GLXMakeContextCurrent,
False);
goto out;
}
if (gc->thread_refcount == 0) {
SetGC(gc, dpy, draw, read);
}
gc->thread_refcount++;
__glXSetCurrentContext(gc);
}
} }
ret = GL_TRUE;
out:
__glXUnlock(); __glXUnlock();
return ret;
return GL_TRUE;
} }
......
...@@ -61,40 +61,135 @@ indirect_destroy_context(struct glx_context *gc) ...@@ -61,40 +61,135 @@ indirect_destroy_context(struct glx_context *gc)
free((char *) 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 static int
indirect_bind_context(struct glx_context *gc, struct glx_context *old, indirect_bind_context(struct glx_context *gc, struct glx_context *old,
GLXDrawable draw, GLXDrawable read) GLXDrawable draw, GLXDrawable read)
{ {
__GLXattribute *state = gc->client_state_private; GLXContextTag tag;
Display *dpy = gc->psc->dpy;
if (!IndirectAPI) Bool sent;
IndirectAPI = __glXNewIndirectAPI();
_glapi_set_dispatch(IndirectAPI); if (old != &dummyContext && !old->isDirect && old->psc->dpy == dpy) {
tag = old->currentContextTag;
/* The indirect vertex array state must to be initialised after we old->currentContextTag = 0;
* have setup the context, as it needs to query server attributes. } else {
* tag = 0;
* 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);
__indirect_glGetString(GL_EXTENSIONS);
__indirect_glGetString(GL_VERSION);
__glXInitVertexArrayState(gc);
} }
if (state != NULL && state->array_state != NULL) sent = SendMakeCurrentRequest(dpy, gc->xid, tag, draw, read,
return Success; &gc->currentContextTag);
return BadAlloc; 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 !sent;
} }
static void static void
indirect_unbind_context(struct glx_context *gc, struct glx_context *new) 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 static void
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment