[core] Split RenderStyle from Style
This commit is contained in:
@@ -184,6 +184,9 @@ set(MBGL_CORE_FILES
|
||||
src/mbgl/renderer/render_source.cpp
|
||||
src/mbgl/renderer/render_source.hpp
|
||||
src/mbgl/renderer/render_source_observer.hpp
|
||||
src/mbgl/renderer/render_style.cpp
|
||||
src/mbgl/renderer/render_style.hpp
|
||||
src/mbgl/renderer/render_style_observer.hpp
|
||||
src/mbgl/renderer/render_tile.cpp
|
||||
src/mbgl/renderer/render_tile.hpp
|
||||
src/mbgl/renderer/style_diff.cpp
|
||||
|
||||
@@ -59,7 +59,7 @@ std::map<UnwrappedTileID, RenderTile>& RenderAnnotationSource::getRenderTiles()
|
||||
std::unordered_map<std::string, std::vector<Feature>>
|
||||
RenderAnnotationSource::queryRenderedFeatures(const ScreenLineString& geometry,
|
||||
const TransformState& transformState,
|
||||
const style::Style& style,
|
||||
const RenderStyle& style,
|
||||
const RenderedQueryOptions& options) const {
|
||||
return tilePyramid.queryRenderedFeatures(geometry, transformState, style, options);
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ public:
|
||||
std::unordered_map<std::string, std::vector<Feature>>
|
||||
queryRenderedFeatures(const ScreenLineString& geometry,
|
||||
const TransformState& transformState,
|
||||
const style::Style& style,
|
||||
const RenderStyle& style,
|
||||
const RenderedQueryOptions& options) const final;
|
||||
|
||||
std::vector<Feature>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include <mbgl/geometry/feature_index.hpp>
|
||||
#include <mbgl/style/style.hpp>
|
||||
#include <mbgl/renderer/render_style.hpp>
|
||||
#include <mbgl/renderer/render_layer.hpp>
|
||||
#include <mbgl/renderer/layers/render_symbol_layer.hpp>
|
||||
#include <mbgl/text/collision_tile.hpp>
|
||||
@@ -54,7 +54,7 @@ static bool topDownSymbols(const IndexedSubfeature& a, const IndexedSubfeature&
|
||||
}
|
||||
|
||||
static int16_t getAdditionalQueryRadius(const RenderedQueryOptions& queryOptions,
|
||||
const style::Style& style,
|
||||
const RenderStyle& style,
|
||||
const GeometryTile& tile,
|
||||
const float pixelsToTileUnits) {
|
||||
|
||||
@@ -69,7 +69,7 @@ static int16_t getAdditionalQueryRadius(const RenderedQueryOptions& queryOptions
|
||||
|
||||
if (queryOptions.layerIDs) {
|
||||
for (const auto& layerID : *queryOptions.layerIDs) {
|
||||
RenderLayer* layer = style.getRenderLayer(layerID);
|
||||
const RenderLayer* layer = style.getRenderLayer(layerID);
|
||||
if (layer) {
|
||||
getQueryRadius(*layer);
|
||||
}
|
||||
@@ -92,7 +92,7 @@ void FeatureIndex::query(
|
||||
const RenderedQueryOptions& queryOptions,
|
||||
const GeometryTileData& geometryTileData,
|
||||
const CanonicalTileID& tileID,
|
||||
const style::Style& style,
|
||||
const RenderStyle& style,
|
||||
const CollisionTile* collisionTile,
|
||||
const GeometryTile& tile) const {
|
||||
|
||||
@@ -135,7 +135,7 @@ void FeatureIndex::addFeature(
|
||||
const RenderedQueryOptions& options,
|
||||
const GeometryTileData& geometryTileData,
|
||||
const CanonicalTileID& tileID,
|
||||
const style::Style& style,
|
||||
const RenderStyle& style,
|
||||
const float bearing,
|
||||
const float pixelsToTileUnits) const {
|
||||
|
||||
|
||||
@@ -13,10 +13,7 @@ namespace mbgl {
|
||||
|
||||
class GeometryTile;
|
||||
class RenderedQueryOptions;
|
||||
|
||||
namespace style {
|
||||
class Style;
|
||||
} // namespace style
|
||||
class RenderStyle;
|
||||
|
||||
class CollisionTile;
|
||||
class CanonicalTileID;
|
||||
@@ -45,7 +42,7 @@ public:
|
||||
const RenderedQueryOptions& options,
|
||||
const GeometryTileData&,
|
||||
const CanonicalTileID&,
|
||||
const style::Style&,
|
||||
const RenderStyle&,
|
||||
const CollisionTile*,
|
||||
const GeometryTile& tile) const;
|
||||
|
||||
@@ -66,7 +63,7 @@ private:
|
||||
const RenderedQueryOptions& options,
|
||||
const GeometryTileData&,
|
||||
const CanonicalTileID&,
|
||||
const style::Style&,
|
||||
const RenderStyle&,
|
||||
const float bearing,
|
||||
const float pixelsToTileUnits) const;
|
||||
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
#include <mbgl/renderer/update_parameters.hpp>
|
||||
#include <mbgl/renderer/painter.hpp>
|
||||
#include <mbgl/renderer/render_source.hpp>
|
||||
#include <mbgl/renderer/render_style.hpp>
|
||||
#include <mbgl/renderer/render_style_observer.hpp>
|
||||
#include <mbgl/storage/file_source.hpp>
|
||||
#include <mbgl/storage/resource.hpp>
|
||||
#include <mbgl/storage/response.hpp>
|
||||
@@ -48,7 +50,8 @@ struct StillImageRequest {
|
||||
Map::StillImageCallback callback;
|
||||
};
|
||||
|
||||
class Map::Impl : public style::Observer {
|
||||
class Map::Impl : public style::Observer,
|
||||
public RenderStyleObserver {
|
||||
public:
|
||||
Impl(Map&,
|
||||
Backend&,
|
||||
@@ -63,6 +66,7 @@ public:
|
||||
|
||||
void onSourceChanged(style::Source&) override;
|
||||
void onUpdate(Update) override;
|
||||
void onInvalidate() override;
|
||||
void onStyleLoaded() override;
|
||||
void onStyleError(std::exception_ptr) override;
|
||||
void onResourceError(std::exception_ptr) override;
|
||||
@@ -93,6 +97,7 @@ public:
|
||||
AnnotationManager annotationManager;
|
||||
std::unique_ptr<Painter> painter;
|
||||
std::unique_ptr<Style> style;
|
||||
std::unique_ptr<RenderStyle> renderStyle;
|
||||
|
||||
std::string styleURL;
|
||||
std::string styleJSON;
|
||||
@@ -169,6 +174,7 @@ Map::~Map() {
|
||||
|
||||
// Explicit resets currently necessary because these abandon resources that need to be
|
||||
// cleaned up by context.reset();
|
||||
impl->renderStyle.reset();
|
||||
impl->style.reset();
|
||||
impl->painter.reset();
|
||||
}
|
||||
@@ -238,16 +244,22 @@ void Map::Impl::render(View& view) {
|
||||
annotationManager.updateData();
|
||||
}
|
||||
|
||||
style->update({
|
||||
renderStyle->update({
|
||||
mode,
|
||||
updateFlags,
|
||||
pixelRatio,
|
||||
debugOptions,
|
||||
timePoint,
|
||||
transform.getState(),
|
||||
style->getGlyphURL(),
|
||||
style->spriteLoaded,
|
||||
style->getTransitionOptions(),
|
||||
style->getLight()->impl,
|
||||
style->getImageImpls(),
|
||||
style->getSourceImpls(),
|
||||
style->getLayerImpls(),
|
||||
scheduler,
|
||||
fileSource,
|
||||
annotationManager
|
||||
annotationManager,
|
||||
transform.getState()
|
||||
});
|
||||
|
||||
updateFlags = Update::Nothing;
|
||||
@@ -257,6 +269,8 @@ void Map::Impl::render(View& view) {
|
||||
painter = std::make_unique<Painter>(context, transform.getState(), pixelRatio, programCacheDir);
|
||||
}
|
||||
|
||||
bool loaded = style->isLoaded() && renderStyle->isLoaded();
|
||||
|
||||
if (mode == MapMode::Continuous) {
|
||||
if (renderState == RenderState::Never) {
|
||||
observer.onWillStartRenderingMap();
|
||||
@@ -272,15 +286,17 @@ void Map::Impl::render(View& view) {
|
||||
|
||||
backend.updateAssumedState();
|
||||
|
||||
painter->render(*style,
|
||||
painter->render(*renderStyle,
|
||||
frameData,
|
||||
view);
|
||||
|
||||
painter->cleanup();
|
||||
|
||||
observer.onDidFinishRenderingFrame(style->isLoaded() ? MapObserver::RenderMode::Full : MapObserver::RenderMode::Partial);
|
||||
observer.onDidFinishRenderingFrame(loaded
|
||||
? MapObserver::RenderMode::Full
|
||||
: MapObserver::RenderMode::Partial);
|
||||
|
||||
if (!style->isLoaded()) {
|
||||
if (!loaded) {
|
||||
renderState = RenderState::Partial;
|
||||
} else if (renderState != RenderState::Fully) {
|
||||
renderState = RenderState::Fully;
|
||||
@@ -293,10 +309,10 @@ void Map::Impl::render(View& view) {
|
||||
|
||||
// Schedule an update if we need to paint another frame due to transitions or
|
||||
// animations that are still in progress
|
||||
if (style->hasTransitions() || painter->needsAnimation() || transform.inTransition()) {
|
||||
if (renderStyle->hasTransitions() || painter->needsAnimation() || transform.inTransition()) {
|
||||
onUpdate(Update::Repaint);
|
||||
}
|
||||
} else if (stillImageRequest && style->isLoaded()) {
|
||||
} else if (stillImageRequest && loaded) {
|
||||
FrameData frameData { timePoint,
|
||||
pixelRatio,
|
||||
mode,
|
||||
@@ -305,7 +321,7 @@ void Map::Impl::render(View& view) {
|
||||
|
||||
backend.updateAssumedState();
|
||||
|
||||
painter->render(*style,
|
||||
painter->render(*renderStyle,
|
||||
frameData,
|
||||
view);
|
||||
|
||||
@@ -333,6 +349,7 @@ void Map::setStyleURL(const std::string& url) {
|
||||
impl->styleMutated = false;
|
||||
|
||||
impl->style = std::make_unique<Style>(impl->scheduler, impl->fileSource, impl->pixelRatio);
|
||||
impl->renderStyle = std::make_unique<RenderStyle>(impl->scheduler, impl->fileSource);
|
||||
|
||||
impl->styleRequest = impl->fileSource.request(Resource::style(impl->styleURL), [this](Response res) {
|
||||
// Once we get a fresh style, or the style is mutated, stop revalidating.
|
||||
@@ -379,12 +396,15 @@ void Map::setStyleJSON(const std::string& json) {
|
||||
impl->styleMutated = false;
|
||||
|
||||
impl->style = std::make_unique<Style>(impl->scheduler, impl->fileSource, impl->pixelRatio);
|
||||
impl->renderStyle = std::make_unique<RenderStyle>(impl->scheduler, impl->fileSource);
|
||||
|
||||
impl->loadStyleJSON(json);
|
||||
}
|
||||
|
||||
void Map::Impl::loadStyleJSON(const std::string& json) {
|
||||
style->setObserver(this);
|
||||
renderStyle->setObserver(this);
|
||||
|
||||
style->setJSON(json);
|
||||
styleJSON = json;
|
||||
|
||||
@@ -816,7 +836,7 @@ void Map::removeAnnotation(AnnotationID annotation) {
|
||||
std::vector<Feature> Map::queryRenderedFeatures(const ScreenCoordinate& point, const RenderedQueryOptions& options) {
|
||||
if (!impl->style) return {};
|
||||
|
||||
return impl->style->queryRenderedFeatures(
|
||||
return impl->renderStyle->queryRenderedFeatures(
|
||||
{ point },
|
||||
impl->transform.getState(),
|
||||
options
|
||||
@@ -826,7 +846,7 @@ std::vector<Feature> Map::queryRenderedFeatures(const ScreenCoordinate& point, c
|
||||
std::vector<Feature> Map::queryRenderedFeatures(const ScreenBox& box, const RenderedQueryOptions& options) {
|
||||
if (!impl->style) return {};
|
||||
|
||||
return impl->style->queryRenderedFeatures(
|
||||
return impl->renderStyle->queryRenderedFeatures(
|
||||
{
|
||||
box.min,
|
||||
{ box.max.x, box.min.y },
|
||||
@@ -842,7 +862,7 @@ std::vector<Feature> Map::queryRenderedFeatures(const ScreenBox& box, const Rend
|
||||
std::vector<Feature> Map::querySourceFeatures(const std::string& sourceID, const SourceQueryOptions& options) {
|
||||
if (!impl->style) return {};
|
||||
|
||||
const RenderSource* source = impl->style->getRenderSource(sourceID);
|
||||
const RenderSource* source = impl->renderStyle->getRenderSource(sourceID);
|
||||
if (!source) return {};
|
||||
|
||||
return source->querySourceFeatures(options);
|
||||
@@ -1046,7 +1066,7 @@ MapDebugOptions Map::getDebug() const {
|
||||
}
|
||||
|
||||
bool Map::isFullyLoaded() const {
|
||||
return impl->style ? impl->style->isLoaded() : false;
|
||||
return impl->style && impl->style->isLoaded() && impl->renderStyle->isLoaded();
|
||||
}
|
||||
|
||||
style::TransitionOptions Map::getTransitionOptions() const {
|
||||
@@ -1066,7 +1086,7 @@ void Map::setSourceTileCacheSize(size_t size) {
|
||||
if (size != impl->sourceCacheSize) {
|
||||
impl->sourceCacheSize = size;
|
||||
if (!impl->style) return;
|
||||
impl->style->setSourceTileCacheSize(size);
|
||||
impl->renderStyle->setSourceTileCacheSize(size);
|
||||
impl->backend.invalidate();
|
||||
}
|
||||
}
|
||||
@@ -1076,8 +1096,8 @@ void Map::onLowMemory() {
|
||||
BackendScope guard(impl->backend);
|
||||
impl->painter->cleanup();
|
||||
}
|
||||
if (impl->style) {
|
||||
impl->style->onLowMemory();
|
||||
if (impl->renderStyle) {
|
||||
impl->renderStyle->onLowMemory();
|
||||
impl->backend.invalidate();
|
||||
}
|
||||
}
|
||||
@@ -1091,6 +1111,10 @@ void Map::Impl::onUpdate(Update flags) {
|
||||
asyncInvalidate.send();
|
||||
}
|
||||
|
||||
void Map::Impl::onInvalidate() {
|
||||
onUpdate(Update::Repaint);
|
||||
}
|
||||
|
||||
void Map::Impl::onStyleLoaded() {
|
||||
observer.onDidFinishLoadingStyle();
|
||||
}
|
||||
@@ -1111,6 +1135,7 @@ void Map::dumpDebugLogs() const {
|
||||
Log::Info(Event::General, "MapContext::styleURL: %s", impl->styleURL.c_str());
|
||||
if (impl->style) {
|
||||
impl->style->dumpDebugLogs();
|
||||
impl->renderStyle->dumpDebugLogs();
|
||||
} else {
|
||||
Log::Info(Event::General, "no style loaded");
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include <mbgl/renderer/paint_parameters.hpp>
|
||||
#include <mbgl/renderer/render_tile.hpp>
|
||||
#include <mbgl/renderer/render_source.hpp>
|
||||
#include <mbgl/renderer/render_style.hpp>
|
||||
|
||||
#include <mbgl/style/source.hpp>
|
||||
#include <mbgl/style/source_impl.hpp>
|
||||
@@ -11,7 +12,6 @@
|
||||
#include <mbgl/util/logging.hpp>
|
||||
#include <mbgl/gl/debugging.hpp>
|
||||
|
||||
#include <mbgl/style/style.hpp>
|
||||
#include <mbgl/style/layer_impl.hpp>
|
||||
#include <mbgl/style/layers/custom_layer_impl.hpp>
|
||||
|
||||
@@ -126,7 +126,7 @@ void Painter::cleanup() {
|
||||
context.performCleanup();
|
||||
}
|
||||
|
||||
void Painter::render(const Style& style, const FrameData& frame_, View& view) {
|
||||
void Painter::render(RenderStyle& style, const FrameData& frame_, View& view) {
|
||||
frame = frame_;
|
||||
if (frame.contextMode == GLContextMode::Shared) {
|
||||
context.setDirtyState();
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <mbgl/renderer/frame_history.hpp>
|
||||
#include <mbgl/renderer/render_item.hpp>
|
||||
#include <mbgl/renderer/bucket.hpp>
|
||||
#include <mbgl/renderer/render_light.hpp>
|
||||
|
||||
#include <mbgl/gl/context.hpp>
|
||||
#include <mbgl/programs/debug_program.hpp>
|
||||
@@ -15,8 +16,6 @@
|
||||
#include <mbgl/programs/extrusion_texture_program.hpp>
|
||||
#include <mbgl/programs/raster_program.hpp>
|
||||
|
||||
#include <mbgl/style/style.hpp>
|
||||
|
||||
#include <mbgl/util/noncopyable.hpp>
|
||||
#include <mbgl/util/chrono.hpp>
|
||||
#include <mbgl/util/constants.hpp>
|
||||
@@ -29,6 +28,7 @@
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class RenderStyle;
|
||||
class RenderTile;
|
||||
class SpriteAtlas;
|
||||
class View;
|
||||
@@ -59,11 +59,6 @@ class TilePyramid;
|
||||
|
||||
struct ClipID;
|
||||
|
||||
namespace style {
|
||||
class Style;
|
||||
class Source;
|
||||
} // namespace style
|
||||
|
||||
struct FrameData {
|
||||
TimePoint timePoint;
|
||||
float pixelRatio;
|
||||
@@ -77,7 +72,7 @@ public:
|
||||
Painter(gl::Context&, const TransformState&, float pixelRatio, const std::string& programCacheDir);
|
||||
~Painter();
|
||||
|
||||
void render(const style::Style&,
|
||||
void render(RenderStyle&,
|
||||
const FrameData&,
|
||||
View&);
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ namespace mbgl {
|
||||
class Painter;
|
||||
class TransformState;
|
||||
class RenderTile;
|
||||
class RenderStyle;
|
||||
class RenderLayer;
|
||||
class RenderedQueryOptions;
|
||||
class SourceQueryOptions;
|
||||
@@ -25,10 +26,6 @@ class Tile;
|
||||
class RenderSourceObserver;
|
||||
class TileParameters;
|
||||
|
||||
namespace style {
|
||||
class Style;
|
||||
} // namespace style
|
||||
|
||||
namespace algorithm {
|
||||
class ClipIDGenerator;
|
||||
} // namespace algorithm
|
||||
@@ -72,7 +69,7 @@ public:
|
||||
virtual std::unordered_map<std::string, std::vector<Feature>>
|
||||
queryRenderedFeatures(const ScreenLineString& geometry,
|
||||
const TransformState& transformState,
|
||||
const style::Style& style,
|
||||
const RenderStyle& style,
|
||||
const RenderedQueryOptions& options) const = 0;
|
||||
|
||||
virtual std::vector<Feature>
|
||||
|
||||
445
src/mbgl/renderer/render_style.cpp
Normal file
445
src/mbgl/renderer/render_style.cpp
Normal file
@@ -0,0 +1,445 @@
|
||||
#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/style/style.hpp>
|
||||
#include <mbgl/style/source_impl.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/sprite/sprite_atlas.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_),
|
||||
glyphAtlas(std::make_unique<GlyphAtlas>(Size{ 2048, 2048 }, fileSource)),
|
||||
spriteAtlas(std::make_unique<SpriteAtlas>()),
|
||||
lineAtlas(std::make_unique<LineAtlas>(Size{ 256, 512 })),
|
||||
renderLight(makeMutable<Light::Impl>()),
|
||||
observer(&nullObserver) {
|
||||
glyphAtlas->setObserver(this);
|
||||
}
|
||||
|
||||
RenderStyle::~RenderStyle() = default;
|
||||
|
||||
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) {
|
||||
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_FADE_DURATION : Duration::zero()
|
||||
};
|
||||
|
||||
const TileParameters tileParameters {
|
||||
parameters.pixelRatio,
|
||||
parameters.debugOptions,
|
||||
parameters.transformState,
|
||||
parameters.scheduler,
|
||||
parameters.fileSource,
|
||||
parameters.mode,
|
||||
parameters.annotationManager,
|
||||
*spriteAtlas,
|
||||
*glyphAtlas
|
||||
};
|
||||
|
||||
glyphAtlas->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) {
|
||||
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 (parameters.spriteLoaded && !spriteAtlas->isLoaded()) {
|
||||
spriteAtlas->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[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, 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 (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);
|
||||
}
|
||||
}
|
||||
|
||||
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 (!spriteAtlas->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[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();
|
||||
}
|
||||
|
||||
spriteAtlas->dumpDebugLogs();
|
||||
}
|
||||
|
||||
} // namespace mbgl
|
||||
93
src/mbgl/renderer/render_style.hpp
Normal file
93
src/mbgl/renderer/render_style.hpp
Normal file
@@ -0,0 +1,93 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/style/image.hpp>
|
||||
#include <mbgl/renderer/render_source.hpp>
|
||||
#include <mbgl/renderer/render_source_observer.hpp>
|
||||
#include <mbgl/renderer/render_layer.hpp>
|
||||
#include <mbgl/renderer/render_light.hpp>
|
||||
#include <mbgl/text/glyph_atlas_observer.hpp>
|
||||
#include <mbgl/map/zoom_history.hpp>
|
||||
#include <mbgl/map/mode.hpp>
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class FileSource;
|
||||
class GlyphAtlas;
|
||||
class SpriteAtlas;
|
||||
class LineAtlas;
|
||||
class RenderData;
|
||||
class TransformState;
|
||||
class RenderedQueryOptions;
|
||||
class Scheduler;
|
||||
class UpdateParameters;
|
||||
class RenderStyleObserver;
|
||||
|
||||
namespace style {
|
||||
class Image;
|
||||
class Source;
|
||||
class Layer;
|
||||
} // namespace style
|
||||
|
||||
class RenderStyle : public GlyphAtlasObserver,
|
||||
public RenderSourceObserver {
|
||||
public:
|
||||
RenderStyle(Scheduler&, FileSource&);
|
||||
~RenderStyle() final;
|
||||
|
||||
void setObserver(RenderStyleObserver*);
|
||||
void update(const UpdateParameters&);
|
||||
|
||||
bool isLoaded() const;
|
||||
bool hasTransitions() const;
|
||||
|
||||
RenderSource* getRenderSource(const std::string& id) const;
|
||||
|
||||
std::vector<const RenderLayer*> getRenderLayers() const;
|
||||
|
||||
RenderLayer* getRenderLayer(const std::string& id);
|
||||
const RenderLayer* getRenderLayer(const std::string& id) const;
|
||||
|
||||
const RenderLight& getRenderLight() const;
|
||||
|
||||
RenderData getRenderData(MapDebugOptions, float angle);
|
||||
|
||||
std::vector<Feature> queryRenderedFeatures(const ScreenLineString& geometry,
|
||||
const TransformState& transformState,
|
||||
const RenderedQueryOptions& options) const;
|
||||
|
||||
void setSourceTileCacheSize(size_t);
|
||||
void onLowMemory();
|
||||
|
||||
void dumpDebugLogs() const;
|
||||
|
||||
Scheduler& scheduler;
|
||||
FileSource& fileSource;
|
||||
std::unique_ptr<GlyphAtlas> glyphAtlas;
|
||||
std::unique_ptr<SpriteAtlas> spriteAtlas;
|
||||
std::unique_ptr<LineAtlas> lineAtlas;
|
||||
|
||||
private:
|
||||
std::vector<Immutable<style::Image::Impl>> imageImpls;
|
||||
std::vector<Immutable<style::Source::Impl>> sourceImpls;
|
||||
std::vector<Immutable<style::Layer::Impl>> layerImpls;
|
||||
|
||||
std::unordered_map<std::string, std::unique_ptr<RenderSource>> renderSources;
|
||||
std::unordered_map<std::string, std::unique_ptr<RenderLayer>> renderLayers;
|
||||
RenderLight renderLight;
|
||||
|
||||
// GlyphAtlasObserver implementation.
|
||||
void onGlyphsError(const FontStack&, const GlyphRange&, std::exception_ptr) override;
|
||||
|
||||
// RenderSourceObserver implementation.
|
||||
void onTileChanged(RenderSource&, const OverscaledTileID&) override;
|
||||
void onTileError(RenderSource&, const OverscaledTileID&, std::exception_ptr) override;
|
||||
|
||||
RenderStyleObserver* observer;
|
||||
ZoomHistory zoomHistory;
|
||||
};
|
||||
|
||||
} // namespace mbgl
|
||||
14
src/mbgl/renderer/render_style_observer.hpp
Normal file
14
src/mbgl/renderer/render_style_observer.hpp
Normal file
@@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include <exception>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class RenderStyleObserver {
|
||||
public:
|
||||
virtual ~RenderStyleObserver() = default;
|
||||
virtual void onInvalidate() {}
|
||||
virtual void onResourceError(std::exception_ptr) {}
|
||||
};
|
||||
|
||||
} // namespace mbgl
|
||||
@@ -74,7 +74,7 @@ std::map<UnwrappedTileID, RenderTile>& RenderGeoJSONSource::getRenderTiles() {
|
||||
std::unordered_map<std::string, std::vector<Feature>>
|
||||
RenderGeoJSONSource::queryRenderedFeatures(const ScreenLineString& geometry,
|
||||
const TransformState& transformState,
|
||||
const style::Style& style,
|
||||
const RenderStyle& style,
|
||||
const RenderedQueryOptions& options) const {
|
||||
return tilePyramid.queryRenderedFeatures(geometry, transformState, style, options);
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ public:
|
||||
std::unordered_map<std::string, std::vector<Feature>>
|
||||
queryRenderedFeatures(const ScreenLineString& geometry,
|
||||
const TransformState& transformState,
|
||||
const style::Style& style,
|
||||
const RenderStyle& style,
|
||||
const RenderedQueryOptions& options) const final;
|
||||
|
||||
std::vector<Feature>
|
||||
|
||||
@@ -57,7 +57,7 @@ void RenderImageSource::finishRender(Painter& painter) {
|
||||
std::unordered_map<std::string, std::vector<Feature>>
|
||||
RenderImageSource::queryRenderedFeatures(const ScreenLineString&,
|
||||
const TransformState&,
|
||||
const style::Style&,
|
||||
const RenderStyle&,
|
||||
const RenderedQueryOptions&) const {
|
||||
return {};
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ public:
|
||||
std::unordered_map<std::string, std::vector<Feature>>
|
||||
queryRenderedFeatures(const ScreenLineString& geometry,
|
||||
const TransformState& transformState,
|
||||
const style::Style& style,
|
||||
const RenderStyle& style,
|
||||
const RenderedQueryOptions& options) const final;
|
||||
|
||||
std::vector<Feature> querySourceFeatures(const SourceQueryOptions&) const final;
|
||||
|
||||
@@ -71,7 +71,7 @@ std::map<UnwrappedTileID, RenderTile>& RenderRasterSource::getRenderTiles() {
|
||||
std::unordered_map<std::string, std::vector<Feature>>
|
||||
RenderRasterSource::queryRenderedFeatures(const ScreenLineString&,
|
||||
const TransformState&,
|
||||
const style::Style&,
|
||||
const RenderStyle&,
|
||||
const RenderedQueryOptions&) const {
|
||||
return {};
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ public:
|
||||
std::unordered_map<std::string, std::vector<Feature>>
|
||||
queryRenderedFeatures(const ScreenLineString& geometry,
|
||||
const TransformState& transformState,
|
||||
const style::Style& style,
|
||||
const RenderStyle& style,
|
||||
const RenderedQueryOptions& options) const final;
|
||||
|
||||
std::vector<Feature>
|
||||
|
||||
@@ -75,7 +75,7 @@ std::map<UnwrappedTileID, RenderTile>& RenderVectorSource::getRenderTiles() {
|
||||
std::unordered_map<std::string, std::vector<Feature>>
|
||||
RenderVectorSource::queryRenderedFeatures(const ScreenLineString& geometry,
|
||||
const TransformState& transformState,
|
||||
const style::Style& style,
|
||||
const RenderStyle& style,
|
||||
const RenderedQueryOptions& options) const {
|
||||
return tilePyramid.queryRenderedFeatures(geometry, transformState, style, options);
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ public:
|
||||
std::unordered_map<std::string, std::vector<Feature>>
|
||||
queryRenderedFeatures(const ScreenLineString& geometry,
|
||||
const TransformState& transformState,
|
||||
const style::Style& style,
|
||||
const RenderStyle& style,
|
||||
const RenderedQueryOptions& options) const final;
|
||||
|
||||
std::vector<Feature>
|
||||
|
||||
@@ -186,7 +186,7 @@ void TilePyramid::removeStaleTiles(const std::set<OverscaledTileID>& retain) {
|
||||
|
||||
std::unordered_map<std::string, std::vector<Feature>> TilePyramid::queryRenderedFeatures(const ScreenLineString& geometry,
|
||||
const TransformState& transformState,
|
||||
const style::Style& style,
|
||||
const RenderStyle& style,
|
||||
const RenderedQueryOptions& options) const {
|
||||
std::unordered_map<std::string, std::vector<Feature>> result;
|
||||
if (renderTiles.empty() || geometry.empty()) {
|
||||
|
||||
@@ -21,14 +21,11 @@ namespace mbgl {
|
||||
class Painter;
|
||||
class TransformState;
|
||||
class RenderTile;
|
||||
class RenderStyle;
|
||||
class RenderedQueryOptions;
|
||||
class SourceQueryOptions;
|
||||
class TileParameters;
|
||||
|
||||
namespace style {
|
||||
class Style;
|
||||
} // namespace style
|
||||
|
||||
class TilePyramid {
|
||||
public:
|
||||
TilePyramid();
|
||||
@@ -55,7 +52,7 @@ public:
|
||||
std::unordered_map<std::string, std::vector<Feature>>
|
||||
queryRenderedFeatures(const ScreenLineString& geometry,
|
||||
const TransformState& transformState,
|
||||
const style::Style& style,
|
||||
const RenderStyle& style,
|
||||
const RenderedQueryOptions& options) const;
|
||||
|
||||
std::vector<Feature> querySourceFeatures(const SourceQueryOptions&) const;
|
||||
|
||||
@@ -13,14 +13,22 @@ class AnnotationManager;
|
||||
class UpdateParameters {
|
||||
public:
|
||||
const MapMode mode;
|
||||
const Update updateFlags;
|
||||
const float pixelRatio;
|
||||
const MapDebugOptions debugOptions;
|
||||
const TimePoint timePoint;
|
||||
const TransformState& transformState;
|
||||
|
||||
const std::string glyphURL;
|
||||
const bool spriteLoaded;
|
||||
const style::TransitionOptions transitionOptions;
|
||||
const Immutable<style::Light::Impl> light;
|
||||
const std::vector<Immutable<style::Image::Impl>> images;
|
||||
const std::vector<Immutable<style::Source::Impl>> sources;
|
||||
const std::vector<Immutable<style::Layer::Impl>> layers;
|
||||
|
||||
Scheduler& scheduler;
|
||||
FileSource& fileSource;
|
||||
AnnotationManager& annotationManager;
|
||||
const TransformState& transformState;
|
||||
};
|
||||
|
||||
} // namespace mbgl
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& entry : renderSources) {
|
||||
entry.second->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;
|
||||
}
|
||||
|
||||
spriteAtlas->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;
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
@@ -5,49 +5,30 @@
|
||||
#include <mbgl/style/source_observer.hpp>
|
||||
#include <mbgl/style/layer_observer.hpp>
|
||||
#include <mbgl/style/light_observer.hpp>
|
||||
#include <mbgl/style/image.hpp>
|
||||
#include <mbgl/renderer/render_source.hpp>
|
||||
#include <mbgl/renderer/render_source_observer.hpp>
|
||||
#include <mbgl/renderer/render_layer.hpp>
|
||||
#include <mbgl/renderer/render_light.hpp>
|
||||
#include <mbgl/text/glyph_atlas_observer.hpp>
|
||||
#include <mbgl/sprite/sprite_loader_observer.hpp>
|
||||
#include <mbgl/map/mode.hpp>
|
||||
#include <mbgl/map/zoom_history.hpp>
|
||||
#include <mbgl/style/image.hpp>
|
||||
#include <mbgl/style/source.hpp>
|
||||
#include <mbgl/style/layer.hpp>
|
||||
|
||||
#include <mbgl/util/noncopyable.hpp>
|
||||
#include <mbgl/util/chrono.hpp>
|
||||
#include <mbgl/util/optional.hpp>
|
||||
#include <mbgl/util/feature.hpp>
|
||||
#include <mbgl/util/geo.hpp>
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class FileSource;
|
||||
class GlyphAtlas;
|
||||
class SpriteAtlas;
|
||||
class SpriteLoader;
|
||||
class LineAtlas;
|
||||
class RenderData;
|
||||
class TransformState;
|
||||
class RenderedQueryOptions;
|
||||
class Scheduler;
|
||||
class UpdateParameters;
|
||||
class FileSource;
|
||||
class SpriteLoader;
|
||||
|
||||
namespace style {
|
||||
|
||||
class Layer;
|
||||
class QueryParameters;
|
||||
|
||||
class Style : public GlyphAtlasObserver,
|
||||
public SpriteLoaderObserver,
|
||||
class Style : public SpriteLoaderObserver,
|
||||
public SourceObserver,
|
||||
public RenderSourceObserver,
|
||||
public LayerObserver,
|
||||
public LightObserver,
|
||||
public util::noncopyable {
|
||||
@@ -61,32 +42,21 @@ public:
|
||||
|
||||
bool isLoaded() const;
|
||||
|
||||
void update(const UpdateParameters&);
|
||||
|
||||
bool hasTransitions() const;
|
||||
|
||||
std::exception_ptr getLastError() const {
|
||||
return lastError;
|
||||
}
|
||||
|
||||
std::vector<const Source*> getSources() const;
|
||||
std::vector<Source*> getSources();
|
||||
Source* getSource(const std::string& id) const;
|
||||
void addSource(std::unique_ptr<Source>);
|
||||
std::unique_ptr<Source> removeSource(const std::string& sourceID);
|
||||
|
||||
std::vector<const Layer*> getLayers() const;
|
||||
std::vector<Layer*> getLayers();
|
||||
Layer* getLayer(const std::string& id) const;
|
||||
Layer* addLayer(std::unique_ptr<Layer>,
|
||||
optional<std::string> beforeLayerID = {});
|
||||
std::unique_ptr<Layer> removeLayer(const std::string& layerID);
|
||||
|
||||
// Should be moved to Impl eventually
|
||||
std::vector<const RenderLayer*> getRenderLayers() const;
|
||||
std::vector<RenderLayer*> getRenderLayers();
|
||||
RenderLayer* getRenderLayer(const std::string& id) const;
|
||||
|
||||
std::string getName() const;
|
||||
LatLng getDefaultLatLng() const;
|
||||
double getDefaultZoom() const;
|
||||
@@ -98,33 +68,28 @@ public:
|
||||
|
||||
void setLight(std::unique_ptr<Light>);
|
||||
Light* getLight() const;
|
||||
const RenderLight& getRenderLight() const;
|
||||
|
||||
const style::Image* getImage(const std::string&) const;
|
||||
void addImage(std::unique_ptr<style::Image>);
|
||||
void removeImage(const std::string&);
|
||||
|
||||
RenderData getRenderData(MapDebugOptions, float angle) const;
|
||||
const std::string& getGlyphURL() const;
|
||||
|
||||
std::vector<Feature> queryRenderedFeatures(const ScreenLineString& geometry,
|
||||
const TransformState& transformState,
|
||||
const RenderedQueryOptions& options) const;
|
||||
|
||||
void setSourceTileCacheSize(size_t);
|
||||
void onLowMemory();
|
||||
std::vector<Immutable<Image::Impl>> getImageImpls() const;
|
||||
std::vector<Immutable<Source::Impl>> getSourceImpls() const;
|
||||
std::vector<Immutable<Layer::Impl>> getLayerImpls() const;
|
||||
|
||||
void dumpDebugLogs() const;
|
||||
|
||||
Scheduler& scheduler;
|
||||
FileSource& fileSource;
|
||||
std::unique_ptr<GlyphAtlas> glyphAtlas;
|
||||
std::unique_ptr<SpriteLoader> spriteLoader;
|
||||
std::unique_ptr<SpriteAtlas> spriteAtlas;
|
||||
std::unique_ptr<LineAtlas> lineAtlas;
|
||||
|
||||
RenderSource* getRenderSource(const std::string& id) const;
|
||||
bool loaded = false;
|
||||
bool spriteLoaded = false;
|
||||
|
||||
private:
|
||||
Scheduler& scheduler;
|
||||
FileSource& fileSource;
|
||||
std::unique_ptr<SpriteLoader> spriteLoader;
|
||||
std::string glyphURL;
|
||||
|
||||
std::unordered_map<std::string, std::unique_ptr<style::Image>> images;
|
||||
std::vector<std::unique_ptr<Source>> sources;
|
||||
std::vector<std::unique_ptr<Layer>> layers;
|
||||
@@ -138,19 +103,8 @@ private:
|
||||
double defaultBearing = 0;
|
||||
double defaultPitch = 0;
|
||||
|
||||
std::vector<Immutable<Image::Impl>> imageImpls;
|
||||
std::vector<Immutable<Source::Impl>> sourceImpls;
|
||||
std::vector<Immutable<Layer::Impl>> layerImpls;
|
||||
|
||||
std::unordered_map<std::string, std::unique_ptr<RenderSource>> renderSources;
|
||||
std::unordered_map<std::string, std::unique_ptr<RenderLayer>> renderLayers;
|
||||
RenderLight renderLight;
|
||||
|
||||
std::vector<std::unique_ptr<Layer>>::const_iterator findLayer(const std::string& layerID) const;
|
||||
|
||||
// GlyphAtlasObserver implementation.
|
||||
void onGlyphsError(const FontStack&, const GlyphRange&, std::exception_ptr) override;
|
||||
|
||||
// SpriteLoaderObserver implementation.
|
||||
void onSpriteLoaded(std::vector<std::unique_ptr<Image>>&&) override;
|
||||
void onSpriteError(std::exception_ptr) override;
|
||||
@@ -160,8 +114,6 @@ private:
|
||||
void onSourceChanged(Source&) override;
|
||||
void onSourceError(Source&, std::exception_ptr) override;
|
||||
void onSourceDescriptionChanged(Source&) override;
|
||||
void onTileChanged(RenderSource&, const OverscaledTileID&) override;
|
||||
void onTileError(RenderSource&, const OverscaledTileID&, std::exception_ptr) override;
|
||||
|
||||
// LayerObserver implementation.
|
||||
void onLayerChanged(Layer&) override;
|
||||
@@ -173,12 +125,6 @@ private:
|
||||
Observer* observer = &nullObserver;
|
||||
|
||||
std::exception_ptr lastError;
|
||||
|
||||
ZoomHistory zoomHistory;
|
||||
bool spriteLoaded = false;
|
||||
|
||||
public:
|
||||
bool loaded = false;
|
||||
};
|
||||
|
||||
} // namespace style
|
||||
|
||||
@@ -176,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 RenderStyle& style,
|
||||
const RenderedQueryOptions& options) {
|
||||
|
||||
if (!featureIndex || !data) return;
|
||||
|
||||
@@ -19,6 +19,7 @@ namespace mbgl {
|
||||
class GeometryTileData;
|
||||
class FeatureIndex;
|
||||
class CollisionTile;
|
||||
class RenderStyle;
|
||||
class RenderLayer;
|
||||
class SourceQueryOptions;
|
||||
class TileParameters;
|
||||
@@ -49,7 +50,7 @@ public:
|
||||
std::unordered_map<std::string, std::vector<Feature>>& result,
|
||||
const GeometryCoordinates& queryGeometry,
|
||||
const TransformState&,
|
||||
const style::Style&,
|
||||
const RenderStyle&,
|
||||
const RenderedQueryOptions& options) override;
|
||||
|
||||
void querySourceFeatures(
|
||||
|
||||
@@ -33,7 +33,7 @@ void Tile::queryRenderedFeatures(
|
||||
std::unordered_map<std::string, std::vector<Feature>>&,
|
||||
const GeometryCoordinates&,
|
||||
const TransformState&,
|
||||
const style::Style&,
|
||||
const RenderStyle&,
|
||||
const RenderedQueryOptions&) {}
|
||||
|
||||
void Tile::querySourceFeatures(
|
||||
|
||||
@@ -22,13 +22,10 @@ class DebugBucket;
|
||||
class TransformState;
|
||||
class TileObserver;
|
||||
class PlacementConfig;
|
||||
class RenderStyle;
|
||||
class RenderedQueryOptions;
|
||||
class SourceQueryOptions;
|
||||
|
||||
namespace style {
|
||||
class Style;
|
||||
} // namespace style
|
||||
|
||||
class Tile : private util::noncopyable {
|
||||
public:
|
||||
Tile(OverscaledTileID);
|
||||
@@ -57,7 +54,7 @@ public:
|
||||
std::unordered_map<std::string, std::vector<Feature>>& result,
|
||||
const GeometryCoordinates& queryGeometry,
|
||||
const TransformState&,
|
||||
const style::Style&,
|
||||
const RenderStyle&,
|
||||
const RenderedQueryOptions& options);
|
||||
|
||||
virtual void querySourceFeatures(
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include <mbgl/util/run_loop.hpp>
|
||||
#include <mbgl/map/transform.hpp>
|
||||
#include <mbgl/map/query.hpp>
|
||||
#include <mbgl/style/style.hpp>
|
||||
#include <mbgl/renderer/render_style.hpp>
|
||||
#include <mbgl/renderer/tile_parameters.hpp>
|
||||
#include <mbgl/map/query.hpp>
|
||||
#include <mbgl/text/collision_tile.hpp>
|
||||
@@ -26,7 +26,7 @@ public:
|
||||
util::RunLoop loop;
|
||||
ThreadPool threadPool { 1 };
|
||||
AnnotationManager annotationManager;
|
||||
style::Style style { threadPool, fileSource, 1.0 };
|
||||
RenderStyle style { threadPool, fileSource };
|
||||
SpriteAtlas spriteAtlas;
|
||||
GlyphAtlas glyphAtlas { { 512, 512, }, fileSource };
|
||||
|
||||
|
||||
Reference in New Issue
Block a user