summaryrefslogtreecommitdiff
path: root/src/mbgl/style/style.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mbgl/style/style.cpp')
-rw-r--r--src/mbgl/style/style.cpp483
1 files changed, 29 insertions, 454 deletions
diff --git a/src/mbgl/style/style.cpp b/src/mbgl/style/style.cpp
index 98d774f974..34e1cdeb6f 100644
--- a/src/mbgl/style/style.cpp
+++ b/src/mbgl/style/style.cpp
@@ -15,39 +15,10 @@
#include <mbgl/style/layer_impl.hpp>
#include <mbgl/style/parser.hpp>
#include <mbgl/style/transition_options.hpp>
-#include <mbgl/sprite/sprite_atlas.hpp>
#include <mbgl/sprite/sprite_loader.hpp>
-#include <mbgl/text/glyph_atlas.hpp>
-#include <mbgl/geometry/line_atlas.hpp>
-#include <mbgl/renderer/update_parameters.hpp>
-#include <mbgl/renderer/transition_parameters.hpp>
-#include <mbgl/renderer/property_evaluation_parameters.hpp>
-#include <mbgl/renderer/tile_parameters.hpp>
-#include <mbgl/renderer/render_source.hpp>
-#include <mbgl/renderer/render_item.hpp>
-#include <mbgl/renderer/render_tile.hpp>
-#include <mbgl/renderer/layers/render_background_layer.hpp>
-#include <mbgl/renderer/layers/render_circle_layer.hpp>
-#include <mbgl/renderer/layers/render_custom_layer.hpp>
-#include <mbgl/renderer/layers/render_fill_extrusion_layer.hpp>
-#include <mbgl/renderer/layers/render_fill_layer.hpp>
-#include <mbgl/renderer/layers/render_line_layer.hpp>
-#include <mbgl/renderer/layers/render_raster_layer.hpp>
-#include <mbgl/renderer/layers/render_symbol_layer.hpp>
-#include <mbgl/renderer/style_diff.hpp>
-#include <mbgl/sprite/sprite_atlas.hpp>
-#include <mbgl/tile/tile.hpp>
-#include <mbgl/util/constants.hpp>
#include <mbgl/util/exception.hpp>
-#include <mbgl/util/geometry.hpp>
#include <mbgl/util/string.hpp>
#include <mbgl/util/logging.hpp>
-#include <mbgl/util/math.hpp>
-#include <mbgl/util/std.hpp>
-#include <mbgl/math/minmax.hpp>
-#include <mbgl/map/query.hpp>
-
-#include <algorithm>
namespace mbgl {
namespace style {
@@ -57,14 +28,9 @@ static Observer nullObserver;
Style::Style(Scheduler& scheduler_, FileSource& fileSource_, float pixelRatio)
: scheduler(scheduler_),
fileSource(fileSource_),
- glyphAtlas(std::make_unique<GlyphAtlas>(Size{ 2048, 2048 }, fileSource)),
spriteLoader(std::make_unique<SpriteLoader>(pixelRatio)),
- spriteAtlas(std::make_unique<SpriteAtlas>()),
- lineAtlas(std::make_unique<LineAtlas>(Size{ 256, 512 })),
light(std::make_unique<Light>()),
- renderLight(light->impl),
observer(&nullObserver) {
- glyphAtlas->setObserver(this);
spriteLoader->setObserver(this);
light->setObserver(this);
}
@@ -87,7 +53,6 @@ TransitionOptions Style::getTransitionOptions() const {
void Style::setJSON(const std::string& json) {
sources.clear();
- renderSources.clear();
layers.clear();
transitionOptions = {};
@@ -117,8 +82,8 @@ void Style::setJSON(const std::string& json) {
defaultPitch = parser.pitch;
setLight(std::make_unique<Light>(parser.light));
- glyphAtlas->setURL(parser.glyphURL);
spriteLoader->load(parser.spriteURL, scheduler, fileSource);
+ glyphURL = parser.glyphURL;
loaded = true;
@@ -181,15 +146,6 @@ std::unique_ptr<Source> Style::removeSource(const std::string& id) {
return source;
}
-std::vector<const Layer*> Style::getLayers() const {
- std::vector<const Layer*> result;
- result.reserve(layers.size());
- for (const auto& layer : layers) {
- result.push_back(layer.get());
- }
- return result;
-}
-
std::vector<Layer*> Style::getLayers() {
std::vector<Layer*> result;
result.reserve(layers.size());
@@ -250,29 +206,6 @@ std::unique_ptr<Layer> Style::removeLayer(const std::string& id) {
return layer;
}
-std::vector<const RenderLayer*> Style::getRenderLayers() const {
- std::vector<const RenderLayer*> result;
- result.reserve(renderLayers.size());
- for (const auto& entry : renderLayers) {
- result.push_back(entry.second.get());
- }
- return result;
-}
-
-std::vector<RenderLayer*> Style::getRenderLayers() {
- std::vector<RenderLayer*> result;
- result.reserve(renderLayers.size());
- for (auto& entry : renderLayers) {
- result.push_back(entry.second.get());
- }
- return result;
-}
-
-RenderLayer* Style::getRenderLayer(const std::string& id) const {
- auto it = renderLayers.find(id);
- return it != renderLayers.end() ? it->second.get() : nullptr;
-}
-
void Style::setLight(std::unique_ptr<Light> light_) {
light = std::move(light_);
light->setObserver(this);
@@ -283,10 +216,6 @@ Light* Style::getLight() const {
return light.get();
}
-const RenderLight& Style::getRenderLight() const {
- return renderLight;
-}
-
std::string Style::getName() const {
return name;
}
@@ -307,177 +236,6 @@ double Style::getDefaultPitch() const {
return defaultPitch;
}
-void Style::update(const UpdateParameters& parameters) {
- const bool zoomChanged = zoomHistory.update(parameters.transformState.getZoom(), parameters.timePoint);
-
- const TransitionParameters transitionParameters {
- parameters.mode == MapMode::Continuous ? parameters.timePoint : Clock::time_point::max(),
- parameters.mode == MapMode::Continuous ? transitionOptions : TransitionOptions()
- };
-
- const PropertyEvaluationParameters evaluationParameters {
- zoomHistory,
- parameters.mode == MapMode::Continuous ? parameters.timePoint : Clock::time_point::max(),
- 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,
- *spriteAtlas,
- *glyphAtlas
- };
-
- // Update light.
- const bool lightChanged = renderLight.impl != light->impl;
-
- if (lightChanged) {
- renderLight.impl = light->impl;
- renderLight.transition(transitionParameters);
- }
-
- if (lightChanged || zoomChanged || renderLight.hasTransition()) {
- renderLight.evaluate(evaluationParameters);
- }
-
-
- std::vector<Immutable<Image::Impl>> newImageImpls;
- newImageImpls.reserve(images.size());
- for (const auto& entry : images) {
- newImageImpls.push_back(entry.second->impl);
- }
-
- const ImageDifference imageDiff = diffImages(imageImpls, newImageImpls);
- imageImpls = std::move(newImageImpls);
-
- // Remove removed images from sprite atlas.
- for (const auto& entry : imageDiff.removed) {
- spriteAtlas->removeImage(entry.first);
- }
-
- // Add added images to sprite atlas.
- for (const auto& entry : imageDiff.added) {
- spriteAtlas->addImage(entry.second);
- }
-
- // Update changed images.
- for (const auto& entry : imageDiff.changed) {
- spriteAtlas->updateImage(entry.second[1]);
- }
-
- if (spriteLoaded && !spriteAtlas->isLoaded()) {
- spriteAtlas->onSpriteLoaded();
- }
-
-
- std::vector<Immutable<Source::Impl>> newSourceImpls;
- newSourceImpls.reserve(sources.size());
- for (const auto& source : sources) {
- newSourceImpls.push_back(source->baseImpl);
- }
-
-
- std::vector<Immutable<Layer::Impl>> newLayerImpls;
- newLayerImpls.reserve(layers.size());
- for (const auto& layer : layers) {
- newLayerImpls.push_back(layer->baseImpl);
- }
-
- const LayerDifference layerDiff = diffLayers(layerImpls, newLayerImpls);
- layerImpls = std::move(newLayerImpls);
-
- // Remove render layers for removed layers.
- for (const auto& entry : layerDiff.removed) {
- renderLayers.erase(entry.first);
- }
-
- // Create render layers for newly added layers.
- for (const auto& entry : layerDiff.added) {
- renderLayers.emplace(entry.first, RenderLayer::create(entry.second));
- }
-
- // Update render layers for changed layers.
- for (const auto& entry : layerDiff.changed) {
- renderLayers.at(entry.first)->setImpl(entry.second[1]);
- }
-
- // Update layers for class and zoom changes.
- for (const auto& entry : renderLayers) {
- RenderLayer& layer = *entry.second;
- const bool layerAdded = layerDiff.added.count(entry.first);
- const bool layerChanged = layerDiff.changed.count(entry.first);
-
- if (layerAdded || layerChanged) {
- layer.transition(transitionParameters);
- }
-
- if (layerAdded || layerChanged || zoomChanged || layer.hasTransition()) {
- layer.evaluate(evaluationParameters);
- }
- }
-
-
- 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);
- }
-
- // 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;
- }
-
- if (getRenderLayer(layer->id)->needsRendering(zoomHistory.lastZoom)) {
- needsRendering = true;
- }
-
- 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 {
- std::vector<const Source*> result;
- result.reserve(sources.size());
- for (const auto& source : sources) {
- result.push_back(source.get());
- }
- return result;
-}
-
std::vector<Source*> Style::getSources() {
std::vector<Source*> result;
result.reserve(sources.size());
@@ -495,25 +253,6 @@ Source* Style::getSource(const std::string& id) const {
return it != sources.end() ? it->get() : nullptr;
}
-RenderSource* Style::getRenderSource(const std::string& id) const {
- auto it = renderSources.find(id);
- return it != renderSources.end() ? it->second.get() : nullptr;
-}
-
-bool Style::hasTransitions() const {
- if (renderLight.hasTransition()) {
- return true;
- }
-
- for (const auto& entry : renderLayers) {
- if (entry.second->hasTransition()) {
- return true;
- }
- }
-
- return false;
-}
-
bool Style::isLoaded() const {
if (!loaded) {
return false;
@@ -529,12 +268,6 @@ bool Style::isLoaded() const {
}
}
- for (const auto& entry: renderSources) {
- if (!entry.second->isLoaded()) {
- return false;
- }
- }
-
return true;
}
@@ -557,182 +290,10 @@ const style::Image* Style::getImage(const std::string& id) const {
return it == images.end() ? nullptr : it->second.get();
}
-RenderData Style::getRenderData(MapDebugOptions debugOptions, float angle) const {
- RenderData result;
-
- for (const auto& entry : renderSources) {
- if (entry.second->isEnabled()) {
- result.sources.insert(entry.second.get());
- }
- }
-
- for (auto& layerImpl : layerImpls) {
- RenderLayer* layer = getRenderLayer(layerImpl->id);
- assert(layer);
-
- if (!layer->needsRendering(zoomHistory.lastZoom)) {
- continue;
- }
-
- if (const RenderBackgroundLayer* background = layer->as<RenderBackgroundLayer>()) {
- if (debugOptions & MapDebugOptions::Overdraw) {
- // We want to skip glClear optimization in overdraw mode.
- result.order.emplace_back(*layer, nullptr);
- continue;
- }
- const BackgroundPaintProperties::PossiblyEvaluated& paint = background->evaluated;
- if (layerImpl.get() == layerImpls[0].get() && paint.get<BackgroundPattern>().from.empty()) {
- // This is a solid background. We can use glClear().
- result.backgroundColor = paint.get<BackgroundColor>() * paint.get<BackgroundOpacity>();
- } else {
- // This is a textured background, or not the bottommost layer. We need to render it with a quad.
- result.order.emplace_back(*layer, nullptr);
- }
- continue;
- }
-
- if (layer->is<RenderCustomLayer>()) {
- result.order.emplace_back(*layer, nullptr);
- continue;
- }
-
- RenderSource* source = getRenderSource(layer->baseImpl->source);
- if (!source) {
- Log::Warning(Event::Render, "can't find source for layer '%s'", layer->getID().c_str());
- continue;
- }
-
- auto& renderTiles = source->getRenderTiles();
- const bool symbolLayer = layer->is<RenderSymbolLayer>();
-
- // Sort symbol tiles in opposite y position, so tiles with overlapping
- // symbols are drawn on top of each other, with lower symbols being
- // drawn on top of higher symbols.
- std::vector<std::reference_wrapper<RenderTile>> sortedTiles;
- std::transform(renderTiles.begin(), renderTiles.end(), std::back_inserter(sortedTiles),
- [](auto& pair) { return std::ref(pair.second); });
- if (symbolLayer) {
- std::sort(sortedTiles.begin(), sortedTiles.end(),
- [angle](const RenderTile& a, const RenderTile& b) {
- Point<float> pa(a.id.canonical.x, a.id.canonical.y);
- Point<float> pb(b.id.canonical.x, b.id.canonical.y);
-
- auto par = util::rotate(pa, angle);
- auto pbr = util::rotate(pb, angle);
-
- return std::tie(par.y, par.x) < std::tie(pbr.y, pbr.x);
- });
- }
-
- std::vector<std::reference_wrapper<RenderTile>> sortedTilesForInsertion;
- for (auto& sortedTile : sortedTiles) {
- auto& tile = sortedTile.get();
- if (!tile.tile.isRenderable()) {
- continue;
- }
-
- // We're not clipping symbol layers, so when we have both parents and children of symbol
- // layers, we drop all children in favor of their parent to avoid duplicate labels.
- // See https://github.com/mapbox/mapbox-gl-native/issues/2482
- if (symbolLayer) {
- bool skip = false;
- // Look back through the buckets we decided to render to find out whether there is
- // already a bucket from this layer that is a parent of this tile. Tiles are ordered
- // by zoom level when we obtain them from getTiles().
- for (auto it = sortedTilesForInsertion.rbegin();
- it != sortedTilesForInsertion.rend(); ++it) {
- if (tile.tile.id.isChildOf(it->get().tile.id)) {
- skip = true;
- break;
- }
- }
- if (skip) {
- continue;
- }
- }
-
- auto bucket = tile.tile.getBucket(*layer->baseImpl);
- if (bucket) {
- sortedTilesForInsertion.emplace_back(tile);
- tile.used = true;
- }
- }
- layer->setRenderTiles(std::move(sortedTilesForInsertion));
- result.order.emplace_back(*layer, source);
- }
-
- return result;
-}
-
-std::vector<Feature> Style::queryRenderedFeatures(const ScreenLineString& geometry,
- const TransformState& transformState,
- const RenderedQueryOptions& options) const {
- std::unordered_map<std::string, std::vector<Feature>> resultsByLayer;
-
- if (options.layerIDs) {
- std::unordered_set<std::string> sourceIDs;
- for (const auto& layerID : *options.layerIDs) {
- if (Layer* layer = getLayer(layerID)) {
- sourceIDs.emplace(layer->baseImpl->source);
- }
- }
- for (const auto& sourceID : sourceIDs) {
- if (RenderSource* renderSource = getRenderSource(sourceID)) {
- auto sourceResults = renderSource->queryRenderedFeatures(geometry, transformState, *this, options);
- std::move(sourceResults.begin(), sourceResults.end(), std::inserter(resultsByLayer, resultsByLayer.begin()));
- }
- }
- } else {
- for (const auto& entry : renderSources) {
- auto sourceResults = entry.second->queryRenderedFeatures(geometry, transformState, *this, options);
- std::move(sourceResults.begin(), sourceResults.end(), std::inserter(resultsByLayer, resultsByLayer.begin()));
- }
- }
-
- std::vector<Feature> result;
-
- if (resultsByLayer.empty()) {
- return result;
- }
-
- // Combine all results based on the style layer order.
- for (const auto& layerImpl : layerImpls) {
- const RenderLayer* layer = getRenderLayer(layerImpl->id);
- if (!layer->needsRendering(zoomHistory.lastZoom)) {
- continue;
- }
- auto it = resultsByLayer.find(layer->baseImpl->id);
- if (it != resultsByLayer.end()) {
- std::move(it->second.begin(), it->second.end(), std::back_inserter(result));
- }
- }
-
- return result;
-}
-
-void Style::setSourceTileCacheSize(size_t size) {
- for (const auto& entry : renderSources) {
- entry.second->setCacheSize(size);
- }
-}
-
-void Style::onLowMemory() {
- for (const auto& entry : renderSources) {
- entry.second->onLowMemory();
- }
-}
-
void Style::setObserver(style::Observer* observer_) {
observer = observer_;
}
-void Style::onGlyphsError(const FontStack& fontStack, const GlyphRange& glyphRange, std::exception_ptr error) {
- lastError = error;
- Log::Error(Event::Style, "Failed to load glyph range %d-%d for font stack %s: %s",
- glyphRange.first, glyphRange.second, fontStackToString(fontStack).c_str(), util::toString(error).c_str());
- observer->onResourceError(error);
-}
-
void Style::onSourceLoaded(Source& source) {
observer->onSourceLoaded(source);
observer->onUpdate(Update::Repaint);
@@ -757,17 +318,6 @@ void Style::onSourceDescriptionChanged(Source& source) {
}
}
-void Style::onTileChanged(RenderSource&, const OverscaledTileID&) {
- observer->onUpdate(Update::Repaint);
-}
-
-void Style::onTileError(RenderSource& source, const OverscaledTileID& tileID, std::exception_ptr error) {
- lastError = error;
- Log::Error(Event::Style, "Failed to load tile %s for source %s: %s",
- util::toString(tileID).c_str(), source.baseImpl->id.c_str(), util::toString(error).c_str());
- observer->onResourceError(error);
-}
-
void Style::onSpriteLoaded(std::vector<std::unique_ptr<Image>>&& images_) {
for (auto& image : images_) {
addImage(std::move(image));
@@ -794,12 +344,37 @@ void Style::dumpDebugLogs() const {
for (const auto& source : sources) {
source->dumpDebugLogs();
}
+}
+
+const std::string& Style::getGlyphURL() const {
+ return glyphURL;
+}
+
+std::vector<Immutable<Image::Impl>> Style::getImageImpls() const {
+ std::vector<Immutable<style::Image::Impl>> result;
+ result.reserve(images.size());
+ for (const auto& image : images) {
+ result.push_back(image.second->impl);
+ }
+ return result;
+}
- for (const auto& entry : renderSources) {
- entry.second->dumpDebugLogs();
+std::vector<Immutable<Source::Impl>> Style::getSourceImpls() const {
+ std::vector<Immutable<style::Source::Impl>> result;
+ result.reserve(sources.size());
+ for (const auto& source : sources) {
+ result.push_back(source->baseImpl);
}
+ return result;
+}
- spriteAtlas->dumpDebugLogs();
+std::vector<Immutable<Layer::Impl>> Style::getLayerImpls() const {
+ std::vector<Immutable<style::Layer::Impl>> result;
+ result.reserve(layers.size());
+ for (const auto& layer : layers) {
+ result.push_back(layer->baseImpl);
+ }
+ return result;
}
} // namespace style