diff options
Diffstat (limited to 'src/glx/x11/glxcmds.c')
-rw-r--r-- | src/glx/x11/glxcmds.c | 707 |
1 files changed, 378 insertions, 329 deletions
diff --git a/src/glx/x11/glxcmds.c b/src/glx/x11/glxcmds.c index 4345678a98..80281896f6 100644 --- a/src/glx/x11/glxcmds.c +++ b/src/glx/x11/glxcmds.c @@ -38,110 +38,63 @@ * Client-side GLX interface. */ +#include <inttypes.h> #include "glxclient.h" +#include <X11/extensions/extutil.h> +#include <X11/extensions/Xext.h> +#include <assert.h> +#include <string.h> #include "glapi.h" -#include "glxextensions.h" -#include "glcontextmodes.h" -#include "glheader.h" - #ifdef GLX_DIRECT_RENDERING -#include <sys/time.h> +#include "indirect_init.h" #include <X11/extensions/xf86vmode.h> #include "xf86dri.h" #endif +#include "glxextensions.h" +#include "glcontextmodes.h" +#include "glheader.h" +#include <sys/time.h> static const char __glXGLXClientVendorName[] = "SGI"; static const char __glXGLXClientVersion[] = "1.4"; /****************************************************************************/ - -#ifdef GLX_DIRECT_RENDERING - -static Bool windowExistsFlag; -static int windowExistsErrorHandler(Display *dpy, XErrorEvent *xerr) -{ - if (xerr->error_code == BadWindow) { - windowExistsFlag = GL_FALSE; - } - return 0; -} - -/** - * Find drawables in the local hash that have been destroyed on the - * server. - * - * \param dpy Display to destroy drawables for - * \param screen Screen number to destroy drawables for - */ -static void GarbageCollectDRIDrawables(Display *dpy, __GLXscreenConfigs *sc) -{ - XID draw; - __GLXDRIdrawable *pdraw; - XWindowAttributes xwa; - int (*oldXErrorHandler)(Display *, XErrorEvent *); - - /* Set no-op error handler so Xlib doesn't bail out if the windows - * has alreay been destroyed on the server. */ - XSync(dpy, GL_FALSE); - oldXErrorHandler = XSetErrorHandler(windowExistsErrorHandler); - - if (__glxHashFirst(sc->drawHash, &draw, (void *)&pdraw) == 1) { - do { - windowExistsFlag = GL_TRUE; - XGetWindowAttributes(dpy, draw, &xwa); /* dummy request */ - if (!windowExistsFlag) { - /* Destroy the local drawable data, if the drawable no - longer exists in the Xserver */ - (*pdraw->destroyDrawable)(pdraw); - __glxHashDelete(sc->drawHash, draw); - } - } while (__glxHashNext(sc->drawHash, &draw, (void *)&pdraw) == 1); - } - - XSync(dpy, GL_FALSE); - XSetErrorHandler(oldXErrorHandler); -} - -extern __GLXDRIdrawable * -GetGLXDRIDrawable(Display *dpy, GLXDrawable drawable, int * const scrn_num); - /** * Get the __DRIdrawable for the drawable associated with a GLXContext * * \param dpy The display associated with \c drawable. * \param drawable GLXDrawable whose __DRIdrawable part is to be retrieved. - * \param scrn_num If non-NULL, the drawables screen is stored there * \returns A pointer to the context's __DRIdrawable on success, or NULL if * the drawable is not associated with a direct-rendering context. */ -_X_HIDDEN __GLXDRIdrawable * -GetGLXDRIDrawable(Display *dpy, GLXDrawable drawable, int * const scrn_num) + +#ifdef GLX_DIRECT_RENDERING +static __DRIdrawable * +GetDRIDrawable( Display *dpy, GLXDrawable drawable, int * const scrn_num ) { - __GLXdisplayPrivate *priv = __glXInitialize(dpy); - __GLXDRIdrawable *pdraw; - const unsigned screen_count = ScreenCount(dpy); - unsigned i; - __GLXscreenConfigs *psc; + __GLXdisplayPrivate * const priv = __glXInitialize(dpy); - if (priv == NULL) - return NULL; - - for (i = 0; i < screen_count; i++) { - psc = &priv->screenConfigs[i]; - if (psc->drawHash == NULL) - continue; - - if (__glxHashLookup(psc->drawHash, drawable, (void *) &pdraw) == 0) { - if (scrn_num != NULL) - *scrn_num = i; - return pdraw; + if ( (priv != NULL) && (priv->driDisplay.private != NULL) ) { + const unsigned screen_count = ScreenCount(dpy); + unsigned i; + + for ( i = 0 ; i < screen_count ; i++ ) { + __DRIscreen * const psc = &priv->screenConfigs[i].driScreen; + __DRIdrawable * const pdraw = (psc->private != NULL) + ? (*psc->getDrawable)(dpy, drawable, psc->private) : NULL; + + if ( pdraw != NULL ) { + if ( scrn_num != NULL ) { + *scrn_num = i; + } + return pdraw; + } } } return NULL; } - #endif @@ -311,9 +264,9 @@ GLXContext AllocateGLXContext( Display *dpy ) */ gc->fastImageUnpack = GL_FALSE; gc->fillImage = __glFillImage; + gc->isDirect = GL_FALSE; gc->pc = gc->buf; gc->bufEnd = gc->buf + bufSize; - gc->isDirect = GL_FALSE; if (__glXDebug) { /* ** Set limit register so that there will be one command per packet @@ -359,10 +312,6 @@ CreateContext(Display *dpy, XVisualInfo *vis, Bool use_glx_1_3, int renderType) { GLXContext gc; -#ifdef GLX_DIRECT_RENDERING - int screen = (fbconfig == NULL) ? vis->screen : fbconfig->screen; - __GLXscreenConfigs * const psc = GetGLXScreenConfigs(dpy, screen); -#endif if ( dpy == NULL ) return NULL; @@ -376,36 +325,41 @@ CreateContext(Display *dpy, XVisualInfo *vis, return NULL; #ifdef GLX_DIRECT_RENDERING - if (allowDirect && psc->driScreen) { + if (allowDirect) { + int screen = (fbconfig == NULL) ? vis->screen : fbconfig->screen; + __GLXscreenConfigs * const psc = GetGLXScreenConfigs(dpy, screen); const __GLcontextModes * mode; - if (fbconfig == NULL) { - mode = _gl_context_modes_find_visual(psc->visuals, vis->visualid); - if (mode == NULL) { - xError error; - - error.errorCode = BadValue; - error.resourceID = vis->visualid; - error.sequenceNumber = dpy->request; - error.type = X_Error; - error.majorCode = gc->majorOpcode; - error.minorCode = X_GLXCreateContext; - _XError(dpy, &error); - return None; - } + /* The value of fbconfig cannot change because it is tested + * later in the function. + */ + if ( fbconfig == NULL ) { + /* FIXME: Is it possible for the __GLcontextModes structure + * FIXME: to not be found? + */ + mode = _gl_context_modes_find_visual( psc->configs, + vis->visualid ); + assert( mode != NULL ); + assert( mode->screen == screen ); } else { mode = fbconfig; } - gc->driContext = psc->driScreen->createContext(psc, mode, gc, - shareList, - renderType); - if (gc->driContext != NULL) { - gc->screen = mode->screen; - gc->psc = psc; - gc->mode = mode; - gc->isDirect = GL_TRUE; + if (psc && psc->driScreen.private) { + void * const shared = (shareList != NULL) + ? shareList->driContext.private : NULL; + gc->driContext.private = + (*psc->driScreen.createNewContext)( dpy, mode, renderType, + shared, + &gc->driContext ); + if (gc->driContext.private) { + gc->isDirect = GL_TRUE; + gc->screen = mode->screen; + gc->vid = mode->visualID; + gc->fbconfigID = mode->fbconfigID; + gc->driContext.mode = mode; + } } } #endif @@ -422,7 +376,7 @@ CreateContext(Display *dpy, XVisualInfo *vis, req->visual = vis->visualid; req->screen = vis->screen; req->shareList = shareList ? shareList->xid : None; - req->isDirect = gc->driContext != NULL; + req->isDirect = gc->isDirect; } else if ( use_glx_1_3 ) { xGLXCreateNewContextReq *req; @@ -436,7 +390,7 @@ CreateContext(Display *dpy, XVisualInfo *vis, req->screen = fbconfig->screen; req->renderType = renderType; req->shareList = shareList ? shareList->xid : None; - req->isDirect = gc->driContext != NULL; + req->isDirect = gc->isDirect; } else { xGLXVendorPrivateWithReplyReq *vpreq; @@ -454,7 +408,7 @@ CreateContext(Display *dpy, XVisualInfo *vis, req->screen = fbconfig->screen; req->renderType = renderType; req->shareList = shareList ? shareList->xid : None; - req->isDirect = gc->driContext != NULL; + req->isDirect = gc->isDirect; } UnlockDisplay(dpy); @@ -476,7 +430,7 @@ PUBLIC GLXContext glXCreateContext(Display *dpy, XVisualInfo *vis, False, 0); } -_X_HIDDEN void __glXFreeContext(__GLXcontext *gc) +void __glXFreeContext(__GLXcontext *gc) { if (gc->vendor) XFree((char *) gc->vendor); if (gc->renderer) XFree((char *) gc->renderer); @@ -512,10 +466,12 @@ DestroyContext(Display *dpy, GLXContext gc) #ifdef GLX_DIRECT_RENDERING /* Destroy the direct rendering context */ - if (gc->driContext) { - (*gc->driContext->destroyContext)(gc->driContext, gc->psc, dpy); - gc->driContext = NULL; - GarbageCollectDRIDrawables(dpy, gc->psc); + if (gc->isDirect) { + if (gc->driContext.private) { + (*gc->driContext.destroyContext)(dpy, gc->screen, + gc->driContext.private); + gc->driContext.private = NULL; + } } #endif @@ -596,7 +552,7 @@ PUBLIC void glXWaitGL(void) __glXFlushRenderBuffer(gc, gc->pc); #ifdef GLX_DIRECT_RENDERING - if (gc->driContext) { + if (gc->isDirect) { /* This bit of ugliness unwraps the glFinish function */ #ifdef glFinish #undef glFinish @@ -632,7 +588,7 @@ PUBLIC void glXWaitX(void) __glXFlushRenderBuffer(gc, gc->pc); #ifdef GLX_DIRECT_RENDERING - if (gc->driContext) { + if (gc->isDirect) { XSync(dpy, False); return; } @@ -662,7 +618,7 @@ PUBLIC void glXUseXFont(Font font, int first, int count, int listBase) (void) __glXFlushRenderBuffer(gc, gc->pc); #ifdef GLX_DIRECT_RENDERING - if (gc->driContext) { + if (gc->isDirect) { DRI_glXUseXFont(font, first, count, listBase); return; } @@ -702,7 +658,7 @@ PUBLIC void glXCopyContext(Display *dpy, GLXContext source, } #ifdef GLX_DIRECT_RENDERING - if (gc->driContext) { + if (gc->isDirect) { /* NOT_DONE: This does not work yet */ } #endif @@ -774,7 +730,7 @@ PUBLIC Bool glXIsDirect(Display *dpy, GLXContext gc) if (!gc) { return GL_FALSE; #ifdef GLX_DIRECT_RENDERING - } else if (gc->driContext) { + } else if (gc->isDirect) { return GL_TRUE; #endif } @@ -837,10 +793,10 @@ PUBLIC void glXSwapBuffers(Display *dpy, GLXDrawable drawable) GLXContextTag tag; CARD8 opcode; #ifdef GLX_DIRECT_RENDERING - __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, NULL); + __DRIdrawable *pdraw = GetDRIDrawable( dpy, drawable, NULL ); - if (pdraw != NULL) { - (*pdraw->psc->core->swapBuffers)(pdraw->driDrawable); + if ( pdraw != NULL ) { + (*pdraw->swapBuffers)(dpy, pdraw->private); return; } #endif @@ -884,12 +840,12 @@ PUBLIC int glXGetConfig(Display *dpy, XVisualInfo *vis, int attribute, { __GLXdisplayPrivate *priv; __GLXscreenConfigs *psc; - __GLcontextModes *modes; int status; status = GetGLXPrivScreenConfig( dpy, vis->screen, & priv, & psc ); if ( status == Success ) { - modes = _gl_context_modes_find_visual(psc->visuals, vis->visualid); + const __GLcontextModes * const modes = _gl_context_modes_find_visual( + psc->configs, vis->visualid ); /* Lookup attribute after first finding a match on the visual */ if ( modes != NULL ) { @@ -1267,7 +1223,7 @@ PUBLIC XVisualInfo *glXChooseVisual(Display *dpy, int screen, int *attribList) ** Compute a score for those that do ** Remember which visual, if any, got the highest score */ - for ( modes = psc->visuals ; modes != NULL ; modes = modes->next ) { + for ( modes = psc->configs ; modes != NULL ; modes = modes->next ) { if ( fbconfigs_compatible( & test_config, modes ) && ((best_config == NULL) || (fbconfig_compare( (const __GLcontextModes * const * const)&modes, &best_config ) < 0)) ) { @@ -1312,7 +1268,7 @@ PUBLIC const char *glXQueryExtensionsString( Display *dpy, int screen ) __glXCalculateUsableExtensions(psc, #ifdef GLX_DIRECT_RENDERING - (psc->driScreen != NULL), + (psc->driScreen.private != NULL), #else GL_FALSE, #endif @@ -1491,15 +1447,13 @@ static int __glXQueryContextInfo(Display *dpy, GLXContext ctx) ctx->share_xid = *pProp++; break; case GLX_VISUAL_ID_EXT: - ctx->mode = - _gl_context_modes_find_visual(ctx->psc->visuals, *pProp++); + ctx->vid = *pProp++; break; case GLX_SCREEN: ctx->screen = *pProp++; break; case GLX_FBCONFIG_ID: - ctx->mode = - _gl_context_modes_find_fbconfig(ctx->psc->configs, *pProp++); + ctx->fbconfigID = *pProp++; break; case GLX_RENDER_TYPE: ctx->renderType = *pProp++; @@ -1524,7 +1478,7 @@ glXQueryContext(Display *dpy, GLXContext ctx, int attribute, int *value) int retVal; /* get the information from the server if we don't have it already */ - if (!ctx->driContext && (ctx->mode == NULL)) { + if (!ctx->isDirect && (ctx->vid == None)) { retVal = __glXQueryContextInfo(dpy, ctx); if (Success != retVal) return retVal; } @@ -1533,13 +1487,13 @@ glXQueryContext(Display *dpy, GLXContext ctx, int attribute, int *value) *value = (int)(ctx->share_xid); break; case GLX_VISUAL_ID_EXT: - *value = ctx->mode ? ctx->mode->visualID : None; + *value = (int)(ctx->vid); break; case GLX_SCREEN: *value = (int)(ctx->screen); break; case GLX_FBCONFIG_ID: - *value = ctx->mode ? ctx->mode->fbconfigID : None; + *value = (int)(ctx->fbconfigID); break; case GLX_RENDER_TYPE: *value = (int)(ctx->renderType); @@ -1637,7 +1591,6 @@ PUBLIC GLXFBConfig *glXGetFBConfigs(Display *dpy, int screen, int *nelements) __GLcontextModes ** config = NULL; int i; - *nelements = 0; if ( (priv->screenConfigs != NULL) && (screen >= 0) && (screen <= ScreenCount(dpy)) && (priv->screenConfigs[screen].configs != NULL) @@ -1662,10 +1615,8 @@ PUBLIC GLXFBConfig *glXGetFBConfigs(Display *dpy, int screen, int *nelements) for ( modes = priv->screenConfigs[screen].configs ; modes != NULL ; modes = modes->next ) { - if ( modes->fbconfigID != GLX_DONT_CARE ) { - config[i] = modes; - i++; - } + config[i] = modes; + i++; } } } @@ -1717,15 +1668,16 @@ static int __glXSwapIntervalSGI(int interval) return GLX_BAD_VALUE; } -#ifdef __DRI_SWAP_CONTROL - if (gc->driContext) { +#ifdef GLX_DIRECT_RENDERING + if ( gc->isDirect ) { __GLXscreenConfigs * const psc = GetGLXScreenConfigs( gc->currentDpy, gc->screen ); - __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(gc->currentDpy, - gc->currentDrawable, - NULL); - if (psc->swapControl != NULL && pdraw != NULL) { - psc->swapControl->setSwapInterval(pdraw->driDrawable, interval); + __DRIdrawable * const pdraw = GetDRIDrawable( gc->currentDpy, + gc->currentDrawable, + NULL ); + if ( __glXExtensionBitIsEnabled( psc, SGI_swap_control_bit ) + && (pdraw != NULL) ) { + pdraw->swap_interval = interval; return 0; } else { @@ -1763,22 +1715,25 @@ static int __glXSwapIntervalSGI(int interval) */ static int __glXSwapIntervalMESA(unsigned int interval) { -#ifdef __DRI_SWAP_CONTROL +#ifdef GLX_DIRECT_RENDERING GLXContext gc = __glXGetCurrentContext(); if ( interval < 0 ) { return GLX_BAD_VALUE; } - if (gc != NULL && gc->driContext) { + if ( (gc != NULL) && gc->isDirect ) { __GLXscreenConfigs * const psc = GetGLXScreenConfigs( gc->currentDpy, gc->screen ); - if ( (psc != NULL) && (psc->driScreen != NULL) ) { - __GLXDRIdrawable *pdraw = - GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable, NULL); - if (psc->swapControl != NULL && pdraw != NULL) { - psc->swapControl->setSwapInterval(pdraw->driDrawable, interval); + if ( (psc != NULL) && (psc->driScreen.private != NULL) + && __glXExtensionBitIsEnabled( psc, MESA_swap_control_bit ) ) { + __DRIdrawable * const pdraw = + (*psc->driScreen.getDrawable)(gc->currentDpy, + gc->currentDrawable, + psc->driScreen.private); + if ( pdraw != NULL ) { + pdraw->swap_interval = interval; return 0; } } @@ -1793,18 +1748,21 @@ static int __glXSwapIntervalMESA(unsigned int interval) static int __glXGetSwapIntervalMESA(void) { -#ifdef __DRI_SWAP_CONTROL +#ifdef GLX_DIRECT_RENDERING GLXContext gc = __glXGetCurrentContext(); - if (gc != NULL && gc->driContext) { + if ( (gc != NULL) && gc->isDirect ) { __GLXscreenConfigs * const psc = GetGLXScreenConfigs( gc->currentDpy, gc->screen ); - if ( (psc != NULL) && (psc->driScreen != NULL) ) { - __GLXDRIdrawable *pdraw = - GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable, NULL); - if (psc->swapControl != NULL && pdraw != NULL) { - return psc->swapControl->getSwapInterval(pdraw->driDrawable); + if ( (psc != NULL) && (psc->driScreen.private != NULL) + && __glXExtensionBitIsEnabled( psc, MESA_swap_control_bit ) ) { + __DRIdrawable * const pdraw = + (*psc->driScreen.getDrawable)(gc->currentDpy, + gc->currentDrawable, + psc->driScreen.private); + if ( pdraw != NULL ) { + return pdraw->swap_interval; } } } @@ -1821,13 +1779,15 @@ static int __glXGetSwapIntervalMESA(void) static GLint __glXBeginFrameTrackingMESA(Display *dpy, GLXDrawable drawable) { int status = GLX_BAD_CONTEXT; -#ifdef __DRI_FRAME_TRACKING +#ifdef GLX_DIRECT_RENDERING int screen; - __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, &screen); + __DRIdrawable * const pdraw = GetDRIDrawable(dpy, drawable, & screen); __GLXscreenConfigs * const psc = GetGLXScreenConfigs(dpy, screen); - if (pdraw != NULL && psc->frameTracking != NULL) - status = psc->frameTracking->frameTracking(pdraw->driDrawable, GL_TRUE); + if ( (pdraw != NULL) && (pdraw->frameTracking != NULL) + && __glXExtensionBitIsEnabled( psc, MESA_swap_frame_usage_bit ) ) { + status = pdraw->frameTracking( dpy, pdraw->private, GL_TRUE ); + } #else (void) dpy; (void) drawable; @@ -1839,14 +1799,15 @@ static GLint __glXBeginFrameTrackingMESA(Display *dpy, GLXDrawable drawable) static GLint __glXEndFrameTrackingMESA(Display *dpy, GLXDrawable drawable) { int status = GLX_BAD_CONTEXT; -#ifdef __DRI_FRAME_TRACKING +#ifdef GLX_DIRECT_RENDERING int screen; - __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, & screen); - __GLXscreenConfigs *psc = GetGLXScreenConfigs(dpy, screen); + __DRIdrawable * const pdraw = GetDRIDrawable(dpy, drawable, & screen); + __GLXscreenConfigs * const psc = GetGLXScreenConfigs(dpy, screen); - if (pdraw != NULL && psc->frameTracking != NULL) - status = psc->frameTracking->frameTracking(pdraw->driDrawable, - GL_FALSE); + if ( (pdraw != NULL) && (pdraw->frameTracking != NULL) + && __glXExtensionBitIsEnabled( psc, MESA_swap_frame_usage_bit ) ) { + status = pdraw->frameTracking( dpy, pdraw->private, GL_FALSE ); + } #else (void) dpy; (void) drawable; @@ -1859,20 +1820,19 @@ static GLint __glXGetFrameUsageMESA(Display *dpy, GLXDrawable drawable, GLfloat *usage) { int status = GLX_BAD_CONTEXT; -#ifdef __DRI_FRAME_TRACKING +#ifdef GLX_DIRECT_RENDERING int screen; - __GLXDRIdrawable * const pdraw = GetGLXDRIDrawable(dpy, drawable, & screen); + __DRIdrawable * const pdraw = GetDRIDrawable(dpy, drawable, & screen); __GLXscreenConfigs * const psc = GetGLXScreenConfigs(dpy, screen); - if (pdraw != NULL && psc->frameTracking != NULL) { - int64_t sbc, missedFrames; - float lastMissedUsage; + if ( (pdraw != NULL ) && (pdraw->queryFrameTracking != NULL) + && __glXExtensionBitIsEnabled( psc, MESA_swap_frame_usage_bit ) ) { + int64_t sbc, missedFrames; + float lastMissedUsage; - status = psc->frameTracking->queryFrameTracking(pdraw->driDrawable, - &sbc, - &missedFrames, - &lastMissedUsage, - usage); + status = pdraw->queryFrameTracking( dpy, pdraw->private, &sbc, + &missedFrames, &lastMissedUsage, + usage ); } #else (void) dpy; @@ -1888,17 +1848,18 @@ static GLint __glXQueryFrameTrackingMESA(Display *dpy, GLXDrawable drawable, GLfloat *lastMissedUsage) { int status = GLX_BAD_CONTEXT; -#ifdef __DRI_FRAME_TRACKING +#ifdef GLX_DIRECT_RENDERING int screen; - __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, & screen); + __DRIdrawable * const pdraw = GetDRIDrawable(dpy, drawable, & screen); __GLXscreenConfigs * const psc = GetGLXScreenConfigs(dpy, screen); - if (pdraw != NULL && psc->frameTracking != NULL) { + if ( (pdraw != NULL ) && (pdraw->queryFrameTracking != NULL) + && __glXExtensionBitIsEnabled( psc, MESA_swap_frame_usage_bit ) ) { float usage; - status = psc->frameTracking->queryFrameTracking(pdraw->driDrawable, - sbc, missedFrames, - lastMissedUsage, &usage); + status = pdraw->queryFrameTracking( dpy, pdraw->private, sbc, + missedFrames, lastMissedUsage, + & usage ); } #else (void) dpy; @@ -1920,24 +1881,21 @@ static int __glXGetVideoSyncSGI(unsigned int *count) * FIXME: there should be a GLX encoding for this call. I can find no * FIXME: documentation for the GLX encoding. */ -#ifdef __DRI_MEDIA_STREAM_COUNTER +#ifdef GLX_DIRECT_RENDERING GLXContext gc = __glXGetCurrentContext(); - if (gc != NULL && gc->driContext) { + if ( (gc != NULL) && gc->isDirect ) { __GLXscreenConfigs * const psc = GetGLXScreenConfigs( gc->currentDpy, gc->screen ); - if ( psc->msc && psc->driScreen ) { - __GLXDRIdrawable *pdraw = - GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable, NULL); - int64_t temp; - int ret; - - ret = (*psc->msc->getDrawableMSC)(psc->__driScreen, - pdraw->driDrawable, &temp); - *count = (unsigned) temp; + if ( __glXExtensionBitIsEnabled( psc, SGI_video_sync_bit ) + && psc->driScreen.private && psc->driScreen.getMSC) { + int ret; + int64_t temp; - return (ret == 0) ? 0 : GLX_BAD_CONTEXT; + ret = psc->driScreen.getMSC( psc->driScreen.private, & temp ); + *count = (unsigned) temp; + return (ret == 0) ? 0 : GLX_BAD_CONTEXT; } } #else @@ -1948,26 +1906,32 @@ static int __glXGetVideoSyncSGI(unsigned int *count) static int __glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count) { -#ifdef __DRI_MEDIA_STREAM_COUNTER +#ifdef GLX_DIRECT_RENDERING GLXContext gc = __glXGetCurrentContext(); if ( divisor <= 0 || remainder < 0 ) return GLX_BAD_VALUE; - if (gc != NULL && gc->driContext) { + if ( (gc != NULL) && gc->isDirect ) { __GLXscreenConfigs * const psc = GetGLXScreenConfigs( gc->currentDpy, gc->screen ); - if (psc->msc != NULL && psc->driScreen ) { - __GLXDRIdrawable *pdraw = - GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable, NULL); - int ret; - int64_t msc; - int64_t sbc; - - ret = (*psc->msc->waitForMSC)(pdraw->driDrawable, 0, - divisor, remainder, &msc, &sbc); - *count = (unsigned) msc; - return (ret == 0) ? 0 : GLX_BAD_CONTEXT; + if ( __glXExtensionBitIsEnabled( psc, SGI_video_sync_bit ) + && psc->driScreen.private ) { + __DRIdrawable * const pdraw = + (*psc->driScreen.getDrawable)(gc->currentDpy, + gc->currentDrawable, + psc->driScreen.private); + if ( (pdraw != NULL) && (pdraw->waitForMSC != NULL) ) { + int ret; + int64_t msc; + int64_t sbc; + + ret = (*pdraw->waitForMSC)( gc->currentDpy, pdraw->private, + 0, divisor, remainder, + & msc, & sbc ); + *count = (unsigned) msc; + return (ret == 0) ? 0 : GLX_BAD_CONTEXT; + } } } #else @@ -2119,19 +2083,20 @@ static Bool __glXQueryMaxSwapBarriersSGIX(Display *dpy, int screen, int *max) static Bool __glXGetSyncValuesOML(Display *dpy, GLXDrawable drawable, int64_t *ust, int64_t *msc, int64_t *sbc) { -#if defined(__DRI_SWAP_BUFFER_COUNTER) && defined(__DRI_MEDIA_STREAM_COUNTER) +#ifdef GLX_DIRECT_RENDERING __GLXdisplayPrivate * const priv = __glXInitialize(dpy); if ( priv != NULL ) { int i; - __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, &i); + __DRIdrawable * const pdraw = GetDRIDrawable( dpy, drawable, & i ); __GLXscreenConfigs * const psc = &priv->screenConfigs[i]; assert( (pdraw == NULL) || (i != -1) ); - return ( (pdraw && psc->sbc && psc->msc) - && ((*psc->msc->getMSC)(psc->driScreen, msc) == 0) - && ((*psc->sbc->getSBC)(pdraw->driDrawable, sbc) == 0) - && (__glXGetUST(ust) == 0) ); + return ( (pdraw && pdraw->getSBC && psc->driScreen.getMSC) + && __glXExtensionBitIsEnabled( psc, OML_sync_control_bit ) + && ((*psc->driScreen.getMSC)( psc->driScreen.private, msc ) == 0) + && ((*pdraw->getSBC)( dpy, psc->driScreen.private, sbc ) == 0) + && (__glXGetUST( ust ) == 0) ); } #else (void) dpy; @@ -2143,68 +2108,6 @@ static Bool __glXGetSyncValuesOML(Display *dpy, GLXDrawable drawable, return False; } -#ifdef GLX_DIRECT_RENDERING -_X_HIDDEN GLboolean -__driGetMscRateOML(__DRIdrawable *draw, - int32_t *numerator, int32_t *denominator, void *private) -{ -#ifdef XF86VIDMODE - __GLXscreenConfigs *psc; - XF86VidModeModeLine mode_line; - int dot_clock; - int i; - __GLXDRIdrawable *glxDraw = private; - - psc = glxDraw->psc; - if (XF86VidModeQueryVersion(psc->dpy, &i, &i) && - XF86VidModeGetModeLine(psc->dpy, psc->scr, &dot_clock, &mode_line) ) { - unsigned n = dot_clock * 1000; - unsigned d = mode_line.vtotal * mode_line.htotal; - -# define V_INTERLACE 0x010 -# define V_DBLSCAN 0x020 - - if (mode_line.flags & V_INTERLACE) - n *= 2; - else if (mode_line.flags & V_DBLSCAN) - d *= 2; - - /* The OML_sync_control spec requires that if the refresh rate is a - * whole number, that the returned numerator be equal to the refresh - * rate and the denominator be 1. - */ - - if (n % d == 0) { - n /= d; - d = 1; - } - else { - static const unsigned f[] = { 13, 11, 7, 5, 3, 2, 0 }; - - /* This is a poor man's way to reduce a fraction. It's far from - * perfect, but it will work well enough for this situation. - */ - - for (i = 0; f[i] != 0; i++) { - while (n % f[i] == 0 && d % f[i] == 0) { - d /= f[i]; - n /= f[i]; - } - } - } - - *numerator = n; - *denominator = d; - - return True; - } - else - return False; -#else - return False; -#endif -} -#endif /** * Determine the refresh rate of the specified drawable and display. @@ -2222,17 +2125,70 @@ __driGetMscRateOML(__DRIdrawable *draw, * when GLX_OML_sync_control appears in the client extension string. */ -_X_HIDDEN GLboolean __glXGetMscRateOML(Display * dpy, GLXDrawable drawable, - int32_t * numerator, - int32_t * denominator) +Bool __glXGetMscRateOML(Display * dpy, GLXDrawable drawable, + int32_t * numerator, int32_t * denominator) { #if defined( GLX_DIRECT_RENDERING ) && defined( XF86VIDMODE ) - __GLXDRIdrawable *draw = GetGLXDRIDrawable(dpy, drawable, NULL); + __GLXdisplayPrivate * const priv = __glXInitialize(dpy); - if (draw == NULL) - return False; - return __driGetMscRateOML(draw->driDrawable, numerator, denominator, draw); + if ( priv != NULL ) { + XF86VidModeModeLine mode_line; + int dot_clock; + int screen_num; + int i; + + + GetDRIDrawable( dpy, drawable, & screen_num ); + if ( (screen_num != -1) + && XF86VidModeQueryVersion( dpy, & i, & i ) + && XF86VidModeGetModeLine( dpy, screen_num, & dot_clock, + & mode_line ) ) { + unsigned n = dot_clock * 1000; + unsigned d = mode_line.vtotal * mode_line.htotal; + +# define V_INTERLACE 0x010 +# define V_DBLSCAN 0x020 + + if ( (mode_line.flags & V_INTERLACE) ) { + n *= 2; + } + else if ( (mode_line.flags & V_DBLSCAN) ) { + d *= 2; + } + + /* The OML_sync_control spec requires that if the refresh rate is a + * whole number, that the returned numerator be equal to the refresh + * rate and the denominator be 1. + */ + + if ( (n % d) == 0 ) { + n /= d; + d = 1; + } + else { + static const unsigned f[] = { 13, 11, 7, 5, 3, 2, 0 }; + + + /* This is a poor man's way to reduce a fraction. It's far from + * perfect, but it will work well enough for this situation. + */ + + for ( i = 0 ; f[i] != 0 ; i++ ) { + while ( ((n % f[i]) == 0) && ((d % f[i]) == 0) ) { + d /= f[i]; + n /= f[i]; + } + } + } + + *numerator = n; + *denominator = d; + + (void) drawable; + return True; + } + } #else (void) dpy; (void) drawable; @@ -2247,9 +2203,9 @@ static int64_t __glXSwapBuffersMscOML(Display *dpy, GLXDrawable drawable, int64_t target_msc, int64_t divisor, int64_t remainder) { -#ifdef __DRI_SWAP_BUFFER_COUNTER +#ifdef GLX_DIRECT_RENDERING int screen; - __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, &screen); + __DRIdrawable *pdraw = GetDRIDrawable( dpy, drawable, & screen ); __GLXscreenConfigs * const psc = GetGLXScreenConfigs( dpy, screen ); /* The OML_sync_control spec says these should "generate a GLX_BAD_VALUE @@ -2262,10 +2218,11 @@ static int64_t __glXSwapBuffersMscOML(Display *dpy, GLXDrawable drawable, if ( divisor > 0 && remainder >= divisor ) return -1; - if (pdraw != NULL && psc->counters != NULL) - return (*psc->sbc->swapBuffersMSC)(pdraw->driDrawable, target_msc, - divisor, remainder); - + if ( (pdraw != NULL) && (pdraw->swapBuffersMSC != NULL) + && __glXExtensionBitIsEnabled( psc, OML_sync_control_bit ) ) { + return (*pdraw->swapBuffersMSC)(dpy, pdraw->private, target_msc, + divisor, remainder); + } #else (void) dpy; (void) drawable; @@ -2282,9 +2239,9 @@ static Bool __glXWaitForMscOML(Display * dpy, GLXDrawable drawable, int64_t remainder, int64_t *ust, int64_t *msc, int64_t *sbc) { -#ifdef __DRI_MEDIA_STREAM_COUNTER +#ifdef GLX_DIRECT_RENDERING int screen; - __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, &screen); + __DRIdrawable *pdraw = GetDRIDrawable( dpy, drawable, & screen ); __GLXscreenConfigs * const psc = GetGLXScreenConfigs( dpy, screen ); int ret; @@ -2296,9 +2253,10 @@ static Bool __glXWaitForMscOML(Display * dpy, GLXDrawable drawable, if ( divisor > 0 && remainder >= divisor ) return False; - if (pdraw != NULL && psc->msc != NULL) { - ret = (*psc->msc->waitForMSC)(pdraw->driDrawable, target_msc, - divisor, remainder, msc, sbc); + if ( (pdraw != NULL) && (pdraw->waitForMSC != NULL) + && __glXExtensionBitIsEnabled( psc, OML_sync_control_bit ) ) { + ret = (*pdraw->waitForMSC)( dpy, pdraw->private, target_msc, + divisor, remainder, msc, sbc ); /* __glXGetUST returns zero on success and non-zero on failure. * This function returns True on success and False on failure. @@ -2323,9 +2281,9 @@ static Bool __glXWaitForSbcOML(Display * dpy, GLXDrawable drawable, int64_t target_sbc, int64_t *ust, int64_t *msc, int64_t *sbc ) { -#ifdef __DRI_SWAP_BUFFER_COUNTER +#ifdef GLX_DIRECT_RENDERING int screen; - __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, &screen); + __DRIdrawable *pdraw = GetDRIDrawable( dpy, drawable, & screen ); __GLXscreenConfigs * const psc = GetGLXScreenConfigs( dpy, screen ); int ret; @@ -2335,8 +2293,9 @@ static Bool __glXWaitForSbcOML(Display * dpy, GLXDrawable drawable, if ( target_sbc < 0 ) return False; - if (pdraw != NULL && psc->sbc != NULL) { - ret = (*psc->sbc->waitForSBC)(pdraw->driDrawable, target_sbc, msc, sbc); + if ( (pdraw != NULL) && (pdraw->waitForSBC != NULL) + && __glXExtensionBitIsEnabled( psc, OML_sync_control_bit )) { + ret = (*pdraw->waitForSBC)( dpy, pdraw->private, target_sbc, msc, sbc ); /* __glXGetUST returns zero on success and non-zero on failure. * This function returns True on success and False on failure. @@ -2364,13 +2323,16 @@ PUBLIC void *glXAllocateMemoryMESA(Display *dpy, int scrn, size_t size, float readFreq, float writeFreq, float priority) { -#ifdef __DRI_ALLOCATE +#ifdef GLX_DIRECT_RENDERING __GLXscreenConfigs * const psc = GetGLXScreenConfigs( dpy, scrn ); - if (psc && psc->allocate) - return (*psc->allocate->allocateMemory)(psc->__driScreen, size, - readFreq, writeFreq, priority); - + if ( __glXExtensionBitIsEnabled( psc, MESA_allocate_memory_bit ) ) { + if (psc && psc->driScreen.private && psc->driScreen.allocateMemory) { + return (*psc->driScreen.allocateMemory)( dpy, scrn, size, + readFreq, writeFreq, + priority ); + } + } #else (void) dpy; (void) scrn; @@ -2386,12 +2348,14 @@ PUBLIC void *glXAllocateMemoryMESA(Display *dpy, int scrn, PUBLIC void glXFreeMemoryMESA(Display *dpy, int scrn, void *pointer) { -#ifdef __DRI_ALLOCATE +#ifdef GLX_DIRECT_RENDERING __GLXscreenConfigs * const psc = GetGLXScreenConfigs( dpy, scrn ); - if (psc && psc->allocate) - (*psc->allocate->freeMemory)(psc->__driScreen, pointer); - + if ( __glXExtensionBitIsEnabled( psc, MESA_allocate_memory_bit ) ) { + if (psc && psc->driScreen.private && psc->driScreen.freeMemory) { + (*psc->driScreen.freeMemory)( dpy, scrn, pointer ); + } + } #else (void) dpy; (void) scrn; @@ -2403,12 +2367,14 @@ PUBLIC void glXFreeMemoryMESA(Display *dpy, int scrn, void *pointer) PUBLIC GLuint glXGetMemoryOffsetMESA( Display *dpy, int scrn, const void *pointer ) { -#ifdef __DRI_ALLOCATE +#ifdef GLX_DIRECT_RENDERING __GLXscreenConfigs * const psc = GetGLXScreenConfigs( dpy, scrn ); - if (psc && psc->allocate) - return (*psc->allocate->memoryOffset)(psc->__driScreen, pointer); - + if ( __glXExtensionBitIsEnabled( psc, MESA_allocate_memory_bit ) ) { + if (psc && psc->driScreen.private && psc->driScreen.memoryOffset) { + return (*psc->driScreen.memoryOffset)( dpy, scrn, pointer ); + } + } #else (void) dpy; (void) scrn; @@ -2481,14 +2447,13 @@ static void __glXCopySubBufferMESA(Display *dpy, GLXDrawable drawable, INT32 *x_ptr, *y_ptr, *w_ptr, *h_ptr; CARD8 opcode; -#ifdef __DRI_COPY_SUB_BUFFER +#ifdef GLX_DIRECT_RENDERING int screen; - __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, &screen); + __DRIdrawable *pdraw = GetDRIDrawable( dpy, drawable, & screen ); if ( pdraw != NULL ) { __GLXscreenConfigs * const psc = GetGLXScreenConfigs( dpy, screen ); - if (psc->copySubBuffer != NULL) { - (*psc->copySubBuffer->copySubBuffer)(pdraw->driDrawable, - x, y, width, height); + if ( __glXExtensionBitIsEnabled( psc, MESA_copy_sub_buffer_bit ) ) { + (*pdraw->copySubBuffer)(dpy, pdraw->private, x, y, width, height); } return; @@ -2564,16 +2529,8 @@ static void __glXBindTexImageEXT(Display *dpy, } #ifdef GLX_DIRECT_RENDERING - if (gc->driContext) { - __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, NULL); - - if (pdraw != NULL) - (*pdraw->psc->texBuffer->setTexBuffer)(gc->__driContext, - pdraw->textureTarget, - pdraw->driDrawable); - + if (gc->isDirect) return; - } #endif opcode = __glXSetupForCommand(dpy); @@ -2624,7 +2581,7 @@ static void __glXReleaseTexImageEXT(Display *dpy, return; #ifdef GLX_DIRECT_RENDERING - if (gc->driContext) + if (gc->isDirect) return; #endif @@ -2656,7 +2613,7 @@ static void __glXReleaseTexImageEXT(Display *dpy, * * \sa strdup */ -_X_HIDDEN char * +char * __glXstrdup(const char *str) { char *copy; @@ -2884,6 +2841,98 @@ PUBLIC void (*glXGetProcAddress(const GLubyte *procName))( void ) #ifdef GLX_DIRECT_RENDERING /** + * Retrieves the verion of the internal libGL API in YYYYMMDD format. This + * might be used by the DRI drivers to determine how new libGL is at runtime. + * Drivers should not call this function directly. They should instead use + * \c glXGetProcAddress to obtain a pointer to the function. + * + * \returns An 8-digit decimal number representing the internal libGL API in + * YYYYMMDD format. + * + * \sa glXGetProcAddress, PFNGLXGETINTERNALVERSIONPROC + * + * \since Internal API version 20021121. + */ +int __glXGetInternalVersion(void) +{ + /* History: + * 20021121 - Initial version + * 20021128 - Added __glXWindowExists() function + * 20021207 - Added support for dynamic GLX extensions, + * GLX_SGI_swap_control, GLX_SGI_video_sync, + * GLX_OML_sync_control, and GLX_MESA_swap_control. + * Never officially released. Do NOT test against + * this version. Use 20030317 instead. + * 20030317 - Added support GLX_SGIX_fbconfig, + * GLX_MESA_swap_frame_usage, GLX_OML_swap_method, + * GLX_{ARB,SGIS}_multisample, and + * GLX_SGIX_visual_select_group. + * 20030606 - Added support for GLX_SGI_make_current_read. + * 20030813 - Made support for dynamic extensions multi-head aware. + * 20030818 - Added support for GLX_MESA_allocate_memory in place of the + * deprecated GLX_NV_vertex_array_range & GLX_MESA_agp_offset + * interfaces. + * 20031201 - Added support for the first round of DRI interface changes. + * Do NOT test against this version! It has binary + * compatibility bugs, use 20040317 instead. + * 20040317 - Added the 'mode' field to __DRIcontextRec. + * 20040415 - Added support for bindContext3 and unbindContext3. + * 20040602 - Add __glXGetDrawableInfo. I though that was there + * months ago. :( + * 20050727 - Gut all the old interfaces. This breaks compatability with + * any DRI driver built to any previous version. + * 20060314 - Added support for GLX_MESA_copy_sub_buffer. + * 20070105 - Added support for damage reporting. + */ + return 20070105; +} + + + +static Bool windowExistsFlag; + +static int windowExistsErrorHandler(Display *dpy, XErrorEvent *xerr) +{ + if (xerr->error_code == BadWindow) { + windowExistsFlag = GL_FALSE; + } + return 0; +} + +/** + * Determine if a window associated with a \c GLXDrawable exists on the + * X-server. This function is not used internally by libGL. It is provided + * as a utility function for DRI drivers. + * Drivers should not call this function directly. They should instead use + * \c glXGetProcAddress to obtain a pointer to the function. + * + * \param dpy Display associated with the drawable to be queried. + * \param draw \c GLXDrawable to test. + * + * \returns \c GL_TRUE if a window exists that is associated with \c draw, + * otherwise \c GL_FALSE is returned. + * + * \warning This function is not currently thread-safe. + * + * \sa glXGetProcAddress + * + * \since Internal API version 20021128. + */ +Bool __glXWindowExists(Display *dpy, GLXDrawable draw) +{ + XWindowAttributes xwa; + int (*oldXErrorHandler)(Display *, XErrorEvent *); + + XSync(dpy, GL_FALSE); + windowExistsFlag = GL_TRUE; + oldXErrorHandler = XSetErrorHandler(windowExistsErrorHandler); + XGetWindowAttributes(dpy, draw, &xwa); /* dummy request */ + XSetErrorHandler(oldXErrorHandler); + return windowExistsFlag; +} + + +/** * Get the unadjusted system time (UST). Currently, the UST is measured in * microseconds since Epoc. The actual resolution of the UST may vary from * system to system, and the units may vary from release to release. @@ -2897,7 +2946,7 @@ PUBLIC void (*glXGetProcAddress(const GLubyte *procName))( void ) * * \since Internal API version 20030317. */ -_X_HIDDEN int __glXGetUST( int64_t * ust ) +int __glXGetUST( int64_t * ust ) { struct timeval tv; |