diff options
author | Asheem Mamoowala <asheem.mamoowala@mapbox.com> | 2018-10-31 16:58:59 -0700 |
---|---|---|
committer | Asheem Mamoowala <asheem.mamoowala@mapbox.com> | 2018-10-31 16:58:59 -0700 |
commit | 80cba7200f26140d265159e0721a573ffc4c40eb (patch) | |
tree | d05ae0faa3769bb68269248cb04cc8bd2fdf87fe | |
parent | 6f51186dc1dfb52f5add46cb24825873d173ecef (diff) |
Update vertex vectors and upload updated buffers
-rw-r--r-- | src/mbgl/gl/context.hpp | 14 | ||||
-rw-r--r-- | src/mbgl/gl/vertex_buffer.hpp | 3 | ||||
-rw-r--r-- | src/mbgl/renderer/buckets/circle_bucket.cpp | 27 | ||||
-rw-r--r-- | src/mbgl/renderer/buckets/circle_bucket.hpp | 5 | ||||
-rw-r--r-- | src/mbgl/renderer/paint_property_binder.hpp | 34 | ||||
-rw-r--r-- | src/mbgl/tile/geometry_tile.cpp | 3 |
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()) { |