[core] Refactor RenderSource updates

* Eliminate updateBatch in favor of diffing layers and detecting changes to properties upon which layout depends.
* Replace RenderSource::{update,remove,invalidate,reload}Tiles with a single update method
* Replace TilePyramid::{update,remove,invalidate,reload}Tiles with a single update method
* Remove Style& dependency TODO from GeometryTile and TileParameters
This commit is contained in:
John Firebaugh
2017-05-30 13:40:36 -07:00
parent 32589c271c
commit 591af0021b
52 changed files with 494 additions and 432 deletions

View File

@@ -353,7 +353,6 @@ set(MBGL_CORE_FILES
src/mbgl/style/style.cpp
src/mbgl/style/style.hpp
src/mbgl/style/types.cpp
src/mbgl/style/update_batch.hpp
# style/conversion
include/mbgl/style/conversion/constant.hpp

View File

@@ -59,6 +59,10 @@ public:
auto evaluate(const Evaluator& evaluator, TimePoint = {}) const {
return Value::visit(value, evaluator);
}
bool hasDataDrivenPropertyDifference(const DataDrivenPropertyValue<T>& other) const {
return *this != other && (isDataDriven() || other.isDataDriven());
}
};
} // namespace style

View File

@@ -38,6 +38,10 @@ public:
auto evaluate(const Evaluator& evaluator, TimePoint = {}) const {
return Value::visit(value, evaluator);
}
bool hasDataDrivenPropertyDifference(const PropertyValue<T>&) const {
return false;
}
};
} // namespace style

View File

@@ -3,7 +3,6 @@
#include <mbgl/util/constants.hpp>
#include <mbgl/storage/file_source.hpp>
#include <mbgl/renderer/tile_parameters.hpp>
#include <mbgl/style/style.hpp>
#include <utility>
@@ -11,9 +10,7 @@ namespace mbgl {
AnnotationTile::AnnotationTile(const OverscaledTileID& overscaledTileID,
const TileParameters& parameters)
: GeometryTile(overscaledTileID, AnnotationManager::SourceID, parameters,
*parameters.style.glyphAtlas,
*parameters.style.spriteAtlas),
: GeometryTile(overscaledTileID, AnnotationManager::SourceID, parameters),
annotationManager(parameters.annotationManager) {
annotationManager.addTile(*this);
}

View File

@@ -22,8 +22,25 @@ bool RenderAnnotationSource::isLoaded() const {
return tilePyramid.isLoaded();
}
void RenderAnnotationSource::invalidateTiles() {
tilePyramid.invalidateTiles();
void RenderAnnotationSource::update(Immutable<style::Source::Impl> baseImpl_,
const std::vector<Immutable<Layer::Impl>>& layers,
const bool needsRendering,
const bool needsRelayout,
const TileParameters& parameters) {
std::swap(baseImpl, baseImpl_);
enabled = needsRendering;
tilePyramid.update(layers,
needsRendering,
needsRelayout,
parameters,
SourceType::Annotations,
util::tileSize,
{ 0, 22 },
[&] (const OverscaledTileID& tileID) {
return std::make_unique<AnnotationTile>(tileID, parameters);
});
}
void RenderAnnotationSource::startRender(algorithm::ClipIDGenerator& generator, const mat4& projMatrix, const mat4& clipMatrix, const TransformState& transform) {
@@ -39,24 +56,6 @@ std::map<UnwrappedTileID, RenderTile>& RenderAnnotationSource::getRenderTiles()
return tilePyramid.getRenderTiles();
}
void RenderAnnotationSource::updateTiles(const TileParameters& parameters) {
tilePyramid.updateTiles(parameters,
SourceType::Annotations,
util::tileSize,
{ 0, 22 },
[&] (const OverscaledTileID& tileID) {
return std::make_unique<AnnotationTile>(tileID, parameters);
});
}
void RenderAnnotationSource::removeTiles() {
tilePyramid.removeTiles();
}
void RenderAnnotationSource::reloadTiles() {
tilePyramid.reloadTiles();
}
std::unordered_map<std::string, std::vector<Feature>>
RenderAnnotationSource::queryRenderedFeatures(const ScreenLineString& geometry,
const TransformState& transformState,

View File

@@ -12,19 +12,11 @@ public:
bool isLoaded() const final;
// Called when the camera has changed. May load new tiles, unload obsolete tiles, or
// trigger re-placement of existing complete tiles.
void updateTiles(const TileParameters&) final;
// Removes all tiles (by putting them into the cache).
void removeTiles() final;
// Remove all tiles and clear the cache.
void invalidateTiles() final;
// Request that all loaded tiles re-run the layout operation on the existing source
// data with fresh style information.
void reloadTiles() final;
void update(Immutable<style::Source::Impl>,
const std::vector<Immutable<style::Layer::Impl>>&,
bool needsRendering,
bool needsRelayout,
const TileParameters&) final;
void startRender(algorithm::ClipIDGenerator&,
const mat4& projMatrix,

View File

@@ -3,6 +3,7 @@
#include <mbgl/renderer/sources/render_geojson_source.hpp>
#include <mbgl/renderer/sources/render_raster_source.hpp>
#include <mbgl/renderer/sources/render_vector_source.hpp>
#include <mbgl/renderer/tile_parameters.hpp>
#include <mbgl/annotation/render_annotation_source.hpp>
#include <mbgl/renderer/sources/render_image_source.hpp>
#include <mbgl/tile/tile.hpp>
@@ -44,10 +45,6 @@ void RenderSource::setObserver(RenderSourceObserver* observer_) {
observer = observer_;
}
void RenderSource::setImpl(Immutable<style::Source::Impl> impl) {
baseImpl = impl;
}
void RenderSource::onTileChanged(Tile& tile) {
observer->onTileChanged(*this, tile.id);
}
@@ -56,4 +53,8 @@ void RenderSource::onTileError(Tile& tile, std::exception_ptr error) {
observer->onTileError(*this, tile.id, error);
}
bool RenderSource::isEnabled() const {
return enabled;
}
} // namespace mbgl

View File

@@ -6,6 +6,7 @@
#include <mbgl/util/geo.hpp>
#include <mbgl/util/feature.hpp>
#include <mbgl/style/source_impl.hpp>
#include <mbgl/style/layer_impl.hpp>
#include <unordered_map>
#include <vector>
@@ -17,6 +18,7 @@ namespace mbgl {
class Painter;
class TransformState;
class RenderTile;
class RenderLayer;
class RenderedQueryOptions;
class SourceQueryOptions;
class Tile;
@@ -35,8 +37,6 @@ class RenderSource : protected TileObserver {
public:
static std::unique_ptr<RenderSource> create(Immutable<style::Source::Impl>);
~RenderSource() override = default;
// Check whether this source is of the given subtype.
template <class T>
bool is() const;
@@ -52,21 +52,14 @@ public:
return is<T>() ? reinterpret_cast<const T*>(this) : nullptr;
}
bool isEnabled() const;
virtual bool isLoaded() const = 0;
// Called when the camera has changed. May load new tiles, unload obsolete tiles, or
// trigger re-placement of existing complete tiles.
virtual void updateTiles(const TileParameters&) = 0;
// Removes all tiles (by putting them into the cache).
virtual void removeTiles() = 0;
// Remove all tiles and clear the cache.
virtual void invalidateTiles() = 0;
// Request that all loaded tiles re-run the layout operation on the existing source
// data with fresh style information.
virtual void reloadTiles() = 0;
virtual void update(Immutable<style::Source::Impl>,
const std::vector<Immutable<style::Layer::Impl>>&,
bool needsRendering,
bool needsRelayout,
const TileParameters&) = 0;
virtual void startRender(algorithm::ClipIDGenerator&,
const mat4& projMatrix,
@@ -93,14 +86,13 @@ public:
void setObserver(RenderSourceObserver*);
Immutable<style::Source::Impl> baseImpl;
void setImpl(Immutable<style::Source::Impl>);
bool enabled = false;
protected:
RenderSource(Immutable<style::Source::Impl>);
RenderSourceObserver* observer;
bool enabled = false;
void onTileChanged(Tile&) final;
void onTileError(Tile&, std::exception_ptr) final;
};

View File

@@ -22,24 +22,15 @@ bool RenderGeoJSONSource::isLoaded() const {
return tilePyramid.isLoaded();
}
void RenderGeoJSONSource::invalidateTiles() {
tilePyramid.invalidateTiles();
}
void RenderGeoJSONSource::update(Immutable<style::Source::Impl> baseImpl_,
const std::vector<Immutable<Layer::Impl>>& layers,
const bool needsRendering,
const bool needsRelayout,
const TileParameters& parameters) {
std::swap(baseImpl, baseImpl_);
void RenderGeoJSONSource::startRender(algorithm::ClipIDGenerator& generator, const mat4& projMatrix, const mat4& clipMatrix, const TransformState& transform) {
generator.update(tilePyramid.getRenderTiles());
tilePyramid.startRender(projMatrix, clipMatrix, transform);
}
enabled = needsRendering;
void RenderGeoJSONSource::finishRender(Painter& painter) {
tilePyramid.finishRender(painter);
}
std::map<UnwrappedTileID, RenderTile>& RenderGeoJSONSource::getRenderTiles() {
return tilePyramid.getRenderTiles();
}
void RenderGeoJSONSource::updateTiles(const TileParameters& parameters) {
GeoJSONData* data_ = impl().getData();
if (!data_) {
@@ -55,21 +46,29 @@ void RenderGeoJSONSource::updateTiles(const TileParameters& parameters) {
}
}
tilePyramid.updateTiles(parameters,
SourceType::GeoJSON,
util::tileSize,
impl().getZoomRange(),
[&] (const OverscaledTileID& tileID) {
return std::make_unique<GeoJSONTile>(tileID, impl().id, parameters, data->getTile(tileID.canonical));
});
tilePyramid.update(layers,
needsRendering,
needsRelayout,
parameters,
SourceType::GeoJSON,
util::tileSize,
impl().getZoomRange(),
[&] (const OverscaledTileID& tileID) {
return std::make_unique<GeoJSONTile>(tileID, impl().id, parameters, data->getTile(tileID.canonical));
});
}
void RenderGeoJSONSource::removeTiles() {
tilePyramid.removeTiles();
void RenderGeoJSONSource::startRender(algorithm::ClipIDGenerator& generator, const mat4& projMatrix, const mat4& clipMatrix, const TransformState& transform) {
generator.update(tilePyramid.getRenderTiles());
tilePyramid.startRender(projMatrix, clipMatrix, transform);
}
void RenderGeoJSONSource::reloadTiles() {
tilePyramid.reloadTiles();
void RenderGeoJSONSource::finishRender(Painter& painter) {
tilePyramid.finishRender(painter);
}
std::map<UnwrappedTileID, RenderTile>& RenderGeoJSONSource::getRenderTiles() {
return tilePyramid.getRenderTiles();
}
std::unordered_map<std::string, std::vector<Feature>>

View File

@@ -16,19 +16,11 @@ public:
bool isLoaded() const final;
// Called when the camera has changed. May load new tiles, unload obsolete tiles, or
// trigger re-placement of existing complete tiles.
void updateTiles(const TileParameters&) final;
// Removes all tiles (by putting them into the cache).
void removeTiles() final;
// Remove all tiles and clear the cache.
void invalidateTiles() final;
// Request that all loaded tiles re-run the layout operation on the existing source
// data with fresh style information.
void reloadTiles() final;
void update(Immutable<style::Source::Impl>,
const std::vector<Immutable<style::Layer::Impl>>&,
bool needsRendering,
bool needsRelayout,
const TileParameters&) final;
void startRender(algorithm::ClipIDGenerator&,
const mat4& projMatrix,

View File

@@ -72,7 +72,14 @@ void RenderImageSource::upload(gl::Context& context) {
}
}
void RenderImageSource::updateTiles(const TileParameters& parameters) {
void RenderImageSource::update(Immutable<style::Source::Impl> baseImpl_,
const std::vector<Immutable<Layer::Impl>>&,
const bool needsRendering,
const bool,
const TileParameters& parameters) {
std::swap(baseImpl, baseImpl_);
enabled = needsRendering;
auto transformState = parameters.transformState;
auto size = transformState.getSize();

View File

@@ -30,13 +30,11 @@ public:
void finishRender(Painter&) final;
void updateTiles(const TileParameters&) final;
void removeTiles() final {
}
void invalidateTiles() final {
}
void reloadTiles() final {
}
void update(Immutable<style::Source::Impl>,
const std::vector<Immutable<style::Layer::Impl>>&,
bool needsRendering,
bool needsRelayout,
const TileParameters&) final;
std::map<UnwrappedTileID, RenderTile>& getRenderTiles() final {
return tiles;

View File

@@ -19,8 +19,41 @@ bool RenderRasterSource::isLoaded() const {
return tilePyramid.isLoaded();
}
void RenderRasterSource::invalidateTiles() {
tilePyramid.invalidateTiles();
void RenderRasterSource::update(Immutable<style::Source::Impl> baseImpl_,
const std::vector<Immutable<Layer::Impl>>& layers,
const bool needsRendering,
const bool needsRelayout,
const TileParameters& parameters) {
std::swap(baseImpl, baseImpl_);
enabled = needsRendering;
optional<Tileset> tileset = impl().getTileset();
if (!tileset) {
return;
}
if (tileURLTemplates != tileset->tiles) {
tileURLTemplates = tileset->tiles;
// TODO: this removes existing buckets, and will cause flickering.
// Should instead refresh tile data in place.
tilePyramid.tiles.clear();
tilePyramid.renderTiles.clear();
tilePyramid.cache.clear();
}
tilePyramid.update(layers,
needsRendering,
needsRelayout,
parameters,
SourceType::Raster,
impl().getTileSize(),
tileset->zoomRange,
[&] (const OverscaledTileID& tileID) {
return std::make_unique<RasterTile>(tileID, parameters, *tileset);
});
}
void RenderRasterSource::startRender(algorithm::ClipIDGenerator&, const mat4& projMatrix, const mat4& clipMatrix, const TransformState& transform) {
@@ -35,35 +68,6 @@ std::map<UnwrappedTileID, RenderTile>& RenderRasterSource::getRenderTiles() {
return tilePyramid.getRenderTiles();
}
void RenderRasterSource::updateTiles(const TileParameters& parameters) {
optional<Tileset> tileset = impl().getTileset();
if (!tileset) {
return;
}
if (tileURLTemplates != tileset->tiles) {
tileURLTemplates = tileset->tiles;
tilePyramid.invalidateTiles();
}
tilePyramid.updateTiles(parameters,
SourceType::Raster,
impl().getTileSize(),
tileset->zoomRange,
[&] (const OverscaledTileID& tileID) {
return std::make_unique<RasterTile>(tileID, parameters, *tileset);
});
}
void RenderRasterSource::removeTiles() {
tilePyramid.removeTiles();
}
void RenderRasterSource::reloadTiles() {
tilePyramid.reloadTiles();
}
std::unordered_map<std::string, std::vector<Feature>>
RenderRasterSource::queryRenderedFeatures(const ScreenLineString&,
const TransformState&,

View File

@@ -12,19 +12,11 @@ public:
bool isLoaded() const final;
// Called when the camera has changed. May load new tiles, unload obsolete tiles, or
// trigger re-placement of existing complete tiles.
void updateTiles(const TileParameters&) final;
// Removes all tiles (by putting them into the cache).
void removeTiles() final;
// Remove all tiles and clear the cache.
void invalidateTiles() final;
// Request that all loaded tiles re-run the layout operation on the existing source
// data with fresh style information.
void reloadTiles() final;
void update(Immutable<style::Source::Impl>,
const std::vector<Immutable<style::Layer::Impl>>&,
bool needsRendering,
bool needsRelayout,
const TileParameters&) final;
void startRender(algorithm::ClipIDGenerator&,
const mat4& projMatrix,

View File

@@ -22,8 +22,41 @@ bool RenderVectorSource::isLoaded() const {
return tilePyramid.isLoaded();
}
void RenderVectorSource::invalidateTiles() {
tilePyramid.invalidateTiles();
void RenderVectorSource::update(Immutable<style::Source::Impl> baseImpl_,
const std::vector<Immutable<Layer::Impl>>& layers,
const bool needsRendering,
const bool needsRelayout,
const TileParameters& parameters) {
std::swap(baseImpl, baseImpl_);
enabled = needsRendering;
optional<Tileset> tileset = impl().getTileset();
if (!tileset) {
return;
}
if (tileURLTemplates != tileset->tiles) {
tileURLTemplates = tileset->tiles;
// TODO: this removes existing buckets, and will cause flickering.
// Should instead refresh tile data in place.
tilePyramid.tiles.clear();
tilePyramid.renderTiles.clear();
tilePyramid.cache.clear();
}
tilePyramid.update(layers,
needsRendering,
needsRelayout,
parameters,
SourceType::Vector,
util::tileSize,
tileset->zoomRange,
[&] (const OverscaledTileID& tileID) {
return std::make_unique<VectorTile>(tileID, impl().id, parameters, *tileset);
});
}
void RenderVectorSource::startRender(algorithm::ClipIDGenerator& generator, const mat4& projMatrix, const mat4& clipMatrix, const TransformState& transform) {
@@ -39,35 +72,6 @@ std::map<UnwrappedTileID, RenderTile>& RenderVectorSource::getRenderTiles() {
return tilePyramid.getRenderTiles();
}
void RenderVectorSource::updateTiles(const TileParameters& parameters) {
optional<Tileset> tileset = impl().getTileset();
if (!tileset) {
return;
}
if (tileURLTemplates != tileset->tiles) {
tileURLTemplates = tileset->tiles;
tilePyramid.invalidateTiles();
}
tilePyramid.updateTiles(parameters,
SourceType::Vector,
util::tileSize,
tileset->zoomRange,
[&] (const OverscaledTileID& tileID) {
return std::make_unique<VectorTile>(tileID, impl().id, parameters, *tileset);
});
}
void RenderVectorSource::removeTiles() {
tilePyramid.removeTiles();
}
void RenderVectorSource::reloadTiles() {
tilePyramid.reloadTiles();
}
std::unordered_map<std::string, std::vector<Feature>>
RenderVectorSource::queryRenderedFeatures(const ScreenLineString& geometry,
const TransformState& transformState,

View File

@@ -12,19 +12,11 @@ public:
bool isLoaded() const final;
// Called when the camera has changed. May load new tiles, unload obsolete tiles, or
// trigger re-placement of existing complete tiles.
void updateTiles(const TileParameters&) final;
// Removes all tiles (by putting them into the cache).
void removeTiles() final;
// Remove all tiles and clear the cache.
void invalidateTiles() final;
// Request that all loaded tiles re-run the layout operation on the existing source
// data with fresh style information.
void reloadTiles() final;
void update(Immutable<style::Source::Impl>,
const std::vector<Immutable<style::Layer::Impl>>&,
bool needsRendering,
bool needsRelayout,
const TileParameters&) final;
void startRender(algorithm::ClipIDGenerator&,
const mat4& projMatrix,

View File

@@ -27,7 +27,7 @@ StyleDifference<T> diff(const std::vector<T>& a, const std::vector<T>& b, const
bIt++;
} else {
if (aIt->get() != bIt->get()) {
result.changed.emplace((*bIt)->id, *bIt);
result.changed.emplace((*bIt)->id, std::array<T, 2> {{ *aIt, *bIt }});
}
aIt++;
bIt++;
@@ -61,4 +61,13 @@ LayerDifference diffLayers(const std::vector<ImmutableLayer>& a,
});
}
bool hasLayoutDifference(const LayerDifference& layerDiff, const std::string& layerID) {
if (layerDiff.added.count(layerID))
return true;
const auto it = layerDiff.changed.find(layerID);
if (it == layerDiff.changed.end())
return false;
return it->second[0]->hasLayoutDifference(*it->second[1]);
}
} // namespace mbgl

View File

@@ -1,3 +1,5 @@
#pragma once
#include <mbgl/style/image_impl.hpp>
#include <mbgl/style/source_impl.hpp>
#include <mbgl/style/layer_impl.hpp>
@@ -13,7 +15,7 @@ class StyleDifference {
public:
std::unordered_map<std::string, T> added;
std::unordered_map<std::string, T> removed;
std::unordered_map<std::string, T> changed;
std::unordered_map<std::string, std::array<T, 2>> changed;
};
using ImmutableImage = Immutable<style::Image::Impl>;
@@ -34,4 +36,6 @@ using LayerDifference = StyleDifference<ImmutableLayer>;
LayerDifference diffLayers(const std::vector<ImmutableLayer>&,
const std::vector<ImmutableLayer>&);
bool hasLayoutDifference(const LayerDifference&, const std::string& layerID);
} // namespace mbgl

View File

@@ -8,30 +8,11 @@ class TransformState;
class Scheduler;
class FileSource;
class AnnotationManager;
namespace style {
class Style;
} // namespace style
class SpriteAtlas;
class GlyphAtlas;
class TileParameters {
public:
TileParameters(float pixelRatio_,
MapDebugOptions debugOptions_,
const TransformState& transformState_,
Scheduler& workerScheduler_,
FileSource& fileSource_,
const MapMode mode_,
AnnotationManager& annotationManager_,
style::Style& style_)
: pixelRatio(pixelRatio_),
debugOptions(debugOptions_),
transformState(transformState_),
workerScheduler(workerScheduler_),
fileSource(fileSource_),
mode(mode_),
annotationManager(annotationManager_),
style(style_) {}
float pixelRatio;
MapDebugOptions debugOptions;
const TransformState& transformState;
@@ -39,9 +20,8 @@ public:
FileSource& fileSource;
const MapMode mode;
AnnotationManager& annotationManager;
// TODO: remove
style::Style& style;
SpriteAtlas& spriteAtlas;
GlyphAtlas& glyphAtlas;
};
} // namespace mbgl

View File

@@ -39,12 +39,6 @@ bool TilePyramid::isLoaded() const {
return true;
}
void TilePyramid::invalidateTiles() {
tiles.clear();
renderTiles.clear();
cache.clear();
}
void TilePyramid::startRender(const mat4& projMatrix,
const mat4& clipMatrix,
const TransformState& transform) {
@@ -67,11 +61,34 @@ std::map<UnwrappedTileID, RenderTile>& TilePyramid::getRenderTiles() {
return renderTiles;
}
void TilePyramid::updateTiles(const TileParameters& parameters,
const SourceType type,
const uint16_t tileSize,
const Range<uint8_t> zoomRange,
std::function<std::unique_ptr<Tile> (const OverscaledTileID&)> createTile) {
void TilePyramid::update(const std::vector<Immutable<style::Layer::Impl>>& layers,
const bool needsRendering,
const bool needsRelayout,
const TileParameters& parameters,
const SourceType type,
const uint16_t tileSize,
const Range<uint8_t> zoomRange,
std::function<std::unique_ptr<Tile> (const OverscaledTileID&)> createTile) {
// If we need a relayout, abandon any cached tiles; they're now stale.
if (needsRelayout) {
cache.clear();
}
// If we're not going to render anything, move our existing tiles into
// the cache (if they're not stale) or abandon them, and return.
if (!needsRendering) {
if (!needsRelayout) {
for (auto& entry : tiles) {
cache.add(entry.first, std::move(entry.second));
}
}
tiles.clear();
renderTiles.clear();
return;
}
// Determine the overzooming/underzooming amounts and required tiles.
int32_t overscaledZoom = util::coveringZoomLevel(parameters.transformState.getZoom(), type, tileSize);
int32_t tileZoom = overscaledZoom;
@@ -97,6 +114,9 @@ void TilePyramid::updateTiles(const TileParameters& parameters,
auto retainTileFn = [&](Tile& tile, Resource::Necessity necessity) -> void {
retain.emplace(tile.id);
tile.setNecessity(necessity);
if (needsRelayout) {
tile.setLayers(layers);
}
};
auto getTileFn = [&](const OverscaledTileID& tileID) -> Tile* {
auto it = tiles.find(tileID);
@@ -108,6 +128,7 @@ void TilePyramid::updateTiles(const TileParameters& parameters,
tile = createTile(tileID);
if (tile) {
tile->setObserver(observer);
tile->setLayers(layers);
}
}
if (!tile) {
@@ -163,21 +184,6 @@ void TilePyramid::removeStaleTiles(const std::set<OverscaledTileID>& retain) {
}
}
void TilePyramid::removeTiles() {
renderTiles.clear();
if (!tiles.empty()) {
removeStaleTiles({});
}
}
void TilePyramid::reloadTiles() {
cache.clear();
for (auto& pair : tiles) {
pair.second->redoLayout();
}
}
std::unordered_map<std::string, std::vector<Feature>> TilePyramid::queryRenderedFeatures(const ScreenLineString& geometry,
const TransformState& transformState,
const style::Style& style,

View File

@@ -5,6 +5,7 @@
#include <mbgl/tile/tile.hpp>
#include <mbgl/tile/tile_cache.hpp>
#include <mbgl/style/types.hpp>
#include <mbgl/style/layer_impl.hpp>
#include <mbgl/util/mat4.hpp>
#include <mbgl/util/feature.hpp>
@@ -35,23 +36,14 @@ public:
bool isLoaded() const;
// Called when the camera has changed. May load new tiles, unload obsolete tiles, or
// trigger re-placement of existing complete tiles.
void updateTiles(const TileParameters&,
SourceType type,
uint16_t tileSize,
Range<uint8_t> zoomRange,
std::function<std::unique_ptr<Tile> (const OverscaledTileID&)> createTile);
// Removes all tiles (by putting them into the cache).
void removeTiles();
// Remove all tiles and clear the cache.
void invalidateTiles();
// Request that all loaded tiles re-run the layout operation on the existing source
// data with fresh style information.
void reloadTiles();
void update(const std::vector<Immutable<style::Layer::Impl>>&,
bool needsRendering,
bool needsRelayout,
const TileParameters&,
SourceType type,
uint16_t tileSize,
Range<uint8_t> zoomRange,
std::function<std::unique_ptr<Tile> (const OverscaledTileID&)> createTile);
void startRender(const mat4& projMatrix,
const mat4& clipMatrix,

View File

@@ -34,6 +34,10 @@ public:
Impl& operator=(const Impl&) = delete;
// Returns true buckets if properties affecting layout have changed: i.e. filter,
// visibility, layout properties, or data-driven paint properties.
virtual bool hasLayoutDifference(const Layer::Impl&) const = 0;
// Utility function for automatic layer grouping.
virtual void stringifyLayout(rapidjson::Writer<rapidjson::StringBuffer>&) const = 0;

View File

@@ -3,5 +3,9 @@
namespace mbgl {
namespace style {
bool BackgroundLayer::Impl::hasLayoutDifference(const Layer::Impl&) const {
return false;
}
} // namespace style
} // namespace mbgl

View File

@@ -11,6 +11,7 @@ class BackgroundLayer::Impl : public Layer::Impl {
public:
using Layer::Impl::Impl;
bool hasLayoutDifference(const Layer::Impl&) const override;
void stringifyLayout(rapidjson::Writer<rapidjson::StringBuffer>&) const override;
BackgroundPaintProperties::Transitionable paint;

View File

@@ -3,5 +3,13 @@
namespace mbgl {
namespace style {
bool CircleLayer::Impl::hasLayoutDifference(const Layer::Impl& other) const {
assert(dynamic_cast<const CircleLayer::Impl*>(&other));
const auto& impl = static_cast<const style::CircleLayer::Impl&>(other);
return filter != impl.filter ||
visibility != impl.visibility ||
paint.hasDataDrivenPropertyDifference(impl.paint);
}
} // namespace style
} // namespace mbgl

View File

@@ -11,6 +11,7 @@ class CircleLayer::Impl : public Layer::Impl {
public:
using Layer::Impl::Impl;
bool hasLayoutDifference(const Layer::Impl&) const override;
void stringifyLayout(rapidjson::Writer<rapidjson::StringBuffer>&) const override;
CirclePaintProperties::Transitionable paint;

View File

@@ -16,6 +16,10 @@ CustomLayer::Impl::Impl(const std::string& id_,
context = context_;
}
bool CustomLayer::Impl::hasLayoutDifference(const Layer::Impl&) const {
return false;
}
void CustomLayer::Impl::stringifyLayout(rapidjson::Writer<rapidjson::StringBuffer>&) const {
}

View File

@@ -22,6 +22,7 @@ public:
void render(const TransformState&) const;
private:
bool hasLayoutDifference(const Layer::Impl&) const override;
void stringifyLayout(rapidjson::Writer<rapidjson::StringBuffer>&) const override;
CustomLayerInitializeFunction initializeFn = nullptr;

View File

@@ -3,5 +3,13 @@
namespace mbgl {
namespace style {
bool FillExtrusionLayer::Impl::hasLayoutDifference(const Layer::Impl& other) const {
assert(dynamic_cast<const FillExtrusionLayer::Impl*>(&other));
const auto& impl = static_cast<const style::FillExtrusionLayer::Impl&>(other);
return filter != impl.filter ||
visibility != impl.visibility ||
paint.hasDataDrivenPropertyDifference(impl.paint);
}
} // namespace style
} // namespace mbgl

View File

@@ -11,6 +11,7 @@ class FillExtrusionLayer::Impl : public Layer::Impl {
public:
using Layer::Impl::Impl;
bool hasLayoutDifference(const Layer::Impl&) const override;
void stringifyLayout(rapidjson::Writer<rapidjson::StringBuffer>&) const override;
FillExtrusionPaintProperties::Transitionable paint;

View File

@@ -3,5 +3,13 @@
namespace mbgl {
namespace style {
bool FillLayer::Impl::hasLayoutDifference(const Layer::Impl& other) const {
assert(dynamic_cast<const FillLayer::Impl*>(&other));
const auto& impl = static_cast<const style::FillLayer::Impl&>(other);
return filter != impl.filter ||
visibility != impl.visibility ||
paint.hasDataDrivenPropertyDifference(impl.paint);
}
} // namespace style
} // namespace mbgl

View File

@@ -11,6 +11,7 @@ class FillLayer::Impl : public Layer::Impl {
public:
using Layer::Impl::Impl;
bool hasLayoutDifference(const Layer::Impl&) const override;
void stringifyLayout(rapidjson::Writer<rapidjson::StringBuffer>&) const override;
FillPaintProperties::Transitionable paint;

View File

@@ -3,5 +3,14 @@
namespace mbgl {
namespace style {
bool LineLayer::Impl::hasLayoutDifference(const Layer::Impl& other) const {
assert(dynamic_cast<const LineLayer::Impl*>(&other));
const auto& impl = static_cast<const style::LineLayer::Impl&>(other);
return filter != impl.filter ||
visibility != impl.visibility ||
layout != impl.layout ||
paint.hasDataDrivenPropertyDifference(impl.paint);
}
} // namespace style
} // namespace mbgl

View File

@@ -11,6 +11,7 @@ class LineLayer::Impl : public Layer::Impl {
public:
using Layer::Impl::Impl;
bool hasLayoutDifference(const Layer::Impl&) const override;
void stringifyLayout(rapidjson::Writer<rapidjson::StringBuffer>&) const override;
LineLayoutProperties::Unevaluated layout;

View File

@@ -3,5 +3,9 @@
namespace mbgl {
namespace style {
bool RasterLayer::Impl::hasLayoutDifference(const Layer::Impl&) const {
return false;
}
} // namespace style
} // namespace mbgl

View File

@@ -11,6 +11,7 @@ class RasterLayer::Impl : public Layer::Impl {
public:
using Layer::Impl::Impl;
bool hasLayoutDifference(const Layer::Impl&) const override;
void stringifyLayout(rapidjson::Writer<rapidjson::StringBuffer>&) const override;
RasterPaintProperties::Transitionable paint;

View File

@@ -3,5 +3,14 @@
namespace mbgl {
namespace style {
bool SymbolLayer::Impl::hasLayoutDifference(const Layer::Impl& other) const {
assert(dynamic_cast<const SymbolLayer::Impl*>(&other));
const auto& impl = static_cast<const style::SymbolLayer::Impl&>(other);
return filter != impl.filter ||
visibility != impl.visibility ||
layout != impl.layout ||
paint.hasDataDrivenPropertyDifference(impl.paint);
}
} // namespace style
} // namespace mbgl

View File

@@ -11,6 +11,7 @@ class SymbolLayer::Impl : public Layer::Impl {
public:
using Layer::Impl::Impl;
bool hasLayoutDifference(const Layer::Impl&) const override;
void stringifyLayout(rapidjson::Writer<rapidjson::StringBuffer>&) const override;
SymbolLayoutProperties::Unevaluated layout;

View File

@@ -205,6 +205,12 @@ public:
.transition(parameters, std::move(prior.template get<Ps>()))...
};
}
bool hasDataDrivenPropertyDifference(const Transitionable& other) const {
bool result = false;
util::ignore({ (result |= this->template get<Ps>().value.hasDataDrivenPropertyDifference(other.template get<Ps>().value))... });
return result;
}
};
};

View File

@@ -54,21 +54,6 @@ namespace style {
static Observer nullObserver;
struct QueueSourceReloadVisitor {
UpdateBatch& updateBatch;
// No need to reload sources for these types; their visibility can change but
// they don't participate in layout.
void operator()(CustomLayer&) {}
void operator()(RasterLayer&) {}
void operator()(BackgroundLayer&) {}
template <class VectorLayer>
void operator()(VectorLayer& layer) {
updateBatch.sourceIDs.insert(layer.getSourceID());
}
};
Style::Style(Scheduler& scheduler_, FileSource& fileSource_, float pixelRatio)
: scheduler(scheduler_),
fileSource(fileSource_),
@@ -105,7 +90,6 @@ void Style::setJSON(const std::string& json) {
renderSources.clear();
layers.clear();
transitionOptions = {};
updateBatch = {};
Parser parser;
auto error = parser.parse(json);
@@ -193,7 +177,6 @@ std::unique_ptr<Source> Style::removeSource(const std::string& id) {
auto source = std::move(*it);
source->setObserver(nullptr);
sources.erase(it);
updateBatch.sourceIDs.erase(id);
return source;
}
@@ -244,7 +227,6 @@ Layer* Style::addLayer(std::unique_ptr<Layer> layer, optional<std::string> befor
}
layer->setObserver(this);
layer->accept(QueueSourceReloadVisitor { updateBatch });
return layers.emplace(before ? findLayer(*before) : layers.end(), std::move(layer))->get();
}
@@ -339,14 +321,17 @@ void Style::update(const UpdateParameters& parameters) {
parameters.mode == MapMode::Continuous ? util::DEFAULT_FADE_DURATION : Duration::zero()
};
const TileParameters tileParameters(parameters.pixelRatio,
parameters.debugOptions,
parameters.transformState,
parameters.scheduler,
parameters.fileSource,
parameters.mode,
parameters.annotationManager,
*this);
const TileParameters tileParameters {
parameters.pixelRatio,
parameters.debugOptions,
parameters.transformState,
parameters.scheduler,
parameters.fileSource,
parameters.mode,
parameters.annotationManager,
*spriteAtlas,
*glyphAtlas
};
// Update light.
const bool lightChanged = renderLight.impl != light->impl;
@@ -382,7 +367,7 @@ void Style::update(const UpdateParameters& parameters) {
// Update changed images.
for (const auto& entry : imageDiff.changed) {
spriteAtlas->updateImage(entry.second);
spriteAtlas->updateImage(entry.second[1]);
}
if (spriteLoaded && !spriteAtlas->isLoaded()) {
@@ -396,26 +381,6 @@ void Style::update(const UpdateParameters& parameters) {
newSourceImpls.push_back(source->baseImpl);
}
const SourceDifference sourceDiff = diffSources(sourceImpls, newSourceImpls);
sourceImpls = std::move(newSourceImpls);
// Remove render layers for removed sources.
for (const auto& entry : sourceDiff.removed) {
renderLayers.erase(entry.first);
}
// Create render sources for newly added sources.
for (const auto& entry : sourceDiff.added) {
std::unique_ptr<RenderSource> renderSource = RenderSource::create(entry.second);
renderSource->setObserver(this);
renderSources.emplace(entry.first, std::move(renderSource));
}
// Update render sources for changed sources.
for (const auto& entry : sourceDiff.changed) {
renderSources.at(entry.first)->setImpl(entry.second);
}
std::vector<Immutable<Layer::Impl>> newLayerImpls;
newLayerImpls.reserve(layers.size());
@@ -438,7 +403,7 @@ void Style::update(const UpdateParameters& parameters) {
// Update render layers for changed layers.
for (const auto& entry : layerDiff.changed) {
renderLayers.at(entry.first)->setImpl(entry.second);
renderLayers.at(entry.first)->setImpl(entry.second[1]);
}
// Update layers for class and zoom changes.
@@ -457,35 +422,51 @@ void Style::update(const UpdateParameters& parameters) {
}
// Update tiles for each source.
for (const auto& entry : renderSources) {
entry.second->enabled = false;
const SourceDifference sourceDiff = diffSources(sourceImpls, newSourceImpls);
sourceImpls = std::move(newSourceImpls);
// Remove render layers for removed sources.
for (const auto& entry : sourceDiff.removed) {
renderSources.erase(entry.first);
}
for (const auto& entry : renderLayers) {
RenderLayer& layer = *entry.second;
if (layer.needsRendering(zoomHistory.lastZoom)) {
if (RenderSource* source = getRenderSource(layer.baseImpl->source)) {
source->enabled = true;
// Create render sources for newly added sources.
for (const auto& entry : sourceDiff.added) {
std::unique_ptr<RenderSource> renderSource = RenderSource::create(entry.second);
renderSource->setObserver(this);
renderSources.emplace(entry.first, std::move(renderSource));
}
// Update all sources.
for (const auto& source : sourceImpls) {
std::vector<Immutable<Layer::Impl>> filteredLayers;
bool needsRendering = false;
bool needsRelayout = false;
for (const auto& layer : layerImpls) {
if (layer->type == LayerType::Background ||
layer->type == LayerType::Custom ||
layer->source != source->id) {
continue;
}
}
}
for (const auto& entry : renderSources) {
bool updated = updateBatch.sourceIDs.count(entry.first);
if (entry.second->enabled) {
if (updated) {
entry.second->reloadTiles();
if (getRenderLayer(layer->id)->needsRendering(zoomHistory.lastZoom)) {
needsRendering = true;
}
entry.second->updateTiles(tileParameters);
} else if (updated) {
entry.second->invalidateTiles();
} else {
entry.second->removeTiles();
}
}
updateBatch.sourceIDs.clear();
if (hasLayoutDifference(layerDiff, layer->id)) {
needsRelayout = true;
}
filteredLayers.push_back(layer);
}
renderSources.at(source->id)->update(source,
filteredLayers,
needsRendering,
needsRelayout,
tileParameters);
}
}
std::vector<const Source*> Style::getSources() const {
@@ -580,7 +561,7 @@ RenderData Style::getRenderData(MapDebugOptions debugOptions, float angle) const
RenderData result;
for (const auto& entry : renderSources) {
if (entry.second->enabled) {
if (entry.second->isEnabled()) {
result.sources.insert(entry.second.get());
}
}
@@ -801,13 +782,11 @@ void Style::onSpriteError(std::exception_ptr error) {
observer->onResourceError(error);
}
void Style::onLayerFilterChanged(Layer& layer) {
layer.accept(QueueSourceReloadVisitor { updateBatch });
void Style::onLayerFilterChanged(Layer&) {
observer->onUpdate(Update::Repaint);
}
void Style::onLayerVisibilityChanged(Layer& layer) {
layer.accept(QueueSourceReloadVisitor { updateBatch });
void Style::onLayerVisibilityChanged(Layer&) {
observer->onUpdate(Update::Repaint);
}
@@ -815,13 +794,11 @@ void Style::onLayerPaintPropertyChanged(Layer&) {
observer->onUpdate(Update::Repaint);
}
void Style::onLayerDataDrivenPaintPropertyChanged(Layer& layer) {
layer.accept(QueueSourceReloadVisitor { updateBatch });
void Style::onLayerDataDrivenPaintPropertyChanged(Layer&) {
observer->onUpdate(Update::Repaint);
}
void Style::onLayerLayoutPropertyChanged(Layer& layer, const char *) {
layer.accept(QueueSourceReloadVisitor { updateBatch });
void Style::onLayerLayoutPropertyChanged(Layer&, const char *) {
observer->onUpdate(Update::Repaint);
}

View File

@@ -5,7 +5,6 @@
#include <mbgl/style/source_observer.hpp>
#include <mbgl/style/layer_observer.hpp>
#include <mbgl/style/light_observer.hpp>
#include <mbgl/style/update_batch.hpp>
#include <mbgl/style/image.hpp>
#include <mbgl/renderer/render_source.hpp>
#include <mbgl/renderer/render_source_observer.hpp>
@@ -179,7 +178,6 @@ private:
std::exception_ptr lastError;
UpdateBatch updateBatch;
ZoomHistory zoomHistory;
bool spriteLoaded = false;

View File

@@ -1,15 +0,0 @@
#pragma once
#include <unordered_set>
#include <string>
namespace mbgl {
namespace style {
class UpdateBatch {
public:
std::unordered_set<std::string> sourceIDs;
};
} // namespace style
} // namespace mbgl

View File

@@ -1,7 +1,6 @@
#include <mbgl/tile/geojson_tile.hpp>
#include <mbgl/tile/geometry_tile_data.hpp>
#include <mbgl/map/query.hpp>
#include <mbgl/style/style.hpp>
#include <mbgl/renderer/tile_parameters.hpp>
#include <mapbox/geojsonvt.hpp>
@@ -86,9 +85,7 @@ GeoJSONTile::GeoJSONTile(const OverscaledTileID& overscaledTileID,
std::string sourceID_,
const TileParameters& parameters,
mapbox::geometry::feature_collection<int16_t> features)
: GeometryTile(overscaledTileID, sourceID_, parameters,
*parameters.style.glyphAtlas,
*parameters.style.spriteAtlas) {
: GeometryTile(overscaledTileID, sourceID_, parameters) {
updateData(std::move(features));
}

View File

@@ -10,7 +10,6 @@
#include <mbgl/renderer/layers/render_custom_layer.hpp>
#include <mbgl/renderer/layers/render_symbol_layer.hpp>
#include <mbgl/renderer/buckets/symbol_bucket.hpp>
#include <mbgl/style/style.hpp>
#include <mbgl/storage/file_source.hpp>
#include <mbgl/geometry/feature_index.hpp>
#include <mbgl/text/collision_tile.hpp>
@@ -29,12 +28,9 @@ using namespace style;
GeometryTile::GeometryTile(const OverscaledTileID& id_,
std::string sourceID_,
const TileParameters& parameters,
GlyphAtlas& glyphAtlas_,
SpriteAtlas& spriteAtlas_)
const TileParameters& parameters)
: Tile(id_),
sourceID(std::move(sourceID_)),
style(parameters.style),
mailbox(std::make_shared<Mailbox>(*util::RunLoop::Get())),
worker(parameters.workerScheduler,
ActorRef<GeometryTile>(*this, mailbox),
@@ -42,8 +38,8 @@ GeometryTile::GeometryTile(const OverscaledTileID& id_,
obsolete,
parameters.mode,
parameters.pixelRatio),
glyphAtlas(glyphAtlas_),
spriteAtlas(spriteAtlas_),
glyphAtlas(parameters.glyphAtlas),
spriteAtlas(parameters.spriteAtlas),
placementThrottler(Milliseconds(300), [this] { invokePlacement(); }) {
}
@@ -74,7 +70,6 @@ void GeometryTile::setData(std::unique_ptr<const GeometryTileData> data_) {
++correlationID;
worker.invoke(&GeometryTileWorker::setData, std::move(data_), correlationID);
redoLayout();
}
void GeometryTile::setPlacementConfig(const PlacementConfig& desiredConfig) {
@@ -97,25 +92,25 @@ void GeometryTile::invokePlacement() {
}
}
void GeometryTile::redoLayout() {
void GeometryTile::setLayers(const std::vector<Immutable<Layer::Impl>>& layers) {
// Mark the tile as pending again if it was complete before to prevent signaling a complete
// state despite pending parse operations.
pending = true;
std::vector<Immutable<Layer::Impl>> impls;
for (const Layer* layer : style.getLayers()) {
for (const auto& layer : layers) {
// Skip irrelevant layers.
if (layer->is<BackgroundLayer>() ||
layer->is<CustomLayer>() ||
layer->baseImpl->source != sourceID ||
id.overscaledZ < std::floor(layer->baseImpl->minZoom) ||
id.overscaledZ >= std::ceil(layer->baseImpl->maxZoom) ||
layer->baseImpl->visibility == VisibilityType::None) {
if (layer->type == LayerType::Background ||
layer->type == LayerType::Custom ||
layer->source != sourceID ||
id.overscaledZ < std::floor(layer->minZoom) ||
id.overscaledZ >= std::ceil(layer->maxZoom) ||
layer->visibility == VisibilityType::None) {
continue;
}
impls.push_back(layer->baseImpl);
impls.push_back(layer);
}
++correlationID;
@@ -181,7 +176,7 @@ void GeometryTile::queryRenderedFeatures(
std::unordered_map<std::string, std::vector<Feature>>& result,
const GeometryCoordinates& queryGeometry,
const TransformState& transformState,
const style::Style& style_,
const style::Style& style,
const RenderedQueryOptions& options) {
if (!featureIndex || !data) return;
@@ -194,7 +189,7 @@ void GeometryTile::queryRenderedFeatures(
options,
*data,
id.canonical,
style_,
style,
collisionTile.get(),
*this);
}

View File

@@ -23,17 +23,11 @@ class RenderLayer;
class SourceQueryOptions;
class TileParameters;
namespace style {
class Style;
} // namespace style
class GeometryTile : public Tile, public GlyphRequestor, IconRequestor {
public:
GeometryTile(const OverscaledTileID&,
std::string sourceID,
const TileParameters&,
GlyphAtlas&,
SpriteAtlas&);
const TileParameters&);
~GeometryTile() override;
@@ -41,7 +35,7 @@ public:
void setData(std::unique_ptr<const GeometryTileData>);
void setPlacementConfig(const PlacementConfig&) override;
void redoLayout() override;
void setLayers(const std::vector<Immutable<style::Layer::Impl>>&) override;
void onGlyphsAvailable(GlyphPositionMap) override;
void onIconsAvailable(IconMap) override;
@@ -94,9 +88,6 @@ private:
const std::string sourceID;
// TODO: remove
style::Style& style;
// Used to signal the worker that it should abandon parsing this tile as soon as possible.
std::atomic<bool> obsolete { false };

View File

@@ -51,7 +51,7 @@ public:
virtual Bucket* getBucket(const style::Layer::Impl&) const = 0;
virtual void setPlacementConfig(const PlacementConfig&) {}
virtual void redoLayout() {}
virtual void setLayers(const std::vector<Immutable<style::Layer::Impl>>&) {}
virtual void queryRenderedFeatures(
std::unordered_map<std::string, std::vector<Feature>>& result,

View File

@@ -1,7 +1,6 @@
#include <mbgl/tile/vector_tile.hpp>
#include <mbgl/tile/tile_loader_impl.hpp>
#include <mbgl/tile/geometry_tile_data.hpp>
#include <mbgl/style/style.hpp>
#include <mbgl/renderer/tile_parameters.hpp>
#include <protozero/pbf_reader.hpp>
@@ -85,9 +84,7 @@ VectorTile::VectorTile(const OverscaledTileID& id_,
std::string sourceID_,
const TileParameters& parameters,
const Tileset& tileset)
: GeometryTile(id_, sourceID_, parameters,
*parameters.style.glyphAtlas,
*parameters.style.spriteAtlas),
: GeometryTile(id_, sourceID_, parameters),
loader(*this, id_, parameters, tileset) {
}

View File

@@ -8,6 +8,8 @@
#include <mbgl/style/sources/vector_source.hpp>
#include <mbgl/style/sources/geojson_source.hpp>
#include <mbgl/style/sources/image_source.hpp>
#include <mbgl/style/layers/raster_layer.cpp>
#include <mbgl/style/layers/line_layer.hpp>
#include <mbgl/renderer/sources/render_raster_source.hpp>
#include <mbgl/renderer/sources/render_vector_source.hpp>
@@ -27,12 +29,10 @@
#include <mbgl/util/range.hpp>
#include <mbgl/map/transform.hpp>
#include <mbgl/style/style.hpp>
#include <mbgl/style/layers/line_layer.hpp>
#include <mbgl/annotation/annotation_manager.hpp>
#include <mbgl/annotation/annotation_source.hpp>
#include <mapbox/geojsonvt.hpp>
#include <mbgl/sprite/sprite_atlas.hpp>
#include <mbgl/text/glyph_atlas.hpp>
#include <cstdint>
@@ -48,7 +48,8 @@ public:
TransformState transformState;
ThreadPool threadPool { 1 };
AnnotationManager annotationManager;
style::Style style { threadPool, fileSource, 1.0 };
SpriteAtlas spriteAtlas;
GlyphAtlas glyphAtlas { { 512, 512, }, fileSource };
TileParameters tileParameters {
1.0,
@@ -58,7 +59,8 @@ public:
fileSource,
MapMode::Continuous,
annotationManager,
style
spriteAtlas,
glyphAtlas
};
SourceTest() {
@@ -137,6 +139,9 @@ TEST(Source, RasterTileEmpty) {
return response;
};
RasterLayer layer("id", "source");
std::vector<Immutable<Layer::Impl>> layers {{ layer.baseImpl }};
Tileset tileset;
tileset.tiles = { "tiles" };
@@ -154,7 +159,11 @@ TEST(Source, RasterTileEmpty) {
auto renderSource = RenderSource::create(source.baseImpl);
renderSource->setObserver(&test.renderSourceObserver);
renderSource->updateTiles(test.tileParameters);
renderSource->update(source.baseImpl,
layers,
true,
true,
test.tileParameters);
test.run();
}
@@ -168,6 +177,11 @@ TEST(Source, VectorTileEmpty) {
return response;
};
LineLayer layer("id", "source");
layer.setSourceLayer("water");
std::vector<Immutable<Layer::Impl>> layers {{ layer.baseImpl }};
Tileset tileset;
tileset.tiles = { "tiles" };
@@ -185,7 +199,11 @@ TEST(Source, VectorTileEmpty) {
auto renderSource = RenderSource::create(source.baseImpl);
renderSource->setObserver(&test.renderSourceObserver);
renderSource->updateTiles(test.tileParameters);
renderSource->update(source.baseImpl,
layers,
true,
true,
test.tileParameters);
test.run();
}
@@ -201,6 +219,9 @@ TEST(Source, RasterTileFail) {
return response;
};
RasterLayer layer("id", "source");
std::vector<Immutable<Layer::Impl>> layers {{ layer.baseImpl }};
Tileset tileset;
tileset.tiles = { "tiles" };
@@ -216,7 +237,11 @@ TEST(Source, RasterTileFail) {
auto renderSource = RenderSource::create(source.baseImpl);
renderSource->setObserver(&test.renderSourceObserver);
renderSource->updateTiles(test.tileParameters);
renderSource->update(source.baseImpl,
layers,
true,
true,
test.tileParameters);
test.run();
}
@@ -232,6 +257,11 @@ TEST(Source, VectorTileFail) {
return response;
};
LineLayer layer("id", "source");
layer.setSourceLayer("water");
std::vector<Immutable<Layer::Impl>> layers {{ layer.baseImpl }};
Tileset tileset;
tileset.tiles = { "tiles" };
@@ -247,7 +277,11 @@ TEST(Source, VectorTileFail) {
auto renderSource = RenderSource::create(source.baseImpl);
renderSource->setObserver(&test.renderSourceObserver);
renderSource->updateTiles(test.tileParameters);
renderSource->update(source.baseImpl,
layers,
true,
true,
test.tileParameters);
test.run();
}
@@ -261,6 +295,9 @@ TEST(Source, RasterTileCorrupt) {
return response;
};
RasterLayer layer("id", "source");
std::vector<Immutable<Layer::Impl>> layers {{ layer.baseImpl }};
Tileset tileset;
tileset.tiles = { "tiles" };
@@ -277,7 +314,11 @@ TEST(Source, RasterTileCorrupt) {
auto renderSource = RenderSource::create(source.baseImpl);
renderSource->setObserver(&test.renderSourceObserver);
renderSource->updateTiles(test.tileParameters);
renderSource->update(source.baseImpl,
layers,
true,
true,
test.tileParameters);
test.run();
}
@@ -291,10 +332,10 @@ TEST(Source, VectorTileCorrupt) {
return response;
};
// Need to have at least one layer that uses the source.
auto layer = std::make_unique<LineLayer>("id", "source");
layer->setSourceLayer("water");
test.style.addLayer(std::move(layer));
LineLayer layer("id", "source");
layer.setSourceLayer("water");
std::vector<Immutable<Layer::Impl>> layers {{ layer.baseImpl }};
Tileset tileset;
tileset.tiles = { "tiles" };
@@ -311,7 +352,11 @@ TEST(Source, VectorTileCorrupt) {
auto renderSource = RenderSource::create(source.baseImpl);
renderSource->setObserver(&test.renderSourceObserver);
renderSource->updateTiles(test.tileParameters);
renderSource->update(source.baseImpl,
layers,
true,
true,
test.tileParameters);
test.run();
}
@@ -324,6 +369,9 @@ TEST(Source, RasterTileCancel) {
return optional<Response>();
};
RasterLayer layer("id", "source");
std::vector<Immutable<Layer::Impl>> layers {{ layer.baseImpl }};
Tileset tileset;
tileset.tiles = { "tiles" };
@@ -340,7 +388,11 @@ TEST(Source, RasterTileCancel) {
auto renderSource = RenderSource::create(source.baseImpl);
renderSource->setObserver(&test.renderSourceObserver);
renderSource->updateTiles(test.tileParameters);
renderSource->update(source.baseImpl,
layers,
true,
true,
test.tileParameters);
test.run();
}
@@ -353,6 +405,11 @@ TEST(Source, VectorTileCancel) {
return optional<Response>();
};
LineLayer layer("id", "source");
layer.setSourceLayer("water");
std::vector<Immutable<Layer::Impl>> layers {{ layer.baseImpl }};
Tileset tileset;
tileset.tiles = { "tiles" };
@@ -369,7 +426,11 @@ TEST(Source, VectorTileCancel) {
auto renderSource = RenderSource::create(source.baseImpl);
renderSource->setObserver(&test.renderSourceObserver);
renderSource->updateTiles(test.tileParameters);
renderSource->update(source.baseImpl,
layers,
true,
true,
test.tileParameters);
test.run();
}
@@ -377,6 +438,9 @@ TEST(Source, VectorTileCancel) {
TEST(Source, RasterTileAttribution) {
SourceTest test;
RasterLayer layer("id", "source");
std::vector<Immutable<Layer::Impl>> layers {{ layer.baseImpl }};
std::string mapboxOSM = ("<a href='https://www.mapbox.com/about/maps/' target='_blank'>&copy; Mapbox</a> "
"<a href='http://www.openstreetmap.org/about/' target='_blank'>©️ OpenStreetMap</a>");
@@ -406,7 +470,11 @@ TEST(Source, RasterTileAttribution) {
source.loadDescription(test.fileSource);
auto renderSource = RenderSource::create(source.baseImpl);
renderSource->updateTiles(test.tileParameters);
renderSource->update(source.baseImpl,
layers,
true,
true,
test.tileParameters);
test.run();
}

View File

@@ -12,6 +12,8 @@
#include <mbgl/geometry/feature_index.hpp>
#include <mbgl/annotation/annotation_manager.hpp>
#include <mbgl/annotation/annotation_tile.hpp>
#include <mbgl/sprite/sprite_atlas.hpp>
#include <mbgl/text/glyph_atlas.hpp>
#include <memory>
@@ -25,6 +27,8 @@ public:
ThreadPool threadPool { 1 };
AnnotationManager annotationManager;
style::Style style { threadPool, fileSource, 1.0 };
SpriteAtlas spriteAtlas;
GlyphAtlas glyphAtlas { { 512, 512, }, fileSource };
TileParameters tileParameters {
1.0,
@@ -34,7 +38,8 @@ public:
fileSource,
MapMode::Continuous,
annotationManager,
style
spriteAtlas,
glyphAtlas
};
};

View File

@@ -7,10 +7,11 @@
#include <mbgl/util/default_thread_pool.hpp>
#include <mbgl/util/run_loop.hpp>
#include <mbgl/map/transform.hpp>
#include <mbgl/style/style.hpp>
#include <mbgl/renderer/tile_parameters.hpp>
#include <mbgl/style/layers/circle_layer.hpp>
#include <mbgl/annotation/annotation_manager.hpp>
#include <mbgl/sprite/sprite_atlas.hpp>
#include <mbgl/text/glyph_atlas.hpp>
#include <memory>
@@ -24,7 +25,8 @@ public:
util::RunLoop loop;
ThreadPool threadPool { 1 };
AnnotationManager annotationManager;
style::Style style { threadPool, fileSource, 1.0 };
SpriteAtlas spriteAtlas;
GlyphAtlas glyphAtlas { { 512, 512, }, fileSource };
Tileset tileset { { "https://example.com" }, { 0, 22 }, "none" };
TileParameters tileParameters {
@@ -35,14 +37,15 @@ public:
fileSource,
MapMode::Continuous,
annotationManager,
style
spriteAtlas,
glyphAtlas
};
};
TEST(GeoJSONTile, Issue7648) {
GeoJSONTileTest test;
test.style.addLayer(std::make_unique<CircleLayer>("circle", "source"));
CircleLayer layer("circle", "source");
mapbox::geometry::feature_collection<int16_t> features;
features.push_back(mapbox::geometry::feature<int16_t> {
@@ -55,9 +58,10 @@ TEST(GeoJSONTile, Issue7648) {
observer.tileChanged = [&] (const Tile&) {
// Once present, the bucket should never "disappear", which would cause
// flickering.
ASSERT_NE(nullptr, tile.getBucket(*test.style.getLayer("circle")->baseImpl));
ASSERT_NE(nullptr, tile.getBucket(*layer.baseImpl));
};
tile.setLayers({{ layer.baseImpl }});
tile.setObserver(&observer);
tile.setPlacementConfig({});

View File

@@ -6,10 +6,11 @@
#include <mbgl/util/default_thread_pool.hpp>
#include <mbgl/util/run_loop.hpp>
#include <mbgl/map/transform.hpp>
#include <mbgl/style/style.hpp>
#include <mbgl/annotation/annotation_manager.hpp>
#include <mbgl/renderer/tile_parameters.hpp>
#include <mbgl/renderer/buckets/raster_bucket.hpp>
#include <mbgl/sprite/sprite_atlas.hpp>
#include <mbgl/text/glyph_atlas.hpp>
using namespace mbgl;
@@ -20,7 +21,8 @@ public:
util::RunLoop loop;
ThreadPool threadPool { 1 };
AnnotationManager annotationManager;
style::Style style { threadPool, fileSource, 1.0 };
SpriteAtlas spriteAtlas;
GlyphAtlas glyphAtlas { { 512, 512, }, fileSource };
Tileset tileset { { "https://example.com" }, { 0, 22 }, "none" };
TileParameters tileParameters {
@@ -31,7 +33,8 @@ public:
fileSource,
MapMode::Continuous,
annotationManager,
style
spriteAtlas,
glyphAtlas
};
};

View File

@@ -7,13 +7,14 @@
#include <mbgl/util/run_loop.hpp>
#include <mbgl/map/transform.hpp>
#include <mbgl/map/query.hpp>
#include <mbgl/style/style.hpp>
#include <mbgl/style/layers/symbol_layer.hpp>
#include <mbgl/renderer/tile_parameters.hpp>
#include <mbgl/renderer/buckets/symbol_bucket.hpp>
#include <mbgl/text/collision_tile.hpp>
#include <mbgl/geometry/feature_index.hpp>
#include <mbgl/annotation/annotation_manager.hpp>
#include <mbgl/sprite/sprite_atlas.hpp>
#include <mbgl/text/glyph_atlas.hpp>
#include <memory>
@@ -26,7 +27,8 @@ public:
util::RunLoop loop;
ThreadPool threadPool { 1 };
AnnotationManager annotationManager;
style::Style style { threadPool, fileSource, 1.0 };
SpriteAtlas spriteAtlas;
GlyphAtlas glyphAtlas { { 512, 512, }, fileSource };
Tileset tileset { { "https://example.com" }, { 0, 22 }, "none" };
TileParameters tileParameters {
@@ -37,7 +39,8 @@ public:
fileSource,
MapMode::Continuous,
annotationManager,
style
spriteAtlas,
glyphAtlas
};
};