diff options
-rw-r--r-- | src/mbgl/renderer/painter_background.cpp | 6 | ||||
-rw-r--r-- | src/mbgl/renderer/painter_fill.cpp | 6 | ||||
-rw-r--r-- | src/mbgl/renderer/painter_line.cpp | 6 | ||||
-rw-r--r-- | src/mbgl/renderer/symbol_bucket.cpp | 2 | ||||
-rw-r--r-- | src/mbgl/sprite/sprite_atlas.cpp | 22 | ||||
-rw-r--r-- | src/mbgl/sprite/sprite_atlas.hpp | 14 | ||||
-rw-r--r-- | test/sprite/sprite_atlas.cpp | 12 |
7 files changed, 41 insertions, 27 deletions
diff --git a/src/mbgl/renderer/painter_background.cpp b/src/mbgl/renderer/painter_background.cpp index 51a892575b..48c03fe3f9 100644 --- a/src/mbgl/renderer/painter_background.cpp +++ b/src/mbgl/renderer/painter_background.cpp @@ -27,8 +27,10 @@ void Painter::renderBackground(PaintParameters& parameters, const BackgroundLaye auto& arrayBackground = parameters.shaders.backgroundArray; if (isPatterned) { - imagePosA = spriteAtlas->getPosition(properties.backgroundPattern.value.from, true); - imagePosB = spriteAtlas->getPosition(properties.backgroundPattern.value.to, true); + imagePosA = spriteAtlas->getPosition(properties.backgroundPattern.value.from, + SpritePatternMode::Repeating); + imagePosB = spriteAtlas->getPosition(properties.backgroundPattern.value.to, + SpritePatternMode::Repeating); if (!imagePosA || !imagePosB) return; diff --git a/src/mbgl/renderer/painter_fill.cpp b/src/mbgl/renderer/painter_fill.cpp index 9af2af9d10..106d030fcc 100644 --- a/src/mbgl/renderer/painter_fill.cpp +++ b/src/mbgl/renderer/painter_fill.cpp @@ -73,8 +73,10 @@ void Painter::renderFill(PaintParameters& parameters, } if (pattern) { - optional<SpriteAtlasPosition> imagePosA = spriteAtlas->getPosition(properties.fillPattern.value.from, true); - optional<SpriteAtlasPosition> imagePosB = spriteAtlas->getPosition(properties.fillPattern.value.to, true); + optional<SpriteAtlasPosition> imagePosA = spriteAtlas->getPosition( + properties.fillPattern.value.from, SpritePatternMode::Repeating); + optional<SpriteAtlasPosition> imagePosB = + spriteAtlas->getPosition(properties.fillPattern.value.to, SpritePatternMode::Repeating); // Image fill. if (pass == RenderPass::Translucent && imagePosA && imagePosB) { diff --git a/src/mbgl/renderer/painter_line.cpp b/src/mbgl/renderer/painter_line.cpp index ed1975f955..b0b2bf6924 100644 --- a/src/mbgl/renderer/painter_line.cpp +++ b/src/mbgl/renderer/painter_line.cpp @@ -99,8 +99,10 @@ void Painter::renderLine(PaintParameters& parameters, bucket.drawLineSDF(linesdfShader, store, isOverdraw()); } else if (!properties.linePattern.value.from.empty()) { - optional<SpriteAtlasPosition> imagePosA = spriteAtlas->getPosition(properties.linePattern.value.from, true); - optional<SpriteAtlasPosition> imagePosB = spriteAtlas->getPosition(properties.linePattern.value.to, true); + optional<SpriteAtlasPosition> imagePosA = spriteAtlas->getPosition( + properties.linePattern.value.from, SpritePatternMode::Repeating); + optional<SpriteAtlasPosition> imagePosB = + spriteAtlas->getPosition(properties.linePattern.value.to, SpritePatternMode::Repeating); if (!imagePosA || !imagePosB) return; diff --git a/src/mbgl/renderer/symbol_bucket.cpp b/src/mbgl/renderer/symbol_bucket.cpp index 008372b2bf..842322ddcc 100644 --- a/src/mbgl/renderer/symbol_bucket.cpp +++ b/src/mbgl/renderer/symbol_bucket.cpp @@ -273,7 +273,7 @@ void SymbolBucket::addFeatures(uintptr_t tileUID, // if feature has icon, get sprite atlas position if (feature.sprite.length()) { - auto image = spriteAtlas.getImage(feature.sprite, false); + auto image = spriteAtlas.getImage(feature.sprite, SpritePatternMode::Single); if (image) { shapedIcon = shapeIcon(*image, layout); assert((*image).spriteImage); diff --git a/src/mbgl/sprite/sprite_atlas.cpp b/src/mbgl/sprite/sprite_atlas.cpp index 05b713f454..d346464b51 100644 --- a/src/mbgl/sprite/sprite_atlas.cpp +++ b/src/mbgl/sprite/sprite_atlas.cpp @@ -46,10 +46,11 @@ Rect<SpriteAtlas::dimension> SpriteAtlas::allocateImage(const SpriteImage& sprit return rect; } -optional<SpriteAtlasElement> SpriteAtlas::getImage(const std::string& name, const bool wrap) { +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, wrap }); + 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 }; } @@ -67,16 +68,17 @@ optional<SpriteAtlasElement> SpriteAtlas::getImage(const std::string& name, cons return {}; } - const Holder& holder = images.emplace(Key{ name, wrap }, Holder{ sprite, rect }).first->second; - copy(holder, wrap); + const Holder& holder = images.emplace(Key{ name, mode }, Holder{ sprite, rect }).first->second; + copy(holder, mode); return SpriteAtlasElement { rect, sprite, sprite->pixelRatio / pixelRatio }; } -optional<SpriteAtlasPosition> SpriteAtlas::getPosition(const std::string& name, bool repeating) { +optional<SpriteAtlasPosition> SpriteAtlas::getPosition(const std::string& name, + const SpritePatternMode mode) { std::lock_guard<std::recursive_mutex> lock(mtx); - auto img = getImage(name, repeating); + auto img = getImage(name, mode); if (!img) { return {}; } @@ -98,13 +100,13 @@ optional<SpriteAtlasPosition> SpriteAtlas::getPosition(const std::string& name, void copyBitmap(const uint32_t *src, const uint32_t srcStride, const uint32_t srcX, const uint32_t srcY, uint32_t *const dst, const uint32_t dstStride, const uint32_t dstX, const uint32_t dstY, int dstSize, - const int width, const int height, const bool wrap) { + const int width, const int height, const SpritePatternMode mode) { int srcI = srcY * srcStride + srcX; int dstI = dstY * dstStride + dstX; int x, y; - if (wrap) { + if (mode == SpritePatternMode::Repeating) { // add 1 pixel wrapped padding on each side of the image dstI -= dstStride; for (y = -1; y <= height; y++, srcI = ((y + height) % height + srcY) * srcStride + srcX, dstI += dstStride) { @@ -124,7 +126,7 @@ void copyBitmap(const uint32_t *src, const uint32_t srcStride, const uint32_t sr } } -void SpriteAtlas::copy(const Holder& holder, const bool wrap) { +void SpriteAtlas::copy(const Holder& holder, const SpritePatternMode mode) { if (!data) { data = std::make_unique<uint32_t[]>(pixelWidth * pixelHeight); std::fill(data.get(), data.get() + pixelWidth * pixelHeight, 0); @@ -138,7 +140,7 @@ void SpriteAtlas::copy(const Holder& holder, const bool wrap) { copyBitmap(srcData, uint32_t(holder.spriteImage->image.width), 0, 0, dstData, pixelWidth, (holder.pos.x + padding) * pixelRatio, (holder.pos.y + padding) * pixelRatio, pixelWidth * pixelHeight, - uint32_t(holder.spriteImage->image.width), uint32_t(holder.spriteImage->image.height), wrap); + uint32_t(holder.spriteImage->image.width), uint32_t(holder.spriteImage->image.height), mode); dirty = true; } diff --git a/src/mbgl/sprite/sprite_atlas.hpp b/src/mbgl/sprite/sprite_atlas.hpp index b58a16ab53..d7901244cb 100644 --- a/src/mbgl/sprite/sprite_atlas.hpp +++ b/src/mbgl/sprite/sprite_atlas.hpp @@ -35,6 +35,11 @@ struct SpriteAtlasElement { float relativePixelRatio; }; +enum class SpritePatternMode : bool { + Single = false, + Repeating = true, +}; + class SpriteAtlas : public util::noncopyable { public: typedef uint16_t dimension; @@ -44,10 +49,11 @@ public: // If the sprite is loaded, copies the requsted image from it into the atlas and returns // the resulting icon measurements. If not, returns an empty optional. - optional<SpriteAtlasElement> getImage(const std::string& name, const bool wrap); + optional<SpriteAtlasElement> getImage(const std::string& name, SpritePatternMode mode); // This function is used for getting the position during render time. - optional<SpriteAtlasPosition> getPosition(const std::string& name, bool repeating = false); + optional<SpriteAtlasPosition> getPosition(const std::string& name, + SpritePatternMode mode = SpritePatternMode::Single); // Binds the atlas texture to the GPU, and uploads data if it is out of date. void bind(bool linear, gl::ObjectStore&, gl::Config&, uint32_t unit); @@ -80,10 +86,10 @@ private: const Rect<dimension> pos; }; - using Key = std::pair<std::string, bool>; + using Key = std::pair<std::string, SpritePatternMode>; Rect<SpriteAtlas::dimension> allocateImage(const SpriteImage&); - void copy(const Holder& holder, const bool wrap); + void copy(const Holder& holder, SpritePatternMode mode); std::recursive_mutex mtx; SpriteStore& store; diff --git a/test/sprite/sprite_atlas.cpp b/test/sprite/sprite_atlas.cpp index d9f96d57d1..10bfbfa67f 100644 --- a/test/sprite/sprite_atlas.cpp +++ b/test/sprite/sprite_atlas.cpp @@ -45,7 +45,7 @@ TEST(Sprite, SpriteAtlas) { // Image hasn't been created yet. EXPECT_FALSE(atlas.getData()); - auto metro = *atlas.getImage("metro", false); + auto metro = *atlas.getImage("metro", SpritePatternMode::Single); EXPECT_EQ(0, metro.pos.x); EXPECT_EQ(0, metro.pos.y); EXPECT_EQ(20, metro.pos.w); @@ -58,7 +58,7 @@ TEST(Sprite, SpriteAtlas) { EXPECT_TRUE(atlas.getData()); - auto pos = *atlas.getPosition("metro", false); + auto pos = *atlas.getPosition("metro", SpritePatternMode::Single); EXPECT_DOUBLE_EQ(18, pos.size[0]); EXPECT_DOUBLE_EQ(18, pos.size[1]); EXPECT_DOUBLE_EQ(1.0f / 63, pos.tl[0]); @@ -66,7 +66,7 @@ TEST(Sprite, SpriteAtlas) { EXPECT_DOUBLE_EQ(19.0f / 63, pos.br[0]); EXPECT_DOUBLE_EQ(19.0f / 112, pos.br[1]); - auto missing = atlas.getImage("doesnotexist", false); + auto missing = atlas.getImage("doesnotexist", SpritePatternMode::Single); EXPECT_FALSE(missing); EXPECT_EQ(1u, log.count({ @@ -77,7 +77,7 @@ TEST(Sprite, SpriteAtlas) { })); // Different wrapping mode produces different image. - auto metro2 = *atlas.getImage("metro", true); + auto metro2 = *atlas.getImage("metro", SpritePatternMode::Repeating); EXPECT_EQ(20, metro2.pos.x); EXPECT_EQ(0, metro2.pos.y); EXPECT_EQ(20, metro2.pos.w); @@ -101,7 +101,7 @@ TEST(Sprite, SpriteAtlasSize) { EXPECT_EQ(89, atlas.getTextureWidth()); EXPECT_EQ(157, atlas.getTextureHeight()); - auto metro = *atlas.getImage("metro", false); + auto metro = *atlas.getImage("metro", SpritePatternMode::Single); EXPECT_EQ(0, metro.pos.x); EXPECT_EQ(0, metro.pos.y); EXPECT_EQ(16, metro.pos.w); @@ -128,7 +128,7 @@ TEST(Sprite, SpriteAtlasUpdates) { EXPECT_EQ(32, atlas.getTextureHeight()); store.setSprite("one", std::make_shared<SpriteImage>(PremultipliedImage(16, 12), 1)); - auto one = *atlas.getImage("one", false); + auto one = *atlas.getImage("one", SpritePatternMode::Single); EXPECT_EQ(0, one.pos.x); EXPECT_EQ(0, one.pos.y); EXPECT_EQ(20, one.pos.w); |