#include "glapi.h"
#include "glxextensions.h"
#include "indirect.h"
+#include "glx_error.h"
#ifdef GLX_DIRECT_RENDERING
#ifdef GLX_USE_APPLEGL
-#include "apple_glx_context.h"
-#include "apple_glx.h"
-#include "glx_error.h"
+#include "apple/apple_glx_context.h"
+#include "apple/apple_glx.h"
+#include "util/debug.h"
#else
#include <sys/time.h>
-#ifdef XF86VIDMODE
+#ifndef GLX_USE_WINDOWSGL
#include <X11/extensions/xf86vmode.h>
+#endif /* GLX_USE_WINDOWSGL */
#endif
-#include "xf86dri.h"
-#endif
-#else
#endif
-#if defined(USE_XCB)
#include <X11/Xlib-xcb.h>
#include <xcb/xcb.h>
#include <xcb/glx.h>
-#endif
+#include "GL/mesa_glinterop.h"
static const char __glXGLXClientVendorName[] = "Mesa Project and SGI";
static const char __glXGLXClientVersion[] = "1.4";
#endif
+_X_HIDDEN struct glx_drawable *
+GetGLXDrawable(Display *dpy, GLXDrawable drawable)
+{
+ struct glx_display *priv = __glXInitialize(dpy);
+ struct glx_drawable *glxDraw;
+
+ if (priv == NULL)
+ return NULL;
+
+ if (__glxHashLookup(priv->glXDrawHash, drawable, (void *) &glxDraw) == 0)
+ return glxDraw;
+
+ return NULL;
+}
+
+_X_HIDDEN int
+InitGLXDrawable(Display *dpy, struct glx_drawable *glxDraw, XID xDrawable,
+ GLXDrawable drawable)
+{
+ struct glx_display *priv = __glXInitialize(dpy);
+
+ if (!priv)
+ return -1;
+
+ glxDraw->xDrawable = xDrawable;
+ glxDraw->drawable = drawable;
+ glxDraw->lastEventSbc = 0;
+ glxDraw->eventSbcWrap = 0;
+
+ return __glxHashInsert(priv->glXDrawHash, drawable, glxDraw);
+}
+
+_X_HIDDEN void
+DestroyGLXDrawable(Display *dpy, GLXDrawable drawable)
+{
+ struct glx_display *priv = __glXInitialize(dpy);
+ struct glx_drawable *glxDraw;
+
+ if (!priv)
+ return;
+
+ glxDraw = GetGLXDrawable(dpy, drawable);
+ __glxHashDelete(priv->glXDrawHash, drawable);
+ free(glxDraw);
+}
/**
* Get the GLX per-screen data structure associated with a GLX context.
* number range for \c dpy?
*/
-static struct glx_screen *
+_X_HIDDEN struct glx_screen *
GetGLXScreenConfigs(Display * dpy, int scrn)
{
struct glx_display *const priv = __glXInitialize(dpy);
/* Check to see if the GL is supported on this screen */
*ppsc = (*ppriv)->screens[scrn];
- if ((*ppsc)->configs == NULL) {
+ if ((*ppsc)->configs == NULL && (*ppsc)->visuals == NULL) {
/* No support for GL on this screen regardless of visual */
return GLX_BAD_VISUAL;
}
return NULL;
}
+/**
+ * Verifies context's GLX_RENDER_TYPE value with config.
+ *
+ * \param config GLX FBConfig which will support the returned renderType.
+ * \param renderType The context render type to be verified.
+ * \return True if the value of context renderType was approved, or 0 if no
+ * valid value was found.
+ */
+Bool
+validate_renderType_against_config(const struct glx_config *config,
+ int renderType)
+{
+ /* GLX_EXT_no_config_context supports any render type */
+ if (!config)
+ return True;
+
+ switch (renderType) {
+ case GLX_RGBA_TYPE:
+ return (config->renderType & GLX_RGBA_BIT) != 0;
+ case GLX_COLOR_INDEX_TYPE:
+ return (config->renderType & GLX_COLOR_INDEX_BIT) != 0;
+ case GLX_RGBA_FLOAT_TYPE_ARB:
+ return (config->renderType & GLX_RGBA_FLOAT_BIT_ARB) != 0;
+ case GLX_RGBA_UNSIGNED_FLOAT_TYPE_EXT:
+ return (config->renderType & GLX_RGBA_UNSIGNED_FLOAT_BIT_EXT) != 0;
+ default:
+ break;
+ }
+ return 0;
+}
+
_X_HIDDEN Bool
glx_context_init(struct glx_context *gc,
struct glx_screen *psc, struct glx_config *config)
{
gc->majorOpcode = __glXSetupForCommand(psc->display->dpy);
if (!gc->majorOpcode)
- return GL_FALSE;
+ return False;
gc->screen = psc->scr;
gc->psc = psc;
gc->isDirect = GL_TRUE;
gc->currentContextTag = -1;
- return GL_TRUE;
+ return True;
}
+/**
+ * Determine if a context uses direct rendering.
+ *
+ * \param dpy Display where the context was created.
+ * \param contextID ID of the context to be tested.
+ * \param error Out parameter, set to True on error if not NULL
+ *
+ * \returns \c True if the context is direct rendering or not.
+ */
+static Bool
+__glXIsDirect(Display * dpy, GLXContextID contextID, Bool *error)
+{
+ CARD8 opcode;
+ xcb_connection_t *c;
+ xcb_generic_error_t *err;
+ xcb_glx_is_direct_reply_t *reply;
+ Bool is_direct;
+
+ opcode = __glXSetupForCommand(dpy);
+ if (!opcode) {
+ return False;
+ }
+
+ c = XGetXCBConnection(dpy);
+ reply = xcb_glx_is_direct_reply(c, xcb_glx_is_direct(c, contextID), &err);
+ is_direct = (reply != NULL && reply->is_direct) ? True : False;
+
+ if (err != NULL) {
+ if (error)
+ *error = True;
+ __glXSendErrorForXcb(dpy, err);
+ free(err);
+ }
+
+ free(reply);
+
+ return is_direct;
+}
/**
* Create a new context.
return NULL;
gc = NULL;
+#ifdef GLX_USE_APPLEGL
+ gc = applegl_create_context(psc, config, shareList, renderType);
+#else
if (allowDirect && psc->vtable->create_context)
gc = psc->vtable->create_context(psc, config, shareList, renderType);
if (!gc)
gc = indirect_create_context(psc, config, shareList, renderType);
+#endif
if (!gc)
return NULL;
UnlockDisplay(dpy);
SyncHandle();
+ gc->share_xid = shareList ? shareList->xid : None;
gc->imported = GL_FALSE;
- gc->renderType = renderType;
+
+ /* Unlike most X resource creation requests, we're about to return a handle
+ * with client-side state, not just an XID. To simplify error handling
+ * elsewhere in libGL, force a round-trip here to ensure the CreateContext
+ * request above succeeded.
+ */
+ {
+ Bool error = False;
+ int isDirect = __glXIsDirect(dpy, gc->xid, &error);
+
+ if (error != False || isDirect != gc->isDirect) {
+ gc->vtable->destroy(gc);
+ gc = NULL;
+ }
+ }
return (GLXContext) gc;
}
-_X_EXPORT GLXContext
+_GLX_PUBLIC GLXContext
glXCreateContext(Display * dpy, XVisualInfo * vis,
GLXContext shareList, Bool allowDirect)
{
struct glx_config *config = NULL;
- int renderType = 0;
+ int renderType = GLX_RGBA_TYPE;
#if defined(GLX_DIRECT_RENDERING) || defined(GLX_USE_APPLEGL)
struct glx_screen *const psc = GetGLXScreenConfigs(dpy, vis->screen);
- config = glx_config_find_visual(psc->visuals, vis->visualid);
+ if (psc)
+ config = glx_config_find_visual(psc->visuals, vis->visualid);
+
if (config == NULL) {
- xError error;
-
- error.errorCode = BadValue;
- error.resourceID = vis->visualid;
- error.sequenceNumber = dpy->request;
- error.type = X_Error;
- error.majorCode = __glXSetupForCommand(dpy);
- error.minorCode = X_GLXCreateContext;
- _XError(dpy, &error);
+ __glXSendError(dpy, BadValue, vis->visualid, X_GLXCreateContext, True);
return None;
}
- renderType = config->rgbMode ? GLX_RGBA_TYPE : GLX_COLOR_INDEX_TYPE;
+ /* Choose the context render type based on DRI config values. It is
+ * unusual to set this type from config, but we have no other choice, as
+ * this old API does not provide renderType parameter.
+ */
+ if (config->renderType & GLX_RGBA_FLOAT_BIT_ARB) {
+ renderType = GLX_RGBA_FLOAT_TYPE_ARB;
+ } else if (config->renderType & GLX_RGBA_UNSIGNED_FLOAT_BIT_EXT) {
+ renderType = GLX_RGBA_UNSIGNED_FLOAT_TYPE_EXT;
+ } else if (config->renderType & GLX_RGBA_BIT) {
+ renderType = GLX_RGBA_TYPE;
+ } else if (config->renderType & GLX_COLOR_INDEX_BIT) {
+ renderType = GLX_COLOR_INDEX_TYPE;
+ } else if (config->rgbMode) {
+ /* If we're here, then renderType is not set correctly. Let's use a
+ * safeguard - any TrueColor or DirectColor mode is RGB mode. Such
+ * default value is needed by old DRI drivers, which didn't set
+ * renderType correctly as the value was just ignored.
+ */
+ renderType = GLX_RGBA_TYPE;
+ } else {
+ /* Safeguard - only one option left, all non-RGB modes are indexed
+ * modes. Again, this allows drivers with invalid renderType to work
+ * properly.
+ */
+ renderType = GLX_COLOR_INDEX_TYPE;
+ }
#endif
return CreateContext(dpy, vis->visualid, config, shareList, allowDirect,
X_GLXCreateContext, renderType, vis->screen);
}
-_X_HIDDEN void
+static void
glx_send_destroy_context(Display *dpy, XID xid)
{
CARD8 opcode = __glXSetupForCommand(dpy);
/*
** Destroy the named context
*/
-static void
-DestroyContext(Display * dpy, GLXContext ctx)
+
+_GLX_PUBLIC void
+glXDestroyContext(Display * dpy, GLXContext ctx)
{
struct glx_context *gc = (struct glx_context *) ctx;
- if (!gc)
+ if (gc == NULL || gc->xid == None)
return;
__glXLock();
+ if (!gc->imported)
+ glx_send_destroy_context(dpy, gc->xid);
+
if (gc->currentDpy) {
/* This context is bound to some thread. According to the man page,
* we should not actually delete the context until it's unbound.
* Note that we set gc->xid = None above. In MakeContextCurrent()
* we check for that and delete the context there.
*/
- if (!gc->imported)
- glx_send_destroy_context(dpy, gc->xid);
gc->xid = None;
- __glXUnlock();
- return;
+ } else {
+ gc->vtable->destroy(gc);
}
__glXUnlock();
-
- if (gc->vtable->destroy)
- gc->vtable->destroy(gc);
-}
-
-_X_EXPORT void
-glXDestroyContext(Display * dpy, GLXContext gc)
-{
- DestroyContext(dpy, gc);
}
/*
** Return the major and minor version #s for the GLX extension
*/
-_X_EXPORT Bool
+_GLX_PUBLIC Bool
glXQueryVersion(Display * dpy, int *major, int *minor)
{
struct glx_display *priv;
/* Init the extension. This fetches the major and minor version. */
priv = __glXInitialize(dpy);
if (!priv)
- return GL_FALSE;
+ return False;
if (major)
*major = priv->majorVersion;
if (minor)
*minor = priv->minorVersion;
- return GL_TRUE;
+ return True;
}
/*
-** Query the existance of the GLX extension
+** Query the existence of the GLX extension
*/
-_X_EXPORT Bool
+_GLX_PUBLIC Bool
glXQueryExtension(Display * dpy, int *errorBase, int *eventBase)
{
int major_op, erb, evb;
** Put a barrier in the token stream that forces the GL to finish its
** work before X can proceed.
*/
-_X_EXPORT void
+_GLX_PUBLIC void
glXWaitGL(void)
{
struct glx_context *gc = __glXGetCurrentContext();
- if (gc && gc->vtable->wait_gl)
+ if (gc->vtable->wait_gl)
gc->vtable->wait_gl(gc);
}
** Put a barrier in the token stream that forces X to finish its
** work before GL can proceed.
*/
-_X_EXPORT void
+_GLX_PUBLIC void
glXWaitX(void)
{
struct glx_context *gc = __glXGetCurrentContext();
- if (gc && gc->vtable->wait_x)
+ if (gc->vtable->wait_x)
gc->vtable->wait_x(gc);
}
-_X_EXPORT void
+_GLX_PUBLIC void
glXUseXFont(Font font, int first, int count, int listBase)
{
struct glx_context *gc = __glXGetCurrentContext();
- if (gc && gc->vtable->use_x_font)
+ if (gc->vtable->use_x_font)
gc->vtable->use_x_font(gc, font, first, count, listBase);
}
** Copy the source context to the destination context using the
** attribute "mask".
*/
-_X_EXPORT void
+_GLX_PUBLIC void
glXCopyContext(Display * dpy, GLXContext source_user,
GLXContext dest_user, unsigned long mask)
{
}
-/**
- * Determine if a context uses direct rendering.
- *
- * \param dpy Display where the context was created.
- * \param contextID ID of the context to be tested.
- *
- * \returns \c GL_TRUE if the context is direct rendering or not.
- */
-static Bool
-__glXIsDirect(Display * dpy, GLXContextID contextID)
-{
-#if !defined(USE_XCB)
- xGLXIsDirectReq *req;
- xGLXIsDirectReply reply;
-#endif
- CARD8 opcode;
-
- opcode = __glXSetupForCommand(dpy);
- if (!opcode) {
- return GL_FALSE;
- }
-
-#ifdef USE_XCB
- xcb_connection_t *c = XGetXCBConnection(dpy);
- xcb_glx_is_direct_reply_t *reply = xcb_glx_is_direct_reply(c,
- xcb_glx_is_direct
- (c, contextID),
- NULL);
-
- const Bool is_direct = reply->is_direct ? True : False;
- free(reply);
-
- return is_direct;
-#else
- /* Send the glXIsDirect request */
- LockDisplay(dpy);
- GetReq(GLXIsDirect, req);
- req->reqType = opcode;
- req->glxCode = X_GLXIsDirect;
- req->context = contextID;
- _XReply(dpy, (xReply *) & reply, 0, False);
- UnlockDisplay(dpy);
- SyncHandle();
-
- return reply.isDirect;
-#endif /* USE_XCB */
-}
-
/**
* \todo
- * Shouldn't this function \b always return \c GL_FALSE when
+ * Shouldn't this function \b always return \c False when
* \c GLX_DIRECT_RENDERING is not defined? Do we really need to bother with
* the GLX protocol here at all?
*/
-_X_EXPORT Bool
+_GLX_PUBLIC Bool
glXIsDirect(Display * dpy, GLXContext gc_user)
{
struct glx_context *gc = (struct glx_context *) gc_user;
if (!gc) {
- return GL_FALSE;
+ return False;
}
else if (gc->isDirect) {
- return GL_TRUE;
+ return True;
}
#ifdef GLX_USE_APPLEGL /* TODO: indirect on darwin */
- return GL_FALSE;
+ return False;
#else
- return __glXIsDirect(dpy, gc->xid);
+ return __glXIsDirect(dpy, gc->xid, NULL);
#endif
}
-_X_EXPORT GLXPixmap
+_GLX_PUBLIC GLXPixmap
glXCreateGLXPixmap(Display * dpy, XVisualInfo * vis, Pixmap pixmap)
{
#ifdef GLX_USE_APPLEGL
struct glx_screen *const psc = GetGLXScreenConfigs(dpy, screen);
const struct glx_config *config;
- config = _gl_context_modes_find_visual(psc->visuals, vis->visualid);
+ config = glx_config_find_visual(psc->visuals, vis->visualid);
if(apple_glx_pixmap_create(dpy, vis->screen, pixmap, config))
return None;
return pixmap;
#else
xGLXCreateGLXPixmapReq *req;
+ struct glx_drawable *glxDraw;
GLXPixmap xid;
CARD8 opcode;
+#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
+ struct glx_display *const priv = __glXInitialize(dpy);
+
+ if (priv == NULL)
+ return None;
+#endif
+
opcode = __glXSetupForCommand(dpy);
if (!opcode) {
return None;
}
+ glxDraw = malloc(sizeof(*glxDraw));
+ if (!glxDraw)
+ return None;
+
/* Send the glXCreateGLXPixmap request */
LockDisplay(dpy);
GetReq(GLXCreateGLXPixmap, req);
UnlockDisplay(dpy);
SyncHandle();
+ if (InitGLXDrawable(dpy, glxDraw, pixmap, req->glxpixmap)) {
+ free(glxDraw);
+ return None;
+ }
+
#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
do {
/* FIXME: Maybe delay __DRIdrawable creation until the drawable
* is actually bound to a context... */
- struct glx_display *const priv = __glXInitialize(dpy);
__GLXDRIdrawable *pdraw;
struct glx_screen *psc;
struct glx_config *config;
psc = priv->screens[vis->screen];
if (psc->driScreen == NULL)
- break;
+ return xid;
+
config = glx_config_find_visual(psc->visuals, vis->visualid);
- pdraw = psc->driScreen->createDrawable(psc, pixmap, req->glxpixmap, config);
+ pdraw = psc->driScreen->createDrawable(psc, pixmap, xid, config);
if (pdraw == NULL) {
fprintf(stderr, "failed to create pixmap\n");
+ xid = None;
break;
}
- if (__glxHashInsert(priv->drawHash, req->glxpixmap, pdraw)) {
+ if (__glxHashInsert(priv->drawHash, xid, pdraw)) {
(*pdraw->destroyDrawable) (pdraw);
- return None; /* FIXME: Check what we're supposed to do here... */
+ xid = None;
+ break;
}
} while (0);
+
+ if (xid == None) {
+ xGLXDestroyGLXPixmapReq *dreq;
+ LockDisplay(dpy);
+ GetReq(GLXDestroyGLXPixmap, dreq);
+ dreq->reqType = opcode;
+ dreq->glxCode = X_GLXDestroyGLXPixmap;
+ dreq->glxpixmap = xid;
+ UnlockDisplay(dpy);
+ SyncHandle();
+ }
#endif
return xid;
/*
** Destroy the named pixmap
*/
-_X_EXPORT void
+_GLX_PUBLIC void
glXDestroyGLXPixmap(Display * dpy, GLXPixmap glxpixmap)
{
#ifdef GLX_USE_APPLEGL
UnlockDisplay(dpy);
SyncHandle();
+ DestroyGLXDrawable(dpy, glxpixmap);
+
#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
{
struct glx_display *const priv = __glXInitialize(dpy);
__GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, glxpixmap);
- if (pdraw != NULL) {
+ if (priv != NULL && pdraw != NULL) {
(*pdraw->destroyDrawable) (pdraw);
__glxHashDelete(priv->drawHash, glxpixmap);
}
#endif /* GLX_USE_APPLEGL */
}
-_X_EXPORT void
+_GLX_PUBLIC void
glXSwapBuffers(Display * dpy, GLXDrawable drawable)
{
#ifdef GLX_USE_APPLEGL
- GLXContext gc = glXGetCurrentContext();
- if(gc && apple_glx_is_current_drawable(dpy, gc->driContext, drawable)) {
+ struct glx_context * gc = __glXGetCurrentContext();
+ if(gc != &dummyContext && apple_glx_is_current_drawable(dpy, gc->driContext, drawable)) {
apple_glx_swap_buffers(gc->driContext);
} else {
__glXSendError(dpy, GLXBadCurrentWindow, 0, X_GLXSwapBuffers, false);
struct glx_context *gc;
GLXContextTag tag;
CARD8 opcode;
-#ifdef USE_XCB
xcb_connection_t *c;
-#else
- xGLXSwapBuffersReq *req;
-#endif
gc = __glXGetCurrentContext();
#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
- __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable);
+ {
+ __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable);
- if (pdraw != NULL) {
- if (gc && drawable == gc->currentDrawable) {
- glFlush();
- }
+ if (pdraw != NULL) {
+ Bool flush = gc != &dummyContext && drawable == gc->currentDrawable;
- (*pdraw->psc->driScreen->swapBuffers)(pdraw, 0, 0, 0);
- return;
+ (*pdraw->psc->driScreen->swapBuffers)(pdraw, 0, 0, 0, flush);
+ return;
+ }
}
#endif
** The calling thread may or may not have a current context. If it
** does, send the context tag so the server can do a flush.
*/
- if ((gc != NULL) && (dpy == gc->currentDpy) &&
+ if ((gc != &dummyContext) && (dpy == gc->currentDpy) &&
((drawable == gc->currentDrawable)
|| (drawable == gc->currentReadable))) {
tag = gc->currentContextTag;
tag = 0;
}
-#ifdef USE_XCB
c = XGetXCBConnection(dpy);
xcb_glx_swap_buffers(c, tag, drawable);
xcb_flush(c);
-#else
- /* Send the glXSwapBuffers request */
- LockDisplay(dpy);
- GetReq(GLXSwapBuffers, req);
- req->reqType = opcode;
- req->glxCode = X_GLXSwapBuffers;
- req->drawable = drawable;
- req->contextTag = tag;
- UnlockDisplay(dpy);
- SyncHandle();
- XFlush(dpy);
-#endif /* USE_XCB */
#endif /* GLX_USE_APPLEGL */
}
** Return configuration information for the given display, screen and
** visual combination.
*/
-_X_EXPORT int
+_GLX_PUBLIC int
glXGetConfig(Display * dpy, XVisualInfo * vis, int attribute,
int *value_return)
{
** supported by the OpenGL implementation on the server.
*/
if ((status == GLX_BAD_VISUAL) && (attribute == GLX_USE_GL)) {
- *value_return = GL_FALSE;
+ *value_return = False;
status = Success;
}
config->visualID = (XID) GLX_DONT_CARE;
config->visualType = GLX_DONT_CARE;
- /* glXChooseFBConfig specifies different defaults for these two than
+ /* glXChooseFBConfig specifies different defaults for these properties than
* glXChooseVisual.
*/
if (fbconfig_style_tags) {
config->rgbMode = GL_TRUE;
config->doubleBufferMode = GLX_DONT_CARE;
+ config->renderType = GLX_RGBA_BIT;
}
+ config->drawableType = GLX_WINDOW_BIT;
config->visualRating = GLX_DONT_CARE;
config->transparentPixel = GLX_NONE;
config->transparentRed = GLX_DONT_CARE;
config->transparentAlpha = GLX_DONT_CARE;
config->transparentIndex = GLX_DONT_CARE;
- config->drawableType = GLX_WINDOW_BIT;
- config->renderType =
- (config->rgbMode) ? GLX_RGBA_BIT : GLX_COLOR_INDEX_BIT;
config->xRenderable = GLX_DONT_CARE;
config->fbconfigID = (GLXFBConfigID) (GLX_DONT_CARE);
config->swapMethod = GLX_DONT_CARE;
+ config->sRGBCapable = GLX_DONT_CARE;
}
#define MATCH_DONT_CARE( param ) \
/* Test that all bits from a are contained in b */
#define MATCH_MASK(param) \
do { \
- if ((a->param & ~b->param) != 0) \
+ if ( ((int) a-> param != (int) GLX_DONT_CARE) \
+ && ((a->param & ~b->param) != 0) ) { \
return False; \
+ } \
} while (0);
/**
MATCH_MASK(drawableType);
MATCH_MASK(renderType);
+ MATCH_DONT_CARE(sRGBCapable);
/* There is a bug in a few of the XFree86 DDX drivers. They contain
* visuals with a "transparent type" of 0 when they really mean GLX_NONE.
fbconfig_compare(struct glx_config **a, struct glx_config **b)
{
/* The order of these comparisons must NOT change. It is defined by
- * the GLX 1.3 spec and ARB_multisample.
+ * the GLX 1.4 specification.
*/
PREFER_SMALLER(visualSelectGroup);
PREFER_SMALLER(numAuxBuffers);
+ PREFER_SMALLER(sampleBuffers);
+ PREFER_SMALLER(samples);
+
PREFER_LARGER_OR_ZERO(depthBits);
PREFER_SMALLER(stencilBits);
PREFER_SMALLER(visualType);
- /* None of the multisample specs say where this comparison should happen,
- * so I put it near the end.
- */
- PREFER_SMALLER(sampleBuffers);
- PREFER_SMALLER(samples);
-
/* None of the pbuffer or fbconfig specs say that this comparison needs
* to happen at all, but it seems like it should.
*/
/**
* Selects and sorts a subset of the supplied configs based on the attributes.
- * This function forms to basis of \c glXChooseVisual, \c glXChooseFBConfig,
- * and \c glXChooseFBConfigSGIX.
+ * This function forms to basis of \c glXChooseFBConfig and
+ * \c glXChooseFBConfigSGIX.
*
* \param configs Array of pointers to possible configs. The elements of
* this array that do not meet the criteria will be set to
* the various visual / FBConfig selection rules.
* \param num_configs Number of elements in the \c configs array.
* \param attribList Attributes used select from \c configs. This array is
- * terminated by a \c None tag. The array can either take
- * the form expected by \c glXChooseVisual (where boolean
- * tags do not have a value) or by \c glXChooseFBConfig
- * (where every tag has a value).
- * \param fbconfig_style_tags Selects whether \c attribList is in
- * \c glXChooseVisual style or
- * \c glXChooseFBConfig style.
+ * terminated by a \c None tag. The array is of the form
+ * expected by \c glXChooseFBConfig (where every tag has a
+ * value).
* \returns The number of valid elements left in \c configs.
*
- * \sa glXChooseVisual, glXChooseFBConfig, glXChooseFBConfigSGIX
+ * \sa glXChooseFBConfig, glXChooseFBConfigSGIX
*/
static int
-choose_visual(struct glx_config ** configs, int num_configs,
- const int *attribList, GLboolean fbconfig_style_tags)
+choose_fbconfig(struct glx_config ** configs, int num_configs,
+ const int *attribList)
{
struct glx_config test_config;
int base;
* list.
*/
- init_fbconfig_for_chooser(&test_config, fbconfig_style_tags);
+ init_fbconfig_for_chooser(&test_config, GL_TRUE);
__glXInitializeVisualConfigFromTags(&test_config, 512,
(const INT32 *) attribList,
- GL_TRUE, fbconfig_style_tags);
+ GL_TRUE, GL_TRUE);
base = 0;
for (i = 0; i < num_configs; i++) {
** Return the visual that best matches the template. Return None if no
** visual matches the template.
*/
-_X_EXPORT XVisualInfo *
+_GLX_PUBLIC XVisualInfo *
glXChooseVisual(Display * dpy, int screen, int *attribList)
{
XVisualInfo *visualList = NULL;
&visualTemplate, &i);
if (newList) {
- Xfree(visualList);
+ free(visualList);
visualList = newList;
best_config = config;
}
}
#ifdef GLX_USE_APPLEGL
- if(visualList && getenv("LIBGL_DUMP_VISUALID")) {
+ if(visualList && env_var_as_boolean("LIBGL_DUMP_VISUALID", false)) {
printf("visualid 0x%lx\n", visualList[0].visualid);
}
#endif
}
-_X_EXPORT const char *
+_GLX_PUBLIC const char *
glXQueryExtensionsString(Display * dpy, int screen)
{
struct glx_screen *psc;
return psc->effectiveGLXexts;
}
-_X_EXPORT const char *
+_GLX_PUBLIC const char *
glXGetClientString(Display * dpy, int name)
{
(void) dpy;
}
}
-_X_EXPORT const char *
+_GLX_PUBLIC const char *
glXQueryServerString(Display * dpy, int screen, int name)
{
struct glx_screen *psc;
return *str;
}
-void
-__glXClientInfo(Display * dpy, int opcode)
-{
- char *ext_str = __glXGetClientGLExtensionString();
- int size = strlen(ext_str) + 1;
-
-#ifdef USE_XCB
- xcb_connection_t *c = XGetXCBConnection(dpy);
- xcb_glx_client_info(c,
- GLX_MAJOR_VERSION, GLX_MINOR_VERSION, size, ext_str);
-#else
- xGLXClientInfoReq *req;
-
- /* Send the glXClientInfo request */
- LockDisplay(dpy);
- GetReq(GLXClientInfo, req);
- req->reqType = opcode;
- req->glxCode = X_GLXClientInfo;
- req->major = GLX_MAJOR_VERSION;
- req->minor = GLX_MINOR_VERSION;
-
- req->length += (size + 3) >> 2;
- req->numbytes = size;
- Data(dpy, ext_str, size);
-
- UnlockDisplay(dpy);
- SyncHandle();
-#endif /* USE_XCB */
-
- Xfree(ext_str);
-}
-
/*
** EXT_import_context
*/
-_X_EXPORT Display *
+_GLX_PUBLIC Display *
glXGetCurrentDisplay(void)
{
struct glx_context *gc = __glXGetCurrentContext();
- if (NULL == gc)
+ if (gc == &dummyContext)
return NULL;
return gc->currentDpy;
}
-_X_EXPORT
+_GLX_PUBLIC
GLX_ALIAS(Display *, glXGetCurrentDisplayEXT, (void), (),
glXGetCurrentDisplay)
#ifndef GLX_USE_APPLEGL
-_X_EXPORT GLXContext
+_GLX_PUBLIC GLXContext
glXImportContextEXT(Display *dpy, GLXContextID contextID)
{
struct glx_display *priv = __glXInitialize(dpy);
- struct glx_screen *psc;
+ struct glx_screen *psc = NULL;
xGLXQueryContextReply reply;
CARD8 opcode;
struct glx_context *ctx;
- int propList[__GLX_MAX_CONTEXT_PROPS * 2], *pProp, nPropListBytes;
- int i, renderType;
- XID share;
- struct glx_config *mode;
+ int i, renderType = GLX_RGBA_TYPE; /* By default, assume RGBA context */
+ XID share = None;
+ struct glx_config *mode = NULL;
+ uint32_t fbconfigID = 0;
+ uint32_t visualID = 0;
+ uint32_t screen = 0;
+ Bool got_screen = False;
+
+ if (priv == NULL)
+ return NULL;
+
+ /* The GLX_EXT_import_context spec says:
+ *
+ * "If <contextID> does not refer to a valid context, then a BadContext
+ * error is generated; if <contextID> refers to direct rendering
+ * context then no error is generated but glXImportContextEXT returns
+ * NULL."
+ *
+ * If contextID is None, generate BadContext on the client-side. Other
+ * sorts of invalid contexts will be detected by the server in the
+ * __glXIsDirect call.
+ */
+ if (contextID == None) {
+ __glXSendError(dpy, GLXBadContext, contextID, X_GLXIsDirect, false);
+ return NULL;
+ }
- if (contextID == None || __glXIsDirect(dpy, contextID))
+ if (__glXIsDirect(dpy, contextID, NULL))
return NULL;
opcode = __glXSetupForCommand(dpy);
req->context = contextID;
}
- _XReply(dpy, (xReply *) & reply, 0, False);
-
- if (reply.n <= __GLX_MAX_CONTEXT_PROPS)
- nPropListBytes = reply.n * 2 * sizeof propList[0];
- else
- nPropListBytes = 0;
- _XRead(dpy, (char *) propList, nPropListBytes);
+ if (_XReply(dpy, (xReply *) & reply, 0, False) &&
+ reply.n < (INT32_MAX / 2)) {
+
+ for (i = 0; i < reply.n; i++) {
+ int prop[2];
+
+ _XRead(dpy, (char *)prop, sizeof(prop));
+ switch (prop[0]) {
+ case GLX_SCREEN:
+ screen = prop[1];
+ got_screen = True;
+ break;
+ case GLX_SHARE_CONTEXT_EXT:
+ share = prop[1];
+ break;
+ case GLX_VISUAL_ID_EXT:
+ visualID = prop[1];
+ break;
+ case GLX_FBCONFIG_ID:
+ fbconfigID = prop[1];
+ break;
+ case GLX_RENDER_TYPE:
+ renderType = prop[1];
+ break;
+ }
+ }
+ }
UnlockDisplay(dpy);
SyncHandle();
- /* Look up screen first so we can look up visuals/fbconfigs later */
- psc = NULL;
- for (i = 0, pProp = propList; i < reply.n; i++, pProp += 2)
- if (pProp[0] == GLX_SCREEN)
- psc = GetGLXScreenConfigs(dpy, pProp[1]);
- if (psc == NULL)
+ if (!got_screen)
return NULL;
- share = None;
- mode = NULL;
- renderType = 0;
- pProp = propList;
+ psc = GetGLXScreenConfigs(dpy, screen);
+ if (psc == NULL)
+ return NULL;
- for (i = 0, pProp = propList; i < reply.n; i++, pProp += 2)
- switch (pProp[0]) {
- case GLX_SHARE_CONTEXT_EXT:
- share = pProp[1];
- break;
- case GLX_VISUAL_ID_EXT:
- mode = glx_config_find_visual(psc->visuals, pProp[1]);
- break;
- case GLX_FBCONFIG_ID:
- mode = glx_config_find_fbconfig(psc->configs, pProp[1]);
- break;
- case GLX_RENDER_TYPE:
- renderType = pProp[1];
- break;
- }
+ if (fbconfigID != 0) {
+ mode = glx_config_find_fbconfig(psc->configs, fbconfigID);
+ } else if (visualID != 0) {
+ mode = glx_config_find_visual(psc->visuals, visualID);
+ }
if (mode == NULL)
return NULL;
#endif
-_X_EXPORT int
+_GLX_PUBLIC int
glXQueryContext(Display * dpy, GLXContext ctx_user, int attribute, int *value)
{
struct glx_context *ctx = (struct glx_context *) ctx_user;
return Success;
}
-_X_EXPORT
+_GLX_PUBLIC
GLX_ALIAS(int, glXQueryContextInfoEXT,
(Display * dpy, GLXContext ctx, int attribute, int *value),
(dpy, ctx, attribute, value), glXQueryContext)
-_X_EXPORT GLXContextID glXGetContextIDEXT(const GLXContext ctx_user)
+_GLX_PUBLIC GLXContextID glXGetContextIDEXT(const GLXContext ctx_user)
{
struct glx_context *ctx = (struct glx_context *) ctx_user;
- return ctx->xid;
+ return (ctx == NULL) ? None : ctx->xid;
}
-_X_EXPORT void
-glXFreeContextEXT(Display * dpy, GLXContext ctx)
+_GLX_PUBLIC void
+glXFreeContextEXT(Display *dpy, GLXContext ctx)
{
- DestroyContext(dpy, ctx);
-}
+ struct glx_context *gc = (struct glx_context *) ctx;
+ if (gc == NULL || gc->xid == None)
+ return;
-_X_EXPORT GLXFBConfig *
+ /* The GLX_EXT_import_context spec says:
+ *
+ * "glXFreeContext does not free the server-side context information or
+ * the XID associated with the server-side context."
+ *
+ * Don't send any protocol. Just destroy the client-side tracking of the
+ * context. Also, only release the context structure if it's not current.
+ */
+ __glXLock();
+ if (gc->currentDpy) {
+ gc->xid = None;
+ } else {
+ gc->vtable->destroy(gc);
+ }
+ __glXUnlock();
+}
+
+_GLX_PUBLIC GLXFBConfig *
glXChooseFBConfig(Display * dpy, int screen,
const int *attribList, int *nitems)
{
glXGetFBConfigs(dpy, screen, &list_size);
if ((config_list != NULL) && (list_size > 0) && (attribList != NULL)) {
- list_size = choose_visual(config_list, list_size, attribList, GL_TRUE);
+ list_size = choose_fbconfig(config_list, list_size, attribList);
if (list_size == 0) {
- XFree(config_list);
+ free(config_list);
config_list = NULL;
}
}
}
-_X_EXPORT GLXContext
+_GLX_PUBLIC GLXContext
glXCreateNewContext(Display * dpy, GLXFBConfig fbconfig,
int renderType, GLXContext shareList, Bool allowDirect)
{
struct glx_config *config = (struct glx_config *) fbconfig;
+ struct glx_config **config_list;
+ int list_size;
+ unsigned i;
+
+ if (!config) {
+ __glXSendError(dpy, GLXBadFBConfig, 0, X_GLXCreateNewContext, false);
+ return NULL;
+ }
+
+ config_list = (struct glx_config **)
+ glXGetFBConfigs(dpy, config->screen, &list_size);
+
+ for (i = 0; i < list_size; i++) {
+ if (config_list[i] == config)
+ break;
+ }
+ free(config_list);
+
+ if (i == list_size) {
+ __glXSendError(dpy, GLXBadFBConfig, 0, X_GLXCreateNewContext, false);
+ return NULL;
+ }
return CreateContext(dpy, config->fbconfigID, config, shareList,
allowDirect, X_GLXCreateNewContext, renderType,
}
-_X_EXPORT GLXDrawable
+_GLX_PUBLIC GLXDrawable
glXGetCurrentReadDrawable(void)
{
struct glx_context *gc = __glXGetCurrentContext();
}
-_X_EXPORT GLXFBConfig *
+_GLX_PUBLIC GLXFBConfig *
glXGetFBConfigs(Display * dpy, int screen, int *nelements)
{
struct glx_display *priv = __glXInitialize(dpy);
*nelements = 0;
if (priv && (priv->screens != NULL)
- && (screen >= 0) && (screen <= ScreenCount(dpy))
+ && (screen >= 0) && (screen < ScreenCount(dpy))
&& (priv->screens[screen]->configs != NULL)
&& (priv->screens[screen]->configs->fbconfigID
!= (int) GLX_DONT_CARE)) {
}
}
- config_list = Xmalloc(num_configs * sizeof *config_list);
+ config_list = malloc(num_configs * sizeof *config_list);
if (config_list != NULL) {
*nelements = num_configs;
i = 0;
}
-_X_EXPORT int
+_GLX_PUBLIC int
glXGetFBConfigAttrib(Display * dpy, GLXFBConfig fbconfig,
int attribute, int *value)
{
}
-_X_EXPORT XVisualInfo *
+_GLX_PUBLIC XVisualInfo *
glXGetVisualFromFBConfig(Display * dpy, GLXFBConfig fbconfig)
{
XVisualInfo visualTemplate;
CARD32 *interval_ptr;
CARD8 opcode;
- if (gc == NULL) {
+ if (gc == &dummyContext) {
return GLX_BAD_CONTEXT;
}
psc = GetGLXScreenConfigs( gc->currentDpy, gc->screen);
#ifdef GLX_DIRECT_RENDERING
- if (gc->isDirect && psc->driScreen && psc->driScreen->setSwapInterval) {
+ if (gc->isDirect && psc && psc->driScreen &&
+ psc->driScreen->setSwapInterval) {
__GLXDRIdrawable *pdraw =
GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable);
- psc->driScreen->setSwapInterval(pdraw, interval);
+ /* Simply ignore the command if the GLX drawable has been destroyed but
+ * the context is still bound.
+ */
+ if (pdraw)
+ psc->driScreen->setSwapInterval(pdraw, interval);
return 0;
}
#endif
#ifdef GLX_DIRECT_RENDERING
struct glx_context *gc = __glXGetCurrentContext();
- if (gc != NULL && gc->isDirect) {
+ if (gc != &dummyContext && gc->isDirect) {
struct glx_screen *psc;
psc = GetGLXScreenConfigs( gc->currentDpy, gc->screen);
- if (psc->driScreen && psc->driScreen->setSwapInterval) {
+ if (psc && psc->driScreen && psc->driScreen->setSwapInterval) {
__GLXDRIdrawable *pdraw =
GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable);
- return psc->driScreen->setSwapInterval(pdraw, interval);
+
+ /* Simply ignore the command if the GLX drawable has been destroyed but
+ * the context is still bound.
+ */
+ if (!pdraw)
+ return 0;
+
+ return psc->driScreen->setSwapInterval(pdraw, interval);
}
}
#endif
#ifdef GLX_DIRECT_RENDERING
struct glx_context *gc = __glXGetCurrentContext();
- if (gc != NULL && gc->isDirect) {
+ if (gc != &dummyContext && gc->isDirect) {
struct glx_screen *psc;
psc = GetGLXScreenConfigs( gc->currentDpy, gc->screen);
- if (psc->driScreen && psc->driScreen->getSwapInterval) {
+ if (psc && psc->driScreen && psc->driScreen->getSwapInterval) {
__GLXDRIdrawable *pdraw =
GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable);
- return psc->driScreen->getSwapInterval(pdraw);
+ if (pdraw)
+ return psc->driScreen->getSwapInterval(pdraw);
}
}
#endif
__GLXDRIdrawable *pdraw;
#endif
- if (!gc)
+ if (gc == &dummyContext)
return GLX_BAD_CONTEXT;
#ifdef GLX_DIRECT_RENDERING
* FIXME: documentation for the GLX encoding.
*/
#ifdef GLX_DIRECT_RENDERING
- if (psc->driScreen && psc->driScreen->getDrawableMSC) {
+ if (psc && psc->driScreen && psc->driScreen->getDrawableMSC) {
ret = psc->driScreen->getDrawableMSC(psc, pdraw, &ust, &msc, &sbc);
*count = (unsigned) msc;
return (ret == True) ? 0 : GLX_BAD_CONTEXT;
if (divisor <= 0 || remainder < 0)
return GLX_BAD_VALUE;
- if (!gc)
+ if (gc == &dummyContext)
return GLX_BAD_CONTEXT;
#ifdef GLX_DIRECT_RENDERING
#endif
#ifdef GLX_DIRECT_RENDERING
- if (psc->driScreen && psc->driScreen->waitForMSC) {
+ if (psc && psc->driScreen && psc->driScreen->waitForMSC) {
ret = psc->driScreen->waitForMSC(pdraw, 0, divisor, remainder, &ust, &msc,
&sbc);
*count = (unsigned) msc;
** GLX_functions table.
*/
-_X_EXPORT
+_GLX_PUBLIC
GLX_ALIAS(int, glXGetFBConfigAttribSGIX,
(Display * dpy, GLXFBConfigSGIX config, int attribute, int *value),
(dpy, config, attribute, value), glXGetFBConfigAttrib)
-_X_EXPORT GLX_ALIAS(GLXFBConfigSGIX *, glXChooseFBConfigSGIX,
+_GLX_PUBLIC GLX_ALIAS(GLXFBConfigSGIX *, glXChooseFBConfigSGIX,
(Display * dpy, int screen, int *attrib_list,
int *nelements), (dpy, screen, attrib_list, nelements),
glXChooseFBConfig)
-_X_EXPORT GLX_ALIAS(XVisualInfo *, glXGetVisualFromFBConfigSGIX,
+_GLX_PUBLIC GLX_ALIAS(XVisualInfo *, glXGetVisualFromFBConfigSGIX,
(Display * dpy, GLXFBConfigSGIX config),
(dpy, config), glXGetVisualFromFBConfig)
-_X_EXPORT GLXPixmap
+_GLX_PUBLIC GLXPixmap
glXCreateGLXPixmapWithConfigSGIX(Display * dpy,
GLXFBConfigSGIX fbconfig,
Pixmap pixmap)
#endif
}
-_X_EXPORT GLXContext
+_GLX_PUBLIC GLXContext
glXCreateContextWithConfigSGIX(Display * dpy,
GLXFBConfigSGIX fbconfig, int renderType,
GLXContext shareList, Bool allowDirect)
}
-_X_EXPORT GLXFBConfigSGIX
+_GLX_PUBLIC GLXFBConfigSGIX
glXGetFBConfigFromVisualSGIX(Display * dpy, XVisualInfo * vis)
{
struct glx_display *priv;
}
#ifndef GLX_USE_APPLEGL
-/*
-** GLX_SGIX_swap_group
-*/
-static void
-__glXJoinSwapGroupSGIX(Display * dpy, GLXDrawable drawable,
- GLXDrawable member)
-{
- (void) dpy;
- (void) drawable;
- (void) member;
-}
-
-
-/*
-** GLX_SGIX_swap_barrier
-*/
-static void
-__glXBindSwapBarrierSGIX(Display * dpy, GLXDrawable drawable, int barrier)
-{
- (void) dpy;
- (void) drawable;
- (void) barrier;
-}
-
-static Bool
-__glXQueryMaxSwapBarriersSGIX(Display * dpy, int screen, int *max)
-{
- (void) dpy;
- (void) screen;
- (void) max;
- return False;
-}
-
-
/*
** GLX_OML_sync_control
*/
#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
_X_HIDDEN GLboolean
-__glxGetMscRate(__GLXDRIdrawable *glxDraw,
+__glxGetMscRate(struct glx_screen *psc,
int32_t * numerator, int32_t * denominator)
{
-#ifdef XF86VIDMODE
- struct glx_screen *psc;
+#if !defined(GLX_USE_WINDOWSGL)
XF86VidModeModeLine mode_line;
int dot_clock;
int i;
- psc = glxDraw->psc;
if (XF86VidModeQueryVersion(psc->dpy, &i, &i) &&
XF86VidModeGetModeLine(psc->dpy, psc->scr, &dot_clock, &mode_line)) {
unsigned n = dot_clock * 1000;
return True;
}
- else
#endif
return False;
__glXGetMscRateOML(Display * dpy, GLXDrawable drawable,
int32_t * numerator, int32_t * denominator)
{
-#if defined( GLX_DIRECT_RENDERING ) && defined( XF86VIDMODE )
+#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) && !defined(GLX_USE_WINDOWSGL)
__GLXDRIdrawable *draw = GetGLXDRIDrawable(dpy, drawable);
if (draw == NULL)
return False;
- return __glxGetMscRate(draw, numerator, denominator);
+ return __glxGetMscRate(draw->psc, numerator, denominator);
#else
(void) dpy;
(void) drawable;
struct glx_screen *psc = pdraw ? pdraw->psc : NULL;
#endif
- if (!gc) /* no GLX for this */
+ if (gc == &dummyContext) /* no GLX for this */
return -1;
#ifdef GLX_DIRECT_RENDERING
#ifdef GLX_DIRECT_RENDERING
if (psc->driScreen && psc->driScreen->swapBuffers)
return (*psc->driScreen->swapBuffers)(pdraw, target_msc, divisor,
- remainder);
+ remainder, False);
#endif
return -1;
}
-_X_EXPORT GLXPixmap
+_GLX_PUBLIC GLXPixmap
glXCreateGLXPixmapMESA(Display * dpy, XVisualInfo * visual,
Pixmap pixmap, Colormap cmap)
{
if (pdraw != NULL) {
struct glx_screen *psc = pdraw->psc;
if (psc->driScreen->copySubBuffer != NULL) {
- glFlush();
- (*psc->driScreen->copySubBuffer) (pdraw, x, y, width, height);
+ (*psc->driScreen->copySubBuffer) (pdraw, x, y, width, height, True);
}
return;
** does, send the context tag so the server can do a flush.
*/
gc = __glXGetCurrentContext();
- if ((gc != NULL) && (dpy == gc->currentDpy) &&
+ if ((gc != &dummyContext) && (dpy == gc->currentDpy) &&
((drawable == gc->currentDrawable) ||
(drawable == gc->currentReadable))) {
tag = gc->currentContextTag;
{
struct glx_context *gc = __glXGetCurrentContext();
- if (gc == NULL || gc->vtable->bind_tex_image == NULL)
+ if (gc->vtable->bind_tex_image == NULL)
return;
gc->vtable->bind_tex_image(dpy, drawable, buffer, attrib_list);
{
struct glx_context *gc = __glXGetCurrentContext();
- if (gc == NULL || gc->vtable->release_tex_image == NULL)
+ if (gc->vtable->release_tex_image == NULL)
return;
gc->vtable->release_tex_image(dpy, drawable, buffer);
#endif /* GLX_USE_APPLEGL */
-/**
- * \c strdup is actually not a standard ANSI C or POSIX routine.
- * Irix will not define it if ANSI mode is in effect.
- *
- * \sa strdup
- */
-_X_HIDDEN char *
-__glXstrdup(const char *str)
-{
- char *copy;
- copy = (char *) Xmalloc(strlen(str) + 1);
- if (!copy)
- return NULL;
- strcpy(copy, str);
- return copy;
-}
-
/*
** glXGetProcAddress support
*/
GLX_FUNCTION(glXSelectEventSGIX),
GLX_FUNCTION(glXGetSelectedEventSGIX),
- /*** GLX_SGIX_swap_group ***/
- GLX_FUNCTION2(glXJoinSwapGroupSGIX, __glXJoinSwapGroupSGIX),
-
- /*** GLX_SGIX_swap_barrier ***/
- GLX_FUNCTION2(glXBindSwapBarrierSGIX, __glXBindSwapBarrierSGIX),
- GLX_FUNCTION2(glXQueryMaxSwapBarriersSGIX, __glXQueryMaxSwapBarriersSGIX),
-
/*** GLX_MESA_copy_sub_buffer ***/
GLX_FUNCTION2(glXCopySubBufferMESA, __glXCopySubBufferMESA),
GLX_FUNCTION2(glXReleaseTexImageEXT, __glXReleaseTexImageEXT),
#endif
-#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
+#if defined(GLX_DIRECT_RENDERING) && defined(GLX_USE_DRM)
/*** DRI configuration ***/
GLX_FUNCTION(glXGetScreenDriver),
GLX_FUNCTION(glXGetDriverConfig),
#endif
+ /*** GLX_ARB_create_context and GLX_ARB_create_context_profile ***/
+ GLX_FUNCTION(glXCreateContextAttribsARB),
+
+ /*** GLX_MESA_query_renderer ***/
+ GLX_FUNCTION(glXQueryRendererIntegerMESA),
+ GLX_FUNCTION(glXQueryRendererStringMESA),
+ GLX_FUNCTION(glXQueryCurrentRendererIntegerMESA),
+ GLX_FUNCTION(glXQueryCurrentRendererStringMESA),
+
{NULL, NULL} /* end of list */
};
-#ifndef GLX_USE_APPLEGL
static const GLvoid *
get_glx_proc_address(const char *funcName)
{
return NULL;
}
-#endif
/**
* Get the address of a named GL function. This is the pre-GLX 1.4 name for
*
* \sa glXGetProcAddress
*/
-_X_EXPORT void (*glXGetProcAddressARB(const GLubyte * procName)) (void)
+_GLX_PUBLIC void (*glXGetProcAddressARB(const GLubyte * procName)) (void)
{
typedef void (*gl_function) (void);
gl_function f;
* DRI based drivers from searching the core GL function table for
* internal API functions.
*/
-#ifdef GLX_USE_APPLEGL
- f = (gl_function) apple_glx_get_proc_address(procName);
-#else
f = (gl_function) get_glx_proc_address((const char *) procName);
if ((f == NULL) && (procName[0] == 'g') && (procName[1] == 'l')
&& (procName[2] != 'X')) {
-#ifdef GLX_SHARED_GLAPI
+#ifdef GLX_INDIRECT_RENDERING
f = (gl_function) __indirect_get_proc_address((const char *) procName);
#endif
if (!f)
f = (gl_function) _glapi_get_proc_address((const char *) procName);
+ if (!f) {
+ struct glx_context *gc = __glXGetCurrentContext();
+
+ if (gc != NULL && gc->vtable->get_proc_address != NULL)
+ f = gc->vtable->get_proc_address((const char *) procName);
+ }
}
-#endif
return f;
}
*
* \sa glXGetProcAddressARB
*/
-_X_EXPORT void (*glXGetProcAddress(const GLubyte * procName)) (void)
-#if defined(__GNUC__) && !defined(GLX_ALIAS_UNSUPPORTED)
- __attribute__ ((alias("glXGetProcAddressARB")));
-#else
-{
- return glXGetProcAddressARB(procName);
-}
-#endif /* __GNUC__ */
-
+_GLX_PUBLIC
+GLX_ALIAS(__GLXextFuncPtr, glXGetProcAddress,
+ (const GLubyte * procName),
+ (procName), glXGetProcAddressARB)
#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
/**
}
}
#endif /* GLX_DIRECT_RENDERING */
+
+#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
+
+PUBLIC int
+MesaGLInteropGLXQueryDeviceInfo(Display *dpy, GLXContext context,
+ struct mesa_glinterop_device_info *out)
+{
+ struct glx_context *gc = (struct glx_context*)context;
+ int ret;
+
+ __glXLock();
+
+ if (!gc || gc->xid == None || !gc->isDirect) {
+ __glXUnlock();
+ return MESA_GLINTEROP_INVALID_CONTEXT;
+ }
+
+ if (!gc->vtable->interop_query_device_info) {
+ __glXUnlock();
+ return MESA_GLINTEROP_UNSUPPORTED;
+ }
+
+ ret = gc->vtable->interop_query_device_info(gc, out);
+ __glXUnlock();
+ return ret;
+}
+
+PUBLIC int
+MesaGLInteropGLXExportObject(Display *dpy, GLXContext context,
+ struct mesa_glinterop_export_in *in,
+ struct mesa_glinterop_export_out *out)
+{
+ struct glx_context *gc = (struct glx_context*)context;
+ int ret;
+
+ __glXLock();
+
+ if (!gc || gc->xid == None || !gc->isDirect) {
+ __glXUnlock();
+ return MESA_GLINTEROP_INVALID_CONTEXT;
+ }
+
+ if (!gc->vtable->interop_export_object) {
+ __glXUnlock();
+ return MESA_GLINTEROP_UNSUPPORTED;
+ }
+
+ ret = gc->vtable->interop_export_object(gc, in, out);
+ __glXUnlock();
+ return ret;
+}
+
+#endif /* defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) */