diff options
author | Chad Versace <chad.versace@linux.intel.com> | 2013-07-09 09:44:47 -0700 |
---|---|---|
committer | Chad Versace <chad.versace@linux.intel.com> | 2013-07-26 20:16:21 -0700 |
commit | 229693794eb4038d8796e1c77e43097e73ca19a6 (patch) | |
tree | 2782ecf826f3f151478466ef1646c8e6f12f85f1 | |
parent | 7217987e5dbf25fcbedda42ba92769121abc5e24 (diff) |
glx: Catch Xlib errors with function wrappers
This patch defines a wrapper for each GLX function called by the glx
directory. Each wrapper catches any Xlib error emitted by the wrapped
function. The wrapper's signature matches the wrapped.
All Xlib errors generated by Waffle must be caught by Waffle. Otherwise,
the Xlib error handler installed by the user will catch the error and
may handle it in a way Waffle doesn't like. Or, even worse, the default
Xlib error handler will catch it, which exits the process.
Signed-off-by: Chad Versace <chad.versace@linux.intel.com>
-rw-r--r-- | src/waffle/glx/glx_config.c | 21 | ||||
-rw-r--r-- | src/waffle/glx/glx_context.c | 35 | ||||
-rw-r--r-- | src/waffle/glx/glx_display.c | 5 | ||||
-rw-r--r-- | src/waffle/glx/glx_platform.c | 7 | ||||
-rw-r--r-- | src/waffle/glx/glx_window.c | 3 | ||||
-rw-r--r-- | src/waffle/glx/glx_wrappers.h | 131 |
6 files changed, 164 insertions, 38 deletions
diff --git a/src/waffle/glx/glx_config.c b/src/waffle/glx/glx_config.c index 1d7c059..1ea19ac 100644 --- a/src/waffle/glx/glx_config.c +++ b/src/waffle/glx/glx_config.c @@ -34,6 +34,7 @@ #include "glx_config.h" #include "glx_display.h" #include "glx_platform.h" +#include "glx_wrappers.h" bool glx_config_destroy(struct wcore_config *wc_self) @@ -198,10 +199,10 @@ glx_config_choose(struct wcore_platform *wc_plat, }; // Set glx_fbconfig. - configs = glXChooseFBConfig(dpy->x11.xlib, - dpy->x11.screen, - attrib_list, - &num_configs); + configs = wrapped_glXChooseFBConfig(dpy->x11.xlib, + dpy->x11.screen, + attrib_list, + &num_configs); if (!configs || num_configs == 0) { wcore_errorf(WAFFLE_ERROR_UNKNOWN, "glXChooseFBConfig returned no matching configs"); @@ -211,18 +212,18 @@ glx_config_choose(struct wcore_platform *wc_plat, self->glx_fbconfig = configs[0]; // Set glx_fbconfig_id. - ok = !glXGetFBConfigAttrib(dpy->x11.xlib, - self->glx_fbconfig, - GLX_FBCONFIG_ID, - &self->glx_fbconfig_id); + ok = !wrapped_glXGetFBConfigAttrib(dpy->x11.xlib, + self->glx_fbconfig, + GLX_FBCONFIG_ID, + &self->glx_fbconfig_id); if (!ok) { wcore_errorf(WAFFLE_ERROR_UNKNOWN, "glxGetFBConfigAttrib failed"); goto error; } // Set xcb_visual_id. - vi = glXGetVisualFromFBConfig(dpy->x11.xlib, - self->glx_fbconfig); + vi = wrapped_glXGetVisualFromFBConfig(dpy->x11.xlib, + self->glx_fbconfig); if (!vi) { wcore_errorf(WAFFLE_ERROR_UNKNOWN, "glXGetVisualInfoFromFBConfig failed with " diff --git a/src/waffle/glx/glx_context.c b/src/waffle/glx/glx_context.c index a0563a3..e65bee3 100644 --- a/src/waffle/glx/glx_context.c +++ b/src/waffle/glx/glx_context.c @@ -38,6 +38,7 @@ #include "glx_context.h" #include "glx_display.h" #include "glx_platform.h" +#include "glx_wrappers.h" bool glx_context_destroy(struct wcore_context *wc_self) @@ -53,7 +54,7 @@ glx_context_destroy(struct wcore_context *wc_self) dpy = glx_display(wc_self->display); if (self->glx) - glXDestroyContext(dpy->x11.xlib, self->glx); + wrapped_glXDestroyContext(dpy->x11.xlib, self->glx); ok &= wcore_context_teardown(wc_self); free(self); @@ -137,11 +138,6 @@ glx_context_fill_attrib_list(struct glx_config *config, return true; } -static int glx_dummy_error_handler(Display *dpy, XErrorEvent *err) -{ - return 0; -} - static GLXContext glx_context_create_native(struct glx_config *config, struct glx_context *share_ctx) @@ -150,10 +146,6 @@ glx_context_create_native(struct glx_config *config, GLXContext real_share_ctx = share_ctx ? share_ctx->glx : NULL; struct glx_display *dpy = glx_display(config->wcore.display); struct glx_platform *platform = glx_platform(dpy->wcore.platform); - int (*old_error_handler)(Display *, XErrorEvent *); - - /* This prevents Xlib from killing the process if there's an error. */ - old_error_handler = XSetErrorHandler(glx_dummy_error_handler); if (dpy->ARB_create_context) { bool ok; @@ -165,11 +157,12 @@ glx_context_create_native(struct glx_config *config, if (!ok) return false; - ctx = platform->glXCreateContextAttribsARB(dpy->x11.xlib, - config->glx_fbconfig, - real_share_ctx, - true /*direct?*/, - attrib_list); + ctx = wrapped_glXCreateContextAttribsARB(platform, + dpy->x11.xlib, + config->glx_fbconfig, + real_share_ctx, + true /*direct?*/, + attrib_list); if (!ctx) { wcore_errorf(WAFFLE_ERROR_UNKNOWN, "glXCreateContextAttribsARB failed"); @@ -177,19 +170,17 @@ glx_context_create_native(struct glx_config *config, } } else { - ctx = glXCreateNewContext(dpy->x11.xlib, - config->glx_fbconfig, - GLX_RGBA_TYPE, - real_share_ctx, - true /*direct?*/); + ctx = wrapped_glXCreateNewContext(dpy->x11.xlib, + config->glx_fbconfig, + GLX_RGBA_TYPE, + real_share_ctx, + true /*direct?*/); if (!ctx) { wcore_errorf(WAFFLE_ERROR_UNKNOWN, "glXCreateContext failed"); return NULL; } } - XSetErrorHandler(old_error_handler); - return ctx; } diff --git a/src/waffle/glx/glx_display.c b/src/waffle/glx/glx_display.c index a29fb3c..184438f 100644 --- a/src/waffle/glx/glx_display.c +++ b/src/waffle/glx/glx_display.c @@ -31,6 +31,7 @@ #include "glx_display.h" #include "glx_platform.h" +#include "glx_wrappers.h" bool glx_display_destroy(struct wcore_display *wc_self) @@ -51,8 +52,8 @@ static bool glx_display_set_extensions(struct glx_display *self) { - const char *s = glXQueryExtensionsString(self->x11.xlib, - self->x11.screen); + const char *s = wrapped_glXQueryExtensionsString(self->x11.xlib, + self->x11.screen); if (!s) { wcore_errorf(WAFFLE_ERROR_UNKNOWN, "glXQueryExtensionsString failed"); diff --git a/src/waffle/glx/glx_platform.c b/src/waffle/glx/glx_platform.c index 658c132..8ddcfcb 100644 --- a/src/waffle/glx/glx_platform.c +++ b/src/waffle/glx/glx_platform.c @@ -34,6 +34,7 @@ #include "glx_display.h" #include "glx_platform.h" #include "glx_window.h" +#include "glx_wrappers.h" static const struct wcore_platform_vtbl glx_platform_vtbl; @@ -88,9 +89,9 @@ glx_platform_make_current(struct wcore_platform *wc_self, struct wcore_window *wc_window, struct wcore_context *wc_ctx) { - return glXMakeCurrent(glx_display(wc_dpy)->x11.xlib, - wc_window ? glx_window(wc_window)->x11.xcb : 0, - wc_ctx ? glx_context(wc_ctx)->glx : NULL); + return wrapped_glXMakeCurrent(glx_display(wc_dpy)->x11.xlib, + wc_window ? glx_window(wc_window)->x11.xcb : 0, + wc_ctx ? glx_context(wc_ctx)->glx : NULL); } static void* diff --git a/src/waffle/glx/glx_window.c b/src/waffle/glx/glx_window.c index b1584d1..6519738 100644 --- a/src/waffle/glx/glx_window.c +++ b/src/waffle/glx/glx_window.c @@ -31,6 +31,7 @@ #include "glx_config.h" #include "glx_display.h" #include "glx_window.h" +#include "glx_wrappers.h" bool glx_window_destroy(struct wcore_window *wc_self) @@ -93,7 +94,7 @@ glx_window_swap_buffers(struct wcore_window *wc_self) struct glx_window *self = glx_window(wc_self); struct glx_display *dpy = glx_display(wc_self->display); - glXSwapBuffers(dpy->x11.xlib, self->x11.xcb); + wrapped_glXSwapBuffers(dpy->x11.xlib, self->x11.xcb); return true; } diff --git a/src/waffle/glx/glx_wrappers.h b/src/waffle/glx/glx_wrappers.h new file mode 100644 index 0000000..5f53332 --- /dev/null +++ b/src/waffle/glx/glx_wrappers.h @@ -0,0 +1,131 @@ +// Copyright 2013 Intel Corporation +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// - Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// +// - Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +/// @file +/// @brief Wrappers for GLX functions +/// +/// Each wrapper catches any Xlib error emitted by the wrapped function. The +/// wrapper's signature matches the wrapped. +/// +/// All Xlib error generated by Waffle must be caught by Waffle. Otherwise, the +/// Xlib error handler installed by the user will catch the error and may +/// handle it in a way Waffle doesn't like. Or, even worse, the default Xlib +/// error handler will catch it, which exits the process. + +#pragma once + +#include <stdbool.h> +#include <stdint.h> + +#include <GL/glx.h> + +#include "glx_platform.h" +#include "x11_wrappers.h" + +static inline GLXFBConfig* +wrapped_glXChooseFBConfig(Display *dpy, int screen, + const int *attribList, int *nitems) +{ + X11_SAVE_ERROR_HANDLER + GLXFBConfig *configs = glXChooseFBConfig(dpy, screen, attribList, nitems); + X11_RESTORE_ERROR_HANDLER + return configs; +} + +static inline GLXContext +wrapped_glXCreateContextAttribsARB( + struct glx_platform *platform, Display *dpy, GLXFBConfig config, + GLXContext share_context, Bool direct, const int *attrib_list) +{ + X11_SAVE_ERROR_HANDLER + GLXContext ctx = platform->glXCreateContextAttribsARB( + dpy, config, share_context, direct, attrib_list); + X11_RESTORE_ERROR_HANDLER + return ctx; +} + +static inline GLXContext +wrapped_glXCreateNewContext(Display *dpy, GLXFBConfig config, int renderType, + GLXContext shareList, Bool direct) +{ + X11_SAVE_ERROR_HANDLER + GLXContext ctx = glXCreateNewContext(dpy, config, renderType, shareList, + direct); + X11_RESTORE_ERROR_HANDLER + return ctx; +} + +static inline int +wrapped_glXGetFBConfigAttrib(Display *dpy, GLXFBConfig config, + int attribute, int *value) +{ + X11_SAVE_ERROR_HANDLER + int error = glXGetFBConfigAttrib(dpy, config, attribute, value); + X11_RESTORE_ERROR_HANDLER + return error; +} + +static inline XVisualInfo* +wrapped_glXGetVisualFromFBConfig(Display *dpy, GLXFBConfig config) +{ + X11_SAVE_ERROR_HANDLER + XVisualInfo *vi = glXGetVisualFromFBConfig(dpy, config); + X11_RESTORE_ERROR_HANDLER + return vi; +} + +static inline void +wrapped_glXDestroyContext(Display *dpy, GLXContext ctx) +{ + X11_SAVE_ERROR_HANDLER + glXDestroyContext(dpy, ctx); + X11_RESTORE_ERROR_HANDLER +} + +static inline Bool +wrapped_glXMakeCurrent(Display *dpy, GLXDrawable drawable, GLXContext ctx) +{ + X11_SAVE_ERROR_HANDLER + Bool ok = glXMakeCurrent(dpy, drawable, ctx); + X11_RESTORE_ERROR_HANDLER + return ok; +} + +static inline const char* +wrapped_glXQueryExtensionsString(Display *dpy, int screen) +{ + X11_SAVE_ERROR_HANDLER + const char *s = glXQueryExtensionsString(dpy, screen); + X11_RESTORE_ERROR_HANDLER + return s; +} + +static inline void +wrapped_glXSwapBuffers(Display *dpy, GLXDrawable drawable) +{ + X11_SAVE_ERROR_HANDLER + glXSwapBuffers(dpy, drawable); + X11_RESTORE_ERROR_HANDLER +} |