Drawable Renderer (#1570), Fix duplicate drawable and vertex state bug

This commit is contained in:
Tim Sylvester
2023-04-25 14:43:23 -07:00
committed by Bart Louwers
parent 5a9b4c3422
commit 107a4ef467
15 changed files with 71 additions and 30 deletions

View File

@@ -38,7 +38,7 @@ public:
const std::vector<DrawablePtr>& getDrawables() const { return drawables; }
/// Get all the completed drawables and release ownership
std::vector<DrawablePtr> clearDrawables() const { return std::move(drawables); }
std::vector<DrawablePtr> clearDrawables() { auto v = std::move(drawables); return v; }
/// Get the ID of the drawable we're currently working on, if any
util::SimpleIdentity getDrawableId();

View File

@@ -21,8 +21,8 @@ inline constexpr bool is_shader_v = std::is_base_of_v<gfx::Shader, T> &&
/// @brief A shader is used as the base class for all programs across any supported
/// backend API. Shaders are registered with a `gfx::ShaderRegistry` instance.
class Shader {
public:
virtual ~Shader() = default;
public:
virtual ~Shader() noexcept = default;
/// @brief Get the type name of this shader
/// @return Shader type name

View File

@@ -23,7 +23,7 @@ class VertexArray;
class DrawableGL : public gfx::Drawable {
public:
DrawableGL();
virtual ~DrawableGL();
~DrawableGL() override;
void draw(const PaintParameters &) const override;
@@ -41,6 +41,9 @@ public:
const gl::VertexArray& getVertexArray() const;
void setVertexArray(gl::VertexArray&&, gfx::UniqueVertexBufferResource&&, gfx::IndexBuffer&&);
const gfx::UniqueVertexBufferResource& getBuffer() const;
const gfx::IndexBuffer& getIndexBuffer() const;
protected:
class Impl;
const std::unique_ptr<Impl> impl;

View File

@@ -14,6 +14,7 @@ public:
VertexAttributeArrayGL&& uniforms,
VertexAttributeArrayGL&& attributes);
ShaderProgramGL(ShaderProgramGL&& other);
~ShaderProgramGL() noexcept override = default;
static constexpr std::string_view Name{"GenericGLShader"};
const std::string_view typeName() const noexcept override { return Name; }

View File

@@ -13,6 +13,7 @@ class ShaderProgramBase : public gfx::Shader {
protected:
ShaderProgramBase() { }
ShaderProgramBase(ShaderProgramBase&&) { }
~ShaderProgramBase() noexcept override = default;
template <typename T>
bool set(gfx::VertexAttributeArray& attrs, const std::string& name, std::size_t i, T value) {

View File

@@ -1,5 +1,7 @@
#pragma once
#include <mbgl/util/string.hpp>
#include <cstdint>
namespace mbgl {
@@ -22,8 +24,11 @@ public:
bool operator==(const SimpleIdentity& other) const { return uniqueID == other.uniqueID; }
bool operator!=(const SimpleIdentity& other) const { return uniqueID != other.uniqueID; }
operator bool() const { return uniqueID != emptyID; }
bool operator!() const { return uniqueID == emptyID; }
std::int64_t id() const { return uniqueID; }
bool isEmpty() const { return uniqueID != emptyID; }
operator bool() const { return isEmpty(); }
bool operator!() const { return !isEmpty(); }
private:
static constexpr std::int64_t emptyID = 0;
@@ -46,6 +51,9 @@ protected:
util::SimpleIdentity uniqueID;
};
inline std::string toString(const util::SimpleIdentity& ident) {
return "{"+std::to_string(ident.id())+"}";
}
} // namespace util
} // namespace mbgl

View File

@@ -15,6 +15,8 @@
#include <mbgl/util/std.hpp>
#include <mbgl/util/logging.hpp>
#include <mbgl/gl/index_buffer_resource.hpp>
#include <cstring>
#include <iterator>
@@ -457,10 +459,10 @@ void Context::setupDraw(const gfx::Drawable& drawable) {
program = value::Program::Default;
}
// setDepthMode(depthMode);
// setStencilMode(stencilMode);
// setColorMode(colorMode);
// setCullFaceMode(cullFaceMode);
//setDepthMode(...);
setStencilMode(gfx::StencilMode::disabled());
setColorMode(gfx::ColorMode::alphaBlended());
setCullFaceMode(gfx::CullFaceMode::disabled());
// uniformStates.bind(uniformValues);
// textureStates.bind(context, textureBindings);
@@ -469,6 +471,9 @@ void Context::setupDraw(const gfx::Drawable& drawable) {
auto& vao = drawableGL.getVertexArray();
if (vao.isValid()) {
bindVertexArray = vao.getID(); // glBindVertexArray
//vertexBuffer = static_cast<gl::VertexBufferResource&>(*drawableGL.getBuffer()).buffer.get();
//globalVertexArrayState.indexBuffer =
// drawableGL.getIndexBuffer().getResource<gl::IndexBufferResource>().buffer;
} else {
bindVertexArray = value::BindVertexArray::Default;
}

View File

@@ -1,5 +1,6 @@
#include <mbgl/gl/drawable_gl.hpp>
#include <mbgl/gl/drawable_gl_impl.hpp>
#include <mbgl/gl/vertex_buffer_resource.hpp>
namespace mbgl {
namespace gl {
@@ -9,6 +10,9 @@ DrawableGL::DrawableGL()
}
DrawableGL::~DrawableGL() {
impl->vertexArray = { { nullptr, false } };
impl->indexBuffer = { 0, nullptr };
impl->attributeBuffer.reset();
}
void DrawableGL::draw(const PaintParameters &parameters) const
@@ -32,6 +36,14 @@ const gl::VertexArray& DrawableGL::getVertexArray() const {
return impl->vertexArray;
}
const gfx::IndexBuffer& DrawableGL::getIndexBuffer() const {
return impl->indexBuffer;
}
const gfx::UniqueVertexBufferResource& DrawableGL::getBuffer() const {
return impl->attributeBuffer;
}
const gfx::VertexAttributeArray& DrawableGL::getVertexAttributes() const {
return impl->vertexAttributes;
}

View File

@@ -24,6 +24,9 @@ void DrawableGLBuilder::init() {
constexpr auto indexOffset = 0;
const auto indexCount = impl->indexes.elements();
drawableGL.setIndexData(impl->indexes.vector(), indexOffset, indexCount);
impl->indexes.clear();
impl->vertices.clear();
}
} // namespace gl

View File

@@ -78,7 +78,7 @@ void RendererBackend::initShaders(gfx::ShaderRegistry& shaders) {
constexpr auto vert = R"(#version 300 es
precision highp float;
in vec2 a_pos;
layout (location = 0) in vec2 a_pos;
uniform mat4 u_matrix;
void main() {

View File

@@ -5,6 +5,8 @@
#include <mbgl/shaders/gl/shader_program_gl.hpp>
#include <cstring>
#include <sstream>
#include <mbgl/util/logging.hpp>
namespace mbgl {
namespace gl {
@@ -158,14 +160,12 @@ void VertexAttributeArrayGL::applyUniforms(const gfx::ShaderProgramBase& shader)
const auto& name = kv.first;
auto& uniform = kv.second;
if (uniform->getDirty()) {
if (uniform->getIndex() < 0) {
const auto index = MBGL_CHECK_ERROR(glGetUniformLocation(program, name.c_str()));
uniform->setIndex(index);
}
std::visit(ApplyUniform { uniform->getIndex() }, uniform->get(0));
uniform->clearDirty();
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));
}
}

View File

@@ -759,8 +759,10 @@ void RenderOrchestrator::addChanges(UniqueChangeRequestVec& changes) {
void RenderOrchestrator::addDrawable(gfx::DrawablePtr drawable) {
if (drawable) {
const auto id = drawable->getId();
drawables.insert(std::make_pair(id, std::move(drawable)));
const auto& id = drawable->getId();
if (!drawables.insert(std::make_pair(id, std::move(drawable))).second) {
Log::Warning(Event::General, "Duplicate drawable " + std::to_string(id) + " ignored");
}
}
}

View File

@@ -124,7 +124,7 @@ void Renderer::Impl::render(const RenderTree& renderTree) {
auto indexBuffer = gfx::IndexBuffer {
indexData.size(),
uploadPass->createIndexBufferResource(
&indexData[0],
indexData.data(),
indexData.size() * sizeof(indexData[0]),
usage)
};
@@ -242,9 +242,10 @@ void Renderer::Impl::render(const RenderTree& renderTree) {
mat4 matrix = drawable.getMatrix();
if (drawable.getTileID()) {
const UnwrappedTileID tileID = {0,0,0};//drawable.getTileID()->toUnwrapped();
const UnwrappedTileID tileID = drawable.getTileID()->toUnwrapped();
const auto tileMat = parameters.matrixForTile(tileID);
matrix::multiply(matrix, drawable.getMatrix(), tileMat);
matrix = tileMat;
}
if (auto& shader = drawable.getShader()) {
@@ -253,6 +254,11 @@ void Renderer::Impl::render(const RenderTree& renderTree) {
}
drawable.draw(parameters);
//static_cast<gl::Context&>(context).program = 0;
//static_cast<gl::Context&>(context).bindVertexArray = 0;
//static_cast<gl::Context&>(context).vertexBuffer = 0;
//static_cast<gl::Context&>(context).globalVertexArrayState.indexBuffer = 0;
}
}

View File

@@ -126,9 +126,9 @@ std::shared_ptr<ShaderProgramGL> ShaderProgramGL::create(
GLsizei length = 0;
GLint size = 0;
GLenum glType = 0;
MBGL_CHECK_ERROR(glGetActiveUniform(program, index, maxLength, &length, &size, &glType, &name[0]));
const GLint location = MBGL_CHECK_ERROR(glGetUniformLocation(program, &name[0]));
addAttr(uniforms, &name[0], location, length, size, glType);
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);
}
VertexAttributeArrayGL attrs;
@@ -141,12 +141,12 @@ std::shared_ptr<ShaderProgramGL> ShaderProgramGL::create(
GLsizei length = 0; // "number of characters actually written in name (excluding the null terminator)"
GLint size = 0; // "size of the attribute variable, in units of the type returned in type"
GLenum glType = 0;
MBGL_CHECK_ERROR(glGetActiveAttrib(program, index, maxLength, &length, &size, &glType, &name[0]));
if (!strncmp(&name[0], "gl_", 3)) { // Is there a better way to detect built-in attributes?
MBGL_CHECK_ERROR(glGetActiveAttrib(program, index, maxLength, &length, &size, &glType, name.data()));
if (!strncmp(name.data(), "gl_", 3)) { // Is there a better way to detect built-in attributes?
continue;
}
const GLint location = MBGL_CHECK_ERROR(glGetAttribLocation(program, &name[0]));
addAttr(attrs, &name[0], location, length, size, glType);
const GLint location = MBGL_CHECK_ERROR(glGetAttribLocation(program, name.data()));
addAttr(attrs, name.data(), location, length, size, glType);
}
return std::make_shared<ShaderProgramGL>(std::move(program), std::move(uniforms), std::move(attrs));

View File

@@ -58,7 +58,7 @@ void BackgroundLayer::Impl::layerRemoved(PaintParameters&, UniqueChangeRequestVe
void BackgroundLayer::Impl::update(PaintParameters& parameters, UniqueChangeRequestVec& changes) const {
std::unique_lock<std::mutex> guard(mutex);
auto builder = std::make_unique<gl::DrawableGLBuilder>(); // from GL-specific code via virtual method on ...Context?
std::unique_ptr<gfx::DrawableBuilder> builder = std::make_unique<gl::DrawableGLBuilder>(); // from GL-specific code via virtual method on ...Context?
builder->setShader(shader);
builder->addTweaker(std::make_shared<gl::DrawableGLTweaker>()); // generally shared across drawables