*/
#include <assert.h>
+#include <stdbool.h>
+
#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"
+#include "apple/apple_glx.h"
+#include "apple/apple_visual.h"
#endif
#include "glxextensions.h"
-#include "glcontextmodes.h"
-#ifdef USE_XCB
+#include "util/debug.h"
+
#include <X11/Xlib-xcb.h>
#include <xcb/xcb.h>
#include <xcb/glx.h>
-#endif
#ifdef DEBUG
-void __glXDumpDrawBuffer(__GLXcontext * ctx);
+void __glXDumpDrawBuffer(struct glx_context * ctx);
#endif
/*
/* Extension required boiler plate */
static const char __glXExtensionName[] = GLX_EXTENSION_NAME;
-static __GLXdisplayPrivate *glx_displays;
+ static struct glx_display *glx_displays;
static /* const */ char *error_list[] = {
"GLXBadContext",
"GLXBadPbuffer",
"GLXBadCurrentDrawable",
"GLXBadWindow",
+ "GLXBadProfileARB",
};
#ifdef GLX_USE_APPLEGL
XEXT_GENERATE_ERROR_STRING(__glXErrorString, __glXExtensionName,
__GLX_NUMBER_ERRORS, error_list)
-static int
-__glXCloseDisplay(Display * dpy, XExtCodes * codes);
-static Bool
-__glXWireToEvent(Display *dpy, XEvent *event, xEvent *wire);
-static Status
-__glXEventToWire(Display *dpy, XEvent *event, xEvent *wire);
-
/*
* GLX events are a bit funky. We don't stuff the X event code into
* our user exposed (via XNextEvent) structure. Instead we use the GLX
static Bool
__glXWireToEvent(Display *dpy, XEvent *event, xEvent *wire)
{
- __GLXdisplayPrivate *glx_dpy = __glXInitialize(dpy);
+ struct glx_display *glx_dpy = __glXInitialize(dpy);
if (glx_dpy == NULL)
return False;
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);
+
+ if (!glxDraw)
+ return False;
+
+ aevent->serial = _XSetLastRequestRead(dpy, (xGenericReply *) wire);
+ aevent->send_event = (awire->type & 0x80) != 0;
+ aevent->display = dpy;
aevent->event_type = awire->event_type;
- aevent->drawable = awire->drawable;
+ aevent->drawable = glxDraw->xDrawable;
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;
+
+ /* Handle 32-Bit wire sbc wraparound in both directions to cope with out
+ * of sequence 64-Bit sbc's
+ */
+ if ((int64_t) awire->sbc < ((int64_t) glxDraw->lastEventSbc - 0x40000000))
+ glxDraw->eventSbcWrap += 0x100000000;
+ if ((int64_t) awire->sbc > ((int64_t) glxDraw->lastEventSbc + 0x40000000))
+ glxDraw->eventSbcWrap -= 0x100000000;
+ glxDraw->lastEventSbc = awire->sbc;
+ aevent->sbc = awire->sbc + glxDraw->eventSbcWrap;
return True;
}
-#endif
default:
/* client doesn't support server event */
break;
static Status
__glXEventToWire(Display *dpy, XEvent *event, xEvent *wire)
{
- __GLXdisplayPrivate *glx_dpy = __glXInitialize(dpy);
+ struct glx_display *glx_dpy = __glXInitialize(dpy);
if (glx_dpy == NULL)
return False;
** __glXScreenConfigs.
*/
static void
-FreeScreenConfigs(__GLXdisplayPrivate * priv)
+FreeScreenConfigs(struct glx_display * priv)
{
- __GLXscreenConfigs *psc;
+ struct glx_screen *psc;
GLint i, screens;
/* Free screen configuration information */
screens = ScreenCount(priv->dpy);
for (i = 0; i < screens; i++) {
- psc = priv->screenConfigs[i];
- if (psc->configs) {
- _gl_context_modes_destroy(psc->configs);
- if (psc->effectiveGLXexts)
- Xfree(psc->effectiveGLXexts);
- psc->configs = NULL; /* NOTE: just for paranoia */
- }
- if (psc->visuals) {
- _gl_context_modes_destroy(psc->visuals);
- psc->visuals = NULL; /* NOTE: just for paranoia */
- }
- Xfree((char *) psc->serverGLXexts);
+ psc = priv->screens[i];
+ glx_screen_cleanup(psc);
#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
if (psc->driScreen) {
psc->driScreen->destroyScreen(psc);
- psc->driScreen = NULL;
} else {
- Xfree(psc);
+ free(psc);
}
#else
- Xfree(psc);
+ free(psc);
#endif
}
- XFree((char *) priv->screenConfigs);
- priv->screenConfigs = NULL;
+ free((char *) priv->screens);
+ 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)
{
- __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);
+ struct glx_context *gc;
gc = __glXGetCurrentContext();
- if (dpy == gc->currentDpy) {
+ if (priv->dpy == gc->currentDpy) {
gc->vtable->destroy(gc);
__glXSetCurrentContextNull();
}
FreeScreenConfigs(priv);
- if (priv->serverGLXvendor)
- Xfree((char *) priv->serverGLXvendor);
- if (priv->serverGLXversion)
- Xfree((char *) priv->serverGLXversion);
+ free((char *) priv->serverGLXvendor);
+ free((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);
priv->driswDisplay = NULL;
+#if defined (GLX_USE_DRM)
if (priv->driDisplay)
(*priv->driDisplay->destroyDisplay) (priv->driDisplay);
priv->driDisplay = NULL;
if (priv->dri2Display)
(*priv->dri2Display->destroyDisplay) (priv->dri2Display);
priv->dri2Display = NULL;
-#endif
- Xfree((char *) priv);
+ if (priv->dri3Display)
+ (*priv->dri3Display->destroyDisplay) (priv->dri3Display);
+ priv->dri3Display = NULL;
+#endif /* GLX_USE_DRM */
+
+#if defined(GLX_USE_WINDOWSGL)
+ if (priv->windowsdriDisplay)
+ (*priv->windowsdriDisplay->destroyDisplay) (priv->windowsdriDisplay);
+ priv->windowsdriDisplay = NULL;
+#endif /* GLX_USE_WINDOWSGL */
+
+#endif /* GLX_DIRECT_RENDERING && !GLX_USE_APPLEGL */
+
+ free((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);
+
+ if (priv != NULL)
+ glx_display_free(priv);
return 1;
}
static Bool
QueryVersion(Display * dpy, int opcode, int *major, int *minor)
{
-#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
xcb_glx_query_version_reply_t *reply = xcb_glx_query_version_reply(c,
xcb_glx_query_version
GLX_MINOR_VERSION),
NULL);
+ if (!reply)
+ return GL_FALSE;
+
if (reply->major_version != GLX_MAJOR_VERSION) {
free(reply);
return GL_FALSE;
*minor = min(reply->minor_version, GLX_MINOR_VERSION);
free(reply);
return GL_TRUE;
-#else
- xGLXQueryVersionReq *req;
- xGLXQueryVersionReply reply;
-
- /* Send the glXQueryVersion request */
- LockDisplay(dpy);
- GetReq(GLXQueryVersion, req);
- req->reqType = opcode;
- req->glxCode = X_GLXQueryVersion;
- req->majorVersion = GLX_MAJOR_VERSION;
- req->minorVersion = GLX_MINOR_VERSION;
- _XReply(dpy, (xReply *) & reply, 0, False);
- UnlockDisplay(dpy);
- SyncHandle();
-
- if (reply.majorVersion != GLX_MAJOR_VERSION) {
- /*
- ** The server does not support the same major release as this
- ** client.
- */
- return GL_FALSE;
- }
- *major = reply.majorVersion;
- *minor = min(reply.minorVersion, GLX_MINOR_VERSION);
- return GL_TRUE;
-#endif /* USE_XCB */
}
/*
};
+static GLint
+convert_from_x_visual_type(int visualType)
+{
+ static const int glx_visual_types[] = {
+ [StaticGray] = GLX_STATIC_GRAY,
+ [GrayScale] = GLX_GRAY_SCALE,
+ [StaticColor] = GLX_STATIC_COLOR,
+ [PseudoColor] = GLX_PSEUDO_COLOR,
+ [TrueColor] = GLX_TRUE_COLOR,
+ [DirectColor] = GLX_DIRECT_COLOR,
+ };
+
+ if (visualType < ARRAY_SIZE(glx_visual_types))
+ return glx_visual_types[visualType];
+
+ return GLX_NONE;
+}
+
/*
* getVisualConfigs uses the !tagged_only path.
* getFBConfigs uses the tagged_only path.
*/
_X_HIDDEN void
-__glXInitializeVisualConfigFromTags(__GLcontextModes * config, int count,
+__glXInitializeVisualConfigFromTags(struct glx_config * config, int count,
const INT32 * bp, Bool tagged_only,
Bool fbconfig_style_tags)
{
int i;
+ GLint renderType = 0;
if (!tagged_only) {
/* Copy in the first set of properties */
config->visualID = *bp++;
- config->visualType = _gl_convert_from_x_visual_type(*bp++);
+ config->visualType = convert_from_x_visual_type(*bp++);
config->rgbMode = *bp++;
config->drawableType |= GLX_WINDOW_BIT | GLX_PIXMAP_BIT | GLX_PBUFFER_BIT;
#endif
break;
- case GLX_RENDER_TYPE:
- config->renderType = *bp++;
+ case GLX_RENDER_TYPE: /* fbconfig render type bits */
+ renderType = *bp++;
break;
case GLX_X_RENDERABLE:
config->xRenderable = *bp++;
config->visualSelectGroup = *bp++;
break;
case GLX_SWAP_METHOD_OML:
- config->swapMethod = *bp++;
+ if (*bp == GLX_SWAP_UNDEFINED_OML ||
+ *bp == GLX_SWAP_COPY_OML ||
+ *bp == GLX_SWAP_EXCHANGE_OML) {
+ config->swapMethod = *bp++;
+ } else {
+ /* X servers with old HW drivers may return any value here, so
+ * assume GLX_SWAP_METHOD_UNDEFINED.
+ */
+ config->swapMethod = GLX_SWAP_UNDEFINED_OML;
+ bp++;
+ }
break;
#endif
case GLX_SAMPLE_BUFFERS_SGIS:
config->yInverted = *bp++;
break;
#endif
+ case GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT:
+ config->sRGBCapable = *bp++;
+ break;
+
case GLX_USE_GL:
if (fbconfig_style_tags)
bp++;
i = count;
break;
default:
- if(getenv("LIBGL_DIAGNOSTIC")) {
+ if(env_var_as_boolean("LIBGL_DIAGNOSTIC", false)) {
long int tagvalue = *bp++;
fprintf(stderr, "WARNING: unknown GLX tag from server: "
"tag 0x%lx value 0x%lx\n", tag, tagvalue);
}
}
- config->renderType =
- (config->rgbMode) ? GLX_RGBA_BIT : GLX_COLOR_INDEX_BIT;
+ if (renderType != 0 && renderType != GLX_DONT_CARE) {
+ config->renderType = renderType;
+ config->floatMode = (renderType &
+ (GLX_RGBA_FLOAT_BIT_ARB|GLX_RGBA_UNSIGNED_FLOAT_BIT_EXT)) != 0;
+ } else {
+ /* If there wasn't GLX_RENDER_TYPE property, set it based on
+ * config->rgbMode. The only way to communicate that the config is
+ * floating-point is via GLX_RENDER_TYPE, so this cannot be a float
+ * config.
+ */
+ config->renderType =
+ (config->rgbMode) ? GLX_RGBA_BIT : GLX_COLOR_INDEX_BIT;
+ }
- config->haveAccumBuffer = ((config->accumRedBits +
- config->accumGreenBits +
- config->accumBlueBits +
- config->accumAlphaBits) > 0);
- config->haveDepthBuffer = (config->depthBits > 0);
- config->haveStencilBuffer = (config->stencilBits > 0);
+ /* The GLX_ARB_fbconfig_float spec says:
+ *
+ * "Note that floating point rendering is only supported for
+ * GLXPbuffer drawables."
+ */
+ if (config->floatMode)
+ config->drawableType &= GLX_PBUFFER_BIT;
}
-static __GLcontextModes *
+static struct glx_config *
createConfigsFromProperties(Display * dpy, int nvisuals, int nprops,
int screen, GLboolean tagged_only)
{
INT32 buf[__GLX_TOTAL_CONFIG], *props;
unsigned prop_size;
- __GLcontextModes *modes, *m;
+ struct glx_config *modes, *m;
int i;
if (nprops == 0)
return NULL;
/* Allocate memory for our config structure */
- modes = _gl_context_modes_create(nvisuals, sizeof(__GLcontextModes));
+ modes = glx_config_create_list(nvisuals);
if (!modes)
return NULL;
if (prop_size <= sizeof(buf))
props = buf;
else
- props = Xmalloc(prop_size);
+ props = malloc(prop_size);
/* Read each config structure and convert it into our format */
m = modes;
*/
m->drawableType = GLX_WINDOW_BIT | GLX_PIXMAP_BIT | GLX_PBUFFER_BIT;
#endif
+ /* Older X servers don't send this so we default it here. */
+ m->sRGBCapable = GL_FALSE;
__glXInitializeVisualConfigFromTags(m, nprops, props,
tagged_only, GL_TRUE);
m->screen = screen;
}
if (props != buf)
- Xfree(props);
+ free(props);
return modes;
}
static GLboolean
-getVisualConfigs(__GLXscreenConfigs *psc,
- __GLXdisplayPrivate *priv, int screen)
+getVisualConfigs(struct glx_screen *psc,
+ struct glx_display *priv, int screen)
{
xGLXGetVisualConfigsReq *req;
xGLXGetVisualConfigsReply reply;
}
static GLboolean
-getFBConfigs(__GLXscreenConfigs *psc, __GLXdisplayPrivate *priv, int screen)
+ getFBConfigs(struct glx_screen *psc, struct glx_display *priv, int screen)
{
xGLXGetFBConfigsReq *fb_req;
xGLXGetFBConfigsSGIXReq *sgi_req;
psc->serverGLXexts =
__glXQueryServerString(dpy, priv->majorOpcode, screen, GLX_EXTENSIONS);
+ if (psc->serverGLXexts == NULL) {
+ return GL_FALSE;
+ }
+
LockDisplay(dpy);
psc->configs = NULL;
}
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;
}
_X_HIDDEN Bool
-glx_screen_init(__GLXscreenConfigs *psc,
- int screen, __GLXdisplayPrivate * priv)
+glx_screen_init(struct glx_screen *psc,
+ int screen, struct glx_display * priv)
{
/* Initialize per screen dynamic client GLX extensions */
psc->ext_list_first_time = GL_TRUE;
psc->dpy = priv->dpy;
psc->display = priv;
- getVisualConfigs(psc, priv, screen);
- getFBConfigs(psc, priv, screen);
+ if (!getVisualConfigs(psc, priv, screen))
+ return GL_FALSE;
+
+ if (!getFBConfigs(psc, priv, screen))
+ return GL_FALSE;
return GL_TRUE;
}
-static __GLXscreenConfigs *
-createIndirectScreen()
+_X_HIDDEN void
+glx_screen_cleanup(struct glx_screen *psc)
{
- __GLXscreenConfigs *psc;
-
- psc = Xmalloc(sizeof *psc);
- memset(psc, 0, sizeof *psc);
-
- return psc;
+ if (psc->configs) {
+ glx_config_destroy_list(psc->configs);
+ free(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 */
+ }
+ free((char *) psc->serverGLXexts);
}
/*
** If that works then fetch the per screen configs data.
*/
static Bool
-AllocAndFetchScreenConfigs(Display * dpy, __GLXdisplayPrivate * priv)
+AllocAndFetchScreenConfigs(Display * dpy, struct glx_display * priv)
{
- __GLXscreenConfigs *psc;
+ struct glx_screen *psc;
GLint i, screens;
/*
** First allocate memory for the array of per screen configs.
*/
screens = ScreenCount(dpy);
- priv->screenConfigs = Xmalloc(screens * sizeof *priv->screenConfigs);
- if (!priv->screenConfigs)
+ priv->screens = malloc(screens * sizeof *priv->screens);
+ if (!priv->screens)
return GL_FALSE;
priv->serverGLXversion =
}
for (i = 0; i < screens; i++, psc++) {
+ psc = NULL;
#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
- if (priv->dri2Display)
+#if defined(GLX_USE_DRM)
+#if defined(HAVE_DRI3)
+ if (priv->dri3Display)
+ psc = (*priv->dri3Display->createScreen) (i, priv);
+#endif /* HAVE_DRI3 */
+ if (psc == NULL && priv->dri2Display)
psc = (*priv->dri2Display->createScreen) (i, priv);
if (psc == NULL && priv->driDisplay)
psc = (*priv->driDisplay->createScreen) (i, priv);
+#endif /* GLX_USE_DRM */
+
+#ifdef GLX_USE_WINDOWSGL
+ if (psc == NULL && priv->windowsdriDisplay)
+ psc = (*priv->windowsdriDisplay->createScreen) (i, priv);
+#endif
+
if (psc == NULL && priv->driswDisplay)
psc = (*priv->driswDisplay->createScreen) (i, priv);
+#endif /* GLX_DIRECT_RENDERING && !GLX_USE_APPLEGL */
+
+#if defined(GLX_USE_APPLEGL)
if (psc == NULL)
- psc = createIndirectScreen (i, priv);
+ psc = applegl_create_screen(i, priv);
+#else
+ if (psc == NULL)
+ psc = indirect_create_screen(i, priv);
#endif
- priv->screenConfigs[i] = psc;
+ priv->screens[i] = psc;
}
SyncHandle();
return GL_TRUE;
/*
** Initialize the client side extension code.
*/
-_X_HIDDEN __GLXdisplayPrivate *
+ _X_HIDDEN struct glx_display *
__glXInitialize(Display * dpy)
{
- __GLXdisplayPrivate *dpyPriv;
+ struct glx_display *dpyPriv, *d;
#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
Bool glx_direct, glx_accel;
#endif
}
}
- dpyPriv = Xcalloc(1, sizeof *dpyPriv);
+ /* Drop the lock while we create the display private. */
+ _XUnlockMutex(_Xglobal_lock);
+
+ dpyPriv = calloc(1, sizeof *dpyPriv);
if (!dpyPriv)
return NULL;
dpyPriv->codes = XInitExtension(dpy, __glXExtensionName);
if (!dpyPriv->codes) {
- Xfree(dpyPriv);
- _XUnlockMutex(_Xglobal_lock);
+ free(dpyPriv);
return NULL;
}
dpyPriv->serverGLXvendor = 0x0;
dpyPriv->serverGLXversion = 0x0;
- /* See if the versions are compatible */
+ /* See if the versions are compatible. This GLX implementation does not
+ * work with servers that only support GLX 1.0.
+ */
if (!QueryVersion(dpy, dpyPriv->majorOpcode,
- &dpyPriv->majorVersion, &dpyPriv->minorVersion)) {
- Xfree(dpyPriv);
- _XUnlockMutex(_Xglobal_lock);
+ &dpyPriv->majorVersion, &dpyPriv->minorVersion)
+ || (dpyPriv->majorVersion == 1 && dpyPriv->minorVersion < 1)) {
+ free(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);
+ glx_direct = !env_var_as_boolean("LIBGL_ALWAYS_INDIRECT", false);
+ glx_accel = !env_var_as_boolean("LIBGL_ALWAYS_SOFTWARE", false);
dpyPriv->drawHash = __glxHashCreate();
** Note: This _must_ be done before calling any other DRI routines
** (e.g., those called in AllocAndFetchScreenConfigs).
*/
+#if defined(GLX_USE_DRM)
if (glx_direct && glx_accel) {
+#if defined(HAVE_DRI3)
+ if (!env_var_as_boolean("LIBGL_DRI3_DISABLE", false))
+ dpyPriv->dri3Display = dri3_create_display(dpy);
+#endif /* HAVE_DRI3 */
dpyPriv->dri2Display = dri2CreateDisplay(dpy);
dpyPriv->driDisplay = driCreateDisplay(dpy);
}
+#endif /* GLX_USE_DRM */
if (glx_direct)
dpyPriv->driswDisplay = driswCreateDisplay(dpy);
-#endif
+#endif /* GLX_DIRECT_RENDERING && !GLX_USE_APPLEGL */
#ifdef GLX_USE_APPLEGL
- if (apple_init_glx(dpy)) {
- Xfree(dpyPriv);
+ if (!applegl_create_display(dpyPriv)) {
+ free(dpyPriv);
return NULL;
}
#endif
+
+#ifdef GLX_USE_WINDOWSGL
+ if (glx_direct && glx_accel)
+ dpyPriv->windowsdriDisplay = driwindowsCreateDisplay(dpy);
+#endif
+
if (!AllocAndFetchScreenConfigs(dpy, dpyPriv)) {
- Xfree(dpyPriv);
+ free(dpyPriv);
return NULL;
}
- if (dpyPriv->majorVersion == 1 && dpyPriv->minorVersion >= 1)
- __glXClientInfo(dpy, dpyPriv->majorOpcode);
+ __glX_send_client_info(dpyPriv);
+
+ /* 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;
- _XUnlockMutex(_Xglobal_lock);
+ _XUnlockMutex(_Xglobal_lock);
return dpyPriv;
}
_X_HIDDEN CARD8
__glXSetupForCommand(Display * dpy)
{
- GLXContext gc;
- __GLXdisplayPrivate *priv;
+ struct glx_context *gc;
+ struct glx_display *priv;
/* If this thread has a current context, flush its rendering commands */
gc = __glXGetCurrentContext();
* \c pc parameter.
*/
_X_HIDDEN GLubyte *
-__glXFlushRenderBuffer(__GLXcontext * ctx, GLubyte * pc)
+__glXFlushRenderBuffer(struct glx_context * ctx, GLubyte * pc)
{
Display *const dpy = ctx->currentDpy;
-#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
-#else
- xGLXRenderReq *req;
-#endif /* USE_XCB */
const GLint size = pc - ctx->buf;
if ((dpy != NULL) && (size > 0)) {
-#ifdef USE_XCB
xcb_glx_render(c, ctx->currentContextTag, size,
(const uint8_t *) ctx->buf);
-#else
- /* Send the entire buffer as an X request */
- LockDisplay(dpy);
- GetReq(GLXRender, req);
- req->reqType = ctx->majorOpcode;
- req->glxCode = X_GLXRender;
- req->contextTag = ctx->currentContextTag;
- req->length += (size + 3) >> 2;
- _XSend(dpy, (char *) ctx->buf, size);
- UnlockDisplay(dpy);
- SyncHandle();
-#endif
}
/* Reset pointer and return it */
* \param dataLen Size, in bytes, of the command data.
*/
_X_HIDDEN void
-__glXSendLargeChunk(__GLXcontext * gc, GLint requestNumber,
+__glXSendLargeChunk(struct glx_context * gc, GLint requestNumber,
GLint totalRequests, const GLvoid * data, GLint dataLen)
{
Display *dpy = gc->currentDpy;
-#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
xcb_glx_render_large(c, gc->currentContextTag, requestNumber,
totalRequests, dataLen, data);
-#else
- xGLXRenderLargeReq *req;
-
- if (requestNumber == 1) {
- LockDisplay(dpy);
- }
-
- GetReq(GLXRenderLarge, req);
- req->reqType = gc->majorOpcode;
- req->glxCode = X_GLXRenderLarge;
- req->contextTag = gc->currentContextTag;
- req->length += (dataLen + 3) >> 2;
- req->requestNumber = requestNumber;
- req->requestTotal = totalRequests;
- req->dataBytes = dataLen;
- Data(dpy, data, dataLen);
-
- if (requestNumber == totalRequests) {
- UnlockDisplay(dpy);
- SyncHandle();
- }
-#endif /* USE_XCB */
}
* \param dataLen Size, in bytes, of the command data.
*/
_X_HIDDEN void
-__glXSendLargeCommand(__GLXcontext * ctx,
+__glXSendLargeCommand(struct glx_context * ctx,
const GLvoid * header, GLint headerLen,
const GLvoid * data, GLint dataLen)
{
#ifdef DEBUG
_X_HIDDEN void
-__glXDumpDrawBuffer(__GLXcontext * ctx)
+__glXDumpDrawBuffer(struct glx_context * ctx)
{
GLubyte *p = ctx->buf;
GLubyte *end = ctx->pc;