summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohn Firebaugh <john.firebaugh@gmail.com>2015-11-06 15:26:12 -0800
committerJohn Firebaugh <john.firebaugh@gmail.com>2015-12-01 11:16:57 -0800
commitb7674040ab768318c5accce50067550a7da4bea9 (patch)
tree500ae9289c8024c55c1406fe9ff6689247055fff /src
parentbafbf6c04b1bfd5da84411f52a72e26783f3bcb7 (diff)
downloadqtlocation-mapboxgl-b7674040ab768318c5accce50067550a7da4bea9.tar.gz
[core] Privatize layers and sources
Diffstat (limited to 'src')
-rw-r--r--src/mbgl/map/map_context.cpp9
-rw-r--r--src/mbgl/renderer/painter.cpp118
-rw-r--r--src/mbgl/renderer/painter.hpp17
-rw-r--r--src/mbgl/style/style.cpp82
-rw-r--r--src/mbgl/style/style.hpp28
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.