diff options
author | John Firebaugh <john.firebaugh@gmail.com> | 2015-11-06 15:26:12 -0800 |
---|---|---|
committer | John Firebaugh <john.firebaugh@gmail.com> | 2015-12-01 11:16:57 -0800 |
commit | b7674040ab768318c5accce50067550a7da4bea9 (patch) | |
tree | 500ae9289c8024c55c1406fe9ff6689247055fff /src | |
parent | bafbf6c04b1bfd5da84411f52a72e26783f3bcb7 (diff) | |
download | qtlocation-mapboxgl-b7674040ab768318c5accce50067550a7da4bea9.tar.gz |
[core] Privatize layers and sources
Diffstat (limited to 'src')
-rw-r--r-- | src/mbgl/map/map_context.cpp | 9 | ||||
-rw-r--r-- | src/mbgl/renderer/painter.cpp | 118 | ||||
-rw-r--r-- | src/mbgl/renderer/painter.hpp | 17 | ||||
-rw-r--r-- | src/mbgl/style/style.cpp | 82 | ||||
-rw-r--r-- | src/mbgl/style/style.hpp | 28 |
5 files changed, 130 insertions, 124 deletions
diff --git a/src/mbgl/map/map_context.cpp b/src/mbgl/map/map_context.cpp index 17d91ab861..2a338e738b 100644 --- a/src/mbgl/map/map_context.cpp +++ b/src/mbgl/map/map_context.cpp @@ -277,9 +277,7 @@ void MapContext::setSourceTileCacheSize(size_t size) { if (size != sourceCacheSize) { sourceCacheSize = size; if (!style) return; - for (const auto &source : style->sources) { - source->setCacheSize(sourceCacheSize); - } + style->setSourceTileCacheSize(size); asyncInvalidate.send(); } } @@ -287,9 +285,7 @@ void MapContext::setSourceTileCacheSize(size_t size) { void MapContext::onLowMemory() { assert(util::ThreadContext::currentlyOn(util::ThreadType::Map)); if (!style) return; - for (const auto &source : style->sources) { - source->onLowMemory(); - } + style->onLowMemory(); asyncInvalidate.send(); } @@ -300,7 +296,6 @@ void MapContext::setSprite(const std::string& name, std::shared_ptr<const Sprite void MapContext::onTileDataChanged() { assert(util::ThreadContext::currentlyOn(util::ThreadType::Map)); - updateFlags |= Update::Repaint; asyncUpdate.send(); } diff --git a/src/mbgl/renderer/painter.cpp b/src/mbgl/renderer/painter.cpp index 9c64fc9f90..70d2c75c0d 100644 --- a/src/mbgl/renderer/painter.cpp +++ b/src/mbgl/renderer/painter.cpp @@ -109,19 +109,6 @@ void Painter::changeMatrix() { matrix::multiply(nativeMatrix, projMatrix, nativeMatrix); } -void Painter::clear() { - MBGL_DEBUG_GROUP("clear"); - config.stencilFunc.reset(); - config.stencilTest = GL_TRUE; - config.stencilMask = 0xFF; - config.depthTest = GL_FALSE; - config.depthMask = GL_TRUE; - config.clearColor = { background[0], background[1], background[2], background[3] }; - config.clearStencil = 0; - config.clearDepth = 1; - MBGL_CHECK_ERROR(glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)); -} - void Painter::prepareTile(const Tile& tile) { const GLint ref = (GLint)tile.clip.reference.to_ulong(); const GLuint mask = (GLuint)tile.clip.mask.to_ulong(); @@ -135,19 +122,14 @@ void Painter::render(const Style& style, const FrameData& frame_, SpriteAtlas& a spriteAtlas = style.spriteAtlas.get(); lineAtlas = style.lineAtlas.get(); - std::set<Source*> sources; - for (const auto& source : style.sources) { - if (source->enabled) { - sources.insert(source.get()); - } - } + RenderData renderData = style.getRenderData(); + const std::vector<RenderItem>& order = renderData.order; + const std::set<Source*>& sources = renderData.sources; + const Color& background = renderData.backgroundColor; resize(); changeMatrix(); - // Figure out what buckets we have to draw and what order we have to draw them in. - const auto order = determineRenderOrder(style); - // - UPLOAD PASS ------------------------------------------------------------------------------- // Uploads all required buffers and images before we do any actual rendering. { @@ -167,6 +149,21 @@ void Painter::render(const Style& style, const FrameData& frame_, SpriteAtlas& a } } + // - CLEAR ------------------------------------------------------------------------------------- + // Renders the backdrop of the OpenGL view. This also paints in areas where we don't have any + // tiles whatsoever. + { + MBGL_DEBUG_GROUP("clear"); + config.stencilFunc.reset(); + config.stencilTest = GL_TRUE; + config.stencilMask = 0xFF; + config.depthTest = GL_FALSE; + config.depthMask = GL_TRUE; + config.clearColor = { background[0], background[1], background[2], background[3] }; + config.clearStencil = 0; + config.clearDepth = 1; + MBGL_CHECK_ERROR(glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)); + } // - CLIPPING MASKS ---------------------------------------------------------------------------- // Draws the clipping masks to the stencil buffer. @@ -180,8 +177,6 @@ void Painter::render(const Style& style, const FrameData& frame_, SpriteAtlas& a source->updateMatrices(projMatrix, state); } - clear(); - drawClippingMasks(sources); } @@ -275,81 +270,6 @@ void Painter::renderPass(RenderPass pass_, } } -std::vector<RenderItem> Painter::determineRenderOrder(const Style& style) { - std::vector<RenderItem> order; - - for (const auto& layerPtr : style.layers) { - const auto& layer = *layerPtr; - if (layer.visibility == VisibilityType::None) continue; - if (layer.type == StyleLayerType::Background) { - // This layer defines a background color/image. - auto& props = dynamic_cast<const BackgroundLayer&>(layer).paint; - if (props.pattern.value.from.empty()) { - // This is a solid background. We can use glClear(). - background = props.color; - background[0] *= props.opacity; - background[1] *= props.opacity; - background[2] *= props.opacity; - background[3] *= props.opacity; - } else { - // This is a textured background. We need to render it with a quad. - background = {{ 0, 0, 0, 0 }}; - order.emplace_back(layer); - } - continue; - } - - Source* source = style.getSource(layer.source); - if (!source) { - Log::Warning(Event::Render, "can't find source for layer '%s'", layer.id.c_str()); - continue; - } - - // 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. - const double zoom = state.getZoom(); - if (layer.minZoom > zoom || - layer.maxZoom <= zoom) { - continue; - } - - const auto& tiles = source->getTiles(); - for (auto tile : tiles) { - assert(tile); - if (!tile->data && !tile->data->isReady()) { - 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 (layer.type == StyleLayerType::Symbol) { - 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 = order.rbegin(); it != order.rend() && (&it->layer == &layer); ++it) { - if (tile->id.isChildOf(it->tile->id)) { - skip = true; - break; - } - } - if (skip) { - continue; - } - } - - auto bucket = tile->data->getBucket(layer); - if (bucket) { - order.emplace_back(layer, tile, bucket); - } - } - } - - return order; -} - void Painter::renderBackground(const BackgroundLayer& layer) { // Note: This function is only called for textured background. Otherwise, the background color // is created with glClear. diff --git a/src/mbgl/renderer/painter.hpp b/src/mbgl/renderer/painter.hpp index 0995ee4e44..3e5ee06732 100644 --- a/src/mbgl/renderer/painter.hpp +++ b/src/mbgl/renderer/painter.hpp @@ -68,27 +68,11 @@ class CollisionBoxShader; struct ClipID; -struct RenderItem { - inline RenderItem(const StyleLayer& layer_, - const Tile* tile_ = nullptr, - Bucket* bucket_ = nullptr) - : tile(tile_), bucket(bucket_), layer(layer_) { - } - - const Tile* const tile; - Bucket* const bucket; - const StyleLayer& layer; -}; - class Painter : private util::noncopyable { public: Painter(MapData&, TransformState&); ~Painter(); - // Renders the backdrop of the OpenGL view. This also paints in areas where we don't have any - // tiles whatsoever. - void clear(); - // Updates the default matrices to the current viewport dimensions. void changeMatrix(); @@ -190,7 +174,6 @@ private: gl::Config config; RenderPass pass = RenderPass::Opaque; - Color background = {{ 0, 0, 0, 0 }}; int numSublayers = 3; GLsizei currentLayer; diff --git a/src/mbgl/style/style.cpp b/src/mbgl/style/style.cpp index 7faa4b254a..b22aa546f7 100644 --- a/src/mbgl/style/style.cpp +++ b/src/mbgl/style/style.cpp @@ -1,6 +1,7 @@ #include <mbgl/style/style.hpp> #include <mbgl/map/map_data.hpp> #include <mbgl/map/source.hpp> +#include <mbgl/map/tile.hpp> #include <mbgl/map/transform_state.hpp> #include <mbgl/layer/symbol_layer.hpp> #include <mbgl/sprite/sprite_store.hpp> @@ -16,6 +17,8 @@ #include <mbgl/geometry/line_atlas.hpp> #include <mbgl/util/constants.hpp> #include <mbgl/platform/log.hpp> +#include <mbgl/layer/background_layer.hpp> + #include <csscolorparser/csscolorparser.hpp> #include <rapidjson/document.h> @@ -220,6 +223,85 @@ bool Style::isLoaded() const { return true; } +RenderData Style::getRenderData() const { + RenderData result; + + for (const auto& source : sources) { + if (source->enabled) { + result.sources.insert(source.get()); + } + } + + for (const auto& layer : layers) { + if (layer->visibility == VisibilityType::None) + continue; + + if (const BackgroundLayer* background = dynamic_cast<const BackgroundLayer*>(layer.get())) { + if (background->paint.pattern.value.from.empty()) { + // This is a solid background. We can use glClear(). + result.backgroundColor = background->paint.color; + result.backgroundColor[0] *= background->paint.opacity; + result.backgroundColor[1] *= background->paint.opacity; + result.backgroundColor[2] *= background->paint.opacity; + result.backgroundColor[3] *= background->paint.opacity; + } else { + // This is a textured background. We need to render it with a quad. + result.order.emplace_back(*layer); + } + continue; + } + + Source* source = getSource(layer->source); + if (!source) { + Log::Warning(Event::Render, "can't find source for layer '%s'", layer->id.c_str()); + continue; + } + + for (auto tile : source->getTiles()) { + if (!tile->data || !tile->data->isReady()) + 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 (layer->type == StyleLayerType::Symbol) { + 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 = result.order.rbegin(); it != result.order.rend() && (&it->layer == layer.get()); ++it) { + if (tile->id.isChildOf(it->tile->id)) { + skip = true; + break; + } + } + if (skip) { + continue; + } + } + + auto bucket = tile->data->getBucket(*layer); + if (bucket) { + result.order.emplace_back(*layer, tile, bucket); + } + } + } + + return result; +} + +void Style::setSourceTileCacheSize(size_t size) { + for (const auto& source : sources) { + source->setCacheSize(size); + } +} + +void Style::onLowMemory() { + for (const auto& source : sources) { + source->onLowMemory(); + } +} + void Style::setObserver(Observer* observer_) { assert(util::ThreadContext::currentlyOn(util::ThreadType::Map)); assert(!observer); diff --git a/src/mbgl/style/style.hpp b/src/mbgl/style/style.hpp index d9cd137767..9afd933ffc 100644 --- a/src/mbgl/style/style.hpp +++ b/src/mbgl/style/style.hpp @@ -29,6 +29,27 @@ class StyleLayer; class TransformState; class TexturePool; +class Tile; +class Bucket; + +struct RenderItem { + inline RenderItem(const StyleLayer& layer_, + const Tile* tile_ = nullptr, + Bucket* bucket_ = nullptr) + : tile(tile_), bucket(bucket_), layer(layer_) { + } + + const Tile* const tile; + Bucket* const bucket; + const StyleLayer& layer; +}; + +struct RenderData { + Color backgroundColor = {{ 0, 0, 0, 0 }}; + std::set<Source*> sources; + std::vector<RenderItem> order; +}; + class Style : public GlyphStore::Observer, public SpriteStore::Observer, public Source::Observer, @@ -73,6 +94,11 @@ public: void addLayer(std::unique_ptr<StyleLayer>, const std::string& beforeLayerID); void removeLayer(const std::string& layerID); + RenderData getRenderData() const; + + void setSourceTileCacheSize(size_t); + void onLowMemory(); + void dumpDebugLogs() const; MapData& data; @@ -82,10 +108,10 @@ public: std::unique_ptr<SpriteAtlas> spriteAtlas; std::unique_ptr<LineAtlas> lineAtlas; +private: std::vector<std::unique_ptr<Source>> sources; std::vector<std::unique_ptr<StyleLayer>> layers; -private: std::vector<std::unique_ptr<StyleLayer>>::const_iterator findLayer(const std::string& layerID) const; // GlyphStore::Observer implementation. |