@@ -30,7 +30,6 @@ class LayerDescription;
|
||||
class Sprite;
|
||||
class Style;
|
||||
class StyleLayer;
|
||||
class StyleSource;
|
||||
class TexturePool;
|
||||
class FileSource;
|
||||
class View;
|
||||
@@ -175,7 +174,6 @@ private:
|
||||
void setup();
|
||||
|
||||
void updateTiles();
|
||||
void updateSources();
|
||||
|
||||
// Triggered by triggerUpdate();
|
||||
void update();
|
||||
@@ -249,8 +247,6 @@ private:
|
||||
|
||||
const std::unique_ptr<MapData> data;
|
||||
|
||||
std::set<util::ptr<StyleSource>> activeSources;
|
||||
|
||||
std::atomic<UpdateType> updated;
|
||||
|
||||
std::mutex mutexTask;
|
||||
|
||||
@@ -90,7 +90,6 @@ Map::~Map() {
|
||||
"MapandMain");
|
||||
|
||||
// Explicitly reset all pointers.
|
||||
activeSources.clear();
|
||||
sprite.reset();
|
||||
glyphStore.reset();
|
||||
style.reset();
|
||||
@@ -129,11 +128,6 @@ void Map::start(bool startPaused) {
|
||||
// Remove all of these to make sure they are destructed in the correct thread.
|
||||
style.reset();
|
||||
|
||||
// Since we don't have a stylesheet anymore, this will disable all Sources and cancel
|
||||
// their associated requests.
|
||||
updateSources();
|
||||
assert(activeSources.empty());
|
||||
|
||||
// It's now safe to destroy/join the workers since there won't be any more callbacks that
|
||||
// could dispatch to the worker pool.
|
||||
workers.reset();
|
||||
@@ -624,9 +618,10 @@ LatLngBounds Map::getBoundsForAnnotations(const std::vector<uint32_t>& annotatio
|
||||
|
||||
void Map::updateAnnotationTiles(const std::vector<Tile::ID>& ids) {
|
||||
assert(Environment::currentlyOn(ThreadType::Map));
|
||||
for (const auto &source : activeSources) {
|
||||
if (!style) return;
|
||||
for (const auto &source : style->sources) {
|
||||
if (source->info.type == SourceType::Annotations) {
|
||||
source->source->invalidateTiles(*this, ids);
|
||||
source->invalidateTiles(*this, ids);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -689,45 +684,11 @@ Duration Map::getDefaultTransitionDuration() {
|
||||
return data->getDefaultTransitionDuration();
|
||||
}
|
||||
|
||||
void Map::updateSources() {
|
||||
assert(Environment::currentlyOn(ThreadType::Map));
|
||||
|
||||
// First, disable all existing sources.
|
||||
for (const auto& source : activeSources) {
|
||||
source->enabled = false;
|
||||
}
|
||||
|
||||
// Then, reenable all of those that we actually use when drawing this layer.
|
||||
if (style) {
|
||||
for (const auto& layer : style->layers) {
|
||||
if (layer->bucket && layer->bucket->style_source) {
|
||||
(*activeSources.emplace(layer->bucket->style_source).first)->enabled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Then, construct or destroy the actual source object, depending on enabled state.
|
||||
for (const auto& source : activeSources) {
|
||||
if (source->enabled) {
|
||||
if (!source->source) {
|
||||
source->source = std::make_shared<Source>(source->info);
|
||||
source->source->load(*this, *env);
|
||||
}
|
||||
} else {
|
||||
source->source.reset();
|
||||
}
|
||||
}
|
||||
|
||||
// Finally, remove all sources that are disabled.
|
||||
util::erase_if(activeSources, [](util::ptr<StyleSource> source){
|
||||
return !source->enabled;
|
||||
});
|
||||
}
|
||||
|
||||
void Map::updateTiles() {
|
||||
assert(Environment::currentlyOn(ThreadType::Map));
|
||||
for (const auto& source : activeSources) {
|
||||
source->source->update(*this, getWorker(), style, *glyphAtlas, *glyphStore,
|
||||
if (!style) return;
|
||||
for (const auto& source : style->sources) {
|
||||
source->update(*this, getWorker(), style, *glyphAtlas, *glyphStore,
|
||||
*spriteAtlas, getSprite(), *texturePool, [this]() {
|
||||
assert(Environment::currentlyOn(ThreadType::Map));
|
||||
triggerUpdate();
|
||||
@@ -779,6 +740,10 @@ void Map::loadStyleJSON(const std::string& json, const std::string& base) {
|
||||
const std::string glyphURL = util::mapbox::normalizeGlyphsURL(style->glyph_url, getAccessToken());
|
||||
glyphStore->setURL(glyphURL);
|
||||
|
||||
for (const auto& source : style->sources) {
|
||||
source->load(*this, *env);
|
||||
}
|
||||
|
||||
triggerUpdate(Update::Zoom);
|
||||
}
|
||||
|
||||
@@ -821,8 +786,6 @@ void Map::prepare() {
|
||||
style->recalculate(state.getNormalizedZoom(), now);
|
||||
}
|
||||
|
||||
updateSources();
|
||||
|
||||
// Allow the sprite atlas to potentially pull new sprite images if needed.
|
||||
spriteAtlas->resize(state.getPixelRatio());
|
||||
spriteAtlas->setSprite(getSprite());
|
||||
@@ -843,8 +806,8 @@ void Map::render() {
|
||||
|
||||
assert(style);
|
||||
assert(painter);
|
||||
painter->render(*style, activeSources,
|
||||
state, data->getAnimationTime());
|
||||
|
||||
painter->render(*style, state, data->getAnimationTime());
|
||||
|
||||
// Schedule another rerender when we definitely need a next frame.
|
||||
if (transform.needsTransition() || style->hasTransitions()) {
|
||||
|
||||
@@ -27,8 +27,7 @@
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
Source::Source(SourceInfo& info_)
|
||||
: info(info_)
|
||||
Source::Source()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ struct box;
|
||||
|
||||
class Source : public std::enable_shared_from_this<Source>, private util::noncopyable {
|
||||
public:
|
||||
Source(SourceInfo&);
|
||||
Source();
|
||||
|
||||
void load(Map &, Environment &);
|
||||
void update(Map &, uv::worker &, util::ptr<Style>, GlyphAtlas &, GlyphStore &,
|
||||
@@ -49,6 +49,9 @@ public:
|
||||
std::forward_list<Tile *> getLoadedTiles() const;
|
||||
void updateClipIDs(const std::map<Tile::ID, ClipID> &mapping);
|
||||
|
||||
SourceInfo info;
|
||||
bool enabled;
|
||||
|
||||
private:
|
||||
bool findLoadedChildren(const Tile::ID& id, int32_t maxCoveringZoom, std::forward_list<Tile::ID>& retain);
|
||||
bool findLoadedParent(const Tile::ID& id, int32_t minCoveringZoom, std::forward_list<Tile::ID>& retain);
|
||||
@@ -63,7 +66,6 @@ private:
|
||||
|
||||
double getZoom(const TransformState &state) const;
|
||||
|
||||
SourceInfo& info;
|
||||
bool loaded = false;
|
||||
|
||||
// Stores the time when this source was most recently updated.
|
||||
|
||||
@@ -215,19 +215,25 @@ void Painter::prepareTile(const Tile& tile) {
|
||||
MBGL_CHECK_ERROR(glStencilFunc(GL_EQUAL, ref, mask));
|
||||
}
|
||||
|
||||
void Painter::render(const Style& style, const std::set<util::ptr<StyleSource>>& sources,
|
||||
TransformState state_, TimePoint time) {
|
||||
void Painter::render(const Style& style, TransformState state_, TimePoint time) {
|
||||
state = state_;
|
||||
|
||||
clear();
|
||||
resize();
|
||||
changeMatrix();
|
||||
|
||||
std::set<Source*> sources;
|
||||
for (const auto& source : style.sources) {
|
||||
if (source->enabled) {
|
||||
sources.insert(source.get());
|
||||
}
|
||||
}
|
||||
|
||||
// Update all clipping IDs.
|
||||
ClipIDGenerator generator;
|
||||
for (const auto& source : sources) {
|
||||
generator.update(source->source->getLoadedTiles());
|
||||
source->source->updateMatrices(projMatrix, state);
|
||||
generator.update(source->getLoadedTiles());
|
||||
source->updateMatrices(projMatrix, state);
|
||||
}
|
||||
|
||||
drawClippingMasks(sources);
|
||||
@@ -280,7 +286,7 @@ void Painter::render(const Style& style, const std::set<util::ptr<StyleSource>>&
|
||||
// When only rendering layers via the stylesheet, it's possible that we don't
|
||||
// ever visit a tile during rendering.
|
||||
for (const auto& source : sources) {
|
||||
source->source->finishRender(*this);
|
||||
source->finishRender(*this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -302,18 +308,11 @@ void Painter::renderLayer(const StyleLayer &layer_desc) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!layer_desc.bucket->style_source) {
|
||||
if (!layer_desc.bucket->source) {
|
||||
Log::Warning(Event::Render, "can't find source for layer '%s'", layer_desc.id.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
StyleSource const& style_source = *layer_desc.bucket->style_source;
|
||||
|
||||
// Skip this layer if there is no data.
|
||||
if (!style_source.source) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Skip this layer if it's outside the range of min/maxzoom.
|
||||
// This may occur when there /is/ a bucket created for this layer, but the min/max-zoom
|
||||
// is set to a fractional value, or value that is larger than the source maxzoom.
|
||||
@@ -350,7 +349,7 @@ void Painter::renderLayer(const StyleLayer &layer_desc) {
|
||||
StyleLayerTypeClass(layer_desc.type).c_str());
|
||||
}
|
||||
|
||||
style_source.source->render(*this, layer_desc);
|
||||
layer_desc.bucket->source->render(*this, layer_desc);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -42,7 +42,6 @@ class SpriteAtlas;
|
||||
class GlyphAtlas;
|
||||
class LineAtlas;
|
||||
class Source;
|
||||
class StyleSource;
|
||||
|
||||
class FillBucket;
|
||||
class LineBucket;
|
||||
@@ -76,7 +75,6 @@ public:
|
||||
void changeMatrix();
|
||||
|
||||
void render(const Style& style,
|
||||
const std::set<util::ptr<StyleSource>>& sources,
|
||||
TransformState state,
|
||||
TimePoint time);
|
||||
|
||||
@@ -121,7 +119,7 @@ public:
|
||||
// Configures the painter strata that is used for early z-culling of fragments.
|
||||
void setStrata(float strata);
|
||||
|
||||
void drawClippingMasks(const std::set<util::ptr<StyleSource>> &sources);
|
||||
void drawClippingMasks(const std::set<Source*>&);
|
||||
void drawClippingMask(const mat4& matrix, const ClipID& clip);
|
||||
|
||||
void resetFramebuffer();
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
using namespace mbgl;
|
||||
|
||||
void Painter::drawClippingMasks(const std::set<util::ptr<StyleSource>> &sources) {
|
||||
void Painter::drawClippingMasks(const std::set<Source*>& sources) {
|
||||
gl::group group("clipping masks");
|
||||
|
||||
useProgram(plainShader->program);
|
||||
@@ -18,7 +18,7 @@ void Painter::drawClippingMasks(const std::set<util::ptr<StyleSource>> &sources)
|
||||
coveringPlainArray.bind(*plainShader, tileStencilBuffer, BUFFER_OFFSET(0));
|
||||
|
||||
for (const auto& source : sources) {
|
||||
source->source->drawClippingMasks(*this);
|
||||
source->drawClippingMasks(*this);
|
||||
}
|
||||
|
||||
MBGL_CHECK_ERROR(glEnable(GL_DEPTH_TEST));
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include <mbgl/style/style.hpp>
|
||||
#include <mbgl/map/sprite.hpp>
|
||||
#include <mbgl/map/source.hpp>
|
||||
#include <mbgl/style/style_layer.hpp>
|
||||
#include <mbgl/style/style_parser.hpp>
|
||||
#include <mbgl/style/style_bucket.hpp>
|
||||
@@ -36,10 +37,17 @@ void Style::cascade(const std::vector<std::string>& classes) {
|
||||
void Style::recalculate(float z, TimePoint now) {
|
||||
uv::writelock lock(mtx);
|
||||
|
||||
for (const auto& source : sources) {
|
||||
source->enabled = false;
|
||||
}
|
||||
|
||||
zoomHistory.update(z, now);
|
||||
|
||||
for (const auto& layer : layers) {
|
||||
layer->updateProperties(z, now, zoomHistory);
|
||||
if (layer->bucket && layer->bucket->source) {
|
||||
layer->bucket->source->enabled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,6 +81,7 @@ void Style::loadJSON(const uint8_t *const data) {
|
||||
StyleParser parser;
|
||||
parser.parse(doc);
|
||||
|
||||
sources = parser.getSources();
|
||||
layers = parser.getLayers();
|
||||
sprite_url = parser.getSprite();
|
||||
glyph_url = parser.getGlyphURL();
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class Source;
|
||||
class StyleLayer;
|
||||
|
||||
class Style : public util::noncopyable {
|
||||
@@ -32,6 +33,7 @@ public:
|
||||
|
||||
const std::string &getSpriteURL() const;
|
||||
|
||||
std::vector<util::ptr<Source>> sources;
|
||||
std::vector<util::ptr<StyleLayer>> layers;
|
||||
std::string glyph_url;
|
||||
std::string base;
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class StyleSource;
|
||||
class Source;
|
||||
|
||||
class StyleBucket : public util::noncopyable {
|
||||
public:
|
||||
@@ -20,7 +20,7 @@ public:
|
||||
|
||||
const StyleLayerType type;
|
||||
std::string name;
|
||||
util::ptr<StyleSource> style_source;
|
||||
util::ptr<Source> source;
|
||||
std::string source_layer;
|
||||
FilterExpression filter;
|
||||
ClassProperties layout;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include <mbgl/style/style_source.hpp>
|
||||
#include <mbgl/style/style_parser.hpp>
|
||||
#include <mbgl/map/source.hpp>
|
||||
#include <mbgl/style/style_layer.hpp>
|
||||
#include <mbgl/map/annotation.hpp>
|
||||
#include <mbgl/util/constants.hpp>
|
||||
@@ -59,11 +59,11 @@ void StyleParser::parse(JSVal document) {
|
||||
iconOverlap.AddMember("icon-allow-overlap", true, d.GetAllocator());
|
||||
parseLayout(iconOverlap, pointBucket);
|
||||
|
||||
SourceInfo& info = sources.emplace(id, std::make_shared<StyleSource>()).first->second->info;
|
||||
info.type = SourceType::Annotations;
|
||||
|
||||
auto source_it = sources.find(id);
|
||||
pointBucket->style_source = source_it->second;
|
||||
util::ptr<Source> source = std::make_shared<Source>();
|
||||
sourcesMap.emplace(id, source);
|
||||
sources.emplace_back(source);
|
||||
source->info.type = SourceType::Annotations;
|
||||
pointBucket->source = source;
|
||||
annotations->bucket = pointBucket;
|
||||
//
|
||||
// end point annotations
|
||||
@@ -218,12 +218,13 @@ void StyleParser::parseSources(JSVal value) {
|
||||
rapidjson::Value::ConstMemberIterator itr = value.MemberBegin();
|
||||
for (; itr != value.MemberEnd(); ++itr) {
|
||||
std::string name { itr->name.GetString(), itr->name.GetStringLength() };
|
||||
SourceInfo& info = sources.emplace(name, std::make_shared<StyleSource>()).first->second->info;
|
||||
|
||||
parseRenderProperty<SourceTypeClass>(itr->value, info.type, "type");
|
||||
parseRenderProperty(itr->value, info.url, "url");
|
||||
parseRenderProperty(itr->value, info.tile_size, "tileSize");
|
||||
info.parseTileJSONProperties(itr->value);
|
||||
util::ptr<Source> source = std::make_shared<Source>();
|
||||
parseRenderProperty<SourceTypeClass>(itr->value, source->info.type, "type");
|
||||
parseRenderProperty(itr->value, source->info.url, "url");
|
||||
parseRenderProperty(itr->value, source->info.tile_size, "tileSize");
|
||||
source->info.parseTileJSONProperties(itr->value);
|
||||
sources.emplace_back(source);
|
||||
sourcesMap.emplace(name, source);
|
||||
}
|
||||
} else {
|
||||
Log::Warning(Event::ParseStyle, "sources must be an object");
|
||||
@@ -939,9 +940,9 @@ void StyleParser::parseBucket(JSVal value, util::ptr<StyleLayer> &layer) {
|
||||
JSVal value_source = replaceConstant(value["source"]);
|
||||
if (value_source.IsString()) {
|
||||
const std::string source_name = { value_source.GetString(), value_source.GetStringLength() };
|
||||
auto source_it = sources.find(source_name);
|
||||
if (source_it != sources.end()) {
|
||||
bucket->style_source = source_it->second;
|
||||
auto source_it = sourcesMap.find(source_name);
|
||||
if (source_it != sourcesMap.end()) {
|
||||
bucket->source = source_it->second;
|
||||
} else {
|
||||
Log::Warning(Event::ParseStyle, "can't find source '%s' required for layer '%s'", source_name.c_str(), layer->id.c_str());
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ namespace mbgl {
|
||||
enum class ClassID : uint32_t;
|
||||
|
||||
class StyleLayer;
|
||||
class Source;
|
||||
|
||||
class StyleParser {
|
||||
public:
|
||||
@@ -26,6 +27,10 @@ public:
|
||||
|
||||
void parse(JSVal document);
|
||||
|
||||
std::vector<util::ptr<Source>> getSources() {
|
||||
return sources;
|
||||
}
|
||||
|
||||
std::vector<util::ptr<StyleLayer>> getLayers() {
|
||||
return layers;
|
||||
}
|
||||
@@ -90,12 +95,10 @@ private:
|
||||
private:
|
||||
std::unordered_map<std::string, const rapidjson::Value *> constants;
|
||||
|
||||
std::unordered_map<std::string, const util::ptr<StyleSource>> sources;
|
||||
|
||||
// This stores the root layer.
|
||||
std::vector<util::ptr<Source>> sources;
|
||||
std::vector<util::ptr<StyleLayer>> layers;
|
||||
|
||||
// This maps ids to Layer objects, with all items being at the root level.
|
||||
std::unordered_map<std::string, const util::ptr<Source>> sourcesMap;
|
||||
std::unordered_map<std::string, std::pair<JSVal, util::ptr<StyleLayer>>> layersMap;
|
||||
|
||||
// Store a stack of layers we're parsing right now. This is to prevent reference cycles.
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
#define MBGL_STYLE_STYLE_SOURCE
|
||||
|
||||
#include <mbgl/style/types.hpp>
|
||||
#include <mbgl/util/ptr.hpp>
|
||||
#include <mbgl/util/noncopyable.hpp>
|
||||
#include <rapidjson/document.h>
|
||||
|
||||
@@ -11,8 +10,6 @@
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class Source;
|
||||
|
||||
class SourceInfo : private util::noncopyable {
|
||||
public:
|
||||
SourceType type = SourceType::Vector;
|
||||
@@ -28,14 +25,6 @@ public:
|
||||
void parseTileJSONProperties(const rapidjson::Value&);
|
||||
};
|
||||
|
||||
|
||||
class StyleSource : private util::noncopyable {
|
||||
public:
|
||||
SourceInfo info;
|
||||
bool enabled = false;
|
||||
util::ptr<Source> source;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user