diff --git a/include/mbgl/map/map.hpp b/include/mbgl/map/map.hpp index afa856720..29e178ec5 100644 --- a/include/mbgl/map/map.hpp +++ b/include/mbgl/map/map.hpp @@ -46,6 +46,8 @@ public: // Resumes a paused render thread void resume(); + // Register a callback that will get called (on the render thread) when all resources have + // been loaded and a complete render occurs. using StillImageCallback = std::function)>; void renderStill(StillImageCallback callback); diff --git a/src/mbgl/map/map.cpp b/src/mbgl/map/map.cpp index 35b5f982d..83606b2ab 100644 --- a/src/mbgl/map/map.cpp +++ b/src/mbgl/map/map.cpp @@ -64,19 +64,8 @@ void Map::resume() { data->condResume.notify_all(); } -void Map::renderStill(StillImageCallback fn) { - assert(Environment::currentlyOn(ThreadType::Main)); - - if (data->mode != MapMode::Still) { - throw util::Exception("Map is not in still image render mode"); - } - - if (data->callback) { - throw util::Exception("Map is currently rendering an image"); - } - - data->callback = std::move(fn); - update(Update::RenderStill); +void Map::renderStill(StillImageCallback callback) { + context->invoke(&MapContext::renderStill, callback); } void Map::renderSync() { diff --git a/src/mbgl/map/map_context.cpp b/src/mbgl/map/map_context.cpp index 86a3ec7b4..b4b2a3f55 100644 --- a/src/mbgl/map/map_context.cpp +++ b/src/mbgl/map/map_context.cpp @@ -26,6 +26,7 @@ #include #include #include +#include namespace mbgl { @@ -226,6 +227,19 @@ void MapContext::update() { } } +void MapContext::renderStill(StillImageCallback fn) { + if (data.mode != MapMode::Still) { + throw util::Exception("Map is not in still image render mode"); + } + + if (callback) { + throw util::Exception("Map is currently rendering an image"); + } + + callback = fn; + triggerUpdate(Update::RenderStill); +} + void MapContext::render() { assert(Environment::currentlyOn(ThreadType::Map)); @@ -237,16 +251,9 @@ void MapContext::render() { painter->render(*style, transformState, data.getAnimationTime()); - if (data.mode == MapMode::Still && data.callback && style->isLoaded() && getSprite()->isLoaded()) { - auto image = view.readStillImage(); - - // We are moving the callback out of the way and empty it in case the callback function - // starts the next map image render. - MapData::StillImageCallback cb; - std::swap(cb, data.callback); - - // Now we can finally invoke the callback function with the map image we rendered. - cb(std::move(image)); + if (data.mode == MapMode::Still && callback && style->isLoaded() && getSprite()->isLoaded()) { + callback(view.readStillImage()); + callback = nullptr; } // Schedule another rerender when we definitely need a next frame. diff --git a/src/mbgl/map/map_context.hpp b/src/mbgl/map/map_context.hpp index 4b2d72652..e31b6f483 100644 --- a/src/mbgl/map/map_context.hpp +++ b/src/mbgl/map/map_context.hpp @@ -32,6 +32,7 @@ class Painter; class Sprite; class Style; class Worker; +class StillImage; struct LatLng; struct LatLngBounds; @@ -45,7 +46,9 @@ public: void resize(uint16_t width, uint16_t height, float ratio); - // Notifies the Map thread that the state has changed and an update might be necessary. + using StillImageCallback = std::function)>; + void renderStill(StillImageCallback callback); + void triggerUpdate(Update = Update::Nothing); void setStyleURL(const std::string&); @@ -93,6 +96,7 @@ private: std::string styleURL; std::string styleJSON; + StillImageCallback callback; size_t sourceCacheSize; TransformState transformState; }; diff --git a/src/mbgl/map/map_data.hpp b/src/mbgl/map/map_data.hpp index 664229912..86a22e123 100644 --- a/src/mbgl/map/map_data.hpp +++ b/src/mbgl/map/map_data.hpp @@ -18,8 +18,6 @@ namespace mbgl { -class StillImage; - class MapData { using Lock = std::lock_guard; @@ -101,9 +99,6 @@ public: std::mutex mutexPause; std::condition_variable condPaused; std::condition_variable condResume; - - using StillImageCallback = std::function)>; - StillImageCallback callback; }; }