Merge remote-tracking branch 'origin' into linux-ci
This commit is contained in:
@@ -1114,6 +1114,7 @@ if(MLN_WITH_OPENGL)
|
||||
list(APPEND INCLUDE_FILES
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/background_layer_ubo.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/circle_layer_ubo.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/collision_layer_ubo.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/fill_layer_ubo.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/fill_extrusion_layer_ubo.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/heatmap_layer_ubo.hpp
|
||||
@@ -1178,6 +1179,8 @@ if(MBGL_WITH_METAL)
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/mtl/circle.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/mtl/clipping_mask.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/mtl/common.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/mtl/collision_box.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/mtl/collision_circle.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/mtl/fill.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/mtl/fill_extrusion.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/mtl/fill_extrusion_pattern.hpp
|
||||
@@ -1214,6 +1217,25 @@ if(MBGL_WITH_METAL)
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/mtl/upload_pass.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/mtl/vertex_attribute.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/shaders/mtl/shader_program.cpp
|
||||
${PROJECT_SOURCE_DIR}src/mbgl/shaders/mtl/background.cpp
|
||||
${PROJECT_SOURCE_DIR}src/mbgl/shaders/mtl/background_pattern.cpp
|
||||
${PROJECT_SOURCE_DIR}src/mbgl/shaders/mtl/circle.cpp
|
||||
${PROJECT_SOURCE_DIR}src/mbgl/shaders/mtl/collision_box.cpp
|
||||
${PROJECT_SOURCE_DIR}src/mbgl/shaders/mtl/collision_circle.cpp
|
||||
${PROJECT_SOURCE_DIR}src/mbgl/shaders/mtl/clipping_mask.cpp
|
||||
${PROJECT_SOURCE_DIR}src/mbgl/shaders/mtl/fill.cpp
|
||||
${PROJECT_SOURCE_DIR}src/mbgl/shaders/mtl/fill_extrusion.cpp
|
||||
${PROJECT_SOURCE_DIR}src/mbgl/shaders/mtl/fill_extrusion_pattern.cpp
|
||||
${PROJECT_SOURCE_DIR}src/mbgl/shaders/mtl/heatmap.cpp
|
||||
${PROJECT_SOURCE_DIR}src/mbgl/shaders/mtl/heatmap_texture.cpp
|
||||
${PROJECT_SOURCE_DIR}src/mbgl/shaders/mtl/hillshade.cpp
|
||||
${PROJECT_SOURCE_DIR}src/mbgl/shaders/mtl/hillshade_prepare.cpp
|
||||
${PROJECT_SOURCE_DIR}src/mbgl/shaders/mtl/line.cpp
|
||||
${PROJECT_SOURCE_DIR}src/mbgl/shaders/mtl/line_gradient.cpp
|
||||
${PROJECT_SOURCE_DIR}src/mbgl/shaders/mtl/raster.cpp
|
||||
${PROJECT_SOURCE_DIR}src/mbgl/shaders/mtl/symbol_icon.cpp
|
||||
${PROJECT_SOURCE_DIR}src/mbgl/shaders/mtl/symbol_sdf.cpp
|
||||
${PROJECT_SOURCE_DIR}src/mbgl/shaders/mtl/symbol_text_and_icon.cpp
|
||||
]
|
||||
)
|
||||
endif()
|
||||
|
||||
@@ -10,8 +10,8 @@ http_archive(
|
||||
|
||||
http_archive(
|
||||
name = "rules_xcodeproj",
|
||||
sha256 = "4886d10566dade9048a0b239fc43c21c29bb0ba03fb611a997f7b786d6e859b6",
|
||||
url = "https://github.com/MobileNativeFoundation/rules_xcodeproj/releases/download/1.11.0/release.tar.gz",
|
||||
sha256 = "d25a6af62c0b9ad781a824f6c1e866f8106531019cb7a172bd17eb9cc805a6f7",
|
||||
url = "https://github.com/MobileNativeFoundation/rules_xcodeproj/releases/download/1.12.0/release.tar.gz",
|
||||
)
|
||||
|
||||
load(
|
||||
|
||||
@@ -961,6 +961,7 @@ MLN_DRAWABLES_HEADERS = [
|
||||
"include/mbgl/renderer/render_target.hpp",
|
||||
"include/mbgl/shaders/background_layer_ubo.hpp",
|
||||
"include/mbgl/shaders/circle_layer_ubo.hpp",
|
||||
"include/mbgl/shaders/collision_layer_ubo.hpp",
|
||||
"include/mbgl/shaders/fill_layer_ubo.hpp",
|
||||
"include/mbgl/shaders/fill_extrusion_layer_ubo.hpp",
|
||||
"include/mbgl/shaders/heatmap_layer_ubo.hpp",
|
||||
@@ -1019,6 +1020,25 @@ MLN_DRAWABLES_MTL_SOURCE = [
|
||||
"src/mbgl/mtl/upload_pass.cpp",
|
||||
"src/mbgl/mtl/vertex_attribute.cpp",
|
||||
"src/mbgl/shaders/mtl/shader_program.cpp",
|
||||
"src/mbgl/shaders/mtl/background.cpp",
|
||||
"src/mbgl/shaders/mtl/background_pattern.cpp",
|
||||
"src/mbgl/shaders/mtl/circle.cpp",
|
||||
"src/mbgl/shaders/mtl/collision_box.cpp",
|
||||
"src/mbgl/shaders/mtl/collision_circle.cpp",
|
||||
"src/mbgl/shaders/mtl/clipping_mask.cpp",
|
||||
"src/mbgl/shaders/mtl/fill.cpp",
|
||||
"src/mbgl/shaders/mtl/fill_extrusion.cpp",
|
||||
"src/mbgl/shaders/mtl/fill_extrusion_pattern.cpp",
|
||||
"src/mbgl/shaders/mtl/heatmap.cpp",
|
||||
"src/mbgl/shaders/mtl/heatmap_texture.cpp",
|
||||
"src/mbgl/shaders/mtl/hillshade.cpp",
|
||||
"src/mbgl/shaders/mtl/hillshade_prepare.cpp",
|
||||
"src/mbgl/shaders/mtl/line.cpp",
|
||||
"src/mbgl/shaders/mtl/line_gradient.cpp",
|
||||
"src/mbgl/shaders/mtl/raster.cpp",
|
||||
"src/mbgl/shaders/mtl/symbol_icon.cpp",
|
||||
"src/mbgl/shaders/mtl/symbol_sdf.cpp",
|
||||
"src/mbgl/shaders/mtl/symbol_text_and_icon.cpp",
|
||||
]
|
||||
|
||||
MLN_DRAWABLES_MTL_HEADERS = [
|
||||
@@ -1045,6 +1065,8 @@ MLN_DRAWABLES_MTL_HEADERS = [
|
||||
"include/mbgl/shaders/mtl/background_pattern.hpp",
|
||||
"include/mbgl/shaders/mtl/circle.hpp",
|
||||
"include/mbgl/shaders/mtl/clipping_mask.hpp",
|
||||
"include/mbgl/shaders/mtl/collision_box.hpp",
|
||||
"include/mbgl/shaders/mtl/collision_circle.hpp",
|
||||
"include/mbgl/shaders/mtl/common.hpp",
|
||||
"include/mbgl/shaders/mtl/fill.hpp",
|
||||
"include/mbgl/shaders/mtl/fill_extrusion.hpp",
|
||||
|
||||
@@ -19,7 +19,7 @@ public:
|
||||
|
||||
#if MLN_RENDER_BACKEND_METAL
|
||||
static constexpr Type DefaultType = Type::Metal;
|
||||
#else // assume MLN_RENDER_BACKEND_METAL
|
||||
#else // assume MLN_RENDER_BACKEND_OPENGL
|
||||
static constexpr Type DefaultType = Type::OpenGL;
|
||||
#endif
|
||||
|
||||
@@ -33,7 +33,11 @@ public:
|
||||
|
||||
template <typename T, typename... Args>
|
||||
static std::unique_ptr<T> Create(Args... args) {
|
||||
#if MLN_RENDER_BACKEND_METAL
|
||||
return Create<Type::Metal, T, Args...>(std::forward<Args>(args)...);
|
||||
#else // assume MLN_RENDER_BACKEND_OPENGL
|
||||
return Create<Type::OpenGL, T, Args...>(std::forward<Args>(args)...);
|
||||
#endif
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -134,7 +134,7 @@ public:
|
||||
bool getEnableStencil() const { return enableStencil; }
|
||||
|
||||
/// Set stencil usage
|
||||
void setEnableStencil(bool value) { enableStencil = value; }
|
||||
virtual void setEnableStencil(bool value) { enableStencil = value; }
|
||||
|
||||
/// not used for anything yet
|
||||
DrawPriority getDrawPriority() const { return drawPriority; }
|
||||
@@ -142,19 +142,19 @@ public:
|
||||
|
||||
/// Whether to enable depth testing
|
||||
bool getEnableDepth() { return enableDepth; }
|
||||
void setEnableDepth(bool value) { enableDepth = value; }
|
||||
virtual void setEnableDepth(bool value) { enableDepth = value; }
|
||||
|
||||
/// Determines depth range within the layer for 2D drawables
|
||||
int32_t getSubLayerIndex() const { return subLayerIndex; }
|
||||
|
||||
/// Set sub-layer index
|
||||
void setSubLayerIndex(int32_t value) { subLayerIndex = value; }
|
||||
virtual void setSubLayerIndex(int32_t value) { subLayerIndex = value; }
|
||||
|
||||
/// Depth writability for 2D drawables
|
||||
DepthMaskType getDepthType() const { return depthType; }
|
||||
|
||||
/// Set depth type
|
||||
void setDepthType(DepthMaskType value) { depthType = value; }
|
||||
virtual void setDepthType(DepthMaskType value) { depthType = value; }
|
||||
|
||||
/// Uses 3D depth mode
|
||||
bool getIs3D() const { return is3D; }
|
||||
|
||||
@@ -6,9 +6,12 @@
|
||||
#include <mutex>
|
||||
#include <shared_mutex>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
#include <unordered_set>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
using StringIdentity = std::size_t;
|
||||
|
||||
namespace gfx {
|
||||
|
||||
class Context;
|
||||
@@ -138,12 +141,13 @@ public:
|
||||
|
||||
/// @brief Get a shader from the group by its set of data driven properties as uniforms.
|
||||
/// if no shader is found, create and register the shader.
|
||||
/// @param propertiesAsUniforms Vector of data driven properties as uniforms.
|
||||
/// @param propertiesAsUniforms Set of data driven properties as uniforms.
|
||||
/// @param firstAttribName Name of the first attribute
|
||||
/// @return A `gfx::ShaderPtr`
|
||||
virtual gfx::ShaderPtr getOrCreateShader(gfx::Context&,
|
||||
[[maybe_unused]] const std::vector<std::string>& propertiesAsUniforms,
|
||||
[[maybe_unused]] std::string_view firstAttribName = "a_pos") {
|
||||
virtual gfx::ShaderPtr getOrCreateShader(
|
||||
gfx::Context&,
|
||||
[[maybe_unused]] const std::unordered_set<StringIdentity>& propertiesAsUniforms,
|
||||
[[maybe_unused]] std::string_view firstAttribName = "a_pos") {
|
||||
return {};
|
||||
}
|
||||
|
||||
|
||||
@@ -113,6 +113,7 @@ enum class TexturePixelType : uint8_t {
|
||||
enum class TextureChannelDataType : uint8_t {
|
||||
UnsignedByte, ///< 8 bit unsigned byte
|
||||
HalfFloat, ///< 16 bit "half-float"
|
||||
Float, ///< 32 bit float
|
||||
};
|
||||
|
||||
/// Texture mip map type
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#include <variant>
|
||||
#include <vector>
|
||||
|
||||
@@ -365,9 +366,15 @@ public:
|
||||
}
|
||||
|
||||
/// Specialized DataDrivenPaintProperty reader
|
||||
/// @param binders Property binders for the target shader
|
||||
/// @param evaluated Evaluated properties
|
||||
/// @param propertiesAsUniforms [out] A set of string identities for the properties which will be constant, not
|
||||
/// attributes.
|
||||
/// @details The property name IDs refer to the "a\_" prefixed values to match the shader definitions.
|
||||
template <class... DataDrivenPaintProperty, class Binders, class Evaluated>
|
||||
std::vector<std::string> readDataDrivenPaintProperties(const Binders& binders, const Evaluated& evaluated) {
|
||||
std::vector<std::string> propertiesAsUniforms;
|
||||
void readDataDrivenPaintProperties(const Binders& binders,
|
||||
const Evaluated& evaluated,
|
||||
std::unordered_set<StringIdentity>& propertiesAsUniforms) {
|
||||
propertiesAsUniforms.reserve(sizeof...(DataDrivenPaintProperty));
|
||||
(
|
||||
[&](const auto& attributeNames) {
|
||||
@@ -378,15 +385,14 @@ public:
|
||||
using Type = typename Attribute::Type; // ::mbgl::gfx::AttributeType<type_, n_>
|
||||
using InterpType = ZoomInterpolatedAttributeType<Type>;
|
||||
|
||||
auto& attributeNameID = DataDrivenPaintProperty::AttributeNameIDs[attrIndex];
|
||||
if (!attributeNameID) {
|
||||
attributeNameID = stringIndexer().get(attributePrefix + attributeName.data());
|
||||
}
|
||||
|
||||
const auto vertexCount = binder->getVertexCount();
|
||||
const auto isConstant = evaluated.template get<DataDrivenPaintProperty>().isConstant();
|
||||
if (vertexCount > 0 && !isConstant) {
|
||||
auto& attributeNameID = DataDrivenPaintProperty::AttributeNameIDs[attrIndex];
|
||||
if (!attributeNameID) {
|
||||
static const std::string attributePrefix = "a_";
|
||||
attributeNameID = stringIndexer().get(attributePrefix + attributeName.data());
|
||||
}
|
||||
|
||||
if (auto& attr = getOrAdd(*attributeNameID)) {
|
||||
if (const auto& sharedVector = binder->getSharedVertexVector()) {
|
||||
const auto rawSize = static_cast<uint32_t>(sharedVector->getRawSize());
|
||||
@@ -403,15 +409,13 @@ public:
|
||||
}
|
||||
}
|
||||
}
|
||||
propertiesAsUniforms.emplace_back(std::string());
|
||||
} else {
|
||||
propertiesAsUniforms.emplace_back(attributeName);
|
||||
propertiesAsUniforms.emplace(*attributeNameID);
|
||||
}
|
||||
}
|
||||
}
|
||||
}(DataDrivenPaintProperty::AttributeNames),
|
||||
...);
|
||||
return propertiesAsUniforms;
|
||||
}
|
||||
|
||||
/// Copy another collection into this one
|
||||
@@ -436,7 +440,8 @@ protected:
|
||||
|
||||
protected:
|
||||
AttributeMap attrs;
|
||||
static std::unique_ptr<VertexAttribute> nullref;
|
||||
static const std::unique_ptr<VertexAttribute> nullref;
|
||||
static const std::string attributePrefix;
|
||||
};
|
||||
|
||||
} // namespace gfx
|
||||
|
||||
@@ -78,6 +78,8 @@ public:
|
||||
|
||||
void setDirtyState() override;
|
||||
|
||||
std::unique_ptr<gfx::OffscreenTexture> createOffscreenTexture(Size, gfx::TextureChannelDataType, bool, bool);
|
||||
|
||||
std::unique_ptr<gfx::OffscreenTexture> createOffscreenTexture(Size, gfx::TextureChannelDataType) override;
|
||||
|
||||
std::unique_ptr<gfx::TextureResource> createTextureResource(Size,
|
||||
|
||||
@@ -4,8 +4,6 @@
|
||||
#include <mbgl/gfx/draw_mode.hpp>
|
||||
#include <mbgl/mtl/upload_pass.hpp>
|
||||
#include <mbgl/programs/segment.hpp>
|
||||
#include <mbgl/mtl/mtl_fwd.hpp>
|
||||
#include <mbgl/mtl/render_pass.hpp>
|
||||
|
||||
#include <memory>
|
||||
|
||||
@@ -59,6 +57,11 @@ public:
|
||||
|
||||
void setShader(gfx::ShaderProgramBasePtr) override;
|
||||
|
||||
void setEnableStencil(bool) override;
|
||||
void setEnableDepth(bool) override;
|
||||
void setSubLayerIndex(int32_t) override;
|
||||
void setDepthType(gfx::DepthMaskType) override;
|
||||
|
||||
protected:
|
||||
// For testing only.
|
||||
Drawable(std::unique_ptr<Impl>);
|
||||
@@ -76,12 +79,6 @@ protected:
|
||||
|
||||
class Impl;
|
||||
const std::unique_ptr<Impl> impl;
|
||||
|
||||
gfx::AttributeBindingArray attributeBindings;
|
||||
|
||||
mutable MTLRenderPipelineStatePtr pipelineState;
|
||||
|
||||
mutable std::optional<gfx::RenderPassDescriptor> renderPassDescriptor;
|
||||
};
|
||||
|
||||
} // namespace mtl
|
||||
|
||||
@@ -11,7 +11,7 @@ class Texture2D;
|
||||
|
||||
class OffscreenTexture final : public gfx::OffscreenTexture {
|
||||
public:
|
||||
OffscreenTexture(Context&, Size size, gfx::TextureChannelDataType type = gfx::TextureChannelDataType::UnsignedByte);
|
||||
OffscreenTexture(Context&, Size size, gfx::TextureChannelDataType type, bool depth, bool stencil);
|
||||
|
||||
bool isRenderable() override;
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ public:
|
||||
virtual const mbgl::mtl::RendererBackend& getBackend() const = 0;
|
||||
virtual const mbgl::mtl::MTLCommandBufferPtr& getCommandBuffer() const = 0;
|
||||
virtual mbgl::mtl::MTLBlitPassDescriptorPtr getUploadPassDescriptor() const = 0;
|
||||
virtual mbgl::mtl::MTLRenderPassDescriptorPtr getRenderPassDescriptor() const = 0;
|
||||
virtual const mbgl::mtl::MTLRenderPassDescriptorPtr& getRenderPassDescriptor() const = 0;
|
||||
};
|
||||
|
||||
} // namespace mtl
|
||||
|
||||
@@ -1,26 +1,31 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/shaders/shader_source.hpp>
|
||||
#include <mbgl/util/immutable.hpp>
|
||||
|
||||
#include <array>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <unordered_set>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
namespace gfx {
|
||||
class Drawable;
|
||||
class UniformBuffer;
|
||||
using UniformBufferPtr = std::shared_ptr<UniformBuffer>;
|
||||
} // namespace gfx
|
||||
|
||||
namespace shaders {
|
||||
enum class AttributeSource : int32_t;
|
||||
struct ExpressionInputsUBO;
|
||||
} // namespace shaders
|
||||
|
||||
namespace style {
|
||||
class LayerProperties;
|
||||
enum class TranslateAnchorType : bool;
|
||||
} // namespace style
|
||||
|
||||
class TransformState;
|
||||
class LayerGroupBase;
|
||||
class PaintParameters;
|
||||
@@ -28,6 +33,7 @@ class RenderTree;
|
||||
class UnwrappedTileID;
|
||||
|
||||
using mat4 = std::array<double, 16>;
|
||||
using StringIdentity = std::size_t;
|
||||
|
||||
/**
|
||||
Base class for layer tweakers, which manipulate layer group per frame
|
||||
@@ -47,19 +53,21 @@ public:
|
||||
static shaders::ExpressionInputsUBO buildExpressionUBO(double zoom, uint64_t frameCount);
|
||||
|
||||
/// @brief Check whether a property name exists within the previously set collection.
|
||||
/// @details The string value provided is expected to have the "a_" prefix, as defined in the shader classes.
|
||||
bool hasPropertyAsUniform(std::string_view) const;
|
||||
shaders::AttributeSource getAttributeSource(const std::string_view& attribName) const;
|
||||
bool hasPropertyAsUniform(StringIdentity) const;
|
||||
shaders::AttributeSource getAttributeSource(StringIdentity) const;
|
||||
|
||||
template <shaders::BuiltIn ShaderType>
|
||||
shaders::AttributeSource getAttributeSource(size_t index) {
|
||||
using ShaderClass = shaders::ShaderSource<ShaderType, gfx::Backend::Type::Metal>;
|
||||
return getAttributeSource(ShaderClass::attributes[index].nameID);
|
||||
}
|
||||
#endif // MLN_RENDER_BACKEND_METAL
|
||||
|
||||
/// @brief Set the collection of attribute names which will be provided at uniform values rather than per-vertex
|
||||
/// attributes.
|
||||
/// @details These values should not have "a_" prefixes, as produced by `readDataDrivenPaintProperties`.
|
||||
#if MLN_RENDER_BACKEND_OPENGL
|
||||
void setPropertiesAsUniforms(const std::vector<std::string>&) {}
|
||||
#else
|
||||
void setPropertiesAsUniforms(std::vector<std::string>);
|
||||
#endif
|
||||
void setPropertiesAsUniforms(const std::unordered_set<StringIdentity>&);
|
||||
const std::unordered_set<StringIdentity>& getPropertiesAsUniforms() const;
|
||||
|
||||
void enableOverdrawInspector(bool);
|
||||
|
||||
@@ -90,7 +98,7 @@ protected:
|
||||
#if MLN_RENDER_BACKEND_METAL
|
||||
// For Metal, whether a property is provided through attribtues or uniforms is specified in
|
||||
// a uniform buffer rather than by a shader compiled with different preprocessor definitions.
|
||||
std::vector<std::string> propertiesAsUniforms;
|
||||
std::unordered_set<StringIdentity> propertiesAsUniforms;
|
||||
#endif // MLN_RENDER_BACKEND_METAL
|
||||
|
||||
// Indicates that the evaluated properties have changed
|
||||
|
||||
18
include/mbgl/shaders/collision_layer_ubo.hpp
Normal file
18
include/mbgl/shaders/collision_layer_ubo.hpp
Normal file
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/shaders/layer_ubo.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace shaders {
|
||||
|
||||
struct alignas(16) CollisionUBO {
|
||||
std::array<float, 4 * 4> matrix;
|
||||
std::array<float, 2> extrude_scale;
|
||||
float camera_to_center_distance;
|
||||
float overscale_factor;
|
||||
};
|
||||
static_assert(sizeof(CollisionUBO) % 16 == 0);
|
||||
static_assert(sizeof(CollisionUBO) == 80);
|
||||
|
||||
} // namespace shaders
|
||||
} // namespace mbgl
|
||||
@@ -4,6 +4,10 @@
|
||||
#include <mbgl/shaders/gl/shader_program_gl.hpp>
|
||||
#include <mbgl/shaders/shader_source.hpp>
|
||||
#include <mbgl/programs/program_parameters.hpp>
|
||||
#include <mbgl/util/hash.hpp>
|
||||
|
||||
#include <sstream>
|
||||
#include <unordered_set>
|
||||
|
||||
namespace mbgl {
|
||||
namespace gl {
|
||||
@@ -13,40 +17,61 @@ class ShaderGroupGL final : public gfx::ShaderGroup {
|
||||
public:
|
||||
ShaderGroupGL(const ProgramParameters& programParameters_)
|
||||
: ShaderGroup(),
|
||||
programParameters(programParameters_){};
|
||||
programParameters(programParameters_) {}
|
||||
~ShaderGroupGL() noexcept override = default;
|
||||
|
||||
gfx::ShaderPtr getOrCreateShader(gfx::Context& context,
|
||||
const std::vector<std::string>& propertiesAsUniforms,
|
||||
const std::unordered_set<StringIdentity>& propertiesAsUniforms,
|
||||
std::string_view firstAttribName) override {
|
||||
constexpr auto& name = shaders::ShaderSource<ShaderID, gfx::Backend::Type::OpenGL>::name;
|
||||
constexpr auto& vert = shaders::ShaderSource<ShaderID, gfx::Backend::Type::OpenGL>::vertex;
|
||||
constexpr auto& frag = shaders::ShaderSource<ShaderID, gfx::Backend::Type::OpenGL>::fragment;
|
||||
|
||||
uint32_t key = 0;
|
||||
// Generate a map key for the specified combination of properties
|
||||
const size_t key = util::order_independent_hash(propertiesAsUniforms.begin(), propertiesAsUniforms.end());
|
||||
|
||||
// We could cache these by key here to avoid creating a string key each time, but we
|
||||
// would need another mutex. We could also push string IDs down into `ShaderGroup`.
|
||||
const std::string shaderName = getShaderName(key);
|
||||
auto shader = get<gl::ShaderProgramGL>(shaderName);
|
||||
if (shader) {
|
||||
return shader;
|
||||
}
|
||||
|
||||
// No match, we need to create the shader.
|
||||
std::string additionalDefines;
|
||||
for (unsigned int i = 0; i < propertiesAsUniforms.size(); i++) {
|
||||
if (propertiesAsUniforms[i].empty()) {
|
||||
continue;
|
||||
additionalDefines.reserve(propertiesAsUniforms.size() * 48);
|
||||
for (const auto nameID : propertiesAsUniforms) {
|
||||
// We expect the names to be prefixed by "a_", but we need just the base here.
|
||||
const auto prefixedAttrName = stringIndexer().get(nameID);
|
||||
const auto* prefix = prefixedAttrName.data();
|
||||
if (prefix[0] == 'a' && prefix[1] == '_') {
|
||||
prefix += 2;
|
||||
}
|
||||
key |= 1 << i;
|
||||
|
||||
additionalDefines += "#define HAS_UNIFORM_u_";
|
||||
additionalDefines += propertiesAsUniforms[i];
|
||||
additionalDefines += prefix;
|
||||
additionalDefines += "\n";
|
||||
}
|
||||
const std::string shaderName = std::string(name) + "#" + std::to_string(key);
|
||||
auto shader = get<gl::ShaderProgramGL>(shaderName);
|
||||
if (!shader) {
|
||||
auto& glContext = static_cast<gl::Context&>(context);
|
||||
shader = ShaderProgramGL::create(
|
||||
glContext, programParameters, shaderName, firstAttribName, vert, frag, additionalDefines);
|
||||
if (!shader || !registerShader(shader, shaderName)) {
|
||||
throw std::runtime_error("Failed to register " + shaderName + " with shader group!");
|
||||
}
|
||||
|
||||
auto& glContext = static_cast<gl::Context&>(context);
|
||||
shader = ShaderProgramGL::create(
|
||||
glContext, programParameters, shaderName, firstAttribName, vert, frag, additionalDefines);
|
||||
if (!shader || !registerShader(shader, shaderName)) {
|
||||
throw std::runtime_error("Failed to register " + shaderName + " with shader group!");
|
||||
}
|
||||
return shader;
|
||||
}
|
||||
|
||||
protected:
|
||||
std::string getShaderName(std::size_t key) {
|
||||
constexpr auto& name = shaders::ShaderSource<ShaderID, gfx::Backend::Type::OpenGL>::name;
|
||||
|
||||
// This could be more efficient.
|
||||
std::ostringstream stream;
|
||||
stream << name << '#' << key;
|
||||
return stream.str();
|
||||
}
|
||||
|
||||
private:
|
||||
ProgramParameters programParameters;
|
||||
};
|
||||
|
||||
@@ -5,8 +5,6 @@
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
|
||||
#define MLN_STRINGIZE(X) #X
|
||||
|
||||
namespace mbgl {
|
||||
namespace shaders {
|
||||
|
||||
|
||||
@@ -14,14 +14,9 @@ struct ShaderSource<BuiltIn::BackgroundShader, gfx::Backend::Type::Metal> {
|
||||
static constexpr auto vertexMainFunction = "vertexMain";
|
||||
static constexpr auto fragmentMainFunction = "fragmentMain";
|
||||
|
||||
static constexpr AttributeInfo attributes[] = {
|
||||
{0, gfx::AttributeDataType::Float3, 1, "a_pos"},
|
||||
};
|
||||
static constexpr UniformBlockInfo uniforms[] = {
|
||||
MLN_MTL_UNIFORM_BLOCK(1, true, true, BackgroundLayerUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(2, true, false, BackgroundDrawableUBO),
|
||||
};
|
||||
static constexpr TextureInfo textures[] = {};
|
||||
static const std::array<AttributeInfo, 1> attributes;
|
||||
static const std::array<UniformBlockInfo, 2> uniforms;
|
||||
static const std::array<TextureInfo, 0> textures;
|
||||
|
||||
static constexpr auto source = R"(
|
||||
#include <metal_stdlib>
|
||||
|
||||
@@ -9,11 +9,7 @@ template <>
|
||||
struct ShaderSource<BuiltIn::BackgroundPatternShader, gfx::Backend::Type::Metal>
|
||||
: public ShaderSource<BuiltIn::BackgroundShader, gfx::Backend::Type::Metal> {
|
||||
static constexpr auto name = "BackgroundPatternShader";
|
||||
static constexpr UniformBlockInfo uniforms[] = {
|
||||
{1, sizeof(BackgroundLayerUBO), true, false, "BackgroundLayerUBO"},
|
||||
{2, sizeof(BackgroundDrawableUBO), true, false, "BackgroundDrawableUBO"},
|
||||
{3, sizeof(BackgroundPatternLayerUBO), true, false, "BackgroundPatternLayerUBO"},
|
||||
};
|
||||
static const std::array<UniformBlockInfo, 3> uniforms;
|
||||
};
|
||||
|
||||
} // namespace shaders
|
||||
|
||||
@@ -14,25 +14,9 @@ struct ShaderSource<BuiltIn::CircleShader, gfx::Backend::Type::Metal> {
|
||||
static constexpr auto vertexMainFunction = "vertexMain";
|
||||
static constexpr auto fragmentMainFunction = "fragmentMain";
|
||||
|
||||
static constexpr AttributeInfo attributes[] = {
|
||||
{0, gfx::AttributeDataType::Short2, 1, "a_pos"},
|
||||
{1, gfx::AttributeDataType::Float2, 1, "a_color"},
|
||||
{2, gfx::AttributeDataType::Float2, 1, "a_radius"},
|
||||
{3, gfx::AttributeDataType::Float2, 1, "a_blur"},
|
||||
{4, gfx::AttributeDataType::Float2, 1, "a_opacity"},
|
||||
{5, gfx::AttributeDataType::Float4, 1, "a_stroke_color"},
|
||||
{6, gfx::AttributeDataType::Float2, 1, "a_stroke_width"},
|
||||
{7, gfx::AttributeDataType::Float2, 1, "a_stroke_opacity"},
|
||||
};
|
||||
static constexpr UniformBlockInfo uniforms[] = {
|
||||
MLN_MTL_UNIFORM_BLOCK(8, true, false, CircleDrawableUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(9, true, true, CirclePaintParamsUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(10, true, true, CircleEvaluatedPropsUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(11, true, false, CircleInterpolateUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(12, true, true, CirclePermutationUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(13, true, false, ExpressionInputsUBO),
|
||||
};
|
||||
static constexpr TextureInfo textures[] = {};
|
||||
static const std::array<AttributeInfo, 8> attributes;
|
||||
static const std::array<UniformBlockInfo, 6> uniforms;
|
||||
static const std::array<TextureInfo, 0> textures;
|
||||
|
||||
static constexpr auto source = R"(
|
||||
|
||||
|
||||
@@ -20,13 +20,9 @@ struct ShaderSource<BuiltIn::ClippingMaskProgram, gfx::Backend::Type::Metal> {
|
||||
static constexpr auto vertexMainFunction = "vertexMain";
|
||||
static constexpr auto fragmentMainFunction = "fragmentMain";
|
||||
|
||||
static constexpr AttributeInfo attributes[] = {
|
||||
{0, gfx::AttributeDataType::Float3, 1, "a_pos"},
|
||||
};
|
||||
static constexpr UniformBlockInfo uniforms[] = {
|
||||
MLN_MTL_UNIFORM_BLOCK(1, true, false, ClipUBO),
|
||||
};
|
||||
static constexpr TextureInfo textures[] = {};
|
||||
static const std::array<AttributeInfo, 1> attributes;
|
||||
static const std::array<UniformBlockInfo, 1> uniforms;
|
||||
static const std::array<TextureInfo, 0> textures;
|
||||
|
||||
static constexpr auto source = R"(
|
||||
#include <metal_stdlib>
|
||||
|
||||
91
include/mbgl/shaders/mtl/collision_box.hpp
Normal file
91
include/mbgl/shaders/mtl/collision_box.hpp
Normal file
@@ -0,0 +1,91 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/shaders/collision_layer_ubo.hpp>
|
||||
#include <mbgl/shaders/shader_source.hpp>
|
||||
#include <mbgl/shaders/mtl/common.hpp>
|
||||
#include <mbgl/shaders/mtl/shader_program.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace shaders {
|
||||
|
||||
template <>
|
||||
struct ShaderSource<BuiltIn::CollisionBoxShader, gfx::Backend::Type::Metal> {
|
||||
static constexpr auto name = "CollisionBoxShader";
|
||||
static constexpr auto vertexMainFunction = "vertexMain";
|
||||
static constexpr auto fragmentMainFunction = "fragmentMain";
|
||||
|
||||
static const std::array<AttributeInfo, 5> attributes;
|
||||
static const std::array<UniformBlockInfo, 1> uniforms;
|
||||
static const std::array<TextureInfo, 0> textures;
|
||||
|
||||
static constexpr auto source = R"(
|
||||
|
||||
struct VertexStage {
|
||||
short2 pos [[attribute(0)]];
|
||||
short2 anchor_pos [[attribute(1)]];
|
||||
short2 extrude [[attribute(2)]];
|
||||
uchar2 placed [[attribute(3)]];
|
||||
float2 shift [[attribute(4)]];
|
||||
};
|
||||
|
||||
struct FragmentStage {
|
||||
float4 position [[position, invariant]];
|
||||
float placed;
|
||||
float notUsed;
|
||||
};
|
||||
|
||||
struct alignas(16) CollisionBoxUBO {
|
||||
float4x4 matrix;
|
||||
float2 extrude_scale;
|
||||
float camera_to_center_distance;
|
||||
float pad1;
|
||||
};
|
||||
|
||||
FragmentStage vertex vertexMain(thread const VertexStage vertx [[stage_in]],
|
||||
device const CollisionBoxUBO& drawable [[buffer(5)]]) {
|
||||
|
||||
float4 projectedPoint = drawable.matrix * float4(float2(vertx.anchor_pos), 0, 1);
|
||||
float camera_to_anchor_distance = projectedPoint.w;
|
||||
float collision_perspective_ratio = clamp(
|
||||
0.5 + 0.5 * (drawable.camera_to_center_distance / camera_to_anchor_distance),
|
||||
0.0, // Prevents oversized near-field boxes in pitched/overzoomed tiles
|
||||
4.0);
|
||||
|
||||
float4 position = drawable.matrix * float4(float2(vertx.pos), 0.0, 1.0);
|
||||
position.xy += (float2(vertx.extrude) + vertx.shift) * drawable.extrude_scale * position.w * collision_perspective_ratio;
|
||||
|
||||
float placed = float(vertx.placed.x);
|
||||
float notUsed = float(vertx.placed.y);
|
||||
|
||||
return {
|
||||
.position = position,
|
||||
.placed = placed,
|
||||
.notUsed = notUsed,
|
||||
};
|
||||
}
|
||||
|
||||
half4 fragment fragmentMain(FragmentStage in [[stage_in]],
|
||||
device const CollisionBoxUBO& drawable [[buffer(5)]]) {
|
||||
|
||||
float alpha = 0.5;
|
||||
|
||||
// Red = collision, hide label
|
||||
float4 color = float4(1.0, 0.0, 0.0, 1.0) * alpha;
|
||||
|
||||
// Blue = no collision, label is showing
|
||||
if (in.placed > 0.5) {
|
||||
color = float4(0.0, 0.0, 1.0, 0.5) * alpha;
|
||||
}
|
||||
|
||||
if (in.notUsed > 0.5) {
|
||||
// This box not used, fade it out
|
||||
color *= 0.1;
|
||||
}
|
||||
|
||||
return half4(color);
|
||||
}
|
||||
)";
|
||||
};
|
||||
|
||||
} // namespace shaders
|
||||
} // namespace mbgl
|
||||
110
include/mbgl/shaders/mtl/collision_circle.hpp
Normal file
110
include/mbgl/shaders/mtl/collision_circle.hpp
Normal file
@@ -0,0 +1,110 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/shaders/collision_layer_ubo.hpp>
|
||||
#include <mbgl/shaders/shader_source.hpp>
|
||||
#include <mbgl/shaders/mtl/common.hpp>
|
||||
#include <mbgl/shaders/mtl/shader_program.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace shaders {
|
||||
|
||||
template <>
|
||||
struct ShaderSource<BuiltIn::CollisionCircleShader, gfx::Backend::Type::Metal> {
|
||||
static constexpr auto name = "CollisionCircleShader";
|
||||
static constexpr auto vertexMainFunction = "vertexMain";
|
||||
static constexpr auto fragmentMainFunction = "fragmentMain";
|
||||
|
||||
static const std::array<AttributeInfo, 4> attributes;
|
||||
static const std::array<UniformBlockInfo, 1> uniforms;
|
||||
static const std::array<TextureInfo, 0> textures;
|
||||
|
||||
static constexpr auto source = R"(
|
||||
|
||||
struct VertexStage {
|
||||
short2 pos [[attribute(0)]];
|
||||
short2 anchor_pos [[attribute(1)]];
|
||||
short2 extrude [[attribute(2)]];
|
||||
uchar2 placed [[attribute(3)]];
|
||||
};
|
||||
|
||||
struct FragmentStage {
|
||||
float4 position [[position, invariant]];
|
||||
float placed;
|
||||
float notUsed;
|
||||
float radius;
|
||||
float2 extrude;
|
||||
float2 extrude_scale;
|
||||
};
|
||||
|
||||
struct alignas(16) CollisionCircleUBO {
|
||||
float4x4 matrix;
|
||||
float2 extrude_scale;
|
||||
float camera_to_center_distance;
|
||||
float overscale_factor;
|
||||
};
|
||||
|
||||
FragmentStage vertex vertexMain(thread const VertexStage vertx [[stage_in]],
|
||||
device const CollisionCircleUBO& drawable [[buffer(4)]]) {
|
||||
|
||||
float4 projectedPoint = drawable.matrix * float4(float2(vertx.anchor_pos), 0, 1);
|
||||
float camera_to_anchor_distance = projectedPoint.w;
|
||||
float collision_perspective_ratio = clamp(
|
||||
0.5 + 0.5 * (drawable.camera_to_center_distance / camera_to_anchor_distance),
|
||||
0.0, // Prevents oversized near-field circles in pitched/overzoomed tiles
|
||||
4.0);
|
||||
|
||||
float4 position = drawable.matrix * float4(float2(vertx.pos), 0.0, 1.0);
|
||||
|
||||
float padding_factor = 1.2; // Pad the vertices slightly to make room for anti-alias blur
|
||||
position.xy += float2(vertx.extrude) * drawable.extrude_scale * padding_factor * position.w * collision_perspective_ratio;
|
||||
|
||||
float placed = float(vertx.placed.x);
|
||||
float notUsed = float(vertx.placed.y);
|
||||
float radius = abs(float(vertx.extrude.y)); // We don't pitch the circles, so both units of the extrusion vector are equal in magnitude to the radius
|
||||
|
||||
float2 extrude = float2(vertx.extrude) * padding_factor;
|
||||
float2 extrude_scale = drawable.extrude_scale * drawable.camera_to_center_distance * collision_perspective_ratio;
|
||||
|
||||
return {
|
||||
.position = position,
|
||||
.placed = placed,
|
||||
.notUsed = notUsed,
|
||||
.radius = radius,
|
||||
.extrude = extrude,
|
||||
.extrude_scale = extrude_scale,
|
||||
};
|
||||
}
|
||||
|
||||
half4 fragment fragmentMain(FragmentStage in [[stage_in]],
|
||||
device const CollisionCircleUBO& drawable [[buffer(4)]]) {
|
||||
|
||||
float alpha = 0.5;
|
||||
|
||||
// Red = collision, hide label
|
||||
float4 color = float4(1.0, 0.0, 0.0, 1.0) * alpha;
|
||||
|
||||
// Blue = no collision, label is showing
|
||||
if (in.placed > 0.5) {
|
||||
color = float4(0.0, 0.0, 1.0, 0.5) * alpha;
|
||||
}
|
||||
|
||||
if (in.notUsed > 0.5) {
|
||||
// This box not used, fade it out
|
||||
color *= 0.2;
|
||||
}
|
||||
|
||||
float extrude_scale_length = length(in.extrude_scale);
|
||||
float extrude_length = length(in.extrude) * extrude_scale_length;
|
||||
float stroke_width = 15.0 * extrude_scale_length / drawable.overscale_factor;
|
||||
float radius = in.radius * extrude_scale_length;
|
||||
|
||||
float distance_to_edge = abs(extrude_length - radius);
|
||||
float opacity_t = smoothstep(-stroke_width, 0.0, -distance_to_edge);
|
||||
|
||||
return half4(opacity_t * color);
|
||||
}
|
||||
)";
|
||||
};
|
||||
|
||||
} // namespace shaders
|
||||
} // namespace mbgl
|
||||
@@ -1,8 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#define MLN_MTL_UNIFORM_BLOCK(idx, vert, frag, struc) \
|
||||
{ idx, vert, frag, sizeof(struc), MLN_STRINGIZE(struc) }
|
||||
|
||||
namespace mbgl {
|
||||
namespace shaders {
|
||||
|
||||
|
||||
@@ -14,24 +14,9 @@ struct ShaderSource<BuiltIn::FillShader, gfx::Backend::Type::Metal> {
|
||||
static constexpr auto vertexMainFunction = "vertexMain";
|
||||
static constexpr auto fragmentMainFunction = "fragmentMain";
|
||||
|
||||
static constexpr AttributeInfo attributes[] = {
|
||||
{0, gfx::AttributeDataType::Short2, 1, "a_pos"},
|
||||
{1, gfx::AttributeDataType::Float2, 1, "a_color"},
|
||||
{2, gfx::AttributeDataType::Float2, 1, "a_opacity"},
|
||||
|
||||
// This shader doesn't use it, but we need this so that the layer can assign the same
|
||||
// attributes to all the drawables. If/When `VertexAttributeArray::resolve` allows it,
|
||||
// this can be removed.
|
||||
{8, gfx::AttributeDataType::Float2, 1, "a_outline_color"},
|
||||
};
|
||||
static constexpr UniformBlockInfo uniforms[] = {
|
||||
MLN_MTL_UNIFORM_BLOCK(3, true, false, FillDrawableUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(4, true, true, FillEvaluatedPropsUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(5, true, false, FillInterpolateUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(6, true, true, FillPermutationUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(7, true, false, ExpressionInputsUBO),
|
||||
};
|
||||
static constexpr TextureInfo textures[] = {};
|
||||
static const std::array<AttributeInfo, 4> attributes;
|
||||
static const std::array<UniformBlockInfo, 5> uniforms;
|
||||
static const std::array<TextureInfo, 0> textures;
|
||||
|
||||
static constexpr auto source = R"(
|
||||
|
||||
@@ -104,22 +89,9 @@ struct ShaderSource<BuiltIn::FillOutlineShader, gfx::Backend::Type::Metal> {
|
||||
static constexpr auto vertexMainFunction = "vertexMain";
|
||||
static constexpr auto fragmentMainFunction = "fragmentMain";
|
||||
|
||||
static constexpr AttributeInfo attributes[] = {
|
||||
{0, gfx::AttributeDataType::Short2, 1, "a_pos"},
|
||||
{1, gfx::AttributeDataType::Float2, 1, "a_outline_color"},
|
||||
{2, gfx::AttributeDataType::Float2, 1, "a_opacity"},
|
||||
|
||||
// See `a_outline_color` in FillShader
|
||||
{8, gfx::AttributeDataType::Float2, 1, "a_color"},
|
||||
};
|
||||
static constexpr UniformBlockInfo uniforms[] = {
|
||||
MLN_MTL_UNIFORM_BLOCK(3, true, false, FillOutlineDrawableUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(4, true, true, FillOutlineEvaluatedPropsUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(5, true, false, FillOutlineInterpolateUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(6, true, true, FillOutlinePermutationUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(7, true, false, ExpressionInputsUBO),
|
||||
};
|
||||
static constexpr TextureInfo textures[] = {};
|
||||
static const std::array<AttributeInfo, 4> attributes;
|
||||
static const std::array<UniformBlockInfo, 5> uniforms;
|
||||
static const std::array<TextureInfo, 0> textures;
|
||||
|
||||
static constexpr auto source = R"(
|
||||
|
||||
@@ -203,24 +175,9 @@ struct ShaderSource<BuiltIn::FillPatternShader, gfx::Backend::Type::Metal> {
|
||||
static constexpr auto vertexMainFunction = "vertexMain";
|
||||
static constexpr auto fragmentMainFunction = "fragmentMain";
|
||||
|
||||
static constexpr AttributeInfo attributes[] = {
|
||||
{0, gfx::AttributeDataType::Short2, 1, "a_pos"},
|
||||
{1, gfx::AttributeDataType::UShort4, 1, "a_pattern_from"},
|
||||
{2, gfx::AttributeDataType::UShort4, 1, "a_pattern_to"},
|
||||
{3, gfx::AttributeDataType::Float2, 1, "a_opacity"},
|
||||
};
|
||||
static constexpr UniformBlockInfo uniforms[] = {
|
||||
MLN_MTL_UNIFORM_BLOCK(4, true, true, FillPatternDrawableUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(5, true, false, FillPatternTilePropsUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(6, true, true, FillPatternEvaluatedPropsUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(7, true, false, FillPatternInterpolateUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(8, true, true, FillPatternPermutationUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(9, true, false, ExpressionInputsUBO),
|
||||
};
|
||||
|
||||
static constexpr TextureInfo textures[] = {
|
||||
{0, "u_image"},
|
||||
};
|
||||
static const std::array<AttributeInfo, 4> attributes;
|
||||
static const std::array<UniformBlockInfo, 6> uniforms;
|
||||
static const std::array<TextureInfo, 1> textures;
|
||||
|
||||
static constexpr auto source = R"(
|
||||
|
||||
@@ -341,24 +298,9 @@ struct ShaderSource<BuiltIn::FillOutlinePatternShader, gfx::Backend::Type::Metal
|
||||
static constexpr auto vertexMainFunction = "vertexMain";
|
||||
static constexpr auto fragmentMainFunction = "fragmentMain";
|
||||
|
||||
static constexpr AttributeInfo attributes[] = {
|
||||
{0, gfx::AttributeDataType::Short2, 1, "a_pos"},
|
||||
{1, gfx::AttributeDataType::UShort4, 1, "a_pattern_from"},
|
||||
{2, gfx::AttributeDataType::UShort4, 1, "a_pattern_to"},
|
||||
{3, gfx::AttributeDataType::Float2, 1, "a_opacity"},
|
||||
};
|
||||
static constexpr UniformBlockInfo uniforms[] = {
|
||||
MLN_MTL_UNIFORM_BLOCK(4, true, true, FillOutlinePatternDrawableUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(5, true, false, FillOutlinePatternTilePropsUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(6, true, true, FillOutlinePatternEvaluatedPropsUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(7, true, false, FillOutlinePatternInterpolateUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(8, true, true, FillOutlinePatternPermutationUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(9, true, false, ExpressionInputsUBO),
|
||||
};
|
||||
|
||||
static constexpr TextureInfo textures[] = {
|
||||
{0, "u_image"},
|
||||
};
|
||||
static const std::array<AttributeInfo, 4> attributes;
|
||||
static const std::array<UniformBlockInfo, 6> uniforms;
|
||||
static const std::array<TextureInfo, 1> textures;
|
||||
|
||||
static constexpr auto source = R"(
|
||||
|
||||
|
||||
@@ -14,21 +14,9 @@ struct ShaderSource<BuiltIn::FillExtrusionShader, gfx::Backend::Type::Metal> {
|
||||
static constexpr auto vertexMainFunction = "vertexMain";
|
||||
static constexpr auto fragmentMainFunction = "fragmentMain";
|
||||
|
||||
static constexpr AttributeInfo attributes[] = {
|
||||
{0, gfx::AttributeDataType::Short2, 1, "a_pos"},
|
||||
{1, gfx::AttributeDataType::Short4, 1, "a_normal_ed"},
|
||||
{2, gfx::AttributeDataType::Float4, 1, "a_color"},
|
||||
{3, gfx::AttributeDataType::Float, 1, "a_base"},
|
||||
{4, gfx::AttributeDataType::Float, 1, "a_height"},
|
||||
};
|
||||
static constexpr UniformBlockInfo uniforms[] = {
|
||||
MLN_MTL_UNIFORM_BLOCK(5, true, false, FillExtrusionDrawableUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(6, true, false, FillExtrusionDrawablePropsUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(7, true, false, FillExtrusionInterpolateUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(8, true, false, FillExtrusionPermutationUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(9, true, false, ExpressionInputsUBO),
|
||||
};
|
||||
static constexpr TextureInfo textures[] = {};
|
||||
static const std::array<AttributeInfo, 5> attributes;
|
||||
static const std::array<UniformBlockInfo, 5> uniforms;
|
||||
static const std::array<TextureInfo, 0> textures;
|
||||
|
||||
static constexpr auto source = R"(
|
||||
struct alignas(16) FillExtrusionInterpolateUBO {
|
||||
|
||||
@@ -14,9 +14,9 @@ struct ShaderSource<BuiltIn::FillExtrusionPatternShader, gfx::Backend::Type::Met
|
||||
static constexpr auto vertexMainFunction = "vertexMain";
|
||||
static constexpr auto fragmentMainFunction = "fragmentMain";
|
||||
|
||||
static constexpr AttributeInfo attributes[] = {};
|
||||
static constexpr UniformBlockInfo uniforms[] = {};
|
||||
static constexpr TextureInfo textures[] = {};
|
||||
static const std::array<AttributeInfo, 0> attributes;
|
||||
static const std::array<UniformBlockInfo, 0> uniforms;
|
||||
static const std::array<TextureInfo, 0> textures;
|
||||
|
||||
static constexpr auto source = R"(
|
||||
)";
|
||||
|
||||
@@ -14,19 +14,9 @@ struct ShaderSource<BuiltIn::HeatmapShader, gfx::Backend::Type::Metal> {
|
||||
static constexpr auto vertexMainFunction = "vertexMain";
|
||||
static constexpr auto fragmentMainFunction = "fragmentMain";
|
||||
|
||||
static constexpr AttributeInfo attributes[] = {
|
||||
{0, gfx::AttributeDataType::Short2, 1, "a_pos"},
|
||||
{1, gfx::AttributeDataType::Float2, 1, "a_weight"},
|
||||
{2, gfx::AttributeDataType::Float2, 1, "a_radius"},
|
||||
};
|
||||
static constexpr UniformBlockInfo uniforms[] = {
|
||||
MLN_MTL_UNIFORM_BLOCK(3, true, false, HeatmapDrawableUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(4, true, true, HeatmapEvaluatedPropsUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(5, true, false, HeatmapInterpolateUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(6, true, true, HeatmapPermutationUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(7, true, false, ExpressionInputsUBO),
|
||||
};
|
||||
static constexpr TextureInfo textures[] = {};
|
||||
static const std::array<AttributeInfo, 3> attributes;
|
||||
static const std::array<UniformBlockInfo, 5> uniforms;
|
||||
static const std::array<TextureInfo, 0> textures;
|
||||
|
||||
static constexpr auto source = R"(
|
||||
|
||||
|
||||
@@ -14,16 +14,10 @@ struct ShaderSource<BuiltIn::HeatmapTextureShader, gfx::Backend::Type::Metal> {
|
||||
static constexpr auto vertexMainFunction = "vertexMain";
|
||||
static constexpr auto fragmentMainFunction = "fragmentMain";
|
||||
|
||||
static constexpr AttributeInfo attributes[] = {
|
||||
{0, gfx::AttributeDataType::Short2, 1, "a_pos"},
|
||||
};
|
||||
static constexpr UniformBlockInfo uniforms[] = {
|
||||
MLN_MTL_UNIFORM_BLOCK(1, true, true, HeatmapTextureDrawableUBO),
|
||||
};
|
||||
static constexpr TextureInfo textures[] = {
|
||||
{0, "u_image"},
|
||||
{1, "u_color_ramp"},
|
||||
};
|
||||
static const std::array<AttributeInfo, 1> attributes;
|
||||
static const std::array<UniformBlockInfo, 1> uniforms;
|
||||
static const std::array<TextureInfo, 2> textures;
|
||||
|
||||
static constexpr auto source = R"(
|
||||
|
||||
struct VertexStage {
|
||||
|
||||
@@ -14,17 +14,9 @@ struct ShaderSource<BuiltIn::HillshadeShader, gfx::Backend::Type::Metal> {
|
||||
static constexpr auto vertexMainFunction = "vertexMain";
|
||||
static constexpr auto fragmentMainFunction = "fragmentMain";
|
||||
|
||||
static constexpr AttributeInfo attributes[] = {
|
||||
{0, gfx::AttributeDataType::Short2, 1, "a_pos"},
|
||||
{1, gfx::AttributeDataType::Short2, 1, "a_texture_pos"},
|
||||
};
|
||||
static constexpr UniformBlockInfo uniforms[] = {
|
||||
MLN_MTL_UNIFORM_BLOCK(2, true, true, HillshadeDrawableUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(3, false, true, HillshadeEvaluatedPropsUBO),
|
||||
};
|
||||
static constexpr TextureInfo textures[] = {
|
||||
{0, "u_image"},
|
||||
};
|
||||
static const std::array<AttributeInfo, 2> attributes;
|
||||
static const std::array<UniformBlockInfo, 2> uniforms;
|
||||
static const std::array<TextureInfo, 1> textures;
|
||||
|
||||
static constexpr auto source = R"(
|
||||
|
||||
|
||||
@@ -14,16 +14,10 @@ struct ShaderSource<BuiltIn::HillshadePrepareShader, gfx::Backend::Type::Metal>
|
||||
static constexpr auto vertexMainFunction = "vertexMain";
|
||||
static constexpr auto fragmentMainFunction = "fragmentMain";
|
||||
|
||||
static constexpr AttributeInfo attributes[] = {
|
||||
{0, gfx::AttributeDataType::Short2, 1, "a_pos"},
|
||||
{1, gfx::AttributeDataType::Short2, 1, "a_texture_pos"},
|
||||
};
|
||||
static constexpr UniformBlockInfo uniforms[] = {
|
||||
MLN_MTL_UNIFORM_BLOCK(2, true, true, HillshadePrepareDrawableUBO),
|
||||
};
|
||||
static constexpr TextureInfo textures[] = {
|
||||
{0, "u_image"},
|
||||
};
|
||||
static const std::array<AttributeInfo, 2> attributes;
|
||||
static const std::array<UniformBlockInfo, 1> uniforms;
|
||||
static const std::array<TextureInfo, 1> textures;
|
||||
|
||||
static constexpr auto source = R"(
|
||||
|
||||
struct VertexStage {
|
||||
|
||||
@@ -14,24 +14,9 @@ struct ShaderSource<BuiltIn::LineShader, gfx::Backend::Type::Metal> {
|
||||
static constexpr auto vertexMainFunction = "vertexMain";
|
||||
static constexpr auto fragmentMainFunction = "fragmentMain";
|
||||
|
||||
static constexpr AttributeInfo attributes[] = {
|
||||
{0, gfx::AttributeDataType::Short2, 1, "a_pos_normal"},
|
||||
{1, gfx::AttributeDataType::UByte4, 1, "a_data"},
|
||||
{2, gfx::AttributeDataType::Float4, 1, "a_color"},
|
||||
{3, gfx::AttributeDataType::Float2, 1, "a_blur"},
|
||||
{4, gfx::AttributeDataType::Float2, 1, "a_opacity"},
|
||||
{5, gfx::AttributeDataType::Float2, 1, "a_gapwidth"},
|
||||
{6, gfx::AttributeDataType::Float2, 1, "a_offset"},
|
||||
{7, gfx::AttributeDataType::Float2, 1, "a_width"},
|
||||
};
|
||||
static constexpr UniformBlockInfo uniforms[] = {
|
||||
MLN_MTL_UNIFORM_BLOCK(8, true, true, LineUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(9, true, false, LinePropertiesUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(10, true, false, LineInterpolationUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(11, true, true, LinePermutationUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(12, true, false, ExpressionInputsUBO),
|
||||
};
|
||||
static constexpr TextureInfo textures[] = {};
|
||||
static const std::array<AttributeInfo, 8> attributes;
|
||||
static const std::array<UniformBlockInfo, 5> uniforms;
|
||||
static const std::array<TextureInfo, 0> textures;
|
||||
|
||||
static constexpr auto source = R"(
|
||||
|
||||
@@ -143,28 +128,9 @@ struct ShaderSource<BuiltIn::LinePatternShader, gfx::Backend::Type::Metal> {
|
||||
static constexpr auto vertexMainFunction = "vertexMain";
|
||||
static constexpr auto fragmentMainFunction = "fragmentMain";
|
||||
|
||||
static constexpr AttributeInfo attributes[] = {
|
||||
{0, gfx::AttributeDataType::Short2, 1, "a_pos_normal"},
|
||||
{1, gfx::AttributeDataType::UByte4, 1, "a_data"},
|
||||
{2, gfx::AttributeDataType::Float2, 1, "a_blur"},
|
||||
{3, gfx::AttributeDataType::Float2, 1, "a_opacity"},
|
||||
{4, gfx::AttributeDataType::Float2, 1, "a_gapwidth"},
|
||||
{5, gfx::AttributeDataType::Float2, 1, "a_offset"},
|
||||
{6, gfx::AttributeDataType::Float2, 1, "a_width"},
|
||||
{7, gfx::AttributeDataType::UShort4, 1, "a_pattern_from"},
|
||||
{8, gfx::AttributeDataType::UShort4, 1, "a_pattern_to"},
|
||||
};
|
||||
static constexpr UniformBlockInfo uniforms[] = {
|
||||
MLN_MTL_UNIFORM_BLOCK(9, true, true, LinePatternUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(10, true, false, LinePatternPropertiesUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(11, true, false, LinePatternInterpolationUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(12, true, false, LinePatternTilePropertiesUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(13, true, true, LinePermutationUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(14, true, false, ExpressionInputsUBO),
|
||||
};
|
||||
static constexpr TextureInfo textures[] = {
|
||||
{0, "u_image"},
|
||||
};
|
||||
static const std::array<AttributeInfo, 9> attributes;
|
||||
static const std::array<UniformBlockInfo, 6> uniforms;
|
||||
static const std::array<TextureInfo, 1> textures;
|
||||
|
||||
static constexpr auto source = R"(
|
||||
|
||||
|
||||
@@ -14,25 +14,9 @@ struct ShaderSource<BuiltIn::LineGradientShader, gfx::Backend::Type::Metal> {
|
||||
static constexpr auto vertexMainFunction = "vertexMain";
|
||||
static constexpr auto fragmentMainFunction = "fragmentMain";
|
||||
|
||||
static constexpr AttributeInfo attributes[] = {
|
||||
{0, gfx::AttributeDataType::Short2, 1, "a_pos_normal"},
|
||||
{1, gfx::AttributeDataType::UByte4, 1, "a_data"},
|
||||
{2, gfx::AttributeDataType::Float2, 1, "a_blur"},
|
||||
{3, gfx::AttributeDataType::Float2, 1, "a_opacity"},
|
||||
{4, gfx::AttributeDataType::Float2, 1, "a_gapwidth"},
|
||||
{5, gfx::AttributeDataType::Float2, 1, "a_offset"},
|
||||
{6, gfx::AttributeDataType::Float2, 1, "a_width"},
|
||||
};
|
||||
static constexpr UniformBlockInfo uniforms[] = {
|
||||
MLN_MTL_UNIFORM_BLOCK(7, true, true, LineGradientUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(8, true, false, LineGradientPropertiesUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(9, true, false, LineGradientInterpolationUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(10, true, true, LinePermutationUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(11, true, false, ExpressionInputsUBO),
|
||||
};
|
||||
static constexpr TextureInfo textures[] = {
|
||||
{0, "u_image"},
|
||||
};
|
||||
static const std::array<AttributeInfo, 7> attributes;
|
||||
static const std::array<UniformBlockInfo, 5> uniforms;
|
||||
static const std::array<TextureInfo, 1> textures;
|
||||
|
||||
static constexpr auto source = R"(
|
||||
struct VertexStage {
|
||||
|
||||
@@ -14,17 +14,10 @@ struct ShaderSource<BuiltIn::RasterShader, gfx::Backend::Type::Metal> {
|
||||
static constexpr auto vertexMainFunction = "vertexMain";
|
||||
static constexpr auto fragmentMainFunction = "fragmentMain";
|
||||
|
||||
static constexpr AttributeInfo attributes[] = {
|
||||
{0, gfx::AttributeDataType::Short2, 1, "a_pos"},
|
||||
{1, gfx::AttributeDataType::Short2, 1, "a_texture_pos"},
|
||||
};
|
||||
static constexpr UniformBlockInfo uniforms[] = {
|
||||
MLN_MTL_UNIFORM_BLOCK(2, true, true, RasterDrawableUBO),
|
||||
};
|
||||
static constexpr TextureInfo textures[] = {
|
||||
{0, "u_image0"},
|
||||
{1, "u_image1"},
|
||||
};
|
||||
static const std::array<AttributeInfo, 2> attributes;
|
||||
static const std::array<UniformBlockInfo, 1> uniforms;
|
||||
static const std::array<TextureInfo, 2> textures;
|
||||
|
||||
static constexpr auto source = R"(
|
||||
|
||||
struct VertexStage {
|
||||
|
||||
@@ -22,32 +22,20 @@ public:
|
||||
~ShaderGroup() noexcept override = default;
|
||||
|
||||
gfx::ShaderPtr getOrCreateShader(gfx::Context& gfxContext,
|
||||
const std::vector<std::string>& propertiesAsUniforms,
|
||||
const std::unordered_set<StringIdentity>& propertiesAsUniforms,
|
||||
std::string_view /*firstAttribName*/) override {
|
||||
constexpr auto& name = shaders::ShaderSource<ShaderID, gfx::Backend::Type::Metal>::name;
|
||||
constexpr auto& source = shaders::ShaderSource<ShaderID, gfx::Backend::Type::Metal>::source;
|
||||
constexpr auto& vertMain = shaders::ShaderSource<ShaderID, gfx::Backend::Type::Metal>::vertexMainFunction;
|
||||
constexpr auto& fragMain = shaders::ShaderSource<ShaderID, gfx::Backend::Type::Metal>::fragmentMainFunction;
|
||||
|
||||
uint32_t key = 0;
|
||||
assert(propertiesAsUniforms.size() < 32);
|
||||
std::unordered_map<std::string, std::string> additionalDefines(propertiesAsUniforms.size());
|
||||
for (unsigned int i = 0; i < propertiesAsUniforms.size(); i++) {
|
||||
if (!propertiesAsUniforms[i].empty()) {
|
||||
key |= 1U << i;
|
||||
auto name = std::string("HAS_UNIFORM_u_") + propertiesAsUniforms[i];
|
||||
additionalDefines.insert(std::make_pair(std::move(name), "1"));
|
||||
}
|
||||
}
|
||||
|
||||
const std::string shaderName = std::string(name); // + "#" + std::to_string(key);
|
||||
const std::string shaderName = std::string(name);
|
||||
const auto shaderSource = std::string(shaders::prelude) + source;
|
||||
|
||||
auto shader = get<mtl::ShaderProgram>(shaderName);
|
||||
if (!shader) {
|
||||
auto& context = static_cast<Context&>(gfxContext);
|
||||
shader = context.createProgram(
|
||||
shaderName, shaderSource, vertMain, fragMain, programParameters, additionalDefines);
|
||||
shader = context.createProgram(shaderName, shaderSource, vertMain, fragMain, programParameters, {});
|
||||
assert(shader);
|
||||
if (!shader || !registerShader(shader, shaderName)) {
|
||||
assert(false);
|
||||
|
||||
@@ -15,21 +15,27 @@
|
||||
namespace mbgl {
|
||||
namespace shaders {
|
||||
struct AttributeInfo {
|
||||
AttributeInfo(std::size_t index, gfx::AttributeDataType dataType, std::size_t count, std::string_view name);
|
||||
std::size_t index;
|
||||
gfx::AttributeDataType dataType;
|
||||
std::size_t count;
|
||||
std::string_view name;
|
||||
StringIdentity nameID;
|
||||
};
|
||||
struct UniformBlockInfo {
|
||||
UniformBlockInfo(std::size_t index, bool vertex, bool fragment, std::size_t size, std::string_view name);
|
||||
std::size_t index;
|
||||
bool vertex;
|
||||
bool fragment;
|
||||
std::size_t size;
|
||||
std::string_view name;
|
||||
StringIdentity nameID;
|
||||
};
|
||||
struct TextureInfo {
|
||||
TextureInfo(std::size_t index, std::string_view name);
|
||||
std::size_t index;
|
||||
std::string_view name;
|
||||
StringIdentity nameID;
|
||||
};
|
||||
} // namespace shaders
|
||||
namespace mtl {
|
||||
|
||||
@@ -14,28 +14,9 @@ struct ShaderSource<BuiltIn::SymbolIconShader, gfx::Backend::Type::Metal> {
|
||||
static constexpr auto vertexMainFunction = "vertexMain";
|
||||
static constexpr auto fragmentMainFunction = "fragmentMain";
|
||||
|
||||
static constexpr AttributeInfo attributes[] = {
|
||||
// always attributes
|
||||
{0, gfx::AttributeDataType::Short4, 1, "a_pos_offset"},
|
||||
{1, gfx::AttributeDataType::UShort4, 1, "a_data"},
|
||||
{2, gfx::AttributeDataType::Short4, 1, "a_pixeloffset"},
|
||||
{3, gfx::AttributeDataType::Float3, 1, "a_projected_pos"},
|
||||
{4, gfx::AttributeDataType::Float, 1, "a_fade_opacity"},
|
||||
|
||||
// sometimes uniforms
|
||||
{5, gfx::AttributeDataType::Float, 1, "a_opacity"},
|
||||
};
|
||||
static constexpr UniformBlockInfo uniforms[] = {
|
||||
MLN_MTL_UNIFORM_BLOCK(8, true, true, SymbolDrawableUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(9, true, true, SymbolDrawablePaintUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(10, true, false, SymbolDrawableTilePropsUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(11, true, false, SymbolDrawableInterpolateUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(12, true, true, SymbolPermutationUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(13, true, false, ExpressionInputsUBO),
|
||||
};
|
||||
static constexpr TextureInfo textures[] = {
|
||||
{0, "u_texture"},
|
||||
};
|
||||
static const std::array<AttributeInfo, 6> attributes;
|
||||
static const std::array<UniformBlockInfo, 6> uniforms;
|
||||
static const std::array<TextureInfo, 1> textures;
|
||||
|
||||
static constexpr auto source = R"(
|
||||
struct VertexStage {
|
||||
|
||||
@@ -14,32 +14,9 @@ struct ShaderSource<BuiltIn::SymbolSDFIconShader, gfx::Backend::Type::Metal> {
|
||||
static constexpr auto vertexMainFunction = "vertexMain";
|
||||
static constexpr auto fragmentMainFunction = "fragmentMain";
|
||||
|
||||
static constexpr AttributeInfo attributes[] = {
|
||||
// always attributes
|
||||
{0, gfx::AttributeDataType::Short4, 1, "a_pos_offset"},
|
||||
{1, gfx::AttributeDataType::UShort4, 1, "a_data"},
|
||||
{2, gfx::AttributeDataType::Short4, 1, "a_pixeloffset"},
|
||||
{3, gfx::AttributeDataType::Float3, 1, "a_projected_pos"},
|
||||
{4, gfx::AttributeDataType::Float, 1, "a_fade_opacity"},
|
||||
|
||||
// sometimes uniforms
|
||||
{5, gfx::AttributeDataType::Float4, 1, "a_fill_color"},
|
||||
{6, gfx::AttributeDataType::Float4, 1, "a_halo_color"},
|
||||
{7, gfx::AttributeDataType::Float, 1, "a_opacity"},
|
||||
{8, gfx::AttributeDataType::Float, 1, "a_halo_width"},
|
||||
{9, gfx::AttributeDataType::Float, 1, "a_halo_blur"},
|
||||
};
|
||||
static constexpr UniformBlockInfo uniforms[] = {
|
||||
MLN_MTL_UNIFORM_BLOCK(10, true, true, SymbolDrawableUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(11, true, false, SymbolDrawablePaintUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(12, true, true, SymbolDrawableTilePropsUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(13, true, false, SymbolDrawableInterpolateUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(14, true, true, SymbolPermutationUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(15, true, false, ExpressionInputsUBO),
|
||||
};
|
||||
static constexpr TextureInfo textures[] = {
|
||||
{0, "u_texture"},
|
||||
};
|
||||
static const std::array<AttributeInfo, 10> attributes;
|
||||
static const std::array<UniformBlockInfo, 6> uniforms;
|
||||
static const std::array<TextureInfo, 1> textures;
|
||||
|
||||
static constexpr auto source = R"(
|
||||
struct VertexStage {
|
||||
|
||||
@@ -14,32 +14,9 @@ struct ShaderSource<BuiltIn::SymbolTextAndIconShader, gfx::Backend::Type::Metal>
|
||||
static constexpr auto vertexMainFunction = "vertexMain";
|
||||
static constexpr auto fragmentMainFunction = "fragmentMain";
|
||||
|
||||
static constexpr AttributeInfo attributes[] = {
|
||||
// always attributes
|
||||
{0, gfx::AttributeDataType::Short4, 1, "a_pos_offset"},
|
||||
{1, gfx::AttributeDataType::UShort4, 1, "a_data"},
|
||||
{2, gfx::AttributeDataType::Float3, 1, "a_projected_pos"},
|
||||
{3, gfx::AttributeDataType::Float, 1, "a_fade_opacity"},
|
||||
|
||||
// sometimes uniforms
|
||||
{4, gfx::AttributeDataType::Float4, 1, "a_fill_color"},
|
||||
{5, gfx::AttributeDataType::Float4, 1, "a_halo_color"},
|
||||
{6, gfx::AttributeDataType::Float, 1, "a_opacity"},
|
||||
{7, gfx::AttributeDataType::Float, 1, "a_halo_width"},
|
||||
{8, gfx::AttributeDataType::Float, 1, "a_halo_blur"},
|
||||
};
|
||||
static constexpr UniformBlockInfo uniforms[] = {
|
||||
MLN_MTL_UNIFORM_BLOCK(9, true, true, SymbolDrawableUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(10, true, false, SymbolDrawablePaintUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(11, true, true, SymbolDrawableTilePropsUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(12, true, false, SymbolDrawableInterpolateUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(13, true, true, SymbolPermutationUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(14, true, false, ExpressionInputsUBO),
|
||||
};
|
||||
static constexpr TextureInfo textures[] = {
|
||||
{0, "u_texture"},
|
||||
{1, "u_texture_icon"},
|
||||
};
|
||||
static const std::array<AttributeInfo, 9> attributes;
|
||||
static const std::array<UniformBlockInfo, 6> uniforms;
|
||||
static const std::array<TextureInfo, 2> textures;
|
||||
|
||||
static constexpr auto source = R"(
|
||||
#define SDF 1.0
|
||||
@@ -141,7 +118,7 @@ FragmentStage vertex vertexMain(thread const VertexStage vertx [[stage_in]],
|
||||
const float2x2 rotation_matrix = float2x2(angle_cos, -1.0 * angle_sin, angle_sin, angle_cos);
|
||||
|
||||
const float4 projected_pos = drawable.label_plane_matrix * float4(vertx.projected_pos.xy, 0.0, 1.0);
|
||||
const float2 pos_rot = a_offset / 32.0 * fontScale + a_pxoffset;
|
||||
const float2 pos_rot = a_offset / 32.0 * fontScale;
|
||||
const float2 pos0 = projected_pos.xy / projected_pos.w + rotation_matrix * pos_rot;
|
||||
const float4 position = drawable.coord_matrix * float4(pos0, 0.0, 1.0);
|
||||
const float gamma_scale = position.w;
|
||||
@@ -178,7 +155,7 @@ half4 fragment fragmentMain(FragmentStage in [[stage_in]],
|
||||
|
||||
if (in.data1.w == ICON) {
|
||||
const float2 tex_icon = in.data0.zw;
|
||||
const float alpha = opacity * fade_opacity;
|
||||
const float alpha = in.opacity * fade_opacity;
|
||||
return half4(icon_image.sample(icon_sampler, tex_icon) * alpha);
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
using StringIdentity = size_t;
|
||||
using StringIdentity = std::size_t;
|
||||
|
||||
class StringIndexer {
|
||||
public:
|
||||
|
||||
@@ -55,7 +55,7 @@ cc_library(
|
||||
"src/mbgl/util/thread_local.cpp",
|
||||
"src/mbgl/util/utf.cpp",
|
||||
] + select({
|
||||
"//:metal_renderer": [],
|
||||
"//:metal_renderer": ["src/mbgl/mtl/headless_backend.cpp"],
|
||||
"//conditions:default": ["src/mbgl/gl/headless_backend.cpp"],
|
||||
}) + select({
|
||||
"//:linux": [
|
||||
@@ -89,7 +89,7 @@ cc_library(
|
||||
"include/mbgl/storage/sqlite3.hpp",
|
||||
"include/mbgl/text/unaccent.hpp",
|
||||
] + select({
|
||||
"//:metal_renderer": [],
|
||||
"//:metal_renderer": ["include/mbgl/mtl/headless_backend.hpp"],
|
||||
"//conditions:default": ["include/mbgl/gl/headless_backend.hpp"],
|
||||
}),
|
||||
copts = CPP_FLAGS + MAPLIBRE_FLAGS,
|
||||
|
||||
@@ -24,11 +24,7 @@ public:
|
||||
static std::unique_ptr<HeadlessBackend> Create(const Size size = {256, 256},
|
||||
SwapBehaviour swapBehavior = SwapBehaviour::NoFlush,
|
||||
const gfx::ContextMode contextMode = gfx::ContextMode::Unique) {
|
||||
#if MLN_RENDER_BACKEND_METAL
|
||||
throw std::runtime_error("Not yet implemented");
|
||||
#else // MLN_RENDER_BACKEND_OPENGL
|
||||
return Backend::Create<HeadlessBackend, Size, SwapBehaviour, gfx::ContextMode>(size, swapBehavior, contextMode);
|
||||
#endif
|
||||
}
|
||||
|
||||
virtual PremultipliedImage readStillImage() = 0;
|
||||
|
||||
33
platform/default/include/mbgl/mtl/headless_backend.hpp
Normal file
33
platform/default/include/mbgl/mtl/headless_backend.hpp
Normal file
@@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/gfx/headless_backend.hpp>
|
||||
#include <mbgl/mtl/renderer_backend.hpp>
|
||||
#include <memory>
|
||||
#include <functional>
|
||||
|
||||
namespace mbgl {
|
||||
namespace mtl {
|
||||
|
||||
class HeadlessBackend final : public mtl::RendererBackend, public gfx::HeadlessBackend {
|
||||
public:
|
||||
HeadlessBackend(Size = {256, 256},
|
||||
SwapBehaviour = SwapBehaviour::NoFlush,
|
||||
gfx::ContextMode = gfx::ContextMode::Unique);
|
||||
~HeadlessBackend() override;
|
||||
void updateAssumedState() override;
|
||||
gfx::Renderable& getDefaultRenderable() override;
|
||||
PremultipliedImage readStillImage() override;
|
||||
RendererBackend* getRendererBackend() override;
|
||||
SwapBehaviour getSwapBehaviour();
|
||||
|
||||
private:
|
||||
void activate() override;
|
||||
void deactivate() override;
|
||||
|
||||
private:
|
||||
bool active = false;
|
||||
SwapBehaviour swapBehaviour = SwapBehaviour::NoFlush;
|
||||
};
|
||||
|
||||
} // namespace mtl
|
||||
} // namespace mbgl
|
||||
107
platform/default/src/mbgl/mtl/headless_backend.cpp
Normal file
107
platform/default/src/mbgl/mtl/headless_backend.cpp
Normal file
@@ -0,0 +1,107 @@
|
||||
#include <mbgl/mtl/headless_backend.hpp>
|
||||
#include <mbgl/mtl/renderable_resource.hpp>
|
||||
#include <mbgl/mtl/offscreen_texture.hpp>
|
||||
#include <mbgl/mtl/context.hpp>
|
||||
#include <mbgl/gfx/backend_scope.hpp>
|
||||
|
||||
#include <cassert>
|
||||
#include <stdexcept>
|
||||
#include <type_traits>
|
||||
#include <Metal/Metal.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace mtl {
|
||||
|
||||
class HeadlessRenderableResource final : public mtl::RenderableResource {
|
||||
public:
|
||||
HeadlessRenderableResource(HeadlessBackend& backend_, mtl::Context& context_, Size size)
|
||||
: backend(backend_),
|
||||
context(context_) {
|
||||
offscreenTexture = context.createOffscreenTexture(size, gfx::TextureChannelDataType::UnsignedByte, true, true);
|
||||
}
|
||||
|
||||
~HeadlessRenderableResource() noexcept override = default;
|
||||
|
||||
void bind() override { offscreenTexture->getResource<RenderableResource>().bind(); }
|
||||
|
||||
void swap() override { offscreenTexture->getResource<RenderableResource>().swap(); }
|
||||
|
||||
PremultipliedImage readStillImage() { return offscreenTexture->readStillImage(); }
|
||||
|
||||
const RendererBackend& getBackend() const override { return context.getBackend(); }
|
||||
|
||||
const MTLCommandBufferPtr& getCommandBuffer() const override {
|
||||
return offscreenTexture->getResource<RenderableResource>().getCommandBuffer();
|
||||
}
|
||||
|
||||
MTLBlitPassDescriptorPtr getUploadPassDescriptor() const override {
|
||||
return offscreenTexture->getResource<RenderableResource>().getUploadPassDescriptor();
|
||||
}
|
||||
|
||||
const MTLRenderPassDescriptorPtr& getRenderPassDescriptor() const override {
|
||||
return offscreenTexture->getResource<RenderableResource>().getRenderPassDescriptor();
|
||||
}
|
||||
|
||||
HeadlessBackend& backend;
|
||||
Context& context;
|
||||
std::unique_ptr<gfx::OffscreenTexture> offscreenTexture;
|
||||
};
|
||||
|
||||
HeadlessBackend::HeadlessBackend(const Size size_,
|
||||
gfx::HeadlessBackend::SwapBehaviour swapBehaviour_,
|
||||
const gfx::ContextMode contextMode_)
|
||||
: mbgl::mtl::RendererBackend(contextMode_),
|
||||
mbgl::gfx::HeadlessBackend(size_),
|
||||
swapBehaviour(swapBehaviour_) {}
|
||||
|
||||
HeadlessBackend::~HeadlessBackend() {
|
||||
gfx::BackendScope guard{*this, gfx::BackendScope::ScopeType::Implicit};
|
||||
// Explicitly reset the renderable resource
|
||||
resource.reset();
|
||||
// Explicitly reset the context
|
||||
context.reset();
|
||||
}
|
||||
|
||||
void HeadlessBackend::activate() {
|
||||
active = true;
|
||||
}
|
||||
|
||||
void HeadlessBackend::deactivate() {
|
||||
active = false;
|
||||
}
|
||||
|
||||
gfx::Renderable& HeadlessBackend::getDefaultRenderable() {
|
||||
if (!resource) {
|
||||
resource = std::make_unique<HeadlessRenderableResource>(*this, static_cast<mtl::Context&>(getContext()), size);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
void HeadlessBackend::updateAssumedState() {
|
||||
// no-op
|
||||
}
|
||||
|
||||
PremultipliedImage HeadlessBackend::readStillImage() {
|
||||
return getResource<HeadlessRenderableResource>().readStillImage();
|
||||
}
|
||||
|
||||
RendererBackend* HeadlessBackend::getRendererBackend() {
|
||||
return this;
|
||||
}
|
||||
|
||||
HeadlessBackend::SwapBehaviour HeadlessBackend::getSwapBehaviour() {
|
||||
return swapBehaviour;
|
||||
}
|
||||
|
||||
} // namespace mtl
|
||||
|
||||
namespace gfx {
|
||||
|
||||
template <>
|
||||
std::unique_ptr<gfx::HeadlessBackend> Backend::Create<gfx::Backend::Type::Metal>(
|
||||
const Size size, gfx::HeadlessBackend::SwapBehaviour swapBehavior, const gfx::ContextMode contextMode) {
|
||||
return std::make_unique<mtl::HeadlessBackend>(size, swapBehavior, contextMode);
|
||||
}
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace mbgl
|
||||
@@ -1,6 +1,6 @@
|
||||
#import "MBXFrameTimeGraphView.h"
|
||||
|
||||
const CGFloat MBXFrameTimeExaggeration = 4.f * 1000.f;
|
||||
const CGFloat MBXFrameTimeExaggeration = 10.f;
|
||||
const CGFloat MBXFrameTimeBarWidth = 4.f;
|
||||
|
||||
@interface MBXFrameTimeGraphView ()
|
||||
@@ -58,7 +58,7 @@ const CGFloat MBXFrameTimeBarWidth = 4.f;
|
||||
if (!CGRectEqualToRect(self.scrollLayer.frame, self.bounds)) {
|
||||
self.scrollLayer.frame = self.bounds;
|
||||
|
||||
CGRect thresholdLineRect = CGRectMake(0, self.frame.size.height - [self renderDurationTargetMilliseconds], self.frame.size.width, 1);
|
||||
CGRect thresholdLineRect = CGRectMake(0, self.frame.size.height - self.frame.size.height * MBXFrameTimeExaggeration * [self renderDurationTargetMilliseconds], self.frame.size.width, 1);
|
||||
|
||||
{
|
||||
CGPathRef path = CGPathCreateWithRect(thresholdLineRect, nil);
|
||||
@@ -96,8 +96,8 @@ const CGFloat MBXFrameTimeBarWidth = 4.f;
|
||||
maximumFramesPerSecond = 60;
|
||||
}
|
||||
|
||||
CGFloat target = (1.0 / maximumFramesPerSecond) * MBXFrameTimeExaggeration;
|
||||
return [self roundedFloat:target];
|
||||
CGFloat target = (1.0 / maximumFramesPerSecond);
|
||||
return target;
|
||||
}
|
||||
|
||||
- (CGFloat)roundedFloat:(CGFloat)f {
|
||||
@@ -112,7 +112,7 @@ const CGFloat MBXFrameTimeBarWidth = 4.f;
|
||||
- (CAShapeLayer *)barWithFrameDuration:(CFTimeInterval)frameDuration {
|
||||
CAShapeLayer *bar = [CAShapeLayer layer];
|
||||
|
||||
CGRect barRect = CGRectMake(0, 0, MBXFrameTimeBarWidth, -(fminf(frameDuration * MBXFrameTimeExaggeration, self.frame.size.height)));
|
||||
CGRect barRect = CGRectMake(0, 0, MBXFrameTimeBarWidth, -(fminf(frameDuration * MBXFrameTimeExaggeration * self.frame.size.height, self.frame.size.height)));
|
||||
UIBezierPath *barPath = [UIBezierPath bezierPathWithRect:barRect];
|
||||
bar.path = barPath.CGPath;
|
||||
bar.fillColor = [self colorForFrameDuration:frameDuration].CGColor;
|
||||
@@ -121,15 +121,15 @@ const CGFloat MBXFrameTimeBarWidth = 4.f;
|
||||
}
|
||||
|
||||
- (UIColor *)colorForFrameDuration:(CFTimeInterval)frameDuration {
|
||||
CGFloat renderDurationTargetMilliseconds = [self renderDurationTargetMilliseconds];
|
||||
frameDuration *= MBXFrameTimeExaggeration;
|
||||
const double greenLevel = [self renderDurationTargetMilliseconds];
|
||||
const double yellowLevel = greenLevel * 3.0;
|
||||
|
||||
if (frameDuration < renderDurationTargetMilliseconds && frameDuration > (renderDurationTargetMilliseconds * 0.75)) {
|
||||
return self.warningColor;
|
||||
} else if (frameDuration > renderDurationTargetMilliseconds) {
|
||||
return self.dangerColor;
|
||||
} else {
|
||||
if (frameDuration <= greenLevel) {
|
||||
return self.safeColor;
|
||||
} else if (frameDuration <= yellowLevel) {
|
||||
return self.warningColor;
|
||||
} else {
|
||||
return self.dangerColor;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -69,6 +69,7 @@ typedef NS_ENUM(NSInteger, MBXSettingsAnnotationsRows) {
|
||||
MBXSettingsAnnotations10000Sprites,
|
||||
MBXSettingsAnnotationAnimation,
|
||||
MBXSettingsAnnotationsTestShapes,
|
||||
MBXSettingsAnnotationsManyTestShapes,
|
||||
MBXSettingsAnnotationsCustomCallout,
|
||||
MBXSettingsAnnotationsQueryAnnotations,
|
||||
MBXSettingsAnnotationsCustomUserDot,
|
||||
@@ -400,6 +401,7 @@ CLLocationCoordinate2D randomWorldCoordinate(void) {
|
||||
@"Add 10,000 Sprites",
|
||||
@"Animate an Annotation View",
|
||||
@"Add Test Shapes",
|
||||
@"Add 10x Test Shapes",
|
||||
@"Add Point With Custom Callout",
|
||||
@"Query Annotations",
|
||||
[NSString stringWithFormat:@"%@ Custom User Dot", (_customUserLocationAnnnotationEnabled ? @"Disable" : @"Enable")],
|
||||
@@ -548,7 +550,10 @@ CLLocationCoordinate2D randomWorldCoordinate(void) {
|
||||
[self animateAnnotationView];
|
||||
break;
|
||||
case MBXSettingsAnnotationsTestShapes:
|
||||
[self addTestShapes];
|
||||
[self addTestShapes:1];
|
||||
break;
|
||||
case MBXSettingsAnnotationsManyTestShapes:
|
||||
[self addTestShapes:10];
|
||||
break;
|
||||
case MBXSettingsAnnotationsCustomCallout:
|
||||
[self addAnnotationWithCustomCallout];
|
||||
@@ -881,102 +886,107 @@ CLLocationCoordinate2D randomWorldCoordinate(void) {
|
||||
});
|
||||
};
|
||||
|
||||
- (void)addTestShapes
|
||||
- (void)addTestShapes:(NSUInteger)featuresCount
|
||||
{
|
||||
// Pacific Northwest triangle
|
||||
//
|
||||
CLLocationCoordinate2D triangleCoordinates[3] =
|
||||
{
|
||||
CLLocationCoordinate2DMake(44, -122),
|
||||
CLLocationCoordinate2DMake(46, -122),
|
||||
CLLocationCoordinate2DMake(46, -121)
|
||||
};
|
||||
|
||||
MLNPolygon *triangle = [MLNPolygon polygonWithCoordinates:triangleCoordinates count:3];
|
||||
|
||||
[self.mapView addAnnotation:triangle];
|
||||
|
||||
// West coast polyline
|
||||
//
|
||||
CLLocationCoordinate2D lineCoordinates[4] = {
|
||||
CLLocationCoordinate2DMake(47.6025, -122.3327),
|
||||
CLLocationCoordinate2DMake(45.5189, -122.6726),
|
||||
CLLocationCoordinate2DMake(37.7790, -122.4177),
|
||||
CLLocationCoordinate2DMake(34.0532, -118.2349)
|
||||
};
|
||||
MLNPolyline *line = [MLNPolyline polylineWithCoordinates:lineCoordinates count:4];
|
||||
[self.mapView addAnnotation:line];
|
||||
|
||||
// Orcas Island, WA hike polyline
|
||||
//
|
||||
NSDictionary *hike = [NSJSONSerialization JSONObjectWithData:
|
||||
[NSData dataWithContentsOfFile:
|
||||
[[NSBundle mainBundle] pathForResource:@"polyline" ofType:@"geojson"]]
|
||||
options:0
|
||||
error:nil];
|
||||
|
||||
NSArray *hikeCoordinatePairs = hike[@"features"][0][@"geometry"][@"coordinates"];
|
||||
|
||||
CLLocationCoordinate2D *polylineCoordinates = (CLLocationCoordinate2D *)malloc([hikeCoordinatePairs count] * sizeof(CLLocationCoordinate2D));
|
||||
|
||||
for (NSUInteger i = 0; i < [hikeCoordinatePairs count]; i++)
|
||||
{
|
||||
polylineCoordinates[i] = CLLocationCoordinate2DMake([hikeCoordinatePairs[i][1] doubleValue], [hikeCoordinatePairs[i][0] doubleValue]);
|
||||
}
|
||||
|
||||
MLNPolyline *polyline = [MLNPolyline polylineWithCoordinates:polylineCoordinates
|
||||
count:[hikeCoordinatePairs count]];
|
||||
|
||||
[self.mapView addAnnotation:polyline];
|
||||
|
||||
free(polylineCoordinates);
|
||||
|
||||
// PA/NJ/DE polygons
|
||||
//
|
||||
NSDictionary *threestates = [NSJSONSerialization JSONObjectWithData:
|
||||
[NSData dataWithContentsOfFile:
|
||||
[[NSBundle mainBundle] pathForResource:@"threestates" ofType:@"geojson"]]
|
||||
options:0
|
||||
error:nil];
|
||||
|
||||
for (NSDictionary *feature in threestates[@"features"])
|
||||
{
|
||||
NSArray *stateCoordinatePairs = feature[@"geometry"][@"coordinates"];
|
||||
|
||||
while ([stateCoordinatePairs count] == 1) stateCoordinatePairs = stateCoordinatePairs[0];
|
||||
|
||||
CLLocationCoordinate2D *polygonCoordinates = (CLLocationCoordinate2D *)malloc([stateCoordinatePairs count] * sizeof(CLLocationCoordinate2D));
|
||||
|
||||
for (NSUInteger i = 0; i < [stateCoordinatePairs count]; i++)
|
||||
for (int featureIndex = 0; featureIndex < featuresCount; ++featureIndex) {
|
||||
double deltaLongitude = featureIndex * 0.01;
|
||||
double deltaLatitude = -featureIndex * 0.01;
|
||||
|
||||
// Pacific Northwest triangle
|
||||
//
|
||||
CLLocationCoordinate2D triangleCoordinates[3] =
|
||||
{
|
||||
polygonCoordinates[i] = CLLocationCoordinate2DMake([stateCoordinatePairs[i][1] doubleValue], [stateCoordinatePairs[i][0] doubleValue]);
|
||||
CLLocationCoordinate2DMake(44 + deltaLatitude, -122 + deltaLongitude),
|
||||
CLLocationCoordinate2DMake(46 + deltaLatitude, -122 + deltaLongitude),
|
||||
CLLocationCoordinate2DMake(46 + deltaLatitude, -121 + deltaLongitude)
|
||||
};
|
||||
|
||||
MLNPolygon *triangle = [MLNPolygon polygonWithCoordinates:triangleCoordinates count:3];
|
||||
|
||||
[self.mapView addAnnotation:triangle];
|
||||
|
||||
// West coast polyline
|
||||
//
|
||||
CLLocationCoordinate2D lineCoordinates[4] = {
|
||||
CLLocationCoordinate2DMake(47.6025 + deltaLatitude, -122.3327 + deltaLongitude),
|
||||
CLLocationCoordinate2DMake(45.5189 + deltaLatitude, -122.6726 + deltaLongitude),
|
||||
CLLocationCoordinate2DMake(37.7790 + deltaLatitude, -122.4177 + deltaLongitude),
|
||||
CLLocationCoordinate2DMake(34.0532 + deltaLatitude, -118.2349 + deltaLongitude)
|
||||
};
|
||||
MLNPolyline *line = [MLNPolyline polylineWithCoordinates:lineCoordinates count:4];
|
||||
[self.mapView addAnnotation:line];
|
||||
|
||||
// Orcas Island, WA hike polyline
|
||||
//
|
||||
NSDictionary *hike = [NSJSONSerialization JSONObjectWithData:
|
||||
[NSData dataWithContentsOfFile:
|
||||
[[NSBundle mainBundle] pathForResource:@"polyline" ofType:@"geojson"]]
|
||||
options:0
|
||||
error:nil];
|
||||
|
||||
NSArray *hikeCoordinatePairs = hike[@"features"][0][@"geometry"][@"coordinates"];
|
||||
|
||||
CLLocationCoordinate2D *polylineCoordinates = (CLLocationCoordinate2D *)malloc([hikeCoordinatePairs count] * sizeof(CLLocationCoordinate2D));
|
||||
|
||||
for (NSUInteger i = 0; i < [hikeCoordinatePairs count]; i++)
|
||||
{
|
||||
polylineCoordinates[i] = CLLocationCoordinate2DMake([hikeCoordinatePairs[i][1] doubleValue] + deltaLatitude, [hikeCoordinatePairs[i][0] doubleValue] + deltaLongitude);
|
||||
}
|
||||
|
||||
MLNPolygon *polygon = [MLNPolygon polygonWithCoordinates:polygonCoordinates count:[stateCoordinatePairs count]];
|
||||
polygon.title = feature[@"properties"][@"NAME"];
|
||||
|
||||
[self.mapView addAnnotation:polygon];
|
||||
|
||||
free(polygonCoordinates);
|
||||
|
||||
MLNPolyline *polyline = [MLNPolyline polylineWithCoordinates:polylineCoordinates
|
||||
count:[hikeCoordinatePairs count]];
|
||||
|
||||
[self.mapView addAnnotation:polyline];
|
||||
|
||||
free(polylineCoordinates);
|
||||
|
||||
// PA/NJ/DE polygons
|
||||
//
|
||||
NSDictionary *threestates = [NSJSONSerialization JSONObjectWithData:
|
||||
[NSData dataWithContentsOfFile:
|
||||
[[NSBundle mainBundle] pathForResource:@"threestates" ofType:@"geojson"]]
|
||||
options:0
|
||||
error:nil];
|
||||
|
||||
for (NSDictionary *feature in threestates[@"features"])
|
||||
{
|
||||
NSArray *stateCoordinatePairs = feature[@"geometry"][@"coordinates"];
|
||||
|
||||
while ([stateCoordinatePairs count] == 1) stateCoordinatePairs = stateCoordinatePairs[0];
|
||||
|
||||
CLLocationCoordinate2D *polygonCoordinates = (CLLocationCoordinate2D *)malloc([stateCoordinatePairs count] * sizeof(CLLocationCoordinate2D));
|
||||
|
||||
for (NSUInteger i = 0; i < [stateCoordinatePairs count]; i++)
|
||||
{
|
||||
polygonCoordinates[i] = CLLocationCoordinate2DMake([stateCoordinatePairs[i][1] doubleValue] + deltaLatitude, [stateCoordinatePairs[i][0] doubleValue] + deltaLongitude);
|
||||
}
|
||||
|
||||
MLNPolygon *polygon = [MLNPolygon polygonWithCoordinates:polygonCoordinates count:[stateCoordinatePairs count]];
|
||||
polygon.title = feature[@"properties"][@"NAME"];
|
||||
|
||||
[self.mapView addAnnotation:polygon];
|
||||
|
||||
free(polygonCoordinates);
|
||||
}
|
||||
|
||||
// Null Island polygon with an interior hole
|
||||
//
|
||||
CLLocationCoordinate2D innerCoordinates[] = {
|
||||
CLLocationCoordinate2DMake(-5 + deltaLatitude, -5 + deltaLongitude),
|
||||
CLLocationCoordinate2DMake(-5 + deltaLatitude, 5 + deltaLongitude),
|
||||
CLLocationCoordinate2DMake(5 + deltaLatitude, 5 + deltaLongitude),
|
||||
CLLocationCoordinate2DMake(5 + deltaLatitude, -5 + deltaLongitude),
|
||||
};
|
||||
MLNPolygon *innerPolygon = [MLNPolygon polygonWithCoordinates:innerCoordinates count:sizeof(innerCoordinates) / sizeof(innerCoordinates[0])];
|
||||
CLLocationCoordinate2D outerCoordinates[] = {
|
||||
CLLocationCoordinate2DMake(-10 + deltaLatitude, -10 + deltaLongitude),
|
||||
CLLocationCoordinate2DMake(-10 + deltaLatitude, 10 + deltaLongitude),
|
||||
CLLocationCoordinate2DMake(10 + deltaLatitude, 10 + deltaLongitude),
|
||||
CLLocationCoordinate2DMake(10 + deltaLatitude, -10 + deltaLongitude),
|
||||
};
|
||||
MLNPolygon *outerPolygon = [MLNPolygon polygonWithCoordinates:outerCoordinates count:sizeof(outerCoordinates) / sizeof(outerCoordinates[0]) interiorPolygons:@[innerPolygon]];
|
||||
[self.mapView addAnnotation:outerPolygon];
|
||||
}
|
||||
|
||||
// Null Island polygon with an interior hole
|
||||
//
|
||||
CLLocationCoordinate2D innerCoordinates[] = {
|
||||
CLLocationCoordinate2DMake(-5, -5),
|
||||
CLLocationCoordinate2DMake(-5, 5),
|
||||
CLLocationCoordinate2DMake(5, 5),
|
||||
CLLocationCoordinate2DMake(5, -5),
|
||||
};
|
||||
MLNPolygon *innerPolygon = [MLNPolygon polygonWithCoordinates:innerCoordinates count:sizeof(innerCoordinates) / sizeof(innerCoordinates[0])];
|
||||
CLLocationCoordinate2D outerCoordinates[] = {
|
||||
CLLocationCoordinate2DMake(-10, -10),
|
||||
CLLocationCoordinate2DMake(-10, 10),
|
||||
CLLocationCoordinate2DMake(10, 10),
|
||||
CLLocationCoordinate2DMake(10, -10),
|
||||
};
|
||||
MLNPolygon *outerPolygon = [MLNPolygon polygonWithCoordinates:outerCoordinates count:sizeof(outerCoordinates) / sizeof(outerCoordinates[0]) interiorPolygons:@[innerPolygon]];
|
||||
[self.mapView addAnnotation:outerPolygon];
|
||||
}
|
||||
|
||||
- (void)addAnnotationWithCustomCallout
|
||||
@@ -2439,9 +2449,9 @@ CLLocationCoordinate2D randomWorldCoordinate(void) {
|
||||
return features;
|
||||
}
|
||||
|
||||
- (void)mapViewDidFinishRenderingFrame:(MLNMapView *)mapView fullyRendered:(BOOL)fullyRendered {
|
||||
- (void)mapViewDidFinishRenderingFrame:(MLNMapView *)mapView fullyRendered:(BOOL)fullyRendered frameTime:(double)frameTime {
|
||||
if (self.frameTimeGraphEnabled) {
|
||||
[self.frameTimeGraphView updatePathWithFrameDuration:mapView.frameTime];
|
||||
[self.frameTimeGraphView updatePathWithFrameDuration:frameTime];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
2
platform/ios/benchmark/assets/glyphs/.gitignore
vendored
Normal file
2
platform/ios/benchmark/assets/glyphs/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
*/*.pbf
|
||||
|
||||
2
platform/ios/benchmark/assets/tiles/.gitignore
vendored
Normal file
2
platform/ios/benchmark/assets/tiles/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
tiles/
|
||||
|
||||
@@ -69,8 +69,12 @@ public:
|
||||
return NS::TransferPtr(MTL::BlitPassDescriptor::alloc()->init());
|
||||
}
|
||||
|
||||
mbgl::mtl::MTLRenderPassDescriptorPtr getRenderPassDescriptor() const override {
|
||||
return NS::RetainPtr((__bridge MTL::RenderPassDescriptor*)mtlView.currentRenderPassDescriptor);
|
||||
const mbgl::mtl::MTLRenderPassDescriptorPtr& getRenderPassDescriptor() const override {
|
||||
if (!cachedRenderPassDescriptor) {
|
||||
auto* mtlDesc = mtlView.currentRenderPassDescriptor;
|
||||
cachedRenderPassDescriptor = NS::RetainPtr((__bridge MTL::RenderPassDescriptor*)mtlDesc);
|
||||
}
|
||||
return cachedRenderPassDescriptor;
|
||||
}
|
||||
|
||||
void swap() override {
|
||||
@@ -83,6 +87,8 @@ public:
|
||||
|
||||
commandBuffer = nil;
|
||||
commandBufferPtr.reset();
|
||||
|
||||
cachedRenderPassDescriptor.reset();
|
||||
}
|
||||
|
||||
mbgl::Size framebufferSize() {
|
||||
@@ -94,6 +100,7 @@ public:
|
||||
private:
|
||||
MLNMapViewMetalImpl& backend;
|
||||
mbgl::mtl::MTLCommandBufferPtr commandBufferPtr;
|
||||
mutable mbgl::mtl::MTLRenderPassDescriptorPtr cachedRenderPassDescriptor;
|
||||
|
||||
public:
|
||||
MLNMapViewImplDelegate* delegate = nil;
|
||||
|
||||
@@ -17,7 +17,8 @@ std::size_t VertexAttribute::getCount() const {
|
||||
return sharedRawData ? sharedRawData->getRawCount() : items.size();
|
||||
}
|
||||
|
||||
std::unique_ptr<VertexAttribute> VertexAttributeArray::nullref = nullptr;
|
||||
const std::unique_ptr<VertexAttribute> VertexAttributeArray::nullref;
|
||||
const std::string VertexAttributeArray::attributePrefix = "a_";
|
||||
|
||||
VertexAttributeArray::VertexAttributeArray(VertexAttributeArray&& other)
|
||||
: attrs(std::move(other.attrs)) {}
|
||||
|
||||
@@ -489,12 +489,11 @@ gfx::UniformBufferPtr Context::createUniformBuffer(const void* data, std::size_t
|
||||
}
|
||||
|
||||
gfx::ShaderProgramBasePtr Context::getGenericShader(gfx::ShaderRegistry& shaders, const std::string& name) {
|
||||
std::vector<std::string> emptyProperties(0);
|
||||
auto shaderGroup = shaders.getShaderGroup(name);
|
||||
if (!shaderGroup) {
|
||||
return nullptr;
|
||||
}
|
||||
return std::static_pointer_cast<gfx::ShaderProgramBase>(shaderGroup->getOrCreateShader(*this, emptyProperties));
|
||||
return std::static_pointer_cast<gfx::ShaderProgramBase>(shaderGroup->getOrCreateShader(*this, {}));
|
||||
}
|
||||
|
||||
TileLayerGroupPtr Context::createTileLayerGroup(int32_t layerIndex, std::size_t initialCapacity, std::string name) {
|
||||
|
||||
@@ -122,10 +122,10 @@ void DrawableGL::bindUniformBuffers() const {
|
||||
const auto& uniformBuffer = getUniformBuffers().get(element.first);
|
||||
if (!uniformBuffer) {
|
||||
using namespace std::string_literals;
|
||||
const auto currTileID = getTileID() ? util::toString(*getTileID()) : "<no tile>";
|
||||
const auto tileIDStr = getTileID() ? util::toString(*getTileID()) : "<no tile>";
|
||||
Log::Error(Event::General,
|
||||
"bindUniformBuffers: UBO "s + std::string(stringIndexer().get(element.first)) +
|
||||
" not found for " + util::toString(getID()) + " / " + getName() + " / " + currTileID +
|
||||
" not found for " + util::toString(getID()) + " / " + getName() + " / " + tileIDStr +
|
||||
". skipping.");
|
||||
assert(false);
|
||||
continue;
|
||||
|
||||
@@ -397,6 +397,15 @@ platform::GLenum Enum<gfx::TexturePixelType>::sizedFor<>(const gfx::TexturePixel
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case gfx::TextureChannelDataType::Float: {
|
||||
switch (value) {
|
||||
case gfx::TexturePixelType::RGBA:
|
||||
return GL_RGBA32F;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -410,6 +419,8 @@ gfx::TextureChannelDataType Enum<gfx::TextureChannelDataType>::from(const platfo
|
||||
return gfx::TextureChannelDataType::UnsignedByte;
|
||||
case GL_HALF_FLOAT:
|
||||
return gfx::TextureChannelDataType::HalfFloat;
|
||||
case GL_FLOAT:
|
||||
return gfx::TextureChannelDataType::Float;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
@@ -421,6 +432,8 @@ platform::GLenum Enum<gfx::TextureChannelDataType>::to(const gfx::TextureChannel
|
||||
return GL_UNSIGNED_BYTE;
|
||||
case gfx::TextureChannelDataType::HalfFloat:
|
||||
return GL_HALF_FLOAT;
|
||||
case gfx::TextureChannelDataType::Float:
|
||||
return GL_FLOAT;
|
||||
}
|
||||
return GL_INVALID_ENUM;
|
||||
}
|
||||
|
||||
@@ -151,12 +151,9 @@ gfx::UniformBufferPtr Context::createUniformBuffer(const void* data, std::size_t
|
||||
}
|
||||
|
||||
gfx::ShaderProgramBasePtr Context::getGenericShader(gfx::ShaderRegistry& shaders, const std::string& name) {
|
||||
std::vector<std::string> emptyProperties(0);
|
||||
auto shaderGroup = shaders.getShaderGroup(name);
|
||||
if (!shaderGroup) {
|
||||
return nullptr;
|
||||
}
|
||||
return std::static_pointer_cast<gfx::ShaderProgramBase>(shaderGroup->getOrCreateShader(*this, emptyProperties));
|
||||
const auto shaderGroup = shaders.getShaderGroup(name);
|
||||
auto shader = shaderGroup ? shaderGroup->getOrCreateShader(*this, {}) : gfx::ShaderProgramBasePtr{};
|
||||
return std::static_pointer_cast<gfx::ShaderProgramBase>(std::move(shader));
|
||||
}
|
||||
|
||||
TileLayerGroupPtr Context::createTileLayerGroup(int32_t layerIndex, std::size_t initialCapacity, std::string name) {
|
||||
@@ -189,8 +186,15 @@ bool Context::emplaceOrUpdateUniformBuffer(gfx::UniformBufferPtr& buffer, const
|
||||
|
||||
void Context::setDirtyState() {}
|
||||
|
||||
std::unique_ptr<gfx::OffscreenTexture> Context::createOffscreenTexture(Size size,
|
||||
gfx::TextureChannelDataType type,
|
||||
bool depth,
|
||||
bool stencil) {
|
||||
return std::make_unique<OffscreenTexture>(*this, size, type, depth, stencil);
|
||||
}
|
||||
|
||||
std::unique_ptr<gfx::OffscreenTexture> Context::createOffscreenTexture(Size size, gfx::TextureChannelDataType type) {
|
||||
return std::make_unique<OffscreenTexture>(*this, size, type);
|
||||
return createOffscreenTexture(size, type, false, false);
|
||||
}
|
||||
|
||||
std::unique_ptr<gfx::TextureResource> Context::createTextureResource(Size,
|
||||
|
||||
@@ -123,12 +123,32 @@ MTL::Winding mapWindingMode(const gfx::CullFaceWindingType mode) {
|
||||
} // namespace
|
||||
|
||||
void Drawable::setColorMode(const gfx::ColorMode& value) {
|
||||
pipelineState.reset();
|
||||
impl->pipelineState.reset();
|
||||
gfx::Drawable::setColorMode(value);
|
||||
}
|
||||
|
||||
void Drawable::setEnableStencil(bool value) {
|
||||
gfx::Drawable::setEnableStencil(value);
|
||||
impl->depthStencilState.reset();
|
||||
}
|
||||
|
||||
void Drawable::setEnableDepth(bool value) {
|
||||
gfx::Drawable::setEnableDepth(value);
|
||||
impl->depthStencilState.reset();
|
||||
}
|
||||
|
||||
void Drawable::setSubLayerIndex(int32_t value) {
|
||||
gfx::Drawable::setSubLayerIndex(value);
|
||||
impl->depthStencilState.reset();
|
||||
}
|
||||
|
||||
void Drawable::setDepthType(gfx::DepthMaskType value) {
|
||||
gfx::Drawable::setDepthType(value);
|
||||
impl->depthStencilState.reset();
|
||||
}
|
||||
|
||||
void Drawable::setShader(gfx::ShaderProgramBasePtr value) {
|
||||
pipelineState.reset();
|
||||
impl->pipelineState.reset();
|
||||
gfx::Drawable::setShader(value);
|
||||
}
|
||||
|
||||
@@ -151,13 +171,12 @@ void Drawable::draw(PaintParameters& parameters) const {
|
||||
return;
|
||||
}
|
||||
|
||||
if (renderPassDescriptor.has_value() && renderPass.getDescriptor() != renderPassDescriptor.value()) {
|
||||
pipelineState.reset();
|
||||
const auto& descriptor = renderPass.getDescriptor();
|
||||
if (impl->renderPassDescriptor && descriptor != *impl->renderPassDescriptor) {
|
||||
impl->pipelineState.reset();
|
||||
}
|
||||
renderPassDescriptor.emplace(gfx::RenderPassDescriptor{renderPass.getDescriptor().renderable,
|
||||
renderPass.getDescriptor().clearColor,
|
||||
renderPass.getDescriptor().clearDepth,
|
||||
renderPass.getDescriptor().clearStencil});
|
||||
impl->renderPassDescriptor.emplace(gfx::RenderPassDescriptor{
|
||||
descriptor.renderable, descriptor.clearColor, descriptor.clearDepth, descriptor.clearStencil});
|
||||
|
||||
const auto& shaderMTL = static_cast<const ShaderProgram&>(*shader);
|
||||
|
||||
@@ -165,23 +184,6 @@ void Drawable::draw(PaintParameters& parameters) const {
|
||||
const auto debugGroup = parameters.encoder->createDebugGroup(debugLabel(*this));
|
||||
#endif
|
||||
|
||||
/*
|
||||
context.setDepthMode(getIs3D() ? parameters.depthModeFor3D()
|
||||
: parameters.depthModeForSublayer(getSubLayerIndex(), getDepthType()));
|
||||
|
||||
// force disable depth test for debugging
|
||||
// context.setDepthMode({gfx::DepthFunctionType::Always, gfx::DepthMaskType::ReadOnly, {0,1}});
|
||||
|
||||
// For 3D mode, stenciling is handled by the layer group
|
||||
if (!is3D) {
|
||||
context.setStencilMode(makeStencilMode(parameters));
|
||||
}
|
||||
|
||||
context.setColorMode(getColorMode());
|
||||
context.setCullFaceMode(getCullFaceMode());
|
||||
|
||||
*/
|
||||
|
||||
bindAttributes(renderPass);
|
||||
bindUniformBuffers(renderPass);
|
||||
bindTextures(renderPass);
|
||||
@@ -207,11 +209,11 @@ void Drawable::draw(PaintParameters& parameters) const {
|
||||
encoder->setCullMode(cullMode.enabled ? mapCullMode(cullMode.side) : MTL::CullModeNone);
|
||||
encoder->setFrontFacingWinding(mapWindingMode(cullMode.winding));
|
||||
|
||||
if (!pipelineState) {
|
||||
pipelineState = shaderMTL.getRenderPipelineState(renderPassDescriptor, impl->vertexDesc, getColorMode());
|
||||
if (!impl->pipelineState) {
|
||||
impl->pipelineState = shaderMTL.getRenderPipelineState(renderPassDescriptor, impl->vertexDesc, getColorMode());
|
||||
}
|
||||
if (pipelineState) {
|
||||
encoder->setRenderPipelineState(pipelineState.get());
|
||||
if (impl->pipelineState) {
|
||||
encoder->setRenderPipelineState(impl->pipelineState.get());
|
||||
} else {
|
||||
assert(!"Failed to create render pipeline state");
|
||||
return;
|
||||
@@ -219,12 +221,30 @@ void Drawable::draw(PaintParameters& parameters) const {
|
||||
|
||||
// For 3D mode, stenciling is handled by the layer group
|
||||
if (!is3D) {
|
||||
const auto depthMode = parameters.depthModeForSublayer(getSubLayerIndex(), getDepthType());
|
||||
const auto stencilMode = enableStencil ? parameters.stencilModeForClipping(tileID->toUnwrapped())
|
||||
: gfx::StencilMode::disabled();
|
||||
if (auto depthStencilState = context.makeDepthStencilState(depthMode, stencilMode, renderPass)) {
|
||||
encoder->setDepthStencilState(depthStencilState.get());
|
||||
encoder->setStencilReferenceValue(stencilMode.ref);
|
||||
std::optional<gfx::StencilMode> newStencilMode;
|
||||
|
||||
// If we have a stencil state, we may be able to reuse it, if the tile masks haven't changed.
|
||||
// We assume that only the reference value needs to be compared.
|
||||
if (impl->depthStencilState && enableStencil) {
|
||||
newStencilMode = parameters.stencilModeForClipping(tileID->toUnwrapped());
|
||||
if (newStencilMode->ref != impl->previousStencilMode.ref) {
|
||||
// No, need to rebuild it
|
||||
impl->depthStencilState.reset();
|
||||
}
|
||||
}
|
||||
if (!impl->depthStencilState) {
|
||||
if (enableStencil && !newStencilMode) {
|
||||
newStencilMode = parameters.stencilModeForClipping(tileID->toUnwrapped());
|
||||
}
|
||||
const auto depthMode = parameters.depthModeForSublayer(getSubLayerIndex(), getDepthType());
|
||||
const auto stencilMode = enableStencil ? parameters.stencilModeForClipping(tileID->toUnwrapped())
|
||||
: gfx::StencilMode::disabled();
|
||||
impl->depthStencilState = context.makeDepthStencilState(depthMode, stencilMode, renderPass);
|
||||
impl->previousStencilMode = *newStencilMode;
|
||||
}
|
||||
if (impl->depthStencilState) {
|
||||
encoder->setDepthStencilState(impl->depthStencilState.get());
|
||||
encoder->setStencilReferenceValue(impl->previousStencilMode.ref);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -266,7 +286,7 @@ void Drawable::draw(PaintParameters& parameters) const {
|
||||
assert(mlSegment.indexOffset + mlSegment.indexLength <= indexBufferLength);
|
||||
assert(static_cast<std::size_t>(maxIndex) < mlSegment.vertexLength);
|
||||
|
||||
for (const auto& binding : attributeBindings) {
|
||||
for (const auto& binding : impl->attributeBindings) {
|
||||
if (binding) {
|
||||
if (const auto buffer = getMetalBuffer(binding ? binding->vertexBufferResource : nullptr)) {
|
||||
assert((maxIndex + mlSegment.vertexOffset) * binding->vertexStride <= buffer->length());
|
||||
@@ -348,7 +368,7 @@ void Drawable::bindAttributes(const RenderPass& renderPass) const {
|
||||
const auto& encoder = renderPass.getMetalEncoder();
|
||||
|
||||
NS::UInteger attributeIndex = 0;
|
||||
for (const auto& binding : attributeBindings) {
|
||||
for (const auto& binding : impl->attributeBindings) {
|
||||
if (const auto buffer = getMetalBuffer(binding ? binding->vertexBufferResource : nullptr)) {
|
||||
assert(binding->vertexStride * impl->vertexCount <= getBufferSize(binding->vertexBufferResource));
|
||||
encoder->setVertexBuffer(buffer, /*offset=*/0, attributeIndex);
|
||||
@@ -363,7 +383,7 @@ void Drawable::unbindAttributes(const RenderPass& renderPass) const {
|
||||
const auto& encoder = renderPass.getMetalEncoder();
|
||||
|
||||
NS::UInteger attributeIndex = 0;
|
||||
for (const auto& binding : attributeBindings) {
|
||||
for (const auto& binding : impl->attributeBindings) {
|
||||
encoder->setVertexBuffer(nullptr, /*offset=*/0, attributeIndex);
|
||||
attributeIndex += 1;
|
||||
}
|
||||
@@ -560,14 +580,14 @@ void Drawable::upload(gfx::UploadPass& uploadPass_) {
|
||||
impl->vertexAttributes.visitAttributes(
|
||||
[](const auto&, gfx::VertexAttribute& attrib) { attrib.setDirty(false); });
|
||||
|
||||
if (attributeBindings != attributeBindings_) {
|
||||
attributeBindings = attributeBindings_;
|
||||
if (impl->attributeBindings != attributeBindings_) {
|
||||
impl->attributeBindings = attributeBindings_;
|
||||
|
||||
// Create a layout descriptor for each attribute
|
||||
auto vertDesc = NS::RetainPtr(MTL::VertexDescriptor::vertexDescriptor());
|
||||
|
||||
NS::UInteger index = 0;
|
||||
for (auto& binding : attributeBindings) {
|
||||
for (auto& binding : impl->attributeBindings) {
|
||||
if (!binding) {
|
||||
assert("Missing attribute binding");
|
||||
continue;
|
||||
@@ -597,7 +617,7 @@ void Drawable::upload(gfx::UploadPass& uploadPass_) {
|
||||
}
|
||||
|
||||
impl->vertexDesc = std::move(vertDesc);
|
||||
pipelineState.reset();
|
||||
impl->pipelineState.reset();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <mbgl/gfx/uniform_buffer.hpp>
|
||||
#include <mbgl/gfx/vertex_attribute.hpp>
|
||||
#include <mbgl/mtl/mtl_fwd.hpp>
|
||||
#include <mbgl/mtl/render_pass.hpp>
|
||||
#include <mbgl/mtl/uniform_buffer.hpp>
|
||||
#include <mbgl/mtl/upload_pass.hpp>
|
||||
#include <mbgl/programs/segment.hpp>
|
||||
@@ -55,6 +56,15 @@ public:
|
||||
StringIdentity idVertexAttrName = stringIndexer().get("a_pos");
|
||||
|
||||
gfx::UniqueVertexBufferResource noBindingBuffer;
|
||||
|
||||
gfx::AttributeBindingArray attributeBindings;
|
||||
|
||||
MTLRenderPipelineStatePtr pipelineState;
|
||||
|
||||
std::optional<gfx::RenderPassDescriptor> renderPassDescriptor;
|
||||
|
||||
MTLDepthStencilStatePtr depthStencilState;
|
||||
gfx::StencilMode previousStencilMode;
|
||||
};
|
||||
|
||||
struct Drawable::DrawSegment final : public gfx::Drawable::DrawSegment {
|
||||
|
||||
@@ -11,18 +11,39 @@ namespace mtl {
|
||||
|
||||
class OffscreenTextureResource final : public RenderableResource {
|
||||
public:
|
||||
OffscreenTextureResource(Context& context_, const Size size_, const gfx::TextureChannelDataType type_)
|
||||
OffscreenTextureResource(
|
||||
Context& context_, const Size size_, const gfx::TextureChannelDataType type_, bool depth, bool stencil)
|
||||
: context(context_),
|
||||
size(size_),
|
||||
type(type_) {
|
||||
assert(!size.isEmpty());
|
||||
texture = context.createTexture2D();
|
||||
texture->setSize(size);
|
||||
texture->setFormat(gfx::TexturePixelType::RGBA, type);
|
||||
texture->setSamplerConfiguration(
|
||||
colorTexture = context.createTexture2D();
|
||||
colorTexture->setSize(size);
|
||||
colorTexture->setFormat(gfx::TexturePixelType::RGBA, type);
|
||||
colorTexture->setSamplerConfiguration(
|
||||
{gfx::TextureFilterType::Nearest, gfx::TextureWrapType::Clamp, gfx::TextureWrapType::Clamp});
|
||||
static_cast<Texture2D*>(texture.get())
|
||||
static_cast<Texture2D*>(colorTexture.get())
|
||||
->setUsage(MTL::TextureUsageShaderRead | MTL::TextureUsageShaderWrite | MTL::TextureUsageRenderTarget);
|
||||
|
||||
if (depth) {
|
||||
depthTexture = context.createTexture2D();
|
||||
depthTexture->setSize(size);
|
||||
depthTexture->setFormat(gfx::TexturePixelType::Depth, gfx::TextureChannelDataType::Float);
|
||||
depthTexture->setSamplerConfiguration(
|
||||
{gfx::TextureFilterType::Nearest, gfx::TextureWrapType::Clamp, gfx::TextureWrapType::Clamp});
|
||||
static_cast<Texture2D*>(depthTexture.get())
|
||||
->setUsage(MTL::TextureUsageShaderRead | MTL::TextureUsageShaderWrite | MTL::TextureUsageRenderTarget);
|
||||
}
|
||||
|
||||
if (stencil) {
|
||||
stencilTexture = context.createTexture2D();
|
||||
stencilTexture->setSize(size);
|
||||
stencilTexture->setFormat(gfx::TexturePixelType::Stencil, gfx::TextureChannelDataType::UnsignedByte);
|
||||
stencilTexture->setSamplerConfiguration(
|
||||
{gfx::TextureFilterType::Nearest, gfx::TextureWrapType::Clamp, gfx::TextureWrapType::Clamp});
|
||||
static_cast<Texture2D*>(stencilTexture.get())
|
||||
->setUsage(MTL::TextureUsageShaderRead | MTL::TextureUsageShaderWrite | MTL::TextureUsageRenderTarget);
|
||||
}
|
||||
}
|
||||
|
||||
~OffscreenTextureResource() noexcept override = default;
|
||||
@@ -30,7 +51,25 @@ public:
|
||||
void bind() override {
|
||||
assert(context.getBackend().getCommandQueue());
|
||||
commandBuffer = NS::RetainPtr(context.getBackend().getCommandQueue()->commandBuffer());
|
||||
texture->create();
|
||||
colorTexture->create();
|
||||
|
||||
renderPassDescriptor = NS::TransferPtr(MTL::RenderPassDescriptor::alloc()->init());
|
||||
if (auto* colorTarget = renderPassDescriptor->colorAttachments()->object(0)) {
|
||||
colorTarget->setTexture(static_cast<Texture2D*>(colorTexture.get())->getMetalTexture());
|
||||
}
|
||||
|
||||
if (depthTexture) {
|
||||
depthTexture->create();
|
||||
if (auto* depthTarget = renderPassDescriptor->depthAttachment()) {
|
||||
depthTarget->setTexture(static_cast<Texture2D*>(depthTexture.get())->getMetalTexture());
|
||||
}
|
||||
}
|
||||
if (stencilTexture) {
|
||||
stencilTexture->create();
|
||||
if (auto* stencilTarget = renderPassDescriptor->stencilAttachment()) {
|
||||
stencilTarget->setTexture(static_cast<Texture2D*>(stencilTexture.get())->getMetalTexture());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void swap() override {
|
||||
@@ -38,16 +77,24 @@ public:
|
||||
commandBuffer->commit();
|
||||
commandBuffer->waitUntilCompleted();
|
||||
commandBuffer.reset();
|
||||
renderPassDescriptor.reset();
|
||||
}
|
||||
|
||||
PremultipliedImage readStillImage() {
|
||||
assert(false);
|
||||
return PremultipliedImage();
|
||||
assert(static_cast<Texture2D*>(colorTexture.get())->getMetalTexture());
|
||||
|
||||
auto data = std::make_unique<uint8_t[]>(colorTexture->getDataSize());
|
||||
MTL::Region region = MTL::Region::Make2D(0, 0, size.width, size.height);
|
||||
NS::UInteger bytesPerRow = size.width * colorTexture->getPixelStride();
|
||||
|
||||
static_cast<Texture2D*>(colorTexture.get())->getMetalTexture()->getBytes(data.get(), bytesPerRow, region, 0);
|
||||
|
||||
return {size, std::move(data)};
|
||||
}
|
||||
|
||||
gfx::Texture2DPtr& getTexture() {
|
||||
assert(texture);
|
||||
return texture;
|
||||
assert(colorTexture);
|
||||
return colorTexture;
|
||||
}
|
||||
|
||||
const RendererBackend& getBackend() const override { return context.getBackend(); }
|
||||
@@ -55,15 +102,11 @@ public:
|
||||
const MTLCommandBufferPtr& getCommandBuffer() const override { return commandBuffer; }
|
||||
|
||||
MTLBlitPassDescriptorPtr getUploadPassDescriptor() const override {
|
||||
assert(false);
|
||||
return NS::TransferPtr(MTL::BlitPassDescriptor::alloc()->init());
|
||||
}
|
||||
|
||||
MTLRenderPassDescriptorPtr getRenderPassDescriptor() const override {
|
||||
auto renderPassDescriptor = NS::TransferPtr(MTL::RenderPassDescriptor::alloc()->init());
|
||||
if (auto* colorTarget = renderPassDescriptor->colorAttachments()->object(0)) {
|
||||
colorTarget->setTexture(static_cast<Texture2D*>(texture.get())->getMetalTexture());
|
||||
}
|
||||
const MTLRenderPassDescriptorPtr& getRenderPassDescriptor() const override {
|
||||
assert(renderPassDescriptor);
|
||||
return renderPassDescriptor;
|
||||
}
|
||||
|
||||
@@ -71,12 +114,16 @@ private:
|
||||
Context& context;
|
||||
const Size size;
|
||||
const gfx::TextureChannelDataType type;
|
||||
gfx::Texture2DPtr texture;
|
||||
gfx::Texture2DPtr colorTexture;
|
||||
gfx::Texture2DPtr depthTexture;
|
||||
gfx::Texture2DPtr stencilTexture;
|
||||
MTLCommandBufferPtr commandBuffer;
|
||||
MTLRenderPassDescriptorPtr renderPassDescriptor;
|
||||
};
|
||||
|
||||
OffscreenTexture::OffscreenTexture(Context& context, const Size size_, const gfx::TextureChannelDataType type)
|
||||
: gfx::OffscreenTexture(size, std::make_unique<OffscreenTextureResource>(context, size_, type)) {}
|
||||
OffscreenTexture::OffscreenTexture(
|
||||
Context& context, const Size size_, const gfx::TextureChannelDataType type, bool depth, bool stencil)
|
||||
: gfx::OffscreenTexture(size, std::make_unique<OffscreenTextureResource>(context, size_, type, depth, stencil)) {}
|
||||
|
||||
bool OffscreenTexture::isRenderable() {
|
||||
assert(false);
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
#include <mbgl/shaders/mtl/background_pattern.hpp>
|
||||
#include <mbgl/shaders/mtl/circle.hpp>
|
||||
#include <mbgl/shaders/mtl/clipping_mask.hpp>
|
||||
#include <mbgl/shaders/mtl/collision_box.hpp>
|
||||
#include <mbgl/shaders/mtl/collision_circle.hpp>
|
||||
#include <mbgl/shaders/mtl/fill.hpp>
|
||||
#include <mbgl/shaders/mtl/fill_extrusion.hpp>
|
||||
#include <mbgl/shaders/mtl/fill_extrusion_pattern.hpp>
|
||||
@@ -124,6 +126,8 @@ void RendererBackend::initShaders(gfx::ShaderRegistry& shaders, const ProgramPar
|
||||
shaders::BuiltIn::BackgroundPatternShader,
|
||||
shaders::BuiltIn::CircleShader,
|
||||
shaders::BuiltIn::ClippingMaskProgram,
|
||||
shaders::BuiltIn::CollisionBoxShader,
|
||||
shaders::BuiltIn::CollisionCircleShader,
|
||||
shaders::BuiltIn::FillShader,
|
||||
shaders::BuiltIn::FillOutlineShader,
|
||||
shaders::BuiltIn::FillOutlinePatternShader,
|
||||
|
||||
@@ -56,6 +56,8 @@ size_t Texture2D::getPixelStride() const noexcept {
|
||||
return 1 * numChannels();
|
||||
case gfx::TextureChannelDataType::HalfFloat:
|
||||
return 2 * numChannels();
|
||||
case gfx::TextureChannelDataType::Float:
|
||||
return 4 * numChannels();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,6 +67,10 @@ size_t Texture2D::numChannels() const noexcept {
|
||||
return 4;
|
||||
case gfx::TexturePixelType::Alpha:
|
||||
return 1;
|
||||
case gfx::TexturePixelType::Stencil:
|
||||
return 1;
|
||||
case gfx::TexturePixelType::Depth:
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
@@ -78,6 +84,8 @@ MTL::PixelFormat Texture2D::getMetalPixelFormat() const noexcept {
|
||||
return MTL::PixelFormat::PixelFormatRGBA8Unorm;
|
||||
case gfx::TexturePixelType::Alpha:
|
||||
return MTL::PixelFormat::PixelFormatA8Unorm;
|
||||
case gfx::TexturePixelType::Stencil:
|
||||
return MTL::PixelFormat::PixelFormatStencil8;
|
||||
default:
|
||||
assert(false);
|
||||
return MTL::PixelFormat::PixelFormatInvalid;
|
||||
@@ -92,6 +100,18 @@ MTL::PixelFormat Texture2D::getMetalPixelFormat() const noexcept {
|
||||
assert(false);
|
||||
return MTL::PixelFormat::PixelFormatInvalid;
|
||||
}
|
||||
case gfx::TextureChannelDataType::Float:
|
||||
switch (pixelFormat) {
|
||||
case gfx::TexturePixelType::RGBA:
|
||||
return MTL::PixelFormat::PixelFormatRGBA32Float;
|
||||
case gfx::TexturePixelType::Alpha:
|
||||
return MTL::PixelFormat::PixelFormatR32Float;
|
||||
case gfx::TexturePixelType::Depth:
|
||||
return MTL::PixelFormat::PixelFormatDepth32Float;
|
||||
default:
|
||||
assert(false);
|
||||
return MTL::PixelFormat::PixelFormatInvalid;
|
||||
}
|
||||
default:
|
||||
assert(false);
|
||||
return MTL::PixelFormat::PixelFormatInvalid;
|
||||
|
||||
@@ -66,30 +66,39 @@ shaders::ExpressionInputsUBO LayerTweaker::buildExpressionUBO(double zoom, uint6
|
||||
0};
|
||||
}
|
||||
|
||||
#if !MLN_RENDER_BACKEND_OPENGL
|
||||
void LayerTweaker::setPropertiesAsUniforms(std::vector<std::string> props) {
|
||||
if (props != propertiesAsUniforms) {
|
||||
propertiesAsUniforms = std::move(props);
|
||||
permutationUpdated = true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
bool LayerTweaker::hasPropertyAsUniform(const std::string_view attrName) const {
|
||||
// `attrName` is expected to have the "a_" prefix, while the values in `propertiesAsUniforms`
|
||||
// do not. Search for the former within the latter without allocating temporary strings.
|
||||
return propertiesAsUniforms.end() !=
|
||||
std::find_if(propertiesAsUniforms.begin(), propertiesAsUniforms.end(), [&](const auto& name) {
|
||||
return name.size() + 2 == attrName.size() && 0 == std::strcmp(name.data(), attrName.data() + 2);
|
||||
});
|
||||
bool LayerTweaker::hasPropertyAsUniform(const StringIdentity attrNameID) const {
|
||||
return propertiesAsUniforms.find(attrNameID) != propertiesAsUniforms.end();
|
||||
}
|
||||
|
||||
using namespace shaders;
|
||||
AttributeSource LayerTweaker::getAttributeSource(const std::string_view& attribName) const {
|
||||
return hasPropertyAsUniform(attribName) ? AttributeSource::Constant : AttributeSource::PerVertex;
|
||||
AttributeSource LayerTweaker::getAttributeSource(const StringIdentity attribNameID) const {
|
||||
return hasPropertyAsUniform(attribNameID) ? AttributeSource::Constant : AttributeSource::PerVertex;
|
||||
}
|
||||
#endif // MLN_RENDER_BACKEND_METAL
|
||||
|
||||
void LayerTweaker::setPropertiesAsUniforms([[maybe_unused]] const std::unordered_set<StringIdentity>& props) {
|
||||
#if MLN_RENDER_BACKEND_METAL
|
||||
if (props != propertiesAsUniforms) {
|
||||
propertiesAsUniforms = props;
|
||||
permutationUpdated = true;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !MLN_RENDER_BACKEND_METAL
|
||||
namespace {
|
||||
const std::unordered_set<StringIdentity> emptyIDSet;
|
||||
}
|
||||
#endif
|
||||
|
||||
const std::unordered_set<StringIdentity>& LayerTweaker::getPropertiesAsUniforms() const {
|
||||
#if MLN_RENDER_BACKEND_METAL
|
||||
return propertiesAsUniforms;
|
||||
#else
|
||||
return emptyIDSet;
|
||||
#endif
|
||||
}
|
||||
|
||||
void LayerTweaker::enableOverdrawInspector(bool value) {
|
||||
if (overdrawInspector != value) {
|
||||
overdrawInspector = value;
|
||||
|
||||
@@ -60,20 +60,15 @@ void CircleLayerTweaker::execute(LayerGroupBase& layerGroup,
|
||||
const auto zoom = parameters.state.getZoom();
|
||||
|
||||
#if MLN_RENDER_BACKEND_METAL
|
||||
using ShaderClass = shaders::ShaderSource<BuiltIn::CircleShader, gfx::Backend::Type::Metal>;
|
||||
if (permutationUpdated) {
|
||||
const auto source = [this](const std::string_view& attrName) {
|
||||
return hasPropertyAsUniform(attrName) ? AttributeSource::Constant : AttributeSource::PerVertex;
|
||||
};
|
||||
|
||||
const CirclePermutationUBO permutationUBO = {
|
||||
/* .color = */ {/*.source=*/source(ShaderClass::attributes[1].name), /*.expression=*/{}},
|
||||
/* .radius = */ {/*.source=*/source(ShaderClass::attributes[2].name), /*.expression=*/{}},
|
||||
/* .blur = */ {/*.source=*/source(ShaderClass::attributes[3].name), /*.expression=*/{}},
|
||||
/* .opacity = */ {/*.source=*/source(ShaderClass::attributes[4].name), /*.expression=*/{}},
|
||||
/* .stroke_color = */ {/*.source=*/source(ShaderClass::attributes[5].name), /*.expression=*/{}},
|
||||
/* .stroke_width = */ {/*.source=*/source(ShaderClass::attributes[6].name), /*.expression=*/{}},
|
||||
/* .stroke_opacity = */ {/*.source=*/source(ShaderClass::attributes[7].name), /*.expression=*/{}},
|
||||
/* .color = */ {/*.source=*/getAttributeSource<BuiltIn::CircleShader>(1), /*.expression=*/{}},
|
||||
/* .radius = */ {/*.source=*/getAttributeSource<BuiltIn::CircleShader>(2), /*.expression=*/{}},
|
||||
/* .blur = */ {/*.source=*/getAttributeSource<BuiltIn::CircleShader>(3), /*.expression=*/{}},
|
||||
/* .opacity = */ {/*.source=*/getAttributeSource<BuiltIn::CircleShader>(4), /*.expression=*/{}},
|
||||
/* .stroke_color = */ {/*.source=*/getAttributeSource<BuiltIn::CircleShader>(5), /*.expression=*/{}},
|
||||
/* .stroke_width = */ {/*.source=*/getAttributeSource<BuiltIn::CircleShader>(6), /*.expression=*/{}},
|
||||
/* .stroke_opacity = */ {/*.source=*/getAttributeSource<BuiltIn::CircleShader>(7), /*.expression=*/{}},
|
||||
/* .overdrawInspector = */ overdrawInspector,
|
||||
/* .pad = */ 0,
|
||||
0,
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <mbgl/renderer/render_tree.hpp>
|
||||
#include <mbgl/renderer/paint_parameters.hpp>
|
||||
#include <mbgl/renderer/paint_property_binder.hpp>
|
||||
#include <mbgl/shaders/collision_layer_ubo.hpp>
|
||||
#include <mbgl/shaders/shader_program_base.hpp>
|
||||
#include <mbgl/style/layers/symbol_layer_properties.hpp>
|
||||
#include <mbgl/util/convert.hpp>
|
||||
@@ -18,18 +19,7 @@
|
||||
namespace mbgl {
|
||||
|
||||
using namespace style;
|
||||
|
||||
namespace {
|
||||
|
||||
struct alignas(16) CollisionUBO {
|
||||
std::array<float, 4 * 4> matrix;
|
||||
std::array<float, 2> extrude_scale;
|
||||
float camera_to_center_distance;
|
||||
float overscale_factor;
|
||||
};
|
||||
static_assert(sizeof(CollisionUBO) == 20 * 4);
|
||||
|
||||
} // namespace
|
||||
using namespace shaders;
|
||||
|
||||
const StringIdentity CollisionLayerTweaker::idCollisionCircleUBOName = stringIndexer().get(CollisionCircleUBOName);
|
||||
const StringIdentity CollisionLayerTweaker::idCollisionBoxUBOName = stringIndexer().get(CollisionBoxUBOName);
|
||||
|
||||
@@ -16,6 +16,10 @@
|
||||
#include <mbgl/util/std.hpp>
|
||||
#include <mbgl/util/string_indexer.hpp>
|
||||
|
||||
#if MLN_RENDER_BACKEND_METAL
|
||||
#include <mbgl/shaders/mtl/fill_extrusion.hpp>
|
||||
#endif
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
using namespace shaders;
|
||||
@@ -79,9 +83,9 @@ void FillExtrusionLayerTweaker::execute(LayerGroupBase& layerGroup,
|
||||
const auto zoom = parameters.state.getZoom();
|
||||
if (permutationUpdated) {
|
||||
const FillExtrusionPermutationUBO permutationUBO = {
|
||||
/* .color = */ {/*.source=*/getAttributeSource("a_color"), /*.expression=*/{}},
|
||||
/* .base = */ {/*.source=*/getAttributeSource("a_base"), /*.expression=*/{}},
|
||||
/* .height = */ {/*.source=*/getAttributeSource("a_height"), /*.expression=*/{}},
|
||||
/* .color = */ {/*.source=*/getAttributeSource<BuiltIn::FillExtrusionShader>(2), /*.expression=*/{}},
|
||||
/* .base = */ {/*.source=*/getAttributeSource<BuiltIn::FillExtrusionShader>(3), /*.expression=*/{}},
|
||||
/* .height = */ {/*.source=*/getAttributeSource<BuiltIn::FillExtrusionShader>(4), /*.expression=*/{}},
|
||||
/* .overdrawInspector = */ overdrawInspector,
|
||||
/* .pad = */ 0,
|
||||
0,
|
||||
|
||||
@@ -78,26 +78,21 @@ void FillLayerTweaker::execute(LayerGroupBase& layerGroup,
|
||||
const auto debugGroup = parameters.encoder->createDebugGroup(label.c_str());
|
||||
#endif
|
||||
|
||||
#if MLN_RENDER_BACKEND_METAL
|
||||
const auto source = [this](const std::string_view& attrName) {
|
||||
return hasPropertyAsUniform(attrName) ? AttributeSource::Constant : AttributeSource::PerVertex;
|
||||
};
|
||||
#endif
|
||||
|
||||
// Only run each update function once
|
||||
bool fillUniformBufferUpdated = false;
|
||||
bool fillOutlineUniformBufferUpdated = false;
|
||||
bool fillPatternUniformBufferUpdated = false;
|
||||
bool fillOutlinePatternUniformBufferUpdated = false;
|
||||
|
||||
auto UpdateFillUniformBuffers = [&]() {
|
||||
const auto UpdateFillUniformBuffers = [&]() {
|
||||
if (fillUniformBufferUpdated) return;
|
||||
fillUniformBufferUpdated = true;
|
||||
|
||||
#if MLN_RENDER_BACKEND_METAL
|
||||
using ShaderClass = ShaderSource<BuiltIn::FillShader, gfx::Backend::Type::Metal>;
|
||||
if (permutationUpdated || !fillPermutationUniformBuffer) {
|
||||
const FillPermutationUBO permutationUBO = {
|
||||
/* .color = */ {/*.source=*/source(ShaderClass::attributes[1].name), /*.expression=*/{}},
|
||||
/* .opacity = */ {/*.source=*/source(ShaderClass::attributes[2].name), /*.expression=*/{}},
|
||||
/* .color = */ {/*.source=*/getAttributeSource<BuiltIn::FillShader>(1), /*.expression=*/{}},
|
||||
/* .opacity = */ {/*.source=*/getAttributeSource<BuiltIn::FillShader>(2), /*.expression=*/{}},
|
||||
/* .overdrawInspector = */ overdrawInspector,
|
||||
0,
|
||||
0,
|
||||
@@ -107,16 +102,11 @@ void FillLayerTweaker::execute(LayerGroupBase& layerGroup,
|
||||
0,
|
||||
};
|
||||
|
||||
if (fillPermutationUniformBuffer) {
|
||||
fillPermutationUniformBuffer->update(&permutationUBO, sizeof(permutationUBO));
|
||||
} else {
|
||||
fillPermutationUniformBuffer = context.createUniformBuffer(&permutationUBO, sizeof(permutationUBO));
|
||||
}
|
||||
fillUniformBufferUpdated = true;
|
||||
context.emplaceOrUpdateUniformBuffer(fillPermutationUniformBuffer, &permutationUBO);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!fillPropsUniformBuffer) {
|
||||
if (!fillPropsUniformBuffer || propertiesUpdated) {
|
||||
const FillEvaluatedPropsUBO paramsUBO = {
|
||||
/* .color = */ evaluated.get<FillColor>().constantOr(FillColor::defaultValue()),
|
||||
/* .opacity = */ evaluated.get<FillOpacity>().constantOr(FillOpacity::defaultValue()),
|
||||
@@ -124,19 +114,20 @@ void FillLayerTweaker::execute(LayerGroupBase& layerGroup,
|
||||
0,
|
||||
0,
|
||||
};
|
||||
fillPropsUniformBuffer = context.createUniformBuffer(¶msUBO, sizeof(paramsUBO));
|
||||
context.emplaceOrUpdateUniformBuffer(fillPropsUniformBuffer, ¶msUBO);
|
||||
}
|
||||
};
|
||||
|
||||
auto UpdateFillOutlineUniformBuffers = [&]() {
|
||||
const auto UpdateFillOutlineUniformBuffers = [&]() {
|
||||
if (fillOutlineUniformBufferUpdated) return;
|
||||
fillOutlineUniformBufferUpdated = true;
|
||||
|
||||
#if MLN_RENDER_BACKEND_METAL
|
||||
using ShaderClass = ShaderSource<BuiltIn::FillOutlineShader, gfx::Backend::Type::Metal>;
|
||||
if (permutationUpdated || !fillOutlinePermutationUniformBuffer) {
|
||||
const FillOutlinePermutationUBO permutationUBO = {
|
||||
/* .outline_color = */ {/*.source=*/source(ShaderClass::attributes[1].name), /*.expression=*/{}},
|
||||
/* .opacity = */ {/*.source=*/source(ShaderClass::attributes[2].name), /*.expression=*/{}},
|
||||
/* .outline_color = */ {/*.source=*/getAttributeSource<BuiltIn::FillOutlineShader>(1),
|
||||
/*.expression=*/{}},
|
||||
/* .opacity = */ {/*.source=*/getAttributeSource<BuiltIn::FillOutlineShader>(2), /*.expression=*/{}},
|
||||
/* .overdrawInspector = */ overdrawInspector,
|
||||
0,
|
||||
0,
|
||||
@@ -145,17 +136,11 @@ void FillLayerTweaker::execute(LayerGroupBase& layerGroup,
|
||||
0,
|
||||
0,
|
||||
};
|
||||
|
||||
if (fillOutlinePermutationUniformBuffer) {
|
||||
fillOutlinePermutationUniformBuffer->update(&permutationUBO, sizeof(permutationUBO));
|
||||
} else {
|
||||
fillOutlinePermutationUniformBuffer = context.createUniformBuffer(&permutationUBO,
|
||||
sizeof(permutationUBO));
|
||||
}
|
||||
context.emplaceOrUpdateUniformBuffer(fillOutlinePermutationUniformBuffer, &permutationUBO);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!fillOutlinePropsUniformBuffer) {
|
||||
if (!fillOutlinePropsUniformBuffer || propertiesUpdated) {
|
||||
const FillOutlineEvaluatedPropsUBO paramsUBO = {
|
||||
/* .outline_color = */ evaluated.get<FillOutlineColor>().constantOr(FillOutlineColor::defaultValue()),
|
||||
/* .opacity = */ evaluated.get<FillOpacity>().constantOr(FillOpacity::defaultValue()),
|
||||
@@ -163,118 +148,104 @@ void FillLayerTweaker::execute(LayerGroupBase& layerGroup,
|
||||
0,
|
||||
0,
|
||||
};
|
||||
fillOutlinePropsUniformBuffer = context.createUniformBuffer(¶msUBO, sizeof(paramsUBO));
|
||||
context.emplaceOrUpdateUniformBuffer(fillOutlinePropsUniformBuffer, ¶msUBO);
|
||||
}
|
||||
|
||||
fillOutlineUniformBufferUpdated = true;
|
||||
};
|
||||
|
||||
auto UpdateFillPatternUniformBuffers = [&]() {
|
||||
const auto UpdateFillPatternUniformBuffers = [&]() {
|
||||
if (fillPatternUniformBufferUpdated) return;
|
||||
fillPatternUniformBufferUpdated = true;
|
||||
|
||||
#if MLN_RENDER_BACKEND_METAL
|
||||
using ShaderClass = ShaderSource<BuiltIn::FillOutlinePatternShader, gfx::Backend::Type::Metal>;
|
||||
if (permutationUpdated || !fillPatternPermutationUniformBuffer) {
|
||||
const FillPatternPermutationUBO permutationUBO = {
|
||||
/* .pattern_from = */ {/*.source=*/source(ShaderClass::attributes[1].name), /*.expression=*/{}},
|
||||
/* .pattern_to = */ {/*.source=*/source(ShaderClass::attributes[2].name), /*.expression=*/{}},
|
||||
/* .opacity = */ {/*.source=*/source(ShaderClass::attributes[3].name), /*.expression=*/{}},
|
||||
/* .pattern_from = */ {/*.source=*/getAttributeSource<BuiltIn::FillPatternShader>(1),
|
||||
/*.expression=*/{}},
|
||||
/* .pattern_to = */
|
||||
{/*.source=*/getAttributeSource<BuiltIn::FillPatternShader>(2), /*.expression=*/{}},
|
||||
/* .opacity = */
|
||||
{/*.source=*/getAttributeSource<BuiltIn::FillPatternShader>(3), /*.expression=*/{}},
|
||||
/* .overdrawInspector = */ overdrawInspector,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
};
|
||||
|
||||
if (fillPatternPermutationUniformBuffer) {
|
||||
fillPatternPermutationUniformBuffer->update(&permutationUBO, sizeof(permutationUBO));
|
||||
} else {
|
||||
fillPatternPermutationUniformBuffer = context.createUniformBuffer(&permutationUBO,
|
||||
sizeof(permutationUBO));
|
||||
}
|
||||
context.emplaceOrUpdateUniformBuffer(fillPatternPermutationUniformBuffer, &permutationUBO);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!fillPatternPropsUniformBuffer) {
|
||||
if (!fillPatternPropsUniformBuffer || propertiesUpdated) {
|
||||
const FillPatternEvaluatedPropsUBO paramsUBO = {
|
||||
/* .opacity = */ evaluated.get<FillOpacity>().constantOr(FillOpacity::defaultValue()),
|
||||
/* .fade = */ crossfade.t,
|
||||
0,
|
||||
0,
|
||||
};
|
||||
fillPatternPropsUniformBuffer = context.createUniformBuffer(¶msUBO, sizeof(paramsUBO));
|
||||
context.emplaceOrUpdateUniformBuffer(fillPatternPropsUniformBuffer, ¶msUBO);
|
||||
}
|
||||
|
||||
fillPatternUniformBufferUpdated = true;
|
||||
};
|
||||
|
||||
auto UpdateFillOutlinePatternUniformBuffers = [&]() {
|
||||
const auto UpdateFillOutlinePatternUniformBuffers = [&]() {
|
||||
if (fillOutlinePatternUniformBufferUpdated) return;
|
||||
fillOutlinePatternUniformBufferUpdated = true;
|
||||
|
||||
#if MLN_RENDER_BACKEND_METAL
|
||||
using ShaderClass = ShaderSource<BuiltIn::FillOutlinePatternShader, gfx::Backend::Type::Metal>;
|
||||
if (permutationUpdated || !fillOutlinePatternPermutationUniformBuffer) {
|
||||
const FillOutlinePatternPermutationUBO permutationUBO = {
|
||||
/* .pattern_from = */ {/*.source=*/source(ShaderClass::attributes[1].name), /*.expression=*/{}},
|
||||
/* .pattern_to = */ {/*.source=*/source(ShaderClass::attributes[2].name), /*.expression=*/{}},
|
||||
/* .opacity = */ {/*.source=*/source(ShaderClass::attributes[3].name), /*.expression=*/{}},
|
||||
/* .pattern_from = */ {/*.source=*/getAttributeSource<BuiltIn::FillOutlinePatternShader>(1),
|
||||
/*.expression=*/{}},
|
||||
/* .pattern_to = */
|
||||
{/*.source=*/getAttributeSource<BuiltIn::FillOutlinePatternShader>(2), /*.expression=*/{}},
|
||||
/* .opacity = */
|
||||
{/*.source=*/getAttributeSource<BuiltIn::FillOutlinePatternShader>(3), /*.expression=*/{}},
|
||||
/* .overdrawInspector = */ overdrawInspector,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
};
|
||||
|
||||
if (fillOutlinePatternPermutationUniformBuffer) {
|
||||
fillOutlinePatternPermutationUniformBuffer->update(&permutationUBO, sizeof(permutationUBO));
|
||||
} else {
|
||||
fillOutlinePatternPermutationUniformBuffer = context.createUniformBuffer(&permutationUBO,
|
||||
sizeof(permutationUBO));
|
||||
}
|
||||
context.emplaceOrUpdateUniformBuffer(fillOutlinePatternPermutationUniformBuffer, &permutationUBO);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!fillOutlinePatternPropsUniformBuffer) {
|
||||
if (!fillOutlinePatternPropsUniformBuffer || propertiesUpdated) {
|
||||
const FillOutlinePatternEvaluatedPropsUBO paramsUBO = {
|
||||
/* .opacity = */ evaluated.get<FillOpacity>().constantOr(FillOpacity::defaultValue()),
|
||||
/* .fade = */ crossfade.t,
|
||||
0,
|
||||
0,
|
||||
};
|
||||
fillOutlinePatternPropsUniformBuffer = context.createUniformBuffer(¶msUBO, sizeof(paramsUBO));
|
||||
context.emplaceOrUpdateUniformBuffer(fillOutlinePatternPropsUniformBuffer, ¶msUBO);
|
||||
}
|
||||
|
||||
fillOutlinePatternUniformBufferUpdated = true;
|
||||
};
|
||||
|
||||
#if MLN_RENDER_BACKEND_METAL
|
||||
if (!expressionUniformBuffer) {
|
||||
const auto zoom = parameters.state.getZoom();
|
||||
const auto expressionUBO = buildExpressionUBO(zoom, parameters.frameCount);
|
||||
expressionUniformBuffer = context.createUniformBuffer(&expressionUBO, sizeof(expressionUBO));
|
||||
}
|
||||
const auto zoom = parameters.state.getZoom();
|
||||
const auto expressionUBO = buildExpressionUBO(zoom, parameters.frameCount);
|
||||
context.emplaceOrUpdateUniformBuffer(expressionUniformBuffer, &expressionUBO);
|
||||
#endif
|
||||
|
||||
const auto& translation = evaluated.get<FillTranslate>();
|
||||
const auto anchor = evaluated.get<FillTranslateAnchor>();
|
||||
|
||||
const auto renderableSize = parameters.backend.getDefaultRenderable().getSize();
|
||||
const auto intZoom = parameters.state.getIntegerZoom();
|
||||
const auto pixelRatio = parameters.pixelRatio;
|
||||
|
||||
layerGroup.visitDrawables([&](gfx::Drawable& drawable) {
|
||||
if (!drawable.getTileID() || !checkTweakDrawable(drawable)) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto& uniforms = drawable.mutableUniformBuffers();
|
||||
// auto& drawableType = drawable.getShader()->typeName();
|
||||
|
||||
const UnwrappedTileID tileID = drawable.getTileID()->toUnwrapped();
|
||||
|
||||
const auto& translation = evaluated.get<FillTranslate>();
|
||||
const auto anchor = evaluated.get<FillTranslateAnchor>();
|
||||
constexpr bool inViewportPixelUnits = false; // from RenderTile::translatedMatrix
|
||||
constexpr bool nearClipped = false;
|
||||
const auto matrix = getTileMatrix(
|
||||
tileID, renderTree, parameters.state, translation, anchor, nearClipped, inViewportPixelUnits);
|
||||
|
||||
// from FillPatternProgram::layoutUniformValues
|
||||
const auto renderableSize = parameters.backend.getDefaultRenderable().getSize();
|
||||
const auto intZoom = parameters.state.getIntegerZoom();
|
||||
const auto tileRatio = 1.0f / tileID.pixelsToTileUnits(1.0f, intZoom);
|
||||
const int32_t tileSizeAtNearestZoom = static_cast<int32_t>(
|
||||
util::tileSize_D * parameters.state.zoomScale(intZoom - tileID.canonical.z));
|
||||
@@ -282,7 +253,6 @@ void FillLayerTweaker::execute(LayerGroupBase& layerGroup,
|
||||
tileSizeAtNearestZoom *
|
||||
(tileID.canonical.x + tileID.wrap * parameters.state.zoomScale(tileID.canonical.z)));
|
||||
const int32_t pixelY = tileSizeAtNearestZoom * tileID.canonical.y;
|
||||
const auto pixelRatio = parameters.pixelRatio;
|
||||
|
||||
Size textureSize = {0, 0};
|
||||
if (const auto shader = drawable.getShader()) {
|
||||
@@ -293,12 +263,13 @@ void FillLayerTweaker::execute(LayerGroupBase& layerGroup,
|
||||
}
|
||||
}
|
||||
|
||||
auto& uniforms = drawable.mutableUniformBuffers();
|
||||
if (uniforms.get(idFillInterpolateUBOName)) {
|
||||
UpdateFillUniformBuffers();
|
||||
|
||||
uniforms.addOrReplace(idFillEvaluatedPropsUBOName, fillPropsUniformBuffer);
|
||||
const FillDrawableUBO drawableUBO = {/*.matrix=*/util::cast<float>(matrix)};
|
||||
|
||||
const FillDrawableUBO drawableUBO = {/*.matrix=*/util::cast<float>(matrix)};
|
||||
uniforms.createOrUpdate(idFillDrawableUBOName, &drawableUBO, context);
|
||||
|
||||
#if MLN_RENDER_BACKEND_METAL
|
||||
@@ -308,12 +279,12 @@ void FillLayerTweaker::execute(LayerGroupBase& layerGroup,
|
||||
UpdateFillOutlineUniformBuffers();
|
||||
|
||||
uniforms.addOrReplace(idFillOutlineEvaluatedPropsUBOName, fillOutlinePropsUniformBuffer);
|
||||
|
||||
const FillOutlineDrawableUBO drawableUBO = {
|
||||
/*.matrix=*/util::cast<float>(matrix),
|
||||
/*.world=*/{(float)renderableSize.width, (float)renderableSize.height},
|
||||
/* pad1 */ 0,
|
||||
/* pad2 */ 0};
|
||||
|
||||
uniforms.createOrUpdate(idFillOutlineDrawableUBOName, &drawableUBO, context);
|
||||
|
||||
#if MLN_RENDER_BACKEND_METAL
|
||||
@@ -323,6 +294,7 @@ void FillLayerTweaker::execute(LayerGroupBase& layerGroup,
|
||||
UpdateFillPatternUniformBuffers();
|
||||
|
||||
uniforms.addOrReplace(idFillPatternEvaluatedPropsUBOName, fillPatternPropsUniformBuffer);
|
||||
|
||||
const FillPatternDrawableUBO drawableUBO = {
|
||||
/*.matrix=*/util::cast<float>(matrix),
|
||||
/*.scale=*/{pixelRatio, tileRatio, crossfade.fromScale, crossfade.toScale},
|
||||
@@ -332,7 +304,6 @@ void FillLayerTweaker::execute(LayerGroupBase& layerGroup,
|
||||
0,
|
||||
0,
|
||||
};
|
||||
|
||||
uniforms.createOrUpdate(idFillPatternDrawableUBOName, &drawableUBO, context);
|
||||
|
||||
#if MLN_RENDER_BACKEND_METAL
|
||||
@@ -342,6 +313,7 @@ void FillLayerTweaker::execute(LayerGroupBase& layerGroup,
|
||||
UpdateFillOutlinePatternUniformBuffers();
|
||||
|
||||
uniforms.addOrReplace(idFillOutlinePatternEvaluatedPropsUBOName, fillOutlinePatternPropsUniformBuffer);
|
||||
|
||||
const FillOutlinePatternDrawableUBO drawableUBO = {
|
||||
/*.matrix=*/util::cast<float>(matrix),
|
||||
/*.scale=*/{pixelRatio, tileRatio, crossfade.fromScale, crossfade.toScale},
|
||||
@@ -350,7 +322,6 @@ void FillLayerTweaker::execute(LayerGroupBase& layerGroup,
|
||||
/*.pixel_coord_lower=*/{static_cast<float>(pixelX & 0xFFFF), static_cast<float>(pixelY & 0xFFFF)},
|
||||
/*.texsize=*/{static_cast<float>(textureSize.width), static_cast<float>(textureSize.height)},
|
||||
};
|
||||
|
||||
uniforms.createOrUpdate(idFillOutlinePatternDrawableUBOName, &drawableUBO, context);
|
||||
|
||||
#if MLN_RENDER_BACKEND_METAL
|
||||
@@ -364,6 +335,7 @@ void FillLayerTweaker::execute(LayerGroupBase& layerGroup,
|
||||
});
|
||||
|
||||
permutationUpdated = false;
|
||||
propertiesUpdated = false;
|
||||
}
|
||||
|
||||
} // namespace mbgl
|
||||
|
||||
@@ -43,15 +43,10 @@ void HeatmapLayerTweaker::execute(LayerGroupBase& layerGroup,
|
||||
const auto zoom = parameters.state.getZoom();
|
||||
|
||||
#if MLN_RENDER_BACKEND_METAL
|
||||
using ShaderClass = shaders::ShaderSource<BuiltIn::HeatmapShader, gfx::Backend::Type::Metal>;
|
||||
if (permutationUpdated) {
|
||||
const auto source = [this](const std::string_view& attrName) {
|
||||
return hasPropertyAsUniform(attrName) ? AttributeSource::Constant : AttributeSource::PerVertex;
|
||||
};
|
||||
|
||||
const HeatmapPermutationUBO permutationUBO = {
|
||||
/* .weight = */ {/*.source=*/source(ShaderClass::attributes[1].name), /*.expression=*/{}},
|
||||
/* .radius = */ {/*.source=*/source(ShaderClass::attributes[2].name), /*.expression=*/{}},
|
||||
/* .weight = */ {/*.source=*/getAttributeSource<BuiltIn::HeatmapShader>(1), /*.expression=*/{}},
|
||||
/* .radius = */ {/*.source=*/getAttributeSource<BuiltIn::HeatmapShader>(2), /*.expression=*/{}},
|
||||
/* .overdrawInspector = */ overdrawInspector,
|
||||
/* .pad1/2/3 = */ 0,
|
||||
0,
|
||||
|
||||
@@ -112,19 +112,14 @@ void LineLayerTweaker::execute(LayerGroupBase& layerGroup,
|
||||
};
|
||||
|
||||
#if MLN_RENDER_BACKEND_METAL
|
||||
using LineShaderClass = shaders::ShaderSource<BuiltIn::LineShader, gfx::Backend::Type::Metal>;
|
||||
if (permutationUpdated) {
|
||||
const auto source = [this](const std::string_view& attrName) {
|
||||
return hasPropertyAsUniform(attrName) ? AttributeSource::Constant : AttributeSource::PerVertex;
|
||||
};
|
||||
|
||||
const LinePermutationUBO permutationUBO = {
|
||||
/* .color = */ {/*.source=*/source(LineShaderClass::attributes[2].name), /*.expression=*/{}},
|
||||
/* .blur = */ {/*.source=*/source(LineShaderClass::attributes[3].name), /*.expression=*/{}},
|
||||
/* .opacity = */ {/*.source=*/source(LineShaderClass::attributes[4].name), /*.expression=*/{}},
|
||||
/* .gapwidth = */ {/*.source=*/source(LineShaderClass::attributes[5].name), /*.expression=*/{}},
|
||||
/* .offset = */ {/*.source=*/source(LineShaderClass::attributes[6].name), /*.expression=*/{}},
|
||||
/* .width = */ {/*.source=*/source(LineShaderClass::attributes[7].name), /*.expression=*/{}},
|
||||
/* .color = */ {/*.source=*/getAttributeSource<BuiltIn::LineShader>(2), /*.expression=*/{}},
|
||||
/* .blur = */ {/*.source=*/getAttributeSource<BuiltIn::LineShader>(3), /*.expression=*/{}},
|
||||
/* .opacity = */ {/*.source=*/getAttributeSource<BuiltIn::LineShader>(4), /*.expression=*/{}},
|
||||
/* .gapwidth = */ {/*.source=*/getAttributeSource<BuiltIn::LineShader>(5), /*.expression=*/{}},
|
||||
/* .offset = */ {/*.source=*/getAttributeSource<BuiltIn::LineShader>(6), /*.expression=*/{}},
|
||||
/* .width = */ {/*.source=*/getAttributeSource<BuiltIn::LineShader>(7), /*.expression=*/{}},
|
||||
/* .floorwidth = */ {/*.source=*/AttributeSource::Constant, /*.expression=*/{}},
|
||||
/* .pattern_from = */ {/*.source=*/AttributeSource::Constant, /*.expression=*/{}},
|
||||
/* .pattern_to = */ {/*.source=*/AttributeSource::Constant, /*.expression=*/{}},
|
||||
|
||||
@@ -326,6 +326,7 @@ void RenderCircleLayer::update(gfx::ShaderRegistry& shaders,
|
||||
[&](gfx::Drawable& drawable) { return drawable.getTileID() && !hasRenderTile(*drawable.getTileID()); });
|
||||
|
||||
const auto& evaluated = static_cast<const CircleLayerProperties&>(*evaluatedProperties).evaluated;
|
||||
std::unordered_set<StringIdentity> propertiesAsUniforms;
|
||||
|
||||
for (const RenderTile& tile : *renderTiles) {
|
||||
const auto& tileID = tile.getOverscaledTileID();
|
||||
@@ -377,15 +378,16 @@ void RenderCircleLayer::update(gfx::ShaderRegistry& shaders,
|
||||
|
||||
const auto interpBuffer = context.createUniformBuffer(&interpolateUBO, sizeof(interpolateUBO));
|
||||
|
||||
propertiesAsUniforms.clear();
|
||||
gfx::VertexAttributeArray circleVertexAttrs;
|
||||
auto propertiesAsUniforms = circleVertexAttrs.readDataDrivenPaintProperties<CircleColor,
|
||||
CircleRadius,
|
||||
CircleBlur,
|
||||
CircleOpacity,
|
||||
CircleStrokeColor,
|
||||
CircleStrokeWidth,
|
||||
CircleStrokeOpacity>(
|
||||
paintPropertyBinders, evaluated);
|
||||
circleVertexAttrs.readDataDrivenPaintProperties<CircleColor,
|
||||
CircleRadius,
|
||||
CircleBlur,
|
||||
CircleOpacity,
|
||||
CircleStrokeColor,
|
||||
CircleStrokeWidth,
|
||||
CircleStrokeOpacity>(
|
||||
paintPropertyBinders, evaluated, propertiesAsUniforms);
|
||||
|
||||
if (!circleShaderGroup) {
|
||||
continue;
|
||||
@@ -396,7 +398,7 @@ void RenderCircleLayer::update(gfx::ShaderRegistry& shaders,
|
||||
}
|
||||
|
||||
if (layerTweaker) {
|
||||
layerTweaker->setPropertiesAsUniforms(std::move(propertiesAsUniforms));
|
||||
layerTweaker->setPropertiesAsUniforms(propertiesAsUniforms);
|
||||
}
|
||||
|
||||
if (const auto& attr = circleVertexAttrs.add(idVertexAttribName)) {
|
||||
|
||||
@@ -341,6 +341,7 @@ void RenderFillExtrusionLayer::update(gfx::ShaderRegistry& shaders,
|
||||
return;
|
||||
}
|
||||
|
||||
std::unordered_set<StringIdentity> propertiesAsUniforms;
|
||||
for (const RenderTile& tile : *renderTiles) {
|
||||
const auto& tileID = tile.getOverscaledTileID();
|
||||
|
||||
@@ -412,16 +413,17 @@ void RenderFillExtrusionLayer::update(gfx::ShaderRegistry& shaders,
|
||||
continue;
|
||||
}
|
||||
|
||||
gfx::VertexAttributeArray vertexAttrs;
|
||||
const auto propertiesAsUniforms = vertexAttrs.readDataDrivenPaintProperties<FillExtrusionBase,
|
||||
FillExtrusionColor,
|
||||
FillExtrusionHeight,
|
||||
FillExtrusionPattern>(binders,
|
||||
evaluated);
|
||||
|
||||
if (!shaderGroup) {
|
||||
continue;
|
||||
}
|
||||
|
||||
gfx::VertexAttributeArray vertexAttrs;
|
||||
propertiesAsUniforms.clear();
|
||||
vertexAttrs.readDataDrivenPaintProperties<FillExtrusionBase,
|
||||
FillExtrusionColor,
|
||||
FillExtrusionHeight,
|
||||
FillExtrusionPattern>(binders, evaluated, propertiesAsUniforms);
|
||||
|
||||
const auto shader = std::static_pointer_cast<gfx::ShaderProgramBase>(
|
||||
shaderGroup->getOrCreateShader(context, propertiesAsUniforms));
|
||||
if (!shader) {
|
||||
@@ -429,7 +431,7 @@ void RenderFillExtrusionLayer::update(gfx::ShaderRegistry& shaders,
|
||||
}
|
||||
|
||||
if (layerTweaker) {
|
||||
layerTweaker->setPropertiesAsUniforms(std::move(propertiesAsUniforms));
|
||||
layerTweaker->setPropertiesAsUniforms(propertiesAsUniforms);
|
||||
}
|
||||
|
||||
// The non-pattern path in `render()` only uses two-pass rendering if there's translucency.
|
||||
|
||||
@@ -102,9 +102,8 @@ void RenderFillLayer::evaluate(const PropertyEvaluationParameters& parameters) {
|
||||
evaluatedProperties = std::move(properties);
|
||||
|
||||
#if MLN_DRAWABLE_RENDERER
|
||||
if (layerGroup) {
|
||||
auto newTweaker = std::make_shared<FillLayerTweaker>(getID(), evaluatedProperties);
|
||||
replaceTweaker(layerTweaker, std::move(newTweaker), {layerGroup});
|
||||
if (layerTweaker) {
|
||||
layerTweaker->updateProperties(evaluatedProperties);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -372,6 +371,7 @@ void RenderFillLayer::update(gfx::ShaderRegistry& shaders,
|
||||
return tileID && !hasRenderTile(*tileID);
|
||||
});
|
||||
|
||||
std::unordered_set<StringIdentity> propertiesAsUniforms;
|
||||
for (const RenderTile& tile : *renderTiles) {
|
||||
const auto& tileID = tile.getOverscaledTileID();
|
||||
|
||||
@@ -502,9 +502,9 @@ void RenderFillLayer::update(gfx::ShaderRegistry& shaders,
|
||||
|
||||
// `Fill*Program` all use `style::FillPaintProperties`
|
||||
gfx::VertexAttributeArray vertexAttrs;
|
||||
const auto propertiesAsUniforms =
|
||||
vertexAttrs.readDataDrivenPaintProperties<FillColor, FillOpacity, FillOutlineColor, FillPattern>(binders,
|
||||
evaluated);
|
||||
propertiesAsUniforms.clear();
|
||||
vertexAttrs.readDataDrivenPaintProperties<FillColor, FillOpacity, FillOutlineColor, FillPattern>(
|
||||
binders, evaluated, propertiesAsUniforms);
|
||||
|
||||
if (layerTweaker) {
|
||||
layerTweaker->setPropertiesAsUniforms(propertiesAsUniforms);
|
||||
|
||||
@@ -353,6 +353,7 @@ void RenderHeatmapLayer::update(gfx::ShaderRegistry& shaders,
|
||||
[&](gfx::Drawable& drawable) { return drawable.getTileID() && !hasRenderTile(*drawable.getTileID()); });
|
||||
|
||||
const auto& evaluated = static_cast<const HeatmapLayerProperties&>(*evaluatedProperties).evaluated;
|
||||
std::unordered_set<StringIdentity> propertiesAsUniforms;
|
||||
|
||||
for (const RenderTile& tile : *renderTiles) {
|
||||
const auto& tileID = tile.getOverscaledTileID();
|
||||
@@ -389,9 +390,10 @@ void RenderHeatmapLayer::update(gfx::ShaderRegistry& shaders,
|
||||
};
|
||||
|
||||
gfx::VertexAttributeArray heatmapVertexAttrs;
|
||||
const auto propertiesAsUniforms =
|
||||
heatmapVertexAttrs.readDataDrivenPaintProperties<HeatmapWeight, HeatmapRadius>(paintPropertyBinders,
|
||||
evaluated);
|
||||
propertiesAsUniforms.clear();
|
||||
heatmapVertexAttrs.readDataDrivenPaintProperties<HeatmapWeight, HeatmapRadius>(
|
||||
paintPropertyBinders, evaluated, propertiesAsUniforms);
|
||||
|
||||
if (layerTweaker) {
|
||||
layerTweaker->setPropertiesAsUniforms(propertiesAsUniforms);
|
||||
}
|
||||
|
||||
@@ -83,6 +83,12 @@ void RenderLineLayer::evaluate(const PropertyEvaluationParameters& parameters) {
|
||||
#if MLN_DRAWABLE_RENDERER
|
||||
if (layerGroup) {
|
||||
auto newTweaker = std::make_shared<LineLayerTweaker>(getID(), evaluatedProperties);
|
||||
|
||||
// propertiesAsUniforms isn't recalculated every update, so carry it over
|
||||
if (layerTweaker) {
|
||||
newTweaker->setPropertiesAsUniforms(layerTweaker->getPropertiesAsUniforms());
|
||||
}
|
||||
|
||||
replaceTweaker(layerTweaker, std::move(newTweaker), {layerGroup});
|
||||
}
|
||||
#endif
|
||||
@@ -459,6 +465,7 @@ void RenderLineLayer::update(gfx::ShaderRegistry& shaders,
|
||||
builder->setSegments(gfx::Triangles(), bucket.sharedTriangles, bucket.segments.data(), bucket.segments.size());
|
||||
};
|
||||
|
||||
std::unordered_set<StringIdentity> propertiesAsUniforms;
|
||||
for (const RenderTile& tile : *renderTiles) {
|
||||
const auto& tileID = tile.getOverscaledTileID();
|
||||
|
||||
@@ -565,6 +572,8 @@ void RenderLineLayer::update(gfx::ShaderRegistry& shaders,
|
||||
else if (shaderUniforms.get(idLineSDFInterpolationUBOName)) {
|
||||
drawableUniforms.createOrUpdate(idLineSDFInterpolationUBOName, &lineSDFInterpolationUBO, context);
|
||||
}
|
||||
|
||||
// TODO: vertex attributes or `propertiesAsUniforms` updated, is that needed?
|
||||
});
|
||||
|
||||
if (tileLayerGroup->getDrawableCount(renderPass, tileID) > 0) {
|
||||
@@ -572,27 +581,29 @@ void RenderLineLayer::update(gfx::ShaderRegistry& shaders,
|
||||
}
|
||||
|
||||
if (!evaluated.get<LineDasharray>().from.empty()) {
|
||||
// dash array line (SDF)
|
||||
gfx::VertexAttributeArray vertexAttrs;
|
||||
auto propertiesAsUniforms = vertexAttrs.readDataDrivenPaintProperties<LineColor,
|
||||
LineBlur,
|
||||
LineOpacity,
|
||||
LineGapWidth,
|
||||
LineOffset,
|
||||
LineWidth,
|
||||
LineFloorWidth>(paintPropertyBinders,
|
||||
evaluated);
|
||||
|
||||
if (!lineSDFShaderGroup) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// dash array line (SDF)
|
||||
propertiesAsUniforms.clear();
|
||||
gfx::VertexAttributeArray vertexAttrs;
|
||||
vertexAttrs.readDataDrivenPaintProperties<LineColor,
|
||||
LineBlur,
|
||||
LineOpacity,
|
||||
LineGapWidth,
|
||||
LineOffset,
|
||||
LineWidth,
|
||||
LineFloorWidth>(
|
||||
paintPropertyBinders, evaluated, propertiesAsUniforms);
|
||||
|
||||
auto shader = lineSDFShaderGroup->getOrCreateShader(context, propertiesAsUniforms);
|
||||
if (!shader) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (layerTweaker) {
|
||||
layerTweaker->setPropertiesAsUniforms(std::move(propertiesAsUniforms));
|
||||
layerTweaker->setPropertiesAsUniforms(propertiesAsUniforms);
|
||||
}
|
||||
|
||||
auto builder = createLineBuilder("lineSDF", std::move(shader));
|
||||
@@ -617,27 +628,26 @@ void RenderLineLayer::update(gfx::ShaderRegistry& shaders,
|
||||
++stats.drawablesAdded;
|
||||
}
|
||||
} else if (!unevaluated.get<LinePattern>().isUndefined()) {
|
||||
// pattern line
|
||||
gfx::VertexAttributeArray vertexAttrs;
|
||||
paintPropertyBinders.setPatternParameters(patternPosA, patternPosB, crossfade);
|
||||
auto propertiesAsUniforms = vertexAttrs.readDataDrivenPaintProperties<LineBlur,
|
||||
LineOpacity,
|
||||
LineOffset,
|
||||
LineGapWidth,
|
||||
LineWidth,
|
||||
LinePattern>(paintPropertyBinders,
|
||||
evaluated);
|
||||
|
||||
if (!linePatternShaderGroup) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// pattern line
|
||||
paintPropertyBinders.setPatternParameters(patternPosA, patternPosB, crossfade);
|
||||
|
||||
propertiesAsUniforms.clear();
|
||||
gfx::VertexAttributeArray vertexAttrs;
|
||||
vertexAttrs
|
||||
.readDataDrivenPaintProperties<LineBlur, LineOpacity, LineOffset, LineGapWidth, LineWidth, LinePattern>(
|
||||
paintPropertyBinders, evaluated, propertiesAsUniforms);
|
||||
|
||||
auto shader = linePatternShaderGroup->getOrCreateShader(context, propertiesAsUniforms);
|
||||
if (!shader) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (layerTweaker) {
|
||||
layerTweaker->setPropertiesAsUniforms(std::move(propertiesAsUniforms));
|
||||
layerTweaker->setPropertiesAsUniforms(propertiesAsUniforms);
|
||||
}
|
||||
|
||||
auto builder = createLineBuilder("linePattern", std::move(shader));
|
||||
@@ -678,22 +688,23 @@ void RenderLineLayer::update(gfx::ShaderRegistry& shaders,
|
||||
}
|
||||
}
|
||||
} else if (!unevaluated.get<LineGradient>().getValue().isUndefined()) {
|
||||
// gradient line
|
||||
gfx::VertexAttributeArray vertexAttrs;
|
||||
auto propertiesAsUniforms =
|
||||
vertexAttrs.readDataDrivenPaintProperties<LineBlur, LineOpacity, LineGapWidth, LineOffset, LineWidth>(
|
||||
paintPropertyBinders, evaluated);
|
||||
|
||||
if (!lineGradientShaderGroup) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// gradient line
|
||||
propertiesAsUniforms.clear();
|
||||
gfx::VertexAttributeArray vertexAttrs;
|
||||
vertexAttrs.readDataDrivenPaintProperties<LineBlur, LineOpacity, LineGapWidth, LineOffset, LineWidth>(
|
||||
paintPropertyBinders, evaluated, propertiesAsUniforms);
|
||||
|
||||
auto shader = lineGradientShaderGroup->getOrCreateShader(context, propertiesAsUniforms);
|
||||
if (!shader) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (layerTweaker) {
|
||||
layerTweaker->setPropertiesAsUniforms(std::move(propertiesAsUniforms));
|
||||
layerTweaker->setPropertiesAsUniforms(propertiesAsUniforms);
|
||||
}
|
||||
|
||||
auto builder = createLineBuilder("lineGradient", std::move(shader));
|
||||
@@ -731,33 +742,25 @@ void RenderLineLayer::update(gfx::ShaderRegistry& shaders,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
// simple line
|
||||
gfx::VertexAttributeArray vertexAttrs;
|
||||
const auto propertiesAsUniforms = vertexAttrs.readDataDrivenPaintProperties<LineColor,
|
||||
LineBlur,
|
||||
LineOpacity,
|
||||
LineGapWidth,
|
||||
LineOffset,
|
||||
LineWidth>(paintPropertyBinders,
|
||||
evaluated);
|
||||
|
||||
assert(6 == propertiesAsUniforms.size());
|
||||
assert(vertexAttrs.size() == (size_t)std::count_if(propertiesAsUniforms.begin(),
|
||||
propertiesAsUniforms.end(),
|
||||
[](const auto& s) { return s.empty(); }));
|
||||
|
||||
if (!lineShaderGroup) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// simple line
|
||||
propertiesAsUniforms.clear();
|
||||
gfx::VertexAttributeArray vertexAttrs;
|
||||
vertexAttrs
|
||||
.readDataDrivenPaintProperties<LineColor, LineBlur, LineOpacity, LineGapWidth, LineOffset, LineWidth>(
|
||||
paintPropertyBinders, evaluated, propertiesAsUniforms);
|
||||
|
||||
auto shader = lineShaderGroup->getOrCreateShader(context, propertiesAsUniforms);
|
||||
if (!shader) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (layerTweaker) {
|
||||
layerTweaker->setPropertiesAsUniforms(std::move(propertiesAsUniforms));
|
||||
layerTweaker->setPropertiesAsUniforms(propertiesAsUniforms);
|
||||
}
|
||||
|
||||
auto builder = createLineBuilder("line", std::move(shader));
|
||||
|
||||
@@ -748,19 +748,21 @@ SymbolDrawableTilePropsUBO buildTileUBO(const SymbolBucket& bucket,
|
||||
};
|
||||
}
|
||||
|
||||
const StringIdentity idDataAttibName = stringIndexer().get("a_data");
|
||||
const StringIdentity idPosOffsetAttribName = stringIndexer().get("a_pos_offset");
|
||||
const StringIdentity idPixOffsetAttribName = stringIndexer().get("a_pixeloffset");
|
||||
const StringIdentity idProjPosAttribName = stringIndexer().get("a_projected_pos");
|
||||
const StringIdentity idFadeOpacityAttribName = stringIndexer().get("a_fade_opacity");
|
||||
const StringIdentity idTexUniformName = stringIndexer().get("u_texture");
|
||||
const StringIdentity idTexIconUniformName = stringIndexer().get("u_texture_icon");
|
||||
const auto idDataAttibName = stringIndexer().get("a_data");
|
||||
const auto posOffsetAttribName = "a_pos_offset";
|
||||
const auto idPosOffsetAttribName = stringIndexer().get(posOffsetAttribName);
|
||||
const auto idPixOffsetAttribName = stringIndexer().get("a_pixeloffset");
|
||||
const auto idProjPosAttribName = stringIndexer().get("a_projected_pos");
|
||||
const auto idFadeOpacityAttribName = stringIndexer().get("a_fade_opacity");
|
||||
const auto idTexUniformName = stringIndexer().get("u_texture");
|
||||
const auto idTexIconUniformName = stringIndexer().get("u_texture_icon");
|
||||
|
||||
std::vector<std::string> updateTileAttributes(const SymbolBucket::Buffer& buffer,
|
||||
const bool isText,
|
||||
const SymbolBucket::PaintProperties& paintProps,
|
||||
const SymbolPaintProperties::PossiblyEvaluated& evaluated,
|
||||
gfx::VertexAttributeArray& attribs) {
|
||||
void updateTileAttributes(const SymbolBucket::Buffer& buffer,
|
||||
const bool isText,
|
||||
const SymbolBucket::PaintProperties& paintProps,
|
||||
const SymbolPaintProperties::PossiblyEvaluated& evaluated,
|
||||
gfx::VertexAttributeArray& attribs,
|
||||
std::unordered_set<StringIdentity>& propertiesAsUniforms) {
|
||||
if (const auto& attr = attribs.getOrAdd(idPosOffsetAttribName)) {
|
||||
attr->setSharedRawData(buffer.sharedVertices,
|
||||
offsetof(SymbolLayoutVertex, a1),
|
||||
@@ -800,13 +802,13 @@ std::vector<std::string> updateTileAttributes(const SymbolBucket::Buffer& buffer
|
||||
gfx::AttributeDataType::Float);
|
||||
}
|
||||
|
||||
return isText
|
||||
? attribs
|
||||
.readDataDrivenPaintProperties<TextOpacity, TextColor, TextHaloColor, TextHaloWidth, TextHaloBlur>(
|
||||
paintProps.textBinders, evaluated)
|
||||
: attribs
|
||||
.readDataDrivenPaintProperties<IconOpacity, IconColor, IconHaloColor, IconHaloWidth, IconHaloBlur>(
|
||||
paintProps.iconBinders, evaluated);
|
||||
if (isText) {
|
||||
attribs.readDataDrivenPaintProperties<TextOpacity, TextColor, TextHaloColor, TextHaloWidth, TextHaloBlur>(
|
||||
paintProps.textBinders, evaluated, propertiesAsUniforms);
|
||||
} else {
|
||||
attribs.readDataDrivenPaintProperties<IconOpacity, IconColor, IconHaloColor, IconHaloWidth, IconHaloBlur>(
|
||||
paintProps.iconBinders, evaluated, propertiesAsUniforms);
|
||||
}
|
||||
}
|
||||
|
||||
void updateTileDrawable(gfx::Drawable& drawable,
|
||||
@@ -816,7 +818,8 @@ void updateTileDrawable(gfx::Drawable& drawable,
|
||||
const SymbolPaintProperties::PossiblyEvaluated& evaluated,
|
||||
const TransformState& state,
|
||||
gfx::UniformBufferPtr& textInterpUBO,
|
||||
gfx::UniformBufferPtr& iconInterpUBO) {
|
||||
gfx::UniformBufferPtr& iconInterpUBO,
|
||||
std::unordered_set<StringIdentity>& propertiesAsUniforms) {
|
||||
if (!drawable.getData()) {
|
||||
return;
|
||||
}
|
||||
@@ -858,7 +861,7 @@ void updateTileDrawable(gfx::Drawable& drawable,
|
||||
// See `Placement::updateBucketDynamicVertices`
|
||||
|
||||
gfx::VertexAttributeArray attribs;
|
||||
updateTileAttributes(buffer, isText, paintProps, evaluated, attribs);
|
||||
updateTileAttributes(buffer, isText, paintProps, evaluated, attribs, propertiesAsUniforms);
|
||||
drawable.setVertexAttributes(std::move(attribs));
|
||||
}
|
||||
|
||||
@@ -1085,6 +1088,7 @@ void RenderSymbolLayer::update(gfx::ShaderRegistry& shaders,
|
||||
collisionBuilder->setColorMode(gfx::ColorMode::alphaBlended());
|
||||
collisionBuilder->setVertexAttrNameId(idCollisionPosAttribName);
|
||||
|
||||
std::unordered_set<StringIdentity> propertiesAsUniforms;
|
||||
for (const RenderTile& tile : *renderTiles) {
|
||||
const auto& tileID = tile.getOverscaledTileID();
|
||||
|
||||
@@ -1195,8 +1199,16 @@ void RenderSymbolLayer::update(gfx::ShaderRegistry& shaders,
|
||||
}
|
||||
|
||||
const auto& evaluated = getEvaluated<SymbolLayerProperties>(renderData.layerProperties);
|
||||
updateTileDrawable(
|
||||
drawable, context, bucket, bucketPaintProperties, evaluated, state, textInterpUBO, iconInterpUBO);
|
||||
propertiesAsUniforms.clear();
|
||||
updateTileDrawable(drawable,
|
||||
context,
|
||||
bucket,
|
||||
bucketPaintProperties,
|
||||
evaluated,
|
||||
state,
|
||||
textInterpUBO,
|
||||
iconInterpUBO,
|
||||
propertiesAsUniforms);
|
||||
});
|
||||
|
||||
// re-create collision drawables
|
||||
@@ -1280,9 +1292,9 @@ void RenderSymbolLayer::update(gfx::ShaderRegistry& shaders,
|
||||
|
||||
const auto vertexCount = buffer.vertices().elements();
|
||||
|
||||
propertiesAsUniforms.clear();
|
||||
gfx::VertexAttributeArray attribs;
|
||||
const auto propertiesAsUniforms = updateTileAttributes(
|
||||
buffer, isText, bucketPaintProperties, evaluated, attribs);
|
||||
updateTileAttributes(buffer, isText, bucketPaintProperties, evaluated, attribs, propertiesAsUniforms);
|
||||
if (layerTweaker) {
|
||||
layerTweaker->setPropertiesAsUniforms(propertiesAsUniforms);
|
||||
}
|
||||
@@ -1354,8 +1366,8 @@ void RenderSymbolLayer::update(gfx::ShaderRegistry& shaders,
|
||||
if (!shaderGroup) {
|
||||
return;
|
||||
}
|
||||
const auto shader = std::static_pointer_cast<gfx::ShaderProgramBase>(shaderGroup->getOrCreateShader(
|
||||
context, propertiesAsUniforms, stringIndexer().get(idPosOffsetAttribName)));
|
||||
const auto shader = std::static_pointer_cast<gfx::ShaderProgramBase>(
|
||||
shaderGroup->getOrCreateShader(context, propertiesAsUniforms, posOffsetAttribName));
|
||||
if (!shader) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
#if MLN_RENDER_BACKEND_METAL
|
||||
#include <mbgl/shaders/mtl/symbol_icon.hpp>
|
||||
#include <mbgl/shaders/mtl/symbol_sdf.hpp>
|
||||
#endif // MLN_RENDER_BACKEND_METAL
|
||||
|
||||
namespace mbgl {
|
||||
@@ -92,11 +93,11 @@ void SymbolLayerTweaker::execute(LayerGroupBase& layerGroup,
|
||||
#if MLN_RENDER_BACKEND_METAL
|
||||
if (permutationUpdated) {
|
||||
const SymbolPermutationUBO permutationUBO = {
|
||||
/* .fill_color = */ {/*.source=*/getAttributeSource("a_fill_color"), /*.expression=*/{}},
|
||||
/* .halo_color = */ {/*.source=*/getAttributeSource("a_halo_color"), /*.expression=*/{}},
|
||||
/* .opacity = */ {/*.source=*/getAttributeSource("a_opacity"), /*.expression=*/{}},
|
||||
/* .halo_width = */ {/*.source=*/getAttributeSource("a_halo_width"), /*.expression=*/{}},
|
||||
/* .halo_blur = */ {/*.source=*/getAttributeSource("a_halo_blur"), /*.expression=*/{}},
|
||||
/* .fill_color = */ {/*.source=*/getAttributeSource<BuiltIn::SymbolSDFIconShader>(5), /*.expression=*/{}},
|
||||
/* .halo_color = */ {/*.source=*/getAttributeSource<BuiltIn::SymbolSDFIconShader>(6), /*.expression=*/{}},
|
||||
/* .opacity = */ {/*.source=*/getAttributeSource<BuiltIn::SymbolSDFIconShader>(7), /*.expression=*/{}},
|
||||
/* .halo_width = */ {/*.source=*/getAttributeSource<BuiltIn::SymbolSDFIconShader>(8), /*.expression=*/{}},
|
||||
/* .halo_blur = */ {/*.source=*/getAttributeSource<BuiltIn::SymbolSDFIconShader>(9), /*.expression=*/{}},
|
||||
/* .overdrawInspector = */ overdrawInspector,
|
||||
/* .pad = */ 0,
|
||||
0,
|
||||
|
||||
@@ -157,6 +157,24 @@ void PaintParameters::clearTileClippingMasks() {
|
||||
}
|
||||
}
|
||||
|
||||
#if MLN_RENDER_BACKEND_METAL
|
||||
namespace {
|
||||
const auto clipMaskStencilMode = gfx::StencilMode{
|
||||
/*.test=*/gfx::StencilMode::Always(),
|
||||
/*.ref=*/0,
|
||||
/*.mask=*/0b11111111,
|
||||
/*.fail=*/gfx::StencilOpType::Keep,
|
||||
/*.depthFail=*/gfx::StencilOpType::Keep,
|
||||
/*.pass=*/gfx::StencilOpType::Replace,
|
||||
};
|
||||
const auto clipMaskDepthMode = gfx::DepthMode{
|
||||
/*.func=*/gfx::DepthFunctionType::Always,
|
||||
/*.mask=*/gfx::DepthMaskType::ReadOnly,
|
||||
/*.range=*/{0, 1},
|
||||
};
|
||||
} // namespace
|
||||
#endif // MLN_RENDER_BACKEND_METAL
|
||||
|
||||
template <typename TIter>
|
||||
void PaintParameters::renderTileClippingMasks(TIter beg, TIter end, GetTileIDFunc<TIter>&& f, bool clear) {
|
||||
if (tileIDsIdentical(beg, end, f, tileClippingMaskIDs)) {
|
||||
@@ -238,32 +256,13 @@ void PaintParameters::renderTileClippingMasks(TIter beg, TIter end, GetTileIDFun
|
||||
// gfx::CullFaceMode::disabled();
|
||||
encoder->setCullMode(MTL::CullModeNone);
|
||||
|
||||
auto stencilDescriptor = NS::TransferPtr(MTL::StencilDescriptor::alloc()->init());
|
||||
if (!stencilDescriptor) {
|
||||
if (auto depthStencilState = mtlContext.makeDepthStencilState(
|
||||
clipMaskDepthMode, clipMaskStencilMode, mtlRenderPass)) {
|
||||
encoder->setDepthStencilState(depthStencilState.get());
|
||||
} else {
|
||||
assert(!"Failed to create depth-stencil state");
|
||||
return;
|
||||
}
|
||||
stencilDescriptor->setStencilCompareFunction(MTL::CompareFunction::CompareFunctionAlways);
|
||||
stencilDescriptor->setStencilFailureOperation(MTL::StencilOperation::StencilOperationKeep);
|
||||
stencilDescriptor->setDepthFailureOperation(MTL::StencilOperation::StencilOperationKeep);
|
||||
stencilDescriptor->setDepthStencilPassOperation(MTL::StencilOperation::StencilOperationReplace);
|
||||
stencilDescriptor->setReadMask(0);
|
||||
stencilDescriptor->setWriteMask(0b11111111);
|
||||
|
||||
auto depthStencilDescriptor = NS::TransferPtr(MTL::DepthStencilDescriptor::alloc()->init());
|
||||
if (!depthStencilDescriptor) {
|
||||
return;
|
||||
}
|
||||
depthStencilDescriptor->setDepthCompareFunction(MTL::CompareFunction::CompareFunctionAlways);
|
||||
depthStencilDescriptor->setDepthWriteEnabled(false);
|
||||
depthStencilDescriptor->setFrontFaceStencil(stencilDescriptor.get());
|
||||
depthStencilDescriptor->setBackFaceStencil(stencilDescriptor.get());
|
||||
|
||||
auto& device = mtlContext.getBackend().getDevice();
|
||||
auto depthStencilState = NS::TransferPtr(device->newDepthStencilState(depthStencilDescriptor.get()));
|
||||
if (!depthStencilState) {
|
||||
return;
|
||||
}
|
||||
encoder->setDepthStencilState(depthStencilState.get());
|
||||
|
||||
// Create a render pipeline state, telling Metal how to render the primitives
|
||||
const auto& renderPassDescriptor = mtlRenderPass.getDescriptor();
|
||||
|
||||
@@ -392,10 +392,7 @@ void Renderer::Impl::render(const RenderTree& renderTree,
|
||||
|
||||
// Ends the RenderPass
|
||||
parameters.renderPass.reset();
|
||||
const bool isMapModeContinuous = renderTreeParameters.mapMode == MapMode::Continuous;
|
||||
if (isMapModeContinuous) {
|
||||
parameters.encoder->present(parameters.backend.getDefaultRenderable());
|
||||
}
|
||||
parameters.encoder->present(parameters.backend.getDefaultRenderable());
|
||||
|
||||
// CommandEncoder destructor submits render commands.
|
||||
parameters.encoder.reset();
|
||||
|
||||
@@ -24,11 +24,13 @@ void ImageSourceRenderData::upload(gfx::UploadPass& uploadPass) const {
|
||||
bucket->upload(uploadPass);
|
||||
}
|
||||
|
||||
#if MLN_LEGACY_RENDERER
|
||||
if (!debugTexture) {
|
||||
std::array<uint8_t, 4> data{{0, 0, 0, 0}};
|
||||
static const PremultipliedImage emptyImage{Size(1, 1), data.data(), data.size()};
|
||||
debugTexture = uploadPass.createTexture(emptyImage);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void ImageSourceRenderData::render(PaintParameters& parameters) const {
|
||||
|
||||
17
src/mbgl/shaders/mtl/background.cpp
Normal file
17
src/mbgl/shaders/mtl/background.cpp
Normal file
@@ -0,0 +1,17 @@
|
||||
#include <mbgl/shaders/mtl/background.hpp>
|
||||
#include <mbgl/shaders/background_layer_ubo.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace shaders {
|
||||
|
||||
const std::array<AttributeInfo, 1> ShaderSource<BuiltIn::BackgroundShader, gfx::Backend::Type::Metal>::attributes = {
|
||||
AttributeInfo{0, gfx::AttributeDataType::Float3, 1, "a_pos"},
|
||||
};
|
||||
const std::array<UniformBlockInfo, 2> ShaderSource<BuiltIn::BackgroundShader, gfx::Backend::Type::Metal>::uniforms = {
|
||||
UniformBlockInfo{1, true, true, sizeof(BackgroundLayerUBO), "BackgroundLayerUBO"},
|
||||
UniformBlockInfo{2, true, false, sizeof(BackgroundDrawableUBO), "BackgroundDrawableUBO"},
|
||||
};
|
||||
const std::array<TextureInfo, 0> ShaderSource<BuiltIn::BackgroundShader, gfx::Backend::Type::Metal>::textures = {};
|
||||
|
||||
} // namespace shaders
|
||||
} // namespace mbgl
|
||||
14
src/mbgl/shaders/mtl/background_pattern.cpp
Normal file
14
src/mbgl/shaders/mtl/background_pattern.cpp
Normal file
@@ -0,0 +1,14 @@
|
||||
#include <mbgl/shaders/mtl/background_pattern.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace shaders {
|
||||
|
||||
const std::array<UniformBlockInfo, 3>
|
||||
ShaderSource<BuiltIn::BackgroundPatternShader, gfx::Backend::Type::Metal>::uniforms = {
|
||||
UniformBlockInfo{1, sizeof(BackgroundLayerUBO), true, false, "BackgroundLayerUBO"},
|
||||
UniformBlockInfo{2, sizeof(BackgroundDrawableUBO), true, false, "BackgroundDrawableUBO"},
|
||||
UniformBlockInfo{3, sizeof(BackgroundPatternLayerUBO), true, false, "BackgroundLayerUBO"},
|
||||
};
|
||||
|
||||
} // namespace shaders
|
||||
} // namespace mbgl
|
||||
27
src/mbgl/shaders/mtl/circle.cpp
Normal file
27
src/mbgl/shaders/mtl/circle.cpp
Normal file
@@ -0,0 +1,27 @@
|
||||
#include <mbgl/shaders/mtl/circle.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace shaders {
|
||||
|
||||
const std::array<AttributeInfo, 8> ShaderSource<BuiltIn::CircleShader, gfx::Backend::Type::Metal>::attributes = {
|
||||
AttributeInfo{0, gfx::AttributeDataType::Short2, 1, "a_pos"},
|
||||
AttributeInfo{1, gfx::AttributeDataType::Float2, 1, "a_color"},
|
||||
AttributeInfo{2, gfx::AttributeDataType::Float2, 1, "a_radius"},
|
||||
AttributeInfo{3, gfx::AttributeDataType::Float2, 1, "a_blur"},
|
||||
AttributeInfo{4, gfx::AttributeDataType::Float2, 1, "a_opacity"},
|
||||
AttributeInfo{5, gfx::AttributeDataType::Float4, 1, "a_stroke_color"},
|
||||
AttributeInfo{6, gfx::AttributeDataType::Float2, 1, "a_stroke_width"},
|
||||
AttributeInfo{7, gfx::AttributeDataType::Float2, 1, "a_stroke_opacity"},
|
||||
};
|
||||
const std::array<UniformBlockInfo, 6> ShaderSource<BuiltIn::CircleShader, gfx::Backend::Type::Metal>::uniforms = {
|
||||
UniformBlockInfo{8, true, false, sizeof(CircleDrawableUBO), "CircleDrawableUBO"},
|
||||
UniformBlockInfo{9, true, true, sizeof(CirclePaintParamsUBO), "CirclePaintParamsUBO"},
|
||||
UniformBlockInfo{10, true, true, sizeof(CircleEvaluatedPropsUBO), "CircleEvaluatedPropsUBO"},
|
||||
UniformBlockInfo{11, true, false, sizeof(CircleInterpolateUBO), "CircleInterpolateUBO"},
|
||||
UniformBlockInfo{12, true, true, sizeof(CirclePermutationUBO), "CirclePermutationUBO"},
|
||||
UniformBlockInfo{13, true, false, sizeof(ExpressionInputsUBO), "ExpressionInputsUBO"},
|
||||
};
|
||||
const std::array<TextureInfo, 0> ShaderSource<BuiltIn::CircleShader, gfx::Backend::Type::Metal>::textures = {};
|
||||
|
||||
} // namespace shaders
|
||||
} // namespace mbgl
|
||||
16
src/mbgl/shaders/mtl/clipping_mask.cpp
Normal file
16
src/mbgl/shaders/mtl/clipping_mask.cpp
Normal file
@@ -0,0 +1,16 @@
|
||||
#include <mbgl/shaders/mtl/clipping_mask.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace shaders {
|
||||
|
||||
const std::array<AttributeInfo, 1> ShaderSource<BuiltIn::ClippingMaskProgram, gfx::Backend::Type::Metal>::attributes = {
|
||||
AttributeInfo{0, gfx::AttributeDataType::Float3, 1, "a_pos"},
|
||||
};
|
||||
const std::array<UniformBlockInfo, 1> ShaderSource<BuiltIn::ClippingMaskProgram, gfx::Backend::Type::Metal>::uniforms =
|
||||
{
|
||||
UniformBlockInfo{1, true, false, sizeof(ClipUBO), "ClipUBO"},
|
||||
};
|
||||
const std::array<TextureInfo, 0> ShaderSource<BuiltIn::ClippingMaskProgram, gfx::Backend::Type::Metal>::textures = {};
|
||||
|
||||
} // namespace shaders
|
||||
} // namespace mbgl
|
||||
19
src/mbgl/shaders/mtl/collision_box.cpp
Normal file
19
src/mbgl/shaders/mtl/collision_box.cpp
Normal file
@@ -0,0 +1,19 @@
|
||||
#include <mbgl/shaders/mtl/collision_box.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace shaders {
|
||||
|
||||
const std::array<AttributeInfo, 5> ShaderSource<BuiltIn::CollisionBoxShader, gfx::Backend::Type::Metal>::attributes = {
|
||||
AttributeInfo{0, gfx::AttributeDataType::Short2, 1, "a_pos"},
|
||||
AttributeInfo{1, gfx::AttributeDataType::Short2, 1, "a_anchor_pos"},
|
||||
AttributeInfo{2, gfx::AttributeDataType::Short2, 1, "a_extrude"},
|
||||
AttributeInfo{3, gfx::AttributeDataType::UByte2, 1, "a_placed"},
|
||||
AttributeInfo{4, gfx::AttributeDataType::Float2, 1, "a_shift"},
|
||||
};
|
||||
const std::array<UniformBlockInfo, 1> ShaderSource<BuiltIn::CollisionBoxShader, gfx::Backend::Type::Metal>::uniforms = {
|
||||
UniformBlockInfo{5, true, true, sizeof(CollisionUBO), "CollisionBoxUBO"},
|
||||
};
|
||||
const std::array<TextureInfo, 0> ShaderSource<BuiltIn::CollisionBoxShader, gfx::Backend::Type::Metal>::textures = {};
|
||||
|
||||
} // namespace shaders
|
||||
} // namespace mbgl
|
||||
20
src/mbgl/shaders/mtl/collision_circle.cpp
Normal file
20
src/mbgl/shaders/mtl/collision_circle.cpp
Normal file
@@ -0,0 +1,20 @@
|
||||
#include <mbgl/shaders/mtl/collision_circle.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace shaders {
|
||||
|
||||
const std::array<AttributeInfo, 4> ShaderSource<BuiltIn::CollisionCircleShader, gfx::Backend::Type::Metal>::attributes =
|
||||
{
|
||||
AttributeInfo{0, gfx::AttributeDataType::Short2, 1, "a_pos"},
|
||||
AttributeInfo{1, gfx::AttributeDataType::Short2, 1, "a_anchor_pos"},
|
||||
AttributeInfo{2, gfx::AttributeDataType::Short2, 1, "a_extrude"},
|
||||
AttributeInfo{3, gfx::AttributeDataType::UByte2, 1, "a_placed"},
|
||||
};
|
||||
const std::array<UniformBlockInfo, 1>
|
||||
ShaderSource<BuiltIn::CollisionCircleShader, gfx::Backend::Type::Metal>::uniforms = {
|
||||
UniformBlockInfo{5, true, true, sizeof(CollisionUBO), "CollisionCircleUBO"},
|
||||
};
|
||||
const std::array<TextureInfo, 0> ShaderSource<BuiltIn::CollisionCircleShader, gfx::Backend::Type::Metal>::textures = {};
|
||||
|
||||
} // namespace shaders
|
||||
} // namespace mbgl
|
||||
82
src/mbgl/shaders/mtl/fill.cpp
Normal file
82
src/mbgl/shaders/mtl/fill.cpp
Normal file
@@ -0,0 +1,82 @@
|
||||
#include <mbgl/shaders/mtl/fill.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace shaders {
|
||||
|
||||
const std::array<AttributeInfo, 4> ShaderSource<BuiltIn::FillShader, gfx::Backend::Type::Metal>::attributes = {
|
||||
AttributeInfo{0, gfx::AttributeDataType::Short2, 1, "a_pos"},
|
||||
AttributeInfo{1, gfx::AttributeDataType::Float2, 1, "a_color"},
|
||||
AttributeInfo{2, gfx::AttributeDataType::Float2, 1, "a_opacity"},
|
||||
|
||||
// This shader doesn't use it, but we need this so that the layer can assign the same
|
||||
// attributes to all the drawables. If/When `VertexAttributeArray::resolve` allows it,
|
||||
// this can be removed.
|
||||
AttributeInfo{8, gfx::AttributeDataType::Float2, 1, "a_outline_color"},
|
||||
};
|
||||
const std::array<UniformBlockInfo, 5> ShaderSource<BuiltIn::FillShader, gfx::Backend::Type::Metal>::uniforms = {
|
||||
UniformBlockInfo{3, true, false, sizeof(FillDrawableUBO), "FillDrawableUBO"},
|
||||
UniformBlockInfo{4, true, true, sizeof(FillEvaluatedPropsUBO), "FillEvaluatedPropsUBO"},
|
||||
UniformBlockInfo{5, true, false, sizeof(FillInterpolateUBO), "FillInterpolateUBO"},
|
||||
UniformBlockInfo{6, true, true, sizeof(FillPermutationUBO), "FillPermutationUBO"},
|
||||
UniformBlockInfo{7, true, false, sizeof(ExpressionInputsUBO), "ExpressionInputsUBO"},
|
||||
};
|
||||
const std::array<TextureInfo, 0> ShaderSource<BuiltIn::FillShader, gfx::Backend::Type::Metal>::textures = {};
|
||||
|
||||
const std::array<AttributeInfo, 4> ShaderSource<BuiltIn::FillOutlineShader, gfx::Backend::Type::Metal>::attributes = {
|
||||
AttributeInfo{0, gfx::AttributeDataType::Short2, 1, "a_pos"},
|
||||
AttributeInfo{1, gfx::AttributeDataType::Float2, 1, "a_outline_color"},
|
||||
AttributeInfo{2, gfx::AttributeDataType::Float2, 1, "a_opacity"},
|
||||
|
||||
// See `a_outline_color` in FillShader
|
||||
AttributeInfo{8, gfx::AttributeDataType::Float2, 1, "a_color"},
|
||||
};
|
||||
const std::array<UniformBlockInfo, 5> ShaderSource<BuiltIn::FillOutlineShader, gfx::Backend::Type::Metal>::uniforms = {
|
||||
UniformBlockInfo{3, true, false, sizeof(FillOutlineDrawableUBO), "FillOutlineDrawableUBO"},
|
||||
UniformBlockInfo{4, true, true, sizeof(FillOutlineEvaluatedPropsUBO), "FillOutlineEvaluatedPropsUBO"},
|
||||
UniformBlockInfo{5, true, false, sizeof(FillOutlineInterpolateUBO), "FillOutlineInterpolateUBO"},
|
||||
UniformBlockInfo{6, true, true, sizeof(FillOutlinePermutationUBO), "FillOutlinePermutationUBO"},
|
||||
UniformBlockInfo{7, true, false, sizeof(ExpressionInputsUBO), "ExpressionInputsUBO"},
|
||||
};
|
||||
const std::array<TextureInfo, 0> ShaderSource<BuiltIn::FillOutlineShader, gfx::Backend::Type::Metal>::textures = {};
|
||||
|
||||
const std::array<AttributeInfo, 4> ShaderSource<BuiltIn::FillPatternShader, gfx::Backend::Type::Metal>::attributes = {
|
||||
AttributeInfo{0, gfx::AttributeDataType::Short2, 1, "a_pos"},
|
||||
AttributeInfo{1, gfx::AttributeDataType::UShort4, 1, "a_pattern_from"},
|
||||
AttributeInfo{2, gfx::AttributeDataType::UShort4, 1, "a_pattern_to"},
|
||||
AttributeInfo{3, gfx::AttributeDataType::Float2, 1, "a_opacity"},
|
||||
};
|
||||
const std::array<UniformBlockInfo, 6> ShaderSource<BuiltIn::FillPatternShader, gfx::Backend::Type::Metal>::uniforms = {
|
||||
UniformBlockInfo{4, true, true, sizeof(FillPatternDrawableUBO), "FillPatternDrawableUBO"},
|
||||
UniformBlockInfo{5, true, false, sizeof(FillPatternTilePropsUBO), "FillPatternTilePropsUBO"},
|
||||
UniformBlockInfo{6, true, true, sizeof(FillPatternEvaluatedPropsUBO), "FillPatternEvaluatedPropsUBO"},
|
||||
UniformBlockInfo{7, true, false, sizeof(FillPatternInterpolateUBO), "FillPatternInterpolateUBO"},
|
||||
UniformBlockInfo{8, true, true, sizeof(FillPatternPermutationUBO), "FillPatternPermutationUBO"},
|
||||
UniformBlockInfo{9, true, false, sizeof(ExpressionInputsUBO), "ExpressionInputsUBO"},
|
||||
};
|
||||
const std::array<TextureInfo, 1> ShaderSource<BuiltIn::FillPatternShader, gfx::Backend::Type::Metal>::textures = {
|
||||
TextureInfo{0, "u_image"},
|
||||
};
|
||||
|
||||
const std::array<AttributeInfo, 4>
|
||||
ShaderSource<BuiltIn::FillOutlinePatternShader, gfx::Backend::Type::Metal>::attributes = {
|
||||
AttributeInfo{0, gfx::AttributeDataType::Short2, 1, "a_pos"},
|
||||
AttributeInfo{1, gfx::AttributeDataType::UShort4, 1, "a_pattern_from"},
|
||||
AttributeInfo{2, gfx::AttributeDataType::UShort4, 1, "a_pattern_to"},
|
||||
AttributeInfo{3, gfx::AttributeDataType::Float2, 1, "a_opacity"},
|
||||
};
|
||||
const std::array<UniformBlockInfo, 6> ShaderSource<BuiltIn::FillOutlinePatternShader,
|
||||
gfx::Backend::Type::Metal>::uniforms = {
|
||||
UniformBlockInfo{4, true, true, sizeof(FillOutlinePatternDrawableUBO), "FillOutlinePatternDrawableUBO"},
|
||||
UniformBlockInfo{5, true, false, sizeof(FillOutlinePatternTilePropsUBO), "FillOutlinePatternTilePropsUBO"},
|
||||
UniformBlockInfo{6, true, true, sizeof(FillOutlinePatternEvaluatedPropsUBO), "FillOutlinePatternEvaluatedPropsUBO"},
|
||||
UniformBlockInfo{7, true, false, sizeof(FillOutlinePatternInterpolateUBO), "FillOutlinePatternInterpolateUBO"},
|
||||
UniformBlockInfo{8, true, true, sizeof(FillOutlinePatternPermutationUBO), "FillOutlinePatternPermutationUBO"},
|
||||
UniformBlockInfo{9, true, false, sizeof(ExpressionInputsUBO), "ExpressionInputsUBO"},
|
||||
};
|
||||
const std::array<TextureInfo, 1> ShaderSource<BuiltIn::FillOutlinePatternShader, gfx::Backend::Type::Metal>::textures =
|
||||
{
|
||||
TextureInfo{0, "u_image"},
|
||||
};
|
||||
|
||||
} // namespace shaders
|
||||
} // namespace mbgl
|
||||
24
src/mbgl/shaders/mtl/fill_extrusion.cpp
Normal file
24
src/mbgl/shaders/mtl/fill_extrusion.cpp
Normal file
@@ -0,0 +1,24 @@
|
||||
#include <mbgl/shaders/mtl/fill_extrusion.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace shaders {
|
||||
|
||||
const std::array<AttributeInfo, 5> ShaderSource<BuiltIn::FillExtrusionShader, gfx::Backend::Type::Metal>::attributes = {
|
||||
AttributeInfo{0, gfx::AttributeDataType::Short2, 1, "a_pos"},
|
||||
AttributeInfo{1, gfx::AttributeDataType::Short4, 1, "a_normal_ed"},
|
||||
AttributeInfo{2, gfx::AttributeDataType::Float4, 1, "a_color"},
|
||||
AttributeInfo{3, gfx::AttributeDataType::Float, 1, "a_base"},
|
||||
AttributeInfo{4, gfx::AttributeDataType::Float, 1, "a_height"},
|
||||
};
|
||||
const std::array<UniformBlockInfo, 5> ShaderSource<BuiltIn::FillExtrusionShader, gfx::Backend::Type::Metal>::uniforms =
|
||||
{
|
||||
UniformBlockInfo{5, true, false, sizeof(FillExtrusionDrawableUBO), "FillExtrusionDrawableUBO"},
|
||||
UniformBlockInfo{6, true, false, sizeof(FillExtrusionDrawablePropsUBO), "FillExtrusionDrawablePropsUBO"},
|
||||
UniformBlockInfo{7, true, false, sizeof(FillExtrusionInterpolateUBO), "FillExtrusionInterpolateUBO"},
|
||||
UniformBlockInfo{8, true, false, sizeof(FillExtrusionPermutationUBO), "FillExtrusionPermutationUBO"},
|
||||
UniformBlockInfo{9, true, false, sizeof(ExpressionInputsUBO), "ExpressionInputsUBO"},
|
||||
};
|
||||
const std::array<TextureInfo, 0> ShaderSource<BuiltIn::FillExtrusionShader, gfx::Backend::Type::Metal>::textures = {};
|
||||
|
||||
} // namespace shaders
|
||||
} // namespace mbgl
|
||||
14
src/mbgl/shaders/mtl/fill_extrusion_pattern.cpp
Normal file
14
src/mbgl/shaders/mtl/fill_extrusion_pattern.cpp
Normal file
@@ -0,0 +1,14 @@
|
||||
#include <mbgl/shaders/mtl/fill_extrusion_pattern.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace shaders {
|
||||
|
||||
const std::array<AttributeInfo, 0>
|
||||
ShaderSource<BuiltIn::FillExtrusionPatternShader, gfx::Backend::Type::Metal>::attributes = {};
|
||||
const std::array<UniformBlockInfo, 0>
|
||||
ShaderSource<BuiltIn::FillExtrusionPatternShader, gfx::Backend::Type::Metal>::uniforms = {};
|
||||
const std::array<TextureInfo, 0>
|
||||
ShaderSource<BuiltIn::FillExtrusionPatternShader, gfx::Backend::Type::Metal>::textures = {};
|
||||
|
||||
} // namespace shaders
|
||||
} // namespace mbgl
|
||||
21
src/mbgl/shaders/mtl/heatmap.cpp
Normal file
21
src/mbgl/shaders/mtl/heatmap.cpp
Normal file
@@ -0,0 +1,21 @@
|
||||
#include <mbgl/shaders/mtl/heatmap.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace shaders {
|
||||
|
||||
const std::array<AttributeInfo, 3> ShaderSource<BuiltIn::HeatmapShader, gfx::Backend::Type::Metal>::attributes = {
|
||||
AttributeInfo{0, gfx::AttributeDataType::Short2, 1, "a_pos"},
|
||||
AttributeInfo{1, gfx::AttributeDataType::Float2, 1, "a_weight"},
|
||||
AttributeInfo{2, gfx::AttributeDataType::Float2, 1, "a_radius"},
|
||||
};
|
||||
const std::array<UniformBlockInfo, 5> ShaderSource<BuiltIn::HeatmapShader, gfx::Backend::Type::Metal>::uniforms = {
|
||||
UniformBlockInfo{3, true, false, sizeof(HeatmapDrawableUBO), "HeatmapDrawableUBO"},
|
||||
UniformBlockInfo{4, true, true, sizeof(HeatmapEvaluatedPropsUBO), "HeatmapEvaluatedPropsUBO"},
|
||||
UniformBlockInfo{5, true, false, sizeof(HeatmapInterpolateUBO), "HeatmapInterpolateUBO"},
|
||||
UniformBlockInfo{6, true, true, sizeof(HeatmapPermutationUBO), "HeatmapPermutationUBO"},
|
||||
UniformBlockInfo{7, true, false, sizeof(ExpressionInputsUBO), "ExpressionInputsUBO"},
|
||||
};
|
||||
const std::array<TextureInfo, 0> ShaderSource<BuiltIn::HeatmapShader, gfx::Backend::Type::Metal>::textures = {};
|
||||
|
||||
} // namespace shaders
|
||||
} // namespace mbgl
|
||||
20
src/mbgl/shaders/mtl/heatmap_texture.cpp
Normal file
20
src/mbgl/shaders/mtl/heatmap_texture.cpp
Normal file
@@ -0,0 +1,20 @@
|
||||
#include <mbgl/shaders/mtl/heatmap_texture.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace shaders {
|
||||
|
||||
const std::array<AttributeInfo, 1> ShaderSource<BuiltIn::HeatmapTextureShader, gfx::Backend::Type::Metal>::attributes =
|
||||
{
|
||||
AttributeInfo{0, gfx::AttributeDataType::Short2, 1, "a_pos"},
|
||||
};
|
||||
const std::array<UniformBlockInfo, 1> ShaderSource<BuiltIn::HeatmapTextureShader, gfx::Backend::Type::Metal>::uniforms =
|
||||
{
|
||||
UniformBlockInfo{1, true, true, sizeof(HeatmapTextureDrawableUBO), "HeatmapTextureDrawableUBO"},
|
||||
};
|
||||
const std::array<TextureInfo, 2> ShaderSource<BuiltIn::HeatmapTextureShader, gfx::Backend::Type::Metal>::textures = {
|
||||
TextureInfo{0, "u_image"},
|
||||
TextureInfo{1, "u_color_ramp"},
|
||||
};
|
||||
|
||||
} // namespace shaders
|
||||
} // namespace mbgl
|
||||
19
src/mbgl/shaders/mtl/hillshade.cpp
Normal file
19
src/mbgl/shaders/mtl/hillshade.cpp
Normal file
@@ -0,0 +1,19 @@
|
||||
#include <mbgl/shaders/mtl/hillshade.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace shaders {
|
||||
|
||||
const std::array<AttributeInfo, 2> ShaderSource<BuiltIn::HillshadeShader, gfx::Backend::Type::Metal>::attributes = {
|
||||
AttributeInfo{0, gfx::AttributeDataType::Short2, 1, "a_pos"},
|
||||
AttributeInfo{1, gfx::AttributeDataType::Short2, 1, "a_texture_pos"},
|
||||
};
|
||||
const std::array<UniformBlockInfo, 2> ShaderSource<BuiltIn::HillshadeShader, gfx::Backend::Type::Metal>::uniforms = {
|
||||
UniformBlockInfo{2, true, true, sizeof(HillshadeDrawableUBO), "HillshadeDrawableUBO"},
|
||||
UniformBlockInfo{3, false, true, sizeof(HillshadeEvaluatedPropsUBO), "HillshadeEvaluatedPropsUBO"},
|
||||
};
|
||||
const std::array<TextureInfo, 1> ShaderSource<BuiltIn::HillshadeShader, gfx::Backend::Type::Metal>::textures = {
|
||||
TextureInfo{0, "u_image"},
|
||||
};
|
||||
|
||||
} // namespace shaders
|
||||
} // namespace mbgl
|
||||
20
src/mbgl/shaders/mtl/hillshade_prepare.cpp
Normal file
20
src/mbgl/shaders/mtl/hillshade_prepare.cpp
Normal file
@@ -0,0 +1,20 @@
|
||||
#include <mbgl/shaders/mtl/hillshade_prepare.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace shaders {
|
||||
|
||||
const std::array<AttributeInfo, 2>
|
||||
ShaderSource<BuiltIn::HillshadePrepareShader, gfx::Backend::Type::Metal>::attributes = {
|
||||
AttributeInfo{0, gfx::AttributeDataType::Short2, 1, "a_pos"},
|
||||
AttributeInfo{1, gfx::AttributeDataType::Short2, 1, "a_texture_pos"},
|
||||
};
|
||||
const std::array<UniformBlockInfo, 1>
|
||||
ShaderSource<BuiltIn::HillshadePrepareShader, gfx::Backend::Type::Metal>::uniforms = {
|
||||
UniformBlockInfo{2, true, true, sizeof(HillshadePrepareDrawableUBO), "HillshadePrepareDrawableUBO"},
|
||||
};
|
||||
const std::array<TextureInfo, 1> ShaderSource<BuiltIn::HillshadePrepareShader, gfx::Backend::Type::Metal>::textures = {
|
||||
TextureInfo{0, "u_image"},
|
||||
};
|
||||
|
||||
} // namespace shaders
|
||||
} // namespace mbgl
|
||||
49
src/mbgl/shaders/mtl/line.cpp
Normal file
49
src/mbgl/shaders/mtl/line.cpp
Normal file
@@ -0,0 +1,49 @@
|
||||
#include <mbgl/shaders/mtl/line.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace shaders {
|
||||
|
||||
const std::array<AttributeInfo, 8> ShaderSource<BuiltIn::LineShader, gfx::Backend::Type::Metal>::attributes = {
|
||||
AttributeInfo{0, gfx::AttributeDataType::Short2, 1, "a_pos_normal"},
|
||||
AttributeInfo{1, gfx::AttributeDataType::UByte4, 1, "a_data"},
|
||||
AttributeInfo{2, gfx::AttributeDataType::Float4, 1, "a_color"},
|
||||
AttributeInfo{3, gfx::AttributeDataType::Float2, 1, "a_blur"},
|
||||
AttributeInfo{4, gfx::AttributeDataType::Float2, 1, "a_opacity"},
|
||||
AttributeInfo{5, gfx::AttributeDataType::Float2, 1, "a_gapwidth"},
|
||||
AttributeInfo{6, gfx::AttributeDataType::Float2, 1, "a_offset"},
|
||||
AttributeInfo{7, gfx::AttributeDataType::Float2, 1, "a_width"},
|
||||
};
|
||||
const std::array<UniformBlockInfo, 5> ShaderSource<BuiltIn::LineShader, gfx::Backend::Type::Metal>::uniforms = {
|
||||
UniformBlockInfo{8, true, true, sizeof(LineUBO), "LineUBO"},
|
||||
UniformBlockInfo{9, true, false, sizeof(LinePropertiesUBO), "LinePropertiesUBO"},
|
||||
UniformBlockInfo{10, true, false, sizeof(LineInterpolationUBO), "LineInterpolationUBO"},
|
||||
UniformBlockInfo{11, true, true, sizeof(LinePermutationUBO), "LinePermutationUBO"},
|
||||
UniformBlockInfo{12, true, false, sizeof(ExpressionInputsUBO), "ExpressionInputsUBO"},
|
||||
};
|
||||
const std::array<TextureInfo, 0> ShaderSource<BuiltIn::LineShader, gfx::Backend::Type::Metal>::textures = {};
|
||||
|
||||
const std::array<AttributeInfo, 9> ShaderSource<BuiltIn::LinePatternShader, gfx::Backend::Type::Metal>::attributes = {
|
||||
AttributeInfo{0, gfx::AttributeDataType::Short2, 1, "a_pos_normal"},
|
||||
AttributeInfo{1, gfx::AttributeDataType::UByte4, 1, "a_data"},
|
||||
AttributeInfo{2, gfx::AttributeDataType::Float2, 1, "a_blur"},
|
||||
AttributeInfo{3, gfx::AttributeDataType::Float2, 1, "a_opacity"},
|
||||
AttributeInfo{4, gfx::AttributeDataType::Float2, 1, "a_gapwidth"},
|
||||
AttributeInfo{5, gfx::AttributeDataType::Float2, 1, "a_offset"},
|
||||
AttributeInfo{6, gfx::AttributeDataType::Float2, 1, "a_width"},
|
||||
AttributeInfo{7, gfx::AttributeDataType::UShort4, 1, "a_pattern_from"},
|
||||
AttributeInfo{8, gfx::AttributeDataType::UShort4, 1, "a_pattern_to"},
|
||||
};
|
||||
const std::array<UniformBlockInfo, 6> ShaderSource<BuiltIn::LinePatternShader, gfx::Backend::Type::Metal>::uniforms = {
|
||||
UniformBlockInfo{9, true, true, sizeof(LinePatternUBO), "LinePatternUBO"},
|
||||
UniformBlockInfo{10, true, false, sizeof(LinePatternPropertiesUBO), "LinePatternPropertiesUBO"},
|
||||
UniformBlockInfo{11, true, false, sizeof(LinePatternInterpolationUBO), "LinePatternInterpolationUBO"},
|
||||
UniformBlockInfo{12, true, false, sizeof(LinePatternTilePropertiesUBO), "LinePatternTilePropertiesUBO"},
|
||||
UniformBlockInfo{13, true, true, sizeof(LinePermutationUBO), "LinePermutationUBO"},
|
||||
UniformBlockInfo{14, true, false, sizeof(ExpressionInputsUBO), "ExpressionInputsUBO"},
|
||||
};
|
||||
const std::array<TextureInfo, 1> ShaderSource<BuiltIn::LinePatternShader, gfx::Backend::Type::Metal>::textures = {
|
||||
TextureInfo{0, "u_image"},
|
||||
};
|
||||
|
||||
} // namespace shaders
|
||||
} // namespace mbgl
|
||||
27
src/mbgl/shaders/mtl/line_gradient.cpp
Normal file
27
src/mbgl/shaders/mtl/line_gradient.cpp
Normal file
@@ -0,0 +1,27 @@
|
||||
#include <mbgl/shaders/mtl/line_gradient.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace shaders {
|
||||
|
||||
const std::array<AttributeInfo, 7> ShaderSource<BuiltIn::LineGradientShader, gfx::Backend::Type::Metal>::attributes = {
|
||||
AttributeInfo{0, gfx::AttributeDataType::Short2, 1, "a_pos_normal"},
|
||||
AttributeInfo{1, gfx::AttributeDataType::UByte4, 1, "a_data"},
|
||||
AttributeInfo{2, gfx::AttributeDataType::Float2, 1, "a_blur"},
|
||||
AttributeInfo{3, gfx::AttributeDataType::Float2, 1, "a_opacity"},
|
||||
AttributeInfo{4, gfx::AttributeDataType::Float2, 1, "a_gapwidth"},
|
||||
AttributeInfo{5, gfx::AttributeDataType::Float2, 1, "a_offset"},
|
||||
AttributeInfo{6, gfx::AttributeDataType::Float2, 1, "a_width"},
|
||||
};
|
||||
const std::array<UniformBlockInfo, 5> ShaderSource<BuiltIn::LineGradientShader, gfx::Backend::Type::Metal>::uniforms = {
|
||||
UniformBlockInfo{7, true, true, sizeof(LineGradientUBO), "LineGradientUBO"},
|
||||
UniformBlockInfo{8, true, false, sizeof(LineGradientPropertiesUBO), "LineGradientPropertiesUBO"},
|
||||
UniformBlockInfo{9, true, false, sizeof(LineGradientInterpolationUBO), "LineGradientInterpolationUBO"},
|
||||
UniformBlockInfo{10, true, true, sizeof(LinePermutationUBO), "LinePermutationUBO"},
|
||||
UniformBlockInfo{11, true, false, sizeof(ExpressionInputsUBO), "ExpressionInputsUBO"},
|
||||
};
|
||||
const std::array<TextureInfo, 1> ShaderSource<BuiltIn::LineGradientShader, gfx::Backend::Type::Metal>::textures = {
|
||||
TextureInfo{0, "u_image"},
|
||||
};
|
||||
|
||||
} // namespace shaders
|
||||
} // namespace mbgl
|
||||
19
src/mbgl/shaders/mtl/raster.cpp
Normal file
19
src/mbgl/shaders/mtl/raster.cpp
Normal file
@@ -0,0 +1,19 @@
|
||||
#include <mbgl/shaders/mtl/raster.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace shaders {
|
||||
|
||||
const std::array<AttributeInfo, 2> ShaderSource<BuiltIn::RasterShader, gfx::Backend::Type::Metal>::attributes = {
|
||||
AttributeInfo{0, gfx::AttributeDataType::Short2, 1, "a_pos"},
|
||||
AttributeInfo{1, gfx::AttributeDataType::Short2, 1, "a_texture_pos"},
|
||||
};
|
||||
const std::array<UniformBlockInfo, 1> ShaderSource<BuiltIn::RasterShader, gfx::Backend::Type::Metal>::uniforms = {
|
||||
UniformBlockInfo{2, true, true, sizeof(RasterDrawableUBO), "RasterDrawableUBO"},
|
||||
};
|
||||
const std::array<TextureInfo, 2> ShaderSource<BuiltIn::RasterShader, gfx::Backend::Type::Metal>::textures = {
|
||||
TextureInfo{0, "u_image0"},
|
||||
TextureInfo{1, "u_image1"},
|
||||
};
|
||||
|
||||
} // namespace shaders
|
||||
} // namespace mbgl
|
||||
@@ -22,8 +22,32 @@
|
||||
using namespace std::string_literals;
|
||||
|
||||
namespace mbgl {
|
||||
namespace mtl {
|
||||
|
||||
shaders::AttributeInfo::AttributeInfo(std::size_t index_,
|
||||
gfx::AttributeDataType dataType_,
|
||||
std::size_t count_,
|
||||
std::string_view name_)
|
||||
: index(index_),
|
||||
dataType(dataType_),
|
||||
count(count_),
|
||||
name(name_),
|
||||
nameID(stringIndexer().get(name_)) {}
|
||||
|
||||
shaders::UniformBlockInfo::UniformBlockInfo(
|
||||
std::size_t index_, bool vertex_, bool fragment_, std::size_t size_, std::string_view name_)
|
||||
: index(index_),
|
||||
vertex(vertex_),
|
||||
fragment(fragment_),
|
||||
size(size_),
|
||||
name(name_),
|
||||
nameID(stringIndexer().get(name_)) {}
|
||||
|
||||
shaders::TextureInfo::TextureInfo(std::size_t index_, std::string_view name_)
|
||||
: index(index_),
|
||||
name(name_),
|
||||
nameID(stringIndexer().get(name_)) {}
|
||||
|
||||
namespace mtl {
|
||||
namespace {
|
||||
MTL::BlendOperation metalBlendOperation(const gfx::ColorBlendEquationType& colorBlend) {
|
||||
switch (colorBlend) {
|
||||
|
||||
30
src/mbgl/shaders/mtl/symbol_icon.cpp
Normal file
30
src/mbgl/shaders/mtl/symbol_icon.cpp
Normal file
@@ -0,0 +1,30 @@
|
||||
#include <mbgl/shaders/mtl/symbol_icon.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace shaders {
|
||||
|
||||
const std::array<AttributeInfo, 6> ShaderSource<BuiltIn::SymbolIconShader, gfx::Backend::Type::Metal>::attributes = {
|
||||
// always attributes
|
||||
AttributeInfo{0, gfx::AttributeDataType::Short4, 1, "a_pos_offset"},
|
||||
AttributeInfo{1, gfx::AttributeDataType::UShort4, 1, "a_data"},
|
||||
AttributeInfo{2, gfx::AttributeDataType::Short4, 1, "a_pixeloffset"},
|
||||
AttributeInfo{3, gfx::AttributeDataType::Float3, 1, "a_projected_pos"},
|
||||
AttributeInfo{4, gfx::AttributeDataType::Float, 1, "a_fade_opacity"},
|
||||
|
||||
// sometimes uniforms
|
||||
AttributeInfo{5, gfx::AttributeDataType::Float, 1, "a_opacity"},
|
||||
};
|
||||
const std::array<UniformBlockInfo, 6> ShaderSource<BuiltIn::SymbolIconShader, gfx::Backend::Type::Metal>::uniforms = {
|
||||
UniformBlockInfo{8, true, true, sizeof(SymbolDrawableUBO), "SymbolDrawableUBO"},
|
||||
UniformBlockInfo{9, true, true, sizeof(SymbolDrawablePaintUBO), "SymbolDrawablePaintUBO"},
|
||||
UniformBlockInfo{10, true, false, sizeof(SymbolDrawableTilePropsUBO), "SymbolDrawableTilePropsUBO"},
|
||||
UniformBlockInfo{11, true, false, sizeof(SymbolDrawableInterpolateUBO), "SymbolDrawableInterpolateUBO"},
|
||||
UniformBlockInfo{12, true, true, sizeof(SymbolPermutationUBO), "SymbolPermutationUBO"},
|
||||
UniformBlockInfo{13, true, false, sizeof(ExpressionInputsUBO), "ExpressionInputsUBO"},
|
||||
};
|
||||
const std::array<TextureInfo, 1> ShaderSource<BuiltIn::SymbolIconShader, gfx::Backend::Type::Metal>::textures = {
|
||||
TextureInfo{0, "u_texture"},
|
||||
};
|
||||
|
||||
} // namespace shaders
|
||||
} // namespace mbgl
|
||||
36
src/mbgl/shaders/mtl/symbol_sdf.cpp
Normal file
36
src/mbgl/shaders/mtl/symbol_sdf.cpp
Normal file
@@ -0,0 +1,36 @@
|
||||
#include <mbgl/shaders/mtl/symbol_sdf.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace shaders {
|
||||
|
||||
const std::array<AttributeInfo, 10> ShaderSource<BuiltIn::SymbolSDFIconShader, gfx::Backend::Type::Metal>::attributes =
|
||||
{
|
||||
// always attributes
|
||||
AttributeInfo{0, gfx::AttributeDataType::Short4, 1, "a_pos_offset"},
|
||||
AttributeInfo{1, gfx::AttributeDataType::UShort4, 1, "a_data"},
|
||||
AttributeInfo{2, gfx::AttributeDataType::Short4, 1, "a_pixeloffset"},
|
||||
AttributeInfo{3, gfx::AttributeDataType::Float3, 1, "a_projected_pos"},
|
||||
AttributeInfo{4, gfx::AttributeDataType::Float, 1, "a_fade_opacity"},
|
||||
|
||||
// sometimes uniforms
|
||||
AttributeInfo{5, gfx::AttributeDataType::Float4, 1, "a_fill_color"},
|
||||
AttributeInfo{6, gfx::AttributeDataType::Float4, 1, "a_halo_color"},
|
||||
AttributeInfo{7, gfx::AttributeDataType::Float, 1, "a_opacity"},
|
||||
AttributeInfo{8, gfx::AttributeDataType::Float, 1, "a_halo_width"},
|
||||
AttributeInfo{9, gfx::AttributeDataType::Float, 1, "a_halo_blur"},
|
||||
};
|
||||
const std::array<UniformBlockInfo, 6> ShaderSource<BuiltIn::SymbolSDFIconShader, gfx::Backend::Type::Metal>::uniforms =
|
||||
{
|
||||
UniformBlockInfo{10, true, true, sizeof(SymbolDrawableUBO), "SymbolDrawableUBO"},
|
||||
UniformBlockInfo{11, true, false, sizeof(SymbolDrawablePaintUBO), "SymbolDrawablePaintUBO"},
|
||||
UniformBlockInfo{12, true, true, sizeof(SymbolDrawableTilePropsUBO), "SymbolDrawableTilePropsUBO"},
|
||||
UniformBlockInfo{13, true, false, sizeof(SymbolDrawableInterpolateUBO), "SymbolDrawableInterpolateUBO"},
|
||||
UniformBlockInfo{14, true, true, sizeof(SymbolPermutationUBO), "SymbolPermutationUBO"},
|
||||
UniformBlockInfo{15, true, false, sizeof(ExpressionInputsUBO), "ExpressionInputsUBO"},
|
||||
};
|
||||
const std::array<TextureInfo, 1> ShaderSource<BuiltIn::SymbolSDFIconShader, gfx::Backend::Type::Metal>::textures = {
|
||||
TextureInfo{0, "u_texture"},
|
||||
};
|
||||
|
||||
} // namespace shaders
|
||||
} // namespace mbgl
|
||||
36
src/mbgl/shaders/mtl/symbol_text_and_icon.cpp
Normal file
36
src/mbgl/shaders/mtl/symbol_text_and_icon.cpp
Normal file
@@ -0,0 +1,36 @@
|
||||
#include <mbgl/shaders/mtl/symbol_text_and_icon.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace shaders {
|
||||
|
||||
const std::array<AttributeInfo, 9>
|
||||
ShaderSource<BuiltIn::SymbolTextAndIconShader, gfx::Backend::Type::Metal>::attributes = {
|
||||
// always attributes
|
||||
AttributeInfo{0, gfx::AttributeDataType::Short4, 1, "a_pos_offset"},
|
||||
AttributeInfo{1, gfx::AttributeDataType::UShort4, 1, "a_data"},
|
||||
AttributeInfo{2, gfx::AttributeDataType::Float3, 1, "a_projected_pos"},
|
||||
AttributeInfo{3, gfx::AttributeDataType::Float, 1, "a_fade_opacity"},
|
||||
|
||||
// sometimes uniforms
|
||||
AttributeInfo{4, gfx::AttributeDataType::Float4, 1, "a_fill_color"},
|
||||
AttributeInfo{5, gfx::AttributeDataType::Float4, 1, "a_halo_color"},
|
||||
AttributeInfo{6, gfx::AttributeDataType::Float, 1, "a_opacity"},
|
||||
AttributeInfo{7, gfx::AttributeDataType::Float, 1, "a_halo_width"},
|
||||
AttributeInfo{8, gfx::AttributeDataType::Float, 1, "a_halo_blur"},
|
||||
};
|
||||
const std::array<UniformBlockInfo, 6>
|
||||
ShaderSource<BuiltIn::SymbolTextAndIconShader, gfx::Backend::Type::Metal>::uniforms = {
|
||||
UniformBlockInfo{9, true, true, sizeof(SymbolDrawableUBO), "SymbolDrawableUBO"},
|
||||
UniformBlockInfo{10, true, false, sizeof(SymbolDrawablePaintUBO), "SymbolDrawablePaintUBO"},
|
||||
UniformBlockInfo{11, true, true, sizeof(SymbolDrawableTilePropsUBO), "SymbolDrawableTilePropsUBO"},
|
||||
UniformBlockInfo{12, true, false, sizeof(SymbolDrawableInterpolateUBO), "SymbolDrawableInterpolateUBO"},
|
||||
UniformBlockInfo{13, true, true, sizeof(SymbolPermutationUBO), "SymbolPermutationUBO"},
|
||||
UniformBlockInfo{14, true, false, sizeof(ExpressionInputsUBO), "ExpressionInputsUBO"},
|
||||
};
|
||||
const std::array<TextureInfo, 2> ShaderSource<BuiltIn::SymbolTextAndIconShader, gfx::Backend::Type::Metal>::textures = {
|
||||
TextureInfo{0, "u_texture"},
|
||||
TextureInfo{1, "u_texture_icon"},
|
||||
};
|
||||
|
||||
} // namespace shaders
|
||||
} // namespace mbgl
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <mbgl/util/ignore.hpp>
|
||||
|
||||
#include <functional>
|
||||
#include <type_traits>
|
||||
|
||||
namespace mbgl {
|
||||
namespace util {
|
||||
@@ -19,5 +20,24 @@ std::size_t hash(Args&&... args) {
|
||||
return seed;
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
template <typename TIter>
|
||||
using TIterVal = std::enable_if_t<std::is_integral<typename TIter::value_type>::value, typename TIter::value_type>;
|
||||
} // namespace detail
|
||||
|
||||
/// Generate a hash key from a collection of integer values which doesn't depend on their order.
|
||||
/// Adapted from https://stackoverflow.com/a/76993810/135138
|
||||
/// Default factor prime value from 64-bit FNV hash.
|
||||
template <typename TIter, typename TKey = detail::TIterVal<TIter>, TKey factor = 1099511628211LL>
|
||||
TKey order_independent_hash(TIter cur, const TIter end) {
|
||||
detail::TIterVal<TIter> sum = 0, product = 1;
|
||||
for (; cur != end; ++cur) {
|
||||
const auto& value = *cur;
|
||||
sum += value;
|
||||
product *= (1 + value) * factor;
|
||||
}
|
||||
return sum ^ product;
|
||||
}
|
||||
|
||||
} // namespace util
|
||||
} // namespace mbgl
|
||||
|
||||
@@ -88,6 +88,7 @@ add_library(
|
||||
${PROJECT_SOURCE_DIR}/test/util/dtoa.test.cpp
|
||||
${PROJECT_SOURCE_DIR}/test/util/geo.test.cpp
|
||||
${PROJECT_SOURCE_DIR}/test/util/grid_index.test.cpp
|
||||
${PROJECT_SOURCE_DIR}/test/util/hash.test.cpp
|
||||
${PROJECT_SOURCE_DIR}/test/util/http_timeout.test.cpp
|
||||
${PROJECT_SOURCE_DIR}/test/util/image.test.cpp
|
||||
${PROJECT_SOURCE_DIR}/test/util/mapbox.test.cpp
|
||||
@@ -128,6 +129,7 @@ if(MLN_WITH_OPENGL)
|
||||
PRIVATE
|
||||
${PROJECT_SOURCE_DIR}/test/api/custom_layer.test.cpp
|
||||
${PROJECT_SOURCE_DIR}/test/gl/bucket.test.cpp
|
||||
${PROJECT_SOURCE_DIR}/test/gl/enum.test.cpp
|
||||
${PROJECT_SOURCE_DIR}/test/gl/context.test.cpp
|
||||
${PROJECT_SOURCE_DIR}/test/gl/gl_functions.test.cpp
|
||||
${PROJECT_SOURCE_DIR}/test/gl/object.test.cpp
|
||||
@@ -236,4 +238,4 @@ if (CMAKE_SYSTEM_NAME STREQUAL Linux)
|
||||
mbgl-test
|
||||
PRIVATE USE_CPP_TEST_SERVER
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <mbgl/map/map.hpp>
|
||||
#include <mbgl/map/map_options.hpp>
|
||||
#include <mbgl/platform/gl_functions.hpp>
|
||||
#include <mbgl/renderer/renderer.hpp>
|
||||
#include <mbgl/storage/resource_options.hpp>
|
||||
#include <mbgl/style/layers/background_layer.hpp>
|
||||
#include <mbgl/style/layers/fill_layer.hpp>
|
||||
@@ -114,6 +115,9 @@ TEST(GLContextMode, Shared) {
|
||||
MBGL_CHECK_ERROR(glEnableVertexAttribArray(paintShader.a_pos));
|
||||
MBGL_CHECK_ERROR(glVertexAttribPointer(paintShader.a_pos, 2, GL_FLOAT, GL_FALSE, 0, nullptr));
|
||||
MBGL_CHECK_ERROR(glDrawArrays(GL_TRIANGLE_STRIP, 0, 3));
|
||||
|
||||
frontend.getRenderer()->reduceMemoryUse();
|
||||
ASSERT_TRUE(static_cast<gl::Context&>(frontend.getBackend()->getContext()).empty());
|
||||
}
|
||||
|
||||
test::checkImage("test/fixtures/shared_context", frontend.render(map).image, 0.5, 0.1);
|
||||
|
||||
178
test/gl/enum.test.cpp
Normal file
178
test/gl/enum.test.cpp
Normal file
@@ -0,0 +1,178 @@
|
||||
#include <mbgl/gfx/gfx_types.hpp>
|
||||
#include <mbgl/gfx/types.hpp>
|
||||
#include <mbgl/gl/defines.hpp>
|
||||
#include <mbgl/gl/enum.hpp>
|
||||
#include <mbgl/test/util.hpp>
|
||||
|
||||
using namespace mbgl;
|
||||
using namespace mbgl::gfx;
|
||||
using namespace mbgl::gl;
|
||||
|
||||
TEST(GL, DrawModeType) {
|
||||
ASSERT_EQ(GL_POINTS, Enum<DrawModeType>::to(DrawModeType::Points));
|
||||
ASSERT_EQ(GL_LINES, Enum<DrawModeType>::to(DrawModeType::Lines));
|
||||
ASSERT_EQ(GL_LINE_LOOP, Enum<DrawModeType>::to(DrawModeType::LineLoop));
|
||||
ASSERT_EQ(GL_LINE_STRIP, Enum<DrawModeType>::to(DrawModeType::LineStrip));
|
||||
ASSERT_EQ(GL_TRIANGLES, Enum<DrawModeType>::to(DrawModeType::Triangles));
|
||||
ASSERT_EQ(GL_TRIANGLE_STRIP, Enum<DrawModeType>::to(DrawModeType::TriangleStrip));
|
||||
ASSERT_EQ(GL_TRIANGLE_FAN, Enum<DrawModeType>::to(DrawModeType::TriangleFan));
|
||||
ASSERT_EQ(GL_INVALID_ENUM, Enum<DrawModeType>::to(static_cast<DrawModeType>(-1)));
|
||||
}
|
||||
|
||||
namespace {
|
||||
template <typename T>
|
||||
auto enumIdentity(T x) {
|
||||
return Enum<T>::from(Enum<T>::to(x));
|
||||
}
|
||||
} // namespace
|
||||
|
||||
TEST(GL, ColorBlendEquationType) {
|
||||
// const auto identity = [](auto x){ return Enum<ColorBlendEquationType>::from(Enum<ColorBlendEquationType>::to(x));
|
||||
// };
|
||||
ASSERT_EQ(ColorBlendEquationType::Add, enumIdentity(ColorBlendEquationType::Add));
|
||||
ASSERT_EQ(ColorBlendEquationType::Subtract, enumIdentity(ColorBlendEquationType::Subtract));
|
||||
ASSERT_EQ(ColorBlendEquationType::ReverseSubtract, enumIdentity(ColorBlendEquationType::ReverseSubtract));
|
||||
|
||||
ASSERT_EQ(GL_INVALID_ENUM, Enum<ColorBlendEquationType>::to(static_cast<ColorBlendEquationType>(-1)));
|
||||
ASSERT_EQ(ColorBlendEquationType{}, Enum<ColorBlendEquationType>::from(GL_RGBA8));
|
||||
}
|
||||
|
||||
TEST(GL, ColorBlendFactorType) {
|
||||
ASSERT_EQ(ColorBlendFactorType::Zero, enumIdentity(ColorBlendFactorType::Zero));
|
||||
ASSERT_EQ(ColorBlendFactorType::One, enumIdentity(ColorBlendFactorType::One));
|
||||
ASSERT_EQ(ColorBlendFactorType::SrcColor, enumIdentity(ColorBlendFactorType::SrcColor));
|
||||
ASSERT_EQ(ColorBlendFactorType::OneMinusSrcColor, enumIdentity(ColorBlendFactorType::OneMinusSrcColor));
|
||||
ASSERT_EQ(ColorBlendFactorType::DstColor, enumIdentity(ColorBlendFactorType::DstColor));
|
||||
ASSERT_EQ(ColorBlendFactorType::OneMinusDstColor, enumIdentity(ColorBlendFactorType::OneMinusDstColor));
|
||||
ASSERT_EQ(ColorBlendFactorType::SrcAlpha, enumIdentity(ColorBlendFactorType::SrcAlpha));
|
||||
ASSERT_EQ(ColorBlendFactorType::OneMinusSrcAlpha, enumIdentity(ColorBlendFactorType::OneMinusSrcAlpha));
|
||||
ASSERT_EQ(ColorBlendFactorType::DstAlpha, enumIdentity(ColorBlendFactorType::DstAlpha));
|
||||
ASSERT_EQ(ColorBlendFactorType::OneMinusDstAlpha, enumIdentity(ColorBlendFactorType::OneMinusDstAlpha));
|
||||
ASSERT_EQ(ColorBlendFactorType::ConstantColor, enumIdentity(ColorBlendFactorType::ConstantColor));
|
||||
ASSERT_EQ(ColorBlendFactorType::OneMinusConstantColor, enumIdentity(ColorBlendFactorType::OneMinusConstantColor));
|
||||
ASSERT_EQ(ColorBlendFactorType::ConstantAlpha, enumIdentity(ColorBlendFactorType::ConstantAlpha));
|
||||
ASSERT_EQ(ColorBlendFactorType::OneMinusConstantAlpha, enumIdentity(ColorBlendFactorType::OneMinusConstantAlpha));
|
||||
ASSERT_EQ(ColorBlendFactorType::SrcAlphaSaturate, enumIdentity(ColorBlendFactorType::SrcAlphaSaturate));
|
||||
|
||||
ASSERT_EQ(GL_INVALID_ENUM, Enum<ColorBlendFactorType>::to(static_cast<ColorBlendFactorType>(-1)));
|
||||
ASSERT_EQ(ColorBlendFactorType{}, Enum<ColorBlendFactorType>::from(GL_RGBA8));
|
||||
}
|
||||
|
||||
TEST(GL, DepthFunctionType) {
|
||||
ASSERT_EQ(DepthFunctionType::Never, enumIdentity(DepthFunctionType::Never));
|
||||
ASSERT_EQ(DepthFunctionType::Less, enumIdentity(DepthFunctionType::Less));
|
||||
ASSERT_EQ(DepthFunctionType::Equal, enumIdentity(DepthFunctionType::Equal));
|
||||
ASSERT_EQ(DepthFunctionType::LessEqual, enumIdentity(DepthFunctionType::LessEqual));
|
||||
ASSERT_EQ(DepthFunctionType::Greater, enumIdentity(DepthFunctionType::Greater));
|
||||
ASSERT_EQ(DepthFunctionType::NotEqual, enumIdentity(DepthFunctionType::NotEqual));
|
||||
ASSERT_EQ(DepthFunctionType::GreaterEqual, enumIdentity(DepthFunctionType::GreaterEqual));
|
||||
ASSERT_EQ(DepthFunctionType::Always, enumIdentity(DepthFunctionType::Always));
|
||||
|
||||
ASSERT_EQ(GL_INVALID_ENUM, Enum<DepthFunctionType>::to(static_cast<DepthFunctionType>(-1)));
|
||||
ASSERT_EQ(DepthFunctionType{}, Enum<DepthFunctionType>::from(GL_RGBA8));
|
||||
}
|
||||
|
||||
TEST(GL, DepthMaskType) {
|
||||
ASSERT_EQ(DepthMaskType::ReadOnly, enumIdentity(DepthMaskType::ReadOnly));
|
||||
ASSERT_EQ(DepthMaskType::ReadWrite, enumIdentity(DepthMaskType::ReadWrite));
|
||||
|
||||
// anything non-zero is true, there's no way to represent invalid
|
||||
ASSERT_EQ(GL_TRUE, Enum<DepthMaskType>::to(static_cast<DepthMaskType>(-1)));
|
||||
}
|
||||
|
||||
TEST(GL, StencilFunctionType) {
|
||||
ASSERT_EQ(StencilFunctionType::Never, enumIdentity(StencilFunctionType::Never));
|
||||
ASSERT_EQ(StencilFunctionType::Less, enumIdentity(StencilFunctionType::Less));
|
||||
ASSERT_EQ(StencilFunctionType::Equal, enumIdentity(StencilFunctionType::Equal));
|
||||
ASSERT_EQ(StencilFunctionType::LessEqual, enumIdentity(StencilFunctionType::LessEqual));
|
||||
ASSERT_EQ(StencilFunctionType::Greater, enumIdentity(StencilFunctionType::Greater));
|
||||
ASSERT_EQ(StencilFunctionType::NotEqual, enumIdentity(StencilFunctionType::NotEqual));
|
||||
ASSERT_EQ(StencilFunctionType::GreaterEqual, enumIdentity(StencilFunctionType::GreaterEqual));
|
||||
ASSERT_EQ(StencilFunctionType::Always, enumIdentity(StencilFunctionType::Always));
|
||||
|
||||
ASSERT_EQ(GL_INVALID_ENUM, Enum<StencilFunctionType>::to(static_cast<StencilFunctionType>(-1)));
|
||||
ASSERT_EQ(StencilFunctionType{}, Enum<StencilFunctionType>::from(GL_RGBA8));
|
||||
}
|
||||
|
||||
TEST(GL, StencilOpType) {
|
||||
ASSERT_EQ(StencilOpType::Keep, enumIdentity(StencilOpType::Keep));
|
||||
ASSERT_EQ(StencilOpType::Zero, enumIdentity(StencilOpType::Zero));
|
||||
ASSERT_EQ(StencilOpType::Replace, enumIdentity(StencilOpType::Replace));
|
||||
ASSERT_EQ(StencilOpType::Increment, enumIdentity(StencilOpType::Increment));
|
||||
ASSERT_EQ(StencilOpType::IncrementWrap, enumIdentity(StencilOpType::IncrementWrap));
|
||||
ASSERT_EQ(StencilOpType::Decrement, enumIdentity(StencilOpType::Decrement));
|
||||
ASSERT_EQ(StencilOpType::DecrementWrap, enumIdentity(StencilOpType::DecrementWrap));
|
||||
ASSERT_EQ(StencilOpType::Invert, enumIdentity(StencilOpType::Invert));
|
||||
|
||||
ASSERT_EQ(GL_INVALID_ENUM, Enum<StencilOpType>::to(static_cast<StencilOpType>(-1)));
|
||||
ASSERT_EQ(StencilOpType{}, Enum<StencilOpType>::from(GL_RGBA8));
|
||||
}
|
||||
|
||||
TEST(GL, CullFaceSideType) {
|
||||
ASSERT_EQ(CullFaceSideType::Front, enumIdentity(CullFaceSideType::Front));
|
||||
ASSERT_EQ(CullFaceSideType::Back, enumIdentity(CullFaceSideType::Back));
|
||||
ASSERT_EQ(CullFaceSideType::FrontAndBack, enumIdentity(CullFaceSideType::FrontAndBack));
|
||||
|
||||
ASSERT_EQ(GL_INVALID_ENUM, Enum<CullFaceSideType>::to(static_cast<CullFaceSideType>(-1)));
|
||||
ASSERT_EQ(CullFaceSideType{}, Enum<CullFaceSideType>::from(GL_RGBA8));
|
||||
}
|
||||
|
||||
TEST(GL, CullFaceWindingType) {
|
||||
ASSERT_EQ(CullFaceWindingType::Clockwise, enumIdentity(CullFaceWindingType::Clockwise));
|
||||
ASSERT_EQ(CullFaceWindingType::CounterClockwise, enumIdentity(CullFaceWindingType::CounterClockwise));
|
||||
|
||||
ASSERT_EQ(GL_INVALID_ENUM, Enum<CullFaceWindingType>::to(static_cast<CullFaceWindingType>(-1)));
|
||||
ASSERT_EQ(CullFaceWindingType{}, Enum<CullFaceWindingType>::from(GL_RGBA8));
|
||||
}
|
||||
|
||||
TEST(GL, BufferUsageType) {
|
||||
ASSERT_EQ(BufferUsageType::StreamDraw, enumIdentity(BufferUsageType::StreamDraw));
|
||||
ASSERT_EQ(BufferUsageType::StaticDraw, enumIdentity(BufferUsageType::StaticDraw));
|
||||
ASSERT_EQ(BufferUsageType::DynamicDraw, enumIdentity(BufferUsageType::DynamicDraw));
|
||||
|
||||
ASSERT_EQ(GL_INVALID_ENUM, Enum<BufferUsageType>::to(static_cast<BufferUsageType>(-1)));
|
||||
ASSERT_EQ(BufferUsageType{}, Enum<BufferUsageType>::from(GL_RGBA8));
|
||||
}
|
||||
|
||||
TEST(GL, TexturePixelType) {
|
||||
ASSERT_EQ(TexturePixelType::RGBA, enumIdentity(TexturePixelType::RGBA));
|
||||
ASSERT_EQ(TexturePixelType::Alpha, enumIdentity(TexturePixelType::Alpha));
|
||||
ASSERT_EQ(TexturePixelType::Stencil, enumIdentity(TexturePixelType::Stencil));
|
||||
ASSERT_EQ(TexturePixelType::Depth, enumIdentity(TexturePixelType::Depth));
|
||||
ASSERT_EQ(TexturePixelType::Luminance, enumIdentity(TexturePixelType::Luminance));
|
||||
|
||||
ASSERT_EQ(GL_INVALID_ENUM, Enum<TexturePixelType>::to(static_cast<TexturePixelType>(-1)));
|
||||
ASSERT_EQ(TexturePixelType{}, Enum<TexturePixelType>::from(GL_RGBA8));
|
||||
}
|
||||
|
||||
TEST(GL, TextureChannelDataType) {
|
||||
ASSERT_EQ(TextureChannelDataType::UnsignedByte, enumIdentity(TextureChannelDataType::UnsignedByte));
|
||||
ASSERT_EQ(TextureChannelDataType::HalfFloat, enumIdentity(TextureChannelDataType::HalfFloat));
|
||||
ASSERT_EQ(TextureChannelDataType::Float, enumIdentity(TextureChannelDataType::Float));
|
||||
|
||||
ASSERT_EQ(GL_INVALID_ENUM, Enum<TextureChannelDataType>::to(static_cast<TextureChannelDataType>(-1)));
|
||||
ASSERT_EQ(TextureChannelDataType{}, Enum<TextureChannelDataType>::from(GL_RGBA8));
|
||||
}
|
||||
|
||||
TEST(GL, RenderbufferPixelType) {
|
||||
ASSERT_EQ(RenderbufferPixelType::RGBA, enumIdentity(RenderbufferPixelType::RGBA));
|
||||
ASSERT_EQ(RenderbufferPixelType::Depth, enumIdentity(RenderbufferPixelType::Depth));
|
||||
ASSERT_EQ(RenderbufferPixelType::DepthStencil, enumIdentity(RenderbufferPixelType::DepthStencil));
|
||||
|
||||
ASSERT_EQ(GL_INVALID_ENUM, Enum<RenderbufferPixelType>::to(static_cast<RenderbufferPixelType>(-1)));
|
||||
ASSERT_EQ(RenderbufferPixelType{}, Enum<RenderbufferPixelType>::from(GL_RGBA8));
|
||||
}
|
||||
|
||||
TEST(GL, sizedFor) {
|
||||
ASSERT_EQ(GL_RGBA,
|
||||
Enum<gfx::TexturePixelType>::sizedFor(TexturePixelType::RGBA, TextureChannelDataType::UnsignedByte));
|
||||
ASSERT_EQ(GL_RGBA16F,
|
||||
Enum<gfx::TexturePixelType>::sizedFor(TexturePixelType::RGBA, TextureChannelDataType::HalfFloat));
|
||||
ASSERT_EQ(GL_INVALID_ENUM,
|
||||
Enum<gfx::TexturePixelType>::sizedFor(TexturePixelType::Alpha, TextureChannelDataType::HalfFloat));
|
||||
ASSERT_EQ(GL_RGBA32F, Enum<gfx::TexturePixelType>::sizedFor(TexturePixelType::RGBA, TextureChannelDataType::Float));
|
||||
ASSERT_EQ(GL_INVALID_ENUM,
|
||||
Enum<gfx::TexturePixelType>::sizedFor(TexturePixelType::Alpha, TextureChannelDataType::Float));
|
||||
ASSERT_EQ(GL_INVALID_ENUM,
|
||||
Enum<gfx::TexturePixelType>::sizedFor(TexturePixelType::RGBA, static_cast<TextureChannelDataType>(-1)));
|
||||
}
|
||||
@@ -207,7 +207,11 @@ TEST(ShaderRegistry, NamedReplace) {
|
||||
}
|
||||
|
||||
// Test replacing an actual program instance with a similar instance
|
||||
#if MLN_LEGACY_RENDERER
|
||||
TEST(ShaderRegistry, GLSLReplacement_NoOp) {
|
||||
#else
|
||||
TEST(ShaderRegistry, DISABLED_GLSLReplacement_NoOp) {
|
||||
#endif
|
||||
MapInstance::ShaderAndStyleObserver observer;
|
||||
util::RunLoop runLoop;
|
||||
auto map = MapInstance(1.0f, observer);
|
||||
@@ -233,7 +237,11 @@ TEST(ShaderRegistry, DISABLED_GLSLReplacement_NoOp) {
|
||||
|
||||
// Test replacing an actual program with a similar instance using a different
|
||||
// fragment shader
|
||||
#if MLN_LEGACY_RENDERER
|
||||
TEST(ShaderRegistry, GLSLReplacement1) {
|
||||
#else
|
||||
TEST(ShaderRegistry, DISABLED_GLSLReplacement1) {
|
||||
#endif
|
||||
MapInstance::ShaderAndStyleObserver observer;
|
||||
util::RunLoop runLoop;
|
||||
auto map = MapInstance(1.0f, observer);
|
||||
@@ -267,7 +275,11 @@ void main() {
|
||||
|
||||
// Test replacing an actual program with a similar instance using a different
|
||||
// fragment shader
|
||||
#if MLN_LEGACY_RENDERER
|
||||
TEST(ShaderRegistry, GLSLReplacement2) {
|
||||
#else
|
||||
TEST(ShaderRegistry, DISABLED_GLSLReplacement2) {
|
||||
#endif
|
||||
MapInstance::ShaderAndStyleObserver observer;
|
||||
util::RunLoop runLoop;
|
||||
auto map = MapInstance(1.0f, observer);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user