summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKonstantin Käfer <mail@kkaefer.com>2015-07-01 18:13:16 +0200
committerKonstantin Käfer <mail@kkaefer.com>2015-07-08 19:46:00 +0200
commitafaf74e41a53f6f36a3ab991b83eccf91ebab4ca (patch)
tree36990436cb054266bc363cd2789a452ae5754726 /src
parentd2ee014c6e15e24aabf0ce600fb61d738cc6cb38 (diff)
downloadqtlocation-mapboxgl-afaf74e41a53f6f36a3ab991b83eccf91ebab4ca.tar.gz
use SpriteStore from the SpriteAtlas
Diffstat (limited to 'src')
-rw-r--r--src/mbgl/annotation/sprite_image.cpp6
-rw-r--r--src/mbgl/annotation/sprite_image.hpp6
-rw-r--r--src/mbgl/annotation/sprite_parser.cpp4
-rw-r--r--src/mbgl/geometry/sprite_atlas.cpp95
-rw-r--r--src/mbgl/geometry/sprite_atlas.hpp19
-rw-r--r--src/mbgl/map/map_context.cpp13
-rw-r--r--src/mbgl/map/sprite.cpp83
-rw-r--r--src/mbgl/map/sprite.hpp34
-rw-r--r--src/mbgl/map/tile_worker.cpp4
-rw-r--r--src/mbgl/renderer/symbol_bucket.cpp14
-rw-r--r--src/mbgl/renderer/symbol_bucket.hpp1
-rw-r--r--src/mbgl/style/style.cpp28
-rw-r--r--src/mbgl/style/style.hpp7
13 files changed, 89 insertions, 225 deletions
diff --git a/src/mbgl/annotation/sprite_image.cpp b/src/mbgl/annotation/sprite_image.cpp
index 1a5ae8e099..e482d8f13f 100644
--- a/src/mbgl/annotation/sprite_image.cpp
+++ b/src/mbgl/annotation/sprite_image.cpp
@@ -9,13 +9,15 @@ namespace mbgl {
SpriteImage::SpriteImage(const uint16_t width_,
const uint16_t height_,
const float pixelRatio_,
- std::string&& data_)
+ std::string&& data_,
+ bool sdf_)
: width(width_),
height(height_),
pixelRatio(pixelRatio_),
pixelWidth(std::ceil(width * pixelRatio)),
pixelHeight(std::ceil(height * pixelRatio)),
- data(std::move(data_)) {
+ data(std::move(data_)),
+ sdf(sdf_) {
const size_t size = pixelWidth * pixelHeight * 4;
if (size == 0) {
throw util::SpriteImageException("Sprite image dimensions may not be zero");
diff --git a/src/mbgl/annotation/sprite_image.hpp b/src/mbgl/annotation/sprite_image.hpp
index 19de77c0c4..7d8ea0501c 100644
--- a/src/mbgl/annotation/sprite_image.hpp
+++ b/src/mbgl/annotation/sprite_image.hpp
@@ -12,7 +12,8 @@ namespace mbgl {
class SpriteImage : private util::noncopyable {
public:
- SpriteImage(uint16_t width, uint16_t height, float pixelRatio, std::string&& data);
+ SpriteImage(
+ uint16_t width, uint16_t height, float pixelRatio, std::string&& data, bool sdf = false);
// Logical dimensions of the sprite image.
const uint16_t width;
@@ -29,6 +30,9 @@ public:
// (width * ratio) * (height * ratio) * 4 (RGBA) bytes. The scan lines may
// not have gaps between them (i.e. stride == 0).
const std::string data;
+
+ // Whether this image should be interpreted as a signed distance field icon.
+ const bool sdf;
};
}
diff --git a/src/mbgl/annotation/sprite_parser.cpp b/src/mbgl/annotation/sprite_parser.cpp
index 2791c54a05..c5c731d517 100644
--- a/src/mbgl/annotation/sprite_parser.cpp
+++ b/src/mbgl/annotation/sprite_parser.cpp
@@ -18,7 +18,7 @@ SpriteImagePtr createSpriteImage(const util::Image& image,
const uint16_t srcWidth,
const uint16_t srcHeight,
const double ratio,
- const bool) {
+ const bool sdf) {
// Disallow invalid parameter configurations.
if (srcWidth == 0 || srcHeight == 0 || ratio <= 0 || ratio > 10 || srcWidth > 1024 ||
srcHeight > 1024) {
@@ -52,7 +52,7 @@ SpriteImagePtr createSpriteImage(const util::Image& image,
}
}
- return std::make_unique<const SpriteImage>(width, height, ratio, std::move(data));
+ return std::make_unique<const SpriteImage>(width, height, ratio, std::move(data), sdf);
}
namespace {
diff --git a/src/mbgl/geometry/sprite_atlas.cpp b/src/mbgl/geometry/sprite_atlas.cpp
index b3d2ba7249..dc42a97b98 100644
--- a/src/mbgl/geometry/sprite_atlas.cpp
+++ b/src/mbgl/geometry/sprite_atlas.cpp
@@ -22,50 +22,12 @@ using namespace mbgl;
SpriteAtlas::SpriteAtlas(dimension width_, dimension height_, SpriteStore& store_)
: width(width_),
height(height_),
- bin(width_, height_),
store(store_),
+ pixelRatio(store.pixelRatio),
+ bin(width_, height_),
dirty(true) {
}
-bool SpriteAtlas::resize(const float newRatio) {
- if (pixelRatio == newRatio) return false;
-
- std::lock_guard<std::recursive_mutex> lock(mtx);
-
- const float oldRatio = pixelRatio;
- pixelRatio = newRatio;
-
- if (data) {
- const auto oldData = std::move(data);
- allocate();
-
- const int old_w = width * oldRatio;
- const int old_h = height * oldRatio;
- const int new_w = width * newRatio;
- const int new_h = height * newRatio;
-
- // Basic image scaling. TODO: Replace this with better image scaling.
- for (int y = 0; y < new_h; y++) {
- const int old_yoffset = ((y * old_h) / new_h) * old_w;
- const int new_yoffset = y * new_w;
- for (int x = 0; x < new_w; x++) {
- const int old_x = (x * old_w) / new_w;
- data[new_yoffset + x] = oldData[old_yoffset + old_x];
- }
- }
-
- dirty = true;
- fullUploadRequired = true;
-
- // Mark all sprite images as in need of update
- for (const auto &pair : images) {
- uninitialized.emplace(pair.first);
- }
- }
-
- return dirty;
-}
-
Rect<SpriteAtlas::dimension> SpriteAtlas::allocateImage(const size_t pixel_width, const size_t pixel_height) {
// Increase to next number divisible by 4, but at least 1.
// This is so we can scale down the texture coordinates and pack them
@@ -86,17 +48,17 @@ Rect<SpriteAtlas::dimension> SpriteAtlas::allocateImage(const size_t pixel_width
return rect;
}
-Rect<SpriteAtlas::dimension> SpriteAtlas::getImage(const std::string& name, const bool wrap) {
+SpriteAtlasElement SpriteAtlas::getImage(const std::string& name, const bool wrap) {
std::lock_guard<std::recursive_mutex> lock(mtx);
auto rect_it = images.find(name);
if (rect_it != images.end()) {
- return rect_it->second.pos;
+ return { rect_it->second.pos, rect_it->second.texture };
}
auto sprite = store.getSprite(name);
if (!sprite) {
- return Rect<dimension> { 0, 0, 0, 0 };
+ return { Rect<dimension> { 0, 0, 0, 0 }, nullptr };
}
Rect<dimension> rect = allocateImage(sprite->width, sprite->height);
@@ -104,19 +66,19 @@ Rect<SpriteAtlas::dimension> SpriteAtlas::getImage(const std::string& name, cons
if (debug::spriteWarnings) {
Log::Warning(Event::Sprite, "sprite atlas bitmap overflow");
}
- return rect;
+ return { Rect<dimension> { 0, 0, 0, 0 }, nullptr };
}
const Holder& holder = images.emplace(name, Holder{ sprite, rect }).first->second;
copy(holder, wrap);
- return rect;
+ return { rect, sprite };
}
SpriteAtlasPosition SpriteAtlas::getPosition(const std::string& name, bool repeating) {
std::lock_guard<std::recursive_mutex> lock(mtx);
- Rect<dimension> rect = getImage(name, repeating);
+ auto rect = getImage(name, repeating).pos;
if (repeating) {
// When the image is repeating, get the correct position of the image, rather than the
// one rounded up to 4 pixels.
@@ -202,35 +164,6 @@ void SpriteAtlas::copy(const Holder& holder, const bool wrap) {
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::upload() {
if (dirty) {
bind();
@@ -294,7 +227,9 @@ void SpriteAtlas::bind(bool linear) {
dirty = false;
#ifndef GL_ES_VERSION_2_0
- // platform::showColorDebugImage("Sprite Atlas", reinterpret_cast<const char *>(data), width * pixelRatio, height * pixelRatio, width * pixelRatio, height * pixelRatio);
+ // platform::showColorDebugImage("Sprite Atlas", reinterpret_cast<const char*>(data.get()),
+ // width * pixelRatio, height * pixelRatio, width * pixelRatio,
+ // height * pixelRatio);
#endif
}
};
@@ -306,3 +241,11 @@ SpriteAtlas::~SpriteAtlas() {
texture = 0;
}
}
+
+SpriteAtlas::Holder::Holder(const std::shared_ptr<const SpriteImage>& texture_,
+ const Rect<dimension>& pos_)
+ : texture(texture_), pos(pos_) {
+}
+
+SpriteAtlas::Holder::Holder(Holder&& h) : texture(std::move(h.texture)), pos(h.pos) {
+}
diff --git a/src/mbgl/geometry/sprite_atlas.hpp b/src/mbgl/geometry/sprite_atlas.hpp
index 57e49e3c98..d80b9cb944 100644
--- a/src/mbgl/geometry/sprite_atlas.hpp
+++ b/src/mbgl/geometry/sprite_atlas.hpp
@@ -29,6 +29,11 @@ struct SpriteAtlasPosition {
std::array<float, 2> br;
};
+struct SpriteAtlasElement {
+ const Rect<uint16_t> pos;
+ const std::shared_ptr<const SpriteImage> texture;
+};
+
class SpriteAtlas : public util::noncopyable {
public:
typedef uint16_t dimension;
@@ -37,15 +42,12 @@ public:
SpriteAtlas(dimension width, dimension height, SpriteStore& store);
~SpriteAtlas();
- // Changes the pixel ratio.
- bool resize(float newRatio);
-
// 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.
// Otherwise, it returns a 0/0/0/0 rect.
// This function is used during bucket creation.
- Rect<dimension> getImage(const std::string& name, const bool wrap);
+ SpriteAtlasElement getImage(const std::string& name, const bool wrap);
// This function is used for getting the position during render time.
SpriteAtlasPosition getPosition(const std::string& name, bool repeating = false);
@@ -68,10 +70,9 @@ public:
private:
struct Holder : private util::noncopyable {
- Holder(const std::shared_ptr<const SpriteImage>&, const Rect<dimension>&);
- Holder(Holder&&);
+ inline Holder(const std::shared_ptr<const SpriteImage>&, const Rect<dimension>&);
+ inline Holder(Holder&&);
std::shared_ptr<const SpriteImage> texture;
- std::set<uintptr_t> references;
const Rect<dimension> pos;
};
@@ -80,9 +81,9 @@ private:
void copy(const Holder& holder, const bool wrap);
std::recursive_mutex mtx;
- float pixelRatio = 1.0f;
- BinPack<dimension> bin;
SpriteStore& store;
+ const float pixelRatio;
+ BinPack<dimension> bin;
std::map<std::string, Holder> images;
std::set<std::string> uninitialized;
std::unique_ptr<uint32_t[]> data;
diff --git a/src/mbgl/map/map_context.cpp b/src/mbgl/map/map_context.cpp
index 455539436f..05a046fdb1 100644
--- a/src/mbgl/map/map_context.cpp
+++ b/src/mbgl/map/map_context.cpp
@@ -3,6 +3,7 @@
#include <mbgl/map/view.hpp>
#include <mbgl/map/still_image.hpp>
#include <mbgl/map/annotation.hpp>
+#include <mbgl/annotation/sprite_store.hpp>
#include <mbgl/platform/log.hpp>
@@ -124,7 +125,7 @@ void MapContext::loadStyleJSON(const std::string& json, const std::string& base)
assert(util::ThreadContext::currentlyOn(util::ThreadType::Map));
style.reset();
- style = std::make_unique<Style>(json, base, asyncUpdate->get()->loop);
+ style = std::make_unique<Style>(json, base, data, asyncUpdate->get()->loop);
style->cascade(data.getClasses());
style->setDefaultTransitionDuration(data.getDefaultTransitionDuration());
style->setObserver(this);
@@ -257,7 +258,7 @@ void MapContext::update() {
style->recalculate(transformState.getNormalizedZoom(), now);
}
- style->update(data, transformState, *texturePool);
+ style->update(transformState, *texturePool);
if (data.mode == MapMode::Continuous) {
view.invalidate();
@@ -343,8 +344,12 @@ bool MapContext::isLoaded() const {
double MapContext::getTopOffsetPixelsForAnnotationSymbol(const std::string& symbol) {
assert(util::ThreadContext::currentlyOn(util::ThreadType::Map));
- const SpritePosition pos = style->sprite->getSpritePosition(symbol);
- return -pos.height / pos.pixelRatio / 2;
+ auto sprite = style->spriteStore->getSprite(symbol);
+ if (sprite) {
+ return -sprite->height / 2;
+ } else {
+ return 0;
+ }
}
void MapContext::setSourceTileCacheSize(size_t size) {
diff --git a/src/mbgl/map/sprite.cpp b/src/mbgl/map/sprite.cpp
index 6a310c21cc..589f56f99e 100644
--- a/src/mbgl/map/sprite.cpp
+++ b/src/mbgl/map/sprite.cpp
@@ -17,20 +17,8 @@
using namespace mbgl;
-SpritePosition::SpritePosition(uint16_t x_, uint16_t y_, uint16_t width_, uint16_t height_, float pixelRatio_, bool sdf_)
- : x(x_),
- y(y_),
- width(width_),
- height(height_),
- pixelRatio(pixelRatio_),
- sdf(sdf_) {
-}
-
Sprite::Sprite(const std::string& baseUrl, float pixelRatio_)
- : pixelRatio(pixelRatio_ > 1 ? 2 : 1),
- raster(),
- loadedImage(false),
- loadedJSON(false) {
+ : pixelRatio(pixelRatio_ > 1 ? 2 : 1) {
if (baseUrl.empty()) {
// Treat a non-existent sprite as a successfully loaded empty sprite.
loadedImage = true;
@@ -45,8 +33,8 @@ Sprite::Sprite(const std::string& baseUrl, float pixelRatio_)
jsonRequest = fs->request({ Resource::Kind::JSON, jsonURL }, util::RunLoop::getLoop(), [this, jsonURL](const Response &res) {
jsonRequest = nullptr;
if (res.status == Response::Successful) {
- body = res.data;
- parseJSON(jsonURL);
+ json = res.data;
+ loadedJSON = true;
} else {
std::stringstream message;
message << "Failed to load [" << jsonURL << "]: " << res.message;
@@ -60,7 +48,7 @@ Sprite::Sprite(const std::string& baseUrl, float pixelRatio_)
spriteRequest = nullptr;
if (res.status == Response::Successful) {
image = res.data;
- parseImage(spriteURL);
+ loadedImage = true;
} else {
std::stringstream message;
message << "Failed to load [" << spriteURL << "]: " << res.message;
@@ -100,69 +88,6 @@ bool Sprite::isLoaded() const {
return loadedImage && loadedJSON;
}
-bool Sprite::hasPixelRatio(float ratio) const {
- return pixelRatio == (ratio > 1 ? 2 : 1);
-}
-
-void Sprite::parseImage(const std::string& spriteURL) {
- raster = std::make_unique<util::Image>(image);
- if (!*raster) {
- raster.reset();
- std::stringstream message;
- message << "Failed to parse [" << spriteURL << "]";
- emitSpriteLoadingFailed(message.str());
- return;
- }
-
- image.clear();
- loadedImage = true;
-}
-
-void Sprite::parseJSON(const std::string& jsonURL) {
- rapidjson::Document d;
- d.Parse<0>(body.c_str());
- body.clear();
-
- if (d.HasParseError()) {
- std::stringstream message;
- message << "Failed to parse [" << jsonURL << "]: " << d.GetErrorOffset() << " - " << d.GetParseError();
- emitSpriteLoadingFailed(message.str());
- } else if (d.IsObject()) {
- for (rapidjson::Value::ConstMemberIterator itr = d.MemberBegin(); itr != d.MemberEnd(); ++itr) {
- const std::string name = { itr->name.GetString(), itr->name.GetStringLength() };
- const rapidjson::Value& value = itr->value;
-
- if (value.IsObject()) {
- uint16_t x = 0;
- uint16_t y = 0;
- uint16_t width = 0;
- uint16_t height = 0;
- float spritePixelRatio = 1.0f;
- bool sdf = false;
-
- if (value.HasMember("x")) x = value["x"].GetInt();
- if (value.HasMember("y")) y = value["y"].GetInt();
- if (value.HasMember("width")) width = value["width"].GetInt();
- if (value.HasMember("height")) height = value["height"].GetInt();
- if (value.HasMember("pixelRatio")) spritePixelRatio = value["pixelRatio"].GetInt();
- if (value.HasMember("sdf")) sdf = value["sdf"].GetBool();
- pos.emplace(name, SpritePosition { x, y, width, height, spritePixelRatio, sdf });
- }
- }
- loadedJSON = true;
- } else {
- std::stringstream message;
- message << "Failed to parse [" << jsonURL << "]: Root is not an object";
- emitSpriteLoadingFailed(message.str());
- }
-}
-
-const SpritePosition &Sprite::getSpritePosition(const std::string& name) const {
- if (!isLoaded()) return empty;
- auto it = pos.find(name);
- return it == pos.end() ? empty : it->second;
-}
-
void Sprite::setObserver(Observer* observer_) {
observer = observer_;
}
diff --git a/src/mbgl/map/sprite.hpp b/src/mbgl/map/sprite.hpp
index 47b871faf7..e4905ddbe9 100644
--- a/src/mbgl/map/sprite.hpp
+++ b/src/mbgl/map/sprite.hpp
@@ -16,21 +16,6 @@ namespace mbgl {
class Request;
-class SpritePosition {
-public:
- explicit SpritePosition() {}
- explicit SpritePosition(uint16_t x, uint16_t y, uint16_t width, uint16_t height, float pixelRatio, bool sdf);
-
- operator bool() const {
- return !(width == 0 && height == 0 && x == 0 && y == 0);
- }
-
- uint16_t x = 0, y = 0;
- uint16_t width = 0, height = 0;
- float pixelRatio = 1.0f;
- bool sdf = false;
-};
-
class Sprite : private util::noncopyable {
public:
class Observer {
@@ -44,29 +29,24 @@ public:
Sprite(const std::string& baseUrl, float pixelRatio);
~Sprite();
- const SpritePosition &getSpritePosition(const std::string& name) const;
-
- bool hasPixelRatio(float ratio) const;
-
bool isLoaded() const;
const float pixelRatio;
- std::unique_ptr<util::Image> raster;
void setObserver(Observer* observer);
+
+ inline const std::string& getImage() const { return image; }
+ inline const std::string& getJSON() const { return json; }
+
private:
void emitSpriteLoadedIfComplete();
void emitSpriteLoadingFailed(const std::string& message);
- void parseJSON(const std::string& jsonURL);
- void parseImage(const std::string& spriteURL);
+ bool loadedJSON = false;
+ std::string json;
- std::string body;
+ bool loadedImage = false;
std::string image;
- std::atomic<bool> loadedImage;
- std::atomic<bool> loadedJSON;
- std::unordered_map<std::string, SpritePosition> pos;
- const SpritePosition empty;
Request* jsonRequest = nullptr;
Request* spriteRequest = nullptr;
diff --git a/src/mbgl/map/tile_worker.cpp b/src/mbgl/map/tile_worker.cpp
index e8c8e15b26..6edfe3b1bd 100644
--- a/src/mbgl/map/tile_worker.cpp
+++ b/src/mbgl/map/tile_worker.cpp
@@ -265,8 +265,8 @@ std::unique_ptr<Bucket> TileWorker::createSymbolBucket(const GeometryTileLayer&
return nullptr;
}
- bucket->addFeatures(
- reinterpret_cast<uintptr_t>(this), *style.spriteAtlas, *style.sprite, *style.glyphAtlas, *style.glyphStore);
+ bucket->addFeatures(reinterpret_cast<uintptr_t>(this), *style.spriteAtlas, *style.glyphAtlas,
+ *style.glyphStore);
return bucket->hasData() ? std::move(bucket) : nullptr;
}
diff --git a/src/mbgl/renderer/symbol_bucket.cpp b/src/mbgl/renderer/symbol_bucket.cpp
index d52561d3ec..47087422ec 100644
--- a/src/mbgl/renderer/symbol_bucket.cpp
+++ b/src/mbgl/renderer/symbol_bucket.cpp
@@ -1,6 +1,7 @@
#include <mbgl/renderer/symbol_bucket.hpp>
#include <mbgl/map/geometry_tile.hpp>
#include <mbgl/style/style_layout.hpp>
+#include <mbgl/annotation/sprite_image.hpp>
#include <mbgl/geometry/text_buffer.hpp>
#include <mbgl/geometry/icon_buffer.hpp>
#include <mbgl/geometry/glyph_atlas.hpp>
@@ -172,7 +173,6 @@ bool SymbolBucket::needsDependencies(const GeometryTileLayer& layer,
void SymbolBucket::addFeatures(uintptr_t tileUID,
SpriteAtlas& spriteAtlas,
- Sprite& sprite,
GlyphAtlas& glyphAtlas,
GlyphStore& glyphStore) {
float horizontalAlign = 0.5;
@@ -246,11 +246,13 @@ void SymbolBucket::addFeatures(uintptr_t tileUID,
// if feature has icon, get sprite atlas position
if (feature.sprite.length()) {
- Rect<uint16_t> image = spriteAtlas.getImage(feature.sprite, false);
- shapedIcon = shapeIcon(image, layout);
-
- if (sprite.getSpritePosition(feature.sprite).sdf) {
- sdfIcons = true;
+ auto image = spriteAtlas.getImage(feature.sprite, false);
+ if (image.pos.hasArea() && image.texture) {
+ shapedIcon = shapeIcon(image.pos, layout);
+ assert(image.texture);
+ if (image.texture->sdf) {
+ sdfIcons = true;
+ }
}
}
diff --git a/src/mbgl/renderer/symbol_bucket.hpp b/src/mbgl/renderer/symbol_bucket.hpp
index 5654f9b2ba..a5c98fbf32 100644
--- a/src/mbgl/renderer/symbol_bucket.hpp
+++ b/src/mbgl/renderer/symbol_bucket.hpp
@@ -76,7 +76,6 @@ public:
void addFeatures(uintptr_t tileUID,
SpriteAtlas&,
- Sprite&,
GlyphAtlas&,
GlyphStore&);
diff --git a/src/mbgl/style/style.cpp b/src/mbgl/style/style.cpp
index 91aeed11a0..93235d2a1f 100644
--- a/src/mbgl/style/style.cpp
+++ b/src/mbgl/style/style.cpp
@@ -3,6 +3,8 @@
#include <mbgl/map/map_data.hpp>
#include <mbgl/map/source.hpp>
#include <mbgl/map/transform_state.hpp>
+#include <mbgl/annotation/sprite_store.hpp>
+#include <mbgl/annotation/sprite_parser.hpp>
#include <mbgl/style/style_layer.hpp>
#include <mbgl/style/style_parser.hpp>
#include <mbgl/style/style_bucket.hpp>
@@ -20,17 +22,19 @@
namespace mbgl {
-Style::Style(const std::string& data, const std::string&,
+Style::Style(const std::string& json, const std::string&, MapData& data_,
uv_loop_t* loop)
- : glyphStore(std::make_unique<GlyphStore>(loop)),
+ : data(data_),
+ glyphStore(std::make_unique<GlyphStore>(loop)),
glyphAtlas(std::make_unique<GlyphAtlas>(1024, 1024)),
+ spriteStore(std::make_unique<SpriteStore>(data.pixelRatio)),
spriteAtlas(std::make_unique<SpriteAtlas>(512, 512, *spriteStore)),
lineAtlas(std::make_unique<LineAtlas>(512, 512)),
mtx(std::make_unique<uv::rwlock>()),
workers(4) {
rapidjson::Document doc;
- doc.Parse<0>((const char *const)data.c_str());
+ doc.Parse<0>((const char *const)json.c_str());
if (doc.HasParseError()) {
Log::Error(Event::ParseStyle, "Error parsing style JSON at %i: %s", doc.GetErrorOffset(), doc.GetParseError());
return;
@@ -42,7 +46,9 @@ Style::Style(const std::string& data, const std::string&,
sources = parser.getSources();
layers = parser.getLayers();
- spriteURL = parser.getSprite();
+ sprite = std::make_unique<Sprite>(parser.getSprite(), data.pixelRatio);
+ sprite->setObserver(this);
+
glyphStore->setURL(parser.getGlyphURL());
for (const auto& source : sources) {
@@ -65,17 +71,8 @@ Style::~Style() {
}
}
-void Style::update(MapData& data,
- const TransformState& transform,
+void Style::update(const TransformState& transform,
TexturePool& texturePool) {
- if (!sprite || !sprite->hasPixelRatio(data.pixelRatio)) {
- sprite = std::make_unique<Sprite>(spriteURL, data.pixelRatio);
- sprite->setObserver(this);
-
- spriteAtlas->resize(data.pixelRatio);
- spriteAtlas->setSprite(sprite);
- }
-
bool allTilesUpdated = true;
for (const auto& source : sources) {
if (!source->update(data, transform, *this, texturePool, shouldReparsePartialTiles)) {
@@ -195,6 +192,9 @@ void Style::onTileLoadingFailed(std::exception_ptr error) {
}
void Style::onSpriteLoaded() {
+ // Add all sprite images to the SpriteStore object
+ spriteStore->setSprites(parseSprite(sprite->getImage(), sprite->getJSON()));
+
shouldReparsePartialTiles = true;
emitTileDataChanged();
diff --git a/src/mbgl/style/style.hpp b/src/mbgl/style/style.hpp
index d96833da25..3362ce7f73 100644
--- a/src/mbgl/style/style.hpp
+++ b/src/mbgl/style/style.hpp
@@ -22,6 +22,7 @@ namespace mbgl {
class GlyphAtlas;
class GlyphStore;
+class SpriteStore;
class SpriteAtlas;
class LineAtlas;
class StyleLayer;
@@ -33,6 +34,7 @@ class Style : public GlyphStore::Observer,
public:
Style(const std::string& data,
const std::string& base,
+ MapData&,
uv_loop_t*);
~Style();
@@ -50,7 +52,7 @@ public:
// Fetch the tiles needed by the current viewport and emit a signal when
// a tile is ready so observers can render the tile.
- void update(MapData&, const TransformState&, TexturePool&);
+ void update(const TransformState&, TexturePool&);
void cascade(const std::vector<std::string>&);
void recalculate(float z, TimePoint now);
@@ -64,9 +66,11 @@ public:
Source* getSource(const std::string& id) const;
+ MapData& data;
std::unique_ptr<GlyphStore> glyphStore;
std::unique_ptr<GlyphAtlas> glyphAtlas;
util::ptr<Sprite> sprite;
+ std::unique_ptr<SpriteStore> spriteStore;
std::unique_ptr<SpriteAtlas> spriteAtlas;
std::unique_ptr<LineAtlas> lineAtlas;
@@ -97,7 +101,6 @@ private:
std::exception_ptr lastError;
- std::string spriteURL;
PropertyTransition defaultTransition;
std::unique_ptr<uv::rwlock> mtx;
ZoomHistory zoomHistory;