First cut at Drawable fundamentals (#983)

Co-authored-by: mwilsnd <mwilsnd@gmail.com>
Co-authored-by: Alex Cristici <alex.cristici@gmail.com>
This commit is contained in:
Tim Sylvester
2023-04-17 09:58:57 -07:00
committed by Bart Louwers
parent 42afe4189c
commit 14b53e54ec
60 changed files with 1904 additions and 87 deletions

View File

@@ -140,11 +140,16 @@ list(APPEND INCLUDE_FILES
${PROJECT_SOURCE_DIR}/include/mbgl/actor/scheduler.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/annotation/annotation.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/gfx/backend_scope.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/gfx/drawable.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/gfx/drawable_builder.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/gfx/drawable_tweaker.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/gfx/gfx_types.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/gfx/renderable.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/gfx/renderer_backend.hpp
${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/vertex_attribute.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/layermanager/background_layer_factory.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/layermanager/circle_layer_factory.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/layermanager/fill_extrusion_layer_factory.hpp
@@ -177,6 +182,9 @@ list(APPEND INCLUDE_FILES
${PROJECT_SOURCE_DIR}/include/mbgl/renderer/renderer_frontend.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/renderer/renderer_observer.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/renderer/renderer_state.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/shader_program_base.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/gl/shader_program_gl.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/mtl/shader_program_mtl.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/storage/database_file_source.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/storage/file_source.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/storage/file_source_manager.hpp
@@ -296,6 +304,7 @@ list(APPEND INCLUDE_FILES
${PROJECT_SOURCE_DIR}/include/mbgl/util/geo.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/util/geojson.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/util/geometry.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/util/identity.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/util/ignore.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/util/image.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/util/immutable.hpp
@@ -364,6 +373,10 @@ list(APPEND SRC_FILES
${PROJECT_SOURCE_DIR}/src/mbgl/gfx/depth_mode.hpp
${PROJECT_SOURCE_DIR}/src/mbgl/gfx/draw_mode.hpp
${PROJECT_SOURCE_DIR}/src/mbgl/gfx/draw_scope.hpp
${PROJECT_SOURCE_DIR}/src/mbgl/gfx/drawable.cpp
${PROJECT_SOURCE_DIR}/src/mbgl/gfx/drawable_builder.cpp
${PROJECT_SOURCE_DIR}/src/mbgl/gfx/drawable_builder_impl.hpp
${PROJECT_SOURCE_DIR}/src/mbgl/gfx/drawable_tweaker.cpp
${PROJECT_SOURCE_DIR}/src/mbgl/gfx/index_buffer.hpp
${PROJECT_SOURCE_DIR}/src/mbgl/gfx/index_vector.hpp
${PROJECT_SOURCE_DIR}/src/mbgl/gfx/offscreen_texture.hpp
@@ -378,6 +391,7 @@ list(APPEND SRC_FILES
${PROJECT_SOURCE_DIR}/src/mbgl/gfx/types.hpp
${PROJECT_SOURCE_DIR}/src/mbgl/gfx/uniform.hpp
${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
${PROJECT_SOURCE_DIR}/src/mbgl/gfx/vertex_vector.hpp
${PROJECT_SOURCE_DIR}/src/mbgl/layermanager/background_layer_factory.cpp
@@ -572,6 +586,9 @@ list(APPEND SRC_FILES
${PROJECT_SOURCE_DIR}/src/mbgl/renderer/transition_parameters.hpp
${PROJECT_SOURCE_DIR}/src/mbgl/renderer/update_parameters.hpp
${PROJECT_SOURCE_DIR}/src/mbgl/renderer/upload_parameters.hpp
${PROJECT_SOURCE_DIR}/src/mbgl/shaders/shader_program_base.cpp
${PROJECT_SOURCE_DIR}/src/mbgl/shaders/gl/shader_program_gl.cpp
${PROJECT_SOURCE_DIR}/src/mbgl/shaders/mtl/shader_program_mtl.cpp
${PROJECT_SOURCE_DIR}/src/mbgl/sprite/sprite_loader.cpp
${PROJECT_SOURCE_DIR}/src/mbgl/sprite/sprite_loader.hpp
${PROJECT_SOURCE_DIR}/src/mbgl/sprite/sprite_loader_observer.hpp
@@ -824,6 +841,7 @@ list(APPEND SRC_FILES
${PROJECT_SOURCE_DIR}/src/mbgl/util/http_header.hpp
${PROJECT_SOURCE_DIR}/src/mbgl/util/http_timeout.cpp
${PROJECT_SOURCE_DIR}/src/mbgl/util/http_timeout.hpp
${PROJECT_SOURCE_DIR}/src/mbgl/util/identity.cpp
${PROJECT_SOURCE_DIR}/src/mbgl/util/i18n.cpp
${PROJECT_SOURCE_DIR}/src/mbgl/util/i18n.hpp
${PROJECT_SOURCE_DIR}/src/mbgl/util/interpolate.cpp
@@ -886,10 +904,15 @@ if(MLN_WITH_OPENGL)
${PROJECT_SOURCE_DIR}/include/mbgl/gfx/backend.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/gl/custom_layer.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/gl/custom_layer_factory.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/gl/drawable_gl.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/gl/drawable_gl_builder.hpp
${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/vertex_attribute_gl.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/layermanager/location_indicator_layer_factory.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/platform/gl_functions.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/renderer/change_request.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/style/layers/location_indicator_layer.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/shader_source.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/shader_manifest.hpp
@@ -937,6 +960,10 @@ if(MLN_WITH_OPENGL)
${PROJECT_SOURCE_DIR}/src/mbgl/gl/debugging_extension.hpp
${PROJECT_SOURCE_DIR}/src/mbgl/gl/defines.hpp
${PROJECT_SOURCE_DIR}/src/mbgl/gl/draw_scope_resource.hpp
${PROJECT_SOURCE_DIR}/src/mbgl/gl/drawable_gl.cpp
${PROJECT_SOURCE_DIR}/src/mbgl/gl/drawable_gl_builder.cpp
${PROJECT_SOURCE_DIR}/src/mbgl/gl/drawable_gl_impl.hpp
${PROJECT_SOURCE_DIR}/src/mbgl/gl/drawable_gl_tweaker.cpp
${PROJECT_SOURCE_DIR}/src/mbgl/gl/enum.cpp
${PROJECT_SOURCE_DIR}/src/mbgl/gl/enum.hpp
${PROJECT_SOURCE_DIR}/src/mbgl/gl/extension.hpp
@@ -968,10 +995,12 @@ if(MLN_WITH_OPENGL)
${PROJECT_SOURCE_DIR}/src/mbgl/gl/value.hpp
${PROJECT_SOURCE_DIR}/src/mbgl/gl/vertex_array.cpp
${PROJECT_SOURCE_DIR}/src/mbgl/gl/vertex_array.hpp
${PROJECT_SOURCE_DIR}/src/mbgl/gl/vertex_attribute_gl.cpp
${PROJECT_SOURCE_DIR}/src/mbgl/gl/vertex_buffer_resource.cpp
${PROJECT_SOURCE_DIR}/src/mbgl/gl/vertex_buffer_resource.hpp
${PROJECT_SOURCE_DIR}/src/mbgl/layermanager/location_indicator_layer_factory.cpp
${PROJECT_SOURCE_DIR}/src/mbgl/platform/gl_functions.cpp
${PROJECT_SOURCE_DIR}/src/mbgl/renderer/change_request.cpp
${PROJECT_SOURCE_DIR}/src/mbgl/renderer/layers/render_location_indicator_layer.cpp
${PROJECT_SOURCE_DIR}/src/mbgl/renderer/layers/render_location_indicator_layer.hpp
${PROJECT_SOURCE_DIR}/src/mbgl/style/layers/location_indicator_layer.cpp
@@ -982,6 +1011,26 @@ if(MLN_WITH_OPENGL)
)
endif()
if(MBGL_WITH_METAL)
message(STATUS "Configuring Metal renderer backend")
target_compile_definitions(
mbgl-core
PRIVATE MBGL_RENDER_BACKEND_METAL=1
)
list(APPEND
INCLUDE_FILES
${PROJECT_SOURCE_DIR}/include/mbgl/mtl/drawable_mtl.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/mtl/drawable_mtl_builder.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/mtl/drawable_mtl_tweaker.hpp
)
list(APPEND
SRC_FILES
${PROJECT_SOURCE_DIR}/src/mbgl/mtl/drawable_mtl.cpp
${PROJECT_SOURCE_DIR}/src/mbgl/mtl/drawable_mtl_builder.cpp
${PROJECT_SOURCE_DIR}/src/mbgl/mtl/drawable_mtl_tweaker.cpp
)
endif()
target_sources(
mbgl-core PRIVATE
${INCLUDE_FILES}

View File

@@ -0,0 +1,72 @@
#pragma once
#include <mbgl/util/identity.hpp>
#include <mbgl/gfx/vertex_attribute.hpp>
#include <cstdint>
#include <memory>
#include <vector>
namespace mbgl {
class PaintParameters;
namespace gfx {
class DrawableTweaker;
using DrawPriority = int64_t;
using DrawableTweakerPtr = std::shared_ptr<DrawableTweaker>;
class Drawable {
protected:
Drawable() {
}
public:
virtual ~Drawable() = default;
const util::SimpleIdentity& getId() const { return uniqueID; }
/// Draw the drawable
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); }
/// DrawPriority determines the drawing order
DrawPriority getDrawPriority() const { return drawPriority; }
void setDrawPriority(DrawPriority value) { drawPriority = value; }
/// Get the vertex attributes that override default values in the shader program
virtual const gfx::VertexAttributeArray& getVertexAttributes() const = 0;
virtual void setVertexAttributes(const gfx::VertexAttributeArray&) = 0;
virtual void setVertexAttributes(gfx::VertexAttributeArray&&) = 0;
virtual std::vector<std::uint16_t>& getIndexData() const = 0;
/// Attach a tweaker to be run on this drawable for each frame
void addTweaker(DrawableTweakerPtr tweaker) { tweakers.emplace_back(std::move(tweaker)); }
template <typename TIter>
void addTweakers(TIter beg, TIter end) { tweakers.insert(tweakers.end(), beg, end); }
/// Get the tweakers attached to this drawable
std::vector<DrawableTweakerPtr> getTweakers() const { return tweakers; }
protected:
util::SimpleIdentity uniqueID;
//util::SimpleIdentity shaderID = util::SimpleIdentity::Empty;
std::string shaderID;
DrawPriority drawPriority = 0;
std::vector<DrawableTweakerPtr> tweakers;
};
using DrawablePtr = std::shared_ptr<Drawable>;
} // namespace gfx
} // namespace mbgl

View File

@@ -0,0 +1,99 @@
#pragma once
#include <mbgl/gfx/drawable.hpp>
#include <mbgl/gfx/vertex_attribute.hpp>
#include <memory>
#include <vector>
namespace mbgl {
class Color;
namespace gfx {
class DrawableTweaker;
using DrawableTweakerPtr = std::shared_ptr<DrawableTweaker>;
/**
Base class for drawable builders, which construct Drawables from primitives
*/
class DrawableBuilder {
protected:
DrawableBuilder();
public:
virtual ~DrawableBuilder();
/// Get the drawable we're currently working on, if any
DrawablePtr getCurrentDrawable(bool createIfNone);
/// Close the current drawable, using a new one for any further work
void flush();
/// Get all the completed drawables
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); }
/// Get the ID of the drawable we're currently working on, if any
util::SimpleIdentity getDrawableId();
/// Get the draw priority assigned to generated drawables
DrawPriority getDrawPriority() const;
/// Set the draw priority assigned to generated drawables
void setDrawPriority(DrawPriority);
/// Set the draw priority on all drawables including those already generated
void resetDrawPriority(DrawPriority);
/// The color used for emitted vertexes
const Color& getColor() const;
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); }
/// Get the vertex attributes that override default values in the shader program
virtual const gfx::VertexAttributeArray& getVertexAttributes() const = 0;
/// Add a triangle
void addTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2);
/// Add another triangle based on the previous two points
void appendTriangle(int16_t x0, int16_t y0);
/// Add a rectangle consisting of two triangles
void addQuad(int16_t x0, int16_t y0, int16_t x1, int16_t y1);
/// Add a tweaker to be attached to each emitted drawable
void addTweaker(DrawableTweakerPtr tweaker) { tweakers.emplace_back(std::move(tweaker)); }
protected:
/// Create an instance of the appropriate drawable type
virtual DrawablePtr createDrawable() const = 0;
/// Setup the SDK-specific aspects after all the values are present
virtual void init() = 0;
protected:
DrawPriority drawPriority = 0;
//util::SimpleIdentity shaderID = util::SimpleIdentity::Empty;
std::string shaderID;
DrawablePtr currentDrawable;
std::vector<DrawablePtr> drawables;
std::vector<DrawableTweakerPtr> tweakers;
struct Impl;
std::unique_ptr<Impl> impl;
};
} // namespace gfx
} // namespace mbgl

View File

@@ -0,0 +1,29 @@
#pragma once
#include <memory>
namespace mbgl {
class PaintParameters;
namespace gfx {
class Drawable;
/**
Base class for drawable tweakers, which manipulate drawables per frame
*/
class DrawableTweaker {
protected:
DrawableTweaker() = default;
public:
virtual ~DrawableTweaker() = default;
virtual void execute(Drawable&, const PaintParameters&) = 0;
};
using DrawableTweakerPtr = std::shared_ptr<DrawableTweaker>;
} // namespace gfx
} // namespace mbgl

View File

@@ -0,0 +1,65 @@
#pragma once
#include <cstdint>
namespace mbgl {
namespace gfx {
enum class PrimitiveType : uint8_t {
Point,
Line,
Triangle,
};
enum class DrawModeType : uint8_t {
Points,
Lines,
LineLoop,
LineStrip,
Triangles,
TriangleStrip,
TriangleFan,
};
enum class AttributeDataType : uint8_t {
Byte,
Byte2,
Byte3,
Byte4,
UByte,
UByte2,
UByte3,
UByte4,
Short,
Short2,
Short3,
Short4,
UShort,
UShort2,
UShort3,
UShort4,
Int,
Int2,
Int3,
Int4,
UInt,
UInt2,
UInt3,
UInt4,
Float,
Float2,
Float3,
Float4,
Invalid = 255,
};
} // namespace gfx
} // namespace mbgl

View File

@@ -11,7 +11,7 @@ class Shader;
// Assert that a type is a valid shader for downcasting.
// A valid shader must:
// * Inherit gfx::Shader
// * Declare a public, unique type name (string_view T::Name)
// * Have properly called DECLARE_SHADER_TYPEINFO in the class body
// * Be a final class
template <typename T>
inline constexpr bool is_shader_v = std::is_base_of_v<gfx::Shader, T> &&

View File

@@ -0,0 +1,142 @@
#pragma once
#include <mbgl/gfx/gfx_types.hpp>
#include <array>
#include <cstdint>
#include <functional>
#include <memory>
#include <string>
#include <unordered_map>
#include <variant>
#include <vector>
namespace mbgl {
using mat2 = std::array<double, 2*2>;
using mat3 = std::array<double, 3*3>;
using mat4 = std::array<double, 4*4>;
namespace gfx {
// static_assert(sizeof(Type) < 256, "vertex type must be smaller than 256 bytes");
// static_assert(std::is_standard_layout_v<Type>, "vertex type must use standard layout");
// static_assert(I < Descriptor::data.count, "attribute index must be in range");
class VertexAttributeArray;
class VertexAttribute {
public:
using float2 = std::array<float, 2>;
using float3 = std::array<float, 3>;
using matf2 = std::array<float, 2*2>;
using matf3 = std::array<float, 3*3>;
using matf4 = std::array<float, 4*4>;
using int2 = std::array<std::int32_t, 2>;
using int3 = std::array<std::int32_t, 3>;
using int4 = std::array<std::int32_t, 4>;
using ElementType = std::variant<std::int32_t, int2, int3, int4, float, float2, float3, matf2, matf4>;
// Can only be created by VertexAttributeArray implementations
protected:
VertexAttribute(int index_, AttributeDataType dataType_, std::size_t count_)
: index(index_),
dataType(dataType_),
items(count_) {
}
VertexAttribute(const VertexAttribute &) = default;
VertexAttribute(VertexAttribute&& other)
: index(other.index),
dataType(other.dataType),
items(std::move(other.items)) {
}
public:
~VertexAttribute() = default;
int getIndex() const { return index; }
std::size_t getCount() const { return items.size(); }
AttributeDataType getDataType() const { return dataType; }
const ElementType& get(std::size_t i) const { return items[i]; }
template <typename T>
const ElementType& set(std::size_t i, T value) {
dirty = true; // need to rebuild the raw data next time
return items[i] = value;
}
protected:
VertexAttribute& operator=(const VertexAttribute&) = default;
VertexAttribute& operator=(const VertexAttribute&& other) {
index = other.index;
dataType = other.dataType;
items = std::move(other.items);
return *this;
}
protected:
int index;
/// indicates that a value has changed and any cached result should be discarded
mutable bool dirty = true;
AttributeDataType dataType;
std::vector<ElementType> items;
};
/// Stores a collection of vertex attributes by name
class VertexAttributeArray {
public:
using AttributeMap = std::unordered_map<std::string, std::unique_ptr<VertexAttribute>>;
VertexAttributeArray(int initCapacity = 10);
VertexAttributeArray(VertexAttributeArray &&);
VertexAttributeArray(const VertexAttributeArray&);
virtual ~VertexAttributeArray() = default;
std::size_t size() const { return attrs.size(); }
/// 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;
/// 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, AttributeDataType, std::size_t count);
/// 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, AttributeDataType, std::size_t count);
using ResolveDelegate = std::function<void(const std::string&, const VertexAttribute&, const VertexAttribute*)>;
/// Call the provided delegate with each value, providing the override if one exists.
void resolve(const VertexAttributeArray& overrides, ResolveDelegate) const;
VertexAttributeArray& operator=(VertexAttributeArray &&);
VertexAttributeArray& operator=(const VertexAttributeArray&);
protected:
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();
} else {
return nullptr;
}
}
virtual std::unique_ptr<VertexAttribute> create(int index, AttributeDataType dataType, std::size_t count) = 0;
virtual std::unique_ptr<VertexAttribute> copy(const VertexAttribute& attr) = 0;
protected:
AttributeMap attrs;
};
} // namespace gfx
} // namespace mbgl

View File

@@ -0,0 +1,57 @@
#pragma once
#include <mbgl/gfx/drawable.hpp>
#include <mbgl/gl/vertex_attribute_gl.hpp>
#include <memory>
namespace mbgl {
namespace gfx {
class IndexBuffer;
class VertexBufferResource;
using UniqueVertexBufferResource = std::unique_ptr<gfx::VertexBufferResource>;
} // namespace gfx
namespace gl {
class VertexArray;
class DrawableGL : public gfx::Drawable {
public:
DrawableGL();
virtual ~DrawableGL();
void draw(const PaintParameters &) const override;
void setVertData(std::vector<std::uint8_t> vertexData_, std::vector<uint16_t> indexes_);
const gfx::VertexAttributeArray& getVertexAttributes() const override { return vertexAttributes; }
void setVertexAttributes(const gfx::VertexAttributeArray& value) override {
vertexAttributes = static_cast<const VertexAttributeArrayGL&>(value);
}
void setVertexAttributes(gfx::VertexAttributeArray&& value) override {
vertexAttributes = std::move(static_cast<VertexAttributeArrayGL&&>(value));
}
const gl::VertexArray& getVertexArray() const;
void setVertexArray(gl::VertexArray&&, gfx::UniqueVertexBufferResource&&, gfx::IndexBuffer&&);
std::vector<std::uint16_t>& getIndexData() const override;
protected:
class Impl;
const std::unique_ptr<Impl> impl;
// For testing only.
DrawableGL(std::unique_ptr<Impl>);
private:
VertexAttributeArrayGL vertexAttributes;
};
} // namespace gl
} // namespace mbgl

View File

@@ -0,0 +1,33 @@
#pragma once
#include <mbgl/gfx/drawable_builder.hpp>
#include <mbgl/gl/vertex_attribute_gl.hpp>
namespace mbgl {
namespace gl {
/**
Base class for OpenGL-specific drawable builders.
*/
class DrawableGLBuilder final : public gfx::DrawableBuilder {
public:
DrawableGLBuilder() {
}
virtual ~DrawableGLBuilder() = default;
const gfx::VertexAttributeArray& getVertexAttributes() const override { return vertexAttributes; }
void setVertexAttributes(const VertexAttributeArrayGL& value) { vertexAttributes = value; }
void setVertexAttributes(VertexAttributeArrayGL&& value) { vertexAttributes = std::move(value); }
protected:
gfx::DrawablePtr createDrawable() const override;
/// Setup the SDK-specific aspects after all the values are present
void init() override;
private:
VertexAttributeArrayGL vertexAttributes;
};
} // namespace gl
} // namespace mbgl

View File

@@ -0,0 +1,27 @@
#pragma once
#include <mbgl/gfx/drawable_tweaker.hpp>
namespace mbgl {
namespace gfx {
class Drawable;
}
namespace gl {
/**
OpenGL-specific drawable tweaker
*/
class DrawableGLTweaker : public gfx::DrawableTweaker {
public:
DrawableGLTweaker() = default;
public:
virtual ~DrawableGLTweaker() = default;
virtual void execute(gfx::Drawable&, const PaintParameters&) override;
};
} // namespace gl
} // namespace mbgl

View File

@@ -0,0 +1,71 @@
#pragma once
#include <mbgl/gfx/vertex_attribute.hpp>
#include <mbgl/platform/gl_functions.hpp>
namespace mbgl {
namespace gl {
class VertexAttributeArrayGL;
class VertexAttributeGL final : public gfx::VertexAttribute {
// Can only be created by VertexAttributeArrayGL
private:
friend VertexAttributeArrayGL;
VertexAttributeGL(int index_, gfx::AttributeDataType dataType_, std::size_t count_)
: VertexAttribute(index_, dataType_, count_) {
}
VertexAttributeGL(const VertexAttributeGL& other)
: VertexAttribute(other),
glType(other.glType) {
}
VertexAttributeGL(VertexAttributeGL&& other)
: VertexAttribute(std::move(other)),
glType(other.glType) {
}
public:
platform::GLenum getGLType() const { return glType; }
void setGLType(platform::GLenum value) { glType = value; }
bool getNormalized() const { return normalized; }
void setNormalized(bool value) { normalized = value; }
std::size_t getStride() const { return stride; }
const std::vector<uint8_t>& getRaw() const;
private:
platform::GLenum glType = 0;
bool normalized = false;
mutable int stride = 0;
mutable std::vector<uint8_t> rawData;
};
/// Stores a collection of vertex attributes by name
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() = default;
VertexAttributeArrayGL& operator=(VertexAttributeArrayGL &&other) {
VertexAttributeArray::operator=(std::move(other));
return *this;
}
VertexAttributeArrayGL& operator=(const VertexAttributeArrayGL& other) {
VertexAttributeArray::operator=(other);
return *this;
}
private:
std::unique_ptr<gfx::VertexAttribute> create(int index, gfx::AttributeDataType dataType, std::size_t count) override {
return std::unique_ptr<gfx::VertexAttribute>(new VertexAttributeGL(index, dataType, count));
}
std::unique_ptr<gfx::VertexAttribute> copy(const gfx::VertexAttribute& attr) override {
return std::unique_ptr<gfx::VertexAttribute>(new VertexAttributeGL(static_cast<const VertexAttributeGL&>(attr)));
}
};
} // namespace gfx
} // namespace mbgl

View File

View File

View File

@@ -0,0 +1,72 @@
#pragma once
#include <mbgl/util/identity.hpp>
#include <memory>
#include <vector>
namespace mbgl {
class RenderOrchestrator;
namespace gfx {
class Drawable;
using DrawablePtr = std::shared_ptr<Drawable>;
} // namespace gfx
/**
Base class for changes to be made to the scene
*/
class ChangeRequest {
protected:
ChangeRequest() = default;
public:
virtual ~ChangeRequest() = default;
virtual void execute(RenderOrchestrator &) = 0;
protected:
};
using ChangeRequestPtr = std::shared_ptr<ChangeRequest>;
using UniqueChangeRequest = std::unique_ptr<ChangeRequest>;
using UniqueChangeRequestVec = std::vector<UniqueChangeRequest>;
/**
Add a new drawable to the scene
*/
class AddDrawableRequest : public ChangeRequest {
public:
AddDrawableRequest(gfx::DrawablePtr drawable_)
: drawable(std::move(drawable_)) {
}
AddDrawableRequest(AddDrawableRequest&& other)
: drawable(std::move(other.drawable)) {
}
void execute(RenderOrchestrator &) override;
protected:
gfx::DrawablePtr drawable;
};
/**
Remove a drawable from the scene
*/
class RemoveDrawableRequest : public ChangeRequest {
public:
RemoveDrawableRequest(util::SimpleIdentity drawableId_) : drawableId(drawableId_) { }
RemoveDrawableRequest(const RemoveDrawableRequest& other) : drawableId(other.drawableId) { }
void execute(RenderOrchestrator &) override;
protected:
util::SimpleIdentity drawableId;
};
} // namespace mbgl

View File

@@ -107,6 +107,11 @@ public:
*/
const std::vector<PlacedSymbolData>& getPlacedSymbolsData() const;
/**
Update the layers
*/
void update(const std::shared_ptr<UpdateParameters>&);
// Memory
void reduceMemoryUse();
void clearData();

View File

@@ -1,5 +1,7 @@
#pragma once
#include <mbgl/gfx/drawable.hpp>
#include <memory>
namespace mbgl {
@@ -25,6 +27,8 @@ public:
/// Coalescing updates is up to the implementer
virtual void update(std::shared_ptr<UpdateParameters>) = 0;
protected:
};
} // namespace mbgl

View File

@@ -0,0 +1,34 @@
#pragma once
#include <mbgl/gl/context.hpp>
#include <mbgl/gl/vertex_attribute_gl.hpp>
#include <mbgl/shaders/shader_program_base.hpp>
namespace mbgl {
namespace gl {
class ShaderProgramGL final : public gfx::ShaderProgramBase {
public:
ShaderProgramGL(UniqueProgram&& glProgram_);
ShaderProgramGL(ShaderProgramGL&& other);
virtual ~ShaderProgramGL() noexcept = default;
static constexpr std::string_view Name{"GenericGLShader"};
const std::string_view typeName() const noexcept override { return Name; }
static std::shared_ptr<ShaderProgramGL> create(
Context&,
std::string_view name,
std::string_view vertexSource,
std::string_view fragmentSource) noexcept(false);
const gfx::VertexAttributeArray& getVertexAttributes() const override { return vertexAttributes; }
protected:
UniqueProgram glProgram;
VertexAttributeArrayGL vertexAttributes;
};
} // namespace gl
} // namespace mbgl

View File

@@ -0,0 +1,26 @@
#pragma once
#include <mbgl/shaders/shader_program_base.hpp>
namespace mbgl {
namespace mtl {
class ShaderProgramMTL : public gfx::ShaderProgramBase {
public:
ShaderProgramMTL() : ShaderProgramBase() { }
virtual ~ShaderProgramMTL() = default;
static constexpr std::string_view Name{"GenericMTLShader"};
const std::string_view typeName() const noexcept override { return Name; }
//bool compile(std::string_view vert, std::string_view frag);
// Load compiled Metal functions from the default library in a bundle
//bool load(NSBundle*, std::string_view vertFuncName, std::string_view fragFuncName);
// Load compiled Metal functions from a specific library
//bool load(id<MTLLibrary>, std::string_view vertFuncName, std::string_view fragFuncName);
protected:
};
} // namespace mtl
} // namespace mbgl

View File

@@ -0,0 +1,30 @@
#pragma once
#include <mbgl/gfx/shader.hpp>
#include <mbgl/gfx/vertex_attribute.hpp>
#include <mbgl/util/identity.hpp>
#include <string>
namespace mbgl {
namespace gfx {
class ShaderProgramBase : public gfx::Shader {
protected:
ShaderProgramBase() { }
ShaderProgramBase(ShaderProgramBase&&) { }
public:
virtual ~ShaderProgramBase() noexcept = default;
const util::SimpleIdentity& getID() const { return shaderProgramID; }
/// Get the available vertex attributes and their default values
virtual const gfx::VertexAttributeArray& getVertexAttributes() const = 0;
protected:
util::SimpleIdentity shaderProgramID;
};
} // namespace gfx
} // namespace mbgl

View File

@@ -0,0 +1,51 @@
#pragma once
#include <cstdint>
namespace mbgl {
namespace util {
/**
A simple unique identifier
*/
class SimpleIdentity final {
private:
constexpr SimpleIdentity(std::int64_t id) : uniqueID(id) { }
public:
SimpleIdentity();
SimpleIdentity(const SimpleIdentity&) = default;
~SimpleIdentity() = default;
static const SimpleIdentity Empty;
bool operator<(const SimpleIdentity& other) const { return uniqueID < other.uniqueID; }
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; }
private:
static constexpr std::int64_t emptyID = 0;
std::int64_t uniqueID;
};
/**
Base class for objects that inherit an automatically-assigned unique identity
*/
class SimpleIdentifiable {
protected:
SimpleIdentifiable() = default;
SimpleIdentifiable(const SimpleIdentifiable&) = default;
virtual ~SimpleIdentifiable() = default;
const util::SimpleIdentity& getId() const { return uniqueID; }
protected:
util::SimpleIdentity uniqueID;
};
} // namespace util
} // namespace mbgl

View File

@@ -35,6 +35,9 @@ public:
} else {
[nativeView setNeedsRerender];
}
if (renderer) {
renderer->update(updateParameters);
}
}
void setObserver(mbgl::RendererObserver& observer) override {

View File

@@ -0,0 +1,9 @@
#include <mbgl/gfx/drawable.hpp>
namespace mbgl {
namespace gfx {
} // namespace gfx
} // namespace mbgl

View File

@@ -0,0 +1,86 @@
#include <mbgl/gfx/drawable_builder.hpp>
#include <mbgl/gfx/drawable_builder_impl.hpp>
namespace mbgl {
namespace gfx {
DrawableBuilder::DrawableBuilder()
: impl(std::make_unique<Impl>()) {
}
DrawableBuilder::~DrawableBuilder() = default;
const Color& DrawableBuilder::getColor() const {
return impl->currentColor;
}
void DrawableBuilder::setColor(const Color& value) {
impl->currentColor = value;
}
DrawablePtr DrawableBuilder::getCurrentDrawable(bool createIfNone) {
if (!currentDrawable && createIfNone) {
currentDrawable = createDrawable();
}
return currentDrawable;
}
void DrawableBuilder::flush() {
if (!impl->vertices.empty()) {
auto draw = getCurrentDrawable(/*create=*/true);
currentDrawable->setDrawPriority(drawPriority);
currentDrawable->setShaderID(shaderID);
currentDrawable->setVertexAttributes(getVertexAttributes());
currentDrawable->addTweakers(tweakers.begin(), tweakers.end());
init();
}
if (currentDrawable) {
drawables.push_back(currentDrawable);
currentDrawable.reset();
}
}
util::SimpleIdentity DrawableBuilder::getDrawableId() {
return currentDrawable ? currentDrawable->getId() : util::SimpleIdentity::Empty;
}
DrawPriority DrawableBuilder::getDrawPriority() const {
return drawPriority;
}
void DrawableBuilder::setDrawPriority(DrawPriority value) {
drawPriority = value;
if (currentDrawable) {
currentDrawable->setDrawPriority(value);
}
}
void DrawableBuilder::resetDrawPriority(DrawPriority value) {
setDrawPriority(value);
for (auto &drawble : drawables) {
drawble->setDrawPriority(value);
}
}
void DrawableBuilder::addTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2) {
const auto n = (uint16_t)impl->vertices.elements();
impl->vertices.emplace_back(Impl::VT({{{ x0, y0 }}}));
impl->vertices.emplace_back(Impl::VT({{{ x1, y1 }}}));
impl->vertices.emplace_back(Impl::VT({{{ x2, y2 }}}));
impl->indexes.emplace_back(n, n+1, n+2);
impl->colors.insert(impl->colors.end(), 3, impl->currentColor);
}
void DrawableBuilder::appendTriangle(int16_t x0, int16_t y0) {
const auto n = (uint16_t)impl->vertices.elements();
impl->vertices.emplace_back(Impl::VT({{{ x0, y0 }}}));
impl->indexes.emplace_back(n-1, n, n+1);
impl->colors.emplace_back(impl->currentColor);
}
void DrawableBuilder::addQuad(int16_t x0, int16_t y0, int16_t x1, int16_t y1) {
addTriangle(x0, y0, x1, y0, x0, y1);
appendTriangle(x1, y1);
}
} // namespace gfx
} // namespace mbgl

View File

@@ -0,0 +1,21 @@
#include <mbgl/gfx/attribute.hpp>
#include <mbgl/gfx/index_vector.hpp>
#include <mbgl/gfx/vertex_vector.hpp>
#include <mbgl/programs/segment.hpp>
#include <mbgl/util/color.hpp>
namespace mbgl {
namespace gfx {
struct DrawableBuilder::Impl {
using VT = gfx::detail::VertexType<gfx::AttributeType<short,2>>;
gfx::VertexVector<VT> vertices;
gfx::IndexVector<gfx::Triangles> indexes;
SegmentVector<TypeList<void>> segments;
Color currentColor = Color::white();
std::vector<Color> colors;
};
} // namespace gfx
} // namespace mbgl

View File

View File

@@ -1,65 +1,12 @@
#pragma once
#include <mbgl/gfx/gfx_types.hpp>
#include <cstdint>
namespace mbgl {
namespace gfx {
enum class PrimitiveType : uint8_t {
Point,
Line,
Triangle,
};
enum class DrawModeType : uint8_t {
Points,
Lines,
LineLoop,
LineStrip,
Triangles,
TriangleStrip,
TriangleFan,
};
enum class AttributeDataType : uint8_t {
Byte,
Byte2,
Byte3,
Byte4,
UByte,
UByte2,
UByte3,
UByte4,
Short,
Short2,
Short3,
Short4,
UShort,
UShort2,
UShort3,
UShort4,
Int,
Int2,
Int3,
Int4,
UInt,
UInt2,
UInt3,
UInt4,
Float,
Float2,
Float3,
Float4,
Invalid = 255,
};
enum class ColorBlendEquationType : uint8_t {
Add,
Subtract,

View File

@@ -1,5 +1,6 @@
#pragma once
#include <mbgl/gfx/attribute.hpp>
#include <mbgl/gfx/debug_group.hpp>
#include <mbgl/gfx/vertex_vector.hpp>
#include <mbgl/gfx/vertex_buffer.hpp>
@@ -8,9 +9,16 @@
#include <mbgl/gfx/texture.hpp>
#include <mbgl/util/size.hpp>
#include <optional>
#include <vector>
namespace mbgl {
namespace gfx {
class VertexAttributeArray;
using AttributeBindingArray = std::vector<std::optional<gfx::AttributeBinding>>;
class UploadPass {
protected:
UploadPass() = default;
@@ -51,12 +59,18 @@ public:
updateIndexBufferResource(buffer.getResource(), v.data(), v.bytes());
}
virtual std::pair<gfx::AttributeBindingArray, std::unique_ptr<gfx::VertexBufferResource>>
buildAttributeBindings(const gfx::VertexAttributeArray& defaults,
const gfx::VertexAttributeArray& overrides,
gfx::BufferUsageType) = 0;
protected:
virtual std::unique_ptr<VertexBufferResource> createVertexBufferResource(const void* data,
std::size_t size,
BufferUsageType) = 0;
virtual void updateVertexBufferResource(VertexBufferResource&, const void* data, std::size_t size) = 0;
public:
virtual std::unique_ptr<IndexBufferResource> createIndexBufferResource(const void* data,
std::size_t size,
BufferUsageType) = 0;

View File

@@ -0,0 +1,70 @@
#include <mbgl/gfx/vertex_attribute.hpp>
namespace mbgl {
namespace gfx {
VertexAttributeArray::VertexAttributeArray(int initCapacity)
: attrs(initCapacity) {
}
VertexAttributeArray::VertexAttributeArray(VertexAttributeArray &&other)
: attrs(std::move(other.attrs)) {
}
VertexAttributeArray::VertexAttributeArray(const VertexAttributeArray& other)
: attrs(other.attrs.size()) {
operator=(other);
}
VertexAttributeArray& VertexAttributeArray::operator=(VertexAttributeArray &&other) {
attrs = std::move(other.attrs);
return *this;
}
VertexAttributeArray& VertexAttributeArray::operator=(const VertexAttributeArray& other) {
attrs.clear();
for (const auto &kv : other.attrs) {
add(kv.first, copy(*kv.second));
}
return *this;
}
VertexAttribute* VertexAttributeArray::get(const std::string& name) const {
const auto result = attrs.find(name);
return (result != attrs.end()) ? result->second.get() : nullptr;
}
VertexAttribute* VertexAttributeArray::add(std::string name, int index,
AttributeDataType dataType, 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, count);
return result.first->second.get();
} else {
return nullptr;
}
}
VertexAttribute* VertexAttributeArray::getOrAdd(std::string name, int index,
AttributeDataType dataType, 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>()));
if (result.second) {
result.first->second = create(index, dataType, count);
} else if (result.first->second->getDataType() != dataType ||
result.first->second->getCount() != count) {
return nullptr;
}
return result.first->second.get();
}
void VertexAttributeArray::resolve(const VertexAttributeArray& overrides,
ResolveDelegate delegate) const {
for (auto& kv : attrs) {
const auto overrideAttr = overrides.get(kv.first);
delegate(kv.first, *kv.second, overrideAttr);
}
}
} // namespace gfx
} // namespace mbgl

View File

@@ -14,15 +14,16 @@ public:
virtual ~VertexBufferResource() = default;
};
// This class has a template argument that we use to specify the vertex type. It
// is not used by the implementation, but serves type checking purposes during
// build time.
using UniqueVertexBufferResource = std::unique_ptr<VertexBufferResource>;
// This class has a template argument that we use to specify the vertex type. It is not used by
// the implementation, but serves type checking purposes during build time.
template <class>
class VertexBuffer {
public:
VertexBuffer(const std::size_t elements_, std::unique_ptr<VertexBufferResource>&& resource_)
: elements(elements_),
resource(std::move(resource_)) {}
VertexBuffer(const std::size_t elements_, UniqueVertexBufferResource&& resource_)
: elements(elements_), resource(std::move(resource_)) {
}
std::size_t elements;
@@ -33,7 +34,7 @@ public:
}
protected:
std::unique_ptr<VertexBufferResource> resource;
UniqueVertexBufferResource resource;
};
} // namespace gfx

View File

@@ -163,8 +163,10 @@ private:
UniqueFramebuffer createFramebuffer();
std::unique_ptr<uint8_t[]> readFramebuffer(Size, gfx::TexturePixelType, bool flip);
public:
VertexArray createVertexArray();
private:
friend detail::ProgramDeleter;
friend detail::ShaderDeleter;
friend detail::BufferDeleter;

View File

@@ -0,0 +1,42 @@
#include <mbgl/gl/drawable_gl.hpp>
#include <mbgl/gl/drawable_gl_impl.hpp>
namespace mbgl {
namespace gl {
DrawableGL::DrawableGL()
: impl(std::make_unique<Impl>()) {
}
DrawableGL::~DrawableGL() {
}
void DrawableGL::draw(const PaintParameters &parameters) const
{
impl->draw(parameters);
}
void DrawableGL::setVertData(std::vector<std::uint8_t> vertexData_,
std::vector<std::uint16_t> indexes_) {
impl->vertData = std::move(vertexData_);
impl->indexes = std::move(indexes_);
}
std::vector<std::uint16_t>& DrawableGL::getIndexData() const {
return impl->indexes;
}
const gl::VertexArray& DrawableGL::getVertexArray() const {
return impl->vertexArray;
}
void DrawableGL::setVertexArray(gl::VertexArray&& vertexArray_,
gfx::UniqueVertexBufferResource&& attributeBuffer_,
gfx::IndexBuffer&& indexBuffer_) {
impl->vertexArray = std::move(vertexArray_);
impl->attributeBuffer = std::move(attributeBuffer_);
impl->indexBuffer = std::move(indexBuffer_);
}
} // namespace gl
} // namespace mbgl

View File

@@ -0,0 +1,36 @@
#include <mbgl/gl/drawable_gl_builder.hpp>
#include <mbgl/gfx/drawable_builder_impl.hpp>
#include <mbgl/gl/drawable_gl.hpp>
namespace mbgl {
namespace gl {
gfx::DrawablePtr DrawableGLBuilder::createDrawable() const {
return std::make_shared<DrawableGL>();
};
void DrawableGLBuilder::init() {
const auto n = impl->vertices.elements();
assert(n <= impl->indexes.elements());
assert(n == impl->colors.size());
// temp
const auto vertSize = sizeof(Impl::VT) + 4 * sizeof(float);
std::vector<uint8_t> rawVert(n * vertSize);
auto p = &rawVert[0];
for (auto i = 0ULL; i < n; ++i) {
*(Impl::VT*)p = impl->vertices.at(i); p += sizeof(Impl::VT);
*(float*)p = impl->colors[i].r; p += sizeof(float);
*(float*)p = impl->colors[i].g; p += sizeof(float);
*(float*)p = impl->colors[i].b; p += sizeof(float);
*(float*)p = impl->colors[i].a; p += sizeof(float);
}
((DrawableGL*)currentDrawable.get())->setVertData(std::move(rawVert), impl->indexes.vector());
}
} // namespace gl
} // namespace mbgl

View File

@@ -0,0 +1,66 @@
#pragma once
#include <mbgl/gfx/drawable.hpp>
#include <mbgl/gfx/index_buffer.hpp>
#include <mbgl/gfx/program.hpp>
#include <mbgl/gfx/uniform.hpp>
#include <mbgl/gl/defines.hpp>
#include <mbgl/gl/enum.hpp>
#include <mbgl/gl/program.hpp>
#include <mbgl/gl/vertex_array.hpp>
#include <mbgl/platform/gl_functions.hpp>
#include <mbgl/util/mat4.hpp>
#include <cstdint>
#include <memory>
#include <vector>
namespace mbgl {
namespace gl {
using namespace platform;
class DrawableGL::Impl final {
public:
Impl() {
}
~Impl() = default;
void draw(const PaintParameters& /*parameters*/) const {
MBGL_CHECK_ERROR(glDrawElements(
Enum<gfx::DrawModeType>::to(type),
static_cast<GLsizei>(indexLength),
GL_UNSIGNED_SHORT,
reinterpret_cast<GLvoid*>(sizeof(uint16_t) * indexOffset)));
}
const gfx::DrawModeType type = gfx::DrawModeType::Triangles;
ShaderID shaderId;
RenderbufferID renderTarget;
std::vector<TextureID> textures;
std::vector<std::uint8_t> vertData;
std::vector<std::uint16_t> indexes;
VertexArray vertexArray = { { nullptr, false } };
gfx::IndexBuffer indexBuffer = { 0, nullptr };
gfx::UniqueVertexBufferResource attributeBuffer;
std::size_t indexOffset = 0;
std::size_t indexLength = 0;
mat4 matrix;
gfx::DepthMode depthMode = gfx::DepthMode::disabled();
gfx::StencilMode stencilMode;
gfx::ColorMode colorMode;
gfx::CullFaceMode cullFaceMode;
//gfx::UniformValues<typename Program<>::UniformList> uniformValues;
//Segment<Program<>::AttributeList> segment;
//gfx::AttributeBindings<Program<>::AttributeList> attributeBindings;
//gfx::TextureBindings<Program<>::TextureList> textureBindings;
GLfloat pointSize = 0.0f;
};
} // namespace gl
} // namespace mbgl

View File

@@ -0,0 +1,16 @@
#include <mbgl/gl/drawable_gl_tweaker.hpp>
#include <mbgl/gl/drawable_gl.hpp>
#include <mbgl/renderer/paint_parameters.hpp>
namespace mbgl {
namespace gl {
void DrawableGLTweaker::execute(gfx::Drawable& drawable, const PaintParameters &) {
auto& drawGL = (gl::DrawableGL&)drawable;
// apply expressions based on current state, update attributes, uniforms, etc.
drawGL.getId();
}
} // namespace gl
} // namespace mbgl

View File

@@ -3,10 +3,13 @@
#include <mbgl/gl/enum.hpp>
#include <mbgl/gl/defines.hpp>
#include <mbgl/gl/command_encoder.hpp>
#include <mbgl/gl/vertex_attribute_gl.hpp>
#include <mbgl/gl/vertex_buffer_resource.hpp>
#include <mbgl/gl/index_buffer_resource.hpp>
#include <mbgl/gl/texture_resource.hpp>
#include <algorithm>
namespace mbgl {
namespace gl {
@@ -119,6 +122,54 @@ void UploadPass::updateTextureResourceSub(gfx::TextureResource& resource,
data));
}
std::pair<gfx::AttributeBindingArray, std::unique_ptr<gfx::VertexBufferResource>>
UploadPass::buildAttributeBindings(const gfx::VertexAttributeArray& defaults,
const gfx::VertexAttributeArray& overrides,
const gfx::BufferUsageType usage) {
AttributeBindingArray bindings;
bindings.reserve(defaults.size());
std::vector<std::uint8_t> allData;
constexpr auto ExpectedSize = 32;
allData.reserve(defaults.size() * ExpectedSize);
defaults.resolve(overrides, [&](const std::string& /*name*/,
const gfx::VertexAttribute& defaultAttr,
const gfx::VertexAttribute* overrideAttr) {
const auto& effectiveAttr = *(overrideAttr ? overrideAttr : &defaultAttr);
const auto& effectiveGL = static_cast<const gl::VertexAttributeGL&>(effectiveAttr);
const auto& defaultGL = static_cast<const gl::VertexAttributeGL&>(defaultAttr);
// Pad to 16 bytes
allData.insert(allData.end(), 16 - allData.size() % 16, 0);
const auto offset = static_cast<uint8_t>(allData.size());
bindings.emplace_back(gfx::AttributeBinding{
gfx::AttributeDescriptor{ defaultAttr.getDataType(), offset },
static_cast<uint8_t>(effectiveGL.getStride()),
nullptr, // buffer pointer established later
static_cast<uint32_t>(defaultGL.getIndex())
});
const auto& rawData = effectiveGL.getRaw();
allData.insert(allData.begin(), rawData.begin(), rawData.end());
});
auto vertBuf = createVertexBufferResource(&allData[0], allData.size(), usage);
// Assign to each element
std::for_each(bindings.begin(), bindings.end(), [&](auto& b){ b->vertexBufferResource = vertBuf.get(); });
gfx::AttributeBindingArray& a = bindings;
std::unique_ptr<gfx::VertexBufferResource>& b = vertBuf;
return std::make_pair(std::move(a), std::move(b));
//return std::make_pair(bindings, vertBuf);
}
void UploadPass::pushDebugGroup(const char* name) {
commandEncoder.pushDebugGroup(name);
}

View File

@@ -1,6 +1,7 @@
#pragma once
#include <mbgl/gfx/upload_pass.hpp>
#include <mbgl/gl/types.hpp>
namespace mbgl {
namespace gfx {
@@ -13,6 +14,7 @@ namespace gl {
class CommandEncoder;
class Context;
class VertexArray;
class UploadPass final : public gfx::UploadPass {
public:
@@ -32,6 +34,11 @@ public:
gfx::BufferUsageType) override;
void updateIndexBufferResource(gfx::IndexBufferResource&, const void* data, std::size_t size) override;
std::pair<gfx::AttributeBindingArray, std::unique_ptr<gfx::VertexBufferResource>>
buildAttributeBindings(const gfx::VertexAttributeArray& defaults,
const gfx::VertexAttributeArray& overrides,
gfx::BufferUsageType) override;
public:
std::unique_ptr<gfx::TextureResource> createTextureResource(Size,
const void* data,

View File

@@ -57,10 +57,21 @@ using UniqueVertexArrayState = std::unique_ptr<VertexArrayState, VertexArrayStat
class VertexArray {
public:
VertexArray(UniqueVertexArrayState state_)
: state(std::move(state_)) {}
: state(std::move(state_)) {
}
VertexArray(VertexArray&& other)
: state(std::move(other.state)) {
}
void bind(Context&, const gfx::IndexBuffer&, const AttributeBindingArray&);
VertexArray& operator=(VertexArray&& other) {
state = std::move(other.state);
return *this;
}
bool isValid() const { return state.operator bool(); }
private:
UniqueVertexArrayState state;
};

View File

@@ -0,0 +1,74 @@
#include <mbgl/gl/vertex_attribute_gl.hpp>
#include <mbgl/gl/defines.hpp>
#include <cstring>
namespace mbgl {
namespace gl {
class VertexAttributeArrayGL;
using namespace platform;
static std::pair<int,int> getSizeAndStride(GLenum glType) {
switch (glType) {
case GL_FLOAT: return { 4*1, 4*1 };
case GL_FLOAT_VEC2: return { 4*2, 4*2 };
case GL_FLOAT_VEC3: return { 4*3, 4*4 };
case GL_FLOAT_VEC4: return { 4*4, 4*4 };
case GL_FLOAT_MAT2: return { 4*4, 4*4 };
case GL_INT: return { 4*1, 4*1 };
case GL_UNSIGNED_INT: return { 4*1, 4*1 };
case GL_INT_VEC2: return { 4*2, 4*2 };
case GL_INT_VEC3: return { 4*3, 4*4 };
case GL_INT_VEC4: return { 4*4, 4*4 };
default: return { 0, 0 };
}
}
static const void* getPtr(const gfx::VertexAttribute::ElementType& element, GLenum glType) {
switch (glType) {
case GL_FLOAT:
case GL_FLOAT_VEC2:
case GL_FLOAT_VEC3:
case GL_FLOAT_VEC4:
case GL_FLOAT_MAT2: return std::get_if<float>(&element);
case GL_INT:
case GL_UNSIGNED_INT:
case GL_INT_VEC2:
case GL_INT_VEC3:
case GL_INT_VEC4: return std::get_if<int>(&element);
default: return nullptr;
}
}
const std::vector<uint8_t>& VertexAttributeGL::getRaw() const {
if (dirty) {
const auto count = getCount();
const auto sizes = getSizeAndStride(getGLType());
stride = sizes.second;
rawData.resize(stride * count);
std::fill(rawData.begin(), rawData.end(), 0);
if (rawData.size() > 0) {
std::uint8_t* outPtr = &rawData[0];
for (std::size_t i = 0; i < count; ++i) {
if (const auto rawPtr = getPtr(items[i], getGLType())) {
std::memcpy(outPtr, rawPtr, sizes.first);
}
outPtr += stride;
}
}
dirty = false;
}
return rawData;
}
} // namespace gfx
} // namespace mbgl

View File

View File

View File

View File

@@ -0,0 +1,14 @@
#include <mbgl/renderer/change_request.hpp>
#include <mbgl/renderer/render_orchestrator.hpp>
namespace mbgl {
void AddDrawableRequest::execute(RenderOrchestrator &orchestrator) {
orchestrator.addDrawable(std::move(drawable));
}
void RemoveDrawableRequest::execute(RenderOrchestrator &orchestrator) {
orchestrator.removeDrawable(drawableId);
}
} // namespace mbgl

View File

@@ -1,16 +1,19 @@
#include <mbgl/gfx/cull_face_mode.hpp>
#include <mbgl/gfx/shader_registry.hpp>
#include <mbgl/renderer/layers/render_background_layer.hpp>
#include <mbgl/style/layers/background_layer_impl.hpp>
#include <mbgl/renderer/bucket.hpp>
#include <mbgl/renderer/change_request.hpp>
#include <mbgl/renderer/upload_parameters.hpp>
#include <mbgl/renderer/paint_parameters.hpp>
#include <mbgl/renderer/pattern_atlas.hpp>
#include <mbgl/renderer/image_manager.hpp>
#include <mbgl/renderer/render_static_data.hpp>
#include <mbgl/programs/programs.hpp>
#include <mbgl/shaders/gl/shader_program_gl.hpp>
#include <mbgl/util/tile_cover.hpp>
#include <mbgl/map/transform_state.hpp>
#include <mbgl/gfx/cull_face_mode.hpp>
#include <mbgl/gfx/shader_registry.hpp>
#include <mbgl/util/logging.hpp>
namespace mbgl {
@@ -35,10 +38,12 @@ void RenderBackgroundLayer::transition(const TransitionParameters& parameters) {
unevaluated = impl_cast(baseImpl).paint.transitioned(parameters, std::move(unevaluated));
}
void RenderBackgroundLayer::evaluate(const PropertyEvaluationParameters& parameters) {
auto properties = makeMutable<BackgroundLayerProperties>(staticImmutableCast<BackgroundLayer::Impl>(baseImpl),
parameters.getCrossfadeParameters(),
unevaluated.evaluate(parameters));
void RenderBackgroundLayer::evaluate(
const PropertyEvaluationParameters &parameters) {
auto properties = makeMutable<BackgroundLayerProperties>(
staticImmutableCast<BackgroundLayer::Impl>(baseImpl),
parameters.getCrossfadeParameters(),
unevaluated.evaluate(parameters));
passes = properties->evaluated.get<style::BackgroundOpacity>() == 0.0f ? RenderPass::None
: (!unevaluated.get<style::BackgroundPattern>().isUndefined() ||
@@ -159,7 +164,8 @@ std::optional<Color> RenderBackgroundLayer::getSolidBackground() const {
return std::nullopt;
}
return {evaluated.get<BackgroundColor>() * evaluated.get<BackgroundOpacity>()};
return std::nullopt;
//return { evaluated.get<BackgroundColor>() * evaluated.get<BackgroundOpacity>() };
}
namespace {

View File

@@ -5,8 +5,19 @@
#include <mbgl/style/layers/background_layer_impl.hpp>
#include <mbgl/style/layers/background_layer_properties.hpp>
#include <optional>
#include <memory>
#include <vector>
namespace mbgl {
namespace gfx {
class Drawable;
using DrawablePtr = std::shared_ptr<Drawable>;
} // namespace gfc
class ChangeRequest;
class RenderBackgroundLayer final : public RenderLayer {
public:
explicit RenderBackgroundLayer(Immutable<style::BackgroundLayer::Impl>);

View File

@@ -1,3 +1,4 @@
#include <mbgl/renderer/change_request.hpp>
#include <mbgl/renderer/render_layer.hpp>
#include <mbgl/renderer/paint_parameters.hpp>
#include <mbgl/renderer/render_source.hpp>

View File

@@ -1,5 +1,6 @@
#pragma once
#include <list>
#include <mbgl/gfx/drawable.hpp>
#include <mbgl/layout/layout.hpp>
#include <mbgl/renderer/render_pass.hpp>
#include <mbgl/renderer/render_source.hpp>
@@ -12,6 +13,7 @@
namespace mbgl {
class Bucket;
class ChangeRequest;
class TransitionParameters;
class PropertyEvaluationParameters;
class UploadParameters;
@@ -147,6 +149,8 @@ protected:
LayerPlacementData placementData;
gfx::DrawablePtr drawables;
private:
// Some layers may not render correctly on some hardware when the vertex
// attribute limit of that GPU is exceeded. More attributes are used when

View File

@@ -2,6 +2,7 @@
#include <mbgl/annotation/annotation_manager.hpp>
#include <mbgl/layermanager/layer_manager.hpp>
#include <mbgl/renderer/change_request.hpp>
#include <mbgl/renderer/renderer_observer.hpp>
#include <mbgl/renderer/render_source.hpp>
#include <mbgl/renderer/render_layer.hpp>
@@ -137,6 +138,10 @@ void RenderOrchestrator::setObserver(RendererObserver* observer_) {
std::unique_ptr<RenderTree> RenderOrchestrator::createRenderTree(
const std::shared_ptr<UpdateParameters>& updateParameters) {
layersAdded.clear();
layersRemoved.clear();
const bool isMapModeContinuous = updateParameters->mode == MapMode::Continuous;
if (!isMapModeContinuous) {
// Reset zoom history state.
@@ -217,7 +222,7 @@ std::unique_ptr<RenderTree> RenderOrchestrator::createRenderTree(
imageManager->notifyIfMissingImageAdded();
imageManager->setLoaded(updateParameters->spriteLoaded);
const LayerDifference layerDiff = diffLayers(layerImpls, updateParameters->layers);
LayerDifference layerDiff = diffLayers(layerImpls, updateParameters->layers);
layerImpls = updateParameters->layers;
const bool layersAddedOrRemoved = !layerDiff.added.empty() || !layerDiff.removed.empty();
@@ -452,6 +457,9 @@ std::unique_ptr<RenderTree> RenderOrchestrator::createRenderTree(
}
}
layersAdded = std::move(layerDiff.added);
layersRemoved = std::move(layerDiff.removed);
return std::make_unique<RenderTreeImpl>(std::move(renderTreeParameters),
std::move(layerRenderItems),
std::move(sourceRenderItems),
@@ -711,13 +719,18 @@ bool RenderOrchestrator::hasTransitions(TimePoint timePoint) const {
}
bool RenderOrchestrator::isLoaded() const {
for (const auto& entry : renderSources) {
// do the simple boolean check before iterating over all the tiles in all the sources
if (!imageManager->isLoaded()) {
return false;
}
for (const auto& entry: renderSources) {
if (!entry.second->isLoaded()) {
return false;
}
}
return imageManager->isLoaded();
return true;
}
void RenderOrchestrator::clearData() {
@@ -737,13 +750,59 @@ void RenderOrchestrator::clearData() {
glyphManager->evict(fontStacks(*layerImpls));
}
void RenderOrchestrator::onGlyphsError(const FontStack& fontStack,
const GlyphRange& glyphRange,
std::exception_ptr error) {
Log::Error(Event::Style,
"Failed to load glyph range " + std::to_string(glyphRange.first) + "-" +
std::to_string(glyphRange.second) + " for font stack " + fontStackToString(fontStack) + ": " +
util::toString(error));
void RenderOrchestrator::update(const std::shared_ptr<UpdateParameters>& parameters) {
if (!parameters) {
return;
}
// TODO: Removed layers need a chance to remove their drawables
std::vector<std::unique_ptr<ChangeRequest>> changes;
for (auto& layer : *parameters->layers) {
layer->update(changes);
addChanges(changes);
}
}
void RenderOrchestrator::addChanges(UniqueChangeRequestVec& changes) {
pendingChanges.insert(pendingChanges.end(),
std::make_move_iterator(changes.begin()),
std::make_move_iterator(changes.end()));
changes.clear();
}
void RenderOrchestrator::addDrawable(gfx::DrawablePtr drawable) {
if (drawable) {
const auto id = drawable->getId();
drawables.insert(std::make_pair(id, std::move(drawable)));
}
}
void RenderOrchestrator::removeDrawable(const util::SimpleIdentity& drawableId) {
drawables.erase(drawableId);
}
void RenderOrchestrator::updateLayers(PaintParameters& parameters) {
std::vector<std::unique_ptr<ChangeRequest>> changes;
for (auto& kv : layersRemoved) {
kv.second->layerRemoved(parameters, changes);
addChanges(changes);
}
for (auto& kv : layersAdded) {
kv.second->layerAdded(parameters, changes);
addChanges(changes);
}
}
void RenderOrchestrator::processChanges() {
auto localChanges = std::move(pendingChanges);
for (auto &change : localChanges) {
change->execute(*this);
}
}
void RenderOrchestrator::onGlyphsError(const FontStack& fontStack, const GlyphRange& glyphRange, std::exception_ptr error) {
Log::Error(Event::Style, "Failed to load glyph range " + std::to_string(glyphRange.first) + "-" + std::to_string(glyphRange.second) +
" for font stack " + fontStackToString(fontStack) + ": " + util::toString(error));
observer->onResourceError(error);
}

View File

@@ -15,10 +15,12 @@
#include <memory>
#include <string>
#include <unordered_map>
#include <vector>
namespace mbgl {
class ChangeRequest;
class RendererObserver;
class RenderSource;
class UpdateParameters;
@@ -32,11 +34,20 @@ class PatternAtlas;
class CrossTileSymbolIndex;
class RenderTree;
namespace gfx {
class Drawable;
using DrawablePtr = std::shared_ptr<Drawable>;
} // namespace gfx
namespace style {
class LayerProperties;
} // namespace style
class RenderOrchestrator final : public GlyphManagerObserver, public ImageManagerObserver, public RenderSourceObserver {
using ImmutableLayer = Immutable<style::Layer::Impl>;
class RenderOrchestrator final : public GlyphManagerObserver,
public ImageManagerObserver,
public RenderSourceObserver {
public:
RenderOrchestrator(bool backgroundLayerAsColor_, const std::optional<std::string>& localFontFamily_);
~RenderOrchestrator() override;
@@ -78,6 +89,18 @@ public:
const std::vector<PlacedSymbolData>& getPlacedSymbolsData() const;
void clearData();
void update(const std::shared_ptr<UpdateParameters>&);
using DrawableMap = std::map<util::SimpleIdentity, gfx::DrawablePtr>;
const DrawableMap& getDrawables() const { return drawables; }
void addDrawable(gfx::DrawablePtr);
void removeDrawable(const util::SimpleIdentity& drawableId);
void updateLayers(PaintParameters&);
void processChanges();
private:
bool isLoaded() const;
bool hasTransitions(TimePoint) const;
@@ -107,6 +130,9 @@ private:
void onStyleImageMissing(const std::string&, const std::function<void()>&) override;
void onRemoveUnusedStyleImages(const std::vector<std::string>&) override;
/// Move changes into the pending set, clearing the provided collection
void addChanges(UniqueChangeRequestVec&);
RendererObserver* observer;
ZoomHistory zoomHistory;
@@ -125,6 +151,10 @@ private:
std::unordered_map<std::string, std::unique_ptr<RenderLayer>> renderLayers;
RenderLight renderLight;
// Layers added and removed in the last update
std::unordered_map<std::string, ImmutableLayer> layersAdded;
std::unordered_map<std::string, ImmutableLayer> layersRemoved;
CrossTileSymbolIndex crossTileSymbolIndex;
PlacementController placementController;
@@ -137,6 +167,10 @@ private:
std::vector<Immutable<style::LayerProperties>> filteredLayersForSource;
RenderLayerReferences orderedLayers;
RenderLayerReferences layersNeedPlacement;
protected:
DrawableMap drawables;
std::vector<std::unique_ptr<ChangeRequest>> pendingChanges;
};
} // namespace mbgl

View File

@@ -1,5 +1,6 @@
#pragma once
#include <mbgl/gfx/drawable.hpp>
#include <mbgl/renderer/paint_parameters.hpp>
#include <cassert>

View File

@@ -129,6 +129,10 @@ const std::vector<PlacedSymbolData>& Renderer::getPlacedSymbolsData() const {
return impl->orchestrator.getPlacedSymbolsData();
}
void Renderer::update(const std::shared_ptr<UpdateParameters>& parameters) {
impl->orchestrator.update(parameters);
}
void Renderer::reduceMemoryUse() {
gfx::BackendScope guard{impl->backend};
impl->reduceMemoryUse();

View File

@@ -2,17 +2,20 @@
#include <mbgl/geometry/line_atlas.hpp>
#include <mbgl/gfx/backend_scope.hpp>
#include <mbgl/gfx/renderer_backend.hpp>
#include <mbgl/gfx/upload_pass.hpp>
#include <mbgl/gfx/render_pass.hpp>
#include <mbgl/gfx/cull_face_mode.hpp>
#include <mbgl/gfx/context.hpp>
#include <mbgl/gfx/cull_face_mode.hpp>
#include <mbgl/gfx/drawable_tweaker.hpp>
#include <mbgl/gfx/render_pass.hpp>
#include <mbgl/gfx/renderer_backend.hpp>
#include <mbgl/gfx/renderable.hpp>
#include <mbgl/gfx/upload_pass.hpp>
#include <mbgl/gl/drawable_gl.hpp>
#include <mbgl/programs/programs.hpp>
#include <mbgl/renderer/pattern_atlas.hpp>
#include <mbgl/renderer/renderer_observer.hpp>
#include <mbgl/renderer/render_static_data.hpp>
#include <mbgl/renderer/render_tree.hpp>
#include <mbgl/shaders/gl/shader_program_gl.hpp>
#include <mbgl/util/string.hpp>
#include <mbgl/util/logging.hpp>
@@ -73,6 +76,8 @@ void Renderer::Impl::render(const RenderTree& renderTree) {
renderTree.getLineAtlas(),
renderTree.getPatternAtlas()};
orchestrator.updateLayers(parameters);
parameters.symbolFadeChange = renderTreeParameters.symbolFadeChange;
parameters.opaquePassCutoff = renderTreeParameters.opaquePassCutOff;
const auto& sourceRenderItems = renderTree.getSourceRenderItems();
@@ -93,6 +98,47 @@ void Renderer::Impl::render(const RenderTree& renderTree) {
staticData->upload(*uploadPass);
renderTree.getLineAtlas().upload(*uploadPass);
renderTree.getPatternAtlas().upload(*uploadPass);
for (const auto& pair : orchestrator.getDrawables()) {
auto& drawable = *pair.second;
// Run tweakers to update any dynamic elements
for (auto& tweaker : drawable.getTweakers()) {
tweaker->execute(drawable, parameters);
}
// 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;
// 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);
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));
}
}
}
}
// - 3D PASS
@@ -143,6 +189,27 @@ void Renderer::Impl::render(const RenderTree& renderTree) {
parameters.depthRangeSize = 1 - (layerRenderItems.size() + 2) * parameters.numSublayers * parameters.depthEpsilon;
// Run changes
orchestrator.processChanges();
// Draw Drawables
{
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)
drawable.draw(parameters);
}
}
// - OPAQUE PASS -------------------------------------------------------------------------------
// Render everything top-to-bottom by using reverse iterators. Render opaque objects first.
{

View File

@@ -0,0 +1,118 @@
#include <mbgl/shaders/gl/shader_program_gl.hpp>
#include <mbgl/gl/defines.hpp>
#include <mbgl/gl/types.hpp>
#include <mbgl/gl/vertex_attribute_gl.hpp>
#include <mbgl/platform/gl_functions.hpp>
#include <utility>
namespace mbgl {
namespace gl {
static gfx::AttributeDataType mapType(platform::GLenum attrType) {
using T = gfx::AttributeDataType;
switch (attrType) {
case GL_FLOAT: return T::Float;
case GL_FLOAT_VEC2: return T::Float2;
case GL_FLOAT_VEC3: return T::Float3;
case GL_FLOAT_VEC4: return T::Float4;
case GL_FLOAT_MAT2: return T::Float4; // does that work ?
case GL_FLOAT_MAT3:
case GL_FLOAT_MAT4: return T::Invalid;
case GL_INT: return T::Int;
case GL_INT_VEC2: return T::Int2;
case GL_INT_VEC3: return T::Int3;
case GL_INT_VEC4: return T::Int4;
case GL_UNSIGNED_INT: return T::UInt;
// ES3 stuff that isn't defined yet:
//case GL_FLOAT_MAT2x3:
//case GL_FLOAT_MAT2x4:
//case GL_FLOAT_MAT3x2:
//case GL_FLOAT_MAT3x4:
//case GL_FLOAT_MAT4x2:
//case GL_FLOAT_MAT4x3: return T::Invalid;
//case GL_UNSIGNED_INT_VEC2: return T::UInt2;
//case GL_UNSIGNED_INT_VEC3: return T::UInt3;
//case GL_UNSIGNED_INT_VEC4: return T::UInt4;
//case GL_DOUBLE: return T::Float;
//case GL_DOUBLE_VEC2: return T::Float2;
//case GL_DOUBLE_VEC3: return T::Float3;
//case GL_DOUBLE_VEC4: return T::Float4;
//case GL_DOUBLE_MAT2: return T::Float4;
//case GL_DOUBLE_MAT3:
//case GL_DOUBLE_MAT4:
//case GL_DOUBLE_MAT2x3:
//case GL_DOUBLE_MAT2x4:
//case GL_DOUBLE_MAT3x2:
//case GL_DOUBLE_MAT3x4:
//case GL_DOUBLE_MAT4x2:
//case GL_DOUBLE_MAT4x3:
default: return T::Invalid;
}
}
ShaderProgramGL::ShaderProgramGL(UniqueProgram&& glProgram_)
: ShaderProgramBase(),
glProgram(std::move(glProgram_)) {
}
ShaderProgramGL::ShaderProgramGL(ShaderProgramGL&& other)
: ShaderProgramBase(std::forward<ShaderProgramBase&&>(other)),
glProgram(std::move(other.glProgram)) {
}
std::shared_ptr<ShaderProgramGL> ShaderProgramGL::create(
Context& context,
std::string_view /*name*/,
std::string_view vertexSource,
std::string_view fragmentSource) noexcept(false) {
const auto firstAttrib = "pos";
// throws on compile error
auto vertProg = context.createShader(ShaderType::Vertex, std::initializer_list<const char*>{vertexSource.data()});
auto fragProg = context.createShader(ShaderType::Fragment, std::initializer_list<const char*>{fragmentSource.data()});
auto program = context.createProgram(vertProg, fragProg, firstAttrib);
using namespace platform;
// ES3
//GLint numAttribs;
//glGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, &numAttribs);
GLint count;
GLint maxLength;
MBGL_CHECK_ERROR(glGetProgramiv(program, GL_ACTIVE_UNIFORMS, &count));
MBGL_CHECK_ERROR(glGetProgramiv(program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxLength));
auto name = std::make_unique<GLchar[]>(maxLength);
for (GLint index = 0; index < count; ++index) {
GLsizei length = 0;
GLint size = 0;
GLenum type = 0;
MBGL_CHECK_ERROR(glGetActiveUniform(program, index, maxLength, &length, &size, &type, name.get()));
}
VertexAttributeArrayGL attrs;
MBGL_CHECK_ERROR(glGetProgramiv(program, GL_ACTIVE_ATTRIBUTES, &count));
MBGL_CHECK_ERROR(glGetProgramiv(program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &maxLength));
for (GLint index = 0; index < count; ++index) {
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.get()));
const auto elementType = mapType(glType);
if (elementType != gfx::AttributeDataType::Invalid && length > 0) {
if (auto newAttr = attrs.add(name.get(), index, elementType, size)) {
static_cast<VertexAttributeGL*>(newAttr)->setGLType(glType);
}
}
}
return std::make_shared<ShaderProgramGL>(std::move(program));
}
} // namespace gl
} // namespace mbgl

View File

@@ -0,0 +1,11 @@
#include <mbgl/shaders/mtl/shader_program_mtl.hpp>
namespace mbgl {
namespace mtl {
//bool ShaderProgramMTL::compile(std::string_view vert, std::string_view frag) {
// return false;
//}
} // namespace mtl
} // namespace mbgl

View File

@@ -0,0 +1,4 @@
#include <mbgl/shaders/shader_program_base.hpp>
#include <mbgl/gfx/vertex_attribute.hpp>

View File

@@ -7,11 +7,19 @@
#include <rapidjson/writer.h>
#include <rapidjson/stringbuffer.h>
#include <string>
#include <limits>
#include <memory>
#include <string>
#include <vector>
namespace mbgl {
class ChangeRequest;
class PaintParameters;
using UniqueChangeRequest = std::unique_ptr<ChangeRequest>;
using UniqueChangeRequestVec = std::vector<UniqueChangeRequest>;
namespace style {
/**
@@ -47,6 +55,12 @@ public:
// Populates the given \a fontStack with fonts being used by the layer.
virtual void populateFontStack(std::set<FontStack>& fontStack) const;
/// Generate any changes needed by the layer
virtual void update(UniqueChangeRequestVec&) const { }
virtual void layerAdded(PaintParameters&, UniqueChangeRequestVec&) const { }
virtual void layerRemoved(PaintParameters&, UniqueChangeRequestVec&) const { }
std::string id;
std::string source;
std::string sourceLayer;

View File

@@ -1,5 +1,14 @@
#include <mbgl/style/layers/background_layer_impl.hpp>
#include <mbgl/gfx/shader_registry.hpp>
#include <mbgl/gl/context.hpp>
#include <mbgl/gl/drawable_gl_builder.hpp>
#include <mbgl/gl/drawable_gl_tweaker.hpp>
#include <mbgl/renderer/change_request.hpp>
#include <mbgl/renderer/paint_parameters.hpp>
#include <mbgl/shaders/gl/shader_program_gl.hpp>
#include <mbgl/util/logging.hpp>
namespace mbgl {
namespace style {
@@ -7,5 +16,99 @@ bool BackgroundLayer::Impl::hasLayoutDifference(const Layer::Impl&) const {
return false;
}
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;
}
}
buildDrawables(changes);
}
void BackgroundLayer::Impl::layerRemoved(PaintParameters&, UniqueChangeRequestVec& changes) const {
if (drawable) {
changes.emplace_back(std::make_unique<RemoveDrawableRequest>(drawable->getId()));
drawable.reset();
}
}
void BackgroundLayer::Impl::buildDrawables(UniqueChangeRequestVec& changes) const {
auto builder = std::make_unique<gl::DrawableGLBuilder>(); // from GL-specific code via virtual method?
builder->setShaderID(shaderName);
builder->addTweaker(std::make_shared<gl::DrawableGLTweaker>()); // generally shared across drawables
builder->addQuad(0, 0, util::EXTENT, util::EXTENT);
builder->flush();
changes.reserve(builder->getDrawables().size());
for (auto &draw : builder->clearDrawables()) {
drawable = draw;
changes.emplace_back(std::make_unique<AddDrawableRequest>(std::move(draw)));
}
}
void BackgroundLayer::Impl::update(UniqueChangeRequestVec& changes) const {
if (!drawable /* && visible/enabled */) {
buildDrawables(changes);
// } else if (drawable && !visible/enabled) {
// changes.emplace_back(std::make_unique<RemoveDrawableRequest>(drawable->getId()));
// drawable.reset();
}
}
} // namespace style
} // namespace mbgl

View File

@@ -4,7 +4,16 @@
#include <mbgl/style/layers/background_layer.hpp>
#include <mbgl/style/layers/background_layer_properties.hpp>
#include <memory>
namespace mbgl {
namespace gfx {
class Drawable;
using DrawablePtr = std::shared_ptr<Drawable>;
} // namespace gfx
namespace style {
class BackgroundLayer::Impl : public Layer::Impl {
@@ -14,8 +23,20 @@ public:
bool hasLayoutDifference(const Layer::Impl&) const override;
void stringifyLayout(rapidjson::Writer<rapidjson::StringBuffer>&) const override;
void layerAdded(PaintParameters&, UniqueChangeRequestVec&) const override;
void layerRemoved(PaintParameters&, UniqueChangeRequestVec&) const override;
/// Generate any changes needed by the layer
void update(UniqueChangeRequestVec& changes) const override;
private:
void buildDrawables(UniqueChangeRequestVec&) const;
public:
BackgroundPaintProperties::Transitionable paint;
mutable gfx::DrawablePtr drawable;
DECLARE_LAYER_TYPE_INFO;
};

View File

@@ -0,0 +1,23 @@
#include <mbgl/util/identity.hpp>
#include <atomic>
namespace {
// This is not in the class declaration to minimize include dependencies
static std::atomic<std::int64_t> nextId = 1;
} // anonymous namespace
namespace mbgl {
namespace util {
const SimpleIdentity SimpleIdentity::Empty = {emptyID};
SimpleIdentity::SimpleIdentity()
: uniqueID(nextId++)
{
}
} // namespace util
} // namespace mbgl