diff options
-rw-r--r-- | common/glfw_view.cpp | 9 | ||||
-rw-r--r-- | common/glfw_view.hpp | 1 | ||||
-rw-r--r-- | common/headless_view.cpp | 23 | ||||
-rw-r--r-- | common/headless_view.hpp | 1 | ||||
-rw-r--r-- | include/mbgl/map/map.hpp | 3 | ||||
-rw-r--r-- | include/mbgl/map/view.hpp | 4 | ||||
-rw-r--r-- | include/mbgl/renderer/painter.hpp | 2 | ||||
-rw-r--r-- | src/map/map.cpp | 14 | ||||
-rw-r--r-- | src/renderer/painter.cpp | 20 | ||||
-rw-r--r-- | test/headless.cpp | 3 |
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); |