summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
authorKonstantin Käfer <mail@kkaefer.com>2014-10-15 16:08:36 +0200
committerKonstantin Käfer <mail@kkaefer.com>2014-10-15 16:08:36 +0200
commit9ff1d9e3bdc05817d9f9de820e1d07dd17a699cd (patch)
tree2e2cfba380f6a0367229742d86317abbe6ddffe3 /common
parentc1e4d8554fac803304361550357e90d78d5acd46 (diff)
downloadqtlocation-mapboxgl-9ff1d9e3bdc05817d9f9de820e1d07dd17a699cd.tar.gz
experimental pbuffer support
[skip ci]
Diffstat (limited to 'common')
-rw-r--r--common/headless_display.cpp32
-rw-r--r--common/headless_display.hpp2
-rw-r--r--common/headless_view.cpp50
-rw-r--r--common/headless_view.hpp5
4 files changed, 60 insertions, 29 deletions
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 <sstream>
#include <string>
+#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
};