*/
#include <assert.h>
+#include <stdbool.h>
+
#include "glxclient.h"
#include <X11/extensions/Xext.h>
#include <X11/extensions/extutil.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"
-#ifdef USE_XCB
+#include "util/debug.h"
+#ifndef GLX_USE_APPLEGL
+#include "dri_common.h"
+#endif
+
#include <X11/Xlib-xcb.h>
#include <xcb/xcb.h>
#include <xcb/glx.h>
-#endif
#ifdef DEBUG
/* Extension required boiler plate */
static const char __glXExtensionName[] = GLX_EXTENSION_NAME;
- static struct glx_display *glx_displays;
+static struct glx_display *glx_displays;
static /* const */ char *error_list[] = {
"GLXBadContext",
"GLXBadPbuffer",
"GLXBadCurrentDrawable",
"GLXBadWindow",
+ "GLXBadProfileARB",
};
#ifdef GLX_USE_APPLEGL
GLXBufferSwapComplete *aevent = (GLXBufferSwapComplete *)event;
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;
if (!glxDraw)
return False;
- if (awire->sbc < glxDraw->lastEventSbc)
- glxDraw->eventSbcWrap += 0x100000000;
+ aevent->serial = _XSetLastRequestRead(dpy, (xGenericReply *) wire);
+ aevent->send_event = (awire->type & 0x80) != 0;
+ aevent->display = dpy;
+ aevent->event_type = awire->event_type;
+ aevent->drawable = glxDraw->xDrawable;
+ aevent->ust = ((CARD64)awire->ust_hi << 32) | awire->ust_lo;
+ aevent->msc = ((CARD64)awire->msc_hi << 32) | awire->msc_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;
screens = ScreenCount(priv->dpy);
for (i = 0; i < screens; i++) {
psc = priv->screens[i];
+ if (!psc)
+ continue;
glx_screen_cleanup(psc);
#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
(*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
+
+ 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);
}
}
_XUnlockMutex(_Xglobal_lock);
- glx_display_free(priv);
+ 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
*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 */
}
/*
convert_from_x_visual_type(int visualType)
{
static const int glx_visual_types[] = {
- GLX_STATIC_GRAY, GLX_GRAY_SCALE,
- GLX_STATIC_COLOR, GLX_PSEUDO_COLOR,
- GLX_TRUE_COLOR, GLX_DIRECT_COLOR
+ [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))
config->visualType = convert_from_x_visual_type(*bp++);
- config->rgbMode = *bp++;
+ config->renderType = *bp++ ? GLX_RGBA_BIT : GLX_COLOR_INDEX_BIT;
config->redBits = *bp++;
config->greenBits = *bp++;
switch (tag) {
case GLX_RGBA:
- FETCH_OR_SET(rgbMode);
+ if (fbconfig_style_tags)
+ config->renderType = *bp++ ? GLX_RGBA_BIT : GLX_COLOR_INDEX_BIT;
+ else
+ config->renderType = GLX_RGBA_BIT;
break;
case GLX_BUFFER_SIZE:
config->rgbBits = *bp++;
config->drawableType |= GLX_WINDOW_BIT | GLX_PIXMAP_BIT | GLX_PBUFFER_BIT;
#endif
break;
- case GLX_RENDER_TYPE:
+ case GLX_RENDER_TYPE: /* fbconfig render type bits */
config->renderType = *bp++;
break;
case GLX_X_RENDERABLE:
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:
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;
+ /* The GLX_ARB_fbconfig_float spec says:
+ *
+ * "Note that floating point rendering is only supported for
+ * GLXPbuffer drawables."
+ */
+ if (config->renderType &
+ (GLX_RGBA_FLOAT_BIT_ARB|GLX_RGBA_UNSIGNED_FLOAT_BIT_EXT))
+ config->drawableType &= GLX_PBUFFER_BIT;
}
static struct glx_config *
*/
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;
psc->serverGLXexts =
__glXQueryServerString(dpy, priv->majorOpcode, screen, GLX_EXTENSIONS);
+ if (psc->serverGLXexts == NULL) {
+ return GL_FALSE;
+ }
+
LockDisplay(dpy);
psc->configs = NULL;
- if (atof(priv->serverGLXversion) >= 1.3) {
+ if (priv->majorVersion > 1 ||
+ (priv->majorVersion == 1 && priv->minorVersion >= 3)) {
GetReq(GLXGetFBConfigs, fb_req);
fb_req->reqType = priv->majorOpcode;
fb_req->glxCode = X_GLXGetFBConfigs;
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;
}
** First allocate memory for the array of per screen configs.
*/
screens = ScreenCount(dpy);
- priv->screens = malloc(screens * sizeof *priv->screens);
+ priv->screens = calloc(screens, sizeof *priv->screens);
if (!priv->screens)
return GL_FALSE;
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
+#endif /* GLX_DIRECT_RENDERING && !GLX_USE_APPLEGL */
+
#if defined(GLX_USE_APPLEGL)
if (psc == NULL)
psc = applegl_create_screen(i, priv);
dpyPriv->codes = XInitExtension(dpy, __glXExtensionName);
if (!dpyPriv->codes) {
free(dpyPriv);
- _XUnlockMutex(_Xglobal_lock);
return NULL;
}
&dpyPriv->majorVersion, &dpyPriv->minorVersion)
|| (dpyPriv->majorVersion == 1 && dpyPriv->minorVersion < 1)) {
free(dpyPriv);
- _XUnlockMutex(_Xglobal_lock);
return NULL;
}
}
XESetCloseDisplay(dpy, dpyPriv->codes->extension, __glXCloseDisplay);
- XESetErrorString (dpy, dpyPriv->codes->extension,__glXErrorString);
+ 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();
+#ifndef GLX_USE_APPLEGL
+ /* Set the logger before the *CreateDisplay functions. */
+ loader_set_logger(dri_message);
+#endif
+
/*
** Initialize the direct rendering per display data and functions.
** 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 (!applegl_create_display(dpyPriv)) {
return NULL;
}
#endif
+
+#ifdef GLX_USE_WINDOWSGL
+ if (glx_direct && glx_accel)
+ dpyPriv->windowsdriDisplay = driwindowsCreateDisplay(dpy);
+#endif
+
if (!AllocAndFetchScreenConfigs(dpy, dpyPriv)) {
free(dpyPriv);
return NULL;
}
-#ifdef USE_XCB
__glX_send_client_info(dpyPriv);
-#else
- __glXClientInfo(dpy, dpyPriv->majorOpcode);
-#endif
/* Grab the lock again and add the dispay private, unless somebody
* beat us to initializing on this display in the meantime. */
dpyPriv->next = glx_displays;
glx_displays = dpyPriv;
- _XUnlockMutex(_Xglobal_lock);
+ _XUnlockMutex(_Xglobal_lock);
return dpyPriv;
}
__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 */
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 */
}