[4/6] glx: Lift sending the MakeCurrent request to top-level code

Submitted by Adam Jackson on Nov. 14, 2017, 8:13 p.m.

Details

Message ID 20171114201306.28276-5-ajax@redhat.com
State New
Headers show
Series "glx: Implement GLX_EXT_no_config_context" ( rev: 1 ) in Mesa

Not browsing as part of any series.

Commit Message

Adam Jackson Nov. 14, 2017, 8:13 p.m.
Somewhat terrifyingly, we never sent this for direct contexts, which
means the server never knew the context/drawable bindings.

To handle this sanely, pull the request code up out of the indirect
backend, and rewrite the context switch path to call it as appropriate.
This attempts to preserve the existing behavior of not calling unbind()
on the context if its refcount would not drop to zero, which is why the

Patch hide | download patch | download mbox

diff is a little uglier than I'd like.

Signed-off-by: Adam Jackson <ajax@redhat.com>
---
 src/glx/glxcurrent.c   | 181 +++++++++++++++++++++++++++++++++++++------------
 src/glx/indirect_glx.c | 125 ++++------------------------------
 2 files changed, 151 insertions(+), 155 deletions(-)

diff --git a/src/glx/glxcurrent.c b/src/glx/glxcurrent.c
index 9f8bf7cee1..7ee8a04a60 100644
--- a/src/glx/glxcurrent.c
+++ b/src/glx/glxcurrent.c
@@ -165,17 +165,85 @@  glXGetCurrentDrawable(void)
    return gc->currentDrawable;
 }
 
-/**
- * Make a particular context current.
- *
- * \note This is in this file so that it can access dummyContext.
- */
+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 (out_tag)
+      *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
 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
@@ -186,59 +254,86 @@  MakeContextCurrent(Display * dpy, GLXDrawable draw,
    }
 
    _glapi_check_multithread();
-
    __glXLock();
+
+   /* Same context and drawables: no op, just return */
    if (oldGC == gc &&
-       gc->currentDrawable == draw && gc->currentReadable == read) {
-      __glXUnlock();
-      return True;
+       gc->currentDrawable == draw &&
+       gc->currentReadable == read) {
+      ret = GL_TRUE;
    }
 
-   if (oldGC != &dummyContext) {
-      if (--oldGC->thread_refcount == 0) {
-	 oldGC->vtable->unbind(oldGC, gc);
-	 oldGC->currentDpy = 0;
+   /* Same context and new drawbles: update drawable bindings */
+   else if (oldGC == gc) {
+      if (!SendMakeCurrentRequest(dpy, gc->xid, gc->currentContextTag,
+                                  draw, read, &gc->currentContextTag)) {
+         goto out;
       }
-   }
 
-   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) {
+      if (gc->vtable->bind(gc, gc, draw, read) != Success) {
          __glXSetCurrentContextNull();
-         __glXUnlock();
-         __glXSendError(dpy, GLXBadContext, None, X_GLXMakeContextCurrent,
-                        False);
-         return GL_FALSE;
+         goto out;
       }
+   }
 
-      if (gc->thread_refcount == 0) {
-         gc->currentDpy = dpy;
-         gc->currentDrawable = draw;
-         gc->currentReadable = read;
+   /* Different contexts: release the old, bind the new */
+   else {
+      if (oldGC != &dummyContext) {
+         if (--oldGC->thread_refcount == 0) {
+            if (!SendMakeCurrentRequest(dpy, None, oldGC->currentContextTag,
+                                        None, None, &oldGC->currentContextTag)){
+               goto out;
+            }
+
+            oldGC->vtable->unbind(oldGC, gc);
+
+            if (!oldGC->xid == None) {
+               /* destroyed context, free it */
+               oldGC->vtable->destroy(oldGC);
+            } else {
+               SetGC(oldGC, NULL, None, None);
+            }
+         }
       }
-      gc->thread_refcount++;
-      __glXSetCurrentContext(gc);
-   } else {
       __glXSetCurrentContextNull();
-   }
 
-   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);
+      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 (!gc->isDirect || !gc->thread_refcount || new_drawables) {
+            if (!SendMakeCurrentRequest(dpy, gc->xid, oldGC->currentContextTag,
+                                        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();
-
-   return GL_TRUE;
+   return ret;
 }
 
 
diff --git a/src/glx/indirect_glx.c b/src/glx/indirect_glx.c
index b552b5768a..8ac8fd1b47 100644
--- a/src/glx/indirect_glx.c
+++ b/src/glx/indirect_glx.c
@@ -61,129 +61,30 @@  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)
 {
-   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;
-   }
-
-   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.
-       */
-      __GLXattribute *state = gc->client_state_private;
-      if (state && state->array_state == NULL) {
-         glGetString(GL_EXTENSIONS);
-         glGetString(GL_VERSION);
-         __glXInitVertexArrayState(gc);
-      }
+   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.
+    */
+   __GLXattribute *state = gc->client_state_private;
+   if (state && state->array_state == NULL) {
+      glGetString(GL_EXTENSIONS);
+      glGetString(GL_VERSION);
+      __glXInitVertexArrayState(gc);
    }
 
-   return !sent;
+   return state != NULL && state->array_state != NULL;
 }
 
 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

Comments

A couple style nits below.  At least some of this patch will have to
change pending possible changes to patch 3.  Aside from that, I think
this is ok.

On 11/14/2017 12:13 PM, Adam Jackson wrote:
> Somewhat terrifyingly, we never sent this for direct contexts, which
> means the server never knew the context/drawable bindings.
> 
> To handle this sanely, pull the request code up out of the indirect
> backend, and rewrite the context switch path to call it as appropriate.
> This attempts to preserve the existing behavior of not calling unbind()
> on the context if its refcount would not drop to zero, which is why the
> diff is a little uglier than I'd like.
> 
> Signed-off-by: Adam Jackson <ajax@redhat.com>
> ---
>  src/glx/glxcurrent.c   | 181 +++++++++++++++++++++++++++++++++++++------------
>  src/glx/indirect_glx.c | 125 ++++------------------------------
>  2 files changed, 151 insertions(+), 155 deletions(-)
> 
> diff --git a/src/glx/glxcurrent.c b/src/glx/glxcurrent.c
> index 9f8bf7cee1..7ee8a04a60 100644
> --- a/src/glx/glxcurrent.c
> +++ b/src/glx/glxcurrent.c
> @@ -165,17 +165,85 @@ glXGetCurrentDrawable(void)
>     return gc->currentDrawable;
>  }
>  
> -/**
> - * Make a particular context current.
> - *
> - * \note This is in this file so that it can access dummyContext.
> - */
> +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 (out_tag)
> +      *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
>  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
> @@ -186,59 +254,86 @@ MakeContextCurrent(Display * dpy, GLXDrawable draw,
>     }
>  
>     _glapi_check_multithread();
> -
>     __glXLock();
> +
> +   /* Same context and drawables: no op, just return */
>     if (oldGC == gc &&
> -       gc->currentDrawable == draw && gc->currentReadable == read) {
> -      __glXUnlock();
> -      return True;
> +       gc->currentDrawable == draw &&
> +       gc->currentReadable == read) {
> +      ret = GL_TRUE;
>     }
>  
> -   if (oldGC != &dummyContext) {
> -      if (--oldGC->thread_refcount == 0) {
> -	 oldGC->vtable->unbind(oldGC, gc);
> -	 oldGC->currentDpy = 0;
> +   /* Same context and new drawbles: update drawable bindings */
> +   else if (oldGC == gc) {

I'm not a fan of

   if () {
      ...
   }

   /* comment */
   else if () {
      ...
   }

I think the comment should move inside the else and the else should go
back with the }.

> +      if (!SendMakeCurrentRequest(dpy, gc->xid, gc->currentContextTag,
> +                                  draw, read, &gc->currentContextTag)) {
> +         goto out;
>        }
> -   }
>  
> -   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) {
> +      if (gc->vtable->bind(gc, gc, draw, read) != Success) {
>           __glXSetCurrentContextNull();
> -         __glXUnlock();
> -         __glXSendError(dpy, GLXBadContext, None, X_GLXMakeContextCurrent,
> -                        False);
> -         return GL_FALSE;
> +         goto out;
>        }
> +   }
>  
> -      if (gc->thread_refcount == 0) {
> -         gc->currentDpy = dpy;
> -         gc->currentDrawable = draw;
> -         gc->currentReadable = read;
> +   /* Different contexts: release the old, bind the new */
> +   else {
> +      if (oldGC != &dummyContext) {
> +         if (--oldGC->thread_refcount == 0) {
> +            if (!SendMakeCurrentRequest(dpy, None, oldGC->currentContextTag,
> +                                        None, None, &oldGC->currentContextTag)){
                                                                                  ^
Space before the {.

> +               goto out;
> +            }
> +
> +            oldGC->vtable->unbind(oldGC, gc);
> +
> +            if (!oldGC->xid == None) {
> +               /* destroyed context, free it */
> +               oldGC->vtable->destroy(oldGC);
> +            } else {
> +               SetGC(oldGC, NULL, None, None);
> +            }
> +         }
>        }
> -      gc->thread_refcount++;
> -      __glXSetCurrentContext(gc);
> -   } else {
>        __glXSetCurrentContextNull();
> -   }
>  
> -   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);
> +      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);

I know krh would complain about the (not strictly necessary) parens.

> +
> +         if (!gc->isDirect || !gc->thread_refcount || new_drawables) {
> +            if (!SendMakeCurrentRequest(dpy, gc->xid, oldGC->currentContextTag,
> +                                        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);
> +         }

Since the body and the condition are each only one line, the { and } are
optional.  This is a fairly recent Mesa style change.

> +         gc->thread_refcount++;
> +         __glXSetCurrentContext(gc);
> +      }
>     }
> +   ret = GL_TRUE;
>  
> +out:
>     __glXUnlock();
> -
> -   return GL_TRUE;
> +   return ret;
>  }
>  
>  
> diff --git a/src/glx/indirect_glx.c b/src/glx/indirect_glx.c
> index b552b5768a..8ac8fd1b47 100644
> --- a/src/glx/indirect_glx.c
> +++ b/src/glx/indirect_glx.c
> @@ -61,129 +61,30 @@ 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)
>  {
> -   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;
> -   }
> -
> -   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.
> -       */
> -      __GLXattribute *state = gc->client_state_private;
> -      if (state && state->array_state == NULL) {
> -         glGetString(GL_EXTENSIONS);
> -         glGetString(GL_VERSION);
> -         __glXInitVertexArrayState(gc);
> -      }
> +   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.
> +    */
> +   __GLXattribute *state = gc->client_state_private;
> +   if (state && state->array_state == NULL) {
> +      glGetString(GL_EXTENSIONS);
> +      glGetString(GL_VERSION);
> +      __glXInitVertexArrayState(gc);
>     }
>  
> -   return !sent;
> +   return state != NULL && state->array_state != NULL;
>  }
>  
>  static void
>  indirect_unbind_context(struct glx_context *gc, struct glx_context *new)
>  {

Mark the parameters UNUSED so that I don't get extra warnings. :)

> -   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
On Tue, 2017-11-14 at 14:03 -0800, Ian Romanick wrote:

> >  static void
> >  indirect_unbind_context(struct glx_context *gc, struct glx_context *new)
> >  {
> 
> Mark the parameters UNUSED so that I don't get extra warnings. :)

How do I provoke these warnings in my own build?

- ajax
On 11/14/2017 02:18 PM, Adam Jackson wrote:
> On Tue, 2017-11-14 at 14:03 -0800, Ian Romanick wrote:
> 
>>>  static void
>>>  indirect_unbind_context(struct glx_context *gc, struct glx_context *new)
>>>  {
>>
>> Mark the parameters UNUSED so that I don't get extra warnings. :)
> 
> How do I provoke these warnings in my own build?

I use -Wall -Wextra -Wunsafe-loop-optimizations -Werror=format-security
-Wno-sign-compare, but I think -Wunused (set by -Wall) is sufficient to
provoke this particular warning.

> - ajax