diff options
Diffstat (limited to 'src/mbgl')
-rw-r--r-- | src/mbgl/gfx/vertex_vector.hpp | 5 | ||||
-rw-r--r-- | src/mbgl/layout/pattern_layout.hpp | 2 | ||||
-rw-r--r-- | src/mbgl/layout/symbol_layout.cpp | 4 | ||||
-rw-r--r-- | src/mbgl/renderer/bucket.hpp | 6 | ||||
-rw-r--r-- | src/mbgl/renderer/buckets/circle_bucket.cpp | 19 | ||||
-rw-r--r-- | src/mbgl/renderer/buckets/circle_bucket.hpp | 5 | ||||
-rw-r--r-- | src/mbgl/renderer/buckets/fill_bucket.cpp | 23 | ||||
-rw-r--r-- | src/mbgl/renderer/buckets/fill_bucket.hpp | 5 | ||||
-rw-r--r-- | src/mbgl/renderer/buckets/fill_extrusion_bucket.cpp | 21 | ||||
-rw-r--r-- | src/mbgl/renderer/buckets/fill_extrusion_bucket.hpp | 5 | ||||
-rw-r--r-- | src/mbgl/renderer/buckets/heatmap_bucket.cpp | 5 | ||||
-rw-r--r-- | src/mbgl/renderer/buckets/heatmap_bucket.hpp | 3 | ||||
-rw-r--r-- | src/mbgl/renderer/buckets/line_bucket.cpp | 21 | ||||
-rw-r--r-- | src/mbgl/renderer/buckets/line_bucket.hpp | 5 | ||||
-rw-r--r-- | src/mbgl/renderer/paint_property_binder.hpp | 119 | ||||
-rw-r--r-- | src/mbgl/tile/geometry_tile_worker.cpp | 2 |
16 files changed, 208 insertions, 42 deletions
diff --git a/src/mbgl/gfx/vertex_vector.hpp b/src/mbgl/gfx/vertex_vector.hpp index 59fe67586b..091ecb912e 100644 --- a/src/mbgl/gfx/vertex_vector.hpp +++ b/src/mbgl/gfx/vertex_vector.hpp @@ -20,6 +20,11 @@ public: v.resize(v.size() + n, val); } + Vertex& at(std::size_t n) { + assert(n < v.size()); + return v.at(n); + } + std::size_t elements() const { return v.size(); } diff --git a/src/mbgl/layout/pattern_layout.hpp b/src/mbgl/layout/pattern_layout.hpp index 858d515347..d6d878955f 100644 --- a/src/mbgl/layout/pattern_layout.hpp +++ b/src/mbgl/layout/pattern_layout.hpp @@ -108,7 +108,7 @@ public: const PatternLayerMap& patterns = patternFeature.patterns; const GeometryCollection& geometries = feature->getGeometries(); - bucket->addFeature(*feature, geometries, patternPositions, patterns); + bucket->addFeature(*feature, geometries, patternPositions, patterns, i); featureIndex->insert(geometries, i, sourceLayerID, bucketLeaderID); } if (bucket->hasData()) { diff --git a/src/mbgl/layout/symbol_layout.cpp b/src/mbgl/layout/symbol_layout.cpp index 1dbb5d91dc..71724cad5f 100644 --- a/src/mbgl/layout/symbol_layout.cpp +++ b/src/mbgl/layout/symbol_layout.cpp @@ -713,7 +713,7 @@ void SymbolLayout::createBucket(const ImagePositions&, std::unique_ptr<FeatureIn } for (auto& pair : bucket->paintProperties) { - pair.second.iconBinders.populateVertexVectors(feature, iconBuffer.vertices.elements(), {}, {}); + pair.second.iconBinders.populateVertexVectors(feature, iconBuffer.vertices.elements(), symbolInstance.dataFeatureIndex, {}, {}); } } @@ -765,7 +765,7 @@ void SymbolLayout::updatePaintPropertiesForSection(SymbolBucket& bucket, std::size_t sectionIndex) { const auto& formattedSection = sectionOptionsToValue((*feature.formattedText).sectionAt(sectionIndex)); for (auto& pair : bucket.paintProperties) { - pair.second.textBinders.populateVertexVectors(feature, bucket.text.vertices.elements(), {}, {}, formattedSection); + pair.second.textBinders.populateVertexVectors(feature, bucket.text.vertices.elements(), feature.index, {}, {}, formattedSection); } } diff --git a/src/mbgl/renderer/bucket.hpp b/src/mbgl/renderer/bucket.hpp index a978c06d6b..98c2200ce9 100644 --- a/src/mbgl/renderer/bucket.hpp +++ b/src/mbgl/renderer/bucket.hpp @@ -35,7 +35,11 @@ public: virtual void addFeature(const GeometryTileFeature&, const GeometryCollection&, const ImagePositions&, - const PatternLayerMap&) {}; + const PatternLayerMap&, + std::size_t) {}; + + virtual void update(const FeatureStates&, const GeometryTileLayer&, const std::string&, const ImagePositions&) {} + // As long as this bucket has a Prepare render pass, this function is getting called. Typically, // this only happens once when the bucket is being rendered for the first time. diff --git a/src/mbgl/renderer/buckets/circle_bucket.cpp b/src/mbgl/renderer/buckets/circle_bucket.cpp index 7ba130da64..ffa6f59128 100644 --- a/src/mbgl/renderer/buckets/circle_bucket.cpp +++ b/src/mbgl/renderer/buckets/circle_bucket.cpp @@ -25,8 +25,10 @@ CircleBucket::CircleBucket(const BucketParameters& parameters, const std::vector CircleBucket::~CircleBucket() = default; void CircleBucket::upload(gfx::UploadPass& uploadPass) { - vertexBuffer = uploadPass.createVertexBuffer(std::move(vertices)); - indexBuffer = uploadPass.createIndexBuffer(std::move(triangles)); + if (!uploaded) { + vertexBuffer = uploadPass.createVertexBuffer(std::move(vertices)); + indexBuffer = uploadPass.createIndexBuffer(std::move(triangles)); + } for (auto& pair : paintPropertyBinders) { pair.second.upload(uploadPass); @@ -42,7 +44,8 @@ bool CircleBucket::hasData() const { void CircleBucket::addFeature(const GeometryTileFeature& feature, const GeometryCollection& geometry, const ImagePositions&, - const PatternLayerMap&) { + const PatternLayerMap&, + std::size_t featureIndex) { constexpr const uint16_t vertexLength = 4; for (auto& circle : geometry) { @@ -90,7 +93,7 @@ void CircleBucket::addFeature(const GeometryTileFeature& feature, } for (auto& pair : paintPropertyBinders) { - pair.second.populateVertexVectors(feature, vertices.elements(), {}, {}); + pair.second.populateVertexVectors(feature, vertices.elements(), featureIndex, {}, {}); } } @@ -112,4 +115,12 @@ float CircleBucket::getQueryRadius(const RenderLayer& layer) const { return radius + stroke + util::length(translate[0], translate[1]); } +void CircleBucket::update(const FeatureStates& states, const GeometryTileLayer& layer, const std::string& layerID, const ImagePositions& imagePositions) { + auto it = paintPropertyBinders.find(layerID); + if (it != paintPropertyBinders.end()) { + it->second.updateVertexVectors(states, layer, imagePositions); + uploaded = false; + } +} + } // namespace mbgl diff --git a/src/mbgl/renderer/buckets/circle_bucket.hpp b/src/mbgl/renderer/buckets/circle_bucket.hpp index 27423bc568..9fee45ad79 100644 --- a/src/mbgl/renderer/buckets/circle_bucket.hpp +++ b/src/mbgl/renderer/buckets/circle_bucket.hpp @@ -21,7 +21,8 @@ public: void addFeature(const GeometryTileFeature&, const GeometryCollection&, const ImagePositions&, - const PatternLayerMap&) override; + const PatternLayerMap&, + std::size_t) override; bool hasData() const override; @@ -29,6 +30,8 @@ public: float getQueryRadius(const RenderLayer&) const override; + void update(const FeatureStates&, const GeometryTileLayer&, const std::string&, const ImagePositions&) override; + gfx::VertexVector<CircleLayoutVertex> vertices; gfx::IndexVector<gfx::Triangles> triangles; SegmentVector<CircleAttributes> segments; diff --git a/src/mbgl/renderer/buckets/fill_bucket.cpp b/src/mbgl/renderer/buckets/fill_bucket.cpp index 8a089c679e..ea79a1e687 100644 --- a/src/mbgl/renderer/buckets/fill_bucket.cpp +++ b/src/mbgl/renderer/buckets/fill_bucket.cpp @@ -47,7 +47,8 @@ FillBucket::~FillBucket() = default; void FillBucket::addFeature(const GeometryTileFeature& feature, const GeometryCollection& geometry, const ImagePositions& patternPositions, - const PatternLayerMap& patternDependencies) { + const PatternLayerMap& patternDependencies, + std::size_t index) { for (auto& polygon : classifyRings(geometry)) { // Optimize polygons with many interior rings for earcut tesselation. limitHoles(polygon, 500); @@ -114,17 +115,19 @@ void FillBucket::addFeature(const GeometryTileFeature& feature, for (auto& pair : paintPropertyBinders) { const auto it = patternDependencies.find(pair.first); if (it != patternDependencies.end()){ - pair.second.populateVertexVectors(feature, vertices.elements(), patternPositions, it->second); + pair.second.populateVertexVectors(feature, vertices.elements(), index, patternPositions, it->second); } else { - pair.second.populateVertexVectors(feature, vertices.elements(), patternPositions, {}); + pair.second.populateVertexVectors(feature, vertices.elements(), index, patternPositions, {}); } } } void FillBucket::upload(gfx::UploadPass& uploadPass) { - vertexBuffer = uploadPass.createVertexBuffer(std::move(vertices)); - lineIndexBuffer = uploadPass.createIndexBuffer(std::move(lines)); - triangleIndexBuffer = triangles.empty() ? optional<gfx::IndexBuffer> {} : uploadPass.createIndexBuffer(std::move(triangles)); + if (!uploaded) { + vertexBuffer = uploadPass.createVertexBuffer(std::move(vertices)); + lineIndexBuffer = uploadPass.createIndexBuffer(std::move(lines)); + triangleIndexBuffer = triangles.empty() ? optional<gfx::IndexBuffer> {} : uploadPass.createIndexBuffer(std::move(triangles)); + } for (auto& pair : paintPropertyBinders) { pair.second.upload(uploadPass); @@ -143,4 +146,12 @@ float FillBucket::getQueryRadius(const RenderLayer& layer) const { return util::length(translate[0], translate[1]); } +void FillBucket::update(const FeatureStates& states, const GeometryTileLayer& layer, const std::string& layerID, const ImagePositions& imagePositions) { + auto it = paintPropertyBinders.find(layerID); + if (it != paintPropertyBinders.end()) { + it->second.updateVertexVectors(states, layer, imagePositions); + uploaded = false; + } +} + } // namespace mbgl diff --git a/src/mbgl/renderer/buckets/fill_bucket.hpp b/src/mbgl/renderer/buckets/fill_bucket.hpp index 6747c1083f..eee421f938 100644 --- a/src/mbgl/renderer/buckets/fill_bucket.hpp +++ b/src/mbgl/renderer/buckets/fill_bucket.hpp @@ -29,7 +29,8 @@ public: void addFeature(const GeometryTileFeature&, const GeometryCollection&, const mbgl::ImagePositions&, - const PatternLayerMap&) override; + const PatternLayerMap&, + std::size_t) override; bool hasData() const override; @@ -37,6 +38,8 @@ public: float getQueryRadius(const RenderLayer&) const override; + void update(const FeatureStates&, const GeometryTileLayer&, const std::string&, const ImagePositions&) override; + gfx::VertexVector<FillLayoutVertex> vertices; gfx::IndexVector<gfx::Lines> lines; gfx::IndexVector<gfx::Triangles> triangles; diff --git a/src/mbgl/renderer/buckets/fill_extrusion_bucket.cpp b/src/mbgl/renderer/buckets/fill_extrusion_bucket.cpp index be13850e55..6a25349c22 100644 --- a/src/mbgl/renderer/buckets/fill_extrusion_bucket.cpp +++ b/src/mbgl/renderer/buckets/fill_extrusion_bucket.cpp @@ -53,7 +53,8 @@ FillExtrusionBucket::~FillExtrusionBucket() = default; void FillExtrusionBucket::addFeature(const GeometryTileFeature& feature, const GeometryCollection& geometry, const ImagePositions& patternPositions, - const PatternLayerMap& patternDependencies) { + const PatternLayerMap& patternDependencies, + std::size_t index) { for (auto& polygon : classifyRings(geometry)) { // Optimize polygons with many interior rings for earcut tesselation. limitHoles(polygon, 500); @@ -158,16 +159,18 @@ void FillExtrusionBucket::addFeature(const GeometryTileFeature& feature, for (auto& pair : paintPropertyBinders) { const auto it = patternDependencies.find(pair.first); if (it != patternDependencies.end()){ - pair.second.populateVertexVectors(feature, vertices.elements(), patternPositions, it->second); + pair.second.populateVertexVectors(feature, vertices.elements(), index, patternPositions, it->second); } else { - pair.second.populateVertexVectors(feature, vertices.elements(), patternPositions, {}); + pair.second.populateVertexVectors(feature, vertices.elements(), index, patternPositions, {}); } } } void FillExtrusionBucket::upload(gfx::UploadPass& uploadPass) { - vertexBuffer = uploadPass.createVertexBuffer(std::move(vertices)); - indexBuffer = uploadPass.createIndexBuffer(std::move(triangles)); + if (!uploaded) { + vertexBuffer = uploadPass.createVertexBuffer(std::move(vertices)); + indexBuffer = uploadPass.createIndexBuffer(std::move(triangles)); + } for (auto& pair : paintPropertyBinders) { pair.second.upload(uploadPass); @@ -186,4 +189,12 @@ float FillExtrusionBucket::getQueryRadius(const RenderLayer& layer) const { return util::length(translate[0], translate[1]); } +void FillExtrusionBucket::update(const FeatureStates& states, const GeometryTileLayer& layer, const std::string& layerID, const ImagePositions& imagePositions) { + auto it = paintPropertyBinders.find(layerID); + if (it != paintPropertyBinders.end()) { + it->second.updateVertexVectors(states, layer, imagePositions); + uploaded = false; + } +} + } // namespace mbgl diff --git a/src/mbgl/renderer/buckets/fill_extrusion_bucket.hpp b/src/mbgl/renderer/buckets/fill_extrusion_bucket.hpp index 4c97618a77..582480bf41 100644 --- a/src/mbgl/renderer/buckets/fill_extrusion_bucket.hpp +++ b/src/mbgl/renderer/buckets/fill_extrusion_bucket.hpp @@ -27,7 +27,8 @@ public: void addFeature(const GeometryTileFeature&, const GeometryCollection&, const mbgl::ImagePositions&, - const PatternLayerMap&) override; + const PatternLayerMap&, + std::size_t) override; bool hasData() const override; @@ -35,6 +36,8 @@ public: float getQueryRadius(const RenderLayer&) const override; + void update(const FeatureStates&, const GeometryTileLayer&, const std::string&, const ImagePositions&) override; + gfx::VertexVector<FillExtrusionLayoutVertex> vertices; gfx::IndexVector<gfx::Triangles> triangles; SegmentVector<FillExtrusionAttributes> triangleSegments; diff --git a/src/mbgl/renderer/buckets/heatmap_bucket.cpp b/src/mbgl/renderer/buckets/heatmap_bucket.cpp index fad78f6cec..0ea645a9a0 100644 --- a/src/mbgl/renderer/buckets/heatmap_bucket.cpp +++ b/src/mbgl/renderer/buckets/heatmap_bucket.cpp @@ -42,7 +42,8 @@ bool HeatmapBucket::hasData() const { void HeatmapBucket::addFeature(const GeometryTileFeature& feature, const GeometryCollection& geometry, const ImagePositions&, - const PatternLayerMap&) { + const PatternLayerMap&, + std::size_t featureIndex) { constexpr const uint16_t vertexLength = 4; for (auto& points : geometry) { @@ -89,7 +90,7 @@ void HeatmapBucket::addFeature(const GeometryTileFeature& feature, } for (auto& pair : paintPropertyBinders) { - pair.second.populateVertexVectors(feature, vertices.elements(), {}, {}); + pair.second.populateVertexVectors(feature, vertices.elements(), featureIndex, {}, {}); } } diff --git a/src/mbgl/renderer/buckets/heatmap_bucket.hpp b/src/mbgl/renderer/buckets/heatmap_bucket.hpp index 68790bf5bf..3f9d1cb5c3 100644 --- a/src/mbgl/renderer/buckets/heatmap_bucket.hpp +++ b/src/mbgl/renderer/buckets/heatmap_bucket.hpp @@ -21,7 +21,8 @@ public: void addFeature(const GeometryTileFeature&, const GeometryCollection&, const ImagePositions&, - const PatternLayerMap&) override; + const PatternLayerMap&, + std::size_t) override; bool hasData() const override; void upload(gfx::UploadPass&) override; diff --git a/src/mbgl/renderer/buckets/line_bucket.cpp b/src/mbgl/renderer/buckets/line_bucket.cpp index 9019e76d3b..318af99b0f 100644 --- a/src/mbgl/renderer/buckets/line_bucket.cpp +++ b/src/mbgl/renderer/buckets/line_bucket.cpp @@ -33,7 +33,8 @@ LineBucket::~LineBucket() = default; void LineBucket::addFeature(const GeometryTileFeature& feature, const GeometryCollection& geometryCollection, const ImagePositions& patternPositions, - const PatternLayerMap& patternDependencies) { + const PatternLayerMap& patternDependencies, + std::size_t index) { for (auto& line : geometryCollection) { addGeometry(line, feature); } @@ -41,9 +42,9 @@ void LineBucket::addFeature(const GeometryTileFeature& feature, for (auto& pair : paintPropertyBinders) { const auto it = patternDependencies.find(pair.first); if (it != patternDependencies.end()){ - pair.second.populateVertexVectors(feature, vertices.elements(), patternPositions, it->second); + pair.second.populateVertexVectors(feature, vertices.elements(), index, patternPositions, it->second); } else { - pair.second.populateVertexVectors(feature, vertices.elements(), patternPositions, {}); + pair.second.populateVertexVectors(feature, vertices.elements(), index, patternPositions, {}); } } } @@ -517,8 +518,10 @@ void LineBucket::addPieSliceVertex(const GeometryCoordinate& currentVertex, } void LineBucket::upload(gfx::UploadPass& uploadPass) { - vertexBuffer = uploadPass.createVertexBuffer(std::move(vertices)); - indexBuffer = uploadPass.createIndexBuffer(std::move(triangles)); + if (!uploaded) { + vertexBuffer = uploadPass.createVertexBuffer(std::move(vertices)); + indexBuffer = uploadPass.createIndexBuffer(std::move(triangles)); + } for (auto& pair : paintPropertyBinders) { pair.second.upload(uploadPass); @@ -554,4 +557,12 @@ float LineBucket::getQueryRadius(const RenderLayer& layer) const { return lineWidth / 2.0f + std::abs(offset) + util::length(translate[0], translate[1]); } +void LineBucket::update(const FeatureStates& states, const GeometryTileLayer& layer, const std::string& layerID, const ImagePositions& imagePositions) { + auto it = paintPropertyBinders.find(layerID); + if (it != paintPropertyBinders.end()) { + it->second.updateVertexVectors(states, layer, imagePositions); + uploaded = false; + } +} + } // namespace mbgl diff --git a/src/mbgl/renderer/buckets/line_bucket.hpp b/src/mbgl/renderer/buckets/line_bucket.hpp index eac9e14e4c..6be35593d9 100644 --- a/src/mbgl/renderer/buckets/line_bucket.hpp +++ b/src/mbgl/renderer/buckets/line_bucket.hpp @@ -29,7 +29,8 @@ public: void addFeature(const GeometryTileFeature&, const GeometryCollection&, const mbgl::ImagePositions& patternPositions, - const PatternLayerMap&) override; + const PatternLayerMap&, + std::size_t) override; bool hasData() const override; @@ -37,6 +38,8 @@ public: float getQueryRadius(const RenderLayer&) const override; + void update(const FeatureStates&, const GeometryTileLayer&, const std::string&, const ImagePositions&) override; + PossiblyEvaluatedLayoutProperties layout; gfx::VertexVector<LineLayoutVertex> vertices; diff --git a/src/mbgl/renderer/paint_property_binder.hpp b/src/mbgl/renderer/paint_property_binder.hpp index cd6b259e88..fdfbc99642 100644 --- a/src/mbgl/renderer/paint_property_binder.hpp +++ b/src/mbgl/renderer/paint_property_binder.hpp @@ -19,6 +19,15 @@ namespace mbgl { +// Maps vertex range to feature index +struct FeatureVertexRange { + std::size_t featureIndex; + std::size_t start; + std::size_t end; +}; + +using FeatureVertexRangeMap = std::map<std::string, std::vector<FeatureVertexRange>>; + /* ZoomInterpolatedAttribute<Attr> is a 'compound' attribute, representing two values of the the base attribute Attr. These two values are provided to the shader to allow interpolation @@ -97,9 +106,17 @@ public: virtual ~PaintPropertyBinder() = default; virtual void populateVertexVector(const GeometryTileFeature& feature, - std::size_t length, const ImagePositions&, + std::size_t length, std::size_t index, + const ImagePositions&, const optional<PatternDependency>&, const style::expression::Value&) = 0; + + virtual void updateVertexVectors(const FeatureStates&, + const GeometryTileLayer&, + const ImagePositions&) {} + + virtual void updateVertexVector(std::size_t, std::size_t, const GeometryTileFeature&, const FeatureState&) = 0; + virtual void upload(gfx::UploadPass&) = 0; virtual void setPatternParameters(const optional<ImagePosition>&, const optional<ImagePosition>&, const CrossfadeParameters&) = 0; virtual std::tuple<ExpandToType<As, optional<gfx::AttributeBinding>>...> attributeBinding(const PossiblyEvaluatedType& currentValue) const = 0; @@ -118,7 +135,8 @@ public: : constant(std::move(constant_)) { } - void populateVertexVector(const GeometryTileFeature&, std::size_t, const ImagePositions&, const optional<PatternDependency>&, const style::expression::Value&) override {} + void populateVertexVector(const GeometryTileFeature&, std::size_t, std::size_t, const ImagePositions&, const optional<PatternDependency>&, const style::expression::Value&) override {} + void updateVertexVector(std::size_t, std::size_t, const GeometryTileFeature&, const FeatureState&) override {} void upload(gfx::UploadPass&) override {} void setPatternParameters(const optional<ImagePosition>&, const optional<ImagePosition>&, const CrossfadeParameters&) override {}; @@ -145,7 +163,8 @@ public: : constant(std::move(constant_)), constantPatternPositions({}) { } - void populateVertexVector(const GeometryTileFeature&, std::size_t, const ImagePositions&, const optional<PatternDependency>&, const style::expression::Value&) override {} + void populateVertexVector(const GeometryTileFeature&, std::size_t, std::size_t, const ImagePositions&, const optional<PatternDependency>&, const style::expression::Value&) override {} + void updateVertexVector(std::size_t, std::size_t, const GeometryTileFeature&, const FeatureState&) override {} void upload(gfx::UploadPass&) override {} void setPatternParameters(const optional<ImagePosition>& posA, const optional<ImagePosition>& posB, const CrossfadeParameters&) override { @@ -187,14 +206,46 @@ public: defaultValue(std::move(defaultValue_)) { } void setPatternParameters(const optional<ImagePosition>&, const optional<ImagePosition>&, const CrossfadeParameters&) override {}; - void populateVertexVector(const GeometryTileFeature& feature, std::size_t length, const ImagePositions&, const optional<PatternDependency>&, const style::expression::Value& formattedSection) override { + void populateVertexVector(const GeometryTileFeature& feature, std::size_t length, std::size_t index, const ImagePositions&, const optional<PatternDependency>&, const style::expression::Value& formattedSection) override { using style::expression::EvaluationContext; auto evaluated = expression.evaluate(EvaluationContext(&feature).withFormattedSection(&formattedSection), defaultValue); this->statistics.add(evaluated); auto value = attributeValue(evaluated); - for (std::size_t i = vertexVector.elements(); i < length; ++i) { + auto elements = vertexVector.elements(); + for (std::size_t i = elements; i < length; ++i) { vertexVector.emplace_back(BaseVertex { value }); } + optional<std::string> idStr = featureIDtoString(feature.getID()); + if (idStr) { + featureMap[*idStr].emplace_back(FeatureVertexRange { index, elements, length }); + } + } + + void updateVertexVectors(const FeatureStates& states, const GeometryTileLayer& layer, const ImagePositions&) override { + for (const auto& it : states) { + const auto positions = featureMap.find(it.first); + if (positions == featureMap.end()) { + continue; + } + + for (const auto& pos : positions->second) { + std::unique_ptr<GeometryTileFeature> feature = layer.getFeature(pos.featureIndex); + if (feature) { + updateVertexVector(pos.start, pos.end, *feature, it.second); + } + } + } + } + + void updateVertexVector(std::size_t start, std::size_t end, const GeometryTileFeature& feature, const FeatureState& state) override { + using style::expression::EvaluationContext; + + auto evaluated = expression.evaluate(EvaluationContext(&feature).withFeatureState(&state), defaultValue); + this->statistics.add(evaluated); + auto value = attributeValue(evaluated); + for (std::size_t i = start; i < end; ++i) { + vertexVector.at(i) = BaseVertex { value }; + } } void upload(gfx::UploadPass& uploadPass) override { @@ -229,6 +280,7 @@ private: T defaultValue; gfx::VertexVector<BaseVertex> vertexVector; optional<gfx::VertexBuffer<BaseVertex>> vertexBuffer; + FeatureVertexRangeMap featureMap; }; template <class T, class A> @@ -245,7 +297,7 @@ public: zoomRange({zoom, zoom + 1}) { } void setPatternParameters(const optional<ImagePosition>&, const optional<ImagePosition>&, const CrossfadeParameters&) override {}; - void populateVertexVector(const GeometryTileFeature& feature, std::size_t length, const ImagePositions&, const optional<PatternDependency>&, const style::expression::Value& formattedSection) override { + void populateVertexVector(const GeometryTileFeature& feature, std::size_t length, std::size_t index, const ImagePositions&, const optional<PatternDependency>&, const style::expression::Value& formattedSection) override { using style::expression::EvaluationContext; Range<T> range = { expression.evaluate(EvaluationContext(zoomRange.min, &feature).withFormattedSection(&formattedSection), defaultValue), @@ -256,9 +308,47 @@ public: AttributeValue value = zoomInterpolatedAttributeValue( attributeValue(range.min), attributeValue(range.max)); - for (std::size_t i = vertexVector.elements(); i < length; ++i) { + auto elements = vertexVector.elements(); + for (std::size_t i = elements; i < length; ++i) { vertexVector.emplace_back(Vertex { value }); } + optional<std::string> idStr = featureIDtoString(feature.getID()); + if (idStr) { + featureMap[*idStr].emplace_back(FeatureVertexRange { index, elements, length }); + } + } + + void updateVertexVectors(const FeatureStates& states, const GeometryTileLayer& layer, const ImagePositions&) override { + for (const auto& it : states) { + const auto positions = featureMap.find(it.first); + if (positions == featureMap.end()) { + continue; + } + + for (const auto& pos : positions->second) { + std::unique_ptr<GeometryTileFeature> feature = layer.getFeature(pos.featureIndex); + if (feature) { + updateVertexVector(pos.start, pos.end, *feature, it.second); + } + } + } + } + + void updateVertexVector(std::size_t start, std::size_t end, const GeometryTileFeature& feature, const FeatureState& state) override { + using style::expression::EvaluationContext; + Range<T> range = { + expression.evaluate(EvaluationContext(zoomRange.min, &feature, &state), defaultValue), + expression.evaluate(EvaluationContext(zoomRange.max, &feature, &state), defaultValue), + }; + this->statistics.add(range.min); + this->statistics.add(range.max); + AttributeValue value = zoomInterpolatedAttributeValue( + attributeValue(range.min), + attributeValue(range.max)); + + for (std::size_t i = start; i < end; ++i) { + vertexVector.at(i) = Vertex { value }; + } } void upload(gfx::UploadPass& uploadPass) override { @@ -298,6 +388,7 @@ private: Range<float> zoomRange; gfx::VertexVector<Vertex> vertexVector; optional<gfx::VertexBuffer<Vertex>> vertexBuffer; + FeatureVertexRangeMap featureMap; }; template <class T, class A1, class A2> @@ -322,7 +413,7 @@ public: crossfade = crossfade_; }; - void populateVertexVector(const GeometryTileFeature&, std::size_t length, const ImagePositions& patternPositions, const optional<PatternDependency>& patternDependencies, const style::expression::Value&) override { + void populateVertexVector(const GeometryTileFeature&, std::size_t length, std::size_t /* index */, const ImagePositions& patternPositions, const optional<PatternDependency>& patternDependencies, const style::expression::Value&) override { if (!patternDependencies || patternDependencies->mid.empty()) { // Unlike other propperties with expressions that evaluate to null, the default value for `*-pattern` properties is an empty @@ -353,6 +444,8 @@ public: } } + void updateVertexVector(std::size_t, std::size_t, const GeometryTileFeature&, const FeatureState&) override {} + void upload(gfx::UploadPass& uploadPass) override { if (!patternToVertexVector.empty()) { assert(!zoomInVertexVector.empty()); @@ -491,9 +584,15 @@ public: PaintPropertyBinders(PaintPropertyBinders&&) = default; PaintPropertyBinders(const PaintPropertyBinders&) = delete; - void populateVertexVectors(const GeometryTileFeature& feature, std::size_t length, const ImagePositions& patternPositions, const optional<PatternDependency>& patternDependencies, const style::expression::Value& formattedSection = {}) { + void populateVertexVectors(const GeometryTileFeature& feature, std::size_t length, std::size_t index, const ImagePositions& patternPositions, const optional<PatternDependency>& patternDependencies, const style::expression::Value& formattedSection = {}) { + util::ignore({ + (binders.template get<Ps>()->populateVertexVector(feature, length, index, patternPositions, patternDependencies, formattedSection), 0)... + }); + } + + void updateVertexVectors(const FeatureStates& states, const GeometryTileLayer& layer, const ImagePositions& imagePositions) { util::ignore({ - (binders.template get<Ps>()->populateVertexVector(feature, length, patternPositions, patternDependencies, formattedSection), 0)... + (binders.template get<Ps>()->updateVertexVectors(states, layer, imagePositions), 0)... }); } diff --git a/src/mbgl/tile/geometry_tile_worker.cpp b/src/mbgl/tile/geometry_tile_worker.cpp index 428a5b0d5e..ce883ad93f 100644 --- a/src/mbgl/tile/geometry_tile_worker.cpp +++ b/src/mbgl/tile/geometry_tile_worker.cpp @@ -384,7 +384,7 @@ void GeometryTileWorker::parse() { continue; const GeometryCollection& geometries = feature->getGeometries(); - bucket->addFeature(*feature, geometries, {}, PatternLayerMap ()); + bucket->addFeature(*feature, geometries, {}, PatternLayerMap (), i); featureIndex->insert(geometries, i, sourceLayerID, leaderImpl.id); } |