Issue/1687 (#1697)
Co-authored-by: Bart Louwers <bart@emeel.net> Co-authored-by: mwilsnd <mwilsnd@gmail.com>
This commit is contained in:
@@ -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 = [
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {};
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -4,6 +4,10 @@
|
||||
#include <mbgl/shaders/gl/shader_program_gl.hpp>
|
||||
#include <mbgl/shaders/shader_source.hpp>
|
||||
#include <mbgl/programs/program_parameters.hpp>
|
||||
#include <mbgl/util/hash.hpp>
|
||||
|
||||
#include <sstream>
|
||||
#include <unordered_set>
|
||||
|
||||
namespace mbgl {
|
||||
namespace gl {
|
||||
@@ -13,40 +17,61 @@ class ShaderGroupGL final : public gfx::ShaderGroup {
|
||||
public:
|
||||
ShaderGroupGL(const ProgramParameters& programParameters_)
|
||||
: ShaderGroup(),
|
||||
programParameters(programParameters_){};
|
||||
programParameters(programParameters_) {}
|
||||
~ShaderGroupGL() noexcept override = default;
|
||||
|
||||
gfx::ShaderPtr getOrCreateShader(gfx::Context& context,
|
||||
const std::vector<std::string>& propertiesAsUniforms,
|
||||
const std::unordered_set<StringIdentity>& propertiesAsUniforms,
|
||||
std::string_view firstAttribName) override {
|
||||
constexpr auto& name = shaders::ShaderSource<ShaderID, gfx::Backend::Type::OpenGL>::name;
|
||||
constexpr auto& vert = shaders::ShaderSource<ShaderID, gfx::Backend::Type::OpenGL>::vertex;
|
||||
constexpr auto& frag = shaders::ShaderSource<ShaderID, gfx::Backend::Type::OpenGL>::fragment;
|
||||
|
||||
uint32_t key = 0;
|
||||
// Generate a map key for the specified combination of properties
|
||||
const size_t key = util::order_independent_hash(propertiesAsUniforms.begin(), propertiesAsUniforms.end());
|
||||
|
||||
// We could cache these by key here to avoid creating a string key each time, but we
|
||||
// would need another mutex. We could also push string IDs down into `ShaderGroup`.
|
||||
const std::string shaderName = getShaderName(key);
|
||||
auto shader = get<gl::ShaderProgramGL>(shaderName);
|
||||
if (shader) {
|
||||
return shader;
|
||||
}
|
||||
|
||||
// No match, we need to create the shader.
|
||||
std::string additionalDefines;
|
||||
for (unsigned int i = 0; i < propertiesAsUniforms.size(); i++) {
|
||||
if (propertiesAsUniforms[i].empty()) {
|
||||
continue;
|
||||
additionalDefines.reserve(propertiesAsUniforms.size() * 48);
|
||||
for (const auto nameID : propertiesAsUniforms) {
|
||||
// We expect the names to be prefixed by "a_", but we need just the base here.
|
||||
const auto prefixedAttrName = StringIndexer::get(nameID);
|
||||
const auto* prefix = prefixedAttrName.data();
|
||||
if (prefix[0] == 'a' && prefix[1] == '_') {
|
||||
prefix += 2;
|
||||
}
|
||||
key |= 1 << i;
|
||||
|
||||
additionalDefines += "#define HAS_UNIFORM_u_";
|
||||
additionalDefines += propertiesAsUniforms[i];
|
||||
additionalDefines += prefix;
|
||||
additionalDefines += "\n";
|
||||
}
|
||||
const std::string shaderName = std::string(name) + "#" + std::to_string(key);
|
||||
auto shader = get<gl::ShaderProgramGL>(shaderName);
|
||||
if (!shader) {
|
||||
auto& glContext = static_cast<gl::Context&>(context);
|
||||
shader = ShaderProgramGL::create(
|
||||
glContext, programParameters, shaderName, firstAttribName, vert, frag, additionalDefines);
|
||||
if (!shader || !registerShader(shader, shaderName)) {
|
||||
throw std::runtime_error("Failed to register " + shaderName + " with shader group!");
|
||||
}
|
||||
|
||||
auto& glContext = static_cast<gl::Context&>(context);
|
||||
shader = ShaderProgramGL::create(
|
||||
glContext, programParameters, shaderName, firstAttribName, vert, frag, additionalDefines);
|
||||
if (!shader || !registerShader(shader, shaderName)) {
|
||||
throw std::runtime_error("Failed to register " + shaderName + " with shader group!");
|
||||
}
|
||||
return shader;
|
||||
}
|
||||
|
||||
protected:
|
||||
std::string getShaderName(std::size_t key) {
|
||||
constexpr auto& name = shaders::ShaderSource<ShaderID, gfx::Backend::Type::OpenGL>::name;
|
||||
|
||||
// This could be more efficient.
|
||||
std::ostringstream stream;
|
||||
stream << name << '#' << key;
|
||||
return stream.str();
|
||||
}
|
||||
|
||||
private:
|
||||
ProgramParameters programParameters;
|
||||
};
|
||||
|
||||
@@ -5,8 +5,6 @@
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
|
||||
#define MLN_STRINGIZE(X) #X
|
||||
|
||||
namespace mbgl {
|
||||
namespace shaders {
|
||||
|
||||
|
||||
@@ -14,14 +14,9 @@ struct ShaderSource<BuiltIn::BackgroundShader, gfx::Backend::Type::Metal> {
|
||||
static constexpr auto vertexMainFunction = "vertexMain";
|
||||
static constexpr auto fragmentMainFunction = "fragmentMain";
|
||||
|
||||
static constexpr AttributeInfo attributes[] = {
|
||||
{0, gfx::AttributeDataType::Float3, 1, "a_pos"},
|
||||
};
|
||||
static constexpr UniformBlockInfo uniforms[] = {
|
||||
MLN_MTL_UNIFORM_BLOCK(1, true, true, BackgroundLayerUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(2, true, false, BackgroundDrawableUBO),
|
||||
};
|
||||
static constexpr TextureInfo textures[] = {};
|
||||
static const std::array<AttributeInfo, 1> attributes;
|
||||
static const std::array<UniformBlockInfo, 2> uniforms;
|
||||
static const std::array<TextureInfo, 0> textures;
|
||||
|
||||
static constexpr auto source = R"(
|
||||
#include <metal_stdlib>
|
||||
|
||||
@@ -9,11 +9,7 @@ template <>
|
||||
struct ShaderSource<BuiltIn::BackgroundPatternShader, gfx::Backend::Type::Metal>
|
||||
: public ShaderSource<BuiltIn::BackgroundShader, gfx::Backend::Type::Metal> {
|
||||
static constexpr auto name = "BackgroundPatternShader";
|
||||
static constexpr UniformBlockInfo uniforms[] = {
|
||||
{1, sizeof(BackgroundLayerUBO), true, false, "BackgroundLayerUBO"},
|
||||
{2, sizeof(BackgroundDrawableUBO), true, false, "BackgroundDrawableUBO"},
|
||||
{3, sizeof(BackgroundPatternLayerUBO), true, false, "BackgroundPatternLayerUBO"},
|
||||
};
|
||||
static const std::array<UniformBlockInfo, 3> uniforms;
|
||||
};
|
||||
|
||||
} // namespace shaders
|
||||
|
||||
@@ -14,25 +14,9 @@ struct ShaderSource<BuiltIn::CircleShader, gfx::Backend::Type::Metal> {
|
||||
static constexpr auto vertexMainFunction = "vertexMain";
|
||||
static constexpr auto fragmentMainFunction = "fragmentMain";
|
||||
|
||||
static constexpr AttributeInfo attributes[] = {
|
||||
{0, gfx::AttributeDataType::Short2, 1, "a_pos"},
|
||||
{1, gfx::AttributeDataType::Float2, 1, "a_color"},
|
||||
{2, gfx::AttributeDataType::Float2, 1, "a_radius"},
|
||||
{3, gfx::AttributeDataType::Float2, 1, "a_blur"},
|
||||
{4, gfx::AttributeDataType::Float2, 1, "a_opacity"},
|
||||
{5, gfx::AttributeDataType::Float4, 1, "a_stroke_color"},
|
||||
{6, gfx::AttributeDataType::Float2, 1, "a_stroke_width"},
|
||||
{7, gfx::AttributeDataType::Float2, 1, "a_stroke_opacity"},
|
||||
};
|
||||
static constexpr UniformBlockInfo uniforms[] = {
|
||||
MLN_MTL_UNIFORM_BLOCK(8, true, false, CircleDrawableUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(9, true, true, CirclePaintParamsUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(10, true, true, CircleEvaluatedPropsUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(11, true, false, CircleInterpolateUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(12, true, true, CirclePermutationUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(13, true, false, ExpressionInputsUBO),
|
||||
};
|
||||
static constexpr TextureInfo textures[] = {};
|
||||
static const std::array<AttributeInfo, 8> attributes;
|
||||
static const std::array<UniformBlockInfo, 6> uniforms;
|
||||
static const std::array<TextureInfo, 0> textures;
|
||||
|
||||
static constexpr auto source = R"(
|
||||
|
||||
|
||||
@@ -20,13 +20,9 @@ struct ShaderSource<BuiltIn::ClippingMaskProgram, gfx::Backend::Type::Metal> {
|
||||
static constexpr auto vertexMainFunction = "vertexMain";
|
||||
static constexpr auto fragmentMainFunction = "fragmentMain";
|
||||
|
||||
static constexpr AttributeInfo attributes[] = {
|
||||
{0, gfx::AttributeDataType::Float3, 1, "a_pos"},
|
||||
};
|
||||
static constexpr UniformBlockInfo uniforms[] = {
|
||||
MLN_MTL_UNIFORM_BLOCK(1, true, false, ClipUBO),
|
||||
};
|
||||
static constexpr TextureInfo textures[] = {};
|
||||
static const std::array<AttributeInfo, 1> attributes;
|
||||
static const std::array<UniformBlockInfo, 1> uniforms;
|
||||
static const std::array<TextureInfo, 0> textures;
|
||||
|
||||
static constexpr auto source = R"(
|
||||
#include <metal_stdlib>
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#define MLN_MTL_UNIFORM_BLOCK(idx, vert, frag, struc) \
|
||||
{ idx, vert, frag, sizeof(struc), MLN_STRINGIZE(struc) }
|
||||
|
||||
namespace mbgl {
|
||||
namespace shaders {
|
||||
|
||||
|
||||
@@ -14,24 +14,9 @@ struct ShaderSource<BuiltIn::FillShader, gfx::Backend::Type::Metal> {
|
||||
static constexpr auto vertexMainFunction = "vertexMain";
|
||||
static constexpr auto fragmentMainFunction = "fragmentMain";
|
||||
|
||||
static constexpr AttributeInfo attributes[] = {
|
||||
{0, gfx::AttributeDataType::Short2, 1, "a_pos"},
|
||||
{1, gfx::AttributeDataType::Float2, 1, "a_color"},
|
||||
{2, gfx::AttributeDataType::Float2, 1, "a_opacity"},
|
||||
|
||||
// This shader doesn't use it, but we need this so that the layer can assign the same
|
||||
// attributes to all the drawables. If/When `VertexAttributeArray::resolve` allows it,
|
||||
// this can be removed.
|
||||
{8, gfx::AttributeDataType::Float2, 1, "a_outline_color"},
|
||||
};
|
||||
static constexpr UniformBlockInfo uniforms[] = {
|
||||
MLN_MTL_UNIFORM_BLOCK(3, true, false, FillDrawableUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(4, true, true, FillEvaluatedPropsUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(5, true, false, FillInterpolateUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(6, true, true, FillPermutationUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(7, true, false, ExpressionInputsUBO),
|
||||
};
|
||||
static constexpr TextureInfo textures[] = {};
|
||||
static const std::array<AttributeInfo, 4> attributes;
|
||||
static const std::array<UniformBlockInfo, 5> uniforms;
|
||||
static const std::array<TextureInfo, 0> textures;
|
||||
|
||||
static constexpr auto source = R"(
|
||||
|
||||
@@ -104,22 +89,9 @@ struct ShaderSource<BuiltIn::FillOutlineShader, gfx::Backend::Type::Metal> {
|
||||
static constexpr auto vertexMainFunction = "vertexMain";
|
||||
static constexpr auto fragmentMainFunction = "fragmentMain";
|
||||
|
||||
static constexpr AttributeInfo attributes[] = {
|
||||
{0, gfx::AttributeDataType::Short2, 1, "a_pos"},
|
||||
{1, gfx::AttributeDataType::Float2, 1, "a_outline_color"},
|
||||
{2, gfx::AttributeDataType::Float2, 1, "a_opacity"},
|
||||
|
||||
// See `a_outline_color` in FillShader
|
||||
{8, gfx::AttributeDataType::Float2, 1, "a_color"},
|
||||
};
|
||||
static constexpr UniformBlockInfo uniforms[] = {
|
||||
MLN_MTL_UNIFORM_BLOCK(3, true, false, FillOutlineDrawableUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(4, true, true, FillOutlineEvaluatedPropsUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(5, true, false, FillOutlineInterpolateUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(6, true, true, FillOutlinePermutationUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(7, true, false, ExpressionInputsUBO),
|
||||
};
|
||||
static constexpr TextureInfo textures[] = {};
|
||||
static const std::array<AttributeInfo, 4> attributes;
|
||||
static const std::array<UniformBlockInfo, 5> uniforms;
|
||||
static const std::array<TextureInfo, 0> textures;
|
||||
|
||||
static constexpr auto source = R"(
|
||||
|
||||
@@ -203,24 +175,9 @@ struct ShaderSource<BuiltIn::FillPatternShader, gfx::Backend::Type::Metal> {
|
||||
static constexpr auto vertexMainFunction = "vertexMain";
|
||||
static constexpr auto fragmentMainFunction = "fragmentMain";
|
||||
|
||||
static constexpr AttributeInfo attributes[] = {
|
||||
{0, gfx::AttributeDataType::Short2, 1, "a_pos"},
|
||||
{1, gfx::AttributeDataType::UShort4, 1, "a_pattern_from"},
|
||||
{2, gfx::AttributeDataType::UShort4, 1, "a_pattern_to"},
|
||||
{3, gfx::AttributeDataType::Float2, 1, "a_opacity"},
|
||||
};
|
||||
static constexpr UniformBlockInfo uniforms[] = {
|
||||
MLN_MTL_UNIFORM_BLOCK(4, true, true, FillPatternDrawableUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(5, true, false, FillPatternTilePropsUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(6, true, true, FillPatternEvaluatedPropsUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(7, true, false, FillPatternInterpolateUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(8, true, true, FillPatternPermutationUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(9, true, false, ExpressionInputsUBO),
|
||||
};
|
||||
|
||||
static constexpr TextureInfo textures[] = {
|
||||
{0, "u_image"},
|
||||
};
|
||||
static const std::array<AttributeInfo, 4> attributes;
|
||||
static const std::array<UniformBlockInfo, 6> uniforms;
|
||||
static const std::array<TextureInfo, 1> textures;
|
||||
|
||||
static constexpr auto source = R"(
|
||||
|
||||
@@ -341,24 +298,9 @@ struct ShaderSource<BuiltIn::FillOutlinePatternShader, gfx::Backend::Type::Metal
|
||||
static constexpr auto vertexMainFunction = "vertexMain";
|
||||
static constexpr auto fragmentMainFunction = "fragmentMain";
|
||||
|
||||
static constexpr AttributeInfo attributes[] = {
|
||||
{0, gfx::AttributeDataType::Short2, 1, "a_pos"},
|
||||
{1, gfx::AttributeDataType::UShort4, 1, "a_pattern_from"},
|
||||
{2, gfx::AttributeDataType::UShort4, 1, "a_pattern_to"},
|
||||
{3, gfx::AttributeDataType::Float2, 1, "a_opacity"},
|
||||
};
|
||||
static constexpr UniformBlockInfo uniforms[] = {
|
||||
MLN_MTL_UNIFORM_BLOCK(4, true, true, FillOutlinePatternDrawableUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(5, true, false, FillOutlinePatternTilePropsUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(6, true, true, FillOutlinePatternEvaluatedPropsUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(7, true, false, FillOutlinePatternInterpolateUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(8, true, true, FillOutlinePatternPermutationUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(9, true, false, ExpressionInputsUBO),
|
||||
};
|
||||
|
||||
static constexpr TextureInfo textures[] = {
|
||||
{0, "u_image"},
|
||||
};
|
||||
static const std::array<AttributeInfo, 4> attributes;
|
||||
static const std::array<UniformBlockInfo, 6> uniforms;
|
||||
static const std::array<TextureInfo, 1> textures;
|
||||
|
||||
static constexpr auto source = R"(
|
||||
|
||||
|
||||
@@ -14,21 +14,9 @@ struct ShaderSource<BuiltIn::FillExtrusionShader, gfx::Backend::Type::Metal> {
|
||||
static constexpr auto vertexMainFunction = "vertexMain";
|
||||
static constexpr auto fragmentMainFunction = "fragmentMain";
|
||||
|
||||
static constexpr AttributeInfo attributes[] = {
|
||||
{0, gfx::AttributeDataType::Short2, 1, "a_pos"},
|
||||
{1, gfx::AttributeDataType::Short4, 1, "a_normal_ed"},
|
||||
{2, gfx::AttributeDataType::Float4, 1, "a_color"},
|
||||
{3, gfx::AttributeDataType::Float, 1, "a_base"},
|
||||
{4, gfx::AttributeDataType::Float, 1, "a_height"},
|
||||
};
|
||||
static constexpr UniformBlockInfo uniforms[] = {
|
||||
MLN_MTL_UNIFORM_BLOCK(5, true, false, FillExtrusionDrawableUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(6, true, false, FillExtrusionDrawablePropsUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(7, true, false, FillExtrusionInterpolateUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(8, true, false, FillExtrusionPermutationUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(9, true, false, ExpressionInputsUBO),
|
||||
};
|
||||
static constexpr TextureInfo textures[] = {};
|
||||
static const std::array<AttributeInfo, 5> attributes;
|
||||
static const std::array<UniformBlockInfo, 5> uniforms;
|
||||
static const std::array<TextureInfo, 0> textures;
|
||||
|
||||
static constexpr auto source = R"(
|
||||
struct alignas(16) FillExtrusionInterpolateUBO {
|
||||
|
||||
@@ -14,9 +14,9 @@ struct ShaderSource<BuiltIn::FillExtrusionPatternShader, gfx::Backend::Type::Met
|
||||
static constexpr auto vertexMainFunction = "vertexMain";
|
||||
static constexpr auto fragmentMainFunction = "fragmentMain";
|
||||
|
||||
static constexpr AttributeInfo attributes[] = {};
|
||||
static constexpr UniformBlockInfo uniforms[] = {};
|
||||
static constexpr TextureInfo textures[] = {};
|
||||
static const std::array<AttributeInfo, 0> attributes;
|
||||
static const std::array<UniformBlockInfo, 0> uniforms;
|
||||
static const std::array<TextureInfo, 0> textures;
|
||||
|
||||
static constexpr auto source = R"(
|
||||
)";
|
||||
|
||||
@@ -14,19 +14,9 @@ struct ShaderSource<BuiltIn::HeatmapShader, gfx::Backend::Type::Metal> {
|
||||
static constexpr auto vertexMainFunction = "vertexMain";
|
||||
static constexpr auto fragmentMainFunction = "fragmentMain";
|
||||
|
||||
static constexpr AttributeInfo attributes[] = {
|
||||
{0, gfx::AttributeDataType::Short2, 1, "a_pos"},
|
||||
{1, gfx::AttributeDataType::Float2, 1, "a_weight"},
|
||||
{2, gfx::AttributeDataType::Float2, 1, "a_radius"},
|
||||
};
|
||||
static constexpr UniformBlockInfo uniforms[] = {
|
||||
MLN_MTL_UNIFORM_BLOCK(3, true, false, HeatmapDrawableUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(4, true, true, HeatmapEvaluatedPropsUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(5, true, false, HeatmapInterpolateUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(6, true, true, HeatmapPermutationUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(7, true, false, ExpressionInputsUBO),
|
||||
};
|
||||
static constexpr TextureInfo textures[] = {};
|
||||
static const std::array<AttributeInfo, 3> attributes;
|
||||
static const std::array<UniformBlockInfo, 5> uniforms;
|
||||
static const std::array<TextureInfo, 0> textures;
|
||||
|
||||
static constexpr auto source = R"(
|
||||
|
||||
|
||||
@@ -14,16 +14,10 @@ struct ShaderSource<BuiltIn::HeatmapTextureShader, gfx::Backend::Type::Metal> {
|
||||
static constexpr auto vertexMainFunction = "vertexMain";
|
||||
static constexpr auto fragmentMainFunction = "fragmentMain";
|
||||
|
||||
static constexpr AttributeInfo attributes[] = {
|
||||
{0, gfx::AttributeDataType::Short2, 1, "a_pos"},
|
||||
};
|
||||
static constexpr UniformBlockInfo uniforms[] = {
|
||||
MLN_MTL_UNIFORM_BLOCK(1, true, true, HeatmapTextureDrawableUBO),
|
||||
};
|
||||
static constexpr TextureInfo textures[] = {
|
||||
{0, "u_image"},
|
||||
{1, "u_color_ramp"},
|
||||
};
|
||||
static const std::array<AttributeInfo, 1> attributes;
|
||||
static const std::array<UniformBlockInfo, 1> uniforms;
|
||||
static const std::array<TextureInfo, 2> textures;
|
||||
|
||||
static constexpr auto source = R"(
|
||||
|
||||
struct VertexStage {
|
||||
|
||||
@@ -14,17 +14,9 @@ struct ShaderSource<BuiltIn::HillshadeShader, gfx::Backend::Type::Metal> {
|
||||
static constexpr auto vertexMainFunction = "vertexMain";
|
||||
static constexpr auto fragmentMainFunction = "fragmentMain";
|
||||
|
||||
static constexpr AttributeInfo attributes[] = {
|
||||
{0, gfx::AttributeDataType::Short2, 1, "a_pos"},
|
||||
{1, gfx::AttributeDataType::Short2, 1, "a_texture_pos"},
|
||||
};
|
||||
static constexpr UniformBlockInfo uniforms[] = {
|
||||
MLN_MTL_UNIFORM_BLOCK(2, true, true, HillshadeDrawableUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(3, false, true, HillshadeEvaluatedPropsUBO),
|
||||
};
|
||||
static constexpr TextureInfo textures[] = {
|
||||
{0, "u_image"},
|
||||
};
|
||||
static const std::array<AttributeInfo, 2> attributes;
|
||||
static const std::array<UniformBlockInfo, 2> uniforms;
|
||||
static const std::array<TextureInfo, 1> textures;
|
||||
|
||||
static constexpr auto source = R"(
|
||||
|
||||
|
||||
@@ -14,16 +14,10 @@ struct ShaderSource<BuiltIn::HillshadePrepareShader, gfx::Backend::Type::Metal>
|
||||
static constexpr auto vertexMainFunction = "vertexMain";
|
||||
static constexpr auto fragmentMainFunction = "fragmentMain";
|
||||
|
||||
static constexpr AttributeInfo attributes[] = {
|
||||
{0, gfx::AttributeDataType::Short2, 1, "a_pos"},
|
||||
{1, gfx::AttributeDataType::Short2, 1, "a_texture_pos"},
|
||||
};
|
||||
static constexpr UniformBlockInfo uniforms[] = {
|
||||
MLN_MTL_UNIFORM_BLOCK(2, true, true, HillshadePrepareDrawableUBO),
|
||||
};
|
||||
static constexpr TextureInfo textures[] = {
|
||||
{0, "u_image"},
|
||||
};
|
||||
static const std::array<AttributeInfo, 2> attributes;
|
||||
static const std::array<UniformBlockInfo, 1> uniforms;
|
||||
static const std::array<TextureInfo, 1> textures;
|
||||
|
||||
static constexpr auto source = R"(
|
||||
|
||||
struct VertexStage {
|
||||
|
||||
@@ -14,24 +14,9 @@ struct ShaderSource<BuiltIn::LineShader, gfx::Backend::Type::Metal> {
|
||||
static constexpr auto vertexMainFunction = "vertexMain";
|
||||
static constexpr auto fragmentMainFunction = "fragmentMain";
|
||||
|
||||
static constexpr AttributeInfo attributes[] = {
|
||||
{0, gfx::AttributeDataType::Short2, 1, "a_pos_normal"},
|
||||
{1, gfx::AttributeDataType::UByte4, 1, "a_data"},
|
||||
{2, gfx::AttributeDataType::Float4, 1, "a_color"},
|
||||
{3, gfx::AttributeDataType::Float2, 1, "a_blur"},
|
||||
{4, gfx::AttributeDataType::Float2, 1, "a_opacity"},
|
||||
{5, gfx::AttributeDataType::Float2, 1, "a_gapwidth"},
|
||||
{6, gfx::AttributeDataType::Float2, 1, "a_offset"},
|
||||
{7, gfx::AttributeDataType::Float2, 1, "a_width"},
|
||||
};
|
||||
static constexpr UniformBlockInfo uniforms[] = {
|
||||
MLN_MTL_UNIFORM_BLOCK(8, true, true, LineUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(9, true, false, LinePropertiesUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(10, true, false, LineInterpolationUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(11, true, true, LinePermutationUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(12, true, false, ExpressionInputsUBO),
|
||||
};
|
||||
static constexpr TextureInfo textures[] = {};
|
||||
static const std::array<AttributeInfo, 8> attributes;
|
||||
static const std::array<UniformBlockInfo, 5> uniforms;
|
||||
static const std::array<TextureInfo, 0> textures;
|
||||
|
||||
static constexpr auto source = R"(
|
||||
|
||||
@@ -143,28 +128,9 @@ struct ShaderSource<BuiltIn::LinePatternShader, gfx::Backend::Type::Metal> {
|
||||
static constexpr auto vertexMainFunction = "vertexMain";
|
||||
static constexpr auto fragmentMainFunction = "fragmentMain";
|
||||
|
||||
static constexpr AttributeInfo attributes[] = {
|
||||
{0, gfx::AttributeDataType::Short2, 1, "a_pos_normal"},
|
||||
{1, gfx::AttributeDataType::UByte4, 1, "a_data"},
|
||||
{2, gfx::AttributeDataType::Float2, 1, "a_blur"},
|
||||
{3, gfx::AttributeDataType::Float2, 1, "a_opacity"},
|
||||
{4, gfx::AttributeDataType::Float2, 1, "a_gapwidth"},
|
||||
{5, gfx::AttributeDataType::Float2, 1, "a_offset"},
|
||||
{6, gfx::AttributeDataType::Float2, 1, "a_width"},
|
||||
{7, gfx::AttributeDataType::UShort4, 1, "a_pattern_from"},
|
||||
{8, gfx::AttributeDataType::UShort4, 1, "a_pattern_to"},
|
||||
};
|
||||
static constexpr UniformBlockInfo uniforms[] = {
|
||||
MLN_MTL_UNIFORM_BLOCK(9, true, true, LinePatternUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(10, true, false, LinePatternPropertiesUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(11, true, false, LinePatternInterpolationUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(12, true, false, LinePatternTilePropertiesUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(13, true, true, LinePermutationUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(14, true, false, ExpressionInputsUBO),
|
||||
};
|
||||
static constexpr TextureInfo textures[] = {
|
||||
{0, "u_image"},
|
||||
};
|
||||
static const std::array<AttributeInfo, 9> attributes;
|
||||
static const std::array<UniformBlockInfo, 6> uniforms;
|
||||
static const std::array<TextureInfo, 1> textures;
|
||||
|
||||
static constexpr auto source = R"(
|
||||
|
||||
|
||||
@@ -14,25 +14,9 @@ struct ShaderSource<BuiltIn::LineGradientShader, gfx::Backend::Type::Metal> {
|
||||
static constexpr auto vertexMainFunction = "vertexMain";
|
||||
static constexpr auto fragmentMainFunction = "fragmentMain";
|
||||
|
||||
static constexpr AttributeInfo attributes[] = {
|
||||
{0, gfx::AttributeDataType::Short2, 1, "a_pos_normal"},
|
||||
{1, gfx::AttributeDataType::UByte4, 1, "a_data"},
|
||||
{2, gfx::AttributeDataType::Float2, 1, "a_blur"},
|
||||
{3, gfx::AttributeDataType::Float2, 1, "a_opacity"},
|
||||
{4, gfx::AttributeDataType::Float2, 1, "a_gapwidth"},
|
||||
{5, gfx::AttributeDataType::Float2, 1, "a_offset"},
|
||||
{6, gfx::AttributeDataType::Float2, 1, "a_width"},
|
||||
};
|
||||
static constexpr UniformBlockInfo uniforms[] = {
|
||||
MLN_MTL_UNIFORM_BLOCK(7, true, true, LineGradientUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(8, true, false, LineGradientPropertiesUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(9, true, false, LineGradientInterpolationUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(10, true, true, LinePermutationUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(11, true, false, ExpressionInputsUBO),
|
||||
};
|
||||
static constexpr TextureInfo textures[] = {
|
||||
{0, "u_image"},
|
||||
};
|
||||
static const std::array<AttributeInfo, 7> attributes;
|
||||
static const std::array<UniformBlockInfo, 5> uniforms;
|
||||
static const std::array<TextureInfo, 1> textures;
|
||||
|
||||
static constexpr auto source = R"(
|
||||
struct VertexStage {
|
||||
|
||||
@@ -14,17 +14,10 @@ struct ShaderSource<BuiltIn::RasterShader, gfx::Backend::Type::Metal> {
|
||||
static constexpr auto vertexMainFunction = "vertexMain";
|
||||
static constexpr auto fragmentMainFunction = "fragmentMain";
|
||||
|
||||
static constexpr AttributeInfo attributes[] = {
|
||||
{0, gfx::AttributeDataType::Short2, 1, "a_pos"},
|
||||
{1, gfx::AttributeDataType::Short2, 1, "a_texture_pos"},
|
||||
};
|
||||
static constexpr UniformBlockInfo uniforms[] = {
|
||||
MLN_MTL_UNIFORM_BLOCK(2, true, true, RasterDrawableUBO),
|
||||
};
|
||||
static constexpr TextureInfo textures[] = {
|
||||
{0, "u_image0"},
|
||||
{1, "u_image1"},
|
||||
};
|
||||
static const std::array<AttributeInfo, 2> attributes;
|
||||
static const std::array<UniformBlockInfo, 1> uniforms;
|
||||
static const std::array<TextureInfo, 2> textures;
|
||||
|
||||
static constexpr auto source = R"(
|
||||
|
||||
struct VertexStage {
|
||||
|
||||
@@ -22,32 +22,20 @@ public:
|
||||
~ShaderGroup() noexcept override = default;
|
||||
|
||||
gfx::ShaderPtr getOrCreateShader(gfx::Context& gfxContext,
|
||||
const std::vector<std::string>& propertiesAsUniforms,
|
||||
const std::unordered_set<StringIdentity>& propertiesAsUniforms,
|
||||
std::string_view /*firstAttribName*/) override {
|
||||
constexpr auto& name = shaders::ShaderSource<ShaderID, gfx::Backend::Type::Metal>::name;
|
||||
constexpr auto& source = shaders::ShaderSource<ShaderID, gfx::Backend::Type::Metal>::source;
|
||||
constexpr auto& vertMain = shaders::ShaderSource<ShaderID, gfx::Backend::Type::Metal>::vertexMainFunction;
|
||||
constexpr auto& fragMain = shaders::ShaderSource<ShaderID, gfx::Backend::Type::Metal>::fragmentMainFunction;
|
||||
|
||||
uint32_t key = 0;
|
||||
assert(propertiesAsUniforms.size() < 32);
|
||||
std::unordered_map<std::string, std::string> additionalDefines(propertiesAsUniforms.size());
|
||||
for (unsigned int i = 0; i < propertiesAsUniforms.size(); i++) {
|
||||
if (!propertiesAsUniforms[i].empty()) {
|
||||
key |= 1U << i;
|
||||
auto name = std::string("HAS_UNIFORM_u_") + propertiesAsUniforms[i];
|
||||
additionalDefines.insert(std::make_pair(std::move(name), "1"));
|
||||
}
|
||||
}
|
||||
|
||||
const std::string shaderName = std::string(name); // + "#" + std::to_string(key);
|
||||
const std::string shaderName = std::string(name);
|
||||
const auto shaderSource = std::string(shaders::prelude) + source;
|
||||
|
||||
auto shader = get<mtl::ShaderProgram>(shaderName);
|
||||
if (!shader) {
|
||||
auto& context = static_cast<Context&>(gfxContext);
|
||||
shader = context.createProgram(
|
||||
shaderName, shaderSource, vertMain, fragMain, programParameters, additionalDefines);
|
||||
shader = context.createProgram(shaderName, shaderSource, vertMain, fragMain, programParameters, {});
|
||||
assert(shader);
|
||||
if (!shader || !registerShader(shader, shaderName)) {
|
||||
assert(false);
|
||||
|
||||
@@ -15,21 +15,27 @@
|
||||
namespace mbgl {
|
||||
namespace shaders {
|
||||
struct AttributeInfo {
|
||||
AttributeInfo(std::size_t index, gfx::AttributeDataType dataType, std::size_t count, std::string_view name);
|
||||
std::size_t index;
|
||||
gfx::AttributeDataType dataType;
|
||||
std::size_t count;
|
||||
std::string_view name;
|
||||
StringIdentity nameID;
|
||||
};
|
||||
struct UniformBlockInfo {
|
||||
UniformBlockInfo(std::size_t index, bool vertex, bool fragment, std::size_t size, std::string_view name);
|
||||
std::size_t index;
|
||||
bool vertex;
|
||||
bool fragment;
|
||||
std::size_t size;
|
||||
std::string_view name;
|
||||
StringIdentity nameID;
|
||||
};
|
||||
struct TextureInfo {
|
||||
TextureInfo(std::size_t index, std::string_view name);
|
||||
std::size_t index;
|
||||
std::string_view name;
|
||||
StringIdentity nameID;
|
||||
};
|
||||
} // namespace shaders
|
||||
namespace mtl {
|
||||
|
||||
@@ -14,28 +14,9 @@ struct ShaderSource<BuiltIn::SymbolIconShader, gfx::Backend::Type::Metal> {
|
||||
static constexpr auto vertexMainFunction = "vertexMain";
|
||||
static constexpr auto fragmentMainFunction = "fragmentMain";
|
||||
|
||||
static constexpr AttributeInfo attributes[] = {
|
||||
// always attributes
|
||||
{0, gfx::AttributeDataType::Short4, 1, "a_pos_offset"},
|
||||
{1, gfx::AttributeDataType::UShort4, 1, "a_data"},
|
||||
{2, gfx::AttributeDataType::Short4, 1, "a_pixeloffset"},
|
||||
{3, gfx::AttributeDataType::Float3, 1, "a_projected_pos"},
|
||||
{4, gfx::AttributeDataType::Float, 1, "a_fade_opacity"},
|
||||
|
||||
// sometimes uniforms
|
||||
{5, gfx::AttributeDataType::Float, 1, "a_opacity"},
|
||||
};
|
||||
static constexpr UniformBlockInfo uniforms[] = {
|
||||
MLN_MTL_UNIFORM_BLOCK(8, true, true, SymbolDrawableUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(9, true, true, SymbolDrawablePaintUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(10, true, false, SymbolDrawableTilePropsUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(11, true, false, SymbolDrawableInterpolateUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(12, true, true, SymbolPermutationUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(13, true, false, ExpressionInputsUBO),
|
||||
};
|
||||
static constexpr TextureInfo textures[] = {
|
||||
{0, "u_texture"},
|
||||
};
|
||||
static const std::array<AttributeInfo, 6> attributes;
|
||||
static const std::array<UniformBlockInfo, 6> uniforms;
|
||||
static const std::array<TextureInfo, 1> textures;
|
||||
|
||||
static constexpr auto source = R"(
|
||||
struct VertexStage {
|
||||
|
||||
@@ -14,32 +14,9 @@ struct ShaderSource<BuiltIn::SymbolSDFIconShader, gfx::Backend::Type::Metal> {
|
||||
static constexpr auto vertexMainFunction = "vertexMain";
|
||||
static constexpr auto fragmentMainFunction = "fragmentMain";
|
||||
|
||||
static constexpr AttributeInfo attributes[] = {
|
||||
// always attributes
|
||||
{0, gfx::AttributeDataType::Short4, 1, "a_pos_offset"},
|
||||
{1, gfx::AttributeDataType::UShort4, 1, "a_data"},
|
||||
{2, gfx::AttributeDataType::Short4, 1, "a_pixeloffset"},
|
||||
{3, gfx::AttributeDataType::Float3, 1, "a_projected_pos"},
|
||||
{4, gfx::AttributeDataType::Float, 1, "a_fade_opacity"},
|
||||
|
||||
// sometimes uniforms
|
||||
{5, gfx::AttributeDataType::Float4, 1, "a_fill_color"},
|
||||
{6, gfx::AttributeDataType::Float4, 1, "a_halo_color"},
|
||||
{7, gfx::AttributeDataType::Float, 1, "a_opacity"},
|
||||
{8, gfx::AttributeDataType::Float, 1, "a_halo_width"},
|
||||
{9, gfx::AttributeDataType::Float, 1, "a_halo_blur"},
|
||||
};
|
||||
static constexpr UniformBlockInfo uniforms[] = {
|
||||
MLN_MTL_UNIFORM_BLOCK(10, true, true, SymbolDrawableUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(11, true, false, SymbolDrawablePaintUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(12, true, true, SymbolDrawableTilePropsUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(13, true, false, SymbolDrawableInterpolateUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(14, true, true, SymbolPermutationUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(15, true, false, ExpressionInputsUBO),
|
||||
};
|
||||
static constexpr TextureInfo textures[] = {
|
||||
{0, "u_texture"},
|
||||
};
|
||||
static const std::array<AttributeInfo, 10> attributes;
|
||||
static const std::array<UniformBlockInfo, 6> uniforms;
|
||||
static const std::array<TextureInfo, 1> textures;
|
||||
|
||||
static constexpr auto source = R"(
|
||||
struct VertexStage {
|
||||
|
||||
@@ -14,32 +14,9 @@ struct ShaderSource<BuiltIn::SymbolTextAndIconShader, gfx::Backend::Type::Metal>
|
||||
static constexpr auto vertexMainFunction = "vertexMain";
|
||||
static constexpr auto fragmentMainFunction = "fragmentMain";
|
||||
|
||||
static constexpr AttributeInfo attributes[] = {
|
||||
// always attributes
|
||||
{0, gfx::AttributeDataType::Short4, 1, "a_pos_offset"},
|
||||
{1, gfx::AttributeDataType::UShort4, 1, "a_data"},
|
||||
{2, gfx::AttributeDataType::Float3, 1, "a_projected_pos"},
|
||||
{3, gfx::AttributeDataType::Float, 1, "a_fade_opacity"},
|
||||
|
||||
// sometimes uniforms
|
||||
{4, gfx::AttributeDataType::Float4, 1, "a_fill_color"},
|
||||
{5, gfx::AttributeDataType::Float4, 1, "a_halo_color"},
|
||||
{6, gfx::AttributeDataType::Float, 1, "a_opacity"},
|
||||
{7, gfx::AttributeDataType::Float, 1, "a_halo_width"},
|
||||
{8, gfx::AttributeDataType::Float, 1, "a_halo_blur"},
|
||||
};
|
||||
static constexpr UniformBlockInfo uniforms[] = {
|
||||
MLN_MTL_UNIFORM_BLOCK(9, true, true, SymbolDrawableUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(10, true, false, SymbolDrawablePaintUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(11, true, true, SymbolDrawableTilePropsUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(12, true, false, SymbolDrawableInterpolateUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(13, true, true, SymbolPermutationUBO),
|
||||
MLN_MTL_UNIFORM_BLOCK(14, true, false, ExpressionInputsUBO),
|
||||
};
|
||||
static constexpr TextureInfo textures[] = {
|
||||
{0, "u_texture"},
|
||||
{1, "u_texture_icon"},
|
||||
};
|
||||
static const std::array<AttributeInfo, 9> attributes;
|
||||
static const std::array<UniformBlockInfo, 6> uniforms;
|
||||
static const std::array<TextureInfo, 2> textures;
|
||||
|
||||
static constexpr auto source = R"(
|
||||
#define SDF 1.0
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
using StringIdentity = size_t;
|
||||
using StringIdentity = std::size_t;
|
||||
|
||||
class StringIndexer {
|
||||
public:
|
||||
|
||||
@@ -17,7 +17,8 @@ std::size_t VertexAttribute::getCount() const {
|
||||
return sharedRawData ? sharedRawData->getRawCount() : items.size();
|
||||
}
|
||||
|
||||
std::unique_ptr<VertexAttribute> VertexAttributeArray::nullref = nullptr;
|
||||
const std::unique_ptr<VertexAttribute> VertexAttributeArray::nullref;
|
||||
const std::string VertexAttributeArray::attributePrefix = "a_";
|
||||
|
||||
VertexAttributeArray::VertexAttributeArray(VertexAttributeArray&& other)
|
||||
: attrs(std::move(other.attrs)) {}
|
||||
|
||||
@@ -489,12 +489,11 @@ gfx::UniformBufferPtr Context::createUniformBuffer(const void* data, std::size_t
|
||||
}
|
||||
|
||||
gfx::ShaderProgramBasePtr Context::getGenericShader(gfx::ShaderRegistry& shaders, const std::string& name) {
|
||||
std::vector<std::string> emptyProperties(0);
|
||||
auto shaderGroup = shaders.getShaderGroup(name);
|
||||
if (!shaderGroup) {
|
||||
return nullptr;
|
||||
}
|
||||
return std::static_pointer_cast<gfx::ShaderProgramBase>(shaderGroup->getOrCreateShader(*this, emptyProperties));
|
||||
return std::static_pointer_cast<gfx::ShaderProgramBase>(shaderGroup->getOrCreateShader(*this, {}));
|
||||
}
|
||||
|
||||
TileLayerGroupPtr Context::createTileLayerGroup(int32_t layerIndex, std::size_t initialCapacity, std::string name) {
|
||||
|
||||
@@ -122,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;
|
||||
}
|
||||
|
||||
@@ -43,6 +43,7 @@ void DrawableGLBuilder::init() {
|
||||
impl->buildIndexes.clear();
|
||||
impl->segments.clear();
|
||||
impl->vertices.clear();
|
||||
textures.clear();
|
||||
}
|
||||
|
||||
} // namespace gl
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -43,6 +43,7 @@ void DrawableBuilder::init() {
|
||||
impl->buildIndexes.clear();
|
||||
impl->segments.clear();
|
||||
impl->vertices.clear();
|
||||
textures.clear();
|
||||
}
|
||||
|
||||
} // namespace mtl
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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)},
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -75,8 +75,7 @@ private:
|
||||
using HillshadeVertexVector = gfx::VertexVector<HillshadeLayoutVertex>;
|
||||
std::shared_ptr<HillshadeVertexVector> staticDataSharedVertices;
|
||||
|
||||
HillshadeLayerTweakerPtr tweaker;
|
||||
bool overdrawInspector = false;
|
||||
LayerTweakerPtr prepareLayerTweaker;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
17
src/mbgl/shaders/mtl/background.cpp
Normal file
17
src/mbgl/shaders/mtl/background.cpp
Normal file
@@ -0,0 +1,17 @@
|
||||
#include <mbgl/shaders/mtl/background.hpp>
|
||||
#include <mbgl/shaders/background_layer_ubo.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace shaders {
|
||||
|
||||
const std::array<AttributeInfo, 1> ShaderSource<BuiltIn::BackgroundShader, gfx::Backend::Type::Metal>::attributes = {
|
||||
AttributeInfo{0, gfx::AttributeDataType::Float3, 1, "a_pos"},
|
||||
};
|
||||
const std::array<UniformBlockInfo, 2> ShaderSource<BuiltIn::BackgroundShader, gfx::Backend::Type::Metal>::uniforms = {
|
||||
UniformBlockInfo{1, true, true, sizeof(BackgroundLayerUBO), "BackgroundLayerUBO"},
|
||||
UniformBlockInfo{2, true, false, sizeof(BackgroundDrawableUBO), "BackgroundDrawableUBO"},
|
||||
};
|
||||
const std::array<TextureInfo, 0> ShaderSource<BuiltIn::BackgroundShader, gfx::Backend::Type::Metal>::textures = {};
|
||||
|
||||
} // namespace shaders
|
||||
} // namespace mbgl
|
||||
14
src/mbgl/shaders/mtl/background_pattern.cpp
Normal file
14
src/mbgl/shaders/mtl/background_pattern.cpp
Normal file
@@ -0,0 +1,14 @@
|
||||
#include <mbgl/shaders/mtl/background_pattern.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace shaders {
|
||||
|
||||
const std::array<UniformBlockInfo, 3>
|
||||
ShaderSource<BuiltIn::BackgroundPatternShader, gfx::Backend::Type::Metal>::uniforms = {
|
||||
UniformBlockInfo{1, sizeof(BackgroundLayerUBO), true, false, "BackgroundLayerUBO"},
|
||||
UniformBlockInfo{2, sizeof(BackgroundDrawableUBO), true, false, "BackgroundDrawableUBO"},
|
||||
UniformBlockInfo{3, sizeof(BackgroundPatternLayerUBO), true, false, "BackgroundPatternLayerUBO"},
|
||||
};
|
||||
|
||||
} // namespace shaders
|
||||
} // namespace mbgl
|
||||
27
src/mbgl/shaders/mtl/circle.cpp
Normal file
27
src/mbgl/shaders/mtl/circle.cpp
Normal file
@@ -0,0 +1,27 @@
|
||||
#include <mbgl/shaders/mtl/circle.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace shaders {
|
||||
|
||||
const std::array<AttributeInfo, 8> ShaderSource<BuiltIn::CircleShader, gfx::Backend::Type::Metal>::attributes = {
|
||||
AttributeInfo{0, gfx::AttributeDataType::Short2, 1, "a_pos"},
|
||||
AttributeInfo{1, gfx::AttributeDataType::Float2, 1, "a_color"},
|
||||
AttributeInfo{2, gfx::AttributeDataType::Float2, 1, "a_radius"},
|
||||
AttributeInfo{3, gfx::AttributeDataType::Float2, 1, "a_blur"},
|
||||
AttributeInfo{4, gfx::AttributeDataType::Float2, 1, "a_opacity"},
|
||||
AttributeInfo{5, gfx::AttributeDataType::Float4, 1, "a_stroke_color"},
|
||||
AttributeInfo{6, gfx::AttributeDataType::Float2, 1, "a_stroke_width"},
|
||||
AttributeInfo{7, gfx::AttributeDataType::Float2, 1, "a_stroke_opacity"},
|
||||
};
|
||||
const std::array<UniformBlockInfo, 6> ShaderSource<BuiltIn::CircleShader, gfx::Backend::Type::Metal>::uniforms = {
|
||||
UniformBlockInfo{8, true, false, sizeof(CircleDrawableUBO), "CircleDrawableUBO"},
|
||||
UniformBlockInfo{9, true, true, sizeof(CirclePaintParamsUBO), "CirclePaintParamsUBO"},
|
||||
UniformBlockInfo{10, true, true, sizeof(CircleEvaluatedPropsUBO), "CircleEvaluatedPropsUBO"},
|
||||
UniformBlockInfo{11, true, false, sizeof(CircleInterpolateUBO), "CircleInterpolateUBO"},
|
||||
UniformBlockInfo{12, true, true, sizeof(CirclePermutationUBO), "CirclePermutationUBO"},
|
||||
UniformBlockInfo{13, true, false, sizeof(ExpressionInputsUBO), "ExpressionInputsUBO"},
|
||||
};
|
||||
const std::array<TextureInfo, 0> ShaderSource<BuiltIn::CircleShader, gfx::Backend::Type::Metal>::textures = {};
|
||||
|
||||
} // namespace shaders
|
||||
} // namespace mbgl
|
||||
16
src/mbgl/shaders/mtl/clipping_mask.cpp
Normal file
16
src/mbgl/shaders/mtl/clipping_mask.cpp
Normal file
@@ -0,0 +1,16 @@
|
||||
#include <mbgl/shaders/mtl/clipping_mask.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace shaders {
|
||||
|
||||
const std::array<AttributeInfo, 1> ShaderSource<BuiltIn::ClippingMaskProgram, gfx::Backend::Type::Metal>::attributes = {
|
||||
AttributeInfo{0, gfx::AttributeDataType::Float3, 1, "a_pos"},
|
||||
};
|
||||
const std::array<UniformBlockInfo, 1> ShaderSource<BuiltIn::ClippingMaskProgram, gfx::Backend::Type::Metal>::uniforms =
|
||||
{
|
||||
UniformBlockInfo{1, true, false, sizeof(ClipUBO), "ClipUBO"},
|
||||
};
|
||||
const std::array<TextureInfo, 0> ShaderSource<BuiltIn::ClippingMaskProgram, gfx::Backend::Type::Metal>::textures = {};
|
||||
|
||||
} // namespace shaders
|
||||
} // namespace mbgl
|
||||
82
src/mbgl/shaders/mtl/fill.cpp
Normal file
82
src/mbgl/shaders/mtl/fill.cpp
Normal file
@@ -0,0 +1,82 @@
|
||||
#include <mbgl/shaders/mtl/fill.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace shaders {
|
||||
|
||||
const std::array<AttributeInfo, 4> ShaderSource<BuiltIn::FillShader, gfx::Backend::Type::Metal>::attributes = {
|
||||
AttributeInfo{0, gfx::AttributeDataType::Short2, 1, "a_pos"},
|
||||
AttributeInfo{1, gfx::AttributeDataType::Float2, 1, "a_color"},
|
||||
AttributeInfo{2, gfx::AttributeDataType::Float2, 1, "a_opacity"},
|
||||
|
||||
// This shader doesn't use it, but we need this so that the layer can assign the same
|
||||
// attributes to all the drawables. If/When `VertexAttributeArray::resolve` allows it,
|
||||
// this can be removed.
|
||||
AttributeInfo{8, gfx::AttributeDataType::Float2, 1, "a_outline_color"},
|
||||
};
|
||||
const std::array<UniformBlockInfo, 5> ShaderSource<BuiltIn::FillShader, gfx::Backend::Type::Metal>::uniforms = {
|
||||
UniformBlockInfo{3, true, false, sizeof(FillDrawableUBO), "FillDrawableUBO"},
|
||||
UniformBlockInfo{4, true, true, sizeof(FillEvaluatedPropsUBO), "FillEvaluatedPropsUBO"},
|
||||
UniformBlockInfo{5, true, false, sizeof(FillInterpolateUBO), "FillInterpolateUBO"},
|
||||
UniformBlockInfo{6, true, true, sizeof(FillPermutationUBO), "FillPermutationUBO"},
|
||||
UniformBlockInfo{7, true, false, sizeof(ExpressionInputsUBO), "ExpressionInputsUBO"},
|
||||
};
|
||||
const std::array<TextureInfo, 0> ShaderSource<BuiltIn::FillShader, gfx::Backend::Type::Metal>::textures = {};
|
||||
|
||||
const std::array<AttributeInfo, 4> ShaderSource<BuiltIn::FillOutlineShader, gfx::Backend::Type::Metal>::attributes = {
|
||||
AttributeInfo{0, gfx::AttributeDataType::Short2, 1, "a_pos"},
|
||||
AttributeInfo{1, gfx::AttributeDataType::Float2, 1, "a_outline_color"},
|
||||
AttributeInfo{2, gfx::AttributeDataType::Float2, 1, "a_opacity"},
|
||||
|
||||
// See `a_outline_color` in FillShader
|
||||
AttributeInfo{8, gfx::AttributeDataType::Float2, 1, "a_color"},
|
||||
};
|
||||
const std::array<UniformBlockInfo, 5> ShaderSource<BuiltIn::FillOutlineShader, gfx::Backend::Type::Metal>::uniforms = {
|
||||
UniformBlockInfo{3, true, false, sizeof(FillOutlineDrawableUBO), "FillOutlineDrawableUBO"},
|
||||
UniformBlockInfo{4, true, true, sizeof(FillOutlineEvaluatedPropsUBO), "FillOutlineEvaluatedPropsUBO"},
|
||||
UniformBlockInfo{5, true, false, sizeof(FillOutlineInterpolateUBO), "FillOutlineInterpolateUBO"},
|
||||
UniformBlockInfo{6, true, true, sizeof(FillOutlinePermutationUBO), "FillOutlinePermutationUBO"},
|
||||
UniformBlockInfo{7, true, false, sizeof(ExpressionInputsUBO), "ExpressionInputsUBO"},
|
||||
};
|
||||
const std::array<TextureInfo, 0> ShaderSource<BuiltIn::FillOutlineShader, gfx::Backend::Type::Metal>::textures = {};
|
||||
|
||||
const std::array<AttributeInfo, 4> ShaderSource<BuiltIn::FillPatternShader, gfx::Backend::Type::Metal>::attributes = {
|
||||
AttributeInfo{0, gfx::AttributeDataType::Short2, 1, "a_pos"},
|
||||
AttributeInfo{1, gfx::AttributeDataType::UShort4, 1, "a_pattern_from"},
|
||||
AttributeInfo{2, gfx::AttributeDataType::UShort4, 1, "a_pattern_to"},
|
||||
AttributeInfo{3, gfx::AttributeDataType::Float2, 1, "a_opacity"},
|
||||
};
|
||||
const std::array<UniformBlockInfo, 6> ShaderSource<BuiltIn::FillPatternShader, gfx::Backend::Type::Metal>::uniforms = {
|
||||
UniformBlockInfo{4, true, true, sizeof(FillPatternDrawableUBO), "FillPatternDrawableUBO"},
|
||||
UniformBlockInfo{5, true, false, sizeof(FillPatternTilePropsUBO), "FillPatternTilePropsUBO"},
|
||||
UniformBlockInfo{6, true, true, sizeof(FillPatternEvaluatedPropsUBO), "FillPatternEvaluatedPropsUBO"},
|
||||
UniformBlockInfo{7, true, false, sizeof(FillPatternInterpolateUBO), "FillPatternInterpolateUBO"},
|
||||
UniformBlockInfo{8, true, true, sizeof(FillPatternPermutationUBO), "FillPatternPermutationUBO"},
|
||||
UniformBlockInfo{9, true, false, sizeof(ExpressionInputsUBO), "ExpressionInputsUBO"},
|
||||
};
|
||||
const std::array<TextureInfo, 1> ShaderSource<BuiltIn::FillPatternShader, gfx::Backend::Type::Metal>::textures = {
|
||||
TextureInfo{0, "u_image"},
|
||||
};
|
||||
|
||||
const std::array<AttributeInfo, 4>
|
||||
ShaderSource<BuiltIn::FillOutlinePatternShader, gfx::Backend::Type::Metal>::attributes = {
|
||||
AttributeInfo{0, gfx::AttributeDataType::Short2, 1, "a_pos"},
|
||||
AttributeInfo{1, gfx::AttributeDataType::UShort4, 1, "a_pattern_from"},
|
||||
AttributeInfo{2, gfx::AttributeDataType::UShort4, 1, "a_pattern_to"},
|
||||
AttributeInfo{3, gfx::AttributeDataType::Float2, 1, "a_opacity"},
|
||||
};
|
||||
const std::array<UniformBlockInfo, 6> ShaderSource<BuiltIn::FillOutlinePatternShader,
|
||||
gfx::Backend::Type::Metal>::uniforms = {
|
||||
UniformBlockInfo{4, true, true, sizeof(FillOutlinePatternDrawableUBO), "FillOutlinePatternDrawableUBO"},
|
||||
UniformBlockInfo{5, true, false, sizeof(FillOutlinePatternTilePropsUBO), "FillOutlinePatternTilePropsUBO"},
|
||||
UniformBlockInfo{6, true, true, sizeof(FillOutlinePatternEvaluatedPropsUBO), "FillOutlinePatternEvaluatedPropsUBO"},
|
||||
UniformBlockInfo{7, true, false, sizeof(FillOutlinePatternInterpolateUBO), "FillOutlinePatternInterpolateUBO"},
|
||||
UniformBlockInfo{8, true, true, sizeof(FillOutlinePatternPermutationUBO), "FillOutlinePatternPermutationUBO"},
|
||||
UniformBlockInfo{9, true, false, sizeof(ExpressionInputsUBO), "ExpressionInputsUBO"},
|
||||
};
|
||||
const std::array<TextureInfo, 1> ShaderSource<BuiltIn::FillOutlinePatternShader, gfx::Backend::Type::Metal>::textures =
|
||||
{
|
||||
TextureInfo{0, "u_image"},
|
||||
};
|
||||
|
||||
} // namespace shaders
|
||||
} // namespace mbgl
|
||||
24
src/mbgl/shaders/mtl/fill_extrusion.cpp
Normal file
24
src/mbgl/shaders/mtl/fill_extrusion.cpp
Normal file
@@ -0,0 +1,24 @@
|
||||
#include <mbgl/shaders/mtl/fill_extrusion.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace shaders {
|
||||
|
||||
const std::array<AttributeInfo, 5> ShaderSource<BuiltIn::FillExtrusionShader, gfx::Backend::Type::Metal>::attributes = {
|
||||
AttributeInfo{0, gfx::AttributeDataType::Short2, 1, "a_pos"},
|
||||
AttributeInfo{1, gfx::AttributeDataType::Short4, 1, "a_normal_ed"},
|
||||
AttributeInfo{2, gfx::AttributeDataType::Float4, 1, "a_color"},
|
||||
AttributeInfo{3, gfx::AttributeDataType::Float, 1, "a_base"},
|
||||
AttributeInfo{4, gfx::AttributeDataType::Float, 1, "a_height"},
|
||||
};
|
||||
const std::array<UniformBlockInfo, 5> ShaderSource<BuiltIn::FillExtrusionShader, gfx::Backend::Type::Metal>::uniforms =
|
||||
{
|
||||
UniformBlockInfo{5, true, false, sizeof(FillExtrusionDrawableUBO), "FillExtrusionDrawableUBO"},
|
||||
UniformBlockInfo{6, true, false, sizeof(FillExtrusionDrawablePropsUBO), "FillExtrusionDrawablePropsUBO"},
|
||||
UniformBlockInfo{7, true, false, sizeof(FillExtrusionInterpolateUBO), "FillExtrusionInterpolateUBO"},
|
||||
UniformBlockInfo{8, true, false, sizeof(FillExtrusionPermutationUBO), "FillExtrusionPermutationUBO"},
|
||||
UniformBlockInfo{9, true, false, sizeof(ExpressionInputsUBO), "ExpressionInputsUBO"},
|
||||
};
|
||||
const std::array<TextureInfo, 0> ShaderSource<BuiltIn::FillExtrusionShader, gfx::Backend::Type::Metal>::textures = {};
|
||||
|
||||
} // namespace shaders
|
||||
} // namespace mbgl
|
||||
14
src/mbgl/shaders/mtl/fill_extrusion_pattern.cpp
Normal file
14
src/mbgl/shaders/mtl/fill_extrusion_pattern.cpp
Normal file
@@ -0,0 +1,14 @@
|
||||
#include <mbgl/shaders/mtl/fill_extrusion_pattern.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace shaders {
|
||||
|
||||
const std::array<AttributeInfo, 0>
|
||||
ShaderSource<BuiltIn::FillExtrusionPatternShader, gfx::Backend::Type::Metal>::attributes = {};
|
||||
const std::array<UniformBlockInfo, 0>
|
||||
ShaderSource<BuiltIn::FillExtrusionPatternShader, gfx::Backend::Type::Metal>::uniforms = {};
|
||||
const std::array<TextureInfo, 0>
|
||||
ShaderSource<BuiltIn::FillExtrusionPatternShader, gfx::Backend::Type::Metal>::textures = {};
|
||||
|
||||
} // namespace shaders
|
||||
} // namespace mbgl
|
||||
21
src/mbgl/shaders/mtl/heatmap.cpp
Normal file
21
src/mbgl/shaders/mtl/heatmap.cpp
Normal file
@@ -0,0 +1,21 @@
|
||||
#include <mbgl/shaders/mtl/heatmap.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace shaders {
|
||||
|
||||
const std::array<AttributeInfo, 3> ShaderSource<BuiltIn::HeatmapShader, gfx::Backend::Type::Metal>::attributes = {
|
||||
AttributeInfo{0, gfx::AttributeDataType::Short2, 1, "a_pos"},
|
||||
AttributeInfo{1, gfx::AttributeDataType::Float2, 1, "a_weight"},
|
||||
AttributeInfo{2, gfx::AttributeDataType::Float2, 1, "a_radius"},
|
||||
};
|
||||
const std::array<UniformBlockInfo, 5> ShaderSource<BuiltIn::HeatmapShader, gfx::Backend::Type::Metal>::uniforms = {
|
||||
UniformBlockInfo{3, true, false, sizeof(HeatmapDrawableUBO), "HeatmapDrawableUBO"},
|
||||
UniformBlockInfo{4, true, true, sizeof(HeatmapEvaluatedPropsUBO), "HeatmapEvaluatedPropsUBO"},
|
||||
UniformBlockInfo{5, true, false, sizeof(HeatmapInterpolateUBO), "HeatmapInterpolateUBO"},
|
||||
UniformBlockInfo{6, true, true, sizeof(HeatmapPermutationUBO), "HeatmapPermutationUBO"},
|
||||
UniformBlockInfo{7, true, false, sizeof(ExpressionInputsUBO), "ExpressionInputsUBO"},
|
||||
};
|
||||
const std::array<TextureInfo, 0> ShaderSource<BuiltIn::HeatmapShader, gfx::Backend::Type::Metal>::textures = {};
|
||||
|
||||
} // namespace shaders
|
||||
} // namespace mbgl
|
||||
20
src/mbgl/shaders/mtl/heatmap_texture.cpp
Normal file
20
src/mbgl/shaders/mtl/heatmap_texture.cpp
Normal file
@@ -0,0 +1,20 @@
|
||||
#include <mbgl/shaders/mtl/heatmap_texture.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace shaders {
|
||||
|
||||
const std::array<AttributeInfo, 1> ShaderSource<BuiltIn::HeatmapTextureShader, gfx::Backend::Type::Metal>::attributes =
|
||||
{
|
||||
AttributeInfo{0, gfx::AttributeDataType::Short2, 1, "a_pos"},
|
||||
};
|
||||
const std::array<UniformBlockInfo, 1> ShaderSource<BuiltIn::HeatmapTextureShader, gfx::Backend::Type::Metal>::uniforms =
|
||||
{
|
||||
UniformBlockInfo{1, true, true, sizeof(HeatmapTextureDrawableUBO), "HeatmapTextureDrawableUBO"},
|
||||
};
|
||||
const std::array<TextureInfo, 2> ShaderSource<BuiltIn::HeatmapTextureShader, gfx::Backend::Type::Metal>::textures = {
|
||||
TextureInfo{0, "u_image"},
|
||||
TextureInfo{1, "u_color_ramp"},
|
||||
};
|
||||
|
||||
} // namespace shaders
|
||||
} // namespace mbgl
|
||||
19
src/mbgl/shaders/mtl/hillshade.cpp
Normal file
19
src/mbgl/shaders/mtl/hillshade.cpp
Normal file
@@ -0,0 +1,19 @@
|
||||
#include <mbgl/shaders/mtl/hillshade.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace shaders {
|
||||
|
||||
const std::array<AttributeInfo, 2> ShaderSource<BuiltIn::HillshadeShader, gfx::Backend::Type::Metal>::attributes = {
|
||||
AttributeInfo{0, gfx::AttributeDataType::Short2, 1, "a_pos"},
|
||||
AttributeInfo{1, gfx::AttributeDataType::Short2, 1, "a_texture_pos"},
|
||||
};
|
||||
const std::array<UniformBlockInfo, 2> ShaderSource<BuiltIn::HillshadeShader, gfx::Backend::Type::Metal>::uniforms = {
|
||||
UniformBlockInfo{2, true, true, sizeof(HillshadeDrawableUBO), "HillshadeDrawableUBO"},
|
||||
UniformBlockInfo{3, false, true, sizeof(HillshadeEvaluatedPropsUBO), "HillshadeEvaluatedPropsUBO"},
|
||||
};
|
||||
const std::array<TextureInfo, 1> ShaderSource<BuiltIn::HillshadeShader, gfx::Backend::Type::Metal>::textures = {
|
||||
TextureInfo{0, "u_image"},
|
||||
};
|
||||
|
||||
} // namespace shaders
|
||||
} // namespace mbgl
|
||||
20
src/mbgl/shaders/mtl/hillshade_prepare.cpp
Normal file
20
src/mbgl/shaders/mtl/hillshade_prepare.cpp
Normal file
@@ -0,0 +1,20 @@
|
||||
#include <mbgl/shaders/mtl/hillshade_prepare.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace shaders {
|
||||
|
||||
const std::array<AttributeInfo, 2>
|
||||
ShaderSource<BuiltIn::HillshadePrepareShader, gfx::Backend::Type::Metal>::attributes = {
|
||||
AttributeInfo{0, gfx::AttributeDataType::Short2, 1, "a_pos"},
|
||||
AttributeInfo{1, gfx::AttributeDataType::Short2, 1, "a_texture_pos"},
|
||||
};
|
||||
const std::array<UniformBlockInfo, 1>
|
||||
ShaderSource<BuiltIn::HillshadePrepareShader, gfx::Backend::Type::Metal>::uniforms = {
|
||||
UniformBlockInfo{2, true, true, sizeof(HillshadePrepareDrawableUBO), "HillshadePrepareDrawableUBO"},
|
||||
};
|
||||
const std::array<TextureInfo, 1> ShaderSource<BuiltIn::HillshadePrepareShader, gfx::Backend::Type::Metal>::textures = {
|
||||
TextureInfo{0, "u_image"},
|
||||
};
|
||||
|
||||
} // namespace shaders
|
||||
} // namespace mbgl
|
||||
49
src/mbgl/shaders/mtl/line.cpp
Normal file
49
src/mbgl/shaders/mtl/line.cpp
Normal file
@@ -0,0 +1,49 @@
|
||||
#include <mbgl/shaders/mtl/line.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace shaders {
|
||||
|
||||
const std::array<AttributeInfo, 8> ShaderSource<BuiltIn::LineShader, gfx::Backend::Type::Metal>::attributes = {
|
||||
AttributeInfo{0, gfx::AttributeDataType::Short2, 1, "a_pos_normal"},
|
||||
AttributeInfo{1, gfx::AttributeDataType::UByte4, 1, "a_data"},
|
||||
AttributeInfo{2, gfx::AttributeDataType::Float4, 1, "a_color"},
|
||||
AttributeInfo{3, gfx::AttributeDataType::Float2, 1, "a_blur"},
|
||||
AttributeInfo{4, gfx::AttributeDataType::Float2, 1, "a_opacity"},
|
||||
AttributeInfo{5, gfx::AttributeDataType::Float2, 1, "a_gapwidth"},
|
||||
AttributeInfo{6, gfx::AttributeDataType::Float2, 1, "a_offset"},
|
||||
AttributeInfo{7, gfx::AttributeDataType::Float2, 1, "a_width"},
|
||||
};
|
||||
const std::array<UniformBlockInfo, 5> ShaderSource<BuiltIn::LineShader, gfx::Backend::Type::Metal>::uniforms = {
|
||||
UniformBlockInfo{8, true, true, sizeof(LineUBO), "LineUBO"},
|
||||
UniformBlockInfo{9, true, false, sizeof(LinePropertiesUBO), "LinePropertiesUBO"},
|
||||
UniformBlockInfo{10, true, false, sizeof(LineInterpolationUBO), "LineInterpolationUBO"},
|
||||
UniformBlockInfo{11, true, true, sizeof(LinePermutationUBO), "LinePermutationUBO"},
|
||||
UniformBlockInfo{12, true, false, sizeof(ExpressionInputsUBO), "ExpressionInputsUBO"},
|
||||
};
|
||||
const std::array<TextureInfo, 0> ShaderSource<BuiltIn::LineShader, gfx::Backend::Type::Metal>::textures = {};
|
||||
|
||||
const std::array<AttributeInfo, 9> ShaderSource<BuiltIn::LinePatternShader, gfx::Backend::Type::Metal>::attributes = {
|
||||
AttributeInfo{0, gfx::AttributeDataType::Short2, 1, "a_pos_normal"},
|
||||
AttributeInfo{1, gfx::AttributeDataType::UByte4, 1, "a_data"},
|
||||
AttributeInfo{2, gfx::AttributeDataType::Float2, 1, "a_blur"},
|
||||
AttributeInfo{3, gfx::AttributeDataType::Float2, 1, "a_opacity"},
|
||||
AttributeInfo{4, gfx::AttributeDataType::Float2, 1, "a_gapwidth"},
|
||||
AttributeInfo{5, gfx::AttributeDataType::Float2, 1, "a_offset"},
|
||||
AttributeInfo{6, gfx::AttributeDataType::Float2, 1, "a_width"},
|
||||
AttributeInfo{7, gfx::AttributeDataType::UShort4, 1, "a_pattern_from"},
|
||||
AttributeInfo{8, gfx::AttributeDataType::UShort4, 1, "a_pattern_to"},
|
||||
};
|
||||
const std::array<UniformBlockInfo, 6> ShaderSource<BuiltIn::LinePatternShader, gfx::Backend::Type::Metal>::uniforms = {
|
||||
UniformBlockInfo{9, true, true, sizeof(LinePatternUBO), "LinePatternUBO"},
|
||||
UniformBlockInfo{10, true, false, sizeof(LinePatternPropertiesUBO), "LinePatternPropertiesUBO"},
|
||||
UniformBlockInfo{11, true, false, sizeof(LinePatternInterpolationUBO), "LinePatternInterpolationUBO"},
|
||||
UniformBlockInfo{12, true, false, sizeof(LinePatternTilePropertiesUBO), "LinePatternTilePropertiesUBO"},
|
||||
UniformBlockInfo{13, true, true, sizeof(LinePermutationUBO), "LinePermutationUBO"},
|
||||
UniformBlockInfo{14, true, false, sizeof(ExpressionInputsUBO), "ExpressionInputsUBO"},
|
||||
};
|
||||
const std::array<TextureInfo, 1> ShaderSource<BuiltIn::LinePatternShader, gfx::Backend::Type::Metal>::textures = {
|
||||
TextureInfo{0, "u_image"},
|
||||
};
|
||||
|
||||
} // namespace shaders
|
||||
} // namespace mbgl
|
||||
27
src/mbgl/shaders/mtl/line_gradient.cpp
Normal file
27
src/mbgl/shaders/mtl/line_gradient.cpp
Normal file
@@ -0,0 +1,27 @@
|
||||
#include <mbgl/shaders/mtl/line_gradient.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace shaders {
|
||||
|
||||
const std::array<AttributeInfo, 7> ShaderSource<BuiltIn::LineGradientShader, gfx::Backend::Type::Metal>::attributes = {
|
||||
AttributeInfo{0, gfx::AttributeDataType::Short2, 1, "a_pos_normal"},
|
||||
AttributeInfo{1, gfx::AttributeDataType::UByte4, 1, "a_data"},
|
||||
AttributeInfo{2, gfx::AttributeDataType::Float2, 1, "a_blur"},
|
||||
AttributeInfo{3, gfx::AttributeDataType::Float2, 1, "a_opacity"},
|
||||
AttributeInfo{4, gfx::AttributeDataType::Float2, 1, "a_gapwidth"},
|
||||
AttributeInfo{5, gfx::AttributeDataType::Float2, 1, "a_offset"},
|
||||
AttributeInfo{6, gfx::AttributeDataType::Float2, 1, "a_width"},
|
||||
};
|
||||
const std::array<UniformBlockInfo, 5> ShaderSource<BuiltIn::LineGradientShader, gfx::Backend::Type::Metal>::uniforms = {
|
||||
UniformBlockInfo{7, true, true, sizeof(LineGradientUBO), "LineGradientUBO"},
|
||||
UniformBlockInfo{8, true, false, sizeof(LineGradientPropertiesUBO), "LineGradientPropertiesUBO"},
|
||||
UniformBlockInfo{9, true, false, sizeof(LineGradientInterpolationUBO), "LineGradientInterpolationUBO"},
|
||||
UniformBlockInfo{10, true, true, sizeof(LinePermutationUBO), "LinePermutationUBO"},
|
||||
UniformBlockInfo{11, true, false, sizeof(ExpressionInputsUBO), "ExpressionInputsUBO"},
|
||||
};
|
||||
const std::array<TextureInfo, 1> ShaderSource<BuiltIn::LineGradientShader, gfx::Backend::Type::Metal>::textures = {
|
||||
TextureInfo{0, "u_image"},
|
||||
};
|
||||
|
||||
} // namespace shaders
|
||||
} // namespace mbgl
|
||||
19
src/mbgl/shaders/mtl/raster.cpp
Normal file
19
src/mbgl/shaders/mtl/raster.cpp
Normal file
@@ -0,0 +1,19 @@
|
||||
#include <mbgl/shaders/mtl/raster.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace shaders {
|
||||
|
||||
const std::array<AttributeInfo, 2> ShaderSource<BuiltIn::RasterShader, gfx::Backend::Type::Metal>::attributes = {
|
||||
AttributeInfo{0, gfx::AttributeDataType::Short2, 1, "a_pos"},
|
||||
AttributeInfo{1, gfx::AttributeDataType::Short2, 1, "a_texture_pos"},
|
||||
};
|
||||
const std::array<UniformBlockInfo, 1> ShaderSource<BuiltIn::RasterShader, gfx::Backend::Type::Metal>::uniforms = {
|
||||
UniformBlockInfo{2, true, true, sizeof(RasterDrawableUBO), "RasterDrawableUBO"},
|
||||
};
|
||||
const std::array<TextureInfo, 2> ShaderSource<BuiltIn::RasterShader, gfx::Backend::Type::Metal>::textures = {
|
||||
TextureInfo{0, "u_image0"},
|
||||
TextureInfo{1, "u_image1"},
|
||||
};
|
||||
|
||||
} // namespace shaders
|
||||
} // namespace mbgl
|
||||
@@ -22,8 +22,32 @@
|
||||
using namespace std::string_literals;
|
||||
|
||||
namespace mbgl {
|
||||
namespace mtl {
|
||||
|
||||
shaders::AttributeInfo::AttributeInfo(std::size_t index_,
|
||||
gfx::AttributeDataType dataType_,
|
||||
std::size_t count_,
|
||||
std::string_view name_)
|
||||
: index(index_),
|
||||
dataType(dataType_),
|
||||
count(count_),
|
||||
name(name_),
|
||||
nameID(StringIndexer::get(name_)) {}
|
||||
|
||||
shaders::UniformBlockInfo::UniformBlockInfo(
|
||||
std::size_t index_, bool vertex_, bool fragment_, std::size_t size_, std::string_view name_)
|
||||
: index(index_),
|
||||
vertex(vertex_),
|
||||
fragment(fragment_),
|
||||
size(size_),
|
||||
name(name_),
|
||||
nameID(StringIndexer::get(name_)) {}
|
||||
|
||||
shaders::TextureInfo::TextureInfo(std::size_t index_, std::string_view name_)
|
||||
: index(index_),
|
||||
name(name_),
|
||||
nameID(StringIndexer::get(name_)) {}
|
||||
|
||||
namespace mtl {
|
||||
namespace {
|
||||
MTL::BlendOperation metalBlendOperation(const gfx::ColorBlendEquationType& colorBlend) {
|
||||
switch (colorBlend) {
|
||||
|
||||
30
src/mbgl/shaders/mtl/symbol_icon.cpp
Normal file
30
src/mbgl/shaders/mtl/symbol_icon.cpp
Normal file
@@ -0,0 +1,30 @@
|
||||
#include <mbgl/shaders/mtl/symbol_icon.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace shaders {
|
||||
|
||||
const std::array<AttributeInfo, 6> ShaderSource<BuiltIn::SymbolIconShader, gfx::Backend::Type::Metal>::attributes = {
|
||||
// always attributes
|
||||
AttributeInfo{0, gfx::AttributeDataType::Short4, 1, "a_pos_offset"},
|
||||
AttributeInfo{1, gfx::AttributeDataType::UShort4, 1, "a_data"},
|
||||
AttributeInfo{2, gfx::AttributeDataType::Short4, 1, "a_pixeloffset"},
|
||||
AttributeInfo{3, gfx::AttributeDataType::Float3, 1, "a_projected_pos"},
|
||||
AttributeInfo{4, gfx::AttributeDataType::Float, 1, "a_fade_opacity"},
|
||||
|
||||
// sometimes uniforms
|
||||
AttributeInfo{5, gfx::AttributeDataType::Float, 1, "a_opacity"},
|
||||
};
|
||||
const std::array<UniformBlockInfo, 6> ShaderSource<BuiltIn::SymbolIconShader, gfx::Backend::Type::Metal>::uniforms = {
|
||||
UniformBlockInfo{8, true, true, sizeof(SymbolDrawableUBO), "SymbolDrawableUBO"},
|
||||
UniformBlockInfo{9, true, true, sizeof(SymbolDrawablePaintUBO), "SymbolDrawablePaintUBO"},
|
||||
UniformBlockInfo{10, true, false, sizeof(SymbolDrawableTilePropsUBO), "SymbolDrawableTilePropsUBO"},
|
||||
UniformBlockInfo{11, true, false, sizeof(SymbolDrawableInterpolateUBO), "SymbolDrawableInterpolateUBO"},
|
||||
UniformBlockInfo{12, true, true, sizeof(SymbolPermutationUBO), "SymbolPermutationUBO"},
|
||||
UniformBlockInfo{13, true, false, sizeof(ExpressionInputsUBO), "ExpressionInputsUBO"},
|
||||
};
|
||||
const std::array<TextureInfo, 1> ShaderSource<BuiltIn::SymbolIconShader, gfx::Backend::Type::Metal>::textures = {
|
||||
TextureInfo{0, "u_texture"},
|
||||
};
|
||||
|
||||
} // namespace shaders
|
||||
} // namespace mbgl
|
||||
36
src/mbgl/shaders/mtl/symbol_sdf.cpp
Normal file
36
src/mbgl/shaders/mtl/symbol_sdf.cpp
Normal file
@@ -0,0 +1,36 @@
|
||||
#include <mbgl/shaders/mtl/symbol_sdf.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace shaders {
|
||||
|
||||
const std::array<AttributeInfo, 10> ShaderSource<BuiltIn::SymbolSDFIconShader, gfx::Backend::Type::Metal>::attributes =
|
||||
{
|
||||
// always attributes
|
||||
AttributeInfo{0, gfx::AttributeDataType::Short4, 1, "a_pos_offset"},
|
||||
AttributeInfo{1, gfx::AttributeDataType::UShort4, 1, "a_data"},
|
||||
AttributeInfo{2, gfx::AttributeDataType::Short4, 1, "a_pixeloffset"},
|
||||
AttributeInfo{3, gfx::AttributeDataType::Float3, 1, "a_projected_pos"},
|
||||
AttributeInfo{4, gfx::AttributeDataType::Float, 1, "a_fade_opacity"},
|
||||
|
||||
// sometimes uniforms
|
||||
AttributeInfo{5, gfx::AttributeDataType::Float4, 1, "a_fill_color"},
|
||||
AttributeInfo{6, gfx::AttributeDataType::Float4, 1, "a_halo_color"},
|
||||
AttributeInfo{7, gfx::AttributeDataType::Float, 1, "a_opacity"},
|
||||
AttributeInfo{8, gfx::AttributeDataType::Float, 1, "a_halo_width"},
|
||||
AttributeInfo{9, gfx::AttributeDataType::Float, 1, "a_halo_blur"},
|
||||
};
|
||||
const std::array<UniformBlockInfo, 6> ShaderSource<BuiltIn::SymbolSDFIconShader, gfx::Backend::Type::Metal>::uniforms =
|
||||
{
|
||||
UniformBlockInfo{10, true, true, sizeof(SymbolDrawableUBO), "SymbolDrawableUBO"},
|
||||
UniformBlockInfo{11, true, false, sizeof(SymbolDrawablePaintUBO), "SymbolDrawablePaintUBO"},
|
||||
UniformBlockInfo{12, true, true, sizeof(SymbolDrawableTilePropsUBO), "SymbolDrawableTilePropsUBO"},
|
||||
UniformBlockInfo{13, true, false, sizeof(SymbolDrawableInterpolateUBO), "SymbolDrawableInterpolateUBO"},
|
||||
UniformBlockInfo{14, true, true, sizeof(SymbolPermutationUBO), "SymbolPermutationUBO"},
|
||||
UniformBlockInfo{15, true, false, sizeof(ExpressionInputsUBO), "ExpressionInputsUBO"},
|
||||
};
|
||||
const std::array<TextureInfo, 1> ShaderSource<BuiltIn::SymbolSDFIconShader, gfx::Backend::Type::Metal>::textures = {
|
||||
TextureInfo{0, "u_texture"},
|
||||
};
|
||||
|
||||
} // namespace shaders
|
||||
} // namespace mbgl
|
||||
36
src/mbgl/shaders/mtl/symbol_text_and_icon.cpp
Normal file
36
src/mbgl/shaders/mtl/symbol_text_and_icon.cpp
Normal file
@@ -0,0 +1,36 @@
|
||||
#include <mbgl/shaders/mtl/symbol_text_and_icon.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace shaders {
|
||||
|
||||
const std::array<AttributeInfo, 9>
|
||||
ShaderSource<BuiltIn::SymbolTextAndIconShader, gfx::Backend::Type::Metal>::attributes = {
|
||||
// always attributes
|
||||
AttributeInfo{0, gfx::AttributeDataType::Short4, 1, "a_pos_offset"},
|
||||
AttributeInfo{1, gfx::AttributeDataType::UShort4, 1, "a_data"},
|
||||
AttributeInfo{2, gfx::AttributeDataType::Float3, 1, "a_projected_pos"},
|
||||
AttributeInfo{3, gfx::AttributeDataType::Float, 1, "a_fade_opacity"},
|
||||
|
||||
// sometimes uniforms
|
||||
AttributeInfo{4, gfx::AttributeDataType::Float4, 1, "a_fill_color"},
|
||||
AttributeInfo{5, gfx::AttributeDataType::Float4, 1, "a_halo_color"},
|
||||
AttributeInfo{6, gfx::AttributeDataType::Float, 1, "a_opacity"},
|
||||
AttributeInfo{7, gfx::AttributeDataType::Float, 1, "a_halo_width"},
|
||||
AttributeInfo{8, gfx::AttributeDataType::Float, 1, "a_halo_blur"},
|
||||
};
|
||||
const std::array<UniformBlockInfo, 6>
|
||||
ShaderSource<BuiltIn::SymbolTextAndIconShader, gfx::Backend::Type::Metal>::uniforms = {
|
||||
UniformBlockInfo{9, true, true, sizeof(SymbolDrawableUBO), "SymbolDrawableUBO"},
|
||||
UniformBlockInfo{10, true, false, sizeof(SymbolDrawablePaintUBO), "SymbolDrawablePaintUBO"},
|
||||
UniformBlockInfo{11, true, true, sizeof(SymbolDrawableTilePropsUBO), "SymbolDrawableTilePropsUBO"},
|
||||
UniformBlockInfo{12, true, false, sizeof(SymbolDrawableInterpolateUBO), "SymbolDrawableInterpolateUBO"},
|
||||
UniformBlockInfo{13, true, true, sizeof(SymbolPermutationUBO), "SymbolPermutationUBO"},
|
||||
UniformBlockInfo{14, true, false, sizeof(ExpressionInputsUBO), "ExpressionInputsUBO"},
|
||||
};
|
||||
const std::array<TextureInfo, 2> ShaderSource<BuiltIn::SymbolTextAndIconShader, gfx::Backend::Type::Metal>::textures = {
|
||||
TextureInfo{0, "u_texture"},
|
||||
TextureInfo{1, "u_texture_icon"},
|
||||
};
|
||||
|
||||
} // namespace shaders
|
||||
} // namespace mbgl
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <mbgl/util/ignore.hpp>
|
||||
|
||||
#include <functional>
|
||||
#include <type_traits>
|
||||
|
||||
namespace mbgl {
|
||||
namespace util {
|
||||
@@ -19,5 +20,24 @@ std::size_t hash(Args&&... args) {
|
||||
return seed;
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
template <typename TIter>
|
||||
using TIterVal = std::enable_if_t<std::is_integral<typename TIter::value_type>::value, typename TIter::value_type>;
|
||||
} // namespace detail
|
||||
|
||||
/// Generate a hash key from a collection of integer values which doesn't depend on their order.
|
||||
/// Adapted from https://stackoverflow.com/a/76993810/135138
|
||||
/// Default factor prime value from 64-bit FNV hash.
|
||||
template <typename TIter, typename TKey = detail::TIterVal<TIter>, TKey factor = 1099511628211LL>
|
||||
TKey order_independent_hash(TIter cur, const TIter end) {
|
||||
detail::TIterVal<TIter> sum = 0, product = 1;
|
||||
for (; cur != end; ++cur) {
|
||||
const auto& value = *cur;
|
||||
sum += value;
|
||||
product *= (1 + value) * factor;
|
||||
}
|
||||
return sum ^ product;
|
||||
}
|
||||
|
||||
} // namespace util
|
||||
} // namespace mbgl
|
||||
|
||||
@@ -88,6 +88,7 @@ add_library(
|
||||
${PROJECT_SOURCE_DIR}/test/util/dtoa.test.cpp
|
||||
${PROJECT_SOURCE_DIR}/test/util/geo.test.cpp
|
||||
${PROJECT_SOURCE_DIR}/test/util/grid_index.test.cpp
|
||||
${PROJECT_SOURCE_DIR}/test/util/hash.test.cpp
|
||||
${PROJECT_SOURCE_DIR}/test/util/http_timeout.test.cpp
|
||||
${PROJECT_SOURCE_DIR}/test/util/image.test.cpp
|
||||
${PROJECT_SOURCE_DIR}/test/util/mapbox.test.cpp
|
||||
@@ -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
54
test/util/hash.test.cpp
Normal 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()));
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user