summaryrefslogtreecommitdiff
path: root/src/mbgl/renderer/paint_property_binder.hpp
diff options
context:
space:
mode:
authorJuha Alanen <juha.alanen@mapbox.com>2019-08-21 16:03:36 +0300
committerJuha Alanen <19551460+jmalanen@users.noreply.github.com>2019-09-18 14:29:15 +0300
commit413278ca20de77f7025b5304493dca6d1863fbb3 (patch)
tree194c238e77795c3421fc0f849406340fd8e4ad77 /src/mbgl/renderer/paint_property_binder.hpp
parent91171bc1a98acf3d21704fa86ad7ada5d1ac762e (diff)
downloadqtlocation-mapboxgl-413278ca20de77f7025b5304493dca6d1863fbb3.tar.gz
[core] Add feature state support to bucket classes
Diffstat (limited to 'src/mbgl/renderer/paint_property_binder.hpp')
-rw-r--r--src/mbgl/renderer/paint_property_binder.hpp119
1 files changed, 109 insertions, 10 deletions
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)...
});
}