Topic/drawable 2 (#1029)

This commit is contained in:
Tim Sylvester
2023-04-17 15:34:47 -07:00
committed by Bart Louwers
parent 14b53e54ec
commit e2bc75289c
16 changed files with 190 additions and 109 deletions

View File

@@ -14,6 +14,8 @@ class PaintParameters;
namespace gfx {
class DrawableTweaker;
class ShaderProgramBase;
using ShaderProgramBasePtr = std::shared_ptr<ShaderProgramBase>;
using DrawPriority = int64_t;
using DrawableTweakerPtr = std::shared_ptr<DrawableTweaker>;
@@ -32,10 +34,8 @@ public:
virtual void draw(const PaintParameters &) const = 0;
/// Which shader to use when rendering this drawable
//util::SimpleIdentity getShaderID() const { return shaderID; }
//void setShaderID(util::SimpleIdentity value) { shaderID = value; }
const std::string& getShaderID() const { return shaderID; }
void setShaderID(std::string value) { shaderID = std::move(value); }
const gfx::ShaderProgramBasePtr& getShader() const { return shader; }
void setShader(gfx::ShaderProgramBasePtr value) { shader = std::move(value); }
/// DrawPriority determines the drawing order
DrawPriority getDrawPriority() const { return drawPriority; }
@@ -58,8 +58,7 @@ public:
protected:
util::SimpleIdentity uniqueID;
//util::SimpleIdentity shaderID = util::SimpleIdentity::Empty;
std::string shaderID;
gfx::ShaderProgramBasePtr shader;
DrawPriority drawPriority = 0;

View File

@@ -13,8 +13,10 @@ class Color;
namespace gfx {
class DrawableTweaker;
class ShaderProgramBase;
using DrawableTweakerPtr = std::shared_ptr<DrawableTweaker>;
using ShaderProgramBasePtr = std::shared_ptr<ShaderProgramBase>;
/**
Base class for drawable builders, which construct Drawables from primitives
@@ -54,10 +56,8 @@ public:
void setColor(const Color& value);
/// Which shader to use when rendering emitted drawables
//util::SimpleIdentity getShaderID() const { return shaderID; }
//void setShaderID(util::SimpleIdentity value) { shaderID = value; }
const std::string& getShaderID() const { return shaderID; }
void setShaderID(std::string value) { shaderID = std::move(value); }
const gfx::ShaderProgramBasePtr& getShader() const { return shader; }
void setShader(gfx::ShaderProgramBasePtr value) { shader = std::move(value); }
/// Get the vertex attributes that override default values in the shader program
virtual const gfx::VertexAttributeArray& getVertexAttributes() const = 0;
@@ -83,8 +83,7 @@ protected:
protected:
DrawPriority drawPriority = 0;
//util::SimpleIdentity shaderID = util::SimpleIdentity::Empty;
std::string shaderID;
gfx::ShaderProgramBasePtr shader;
DrawablePtr currentDrawable;
std::vector<DrawablePtr> drawables;

View File

@@ -8,9 +8,10 @@
namespace mbgl {
namespace gfx {
class BackendScope;
class Context;
class Renderable;
class BackendScope;
class ShaderRegistry;
// We can make some optimizations if we know that the drawing context is not shared with other code.
enum class ContextMode : bool {
@@ -40,6 +41,9 @@ public:
/// Returns a reference to the default surface that should be rendered on.
virtual Renderable& getDefaultRenderable() = 0;
/// One-time shader initialization
virtual void initShaders(gfx::ShaderRegistry&) = 0;
protected:
virtual std::unique_ptr<Context> createContext() = 0;

View File

@@ -19,6 +19,9 @@ public:
/// Called prior to rendering to update the internally assumed OpenGL state.
virtual void updateAssumedState() = 0;
/// One-time shader initialization
void initShaders(gfx::ShaderRegistry&) override;
protected:
std::unique_ptr<gfx::Context> createContext() override;

View File

@@ -45,8 +45,8 @@ private:
class VertexAttributeArrayGL final : public gfx::VertexAttributeArray {
public:
VertexAttributeArrayGL(int initCapacity = 10) : VertexAttributeArray(initCapacity) { }
VertexAttributeArrayGL(VertexAttributeArray &&other) : VertexAttributeArray(std::move(other)) { }
VertexAttributeArrayGL(const VertexAttributeArray& other) : VertexAttributeArray(other) { }
VertexAttributeArrayGL(VertexAttributeArrayGL &&other) : VertexAttributeArray(std::move(other)) { }
VertexAttributeArrayGL(const VertexAttributeArrayGL& other) : VertexAttributeArray(other) { }
~VertexAttributeArrayGL() = default;
VertexAttributeArrayGL& operator=(VertexAttributeArrayGL &&other) {

View File

@@ -10,6 +10,7 @@ namespace gl {
class ShaderProgramGL final : public gfx::ShaderProgramBase {
public:
ShaderProgramGL(UniqueProgram&& glProgram_);
ShaderProgramGL(UniqueProgram&& glProgram_, VertexAttributeArrayGL&& attributes);
ShaderProgramGL(ShaderProgramGL&& other);
virtual ~ShaderProgramGL() noexcept = default;
@@ -24,6 +25,8 @@ public:
const gfx::VertexAttributeArray& getVertexAttributes() const override { return vertexAttributes; }
ProgramID getGLProgramID() const { return glProgram; }
protected:
UniqueProgram glProgram;

View File

@@ -15,7 +15,12 @@ class ProgramParameters;
namespace gfx {
class Drawable;
class OffscreenTexture;
class ShaderProgramBase;
using ShaderProgramBasePtr = std::shared_ptr<ShaderProgramBase>;
class Context {
protected:
@@ -81,6 +86,17 @@ public:
#endif
virtual void clearStencilBuffer(int32_t) = 0;
public:
const gfx::ShaderProgramBasePtr& getCurrentShader() const { return currentShader; }
virtual void setCurrentShader(ShaderProgramBasePtr) = 0;
/// Activate the shader, vertex attributes, etc., specified by the drawable
virtual void setupDraw(const gfx::Drawable&) = 0;
protected:
ShaderProgramBasePtr currentShader;
};
} // namespace gfx

View File

@@ -28,7 +28,7 @@ void DrawableBuilder::flush() {
if (!impl->vertices.empty()) {
auto draw = getCurrentDrawable(/*create=*/true);
currentDrawable->setDrawPriority(drawPriority);
currentDrawable->setShaderID(shaderID);
currentDrawable->setShader(shader);
currentDrawable->setVertexAttributes(getVertexAttributes());
currentDrawable->addTweakers(tweakers.begin(), tweakers.end());
init();

View File

@@ -1,4 +1,5 @@
#include <mbgl/gl/context.hpp>
#include <mbgl/gl/drawable_gl.hpp>
#include <mbgl/gl/enum.hpp>
#include <mbgl/gl/renderer_backend.hpp>
#include <mbgl/gl/texture_resource.hpp>
@@ -9,6 +10,7 @@
#include <mbgl/gl/command_encoder.hpp>
#include <mbgl/gl/debugging_extension.hpp>
#include <mbgl/gl/defines.hpp>
#include <mbgl/shaders/gl/shader_program_gl.hpp>
#include <mbgl/util/traits.hpp>
#include <mbgl/util/std.hpp>
#include <mbgl/util/logging.hpp>
@@ -445,7 +447,34 @@ void Context::setDirtyState() {
globalVertexArrayState.setDirty();
}
void Context::clear(std::optional<mbgl::Color> color, std::optional<float> depth, std::optional<int32_t> stencil) {
void Context::setupDraw(const gfx::Drawable& drawable) {
if (auto &shader = drawable.getShader()) {
if (shader != currentShader) {
setCurrentShader(shader);
}
}
auto& drawableGL = static_cast<const DrawableGL&>(drawable);
auto& vao = drawableGL.getVertexArray();
if (vao.isValid()) {
bindVertexArray = vao.getID(); // glBindVertexArray
} else {
bindVertexArray = value::BindVertexArray::Default;
}
}
void Context::setCurrentShader(gfx::ShaderProgramBasePtr value) {
if ((currentShader = std::move(value))) {
auto& shaderGL = static_cast<ShaderProgramGL&>(*currentShader);
this->program = shaderGL.getGLProgramID();
} else {
this->program = value::Program::Default;
}
}
void Context::clear(std::optional<mbgl::Color> color,
std::optional<float> depth,
std::optional<int32_t> stencil) {
GLbitfield mask = 0;
if (color) {

View File

@@ -104,6 +104,10 @@ public:
void setCleanupOnDestruction(bool cleanup) { cleanupOnDestruction = cleanup; }
void setupDraw(const gfx::Drawable&) override;
void setCurrentShader(gfx::ShaderProgramBasePtr) override;
private:
RendererBackend& backend;
bool cleanupOnDestruction = true;

View File

@@ -1,7 +1,10 @@
#include <mbgl/gl/renderer_backend.hpp>
#include <mbgl/gfx/backend_scope.hpp>
#include <mbgl/gfx/shader_registry.hpp>
#include <mbgl/gl/context.hpp>
#include <mbgl/gl/extension.hpp>
#include <mbgl/shaders/gl/shader_program_gl.hpp>
#include <mbgl/util/logging.hpp>
#include <cassert>
@@ -62,5 +65,67 @@ void RendererBackend::setScissorTest(bool enabled) {
RendererBackend::~RendererBackend() = default;
void RendererBackend::initShaders(gfx::ShaderRegistry& shaders) {
constexpr auto shaderName = "background_generic";
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 float a;
uniform int b;
uniform mat4 c;
layout (location = 0) in vec3 pos;
in float d;
in int e;
in mat2 f;
in mat4 g;
void main() {
gl_Position = vec4(d, float(e), f[0][0], a)/1.0e12;
gl_Position = vec4(pos, 1.0);
})";
constexpr auto frag = R"(
#version 300 es
precision highp float;
in vec4 pos;
out vec4 color;
void main() {
color = vec4(1.0,0.0,0.0,1.0);
})";
try {
// Compile
shader = gl::ShaderProgramGL::create(glContext, shaderName, vert, frag);
if (shader) {
// Set default values
if (auto *attr = shader->getVertexAttributes().get("d")) {
attr->set(0, 12.3f);
}
if (auto *attr = shader->getVertexAttributes().get("e")) {
attr->set(0, 123);
}
if (auto *attr = shader->getVertexAttributes().get("f")) {
attr->set(0, gfx::VertexAttribute::matf2{ 1.0f, 2.0f, 3.0f, 4.0f });
}
// Add to the registry
if (!shaders.registerShader(shader, shaderName)) {
Log::Warning(Event::General, "Shader conflict - " + std::string(shaderName));
return;
}
} else {
Log::Warning(Event::General, "Shader create failed - " + std::string(shaderName));
return;
}
} catch (const std::runtime_error& ex) {
Log::Warning(Event::General, "Shader create exception - " + std::string(ex.what()));
return;
}
}
}
} // namespace gl
} // namespace mbgl

View File

@@ -72,6 +72,8 @@ public:
bool isValid() const { return state.operator bool(); }
VertexArrayID getID() const { return state->vertexArray; }
private:
UniqueVertexArrayState state;
};

View File

@@ -61,6 +61,10 @@ void Renderer::Impl::render(const RenderTree& renderTree) {
auto& context = backend.getContext();
// Now that the shader registry is set up, do one-time shader init.
// TODO: Both should be done earlier.
backend.initShaders(*staticData->shaders);
// Blocks execution until the renderable is available.
backend.getDefaultRenderable().wait();
@@ -109,34 +113,32 @@ void Renderer::Impl::render(const RenderTree& renderTree) {
// Generate a vertex array object for the drawable state, if necessary
auto& drawableGL = static_cast<gl::DrawableGL&>(drawable);
if (!drawableGL.getVertexArray().isValid() && !drawable.getShaderID().empty()) {
// TODO: avoid having to do this lookup twice
if (auto shader = parameters.shaders.get<gl::ShaderProgramGL>(drawable.getShaderID())) {
const auto usage = gfx::BufferUsageType::StaticDraw;
const auto& shader = drawable.getShader();
if (shader && !drawableGL.getVertexArray().isValid()) {
const auto usage = gfx::BufferUsageType::StaticDraw;
// Build index buffer
const auto& indexData = drawable.getIndexData();
auto indexBuffer = gfx::IndexBuffer {
indexData.size(),
uploadPass->createIndexBufferResource(
&indexData[0],
indexData.size() * sizeof(indexData[0]),
usage)
};
// Build index buffer
const auto& indexData = drawable.getIndexData();
auto indexBuffer = gfx::IndexBuffer {
indexData.size(),
uploadPass->createIndexBufferResource(
&indexData[0],
indexData.size() * sizeof(indexData[0]),
usage)
};
// Apply drawable values to shader defaults
const auto& defaults = shader->getVertexAttributes();
const auto& overrides = drawable.getVertexAttributes();
auto bindingsAndBuffer = uploadPass->buildAttributeBindings(defaults, overrides, usage);
// Apply drawable values to shader defaults
const auto& defaults = shader->getVertexAttributes();
const auto& overrides = drawable.getVertexAttributes();
auto bindingsAndBuffer = uploadPass->buildAttributeBindings(defaults, overrides, usage);
auto& glContext = static_cast<gl::Context&>(context);
auto vertexArray = glContext.createVertexArray();
vertexArray.bind(glContext, indexBuffer, bindingsAndBuffer.first);
drawableGL.setVertexArray(std::move(vertexArray),
std::move(bindingsAndBuffer.second),
std::move(indexBuffer));
}
auto& glContext = static_cast<gl::Context&>(context);
auto vertexArray = glContext.createVertexArray();
vertexArray.bind(glContext, indexBuffer, bindingsAndBuffer.first);
drawableGL.setVertexArray(std::move(vertexArray),
std::move(bindingsAndBuffer.second),
std::move(indexBuffer));
}
}
}
@@ -196,15 +198,8 @@ void Renderer::Impl::render(const RenderTree& renderTree) {
{
for (const auto &pair : orchestrator.getDrawables()) {
const auto& drawable = *pair.second;
if (!drawable.getShaderID().empty()) {
// if shader != currentShader
if (auto shader = parameters.shaders.get<gl::ShaderProgramGL>(drawable.getShaderID())) {
// Context.activate(shader)
}
}
// Context.bind(drawable vao)
context.setupDraw(drawable);
drawable.draw(parameters);
}

View File

@@ -57,9 +57,17 @@ ShaderProgramGL::ShaderProgramGL(UniqueProgram&& glProgram_)
glProgram(std::move(glProgram_)) {
}
ShaderProgramGL::ShaderProgramGL(UniqueProgram&& glProgram_,
VertexAttributeArrayGL&& attributes)
: ShaderProgramBase(),
glProgram(std::move(glProgram_)),
vertexAttributes(std::move(attributes)) {
}
ShaderProgramGL::ShaderProgramGL(ShaderProgramGL&& other)
: ShaderProgramBase(std::forward<ShaderProgramBase&&>(other)),
glProgram(std::move(other.glProgram)) {
glProgram(std::move(other.glProgram)),
vertexAttributes(std::move(other.vertexAttributes)) {
}
std::shared_ptr<ShaderProgramGL> ShaderProgramGL::create(
@@ -111,7 +119,7 @@ std::shared_ptr<ShaderProgramGL> ShaderProgramGL::create(
}
}
return std::make_shared<ShaderProgramGL>(std::move(program));
return std::make_shared<ShaderProgramGL>(std::move(program), std::move(attrs));
}
} // namespace gl

View File

@@ -19,62 +19,8 @@ bool BackgroundLayer::Impl::hasLayoutDifference(const Layer::Impl&) const {
constexpr auto shaderName = "background_generic";
void BackgroundLayer::Impl::layerAdded(PaintParameters& parameters, UniqueChangeRequestVec& changes) const {
// TODO: this should happen a GL-specific part of map initialization
auto &glContext = static_cast<gl::Context&>(parameters.context);
auto shader = parameters.shaders.get<gl::ShaderProgramGL>(shaderName);
if (!shader) {
constexpr auto vert = R"(
//#version 300 es
precision highp float;
uniform float a;
uniform int b;
uniform mat4 c;
attribute vec3 pos; //layout (location = 0) in vec3 pos;
attribute float d;
//attribute int e;
attribute mat2 f;
attribute mat4 g;
void main() {
gl_Position = vec4(a, g[0][0], f[0][0], d);
gl_Position = vec4(pos, 1.0);
})";
constexpr auto frag = R"(
//#version 300 es
precision highp float;
//out vec4 color;
void main() {
//color = vec4(1.0,0.0,0.0,1.0);
gl_FragColor = vec4(1.0,0.0,0.0,1.0);
})";
try {
// Compile
shader = gl::ShaderProgramGL::create(glContext, shaderName, vert, frag);
if (shader) {
// Set default values
if (auto *attr = shader->getVertexAttributes().get("a")) {
attr->set(0, 12.3f);
}
if (auto *attr = shader->getVertexAttributes().get("b")) {
attr->set(0, 123);
}
if (auto *attr = shader->getVertexAttributes().get("f")) {
attr->set(0, gfx::VertexAttribute::matf2{ 1.0f, 2.0f, 3.0f, 4.0f });
}
// Add to the registry
if (!parameters.shaders.registerShader(shader, shaderName)) {
Log::Warning(Event::General, "Shader conflict - " + std::string(shaderName));
return;
}
} else {
Log::Warning(Event::General, "Shader create failed - " + std::string(shaderName));
return;
}
} catch (const std::runtime_error& ex) {
Log::Warning(Event::General, "Shader create exception - " + std::string(ex.what()));
return;
}
shader = parameters.shaders.get<gl::ShaderProgramGL>(shaderName);
}
buildDrawables(changes);
@@ -88,8 +34,13 @@ void BackgroundLayer::Impl::layerRemoved(PaintParameters&, UniqueChangeRequestVe
}
void BackgroundLayer::Impl::buildDrawables(UniqueChangeRequestVec& changes) const {
if (!shader) {
return;
}
auto builder = std::make_unique<gl::DrawableGLBuilder>(); // from GL-specific code via virtual method?
builder->setShaderID(shaderName);
builder->setShader(shader);
builder->addTweaker(std::make_shared<gl::DrawableGLTweaker>()); // generally shared across drawables
builder->addQuad(0, 0, util::EXTENT, util::EXTENT);
builder->flush();

View File

@@ -10,7 +10,9 @@ namespace mbgl {
namespace gfx {
class Drawable;
class ShaderProgramBase;
using DrawablePtr = std::shared_ptr<Drawable>;
using ShaderProgramBasePtr = std::shared_ptr<ShaderProgramBase>;
} // namespace gfx
@@ -27,7 +29,7 @@ public:
void layerRemoved(PaintParameters&, UniqueChangeRequestVec&) const override;
/// Generate any changes needed by the layer
void update(UniqueChangeRequestVec& changes) const override;
void update(UniqueChangeRequestVec&) const override;
private:
void buildDrawables(UniqueChangeRequestVec&) const;
@@ -35,6 +37,7 @@ private:
public:
BackgroundPaintProperties::Transitionable paint;
mutable gfx::ShaderProgramBasePtr shader;
mutable gfx::DrawablePtr drawable;
DECLARE_LAYER_TYPE_INFO;