summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMikhail Pozdnyakov <mikhail.pozdnyakov@mapbox.com>2019-07-08 12:46:32 +0300
committerMikhail Pozdnyakov <mikhail.pozdnyakov@mapbox.com>2019-07-08 12:46:32 +0300
commit10d3402162f01a358342c005c0532412cd821f50 (patch)
tree6f0110095604249342cd70bcbba9d5f028ff05c6
parentc1e4bf91f8c3e490336e9722f8e3d8bd63979c6f (diff)
downloadqtlocation-mapboxgl-10d3402162f01a358342c005c0532412cd821f50.tar.gz
[core] Renderer for RenderSymbolLayer
-rw-r--r--src/mbgl/renderer/layers/render_symbol_layer.cpp385
-rw-r--r--src/mbgl/renderer/layers/render_symbol_layer.hpp3
2 files changed, 196 insertions, 192 deletions
diff --git a/src/mbgl/renderer/layers/render_symbol_layer.cpp b/src/mbgl/renderer/layers/render_symbol_layer.cpp
index 60b0c8e2d8..910c26a61c 100644
--- a/src/mbgl/renderer/layers/render_symbol_layer.cpp
+++ b/src/mbgl/renderer/layers/render_symbol_layer.cpp
@@ -239,6 +239,200 @@ RenderSymbolLayer::RenderSymbolLayer(Immutable<style::SymbolLayer::Impl> _impl)
RenderSymbolLayer::~RenderSymbolLayer() = default;
+LayerRenderer RenderSymbolLayer::createRenderer() {
+ return [](PaintParameters& parameters, const LayerRenderItem& renderItem) {
+ if (parameters.pass == RenderPass::Opaque) {
+ return;
+ }
+ const auto& renderTiles = renderItem.renderTiles;
+ const auto& symbolImpl = impl(renderItem.evaluatedProperties->baseImpl);
+ const bool sortFeaturesByKey = !symbolImpl.layout.get<SymbolSortKey>().isUndefined();
+ std::multiset<RenderableSegment> renderableSegments;
+
+ const auto draw = [&parameters, &symbolImpl, &renderItem] (auto& programInstance,
+ const auto& uniformValues,
+ const auto& buffers,
+ auto& segments,
+ const auto& symbolSizeBinder,
+ const auto& binders,
+ const auto& paintProperties,
+ const auto& textureBindings,
+ const std::string& suffix) {
+ const auto allUniformValues = programInstance.computeAllUniformValues(
+ uniformValues,
+ *symbolSizeBinder,
+ binders,
+ paintProperties,
+ parameters.state.getZoom()
+ );
+
+ const auto allAttributeBindings = programInstance.computeAllAttributeBindings(
+ *buffers.vertexBuffer,
+ *buffers.dynamicVertexBuffer,
+ *buffers.opacityVertexBuffer,
+ binders,
+ paintProperties
+ );
+
+ renderItem.checkRenderability(parameters, programInstance.activeBindingCount(allAttributeBindings));
+
+ segments.match(
+ [&](const std::reference_wrapper<Segment<SymbolTextAttributes>>& segment) {
+ programInstance.draw(
+ parameters.context,
+ *parameters.renderPass,
+ gfx::Triangles(),
+ parameters.depthModeForSublayer(0, gfx::DepthMaskType::ReadOnly),
+ gfx::StencilMode::disabled(),
+ parameters.colorModeForRenderPass(),
+ gfx::CullFaceMode::disabled(),
+ *buffers.indexBuffer,
+ segment,
+ allUniformValues,
+ allAttributeBindings,
+ textureBindings,
+ symbolImpl.id + "/" + suffix
+ );
+ },
+ [&](const std::reference_wrapper<SegmentVector<SymbolTextAttributes>>& segmentVector) {
+ programInstance.draw(
+ parameters.context,
+ *parameters.renderPass,
+ gfx::Triangles(),
+ parameters.depthModeForSublayer(0, gfx::DepthMaskType::ReadOnly),
+ gfx::StencilMode::disabled(),
+ parameters.colorModeForRenderPass(),
+ gfx::CullFaceMode::disabled(),
+ *buffers.indexBuffer,
+ segmentVector,
+ allUniformValues,
+ allAttributeBindings,
+ textureBindings,
+ symbolImpl.id + "/" + suffix
+ );
+ }
+ );
+ };
+
+ for (const RenderTile& tile : renderTiles) {
+ const LayerRenderData* renderData = tile.getLayerRenderData(symbolImpl);
+ if (!renderData) {
+ continue;
+ }
+
+ auto& bucket = static_cast<SymbolBucket&>(*renderData->bucket);
+ assert(bucket.paintProperties.find(symbolImpl.id) != bucket.paintProperties.end());
+ const auto& bucketPaintProperties = bucket.paintProperties.at(symbolImpl.id);
+
+ auto addRenderables = [&renderableSegments, &tile, renderData, &bucketPaintProperties, it = renderableSegments.begin()] (auto& segments, bool isText) mutable {
+ for (auto& segment : segments) {
+ it = renderableSegments.emplace_hint(it, SegmentWrapper{std::ref(segment)}, tile, *renderData, bucketPaintProperties, segment.sortKey, isText);
+ }
+ };
+
+ if (bucket.hasIconData()) {
+ if (sortFeaturesByKey) {
+ addRenderables(bucket.icon.segments, false /*isText*/);
+ } else {
+ drawIcon(draw, tile, *renderData, std::ref(bucket.icon.segments), bucketPaintProperties, parameters);
+ }
+ }
+
+ if (bucket.hasTextData()) {
+ if (sortFeaturesByKey) {
+ addRenderables(bucket.text.segments, true /*isText*/);
+ } else {
+ drawText(draw, tile, *renderData, std::ref(bucket.text.segments), bucketPaintProperties, parameters);
+ }
+ }
+
+ if (bucket.hasCollisionBoxData()) {
+ static const style::Properties<>::PossiblyEvaluated properties {};
+ static const CollisionBoxProgram::Binders paintAttributeData(properties, 0);
+
+ auto pixelRatio = tile.id.pixelsToTileUnits(1, parameters.state.getZoom());
+ const float scale = std::pow(2, parameters.state.getZoom() - tile.getOverscaledTileID().overscaledZ);
+ std::array<float,2> extrudeScale =
+ {{
+ parameters.pixelsToGLUnits[0] / (pixelRatio * scale),
+ parameters.pixelsToGLUnits[1] / (pixelRatio * scale)
+ }};
+ parameters.programs.getSymbolLayerPrograms().collisionBox.draw(
+ parameters.context,
+ *parameters.renderPass,
+ gfx::Lines { 1.0f },
+ gfx::DepthMode::disabled(),
+ gfx::StencilMode::disabled(),
+ parameters.colorModeForRenderPass(),
+ gfx::CullFaceMode::disabled(),
+ CollisionBoxProgram::LayoutUniformValues {
+ uniforms::matrix::Value( tile.matrix ),
+ uniforms::extrude_scale::Value( extrudeScale ),
+ uniforms::camera_to_center_distance::Value( parameters.state.getCameraToCenterDistance() )
+ },
+ *bucket.collisionBox.vertexBuffer,
+ *bucket.collisionBox.dynamicVertexBuffer,
+ *bucket.collisionBox.indexBuffer,
+ bucket.collisionBox.segments,
+ paintAttributeData,
+ properties,
+ CollisionBoxProgram::TextureBindings{},
+ parameters.state.getZoom(),
+ symbolImpl.id
+ );
+ }
+
+ if (bucket.hasCollisionCircleData()) {
+ static const style::Properties<>::PossiblyEvaluated properties {};
+ static const CollisionBoxProgram::Binders paintAttributeData(properties, 0);
+
+ auto pixelRatio = tile.id.pixelsToTileUnits(1, parameters.state.getZoom());
+ const float scale = std::pow(2, parameters.state.getZoom() - tile.getOverscaledTileID().overscaledZ);
+ std::array<float,2> extrudeScale =
+ {{
+ parameters.pixelsToGLUnits[0] / (pixelRatio * scale),
+ parameters.pixelsToGLUnits[1] / (pixelRatio * scale)
+ }};
+
+ parameters.programs.getSymbolLayerPrograms().collisionCircle.draw(
+ parameters.context,
+ *parameters.renderPass,
+ gfx::Triangles(),
+ gfx::DepthMode::disabled(),
+ gfx::StencilMode::disabled(),
+ parameters.colorModeForRenderPass(),
+ gfx::CullFaceMode::disabled(),
+ CollisionCircleProgram::LayoutUniformValues {
+ uniforms::matrix::Value( tile.matrix ),
+ uniforms::extrude_scale::Value( extrudeScale ),
+ uniforms::overscale_factor::Value( float(tile.getOverscaledTileID().overscaleFactor()) ),
+ uniforms::camera_to_center_distance::Value( parameters.state.getCameraToCenterDistance() )
+ },
+ *bucket.collisionCircle.vertexBuffer,
+ *bucket.collisionCircle.dynamicVertexBuffer,
+ *bucket.collisionCircle.indexBuffer,
+ bucket.collisionCircle.segments,
+ paintAttributeData,
+ properties,
+ CollisionCircleProgram::TextureBindings{},
+ parameters.state.getZoom(),
+ symbolImpl.id
+ );
+ }
+ }
+
+ if (sortFeaturesByKey) {
+ for (auto& renderable : renderableSegments) {
+ if (renderable.isText) {
+ drawText(draw, renderable.tile, renderable.renderData, renderable.segment, renderable.bucketPaintProperties, parameters);
+ } else {
+ drawIcon(draw, renderable.tile, renderable.renderData, renderable.segment, renderable.bucketPaintProperties, parameters);
+ }
+ }
+ }
+ };
+}
+
void RenderSymbolLayer::transition(const TransitionParameters& parameters) {
unevaluated = impl(baseImpl).paint.transitioned(parameters, std::move(unevaluated));
hasFormatSectionOverrides = SymbolLayerPaintPropertyOverrides::hasOverrides(impl(baseImpl).layout.get<TextField>());
@@ -275,197 +469,6 @@ bool RenderSymbolLayer::hasCrossfade() const {
return false;
}
-void RenderSymbolLayer::render(PaintParameters& parameters) {
- if (parameters.pass == RenderPass::Opaque) {
- return;
- }
-
- const bool sortFeaturesByKey = !impl(baseImpl).layout.get<SymbolSortKey>().isUndefined();
- std::multiset<RenderableSegment> renderableSegments;
-
- const auto draw = [&parameters, this] (auto& programInstance,
- const auto& uniformValues,
- const auto& buffers,
- auto& segments,
- const auto& symbolSizeBinder,
- const auto& binders,
- const auto& paintProperties,
- const auto& textureBindings,
- const std::string& suffix) {
- const auto allUniformValues = programInstance.computeAllUniformValues(
- uniformValues,
- *symbolSizeBinder,
- binders,
- paintProperties,
- parameters.state.getZoom()
- );
-
- const auto allAttributeBindings = programInstance.computeAllAttributeBindings(
- *buffers.vertexBuffer,
- *buffers.dynamicVertexBuffer,
- *buffers.opacityVertexBuffer,
- binders,
- paintProperties
- );
-
- this->checkRenderability(parameters, programInstance.activeBindingCount(allAttributeBindings));
-
- segments.match(
- [&](const std::reference_wrapper<Segment<SymbolTextAttributes>>& segment) {
- programInstance.draw(
- parameters.context,
- *parameters.renderPass,
- gfx::Triangles(),
- parameters.depthModeForSublayer(0, gfx::DepthMaskType::ReadOnly),
- gfx::StencilMode::disabled(),
- parameters.colorModeForRenderPass(),
- gfx::CullFaceMode::disabled(),
- *buffers.indexBuffer,
- segment,
- allUniformValues,
- allAttributeBindings,
- textureBindings,
- this->getID() + "/" + suffix
- );
- },
- [&](const std::reference_wrapper<SegmentVector<SymbolTextAttributes>>& segmentVector) {
- programInstance.draw(
- parameters.context,
- *parameters.renderPass,
- gfx::Triangles(),
- parameters.depthModeForSublayer(0, gfx::DepthMaskType::ReadOnly),
- gfx::StencilMode::disabled(),
- parameters.colorModeForRenderPass(),
- gfx::CullFaceMode::disabled(),
- *buffers.indexBuffer,
- segmentVector,
- allUniformValues,
- allAttributeBindings,
- textureBindings,
- this->getID() + "/" + suffix
- );
- }
- );
- };
-
- for (const RenderTile& tile : renderTiles) {
- const LayerRenderData* renderData = tile.getLayerRenderData(*baseImpl);
- if (!renderData) {
- continue;
- }
-
- auto& bucket = static_cast<SymbolBucket&>(*renderData->bucket);
- assert(bucket.paintProperties.find(getID()) != bucket.paintProperties.end());
- const auto& bucketPaintProperties = bucket.paintProperties.at(getID());
-
- auto addRenderables = [&renderableSegments, &tile, renderData, &bucketPaintProperties, it = renderableSegments.begin()] (auto& segments, bool isText) mutable {
- for (auto& segment : segments) {
- it = renderableSegments.emplace_hint(it, SegmentWrapper{std::ref(segment)}, tile, *renderData, bucketPaintProperties, segment.sortKey, isText);
- }
- };
-
- if (bucket.hasIconData()) {
- if (sortFeaturesByKey) {
- addRenderables(bucket.icon.segments, false /*isText*/);
- } else {
- drawIcon(draw, tile, *renderData, std::ref(bucket.icon.segments), bucketPaintProperties, parameters);
- }
- }
-
- if (bucket.hasTextData()) {
- if (sortFeaturesByKey) {
- addRenderables(bucket.text.segments, true /*isText*/);
- } else {
- drawText(draw, tile, *renderData, std::ref(bucket.text.segments), bucketPaintProperties, parameters);
- }
- }
-
- if (bucket.hasCollisionBoxData()) {
- static const style::Properties<>::PossiblyEvaluated properties {};
- static const CollisionBoxProgram::Binders paintAttributeData(properties, 0);
-
- auto pixelRatio = tile.id.pixelsToTileUnits(1, parameters.state.getZoom());
- const float scale = std::pow(2, parameters.state.getZoom() - tile.getOverscaledTileID().overscaledZ);
- std::array<float,2> extrudeScale =
- {{
- parameters.pixelsToGLUnits[0] / (pixelRatio * scale),
- parameters.pixelsToGLUnits[1] / (pixelRatio * scale)
- }};
- parameters.programs.getSymbolLayerPrograms().collisionBox.draw(
- parameters.context,
- *parameters.renderPass,
- gfx::Lines { 1.0f },
- gfx::DepthMode::disabled(),
- gfx::StencilMode::disabled(),
- parameters.colorModeForRenderPass(),
- gfx::CullFaceMode::disabled(),
- CollisionBoxProgram::LayoutUniformValues {
- uniforms::matrix::Value( tile.matrix ),
- uniforms::extrude_scale::Value( extrudeScale ),
- uniforms::camera_to_center_distance::Value( parameters.state.getCameraToCenterDistance() )
- },
- *bucket.collisionBox.vertexBuffer,
- *bucket.collisionBox.dynamicVertexBuffer,
- *bucket.collisionBox.indexBuffer,
- bucket.collisionBox.segments,
- paintAttributeData,
- properties,
- CollisionBoxProgram::TextureBindings{},
- parameters.state.getZoom(),
- getID()
- );
- }
-
- if (bucket.hasCollisionCircleData()) {
- static const style::Properties<>::PossiblyEvaluated properties {};
- static const CollisionBoxProgram::Binders paintAttributeData(properties, 0);
-
- auto pixelRatio = tile.id.pixelsToTileUnits(1, parameters.state.getZoom());
- const float scale = std::pow(2, parameters.state.getZoom() - tile.getOverscaledTileID().overscaledZ);
- std::array<float,2> extrudeScale =
- {{
- parameters.pixelsToGLUnits[0] / (pixelRatio * scale),
- parameters.pixelsToGLUnits[1] / (pixelRatio * scale)
- }};
-
- parameters.programs.getSymbolLayerPrograms().collisionCircle.draw(
- parameters.context,
- *parameters.renderPass,
- gfx::Triangles(),
- gfx::DepthMode::disabled(),
- gfx::StencilMode::disabled(),
- parameters.colorModeForRenderPass(),
- gfx::CullFaceMode::disabled(),
- CollisionCircleProgram::LayoutUniformValues {
- uniforms::matrix::Value( tile.matrix ),
- uniforms::extrude_scale::Value( extrudeScale ),
- uniforms::overscale_factor::Value( float(tile.getOverscaledTileID().overscaleFactor()) ),
- uniforms::camera_to_center_distance::Value( parameters.state.getCameraToCenterDistance() )
- },
- *bucket.collisionCircle.vertexBuffer,
- *bucket.collisionCircle.dynamicVertexBuffer,
- *bucket.collisionCircle.indexBuffer,
- bucket.collisionCircle.segments,
- paintAttributeData,
- properties,
- CollisionCircleProgram::TextureBindings{},
- parameters.state.getZoom(),
- getID()
- );
- }
- }
-
- if (sortFeaturesByKey) {
- for (auto& renderable : renderableSegments) {
- if (renderable.isText) {
- drawText(draw, renderable.tile, renderable.renderData, renderable.segment, renderable.bucketPaintProperties, parameters);
- } else {
- drawIcon(draw, renderable.tile, renderable.renderData, renderable.segment, renderable.bucketPaintProperties, parameters);
- }
- }
- }
-}
-
// static
style::IconPaintProperties::PossiblyEvaluated RenderSymbolLayer::iconPaintProperties(const style::SymbolPaintProperties::PossiblyEvaluated& evaluated_) {
return style::IconPaintProperties::PossiblyEvaluated {
diff --git a/src/mbgl/renderer/layers/render_symbol_layer.hpp b/src/mbgl/renderer/layers/render_symbol_layer.hpp
index d9ce8c688d..3951587016 100644
--- a/src/mbgl/renderer/layers/render_symbol_layer.hpp
+++ b/src/mbgl/renderer/layers/render_symbol_layer.hpp
@@ -61,11 +61,12 @@ public:
static style::TextPaintProperties::PossiblyEvaluated textPaintProperties(const style::SymbolPaintProperties::PossiblyEvaluated&);
private:
+ LayerRenderer createRenderer() override;
void transition(const TransitionParameters&) override;
void evaluate(const PropertyEvaluationParameters&) override;
bool hasTransition() const override;
bool hasCrossfade() const override;
- void render(PaintParameters&) override;
+ void render(PaintParameters&) override {}
void prepare(const LayerPrepareParameters&) override;
// Paint properties