Example #1
0
/*
** Initialize the client side extension code.
*/
_X_HIDDEN __GLXdisplayPrivate *
__glXInitialize(Display * dpy)
{
   XExtDisplayInfo *info = __glXFindDisplay(dpy);
   XExtData **privList, *private, *found;
   __GLXdisplayPrivate *dpyPriv;
   XEDataObject dataObj;
   int major, minor;
#ifdef GLX_DIRECT_RENDERING
   Bool glx_direct, glx_accel;
#endif

   /* The one and only long long lock */
   __glXLock();

   if (!XextHasExtension(info)) {
      /* No GLX extension supported by this server. Oh well. */
      __glXUnlock();
      XMissingExtension(dpy, __glXExtensionName);
      return 0;
   }

   /* See if a display private already exists.  If so, return it */
   dataObj.display = dpy;
   privList = XEHeadOfExtensionList(dataObj);
   found = XFindOnExtensionList(privList, info->codes->extension);
   if (found) {
      __glXUnlock();
      return (__GLXdisplayPrivate *) found->private_data;
   }

   /* See if the versions are compatible */
   if (!QueryVersion(dpy, info->codes->major_opcode, &major, &minor)) {
      /* The client and server do not agree on versions.  Punt. */
      __glXUnlock();
      return 0;
   }

   /*
    ** Allocate memory for all the pieces needed for this buffer.
    */
   private = (XExtData *) Xmalloc(sizeof(XExtData));
Example #2
0
/**
 * 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();

   /* 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
    * context.
    */
   if ((gc != NULL) && (gc->xid == None)) {
      return GL_FALSE;
   }

   _glapi_check_multithread();

   __glXLock();
   if (oldGC == gc &&
       gc->currentDrawable == draw && gc->currentReadable == read) {
      __glXUnlock();
      return True;
   }

   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();
         __glXUnlock();
         __glXGenerateError(dpy, None, GLXBadContext, X_GLXMakeContextCurrent);
         return GL_FALSE;
      }

      if (gc->thread_refcount == 0) {
         gc->currentDpy = dpy;
         gc->currentDrawable = draw;
         gc->currentReadable = read;
      }
      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);
   }

   __glXUnlock();

   return GL_TRUE;
}
Example #3
0
/**
 * 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)
{
   const GLXContext oldGC = __glXGetCurrentContext();
#ifdef GLX_USE_APPLEGL
   bool error = apple_glx_make_current_context(dpy, 
                   (oldGC && oldGC != &dummyContext) ? oldGC->apple : NULL, 
                   gc ? gc->apple : NULL, draw);
   
   apple_glx_diagnostic("%s: error %s\n", __func__, error ? "YES" : "NO");
   if(error)
      return GL_FALSE;
#else
   xGLXMakeCurrentReply reply;
   const CARD8 opcode = __glXSetupForCommand(dpy);
   const CARD8 oldOpcode = ((gc == oldGC) || (oldGC == &dummyContext))
      ? opcode : __glXSetupForCommand(oldGC->currentDpy);
   Bool bindReturnValue;
   __GLXattribute *state;

   if (!opcode || !oldOpcode) {
      return 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
    * context.
    */
   if ((gc != NULL) && (gc->xid == None)) {
      return GL_FALSE;
   }

   if (gc == NULL && (draw != None || read != None)) {
      __glXGenerateError(dpy, gc, (draw != None) ? draw : read,
                         BadMatch, X_GLXMakeContextCurrent);
      return False;
   }
   if (gc != NULL && (draw == None || read == None)) {
      __glXGenerateError(dpy, gc, None, BadMatch, X_GLXMakeContextCurrent);
      return False;
   }

   _glapi_check_multithread();

   if (gc != NULL && gc->thread_id != 0 && gc->thread_id != _glthread_GetID()) {
      __glXGenerateError(dpy, gc, gc->xid,
                         BadAccess, X_GLXMakeContextCurrent);
      return False;
   }

#ifdef GLX_DIRECT_RENDERING
   /* Bind the direct rendering context to the drawable */
   if (gc && gc->driContext) {
      __GLXDRIdrawable *pdraw = FetchDRIDrawable(dpy, draw, gc);
      __GLXDRIdrawable *pread = FetchDRIDrawable(dpy, read, gc);

      if ((pdraw == NULL) || (pread == NULL)) {
         __glXGenerateError(dpy, gc, (pdraw == NULL) ? draw : read,
                            GLXBadDrawable, X_GLXMakeContextCurrent);
         return False;
      }

      bindReturnValue =
         (gc->driContext->bindContext) (gc->driContext, pdraw, pread);
   }
   else if (!gc && oldGC && oldGC->driContext) {
      bindReturnValue = True;
   }
   else
#endif
   {
      /* Send a glXMakeCurrent request to bind the new context. */
      bindReturnValue =
         SendMakeCurrentRequest(dpy, opcode, gc ? gc->xid : None,
                                ((dpy != oldGC->currentDpy)
                                 || oldGC->isDirect)
                                ? None : oldGC->currentContextTag, draw, read,
                                &reply);
   }


   if (!bindReturnValue) {
      return False;
   }

#ifdef GLX_DIRECT_RENDERING
   if ((dpy != oldGC->currentDpy || (gc && gc->driContext)) &&
       !oldGC->isDirect && oldGC != &dummyContext) {
#else
   if ((dpy != oldGC->currentDpy) && oldGC != &dummyContext) {
#endif
      xGLXMakeCurrentReply dummy_reply;

      /* We are either switching from one dpy to another and have to
       * send a request to the previous dpy to unbind the previous
       * context, or we are switching away from a indirect context to
       * a direct context and have to send a request to the dpy to
       * unbind the previous context.
       */
      (void) SendMakeCurrentRequest(oldGC->currentDpy, oldOpcode, None,
                                    oldGC->currentContextTag, None, None,
                                    &dummy_reply);
   }
#ifdef GLX_DIRECT_RENDERING
   else if (oldGC->driContext && oldGC != gc) {
      oldGC->driContext->unbindContext(oldGC->driContext);
   }
#endif

#endif /* GLX_USE_APPLEGL */

   /* Update our notion of what is current */
   __glXLock();
   if (gc == oldGC) {
      /* Even though the contexts are the same the drawable might have
       * changed.  Note that gc cannot be the dummy, and that oldGC
       * cannot be NULL, therefore if they are the same, gc is not
       * NULL and not the dummy.
       */
      if(gc) {
        gc->currentDrawable = draw;
        gc->currentReadable = read;
      }
   }
   else {
      if (oldGC != &dummyContext) {
         /* Old current context is no longer current to anybody */
         oldGC->currentDpy = 0;
         oldGC->currentDrawable = None;
         oldGC->currentReadable = None;
         oldGC->currentContextTag = 0;
         oldGC->thread_id = 0;
#ifdef GLX_USE_APPLEGL
         
         /*
          * At this point we should check if the context has been
          * through glXDestroyContext, and redestroy it if so.
          */
         if(oldGC->do_destroy) {
            __glXUnlock();
            /* glXDestroyContext uses the same global lock. */
            glXDestroyContext(dpy, oldGC);
            __glXLock();
#else
         if (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.
             */
#ifdef GLX_DIRECT_RENDERING
            /* Destroy the old direct rendering context */
            if (oldGC->driContext) {
               oldGC->driContext->destroyContext(oldGC->driContext,
                                                 oldGC->psc,
                                                 oldGC->createDpy);
               oldGC->driContext = NULL;
            }
#endif
            __glXFreeContext(oldGC);
#endif /* GLX_USE_APPLEGL */
         }
      }
      if (gc) {
         __glXSetCurrentContext(gc);

         gc->currentDpy = dpy;
         gc->currentDrawable = draw;
         gc->currentReadable = read;
#ifndef GLX_USE_APPLEGL
         gc->thread_id = _glthread_GetID();

#ifdef GLX_DIRECT_RENDERING
         if (!gc->driContext) {
#endif
            if (!IndirectAPI)
               IndirectAPI = __glXNewIndirectAPI();
            _glapi_set_dispatch(IndirectAPI);

#ifdef GLX_USE_APPLEGL
            do {
               extern void XAppleDRIUseIndirectDispatch(void);
               XAppleDRIUseIndirectDispatch();
            } while (0);
#endif

            state = (__GLXattribute *) (gc->client_state_private);

            gc->currentContextTag = reply.contextTag;
            if (state->array_state == NULL) {
               (void) glGetString(GL_EXTENSIONS);
               (void) glGetString(GL_VERSION);
               __glXInitVertexArrayState(gc);
            }
#ifdef GLX_DIRECT_RENDERING
         }
         else {
            gc->currentContextTag = -1;
         }
#endif
#endif /* GLX_USE_APPLEGL */
      }
      else {
         __glXSetCurrentContextNull();
      }
   }
   __glXUnlock();
   return GL_TRUE;
}


PUBLIC Bool
glXMakeCurrent(Display * dpy, GLXDrawable draw, GLXContext gc)
{
   return MakeContextCurrent(dpy, draw, draw, gc);
}

PUBLIC
GLX_ALIAS(Bool, glXMakeCurrentReadSGI,
          (Display * dpy, GLXDrawable d, GLXDrawable r, GLXContext ctx),
          (dpy, d, r, ctx), MakeContextCurrent)

PUBLIC
GLX_ALIAS(Bool, glXMakeContextCurrent,
          (Display * dpy, GLXDrawable d, GLXDrawable r,
           GLXContext ctx), (dpy, d, r, ctx), MakeContextCurrent)
Example #4
0
/**
 * 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();

   /* XXX: If this is left out, then libGL ends up not having this
    * symbol, and drivers using it fail to load.  Compare the
    * implementation of this symbol to _glapi_noop_enable_warnings(),
    * though, which gets into the library despite no callers, the same
    * prototypes, and the same compile flags to the files containing
    * them.  Moving the definition to glapi_nop.c gets it into the
    * library, though.
    */
   (void)_glthread_GetID();

   /* 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
    * context.
    */
   if ((gc != NULL) && (gc->xid == None)) {
      return GL_FALSE;
   }

   if (gc == NULL && (draw != None || read != None)) {
      __glXGenerateError(dpy, (draw != None) ? draw : read,
                         BadMatch, X_GLXMakeContextCurrent);
      return False;
   }
   if (gc != NULL && (draw == None || read == None)) {
      __glXGenerateError(dpy, None, BadMatch, X_GLXMakeContextCurrent);
      return False;
   }

   _glapi_check_multithread();

   __glXLock();
   if (oldGC == gc &&
       gc->currentDrawable == draw && gc->currentReadable == read) {
      __glXUnlock();
      return True;
   }

   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();
         __glXUnlock();
         __glXGenerateError(dpy, None, GLXBadContext, X_GLXMakeContextCurrent);
         return GL_FALSE;
      }

      if (gc->thread_refcount == 0) {
         gc->currentDpy = dpy;
         gc->currentDrawable = draw;
         gc->currentReadable = read;
      }
      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);
   }

   __glXUnlock();

   return GL_TRUE;
}