Metal permutations 2 (#1923)

This commit is contained in:
Tim Sylvester
2023-12-07 08:21:24 -08:00
committed by GitHub
parent 7ccc5de6b1
commit 18e6802973
76 changed files with 518 additions and 1467 deletions

View File

@@ -17,11 +17,6 @@ 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;
@@ -49,31 +44,6 @@ public:
const std::string& getID() const { return id; }
#if MLN_RENDER_BACKEND_METAL
/// 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.
shaders::AttributeSource getAttributeSource(const StringIdentity id) {
return propertiesAsUniforms.count(id) ? shaders::AttributeSource::Constant
: shaders::AttributeSource::PerVertex;
}
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(const mbgl::unordered_set<StringIdentity>&);
const mbgl::unordered_set<StringIdentity>& getPropertiesAsUniforms() const;
void enableOverdrawInspector(bool);
virtual void execute(LayerGroupBase&, const PaintParameters&) = 0;
void updateProperties(Immutable<style::LayerProperties>);
@@ -96,19 +66,8 @@ protected:
std::string id;
Immutable<style::LayerProperties> evaluatedProperties;
#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.
mbgl::unordered_set<StringIdentity> propertiesAsUniforms;
#endif // MLN_RENDER_BACKEND_METAL
// Indicates that the evaluated properties have changed
bool propertiesUpdated = true;
// Indicates that the properties-as-uniforms has changed
bool permutationUpdated = true;
bool overdrawInspector = false;
};
} // namespace mbgl

View File

@@ -15,10 +15,7 @@ static_assert(sizeof(BackgroundDrawableUBO) % 16 == 0);
struct alignas(16) BackgroundLayerUBO {
/* 0 */ Color color;
/* 16 */ float opacity;
// overdrawInspector is used only in Metal, while in GL this is a 16 bytes empty padding.
/* 20 */ bool overdrawInspector;
/* 21 */ uint8_t pad1, pad2, pad3;
/* 24 */ float pad4, pad5;
/* 24 */ float pad1, pad2, pad3;
/* 32 */
};
static_assert(sizeof(BackgroundLayerUBO) == 32);
@@ -38,9 +35,7 @@ struct alignas(16) BackgroundPatternLayerUBO {
/* 80 */ float scale_b;
/* 84 */ float mix;
/* 88 */ float opacity;
// overdrawInspector is used only in Metal, while in GL this is a 4 bytes empty padding.
/* 92 */ bool overdrawInspector;
/* 93 */ uint8_t pad1, pad2, pad3;
/* 92 */ float pad1;
/* 96 */
};
static_assert(sizeof(BackgroundPatternLayerUBO) == 96);

View File

@@ -47,20 +47,5 @@ struct alignas(16) CircleInterpolateUBO {
};
static_assert(sizeof(CircleInterpolateUBO) % 16 == 0);
struct alignas(16) CirclePermutationUBO {
/* 0 */ Attribute color;
/* 8 */ Attribute radius;
/* 16 */ Attribute blur;
/* 24 */ Attribute opacity;
/* 32 */ Attribute stroke_color;
/* 40 */ Attribute stroke_width;
/* 48 */ Attribute stroke_opacity;
/* 56 */ bool overdrawInspector;
/* 57 */ uint8_t pad1, pad2, pad3;
/* 60 */ float pad4;
/* 64 */
};
static_assert(sizeof(CirclePermutationUBO) == 4 * 16);
} // namespace shaders
} // namespace mbgl

View File

@@ -56,18 +56,5 @@ struct alignas(16) FillExtrusionDrawablePropsUBO {
};
static_assert(sizeof(FillExtrusionDrawablePropsUBO) == 5 * 16);
struct alignas(16) FillExtrusionPermutationUBO {
/* 0 */ Attribute color;
/* 8 */ Attribute base;
/* 16 */ Attribute height;
/* 24 */ Attribute pattern_from;
/* 32 */ Attribute pattern_to;
/* 40 */ bool overdrawInspector;
/* 41 */ uint8_t pad1, pad2, pad3;
/* 44 */ float pad4;
/* 48 */
};
static_assert(sizeof(FillExtrusionPermutationUBO) == 3 * 16, "unexpected padding");
} // namespace shaders
} // namespace mbgl

View File

@@ -27,16 +27,6 @@ struct alignas(16) FillInterpolateUBO {
};
static_assert(sizeof(FillInterpolateUBO) % 16 == 0);
struct alignas(16) FillPermutationUBO {
/* 0 */ Attribute color;
/* 8 */ Attribute opacity;
/* 16 */ bool overdrawInspector;
/* 17 */ bool pad1, pad2, pad3;
/* 20 */ float pad4, pad5, pad6;
/* 32 */
};
static_assert(sizeof(FillPermutationUBO) == 2 * 16);
//
// Fill outline
@@ -62,16 +52,6 @@ struct alignas(16) FillOutlineInterpolateUBO {
};
static_assert(sizeof(FillOutlineInterpolateUBO) == 1 * 16);
struct alignas(16) FillOutlinePermutationUBO {
/* 0 */ Attribute outline_color;
/* 8 */ Attribute opacity;
/* 16 */ bool overdrawInspector;
/* 17 */ bool pad1, pad2, pad3;
/* 20 */ float pad4, pad5, pad6;
/* 32 */
};
static_assert(sizeof(FillOutlinePermutationUBO) == 2 * 16);
//
// Fill Pattern
@@ -107,17 +87,6 @@ struct alignas(16) FillPatternInterpolateUBO {
};
static_assert(sizeof(FillPatternInterpolateUBO) == 1 * 16);
struct alignas(16) FillPatternPermutationUBO {
/* 0 */ Attribute pattern_from;
/* 8 */ Attribute pattern_to;
/* 16 */ Attribute opacity;
/* 24 */ bool overdrawInspector;
/* 25 */ bool pad1, pad2, pad3;
/* 28 */ float pad4;
/* 32 */
};
static_assert(sizeof(FillPatternPermutationUBO) == 2 * 16);
//
// Fill pattern outline
@@ -152,16 +121,5 @@ struct alignas(16) FillOutlinePatternInterpolateUBO {
};
static_assert(sizeof(FillOutlinePatternInterpolateUBO) == 1 * 16);
struct alignas(16) FillOutlinePatternPermutationUBO {
/* 0 */ Attribute pattern_from;
/* 8 */ Attribute pattern_to;
/* 16 */ Attribute opacity;
/* 24 */ bool overdrawInspector;
/* 17 */ bool pad1, pad2, pad3;
/* 20 */ float pad4;
/* 32 */
};
static_assert(sizeof(FillOutlinePatternPermutationUBO) == 2 * 16);
} // namespace shaders
} // namespace mbgl

View File

@@ -27,15 +27,5 @@ struct alignas(16) HeatmapInterpolateUBO {
};
static_assert(sizeof(HeatmapInterpolateUBO) % 16 == 0);
struct alignas(16) HeatmapPermutationUBO {
/* 0 */ Attribute weight;
/* 8 */ Attribute radius;
/* 16 */ bool overdrawInspector;
/* 17 */ uint8_t pad1, pad2, pad3;
/* 20 */ float pad4, pad5, pad6;
/* 32 */
};
static_assert(sizeof(HeatmapPermutationUBO) == 2 * 16);
} // namespace shaders
} // namespace mbgl

View File

@@ -9,9 +9,7 @@ struct alignas(16) HeatmapTextureDrawableUBO {
std::array<float, 4 * 4> matrix;
std::array<float, 2> world;
float opacity;
// overdrawInspector is used only in Metal, while in GL this is a 4 bytes empty padding.
bool overdrawInspector;
uint8_t pad1, pad2, pad3;
float pad1;
};
static_assert(sizeof(HeatmapTextureDrawableUBO) % 16 == 0);

View File

@@ -9,12 +9,8 @@ struct alignas(16) HillshadeDrawableUBO {
std::array<float, 4 * 4> matrix;
std::array<float, 2> latrange;
std::array<float, 2> light;
// overdrawInspector is used only in Metal, while in GL this is a 16 bytes empty padding.
bool overdrawInspector;
uint8_t pad1, pad2, pad3;
float pad4, pad5, pad6;
};
static_assert(sizeof(HillshadeDrawableUBO) % 16 == 0);
static_assert(sizeof(HillshadeDrawableUBO) == 16 * 5);
struct alignas(16) HillshadeEvaluatedPropsUBO {
Color highlight;

View File

@@ -11,10 +11,6 @@ struct alignas(16) HillshadePrepareDrawableUBO {
std::array<float, 2> dimension;
float zoom;
float maxzoom;
// overdrawInspector is used only in Metal, while in GL this is a 16 bytes empty padding.
bool overdrawInspector;
uint8_t pad1, pad2, pad3;
float pad4, pad5, pad6;
};
static_assert(sizeof(HillshadePrepareDrawableUBO) % 16 == 0);

View File

@@ -33,18 +33,5 @@ struct Attribute {
};
static_assert(sizeof(Attribute) == 8);
struct alignas(16) ExpressionInputsUBO {
// These can use uint64_t in later versions of Metal
/* 0 */ uint32_t time_lo; /// Current scene time (nanoseconds)
/* 4 */ uint32_t time_hi;
/* 8 */ uint32_t frame_lo; /// Current frame count
/* 12 */ uint32_t frame_hi;
/* 16 */ float zoom; /// Current zoom level
/* 20 */ float zoom_frac; /// double precision zoom
/* 24 */ float pad1, pad2;
/* 32 */
};
static_assert(sizeof(ExpressionInputsUBO) == 2 * 16);
} // namespace shaders
} // namespace mbgl

View File

@@ -147,22 +147,5 @@ struct alignas(16) LinePatternTilePropertiesUBO {
};
static_assert(sizeof(LinePatternTilePropertiesUBO) % 16 == 0);
struct alignas(16) LinePermutationUBO {
/* 0 */ Attribute color;
/* 8 */ Attribute blur;
/* 16 */ Attribute opacity;
/* 24 */ Attribute gapwidth;
/* 32 */ Attribute offset;
/* 40 */ Attribute width;
/* 48 */ Attribute floorwidth;
/* 56 */ Attribute pattern_from;
/* 64 */ Attribute pattern_to;
/* 72 */ bool overdrawInspector;
/* 73 */ uint8_t pad1, pad2, pad3;
/* 76 */ float pad4;
/* 80 */
};
static_assert(sizeof(LinePermutationUBO) == 5 * 16);
} // namespace shaders
} // namespace mbgl

View File

@@ -13,7 +13,6 @@ struct ShaderSource<BuiltIn::BackgroundShader, gfx::Backend::Type::Metal> {
static constexpr auto name = "BackgroundShader";
static constexpr auto vertexMainFunction = "vertexMain";
static constexpr auto fragmentMainFunction = "fragmentMain";
static constexpr auto hasPermutations = false;
static const std::array<AttributeInfo, 1> attributes;
static const std::array<UniformBlockInfo, 2> uniforms;
@@ -51,10 +50,10 @@ FragmentStage vertex vertexMain(VertexStage in [[stage_in]],
half4 fragment fragmentMain(FragmentStage in [[stage_in]],
device const BackgroundLayerUBO& layerUBO [[buffer(2)]]) {
if (layerUBO.overdrawInspector) {
return half4(0.0);
}
#if defined(OVERDRAW_INSPECTOR)
return half4(1.0);
#endif
return half4(layerUBO.color * layerUBO.opacity);
}
)";

View File

@@ -10,7 +10,6 @@ struct ShaderSource<BuiltIn::BackgroundPatternShader, gfx::Backend::Type::Metal>
static constexpr auto name = "BackgroundPatternShader";
static constexpr auto vertexMainFunction = "vertexMain";
static constexpr auto fragmentMainFunction = "fragmentMain";
static constexpr auto hasPermutations = false;
static const std::array<AttributeInfo, 1> attributes;
static const std::array<UniformBlockInfo, 2> uniforms;
@@ -56,13 +55,20 @@ FragmentStage vertex vertexMain(VertexStage in [[stage_in]],
device const BackgroundDrawableUBO& drawableUBO [[buffer(1)]],
device const BackgroundLayerUBO& layerUBO [[buffer(2)]]) {
const float2 pos = float2(in.position);
float2 pos_a = get_pattern_pos(layerUBO.pixel_coord_upper, layerUBO.pixel_coord_lower, layerUBO.scale_a * layerUBO.pattern_size_a, layerUBO.tile_units_to_pixels, pos);
float2 pos_b = get_pattern_pos(layerUBO.pixel_coord_upper, layerUBO.pixel_coord_lower, layerUBO.scale_b * layerUBO.pattern_size_b, layerUBO.tile_units_to_pixels, pos);
const float2 pos_a = get_pattern_pos(layerUBO.pixel_coord_upper,
layerUBO.pixel_coord_lower,
layerUBO.scale_a * layerUBO.pattern_size_a,
layerUBO.tile_units_to_pixels,
pos);
const float2 pos_b = get_pattern_pos(layerUBO.pixel_coord_upper,
layerUBO.pixel_coord_lower,
layerUBO.scale_b * layerUBO.pattern_size_b,
layerUBO.tile_units_to_pixels,
pos);
return {
.position = drawableUBO.matrix * float4(float2(in.position.xy), 0, 1),
.pos_a = pos_a,
.pos_b = pos_b
.pos_b = pos_b,
};
}
@@ -70,17 +76,16 @@ half4 fragment fragmentMain(FragmentStage in [[stage_in]],
device const BackgroundLayerUBO& layerUBO [[buffer(2)]],
texture2d<float, access::sample> image [[texture(0)]],
sampler image_sampler [[sampler(0)]]) {
if (layerUBO.overdrawInspector) {
return half4(0.0);
}
float2 imagecoord = glMod(in.pos_a, 1.0);
float2 pos = mix(layerUBO.pattern_tl_a / layerUBO.texsize, layerUBO.pattern_br_a / layerUBO.texsize, imagecoord);
float4 color1 = image.sample(image_sampler, pos);
#if defined(OVERDRAW_INSPECTOR)
return half4(1.0);
#endif
float2 imagecoord_b = glMod(in.pos_b, 1.0);
float2 pos2 = mix(layerUBO.pattern_tl_b / layerUBO.texsize, layerUBO.pattern_br_b / layerUBO.texsize, imagecoord_b);
float4 color2 = image.sample(image_sampler, pos2);
const float2 imagecoord = glMod(float2(in.pos_a), 1.0);
const float2 pos = mix(layerUBO.pattern_tl_a / layerUBO.texsize, layerUBO.pattern_br_a / layerUBO.texsize, imagecoord);
const float4 color1 = image.sample(image_sampler, pos);
const float2 imagecoord_b = glMod(float2(in.pos_b), 1.0);
const float2 pos2 = mix(layerUBO.pattern_tl_b / layerUBO.texsize, layerUBO.pattern_br_b / layerUBO.texsize, imagecoord_b);
const float4 color2 = image.sample(image_sampler, pos2);
return half4(mix(color1, color2, layerUBO.mix) * layerUBO.opacity);
}

View File

@@ -13,14 +13,12 @@ struct ShaderSource<BuiltIn::CircleShader, gfx::Backend::Type::Metal> {
static constexpr auto name = "CircleShader";
static constexpr auto vertexMainFunction = "vertexMain";
static constexpr auto fragmentMainFunction = "fragmentMain";
static constexpr auto hasPermutations = true;
static const std::array<AttributeInfo, 8> attributes;
static const std::array<UniformBlockInfo, 6> uniforms;
static const std::array<UniformBlockInfo, 4> uniforms;
static const std::array<TextureInfo, 0> textures;
static constexpr auto source = R"(
struct VertexStage {
short2 position [[attribute(0)]];
@@ -50,7 +48,7 @@ struct VertexStage {
struct FragmentStage {
float4 position [[position, invariant]];
float2 extrude;
half antialiasblur;
float antialiasblur;
#if !defined(HAS_UNIFORM_u_color)
half4 color;
@@ -109,35 +107,22 @@ struct alignas(16) CircleInterpolateUBO {
float pad1_;
};
struct alignas(16) CirclePermutationUBO {
Attribute color;
Attribute radius;
Attribute blur;
Attribute opacity;
Attribute stroke_color;
Attribute stroke_width;
Attribute stroke_opacity;
bool overdrawInspector;
};
FragmentStage vertex vertexMain(thread const VertexStage vertx [[stage_in]],
device const CircleDrawableUBO& drawable [[buffer(8)]],
device const CirclePaintParamsUBO& params [[buffer(9)]],
device const CircleEvaluatedPropsUBO& props [[buffer(10)]],
device const CircleInterpolateUBO& interp [[buffer(11)]],
device const CirclePermutationUBO& permutation [[buffer(12)]],
device const ExpressionInputsUBO& expr [[buffer(13)]]) {
device const CircleInterpolateUBO& interp [[buffer(11)]]) {
#if defined(HAS_UNIFORM_u_radius)
const auto radius = props.radius;
#else
const auto radius = valueFor(permutation.radius, props.radius, vertx.radius, interp.radius_t, expr);
const auto radius = unpack_mix_float(vertx.radius, interp.radius_t);
#endif
#if defined(HAS_UNIFORM_u_stroke_width)
const auto stroke_width = props.stroke_width;
#else
const auto stroke_width = valueFor(permutation.stroke_width, props.stroke_width, vertx.stroke_width, interp.stroke_width_t, expr);
const auto stroke_width = unpack_mix_float(vertx.stroke_width, interp.stroke_width_t);
#endif
// unencode the extrusion vector that we snuck into the a_pos vector
@@ -156,7 +141,7 @@ FragmentStage vertex vertexMain(thread const VertexStage vertx [[stage_in]],
// Pitching the circle with the map effectively scales it with the map
// To counteract the effect for pitch-scale: viewport, we rescale the
// whole circle based on the pitch scaling effect at its central point
float4 projected_center = drawable.matrix * float4(circle_center, 0, 1);
const float4 projected_center = drawable.matrix * float4(circle_center, 0, 1);
corner_position += scaled_extrude * (radius + stroke_width) *
(projected_center.w / params.camera_to_center_distance);
}
@@ -180,36 +165,35 @@ FragmentStage vertex vertexMain(thread const VertexStage vertx [[stage_in]],
.antialiasblur = antialiasblur,
#if !defined(HAS_UNIFORM_u_color)
.color = half4(colorFor(permutation.color, props.color, vertx.color, interp.color_t, expr)),
.color = half4(unpack_mix_color(vertx.color, interp.color_t)),
#endif
#if !defined(HAS_UNIFORM_u_radius)
.radius = half(radius),
.radius = radius,
#endif
#if !defined(HAS_UNIFORM_u_blur)
.blur = half(valueFor(permutation.blur, props.blur, vertx.blur, interp.blur_t, expr)),
.blur = half(unpack_mix_float(vertx.blur, interp.blur_t)),
#endif
#if !defined(HAS_UNIFORM_u_opacity)
.opacity = half(valueFor(permutation.opacity, props.opacity, vertx.opacity, interp.opacity_t, expr)),
.opacity = half(unpack_mix_float(vertx.opacity, interp.opacity_t)),
#endif
#if !defined(HAS_UNIFORM_u_stroke_color)
.stroke_color = half4(colorFor(permutation.stroke_color, props.stroke_color, vertx.stroke_color, interp.stroke_color_t, expr)),
.stroke_color = half4(unpack_mix_color(vertx.stroke_color, interp.stroke_color_t)),
#endif
#if !defined(HAS_UNIFORM_u_stroke_width)
.stroke_width = half(stroke_width),
#endif
#if !defined(HAS_UNIFORM_u_stroke_opacity)
.stroke_opacity = half(valueFor(permutation.stroke_opacity, props.stroke_opacity, vertx.stroke_opacity, interp.stroke_opacity_t, expr)),
.stroke_opacity = half(unpack_mix_float(vertx.stroke_opacity, interp.stroke_opacity_t)),
#endif
};
}
half4 fragment fragmentMain(FragmentStage in [[stage_in]],
device const CirclePaintParamsUBO& params [[buffer(9)]],
device const CircleEvaluatedPropsUBO& props [[buffer(10)]],
device const CirclePermutationUBO& permutation [[buffer(12)]]) {
if (permutation.overdrawInspector) {
return half4(1.0);
}
device const CircleEvaluatedPropsUBO& props [[buffer(10)]]) {
#if defined(OVERDRAW_INSPECTOR)
return half4(1.0);
#endif
#if defined(HAS_UNIFORM_u_color)
const half4 color = half4(props.color);
@@ -222,14 +206,14 @@ half4 fragment fragmentMain(FragmentStage in [[stage_in]],
const float radius = in.radius;
#endif
#if defined(HAS_UNIFORM_u_blur)
const half blur = props.blur;
const float blur = props.blur;
#else
const half blur = in.blur;
const float blur = in.blur;
#endif
#if defined(HAS_UNIFORM_u_opacity)
const half opacity = props.opacity;
const float opacity = props.opacity;
#else
const half opacity = in.opacity;
const float opacity = in.opacity;
#endif
#if defined(HAS_UNIFORM_u_stroke_color)
const half4 stroke_color = half4(props.stroke_color);
@@ -237,14 +221,14 @@ half4 fragment fragmentMain(FragmentStage in [[stage_in]],
const half4 stroke_color = in.stroke_color;
#endif
#if defined(HAS_UNIFORM_u_stroke_width)
const half stroke_width = props.stroke_width;
const float stroke_width = props.stroke_width;
#else
const half stroke_width = in.stroke_width;
const float stroke_width = in.stroke_width;
#endif
#if defined(HAS_UNIFORM_u_stroke_opacity)
const half stroke_opacity = props.stroke_opacity;
const float stroke_opacity = props.stroke_opacity;
#else
const half stroke_opacity = in.stroke_opacity;
const float stroke_opacity = in.stroke_opacity;
#endif
const float extrude_length = length(in.extrude);

View File

@@ -21,7 +21,6 @@ struct ShaderSource<BuiltIn::ClippingMaskProgram, gfx::Backend::Type::Metal> {
static constexpr auto name = "ClippingMaskProgram";
static constexpr auto vertexMainFunction = "vertexMain";
static constexpr auto fragmentMainFunction = "fragmentMain";
static constexpr auto hasPermutations = false;
static const std::array<AttributeInfo, 1> attributes;
static const std::array<UniformBlockInfo, 1> uniforms;

View File

@@ -13,7 +13,6 @@ struct ShaderSource<BuiltIn::CollisionBoxShader, gfx::Backend::Type::Metal> {
static constexpr auto name = "CollisionBoxShader";
static constexpr auto vertexMainFunction = "vertexMain";
static constexpr auto fragmentMainFunction = "fragmentMain";
static constexpr auto hasPermutations = false;
static const std::array<AttributeInfo, 5> attributes;
static const std::array<UniformBlockInfo, 1> uniforms;

View File

@@ -13,7 +13,6 @@ struct ShaderSource<BuiltIn::CollisionCircleShader, gfx::Backend::Type::Metal> {
static constexpr auto name = "CollisionCircleShader";
static constexpr auto vertexMainFunction = "vertexMain";
static constexpr auto fragmentMainFunction = "fragmentMain";
static constexpr auto hasPermutations = false;
static const std::array<AttributeInfo, 4> attributes;
static const std::array<UniformBlockInfo, 1> uniforms;

View File

@@ -27,30 +27,6 @@ float radians(float degrees) {
return M_PI_F * degrees / 180.0;
}
enum class AttributeSource : int32_t {
Constant,
PerVertex,
Computed,
};
struct Expression {};
struct Attribute {
AttributeSource source;
Expression expression;
};
struct alignas(16) ExpressionInputsUBO {
// These can use uint64_t in later versions of Metal
/* 0 */ uint32_t time_lo; // Current scene time (nanoseconds)
/* 4 */ uint32_t time_hi;
/* 8 */ uint32_t frame_lo; // Current frame count
/* 12 */ uint32_t frame_hi;
/* 16 */ float zoom; // Current zoom level
/* 20 */ float pad1, pad2, pad3;
/* 32 */
};
// Unpack a pair of values that have been packed into a single float.
// The packed values are assumed to be 8-bit unsigned integers, and are
// packed like so: packedValue = floor(input[0]) * 256 + input[1],
@@ -78,44 +54,6 @@ float4 unpack_mix_color(const float4 packedColors, const float t) {
decode_color(float2(packedColors[2], packedColors[3])), t);
}
float valueFor(device const Attribute& attrib,
const float constValue,
thread const float2& vertexValue,
const float t,
device const ExpressionInputsUBO&) {
switch (attrib.source) {
case AttributeSource::PerVertex: return unpack_mix_float(vertexValue, t);
case AttributeSource::Computed: // TODO
default:
case AttributeSource::Constant: return constValue;
}
}
// single packed color
float4 colorFor(device const Attribute& attrib,
device const float4& constValue,
thread const float2& vertexValue,
device const ExpressionInputsUBO&) {
switch (attrib.source) {
case AttributeSource::PerVertex: return decode_color(float2(vertexValue[0], vertexValue[1]));
case AttributeSource::Computed: // TODO
default:
case AttributeSource::Constant: return constValue;
}
}
// interpolated packed colors
float4 colorFor(device const Attribute& attrib,
device const float4& constValue,
const float4 vertexValue,
const float t,
device const ExpressionInputsUBO&) {
switch (attrib.source) {
case AttributeSource::PerVertex: return unpack_mix_color(vertexValue, t);
case AttributeSource::Computed: // TODO
default:
case AttributeSource::Constant: return constValue;
}
}
struct alignas(16) LineUBO {
float4x4 matrix;
float2 units_to_pixels;
@@ -163,21 +101,6 @@ struct alignas(16) LineGradientPropertiesUBO {
float pad1, pad2, pad3;
};
struct alignas(16) LinePermutationUBO {
Attribute color;
Attribute blur;
Attribute opacity;
Attribute gapwidth;
Attribute offset;
Attribute width;
Attribute floorwidth;
Attribute pattern_from;
Attribute pattern_to;
bool overdrawInspector;
uint8_t pad1, pad2, pad3;
float pad4;
};
struct alignas(16) LineInterpolationUBO {
float color_t;
float blur_t;
@@ -251,31 +174,6 @@ struct alignas(16) SymbolDrawablePaintUBO {
};
static_assert(sizeof(SymbolDrawablePaintUBO) == 3 * 16, "unexpected padding");
struct alignas(16) SymbolPermutationUBO {
Attribute fill_color;
Attribute halo_color;
Attribute opacity;
Attribute halo_width;
Attribute halo_blur;
int32_t /*bool*/ overdrawInspector;
float pad1, pad2, pad3;
};
static_assert(sizeof(SymbolPermutationUBO) == 4 * 16, "unexpected padding");
float4 patternFor(device const Attribute& attrib,
device const float4& constValue,
thread const ushort4& vertexValue,
device const float& ,
device const ExpressionInputsUBO&) {
switch (attrib.source) {
case AttributeSource::PerVertex: return float4(vertexValue);
case AttributeSource::Computed: // TODO
default:
case AttributeSource::Constant: return constValue;
}
}
// unpack pattern position
inline float2 get_pattern_pos(const float2 pixel_coord_upper, const float2 pixel_coord_lower,
const float2 pattern_size, const float tile_units_to_pixels, const float2 pos) {

View File

@@ -13,7 +13,6 @@ struct ShaderSource<BuiltIn::DebugShader, gfx::Backend::Type::Metal> {
static constexpr auto name = "DebugShader";
static constexpr auto vertexMainFunction = "vertexMain";
static constexpr auto fragmentMainFunction = "fragmentMain";
static constexpr auto hasPermutations = false;
static const std::array<AttributeInfo, 1> attributes;
static const std::array<UniformBlockInfo, 1> uniforms;

View File

@@ -13,10 +13,9 @@ struct ShaderSource<BuiltIn::FillShader, gfx::Backend::Type::Metal> {
static constexpr auto name = "FillShader";
static constexpr auto vertexMainFunction = "vertexMain";
static constexpr auto fragmentMainFunction = "fragmentMain";
static constexpr auto hasPermutations = true;
static const std::array<AttributeInfo, 3> attributes;
static const std::array<UniformBlockInfo, 5> uniforms;
static const std::array<UniformBlockInfo, 3> uniforms;
static const std::array<TextureInfo, 0> textures;
static constexpr auto source = R"(
@@ -57,35 +56,26 @@ struct alignas(16) FillInterpolateUBO {
float opacity_t;
};
struct alignas(16) FillPermutationUBO {
Attribute color;
Attribute opacity;
bool overdrawInspector;
};
FragmentStage vertex vertexMain(thread const VertexStage vertx [[stage_in]],
device const FillDrawableUBO& drawable [[buffer(3)]],
device const FillEvaluatedPropsUBO& props [[buffer(4)]],
device const FillInterpolateUBO& interp [[buffer(5)]],
device const FillPermutationUBO& permutation [[buffer(6)]],
device const ExpressionInputsUBO& expr [[buffer(7)]]) {
device const FillInterpolateUBO& interp [[buffer(5)]]) {
return {
.position = drawable.matrix * float4(float2(vertx.position), 0.0f, 1.0f),
#if !defined(HAS_UNIFORM_u_color)
.color = half4(colorFor(permutation.color, props.color, vertx.color, interp.color_t, expr)),
.color = half4(unpack_mix_color(vertx.color, interp.color_t)),
#endif
#if !defined(HAS_UNIFORM_u_opacity)
.opacity = half(valueFor(permutation.opacity, props.opacity, vertx.opacity, interp.opacity_t, expr)),
.opacity = half(unpack_mix_float(vertx.opacity, interp.opacity_t)),
#endif
};
}
half4 fragment fragmentMain(FragmentStage in [[stage_in]],
device const FillEvaluatedPropsUBO& props [[buffer(4)]],
device const FillPermutationUBO& permutation [[buffer(6)]]) {
if (permutation.overdrawInspector) {
return half4(1.0);
}
device const FillEvaluatedPropsUBO& props [[buffer(4)]]) {
#if defined(OVERDRAW_INSPECTOR)
return half4(1.0);
#endif
#if defined(HAS_UNIFORM_u_color)
const half4 color = half4(props.color);
@@ -109,10 +99,9 @@ struct ShaderSource<BuiltIn::FillOutlineShader, gfx::Backend::Type::Metal> {
static constexpr auto name = "FillOutlineShader";
static constexpr auto vertexMainFunction = "vertexMain";
static constexpr auto fragmentMainFunction = "fragmentMain";
static constexpr auto hasPermutations = true;
static const std::array<AttributeInfo, 3> attributes;
static const std::array<UniformBlockInfo, 5> uniforms;
static const std::array<UniformBlockInfo, 3> uniforms;
static const std::array<TextureInfo, 0> textures;
static constexpr auto source = R"(
@@ -149,37 +138,28 @@ struct alignas(16) FillOutlineInterpolateUBO {
float opacity_t;
};
struct alignas(16) FillOutlinePermutationUBO {
Attribute outline_color;
Attribute opacity;
bool overdrawInspector;
};
FragmentStage vertex vertexMain(thread const VertexStage vertx [[stage_in]],
device const FillOutlineDrawableUBO& drawable [[buffer(3)]],
device const FillOutlineEvaluatedPropsUBO& props [[buffer(4)]],
device const FillOutlineInterpolateUBO& interp [[buffer(5)]],
device const FillOutlinePermutationUBO& permutation [[buffer(6)]],
device const ExpressionInputsUBO& expr [[buffer(7)]]) {
device const FillOutlineInterpolateUBO& interp [[buffer(5)]]) {
const float4 position = drawable.matrix * float4(float2(vertx.position), 0.0f, 1.0f);
return {
.position = position,
.pos = (position.xy / position.w + 1.0) / 2.0 * drawable.world,
#if !defined(HAS_UNIFORM_u_outline_color)
.outline_color = half4(colorFor(permutation.outline_color, props.outline_color, vertx.outline_color, interp.outline_color_t, expr)),
.outline_color = half4(unpack_mix_color(vertx.outline_color, interp.outline_color_t)),
#endif
#if !defined(HAS_UNIFORM_u_opacity)
.opacity = half( valueFor(permutation.opacity, props.opacity, vertx.opacity, interp.opacity_t, expr)),
.opacity = half(unpack_mix_float(vertx.opacity, interp.opacity_t)),
#endif
};
}
half4 fragment fragmentMain(FragmentStage in [[stage_in]],
device const FillOutlineEvaluatedPropsUBO& props [[buffer(4)]],
device const FillOutlinePermutationUBO& permutation [[buffer(6)]]) {
if (permutation.overdrawInspector) {
return half4(1.0);
}
device const FillOutlineEvaluatedPropsUBO& props [[buffer(4)]]) {
#if defined(OVERDRAW_INSPECTOR)
return half4(1.0);
#endif
// TODO: Cause metal line primitive only support draw 1 pixel width line
// use alpha to provide edge antialiased is no point
@@ -209,10 +189,9 @@ struct ShaderSource<BuiltIn::FillPatternShader, gfx::Backend::Type::Metal> {
static constexpr auto name = "FillPatternShader";
static constexpr auto vertexMainFunction = "vertexMain";
static constexpr auto fragmentMainFunction = "fragmentMain";
static constexpr auto hasPermutations = true;
static const std::array<AttributeInfo, 4> attributes;
static const std::array<UniformBlockInfo, 6> uniforms;
static const std::array<UniformBlockInfo, 4> uniforms;
static const std::array<TextureInfo, 1> textures;
static constexpr auto source = R"(
@@ -236,10 +215,10 @@ struct FragmentStage {
float2 v_pos_b;
#if !defined(HAS_UNIFORM_u_pattern_from)
float4 pattern_from;
half4 pattern_from;
#endif
#if !defined(HAS_UNIFORM_u_pattern_to)
float4 pattern_to;
half4 pattern_to;
#endif
#if !defined(HAS_UNIFORM_u_opacity)
half opacity;
@@ -270,30 +249,21 @@ struct alignas(16) FillPatternInterpolateUBO {
float opacity_t;
};
struct alignas(16) FillPatternPermutationUBO {
Attribute pattern_from;
Attribute pattern_to;
Attribute opacity;
bool overdrawInspector;
};
FragmentStage vertex vertexMain(thread const VertexStage vertx [[stage_in]],
device const FillPatternDrawableUBO& drawable [[buffer(4)]],
device const FillPatternTilePropsUBO& tileProps [[buffer(5)]],
device const FillPatternEvaluatedPropsUBO& props [[buffer(6)]],
device const FillPatternInterpolateUBO& interp [[buffer(7)]],
device const FillPatternPermutationUBO& permutation [[buffer(8)]],
device const ExpressionInputsUBO& expr [[buffer(9)]]) {
device const FillPatternInterpolateUBO& interp [[buffer(7)]]) {
#if defined(HAS_UNIFORM_u_pattern_from)
const auto pattern_from = tileProps.pattern_from;
const auto pattern_from = float4(tileProps.pattern_from);
#else
const auto pattern_from = patternFor(permutation.pattern_from, tileProps.pattern_from, vertx.pattern_from, interp.pattern_from_t, expr);
const auto pattern_from = float4(vertx.pattern_from);
#endif
#if defined(HAS_UNIFORM_u_pattern_to)
const auto pattern_to = tileProps.pattern_to;
const auto pattern_to = float4(tileProps.pattern_to);
#else
const auto pattern_to = patternFor(permutation.pattern_to, tileProps.pattern_to, vertx.pattern_to, interp.pattern_to_t, expr);
const auto pattern_to = float4(vertx.pattern_to);
#endif
const float2 pattern_tl_a = pattern_from.xy;
@@ -315,13 +285,13 @@ FragmentStage vertex vertexMain(thread const VertexStage vertx [[stage_in]],
.v_pos_a = get_pattern_pos(drawable.pixel_coord_upper, drawable.pixel_coord_lower, fromScale * display_size_a, tileZoomRatio, postion),
.v_pos_b = get_pattern_pos(drawable.pixel_coord_upper, drawable.pixel_coord_lower, toScale * display_size_b, tileZoomRatio, postion),
#if !defined(HAS_UNIFORM_u_pattern_from)
.pattern_from = pattern_from,
.pattern_from = half4(pattern_from),
#endif
#if !defined(HAS_UNIFORM_u_pattern_to)
.pattern_to = pattern_to,
.pattern_to = half4(pattern_to),
#endif
#if !defined(HAS_UNIFORM_u_opacity)
.opacity = half(valueFor(permutation.opacity, props.opacity, vertx.opacity, interp.opacity_t, expr)),
.opacity = half(unpack_mix_float(vertx.opacity, interp.opacity_t)),
#endif
};
}
@@ -330,23 +300,22 @@ half4 fragment fragmentMain(FragmentStage in [[stage_in]],
device const FillPatternDrawableUBO& drawable [[buffer(4)]],
device const FillPatternTilePropsUBO& tileProps [[buffer(5)]],
device const FillPatternEvaluatedPropsUBO& props [[buffer(6)]],
device const FillPatternPermutationUBO& permutation [[buffer(8)]],
texture2d<float, access::sample> image0 [[texture(0)]],
sampler image0_sampler [[sampler(0)]]) {
if (permutation.overdrawInspector) {
return half4(1.0);
}
#if defined(OVERDRAW_INSPECTOR)
return half4(1.0);
#endif
#if defined(HAS_UNIFORM_u_pattern_from)
const auto pattern_from = tileProps.pattern_from;
const auto pattern_from = float4(tileProps.pattern_from);
#else
const auto pattern_from = in.pattern_from;
const auto pattern_from = float4(in.pattern_from);
#endif
#if defined(HAS_UNIFORM_u_pattern_to)
const auto pattern_to = tileProps.pattern_to;
const auto pattern_to = float4(tileProps.pattern_to);
#else
const auto pattern_to = in.pattern_to;
const auto pattern_to = float4(in.pattern_to);
#endif
#if defined(HAS_UNIFORM_u_opacity)
@@ -378,10 +347,9 @@ struct ShaderSource<BuiltIn::FillOutlinePatternShader, gfx::Backend::Type::Metal
static constexpr auto name = "FillOutlinePatternShader";
static constexpr auto vertexMainFunction = "vertexMain";
static constexpr auto fragmentMainFunction = "fragmentMain";
static constexpr auto hasPermutations = true;
static const std::array<AttributeInfo, 4> attributes;
static const std::array<UniformBlockInfo, 6> uniforms;
static const std::array<UniformBlockInfo, 4> uniforms;
static const std::array<TextureInfo, 1> textures;
static constexpr auto source = R"(
@@ -407,10 +375,10 @@ struct FragmentStage {
float2 v_pos;
#if !defined(HAS_UNIFORM_u_pattern_from)
float4 pattern_from;
half4 pattern_from;
#endif
#if !defined(HAS_UNIFORM_u_pattern_to)
float4 pattern_to;
half4 pattern_to;
#endif
#if !defined(HAS_UNIFORM_u_opacity)
half opacity;
@@ -442,34 +410,25 @@ struct alignas(16) FillOutlinePatternInterpolateUBO {
float opacity_t;
};
struct alignas(16) FillOutlinePatternPermutationUBO {
Attribute pattern_from;
Attribute pattern_to;
Attribute opacity;
bool overdrawInspector;
};
FragmentStage vertex vertexMain(thread const VertexStage vertx [[stage_in]],
device const FillOutlinePatternDrawableUBO& drawable [[buffer(4)]],
device const FillOutlinePatternTilePropsUBO& tileProps [[buffer(5)]],
device const FillOutlinePatternEvaluatedPropsUBO& props [[buffer(6)]],
device const FillOutlinePatternInterpolateUBO& interp [[buffer(7)]],
device const FillOutlinePatternPermutationUBO& permutation [[buffer(8)]],
device const ExpressionInputsUBO& expr [[buffer(9)]]) {
device const FillOutlinePatternInterpolateUBO& interp [[buffer(7)]]) {
#if defined(HAS_UNIFORM_u_pattern_from)
const auto pattern_from = tileProps.pattern_from;
#else
const auto pattern_from = patternFor(permutation.pattern_from, tileProps.pattern_from, vertx.pattern_from, interp.pattern_from_t, expr);
const auto pattern_from = float4(vertx.pattern_from);
#endif
#if defined(HAS_UNIFORM_u_pattern_to)
const auto pattern_to = tileProps.pattern_to;
#else
const auto pattern_to = patternFor(permutation.pattern_to, tileProps.pattern_to, vertx.pattern_to, interp.pattern_to_t, expr);
const auto pattern_to = float4(vertx.pattern_to);
#endif
#if !defined(HAS_UNIFORM_u_opacity)
const auto opacity = valueFor(permutation.opacity, props.opacity, vertx.opacity, interp.opacity_t, expr);
const auto opacity = unpack_mix_float(vertx.opacity, interp.opacity_t);
#endif
const float2 pattern_tl_a = pattern_from.xy;
@@ -494,10 +453,10 @@ FragmentStage vertex vertexMain(thread const VertexStage vertx [[stage_in]],
.v_pos = (position.xy / position.w + 1.0) / 2.0 * drawable.world,
#if !defined(HAS_UNIFORM_u_pattern_from)
.pattern_from = pattern_from,
.pattern_from = half4(pattern_from),
#endif
#if !defined(HAS_UNIFORM_u_pattern_to)
.pattern_to = pattern_to,
.pattern_to = half4(pattern_to),
#endif
#if !defined(HAS_UNIFORM_u_opacity)
.opacity = half(opacity),
@@ -509,23 +468,22 @@ half4 fragment fragmentMain(FragmentStage in [[stage_in]],
device const FillOutlinePatternDrawableUBO& drawable [[buffer(4)]],
device const FillOutlinePatternTilePropsUBO& tileProps [[buffer(5)]],
device const FillOutlinePatternEvaluatedPropsUBO& props [[buffer(6)]],
device const FillOutlinePatternPermutationUBO& permutation [[buffer(8)]],
texture2d<float, access::sample> image0 [[texture(0)]],
sampler image0_sampler [[sampler(0)]]) {
if (permutation.overdrawInspector) {
return half4(1.0);
}
#if defined(OVERDRAW_INSPECTOR)
return half4(1.0);
#endif
#if defined(HAS_UNIFORM_u_pattern_from)
const auto pattern_from = tileProps.pattern_from;
const auto pattern_from = float4(tileProps.pattern_from);
#else
const auto pattern_from = in.pattern_from;
const auto pattern_from = float4(in.pattern_from);
#endif
#if defined(HAS_UNIFORM_u_pattern_to)
const auto pattern_to = tileProps.pattern_to;
const auto pattern_to = float4(tileProps.pattern_to);
#else
const auto pattern_to = in.pattern_to;
const auto pattern_to = float4(in.pattern_to);
#endif
#if defined(HAS_UNIFORM_u_opacity)

View File

@@ -13,10 +13,9 @@ struct ShaderSource<BuiltIn::FillExtrusionShader, gfx::Backend::Type::Metal> {
static constexpr auto name = "FillExtrusionShader";
static constexpr auto vertexMainFunction = "vertexMain";
static constexpr auto fragmentMainFunction = "fragmentMain";
static constexpr auto hasPermutations = false;
static const std::array<AttributeInfo, 5> attributes;
static const std::array<UniformBlockInfo, 5> uniforms;
static const std::array<UniformBlockInfo, 3> uniforms;
static const std::array<TextureInfo, 0> textures;
static constexpr auto source = R"(
@@ -57,25 +56,19 @@ struct alignas(16) FillExtrusionDrawablePropsUBO {
};
static_assert(sizeof(FillExtrusionDrawablePropsUBO) == 5 * 16, "unexpected padding");
struct alignas(16) FillExtrusionPermutationUBO {
/* 0 */ Attribute color;
/* 8 */ Attribute base;
/* 16 */ Attribute height;
/* 24 */ Attribute pattern_from;
/* 32 */ Attribute pattern_to;
/* 40 */ bool overdrawInspector;
/* 41 */ uint8_t pad1, pad2, pad3;
/* 44 */ float pad4;
/* 48 */
};
static_assert(sizeof(FillExtrusionPermutationUBO) == 3 * 16, "unexpected padding");
struct VertexStage {
short2 pos [[attribute(0)]];
short4 normal_ed [[attribute(1)]];
#if !defined(HAS_UNIFORM_u_color)
float4 color [[attribute(2)]];
#endif
#if !defined(HAS_UNIFORM_u_base)
float base [[attribute(3)]];
#endif
#if !defined(HAS_UNIFORM_u_height)
float height [[attribute(4)]];
#endif
};
struct FragmentStage {
@@ -91,27 +84,36 @@ struct FragmentOutput {
FragmentStage vertex vertexMain(thread const VertexStage vertx [[stage_in]],
device const FillExtrusionDrawableUBO& fill [[buffer(5)]],
device const FillExtrusionDrawablePropsUBO& props [[buffer(6)]],
device const FillExtrusionInterpolateUBO& interp [[buffer(7)]],
device const FillExtrusionPermutationUBO& permutation [[buffer(8)]],
device const ExpressionInputsUBO& expr [[buffer(9)]]) {
device const FillExtrusionInterpolateUBO& interp [[buffer(7)]]) {
const float u_base = props.light_position_base.w;
const auto base = max(valueFor(permutation.base, u_base, vertx.base, interp.base_t, expr), 0.0);
const auto height = max(valueFor(permutation.height, props.height, vertx.height, interp.height_t, expr), 0.0);
#if defined(HAS_UNIFORM_u_base)
const auto base = props.light_position_base.w;
#else
const auto base = max(unpack_mix_float(vertx.base, interp.base_t), 0.0);
#endif
#if defined(HAS_UNIFORM_u_height)
const auto height = props.height;
#else
const auto height = max(unpack_mix_float(vertx.height, interp.height_t), 0.0);
#endif
const float3 normal = float3(vertx.normal_ed.xyz);
const float t = glMod(normal.x, 2.0);
const float z = (t != 0.0) ? height : base; // TODO: This would come out wrong on GL for negative values, check it...
const float4 position = fill.matrix * float4(float2(vertx.pos), z, 1);
if (permutation.overdrawInspector) {
return {
.position = position,
.color = half4(1.0),
};
}
#if defined(OVERDRAW_INSPECTOR)
return {
.position = position,
.color = half4(1.0),
};
#endif
auto color = colorFor(permutation.color, props.color, vertx.color, interp.color_t, expr);
#if defined(HAS_UNIFORM_u_color)
auto color = props.color;
#else
auto color = unpack_mix_color(vertx.color, interp.color_t);
#endif
// Relative luminance (how dark/bright is the surface color?)
const float luminance = color.r * 0.2126 + color.g * 0.7152 + color.b * 0.0722;

View File

@@ -13,10 +13,9 @@ struct ShaderSource<BuiltIn::FillExtrusionPatternShader, gfx::Backend::Type::Met
static constexpr auto name = "FillExtrusionPatternShader";
static constexpr auto vertexMainFunction = "vertexMain";
static constexpr auto fragmentMainFunction = "fragmentMain";
static constexpr auto hasPermutations = false;
static const std::array<AttributeInfo, 6> attributes;
static const std::array<UniformBlockInfo, 6> uniforms;
static const std::array<UniformBlockInfo, 4> uniforms;
static const std::array<TextureInfo, 1> textures;
static constexpr auto source = R"(
@@ -63,35 +62,36 @@ struct alignas(16) FillExtrusionDrawablePropsUBO {
};
static_assert(sizeof(FillExtrusionDrawablePropsUBO) == 5 * 16, "unexpected padding");
struct alignas(16) FillExtrusionPermutationUBO {
/* 0 */ Attribute color;
/* 8 */ Attribute base;
/* 16 */ Attribute height;
/* 24 */ Attribute pattern_from;
/* 32 */ Attribute pattern_to;
/* 40 */ bool overdrawInspector;
/* 41 */ uint8_t pad1, pad2, pad3;
/* 44 */ float pad4;
/* 48 */
};
static_assert(sizeof(FillExtrusionPermutationUBO) == 3 * 16, "unexpected padding");
struct VertexStage {
short2 pos [[attribute(0)]];
short4 normal_ed [[attribute(1)]];
#if !defined(HAS_UNIFORM_u_base)
float base [[attribute(2)]];
#endif
#if !defined(HAS_UNIFORM_u_height)
float height [[attribute(3)]];
#endif
#if !defined(HAS_UNIFORM_u_pattern_from)
ushort4 pattern_from [[attribute(4)]];
#endif
#if !defined(HAS_UNIFORM_u_pattern_to)
ushort4 pattern_to [[attribute(5)]];
#endif
};
struct FragmentStage {
float4 position [[position, invariant]];
float4 lighting;
float4 pattern_from;
float4 pattern_to;
float2 pos_a;
float2 pos_b;
#if !defined(HAS_UNIFORM_u_pattern_from)
half4 pattern_from;
#endif
#if !defined(HAS_UNIFORM_u_pattern_to)
half4 pattern_to;
#endif
};
struct FragmentOutput {
@@ -103,13 +103,18 @@ FragmentStage vertex vertexMain(thread const VertexStage vertx [[stage_in]],
device const FillExtrusionDrawableUBO& fill [[buffer(6)]],
device const FillExtrusionDrawablePropsUBO& props [[buffer(7)]],
device const FillExtrusionDrawableTilePropsUBO& tileProps [[buffer(8)]],
device const FillExtrusionInterpolateUBO& interp [[buffer(9)]],
device const FillExtrusionPermutationUBO& permutation [[buffer(10)]],
device const ExpressionInputsUBO& expr [[buffer(11)]]) {
device const FillExtrusionInterpolateUBO& interp [[buffer(9)]]) {
const float u_base = props.light_position_base.w;
const auto base = max(valueFor(permutation.base, u_base, vertx.base, interp.base_t, expr), 0.0);
const auto height = max(valueFor(permutation.height, props.height, vertx.height, interp.height_t, expr), 0.0);
#if defined(HAS_UNIFORM_u_base)
const auto base = props.light_position_base.w;
#else
const auto base = max(unpack_mix_float(vertx.base, interp.base_t), 0.0);
#endif
#if defined(HAS_UNIFORM_u_height)
const auto height = props.height;
#else
const auto height = max(unpack_mix_float(vertx.height, interp.height_t), 0.0);
#endif
const float3 normal = float3(vertx.normal_ed.xyz);
const float edgedistance = vertx.normal_ed.w;
@@ -117,34 +122,42 @@ FragmentStage vertex vertexMain(thread const VertexStage vertx [[stage_in]],
const float z = (t != 0.0) ? height : base; // TODO: This would come out wrong on GL for negative values, check it...
const float4 position = fill.matrix * float4(float2(vertx.pos), z, 1);
const auto pattern_from = patternFor(permutation.pattern_from, tileProps.pattern_from, vertx.pattern_from, interp.pattern_from_t, expr);
const auto pattern_to = patternFor(permutation.pattern_to, tileProps.pattern_to, vertx.pattern_to, interp.pattern_to_t, expr);
#if defined(OVERDRAW_INSPECTOR)
return {
.position = position,
.lighting = float4(1.0),
.pattern_from = float4(1.0),
.pattern_to = float4(1.0),
.pos_a = float2(1.0),
.pos_b = float2(1.0),
};
#endif
if (permutation.overdrawInspector) {
return {
.position = position,
.lighting = float4(1.0),
.pattern_from = float4(1.0),
.pattern_to = float4(1.0),
.pos_a = float2(1.0),
.pos_b = float2(1.0),
};
}
#if defined(HAS_UNIFORM_u_pattern_from)
const auto pattern_from = tileProps.pattern_from;
#else
const auto pattern_from = float4(vertx.pattern_from);
#endif
#if defined(HAS_UNIFORM_u_pattern_to)
const auto pattern_to = tileProps.pattern_to;
#else
const auto pattern_to = float4(vertx.pattern_to);
#endif
float2 pattern_tl_a = pattern_from.xy;
float2 pattern_br_a = pattern_from.zw;
float2 pattern_tl_b = pattern_to.xy;
float2 pattern_br_b = pattern_to.zw;
const float2 pattern_tl_a = pattern_from.xy;
const float2 pattern_br_a = pattern_from.zw;
const float2 pattern_tl_b = pattern_to.xy;
const float2 pattern_br_b = pattern_to.zw;
float pixelRatio = fill.scale.x;
float tileZoomRatio = fill.scale.y;
float fromScale = fill.scale.z;
float toScale = fill.scale.w;
const float pixelRatio = fill.scale.x;
const float tileZoomRatio = fill.scale.y;
const float fromScale = fill.scale.z;
const float toScale = fill.scale.w;
float2 display_size_a = float2((pattern_br_a.x - pattern_tl_a.x) / pixelRatio, (pattern_br_a.y - pattern_tl_a.y) / pixelRatio);
float2 display_size_b = float2((pattern_br_b.x - pattern_tl_b.x) / pixelRatio, (pattern_br_b.y - pattern_tl_b.y) / pixelRatio);
const float2 display_size_a = float2((pattern_br_a.x - pattern_tl_a.x) / pixelRatio, (pattern_br_a.y - pattern_tl_a.y) / pixelRatio);
const float2 display_size_b = float2((pattern_br_b.x - pattern_tl_b.x) / pixelRatio, (pattern_br_b.y - pattern_tl_b.y) / pixelRatio);
float2 pos = normal.x == 1.0 && normal.y == 0.0 && normal.z == 16384.0
const float2 pos = normal.x == 1.0 && normal.y == 0.0 && normal.z == 16384.0
? float2(vertx.pos) // extrusion top
: float2(edgedistance, z * fill.height_factor); // extrusion side
@@ -166,8 +179,12 @@ FragmentStage vertex vertexMain(thread const VertexStage vertx [[stage_in]],
return {
.position = position,
.lighting = lighting,
.pattern_from = pattern_from,
.pattern_to = pattern_to,
#if !defined(HAS_UNIFORM_u_pattern_from)
.pattern_from = half4(pattern_from),
#endif
#if !defined(HAS_UNIFORM_u_pattern_from)
.pattern_to = half4(pattern_to),
#endif
.pos_a = get_pattern_pos(fill.pixel_coord_upper, fill.pixel_coord_lower, fromScale * display_size_a, tileZoomRatio, pos),
.pos_b = get_pattern_pos(fill.pixel_coord_upper, fill.pixel_coord_lower, toScale * display_size_b, tileZoomRatio, pos),
};
@@ -176,19 +193,28 @@ FragmentStage vertex vertexMain(thread const VertexStage vertx [[stage_in]],
fragment FragmentOutput fragmentMain(FragmentStage in [[stage_in]],
device const FillExtrusionDrawableUBO& fill [[buffer(6)]],
device const FillExtrusionDrawablePropsUBO& props [[buffer(7)]],
device const FillExtrusionPermutationUBO& permutation [[buffer(10)]],
device const FillExtrusionDrawableTilePropsUBO& tileProps [[buffer(8)]],
texture2d<float, access::sample> image0 [[texture(0)]],
sampler image0_sampler [[sampler(0)]]) {
if (permutation.overdrawInspector) {
return {half4(1.0)/*, in.position.z*/};
}
#if defined(OVERDRAW_INSPECTOR)
return {half4(1.0)/*, in.position.z*/};
#endif
#if defined(HAS_UNIFORM_u_pattern_from)
const auto pattern_from = float4(tileProps.pattern_from);
#else
const auto pattern_from = float4(in.pattern_from);
#endif
#if defined(HAS_UNIFORM_u_pattern_to)
const auto pattern_to = float4(tileProps.pattern_to);
#else
const auto pattern_to = float4(in.pattern_to);
#endif
const float2 pattern_tl_a = in.pattern_from.xy;
const float2 pattern_br_a = in.pattern_from.zw;
const float2 pattern_tl_b = in.pattern_to.xy;
const float2 pattern_br_b = in.pattern_to.zw;
const float2 pattern_tl_a = pattern_from.xy;
const float2 pattern_br_a = pattern_from.zw;
const float2 pattern_tl_b = pattern_to.xy;
const float2 pattern_br_b = pattern_to.zw;
const float2 imagecoord = glMod(in.pos_a, 1.0);
const float2 pos = mix(pattern_tl_a / fill.texsize, pattern_br_a / fill.texsize, imagecoord);

View File

@@ -13,18 +13,22 @@ struct ShaderSource<BuiltIn::HeatmapShader, gfx::Backend::Type::Metal> {
static constexpr auto name = "HeatmapShader";
static constexpr auto vertexMainFunction = "vertexMain";
static constexpr auto fragmentMainFunction = "fragmentMain";
static constexpr auto hasPermutations = false;
static const std::array<AttributeInfo, 3> attributes;
static const std::array<UniformBlockInfo, 5> uniforms;
static const std::array<UniformBlockInfo, 3> uniforms;
static const std::array<TextureInfo, 0> textures;
static constexpr auto source = R"(
struct VertexStage {
short2 pos [[attribute(0)]];
#if !defined(HAS_UNIFORM_u_weight)
float2 weight [[attribute(1)]];
#endif
#if !defined(HAS_UNIFORM_u_radius)
float2 radius [[attribute(2)]];
#endif
};
struct FragmentStage {
@@ -53,14 +57,6 @@ struct alignas(16) HeatmapInterpolateUBO {
float2 pad1;
};
struct alignas(16) HeatmapPermutationUBO {
Attribute weight;
Attribute radius;
bool overdrawInspector;
uint8_t pad1, pad2, pad3;
float pad4, pad5, pad6;
};
// Effective "0" in the kernel density texture to adjust the kernel size to;
// this empirically chosen number minimizes artifacts on overlapping kernels
// for typical heatmap cases (assuming clustered source)
@@ -72,15 +68,21 @@ constant const float ZERO = 1.0 / 255.0 / 16.0;
FragmentStage vertex vertexMain(thread const VertexStage vertx [[stage_in]],
device const HeatmapDrawableUBO& drawable [[buffer(3)]],
device const HeatmapEvaluatedPropsUBO& props [[buffer(4)]],
device const HeatmapInterpolateUBO& interp [[buffer(5)]],
device const HeatmapPermutationUBO& permutation [[buffer(6)]],
device const ExpressionInputsUBO& expr [[buffer(7)]]) {
device const HeatmapInterpolateUBO& interp [[buffer(5)]]) {
#if defined(HAS_UNIFORM_u_weight)
const auto weight = props.weight;
#else
const auto weight = unpack_mix_float(vertx.weight, interp.weight_t);
#endif
#if defined(HAS_UNIFORM_u_radius)
const auto radius = props.radius;
#else
const auto radius = unpack_mix_float(vertx.radius, interp.radius_t);
#endif
const auto weight = valueFor(permutation.weight, props.weight, vertx.weight, interp.weight_t, expr);
const auto radius = valueFor(permutation.radius, props.radius, vertx.radius, interp.radius_t, expr);
// unencode the extrusion vector that we snuck into the a_pos vector
float2 unscaled_extrude = float2(glMod(float2(vertx.pos), 2.0) * 2.0 - 1.0);
const float2 unscaled_extrude = float2(glMod(float2(vertx.pos), 2.0) * 2.0 - 1.0);
// This 'extrude' comes in ranging from [-1, -1], to [1, 1]. We'll use
// it to produce the vertices of a square mesh framing the point feature
@@ -93,39 +95,35 @@ FragmentStage vertex vertexMain(thread const VertexStage vertx [[stage_in]],
// weight * u_intensity * GAUSS_COEF * exp(-0.5 * 3.0^2 * S^2) == ZERO
// Which solves to:
// S = sqrt(-2.0 * log(ZERO / (weight * u_intensity * GAUSS_COEF))) / 3.0
float S = sqrt(-2.0 * log(ZERO / weight / props.intensity / GAUSS_COEF)) / 3.0;
const float S = sqrt(-2.0 * log(ZERO / weight / props.intensity / GAUSS_COEF)) / 3.0;
// Pass the varying in units of radius
float2 extrude = S * unscaled_extrude;
const float2 extrude = S * unscaled_extrude;
// Scale by radius and the zoom-based scale factor to produce actual
// mesh position
float2 scaled_extrude = extrude * radius * drawable.extrude_scale;
const float2 scaled_extrude = extrude * radius * drawable.extrude_scale;
// multiply a_pos by 0.5, since we had it * 2 in order to sneak
// in extrusion data
float4 pos = float4(floor(float2(vertx.pos) * 0.5) + scaled_extrude, 0, 1);
const float4 pos = float4(floor(float2(vertx.pos) * 0.5) + scaled_extrude, 0, 1);
float4 position = drawable.matrix * pos;
return {
.position = position,
.position = drawable.matrix * pos,
.weight = weight,
.extrude = extrude,
};
}
half4 fragment fragmentMain(FragmentStage in [[stage_in]],
device const HeatmapEvaluatedPropsUBO& props [[buffer(4)]],
device const HeatmapPermutationUBO& permutation [[buffer(6)]]) {
if (permutation.overdrawInspector) {
return half4(1.0);
}
device const HeatmapEvaluatedPropsUBO& props [[buffer(4)]]) {
#if defined(OVERDRAW_INSPECTOR)
return half4(1.0);
#endif
// Kernel density estimation with a Gaussian kernel of size 5x5
float d = -0.5 * 3.0 * 3.0 * dot(in.extrude, in.extrude);
float val = in.weight * props.intensity * GAUSS_COEF * exp(d);
const float d = -0.5 * 3.0 * 3.0 * dot(in.extrude, in.extrude);
const float val = in.weight * props.intensity * GAUSS_COEF * exp(d);
return half4(val, 1.0, 1.0, 1.0);
}

View File

@@ -13,7 +13,6 @@ struct ShaderSource<BuiltIn::HeatmapTextureShader, gfx::Backend::Type::Metal> {
static constexpr auto name = "HeatmapTextureShader";
static constexpr auto vertexMainFunction = "vertexMain";
static constexpr auto fragmentMainFunction = "fragmentMain";
static constexpr auto hasPermutations = false;
static const std::array<AttributeInfo, 1> attributes;
static const std::array<UniformBlockInfo, 1> uniforms;
@@ -57,9 +56,9 @@ half4 fragment fragmentMain(FragmentStage in [[stage_in]],
sampler image_sampler [[sampler(0)]],
sampler color_ramp_sampler [[sampler(1)]]) {
if (drawable.overdrawInspector) {
return half4(0.0);
}
#if defined(OVERDRAW_INSPECTOR)
return half4(1.0);
#endif
float t = image.sample(image_sampler, in.pos).r;
float4 color = color_ramp.sample(color_ramp_sampler, float2(t, 0.5));

View File

@@ -13,7 +13,6 @@ struct ShaderSource<BuiltIn::HillshadeShader, gfx::Backend::Type::Metal> {
static constexpr auto name = "HillshadeShader";
static constexpr auto vertexMainFunction = "vertexMain";
static constexpr auto fragmentMainFunction = "fragmentMain";
static constexpr auto hasPermutations = false;
static const std::array<AttributeInfo, 2> attributes;
static const std::array<UniformBlockInfo, 2> uniforms;
@@ -35,9 +34,6 @@ struct alignas(16) HillshadeDrawableUBO {
float4x4 matrix;
float2 latrange;
float2 light;
bool overdrawInspector;
uint8_t pad1, pad2, pad3;
float pad4, pad5, pad6;
};
struct alignas(16) HillshadeEvaluatedPropsUBO {
@@ -64,10 +60,9 @@ half4 fragment fragmentMain(FragmentStage in [[stage_in]],
device const HillshadeEvaluatedPropsUBO& props [[buffer(3)]],
texture2d<float, access::sample> image [[texture(0)]],
sampler image_sampler [[sampler(0)]]) {
if (drawable.overdrawInspector) {
return half4(1.0);
}
#if defined(OVERDRAW_INSPECTOR)
return half4(1.0);
#endif
float4 pixel = image.sample(image_sampler, in.pos);

View File

@@ -13,14 +13,12 @@ struct ShaderSource<BuiltIn::HillshadePrepareShader, gfx::Backend::Type::Metal>
static constexpr auto name = "HillshadePrepareShader";
static constexpr auto vertexMainFunction = "vertexMain";
static constexpr auto fragmentMainFunction = "fragmentMain";
static constexpr auto hasPermutations = false;
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 {
short2 pos [[attribute(0)]];
short2 texture_pos [[attribute(1)]];
@@ -37,9 +35,6 @@ struct alignas(16) HillshadePrepareDrawableUBO {
float2 dimension;
float zoom;
float maxzoom;
bool overdrawInspector;
uint8_t pad1, pad2, pad3;
float pad4, pad5, pad6;
};
FragmentStage vertex vertexMain(thread const VertexStage vertx [[stage_in]],
@@ -68,10 +63,9 @@ half4 fragment fragmentMain(FragmentStage in [[stage_in]],
device const HillshadePrepareDrawableUBO& drawable [[buffer(2)]],
texture2d<float, access::sample> image [[texture(0)]],
sampler image_sampler [[sampler(0)]]) {
if (drawable.overdrawInspector) {
return half4(1.0);
}
#if defined(OVERDRAW_INSPECTOR)
return half4(1.0);
#endif
float2 epsilon = 1.0 / drawable.dimension;

View File

@@ -13,10 +13,9 @@ struct ShaderSource<BuiltIn::LineShader, gfx::Backend::Type::Metal> {
static constexpr auto name = "LineShader";
static constexpr auto vertexMainFunction = "vertexMain";
static constexpr auto fragmentMainFunction = "fragmentMain";
static constexpr auto hasPermutations = true;
static const std::array<AttributeInfo, 8> attributes;
static const std::array<UniformBlockInfo, 5> uniforms;
static const std::array<UniformBlockInfo, 3> uniforms;
static const std::array<TextureInfo, 0> textures;
static constexpr auto source = R"(
@@ -64,24 +63,22 @@ struct FragmentStage {
FragmentStage vertex vertexMain(thread const VertexStage vertx [[stage_in]],
device const LineUBO& line [[buffer(8)]],
device const LinePropertiesUBO& props [[buffer(9)]],
device const LineInterpolationUBO& interp [[buffer(10)]],
device const LinePermutationUBO& permutation [[buffer(11)]],
device const ExpressionInputsUBO& expr [[buffer(12)]]) {
device const LineInterpolationUBO& interp [[buffer(10)]]) {
#if defined(HAS_UNIFORM_u_gapwidth)
const auto gapwidth = props.gapwidth / 2;
#else
const auto gapwidth = valueFor(permutation.gapwidth, props.gapwidth, vertx.gapwidth, interp.gapwidth_t, expr) / 2;
const auto gapwidth = unpack_mix_float(vertx.gapwidth, interp.gapwidth_t) / 2;
#endif
#if defined(HAS_UNIFORM_u_offset)
const auto offset = props.offset * -1;
#else
const auto offset = valueFor(permutation.offset, props.offset, vertx.offset, interp.offset_t, expr) * -1;
const auto offset = unpack_mix_float(vertx.offset, interp.offset_t) * -1;
#endif
#if defined(HAS_UNIFORM_u_width)
const auto width = props.width;
#else
const auto width = valueFor(permutation.width, props.width, vertx.width, interp.width_t, expr);
const auto width = unpack_mix_float(vertx.width, interp.width_t);
#endif
// the distance over which the line edge fades out.
@@ -127,24 +124,23 @@ FragmentStage vertex vertexMain(thread const VertexStage vertx [[stage_in]],
.gamma_scale = half(extrude_length_without_perspective / extrude_length_with_perspective),
#if !defined(HAS_UNIFORM_u_color)
.color = colorFor(permutation.color, props.color, vertx.color, interp.color_t, expr),
.color = unpack_mix_color(vertx.color, interp.color_t),
#endif
#if !defined(HAS_UNIFORM_u_blur)
.blur = valueFor(permutation.blur, props.blur, vertx.blur, interp.blur_t, expr),
.blur = unpack_mix_float(vertx.blur, interp.blur_t),
#endif
#if !defined(HAS_UNIFORM_u_opacity)
.opacity = valueFor(permutation.opacity, props.opacity, vertx.opacity, interp.opacity_t, expr),
.opacity = unpack_mix_float(vertx.opacity, interp.opacity_t),
#endif
};
}
half4 fragment fragmentMain(FragmentStage in [[stage_in]],
device const LineUBO& line [[buffer(8)]],
device const LinePropertiesUBO& props [[buffer(9)]],
device const LinePermutationUBO& permutation [[buffer(11)]]) {
if (permutation.overdrawInspector) {
return half4(1.0);
}
device const LinePropertiesUBO& props [[buffer(9)]]) {
#if defined(OVERDRAW_INSPECTOR)
return half4(1.0);
#endif
#if defined(HAS_UNIFORM_u_color)
const float4 color = props.color;
@@ -180,10 +176,9 @@ struct ShaderSource<BuiltIn::LinePatternShader, gfx::Backend::Type::Metal> {
static constexpr auto name = "LinePatternShader";
static constexpr auto vertexMainFunction = "vertexMain";
static constexpr auto fragmentMainFunction = "fragmentMain";
static constexpr auto hasPermutations = false;
static const std::array<AttributeInfo, 9> attributes;
static const std::array<UniformBlockInfo, 6> uniforms;
static const std::array<UniformBlockInfo, 4> uniforms;
static const std::array<TextureInfo, 1> textures;
static constexpr auto source = R"(
@@ -217,21 +212,21 @@ struct VertexStage {
struct FragmentStage {
float4 position [[position, invariant]];
float2 width2;
float2 normal;
half gamma_scale;
float linesofar;
half2 normal;
half gamma_scale;
#if !defined(HAS_UNIFORM_u_blur)
float blur;
half blur;
#endif
#if !defined(HAS_UNIFORM_u_opacity)
float opacity;
half opacity;
#endif
#if !defined(HAS_UNIFORM_u_pattern_from)
float4 pattern_from;
half4 pattern_from;
#endif
#if !defined(HAS_UNIFORM_u_pattern_to)
float4 pattern_to;
half4 pattern_to;
#endif
};
@@ -275,24 +270,22 @@ FragmentStage vertex vertexMain(thread const VertexStage vertx [[stage_in]],
device const LinePatternUBO& line [[buffer(9)]],
device const LinePatternPropertiesUBO& props [[buffer(10)]],
device const LinePatternInterpolationUBO& interp [[buffer(11)]],
device const LinePatternTilePropertiesUBO& tileProps [[buffer(12)]],
device const LinePermutationUBO& permutation [[buffer(13)]],
device const ExpressionInputsUBO& expr [[buffer(14)]]) {
device const LinePatternTilePropertiesUBO& tileProps [[buffer(12)]]) {
#if defined(HAS_UNIFORM_u_gapwidth)
const auto gapwidth = props.gapwidth / 2;
#else
const auto gapwidth = valueFor(permutation.gapwidth, props.gapwidth, vertx.gapwidth, interp.gapwidth_t, expr) / 2;
const auto gapwidth = unpack_mix_float(vertx.gapwidth, interp.gapwidth_t) / 2;
#endif
#if defined(HAS_UNIFORM_u_offset)
const auto offset = props.offset * -1;
#else
const auto offset = valueFor(permutation.offset, props.offset, vertx.offset, interp.offset_t, expr) * -1;
const auto offset = unpack_mix_float(vertx.offset, interp.offset_t) * -1;
#endif
#if defined(HAS_UNIFORM_u_width)
const auto width = props.width;
#else
const auto width = valueFor(permutation.width, props.width, vertx.width, interp.width_t, expr);
const auto width = unpack_mix_float(vertx.width, interp.width_t);
#endif
// the distance over which the line edge fades out.
@@ -336,21 +329,21 @@ FragmentStage vertex vertexMain(thread const VertexStage vertx [[stage_in]],
return {
.position = position,
.width2 = float2(outset, inset),
.normal = v_normal,
.normal = half2(v_normal),
.gamma_scale = half(extrude_length_without_perspective / extrude_length_with_perspective),
.linesofar = linesofar,
#if !defined(HAS_UNIFORM_u_blur)
.blur = valueFor(permutation.blur, props.blur, vertx.blur, interp.blur_t, expr),
.blur = half(unpack_mix_float(vertx.blur, interp.blur_t)),
#endif
#if !defined(HAS_UNIFORM_u_opacity)
.opacity = valueFor(permutation.opacity, props.opacity, vertx.opacity, interp.opacity_t, expr),
.opacity = half(unpack_mix_float(vertx.opacity, interp.opacity_t)),
#endif
#if !defined(HAS_UNIFORM_u_pattern_from)
.pattern_from = patternFor(permutation.pattern_from, tileProps.pattern_from, vertx.pattern_from, interp.pattern_from_t, expr),
.pattern_from = half4(vertx.pattern_from),
#endif
#if !defined(HAS_UNIFORM_u_pattern_to)
.pattern_to = patternFor(permutation.pattern_to, tileProps.pattern_to, vertx.pattern_to, interp.pattern_to_t, expr),
.pattern_to = half4(vertx.pattern_to),
#endif
};
}
@@ -359,32 +352,31 @@ half4 fragment fragmentMain(FragmentStage in [[stage_in]],
device const LinePatternUBO& line [[buffer(9)]],
device const LinePatternPropertiesUBO& props [[buffer(10)]],
device const LinePatternTilePropertiesUBO& tileProps [[buffer(12)]],
device const LinePermutationUBO& permutation [[buffer(13)]],
texture2d<float, access::sample> image0 [[texture(0)]],
sampler image0_sampler [[sampler(0)]]) {
if (permutation.overdrawInspector) {
return half4(1.0);
}
#if defined(OVERDRAW_INSPECTOR)
return half4(1.0);
#endif
#if defined(HAS_UNIFORM_u_blur)
const auto blur = props.blur;
const half blur = props.blur;
#else
const auto blur = in.blur;
const half blur = in.blur;
#endif
#if defined(HAS_UNIFORM_u_opacity)
const auto opacity = props.opacity;
const half opacity = props.opacity;
#else
const auto opacity = in.opacity;
const half opacity = in.opacity;
#endif
#if defined(HAS_UNIFORM_u_pattern_from)
const auto pattern_from = tileProps.pattern_from;
const auto pattern_from = float4(tileProps.pattern_from);
#else
const auto pattern_from = in.pattern_from;
const auto pattern_from = float4(in.pattern_from);
#endif
#if defined(HAS_UNIFORM_u_pattern_to)
const auto pattern_to = tileProps.pattern_to;
const auto pattern_to = float4(tileProps.pattern_to);
#else
const auto pattern_to = in.pattern_to;
const auto pattern_to = float4(in.pattern_to);
#endif
const float2 pattern_tl_a = pattern_from.xy;
@@ -437,10 +429,9 @@ struct ShaderSource<BuiltIn::LineSDFShader, gfx::Backend::Type::Metal> {
static constexpr auto name = "LineSDFShader";
static constexpr auto vertexMainFunction = "vertexMain";
static constexpr auto fragmentMainFunction = "fragmentMain";
static constexpr auto hasPermutations = true;
static const std::array<AttributeInfo, 9> attributes;
static const std::array<UniformBlockInfo, 5> uniforms;
static const std::array<UniformBlockInfo, 3> uniforms;
static const std::array<TextureInfo, 1> textures;
static constexpr auto source = R"(
@@ -531,29 +522,27 @@ struct alignas(16) LineSDFInterpolationUBO {
FragmentStage vertex vertexMain(thread const VertexStage vertx [[stage_in]],
device const LineSDFUBO& line [[buffer(9)]],
device const LineSDFPropertiesUBO& props [[buffer(10)]],
device const LineSDFInterpolationUBO& interp [[buffer(11)]],
device const LinePermutationUBO& permutation [[buffer(12)]],
device const ExpressionInputsUBO& expr [[buffer(13)]]) {
device const LineSDFInterpolationUBO& interp [[buffer(11)]]) {
#if defined(HAS_UNIFORM_u_gapwidth)
const auto gapwidth = props.gapwidth / 2;
#else
const auto gapwidth = valueFor(permutation.gapwidth, props.gapwidth, vertx.gapwidth, interp.gapwidth_t, expr) / 2;
const auto gapwidth = unpack_mix_float(vertx.gapwidth, interp.gapwidth_t) / 2;
#endif
#if defined(HAS_UNIFORM_u_offset)
const auto offset = props.offset * -1;
#else
const auto offset = valueFor(permutation.offset, props.offset, vertx.offset, interp.offset_t, expr) * -1;
const auto offset = unpack_mix_float(vertx.offset, interp.offset_t) * -1;
#endif
#if defined(HAS_UNIFORM_u_width)
const auto width = props.width;
#else
const auto width = valueFor(permutation.width, props.width, vertx.width, interp.width_t, expr);
const auto width = unpack_mix_float(vertx.width, interp.width_t);
#endif
#if defined(HAS_UNIFORM_u_floorwidth)
const auto floorwidth = props.floorwidth;
#else
const auto floorwidth = valueFor(permutation.floorwidth, props.floorwidth, vertx.floorwidth, interp.floorwidth_t, expr);
const auto floorwidth = unpack_mix_float(vertx.floorwidth, interp.floorwidth_t);
#endif
// the distance over which the line edge fades out.
@@ -603,13 +592,13 @@ FragmentStage vertex vertexMain(thread const VertexStage vertx [[stage_in]],
.tex_b = float2(linesofar * line.patternscale_b.x / floorwidth, (normal.y * line.patternscale_b.y + line.tex_y_b) * 2.0),
#if !defined(HAS_UNIFORM_u_color)
.color = colorFor(permutation.color, props.color, vertx.color, interp.color_t, expr),
.color = unpack_mix_color(vertx.color, interp.color_t),
#endif
#if !defined(HAS_UNIFORM_u_blur)
.blur = valueFor(permutation.blur, props.blur, vertx.blur, interp.blur_t, expr),
.blur = unpack_mix_float(vertx.blur, interp.blur_t),
#endif
#if !defined(HAS_UNIFORM_u_opacity)
.opacity = valueFor(permutation.opacity, props.opacity, vertx.opacity, interp.opacity_t, expr),
.opacity = unpack_mix_float(vertx.opacity, interp.opacity_t),
#endif
#if !defined(HAS_UNIFORM_u_floorwidth)
.floorwidth = floorwidth,
@@ -620,12 +609,11 @@ FragmentStage vertex vertexMain(thread const VertexStage vertx [[stage_in]],
half4 fragment fragmentMain(FragmentStage in [[stage_in]],
device const LineSDFUBO& line [[buffer(9)]],
device const LineSDFPropertiesUBO& props [[buffer(10)]],
device const LinePermutationUBO& permutation [[buffer(12)]],
texture2d<float, access::sample> image0 [[texture(0)]],
sampler image0_sampler [[sampler(0)]]) {
if (permutation.overdrawInspector) {
return half4(1.0);
}
#if defined(OVERDRAW_INSPECTOR)
return half4(1.0);
#endif
#if defined(HAS_UNIFORM_u_color)
const float4 color = props.color;
@@ -669,7 +657,6 @@ struct ShaderSource<BuiltIn::LineBasicShader, gfx::Backend::Type::Metal> {
static constexpr auto name = "LineBasicShader";
static constexpr auto vertexMainFunction = "vertexMain";
static constexpr auto fragmentMainFunction = "fragmentMain";
static constexpr auto hasPermutations = true;
static const std::array<AttributeInfo, 2> attributes;
static const std::array<UniformBlockInfo, 2> uniforms;

View File

@@ -13,10 +13,9 @@ struct ShaderSource<BuiltIn::LineGradientShader, gfx::Backend::Type::Metal> {
static constexpr auto name = "LineGradientShader";
static constexpr auto vertexMainFunction = "vertexMain";
static constexpr auto fragmentMainFunction = "fragmentMain";
static constexpr auto hasPermutations = false;
static const std::array<AttributeInfo, 7> attributes;
static const std::array<UniformBlockInfo, 5> uniforms;
static const std::array<UniformBlockInfo, 3> uniforms;
static const std::array<TextureInfo, 1> textures;
static constexpr auto source = R"(
@@ -33,26 +32,44 @@ struct VertexStage {
struct FragmentStage {
float4 position [[position, invariant]];
float2 width2;
float2 gapwidth;
float2 normal;
float gamma_scale;
float blur;
float opacity;
half2 normal;
half gamma_scale;
float lineprogress;
#if !defined(HAS_UNIFORM_u_blur)
half blur;
#endif
#if !defined(HAS_UNIFORM_u_opacity)
half opacity;
#endif
};
FragmentStage vertex vertexMain(thread const VertexStage vertx [[stage_in]],
device const LineGradientUBO& line [[buffer(7)]],
device const LineGradientPropertiesUBO& props [[buffer(8)]],
device const LineGradientInterpolationUBO& interp [[buffer(9)]],
device const LinePermutationUBO& permutation [[buffer(10)]],
device const ExpressionInputsUBO& expr [[buffer(11)]]) {
device const LineGradientInterpolationUBO& interp [[buffer(9)]]) {
const auto blur = valueFor(permutation.blur, props.blur, vertx.blur, interp.blur_t, expr);
const auto opacity = valueFor(permutation.opacity, props.opacity, vertx.opacity, interp.opacity_t, expr);
const auto gapwidth = valueFor(permutation.gapwidth, props.gapwidth, vertx.gapwidth, interp.gapwidth_t, expr) / 2;
const auto offset = valueFor(permutation.offset, props.offset, vertx.offset, interp.offset_t, expr) * -1;
const auto width = valueFor(permutation.width, props.width, vertx.width, interp.width_t, expr);
#if !defined(HAS_UNIFORM_u_blur)
const auto blur = unpack_mix_float(vertx.blur, interp.blur_t);
#endif
#if !defined(HAS_UNIFORM_u_opacity)
const auto opacity = unpack_mix_float(vertx.opacity, interp.opacity_t);
#endif
#if defined(HAS_UNIFORM_u_gapwidth)
const auto gapwidth = props.gapwidth;
#else
const auto gapwidth = unpack_mix_float(vertx.gapwidth, interp.gapwidth_t) / 2;
#endif
#if defined(HAS_UNIFORM_u_offset)
const auto offset = props.offset;
#else
const auto offset = unpack_mix_float(vertx.offset, interp.offset_t) * -1;
#endif
#if defined(HAS_UNIFORM_u_width)
const auto width = props.width;
#else
const auto width = unpack_mix_float(vertx.width, interp.width_t);
#endif
// the distance over which the line edge fades out.
// Retina devices need a smaller distance to avoid aliasing.
@@ -94,29 +111,44 @@ FragmentStage vertex vertexMain(thread const VertexStage vertx [[stage_in]],
return {
.position = position,
.width2 = float2(outset, inset),
.gapwidth = gapwidth,
.normal = v_normal,
.gamma_scale = extrude_length_without_perspective / extrude_length_with_perspective,
.blur = blur,
.opacity = opacity,
.normal = half2(v_normal),
.gamma_scale = half(extrude_length_without_perspective / extrude_length_with_perspective),
.lineprogress = v_lineprogress,
#if !defined(HAS_UNIFORM_u_blur)
.blur = half(blur),
#endif
#if !defined(HAS_UNIFORM_u_opacity)
.opacity = half(opacity),
#endif
};
}
half4 fragment fragmentMain(FragmentStage in [[stage_in]],
device const LineGradientUBO& line [[buffer(7)]],
device const LinePermutationUBO& permutation [[buffer(10)]],
device const LineGradientPropertiesUBO& props [[buffer(8)]],
texture2d<float, access::sample> gradientTexture [[texture(0)]]) {
if (permutation.overdrawInspector) {
return half4(1.0);
}
#if defined(OVERDRAW_INSPECTOR)
return half4(1.0);
#endif
#if defined(HAS_UNIFORM_u_blur)
const float blur = props.blur;
#else
const float blur = float(in.blur);
#endif
#if defined(HAS_UNIFORM_u_opacity)
const float opacity = props.opacity;
#else
const float opacity = float(in.opacity);
#endif
// Calculate the distance of the pixel from the line in pixels.
const float dist = length(in.normal) * in.width2.x;
// Calculate the antialiasing fade factor. This is either when fading in the
// line in case of an offset line (v_width2.y) or when fading out (v_width2.x)
const float blur2 = (in.blur + 1.0 / line.device_pixel_ratio) * in.gamma_scale;
const float blur2 = (blur + 1.0 / line.device_pixel_ratio) * in.gamma_scale;
const float alpha = clamp(min(dist - (in.width2.y - blur2), in.width2.x - dist) / blur2, 0.0, 1.0);
// For gradient lines, v_lineprogress is the ratio along the entire line,
@@ -124,7 +156,7 @@ half4 fragment fragmentMain(FragmentStage in [[stage_in]],
constexpr sampler sampler2d(coord::normalized, filter::linear);
const float4 color = gradientTexture.sample(sampler2d, float2(in.lineprogress, 0.5));
return half4(color * (alpha * in.opacity));
return half4(color * (alpha * opacity));
}
)";
};

View File

@@ -13,7 +13,6 @@ struct ShaderSource<BuiltIn::RasterShader, gfx::Backend::Type::Metal> {
static constexpr auto name = "RasterShader";
static constexpr auto vertexMainFunction = "vertexMain";
static constexpr auto fragmentMainFunction = "fragmentMain";
static constexpr auto hasPermutations = false;
static const std::array<AttributeInfo, 2> attributes;
static const std::array<UniformBlockInfo, 1> uniforms;
@@ -75,10 +74,9 @@ half4 fragment fragmentMain(FragmentStage in [[stage_in]],
texture2d<float, access::sample> image1 [[texture(1)]],
sampler image0_sampler [[sampler(0)]],
sampler image1_sampler [[sampler(1)]]) {
if (drawable.overdrawInspector) {
return half4(1.0);
}
#if defined(OVERDRAW_INSPECTOR)
return half4(1.0);
#endif
// read and cross-fade colors from the main and parent tiles
float4 color0 = image0.sample(image0_sampler, in.pos0);

View File

@@ -20,26 +20,35 @@ public:
using StringIDSet = mbgl::unordered_set<StringIdentity>;
protected:
ShaderGroupBase(const ProgramParameters& parameters_)
: programParameters(parameters_) {}
using DefinesMap = mbgl::unordered_map<std::string, std::string>;
void addAdditionalDefines(const StringIDSet& propertiesAsUniforms, DefinesMap& additionalDefines) {
const std::string uniformPrefix = "HAS_UNIFORM_u_";
additionalDefines.reserve(propertiesAsUniforms.size() + 1);
additionalDefines.insert(std::make_pair("HAS_PERMUTATIONS", std::string()));
if (programParameters.getOverdrawInspectorEnabled()) {
additionalDefines.insert(std::make_pair(overdrawName, std::string()));
}
for (const auto nameID : propertiesAsUniforms) {
// We expect the names to be prefixed by "a_", but we need just the base here.
const auto name = stringIndexer().get(nameID);
const auto* base = (name[0] == 'a' && name[1] == '_') ? &name[2] : name.data();
additionalDefines.insert(std::make_pair(uniformPrefix + base, std::string()));
additionalDefines.insert(std::make_pair(std::string(uniformPrefix) + base, std::string()));
}
}
ProgramParameters programParameters;
private:
static constexpr auto uniformPrefix = "HAS_UNIFORM_u_";
static constexpr auto overdrawName = "OVERDRAW_INSPECTOR";
};
template <shaders::BuiltIn ShaderID>
class ShaderGroup final : public ShaderGroupBase {
public:
ShaderGroup(const ProgramParameters& programParameters_)
: ShaderGroupBase(),
programParameters(programParameters_) {}
: ShaderGroupBase(programParameters_) {}
~ShaderGroup() noexcept override = default;
gfx::ShaderPtr getOrCreateShader(gfx::Context& gfxContext,
@@ -50,17 +59,13 @@ public:
constexpr auto& source = ShaderSource::source;
constexpr auto& vertMain = ShaderSource::vertexMainFunction;
constexpr auto& fragMain = ShaderSource::fragmentMainFunction;
constexpr auto permutations = shaders::ShaderSource<ShaderID, gfx::Backend::Type::Metal>::hasPermutations;
const PropertyHashType key = permutations ? propertyHash(propertiesAsUniforms) : 0;
const std::string shaderName = permutations ? getShaderName(name, key) : name;
const std::string shaderName = getShaderName(name, propertyHash(propertiesAsUniforms));
auto shader = get<mtl::ShaderProgram>(shaderName);
if (!shader) {
DefinesMap additionalDefines;
if (permutations) {
addAdditionalDefines(propertiesAsUniforms, additionalDefines);
}
addAdditionalDefines(propertiesAsUniforms, additionalDefines);
auto& context = static_cast<Context&>(gfxContext);
const auto shaderSource = std::string(shaders::prelude) + source;
@@ -72,11 +77,9 @@ public:
throw std::runtime_error("Failed to register " + shaderName + " with shader group!");
}
shader->setBindMissingAttributes(!permutations);
using ShaderClass = shaders::ShaderSource<ShaderID, gfx::Backend::Type::Metal>;
for (const auto& attrib : ShaderClass::attributes) {
if (!permutations || !propertiesAsUniforms.count(attrib.nameID)) {
if (!propertiesAsUniforms.count(attrib.nameID)) {
shader->initAttribute(attrib);
}
}
@@ -89,9 +92,6 @@ public:
}
return shader;
}
private:
ProgramParameters programParameters;
};
} // namespace mtl

View File

@@ -69,9 +69,6 @@ public:
void initUniformBlock(const shaders::UniformBlockInfo&);
void initTexture(const shaders::TextureInfo&);
bool getBindMissingAttributes() const { return bindMissingAttributes; }
void setBindMissingAttributes(bool value) { bindMissingAttributes = value; }
protected:
std::string shaderName;
RendererBackend& backend;
@@ -80,7 +77,6 @@ protected:
UniformBlockArray uniformBlocks;
VertexAttributeArray vertexAttributes;
std::unordered_map<StringIdentity, std::size_t> textureBindings;
bool bindMissingAttributes = true;
};
} // namespace mtl

View File

@@ -13,10 +13,9 @@ struct ShaderSource<BuiltIn::SymbolIconShader, gfx::Backend::Type::Metal> {
static constexpr auto name = "SymbolIconShader";
static constexpr auto vertexMainFunction = "vertexMain";
static constexpr auto fragmentMainFunction = "fragmentMain";
static constexpr auto hasPermutations = true;
static const std::array<AttributeInfo, 6> attributes;
static const std::array<UniformBlockInfo, 7> uniforms;
static const std::array<UniformBlockInfo, 5> uniforms;
static const std::array<TextureInfo, 1> textures;
static constexpr auto source = R"(
@@ -34,10 +33,13 @@ struct VertexStage {
struct FragmentStage {
float4 position [[position, invariant]];
float2 tex;
half fade_opacity;
half2 tex;
#if !defined(HAS_UNIFORM_u_opacity)
#if defined(HAS_UNIFORM_u_opacity)
// We only need to pass `fade_opacity` separately if opacity is a
// uniform, otherwise it's multiplied into fragment opacity, below.
half fade_opacity;
#else
half opacity;
#endif
};
@@ -47,9 +49,7 @@ FragmentStage vertex vertexMain(thread const VertexStage vertx [[stage_in]],
device const SymbolDynamicUBO& dynamic [[buffer(9)]],
device const SymbolDrawablePaintUBO& paint [[buffer(10)]],
device const SymbolDrawableTilePropsUBO& props [[buffer(11)]],
device const SymbolDrawableInterpolateUBO& interp [[buffer(12)]],
device const SymbolPermutationUBO& permutation [[buffer(13)]],
device const ExpressionInputsUBO& expr [[buffer(14)]]) {
device const SymbolDrawableInterpolateUBO& interp [[buffer(12)]]) {
const float2 a_pos = vertx.pos_offset.xy;
const float2 a_offset = vertx.pos_offset.zw;
@@ -106,15 +106,17 @@ FragmentStage vertex vertexMain(thread const VertexStage vertx [[stage_in]],
const float2 posOffset = a_offset * max(a_minFontScale, fontScale) / 32.0 + a_pxoffset / 16.0;
const float4 position = drawable.coord_matrix * float4(pos0 + rotation_matrix * posOffset, 0.0, 1.0);
const float2 fade_opacity = unpack_opacity(vertx.fade_opacity);
const float fade_change = fade_opacity[1] > 0.5 ? dynamic.fade_change : -dynamic.fade_change;
const float2 raw_fade_opacity = unpack_opacity(vertx.fade_opacity);
const float fade_change = raw_fade_opacity[1] > 0.5 ? dynamic.fade_change : -dynamic.fade_change;
const float fade_opacity = max(0.0, min(1.0, raw_fade_opacity[0] + fade_change));
return {
.position = position,
.tex = a_tex / drawable.texsize,
.fade_opacity = half(max(0.0, min(1.0, fade_opacity[0] + fade_change))),
#if !defined(HAS_UNIFORM_u_opacity)
.opacity = half(valueFor(permutation.opacity, paint.opacity, vertx.opacity, interp.opacity_t, expr)),
.tex = half2(a_tex / drawable.texsize),
#if defined(HAS_UNIFORM_u_opacity)
.fade_opacity = half(fade_opacity),
#else
.opacity = half(unpack_mix_float(vertx.opacity, interp.opacity_t) * fade_opacity),
#endif
};
}
@@ -122,20 +124,19 @@ FragmentStage vertex vertexMain(thread const VertexStage vertx [[stage_in]],
half4 fragment fragmentMain(FragmentStage in [[stage_in]],
device const SymbolDrawableUBO& drawable [[buffer(8)]],
device const SymbolDrawablePaintUBO& paint [[buffer(10)]],
device const SymbolPermutationUBO& permutation [[buffer(13)]],
texture2d<float, access::sample> image [[texture(0)]],
sampler image_sampler [[sampler(0)]]) {
if (permutation.overdrawInspector) {
return half4(1.0);
}
#if defined(HAS_UNIFORM_u_opacity)
const half opacity = half(paint.opacity);
#else
const half opacity = in.opacity;
#if defined(OVERDRAW_INSPECTOR)
return half4(1.0);
#endif
return half4(image.sample(image_sampler, in.tex) * (opacity * in.fade_opacity));
#if defined(HAS_UNIFORM_u_opacity)
const float opacity = paint.opacity * in.fade_opacity;
#else
const float opacity = in.opacity; // fade_opacity is baked in for this case
#endif
return half4(image.sample(image_sampler, float2(in.tex)) * opacity);
}
)";
};

View File

@@ -13,10 +13,9 @@ struct ShaderSource<BuiltIn::SymbolSDFIconShader, gfx::Backend::Type::Metal> {
static constexpr auto name = "SymbolSDFIconShader";
static constexpr auto vertexMainFunction = "vertexMain";
static constexpr auto fragmentMainFunction = "fragmentMain";
static constexpr auto hasPermutations = true;
static const std::array<AttributeInfo, 10> attributes;
static const std::array<UniformBlockInfo, 7> uniforms;
static const std::array<UniformBlockInfo, 5> uniforms;
static const std::array<TextureInfo, 1> textures;
static constexpr auto source = R"(
@@ -46,8 +45,6 @@ struct VertexStage {
struct FragmentStage {
float4 position [[position, invariant]];
float2 data0;
float3 data1;
#if !defined(HAS_UNIFORM_u_fill_color)
half4 fill_color;
@@ -55,6 +52,12 @@ struct FragmentStage {
#if !defined(HAS_UNIFORM_u_halo_color)
half4 halo_color;
#endif
half2 tex;
half gamma_scale;
half fontScale;
half fade_opacity;
#if !defined(HAS_UNIFORM_u_opacity)
half opacity;
#endif
@@ -71,9 +74,7 @@ FragmentStage vertex vertexMain(thread const VertexStage vertx [[stage_in]],
device const SymbolDynamicUBO& dynamic [[buffer(11)]],
device const SymbolDrawablePaintUBO& paint [[buffer(12)]],
device const SymbolDrawableTilePropsUBO& props [[buffer(13)]],
device const SymbolDrawableInterpolateUBO& interp [[buffer(14)]],
device const SymbolPermutationUBO& permutation [[buffer(15)]],
device const ExpressionInputsUBO& expr [[buffer(16)]]) {
device const SymbolDrawableInterpolateUBO& interp [[buffer(14)]]) {
const float2 a_pos = vertx.pos_offset.xy;
const float2 a_offset = vertx.pos_offset.zw;
@@ -130,37 +131,35 @@ FragmentStage vertex vertexMain(thread const VertexStage vertx [[stage_in]],
const float angle_sin = sin(segment_angle + symbol_rotation);
const float angle_cos = cos(segment_angle + symbol_rotation);
const float2x2 rotation_matrix = float2x2(angle_cos, -1.0 * angle_sin, angle_sin, angle_cos);
const auto rotation_matrix = float2x2(angle_cos, -1.0 * angle_sin, angle_sin, angle_cos);
const float4 projected_pos = drawable.label_plane_matrix * float4(vertx.projected_pos.xy, 0.0, 1.0);
const float2 pos_rot = a_offset / 32.0 * fontScale + a_pxoffset;
const float2 pos0 = projected_pos.xy / projected_pos.w + rotation_matrix * pos_rot;
const float4 position = drawable.coord_matrix * float4(pos0, 0.0, 1.0);
const float gamma_scale = position.w;
const float2 fade_opacity = unpack_opacity(vertx.fade_opacity);
const float fade_change = (fade_opacity[1] > 0.5) ? dynamic.fade_change : -dynamic.fade_change;
const float interpolated_fade_opacity = max(0.0, min(1.0, fade_opacity[0] + fade_change));
return {
.position = position,
.position = position,
#if !defined(HAS_UNIFORM_u_fill_color)
.fill_color = half4(colorFor(permutation.fill_color, paint.fill_color, vertx.fill_color, interp.fill_color_t, expr)),
.fill_color = half4(unpack_mix_color(vertx.fill_color, interp.fill_color_t)),
#endif
#if !defined(HAS_UNIFORM_u_halo_color)
.halo_color = half4(colorFor(permutation.halo_color, paint.halo_color, vertx.halo_color, interp.halo_color_t, expr)),
.halo_color = half4(unpack_mix_color(vertx.halo_color, interp.halo_color_t)),
#endif
#if !defined(HAS_UNIFORM_u_halo_width)
.halo_width = half(valueFor(permutation.halo_width, paint.halo_width, vertx.halo_width, interp.halo_width_t, expr)),
.halo_width = half(unpack_mix_float(vertx.halo_width, interp.halo_width_t)),
#endif
#if !defined(HAS_UNIFORM_u_halo_blur)
.halo_blur = half(valueFor(permutation.halo_blur, paint.halo_blur, vertx.halo_blur, interp.halo_blur_t, expr)),
.halo_blur = half(unpack_mix_float(vertx.halo_blur, interp.halo_blur_t)),
#endif
#if !defined(HAS_UNIFORM_u_opacity)
.opacity = half(valueFor(permutation.opacity, paint.opacity, vertx.opacity, interp.opacity_t, expr)),
.opacity = half(unpack_mix_float(vertx.opacity, interp.opacity_t)),
#endif
.data0 = a_tex / drawable.texsize,
.data1 = float3(gamma_scale, size, interpolated_fade_opacity),
.tex = half2(a_tex / drawable.texsize),
.gamma_scale = half(position.w),
.fontScale = half(fontScale),
.fade_opacity = half(max(0.0, min(1.0, fade_opacity[0] + fade_change))),
};
}
@@ -169,12 +168,11 @@ half4 fragment fragmentMain(FragmentStage in [[stage_in]],
device const SymbolDynamicUBO& dynamic [[buffer(11)]],
device const SymbolDrawablePaintUBO& paint [[buffer(12)]],
device const SymbolDrawableTilePropsUBO& props [[buffer(13)]],
device const SymbolPermutationUBO& permutation [[buffer(15)]],
texture2d<float, access::sample> image [[texture(0)]],
sampler image_sampler [[sampler(0)]]) {
if (permutation.overdrawInspector) {
return half4(1.0);
}
#if defined(OVERDRAW_INSPECTOR)
return half4(1.0);
#endif
#if defined(HAS_UNIFORM_u_fill_color)
const half4 fill_color = half4(paint.fill_color);
@@ -187,36 +185,31 @@ half4 fragment fragmentMain(FragmentStage in [[stage_in]],
const half4 halo_color = in.halo_color;
#endif
#if defined(HAS_UNIFORM_u_opacity)
const half opacity = half(paint.opacity);
const float opacity = paint.opacity;
#else
const half opacity = in.opacity;
const float opacity = in.opacity;
#endif
#if defined(HAS_UNIFORM_u_halo_width)
const half halo_width = half(paint.halo_width);
const float halo_width = paint.halo_width;
#else
const half halo_width = in.halo_width;
const float halo_width = in.halo_width;
#endif
#if defined(HAS_UNIFORM_u_halo_blur)
const half halo_blur = half(paint.halo_blur);
const float halo_blur = paint.halo_blur;
#else
const half halo_blur = in.halo_blur;
const float halo_blur = in.halo_blur;
#endif
const float EDGE_GAMMA = 0.105 / dynamic.device_pixel_ratio;
const float2 tex = in.data0.xy;
const float gamma_scale = in.data1.x;
const float size = in.data1.y;
const float fade_opacity = in.data1[2];
const float fontScale = props.is_text ? size / 24.0 : size;
const float fontGamma = fontScale * drawable.gamma_scale;
const float fontGamma = in.fontScale * drawable.gamma_scale;
const half4 color = props.is_halo ? halo_color : fill_color;
const float gamma = ((props.is_halo ? (halo_blur * 1.19 / SDF_PX) : 0) + EDGE_GAMMA) / fontGamma;
const float buff = props.is_halo ? (6.0 - halo_width / fontScale) / SDF_PX : (256.0 - 64.0) / 256.0;
const float dist = image.sample(image_sampler, tex).a;
const float gamma_scaled = gamma * gamma_scale;
const float buff = props.is_halo ? (6.0 - halo_width / in.fontScale) / SDF_PX : (256.0 - 64.0) / 256.0;
const float dist = image.sample(image_sampler, float2(in.tex)).a;
const float gamma_scaled = gamma * in.gamma_scale;
const float alpha = smoothstep(buff - gamma_scaled, buff + gamma_scaled, dist);
return half4(color * (alpha * opacity * fade_opacity));
return half4(color * (alpha * opacity * in.fade_opacity));
}
)";
};

View File

@@ -13,10 +13,9 @@ struct ShaderSource<BuiltIn::SymbolTextAndIconShader, gfx::Backend::Type::Metal>
static constexpr auto name = "SymbolTextAndIconShader";
static constexpr auto vertexMainFunction = "vertexMain";
static constexpr auto fragmentMainFunction = "fragmentMain";
static constexpr auto hasPermutations = true;
static const std::array<AttributeInfo, 9> attributes;
static const std::array<UniformBlockInfo, 7> uniforms;
static const std::array<UniformBlockInfo, 5> uniforms;
static const std::array<TextureInfo, 2> textures;
static constexpr auto source = R"(
@@ -48,8 +47,6 @@ struct VertexStage {
struct FragmentStage {
float4 position [[position, invariant]];
float4 data0;
float4 data1;
#if !defined(HAS_UNIFORM_u_fill_color)
half4 fill_color;
@@ -57,6 +54,9 @@ struct FragmentStage {
#if !defined(HAS_UNIFORM_u_halo_color)
half4 halo_color;
#endif
half2 tex;
#if !defined(HAS_UNIFORM_u_opacity)
half opacity;
#endif
@@ -66,6 +66,11 @@ struct FragmentStage {
#if !defined(HAS_UNIFORM_u_halo_blur)
half halo_blur;
#endif
half gamma_scale;
half fontScale;
half fade_opacity;
bool is_icon;
};
FragmentStage vertex vertexMain(thread const VertexStage vertx [[stage_in]],
@@ -73,9 +78,7 @@ FragmentStage vertex vertexMain(thread const VertexStage vertx [[stage_in]],
device const SymbolDynamicUBO& dynamic [[buffer(10)]],
device const SymbolDrawablePaintUBO& paint [[buffer(11)]],
device const SymbolDrawableTilePropsUBO& props [[buffer(12)]],
device const SymbolDrawableInterpolateUBO& interp [[buffer(13)]],
device const SymbolPermutationUBO& permutation [[buffer(14)]],
device const ExpressionInputsUBO& expr [[buffer(15)]]) {
device const SymbolDrawableInterpolateUBO& interp [[buffer(13)]]) {
const float2 a_pos = vertx.pos_offset.xy;
const float2 a_offset = vertx.pos_offset.zw;
@@ -142,27 +145,30 @@ FragmentStage vertex vertexMain(thread const VertexStage vertx [[stage_in]],
const float2 fade_opacity = unpack_opacity(vertx.fade_opacity);
const float fade_change = (fade_opacity[1] > 0.5) ? dynamic.fade_change : -dynamic.fade_change;
const float interpolated_fade_opacity = max(0.0, min(1.0, fade_opacity[0] + fade_change));
const bool is_icon = (is_sdf == ICON);
return {
.position = position,
.data0 = float4(a_tex / drawable.texsize, a_tex / drawable.texsize_icon),
.data1 = float4(gamma_scale, size, interpolated_fade_opacity, is_sdf),
.position = position,
.tex = half2(a_tex / (is_icon ? drawable.texsize_icon : drawable.texsize)),
.gamma_scale = half(gamma_scale),
.fontScale = half(fontScale),
.fade_opacity = half(max(0.0, min(1.0, fade_opacity[0] + fade_change))),
.is_icon = is_icon,
#if !defined(HAS_UNIFORM_u_fill_color)
.fill_color = half(colorFor(permutation.fill_color, paint.fill_color, vertx.fill_color, interp.fill_color_t, expr));
.fill_color = half(unpack_mix_color(vertx.fill_color, interp.fill_color_t));
#endif
#if !defined(HAS_UNIFORM_u_halo_color)
.halo_color = half(colorFor(permutation.halo_color, paint.halo_color, vertx.halo_color, interp.halo_color_t, expr));
.halo_color = half(unpack_mix_color(vertx.halo_color, interp.halo_color_t));
#endif
#if !defined(HAS_UNIFORM_u_opacity)
.opacity = half(valueFor(permutation.opacity, paint.opacity, vertx.opacity, interp.opacity_t, expr));
.opacity = half(unpack_mix_float(vertx.opacity, interp.opacity_t));
#endif
#if !defined(HAS_UNIFORM_u_halo_width)
.halo_width = half(valueFor(permutation.halo_width, paint.halo_width, vertx.halo_width, interp.halo_width_t, expr));
.halo_width = half(unpack_mix_float(vertx.halo_width, interp.halo_width_t));
#endif
#if !defined(HAS_UNIFORM_u_halo_blur)
.halo_blur = half(valueFor(permutation.halo_blur, paint.halo_blur, vertx.halo_blur, interp.halo_blur_t, expr));
.halo_blur = half(unpack_mix_float(vertx.halo_blur, interp.halo_blur_t));
#endif
};
}
@@ -172,14 +178,13 @@ half4 fragment fragmentMain(FragmentStage in [[stage_in]],
device const SymbolDynamicUBO& dynamic [[buffer(10)]],
device const SymbolDrawablePaintUBO& paint [[buffer(11)]],
device const SymbolDrawableTilePropsUBO& props [[buffer(12)]],
device const SymbolPermutationUBO& permutation [[buffer(14)]],
texture2d<float, access::sample> glyph_image [[texture(0)]],
texture2d<float, access::sample> icon_image [[texture(1)]],
sampler glyph_sampler [[sampler(0)]],
sampler icon_sampler [[sampler(1)]]) {
if (permutation.overdrawInspector) {
return half4(1.0);
}
#if defined(OVERDRAW_INSPECTOR)
return half4(1.0);
#endif
#if defined(HAS_UNIFORM_u_fill_color)
const half4 fill_color = half4(paint.fill_color);
@@ -207,28 +212,21 @@ half4 fragment fragmentMain(FragmentStage in [[stage_in]],
const half halo_blur = in.halo_blur;
#endif
const float fade_opacity = in.data1[2];
if (in.data1.w == ICON) {
const float2 tex_icon = in.data0.zw;
const float alpha = opacity * fade_opacity;
return half4(icon_image.sample(icon_sampler, tex_icon) * alpha);
if (in.is_icon) {
const float alpha = opacity * in.fade_opacity;
return half4(icon_image.sample(icon_sampler, float2(in.tex)) * alpha);
}
const float2 tex = in.data0.xy;
const float EDGE_GAMMA = 0.105 / dynamic.device_pixel_ratio;
const float gamma_scale = in.data1.x;
const float size = in.data1.y;
const float fontScale = size / 24.0;
const half4 color = props.is_halo ? halo_color : fill_color;
const float fontGamma = fontScale * drawable.gamma_scale;
const float fontGamma = in.fontScale * drawable.gamma_scale;
const float gamma = ((props.is_halo ? (halo_blur * 1.19 / SDF_PX) : 0) + EDGE_GAMMA) / fontGamma;
const float buff = props.is_halo ? (6.0 - halo_width / fontScale) / SDF_PX : (256.0 - 64.0) / 256.0;
const float dist = glyph_image.sample(glyph_sampler, tex).a;
const float gamma_scaled = gamma * gamma_scale;
const float buff = props.is_halo ? (6.0 - halo_width / in.fontScale) / SDF_PX : (256.0 - 64.0) / 256.0;
const float dist = glyph_image.sample(glyph_sampler, float2(in.tex)).a;
const float gamma_scaled = gamma * in.gamma_scale;
const float alpha = smoothstep(buff - gamma_scaled, buff + gamma_scaled, dist);
return half4(color * (alpha * opacity * fade_opacity));
return half4(color * (alpha * opacity * in.fade_opacity));
}
)";
};

View File

@@ -17,9 +17,7 @@ struct alignas(16) RasterDrawableUBO {
float brightness_high;
float saturation_factor;
float contrast_factor;
bool overdrawInspector;
uint8_t pad1, pad2, pad3;
float pad4;
float pad1, pad2;
};
static_assert(sizeof(RasterDrawableUBO) == 128);
static_assert(sizeof(RasterDrawableUBO) % 16 == 0);

View File

@@ -69,17 +69,5 @@ struct alignas(16) SymbolDrawablePaintUBO {
};
static_assert(sizeof(SymbolDrawablePaintUBO) == 3 * 16);
struct alignas(16) SymbolPermutationUBO {
/* 0 */ Attribute fill_color;
/* 8 */ Attribute halo_color;
/* 16 */ Attribute opacity;
/* 24 */ Attribute halo_width;
/* 40 */ Attribute halo_blur;
/* 48 */ int32_t /*bool*/ overdrawInspector;
/* 52 */ float pad1, pad2, pad3;
/* 64 */
};
static_assert(sizeof(SymbolPermutationUBO) == 4 * 16);
} // namespace shaders
} // namespace mbgl

View File

@@ -11,10 +11,6 @@ layout (std140) uniform HillshadePrepareDrawableUBO {
highp vec2 u_dimension;
highp float u_zoom;
highp float u_maxzoom;
lowp float pad0_;
lowp float pad1_;
lowp float pad2_;
lowp float pad3_;
};
float getElevation(vec2 coord, float bias) {

View File

@@ -7,10 +7,6 @@ layout (std140) uniform HillshadePrepareDrawableUBO {
highp vec2 u_dimension;
highp float u_zoom;
highp float u_maxzoom;
lowp float pad0_;
lowp float pad1_;
lowp float pad2_;
lowp float pad3_;
};
out vec2 v_pos;

View File

@@ -346,12 +346,8 @@ void Drawable::bindAttributes(RenderPass& renderPass) const noexcept {
renderPass.bindVertex(buffer->get(), /*offset=*/0, attributeIndex);
} else {
const auto* shaderMTL = static_cast<const ShaderProgram*>(shader.get());
if (impl->noBindingBuffer && shaderMTL && shaderMTL->getBindMissingAttributes()) {
renderPass.bindVertex(impl->noBindingBuffer->get(), /*offset=*/0, attributeIndex);
} else {
auto& context = renderPass.getCommandEncoder().getContext();
renderPass.bindVertex(context.getEmptyBuffer(), /*offset=*/0, attributeIndex);
}
auto& context = renderPass.getCommandEncoder().getContext();
renderPass.bindVertex(context.getEmptyBuffer(), /*offset=*/0, attributeIndex);
}
attributeIndex += 1;
}

View File

@@ -8,7 +8,8 @@
namespace mbgl {
ProgramParameters::ProgramParameters(const float pixelRatio, const bool overdraw)
: defines(2) {
: defines(2),
overdrawInspector(overdraw) {
defines["DEVICE_PIXEL_RATIO"] = util::toString(pixelRatio, true);
if (overdraw) {
defines["OVERDRAW_INSPECTOR"] = std::string();

View File

@@ -61,6 +61,8 @@ public:
/// @return Shader source string
const std::string& fragmentSource(gfx::Backend::Type backend) const;
bool getOverdrawInspectorEnabled() const { return overdrawInspector; }
private:
std::unordered_map<std::string, std::string> defines;
@@ -69,6 +71,8 @@ private:
std::array<ProgramSource, static_cast<size_t>(gfx::Backend::Type::TYPE_MAX)> defaultSources;
std::array<ProgramSource, static_cast<size_t>(gfx::Backend::Type::TYPE_MAX)> userSources;
bool overdrawInspector;
};
} // namespace mbgl

View File

@@ -52,49 +52,4 @@ void LayerTweaker::updateProperties(Immutable<style::LayerProperties> newProps)
propertiesUpdated = true;
}
#if MLN_RENDER_BACKEND_METAL
shaders::ExpressionInputsUBO LayerTweaker::buildExpressionUBO(double zoom, uint64_t frameCount) {
const auto time = util::MonotonicTimer::now();
const auto time_ns = std::chrono::duration_cast<std::chrono::nanoseconds>(time).count();
return {/* .time_lo = */ static_cast<uint32_t>(time_ns),
/* .time_hi = */ static_cast<uint32_t>(time_ns >> 32),
/* .frame_lo = */ static_cast<uint32_t>(frameCount),
/* .frame_hi = */ static_cast<uint32_t>(frameCount >> 32),
/* .zoom = */ static_cast<float>(zoom),
/* .zoom_frac = */ static_cast<float>(zoom - static_cast<float>(zoom)),
/* .pad = */ 0,
0};
}
#endif // MLN_RENDER_BACKEND_METAL
void LayerTweaker::setPropertiesAsUniforms([[maybe_unused]] const mbgl::unordered_set<StringIdentity>& props) {
#if MLN_RENDER_BACKEND_METAL
if (props != propertiesAsUniforms) {
propertiesAsUniforms = props;
permutationUpdated = true;
}
#endif
}
#if !MLN_RENDER_BACKEND_METAL
namespace {
const mbgl::unordered_set<StringIdentity> emptyIDSet;
}
#endif
const mbgl::unordered_set<StringIdentity>& LayerTweaker::getPropertiesAsUniforms() const {
#if MLN_RENDER_BACKEND_METAL
return propertiesAsUniforms;
#else
return emptyIDSet;
#endif
}
void LayerTweaker::enableOverdrawInspector(bool value) {
if (overdrawInspector != value) {
overdrawInspector = value;
permutationUpdated = true;
}
}
} // namespace mbgl

View File

@@ -109,10 +109,7 @@ void BackgroundLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintPara
/* .scale_b = */ crossfade.toScale,
/* .mix = */ crossfade.t,
/* .opacity = */ evaluated.get<BackgroundOpacity>(),
/* .overdrawInspector = */ overdrawInspector,
/* .pad1/2/3 = */ 0,
0,
0,
/* .pad1 = */ 0,
};
uniforms.createOrUpdate(idBackgroundLayerUBOName, &layerUBO, context);
} else {
@@ -120,11 +117,8 @@ void BackgroundLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintPara
if (!backgroundLayerBuffer) {
const BackgroundLayerUBO layerUBO = {/* .color = */ evaluated.get<BackgroundColor>(),
/* .opacity = */ evaluated.get<BackgroundOpacity>(),
/* .overdrawInspector = */ overdrawInspector,
/* .pad1/2/3 = */ 0,
0,
0,
/* .pad4/5 = */ 0,
0};
backgroundLayerBuffer = context.createUniformBuffer(&layerUBO, sizeof(layerUBO));
}

View File

@@ -26,9 +26,6 @@ static const StringIdentity idCircleDrawableUBOName = stringIndexer().get("Circl
static const StringIdentity idCirclePaintParamsUBOName = stringIndexer().get("CirclePaintParamsUBO");
static const StringIdentity idCircleEvaluatedPropsUBOName = stringIndexer().get("CircleEvaluatedPropsUBO");
static const StringIdentity idExpressionInputsUBOName = stringIndexer().get("ExpressionInputsUBO");
static const StringIdentity idCirclePermutationUBOName = stringIndexer().get("CirclePermutationUBO");
void CircleLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintParameters& parameters) {
auto& context = parameters.context;
const auto& evaluated = static_cast<const CircleLayerProperties&>(*evaluatedProperties).evaluated;
@@ -56,37 +53,6 @@ void CircleLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintParamete
}
const auto zoom = parameters.state.getZoom();
#if MLN_RENDER_BACKEND_METAL
if (permutationUpdated) {
const CirclePermutationUBO permutationUBO = {
/* .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,
0,
0};
if (permutationUniformBuffer) {
permutationUniformBuffer->update(&permutationUBO, sizeof(permutationUBO));
} else {
permutationUniformBuffer = context.createUniformBuffer(&permutationUBO, sizeof(permutationUBO));
}
permutationUpdated = false;
}
if (!expressionUniformBuffer) {
const auto expressionUBO = buildExpressionUBO(zoom, parameters.frameCount);
expressionUniformBuffer = context.createUniformBuffer(&expressionUBO, sizeof(expressionUBO));
}
#endif
const bool pitchWithMap = evaluated.get<CirclePitchAlignment>() == AlignmentType::Map;
const bool scaleWithMap = evaluated.get<CirclePitchScale>() == CirclePitchScaleType::Map;
@@ -133,10 +99,6 @@ void CircleLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintParamete
/* .padding = */ 0};
uniforms.createOrUpdate(idCircleDrawableUBOName, &drawableUBO, context);
#if MLN_RENDER_BACKEND_METAL
uniforms.addOrReplace(idExpressionInputsUBOName, expressionUniformBuffer);
uniforms.addOrReplace(idCirclePermutationUBOName, permutationUniformBuffer);
#endif // MLN_RENDER_BACKEND_METAL
});
}

View File

@@ -21,11 +21,6 @@ public:
protected:
gfx::UniformBufferPtr paintParamsUniformBuffer;
gfx::UniformBufferPtr evaluatedPropsUniformBuffer;
#if MLN_RENDER_BACKEND_METAL
gfx::UniformBufferPtr permutationUniformBuffer;
gfx::UniformBufferPtr expressionUniformBuffer;
#endif // MLN_RENDER_BACKEND_METAL
};
} // namespace mbgl

View File

@@ -29,8 +29,6 @@ using namespace style;
namespace {
const StringIdentity idFillExtrusionDrawableUBOName = stringIndexer().get("FillExtrusionDrawableUBO");
const StringIdentity idFillExtrusionDrawablePropsUBOName = stringIndexer().get("FillExtrusionDrawablePropsUBO");
const StringIdentity idExpressionInputsUBOName = stringIndexer().get("ExpressionInputsUBO");
const StringIdentity idFillExtrusionPermutationUBOName = stringIndexer().get("FillExtrusionPermutationUBO");
const StringIdentity idTexImageName = stringIndexer().get("u_image");
} // namespace
@@ -78,36 +76,6 @@ void FillExtrusionLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintP
propsBuffer->update(&paramsUBO, sizeof(paramsUBO));
}
#if MLN_RENDER_BACKEND_METAL
const auto zoom = parameters.state.getZoom();
if (permutationUpdated) {
const FillExtrusionPermutationUBO permutationUBO = {
/* .color = */ {/*.source=*/getAttributeSource<BuiltIn::FillExtrusionShader>(2), /*.expression=*/{}},
/* .base = */ {/*.source=*/getAttributeSource<BuiltIn::FillExtrusionShader>(3), /*.expression=*/{}},
/* .height = */ {/*.source=*/getAttributeSource<BuiltIn::FillExtrusionShader>(4), /*.expression=*/{}},
/* .pattern_from = */
{/*.source=*/getAttributeSource<BuiltIn::FillExtrusionPatternShader>(4), /*.expression=*/{}},
/* .pattern_to = */
{/*.source=*/getAttributeSource<BuiltIn::FillExtrusionPatternShader>(5), /*.expression=*/{}},
/* .overdrawInspector = */ overdrawInspector,
/* .pad = */ 0,
0,
0,
0};
if (permutationUniformBuffer) {
permutationUniformBuffer->update(&permutationUBO, sizeof(permutationUBO));
} else {
permutationUniformBuffer = context.createUniformBuffer(&permutationUBO, sizeof(permutationUBO));
}
permutationUpdated = false;
}
if (!expressionUniformBuffer) {
const auto expressionUBO = buildExpressionUBO(zoom, parameters.frameCount);
expressionUniformBuffer = context.createUniformBuffer(&expressionUBO, sizeof(expressionUBO));
}
#endif
visitLayerGroupDrawables(layerGroup, [&](gfx::Drawable& drawable) {
if (!drawable.getTileID() || !checkTweakDrawable(drawable)) {
return;
@@ -154,11 +122,6 @@ void FillExtrusionLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintP
/* .pad = */ 0};
uniforms.createOrUpdate(idFillExtrusionDrawableUBOName, &drawableUBO, context);
#if MLN_RENDER_BACKEND_METAL
uniforms.addOrReplace(idExpressionInputsUBOName, expressionUniformBuffer);
uniforms.addOrReplace(idFillExtrusionPermutationUBOName, permutationUniformBuffer);
#endif // MLN_RENDER_BACKEND_METAL
});
}

View File

@@ -27,7 +27,6 @@ using namespace style;
static const StringIdentity idFillDrawableUBOName = stringIndexer().get("FillDrawableUBO");
static const StringIdentity idFillDrawablePropsUBOName = stringIndexer().get("FillDrawablePropsUBO");
static const StringIdentity idFillEvaluatedPropsUBOName = stringIndexer().get("FillEvaluatedPropsUBO");
static const StringIdentity idFillPermutationUBOName = stringIndexer().get("FillPermutationUBO");
const StringIdentity FillLayerTweaker::idFillTilePropsUBOName = stringIndexer().get("FillDrawableTilePropsUBO");
const StringIdentity FillLayerTweaker::idFillInterpolateUBOName = stringIndexer().get("FillInterpolateUBO");
@@ -36,19 +35,15 @@ const StringIdentity FillLayerTweaker::idFillOutlineInterpolateUBOName = stringI
static const StringIdentity idFillOutlineDrawableUBOName = stringIndexer().get("FillOutlineDrawableUBO");
static const StringIdentity idFillOutlineEvaluatedPropsUBOName = stringIndexer().get("FillOutlineEvaluatedPropsUBO");
static const StringIdentity idFillOutlinePermutationUBOName = stringIndexer().get("FillOutlinePermutationUBO");
static const StringIdentity idFillOutlineInterpolateUBOName = stringIndexer().get("FillOutlineInterpolateUBO");
static const StringIdentity idFillPatternDrawableUBOName = stringIndexer().get("FillPatternDrawableUBO");
static const StringIdentity idFillPatternPermutationUBOName = stringIndexer().get("FillPatternPermutationUBO");
static const StringIdentity idFillPatternInterpolateUBOName = stringIndexer().get("FillPatternInterpolateUBO");
static const StringIdentity idFillPatternEvaluatedPropsUBOName = stringIndexer().get("FillPatternEvaluatedPropsUBO");
static const StringIdentity idFillPatternTilePropsUBOName = stringIndexer().get("FillPatternTilePropsUBO");
static const StringIdentity idFillOutlinePatternDrawableUBOName = stringIndexer().get("FillOutlinePatternDrawableUBO");
static const StringIdentity idFillOutlinePatternPermutationUBOName = stringIndexer().get(
"FillOutlinePatternPermutationUBO");
static const StringIdentity idFillOutlinePatternInterpolateUBOName = stringIndexer().get(
"FillOutlinePatternInterpolateUBO");
static const StringIdentity idFillOutlinePatternEvaluatedPropsUBOName = stringIndexer().get(
@@ -56,8 +51,6 @@ static const StringIdentity idFillOutlinePatternEvaluatedPropsUBOName = stringIn
static const StringIdentity idFillOutlinePatternTilePropsUBOName = stringIndexer().get(
"FillOutlinePatternTilePropsUBO");
static const StringIdentity idExpressionInputsUBOName = stringIndexer().get("ExpressionInputsUBO");
static const StringIdentity idTexImageName = stringIndexer().get("u_image");
using namespace shaders;
@@ -86,24 +79,6 @@ void FillLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintParameters
if (fillUniformBufferUpdated) return;
fillUniformBufferUpdated = true;
#if MLN_RENDER_BACKEND_METAL
if (permutationUpdated || !fillPermutationUniformBuffer) {
const FillPermutationUBO permutationUBO = {
/* .color = */ {/*.source=*/getAttributeSource<BuiltIn::FillShader>(1), /*.expression=*/{}},
/* .opacity = */ {/*.source=*/getAttributeSource<BuiltIn::FillShader>(2), /*.expression=*/{}},
/* .overdrawInspector = */ overdrawInspector,
0,
0,
0,
0,
0,
0,
};
context.emplaceOrUpdateUniformBuffer(fillPermutationUniformBuffer, &permutationUBO);
}
#endif
if (!fillPropsUniformBuffer || propertiesUpdated) {
const FillEvaluatedPropsUBO paramsUBO = {
/* .color = */ evaluated.get<FillColor>().constantOr(FillColor::defaultValue()),
@@ -120,24 +95,6 @@ void FillLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintParameters
if (fillOutlineUniformBufferUpdated) return;
fillOutlineUniformBufferUpdated = true;
#if MLN_RENDER_BACKEND_METAL
if (permutationUpdated || !fillOutlinePermutationUniformBuffer) {
const FillOutlinePermutationUBO permutationUBO = {
/* .outline_color = */ {/*.source=*/getAttributeSource<BuiltIn::FillOutlineShader>(1),
/*.expression=*/{}},
/* .opacity = */ {/*.source=*/getAttributeSource<BuiltIn::FillOutlineShader>(2), /*.expression=*/{}},
/* .overdrawInspector = */ overdrawInspector,
0,
0,
0,
0,
0,
0,
};
context.emplaceOrUpdateUniformBuffer(fillOutlinePermutationUniformBuffer, &permutationUBO);
}
#endif
if (!fillOutlinePropsUniformBuffer || propertiesUpdated) {
const FillOutlineEvaluatedPropsUBO paramsUBO = {
/* .outline_color = */ evaluated.get<FillOutlineColor>().constantOr(FillOutlineColor::defaultValue()),
@@ -154,25 +111,6 @@ void FillLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintParameters
if (fillPatternUniformBufferUpdated) return;
fillPatternUniformBufferUpdated = true;
#if MLN_RENDER_BACKEND_METAL
if (permutationUpdated || !fillPatternPermutationUniformBuffer) {
const FillPatternPermutationUBO permutationUBO = {
/* .pattern_from = */ {/*.source=*/getAttributeSource<BuiltIn::FillPatternShader>(1),
/*.expression=*/{}},
/* .pattern_to = */
{/*.source=*/getAttributeSource<BuiltIn::FillPatternShader>(2), /*.expression=*/{}},
/* .opacity = */
{/*.source=*/getAttributeSource<BuiltIn::FillPatternShader>(3), /*.expression=*/{}},
/* .overdrawInspector = */ overdrawInspector,
0,
0,
0,
0,
};
context.emplaceOrUpdateUniformBuffer(fillPatternPermutationUniformBuffer, &permutationUBO);
}
#endif
if (!fillPatternPropsUniformBuffer || propertiesUpdated) {
const FillPatternEvaluatedPropsUBO paramsUBO = {
/* .opacity = */ evaluated.get<FillOpacity>().constantOr(FillOpacity::defaultValue()),
@@ -188,25 +126,6 @@ void FillLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintParameters
if (fillOutlinePatternUniformBufferUpdated) return;
fillOutlinePatternUniformBufferUpdated = true;
#if MLN_RENDER_BACKEND_METAL
if (permutationUpdated || !fillOutlinePatternPermutationUniformBuffer) {
const FillOutlinePatternPermutationUBO permutationUBO = {
/* .pattern_from = */ {/*.source=*/getAttributeSource<BuiltIn::FillOutlinePatternShader>(1),
/*.expression=*/{}},
/* .pattern_to = */
{/*.source=*/getAttributeSource<BuiltIn::FillOutlinePatternShader>(2), /*.expression=*/{}},
/* .opacity = */
{/*.source=*/getAttributeSource<BuiltIn::FillOutlinePatternShader>(3), /*.expression=*/{}},
/* .overdrawInspector = */ overdrawInspector,
0,
0,
0,
0,
};
context.emplaceOrUpdateUniformBuffer(fillOutlinePatternPermutationUniformBuffer, &permutationUBO);
}
#endif
if (!fillOutlinePatternPropsUniformBuffer || propertiesUpdated) {
const FillOutlinePatternEvaluatedPropsUBO paramsUBO = {
/* .opacity = */ evaluated.get<FillOpacity>().constantOr(FillOpacity::defaultValue()),
@@ -218,12 +137,6 @@ void FillLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintParameters
}
};
#if MLN_RENDER_BACKEND_METAL
const auto zoom = parameters.state.getZoom();
const auto expressionUBO = buildExpressionUBO(zoom, parameters.frameCount);
context.emplaceOrUpdateUniformBuffer(expressionUniformBuffer, &expressionUBO);
#endif
const auto& translation = evaluated.get<FillTranslate>();
const auto anchor = evaluated.get<FillTranslateAnchor>();
@@ -268,10 +181,6 @@ void FillLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintParameters
const FillDrawableUBO drawableUBO = {/*.matrix=*/util::cast<float>(matrix)};
uniforms.createOrUpdate(idFillDrawableUBOName, &drawableUBO, context);
#if MLN_RENDER_BACKEND_METAL
uniforms.addOrReplace(idFillPermutationUBOName, fillPermutationUniformBuffer);
#endif // MLN_RENDER_BACKEND_METAL
} else if (uniforms.get(idFillOutlineInterpolateUBOName)) {
UpdateFillOutlineUniformBuffers();
@@ -283,10 +192,6 @@ void FillLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintParameters
/* pad1 */ 0,
/* pad2 */ 0};
uniforms.createOrUpdate(idFillOutlineDrawableUBOName, &drawableUBO, context);
#if MLN_RENDER_BACKEND_METAL
uniforms.addOrReplace(idFillOutlinePermutationUBOName, fillOutlinePermutationUniformBuffer);
#endif // MLN_RENDER_BACKEND_METAL
} else if (uniforms.get(idFillPatternInterpolateUBOName)) {
UpdateFillPatternUniformBuffers();
@@ -302,10 +207,6 @@ void FillLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintParameters
0,
};
uniforms.createOrUpdate(idFillPatternDrawableUBOName, &drawableUBO, context);
#if MLN_RENDER_BACKEND_METAL
uniforms.addOrReplace(idFillPatternPermutationUBOName, fillPatternPermutationUniformBuffer);
#endif // MLN_RENDER_BACKEND_METAL
} else if (uniforms.get(idFillOutlinePatternInterpolateUBOName)) {
UpdateFillOutlinePatternUniformBuffers();
@@ -320,18 +221,9 @@ void FillLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintParameters
/*.texsize=*/{static_cast<float>(textureSize.width), static_cast<float>(textureSize.height)},
};
uniforms.createOrUpdate(idFillOutlinePatternDrawableUBOName, &drawableUBO, context);
#if MLN_RENDER_BACKEND_METAL
uniforms.addOrReplace(idFillOutlinePatternPermutationUBOName, fillOutlinePatternPermutationUniformBuffer);
#endif // MLN_RENDER_BACKEND_METAL
}
#if MLN_RENDER_BACKEND_METAL
uniforms.addOrReplace(idExpressionInputsUBOName, expressionUniformBuffer);
#endif // MLN_RENDER_BACKEND_METAL
});
permutationUpdated = false;
propertiesUpdated = false;
}

View File

@@ -29,14 +29,6 @@ private:
gfx::UniformBufferPtr fillOutlinePropsUniformBuffer;
gfx::UniformBufferPtr fillPatternPropsUniformBuffer;
gfx::UniformBufferPtr fillOutlinePatternPropsUniformBuffer;
gfx::UniformBufferPtr fillPermutationUniformBuffer;
gfx::UniformBufferPtr fillOutlinePermutationUniformBuffer;
gfx::UniformBufferPtr fillPatternPermutationUniformBuffer;
gfx::UniformBufferPtr fillOutlinePatternPermutationUniformBuffer;
#if MLN_RENDER_BACKEND_METAL
gfx::UniformBufferPtr expressionUniformBuffer;
#endif // MLN_RENDER_BACKEND_METAL
};
} // namespace mbgl

View File

@@ -22,8 +22,6 @@ using namespace shaders;
static const StringIdentity idHeatmapDrawableUBOName = stringIndexer().get("HeatmapDrawableUBO");
static const StringIdentity idHeatmapEvaluatedPropsUBOName = stringIndexer().get("HeatmapEvaluatedPropsUBO");
static const StringIdentity idHeatmapPermutationUBOName = stringIndexer().get("HeatmapPermutationUBO");
static const StringIdentity idExpressionInputsUBOName = stringIndexer().get("ExpressionInputsUBO");
void HeatmapLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintParameters& parameters) {
auto& context = parameters.context;
@@ -40,33 +38,6 @@ void HeatmapLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintParamet
const auto zoom = parameters.state.getZoom();
#if MLN_RENDER_BACKEND_METAL
if (permutationUpdated) {
const HeatmapPermutationUBO permutationUBO = {
/* .weight = */ {/*.source=*/getAttributeSource<BuiltIn::HeatmapShader>(1), /*.expression=*/{}},
/* .radius = */ {/*.source=*/getAttributeSource<BuiltIn::HeatmapShader>(2), /*.expression=*/{}},
/* .overdrawInspector = */ overdrawInspector,
/* .pad1/2/3 = */ 0,
0,
0,
/* .pad4/5/6 = */ 0,
0,
0};
if (permutationUniformBuffer) {
permutationUniformBuffer->update(&permutationUBO, sizeof(permutationUBO));
} else {
permutationUniformBuffer = context.createUniformBuffer(&permutationUBO, sizeof(permutationUBO));
}
permutationUpdated = false;
}
if (!expressionUniformBuffer) {
const auto expressionUBO = buildExpressionUBO(zoom, parameters.frameCount);
expressionUniformBuffer = context.createUniformBuffer(&expressionUBO, sizeof(expressionUBO));
}
#endif
if (!evaluatedPropsUniformBuffer) {
const HeatmapEvaluatedPropsUBO evaluatedPropsUBO = {
/* .weight = */ evaluated.get<HeatmapWeight>().constantOr(HeatmapWeight::defaultValue()),
@@ -97,11 +68,6 @@ void HeatmapLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintParamet
/* .padding = */ {0}};
uniforms.createOrUpdate(idHeatmapDrawableUBOName, &drawableUBO, context);
#if MLN_RENDER_BACKEND_METAL
uniforms.addOrReplace(idHeatmapPermutationUBOName, permutationUniformBuffer);
uniforms.addOrReplace(idExpressionInputsUBOName, expressionUniformBuffer);
#endif // MLN_RENDER_BACKEND_METAL
});
}

View File

@@ -42,10 +42,8 @@ void HeatmapTextureLayerTweaker::execute(LayerGroupBase& layerGroup, const Paint
/* .matrix = */ util::cast<float>(viewportMat),
/* .world = */ {static_cast<float>(size.width), static_cast<float>(size.height)},
/* .opacity = */ evaluated.get<HeatmapOpacity>(),
/* .overdrawInspector = */ overdrawInspector,
/* .pad1 = */ 0,
/* .pad2 = */ 0,
/* .pad3 = */ 0};
};
drawable.mutableUniformBuffers().createOrUpdate(
idHeatmapTextureDrawableUBOName, &drawableUBO, parameters.context);

View File

@@ -65,14 +65,7 @@ void HillshadeLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintParam
tileID, parameters, {0.f, 0.f}, TranslateAnchorType::Viewport, false, false, true);
HillshadeDrawableUBO drawableUBO = {/* .matrix = */ util::cast<float>(matrix),
/* .latrange = */ getLatRange(tileID),
/* .light = */ getLight(parameters, evaluated),
/* .overdrawInspector = */ overdrawInspector,
/* .pad1/2/3 = */ 0,
0,
0,
/* .pad4/5/6 = */ 0,
0,
0};
/* .light = */ getLight(parameters, evaluated)};
drawable.mutableUniformBuffers().createOrUpdate(idHillshadeDrawableUBOName, &drawableUBO, parameters.context);
});

View File

@@ -55,14 +55,7 @@ void HillshadePrepareLayerTweaker::execute(LayerGroupBase& layerGroup, const Pai
/* .unpack = */ getUnpackVector(drawableData.encoding),
/* .dimension = */ {static_cast<float>(drawableData.stride), static_cast<float>(drawableData.stride)},
/* .zoom = */ static_cast<float>(tileID.canonical.z),
/* .maxzoom = */ static_cast<float>(drawableData.maxzoom),
/* .overdrawInspector = */ overdrawInspector,
/* .pad1/2/3 = */ 0,
0,
0,
/* .pad4/5/6 = */ 0,
0,
0};
/* .maxzoom = */ static_cast<float>(drawableData.maxzoom)};
drawable.mutableUniformBuffers().createOrUpdate(
idHillshadePrepareDrawableUBOName, &drawableUBO, parameters.context);

View File

@@ -35,9 +35,6 @@ static const StringIdentity idLineSDFUBOName = stringIndexer().get("LineSDFUBO")
static const StringIdentity idLineSDFPropertiesUBOName = stringIndexer().get("LineSDFPropertiesUBO");
static const StringIdentity idTexImageName = stringIndexer().get("u_image");
static const StringIdentity idExpressionInputsUBOName = stringIndexer().get("ExpressionInputsUBO");
static const StringIdentity idLinePermutationUBOName = stringIndexer().get("LinePermutationUBO");
void LineLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintParameters& parameters) {
auto& context = parameters.context;
const auto& evaluated = static_cast<const LineLayerProperties&>(*evaluatedProperties).evaluated;
@@ -110,13 +107,6 @@ void LineLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintParameters
return lineSDFPropertiesBuffer;
};
#if MLN_RENDER_BACKEND_METAL
if (!expressionUniformBuffer) {
const auto expressionUBO = buildExpressionUBO(zoom, parameters.frameCount);
expressionUniformBuffer = context.createUniformBuffer(&expressionUBO, sizeof(expressionUBO));
}
#endif
visitLayerGroupDrawables(layerGroup, [&](gfx::Drawable& drawable) {
const auto shader = drawable.getShader();
if (!drawable.getTileID() || !shader || !checkTweakDrawable(drawable)) {
@@ -145,29 +135,6 @@ void LineLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintParameters
// properties UBO
uniforms.addOrReplace(idLinePropertiesUBOName, getLinePropsBuffer());
#if MLN_RENDER_BACKEND_METAL
if (permutationUpdated) {
const LinePermutationUBO permutationUBO = {
/* .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=*/{}},
/* .overdrawInspector = */ overdrawInspector,
/* .pad = */ 0,
0,
0,
0};
context.emplaceOrUpdateUniformBuffer(permutationUniformBuffer, &permutationUBO);
permutationUpdated = false;
}
#endif
} break;
case LineType::Gradient: {
@@ -180,34 +147,6 @@ void LineLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintParameters
// properties UBO
uniforms.addOrReplace(idLineGradientPropertiesUBOName, getLineGradientPropsBuffer());
#if MLN_RENDER_BACKEND_METAL
if (permutationUpdated) {
const LinePermutationUBO permutationUBO = {
/* .color = */ {/*.source=*/AttributeSource::Constant, /*.expression=*/{}},
/* .blur = */
{/*.source=*/getAttributeSource<BuiltIn::LineGradientShader>(2), /*.expression=*/{}},
/* .opacity = */
{/*.source=*/getAttributeSource<BuiltIn::LineGradientShader>(3), /*.expression=*/{}},
/* .gapwidth = */
{/*.source=*/getAttributeSource<BuiltIn::LineGradientShader>(4), /*.expression=*/{}},
/* .offset = */
{/*.source=*/getAttributeSource<BuiltIn::LineGradientShader>(5), /*.expression=*/{}},
/* .width = */
{/*.source=*/getAttributeSource<BuiltIn::LineGradientShader>(6), /*.expression=*/{}},
/* .floorwidth = */ {/*.source=*/AttributeSource::Constant, /*.expression=*/{}},
/* .pattern_from = */ {/*.source=*/AttributeSource::Constant, /*.expression=*/{}},
/* .pattern_to = */ {/*.source=*/AttributeSource::Constant, /*.expression=*/{}},
/* .overdrawInspector = */ overdrawInspector,
/* .pad = */ 0,
0,
0,
0};
context.emplaceOrUpdateUniformBuffer(permutationUniformBuffer, &permutationUBO);
permutationUpdated = false;
}
#endif
} break;
case LineType::Pattern: {
@@ -234,35 +173,6 @@ void LineLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintParameters
// properties UBO
uniforms.addOrReplace(idLinePatternPropertiesUBOName, getLinePatternPropsBuffer());
#if MLN_RENDER_BACKEND_METAL
if (permutationUpdated) {
const LinePermutationUBO permutationUBO = {
/* .color = */ {/*.source=*/AttributeSource::Constant, /*.expression=*/{}},
/* .blur = */
{/*.source=*/getAttributeSource<BuiltIn::LinePatternShader>(2), /*.expression=*/{}},
/* .opacity = */
{/*.source=*/getAttributeSource<BuiltIn::LinePatternShader>(3), /*.expression=*/{}},
/* .gapwidth = */
{/*.source=*/getAttributeSource<BuiltIn::LinePatternShader>(4), /*.expression=*/{}},
/* .offset = */
{/*.source=*/getAttributeSource<BuiltIn::LinePatternShader>(5), /*.expression=*/{}},
/* .width = */
{/*.source=*/getAttributeSource<BuiltIn::LinePatternShader>(6), /*.expression=*/{}},
/* .floorwidth = */ {/*.source=*/AttributeSource::Constant, /*.expression=*/{}},
/* .pattern_from = */
{/*.source=*/getAttributeSource<BuiltIn::LinePatternShader>(7), /*.expression=*/{}},
/* .pattern_to = */
{/*.source=*/getAttributeSource<BuiltIn::LinePatternShader>(8), /*.expression=*/{}},
/* .overdrawInspector = */ overdrawInspector,
/* .pad = */ 0,
0,
0,
0};
context.emplaceOrUpdateUniformBuffer(permutationUniformBuffer, &permutationUBO);
permutationUpdated = false;
}
#endif
} break;
case LineType::SDF: {
@@ -309,32 +219,6 @@ void LineLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintParameters
// properties UBO
uniforms.addOrReplace(idLineSDFPropertiesUBOName, getLineSDFPropsBuffer());
}
#if MLN_RENDER_BACKEND_METAL
if (permutationUpdated) {
const LinePermutationUBO permutationUBO = {
/* .color = */ {/*.source=*/getAttributeSource<BuiltIn::LineSDFShader>(2), /*.expression=*/{}},
/* .blur = */ {/*.source=*/getAttributeSource<BuiltIn::LineSDFShader>(3), /*.expression=*/{}},
/* .opacity = */
{/*.source=*/getAttributeSource<BuiltIn::LineSDFShader>(4), /*.expression=*/{}},
/* .gapwidth = */
{/*.source=*/getAttributeSource<BuiltIn::LineSDFShader>(5), /*.expression=*/{}},
/* .offset = */ {/*.source=*/getAttributeSource<BuiltIn::LineSDFShader>(6), /*.expression=*/{}},
/* .width = */ {/*.source=*/getAttributeSource<BuiltIn::LineSDFShader>(7), /*.expression=*/{}},
/* .floorwidth = */
{/*.source=*/getAttributeSource<BuiltIn::LineSDFShader>(8), /*.expression=*/{}},
/* .pattern_from = */ {/*.source=*/AttributeSource::Constant, /*.expression=*/{}},
/* .pattern_to = */ {/*.source=*/AttributeSource::Constant, /*.expression=*/{}},
/* .overdrawInspector = */ overdrawInspector,
/* .pad = */ 0,
0,
0,
0};
context.emplaceOrUpdateUniformBuffer(permutationUniformBuffer, &permutationUBO);
permutationUpdated = false;
}
#endif
} break;
default: {
@@ -343,11 +227,6 @@ void LineLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintParameters
"LineLayerTweaker: unknown line type: "s + std::to_string(mbgl::underlying_type(type)));
} break;
}
#if MLN_RENDER_BACKEND_METAL
uniforms.addOrReplace(idExpressionInputsUBOName, expressionUniformBuffer);
uniforms.addOrReplace(idLinePermutationUBOName, permutationUniformBuffer);
#endif // MLN_RENDER_BACKEND_METAL
});
}

View File

@@ -80,9 +80,6 @@ void RasterLayerTweaker::execute([[maybe_unused]] LayerGroupBase& layerGroup,
/*.brightness_high = */ evaluated.get<RasterBrightnessMax>(),
/*.saturation_factor = */ saturationFactor(evaluated.get<RasterSaturation>()),
/*.contrast_factor = */ contrastFactor(evaluated.get<RasterContrast>()),
/*.overdrawInspector = */ overdrawInspector,
0,
0,
0,
0};
auto& uniforms = drawable.mutableUniformBuffers();

View File

@@ -213,7 +213,7 @@ static constexpr std::string_view BackgroundPatternShaderName = "BackgroundPatte
void RenderBackgroundLayer::update(gfx::ShaderRegistry& shaders,
gfx::Context& context,
const TransformState& state,
const std::shared_ptr<UpdateParameters>& updateParameters,
const std::shared_ptr<UpdateParameters>&,
[[maybe_unused]] const RenderTree& renderTree,
[[maybe_unused]] UniqueChangeRequestVec& changes) {
std::unique_lock<std::mutex> guard(mutex);
@@ -258,7 +258,6 @@ void RenderBackgroundLayer::update(gfx::ShaderRegistry& shaders,
layerTweaker = std::make_shared<BackgroundLayerTweaker>(getID(), evaluatedProperties);
layerGroup->addLayerTweaker(layerTweaker);
}
layerTweaker->enableOverdrawInspector(!!(updateParameters->debugOptions & MapDebugOptions::Overdraw));
if (!hasPattern && !plainShader) {
plainShader = context.getGenericShader(shaders, std::string(BackgroundPlainShaderName));

View File

@@ -88,12 +88,6 @@ void RenderCircleLayer::evaluate(const PropertyEvaluationParameters& parameters)
#if MLN_DRAWABLE_RENDERER
if (layerGroup) {
auto newTweaker = std::make_shared<CircleLayerTweaker>(getID(), evaluatedProperties);
// propertiesAsUniforms isn't recalculated every update, so carry it over
if (layerTweaker) {
newTweaker->setPropertiesAsUniforms(layerTweaker->getPropertiesAsUniforms());
}
replaceTweaker(layerTweaker, std::move(newTweaker), {layerGroup});
}
#endif // MLN_DRAWABLE_RENDERER
@@ -281,7 +275,7 @@ using namespace shaders;
void RenderCircleLayer::update(gfx::ShaderRegistry& shaders,
gfx::Context& context,
const TransformState& state,
[[maybe_unused]] const std::shared_ptr<UpdateParameters>& updateParameters,
[[maybe_unused]] const std::shared_ptr<UpdateParameters>&,
[[maybe_unused]] const RenderTree& renderTree,
UniqueChangeRequestVec& changes) {
std::unique_lock<std::mutex> guard(mutex);
@@ -300,12 +294,10 @@ void RenderCircleLayer::update(gfx::ShaderRegistry& shaders,
}
}
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);
@@ -398,10 +390,6 @@ void RenderCircleLayer::update(gfx::ShaderRegistry& shaders,
continue;
}
if (layerTweaker) {
layerTweaker->setPropertiesAsUniforms(propertiesAsUniforms);
}
if (const auto& attr = circleVertexAttrs->add(idVertexAttribName)) {
attr->setSharedRawData(bucket.sharedVertices,
offsetof(CircleLayoutVertex, a1),

View File

@@ -77,12 +77,6 @@ void RenderFillExtrusionLayer::evaluate(const PropertyEvaluationParameters& para
#if MLN_DRAWABLE_RENDERER
if (layerGroup) {
auto newTweaker = std::make_shared<FillExtrusionLayerTweaker>(getID(), evaluatedProperties);
// propertiesAsUniforms isn't recalculated every update, so carry it over
if (layerTweaker) {
newTweaker->setPropertiesAsUniforms(layerTweaker->getPropertiesAsUniforms());
}
replaceTweaker(layerTweaker, std::move(newTweaker), {layerGroup});
}
#endif // MLN_DRAWABLE_RENDERER
@@ -283,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>& updateParameters,
const std::shared_ptr<UpdateParameters>&,
const RenderTree& /*renderTree*/,
UniqueChangeRequestVec& changes) {
if (!renderTiles || renderTiles->empty() || passes == RenderPass::None) {
@@ -305,8 +299,6 @@ void RenderFillExtrusionLayer::update(gfx::ShaderRegistry& shaders,
layerGroup->addLayerTweaker(layerTweaker);
}
layerTweaker->enableOverdrawInspector(!!(updateParameters->debugOptions & MapDebugOptions::Overdraw));
if (!fillExtrusionGroup) {
fillExtrusionGroup = shaders.getShaderGroup("FillExtrusionShader");
}
@@ -433,10 +425,6 @@ void RenderFillExtrusionLayer::update(gfx::ShaderRegistry& shaders,
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);

View File

@@ -405,7 +405,7 @@ private:
void RenderFillLayer::update(gfx::ShaderRegistry& shaders,
gfx::Context& context,
const TransformState& state,
const std::shared_ptr<UpdateParameters>& updateParameters,
const std::shared_ptr<UpdateParameters>&,
[[maybe_unused]] const RenderTree& renderTree,
[[maybe_unused]] UniqueChangeRequestVec& changes) {
std::unique_lock<std::mutex> guard(mutex);
@@ -441,7 +441,6 @@ void RenderFillLayer::update(gfx::ShaderRegistry& shaders,
layerTweaker = std::make_shared<FillLayerTweaker>(getID(), evaluatedProperties);
layerGroup->addLayerTweaker(layerTweaker);
}
layerTweaker->enableOverdrawInspector(!!(updateParameters->debugOptions & MapDebugOptions::Overdraw));
if (!fillShaderGroup) {
fillShaderGroup = shaders.getShaderGroup(std::string(FillShaderName));
@@ -627,10 +626,6 @@ void RenderFillLayer::update(gfx::ShaderRegistry& shaders,
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)) {
attr->setSharedRawData(bucket.sharedVertices,

View File

@@ -71,11 +71,6 @@ void RenderHeatmapLayer::evaluate(const PropertyEvaluationParameters& parameters
if (renderTarget) {
if (auto tileLayerGroup = renderTarget->getLayerGroup(0)) {
auto newTweaker = std::make_shared<HeatmapLayerTweaker>(getID(), evaluatedProperties);
if (layerTweaker) {
newTweaker->setPropertiesAsUniforms(layerTweaker->getPropertiesAsUniforms());
}
replaceTweaker(layerTweaker, std::move(newTweaker), {std::move(tileLayerGroup)});
}
}
@@ -290,7 +285,7 @@ using namespace shaders;
void RenderHeatmapLayer::update(gfx::ShaderRegistry& shaders,
gfx::Context& context,
const TransformState& state,
const std::shared_ptr<UpdateParameters>& updateParameters,
const std::shared_ptr<UpdateParameters>&,
[[maybe_unused]] const RenderTree& renderTree,
UniqueChangeRequestVec& changes) {
std::unique_lock<std::mutex> guard(mutex);
@@ -338,7 +333,6 @@ void RenderHeatmapLayer::update(gfx::ShaderRegistry& shaders,
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;
@@ -477,10 +471,6 @@ void RenderHeatmapLayer::update(gfx::ShaderRegistry& shaders,
}
}
if (layerTweaker && propertiesAsUniforms) {
layerTweaker->setPropertiesAsUniforms(*propertiesAsUniforms);
}
// Set up texture layer group
if (!layerGroup) {
if (auto layerGroup_ = context.createLayerGroup(layerIndex, /*initialCapacity=*/1, getID())) {
@@ -496,7 +486,6 @@ void RenderHeatmapLayer::update(gfx::ShaderRegistry& shaders,
textureTweaker = std::make_shared<HeatmapTextureLayerTweaker>(getID(), evaluatedProperties);
layerGroup->addLayerTweaker(textureTweaker);
}
textureTweaker->enableOverdrawInspector(!!(updateParameters->debugOptions & MapDebugOptions::Overdraw));
if (!heatmapTextureShader) {
heatmapTextureShader = context.getGenericShader(shaders, HeatmapTextureShaderGroupName);

View File

@@ -306,7 +306,7 @@ static const StringIdentity idTexImageName = stringIndexer().get("u_image");
void RenderHillshadeLayer::update(gfx::ShaderRegistry& shaders,
gfx::Context& context,
[[maybe_unused]] const TransformState& state,
const std::shared_ptr<UpdateParameters>& updateParameters,
const std::shared_ptr<UpdateParameters>&,
[[maybe_unused]] const RenderTree& renderTree,
UniqueChangeRequestVec& changes) {
std::unique_lock<std::mutex> guard(mutex);
@@ -331,7 +331,6 @@ void RenderHillshadeLayer::update(gfx::ShaderRegistry& shaders,
layerTweaker = std::make_shared<HillshadeLayerTweaker>(getID(), evaluatedProperties);
layerGroup->addLayerTweaker(layerTweaker);
}
layerTweaker->enableOverdrawInspector(!!(updateParameters->debugOptions & MapDebugOptions::Overdraw));
if (!hillshadePrepareShader) {
hillshadePrepareShader = context.getGenericShader(shaders, HillshadePrepareShaderGroupName);

View File

@@ -83,12 +83,6 @@ void RenderLineLayer::evaluate(const PropertyEvaluationParameters& parameters) {
#if MLN_DRAWABLE_RENDERER
if (layerGroup) {
auto newTweaker = std::make_shared<LineLayerTweaker>(getID(), evaluatedProperties);
// propertiesAsUniforms isn't recalculated every update, so carry it over
if (layerTweaker) {
newTweaker->setPropertiesAsUniforms(layerTweaker->getPropertiesAsUniforms());
}
replaceTweaker(layerTweaker, std::move(newTweaker), {layerGroup});
}
#endif
@@ -366,7 +360,7 @@ static const StringIdentity idLineImageUniformName = stringIndexer().get("u_imag
void RenderLineLayer::update(gfx::ShaderRegistry& shaders,
gfx::Context& context,
const TransformState& state,
const std::shared_ptr<UpdateParameters>& updateParameters,
const std::shared_ptr<UpdateParameters>&,
[[maybe_unused]] const RenderTree& renderTree,
[[maybe_unused]] UniqueChangeRequestVec& changes) {
std::unique_lock<std::mutex> guard(mutex);
@@ -390,7 +384,6 @@ void RenderLineLayer::update(gfx::ShaderRegistry& shaders,
layerTweaker = std::make_shared<LineLayerTweaker>(getID(), evaluatedProperties);
layerGroup->addLayerTweaker(layerTweaker);
}
layerTweaker->enableOverdrawInspector(!!(updateParameters->debugOptions & MapDebugOptions::Overdraw));
if (!lineShaderGroup) {
lineShaderGroup = shaders.getShaderGroup("LineShader");
@@ -599,10 +592,6 @@ void RenderLineLayer::update(gfx::ShaderRegistry& shaders,
continue;
}
if (layerTweaker) {
layerTweaker->setPropertiesAsUniforms(propertiesAsUniforms);
}
auto builder = createLineBuilder("lineSDF", std::move(shader));
// vertices, attributes and segments
@@ -647,10 +636,6 @@ void RenderLineLayer::update(gfx::ShaderRegistry& shaders,
continue;
}
if (layerTweaker) {
layerTweaker->setPropertiesAsUniforms(propertiesAsUniforms);
}
auto builder = createLineBuilder("linePattern", std::move(shader));
// vertices and attributes
@@ -704,10 +689,6 @@ void RenderLineLayer::update(gfx::ShaderRegistry& shaders,
continue;
}
if (layerTweaker) {
layerTweaker->setPropertiesAsUniforms(propertiesAsUniforms);
}
auto builder = createLineBuilder("lineGradient", std::move(shader));
// vertices and attributes
@@ -760,10 +741,6 @@ void RenderLineLayer::update(gfx::ShaderRegistry& shaders,
continue;
}
if (layerTweaker) {
layerTweaker->setPropertiesAsUniforms(propertiesAsUniforms);
}
auto builder = createLineBuilder("line", std::move(shader));
// vertices, attributes and segments

View File

@@ -254,7 +254,7 @@ static const StringIdentity idTexImage1Name = stringIndexer().get("u_image1");
void RenderRasterLayer::update(gfx::ShaderRegistry& shaders,
gfx::Context& context,
const TransformState& /*state*/,
const std::shared_ptr<UpdateParameters>& updateParameters,
const std::shared_ptr<UpdateParameters>&,
[[maybe_unused]] const RenderTree& renderTree,
[[maybe_unused]] UniqueChangeRequestVec& changes) {
std::unique_lock<std::mutex> guard(mutex);
@@ -290,7 +290,6 @@ void RenderRasterLayer::update(gfx::ShaderRegistry& shaders,
imageLayerGroup->addLayerTweaker(layerTweaker);
}
}
layerTweaker->enableOverdrawInspector(!!(updateParameters->debugOptions & MapDebugOptions::Overdraw));
if (!staticDataVertices) {
staticDataVertices = std::make_shared<RasterVertexVector>(RenderStaticData::rasterVertices());

View File

@@ -974,7 +974,7 @@ std::size_t RenderSymbolLayer::removeAllDrawables() {
void RenderSymbolLayer::update(gfx::ShaderRegistry& shaders,
gfx::Context& context,
const TransformState& state,
const std::shared_ptr<UpdateParameters>& updateParameters,
const std::shared_ptr<UpdateParameters>&,
const RenderTree& /*renderTree*/,
UniqueChangeRequestVec& changes) {
if (!renderTiles || renderTiles->empty() || passes == RenderPass::None) {
@@ -993,7 +993,6 @@ void RenderSymbolLayer::update(gfx::ShaderRegistry& shaders,
layerTweaker = std::make_shared<SymbolLayerTweaker>(getID(), evaluatedProperties);
layerGroup->addLayerTweaker(layerTweaker);
}
layerTweaker->enableOverdrawInspector(!!(updateParameters->debugOptions & MapDebugOptions::Overdraw));
const auto& getCollisionTileLayerGroup = [&] {
if (!collisionTileLayerGroup) {

View File

@@ -46,8 +46,6 @@ std::array<float, 2> toArray(const Size& s) {
const StringIdentity idTexUniformName = stringIndexer().get("u_texture");
const StringIdentity idTexIconUniformName = stringIndexer().get("u_texture_icon");
const StringIdentity idExpressionInputsUBOName = stringIndexer().get("ExpressionInputsUBO");
const StringIdentity idSymbolPermutationUBOName = stringIndexer().get("SymbolPermutationUBO");
SymbolDrawablePaintUBO buildPaintUBO(bool isText, const SymbolPaintProperties::PossiblyEvaluated& evaluated) {
return {
@@ -86,15 +84,6 @@ void SymbolLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintParamete
const auto debugGroup = parameters.encoder->createDebugGroup(label.c_str());
#endif
const auto zoom = parameters.state.getZoom();
#if MLN_RENDER_BACKEND_METAL
if (!expressionUniformBuffer) {
const auto expressionUBO = buildExpressionUBO(zoom, parameters.frameCount);
expressionUniformBuffer = context.createUniformBuffer(&expressionUBO, sizeof(expressionUBO));
}
#endif
if (propertiesUpdated) {
textPropertiesUpdated = true;
iconPropertiesUpdated = true;
@@ -142,7 +131,7 @@ void SymbolLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintParamete
const auto matrix = getTileMatrix(tileID, parameters, translate, anchor, nearClipped, inViewportPixelUnits);
// from symbol_program, makeValues
const auto currentZoom = static_cast<float>(zoom);
const auto currentZoom = static_cast<float>(parameters.state.getZoom());
const float pixelsToTileUnits = tileID.pixelsToTileUnits(1.f, currentZoom);
const bool pitchWithMap = symbolData.pitchAlignment == style::AlignmentType::Map;
const bool rotateWithMap = symbolData.rotationAlignment == style::AlignmentType::Map;
@@ -183,31 +172,6 @@ void SymbolLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintParamete
uniforms.addOrReplace(idSymbolDynamicUBOName, dynamicBuffer);
uniforms.addOrReplace(idSymbolDrawablePaintUBOName, isText ? textPaintBuffer : iconPaintBuffer);
#if MLN_RENDER_BACKEND_METAL
assert(propertiesAsUniforms.empty());
using namespace shaders;
using ShaderClass = ShaderSource<BuiltIn::SymbolSDFIconShader, gfx::Backend::Type::Metal>;
const auto source = [&](int index) {
const auto nameID = ShaderClass::attributes[index].nameID;
const bool uniform = symbolData.propertiesAsUniforms.count(nameID);
return uniform ? AttributeSource::Constant : AttributeSource::PerVertex;
};
const SymbolPermutationUBO permutationUBO = {/* .fill_color = */ {/*.source=*/source(5), /*.expression=*/{}},
/* .halo_color = */ {/*.source=*/source(6), /*.expression=*/{}},
/* .opacity = */ {/*.source=*/source(7), /*.expression=*/{}},
/* .halo_width = */ {/*.source=*/source(8), /*.expression=*/{}},
/* .halo_blur = */ {/*.source=*/source(9), /*.expression=*/{}},
/* .overdrawInspector = */ overdrawInspector,
/* .pad = */ 0,
0,
0};
uniforms.createOrUpdate(idSymbolPermutationUBOName, &permutationUBO, context);
uniforms.addOrReplace(idExpressionInputsUBOName, expressionUniformBuffer);
#endif // MLN_RENDER_BACKEND_METAL
});
}

View File

@@ -232,28 +232,6 @@ void TileSourceRenderItem::updateDebugDrawables(DebugLayerGroupMap& debugLayerGr
uniforms.createOrUpdate(idLineUBOName, &lineUBO, parameters.context);
uniforms.createOrUpdate(idLinePropertiesUBOName, &linePropertiesUBO, parameters.context);
uniforms.createOrUpdate(idLineInterpolationUBOName, &lineInterpolationUBO, parameters.context);
static const StringIdentity idExpressionInputsUBOName = stringIndexer().get("ExpressionInputsUBO");
const auto expressionUBO = LayerTweaker::buildExpressionUBO(zoom, parameters.frameCount);
uniforms.createOrUpdate(idExpressionInputsUBOName, &expressionUBO, parameters.context);
static const StringIdentity idLinePermutationUBOName = stringIndexer().get("LinePermutationUBO");
const shaders::LinePermutationUBO permutationUBO = {
/* .color = */ {/*.source=*/shaders::AttributeSource::Constant, /*.expression=*/{}},
/* .blur = */ {/*.source=*/shaders::AttributeSource::Constant, /*.expression=*/{}},
/* .opacity = */ {/*.source=*/shaders::AttributeSource::Constant, /*.expression=*/{}},
/* .gapwidth = */ {/*.source=*/shaders::AttributeSource::Constant, /*.expression=*/{}},
/* .offset = */ {/*.source=*/shaders::AttributeSource::Constant, /*.expression=*/{}},
/* .width = */ {/*.source=*/shaders::AttributeSource::Constant, /*.expression=*/{}},
/* .floorwidth = */ {/*.source=*/shaders::AttributeSource::Constant, /*.expression=*/{}},
/* .pattern_from = */ {/*.source=*/shaders::AttributeSource::Constant, /*.expression=*/{}},
/* .pattern_to = */ {/*.source=*/shaders::AttributeSource::Constant, /*.expression=*/{}},
/* .overdrawInspector = */ false,
/* .pad = */ 0,
0,
0,
0};
uniforms.createOrUpdate(idLinePermutationUBOName, &permutationUBO, parameters.context);
};
private:

View File

@@ -13,13 +13,11 @@ const std::array<AttributeInfo, 8> ShaderSource<BuiltIn::CircleShader, gfx::Back
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 = {
const std::array<UniformBlockInfo, 4> 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 = {};

View File

@@ -8,12 +8,10 @@ const std::array<AttributeInfo, 3> ShaderSource<BuiltIn::FillShader, gfx::Backen
AttributeInfo{1, gfx::AttributeDataType::Float4, 1, "a_color"},
AttributeInfo{2, gfx::AttributeDataType::Float2, 1, "a_opacity"},
};
const std::array<UniformBlockInfo, 5> ShaderSource<BuiltIn::FillShader, gfx::Backend::Type::Metal>::uniforms = {
const std::array<UniformBlockInfo, 3> 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 = {};
@@ -22,12 +20,10 @@ const std::array<AttributeInfo, 3> ShaderSource<BuiltIn::FillOutlineShader, gfx:
AttributeInfo{1, gfx::AttributeDataType::Float4, 1, "a_outline_color"},
AttributeInfo{2, gfx::AttributeDataType::Float2, 1, "a_opacity"},
};
const std::array<UniformBlockInfo, 5> ShaderSource<BuiltIn::FillOutlineShader, gfx::Backend::Type::Metal>::uniforms = {
const std::array<UniformBlockInfo, 3> 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 = {};
@@ -37,13 +33,11 @@ const std::array<AttributeInfo, 4> ShaderSource<BuiltIn::FillPatternShader, gfx:
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 = {
const std::array<UniformBlockInfo, 4> ShaderSource<BuiltIn::FillPatternShader, gfx::Backend::Type::Metal>::uniforms = {
UniformBlockInfo{4, true, true, sizeof(FillPatternDrawableUBO), "FillPatternDrawableUBO"},
UniformBlockInfo{5, true, true, 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"},
@@ -56,14 +50,12 @@ const std::array<AttributeInfo, 4>
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,
const std::array<UniformBlockInfo, 4> ShaderSource<BuiltIn::FillOutlinePatternShader,
gfx::Backend::Type::Metal>::uniforms = {
UniformBlockInfo{4, true, true, sizeof(FillOutlinePatternDrawableUBO), "FillOutlinePatternDrawableUBO"},
UniformBlockInfo{5, true, true, 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 =
{

View File

@@ -10,13 +10,11 @@ const std::array<AttributeInfo, 5> ShaderSource<BuiltIn::FillExtrusionShader, gf
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 =
const std::array<UniformBlockInfo, 3> 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 = {};

View File

@@ -13,14 +13,12 @@ const std::array<AttributeInfo, 6>
AttributeInfo{4, gfx::AttributeDataType::UShort4, 1, "a_pattern_from"},
AttributeInfo{5, gfx::AttributeDataType::UShort4, 1, "a_pattern_to"},
};
const std::array<UniformBlockInfo, 6> ShaderSource<BuiltIn::FillExtrusionPatternShader,
gfx::Backend::Type::Metal>::uniforms = {
UniformBlockInfo{6, true, true, sizeof(FillExtrusionDrawableUBO), "FillExtrusionDrawableUBO"},
UniformBlockInfo{7, true, true, sizeof(FillExtrusionDrawablePropsUBO), "FillExtrusionDrawablePropsUBO"},
UniformBlockInfo{8, true, false, sizeof(FillExtrusionDrawableTilePropsUBO), "FillExtrusionDrawableTilePropsUBO"},
UniformBlockInfo{9, true, false, sizeof(FillExtrusionInterpolateUBO), "FillExtrusionInterpolateUBO"},
UniformBlockInfo{10, true, true, sizeof(FillExtrusionPermutationUBO), "FillExtrusionPermutationUBO"},
UniformBlockInfo{11, true, false, sizeof(ExpressionInputsUBO), "ExpressionInputsUBO"},
const std::array<UniformBlockInfo, 4>
ShaderSource<BuiltIn::FillExtrusionPatternShader, gfx::Backend::Type::Metal>::uniforms = {
UniformBlockInfo{6, true, true, sizeof(FillExtrusionDrawableUBO), "FillExtrusionDrawableUBO"},
UniformBlockInfo{7, true, true, sizeof(FillExtrusionDrawablePropsUBO), "FillExtrusionDrawablePropsUBO"},
UniformBlockInfo{8, true, true, sizeof(FillExtrusionDrawableTilePropsUBO), "FillExtrusionDrawableTilePropsUBO"},
UniformBlockInfo{9, true, false, sizeof(FillExtrusionInterpolateUBO), "FillExtrusionInterpolateUBO"},
};
const std::array<TextureInfo, 1>
ShaderSource<BuiltIn::FillExtrusionPatternShader, gfx::Backend::Type::Metal>::textures = {

View File

@@ -8,12 +8,10 @@ const std::array<AttributeInfo, 3> ShaderSource<BuiltIn::HeatmapShader, gfx::Bac
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 = {
const std::array<UniformBlockInfo, 3> 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 = {};

View File

@@ -13,12 +13,10 @@ const std::array<AttributeInfo, 8> ShaderSource<BuiltIn::LineShader, gfx::Backen
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 = {
const std::array<UniformBlockInfo, 3> ShaderSource<BuiltIn::LineShader, gfx::Backend::Type::Metal>::uniforms = {
UniformBlockInfo{8, true, true, sizeof(LineUBO), "LineUBO"},
UniformBlockInfo{9, true, true, 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 = {};
@@ -33,13 +31,11 @@ const std::array<AttributeInfo, 9> ShaderSource<BuiltIn::LinePatternShader, gfx:
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 = {
const std::array<UniformBlockInfo, 4> ShaderSource<BuiltIn::LinePatternShader, gfx::Backend::Type::Metal>::uniforms = {
UniformBlockInfo{9, true, true, sizeof(LinePatternUBO), "LinePatternUBO"},
UniformBlockInfo{10, true, true, sizeof(LinePatternPropertiesUBO), "LinePatternPropertiesUBO"},
UniformBlockInfo{11, true, false, sizeof(LinePatternInterpolationUBO), "LinePatternInterpolationUBO"},
UniformBlockInfo{12, true, true, 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"},
@@ -56,12 +52,10 @@ const std::array<AttributeInfo, 9> ShaderSource<BuiltIn::LineSDFShader, gfx::Bac
AttributeInfo{7, gfx::AttributeDataType::Float2, 1, "a_width"},
AttributeInfo{8, gfx::AttributeDataType::Float2, 1, "a_floorwidth"},
};
const std::array<UniformBlockInfo, 5> ShaderSource<BuiltIn::LineSDFShader, gfx::Backend::Type::Metal>::uniforms = {
const std::array<UniformBlockInfo, 3> ShaderSource<BuiltIn::LineSDFShader, gfx::Backend::Type::Metal>::uniforms = {
UniformBlockInfo{9, true, true, sizeof(LineSDFUBO), "LineSDFUBO"},
UniformBlockInfo{10, true, true, sizeof(LineSDFPropertiesUBO), "LineSDFPropertiesUBO"},
UniformBlockInfo{11, true, false, sizeof(LineSDFInterpolationUBO), "LineSDFInterpolationUBO"},
UniformBlockInfo{12, true, true, sizeof(LinePermutationUBO), "LinePermutationUBO"},
UniformBlockInfo{13, true, false, sizeof(ExpressionInputsUBO), "ExpressionInputsUBO"},
};
const std::array<TextureInfo, 1> ShaderSource<BuiltIn::LineSDFShader, gfx::Backend::Type::Metal>::textures = {
TextureInfo{0, "u_image"},

View File

@@ -12,12 +12,10 @@ const std::array<AttributeInfo, 7> ShaderSource<BuiltIn::LineGradientShader, gfx
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 = {
const std::array<UniformBlockInfo, 3> ShaderSource<BuiltIn::LineGradientShader, gfx::Backend::Type::Metal>::uniforms = {
UniformBlockInfo{7, true, true, sizeof(LineGradientUBO), "LineGradientUBO"},
UniformBlockInfo{8, true, false, sizeof(LineGradientPropertiesUBO), "LineGradientPropertiesUBO"},
UniformBlockInfo{8, true, true, 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"},

View File

@@ -14,14 +14,12 @@ const std::array<AttributeInfo, 6> ShaderSource<BuiltIn::SymbolIconShader, gfx::
// sometimes uniforms
AttributeInfo{5, gfx::AttributeDataType::Float, 1, "a_opacity"},
};
const std::array<UniformBlockInfo, 7> ShaderSource<BuiltIn::SymbolIconShader, gfx::Backend::Type::Metal>::uniforms = {
const std::array<UniformBlockInfo, 5> ShaderSource<BuiltIn::SymbolIconShader, gfx::Backend::Type::Metal>::uniforms = {
UniformBlockInfo{8, true, true, sizeof(SymbolDrawableUBO), "SymbolDrawableUBO"},
UniformBlockInfo{9, true, false, sizeof(SymbolDynamicUBO), "SymbolDynamicUBO"},
UniformBlockInfo{10, true, true, sizeof(SymbolDrawablePaintUBO), "SymbolDrawablePaintUBO"},
UniformBlockInfo{11, true, false, 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, 1> ShaderSource<BuiltIn::SymbolIconShader, gfx::Backend::Type::Metal>::textures = {
TextureInfo{0, "u_texture"},

View File

@@ -19,15 +19,13 @@ const std::array<AttributeInfo, 10> ShaderSource<BuiltIn::SymbolSDFIconShader, g
AttributeInfo{8, gfx::AttributeDataType::Float, 1, "a_halo_width"},
AttributeInfo{9, gfx::AttributeDataType::Float, 1, "a_halo_blur"},
};
const std::array<UniformBlockInfo, 7> ShaderSource<BuiltIn::SymbolSDFIconShader, gfx::Backend::Type::Metal>::uniforms =
const std::array<UniformBlockInfo, 5> ShaderSource<BuiltIn::SymbolSDFIconShader, gfx::Backend::Type::Metal>::uniforms =
{
UniformBlockInfo{10, true, true, sizeof(SymbolDrawableUBO), "SymbolDrawableUBO"},
UniformBlockInfo{11, true, true, sizeof(SymbolDynamicUBO), "SymbolDynamicUBO"},
UniformBlockInfo{12, true, true, sizeof(SymbolDrawablePaintUBO), "SymbolDrawablePaintUBO"},
UniformBlockInfo{13, true, true, sizeof(SymbolDrawableTilePropsUBO), "SymbolDrawableTilePropsUBO"},
UniformBlockInfo{14, true, false, sizeof(SymbolDrawableInterpolateUBO), "SymbolDrawableInterpolateUBO"},
UniformBlockInfo{15, true, true, sizeof(SymbolPermutationUBO), "SymbolPermutationUBO"},
UniformBlockInfo{16, true, false, sizeof(ExpressionInputsUBO), "ExpressionInputsUBO"},
};
const std::array<TextureInfo, 1> ShaderSource<BuiltIn::SymbolSDFIconShader, gfx::Backend::Type::Metal>::textures = {
TextureInfo{0, "u_texture"},

View File

@@ -18,15 +18,13 @@ const std::array<AttributeInfo, 9>
AttributeInfo{7, gfx::AttributeDataType::Float, 1, "a_halo_width"},
AttributeInfo{8, gfx::AttributeDataType::Float, 1, "a_halo_blur"},
};
const std::array<UniformBlockInfo, 7>
const std::array<UniformBlockInfo, 5>
ShaderSource<BuiltIn::SymbolTextAndIconShader, gfx::Backend::Type::Metal>::uniforms = {
UniformBlockInfo{9, true, true, sizeof(SymbolDrawableUBO), "SymbolDrawableUBO"},
UniformBlockInfo{10, true, true, sizeof(SymbolDynamicUBO), "SymbolDynamicUBO"},
UniformBlockInfo{11, true, true, 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, 2> ShaderSource<BuiltIn::SymbolTextAndIconShader, gfx::Backend::Type::Metal>::textures = {
TextureInfo{0, "u_texture"},

View File

@@ -119,30 +119,6 @@ public:
uniforms.createOrUpdate(idLineUBOName, &lineUBO, parameters.context);
uniforms.createOrUpdate(idLinePropertiesUBOName, &linePropertiesUBO, parameters.context);
uniforms.createOrUpdate(idLineInterpolationUBOName, &lineInterpolationUBO, parameters.context);
#if MLN_RENDER_BACKEND_METAL
static const StringIdentity idExpressionInputsUBOName = stringIndexer().get("ExpressionInputsUBO");
const auto expressionUBO = LayerTweaker::buildExpressionUBO(zoom, parameters.frameCount);
uniforms.createOrUpdate(idExpressionInputsUBOName, &expressionUBO, parameters.context);
static const StringIdentity idLinePermutationUBOName = stringIndexer().get("LinePermutationUBO");
const shaders::LinePermutationUBO permutationUBO = {
/* .color = */ {/*.source=*/shaders::AttributeSource::Constant, /*.expression=*/{}},
/* .blur = */ {/*.source=*/shaders::AttributeSource::Constant, /*.expression=*/{}},
/* .opacity = */ {/*.source=*/shaders::AttributeSource::Constant, /*.expression=*/{}},
/* .gapwidth = */ {/*.source=*/shaders::AttributeSource::Constant, /*.expression=*/{}},
/* .offset = */ {/*.source=*/shaders::AttributeSource::Constant, /*.expression=*/{}},
/* .width = */ {/*.source=*/shaders::AttributeSource::Constant, /*.expression=*/{}},
/* .floorwidth = */ {/*.source=*/shaders::AttributeSource::Constant, /*.expression=*/{}},
/* .pattern_from = */ {/*.source=*/shaders::AttributeSource::Constant, /*.expression=*/{}},
/* .pattern_to = */ {/*.source=*/shaders::AttributeSource::Constant, /*.expression=*/{}},
/* .overdrawInspector = */ false,
/* .pad = */ 0,
0,
0,
0};
uniforms.createOrUpdate(idLinePermutationUBOName, &permutationUBO, parameters.context);
#endif // MLN_RENDER_BACKEND_METAL
};
private:
@@ -193,27 +169,6 @@ public:
uniforms.createOrUpdate(idFillDrawableUBOName, &fillUBO, parameters.context);
uniforms.createOrUpdate(idFillEvaluatedPropsUBOName, &fillPropertiesUBO, parameters.context);
uniforms.createOrUpdate(idFillInterpolateUBOName, &fillInterpolateUBO, parameters.context);
#if MLN_RENDER_BACKEND_METAL
const auto zoom = parameters.state.getZoom();
static const StringIdentity idExpressionInputsUBOName = stringIndexer().get("ExpressionInputsUBO");
const auto expressionUBO = LayerTweaker::buildExpressionUBO(zoom, parameters.frameCount);
uniforms.createOrUpdate(idExpressionInputsUBOName, &expressionUBO, parameters.context);
static const StringIdentity idFillPermutationUBOName = stringIndexer().get("FillPermutationUBO");
const shaders::FillPermutationUBO permutationUBO = {
/* .color = */ {/*.source=*/shaders::AttributeSource::Constant, /*.expression=*/{}},
/* .opacity = */ {/*.source=*/shaders::AttributeSource::Constant, /*.expression=*/{}},
/* .overdrawInspector = */ false,
0,
0,
0,
0,
0,
0,
};
uniforms.createOrUpdate(idFillPermutationUBOName, &permutationUBO, parameters.context);
#endif // MLN_RENDER_BACKEND_METAL
};
private: