Render drawables in order (#1321)
This commit is contained in:
committed by
Bart Louwers
parent
eac6c84508
commit
d094b9928e
@@ -181,7 +181,7 @@ protected:
|
||||
bool is3D = false;
|
||||
bool isCustom = false;
|
||||
std::string name;
|
||||
util::SimpleIdentity uniqueID;
|
||||
const util::SimpleIdentity uniqueID;
|
||||
gfx::ShaderProgramBasePtr shader;
|
||||
mbgl::RenderPass renderPass;
|
||||
std::optional<OverscaledTileID> tileID;
|
||||
@@ -203,7 +203,7 @@ using UniqueDrawable = std::unique_ptr<Drawable>;
|
||||
|
||||
/// Comparator for sorting drawable pointers primarily by draw priority
|
||||
struct DrawableLessByPriority {
|
||||
DrawableLessByPriority(bool descending)
|
||||
DrawableLessByPriority(bool descending = false)
|
||||
: desc(descending) {}
|
||||
bool operator()(const Drawable& left, const Drawable& right) const {
|
||||
const auto& a = desc ? right : left;
|
||||
@@ -213,6 +213,8 @@ struct DrawableLessByPriority {
|
||||
}
|
||||
return a.getId() < b.getId();
|
||||
}
|
||||
bool operator()(const Drawable* left, const Drawable* right) const { return operator()(*left, *right); }
|
||||
bool operator()(const UniqueDrawable& left, const UniqueDrawable& right) const { return operator()(*left, *right); }
|
||||
bool operator()(const DrawablePtr& left, const DrawablePtr& right) const {
|
||||
const auto& a = desc ? right : left;
|
||||
const auto& b = desc ? left : right;
|
||||
|
||||
@@ -66,12 +66,14 @@ public:
|
||||
/// Called at the end of each frame
|
||||
virtual void postRender(RenderOrchestrator&, PaintParameters&) {}
|
||||
|
||||
/// Call the provided function for each drawable in undefined order
|
||||
virtual void observeDrawables(std::function<void(gfx::Drawable&)>) = 0;
|
||||
virtual void observeDrawables(std::function<void(const gfx::Drawable&)>) const = 0;
|
||||
/// Call the provided function for each drawable in priority order
|
||||
virtual void observeDrawables(const std::function<void(gfx::Drawable&)>&&) = 0;
|
||||
virtual void observeDrawables(const std::function<void(const gfx::Drawable&)>&&) const = 0;
|
||||
|
||||
/// Call the provided function for each drawable in undefined order, allowing ownership to be taken.
|
||||
virtual void observeDrawables(std::function<void(gfx::UniqueDrawable&)>) = 0;
|
||||
/// Call the provided function for each drawable in undefined order, allowing for removal.
|
||||
/// @param f A function called with each drawable, returning true to keep and false to discard it.
|
||||
/// @return The number of items removed
|
||||
virtual std::size_t observeDrawablesRemove(const std::function<bool(gfx::Drawable&)>&& f) = 0;
|
||||
|
||||
/// Attach a tweaker to be run on this layer group for each frame
|
||||
void setLayerTweaker(LayerTweakerPtr tweaker) { layerTweaker = std::move(tweaker); }
|
||||
@@ -100,13 +102,15 @@ public:
|
||||
std::vector<gfx::UniqueDrawable> removeDrawables(mbgl::RenderPass, const OverscaledTileID&);
|
||||
void addDrawable(mbgl::RenderPass, const OverscaledTileID&, gfx::UniqueDrawable&&);
|
||||
|
||||
void observeDrawables(std::function<void(gfx::Drawable&)>) override;
|
||||
void observeDrawables(std::function<void(const gfx::Drawable&)>) const override;
|
||||
void observeDrawables(std::function<void(gfx::UniqueDrawable&)>) override;
|
||||
void observeDrawables(const std::function<void(gfx::Drawable&)>&&) override;
|
||||
void observeDrawables(const std::function<void(const gfx::Drawable&)>&&) const override;
|
||||
std::size_t observeDrawablesRemove(const std::function<bool(gfx::Drawable&)>&&) override;
|
||||
|
||||
/// Call the provided function for each drawable for the given tile
|
||||
void observeDrawables(mbgl::RenderPass, const OverscaledTileID&, std::function<void(gfx::Drawable&)>&&);
|
||||
void observeDrawables(mbgl::RenderPass, const OverscaledTileID&, std::function<void(const gfx::Drawable&)>&&) const;
|
||||
void observeDrawables(mbgl::RenderPass, const OverscaledTileID&, const std::function<void(gfx::Drawable&)>&&);
|
||||
void observeDrawables(mbgl::RenderPass,
|
||||
const OverscaledTileID&,
|
||||
const std::function<void(const gfx::Drawable&)>&&) const;
|
||||
|
||||
std::size_t clearDrawables() override;
|
||||
|
||||
@@ -129,9 +133,9 @@ public:
|
||||
std::vector<gfx::UniqueDrawable> removeDrawables(mbgl::RenderPass);
|
||||
void addDrawable(gfx::UniqueDrawable&&);
|
||||
|
||||
void observeDrawables(std::function<void(gfx::Drawable&)>) override;
|
||||
void observeDrawables(std::function<void(const gfx::Drawable&)>) const override;
|
||||
void observeDrawables(std::function<void(gfx::UniqueDrawable&)>) override;
|
||||
void observeDrawables(const std::function<void(gfx::Drawable&)>&&) override;
|
||||
void observeDrawables(const std::function<void(const gfx::Drawable&)>&&) const override;
|
||||
std::size_t observeDrawablesRemove(const std::function<bool(gfx::Drawable&)>&&) override;
|
||||
|
||||
std::size_t clearDrawables() override;
|
||||
|
||||
|
||||
@@ -4,20 +4,18 @@
|
||||
#include <mbgl/renderer/paint_parameters.hpp>
|
||||
#include <mbgl/renderer/render_orchestrator.hpp>
|
||||
|
||||
#include <unordered_map>
|
||||
#include <set>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
struct LayerGroup::Impl {
|
||||
Impl(std::size_t capacity) { drawables.reserve(capacity); }
|
||||
|
||||
using DrawableCollection = std::vector<gfx::UniqueDrawable>;
|
||||
using DrawableCollection = std::set<gfx::UniqueDrawable, gfx::DrawableLessByPriority>;
|
||||
DrawableCollection drawables;
|
||||
};
|
||||
|
||||
LayerGroup::LayerGroup(int32_t layerIndex_, std::size_t initialCapacity, std::string name_)
|
||||
LayerGroup::LayerGroup(int32_t layerIndex_, std::size_t /*initialCapacity*/, std::string name_)
|
||||
: LayerGroupBase(layerIndex_, std::move(name_)),
|
||||
impl(std::make_unique<Impl>(initialCapacity)) {}
|
||||
impl(std::make_unique<Impl>()) {}
|
||||
|
||||
LayerGroup::~LayerGroup() = default;
|
||||
|
||||
@@ -26,10 +24,10 @@ std::size_t LayerGroup::getDrawableCount() const {
|
||||
}
|
||||
|
||||
void LayerGroup::addDrawable(gfx::UniqueDrawable&& drawable) {
|
||||
impl->drawables.emplace_back(std::move(drawable));
|
||||
impl->drawables.emplace(std::move(drawable));
|
||||
}
|
||||
|
||||
void LayerGroup::observeDrawables(std::function<void(gfx::Drawable&)> f) {
|
||||
void LayerGroup::observeDrawables(const std::function<void(gfx::Drawable&)>&& f) {
|
||||
for (const auto& item : impl->drawables) {
|
||||
if (item) {
|
||||
f(*item);
|
||||
@@ -37,7 +35,7 @@ void LayerGroup::observeDrawables(std::function<void(gfx::Drawable&)> f) {
|
||||
}
|
||||
}
|
||||
|
||||
void LayerGroup::observeDrawables(std::function<void(const gfx::Drawable&)> f) const {
|
||||
void LayerGroup::observeDrawables(const std::function<void(const gfx::Drawable&)>&& f) const {
|
||||
for (const auto& item : impl->drawables) {
|
||||
if (item) {
|
||||
f(*item);
|
||||
@@ -45,20 +43,20 @@ void LayerGroup::observeDrawables(std::function<void(const gfx::Drawable&)> f) c
|
||||
}
|
||||
}
|
||||
|
||||
void LayerGroup::observeDrawables(std::function<void(gfx::UniqueDrawable&)> f) {
|
||||
for (auto i = impl->drawables.begin(); i != impl->drawables.end();) {
|
||||
auto& drawable = *i;
|
||||
if (drawable) {
|
||||
f(drawable);
|
||||
}
|
||||
if (drawable) {
|
||||
// Not removed, keep going
|
||||
++i;
|
||||
} else {
|
||||
// Removed, take it out of the map
|
||||
i = impl->drawables.erase(i);
|
||||
std::size_t LayerGroup::observeDrawablesRemove(const std::function<bool(gfx::Drawable&)>&& f) {
|
||||
decltype(impl->drawables) newSet;
|
||||
const auto oldSize = impl->drawables.size();
|
||||
while (!impl->drawables.empty()) {
|
||||
// set members are immutable, since changes could affect its position, so extract each item
|
||||
gfx::UniqueDrawable drawable = std::move(impl->drawables.extract(impl->drawables.begin()).value());
|
||||
if (f(*drawable)) {
|
||||
// Not removed, keep it, but in a new set so that if the key value
|
||||
// has increased, we don't see it again during this iteration.
|
||||
newSet.emplace_hint(newSet.end(), std::move(drawable));
|
||||
}
|
||||
}
|
||||
std::swap(impl->drawables, newSet);
|
||||
return (oldSize - impl->drawables.size());
|
||||
}
|
||||
|
||||
std::size_t LayerGroup::clearDrawables() {
|
||||
|
||||
@@ -203,6 +203,10 @@ void RenderBackgroundLayer::prepare(const LayerPrepareParameters& params) {
|
||||
addPatternIfNeeded(evaluated.get<BackgroundPattern>().from.id(), params);
|
||||
addPatternIfNeeded(evaluated.get<BackgroundPattern>().to.id(), params);
|
||||
}
|
||||
|
||||
#if MLN_DRAWABLE_RENDERER
|
||||
updateRenderTileIDs();
|
||||
#endif // MLN_DRAWABLE_RENDERER
|
||||
}
|
||||
|
||||
#if MLN_DRAWABLE_RENDERER
|
||||
@@ -275,21 +279,11 @@ void RenderBackgroundLayer::update(gfx::ShaderRegistry& shaders,
|
||||
const auto indexes = RenderStaticData::quadTriangleIndices();
|
||||
const auto segs = RenderStaticData::tileTriangleSegments();
|
||||
|
||||
// Put the tile cover into a searchable form.
|
||||
// TODO: Likely better to sort and `std::binary_search` the vector.
|
||||
// If it's returned in a well-defined order, we might not even need to sort.
|
||||
const std::unordered_set<OverscaledTileID> newTileIDs(tileCover.begin(), tileCover.end());
|
||||
|
||||
std::unique_ptr<gfx::DrawableBuilder> builder;
|
||||
|
||||
tileLayerGroup->observeDrawables([&](gfx::UniqueDrawable& drawable) {
|
||||
tileLayerGroup->observeDrawables([&](gfx::Drawable& drawable) -> bool {
|
||||
// Has this tile dropped out of the cover set?
|
||||
const auto tileID = drawable->getTileID();
|
||||
if (tileID && newTileIDs.find(*tileID) == newTileIDs.end()) {
|
||||
drawable.reset();
|
||||
++stats.drawablesRemoved;
|
||||
return;
|
||||
}
|
||||
return (!drawable.getTileID() || renderTileIDs.find(*drawable.getTileID()) != renderTileIDs.end());
|
||||
});
|
||||
|
||||
// For each tile in the cover set, add a tile drawable if one doesn't already exist.
|
||||
|
||||
@@ -300,28 +300,17 @@ void RenderCircleLayer::update(gfx::ShaderRegistry& shaders,
|
||||
return;
|
||||
}
|
||||
|
||||
std::unordered_set<OverscaledTileID> newTileIDs(renderTiles->size());
|
||||
std::transform(renderTiles->begin(),
|
||||
renderTiles->end(),
|
||||
std::inserter(newTileIDs, newTileIDs.begin()),
|
||||
[](const auto& renderTile) -> OverscaledTileID { return renderTile.get().getOverscaledTileID(); });
|
||||
|
||||
std::unique_ptr<gfx::DrawableBuilder> circleBuilder;
|
||||
std::vector<gfx::DrawablePtr> newTiles;
|
||||
gfx::VertexAttributeArray circleVertexAttrs;
|
||||
auto renderPass = RenderPass::Translucent;
|
||||
constexpr auto renderPass = RenderPass::Translucent;
|
||||
|
||||
if (!(mbgl::underlying_type(renderPass) & evaluatedProperties->renderPasses)) {
|
||||
return;
|
||||
}
|
||||
|
||||
tileLayerGroup->observeDrawables([&](gfx::UniqueDrawable& drawable) {
|
||||
const auto tileID = drawable->getTileID();
|
||||
if (tileID && newTileIDs.find(*tileID) == newTileIDs.end()) {
|
||||
// remove it
|
||||
drawable.reset();
|
||||
++stats.drawablesRemoved;
|
||||
}
|
||||
stats.drawablesRemoved += tileLayerGroup->observeDrawablesRemove([&](gfx::Drawable& drawable) {
|
||||
return (!drawable.getTileID() || renderTileIDs.find(*drawable.getTileID()) != renderTileIDs.end());
|
||||
});
|
||||
|
||||
const auto& evaluated = static_cast<const CircleLayerProperties&>(*evaluatedProperties).evaluated;
|
||||
|
||||
@@ -92,14 +92,6 @@ bool RenderFillExtrusionLayer::is3D() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
void RenderFillExtrusionLayer::prepare(const LayerPrepareParameters& params) {
|
||||
RenderLayer::prepare(params);
|
||||
|
||||
#if MLN_DRAWABLE_RENDERER
|
||||
updateRenderTileIDs();
|
||||
#endif // MLN_DRAWABLE_RENDERER
|
||||
}
|
||||
|
||||
#if MLN_LEGACY_RENDERER
|
||||
void RenderFillExtrusionLayer::render(PaintParameters& parameters) {
|
||||
assert(renderTiles);
|
||||
@@ -315,13 +307,10 @@ void RenderFillExtrusionLayer::update(gfx::ShaderRegistry& shaders,
|
||||
// in the "3D pass".
|
||||
constexpr auto drawPass = RenderPass::Translucent;
|
||||
|
||||
tileLayerGroup->observeDrawables([&](gfx::UniqueDrawable& drawable) {
|
||||
stats.drawablesRemoved += tileLayerGroup->observeDrawablesRemove([&](gfx::Drawable& drawable) {
|
||||
// If the render pass has changed or the tile has dropped out of the cover set, remove it.
|
||||
const auto tileID = drawable->getTileID();
|
||||
if (drawable->getRenderPass() != drawPass || (tileID && renderTileIDs.find(*tileID) == renderTileIDs.end())) {
|
||||
drawable.reset();
|
||||
++stats.drawablesRemoved;
|
||||
}
|
||||
return (drawable.getRenderPass() == drawPass &&
|
||||
(!drawable.getTileID() || renderTileIDs.find(*drawable.getTileID()) != renderTileIDs.end()));
|
||||
});
|
||||
|
||||
const auto zoom = static_cast<float>(state.getZoom());
|
||||
|
||||
@@ -23,7 +23,6 @@ private:
|
||||
bool hasTransition() const override;
|
||||
bool hasCrossfade() const override;
|
||||
bool is3D() const override;
|
||||
void prepare(const LayerPrepareParameters&) override;
|
||||
|
||||
#if MLN_LEGACY_RENDERER
|
||||
void render(PaintParameters&) override;
|
||||
|
||||
@@ -325,12 +325,6 @@ void RenderFillLayer::update(gfx::ShaderRegistry& shaders,
|
||||
return;
|
||||
}
|
||||
|
||||
std::unordered_set<OverscaledTileID> newTileIDs(renderTiles->size());
|
||||
std::transform(renderTiles->begin(),
|
||||
renderTiles->end(),
|
||||
std::inserter(newTileIDs, newTileIDs.begin()),
|
||||
[](const auto& renderTile) -> OverscaledTileID { return renderTile.get().getOverscaledTileID(); });
|
||||
|
||||
std::unique_ptr<gfx::DrawableBuilder> fillBuilder;
|
||||
std::unique_ptr<gfx::DrawableBuilder> outlineBuilder;
|
||||
std::unique_ptr<gfx::DrawableBuilder> patternBuilder;
|
||||
@@ -364,13 +358,10 @@ void RenderFillLayer::update(gfx::ShaderRegistry& shaders,
|
||||
builder.setEnableStencil(true);
|
||||
};
|
||||
|
||||
tileLayerGroup->observeDrawables([&](gfx::UniqueDrawable& drawable) {
|
||||
stats.drawablesRemoved += tileLayerGroup->observeDrawablesRemove([&](gfx::Drawable& drawable) {
|
||||
// If the render pass has changed or the tile has dropped out of the cover set, remove it.
|
||||
const auto tileID = drawable->getTileID();
|
||||
if (drawable->getRenderPass() != renderPass || (tileID && newTileIDs.find(*tileID) == newTileIDs.end())) {
|
||||
drawable.reset();
|
||||
++stats.drawablesRemoved;
|
||||
}
|
||||
return (drawable.getRenderPass() == renderPass &&
|
||||
(!drawable.getTileID() || renderTileIDs.find(*drawable.getTileID()) != renderTileIDs.end()));
|
||||
});
|
||||
|
||||
for (const RenderTile& tile : *renderTiles) {
|
||||
|
||||
@@ -317,12 +317,6 @@ void RenderHeatmapLayer::update(gfx::ShaderRegistry& shaders,
|
||||
return;
|
||||
}
|
||||
|
||||
std::unordered_set<OverscaledTileID> newTileIDs(renderTiles->size());
|
||||
std::transform(renderTiles->begin(),
|
||||
renderTiles->end(),
|
||||
std::inserter(newTileIDs, newTileIDs.begin()),
|
||||
[](const auto& renderTile) -> OverscaledTileID { return renderTile.get().getOverscaledTileID(); });
|
||||
|
||||
std::unique_ptr<gfx::DrawableBuilder> heatmapBuilder;
|
||||
std::vector<gfx::DrawablePtr> newTiles;
|
||||
gfx::VertexAttributeArray heatmapVertexAttrs;
|
||||
@@ -332,13 +326,8 @@ void RenderHeatmapLayer::update(gfx::ShaderRegistry& shaders,
|
||||
return;
|
||||
}
|
||||
|
||||
tileLayerGroup->observeDrawables([&](gfx::UniqueDrawable& drawable) {
|
||||
const auto tileID = drawable->getTileID();
|
||||
if (tileID && newTileIDs.find(*tileID) == newTileIDs.end()) {
|
||||
// remove it
|
||||
drawable.reset();
|
||||
++stats.drawablesRemoved;
|
||||
}
|
||||
stats.drawablesRemoved += tileLayerGroup->observeDrawablesRemove([&](gfx::Drawable& drawable) {
|
||||
return (!drawable.getTileID() || renderTileIDs.find(*drawable.getTileID()) != renderTileIDs.end());
|
||||
});
|
||||
|
||||
const auto& evaluated = static_cast<const HeatmapLayerProperties&>(*evaluatedProperties).evaluated;
|
||||
|
||||
@@ -90,7 +90,7 @@ void RenderLineLayer::prepare(const LayerPrepareParameters& params) {
|
||||
const auto& evaluated = getEvaluated<LineLayerProperties>(renderData->layerProperties);
|
||||
if (evaluated.get<LineDasharray>().from.empty()) continue;
|
||||
|
||||
auto& bucket = static_cast<LineBucket&>(*renderData->bucket);
|
||||
const auto& bucket = static_cast<const LineBucket&>(*renderData->bucket);
|
||||
const LinePatternCap cap = bucket.layout.get<LineCap>() == LineCapType::Round ? LinePatternCap::Round
|
||||
: LinePatternCap::Square;
|
||||
// Ensures that the dash data gets added to the atlas.
|
||||
@@ -441,22 +441,13 @@ void RenderLineLayer::update(gfx::ShaderRegistry& shaders,
|
||||
lineSDFShaderGroup = shaders.getShaderGroup("LineSDFShader");
|
||||
}
|
||||
|
||||
std::unordered_set<OverscaledTileID> newTileIDs(renderTiles->size());
|
||||
std::transform(renderTiles->begin(),
|
||||
renderTiles->end(),
|
||||
std::inserter(newTileIDs, newTileIDs.begin()),
|
||||
[](const auto& renderTile) -> OverscaledTileID { return renderTile.get().getOverscaledTileID(); });
|
||||
|
||||
const RenderPass renderPass = static_cast<RenderPass>(evaluatedProperties->renderPasses &
|
||||
~mbgl::underlying_type(RenderPass::Opaque));
|
||||
|
||||
tileLayerGroup->observeDrawables([&](gfx::UniqueDrawable& drawable) {
|
||||
stats.drawablesRemoved += tileLayerGroup->observeDrawablesRemove([&](gfx::Drawable& drawable) {
|
||||
// If the render pass has changed or the tile has dropped out of the cover set, remove it.
|
||||
const auto tileID = drawable->getTileID();
|
||||
if (drawable->getRenderPass() != renderPass || (tileID && newTileIDs.find(*tileID) == newTileIDs.end())) {
|
||||
drawable.reset();
|
||||
++stats.drawablesRemoved;
|
||||
}
|
||||
return (drawable.getRenderPass() == renderPass &&
|
||||
(!drawable.getTileID() || renderTileIDs.find(*drawable.getTileID()) != renderTileIDs.end()));
|
||||
});
|
||||
|
||||
auto createLineBuilder = [&](const std::string& name,
|
||||
|
||||
@@ -97,6 +97,10 @@ void RenderRasterLayer::prepare(const LayerPrepareParameters& params) {
|
||||
imageData = params.source->getImageRenderData();
|
||||
// It is possible image data is not available until the source loads it.
|
||||
assert(renderTiles || imageData || !params.source->isEnabled());
|
||||
|
||||
#if MLN_DRAWABLE_RENDERER
|
||||
updateRenderTileIDs();
|
||||
#endif // MLN_DRAWABLE_RENDERER
|
||||
}
|
||||
|
||||
#if MLN_LEGACY_RENDERER
|
||||
@@ -416,19 +420,9 @@ void RenderRasterLayer::update(gfx::ShaderRegistry& shaders,
|
||||
}
|
||||
} else if (renderTiles) {
|
||||
if (layerGroup) {
|
||||
layerGroup->observeDrawables([&](gfx::UniqueDrawable& drawable) {
|
||||
stats.drawablesRemoved += layerGroup->observeDrawablesRemove([&](gfx::Drawable& drawable) {
|
||||
// Has this tile dropped out of the cover set?
|
||||
if (const auto it = std::find_if(renderTiles->begin(),
|
||||
renderTiles->end(),
|
||||
[&drawable](const auto& renderTile) {
|
||||
return drawable->getTileID() ==
|
||||
renderTile.get().getOverscaledTileID();
|
||||
});
|
||||
it == renderTiles->end()) {
|
||||
// remove it
|
||||
drawable.reset();
|
||||
++stats.drawablesRemoved;
|
||||
}
|
||||
return (!drawable.getTileID() || renderTileIDs.find(*drawable.getTileID()) != renderTileIDs.end());
|
||||
});
|
||||
} else {
|
||||
// Set up a tile layer group
|
||||
|
||||
@@ -831,14 +831,14 @@ void RenderSymbolLayer::update(gfx::ShaderRegistry& shaders,
|
||||
}
|
||||
|
||||
auto* tileLayerGroup = static_cast<TileLayerGroup*>(layerGroup.get());
|
||||
tileLayerGroup->observeDrawables([&](gfx::UniqueDrawable& drawable) {
|
||||
stats.drawablesRemoved += tileLayerGroup->observeDrawablesRemove([&](gfx::Drawable& drawable) {
|
||||
// If the render pass has changed or the tile has dropped out of the cover set, remove it.
|
||||
const auto tileID = drawable->getTileID();
|
||||
if (drawable->getRenderPass() != passes || (tileID && renderTileIDs.find(*tileID) == renderTileIDs.end())) {
|
||||
drawable.reset();
|
||||
const auto& tileID = drawable.getTileID();
|
||||
if (drawable.getRenderPass() != passes || (tileID && renderTileIDs.find(*tileID) == renderTileIDs.end())) {
|
||||
tileBucketInstances.erase(*tileID);
|
||||
++stats.drawablesRemoved;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
const bool sortFeaturesByKey = !impl_cast(baseImpl).layout.get<SymbolSortKey>().isUndefined();
|
||||
|
||||
@@ -58,6 +58,10 @@ void RenderLayer::prepare(const LayerPrepareParameters& params) {
|
||||
assert(params.source->isEnabled());
|
||||
renderTiles = params.source->getRenderTiles();
|
||||
addRenderPassesFromTiles();
|
||||
|
||||
#if MLN_DRAWABLE_RENDERER
|
||||
updateRenderTileIDs();
|
||||
#endif // MLN_DRAWABLE_RENDERER
|
||||
}
|
||||
|
||||
std::optional<Color> RenderLayer::getSolidBackground() const {
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <mbgl/renderer/render_orchestrator.hpp>
|
||||
|
||||
#include <unordered_map>
|
||||
#include <set>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
@@ -22,11 +23,14 @@ struct TileLayerGroupTileKey {
|
||||
};
|
||||
|
||||
struct TileLayerGroup::Impl {
|
||||
Impl(std::size_t capacity)
|
||||
: tileDrawables(capacity) {}
|
||||
Impl(std::size_t initialCapacity)
|
||||
: drawablesByTile(initialCapacity) {}
|
||||
|
||||
using TileMap = std::unordered_multimap<TileLayerGroupTileKey, gfx::UniqueDrawable, TileLayerGroupTileKey::hash>;
|
||||
TileMap tileDrawables;
|
||||
TileMap drawablesByTile;
|
||||
|
||||
using DrawableMap = std::set<gfx::Drawable*, gfx::DrawableLessByPriority>;
|
||||
DrawableMap sortedDrawables;
|
||||
};
|
||||
|
||||
LayerGroupBase::LayerGroupBase(int32_t layerIndex_, std::string name_)
|
||||
@@ -40,80 +44,97 @@ TileLayerGroup::TileLayerGroup(int32_t layerIndex_, std::size_t initialCapacity,
|
||||
TileLayerGroup::~TileLayerGroup() = default;
|
||||
|
||||
std::size_t TileLayerGroup::getDrawableCount() const {
|
||||
return impl->tileDrawables.size();
|
||||
return impl->drawablesByTile.size();
|
||||
}
|
||||
|
||||
static const gfx::UniqueDrawable no_tile;
|
||||
|
||||
std::size_t TileLayerGroup::getDrawableCount(mbgl::RenderPass pass, const OverscaledTileID& id) const {
|
||||
const auto range = impl->tileDrawables.equal_range({pass, id});
|
||||
assert(impl->drawablesByTile.size() == impl->sortedDrawables.size());
|
||||
const auto range = impl->drawablesByTile.equal_range({pass, id});
|
||||
return std::distance(range.first, range.second);
|
||||
}
|
||||
|
||||
std::vector<gfx::UniqueDrawable> TileLayerGroup::removeDrawables(mbgl::RenderPass pass, const OverscaledTileID& id) {
|
||||
const auto range = impl->tileDrawables.equal_range({pass, id});
|
||||
assert(impl->drawablesByTile.size() == impl->sortedDrawables.size());
|
||||
const auto range = impl->drawablesByTile.equal_range({pass, id});
|
||||
std::vector<gfx::UniqueDrawable> result(std::distance(range.first, range.second));
|
||||
std::transform(
|
||||
std::make_move_iterator(range.first), std::make_move_iterator(range.second), result.begin(), [](auto&& pair) {
|
||||
return std::move(pair.second);
|
||||
});
|
||||
impl->tileDrawables.erase(range.first, range.second);
|
||||
impl->drawablesByTile.erase(range.first, range.second);
|
||||
std::for_each(result.begin(), result.end(), [&](const auto& item) {
|
||||
const auto hit = impl->sortedDrawables.find(item.get());
|
||||
assert(hit != impl->sortedDrawables.end());
|
||||
if (hit != impl->sortedDrawables.end()) {
|
||||
impl->sortedDrawables.erase(hit);
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
void TileLayerGroup::addDrawable(mbgl::RenderPass pass, const OverscaledTileID& id, gfx::UniqueDrawable&& drawable) {
|
||||
impl->tileDrawables.insert(std::make_pair(TileLayerGroupTileKey{pass, id}, std::move(drawable)));
|
||||
}
|
||||
|
||||
void TileLayerGroup::observeDrawables(std::function<void(gfx::Drawable&)> f) {
|
||||
for (auto& pair : impl->tileDrawables) {
|
||||
if (pair.second) {
|
||||
f(*pair.second);
|
||||
}
|
||||
assert(impl->drawablesByTile.size() == impl->sortedDrawables.size());
|
||||
if (drawable) {
|
||||
[[maybe_unused]] const auto result = impl->sortedDrawables.insert(drawable.get());
|
||||
assert(result.second);
|
||||
impl->drawablesByTile.insert(std::make_pair(TileLayerGroupTileKey{pass, id}, std::move(drawable)));
|
||||
}
|
||||
}
|
||||
|
||||
void TileLayerGroup::observeDrawables(std::function<void(const gfx::Drawable&)> f) const {
|
||||
for (const auto& pair : impl->tileDrawables) {
|
||||
if (pair.second) {
|
||||
f(*pair.second);
|
||||
}
|
||||
void TileLayerGroup::observeDrawables(const std::function<void(gfx::Drawable&)>&& f) {
|
||||
assert(impl->drawablesByTile.size() == impl->sortedDrawables.size());
|
||||
for (auto* drawable : impl->sortedDrawables) {
|
||||
f(*drawable);
|
||||
}
|
||||
}
|
||||
|
||||
void TileLayerGroup::observeDrawables(std::function<void(gfx::UniqueDrawable&)> f) {
|
||||
for (auto i = impl->tileDrawables.begin(); i != impl->tileDrawables.end();) {
|
||||
void TileLayerGroup::observeDrawables(const std::function<void(const gfx::Drawable&)>&& f) const {
|
||||
assert(impl->drawablesByTile.size() == impl->sortedDrawables.size());
|
||||
for (const auto* drawable : impl->sortedDrawables) {
|
||||
f(*drawable);
|
||||
}
|
||||
}
|
||||
|
||||
std::size_t TileLayerGroup::observeDrawablesRemove(const std::function<bool(gfx::Drawable&)>&& f) {
|
||||
const auto oldSize = impl->drawablesByTile.size();
|
||||
for (auto i = impl->drawablesByTile.begin(); i != impl->drawablesByTile.end();) {
|
||||
auto& drawable = i->second;
|
||||
if (drawable) {
|
||||
f(drawable);
|
||||
}
|
||||
if (drawable) {
|
||||
if (f(*drawable)) {
|
||||
// Not removed, keep going
|
||||
++i;
|
||||
} else {
|
||||
// Removed, take it out of the map
|
||||
i = impl->tileDrawables.erase(i);
|
||||
// Removed, take it out of the collections
|
||||
impl->sortedDrawables.erase(drawable.get());
|
||||
i = impl->drawablesByTile.erase(i);
|
||||
}
|
||||
assert(impl->drawablesByTile.size() == impl->sortedDrawables.size());
|
||||
}
|
||||
return (oldSize - impl->drawablesByTile.size());
|
||||
}
|
||||
|
||||
void TileLayerGroup::observeDrawables(mbgl::RenderPass pass,
|
||||
const OverscaledTileID& tileID,
|
||||
std::function<void(gfx::Drawable&)>&& f) {
|
||||
const auto range = impl->tileDrawables.equal_range({pass, tileID});
|
||||
const std::function<void(gfx::Drawable&)>&& f) {
|
||||
assert(impl->drawablesByTile.size() == impl->sortedDrawables.size());
|
||||
const auto range = impl->drawablesByTile.equal_range({pass, tileID});
|
||||
std::for_each(range.first, range.second, [&f](const auto& pair) { f(*pair.second); });
|
||||
}
|
||||
|
||||
void TileLayerGroup::observeDrawables(mbgl::RenderPass pass,
|
||||
const OverscaledTileID& tileID,
|
||||
std::function<void(const gfx::Drawable&)>&& f) const {
|
||||
const auto range = impl->tileDrawables.equal_range({pass, tileID});
|
||||
const std::function<void(const gfx::Drawable&)>&& f) const {
|
||||
assert(impl->drawablesByTile.size() == impl->sortedDrawables.size());
|
||||
const auto range = impl->drawablesByTile.equal_range({pass, tileID});
|
||||
std::for_each(range.first, range.second, [&f](const auto& pair) { f(*pair.second); });
|
||||
}
|
||||
|
||||
std::size_t TileLayerGroup::clearDrawables() {
|
||||
const auto count = impl->tileDrawables.size();
|
||||
impl->tileDrawables.clear();
|
||||
const auto count = impl->drawablesByTile.size();
|
||||
assert(count == impl->sortedDrawables.size());
|
||||
impl->sortedDrawables.clear();
|
||||
impl->drawablesByTile.clear();
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user