summaryrefslogtreecommitdiff
path: root/src/mbgl/sprite
diff options
context:
space:
mode:
authorChris Loer <chris.loer@gmail.com>2017-03-31 14:53:18 -0700
committerChris Loer <chris.loer@mapbox.com>2017-04-04 11:33:12 -0700
commit5cdf838a387cae446dba500ac49a1c5524bf7949 (patch)
tree3b438034a7842c36a7804096785fca1a6ad6fa80 /src/mbgl/sprite
parent64beba3accb0f2088b2e01fad710f915c81d99c7 (diff)
downloadqtlocation-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.cpp45
-rw-r--r--src/mbgl/sprite/sprite_atlas.hpp32
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