Drawable Renderer (#1570), order drawables

This commit is contained in:
Tim Sylvester
2023-05-02 13:54:50 -07:00
committed by Bart Louwers
parent caee9cc12f
commit 4af4491626
8 changed files with 92 additions and 33 deletions

View File

@@ -28,59 +28,63 @@ using DrawableTweakerPtr = std::shared_ptr<DrawableTweaker>;
class Drawable {
protected:
Drawable(std::string name);
public:
virtual ~Drawable() = default;
const util::SimpleIdentity& getId() const { return uniqueID; }
/// Draw the drawable
virtual void draw(const PaintParameters&) const = 0;
/// Drawable name is used for debugging and troubleshooting
const std::string& getName() const { return name; }
void setName(std::string value) { name = std::move(value); }
/// Which shader to use when rendering this drawable
const gfx::ShaderProgramBasePtr& getShader() const { return shader; }
void setShader(gfx::ShaderProgramBasePtr value) { shader = std::move(value); }
/// DrawPriority determines the drawing order
/// not used for anything yet
DrawPriority getDrawPriority() const { return drawPriority; }
void setDrawPriority(DrawPriority value) { drawPriority = value; }
/// The layer index determines the drawing order
int32_t getLayerIndex() const { return layerIndex; }
void setLayerIndex(int32_t value) { layerIndex = value; }
std::optional<OverscaledTileID> getTileID() const { return tileID; }
void setTileID(OverscaledTileID value) { tileID = value; }
mat4 getMatrix() const { return matrix; }
void setMatrix(mat4 value) { matrix = value; }
DepthMaskType getDepthType() const { return depthType; }
void setDepthType(DepthMaskType value) { depthType = value; }
/// Get the number of vertexes
std::size_t getVertexCount() const { return getVertexAttributes().getMaxCount(); }
/// Get the vertex attributes that override default values in the shader program
virtual const gfx::VertexAttributeArray& getVertexAttributes() const = 0;
virtual void setVertexAttributes(const gfx::VertexAttributeArray&) = 0;
virtual void setVertexAttributes(gfx::VertexAttributeArray&&) = 0;
virtual std::vector<std::uint16_t>& getIndexData() const = 0;
/// Attach a tweaker to be run on this drawable for each frame
void addTweaker(DrawableTweakerPtr tweaker) { tweakers.emplace_back(std::move(tweaker)); }
template <typename TIter>
void addTweakers(TIter beg, TIter end) {
tweakers.insert(tweakers.end(), beg, end);
}
/// Get the tweakers attached to this drawable
const std::vector<DrawableTweakerPtr>& getTweakers() const { return tweakers; }
// Reset a single color attribute for all vertexes
virtual void resetColor(const Color&) = 0;
protected:
std::string name;
util::SimpleIdentity uniqueID;
@@ -88,12 +92,35 @@ protected:
mat4 matrix; //= matrix::identity4();
std::optional<OverscaledTileID> tileID;
DrawPriority drawPriority = 0;
int32_t layerIndex = -1;
DepthMaskType depthType; // = DepthMaskType::ReadOnly;
std::vector<DrawableTweakerPtr> tweakers;
};
using DrawablePtr = std::shared_ptr<Drawable>;
/// Comparator for sorting drawable pointers primarily by layer index
struct DrawablePtrLessByLayer {
DrawablePtrLessByLayer(bool descending) : desc(descending) { }
bool operator()(const DrawablePtr& left, const DrawablePtr& right) const {
const auto& a = desc ? right : left;
const auto& b = desc ? left : right;
if (!a || !b) {
// nulls are less than non-nulls
return (!a && b);
}
if (a->getLayerIndex() != b->getLayerIndex()) {
return a->getLayerIndex() < b->getLayerIndex();
}
if (a->getDrawPriority() != b->getDrawPriority()) {
return a->getDrawPriority() < b->getDrawPriority();
}
return a->getId() < b->getId();
}
private:
bool desc;
};
} // namespace gfx
} // namespace mbgl

View File

@@ -48,11 +48,14 @@ public:
/// Get the ID of the drawable we're currently working on, if any
util::SimpleIdentity getDrawableId();
/// Get the draw priority assigned to generated drawables
/// The draw priority assigned to generated drawables
DrawPriority getDrawPriority() const;
/// Set the draw priority assigned to generated drawables
void setDrawPriority(DrawPriority);
/// The layer index assigned to generated drawables
int32_t getLayerIndex() const { return layerIndex; }
void setLayerIndex(int32_t value) { layerIndex = value; }
/// Set the draw priority on all drawables including those already generated
void resetDrawPriority(DrawPriority);
@@ -106,6 +109,7 @@ protected:
std::string name;
std::string drawableName;
DrawPriority drawPriority = 0;
int32_t layerIndex = -1;
DepthMaskType depthType = DepthMaskType::ReadOnly;
gfx::ShaderProgramBasePtr shader;
mat4 matrix;

View File

@@ -28,6 +28,7 @@ void DrawableBuilder::flush() {
if (!impl->vertices.empty()) {
auto draw = getCurrentDrawable(/*createIfNone=*/true);
currentDrawable->setDrawPriority(drawPriority);
currentDrawable->setLayerIndex(layerIndex);
currentDrawable->setDepthType(depthType);
currentDrawable->setShader(shader);
currentDrawable->setMatrix(matrix);

View File

@@ -797,8 +797,13 @@ void RenderOrchestrator::updateLayers(gfx::ShaderRegistry& shaders,
kv.second->layerAdded(shaders, context, state, evalParameters, changes);
}
// Layer index, similar but not identical to `layerRenderItems` index in render_impl
//int32_t i = static_cast<int32_t>(layerRenderItems.size()) - 1;
//for (auto it = layerRenderItems.begin(); it != layerRenderItems.end() && i >= 0; ++it, --i) {
auto index = static_cast<int32_t>(layerImpls->size()) - 1;
for (auto& impl : *layerImpls) {
impl->update(context, state, evalParameters, changes);
impl->update(index--, context, state, evalParameters, changes);
}
addChanges(changes);

View File

@@ -89,6 +89,23 @@ void Renderer::Impl::render(const RenderTree& renderTree) {
// Run changes
orchestrator.processChanges();
// Collect drawables
std::vector<gfx::DrawablePtr> drawables(orchestrator.getDrawables().size());
std::transform(orchestrator.getDrawables().begin(),
orchestrator.getDrawables().end(),
drawables.begin(),
std::bind(&RenderOrchestrator::DrawableMap::value_type::second));
// Run tweakers to update any dynamic elements
for (auto& drawable : drawables) {
for (auto& tweaker : drawable->getTweakers()) {
tweaker->execute(*drawable, parameters);
}
}
// Sort the drawables
std::sort(drawables.begin(), drawables.end(), gfx::DrawablePtrLessByLayer(/*descending=*/true));
// - UPLOAD PASS -------------------------------------------------------------------------------
// Uploads all required buffers and images before we do any actual rendering.
{
@@ -105,13 +122,8 @@ void Renderer::Impl::render(const RenderTree& renderTree) {
renderTree.getLineAtlas().upload(*uploadPass);
renderTree.getPatternAtlas().upload(*uploadPass);
for (const auto& pair : orchestrator.getDrawables()) {
auto& drawable = *pair.second;
// Run tweakers to update any dynamic elements
for (auto& tweaker : drawable.getTweakers()) {
tweaker->execute(drawable, parameters);
}
for (const auto& drawPtr : drawables) {
auto& drawable = *drawPtr;
auto& drawableGL = static_cast<gl::DrawableGL&>(drawable);
auto& shader = drawable.getShader();
@@ -198,8 +210,8 @@ void Renderer::Impl::render(const RenderTree& renderTree) {
parameters.depthRangeSize = 1 - (1 + 2) * parameters.numSublayers * parameters.depthEpsilon;
const auto debugGroup(parameters.renderPass->createDebugGroup("drawables"));
for (const auto& pair : orchestrator.getDrawables()) {
const auto& drawable = *pair.second;
for (const auto& drawPtr : drawables) {
auto& drawable = *drawPtr;
if (!context.setupDraw(parameters, drawable)) {
continue;

View File

@@ -63,7 +63,8 @@ public:
virtual void populateFontStack(std::set<FontStack>& fontStack) const;
/// Generate any changes needed by the layer
virtual void update(gfx::Context&,
virtual void update(int32_t /*layerIndex*/,
gfx::Context&,
const TransformState&,
const PropertyEvaluationParameters&,
UniqueChangeRequestVec&) const {}

View File

@@ -56,7 +56,8 @@ void BackgroundLayer::Impl::layerRemoved(UniqueChangeRequestVec& changes) const
localDrawables.cbegin(), localDrawables.cend(), changes, [](auto& ii) { return ii->second->getId(); });
}
void BackgroundLayer::Impl::update(gfx::Context& context,
void BackgroundLayer::Impl::update(const int32_t layerIndex,
gfx::Context& context,
const TransformState& state,
const PropertyEvaluationParameters& evalParameters,
UniqueChangeRequestVec& changes) const {
@@ -96,7 +97,9 @@ void BackgroundLayer::Impl::update(gfx::Context& context,
}
const bool colorChange = (color != lastColor);
const bool layerChange = (layerIndex != lastLayerIndex);
lastColor = color;
lastLayerIndex = layerIndex;
const auto zoom = state.getIntegerZoom();
const auto tileCover = util::tileCover(state, zoom);
@@ -129,6 +132,9 @@ void BackgroundLayer::Impl::update(gfx::Context& context,
if (colorChange) {
drawable->resetColor(*color);
}
if (layerChange) {
drawable->setLayerIndex(layerIndex);
}
}
std::unique_ptr<gfx::DrawableBuilder> builder;
@@ -151,6 +157,7 @@ void BackgroundLayer::Impl::update(gfx::Context& context,
builder->setColor(*color);
builder->setColorMode(gfx::DrawableBuilder::ColorMode::PerDrawable);
builder->setDepthType(gfx::DepthMaskType::ReadWrite);
builder->setLayerIndex(layerIndex);
}
// Tile coordinates are fixed...

View File

@@ -41,7 +41,8 @@ public:
void layerRemoved(UniqueChangeRequestVec&) const override;
/// Generate any changes needed by the layer
void update(gfx::Context&,
void update(int32_t layerIndex,
gfx::Context&,
const TransformState&,
const PropertyEvaluationParameters&,
UniqueChangeRequestVec&) const override;
@@ -62,6 +63,7 @@ private:
mutable gfx::ShaderProgramBasePtr shader;
mutable std::unordered_map<OverscaledTileID, gfx::DrawablePtr> tileDrawables;
mutable std::optional<Color> lastColor;
mutable int32_t lastLayerIndex = -1;
mutable struct Stats {
size_t tileDrawablesAdded = 0;