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:
committed by
Bart Louwers
parent
90aea725e5
commit
dc5f6c4d69
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()));
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -28,8 +28,6 @@ public:
|
||||
void execute(LayerGroup&, const RenderTree&, const PaintParameters&) override;
|
||||
|
||||
protected:
|
||||
gfx::ShaderProgramBasePtr shader;
|
||||
gfx::ShaderProgramBasePtr patternShader;
|
||||
};
|
||||
|
||||
} // namespace mbgl
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user