diff options
author | Chris Loer <chris.loer@gmail.com> | 2017-03-31 14:53:18 -0700 |
---|---|---|
committer | Chris Loer <chris.loer@mapbox.com> | 2017-04-04 11:33:12 -0700 |
commit | 5cdf838a387cae446dba500ac49a1c5524bf7949 (patch) | |
tree | 3b438034a7842c36a7804096785fca1a6ad6fa80 /src/mbgl/sprite | |
parent | 64beba3accb0f2088b2e01fad710f915c81d99c7 (diff) | |
download | qtlocation-mapboxgl-5cdf838a387cae446dba500ac49a1c5524bf7949.tar.gz |
[core] De-mutex GlyphAtlas and SpriteAtlas
- Expose glyph and icon information to workers via message interface.
- Glyph/SpriteAtlas track which tiles have outstanding requests
and send messages to them when glyphs/icons become available.
- Remove obsolete "updateSymbolDependentTiles" pathway
- Symbol preparation for a tile now depends on all glyphs becoming
available before it can start.
- Start tracking individual icons needed for a tile, although we don't
do anything with the information yet.
- Introduce typedef for GlyphID
Diffstat (limited to 'src/mbgl/sprite')
-rw-r--r-- | src/mbgl/sprite/sprite_atlas.cpp | 45 | ||||
-rw-r--r-- | src/mbgl/sprite/sprite_atlas.hpp | 32 |
2 files changed, 62 insertions, 15 deletions
diff --git a/src/mbgl/sprite/sprite_atlas.cpp b/src/mbgl/sprite/sprite_atlas.cpp index 2bf8a3095a..bdccf289df 100644 --- a/src/mbgl/sprite/sprite_atlas.cpp +++ b/src/mbgl/sprite/sprite_atlas.cpp @@ -28,11 +28,13 @@ struct SpriteAtlas::Loader { }; SpriteAtlasElement::SpriteAtlasElement(Rect<uint16_t> rect_, - std::shared_ptr<const SpriteImage> image_, + std::shared_ptr<const SpriteImage> spriteImage, Size size_, float pixelRatio) : pos(std::move(rect_)), - spriteImage(std::move(image_)), - relativePixelRatio(spriteImage->pixelRatio / pixelRatio) { + sdf(spriteImage->sdf), + relativePixelRatio(spriteImage->pixelRatio / pixelRatio), + width(spriteImage->getWidth()), + height(spriteImage->getHeight()) { const float padding = 1; @@ -105,6 +107,10 @@ void SpriteAtlas::emitSpriteLoadedIfComplete() { loaded = true; setSprites(result.get<Sprites>()); observer->onSpriteLoaded(); + for (auto requestor : requestors) { + requestor->onIconsAvailable(this, buildIconMap()); + } + requestors.clear(); } else { observer->onSpriteError(result.get<std::exception_ptr>()); } @@ -119,20 +125,17 @@ void SpriteAtlas::dumpDebugLogs() const { } void SpriteAtlas::setSprites(const Sprites& newSprites) { - std::lock_guard<std::mutex> lock(mutex); for (const auto& pair : newSprites) { _setSprite(pair.first, pair.second); } } void SpriteAtlas::setSprite(const std::string& name, std::shared_ptr<const SpriteImage> sprite) { - std::lock_guard<std::mutex> lock(mutex); _setSprite(name, sprite); } void SpriteAtlas::removeSprite(const std::string& name) { - std::lock_guard<std::mutex> lock(mutex); - + icons.clear(); auto it = entries.find(name); if (it == entries.end()) { return; @@ -153,6 +156,7 @@ void SpriteAtlas::removeSprite(const std::string& name) { void SpriteAtlas::_setSprite(const std::string& name, const std::shared_ptr<const SpriteImage>& sprite) { + icons.clear(); if (!sprite->image.valid()) { Log::Warning(Event::Sprite, "invalid sprite image '%s'", name.c_str()); return; @@ -184,7 +188,6 @@ void SpriteAtlas::_setSprite(const std::string& name, } std::shared_ptr<const SpriteImage> SpriteAtlas::getSprite(const std::string& name) { - std::lock_guard<std::mutex> lock(mutex); const auto it = entries.find(name); if (it != entries.end()) { return it->second.spriteImage; @@ -196,6 +199,18 @@ std::shared_ptr<const SpriteImage> SpriteAtlas::getSprite(const std::string& nam } } +void SpriteAtlas::getIcons(IconRequestor& requestor) { + if (isLoaded()) { + requestor.onIconsAvailable(this, buildIconMap()); + } else { + requestors.insert(&requestor); + } +} + +void SpriteAtlas::removeRequestor(IconRequestor& requestor) { + requestors.erase(&requestor); +} + optional<SpriteAtlasElement> SpriteAtlas::getIcon(const std::string& name) { return getImage(name, &Entry::iconRect); } @@ -206,7 +221,6 @@ optional<SpriteAtlasElement> SpriteAtlas::getPattern(const std::string& name) { optional<SpriteAtlasElement> SpriteAtlas::getImage(const std::string& name, optional<Rect<uint16_t>> Entry::*entryRect) { - std::lock_guard<std::mutex> lock(mutex); auto it = entries.find(name); if (it == entries.end()) { @@ -219,6 +233,7 @@ optional<SpriteAtlasElement> SpriteAtlas::getImage(const std::string& name, Entry& entry = it->second; if (entry.*entryRect) { + assert(entry.spriteImage.get()); return SpriteAtlasElement { *(entry.*entryRect), entry.spriteImage, @@ -285,6 +300,18 @@ void SpriteAtlas::copy(const Entry& entry, optional<Rect<uint16_t>> Entry::*entr dirty = true; } +IconMap SpriteAtlas::buildIconMap() { + if (icons.empty()) { + for (auto entry : entries) { + icons.emplace(std::piecewise_construct, + std::forward_as_tuple(entry.first), + std::forward_as_tuple(*getIcon(entry.first))); + + } + } + return icons; +} + void SpriteAtlas::upload(gl::Context& context, gl::TextureUnit unit) { if (!texture) { texture = context.createTexture(image, unit); diff --git a/src/mbgl/sprite/sprite_atlas.hpp b/src/mbgl/sprite/sprite_atlas.hpp index c7b266376b..3c37f57708 100644 --- a/src/mbgl/sprite/sprite_atlas.hpp +++ b/src/mbgl/sprite/sprite_atlas.hpp @@ -6,10 +6,9 @@ #include <mbgl/util/optional.hpp> #include <mbgl/sprite/sprite_image.hpp> -#include <atomic> #include <string> #include <map> -#include <mutex> +#include <set> #include <unordered_map> #include <array> #include <memory> @@ -28,12 +27,26 @@ public: SpriteAtlasElement(Rect<uint16_t>, std::shared_ptr<const SpriteImage>, Size size, float pixelRatio); Rect<uint16_t> pos; - std::shared_ptr<const SpriteImage> spriteImage; + bool sdf; float relativePixelRatio; std::array<float, 2> size; std::array<float, 2> tl; std::array<float, 2> br; + float width; + float height; +}; + +class SpriteAtlas; + +typedef std::map<std::string,SpriteAtlasElement> IconMap; +typedef std::set<std::string> IconDependencies; +typedef std::map<uintptr_t,IconMap> IconAtlasMap; +typedef std::map<SpriteAtlas*,IconDependencies> IconDependencyMap; + +class IconRequestor { +public: + virtual void onIconsAvailable(SpriteAtlas*, IconMap) = 0; }; class SpriteAtlas : public util::noncopyable { @@ -55,8 +68,11 @@ public: void setSprite(const std::string&, std::shared_ptr<const SpriteImage>); void removeSprite(const std::string&); + + std::shared_ptr<const SpriteImage> getSprite(const std::string& name); - std::shared_ptr<const SpriteImage> getSprite(const std::string&); + void getIcons(IconRequestor& requestor); + void removeRequestor(IconRequestor& requestor); optional<SpriteAtlasElement> getIcon(const std::string& name); optional<SpriteAtlasElement> getPattern(const std::string& name); @@ -105,13 +121,17 @@ private: optional<SpriteAtlasElement> getImage(const std::string& name, optional<Rect<uint16_t>> Entry::*rect); void copy(const Entry&, optional<Rect<uint16_t>> Entry::*rect); + + IconMap buildIconMap(); - std::mutex mutex; std::unordered_map<std::string, Entry> entries; BinPack<uint16_t> bin; PremultipliedImage image; mbgl::optional<gl::Texture> texture; - std::atomic<bool> dirty; + bool dirty; + + std::set<IconRequestor*> requestors; + IconMap icons; }; } // namespace mbgl |