From d2ee014c6e15e24aabf0ce600fb61d738cc6cb38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20K=C3=A4fer?= Date: Wed, 1 Jul 2015 13:52:59 +0200 Subject: [PATCH] move SpriteAtlas to the SpriteStore backend --- src/mbgl/geometry/sprite_atlas.cpp | 85 +++++++++++++++--------------- src/mbgl/geometry/sprite_atlas.hpp | 22 +++++--- src/mbgl/style/style.cpp | 2 +- 3 files changed, 58 insertions(+), 51 deletions(-) diff --git a/src/mbgl/geometry/sprite_atlas.cpp b/src/mbgl/geometry/sprite_atlas.cpp index 799f43b16..b3d2ba724 100644 --- a/src/mbgl/geometry/sprite_atlas.cpp +++ b/src/mbgl/geometry/sprite_atlas.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -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::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 { 0, 0, 0, 0 }; } - Rect rect = allocateImage(pos.width / pos.pixelRatio, pos.height / pos.pixelRatio); + Rect 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::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& dst, const SpritePosition& src, const bool wrap) { - if (!sprite->raster) return; - - const uint32_t *srcData = reinterpret_cast(sprite->raster->getData()); +void SpriteAtlas::copy(const Holder& holder, const bool wrap) { + const uint32_t *srcData = reinterpret_cast(holder.texture->data.data()); if (!srcData) return; - const vec2 srcSize { sprite->raster->getWidth(), sprite->raster->getHeight() }; - const Rect srcPos { src.x, src.y, src.width, src.height }; + const vec2 srcSize { holder.texture->pixelWidth, holder.texture->pixelHeight }; + const Rect 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& dst, const SpritePosition& src, co dirty = true; } -void SpriteAtlas::setSprite(util::ptr sprite_) { - std::lock_guard lock(mtx); +// void SpriteAtlas::setSprite(util::ptr sprite_) { +// std::lock_guard lock(mtx); - sprite = sprite_; +// sprite = sprite_; - if (!sprite->isLoaded()) return; +// if (!sprite->isLoaded()) return; - util::erase_if(uninitialized, [this](const std::string &name) { - Rect 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; - } +// util::erase_if(uninitialized, [this](const std::string &name) { +// Rect 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; - } - }); -} +// 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 3da472fa7..57e49e3c9 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); - // 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 Rect&); + Holder(Holder&&); + std::shared_ptr texture; + std::set references; + const Rect pos; + }; + void allocate(); Rect allocateImage(size_t width, size_t height); - void copy(const Rect& dst, const SpritePosition& src, const bool wrap); + void copy(const Holder& holder, const bool wrap); std::recursive_mutex mtx; float pixelRatio = 1.0f; BinPack bin; - util::ptr sprite; - std::map> images; + SpriteStore& store; + std::map images; std::set uninitialized; std::unique_ptr data; std::atomic dirty; diff --git a/src/mbgl/style/style.cpp b/src/mbgl/style/style.cpp index c844a656d..91aeed11a 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(loop)), glyphAtlas(std::make_unique(1024, 1024)), - spriteAtlas(std::make_unique(512, 512)), + spriteAtlas(std::make_unique(512, 512, *spriteStore)), lineAtlas(std::make_unique(512, 512)), mtx(std::make_unique()), workers(4) {