summaryrefslogtreecommitdiff
path: root/src/glx/x11/glxcmds.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/glx/x11/glxcmds.c')
-rw-r--r--src/glx/x11/glxcmds.c707
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;