From bda6ed26c65b541b0633fcdf824f2baef30aa0cc Mon Sep 17 00:00:00 2001 From: Ivo van Dongen Date: Fri, 15 Sep 2017 18:03:04 +0300 Subject: [core] send signal to RenderCustomLayer when gl context has been lost - Prevents cleaning up of GL resources that no longer exist, resulting in a crash --- include/mbgl/renderer/renderer.hpp | 2 ++ src/mbgl/renderer/layers/render_custom_layer.cpp | 2 +- src/mbgl/renderer/layers/render_custom_layer.hpp | 5 +++++ src/mbgl/renderer/renderer.cpp | 4 ++++ src/mbgl/renderer/renderer_impl.cpp | 11 +++++++++++ src/mbgl/renderer/renderer_impl.hpp | 6 ++++++ 6 files changed, 29 insertions(+), 1 deletion(-) diff --git a/include/mbgl/renderer/renderer.hpp b/include/mbgl/renderer/renderer.hpp index 95828a1b79..be8abb2c29 100644 --- a/include/mbgl/renderer/renderer.hpp +++ b/include/mbgl/renderer/renderer.hpp @@ -28,6 +28,8 @@ public: const optional programCacheDir = {}); ~Renderer(); + void markContextLost(); + void setObserver(RendererObserver*); void render(const UpdateParameters&); diff --git a/src/mbgl/renderer/layers/render_custom_layer.cpp b/src/mbgl/renderer/layers/render_custom_layer.cpp index ae0c4b026b..3d19f5ef46 100644 --- a/src/mbgl/renderer/layers/render_custom_layer.cpp +++ b/src/mbgl/renderer/layers/render_custom_layer.cpp @@ -16,7 +16,7 @@ RenderCustomLayer::RenderCustomLayer(Immutable _impl) RenderCustomLayer::~RenderCustomLayer() { assert(BackendScope::exists()); - if (initialized && impl().deinitializeFn) { + if (initialized && !contextDestroyed && impl().deinitializeFn) { impl().deinitializeFn(impl().context); } } diff --git a/src/mbgl/renderer/layers/render_custom_layer.hpp b/src/mbgl/renderer/layers/render_custom_layer.hpp index d8e9d93811..32ed9da8da 100644 --- a/src/mbgl/renderer/layers/render_custom_layer.hpp +++ b/src/mbgl/renderer/layers/render_custom_layer.hpp @@ -19,8 +19,13 @@ public: const style::CustomLayer::Impl& impl() const; + void markContextDestroyed() { + contextDestroyed = true; + }; + private: bool initialized = false; + bool contextDestroyed = false; }; template <> diff --git a/src/mbgl/renderer/renderer.cpp b/src/mbgl/renderer/renderer.cpp index a106d6c5fa..e915f5e146 100644 --- a/src/mbgl/renderer/renderer.cpp +++ b/src/mbgl/renderer/renderer.cpp @@ -20,6 +20,10 @@ Renderer::~Renderer() { impl.reset(); } +void Renderer::markContextLost() { + impl->markContextLost(); +} + void Renderer::setObserver(RendererObserver* observer) { impl->setObserver(observer); } diff --git a/src/mbgl/renderer/renderer_impl.cpp b/src/mbgl/renderer/renderer_impl.cpp index c45295b693..1a828b80a3 100644 --- a/src/mbgl/renderer/renderer_impl.cpp +++ b/src/mbgl/renderer/renderer_impl.cpp @@ -62,6 +62,17 @@ Renderer::Impl::Impl(RendererBackend& backend_, Renderer::Impl::~Impl() { assert(BackendScope::exists()); + + if (contextLost) { + // Signal all RenderCustomLayers that the context was lost + // before cleaning up + for (const auto& entry : renderLayers) { + RenderLayer& layer = *entry.second; + if (layer.is()) { + layer.as()->markContextDestroyed(); + } + } + } }; void Renderer::Impl::setObserver(RendererObserver* observer_) { diff --git a/src/mbgl/renderer/renderer_impl.hpp b/src/mbgl/renderer/renderer_impl.hpp index 8bdb472442..30e7f70722 100644 --- a/src/mbgl/renderer/renderer_impl.hpp +++ b/src/mbgl/renderer/renderer_impl.hpp @@ -39,6 +39,10 @@ public: const optional programCacheDir); ~Impl() final; + void markContextLost() { + contextLost = true; + }; + void setObserver(RendererObserver*); void render(const UpdateParameters&); @@ -100,6 +104,8 @@ private: std::unordered_map> renderSources; std::unordered_map> renderLayers; RenderLight renderLight; + + bool contextLost = false; }; } // namespace mbgl -- cgit v1.2.1