Drawable Renderer (#1570), order drawables
This commit is contained in:
committed by
Bart Louwers
parent
caee9cc12f
commit
4af4491626
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 {}
|
||||
|
||||
@@ -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...
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user