summaryrefslogtreecommitdiff
path: root/src/mbgl/renderer
diff options
context:
space:
mode:
authorAndrew Hay Kurtz <andrew.hay.kurtz@gmail.com>2019-10-29 13:49:22 -0700
committerMikhail Pozdnyakov <mikhail.pozdnyakov@mapbox.com>2020-04-14 22:30:40 +0300
commit0c95acf10379266e4142572b6cc7fb1c29271f3b (patch)
tree562c723da46b44a6c5905586f7a25f5194213d15 /src/mbgl/renderer
parent08ad74216442a8c306a3d7ca4696f5ddb780557f (diff)
downloadqtlocation-mapboxgl-0c95acf10379266e4142572b6cc7fb1c29271f3b.tar.gz
Enable 'circle-sort-key' layout property
Diffstat (limited to 'src/mbgl/renderer')
-rw-r--r--src/mbgl/renderer/buckets/circle_bucket.cpp74
-rw-r--r--src/mbgl/renderer/buckets/circle_bucket.hpp13
-rw-r--r--src/mbgl/renderer/layers/render_circle_layer.cpp82
3 files changed, 80 insertions, 89 deletions
diff --git a/src/mbgl/renderer/buckets/circle_bucket.cpp b/src/mbgl/renderer/buckets/circle_bucket.cpp
index 744b559c42..5a1184f5fd 100644
--- a/src/mbgl/renderer/buckets/circle_bucket.cpp
+++ b/src/mbgl/renderer/buckets/circle_bucket.cpp
@@ -10,15 +10,14 @@ namespace mbgl {
using namespace style;
-CircleBucket::CircleBucket(const BucketParameters& parameters, const std::vector<Immutable<style::LayerProperties>>& layers)
- : mode(parameters.mode) {
- for (const auto& layer : layers) {
- paintPropertyBinders.emplace(
- std::piecewise_construct,
- std::forward_as_tuple(layer->baseImpl->id),
- std::forward_as_tuple(
- getEvaluated<CircleLayerProperties>(layer),
- parameters.tileID.overscaledZ));
+CircleBucket::CircleBucket(const std::map<std::string, Immutable<LayerProperties>>& layerPaintProperties,
+ const MapMode mode_,
+ const float zoom)
+ : mode(mode_) {
+ for (const auto& pair : layerPaintProperties) {
+ paintPropertyBinders.emplace(std::piecewise_construct,
+ std::forward_as_tuple(pair.first),
+ std::forward_as_tuple(getEvaluated<CircleLayerProperties>(pair.second), zoom));
}
}
@@ -41,63 +40,6 @@ bool CircleBucket::hasData() const {
return !segments.empty();
}
-void CircleBucket::addFeature(const GeometryTileFeature& feature,
- const GeometryCollection& geometry,
- const ImagePositions&,
- const PatternLayerMap&,
- std::size_t featureIndex,
- const CanonicalTileID& canonical) {
- constexpr const uint16_t vertexLength = 4;
-
- for (auto& circle : geometry) {
- for(auto& point : circle) {
- auto x = point.x;
- auto y = point.y;
-
- // Do not include points that are outside the tile boundaries.
- // Include all points in Still mode. You need to include points from
- // neighbouring tiles so that they are not clipped at tile boundaries.
- if ((mode == MapMode::Continuous) &&
- (x < 0 || x >= util::EXTENT || y < 0 || y >= util::EXTENT)) continue;
-
- if (segments.empty() || segments.back().vertexLength + vertexLength > std::numeric_limits<uint16_t>::max()) {
- // Move to a new segments because the old one can't hold the geometry.
- segments.emplace_back(vertices.elements(), triangles.elements());
- }
-
- // this geometry will be of the Point type, and we'll derive
- // two triangles from it.
- //
- // ┌─────────┐
- // │ 4 3 │
- // │ │
- // │ 1 2 │
- // └─────────┘
- //
- vertices.emplace_back(CircleProgram::vertex(point, -1, -1)); // 1
- vertices.emplace_back(CircleProgram::vertex(point, 1, -1)); // 2
- vertices.emplace_back(CircleProgram::vertex(point, 1, 1)); // 3
- vertices.emplace_back(CircleProgram::vertex(point, -1, 1)); // 4
-
- auto& segment = segments.back();
- assert(segment.vertexLength <= std::numeric_limits<uint16_t>::max());
- uint16_t index = segment.vertexLength;
-
- // 1, 2, 3
- // 1, 4, 3
- triangles.emplace_back(index, index + 1, index + 2);
- triangles.emplace_back(index, index + 3, index + 2);
-
- segment.vertexLength += vertexLength;
- segment.indexLength += 6;
- }
- }
-
- for (auto& pair : paintPropertyBinders) {
- pair.second.populateVertexVectors(feature, vertices.elements(), featureIndex, {}, {}, canonical);
- }
-}
-
template <class Property>
static float get(const CirclePaintProperties::PossiblyEvaluated& evaluated, const std::string& id, const std::map<std::string, CircleProgram::Binders>& paintPropertyBinders) {
auto it = paintPropertyBinders.find(id);
diff --git a/src/mbgl/renderer/buckets/circle_bucket.hpp b/src/mbgl/renderer/buckets/circle_bucket.hpp
index 17ddd9dc10..221deb5f17 100644
--- a/src/mbgl/renderer/buckets/circle_bucket.hpp
+++ b/src/mbgl/renderer/buckets/circle_bucket.hpp
@@ -15,15 +15,12 @@ class BucketParameters;
class CircleBucket final : public Bucket {
public:
- CircleBucket(const BucketParameters&, const std::vector<Immutable<style::LayerProperties>>&);
- ~CircleBucket() override;
+ using PossiblyEvaluatedLayoutProperties = style::CircleLayoutProperties::PossiblyEvaluated;
- void addFeature(const GeometryTileFeature&,
- const GeometryCollection&,
- const ImagePositions&,
- const PatternLayerMap&,
- std::size_t,
- const CanonicalTileID&) override;
+ CircleBucket(const std::map<std::string, Immutable<style::LayerProperties>>& layerPaintProperties,
+ const MapMode mode,
+ const float zoom);
+ ~CircleBucket() override;
bool hasData() const override;
diff --git a/src/mbgl/renderer/layers/render_circle_layer.cpp b/src/mbgl/renderer/layers/render_circle_layer.cpp
index a8a70d2a3a..a85b82b2d2 100644
--- a/src/mbgl/renderer/layers/render_circle_layer.cpp
+++ b/src/mbgl/renderer/layers/render_circle_layer.cpp
@@ -17,6 +17,32 @@ using namespace style;
namespace {
+struct RenderableSegment {
+ RenderableSegment(const Segment<CircleAttributes>& segment_,
+ CircleProgram& programInstance_,
+ const CircleBucket& bucket_,
+ const CircleProgram::UniformValues& allUniformValues_,
+ const CircleProgram::AttributeBindings& allAttributeBindings_,
+ float sortKey_)
+ : segment(segment_),
+ programInstance(programInstance_),
+ bucket(bucket_),
+ allUniformValues(allUniformValues_),
+ allAttributeBindings(allAttributeBindings_),
+ sortKey(sortKey_) {}
+
+ const Segment<CircleAttributes>& segment;
+ CircleProgram& programInstance;
+ const CircleBucket& bucket;
+ const CircleProgram::UniformValues& allUniformValues;
+ const CircleProgram::AttributeBindings& allAttributeBindings;
+ const float sortKey;
+
+ friend bool operator<(const RenderableSegment& lhs, const RenderableSegment& rhs) {
+ return lhs.sortKey < rhs.sortKey;
+ }
+};
+
inline const style::CircleLayer::Impl& impl_cast(const Immutable<style::Layer::Impl>& impl) {
assert(impl->getTypeInfo() == CircleLayer::Impl::staticTypeInfo());
return static_cast<const style::CircleLayer::Impl&>(*impl);
@@ -63,6 +89,9 @@ void RenderCircleLayer::render(PaintParameters& parameters) {
return;
}
+ const bool sortFeaturesByKey = !impl_cast(baseImpl).layout.get<CircleSortKey>().isUndefined();
+ std::multiset<RenderableSegment> renderableSegments{};
+
for (const RenderTile& tile : *renderTiles) {
const LayerRenderData* renderData = getRenderDataForPass(tile, parameters.pass);
if (!renderData) {
@@ -96,21 +125,44 @@ void RenderCircleLayer::render(PaintParameters& parameters) {
checkRenderability(parameters, CircleProgram::activeBindingCount(allAttributeBindings));
- programInstance.draw(
- parameters.context,
- *parameters.renderPass,
- gfx::Triangles(),
- parameters.depthModeForSublayer(0, gfx::DepthMaskType::ReadOnly),
- gfx::StencilMode::disabled(),
- parameters.colorModeForRenderPass(),
- gfx::CullFaceMode::disabled(),
- *bucket.indexBuffer,
- bucket.segments,
- allUniformValues,
- allAttributeBindings,
- CircleProgram::TextureBindings{},
- getID()
- );
+ if (sortFeaturesByKey) {
+ for (auto& segment : bucket.segments) {
+ renderableSegments.emplace(
+ segment, programInstance, bucket, allUniformValues, allAttributeBindings, segment.sortKey);
+ }
+ } else {
+ programInstance.draw(parameters.context,
+ *parameters.renderPass,
+ gfx::Triangles(),
+ parameters.depthModeForSublayer(0, gfx::DepthMaskType::ReadOnly),
+ gfx::StencilMode::disabled(),
+ parameters.colorModeForRenderPass(),
+ gfx::CullFaceMode::disabled(),
+ *bucket.indexBuffer,
+ bucket.segments,
+ allUniformValues,
+ allAttributeBindings,
+ CircleProgram::TextureBindings{},
+ getID());
+ }
+ }
+
+ if (sortFeaturesByKey) {
+ for (const auto& renderable : renderableSegments) {
+ renderable.programInstance.draw(parameters.context,
+ *parameters.renderPass,
+ gfx::Triangles(),
+ parameters.depthModeForSublayer(0, gfx::DepthMaskType::ReadOnly),
+ gfx::StencilMode::disabled(),
+ parameters.colorModeForRenderPass(),
+ gfx::CullFaceMode::disabled(),
+ *renderable.bucket.indexBuffer,
+ renderable.segment,
+ renderable.allUniformValues,
+ renderable.allAttributeBindings,
+ CircleProgram::TextureBindings{},
+ getID());
+ }
}
}