mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2024-12-03 23:24:17 +08:00
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 commit80b67a3b44
. Fixes:80b67a3b44
glx: Lift sending the MakeCurrent request to top-level code Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/4639 Acked-by: Marek Olšák <marek.olsak@amd.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10260>
This commit is contained in:
parent
d148540e5a
commit
fc9b3b260e
@ -1,3 +1,5 @@
|
||||
glx@glx-make-current,Crash
|
||||
glx@glx-multi-window-single-context,Fail
|
||||
glx@glx-multithread-buffer,Fail
|
||||
glx@glx-swap-pixmap-bad,Fail
|
||||
glx@glx-visuals-depth -pixmap,Crash
|
||||
|
@ -4,6 +4,7 @@ spec@egl_ext_device_base@conformance,Crash
|
||||
spec@egl_khr_wait_sync@conformance,Crash
|
||||
glx@glx-copy-sub-buffer samples=2,Crash
|
||||
glx@glx-copy-sub-buffer samples=4,Crash
|
||||
glx@glx-make-current,Crash
|
||||
glx@glx-multithread-buffer,Fail
|
||||
glx@glx-multithread-texture,Timeout
|
||||
glx@glx-swap-pixmap-bad,Fail
|
||||
|
@ -1,4 +1,5 @@
|
||||
shaders@glsl-vs-loop
|
||||
spec@arb_framebuffer_srgb@blit renderbuffer srgb single_sampled enabled clear
|
||||
glx@glx-multi-window-single-context
|
||||
glx@glx_arb_sync_control@timing
|
||||
spec@egl_chromium_sync_control@conformance
|
||||
|
@ -1,5 +1,8 @@
|
||||
fast_color_clear@fcc-read-after-clear copy rb,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-visuals-depth -pixmap,Crash
|
||||
glx@glx-visuals-stencil -pixmap,Crash
|
||||
|
@ -1,6 +1,9 @@
|
||||
glx@glx_arb_sync_control@timing -fullscreen -msc-delta 1,Fail
|
||||
glx@glx_arb_sync_control@timing -waitformsc -msc-delta 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-visuals-depth -pixmap,Crash
|
||||
glx@glx-visuals-stencil -pixmap,Crash
|
||||
|
@ -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=6: 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-2: skip
|
||||
glx/glx-multithread-makecurrent-3: skip
|
||||
glx/glx-multithread-makecurrent-4: skip
|
||||
glx/glx-multithread-texture: fail
|
||||
glx/glx-query-drawable-glx_fbconfig_id-window: fail
|
||||
glx/glx-swap-copy: fail
|
||||
glx/glx-swap-event_async: skip
|
||||
glx/glx-swap-event_event: 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=6: skip
|
||||
glx/glx-copy-sub-buffer samples=8: skip
|
||||
glx/glx-make-current: fail
|
||||
glx/glx-multi-context-front: fail
|
||||
glx/glx-multi-window-single-context: fail
|
||||
glx/glx-multithread-makecurrent-1: skip
|
||||
glx/glx-multithread-makecurrent-2: skip
|
||||
glx/glx-multithread-makecurrent-3: skip
|
||||
glx/glx-multithread-makecurrent-4: skip
|
||||
glx/glx-query-drawable-glx_fbconfig_id-window: fail
|
||||
glx/glx-swap-copy: fail
|
||||
glx/glx-swap-event_async: skip
|
||||
glx/glx-swap-event_event: skip
|
||||
|
@ -2,6 +2,7 @@ glx@extension string sanity,Fail
|
||||
glx@glx-copy-sub-buffer,Fail
|
||||
glx@glx-copy-sub-buffer samples=2,Fail
|
||||
glx@glx-copy-sub-buffer samples=4,Fail
|
||||
glx@glx-multi-window-single-context,Fail
|
||||
glx@glx-multithread-buffer,Fail
|
||||
glx@glx-multithread-texture,Fail
|
||||
glx@glx-swap-copy,Fail
|
||||
@ -11,6 +12,7 @@ glx@glx-visuals-depth,Crash
|
||||
glx@glx-visuals-depth -pixmap,Crash
|
||||
glx@glx-visuals-stencil,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_ext_import_context@free context,Fail
|
||||
glx@glx_ext_import_context@get context id,Fail
|
||||
|
@ -165,100 +165,17 @@ glXGetCurrentDrawable(void)
|
||||
return gc->currentDrawable;
|
||||
}
|
||||
|
||||
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 ((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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a particular context current.
|
||||
*
|
||||
* \note This is in this file so that it can access dummyContext.
|
||||
*/
|
||||
static Bool
|
||||
MakeContextCurrent(Display * dpy, GLXDrawable draw,
|
||||
GLXDrawable read, GLXContext gc_user)
|
||||
{
|
||||
struct glx_context *gc = (struct glx_context *) gc_user;
|
||||
struct glx_context *oldGC = __glXGetCurrentContext();
|
||||
Bool ret = GL_FALSE;
|
||||
|
||||
/* 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
|
||||
@ -269,97 +186,66 @@ MakeContextCurrent(Display * dpy, GLXDrawable draw,
|
||||
}
|
||||
|
||||
_glapi_check_multithread();
|
||||
|
||||
__glXLock();
|
||||
|
||||
if (oldGC == gc &&
|
||||
gc->currentDrawable == draw &&
|
||||
gc->currentReadable == read) {
|
||||
/* Same context and drawables: no op, just return */
|
||||
ret = GL_TRUE;
|
||||
gc->currentDrawable == draw && gc->currentReadable == read) {
|
||||
__glXUnlock();
|
||||
return True;
|
||||
}
|
||||
|
||||
else if (oldGC == gc) {
|
||||
/* Same context and new drawables: update drawable bindings */
|
||||
if (should_send(dpy, gc)) {
|
||||
if (!SendMakeCurrentRequest(dpy, gc->xid, gc->currentContextTag,
|
||||
draw, read, &gc->currentContextTag)) {
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
/* can't have only one be 0 */
|
||||
if (!!draw != !!read) {
|
||||
__glXUnlock();
|
||||
__glXSendError(dpy, BadMatch, None, X_GLXMakeContextCurrent, True);
|
||||
return False;
|
||||
}
|
||||
|
||||
if (gc->vtable->bind(gc, gc, draw, read) != Success) {
|
||||
if (oldGC != &dummyContext) {
|
||||
if (--oldGC->thread_refcount == 0) {
|
||||
oldGC->vtable->unbind(oldGC, gc);
|
||||
oldGC->currentDpy = 0;
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
goto out;
|
||||
__glXUnlock();
|
||||
__glXSendError(dpy, GLXBadContext, None, X_GLXMakeContextCurrent,
|
||||
False);
|
||||
return GL_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
else {
|
||||
/* Different contexts: release the old, bind the new */
|
||||
GLXContextTag oldTag = oldGC->currentContextTag;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
if (gc->thread_refcount == 0) {
|
||||
gc->currentDpy = dpy;
|
||||
gc->currentDrawable = draw;
|
||||
gc->currentReadable = read;
|
||||
}
|
||||
gc->thread_refcount++;
|
||||
__glXSetCurrentContext(gc);
|
||||
} else {
|
||||
__glXSetCurrentContextNull();
|
||||
|
||||
if (gc) {
|
||||
/*
|
||||
* MESA_multithread_makecurrent makes this complicated. We need to
|
||||
* send the request if the new context is
|
||||
*
|
||||
* 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:
|
||||
if (oldGC->thread_refcount == 0 && oldGC != &dummyContext && oldGC->xid == None) {
|
||||
/* We are switching away from a context that was
|
||||
* previously destroyed, so we need to free the memory
|
||||
* for the old handle. */
|
||||
oldGC->vtable->destroy(oldGC);
|
||||
}
|
||||
|
||||
__glXUnlock();
|
||||
return ret;
|
||||
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
@ -61,40 +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;
|
||||
GLXContextTag tag;
|
||||
Display *dpy = gc->psc->dpy;
|
||||
Bool 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.
|
||||
*/
|
||||
if (state && state->array_state == NULL) {
|
||||
gc->currentDpy = gc->psc->dpy;
|
||||
__glXSetCurrentContext(gc);
|
||||
__indirect_glGetString(GL_EXTENSIONS);
|
||||
__indirect_glGetString(GL_VERSION);
|
||||
__glXInitVertexArrayState(gc);
|
||||
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);
|
||||
|
||||
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
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user