X-Git-Url: https://git.ralfj.de/gltest.git/blobdiff_plain/867982470c8f197aaa6364da1c52d530a2023dec..b0ce9e768aed86e894dcffae75e69a80c51e7b5d:/glxbackend.cpp diff --git a/glxbackend.cpp b/glxbackend.cpp index 2023954..d51e7a7 100644 --- a/glxbackend.cpp +++ b/glxbackend.cpp @@ -1,20 +1,20 @@ /* gltest - small OpenGL tearing test program - * Copyright (C) 2012-2013 Ralf Jung - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ +* Copyright (C) 2012-2013 Ralf Jung +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ #include "glxbackend.h" #include "glutil.h" @@ -31,125 +31,131 @@ // attributes for a double buffered framebuffer in RGBA format with at least 4 bits per color static int configAttribs[] = { - GLX_RENDER_TYPE, GLX_RGBA_BIT, - GLX_DOUBLEBUFFER, True, - GLX_RED_SIZE, 4, - GLX_GREEN_SIZE, 4, - GLX_BLUE_SIZE, 4, - None + GLX_RENDER_TYPE, GLX_RGBA_BIT, + GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT, + GLX_DOUBLEBUFFER, True, + GLX_RED_SIZE, 4, + GLX_GREEN_SIZE, 4, + GLX_BLUE_SIZE, 4, + None }; #ifdef CON_GL3 // attributes for a GL3 context static int contextAttribs[] = { - GLX_CONTEXT_MAJOR_VERSION_ARB, 3, - GLX_CONTEXT_MINOR_VERSION_ARB, 0, - GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB, - None + GLX_CONTEXT_MAJOR_VERSION_ARB, 3, + GLX_CONTEXT_MINOR_VERSION_ARB, 0, + GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB, + None }; #endif VisualID GLXBackend::initialize(Display *display) { - if (this->display == NULL) { // this implies that the context is also unitialized - this->display = display; - // debugging: show version information - int glxMajor, glxMinor; - glXQueryVersion(display, &glxMajor, &glxMinor); - printf("Using GLX version: %d.%d\n", glxMajor, glxMinor); - if (glxMajor < 1 || (glxMajor == 1 && glxMinor < 3)) { - // glXChooseFBConfig and glXCreateNewContext require GLX 1.3 - die("Need at least GLX 1.3 to function properly\n"); - } - // check for extension-based functions - funSwapIntervalMesa = (PFNGLXSWAPINTERVALMESAPROC)resolveGLXFunction("GLX_MESA_swap_control", "glXSwapIntervalMESA"); - funSwapIntervalExt = (PFNGLXSWAPINTERVALEXTPROC)resolveGLXFunction("GLX_EXT_swap_control", "glXSwapIntervalEXT"); - funCreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC)resolveGLXFunction("GLX_ARB_create_context", "glXCreateContextAttribsARB"); - // get the first usable framebuffer configuration - int count = 0; - GLXFBConfig *configs = glXChooseFBConfig(display, DefaultScreen(display), configAttribs, &count); - if (count < 1) { - die("Failed to choose framebuffer configuration\n"); - } - config = configs[0]; - XFree(configs); - } - // return visual ID - XVisualInfo *vi = glXGetVisualFromFBConfig(display, config); - VisualID visualid = vi->visualid; - XFree(vi); - return visualid; + if (this->display == NULL) { // this implies that the context is also unitialized + this->display = display; + // debugging: show version information + int glxMajor, glxMinor; + glXQueryVersion(display, &glxMajor, &glxMinor); + printf("Using GLX version: %d.%d\n", glxMajor, glxMinor); + if (glxMajor == 1 && glxMinor < 4) { + // glXChooseFBConfig and glXCreateNewContext require GLX 1.3; GLX_ARB_create_context requires GLX 1.4 + die("Need at least GLX 1.4 to function properly\n"); + } + // check for extension-based functions + funSwapIntervalMesa = (PFNGLXSWAPINTERVALMESAPROC)resolveGLXFunction("GLX_MESA_swap_control", "glXSwapIntervalMESA"); + funSwapIntervalExt = (PFNGLXSWAPINTERVALEXTPROC)resolveGLXFunction("GLX_EXT_swap_control", "glXSwapIntervalEXT"); + funCreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC)resolveGLXFunction("GLX_ARB_create_context", "glXCreateContextAttribsARB"); + // get the first usable framebuffer configuration + int count = 0; + GLXFBConfig *configs = glXChooseFBConfig(display, DefaultScreen(display), configAttribs, &count); + if (count < 1) { + die("Failed to choose framebuffer configuration\n"); + } + config = configs[0]; + XFree(configs); + } + // return visual ID + XVisualInfo *vi = glXGetVisualFromFBConfig(display, config); + if (vi== NULL) { + die("The GLXFBConfig I got is invalid\n"); + } + VisualID visualid = vi->visualid; + XFree(vi); + return visualid; } bool GLXBackend::haveGLXExtension(const std::string &name) { - assert(display != NULL); - std::string extensions = glXQueryExtensionsString(display, DefaultScreen(display)); - return (std::string(" "+extensions+" ").find(" "+name+" ") != std::string::npos); + assert(display != NULL); + std::string extensions = glXQueryExtensionsString(display, DefaultScreen(display)); + return (std::string(" "+extensions+" ").find(" "+name+" ") != std::string::npos); } T_proc GLXBackend::resolveGLXFunction(const char *extension, const char *function) { - if (!haveGLXExtension(extension)) return NULL; - T_proc f = glXGetProcAddress((const GLubyte*)function); - if (f) - printf("%s is supported, using it for %s\n", extension, function); - return f; + if (!haveGLXExtension(extension)) return NULL; + T_proc f = glXGetProcAddress((const GLubyte*)function); + if (f) + printf("%s is supported, using it for %s\n", extension, function); + else + printf("%s is supported, but I could not find %s\n", extension, function); + return f; } void GLXBackend::createContext(Window window) { - assert(display != NULL && context == None); - this->window = window; - // create context with that window + assert(display != NULL && context == None); + this->window = window; + // create context with that window #ifdef CON_GL1 - context = glXCreateNewContext(display, config, GLX_RGBA_TYPE, NULL, GL_TRUE); + context = glXCreateNewContext(display, config, GLX_RGBA_TYPE, NULL, GL_TRUE); #else - if (!funCreateContextAttribsARB) { - die("Cannot create GL3 context: GLX_ARB_create_context not supported\n"); - } - context = funCreateContextAttribsARB(display, config, NULL, GL_TRUE, contextAttribs); + if (!funCreateContextAttribsARB) { + die("Cannot create GL3 context: GLX_ARB_create_context not supported\n"); + } + context = funCreateContextAttribsARB(display, config, NULL, GL_TRUE, contextAttribs); #endif - if (!context) { - die("Error creating context\n"); - } - glXMakeCurrent(display, window, context); - assert(glXIsDirect(display, context)); - printf("Using GL version: %s\n", glGetString(GL_VERSION)); - // initialise GL utilities - resolveFunctionPointers((T_glGetProcAddress)glXGetProcAddress); + if (!context) { + die("Error creating context\n"); + } + glXMakeCurrent(display, window, context); + assert(glXIsDirect(display, context)); + printf("Using GL version: %s\n", glGetString(GL_VERSION)); + // initialise GL utilities + resolveFunctionPointers((T_glGetProcAddress)glXGetProcAddress); } GLXBackend::~GLXBackend() { - if (display != NULL) { - if (context != None) { - glXMakeCurrent(display, None, NULL); - glXDestroyContext(display, context); - } - } + if (display != NULL) { + if (context != None) { + glXMakeCurrent(display, None, NULL); + glXDestroyContext(display, context); + } + } } void GLXBackend::swapBuffers() const { - assert(context != None); // this implies the display is also initialized - glXSwapBuffers(display, window); + assert(context != None); // this implies the display is also initialized + glXSwapBuffers(display, window); } void GLXBackend::setSwapInterval(int i) const { - assert(context != None); - // check if swap interval value is supported - if (i < 0) { - die("Cannot set swap interval to %d, must not be negative\n", i); - } - // set it - if (funSwapIntervalExt) - funSwapIntervalExt(display, window, i); - else if (funSwapIntervalMesa) - funSwapIntervalMesa(i); - else { - die("At least one of GLX_EXT_swap_control, GLX_MESA_swap_control must be supported by the system\n"); - } + assert(context != None); + // check if swap interval value is supported + if (i < 0) { + die("Cannot set swap interval to %d, must not be negative\n", i); + } + // set it + if (funSwapIntervalExt) + funSwapIntervalExt(display, window, i); + else if (funSwapIntervalMesa) + funSwapIntervalMesa(i); + else { + die("At least one of GLX_EXT_swap_control, GLX_MESA_swap_control must be supported by the system\n"); + } }