summaryrefslogtreecommitdiff
path: root/src/mbgl/style/style.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mbgl/style/style.cpp')
-rw-r--r--src/mbgl/style/style.cpp181
1 files changed, 144 insertions, 37 deletions
diff --git a/src/mbgl/style/style.cpp b/src/mbgl/style/style.cpp
index 0acf66eb56..8999af3c7f 100644
--- a/src/mbgl/style/style.cpp
+++ b/src/mbgl/style/style.cpp
@@ -1,9 +1,13 @@
#include <mbgl/style/style.hpp>
#include <mbgl/map/sprite.hpp>
#include <mbgl/map/source.hpp>
+#include <mbgl/map/transform_state.hpp>
#include <mbgl/style/style_layer.hpp>
#include <mbgl/style/style_parser.hpp>
#include <mbgl/style/style_bucket.hpp>
+#include <mbgl/geometry/glyph_atlas.hpp>
+#include <mbgl/geometry/sprite_atlas.hpp>
+#include <mbgl/geometry/line_atlas.hpp>
#include <mbgl/util/constants.hpp>
#include <mbgl/util/uv_detail.hpp>
#include <mbgl/platform/log.hpp>
@@ -15,15 +19,77 @@
namespace mbgl {
-Style::Style()
- : mtx(std::make_unique<uv::rwlock>()),
+Style::Style(const std::string& data, const std::string&,
+ uv_loop_t* loop, Environment& env)
+ : glyphStore(std::make_unique<GlyphStore>(loop, env)),
+ glyphAtlas(std::make_unique<GlyphAtlas>(1024, 1024)),
+ spriteAtlas(std::make_unique<SpriteAtlas>(512, 512)),
+ lineAtlas(std::make_unique<LineAtlas>(512, 512)),
+ mtx(std::make_unique<uv::rwlock>()),
workers(4) {
+
+ rapidjson::Document doc;
+ doc.Parse<0>((const char *const)data.c_str());
+ if (doc.HasParseError()) {
+ Log::Error(Event::ParseStyle, "Error parsing style JSON at %i: %s", doc.GetErrorOffset(), doc.GetParseError());
+ return;
+ }
+
+ StyleParser parser;
+ parser.parse(doc);
+
+ sources = parser.getSources();
+ layers = parser.getLayers();
+
+ spriteURL = parser.getSprite();
+ glyphStore->setURL(parser.getGlyphURL());
+
+ for (const auto& source : sources) {
+ source->setObserver(this);
+ source->load();
+ }
+
+ glyphStore->setObserver(this);
}
-// Note: This constructor is seemingly empty, but we need to declare it anyway
-// because this file includes uv_detail.hpp, which has the declarations necessary
-// for deleting the std::unique_ptr<uv::rwlock>.
-Style::~Style() {}
+Style::~Style() {
+ for (const auto& source : sources) {
+ source->setObserver(nullptr);
+ }
+
+ glyphStore->setObserver(nullptr);
+
+ if (sprite) {
+ sprite->setObserver(nullptr);
+ }
+}
+
+void Style::update(MapData& data,
+ const TransformState& transform,
+ TexturePool& texturePool) {
+ const float pixelRatio = transform.getPixelRatio();
+ if (!sprite || !sprite->hasPixelRatio(pixelRatio)) {
+ sprite = std::make_unique<Sprite>(spriteURL, pixelRatio);
+ sprite->setObserver(this);
+
+ spriteAtlas->resize(pixelRatio);
+ spriteAtlas->setSprite(sprite);
+ }
+
+ bool allTilesUpdated = true;
+ for (const auto& source : sources) {
+ if (!source->update(data, transform, *this, *glyphAtlas, *glyphStore,
+ *spriteAtlas, sprite, texturePool, shouldReparsePartialTiles)) {
+ allTilesUpdated = false;
+ }
+ }
+
+ // We can only stop updating "partial" tiles when all of them
+ // were notified of the arrival of the new resources.
+ if (allTilesUpdated) {
+ shouldReparsePartialTiles = false;
+ }
+}
void Style::cascade(const std::vector<std::string>& classes) {
TimePoint now = Clock::now();
@@ -50,10 +116,6 @@ void Style::recalculate(float z, TimePoint now) {
}
}
-const std::string &Style::getSpriteURL() const {
- return sprite_url;
-}
-
void Style::setDefaultTransitionDuration(Duration duration) {
defaultTransition.duration = duration;
}
@@ -67,44 +129,89 @@ bool Style::hasTransitions() const {
return false;
}
-void Style::loadJSON(const uint8_t *const data) {
- uv::writelock lock(mtx);
+bool Style::isLoaded() const {
+ for (const auto& source : sources) {
+ if (!source->isLoaded()) {
+ return false;
+ }
+ }
- rapidjson::Document doc;
- doc.Parse<0>((const char *const)data);
- if (doc.HasParseError()) {
- Log::Error(Event::ParseStyle, "Error parsing style JSON at %i: %s", doc.GetErrorOffset(), doc.GetParseError());
- return;
+ if (sprite && !sprite->isLoaded()) {
+ return false;
}
- StyleParser parser;
- parser.parse(doc);
+ return true;
+}
- sources = parser.getSources();
- layers = parser.getLayers();
- sprite_url = parser.getSprite();
- glyph_url = parser.getGlyphURL();
- loaded = true;
+void Style::setObserver(Observer* observer_) {
+ assert(Environment::currentlyOn(ThreadType::Map));
+ assert(!observer);
+
+ observer = observer_;
}
-bool Style::isLoaded() const {
- // TODO: move loading into Style
- if (!loaded) {
- return false;
+void Style::onGlyphRangeLoaded() {
+ shouldReparsePartialTiles = true;
+
+ emitTileDataChanged();
+}
+
+void Style::onGlyphRangeLoadingFailed(std::exception_ptr error) {
+ emitResourceLoadingFailed(error);
+}
+
+void Style::onSourceLoaded() {
+ emitTileDataChanged();
+}
+
+void Style::onSourceLoadingFailed(std::exception_ptr error) {
+ emitResourceLoadingFailed(error);
+}
+
+void Style::onTileLoaded(bool isNewTile) {
+ if (isNewTile) {
+ shouldReparsePartialTiles = true;
}
- for (const auto& source : sources) {
- if (!source->isLoaded()) {
- return false;
- }
+ emitTileDataChanged();
+}
+
+void Style::onTileLoadingFailed(std::exception_ptr error) {
+ emitResourceLoadingFailed(error);
+}
+
+void Style::onSpriteLoaded() {
+ shouldReparsePartialTiles = true;
+
+ emitTileDataChanged();
+}
+
+void Style::onSpriteLoadingFailed(std::exception_ptr error) {
+ emitResourceLoadingFailed(error);
+}
+
+void Style::emitTileDataChanged() {
+ assert(Environment::currentlyOn(ThreadType::Map));
+
+ if (observer) {
+ observer->onTileDataChanged();
}
+}
- // TODO: move sprite into Style
-// if (sprite && !sprite.isLoaded()) {
-// return false;
-// }
+void Style::emitResourceLoadingFailed(std::exception_ptr error) {
+ assert(Environment::currentlyOn(ThreadType::Map));
- return true;
+ try {
+ if (error) {
+ std::rethrow_exception(error);
+ }
+ } catch(const std::exception& e) {
+ Log::Error(Event::Style, e.what());
+ }
+
+ if (observer) {
+ observer->onResourceLoadingFailed(error);
+ }
}
}