diff --git a/CMakeLists.txt b/CMakeLists.txt index f0c7a2ac572..50e82553a4f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -56,6 +56,7 @@ mason_use(pixelmatch VERSION 0.10.0 HEADER_ONLY) mason_use(geojson VERSION 0.4.0 HEADER_ONLY) mason_use(polylabel VERSION 1.0.2 HEADER_ONLY) mason_use(wagyu VERSION 0.4.1 HEADER_ONLY) +mason_use(shelf-pack VERSION 2.0.1 HEADER_ONLY) add_definitions(-DRAPIDJSON_HAS_STDSTRING=1) diff --git a/cmake/core-files.cmake b/cmake/core-files.cmake index dfe11b82b84..e56f2fdc37d 100644 --- a/cmake/core-files.cmake +++ b/cmake/core-files.cmake @@ -288,8 +288,6 @@ set(MBGL_CORE_FILES # sprite src/mbgl/sprite/sprite_atlas.cpp src/mbgl/sprite/sprite_atlas.hpp - src/mbgl/sprite/sprite_image_collection.cpp - src/mbgl/sprite/sprite_image_collection.hpp src/mbgl/sprite/sprite_loader.cpp src/mbgl/sprite/sprite_loader.hpp src/mbgl/sprite/sprite_loader_observer.hpp diff --git a/cmake/core.cmake b/cmake/core.cmake index 531edc092da..5671ab53b5d 100644 --- a/cmake/core.cmake +++ b/cmake/core.cmake @@ -26,6 +26,7 @@ target_add_mason_package(mbgl-core PRIVATE earcut) target_add_mason_package(mbgl-core PRIVATE protozero) target_add_mason_package(mbgl-core PRIVATE polylabel) target_add_mason_package(mbgl-core PRIVATE wagyu) +target_add_mason_package(mbgl-core PRIVATE shelf-pack) mbgl_platform_core() diff --git a/cmake/test-files.cmake b/cmake/test-files.cmake index 83b935d63ff..c0673bedefd 100644 --- a/cmake/test-files.cmake +++ b/cmake/test-files.cmake @@ -46,7 +46,6 @@ set(MBGL_TEST_FILES # sprite test/sprite/sprite_atlas.test.cpp - test/sprite/sprite_image_collection.test.cpp test/sprite/sprite_loader.test.cpp test/sprite/sprite_parser.test.cpp diff --git a/cmake/test.cmake b/cmake/test.cmake index 3c63f7bcf89..8a5233f5a52 100644 --- a/cmake/test.cmake +++ b/cmake/test.cmake @@ -35,6 +35,7 @@ target_add_mason_package(mbgl-test PRIVATE pixelmatch) target_add_mason_package(mbgl-test PRIVATE boost) target_add_mason_package(mbgl-test PRIVATE geojson) target_add_mason_package(mbgl-test PRIVATE geojsonvt) +target_add_mason_package(mbgl-test PRIVATE shelf-pack) mbgl_platform_test() diff --git a/include/mbgl/style/image.hpp b/include/mbgl/style/image.hpp index 53cab23c2f8..55760ca5034 100644 --- a/include/mbgl/style/image.hpp +++ b/include/mbgl/style/image.hpp @@ -11,6 +11,7 @@ namespace style { class Image { public: Image(std::string id, PremultipliedImage&&, float pixelRatio, bool sdf = false); + Image(const Image&); std::string getID() const; diff --git a/src/mbgl/annotation/annotation_manager.cpp b/src/mbgl/annotation/annotation_manager.cpp index a7f1c69f3bb..9ea47acadb4 100644 --- a/src/mbgl/annotation/annotation_manager.cpp +++ b/src/mbgl/annotation/annotation_manager.cpp @@ -4,9 +4,7 @@ #include #include #include -#include #include -#include #include #include #include @@ -20,13 +18,7 @@ using namespace style; const std::string AnnotationManager::SourceID = "com.mapbox.annotations"; const std::string AnnotationManager::PointLayerID = "com.mapbox.annotations.points"; -AnnotationManager::AnnotationManager(float pixelRatio) - : spriteAtlas({ 1024, 1024 }, pixelRatio){ - // This is a special atlas, holding only images added via addIcon, so we always treat it as - // loaded. - spriteAtlas.markAsLoaded(); -} - +AnnotationManager::AnnotationManager() = default; AnnotationManager::~AnnotationManager() = default; AnnotationID AnnotationManager::addAnnotation(const Annotation& annotation, const uint8_t maxZoom) { @@ -156,7 +148,7 @@ void AnnotationManager::updateStyle(Style& style) { std::unique_ptr layer = std::make_unique(PointLayerID, SourceID); layer->setSourceLayer(PointLayerID); - layer->setIconImage({"{sprite}"}); + layer->setIconImage({SourceID + ".{sprite}"}); layer->setIconAllowOverlap(true); layer->setIconIgnorePlacement(true); @@ -167,13 +159,30 @@ void AnnotationManager::updateStyle(Style& style) { shape.second->updateStyle(style); } + for (const auto& image : images) { + // Call addImage even for images we may have previously added, because we must support + // addAnnotationImage being used to update an existing image. Creating a new image is + // relatively cheap, as it copies only the Immutable reference. (We can't keep track + // of which images need to be added because we don't know if the style is the same + // instance as in the last updateStyle call. If it's a new style, we need to add all + // images.) + style.addImage(std::make_unique(image.second)); + } + for (const auto& layer : obsoleteShapeAnnotationLayers) { if (style.getLayer(layer)) { style.removeLayer(layer); } } + for (const auto& image : obsoleteImages) { + if (style.getImage(image)) { + style.removeImage(image); + } + } + obsoleteShapeAnnotationLayers.clear(); + obsoleteImages.clear(); } void AnnotationManager::updateData() { @@ -192,20 +201,23 @@ void AnnotationManager::removeTile(AnnotationTile& tile) { } void AnnotationManager::addImage(std::unique_ptr image) { - addSpriteImage(spriteImages, std::move(image), [&](style::Image& added) { - spriteAtlas.addImage(added.impl); - }); + // To ensure that annotation images do not collide with images from the style, + // create a new image with the input ID prefixed by "com.mapbox.annotations". + std::string id = SourceID + "." + image->getID(); + images.erase(id); + images.emplace(id, + style::Image(id, image->getImage().clone(), image->getPixelRatio(), image->isSdf())); + obsoleteImages.erase(id); } void AnnotationManager::removeImage(const std::string& id) { - removeSpriteImage(spriteImages, id, [&] () { - spriteAtlas.removeImage(id); - }); + images.erase(id); + obsoleteImages.insert(id); } double AnnotationManager::getTopOffsetPixelsForImage(const std::string& id) { - const style::Image::Impl* impl = spriteAtlas.getImage(id); - return impl ? -(impl->image.size.height / impl->pixelRatio) / 2 : 0; + auto it = images.find(id); + return it == images.end() ? -(it->second.getImage().size.height / it->second.getPixelRatio()) / 2 : 0; } } // namespace mbgl diff --git a/src/mbgl/annotation/annotation_manager.hpp b/src/mbgl/annotation/annotation_manager.hpp index 837827b75c4..36f18e1aaea 100644 --- a/src/mbgl/annotation/annotation_manager.hpp +++ b/src/mbgl/annotation/annotation_manager.hpp @@ -2,7 +2,7 @@ #include #include -#include +#include #include #include @@ -21,12 +21,11 @@ class ShapeAnnotationImpl; namespace style { class Style; -class Image; } // namespace style class AnnotationManager : private util::noncopyable { public: - AnnotationManager(float pixelRatio); + AnnotationManager(); ~AnnotationManager(); AnnotationID addAnnotation(const Annotation&, const uint8_t maxZoom); @@ -36,7 +35,6 @@ class AnnotationManager : private util::noncopyable { void addImage(std::unique_ptr); void removeImage(const std::string&); double getTopOffsetPixelsForImage(const std::string&); - SpriteAtlas& getSpriteAtlas() { return spriteAtlas; } void updateStyle(style::Style&); void updateData(); @@ -67,16 +65,16 @@ class AnnotationManager : private util::noncopyable { // using SymbolAnnotationMap = std::map>; using ShapeAnnotationMap = std::map>; + using ImageMap = std::unordered_map; SymbolAnnotationTree symbolTree; SymbolAnnotationMap symbolAnnotations; ShapeAnnotationMap shapeAnnotations; + ImageMap images; std::unordered_set obsoleteShapeAnnotationLayers; + std::unordered_set obsoleteImages; std::unordered_set tiles; - std::unordered_map> spriteImages; - SpriteAtlas spriteAtlas; - friend class AnnotationTile; }; diff --git a/src/mbgl/annotation/annotation_tile.cpp b/src/mbgl/annotation/annotation_tile.cpp index 12536814140..1b34026f741 100644 --- a/src/mbgl/annotation/annotation_tile.cpp +++ b/src/mbgl/annotation/annotation_tile.cpp @@ -13,7 +13,7 @@ AnnotationTile::AnnotationTile(const OverscaledTileID& overscaledTileID, const TileParameters& parameters) : GeometryTile(overscaledTileID, AnnotationManager::SourceID, parameters, *parameters.style.glyphAtlas, - parameters.annotationManager.spriteAtlas), + *parameters.style.spriteAtlas), annotationManager(parameters.annotationManager) { annotationManager.addTile(*this); } diff --git a/src/mbgl/map/map.cpp b/src/mbgl/map/map.cpp index e994428bf1d..75447609271 100644 --- a/src/mbgl/map/map.cpp +++ b/src/mbgl/map/map.cpp @@ -90,7 +90,7 @@ class Map::Impl : public style::Observer { Update updateFlags = Update::Nothing; - std::unique_ptr annotationManager; + AnnotationManager annotationManager; std::unique_ptr painter; std::unique_ptr