[core] Fix overspecialization of PaintPropertyBinder template
PaintPropertyBinder and subclass templates were being instantiated for every unique attribute type (e.g. a_color, a_fill_color, a_halo_color) even though they behave identically for a given property value type (e.g. Color). To fix this, a unique type such as a_color no longer derives from gl::Attribute<...> -- instead it has an inner Type typedef, which should be used wherever neither a unique type nor attribute name is required. This reduces binary size substantially:
VM SIZE FILE SIZE
++++++++++++++ GROWING ++++++++++++++
-------------- SHRINKING --------------
-2.0% -49.3Ki __TEXT,__text -49.3Ki -2.0%
-3.1% -5.21Ki [None] -2.79Ki -1.6%
-2.1% -4.12Ki __TEXT,__const -4.12Ki -2.1%
-1.4% -4.04Ki __TEXT,__gcc_except_tab -4.04Ki -1.4%
-19.3% -3.62Ki __DATA,__data -3.62Ki -19.3%
-2.5% -1.65Ki __TEXT,__unwind_info -1.65Ki -2.5%
-4.2% -8 __DATA,__mod_init_func 0 [ = ]
-1.9% -68.0Ki TOTAL -65.6Ki -1.9%
This commit is contained in:
@@ -113,8 +113,11 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
#define MBGL_DEFINE_ATTRIBUTE(type_, n_, name_) \
|
||||
struct name_ : ::mbgl::gl::Attribute<type_, n_> { static auto name() { return #name_; } }
|
||||
#define MBGL_DEFINE_ATTRIBUTE(type_, n_, name_) \
|
||||
struct name_ { \
|
||||
static auto name() { return #name_; } \
|
||||
using Type = ::mbgl::gl::Attribute<type_, n_>; \
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
|
||||
@@ -234,15 +237,15 @@ public:
|
||||
using Types = TypeList<As...>;
|
||||
using Locations = IndexedTuple<
|
||||
TypeList<As...>,
|
||||
TypeList<typename As::Location...>>;
|
||||
TypeList<typename As::Type::Location...>>;
|
||||
using Bindings = IndexedTuple<
|
||||
TypeList<As...>,
|
||||
TypeList<typename As::Binding...>>;
|
||||
TypeList<typename As::Type::Binding...>>;
|
||||
using VariableBindings = IndexedTuple<
|
||||
TypeList<As...>,
|
||||
TypeList<optional<typename As::VariableBinding>...>>;
|
||||
TypeList<optional<typename As::Type::VariableBinding>...>>;
|
||||
|
||||
using Vertex = detail::Vertex<As...>;
|
||||
using Vertex = detail::Vertex<typename As::Type...>;
|
||||
|
||||
template <class A>
|
||||
static constexpr std::size_t Index = TypeIndex<A, As...>::value;
|
||||
@@ -253,7 +256,7 @@ public:
|
||||
|
||||
template <class DrawMode>
|
||||
static Bindings allVariableBindings(const VertexBuffer<Vertex, DrawMode>& buffer) {
|
||||
return Bindings { As::variableBinding(buffer, Index<As>)... };
|
||||
return Bindings { As::Type::variableBinding(buffer, Index<As>)... };
|
||||
}
|
||||
|
||||
static void bind(Context& context,
|
||||
@@ -261,11 +264,11 @@ public:
|
||||
VariableBindings& oldBindings,
|
||||
const Bindings& newBindings,
|
||||
std::size_t vertexOffset) {
|
||||
util::ignore({ (As::bind(context,
|
||||
locations.template get<As>(),
|
||||
oldBindings.template get<As>(),
|
||||
newBindings.template get<As>(),
|
||||
vertexOffset), 0)... });
|
||||
util::ignore({ (As::Type::bind(context,
|
||||
locations.template get<As>(),
|
||||
oldBindings.template get<As>(),
|
||||
newBindings.template get<As>(),
|
||||
vertexOffset), 0)... });
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -16,209 +16,104 @@ MBGL_DEFINE_ATTRIBUTE(int16_t, 4, a_pos_offset);
|
||||
MBGL_DEFINE_ATTRIBUTE(uint16_t, 2, a_texture_pos);
|
||||
|
||||
template <std::size_t N>
|
||||
struct a_data : gl::Attribute<uint8_t, N> {
|
||||
struct a_data {
|
||||
static auto name() { return "a_data"; }
|
||||
using Type = gl::Attribute<uint8_t, N>;
|
||||
};
|
||||
|
||||
template <std::size_t N>
|
||||
struct a_offset : gl::Attribute<int16_t, N> {
|
||||
struct a_offset {
|
||||
static auto name() { return "a_offset"; }
|
||||
using Type = gl::Attribute<int16_t, N>;
|
||||
};
|
||||
|
||||
// Paint attributes
|
||||
|
||||
/*
|
||||
ZoomInterpolatedAttribute<Attr> is a 'compound' attribute, representing two values of the
|
||||
the base attribute Attr. These two values are provided to the shader to allow interpolation
|
||||
between zoom levels, without the need to repopulate vertex buffers each frame as the map is
|
||||
being zoomed.
|
||||
*/
|
||||
template <class Attr>
|
||||
struct ZoomInterpolatedAttribute : gl::Attribute<typename Attr::ValueType, Attr::Dimensions * 2> {
|
||||
using Value = typename gl::Attribute<typename Attr::ValueType, Attr::Dimensions * 2>::Value;
|
||||
|
||||
static auto name() {
|
||||
return Attr::name();
|
||||
}
|
||||
|
||||
template <class InputType>
|
||||
static Value value(const InputType& min, const InputType& max){
|
||||
auto minValue = Attr::value(min);
|
||||
auto maxValue = Attr::value(max);
|
||||
Value result = {{}};
|
||||
for (size_t i = 0; i < Attr::Dimensions; i++) {
|
||||
result[i] = minValue[i];
|
||||
result[Attr::Dimensions+i] = maxValue[i];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
template <class Attr>
|
||||
struct InterpolationUniform : gl::UniformScalar<InterpolationUniform<Attr>, float> {
|
||||
static auto name() {
|
||||
static const std::string name = Attr::name() + std::string("_t");
|
||||
return name.c_str();
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
Encode a four-component color value into a pair of floats. Since csscolorparser
|
||||
uses 8-bit precision for each color component, for each float we use the upper 8
|
||||
bits for one component (e.g. (color.r * 255) * 256), and the lower 8 for another.
|
||||
|
||||
Also note:
|
||||
- Colors come in as floats 0..1, so we scale by 255.
|
||||
- Casting the scaled values to ints is important: without doing this, e.g., the
|
||||
fractional part of the `r` component would corrupt the lower-8 bits of the encoded
|
||||
value, which must be reserved for the `g` component.
|
||||
*/
|
||||
static std::array<float, 2> encodeColor (const Color& color) {
|
||||
const auto v1 = static_cast<uint16_t>( static_cast<uint16_t>(color.r*255)*256 + color.g*255);
|
||||
const auto v2 = static_cast<uint16_t>( static_cast<uint16_t>(color.b*255)*256 + color.a*255);
|
||||
return {{ static_cast<float>(v1), static_cast<float>(v2) }};
|
||||
}
|
||||
|
||||
struct a_color : gl::Attribute<float, 2> {
|
||||
struct a_color {
|
||||
static auto name() { return "a_color"; }
|
||||
|
||||
static Value value(const Color& color) {
|
||||
return encodeColor(color);
|
||||
}
|
||||
using Type = gl::Attribute<float, 2>;
|
||||
};
|
||||
|
||||
// used in the symbol sdf shader
|
||||
struct a_fill_color : gl::Attribute<float, 2> {
|
||||
struct a_fill_color {
|
||||
static auto name() { return "a_fill_color"; }
|
||||
|
||||
static Value value(const Color& color) {
|
||||
return encodeColor(color);
|
||||
}
|
||||
using Type = gl::Attribute<float, 2>;
|
||||
};
|
||||
|
||||
// used in the symbol sdf shader
|
||||
struct a_halo_color : gl::Attribute<float, 2> {
|
||||
struct a_halo_color {
|
||||
static auto name() { return "a_halo_color"; }
|
||||
|
||||
static Value value(const Color& color) {
|
||||
return encodeColor(color);
|
||||
}
|
||||
using Type = gl::Attribute<float, 2>;
|
||||
};
|
||||
|
||||
struct a_stroke_color : gl::Attribute<float, 2> {
|
||||
struct a_stroke_color {
|
||||
static auto name() { return "a_stroke_color"; }
|
||||
|
||||
static Value value(const Color& color) {
|
||||
return encodeColor(color);
|
||||
}
|
||||
using Type = gl::Attribute<float, 2>;
|
||||
};
|
||||
|
||||
struct a_outline_color : gl::Attribute<float, 2> {
|
||||
struct a_outline_color {
|
||||
static auto name() { return "a_outline_color"; }
|
||||
|
||||
static Value value(const Color& color) {
|
||||
return encodeColor(color);
|
||||
}
|
||||
using Type = gl::Attribute<float, 2>;
|
||||
};
|
||||
|
||||
struct a_opacity : gl::Attribute<float, 1> {
|
||||
struct a_opacity {
|
||||
static auto name() { return "a_opacity"; }
|
||||
|
||||
static Value value(float opacity) {
|
||||
return {{ opacity }};
|
||||
}
|
||||
using Type = gl::Attribute<float, 1>;
|
||||
};
|
||||
|
||||
struct a_stroke_opacity : gl::Attribute<float, 1> {
|
||||
struct a_stroke_opacity {
|
||||
static auto name() { return "a_stroke_opacity"; }
|
||||
|
||||
static Value value(float opacity) {
|
||||
return {{ opacity }};
|
||||
}
|
||||
using Type = gl::Attribute<float, 1>;
|
||||
};
|
||||
|
||||
struct a_blur : gl::Attribute<float, 1> {
|
||||
struct a_blur {
|
||||
static auto name() { return "a_blur"; }
|
||||
|
||||
static Value value(float blur) {
|
||||
return {{ blur }};
|
||||
}
|
||||
using Type = gl::Attribute<float, 1>;
|
||||
};
|
||||
|
||||
struct a_radius : gl::Attribute<float, 1> {
|
||||
struct a_radius {
|
||||
static auto name() { return "a_radius"; }
|
||||
|
||||
static Value value(float radius) {
|
||||
return {{ radius }};
|
||||
}
|
||||
using Type = gl::Attribute<float, 1>;
|
||||
};
|
||||
|
||||
struct a_width : gl::Attribute<float, 1> {
|
||||
struct a_width {
|
||||
static auto name() { return "a_width"; }
|
||||
|
||||
static Value value(float width) {
|
||||
return {{ width }};
|
||||
}
|
||||
using Type = gl::Attribute<float, 1>;
|
||||
};
|
||||
|
||||
struct a_height : gl::Attribute<float, 1> {
|
||||
struct a_height {
|
||||
static auto name() { return "a_height"; }
|
||||
|
||||
static Value value(float width) {
|
||||
return {{ width }};
|
||||
}
|
||||
using Type = gl::Attribute<float, 1>;
|
||||
};
|
||||
|
||||
struct a_base : gl::Attribute<float, 1> {
|
||||
struct a_base {
|
||||
static auto name() { return "a_base"; }
|
||||
|
||||
static Value value(float width) {
|
||||
return {{ width }};
|
||||
}
|
||||
using Type = gl::Attribute<float, 1>;
|
||||
};
|
||||
|
||||
struct a_gap_width : gl::Attribute<float, 1> {
|
||||
struct a_gap_width {
|
||||
static auto name() { return "a_gapwidth"; }
|
||||
|
||||
static Value value(float width) {
|
||||
return {{ width }};
|
||||
}
|
||||
using Type = gl::Attribute<float, 1>;
|
||||
};
|
||||
|
||||
struct a_stroke_width : gl::Attribute<float, 1> {
|
||||
struct a_stroke_width {
|
||||
static auto name() { return "a_stroke_width"; }
|
||||
|
||||
static Value value(float width) {
|
||||
return {{ width }};
|
||||
}
|
||||
using Type = gl::Attribute<float, 1>;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct a_offset<1> : gl::Attribute<float, 1> {
|
||||
struct a_offset<1> {
|
||||
static auto name() { return "a_offset"; }
|
||||
|
||||
static Value value(float offset) {
|
||||
return {{ offset }};
|
||||
}
|
||||
using Type = gl::Attribute<float, 1>;
|
||||
};
|
||||
|
||||
struct a_halo_width : gl::Attribute<float, 1> {
|
||||
struct a_halo_width {
|
||||
static auto name() { return "a_halo_width"; }
|
||||
|
||||
static Value value(float width) {
|
||||
return {{ width }};
|
||||
}
|
||||
using Type = gl::Attribute<float, 1>;
|
||||
};
|
||||
|
||||
struct a_halo_blur : gl::Attribute<float, 1> {
|
||||
struct a_halo_blur {
|
||||
static auto name() { return "a_halo_blur"; }
|
||||
|
||||
static Value value(float blur) {
|
||||
return {{ blur }};
|
||||
}
|
||||
using Type = gl::Attribute<float, 1>;
|
||||
};
|
||||
|
||||
|
||||
|
||||
} // namespace attributes
|
||||
} // namespace mbgl
|
||||
|
||||
@@ -8,11 +8,51 @@
|
||||
namespace mbgl {
|
||||
namespace style {
|
||||
|
||||
/*
|
||||
ZoomInterpolatedAttribute<Attr> is a 'compound' attribute, representing two values of the
|
||||
the base attribute Attr. These two values are provided to the shader to allow interpolation
|
||||
between zoom levels, without the need to repopulate vertex buffers each frame as the map is
|
||||
being zoomed.
|
||||
*/
|
||||
template <class A>
|
||||
using ZoomInterpolatedAttributeType = gl::Attribute<typename A::ValueType, A::Dimensions * 2>;
|
||||
|
||||
inline std::array<float, 1> attributeValue(float v) {
|
||||
return {{ v }};
|
||||
}
|
||||
|
||||
/*
|
||||
Encode a four-component color value into a pair of floats. Since csscolorparser
|
||||
uses 8-bit precision for each color component, for each float we use the upper 8
|
||||
bits for one component (e.g. (color.r * 255) * 256), and the lower 8 for another.
|
||||
|
||||
Also note:
|
||||
- Colors come in as floats 0..1, so we scale by 255.
|
||||
- Casting the scaled values to ints is important: without doing this, e.g., the
|
||||
fractional part of the `r` component would corrupt the lower-8 bits of the encoded
|
||||
value, which must be reserved for the `g` component.
|
||||
*/
|
||||
inline std::array<float, 2> attributeValue(const Color& color) {
|
||||
return {{
|
||||
static_cast<float>(static_cast<uint16_t>(color.r * 255) * 256 + static_cast<uint16_t>(color.g * 255)),
|
||||
static_cast<float>(static_cast<uint16_t>(color.b * 255) * 256 + static_cast<uint16_t>(color.a * 255))
|
||||
}};
|
||||
}
|
||||
|
||||
template <size_t N>
|
||||
std::array<float, N*2> zoomInterpolatedAttributeValue(const std::array<float, N>& min, const std::array<float, N>& max) {
|
||||
std::array<float, N*2> result;
|
||||
for (size_t i = 0; i < N; i++) {
|
||||
result[i] = min[i];
|
||||
result[i+N] = max[i];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class T, class A>
|
||||
class PaintPropertyBinder {
|
||||
public:
|
||||
using BaseAttribute = A;
|
||||
using Attribute = attributes::ZoomInterpolatedAttribute<BaseAttribute>;
|
||||
using Attribute = ZoomInterpolatedAttributeType<A>;
|
||||
using AttributeBinding = typename Attribute::Binding;
|
||||
|
||||
virtual ~PaintPropertyBinder() = default;
|
||||
@@ -21,16 +61,14 @@ public:
|
||||
virtual void upload(gl::Context& context) = 0;
|
||||
virtual AttributeBinding attributeBinding(const PossiblyEvaluatedPropertyValue<T>& currentValue) const = 0;
|
||||
virtual float interpolationFactor(float currentZoom) const = 0;
|
||||
|
||||
static std::unique_ptr<PaintPropertyBinder> create(const PossiblyEvaluatedPropertyValue<T>& value, float zoom, T defaultValue);
|
||||
};
|
||||
|
||||
template <class T, class A>
|
||||
class ConstantPaintPropertyBinder : public PaintPropertyBinder<T, A> {
|
||||
public:
|
||||
using BaseAttribute = A;
|
||||
using BaseAttributeValue = typename BaseAttribute::Value;
|
||||
using BaseAttributeBinding = typename BaseAttribute::Binding;
|
||||
|
||||
using Attribute = attributes::ZoomInterpolatedAttribute<BaseAttribute>;
|
||||
using Attribute = ZoomInterpolatedAttributeType<A>;
|
||||
using AttributeBinding = typename Attribute::Binding;
|
||||
|
||||
ConstantPaintPropertyBinder(T constant_)
|
||||
@@ -41,9 +79,9 @@ public:
|
||||
void upload(gl::Context&) override {}
|
||||
|
||||
AttributeBinding attributeBinding(const PossiblyEvaluatedPropertyValue<T>& currentValue) const override {
|
||||
auto val = currentValue.constantOr(constant);
|
||||
auto value = attributeValue(currentValue.constantOr(constant));
|
||||
return typename Attribute::ConstantBinding {
|
||||
Attribute::value(val, val)
|
||||
zoomInterpolatedAttributeValue(value, value)
|
||||
};
|
||||
}
|
||||
|
||||
@@ -60,10 +98,9 @@ class SourceFunctionPaintPropertyBinder : public PaintPropertyBinder<T, A> {
|
||||
public:
|
||||
using BaseAttribute = A;
|
||||
using BaseAttributeValue = typename BaseAttribute::Value;
|
||||
using BaseAttributeBinding = typename BaseAttribute::Binding;
|
||||
using BaseVertex = typename gl::Attributes<BaseAttribute>::Vertex;
|
||||
using BaseVertex = gl::detail::Vertex<BaseAttribute>;
|
||||
|
||||
using Attribute = attributes::ZoomInterpolatedAttribute<BaseAttribute>;
|
||||
using Attribute = ZoomInterpolatedAttributeType<A>;
|
||||
using AttributeBinding = typename Attribute::Binding;
|
||||
|
||||
SourceFunctionPaintPropertyBinder(SourceFunction<T> function_, T defaultValue_)
|
||||
@@ -72,8 +109,7 @@ public:
|
||||
}
|
||||
|
||||
void populateVertexVector(const GeometryTileFeature& feature, std::size_t length) override {
|
||||
auto val = function.evaluate(feature, defaultValue);
|
||||
BaseAttributeValue value = BaseAttribute::value(val);
|
||||
auto value = attributeValue(function.evaluate(feature, defaultValue));
|
||||
for (std::size_t i = vertexVector.vertexSize(); i < length; ++i) {
|
||||
vertexVector.emplace_back(BaseVertex { value });
|
||||
}
|
||||
@@ -85,9 +121,9 @@ public:
|
||||
|
||||
AttributeBinding attributeBinding(const PossiblyEvaluatedPropertyValue<T>& currentValue) const override {
|
||||
if (currentValue.isConstant()) {
|
||||
auto val = *currentValue.constant();
|
||||
BaseAttributeValue value = attributeValue(*currentValue.constant());
|
||||
return typename Attribute::ConstantBinding {
|
||||
Attribute::value(val, val)
|
||||
zoomInterpolatedAttributeValue(value, value)
|
||||
};
|
||||
} else {
|
||||
return Attribute::variableBinding(*vertexBuffer, 0, BaseAttribute::Dimensions);
|
||||
@@ -108,10 +144,13 @@ private:
|
||||
template <class T, class A>
|
||||
class CompositeFunctionPaintPropertyBinder : public PaintPropertyBinder<T, A> {
|
||||
public:
|
||||
using Attribute = attributes::ZoomInterpolatedAttribute<A>;
|
||||
using BaseAttribute = A;
|
||||
using BaseAttributeValue = typename BaseAttribute::Value;
|
||||
|
||||
using Attribute = ZoomInterpolatedAttributeType<A>;
|
||||
using AttributeValue = typename Attribute::Value;
|
||||
using AttributeBinding = typename Attribute::Binding;
|
||||
using Vertex = typename gl::Attributes<Attribute>::Vertex;
|
||||
using Vertex = gl::detail::Vertex<Attribute>;
|
||||
|
||||
CompositeFunctionPaintPropertyBinder(CompositeFunction<T> function_, float zoom, T defaultValue_)
|
||||
: function(std::move(function_)),
|
||||
@@ -121,9 +160,11 @@ public:
|
||||
|
||||
void populateVertexVector(const GeometryTileFeature& feature, std::size_t length) override {
|
||||
Range<T> range = function.evaluate(std::get<1>(coveringRanges), feature, defaultValue);
|
||||
AttributeValue minMax = Attribute::value(range.min, range.max);
|
||||
AttributeValue value = zoomInterpolatedAttributeValue(
|
||||
attributeValue(range.min),
|
||||
attributeValue(range.max));
|
||||
for (std::size_t i = vertexVector.vertexSize(); i < length; ++i) {
|
||||
vertexVector.emplace_back(Vertex { minMax });
|
||||
vertexVector.emplace_back(Vertex { value });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,9 +174,9 @@ public:
|
||||
|
||||
AttributeBinding attributeBinding(const PossiblyEvaluatedPropertyValue<T>& currentValue) const override {
|
||||
if (currentValue.isConstant()) {
|
||||
auto val = *currentValue.constant();
|
||||
BaseAttributeValue value = attributeValue(*currentValue.constant());
|
||||
return typename Attribute::ConstantBinding {
|
||||
Attribute::value(val, val)
|
||||
zoomInterpolatedAttributeValue(value, value)
|
||||
};
|
||||
} else {
|
||||
return Attribute::variableBinding(*vertexBuffer, 0);
|
||||
@@ -155,36 +196,52 @@ private:
|
||||
optional<gl::VertexBuffer<Vertex>> vertexBuffer;
|
||||
};
|
||||
|
||||
template <class PaintProperty>
|
||||
auto createPaintPropertyBinder(const typename PaintProperty::EvaluatedType& value, float zoom) {
|
||||
using Type = typename PaintProperty::Type;
|
||||
using Attribute = typename PaintProperty::Attribute;
|
||||
template <class T, class A>
|
||||
std::unique_ptr<PaintPropertyBinder<T, A>>
|
||||
PaintPropertyBinder<T, A>::create(const PossiblyEvaluatedPropertyValue<T>& value, float zoom, T defaultValue) {
|
||||
return value.match(
|
||||
[&] (const Type& constant) -> std::unique_ptr<PaintPropertyBinder<Type, Attribute>> {
|
||||
return std::make_unique<ConstantPaintPropertyBinder<Type, Attribute>>(constant);
|
||||
[&] (const T& constant) -> std::unique_ptr<PaintPropertyBinder<T, A>> {
|
||||
return std::make_unique<ConstantPaintPropertyBinder<T, A>>(constant);
|
||||
},
|
||||
[&] (const SourceFunction<Type>& function) {
|
||||
return std::make_unique<SourceFunctionPaintPropertyBinder<Type, Attribute>>(function, PaintProperty::defaultValue());
|
||||
[&] (const SourceFunction<T>& function) {
|
||||
return std::make_unique<SourceFunctionPaintPropertyBinder<T, A>>(function, defaultValue);
|
||||
},
|
||||
[&] (const CompositeFunction<Type>& function) {
|
||||
return std::make_unique<CompositeFunctionPaintPropertyBinder<Type, Attribute>>(function, zoom, PaintProperty::defaultValue());
|
||||
[&] (const CompositeFunction<T>& function) {
|
||||
return std::make_unique<CompositeFunctionPaintPropertyBinder<T, A>>(function, zoom, defaultValue);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
template <class Attr>
|
||||
struct ZoomInterpolatedAttribute {
|
||||
static auto name() { return Attr::name(); }
|
||||
using Type = ZoomInterpolatedAttributeType<typename Attr::Type>;
|
||||
};
|
||||
|
||||
template <class Attr>
|
||||
struct InterpolationUniform : gl::UniformScalar<InterpolationUniform<Attr>, float> {
|
||||
static auto name() {
|
||||
static const std::string name = Attr::name() + std::string("_t");
|
||||
return name.c_str();
|
||||
}
|
||||
};
|
||||
|
||||
template <class Ps>
|
||||
class PaintPropertyBinders;
|
||||
|
||||
template <class... Ps>
|
||||
class PaintPropertyBinders<TypeList<Ps...>> {
|
||||
public:
|
||||
template <class P>
|
||||
using Binder = PaintPropertyBinder<typename P::Type, typename P::Attribute::Type>;
|
||||
|
||||
using Binders = IndexedTuple<
|
||||
TypeList<Ps...>,
|
||||
TypeList<std::unique_ptr<PaintPropertyBinder<typename Ps::Type, typename Ps::Attribute>>...>>;
|
||||
TypeList<std::unique_ptr<Binder<Ps>>...>>;
|
||||
|
||||
template <class EvaluatedProperties>
|
||||
PaintPropertyBinders(const EvaluatedProperties& properties, float z)
|
||||
: binders(createPaintPropertyBinder<Ps>(properties.template get<Ps>(), z)...) {
|
||||
: binders(Binder<Ps>::create(properties.template get<Ps>(), z, Ps::defaultValue())...) {
|
||||
(void)z; // Workaround for https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56958
|
||||
}
|
||||
|
||||
@@ -203,7 +260,10 @@ public:
|
||||
});
|
||||
}
|
||||
|
||||
using Attributes = gl::Attributes<typename PaintPropertyBinder<typename Ps::Type, typename Ps::Attribute>::Attribute...>;
|
||||
template <class P>
|
||||
using Attribute = ZoomInterpolatedAttribute<typename P::Attribute>;
|
||||
|
||||
using Attributes = gl::Attributes<Attribute<Ps>...>;
|
||||
using AttributeBindings = typename Attributes::Bindings;
|
||||
|
||||
template <class EvaluatedProperties>
|
||||
@@ -213,13 +273,13 @@ public:
|
||||
};
|
||||
}
|
||||
|
||||
using Uniforms = gl::Uniforms<attributes::InterpolationUniform<typename Ps::Attribute>...>;
|
||||
using Uniforms = gl::Uniforms<InterpolationUniform<typename Ps::Attribute>...>;
|
||||
using UniformValues = typename Uniforms::Values;
|
||||
|
||||
UniformValues uniformValues(float currentZoom) const {
|
||||
(void)currentZoom; // Workaround for https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56958
|
||||
return UniformValues {
|
||||
typename attributes::InterpolationUniform<typename Ps::Attribute>::Value {
|
||||
typename InterpolationUniform<typename Ps::Attribute>::Value {
|
||||
binders.template get<Ps>()->interpolationFactor(currentZoom)
|
||||
}...
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user