From 9ff1d9e3bdc05817d9f9de820e1d07dd17a699cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20Ka=CC=88fer?= Date: Wed, 15 Oct 2014 16:08:36 +0200 Subject: experimental pbuffer support [skip ci] --- common/headless_display.cpp | 32 ++++++++++++++++++++--------- common/headless_display.hpp | 2 +- common/headless_view.cpp | 50 +++++++++++++++++++++++++++++++-------------- common/headless_view.hpp | 5 ++--- 4 files changed, 60 insertions(+), 29 deletions(-) (limited to 'common') diff --git a/common/headless_display.cpp b/common/headless_display.cpp index bbb1c10f51..a938347527 100644 --- a/common/headless_display.cpp +++ b/common/headless_display.cpp @@ -27,30 +27,42 @@ HeadlessDisplay::HeadlessDisplay() { if (!XInitThreads()) { throw std::runtime_error("Failed to XInitThreads"); } - - x_display = XOpenDisplay(0); + x_display = XOpenDisplay(nullptr); if (x_display == nullptr) { throw std::runtime_error("Failed to open X display"); } + const char *extensions = (char *)glXQueryServerString(x_display, DefaultScreen(x_display), GLX_EXTENSIONS); + if (!extensions) { + throw std::runtime_error("Cannot read GLX extensions"); + } + if (!strstr(extensions,"GLX_SGIX_fbconfig")) { + throw std::runtime_error("Extension GLX_SGIX_fbconfig was not found"); + } + if (!strstr(extensions, "GLX_SGIX_pbuffer")) { + throw std::runtime_error("Cannot find glXCreateContextAttribsARB"); + } + + static int pixelFormat[] = { - GLX_RGBA, - GLX_DOUBLEBUFFER, + GLX_DOUBLEBUFFER, False, GLX_RED_SIZE, 8, GLX_GREEN_SIZE, 8, GLX_BLUE_SIZE, 8, GLX_ALPHA_SIZE, 8, GLX_DEPTH_SIZE, 24, GLX_STENCIL_SIZE, 8, - 0 + None }; - x_info = glXChooseVisual(x_display, DefaultScreen(x_display), pixelFormat); - - if (x_info == nullptr) { - throw std::runtime_error("Error pixel format"); + int configs = 0; + fb_configs = glXChooseFBConfig(x_display, DefaultScreen(x_display), pixelFormat, &configs); + if (configs <= 0) { + throw std::runtime_error("No Framebuffer configurations"); } + + XSync(x_display, False); #endif } @@ -60,7 +72,7 @@ HeadlessDisplay::~HeadlessDisplay() { #endif #if MBGL_USE_GLX - XFree(x_info); + XFree(fb_configs); XCloseDisplay(x_display); #endif } diff --git a/common/headless_display.hpp b/common/headless_display.hpp index 0eb41911ee..5b33fd6990 100644 --- a/common/headless_display.hpp +++ b/common/headless_display.hpp @@ -16,7 +16,7 @@ public: #if MBGL_USE_GLX Display *x_display = nullptr; - XVisualInfo *x_info = nullptr; + GLXFBConfig *fb_configs = nullptr; #endif }; diff --git a/common/headless_view.cpp b/common/headless_view.cpp index c2084ac90d..dd62d9d23e 100644 --- a/common/headless_view.cpp +++ b/common/headless_view.cpp @@ -5,6 +5,11 @@ #include #include +#if MBGL_USE_GLX +typedef GLXContext (*glXCreateContextAttribsARBProc)(Display *, GLXFBConfig, GLXContext, Bool, const int *); +static glXCreateContextAttribsARBProc glXCreateContextAttribsARB = nullptr; +#endif + namespace mbgl { HeadlessView::HeadlessView() @@ -31,13 +36,29 @@ void HeadlessView::createContext() { #endif #if MBGL_USE_GLX + if (glXCreateContextAttribsARB == nullptr) { + glXCreateContextAttribsARB = (glXCreateContextAttribsARBProc)glXGetProcAddressARB((const GLubyte *)"glXCreateContextAttribsARB"); + } + if (glXCreateContextAttribsARB == nullptr) { + throw std::runtime_error("Cannot find glXCreateContextAttribsARB"); + } + x_display = display_->x_display; - x_info = display_->x_info; + fb_configs = display_->fb_configs; - gl_context = glXCreateContext(x_display, x_info, 0, GL_TRUE); + + int attributes[] = { + GLX_CONTEXT_MAJOR_VERSION_ARB, 2, + GLX_CONTEXT_MINOR_VERSION_ARB, 1, + GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_DEBUG_BIT_ARB, + GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, + None + }; + gl_context = glXCreateContextAttribsARB(x_display, fb_configs[0], 0, True, attributes); if (gl_context == nullptr) { throw std::runtime_error("Error creating GL context object"); } + #endif } @@ -92,8 +113,12 @@ void HeadlessView::resize(uint16_t width, uint16_t height, float pixelRatio) { #endif #if MBGL_USE_GLX - x_pixmap = XCreatePixmap(x_display, DefaultRootWindow(x_display), w, h, 32); - glx_pixmap = glXCreateGLXPixmap(x_display, x_info, x_pixmap); + int attributes[] = { + GLX_PBUFFER_WIDTH, w, + GLX_PBUFFER_HEIGHT, h, + None + }; + GLXPbuffer pbuffer = glXCreatePbuffer(x_display, fg_configs[0], attributes); #endif } @@ -135,17 +160,12 @@ void HeadlessView::clear_buffers() { #endif #if MBGL_USE_GLX - if (glx_pixmap) { - glXDestroyGLXPixmap(x_display, glx_pixmap); - glx_pixmap = 0; - } + make_inactive(); - if (x_pixmap) { - XFreePixmap(x_display, x_pixmap); - x_pixmap = 0; + if (glx_pbuffer) { + glXDestroyPbuffer(x_display, glx_pbuffer); + glx_pbuffer = 0; } - - make_inactive(); #endif } @@ -178,7 +198,7 @@ void HeadlessView::make_active() { #endif #if MBGL_USE_GLX - if (!glXMakeCurrent(x_display, glx_pixmap, gl_context)) { + if (!glXMakeContextCurrent(x_display, glx_pbuffer, glx_pbuffer, gl_context)) { throw std::runtime_error("Switching OpenGL context failed\n"); } #endif @@ -193,7 +213,7 @@ void HeadlessView::make_inactive() { #endif #if MBGL_USE_GLX - if (!glXMakeCurrent(x_display, 0, NULL)) { + if (!glXMakeContextCurrent(x_display, 0, 0, nullptr)) { throw std::runtime_error("Removing OpenGL context failed\n"); } #endif diff --git a/common/headless_view.hpp b/common/headless_view.hpp index d2fe75382a..9ba25c73f0 100644 --- a/common/headless_view.hpp +++ b/common/headless_view.hpp @@ -53,10 +53,9 @@ private: #if MBGL_USE_GLX Display *x_display = nullptr; - XVisualInfo *x_info = nullptr; + GLXFBConfig *fb_configs = nullptr; GLXContext gl_context = nullptr; - Pixmap x_pixmap = 0; - GLXPixmap glx_pixmap = 0; + GLXPBuffer glx_pbuffer = 0; #endif }; -- cgit v1.2.1