diff options
-rw-r--r-- | include/mbgl/platform/default/headless_display.hpp | 19 | ||||
-rw-r--r-- | platform/darwin/src/headless_backend_cgl.cpp | 2 | ||||
-rw-r--r-- | platform/darwin/src/headless_display_cgl.cpp | 52 | ||||
-rw-r--r-- | platform/default/headless_display.cpp | 75 | ||||
-rw-r--r-- | platform/linux/config.cmake | 5 | ||||
-rw-r--r-- | platform/linux/src/headless_backend_glx.cpp (renamed from platform/default/headless_backend_glx.cpp) | 4 | ||||
-rw-r--r-- | platform/linux/src/headless_display_glx.cpp | 79 | ||||
-rw-r--r-- | platform/macos/config.cmake | 2 |
8 files changed, 148 insertions, 90 deletions
diff --git a/include/mbgl/platform/default/headless_display.hpp b/include/mbgl/platform/default/headless_display.hpp index f43e61340f..433df952fd 100644 --- a/include/mbgl/platform/default/headless_display.hpp +++ b/include/mbgl/platform/default/headless_display.hpp @@ -2,12 +2,7 @@ #include <mbgl/gl/implementation.hpp> -#if MBGL_USE_CGL -#include <OpenGL/OpenGL.h> -#elif MBGL_USE_GLX -typedef struct _XDisplay Display; -typedef struct __GLXFBConfigRec* GLXFBConfig; -#endif +#include <memory> namespace mbgl { @@ -16,14 +11,12 @@ public: HeadlessDisplay(); ~HeadlessDisplay(); -#if MBGL_USE_CGL - CGLPixelFormatObj pixelFormat = nullptr; -#endif + template <typename DisplayAttribute> + DisplayAttribute attribute() const; -#if MBGL_USE_GLX - Display *xDisplay = nullptr; - GLXFBConfig *fbConfigs = nullptr; -#endif +private: + class Impl; + std::unique_ptr<Impl> impl; }; } // namespace mbgl diff --git a/platform/darwin/src/headless_backend_cgl.cpp b/platform/darwin/src/headless_backend_cgl.cpp index 4ca567f55c..081156e8aa 100644 --- a/platform/darwin/src/headless_backend_cgl.cpp +++ b/platform/darwin/src/headless_backend_cgl.cpp @@ -22,7 +22,7 @@ gl::glProc HeadlessBackend::initializeExtension(const char* name) { } void HeadlessBackend::createContext() { - CGLError error = CGLCreateContext(display->pixelFormat, nullptr, &glContext); + CGLError error = CGLCreateContext(display->attribute<CGLPixelFormatObj>(), nullptr, &glContext); if (error != kCGLNoError) { throw std::runtime_error(std::string("Error creating GL context object:") + CGLErrorString(error) + "\n"); diff --git a/platform/darwin/src/headless_display_cgl.cpp b/platform/darwin/src/headless_display_cgl.cpp new file mode 100644 index 0000000000..e2907a80c9 --- /dev/null +++ b/platform/darwin/src/headless_display_cgl.cpp @@ -0,0 +1,52 @@ +#include <mbgl/platform/default/headless_display.hpp> + +#include <OpenGL/OpenGL.h> + +#include <stdexcept> +#include <string> + +namespace mbgl { + +class HeadlessDisplay::Impl { +public: + Impl(); + ~Impl(); + CGLPixelFormatObj pixelFormat = nullptr; +}; + +HeadlessDisplay::Impl::Impl() { + // TODO: test if OpenGL 4.1 with GL_ARB_ES2_compatibility is supported + // If it is, use kCGLOGLPVersion_3_2_Core and enable that extension. + CGLPixelFormatAttribute attributes[] = { + kCGLPFAOpenGLProfile, + static_cast<CGLPixelFormatAttribute>(kCGLOGLPVersion_Legacy), + static_cast<CGLPixelFormatAttribute>(0) + }; + + GLint num; + CGLError error = CGLChoosePixelFormat(attributes, &pixelFormat, &num); + if (error != kCGLNoError) { + throw std::runtime_error(std::string("Error choosing pixel format:") + CGLErrorString(error) + "\n"); + } + if (num <= 0) { + throw std::runtime_error("No pixel formats found."); + } +} + +HeadlessDisplay::Impl::~Impl() { + CGLDestroyPixelFormat(pixelFormat); +} + +template <> +CGLPixelFormatObj HeadlessDisplay::attribute() const { + return impl->pixelFormat; +} + +HeadlessDisplay::HeadlessDisplay() + : impl(std::make_unique<Impl>()) { +} + +HeadlessDisplay::~HeadlessDisplay() { +} + +} // namespace mbgl diff --git a/platform/default/headless_display.cpp b/platform/default/headless_display.cpp index b98aef7903..4ab111f775 100644 --- a/platform/default/headless_display.cpp +++ b/platform/default/headless_display.cpp @@ -1,82 +1,15 @@ #include <mbgl/platform/default/headless_display.hpp> -#if MBGL_USE_GLX -#include <GL/glx.h> -#endif - -#include <cstring> -#include <stdexcept> -#include <string> - namespace mbgl { -HeadlessDisplay::HeadlessDisplay() { -#if MBGL_USE_CGL - // TODO: test if OpenGL 4.1 with GL_ARB_ES2_compatibility is supported - // If it is, use kCGLOGLPVersion_3_2_Core and enable that extension. - CGLPixelFormatAttribute attributes[] = { - kCGLPFAOpenGLProfile, - static_cast<CGLPixelFormatAttribute>(kCGLOGLPVersion_Legacy), - static_cast<CGLPixelFormatAttribute>(0) - }; - - GLint num; - CGLError error = CGLChoosePixelFormat(attributes, &pixelFormat, &num); - if (error != kCGLNoError) { - throw std::runtime_error(std::string("Error choosing pixel format:") + CGLErrorString(error) + "\n"); - } - if (num <= 0) { - throw std::runtime_error("No pixel formats found."); - } -#endif - -#if MBGL_USE_GLX - if (!XInitThreads()) { - throw std::runtime_error("Failed to XInitThreads."); - } +class HeadlessDisplay::Impl {}; - xDisplay = XOpenDisplay(nullptr); - if (xDisplay == nullptr) { - throw std::runtime_error("Failed to open X display."); - } - - const char *extensions = reinterpret_cast<const char *>(glXQueryServerString(xDisplay, DefaultScreen(xDisplay), 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."); - } - - // We're creating a dummy pbuffer anyway that we're not using. - static int pixelFormat[] = { - GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT, - None - }; - - int configs = 0; - fbConfigs = glXChooseFBConfig(xDisplay, DefaultScreen(xDisplay), pixelFormat, &configs); - if (fbConfigs == nullptr) { - throw std::runtime_error("Failed to glXChooseFBConfig."); - } - if (configs <= 0) { - throw std::runtime_error("No Framebuffer configurations."); - } -#endif +HeadlessDisplay::HeadlessDisplay() { + // no-op } HeadlessDisplay::~HeadlessDisplay() { -#if MBGL_USE_CGL - CGLDestroyPixelFormat(pixelFormat); -#endif - -#if MBGL_USE_GLX - XFree(fbConfigs); - XCloseDisplay(xDisplay); -#endif + // no-op } } // namespace mbgl diff --git a/platform/linux/config.cmake b/platform/linux/config.cmake index 8acb6e7e14..76be2dddc3 100644 --- a/platform/linux/config.cmake +++ b/platform/linux/config.cmake @@ -14,7 +14,8 @@ include(cmake/loop-uv.cmake) macro(use_glx_backend _TARGET) target_sources(${_TARGET} - PRIVATE platform/default/headless_backend_glx.cpp + PRIVATE platform/linux/src/headless_backend_glx.cpp + PRIVATE platform/linux/src/headless_display_glx.cpp ) target_link_libraries(${_TARGET} @@ -26,6 +27,7 @@ endmacro() macro(use_osmesa_backend _TARGET) target_sources(${_TARGET} PRIVATE platform/default/headless_backend_osmesa.cpp + PRIVATE platform/default/headless_display.cpp ) target_add_mason_package(${_TARGET} @@ -70,7 +72,6 @@ macro(mbgl_platform_core) # Headless view PRIVATE platform/default/headless_backend.cpp - PRIVATE platform/default/headless_display.cpp PRIVATE platform/default/offscreen_view.cpp # Thread pool diff --git a/platform/default/headless_backend_glx.cpp b/platform/linux/src/headless_backend_glx.cpp index bbfd19345b..929eb73f5a 100644 --- a/platform/default/headless_backend_glx.cpp +++ b/platform/linux/src/headless_backend_glx.cpp @@ -14,8 +14,8 @@ gl::glProc HeadlessBackend::initializeExtension(const char* name) { } void HeadlessBackend::createContext() { - xDisplay = display->xDisplay; - fbConfigs = display->fbConfigs; + xDisplay = display->attribute<Display*>(); + fbConfigs = display->attribute<GLXFBConfig*>(); if (!glContext) { // Try to create a legacy context diff --git a/platform/linux/src/headless_display_glx.cpp b/platform/linux/src/headless_display_glx.cpp new file mode 100644 index 0000000000..2023d4dcd2 --- /dev/null +++ b/platform/linux/src/headless_display_glx.cpp @@ -0,0 +1,79 @@ +#include <mbgl/platform/default/headless_display.hpp> + +#include <GL/glx.h> + +#include <cstring> +#include <stdexcept> +#include <string> + +namespace mbgl { + +class HeadlessDisplay::Impl { +public: + Impl(); + ~Impl(); + + Display* xDisplay = nullptr; + GLXFBConfig* fbConfigs = nullptr; +}; + +HeadlessDisplay::Impl::Impl() { + if (!XInitThreads()) { + throw std::runtime_error("Failed to XInitThreads."); + } + + xDisplay = XOpenDisplay(nullptr); + if (xDisplay == nullptr) { + throw std::runtime_error("Failed to open X display."); + } + + const char *extensions = reinterpret_cast<const char *>(glXQueryServerString(xDisplay, DefaultScreen(xDisplay), 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."); + } + + // We're creating a dummy pbuffer anyway that we're not using. + static int pixelFormat[] = { + GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT, + None + }; + + int configs = 0; + fbConfigs = glXChooseFBConfig(xDisplay, DefaultScreen(xDisplay), pixelFormat, &configs); + if (fbConfigs == nullptr) { + throw std::runtime_error("Failed to glXChooseFBConfig."); + } + if (configs <= 0) { + throw std::runtime_error("No Framebuffer configurations."); + } +} + +HeadlessDisplay::Impl::~Impl() { + XFree(fbConfigs); + XCloseDisplay(xDisplay); +} + +template <> +Display* HeadlessDisplay::attribute() const { + return impl->xDisplay; +} + +template <> +GLXFBConfig* HeadlessDisplay::attribute() const { + return impl->fbConfigs; +} + +HeadlessDisplay::HeadlessDisplay() + : impl(std::make_unique<Impl>()) { +} + +HeadlessDisplay::~HeadlessDisplay() { +} + +} // namespace mbgl diff --git a/platform/macos/config.cmake b/platform/macos/config.cmake index 27bf555ec6..b1f31d4ed9 100644 --- a/platform/macos/config.cmake +++ b/platform/macos/config.cmake @@ -36,8 +36,8 @@ macro(mbgl_platform_core) # Headless view PRIVATE platform/darwin/src/headless_backend_cgl.cpp + PRIVATE platform/darwin/src/headless_display_cgl.cpp PRIVATE platform/default/headless_backend.cpp - PRIVATE platform/default/headless_display.cpp PRIVATE platform/default/offscreen_view.cpp # Thread pool |