summaryrefslogtreecommitdiff
path: root/platform/default
diff options
context:
space:
mode:
authorKonstantin Käfer <mail@kkaefer.com>2016-10-06 13:23:50 +0200
committerKonstantin Käfer <mail@kkaefer.com>2016-10-25 13:52:36 -0700
commit5cc390d694fc7510d445310d8eb9e32429a5e67b (patch)
tree7a24706f919ac3e8154be8b4ce33aed5bf42188d /platform/default
parent45f4dc0166f2d609d014d2174209fdbe1994c943 (diff)
downloadqtlocation-mapboxgl-5cc390d694fc7510d445310d8eb9e32429a5e67b.tar.gz
[core] separate Backend from View for headless rendering
Diffstat (limited to 'platform/default')
-rw-r--r--platform/default/glfw_view.cpp4
-rw-r--r--platform/default/headless_backend.cpp56
-rw-r--r--platform/default/headless_backend_glx.cpp67
-rw-r--r--platform/default/headless_display.cpp7
-rw-r--r--platform/default/headless_view.cpp72
-rw-r--r--platform/default/headless_view_glx.cpp64
6 files changed, 148 insertions, 122 deletions
diff --git a/platform/default/glfw_view.cpp b/platform/default/glfw_view.cpp
index 9c54fc4ebf..044181e8c8 100644
--- a/platform/default/glfw_view.cpp
+++ b/platform/default/glfw_view.cpp
@@ -129,6 +129,10 @@ void GLFWView::initialize(mbgl::Map *map_) {
map->addAnnotationIcon("default_marker", makeSpriteImage(22, 22, 1));
}
+void GLFWView::bind() {
+ MBGL_CHECK_ERROR(glBindFramebuffer(GL_FRAMEBUFFER, 0));
+}
+
void GLFWView::onKey(GLFWwindow *window, int key, int /*scancode*/, int action, int mods) {
GLFWView *view = reinterpret_cast<GLFWView *>(glfwGetWindowUserPointer(window));
diff --git a/platform/default/headless_backend.cpp b/platform/default/headless_backend.cpp
new file mode 100644
index 0000000000..279a7973c9
--- /dev/null
+++ b/platform/default/headless_backend.cpp
@@ -0,0 +1,56 @@
+#include <mbgl/platform/default/headless_backend.hpp>
+#include <mbgl/platform/default/headless_display.hpp>
+
+#include <cassert>
+#include <stdexcept>
+
+namespace mbgl {
+
+HeadlessBackend::HeadlessBackend() : display(std::make_shared<HeadlessDisplay>()) {
+ activate();
+}
+
+HeadlessBackend::HeadlessBackend(std::shared_ptr<HeadlessDisplay> display_)
+ : display(std::move(display_)) {
+ activate();
+}
+
+HeadlessBackend::~HeadlessBackend() {
+ deactivate();
+ destroyContext();
+}
+
+void HeadlessBackend::activate() {
+ active = true;
+
+ if (!glContext) {
+ if (!display) {
+ throw std::runtime_error("Display is not set");
+ }
+ createContext();
+ }
+
+ activateContext();
+
+ if (!extensionsLoaded) {
+ gl::InitializeExtensions(initializeExtension);
+ extensionsLoaded = true;
+ }
+}
+
+void HeadlessBackend::deactivate() {
+ deactivateContext();
+ active = false;
+}
+
+void HeadlessBackend::invalidate() {
+ assert(false);
+}
+
+void HeadlessBackend::notifyMapChange(MapChange change) {
+ if (mapChangeCallback) {
+ mapChangeCallback(change);
+ }
+}
+
+} // namespace mbgl
diff --git a/platform/default/headless_backend_glx.cpp b/platform/default/headless_backend_glx.cpp
new file mode 100644
index 0000000000..bbfd19345b
--- /dev/null
+++ b/platform/default/headless_backend_glx.cpp
@@ -0,0 +1,67 @@
+#include <mbgl/platform/default/headless_backend.hpp>
+#include <mbgl/platform/default/headless_display.hpp>
+
+#include <mbgl/platform/log.hpp>
+
+// #include <cassert>
+
+#include <GL/glx.h>
+
+namespace mbgl {
+
+gl::glProc HeadlessBackend::initializeExtension(const char* name) {
+ return glXGetProcAddress(reinterpret_cast<const GLubyte*>(name));
+}
+
+void HeadlessBackend::createContext() {
+ xDisplay = display->xDisplay;
+ fbConfigs = display->fbConfigs;
+
+ if (!glContext) {
+ // Try to create a legacy context
+ glContext = glXCreateNewContext(xDisplay, fbConfigs[0], GLX_RGBA_TYPE, None, True);
+ if (glContext) {
+ if (!glXIsDirect(xDisplay, glContext)) {
+ Log::Error(Event::OpenGL, "failed to create direct OpenGL Legacy context");
+ glXDestroyContext(xDisplay, glContext);
+ glContext = nullptr;
+ }
+ }
+ }
+
+ if (glContext == nullptr) {
+ throw std::runtime_error("Error creating GL context object.");
+ }
+
+ // Create a dummy pbuffer. We will render to framebuffers anyway, but we need a pbuffer to
+ // activate the context.
+ int pbufferAttributes[] = {
+ GLX_PBUFFER_WIDTH, 8,
+ GLX_PBUFFER_HEIGHT, 8,
+ None
+ };
+ glxPbuffer = glXCreatePbuffer(xDisplay, fbConfigs[0], pbufferAttributes);
+}
+
+void HeadlessBackend::destroyContext() {
+ if (glxPbuffer) {
+ glXDestroyPbuffer(xDisplay, glxPbuffer);
+ glxPbuffer = 0;
+ }
+
+ glXDestroyContext(xDisplay, glContext);
+}
+
+void HeadlessBackend::activateContext() {
+ if (!glXMakeContextCurrent(xDisplay, glxPbuffer, glxPbuffer, glContext)) {
+ throw std::runtime_error("Switching OpenGL context failed.\n");
+ }
+}
+
+void HeadlessBackend::deactivateContext() {
+ if (!glXMakeContextCurrent(xDisplay, 0, 0, nullptr)) {
+ throw std::runtime_error("Removing OpenGL context failed.\n");
+ }
+}
+
+} // namespace mbgl
diff --git a/platform/default/headless_display.cpp b/platform/default/headless_display.cpp
index 8b9f3fe04b..b98aef7903 100644
--- a/platform/default/headless_display.cpp
+++ b/platform/default/headless_display.cpp
@@ -1,12 +1,13 @@
#include <mbgl/platform/default/headless_display.hpp>
-#include <cstring>
-#include <stdexcept>
-
#if MBGL_USE_GLX
#include <GL/glx.h>
#endif
+#include <cstring>
+#include <stdexcept>
+#include <string>
+
namespace mbgl {
HeadlessDisplay::HeadlessDisplay() {
diff --git a/platform/default/headless_view.cpp b/platform/default/headless_view.cpp
index 95b196b746..f96b0a7f6d 100644
--- a/platform/default/headless_view.cpp
+++ b/platform/default/headless_view.cpp
@@ -1,34 +1,27 @@
#include <mbgl/platform/default/headless_view.hpp>
-#include <mbgl/platform/default/headless_display.hpp>
-#include <cassert>
+#include <mbgl/gl/gl.hpp>
+
#include <cstring>
namespace mbgl {
HeadlessView::HeadlessView(float pixelRatio_, uint16_t width, uint16_t height)
- : display(std::make_shared<HeadlessDisplay>())
- , pixelRatio(pixelRatio_)
- , dimensions({{ width, height }})
- , needsResize(true) {
-}
-
-HeadlessView::HeadlessView(std::shared_ptr<HeadlessDisplay> display_,
- float pixelRatio_,
- uint16_t width,
- uint16_t height)
- : display(std::move(display_))
- , pixelRatio(pixelRatio_)
- , dimensions({{ width, height }})
- , needsResize(true) {
+ : pixelRatio(pixelRatio_), dimensions({ { width, height } }), needsResize(true) {
}
HeadlessView::~HeadlessView() {
- activate();
clearBuffers();
- deactivate();
+}
- destroyContext();
+void HeadlessView::bind() {
+ if (needsResize) {
+ clearBuffers();
+ resizeFramebuffer();
+ needsResize = false;
+ } else {
+ bindFramebuffer();
+ }
}
void HeadlessView::resize(const uint16_t width, const uint16_t height) {
@@ -41,8 +34,6 @@ void HeadlessView::resize(const uint16_t width, const uint16_t height) {
}
PremultipliedImage HeadlessView::readStillImage(std::array<uint16_t, 2> size) {
- assert(active);
-
if (!size[0] || !size[1]) {
size[0] = dimensions[0] * pixelRatio;
size[1] = dimensions[1] * pixelRatio;
@@ -76,43 +67,4 @@ std::array<uint16_t, 2> HeadlessView::getFramebufferSize() const {
static_cast<uint16_t>(dimensions[1] * pixelRatio) }};
}
-void HeadlessView::activate() {
- active = true;
-
- if (!glContext) {
- if (!display) {
- throw std::runtime_error("Display is not set");
- }
- createContext();
- }
-
- activateContext();
-
- if (!extensionsLoaded) {
- gl::InitializeExtensions(initializeExtension);
- extensionsLoaded = true;
- }
-
- if (needsResize) {
- clearBuffers();
- resizeFramebuffer();
- needsResize = false;
- }
-}
-
-void HeadlessView::deactivate() {
- deactivateContext();
- active = false;
-}
-
-void HeadlessView::invalidate() {
- assert(false);
-}
-
-void HeadlessView::notifyMapChange(MapChange change) {
- if (mapChangeCallback) {
- mapChangeCallback(change);
- }
-}
-
} // namespace mbgl
diff --git a/platform/default/headless_view_glx.cpp b/platform/default/headless_view_glx.cpp
index 55d9313f99..08f0da8751 100644
--- a/platform/default/headless_view_glx.cpp
+++ b/platform/default/headless_view_glx.cpp
@@ -1,54 +1,14 @@
#include <mbgl/platform/default/headless_view.hpp>
-#include <mbgl/platform/default/headless_display.hpp>
-#include <mbgl/platform/log.hpp>
-#include <cassert>
+#include <mbgl/gl/gl.hpp>
-#include <GL/glx.h>
+#include <cassert>
namespace mbgl {
-gl::glProc HeadlessView::initializeExtension(const char* name) {
- return glXGetProcAddress(reinterpret_cast<const GLubyte*>(name));
-}
-
-void HeadlessView::createContext() {
- xDisplay = display->xDisplay;
- fbConfigs = display->fbConfigs;
-
- if (!glContext) {
- // Try to create a legacy context
- glContext = glXCreateNewContext(xDisplay, fbConfigs[0], GLX_RGBA_TYPE, None, True);
- if (glContext) {
- if (!glXIsDirect(xDisplay, glContext)) {
- Log::Error(Event::OpenGL, "failed to create direct OpenGL Legacy context");
- glXDestroyContext(xDisplay, glContext);
- glContext = nullptr;
- }
- }
- }
-
- if (glContext == nullptr) {
- throw std::runtime_error("Error creating GL context object.");
- }
-
- // Create a dummy pbuffer. We will render to framebuffers anyway, but we need a pbuffer to
- // activate the context.
- int pbufferAttributes[] = {
- GLX_PBUFFER_WIDTH, 8,
- GLX_PBUFFER_HEIGHT, 8,
- None
- };
- glxPbuffer = glXCreatePbuffer(xDisplay, fbConfigs[0], pbufferAttributes);
-}
-
-void HeadlessView::destroyContext() {
- if (glxPbuffer) {
- glXDestroyPbuffer(xDisplay, glxPbuffer);
- glxPbuffer = 0;
- }
-
- glXDestroyContext(xDisplay, glContext);
+void HeadlessView::bindFramebuffer() {
+ assert(fbo);
+ MBGL_CHECK_ERROR(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo));
}
void HeadlessView::resizeFramebuffer() {
@@ -93,8 +53,6 @@ void HeadlessView::resizeFramebuffer() {
}
void HeadlessView::clearBuffers() {
- assert(active);
-
MBGL_CHECK_ERROR(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0));
if (fbo) {
@@ -113,16 +71,4 @@ void HeadlessView::clearBuffers() {
}
}
-void HeadlessView::activateContext() {
- if (!glXMakeContextCurrent(xDisplay, glxPbuffer, glxPbuffer, glContext)) {
- throw std::runtime_error("Switching OpenGL context failed.\n");
- }
-}
-
-void HeadlessView::deactivateContext() {
- if (!glXMakeContextCurrent(xDisplay, 0, 0, nullptr)) {
- throw std::runtime_error("Removing OpenGL context failed.\n");
- }
-}
-
} // namespace mbgl