[core] Bring optimized animated annotations to Android release branch
Part of #5385
This commit is contained in:
committed by
Antonio Zugaldia
parent
ebbe90983f
commit
11dd4afc5b
@@ -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) {
|
||||
|
||||
@@ -49,14 +49,29 @@ AnnotationManager::addShapeAnnotations(const std::vector<ShapeAnnotation>& 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<PointAnnotationImpl>(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<PointAnnotationImpl>(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));
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#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/map/update.hpp>
|
||||
#include <mbgl/util/noncopyable.hpp>
|
||||
|
||||
#include <string>
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class LatLngBounds;
|
||||
class PointAnnotation;
|
||||
class ShapeAnnotation;
|
||||
class AnnotationTile;
|
||||
@@ -27,7 +28,7 @@ public:
|
||||
|
||||
AnnotationIDs addPointAnnotations(const std::vector<PointAnnotation>&, const uint8_t maxZoom);
|
||||
AnnotationIDs addShapeAnnotations(const std::vector<ShapeAnnotation>&, 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 @@ public:
|
||||
SpriteAtlas& getSpriteAtlas() { return spriteAtlas; }
|
||||
|
||||
void updateStyle(Style&);
|
||||
void updateData();
|
||||
|
||||
void addTileMonitor(AnnotationTileMonitor&);
|
||||
void removeTileMonitor(AnnotationTileMonitor&);
|
||||
|
||||
@@ -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<PointAnnotation>& 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<ShapeAnnotation>& 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) {
|
||||
|
||||
@@ -109,11 +109,11 @@ void Style::addSource(std::unique_ptr<Source> source) {
|
||||
sources.emplace_back(std::move(source));
|
||||
}
|
||||
|
||||
std::vector<std::unique_ptr<StyleLayer>> Style::getLayers() const {
|
||||
std::vector<std::unique_ptr<StyleLayer>> result;
|
||||
std::vector<const StyleLayer*> Style::getLayers() const {
|
||||
std::vector<const StyleLayer*> result;
|
||||
result.reserve(layers.size());
|
||||
for (const auto& layer : layers) {
|
||||
result.push_back(layer->clone());
|
||||
result.push_back(layer.get());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ public:
|
||||
Source* getSource(const std::string& id) const;
|
||||
void addSource(std::unique_ptr<Source>);
|
||||
|
||||
std::vector<std::unique_ptr<StyleLayer>> getLayers() const;
|
||||
std::vector<const StyleLayer*> getLayers() const;
|
||||
StyleLayer* getLayer(const std::string& id) const;
|
||||
void addLayer(std::unique_ptr<StyleLayer>,
|
||||
optional<std::string> beforeLayerID = {});
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
#include <mbgl/tile/geometry_tile.hpp>
|
||||
#include <mbgl/style/style_layer.hpp>
|
||||
#include <mbgl/style/style_bucket_parameters.hpp>
|
||||
#include <mbgl/layer/background_layer.hpp>
|
||||
#include <mbgl/layer/custom_layer.hpp>
|
||||
#include <mbgl/layer/symbol_layer.hpp>
|
||||
#include <mbgl/sprite/sprite_atlas.hpp>
|
||||
#include <mbgl/geometry/glyph_atlas.hpp>
|
||||
@@ -13,19 +11,18 @@
|
||||
#include <mbgl/util/constants.hpp>
|
||||
#include <mbgl/util/string.hpp>
|
||||
#include <mbgl/util/exception.hpp>
|
||||
|
||||
#include <utility>
|
||||
|
||||
using namespace mbgl;
|
||||
|
||||
TileWorker::TileWorker(const OverscaledTileID& id_,
|
||||
std::string sourceID_,
|
||||
SpriteStore& spriteStore_,
|
||||
GlyphAtlas& glyphAtlas_,
|
||||
GlyphStore& glyphStore_,
|
||||
const util::Atomic<bool>& 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<BackgroundLayer>() || layer->is<CustomLayer>())
|
||||
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.
|
||||
|
||||
@@ -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 @@ private:
|
||||
std::unique_ptr<CollisionTile> placeLayers(PlacementConfig);
|
||||
|
||||
const OverscaledTileID id;
|
||||
const std::string sourceID;
|
||||
|
||||
SpriteStore& spriteStore;
|
||||
GlyphAtlas& glyphAtlas;
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#include <mbgl/tile/vector_tile_data.hpp>
|
||||
#include <mbgl/tile/geometry_tile.hpp>
|
||||
#include <mbgl/style/style_layer.hpp>
|
||||
#include <mbgl/layer/background_layer.hpp>
|
||||
#include <mbgl/layer/custom_layer.hpp>
|
||||
#include <mbgl/util/worker.hpp>
|
||||
#include <mbgl/util/work_request.hpp>
|
||||
#include <mbgl/style/style.hpp>
|
||||
@@ -13,15 +15,15 @@ namespace mbgl {
|
||||
|
||||
VectorTileData::VectorTileData(const OverscaledTileID& id_,
|
||||
std::unique_ptr<GeometryTileMonitor> monitor_,
|
||||
std::string sourceID,
|
||||
std::string sourceID_,
|
||||
Style& style_,
|
||||
const MapMode mode_,
|
||||
const std::function<void(std::exception_ptr)>& 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<std::unique_ptr<StyleLayer>> VectorTileData::cloneStyleLayers() const {
|
||||
std::vector<std::unique_ptr<StyleLayer>> result;
|
||||
|
||||
for (const StyleLayer* layer : style.getLayers()) {
|
||||
// Avoid cloning and including irrelevant layers.
|
||||
if (layer->is<BackgroundLayer>() ||
|
||||
layer->is<CustomLayer>() ||
|
||||
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<void(std::exception_ptr)> callback) {
|
||||
if (workRequest) {
|
||||
// There's already parsing or placement going on.
|
||||
|
||||
@@ -8,10 +8,12 @@
|
||||
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class Style;
|
||||
class StyleLayer;
|
||||
class AsyncRequest;
|
||||
class GeometryTileMonitor;
|
||||
class FeatureIndex;
|
||||
@@ -43,6 +45,9 @@ public:
|
||||
void cancel() override;
|
||||
|
||||
private:
|
||||
std::vector<std::unique_ptr<StyleLayer>> cloneStyleLayers() const;
|
||||
|
||||
const std::string sourceID;
|
||||
Style& style;
|
||||
Worker& worker;
|
||||
TileWorker tileWorker;
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user