From 11dd4afc5b271c4efb0e900320bdca4d137cd049 Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Fri, 17 Jun 2016 08:28:19 -0700 Subject: [PATCH] [core] Bring optimized animated annotations to Android release branch Part of #5385 --- include/mbgl/map/update.hpp | 3 ++- src/mbgl/annotation/annotation_manager.cpp | 29 +++++++++++++++++----- src/mbgl/annotation/annotation_manager.hpp | 6 +++-- src/mbgl/map/map.cpp | 17 +++++++------ src/mbgl/style/style.cpp | 6 ++--- src/mbgl/style/style.hpp | 2 +- src/mbgl/tile/tile_worker.cpp | 17 +------------ src/mbgl/tile/tile_worker.hpp | 2 -- src/mbgl/tile/vector_tile_data.cpp | 28 ++++++++++++++++++--- src/mbgl/tile/vector_tile_data.hpp | 5 ++++ test/api/annotations.cpp | 2 +- 11 files changed, 75 insertions(+), 42 deletions(-) diff --git a/include/mbgl/map/update.hpp b/include/mbgl/map/update.hpp index 3915545bb0c..1c1270ac700 100644 --- a/include/mbgl/map/update.hpp +++ b/include/mbgl/map/update.hpp @@ -13,7 +13,8 @@ enum class Update : uint8_t { RecalculateStyle = 1 << 3, RenderStill = 1 << 4, Repaint = 1 << 5, - Annotations = 1 << 6, + AnnotationStyle = 1 << 6, + AnnotationData = 1 << 7, }; inline Update operator| (const Update& lhs, const Update& rhs) { diff --git a/src/mbgl/annotation/annotation_manager.cpp b/src/mbgl/annotation/annotation_manager.cpp index 1febc757a4c..5cd26169604 100644 --- a/src/mbgl/annotation/annotation_manager.cpp +++ b/src/mbgl/annotation/annotation_manager.cpp @@ -49,14 +49,29 @@ AnnotationManager::addShapeAnnotations(const std::vector& shape return annotationIDs; } -void AnnotationManager::updatePointAnnotation(const AnnotationID& id, const PointAnnotation& point, const uint8_t) { +Update AnnotationManager::updatePointAnnotation(const AnnotationID& id, const PointAnnotation& point, const uint8_t) { auto foundAnnotation = pointAnnotations.find(id); - if (foundAnnotation != pointAnnotations.end()) { - auto updatedAnnotation = std::make_shared(id, point); - pointTree.remove(foundAnnotation->second); - pointTree.insert(updatedAnnotation); - foundAnnotation->second = updatedAnnotation; + if (foundAnnotation == pointAnnotations.end()) { + return Update::Nothing; } + + Update result = Update::Nothing; + const PointAnnotation& existing = foundAnnotation->second->point; + + if (existing.position != point.position) { + result |= Update::AnnotationData; + } + + if (existing.icon != point.icon) { + result |= Update::AnnotationData | Update::AnnotationStyle; + } + + auto updatedAnnotation = std::make_shared(id, point); + pointTree.remove(foundAnnotation->second); + pointTree.insert(updatedAnnotation); + foundAnnotation->second = updatedAnnotation; + + return result; } void AnnotationManager::removeAnnotations(const AnnotationIDs& ids) { @@ -135,7 +150,9 @@ void AnnotationManager::updateStyle(Style& style) { } obsoleteShapeAnnotationLayers.clear(); +} +void AnnotationManager::updateData() { for (auto& monitor : monitors) { monitor->update(getTile(monitor->tileID.canonical)); } diff --git a/src/mbgl/annotation/annotation_manager.hpp b/src/mbgl/annotation/annotation_manager.hpp index aaa60278cf0..560a166894f 100644 --- a/src/mbgl/annotation/annotation_manager.hpp +++ b/src/mbgl/annotation/annotation_manager.hpp @@ -5,7 +5,7 @@ #include #include #include -#include +#include #include #include @@ -14,6 +14,7 @@ namespace mbgl { +class LatLngBounds; class PointAnnotation; class ShapeAnnotation; class AnnotationTile; @@ -27,7 +28,7 @@ class AnnotationManager : private util::noncopyable { AnnotationIDs addPointAnnotations(const std::vector&, const uint8_t maxZoom); AnnotationIDs addShapeAnnotations(const std::vector&, const uint8_t maxZoom); - void updatePointAnnotation(const AnnotationID&, const PointAnnotation&, const uint8_t maxZoom); + Update updatePointAnnotation(const AnnotationID&, const PointAnnotation&, const uint8_t maxZoom); void removeAnnotations(const AnnotationIDs&); AnnotationIDs getPointAnnotationsInBounds(const LatLngBounds&) const; @@ -38,6 +39,7 @@ class AnnotationManager : private util::noncopyable { SpriteAtlas& getSpriteAtlas() { return spriteAtlas; } void updateStyle(Style&); + void updateData(); void addTileMonitor(AnnotationTileMonitor&); void removeTileMonitor(AnnotationTileMonitor&); diff --git a/src/mbgl/map/map.cpp b/src/mbgl/map/map.cpp index 841b4607c67..99262beb2ea 100644 --- a/src/mbgl/map/map.cpp +++ b/src/mbgl/map/map.cpp @@ -211,11 +211,15 @@ void Map::Impl::update() { // - Hint style sources to notify when all its tiles are loaded; timePoint = Clock::now(); - if (style->loaded && updateFlags & Update::Annotations) { + if (style->loaded && updateFlags & Update::AnnotationStyle) { annotationManager->updateStyle(*style); updateFlags |= Update::Classes; } + if (updateFlags & Update::AnnotationData) { + annotationManager->updateData(); + } + if (updateFlags & Update::Classes) { style->cascade(timePoint, mode); } @@ -344,7 +348,7 @@ void Map::Impl::loadStyleJSON(const std::string& json, const std::string& base) // force style cascade, causing all pending transitions to complete. style->cascade(Clock::now(), mode); - updateFlags |= Update::Classes | Update::RecalculateStyle | Update::Annotations; + updateFlags |= Update::Classes | Update::RecalculateStyle | Update::AnnotationStyle; asyncUpdate.send(); } @@ -700,7 +704,7 @@ AnnotationID Map::addPointAnnotation(const PointAnnotation& annotation) { AnnotationIDs Map::addPointAnnotations(const std::vector& annotations) { auto result = impl->annotationManager->addPointAnnotations(annotations, getMaxZoom()); - update(Update::Annotations); + update(Update::AnnotationStyle | Update::AnnotationData); return result; } @@ -710,13 +714,12 @@ AnnotationID Map::addShapeAnnotation(const ShapeAnnotation& annotation) { AnnotationIDs Map::addShapeAnnotations(const std::vector& annotations) { auto result = impl->annotationManager->addShapeAnnotations(annotations, getMaxZoom()); - update(Update::Annotations); + update(Update::AnnotationStyle | Update::AnnotationData); return result; } void Map::updatePointAnnotation(AnnotationID annotationId, const PointAnnotation& annotation) { - impl->annotationManager->updatePointAnnotation(annotationId, annotation, getMaxZoom()); - update(Update::Annotations); + update(impl->annotationManager->updatePointAnnotation(annotationId, annotation, getMaxZoom())); } void Map::removeAnnotation(AnnotationID annotation) { @@ -725,7 +728,7 @@ void Map::removeAnnotation(AnnotationID annotation) { void Map::removeAnnotations(const AnnotationIDs& annotations) { impl->annotationManager->removeAnnotations(annotations); - update(Update::Annotations); + update(Update::AnnotationStyle | Update::AnnotationData); } AnnotationIDs Map::getPointAnnotationsInBounds(const LatLngBounds& bounds) { diff --git a/src/mbgl/style/style.cpp b/src/mbgl/style/style.cpp index bc2a1d9a402..774e523b7b5 100644 --- a/src/mbgl/style/style.cpp +++ b/src/mbgl/style/style.cpp @@ -109,11 +109,11 @@ void Style::addSource(std::unique_ptr source) { sources.emplace_back(std::move(source)); } -std::vector> Style::getLayers() const { - std::vector> result; +std::vector Style::getLayers() const { + std::vector result; result.reserve(layers.size()); for (const auto& layer : layers) { - result.push_back(layer->clone()); + result.push_back(layer.get()); } return result; } diff --git a/src/mbgl/style/style.hpp b/src/mbgl/style/style.hpp index 5fdd6cdc8e2..1150c9daf56 100644 --- a/src/mbgl/style/style.hpp +++ b/src/mbgl/style/style.hpp @@ -69,7 +69,7 @@ class Style : public GlyphStoreObserver, Source* getSource(const std::string& id) const; void addSource(std::unique_ptr); - std::vector> getLayers() const; + std::vector getLayers() const; StyleLayer* getLayer(const std::string& id) const; void addLayer(std::unique_ptr, optional beforeLayerID = {}); diff --git a/src/mbgl/tile/tile_worker.cpp b/src/mbgl/tile/tile_worker.cpp index 266e357ab11..ae26ccd4a37 100644 --- a/src/mbgl/tile/tile_worker.cpp +++ b/src/mbgl/tile/tile_worker.cpp @@ -3,8 +3,6 @@ #include #include #include -#include -#include #include #include #include @@ -13,19 +11,18 @@ #include #include #include + #include using namespace mbgl; TileWorker::TileWorker(const OverscaledTileID& id_, - std::string sourceID_, SpriteStore& spriteStore_, GlyphAtlas& glyphAtlas_, GlyphStore& glyphStore_, const util::Atomic& obsolete_, const MapMode mode_) : id(id_), - sourceID(std::move(sourceID_)), spriteStore(spriteStore_), glyphAtlas(glyphAtlas_), glyphStore(glyphStore_), @@ -134,18 +131,6 @@ void TileWorker::parseLayer(const StyleLayer* layer) { if (obsolete) return; - // Background and custom layers are special cases. - if (layer->is() || layer->is()) - return; - - // Skip this bucket if we are to not render this - if ((layer->source != sourceID) || - (id.overscaledZ < std::floor(layer->minZoom)) || - (id.overscaledZ >= std::ceil(layer->maxZoom)) || - (layer->visibility == VisibilityType::None)) { - return; - } - auto geometryLayer = geometryTile->getLayer(layer->sourceLayer); if (!geometryLayer) { // The layer specified in the bucket does not exist. Do nothing. diff --git a/src/mbgl/tile/tile_worker.hpp b/src/mbgl/tile/tile_worker.hpp index e19d803ac4d..5a8b336e316 100644 --- a/src/mbgl/tile/tile_worker.hpp +++ b/src/mbgl/tile/tile_worker.hpp @@ -43,7 +43,6 @@ using TileParseResult = variant< class TileWorker : public util::noncopyable { public: TileWorker(const OverscaledTileID&, - std::string sourceID, SpriteStore&, GlyphAtlas&, GlyphStore&, @@ -67,7 +66,6 @@ class TileWorker : public util::noncopyable { std::unique_ptr placeLayers(PlacementConfig); const OverscaledTileID id; - const std::string sourceID; SpriteStore& spriteStore; GlyphAtlas& glyphAtlas; diff --git a/src/mbgl/tile/vector_tile_data.cpp b/src/mbgl/tile/vector_tile_data.cpp index 428c605f266..e81e94ed5ac 100644 --- a/src/mbgl/tile/vector_tile_data.cpp +++ b/src/mbgl/tile/vector_tile_data.cpp @@ -1,6 +1,8 @@ #include #include #include +#include +#include #include #include #include @@ -13,15 +15,15 @@ namespace mbgl { VectorTileData::VectorTileData(const OverscaledTileID& id_, std::unique_ptr monitor_, - std::string sourceID, + std::string sourceID_, Style& style_, const MapMode mode_, const std::function& callback) : TileData(id_), + sourceID(std::move(sourceID_)), style(style_), worker(style_.workers), tileWorker(id_, - sourceID, *style_.spriteStore, *style_.glyphAtlas, *style_.glyphStore, @@ -60,7 +62,7 @@ VectorTileData::VectorTileData(const OverscaledTileID& id_, // when tile data changed. Replacing the workdRequest will cancel a pending work // request in case there is one. workRequest.reset(); - workRequest = worker.parseGeometryTile(tileWorker, style.getLayers(), std::move(tile), targetConfig, [callback, this, config = targetConfig] (TileParseResult result) { + workRequest = worker.parseGeometryTile(tileWorker, cloneStyleLayers(), std::move(tile), targetConfig, [callback, this, config = targetConfig] (TileParseResult result) { workRequest.reset(); std::exception_ptr error; @@ -97,6 +99,26 @@ VectorTileData::~VectorTileData() { cancel(); } +std::vector> VectorTileData::cloneStyleLayers() const { + std::vector> result; + + for (const StyleLayer* layer : style.getLayers()) { + // Avoid cloning and including irrelevant layers. + if (layer->is() || + layer->is() || + layer->source != sourceID || + id.overscaledZ < std::floor(layer->minZoom) || + id.overscaledZ >= std::ceil(layer->maxZoom) || + layer->visibility == VisibilityType::None) { + continue; + } + + result.push_back(layer->clone()); + } + + return result; +} + bool VectorTileData::parsePending(std::function callback) { if (workRequest) { // There's already parsing or placement going on. diff --git a/src/mbgl/tile/vector_tile_data.hpp b/src/mbgl/tile/vector_tile_data.hpp index ec557e2023c..a6ed6213cec 100644 --- a/src/mbgl/tile/vector_tile_data.hpp +++ b/src/mbgl/tile/vector_tile_data.hpp @@ -8,10 +8,12 @@ #include #include +#include namespace mbgl { class Style; +class StyleLayer; class AsyncRequest; class GeometryTileMonitor; class FeatureIndex; @@ -43,6 +45,9 @@ class VectorTileData : public TileData { void cancel() override; private: + std::vector> cloneStyleLayers() const; + + const std::string sourceID; Style& style; Worker& worker; TileWorker tileWorker; diff --git a/test/api/annotations.cpp b/test/api/annotations.cpp index 8640ce9dbe7..0764cd8a5d8 100644 --- a/test/api/annotations.cpp +++ b/test/api/annotations.cpp @@ -159,7 +159,7 @@ TEST(Annotations, UpdateIcon) { map.removeAnnotationIcon("flipped_marker"); map.addAnnotationIcon("flipped_marker", namedMarker("flipped_marker.png")); - map.update(Update::Annotations); + map.update(Update::AnnotationData | Update::AnnotationStyle); checkRendering(map, "update_icon"); }