diff options
author | John Firebaugh <john.firebaugh@gmail.com> | 2015-03-12 15:54:54 -0700 |
---|---|---|
committer | John Firebaugh <john.firebaugh@gmail.com> | 2015-03-13 10:55:47 -0700 |
commit | bffee0715458530c6c86f440f757a4de667278a2 (patch) | |
tree | 603205a6487065d7d9f61663879ce91b70cdddc8 /src | |
parent | c36522e2a0481eaa0960f45f59ac3b023846b3e0 (diff) | |
download | qtlocation-mapboxgl-bffee0715458530c6c86f440f757a4de667278a2.tar.gz |
Move atlas ownership to Style
This follows gl-js and just makes sense -- whenever the style changes
the atlases should be blown away.
Refs #957
Diffstat (limited to 'src')
-rw-r--r-- | src/mbgl/map/map.cpp | 101 | ||||
-rw-r--r-- | src/mbgl/renderer/painter.cpp | 16 | ||||
-rw-r--r-- | src/mbgl/renderer/painter.hpp | 8 | ||||
-rw-r--r-- | src/mbgl/renderer/painter_fill.cpp | 6 | ||||
-rw-r--r-- | src/mbgl/renderer/painter_line.cpp | 14 | ||||
-rw-r--r-- | src/mbgl/renderer/painter_symbol.cpp | 10 | ||||
-rw-r--r-- | src/mbgl/style/style.cpp | 81 | ||||
-rw-r--r-- | src/mbgl/style/style.hpp | 31 |
8 files changed, 136 insertions, 131 deletions
diff --git a/src/mbgl/map/map.cpp b/src/mbgl/map/map.cpp index 29521f9499..cdad5f3ba2 100644 --- a/src/mbgl/map/map.cpp +++ b/src/mbgl/map/map.cpp @@ -2,7 +2,6 @@ #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> @@ -13,19 +12,14 @@ #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> @@ -65,12 +59,8 @@ 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>(*spriteAtlas, *glyphAtlas, *lineAtlas)) + painter(util::make_unique<Painter>()) { view.initialize(this); } @@ -81,9 +71,6 @@ Map::~Map() { } // Explicitly reset all pointers. - activeSources.clear(); - sprite.reset(); - glyphStore.reset(); style.reset(); texturePool.reset(); workers.reset(); @@ -114,7 +101,6 @@ 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; @@ -351,9 +337,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>(); + style = std::make_shared<Style>(*env); } style->base = base; @@ -361,9 +347,6 @@ 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(); } @@ -371,16 +354,6 @@ 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 @@ -604,64 +577,11 @@ 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>(); + style = std::make_shared<Style>(*env); env->request({ Resource::Kind::JSON, styleURL}, [&](const Response &res) { if (res.status == Response::Successful) { @@ -688,14 +608,13 @@ void Map::prepare() { state = transform.currentState(); animationTime = std::chrono::steady_clock::now(); - 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()); + style->updateSources(*this, *env, *workers, *texturePool, [this]() { + assert(std::this_thread::get_id() == mapThread); + triggerUpdate(); + }); - updateTiles(); + style->updateProperties(state.getNormalizedZoom(), animationTime); if (mode == Mode::Continuous) { view.invalidate(); @@ -705,7 +624,7 @@ void Map::prepare() { void Map::render() { assert(std::this_thread::get_id() == mapThread); assert(painter); - painter->render(*style, activeSources, + painter->render(*style, style->activeSources, state, animationTime); // Schedule another rerender when we definitely need a next frame. if (transform.needsTransition() || style->hasTransitions()) { diff --git a/src/mbgl/renderer/painter.cpp b/src/mbgl/renderer/painter.cpp index 544198fe61..d7b0937341 100644 --- a/src/mbgl/renderer/painter.cpp +++ b/src/mbgl/renderer/painter.cpp @@ -24,11 +24,7 @@ using namespace mbgl; #define BUFFER_OFFSET(i) ((char *)nullptr + (i)) -Painter::Painter(SpriteAtlas& spriteAtlas_, GlyphAtlas& glyphAtlas_, LineAtlas& lineAtlas_) - : spriteAtlas(spriteAtlas_) - , glyphAtlas(glyphAtlas_) - , lineAtlas(lineAtlas_) -{ +Painter::Painter() { } Painter::~Painter() { @@ -219,6 +215,10 @@ 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; diff --git a/src/mbgl/renderer/painter.hpp b/src/mbgl/renderer/painter.hpp index 9c9c6a4642..6a2716657b 100644 --- a/src/mbgl/renderer/painter.hpp +++ b/src/mbgl/renderer/painter.hpp @@ -59,7 +59,7 @@ class RasterTileData; class Painter : private util::noncopyable { public: - Painter(SpriteAtlas&, GlyphAtlas&, LineAtlas&); + Painter(); ~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; diff --git a/src/mbgl/renderer/painter_fill.cpp b/src/mbgl/renderer/painter_fill.cpp index 53fa337bed..8393cce744 100644 --- a/src/mbgl/renderer/painter_fill.cpp +++ b/src/mbgl/renderer/painter_fill.cpp @@ -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); diff --git a/src/mbgl/renderer/painter_line.cpp b/src/mbgl/renderer/painter_line.cpp index 36b8c3b689..643bd01496 100644 --- a/src/mbgl/renderer/painter_line.cpp +++ b/src/mbgl/renderer/painter_line.cpp @@ -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); diff --git a/src/mbgl/renderer/painter_symbol.cpp b/src/mbgl/renderer/painter_symbol.cpp index 9b533699e0..1b7b28ae5a 100644 --- a/src/mbgl/renderer/painter_symbol.cpp +++ b/src/mbgl/renderer/painter_symbol.cpp @@ -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); } diff --git a/src/mbgl/style/style.cpp b/src/mbgl/style/style.cpp index 45217950f6..c606039a2c 100644 --- a/src/mbgl/style/style.cpp +++ b/src/mbgl/style/style.cpp @@ -1,5 +1,6 @@ #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> @@ -8,6 +9,13 @@ #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> @@ -16,14 +24,76 @@ namespace mbgl { -Style::Style() - : mtx(util::make_unique<uv::rwlock>()) { +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)) +{ } // 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() {} +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); + } +} void Style::updateProperties(float z, std::chrono::steady_clock::time_point now) { uv::writelock lock(mtx); @@ -41,10 +111,6 @@ 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; } @@ -64,7 +130,6 @@ bool Style::hasTransitions() const { return false; } - void Style::loadJSON(const uint8_t *const data) { uv::writelock lock(mtx); diff --git a/src/mbgl/style/style.hpp b/src/mbgl/style/style.hpp index 4de827a38c..04979b3377 100644 --- a/src/mbgl/style/style.hpp +++ b/src/mbgl/style/style.hpp @@ -15,23 +15,39 @@ #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 { +class Style : public util::noncopyable, + public std::enable_shared_from_this<Style> { public: struct exception : std::runtime_error { exception(const char *msg) : std::runtime_error(msg) {} }; - Style(); + Style(Environment&); ~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()); @@ -39,19 +55,24 @@ public: bool hasTransitions() const; - const std::string &getSpriteURL() const; + const std::unique_ptr<GlyphAtlas> glyphAtlas; + const std::unique_ptr<SpriteAtlas> spriteAtlas; + const std::unique_ptr<LineAtlas> lineAtlas; util::ptr<StyleLayerGroup> layers; - std::vector<std::string> appliedClasses; - std::string glyph_url; + std::set<util::ptr<StyleSource>> activeSources; 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; }; } |