summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/mbgl/map/map.cpp153
-rw-r--r--src/mbgl/map/source.cpp6
-rw-r--r--src/mbgl/map/view.cpp10
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
+}
+
+
}