From f3e07519152b470faef73f50a1d0cbeb6f481b4f Mon Sep 17 00:00:00 2001 From: Jon TURNEY Date: Tue, 3 Jul 2012 19:38:13 +0100 Subject: Do not report the GLX_INTEL_swap_event extension for indirect swrast Commit 84956ca4 bogusly adds GLX_INTEL_swap_event to the extensions reported by swrast. swrast does not support this extension and should not report it, otherwise toolkits like clutter will only ever SwapBuffers once and wait forever for an event that's not coming. (A similar bug for direct swrast is already fixed in mesa commit 25620eb1) Ensure this kind of bug doesn't occur in future, by rather than using a fixed list of GLX extensions for swrast, generate the extension list in the same way as dri and dri2 do. This still looks a bit wonky: swrast and DRI1 will still always report certain GLX extensions, as __glXInitExtensionEnableBits() has enabled them, even though they then subsequently check if the underlying driver supports them (e.g. GLX_SGI_make_current_read) This has a couple of side-effects on the reported GLX extensions for swrast: - GLX_SGIS_multisample is now reported on APPLE (I can't work out why this conditional was added, it dates back to the XFree86 4.4RC3 import) - GLX_SGIX_visual_select_group is now reported (this is probably pointless but benign) (Note that this may be papering over the cracks somewhat, as if we do report GLX_INTEL_swap_event, some clutter apps fail with GLXBadDrawable calling GLXChangeDrawableAttributes to change the setting of GLX_BUFFER_SWAP_COMPLETE_INTEL_MASK in the GLX_EVENT_MASK, apparently after the drawable is destroyed, which suggests a bug with GLXDrawable lifetimes) Also: - Don't record GLX_INTEL_swap_event as being required by GLX 1.4, it isn't. (This data is not currently used) Signed-off-by: Jon TURNEY --- glx/extension_string.c | 2 +- glx/glxdriswrast.c | 57 +++++++++++++++++++++++++++++++++++++++----------- glx/glxscreens.c | 19 +---------------- 3 files changed, 47 insertions(+), 31 deletions(-) diff --git a/glx/extension_string.c b/glx/extension_string.c index 7721cb056..707acba86 100644 --- a/glx/extension_string.c +++ b/glx/extension_string.c @@ -82,7 +82,7 @@ static const struct extension_info known_glx_extensions[] = { { GLX(SGIX_fbconfig), VER(1,3), Y, }, { GLX(SGIX_pbuffer), VER(1,3), Y, }, { GLX(SGIX_visual_select_group), VER(0,0), Y, }, - { GLX(INTEL_swap_event), VER(1,4), N, }, + { GLX(INTEL_swap_event), VER(0,0), N, }, { NULL } }; diff --git a/glx/glxdriswrast.c b/glx/glxdriswrast.c index d064a0536..6986098bb 100644 --- a/glx/glxdriswrast.c +++ b/glx/glxdriswrast.c @@ -75,6 +75,8 @@ struct __GLXDRIscreen { const __DRIcopySubBufferExtension *copySubBuffer; const __DRItexBufferExtension *texBuffer; const __DRIconfig **driConfigs; + + unsigned char glx_enable_bits[__GLX_EXT_BYTES]; }; struct __GLXDRIcontext { @@ -339,8 +341,7 @@ __glXDRIscreenCreateDrawable(ClientPtr client, static void swrastGetDrawableInfo(__DRIdrawable *draw, - int *x, int *y, int *w, int *h, - void *loaderPrivate) + int *x, int *y, int *w, int *h, void *loaderPrivate) { __GLXDRIdrawable *drawable = loaderPrivate; DrawablePtr pDraw = drawable->base.pDraw; @@ -410,21 +411,37 @@ initializeExtensions(__GLXDRIscreen *screen) extensions = screen->core->getExtensions(screen->driScreen); + /* GLX_MESA_copy_sub_buffer is always enabled. */ + __glXEnableExtension(screen->glx_enable_bits, "GLX_MESA_copy_sub_buffer"); + for (i = 0; extensions[i]; i++) { +#ifdef __DRI_READ_DRAWABLE + if (strcmp(extensions[i]->name, __DRI_READ_DRAWABLE) == 0) { + __glXEnableExtension(screen->glx_enable_bits, + "GLX_SGI_make_current_read"); + + LogMessage(X_INFO, "AIGLX: enabled GLX_SGI_make_current_read\n"); + } +#endif + #ifdef __DRI_COPY_SUB_BUFFER - if (strcmp(extensions[i]->name, __DRI_COPY_SUB_BUFFER) == 0) { - screen->copySubBuffer = - (const __DRIcopySubBufferExtension *) extensions[i]; - /* GLX_MESA_copy_sub_buffer is always enabled. */ - } + if (strcmp(extensions[i]->name, __DRI_COPY_SUB_BUFFER) == 0) { + screen->copySubBuffer = + (const __DRIcopySubBufferExtension *) extensions[i]; + __glXEnableExtension(screen->glx_enable_bits, + "GLX_MESA_copy_sub_buffer"); + + LogMessage(X_INFO, "AIGLX: enabled GLX_MESA_copy_sub_buffer\n"); + } #endif #ifdef __DRI_TEX_BUFFER - if (strcmp(extensions[i]->name, __DRI_TEX_BUFFER) == 0) { - screen->texBuffer = - (const __DRItexBufferExtension *) extensions[i]; - /* GLX_EXT_texture_from_pixmap is always enabled. */ - } + if (strcmp(extensions[i]->name, __DRI_TEX_BUFFER) == 0) { + screen->texBuffer = (const __DRItexBufferExtension *) extensions[i]; + /* GLX_EXT_texture_from_pixmap is always enabled. */ + LogMessage(X_INFO, + "AIGLX: enabled GLX_EXT_texture_from_pixmapo\n"); + } #endif /* Ignore unknown extensions */ } @@ -435,6 +452,7 @@ __glXDRIscreenProbe(ScreenPtr pScreen) { const char *driverName = "swrast"; __GLXDRIscreen *screen; + size_t buffer_size; screen = calloc(1, sizeof *screen); if (screen == NULL) @@ -446,6 +464,8 @@ __glXDRIscreenProbe(ScreenPtr pScreen) screen->base.swapInterval = NULL; screen->base.pScreen = pScreen; + __glXInitExtensionEnableBits(screen->glx_enable_bits); + screen->driver = glxProbeDriver(driverName, (void **)&screen->core, __DRI_CORE, __DRI_CORE_VERSION, @@ -476,6 +496,19 @@ __glXDRIscreenProbe(ScreenPtr pScreen) __glXScreenInit(&screen->base, pScreen); + /* The first call simply determines the length of the extension string. + * This allows us to allocate some memory to hold the extension string, + * but it requires that we call __glXGetExtensionString a second time. + */ + buffer_size = __glXGetExtensionString(screen->glx_enable_bits, NULL); + if (buffer_size > 0) { + free(screen->base.GLXextensions); + + screen->base.GLXextensions = xnfalloc(buffer_size); + (void) __glXGetExtensionString(screen->glx_enable_bits, + screen->base.GLXextensions); + } + screen->base.GLXmajor = 1; screen->base.GLXminor = 4; diff --git a/glx/glxscreens.c b/glx/glxscreens.c index ebb9747b4..380dffbca 100644 --- a/glx/glxscreens.c +++ b/glx/glxscreens.c @@ -165,22 +165,6 @@ static const char GLServerExtensions[] = static char GLXServerVendorName[] = "SGI"; unsigned glxMajorVersion = SERVER_GLX_MAJOR_VERSION; unsigned glxMinorVersion = SERVER_GLX_MINOR_VERSION; -static char GLXServerExtensions[] = - "GLX_ARB_multisample " - "GLX_EXT_visual_info " - "GLX_EXT_visual_rating " - "GLX_EXT_import_context " - "GLX_EXT_texture_from_pixmap " - "GLX_OML_swap_method " - "GLX_SGI_make_current_read " -#ifndef __APPLE__ - "GLX_SGIS_multisample " -#endif - "GLX_SGIX_fbconfig " - "GLX_SGIX_pbuffer " - "GLX_MESA_copy_sub_buffer " - "GLX_INTEL_swap_event" - ; static Bool glxCloseScreen (int index, ScreenPtr pScreen) @@ -331,8 +315,7 @@ void __glXScreenInit(__GLXscreen *pGlxScreen, ScreenPtr pScreen) pGlxScreen->pScreen = pScreen; pGlxScreen->GLextensions = strdup(GLServerExtensions); pGlxScreen->GLXvendor = strdup(GLXServerVendorName); - pGlxScreen->GLXextensions = strdup(GLXServerExtensions); - + pGlxScreen->GLXextensions = strdup(""); /* All GLX providers must support all of the functionality required for at * least GLX 1.2. If the provider supports a higher version, the GLXminor * version can be changed in the provider's screen-probe routine. For -- cgit v1.2.3