summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAdam Hunter <adam@mapbox.com>2015-11-16 16:26:02 -0800
committerJohn Firebaugh <john.firebaugh@gmail.com>2015-12-01 09:15:05 -0800
commite1091db45ea5e921337f1cfccb36f46ab01dd54e (patch)
treef8c9f98ffeb84e1ec698961aed432a1b5ae32bee /src
parent58886842bc381cd30bac7102d4f70497c0128aa7 (diff)
downloadqtlocation-mapboxgl-e1091db45ea5e921337f1cfccb36f46ab01dd54e.tar.gz
[core] Use a separate atlas and store for annotation sprites
Fixes #1488
Diffstat (limited to 'src')
-rw-r--r--src/mbgl/annotation/annotation_manager.cpp17
-rw-r--r--src/mbgl/annotation/annotation_manager.hpp11
-rw-r--r--src/mbgl/layer/symbol_layer.cpp3
-rw-r--r--src/mbgl/layer/symbol_layer.hpp4
-rw-r--r--src/mbgl/map/map_context.cpp19
-rw-r--r--src/mbgl/map/map_data.hpp1
-rw-r--r--src/mbgl/map/tile_worker.cpp4
-rw-r--r--src/mbgl/renderer/painter.cpp3
-rw-r--r--src/mbgl/renderer/painter.hpp3
-rw-r--r--src/mbgl/renderer/painter_symbol.cpp5
-rw-r--r--src/mbgl/sprite/sprite_atlas.cpp11
-rw-r--r--src/mbgl/sprite/sprite_atlas.hpp4
-rw-r--r--src/mbgl/style/style.cpp7
13 files changed, 66 insertions, 26 deletions
diff --git a/src/mbgl/annotation/annotation_manager.cpp b/src/mbgl/annotation/annotation_manager.cpp
index 5b1138a14a..83cf34ac66 100644
--- a/src/mbgl/annotation/annotation_manager.cpp
+++ b/src/mbgl/annotation/annotation_manager.cpp
@@ -10,7 +10,11 @@ namespace mbgl {
const std::string AnnotationManager::SourceID = "com.mapbox.annotations";
const std::string AnnotationManager::PointLayerID = "com.mapbox.annotations.points";
-AnnotationManager::AnnotationManager() = default;
+AnnotationManager::AnnotationManager(float pixelRatio)
+ : spriteStore(pixelRatio),
+ spriteAtlas(512, 512, pixelRatio, spriteStore) {
+}
+
AnnotationManager::~AnnotationManager() = default;
AnnotationIDs
@@ -122,6 +126,7 @@ void AnnotationManager::updateStyle(Style& style) {
layer->sourceLayer = PointLayerID;
layer->layout.icon.image = std::string("{sprite}");
layer->layout.icon.allowOverlap = true;
+ layer->spriteAtlas = &spriteAtlas;
style.addLayer(std::move(layer));
}
@@ -152,4 +157,14 @@ void AnnotationManager::removeTileMonitor(AnnotationTileMonitor& monitor) {
monitors.erase(&monitor);
}
+void AnnotationManager::setSprite(const std::string& name, std::shared_ptr<const SpriteImage> sprite) {
+ spriteStore.setSprite(name, sprite);
+ spriteAtlas.updateDirty();
+}
+
+double AnnotationManager::getTopOffsetPixelsForAnnotationSymbol(const std::string& name) {
+ auto sprite = spriteStore.getSprite(name);
+ return sprite ? -sprite->height / 2 : 0;
+}
+
}
diff --git a/src/mbgl/annotation/annotation_manager.hpp b/src/mbgl/annotation/annotation_manager.hpp
index f1b41c9ccc..9fbbcc57c8 100644
--- a/src/mbgl/annotation/annotation_manager.hpp
+++ b/src/mbgl/annotation/annotation_manager.hpp
@@ -4,6 +4,8 @@
#include <mbgl/annotation/annotation.hpp>
#include <mbgl/annotation/point_annotation_impl.hpp>
#include <mbgl/annotation/shape_annotation_impl.hpp>
+#include <mbgl/sprite/sprite_store.hpp>
+#include <mbgl/sprite/sprite_atlas.hpp>
#include <mbgl/util/geo.hpp>
#include <mbgl/util/noncopyable.hpp>
@@ -21,7 +23,7 @@ class Style;
class AnnotationManager : private util::noncopyable {
public:
- AnnotationManager();
+ AnnotationManager(float pixelRatio);
~AnnotationManager();
AnnotationIDs addPointAnnotations(const std::vector<PointAnnotation>&, const uint8_t maxZoom);
@@ -31,6 +33,10 @@ public:
AnnotationIDs getPointAnnotationsInBounds(const LatLngBounds&) const;
LatLngBounds getBoundsForAnnotations(const AnnotationIDs&) const;
+ void setSprite(const std::string& name, std::shared_ptr<const SpriteImage>);
+ double getTopOffsetPixelsForAnnotationSymbol(const std::string& name);
+ SpriteAtlas& getSpriteAtlas() { return spriteAtlas; }
+
void updateStyle(Style&);
void addTileMonitor(AnnotationTileMonitor&);
@@ -48,6 +54,9 @@ private:
ShapeAnnotationImpl::Map shapeAnnotations;
std::vector<std::string> obsoleteShapeAnnotationLayers;
std::set<AnnotationTileMonitor*> monitors;
+
+ SpriteStore spriteStore;
+ SpriteAtlas spriteAtlas;
};
}
diff --git a/src/mbgl/layer/symbol_layer.cpp b/src/mbgl/layer/symbol_layer.cpp
index 8e43d3454e..f954999614 100644
--- a/src/mbgl/layer/symbol_layer.cpp
+++ b/src/mbgl/layer/symbol_layer.cpp
@@ -10,6 +10,7 @@ std::unique_ptr<StyleLayer> SymbolLayer::clone() const {
result->copy(*this);
result->layout = layout;
result->paint = paint;
+ result->spriteAtlas = spriteAtlas;
return std::move(result);
}
@@ -178,7 +179,7 @@ std::unique_ptr<Bucket> SymbolLayer::createBucket(StyleBucketParameters& paramet
// needed by this tile.
if (!parameters.partialParse) {
bucket->addFeatures(parameters.tileUID,
- parameters.spriteAtlas,
+ *spriteAtlas,
parameters.glyphAtlas,
parameters.glyphStore,
parameters.collisionTile);
diff --git a/src/mbgl/layer/symbol_layer.hpp b/src/mbgl/layer/symbol_layer.hpp
index 9e4555350a..1a9e4587bb 100644
--- a/src/mbgl/layer/symbol_layer.hpp
+++ b/src/mbgl/layer/symbol_layer.hpp
@@ -7,6 +7,8 @@
namespace mbgl {
+class SpriteAtlas;
+
class SymbolLayoutProperties {
public:
LayoutProperty<PlacementType> placement = PlacementType::Point;
@@ -94,6 +96,8 @@ public:
SymbolLayoutProperties layout;
SymbolPaintProperties paint;
+
+ SpriteAtlas* spriteAtlas;
};
}
diff --git a/src/mbgl/map/map_context.cpp b/src/mbgl/map/map_context.cpp
index 32cf760afa..17d91ab861 100644
--- a/src/mbgl/map/map_context.cpp
+++ b/src/mbgl/map/map_context.cpp
@@ -243,7 +243,7 @@ bool MapContext::renderSync(const TransformState& state, const FrameData& frame)
glObjectStore.performCleanup();
if (!painter) painter = std::make_unique<Painter>(data, transformState);
- painter->render(*style, frame);
+ painter->render(*style, frame, data.getAnnotationManager()->getSpriteAtlas());
if (data.mode == MapMode::Still) {
callback(nullptr, std::move(view.readStillImage()));
@@ -269,12 +269,7 @@ bool MapContext::isLoaded() const {
double MapContext::getTopOffsetPixelsForAnnotationSymbol(const std::string& symbol) {
assert(util::ThreadContext::currentlyOn(util::ThreadType::Map));
- auto sprite = style->spriteStore->getSprite(symbol);
- if (sprite) {
- return -sprite->height / 2;
- } else {
- return 0;
- }
+ return data.getAnnotationManager()->getTopOffsetPixelsForAnnotationSymbol(symbol);
}
void MapContext::setSourceTileCacheSize(size_t size) {
@@ -299,14 +294,8 @@ void MapContext::onLowMemory() {
}
void MapContext::setSprite(const std::string& name, std::shared_ptr<const SpriteImage> sprite) {
- if (!style) {
- Log::Info(Event::Sprite, "Ignoring sprite without stylesheet");
- return;
- }
-
- style->spriteStore->setSprite(name, sprite);
-
- style->spriteAtlas->updateDirty();
+ assert(util::ThreadContext::currentlyOn(util::ThreadType::Map));
+ data.getAnnotationManager()->setSprite(name, sprite);
}
void MapContext::onTileDataChanged() {
diff --git a/src/mbgl/map/map_data.hpp b/src/mbgl/map/map_data.hpp
index 43765e25b2..cf6ad20475 100644
--- a/src/mbgl/map/map_data.hpp
+++ b/src/mbgl/map/map_data.hpp
@@ -24,6 +24,7 @@ public:
: mode(mode_)
, contextMode(contextMode_)
, pixelRatio(pixelRatio_)
+ , annotationManager(pixelRatio)
, animationTime(Duration::zero())
, defaultFadeDuration(mode_ == MapMode::Continuous ? std::chrono::milliseconds(300) : Duration::zero())
, defaultTransitionDuration(Duration::zero())
diff --git a/src/mbgl/map/tile_worker.cpp b/src/mbgl/map/tile_worker.cpp
index 9dc0698db7..9686d579ae 100644
--- a/src/mbgl/map/tile_worker.cpp
+++ b/src/mbgl/map/tile_worker.cpp
@@ -64,7 +64,9 @@ TileParseResult TileWorker::parsePendingLayers() {
if (layer.type == StyleLayerType::Symbol) {
auto symbolBucket = dynamic_cast<SymbolBucket*>(bucket.get());
if (!symbolBucket->needsDependencies(*style.glyphStore, *style.spriteStore)) {
- symbolBucket->addFeatures(reinterpret_cast<uintptr_t>(this), *style.spriteAtlas,
+ const SymbolLayer* symbolLayer = dynamic_cast<const SymbolLayer*>(&layer);
+ symbolBucket->addFeatures(reinterpret_cast<uintptr_t>(this),
+ *symbolLayer->spriteAtlas,
*style.glyphAtlas, *style.glyphStore, *collisionTile);
insertBucket(layer.bucketName(), std::move(bucket));
pending.erase(it++);
diff --git a/src/mbgl/renderer/painter.cpp b/src/mbgl/renderer/painter.cpp
index a3902fece0..9c64fc9f90 100644
--- a/src/mbgl/renderer/painter.cpp
+++ b/src/mbgl/renderer/painter.cpp
@@ -128,7 +128,7 @@ void Painter::prepareTile(const Tile& tile) {
config.stencilFunc = { GL_EQUAL, ref, mask };
}
-void Painter::render(const Style& style, const FrameData& frame_) {
+void Painter::render(const Style& style, const FrameData& frame_, SpriteAtlas& annotationSpriteAtlas) {
frame = frame_;
glyphAtlas = style.glyphAtlas.get();
@@ -158,6 +158,7 @@ void Painter::render(const Style& style, const FrameData& frame_) {
spriteAtlas->upload();
lineAtlas->upload();
glyphAtlas->upload();
+ annotationSpriteAtlas.upload();
for (const auto& item : order) {
if (item.bucket && item.bucket->needsUpload()) {
diff --git a/src/mbgl/renderer/painter.hpp b/src/mbgl/renderer/painter.hpp
index 5de1031d23..0995ee4e44 100644
--- a/src/mbgl/renderer/painter.hpp
+++ b/src/mbgl/renderer/painter.hpp
@@ -93,7 +93,8 @@ public:
void changeMatrix();
void render(const Style& style,
- const FrameData& frame);
+ const FrameData& frame,
+ SpriteAtlas& annotationSpriteAtlas);
// Renders debug information for a tile.
void renderTileDebug(const Tile& tile);
diff --git a/src/mbgl/renderer/painter_symbol.cpp b/src/mbgl/renderer/painter_symbol.cpp
index f46a9c8454..4a00d941db 100644
--- a/src/mbgl/renderer/painter_symbol.cpp
+++ b/src/mbgl/renderer/painter_symbol.cpp
@@ -192,7 +192,8 @@ void Painter::renderSymbol(SymbolBucket& bucket, const SymbolLayer& layer, const
const float fontSize = properties.icon.size;
const float fontScale = fontSize / 1.0f;
- spriteAtlas->bind(state.isChanging() || layout.placement == PlacementType::Line
+ SpriteAtlas* activeSpriteAtlas = layer.spriteAtlas;
+ activeSpriteAtlas->bind(state.isChanging() || layout.placement == PlacementType::Line
|| angleOffset != 0 || fontScale != 1 || sdf || state.getPitch() != 0);
if (sdf) {
@@ -202,7 +203,7 @@ void Painter::renderSymbol(SymbolBucket& bucket, const SymbolLayer& layer, const
layout.icon,
properties.icon,
1.0f,
- {{ float(spriteAtlas->getWidth()) / 4.0f, float(spriteAtlas->getHeight()) / 4.0f }},
+ {{ float(activeSpriteAtlas->getWidth()) / 4.0f, float(activeSpriteAtlas->getHeight()) / 4.0f }},
*sdfIconShader,
&SymbolBucket::drawIcons);
} else {
diff --git a/src/mbgl/sprite/sprite_atlas.cpp b/src/mbgl/sprite/sprite_atlas.cpp
index 45b0511c68..ae71f18f03 100644
--- a/src/mbgl/sprite/sprite_atlas.cpp
+++ b/src/mbgl/sprite/sprite_atlas.cpp
@@ -24,9 +24,7 @@ SpriteAtlas::SpriteAtlas(dimension width_, dimension height_, float pixelRatio_,
pixelRatio(pixelRatio_),
store(store_),
bin(width_, height_),
- data(std::make_unique<uint32_t[]>(pixelWidth * pixelHeight)),
dirty(true) {
- std::fill(data.get(), data.get() + pixelWidth * pixelHeight, 0);
}
Rect<SpriteAtlas::dimension> SpriteAtlas::allocateImage(const size_t pixel_width, const size_t pixel_height) {
@@ -103,6 +101,11 @@ SpriteAtlasPosition SpriteAtlas::getPosition(const std::string& name, bool repea
}
void SpriteAtlas::copy(const Holder& holder, const bool wrap) {
+ if (!data) {
+ data = std::make_unique<uint32_t[]>(pixelWidth * pixelHeight);
+ std::fill(data.get(), data.get() + pixelWidth * pixelHeight, 0);
+ }
+
const uint32_t *srcData = reinterpret_cast<const uint32_t *>(holder.texture->data.data());
if (!srcData) return;
const vec2<uint32_t> srcSize { holder.texture->pixelWidth, holder.texture->pixelHeight };
@@ -189,6 +192,10 @@ void SpriteAtlas::updateDirty() {
}
void SpriteAtlas::bind(bool linear) {
+ if (!data) {
+ return; // Empty atlas
+ }
+
if (!texture) {
MBGL_CHECK_ERROR(glGenTextures(1, &texture));
MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, texture));
diff --git a/src/mbgl/sprite/sprite_atlas.hpp b/src/mbgl/sprite/sprite_atlas.hpp
index 0d86279e2d..0e3e8cf225 100644
--- a/src/mbgl/sprite/sprite_atlas.hpp
+++ b/src/mbgl/sprite/sprite_atlas.hpp
@@ -66,6 +66,8 @@ public:
inline dimension getTextureWidth() const { return pixelWidth; }
inline dimension getTextureHeight() const { return pixelHeight; }
inline float getPixelRatio() const { return pixelRatio; }
+
+ // Only for use in tests.
inline const uint32_t* getData() const { return data.get(); }
private:
@@ -90,7 +92,7 @@ private:
BinPack<dimension> bin;
std::map<Key, Holder> images;
std::set<std::string> uninitialized;
- const std::unique_ptr<uint32_t[]> data;
+ std::unique_ptr<uint32_t[]> data;
std::atomic<bool> dirty;
bool fullUploadRequired = true;
GLuint texture = 0;
diff --git a/src/mbgl/style/style.cpp b/src/mbgl/style/style.cpp
index 69f28e86bb..aa514de40c 100644
--- a/src/mbgl/style/style.cpp
+++ b/src/mbgl/style/style.cpp
@@ -2,6 +2,7 @@
#include <mbgl/map/map_data.hpp>
#include <mbgl/map/source.hpp>
#include <mbgl/map/transform_state.hpp>
+#include <mbgl/layer/symbol_layer.hpp>
#include <mbgl/sprite/sprite_store.hpp>
#include <mbgl/sprite/sprite_atlas.hpp>
#include <mbgl/style/style_layer.hpp>
@@ -88,6 +89,12 @@ StyleLayer* Style::getLayer(const std::string& id) const {
}
void Style::addLayer(util::ptr<StyleLayer> layer) {
+ if (SymbolLayer* symbolLayer = dynamic_cast<SymbolLayer*>(layer.get())) {
+ if (!symbolLayer->spriteAtlas) {
+ symbolLayer->spriteAtlas = spriteAtlas.get();
+ }
+ }
+
layers.emplace_back(std::move(layer));
}