diff options
-rw-r--r-- | src/mbgl/geometry/sprite_atlas.cpp | 93 | ||||
-rw-r--r-- | src/mbgl/geometry/sprite_atlas.hpp | 22 | ||||
-rw-r--r-- | src/mbgl/style/style.cpp | 2 |
3 files changed, 62 insertions, 55 deletions
diff --git a/src/mbgl/geometry/sprite_atlas.cpp b/src/mbgl/geometry/sprite_atlas.cpp index 799f43b161..b3d2ba7249 100644 --- a/src/mbgl/geometry/sprite_atlas.cpp +++ b/src/mbgl/geometry/sprite_atlas.cpp @@ -1,4 +1,5 @@ #include <mbgl/geometry/sprite_atlas.hpp> +#include <mbgl/annotation/sprite_store.hpp> #include <mbgl/platform/gl.hpp> #include <mbgl/platform/log.hpp> #include <mbgl/platform/platform.hpp> @@ -18,10 +19,11 @@ using namespace mbgl; -SpriteAtlas::SpriteAtlas(dimension width_, dimension height_) +SpriteAtlas::SpriteAtlas(dimension width_, dimension height_, SpriteStore& store_) : width(width_), height(height_), bin(width_, height_), + store(store_), dirty(true) { } @@ -89,15 +91,15 @@ Rect<SpriteAtlas::dimension> SpriteAtlas::getImage(const std::string& name, cons auto rect_it = images.find(name); if (rect_it != images.end()) { - return rect_it->second; + return rect_it->second.pos; } - const SpritePosition &pos = sprite->getSpritePosition(name); - if (!pos.width || !pos.height) { + auto sprite = store.getSprite(name); + if (!sprite) { return Rect<dimension> { 0, 0, 0, 0 }; } - Rect<dimension> rect = allocateImage(pos.width / pos.pixelRatio, pos.height / pos.pixelRatio); + Rect<dimension> rect = allocateImage(sprite->width, sprite->height); if (rect.w == 0) { if (debug::spriteWarnings) { Log::Warning(Event::Sprite, "sprite atlas bitmap overflow"); @@ -105,9 +107,8 @@ Rect<SpriteAtlas::dimension> SpriteAtlas::getImage(const std::string& name, cons return rect; } - images.emplace(name, rect); - - copy(rect, pos, wrap); + const Holder& holder = images.emplace(name, Holder{ sprite, rect }).first->second; + copy(holder, wrap); return rect; } @@ -119,13 +120,14 @@ SpriteAtlasPosition SpriteAtlas::getPosition(const std::string& name, bool repea if (repeating) { // When the image is repeating, get the correct position of the image, rather than the // one rounded up to 4 pixels. - const SpritePosition &pos = sprite->getSpritePosition(name); - if (!pos.width || !pos.height) { + // TODO: Can't we just use originalW/originalH? + auto sprite = store.getSprite(name); + if (!sprite) { return SpriteAtlasPosition {}; } - rect.w = pos.width / pos.pixelRatio; - rect.h = pos.height / pos.pixelRatio; + rect.w = sprite->width; + rect.h = sprite->height; } const float padding = 1; @@ -146,13 +148,12 @@ void SpriteAtlas::allocate() { } } -void SpriteAtlas::copy(const Rect<dimension>& dst, const SpritePosition& src, const bool wrap) { - if (!sprite->raster) return; - - const uint32_t *srcData = reinterpret_cast<const uint32_t *>(sprite->raster->getData()); +void SpriteAtlas::copy(const Holder& holder, const bool wrap) { + const uint32_t *srcData = reinterpret_cast<const uint32_t *>(holder.texture->data.data()); if (!srcData) return; - const vec2<uint32_t> srcSize { sprite->raster->getWidth(), sprite->raster->getHeight() }; - const Rect<uint32_t> srcPos { src.x, src.y, src.width, src.height }; + const vec2<uint32_t> srcSize { holder.texture->pixelWidth, holder.texture->pixelHeight }; + const Rect<uint32_t> srcPos { 0, 0, srcSize.x, srcSize.y }; + const auto& dst = holder.pos; const int offset = 1; @@ -201,34 +202,34 @@ void SpriteAtlas::copy(const Rect<dimension>& dst, const SpritePosition& src, co 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::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) { diff --git a/src/mbgl/geometry/sprite_atlas.hpp b/src/mbgl/geometry/sprite_atlas.hpp index 3da472fa72..57e49e3c98 100644 --- a/src/mbgl/geometry/sprite_atlas.hpp +++ b/src/mbgl/geometry/sprite_atlas.hpp @@ -15,7 +15,8 @@ namespace mbgl { -class Sprite; +class SpriteStore; +class SpriteImage; class SpritePosition; struct SpriteAtlasPosition { @@ -33,15 +34,12 @@ public: typedef uint16_t dimension; // Add way to construct this from another SpriteAtlas (e.g. with another pixelRatio) - SpriteAtlas(dimension width, dimension height); + SpriteAtlas(dimension width, dimension height, SpriteStore& store); ~SpriteAtlas(); // Changes the pixel ratio. bool resize(float newRatio); - // Changes the source sprite. - void setSprite(util::ptr<Sprite> sprite); - // 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. @@ -69,15 +67,23 @@ public: const dimension height = 0; private: + struct Holder : private util::noncopyable { + Holder(const std::shared_ptr<const SpriteImage>&, const Rect<dimension>&); + Holder(Holder&&); + std::shared_ptr<const SpriteImage> texture; + std::set<uintptr_t> references; + const Rect<dimension> pos; + }; + void allocate(); Rect<SpriteAtlas::dimension> allocateImage(size_t width, size_t height); - void copy(const Rect<dimension>& dst, const SpritePosition& src, const bool wrap); + void copy(const Holder& holder, const bool wrap); std::recursive_mutex mtx; float pixelRatio = 1.0f; BinPack<dimension> bin; - util::ptr<Sprite> sprite; - std::map<std::string, Rect<dimension>> images; + SpriteStore& store; + std::map<std::string, Holder> images; std::set<std::string> uninitialized; std::unique_ptr<uint32_t[]> data; std::atomic<bool> dirty; diff --git a/src/mbgl/style/style.cpp b/src/mbgl/style/style.cpp index c844a656d9..91aeed11a0 100644 --- a/src/mbgl/style/style.cpp +++ b/src/mbgl/style/style.cpp @@ -24,7 +24,7 @@ Style::Style(const std::string& data, const std::string&, uv_loop_t* loop) : glyphStore(std::make_unique<GlyphStore>(loop)), glyphAtlas(std::make_unique<GlyphAtlas>(1024, 1024)), - spriteAtlas(std::make_unique<SpriteAtlas>(512, 512)), + spriteAtlas(std::make_unique<SpriteAtlas>(512, 512, *spriteStore)), lineAtlas(std::make_unique<LineAtlas>(512, 512)), mtx(std::make_unique<uv::rwlock>()), workers(4) { |