Scope the Map thread to an Environment
Also, replace manual thread type checks with Environment::currentlyOn().
This commit is contained in:
committed by
Konstantin Käfer
parent
b52aab5f7c
commit
b5facd35bc
@@ -217,9 +217,6 @@ private:
|
||||
// Stores whether the map thread has been stopped already.
|
||||
std::atomic_bool isStopped;
|
||||
|
||||
const std::thread::id mainThread;
|
||||
std::thread::id mapThread;
|
||||
|
||||
Transform transform;
|
||||
TransformState state;
|
||||
|
||||
|
||||
@@ -102,25 +102,17 @@ std::string Environment::threadName() {
|
||||
return threadInfoStore.getThreadInfo().name;
|
||||
}
|
||||
|
||||
void Environment::setup() {
|
||||
mapThread = std::this_thread::get_id();
|
||||
}
|
||||
|
||||
bool Environment::inMapThread() const {
|
||||
return std::this_thread::get_id() == mapThread;
|
||||
}
|
||||
|
||||
void Environment::requestAsync(const Resource &resource, std::function<void(const Response &)> callback) {
|
||||
fileSource.request(resource, *this, std::move(callback));
|
||||
}
|
||||
|
||||
Request *Environment::request(const Resource &resource, std::function<void(const Response &)> callback) {
|
||||
assert(inMapThread());
|
||||
assert(currentlyOn(ThreadType::Map));
|
||||
return fileSource.request(resource, loop, *this, std::move(callback));
|
||||
}
|
||||
|
||||
void Environment::cancelRequest(Request *req) {
|
||||
assert(inMapThread());
|
||||
assert(currentlyOn(ThreadType::Map));
|
||||
fileSource.cancel(req);
|
||||
}
|
||||
|
||||
|
||||
@@ -40,10 +40,6 @@ public:
|
||||
static bool currentlyOn(ThreadType);
|
||||
static std::string threadName();
|
||||
|
||||
void setup();
|
||||
|
||||
bool inMapThread() const;
|
||||
|
||||
void requestAsync(const Resource &, std::function<void(const Response &)>);
|
||||
Request *request(const Resource &, std::function<void(const Response &)>);
|
||||
void cancelRequest(Request *);
|
||||
|
||||
@@ -62,8 +62,6 @@ using namespace mbgl;
|
||||
Map::Map(View& view_, FileSource& fileSource_)
|
||||
: env(util::make_unique<Environment>(fileSource_)),
|
||||
view(view_),
|
||||
mainThread(std::this_thread::get_id()),
|
||||
mapThread(mainThread),
|
||||
transform(view_),
|
||||
fileSource(fileSource_),
|
||||
glyphAtlas(util::make_unique<GlyphAtlas>(1024, 1024)),
|
||||
@@ -99,7 +97,7 @@ uv::worker &Map::getWorker() {
|
||||
}
|
||||
|
||||
void Map::start(bool startPaused) {
|
||||
assert(std::this_thread::get_id() == mainThread);
|
||||
assert(Environment::currentlyOn(ThreadType::Main));
|
||||
assert(mode == Mode::None);
|
||||
|
||||
// When starting map rendering in another thread, we perform async/continuously
|
||||
@@ -111,7 +109,7 @@ void Map::start(bool startPaused) {
|
||||
|
||||
// Setup async notifications
|
||||
asyncTerminate = util::make_unique<uv::async>(env->loop, [this]() {
|
||||
assert(std::this_thread::get_id() == mapThread);
|
||||
assert(Environment::currentlyOn(ThreadType::Map));
|
||||
|
||||
// Remove all of these to make sure they are destructed in the correct thread.
|
||||
style.reset();
|
||||
@@ -127,7 +125,7 @@ void Map::start(bool startPaused) {
|
||||
});
|
||||
|
||||
asyncUpdate = util::make_unique<uv::async>(env->loop, [this] {
|
||||
assert(std::this_thread::get_id() == mapThread);
|
||||
assert(Environment::currentlyOn(ThreadType::Map));
|
||||
|
||||
if (state.hasSize()) {
|
||||
prepare();
|
||||
@@ -136,7 +134,7 @@ void Map::start(bool startPaused) {
|
||||
|
||||
asyncRender = util::make_unique<uv::async>(env->loop, [this] {
|
||||
// Must be called in Map thread.
|
||||
assert(std::this_thread::get_id() == mapThread);
|
||||
assert(Environment::currentlyOn(ThreadType::Map));
|
||||
|
||||
render();
|
||||
|
||||
@@ -154,20 +152,12 @@ void Map::start(bool startPaused) {
|
||||
}
|
||||
|
||||
thread = std::thread([this]() {
|
||||
#ifdef DEBUG
|
||||
mapThread = std::this_thread::get_id();
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
pthread_setname_np("Map");
|
||||
#endif
|
||||
|
||||
run();
|
||||
|
||||
#ifdef DEBUG
|
||||
mapThread = std::thread::id();
|
||||
#endif
|
||||
|
||||
// Make sure that the stop() function knows when to stop invoking the callback function.
|
||||
isStopped = true;
|
||||
view.notify();
|
||||
@@ -175,8 +165,7 @@ void Map::start(bool startPaused) {
|
||||
}
|
||||
|
||||
void Map::stop(std::function<void ()> callback) {
|
||||
assert(std::this_thread::get_id() == mainThread);
|
||||
assert(mainThread != mapThread);
|
||||
assert(Environment::currentlyOn(ThreadType::Main));
|
||||
assert(mode == Mode::Continuous);
|
||||
|
||||
asyncTerminate->send();
|
||||
@@ -203,7 +192,7 @@ void Map::stop(std::function<void ()> callback) {
|
||||
}
|
||||
|
||||
void Map::pause(bool waitForPause) {
|
||||
assert(std::this_thread::get_id() == mainThread);
|
||||
assert(Environment::currentlyOn(ThreadType::Main));
|
||||
assert(mode == Mode::Continuous);
|
||||
mutexRun.lock();
|
||||
pausing = true;
|
||||
@@ -221,7 +210,7 @@ void Map::pause(bool waitForPause) {
|
||||
}
|
||||
|
||||
void Map::resume() {
|
||||
assert(std::this_thread::get_id() == mainThread);
|
||||
assert(Environment::currentlyOn(ThreadType::Main));
|
||||
assert(mode == Mode::Continuous);
|
||||
|
||||
mutexRun.lock();
|
||||
@@ -231,13 +220,20 @@ void Map::resume() {
|
||||
}
|
||||
|
||||
void Map::run() {
|
||||
ThreadType threadType = ThreadType::Map;
|
||||
std::string threadName("Map");
|
||||
|
||||
if (mode == Mode::None) {
|
||||
#ifdef DEBUG
|
||||
mapThread = mainThread;
|
||||
#endif
|
||||
mode = Mode::Static;
|
||||
|
||||
// FIXME: Threads should have only one purpose. When running on Static mode,
|
||||
// we are currently not spawning a Map thread and running the code on the
|
||||
// Main thread, thus, the Main thread in this case is both Main and Map thread.
|
||||
threadType = static_cast<ThreadType>(static_cast<uint8_t>(threadType) | static_cast<uint8_t>(ThreadType::Main));
|
||||
threadName += "andMain";
|
||||
}
|
||||
assert(std::this_thread::get_id() == mapThread);
|
||||
|
||||
Environment::Scope scope(*env, threadType, threadName);
|
||||
|
||||
if (mode == Mode::Continuous) {
|
||||
checkForPause();
|
||||
@@ -251,8 +247,6 @@ void Map::run() {
|
||||
|
||||
workers = util::make_unique<uv::worker>(env->loop, 4, "Tile Worker");
|
||||
|
||||
env->setup();
|
||||
|
||||
setup();
|
||||
prepare();
|
||||
|
||||
@@ -273,9 +267,6 @@ void Map::run() {
|
||||
// *after* all events have been processed.
|
||||
if (mode == Mode::Static) {
|
||||
render();
|
||||
#ifdef DEBUG
|
||||
mapThread = std::thread::id();
|
||||
#endif
|
||||
mode = Mode::None;
|
||||
}
|
||||
|
||||
@@ -284,7 +275,7 @@ void Map::run() {
|
||||
|
||||
void Map::renderSync() {
|
||||
// Must be called in UI thread.
|
||||
assert(std::this_thread::get_id() == mainThread);
|
||||
assert(Environment::currentlyOn(ThreadType::Main));
|
||||
|
||||
triggerRender();
|
||||
|
||||
@@ -335,7 +326,7 @@ void Map::terminate() {
|
||||
#pragma mark - Setup
|
||||
|
||||
void Map::setup() {
|
||||
assert(std::this_thread::get_id() == mapThread);
|
||||
assert(Environment::currentlyOn(ThreadType::Map));
|
||||
assert(painter);
|
||||
painter->setup();
|
||||
}
|
||||
@@ -541,42 +532,42 @@ const std::string &Map::getAccessToken() const {
|
||||
#pragma mark - Annotations
|
||||
|
||||
void Map::setDefaultPointAnnotationSymbol(std::string& symbol) {
|
||||
assert(std::this_thread::get_id() == mainThread);
|
||||
assert(Environment::currentlyOn(ThreadType::Main));
|
||||
annotationManager->setDefaultPointAnnotationSymbol(symbol);
|
||||
}
|
||||
|
||||
uint32_t Map::addPointAnnotation(LatLng point, std::string& symbol) {
|
||||
assert(std::this_thread::get_id() == mainThread);
|
||||
assert(Environment::currentlyOn(ThreadType::Main));
|
||||
std::vector<LatLng> points({ point });
|
||||
std::vector<std::string> symbols({ symbol });
|
||||
return addPointAnnotations(points, symbols)[0];
|
||||
}
|
||||
|
||||
std::vector<uint32_t> Map::addPointAnnotations(std::vector<LatLng> points, std::vector<std::string>& symbols) {
|
||||
assert(std::this_thread::get_id() == mainThread);
|
||||
assert(Environment::currentlyOn(ThreadType::Main));
|
||||
auto result = annotationManager->addPointAnnotations(points, symbols, *this);
|
||||
updateAnnotationTiles(result.first);
|
||||
return result.second;
|
||||
}
|
||||
|
||||
void Map::removeAnnotation(uint32_t annotation) {
|
||||
assert(std::this_thread::get_id() == mainThread);
|
||||
assert(Environment::currentlyOn(ThreadType::Main));
|
||||
removeAnnotations({ annotation });
|
||||
}
|
||||
|
||||
void Map::removeAnnotations(std::vector<uint32_t> annotations) {
|
||||
assert(std::this_thread::get_id() == mainThread);
|
||||
assert(Environment::currentlyOn(ThreadType::Main));
|
||||
auto result = annotationManager->removeAnnotations(annotations);
|
||||
updateAnnotationTiles(result);
|
||||
}
|
||||
|
||||
std::vector<uint32_t> Map::getAnnotationsInBounds(LatLngBounds bounds) const {
|
||||
assert(std::this_thread::get_id() == mainThread);
|
||||
assert(Environment::currentlyOn(ThreadType::Main));
|
||||
return annotationManager->getAnnotationsInBounds(bounds, *this);
|
||||
}
|
||||
|
||||
LatLngBounds Map::getBoundsForAnnotations(std::vector<uint32_t> annotations) const {
|
||||
assert(std::this_thread::get_id() == mainThread);
|
||||
assert(Environment::currentlyOn(ThreadType::Main));
|
||||
return annotationManager->getBoundsForAnnotations(annotations);
|
||||
}
|
||||
|
||||
@@ -658,7 +649,7 @@ std::chrono::steady_clock::duration Map::getDefaultTransitionDuration() {
|
||||
}
|
||||
|
||||
void Map::updateSources() {
|
||||
assert(std::this_thread::get_id() == mapThread);
|
||||
assert(Environment::currentlyOn(ThreadType::Map));
|
||||
|
||||
// First, disable all existing sources.
|
||||
for (const auto& source : activeSources) {
|
||||
@@ -687,7 +678,7 @@ void Map::updateSources() {
|
||||
}
|
||||
|
||||
void Map::updateSources(const util::ptr<StyleLayerGroup> &group) {
|
||||
assert(std::this_thread::get_id() == mapThread);
|
||||
assert(Environment::currentlyOn(ThreadType::Map));
|
||||
if (!group) {
|
||||
return;
|
||||
}
|
||||
@@ -701,18 +692,18 @@ void Map::updateSources(const util::ptr<StyleLayerGroup> &group) {
|
||||
}
|
||||
|
||||
void Map::updateTiles() {
|
||||
assert(std::this_thread::get_id() == mapThread);
|
||||
assert(Environment::currentlyOn(ThreadType::Map));
|
||||
for (const auto &source : activeSources) {
|
||||
source->source->update(*this, *env, getWorker(), style, *glyphAtlas, *glyphStore,
|
||||
*spriteAtlas, getSprite(), *texturePool, [this]() {
|
||||
assert(std::this_thread::get_id() == mapThread);
|
||||
assert(Environment::currentlyOn(ThreadType::Map));
|
||||
triggerUpdate();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void Map::prepare() {
|
||||
assert(std::this_thread::get_id() == mapThread);
|
||||
assert(Environment::currentlyOn(ThreadType::Map));
|
||||
|
||||
if (!style) {
|
||||
style = std::make_shared<Style>();
|
||||
@@ -757,7 +748,7 @@ void Map::prepare() {
|
||||
}
|
||||
|
||||
void Map::render() {
|
||||
assert(std::this_thread::get_id() == mapThread);
|
||||
assert(Environment::currentlyOn(ThreadType::Map));
|
||||
assert(painter);
|
||||
painter->render(*style, activeSources,
|
||||
state, animationTime);
|
||||
|
||||
Reference in New Issue
Block a user