summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common/glfw_view.cpp9
-rw-r--r--common/glfw_view.hpp1
-rw-r--r--common/headless_view.cpp23
-rw-r--r--common/headless_view.hpp1
-rw-r--r--include/mbgl/map/map.hpp3
-rw-r--r--include/mbgl/map/view.hpp4
-rw-r--r--include/mbgl/renderer/painter.hpp2
-rw-r--r--src/map/map.cpp14
-rw-r--r--src/renderer/painter.cpp20
-rw-r--r--test/headless.cpp3
10 files changed, 68 insertions, 12 deletions
diff --git a/common/glfw_view.cpp b/common/glfw_view.cpp
index f53090a000..0908786bb6 100644
--- a/common/glfw_view.cpp
+++ b/common/glfw_view.cpp
@@ -8,7 +8,10 @@ GLFWView::GLFWView(bool fullscreen) : fullscreen(fullscreen) {
#endif
}
-GLFWView::~GLFWView() { glfwTerminate(); }
+GLFWView::~GLFWView() {
+ map->terminate();
+ glfwTerminate();
+}
void GLFWView::initialize(mbgl::Map *map) {
View::initialize(map);
@@ -192,6 +195,10 @@ void GLFWView::make_active() {
glfwMakeContextCurrent(window);
}
+void GLFWView::make_inactive() {
+ glfwMakeContextCurrent(nullptr);
+}
+
void GLFWView::swap() {
glfwPostEmptyEvent();
diff --git a/common/glfw_view.hpp b/common/glfw_view.hpp
index d2f6872fc7..04085f7750 100644
--- a/common/glfw_view.hpp
+++ b/common/glfw_view.hpp
@@ -17,6 +17,7 @@ public:
void initialize(mbgl::Map *map);
void swap();
void make_active();
+ void make_inactive();
void notify_map_change(mbgl::MapChange change, mbgl::timestamp delay = 0);
static void key(GLFWwindow *window, int key, int scancode, int action, int mods);
diff --git a/common/headless_view.cpp b/common/headless_view.cpp
index 42d595310d..37982e6891 100644
--- a/common/headless_view.cpp
+++ b/common/headless_view.cpp
@@ -109,10 +109,7 @@ void HeadlessView::resize(uint16_t width, uint16_t height, float pixelRatio) {
#if MBGL_USE_GLX
x_pixmap = XCreatePixmap(x_display, DefaultRootWindow(x_display), width, height, 32);
glx_pixmap = glXCreateGLXPixmap(x_display, x_info, x_pixmap);
-
- make_active();
#endif
-
}
void HeadlessView::clear_buffers() {
@@ -135,6 +132,8 @@ void HeadlessView::clear_buffers() {
glDeleteRenderbuffersEXT(1, &fbo_depth_stencil);
fbo_depth_stencil = 0;
}
+
+ make_inactive();
#endif
#if MBGL_USE_GLX
@@ -151,14 +150,13 @@ void HeadlessView::clear_buffers() {
}
HeadlessView::~HeadlessView() {
- clear_buffers();
+ make_inactive();
#if MBGL_USE_CGL
CGLDestroyContext(gl_context);
#endif
#if MBGL_USE_GLX
- glXMakeCurrent(x_display, None, NULL);
glXDestroyContext(x_display, gl_context);
XFree(x_info);
XCloseDisplay(x_display);
@@ -184,6 +182,21 @@ void HeadlessView::make_active() {
#endif
}
+void HeadlessView::make_inactive() {
+#if MBGL_USE_CGL
+ CGLError error = CGLSetCurrentContext(nullptr);
+ if (error) {
+ fprintf(stderr, "Removing OpenGL context failed\n");
+ }
+#endif
+
+#if MBGL_USE_GLX
+ if (!glXMakeCurrent(x_display, None, NULL)) {
+ fprintf(stderr, "Removing OpenGL context failed\n");
+ }
+#endif
+}
+
void HeadlessView::swap() {}
unsigned int HeadlessView::root_fbo() {
diff --git a/common/headless_view.hpp b/common/headless_view.hpp
index a8ce4aa325..c8475a2516 100644
--- a/common/headless_view.hpp
+++ b/common/headless_view.hpp
@@ -23,6 +23,7 @@ public:
void notify_map_change(MapChange change, timestamp delay = 0);
void make_active();
+ void make_inactive();
void swap();
unsigned int root_fbo();
diff --git a/include/mbgl/map/map.hpp b/include/mbgl/map/map.hpp
index 4c5952a2c1..ac33dba0ef 100644
--- a/include/mbgl/map/map.hpp
+++ b/include/mbgl/map/map.hpp
@@ -53,6 +53,9 @@ public:
// Triggers a cleanup that releases resources.
void cleanup();
+ // Releases resources immediately
+ void terminate();
+
// Controls buffer swapping.
bool needsSwap();
void swapped();
diff --git a/include/mbgl/map/view.hpp b/include/mbgl/map/view.hpp
index 92d60d4d02..3e2f1a4b5a 100644
--- a/include/mbgl/map/view.hpp
+++ b/include/mbgl/map/view.hpp
@@ -35,6 +35,10 @@ public:
// renderer setup since the render thread doesn't switch the contexts.
virtual void make_active() = 0;
+ // Called from the render thread. Makes the GL context inactive in the current
+ // thread. This is called once just before the rendering thread terminates.
+ virtual void make_inactive() = 0;
+
// Returns the base framebuffer object, if any, and 0 if using the system
// provided framebuffer.
virtual unsigned int root_fbo() {
diff --git a/include/mbgl/renderer/painter.hpp b/include/mbgl/renderer/painter.hpp
index 75529d1136..15331b9b67 100644
--- a/include/mbgl/renderer/painter.hpp
+++ b/include/mbgl/renderer/painter.hpp
@@ -63,6 +63,7 @@ public:
// lazy initialization) in case rendering continues.
void cleanup();
+ void terminate();
// Renders the backdrop of the OpenGL view. This also paints in areas where we don't have any
// tiles whatsoever.
@@ -123,6 +124,7 @@ public:
private:
void setupShaders();
+ void deleteShaders();
mat4 translatedMatrix(const mat4& matrix, const std::array<float, 2> &translation, const Tile::ID &id, TranslateAnchorType anchor);
void prepareTile(const Tile& tile);
diff --git a/src/map/map.cpp b/src/map/map.cpp
index 1399b97ee2..6db6fa2808 100644
--- a/src/map/map.cpp
+++ b/src/map/map.cpp
@@ -111,7 +111,6 @@ void Map::run() {
// If the map rendering wasn't started asynchronously, we perform one render
// *after* all events have been processed.
if (!async) {
- prepare();
render();
}
}
@@ -147,10 +146,13 @@ void Map::cleanup() {
void Map::cleanup(uv_async_t *async, int status) {
Map *map = static_cast<Map *>(async->data);
- map->view.make_active();
map->painter.cleanup();
}
+void Map::terminate() {
+ painter.terminate();
+}
+
void Map::render(uv_async_t *async, int status) {
Map *map = static_cast<Map *>(async->data);
@@ -184,8 +186,6 @@ void Map::terminate(uv_async_t *async, int status) {
#pragma mark - Setup
void Map::setup() {
- view.make_active();
-
painter.setup();
}
@@ -520,8 +520,6 @@ void Map::updateRenderState() {
}
void Map::prepare() {
- view.make_active();
-
// Update transform transitions.
animationTime = util::now();
if (transform.needsTransition()) {
@@ -542,6 +540,8 @@ void Map::prepare() {
}
void Map::render() {
+ view.make_active();
+
#if defined(DEBUG)
std::vector<std::string> debug;
#endif
@@ -576,6 +576,8 @@ void Map::render() {
}
glFlush();
+
+ view.make_inactive();
}
void Map::renderLayers(std::shared_ptr<StyleLayerGroup> group) {
diff --git a/src/renderer/painter.cpp b/src/renderer/painter.cpp
index c1705cd7cf..0d01fd1662 100644
--- a/src/renderer/painter.cpp
+++ b/src/renderer/painter.cpp
@@ -82,9 +82,29 @@ void Painter::setupShaders() {
if (!gaussianShader) gaussianShader = std::make_unique<GaussianShader>();
}
+void Painter::deleteShaders() {
+ plainShader = nullptr;
+ outlineShader = nullptr;
+ lineShader = nullptr;
+ linejoinShader = nullptr;
+ linepatternShader = nullptr;
+ patternShader = nullptr;
+ iconShader = nullptr;
+ rasterShader = nullptr;
+ sdfGlyphShader = nullptr;
+ sdfIconShader = nullptr;
+ dotShader = nullptr;
+ gaussianShader = nullptr;
+}
+
void Painter::cleanup() {
}
+void Painter::terminate() {
+ cleanup();
+ deleteShaders();
+}
+
void Painter::resize() {
const TransformState &state = map.getState();
if (gl_viewport != state.getFramebufferDimensions()) {
diff --git a/test/headless.cpp b/test/headless.cpp
index 3cc2607e47..d4c4d6036e 100644
--- a/test/headless.cpp
+++ b/test/headless.cpp
@@ -96,7 +96,10 @@ TEST_P(HeadlessTest, render) {
const unsigned int h = height * pixelRatio;
const std::unique_ptr<uint32_t[]> pixels(new uint32_t[w * h]);
+
+ map.view.make_active();
glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, pixels.get());
+ map.view.make_inactive();
const std::string image = util::compress_png(w, h, pixels.get(), true);
util::write_file(actual_image, image);