diff options
Diffstat (limited to 'src/mbgl/map')
-rw-r--r-- | src/mbgl/map/map.cpp | 153 | ||||
-rw-r--r-- | src/mbgl/map/source.cpp | 6 | ||||
-rw-r--r-- | src/mbgl/map/view.cpp | 10 |
3 files changed, 94 insertions, 75 deletions
diff --git a/src/mbgl/map/map.cpp b/src/mbgl/map/map.cpp index 0cd7d3621e..29521f9499 100644 --- a/src/mbgl/map/map.cpp +++ b/src/mbgl/map/map.cpp @@ -73,10 +73,6 @@ Map::Map(View& view_, FileSource& fileSource_) painter(util::make_unique<Painter>(*spriteAtlas, *glyphAtlas, *lineAtlas)) { view.initialize(this); - // Make sure that we're doing an initial drawing in all cases. - isClean.clear(); - isRendered.clear(); - isSwapped.test_and_set(); } Map::~Map() { @@ -124,28 +120,32 @@ void Map::start(bool startPaused) { // Closes all open handles on the loop. This means that the loop will automatically terminate. asyncRender.reset(); + asyncUpdate.reset(); asyncTerminate.reset(); }); - asyncRender = util::make_unique<uv::async>(env->loop, [this]() { + asyncUpdate = util::make_unique<uv::async>(env->loop, [this] { assert(std::this_thread::get_id() == mapThread); if (state.hasSize()) { - if (isRendered.test_and_set() == false) { - prepare(); - if (isClean.test_and_set() == false) { - render(); - isSwapped.clear(); - view.swap(); - } else { - // We set the rendered flag in the test above, so we have to reset it - // now that we're not actually rendering because the map is clean. - isRendered.clear(); - } - } + prepare(); } }); + asyncRender = util::make_unique<uv::async>(env->loop, [this] { + // Must be called in Map thread. + assert(std::this_thread::get_id() == mapThread); + + render(); + + // Finally, notify all listeners that we have finished rendering this frame. + { + std::lock_guard<std::mutex> lk(mutexRendered); + rendered = true; + } + condRendered.notify_all(); + }); + // Do we need to pause first? if (startPaused) { pause(); @@ -208,7 +208,7 @@ void Map::pause(bool waitForPause) { mutexRun.unlock(); uv_stop(env->loop); - rerender(); // Needed to ensure uv_stop is seen and uv_run exits, otherwise we deadlock on wait_for_pause + triggerUpdate(); // Needed to ensure uv_stop is seen and uv_run exits, otherwise we deadlock on wait_for_pause if (waitForPause) { std::unique_lock<std::mutex> lockPause (mutexPause); @@ -280,6 +280,30 @@ void Map::run() { view.deactivate(); } +void Map::renderSync() { + // Must be called in UI thread. + assert(std::this_thread::get_id() == mainThread); + + triggerRender(); + + std::unique_lock<std::mutex> lock(mutexRendered); + condRendered.wait(lock, [this] { return rendered; }); + rendered = false; +} + +void Map::triggerUpdate() { + if (mode == Mode::Static) { + prepare(); + } else if (asyncUpdate) { + asyncUpdate->send(); + } +} + +void Map::triggerRender() { + assert(asyncRender); + asyncRender->send(); +} + void Map::checkForPause() { std::unique_lock<std::mutex> lockRun (mutexRun); while (pausing) { @@ -300,32 +324,6 @@ void Map::checkForPause() { mutexPause.unlock(); } -void Map::rerender() { - if (mode == Mode::Static) { - prepare(); - } else if (mode == Mode::Continuous) { - // We only send render events if we want to continuously update the map - // (== async rendering). - if (asyncRender) { - asyncRender->send(); - } - } -} - -void Map::update() { - isClean.clear(); - rerender(); -} - -bool Map::needsSwap() { - return isSwapped.test_and_set() == false; -} - -void Map::swapped() { - isRendered.clear(); - rerender(); -} - void Map::terminate() { assert(painter); painter->terminate(); @@ -350,7 +348,6 @@ void Map::setStyleURL(const std::string &url) { } } - void Map::setStyleJSON(std::string newStyleJSON, const std::string &base) { // TODO: Make threadsafe. styleJSON.swap(newStyleJSON); @@ -367,7 +364,7 @@ void Map::setStyleJSON(std::string newStyleJSON, const std::string &base) { const std::string glyphURL = util::mapbox::normalizeGlyphsURL(style->glyph_url, getAccessToken()); glyphStore->setURL(glyphURL); - update(); + triggerUpdate(); } std::string Map::getStyleJSON() const { @@ -393,7 +390,7 @@ void Map::resize(uint16_t width, uint16_t height, float ratio) { void Map::resize(uint16_t width, uint16_t height, float ratio, uint16_t fbWidth, uint16_t fbHeight) { if (transform.resize(width, height, ratio, fbWidth, fbHeight)) { - update(); + triggerUpdate(); } } @@ -402,7 +399,7 @@ void Map::resize(uint16_t width, uint16_t height, float ratio, uint16_t fbWidth, void Map::cancelTransitions() { transform.cancelTransitions(); - update(); + triggerUpdate(); } @@ -410,12 +407,12 @@ void Map::cancelTransitions() { void Map::moveBy(double dx, double dy, std::chrono::steady_clock::duration duration) { transform.moveBy(dx, dy, duration); - update(); + triggerUpdate(); } void Map::setLatLng(LatLng latLng, std::chrono::steady_clock::duration duration) { transform.setLatLng(latLng, duration); - update(); + triggerUpdate(); } LatLng Map::getLatLng() const { @@ -424,19 +421,19 @@ LatLng Map::getLatLng() const { void Map::startPanning() { transform.startPanning(); - update(); + triggerUpdate(); } void Map::stopPanning() { transform.stopPanning(); - update(); + triggerUpdate(); } void Map::resetPosition() { transform.setAngle(0); transform.setLatLng(LatLng(0, 0)); transform.setZoom(0); - update(); + triggerUpdate(); } @@ -444,12 +441,12 @@ void Map::resetPosition() { void Map::scaleBy(double ds, double cx, double cy, std::chrono::steady_clock::duration duration) { transform.scaleBy(ds, cx, cy, duration); - update(); + triggerUpdate(); } void Map::setScale(double scale, double cx, double cy, std::chrono::steady_clock::duration duration) { transform.setScale(scale, cx, cy, duration); - update(); + triggerUpdate(); } double Map::getScale() const { @@ -458,7 +455,7 @@ double Map::getScale() const { void Map::setZoom(double zoom, std::chrono::steady_clock::duration duration) { transform.setZoom(zoom, duration); - update(); + triggerUpdate(); } double Map::getZoom() const { @@ -467,7 +464,7 @@ double Map::getZoom() const { void Map::setLatLngZoom(LatLng latLng, double zoom, std::chrono::steady_clock::duration duration) { transform.setLatLngZoom(latLng, zoom, duration); - update(); + triggerUpdate(); } void Map::resetZoom() { @@ -476,12 +473,12 @@ void Map::resetZoom() { void Map::startScaling() { transform.startScaling(); - update(); + triggerUpdate(); } void Map::stopScaling() { transform.stopScaling(); - update(); + triggerUpdate(); } double Map::getMinZoom() const { @@ -497,17 +494,17 @@ double Map::getMaxZoom() const { void Map::rotateBy(double sx, double sy, double ex, double ey, std::chrono::steady_clock::duration duration) { transform.rotateBy(sx, sy, ex, ey, duration); - update(); + triggerUpdate(); } void Map::setBearing(double degrees, std::chrono::steady_clock::duration duration) { transform.setAngle(-degrees * M_PI / 180, duration); - update(); + triggerUpdate(); } void Map::setBearing(double degrees, double cx, double cy) { transform.setAngle(-degrees * M_PI / 180, cx, cy); - update(); + triggerUpdate(); } double Map::getBearing() const { @@ -516,17 +513,17 @@ double Map::getBearing() const { void Map::resetNorth() { transform.setAngle(0, std::chrono::milliseconds(500)); - update(); + triggerUpdate(); } void Map::startRotating() { transform.startRotating(); - update(); + triggerUpdate(); } void Map::stopRotating() { transform.stopRotating(); - update(); + triggerUpdate(); } #pragma mark - Access Token @@ -545,7 +542,7 @@ void Map::setDebug(bool value) { debug = value; assert(painter); painter->setDebug(debug); - update(); + triggerUpdate(); } void Map::toggleDebug() { @@ -562,7 +559,7 @@ void Map::addClass(const std::string& klass) { if (style) { style->cascadeClasses(classes); if (style->hasTransitions()) { - update(); + triggerUpdate(); } } } @@ -573,7 +570,7 @@ void Map::removeClass(const std::string& klass) { if (style) { style->cascadeClasses(classes); if (style->hasTransitions()) { - update(); + triggerUpdate(); } } } @@ -583,7 +580,7 @@ void Map::setClasses(const std::vector<std::string>& classes_) { if (style) { style->cascadeClasses(classes); if (style->hasTransitions()) { - update(); + triggerUpdate(); } } } @@ -637,6 +634,7 @@ void Map::updateSources() { } void Map::updateSources(const util::ptr<StyleLayerGroup> &group) { + assert(std::this_thread::get_id() == mapThread); if (!group) { return; } @@ -649,13 +647,19 @@ void Map::updateSources(const util::ptr<StyleLayerGroup> &group) { } void Map::updateTiles() { - for (const auto& source : activeSources) { + assert(std::this_thread::get_id() == mapThread); + for (const auto &source : activeSources) { source->source->update(*this, *env, getWorker(), style, *glyphAtlas, *glyphStore, - *spriteAtlas, getSprite(), *texturePool, [this]() { update(); }); + *spriteAtlas, getSprite(), *texturePool, [this]() { + assert(std::this_thread::get_id() == mapThread); + triggerUpdate(); + }); } } void Map::prepare() { + assert(std::this_thread::get_id() == mapThread); + if (!style) { style = std::make_shared<Style>(); @@ -692,14 +696,19 @@ void Map::prepare() { spriteAtlas->setSprite(getSprite()); updateTiles(); + + if (mode == Mode::Continuous) { + view.invalidate(); + } } void Map::render() { + assert(std::this_thread::get_id() == mapThread); assert(painter); painter->render(*style, activeSources, state, animationTime); // Schedule another rerender when we definitely need a next frame. if (transform.needsTransition() || style->hasTransitions()) { - update(); + triggerUpdate(); } } diff --git a/src/mbgl/map/source.cpp b/src/mbgl/map/source.cpp index ec3a1b8e00..447f25d4b7 100644 --- a/src/mbgl/map/source.cpp +++ b/src/mbgl/map/source.cpp @@ -60,8 +60,7 @@ void Source::load(Map &map, Environment &env) { source->info.parseTileJSONProperties(d); source->loaded = true; - map.update(); - + map.triggerUpdate(); }); } @@ -293,8 +292,9 @@ void Source::update(Map &map, util::ptr<Sprite> sprite, TexturePool &texturePool, std::function<void()> callback) { - if (!loaded || map.getTime() <= updated) + if (!loaded || map.getTime() <= updated) { return; + } bool changed = false; diff --git a/src/mbgl/map/view.cpp b/src/mbgl/map/view.cpp index 3927652ba6..21ba4daf36 100644 --- a/src/mbgl/map/view.cpp +++ b/src/mbgl/map/view.cpp @@ -3,9 +3,19 @@ namespace mbgl { +void View::initialize(Map *map_) { + assert(map_); + map = map_; +} + void View::resize(uint16_t width, uint16_t height, float ratio, uint16_t fbWidth, uint16_t fbHeight) { assert(map); map->resize(width, height, ratio, fbWidth, fbHeight); } +void View::notifyMapChange(MapChange, std::chrono::steady_clock::duration) { + // no-op +} + + } |