X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fglx%2Fglxcmds.c;h=3856032ce6841bd52601864c7b4e4418bd8c4dc2;hb=b47839ad8361ef42a0f38c52fe24307b865c5489;hp=012cd79506e2ff8438b7336f1f3d4bb7aafecc12;hpb=3869be74afb184dbdf9d67fda3de3e3ac7e3db6c;p=mesa.git diff --git a/src/glx/glxcmds.c b/src/glx/glxcmds.c index 012cd79506e..3856032ce68 100644 --- a/src/glx/glxcmds.c +++ b/src/glx/glxcmds.c @@ -37,27 +37,24 @@ #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" #else #include #ifdef XF86VIDMODE #include #endif -#include "xf86dri.h" #endif -#else #endif -#if defined(USE_XCB) #include #include #include -#endif +#include "GL/mesa_glinterop.h" static const char __glXGLXClientVendorName[] = "Mesa Project and SGI"; static const char __glXGLXClientVersion[] = "1.4"; @@ -90,6 +87,51 @@ GetGLXDRIDrawable(Display * dpy, GLXDrawable drawable) #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. @@ -105,7 +147,7 @@ GetGLXDRIDrawable(Display * dpy, GLXDrawable drawable) * 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); @@ -140,7 +182,7 @@ GetGLXPrivScreenConfig(Display * dpy, int scrn, struct glx_display ** ppriv, /* 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; } @@ -181,13 +223,40 @@ ValidateGLXFBConfig(Display * dpy, GLXFBConfig fbconfig) 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) +{ + 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; @@ -195,7 +264,7 @@ glx_context_init(struct glx_context *gc, gc->isDirect = GL_TRUE; gc->currentContextTag = -1; - return GL_TRUE; + return True; } @@ -224,10 +293,14 @@ CreateContext(Display *dpy, int generic_id, struct glx_config *config, 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; @@ -295,23 +368,25 @@ CreateContext(Display *dpy, int generic_id, struct glx_config *config, UnlockDisplay(dpy); SyncHandle(); + gc->share_xid = shareList ? shareList->xid : None; gc->imported = GL_FALSE; - gc->renderType = renderType; 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; @@ -325,14 +400,39 @@ glXCreateContext(Display * dpy, XVisualInfo * vis, 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); @@ -350,43 +450,36 @@ glx_send_destroy_context(Display *dpy, XID xid) /* ** 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; @@ -394,19 +487,19 @@ glXQueryVersion(Display * dpy, int *major, int *minor) /* 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; @@ -426,7 +519,7 @@ glXQueryExtension(Display * dpy, int *errorBase, int *eventBase) ** 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(); @@ -439,7 +532,7 @@ glXWaitGL(void) ** 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(); @@ -448,7 +541,7 @@ glXWaitX(void) 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(); @@ -463,7 +556,7 @@ glXUseXFont(Font font, int first, int count, int 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) { @@ -528,73 +621,61 @@ glXCopyContext(Display * dpy, GLXContext source_user, * \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. + * \returns \c 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; + 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 GL_FALSE; + return 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); + 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) { + __glXSendErrorForXcb(dpy, err); + free(err); + } - 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); #endif } -_X_EXPORT GLXPixmap +_GLX_PUBLIC GLXPixmap glXCreateGLXPixmap(Display * dpy, XVisualInfo * vis, Pixmap pixmap) { #ifdef GLX_USE_APPLEGL @@ -602,7 +683,7 @@ glXCreateGLXPixmap(Display * dpy, XVisualInfo * vis, Pixmap pixmap) 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; @@ -610,14 +691,26 @@ glXCreateGLXPixmap(Display * dpy, XVisualInfo * vis, Pixmap pixmap) 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); @@ -630,31 +723,49 @@ glXCreateGLXPixmap(Display * dpy, XVisualInfo * vis, Pixmap pixmap) 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; @@ -664,7 +775,7 @@ glXCreateGLXPixmap(Display * dpy, XVisualInfo * vis, Pixmap pixmap) /* ** Destroy the named pixmap */ -_X_EXPORT void +_GLX_PUBLIC void glXDestroyGLXPixmap(Display * dpy, GLXPixmap glxpixmap) { #ifdef GLX_USE_APPLEGL @@ -688,12 +799,14 @@ glXDestroyGLXPixmap(Display * dpy, GLXPixmap glxpixmap) 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); } @@ -702,11 +815,11 @@ glXDestroyGLXPixmap(Display * dpy, GLXPixmap glxpixmap) #endif /* GLX_USE_APPLEGL */ } -_X_EXPORT void +_GLX_PUBLIC void glXSwapBuffers(Display * dpy, GLXDrawable drawable) { #ifdef GLX_USE_APPLEGL - GLXContext gc = glXGetCurrentContext(); + struct glx_context * gc = __glXGetCurrentContext(); if(gc && apple_glx_is_current_drawable(dpy, gc->driContext, drawable)) { apple_glx_swap_buffers(gc->driContext); } else { @@ -716,24 +829,20 @@ glXSwapBuffers(Display * dpy, GLXDrawable drawable) 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 && drawable == gc->currentDrawable; - (*pdraw->psc->driScreen->swapBuffers)(pdraw, 0, 0, 0); - return; + (*pdraw->psc->driScreen->swapBuffers)(pdraw, 0, 0, 0, flush); + return; + } } #endif @@ -755,22 +864,9 @@ glXSwapBuffers(Display * dpy, GLXDrawable drawable) 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 */ } @@ -779,7 +875,7 @@ glXSwapBuffers(Display * dpy, GLXDrawable drawable) ** 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) { @@ -805,7 +901,7 @@ glXGetConfig(Display * dpy, XVisualInfo * vis, int attribute, ** 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; } @@ -822,14 +918,16 @@ init_fbconfig_for_chooser(struct glx_config * config, 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; @@ -838,9 +936,6 @@ init_fbconfig_for_chooser(struct glx_config * config, 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); @@ -873,8 +968,10 @@ init_fbconfig_for_chooser(struct glx_config * config, /* 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); /** @@ -1007,7 +1104,7 @@ static int 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); @@ -1036,6 +1133,9 @@ fbconfig_compare(struct glx_config **a, struct glx_config **b) PREFER_SMALLER(numAuxBuffers); + PREFER_SMALLER(sampleBuffers); + PREFER_SMALLER(samples); + PREFER_LARGER_OR_ZERO(depthBits); PREFER_SMALLER(stencilBits); @@ -1049,12 +1149,6 @@ fbconfig_compare(struct glx_config **a, struct glx_config **b) 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. */ @@ -1140,7 +1234,7 @@ choose_visual(struct glx_config ** configs, int num_configs, ** 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; @@ -1189,7 +1283,7 @@ glXChooseVisual(Display * dpy, int screen, int *attribList) &visualTemplate, &i); if (newList) { - Xfree(visualList); + free(visualList); visualList = newList; best_config = config; } @@ -1206,7 +1300,7 @@ glXChooseVisual(Display * dpy, int screen, int *attribList) } -_X_EXPORT const char * +_GLX_PUBLIC const char * glXQueryExtensionsString(Display * dpy, int screen) { struct glx_screen *psc; @@ -1235,7 +1329,7 @@ glXQueryExtensionsString(Display * dpy, int screen) return psc->effectiveGLXexts; } -_X_EXPORT const char * +_GLX_PUBLIC const char * glXGetClientString(Display * dpy, int name) { (void) dpy; @@ -1252,7 +1346,7 @@ glXGetClientString(Display * dpy, int name) } } -_X_EXPORT const char * +_GLX_PUBLIC const char * glXQueryServerString(Display * dpy, int screen, int name) { struct glx_screen *psc; @@ -1285,44 +1379,12 @@ glXQueryServerString(Display * dpy, int screen, int name) 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(); @@ -1331,25 +1393,53 @@ glXGetCurrentDisplay(void) 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; + + /* This GLX implementation knows about 5 different properties, so + * allow the server to send us one of each. + */ + int propList[5 * 2], *pProp, nPropListBytes; + int numProps; int i, renderType; XID share; struct glx_config *mode; + 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 does not refer to a valid context, then a BadContext + * error is generated; if 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)) return NULL; opcode = __glXSetupForCommand(dpy); @@ -1392,35 +1482,45 @@ glXImportContextEXT(Display *dpy, GLXContextID contextID) 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) - return NULL; - + numProps = nPropListBytes / (2 * sizeof(propList[0])); share = None; mode = NULL; - renderType = 0; + renderType = GLX_RGBA_TYPE; /* By default, assume RGBA context */ pProp = propList; - for (i = 0, pProp = propList; i < reply.n; i++, pProp += 2) + for (i = 0, pProp = propList; i < numProps; i++, pProp += 2) switch (pProp[0]) { + case GLX_SCREEN: + screen = pProp[1]; + got_screen = True; + break; case GLX_SHARE_CONTEXT_EXT: share = pProp[1]; break; case GLX_VISUAL_ID_EXT: - mode = glx_config_find_visual(psc->visuals, pProp[1]); + visualID = pProp[1]; break; case GLX_FBCONFIG_ID: - mode = glx_config_find_fbconfig(psc->configs, pProp[1]); + fbconfigID = pProp[1]; break; case GLX_RENDER_TYPE: renderType = pProp[1]; break; } + if (!got_screen) + return NULL; + + psc = GetGLXScreenConfigs(dpy, screen); + if (psc == NULL) + return NULL; + + 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; @@ -1437,7 +1537,7 @@ glXImportContextEXT(Display *dpy, GLXContextID contextID) #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; @@ -1464,26 +1564,44 @@ glXQueryContext(Display * dpy, GLXContext ctx_user, int attribute, int *value) 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; + + /* 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(); +} -_X_EXPORT GLXFBConfig * +_GLX_PUBLIC GLXFBConfig * glXChooseFBConfig(Display * dpy, int screen, const int *attribList, int *nitems) { @@ -1497,7 +1615,7 @@ glXChooseFBConfig(Display * dpy, int screen, if ((config_list != NULL) && (list_size > 0) && (attribList != NULL)) { list_size = choose_visual(config_list, list_size, attribList, GL_TRUE); if (list_size == 0) { - XFree(config_list); + free(config_list); config_list = NULL; } } @@ -1507,11 +1625,34 @@ glXChooseFBConfig(Display * dpy, int screen, } -_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; + int screen = DefaultScreen(dpy); + 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, 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, @@ -1519,7 +1660,7 @@ glXCreateNewContext(Display * dpy, GLXFBConfig fbconfig, } -_X_EXPORT GLXDrawable +_GLX_PUBLIC GLXDrawable glXGetCurrentReadDrawable(void) { struct glx_context *gc = __glXGetCurrentContext(); @@ -1528,7 +1669,7 @@ glXGetCurrentReadDrawable(void) } -_X_EXPORT GLXFBConfig * +_GLX_PUBLIC GLXFBConfig * glXGetFBConfigs(Display * dpy, int screen, int *nelements) { struct glx_display *priv = __glXInitialize(dpy); @@ -1539,7 +1680,7 @@ glXGetFBConfigs(Display * dpy, int screen, int *nelements) *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)) { @@ -1551,7 +1692,7 @@ glXGetFBConfigs(Display * dpy, int screen, int *nelements) } } - 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; @@ -1569,7 +1710,7 @@ glXGetFBConfigs(Display * dpy, int screen, int *nelements) } -_X_EXPORT int +_GLX_PUBLIC int glXGetFBConfigAttrib(Display * dpy, GLXFBConfig fbconfig, int attribute, int *value) { @@ -1582,7 +1723,7 @@ glXGetFBConfigAttrib(Display * dpy, GLXFBConfig fbconfig, } -_X_EXPORT XVisualInfo * +_GLX_PUBLIC XVisualInfo * glXGetVisualFromFBConfig(Display * dpy, GLXFBConfig fbconfig) { XVisualInfo visualTemplate; @@ -1621,7 +1762,8 @@ __glXSwapIntervalSGI(int interval) 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); @@ -1667,7 +1809,7 @@ __glXSwapIntervalMESA(unsigned int interval) 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); @@ -1689,7 +1831,7 @@ __glXGetSwapIntervalMESA(void) 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); @@ -1733,7 +1875,7 @@ __glXGetVideoSyncSGI(unsigned int *count) * 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; @@ -1771,7 +1913,7 @@ __glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count) #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; @@ -1790,21 +1932,21 @@ __glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count) ** 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) @@ -1857,7 +1999,7 @@ glXCreateGLXPixmapWithConfigSGIX(Display * dpy, #endif } -_X_EXPORT GLXContext +_GLX_PUBLIC GLXContext glXCreateContextWithConfigSGIX(Display * dpy, GLXFBConfigSGIX fbconfig, int renderType, GLXContext shareList, Bool allowDirect) @@ -1884,13 +2026,13 @@ glXCreateContextWithConfigSGIX(Display * dpy, } -_X_EXPORT GLXFBConfigSGIX +_GLX_PUBLIC GLXFBConfigSGIX glXGetFBConfigFromVisualSGIX(Display * dpy, XVisualInfo * vis) { struct glx_display *priv; struct glx_screen *psc = NULL; - if ((GetGLXPrivScreenConfig(dpy, vis->screen, &priv, &psc) != Success) + if ((GetGLXPrivScreenConfig(dpy, vis->screen, &priv, &psc) == Success) && __glXExtensionBitIsEnabled(psc, SGIX_fbconfig_bit) && (psc->configs->fbconfigID != (int) GLX_DONT_CARE)) { return (GLXFBConfigSGIX) glx_config_find_visual(psc->configs, @@ -1966,16 +2108,14 @@ __glXGetSyncValuesOML(Display * dpy, GLXDrawable drawable, #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; 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; @@ -2051,7 +2191,7 @@ __glXGetMscRateOML(Display * dpy, GLXDrawable drawable, if (draw == NULL) return False; - return __glxGetMscRate(draw, numerator, denominator); + return __glxGetMscRate(draw->psc, numerator, denominator); #else (void) dpy; (void) drawable; @@ -2096,7 +2236,7 @@ __glXSwapBuffersMscOML(Display * dpy, GLXDrawable drawable, #ifdef GLX_DIRECT_RENDERING if (psc->driScreen && psc->driScreen->swapBuffers) return (*psc->driScreen->swapBuffers)(pdraw, target_msc, divisor, - remainder); + remainder, False); #endif return -1; @@ -2202,7 +2342,7 @@ __glXReleaseBuffersMESA(Display * dpy, GLXDrawable d) } -_X_EXPORT GLXPixmap +_GLX_PUBLIC GLXPixmap glXCreateGLXPixmapMESA(Display * dpy, XVisualInfo * visual, Pixmap pixmap, Colormap cmap) { @@ -2236,8 +2376,7 @@ __glXCopySubBufferMESA(Display * dpy, GLXDrawable drawable, 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; @@ -2313,23 +2452,6 @@ __glXReleaseTexImageEXT(Display * dpy, GLXDrawable drawable, int 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 */ @@ -2466,16 +2588,24 @@ static const struct name_address_pair GLX_functions[] = { 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) { @@ -2489,7 +2619,6 @@ 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 @@ -2500,7 +2629,7 @@ get_glx_proc_address(const char *funcName) * * \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; @@ -2512,9 +2641,6 @@ _X_EXPORT void (*glXGetProcAddressARB(const GLubyte * procName)) (void) * 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')) { @@ -2523,8 +2649,13 @@ _X_EXPORT void (*glXGetProcAddressARB(const GLubyte * procName)) (void) #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; } @@ -2537,9 +2668,13 @@ _X_EXPORT void (*glXGetProcAddressARB(const GLubyte * procName)) (void) * * \sa glXGetProcAddressARB */ -_X_EXPORT void (*glXGetProcAddress(const GLubyte * procName)) (void) +_GLX_PUBLIC void (*glXGetProcAddress(const GLubyte * procName)) (void) #if defined(__GNUC__) && !defined(GLX_ALIAS_UNSUPPORTED) +# if defined(USE_MGL_NAMESPACE) + __attribute__ ((alias("mglXGetProcAddressARB"))); +# else __attribute__ ((alias("glXGetProcAddressARB"))); +# endif #else { return glXGetProcAddressARB(procName); @@ -2580,3 +2715,56 @@ __glXGetUST(int64_t * ust) } } #endif /* GLX_DIRECT_RENDERING */ + +#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) + +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; +} + +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) */