@@ -23,6 +23,7 @@
|
||||
namespace mbgl {
|
||||
|
||||
class Painter;
|
||||
class GlyphStore;
|
||||
class LayerDescription;
|
||||
class Sprite;
|
||||
class Style;
|
||||
@@ -32,6 +33,9 @@ class StyleSource;
|
||||
class TexturePool;
|
||||
class FileSource;
|
||||
class View;
|
||||
class GlyphAtlas;
|
||||
class SpriteAtlas;
|
||||
class LineAtlas;
|
||||
class Environment;
|
||||
|
||||
class Map : private util::noncopyable {
|
||||
@@ -149,6 +153,7 @@ private:
|
||||
void resize(uint16_t width, uint16_t height, float ratio = 1);
|
||||
void resize(uint16_t width, uint16_t height, float ratio, uint16_t fbWidth, uint16_t fbHeight);
|
||||
|
||||
util::ptr<Sprite> getSprite();
|
||||
uv::worker& getWorker();
|
||||
|
||||
// Checks if render thread needs to pause
|
||||
@@ -158,6 +163,8 @@ private:
|
||||
void setup();
|
||||
|
||||
void updateTiles();
|
||||
void updateSources();
|
||||
void updateSources(const util::ptr<StyleLayerGroup> &group);
|
||||
|
||||
// Prepares a map render by updating the tiles we need for the current view, as well as updating
|
||||
// the stylesheet.
|
||||
@@ -206,6 +213,11 @@ private:
|
||||
FileSource& fileSource;
|
||||
|
||||
util::ptr<Style> style;
|
||||
const std::unique_ptr<GlyphAtlas> glyphAtlas;
|
||||
util::ptr<GlyphStore> glyphStore;
|
||||
const std::unique_ptr<SpriteAtlas> spriteAtlas;
|
||||
util::ptr<Sprite> sprite;
|
||||
const std::unique_ptr<LineAtlas> lineAtlas;
|
||||
util::ptr<TexturePool> texturePool;
|
||||
|
||||
const std::unique_ptr<Painter> painter;
|
||||
@@ -219,6 +231,8 @@ private:
|
||||
|
||||
bool debug = false;
|
||||
std::chrono::steady_clock::time_point animationTime = std::chrono::steady_clock::time_point::min();
|
||||
|
||||
std::set<util::ptr<StyleSource>> activeSources;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include <mbgl/map/environment.hpp>
|
||||
#include <mbgl/map/view.hpp>
|
||||
#include <mbgl/platform/platform.hpp>
|
||||
#include <mbgl/map/source.hpp>
|
||||
#include <mbgl/renderer/painter.hpp>
|
||||
#include <mbgl/map/sprite.hpp>
|
||||
#include <mbgl/util/transition.hpp>
|
||||
@@ -12,14 +13,19 @@
|
||||
#include <mbgl/util/uv_detail.hpp>
|
||||
#include <mbgl/util/std.hpp>
|
||||
#include <mbgl/style/style.hpp>
|
||||
#include <mbgl/text/glyph_store.hpp>
|
||||
#include <mbgl/geometry/glyph_atlas.hpp>
|
||||
#include <mbgl/style/style_layer.hpp>
|
||||
#include <mbgl/style/style_layer_group.hpp>
|
||||
#include <mbgl/style/style_bucket.hpp>
|
||||
#include <mbgl/util/texture_pool.hpp>
|
||||
#include <mbgl/geometry/sprite_atlas.hpp>
|
||||
#include <mbgl/geometry/line_atlas.hpp>
|
||||
#include <mbgl/storage/file_source.hpp>
|
||||
#include <mbgl/platform/log.hpp>
|
||||
#include <mbgl/util/string.hpp>
|
||||
#include <mbgl/util/uv.hpp>
|
||||
#include <mbgl/util/mapbox.hpp>
|
||||
#include <mbgl/util/exception.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
@@ -59,8 +65,12 @@ Map::Map(View& view_, FileSource& fileSource_)
|
||||
mapThread(mainThread),
|
||||
transform(view_),
|
||||
fileSource(fileSource_),
|
||||
glyphAtlas(util::make_unique<GlyphAtlas>(1024, 1024)),
|
||||
glyphStore(std::make_shared<GlyphStore>(*env)),
|
||||
spriteAtlas(util::make_unique<SpriteAtlas>(512, 512)),
|
||||
lineAtlas(util::make_unique<LineAtlas>(512, 512)),
|
||||
texturePool(std::make_shared<TexturePool>()),
|
||||
painter(util::make_unique<Painter>())
|
||||
painter(util::make_unique<Painter>(*spriteAtlas, *glyphAtlas, *lineAtlas))
|
||||
{
|
||||
view.initialize(this);
|
||||
}
|
||||
@@ -71,6 +81,9 @@ Map::~Map() {
|
||||
}
|
||||
|
||||
// Explicitly reset all pointers.
|
||||
activeSources.clear();
|
||||
sprite.reset();
|
||||
glyphStore.reset();
|
||||
style.reset();
|
||||
texturePool.reset();
|
||||
workers.reset();
|
||||
@@ -101,6 +114,7 @@ void Map::start(bool startPaused) {
|
||||
// Remove all of these to make sure they are destructed in the correct thread.
|
||||
style.reset();
|
||||
workers.reset();
|
||||
activeSources.clear();
|
||||
|
||||
terminating = true;
|
||||
|
||||
@@ -337,9 +351,9 @@ void Map::setStyleURL(const std::string &url) {
|
||||
void Map::setStyleJSON(std::string newStyleJSON, const std::string &base) {
|
||||
// TODO: Make threadsafe.
|
||||
styleJSON.swap(newStyleJSON);
|
||||
|
||||
sprite.reset();
|
||||
if (!style) {
|
||||
style = std::make_shared<Style>(*env);
|
||||
style = std::make_shared<Style>();
|
||||
}
|
||||
|
||||
style->base = base;
|
||||
@@ -347,6 +361,9 @@ void Map::setStyleJSON(std::string newStyleJSON, const std::string &base) {
|
||||
style->cascadeClasses(classes);
|
||||
style->setDefaultTransitionDuration(defaultTransitionDuration);
|
||||
|
||||
const std::string glyphURL = util::mapbox::normalizeGlyphsURL(style->glyph_url, getAccessToken());
|
||||
glyphStore->setURL(glyphURL);
|
||||
|
||||
triggerUpdate();
|
||||
}
|
||||
|
||||
@@ -354,6 +371,16 @@ std::string Map::getStyleJSON() const {
|
||||
return styleJSON;
|
||||
}
|
||||
|
||||
util::ptr<Sprite> Map::getSprite() {
|
||||
const float pixelRatio = state.getPixelRatio();
|
||||
const std::string &sprite_url = style->getSpriteURL();
|
||||
if (!sprite || sprite->pixelRatio != pixelRatio) {
|
||||
sprite = Sprite::Create(sprite_url, pixelRatio, *env);
|
||||
}
|
||||
|
||||
return sprite;
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - Size
|
||||
|
||||
@@ -577,11 +604,64 @@ std::chrono::steady_clock::duration Map::getDefaultTransitionDuration() {
|
||||
return defaultTransitionDuration;
|
||||
}
|
||||
|
||||
void Map::updateSources() {
|
||||
assert(std::this_thread::get_id() == mapThread);
|
||||
|
||||
// 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.
|
||||
updateSources(style->layers);
|
||||
|
||||
// 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::updateSources(const util::ptr<StyleLayerGroup> &group) {
|
||||
assert(std::this_thread::get_id() == mapThread);
|
||||
if (!group) {
|
||||
return;
|
||||
}
|
||||
for (const util::ptr<StyleLayer> &layer : group->layers) {
|
||||
if (!layer) continue;
|
||||
if (layer->bucket && layer->bucket->style_source) {
|
||||
(*activeSources.emplace(layer->bucket->style_source).first)->enabled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Map::updateTiles() {
|
||||
assert(std::this_thread::get_id() == mapThread);
|
||||
for (const auto &source : activeSources) {
|
||||
source->source->update(*this, *env, getWorker(), style, *glyphAtlas, *glyphStore,
|
||||
*spriteAtlas, getSprite(), *texturePool, [this]() {
|
||||
assert(std::this_thread::get_id() == mapThread);
|
||||
triggerUpdate();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void Map::prepare() {
|
||||
assert(std::this_thread::get_id() == mapThread);
|
||||
|
||||
if (!style) {
|
||||
style = std::make_shared<Style>(*env);
|
||||
style = std::make_shared<Style>();
|
||||
|
||||
env->request({ Resource::Kind::JSON, styleURL}, [&](const Response &res) {
|
||||
if (res.status == Response::Successful) {
|
||||
@@ -608,14 +688,15 @@ void Map::prepare() {
|
||||
state = transform.currentState();
|
||||
|
||||
animationTime = std::chrono::steady_clock::now();
|
||||
|
||||
style->updateSources(*this, *env, *workers, *texturePool, [this]() {
|
||||
assert(std::this_thread::get_id() == mapThread);
|
||||
triggerUpdate();
|
||||
});
|
||||
|
||||
updateSources();
|
||||
style->updateProperties(state.getNormalizedZoom(), animationTime);
|
||||
|
||||
// Allow the sprite atlas to potentially pull new sprite images if needed.
|
||||
spriteAtlas->resize(state.getPixelRatio());
|
||||
spriteAtlas->setSprite(getSprite());
|
||||
|
||||
updateTiles();
|
||||
|
||||
if (mode == Mode::Continuous) {
|
||||
view.invalidate();
|
||||
}
|
||||
@@ -624,7 +705,7 @@ void Map::prepare() {
|
||||
void Map::render() {
|
||||
assert(std::this_thread::get_id() == mapThread);
|
||||
assert(painter);
|
||||
painter->render(*style, style->activeSources,
|
||||
painter->render(*style, activeSources,
|
||||
state, animationTime);
|
||||
// Schedule another rerender when we definitely need a next frame.
|
||||
if (transform.needsTransition() || style->hasTransitions()) {
|
||||
|
||||
@@ -24,7 +24,11 @@ using namespace mbgl;
|
||||
|
||||
#define BUFFER_OFFSET(i) ((char *)nullptr + (i))
|
||||
|
||||
Painter::Painter() {
|
||||
Painter::Painter(SpriteAtlas& spriteAtlas_, GlyphAtlas& glyphAtlas_, LineAtlas& lineAtlas_)
|
||||
: spriteAtlas(spriteAtlas_)
|
||||
, glyphAtlas(glyphAtlas_)
|
||||
, lineAtlas(lineAtlas_)
|
||||
{
|
||||
}
|
||||
|
||||
Painter::~Painter() {
|
||||
@@ -215,10 +219,6 @@ void Painter::render(const Style& style, const std::set<util::ptr<StyleSource>>&
|
||||
TransformState state_, std::chrono::steady_clock::time_point time) {
|
||||
state = state_;
|
||||
|
||||
glyphAtlas = style.glyphAtlas.get();
|
||||
spriteAtlas = style.spriteAtlas.get();
|
||||
lineAtlas = style.lineAtlas.get();
|
||||
|
||||
clear();
|
||||
resize();
|
||||
changeMatrix();
|
||||
@@ -377,8 +377,8 @@ void Painter::renderBackground(const StyleLayer &layer_desc) {
|
||||
if ((properties.opacity >= 1.0f) != (pass == RenderPass::Opaque))
|
||||
return;
|
||||
|
||||
SpriteAtlasPosition imagePosA = spriteAtlas->getPosition(properties.image.from, true);
|
||||
SpriteAtlasPosition imagePosB = spriteAtlas->getPosition(properties.image.to, true);
|
||||
SpriteAtlasPosition imagePosA = spriteAtlas.getPosition(properties.image.from, true);
|
||||
SpriteAtlasPosition imagePosB = spriteAtlas.getPosition(properties.image.to, true);
|
||||
float zoomFraction = state.getZoomFraction();
|
||||
|
||||
useProgram(patternShader->program);
|
||||
@@ -427,7 +427,7 @@ void Painter::renderBackground(const StyleLayer &layer_desc) {
|
||||
|
||||
backgroundBuffer.bind();
|
||||
patternShader->bind(0);
|
||||
spriteAtlas->bind(true);
|
||||
spriteAtlas.bind(true);
|
||||
} else {
|
||||
Color color = properties.color;
|
||||
color[0] *= properties.opacity;
|
||||
|
||||
@@ -59,7 +59,7 @@ class RasterTileData;
|
||||
|
||||
class Painter : private util::noncopyable {
|
||||
public:
|
||||
Painter();
|
||||
Painter(SpriteAtlas&, GlyphAtlas&, LineAtlas&);
|
||||
~Painter();
|
||||
|
||||
void setup();
|
||||
@@ -195,9 +195,9 @@ private:
|
||||
public:
|
||||
FrameHistory frameHistory;
|
||||
|
||||
SpriteAtlas* spriteAtlas;
|
||||
GlyphAtlas* glyphAtlas;
|
||||
LineAtlas* lineAtlas;
|
||||
SpriteAtlas& spriteAtlas;
|
||||
GlyphAtlas& glyphAtlas;
|
||||
LineAtlas& lineAtlas;
|
||||
|
||||
std::unique_ptr<PlainShader> plainShader;
|
||||
std::unique_ptr<OutlineShader> outlineShader;
|
||||
|
||||
@@ -60,8 +60,8 @@ void Painter::renderFill(FillBucket& bucket, const StyleLayer &layer_desc, const
|
||||
if (pattern) {
|
||||
// Image fill.
|
||||
if (pass == RenderPass::Translucent) {
|
||||
const SpriteAtlasPosition posA = spriteAtlas->getPosition(properties.image.from, true);
|
||||
const SpriteAtlasPosition posB = spriteAtlas->getPosition(properties.image.to, true);
|
||||
const SpriteAtlasPosition posA = spriteAtlas.getPosition(properties.image.from, true);
|
||||
const SpriteAtlasPosition posB = spriteAtlas.getPosition(properties.image.to, true);
|
||||
float factor = 8.0 / std::pow(2, state.getIntegerZoom() - id.z);
|
||||
|
||||
mat3 patternMatrixA;
|
||||
@@ -88,7 +88,7 @@ void Painter::renderFill(FillBucket& bucket, const StyleLayer &layer_desc, const
|
||||
patternShader->u_patternmatrix_b = patternMatrixB;
|
||||
|
||||
MBGL_CHECK_ERROR(glActiveTexture(GL_TEXTURE0));
|
||||
spriteAtlas->bind(true);
|
||||
spriteAtlas.bind(true);
|
||||
|
||||
// Draw the actual triangles into the color & stencil buffer.
|
||||
depthRange(strata, 1.0f);
|
||||
|
||||
@@ -83,9 +83,9 @@ void Painter::renderLine(LineBucket& bucket, const StyleLayer &layer_desc, const
|
||||
linesdfShader->u_blur = blur;
|
||||
linesdfShader->u_color = color;
|
||||
|
||||
LinePatternPos posA = lineAtlas->getDashPosition(properties.dash_array.from, layout.cap == CapType::Round);
|
||||
LinePatternPos posB = lineAtlas->getDashPosition(properties.dash_array.to, layout.cap == CapType::Round);
|
||||
lineAtlas->bind();
|
||||
LinePatternPos posA = lineAtlas.getDashPosition(properties.dash_array.from, layout.cap == CapType::Round);
|
||||
LinePatternPos posB = lineAtlas.getDashPosition(properties.dash_array.to, layout.cap == CapType::Round);
|
||||
lineAtlas.bind();
|
||||
|
||||
float patternratio = std::pow(2.0, std::floor(std::log2(state.getScale())) - id.z) / 8.0;
|
||||
float scaleXA = patternratio / posA.width / properties.dash_line_width / properties.dash_array.fromScale;
|
||||
@@ -98,14 +98,14 @@ void Painter::renderLine(LineBucket& bucket, const StyleLayer &layer_desc, const
|
||||
linesdfShader->u_patternscale_b = {{ scaleXB, scaleYB }};
|
||||
linesdfShader->u_tex_y_b = posB.y;
|
||||
linesdfShader->u_image = 0;
|
||||
linesdfShader->u_sdfgamma = lineAtlas->width / (properties.dash_line_width * std::min(posA.width, posB.width) * 256.0 * state.getPixelRatio()) / 2;
|
||||
linesdfShader->u_sdfgamma = lineAtlas.width / (properties.dash_line_width * std::min(posA.width, posB.width) * 256.0 * state.getPixelRatio()) / 2;
|
||||
linesdfShader->u_mix = properties.dash_array.t;
|
||||
|
||||
bucket.drawLineSDF(*linesdfShader);
|
||||
|
||||
} else if (properties.image.from.size()) {
|
||||
SpriteAtlasPosition imagePosA = spriteAtlas->getPosition(properties.image.from, true);
|
||||
SpriteAtlasPosition imagePosB = spriteAtlas->getPosition(properties.image.to, true);
|
||||
SpriteAtlasPosition imagePosA = spriteAtlas.getPosition(properties.image.from, true);
|
||||
SpriteAtlasPosition imagePosB = spriteAtlas.getPosition(properties.image.to, true);
|
||||
|
||||
float factor = 8.0 / std::pow(2, state.getIntegerZoom() - id.z);
|
||||
|
||||
@@ -127,7 +127,7 @@ void Painter::renderLine(LineBucket& bucket, const StyleLayer &layer_desc, const
|
||||
linepatternShader->u_opacity = properties.opacity;
|
||||
|
||||
MBGL_CHECK_ERROR(glActiveTexture(GL_TEXTURE0));
|
||||
spriteAtlas->bind(true);
|
||||
spriteAtlas.bind(true);
|
||||
MBGL_CHECK_ERROR(glDepthRange(strata + strata_epsilon, 1.0f)); // may or may not matter
|
||||
|
||||
bucket.drawLinePatterns(*linepatternShader);
|
||||
|
||||
@@ -135,7 +135,7 @@ void Painter::renderSymbol(SymbolBucket &bucket, const StyleLayer &layer_desc, c
|
||||
const float fontSize = properties.icon.size != 0 ? properties.icon.size : layout.icon.max_size;
|
||||
const float fontScale = fontSize / 1.0f;
|
||||
|
||||
spriteAtlas->bind(state.isChanging() || layout.placement == PlacementType::Line || angleOffset != 0 || fontScale != 1 || sdf);
|
||||
spriteAtlas.bind(state.isChanging() || layout.placement == PlacementType::Line || angleOffset != 0 || fontScale != 1 || sdf);
|
||||
|
||||
if (sdf) {
|
||||
renderSDF(bucket,
|
||||
@@ -144,7 +144,7 @@ void Painter::renderSymbol(SymbolBucket &bucket, const StyleLayer &layer_desc, c
|
||||
layout.icon,
|
||||
properties.icon,
|
||||
1.0f,
|
||||
{{ float(spriteAtlas->getWidth()) / 4.0f, float(spriteAtlas->getHeight()) / 4.0f }},
|
||||
{{ float(spriteAtlas.getWidth()) / 4.0f, float(spriteAtlas.getHeight()) / 4.0f }},
|
||||
*sdfIconShader,
|
||||
&SymbolBucket::drawIcons);
|
||||
} else {
|
||||
@@ -162,7 +162,7 @@ void Painter::renderSymbol(SymbolBucket &bucket, const StyleLayer &layer_desc, c
|
||||
useProgram(iconShader->program);
|
||||
iconShader->u_matrix = vtxMatrix;
|
||||
iconShader->u_exmatrix = exMatrix;
|
||||
iconShader->u_texsize = {{ float(spriteAtlas->getWidth()) / 4.0f, float(spriteAtlas->getHeight()) / 4.0f }};
|
||||
iconShader->u_texsize = {{ float(spriteAtlas.getWidth()) / 4.0f, float(spriteAtlas.getHeight()) / 4.0f }};
|
||||
|
||||
// Convert the -pi..pi to an int8 range.
|
||||
const float angle = std::round(state.getAngle() / M_PI * 128);
|
||||
@@ -189,7 +189,7 @@ void Painter::renderSymbol(SymbolBucket &bucket, const StyleLayer &layer_desc, c
|
||||
}
|
||||
|
||||
if (bucket.hasTextData()) {
|
||||
glyphAtlas->bind();
|
||||
glyphAtlas.bind();
|
||||
|
||||
renderSDF(bucket,
|
||||
id,
|
||||
@@ -197,7 +197,7 @@ void Painter::renderSymbol(SymbolBucket &bucket, const StyleLayer &layer_desc, c
|
||||
layout.text,
|
||||
properties.text,
|
||||
24.0f,
|
||||
{{ float(glyphAtlas->width) / 4, float(glyphAtlas->height) / 4 }},
|
||||
{{ float(glyphAtlas.width) / 4, float(glyphAtlas.height) / 4 }},
|
||||
*sdfGlyphShader,
|
||||
&SymbolBucket::drawGlyphs);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#include <mbgl/style/style.hpp>
|
||||
#include <mbgl/map/sprite.hpp>
|
||||
#include <mbgl/map/source.hpp>
|
||||
#include <mbgl/style/style_layer_group.hpp>
|
||||
#include <mbgl/style/style_parser.hpp>
|
||||
#include <mbgl/style/style_bucket.hpp>
|
||||
@@ -9,13 +8,6 @@
|
||||
#include <mbgl/util/std.hpp>
|
||||
#include <mbgl/util/uv_detail.hpp>
|
||||
#include <mbgl/platform/log.hpp>
|
||||
#include <mbgl/text/glyph_store.hpp>
|
||||
#include <mbgl/geometry/glyph_atlas.hpp>
|
||||
#include <mbgl/geometry/sprite_atlas.hpp>
|
||||
#include <mbgl/geometry/line_atlas.hpp>
|
||||
#include <mbgl/util/mapbox.hpp>
|
||||
#include <mbgl/map/map.hpp>
|
||||
|
||||
#include <csscolorparser/csscolorparser.hpp>
|
||||
|
||||
#include <rapidjson/document.h>
|
||||
@@ -24,76 +16,14 @@
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
Style::Style(Environment& env)
|
||||
: glyphAtlas(util::make_unique<GlyphAtlas>(1024, 1024)),
|
||||
spriteAtlas(util::make_unique<SpriteAtlas>(512, 512)),
|
||||
lineAtlas(util::make_unique<LineAtlas>(512, 512)),
|
||||
mtx(util::make_unique<uv::rwlock>()),
|
||||
glyphStore(util::make_unique<GlyphStore>(env))
|
||||
{
|
||||
Style::Style()
|
||||
: mtx(util::make_unique<uv::rwlock>()) {
|
||||
}
|
||||
|
||||
// Note: This constructor is seemingly empty, but we need to declare it anyway
|
||||
// because this file includes uv_detail.hpp, which has the declarations necessary
|
||||
// for deleting the std::unique_ptr<uv::rwlock>.
|
||||
Style::~Style() {
|
||||
}
|
||||
|
||||
void Style::updateSources(Map& map,
|
||||
Environment& env,
|
||||
uv::worker& worker,
|
||||
TexturePool& texturePool,
|
||||
std::function<void()> callback) {
|
||||
// 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 (!layers) {
|
||||
return;
|
||||
}
|
||||
for (const util::ptr<StyleLayer> &layer : layers->layers) {
|
||||
if (!layer) continue;
|
||||
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(map, env);
|
||||
}
|
||||
} else {
|
||||
source->source.reset();
|
||||
}
|
||||
}
|
||||
|
||||
// Finally, remove all sources that are disabled.
|
||||
util::erase_if(activeSources, [](util::ptr<StyleSource> source){
|
||||
return !source->enabled;
|
||||
});
|
||||
|
||||
// Allow the sprite atlas to potentially pull new sprite images if needed.
|
||||
const float pixelRatio = map.getState().getPixelRatio();
|
||||
if (!sprite || sprite->pixelRatio != pixelRatio) {
|
||||
sprite = Sprite::Create(sprite_url, pixelRatio, env);
|
||||
spriteAtlas->resize(pixelRatio);
|
||||
spriteAtlas->setSprite(sprite);
|
||||
}
|
||||
|
||||
glyphStore->setURL(util::mapbox::normalizeGlyphsURL(glyph_url, map.getAccessToken()));
|
||||
|
||||
for (const auto &source : activeSources) {
|
||||
source->source->update(map, env, worker, shared_from_this(),
|
||||
*glyphAtlas, *glyphStore,
|
||||
*spriteAtlas, sprite,
|
||||
texturePool, callback);
|
||||
}
|
||||
}
|
||||
Style::~Style() {}
|
||||
|
||||
void Style::updateProperties(float z, std::chrono::steady_clock::time_point now) {
|
||||
uv::writelock lock(mtx);
|
||||
@@ -111,6 +41,10 @@ void Style::updateProperties(float z, std::chrono::steady_clock::time_point now)
|
||||
}
|
||||
}
|
||||
|
||||
const std::string &Style::getSpriteURL() const {
|
||||
return sprite_url;
|
||||
}
|
||||
|
||||
void Style::setDefaultTransitionDuration(std::chrono::steady_clock::duration duration) {
|
||||
defaultTransition.duration = duration;
|
||||
}
|
||||
@@ -130,6 +64,7 @@ bool Style::hasTransitions() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void Style::loadJSON(const uint8_t *const data) {
|
||||
uv::writelock lock(mtx);
|
||||
|
||||
|
||||
@@ -15,39 +15,23 @@
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <chrono>
|
||||
#include <memory>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class Map;
|
||||
class Environment;
|
||||
class GlyphAtlas;
|
||||
class GlyphStore;
|
||||
class SpriteAtlas;
|
||||
class Sprite;
|
||||
class LineAtlas;
|
||||
class StyleLayer;
|
||||
class StyleLayerGroup;
|
||||
class TexturePool;
|
||||
|
||||
class Style : public util::noncopyable,
|
||||
public std::enable_shared_from_this<Style> {
|
||||
class Style : public util::noncopyable {
|
||||
public:
|
||||
struct exception : std::runtime_error { exception(const char *msg) : std::runtime_error(msg) {} };
|
||||
|
||||
Style(Environment&);
|
||||
Style();
|
||||
~Style();
|
||||
|
||||
void loadJSON(const uint8_t *const data);
|
||||
|
||||
size_t layerCount() const;
|
||||
|
||||
void updateSources(Map&,
|
||||
Environment&,
|
||||
uv::worker&,
|
||||
TexturePool&,
|
||||
std::function<void()> callback);
|
||||
|
||||
void updateProperties(float z, std::chrono::steady_clock::time_point now);
|
||||
|
||||
void setDefaultTransitionDuration(std::chrono::steady_clock::duration duration = std::chrono::steady_clock::duration::zero());
|
||||
@@ -55,24 +39,19 @@ public:
|
||||
|
||||
bool hasTransitions() const;
|
||||
|
||||
const std::unique_ptr<GlyphAtlas> glyphAtlas;
|
||||
const std::unique_ptr<SpriteAtlas> spriteAtlas;
|
||||
const std::unique_ptr<LineAtlas> lineAtlas;
|
||||
const std::string &getSpriteURL() const;
|
||||
|
||||
util::ptr<StyleLayerGroup> layers;
|
||||
std::set<util::ptr<StyleSource>> activeSources;
|
||||
std::vector<std::string> appliedClasses;
|
||||
std::string glyph_url;
|
||||
std::string base;
|
||||
|
||||
private:
|
||||
std::string sprite_url;
|
||||
std::string glyph_url;
|
||||
PropertyTransition defaultTransition;
|
||||
bool initial_render_complete = false;
|
||||
std::unique_ptr<uv::rwlock> mtx;
|
||||
ZoomHistory zoomHistory;
|
||||
|
||||
const std::unique_ptr<GlyphStore> glyphStore;
|
||||
util::ptr<Sprite> sprite;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "../fixtures/util.hpp"
|
||||
|
||||
#include <mbgl/style/style_parser.hpp>
|
||||
#include <mbgl/style/style.hpp>
|
||||
#include <mbgl/util/io.hpp>
|
||||
|
||||
#include <rapidjson/document.h>
|
||||
@@ -22,23 +22,27 @@ class StyleParserTest : public ::testing::TestWithParam<std::string> {};
|
||||
TEST_P(StyleParserTest, ParseStyle) {
|
||||
const std::string &base = "test/fixtures/style_parser/" + GetParam();
|
||||
|
||||
rapidjson::Document infoDoc;
|
||||
infoDoc.Parse<0>(util::read_file(base + ".info.json").c_str());
|
||||
ASSERT_FALSE(infoDoc.HasParseError());
|
||||
ASSERT_TRUE(infoDoc.IsObject());
|
||||
const std::string style_path = base + ".style.json";
|
||||
const std::string info = util::read_file(base + ".info.json");
|
||||
|
||||
rapidjson::Document styleDoc;
|
||||
styleDoc.Parse<0>(util::read_file(base + ".style.json").c_str());
|
||||
ASSERT_FALSE(styleDoc.HasParseError());
|
||||
ASSERT_TRUE(styleDoc.IsObject());
|
||||
// Parse settings.
|
||||
rapidjson::Document doc;
|
||||
doc.Parse<0>((const char *const)info.c_str());
|
||||
ASSERT_FALSE(doc.HasParseError());
|
||||
ASSERT_TRUE(doc.IsObject());
|
||||
|
||||
std::ifstream stylefile(style_path);
|
||||
ASSERT_TRUE(stylefile.good());
|
||||
std::stringstream stylejson;
|
||||
stylejson << stylefile.rdbuf();
|
||||
|
||||
FixtureLogObserver* observer = new FixtureLogObserver();
|
||||
Log::setObserver(std::unique_ptr<Log::Observer>(observer));
|
||||
|
||||
StyleParser parser;
|
||||
parser.parse(styleDoc);
|
||||
Style style;
|
||||
style.loadJSON((const uint8_t *)stylejson.str().c_str());
|
||||
|
||||
for (auto it = infoDoc.MemberBegin(), end = infoDoc.MemberEnd(); it != end; it++) {
|
||||
for (auto it = doc.MemberBegin(), end = doc.MemberEnd(); it != end; it++) {
|
||||
const std::string name { it->name.GetString(), it->name.GetStringLength() };
|
||||
const rapidjson::Value &value = it->value;
|
||||
ASSERT_EQ(true, value.IsObject());
|
||||
|
||||
Reference in New Issue
Block a user