diff options
Diffstat (limited to 'src/mbgl/renderer/render_style.cpp')
-rw-r--r-- | src/mbgl/renderer/render_style.cpp | 456 |
1 files changed, 0 insertions, 456 deletions
diff --git a/src/mbgl/renderer/render_style.cpp b/src/mbgl/renderer/render_style.cpp deleted file mode 100644 index f9c3f0ca9f..0000000000 --- a/src/mbgl/renderer/render_style.cpp +++ /dev/null @@ -1,456 +0,0 @@ -#include <mbgl/renderer/render_style.hpp> -#include <mbgl/renderer/render_style_observer.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/renderer/image_manager.hpp> -#include <mbgl/style/style.hpp> -#include <mbgl/style/source_impl.hpp> -#include <mbgl/style/transition_options.hpp> -#include <mbgl/sprite/sprite_loader.hpp> -#include <mbgl/text/glyph_manager.hpp> -#include <mbgl/geometry/line_atlas.hpp> -#include <mbgl/map/backend_scope.hpp> -#include <mbgl/map/query.hpp> -#include <mbgl/tile/tile.hpp> -#include <mbgl/util/math.hpp> -#include <mbgl/util/string.hpp> - -namespace mbgl { - -using namespace style; - -RenderStyleObserver nullObserver; - -RenderStyle::RenderStyle(Scheduler& scheduler_, FileSource& fileSource_) - : scheduler(scheduler_), - fileSource(fileSource_), - glyphManager(std::make_unique<GlyphManager>(fileSource)), - imageManager(std::make_unique<ImageManager>()), - lineAtlas(std::make_unique<LineAtlas>(Size{ 256, 512 })), - imageImpls(makeMutable<std::vector<Immutable<style::Image::Impl>>>()), - sourceImpls(makeMutable<std::vector<Immutable<style::Source::Impl>>>()), - layerImpls(makeMutable<std::vector<Immutable<style::Layer::Impl>>>()), - renderLight(makeMutable<Light::Impl>()), - observer(&nullObserver) { - glyphManager->setObserver(this); -} - -RenderStyle::~RenderStyle() { - assert(BackendScope::exists()); // Required for custom layers. -} - -void RenderStyle::setObserver(RenderStyleObserver* observer_) { - observer = observer_; -} - -std::vector<const RenderLayer*> RenderStyle::getRenderLayers() const { - std::vector<const RenderLayer*> result; - result.reserve(renderLayers.size()); - for (const auto& layer : *layerImpls) { - result.push_back(getRenderLayer(layer->id)); - } - return result; -} - -RenderLayer* RenderStyle::getRenderLayer(const std::string& id) { - auto it = renderLayers.find(id); - return it != renderLayers.end() ? it->second.get() : nullptr; -} - -const RenderLayer* RenderStyle::getRenderLayer(const std::string& id) const { - auto it = renderLayers.find(id); - return it != renderLayers.end() ? it->second.get() : nullptr; -} - -const RenderLight& RenderStyle::getRenderLight() const { - return renderLight; -} - -void RenderStyle::update(const UpdateParameters& parameters) { - assert(BackendScope::exists()); // Required for custom layers. - - 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 ? parameters.transitionOptions : TransitionOptions() - }; - - const PropertyEvaluationParameters evaluationParameters { - zoomHistory, - parameters.mode == MapMode::Continuous ? parameters.timePoint : Clock::time_point::max(), - parameters.mode == MapMode::Continuous ? util::DEFAULT_TRANSITION_DURATION : Duration::zero() - }; - - const TileParameters tileParameters { - parameters.pixelRatio, - parameters.debugOptions, - parameters.transformState, - parameters.scheduler, - parameters.fileSource, - parameters.mode, - parameters.annotationManager, - *imageManager, - *glyphManager - }; - - glyphManager->setURL(parameters.glyphURL); - - // Update light. - const bool lightChanged = renderLight.impl != parameters.light; - - if (lightChanged) { - renderLight.impl = parameters.light; - renderLight.transition(transitionParameters); - } - - if (lightChanged || zoomChanged || renderLight.hasTransition()) { - renderLight.evaluate(evaluationParameters); - } - - - const ImageDifference imageDiff = diffImages(imageImpls, parameters.images); - imageImpls = parameters.images; - - // Remove removed images from sprite atlas. - for (const auto& entry : imageDiff.removed) { - imageManager->removeImage(entry.first); - } - - // Add added images to sprite atlas. - for (const auto& entry : imageDiff.added) { - imageManager->addImage(entry.second); - } - - // Update changed images. - for (const auto& entry : imageDiff.changed) { - imageManager->updateImage(entry.second.after); - } - - if (parameters.spriteLoaded && !imageManager->isLoaded()) { - imageManager->onSpriteLoaded(); - } - - - const LayerDifference layerDiff = diffLayers(layerImpls, parameters.layers); - layerImpls = parameters.layers; - - // 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.after); - } - - // 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, parameters.sources); - sourceImpls = parameters.sources; - - // 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 (!needsRendering && getRenderLayer(layer->id)->needsRendering(zoomHistory.lastZoom)) { - needsRendering = true; - } - - if (!needsRelayout && ( - hasLayoutDifference(layerDiff, layer->id) || - !imageDiff.added.empty() || - !imageDiff.removed.empty() || - !imageDiff.changed.empty())) { - needsRelayout = true; - } - - filteredLayers.push_back(layer); - } - - renderSources.at(source->id)->update(source, - filteredLayers, - needsRendering, - needsRelayout, - tileParameters); - } -} - -RenderSource* RenderStyle::getRenderSource(const std::string& id) const { - auto it = renderSources.find(id); - return it != renderSources.end() ? it->second.get() : nullptr; -} - -bool RenderStyle::hasTransitions() const { - if (renderLight.hasTransition()) { - return true; - } - - for (const auto& entry : renderLayers) { - if (entry.second->hasTransition()) { - return true; - } - } - - return false; -} - -bool RenderStyle::isLoaded() const { - for (const auto& entry: renderSources) { - if (!entry.second->isLoaded()) { - return false; - } - } - - if (!imageManager->isLoaded()) { - return false; - } - - return true; -} - -RenderData RenderStyle::getRenderData(MapDebugOptions debugOptions, float angle) { - 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->at(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> RenderStyle::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 (const RenderLayer* layer = getRenderLayer(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 RenderStyle::setSourceTileCacheSize(size_t size) { - for (const auto& entry : renderSources) { - entry.second->setCacheSize(size); - } -} - -void RenderStyle::onLowMemory() { - for (const auto& entry : renderSources) { - entry.second->onLowMemory(); - } -} - -void RenderStyle::onGlyphsError(const FontStack& fontStack, const GlyphRange& glyphRange, std::exception_ptr 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 RenderStyle::onTileError(RenderSource& source, const OverscaledTileID& tileID, std::exception_ptr 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 RenderStyle::onTileChanged(RenderSource&, const OverscaledTileID&) { - observer->onInvalidate(); -} - -void RenderStyle::dumpDebugLogs() const { - for (const auto& entry : renderSources) { - entry.second->dumpDebugLogs(); - } - - imageManager->dumpDebugLogs(); -} - -} // namespace mbgl |