-/* $XFree86: xc/lib/GL/glx/glxext.c,v 1.22 2003/12/08 17:35:28 dawes Exp $ */
/*
** License Applicability. Except to the extent portions of this file are
#include "glxclient.h"
#include <stdio.h>
-#include <Xext.h>
-#include <extutil.h>
+#include <X11/extensions/Xext.h>
+#include <X11/extensions/extutil.h>
+#include <X11/extensions/Xfixes.h>
+#include <X11/extensions/Xdamage.h>
#include <assert.h>
#include "indirect_init.h"
#include "glapi.h"
-#ifdef XTHREADS
-#include "Xthreads.h"
-#endif
#include "glxextensions.h"
#include "glcontextmodes.h"
#include "glheader.h"
#include "dri_glx.h"
#endif
+#ifdef USE_XCB
+#include <X11/Xlib-xcb.h>
+#include <xcb/xcb.h>
+#include <xcb/glx.h>
+#endif
+
#include <assert.h>
#ifdef DEBUG
#define INIT_MESA_SPARC
#endif
+#ifdef GLX_DIRECT_RENDERING
+static __DRIscreen *__glXFindDRIScreen(__DRInativeDisplay *dpy, int scrn);
+#endif /* GLX_DIRECT_RENDERING */
+
static Bool MakeContextCurrent(Display *dpy, GLXDrawable draw,
GLXDrawable read, GLXContext gc);
* Current context management and locking
*/
-#if defined(GLX_DIRECT_RENDERING) && defined(XTHREADS)
+#if defined( USE_XTHREADS )
/* thread safe */
static GLboolean TSDinitialized = GL_FALSE;
/* Used by the __glXLock() and __glXUnlock() macros */
xmutex_rec __glXmutex;
+#elif defined( PTHREADS )
+
+pthread_mutex_t __glXmutex = PTHREAD_MUTEX_INITIALIZER;
+
+# if defined( GLX_USE_TLS )
+
+/**
+ * Per-thread GLX context pointer.
+ *
+ * \c __glXSetCurrentContext is written is such a way that this pointer can
+ * \b never be \c NULL. This is important! Because of this
+ * \c __glXGetCurrentContext can be implemented as trivial macro.
+ */
+__thread void * __glX_tls_Context __attribute__((tls_model("initial-exec")))
+ = &dummyContext;
+
+void __glXSetCurrentContext( __GLXcontext * c )
+{
+ __glX_tls_Context = (c != NULL) ? c : &dummyContext;
+}
+
+# else
+
+static pthread_once_t once_control = PTHREAD_ONCE_INIT;
+
+/**
+ * Per-thread data key.
+ *
+ * Once \c init_thread_data has been called, the per-thread data key will
+ * take a value of \c NULL. As each new thread is created the default
+ * value, in that thread, will be \c NULL.
+ */
+static pthread_key_t ContextTSD;
+
+/**
+ * Initialize the per-thread data key.
+ *
+ * This function is called \b exactly once per-process (not per-thread!) to
+ * initialize the per-thread data key. This is ideally done using the
+ * \c pthread_once mechanism.
+ */
+static void init_thread_data( void )
+{
+ if ( pthread_key_create( & ContextTSD, NULL ) != 0 ) {
+ perror( "pthread_key_create" );
+ exit( -1 );
+ }
+}
+
+void __glXSetCurrentContext( __GLXcontext * c )
+{
+ pthread_once( & once_control, init_thread_data );
+ pthread_setspecific( ContextTSD, c );
+}
+
+__GLXcontext * __glXGetCurrentContext( void )
+{
+ void * v;
+
+ pthread_once( & once_control, init_thread_data );
+
+ v = pthread_getspecific( ContextTSD );
+ return (v == NULL) ? & dummyContext : (__GLXcontext *) v;
+}
+
+# endif /* defined( GLX_USE_TLS ) */
+
+#elif defined( THREADS )
+
+#error Unknown threading method specified.
+
#else
/* not thread safe */
*/
int __glXCloseDisplay(Display *dpy, XExtCodes *codes);
-static GLboolean FillInVisuals( __GLXscreenConfigs * psc );
/************************************************************************/
"GLXBadRenderRequest",
"GLXBadLargeRequest",
"GLXUnsupportedPrivateRequest",
+ "GLXBadFBConfig",
+ "GLXBadPbuffer",
+ "GLXBadCurrentDrawable",
+ "GLXBadWindow",
};
int __glXCloseDisplay(Display *dpy, XExtCodes *codes)
if(psc->effectiveGLXexts)
Xfree(psc->effectiveGLXexts);
- if ( psc->old_configs != NULL ) {
- Xfree( psc->old_configs );
- psc->old_configs = NULL;
- psc->numOldConfigs = 0;
- }
-
psc->configs = NULL; /* NOTE: just for paranoia */
}
+ Xfree((char*) psc->serverGLXexts);
#ifdef GLX_DIRECT_RENDERING
/* Free the direct rendering per screen data */
priv->serverGLXversion = 0x0; /* to protect against double free's */
}
-#if 0 /* GLX_DIRECT_RENDERING */
+#ifdef GLX_DIRECT_RENDERING
/* Free the direct rendering per display data */
if (priv->driDisplay.private)
(*priv->driDisplay.destroyDisplay)(priv->dpy,
priv->driDisplay.private);
priv->driDisplay.private = NULL;
-#endif
-
-#ifdef GLX_DIRECT_RENDERING
- XFree(priv->driDisplay.createScreen);
+ if (priv->driDisplay.createNewScreen) {
+ Xfree(priv->driDisplay.createNewScreen); /* free array of ptrs */
+ priv->driDisplay.createNewScreen = NULL;
+ }
#endif
Xfree((char*) priv);
}
-/**
- * Determine if a \c __GLcontextModes structure has the right mojo to be
- * converted to a \c __GLXvisualConfig to be sent to an "old" style DRI
- * driver.
- */
-#define MODE_HAS_MOJO(m) \
- ((m)->visualID != GLX_DONT_CARE) \
- && ((m)->sampleBuffers == 0) \
- && ((m)->samples == 0) \
- && (((m)->drawableType & GLX_WINDOW_BIT) != 0) \
- && (((m)->xRenderable == GL_TRUE) \
- || ((m)->xRenderable == GLX_DONT_CARE))
-
-
-/**
- * Convert the FBConfigs associated with a screen into an array of
- * \c __GLXvisualConfig structures. These structures are passed into DRI
- * drivers that use the "old" interface. The old-style drivers had a fairly
- * strict set of visual types that could be supported. FBConfigs that
- * cannot be supported are not converted.
- *
- * \param psc Screen whose FBConfigs need to be swizzled.
- *
- * \returns
- * If memory could be allocated and at least one FBConfig could be converted
- * to a \c __GLXvisualConfig structure, \c GL_TRUE is returned. Otherwise,
- * \c GL_FALSE is returned.
- *
- * \todo
- * When the old DRI driver interface is no longer supported, this function
- * can be removed.
- */
-static GLboolean
-FillInVisuals( __GLXscreenConfigs * psc )
-{
- __GLcontextModes *modes;
- int glx_visual_count;
-
-
- glx_visual_count = 0;
- for ( modes = psc->configs ; modes != NULL ; modes = modes->next ) {
- if ( MODE_HAS_MOJO( modes ) ) {
- glx_visual_count++;
- }
- }
-
- psc->old_configs = (__GLXvisualConfig *)
- Xmalloc( sizeof( __GLXvisualConfig ) * glx_visual_count );
- if ( psc->old_configs == NULL ) {
- return GL_FALSE;
- }
-
- glx_visual_count = 0;
- for ( modes = psc->configs ; modes != NULL ; modes = modes->next ) {
- if ( MODE_HAS_MOJO( modes ) ) {
-
-#define COPY_VALUE(src_tag,dst_tag) \
- psc->old_configs[glx_visual_count]. dst_tag = modes-> src_tag
-
- COPY_VALUE( visualID, vid );
- COPY_VALUE( rgbMode, rgba );
- COPY_VALUE( stereoMode, stereo );
- COPY_VALUE( doubleBufferMode, doubleBuffer );
-
- psc->old_configs[glx_visual_count].class =
- _gl_convert_to_x_visual_type( modes->visualType );
-
- COPY_VALUE( level, level );
- COPY_VALUE( numAuxBuffers, auxBuffers );
-
- COPY_VALUE( redBits, redSize );
- COPY_VALUE( greenBits, greenSize );
- COPY_VALUE( blueBits, blueSize );
- COPY_VALUE( alphaBits, alphaSize );
- COPY_VALUE( rgbBits, bufferSize );
- COPY_VALUE( accumRedBits, accumRedSize );
- COPY_VALUE( accumGreenBits, accumGreenSize );
- COPY_VALUE( accumBlueBits, accumBlueSize );
- COPY_VALUE( accumAlphaBits, accumAlphaSize );
- COPY_VALUE( depthBits, depthSize );
- COPY_VALUE( stencilBits, stencilSize );
-
- COPY_VALUE( visualRating, visualRating );
- COPY_VALUE( transparentPixel, transparentPixel );
- COPY_VALUE( transparentRed, transparentRed );
- COPY_VALUE( transparentGreen, transparentGreen );
- COPY_VALUE( transparentBlue, transparentBlue );
- COPY_VALUE( transparentAlpha, transparentAlpha );
- COPY_VALUE( transparentIndex, transparentIndex );
-
-#undef COPY_VALUE
-
- glx_visual_count++;
- }
- }
-
- psc->numOldConfigs = glx_visual_count;
- if ( glx_visual_count == 0 ) {
- Xfree( psc->old_configs );
- psc->old_configs = NULL;
- }
-
- return (glx_visual_count != 0);
-}
-
-
void
__glXInitializeVisualConfigFromTags( __GLcontextModes *config, int count,
const INT32 *bp, Bool tagged_only,
case GLX_SAMPLES_SGIS:
config->samples = *bp++;
break;
+ case GLX_BIND_TO_TEXTURE_RGB_EXT:
+ config->bindToTextureRgb = *bp++;
+ break;
+ case GLX_BIND_TO_TEXTURE_RGBA_EXT:
+ config->bindToTextureRgba = *bp++;
+ break;
+ case GLX_BIND_TO_MIPMAP_TEXTURE_EXT:
+ config->bindToMipmapTexture = *bp++;
+ break;
+ case GLX_BIND_TO_TEXTURE_TARGETS_EXT:
+ config->bindToTextureTargets = *bp++;
+ break;
+ case GLX_Y_INVERTED_EXT:
+ config->yInverted = *bp++;
+ break;
case None:
i = count;
break;
if ( do_delete && (m->visualID != 0) ) {
do_delete = GL_FALSE;
- fprintf(stderr, "libGL warning: 3D driver claims to not support "
- "visual 0x%02x\n", m->visualID);
+ if (getenv("LIBGL_DEBUG")) {
+ fprintf(stderr, "libGL warning: 3D driver claims to not support "
+ "visual 0x%02x\n", m->visualID);
+ }
}
if ( do_delete ) {
}
+/**
+ * Implement \c __DRIinterfaceMethods::getProcAddress.
+ */
+static __DRIfuncPtr get_proc_address( const char * proc_name )
+{
+ if (strcmp( proc_name, "glxEnableExtension" ) == 0) {
+ return (__DRIfuncPtr) __glXScrEnableExtension;
+ }
+
+ return NULL;
+}
+
+#ifdef XDAMAGE_1_1_INTERFACE
+static GLboolean has_damage_post(__DRInativeDisplay *dpy)
+{
+ static GLboolean inited = GL_FALSE;
+ static GLboolean has_damage;
+
+ if (!inited) {
+ int major, minor;
+
+ if (XDamageQueryVersion(dpy, &major, &minor) &&
+ major == 1 && minor >= 1)
+ {
+ has_damage = GL_TRUE;
+ } else {
+ has_damage = GL_FALSE;
+ }
+ inited = GL_TRUE;
+ }
+
+ return has_damage;
+}
+#endif /* XDAMAGE_1_1_INTERFACE */
+
+static void __glXReportDamage(__DRInativeDisplay *dpy, int screen,
+ __DRIid drawable,
+ int x, int y,
+ drm_clip_rect_t *rects, int num_rects,
+ GLboolean front_buffer)
+{
+#ifdef XDAMAGE_1_1_INTERFACE
+ XRectangle *xrects;
+ XserverRegion region;
+ int i;
+ int x_off, y_off;
+
+ if (!has_damage_post(dpy))
+ return;
+
+ if (front_buffer) {
+ x_off = x;
+ y_off = y;
+ drawable = RootWindow(dpy, screen);
+ } else{
+ x_off = 0;
+ y_off = 0;
+ }
+
+ xrects = malloc(sizeof(XRectangle) * num_rects);
+ if (xrects == NULL)
+ return;
+
+ for (i = 0; i < num_rects; i++) {
+ xrects[i].x = rects[i].x1 + x_off;
+ xrects[i].y = rects[i].y1 + y_off;
+ xrects[i].width = rects[i].x2 - rects[i].x1;
+ xrects[i].height = rects[i].y2 - rects[i].y1;
+ }
+ region = XFixesCreateRegion(dpy, xrects, num_rects);
+ free(xrects);
+ XDamageAdd(dpy, drawable, region);
+ XFixesDestroyRegion(dpy, region);
+#endif
+}
+
+/**
+ * Table of functions exported by the loader to the driver.
+ */
+static const __DRIinterfaceMethods interface_methods = {
+ get_proc_address,
+
+ _gl_context_modes_create,
+ _gl_context_modes_destroy,
+
+ __glXFindDRIScreen,
+ __glXWindowExists,
+
+ XF86DRICreateContextWithConfig,
+ XF86DRIDestroyContext,
+
+ XF86DRICreateDrawable,
+ XF86DRIDestroyDrawable,
+ XF86DRIGetDrawableInfo,
+
+ __glXGetUST,
+ __glXGetMscRateOML,
+
+ __glXReportDamage,
+};
+
+
/**
* Perform the required libGL-side initialization and call the client-side
static void *
CallCreateNewScreen(Display *dpy, int scrn, __DRIscreen *psc,
__DRIdisplay * driDpy,
- CreateNewScreenFunc createNewScreen)
+ PFNCREATENEWSCREENFUNC createNewScreen)
{
__DRIscreenPrivate *psp = NULL;
#ifndef GLX_USE_APPLEGL
drm_handle_t hSAREA;
- drmAddress pSAREA;
+ drmAddress pSAREA = MAP_FAILED;
char *BusID;
__DRIversion ddx_version;
__DRIversion dri_version;
err_msg = "XF86DRIOpenConnection";
err_extra = NULL;
+ framebuffer.base = MAP_FAILED;
framebuffer.dev_priv = NULL;
if (XF86DRIOpenConnection(dpy, scrn, &hSAREA, &BusID)) {
- fd = drmOpen(NULL,BusID);
+ int newlyopened;
+ fd = drmOpenOnce(NULL,BusID, &newlyopened);
Xfree(BusID); /* No longer needed */
err_msg = "open DRM";
}
err_msg = "XF86DRIAuthConnection";
- if (XF86DRIAuthConnection(dpy, scrn, magic)) {
+ if (!newlyopened || XF86DRIAuthConnection(dpy, scrn, magic)) {
char *driverName;
/*
- * Get device name (like "tdfx") and the ddx version numbers.
- * We'll check the version in each DRI driver's "createScreen"
- * function.
+ * Get device name (like "tdfx") and the ddx version
+ * numbers. We'll check the version in each DRI driver's
+ * "createNewScreen" function.
*/
err_msg = "XF86DRIGetClientDriverName";
if (XF86DRIGetClientDriverName(dpy, scrn,
if ( status == 0 ) {
/*
- * Map the SAREA region. Further mmap regions may be setup in
- * each DRI driver's "createScreen" function.
+ * Map the SAREA region. Further mmap regions
+ * may be setup in each DRI driver's
+ * "createNewScreen" function.
*/
status = drmMap(fd, hSAREA, SAREA_MAX,
&pSAREA);
pSAREA,
fd,
api_ver,
+ & interface_methods,
& driver_modes );
filter_modes( & configs->configs,
}
if ( fd >= 0 ) {
- (void)drmClose(fd);
+ (void)drmCloseOnce(fd);
}
(void)XF86DRICloseConnection(dpy, scrn);
fb_req->glxCode = X_GLXGetFBConfigs;
fb_req->screen = i;
break;
-
+
case 2:
GetReqExtra(GLXVendorPrivateWithReply,
sz_xGLXGetFBConfigsSGIXReq-sz_xGLXVendorPrivateWithReplyReq,vpreq);
if (!_XReply(dpy, (xReply*) &reply, 0, False)) {
/* Something is busted. Punt. */
UnlockDisplay(dpy);
+ SyncHandle();
FreeScreenConfigs(priv);
return GL_FALSE;
}
- UnlockDisplay(dpy);
if (!reply.numVisuals) {
/* This screen does not support GL rendering */
UnlockDisplay(dpy);
psc->ext_list_first_time = GL_TRUE;
/* Initialize the direct rendering per screen data and functions */
if (priv->driDisplay.private != NULL) {
+ /* FIXME: Should it be some sort of an error if createNewScreen[i]
+ * FIXME: is NULL?
+ */
if (priv->driDisplay.createNewScreen &&
priv->driDisplay.createNewScreen[i]) {
& priv->driDisplay,
priv->driDisplay.createNewScreen[i] );
}
- else if (priv->driDisplay.createScreen &&
- priv->driDisplay.createScreen[i]) {
- /* screen initialization (bootstrap the driver) */
- if ( (psc->old_configs == NULL)
- && !FillInVisuals(psc) ) {
- FreeScreenConfigs(priv);
- return GL_FALSE;
- }
-
- psc->driScreen.screenConfigs = (void *)psc;
- psc->driScreen.private =
- (*(priv->driDisplay.createScreen[i]))(dpy, i, &psc->driScreen,
- psc->numOldConfigs,
- psc->old_configs);
- }
}
#endif
}
XEDataObject dataObj;
int major, minor;
-#if defined(GLX_DIRECT_RENDERING) && defined(XTHREADS)
+#if defined(USE_XTHREADS)
{
static int firstCall = 1;
if (firstCall) {
__glXUnlock();
return 0;
}
- dpyPriv = (__GLXdisplayPrivate *) Xmalloc(sizeof(__GLXdisplayPrivate));
+ dpyPriv = (__GLXdisplayPrivate *) Xcalloc(1, sizeof(__GLXdisplayPrivate));
if (!dpyPriv) {
__glXUnlock();
Xfree((char*) private);
** Note: This _must_ be done before calling any other DRI routines
** (e.g., those called in AllocAndFetchScreenConfigs).
*/
- if (getenv("LIBGL_ALWAYS_INDIRECT")) {
- /* Assinging zero here assures we'll never go direct */
- dpyPriv->driDisplay.private = 0;
- dpyPriv->driDisplay.destroyDisplay = 0;
- dpyPriv->driDisplay.createScreen = 0;
- }
- else {
+ if (getenv("LIBGL_ALWAYS_INDIRECT") == NULL) {
dpyPriv->driDisplay.private =
driCreateDisplay(dpy, &dpyPriv->driDisplay);
}
GLubyte *__glXFlushRenderBuffer(__GLXcontext *ctx, GLubyte *pc)
{
Display * const dpy = ctx->currentDpy;
+#ifdef USE_XCB
+ xcb_connection_t *c = XGetXCBConnection(dpy);
+#else
xGLXRenderReq *req;
+#endif /* USE_XCB */
const GLint size = pc - ctx->buf;
if ( (dpy != NULL) && (size > 0) ) {
+#ifdef USE_XCB
+ xcb_glx_render(c, ctx->currentContextTag, size, (char *)ctx->buf);
+#else
/* Send the entire buffer as an X request */
LockDisplay(dpy);
GetReq(GLXRender,req);
_XSend(dpy, (char *)ctx->buf, size);
UnlockDisplay(dpy);
SyncHandle();
+#endif
}
/* Reset pointer and return it */
const GLvoid * data, GLint dataLen)
{
Display *dpy = gc->currentDpy;
+#ifdef USE_XCB
+ xcb_connection_t *c = XGetXCBConnection(dpy);
+ xcb_glx_render_large(c, gc->currentContextTag, requestNumber, totalRequests, dataLen, data);
+#else
xGLXRenderLargeReq *req;
-
+
if ( requestNumber == 1 ) {
LockDisplay(dpy);
}
UnlockDisplay(dpy);
SyncHandle();
}
+#endif /* USE_XCB */
}
/************************************************************************/
-GLXContext glXGetCurrentContext(void)
+PUBLIC GLXContext glXGetCurrentContext(void)
{
GLXContext cx = __glXGetCurrentContext();
}
}
-GLXDrawable glXGetCurrentDrawable(void)
+PUBLIC GLXDrawable glXGetCurrentDrawable(void)
{
GLXContext gc = __glXGetCurrentContext();
return gc->currentDrawable;
* \warning
* This function assumes that \c dpy is locked with \c LockDisplay on entry.
*/
-static Bool SendMakeCurrentRequest( Display *dpy, CARD8 opcode,
- GLXContextID gc_id, GLXContextTag gc_tag,
- GLXDrawable draw, GLXDrawable read,
- xGLXMakeCurrentReply * reply )
+static Bool SendMakeCurrentRequest(Display *dpy, CARD8 opcode,
+ GLXContextID gc_id, GLXContextTag gc_tag,
+ GLXDrawable draw, GLXDrawable read,
+ xGLXMakeCurrentReply *reply)
{
- if ( draw == read ) {
+ Bool ret;
+
+
+ LockDisplay(dpy);
+
+ if (draw == read) {
xGLXMakeCurrentReq *req;
GetReq(GLXMakeCurrent,req);
* not the SGI extension.
*/
- if ( (priv->majorVersion > 1) || (priv->minorVersion >= 3) ) {
+ if ((priv->majorVersion > 1) || (priv->minorVersion >= 3)) {
xGLXMakeContextCurrentReq *req;
GetReq(GLXMakeContextCurrent,req);
}
}
- return _XReply(dpy, (xReply*) reply, 0, False);
+ ret = _XReply(dpy, (xReply*) reply, 0, False);
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+
+ return ret;
}
+#ifdef GLX_DIRECT_RENDERING
static Bool BindContextWrapper( Display *dpy, GLXContext gc,
GLXDrawable draw, GLXDrawable read )
{
-#ifdef GLX_DIRECT_RENDERING
- if ( gc->driContext.bindContext3 != NULL ) {
- return (*gc->driContext.bindContext3)(dpy, gc->screen, draw, read,
- & gc->driContext);
- }
-#ifndef DRI_NEW_INTERFACE_ONLY
- else {
- return (*gc->driContext.bindContext2)(dpy, gc->screen, draw, read,
- gc);
- }
-#endif
-#endif
- return GL_FALSE;
+ return (*gc->driContext.bindContext)(dpy, gc->screen, draw, read,
+ & gc->driContext);
}
-static Bool UnbindContextWrapper( Display *dpy, GLXContext gc )
+static Bool UnbindContextWrapper( GLXContext gc )
{
-#ifdef GLX_DIRECT_RENDERING
- if ( gc->driContext.unbindContext3 != NULL ) {
- return (*gc->driContext.unbindContext3)(dpy, gc->screen,
- gc->currentDrawable,
- gc->currentReadable,
- & gc->driContext );
- }
-#ifndef DRI_NEW_INTERFACE_ONLY
- else {
- return (*gc->driContext.unbindContext2)(dpy, gc->screen,
- gc->currentDrawable,
- gc->currentReadable, gc);
- }
-#endif
-#endif
- return GL_FALSE;
+ return (*gc->driContext.unbindContext)(gc->currentDpy, gc->screen,
+ gc->currentDrawable,
+ gc->currentReadable,
+ & gc->driContext );
}
+#endif /* GLX_DIRECT_RENDERING */
-/*
-** Make a particular context current.
-** NOTE: this is in this file so that it can access dummyContext.
-*/
+/**
+ * Make a particular context current.
+ *
+ * \note This is in this file so that it can access dummyContext.
+ */
USED static Bool MakeContextCurrent(Display *dpy, GLXDrawable draw,
GLXDrawable read, GLXContext gc)
{
xGLXMakeCurrentReply reply;
- GLXContext oldGC;
- CARD8 opcode, oldOpcode;
- Bool sentRequestToOldDpy = False;
- Bool bindReturnValue = True;
+ const GLXContext oldGC = __glXGetCurrentContext();
+ const CARD8 opcode = __glXSetupForCommand(dpy);
+ const CARD8 oldOpcode = ((gc == oldGC) || (oldGC == &dummyContext))
+ ? opcode : __glXSetupForCommand(oldGC->currentDpy);
+ Bool bindReturnValue;
- opcode = __glXSetupForCommand(dpy);
- if (!opcode) {
+
+ 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.
- */
+ /* 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;
}
- oldGC = __glXGetCurrentContext();
- oldOpcode = (gc == oldGC) ? opcode : __glXSetupForCommand(dpy);
- if (!oldOpcode) {
+#ifndef GLX_DIRECT_RENDERING
+ if (gc && gc->isDirect) {
return GL_FALSE;
}
+#endif
- if ((dpy != oldGC->currentDpy || (gc && gc->isDirect)) &&
- !oldGC->isDirect && oldGC != &dummyContext) {
- /*
- ** 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.
- */
- sentRequestToOldDpy = True;
- LockDisplay(oldGC->currentDpy);
- if ( ! SendMakeCurrentRequest( oldGC->currentDpy, oldOpcode, None,
- oldGC->currentContextTag, None, None,
- &reply ) ) {
- /* The make current failed. Just return GL_FALSE. */
- UnlockDisplay(oldGC->currentDpy);
- SyncHandle();
- return GL_FALSE;
- }
+ _glapi_check_multithread();
- oldGC->currentContextTag = 0;
- }
-
#ifdef GLX_DIRECT_RENDERING
- /* Unbind the old direct rendering context */
- if (oldGC->isDirect) {
- if (oldGC->driContext.private) {
- if (! UnbindContextWrapper( oldGC->currentDpy, oldGC )) {
- /* The make current failed. Just return GL_FALSE. */
- return GL_FALSE;
- }
- }
- oldGC->currentContextTag = 0;
- }
-
/* Bind the direct rendering context to the drawable */
if (gc && gc->isDirect) {
- if (gc->driContext.private) {
- bindReturnValue = BindContextWrapper( dpy, gc, draw, read );
- }
- } else {
+ bindReturnValue = (gc->driContext.private)
+ ? BindContextWrapper(dpy, gc, draw, read)
+ : False;
+ } else
#endif
- _glapi_check_multithread();
+ {
/* Send a glXMakeCurrent request to bind the new context. */
- LockDisplay(dpy);
-
- bindReturnValue = SendMakeCurrentRequest( dpy, opcode,
- gc ? gc->xid : None,
- oldGC->currentContextTag,
- draw, read, &reply );
- UnlockDisplay(dpy);
-#ifdef GLX_DIRECT_RENDERING
+ bindReturnValue =
+ SendMakeCurrentRequest(dpy, opcode, gc ? gc->xid : None,
+ ((dpy != oldGC->currentDpy) || oldGC->isDirect)
+ ? None : oldGC->currentContextTag,
+ draw, read, &reply);
}
-#endif
if (!bindReturnValue) {
- /* The make current failed. */
- if (gc && !gc->isDirect) {
- SyncHandle();
- }
+ return False;
+ }
+ if ((dpy != oldGC->currentDpy || (gc && gc->isDirect)) &&
+ !oldGC->isDirect && oldGC != &dummyContext) {
+ 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
- /* If the old context was direct rendering, then re-bind to it. */
- if (oldGC->isDirect) {
- if (oldGC->driContext.private) {
- if (! BindContextWrapper( oldGC->currentDpy, oldGC,
- oldGC->currentDrawable,
- oldGC->currentReadable )) {
- /*
- ** The request failed; this cannot happen with the
- ** current API. If in the future the API is
- ** extended to allow context sharing between
- ** clients, then this may fail (because another
- ** client may have grabbed the context); in that
- ** case, we cannot undo the previous request, and
- ** cannot adhere to the "no-op" behavior.
- */
- }
- }
- } else
-#endif
- /*
- ** If we had just sent a request to a previous dpy, we have to
- ** undo that request (because if a command fails, it should act
- ** like a no-op) by making current to the previous context and
- ** drawable.
- */
- if (sentRequestToOldDpy) {
- if ( !SendMakeCurrentRequest( oldGC->currentDpy, oldOpcode,
- oldGC->xid, 0,
- oldGC->currentDrawable,
- oldGC->currentReadable, &reply ) ) {
- UnlockDisplay(oldGC->currentDpy);
- SyncHandle();
- /*
- ** The request failed; this cannot happen with the
- ** current API. If in the future the API is extended to
- ** allow context sharing between clients, then this may
- ** fail (because another client may have grabbed the
- ** context); in that case, we cannot undo the previous
- ** request, and cannot adhere to the "no-op" behavior.
- */
- }
- else {
- UnlockDisplay(oldGC->currentDpy);
- }
- oldGC->currentContextTag = reply.contextTag;
- }
- return GL_FALSE;
+ else if (oldGC->isDirect && oldGC->driContext.private) {
+ (void) UnbindContextWrapper(oldGC);
}
+#endif
+
/* 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.
- */
+ /* 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.
+ */
gc->currentDrawable = draw;
gc->currentReadable = read;
} else {
oldGC->currentContextTag = 0;
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.
- */
+ /* 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->isDirect) {
}
if (gc) {
__glXSetCurrentContext(gc);
-#ifdef GLX_DIRECT_RENDERING
+
+ gc->currentDpy = dpy;
+ gc->currentDrawable = draw;
+ gc->currentReadable = read;
+
if (!gc->isDirect) {
if (!IndirectAPI)
IndirectAPI = __glXNewIndirectAPI();
_glapi_set_dispatch(IndirectAPI);
-# ifdef GLX_USE_APPLEGL
+
+#ifdef GLX_USE_APPLEGL
do {
extern void XAppleDRIUseIndirectDispatch(void);
XAppleDRIUseIndirectDispatch();
} while (0);
-# endif
- }
-#else
- /* if not direct rendering, always need indirect dispatch */
- if (!IndirectAPI)
- IndirectAPI = __glXNewIndirectAPI();
- _glapi_set_dispatch(IndirectAPI);
#endif
- gc->currentDpy = dpy;
- gc->currentDrawable = draw;
- gc->currentReadable = read;
- if ( ! gc->isDirect ) {
- __GLXattribute * state = (__GLXattribute *)(gc->client_state_private);
+ __GLXattribute *state =
+ (__GLXattribute *)(gc->client_state_private);
gc->currentContextTag = reply.contextTag;
- if ( state->array_state == NULL ) {
- (void) glGetString( GL_EXTENSIONS );
- (void) glGetString( GL_VERSION );
+ if (state->array_state == NULL) {
+ (void) glGetString(GL_EXTENSIONS);
+ (void) glGetString(GL_VERSION);
__glXInitVertexArrayState(gc);
}
}
}
-PUBLIC Bool GLX_PREFIX(glXMakeCurrent)(Display *dpy, GLXDrawable draw,
- GLXContext gc)
+PUBLIC Bool glXMakeCurrent(Display *dpy, GLXDrawable draw, GLXContext gc)
{
return MakeContextCurrent( dpy, draw, draw, gc );
}