[core] Bring optimized animated annotations to Android release branch

Part of #5385
This commit is contained in:
John Firebaugh
2016-06-17 08:28:19 -07:00
committed by Antonio Zugaldia
parent ebbe90983f
commit 11dd4afc5b
11 changed files with 75 additions and 42 deletions

View File

@@ -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) {

View File

@@ -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));
}

View File

@@ -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&);

View File

@@ -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) {

View File

@@ -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;
}

View File

@@ -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 = {});

View File

@@ -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.

View File

@@ -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;

View File

@@ -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.

View File

@@ -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;

View File

@@ -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");
}