Uniform buffer objects (#1127)
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
bbb8bf3c1e
commit
d8ea91de98
@@ -6,6 +6,7 @@
|
||||
#include <mbgl/gfx/program.hpp>
|
||||
#include <mbgl/gfx/renderbuffer.hpp>
|
||||
#include <mbgl/gfx/rendering_stats.hpp>
|
||||
#include <mbgl/gfx/uniform_buffer.hpp>
|
||||
#include <mbgl/gfx/texture.hpp>
|
||||
#include <mbgl/gfx/types.hpp>
|
||||
|
||||
@@ -29,6 +30,7 @@ class ShaderRegistry;
|
||||
using DrawablePtr = std::shared_ptr<Drawable>;
|
||||
using UniqueDrawableBuilder = std::unique_ptr<DrawableBuilder>;
|
||||
using DrawableTweakerPtr = std::shared_ptr<DrawableTweaker>;
|
||||
using UniformBufferPtr = std::shared_ptr<UniformBuffer>;
|
||||
using ShaderProgramBasePtr = std::shared_ptr<ShaderProgramBase>;
|
||||
|
||||
class Context {
|
||||
@@ -106,6 +108,9 @@ public:
|
||||
/// Create a new drawable tweaker
|
||||
virtual DrawableTweakerPtr createDrawableTweaker() = 0;
|
||||
|
||||
/// Create a new uniform buffer
|
||||
virtual UniformBufferPtr createUniformBuffer(const void* data, std::size_t size) = 0;
|
||||
|
||||
/// Get the generic shader with the specified name
|
||||
virtual gfx::ShaderProgramBasePtr getGenericShader(gfx::ShaderRegistry&, const std::string& name) = 0;
|
||||
};
|
||||
|
||||
43
src/mbgl/gfx/uniform_block.cpp
Normal file
43
src/mbgl/gfx/uniform_block.cpp
Normal file
@@ -0,0 +1,43 @@
|
||||
#include <mbgl/gfx/uniform_block.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace gfx {
|
||||
|
||||
std::unique_ptr<UniformBlock> UniformBlockArray::nullref = nullptr;
|
||||
|
||||
UniformBlockArray::UniformBlockArray(int initCapacity)
|
||||
: uniformBlockMap(initCapacity) {}
|
||||
|
||||
UniformBlockArray::UniformBlockArray(UniformBlockArray&& other)
|
||||
: uniformBlockMap(std::move(other.uniformBlockMap)) {}
|
||||
|
||||
UniformBlockArray& UniformBlockArray::operator=(UniformBlockArray&& other) {
|
||||
uniformBlockMap = std::move(other.uniformBlockMap);
|
||||
return *this;
|
||||
}
|
||||
|
||||
UniformBlockArray& UniformBlockArray::operator=(const UniformBlockArray& other) {
|
||||
uniformBlockMap.clear();
|
||||
for (const auto& kv : other.uniformBlockMap) {
|
||||
add(kv.first, copy(*kv.second));
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
const std::unique_ptr<UniformBlock>& UniformBlockArray::get(const std::string& name) const {
|
||||
const auto result = uniformBlockMap.find(name);
|
||||
return (result != uniformBlockMap.end()) ? result->second : nullref;
|
||||
}
|
||||
|
||||
const std::unique_ptr<UniformBlock>& UniformBlockArray::add(std::string name, int index, std::size_t size) {
|
||||
const auto result = uniformBlockMap.insert(std::make_pair(std::move(name), std::unique_ptr<UniformBlock>()));
|
||||
if (result.second) {
|
||||
result.first->second = create(index, size);
|
||||
return result.first->second;
|
||||
} else {
|
||||
return nullref;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace mbgl
|
||||
40
src/mbgl/gfx/uniform_buffer.cpp
Normal file
40
src/mbgl/gfx/uniform_buffer.cpp
Normal file
@@ -0,0 +1,40 @@
|
||||
#include <mbgl/gfx/uniform_buffer.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace gfx {
|
||||
|
||||
std::shared_ptr<UniformBuffer> UniformBufferArray::nullref = nullptr;
|
||||
|
||||
UniformBufferArray::UniformBufferArray(int initCapacity)
|
||||
: uniformBufferMap(initCapacity) {}
|
||||
|
||||
UniformBufferArray::UniformBufferArray(UniformBufferArray&& other)
|
||||
: uniformBufferMap(std::move(other.uniformBufferMap)) {}
|
||||
|
||||
UniformBufferArray& UniformBufferArray::operator=(UniformBufferArray&& other) {
|
||||
uniformBufferMap = std::move(other.uniformBufferMap);
|
||||
return *this;
|
||||
}
|
||||
|
||||
UniformBufferArray& UniformBufferArray::operator=(const UniformBufferArray& other) {
|
||||
uniformBufferMap.clear();
|
||||
for (const auto& kv : other.uniformBufferMap) {
|
||||
add(kv.first, copy(*kv.second));
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
const std::shared_ptr<UniformBuffer>& UniformBufferArray::get(const std::string& name) const {
|
||||
const auto result = uniformBufferMap.find(name);
|
||||
return (result != uniformBufferMap.end()) ? result->second : nullref;
|
||||
}
|
||||
|
||||
const std::shared_ptr<UniformBuffer>& UniformBufferArray::addOrReplace(
|
||||
std::string name, const std::shared_ptr<UniformBuffer>& uniformBuffer) {
|
||||
const auto result = uniformBufferMap.insert(std::make_pair(std::move(name), std::shared_ptr<UniformBuffer>()));
|
||||
result.first->second = std::move(uniformBuffer);
|
||||
return result.first->second;
|
||||
}
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace mbgl
|
||||
@@ -7,6 +7,8 @@
|
||||
namespace mbgl {
|
||||
namespace gfx {
|
||||
|
||||
std::unique_ptr<VertexAttribute> VertexAttributeArray::nullref = nullptr;
|
||||
|
||||
VertexAttributeArray::VertexAttributeArray(int initCapacity)
|
||||
: attrs(initCapacity) {}
|
||||
|
||||
@@ -26,23 +28,23 @@ VertexAttributeArray& VertexAttributeArray::operator=(const VertexAttributeArray
|
||||
return *this;
|
||||
}
|
||||
|
||||
VertexAttribute* VertexAttributeArray::get(const std::string& name) const {
|
||||
const std::unique_ptr<VertexAttribute>& VertexAttributeArray::get(const std::string& name) const {
|
||||
const auto result = attrs.find(name);
|
||||
return (result != attrs.end()) ? result->second.get() : nullptr;
|
||||
return (result != attrs.end()) ? result->second : nullref;
|
||||
}
|
||||
|
||||
VertexAttribute* VertexAttributeArray::add(
|
||||
const std::unique_ptr<VertexAttribute>& VertexAttributeArray::add(
|
||||
std::string name, int index, AttributeDataType dataType, int size, std::size_t count) {
|
||||
const auto result = attrs.insert(std::make_pair(std::move(name), std::unique_ptr<VertexAttribute>()));
|
||||
if (result.second) {
|
||||
result.first->second = create(index, dataType, size, count);
|
||||
return result.first->second.get();
|
||||
return result.first->second;
|
||||
} else {
|
||||
return nullptr;
|
||||
return nullref;
|
||||
}
|
||||
}
|
||||
|
||||
VertexAttribute* VertexAttributeArray::getOrAdd(
|
||||
const std::unique_ptr<VertexAttribute>& VertexAttributeArray::getOrAdd(
|
||||
std::string name, int index, AttributeDataType dataType, int size, std::size_t count) {
|
||||
// attrs.emplace_back(std::make_unique<VertexAttribute>(dataType, count));
|
||||
const auto result = attrs.insert(std::make_pair(std::move(name), std::unique_ptr<VertexAttribute>()));
|
||||
@@ -50,9 +52,9 @@ VertexAttribute* VertexAttributeArray::getOrAdd(
|
||||
result.first->second = create(index, dataType, size, count);
|
||||
} else if (result.first->second->getDataType() != dataType ||
|
||||
result.first->second->getSize() != (std::size_t)size || result.first->second->getCount() != count) {
|
||||
return nullptr;
|
||||
return nullref;
|
||||
}
|
||||
return result.first->second.get();
|
||||
return result.first->second;
|
||||
}
|
||||
|
||||
std::size_t VertexAttributeArray::getTotalSize() const {
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <mbgl/gl/enum.hpp>
|
||||
#include <mbgl/gl/renderer_backend.hpp>
|
||||
#include <mbgl/gl/renderbuffer_resource.hpp>
|
||||
#include <mbgl/gl/uniform_buffer_gl.hpp>
|
||||
#include <mbgl/gl/texture_resource.hpp>
|
||||
#include <mbgl/gl/texture.hpp>
|
||||
#include <mbgl/gl/offscreen_texture.hpp>
|
||||
@@ -497,6 +498,10 @@ gfx::DrawableTweakerPtr Context::createDrawableTweaker() {
|
||||
return std::make_shared<gl::DrawableGLTweaker>();
|
||||
}
|
||||
|
||||
gfx::UniformBufferPtr Context::createUniformBuffer(const void* data, std::size_t size) {
|
||||
return std::make_shared<gl::UniformBufferGL>(data, size);
|
||||
}
|
||||
|
||||
gfx::ShaderProgramBasePtr Context::getGenericShader(gfx::ShaderRegistry& shaders, const std::string& name) {
|
||||
return shaders.get<gl::ShaderProgramGL>(name);
|
||||
}
|
||||
|
||||
@@ -106,6 +106,7 @@ public:
|
||||
|
||||
gfx::UniqueDrawableBuilder createDrawableBuilder(std::string name) override;
|
||||
gfx::DrawableTweakerPtr createDrawableTweaker() override;
|
||||
gfx::UniformBufferPtr createUniformBuffer(const void* data, std::size_t size) override;
|
||||
|
||||
gfx::ShaderProgramBasePtr getGenericShader(gfx::ShaderRegistry&, const std::string& name) override;
|
||||
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
#include <mbgl/gl/drawable_gl_impl.hpp>
|
||||
#include <mbgl/gl/vertex_buffer_resource.hpp>
|
||||
|
||||
#include <mbgl/shaders/gl/shader_program_gl.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace gl {
|
||||
|
||||
@@ -16,7 +18,9 @@ DrawableGL::~DrawableGL() {
|
||||
}
|
||||
|
||||
void DrawableGL::draw(const PaintParameters& parameters) const {
|
||||
bindUniformBuffers();
|
||||
impl->draw(parameters);
|
||||
unbindUniformBuffers();
|
||||
}
|
||||
|
||||
void DrawableGL::setIndexData(std::vector<std::uint16_t> indexes,
|
||||
@@ -67,12 +71,42 @@ void DrawableGL::setVertexArray(gl::VertexArray&& vertexArray_,
|
||||
impl->indexBuffer = std::move(indexBuffer_);
|
||||
}
|
||||
|
||||
const gfx::UniformBufferArray& DrawableGL::getUniformBuffers() const {
|
||||
return impl->uniformBuffers;
|
||||
}
|
||||
|
||||
gfx::UniformBufferArray& DrawableGL::mutableUniformBuffers() {
|
||||
return impl->uniformBuffers;
|
||||
}
|
||||
|
||||
void DrawableGL::resetColor(const Color& newColor) {
|
||||
if (auto* colorAttr = impl->vertexAttributes.get("a_color")) {
|
||||
if (const auto& colorAttr = impl->vertexAttributes.get("a_color")) {
|
||||
colorAttr->clear();
|
||||
colorAttr->set(0, colorAttrValue(newColor));
|
||||
}
|
||||
}
|
||||
|
||||
void DrawableGL::bindUniformBuffers() const {
|
||||
if (shader) {
|
||||
const auto& shaderGL = static_cast<const ShaderProgramGL&>(*shader);
|
||||
for (const auto& element : shaderGL.getUniformBlocks().getMap()) {
|
||||
const auto& uniformBuffer = getUniformBuffers().get(element.first);
|
||||
if (!uniformBuffer) {
|
||||
continue;
|
||||
}
|
||||
element.second->bindBuffer(*uniformBuffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DrawableGL::unbindUniformBuffers() const {
|
||||
if (shader) {
|
||||
const auto& shaderGL = static_cast<const ShaderProgramGL&>(*shader);
|
||||
for (const auto& element : shaderGL.getUniformBlocks().getMap()) {
|
||||
element.second->unbindBuffer();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace gl
|
||||
} // namespace mbgl
|
||||
|
||||
@@ -15,13 +15,13 @@ void DrawableGLBuilder::init() {
|
||||
auto& drawableGL = static_cast<DrawableGL&>(*currentDrawable);
|
||||
|
||||
auto& attrs = drawableGL.mutableVertexAttributes();
|
||||
if (auto posAttr = attrs.getOrAdd("a_pos")) {
|
||||
if (const auto& posAttr = attrs.getOrAdd("a_pos")) {
|
||||
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 (auto colorAttr = attrs.getOrAdd("a_color")) {
|
||||
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()) {
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <mbgl/gl/defines.hpp>
|
||||
#include <mbgl/gl/enum.hpp>
|
||||
#include <mbgl/gl/program.hpp>
|
||||
#include <mbgl/gl/uniform_buffer_gl.hpp>
|
||||
#include <mbgl/gl/vertex_array.hpp>
|
||||
#include <mbgl/platform/gl_functions.hpp>
|
||||
#include <mbgl/renderer/paint_parameters.hpp>
|
||||
@@ -47,6 +48,8 @@ public:
|
||||
gfx::IndexBuffer indexBuffer = {0, nullptr};
|
||||
gfx::UniqueVertexBufferResource attributeBuffer;
|
||||
|
||||
UniformBufferArrayGL uniformBuffers;
|
||||
|
||||
std::size_t indexOffset = 0;
|
||||
std::size_t indexLength = 0;
|
||||
std::size_t attributeOffset = 0;
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <mbgl/gfx/shader_registry.hpp>
|
||||
#include <mbgl/gl/context.hpp>
|
||||
#include <mbgl/gl/extension.hpp>
|
||||
#include <mbgl/shaders/shader_manifest.hpp>
|
||||
#include <mbgl/shaders/gl/shader_program_gl.hpp>
|
||||
#include <mbgl/util/logging.hpp>
|
||||
|
||||
@@ -66,33 +67,14 @@ void RendererBackend::setScissorTest(bool enabled) {
|
||||
RendererBackend::~RendererBackend() = default;
|
||||
|
||||
void RendererBackend::initShaders(gfx::ShaderRegistry& shaders) {
|
||||
constexpr auto shaderName = "background_generic";
|
||||
constexpr auto shaderName = "BackgroundProgramUBO";
|
||||
|
||||
gl::Context& glContext = static_cast<gl::Context&>(*context);
|
||||
|
||||
auto shader = shaders.get<gl::ShaderProgramGL>(shaderName);
|
||||
if (!shader) {
|
||||
constexpr auto vert = R"(#version 300 es
|
||||
precision highp float;
|
||||
|
||||
uniform mat4 u_matrix;
|
||||
layout (location = 0) in vec2 a_pos;
|
||||
layout (location = 1) in vec4 a_color;
|
||||
out vec4 v_color;
|
||||
|
||||
void main() {
|
||||
v_color = a_color;
|
||||
gl_Position = u_matrix * vec4(a_pos, 0, 1);
|
||||
})";
|
||||
constexpr auto frag = R"(#version 300 es
|
||||
precision highp float;
|
||||
in vec4 v_color;
|
||||
out vec4 fragColor;
|
||||
|
||||
void main() {
|
||||
fragColor = v_color;
|
||||
})";
|
||||
|
||||
auto vert = shaders::ShaderSource<shaders::BuiltIn::BackgroundProgramUBO, gfx::Backend::Type::OpenGL>::vertex;
|
||||
auto frag = shaders::ShaderSource<shaders::BuiltIn::BackgroundProgramUBO, gfx::Backend::Type::OpenGL>::fragment;
|
||||
try {
|
||||
// Compile
|
||||
shader = gl::ShaderProgramGL::create(glContext, shaderName, vert, frag);
|
||||
|
||||
27
src/mbgl/gl/uniform_block_gl.cpp
Normal file
27
src/mbgl/gl/uniform_block_gl.cpp
Normal file
@@ -0,0 +1,27 @@
|
||||
|
||||
#include <mbgl/gl/uniform_block_gl.hpp>
|
||||
#include <mbgl/gl/uniform_buffer_gl.hpp>
|
||||
#include <mbgl/gl/defines.hpp>
|
||||
#include <mbgl/platform/gl_functions.hpp>
|
||||
|
||||
#include <cassert>
|
||||
|
||||
namespace mbgl {
|
||||
namespace gl {
|
||||
|
||||
using namespace platform;
|
||||
|
||||
void UniformBlockGL::bindBuffer(const gfx::UniformBuffer& uniformBuffer) {
|
||||
assert(size == uniformBuffer.getSize());
|
||||
GLint binding = index;
|
||||
const auto& uniformBufferGL = static_cast<const UniformBufferGL&>(uniformBuffer);
|
||||
MBGL_CHECK_ERROR(glBindBufferBase(GL_UNIFORM_BUFFER, binding, uniformBufferGL.getID()));
|
||||
}
|
||||
|
||||
void UniformBlockGL::unbindBuffer() {
|
||||
GLint binding = index;
|
||||
MBGL_CHECK_ERROR(glBindBufferBase(GL_UNIFORM_BUFFER, binding, 0));
|
||||
}
|
||||
|
||||
} // namespace gl
|
||||
} // namespace mbgl
|
||||
20
src/mbgl/gl/uniform_buffer_gl.cpp
Normal file
20
src/mbgl/gl/uniform_buffer_gl.cpp
Normal file
@@ -0,0 +1,20 @@
|
||||
|
||||
#include <mbgl/gl/uniform_buffer_gl.hpp>
|
||||
#include <mbgl/gl/defines.hpp>
|
||||
#include <mbgl/platform/gl_functions.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace gl {
|
||||
|
||||
using namespace platform;
|
||||
|
||||
UniformBufferGL::UniformBufferGL(const void* data, std::size_t size_)
|
||||
: UniformBuffer(size_) {
|
||||
MBGL_CHECK_ERROR(glGenBuffers(1, &id));
|
||||
MBGL_CHECK_ERROR(glBindBuffer(GL_UNIFORM_BUFFER, id));
|
||||
MBGL_CHECK_ERROR(glBufferData(GL_UNIFORM_BUFFER, size, data, GL_STATIC_DRAW));
|
||||
MBGL_CHECK_ERROR(glBindBuffer(GL_UNIFORM_BUFFER, 0));
|
||||
}
|
||||
|
||||
} // namespace gl
|
||||
} // namespace mbgl
|
||||
@@ -148,9 +148,7 @@ gfx::AttributeBindingArray UploadPass::buildAttributeBindings(
|
||||
|
||||
// For each attribute in the program, with the corresponding default and optional override...
|
||||
defaults.resolve(overrides,
|
||||
[&](const std::string& name,
|
||||
const gfx::VertexAttribute& defaultAttr,
|
||||
const gfx::VertexAttribute* overrideAttr) -> void {
|
||||
[&](const std::string& name, const auto& defaultAttr, const auto& overrideAttr) -> void {
|
||||
const auto& effectiveAttr = overrideAttr ? *overrideAttr : defaultAttr;
|
||||
const auto& effectiveGL = static_cast<const gl::VertexAttributeGL&>(effectiveAttr);
|
||||
const auto& defaultGL = static_cast<const gl::VertexAttributeGL&>(defaultAttr);
|
||||
|
||||
@@ -169,57 +169,5 @@ const std::vector<std::uint8_t>& VertexAttributeGL::getRaw(platform::GLenum type
|
||||
return rawData;
|
||||
}
|
||||
|
||||
namespace {
|
||||
template <typename T>
|
||||
void applyUniform(GLint, const T&);
|
||||
template <>
|
||||
void applyUniform(GLint, const std::int32_t&) {}
|
||||
template <>
|
||||
void applyUniform(GLint, const gfx::VertexAttribute::int2&) {}
|
||||
template <>
|
||||
void applyUniform(GLint, const gfx::VertexAttribute::int3&) {}
|
||||
template <>
|
||||
void applyUniform(GLint, const gfx::VertexAttribute::int4&) {}
|
||||
template <>
|
||||
void applyUniform(GLint, const float&) {}
|
||||
template <>
|
||||
void applyUniform(GLint, const gfx::VertexAttribute::float2&) {}
|
||||
template <>
|
||||
void applyUniform(GLint, const gfx::VertexAttribute::float3&) {}
|
||||
template <>
|
||||
void applyUniform(GLint, const gfx::VertexAttribute::float4&) {}
|
||||
template <>
|
||||
void applyUniform(GLint, const gfx::VertexAttribute::matf3&) {}
|
||||
template <>
|
||||
void applyUniform(GLint location, const gfx::VertexAttribute::matf4& value) {
|
||||
MBGL_CHECK_ERROR(glUniformMatrix4fv(location, 1, GL_FALSE, value.data()));
|
||||
}
|
||||
} // namespace
|
||||
|
||||
struct ApplyUniform {
|
||||
GLint location;
|
||||
template <typename T>
|
||||
void operator()(const T& value) {
|
||||
applyUniform(location, value);
|
||||
}
|
||||
};
|
||||
|
||||
void VertexAttributeArrayGL::applyUniforms(const gfx::ShaderProgramBase& shader) {
|
||||
const auto& glShader = static_cast<const ShaderProgramGL&>(shader);
|
||||
const auto program = glShader.getGLProgramID();
|
||||
|
||||
for (auto& kv : attrs) {
|
||||
const auto& name = kv.first;
|
||||
auto& uniform = kv.second;
|
||||
|
||||
if (uniform->getIndex() < 0) {
|
||||
const auto index = MBGL_CHECK_ERROR(glGetUniformLocation(program, name.c_str()));
|
||||
Log::Warning(Event::General, "Uniform '" + name + "' = " + std::to_string(index));
|
||||
uniform->setIndex(index);
|
||||
}
|
||||
std::visit(ApplyUniform{uniform->getIndex()}, uniform->get(0));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace gl
|
||||
} // namespace mbgl
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <mbgl/shaders/shader_program_base.hpp>
|
||||
#include <mbgl/util/tile_cover.hpp>
|
||||
#include <mbgl/map/transform_state.hpp>
|
||||
#include <mbgl/util/convert.hpp>
|
||||
#include <mbgl/util/logging.hpp>
|
||||
|
||||
#include <unordered_set>
|
||||
@@ -60,6 +61,7 @@ void RenderBackgroundLayer::evaluate(const PropertyEvaluationParameters& paramet
|
||||
properties->renderPasses = mbgl::underlying_type(passes);
|
||||
|
||||
evaluatedProperties = std::move(properties);
|
||||
evaluatedPropertiesChange = true;
|
||||
}
|
||||
|
||||
bool RenderBackgroundLayer::hasTransition() const {
|
||||
@@ -194,7 +196,7 @@ void RenderBackgroundLayer::prepare(const LayerPrepareParameters& params) {
|
||||
}
|
||||
}
|
||||
|
||||
constexpr auto shaderName = "background_generic";
|
||||
constexpr auto shaderName = "BackgroundProgramUBO";
|
||||
|
||||
void RenderBackgroundLayer::layerRemoved(UniqueChangeRequestVec& changes) {
|
||||
// TODO: This isn't happening on style change, so old tile drawables are being left active
|
||||
@@ -235,25 +237,23 @@ void RenderBackgroundLayer::update(const int32_t layerIndex,
|
||||
// unevaluated.hasTransition();
|
||||
// getCrossfade<BackgroundLayerProperties>(evaluatedProperties).t != 1;
|
||||
|
||||
std::optional<Color> color;
|
||||
if (evaluated.get<BackgroundPattern>().from.empty()) {
|
||||
const auto opacity = evaluated.get<style::BackgroundOpacity>();
|
||||
if (opacity > 0.0f) {
|
||||
color = evaluated.get<BackgroundColor>() * evaluated.get<BackgroundOpacity>();
|
||||
}
|
||||
}
|
||||
|
||||
// If the result is transparent or missing, just remove any existing drawables and stop
|
||||
if (!color) {
|
||||
if (!evaluated.get<BackgroundPattern>().from.empty() || evaluated.get<style::BackgroundOpacity>() <= 0.0f) {
|
||||
removeDrawables<decltype(tileDrawables)::const_iterator>(
|
||||
tileDrawables.cbegin(), tileDrawables.cend(), changes, [](auto& ii) { return ii->second->getId(); });
|
||||
tileDrawables.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
const bool colorChange = (color != lastColor);
|
||||
if (evaluatedPropertiesChange) {
|
||||
BackgroundLayerUBO backgroundLayerUBO;
|
||||
backgroundLayerUBO.color = evaluated.get<BackgroundColor>();
|
||||
backgroundLayerUBO.opacity = evaluated.get<BackgroundOpacity>();
|
||||
uniformBuffer = context.createUniformBuffer(&backgroundLayerUBO, sizeof(backgroundLayerUBO));
|
||||
evaluatedPropertiesChange = false;
|
||||
}
|
||||
|
||||
const bool layerChange = (layerIndex != lastLayerIndex);
|
||||
lastColor = color;
|
||||
lastLayerIndex = layerIndex;
|
||||
|
||||
const auto zoom = state.getIntegerZoom();
|
||||
@@ -283,10 +283,6 @@ void RenderBackgroundLayer::update(const int32_t layerIndex,
|
||||
}
|
||||
++iter;
|
||||
|
||||
// If the color evaluated to a new value, update all vertexes of the drawable to the new color
|
||||
if (colorChange) {
|
||||
drawable->resetColor(*color);
|
||||
}
|
||||
if (layerChange) {
|
||||
drawable->setLayerIndex(layerIndex);
|
||||
}
|
||||
@@ -302,6 +298,7 @@ void RenderBackgroundLayer::update(const int32_t layerIndex,
|
||||
if (!result.second) {
|
||||
// Already present
|
||||
// TODO: Update matrix here or in the tweaker?
|
||||
result.first->second->mutableUniformBuffers().addOrReplace("BackgroundLayerUBO", uniformBuffer);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -311,7 +308,6 @@ void RenderBackgroundLayer::update(const int32_t layerIndex,
|
||||
builder->setRenderPass(drawPasses);
|
||||
builder->setShader(shader);
|
||||
builder->addTweaker(context.createDrawableTweaker());
|
||||
builder->setColor(*color);
|
||||
builder->setColorMode(gfx::DrawableBuilder::ColorMode::PerDrawable);
|
||||
builder->setDepthType(gfx::DepthMaskType::ReadWrite);
|
||||
builder->setLayerIndex(layerIndex);
|
||||
@@ -329,6 +325,7 @@ void RenderBackgroundLayer::update(const int32_t layerIndex,
|
||||
if (!newDrawables.empty()) {
|
||||
auto& drawable = newDrawables[0];
|
||||
drawable->setTileID(tileID);
|
||||
drawable->mutableUniformBuffers().addOrReplace("BackgroundLayerUBO", uniformBuffer);
|
||||
result.first->second = drawable;
|
||||
changes.emplace_back(std::make_unique<AddDrawableRequest>(std::move(drawable)));
|
||||
++stats.tileDrawablesAdded;
|
||||
|
||||
@@ -50,4 +50,26 @@ private:
|
||||
std::shared_ptr<BackgroundPatternProgram> backgroundPatternProgram;
|
||||
};
|
||||
|
||||
struct alignas(16) BackgroundLayerUBO {
|
||||
Color color;
|
||||
float opacity;
|
||||
};
|
||||
|
||||
struct alignas(16) BackgroundPatternLayerUBO {
|
||||
std::array<float, 2> pattern_tl_a;
|
||||
std::array<float, 2> pattern_br_a;
|
||||
std::array<float, 2> pattern_tl_b;
|
||||
std::array<float, 2> pattern_br_b;
|
||||
std::array<float, 2> texsize;
|
||||
std::array<float, 2> pattern_size_a;
|
||||
std::array<float, 2> pattern_size_b;
|
||||
std::array<float, 2> pixel_coord_upper;
|
||||
std::array<float, 2> pixel_coord_lower;
|
||||
float tile_units_to_pixels;
|
||||
float scale_a;
|
||||
float scale_b;
|
||||
float mix;
|
||||
float opacity;
|
||||
};
|
||||
|
||||
} // namespace mbgl
|
||||
|
||||
@@ -260,7 +260,7 @@ bool RenderFillLayer::queryIntersectsFeature(const GeometryCoordinates& queryGeo
|
||||
feature.getGeometries());
|
||||
}
|
||||
|
||||
constexpr auto shaderName = "background_generic";
|
||||
constexpr auto shaderName = "BackgroundProgramUBO";
|
||||
|
||||
void RenderFillLayer::layerRemoved(UniqueChangeRequestVec& changes) {
|
||||
// Remove everything
|
||||
|
||||
@@ -180,8 +180,9 @@ protected:
|
||||
std::mutex mutex;
|
||||
gfx::ShaderProgramBasePtr shader;
|
||||
std::unordered_map<OverscaledTileID, gfx::DrawablePtr> tileDrawables;
|
||||
std::optional<Color> lastColor;
|
||||
int32_t lastLayerIndex = -1;
|
||||
bool evaluatedPropertiesChange = false;
|
||||
gfx::UniformBufferPtr uniformBuffer = nullptr;
|
||||
|
||||
struct Stats {
|
||||
size_t propertyEvaluations = 0;
|
||||
|
||||
@@ -234,10 +234,10 @@ void Renderer::Impl::render(const RenderTree& renderTree) {
|
||||
matrix = tileMat;
|
||||
}
|
||||
|
||||
if (auto& shader = drawable.getShader()) {
|
||||
shader->setUniform("u_matrix", 0, util::convert<float>(matrix));
|
||||
shader->updateUniforms();
|
||||
}
|
||||
gfx::DrawableUBO drawableUBO;
|
||||
drawableUBO.matrix = util::convert<float>(matrix);
|
||||
auto uniformBuffer = context.createUniformBuffer(&drawableUBO, sizeof(drawableUBO));
|
||||
drawable.mutableUniformBuffers().addOrReplace("DrawableUBO", uniformBuffer);
|
||||
|
||||
drawable.draw(parameters);
|
||||
}
|
||||
@@ -261,7 +261,7 @@ void Renderer::Impl::render(const RenderTree& renderTree) {
|
||||
for (auto it = layerRenderItems.rbegin(); it != layerRenderItems.rend(); ++it, ++i) {
|
||||
parameters.currentLayer = i;
|
||||
const RenderItem& renderItem = it->get();
|
||||
if (renderItem.getName() == "background") { // Replaced by drawables, above
|
||||
if (renderItem.getName() == "background") {
|
||||
continue;
|
||||
}
|
||||
if (renderItem.hasRenderPass(parameters.pass)) {
|
||||
|
||||
@@ -82,17 +82,17 @@ ShaderProgramGL::ShaderProgramGL(UniqueProgram&& glProgram_)
|
||||
glProgram(std::move(glProgram_)) {}
|
||||
|
||||
ShaderProgramGL::ShaderProgramGL(UniqueProgram&& program,
|
||||
VertexAttributeArrayGL&& uniforms_,
|
||||
UniformBlockArrayGL&& uniformBlocks_,
|
||||
VertexAttributeArrayGL&& attributes_)
|
||||
: ShaderProgramBase(),
|
||||
glProgram(std::move(program)),
|
||||
uniforms(std::move(uniforms_)),
|
||||
uniformBlocks(std::move(uniformBlocks_)),
|
||||
vertexAttributes(std::move(attributes_)) {}
|
||||
|
||||
ShaderProgramGL::ShaderProgramGL(ShaderProgramGL&& other)
|
||||
: ShaderProgramBase(std::forward<ShaderProgramBase&&>(other)),
|
||||
glProgram(std::move(other.glProgram)),
|
||||
uniforms(std::move(other.uniforms)),
|
||||
uniformBlocks(std::move(other.uniformBlocks)),
|
||||
vertexAttributes(std::move(other.vertexAttributes)) {}
|
||||
|
||||
using namespace platform;
|
||||
@@ -102,8 +102,8 @@ static void addAttr(
|
||||
const auto elementType = mapType(glType);
|
||||
const auto elementCount = mapCount(glType); // number of `elementType`, hopefully temporary
|
||||
if (elementType != gfx::AttributeDataType::Invalid && length > 0) {
|
||||
if (auto newAttr = attrs.add(name, index, elementType, elementCount, count)) {
|
||||
auto* glAttr = static_cast<VertexAttributeGL*>(newAttr);
|
||||
if (const auto& newAttr = attrs.add(name, index, elementType, elementCount, count)) {
|
||||
const auto& glAttr = static_cast<VertexAttributeGL*>(newAttr.get());
|
||||
glAttr->setGLType(glType);
|
||||
}
|
||||
}
|
||||
@@ -125,21 +125,23 @@ std::shared_ptr<ShaderProgramGL> ShaderProgramGL::create(Context& context,
|
||||
// GLint numAttribs;
|
||||
// glGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, &numAttribs);
|
||||
|
||||
VertexAttributeArrayGL uniforms;
|
||||
UniformBlockArrayGL uniformBlocks;
|
||||
|
||||
GLint count = 0;
|
||||
GLint maxLength = 0;
|
||||
MBGL_CHECK_ERROR(glGetProgramiv(program, GL_ACTIVE_UNIFORMS, &count));
|
||||
MBGL_CHECK_ERROR(glGetProgramiv(program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxLength));
|
||||
MBGL_CHECK_ERROR(glGetProgramiv(program, GL_ACTIVE_UNIFORM_BLOCKS, &count));
|
||||
MBGL_CHECK_ERROR(glGetProgramiv(program, GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH, &maxLength));
|
||||
|
||||
auto name = std::vector<GLchar>(maxLength);
|
||||
for (GLint index = 0; index < count; ++index) {
|
||||
GLsizei length = 0;
|
||||
GLint size = 0;
|
||||
GLenum glType = 0;
|
||||
MBGL_CHECK_ERROR(glGetActiveUniform(program, index, maxLength, &length, &size, &glType, name.data()));
|
||||
const GLint location = MBGL_CHECK_ERROR(glGetUniformLocation(program, name.data()));
|
||||
addAttr(uniforms, name.data(), location, length, size, glType);
|
||||
GLint binding = index;
|
||||
MBGL_CHECK_ERROR(glGetActiveUniformBlockName(program, index, maxLength, &length, name.data()));
|
||||
MBGL_CHECK_ERROR(glGetActiveUniformBlockiv(program, index, GL_UNIFORM_BLOCK_DATA_SIZE, &size));
|
||||
assert(length > 0 && size > 0);
|
||||
MBGL_CHECK_ERROR(glUniformBlockBinding(program, index, binding));
|
||||
uniformBlocks.add(name.data(), index, size);
|
||||
}
|
||||
|
||||
VertexAttributeArrayGL attrs;
|
||||
@@ -160,7 +162,7 @@ std::shared_ptr<ShaderProgramGL> ShaderProgramGL::create(Context& context,
|
||||
addAttr(attrs, name.data(), location, length, size, glType);
|
||||
}
|
||||
|
||||
return std::make_shared<ShaderProgramGL>(std::move(program), std::move(uniforms), std::move(attrs));
|
||||
return std::make_shared<ShaderProgramGL>(std::move(program), std::move(uniformBlocks), std::move(attrs));
|
||||
}
|
||||
|
||||
} // namespace gl
|
||||
|
||||
Reference in New Issue
Block a user