GPU Expressions (#2202)
This commit is contained in:
6
.github/workflows/linux-ci.yml
vendored
6
.github/workflows/linux-ci.yml
vendored
@@ -154,12 +154,12 @@ jobs:
|
||||
run: xvfb-run -a build/mbgl-render-test-runner --manifestPath=metrics/linux-${{ matrix.renderer }}.json
|
||||
|
||||
- name: Upload render test result
|
||||
if: always() && steps.render_test.outcome == 'failure' && matrix.renderer == 'drawable'
|
||||
if: always() && steps.render_test.outcome == 'failure'
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: render-test-result
|
||||
name: render-test-result-${{ matrix.renderer }}
|
||||
path: |
|
||||
metrics/linux-drawable.html
|
||||
metrics/linux-${{ matrix.renderer }}.html
|
||||
|
||||
# expression tests
|
||||
|
||||
|
||||
@@ -149,6 +149,7 @@ if(MLN_DRAWABLE_RENDERER)
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/gfx/drawable_tweaker.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/gfx/drawable_atlases_tweaker.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/gfx/drawable_custom_layer_host_tweaker.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/gfx/gpu_expression.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/gfx/uniform_block.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/gfx/uniform_buffer.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/gfx/vertex_attribute.hpp
|
||||
@@ -177,6 +178,7 @@ if(MLN_DRAWABLE_RENDERER)
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gfx/drawable_builder_impl.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gfx/drawable_atlases_tweaker.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gfx/drawable_custom_layer_host_tweaker.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gfx/gpu_expression.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gfx/hillshade_prepare_drawable_data.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gfx/image_drawable_data.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gfx/line_drawable_data.hpp
|
||||
|
||||
@@ -922,6 +922,7 @@ MLN_DRAWABLES_SOURCE = [
|
||||
"src/mbgl/gfx/drawable_builder_impl.cpp",
|
||||
"src/mbgl/gfx/drawable_atlases_tweaker.cpp",
|
||||
"src/mbgl/gfx/drawable_custom_layer_host_tweaker.cpp",
|
||||
"src/mbgl/gfx/gpu_expression.cpp",
|
||||
"src/mbgl/gfx/hillshade_prepare_drawable_data.hpp",
|
||||
"src/mbgl/gfx/image_drawable_data.hpp",
|
||||
"src/mbgl/gfx/line_drawable_data.hpp",
|
||||
@@ -976,6 +977,7 @@ MLN_DRAWABLES_HEADERS = [
|
||||
"include/mbgl/gfx/drawable_tweaker.hpp",
|
||||
"include/mbgl/gfx/drawable_atlases_tweaker.hpp",
|
||||
"include/mbgl/gfx/drawable_custom_layer_host_tweaker.hpp",
|
||||
"include/mbgl/gfx/gpu_expression.hpp",
|
||||
"include/mbgl/gfx/uniform_block.hpp",
|
||||
"include/mbgl/gfx/uniform_buffer.hpp",
|
||||
"include/mbgl/gfx/vertex_attribute.hpp",
|
||||
|
||||
@@ -31,6 +31,9 @@ public:
|
||||
|
||||
static Type GetType() { return Value(DefaultType); }
|
||||
|
||||
static bool getEnableGPUExpressionEval() { return enableGPUExpressionEval; }
|
||||
static void setEnableGPUExpressionEval(bool value) { enableGPUExpressionEval = value; }
|
||||
|
||||
template <typename T, typename... Args>
|
||||
static std::unique_ptr<T> Create(Args... args) {
|
||||
#if MLN_RENDER_BACKEND_METAL
|
||||
@@ -48,6 +51,8 @@ private:
|
||||
static const Type type = value;
|
||||
return type;
|
||||
}
|
||||
|
||||
static bool enableGPUExpressionEval;
|
||||
};
|
||||
|
||||
} // namespace gfx
|
||||
|
||||
108
include/mbgl/gfx/gpu_expression.hpp
Normal file
108
include/mbgl/gfx/gpu_expression.hpp
Normal file
@@ -0,0 +1,108 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/util/color.hpp>
|
||||
#include <mbgl/util/variant.hpp>
|
||||
|
||||
#include <optional>
|
||||
|
||||
#if MLN_DRAWABLE_RENDERER
|
||||
|
||||
namespace mbgl {
|
||||
namespace style {
|
||||
namespace expression {
|
||||
class Expression;
|
||||
class Interpolate;
|
||||
class Step;
|
||||
} // namespace expression
|
||||
using ZoomCurvePtr = variant<std::nullptr_t, const expression::Interpolate*, const expression::Step*>;
|
||||
} // namespace style
|
||||
namespace gfx {
|
||||
|
||||
enum class GPUInterpType : std::uint16_t {
|
||||
Step,
|
||||
Linear,
|
||||
Exponential,
|
||||
Bezier
|
||||
};
|
||||
enum class GPUOutputType : std::uint16_t {
|
||||
Float,
|
||||
Color,
|
||||
};
|
||||
enum class GPUOptions : std::uint16_t {
|
||||
None = 0,
|
||||
IntegerZoom = 1 << 0,
|
||||
Transitioning = 1 << 1,
|
||||
};
|
||||
|
||||
class GPUExpression;
|
||||
using UniqueGPUExpression = std::unique_ptr<GPUExpression>;
|
||||
|
||||
class alignas(16) GPUExpression {
|
||||
public:
|
||||
static constexpr std::size_t maxStops = 16;
|
||||
|
||||
GPUExpression() = delete;
|
||||
GPUExpression(GPUOutputType type, uint16_t count)
|
||||
: outputType(type),
|
||||
stopCount(count) {}
|
||||
GPUExpression(GPUExpression&&) = default;
|
||||
GPUExpression(const GPUExpression&) = default;
|
||||
GPUExpression(const GPUExpression* ptr)
|
||||
: GPUExpression(ptr ? *ptr : empty) {}
|
||||
GPUExpression& operator=(GPUExpression&&) = delete;
|
||||
GPUExpression& operator=(const GPUExpression&) = delete;
|
||||
|
||||
/* 0 */ const GPUOutputType outputType;
|
||||
/* 2 */ const std::uint16_t stopCount;
|
||||
/* 4 */ GPUOptions options;
|
||||
/* 6 */ GPUInterpType interpolation;
|
||||
|
||||
/* 8 */ union InterpOptions {
|
||||
struct Exponential {
|
||||
float base;
|
||||
} exponential;
|
||||
|
||||
struct Bezier {
|
||||
float x1;
|
||||
float y1;
|
||||
float x2;
|
||||
float y2;
|
||||
} bezier;
|
||||
} interpOptions;
|
||||
|
||||
/* 24 */ float inputs[maxStops];
|
||||
|
||||
/* 24 + (4 * maxStops) = 88 */ union Stops {
|
||||
float floats[maxStops];
|
||||
float colors[2 * maxStops];
|
||||
} stops;
|
||||
|
||||
static UniqueGPUExpression create(GPUOutputType, std::uint16_t stopCount);
|
||||
static UniqueGPUExpression create(const style::expression::Expression&, const style::ZoomCurvePtr&, bool intZoom);
|
||||
|
||||
float evaluateFloat(const float zoom) const;
|
||||
Color evaluateColor(const float zoom) const;
|
||||
|
||||
template <typename T>
|
||||
auto evaluate(const float zoom) const;
|
||||
|
||||
Color getColor(std::size_t index) const;
|
||||
|
||||
static const GPUExpression empty;
|
||||
};
|
||||
static_assert(sizeof(GPUExpression) == 32 + (4 + 8) * GPUExpression::maxStops);
|
||||
static_assert(sizeof(GPUExpression) % 16 == 0);
|
||||
|
||||
template <>
|
||||
inline auto GPUExpression::evaluate<Color>(const float zoom) const {
|
||||
return evaluateColor(zoom);
|
||||
}
|
||||
template <>
|
||||
inline auto GPUExpression::evaluate<float>(const float zoom) const {
|
||||
return evaluateFloat(zoom);
|
||||
}
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace mbgl
|
||||
|
||||
#endif
|
||||
@@ -44,7 +44,8 @@ struct alignas(16) GlobalPaintParamsUBO {
|
||||
float symbol_fade_change;
|
||||
float aspect_ratio;
|
||||
float pixel_ratio;
|
||||
float pad1, pad2;
|
||||
float zoom;
|
||||
float pad1;
|
||||
};
|
||||
static_assert(sizeof(GlobalPaintParamsUBO) == 3 * 16);
|
||||
|
||||
|
||||
@@ -1,10 +1,27 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/shaders/layer_ubo.hpp>
|
||||
#include <mbgl/style/property_expression.hpp>
|
||||
#include <mbgl/util/bitmask_operations.hpp>
|
||||
|
||||
#if MLN_DRAWABLE_RENDERER
|
||||
#include <mbgl/gfx/gpu_expression.hpp>
|
||||
#endif // MLN_DRAWABLE_RENDERER
|
||||
|
||||
namespace mbgl {
|
||||
namespace shaders {
|
||||
|
||||
enum class LineExpressionMask : uint32_t {
|
||||
None = 0,
|
||||
Color = 1 << 0,
|
||||
Opacity = 1 << 1,
|
||||
Blur = 1 << 2,
|
||||
Width = 1 << 3,
|
||||
GapWidth = 1 << 4,
|
||||
FloorWidth = 1 << 5,
|
||||
Offset = 1 << 6,
|
||||
};
|
||||
|
||||
//
|
||||
// Line
|
||||
|
||||
@@ -26,6 +43,17 @@ struct alignas(16) LineInterpolationUBO {
|
||||
};
|
||||
static_assert(sizeof(LineInterpolationUBO) % 16 == 0);
|
||||
|
||||
struct alignas(16) LineExpressionUBO {
|
||||
gfx::GPUExpression color;
|
||||
gfx::GPUExpression blur;
|
||||
gfx::GPUExpression opacity;
|
||||
gfx::GPUExpression gapwidth;
|
||||
gfx::GPUExpression offset;
|
||||
gfx::GPUExpression width;
|
||||
gfx::GPUExpression floorWidth;
|
||||
};
|
||||
static_assert(sizeof(LineExpressionUBO) % 16 == 0);
|
||||
|
||||
//
|
||||
// Line gradient
|
||||
|
||||
@@ -110,7 +138,8 @@ struct alignas(16) LineEvaluatedPropsUBO {
|
||||
float offset;
|
||||
float width;
|
||||
float floorwidth;
|
||||
float pad1, pad2;
|
||||
LineExpressionMask expressionMask;
|
||||
float pad1;
|
||||
};
|
||||
static_assert(sizeof(LineEvaluatedPropsUBO) % 16 == 0);
|
||||
|
||||
@@ -119,6 +148,7 @@ enum {
|
||||
idLineInterpolationUBO,
|
||||
idLineTilePropertiesUBO,
|
||||
idLineEvaluatedPropsUBO,
|
||||
idLineExpressionUBO,
|
||||
lineUBOCount
|
||||
};
|
||||
|
||||
|
||||
@@ -54,6 +54,191 @@ float4 unpack_mix_color(const float4 packedColors, const float t) {
|
||||
decode_color(float2(packedColors[2], packedColors[3])), t);
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<class ForwardIt, class T>
|
||||
ForwardIt upper_bound(ForwardIt first, ForwardIt last, thread const T& value)
|
||||
{
|
||||
size_t count = last - first;
|
||||
while (count > 0)
|
||||
{
|
||||
ForwardIt it = first;
|
||||
const size_t step = count / 2;
|
||||
it += step;
|
||||
if (!(value < *it))
|
||||
{
|
||||
first = ++it;
|
||||
count -= step + 1;
|
||||
}
|
||||
else {
|
||||
count = step;
|
||||
}
|
||||
}
|
||||
return first;
|
||||
}
|
||||
|
||||
float interpolationFactor(float base, float rangeMin, float rangeMax, float z) {
|
||||
const float zoomDiff = rangeMax - rangeMin;
|
||||
const float zoomProgress = z - rangeMin;
|
||||
if (zoomDiff == 0) {
|
||||
return 0;
|
||||
} else if (base == 1.0f) {
|
||||
return zoomProgress / zoomDiff;
|
||||
} else {
|
||||
return (pow(base, zoomProgress) - 1) / (pow(base, zoomDiff) - 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
enum class GPUInterpType : uint16_t {
|
||||
Step,
|
||||
Linear,
|
||||
Exponential,
|
||||
Bezier
|
||||
};
|
||||
enum class GPUOutputType : uint16_t {
|
||||
Float,
|
||||
Color,
|
||||
};
|
||||
enum class GPUOptions : uint16_t {
|
||||
None = 0,
|
||||
IntegerZoom = 1 << 0,
|
||||
Transitioning = 1 << 1,
|
||||
};
|
||||
bool operator&(GPUOptions a, GPUOptions b) { return (uint16_t)a & (uint16_t)b; }
|
||||
|
||||
constant const int maxExprStops = 16;
|
||||
struct alignas(16) GPUExpression {
|
||||
GPUOutputType outputType;
|
||||
uint16_t stopCount;
|
||||
GPUOptions options;
|
||||
GPUInterpType interpolation;
|
||||
|
||||
union InterpOptions {
|
||||
struct Exponential {
|
||||
float base;
|
||||
} exponential;
|
||||
|
||||
struct Bezier {
|
||||
float x1;
|
||||
float y1;
|
||||
float x2;
|
||||
float y2;
|
||||
} bezier;
|
||||
} interpOptions;
|
||||
|
||||
float inputs[maxExprStops];
|
||||
|
||||
union Stops {
|
||||
float floats[maxExprStops];
|
||||
float2 colors[maxExprStops];
|
||||
} stops;
|
||||
|
||||
float eval(float zoom) device const {
|
||||
const auto effectiveZoom = (options & GPUOptions::IntegerZoom) ? floor(zoom) : zoom;
|
||||
const auto index = find(effectiveZoom);
|
||||
if (index == 0) {
|
||||
return stops.floats[0];
|
||||
} else if (index == stopCount) {
|
||||
return stops.floats[stopCount - 1];
|
||||
}
|
||||
switch (interpolation) {
|
||||
case GPUInterpType::Step: return stops.floats[index - 1];
|
||||
default: assert(false);
|
||||
[[fallthrough]];
|
||||
case GPUInterpType::Linear: assert(interpOptions.exponential.base == 1.0f);
|
||||
[[fallthrough]];
|
||||
case GPUInterpType::Exponential: {
|
||||
const float rangeBeg = inputs[index - 1];
|
||||
const float rangeEnd = inputs[index];
|
||||
const auto t = interpolationFactor(interpOptions.exponential.base, rangeBeg, rangeEnd, effectiveZoom);
|
||||
return mix(stops.floats[index - 1], stops.floats[index], t);
|
||||
}
|
||||
case GPUInterpType::Bezier:
|
||||
assert(false);
|
||||
return stops.floats[0];
|
||||
}
|
||||
}
|
||||
|
||||
float4 evalColor(float zoom) device const {
|
||||
const auto effectiveZoom = (options & GPUOptions::IntegerZoom) ? floor(zoom) : zoom;
|
||||
const auto index = find(effectiveZoom);
|
||||
if (index == 0) {
|
||||
return getColor(0);
|
||||
} else if (index == stopCount) {
|
||||
return getColor(stopCount - 1);
|
||||
}
|
||||
switch (interpolation) {
|
||||
case GPUInterpType::Step:
|
||||
return getColor(index - 1);
|
||||
default:
|
||||
assert(false);
|
||||
[[fallthrough]];
|
||||
case GPUInterpType::Linear:
|
||||
assert(interpOptions.exponential.base == 1.0f);
|
||||
[[fallthrough]];
|
||||
case GPUInterpType::Exponential: {
|
||||
const float rangeBeg = inputs[index - 1];
|
||||
const float rangeEnd = inputs[index];
|
||||
const auto t = interpolationFactor(interpOptions.exponential.base, rangeBeg, rangeEnd, effectiveZoom);
|
||||
return mix(getColor(index - 1), getColor(index), clamp(t, 0.0, 1.0));
|
||||
}
|
||||
case GPUInterpType::Bezier:
|
||||
assert(false);
|
||||
return getColor(0);
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the index of the entry to use from the zoom level
|
||||
size_t find(float zoom) device const {
|
||||
return upper_bound(&inputs[0], &inputs[stopCount], zoom) - &inputs[0];
|
||||
}
|
||||
|
||||
float4 getColor(size_t index) device const { return decode_color(stops.colors[index]); }
|
||||
};
|
||||
static_assert(sizeof(GPUExpression) == 32 + (4 + 8) * maxExprStops, "wrong alignment");
|
||||
static_assert(sizeof(GPUExpression) % 16 == 0, "wrong alignment");
|
||||
|
||||
|
||||
enum {
|
||||
idGlobalPaintParamsUBO,
|
||||
globalUBOCount
|
||||
};
|
||||
|
||||
enum {
|
||||
idLineDrawableUBO = globalUBOCount,
|
||||
idLineInterpolationUBO,
|
||||
idLineTilePropertiesUBO,
|
||||
idLineEvaluatedPropsUBO,
|
||||
idLineExpressionUBO,
|
||||
lineUBOCount
|
||||
};
|
||||
|
||||
|
||||
enum class LineExpressionMask : uint32_t {
|
||||
None = 0,
|
||||
Color = 1 << 0,
|
||||
Opacity = 1 << 1,
|
||||
Blur = 1 << 2,
|
||||
Width = 1 << 3,
|
||||
GapWidth = 1 << 4,
|
||||
FloorWidth = 1 << 5,
|
||||
Offset = 1 << 6,
|
||||
};
|
||||
bool operator&(LineExpressionMask a, LineExpressionMask b) { return (uint32_t)a & (uint32_t)b; }
|
||||
|
||||
struct alignas(16) LineExpressionUBO {
|
||||
GPUExpression color;
|
||||
GPUExpression blur;
|
||||
GPUExpression opacity;
|
||||
GPUExpression gapwidth;
|
||||
GPUExpression offset;
|
||||
GPUExpression width;
|
||||
GPUExpression floorwidth;
|
||||
};
|
||||
static_assert(sizeof(LineExpressionUBO) % 16 == 0, "wrong alignment");
|
||||
|
||||
|
||||
struct alignas(16) GlobalPaintParamsUBO {
|
||||
/* 0 */ float2 pattern_atlas_texsize;
|
||||
/* 8 */ float2 units_to_pixels;
|
||||
@@ -62,7 +247,8 @@ struct alignas(16) GlobalPaintParamsUBO {
|
||||
/* 28 */ float symbol_fade_change;
|
||||
/* 32 */ float aspect_ratio;
|
||||
/* 36 */ float pixel_ratio;
|
||||
/* 40 */ float pad1, pad2;
|
||||
/* 40 */ float zoom;
|
||||
/* 44 */ float pad1;
|
||||
/* 48 */
|
||||
};
|
||||
static_assert(sizeof(GlobalPaintParamsUBO) == 3 * 16, "unexpected padding");
|
||||
@@ -129,7 +315,8 @@ struct alignas(16) LineEvaluatedPropsUBO {
|
||||
float offset;
|
||||
float width;
|
||||
float floorwidth;
|
||||
float pad1, pad2;
|
||||
LineExpressionMask expressionMask;
|
||||
float pad1;
|
||||
};
|
||||
|
||||
struct alignas(16) SymbolDrawableUBO {
|
||||
|
||||
@@ -14,33 +14,33 @@ struct ShaderSource<BuiltIn::LineShader, gfx::Backend::Type::Metal> {
|
||||
static constexpr auto vertexMainFunction = "vertexMain";
|
||||
static constexpr auto fragmentMainFunction = "fragmentMain";
|
||||
|
||||
static const std::array<UniformBlockInfo, 4> uniforms;
|
||||
static const std::array<UniformBlockInfo, 5> uniforms;
|
||||
static const std::array<AttributeInfo, 8> attributes;
|
||||
static constexpr std::array<AttributeInfo, 0> instanceAttributes{};
|
||||
static const std::array<TextureInfo, 0> textures;
|
||||
|
||||
static constexpr auto source = R"(
|
||||
struct VertexStage {
|
||||
short2 pos_normal [[attribute(5)]];
|
||||
uchar4 data [[attribute(6)]];
|
||||
short2 pos_normal [[attribute(lineUBOCount + 0)]];
|
||||
uchar4 data [[attribute(lineUBOCount + 1)]];
|
||||
|
||||
#if !defined(HAS_UNIFORM_u_color)
|
||||
float4 color [[attribute(7)]];
|
||||
float4 color [[attribute(lineUBOCount + 2)]];
|
||||
#endif
|
||||
#if !defined(HAS_UNIFORM_u_blur)
|
||||
float2 blur [[attribute(8)]];
|
||||
float2 blur [[attribute(lineUBOCount + 3)]];
|
||||
#endif
|
||||
#if !defined(HAS_UNIFORM_u_opacity)
|
||||
float2 opacity [[attribute(9)]];
|
||||
float2 opacity [[attribute(lineUBOCount + 4)]];
|
||||
#endif
|
||||
#if !defined(HAS_UNIFORM_u_gapwidth)
|
||||
float2 gapwidth [[attribute(10)]];
|
||||
float2 gapwidth [[attribute(lineUBOCount + 5)]];
|
||||
#endif
|
||||
#if !defined(HAS_UNIFORM_u_offset)
|
||||
float2 offset [[attribute(11)]];
|
||||
float2 offset [[attribute(lineUBOCount + 6)]];
|
||||
#endif
|
||||
#if !defined(HAS_UNIFORM_u_width)
|
||||
float2 width [[attribute(12)]];
|
||||
float2 width [[attribute(lineUBOCount + 7)]];
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -78,23 +78,29 @@ struct alignas(16) LineInterpolationUBO {
|
||||
};
|
||||
|
||||
FragmentStage vertex vertexMain(thread const VertexStage vertx [[stage_in]],
|
||||
device const GlobalPaintParamsUBO& paintParams [[buffer(0)]],
|
||||
device const LineDrawableUBO& drawable [[buffer(1)]],
|
||||
device const LineInterpolationUBO& interp [[buffer(2)]],
|
||||
device const LineEvaluatedPropsUBO& props [[buffer(4)]]) {
|
||||
device const GlobalPaintParamsUBO& paintParams [[buffer(idGlobalPaintParamsUBO)]],
|
||||
device const LineDrawableUBO& drawable [[buffer(idLineDrawableUBO)]],
|
||||
device const LineInterpolationUBO& interp [[buffer(idLineInterpolationUBO)]],
|
||||
device const LineEvaluatedPropsUBO& props [[buffer(idLineEvaluatedPropsUBO)]],
|
||||
device const LineExpressionUBO& expr [[buffer(idLineExpressionUBO)]]) {
|
||||
|
||||
#if defined(HAS_UNIFORM_u_gapwidth)
|
||||
const auto gapwidth = props.gapwidth / 2;
|
||||
const auto exprGapWidth = (props.expressionMask & LineExpressionMask::GapWidth);
|
||||
const auto gapwidth = (exprGapWidth ? expr.gapwidth.eval(paintParams.zoom) : props.gapwidth) / 2;
|
||||
#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 * -1;
|
||||
const auto exprOffset = (props.expressionMask & LineExpressionMask::Offset);
|
||||
const auto offset = (exprOffset ? expr.offset.eval(paintParams.zoom) : props.offset) * -1;
|
||||
#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;
|
||||
const auto exprWidth = (props.expressionMask & LineExpressionMask::Width);
|
||||
const auto width = exprWidth ? expr.width.eval(paintParams.zoom) : props.width;
|
||||
#else
|
||||
const auto width = unpack_mix_float(vertx.width, interp.width_t);
|
||||
#endif
|
||||
@@ -154,23 +160,30 @@ FragmentStage vertex vertexMain(thread const VertexStage vertx [[stage_in]],
|
||||
}
|
||||
|
||||
half4 fragment fragmentMain(FragmentStage in [[stage_in]],
|
||||
device const LineEvaluatedPropsUBO& props [[buffer(4)]]) {
|
||||
device const GlobalPaintParamsUBO& paintParams [[buffer(idGlobalPaintParamsUBO)]],
|
||||
device const LineEvaluatedPropsUBO& props [[buffer(idLineEvaluatedPropsUBO)]],
|
||||
device const LineExpressionUBO& expr [[buffer(idLineExpressionUBO)]]) {
|
||||
#if defined(OVERDRAW_INSPECTOR)
|
||||
return half4(1.0);
|
||||
#endif
|
||||
|
||||
#if defined(HAS_UNIFORM_u_color)
|
||||
const float4 color = props.color;
|
||||
const auto exprColor = (props.expressionMask & LineExpressionMask::Color);
|
||||
const auto color = exprColor ? expr.color.evalColor(paintParams.zoom) : props.color;
|
||||
#else
|
||||
const float4 color = in.color;
|
||||
#endif
|
||||
|
||||
#if defined(HAS_UNIFORM_u_blur)
|
||||
const float blur = props.blur;
|
||||
const auto exprBlur = (props.expressionMask & LineExpressionMask::Blur);
|
||||
const float blur = exprBlur ? expr.blur.eval(paintParams.zoom) : props.blur;
|
||||
#else
|
||||
const float blur = in.blur;
|
||||
#endif
|
||||
|
||||
#if defined(HAS_UNIFORM_u_opacity)
|
||||
const float opacity = props.opacity;
|
||||
const auto exprOpacity = (props.expressionMask & LineExpressionMask::Opacity);
|
||||
const float opacity = exprOpacity ? expr.opacity.eval(paintParams.zoom) : props.opacity;
|
||||
#else
|
||||
const float opacity = in.opacity;
|
||||
#endif
|
||||
@@ -201,13 +214,23 @@ struct ShaderSource<BuiltIn::LineGradientShader, gfx::Backend::Type::Metal> {
|
||||
|
||||
static constexpr auto source = R"(
|
||||
struct VertexStage {
|
||||
short2 pos_normal [[attribute(5)]];
|
||||
uchar4 data [[attribute(6)]];
|
||||
float2 blur [[attribute(7)]];
|
||||
float2 opacity [[attribute(8)]];
|
||||
float2 gapwidth [[attribute(9)]];
|
||||
float2 offset [[attribute(10)]];
|
||||
float2 width [[attribute(11)]];
|
||||
short2 pos_normal [[attribute(lineUBOCount + 0)]];
|
||||
uchar4 data [[attribute(lineUBOCount + 1)]];
|
||||
#if !defined(HAS_UNIFORM_u_blur)
|
||||
float2 blur [[attribute(lineUBOCount + 2)]];
|
||||
#endif
|
||||
#if !defined(HAS_UNIFORM_u_opacity)
|
||||
float2 opacity [[attribute(lineUBOCount + 3)]];
|
||||
#endif
|
||||
#if !defined(HAS_UNIFORM_u_gapwidth)
|
||||
float2 gapwidth [[attribute(lineUBOCount + 4)]];
|
||||
#endif
|
||||
#if !defined(HAS_UNIFORM_u_offset)
|
||||
float2 offset [[attribute(lineUBOCount + 5)]];
|
||||
#endif
|
||||
#if !defined(HAS_UNIFORM_u_width)
|
||||
float2 width [[attribute(lineUBOCount + 6)]];
|
||||
#endif
|
||||
};
|
||||
|
||||
struct FragmentStage {
|
||||
@@ -241,10 +264,11 @@ struct alignas(16) LineGradientInterpolationUBO {
|
||||
};
|
||||
|
||||
FragmentStage vertex vertexMain(thread const VertexStage vertx [[stage_in]],
|
||||
device const GlobalPaintParamsUBO& paintParams [[buffer(0)]],
|
||||
device const LineGradientDrawableUBO& drawable [[buffer(1)]],
|
||||
device const LineGradientInterpolationUBO& interp [[buffer(2)]],
|
||||
device const LineEvaluatedPropsUBO& props [[buffer(4)]]) {
|
||||
device const GlobalPaintParamsUBO& paintParams [[buffer(idGlobalPaintParamsUBO)]],
|
||||
device const LineGradientDrawableUBO& drawable [[buffer(idLineDrawableUBO)]],
|
||||
device const LineGradientInterpolationUBO& interp [[buffer(idLineInterpolationUBO)]],
|
||||
device const LineEvaluatedPropsUBO& props [[buffer(idLineEvaluatedPropsUBO)]],
|
||||
device const LineExpressionUBO& expr [[buffer(idLineExpressionUBO)]]) {
|
||||
|
||||
#if !defined(HAS_UNIFORM_u_blur)
|
||||
const auto blur = unpack_mix_float(vertx.blur, interp.blur_t);
|
||||
@@ -253,12 +277,12 @@ FragmentStage vertex vertexMain(thread const VertexStage vertx [[stage_in]],
|
||||
const auto opacity = unpack_mix_float(vertx.opacity, interp.opacity_t);
|
||||
#endif
|
||||
#if defined(HAS_UNIFORM_u_gapwidth)
|
||||
const auto gapwidth = props.gapwidth;
|
||||
const auto gapwidth = props.gapwidth / 2;
|
||||
#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;
|
||||
const auto offset = props.offset * -1;
|
||||
#else
|
||||
const auto offset = unpack_mix_float(vertx.offset, interp.offset_t) * -1;
|
||||
#endif
|
||||
@@ -322,7 +346,8 @@ FragmentStage vertex vertexMain(thread const VertexStage vertx [[stage_in]],
|
||||
}
|
||||
|
||||
half4 fragment fragmentMain(FragmentStage in [[stage_in]],
|
||||
device const LineEvaluatedPropsUBO& props [[buffer(4)]],
|
||||
device const LineEvaluatedPropsUBO& props [[buffer(idLineEvaluatedPropsUBO)]],
|
||||
device const LineExpressionUBO& expr [[buffer(idLineExpressionUBO)]],
|
||||
texture2d<float, access::sample> gradientTexture [[texture(0)]]) {
|
||||
#if defined(OVERDRAW_INSPECTOR)
|
||||
return half4(1.0);
|
||||
@@ -363,36 +388,36 @@ struct ShaderSource<BuiltIn::LinePatternShader, gfx::Backend::Type::Metal> {
|
||||
static constexpr auto vertexMainFunction = "vertexMain";
|
||||
static constexpr auto fragmentMainFunction = "fragmentMain";
|
||||
|
||||
static const std::array<UniformBlockInfo, 5> uniforms;
|
||||
static const std::array<UniformBlockInfo, 6> uniforms;
|
||||
static const std::array<AttributeInfo, 9> attributes;
|
||||
static constexpr std::array<AttributeInfo, 0> instanceAttributes{};
|
||||
static const std::array<TextureInfo, 1> textures;
|
||||
|
||||
static constexpr auto source = R"(
|
||||
struct VertexStage {
|
||||
short2 pos_normal [[attribute(5)]];
|
||||
uchar4 data [[attribute(6)]];
|
||||
short2 pos_normal [[attribute(lineUBOCount + 0)]];
|
||||
uchar4 data [[attribute(lineUBOCount + 1)]];
|
||||
|
||||
#if !defined(HAS_UNIFORM_u_blur)
|
||||
float2 blur [[attribute(7)]];
|
||||
float2 blur [[attribute(lineUBOCount + 2)]];
|
||||
#endif
|
||||
#if !defined(HAS_UNIFORM_u_opacity)
|
||||
float2 opacity [[attribute(8)]];
|
||||
float2 opacity [[attribute(lineUBOCount + 3)]];
|
||||
#endif
|
||||
#if !defined(HAS_UNIFORM_u_gapwidth)
|
||||
float2 gapwidth [[attribute(9)]];
|
||||
float2 gapwidth [[attribute(lineUBOCount + 4)]];
|
||||
#endif
|
||||
#if !defined(HAS_UNIFORM_u_offset)
|
||||
float2 offset [[attribute(10)]];
|
||||
float2 offset [[attribute(lineUBOCount + 5)]];
|
||||
#endif
|
||||
#if !defined(HAS_UNIFORM_u_width)
|
||||
float2 width [[attribute(11)]];
|
||||
float2 width [[attribute(lineUBOCount + 6)]];
|
||||
#endif
|
||||
#if !defined(HAS_UNIFORM_u_pattern_from)
|
||||
ushort4 pattern_from [[attribute(12)]];
|
||||
ushort4 pattern_from [[attribute(lineUBOCount + 7)]];
|
||||
#endif
|
||||
#if !defined(HAS_UNIFORM_u_pattern_to)
|
||||
ushort4 pattern_to [[attribute(13)]];
|
||||
ushort4 pattern_to [[attribute(lineUBOCount + 8)]];
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -442,26 +467,32 @@ struct alignas(16) LinePatternTilePropertiesUBO {
|
||||
};
|
||||
|
||||
FragmentStage vertex vertexMain(thread const VertexStage vertx [[stage_in]],
|
||||
device const GlobalPaintParamsUBO& paintParams [[buffer(0)]],
|
||||
device const LinePatternDrawableUBO& drawable [[buffer(1)]],
|
||||
device const LinePatternInterpolationUBO& interp [[buffer(2)]],
|
||||
device const LinePatternTilePropertiesUBO& tileProps [[buffer(3)]],
|
||||
device const LineEvaluatedPropsUBO& props [[buffer(4)]]) {
|
||||
device const GlobalPaintParamsUBO& paintParams [[buffer(idGlobalPaintParamsUBO)]],
|
||||
device const LinePatternDrawableUBO& drawable [[buffer(idLineDrawableUBO)]],
|
||||
device const LinePatternInterpolationUBO& interp [[buffer(idLineInterpolationUBO)]],
|
||||
device const LinePatternTilePropertiesUBO& tileProps [[buffer(idLineTilePropertiesUBO)]],
|
||||
device const LineEvaluatedPropsUBO& props [[buffer(idLineEvaluatedPropsUBO)]],
|
||||
device const LineExpressionUBO& expr [[buffer(idLineExpressionUBO)]]) {
|
||||
|
||||
#if defined(HAS_UNIFORM_u_gapwidth)
|
||||
const auto gapwidth = props.gapwidth / 2;
|
||||
const auto exprGapWidth = (props.expressionMask & LineExpressionMask::GapWidth);
|
||||
const auto gapwidth = (exprGapWidth ? expr.gapwidth.eval(paintParams.zoom) : props.gapwidth) / 2;
|
||||
#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 * -1;
|
||||
const auto exprOffset = (props.expressionMask & LineExpressionMask::Offset);
|
||||
const auto offset = (exprOffset ? expr.offset.eval(paintParams.zoom) : props.offset) * -1;
|
||||
#else
|
||||
const auto offset = unpack_mix_float(vertx.offset, interp.offset_t) * -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;
|
||||
const auto exprWidth = (props.expressionMask & LineExpressionMask::Width);
|
||||
const auto width = exprWidth ? expr.width.eval(paintParams.zoom) : props.width;
|
||||
#else
|
||||
const auto width = unpack_mix_float(vertx.width, interp.width_t);
|
||||
const auto width = unpack_mix_float(vertx.width, interp.width_t);
|
||||
#endif
|
||||
|
||||
// the distance over which the line edge fades out.
|
||||
@@ -525,9 +556,11 @@ FragmentStage vertex vertexMain(thread const VertexStage vertx [[stage_in]],
|
||||
}
|
||||
|
||||
half4 fragment fragmentMain(FragmentStage in [[stage_in]],
|
||||
device const LinePatternDrawableUBO& drawable [[buffer(1)]],
|
||||
device const LinePatternTilePropertiesUBO& tileProps [[buffer(3)]],
|
||||
device const LineEvaluatedPropsUBO& props [[buffer(4)]],
|
||||
device const GlobalPaintParamsUBO& paintParams [[buffer(idGlobalPaintParamsUBO)]],
|
||||
device const LinePatternDrawableUBO& drawable [[buffer(idLineDrawableUBO)]],
|
||||
device const LinePatternTilePropertiesUBO& tileProps [[buffer(idLineTilePropertiesUBO)]],
|
||||
device const LineEvaluatedPropsUBO& props [[buffer(idLineEvaluatedPropsUBO)]],
|
||||
device const LineExpressionUBO& expr [[buffer(idLineExpressionUBO)]],
|
||||
texture2d<float, access::sample> image0 [[texture(0)]],
|
||||
sampler image0_sampler [[sampler(0)]]) {
|
||||
#if defined(OVERDRAW_INSPECTOR)
|
||||
@@ -535,20 +568,25 @@ half4 fragment fragmentMain(FragmentStage in [[stage_in]],
|
||||
#endif
|
||||
|
||||
#if defined(HAS_UNIFORM_u_blur)
|
||||
const half blur = props.blur;
|
||||
const auto exprBlur = (props.expressionMask & LineExpressionMask::Blur);
|
||||
const float blur = exprBlur ? expr.blur.eval(paintParams.zoom) : 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 auto exprOpacity = (props.expressionMask & LineExpressionMask::Opacity);
|
||||
const float opacity = exprOpacity ? expr.opacity.eval(paintParams.zoom) : props.opacity;
|
||||
#else
|
||||
const half opacity = in.opacity;
|
||||
const float opacity = in.opacity;
|
||||
#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
|
||||
@@ -606,36 +644,36 @@ struct ShaderSource<BuiltIn::LineSDFShader, gfx::Backend::Type::Metal> {
|
||||
static constexpr auto vertexMainFunction = "vertexMain";
|
||||
static constexpr auto fragmentMainFunction = "fragmentMain";
|
||||
|
||||
static const std::array<UniformBlockInfo, 4> uniforms;
|
||||
static const std::array<UniformBlockInfo, 5> uniforms;
|
||||
static const std::array<AttributeInfo, 9> attributes;
|
||||
static constexpr std::array<AttributeInfo, 0> instanceAttributes{};
|
||||
static const std::array<TextureInfo, 1> textures;
|
||||
|
||||
static constexpr auto source = R"(
|
||||
struct VertexStage {
|
||||
short2 pos_normal [[attribute(5)]];
|
||||
uchar4 data [[attribute(6)]];
|
||||
short2 pos_normal [[attribute(lineUBOCount + 0)]];
|
||||
uchar4 data [[attribute(lineUBOCount + 1)]];
|
||||
|
||||
#if !defined(HAS_UNIFORM_u_color)
|
||||
float4 color [[attribute(7)]];
|
||||
float4 color [[attribute(lineUBOCount + 2)]];
|
||||
#endif
|
||||
#if !defined(HAS_UNIFORM_u_blur)
|
||||
float2 blur [[attribute(8)]];
|
||||
float2 blur [[attribute(lineUBOCount + 3)]];
|
||||
#endif
|
||||
#if !defined(HAS_UNIFORM_u_opacity)
|
||||
float2 opacity [[attribute(9)]];
|
||||
float2 opacity [[attribute(lineUBOCount + 4)]];
|
||||
#endif
|
||||
#if !defined(HAS_UNIFORM_u_gapwidth)
|
||||
float2 gapwidth [[attribute(10)]];
|
||||
float2 gapwidth [[attribute(lineUBOCount + 5)]];
|
||||
#endif
|
||||
#if !defined(HAS_UNIFORM_u_offset)
|
||||
float2 offset [[attribute(11)]];
|
||||
float2 offset [[attribute(lineUBOCount + 6)]];
|
||||
#endif
|
||||
#if !defined(HAS_UNIFORM_u_width)
|
||||
float2 width [[attribute(12)]];
|
||||
float2 width [[attribute(lineUBOCount + 7)]];
|
||||
#endif
|
||||
#if !defined(HAS_UNIFORM_u_floorwidth)
|
||||
float2 floorwidth [[attribute(13)]];
|
||||
float2 floorwidth [[attribute(lineUBOCount + 8)]];
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -685,28 +723,36 @@ struct alignas(16) LineSDFInterpolationUBO {
|
||||
};
|
||||
|
||||
FragmentStage vertex vertexMain(thread const VertexStage vertx [[stage_in]],
|
||||
device const GlobalPaintParamsUBO& paintParams [[buffer(0)]],
|
||||
device const LineSDFDrawableUBO& drawable [[buffer(1)]],
|
||||
device const LineSDFInterpolationUBO& interp [[buffer(2)]],
|
||||
device const LineEvaluatedPropsUBO& props [[buffer(4)]]) {
|
||||
device const GlobalPaintParamsUBO& paintParams [[buffer(idGlobalPaintParamsUBO)]],
|
||||
device const LineSDFDrawableUBO& drawable [[buffer(idLineDrawableUBO)]],
|
||||
device const LineSDFInterpolationUBO& interp [[buffer(idLineInterpolationUBO)]],
|
||||
device const LineEvaluatedPropsUBO& props [[buffer(idLineEvaluatedPropsUBO)]],
|
||||
device const LineExpressionUBO& expr [[buffer(idLineExpressionUBO)]]) {
|
||||
|
||||
#if defined(HAS_UNIFORM_u_gapwidth)
|
||||
const auto gapwidth = props.gapwidth / 2;
|
||||
const auto exprGapWidth = (props.expressionMask & LineExpressionMask::GapWidth);
|
||||
const auto gapwidth = (exprGapWidth ? expr.gapwidth.eval(paintParams.zoom) : props.gapwidth) / 2;
|
||||
#else
|
||||
const auto gapwidth = unpack_mix_float(vertx.gapwidth, interp.gapwidth_t) / 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;
|
||||
const auto exprOffset = (props.expressionMask & LineExpressionMask::Offset);
|
||||
const auto offset = (exprOffset ? expr.offset.eval(paintParams.zoom) : props.offset) * -1;
|
||||
#else
|
||||
const auto offset = unpack_mix_float(vertx.offset, interp.offset_t) * -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;
|
||||
const auto exprWidth = (props.expressionMask & LineExpressionMask::Width);
|
||||
const auto width = exprWidth ? expr.width.eval(paintParams.zoom) : props.width;
|
||||
#else
|
||||
const auto width = unpack_mix_float(vertx.width, interp.width_t);
|
||||
const auto width = unpack_mix_float(vertx.width, interp.width_t);
|
||||
#endif
|
||||
|
||||
#if defined(HAS_UNIFORM_u_floorwidth)
|
||||
const auto floorwidth = props.floorwidth;
|
||||
const auto exprFloorWidth = (props.expressionMask & LineExpressionMask::FloorWidth);
|
||||
const auto floorwidth = exprFloorWidth ? expr.floorwidth.eval(paintParams.zoom) : props.floorwidth;
|
||||
#else
|
||||
const auto floorwidth = unpack_mix_float(vertx.floorwidth, interp.floorwidth_t);
|
||||
#endif
|
||||
@@ -773,8 +819,10 @@ FragmentStage vertex vertexMain(thread const VertexStage vertx [[stage_in]],
|
||||
}
|
||||
|
||||
half4 fragment fragmentMain(FragmentStage in [[stage_in]],
|
||||
device const LineSDFDrawableUBO& drawable [[buffer(1)]],
|
||||
device const LineEvaluatedPropsUBO& props [[buffer(4)]],
|
||||
device const GlobalPaintParamsUBO& paintParams [[buffer(idGlobalPaintParamsUBO)]],
|
||||
device const LineSDFDrawableUBO& drawable [[buffer(idLineDrawableUBO)]],
|
||||
device const LineEvaluatedPropsUBO& props [[buffer(idLineEvaluatedPropsUBO)]],
|
||||
device const LineExpressionUBO& expr [[buffer(idLineExpressionUBO)]],
|
||||
texture2d<float, access::sample> image0 [[texture(0)]],
|
||||
sampler image0_sampler [[sampler(0)]]) {
|
||||
#if defined(OVERDRAW_INSPECTOR)
|
||||
@@ -782,24 +830,31 @@ half4 fragment fragmentMain(FragmentStage in [[stage_in]],
|
||||
#endif
|
||||
|
||||
#if defined(HAS_UNIFORM_u_color)
|
||||
const float4 color = props.color;
|
||||
const auto exprColor = (props.expressionMask & LineExpressionMask::Color);
|
||||
const auto color = exprColor ? expr.color.evalColor(paintParams.zoom) : props.color;
|
||||
#else
|
||||
const float4 color = in.color;
|
||||
#endif
|
||||
|
||||
#if defined(HAS_UNIFORM_u_blur)
|
||||
const float blur = props.blur;
|
||||
const auto exprBlur = (props.expressionMask & LineExpressionMask::Blur);
|
||||
const float blur = exprBlur ? expr.blur.eval(paintParams.zoom) : props.blur;
|
||||
#else
|
||||
const float blur = in.blur;
|
||||
#endif
|
||||
|
||||
#if defined(HAS_UNIFORM_u_opacity)
|
||||
const float opacity = props.opacity;
|
||||
const auto exprOpacity = (props.expressionMask & LineExpressionMask::Opacity);
|
||||
const float opacity = exprOpacity ? expr.opacity.eval(paintParams.zoom) : props.opacity;
|
||||
#else
|
||||
const float opacity = in.opacity;
|
||||
#endif
|
||||
|
||||
#if defined(HAS_UNIFORM_u_floorwidth)
|
||||
const float floorwidth = props.floorwidth;
|
||||
const auto exprFloorWidth = (props.expressionMask & LineExpressionMask::FloorWidth);
|
||||
const auto floorwidth = exprFloorWidth ? expr.floorwidth.eval(paintParams.zoom) : props.floorwidth;
|
||||
#else
|
||||
const float floorwidth = in.floorwidth;
|
||||
const auto floorwidth = in.floorwidth;
|
||||
#endif
|
||||
|
||||
// Calculate the antialiasing fade factor. This is either when fading in the
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <mbgl/style/expression/type.hpp>
|
||||
#include <mbgl/style/expression/value.hpp>
|
||||
#include <mbgl/tile/tile_id.hpp>
|
||||
#include <mbgl/util/bitmask_operations.hpp>
|
||||
#include <mbgl/util/color.hpp>
|
||||
#include <mbgl/util/traits.hpp>
|
||||
#include <mbgl/util/variant.hpp>
|
||||
@@ -202,17 +203,14 @@ enum class Dependency : uint32_t {
|
||||
Var = 1 << 5, // Use variable binding
|
||||
Override = 1 << 6, // Property override
|
||||
MaskCount = 7,
|
||||
All = (1 << MaskCount) - 1,
|
||||
};
|
||||
inline constexpr static Dependency operator|(Dependency x, Dependency y) noexcept {
|
||||
return Dependency{mbgl::underlying_type(x) | mbgl::underlying_type(y)};
|
||||
}
|
||||
inline constexpr static Dependency operator&(Dependency x, Dependency y) noexcept {
|
||||
return Dependency{mbgl::underlying_type(x) & mbgl::underlying_type(y)};
|
||||
}
|
||||
inline static Dependency& operator|=(Dependency& target, Dependency source) noexcept {
|
||||
target = target | source;
|
||||
return target;
|
||||
}
|
||||
|
||||
class Interpolate;
|
||||
class Step;
|
||||
|
||||
using ZoomCurveOrError = std::optional<variant<const Interpolate*, const Step*, ParsingError>>;
|
||||
using ZoomCurvePtr = variant<std::nullptr_t, const Interpolate*, const Step*>;
|
||||
|
||||
class Expression {
|
||||
public:
|
||||
@@ -264,6 +262,9 @@ public:
|
||||
|
||||
const Dependency dependencies;
|
||||
|
||||
/// Test the expression's dependencies for any of one or more values
|
||||
bool has(Dependency dep) const { return (dependencies & dep); }
|
||||
|
||||
protected:
|
||||
template <typename T>
|
||||
static bool childrenEqual(const T& lhs, const T& rhs) noexcept {
|
||||
|
||||
@@ -11,9 +11,18 @@ namespace mbgl {
|
||||
namespace style {
|
||||
namespace expression {
|
||||
|
||||
std::optional<variant<const Interpolate*, const Step*, ParsingError>> findZoomCurve(const expression::Expression*);
|
||||
using ZoomCurveOrError = std::optional<variant<const Interpolate*, const Step*, ParsingError>>;
|
||||
using ZoomCurvePtr = variant<std::nullptr_t, const Interpolate*, const Step*>;
|
||||
|
||||
variant<std::nullptr_t, const Interpolate*, const Step*> findZoomCurveChecked(const expression::Expression&);
|
||||
/// Find a zoom curve in the expression tree.
|
||||
/// @param expr Expression root
|
||||
/// @return The relevant step or interpolate item, or the error if the expression represents an error
|
||||
ZoomCurveOrError findZoomCurve(const expression::Expression&);
|
||||
|
||||
/// Find a zoom curve in the expression tree.
|
||||
/// @param expr Expression root
|
||||
/// @return The relevant step or interpolate item, or null if the expression represents an error
|
||||
ZoomCurvePtr findZoomCurveChecked(const expression::Expression& expr);
|
||||
|
||||
} // namespace expression
|
||||
} // namespace style
|
||||
|
||||
@@ -34,6 +34,8 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
std::size_t getStopCount() const { return stops.size(); }
|
||||
|
||||
void eachStop(const std::function<void(double, const Expression&)>& visit) const {
|
||||
for (const auto& stop : stops) {
|
||||
visit(stop.first, *stop.second);
|
||||
|
||||
@@ -17,7 +17,8 @@ public:
|
||||
using Bindings = std::map<std::string, std::shared_ptr<Expression>>;
|
||||
|
||||
Let(Bindings bindings_, std::unique_ptr<Expression> result_)
|
||||
: Expression(Kind::Let, result_->getType(), collectDependencies(bindings_) | Dependency::Bind),
|
||||
: Expression(
|
||||
Kind::Let, result_->getType(), collectDependencies(bindings_) | depsOf(result_) | Dependency::Bind),
|
||||
bindings(std::move(bindings_)),
|
||||
result(std::move(result_)) {}
|
||||
|
||||
|
||||
@@ -20,6 +20,8 @@ public:
|
||||
|
||||
EvaluationResult evaluate(const EvaluationContext& params) const override;
|
||||
void eachChild(const std::function<void(const Expression&)>& visit) const override;
|
||||
|
||||
std::size_t getStopCount() const { return stops.size(); }
|
||||
void eachStop(const std::function<void(double, const Expression&)>& visit) const;
|
||||
|
||||
const std::unique_ptr<Expression>& getInput() const noexcept { return input; }
|
||||
|
||||
@@ -5,45 +5,75 @@
|
||||
#include <mbgl/style/expression/interpolate.hpp>
|
||||
#include <mbgl/style/expression/step.hpp>
|
||||
#include <mbgl/style/expression/find_zoom_curve.hpp>
|
||||
#include <mbgl/util/bitmask_operations.hpp>
|
||||
#include <mbgl/util/range.hpp>
|
||||
|
||||
#if MLN_DRAWABLE_RENDERER
|
||||
#include <mbgl/gfx/gpu_expression.hpp>
|
||||
#endif // MLN_DRAWABLE_RENDERER
|
||||
|
||||
#include <optional>
|
||||
|
||||
namespace mbgl {
|
||||
namespace gfx {
|
||||
class GPUExpression;
|
||||
using UniqueGPUExpression = std::unique_ptr<GPUExpression>;
|
||||
} // namespace gfx
|
||||
|
||||
namespace style {
|
||||
|
||||
class PropertyExpressionBase {
|
||||
public:
|
||||
explicit PropertyExpressionBase(std::unique_ptr<expression::Expression>) noexcept;
|
||||
using Expression = expression::Expression;
|
||||
using Dependency = expression::Dependency;
|
||||
using ZoomCurvePtr = expression::ZoomCurvePtr;
|
||||
|
||||
PropertyExpressionBase(PropertyExpressionBase&&);
|
||||
PropertyExpressionBase(const PropertyExpressionBase&);
|
||||
explicit PropertyExpressionBase(std::unique_ptr<Expression>);
|
||||
virtual ~PropertyExpressionBase() = default;
|
||||
|
||||
PropertyExpressionBase& operator=(PropertyExpressionBase&&);
|
||||
PropertyExpressionBase& operator=(const PropertyExpressionBase&);
|
||||
|
||||
bool isZoomConstant() const noexcept { return isZoomConstant_; }
|
||||
bool isFeatureConstant() const noexcept { return isFeatureConstant_; }
|
||||
bool isRuntimeConstant() const noexcept { return isRuntimeConstant_; }
|
||||
float interpolationFactor(const Range<float>&, float) const noexcept;
|
||||
Range<float> getCoveringStops(float, float) const noexcept;
|
||||
const expression::Expression& getExpression() const noexcept;
|
||||
const Expression& getExpression() const noexcept;
|
||||
|
||||
/// Can be used for aggregating property expressions from multiple
|
||||
/// properties(layers) into single match / case expression. Method may
|
||||
/// be removed if a better way of aggregation is found.
|
||||
std::shared_ptr<const expression::Expression> getSharedExpression() const noexcept;
|
||||
bool isGPUCapable() const { return isGPUCapable_; }
|
||||
|
||||
bool useIntegerZoom = false;
|
||||
bool getUseIntegerZoom() const { return useIntegerZoom_; }
|
||||
void setUseIntegerZoom(bool value) { useIntegerZoom_ = value; }
|
||||
|
||||
using Dependency = expression::Dependency;
|
||||
Dependency getDependencies() const noexcept {
|
||||
auto v = expression ? expression->dependencies : Dependency::None;
|
||||
assert(isZoomConstant_ == !(underlying_type(v) & underlying_type(Dependency::Zoom)));
|
||||
assert(isFeatureConstant_ == !(underlying_type(v) & underlying_type(Dependency::Feature)));
|
||||
return v;
|
||||
}
|
||||
/// Can be used for aggregating property expressions from multiple properties(layers) into single match / case
|
||||
/// expression. May be removed if a better way of aggregation is found.
|
||||
std::shared_ptr<const Expression> getSharedExpression() const noexcept;
|
||||
|
||||
#if MLN_DRAWABLE_RENDERER
|
||||
/// Build a cached GPU representation of the expression, with the same lifetime as this object.
|
||||
gfx::UniqueGPUExpression getGPUExpression(bool intZoom) const;
|
||||
#endif // MLN_DRAWABLE_RENDERER
|
||||
|
||||
Dependency getDependencies() const noexcept { return expression ? expression->dependencies : Dependency::None; }
|
||||
|
||||
const ZoomCurvePtr& getZoomCurve() const { return zoomCurve; }
|
||||
|
||||
protected:
|
||||
std::shared_ptr<const expression::Expression> expression;
|
||||
std::shared_ptr<const Expression> expression;
|
||||
|
||||
ZoomCurvePtr zoomCurve;
|
||||
|
||||
bool useIntegerZoom_ = false;
|
||||
bool isZoomConstant_;
|
||||
bool isFeatureConstant_;
|
||||
bool isRuntimeConstant_;
|
||||
variant<std::nullptr_t, const expression::Interpolate*, const expression::Step*> zoomCurve;
|
||||
|
||||
// If the expression depends on zoom and nothing else, and produces
|
||||
// a number or color, we can potentially evaluate it on the GPU
|
||||
bool isGPUCapable_;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
@@ -52,8 +82,7 @@ class PropertyExpression final : public PropertyExpressionBase {
|
||||
|
||||
public:
|
||||
// Second parameter to be used only for conversions from legacy functions.
|
||||
PropertyExpression(std::unique_ptr<expression::Expression> expression_,
|
||||
std::optional<T> defaultValue_ = std::nullopt) noexcept
|
||||
PropertyExpression(std::unique_ptr<Expression> expression_, std::optional<T> defaultValue_ = std::nullopt)
|
||||
: PropertyExpressionBase(std::move(expression_)),
|
||||
defaultValue(std::move(defaultValue_)) {}
|
||||
|
||||
|
||||
@@ -49,6 +49,7 @@ public:
|
||||
|
||||
const T& asConstant() const noexcept { return value.template get<T>(); }
|
||||
|
||||
PropertyExpression<T>& asExpression() noexcept { return value.template get<PropertyExpression<T>>(); }
|
||||
const PropertyExpression<T>& asExpression() const noexcept { return value.template get<PropertyExpression<T>>(); }
|
||||
|
||||
template <class... Ts>
|
||||
|
||||
@@ -27,6 +27,8 @@ public:
|
||||
assert(a_ >= 0.0f);
|
||||
assert(a_ <= 1.0f);
|
||||
}
|
||||
Color(const float rgba[4])
|
||||
: Color(rgba[0], rgba[1], rgba[2], rgba[3]) {}
|
||||
|
||||
float r = 0.0f;
|
||||
float g = 0.0f;
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <cstddef>
|
||||
#include <tuple>
|
||||
#include <type_traits>
|
||||
|
||||
namespace mbgl {
|
||||
@@ -24,5 +25,12 @@ constexpr std::array<To, Size> cast(const std::array<From, Size>& from) {
|
||||
return to;
|
||||
}
|
||||
|
||||
/// Convert an `N`-tuple of all `T`s to `array<T,N>`
|
||||
template <typename... Ts>
|
||||
inline constexpr auto to_array(std::tuple<Ts...>&& tuple) {
|
||||
return std::apply([](auto&&... x) { return std::array{std::forward<decltype(x)>(x)...}; },
|
||||
std::forward<std::tuple<Ts...>>(tuple));
|
||||
}
|
||||
|
||||
} // namespace util
|
||||
} // namespace mbgl
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/util/traits.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <string>
|
||||
|
||||
@@ -30,31 +30,36 @@ public:
|
||||
static_assert(sizeof...(Is) == sizeof...(Ts), "IndexedTuple size mismatch");
|
||||
|
||||
template <class I>
|
||||
auto& get() {
|
||||
return std::get<TypeIndex<I, Is...>::value>(*this);
|
||||
static constexpr std::size_t getIndex() {
|
||||
return TypeIndex<I, Is...>::value;
|
||||
}
|
||||
|
||||
template <class I>
|
||||
const auto& get() const {
|
||||
return std::get<TypeIndex<I, Is...>::value>(*this);
|
||||
constexpr auto& get() {
|
||||
return std::get<getIndex<I>()>(*this);
|
||||
}
|
||||
|
||||
template <class I>
|
||||
constexpr const auto& get() const {
|
||||
return std::get<getIndex<I>()>(*this);
|
||||
}
|
||||
|
||||
template <class... Us>
|
||||
IndexedTuple(Us&&... other)
|
||||
constexpr IndexedTuple(Us&&... other)
|
||||
: std::tuple<Ts...>(std::forward<Us>(other)...) {}
|
||||
|
||||
template <class... Js, class... Us>
|
||||
IndexedTuple<TypeList<Is..., Js...>, TypeList<Ts..., Us...>> concat(
|
||||
constexpr IndexedTuple<TypeList<Is..., Js...>, TypeList<Ts..., Us...>> concat(
|
||||
const IndexedTuple<TypeList<Js...>, TypeList<Us...>>& other) const {
|
||||
return IndexedTuple<TypeList<Is..., Js...>, TypeList<Ts..., Us...>>{get<Is>()..., other.template get<Js>()...};
|
||||
}
|
||||
|
||||
// Help out MSVC++
|
||||
bool operator==(const IndexedTuple<TypeList<Is...>, TypeList<Ts...>>& other) const {
|
||||
constexpr bool operator==(const IndexedTuple<TypeList<Is...>, TypeList<Ts...>>& other) const {
|
||||
return static_cast<const std::tuple<Ts...>&>(*this) == static_cast<const std::tuple<Ts...>&>(other);
|
||||
}
|
||||
|
||||
bool operator!=(const IndexedTuple<TypeList<Is...>, TypeList<Ts...>>& other) const noexcept {
|
||||
constexpr bool operator!=(const IndexedTuple<TypeList<Is...>, TypeList<Ts...>>& other) const {
|
||||
return !(*this == other);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -11,10 +11,18 @@ struct SuppressCopies {
|
||||
SuppressCopies(SuppressCopies const&) noexcept {}
|
||||
SuppressCopies(SuppressCopies&& other)
|
||||
: value(std::forward<T>(other.value)) noexcept {}
|
||||
SuppressCopies& operator=(SuppressCopies o) noexcept {
|
||||
SuppressCopies& operator=(T&& o) {
|
||||
value = std::move(o);
|
||||
return *this;
|
||||
}
|
||||
SuppressCopies& operator=(SuppressCopies o) {
|
||||
std::swap(value, o.value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
T& operator->() noexcept { return value; }
|
||||
const T& operator->() const noexcept { return value; }
|
||||
|
||||
operator T&() noexcept { return value; }
|
||||
T& get() noexcept { return value; }
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ template <class... Ts>
|
||||
struct TypeList {
|
||||
template <template <class...> class T, class... Ps>
|
||||
using ExpandInto = T<Ps..., Ts...>;
|
||||
static constexpr std::size_t TypeCount = sizeof...(Ts);
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
namespace mbgl {
|
||||
namespace gfx {
|
||||
|
||||
bool Backend::enableGPUExpressionEval = false;
|
||||
|
||||
HeadlessBackend::HeadlessBackend(Size size_)
|
||||
: mbgl::gfx::Renderable(size_, nullptr) {}
|
||||
|
||||
|
||||
@@ -229,7 +229,10 @@ ios_application(
|
||||
infoplists = ["//platform/ios/benchmark:info_benchmark_plist"],
|
||||
minimum_os_version = "12.0",
|
||||
provisioning_profile = "xcode_profile",
|
||||
resources = ["//platform/ios/benchmark:bundle_resources"],
|
||||
resources = [
|
||||
"//platform/ios/benchmark:bundle_resources",
|
||||
"//platform/ios/benchmark/assets:benchmark_assets",
|
||||
],
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//platform:ios-benchapp",
|
||||
|
||||
@@ -26,8 +26,6 @@ filegroup(
|
||||
srcs = glob([
|
||||
"*.lproj/**",
|
||||
"Assets.xcassets/**",
|
||||
"assets/**/*.json",
|
||||
"assets/**/*.png",
|
||||
]),
|
||||
visibility = ["//platform/ios:__pkg__"],
|
||||
)
|
||||
|
||||
14
platform/ios/benchmark/assets/BUILD.bazel
Normal file
14
platform/ios/benchmark/assets/BUILD.bazel
Normal file
@@ -0,0 +1,14 @@
|
||||
load("@build_bazel_rules_apple//apple:resources.bzl", "apple_resource_group")
|
||||
|
||||
apple_resource_group(
|
||||
name = "benchmark_assets",
|
||||
structured_resources = glob(
|
||||
[
|
||||
"**/*.json",
|
||||
"**/*.png",
|
||||
"**/*.pbf",
|
||||
],
|
||||
allow_empty = True,
|
||||
),
|
||||
visibility = ["//platform/ios:__pkg__"],
|
||||
)
|
||||
316
platform/ios/benchmark/assets/glyphs/download.sh
Normal file → Executable file
316
platform/ios/benchmark/assets/glyphs/download.sh
Normal file → Executable file
@@ -3,36 +3,300 @@
|
||||
set -u
|
||||
|
||||
LIST=(
|
||||
"Noto%20Sans%20Regular/0-255.pbf"
|
||||
"Roboto%20Condensed%20Italic,Noto%20Sans%20Italic/0-255.pbf"
|
||||
"Roboto%20Condensed%20Italic,Noto%20Sans%20Italic/256-511.pbf"
|
||||
"Roboto%20Medium,Noto%20Sans%20Regular/0-255.pbf"
|
||||
"Roboto%20Medium,Noto%20Sans%20Regular/65024-65279.pbf"
|
||||
"Roboto%20Medium,Noto%20Sans%20Regular/11520-11775.pbf"
|
||||
"Roboto%20Regular,Noto%20Sans%20Regular/0-255.pbf"
|
||||
"Roboto%20Regular,Noto%20Sans%20Regular/256-511.pbf"
|
||||
"Roboto%20Regular,Noto%20Sans%20Regular/512-767.pbf"
|
||||
"Roboto%20Regular,Noto%20Sans%20Regular/768-1023.pbf"
|
||||
"Roboto%20Regular,Noto%20Sans%20Regular/1024-1279.pbf"
|
||||
"Roboto%20Regular,Noto%20Sans%20Regular/8192-8447.pbf"
|
||||
"Roboto%20Medium,Noto%20Sans%20Regular/256-511.pbf"
|
||||
"Roboto%20Medium,Noto%20Sans%20Regular/512-767.pbf"
|
||||
"Roboto%20Medium,Noto%20Sans%20Regular/768-1023.pbf"
|
||||
"Roboto%20Medium,Noto%20Sans%20Regular/1024-1279.pbf"
|
||||
"Noto Sans Regular/0-255.pbf"
|
||||
"Roboto Condensed Italic,Noto Sans Italic/0-255.pbf"
|
||||
"Roboto Condensed Italic,Noto Sans Italic/256-511.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/0-255.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/65024-65279.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/11520-11775.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/0-255.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/256-511.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/512-767.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/768-1023.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/1024-1279.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/8192-8447.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/256-511.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/512-767.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/768-1023.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/1024-1279.pbf"
|
||||
|
||||
# Observed from dynamic benchmark
|
||||
"Noto Sans Regular/19968-20223.pbf"
|
||||
"Noto Sans Regular/22016-22271.pbf"
|
||||
"Noto Sans Regular/22272-22527.pbf"
|
||||
"Noto Sans Regular/26368-26623.pbf"
|
||||
"Noto Sans Regular/26624-26879.pbf"
|
||||
"Noto Sans Regular/27904-28159.pbf"
|
||||
"Noto Sans Regular/34304-34559.pbf"
|
||||
"Noto Sans Regular/38400-38655.pbf"
|
||||
"Roboto Condensed Italic,Noto Sans Italic/512-767.pbf"
|
||||
"Roboto Condensed Italic,Noto Sans Italic/7680-7935.pbf"
|
||||
"Roboto Condensed Italic,Noto Sans Italic/8192-8447.pbf"
|
||||
"Roboto Condensed Italic,Noto Sans Italic/19968-20223.pbf"
|
||||
"Roboto Condensed Italic,Noto Sans Italic/20224-20479.pbf"
|
||||
"Roboto Condensed Italic,Noto Sans Italic/20480-20735.pbf"
|
||||
"Roboto Condensed Italic,Noto Sans Italic/20736-20991.pbf"
|
||||
"Roboto Condensed Italic,Noto Sans Italic/20992-21247.pbf"
|
||||
"Roboto Condensed Italic,Noto Sans Italic/21248-21503.pbf"
|
||||
"Roboto Condensed Italic,Noto Sans Italic/21504-21759.pbf"
|
||||
"Roboto Condensed Italic,Noto Sans Italic/22016-22271.pbf"
|
||||
"Roboto Condensed Italic,Noto Sans Italic/22272-22527.pbf"
|
||||
"Roboto Condensed Italic,Noto Sans Italic/22528-22783.pbf"
|
||||
"Roboto Condensed Italic,Noto Sans Italic/22784-23039.pbf"
|
||||
"Roboto Condensed Italic,Noto Sans Italic/23296-23551.pbf"
|
||||
"Roboto Condensed Italic,Noto Sans Italic/23552-23807.pbf"
|
||||
"Roboto Condensed Italic,Noto Sans Italic/23808-24063.pbf"
|
||||
"Roboto Condensed Italic,Noto Sans Italic/24064-24319.pbf"
|
||||
"Roboto Condensed Italic,Noto Sans Italic/24320-24575.pbf"
|
||||
"Roboto Condensed Italic,Noto Sans Italic/25088-25343.pbf"
|
||||
"Roboto Condensed Italic,Noto Sans Italic/25344-25599.pbf"
|
||||
"Roboto Condensed Italic,Noto Sans Italic/25856-26111.pbf"
|
||||
"Roboto Condensed Italic,Noto Sans Italic/26112-26367.pbf"
|
||||
"Roboto Condensed Italic,Noto Sans Italic/26368-26623.pbf"
|
||||
"Roboto Condensed Italic,Noto Sans Italic/26624-26879.pbf"
|
||||
"Roboto Condensed Italic,Noto Sans Italic/26880-27135.pbf"
|
||||
"Roboto Condensed Italic,Noto Sans Italic/27136-27391.pbf"
|
||||
"Roboto Condensed Italic,Noto Sans Italic/27392-27647.pbf"
|
||||
"Roboto Condensed Italic,Noto Sans Italic/27648-27903.pbf"
|
||||
"Roboto Condensed Italic,Noto Sans Italic/27904-28159.pbf"
|
||||
"Roboto Condensed Italic,Noto Sans Italic/28160-28415.pbf"
|
||||
"Roboto Condensed Italic,Noto Sans Italic/28416-28671.pbf"
|
||||
"Roboto Condensed Italic,Noto Sans Italic/29184-29439.pbf"
|
||||
"Roboto Condensed Italic,Noto Sans Italic/29440-29695.pbf"
|
||||
"Roboto Condensed Italic,Noto Sans Italic/29696-29951.pbf"
|
||||
"Roboto Condensed Italic,Noto Sans Italic/29952-30207.pbf"
|
||||
"Roboto Condensed Italic,Noto Sans Italic/30208-30463.pbf"
|
||||
"Roboto Condensed Italic,Noto Sans Italic/30464-30719.pbf"
|
||||
"Roboto Condensed Italic,Noto Sans Italic/30720-30975.pbf"
|
||||
"Roboto Condensed Italic,Noto Sans Italic/30976-31231.pbf"
|
||||
"Roboto Condensed Italic,Noto Sans Italic/31232-31487.pbf"
|
||||
"Roboto Condensed Italic,Noto Sans Italic/31488-31743.pbf"
|
||||
"Roboto Condensed Italic,Noto Sans Italic/31744-31999.pbf"
|
||||
"Roboto Condensed Italic,Noto Sans Italic/32000-32255.pbf"
|
||||
"Roboto Condensed Italic,Noto Sans Italic/32256-32511.pbf"
|
||||
"Roboto Condensed Italic,Noto Sans Italic/32512-32767.pbf"
|
||||
"Roboto Condensed Italic,Noto Sans Italic/32768-33023.pbf"
|
||||
"Roboto Condensed Italic,Noto Sans Italic/33280-33535.pbf"
|
||||
"Roboto Condensed Italic,Noto Sans Italic/33536-33791.pbf"
|
||||
"Roboto Condensed Italic,Noto Sans Italic/34304-34559.pbf"
|
||||
"Roboto Condensed Italic,Noto Sans Italic/34816-35071.pbf"
|
||||
"Roboto Condensed Italic,Noto Sans Italic/35072-35327.pbf"
|
||||
"Roboto Condensed Italic,Noto Sans Italic/35584-35839.pbf"
|
||||
"Roboto Condensed Italic,Noto Sans Italic/35840-36095.pbf"
|
||||
"Roboto Condensed Italic,Noto Sans Italic/36096-36351.pbf"
|
||||
"Roboto Condensed Italic,Noto Sans Italic/36608-36863.pbf"
|
||||
"Roboto Condensed Italic,Noto Sans Italic/36864-37119.pbf"
|
||||
"Roboto Condensed Italic,Noto Sans Italic/37120-37375.pbf"
|
||||
"Roboto Condensed Italic,Noto Sans Italic/37888-38143.pbf"
|
||||
"Roboto Condensed Italic,Noto Sans Italic/38144-38399.pbf"
|
||||
"Roboto Condensed Italic,Noto Sans Italic/38400-38655.pbf"
|
||||
"Roboto Condensed Italic,Noto Sans Italic/38656-38911.pbf"
|
||||
"Roboto Condensed Italic,Noto Sans Italic/38912-39167.pbf"
|
||||
"Roboto Condensed Italic,Noto Sans Italic/39168-39423.pbf"
|
||||
"Roboto Condensed Italic,Noto Sans Italic/39424-39679.pbf"
|
||||
"Roboto Condensed Italic,Noto Sans Italic/39936-40191.pbf"
|
||||
"Roboto Condensed Italic,Noto Sans Italic/40448-40703.pbf"
|
||||
"Roboto Condensed Italic,Noto Sans Italic/40704-40959.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/1536-1791.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/1792-2047.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/2304-2559.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/2816-3071.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/3584-3839.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/3840-4095.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/4096-4351.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/5888-6143.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/6144-6399.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/7680-7935.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/8192-8447.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/19968-20223.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/20224-20479.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/20736-20991.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/20992-21247.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/21248-21503.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/21504-21759.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/21760-22015.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/22016-22271.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/22272-22527.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/22528-22783.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/22784-23039.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/23040-23295.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/23296-23551.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/23552-23807.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/23808-24063.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/24064-24319.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/24320-24575.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/24576-24831.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/24832-25087.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/25088-25343.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/25856-26111.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/26112-26367.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/26368-26623.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/26624-26879.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/26880-27135.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/27136-27391.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/27392-27647.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/27648-27903.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/27904-28159.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/28160-28415.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/28416-28671.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/28672-28927.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/28928-29183.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/29184-29439.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/29440-29695.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/29696-29951.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/29952-30207.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/30208-30463.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/30464-30719.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/30976-31231.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/31232-31487.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/32256-32511.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/32512-32767.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/32768-33023.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/33024-33279.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/33280-33535.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/33536-33791.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/33792-34047.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/34048-34303.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/34304-34559.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/34816-35071.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/35072-35327.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/35584-35839.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/36096-36351.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/36608-36863.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/36864-37119.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/37120-37375.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/37888-38143.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/38144-38399.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/38400-38655.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/38656-38911.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/38912-39167.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/39168-39423.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/39424-39679.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/40448-40703.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/40704-40959.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/40960-41215.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/41728-41983.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/44032-44287.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/44288-44543.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/44544-44799.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/45056-45311.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/45824-46079.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/46848-47103.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/47616-47871.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/48384-48639.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/49152-49407.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/49408-49663.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/49664-49919.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/50432-50687.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/50688-50943.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/50944-51199.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/51200-51455.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/52224-52479.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/54016-54271.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/54528-54783.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/54784-55039.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/55040-55295.pbf"
|
||||
"Roboto Medium,Noto Sans Regular/64256-64511.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/2816-3071.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/3072-3327.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/7680-7935.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/12288-12543.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/19968-20223.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/20224-20479.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/20480-20735.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/20736-20991.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/20992-21247.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/21248-21503.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/21504-21759.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/21760-22015.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/22016-22271.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/22272-22527.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/22528-22783.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/22784-23039.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/23040-23295.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/23296-23551.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/23552-23807.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/23808-24063.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/24064-24319.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/24320-24575.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/24576-24831.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/24832-25087.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/25088-25343.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/25344-25599.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/25856-26111.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/26112-26367.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/26368-26623.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/26624-26879.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/26880-27135.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/27136-27391.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/27392-27647.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/27648-27903.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/27904-28159.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/28160-28415.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/28416-28671.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/28672-28927.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/28928-29183.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/29184-29439.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/29440-29695.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/29696-29951.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/29952-30207.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/30208-30463.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/30464-30719.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/30720-30975.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/30976-31231.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/31232-31487.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/31488-31743.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/31744-31999.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/32000-32255.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/32256-32511.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/32512-32767.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/32768-33023.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/33024-33279.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/33280-33535.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/33536-33791.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/33792-34047.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/34048-34303.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/34304-34559.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/34560-34815.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/34816-35071.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/35072-35327.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/35584-35839.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/35840-36095.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/36096-36351.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/36608-36863.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/36864-37119.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/37120-37375.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/37888-38143.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/38144-38399.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/38400-38655.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/38656-38911.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/38912-39167.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/39168-39423.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/39424-39679.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/39936-40191.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/40448-40703.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/40704-40959.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/45824-46079.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/50432-50687.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/50688-50943.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/50944-51199.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/51200-51455.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/65024-65279.pbf"
|
||||
"Roboto Regular,Noto Sans Regular/65280-65535.pbf"
|
||||
)
|
||||
|
||||
|
||||
# from https://gist.github.com/cdown/1163649
|
||||
urldecode() {
|
||||
local url_encoded="${1//+/ }"
|
||||
printf '%b' "${url_encoded//%/\\x}"
|
||||
urlencode() {
|
||||
echo $(sed -E "s/ /%20/g" <<< """$1""")
|
||||
}
|
||||
|
||||
for i in ${LIST[@]} ; do
|
||||
OUTPUT=`urldecode "$i"`
|
||||
if [ ! -f "${OUTPUT}" ] ; then
|
||||
mkdir -p "`dirname "${OUTPUT}"`"
|
||||
echo "Downloading glyph '${OUTPUT}'"
|
||||
curl --compressed --progress-bar --output "${OUTPUT}" "https://api.maptiler.com/fonts/${i}?key=${MLN_API_KEY}"
|
||||
for i in "${LIST[@]}" ; do
|
||||
INPUT=$(urlencode "$i")
|
||||
OUTPUT="$i"
|
||||
OUTDIR=$(dirname "$OUTPUT")
|
||||
if [ ! -f "$OUTPUT" ] ; then
|
||||
mkdir -p "$OUTDIR"
|
||||
echo "Downloading glyph '$OUTPUT' from '$INPUT'"
|
||||
curl --compressed --progress-bar --output "${OUTPUT}" "https://api.maptiler.com/fonts/${INPUT}?key=${MLN_API_KEY}"
|
||||
fi
|
||||
done
|
||||
|
||||
683
platform/ios/benchmark/assets/tiles/download.sh
Normal file → Executable file
683
platform/ios/benchmark/assets/tiles/download.sh
Normal file → Executable file
@@ -85,6 +85,689 @@ LIST=(
|
||||
"tiles/v3/6/34/20.pbf"
|
||||
"tiles/v3/6/33/20.pbf"
|
||||
"tiles/v3/6/32/20.pbf"
|
||||
|
||||
# observed from dynamic benchmark
|
||||
"tiles/v3/0/0/0.pbf"
|
||||
"tiles/v3/1/0/0.pbf"
|
||||
"tiles/v3/1/0/1.pbf"
|
||||
"tiles/v3/1/1/0.pbf"
|
||||
"tiles/v3/1/1/1.pbf"
|
||||
"tiles/v3/2/0/0.pbf"
|
||||
"tiles/v3/2/0/1.pbf"
|
||||
"tiles/v3/2/0/2.pbf"
|
||||
"tiles/v3/2/0/3.pbf"
|
||||
"tiles/v3/2/1/0.pbf"
|
||||
"tiles/v3/2/1/1.pbf"
|
||||
"tiles/v3/2/1/2.pbf"
|
||||
"tiles/v3/2/1/3.pbf"
|
||||
"tiles/v3/2/2/0.pbf"
|
||||
"tiles/v3/2/2/1.pbf"
|
||||
"tiles/v3/2/2/2.pbf"
|
||||
"tiles/v3/2/3/0.pbf"
|
||||
"tiles/v3/2/3/1.pbf"
|
||||
"tiles/v3/2/3/2.pbf"
|
||||
"tiles/v3/3/0/2.pbf"
|
||||
"tiles/v3/3/0/3.pbf"
|
||||
"tiles/v3/3/0/4.pbf"
|
||||
"tiles/v3/3/1/2.pbf"
|
||||
"tiles/v3/3/1/3.pbf"
|
||||
"tiles/v3/3/1/4.pbf"
|
||||
"tiles/v3/3/1/5.pbf"
|
||||
"tiles/v3/3/2/1.pbf"
|
||||
"tiles/v3/3/2/2.pbf"
|
||||
"tiles/v3/3/2/3.pbf"
|
||||
"tiles/v3/3/2/4.pbf"
|
||||
"tiles/v3/3/2/5.pbf"
|
||||
"tiles/v3/3/3/1.pbf"
|
||||
"tiles/v3/3/3/2.pbf"
|
||||
"tiles/v3/3/3/3.pbf"
|
||||
"tiles/v3/3/3/4.pbf"
|
||||
"tiles/v3/3/3/5.pbf"
|
||||
"tiles/v3/3/4/1.pbf"
|
||||
"tiles/v3/3/4/2.pbf"
|
||||
"tiles/v3/3/4/3.pbf"
|
||||
"tiles/v3/3/4/4.pbf"
|
||||
"tiles/v3/3/5/1.pbf"
|
||||
"tiles/v3/3/5/2.pbf"
|
||||
"tiles/v3/3/5/3.pbf"
|
||||
"tiles/v3/3/5/4.pbf"
|
||||
"tiles/v3/3/6/2.pbf"
|
||||
"tiles/v3/3/6/3.pbf"
|
||||
"tiles/v3/3/6/4.pbf"
|
||||
"tiles/v3/3/7/2.pbf"
|
||||
"tiles/v3/3/7/3.pbf"
|
||||
"tiles/v3/3/7/4.pbf"
|
||||
"tiles/v3/4/1/5.pbf"
|
||||
"tiles/v3/4/1/6.pbf"
|
||||
"tiles/v3/4/1/7.pbf"
|
||||
"tiles/v3/4/10/6.pbf"
|
||||
"tiles/v3/4/10/7.pbf"
|
||||
"tiles/v3/4/10/8.pbf"
|
||||
"tiles/v3/4/11/6.pbf"
|
||||
"tiles/v3/4/11/7.pbf"
|
||||
"tiles/v3/4/11/8.pbf"
|
||||
"tiles/v3/4/12/5.pbf"
|
||||
"tiles/v3/4/12/6.pbf"
|
||||
"tiles/v3/4/12/7.pbf"
|
||||
"tiles/v3/4/12/8.pbf"
|
||||
"tiles/v3/4/13/5.pbf"
|
||||
"tiles/v3/4/13/6.pbf"
|
||||
"tiles/v3/4/13/7.pbf"
|
||||
"tiles/v3/4/14/5.pbf"
|
||||
"tiles/v3/4/14/6.pbf"
|
||||
"tiles/v3/4/14/7.pbf"
|
||||
"tiles/v3/4/2/5.pbf"
|
||||
"tiles/v3/4/2/6.pbf"
|
||||
"tiles/v3/4/2/7.pbf"
|
||||
"tiles/v3/4/3/5.pbf"
|
||||
"tiles/v3/4/3/6.pbf"
|
||||
"tiles/v3/4/3/7.pbf"
|
||||
"tiles/v3/4/3/8.pbf"
|
||||
"tiles/v3/4/3/9.pbf"
|
||||
"tiles/v3/4/4/5.pbf"
|
||||
"tiles/v3/4/4/6.pbf"
|
||||
"tiles/v3/4/4/7.pbf"
|
||||
"tiles/v3/4/4/8.pbf"
|
||||
"tiles/v3/4/4/9.pbf"
|
||||
"tiles/v3/4/5/5.pbf"
|
||||
"tiles/v3/4/5/6.pbf"
|
||||
"tiles/v3/4/5/7.pbf"
|
||||
"tiles/v3/4/5/8.pbf"
|
||||
"tiles/v3/4/5/9.pbf"
|
||||
"tiles/v3/4/6/4.pbf"
|
||||
"tiles/v3/4/6/5.pbf"
|
||||
"tiles/v3/4/6/6.pbf"
|
||||
"tiles/v3/4/6/7.pbf"
|
||||
"tiles/v3/4/6/8.pbf"
|
||||
"tiles/v3/4/7/4.pbf"
|
||||
"tiles/v3/4/7/5.pbf"
|
||||
"tiles/v3/4/7/6.pbf"
|
||||
"tiles/v3/4/8/3.pbf"
|
||||
"tiles/v3/4/8/4.pbf"
|
||||
"tiles/v3/4/8/5.pbf"
|
||||
"tiles/v3/4/8/6.pbf"
|
||||
"tiles/v3/4/9/3.pbf"
|
||||
"tiles/v3/4/9/4.pbf"
|
||||
"tiles/v3/4/9/5.pbf"
|
||||
"tiles/v3/4/9/6.pbf"
|
||||
"tiles/v3/5/10/15.pbf"
|
||||
"tiles/v3/5/10/16.pbf"
|
||||
"tiles/v3/5/10/17.pbf"
|
||||
"tiles/v3/5/10/18.pbf"
|
||||
"tiles/v3/5/15/10.pbf"
|
||||
"tiles/v3/5/15/11.pbf"
|
||||
"tiles/v3/5/15/9.pbf"
|
||||
"tiles/v3/5/16/10.pbf"
|
||||
"tiles/v3/5/16/11.pbf"
|
||||
"tiles/v3/5/16/9.pbf"
|
||||
"tiles/v3/5/17/10.pbf"
|
||||
"tiles/v3/5/17/11.pbf"
|
||||
"tiles/v3/5/17/8.pbf"
|
||||
"tiles/v3/5/17/9.pbf"
|
||||
"tiles/v3/5/18/10.pbf"
|
||||
"tiles/v3/5/18/8.pbf"
|
||||
"tiles/v3/5/18/9.pbf"
|
||||
"tiles/v3/5/21/13.pbf"
|
||||
"tiles/v3/5/21/14.pbf"
|
||||
"tiles/v3/5/21/15.pbf"
|
||||
"tiles/v3/5/22/13.pbf"
|
||||
"tiles/v3/5/22/14.pbf"
|
||||
"tiles/v3/5/22/15.pbf"
|
||||
"tiles/v3/5/23/13.pbf"
|
||||
"tiles/v3/5/23/14.pbf"
|
||||
"tiles/v3/5/23/15.pbf"
|
||||
"tiles/v3/5/25/12.pbf"
|
||||
"tiles/v3/5/25/13.pbf"
|
||||
"tiles/v3/5/25/14.pbf"
|
||||
"tiles/v3/5/26/12.pbf"
|
||||
"tiles/v3/5/26/13.pbf"
|
||||
"tiles/v3/5/26/14.pbf"
|
||||
"tiles/v3/5/27/12.pbf"
|
||||
"tiles/v3/5/27/13.pbf"
|
||||
"tiles/v3/5/27/14.pbf"
|
||||
"tiles/v3/5/4/11.pbf"
|
||||
"tiles/v3/5/4/12.pbf"
|
||||
"tiles/v3/5/4/13.pbf"
|
||||
"tiles/v3/5/5/11.pbf"
|
||||
"tiles/v3/5/5/12.pbf"
|
||||
"tiles/v3/5/5/13.pbf"
|
||||
"tiles/v3/5/8/15.pbf"
|
||||
"tiles/v3/5/8/16.pbf"
|
||||
"tiles/v3/5/8/17.pbf"
|
||||
"tiles/v3/5/8/18.pbf"
|
||||
"tiles/v3/5/9/15.pbf"
|
||||
"tiles/v3/5/9/16.pbf"
|
||||
"tiles/v3/5/9/17.pbf"
|
||||
"tiles/v3/5/9/18.pbf"
|
||||
"tiles/v3/6/10/23.pbf"
|
||||
"tiles/v3/6/10/24.pbf"
|
||||
"tiles/v3/6/10/25.pbf"
|
||||
"tiles/v3/6/17/23.pbf"
|
||||
"tiles/v3/6/17/24.pbf"
|
||||
"tiles/v3/6/17/25.pbf"
|
||||
"tiles/v3/6/18/23.pbf"
|
||||
"tiles/v3/6/18/24.pbf"
|
||||
"tiles/v3/6/18/25.pbf"
|
||||
"tiles/v3/6/18/33.pbf"
|
||||
"tiles/v3/6/18/34.pbf"
|
||||
"tiles/v3/6/18/35.pbf"
|
||||
"tiles/v3/6/19/23.pbf"
|
||||
"tiles/v3/6/19/24.pbf"
|
||||
"tiles/v3/6/19/25.pbf"
|
||||
"tiles/v3/6/19/33.pbf"
|
||||
"tiles/v3/6/19/34.pbf"
|
||||
"tiles/v3/6/19/35.pbf"
|
||||
"tiles/v3/6/33/19.pbf"
|
||||
"tiles/v3/6/34/19.pbf"
|
||||
"tiles/v3/6/35/17.pbf"
|
||||
"tiles/v3/6/35/18.pbf"
|
||||
"tiles/v3/6/35/19.pbf"
|
||||
"tiles/v3/6/35/20.pbf"
|
||||
"tiles/v3/6/35/21.pbf"
|
||||
"tiles/v3/6/35/22.pbf"
|
||||
"tiles/v3/6/36/17.pbf"
|
||||
"tiles/v3/6/36/18.pbf"
|
||||
"tiles/v3/6/36/19.pbf"
|
||||
"tiles/v3/6/37/17.pbf"
|
||||
"tiles/v3/6/37/18.pbf"
|
||||
"tiles/v3/6/37/19.pbf"
|
||||
"tiles/v3/6/44/28.pbf"
|
||||
"tiles/v3/6/44/29.pbf"
|
||||
"tiles/v3/6/44/30.pbf"
|
||||
"tiles/v3/6/45/28.pbf"
|
||||
"tiles/v3/6/45/29.pbf"
|
||||
"tiles/v3/6/45/30.pbf"
|
||||
"tiles/v3/6/46/28.pbf"
|
||||
"tiles/v3/6/46/29.pbf"
|
||||
"tiles/v3/6/46/30.pbf"
|
||||
"tiles/v3/6/52/25.pbf"
|
||||
"tiles/v3/6/52/26.pbf"
|
||||
"tiles/v3/6/52/27.pbf"
|
||||
"tiles/v3/6/53/25.pbf"
|
||||
"tiles/v3/6/53/26.pbf"
|
||||
"tiles/v3/6/53/27.pbf"
|
||||
"tiles/v3/6/54/25.pbf"
|
||||
"tiles/v3/6/54/26.pbf"
|
||||
"tiles/v3/6/54/27.pbf"
|
||||
"tiles/v3/6/9/23.pbf"
|
||||
"tiles/v3/6/9/24.pbf"
|
||||
"tiles/v3/6/9/25.pbf"
|
||||
"tiles/v3/7/106/51.pbf"
|
||||
"tiles/v3/7/106/52.pbf"
|
||||
"tiles/v3/7/106/53.pbf"
|
||||
"tiles/v3/7/107/51.pbf"
|
||||
"tiles/v3/7/107/52.pbf"
|
||||
"tiles/v3/7/107/53.pbf"
|
||||
"tiles/v3/7/19/48.pbf"
|
||||
"tiles/v3/7/19/49.pbf"
|
||||
"tiles/v3/7/19/50.pbf"
|
||||
"tiles/v3/7/20/48.pbf"
|
||||
"tiles/v3/7/20/49.pbf"
|
||||
"tiles/v3/7/20/50.pbf"
|
||||
"tiles/v3/7/21/48.pbf"
|
||||
"tiles/v3/7/21/49.pbf"
|
||||
"tiles/v3/7/21/50.pbf"
|
||||
"tiles/v3/7/35/47.pbf"
|
||||
"tiles/v3/7/35/48.pbf"
|
||||
"tiles/v3/7/35/49.pbf"
|
||||
"tiles/v3/7/36/47.pbf"
|
||||
"tiles/v3/7/36/48.pbf"
|
||||
"tiles/v3/7/36/49.pbf"
|
||||
"tiles/v3/7/36/67.pbf"
|
||||
"tiles/v3/7/36/68.pbf"
|
||||
"tiles/v3/7/36/69.pbf"
|
||||
"tiles/v3/7/37/47.pbf"
|
||||
"tiles/v3/7/37/48.pbf"
|
||||
"tiles/v3/7/37/49.pbf"
|
||||
"tiles/v3/7/37/67.pbf"
|
||||
"tiles/v3/7/37/68.pbf"
|
||||
"tiles/v3/7/37/69.pbf"
|
||||
"tiles/v3/7/38/67.pbf"
|
||||
"tiles/v3/7/38/68.pbf"
|
||||
"tiles/v3/7/38/69.pbf"
|
||||
"tiles/v3/7/64/41.pbf"
|
||||
"tiles/v3/7/64/42.pbf"
|
||||
"tiles/v3/7/64/43.pbf"
|
||||
"tiles/v3/7/65/41.pbf"
|
||||
"tiles/v3/7/65/42.pbf"
|
||||
"tiles/v3/7/65/43.pbf"
|
||||
"tiles/v3/7/66/41.pbf"
|
||||
"tiles/v3/7/66/42.pbf"
|
||||
"tiles/v3/7/66/43.pbf"
|
||||
"tiles/v3/7/67/41.pbf"
|
||||
"tiles/v3/7/67/42.pbf"
|
||||
"tiles/v3/7/67/43.pbf"
|
||||
"tiles/v3/7/68/40.pbf"
|
||||
"tiles/v3/7/68/41.pbf"
|
||||
"tiles/v3/7/68/42.pbf"
|
||||
"tiles/v3/7/68/43.pbf"
|
||||
"tiles/v3/7/69/40.pbf"
|
||||
"tiles/v3/7/69/41.pbf"
|
||||
"tiles/v3/7/69/42.pbf"
|
||||
"tiles/v3/7/69/43.pbf"
|
||||
"tiles/v3/7/72/36.pbf"
|
||||
"tiles/v3/7/72/37.pbf"
|
||||
"tiles/v3/7/72/38.pbf"
|
||||
"tiles/v3/7/73/36.pbf"
|
||||
"tiles/v3/7/73/37.pbf"
|
||||
"tiles/v3/7/73/38.pbf"
|
||||
"tiles/v3/7/90/58.pbf"
|
||||
"tiles/v3/7/90/59.pbf"
|
||||
"tiles/v3/7/90/60.pbf"
|
||||
"tiles/v3/7/91/58.pbf"
|
||||
"tiles/v3/7/91/59.pbf"
|
||||
"tiles/v3/7/91/60.pbf"
|
||||
"tiles/v3/7/92/58.pbf"
|
||||
"tiles/v3/7/92/59.pbf"
|
||||
"tiles/v3/7/92/60.pbf"
|
||||
"tiles/v3/8/130/83.pbf"
|
||||
"tiles/v3/8/130/84.pbf"
|
||||
"tiles/v3/8/130/85.pbf"
|
||||
"tiles/v3/8/131/83.pbf"
|
||||
"tiles/v3/8/131/84.pbf"
|
||||
"tiles/v3/8/131/85.pbf"
|
||||
"tiles/v3/8/132/83.pbf"
|
||||
"tiles/v3/8/132/84.pbf"
|
||||
"tiles/v3/8/132/85.pbf"
|
||||
"tiles/v3/8/136/82.pbf"
|
||||
"tiles/v3/8/136/83.pbf"
|
||||
"tiles/v3/8/136/84.pbf"
|
||||
"tiles/v3/8/137/82.pbf"
|
||||
"tiles/v3/8/137/83.pbf"
|
||||
"tiles/v3/8/137/84.pbf"
|
||||
"tiles/v3/8/138/82.pbf"
|
||||
"tiles/v3/8/138/83.pbf"
|
||||
"tiles/v3/8/138/84.pbf"
|
||||
"tiles/v3/8/144/73.pbf"
|
||||
"tiles/v3/8/144/74.pbf"
|
||||
"tiles/v3/8/144/75.pbf"
|
||||
"tiles/v3/8/145/73.pbf"
|
||||
"tiles/v3/8/145/74.pbf"
|
||||
"tiles/v3/8/145/75.pbf"
|
||||
"tiles/v3/8/146/73.pbf"
|
||||
"tiles/v3/8/146/74.pbf"
|
||||
"tiles/v3/8/146/75.pbf"
|
||||
"tiles/v3/8/182/117.pbf"
|
||||
"tiles/v3/8/182/118.pbf"
|
||||
"tiles/v3/8/182/119.pbf"
|
||||
"tiles/v3/8/183/117.pbf"
|
||||
"tiles/v3/8/183/118.pbf"
|
||||
"tiles/v3/8/183/119.pbf"
|
||||
"tiles/v3/8/213/103.pbf"
|
||||
"tiles/v3/8/213/104.pbf"
|
||||
"tiles/v3/8/213/105.pbf"
|
||||
"tiles/v3/8/214/103.pbf"
|
||||
"tiles/v3/8/214/104.pbf"
|
||||
"tiles/v3/8/214/105.pbf"
|
||||
"tiles/v3/8/215/103.pbf"
|
||||
"tiles/v3/8/215/104.pbf"
|
||||
"tiles/v3/8/215/105.pbf"
|
||||
"tiles/v3/8/40/97.pbf"
|
||||
"tiles/v3/8/40/98.pbf"
|
||||
"tiles/v3/8/40/99.pbf"
|
||||
"tiles/v3/8/41/97.pbf"
|
||||
"tiles/v3/8/41/98.pbf"
|
||||
"tiles/v3/8/41/99.pbf"
|
||||
"tiles/v3/8/72/96.pbf"
|
||||
"tiles/v3/8/72/97.pbf"
|
||||
"tiles/v3/8/72/98.pbf"
|
||||
"tiles/v3/8/73/96.pbf"
|
||||
"tiles/v3/8/73/97.pbf"
|
||||
"tiles/v3/8/73/98.pbf"
|
||||
"tiles/v3/8/74/136.pbf"
|
||||
"tiles/v3/8/74/137.pbf"
|
||||
"tiles/v3/8/74/138.pbf"
|
||||
"tiles/v3/8/75/136.pbf"
|
||||
"tiles/v3/8/75/137.pbf"
|
||||
"tiles/v3/8/75/138.pbf"
|
||||
"tiles/v3/9/145/194.pbf"
|
||||
"tiles/v3/9/145/195.pbf"
|
||||
"tiles/v3/9/145/196.pbf"
|
||||
"tiles/v3/9/146/194.pbf"
|
||||
"tiles/v3/9/146/195.pbf"
|
||||
"tiles/v3/9/146/196.pbf"
|
||||
"tiles/v3/9/147/194.pbf"
|
||||
"tiles/v3/9/147/195.pbf"
|
||||
"tiles/v3/9/147/196.pbf"
|
||||
"tiles/v3/9/149/273.pbf"
|
||||
"tiles/v3/9/149/274.pbf"
|
||||
"tiles/v3/9/149/275.pbf"
|
||||
"tiles/v3/9/150/273.pbf"
|
||||
"tiles/v3/9/150/274.pbf"
|
||||
"tiles/v3/9/150/275.pbf"
|
||||
"tiles/v3/9/151/273.pbf"
|
||||
"tiles/v3/9/151/274.pbf"
|
||||
"tiles/v3/9/151/275.pbf"
|
||||
"tiles/v3/9/262/167.pbf"
|
||||
"tiles/v3/9/262/168.pbf"
|
||||
"tiles/v3/9/262/169.pbf"
|
||||
"tiles/v3/9/263/167.pbf"
|
||||
"tiles/v3/9/263/168.pbf"
|
||||
"tiles/v3/9/263/169.pbf"
|
||||
"tiles/v3/9/274/166.pbf"
|
||||
"tiles/v3/9/274/167.pbf"
|
||||
"tiles/v3/9/274/168.pbf"
|
||||
"tiles/v3/9/275/166.pbf"
|
||||
"tiles/v3/9/275/167.pbf"
|
||||
"tiles/v3/9/275/168.pbf"
|
||||
"tiles/v3/9/290/147.pbf"
|
||||
"tiles/v3/9/290/148.pbf"
|
||||
"tiles/v3/9/290/149.pbf"
|
||||
"tiles/v3/9/291/147.pbf"
|
||||
"tiles/v3/9/291/148.pbf"
|
||||
"tiles/v3/9/291/149.pbf"
|
||||
"tiles/v3/9/292/147.pbf"
|
||||
"tiles/v3/9/292/148.pbf"
|
||||
"tiles/v3/9/292/149.pbf"
|
||||
"tiles/v3/9/365/236.pbf"
|
||||
"tiles/v3/9/365/237.pbf"
|
||||
"tiles/v3/9/365/238.pbf"
|
||||
"tiles/v3/9/366/236.pbf"
|
||||
"tiles/v3/9/366/237.pbf"
|
||||
"tiles/v3/9/366/238.pbf"
|
||||
"tiles/v3/9/367/236.pbf"
|
||||
"tiles/v3/9/367/237.pbf"
|
||||
"tiles/v3/9/367/238.pbf"
|
||||
"tiles/v3/9/428/208.pbf"
|
||||
"tiles/v3/9/428/209.pbf"
|
||||
"tiles/v3/9/428/210.pbf"
|
||||
"tiles/v3/9/429/208.pbf"
|
||||
"tiles/v3/9/429/209.pbf"
|
||||
"tiles/v3/9/429/210.pbf"
|
||||
"tiles/v3/9/81/196.pbf"
|
||||
"tiles/v3/9/81/197.pbf"
|
||||
"tiles/v3/9/81/198.pbf"
|
||||
"tiles/v3/9/82/196.pbf"
|
||||
"tiles/v3/9/82/197.pbf"
|
||||
"tiles/v3/9/82/198.pbf"
|
||||
"tiles/v3/10/163/394.pbf"
|
||||
"tiles/v3/10/163/395.pbf"
|
||||
"tiles/v3/10/163/396.pbf"
|
||||
"tiles/v3/10/164/394.pbf"
|
||||
"tiles/v3/10/164/395.pbf"
|
||||
"tiles/v3/10/164/396.pbf"
|
||||
"tiles/v3/10/292/390.pbf"
|
||||
"tiles/v3/10/292/391.pbf"
|
||||
"tiles/v3/10/292/392.pbf"
|
||||
"tiles/v3/10/293/390.pbf"
|
||||
"tiles/v3/10/293/391.pbf"
|
||||
"tiles/v3/10/293/392.pbf"
|
||||
"tiles/v3/10/300/548.pbf"
|
||||
"tiles/v3/10/300/549.pbf"
|
||||
"tiles/v3/10/300/550.pbf"
|
||||
"tiles/v3/10/301/548.pbf"
|
||||
"tiles/v3/10/301/549.pbf"
|
||||
"tiles/v3/10/301/550.pbf"
|
||||
"tiles/v3/10/525/335.pbf"
|
||||
"tiles/v3/10/525/336.pbf"
|
||||
"tiles/v3/10/525/337.pbf"
|
||||
"tiles/v3/10/526/335.pbf"
|
||||
"tiles/v3/10/526/336.pbf"
|
||||
"tiles/v3/10/526/337.pbf"
|
||||
"tiles/v3/10/549/334.pbf"
|
||||
"tiles/v3/10/549/335.pbf"
|
||||
"tiles/v3/10/549/336.pbf"
|
||||
"tiles/v3/10/550/334.pbf"
|
||||
"tiles/v3/10/550/335.pbf"
|
||||
"tiles/v3/10/550/336.pbf"
|
||||
"tiles/v3/10/582/295.pbf"
|
||||
"tiles/v3/10/582/296.pbf"
|
||||
"tiles/v3/10/582/297.pbf"
|
||||
"tiles/v3/10/583/295.pbf"
|
||||
"tiles/v3/10/583/296.pbf"
|
||||
"tiles/v3/10/583/297.pbf"
|
||||
"tiles/v3/10/731/473.pbf"
|
||||
"tiles/v3/10/731/474.pbf"
|
||||
"tiles/v3/10/731/475.pbf"
|
||||
"tiles/v3/10/732/473.pbf"
|
||||
"tiles/v3/10/732/474.pbf"
|
||||
"tiles/v3/10/732/475.pbf"
|
||||
"tiles/v3/10/733/473.pbf"
|
||||
"tiles/v3/10/733/474.pbf"
|
||||
"tiles/v3/10/733/475.pbf"
|
||||
"tiles/v3/10/856/417.pbf"
|
||||
"tiles/v3/10/856/418.pbf"
|
||||
"tiles/v3/10/856/419.pbf"
|
||||
"tiles/v3/10/857/417.pbf"
|
||||
"tiles/v3/10/857/418.pbf"
|
||||
"tiles/v3/10/857/419.pbf"
|
||||
"tiles/v3/10/858/417.pbf"
|
||||
"tiles/v3/10/858/418.pbf"
|
||||
"tiles/v3/10/858/419.pbf"
|
||||
"tiles/v3/11/1051/672.pbf"
|
||||
"tiles/v3/11/1051/673.pbf"
|
||||
"tiles/v3/11/1051/674.pbf"
|
||||
"tiles/v3/11/1052/672.pbf"
|
||||
"tiles/v3/11/1052/673.pbf"
|
||||
"tiles/v3/11/1052/674.pbf"
|
||||
"tiles/v3/11/1099/670.pbf"
|
||||
"tiles/v3/11/1099/671.pbf"
|
||||
"tiles/v3/11/1099/672.pbf"
|
||||
"tiles/v3/11/1100/670.pbf"
|
||||
"tiles/v3/11/1100/671.pbf"
|
||||
"tiles/v3/11/1100/672.pbf"
|
||||
"tiles/v3/11/1101/670.pbf"
|
||||
"tiles/v3/11/1101/671.pbf"
|
||||
"tiles/v3/11/1101/672.pbf"
|
||||
"tiles/v3/11/1165/591.pbf"
|
||||
"tiles/v3/11/1165/592.pbf"
|
||||
"tiles/v3/11/1165/593.pbf"
|
||||
"tiles/v3/11/1166/591.pbf"
|
||||
"tiles/v3/11/1166/592.pbf"
|
||||
"tiles/v3/11/1166/593.pbf"
|
||||
"tiles/v3/11/1464/948.pbf"
|
||||
"tiles/v3/11/1464/949.pbf"
|
||||
"tiles/v3/11/1464/950.pbf"
|
||||
"tiles/v3/11/1465/948.pbf"
|
||||
"tiles/v3/11/1465/949.pbf"
|
||||
"tiles/v3/11/1465/950.pbf"
|
||||
"tiles/v3/11/1466/948.pbf"
|
||||
"tiles/v3/11/1466/949.pbf"
|
||||
"tiles/v3/11/1466/950.pbf"
|
||||
"tiles/v3/11/1714/835.pbf"
|
||||
"tiles/v3/11/1714/836.pbf"
|
||||
"tiles/v3/11/1714/837.pbf"
|
||||
"tiles/v3/11/1715/835.pbf"
|
||||
"tiles/v3/11/1715/836.pbf"
|
||||
"tiles/v3/11/1715/837.pbf"
|
||||
"tiles/v3/11/326/790.pbf"
|
||||
"tiles/v3/11/326/791.pbf"
|
||||
"tiles/v3/11/326/792.pbf"
|
||||
"tiles/v3/11/327/790.pbf"
|
||||
"tiles/v3/11/327/791.pbf"
|
||||
"tiles/v3/11/327/792.pbf"
|
||||
"tiles/v3/11/328/790.pbf"
|
||||
"tiles/v3/11/328/791.pbf"
|
||||
"tiles/v3/11/328/792.pbf"
|
||||
"tiles/v3/11/585/782.pbf"
|
||||
"tiles/v3/11/585/783.pbf"
|
||||
"tiles/v3/11/585/784.pbf"
|
||||
"tiles/v3/11/584/782.pbf"
|
||||
"tiles/v3/11/584/783.pbf"
|
||||
"tiles/v3/11/584/784.pbf"
|
||||
"tiles/v3/11/586/782.pbf"
|
||||
"tiles/v3/11/586/783.pbf"
|
||||
"tiles/v3/11/586/784.pbf"
|
||||
"tiles/v3/11/601/1098.pbf"
|
||||
"tiles/v3/11/601/1099.pbf"
|
||||
"tiles/v3/11/601/1100.pbf"
|
||||
"tiles/v3/11/602/1098.pbf"
|
||||
"tiles/v3/11/602/1099.pbf"
|
||||
"tiles/v3/11/602/1100.pbf"
|
||||
"tiles/v3/12/1170/1565.pbf"
|
||||
"tiles/v3/12/1170/1566.pbf"
|
||||
"tiles/v3/12/1170/1567.pbf"
|
||||
"tiles/v3/12/1171/1565.pbf"
|
||||
"tiles/v3/12/1171/1566.pbf"
|
||||
"tiles/v3/12/1171/1567.pbf"
|
||||
"tiles/v3/12/1172/1565.pbf"
|
||||
"tiles/v3/12/1172/1566.pbf"
|
||||
"tiles/v3/12/1172/1567.pbf"
|
||||
"tiles/v3/12/1202/2198.pbf"
|
||||
"tiles/v3/12/1202/2199.pbf"
|
||||
"tiles/v3/12/1202/2200.pbf"
|
||||
"tiles/v3/12/1203/2198.pbf"
|
||||
"tiles/v3/12/1203/2199.pbf"
|
||||
"tiles/v3/12/1203/2200.pbf"
|
||||
"tiles/v3/12/1204/2198.pbf"
|
||||
"tiles/v3/12/1204/2199.pbf"
|
||||
"tiles/v3/12/1204/2200.pbf"
|
||||
"tiles/v3/12/2102/1345.pbf"
|
||||
"tiles/v3/12/2102/1346.pbf"
|
||||
"tiles/v3/12/2102/1347.pbf"
|
||||
"tiles/v3/12/2103/1345.pbf"
|
||||
"tiles/v3/12/2103/1346.pbf"
|
||||
"tiles/v3/12/2103/1347.pbf"
|
||||
"tiles/v3/12/2104/1345.pbf"
|
||||
"tiles/v3/12/2104/1346.pbf"
|
||||
"tiles/v3/12/2104/1347.pbf"
|
||||
"tiles/v3/12/2199/1342.pbf"
|
||||
"tiles/v3/12/2199/1343.pbf"
|
||||
"tiles/v3/12/2199/1344.pbf"
|
||||
"tiles/v3/12/2200/1342.pbf"
|
||||
"tiles/v3/12/2200/1343.pbf"
|
||||
"tiles/v3/12/2200/1344.pbf"
|
||||
"tiles/v3/12/2201/1342.pbf"
|
||||
"tiles/v3/12/2201/1343.pbf"
|
||||
"tiles/v3/12/2201/1344.pbf"
|
||||
"tiles/v3/12/2330/1184.pbf"
|
||||
"tiles/v3/12/2330/1185.pbf"
|
||||
"tiles/v3/12/2330/1186.pbf"
|
||||
"tiles/v3/12/2331/1184.pbf"
|
||||
"tiles/v3/12/2331/1185.pbf"
|
||||
"tiles/v3/12/2331/1186.pbf"
|
||||
"tiles/v3/12/2332/1184.pbf"
|
||||
"tiles/v3/12/2332/1185.pbf"
|
||||
"tiles/v3/12/2332/1186.pbf"
|
||||
"tiles/v3/12/2930/1898.pbf"
|
||||
"tiles/v3/12/2930/1899.pbf"
|
||||
"tiles/v3/12/2930/1900.pbf"
|
||||
"tiles/v3/12/2931/1898.pbf"
|
||||
"tiles/v3/12/2931/1899.pbf"
|
||||
"tiles/v3/12/2931/1900.pbf"
|
||||
"tiles/v3/12/3429/1672.pbf"
|
||||
"tiles/v3/12/3429/1673.pbf"
|
||||
"tiles/v3/12/3429/1674.pbf"
|
||||
"tiles/v3/12/3430/1672.pbf"
|
||||
"tiles/v3/12/3430/1673.pbf"
|
||||
"tiles/v3/12/3430/1674.pbf"
|
||||
"tiles/v3/12/654/1582.pbf"
|
||||
"tiles/v3/12/654/1583.pbf"
|
||||
"tiles/v3/12/654/1584.pbf"
|
||||
"tiles/v3/12/655/1582.pbf"
|
||||
"tiles/v3/12/655/1583.pbf"
|
||||
"tiles/v3/12/655/1584.pbf"
|
||||
"tiles/v3/13/1309/3165.pbf"
|
||||
"tiles/v3/13/1309/3166.pbf"
|
||||
"tiles/v3/13/1309/3167.pbf"
|
||||
"tiles/v3/13/1310/3165.pbf"
|
||||
"tiles/v3/13/1310/3166.pbf"
|
||||
"tiles/v3/13/1310/3167.pbf"
|
||||
"tiles/v3/13/1311/3165.pbf"
|
||||
"tiles/v3/13/1311/3166.pbf"
|
||||
"tiles/v3/13/1311/3167.pbf"
|
||||
"tiles/v3/13/2342/3132.pbf"
|
||||
"tiles/v3/13/2342/3133.pbf"
|
||||
"tiles/v3/13/2342/3134.pbf"
|
||||
"tiles/v3/13/2343/3132.pbf"
|
||||
"tiles/v3/13/2343/3133.pbf"
|
||||
"tiles/v3/13/2343/3134.pbf"
|
||||
"tiles/v3/13/2406/4397.pbf"
|
||||
"tiles/v3/13/2406/4398.pbf"
|
||||
"tiles/v3/13/2406/4399.pbf"
|
||||
"tiles/v3/13/2407/4397.pbf"
|
||||
"tiles/v3/13/2407/4398.pbf"
|
||||
"tiles/v3/13/2407/4399.pbf"
|
||||
"tiles/v3/13/4206/2691.pbf"
|
||||
"tiles/v3/13/4206/2692.pbf"
|
||||
"tiles/v3/13/4206/2693.pbf"
|
||||
"tiles/v3/13/4207/2691.pbf"
|
||||
"tiles/v3/13/4207/2692.pbf"
|
||||
"tiles/v3/13/4207/2693.pbf"
|
||||
"tiles/v3/13/4208/2691.pbf"
|
||||
"tiles/v3/13/4208/2692.pbf"
|
||||
"tiles/v3/13/4208/2693.pbf"
|
||||
"tiles/v3/13/4400/2685.pbf"
|
||||
"tiles/v3/13/4400/2686.pbf"
|
||||
"tiles/v3/13/4400/2687.pbf"
|
||||
"tiles/v3/13/4401/2685.pbf"
|
||||
"tiles/v3/13/4401/2686.pbf"
|
||||
"tiles/v3/13/4401/2687.pbf"
|
||||
"tiles/v3/13/4662/2370.pbf"
|
||||
"tiles/v3/13/4662/2371.pbf"
|
||||
"tiles/v3/13/4662/2372.pbf"
|
||||
"tiles/v3/13/4663/2370.pbf"
|
||||
"tiles/v3/13/4663/2371.pbf"
|
||||
"tiles/v3/13/4663/2372.pbf"
|
||||
"tiles/v3/13/4664/2370.pbf"
|
||||
"tiles/v3/13/4664/2371.pbf"
|
||||
"tiles/v3/13/4664/2372.pbf"
|
||||
"tiles/v3/13/5860/3797.pbf"
|
||||
"tiles/v3/13/5860/3798.pbf"
|
||||
"tiles/v3/13/5860/3799.pbf"
|
||||
"tiles/v3/13/5861/3797.pbf"
|
||||
"tiles/v3/13/5861/3798.pbf"
|
||||
"tiles/v3/13/5861/3799.pbf"
|
||||
"tiles/v3/13/5862/3797.pbf"
|
||||
"tiles/v3/13/5862/3798.pbf"
|
||||
"tiles/v3/13/5862/3799.pbf"
|
||||
"tiles/v3/13/6859/3346.pbf"
|
||||
"tiles/v3/13/6859/3347.pbf"
|
||||
"tiles/v3/13/6859/3348.pbf"
|
||||
"tiles/v3/13/6860/3346.pbf"
|
||||
"tiles/v3/13/6860/3347.pbf"
|
||||
"tiles/v3/13/6860/3348.pbf"
|
||||
"tiles/v3/14/2619/6331.pbf"
|
||||
"tiles/v3/14/2620/6331.pbf"
|
||||
"tiles/v3/14/2621/6331.pbf"
|
||||
"tiles/v3/14/4685/6266.pbf"
|
||||
"tiles/v3/14/4685/6267.pbf"
|
||||
"tiles/v3/14/4685/6268.pbf"
|
||||
"tiles/v3/14/4686/6266.pbf"
|
||||
"tiles/v3/14/4686/6267.pbf"
|
||||
"tiles/v3/14/4686/6268.pbf"
|
||||
"tiles/v3/14/4813/8795.pbf"
|
||||
"tiles/v3/14/4813/8796.pbf"
|
||||
"tiles/v3/14/4813/8797.pbf"
|
||||
"tiles/v3/14/4814/8795.pbf"
|
||||
"tiles/v3/14/4814/8796.pbf"
|
||||
"tiles/v3/14/4814/8797.pbf"
|
||||
"tiles/v3/14/8414/5383.pbf"
|
||||
"tiles/v3/14/8414/5384.pbf"
|
||||
"tiles/v3/14/8414/5385.pbf"
|
||||
"tiles/v3/14/8415/5383.pbf"
|
||||
"tiles/v3/14/8415/5384.pbf"
|
||||
"tiles/v3/14/8415/5385.pbf"
|
||||
"tiles/v3/14/8801/5372.pbf"
|
||||
"tiles/v3/14/8801/5373.pbf"
|
||||
"tiles/v3/14/8801/5374.pbf"
|
||||
"tiles/v3/14/8802/5372.pbf"
|
||||
"tiles/v3/14/8802/5373.pbf"
|
||||
"tiles/v3/14/8802/5374.pbf"
|
||||
"tiles/v3/14/9326/4741.pbf"
|
||||
"tiles/v3/14/9326/4742.pbf"
|
||||
"tiles/v3/14/9326/4743.pbf"
|
||||
"tiles/v3/14/9327/4741.pbf"
|
||||
"tiles/v3/14/9327/4742.pbf"
|
||||
"tiles/v3/14/9327/4743.pbf"
|
||||
"tiles/v3/14/11722/7595.pbf"
|
||||
"tiles/v3/14/11722/7596.pbf"
|
||||
"tiles/v3/14/11722/7597.pbf"
|
||||
"tiles/v3/14/11723/7595.pbf"
|
||||
"tiles/v3/14/11723/7596.pbf"
|
||||
"tiles/v3/14/11723/7597.pbf"
|
||||
"tiles/v3/14/11724/7595.pbf"
|
||||
"tiles/v3/14/11724/7596.pbf"
|
||||
"tiles/v3/14/11724/7597.pbf"
|
||||
"tiles/v3/14/13719/6693.pbf"
|
||||
"tiles/v3/14/13719/6694.pbf"
|
||||
"tiles/v3/14/13719/6695.pbf"
|
||||
"tiles/v3/14/13720/6693.pbf"
|
||||
"tiles/v3/14/13720/6694.pbf"
|
||||
"tiles/v3/14/13720/6695.pbf"
|
||||
"tiles/v3/14/13721/6693.pbf"
|
||||
"tiles/v3/14/13721/6694.pbf"
|
||||
"tiles/v3/14/13721/6695.pbf"
|
||||
)
|
||||
|
||||
for OUTPUT in ${LIST[@]} ; do
|
||||
|
||||
@@ -14,6 +14,10 @@
|
||||
#include "parser.hpp"
|
||||
#include "runner.hpp"
|
||||
|
||||
#if MLN_RENDER_BACKEND_METAL
|
||||
#include <mbgl/gfx/backend.hpp>
|
||||
#endif // MLN_RENDER_BACKEND_METAL
|
||||
|
||||
#ifdef SHOW_ANSI_COLORS
|
||||
#define ANSI_COLOR_RED "\x1b[31m"
|
||||
#define ANSI_COLOR_GREEN "\x1b[32m"
|
||||
@@ -159,6 +163,11 @@ int runRenderTests(int argc, char** argv, std::function<void()> testStatus) {
|
||||
|
||||
NetworkStatus::Set(online ? NetworkStatus::Status::Online : NetworkStatus::Status::Offline);
|
||||
|
||||
#if MLN_RENDER_BACKEND_METAL
|
||||
printf(ANSI_COLOR_YELLOW "Using GPU Expression Evaluation" ANSI_COLOR_RESET "\n");
|
||||
mbgl::gfx::Backend::setEnableGPUExpressionEval(true);
|
||||
#endif // MLN_RENDER_BACKEND_METAL
|
||||
|
||||
const auto& manifest = runner.getManifest();
|
||||
const auto& ignores = manifest.getIgnores();
|
||||
const auto& testPaths = manifest.getTestPaths();
|
||||
|
||||
183
src/mbgl/gfx/gpu_expression.cpp
Normal file
183
src/mbgl/gfx/gpu_expression.cpp
Normal file
@@ -0,0 +1,183 @@
|
||||
#include <mbgl/gfx/gpu_expression.hpp>
|
||||
|
||||
#include <mbgl/renderer/paint_property_binder.hpp>
|
||||
#include <mbgl/style/expression/expression.hpp>
|
||||
#include <mbgl/style/expression/interpolate.hpp>
|
||||
#include <mbgl/style/expression/step.hpp>
|
||||
#include <mbgl/style/expression/value.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace gfx {
|
||||
|
||||
using namespace style::expression;
|
||||
|
||||
namespace {
|
||||
|
||||
inline GPUOutputType getOutputType(const Expression& expression) {
|
||||
if (expression.getType().is<type::NumberType>()) {
|
||||
return GPUOutputType::Float;
|
||||
} else {
|
||||
return GPUOutputType::Color;
|
||||
}
|
||||
}
|
||||
|
||||
inline GPUInterpType getInterpType(const Interpolator& interp) {
|
||||
return interp.match(
|
||||
[&](const ExponentialInterpolator& exp) {
|
||||
return (exp.base == 1.0f) ? GPUInterpType::Linear : GPUInterpType::Exponential;
|
||||
},
|
||||
[&](const CubicBezierInterpolator&) { return GPUInterpType::Bezier; });
|
||||
}
|
||||
|
||||
inline float getInterpBase(const Interpolator& interp) {
|
||||
return interp.match([&](const ExponentialInterpolator& exp) { return static_cast<float>(exp.base); },
|
||||
[&](const CubicBezierInterpolator&) { return 0.0f; });
|
||||
}
|
||||
|
||||
// Produce a function for `eachStop` that extracts a single stop into the target expression
|
||||
auto addStop(UniqueGPUExpression& expr, GPUOutputType outType, std::size_t& index) {
|
||||
return [&, outType](double input, const Expression& output) {
|
||||
if (expr) {
|
||||
if (const auto result = output.evaluate(EvaluationContext{/*zoom=*/0.0f})) {
|
||||
const style::expression::Value& value = *result;
|
||||
expr->inputs[index] = static_cast<float>(input);
|
||||
if (outType == GPUOutputType::Float) {
|
||||
assert(value.is<double>());
|
||||
if (value.is<double>()) {
|
||||
expr->stops.floats[index++] = static_cast<float>(value.get<double>());
|
||||
} else {
|
||||
// Evaluation error, cancel
|
||||
expr.reset();
|
||||
}
|
||||
} else if (outType == GPUOutputType::Color) {
|
||||
assert(value.is<Color>());
|
||||
if (value.is<Color>()) {
|
||||
const auto& color = attributeValue(value.get<Color>());
|
||||
std::copy(color.begin(), color.end(), &expr->stops.colors[2 * index++]);
|
||||
} else {
|
||||
// Evaluation error, cancel
|
||||
expr.reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
const GPUExpression GPUExpression::empty = {GPUOutputType::Float, 0};
|
||||
|
||||
UniqueGPUExpression GPUExpression::create(GPUOutputType type, std::uint16_t count) {
|
||||
if (1 < count && count <= maxStops) {
|
||||
return std::make_unique<GPUExpression>(type, count);
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
UniqueGPUExpression GPUExpression::create(const Expression& expression, const ZoomCurvePtr& zoomCurve, bool intZoom) {
|
||||
std::size_t index = 0;
|
||||
const auto outType = getOutputType(expression);
|
||||
const auto options = (intZoom ? GPUOptions::IntegerZoom : GPUOptions::None);
|
||||
return zoomCurve.match(
|
||||
[&](const Step* step) {
|
||||
if (step->getStopCount() > maxStops) {
|
||||
return UniqueGPUExpression{};
|
||||
}
|
||||
auto expr = GPUExpression::create(outType, step->getStopCount());
|
||||
expr->options = options;
|
||||
expr->interpolation = GPUInterpType::Step;
|
||||
step->eachStop(addStop(expr, outType, index));
|
||||
return expr;
|
||||
},
|
||||
[&](const Interpolate* interp) {
|
||||
if (interp->getStopCount() > maxStops) {
|
||||
return UniqueGPUExpression{};
|
||||
}
|
||||
auto expr = GPUExpression::create(outType, interp->getStopCount());
|
||||
expr->options = options;
|
||||
expr->interpolation = getInterpType(interp->getInterpolator());
|
||||
expr->interpOptions.exponential.base = getInterpBase(interp->getInterpolator());
|
||||
interp->eachStop(addStop(expr, outType, index));
|
||||
return expr;
|
||||
},
|
||||
[](std::nullptr_t) { return UniqueGPUExpression{}; });
|
||||
}
|
||||
|
||||
float GPUExpression::evaluateFloat(const float zoom) const {
|
||||
const auto index = std::distance(&inputs[0], std::upper_bound(&inputs[0], &inputs[stopCount], zoom));
|
||||
if (index == 0) {
|
||||
return stops.floats[0];
|
||||
} else if (index == stopCount) {
|
||||
return stops.floats[stopCount - 1];
|
||||
}
|
||||
switch (interpolation) {
|
||||
case GPUInterpType::Step:
|
||||
return stops.floats[index - 1];
|
||||
default:
|
||||
assert(false);
|
||||
[[fallthrough]];
|
||||
case GPUInterpType::Linear:
|
||||
assert(interpOptions.exponential.base == 1.0f);
|
||||
[[fallthrough]];
|
||||
case GPUInterpType::Exponential: {
|
||||
const Range<double> range{inputs[index - 1], inputs[index]};
|
||||
const ExponentialInterpolator interpolator{interpOptions.exponential.base};
|
||||
const auto t = interpolator.interpolationFactor(range, zoom);
|
||||
return util::Interpolator<float>()(stops.floats[index - 1], stops.floats[index], t);
|
||||
}
|
||||
case GPUInterpType::Bezier:
|
||||
assert(false);
|
||||
return stops.floats[0];
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
std::tuple<float, float> unpack_float(const float packedValue) {
|
||||
const int packedIntValue = int(packedValue);
|
||||
const int v0 = packedIntValue / 256;
|
||||
return {static_cast<float>(v0) / 255, static_cast<float>(packedIntValue - v0 * 256) / 255};
|
||||
}
|
||||
std::tuple<float, float, float, float> decode_color(const float encoded[2]) {
|
||||
return std::tuple_cat(unpack_float(encoded[0]), unpack_float(encoded[1]));
|
||||
}
|
||||
Color toColor(std::tuple<float, float, float, float> rgba) {
|
||||
return {std::get<0>(rgba), std::get<1>(rgba), std::get<2>(rgba), std::get<3>(rgba)};
|
||||
}
|
||||
} // namespace
|
||||
|
||||
Color GPUExpression::getColor(std::size_t index) const {
|
||||
return toColor(decode_color(&stops.colors[2 * index]));
|
||||
}
|
||||
|
||||
Color GPUExpression::evaluateColor(const float zoom) const {
|
||||
const auto index = std::distance(&inputs[0], std::upper_bound(&inputs[0], &inputs[stopCount], zoom));
|
||||
if (index == 0) {
|
||||
return getColor(0);
|
||||
} else if (index == stopCount) {
|
||||
return getColor(stopCount - 1);
|
||||
}
|
||||
switch (interpolation) {
|
||||
case GPUInterpType::Step:
|
||||
return getColor(index - 1);
|
||||
default:
|
||||
assert(false);
|
||||
[[fallthrough]];
|
||||
case GPUInterpType::Linear:
|
||||
assert(interpOptions.exponential.base == 1.0f);
|
||||
[[fallthrough]];
|
||||
case GPUInterpType::Exponential: {
|
||||
const Range<double> range{inputs[index - 1], inputs[index]};
|
||||
const ExponentialInterpolator interpolator{interpOptions.exponential.base};
|
||||
const auto t = interpolator.interpolationFactor(range, zoom);
|
||||
return util::Interpolator<Color>()(getColor(index - 1), getColor(index), t);
|
||||
break;
|
||||
}
|
||||
case GPUInterpType::Bezier:
|
||||
assert(false);
|
||||
return getColor(0);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace mbgl
|
||||
@@ -57,23 +57,44 @@ RenderingStats& RenderingStats::operator+=(const RenderingStats& r) {
|
||||
}
|
||||
|
||||
#if !defined(NDEBUG)
|
||||
template <typename T>
|
||||
std::ostream& optionalStatLine(std::ostream& stream, T value, std::string_view label, std::string_view sep) {
|
||||
if (value) {
|
||||
stream << label << " = " << value << sep;
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
std::string RenderingStats::toString(std::string_view sep) const {
|
||||
std::stringstream ss;
|
||||
ss << "numFrames = " << numFrames << sep << "numDrawCalls = " << numDrawCalls << sep
|
||||
<< "totalDrawCalls = " << totalDrawCalls << sep << "numCreatedTextures = " << numCreatedTextures << sep
|
||||
<< "numActiveTextures = " << numActiveTextures << sep << "numTextureBindings = " << numTextureBindings << sep
|
||||
<< "numTextureUpdates = " << numTextureUpdates << sep << "textureUpdateBytes = " << textureUpdateBytes << sep
|
||||
<< "totalBuffers = " << totalBuffers << sep << "totalBufferObjs = " << totalBufferObjs << sep
|
||||
<< "bufferUpdates = " << bufferUpdates << sep << "bufferObjUpdates = " << bufferObjUpdates << sep
|
||||
<< "bufferUpdateBytes = " << bufferUpdateBytes << sep << "numBuffers = " << numBuffers << sep
|
||||
<< "numFrameBuffers = " << numFrameBuffers << sep << "numIndexBuffers = " << numIndexBuffers << sep
|
||||
<< "indexUpdateBytes = " << indexUpdateBytes << sep << "numVertexBuffers = " << numVertexBuffers << sep
|
||||
<< "vertexUpdateBytes = " << vertexUpdateBytes << sep << "numUniformBuffers = " << numUniformBuffers << sep
|
||||
<< "numUniformUpdates = " << numUniformUpdates << sep << "uniformUpdateBytes = " << uniformUpdateBytes << sep
|
||||
<< "memTextures = " << memTextures << sep << "memBuffers = " << memBuffers << sep
|
||||
<< "memIndexBuffers = " << memIndexBuffers << sep << "memVertexBuffers = " << memVertexBuffers << sep
|
||||
<< "memUniformBuffers = " << memUniformBuffers << sep << "stencilClears = " << stencilClears << sep
|
||||
<< "stencilUpdates = " << stencilUpdates << sep;
|
||||
optionalStatLine(ss, numFrames, "numFrames", sep);
|
||||
optionalStatLine(ss, numDrawCalls, "numDrawCalls", sep);
|
||||
optionalStatLine(ss, totalDrawCalls, "totalDrawCalls", sep);
|
||||
optionalStatLine(ss, numCreatedTextures, "numCreatedTextures", sep);
|
||||
optionalStatLine(ss, numActiveTextures, "numActiveTextures", sep);
|
||||
optionalStatLine(ss, numTextureBindings, "numTextureBindings", sep);
|
||||
optionalStatLine(ss, numTextureUpdates, "numTextureUpdates", sep);
|
||||
optionalStatLine(ss, textureUpdateBytes, "textureUpdateBytes", sep);
|
||||
optionalStatLine(ss, totalBuffers, "totalBuffers", sep);
|
||||
optionalStatLine(ss, totalBufferObjs, "totalBufferObjs", sep);
|
||||
optionalStatLine(ss, bufferUpdates, "bufferUpdates", sep);
|
||||
optionalStatLine(ss, bufferObjUpdates, "bufferObjUpdates", sep);
|
||||
optionalStatLine(ss, bufferUpdateBytes, "bufferUpdateBytes", sep);
|
||||
optionalStatLine(ss, numBuffers, "numBuffers", sep);
|
||||
optionalStatLine(ss, numFrameBuffers, "numFrameBuffers", sep);
|
||||
optionalStatLine(ss, numIndexBuffers, "numIndexBuffers", sep);
|
||||
optionalStatLine(ss, indexUpdateBytes, "indexUpdateBytes", sep);
|
||||
optionalStatLine(ss, numVertexBuffers, "numVertexBuffers", sep);
|
||||
optionalStatLine(ss, vertexUpdateBytes, "vertexUpdateBytes", sep);
|
||||
optionalStatLine(ss, numUniformBuffers, "numUniformBuffers", sep);
|
||||
optionalStatLine(ss, numUniformUpdates, "numUniformUpdates", sep);
|
||||
optionalStatLine(ss, uniformUpdateBytes, "uniformUpdateBytes", sep);
|
||||
optionalStatLine(ss, memTextures, "memTextures", sep);
|
||||
optionalStatLine(ss, memBuffers, "memBuffers", sep);
|
||||
optionalStatLine(ss, memIndexBuffers, "memIndexBuffers", sep);
|
||||
optionalStatLine(ss, memVertexBuffers, "memVertexBuffers", sep);
|
||||
optionalStatLine(ss, memUniformBuffers, "memUniformBuffers", sep);
|
||||
optionalStatLine(ss, stencilClears, "stencilClears", sep);
|
||||
optionalStatLine(ss, stencilUpdates, "stencilUpdates", sep);
|
||||
return ss.str();
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -22,8 +22,7 @@ void logStyleDependencies(EventSeverity severity, Event event, const style::Styl
|
||||
counts[0]++;
|
||||
} else {
|
||||
for (size_t i = 0; i < maskCount; ++i) {
|
||||
const auto mask = Dependency{1u << i};
|
||||
if ((deps & mask) == mask) {
|
||||
if (deps & Dependency{1u << i}) {
|
||||
counts[i + 1]++;
|
||||
}
|
||||
}
|
||||
@@ -33,7 +32,9 @@ void logStyleDependencies(EventSeverity severity, Event event, const style::Styl
|
||||
ss << "Style '" << style.getName() << "' has " << layers.size() << " layers:\n";
|
||||
ss << " " << Dependency::None << ": " << counts[0] << "\n";
|
||||
for (size_t i = 0; i < maskCount; ++i) {
|
||||
ss << " " << Dependency{1u << i} << ": " << counts[i + 1] << "\n";
|
||||
if (counts[i + 1]) {
|
||||
ss << " " << Dependency{1u << i} << ": " << counts[i + 1] << "\n";
|
||||
}
|
||||
}
|
||||
Log::Record(severity, event, ss.str());
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ template <typename T>
|
||||
class CrossFadedPropertyEvaluator {
|
||||
public:
|
||||
using ResultType = Faded<T>;
|
||||
static constexpr bool useIntegerZoom = false;
|
||||
|
||||
CrossFadedPropertyEvaluator(const PropertyEvaluationParameters& parameters_, T defaultValue_)
|
||||
: parameters(parameters_),
|
||||
|
||||
@@ -9,10 +9,11 @@
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
template <typename T, bool useIntegerZoom = false>
|
||||
template <typename T, bool useIntegerZoom_ = false>
|
||||
class DataDrivenPropertyEvaluator {
|
||||
public:
|
||||
using ResultType = PossiblyEvaluatedPropertyValue<T>;
|
||||
static constexpr bool useIntegerZoom = useIntegerZoom_;
|
||||
|
||||
DataDrivenPropertyEvaluator(const PropertyEvaluationParameters& parameters_, T defaultValue_)
|
||||
: parameters(parameters_),
|
||||
@@ -26,7 +27,7 @@ public:
|
||||
if constexpr (useIntegerZoom) { // Compiler will optimize out the unused branch.
|
||||
if (!expression.isFeatureConstant() || !expression.isRuntimeConstant()) {
|
||||
auto returnExpression = expression;
|
||||
returnExpression.useIntegerZoom = true;
|
||||
returnExpression.setUseIntegerZoom(true);
|
||||
return ResultType(returnExpression);
|
||||
}
|
||||
return ResultType(expression.evaluate(std::floor(parameters.z)));
|
||||
@@ -47,6 +48,7 @@ template <typename T>
|
||||
class DataDrivenPropertyEvaluator<Faded<T>> {
|
||||
public:
|
||||
using ResultType = PossiblyEvaluatedPropertyValue<Faded<T>>;
|
||||
static constexpr bool useIntegerZoom = false;
|
||||
|
||||
DataDrivenPropertyEvaluator(const PropertyEvaluationParameters& parameters_, T defaultValue_)
|
||||
: parameters(parameters_),
|
||||
|
||||
@@ -15,6 +15,8 @@ ImagePosition::ImagePosition(const mapbox::Bin& bin, const style::Image::Impl& i
|
||||
stretchY(image.stretchY),
|
||||
content(image.content) {}
|
||||
|
||||
namespace {
|
||||
|
||||
const mapbox::Bin& _packImage(mapbox::ShelfPack& pack,
|
||||
const style::Image::Impl& image,
|
||||
ImageAtlas& resultImage,
|
||||
@@ -26,12 +28,13 @@ const mapbox::Bin& _packImage(mapbox::ShelfPack& pack,
|
||||
|
||||
PremultipliedImage::copy(
|
||||
image.image, resultImage.image, {0, 0}, {bin.x + padding, bin.y + padding}, image.image.size);
|
||||
uint32_t x = bin.x + padding;
|
||||
uint32_t y = bin.y + padding;
|
||||
uint32_t w = image.image.size.width;
|
||||
uint32_t h = image.image.size.height;
|
||||
|
||||
if (imageType == ImageType::Pattern) {
|
||||
const uint32_t x = bin.x + padding;
|
||||
const uint32_t y = bin.y + padding;
|
||||
const uint32_t w = image.image.size.width;
|
||||
const uint32_t h = image.image.size.height;
|
||||
|
||||
// Add 1 pixel wrapped padding on each side of the image.
|
||||
PremultipliedImage::copy(image.image, resultImage.image, {0, h - 1}, {x, y - 1}, {w, 1}); // T
|
||||
PremultipliedImage::copy(image.image, resultImage.image, {0, 0}, {x, y + h}, {w, 1}); // B
|
||||
@@ -41,8 +44,6 @@ const mapbox::Bin& _packImage(mapbox::ShelfPack& pack,
|
||||
return bin;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
void populateImagePatches(ImagePositions& imagePositions,
|
||||
const ImageManager& imageManager,
|
||||
std::vector<ImagePatch>& /*out*/ patches) {
|
||||
|
||||
@@ -10,7 +10,9 @@
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
static ImageManagerObserver nullObserver;
|
||||
namespace {
|
||||
ImageManagerObserver nullObserver;
|
||||
} // namespace
|
||||
|
||||
ImageManager::ImageManager() = default;
|
||||
|
||||
|
||||
@@ -23,30 +23,135 @@ namespace mbgl {
|
||||
using namespace style;
|
||||
using namespace shaders;
|
||||
|
||||
#if MLN_RENDER_BACKEND_METAL && !defined(NDEBUG)
|
||||
constexpr bool diff(float actual, float expected, float e = 1.0e-6) {
|
||||
return actual != expected && (expected == 0 || std::fabs((actual - expected) / expected) > e);
|
||||
}
|
||||
constexpr bool diff(Color actual, Color expected, float e = 1.0e-6) {
|
||||
return diff(actual.r, expected.r, e) || diff(actual.g, expected.g, e) || diff(actual.b, expected.b, e) ||
|
||||
diff(actual.a, expected.a, e);
|
||||
}
|
||||
#endif // MLN_RENDER_BACKEND_METAL
|
||||
|
||||
#if MLN_RENDER_BACKEND_METAL && !defined(NDEBUG)
|
||||
template <typename Result>
|
||||
std::optional<Result> LineLayerTweaker::gpuEvaluate(const LinePaintProperties::PossiblyEvaluated& evaluated,
|
||||
const PaintParameters& parameters,
|
||||
const std::size_t index) const {
|
||||
if (const auto& gpu = gpuExpressions[index]) {
|
||||
const float effectiveZoom = (gpu->options & gfx::GPUOptions::IntegerZoom)
|
||||
? parameters.state.getIntegerZoom()
|
||||
: static_cast<float>(parameters.state.getZoom());
|
||||
return gpu->template evaluate<Result>(effectiveZoom);
|
||||
}
|
||||
return {};
|
||||
}
|
||||
#endif // MLN_RENDER_BACKEND_METAL
|
||||
|
||||
template <typename Property>
|
||||
auto LineLayerTweaker::evaluate([[maybe_unused]] const PaintParameters& parameters) const {
|
||||
const auto& evaluated = static_cast<const LineLayerProperties&>(*evaluatedProperties).evaluated;
|
||||
|
||||
#if MLN_RENDER_BACKEND_METAL && !defined(NDEBUG)
|
||||
constexpr auto index = propertyIndex<Property>();
|
||||
if (auto gpuValue = gpuEvaluate<typename Property::Type>(evaluated, parameters, index)) {
|
||||
assert(!diff(*gpuValue, evaluated.get<Property>().constantOr(Property::defaultValue())));
|
||||
return *gpuValue;
|
||||
}
|
||||
#endif // MLN_RENDER_BACKEND_METAL
|
||||
|
||||
return evaluated.get<Property>().constantOr(Property::defaultValue());
|
||||
}
|
||||
|
||||
void LineLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintParameters& parameters) {
|
||||
auto& context = parameters.context;
|
||||
const auto zoom = parameters.state.getZoom();
|
||||
const auto& evaluated = static_cast<const LineLayerProperties&>(*evaluatedProperties).evaluated;
|
||||
const auto& crossfade = static_cast<const LineLayerProperties&>(*evaluatedProperties).crossfade;
|
||||
|
||||
// Each property UBO is updated at most once if new evaluated properties were set
|
||||
const auto zoom = static_cast<float>(parameters.state.getZoom());
|
||||
const auto intZoom = parameters.state.getIntegerZoom();
|
||||
|
||||
#if MLN_RENDER_BACKEND_METAL
|
||||
const auto getExpressionBuffer = [&]() {
|
||||
const bool enableEval = gfx::Backend::getEnableGPUExpressionEval();
|
||||
if (!expressionUniformBuffer || (gpuExpressionsUpdated && enableEval)) {
|
||||
LineExpressionUBO exprUBO = {
|
||||
/* color = */ enableEval ? gpuExpressions[propertyIndex<LineColor>()].get() : nullptr,
|
||||
/* blur = */ enableEval ? gpuExpressions[propertyIndex<LineBlur>()].get() : nullptr,
|
||||
/* opacity = */ enableEval ? gpuExpressions[propertyIndex<LineOpacity>()].get() : nullptr,
|
||||
/* gapwidth = */ enableEval ? gpuExpressions[propertyIndex<LineGapWidth>()].get() : nullptr,
|
||||
/* offset = */ enableEval ? gpuExpressions[propertyIndex<LineOffset>()].get() : nullptr,
|
||||
/* width = */ enableEval ? gpuExpressions[propertyIndex<LineWidth>()].get() : nullptr,
|
||||
/* floorWidth = */ enableEval ? gpuExpressions[propertyIndex<LineFloorWidth>()].get() : nullptr,
|
||||
};
|
||||
context.emplaceOrUpdateUniformBuffer(expressionUniformBuffer, &exprUBO);
|
||||
gpuExpressionsUpdated = false;
|
||||
}
|
||||
return expressionUniformBuffer;
|
||||
};
|
||||
#endif // MLN_RENDER_BACKEND_METAL
|
||||
|
||||
if (!evaluatedPropsUniformBuffer || propertiesUpdated) {
|
||||
const LineEvaluatedPropsUBO propsUBO = {
|
||||
/*color =*/evaluated.get<LineColor>().constantOr(LineColor::defaultValue()),
|
||||
/*blur =*/evaluated.get<LineBlur>().constantOr(LineBlur::defaultValue()),
|
||||
/*opacity =*/evaluated.get<LineOpacity>().constantOr(LineOpacity::defaultValue()),
|
||||
/*gapwidth =*/evaluated.get<LineGapWidth>().constantOr(LineGapWidth::defaultValue()),
|
||||
/*offset =*/evaluated.get<LineOffset>().constantOr(LineOffset::defaultValue()),
|
||||
/*width =*/evaluated.get<LineWidth>().constantOr(LineWidth::defaultValue()),
|
||||
/*floorwidth =*/evaluated.get<LineFloorWidth>().constantOr(LineFloorWidth::defaultValue()),
|
||||
0,
|
||||
#if MLN_RENDER_BACKEND_METAL
|
||||
expressionMask =
|
||||
!gfx::Backend::getEnableGPUExpressionEval()
|
||||
? LineExpressionMask::None
|
||||
: ((gpuExpressions[propertyIndex<LineColor>()] ? LineExpressionMask::Color : LineExpressionMask::None) |
|
||||
(gpuExpressions[propertyIndex<LineBlur>()] ? LineExpressionMask::Blur : LineExpressionMask::None) |
|
||||
(gpuExpressions[propertyIndex<LineOpacity>()] ? LineExpressionMask::Opacity
|
||||
: LineExpressionMask::None) |
|
||||
(gpuExpressions[propertyIndex<LineGapWidth>()] ? LineExpressionMask::GapWidth
|
||||
: LineExpressionMask::None) |
|
||||
(gpuExpressions[propertyIndex<LineOffset>()] ? LineExpressionMask::Offset
|
||||
: LineExpressionMask::None) |
|
||||
(gpuExpressions[propertyIndex<LineWidth>()] ? LineExpressionMask::Width : LineExpressionMask::None) |
|
||||
(gpuExpressions[propertyIndex<LineFloorWidth>()] ? LineExpressionMask::FloorWidth
|
||||
: LineExpressionMask::None));
|
||||
const LineEvaluatedPropsUBO propsUBO{
|
||||
/*color =*/(expressionMask & LineExpressionMask::Color) ? LineColor::defaultValue()
|
||||
: evaluate<LineColor>(parameters),
|
||||
/*blur =*/
|
||||
(expressionMask & LineExpressionMask::Blur) ? LineBlur::defaultValue() : evaluate<LineBlur>(parameters),
|
||||
/*opacity =*/
|
||||
(expressionMask & LineExpressionMask::Opacity) ? LineOpacity::defaultValue()
|
||||
: evaluate<LineOpacity>(parameters),
|
||||
/*gapwidth =*/
|
||||
(expressionMask & LineExpressionMask::GapWidth) ? LineGapWidth::defaultValue()
|
||||
: evaluate<LineGapWidth>(parameters),
|
||||
/*offset =*/
|
||||
(expressionMask & LineExpressionMask::Offset) ? LineOffset::defaultValue()
|
||||
: evaluate<LineOffset>(parameters),
|
||||
/*width =*/
|
||||
(expressionMask & LineExpressionMask::Width) ? LineWidth::defaultValue() : evaluate<LineWidth>(parameters),
|
||||
/*floorwidth =*/
|
||||
(expressionMask & LineExpressionMask::FloorWidth) ? LineFloorWidth::defaultValue()
|
||||
: evaluate<LineFloorWidth>(parameters),
|
||||
expressionMask,
|
||||
0};
|
||||
#else
|
||||
const LineEvaluatedPropsUBO propsUBO{/*color =*/evaluate<LineColor>(parameters),
|
||||
/*blur =*/evaluate<LineBlur>(parameters),
|
||||
/*opacity =*/evaluate<LineOpacity>(parameters),
|
||||
/*gapwidth =*/evaluate<LineGapWidth>(parameters),
|
||||
/*offset =*/evaluate<LineOffset>(parameters),
|
||||
/*width =*/evaluate<LineWidth>(parameters),
|
||||
/*floorwidth =*/evaluate<LineFloorWidth>(parameters),
|
||||
LineExpressionMask::None,
|
||||
0};
|
||||
#endif // MLN_RENDER_BACKEND_METAL
|
||||
|
||||
context.emplaceOrUpdateUniformBuffer(evaluatedPropsUniformBuffer, &propsUBO);
|
||||
propertiesUpdated = false;
|
||||
}
|
||||
auto& layerUniforms = layerGroup.mutableUniformBuffers();
|
||||
|
||||
layerUniforms.set(idLineEvaluatedPropsUBO, evaluatedPropsUniformBuffer);
|
||||
|
||||
#if MLN_RENDER_BACKEND_METAL
|
||||
// GPU Expressions
|
||||
layerUniforms.set(idLineExpressionUBO, getExpressionBuffer());
|
||||
#endif // MLN_RENDER_BACKEND_METAL
|
||||
|
||||
visitLayerGroupDrawables(layerGroup, [&](gfx::Drawable& drawable) {
|
||||
const auto shader = drawable.getShader();
|
||||
if (!drawable.getTileID() || !shader || !checkTweakDrawable(drawable)) {
|
||||
@@ -83,7 +188,6 @@ void LineLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintParameters
|
||||
0,
|
||||
0};
|
||||
drawableUniforms.createOrUpdate(idLineDrawableUBO, &drawableUBO, context);
|
||||
;
|
||||
} break;
|
||||
|
||||
case LineType::Pattern: {
|
||||
@@ -95,7 +199,7 @@ void LineLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintParameters
|
||||
/*matrix =*/util::cast<float>(matrix),
|
||||
/*scale =*/
|
||||
{parameters.pixelRatio,
|
||||
1 / tileID.pixelsToTileUnits(1, parameters.state.getIntegerZoom()),
|
||||
1 / tileID.pixelsToTileUnits(1, intZoom),
|
||||
crossfade.fromScale,
|
||||
crossfade.toScale},
|
||||
/*texsize =*/{static_cast<float>(textureSize.width), static_cast<float>(textureSize.height)},
|
||||
@@ -128,12 +232,10 @@ void LineLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintParameters
|
||||
const LineSDFDrawableUBO drawableUBO{
|
||||
/* matrix = */ util::cast<float>(matrix),
|
||||
/* patternscale_a = */
|
||||
{1.0f / tileID.pixelsToTileUnits(widthA, parameters.state.getIntegerZoom()),
|
||||
-posA.height / 2.0f},
|
||||
{1.0f / tileID.pixelsToTileUnits(widthA, intZoom), -posA.height / 2.0f},
|
||||
/* patternscale_b = */
|
||||
{1.0f / tileID.pixelsToTileUnits(widthB, parameters.state.getIntegerZoom()),
|
||||
-posB.height / 2.0f},
|
||||
/* ratio = */ 1.0f / tileID.pixelsToTileUnits(1.0f, static_cast<float>(zoom)),
|
||||
{1.0f / tileID.pixelsToTileUnits(widthB, intZoom), -posB.height / 2.0f},
|
||||
/* ratio = */ 1.0f / tileID.pixelsToTileUnits(1.0f, zoom),
|
||||
/* tex_y_a = */ posA.y,
|
||||
/* tex_y_b = */ posB.y,
|
||||
/* sdfgamma = */ static_cast<float>(dashPatternTexture.getSize().width) /
|
||||
@@ -155,4 +257,18 @@ void LineLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintParameters
|
||||
});
|
||||
}
|
||||
|
||||
#if MLN_RENDER_BACKEND_METAL
|
||||
void LineLayerTweaker::updateGPUExpressions(const Unevaluated& unevaluated, TimePoint now) {
|
||||
if (gfx::Backend::getEnableGPUExpressionEval()) {
|
||||
if (unevaluated.updateGPUExpressions(gpuExpressions, now)) {
|
||||
gpuExpressionsUpdated = true;
|
||||
|
||||
// Masks also need to be updated
|
||||
propertiesUpdated = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // MLN_RENDER_BACKEND_METAL
|
||||
|
||||
} // namespace mbgl
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/renderer/layer_tweaker.hpp>
|
||||
#include <mbgl/style/layers/line_layer_properties.hpp>
|
||||
|
||||
#include <string_view>
|
||||
#if MLN_RENDER_BACKEND_METAL
|
||||
#include <mbgl/shaders/line_layer_ubo.hpp>
|
||||
#endif // MLN_RENDER_BACKEND_METAL
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
@@ -30,8 +35,37 @@ public:
|
||||
|
||||
void execute(LayerGroupBase&, const PaintParameters&) override;
|
||||
|
||||
#if MLN_RENDER_BACKEND_METAL
|
||||
using LinePaintProperties = style::LinePaintProperties;
|
||||
using Unevaluated = LinePaintProperties::Unevaluated;
|
||||
void updateGPUExpressions(const Unevaluated&, TimePoint now);
|
||||
|
||||
template <typename T>
|
||||
static constexpr std::size_t propertyIndex() {
|
||||
return LinePaintProperties::Tuple<LinePaintProperties::PropertyTypes>::getIndex<T>();
|
||||
}
|
||||
#endif // MLN_RENDER_BACKEND_METAL
|
||||
|
||||
private:
|
||||
template <typename Property>
|
||||
auto evaluate(const PaintParameters& parameters) const;
|
||||
|
||||
#if MLN_RENDER_BACKEND_METAL
|
||||
template <typename Result>
|
||||
std::optional<Result> gpuEvaluate(const LinePaintProperties::PossiblyEvaluated&,
|
||||
const PaintParameters&,
|
||||
const std::size_t index) const;
|
||||
#endif // MLN_RENDER_BACKEND_METAL
|
||||
|
||||
protected:
|
||||
gfx::UniformBufferPtr evaluatedPropsUniformBuffer;
|
||||
|
||||
#if MLN_RENDER_BACKEND_METAL
|
||||
gfx::UniformBufferPtr expressionUniformBuffer;
|
||||
Unevaluated::GPUExpressions gpuExpressions;
|
||||
shaders::LineExpressionMask expressionMask = shaders::LineExpressionMask::None;
|
||||
bool gpuExpressionsUpdated = true;
|
||||
#endif // MLN_RENDER_BACKEND_METAL
|
||||
};
|
||||
|
||||
} // namespace mbgl
|
||||
|
||||
@@ -53,7 +53,8 @@ void RenderBackgroundLayer::transition(const TransitionParameters& parameters) {
|
||||
}
|
||||
|
||||
void RenderBackgroundLayer::evaluate(const PropertyEvaluationParameters& parameters) {
|
||||
auto evaluated = unevaluated.evaluate(parameters);
|
||||
const auto previousProperties = staticImmutableCast<BackgroundLayerProperties>(evaluatedProperties);
|
||||
auto evaluated = unevaluated.evaluate(parameters, previousProperties->evaluated);
|
||||
auto properties = makeMutable<BackgroundLayerProperties>(
|
||||
staticImmutableCast<BackgroundLayer::Impl>(baseImpl), parameters.getCrossfadeParameters(), evaluated);
|
||||
|
||||
|
||||
@@ -71,8 +71,10 @@ void RenderCircleLayer::transition(const TransitionParameters& parameters) {
|
||||
}
|
||||
|
||||
void RenderCircleLayer::evaluate(const PropertyEvaluationParameters& parameters) {
|
||||
auto properties = makeMutable<CircleLayerProperties>(staticImmutableCast<CircleLayer::Impl>(baseImpl),
|
||||
unevaluated.evaluate(parameters));
|
||||
const auto previousProperties = staticImmutableCast<CircleLayerProperties>(evaluatedProperties);
|
||||
auto properties = makeMutable<CircleLayerProperties>(
|
||||
staticImmutableCast<CircleLayer::Impl>(baseImpl),
|
||||
unevaluated.evaluate(parameters, previousProperties->evaluated));
|
||||
const auto& evaluated = properties->evaluated;
|
||||
|
||||
passes = ((evaluated.get<style::CircleRadius>().constantOr(1) > 0 ||
|
||||
|
||||
@@ -58,9 +58,11 @@ void RenderFillExtrusionLayer::transition(const TransitionParameters& parameters
|
||||
}
|
||||
|
||||
void RenderFillExtrusionLayer::evaluate(const PropertyEvaluationParameters& parameters) {
|
||||
auto properties = makeMutable<FillExtrusionLayerProperties>(staticImmutableCast<FillExtrusionLayer::Impl>(baseImpl),
|
||||
parameters.getCrossfadeParameters(),
|
||||
unevaluated.evaluate(parameters));
|
||||
const auto previousProperties = staticImmutableCast<FillExtrusionLayerProperties>(evaluatedProperties);
|
||||
auto properties = makeMutable<FillExtrusionLayerProperties>(
|
||||
staticImmutableCast<FillExtrusionLayer::Impl>(baseImpl),
|
||||
parameters.getCrossfadeParameters(),
|
||||
unevaluated.evaluate(parameters, previousProperties->evaluated));
|
||||
|
||||
passes = (properties->evaluated.get<style::FillExtrusionOpacity>() > 0)
|
||||
? (RenderPass::Translucent | RenderPass::Pass3D)
|
||||
|
||||
@@ -69,9 +69,10 @@ void RenderFillLayer::transition(const TransitionParameters& parameters) {
|
||||
}
|
||||
|
||||
void RenderFillLayer::evaluate(const PropertyEvaluationParameters& parameters) {
|
||||
const auto previousProperties = staticImmutableCast<FillLayerProperties>(evaluatedProperties);
|
||||
auto properties = makeMutable<FillLayerProperties>(staticImmutableCast<FillLayer::Impl>(baseImpl),
|
||||
parameters.getCrossfadeParameters(),
|
||||
unevaluated.evaluate(parameters));
|
||||
unevaluated.evaluate(parameters, previousProperties->evaluated));
|
||||
auto& evaluated = properties->evaluated;
|
||||
|
||||
if (unevaluated.get<style::FillOutlineColor>().isUndefined()) {
|
||||
|
||||
@@ -63,8 +63,10 @@ void RenderHeatmapLayer::layerChanged(const TransitionParameters& parameters,
|
||||
#endif
|
||||
|
||||
void RenderHeatmapLayer::evaluate(const PropertyEvaluationParameters& parameters) {
|
||||
auto properties = makeMutable<HeatmapLayerProperties>(staticImmutableCast<HeatmapLayer::Impl>(baseImpl),
|
||||
unevaluated.evaluate(parameters));
|
||||
const auto previousProperties = staticImmutableCast<HeatmapLayerProperties>(evaluatedProperties);
|
||||
auto properties = makeMutable<HeatmapLayerProperties>(
|
||||
staticImmutableCast<HeatmapLayer::Impl>(baseImpl),
|
||||
unevaluated.evaluate(parameters, previousProperties->evaluated));
|
||||
|
||||
passes = (properties->evaluated.get<style::HeatmapOpacity>() > 0) ? (RenderPass::Translucent | RenderPass::Pass3D)
|
||||
: RenderPass::None;
|
||||
|
||||
@@ -77,8 +77,11 @@ void RenderHillshadeLayer::layerChanged(const TransitionParameters& parameters,
|
||||
#endif
|
||||
|
||||
void RenderHillshadeLayer::evaluate(const PropertyEvaluationParameters& parameters) {
|
||||
auto properties = makeMutable<HillshadeLayerProperties>(staticImmutableCast<HillshadeLayer::Impl>(baseImpl),
|
||||
unevaluated.evaluate(parameters));
|
||||
const auto previousProperties = staticImmutableCast<HillshadeLayerProperties>(evaluatedProperties);
|
||||
auto properties = makeMutable<HillshadeLayerProperties>(
|
||||
staticImmutableCast<HillshadeLayer::Impl>(baseImpl),
|
||||
unevaluated.evaluate(parameters, previousProperties->evaluated));
|
||||
|
||||
passes = (properties->evaluated.get<style::HillshadeExaggeration>() > 0)
|
||||
? (RenderPass::Translucent | RenderPass::Pass3D)
|
||||
: RenderPass::None;
|
||||
|
||||
@@ -64,12 +64,19 @@ RenderLineLayer::~RenderLineLayer() = default;
|
||||
void RenderLineLayer::transition(const TransitionParameters& parameters) {
|
||||
unevaluated = impl_cast(baseImpl).paint.transitioned(parameters, std::move(unevaluated));
|
||||
updateColorRamp();
|
||||
|
||||
#if MLN_RENDER_BACKEND_METAL
|
||||
if (auto* tweaker = static_cast<LineLayerTweaker*>(layerTweaker.get())) {
|
||||
tweaker->updateGPUExpressions(unevaluated, parameters.now);
|
||||
}
|
||||
#endif // MLN_RENDER_BACKEND_METAL
|
||||
}
|
||||
|
||||
void RenderLineLayer::evaluate(const PropertyEvaluationParameters& parameters) {
|
||||
const auto previousProperties = staticImmutableCast<LineLayerProperties>(evaluatedProperties);
|
||||
auto properties = makeMutable<LineLayerProperties>(staticImmutableCast<LineLayer::Impl>(baseImpl),
|
||||
parameters.getCrossfadeParameters(),
|
||||
unevaluated.evaluate(parameters));
|
||||
unevaluated.evaluate(parameters, previousProperties->evaluated));
|
||||
auto& evaluated = properties->evaluated;
|
||||
|
||||
passes = (evaluated.get<style::LineOpacity>().constantOr(1.0) > 0 &&
|
||||
@@ -81,8 +88,11 @@ void RenderLineLayer::evaluate(const PropertyEvaluationParameters& parameters) {
|
||||
evaluatedProperties = std::move(properties);
|
||||
|
||||
#if MLN_DRAWABLE_RENDERER
|
||||
if (layerTweaker) {
|
||||
layerTweaker->updateProperties(evaluatedProperties);
|
||||
if (auto* tweaker = static_cast<LineLayerTweaker*>(layerTweaker.get())) {
|
||||
tweaker->updateProperties(evaluatedProperties);
|
||||
#if MLN_RENDER_BACKEND_METAL
|
||||
tweaker->updateGPUExpressions(unevaluated, parameters.now);
|
||||
#endif // MLN_RENDER_BACKEND_METAL
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -348,7 +358,7 @@ float RenderLineLayer::getLineWidth(const GeometryTileFeature& feature,
|
||||
void RenderLineLayer::update(gfx::ShaderRegistry& shaders,
|
||||
gfx::Context& context,
|
||||
const TransformState& state,
|
||||
const std::shared_ptr<UpdateParameters>&,
|
||||
[[maybe_unused]] const std::shared_ptr<UpdateParameters>& parameters,
|
||||
[[maybe_unused]] const RenderTree& renderTree,
|
||||
[[maybe_unused]] UniqueChangeRequestVec& changes) {
|
||||
if (!renderTiles || renderTiles->empty()) {
|
||||
@@ -367,7 +377,12 @@ void RenderLineLayer::update(gfx::ShaderRegistry& shaders,
|
||||
auto* tileLayerGroup = static_cast<TileLayerGroup*>(layerGroup.get());
|
||||
|
||||
if (!layerTweaker) {
|
||||
layerTweaker = std::make_shared<LineLayerTweaker>(getID(), evaluatedProperties);
|
||||
auto tweaker = std::make_shared<LineLayerTweaker>(getID(), evaluatedProperties);
|
||||
#if MLN_RENDER_BACKEND_METAL
|
||||
tweaker->updateGPUExpressions(unevaluated, parameters->timePoint);
|
||||
#endif // MLN_RENDER_BACKEND_METAL
|
||||
|
||||
layerTweaker = std::move(tweaker);
|
||||
layerGroup->addLayerTweaker(layerTweaker);
|
||||
}
|
||||
|
||||
|
||||
@@ -50,8 +50,11 @@ void RenderRasterLayer::transition(const TransitionParameters& parameters) {
|
||||
}
|
||||
|
||||
void RenderRasterLayer::evaluate(const PropertyEvaluationParameters& parameters) {
|
||||
auto properties = makeMutable<RasterLayerProperties>(staticImmutableCast<RasterLayer::Impl>(baseImpl),
|
||||
unevaluated.evaluate(parameters));
|
||||
const auto previousProperties = staticImmutableCast<RasterLayerProperties>(evaluatedProperties);
|
||||
auto properties = makeMutable<RasterLayerProperties>(
|
||||
staticImmutableCast<RasterLayer::Impl>(baseImpl),
|
||||
unevaluated.evaluate(parameters, previousProperties->evaluated));
|
||||
|
||||
passes = properties->evaluated.get<style::RasterOpacity>() > 0 ? RenderPass::Translucent : RenderPass::None;
|
||||
properties->renderPasses = mbgl::underlying_type(passes);
|
||||
evaluatedProperties = std::move(properties);
|
||||
|
||||
@@ -371,8 +371,11 @@ void RenderSymbolLayer::transition(const TransitionParameters& parameters) {
|
||||
}
|
||||
|
||||
void RenderSymbolLayer::evaluate(const PropertyEvaluationParameters& parameters) {
|
||||
auto properties = makeMutable<SymbolLayerProperties>(staticImmutableCast<SymbolLayer::Impl>(baseImpl),
|
||||
unevaluated.evaluate(parameters));
|
||||
const auto previousProperties = staticImmutableCast<SymbolLayerProperties>(evaluatedProperties);
|
||||
auto properties = makeMutable<SymbolLayerProperties>(
|
||||
staticImmutableCast<SymbolLayer::Impl>(baseImpl),
|
||||
unevaluated.evaluate(parameters, previousProperties->evaluated));
|
||||
|
||||
auto& evaluated = properties->evaluated;
|
||||
const auto& layout = impl_cast(baseImpl).layout;
|
||||
|
||||
|
||||
@@ -476,7 +476,7 @@ public:
|
||||
#endif // MLN_LEGACY_RENDERER
|
||||
|
||||
std::tuple<float> interpolationFactor(float currentZoom) const override {
|
||||
const float possiblyRoundedZoom = expression.useIntegerZoom ? std::floor(currentZoom) : currentZoom;
|
||||
const float possiblyRoundedZoom = expression.getUseIntegerZoom() ? std::floor(currentZoom) : currentZoom;
|
||||
|
||||
return std::tuple<float>{
|
||||
std::fmax(0.0f, std::fmin(1.0f, expression.interpolationFactor(zoomRange, possiblyRoundedZoom)))};
|
||||
|
||||
@@ -34,6 +34,11 @@ public:
|
||||
return value.match(std::forward<Ts>(ts)...);
|
||||
}
|
||||
|
||||
T evaluate(float zoom) const {
|
||||
return this->match([&](const T& constant_) { return constant_; },
|
||||
[&](const style::PropertyExpression<T>& expression) { return expression.evaluate(zoom); });
|
||||
}
|
||||
|
||||
template <class Feature>
|
||||
T evaluate(const Feature& feature, float zoom, T defaultValue) const {
|
||||
return this->match([&](const T& constant_) { return constant_; },
|
||||
|
||||
@@ -41,6 +41,10 @@ public:
|
||||
TimePoint now;
|
||||
ZoomHistory zoomHistory;
|
||||
Duration defaultFadeDuration;
|
||||
|
||||
bool zoomChanged = true;
|
||||
bool layerChanged = false;
|
||||
bool hasCrossfade = true;
|
||||
};
|
||||
|
||||
} // namespace mbgl
|
||||
|
||||
@@ -9,6 +9,7 @@ template <typename T>
|
||||
class PropertyEvaluator {
|
||||
public:
|
||||
using ResultType = T;
|
||||
static constexpr bool useIntegerZoom = false;
|
||||
|
||||
PropertyEvaluator(const PropertyEvaluationParameters& parameters_, T defaultValue_)
|
||||
: parameters(parameters_),
|
||||
|
||||
@@ -175,12 +175,11 @@ std::unique_ptr<RenderTree> RenderOrchestrator::createRenderTree(
|
||||
: TransitionOptions();
|
||||
|
||||
const TransitionParameters transitionParameters{updateParameters->timePoint, transitionOptions};
|
||||
const auto transitionDuration = transitionOptions.duration.value_or(
|
||||
isMapModeContinuous ? util::DEFAULT_TRANSITION_DURATION : Duration::zero());
|
||||
|
||||
const PropertyEvaluationParameters evaluationParameters{
|
||||
zoomHistory,
|
||||
updateParameters->timePoint,
|
||||
transitionOptions.duration.value_or(isMapModeContinuous ? util::DEFAULT_TRANSITION_DURATION
|
||||
: Duration::zero())};
|
||||
PropertyEvaluationParameters evaluationParameters{zoomHistory, updateParameters->timePoint, transitionDuration};
|
||||
evaluationParameters.zoomChanged = zoomChanged;
|
||||
|
||||
const TileParameters tileParameters{updateParameters->pixelRatio,
|
||||
updateParameters->debugOptions,
|
||||
@@ -300,13 +299,9 @@ std::unique_ptr<RenderTree> RenderOrchestrator::createRenderTree(
|
||||
for (RenderLayer& layer : orderedLayers) {
|
||||
const std::string& id = layer.getID();
|
||||
const bool layerAddedOrChanged = layerDiff.added.count(id) || layerDiff.changed.count(id);
|
||||
|
||||
// Only re-evaluate on change of zoom if the style has some reference to it
|
||||
using Dependency = expression::Dependency;
|
||||
const bool zoomChangedAndMatters = zoomChanged && !layerAddedOrChanged &&
|
||||
(layer.getStyleDependencies() & Dependency::Zoom) != Dependency::None;
|
||||
|
||||
if (layerAddedOrChanged || zoomChangedAndMatters || layer.hasTransition() || layer.hasCrossfade()) {
|
||||
evaluationParameters.layerChanged = layerAddedOrChanged;
|
||||
evaluationParameters.hasCrossfade = layer.hasCrossfade();
|
||||
if (layerAddedOrChanged || zoomChanged || evaluationParameters.hasCrossfade || layer.hasTransition()) {
|
||||
const auto previousMask = layer.evaluatedProperties->constantsMask();
|
||||
layer.evaluate(evaluationParameters);
|
||||
if (previousMask != layer.evaluatedProperties->constantsMask()) {
|
||||
@@ -907,8 +902,12 @@ void RenderOrchestrator::updateLayers(gfx::ShaderRegistry& shaders,
|
||||
transitionOptions.duration.value_or(defDuration),
|
||||
};
|
||||
|
||||
const auto& items = renderTree.getLayerRenderItemMap();
|
||||
|
||||
std::vector<std::unique_ptr<ChangeRequest>> changes;
|
||||
for (const auto& item : renderTree.getLayerRenderItemMap()) {
|
||||
changes.reserve(items.size() * 3);
|
||||
|
||||
for (const auto& item : items) {
|
||||
auto& renderLayer = item.layer.get();
|
||||
renderLayer.update(shaders, context, state, updateParameters, renderTree, changes);
|
||||
}
|
||||
|
||||
@@ -258,8 +258,9 @@ void Renderer::Impl::render(const RenderTree& renderTree,
|
||||
/* .symbol_fade_change = */ parameters.symbolFadeChange,
|
||||
/* .aspect_ratio = */ parameters.state.getSize().aspectRatio(),
|
||||
/* .pixel_ratio = */ parameters.pixelRatio,
|
||||
/* .pad1/2 = */ 0,
|
||||
0};
|
||||
/* .zoom = */ static_cast<float>(parameters.state.getZoom()),
|
||||
/* .pad1 = */ 0,
|
||||
};
|
||||
auto& globalUniforms = context.mutableGlobalUniformBuffers();
|
||||
globalUniforms.createOrUpdate(shaders::idGlobalPaintParamsUBO, &globalPaintParamsUBO, context);
|
||||
#endif
|
||||
|
||||
@@ -188,7 +188,7 @@ void TileSourceRenderItem::updateDebugDrawables(DebugLayerGroupMap& debugLayerGr
|
||||
: linePropertiesUBO(properties) {}
|
||||
~PolylineDrawableTweaker() override = default;
|
||||
|
||||
void init(gfx::Drawable&) override {};
|
||||
void init(gfx::Drawable&) override {}
|
||||
|
||||
void execute(gfx::Drawable& drawable, const PaintParameters& parameters) override {
|
||||
if (!drawable.getTileID().has_value()) {
|
||||
@@ -220,6 +220,9 @@ void TileSourceRenderItem::updateDebugDrawables(DebugLayerGroupMap& debugLayerGr
|
||||
drawableUniforms.createOrUpdate(idLineDrawableUBO, &drawableUBO, parameters.context);
|
||||
drawableUniforms.createOrUpdate(idLineInterpolationUBO, &lineInterpolationUBO, parameters.context);
|
||||
drawableUniforms.createOrUpdate(idLineEvaluatedPropsUBO, &linePropertiesUBO, parameters.context);
|
||||
|
||||
// We would need to set up `idLineExpressionUBO` if the expression mask isn't empty
|
||||
assert(linePropertiesUBO.expressionMask == LineExpressionMask::None);
|
||||
};
|
||||
|
||||
private:
|
||||
@@ -244,7 +247,7 @@ void TileSourceRenderItem::updateDebugDrawables(DebugLayerGroupMap& debugLayerGr
|
||||
/*offset*/ 0.f,
|
||||
/*width*/ 4.f,
|
||||
/*floorwidth*/ 0,
|
||||
0,
|
||||
LineExpressionMask::None,
|
||||
0};
|
||||
auto tweaker = std::make_shared<PolylineDrawableTweaker>(linePropertiesUBO);
|
||||
|
||||
|
||||
@@ -3,11 +3,12 @@
|
||||
namespace mbgl {
|
||||
namespace shaders {
|
||||
|
||||
const std::array<UniformBlockInfo, 4> ShaderSource<BuiltIn::LineShader, gfx::Backend::Type::Metal>::uniforms = {
|
||||
UniformBlockInfo{true, false, sizeof(GlobalPaintParamsUBO), idGlobalPaintParamsUBO},
|
||||
const std::array<UniformBlockInfo, 5> ShaderSource<BuiltIn::LineShader, gfx::Backend::Type::Metal>::uniforms = {
|
||||
UniformBlockInfo{true, true, sizeof(GlobalPaintParamsUBO), idGlobalPaintParamsUBO},
|
||||
UniformBlockInfo{true, false, sizeof(idLineDrawableUBO), idLineDrawableUBO},
|
||||
UniformBlockInfo{true, false, sizeof(LineInterpolationUBO), idLineInterpolationUBO},
|
||||
UniformBlockInfo{true, true, sizeof(LineEvaluatedPropsUBO), idLineEvaluatedPropsUBO},
|
||||
UniformBlockInfo{true, true, sizeof(LineExpressionUBO), idLineExpressionUBO},
|
||||
};
|
||||
const std::array<AttributeInfo, 8> ShaderSource<BuiltIn::LineShader, gfx::Backend::Type::Metal>::attributes = {
|
||||
AttributeInfo{lineUBOCount + 0, gfx::AttributeDataType::Short2, idLinePosNormalVertexAttribute},
|
||||
@@ -22,7 +23,7 @@ const std::array<AttributeInfo, 8> ShaderSource<BuiltIn::LineShader, gfx::Backen
|
||||
const std::array<TextureInfo, 0> ShaderSource<BuiltIn::LineShader, gfx::Backend::Type::Metal>::textures = {};
|
||||
|
||||
const std::array<UniformBlockInfo, 4> ShaderSource<BuiltIn::LineGradientShader, gfx::Backend::Type::Metal>::uniforms = {
|
||||
UniformBlockInfo{true, false, sizeof(GlobalPaintParamsUBO), idGlobalPaintParamsUBO},
|
||||
UniformBlockInfo{true, true, sizeof(GlobalPaintParamsUBO), idGlobalPaintParamsUBO},
|
||||
UniformBlockInfo{true, false, sizeof(LineGradientDrawableUBO), idLineDrawableUBO},
|
||||
UniformBlockInfo{true, false, sizeof(LineGradientInterpolationUBO), idLineInterpolationUBO},
|
||||
UniformBlockInfo{true, true, sizeof(LineEvaluatedPropsUBO), idLineEvaluatedPropsUBO},
|
||||
@@ -40,12 +41,13 @@ const std::array<TextureInfo, 1> ShaderSource<BuiltIn::LineGradientShader, gfx::
|
||||
TextureInfo{0, idLineImageTexture},
|
||||
};
|
||||
|
||||
const std::array<UniformBlockInfo, 5> ShaderSource<BuiltIn::LinePatternShader, gfx::Backend::Type::Metal>::uniforms = {
|
||||
UniformBlockInfo{true, false, sizeof(GlobalPaintParamsUBO), idGlobalPaintParamsUBO},
|
||||
const std::array<UniformBlockInfo, 6> ShaderSource<BuiltIn::LinePatternShader, gfx::Backend::Type::Metal>::uniforms = {
|
||||
UniformBlockInfo{true, true, sizeof(GlobalPaintParamsUBO), idGlobalPaintParamsUBO},
|
||||
UniformBlockInfo{true, true, sizeof(LinePatternDrawableUBO), idLineDrawableUBO},
|
||||
UniformBlockInfo{true, false, sizeof(LinePatternInterpolationUBO), idLineInterpolationUBO},
|
||||
UniformBlockInfo{true, true, sizeof(LinePatternTilePropertiesUBO), idLineTilePropertiesUBO},
|
||||
UniformBlockInfo{true, true, sizeof(LineEvaluatedPropsUBO), idLineEvaluatedPropsUBO},
|
||||
UniformBlockInfo{true, true, sizeof(LineExpressionUBO), idLineExpressionUBO},
|
||||
};
|
||||
const std::array<AttributeInfo, 9> ShaderSource<BuiltIn::LinePatternShader, gfx::Backend::Type::Metal>::attributes = {
|
||||
AttributeInfo{lineUBOCount + 0, gfx::AttributeDataType::Short2, idLinePosNormalVertexAttribute},
|
||||
@@ -62,11 +64,12 @@ const std::array<TextureInfo, 1> ShaderSource<BuiltIn::LinePatternShader, gfx::B
|
||||
TextureInfo{0, idLineImageTexture},
|
||||
};
|
||||
|
||||
const std::array<UniformBlockInfo, 4> ShaderSource<BuiltIn::LineSDFShader, gfx::Backend::Type::Metal>::uniforms = {
|
||||
UniformBlockInfo{true, false, sizeof(GlobalPaintParamsUBO), idGlobalPaintParamsUBO},
|
||||
const std::array<UniformBlockInfo, 5> ShaderSource<BuiltIn::LineSDFShader, gfx::Backend::Type::Metal>::uniforms = {
|
||||
UniformBlockInfo{true, true, sizeof(GlobalPaintParamsUBO), idGlobalPaintParamsUBO},
|
||||
UniformBlockInfo{true, true, sizeof(LineSDFDrawableUBO), idLineDrawableUBO},
|
||||
UniformBlockInfo{true, false, sizeof(LineSDFInterpolationUBO), idLineInterpolationUBO},
|
||||
UniformBlockInfo{true, true, sizeof(LineEvaluatedPropsUBO), idLineEvaluatedPropsUBO},
|
||||
UniformBlockInfo{true, true, sizeof(LineExpressionUBO), idLineExpressionUBO},
|
||||
};
|
||||
const std::array<AttributeInfo, 9> ShaderSource<BuiltIn::LineSDFShader, gfx::Backend::Type::Metal>::attributes = {
|
||||
AttributeInfo{lineUBOCount + 0, gfx::AttributeDataType::Short2, idLinePosNormalVertexAttribute},
|
||||
|
||||
@@ -102,8 +102,9 @@ CoerceFunction getCoerceFunction(const type::Type& t) {
|
||||
return toStringValue;
|
||||
}
|
||||
|
||||
Dependency extraDependency(const type::Type& t) {
|
||||
return t.is<type::ImageType>() ? Dependency::Image : Dependency::None;
|
||||
/// `isRuntimeConstant` does not consider values coerced to `Type` image to be of `Kind` image, so we don't either.
|
||||
constexpr Dependency extraDependency(const type::Type& /*t*/) {
|
||||
return /*t.is<type::ImageType>() ? Dependency::Image :*/ Dependency::None;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -8,14 +8,17 @@ namespace mbgl {
|
||||
namespace style {
|
||||
namespace expression {
|
||||
|
||||
namespace {
|
||||
/// Collators are considered feature-dependent, see `isFeatureConstant`
|
||||
constexpr auto extraDependency = Dependency::Feature;
|
||||
} // namespace
|
||||
|
||||
CollatorExpression::CollatorExpression(std::unique_ptr<Expression> caseSensitive_,
|
||||
std::unique_ptr<Expression> diacriticSensitive_,
|
||||
std::optional<std::unique_ptr<Expression>> locale_)
|
||||
: Expression(Kind::CollatorExpression,
|
||||
type::Collator,
|
||||
depsOf(caseSensitive_) | depsOf(diacriticSensitive_) | depsOf(locale_) |
|
||||
// Collations are treated as feature-dependent. See `style::expression::isFeatureConstant`
|
||||
Dependency::Feature),
|
||||
depsOf(caseSensitive_) | depsOf(diacriticSensitive_) | depsOf(locale_) | extraDependency),
|
||||
caseSensitive(std::move(caseSensitive_)),
|
||||
diacriticSensitive(std::move(diacriticSensitive_)),
|
||||
locale(std::move(locale_)) {}
|
||||
|
||||
@@ -17,7 +17,7 @@ std::ostream& operator<<(std::ostream& os, const Dependency deps) {
|
||||
|
||||
bool any = false;
|
||||
const auto add = [&](Dependency dep, std::string_view name) {
|
||||
if ((deps & dep) != Dependency::None) {
|
||||
if (deps & dep) {
|
||||
os << (any ? "|" : std::string_view{}) << name;
|
||||
any = true;
|
||||
}
|
||||
|
||||
@@ -12,42 +12,46 @@ namespace mbgl {
|
||||
namespace style {
|
||||
namespace expression {
|
||||
|
||||
std::optional<variant<const Interpolate*, const Step*, ParsingError>> findZoomCurve(const expression::Expression* e) {
|
||||
std::optional<variant<const Interpolate*, const Step*, ParsingError>> result;
|
||||
ZoomCurveOrError findZoomCurve(const expression::Expression& e) {
|
||||
ZoomCurveOrError result;
|
||||
|
||||
switch (e->getKind()) {
|
||||
switch (e.getKind()) {
|
||||
case Kind::Let: {
|
||||
auto let = static_cast<const Let*>(e);
|
||||
result = findZoomCurve(let->getResult());
|
||||
const auto& let = static_cast<const Let&>(e);
|
||||
if (const auto& child = let.getResult()) {
|
||||
result = findZoomCurve(*child);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Kind::Coalesce: {
|
||||
auto coalesce = static_cast<const Coalesce*>(e);
|
||||
std::size_t length = coalesce->getLength();
|
||||
const auto& coalesce = static_cast<const Coalesce&>(e);
|
||||
const std::size_t length = coalesce.getLength();
|
||||
for (std::size_t i = 0; i < length; i++) {
|
||||
result = findZoomCurve(coalesce->getChild(i));
|
||||
if (result) {
|
||||
break;
|
||||
if (const auto* child = coalesce.getChild(i)) {
|
||||
result = findZoomCurve(*child);
|
||||
if (result) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Kind::Interpolate: {
|
||||
auto curve = static_cast<const Interpolate*>(e);
|
||||
if (curve->getInput()->getKind() == Kind::CompoundExpression) {
|
||||
auto z = static_cast<CompoundExpression*>(curve->getInput().get());
|
||||
const auto& curve = static_cast<const Interpolate&>(e);
|
||||
if (curve.getInput()->getKind() == Kind::CompoundExpression) {
|
||||
const auto* z = static_cast<CompoundExpression*>(curve.getInput().get());
|
||||
if (z && z->getOperator() == "zoom") {
|
||||
result = {curve};
|
||||
result = {&curve};
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Kind::Step: {
|
||||
auto step = static_cast<const Step*>(e);
|
||||
if (step->getInput()->getKind() == Kind::CompoundExpression) {
|
||||
auto z = static_cast<CompoundExpression*>(step->getInput().get());
|
||||
const auto& step = static_cast<const Step&>(e);
|
||||
if (step.getInput()->getKind() == Kind::CompoundExpression) {
|
||||
const auto* z = static_cast<CompoundExpression*>(step.getInput().get());
|
||||
if (z && z->getOperator() == "zoom") {
|
||||
result = {step};
|
||||
result = {&step};
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -60,9 +64,8 @@ std::optional<variant<const Interpolate*, const Step*, ParsingError>> findZoomCu
|
||||
return result;
|
||||
}
|
||||
|
||||
e->eachChild([&](const Expression& child) {
|
||||
std::optional<variant<const Interpolate*, const Step*, ParsingError>> childResult(findZoomCurve(&child));
|
||||
if (childResult) {
|
||||
e.eachChild([&](const Expression& child) {
|
||||
if (const ZoomCurveOrError childResult = findZoomCurve(child)) {
|
||||
if (childResult->is<ParsingError>()) {
|
||||
result = childResult;
|
||||
} else if (!result && childResult) {
|
||||
@@ -79,16 +82,16 @@ std::optional<variant<const Interpolate*, const Step*, ParsingError>> findZoomCu
|
||||
return result;
|
||||
}
|
||||
|
||||
using ZoomCurveOrNull = variant<std::nullptr_t, const Interpolate*, const Step*>;
|
||||
|
||||
ZoomCurveOrNull findZoomCurveChecked(const expression::Expression& e) {
|
||||
assert(!expression::isZoomConstant(e));
|
||||
return findZoomCurve(&e)->match(
|
||||
[](const ParsingError& err) -> ZoomCurveOrNull {
|
||||
ZoomCurvePtr findZoomCurveChecked(const expression::Expression& e) {
|
||||
if (!e.has(Dependency::Zoom)) {
|
||||
return nullptr;
|
||||
}
|
||||
return findZoomCurve(e)->match(
|
||||
[](const ParsingError& err) -> ZoomCurvePtr {
|
||||
Log::Error(Event::Style, "Invalid Expression: " + err.message);
|
||||
return nullptr;
|
||||
},
|
||||
[](auto zoomCurve) -> ZoomCurveOrNull { return zoomCurve; });
|
||||
[](auto zoomCurve) -> ZoomCurvePtr { return zoomCurve; });
|
||||
}
|
||||
|
||||
} // namespace expression
|
||||
|
||||
@@ -248,19 +248,22 @@ ParseResult ParsingContext::parseExpression(const Convertible& value,
|
||||
}
|
||||
|
||||
ParseResult ParsingContext::parseLayerPropertyExpression(const Convertible& value) {
|
||||
std::optional<TypeAnnotationOption> typeAnnotationOption;
|
||||
if (expected && *expected == type::String) {
|
||||
typeAnnotationOption = TypeAnnotationOption::coerce;
|
||||
}
|
||||
const auto typeAnnotationOption = (expected && *expected == type::String)
|
||||
? std::make_optional(TypeAnnotationOption::coerce)
|
||||
: std::nullopt;
|
||||
ParseResult parsed = parse(value, typeAnnotationOption);
|
||||
if (parsed && !isZoomConstant(**parsed)) {
|
||||
std::optional<variant<const Interpolate*, const Step*, ParsingError>> zoomCurve = findZoomCurve(parsed->get());
|
||||
if (!zoomCurve) {
|
||||
|
||||
// If the expression is zoom-dependent, validate that we can resolve a zoom curve or treat it as an error
|
||||
assert(!parsed || !*parsed || !((*parsed)->dependencies & Dependency::Zoom) == isZoomConstant(**parsed));
|
||||
if (parsed && (*parsed)->has(Dependency::Zoom)) {
|
||||
if (const auto zoomCurve = findZoomCurve(**parsed)) {
|
||||
if (zoomCurve->is<ParsingError>()) {
|
||||
error(zoomCurve->get<ParsingError>().message);
|
||||
return ParseResult();
|
||||
}
|
||||
} else {
|
||||
error(R"("zoom" expression may only be used as input to a top-level "step" or "interpolate" expression.)");
|
||||
return ParseResult();
|
||||
} else if (zoomCurve->is<ParsingError>()) {
|
||||
error(zoomCurve->get<ParsingError>().message);
|
||||
return ParseResult();
|
||||
}
|
||||
}
|
||||
return parsed;
|
||||
|
||||
@@ -91,8 +91,9 @@ class LineDrawableTweaker : public gfx::DrawableTweaker {
|
||||
public:
|
||||
LineDrawableTweaker(const shaders::LineEvaluatedPropsUBO& properties)
|
||||
: linePropertiesUBO(properties) {}
|
||||
~LineDrawableTweaker() override = default;
|
||||
|
||||
void init(gfx::Drawable&) override {};
|
||||
void init(gfx::Drawable&) override {}
|
||||
|
||||
void execute(gfx::Drawable& drawable, const PaintParameters& parameters) override {
|
||||
if (!drawable.getTileID().has_value()) {
|
||||
@@ -124,6 +125,9 @@ public:
|
||||
drawableUniforms.createOrUpdate(idLineDrawableUBO, &drawableUBO, parameters.context);
|
||||
drawableUniforms.createOrUpdate(idLineInterpolationUBO, &lineInterpolationUBO, parameters.context);
|
||||
drawableUniforms.createOrUpdate(idLineEvaluatedPropsUBO, &linePropertiesUBO, parameters.context);
|
||||
|
||||
// We would need to set up `idLineExpressionUBO` if the expression mask isn't empty
|
||||
assert(linePropertiesUBO.expressionMask == LineExpressionMask::None);
|
||||
};
|
||||
|
||||
private:
|
||||
@@ -135,7 +139,7 @@ public:
|
||||
WideVectorDrawableTweaker(const CustomDrawableLayerHost::Interface::LineOptions& options_)
|
||||
: options(options_) {}
|
||||
|
||||
void init(gfx::Drawable&) override {};
|
||||
void init(gfx::Drawable&) override {}
|
||||
|
||||
void execute(gfx::Drawable& drawable, const PaintParameters& parameters) override {
|
||||
if (!drawable.getTileID().has_value()) {
|
||||
@@ -198,8 +202,9 @@ public:
|
||||
FillDrawableTweaker(const Color& color_, float opacity_)
|
||||
: color(color_),
|
||||
opacity(opacity_) {}
|
||||
~FillDrawableTweaker() override = default;
|
||||
|
||||
void init(gfx::Drawable&) override {};
|
||||
void init(gfx::Drawable&) override {}
|
||||
|
||||
void execute(gfx::Drawable& drawable, const PaintParameters& parameters) override {
|
||||
if (!drawable.getTileID().has_value()) {
|
||||
@@ -244,8 +249,9 @@ class SymbolDrawableTweaker : public gfx::DrawableTweaker {
|
||||
public:
|
||||
SymbolDrawableTweaker(const CustomDrawableLayerHost::Interface::SymbolOptions& options_)
|
||||
: options(options_) {}
|
||||
~SymbolDrawableTweaker() override = default;
|
||||
|
||||
void init(gfx::Drawable&) override {};
|
||||
void init(gfx::Drawable&) override {}
|
||||
|
||||
void execute(gfx::Drawable& drawable, const PaintParameters& parameters) override {
|
||||
if (!drawable.getTileID().has_value()) {
|
||||
@@ -536,8 +542,8 @@ void CustomDrawableLayerHost::Interface::finish() {
|
||||
lineOptions.gapWidth,
|
||||
lineOptions.offset,
|
||||
lineOptions.width,
|
||||
0,
|
||||
0,
|
||||
/*floorwidth=*/0,
|
||||
LineExpressionMask::None,
|
||||
0};
|
||||
auto tweaker = std::make_shared<LineDrawableTweaker>(linePropertiesUBO);
|
||||
|
||||
|
||||
@@ -6,10 +6,13 @@
|
||||
#include <mbgl/style/color_ramp_property_value.hpp>
|
||||
#include <mbgl/style/conversion/stringify.hpp>
|
||||
#include <mbgl/style/transition_options.hpp>
|
||||
#include <mbgl/util/convert.hpp>
|
||||
#include <mbgl/util/indexed_tuple.hpp>
|
||||
#include <mbgl/util/ignore.hpp>
|
||||
#include <mbgl/util/logging.hpp>
|
||||
|
||||
#include <bitset>
|
||||
#include <tuple>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
@@ -65,8 +68,13 @@ public:
|
||||
|
||||
bool hasTransition() const noexcept { return bool(prior); }
|
||||
|
||||
bool isTransitioning(TimePoint now) const {
|
||||
return hasTransition() && (begin <= now) && (now < end) && !value.isDataDriven();
|
||||
}
|
||||
|
||||
bool isUndefined() const noexcept { return value.isUndefined(); }
|
||||
|
||||
Value& getValue() noexcept { return value; }
|
||||
const Value& getValue() const noexcept { return value; }
|
||||
|
||||
private:
|
||||
@@ -296,6 +304,24 @@ public:
|
||||
return PossiblyEvaluated{evaluate<Ps>(parameters)...};
|
||||
}
|
||||
|
||||
/// Evaluate the property if necessary, or produce a copy of the previous value if appropriate
|
||||
template <class P>
|
||||
auto maybeEvaluate(const PropertyEvaluationParameters& parameters,
|
||||
const typename P::EvaluatorType::ResultType& oldResult) const {
|
||||
using Evaluator = typename P::EvaluatorType;
|
||||
const auto& property = this->template get<P>();
|
||||
const bool needEvaluate = parameters.layerChanged || parameters.hasCrossfade || property.hasTransition() ||
|
||||
(parameters.zoomChanged && (getDependencies(property) & Dependency::Zoom));
|
||||
return needEvaluate ? property.evaluate(Evaluator(parameters, P::defaultValue()), parameters.now)
|
||||
: oldResult;
|
||||
}
|
||||
|
||||
/// Optionally evaluate each property or produce a copy of the previous value, if appropriate.
|
||||
PossiblyEvaluated evaluate(const PropertyEvaluationParameters& parameters,
|
||||
const PossiblyEvaluated& previous) const {
|
||||
return PossiblyEvaluated{maybeEvaluate<Ps>(parameters, previous.template get<Ps>())...};
|
||||
}
|
||||
|
||||
template <class Writer>
|
||||
void stringify(Writer& writer) const {
|
||||
writer.StartObject();
|
||||
@@ -303,6 +329,8 @@ public:
|
||||
writer.EndObject();
|
||||
}
|
||||
|
||||
unsigned long constantsMask() const { return ConstantsMask<DataDrivenProperties>::getMask(*this); }
|
||||
|
||||
/// Get the combined dependencies of any contained expressions
|
||||
constexpr Dependency getDependencies() const noexcept {
|
||||
Dependency result = Dependency::None;
|
||||
@@ -310,9 +338,20 @@ public:
|
||||
return result;
|
||||
}
|
||||
|
||||
unsigned long constantsMask() const { return ConstantsMask<DataDrivenProperties>::getMask(*this); }
|
||||
#if MLN_DRAWABLE_RENDERER
|
||||
using GPUExpressions = std::array<gfx::UniqueGPUExpression, UnevaluatedTypes::TypeCount>;
|
||||
|
||||
/// Update the GPU expressions, if applicable, for each item in the tuple.
|
||||
/// @return true if any are updated (including being cleared)
|
||||
bool updateGPUExpressions(Unevaluated::GPUExpressions& exprs, TimePoint now) const {
|
||||
const auto results = util::to_array(std::make_tuple(updateGPUExpression<Ps>(exprs, now)...));
|
||||
return std::any_of(results.begin(), results.end(), [](bool x) { return x; });
|
||||
}
|
||||
#endif // MLN_DRAWABLE_RENDERER
|
||||
|
||||
protected:
|
||||
// gather dependencies for each type that can appear in this tuple
|
||||
|
||||
template <class P>
|
||||
Dependency getDependencies(const PropertyValue<P>& v) const noexcept {
|
||||
return v.getDependencies();
|
||||
@@ -322,6 +361,53 @@ public:
|
||||
Dependency getDependencies(const Transitioning<P>& v) const noexcept {
|
||||
return v.getValue().getDependencies();
|
||||
}
|
||||
|
||||
#if MLN_DRAWABLE_RENDERER
|
||||
template <typename P>
|
||||
bool updateGPUExpression(Unevaluated::GPUExpressions& exprs, TimePoint now) const {
|
||||
constexpr auto index = TypeIndex<P, Ps...>::value;
|
||||
constexpr bool forceIntZoom = P::EvaluatorType::useIntegerZoom;
|
||||
return updateGPUExpression(exprs[index], this->template get<P>(), now, forceIntZoom);
|
||||
}
|
||||
|
||||
template <class P>
|
||||
static bool updateGPUExpression(gfx::UniqueGPUExpression& expr,
|
||||
const PropertyValue<P>& val,
|
||||
TimePoint /*now*/,
|
||||
bool intZoom) {
|
||||
if (val.isExpression() && val.asExpression().isGPUCapable()) {
|
||||
if (!expr) {
|
||||
expr = val.asExpression().getGPUExpression(intZoom);
|
||||
return true;
|
||||
}
|
||||
} else if (expr) {
|
||||
// Previously set and shouldn't be
|
||||
expr.reset();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
template <class P>
|
||||
static bool updateGPUExpression(gfx::UniqueGPUExpression& expr,
|
||||
const Transitioning<P>& val,
|
||||
TimePoint now,
|
||||
bool intZoom) {
|
||||
if (val.isTransitioning(now)) {
|
||||
if (expr) {
|
||||
expr.reset();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return updateGPUExpression(expr, val.getValue(), now, intZoom);
|
||||
}
|
||||
static bool updateGPUExpression(gfx::UniqueGPUExpression&,
|
||||
const style::ColorRampPropertyValue&,
|
||||
TimePoint,
|
||||
bool) {
|
||||
return false;
|
||||
}
|
||||
#endif // MLN_DRAWABLE_RENDERER
|
||||
};
|
||||
|
||||
class Transitionable : public Tuple<TransitionableTypes> {
|
||||
|
||||
@@ -1,14 +1,84 @@
|
||||
#include <mbgl/style/property_expression.hpp>
|
||||
|
||||
#include <mbgl/renderer/paint_property_binder.hpp>
|
||||
#include <mbgl/util/convert.hpp>
|
||||
|
||||
#if MLN_DRAWABLE_RENDERER
|
||||
#include <mbgl/gfx/gpu_expression.hpp>
|
||||
#endif // MLN_DRAWABLE_RENDERER
|
||||
|
||||
namespace mbgl {
|
||||
namespace style {
|
||||
|
||||
PropertyExpressionBase::PropertyExpressionBase(std::unique_ptr<expression::Expression> expression_) noexcept
|
||||
namespace {
|
||||
|
||||
using namespace expression;
|
||||
bool checkGPUCapable(const Expression& expression, const ZoomCurvePtr& zoomCurve) {
|
||||
return (expression.dependencies == Dependency::Zoom) && !zoomCurve.is<std::nullptr_t>() &&
|
||||
(expression.getType().is<type::NumberType>() || expression.getType().is<type::ColorType>());
|
||||
}
|
||||
} // namespace
|
||||
|
||||
PropertyExpressionBase::PropertyExpressionBase(std::unique_ptr<expression::Expression> expression_)
|
||||
: expression(std::move(expression_)),
|
||||
isZoomConstant_(expression::isZoomConstant(*expression)),
|
||||
isFeatureConstant_(expression::isFeatureConstant(*expression)),
|
||||
isRuntimeConstant_(expression::isRuntimeConstant(*expression)),
|
||||
zoomCurve(isZoomConstant_ ? nullptr : expression::findZoomCurveChecked(*expression)) {}
|
||||
zoomCurve(expression->has(Dependency::Zoom) ? expression::findZoomCurveChecked(*expression) : nullptr),
|
||||
useIntegerZoom_(false),
|
||||
isZoomConstant_(!expression->has(Dependency::Zoom)),
|
||||
isFeatureConstant_(!expression->has(Dependency::Feature)),
|
||||
isRuntimeConstant_(!expression->has(Dependency::Image)),
|
||||
isGPUCapable_(checkGPUCapable(*expression, zoomCurve)) {
|
||||
assert(isZoomConstant_ == expression::isZoomConstant(*expression));
|
||||
assert(isFeatureConstant_ == expression::isFeatureConstant(*expression));
|
||||
assert(isRuntimeConstant_ == expression::isRuntimeConstant(*expression));
|
||||
}
|
||||
|
||||
PropertyExpressionBase::PropertyExpressionBase(PropertyExpressionBase&& other)
|
||||
: expression(std::move(other.expression)),
|
||||
zoomCurve(std::move(other.zoomCurve)),
|
||||
useIntegerZoom_(other.useIntegerZoom_),
|
||||
isZoomConstant_(other.isZoomConstant_),
|
||||
isFeatureConstant_(other.isFeatureConstant_),
|
||||
isRuntimeConstant_(other.isRuntimeConstant_),
|
||||
isGPUCapable_(other.isGPUCapable_) {}
|
||||
|
||||
PropertyExpressionBase::PropertyExpressionBase(const PropertyExpressionBase& other)
|
||||
: expression(other.expression),
|
||||
zoomCurve(other.zoomCurve),
|
||||
useIntegerZoom_(other.useIntegerZoom_),
|
||||
isZoomConstant_(other.isZoomConstant_),
|
||||
isFeatureConstant_(other.isFeatureConstant_),
|
||||
isRuntimeConstant_(other.isRuntimeConstant_),
|
||||
isGPUCapable_(other.isGPUCapable_) {}
|
||||
|
||||
PropertyExpressionBase& PropertyExpressionBase::operator=(PropertyExpressionBase&& other) {
|
||||
expression = std::move(other.expression);
|
||||
zoomCurve = other.zoomCurve;
|
||||
useIntegerZoom_ = other.useIntegerZoom_;
|
||||
isZoomConstant_ = other.isZoomConstant_;
|
||||
isFeatureConstant_ = other.isFeatureConstant_;
|
||||
isRuntimeConstant_ = other.isRuntimeConstant_;
|
||||
isGPUCapable_ = other.isGPUCapable_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
PropertyExpressionBase& PropertyExpressionBase::operator=(const PropertyExpressionBase& other) {
|
||||
expression = other.expression;
|
||||
zoomCurve = other.zoomCurve;
|
||||
useIntegerZoom_ = other.useIntegerZoom_;
|
||||
isZoomConstant_ = other.isZoomConstant_;
|
||||
isFeatureConstant_ = other.isFeatureConstant_;
|
||||
isRuntimeConstant_ = other.isRuntimeConstant_;
|
||||
isGPUCapable_ = other.isGPUCapable_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
#if MLN_DRAWABLE_RENDERER
|
||||
gfx::UniqueGPUExpression PropertyExpressionBase::getGPUExpression(bool intZoom) const {
|
||||
return isGPUCapable_ ? gfx::GPUExpression::create(*expression, zoomCurve, useIntegerZoom_ || intZoom)
|
||||
: gfx::UniqueGPUExpression{};
|
||||
}
|
||||
#endif // MLN_DRAWABLE_RENDERER
|
||||
|
||||
float PropertyExpressionBase::interpolationFactor(const Range<float>& inputLevels,
|
||||
const float inputValue) const noexcept {
|
||||
return zoomCurve.match(
|
||||
|
||||
@@ -39,7 +39,15 @@ TEST(ExpressionDependencies, Convert) {
|
||||
EXPECT_EQ(Dependency::Feature, toString(number(string(get("color"))))->dependencies);
|
||||
EXPECT_EQ(Dependency::Feature, boolean(string(get("color")))->dependencies);
|
||||
EXPECT_EQ(Dependency::Feature, toFormatted(toColor(string(get("color"))))->dependencies);
|
||||
EXPECT_EQ(Dependency::Feature | Dependency::Image, toImage(string(get("color")))->dependencies);
|
||||
|
||||
/// See `coercion.cpp`, `extraDependency`
|
||||
EXPECT_EQ(Dependency::Feature, toImage(string(get("color")))->dependencies);
|
||||
|
||||
/// See `collator_expression.cpp`, `extraDependency`
|
||||
EXPECT_EQ(Dependency::Feature,
|
||||
createExpression(R"(["resolved-locale",["collator",{"locale": "de"}]])")->dependencies);
|
||||
EXPECT_EQ(Dependency::Feature | Dependency::Zoom,
|
||||
CollatorExpression(gt(literal(1.), zoom()), literal(true), literal("en-us")).dependencies);
|
||||
}
|
||||
|
||||
TEST(ExpressionDependencies, Compare) {
|
||||
@@ -78,8 +86,3 @@ TEST(ExpressionDependencies, CustomLayer) {
|
||||
auto impl = makeMutable<CustomLayer::Impl>("", nullptr);
|
||||
EXPECT_EQ(Dependency::None, CustomLayerProperties{std::move(impl)}.getDependencies());
|
||||
}
|
||||
|
||||
TEST(ExpressionDependencies, Collation) {
|
||||
auto collator = CollatorExpression(gt(literal(1.), zoom()), literal(true), literal("en-us"));
|
||||
EXPECT_EQ(Dependency::Feature | Dependency::Zoom, collator.dependencies);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user