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
@@ -149,6 +149,8 @@ list(APPEND INCLUDE_FILES
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/gfx/rendering_stats.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/gfx/shader_registry.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/gfx/shader.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/gfx/uniform_block.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/gfx/uniform_buffer.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/gfx/vertex_attribute.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/layermanager/background_layer_factory.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/layermanager/circle_layer_factory.hpp
|
||||
@@ -391,6 +393,8 @@ list(APPEND SRC_FILES
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gfx/texture.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gfx/types.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gfx/uniform.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gfx/uniform_block.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gfx/uniform_buffer.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gfx/upload_pass.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gfx/vertex_attribute.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gfx/vertex_buffer.hpp
|
||||
@@ -910,6 +914,8 @@ if(MLN_WITH_OPENGL)
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/gl/drawable_gl_tweaker.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/gl/renderable_resource.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/gl/renderer_backend.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/gl/uniform_block_gl.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/gl/uniform_buffer_gl.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/gl/vertex_attribute_gl.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/layermanager/location_indicator_layer_factory.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/platform/gl_functions.hpp
|
||||
@@ -919,6 +925,7 @@ if(MLN_WITH_OPENGL)
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/shader_manifest.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/gl/prelude.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/gl/background.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/gl/background_ubo.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/gl/background_pattern.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/gl/circle.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/gl/clipping_mask.hpp
|
||||
@@ -990,6 +997,8 @@ if(MLN_WITH_OPENGL)
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gl/types.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gl/uniform.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gl/uniform.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gl/uniform_block_gl.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gl/uniform_buffer_gl.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gl/upload_pass.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gl/upload_pass.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gl/value.cpp
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/gfx/uniform_buffer.hpp>
|
||||
#include <mbgl/gfx/vertex_attribute.hpp>
|
||||
#include <mbgl/tile/tile_id.hpp>
|
||||
#include <mbgl/util/identity.hpp>
|
||||
@@ -22,7 +23,7 @@ enum class DepthMaskType : bool;
|
||||
class DrawableTweaker;
|
||||
class ShaderProgramBase;
|
||||
using ShaderProgramBasePtr = std::shared_ptr<ShaderProgramBase>;
|
||||
|
||||
using UniformBufferPtr = std::shared_ptr<UniformBuffer>;
|
||||
using DrawPriority = int64_t;
|
||||
using DrawableTweakerPtr = std::shared_ptr<DrawableTweaker>;
|
||||
|
||||
@@ -94,6 +95,10 @@ public:
|
||||
/// Get the tweakers attached to this drawable
|
||||
const std::vector<DrawableTweakerPtr>& getTweakers() const { return tweakers; }
|
||||
|
||||
/// Get the uniform buffers attached to this drawable
|
||||
virtual const gfx::UniformBufferArray& getUniformBuffers() const = 0;
|
||||
virtual gfx::UniformBufferArray& mutableUniformBuffers() = 0;
|
||||
|
||||
// Reset a single color attribute for all vertexes
|
||||
virtual void resetColor(const Color&) = 0;
|
||||
|
||||
@@ -137,5 +142,9 @@ private:
|
||||
bool desc;
|
||||
};
|
||||
|
||||
struct alignas(16) DrawableUBO {
|
||||
std::array<float, 4 * 4> matrix;
|
||||
};
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace mbgl
|
||||
|
||||
94
include/mbgl/gfx/uniform_block.hpp
Normal file
94
include/mbgl/gfx/uniform_block.hpp
Normal file
@@ -0,0 +1,94 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace mbgl {
|
||||
namespace gfx {
|
||||
|
||||
class UniformBuffer;
|
||||
|
||||
class UniformBlock {
|
||||
// Can only be created by UniformBlockArray implementations
|
||||
protected:
|
||||
UniformBlock(int index_, std::size_t size_)
|
||||
: index(index_),
|
||||
size(size_) {}
|
||||
UniformBlock(const UniformBlock&) = default;
|
||||
UniformBlock(UniformBlock&& other)
|
||||
: index(other.index),
|
||||
size(other.size) {}
|
||||
|
||||
public:
|
||||
virtual ~UniformBlock() = default;
|
||||
|
||||
int getIndex() const { return index; }
|
||||
|
||||
std::size_t getSize() const { return size; }
|
||||
|
||||
virtual void bindBuffer(const UniformBuffer& uniformBuffer) = 0;
|
||||
virtual void unbindBuffer() = 0;
|
||||
|
||||
protected:
|
||||
UniformBlock& operator=(const UniformBlock&) = default;
|
||||
UniformBlock& operator=(UniformBlock&& other) {
|
||||
index = other.index;
|
||||
size = other.size;
|
||||
return *this;
|
||||
}
|
||||
|
||||
protected:
|
||||
int index;
|
||||
std::size_t size;
|
||||
};
|
||||
|
||||
/// Stores a collection of uniform blocks by name
|
||||
class UniformBlockArray {
|
||||
public:
|
||||
using UniformBlockMap = std::unordered_map<std::string, std::unique_ptr<UniformBlock>>;
|
||||
|
||||
UniformBlockArray(int initCapacity = 10);
|
||||
UniformBlockArray(UniformBlockArray&&);
|
||||
// Would need to use the virtual assignment operator
|
||||
UniformBlockArray(const UniformBlockArray&) = delete;
|
||||
virtual ~UniformBlockArray() = default;
|
||||
|
||||
/// Get map of elements.
|
||||
const UniformBlockMap& getMap() const { return uniformBlockMap; }
|
||||
|
||||
/// Number of elements
|
||||
std::size_t size() const { return uniformBlockMap.size(); }
|
||||
|
||||
/// Get an uniform block element.
|
||||
/// Returns a pointer to the element on success, or null if the uniform block doesn't exists.
|
||||
const std::unique_ptr<UniformBlock>& get(const std::string& name) const;
|
||||
|
||||
/// Add a new uniform block element.
|
||||
/// Returns a pointer to the new element on success, or null if the uniform block already exists.
|
||||
const std::unique_ptr<UniformBlock>& add(std::string name, int index, std::size_t size);
|
||||
|
||||
UniformBlockArray& operator=(UniformBlockArray&&);
|
||||
UniformBlockArray& operator=(const UniformBlockArray&);
|
||||
|
||||
protected:
|
||||
const std::unique_ptr<UniformBlock>& add(std::string name, std::unique_ptr<UniformBlock>&& uniformBlock) {
|
||||
const auto result = uniformBlockMap.insert(std::make_pair(std::move(name), std::unique_ptr<UniformBlock>()));
|
||||
if (result.second) {
|
||||
result.first->second = std::move(uniformBlock);
|
||||
return result.first->second;
|
||||
} else {
|
||||
return nullref;
|
||||
}
|
||||
}
|
||||
|
||||
virtual std::unique_ptr<UniformBlock> create(int index, std::size_t size) = 0;
|
||||
virtual std::unique_ptr<UniformBlock> copy(const UniformBlock& uniformBlock) = 0;
|
||||
|
||||
protected:
|
||||
UniformBlockMap uniformBlockMap;
|
||||
static std::unique_ptr<UniformBlock> nullref;
|
||||
};
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace mbgl
|
||||
79
include/mbgl/gfx/uniform_buffer.hpp
Normal file
79
include/mbgl/gfx/uniform_buffer.hpp
Normal file
@@ -0,0 +1,79 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace mbgl {
|
||||
namespace gfx {
|
||||
|
||||
class UniformBuffer {
|
||||
// Can only be created by platform specific implementations
|
||||
protected:
|
||||
UniformBuffer(std::size_t size_)
|
||||
: size(size_) {}
|
||||
UniformBuffer(const UniformBuffer&) = default;
|
||||
UniformBuffer(UniformBuffer&& other)
|
||||
: size(other.size) {}
|
||||
|
||||
public:
|
||||
virtual ~UniformBuffer() = default;
|
||||
|
||||
std::size_t getSize() const { return size; }
|
||||
|
||||
protected:
|
||||
UniformBuffer& operator=(const UniformBuffer&) = default;
|
||||
UniformBuffer& operator=(UniformBuffer&& other) {
|
||||
size = other.size;
|
||||
return *this;
|
||||
}
|
||||
|
||||
protected:
|
||||
std::size_t size;
|
||||
};
|
||||
|
||||
/// Stores a collection of uniform buffers by name
|
||||
class UniformBufferArray {
|
||||
public:
|
||||
using UniformBufferMap = std::unordered_map<std::string, std::shared_ptr<UniformBuffer>>;
|
||||
|
||||
UniformBufferArray(int initCapacity = 10);
|
||||
UniformBufferArray(UniformBufferArray&&);
|
||||
// Would need to use the virtual assignment operator
|
||||
UniformBufferArray(const UniformBufferArray&) = delete;
|
||||
virtual ~UniformBufferArray() = default;
|
||||
|
||||
/// Number of elements
|
||||
std::size_t size() const { return uniformBufferMap.size(); }
|
||||
|
||||
/// 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;
|
||||
|
||||
/// Add a new uniform buffer element or replace the existing one.
|
||||
const std::shared_ptr<UniformBuffer>& addOrReplace(std::string name,
|
||||
const std::shared_ptr<UniformBuffer>& uniformBuffer);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
virtual std::unique_ptr<UniformBuffer> copy(const UniformBuffer& uniformBuffer) = 0;
|
||||
|
||||
protected:
|
||||
UniformBufferMap uniformBufferMap;
|
||||
static std::shared_ptr<UniformBuffer> nullref;
|
||||
};
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace mbgl
|
||||
@@ -147,30 +147,30 @@ public:
|
||||
/// Add a new attribute element.
|
||||
/// Returns a pointer to the new element on success, or null if the attribute already exists.
|
||||
/// The result is valid only until the next non-const method call on this class.
|
||||
VertexAttribute* get(const std::string& name) const;
|
||||
const std::unique_ptr<VertexAttribute>& get(const std::string& name) const;
|
||||
|
||||
/// Add a new attribute element.
|
||||
/// Returns a pointer to the new element on success, or null if the attribute already exists.
|
||||
/// The result is valid only until the next non-const method call on this class.
|
||||
VertexAttribute* add(std::string name,
|
||||
int index = -1,
|
||||
AttributeDataType = AttributeDataType::Invalid,
|
||||
int size = 1,
|
||||
std::size_t count = 1);
|
||||
const std::unique_ptr<VertexAttribute>& add(std::string name,
|
||||
int index = -1,
|
||||
AttributeDataType = AttributeDataType::Invalid,
|
||||
int size = 1,
|
||||
std::size_t count = 1);
|
||||
|
||||
/// Add a new attribute element if it doesn't already exist.
|
||||
/// Returns a pointer to the new element on success, or null if the type or count conflict with an existing entry.
|
||||
/// The result is valid only until the next non-const method call on this class.
|
||||
VertexAttribute* getOrAdd(std::string name,
|
||||
int index = -1,
|
||||
AttributeDataType = AttributeDataType::Invalid,
|
||||
int size = 1,
|
||||
std::size_t count = 1);
|
||||
const std::unique_ptr<VertexAttribute>& getOrAdd(std::string name,
|
||||
int index = -1,
|
||||
AttributeDataType = AttributeDataType::Invalid,
|
||||
int size = 1,
|
||||
std::size_t count = 1);
|
||||
|
||||
// Set a value if the element is present
|
||||
template <typename T>
|
||||
bool set(const std::string& name, std::size_t i, T value) {
|
||||
if (auto* item = get(name)) {
|
||||
if (const auto& item = get(name)) {
|
||||
return item->set(i, value);
|
||||
}
|
||||
return false;
|
||||
@@ -182,24 +182,22 @@ public:
|
||||
attrs.begin(), attrs.end(), [](const auto& kv) { return kv.second && kv.second->isDirty(); });
|
||||
}
|
||||
|
||||
using ResolveDelegate = std::function<void(const std::string&, const VertexAttribute&, const VertexAttribute*)>;
|
||||
using ResolveDelegate =
|
||||
std::function<void(const std::string&, const VertexAttribute&, const std::unique_ptr<VertexAttribute>&)>;
|
||||
/// Call the provided delegate with each value, providing the override if one exists.
|
||||
void resolve(const VertexAttributeArray& overrides, ResolveDelegate) const;
|
||||
|
||||
/// Apply to the active program
|
||||
virtual void applyUniforms(const ShaderProgramBase&) = 0;
|
||||
|
||||
VertexAttributeArray& operator=(VertexAttributeArray&&);
|
||||
VertexAttributeArray& operator=(const VertexAttributeArray&);
|
||||
|
||||
protected:
|
||||
VertexAttribute* add(std::string name, std::unique_ptr<VertexAttribute>&& attr) {
|
||||
const std::unique_ptr<VertexAttribute>& add(std::string name, std::unique_ptr<VertexAttribute>&& attr) {
|
||||
const auto result = attrs.insert(std::make_pair(std::move(name), std::unique_ptr<VertexAttribute>()));
|
||||
if (result.second) {
|
||||
result.first->second = std::move(attr);
|
||||
return result.first->second.get();
|
||||
return result.first->second;
|
||||
} else {
|
||||
return nullptr;
|
||||
return nullref;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -211,6 +209,7 @@ protected:
|
||||
|
||||
protected:
|
||||
AttributeMap attrs;
|
||||
static std::unique_ptr<VertexAttribute> nullref;
|
||||
};
|
||||
|
||||
} // namespace gfx
|
||||
|
||||
@@ -42,6 +42,9 @@ public:
|
||||
const gfx::UniqueVertexBufferResource& getBuffer() const;
|
||||
const gfx::IndexBuffer& getIndexBuffer() const;
|
||||
|
||||
const gfx::UniformBufferArray& getUniformBuffers() const override;
|
||||
gfx::UniformBufferArray& mutableUniformBuffers() override;
|
||||
|
||||
/// Reset a single color attribute for all vertexes
|
||||
void resetColor(const Color&) override;
|
||||
|
||||
@@ -61,6 +64,8 @@ protected:
|
||||
DrawableGL(std::unique_ptr<Impl>);
|
||||
|
||||
private:
|
||||
void bindUniformBuffers() const;
|
||||
void unbindUniformBuffers() const;
|
||||
};
|
||||
|
||||
} // namespace gl
|
||||
|
||||
57
include/mbgl/gl/uniform_block_gl.hpp
Normal file
57
include/mbgl/gl/uniform_block_gl.hpp
Normal file
@@ -0,0 +1,57 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/gfx/uniform_block.hpp>
|
||||
#include <mbgl/gfx/uniform_buffer.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace gl {
|
||||
|
||||
class UniformBlockArrayGL;
|
||||
|
||||
class UniformBlockGL final : public gfx::UniformBlock {
|
||||
// Can only be created by UniformBlockArrayGL
|
||||
private:
|
||||
friend UniformBlockArrayGL;
|
||||
|
||||
UniformBlockGL(int index_, std::size_t size_)
|
||||
: UniformBlock(index_, size_) {}
|
||||
UniformBlockGL(const UniformBlockGL& other)
|
||||
: UniformBlock(other) {}
|
||||
UniformBlockGL(UniformBlockGL&& other)
|
||||
: UniformBlock(std::move(other)) {}
|
||||
|
||||
public:
|
||||
void bindBuffer(const gfx::UniformBuffer& uniformBuffer) override;
|
||||
void unbindBuffer() override;
|
||||
};
|
||||
|
||||
/// Stores a collection of uniform blocks by name
|
||||
class UniformBlockArrayGL final : public gfx::UniformBlockArray {
|
||||
public:
|
||||
UniformBlockArrayGL(int initCapacity = 10)
|
||||
: UniformBlockArray(initCapacity) {}
|
||||
UniformBlockArrayGL(UniformBlockArrayGL&& other)
|
||||
: UniformBlockArray(std::move(other)) {}
|
||||
UniformBlockArrayGL(const UniformBlockArrayGL&) = delete;
|
||||
|
||||
UniformBlockArrayGL& operator=(UniformBlockArrayGL&& other) {
|
||||
UniformBlockArray::operator=(std::move(other));
|
||||
return *this;
|
||||
}
|
||||
UniformBlockArrayGL& operator=(const UniformBlockArrayGL& other) {
|
||||
UniformBlockArray::operator=(other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
std::unique_ptr<gfx::UniformBlock> create(int index, std::size_t size) override {
|
||||
return std::unique_ptr<gfx::UniformBlock>(new UniformBlockGL(index, size));
|
||||
}
|
||||
std::unique_ptr<gfx::UniformBlock> copy(const gfx::UniformBlock& uniformBlocks) override {
|
||||
return std::unique_ptr<gfx::UniformBlock>(
|
||||
new UniformBlockGL(static_cast<const UniformBlockGL&>(uniformBlocks)));
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace gl
|
||||
} // namespace mbgl
|
||||
49
include/mbgl/gl/uniform_buffer_gl.hpp
Normal file
49
include/mbgl/gl/uniform_buffer_gl.hpp
Normal file
@@ -0,0 +1,49 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/gfx/uniform_buffer.hpp>
|
||||
#include <mbgl/gl/types.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace gl {
|
||||
|
||||
class UniformBufferGL final : public gfx::UniformBuffer {
|
||||
public:
|
||||
UniformBufferGL(const void* data, std::size_t size_);
|
||||
UniformBufferGL(const UniformBufferGL& other)
|
||||
: UniformBuffer(other) {}
|
||||
UniformBufferGL(UniformBufferGL&& other)
|
||||
: UniformBuffer(std::move(other)) {}
|
||||
|
||||
BufferID getID() const { return id; }
|
||||
|
||||
protected:
|
||||
BufferID id = 0;
|
||||
};
|
||||
|
||||
/// Stores a collection of uniform buffers by name
|
||||
class UniformBufferArrayGL final : public gfx::UniformBufferArray {
|
||||
public:
|
||||
UniformBufferArrayGL(int initCapacity = 10)
|
||||
: UniformBufferArray(initCapacity) {}
|
||||
UniformBufferArrayGL(UniformBufferArrayGL&& other)
|
||||
: UniformBufferArray(std::move(other)) {}
|
||||
UniformBufferArrayGL(const UniformBufferArrayGL&) = delete;
|
||||
|
||||
UniformBufferArrayGL& operator=(UniformBufferArrayGL&& other) {
|
||||
UniformBufferArray::operator=(std::move(other));
|
||||
return *this;
|
||||
}
|
||||
UniformBufferArrayGL& operator=(const UniformBufferArrayGL& other) {
|
||||
UniformBufferArray::operator=(other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
std::unique_ptr<gfx::UniformBuffer> copy(const gfx::UniformBuffer& uniformBuffers) override {
|
||||
return std::unique_ptr<gfx::UniformBuffer>(
|
||||
new UniformBufferGL(static_cast<const UniformBufferGL&>(uniformBuffers)));
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace gl
|
||||
} // namespace mbgl
|
||||
@@ -62,8 +62,6 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
void applyUniforms(const gfx::ShaderProgramBase&) override;
|
||||
|
||||
private:
|
||||
std::unique_ptr<gfx::VertexAttribute> create(int index,
|
||||
gfx::AttributeDataType dataType,
|
||||
|
||||
43
include/mbgl/shaders/gl/background_ubo.hpp
Normal file
43
include/mbgl/shaders/gl/background_ubo.hpp
Normal file
@@ -0,0 +1,43 @@
|
||||
#pragma once
|
||||
#include <mbgl/shaders/shader_source.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace shaders {
|
||||
|
||||
template <>
|
||||
struct ShaderSource<BuiltIn::BackgroundProgramUBO, gfx::Backend::Type::OpenGL> {
|
||||
static constexpr const char* vertex = R"(#version 300 es
|
||||
precision highp float;
|
||||
|
||||
layout (location = 0) in vec2 a_pos;
|
||||
|
||||
layout (std140) uniform DrawableUBO {
|
||||
mat4 u_matrix;
|
||||
};
|
||||
|
||||
void main() {
|
||||
gl_Position = u_matrix * vec4(a_pos, 0, 1);
|
||||
}
|
||||
)";
|
||||
static constexpr const char* fragment = R"(#version 300 es
|
||||
precision highp float;
|
||||
|
||||
layout (std140) uniform BackgroundLayerUBO {
|
||||
vec4 u_color;
|
||||
float u_opacity;
|
||||
};
|
||||
|
||||
out vec4 fragColor;
|
||||
|
||||
void main() {
|
||||
fragColor = u_color * u_opacity;
|
||||
|
||||
#ifdef OVERDRAW_INSPECTOR
|
||||
fragColor = vec4(1.0);
|
||||
#endif
|
||||
}
|
||||
)";
|
||||
};
|
||||
|
||||
} // namespace shaders
|
||||
} // namespace mbgl
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/gl/context.hpp>
|
||||
#include <mbgl/gl/uniform_block_gl.hpp>
|
||||
#include <mbgl/gl/vertex_attribute_gl.hpp>
|
||||
#include <mbgl/shaders/shader_program_base.hpp>
|
||||
|
||||
@@ -10,7 +11,7 @@ namespace gl {
|
||||
class ShaderProgramGL final : public gfx::ShaderProgramBase {
|
||||
public:
|
||||
ShaderProgramGL(UniqueProgram&& glProgram_);
|
||||
ShaderProgramGL(UniqueProgram&&, VertexAttributeArrayGL&& uniforms, VertexAttributeArrayGL&& attributes);
|
||||
ShaderProgramGL(UniqueProgram&&, UniformBlockArrayGL&& uniformBlocks, VertexAttributeArrayGL&& attributes);
|
||||
ShaderProgramGL(ShaderProgramGL&& other);
|
||||
~ShaderProgramGL() noexcept override = default;
|
||||
|
||||
@@ -22,21 +23,21 @@ public:
|
||||
std::string_view vertexSource,
|
||||
std::string_view fragmentSource) noexcept(false);
|
||||
|
||||
const gfx::VertexAttributeArray& getUniforms() const override { return uniforms; }
|
||||
const gfx::UniformBlockArray& getUniformBlocks() const override { return uniformBlocks; }
|
||||
|
||||
const gfx::VertexAttributeArray& getVertexAttributes() const override { return vertexAttributes; }
|
||||
|
||||
ProgramID getGLProgramID() const { return glProgram; }
|
||||
|
||||
protected:
|
||||
gfx::VertexAttributeArray& mutableUniforms() override { return uniforms; }
|
||||
gfx::UniformBlockArray& mutableUniformBlocks() override { return uniformBlocks; }
|
||||
|
||||
gfx::VertexAttributeArray& mutableVertexAttributes() override { return vertexAttributes; }
|
||||
|
||||
protected:
|
||||
UniqueProgram glProgram;
|
||||
|
||||
VertexAttributeArrayGL uniforms;
|
||||
UniformBlockArrayGL uniformBlocks;
|
||||
VertexAttributeArrayGL vertexAttributes;
|
||||
};
|
||||
|
||||
|
||||
@@ -32,4 +32,6 @@
|
||||
#include <mbgl/shaders/gl/symbol_sdf_text.hpp>
|
||||
#include <mbgl/shaders/gl/symbol_sdf_icon.hpp>
|
||||
#include <mbgl/shaders/gl/symbol_text_and_icon.hpp>
|
||||
|
||||
#include <mbgl/shaders/gl/background_ubo.hpp>
|
||||
#endif
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/gfx/shader.hpp>
|
||||
#include <mbgl/gfx/uniform_block.hpp>
|
||||
#include <mbgl/gfx/vertex_attribute.hpp>
|
||||
#include <mbgl/util/identity.hpp>
|
||||
|
||||
@@ -17,7 +18,7 @@ protected:
|
||||
|
||||
template <typename T>
|
||||
bool set(gfx::VertexAttributeArray& attrs, const std::string& name, std::size_t i, T value) {
|
||||
auto* item = attrs.get(name);
|
||||
const auto& item = attrs.get(name);
|
||||
if (item && i < item->getCount()) {
|
||||
item->set(i, value);
|
||||
return true;
|
||||
@@ -28,26 +29,19 @@ protected:
|
||||
public:
|
||||
const util::SimpleIdentity& getID() const { return shaderProgramID; }
|
||||
|
||||
/// Get the available vertex attributes and their default values
|
||||
virtual const gfx::VertexAttributeArray& getUniforms() const = 0;
|
||||
/// Get the available uniform blocks attached to this shader
|
||||
virtual const gfx::UniformBlockArray& getUniformBlocks() const = 0;
|
||||
|
||||
/// Get the available vertex attributes and their default values
|
||||
virtual const gfx::VertexAttributeArray& getVertexAttributes() const = 0;
|
||||
|
||||
// Set a value if the element is present
|
||||
template <typename T>
|
||||
bool setUniform(const std::string& name, std::size_t i, T value) {
|
||||
return set(mutableUniforms(), name, i, value);
|
||||
}
|
||||
template <typename T>
|
||||
bool setAttribute(const std::string& name, std::size_t i, T value) {
|
||||
return set(mutableVertexAttributes(), name, i, value);
|
||||
}
|
||||
|
||||
void updateUniforms() { mutableUniforms().applyUniforms(*this); }
|
||||
|
||||
protected:
|
||||
virtual gfx::VertexAttributeArray& mutableUniforms() = 0;
|
||||
virtual gfx::UniformBlockArray& mutableUniformBlocks() = 0;
|
||||
virtual gfx::VertexAttributeArray& mutableVertexAttributes() = 0;
|
||||
|
||||
protected:
|
||||
|
||||
@@ -37,7 +37,9 @@ enum class BuiltIn {
|
||||
SymbolIconProgram,
|
||||
SymbolSDFTextProgram,
|
||||
SymbolSDFIconProgram,
|
||||
SymbolTextAndIconProgram
|
||||
SymbolTextAndIconProgram,
|
||||
|
||||
BackgroundProgramUBO
|
||||
};
|
||||
|
||||
/// @brief Select shader source based on a program type and a desired
|
||||
|
||||
@@ -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