Drawable Renderer (#1570), work on fill drawables

This commit is contained in:
Tim Sylvester
2023-05-05 15:08:53 -07:00
committed by Bart Louwers
parent 66e62e8c66
commit 375083b6cf
5 changed files with 116 additions and 5 deletions

View File

@@ -4,6 +4,7 @@
#include <mbgl/gfx/types.hpp>
#include <mbgl/gfx/vertex_attribute.hpp>
#include <array>
#include <memory>
#include <vector>
@@ -95,6 +96,13 @@ public:
/// Add a rectangle consisting of two triangles
void addQuad(int16_t x0, int16_t y0, int16_t x1, int16_t y1);
/// Add already-set-up triangles directly
void addTriangles(const std::vector<std::array<int16_t,2>>& vertices,
std::size_t vertexOffset, std::size_t vertexLength,
const std::vector<uint16_t>& indexes,
std::size_t indexOffset, std::size_t indexLength);
/// Add a tweaker to be attached to each emitted drawable
void addTweaker(DrawableTweakerPtr tweaker) { tweakers.emplace_back(std::move(tweaker)); }

View File

@@ -89,5 +89,25 @@ void DrawableBuilder::addQuad(int16_t x0, int16_t y0, int16_t x1, int16_t y1) {
appendTriangle(x1, y1);
}
void DrawableBuilder::addTriangles(const std::vector<std::array<int16_t,2>>& vertices,
std::size_t vertexOffset, std::size_t vertexLength,
const std::vector<uint16_t>& indexes,
std::size_t indexOffset, std::size_t indexLength) {
// TODO: bulk add in `gfx::VertexVector`... or use vector directly?
//impl->vertices.insert(impl->vertices.end(),
// std::next(vertices.begin(), vertexOffset),
// std::next(vertices.begin(), vertexOffset + vertexLength));
//impl->indexes.insert(impl->indexes.end(),
// std::next(indexes.begin(), indexOffset),
// std::next(indexes.begin(), indexOffset + indexLength));
std::for_each(std::next(vertices.begin(), vertexOffset),
std::next(vertices.begin(), vertexOffset + vertexLength),
[&](const std::array<int16_t,2>& x){ impl->vertices.emplace_back(Impl::VT({{x}})); });
for (auto i = std::next(indexes.begin(), indexOffset); i != std::next(indexes.begin(), indexOffset + indexLength); ) {
impl->indexes.emplace_back(*i++, *i++, *i++);
}
}
} // namespace gfx
} // namespace mbgl

View File

@@ -463,7 +463,15 @@ bool Context::setupDraw(const PaintParameters& parameters, const gfx::Drawable&
}
setDepthMode(parameters.depthModeForSublayer(0, drawable.getDepthType()));
setStencilMode(gfx::StencilMode::disabled());
if (auto tileID = drawable.getTileID()) {
// Doesn't work until the clipping masks are generated
//parameters.stencilModeForClipping(tileID->toUnwrapped());
setStencilMode(gfx::StencilMode::disabled());
} else {
setStencilMode(gfx::StencilMode::disabled());
}
setColorMode(gfx::ColorMode::alphaBlended());
setCullFaceMode(gfx::CullFaceMode::disabled());

View File

@@ -1,5 +1,6 @@
#include <mbgl/geometry/feature_index.hpp>
#include <mbgl/gfx/context.hpp>
#include <mbgl/gfx/drawable_builder.hpp>
#include <mbgl/gfx/cull_face_mode.hpp>
#include <mbgl/gfx/renderable.hpp>
#include <mbgl/gfx/renderer_backend.hpp>
@@ -275,11 +276,11 @@ void RenderFillLayer::layerRemoved(UniqueChangeRequestVec& changes) {
localDrawables.cbegin(), localDrawables.cend(), changes, [](auto& ii) { return ii->second->getId(); });
}
void RenderFillLayer::update(const int32_t /*layerIndex*/,
void RenderFillLayer::update(const int32_t layerIndex,
gfx::ShaderRegistry& shaders,
gfx::Context& context,
const TransformState& /*state*/,
UniqueChangeRequestVec& /*changes*/) {
UniqueChangeRequestVec& changes) {
std::unique_lock<std::mutex> guard(mutex);
if (!shader) {
@@ -387,17 +388,72 @@ void RenderFillLayer::update(const int32_t /*layerIndex*/,
// }
// }
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(); });
// For each existing tile drawable...
for (auto iter = tileDrawables.begin(); iter != tileDrawables.end();) {
const auto& drawable = iter->second;
// Has this tile dropped out of the cover set?
if (newTileIDs.find(iter->first) == newTileIDs.end()) {
// remove it
if (drawable) {
changes.emplace_back(std::make_unique<RemoveDrawableRequest>(drawable->getId()));
}
// Log::Warning(Event::General, "Removing drawable for " + util::toString(iter->first) + " total " +
// std::to_string(stats.tileDrawablesRemoved+1));
iter = tileDrawables.erase(iter);
++stats.tileDrawablesRemoved;
continue;
}
++iter;
// update...
}
std::unique_ptr<gfx::DrawableBuilder> builder;
if (unevaluated.get<FillPattern>().isUndefined()) {
// parameters.renderTileClippingMasks(renderTiles);
for (const RenderTile& tile : *renderTiles) {
const auto& tileID = tile.getOverscaledTileID();
const auto result = tileDrawables.insert(std::make_pair(tileID, gfx::DrawablePtr()));
if (!result.second) {
// Already present
continue;
}
const auto renderPass = RenderPass::Translucent;
const LayerRenderData* renderData = getRenderDataForPass(tile, renderPass);
if (!renderData) {
continue;
}
// auto& bucket = static_cast<FillBucket&>(*renderData->bucket);
// const auto& evaluated = getEvaluated<FillLayerProperties>(renderData->layerProperties);
auto& bucket = static_cast<FillBucket&>(*renderData->bucket);
//const auto& evaluated = getEvaluated<FillLayerProperties>(renderData->layerProperties);
if (!builder) {
builder = context.createDrawableBuilder("fill");
builder->setShader(shader);
builder->addTweaker(context.createDrawableTweaker());
//builder->setColor(color);
builder->setColorMode(gfx::DrawableBuilder::ColorMode::PerDrawable);
builder->setDepthType(gfx::DepthMaskType::ReadWrite);
builder->setLayerIndex(layerIndex);
}
const std::vector<gfx::VertexVector<gfx::detail::VertexType<gfx::AttributeType<int16_t, 2>>>::Vertex>& verts = bucket.vertices.vector();
std::vector<std::array<int16_t, 2>> rawVerts(verts.size());
std::transform(verts.begin(), verts.end(), rawVerts.begin(), [](const auto& x){ return x.a1; });
for (const auto& seg : bucket.triangleSegments) {
builder->addTriangles(rawVerts, seg.vertexOffset, seg.vertexLength,
bucket.triangles.vector(), seg.indexOffset, seg.indexLength);
}
// evaluated.get<FillTranslate>(),
// evaluated.get<FillTranslateAnchor>(),
// parameters.stencilModeForClipping(tile.id),
@@ -427,6 +483,20 @@ void RenderFillLayer::update(const int32_t /*layerIndex*/,
// bucket.lineSegments,
// FillOutlineProgram::TextureBindings{});
// }
builder->flush();
auto drawables = builder->clearDrawables();
if (!drawables.empty()) {
auto& drawable = drawables[0];
drawable->setTileID(tileID);
result.first->second = drawable;
changes.emplace_back(std::make_unique<AddDrawableRequest>(std::move(drawable)));
++stats.tileDrawablesAdded;
// Log::Warning(Event::General, "Adding drawable for " + util::toString(tileID) + " total " +
// std::to_string(stats.tileDrawablesAdded+1));
}
}
} else {
// if (parameters.pass != RenderPass::Translucent) {

View File

@@ -210,6 +210,11 @@ void Renderer::Impl::render(const RenderTree& renderTree) {
parameters.depthRangeSize = 1 - (1 + 2) * parameters.numSublayers * parameters.depthEpsilon;
const auto debugGroup(parameters.renderPass->createDebugGroup("drawables"));
// TODO: Render tile masks
//for (auto& layer : renderLayers) {
// parameters.renderTileClippingMasks(renderTiles);
//}
for (const auto& drawPtr : drawables) {
auto& drawable = *drawPtr;