Drawable Renderer (#1570), rework attributes for fill drawables

This commit is contained in:
Tim Sylvester
2023-05-15 15:02:41 -07:00
committed by Bart Louwers
parent cec22b8572
commit fffbfcfbb5
12 changed files with 198 additions and 45 deletions

View File

@@ -7,6 +7,8 @@ namespace gfx {
DrawableBuilder::DrawableBuilder(std::string name_)
: name(std::move(name_)),
vertexAttrName("a_pos"),
colorAttrName("a_color"),
renderPass(RenderPass::Opaque),
impl(std::make_unique<Impl>()) {}
@@ -35,8 +37,21 @@ void DrawableBuilder::flush() {
draw->setDepthType(depthType);
draw->setShader(shader);
draw->setMatrix(matrix);
draw->setVertexAttributes(getVertexAttributes());
draw->addTweakers(tweakers.begin(), tweakers.end());
if (auto drawAttrs = getVertexAttributes().clone()) {
vertexAttrs.observeAttributes([&](const std::string& iName, const VertexAttribute& iAttr) {
if (auto& drawAttr = drawAttrs->getOrAdd(iName)) {
for (std::size_t i = 0; i < impl->vertices.elements(); ++i) {
drawAttr->set<const VertexAttribute::ElementType&>(i, iAttr.get(0));
}
}
});
draw->setVertexAttributes(std::move(*drawAttrs));
}
init();
}
if (currentDrawable) {
@@ -91,6 +106,14 @@ void DrawableBuilder::addQuad(int16_t x0, int16_t y0, int16_t x1, int16_t y1) {
appendTriangle(x1, y1);
}
void DrawableBuilder::setVertexAttributes(const VertexAttributeArray& attrs) {
vertexAttrs = attrs;
}
void DrawableBuilder::setVertexAttributes(VertexAttributeArray&& attrs) {
vertexAttrs = attrs;
}
void DrawableBuilder::addTriangles(const std::vector<std::array<int16_t, 2>>& vertices,
std::size_t vertexOffset,
std::size_t vertexLength,

View File

@@ -12,6 +12,10 @@ std::unique_ptr<VertexAttribute> VertexAttributeArray::nullref = nullptr;
VertexAttributeArray::VertexAttributeArray(int initCapacity)
: attrs(initCapacity) {}
VertexAttributeArray::VertexAttributeArray(const VertexAttributeArray& other) {
operator=(other);
}
VertexAttributeArray::VertexAttributeArray(VertexAttributeArray&& other)
: attrs(std::move(other.attrs)) {}
@@ -23,7 +27,9 @@ VertexAttributeArray& VertexAttributeArray::operator=(VertexAttributeArray&& oth
VertexAttributeArray& VertexAttributeArray::operator=(const VertexAttributeArray& other) {
attrs.clear();
for (const auto& kv : other.attrs) {
add(kv.first, copy(*kv.second));
if (kv.second) {
add(kv.first, copy(*kv.second));
}
}
return *this;
}
@@ -69,6 +75,10 @@ std::size_t VertexAttributeArray::getMaxCount() const {
});
}
void VertexAttributeArray::clear() {
attrs.clear();
}
void VertexAttributeArray::resolve(const VertexAttributeArray& overrides, ResolveDelegate delegate) const {
for (auto& kv : attrs) {
delegate(kv.first, *kv.second, overrides.get(kv.first));

View File

@@ -15,26 +15,28 @@ void DrawableGLBuilder::init() {
auto& drawableGL = static_cast<DrawableGL&>(*currentDrawable);
auto& attrs = drawableGL.mutableVertexAttributes();
if (const auto& posAttr = attrs.getOrAdd("a_pos")) {
if (const auto& posAttr = attrs.getOrAdd(vertexAttrName)) {
std::size_t index = 0;
for (const auto& vert : impl->vertices.vector()) {
posAttr->set(index++, gfx::VertexAttribute::int2{vert.a1[0], vert.a1[1]});
}
}
if (const auto& colorAttr = attrs.getOrAdd("a_color")) {
// We should have either a single color or one per vertex. Otherwise,
// the color mode was probably changed after vertexes were added.
if (impl->colors.size() > 1 && impl->colors.size() != impl->vertices.elements()) {
impl->colors.clear();
}
if (impl->colors.empty()) {
colorAttr->set(0, DrawableGL::colorAttrValue(getColor()));
} else {
std::size_t index = 0;
colorAttr->reserve(impl->colors.size());
for (const auto& color : impl->colors) {
colorAttr->set(index++, DrawableGL::colorAttrValue(color));
if (colorMode != ColorMode::None && !colorAttrName.empty()) {
if (const auto& colorAttr = attrs.getOrAdd(colorAttrName)) {
// We should have either a single color or one per vertex. Otherwise,
// the color mode was probably changed after vertexes were added.
if (impl->colors.size() > 1 && impl->colors.size() != impl->vertices.elements()) {
impl->colors.clear();
}
if (impl->colors.empty()) {
colorAttr->set(0, DrawableGL::colorAttrValue(getColor()));
} else {
std::size_t index = 0;
colorAttr->reserve(impl->colors.size());
for (const auto& color : impl->colors) {
colorAttr->set(index++, DrawableGL::colorAttrValue(color));
}
}
}
}

View File

@@ -70,6 +70,13 @@ void TileLayerGroupGL::render(RenderOrchestrator&, PaintParameters& parameters)
return;
}
std::string label;
if (const auto& tileID = drawable.getTileID()) {
label = drawable.getName() + "/" + util::toString(*tileID);
}
const auto labelPtr = (label.empty() ? drawable.getName() : label).c_str();
const auto debugGroup = parameters.encoder->createDebugGroup(labelPtr);
mat4 matrix = drawable.getMatrix();
if (drawable.getTileID()) {
const UnwrappedTileID tileID = drawable.getTileID()->toUnwrapped();

View File

@@ -17,6 +17,7 @@
#include <mbgl/style/layers/fill_layer_impl.hpp>
#include <mbgl/tile/geometry_tile.hpp>
#include <mbgl/tile/tile.hpp>
#include <mbgl/util/convert.hpp>
#include <mbgl/util/intersection_tests.hpp>
#include <mbgl/util/math.hpp>
@@ -305,6 +306,7 @@ void RenderFillLayer::update(const int32_t layerIndex,
std::unique_ptr<gfx::DrawableBuilder> builder;
std::vector<gfx::DrawablePtr> newTiles;
gfx::VertexAttributeArray vertexAttrs;
for (const auto renderPass : {RenderPass::Opaque, RenderPass::Translucent}) {
tileLayerGroup->observeDrawables([&](gfx::UniqueDrawable& drawable) {
@@ -340,8 +342,8 @@ void RenderFillLayer::update(const int32_t layerIndex,
auto& bucket = static_cast<FillBucket&>(*renderData->bucket);
const auto& evaluated = getEvaluated<FillLayerProperties>(renderData->layerProperties);
const auto evalColor = evaluated.get<FillColor>().constantOr(Color());
const auto fillOpacity = evaluated.get<FillOpacity>().constantOr(0);
const auto fillColor = evalColor * (fillOpacity > 0.0f ? fillOpacity : 1.0f);
const auto fillOpacity = evaluated.get<FillOpacity>().constantOr(1);
//const auto fillColor = evalColor * (fillOpacity > 0.0f ? fillOpacity : 1.0f);
const auto fillRenderPass = (evalColor.a >= 1.0f && fillOpacity >= 1.0f
/* && parameters.currentLayer >= parameters.opaquePassCutoff*/)
@@ -353,8 +355,24 @@ void RenderFillLayer::update(const int32_t layerIndex,
continue;
}
vertexAttrs.clear();
if (auto& attr = vertexAttrs.getOrAdd("a_color")) {
attr->set(0, util::cast<float>(evalColor.toArray()));
}
if (auto& attr = vertexAttrs.getOrAdd("a_opacity")) {
attr->set<gfx::VertexAttribute::float2>(0, { fillOpacity, fillOpacity });
}
if (evaluatedPropertiesChange) {
//FillLayerUBO fillLayerUBO;
//fillLayerUBO.color = evaluated.get<FillColor>();
//fillLayerUBO.opacity = evaluated.get<FillOpacity>();
//uniformBuffer = context.createUniformBuffer(&fillLayerUBO, sizeof(fillLayerUBO));
evaluatedPropertiesChange = false;
}
if (tileDrawable) {
// needed and already present, update?
//tileDrawable->mutableUniformBuffers().addOrReplace("FillLayerUBO", uniformBuffer);
continue;
}
@@ -362,7 +380,7 @@ void RenderFillLayer::update(const int32_t layerIndex,
builder = context.createDrawableBuilder("fill");
builder->setShader(shader);
builder->addTweaker(context.createDrawableTweaker());
builder->setColorMode(gfx::DrawableBuilder::ColorMode::PerVertex);
builder->setColorMode(gfx::DrawableBuilder::ColorMode::None);
builder->setDepthType(gfx::DepthMaskType::ReadWrite);
builder->setLayerIndex(layerIndex);
}
@@ -370,8 +388,8 @@ void RenderFillLayer::update(const int32_t layerIndex,
// tile.translatedMatrix(evaluated.get<FillTranslate>(), evaluated.get<FillTranslateAnchor>(),
// parameters.state)
builder->setColor(fillColor);
builder->setRenderPass(renderPass);
builder->setVertexAttributes(vertexAttrs);
const std::vector<gfx::VertexVector<gfx::detail::VertexType<gfx::AttributeType<int16_t, 2>>>::Vertex>&
verts = bucket.vertices.vector();
@@ -423,9 +441,10 @@ void RenderFillLayer::update(const int32_t layerIndex,
if (!newDrawables.empty()) {
auto& drawable = newDrawables[0];
drawable->setTileID(tileID);
//drawable->mutableUniformBuffers().addOrReplace("FillLayerUBO", uniformBuffer);
// Track it.
// tileLayerGroup->addDrawable(renderPass, tileID, std::move(drawable));
tileLayerGroup->addDrawable(renderPass, tileID, std::move(drawable));
++stats.tileDrawablesAdded;
// Log::Warning(Event::General, "Adding drawable for " + util::toString(tileID) + " total " +
// std::to_string(stats.tileDrawablesAdded+1));