X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fglx%2Fglxcmds.c;h=53c9f9ce2afa9ccfd6c30ac33bc3c231d0ac21ab;hb=f446f3fb33528eebe9b120340fca3ac5c5ba518d;hp=26ff804297fee6ff817f0af1aa2d437b91f1e7c1;hpb=05e7f7f4388bde882b7ce74124000a4d435affff;p=mesa.git diff --git a/src/glx/glxcmds.c b/src/glx/glxcmds.c index 26ff804297f..53c9f9ce2af 100644 --- a/src/glx/glxcmds.c +++ b/src/glx/glxcmds.c @@ -54,6 +54,7 @@ #include #include #include +#include "GL/mesa_glinterop.h" static const char __glXGLXClientVendorName[] = "Mesa Project and SGI"; static const char __glXGLXClientVersion[] = "1.4"; @@ -373,7 +374,7 @@ CreateContext(Display *dpy, int generic_id, struct glx_config *config, return (GLXContext) gc; } -_X_EXPORT GLXContext +_GLX_PUBLIC GLXContext glXCreateContext(Display * dpy, XVisualInfo * vis, GLXContext shareList, Bool allowDirect) { @@ -450,7 +451,7 @@ glx_send_destroy_context(Display *dpy, XID xid) ** Destroy the named context */ -_X_EXPORT void +_GLX_PUBLIC void glXDestroyContext(Display * dpy, GLXContext ctx) { struct glx_context *gc = (struct glx_context *) ctx; @@ -478,7 +479,7 @@ glXDestroyContext(Display * dpy, GLXContext ctx) /* ** 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; @@ -498,7 +499,7 @@ glXQueryVersion(Display * dpy, int *major, int *minor) /* ** 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; @@ -518,12 +519,12 @@ 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(); - if (gc && gc->vtable->wait_gl) + if (gc != &dummyContext && gc->vtable->wait_gl) gc->vtable->wait_gl(gc); } @@ -531,21 +532,21 @@ 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(); - if (gc && gc->vtable->wait_x) + if (gc != &dummyContext && 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 != &dummyContext && gc->vtable->use_x_font) gc->vtable->use_x_font(gc, font, first, count, listBase); } @@ -555,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) { @@ -656,7 +657,7 @@ __glXIsDirect(Display * dpy, GLXContextID contextID) * \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; @@ -674,7 +675,7 @@ glXIsDirect(Display * dpy, GLXContext gc_user) #endif } -_X_EXPORT GLXPixmap +_GLX_PUBLIC GLXPixmap glXCreateGLXPixmap(Display * dpy, XVisualInfo * vis, Pixmap pixmap) { #ifdef GLX_USE_APPLEGL @@ -774,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 @@ -814,12 +815,12 @@ glXDestroyGLXPixmap(Display * dpy, GLXPixmap glxpixmap) #endif /* GLX_USE_APPLEGL */ } -_X_EXPORT void +_GLX_PUBLIC void glXSwapBuffers(Display * dpy, GLXDrawable drawable) { #ifdef GLX_USE_APPLEGL struct glx_context * gc = __glXGetCurrentContext(); - if(gc && apple_glx_is_current_drawable(dpy, gc->driContext, drawable)) { + 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); @@ -837,7 +838,7 @@ glXSwapBuffers(Display * dpy, GLXDrawable drawable) __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable); if (pdraw != NULL) { - Bool flush = gc && drawable == gc->currentDrawable; + Bool flush = gc != &dummyContext && drawable == gc->currentDrawable; (*pdraw->psc->driScreen->swapBuffers)(pdraw, 0, 0, 0, flush); return; @@ -854,7 +855,7 @@ glXSwapBuffers(Display * dpy, GLXDrawable drawable) ** 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; @@ -874,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) { @@ -1161,8 +1162,8 @@ fbconfig_compare(struct glx_config **a, struct glx_config **b) /** * 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 @@ -1170,20 +1171,16 @@ fbconfig_compare(struct glx_config **a, struct glx_config **b) * 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; @@ -1195,10 +1192,10 @@ choose_visual(struct glx_config ** configs, int num_configs, * 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++) { @@ -1233,7 +1230,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; @@ -1299,7 +1296,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; @@ -1328,7 +1325,7 @@ glXQueryExtensionsString(Display * dpy, int screen) return psc->effectiveGLXexts; } -_X_EXPORT const char * +_GLX_PUBLIC const char * glXGetClientString(Display * dpy, int name) { (void) dpy; @@ -1345,7 +1342,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; @@ -1383,21 +1380,21 @@ glXQueryServerString(Display * dpy, int screen, int name) ** 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); @@ -1536,7 +1533,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; @@ -1563,19 +1560,19 @@ 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 == NULL) ? None : ctx->xid; } -_X_EXPORT void +_GLX_PUBLIC void glXFreeContextEXT(Display *dpy, GLXContext ctx) { struct glx_context *gc = (struct glx_context *) ctx; @@ -1600,7 +1597,7 @@ glXFreeContextEXT(Display *dpy, GLXContext ctx) __glXUnlock(); } -_X_EXPORT GLXFBConfig * +_GLX_PUBLIC GLXFBConfig * glXChooseFBConfig(Display * dpy, int screen, const int *attribList, int *nitems) { @@ -1612,7 +1609,7 @@ glXChooseFBConfig(Display * dpy, int screen, 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) { free(config_list); config_list = NULL; @@ -1624,11 +1621,33 @@ 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; + 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, @@ -1636,7 +1655,7 @@ glXCreateNewContext(Display * dpy, GLXFBConfig fbconfig, } -_X_EXPORT GLXDrawable +_GLX_PUBLIC GLXDrawable glXGetCurrentReadDrawable(void) { struct glx_context *gc = __glXGetCurrentContext(); @@ -1645,7 +1664,7 @@ glXGetCurrentReadDrawable(void) } -_X_EXPORT GLXFBConfig * +_GLX_PUBLIC GLXFBConfig * glXGetFBConfigs(Display * dpy, int screen, int *nelements) { struct glx_display *priv = __glXInitialize(dpy); @@ -1656,7 +1675,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)) { @@ -1686,7 +1705,7 @@ glXGetFBConfigs(Display * dpy, int screen, int *nelements) } -_X_EXPORT int +_GLX_PUBLIC int glXGetFBConfigAttrib(Display * dpy, GLXFBConfig fbconfig, int attribute, int *value) { @@ -1699,7 +1718,7 @@ glXGetFBConfigAttrib(Display * dpy, GLXFBConfig fbconfig, } -_X_EXPORT XVisualInfo * +_GLX_PUBLIC XVisualInfo * glXGetVisualFromFBConfig(Display * dpy, GLXFBConfig fbconfig) { XVisualInfo visualTemplate; @@ -1727,7 +1746,7 @@ __glXSwapIntervalSGI(int interval) CARD32 *interval_ptr; CARD8 opcode; - if (gc == NULL) { + if (gc == &dummyContext) { return GLX_BAD_CONTEXT; } @@ -1742,7 +1761,11 @@ __glXSwapIntervalSGI(int interval) 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 @@ -1781,14 +1804,21 @@ __glXSwapIntervalMESA(unsigned int interval) #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 && 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 @@ -1803,14 +1833,15 @@ __glXGetSwapIntervalMESA(void) #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 && 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 @@ -1833,7 +1864,7 @@ __glXGetVideoSyncSGI(unsigned int *count) __GLXDRIdrawable *pdraw; #endif - if (!gc) + if (gc == &dummyContext) return GLX_BAD_CONTEXT; #ifdef GLX_DIRECT_RENDERING @@ -1875,7 +1906,7 @@ __glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count) if (divisor <= 0 || remainder < 0) return GLX_BAD_VALUE; - if (!gc) + if (gc == &dummyContext) return GLX_BAD_CONTEXT; #ifdef GLX_DIRECT_RENDERING @@ -1908,21 +1939,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) @@ -1975,7 +2006,7 @@ glXCreateGLXPixmapWithConfigSGIX(Display * dpy, #endif } -_X_EXPORT GLXContext +_GLX_PUBLIC GLXContext glXCreateContextWithConfigSGIX(Display * dpy, GLXFBConfigSGIX fbconfig, int renderType, GLXContext shareList, Bool allowDirect) @@ -2002,7 +2033,7 @@ glXCreateContextWithConfigSGIX(Display * dpy, } -_X_EXPORT GLXFBConfigSGIX +_GLX_PUBLIC GLXFBConfigSGIX glXGetFBConfigFromVisualSGIX(Display * dpy, XVisualInfo * vis) { struct glx_display *priv; @@ -2188,7 +2219,7 @@ __glXSwapBuffersMscOML(Display * dpy, GLXDrawable 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 @@ -2318,7 +2349,7 @@ __glXReleaseBuffersMESA(Display * dpy, GLXDrawable d) } -_X_EXPORT GLXPixmap +_GLX_PUBLIC GLXPixmap glXCreateGLXPixmapMESA(Display * dpy, XVisualInfo * visual, Pixmap pixmap, Colormap cmap) { @@ -2368,7 +2399,7 @@ __glXCopySubBufferMESA(Display * dpy, GLXDrawable drawable, ** 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; @@ -2407,7 +2438,7 @@ __glXBindTexImageEXT(Display * dpy, { struct glx_context *gc = __glXGetCurrentContext(); - if (gc == NULL || gc->vtable->bind_tex_image == NULL) + if (gc == &dummyContext || gc->vtable->bind_tex_image == NULL) return; gc->vtable->bind_tex_image(dpy, drawable, buffer, attrib_list); @@ -2418,7 +2449,7 @@ __glXReleaseTexImageEXT(Display * dpy, GLXDrawable drawable, int buffer) { struct glx_context *gc = __glXGetCurrentContext(); - if (gc == NULL || gc->vtable->release_tex_image == NULL) + if (gc == &dummyContext || gc->vtable->release_tex_image == NULL) return; gc->vtable->release_tex_image(dpy, drawable, buffer); @@ -2605,7 +2636,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; @@ -2644,15 +2675,10 @@ _X_EXPORT void (*glXGetProcAddressARB(const GLubyte * procName)) (void) * * \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) /** @@ -2687,3 +2713,56 @@ __glXGetUST(int64_t * ust) } } #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) */