Drawable Renderer (#1570), Apply render pass to drawables

This commit is contained in:
Tim Sylvester
2023-05-08 08:52:05 -07:00
committed by Bart Louwers
parent 610fb7d63c
commit b052cb904e
7 changed files with 64 additions and 18 deletions

View File

@@ -13,6 +13,7 @@ namespace mbgl {
class Color;
class PaintParameters;
enum class RenderPass : uint8_t;
namespace gfx {
@@ -45,6 +46,17 @@ public:
const gfx::ShaderProgramBasePtr& getShader() const { return shader; }
void setShader(gfx::ShaderProgramBasePtr value) { shader = std::move(value); }
/// The pass on which we'll be rendered
mbgl::RenderPass getRenderPass() const { return renderPass; }
void setRenderPass(mbgl::RenderPass value) { renderPass = value; }
/// Test whether to draw this drawable in a given render pass.
/// If multiple render pass bits are set, all must be present.
bool hasRenderPass(mbgl::RenderPass value) const {
using T = std::underlying_type<mbgl::RenderPass>::type;
return (static_cast<T>(renderPass) & static_cast<T>(value)) == static_cast<T>(value);
}
/// not used for anything yet
DrawPriority getDrawPriority() const { return drawPriority; }
void setDrawPriority(DrawPriority value) { drawPriority = value; }
@@ -89,6 +101,7 @@ protected:
std::string name;
util::SimpleIdentity uniqueID;
gfx::ShaderProgramBasePtr shader;
mbgl::RenderPass renderPass;
mat4 matrix; //= matrix::identity4();
std::optional<OverscaledTileID> tileID;
DrawPriority drawPriority = 0;

View File

@@ -49,6 +49,10 @@ public:
/// Get the ID of the drawable we're currently working on, if any
util::SimpleIdentity getDrawableId();
/// The pass on which we'll be rendered
mbgl::RenderPass getRenderPass() const { return renderPass; }
void setRenderPass(mbgl::RenderPass value) { renderPass = value; }
/// The draw priority assigned to generated drawables
DrawPriority getDrawPriority() const;
void setDrawPriority(DrawPriority);
@@ -118,6 +122,7 @@ protected:
protected:
std::string name;
std::string drawableName;
mbgl::RenderPass renderPass;
DrawPriority drawPriority = 0;
int32_t layerIndex = -1;
DepthMaskType depthType = DepthMaskType::ReadOnly;

View File

@@ -1,5 +1,6 @@
#include <mbgl/gfx/drawable.hpp>
#include <mbgl/gfx/types.hpp>
#include <mbgl/renderer/render_pass.hpp>
#include <mbgl/util/mat4.hpp>
namespace mbgl {
@@ -7,6 +8,7 @@ namespace gfx {
Drawable::Drawable(std::string name_)
: name(name_),
renderPass(RenderPass::Opaque),
matrix(matrix::identity4()),
depthType(DepthMaskType::ReadOnly) {}

View File

@@ -1,11 +1,13 @@
#include <mbgl/gfx/drawable_builder.hpp>
#include <mbgl/gfx/drawable_builder_impl.hpp>
#include <mbgl/renderer/render_pass.hpp>
namespace mbgl {
namespace gfx {
DrawableBuilder::DrawableBuilder(std::string name_)
: name(std::move(name_)),
renderPass(RenderPass::Opaque),
impl(std::make_unique<Impl>()) {}
DrawableBuilder::~DrawableBuilder() = default;
@@ -27,6 +29,7 @@ DrawablePtr DrawableBuilder::getCurrentDrawable(bool createIfNone) {
void DrawableBuilder::flush() {
if (!impl->vertices.empty()) {
auto draw = getCurrentDrawable(/*createIfNone=*/true);
currentDrawable->setRenderPass(renderPass);
currentDrawable->setDrawPriority(drawPriority);
currentDrawable->setLayerIndex(layerIndex);
currentDrawable->setDepthType(depthType);

View File

@@ -8,11 +8,12 @@
#include <mbgl/style/layer_properties.hpp>
#include <mbgl/renderer/bucket.hpp>
#include <mbgl/renderer/change_request.hpp>
#include <mbgl/renderer/upload_parameters.hpp>
#include <mbgl/renderer/image_manager.hpp>
#include <mbgl/renderer/paint_parameters.hpp>
#include <mbgl/renderer/pattern_atlas.hpp>
#include <mbgl/renderer/image_manager.hpp>
#include <mbgl/renderer/render_pass.hpp>
#include <mbgl/renderer/render_static_data.hpp>
#include <mbgl/renderer/upload_parameters.hpp>
#include <mbgl/programs/programs.hpp>
#include <mbgl/shaders/shader_program_base.hpp>
#include <mbgl/util/tile_cover.hpp>
@@ -223,13 +224,13 @@ void RenderBackgroundLayer::update(const int32_t layerIndex,
const auto& evaluated = getEvaluated<BackgroundLayerProperties>(evaluatedProperties);
// TODO: If background is solid, we can skip drawables and rely on the clear color
// const auto passes = eval.get<style::BackgroundOpacity>() == 0.0f
// ? RenderPass::None
// : (!uneval.get<style::BackgroundPattern>().isUndefined()
// || eval.get<style::BackgroundOpacity>() < 1.0f
// || eval.get<style::BackgroundColor>().a < 1.0f)
// ? RenderPass::Translucent
// : RenderPass::Opaque | RenderPass::Translucent; // evaluated based on opaquePassCutoff in render()
const auto passes = evaluated.get<style::BackgroundOpacity>() == 0.0f
? RenderPass::None
: (!unevaluated.get<style::BackgroundPattern>().isUndefined()
|| evaluated.get<style::BackgroundOpacity>() < 1.0f
|| evaluated.get<style::BackgroundColor>().a < 1.0f)
? RenderPass::Translucent
: RenderPass::Opaque | RenderPass::Translucent; // evaluated based on opaquePassCutoff in render()
// unevaluated.hasTransition();
// getCrossfade<BackgroundLayerProperties>(evaluatedProperties).t != 1;
@@ -289,6 +290,7 @@ void RenderBackgroundLayer::update(const int32_t layerIndex,
if (layerChange) {
drawable->setLayerIndex(layerIndex);
}
// TODO: does render pass change dynamically?
}
std::unique_ptr<gfx::DrawableBuilder> builder;
@@ -306,6 +308,7 @@ void RenderBackgroundLayer::update(const int32_t layerIndex,
// We actually need to build things, so set up a builder if we haven't already
if (!builder) {
builder = context.createDrawableBuilder("background");
builder->setRenderPass(passes);
builder->setShader(shader);
builder->addTweaker(context.createDrawableTweaker());
builder->setColor(*color);

View File

@@ -444,18 +444,24 @@ void RenderFillLayer::update(const int32_t layerIndex,
}
auto& bucket = static_cast<FillBucket&>(*renderData->bucket);
// const auto& evaluated = getEvaluated<FillLayerProperties>(renderData->layerProperties);
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 auto fillRenderPass = (evaluated.get<FillColor>().constantOr(Color()).a >= 1.0f &&
evaluated.get<FillOpacity>().constantOr(0) >= 1.0f
/* && parameters.currentLayer >= parameters.opaquePassCutoff*/)
? RenderPass::Opaque
: RenderPass::Translucent;
builder->setRenderPass(fillRenderPass);
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());

View File

@@ -202,11 +202,9 @@ void Renderer::Impl::render(const RenderTree& renderTree) {
}
// Draw Drawables
{
const auto drawDrawables = [&](const mbgl::RenderPass renderPass){
// TODO: figure out how to make drawables participate in the depth system
// Maybe make it a function mapping draw priority to the depth range (always (0,1)?)
parameters.pass = RenderPass::Opaque;
parameters.currentLayer = parameters.opaquePassCutoff;
parameters.depthRangeSize = 1 - (1 + 2) * parameters.numSublayers * parameters.depthEpsilon;
const auto debugGroup(parameters.renderPass->createDebugGroup("drawables"));
@@ -218,6 +216,12 @@ void Renderer::Impl::render(const RenderTree& renderTree) {
for (const auto& drawPtr : drawables) {
auto& drawable = *drawPtr;
if (!drawable.hasRenderPass(renderPass)) {
continue;
}
if (drawable.hasRenderPass(RenderPass::Opaque) && parameters.currentLayer >= parameters.opaquePassCutoff) {
continue;
}
if (!context.setupDraw(parameters, drawable)) {
continue;
}
@@ -237,16 +241,20 @@ void Renderer::Impl::render(const RenderTree& renderTree) {
drawable.draw(parameters);
}
}
};
parameters.pass = RenderPass::Opaque;
parameters.currentLayer = 0;
parameters.opaquePassCutoff = 1;
drawDrawables(parameters.pass);
// Actually render the layers
parameters.opaquePassCutoff = renderTreeParameters.opaquePassCutOff;
parameters.depthRangeSize = 1 - (layerRenderItems.size() + 2) * parameters.numSublayers * parameters.depthEpsilon;
// - OPAQUE PASS -------------------------------------------------------------------------------
// Render everything top-to-bottom by using reverse iterators. Render opaque objects first.
{
parameters.pass = RenderPass::Opaque;
const auto debugGroup(parameters.renderPass->createDebugGroup("opaque"));
uint32_t i = 0;
@@ -263,10 +271,16 @@ void Renderer::Impl::render(const RenderTree& renderTree) {
}
}
parameters.pass = RenderPass::Translucent;
parameters.currentLayer = 1;
parameters.opaquePassCutoff = 1;
drawDrawables(parameters.pass);
parameters.opaquePassCutoff = renderTreeParameters.opaquePassCutOff;
// - TRANSLUCENT PASS --------------------------------------------------------------------------
// Make a second pass, rendering translucent objects. This time, we render bottom-to-top.
{
parameters.pass = RenderPass::Translucent;
const auto debugGroup(parameters.renderPass->createDebugGroup("translucent"));
int32_t i = static_cast<int32_t>(layerRenderItems.size()) - 1;