diff options
Diffstat (limited to 'src/glx/glxext.c')
-rw-r--r-- | src/glx/glxext.c | 294 |
1 files changed, 119 insertions, 175 deletions
diff --git a/src/glx/glxext.c b/src/glx/glxext.c index 69a7b29eb27..4a9c9d499e7 100644 --- a/src/glx/glxext.c +++ b/src/glx/glxext.c @@ -68,13 +68,8 @@ _X_HIDDEN int __glXDebug = 0; /* Extension required boiler plate */ -static char *__glXExtensionName = GLX_EXTENSION_NAME; -#ifdef GLX_USE_APPLEGL -static XExtensionInfo __glXExtensionInfo_data; -XExtensionInfo *__glXExtensionInfo = &__glXExtensionInfo_data; -#else -XExtensionInfo *__glXExtensionInfo = NULL; -#endif +static const char __glXExtensionName[] = GLX_EXTENSION_NAME; +static __GLXdisplayPrivate *glx_displays; static /* const */ char *error_list[] = { "GLXBadContext", @@ -92,21 +87,6 @@ static /* const */ char *error_list[] = { "GLXBadWindow", }; -static int -__glXCloseDisplay(Display * dpy, XExtCodes * codes) -{ - GLXContext gc; - - gc = __glXGetCurrentContext(); - if (dpy == gc->currentDpy) { - __glXSetCurrentContextNull(); - __glXFreeContext(gc); - } - - return XextRemoveDisplay(__glXExtensionInfo, dpy); -} - - #ifdef GLX_USE_APPLEGL static char *__glXErrorString(Display *dpy, int code, XExtCodes *codes, char *buf, int n); @@ -115,28 +95,6 @@ static char *__glXErrorString(Display *dpy, int code, XExtCodes *codes, static XEXT_GENERATE_ERROR_STRING(__glXErrorString, __glXExtensionName, __GLX_NUMBER_ERRORS, error_list) -static Bool -__glXWireToEvent(Display *dpy, XEvent *event, xEvent *wire); -static Status -__glXEventToWire(Display *dpy, XEvent *event, xEvent *wire); - -static /* const */ XExtensionHooks __glXExtensionHooks = { - NULL, /* create_gc */ - NULL, /* copy_gc */ - NULL, /* flush_gc */ - NULL, /* free_gc */ - NULL, /* create_font */ - NULL, /* free_font */ - __glXCloseDisplay, /* close_display */ - __glXWireToEvent, /* wire_to_event */ - __glXEventToWire, /* event_to_wire */ - NULL, /* error */ - __glXErrorString, /* error_string */ -}; - -XEXT_GENERATE_FIND_DISPLAY(__glXFindDisplay, __glXExtensionInfo, - __glXExtensionName, &__glXExtensionHooks, - __GLX_NUMBER_EVENTS, NULL) /* * GLX events are a bit funky. We don't stuff the X event code into @@ -150,11 +108,12 @@ XEXT_GENERATE_FIND_DISPLAY(__glXFindDisplay, __glXExtensionInfo, static Bool __glXWireToEvent(Display *dpy, XEvent *event, xEvent *wire) { - XExtDisplayInfo *info = __glXFindDisplay(dpy); + __GLXdisplayPrivate *glx_dpy = __glXInitialize(dpy); - XextCheckExtension(dpy, info, __glXExtensionName, False); + if (glx_dpy == NULL) + return False; - switch ((wire->u.u.type & 0x7f) - info->codes->first_event) { + switch ((wire->u.u.type & 0x7f) - glx_dpy->codes->first_event) { case GLX_PbufferClobber: { GLXPbufferClobberEvent *aevent = (GLXPbufferClobberEvent *)event; @@ -209,9 +168,10 @@ __glXWireToEvent(Display *dpy, XEvent *event, xEvent *wire) static Status __glXEventToWire(Display *dpy, XEvent *event, xEvent *wire) { - XExtDisplayInfo *info = __glXFindDisplay(dpy); + __GLXdisplayPrivate *glx_dpy = __glXInitialize(dpy); - XextCheckExtension(dpy, info, __glXExtensionName, False); + if (glx_dpy == NULL) + return False; switch (event->type) { case GLX_DAMAGED: @@ -244,9 +204,9 @@ FreeScreenConfigs(__GLXdisplayPrivate * priv) GLint i, screens; /* Free screen configuration information */ - psc = priv->screenConfigs; screens = ScreenCount(priv->dpy); - for (i = 0; i < screens; i++, psc++) { + for (i = 0; i < screens; i++) { + psc = priv->screenConfigs[i]; if (psc->configs) { _gl_context_modes_destroy(psc->configs); if (psc->effectiveGLXexts) @@ -260,19 +220,13 @@ FreeScreenConfigs(__GLXdisplayPrivate * priv) Xfree((char *) psc->serverGLXexts); #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) - if (psc->driver_configs) { - unsigned int j; - for (j = 0; psc->driver_configs[j]; j++) - free((__DRIconfig *) psc->driver_configs[j]); - free(psc->driver_configs); - psc->driver_configs = NULL; - } if (psc->driScreen) { psc->driScreen->destroyScreen(psc); - __glxHashDestroy(psc->drawHash); - XFree(psc->driScreen); - psc->driScreen = NULL; + } else { + Xfree(psc); } +#else + Xfree(psc); #endif } XFree((char *) priv->screenConfigs); @@ -284,20 +238,34 @@ FreeScreenConfigs(__GLXdisplayPrivate * priv) ** structure. The caller will free the extension structure. */ static int -__glXFreeDisplayPrivate(XExtData * extension) +__glXCloseDisplay(Display * dpy, XExtCodes * codes) { - __GLXdisplayPrivate *priv; + __GLXdisplayPrivate *priv, **prev; + GLXContext gc; + + _XLockMutex(_Xglobal_lock); + prev = &glx_displays; + for (priv = glx_displays; priv; prev = &priv->next, priv = priv->next) { + if (priv->dpy == dpy) { + (*prev)->next = priv->next; + break; + } + } + _XUnlockMutex(_Xglobal_lock); + + gc = __glXGetCurrentContext(); + if (dpy == gc->currentDpy) { + gc->vtable->destroy(gc); + __glXSetCurrentContextNull(); + } - priv = (__GLXdisplayPrivate *) extension->private_data; FreeScreenConfigs(priv); - if (priv->serverGLXvendor) { + if (priv->serverGLXvendor) Xfree((char *) priv->serverGLXvendor); - priv->serverGLXvendor = 0x0; /* to protect against double free's */ - } - if (priv->serverGLXversion) { + if (priv->serverGLXversion) Xfree((char *) priv->serverGLXversion); - priv->serverGLXversion = 0x0; /* to protect against double free's */ - } + + __glxHashDestroy(priv->drawHash); #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) /* Free the direct rendering per display data */ @@ -315,10 +283,9 @@ __glXFreeDisplayPrivate(XExtData * extension) #endif Xfree((char *) priv); - return 0; -} -/************************************************************************/ + return 1; +} /* ** Query the version of the GLX extension. This procedure works even if @@ -672,15 +639,15 @@ createConfigsFromProperties(Display * dpy, int nvisuals, int nprops, } static GLboolean -getVisualConfigs(Display * dpy, __GLXdisplayPrivate * priv, int screen) +getVisualConfigs(__GLXscreenConfigs *psc, + __GLXdisplayPrivate *priv, int screen) { xGLXGetVisualConfigsReq *req; - __GLXscreenConfigs *psc; xGLXGetVisualConfigsReply reply; + Display *dpy = priv->dpy; LockDisplay(dpy); - psc = priv->screenConfigs + screen; psc->visuals = NULL; GetReq(GLXGetVisualConfigs, req); req->reqType = priv->majorOpcode; @@ -701,15 +668,14 @@ getVisualConfigs(Display * dpy, __GLXdisplayPrivate * priv, int screen) } static GLboolean -getFBConfigs(Display * dpy, __GLXdisplayPrivate * priv, int screen) +getFBConfigs(__GLXscreenConfigs *psc, __GLXdisplayPrivate *priv, int screen) { xGLXGetFBConfigsReq *fb_req; xGLXGetFBConfigsSGIXReq *sgi_req; xGLXVendorPrivateWithReplyReq *vpreq; xGLXGetFBConfigsReply reply; - __GLXscreenConfigs *psc; + Display *dpy = priv->dpy; - psc = priv->screenConfigs + screen; psc->serverGLXexts = __glXQueryServerString(dpy, priv->majorOpcode, screen, GLX_EXTENSIONS); @@ -748,6 +714,22 @@ getFBConfigs(Display * dpy, __GLXdisplayPrivate * priv, int screen) return psc->configs != NULL; } +_X_HIDDEN Bool +glx_screen_init(__GLXscreenConfigs *psc, + int screen, __GLXdisplayPrivate * priv) +{ + /* Initialize per screen dynamic client GLX extensions */ + psc->ext_list_first_time = GL_TRUE; + psc->scr = screen; + psc->dpy = priv->dpy; + psc->display = priv; + + getVisualConfigs(psc, priv, screen); + getFBConfigs(psc, priv, screen); + + return GL_TRUE; +} + /* ** Allocate the memory for the per screen configs for each screen. ** If that works then fetch the per screen configs data. @@ -762,12 +744,9 @@ AllocAndFetchScreenConfigs(Display * dpy, __GLXdisplayPrivate * priv) ** First allocate memory for the array of per screen configs. */ screens = ScreenCount(dpy); - psc = (__GLXscreenConfigs *) Xmalloc(screens * sizeof(__GLXscreenConfigs)); - if (!psc) { + priv->screenConfigs = Xmalloc(screens * sizeof *priv->screenConfigs); + if (!priv->screenConfigs) return GL_FALSE; - } - memset(psc, 0, screens * sizeof(__GLXscreenConfigs)); - priv->screenConfigs = psc; priv->serverGLXversion = __glXQueryServerString(dpy, priv->majorOpcode, 0, GLX_VERSION); @@ -777,33 +756,18 @@ AllocAndFetchScreenConfigs(Display * dpy, __GLXdisplayPrivate * priv) } for (i = 0; i < screens; i++, psc++) { - getVisualConfigs(dpy, priv, i); - getFBConfigs(dpy, priv, i); - + psc = NULL; #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) - psc->scr = i; - psc->dpy = dpy; - psc->drawHash = __glxHashCreate(); - if (psc->drawHash == NULL) - continue; - - /* Initialize per screen dynamic client GLX extensions */ - psc->ext_list_first_time = GL_TRUE; - if (priv->dri2Display) - psc->driScreen = (*priv->dri2Display->createScreen) (psc, i, priv); - - if (psc->driScreen == NULL && priv->driDisplay) - psc->driScreen = (*priv->driDisplay->createScreen) (psc, i, priv); - - if (psc->driScreen == NULL && priv->driswDisplay) - psc->driScreen = (*priv->driswDisplay->createScreen) (psc, i, priv); - - if (psc->driScreen == NULL) { - __glxHashDestroy(psc->drawHash); - psc->drawHash = NULL; - } + psc = (*priv->dri2Display->createScreen) (i, priv); + if (psc == NULL && priv->driDisplay) + psc = (*priv->driDisplay->createScreen) (i, priv); + if (psc == NULL && priv->driswDisplay) + psc = (*priv->driswDisplay->createScreen) (i, priv); #endif + if (psc == NULL) + psc = indirect_create_screen(i, priv); + priv->screenConfigs[i] = psc; } SyncHandle(); return GL_TRUE; @@ -815,72 +779,59 @@ AllocAndFetchScreenConfigs(Display * dpy, __GLXdisplayPrivate * priv) _X_HIDDEN __GLXdisplayPrivate * __glXInitialize(Display * dpy) { - XExtDisplayInfo *info = __glXFindDisplay(dpy); - XExtData **privList, *private, *found; __GLXdisplayPrivate *dpyPriv; - XEDataObject dataObj; - int major, minor; #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) Bool glx_direct, glx_accel; #endif + int i; - /* The one and only long long lock */ - __glXLock(); + _XLockMutex(_Xglobal_lock); - if (!XextHasExtension(info)) { - /* No GLX extension supported by this server. Oh well. */ - __glXUnlock(); - XMissingExtension(dpy, __glXExtensionName); - return 0; + for (dpyPriv = glx_displays; dpyPriv; dpyPriv = dpyPriv->next) { + if (dpyPriv->dpy == dpy) { + _XUnlockMutex(_Xglobal_lock); + return dpyPriv; + } } - /* See if a display private already exists. If so, return it */ - dataObj.display = dpy; - privList = XEHeadOfExtensionList(dataObj); - found = XFindOnExtensionList(privList, info->codes->extension); - if (found) { - __glXUnlock(); - return (__GLXdisplayPrivate *) found->private_data; + dpyPriv = Xcalloc(1, sizeof *dpyPriv); + if (!dpyPriv) + return NULL; + + dpyPriv->codes = XInitExtension(dpy, __glXExtensionName); + if (!dpyPriv->codes) { + Xfree(dpyPriv); + _XUnlockMutex(_Xglobal_lock); + return NULL; } + dpyPriv->dpy = dpy; + dpyPriv->majorOpcode = dpyPriv->codes->major_opcode; + dpyPriv->serverGLXvendor = 0x0; + dpyPriv->serverGLXversion = 0x0; + /* See if the versions are compatible */ - if (!QueryVersion(dpy, info->codes->major_opcode, &major, &minor)) { - /* The client and server do not agree on versions. Punt. */ - __glXUnlock(); - return 0; + if (!QueryVersion(dpy, dpyPriv->majorOpcode, + &dpyPriv->majorVersion, &dpyPriv->minorVersion)) { + Xfree(dpyPriv); + _XUnlockMutex(_Xglobal_lock); + return NULL; } - /* - ** Allocate memory for all the pieces needed for this buffer. - */ - private = (XExtData *) Xmalloc(sizeof(XExtData)); - if (!private) { - __glXUnlock(); - return 0; + for (i = 0; i < __GLX_NUMBER_EVENTS; i++) { + XESetWireToEvent(dpy, dpyPriv->codes->first_event + i, __glXWireToEvent); + XESetEventToWire(dpy, dpyPriv->codes->first_event + i, __glXEventToWire); } - dpyPriv = (__GLXdisplayPrivate *) Xcalloc(1, sizeof(__GLXdisplayPrivate)); - if (!dpyPriv) { - __glXUnlock(); - Xfree((char *) private); - return 0; - } - - /* - ** Init the display private and then read in the screen config - ** structures from the server. - */ - dpyPriv->majorOpcode = info->codes->major_opcode; - dpyPriv->majorVersion = major; - dpyPriv->minorVersion = minor; - dpyPriv->dpy = dpy; - dpyPriv->serverGLXvendor = 0x0; - dpyPriv->serverGLXversion = 0x0; + XESetCloseDisplay(dpy, dpyPriv->codes->extension, __glXCloseDisplay); + XESetErrorString (dpy, dpyPriv->codes->extension,__glXErrorString); #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) glx_direct = (getenv("LIBGL_ALWAYS_INDIRECT") == NULL); glx_accel = (getenv("LIBGL_ALWAYS_SOFTWARE") == NULL); + dpyPriv->drawHash = __glxHashCreate(); + /* ** Initialize the direct rendering per display data and functions. ** Note: This _must_ be done before calling any other DRI routines @@ -893,32 +844,25 @@ __glXInitialize(Display * dpy) if (glx_direct) dpyPriv->driswDisplay = driswCreateDisplay(dpy); #endif + #ifdef GLX_USE_APPLEGL - if (apple_init_glx(dpy) || !AllocAndFetchScreenConfigs(dpy, dpyPriv)) { -#else - if (!AllocAndFetchScreenConfigs(dpy, dpyPriv)) { + if (apple_init_glx(dpy)) { + Xfree(dpyPriv); + return NULL; + } #endif - __glXUnlock(); - Xfree((char *) dpyPriv); - Xfree((char *) private); - return 0; + if (!AllocAndFetchScreenConfigs(dpy, dpyPriv)) { + Xfree(dpyPriv); + return NULL; } - /* - ** Fill in the private structure. This is the actual structure that - ** hangs off of the Display structure. Our private structure is - ** referred to by this structure. Got that? - */ - private->number = info->codes->extension; - private->next = 0; - private->free_private = __glXFreeDisplayPrivate; - private->private_data = (char *) dpyPriv; - XAddToExtensionList(privList, private); - - if (dpyPriv->majorVersion == 1 && dpyPriv->minorVersion >= 1) { + if (dpyPriv->majorVersion == 1 && dpyPriv->minorVersion >= 1) __glXClientInfo(dpy, dpyPriv->majorOpcode); - } - __glXUnlock(); + + dpyPriv->next = glx_displays; + glx_displays = dpyPriv; + + _XUnlockMutex(_Xglobal_lock); return dpyPriv; } |