Move background tile shader selection back to the render layer (#1200)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
Tim Sylvester
2023-06-05 10:49:04 -07:00
committed by Bart Louwers
parent 90aea725e5
commit dc5f6c4d69
10 changed files with 124 additions and 75 deletions

View File

@@ -104,6 +104,10 @@ public:
/// @param location A sampler location in the shader being used with this drawable.
void setTexture(std::shared_ptr<gfx::Texture2D> texture, int32_t location);
/// Whether the drawble should be drawn
bool getEnabled() const { return enabled; }
void setEnabled(bool value) { enabled = value; }
/// not used for anything yet
DrawPriority getDrawPriority() const { return drawPriority; }
void setDrawPriority(DrawPriority value) { drawPriority = value; }
@@ -150,6 +154,7 @@ public:
}
protected:
bool enabled = true;
std::string name;
util::SimpleIdentity uniqueID;
gfx::ShaderProgramBasePtr shader;

View File

@@ -7,6 +7,8 @@
namespace mbgl {
namespace gfx {
class Context;
class UniformBuffer {
// Can only be created by platform specific implementations
protected:
@@ -49,24 +51,25 @@ public:
/// Get an uniform buffer element.
/// Returns a pointer to the element on success, or null if the uniform buffer doesn't exists.
const std::shared_ptr<UniformBuffer>& get(const std::string& name) const;
const std::shared_ptr<UniformBuffer>& get(std::string_view name) const;
/// Add a new uniform buffer element or replace the existing one.
const std::shared_ptr<UniformBuffer>& addOrReplace(std::string name, std::shared_ptr<UniformBuffer> uniformBuffer);
const std::shared_ptr<UniformBuffer>& addOrReplace(std::string_view name,
std::shared_ptr<UniformBuffer> uniformBuffer);
/// Create and add a new buffer or update an existing one
void createOrUpdate(std::string_view name, const std::vector<uint8_t>& data, gfx::Context&);
void createOrUpdate(std::string_view name, const void* data, std::size_t size, gfx::Context&);
template <typename T>
void createOrUpdate(std::string_view name, const T* data, gfx::Context& context) {
createOrUpdate(name, data, sizeof(T), context);
}
UniformBufferArray& operator=(UniformBufferArray&&);
UniformBufferArray& operator=(const UniformBufferArray&);
protected:
const std::shared_ptr<UniformBuffer>& add(std::string name, std::shared_ptr<UniformBuffer>&& uniformBuffer) {
const auto result = uniformBufferMap.insert(std::make_pair(std::move(name), std::shared_ptr<UniformBuffer>()));
if (result.second) {
result.first->second = std::move(uniformBuffer);
return result.first->second;
} else {
return nullref;
}
}
const std::shared_ptr<UniformBuffer>& add(const std::string_view name, std::shared_ptr<UniformBuffer>&&);
virtual std::unique_ptr<UniformBuffer> copy(const UniformBuffer& uniformBuffer) = 0;

View File

@@ -39,6 +39,10 @@ public:
LayerGroup(const LayerGroup&) = delete;
LayerGroup& operator=(const LayerGroup&) = delete;
/// Whether the drawables should be drawn
bool getEnabled() const { return enabled; }
void setEnabled(bool value) { enabled = value; }
int32_t getLayerIndex() const { return layerIndex; }
/// Called before starting each frame
@@ -64,6 +68,7 @@ public:
const LayerTweakerPtr& getLayerTweaker() const { return layerTweaker; }
protected:
bool enabled = true;
int32_t layerIndex;
LayerTweakerPtr layerTweaker;
};

View File

@@ -1,5 +1,7 @@
#include <mbgl/gfx/uniform_buffer.hpp>
#include <mbgl/gfx/context.hpp>
namespace mbgl {
namespace gfx {
@@ -24,17 +26,45 @@ UniformBufferArray& UniformBufferArray::operator=(const UniformBufferArray& othe
return *this;
}
const std::shared_ptr<UniformBuffer>& UniformBufferArray::get(const std::string& name) const {
const auto result = uniformBufferMap.find(name);
const std::shared_ptr<UniformBuffer>& UniformBufferArray::get(const std::string_view name) const {
const auto result = uniformBufferMap.find(std::string(name));
return (result != uniformBufferMap.end()) ? result->second : nullref;
}
const std::shared_ptr<UniformBuffer>& UniformBufferArray::addOrReplace(std::string name,
const std::shared_ptr<UniformBuffer>& UniformBufferArray::addOrReplace(const std::string_view name,
std::shared_ptr<UniformBuffer> uniformBuffer) {
const auto result = uniformBufferMap.insert(std::make_pair(std::move(name), std::shared_ptr<UniformBuffer>()));
const auto result = uniformBufferMap.insert(std::make_pair(name, std::shared_ptr<UniformBuffer>()));
result.first->second = std::move(uniformBuffer);
return result.first->second;
}
void UniformBufferArray::createOrUpdate(std::string_view name,
const std::vector<uint8_t>& data,
gfx::Context& context) {
createOrUpdate(name, data.data(), data.size(), context);
}
void UniformBufferArray::createOrUpdate(const std::string_view name,
const void* data,
const std::size_t size,
gfx::Context& context) {
if (auto& ubo = get(name); ubo && ubo->getSize() == size) {
ubo->update(data, size);
} else {
add(name, context.createUniformBuffer(data, size));
}
}
const std::shared_ptr<UniformBuffer>& UniformBufferArray::add(const std::string_view name,
std::shared_ptr<UniformBuffer>&& uniformBuffer) {
const auto result = uniformBufferMap.insert(std::make_pair(name, std::shared_ptr<UniformBuffer>()));
if (result.second) {
result.first->second = std::move(uniformBuffer);
return result.first->second;
} else {
return nullref;
}
}
} // namespace gfx
} // namespace mbgl

View File

@@ -7,6 +7,7 @@
#include <mbgl/gl/vertex_buffer_resource.hpp>
#include <mbgl/programs/segment.hpp>
#include <mbgl/shaders/gl/shader_program_gl.hpp>
#include <mbgl/util/logging.hpp>
namespace mbgl {
namespace gl {
@@ -28,8 +29,11 @@ void DrawableGL::draw(const PaintParameters& parameters) const {
if (shaderGL.getGLProgramID() != context.program.getCurrentValue()) {
context.program = shaderGL.getGLProgramID();
}
} else {
context.program = value::Program::Default;
}
if (!shader || context.program.getCurrentValue() == 0) {
mbgl::Log::Warning(Event::General, "Missing shader for drawable " + util::toString(getId()) + "/" + getName());
assert(false);
return;
}
context.setDepthMode(parameters.depthModeForSublayer(getSubLayerIndex(), getDepthType()));

View File

@@ -16,7 +16,15 @@ TileLayerGroupGL::TileLayerGroupGL(int32_t layerIndex_, std::size_t initialCapac
: TileLayerGroup(layerIndex_, initialCapacity) {}
void TileLayerGroupGL::upload(gfx::UploadPass& uploadPass) {
if (!enabled) {
return;
}
observeDrawables([&](gfx::Drawable& drawable) {
if (!drawable.getEnabled()) {
return;
}
auto& drawableGL = static_cast<gl::DrawableGL&>(drawable);
#if !defined(NDEBUG)
@@ -33,13 +41,12 @@ void TileLayerGroupGL::upload(gfx::UploadPass& uploadPass) {
}
void TileLayerGroupGL::render(RenderOrchestrator&, PaintParameters& parameters) {
// TODO: Render tile masks
// for (auto& layer : renderLayers) {
// parameters.renderTileClippingMasks(renderTiles);
//}
if (!enabled) {
return;
}
observeDrawables([&](gfx::Drawable& drawable) {
if (!drawable.hasRenderPass(parameters.pass)) {
if (!drawable.getEnabled() || !drawable.hasRenderPass(parameters.pass)) {
return;
}

View File

@@ -45,55 +45,48 @@ struct alignas(16) BackgroundPatternLayerUBO {
};
static_assert(sizeof(BackgroundPatternLayerUBO) == 96);
static constexpr std::string_view BackgroundPatternShaderName = "BackgroundPatternShader";
static constexpr std::string_view BackgroundDrawableUBOName = "BackgroundDrawableUBO";
static constexpr std::string_view BackgroundLayerUBOName = "BackgroundLayerUBO";
void BackgroundLayerTweaker::execute(LayerGroup& layerGroup, const RenderTree&, const PaintParameters& parameters) {
const auto& state = parameters.state;
auto& context = parameters.context;
const auto& evaluated = static_cast<const BackgroundLayerProperties&>(*evaluatedProperties).evaluated;
const auto& crossfade = static_cast<const BackgroundLayerProperties&>(*evaluatedProperties).crossfade;
const bool hasPattern = !evaluated.get<BackgroundPattern>().to.empty();
const std::optional<ImagePosition> imagePosA = hasPattern ? parameters.patternAtlas.getPattern(
evaluated.get<BackgroundPattern>().from.id())
: std::nullopt;
const std::optional<ImagePosition> imagePosB = hasPattern ? parameters.patternAtlas.getPattern(
evaluated.get<BackgroundPattern>().to.id())
: std::nullopt;
const auto imagePosA = hasPattern ? parameters.patternAtlas.getPattern(evaluated.get<BackgroundPattern>().from.id())
: std::nullopt;
const auto imagePosB = hasPattern ? parameters.patternAtlas.getPattern(evaluated.get<BackgroundPattern>().to.id())
: std::nullopt;
if (hasPattern && (!imagePosA || !imagePosB)) {
// The pattern isn't valid, disable the whole thing.
layerGroup.setEnabled(false);
return;
}
layerGroup.setEnabled(true);
if (!shader) {
shader = parameters.context.getGenericShader(parameters.shaders, "BackgroundShader");
}
if (!patternShader) {
patternShader = parameters.context.getGenericShader(parameters.shaders, "BackgroundPatternShader");
}
const auto& curShader = hasPattern ? patternShader : shader;
if (!curShader) {
return;
}
constexpr int32_t samplerLocation = 0;
layerGroup.observeDrawables([&](gfx::Drawable& drawable) {
assert(drawable.getTileID());
// We assume that drawables don't change between pattern and non-pattern.
assert(hasPattern == (drawable.getShader() ==
context.getGenericShader(parameters.shaders, std::string(BackgroundPatternShaderName))));
const UnwrappedTileID tileID = drawable.getTileID()->toUnwrapped();
const auto matrix = parameters.matrixForTile(tileID);
drawable.setShader(curShader);
BackgroundDrawableUBO drawableUBO = {/* .matrix = */ util::cast<float>(matrix)};
BackgroundDrawableUBO drawableUBO;
drawableUBO.matrix = util::cast<float>(matrix);
if (auto& ubo = drawable.mutableUniformBuffers().get("BackgroundDrawableUBO")) {
ubo->update(&drawableUBO, sizeof(drawableUBO));
} else {
drawable.mutableUniformBuffers().addOrReplace(
"BackgroundDrawableUBO", parameters.context.createUniformBuffer(&drawableUBO, sizeof(drawableUBO)));
}
auto& uniforms = drawable.mutableUniformBuffers();
uniforms.createOrUpdate(BackgroundDrawableUBOName, &drawableUBO, context);
if (hasPattern) {
// TODO: add when raster is merged
// curShader->getSamplerLocation("u_image");
drawable.setTexture(parameters.patternAtlas.texture(), 0);
// if (samplerLocation < 0) curShader->getSamplerLocation("u_image");
drawable.setTexture(parameters.patternAtlas.texture(), samplerLocation);
// from BackgroundPatternProgram::layoutUniformValues
const int32_t tileSizeAtNearestZoom = static_cast<int32_t>(
@@ -121,28 +114,14 @@ void BackgroundLayerTweaker::execute(LayerGroup& layerGroup, const RenderTree&,
/* .opacity = */ evaluated.get<BackgroundOpacity>(),
/* .pad = */ {0},
};
if (auto& ubo = drawable.mutableUniformBuffers().get("BackgroundLayerUBO");
ubo->getSize() == sizeof(layerUBO)) {
ubo->update(&drawableUBO, sizeof(drawableUBO));
} else {
drawable.mutableUniformBuffers().addOrReplace(
"BackgroundLayerUBO", parameters.context.createUniformBuffer(&layerUBO, sizeof(layerUBO)));
}
uniforms.createOrUpdate(BackgroundLayerUBOName, &layerUBO, context);
} else {
const BackgroundLayerUBO layerUBO = {
/* .color = */ evaluated.get<BackgroundColor>(),
/* .opacity = */ evaluated.get<BackgroundOpacity>(),
/* .pad = */ {0, 0, 0},
};
if (auto& ubo = drawable.mutableUniformBuffers().get("BackgroundLayerUBO");
ubo->getSize() == sizeof(layerUBO)) {
ubo->update(&drawableUBO, sizeof(drawableUBO));
} else {
drawable.mutableUniformBuffers().addOrReplace(
"BackgroundLayerUBO", parameters.context.createUniformBuffer(&layerUBO, sizeof(layerUBO)));
}
uniforms.createOrUpdate(BackgroundLayerUBOName, &layerUBO, context);
}
});
}

View File

@@ -28,8 +28,6 @@ public:
void execute(LayerGroup&, const RenderTree&, const PaintParameters&) override;
protected:
gfx::ShaderProgramBasePtr shader;
gfx::ShaderProgramBasePtr patternShader;
};
} // namespace mbgl

View File

@@ -205,7 +205,10 @@ void RenderBackgroundLayer::layerRemoved(UniqueChangeRequestVec& changes) {
}
}
void RenderBackgroundLayer::update(gfx::ShaderRegistry& /*shaders*/,
static constexpr std::string_view BackgroundPlainShaderName = "BackgroundShader";
static constexpr std::string_view BackgroundPatternShaderName = "BackgroundPatternShader";
void RenderBackgroundLayer::update(gfx::ShaderRegistry& shaders,
gfx::Context& context,
const TransformState& state,
[[maybe_unused]] const RenderTree& renderTree,
@@ -229,6 +232,7 @@ void RenderBackgroundLayer::update(gfx::ShaderRegistry& /*shaders*/,
}
const auto& evaluated = getEvaluated<BackgroundLayerProperties>(evaluatedProperties);
const bool hasPattern = !evaluated.get<BackgroundPattern>().to.empty();
// TODO: If background is solid, we can skip drawables and rely on the clear color
const auto drawPasses = evaluated.get<style::BackgroundOpacity>() == 0.0f ? RenderPass::None
@@ -253,8 +257,18 @@ void RenderBackgroundLayer::update(gfx::ShaderRegistry& /*shaders*/,
tileLayerGroup->setLayerTweaker(std::make_shared<BackgroundLayerTweaker>(evaluatedProperties));
}
// Drawables per overscaled or canonical tile?
// const UnwrappedTileID unwrappedTileID = tileID.toUnwrapped();
if (!hasPattern && !plainShader) {
plainShader = context.getGenericShader(shaders, std::string(BackgroundPlainShaderName));
}
if (hasPattern && !patternShader) {
patternShader = context.getGenericShader(shaders, std::string(BackgroundPatternShaderName));
}
const auto& curShader = hasPattern ? patternShader : plainShader;
if (!curShader) {
removeAll();
return;
}
// Put the tile cover into a searchable form.
// TODO: Likely better to sort and `std::binary_search` the vector.
@@ -286,12 +300,12 @@ void RenderBackgroundLayer::update(gfx::ShaderRegistry& /*shaders*/,
if (!builder) {
builder = context.createDrawableBuilder("background");
builder->setRenderPass(drawPasses);
// builder->setShader(shader);
builder->setShader(curShader);
builder->setColorAttrMode(gfx::DrawableBuilder::ColorAttrMode::PerDrawable);
builder->setDepthType(gfx::DepthMaskType::ReadWrite);
}
// Tile coordinates are fixed...
// Tile coordinates are fixed.
builder->addQuad(0, 0, util::EXTENT, util::EXTENT);
builder->flush();

View File

@@ -48,6 +48,10 @@ private:
// Programs
std::shared_ptr<BackgroundProgram> backgroundProgram;
std::shared_ptr<BackgroundPatternProgram> backgroundPatternProgram;
// Drawable shaders
gfx::ShaderProgramBasePtr plainShader;
gfx::ShaderProgramBasePtr patternShader;
};
} // namespace mbgl