aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAsheem Mamoowala <asheem.mamoowala@mapbox.com>2018-10-31 16:58:59 -0700
committerAsheem Mamoowala <asheem.mamoowala@mapbox.com>2018-10-31 16:58:59 -0700
commit80cba7200f26140d265159e0721a573ffc4c40eb (patch)
treed05ae0faa3769bb68269248cb04cc8bd2fdf87fe
parent6f51186dc1dfb52f5add46cb24825873d173ecef (diff)
Update vertex vectors and upload updated buffers
-rw-r--r--src/mbgl/gl/context.hpp14
-rw-r--r--src/mbgl/gl/vertex_buffer.hpp3
-rw-r--r--src/mbgl/renderer/buckets/circle_bucket.cpp27
-rw-r--r--src/mbgl/renderer/buckets/circle_bucket.hpp5
-rw-r--r--src/mbgl/renderer/paint_property_binder.hpp34
-rw-r--r--src/mbgl/tile/geometry_tile.cpp3
6 files changed, 71 insertions, 15 deletions
diff --git a/src/mbgl/gl/context.hpp b/src/mbgl/gl/context.hpp
index bd682f44d..55521b2f6 100644
--- a/src/mbgl/gl/context.hpp
+++ b/src/mbgl/gl/context.hpp
@@ -71,11 +71,25 @@ public:
}
template <class Vertex, class DrawMode>
+ VertexBuffer<Vertex, DrawMode> createVertexBuffer(const VertexVector<Vertex, DrawMode>& v, const BufferUsage usage = BufferUsage::StaticDraw) {
+ return VertexBuffer<Vertex, DrawMode> {
+ v.vertexSize(),
+ createVertexBuffer(v.data(), v.byteSize(), usage)
+ };
+ }
+
+ template <class Vertex, class DrawMode>
void updateVertexBuffer(VertexBuffer<Vertex, DrawMode>& buffer, VertexVector<Vertex, DrawMode>&& v) {
assert(v.vertexSize() == buffer.vertexCount);
updateVertexBuffer(buffer.buffer, v.data(), v.byteSize());
}
+ template <class Vertex, class DrawMode>
+ void updateVertexBuffer(VertexBuffer<Vertex, DrawMode>& buffer, const VertexVector<Vertex, DrawMode>& v) {
+ assert(v.vertexSize() == buffer.vertexCount);
+ updateVertexBuffer(buffer.buffer, v.data(), v.byteSize());
+ }
+
template <class DrawMode>
IndexBuffer<DrawMode> createIndexBuffer(IndexVector<DrawMode>&& v, const BufferUsage usage = BufferUsage::StaticDraw) {
return IndexBuffer<DrawMode> {
diff --git a/src/mbgl/gl/vertex_buffer.hpp b/src/mbgl/gl/vertex_buffer.hpp
index 807776fc8..6eca45142 100644
--- a/src/mbgl/gl/vertex_buffer.hpp
+++ b/src/mbgl/gl/vertex_buffer.hpp
@@ -25,8 +25,9 @@ public:
template<class... Args>
void emplace(size_t startAt, Args&&... args) {
static_assert(sizeof...(args) == groupSize, "wrong buffer element count");
+ assert(startAt < v.size());
auto emplaceIter = v.begin() + (startAt * groupSize);
- util::ignore({(v.emplace(emplaceIter++, std::forward<Args>(args)), 0)...});
+ util::ignore({(std::fill(emplaceIter, std::next(emplaceIter), std::forward<Args>(args)), 0)...});
}
std::size_t vertexSize() const { return v.size(); }
std::size_t byteSize() const { return v.size() * sizeof(Vertex); }
diff --git a/src/mbgl/renderer/buckets/circle_bucket.cpp b/src/mbgl/renderer/buckets/circle_bucket.cpp
index a0e81c00b..20c40eb0c 100644
--- a/src/mbgl/renderer/buckets/circle_bucket.cpp
+++ b/src/mbgl/renderer/buckets/circle_bucket.cpp
@@ -20,13 +20,17 @@ CircleBucket::CircleBucket(const BucketParameters& parameters, const std::vector
std::forward_as_tuple(
layer->as<RenderCircleLayer>()->evaluated,
parameters.tileID.overscaledZ));
+ if (layer->as<RenderCircleLayer>()->evaluated.isFeatureStateDependent()) {
+ stateDependentLayers.emplace(layer->getID());
+ }
}
}
void CircleBucket::upload(gl::Context& context) {
- vertexBuffer = context.createVertexBuffer(std::move(vertices));
- indexBuffer = context.createIndexBuffer(std::move(triangles));
-
+ if (!vertexBuffer) {
+ vertexBuffer = context.createVertexBuffer(std::move(vertices));
+ indexBuffer = context.createIndexBuffer(std::move(triangles));
+ }
for (auto& pair : paintPropertyBinders) {
pair.second.upload(context);
}
@@ -94,6 +98,23 @@ void CircleBucket::addFeature(const GeometryTileFeature& feature,
}
}
+void CircleBucket::setFeatureState(const GeometryTileData* tileData,
+ const std::string& sourceLayer,
+ const FeatureStates& featureStates) {
+ if (featureStates.empty() /*|| stateDependentLayers.empty()*/) { return; }
+
+ auto sourceLayerData = tileData->getLayer(sourceLayer);
+ if (sourceLayerData) {
+ for (auto& pair : paintPropertyBinders) {
+ if (stateDependentLayers.count(pair.first) > 0) {
+ if(pair.second.updateVertexVectors(featureStates, *sourceLayerData)) {
+ //Only toggle uploaded if needed.
+ uploaded = false;
+ }
+ }
+ }
+ }
+}
template <class Property>
static float get(const RenderCircleLayer& layer, const std::map<std::string, CircleProgram::PaintPropertyBinders>& paintPropertyBinders) {
auto it = paintPropertyBinders.find(layer.getID());
diff --git a/src/mbgl/renderer/buckets/circle_bucket.hpp b/src/mbgl/renderer/buckets/circle_bucket.hpp
index 0247103ca..f72d45ffe 100644
--- a/src/mbgl/renderer/buckets/circle_bucket.hpp
+++ b/src/mbgl/renderer/buckets/circle_bucket.hpp
@@ -27,6 +27,10 @@ public:
void upload(gl::Context&) override;
+ void setFeatureState(const GeometryTileData*,
+ const std::string&,
+ const FeatureStates&) override;
+
float getQueryRadius(const RenderLayer&) const override;
gl::VertexVector<CircleLayoutVertex> vertices;
@@ -37,6 +41,7 @@ public:
optional<gl::IndexBuffer<gl::Triangles>> indexBuffer;
std::map<std::string, CircleProgram::PaintPropertyBinders> paintPropertyBinders;
+ std::set<std::string> stateDependentLayers;
const MapMode mode;
};
diff --git a/src/mbgl/renderer/paint_property_binder.hpp b/src/mbgl/renderer/paint_property_binder.hpp
index ca6fcc7a9..abb8463ee 100644
--- a/src/mbgl/renderer/paint_property_binder.hpp
+++ b/src/mbgl/renderer/paint_property_binder.hpp
@@ -190,7 +190,6 @@ public:
void updateVertexVector(size_t start, size_t end, const GeometryTileFeature& feature, const PropertyMap& featureState) override {
if (!isUpdateable) { return; }
- assert(start < end && end < vertexVector.vertexSize());
auto evaluated = expression.evaluate(feature, featureState, defaultValue);
this->statistics.add(evaluated);
auto value = attributeValue(evaluated);
@@ -201,8 +200,15 @@ public:
};
void upload(gl::Context& context) override {
- vertexBuffer = context.createVertexBuffer(std::move(vertexVector),
- isUpdateable ? gl::BufferUsage::StaticDraw : gl::BufferUsage::DynamicDraw);
+ if (isUpdateable) {
+ if (!vertexBuffer) {
+ vertexBuffer = context.createVertexBuffer(vertexVector, gl::BufferUsage::DynamicDraw);
+ } else {
+ context.updateVertexBuffer(*vertexBuffer, vertexVector);
+ }
+ } else {
+ vertexBuffer = context.createVertexBuffer(std::move(vertexVector), gl::BufferUsage::StaticDraw);
+ }
}
std::tuple<optional<gl::AttributeBinding>> attributeBinding(const PossiblyEvaluatedPropertyValue<T>& currentValue) const override {
@@ -264,7 +270,7 @@ public:
void updateVertexVector(size_t start, size_t end, const GeometryTileFeature& feature, const PropertyMap& featureState) override {
if (!isUpdateable) { return; }
- assert(start < end && end < vertexVector.vertexSize());
+ assert(start < end && end <= vertexVector.vertexSize());
Range<T> range = expression.evaluate(zoomRange, feature, featureState, defaultValue);
this->statistics.add(range.min);
this->statistics.add(range.max);
@@ -277,8 +283,15 @@ public:
};
void upload(gl::Context& context) override {
- vertexBuffer = context.createVertexBuffer(std::move(vertexVector),
- isUpdateable ? gl::BufferUsage::StaticDraw : gl::BufferUsage::DynamicDraw);
+ if (isUpdateable) {
+ if(!vertexBuffer) {
+ vertexBuffer = context.createVertexBuffer(vertexVector, gl::BufferUsage::DynamicDraw);
+ } else {
+ context.updateVertexBuffer(*vertexBuffer, vertexVector);
+ }
+ } else {
+ vertexBuffer = context.createVertexBuffer(std::move(vertexVector), gl::BufferUsage::StaticDraw);
+ }
}
std::tuple<optional<gl::AttributeBinding>> attributeBinding(const PossiblyEvaluatedPropertyValue<T>& currentValue) const override {
@@ -517,8 +530,7 @@ public:
});
auto featureId = feature.getID();
if (featureId) {
- auto posArray = idMap[*featureId];
- posArray.emplace_back(index, binderBufferOffset, length);
+ idMap[*featureId].emplace_back(index, binderBufferOffset, length);
}
binderBufferOffset = length;
}
@@ -532,8 +544,10 @@ public:
bool updateVertexVectors(const FeatureStates& featureStates, const GeometryTileLayer& layer) {
bool dirty = false;
for (const auto& pair : featureStates) {
- const auto& posArray = idMap[pair.first];
- for (const auto& info : posArray) {
+ const auto posArray = idMap.find(pair.first);
+ if (posArray == idMap.end()) continue;
+
+ for (const auto& info : posArray->second) {
std::unique_ptr<GeometryTileFeature> feature = layer.getFeature(std::get<0>(info));
const size_t startVertex = std::get<1>(info);
const size_t endVertex = std::get<2>(info);
diff --git a/src/mbgl/tile/geometry_tile.cpp b/src/mbgl/tile/geometry_tile.cpp
index f1c68e3ea..9d11fe81e 100644
--- a/src/mbgl/tile/geometry_tile.cpp
+++ b/src/mbgl/tile/geometry_tile.cpp
@@ -127,12 +127,13 @@ void GeometryTile::setFeatureState(std::shared_ptr<FeatureStatesMap> featureStat
if (featureStatesMap_->empty() || pending == true) {
return;
}
-
+ featureStates = featureStatesMap_;
const auto tileData = latestFeatureIndex->getData();
for (auto& entry : buckets) {
auto& bucket = *entry.second;
if (!bucket.hasData()) { continue; }
const auto& sourceLayer = sourceLayers.at(entry.first);
+
const auto& perLayerFeatureStates = featureStates->find(sourceLayer);
if (perLayerFeatureStates != featureStates->end() &&
!perLayerFeatureStates->second.empty()) {