diff --git a/src/backend/gl/glx.c b/src/backend/gl/glx.c index 40cf9d2..51a82b2 100644 --- a/src/backend/gl/glx.c +++ b/src/backend/gl/glx.c @@ -54,8 +54,8 @@ struct _glx_data { struct glx_fbconfig_info * glx_find_fbconfig(Display *dpy, int screen, struct glx_fbconfig_criteria m) { - log_debug("Looking for FBConfig for RGBA%d%d%d%d, depth %d", m.red_size, m.blue_size, - m.green_size, m.alpha_size, m.visual_depth); + log_debug("Looking for FBConfig for RGBA%d%d%d%d, depth %d", m.red_size, + m.blue_size, m.green_size, m.alpha_size, m.visual_depth); int ncfg; // clang-format off @@ -130,15 +130,18 @@ glx_find_fbconfig(Display *dpy, int screen, struct glx_fbconfig_criteria m) { // All check passed, we are using this one. found = true; ret = cfg[i]; - glXGetFBConfigAttribChecked(dpy, cfg[i], GLX_BIND_TO_TEXTURE_TARGETS_EXT, &texture_tgts); + glXGetFBConfigAttribChecked(dpy, cfg[i], GLX_BIND_TO_TEXTURE_TARGETS_EXT, + &texture_tgts); glXGetFBConfigAttribChecked(dpy, cfg[i], GLX_Y_INVERTED_EXT, &y_inverted); // Prefer the texture format with matching alpha, with the other one as // fallback if (m.alpha_size) { - texture_fmt = rgba ? GLX_TEXTURE_FORMAT_RGBA_EXT : GLX_TEXTURE_FORMAT_RGB_EXT; + texture_fmt = rgba ? GLX_TEXTURE_FORMAT_RGBA_EXT + : GLX_TEXTURE_FORMAT_RGB_EXT; } else { - texture_fmt = rgb ? GLX_TEXTURE_FORMAT_RGB_EXT : GLX_TEXTURE_FORMAT_RGBA_EXT; + texture_fmt = + rgb ? GLX_TEXTURE_FORMAT_RGB_EXT : GLX_TEXTURE_FORMAT_RGBA_EXT; } min_cost = depthbuf + stencil + bufsize * (doublebuf + 1); } @@ -156,28 +159,6 @@ glx_find_fbconfig(Display *dpy, int screen, struct glx_fbconfig_criteria m) { return info; } -/** - * Check if a GLX extension exists. - */ -static inline bool glx_has_extension(session_t *ps, const char *ext) { - const char *glx_exts = glXQueryExtensionsString(ps->dpy, ps->scr); - if (!glx_exts) { - log_error("Failed get GLX extension list."); - return false; - } - - int len = strlen(ext); - char *found = strstr(glx_exts, ext); - if (!found) { - log_info("Missing GLX extension %s.", ext); - return false; - } - - // Make sure extension names are not crazy... - assert(found[len] == ' ' || found[len] == 0); - return true; -} - /** * @brief Release binding of a texture. */ @@ -284,7 +265,7 @@ static void *glx_init(session_t *ps) { } // Ensure GLX_EXT_texture_from_pixmap exists - if (!glx_has_extension(ps, "GLX_EXT_texture_from_pixmap")) + if (!glx_has_extension(ps->dpy, ps->scr, "GLX_EXT_texture_from_pixmap")) goto end; // Initialize GLX data structure @@ -443,7 +424,8 @@ static void *glx_prepare_win(void *backend_data, session_t *ps, win *w) { 0, }; - wd->texture.target = (GLX_TEXTURE_2D_EXT == tex_tgt ? GL_TEXTURE_2D : GL_TEXTURE_RECTANGLE); + wd->texture.target = + (GLX_TEXTURE_2D_EXT == tex_tgt ? GL_TEXTURE_2D : GL_TEXTURE_RECTANGLE); wd->texture.y_inverted = fbcfg->y_inverted; wd->glpixmap = glXCreatePixmap(ps->dpy, fbcfg->cfg, wd->pixmap, attrs); diff --git a/src/backend/gl/glx.h b/src/backend/gl/glx.h index 04cf736..4ffc3a1 100644 --- a/src/backend/gl/glx.h +++ b/src/backend/gl/glx.h @@ -63,3 +63,37 @@ x_visual_to_fbconfig_criteria(xcb_connection_t *c, xcb_visualid_t visual) { .visual_depth = depth, }; } + +/** + * Check if a GLX extension exists. + */ +static inline bool glx_has_extension(Display *dpy, int screen, const char *ext) { + const char *glx_exts = glXQueryExtensionsString(dpy, screen); + if (!glx_exts) { + log_error("Failed get GLX extension list."); + return false; + } + + long inlen = strlen(ext); + const char *curr = glx_exts; + bool match = false; + while (curr && !match) { + const char *end = strchr(curr, ' '); + if (!end) { + // Last extension string + match = strcmp(ext, curr) == 0; + } else if (end - curr == inlen) { + // Length match, do match string + match = strncmp(ext, curr, end - curr) == 0; + } + curr = end ? end + 1 : NULL; + } + + if (!match) { + log_info("Missing GLX extension %s.", ext); + } else { + log_info("Found GLX extension %s.", ext); + } + + return match; +} diff --git a/src/opengl.c b/src/opengl.c index e9115eb..b22de44 100644 --- a/src/opengl.c +++ b/src/opengl.c @@ -83,7 +83,7 @@ glx_init(session_t *ps, bool need_render) { } // Ensure GLX_EXT_texture_from_pixmap exists - if (need_render && !glx_hasglxext(ps, "GLX_EXT_texture_from_pixmap")) + if (need_render && !glx_has_extension(ps->dpy, ps->scr, "GLX_EXT_texture_from_pixmap")) goto glx_init_end; // Initialize GLX data structure diff --git a/src/opengl.h b/src/opengl.h index 52b1cd8..fc93f9e 100644 --- a/src/opengl.h +++ b/src/opengl.h @@ -26,46 +26,6 @@ #include #include -/** - * Check if a word is in string. - */ -static inline bool -wd_is_in_str(const char *haystick, const char *needle) { - if (!haystick) - return false; - - assert(*needle); - - const char *pos = haystick - 1; - while ((pos = strstr(pos + 1, needle))) { - // Continue if it isn't a word boundary - if (((pos - haystick) && !isspace(*(pos - 1))) - || (strlen(pos) > strlen(needle) && !isspace(pos[strlen(needle)]))) - continue; - return true; - } - - return false; -} - -/** - * Check if a GLX extension exists. - */ -static inline bool -glx_hasglxext(session_t *ps, const char *ext) { - const char *glx_exts = glXQueryExtensionsString(ps->dpy, ps->scr); - if (!glx_exts) { - log_error("Failed get GLX extension list."); - return false; - } - - bool found = wd_is_in_str(glx_exts, ext); - if (!found) - log_info("Missing GLX extension %s.", ext); - - return found; -} - bool glx_dim_dst(session_t *ps, int dx, int dy, int width, int height, float z, GLfloat factor, const region_t *reg_tgt); diff --git a/src/vsync.c b/src/vsync.c index 1869147..db5d289 100644 --- a/src/vsync.c +++ b/src/vsync.c @@ -9,6 +9,7 @@ #include "log.h" #ifdef CONFIG_OPENGL +#include "backend/gl/glx.h" #include "opengl.h" #endif @@ -89,7 +90,7 @@ vsync_opengl_init(session_t *ps) { if (!ensure_glx_context(ps)) return false; - if (!glx_hasglxext(ps, "GLX_SGI_video_sync")) { + if (!glx_has_extension(ps->dpy, ps->scr, "GLX_SGI_video_sync")) { log_error("Your driver doesn't support SGI_video_sync, giving up."); return false; } @@ -119,7 +120,7 @@ vsync_opengl_oml_init(session_t *ps) { if (!ensure_glx_context(ps)) return false; - if (!glx_hasglxext(ps, "GLX_OML_sync_control")) { + if (!glx_has_extension(ps->dpy, ps->scr, "GLX_OML_sync_control")) { log_error("Your driver doesn't support OML_sync_control, giving up."); return false; } @@ -150,10 +151,10 @@ vsync_opengl_swc_swap_interval(session_t *ps, unsigned int interval) { return false; if (!ps->psglx->glXSwapIntervalProc && !ps->psglx->glXSwapIntervalMESAProc) { - if (glx_hasglxext(ps, "GLX_MESA_swap_control")) { + if (glx_has_extension(ps->dpy, ps->scr, "GLX_MESA_swap_control")) { ps->psglx->glXSwapIntervalMESAProc = (f_SwapIntervalMESA) glXGetProcAddress ((const GLubyte *) "glXSwapIntervalMESA"); - } else if (glx_hasglxext(ps, "GLX_SGI_swap_control")) { + } else if (glx_has_extension(ps->dpy, ps->scr, "GLX_SGI_swap_control")) { ps->psglx->glXSwapIntervalProc = (f_SwapIntervalSGI) glXGetProcAddress ((const GLubyte *) "glXSwapIntervalSGI"); } else {