Issue/1687 (#1697)

Co-authored-by: Bart Louwers <bart@emeel.net>
Co-authored-by: mwilsnd <mwilsnd@gmail.com>
This commit is contained in:
Tim Sylvester
2023-09-28 11:18:42 -07:00
committed by GitHub
parent 2d8cde8abf
commit 810be67fa2
94 changed files with 1467 additions and 1043 deletions

View File

@@ -1019,6 +1019,23 @@ 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/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 = [

View File

@@ -18,8 +18,11 @@ namespace mbgl {
class Color;
class PaintParameters;
class LayerTweaker;
enum class RenderPass : uint8_t;
using LayerTweakerPtr = std::shared_ptr<LayerTweaker>;
namespace gfx {
class ColorMode;
@@ -234,6 +237,10 @@ public:
/// Get drawable user-defined type
size_t getType() const { return type; }
/// Associate the drawable with a layer tweaker. This is used to manage the lifetime of the tweaker.
void setLayerTweaker(LayerTweakerPtr tweaker) { layerTweaker = std::move(tweaker); }
const LayerTweakerPtr& getLayerTweaker() const { return layerTweaker; }
protected:
bool enabled = true;
bool enableColor = true;
@@ -257,6 +264,7 @@ protected:
Textures textures;
std::vector<DrawableTweakerPtr> tweakers;
LayerTweakerPtr layerTweaker;
std::size_t type = 0;
};

View File

@@ -145,6 +145,9 @@ public:
/// @param location A sampler location in the shader being used.
void setTexture(const gfx::Texture2DPtr&, int32_t location);
/// Direct access to the current texture set
const gfx::Drawable::Textures& getTextures() const { return textures; }
/// Add a tweaker to emitted drawable
void addTweaker(DrawableTweakerPtr value) { tweakers.emplace_back(std::move(value)); }
@@ -225,5 +228,7 @@ protected:
std::unique_ptr<Impl> impl;
};
using UniqueDrawableBuilder = std::unique_ptr<DrawableBuilder>;
} // namespace gfx
} // namespace mbgl

View File

@@ -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 {};
}

View File

@@ -11,6 +11,7 @@
#include <memory>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <variant>
#include <vector>
@@ -364,9 +365,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) {
@@ -377,15 +384,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());
@@ -402,15 +408,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
@@ -435,7 +439,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

View File

@@ -13,6 +13,7 @@ namespace mbgl {
class LayerGroupBase;
class PaintParameters;
class RenderOrchestrator;
class RenderTree;
class TileLayerGroup;
using LayerGroupBasePtr = std::shared_ptr<LayerGroupBase>;
@@ -28,6 +29,7 @@ using UniqueDrawable = std::unique_ptr<Drawable>;
class LayerTweaker;
using LayerTweakerPtr = std::shared_ptr<LayerTweaker>;
using LayerTweakerWeakPtr = std::weak_ptr<LayerTweaker>;
/**
A layer-like group of drawables, not a group of layers.
@@ -86,16 +88,16 @@ public:
/// @return The number of items removed
virtual std::size_t removeDrawablesIf(const std::function<bool(gfx::Drawable&)>&& f) = 0;
/// Attach a tweaker to be run on this layer group for each frame
void setLayerTweaker(LayerTweakerPtr tweaker) { layerTweaker = std::move(tweaker); }
/// Attach a tweaker to be run on this layer group for each frame.
/// Tweaker lifetime is controlled by the render layer and drawables, the layer group retains a weak reference.
void addLayerTweaker(const LayerTweakerPtr& tweaker) { layerTweakers.emplace_back(tweaker); }
/// Get the tweaker attached to this layer group
const LayerTweakerPtr& getLayerTweaker() const { return layerTweaker; }
void runTweakers(const RenderTree&, PaintParameters&);
protected:
bool enabled = true;
int32_t layerIndex;
LayerTweakerPtr layerTweaker;
std::vector<LayerTweakerWeakPtr> layerTweakers;
std::string name;
};

View File

@@ -1,25 +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;
@@ -27,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
@@ -45,16 +52,20 @@ public:
/// Build the common expression inupts UBO
static shaders::ExpressionInputsUBO buildExpressionUBO(double zoom, uint64_t frameCount);
/// @brief Check whether a property name exists within the previously set collection.
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`.
void setPropertiesAsUniforms(std::vector<std::string>);
/// @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;
#endif // MLN_RENDER_BACKEND_METAL
void setPropertiesAsUniforms(const std::unordered_set<StringIdentity>&);
void enableOverdrawInspector(bool);
@@ -63,6 +74,9 @@ public:
void updateProperties(Immutable<style::LayerProperties>);
protected:
/// Determine whether this tweaker should apply to the given drawable
bool checkTweakDrawable(const gfx::Drawable&) const;
/// Calculate matrices for this tile.
/// @param nearClipped If true, the near plane is moved further to enhance depth buffer precision.
/// @param inViewportPixelUnits If false, the translation is scaled based on the current zoom.
@@ -78,14 +92,15 @@ protected:
protected:
std::string id;
Immutable<style::LayerProperties> evaluatedProperties;
bool propertiesUpdated = true;
#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
bool propertiesUpdated = true;
bool propertiesChanged = true;
bool overdrawInspector = false;
};

View File

@@ -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;
};

View File

@@ -5,8 +5,6 @@
#include <array>
#include <cstdint>
#define MLN_STRINGIZE(X) #X
namespace mbgl {
namespace shaders {

View File

@@ -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>

View File

@@ -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

View File

@@ -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"(

View File

@@ -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>

View File

@@ -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 {

View File

@@ -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"(

View File

@@ -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 {

View File

@@ -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"(
)";

View File

@@ -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"(

View File

@@ -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 {

View File

@@ -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"(

View File

@@ -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 {

View File

@@ -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"(

View File

@@ -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 {

View File

@@ -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 {

View File

@@ -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);

View File

@@ -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 {

View File

@@ -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 {

View File

@@ -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 {

View File

@@ -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

View File

@@ -11,7 +11,7 @@
namespace mbgl {
using StringIdentity = size_t;
using StringIdentity = std::size_t;
class StringIndexer {
public:

View File

@@ -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)) {}

View File

@@ -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) {

View File

@@ -122,9 +122,11 @@ void DrawableGL::bindUniformBuffers() const {
const auto& uniformBuffer = getUniformBuffers().get(element.first);
if (!uniformBuffer) {
using namespace std::string_literals;
const auto tileID = getTileID() ? util::toString(*getTileID()) : "<no tile>";
Log::Error(Event::General,
"DrawableGL::bindUniformBuffers: UBO "s + std::string(StringIndexer::get(element.first)) +
" not found. skipping.");
"bindUniformBuffers: UBO "s + std::string(StringIndexer::get(element.first)) +
" not found for " + util::toString(getID()) + " / " + getName() + " / " + tileID +
". skipping.");
assert(false);
continue;
}

View File

@@ -43,6 +43,7 @@ void DrawableGLBuilder::init() {
impl->buildIndexes.clear();
impl->segments.clear();
impl->vertices.clear();
textures.clear();
}
} // namespace gl

View File

@@ -103,7 +103,8 @@ void TileLayerGroupGL::render(RenderOrchestrator&, PaintParameters& parameters)
#if !defined(NDEBUG)
std::string label_tile;
if (const auto& tileID = drawable.getTileID()) {
label_tile = drawable.getName() + "/" + util::toString(*tileID);
label_tile = util::toString(drawable.getID().id()) + "/" + drawable.getName() + "/" +
util::toString(*tileID);
}
const auto labelPtr = (label_tile.empty() ? drawable.getName() : label_tile).c_str();
const auto debugGroupTile = parameters.encoder->createDebugGroup(labelPtr);

View File

@@ -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) {

View File

@@ -377,9 +377,11 @@ void Drawable::bindUniformBuffers(const RenderPass& renderPass) const {
const auto& uniformBuffer = getUniformBuffers().get(element.first);
if (!uniformBuffer) {
using namespace std::string_literals;
const auto tileID = getTileID() ? util::toString(*getTileID()) : "<no tile>";
const auto tileLabel = util::toString(getID()) + "/" + getName() + "/" + tileID;
Log::Error(Event::General,
"Drawable::bindUniformBuffers: UBO "s + StringIndexer::get(element.first) +
" not found. skipping.");
"bindUniformBuffers: UBO "s + StringIndexer::get(element.first) + " not found on " +
tileLabel + ". skipping.");
assert(false);
continue;
}

View File

@@ -43,6 +43,7 @@ void DrawableBuilder::init() {
impl->buildIndexes.clear();
impl->segments.clear();
impl->vertices.clear();
textures.clear();
}
} // namespace mtl

View File

@@ -2,8 +2,10 @@
#include <mbgl/gfx/upload_pass.hpp>
#include <mbgl/gfx/drawable_tweaker.hpp>
#include <mbgl/renderer/layer_tweaker.hpp>
#include <mbgl/renderer/paint_parameters.hpp>
#include <mbgl/renderer/render_orchestrator.hpp>
#include <mbgl/renderer/render_tree.hpp>
#include <set>
@@ -16,6 +18,17 @@ void LayerGroupBase::addDrawable(gfx::UniqueDrawable& drawable) {
}
}
void LayerGroupBase::runTweakers(const RenderTree& renderTree, PaintParameters& parameters) {
for (auto it = layerTweakers.begin(); it != layerTweakers.end();) {
if (auto tweaker = it->lock()) {
tweaker->execute(*this, renderTree, parameters);
++it;
} else {
it = layerTweakers.erase(it);
}
}
}
struct LayerGroup::Impl {
using DrawableCollection = std::set<gfx::UniqueDrawable, gfx::DrawableLessByPriority>;
DrawableCollection drawables;

View File

@@ -19,6 +19,12 @@ LayerTweaker::LayerTweaker(std::string id_, Immutable<style::LayerProperties> pr
: id(std::move(id_)),
evaluatedProperties(std::move(properties)) {}
bool LayerTweaker::checkTweakDrawable(const gfx::Drawable& drawable) const {
// Apply to a drawable if it references us, or if doesn't reference anything.
const auto& tweaker = drawable.getLayerTweaker();
return !tweaker || tweaker.get() == this;
}
mat4 LayerTweaker::getTileMatrix(const UnwrappedTileID& tileID,
const RenderTree& renderTree,
const TransformState& state,
@@ -60,27 +66,25 @@ shaders::ExpressionInputsUBO LayerTweaker::buildExpressionUBO(double zoom, uint6
0};
}
void LayerTweaker::setPropertiesAsUniforms(std::vector<std::string> props) {
if (props != propertiesAsUniforms) {
propertiesAsUniforms = std::move(props);
propertiesChanged = true;
}
}
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;
propertiesChanged = true;
}
#endif
}
void LayerTweaker::enableOverdrawInspector(bool value) {
if (overdrawInspector != value) {
overdrawInspector = value;

View File

@@ -54,6 +54,9 @@ void BackgroundLayerTweaker::execute(LayerGroupBase& layerGroup, const RenderTre
std::optional<uint32_t> samplerLocation{};
layerGroup.visitDrawables([&](gfx::Drawable& drawable) {
assert(drawable.getTileID());
if (!drawable.getTileID() || !checkTweakDrawable(drawable)) {
return;
}
// We assume that drawables don't change between pattern and non-pattern.
const auto& shader = drawable.getShader();

View File

@@ -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 (propertiesChanged) {
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,
@@ -114,16 +109,16 @@ void CircleLayerTweaker::execute(LayerGroupBase& layerGroup,
}
layerGroup.visitDrawables([&](gfx::Drawable& drawable) {
auto& uniforms = drawable.mutableUniformBuffers();
uniforms.addOrReplace(idCirclePaintParamsUBOName, paintParamsUniformBuffer);
uniforms.addOrReplace(idCircleEvaluatedPropsUBOName, evaluatedPropsUniformBuffer);
if (!drawable.getTileID()) {
assert(!"Circles only render with tiles");
assert(drawable.getTileID() || !"Circles only render with tiles");
if (!drawable.getTileID() || !checkTweakDrawable(drawable)) {
return;
}
const UnwrappedTileID tileID = drawable.getTileID()->toUnwrapped();
auto& uniforms = drawable.mutableUniformBuffers();
uniforms.addOrReplace(idCirclePaintParamsUBOName, paintParamsUniformBuffer);
uniforms.addOrReplace(idCircleEvaluatedPropsUBOName, evaluatedPropsUniformBuffer);
const auto& translation = evaluated.get<CircleTranslate>();
const auto anchor = evaluated.get<CircleTranslateAnchor>();
constexpr bool inViewportPixelUnits = false; // from RenderTile::translatedMatrix

View File

@@ -50,7 +50,7 @@ void CollisionLayerTweaker::execute(LayerGroupBase& layerGroup,
#endif
layerGroup.visitDrawables([&](gfx::Drawable& drawable) {
if (!drawable.getTileID() || !drawable.getData()) {
if (!drawable.getTileID() || !drawable.getData() || !checkTweakDrawable(drawable)) {
return;
}

View File

@@ -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 (propertiesChanged) {
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,
@@ -102,15 +106,15 @@ void FillExtrusionLayerTweaker::execute(LayerGroupBase& layerGroup,
#endif
layerGroup.visitDrawables([&](gfx::Drawable& drawable) {
auto& uniforms = drawable.mutableUniformBuffers();
uniforms.addOrReplace(idFillExtrusionDrawablePropsUBOName, propsBuffer);
if (!drawable.getTileID()) {
if (!drawable.getTileID() || !checkTweakDrawable(drawable)) {
return;
}
const UnwrappedTileID tileID = drawable.getTileID()->toUnwrapped();
auto& uniforms = drawable.mutableUniformBuffers();
uniforms.addOrReplace(idFillExtrusionDrawablePropsUBOName, propsBuffer);
const auto& translation = evaluated.get<FillExtrusionTranslate>();
const auto anchor = evaluated.get<FillExtrusionTranslateAnchor>();
constexpr bool inViewportPixelUnits = false; // from RenderTile::translatedMatrix

View File

@@ -77,12 +77,6 @@ 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
bool fillUniformBufferUpdated = false;
bool fillOutlineUniformBufferUpdated = false;
bool fillPatternUniformBufferUpdated = false;
@@ -92,11 +86,10 @@ void FillLayerTweaker::execute(LayerGroupBase& layerGroup,
if (fillUniformBufferUpdated) return;
#if MLN_RENDER_BACKEND_METAL
using ShaderClass = ShaderSource<BuiltIn::FillShader, gfx::Backend::Type::Metal>;
if (propertiesChanged || !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,
@@ -131,11 +124,11 @@ void FillLayerTweaker::execute(LayerGroupBase& layerGroup,
if (fillOutlineUniformBufferUpdated) return;
#if MLN_RENDER_BACKEND_METAL
using ShaderClass = ShaderSource<BuiltIn::FillOutlineShader, gfx::Backend::Type::Metal>;
if (propertiesChanged || !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,
@@ -172,12 +165,14 @@ void FillLayerTweaker::execute(LayerGroupBase& layerGroup,
if (fillPatternUniformBufferUpdated) return;
#if MLN_RENDER_BACKEND_METAL
using ShaderClass = ShaderSource<BuiltIn::FillOutlinePatternShader, gfx::Backend::Type::Metal>;
if (propertiesChanged || !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::FillOutlinePatternShader>(1),
/*.expression=*/{}},
/* .pattern_to = */
{/*.source=*/getAttributeSource<BuiltIn::FillOutlinePatternShader>(2), /*.expression=*/{}},
/* .opacity = */
{/*.source=*/getAttributeSource<BuiltIn::FillOutlinePatternShader>(3), /*.expression=*/{}},
/* .overdrawInspector = */ overdrawInspector,
0,
0,
@@ -211,12 +206,14 @@ void FillLayerTweaker::execute(LayerGroupBase& layerGroup,
if (fillOutlinePatternUniformBufferUpdated) return;
#if MLN_RENDER_BACKEND_METAL
using ShaderClass = ShaderSource<BuiltIn::FillOutlinePatternShader, gfx::Backend::Type::Metal>;
if (propertiesChanged || !fillOutlinePermutationUniformBuffer) {
if (propertiesChanged || !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,
@@ -255,6 +252,10 @@ void FillLayerTweaker::execute(LayerGroupBase& layerGroup,
#endif
layerGroup.visitDrawables([&](gfx::Drawable& drawable) {
if (!drawable.getTileID() || !checkTweakDrawable(drawable)) {
return;
}
auto& uniforms = drawable.mutableUniformBuffers();
// auto& drawableType = drawable.getShader()->typeName();
@@ -287,9 +288,6 @@ void FillLayerTweaker::execute(LayerGroupBase& layerGroup,
}
}
}
if (!drawable.getTileID()) {
return;
}
if (uniforms.get(idFillInterpolateUBOName)) {
UpdateFillUniformBuffers();

View File

@@ -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 (propertiesChanged) {
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,
@@ -85,13 +80,15 @@ void HeatmapLayerTweaker::execute(LayerGroupBase& layerGroup,
}
layerGroup.visitDrawables([&](gfx::Drawable& drawable) {
if (!drawable.getTileID() || !checkTweakDrawable(drawable)) {
return;
}
const UnwrappedTileID tileID = drawable.getTileID()->toUnwrapped();
auto& uniforms = drawable.mutableUniformBuffers();
uniforms.addOrReplace(idHeatmapEvaluatedPropsUBOName, evaluatedPropsUniformBuffer);
if (!drawable.getTileID()) {
return;
}
const UnwrappedTileID tileID = drawable.getTileID()->toUnwrapped();
constexpr bool nearClipped = false;
constexpr bool inViewportPixelUnits = false;
const auto matrix = getTileMatrix(tileID,

View File

@@ -33,6 +33,10 @@ void HeatmapTextureLayerTweaker::execute(LayerGroupBase& layerGroup,
#endif
layerGroup.visitDrawables([&](gfx::Drawable& drawable) {
if (!checkTweakDrawable(drawable)) {
return;
}
const auto& size = parameters.staticData.backendSize;
mat4 viewportMat;
matrix::ortho(viewportMat, 0, size.width, size.height, 0, -1, 1);

View File

@@ -55,12 +55,14 @@ void HillshadeLayerTweaker::execute(LayerGroupBase& layerGroup,
}
layerGroup.visitDrawables([&](gfx::Drawable& drawable) {
drawable.mutableUniformBuffers().addOrReplace(idHillshadeEvaluatedPropsUBOName, evaluatedPropsUniformBuffer);
if (!drawable.getTileID()) {
if (!drawable.getTileID() || !checkTweakDrawable(drawable)) {
return;
}
const UnwrappedTileID tileID = drawable.getTileID()->toUnwrapped();
drawable.mutableUniformBuffers().addOrReplace(idHillshadeEvaluatedPropsUBOName, evaluatedPropsUniformBuffer);
const auto matrix = getTileMatrix(
tileID, renderTree, parameters.state, {0.f, 0.f}, TranslateAnchorType::Viewport, false, false, true);
HillshadeDrawableUBO drawableUBO = {/* .matrix = */ util::cast<float>(matrix),

View File

@@ -42,7 +42,7 @@ void HillshadePrepareLayerTweaker::execute(LayerGroupBase& layerGroup,
#endif
layerGroup.visitDrawables([&](gfx::Drawable& drawable) {
if (!drawable.getTileID() || !drawable.getData()) {
if (!drawable.getTileID() || !drawable.getData() || !checkTweakDrawable(drawable)) {
return;
}
const UnwrappedTileID tileID = drawable.getTileID()->toUnwrapped();
@@ -52,7 +52,7 @@ void HillshadePrepareLayerTweaker::execute(LayerGroupBase& layerGroup,
matrix::ortho(matrix, 0, util::EXTENT, -util::EXTENT, 0, -1, 1);
matrix::translate(matrix, matrix, 0, -util::EXTENT, 0);
HillshadePrepareDrawableUBO drawableUBO = {
const HillshadePrepareDrawableUBO drawableUBO = {
/* .matrix = */ util::cast<float>(matrix),
/* .unpack = */ getUnpackVector(drawableData.encoding),
/* .dimension = */ {static_cast<float>(drawableData.stride), static_cast<float>(drawableData.stride)},

View File

@@ -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 (propertiesChanged) {
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=*/{}},
@@ -149,7 +144,7 @@ void LineLayerTweaker::execute(LayerGroupBase& layerGroup,
layerGroup.visitDrawables([&](gfx::Drawable& drawable) {
const auto shader = drawable.getShader();
if (!drawable.getTileID() || !shader) {
if (!drawable.getTileID() || !shader || !checkTweakDrawable(drawable)) {
return;
}

View File

@@ -25,6 +25,10 @@ void RasterLayerTweaker::execute([[maybe_unused]] LayerGroupBase& layerGroup,
const auto& evaluated = static_cast<const RasterLayerProperties&>(*evaluatedProperties).evaluated;
layerGroup.visitDrawables([&](gfx::Drawable& drawable) {
if (!checkTweakDrawable(drawable)) {
return;
}
const auto spinWeights = [](float spin) -> std::array<float, 4> {
spin = util::deg2radf(spin);
const float s = std::sin(spin);

View File

@@ -3,7 +3,6 @@
#include <mbgl/gfx/cull_face_mode.hpp>
#include <mbgl/map/transform_state.hpp>
#include <mbgl/programs/programs.hpp>
#include <mbgl/renderer/bucket.hpp>
#include <mbgl/renderer/image_manager.hpp>
#include <mbgl/renderer/paint_parameters.hpp>
#include <mbgl/renderer/pattern_atlas.hpp>
@@ -67,7 +66,8 @@ void RenderBackgroundLayer::evaluate(const PropertyEvaluationParameters& paramet
#if MLN_DRAWABLE_RENDERER
if (layerGroup) {
layerGroup->setLayerTweaker(std::make_shared<BackgroundLayerTweaker>(getID(), evaluatedProperties));
auto newTweaker = std::make_shared<BackgroundLayerTweaker>(getID(), evaluatedProperties);
replaceTweaker(layerTweaker, std::move(newTweaker), {layerGroup});
}
#endif
}
@@ -250,12 +250,18 @@ void RenderBackgroundLayer::update(gfx::ShaderRegistry& shaders,
if (!layerGroup) {
if (auto layerGroup_ = context.createTileLayerGroup(layerIndex, /*initialCapacity=*/64, getID())) {
layerGroup_->setLayerTweaker(std::make_shared<BackgroundLayerTweaker>(getID(), evaluatedProperties));
setLayerGroup(std::move(layerGroup_), changes);
} else {
return;
}
}
auto* tileLayerGroup = static_cast<TileLayerGroup*>(layerGroup.get());
if (!layerTweaker) {
layerTweaker = std::make_shared<BackgroundLayerTweaker>(getID(), evaluatedProperties);
layerGroup->addLayerTweaker(layerTweaker);
}
if (!hasPattern && !plainShader) {
plainShader = context.getGenericShader(shaders, std::string(BackgroundPlainShaderName));
}
@@ -312,6 +318,7 @@ void RenderBackgroundLayer::update(gfx::ShaderRegistry& shaders,
for (auto& drawable : builder->clearDrawables()) {
drawable->setTileID(tileID);
drawable->setLayerTweaker(layerTweaker);
tileLayerGroup->addDrawable(drawPasses, tileID, std::move(drawable));
++stats.drawablesAdded;
}

View File

@@ -93,7 +93,10 @@ void RenderCircleLayer::evaluate(const PropertyEvaluationParameters& parameters)
evaluatedProperties = std::move(properties);
#if MLN_DRAWABLE_RENDERER
updateLayerTweaker();
if (layerGroup) {
auto newTweaker = std::make_shared<CircleLayerTweaker>(getID(), evaluatedProperties);
replaceTweaker(layerTweaker, std::move(newTweaker), {layerGroup});
}
#endif // MLN_DRAWABLE_RENDERER
}
@@ -276,19 +279,6 @@ static const StringIdentity idVertexAttribName = StringIndexer::get("a_pos");
using namespace shaders;
#if MLN_DRAWABLE_RENDERER
void RenderCircleLayer::updateLayerTweaker() {
if (layerGroup) {
tweaker = std::make_shared<CircleLayerTweaker>(getID(), evaluatedProperties);
#if MLN_RENDER_BACKEND_METAL
tweaker->setPropertiesAsUniforms(propertiesAsUniforms);
#endif // MLN_RENDER_BACKEND_METAL
tweaker->enableOverdrawInspector(overdrawInspector);
layerGroup->setLayerTweaker(tweaker);
}
}
#endif // MLN_DRAWABLE_RENDERER
void RenderCircleLayer::update(gfx::ShaderRegistry& shaders,
gfx::Context& context,
const TransformState& state,
@@ -305,12 +295,19 @@ void RenderCircleLayer::update(gfx::ShaderRegistry& shaders,
// Set up a layer group
if (!layerGroup) {
if (auto layerGroup_ = context.createTileLayerGroup(layerIndex, /*initialCapacity=*/64, getID())) {
layerGroup_->setLayerTweaker(std::make_shared<CircleLayerTweaker>(getID(), evaluatedProperties));
setLayerGroup(std::move(layerGroup_), changes);
} else {
return;
}
}
auto* tileLayerGroup = static_cast<TileLayerGroup*>(layerGroup.get());
if (!layerTweaker) {
layerTweaker = std::make_shared<CircleLayerTweaker>(getID(), evaluatedProperties);
layerGroup->addLayerTweaker(layerTweaker);
}
layerTweaker->enableOverdrawInspector(!!(updateParameters->debugOptions & MapDebugOptions::Overdraw));
if (!circleShaderGroup) {
circleShaderGroup = shaders.getShaderGroup(CircleShaderGroupName);
}
@@ -319,14 +316,6 @@ void RenderCircleLayer::update(gfx::ShaderRegistry& shaders,
return;
}
const bool overdraw = !!(updateParameters->debugOptions & MapDebugOptions::Overdraw);
if (overdrawInspector != overdraw) {
overdrawInspector = overdraw;
if (tweaker) {
tweaker->enableOverdrawInspector(overdrawInspector);
}
}
std::unique_ptr<gfx::DrawableBuilder> circleBuilder;
constexpr auto renderPass = RenderPass::Translucent;
@@ -338,6 +327,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();
@@ -375,6 +365,11 @@ void RenderCircleLayer::update(gfx::ShaderRegistry& shaders,
// If there are already drawables for this tile, update their UBOs and move on to the next tile.
auto updateExisting = [&](gfx::Drawable& drawable) {
if (drawable.getLayerTweaker() != layerTweaker) {
// This drawable was produced on a previous style/bucket, and should not be updated.
return;
}
auto& uniforms = drawable.mutableUniformBuffers();
uniforms.createOrUpdate(idCircleInterpolateUBOName, &interpolateUBO, context);
};
@@ -384,30 +379,28 @@ 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;
}
const auto circleShader = circleShaderGroup->getOrCreateShader(context, propertiesAsUniforms_);
const auto circleShader = circleShaderGroup->getOrCreateShader(context, propertiesAsUniforms);
if (!circleShader) {
continue;
}
#if MLN_RENDER_BACKEND_METAL
propertiesAsUniforms = std::move(propertiesAsUniforms_);
if (tweaker) {
tweaker->setPropertiesAsUniforms(propertiesAsUniforms);
if (layerTweaker) {
layerTweaker->setPropertiesAsUniforms(propertiesAsUniforms);
}
#endif // MLN_RENDER_BACKEND_METAL
if (const auto& attr = circleVertexAttrs.add(idVertexAttribName)) {
attr->setSharedRawData(bucket.sharedVertices,
@@ -434,6 +427,7 @@ void RenderCircleLayer::update(gfx::ShaderRegistry& shaders,
for (auto& drawable : circleBuilder->clearDrawables()) {
drawable->setTileID(tileID);
drawable->setLayerTweaker(layerTweaker);
auto& uniforms = drawable->mutableUniformBuffers();
uniforms.addOrReplace(idCircleInterpolateUBOName, interpBuffer);

View File

@@ -49,10 +49,6 @@ private:
void render(PaintParameters&) override;
#endif // MLN_LEGACY_RENDERER
#if MLN_DRAWABLE_RENDERER
void updateLayerTweaker();
#endif // MLN_DRAWABLE_RENDERER
private:
// Paint properties
style::CirclePaintProperties::Unevaluated unevaluated;
@@ -64,13 +60,6 @@ private:
#if MLN_DRAWABLE_RENDERER
gfx::ShaderGroupPtr circleShaderGroup;
CircleLayerTweakerPtr tweaker;
#if MLN_RENDER_BACKEND_METAL
std::vector<std::string> propertiesAsUniforms;
#endif // MLN_RENDER_BACKEND_METAL
bool overdrawInspector = false;
#endif
};

View File

@@ -26,6 +26,7 @@
#include <mbgl/gfx/drawable_builder.hpp>
#include <mbgl/renderer/layer_group.hpp>
#include <mbgl/renderer/layers/fill_extrusion_layer_tweaker.hpp>
#include <mbgl/renderer/update_parameters.hpp>
#include <mbgl/shaders/fill_extrusion_layer_ubo.hpp>
#include <mbgl/shaders/shader_program_base.hpp>
#endif // MLN_DRAWABLE_RENDERER
@@ -75,7 +76,8 @@ void RenderFillExtrusionLayer::evaluate(const PropertyEvaluationParameters& para
#if MLN_DRAWABLE_RENDERER
if (layerGroup) {
layerGroup->setLayerTweaker(std::make_shared<FillExtrusionLayerTweaker>(getID(), evaluatedProperties));
auto newTweaker = std::make_shared<FillExtrusionLayerTweaker>(getID(), evaluatedProperties);
replaceTweaker(layerTweaker, std::move(newTweaker), {layerGroup});
}
#endif // MLN_DRAWABLE_RENDERER
}
@@ -275,7 +277,7 @@ bool RenderFillExtrusionLayer::queryIntersectsFeature(const GeometryCoordinates&
void RenderFillExtrusionLayer::update(gfx::ShaderRegistry& shaders,
gfx::Context& context,
const TransformState& state,
const std::shared_ptr<UpdateParameters>&,
const std::shared_ptr<UpdateParameters>& updateParameters,
const RenderTree& /*renderTree*/,
UniqueChangeRequestVec& changes) {
if (!renderTiles || renderTiles->empty() || passes == RenderPass::None) {
@@ -286,11 +288,19 @@ void RenderFillExtrusionLayer::update(gfx::ShaderRegistry& shaders,
// Set up a layer group
if (!layerGroup) {
if (auto layerGroup_ = context.createTileLayerGroup(layerIndex, /*initialCapacity=*/64, getID())) {
layerGroup_->setLayerTweaker(std::make_shared<FillExtrusionLayerTweaker>(getID(), evaluatedProperties));
setLayerGroup(std::move(layerGroup_), changes);
} else {
return;
}
}
if (!layerTweaker) {
layerTweaker = std::make_shared<FillExtrusionLayerTweaker>(getID(), evaluatedProperties);
layerGroup->addLayerTweaker(layerTweaker);
}
layerTweaker->enableOverdrawInspector(!!(updateParameters->debugOptions & MapDebugOptions::Overdraw));
if (!fillExtrusionGroup) {
fillExtrusionGroup = shaders.getShaderGroup("FillExtrusionShader");
}
@@ -331,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();
@@ -388,6 +399,11 @@ void RenderFillExtrusionLayer::update(gfx::ShaderRegistry& shaders,
if (tileLayerGroup->getDrawableCount(drawPass, tileID) > 0) {
// Just update the drawables we already created
tileLayerGroup->visitDrawables(drawPass, tileID, [&](gfx::Drawable& drawable) {
if (drawable.getLayerTweaker() != layerTweaker) {
// This drawable was produced on a previous style/bucket, and should not be updated.
return;
}
auto& uniforms = drawable.mutableUniformBuffers();
uniforms.createOrUpdate(
FillExtrusionLayerTweaker::idFillExtrusionTilePropsUBOName, &tilePropsUBO, context);
@@ -398,20 +414,25 @@ void RenderFillExtrusionLayer::update(gfx::ShaderRegistry& shaders,
}
gfx::VertexAttributeArray vertexAttrs;
const auto uniformProps = vertexAttrs.readDataDrivenPaintProperties<FillExtrusionBase,
FillExtrusionColor,
FillExtrusionHeight,
FillExtrusionPattern>(binders, evaluated);
propertiesAsUniforms.clear();
vertexAttrs.readDataDrivenPaintProperties<FillExtrusionBase,
FillExtrusionColor,
FillExtrusionHeight,
FillExtrusionPattern>(binders, evaluated, propertiesAsUniforms);
if (!shaderGroup) {
continue;
}
const auto shader = std::static_pointer_cast<gfx::ShaderProgramBase>(
shaderGroup->getOrCreateShader(context, uniformProps));
shaderGroup->getOrCreateShader(context, propertiesAsUniforms));
if (!shader) {
continue;
}
if (layerTweaker) {
layerTweaker->setPropertiesAsUniforms(propertiesAsUniforms);
}
// The non-pattern path in `render()` only uses two-pass rendering if there's translucency.
// The pattern path always uses two passes.
const auto doDepthPass = (!opaque || hasPattern);
@@ -501,6 +522,7 @@ void RenderFillExtrusionLayer::update(gfx::ShaderRegistry& shaders,
for (auto& drawable : builder.clearDrawables()) {
drawable->setTileID(tileID);
drawable->setLayerTweaker(layerTweaker);
auto& uniforms = drawable->mutableUniformBuffers();
uniforms.createOrUpdate(

View File

@@ -104,9 +104,9 @@ void RenderFillLayer::evaluate(const PropertyEvaluationParameters& parameters) {
#if MLN_DRAWABLE_RENDERER
if (layerGroup) {
layerGroup->setLayerTweaker(std::make_shared<FillLayerTweaker>(getID(), evaluatedProperties));
auto newTweaker = std::make_shared<FillLayerTweaker>(getID(), evaluatedProperties);
replaceTweaker(layerTweaker, std::move(newTweaker), {layerGroup});
}
updateLayerTweaker();
#endif
}
@@ -308,17 +308,6 @@ bool RenderFillLayer::queryIntersectsFeature(const GeometryCoordinates& queryGeo
#if MLN_DRAWABLE_RENDERER
void RenderFillLayer::updateLayerTweaker() {
if (layerGroup) {
tweaker = std::make_shared<FillLayerTweaker>(getID(), evaluatedProperties);
#if MLN_RENDER_BACKEND_METAL
tweaker->setPropertiesAsUniforms(propertiesAsUniforms);
#endif // MLN_RENDER_BACKEND_METAL
tweaker->enableOverdrawInspector(overdrawInspector);
layerGroup->setLayerTweaker(tweaker);
}
}
void RenderFillLayer::update(gfx::ShaderRegistry& shaders,
gfx::Context& context,
const TransformState& state,
@@ -332,24 +321,22 @@ void RenderFillLayer::update(gfx::ShaderRegistry& shaders,
return;
}
const bool overdraw = !!(updateParameters->debugOptions & MapDebugOptions::Overdraw);
if (overdrawInspector != overdraw) {
overdrawInspector = overdraw;
if (tweaker) {
tweaker->enableOverdrawInspector(overdrawInspector);
}
}
// Set up a layer group
if (!layerGroup) {
if (auto layerGroup_ = context.createTileLayerGroup(layerIndex, /*initialCapacity=*/64, getID())) {
layerGroup_->setLayerTweaker(std::make_shared<FillLayerTweaker>(getID(), evaluatedProperties));
setLayerGroup(std::move(layerGroup_), changes);
updateLayerTweaker();
} else {
return;
}
}
auto* tileLayerGroup = static_cast<TileLayerGroup*>(layerGroup.get());
if (!layerTweaker) {
layerTweaker = std::make_shared<FillLayerTweaker>(getID(), evaluatedProperties);
layerGroup->addLayerTweaker(layerTweaker);
}
layerTweaker->enableOverdrawInspector(!!(updateParameters->debugOptions & MapDebugOptions::Overdraw));
if (!fillShaderGroup) {
fillShaderGroup = shaders.getShaderGroup(std::string(FillShaderName));
}
@@ -373,7 +360,7 @@ void RenderFillLayer::update(gfx::ShaderRegistry& shaders,
std::unique_ptr<gfx::DrawableBuilder> outlinePatternBuilder;
const auto layerPrefix = getID() + "/";
const auto renderPass = RenderPass::Translucent;
constexpr auto renderPass = RenderPass::Translucent;
const auto commonInit = [&](gfx::DrawableBuilder& builder) {
builder.setCullFaceMode(gfx::CullFaceMode::disabled());
@@ -383,12 +370,10 @@ void RenderFillLayer::update(gfx::ShaderRegistry& shaders,
stats.drawablesRemoved += tileLayerGroup->removeDrawablesIf([&](gfx::Drawable& drawable) {
// If the render pass has changed or the tile has dropped out of the cover set, remove it.
const auto& tileID = drawable.getTileID();
if (tileID && !hasRenderTile(*tileID)) {
return true;
}
return false;
return tileID && !hasRenderTile(*tileID);
});
std::unordered_set<StringIdentity> propertiesAsUniforms;
for (const RenderTile& tile : *renderTiles) {
const auto& tileID = tile.getOverscaledTileID();
@@ -519,9 +504,13 @@ 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);
}
const auto vertexCount = bucket.vertices.elements();
if (const auto& attr = vertexAttrs.add(idPosAttribName)) {
@@ -534,6 +523,11 @@ void RenderFillLayer::update(gfx::ShaderRegistry& shaders,
// If we already have drawables for this tile, update them.
auto updateExisting = [&](gfx::Drawable& drawable) {
if (drawable.getLayerTweaker() != layerTweaker) {
// This drawable was produced on a previous style/bucket, and should not be updated.
return;
}
auto& uniforms = drawable.mutableUniformBuffers();
if (uniforms.get(FillLayerTweaker::idFillInterpolateUBOName)) {
uniforms.createOrUpdate(FillLayerTweaker::idFillInterpolateUBOName, &getFillInterpolateUBO(), context);
@@ -566,19 +560,12 @@ void RenderFillLayer::update(gfx::ShaderRegistry& shaders,
continue;
}
const auto fillShader = std::static_pointer_cast<gfx::ShaderProgramBase>(
fillShaderGroup->getOrCreateShader(context, propertiesAsUniforms_));
fillShaderGroup->getOrCreateShader(context, propertiesAsUniforms));
const auto outlineShader = doOutline
? std::static_pointer_cast<gfx::ShaderProgramBase>(
outlineShaderGroup->getOrCreateShader(context, propertiesAsUniforms_))
outlineShaderGroup->getOrCreateShader(context, propertiesAsUniforms))
: nullptr;
#if MLN_RENDER_BACKEND_METAL
propertiesAsUniforms = std::move(propertiesAsUniforms_);
if (tweaker) {
tweaker->setPropertiesAsUniforms(propertiesAsUniforms);
}
#endif // MLN_RENDER_BACKEND_METAL
if (!fillBuilder && fillShader) {
if (auto builder = context.createDrawableBuilder(layerPrefix + "fill")) {
commonInit(*builder);
@@ -610,6 +597,8 @@ void RenderFillLayer::update(gfx::ShaderRegistry& shaders,
for (auto& drawable : builder.clearDrawables()) {
drawable->setTileID(tileID);
drawable->setLayerTweaker(layerTweaker);
auto& uniforms = drawable->mutableUniformBuffers();
uniforms.createOrUpdate(interpolateUBONameId, &interpolateUBO, context);
tileLayerGroup->addDrawable(renderPass, tileID, std::move(drawable));
@@ -653,19 +642,12 @@ void RenderFillLayer::update(gfx::ShaderRegistry& shaders,
}
const auto fillShader = std::static_pointer_cast<gfx::ShaderProgramBase>(
patternShaderGroup->getOrCreateShader(context, propertiesAsUniforms_));
patternShaderGroup->getOrCreateShader(context, propertiesAsUniforms));
const auto outlineShader = doOutline ? std::static_pointer_cast<gfx::ShaderProgramBase>(
outlinePatternShaderGroup->getOrCreateShader(
context, propertiesAsUniforms_))
context, propertiesAsUniforms))
: nullptr;
#if MLN_RENDER_BACKEND_METAL
propertiesAsUniforms = std::move(propertiesAsUniforms_);
if (tweaker) {
tweaker->setPropertiesAsUniforms(propertiesAsUniforms);
}
#endif // MLN_RENDER_BACKEND_METAL
if (!patternBuilder) {
if (auto builder = context.createDrawableBuilder(layerPrefix + "fill-pattern")) {
commonInit(*builder);
@@ -708,6 +690,8 @@ void RenderFillLayer::update(gfx::ShaderRegistry& shaders,
for (auto& drawable : builder.clearDrawables()) {
drawable->setTileID(tileID);
drawable->setLayerTweaker(layerTweaker);
auto& uniforms = drawable->mutableUniformBuffers();
uniforms.createOrUpdate(interpolateNameId, &interpolateUBO, context);
uniforms.createOrUpdate(tileUBONameId, &tileUBO, context);

View File

@@ -46,10 +46,6 @@ private:
void render(PaintParameters&) override;
#endif
#if MLN_DRAWABLE_RENDERER
void updateLayerTweaker();
#endif // MLN_DRAWABLE_RENDERER
bool queryIntersectsFeature(const GeometryCoordinates&,
const GeometryTileFeature&,
float,
@@ -73,13 +69,6 @@ private:
gfx::ShaderGroupPtr outlineShaderGroup;
gfx::ShaderGroupPtr patternShaderGroup;
gfx::ShaderGroupPtr outlinePatternShaderGroup;
FillLayerTweakerPtr tweaker;
#if MLN_RENDER_BACKEND_METAL
std::vector<std::string> propertiesAsUniforms;
#endif // MLN_RENDER_BACKEND_METAL
bool overdrawInspector = false;
#endif
};

View File

@@ -70,8 +70,17 @@ void RenderHeatmapLayer::evaluate(const PropertyEvaluationParameters& parameters
evaluatedProperties = std::move(properties);
#if MLN_DRAWABLE_RENDERER
updateLayerTweaker();
updateLayerTextureTweaker();
if (layerGroup) {
auto newTextureTweaker = std::make_shared<HeatmapTextureLayerTweaker>(getID(), evaluatedProperties);
replaceTweaker(textureTweaker, std::move(newTextureTweaker), {layerGroup});
}
if (renderTarget) {
if (auto tileLayerGroup = renderTarget->getLayerGroup(0)) {
auto newTweaker = std::make_shared<HeatmapLayerTweaker>(getID(), evaluatedProperties);
replaceTweaker(layerTweaker, std::move(newTweaker), {std::move(tileLayerGroup)});
}
}
#endif
}
@@ -247,17 +256,24 @@ void RenderHeatmapLayer::markLayerRenderable(bool willRender, UniqueChangeReques
activateRenderTarget(renderTarget, willRender, changes);
}
void RenderHeatmapLayer::removeTile(RenderPass renderPass, const OverscaledTileID& tileID) {
auto* tileLayerGroup = static_cast<TileLayerGroup*>(renderTarget->getLayerGroup(0).get());
stats.drawablesRemoved += tileLayerGroup->removeDrawables(renderPass, tileID).size();
std::size_t RenderHeatmapLayer::removeTile(RenderPass renderPass, const OverscaledTileID& tileID) {
if (auto* tileLayerGroup = static_cast<TileLayerGroup*>(renderTarget->getLayerGroup(0).get())) {
const auto count = tileLayerGroup->removeDrawables(renderPass, tileID).size();
stats.drawablesRemoved += count;
return count;
}
return 0;
}
void RenderHeatmapLayer::removeAllDrawables() {
RenderLayer::removeAllDrawables();
std::size_t RenderHeatmapLayer::removeAllDrawables() {
auto removed = RenderLayer::removeAllDrawables();
if (renderTarget) {
stats.drawablesRemoved += renderTarget->getLayerGroup(0)->getDrawableCount();
const auto count = renderTarget->getLayerGroup(0)->getDrawableCount();
removed += count;
stats.drawablesRemoved += count;
renderTarget->getLayerGroup(0)->clearDrawables();
}
return removed;
}
namespace {
@@ -273,27 +289,6 @@ static const StringIdentity idTexColorRampName = StringIndexer::get("u_color_ram
using namespace shaders;
#if MLN_DRAWABLE_RENDERER
void RenderHeatmapLayer::updateLayerTweaker() {
if (renderTarget) {
tweaker = std::make_shared<HeatmapLayerTweaker>(getID(), evaluatedProperties);
#if MLN_RENDER_BACKEND_METAL
tweaker->setPropertiesAsUniforms(propertiesAsUniforms);
#endif // MLN_RENDER_BACKEND_METAL
tweaker->enableOverdrawInspector(overdrawInspector);
renderTarget->getLayerGroup(0)->setLayerTweaker(tweaker);
}
}
void RenderHeatmapLayer::updateLayerTextureTweaker() {
if (layerGroup) {
textureTweaker = std::make_shared<HeatmapTextureLayerTweaker>(getID(), evaluatedProperties);
textureTweaker->enableOverdrawInspector(overdrawInspector);
layerGroup->setLayerTweaker(textureTweaker);
}
}
#endif // MLN_DRAWABLE_RENDERER
void RenderHeatmapLayer::update(gfx::ShaderRegistry& shaders,
gfx::Context& context,
const TransformState& state,
@@ -324,7 +319,7 @@ void RenderHeatmapLayer::update(gfx::ShaderRegistry& shaders,
return;
}
renderTarget->addLayerGroup(tileLayerGroup, /*replace=*/true);
updateLayerTweaker();
textureTweaker.reset();
}
if (renderTarget->getTexture()->getSize() != size) {
@@ -341,14 +336,11 @@ void RenderHeatmapLayer::update(gfx::ShaderRegistry& shaders,
return;
}
const bool overdraw = !!(updateParameters->debugOptions & MapDebugOptions::Overdraw);
if (overdrawInspector != overdraw) {
overdrawInspector = overdraw;
if (tweaker) {
tweaker->enableOverdrawInspector(overdrawInspector);
textureTweaker->enableOverdrawInspector(overdrawInspector);
}
if (!layerTweaker) {
layerTweaker = std::make_shared<HeatmapLayerTweaker>(getID(), evaluatedProperties);
tileLayerGroup->addLayerTweaker(layerTweaker);
}
layerTweaker->enableOverdrawInspector(!!(updateParameters->debugOptions & MapDebugOptions::Overdraw));
std::unique_ptr<gfx::DrawableBuilder> heatmapBuilder;
constexpr auto renderPass = RenderPass::Translucent;
@@ -361,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,6 +382,10 @@ void RenderHeatmapLayer::update(gfx::ShaderRegistry& shaders,
/* .padding = */ {0}};
tileLayerGroup->visitDrawables(renderPass, tileID, [&](gfx::Drawable& drawable) {
if (drawable.getLayerTweaker() != layerTweaker) {
// This drawable was produced on a previous style/bucket, and should not be updated.
return;
}
drawable.mutableUniformBuffers().createOrUpdate(idHeatmapInterpolateUBOName, &interpolateUBO, context);
});
@@ -397,25 +394,18 @@ void RenderHeatmapLayer::update(gfx::ShaderRegistry& shaders,
}
gfx::VertexAttributeArray heatmapVertexAttrs;
propertiesAsUniforms.clear();
heatmapVertexAttrs.readDataDrivenPaintProperties<HeatmapWeight, HeatmapRadius>(
paintPropertyBinders, evaluated, propertiesAsUniforms);
const auto propertiesAsUniforms_ =
heatmapVertexAttrs.readDataDrivenPaintProperties<HeatmapWeight, HeatmapRadius>(paintPropertyBinders,
evaluated);
if (!heatmapShaderGroup) {
continue;
}
const auto heatmapShader = heatmapShaderGroup->getOrCreateShader(context, propertiesAsUniforms_);
const auto heatmapShader = heatmapShaderGroup->getOrCreateShader(context, propertiesAsUniforms);
if (!heatmapShader) {
continue;
}
#if MLN_RENDER_BACKEND_METAL
propertiesAsUniforms = std::move(propertiesAsUniforms_);
if (tweaker) {
tweaker->setPropertiesAsUniforms(propertiesAsUniforms);
if (layerTweaker) {
layerTweaker->setPropertiesAsUniforms(propertiesAsUniforms);
}
#endif // MLN_RENDER_BACKEND_METAL
if (const auto& attr = heatmapVertexAttrs.add(idVertexAttribName)) {
attr->setSharedRawData(bucket.sharedVertices,
@@ -441,6 +431,8 @@ void RenderHeatmapLayer::update(gfx::ShaderRegistry& shaders,
for (auto& drawable : heatmapBuilder->clearDrawables()) {
drawable->setTileID(tileID);
drawable->setLayerTweaker(layerTweaker);
drawable->mutableUniformBuffers().createOrUpdate(idHeatmapInterpolateUBOName, &interpolateUBO, context);
tileLayerGroup->addDrawable(renderPass, tileID, std::move(drawable));
@@ -450,13 +442,20 @@ void RenderHeatmapLayer::update(gfx::ShaderRegistry& shaders,
// Set up texture layer group
if (!layerGroup) {
auto layerGroup_ = context.createLayerGroup(layerIndex, /*initialCapacity=*/1, getID());
if (!layerGroup_) {
if (auto layerGroup_ = context.createLayerGroup(layerIndex, /*initialCapacity=*/1, getID())) {
if (textureTweaker) {
layerGroup_->addLayerTweaker(textureTweaker);
}
setLayerGroup(std::move(layerGroup_), changes);
} else {
return;
}
setLayerGroup(std::move(layerGroup_), changes);
updateLayerTextureTweaker();
}
if (!textureTweaker) {
textureTweaker = std::make_shared<HeatmapTextureLayerTweaker>(getID(), evaluatedProperties);
layerGroup->addLayerTweaker(textureTweaker);
}
textureTweaker->enableOverdrawInspector(!!(updateParameters->debugOptions & MapDebugOptions::Overdraw));
if (!heatmapTextureShader) {
heatmapTextureShader = context.getGenericShader(shaders, HeatmapTextureShaderGroupName);
@@ -467,6 +466,7 @@ void RenderHeatmapLayer::update(gfx::ShaderRegistry& shaders,
}
auto* textureLayerGroup = static_cast<LayerGroup*>(layerGroup.get());
// TODO: Don't rebuild drawables every time
textureLayerGroup->clearDrawables();
std::unique_ptr<gfx::DrawableBuilder> heatmapTextureBuilder;
@@ -516,6 +516,7 @@ void RenderHeatmapLayer::update(gfx::ShaderRegistry& shaders,
heatmapTextureBuilder->flush();
for (auto& drawable : heatmapTextureBuilder->clearDrawables()) {
drawable->setLayerTweaker(textureTweaker);
textureLayerGroup->addDrawable(std::move(drawable));
++stats.drawablesAdded;
}

View File

@@ -47,11 +47,6 @@ private:
void render(PaintParameters&) override;
#endif
#if MLN_DRAWABLE_RENDERER
void updateLayerTweaker();
void updateLayerTextureTweaker();
#endif // MLN_DRAWABLE_RENDERER
bool queryIntersectsFeature(const GeometryCoordinates&,
const GeometryTileFeature&,
float,
@@ -63,10 +58,12 @@ private:
#if MLN_DRAWABLE_RENDERER
/// Remove all drawables for the tile from the layer group
void removeTile(RenderPass, const OverscaledTileID&) override;
/// @return The number of drawables actually removed.
std::size_t removeTile(RenderPass, const OverscaledTileID&) override;
/// Remove all the drawables for tiles
void removeAllDrawables() override;
/// @return The number of drawables actually removed.
std::size_t removeAllDrawables() override;
#endif
// Paint properties
@@ -90,13 +87,9 @@ private:
using TextureVertexVector = gfx::VertexVector<HeatmapTextureLayoutVertex>;
std::shared_ptr<TextureVertexVector> sharedTextureVertices;
HeatmapLayerTweakerPtr tweaker;
HeatmapTextureLayerTweakerPtr textureTweaker;
#if MLN_RENDER_BACKEND_METAL
std::vector<std::string> propertiesAsUniforms;
#endif // MLN_RENDER_BACKEND_METAL
bool overdrawInspector = false;
// This is the layer tweaker for applying the off-screen texture to the framebuffer.
// The inherited layer tweaker is for applying tiles to the off-screen texture.
LayerTweakerPtr textureTweaker;
#endif
};

View File

@@ -73,7 +73,26 @@ void RenderHillshadeLayer::evaluate(const PropertyEvaluationParameters& paramete
properties->renderPasses = mbgl::underlying_type(passes);
evaluatedProperties = std::move(properties);
#if MLN_DRAWABLE_RENDERER
updateLayerTweaker();
if (layerGroup) {
auto newTweaker = std::make_shared<HillshadeLayerTweaker>(getID(), evaluatedProperties);
replaceTweaker(layerTweaker, std::move(newTweaker), {layerGroup});
}
if (!activatedRenderTargets.empty()) {
auto newTweaker2 = std::make_shared<HillshadePrepareLayerTweaker>(getID(), evaluatedProperties);
std::vector<LayerGroupBasePtr> groups;
for (const auto& target : activatedRenderTargets) {
if (const auto& group = target->getLayerGroup(0)) {
groups.push_back(group);
}
}
if (groups.empty()) {
prepareLayerTweaker = newTweaker2;
} else {
replaceTweaker(prepareLayerTweaker, std::move(newTweaker2), groups);
}
}
#endif
}
@@ -284,16 +303,6 @@ static const StringIdentity idPosAttribName = StringIndexer::get("a_pos");
static const StringIdentity idTexturePosAttribName = StringIndexer::get("a_texture_pos");
static const StringIdentity idTexImageName = StringIndexer::get("u_image");
#if MLN_DRAWABLE_RENDERER
void RenderHillshadeLayer::updateLayerTweaker() {
if (layerGroup) {
tweaker = std::make_shared<HillshadeLayerTweaker>(getID(), evaluatedProperties);
tweaker->enableOverdrawInspector(overdrawInspector);
layerGroup->setLayerTweaker(tweaker);
}
}
#endif // MLN_DRAWABLE_RENDERER
void RenderHillshadeLayer::update(gfx::ShaderRegistry& shaders,
gfx::Context& context,
[[maybe_unused]] const TransformState& state,
@@ -309,16 +318,21 @@ void RenderHillshadeLayer::update(gfx::ShaderRegistry& shaders,
// Set up a layer group
if (!layerGroup) {
auto layerGroup_ = context.createTileLayerGroup(layerIndex, /*initialCapacity=*/64, getID());
if (!layerGroup_) {
if (auto layerGroup_ = context.createTileLayerGroup(layerIndex, /*initialCapacity=*/64, getID())) {
setLayerGroup(std::move(layerGroup_), changes);
} else {
return;
}
setLayerGroup(std::move(layerGroup_), changes);
updateLayerTweaker();
}
auto* tileLayerGroup = static_cast<TileLayerGroup*>(layerGroup.get());
if (!layerTweaker) {
layerTweaker = std::make_shared<HillshadeLayerTweaker>(getID(), evaluatedProperties);
layerGroup->addLayerTweaker(layerTweaker);
}
layerTweaker->enableOverdrawInspector(!!(updateParameters->debugOptions & MapDebugOptions::Overdraw));
if (!hillshadePrepareShader) {
hillshadePrepareShader = context.getGenericShader(shaders, HillshadePrepareShaderGroupName);
}
@@ -330,14 +344,6 @@ void RenderHillshadeLayer::update(gfx::ShaderRegistry& shaders,
return;
}
const bool overdraw = !!(updateParameters->debugOptions & MapDebugOptions::Overdraw);
if (overdrawInspector != overdraw) {
overdrawInspector = overdraw;
if (tweaker) {
tweaker->enableOverdrawInspector(overdrawInspector);
}
}
auto renderPass = RenderPass::Translucent;
if (!(mbgl::underlying_type(renderPass) & evaluatedProperties->renderPasses)) {
return;
@@ -389,11 +395,13 @@ void RenderHillshadeLayer::update(gfx::ShaderRegistry& shaders,
if (!singleTileLayerGroup) {
return;
}
const auto prepareTweaker = std::make_shared<HillshadePrepareLayerTweaker>(getID(), evaluatedProperties);
prepareTweaker->enableOverdrawInspector(overdrawInspector);
singleTileLayerGroup->setLayerTweaker(prepareTweaker);
renderTarget->addLayerGroup(singleTileLayerGroup, /*replace=*/true);
if (!prepareLayerTweaker) {
prepareLayerTweaker = std::make_shared<HillshadePrepareLayerTweaker>(getID(), evaluatedProperties);
}
singleTileLayerGroup->addLayerTweaker(prepareLayerTweaker);
gfx::VertexAttributeArray hillshadePrepareVertexAttrs;
if (const auto& attr = hillshadePrepareVertexAttrs.add(idPosAttribName)) {
@@ -437,6 +445,7 @@ void RenderHillshadeLayer::update(gfx::ShaderRegistry& shaders,
for (auto& drawable : hillshadePrepareBuilder->clearDrawables()) {
drawable->setTileID(tileID);
drawable->setLayerTweaker(prepareLayerTweaker);
drawable->setData(std::make_unique<gfx::HillshadePrepareDrawableData>(
bucket.getDEMData().stride, bucket.getDEMData().encoding, maxzoom));
singleTileLayerGroup->addDrawable(renderPass, tileID, std::move(drawable));
@@ -474,31 +483,34 @@ void RenderHillshadeLayer::update(gfx::ShaderRegistry& shaders,
hillshadeBuilder = context.createDrawableBuilder("hillshade");
if (tileLayerGroup->getDrawableCount(renderPass, tileID) > 0) {
tileLayerGroup->visitDrawables(renderPass, tileID, [&](gfx::Drawable& drawable) {
drawable.setVertexAttributes(std::move(hillshadeVertexAttrs));
drawable.setVertices({}, vertices->elements(), gfx::AttributeDataType::Short2);
const auto updateExisting = [&](gfx::Drawable& drawable) {
if (drawable.getLayerTweaker() != layerTweaker) {
return;
}
drawable.setVertexAttributes(std::move(hillshadeVertexAttrs));
drawable.setVertices({}, vertices->elements(), gfx::AttributeDataType::Short2);
std::vector<std::unique_ptr<gfx::Drawable::DrawSegment>> drawSegments;
for (std::size_t i = 0; i < segments->size(); ++i) {
const auto& seg = segments->data()[i];
auto segCopy = SegmentBase{
// no copy constructor
seg.vertexOffset,
seg.indexOffset,
seg.vertexLength,
seg.indexLength,
seg.sortKey,
};
drawSegments.emplace_back(hillshadeBuilder->createSegment(gfx::Triangles(), std::move(segCopy)));
}
drawable.setIndexData(indices->vector(), std::move(drawSegments));
std::vector<std::unique_ptr<gfx::Drawable::DrawSegment>> drawSegments;
for (std::size_t i = 0; i < segments->size(); ++i) {
const auto& seg = segments->data()[i];
auto segCopy = SegmentBase{
// no copy constructor
seg.vertexOffset,
seg.indexOffset,
seg.vertexLength,
seg.indexLength,
seg.sortKey,
};
drawSegments.emplace_back(hillshadeBuilder->createSegment(gfx::Triangles(), std::move(segCopy)));
}
drawable.setIndexData(indices->vector(), std::move(drawSegments));
auto imageLocation = hillshadeShader->getSamplerLocation(idTexImageName);
if (imageLocation.has_value()) {
drawable.setTexture(bucket.renderTarget->getTexture(), imageLocation.value());
}
});
auto imageLocation = hillshadeShader->getSamplerLocation(idTexImageName);
if (imageLocation.has_value()) {
drawable.setTexture(bucket.renderTarget->getTexture(), imageLocation.value());
}
};
if (0 < tileLayerGroup->visitDrawables(renderPass, tileID, updateExisting)) {
continue;
}
@@ -521,6 +533,8 @@ void RenderHillshadeLayer::update(gfx::ShaderRegistry& shaders,
for (auto& drawable : hillshadeBuilder->clearDrawables()) {
drawable->setTileID(tileID);
drawable->setLayerTweaker(layerTweaker);
tileLayerGroup->addDrawable(renderPass, tileID, std::move(drawable));
++stats.drawablesAdded;
}

View File

@@ -75,8 +75,7 @@ private:
using HillshadeVertexVector = gfx::VertexVector<HillshadeLayoutVertex>;
std::shared_ptr<HillshadeVertexVector> staticDataSharedVertices;
HillshadeLayerTweakerPtr tweaker;
bool overdrawInspector = false;
LayerTweakerPtr prepareLayerTweaker;
#endif
};

View File

@@ -21,16 +21,6 @@
#include <mbgl/util/logging.hpp>
#include <mbgl/util/math.hpp>
#if MLN_DRAWABLE_RENDERER
#include <mbgl/gfx/drawable_builder.hpp>
#include <mbgl/gfx/drawable_atlases_tweaker.hpp>
#include <mbgl/renderer/layer_group.hpp>
#include <mbgl/renderer/layers/line_layer_tweaker.hpp>
#include <mbgl/gfx/line_drawable_data.hpp>
#include <mbgl/shaders/shader_program_base.hpp>
#include <mbgl/util/string_indexer.hpp>
#endif
#if MLN_DRAWABLE_RENDERER
#include <mbgl/gfx/drawable_atlases_tweaker.hpp>
#include <mbgl/gfx/drawable_builder.hpp>
@@ -40,6 +30,7 @@
#include <mbgl/renderer/update_parameters.hpp>
#include <mbgl/shaders/line_layer_ubo.hpp>
#include <mbgl/shaders/shader_program_base.hpp>
#include <mbgl/util/string_indexer.hpp>
#endif
namespace mbgl {
@@ -90,7 +81,10 @@ void RenderLineLayer::evaluate(const PropertyEvaluationParameters& parameters) {
evaluatedProperties = std::move(properties);
#if MLN_DRAWABLE_RENDERER
updateLayerTweaker();
if (layerGroup) {
auto newTweaker = std::make_shared<LineLayerTweaker>(getID(), evaluatedProperties);
replaceTweaker(layerTweaker, std::move(newTweaker), {layerGroup});
}
#endif
}
@@ -364,16 +358,6 @@ static const StringIdentity idLineSDFInterpolationUBOName = StringIndexer::get("
/// Evaluated properties that depend on the tile
static const StringIdentity idLinePatternTilePropertiesUBOName = StringIndexer::get("LinePatternTilePropertiesUBO");
void RenderLineLayer::updateLayerTweaker() {
if (layerGroup) {
tweaker = std::make_shared<LineLayerTweaker>(getID(), evaluatedProperties);
#if MLN_RENDER_BACKEND_METAL
tweaker->setPropertiesAsUniforms(propertiesAsUniforms);
#endif // MLN_RENDER_BACKEND_METAL
tweaker->enableOverdrawInspector(overdrawInspector);
layerGroup->setLayerTweaker(tweaker);
}
}
static const StringIdentity idLineImageUniformName = StringIndexer::get("u_image");
@@ -390,23 +374,22 @@ void RenderLineLayer::update(gfx::ShaderRegistry& shaders,
return;
}
const bool overdraw = !!(updateParameters->debugOptions & MapDebugOptions::Overdraw);
if (overdrawInspector != overdraw) {
overdrawInspector = overdraw;
if (tweaker) {
tweaker->enableOverdrawInspector(overdrawInspector);
}
}
// Set up a layer group
if (!layerGroup) {
if (auto layerGroup_ = context.createTileLayerGroup(layerIndex, /*initialCapacity=*/64, getID())) {
setLayerGroup(std::move(layerGroup_), changes);
updateLayerTweaker();
} else {
return;
}
}
auto* tileLayerGroup = static_cast<TileLayerGroup*>(layerGroup.get());
if (!layerTweaker) {
layerTweaker = std::make_shared<LineLayerTweaker>(getID(), evaluatedProperties);
layerGroup->addLayerTweaker(layerTweaker);
}
layerTweaker->enableOverdrawInspector(!!(updateParameters->debugOptions & MapDebugOptions::Overdraw));
if (!lineShaderGroup) {
lineShaderGroup = shaders.getShaderGroup("LineShader");
}
@@ -476,6 +459,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();
@@ -546,6 +530,11 @@ void RenderLineLayer::update(gfx::ShaderRegistry& shaders,
// update existing drawables
tileLayerGroup->visitDrawables(renderPass, tileID, [&](gfx::Drawable& drawable) {
if (drawable.getLayerTweaker() != layerTweaker) {
// This drawable was produced on a previous style/bucket, and should not be updated.
return;
}
const auto& shader = drawable.getShader();
const auto& shaderUniforms = shader->getUniformBlocks();
auto& drawableUniforms = drawable.mutableUniformBuffers();
@@ -579,31 +568,30 @@ 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;
}
auto shader = lineSDFShaderGroup->getOrCreateShader(context, propertiesAsUniforms_);
// 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 MLN_RENDER_BACKEND_METAL
propertiesAsUniforms = std::move(propertiesAsUniforms_);
if (tweaker) {
tweaker->setPropertiesAsUniforms(propertiesAsUniforms);
if (layerTweaker) {
layerTweaker->setPropertiesAsUniforms(propertiesAsUniforms);
}
#endif // MLN_RENDER_BACKEND_METAL
auto builder = createLineBuilder("lineSDF", std::move(shader));
@@ -618,6 +606,7 @@ void RenderLineLayer::update(gfx::ShaderRegistry& shaders,
for (auto& drawable : builder->clearDrawables()) {
drawable->setType(mbgl::underlying_type(LineLayerTweaker::LineType::SDF));
drawable->setTileID(tileID);
drawable->setLayerTweaker(layerTweaker);
drawable->setData(std::make_unique<gfx::LineDrawableData>(cap));
drawable->mutableUniformBuffers().createOrUpdate(
idLineSDFInterpolationUBOName, &lineSDFInterpolationUBO, context);
@@ -626,31 +615,27 @@ 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;
}
auto shader = linePatternShaderGroup->getOrCreateShader(context, propertiesAsUniforms_);
// 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 MLN_RENDER_BACKEND_METAL
propertiesAsUniforms = std::move(propertiesAsUniforms_);
if (tweaker) {
tweaker->setPropertiesAsUniforms(propertiesAsUniforms);
if (layerTweaker) {
layerTweaker->setPropertiesAsUniforms(propertiesAsUniforms);
}
#endif // MLN_RENDER_BACKEND_METAL
auto builder = createLineBuilder("linePattern", std::move(shader));
@@ -679,6 +664,7 @@ void RenderLineLayer::update(gfx::ShaderRegistry& shaders,
for (auto& drawable : builder->clearDrawables()) {
drawable->setType(mbgl::underlying_type(LineLayerTweaker::LineType::Pattern));
drawable->setTileID(tileID);
drawable->setLayerTweaker(layerTweaker);
drawable->mutableUniformBuffers().createOrUpdate(
idLinePatternInterpolationUBOName, &linePatternInterpolationUBO, context);
drawable->mutableUniformBuffers().createOrUpdate(
@@ -689,26 +675,24 @@ 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;
}
auto shader = lineGradientShaderGroup->getOrCreateShader(context, propertiesAsUniforms_);
// 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 MLN_RENDER_BACKEND_METAL
propertiesAsUniforms = std::move(propertiesAsUniforms_);
if (tweaker) {
tweaker->setPropertiesAsUniforms(propertiesAsUniforms);
if (layerTweaker) {
layerTweaker->setPropertiesAsUniforms(propertiesAsUniforms);
}
#endif // MLN_RENDER_BACKEND_METAL
auto builder = createLineBuilder("lineGradient", std::move(shader));
@@ -736,6 +720,7 @@ void RenderLineLayer::update(gfx::ShaderRegistry& shaders,
for (auto& drawable : builder->clearDrawables()) {
drawable->setType(mbgl::underlying_type(LineLayerTweaker::LineType::Gradient));
drawable->setTileID(tileID);
drawable->setLayerTweaker(layerTweaker);
drawable->mutableUniformBuffers().createOrUpdate(
idLineGradientInterpolationUBOName, &lineGradientInterpolationUBO, context);
@@ -744,37 +729,26 @@ 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;
}
auto shader = lineShaderGroup->getOrCreateShader(context, propertiesAsUniforms_);
// 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 MLN_RENDER_BACKEND_METAL
propertiesAsUniforms = std::move(propertiesAsUniforms_);
if (tweaker) {
tweaker->setPropertiesAsUniforms(propertiesAsUniforms);
if (layerTweaker) {
layerTweaker->setPropertiesAsUniforms(propertiesAsUniforms);
}
#endif // MLN_RENDER_BACKEND_METAL
auto builder = createLineBuilder("line", std::move(shader));
@@ -787,6 +761,7 @@ void RenderLineLayer::update(gfx::ShaderRegistry& shaders,
for (auto& drawable : builder->clearDrawables()) {
drawable->setType(mbgl::underlying_type(LineLayerTweaker::LineType::Simple));
drawable->setTileID(tileID);
drawable->setLayerTweaker(layerTweaker);
drawable->mutableUniformBuffers().createOrUpdate(
idLineInterpolationUBOName, &lineInterpolationUBO, context);

View File

@@ -58,9 +58,6 @@ private:
#if MLN_LEGACY_RENDERER
void render(PaintParameters&) override;
#endif
#if MLN_DRAWABLE_RENDERER
void updateLayerTweaker();
#endif
bool queryIntersectsFeature(const GeometryCoordinates&,
const GeometryTileFeature&,
@@ -97,13 +94,6 @@ private:
gfx::ShaderGroupPtr linePatternShaderGroup;
gfx::DrawableTweakerPtr iconTweaker;
LineLayerTweakerPtr tweaker;
#if MLN_RENDER_BACKEND_METAL
std::vector<std::string> propertiesAsUniforms;
#endif // MLN_RENDER_BACKEND_METAL
bool overdrawInspector = false;
#endif
};

View File

@@ -53,7 +53,10 @@ void RenderRasterLayer::evaluate(const PropertyEvaluationParameters& parameters)
evaluatedProperties = std::move(properties);
#if MLN_DRAWABLE_RENDERER
updateLayerTweaker();
if (layerGroup) {
auto newTweaker = std::make_shared<RasterLayerTweaker>(getID(), evaluatedProperties);
replaceTweaker(layerTweaker, std::move(newTweaker), {layerGroup, imageLayerGroup});
}
#endif
}
@@ -247,19 +250,6 @@ static const StringIdentity idTexturePosAttribName = StringIndexer::get("a_textu
static const StringIdentity idTexImage0Name = StringIndexer::get("u_image0");
static const StringIdentity idTexImage1Name = StringIndexer::get("u_image1");
void RenderRasterLayer::updateLayerTweaker() {
if (layerGroup || imageLayerGroup) {
tweaker = std::make_shared<RasterLayerTweaker>(getID(), evaluatedProperties);
tweaker->enableOverdrawInspector(overdrawInspector);
if (layerGroup) {
layerGroup->setLayerTweaker(tweaker);
}
if (imageLayerGroup) {
imageLayerGroup->setLayerTweaker(tweaker);
}
}
}
void RenderRasterLayer::update(gfx::ShaderRegistry& shaders,
gfx::Context& context,
const TransformState& /*state*/,
@@ -278,22 +268,28 @@ void RenderRasterLayer::update(gfx::ShaderRegistry& shaders,
return;
}
auto renderPass = RenderPass::Translucent;
constexpr auto renderPass = RenderPass::Translucent;
if (!rasterShader) {
rasterShader = context.getGenericShader(shaders, "RasterShader");
if (!rasterShader) {
return;
}
rasterSampler0 = rasterShader->getSamplerLocation(idTexImage0Name);
rasterSampler1 = rasterShader->getSamplerLocation(idTexImage1Name);
}
const bool overdraw = !!(updateParameters->debugOptions & MapDebugOptions::Overdraw);
if (overdrawInspector != overdraw) {
overdrawInspector = overdraw;
if (tweaker) {
tweaker->enableOverdrawInspector(overdrawInspector);
if (!layerTweaker) {
layerTweaker = std::make_shared<RasterLayerTweaker>(getID(), evaluatedProperties);
if (layerGroup) {
layerGroup->addLayerTweaker(layerTweaker);
}
if (imageLayerGroup) {
imageLayerGroup->addLayerTweaker(layerTweaker);
}
}
layerTweaker->enableOverdrawInspector(!!(updateParameters->debugOptions & MapDebugOptions::Overdraw));
if (!staticDataVertices) {
staticDataVertices = std::make_shared<RasterVertexVector>(RenderStaticData::rasterVertices());
@@ -305,61 +301,47 @@ void RenderRasterLayer::update(gfx::ShaderRegistry& shaders,
staticDataSegments = std::make_shared<RasterSegmentVector>(RenderStaticData::rasterSegments());
}
const auto& evaluated = static_cast<const RasterLayerProperties&>(*evaluatedProperties).evaluated;
RasterProgram::Binders paintAttributeData{evaluated, 0};
const gfx::TextureFilterType filter = evaluated.get<RasterResampling>() == RasterResamplingType::Nearest
? gfx::TextureFilterType::Nearest
: gfx::TextureFilterType::Linear;
auto createBuilder = [&context, &renderPass, this]() -> std::unique_ptr<gfx::DrawableBuilder> {
std::unique_ptr<gfx::DrawableBuilder> builder{context.createDrawableBuilder("raster")};
const auto createBuilder = [&] {
auto builder = context.createDrawableBuilder("raster");
builder->setShader(rasterShader);
builder->setRenderPass(renderPass);
builder->setSubLayerIndex(0);
builder->setDepthType((renderPass == RenderPass::Opaque) ? gfx::DepthMaskType::ReadWrite
: gfx::DepthMaskType::ReadOnly);
builder->setDepthType(gfx::DepthMaskType::ReadOnly);
builder->setColorMode(gfx::ColorMode::alphaBlended());
builder->setCullFaceMode(gfx::CullFaceMode::disabled());
builder->setVertexAttrNameId(idPosAttribName);
return builder;
};
auto setTextures = [&context, &filter, this](std::unique_ptr<gfx::DrawableBuilder>& builder,
const RasterBucket& bucket) {
// textures
auto location0 = rasterShader->getSamplerLocation(idTexImage0Name);
if (location0.has_value()) {
std::shared_ptr<gfx::Texture2D> tex0 = context.createTexture2D();
tex0->setImage(bucket.image);
tex0->setSamplerConfiguration({filter, gfx::TextureWrapType::Clamp, gfx::TextureWrapType::Clamp});
builder->setTexture(tex0, location0.value());
}
auto location1 = rasterShader->getSamplerLocation(idTexImage1Name);
if (location1.has_value()) {
std::shared_ptr<gfx::Texture2D> tex1 = context.createTexture2D();
tex1->setImage(bucket.image);
tex1->setSamplerConfiguration({filter, gfx::TextureWrapType::Clamp, gfx::TextureWrapType::Clamp});
builder->setTexture(tex1, location1.value());
const auto setTextures = [&](gfx::UniqueDrawableBuilder& builder, const RasterBucket& bucket) {
if (bucket.image && (rasterSampler0 || rasterSampler1)) {
if (auto tex = context.createTexture2D()) {
const auto& evaluated = static_cast<const RasterLayerProperties&>(*evaluatedProperties).evaluated;
const bool nearest = evaluated.get<RasterResampling>() == RasterResamplingType::Nearest;
const auto filter = nearest ? gfx::TextureFilterType::Nearest : gfx::TextureFilterType::Linear;
tex->setImage(bucket.image);
tex->setSamplerConfiguration({filter, gfx::TextureWrapType::Clamp, gfx::TextureWrapType::Clamp});
if (rasterSampler0) {
builder->setTexture(tex, *rasterSampler0);
}
if (rasterSampler1) {
builder->setTexture(std::move(tex), *rasterSampler1);
}
}
}
};
auto buildVertexData = [this](std::unique_ptr<gfx::DrawableBuilder>& builder, const RasterBucket& bucket) {
RasterVertexVectorPtr vertices = staticDataVertices;
TriangleIndexVectorPtr indices = staticDataIndices;
const RasterSegmentVector* segments = staticDataSegments.get();
// Build vertex attributes and apply them to a drawable or a builder
const auto buildVertexData =
[this](const gfx::UniqueDrawableBuilder& builder, gfx::Drawable* drawable, const RasterBucket& bucket) {
const bool shared = (!bucket.vertices.empty() && !bucket.indices.empty() && !bucket.segments.empty());
const auto& vertices = shared ? bucket.sharedVertices : staticDataVertices;
const auto& indices = shared ? bucket.sharedTriangles : staticDataIndices;
const auto* segments = shared ? &bucket.segments : staticDataSegments.get();
if (!bucket.vertices.empty() && !bucket.indices.empty() && !bucket.segments.empty()) {
vertices = bucket.sharedVertices;
indices = bucket.sharedTriangles;
segments = &bucket.segments;
}
// attributes
{
gfx::VertexAttributeArray vertexAttrs;
if (auto& attr = vertexAttrs.add(idPosAttribName)) {
attr->setSharedRawData(vertices,
offsetof(RasterLayoutVertex, a1),
@@ -376,76 +358,74 @@ void RenderRasterLayer::update(gfx::ShaderRegistry& shaders,
gfx::AttributeDataType::Short2);
}
builder->setVertexAttributes(std::move(vertexAttrs));
if (drawable) {
drawable->setVertexAttributes(std::move(vertexAttrs));
} else if (builder) {
builder->setVertexAttributes(std::move(vertexAttrs));
builder->setRawVertices({}, vertices->elements(), gfx::AttributeDataType::Short2);
builder->setSegments(gfx::Triangles(), indices, segments->data(), segments->size());
}
};
gfx::UniqueDrawableBuilder builder;
if (imageData) {
// TODO: Can we avoid rebuilding drawables each time in this case as well?
if (imageLayerGroup) {
stats.drawablesRemoved += imageLayerGroup->clearDrawables();
}
builder->setRawVertices({}, vertices->elements(), gfx::AttributeDataType::Short2);
builder->setSegments(gfx::Triangles(), indices, segments->data(), segments->size());
};
auto buildDrawables = [&setTextures, &buildVertexData](std::unique_ptr<gfx::DrawableBuilder>& builder,
const RasterBucket& bucket) {
buildVertexData(builder, bucket);
setTextures(builder, bucket);
};
auto updateTileDrawables = [&](std::unique_ptr<gfx::DrawableBuilder>& builder,
auto* tileLayerGroup,
const auto& tileID,
const RasterBucket& bucket) {
// TODO: check for oportunity to skip
buildVertexData(builder, bucket);
tileLayerGroup->visitDrawables(renderPass, tileID, [&](gfx::Drawable& drawable) {
for (auto& tex : drawable.getTextures()) {
builder->setTexture(tex.second, tex.first);
}
});
};
if (imageData) {
RasterBucket& bucket = *imageData->bucket;
if (!bucket.vertices.empty()) {
if (imageLayerGroup) {
stats.drawablesRemoved += imageLayerGroup->clearDrawables();
} else {
if (!imageLayerGroup) {
// Set up a layer group
imageLayerGroup = context.createLayerGroup(layerIndex, /*initialCapacity=*/64, getID());
imageLayerGroup->addLayerTweaker(layerTweaker);
activateLayerGroup(imageLayerGroup, isRenderable, changes);
updateLayerTweaker();
}
auto builder = createBuilder();
// Create a drawable for each transformation
// TODO: Share textures
builder = createBuilder();
for (const auto& matrix_ : imageData->matrices) {
buildDrawables(builder, bucket);
buildVertexData(builder, /*drawable=*/nullptr, bucket);
setTextures(builder, bucket);
// finish
builder->flush();
for (auto& drawable : builder->clearDrawables()) {
drawable->setData(std::make_unique<gfx::ImageDrawableData>(matrix_));
drawable->setLayerTweaker(layerTweaker);
imageLayerGroup->addDrawable(std::move(drawable));
++stats.drawablesAdded;
}
}
}
} else if (renderTiles) {
if (layerGroup) {
stats.drawablesRemoved += layerGroup->removeDrawablesIf([&](gfx::Drawable& drawable) {
// Has this tile dropped out of the cover set?
return drawable.getTileID() && !hasRenderTile(*drawable.getTileID());
// Update existing drawables, returns the number of drawables found for the tile
const auto updateTileDrawables = [&](auto* tileLayerGroup, const auto& tileID, const RasterBucket& bucket) {
return tileLayerGroup->visitDrawables(renderPass, tileID, [&](gfx::Drawable& drawable) {
if (drawable.getLayerTweaker() == layerTweaker) {
gfx::UniqueDrawableBuilder none;
buildVertexData(none, &drawable, bucket);
}
});
};
// Remove existing drawables that are no longer in the cover set
if (layerGroup) {
stats.drawablesRemoved += layerGroup->removeDrawablesIf(
[&](gfx::Drawable& drawable) { return drawable.getTileID() && !hasRenderTile(*drawable.getTileID()); });
} else {
// Set up a tile layer group
if (auto layerGroup_ = context.createTileLayerGroup(layerIndex, /*initialCapacity=*/64, getID())) {
layerGroup_->addLayerTweaker(layerTweaker);
setLayerGroup(std::move(layerGroup_), changes);
updateLayerTweaker();
}
}
auto* tileLayerGroup = static_cast<TileLayerGroup*>(layerGroup.get());
auto builder = createBuilder();
for (const RenderTile& tile : *renderTiles) {
const auto& tileID = tile.getOverscaledTileID();
@@ -455,30 +435,44 @@ void RenderRasterLayer::update(gfx::ShaderRegistry& shaders,
continue;
}
bool cleared = false;
const auto& bucket = static_cast<const RasterBucket&>(*bucket_);
const auto prevBucketID = getRenderTileBucketID(tileID);
if (prevBucketID != util::SimpleIdentity::Empty && prevBucketID != bucket.getID()) {
// This tile was previously set up from a different bucket, drop and re-create any drawables for it.
// If the bucket data has changed, rebuild the drawables.
const bool bucketSharedData = (!bucket.vertices.empty() && !bucket.indices.empty() &&
!bucket.segments.empty());
const bool bucketDirty = bucketSharedData && (bucket.vertices.getDirty() || bucket.indices.getDirty());
if (bucketDirty) {
// Note, vertex/index dirty flags will be reset when those buffers are uploaded.
removeTile(renderPass, tileID);
cleared = true;
} else if (setRenderTileBucketID(tileID, bucket.getID())) {
// Bucket ID changed, we need to rebuild the drawables
removeTile(renderPass, tileID);
cleared = true;
}
setRenderTileBucketID(tileID, bucket.getID());
if (tileLayerGroup->getDrawableCount(renderPass, tileID) > 0) {
// re-create drawable geometry and pass texture
updateTileDrawables(builder, tileLayerGroup, tileID, bucket);
// If there are any drawables left for this tile, update them.
if (!cleared && 0 < updateTileDrawables(tileLayerGroup, tileID, bucket)) {
continue;
}
// erase current drawable
removeTile(renderPass, tileID);
} else if (bucket.image) {
// build new drawable for this tile
buildDrawables(builder, bucket);
// Otherwise, create new ones.
if (!builder) {
builder = createBuilder();
}
if (bucket.image && builder->getTextures().size() == 0) {
setTextures(builder, bucket);
};
buildVertexData(builder, /*drawable=*/nullptr, bucket);
// finish
builder->flush();
for (auto& drawable : builder->clearDrawables()) {
drawable->setTileID(tileID);
drawable->setLayerTweaker(layerTweaker);
tileLayerGroup->addDrawable(renderPass, tileID, std::move(drawable));
++stats.drawablesAdded;
}

View File

@@ -8,11 +8,6 @@
namespace mbgl {
#if MLN_DRAWABLE_RENDERER
class RasterLayerTweaker;
using RasterLayerTweakerPtr = std::shared_ptr<RasterLayerTweaker>;
#endif // MLN_DRAWABLE_RENDERER
class ImageSourceRenderData;
class RasterProgram;
@@ -60,10 +55,6 @@ private:
void render(PaintParameters&) override;
#endif
#if MLN_DRAWABLE_RENDERER
void updateLayerTweaker();
#endif // MLN_DRAWABLE_RENDERER
// Paint properties
style::RasterPaintProperties::Unevaluated unevaluated;
const ImageSourceRenderData* imageData = nullptr;
@@ -75,6 +66,8 @@ private:
#if MLN_DRAWABLE_RENDERER
gfx::ShaderProgramBasePtr rasterShader;
std::optional<uint32_t> rasterSampler0;
std::optional<uint32_t> rasterSampler1;
LayerGroupPtr imageLayerGroup;
using RasterVertexVector = gfx::VertexVector<RasterLayoutVertex>;
@@ -88,9 +81,6 @@ private:
using RasterSegmentVector = SegmentVector<RasterAttributes>;
using RasterSegmentVectorPtr = std::shared_ptr<RasterSegmentVector>;
std::shared_ptr<RasterSegmentVector> staticDataSegments;
RasterLayerTweakerPtr tweaker;
bool overdrawInspector = false;
#endif
};

View File

@@ -29,6 +29,7 @@
#include <mbgl/gfx/collision_drawable_data.hpp>
#include <mbgl/renderer/layer_group.hpp>
#include <mbgl/renderer/layers/symbol_layer_tweaker.hpp>
#include <mbgl/renderer/update_parameters.hpp>
#include <mbgl/shaders/shader_program_base.hpp>
#include <mbgl/shaders/symbol_layer_ubo.hpp>
#include <mbgl/gfx/collision_drawable_data.hpp>
@@ -379,11 +380,10 @@ void RenderSymbolLayer::evaluate(const PropertyEvaluationParameters& parameters)
evaluatedProperties = std::move(properties);
#if MLN_DRAWABLE_RENDERER
if (layerGroup && layerGroup->getLayerTweaker()) {
#if MLN_RENDER_BACKEND_METAL
layerGroup->getLayerTweaker()->setPropertiesAsUniforms(propertiesAsUniforms);
#endif // MLN_RENDER_BACKEND_METAL
layerGroup->getLayerTweaker()->updateProperties(evaluatedProperties);
// The symbol tweaker supports updating properties.
// When the style changes, it will be replaced in `RenderLayer::layerChanged`
if (layerTweaker) {
layerTweaker->updateProperties(evaluatedProperties);
}
#endif // MLN_DRAWABLE_RENDERER
}
@@ -749,19 +749,21 @@ SymbolDrawableTilePropsUBO buildTileUBO(const SymbolBucket& bucket,
};
}
static const StringIdentity idDataAttibName = StringIndexer::get("a_data");
static const StringIdentity idPosOffsetAttribName = StringIndexer::get("a_pos_offset");
static const StringIdentity idPixOffsetAttribName = StringIndexer::get("a_pixeloffset");
static const StringIdentity idProjPosAttribName = StringIndexer::get("a_projected_pos");
static const StringIdentity idFadeOpacityAttribName = StringIndexer::get("a_fade_opacity");
static const StringIdentity idTexUniformName = StringIndexer::get("u_texture");
static const StringIdentity idTexIconUniformName = StringIndexer::get("u_texture_icon");
static const auto idDataAttibName = StringIndexer::get("a_data");
static const auto posOffsetAttribName = "a_pos_offset";
static const auto idPosOffsetAttribName = StringIndexer::get(posOffsetAttribName);
static const auto idPixOffsetAttribName = StringIndexer::get("a_pixeloffset");
static const auto idProjPosAttribName = StringIndexer::get("a_projected_pos");
static const auto idFadeOpacityAttribName = StringIndexer::get("a_fade_opacity");
static const auto idTexUniformName = StringIndexer::get("u_texture");
static 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),
@@ -801,13 +803,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,
@@ -817,7 +819,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;
}
@@ -859,7 +862,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));
}
@@ -970,16 +973,19 @@ void RenderSymbolLayer::layerIndexChanged(int32_t newLayerIndex, UniqueChangeReq
changeLayerIndex(collisionTileLayerGroup, newLayerIndex, changes);
}
void RenderSymbolLayer::removeTile(RenderPass renderPass, const OverscaledTileID& tileID) {
std::size_t RenderSymbolLayer::removeTile(RenderPass renderPass, const OverscaledTileID& tileID) {
const auto oldValue = stats.drawablesRemoved;
if (const auto tileGroup = static_cast<TileLayerGroup*>(layerGroup.get())) {
stats.drawablesRemoved += tileGroup->removeDrawables(renderPass, tileID).size();
}
if (collisionTileLayerGroup) {
stats.drawablesRemoved += collisionTileLayerGroup->removeDrawables(renderPass, tileID).size();
}
return stats.drawablesRemoved - oldValue;
}
void RenderSymbolLayer::removeAllDrawables() {
std::size_t RenderSymbolLayer::removeAllDrawables() {
const auto oldValue = stats.drawablesRemoved;
if (layerGroup) {
stats.drawablesRemoved += layerGroup->getDrawableCount();
layerGroup->clearDrawables();
@@ -988,12 +994,13 @@ void RenderSymbolLayer::removeAllDrawables() {
stats.drawablesRemoved += collisionTileLayerGroup->getDrawableCount();
collisionTileLayerGroup->clearDrawables();
}
return stats.drawablesRemoved - oldValue;
}
void RenderSymbolLayer::update(gfx::ShaderRegistry& shaders,
gfx::Context& context,
const TransformState& state,
const std::shared_ptr<UpdateParameters>&,
const std::shared_ptr<UpdateParameters>& updateParameters,
const RenderTree& /*renderTree*/,
UniqueChangeRequestVec& changes) {
if (!renderTiles || renderTiles->empty() || passes == RenderPass::None) {
@@ -1004,24 +1011,27 @@ void RenderSymbolLayer::update(gfx::ShaderRegistry& shaders,
// Set up a layer group
if (!layerGroup) {
if (auto layerGroup_ = context.createTileLayerGroup(layerIndex, /*initialCapacity=*/64, getID())) {
tweaker = std::make_shared<SymbolLayerTweaker>(getID(), evaluatedProperties);
#if MLN_RENDER_BACKEND_METAL
tweaker->setPropertiesAsUniforms(propertiesAsUniforms);
#endif // MLN_RENDER_BACKEND_METAL
layerGroup_->setLayerTweaker(tweaker);
setLayerGroup(std::move(layerGroup_), changes);
}
}
if (!layerTweaker) {
layerTweaker = std::make_shared<SymbolLayerTweaker>(getID(), evaluatedProperties);
layerGroup->addLayerTweaker(layerTweaker);
}
layerTweaker->enableOverdrawInspector(!!(updateParameters->debugOptions & MapDebugOptions::Overdraw));
const auto& getCollisionTileLayerGroup = [&] {
if (!collisionTileLayerGroup) {
if ((collisionTileLayerGroup = context.createTileLayerGroup(
layerIndex, /*initialCapacity=*/64, getID() + "-collision"))) {
collisionTileLayerGroup->setLayerTweaker(
std::make_shared<CollisionLayerTweaker>(getID(), evaluatedProperties));
activateLayerGroup(collisionTileLayerGroup, true, changes);
}
}
if (!collisionLayerTweaker) {
collisionLayerTweaker = std::make_shared<CollisionLayerTweaker>(getID(), evaluatedProperties);
collisionTileLayerGroup->addLayerTweaker(collisionLayerTweaker);
}
return collisionTileLayerGroup;
};
@@ -1079,6 +1089,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();
@@ -1168,6 +1179,8 @@ void RenderSymbolLayer::update(gfx::ShaderRegistry& shaders,
// add drawables to layer group
for (auto& drawable : collisionBuilder->clearDrawables()) {
drawable->setTileID(tileID);
drawable->setLayerTweaker(collisionLayerTweaker);
auto drawData = std::make_unique<gfx::CollisionDrawableData>(values.translate, values.translateAnchor);
drawable->setData(std::move(drawData));
group->addDrawable(passes, tileID, std::move(drawable));
@@ -1181,9 +1194,22 @@ void RenderSymbolLayer::update(gfx::ShaderRegistry& shaders,
// Just update the drawables we already created
tileLayerGroup->visitDrawables(passes, tileID, [&](gfx::Drawable& drawable) {
if (drawable.getLayerTweaker() != layerTweaker) {
// This drawable was produced on a previous style/bucket, and should not be updated.
return;
}
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
@@ -1263,15 +1289,12 @@ void RenderSymbolLayer::update(gfx::ShaderRegistry& shaders,
const auto vertexCount = buffer.vertices().elements();
propertiesAsUniforms.clear();
gfx::VertexAttributeArray attribs;
const auto uniformProps = updateTileAttributes(buffer, isText, bucketPaintProperties, evaluated, attribs);
#if MLN_RENDER_BACKEND_METAL
propertiesAsUniforms = uniformProps;
if (tweaker) {
tweaker->setPropertiesAsUniforms(propertiesAsUniforms);
updateTileAttributes(buffer, isText, bucketPaintProperties, evaluated, attribs, propertiesAsUniforms);
if (layerTweaker) {
layerTweaker->setPropertiesAsUniforms(propertiesAsUniforms);
}
#endif // MLN_RENDER_BACKEND_METAL
const auto textHalo = evaluated.get<style::TextHaloColor>().constantOr(Color::black()).a > 0.0f &&
evaluated.get<style::TextHaloWidth>().constantOr(1);
@@ -1341,7 +1364,7 @@ void RenderSymbolLayer::update(gfx::ShaderRegistry& shaders,
return;
}
const auto shader = std::static_pointer_cast<gfx::ShaderProgramBase>(
shaderGroup->getOrCreateShader(context, uniformProps, StringIndexer::get(idPosOffsetAttribName)));
shaderGroup->getOrCreateShader(context, propertiesAsUniforms, posOffsetAttribName));
if (!shader) {
return;
}
@@ -1359,6 +1382,7 @@ void RenderSymbolLayer::update(gfx::ShaderRegistry& shaders,
for (auto& drawable : builder->clearDrawables()) {
drawable->setTileID(tileID);
drawable->setLayerTweaker(layerTweaker);
auto drawData = std::make_unique<gfx::SymbolDrawableData>(
/*.isHalo=*/isHalo,

View File

@@ -118,10 +118,10 @@ protected:
void layerRemoved(UniqueChangeRequestVec&) override;
/// Remove all drawables for the tile from the layer group
void removeTile(RenderPass, const OverscaledTileID&) override;
std::size_t removeTile(RenderPass, const OverscaledTileID&) override;
/// Remove all the drawables for tiles
void removeAllDrawables() override;
std::size_t removeAllDrawables() override;
#endif // MLN_DRAWABLE_RENDERER
private:
@@ -151,8 +151,6 @@ private:
#endif // MLN_LEGACY_RENDERER
#if MLN_DRAWABLE_RENDERER
SymbolLayerTweakerPtr tweaker;
gfx::ShaderGroupPtr symbolIconGroup;
gfx::ShaderGroupPtr symbolSDFGroup;
gfx::ShaderGroupPtr symbolTextAndIconGroup;
@@ -160,11 +158,9 @@ private:
gfx::ShaderGroupPtr collisionBoxGroup;
gfx::ShaderGroupPtr collisionCircleGroup;
std::shared_ptr<TileLayerGroup> collisionTileLayerGroup;
#endif // MLN_DRAWABLE_RENDERER
#if MLN_RENDER_BACKEND_METAL
std::vector<std::string> propertiesAsUniforms;
#endif // MLN_RENDER_BACKEND_METAL
LayerTweakerPtr collisionLayerTweaker;
#endif // MLN_DRAWABLE_RENDERER
};
} // namespace mbgl

View File

@@ -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 (propertiesChanged) {
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,
@@ -116,6 +117,12 @@ void SymbolLayerTweaker::execute(LayerGroupBase& layerGroup,
}
#endif
if (propertiesUpdated) {
textPropertiesUpdated = true;
iconPropertiesUpdated = true;
propertiesUpdated = false;
}
layerGroup.visitDrawables([&](gfx::Drawable& drawable) {
if (!drawable.getTileID() || !drawable.getData()) {
return;
@@ -125,14 +132,15 @@ void SymbolLayerTweaker::execute(LayerGroupBase& layerGroup,
const auto& symbolData = static_cast<gfx::SymbolDrawableData&>(*drawable.getData());
const auto isText = (symbolData.symbolType == SymbolType::Text);
if (isText && (!textPaintBuffer || propertiesUpdated)) {
if (isText && (textPaintBuffer || textPropertiesUpdated)) {
const auto props = buildPaintUBO(true, evaluated);
textPaintBuffer = parameters.context.createUniformBuffer(&props, sizeof(props));
} else if (!isText && (!iconPaintBuffer || propertiesUpdated)) {
textPropertiesUpdated = false;
} else if (!isText && (!iconPaintBuffer || iconPropertiesUpdated)) {
const auto props = buildPaintUBO(false, evaluated);
iconPaintBuffer = parameters.context.createUniformBuffer(&props, sizeof(props));
iconPropertiesUpdated = false;
}
propertiesUpdated = false;
// from RenderTile::translatedMatrix
const auto translate = isText ? evaluated.get<style::TextTranslate>() : evaluated.get<style::IconTranslate>();

View File

@@ -30,6 +30,9 @@ private:
gfx::UniformBufferPtr textPaintBuffer;
gfx::UniformBufferPtr iconPaintBuffer;
bool textPropertiesUpdated = false;
bool iconPropertiesUpdated = false;
#if MLN_RENDER_BACKEND_METAL
gfx::UniformBufferPtr permutationUniformBuffer;
gfx::UniformBufferPtr expressionUniformBuffer;

View File

@@ -70,11 +70,41 @@ std::optional<Color> RenderLayer::getSolidBackground() const {
}
#if MLN_DRAWABLE_RENDERER
void RenderLayer::replaceTweaker(LayerTweakerPtr& curTweaker,
LayerTweakerPtr newTweaker,
const std::vector<LayerGroupBasePtr>& layerGroups) {
const auto prevTweaker = curTweaker;
// We need to re-create the tweaker because it doesn't yet support modifying evaluated
// properties, but we don't want to stop updating drawables (as in the `layerChanged` case)
// so we need to update the tweaker reference on the outstanding drawables so that they
// pass the check in `updateExisting`.
// TODO: Once the tweaker doesn't need to be re-created on each property evaluation, this won't be needed.
for (const auto& group : layerGroups) {
if (group) {
group->addLayerTweaker(newTweaker);
group->visitDrawables([&](gfx::Drawable& drawable) {
if (drawable.getLayerTweaker() == prevTweaker) {
drawable.setLayerTweaker(curTweaker);
}
});
}
}
curTweaker = std::move(newTweaker);
}
void RenderLayer::layerChanged(const TransitionParameters&,
const Immutable<style::Layer::Impl>&,
UniqueChangeRequestVec&) {
// When a layer changes, the bucket won't be replaced until the new source(s) load.
// If we remove the drawables here, they will just be re-created based on the current data.
// Detach the layer tweaker, if any. This keeps the existing tiles up-to-date with the
// most recent evaluated properties, while a new one will be created along with new drawables
// when tiles are loaded and new buckets are available.
layerTweaker.reset();
}
void RenderLayer::layerRemoved(UniqueChangeRequestVec& changes) {
@@ -136,17 +166,23 @@ const LayerRenderData* RenderLayer::getRenderDataForPass(const RenderTile& tile,
}
#if MLN_DRAWABLE_RENDERER
void RenderLayer::removeTile(RenderPass renderPass, const OverscaledTileID& tileID) {
std::size_t RenderLayer::removeTile(RenderPass renderPass, const OverscaledTileID& tileID) {
if (const auto tileGroup = static_cast<TileLayerGroup*>(layerGroup.get())) {
stats.drawablesRemoved += tileGroup->removeDrawables(renderPass, tileID).size();
const auto n = tileGroup->removeDrawables(renderPass, tileID).size();
stats.drawablesRemoved += n;
return n;
}
return 0;
}
void RenderLayer::removeAllDrawables() {
std::size_t RenderLayer::removeAllDrawables() {
if (layerGroup) {
stats.drawablesRemoved += layerGroup->getDrawableCount();
const auto count = layerGroup->getDrawableCount();
stats.drawablesRemoved += count;
layerGroup->clearDrawables();
return count;
}
return 0;
}
void RenderLayer::updateRenderTileIDs() {

View File

@@ -211,10 +211,11 @@ protected:
void changeLayerIndex(const LayerGroupBasePtr&, int32_t newLayerIndex, UniqueChangeRequestVec&);
/// Remove all drawables for the tile from the layer group
virtual void removeTile(RenderPass, const OverscaledTileID&);
/// @return The number of drawables actually removed.
virtual std::size_t removeTile(RenderPass, const OverscaledTileID&);
/// Remove all the drawables for tiles
virtual void removeAllDrawables();
virtual std::size_t removeAllDrawables();
/// Update `renderTileIDs` from `renderTiles`
void updateRenderTileIDs();
@@ -233,6 +234,12 @@ protected:
/// @return true if updated, false if the tile ID is not present in the set of tiles to be rendered or the ID is
/// unchanged
bool setRenderTileBucketID(const OverscaledTileID&, util::SimpleIdentity bucketID);
/// Update the layer tweaker and drawables which reference it
static void replaceTweaker(LayerTweakerPtr& toReplace,
LayerTweakerPtr newTweaker,
const std::vector<LayerGroupBasePtr>&);
#endif // MLN_DRAWABLE_RENDERER
static bool applyColorRamp(const style::ColorRampPropertyValue&, PremultipliedImage&);
@@ -251,6 +258,9 @@ protected:
// will need to be overriden to handle their activation.
LayerGroupBasePtr layerGroup;
// An optional tweaker that will update drawables
LayerTweakerPtr layerTweaker;
// The set of Tile IDs in `renderTiles`, along with the
// identity of the bucket from which they were built.
std::unordered_map<OverscaledTileID, util::SimpleIdentity> renderTileIDs;

View File

@@ -6,6 +6,7 @@
#include <mbgl/renderer/layer_group.hpp>
#include <mbgl/renderer/layer_tweaker.hpp>
#include <mbgl/renderer/paint_parameters.hpp>
#include <mbgl/renderer/render_tree.hpp>
namespace mbgl {
@@ -84,11 +85,7 @@ void RenderTarget::render(RenderOrchestrator& orchestrator, const RenderTree& re
"render target", {*offscreenTexture, Color{0.0f, 0.0f, 0.0f, 1.0f}, {}, {}});
// Run layer tweakers to update any dynamic elements
visitLayerGroups([&](LayerGroupBase& layerGroup) {
if (layerGroup.getLayerTweaker()) {
layerGroup.getLayerTweaker()->execute(layerGroup, renderTree, parameters);
}
});
visitLayerGroups([&](LayerGroupBase& layerGroup) { layerGroup.runTweakers(renderTree, parameters); });
// draw layer groups, opaque pass
parameters.pass = RenderPass::Opaque;

View File

@@ -152,11 +152,8 @@ void Renderer::Impl::render(const RenderTree& renderTree,
#endif
// Tweakers are run in the upload pass so they can set up uniforms.
orchestrator.visitLayerGroups([&](LayerGroupBase& layerGroup) {
if (layerGroup.getLayerTweaker()) {
layerGroup.getLayerTweaker()->execute(layerGroup, renderTree, parameters);
}
});
orchestrator.visitLayerGroups(
[&](LayerGroupBase& layerGroup) { layerGroup.runTweakers(renderTree, parameters); });
}
// Update the debug layer groups

View 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

View 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, "BackgroundPatternLayerUBO"},
};
} // namespace shaders
} // namespace mbgl

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View File

@@ -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) {

View 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

View 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

View 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

View File

@@ -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

View File

@@ -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
@@ -236,4 +237,4 @@ if (CMAKE_SYSTEM_NAME STREQUAL Linux)
mbgl-test
PRIVATE USE_CPP_TEST_SERVER
)
endif()
endif()

54
test/util/hash.test.cpp Normal file
View File

@@ -0,0 +1,54 @@
#include <mbgl/test/util.hpp>
#include <mbgl/util/hash.hpp>
#include <algorithm>
#include <cstdint>
#include <iostream>
#include <iomanip>
#include <random>
#include <vector>
using namespace mbgl;
TEST(OrderIndependentHash, Permutations) {
// Try collections of up to this many elements
constexpr int maxSize = 6;
// Try this many different sets of values for each size
constexpr int iterations = 10;
// Use values up to this large
constexpr size_t maxVal = 10;
std::seed_seq seed{0xf00dLL};
std::default_random_engine engine(seed);
std::uniform_int_distribution<size_t> distribution(0, maxVal);
for (int curSize = 1; curSize <= maxSize; ++curSize) {
for (int ii = 0; ii < iterations; ++ii) {
// Generate `curSize` random values
std::vector<size_t> values;
for (int jj = 0; jj < curSize; ++jj) {
values.push_back(distribution(engine));
}
// Generate the hash for each permutation, comparing subsequent values to the first one.
bool isFirst = true;
size_t initialValue = 0;
do {
const auto curValue = util::order_independent_hash(values.begin(), values.end());
if (isFirst || curValue != initialValue) {
for (auto v : values) {
std::cout << v << ",";
}
std::cout << " - " << std::hex << curValue << std::endl;
}
if (isFirst) {
initialValue = curValue;
isFirst = false;
} else {
EXPECT_EQ(initialValue, curValue);
}
} while (std::next_permutation(values.begin(), values.end()));
}
}
}