From 5dcf7ca18ef1cfdf3f91afd08da73e317eeda67a Mon Sep 17 00:00:00 2001 From: Bruno de Oliveira Abinader Date: Thu, 3 Nov 2016 01:59:24 +0200 Subject: [linux] Added OSMesa headless backend --- CMakeLists.txt | 5 +++ Makefile | 3 +- include/mbgl/gl/implementation.hpp | 2 + include/mbgl/platform/default/headless_backend.hpp | 7 ++++ platform/default/headless_backend_osmesa.cpp | 47 ++++++++++++++++++++++ platform/linux/config.cmake | 31 ++++++++++++-- 6 files changed, 91 insertions(+), 4 deletions(-) create mode 100644 platform/default/headless_backend_osmesa.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 9169dea812..5e99f8031e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,11 +14,16 @@ include(.mason/mason.cmake) option(WITH_CXX11ABI "Use cxx11abi mason packages" OFF) option(WITH_COVERAGE "Enable coverage reports" OFF) +option(WITH_OSMESA "Use OSMesa headless backend" OFF) if(WITH_CXX11ABI) set(MASON_CXXABI_SUFFIX -cxx11abi) endif() +if(WITH_OSMESA) + add_compile_options(-D__OSMESA__) +endif() + mason_use(geometry VERSION 0.8.0 HEADER_ONLY) mason_use(variant VERSION 1.1.0 HEADER_ONLY) mason_use(unique_resource VERSION dev HEADER_ONLY) diff --git a/Makefile b/Makefile index 1415d4f070..29acc367f4 100644 --- a/Makefile +++ b/Makefile @@ -291,7 +291,8 @@ $(LINUX_BUILD): $(BUILD_DEPS) -DCMAKE_BUILD_TYPE=$(BUILDTYPE) \ -DCMAKE_EXPORT_COMPILE_COMMANDS=ON \ -DWITH_CXX11ABI=$(shell scripts/check-cxx11abi.sh) \ - -DWITH_COVERAGE=${WITH_COVERAGE}) + -DWITH_COVERAGE=${WITH_COVERAGE} \ + -DWITH_OSMESA=${WITH_OSMESA}) .PHONY: linux linux: glfw-app render offline diff --git a/include/mbgl/gl/implementation.hpp b/include/mbgl/gl/implementation.hpp index 4e3a3e51c7..a0101085fa 100644 --- a/include/mbgl/gl/implementation.hpp +++ b/include/mbgl/gl/implementation.hpp @@ -9,6 +9,8 @@ #else #define MBGL_USE_CGL 1 #endif +#elif defined(__OSMESA__) + #define MBGL_USE_OSMESA 1 #else #define MBGL_USE_GLX 1 #endif diff --git a/include/mbgl/platform/default/headless_backend.hpp b/include/mbgl/platform/default/headless_backend.hpp index 2f4886a365..b6c654943f 100644 --- a/include/mbgl/platform/default/headless_backend.hpp +++ b/include/mbgl/platform/default/headless_backend.hpp @@ -12,6 +12,8 @@ typedef struct __GLXcontextRec* GLXContext; typedef struct __GLXFBConfigRec* GLXFBConfig; typedef long unsigned int XID; typedef XID GLXPbuffer; +#elif MBGL_USE_OSMESA +#include #endif #include @@ -71,6 +73,11 @@ private: GLXPbuffer glxPbuffer = 0; #endif +#if MBGL_USE_OSMESA + OSMesaContext glContext = nullptr; + GLubyte fakeBuffer = 0; +#endif + std::function mapChangeCallback; }; diff --git a/platform/default/headless_backend_osmesa.cpp b/platform/default/headless_backend_osmesa.cpp new file mode 100644 index 0000000000..e0e385fcc6 --- /dev/null +++ b/platform/default/headless_backend_osmesa.cpp @@ -0,0 +1,47 @@ +#include +#include + +namespace mbgl { + +gl::glProc HeadlessBackend::initializeExtension(const char* name) { + return OSMesaGetProcAddress(name); +} + +void HeadlessBackend::createContext() { + if (glContext == nullptr) { +#if OSMESA_MAJOR_VERSION * 100 + OSMESA_MINOR_VERSION >= 305 + glContext = OSMesaCreateContextExt(OSMESA_RGBA, 16, 0, 0, nullptr); +#else + glContext = OSMesaCreateContext(OSMESA_RGBA, nullptr); +#endif + if (glContext == nullptr) { + Log::Error(Event::OpenGL, "failed to create OSMesa context"); + } + } + + if (glContext == nullptr) { + throw std::runtime_error("Error creating GL context object."); + } +} + +void HeadlessBackend::destroyContext() { + if (glContext) { + if (glContext != OSMesaGetCurrentContext()) { + activateContext(); + } + OSMesaDestroyContext(glContext); + glContext = nullptr; + } +} + +void HeadlessBackend::activateContext() { + if (!OSMesaMakeCurrent(glContext, &fakeBuffer, GL_UNSIGNED_BYTE, 1, 1)) { + throw std::runtime_error("Switching OpenGL context failed.\n"); + } +} + +void HeadlessBackend::deactivateContext() { + // no-op. +} + +} // namespace mbgl diff --git a/platform/linux/config.cmake b/platform/linux/config.cmake index 6bde3136f2..e8de737835 100644 --- a/platform/linux/config.cmake +++ b/platform/linux/config.cmake @@ -1,4 +1,5 @@ mason_use(glfw VERSION 3.2.1) +mason_use(mesa VERSION 13.0.0) mason_use(boost_libprogram_options VERSION 1.60.0) mason_use(sqlite VERSION 3.14.2) mason_use(libuv VERSION 1.9.1) @@ -11,7 +12,34 @@ mason_use(benchmark VERSION 1.0.0) include(cmake/loop-uv.cmake) +macro(use_glx_backend _TARGET) + target_sources(${_TARGET} + PRIVATE platform/default/headless_backend_glx.cpp + ) + + target_link_libraries(${_TARGET} + PUBLIC -lGL + PUBLIC -lX11 + ) +endmacro() + +macro(use_osmesa_backend _TARGET) + target_sources(${_TARGET} + PRIVATE platform/default/headless_backend_osmesa.cpp + ) + + target_add_mason_package(${_TARGET} + PUBLIC mesa + ) +endmacro() + macro(mbgl_platform_core) + if (WITH_OSMESA) + use_osmesa_backend(mbgl-core) + else() + use_glx_backend(mbgl-core) + endif() + target_sources(mbgl-core # File source PRIVATE platform/default/asset_file_source.cpp @@ -41,7 +69,6 @@ macro(mbgl_platform_core) PRIVATE platform/default/webp_reader.cpp # Headless view - PRIVATE platform/default/headless_backend_glx.cpp PRIVATE platform/default/headless_backend.cpp PRIVATE platform/default/headless_display.cpp PRIVATE platform/default/offscreen_view.cpp @@ -63,8 +90,6 @@ macro(mbgl_platform_core) target_link_libraries(mbgl-core PUBLIC -lz PUBLIC -lcurl - PUBLIC -lGL - PUBLIC -lX11 ) endmacro() -- cgit v1.2.1