Revision: 289 http://trac.macosforge.org/projects/xquartz/changeset/289 Author: gstaplin@apple.com Date: 2009-03-07 00:55:38 -0800 (Sat, 07 Mar 2009) Log Message: ----------- Fix an error that occurred with an invalid GLXPbuffer generating a failed XGetGeometry XErrorEvent. The proper XError for glXQueryDrawable is GLXBadDrawable, so add some error catching to fall through to the __glXSendError(). Modified Paths: -------------- AppleSGLX/trunk/glx_pbuffer.c AppleSGLX/trunk/tests/pbuffer/pbuffer_destroy.c Modified: AppleSGLX/trunk/glx_pbuffer.c =================================================================== --- AppleSGLX/trunk/glx_pbuffer.c 2009-03-06 19:11:36 UTC (rev 288) +++ AppleSGLX/trunk/glx_pbuffer.c 2009-03-07 08:55:38 UTC (rev 289) @@ -31,19 +31,34 @@ */ #include <inttypes.h> +#include <pthread.h> #include "glxclient.h" #include <X11/extensions/extutil.h> #include <X11/extensions/Xext.h> #include <assert.h> #include <string.h> -//#include "glapi.h" #include "glxextensions.h" #include "glcontextmodes.h" -//#include "glheader.h" + #include "apple_glx_drawable.h" #include "glx_error.h" + +static pthread_mutex_t queryLock = PTHREAD_MUTEX_INITIALIZER; + +/* + * This is protected by the queryLock. + * Unfortunately XSetErrorHandler requires a lock. + */ +static int errorCount = 0; + +static int +errorHandler(Display *dpy, XErrorEvent *error) { + ++errorCount; + return 0; /* don't exit */ +} + /** * Create a new pbuffer. */ @@ -109,7 +124,6 @@ } } - /** * Query an attribute of a drawable. */ @@ -119,6 +133,7 @@ Window root; int x, y; unsigned int width, height, bd, depth; + int (*old_handler)(Display *, XErrorEvent *); if(apple_glx_pixmap_query(drawable, attribute, value)) return; /*done*/ @@ -126,6 +141,15 @@ if(apple_glx_pbuffer_query(drawable, attribute, value)) return; /*done*/ + /* + * This is used because XSetErrorHandler changes global state. + * Ideally we should prevent other threads from calling XSetErrorHandler. + * Another way of handling this might be a private display connection. + */ + pthread_mutex_lock(&queryLock); + + old_handler = XSetErrorHandler(errorHandler); + if(XGetGeometry(dpy, drawable, &root, &x, &y, &width, &height, &bd, &depth)) { switch(attribute) { case GLX_WIDTH: @@ -139,7 +163,10 @@ /*FALL THROUGH*/ } + XSetErrorHandler(old_handler); + pthread_mutex_unlock(&queryLock); + __glXSendError(dpy, GLXBadDrawable, drawable, X_GLXGetDrawableAttributes, false); } Modified: AppleSGLX/trunk/tests/pbuffer/pbuffer_destroy.c =================================================================== --- AppleSGLX/trunk/tests/pbuffer/pbuffer_destroy.c 2009-03-06 19:11:36 UTC (rev 288) +++ AppleSGLX/trunk/tests/pbuffer/pbuffer_destroy.c 2009-03-07 08:55:38 UTC (rev 289) @@ -7,32 +7,6 @@ GLXPbuffer pbuf; void dump_pbuffer(Display *dpy) { - size_t length = 400 * 400 * /*RGBA*/ 4; - void *p = malloc(length); - unsigned char *cp; - int x, y; - - if(NULL == p) { - perror("malloc"); - abort(); - } - - memset(p, 0, length); - - glReadPixels(0, 0, 400, 400, GL_RGBA, GL_UNSIGNED_BYTE, p); - - cp = p; - for(y = 0; y < 400; ++y) { - for(x = 0; x < 400; ++x) { - printf("%d %d %d %d, ", cp[0], cp[1], cp[2], cp[3]); - cp += 4; - } - putchar('\n'); - } - - free(p); - - { unsigned int width = 0, height = 0, fbid = 0; glXQueryDrawable(dpy, pbuf, GLX_WIDTH, &width); @@ -41,8 +15,6 @@ printf("queried drawable width %u height %u fbconfigID %x\n", width, height, fbid); - - } } void draw(Display *dpy) { @@ -160,7 +132,9 @@ draw(dpy); glXDestroyPbuffer(dpy, pbuf); draw(dpy); + /* This should release the final reference to the pbuffer. */ glXMakeCurrent(dpy, None, ctx); + printf("Expect a GLXBadDrawable error.\n"); draw(dpy); return EXIT_SUCCESS;
participants (1)
-
source_changes@macosforge.org