diff options
-rw-r--r-- | src/mbgl/annotation/sprite_image.cpp | 6 | ||||
-rw-r--r-- | src/mbgl/annotation/sprite_image.hpp | 6 | ||||
-rw-r--r-- | src/mbgl/annotation/sprite_parser.cpp | 4 | ||||
-rw-r--r-- | src/mbgl/geometry/sprite_atlas.cpp | 95 | ||||
-rw-r--r-- | src/mbgl/geometry/sprite_atlas.hpp | 19 | ||||
-rw-r--r-- | src/mbgl/map/map_context.cpp | 13 | ||||
-rw-r--r-- | src/mbgl/map/sprite.cpp | 83 | ||||
-rw-r--r-- | src/mbgl/map/sprite.hpp | 34 | ||||
-rw-r--r-- | src/mbgl/map/tile_worker.cpp | 4 | ||||
-rw-r--r-- | src/mbgl/renderer/symbol_bucket.cpp | 14 | ||||
-rw-r--r-- | src/mbgl/renderer/symbol_bucket.hpp | 1 | ||||
-rw-r--r-- | src/mbgl/style/style.cpp | 28 | ||||
-rw-r--r-- | src/mbgl/style/style.hpp | 7 | ||||
-rw-r--r-- | test/style/resource_loading.cpp | 4 |
14 files changed, 91 insertions, 227 deletions
diff --git a/src/mbgl/annotation/sprite_image.cpp b/src/mbgl/annotation/sprite_image.cpp index 1a5ae8e099..e482d8f13f 100644 --- a/src/mbgl/annotation/sprite_image.cpp +++ b/src/mbgl/annotation/sprite_image.cpp @@ -9,13 +9,15 @@ namespace mbgl { SpriteImage::SpriteImage(const uint16_t width_, const uint16_t height_, const float pixelRatio_, - std::string&& data_) + std::string&& data_, + bool sdf_) : width(width_), height(height_), pixelRatio(pixelRatio_), pixelWidth(std::ceil(width * pixelRatio)), pixelHeight(std::ceil(height * pixelRatio)), - data(std::move(data_)) { + data(std::move(data_)), + sdf(sdf_) { const size_t size = pixelWidth * pixelHeight * 4; if (size == 0) { throw util::SpriteImageException("Sprite image dimensions may not be zero"); diff --git a/src/mbgl/annotation/sprite_image.hpp b/src/mbgl/annotation/sprite_image.hpp index 19de77c0c4..7d8ea0501c 100644 --- a/src/mbgl/annotation/sprite_image.hpp +++ b/src/mbgl/annotation/sprite_image.hpp @@ -12,7 +12,8 @@ namespace mbgl { class SpriteImage : private util::noncopyable { public: - SpriteImage(uint16_t width, uint16_t height, float pixelRatio, std::string&& data); + SpriteImage( + uint16_t width, uint16_t height, float pixelRatio, std::string&& data, bool sdf = false); // Logical dimensions of the sprite image. const uint16_t width; @@ -29,6 +30,9 @@ public: // (width * ratio) * (height * ratio) * 4 (RGBA) bytes. The scan lines may // not have gaps between them (i.e. stride == 0). const std::string data; + + // Whether this image should be interpreted as a signed distance field icon. + const bool sdf; }; } diff --git a/src/mbgl/annotation/sprite_parser.cpp b/src/mbgl/annotation/sprite_parser.cpp index 2791c54a05..c5c731d517 100644 --- a/src/mbgl/annotation/sprite_parser.cpp +++ b/src/mbgl/annotation/sprite_parser.cpp @@ -18,7 +18,7 @@ SpriteImagePtr createSpriteImage(const util::Image& image, const uint16_t srcWidth, const uint16_t srcHeight, const double ratio, - const bool) { + const bool sdf) { // Disallow invalid parameter configurations. if (srcWidth == 0 || srcHeight == 0 || ratio <= 0 || ratio > 10 || srcWidth > 1024 || srcHeight > 1024) { @@ -52,7 +52,7 @@ SpriteImagePtr createSpriteImage(const util::Image& image, } } - return std::make_unique<const SpriteImage>(width, height, ratio, std::move(data)); + return std::make_unique<const SpriteImage>(width, height, ratio, std::move(data), sdf); } namespace { diff --git a/src/mbgl/geometry/sprite_atlas.cpp b/src/mbgl/geometry/sprite_atlas.cpp index b3d2ba7249..dc42a97b98 100644 --- a/src/mbgl/geometry/sprite_atlas.cpp +++ b/src/mbgl/geometry/sprite_atlas.cpp @@ -22,50 +22,12 @@ using namespace mbgl; SpriteAtlas::SpriteAtlas(dimension width_, dimension height_, SpriteStore& store_) : width(width_), height(height_), - bin(width_, height_), store(store_), + pixelRatio(store.pixelRatio), + bin(width_, height_), dirty(true) { } -bool SpriteAtlas::resize(const float newRatio) { - if (pixelRatio == newRatio) return false; - - std::lock_guard<std::recursive_mutex> lock(mtx); - - const float oldRatio = pixelRatio; - pixelRatio = newRatio; - - if (data) { - const auto oldData = std::move(data); - allocate(); - - const int old_w = width * oldRatio; - const int old_h = height * oldRatio; - const int new_w = width * newRatio; - const int new_h = height * newRatio; - - // Basic image scaling. TODO: Replace this with better image scaling. - for (int y = 0; y < new_h; y++) { - const int old_yoffset = ((y * old_h) / new_h) * old_w; - const int new_yoffset = y * new_w; - for (int x = 0; x < new_w; x++) { - const int old_x = (x * old_w) / new_w; - data[new_yoffset + x] = oldData[old_yoffset + old_x]; - } - } - - dirty = true; - fullUploadRequired = true; - - // Mark all sprite images as in need of update - for (const auto &pair : images) { - uninitialized.emplace(pair.first); - } - } - - return dirty; -} - Rect<SpriteAtlas::dimension> SpriteAtlas::allocateImage(const size_t pixel_width, const size_t pixel_height) { // Increase to next number divisible by 4, but at least 1. // This is so we can scale down the texture coordinates and pack them @@ -86,17 +48,17 @@ Rect<SpriteAtlas::dimension> SpriteAtlas::allocateImage(const size_t pixel_width return rect; } -Rect<SpriteAtlas::dimension> SpriteAtlas::getImage(const std::string& name, const bool wrap) { +SpriteAtlasElement SpriteAtlas::getImage(const std::string& name, const bool wrap) { std::lock_guard<std::recursive_mutex> lock(mtx); auto rect_it = images.find(name); if (rect_it != images.end()) { - return rect_it->second.pos; + return { rect_it->second.pos, rect_it->second.texture }; } auto sprite = store.getSprite(name); if (!sprite) { - return Rect<dimension> { 0, 0, 0, 0 }; + return { Rect<dimension> { 0, 0, 0, 0 }, nullptr }; } Rect<dimension> rect = allocateImage(sprite->width, sprite->height); @@ -104,19 +66,19 @@ Rect<SpriteAtlas::dimension> SpriteAtlas::getImage(const std::string& name, cons if (debug::spriteWarnings) { Log::Warning(Event::Sprite, "sprite atlas bitmap overflow"); } - return rect; + return { Rect<dimension> { 0, 0, 0, 0 }, nullptr }; } const Holder& holder = images.emplace(name, Holder{ sprite, rect }).first->second; copy(holder, wrap); - return rect; + return { rect, sprite }; } SpriteAtlasPosition SpriteAtlas::getPosition(const std::string& name, bool repeating) { std::lock_guard<std::recursive_mutex> lock(mtx); - Rect<dimension> rect = getImage(name, repeating); + auto rect = getImage(name, repeating).pos; if (repeating) { // When the image is repeating, get the correct position of the image, rather than the // one rounded up to 4 pixels. @@ -202,35 +164,6 @@ void SpriteAtlas::copy(const Holder& holder, const bool wrap) { dirty = true; } -// void SpriteAtlas::setSprite(util::ptr<Sprite> sprite_) { -// std::lock_guard<std::recursive_mutex> lock(mtx); - -// sprite = sprite_; - -// if (!sprite->isLoaded()) return; - -// util::erase_if(uninitialized, [this](const std::string &name) { -// Rect<dimension> dst = getImage(name, false); -// const SpritePosition& src = sprite->getSpritePosition(name); -// if (!src) { -// if (debug::spriteWarnings) { -// Log::Warning(Event::Sprite, "sprite doesn't have image with name '%s'", name.c_str()); -// } -// return true; -// } - -// if (src.width == dst.w * pixelRatio && src.height == dst.h * pixelRatio && src.pixelRatio == pixelRatio) { -// copy(dst, src, false); -// return true; -// } else { -// if (debug::spriteWarnings) { -// Log::Warning(Event::Sprite, "sprite icon dimension mismatch"); -// } -// return false; -// } -// }); -// } - void SpriteAtlas::upload() { if (dirty) { bind(); @@ -294,7 +227,9 @@ void SpriteAtlas::bind(bool linear) { dirty = false; #ifndef GL_ES_VERSION_2_0 - // platform::showColorDebugImage("Sprite Atlas", reinterpret_cast<const char *>(data), width * pixelRatio, height * pixelRatio, width * pixelRatio, height * pixelRatio); + // platform::showColorDebugImage("Sprite Atlas", reinterpret_cast<const char*>(data.get()), + // width * pixelRatio, height * pixelRatio, width * pixelRatio, + // height * pixelRatio); #endif } }; @@ -306,3 +241,11 @@ SpriteAtlas::~SpriteAtlas() { texture = 0; } } + +SpriteAtlas::Holder::Holder(const std::shared_ptr<const SpriteImage>& texture_, + const Rect<dimension>& pos_) + : texture(texture_), pos(pos_) { +} + +SpriteAtlas::Holder::Holder(Holder&& h) : texture(std::move(h.texture)), pos(h.pos) { +} diff --git a/src/mbgl/geometry/sprite_atlas.hpp b/src/mbgl/geometry/sprite_atlas.hpp index 57e49e3c98..d80b9cb944 100644 --- a/src/mbgl/geometry/sprite_atlas.hpp +++ b/src/mbgl/geometry/sprite_atlas.hpp @@ -29,6 +29,11 @@ struct SpriteAtlasPosition { std::array<float, 2> br; }; +struct SpriteAtlasElement { + const Rect<uint16_t> pos; + const std::shared_ptr<const SpriteImage> texture; +}; + class SpriteAtlas : public util::noncopyable { public: typedef uint16_t dimension; @@ -37,15 +42,12 @@ public: SpriteAtlas(dimension width, dimension height, SpriteStore& store); ~SpriteAtlas(); - // Changes the pixel ratio. - bool resize(float newRatio); - // Returns the coordinates of an image that is sourced from the sprite image. // This getter attempts to read the image from the sprite if it is already loaded. // In that case, it copies it into the sprite atlas and returns the dimensions. // Otherwise, it returns a 0/0/0/0 rect. // This function is used during bucket creation. - Rect<dimension> getImage(const std::string& name, const bool wrap); + SpriteAtlasElement getImage(const std::string& name, const bool wrap); // This function is used for getting the position during render time. SpriteAtlasPosition getPosition(const std::string& name, bool repeating = false); @@ -68,10 +70,9 @@ public: private: struct Holder : private util::noncopyable { - Holder(const std::shared_ptr<const SpriteImage>&, const Rect<dimension>&); - Holder(Holder&&); + inline Holder(const std::shared_ptr<const SpriteImage>&, const Rect<dimension>&); + inline Holder(Holder&&); std::shared_ptr<const SpriteImage> texture; - std::set<uintptr_t> references; const Rect<dimension> pos; }; @@ -80,9 +81,9 @@ private: void copy(const Holder& holder, const bool wrap); std::recursive_mutex mtx; - float pixelRatio = 1.0f; - BinPack<dimension> bin; SpriteStore& store; + const float pixelRatio; + BinPack<dimension> bin; std::map<std::string, Holder> images; std::set<std::string> uninitialized; std::unique_ptr<uint32_t[]> data; diff --git a/src/mbgl/map/map_context.cpp b/src/mbgl/map/map_context.cpp index 455539436f..05a046fdb1 100644 --- a/src/mbgl/map/map_context.cpp +++ b/src/mbgl/map/map_context.cpp @@ -3,6 +3,7 @@ #include <mbgl/map/view.hpp> #include <mbgl/map/still_image.hpp> #include <mbgl/map/annotation.hpp> +#include <mbgl/annotation/sprite_store.hpp> #include <mbgl/platform/log.hpp> @@ -124,7 +125,7 @@ void MapContext::loadStyleJSON(const std::string& json, const std::string& base) assert(util::ThreadContext::currentlyOn(util::ThreadType::Map)); style.reset(); - style = std::make_unique<Style>(json, base, asyncUpdate->get()->loop); + style = std::make_unique<Style>(json, base, data, asyncUpdate->get()->loop); style->cascade(data.getClasses()); style->setDefaultTransitionDuration(data.getDefaultTransitionDuration()); style->setObserver(this); @@ -257,7 +258,7 @@ void MapContext::update() { style->recalculate(transformState.getNormalizedZoom(), now); } - style->update(data, transformState, *texturePool); + style->update(transformState, *texturePool); if (data.mode == MapMode::Continuous) { view.invalidate(); @@ -343,8 +344,12 @@ bool MapContext::isLoaded() const { double MapContext::getTopOffsetPixelsForAnnotationSymbol(const std::string& symbol) { assert(util::ThreadContext::currentlyOn(util::ThreadType::Map)); - const SpritePosition pos = style->sprite->getSpritePosition(symbol); - return -pos.height / pos.pixelRatio / 2; + auto sprite = style->spriteStore->getSprite(symbol); + if (sprite) { + return -sprite->height / 2; + } else { + return 0; + } } void MapContext::setSourceTileCacheSize(size_t size) { diff --git a/src/mbgl/map/sprite.cpp b/src/mbgl/map/sprite.cpp index 6a310c21cc..589f56f99e 100644 --- a/src/mbgl/map/sprite.cpp +++ b/src/mbgl/map/sprite.cpp @@ -17,20 +17,8 @@ using namespace mbgl; -SpritePosition::SpritePosition(uint16_t x_, uint16_t y_, uint16_t width_, uint16_t height_, float pixelRatio_, bool sdf_) - : x(x_), - y(y_), - width(width_), - height(height_), - pixelRatio(pixelRatio_), - sdf(sdf_) { -} - Sprite::Sprite(const std::string& baseUrl, float pixelRatio_) - : pixelRatio(pixelRatio_ > 1 ? 2 : 1), - raster(), - loadedImage(false), - loadedJSON(false) { + : pixelRatio(pixelRatio_ > 1 ? 2 : 1) { if (baseUrl.empty()) { // Treat a non-existent sprite as a successfully loaded empty sprite. loadedImage = true; @@ -45,8 +33,8 @@ Sprite::Sprite(const std::string& baseUrl, float pixelRatio_) jsonRequest = fs->request({ Resource::Kind::JSON, jsonURL }, util::RunLoop::getLoop(), [this, jsonURL](const Response &res) { jsonRequest = nullptr; if (res.status == Response::Successful) { - body = res.data; - parseJSON(jsonURL); + json = res.data; + loadedJSON = true; } else { std::stringstream message; message << "Failed to load [" << jsonURL << "]: " << res.message; @@ -60,7 +48,7 @@ Sprite::Sprite(const std::string& baseUrl, float pixelRatio_) spriteRequest = nullptr; if (res.status == Response::Successful) { image = res.data; - parseImage(spriteURL); + loadedImage = true; } else { std::stringstream message; message << "Failed to load [" << spriteURL << "]: " << res.message; @@ -100,69 +88,6 @@ bool Sprite::isLoaded() const { return loadedImage && loadedJSON; } -bool Sprite::hasPixelRatio(float ratio) const { - return pixelRatio == (ratio > 1 ? 2 : 1); -} - -void Sprite::parseImage(const std::string& spriteURL) { - raster = std::make_unique<util::Image>(image); - if (!*raster) { - raster.reset(); - std::stringstream message; - message << "Failed to parse [" << spriteURL << "]"; - emitSpriteLoadingFailed(message.str()); - return; - } - - image.clear(); - loadedImage = true; -} - -void Sprite::parseJSON(const std::string& jsonURL) { - rapidjson::Document d; - d.Parse<0>(body.c_str()); - body.clear(); - - if (d.HasParseError()) { - std::stringstream message; - message << "Failed to parse [" << jsonURL << "]: " << d.GetErrorOffset() << " - " << d.GetParseError(); - emitSpriteLoadingFailed(message.str()); - } else if (d.IsObject()) { - for (rapidjson::Value::ConstMemberIterator itr = d.MemberBegin(); itr != d.MemberEnd(); ++itr) { - const std::string name = { itr->name.GetString(), itr->name.GetStringLength() }; - const rapidjson::Value& value = itr->value; - - if (value.IsObject()) { - uint16_t x = 0; - uint16_t y = 0; - uint16_t width = 0; - uint16_t height = 0; - float spritePixelRatio = 1.0f; - bool sdf = false; - - if (value.HasMember("x")) x = value["x"].GetInt(); - if (value.HasMember("y")) y = value["y"].GetInt(); - if (value.HasMember("width")) width = value["width"].GetInt(); - if (value.HasMember("height")) height = value["height"].GetInt(); - if (value.HasMember("pixelRatio")) spritePixelRatio = value["pixelRatio"].GetInt(); - if (value.HasMember("sdf")) sdf = value["sdf"].GetBool(); - pos.emplace(name, SpritePosition { x, y, width, height, spritePixelRatio, sdf }); - } - } - loadedJSON = true; - } else { - std::stringstream message; - message << "Failed to parse [" << jsonURL << "]: Root is not an object"; - emitSpriteLoadingFailed(message.str()); - } -} - -const SpritePosition &Sprite::getSpritePosition(const std::string& name) const { - if (!isLoaded()) return empty; - auto it = pos.find(name); - return it == pos.end() ? empty : it->second; -} - void Sprite::setObserver(Observer* observer_) { observer = observer_; } diff --git a/src/mbgl/map/sprite.hpp b/src/mbgl/map/sprite.hpp index 47b871faf7..e4905ddbe9 100644 --- a/src/mbgl/map/sprite.hpp +++ b/src/mbgl/map/sprite.hpp @@ -16,21 +16,6 @@ namespace mbgl { class Request; -class SpritePosition { -public: - explicit SpritePosition() {} - explicit SpritePosition(uint16_t x, uint16_t y, uint16_t width, uint16_t height, float pixelRatio, bool sdf); - - operator bool() const { - return !(width == 0 && height == 0 && x == 0 && y == 0); - } - - uint16_t x = 0, y = 0; - uint16_t width = 0, height = 0; - float pixelRatio = 1.0f; - bool sdf = false; -}; - class Sprite : private util::noncopyable { public: class Observer { @@ -44,29 +29,24 @@ public: Sprite(const std::string& baseUrl, float pixelRatio); ~Sprite(); - const SpritePosition &getSpritePosition(const std::string& name) const; - - bool hasPixelRatio(float ratio) const; - bool isLoaded() const; const float pixelRatio; - std::unique_ptr<util::Image> raster; void setObserver(Observer* observer); + + inline const std::string& getImage() const { return image; } + inline const std::string& getJSON() const { return json; } + private: void emitSpriteLoadedIfComplete(); void emitSpriteLoadingFailed(const std::string& message); - void parseJSON(const std::string& jsonURL); - void parseImage(const std::string& spriteURL); + bool loadedJSON = false; + std::string json; - std::string body; + bool loadedImage = false; std::string image; - std::atomic<bool> loadedImage; - std::atomic<bool> loadedJSON; - std::unordered_map<std::string, SpritePosition> pos; - const SpritePosition empty; Request* jsonRequest = nullptr; Request* spriteRequest = nullptr; diff --git a/src/mbgl/map/tile_worker.cpp b/src/mbgl/map/tile_worker.cpp index e8c8e15b26..6edfe3b1bd 100644 --- a/src/mbgl/map/tile_worker.cpp +++ b/src/mbgl/map/tile_worker.cpp @@ -265,8 +265,8 @@ std::unique_ptr<Bucket> TileWorker::createSymbolBucket(const GeometryTileLayer& return nullptr; } - bucket->addFeatures( - reinterpret_cast<uintptr_t>(this), *style.spriteAtlas, *style.sprite, *style.glyphAtlas, *style.glyphStore); + bucket->addFeatures(reinterpret_cast<uintptr_t>(this), *style.spriteAtlas, *style.glyphAtlas, + *style.glyphStore); return bucket->hasData() ? std::move(bucket) : nullptr; } diff --git a/src/mbgl/renderer/symbol_bucket.cpp b/src/mbgl/renderer/symbol_bucket.cpp index d52561d3ec..47087422ec 100644 --- a/src/mbgl/renderer/symbol_bucket.cpp +++ b/src/mbgl/renderer/symbol_bucket.cpp @@ -1,6 +1,7 @@ #include <mbgl/renderer/symbol_bucket.hpp> #include <mbgl/map/geometry_tile.hpp> #include <mbgl/style/style_layout.hpp> +#include <mbgl/annotation/sprite_image.hpp> #include <mbgl/geometry/text_buffer.hpp> #include <mbgl/geometry/icon_buffer.hpp> #include <mbgl/geometry/glyph_atlas.hpp> @@ -172,7 +173,6 @@ bool SymbolBucket::needsDependencies(const GeometryTileLayer& layer, void SymbolBucket::addFeatures(uintptr_t tileUID, SpriteAtlas& spriteAtlas, - Sprite& sprite, GlyphAtlas& glyphAtlas, GlyphStore& glyphStore) { float horizontalAlign = 0.5; @@ -246,11 +246,13 @@ void SymbolBucket::addFeatures(uintptr_t tileUID, // if feature has icon, get sprite atlas position if (feature.sprite.length()) { - Rect<uint16_t> image = spriteAtlas.getImage(feature.sprite, false); - shapedIcon = shapeIcon(image, layout); - - if (sprite.getSpritePosition(feature.sprite).sdf) { - sdfIcons = true; + auto image = spriteAtlas.getImage(feature.sprite, false); + if (image.pos.hasArea() && image.texture) { + shapedIcon = shapeIcon(image.pos, layout); + assert(image.texture); + if (image.texture->sdf) { + sdfIcons = true; + } } } diff --git a/src/mbgl/renderer/symbol_bucket.hpp b/src/mbgl/renderer/symbol_bucket.hpp index 5654f9b2ba..a5c98fbf32 100644 --- a/src/mbgl/renderer/symbol_bucket.hpp +++ b/src/mbgl/renderer/symbol_bucket.hpp @@ -76,7 +76,6 @@ public: void addFeatures(uintptr_t tileUID, SpriteAtlas&, - Sprite&, GlyphAtlas&, GlyphStore&); diff --git a/src/mbgl/style/style.cpp b/src/mbgl/style/style.cpp index 91aeed11a0..93235d2a1f 100644 --- a/src/mbgl/style/style.cpp +++ b/src/mbgl/style/style.cpp @@ -3,6 +3,8 @@ #include <mbgl/map/map_data.hpp> #include <mbgl/map/source.hpp> #include <mbgl/map/transform_state.hpp> +#include <mbgl/annotation/sprite_store.hpp> +#include <mbgl/annotation/sprite_parser.hpp> #include <mbgl/style/style_layer.hpp> #include <mbgl/style/style_parser.hpp> #include <mbgl/style/style_bucket.hpp> @@ -20,17 +22,19 @@ namespace mbgl { -Style::Style(const std::string& data, const std::string&, +Style::Style(const std::string& json, const std::string&, MapData& data_, uv_loop_t* loop) - : glyphStore(std::make_unique<GlyphStore>(loop)), + : data(data_), + glyphStore(std::make_unique<GlyphStore>(loop)), glyphAtlas(std::make_unique<GlyphAtlas>(1024, 1024)), + spriteStore(std::make_unique<SpriteStore>(data.pixelRatio)), spriteAtlas(std::make_unique<SpriteAtlas>(512, 512, *spriteStore)), 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()); + doc.Parse<0>((const char *const)json.c_str()); if (doc.HasParseError()) { Log::Error(Event::ParseStyle, "Error parsing style JSON at %i: %s", doc.GetErrorOffset(), doc.GetParseError()); return; @@ -42,7 +46,9 @@ Style::Style(const std::string& data, const std::string&, sources = parser.getSources(); layers = parser.getLayers(); - spriteURL = parser.getSprite(); + sprite = std::make_unique<Sprite>(parser.getSprite(), data.pixelRatio); + sprite->setObserver(this); + glyphStore->setURL(parser.getGlyphURL()); for (const auto& source : sources) { @@ -65,17 +71,8 @@ Style::~Style() { } } -void Style::update(MapData& data, - const TransformState& transform, +void Style::update(const TransformState& transform, TexturePool& texturePool) { - if (!sprite || !sprite->hasPixelRatio(data.pixelRatio)) { - sprite = std::make_unique<Sprite>(spriteURL, data.pixelRatio); - sprite->setObserver(this); - - spriteAtlas->resize(data.pixelRatio); - spriteAtlas->setSprite(sprite); - } - bool allTilesUpdated = true; for (const auto& source : sources) { if (!source->update(data, transform, *this, texturePool, shouldReparsePartialTiles)) { @@ -195,6 +192,9 @@ void Style::onTileLoadingFailed(std::exception_ptr error) { } void Style::onSpriteLoaded() { + // Add all sprite images to the SpriteStore object + spriteStore->setSprites(parseSprite(sprite->getImage(), sprite->getJSON())); + shouldReparsePartialTiles = true; emitTileDataChanged(); diff --git a/src/mbgl/style/style.hpp b/src/mbgl/style/style.hpp index d96833da25..3362ce7f73 100644 --- a/src/mbgl/style/style.hpp +++ b/src/mbgl/style/style.hpp @@ -22,6 +22,7 @@ namespace mbgl { class GlyphAtlas; class GlyphStore; +class SpriteStore; class SpriteAtlas; class LineAtlas; class StyleLayer; @@ -33,6 +34,7 @@ class Style : public GlyphStore::Observer, public: Style(const std::string& data, const std::string& base, + MapData&, uv_loop_t*); ~Style(); @@ -50,7 +52,7 @@ public: // Fetch the tiles needed by the current viewport and emit a signal when // a tile is ready so observers can render the tile. - void update(MapData&, const TransformState&, TexturePool&); + void update(const TransformState&, TexturePool&); void cascade(const std::vector<std::string>&); void recalculate(float z, TimePoint now); @@ -64,9 +66,11 @@ public: Source* getSource(const std::string& id) const; + MapData& data; std::unique_ptr<GlyphStore> glyphStore; std::unique_ptr<GlyphAtlas> glyphAtlas; util::ptr<Sprite> sprite; + std::unique_ptr<SpriteStore> spriteStore; std::unique_ptr<SpriteAtlas> spriteAtlas; std::unique_ptr<LineAtlas> lineAtlas; @@ -97,7 +101,6 @@ private: std::exception_ptr lastError; - std::string spriteURL; PropertyTransition defaultTransition; std::unique_ptr<uv::rwlock> mtx; ZoomHistory zoomHistory; diff --git a/test/style/resource_loading.cpp b/test/style/resource_loading.cpp index 071df09338..8c92a1d099 100644 --- a/test/style/resource_loading.cpp +++ b/test/style/resource_loading.cpp @@ -32,7 +32,7 @@ public: transform_.setLatLngZoom({0, 0}, 16); const std::string style = util::read_file("test/fixtures/resources/style.json"); - style_ = std::make_unique<Style>(style, "", util::RunLoop::getLoop()); + style_ = std::make_unique<Style>(style, "", data_, util::RunLoop::getLoop()); style_->setObserver(this); } @@ -46,7 +46,7 @@ public: data_.setAnimationTime(now); transform_.updateTransitions(now); - style_->update(data_, transform_.getState(), texturePool_); + style_->update(transform_.getState(), texturePool_); } // Style::Observer implementation. |