summaryrefslogtreecommitdiff
path: root/src/mbgl/renderer/paint_property_binder.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mbgl/renderer/paint_property_binder.hpp')
-rw-r--r--src/mbgl/renderer/paint_property_binder.hpp137
1 files changed, 122 insertions, 15 deletions
diff --git a/src/mbgl/renderer/paint_property_binder.hpp b/src/mbgl/renderer/paint_property_binder.hpp
index cd6b259e88..1a36f8a2e5 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
@@ -96,10 +105,14 @@ public:
virtual ~PaintPropertyBinder() = default;
- virtual void populateVertexVector(const GeometryTileFeature& feature,
- std::size_t length, const ImagePositions&,
- const optional<PatternDependency>&,
+ virtual void populateVertexVector(const GeometryTileFeature& feature, 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 +131,9 @@ 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 +160,9 @@ 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 +204,50 @@ 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 +282,7 @@ private:
T defaultValue;
gfx::VertexVector<BaseVertex> vertexVector;
optional<gfx::VertexBuffer<BaseVertex>> vertexBuffer;
+ FeatureVertexRangeMap featureMap;
};
template <class T, class A>
@@ -245,7 +299,9 @@ 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 +312,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 +392,7 @@ private:
Range<float> zoomRange;
gfx::VertexVector<Vertex> vertexVector;
optional<gfx::VertexBuffer<Vertex>> vertexBuffer;
+ FeatureVertexRangeMap featureMap;
};
template <class T, class A1, class A2>
@@ -322,8 +417,10 @@ 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
// string and will not have a valid entry in patternPositions. We still need to populate the attribute buffers to avoid crashes
@@ -353,6 +450,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,10 +590,18 @@ 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 = {}) {
- util::ignore({
- (binders.template get<Ps>()->populateVertexVector(feature, length, patternPositions, patternDependencies, formattedSection), 0)...
- });
+ 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>()->updateVertexVectors(states, layer, imagePositions), 0)...});
}
void setPatternParameters(const optional<ImagePosition>& posA, const optional<ImagePosition>& posB, const CrossfadeParameters& crossfade) const {