From 10d3402162f01a358342c005c0532412cd821f50 Mon Sep 17 00:00:00 2001 From: Mikhail Pozdnyakov Date: Mon, 8 Jul 2019 12:46:32 +0300 Subject: [core] Renderer for RenderSymbolLayer --- src/mbgl/renderer/layers/render_symbol_layer.cpp | 385 ++++++++++++----------- src/mbgl/renderer/layers/render_symbol_layer.hpp | 3 +- 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 _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().isUndefined(); + std::multiset renderableSegments; + + const auto draw = [¶meters, &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) { + 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) { + 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(*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 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 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()); @@ -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().isUndefined(); - std::multiset renderableSegments; - - const auto draw = [¶meters, 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) { - 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) { - 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(*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 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 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 -- cgit v1.2.1