Skip to content

Commit

Permalink
Combine multiple segments into a drawable when sortFeaturesByKey is…
Browse files Browse the repository at this point in the history
… not used (#2060)
  • Loading branch information
TimSylvester authored Jan 30, 2024
1 parent c4f852b commit bf15332
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 16 deletions.
14 changes: 11 additions & 3 deletions src/mbgl/mtl/drawable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@
#include <simd/simd.h>

#include <cassert>
#if !defined(NDEBUG)
#include <sstream>
#endif

namespace mbgl {
namespace mtl {
Expand Down Expand Up @@ -72,11 +75,16 @@ MTL::PrimitiveType getPrimitiveType(const gfx::DrawModeType type) noexcept {

#if !defined(NDEBUG)
std::string debugLabel(const gfx::Drawable& drawable) {
std::string result = drawable.getName();
std::ostringstream oss;
oss << drawable.getID().id() << "/" << drawable.getName() << "/tile=";

if (const auto& tileID = drawable.getTileID()) {
result.append("/tile=").append(util::toString(*tileID));
oss << util::toString(*tileID);
} else {
oss << "(none)";
}
return result;

return oss.str();
}
#endif // !defined(NDEBUG)

Expand Down
52 changes: 39 additions & 13 deletions src/mbgl/renderer/layers/render_symbol_layer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,15 +88,14 @@ struct RenderableSegment {
const LayerRenderData& renderData_,
const SymbolBucket::PaintProperties& bucketPaintProperties_,
float sortKey_,
const SymbolType type_,
const uint8_t overscaledZ_ = 0)
const SymbolType type_)
: segment(segment_),
tile(tile_),
renderData(renderData_),
bucketPaintProperties(bucketPaintProperties_),
sortKey(sortKey_),
type(type_),
overscaledZ(overscaledZ_) {}
overscaledZ(tile.getOverscaledTileID().overscaledZ) {}

SegmentWrapper segment;
const RenderTile& tile;
Expand Down Expand Up @@ -129,6 +128,19 @@ struct RenderableSegment {
}
};

struct SegmentGroup {
// A reference to the first or only segment
RenderableSegment renderable;
// A reference to multiple segments, or none
SegmentVectorWrapper segments;

bool operator<(const SegmentGroup& other) const { return renderable < other.renderable; }
};

namespace {
const SegmentVector<SymbolTextAttributes> emptySegmentVector;
}

#if MLN_LEGACY_RENDERER

template <typename DrawFn>
Expand Down Expand Up @@ -1038,7 +1050,7 @@ void RenderSymbolLayer::update(gfx::ShaderRegistry& shaders,
}

const bool sortFeaturesByKey = !impl_cast(baseImpl).layout.get<SymbolSortKey>().isUndefined();
std::multiset<RenderableSegment> renderableSegments;
std::multiset<SegmentGroup> renderableSegments;
std::unique_ptr<gfx::DrawableBuilder> builder;

const auto currentZoom = static_cast<float>(state.getZoom());
Expand Down Expand Up @@ -1169,13 +1181,20 @@ void RenderSymbolLayer::update(gfx::ShaderRegistry& shaders,
}

float serialKey = 1.0f;
auto addRenderables = [&, it = renderableSegments.begin()](const SymbolBucket::Buffer& buffer,
const SymbolType type) mutable {
for (const auto& segment : buffer.segments) {
const auto key = sortFeaturesByKey ? segment.sortKey : (serialKey += 1.0);
assert(segment.vertexOffset + segment.vertexLength <= buffer.vertices().elements());
it = renderableSegments.emplace_hint(
it, std::ref(segment), tile, renderData, bucketPaintProperties, key, type, tileID.overscaledZ);
auto addRenderables = [&](const SymbolBucket::Buffer& buffer, const SymbolType type) mutable {
if (sortFeaturesByKey) {
// Features need to be rendered in a specific order, so we add each segment individually
for (const auto& segment : buffer.segments) {
assert(segment.vertexOffset + segment.vertexLength <= buffer.vertices().elements());
renderableSegments.emplace(SegmentGroup{
{segment, tile, renderData, bucketPaintProperties, segment.sortKey, type}, emptySegmentVector});
}
} else if (!buffer.segments.empty()) {
// Features can be rendered in the order produced, and as grouped by the bucket
const auto& firstSeg = buffer.segments.front();
renderableSegments.emplace(SegmentGroup{
{firstSeg, tile, renderData, bucketPaintProperties, serialKey, type}, buffer.segments});
serialKey += 1.0;
}
};

Expand Down Expand Up @@ -1208,7 +1227,10 @@ void RenderSymbolLayer::update(gfx::ShaderRegistry& shaders,
};
std::unordered_map<UnwrappedTileID, TileInfo> tileCache;

for (auto& renderable : renderableSegments) {
for (auto& group : renderableSegments) {
const auto& renderable = group.renderable;
const auto& segments = group.segments.get();

const auto isText = (renderable.type == SymbolType::Text);
const auto sdfIcons = (renderable.type == SymbolType::IconSDF);

Expand Down Expand Up @@ -1320,7 +1342,11 @@ void RenderSymbolLayer::update(gfx::ShaderRegistry& shaders,
builder->setDrawableName(layerPrefix + std::string(suffix));
builder->setVertexAttributes(attribs);

builder->setSegments(gfx::Triangles(), buffer.sharedTriangles, &renderable.segment.get(), 1);
if (segments.empty()) {
builder->setSegments(gfx::Triangles(), buffer.sharedTriangles, &renderable.segment.get(), 1);
} else {
builder->setSegments(gfx::Triangles(), buffer.sharedTriangles, segments.data(), segments.size());
}

builder->flush(context);

Expand Down

0 comments on commit bf15332

Please sign in to comment.