diff options
author | Andrew Hay Kurtz <andrew.hay.kurtz@gmail.com> | 2019-10-29 13:49:22 -0700 |
---|---|---|
committer | Mikhail Pozdnyakov <mikhail.pozdnyakov@mapbox.com> | 2020-04-14 22:30:40 +0300 |
commit | 0c95acf10379266e4142572b6cc7fb1c29271f3b (patch) | |
tree | 562c723da46b44a6c5905586f7a25f5194213d15 /src/mbgl/renderer | |
parent | 08ad74216442a8c306a3d7ca4696f5ddb780557f (diff) | |
download | qtlocation-mapboxgl-0c95acf10379266e4142572b6cc7fb1c29271f3b.tar.gz |
Enable 'circle-sort-key' layout property
Diffstat (limited to 'src/mbgl/renderer')
-rw-r--r-- | src/mbgl/renderer/buckets/circle_bucket.cpp | 74 | ||||
-rw-r--r-- | src/mbgl/renderer/buckets/circle_bucket.hpp | 13 | ||||
-rw-r--r-- | src/mbgl/renderer/layers/render_circle_layer.cpp | 82 |
3 files changed, 80 insertions, 89 deletions
diff --git a/src/mbgl/renderer/buckets/circle_bucket.cpp b/src/mbgl/renderer/buckets/circle_bucket.cpp index 744b559c42..5a1184f5fd 100644 --- a/src/mbgl/renderer/buckets/circle_bucket.cpp +++ b/src/mbgl/renderer/buckets/circle_bucket.cpp @@ -10,15 +10,14 @@ namespace mbgl { using namespace style; -CircleBucket::CircleBucket(const BucketParameters& parameters, const std::vector<Immutable<style::LayerProperties>>& layers) - : mode(parameters.mode) { - for (const auto& layer : layers) { - paintPropertyBinders.emplace( - std::piecewise_construct, - std::forward_as_tuple(layer->baseImpl->id), - std::forward_as_tuple( - getEvaluated<CircleLayerProperties>(layer), - parameters.tileID.overscaledZ)); +CircleBucket::CircleBucket(const std::map<std::string, Immutable<LayerProperties>>& layerPaintProperties, + const MapMode mode_, + const float zoom) + : mode(mode_) { + for (const auto& pair : layerPaintProperties) { + paintPropertyBinders.emplace(std::piecewise_construct, + std::forward_as_tuple(pair.first), + std::forward_as_tuple(getEvaluated<CircleLayerProperties>(pair.second), zoom)); } } @@ -41,63 +40,6 @@ bool CircleBucket::hasData() const { return !segments.empty(); } -void CircleBucket::addFeature(const GeometryTileFeature& feature, - const GeometryCollection& geometry, - const ImagePositions&, - const PatternLayerMap&, - std::size_t featureIndex, - const CanonicalTileID& canonical) { - constexpr const uint16_t vertexLength = 4; - - for (auto& circle : geometry) { - for(auto& point : circle) { - auto x = point.x; - auto y = point.y; - - // Do not include points that are outside the tile boundaries. - // Include all points in Still mode. You need to include points from - // neighbouring tiles so that they are not clipped at tile boundaries. - if ((mode == MapMode::Continuous) && - (x < 0 || x >= util::EXTENT || y < 0 || y >= util::EXTENT)) continue; - - if (segments.empty() || segments.back().vertexLength + vertexLength > std::numeric_limits<uint16_t>::max()) { - // Move to a new segments because the old one can't hold the geometry. - segments.emplace_back(vertices.elements(), triangles.elements()); - } - - // this geometry will be of the Point type, and we'll derive - // two triangles from it. - // - // ┌─────────┐ - // │ 4 3 │ - // │ │ - // │ 1 2 │ - // └─────────┘ - // - vertices.emplace_back(CircleProgram::vertex(point, -1, -1)); // 1 - vertices.emplace_back(CircleProgram::vertex(point, 1, -1)); // 2 - vertices.emplace_back(CircleProgram::vertex(point, 1, 1)); // 3 - vertices.emplace_back(CircleProgram::vertex(point, -1, 1)); // 4 - - auto& segment = segments.back(); - assert(segment.vertexLength <= std::numeric_limits<uint16_t>::max()); - uint16_t index = segment.vertexLength; - - // 1, 2, 3 - // 1, 4, 3 - triangles.emplace_back(index, index + 1, index + 2); - triangles.emplace_back(index, index + 3, index + 2); - - segment.vertexLength += vertexLength; - segment.indexLength += 6; - } - } - - for (auto& pair : paintPropertyBinders) { - pair.second.populateVertexVectors(feature, vertices.elements(), featureIndex, {}, {}, canonical); - } -} - template <class Property> static float get(const CirclePaintProperties::PossiblyEvaluated& evaluated, const std::string& id, const std::map<std::string, CircleProgram::Binders>& paintPropertyBinders) { auto it = paintPropertyBinders.find(id); diff --git a/src/mbgl/renderer/buckets/circle_bucket.hpp b/src/mbgl/renderer/buckets/circle_bucket.hpp index 17ddd9dc10..221deb5f17 100644 --- a/src/mbgl/renderer/buckets/circle_bucket.hpp +++ b/src/mbgl/renderer/buckets/circle_bucket.hpp @@ -15,15 +15,12 @@ class BucketParameters; class CircleBucket final : public Bucket { public: - CircleBucket(const BucketParameters&, const std::vector<Immutable<style::LayerProperties>>&); - ~CircleBucket() override; + using PossiblyEvaluatedLayoutProperties = style::CircleLayoutProperties::PossiblyEvaluated; - void addFeature(const GeometryTileFeature&, - const GeometryCollection&, - const ImagePositions&, - const PatternLayerMap&, - std::size_t, - const CanonicalTileID&) override; + CircleBucket(const std::map<std::string, Immutable<style::LayerProperties>>& layerPaintProperties, + const MapMode mode, + const float zoom); + ~CircleBucket() override; bool hasData() const override; diff --git a/src/mbgl/renderer/layers/render_circle_layer.cpp b/src/mbgl/renderer/layers/render_circle_layer.cpp index a8a70d2a3a..a85b82b2d2 100644 --- a/src/mbgl/renderer/layers/render_circle_layer.cpp +++ b/src/mbgl/renderer/layers/render_circle_layer.cpp @@ -17,6 +17,32 @@ using namespace style; namespace { +struct RenderableSegment { + RenderableSegment(const Segment<CircleAttributes>& segment_, + CircleProgram& programInstance_, + const CircleBucket& bucket_, + const CircleProgram::UniformValues& allUniformValues_, + const CircleProgram::AttributeBindings& allAttributeBindings_, + float sortKey_) + : segment(segment_), + programInstance(programInstance_), + bucket(bucket_), + allUniformValues(allUniformValues_), + allAttributeBindings(allAttributeBindings_), + sortKey(sortKey_) {} + + const Segment<CircleAttributes>& segment; + CircleProgram& programInstance; + const CircleBucket& bucket; + const CircleProgram::UniformValues& allUniformValues; + const CircleProgram::AttributeBindings& allAttributeBindings; + const float sortKey; + + friend bool operator<(const RenderableSegment& lhs, const RenderableSegment& rhs) { + return lhs.sortKey < rhs.sortKey; + } +}; + inline const style::CircleLayer::Impl& impl_cast(const Immutable<style::Layer::Impl>& impl) { assert(impl->getTypeInfo() == CircleLayer::Impl::staticTypeInfo()); return static_cast<const style::CircleLayer::Impl&>(*impl); @@ -63,6 +89,9 @@ void RenderCircleLayer::render(PaintParameters& parameters) { return; } + const bool sortFeaturesByKey = !impl_cast(baseImpl).layout.get<CircleSortKey>().isUndefined(); + std::multiset<RenderableSegment> renderableSegments{}; + for (const RenderTile& tile : *renderTiles) { const LayerRenderData* renderData = getRenderDataForPass(tile, parameters.pass); if (!renderData) { @@ -96,21 +125,44 @@ void RenderCircleLayer::render(PaintParameters& parameters) { checkRenderability(parameters, CircleProgram::activeBindingCount(allAttributeBindings)); - programInstance.draw( - parameters.context, - *parameters.renderPass, - gfx::Triangles(), - parameters.depthModeForSublayer(0, gfx::DepthMaskType::ReadOnly), - gfx::StencilMode::disabled(), - parameters.colorModeForRenderPass(), - gfx::CullFaceMode::disabled(), - *bucket.indexBuffer, - bucket.segments, - allUniformValues, - allAttributeBindings, - CircleProgram::TextureBindings{}, - getID() - ); + if (sortFeaturesByKey) { + for (auto& segment : bucket.segments) { + renderableSegments.emplace( + segment, programInstance, bucket, allUniformValues, allAttributeBindings, segment.sortKey); + } + } else { + programInstance.draw(parameters.context, + *parameters.renderPass, + gfx::Triangles(), + parameters.depthModeForSublayer(0, gfx::DepthMaskType::ReadOnly), + gfx::StencilMode::disabled(), + parameters.colorModeForRenderPass(), + gfx::CullFaceMode::disabled(), + *bucket.indexBuffer, + bucket.segments, + allUniformValues, + allAttributeBindings, + CircleProgram::TextureBindings{}, + getID()); + } + } + + if (sortFeaturesByKey) { + for (const auto& renderable : renderableSegments) { + renderable.programInstance.draw(parameters.context, + *parameters.renderPass, + gfx::Triangles(), + parameters.depthModeForSublayer(0, gfx::DepthMaskType::ReadOnly), + gfx::StencilMode::disabled(), + parameters.colorModeForRenderPass(), + gfx::CullFaceMode::disabled(), + *renderable.bucket.indexBuffer, + renderable.segment, + renderable.allUniformValues, + renderable.allAttributeBindings, + CircleProgram::TextureBindings{}, + getID()); + } } } |