#include "glxclient.h"
#include <X11/extensions/Xext.h>
#include <X11/extensions/extutil.h>
-#include <X11/extensions/dri2proto.h>
#ifdef GLX_USE_APPLEGL
#include "apple_glx.h"
#include "apple_visual.h"
aevent->count = awire->count;
return True;
}
- /* No easy symbol to test for this, as GLX_BufferSwapComplete is
- * defined in the local glx.h header, but the
- * xGLXBufferSwapComplete typedef is only available in new versions
- * of the external glxproto.h header, which doesn't have any
- * testable versioning define.
- *
- * I'll use the related DRI2 define, in the hope that we won't
- * receive these events unless we know how to ask for them:
- */
-#ifdef X_DRI2SwapBuffers
case GLX_BufferSwapComplete:
{
GLXBufferSwapComplete *aevent = (GLXBufferSwapComplete *)event;
- xGLXBufferSwapComplete *awire = (xGLXBufferSwapComplete *)wire;
+ xGLXBufferSwapComplete2 *awire = (xGLXBufferSwapComplete2 *)wire;
+ struct glx_drawable *glxDraw = GetGLXDrawable(dpy, awire->drawable);
aevent->event_type = awire->event_type;
aevent->drawable = awire->drawable;
aevent->ust = ((CARD64)awire->ust_hi << 32) | awire->ust_lo;
aevent->msc = ((CARD64)awire->msc_hi << 32) | awire->msc_lo;
- aevent->sbc = ((CARD64)awire->sbc_hi << 32) | awire->sbc_lo;
+
+ if (!glxDraw)
+ return False;
+
+ if (awire->sbc < glxDraw->lastEventSbc)
+ glxDraw->eventSbcWrap += 0x100000000;
+ glxDraw->lastEventSbc = awire->sbc;
+ aevent->sbc = awire->sbc + glxDraw->eventSbcWrap;
return True;
}
-#endif
default:
/* client doesn't support server event */
break;
** __glXScreenConfigs.
*/
static void
- FreeScreenConfigs(struct glx_display * priv)
+FreeScreenConfigs(struct glx_display * priv)
{
struct glx_screen *psc;
GLint i, screens;
screens = ScreenCount(priv->dpy);
for (i = 0; i < screens; i++) {
psc = priv->screens[i];
- if (psc->configs) {
- glx_config_destroy_list(psc->configs);
- if (psc->effectiveGLXexts)
- Xfree(psc->effectiveGLXexts);
- psc->configs = NULL; /* NOTE: just for paranoia */
- }
- if (psc->visuals) {
- glx_config_destroy_list(psc->visuals);
- psc->visuals = NULL; /* NOTE: just for paranoia */
- }
- Xfree((char *) psc->serverGLXexts);
+ glx_screen_cleanup(psc);
#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
if (psc->driScreen) {
priv->screens = NULL;
}
-/*
-** Release the private memory referred to in a display private
-** structure. The caller will free the extension structure.
-*/
-static int
-__glXCloseDisplay(Display * dpy, XExtCodes * codes)
+static void
+glx_display_free(struct glx_display *priv)
{
- struct glx_display *priv, **prev;
- struct glx_context *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);
+ struct glx_context *gc;
gc = __glXGetCurrentContext();
- if (dpy == gc->currentDpy) {
+ if (priv->dpy == gc->currentDpy) {
gc->vtable->destroy(gc);
__glXSetCurrentContextNull();
}
if (priv->serverGLXversion)
Xfree((char *) priv->serverGLXversion);
- __glxHashDestroy(priv->drawHash);
+ __glxHashDestroy(priv->glXDrawHash);
#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
+ __glxHashDestroy(priv->drawHash);
+
/* Free the direct rendering per display data */
if (priv->driswDisplay)
(*priv->driswDisplay->destroyDisplay) (priv->driswDisplay);
#endif
Xfree((char *) priv);
+}
+
+static int
+__glXCloseDisplay(Display * dpy, XExtCodes * codes)
+{
+ struct glx_display *priv, **prev;
+
+ _XLockMutex(_Xglobal_lock);
+ prev = &glx_displays;
+ for (priv = glx_displays; priv; prev = &priv->next, priv = priv->next) {
+ if (priv->dpy == dpy) {
+ *prev = priv->next;
+ break;
+ }
+ }
+ _XUnlockMutex(_Xglobal_lock);
+
+ glx_display_free(priv);
return 1;
}
config->yInverted = *bp++;
break;
#endif
+ case GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT:
+ config->sRGBCapable = *bp++;
+ break;
+
case GLX_USE_GL:
if (fbconfig_style_tags)
bp++;
}
else if (strstr(psc->serverGLXexts, "GLX_SGIX_fbconfig") != NULL) {
GetReqExtra(GLXVendorPrivateWithReply,
- sz_xGLXGetFBConfigsSGIXReq +
+ sz_xGLXGetFBConfigsSGIXReq -
sz_xGLXVendorPrivateWithReplyReq, vpreq);
sgi_req = (xGLXGetFBConfigsSGIXReq *) vpreq;
sgi_req->reqType = priv->majorOpcode;
return GL_TRUE;
}
+_X_HIDDEN void
+glx_screen_cleanup(struct glx_screen *psc)
+{
+ if (psc->configs) {
+ glx_config_destroy_list(psc->configs);
+ if (psc->effectiveGLXexts)
+ Xfree(psc->effectiveGLXexts);
+ psc->configs = NULL; /* NOTE: just for paranoia */
+ }
+ if (psc->visuals) {
+ glx_config_destroy_list(psc->visuals);
+ psc->visuals = NULL; /* NOTE: just for paranoia */
+ }
+ Xfree((char *) psc->serverGLXexts);
+}
+
/*
** Allocate the memory for the per screen configs for each screen.
** If that works then fetch the per screen configs data.
*/
static Bool
- AllocAndFetchScreenConfigs(Display * dpy, struct glx_display * priv)
+AllocAndFetchScreenConfigs(Display * dpy, struct glx_display * priv)
{
struct glx_screen *psc;
GLint i, screens;
if (psc == NULL && priv->driswDisplay)
psc = (*priv->driswDisplay->createScreen) (i, priv);
#endif
+#if defined(GLX_USE_APPLEGL)
+ if (psc == NULL)
+ psc = applegl_create_screen(i, priv);
+#else
if (psc == NULL)
psc = indirect_create_screen(i, priv);
+#endif
priv->screens[i] = psc;
}
SyncHandle();
_X_HIDDEN struct glx_display *
__glXInitialize(Display * dpy)
{
- struct glx_display *dpyPriv;
+ struct glx_display *dpyPriv, *d;
#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
Bool glx_direct, glx_accel;
#endif
}
}
+ /* Drop the lock while we create the display private. */
+ _XUnlockMutex(_Xglobal_lock);
+
dpyPriv = Xcalloc(1, sizeof *dpyPriv);
if (!dpyPriv)
return NULL;
XESetCloseDisplay(dpy, dpyPriv->codes->extension, __glXCloseDisplay);
XESetErrorString (dpy, dpyPriv->codes->extension,__glXErrorString);
+ dpyPriv->glXDrawHash = __glxHashCreate();
+
#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
glx_direct = (getenv("LIBGL_ALWAYS_INDIRECT") == NULL);
glx_accel = (getenv("LIBGL_ALWAYS_SOFTWARE") == NULL);
#endif
#ifdef GLX_USE_APPLEGL
- if (apple_init_glx(dpy)) {
+ if (!applegl_create_display(dpyPriv)) {
Xfree(dpyPriv);
return NULL;
}
if (dpyPriv->majorVersion == 1 && dpyPriv->minorVersion >= 1)
__glXClientInfo(dpy, dpyPriv->majorOpcode);
+ /* Grab the lock again and add the dispay private, unless somebody
+ * beat us to initializing on this display in the meantime. */
+ _XLockMutex(_Xglobal_lock);
+
+ for (d = glx_displays; d; d = d->next) {
+ if (d->dpy == dpy) {
+ _XUnlockMutex(_Xglobal_lock);
+ glx_display_free(dpyPriv);
+ return d;
+ }
+ }
+
dpyPriv->next = glx_displays;
glx_displays = dpyPriv;