[core] Eliminate SpriteAtlas::Holder

This commit is contained in:
John Firebaugh
2017-02-13 13:52:16 -08:00
parent 44fa4d6aad
commit 3fa6a4f4ff
2 changed files with 25 additions and 37 deletions

View File

@@ -183,9 +183,9 @@ optional<SpriteAtlasElement> SpriteAtlas::getImage(const std::string& name,
const SpritePatternMode mode) {
std::lock_guard<std::recursive_mutex> lock(mtx);
auto rect_it = images.find({ name, mode });
if (rect_it != images.end()) {
return SpriteAtlasElement { rect_it->second.pos, rect_it->second.spriteImage, rect_it->second.spriteImage->pixelRatio / pixelRatio };
auto it = images.find({ name, mode });
if (it != images.end()) {
return it->second;
}
auto sprite = getSprite(name);
@@ -201,10 +201,12 @@ optional<SpriteAtlasElement> SpriteAtlas::getImage(const std::string& name,
return {};
}
const Holder& holder = images.emplace(Key{ name, mode }, Holder{ sprite, rect }).first->second;
copy(holder, mode);
SpriteAtlasElement element { rect, sprite, sprite->pixelRatio / pixelRatio };
return SpriteAtlasElement { rect, sprite, sprite->pixelRatio / pixelRatio };
images.emplace(Key{ name, mode }, element);
copy(sprite->image, rect, mode);
return element;
}
optional<SpriteAtlasPosition> SpriteAtlas::getPosition(const std::string& name,
@@ -231,31 +233,31 @@ optional<SpriteAtlasPosition> SpriteAtlas::getPosition(const std::string& name,
};
}
void SpriteAtlas::copy(const Holder& holder, const SpritePatternMode mode) {
void SpriteAtlas::copy(const PremultipliedImage& src, Rect<uint16_t> pos, const SpritePatternMode mode) {
if (!image.valid()) {
image = PremultipliedImage({ static_cast<uint32_t>(std::ceil(size.width * pixelRatio)),
static_cast<uint32_t>(std::ceil(size.height * pixelRatio)) });
image.fill(0);
}
if (!holder.spriteImage->image.valid()) {
if (!src.valid()) {
return;
}
const uint32_t padding = 1;
const uint32_t x = (holder.pos.x + padding) * pixelRatio;
const uint32_t y = (holder.pos.y + padding) * pixelRatio;
const uint32_t w = holder.spriteImage->image.size.width;
const uint32_t h = holder.spriteImage->image.size.height;
const uint32_t x = (pos.x + padding) * pixelRatio;
const uint32_t y = (pos.y + padding) * pixelRatio;
const uint32_t w = src.size.width;
const uint32_t h = src.size.height;
PremultipliedImage::copy(holder.spriteImage->image, image, { 0, 0 }, { x, y }, { w, h });
PremultipliedImage::copy(src, image, { 0, 0 }, { x, y }, { w, h });
if (mode == SpritePatternMode::Repeating) {
// Add 1 pixel wrapped padding on each side of the image.
PremultipliedImage::copy(holder.spriteImage->image, image, { 0, h - 1 }, { x, y - 1 }, { w, 1 }); // T
PremultipliedImage::copy(holder.spriteImage->image, image, { 0, 0 }, { x, y + h }, { w, 1 }); // B
PremultipliedImage::copy(holder.spriteImage->image, image, { w - 1, 0 }, { x - 1, y }, { 1, h }); // L
PremultipliedImage::copy(holder.spriteImage->image, image, { 0, 0 }, { x + w, y }, { 1, h }); // R
PremultipliedImage::copy(src, image, { 0, h - 1 }, { x, y - 1 }, { w, 1 }); // T
PremultipliedImage::copy(src, image, { 0, 0 }, { x, y + h }, { w, 1 }); // B
PremultipliedImage::copy(src, image, { w - 1, 0 }, { x - 1, y }, { 1, h }); // L
PremultipliedImage::copy(src, image, { 0, 0 }, { x + w, y }, { 1, h }); // R
}
dirty = true;
@@ -273,10 +275,10 @@ void SpriteAtlas::updateDirty() {
++spriteIterator;
} else {
// The two names match;
Holder& holder = imageIterator->second;
holder.spriteImage = spriteIterator->second;
if (holder.spriteImage != nullptr) {
copy(holder, imageIterator->first.second);
auto& element = imageIterator->second;
element.spriteImage = spriteIterator->second;
if (element.spriteImage != nullptr) {
copy(element.spriteImage->image, element.pos, imageIterator->first.second);
++imageIterator;
} else {
images.erase(imageIterator++);
@@ -313,11 +315,4 @@ void SpriteAtlas::bind(bool linear, gl::Context& context, gl::TextureUnit unit)
linear ? gl::TextureFilter::Linear : gl::TextureFilter::Nearest);
}
SpriteAtlas::Holder::Holder(std::shared_ptr<const SpriteImage> spriteImage_, Rect<uint16_t> pos_)
: spriteImage(std::move(spriteImage_)), pos(std::move(pos_)) {
}
SpriteAtlas::Holder::Holder(Holder&& h) : spriteImage(std::move(h.spriteImage)), pos(h.pos) {
}
} // namespace mbgl

View File

@@ -123,21 +123,14 @@ private:
// Stores all Sprite IDs that changed since the last invocation.
Sprites dirtySprites;
struct Holder : private util::noncopyable {
Holder(std::shared_ptr<const SpriteImage>, Rect<uint16_t>);
Holder(Holder&&);
std::shared_ptr<const SpriteImage> spriteImage;
const Rect<uint16_t> pos;
};
using Key = std::pair<std::string, SpritePatternMode>;
Rect<uint16_t> allocateImage(const SpriteImage&);
void copy(const Holder& holder, SpritePatternMode mode);
void copy(const PremultipliedImage&, Rect<uint16_t>, SpritePatternMode);
std::recursive_mutex mtx;
BinPack<uint16_t> bin;
std::map<Key, Holder> images;
std::map<Key, SpriteAtlasElement> images;
std::unordered_set<std::string> uninitialized;
PremultipliedImage image;
mbgl::optional<gl::Texture> texture;