summaryrefslogtreecommitdiff
path: root/src/mbgl/renderer
diff options
context:
space:
mode:
Diffstat (limited to 'src/mbgl/renderer')
-rw-r--r--src/mbgl/renderer/cascade_parameters.hpp18
-rw-r--r--src/mbgl/renderer/cross_faded_property_evaluator.cpp40
-rw-r--r--src/mbgl/renderer/cross_faded_property_evaluator.hpp45
-rw-r--r--src/mbgl/renderer/data_driven_property_evaluator.hpp40
-rw-r--r--src/mbgl/renderer/paint_property_binder.hpp330
-rw-r--r--src/mbgl/renderer/paint_property_statistics.hpp29
-rw-r--r--src/mbgl/renderer/painter.hpp2
-rw-r--r--src/mbgl/renderer/possibly_evaluated_property_value.hpp74
-rw-r--r--src/mbgl/renderer/property_evaluation_parameters.hpp28
-rw-r--r--src/mbgl/renderer/property_evaluator.hpp26
-rw-r--r--src/mbgl/renderer/render_background_layer.cpp4
-rw-r--r--src/mbgl/renderer/render_background_layer.hpp4
-rw-r--r--src/mbgl/renderer/render_circle_layer.cpp4
-rw-r--r--src/mbgl/renderer/render_circle_layer.hpp4
-rw-r--r--src/mbgl/renderer/render_custom_layer.cpp2
-rw-r--r--src/mbgl/renderer/render_custom_layer.hpp4
-rw-r--r--src/mbgl/renderer/render_fill_extrusion_layer.cpp4
-rw-r--r--src/mbgl/renderer/render_fill_extrusion_layer.hpp4
-rw-r--r--src/mbgl/renderer/render_fill_layer.cpp4
-rw-r--r--src/mbgl/renderer/render_fill_layer.hpp4
-rw-r--r--src/mbgl/renderer/render_layer.hpp7
-rw-r--r--src/mbgl/renderer/render_light.hpp72
-rw-r--r--src/mbgl/renderer/render_line_layer.cpp4
-rw-r--r--src/mbgl/renderer/render_line_layer.hpp4
-rw-r--r--src/mbgl/renderer/render_raster_layer.cpp4
-rw-r--r--src/mbgl/renderer/render_raster_layer.hpp4
-rw-r--r--src/mbgl/renderer/render_source.hpp7
-rw-r--r--src/mbgl/renderer/render_symbol_layer.cpp6
-rw-r--r--src/mbgl/renderer/render_symbol_layer.hpp4
-rw-r--r--src/mbgl/renderer/sources/render_geojson_source.hpp2
-rw-r--r--src/mbgl/renderer/sources/render_raster_source.hpp2
-rw-r--r--src/mbgl/renderer/sources/render_vector_source.hpp2
-rw-r--r--src/mbgl/renderer/tile_pyramid.cpp2
-rw-r--r--src/mbgl/renderer/tile_pyramid.hpp5
-rw-r--r--src/mbgl/renderer/transitioning_property.hpp75
-rw-r--r--src/mbgl/renderer/update_parameters.hpp47
36 files changed, 866 insertions, 51 deletions
diff --git a/src/mbgl/renderer/cascade_parameters.hpp b/src/mbgl/renderer/cascade_parameters.hpp
new file mode 100644
index 0000000000..4096cc5a6b
--- /dev/null
+++ b/src/mbgl/renderer/cascade_parameters.hpp
@@ -0,0 +1,18 @@
+#pragma once
+
+#include <mbgl/util/chrono.hpp>
+#include <mbgl/style/class_dictionary.hpp>
+#include <mbgl/style/transition_options.hpp>
+
+#include <vector>
+
+namespace mbgl {
+
+class CascadeParameters {
+public:
+ std::vector<style::ClassID> classes;
+ TimePoint now;
+ style::TransitionOptions transition;
+};
+
+} // namespace mbgl
diff --git a/src/mbgl/renderer/cross_faded_property_evaluator.cpp b/src/mbgl/renderer/cross_faded_property_evaluator.cpp
new file mode 100644
index 0000000000..ee3c86614f
--- /dev/null
+++ b/src/mbgl/renderer/cross_faded_property_evaluator.cpp
@@ -0,0 +1,40 @@
+#include <mbgl/renderer/cross_faded_property_evaluator.hpp>
+#include <mbgl/util/chrono.hpp>
+
+#include <cmath>
+
+namespace mbgl {
+
+template <typename T>
+Faded<T> CrossFadedPropertyEvaluator<T>::operator()(const style::Undefined&) const {
+ return calculate(defaultValue, defaultValue, defaultValue);
+}
+
+template <typename T>
+Faded<T> CrossFadedPropertyEvaluator<T>::operator()(const T& constant) const {
+ return calculate(constant, constant, constant);
+}
+
+template <typename T>
+Faded<T> CrossFadedPropertyEvaluator<T>::operator()(const style::CameraFunction<T>& function) const {
+ return calculate(function.evaluate(parameters.z - 1.0f),
+ function.evaluate(parameters.z),
+ function.evaluate(parameters.z + 1.0f));
+}
+
+template <typename T>
+Faded<T> CrossFadedPropertyEvaluator<T>::calculate(const T& min, const T& mid, const T& max) const {
+ const float z = parameters.z;
+ const float fraction = z - std::floor(z);
+ const std::chrono::duration<float> d = parameters.defaultFadeDuration;
+ const float t = std::min((parameters.now - parameters.zoomHistory.lastIntegerZoomTime) / d, 1.0f);
+
+ return z > parameters.zoomHistory.lastIntegerZoom
+ ? Faded<T> { min, mid, 2.0f, 1.0f, fraction + (1.0f - fraction) * t }
+ : Faded<T> { max, mid, 0.5f, 1.0f, 1 - (1 - t) * fraction };
+}
+
+template class CrossFadedPropertyEvaluator<std::string>;
+template class CrossFadedPropertyEvaluator<std::vector<float>>;
+
+} // namespace mbgl
diff --git a/src/mbgl/renderer/cross_faded_property_evaluator.hpp b/src/mbgl/renderer/cross_faded_property_evaluator.hpp
new file mode 100644
index 0000000000..40ecba5d93
--- /dev/null
+++ b/src/mbgl/renderer/cross_faded_property_evaluator.hpp
@@ -0,0 +1,45 @@
+#pragma once
+
+#include <mbgl/style/property_value.hpp>
+#include <mbgl/renderer/property_evaluation_parameters.hpp>
+#include <mbgl/util/interpolate.hpp>
+
+namespace mbgl {
+
+template <typename T>
+class Faded {
+public:
+ T from;
+ T to;
+ float fromScale;
+ float toScale;
+ float t;
+};
+
+template <typename T>
+class CrossFadedPropertyEvaluator {
+public:
+ using ResultType = Faded<T>;
+
+ CrossFadedPropertyEvaluator(const PropertyEvaluationParameters& parameters_, T defaultValue_)
+ : parameters(parameters_),
+ defaultValue(std::move(defaultValue_)) {}
+
+ Faded<T> operator()(const style::Undefined&) const;
+ Faded<T> operator()(const T& constant) const;
+ Faded<T> operator()(const style::CameraFunction<T>&) const;
+
+private:
+ Faded<T> calculate(const T& min, const T& mid, const T& max) const;
+
+ const PropertyEvaluationParameters& parameters;
+ T defaultValue;
+};
+
+namespace util {
+template <typename T>
+struct Interpolator<Faded<T>>
+ : Uninterpolated {};
+} // namespace util
+
+} // namespace mbgl
diff --git a/src/mbgl/renderer/data_driven_property_evaluator.hpp b/src/mbgl/renderer/data_driven_property_evaluator.hpp
new file mode 100644
index 0000000000..6406b3478b
--- /dev/null
+++ b/src/mbgl/renderer/data_driven_property_evaluator.hpp
@@ -0,0 +1,40 @@
+#pragma once
+
+#include <mbgl/style/property_value.hpp>
+#include <mbgl/renderer/property_evaluation_parameters.hpp>
+#include <mbgl/renderer/possibly_evaluated_property_value.hpp>
+
+namespace mbgl {
+
+template <typename T>
+class DataDrivenPropertyEvaluator {
+public:
+ using ResultType = PossiblyEvaluatedPropertyValue<T>;
+
+ DataDrivenPropertyEvaluator(const PropertyEvaluationParameters& parameters_, T defaultValue_)
+ : parameters(parameters_),
+ defaultValue(std::move(defaultValue_)) {}
+
+ ResultType operator()(const style::Undefined&) const {
+ return ResultType(defaultValue);
+ }
+
+ ResultType operator()(const T& constant) const {
+ return ResultType(constant);
+ }
+
+ ResultType operator()(const style::CameraFunction<T>& function) const {
+ return ResultType(function.evaluate(parameters.z));
+ }
+
+ template <class Function>
+ ResultType operator()(const Function& function) const {
+ return ResultType(function);
+ }
+
+private:
+ const PropertyEvaluationParameters& parameters;
+ T defaultValue;
+};
+
+} // namespace mbgl
diff --git a/src/mbgl/renderer/paint_property_binder.hpp b/src/mbgl/renderer/paint_property_binder.hpp
new file mode 100644
index 0000000000..3e53bcc884
--- /dev/null
+++ b/src/mbgl/renderer/paint_property_binder.hpp
@@ -0,0 +1,330 @@
+#pragma once
+
+#include <mbgl/programs/attributes.hpp>
+#include <mbgl/gl/attribute.hpp>
+#include <mbgl/gl/uniform.hpp>
+#include <mbgl/util/type_list.hpp>
+#include <mbgl/renderer/paint_property_statistics.hpp>
+
+namespace mbgl {
+
+/*
+ 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 that colors come in as floats 0..1, so we scale by 255.
+*/
+inline std::array<float, 2> attributeValue(const Color& color) {
+ return {{
+ static_cast<float>(mbgl::attributes::packUint8Pair(255 * color.r, 255 * color.g)),
+ static_cast<float>(mbgl::attributes::packUint8Pair(255 * color.b, 255 * color.a))
+ }};
+}
+
+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;
+}
+
+/*
+ PaintPropertyBinder is an abstract class serving as the interface definition for
+ the strategy used for constructing, uploading, and binding paint property data as
+ GLSL attributes.
+
+ It has three concrete subclasses, one for each of the three strategies we use:
+
+ * For _constant_ properties -- those whose value is a constant, or the constant
+ result of evaluating a camera function at a particular camera position -- we
+ don't need a vertex buffer, and can instead use a constant attribute binding
+ via the `glVertexAttrib*` family of functions.
+ * For source functions, we use a vertex buffer with a single attribute value,
+ the evaluated result of the source function for the given feature.
+ * For composite functions, we use a vertex buffer with two attributes: min and
+ max values covering the range of zooms at which we expect the tile to be
+ displayed. These values are calculated by evaluating the composite function for
+ the given feature at strategically chosen zoom levels. In addition to this
+ attribute data, we also use a uniform value which the shader uses to interpolate
+ between the min and max value at the final displayed zoom level. The use of a
+ uniform allows us to cheaply update the value on every frame.
+
+ Note that the shader source is the same regardless of the strategy used to bind
+ the attribute -- in all cases the attribute is declared as a vec2, in order to
+ support composite min and max values (color attributes use a vec4 with special
+ packing). When the constant or source function strategies are used, the
+ interpolation uniform value is set to zero, and the second attribute element is
+ unused. This differs from the GL JS implementation, which dynamically generates
+ shader source based on the strategy used. We found that in WebGL, using
+ `glVertexAttrib*` was unnacceptably slow. Additionally, in GL Native we have
+ implemented binary shader caching, which works better if the shaders are constant.
+*/
+template <class T, class A>
+class PaintPropertyBinder {
+public:
+ using Attribute = ZoomInterpolatedAttributeType<A>;
+ using AttributeBinding = typename Attribute::Binding;
+
+ virtual ~PaintPropertyBinder() = default;
+
+ virtual void populateVertexVector(const GeometryTileFeature& feature, std::size_t length) = 0;
+ 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);
+
+ PaintPropertyStatistics<T> statistics;
+};
+
+template <class T, class A>
+class ConstantPaintPropertyBinder : public PaintPropertyBinder<T, A> {
+public:
+ using Attribute = ZoomInterpolatedAttributeType<A>;
+ using AttributeBinding = typename Attribute::Binding;
+
+ ConstantPaintPropertyBinder(T constant_)
+ : constant(std::move(constant_)) {
+ }
+
+ void populateVertexVector(const GeometryTileFeature&, std::size_t) override {}
+ void upload(gl::Context&) override {}
+
+ AttributeBinding attributeBinding(const PossiblyEvaluatedPropertyValue<T>& currentValue) const override {
+ auto value = attributeValue(currentValue.constantOr(constant));
+ return typename Attribute::ConstantBinding {
+ zoomInterpolatedAttributeValue(value, value)
+ };
+ }
+
+ float interpolationFactor(float) const override {
+ return 0.0f;
+ }
+
+private:
+ T constant;
+};
+
+template <class T, class A>
+class SourceFunctionPaintPropertyBinder : public PaintPropertyBinder<T, A> {
+public:
+ using BaseAttribute = A;
+ using BaseAttributeValue = typename BaseAttribute::Value;
+ using BaseVertex = gl::detail::Vertex<BaseAttribute>;
+
+ using Attribute = ZoomInterpolatedAttributeType<A>;
+ using AttributeBinding = typename Attribute::Binding;
+
+ SourceFunctionPaintPropertyBinder(style::SourceFunction<T> function_, T defaultValue_)
+ : function(std::move(function_)),
+ defaultValue(std::move(defaultValue_)) {
+ }
+
+ void populateVertexVector(const GeometryTileFeature& feature, std::size_t length) override {
+ auto evaluated = function.evaluate(feature, defaultValue);
+ this->statistics.add(evaluated);
+ auto value = attributeValue(evaluated);
+ for (std::size_t i = vertexVector.vertexSize(); i < length; ++i) {
+ vertexVector.emplace_back(BaseVertex { value });
+ }
+ }
+
+ void upload(gl::Context& context) override {
+ vertexBuffer = context.createVertexBuffer(std::move(vertexVector));
+ }
+
+ AttributeBinding attributeBinding(const PossiblyEvaluatedPropertyValue<T>& currentValue) const override {
+ if (currentValue.isConstant()) {
+ BaseAttributeValue value = attributeValue(*currentValue.constant());
+ return typename Attribute::ConstantBinding {
+ zoomInterpolatedAttributeValue(value, value)
+ };
+ } else {
+ return Attribute::variableBinding(*vertexBuffer, 0, BaseAttribute::Dimensions);
+ }
+ }
+
+ float interpolationFactor(float) const override {
+ return 0.0f;
+ }
+
+private:
+ style::SourceFunction<T> function;
+ T defaultValue;
+ gl::VertexVector<BaseVertex> vertexVector;
+ optional<gl::VertexBuffer<BaseVertex>> vertexBuffer;
+};
+
+template <class T, class A>
+class CompositeFunctionPaintPropertyBinder : public PaintPropertyBinder<T, A> {
+public:
+ using BaseAttribute = A;
+ using BaseAttributeValue = typename BaseAttribute::Value;
+
+ using Attribute = ZoomInterpolatedAttributeType<A>;
+ using AttributeValue = typename Attribute::Value;
+ using AttributeBinding = typename Attribute::Binding;
+ using Vertex = gl::detail::Vertex<Attribute>;
+
+ CompositeFunctionPaintPropertyBinder(style::CompositeFunction<T> function_, float zoom, T defaultValue_)
+ : function(std::move(function_)),
+ defaultValue(std::move(defaultValue_)),
+ coveringRanges(function.coveringRanges(zoom)) {
+ }
+
+ void populateVertexVector(const GeometryTileFeature& feature, std::size_t length) override {
+ Range<T> range = function.evaluate(std::get<1>(coveringRanges), feature, defaultValue);
+ this->statistics.add(range.min);
+ this->statistics.add(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 { value });
+ }
+ }
+
+ void upload(gl::Context& context) override {
+ vertexBuffer = context.createVertexBuffer(std::move(vertexVector));
+ }
+
+ AttributeBinding attributeBinding(const PossiblyEvaluatedPropertyValue<T>& currentValue) const override {
+ if (currentValue.isConstant()) {
+ BaseAttributeValue value = attributeValue(*currentValue.constant());
+ return typename Attribute::ConstantBinding {
+ zoomInterpolatedAttributeValue(value, value)
+ };
+ } else {
+ return Attribute::variableBinding(*vertexBuffer, 0);
+ }
+ }
+
+ float interpolationFactor(float currentZoom) const override {
+ return util::interpolationFactor(1.0f, std::get<0>(coveringRanges), currentZoom);
+ }
+
+private:
+ using InnerStops = typename style::CompositeFunction<T>::InnerStops;
+ style::CompositeFunction<T> function;
+ T defaultValue;
+ std::tuple<Range<float>, Range<InnerStops>> coveringRanges;
+ gl::VertexVector<Vertex> vertexVector;
+ optional<gl::VertexBuffer<Vertex>> vertexBuffer;
+};
+
+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 T& constant) -> std::unique_ptr<PaintPropertyBinder<T, A>> {
+ return std::make_unique<ConstantPaintPropertyBinder<T, A>>(constant);
+ },
+ [&] (const style::SourceFunction<T>& function) {
+ return std::make_unique<SourceFunctionPaintPropertyBinder<T, A>>(function, defaultValue);
+ },
+ [&] (const style::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<Binder<Ps>>...>>;
+
+ template <class EvaluatedProperties>
+ PaintPropertyBinders(const EvaluatedProperties& properties, float 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
+ }
+
+ PaintPropertyBinders(PaintPropertyBinders&&) = default;
+ PaintPropertyBinders(const PaintPropertyBinders&) = delete;
+
+ void populateVertexVectors(const GeometryTileFeature& feature, std::size_t length) {
+ util::ignore({
+ (binders.template get<Ps>()->populateVertexVector(feature, length), 0)...
+ });
+ }
+
+ void upload(gl::Context& context) {
+ util::ignore({
+ (binders.template get<Ps>()->upload(context), 0)...
+ });
+ }
+
+ template <class P>
+ using Attribute = ZoomInterpolatedAttribute<typename P::Attribute>;
+
+ using Attributes = gl::Attributes<Attribute<Ps>...>;
+ using AttributeBindings = typename Attributes::Bindings;
+
+ template <class EvaluatedProperties>
+ AttributeBindings attributeBindings(const EvaluatedProperties& currentProperties) const {
+ return AttributeBindings {
+ binders.template get<Ps>()->attributeBinding(currentProperties.template get<Ps>())...
+ };
+ }
+
+ 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 InterpolationUniform<typename Ps::Attribute>::Value {
+ binders.template get<Ps>()->interpolationFactor(currentZoom)
+ }...
+ };
+ }
+
+ template <class P>
+ const auto& statistics() const {
+ return binders.template get<P>()->statistics;
+ }
+
+private:
+ Binders binders;
+};
+
+} // namespace mbgl
diff --git a/src/mbgl/renderer/paint_property_statistics.hpp b/src/mbgl/renderer/paint_property_statistics.hpp
new file mode 100644
index 0000000000..59a8545911
--- /dev/null
+++ b/src/mbgl/renderer/paint_property_statistics.hpp
@@ -0,0 +1,29 @@
+#pragma once
+
+#include <mbgl/util/optional.hpp>
+
+namespace mbgl {
+
+template <class T>
+class PaintPropertyStatistics {
+public:
+ optional<T> max() const { return {}; }
+ void add(const T&) {}
+};
+
+template <>
+class PaintPropertyStatistics<float> {
+public:
+ optional<float> max() const {
+ return _max;
+ }
+
+ void add(float value) {
+ _max = _max ? std::max(*_max, value) : value;
+ }
+
+private:
+ optional<float> _max;
+};
+
+} // namespace mbgl
diff --git a/src/mbgl/renderer/painter.hpp b/src/mbgl/renderer/painter.hpp
index c7c8173d0d..ff72749718 100644
--- a/src/mbgl/renderer/painter.hpp
+++ b/src/mbgl/renderer/painter.hpp
@@ -158,7 +158,7 @@ private:
GlyphAtlas* glyphAtlas = nullptr;
LineAtlas* lineAtlas = nullptr;
- style::EvaluatedLight evaluatedLight;
+ EvaluatedLight evaluatedLight;
FrameHistory frameHistory;
diff --git a/src/mbgl/renderer/possibly_evaluated_property_value.hpp b/src/mbgl/renderer/possibly_evaluated_property_value.hpp
new file mode 100644
index 0000000000..a0bcec2bf1
--- /dev/null
+++ b/src/mbgl/renderer/possibly_evaluated_property_value.hpp
@@ -0,0 +1,74 @@
+#pragma once
+
+#include <mbgl/style/function/source_function.hpp>
+#include <mbgl/style/function/composite_function.hpp>
+#include <mbgl/util/interpolate.hpp>
+#include <mbgl/util/variant.hpp>
+
+namespace mbgl {
+
+template <class T>
+class PossiblyEvaluatedPropertyValue {
+private:
+ using Value = variant<
+ T,
+ style::SourceFunction<T>,
+ style::CompositeFunction<T>>;
+
+ Value value;
+
+public:
+ PossiblyEvaluatedPropertyValue() = default;
+ PossiblyEvaluatedPropertyValue(Value v) : value(std::move(v)) {}
+
+ bool isConstant() const {
+ return value.template is<T>();
+ }
+
+ optional<T> constant() const {
+ return value.match(
+ [&] (const T& t) { return optional<T>(t); },
+ [&] (const auto&) { return optional<T>(); });
+ }
+
+ T constantOr(const T& t) const {
+ return constant().value_or(t);
+ }
+
+ template <class... Ts>
+ auto match(Ts&&... ts) const {
+ return value.match(std::forward<Ts>(ts)...);
+ }
+
+ template <class Feature>
+ T evaluate(const Feature& feature, float zoom, T defaultValue) const {
+ return this->match(
+ [&] (const T& constant) { return constant; },
+ [&] (const style::SourceFunction<T>& function) {
+ return function.evaluate(feature, defaultValue);
+ },
+ [&] (const style::CompositeFunction<T>& function) {
+ return function.evaluate(zoom, feature, defaultValue);
+ }
+ );
+ }
+};
+
+namespace util {
+
+template <typename T>
+struct Interpolator<PossiblyEvaluatedPropertyValue<T>> {
+ PossiblyEvaluatedPropertyValue<T> operator()(const PossiblyEvaluatedPropertyValue<T>& a,
+ const PossiblyEvaluatedPropertyValue<T>& b,
+ const double t) const {
+ if (a.isConstant() && b.isConstant()) {
+ return { interpolate(*a.constant(), *b.constant(), t) };
+ } else {
+ return { a };
+ }
+ }
+};
+
+} // namespace util
+
+} // namespace mbgl
diff --git a/src/mbgl/renderer/property_evaluation_parameters.hpp b/src/mbgl/renderer/property_evaluation_parameters.hpp
new file mode 100644
index 0000000000..b18fe57aca
--- /dev/null
+++ b/src/mbgl/renderer/property_evaluation_parameters.hpp
@@ -0,0 +1,28 @@
+#pragma once
+
+#include <mbgl/map/zoom_history.hpp>
+#include <mbgl/util/chrono.hpp>
+
+namespace mbgl {
+
+class PropertyEvaluationParameters {
+public:
+ explicit PropertyEvaluationParameters(float z_)
+ : z(z_) {}
+
+ PropertyEvaluationParameters(float z_,
+ TimePoint now_,
+ ZoomHistory zoomHistory_,
+ Duration defaultFadeDuration_)
+ : z(z_),
+ now(std::move(now_)),
+ zoomHistory(std::move(zoomHistory_)),
+ defaultFadeDuration(std::move(defaultFadeDuration_)) {}
+
+ float z;
+ TimePoint now;
+ ZoomHistory zoomHistory;
+ Duration defaultFadeDuration;
+};
+
+} // namespace mbgl
diff --git a/src/mbgl/renderer/property_evaluator.hpp b/src/mbgl/renderer/property_evaluator.hpp
new file mode 100644
index 0000000000..3ac0573920
--- /dev/null
+++ b/src/mbgl/renderer/property_evaluator.hpp
@@ -0,0 +1,26 @@
+#pragma once
+
+#include <mbgl/style/property_value.hpp>
+#include <mbgl/renderer/property_evaluation_parameters.hpp>
+
+namespace mbgl {
+
+template <typename T>
+class PropertyEvaluator {
+public:
+ using ResultType = T;
+
+ PropertyEvaluator(const PropertyEvaluationParameters& parameters_, T defaultValue_)
+ : parameters(parameters_),
+ defaultValue(std::move(defaultValue_)) {}
+
+ T operator()(const style::Undefined&) const { return defaultValue; }
+ T operator()(const T& constant) const { return constant; }
+ T operator()(const style::CameraFunction<T>& fn) const { return fn.evaluate(parameters.z); }
+
+private:
+ const PropertyEvaluationParameters& parameters;
+ T defaultValue;
+};
+
+} // namespace mbgl
diff --git a/src/mbgl/renderer/render_background_layer.cpp b/src/mbgl/renderer/render_background_layer.cpp
index 5b98210975..a6b4a5e36e 100644
--- a/src/mbgl/renderer/render_background_layer.cpp
+++ b/src/mbgl/renderer/render_background_layer.cpp
@@ -19,11 +19,11 @@ std::unique_ptr<Bucket> RenderBackgroundLayer::createBucket(const BucketParamete
return nullptr;
}
-void RenderBackgroundLayer::cascade(const style::CascadeParameters &parameters) {
+void RenderBackgroundLayer::cascade(const CascadeParameters &parameters) {
unevaluated = impl->cascading.cascade(parameters, std::move(unevaluated));
}
-bool RenderBackgroundLayer::evaluate(const style::PropertyEvaluationParameters &parameters) {
+bool RenderBackgroundLayer::evaluate(const PropertyEvaluationParameters &parameters) {
evaluated = unevaluated.evaluate(parameters);
passes = evaluated.get<style::BackgroundOpacity>() > 0 ? RenderPass::Translucent
diff --git a/src/mbgl/renderer/render_background_layer.hpp b/src/mbgl/renderer/render_background_layer.hpp
index bd74f7b390..137980389c 100644
--- a/src/mbgl/renderer/render_background_layer.hpp
+++ b/src/mbgl/renderer/render_background_layer.hpp
@@ -14,8 +14,8 @@ public:
std::unique_ptr<RenderLayer> clone() const override;
- void cascade(const style::CascadeParameters&) override;
- bool evaluate(const style::PropertyEvaluationParameters&) override;
+ void cascade(const CascadeParameters&) override;
+ bool evaluate(const PropertyEvaluationParameters&) override;
std::unique_ptr<Bucket> createBucket(const BucketParameters&, const std::vector<const RenderLayer*>&) const override;
diff --git a/src/mbgl/renderer/render_circle_layer.cpp b/src/mbgl/renderer/render_circle_layer.cpp
index aa127e9859..56832d53cb 100644
--- a/src/mbgl/renderer/render_circle_layer.cpp
+++ b/src/mbgl/renderer/render_circle_layer.cpp
@@ -20,11 +20,11 @@ std::unique_ptr<Bucket> RenderCircleLayer::createBucket(const BucketParameters&
return std::make_unique<CircleBucket>(parameters, layers);
}
-void RenderCircleLayer::cascade(const style::CascadeParameters& parameters) {
+void RenderCircleLayer::cascade(const CascadeParameters& parameters) {
unevaluated = impl->cascading.cascade(parameters, std::move(unevaluated));
}
-bool RenderCircleLayer::evaluate(const style::PropertyEvaluationParameters& parameters) {
+bool RenderCircleLayer::evaluate(const PropertyEvaluationParameters& parameters) {
evaluated = unevaluated.evaluate(parameters);
passes = ((evaluated.get<style::CircleRadius>().constantOr(1) > 0 ||
diff --git a/src/mbgl/renderer/render_circle_layer.hpp b/src/mbgl/renderer/render_circle_layer.hpp
index 5117b12246..8a2f73ec83 100644
--- a/src/mbgl/renderer/render_circle_layer.hpp
+++ b/src/mbgl/renderer/render_circle_layer.hpp
@@ -14,8 +14,8 @@ public:
std::unique_ptr<RenderLayer> clone() const override;
- void cascade(const style::CascadeParameters&) override;
- bool evaluate(const style::PropertyEvaluationParameters&) override;
+ void cascade(const CascadeParameters&) override;
+ bool evaluate(const PropertyEvaluationParameters&) override;
bool queryIntersectsFeature(
const GeometryCoordinates&,
diff --git a/src/mbgl/renderer/render_custom_layer.cpp b/src/mbgl/renderer/render_custom_layer.cpp
index f9dda47d7a..d500d11f4a 100644
--- a/src/mbgl/renderer/render_custom_layer.cpp
+++ b/src/mbgl/renderer/render_custom_layer.cpp
@@ -13,7 +13,7 @@ std::unique_ptr<RenderLayer> RenderCustomLayer::clone() const {
return std::make_unique<RenderCustomLayer>(*this);
}
-bool RenderCustomLayer::evaluate(const style::PropertyEvaluationParameters&) {
+bool RenderCustomLayer::evaluate(const PropertyEvaluationParameters&) {
passes = RenderPass::Translucent;
return false;
}
diff --git a/src/mbgl/renderer/render_custom_layer.hpp b/src/mbgl/renderer/render_custom_layer.hpp
index 3c6c06ff7c..cb728fecb3 100644
--- a/src/mbgl/renderer/render_custom_layer.hpp
+++ b/src/mbgl/renderer/render_custom_layer.hpp
@@ -13,8 +13,8 @@ public:
std::unique_ptr<RenderLayer> clone() const override;
- void cascade(const style::CascadeParameters&) final {}
- bool evaluate(const style::PropertyEvaluationParameters&) final;
+ void cascade(const CascadeParameters&) final {}
+ bool evaluate(const PropertyEvaluationParameters&) final;
std::unique_ptr<Bucket> createBucket(const BucketParameters&, const std::vector<const RenderLayer*>&) const final;
diff --git a/src/mbgl/renderer/render_fill_extrusion_layer.cpp b/src/mbgl/renderer/render_fill_extrusion_layer.cpp
index 8df0d36900..70ee74b56e 100644
--- a/src/mbgl/renderer/render_fill_extrusion_layer.cpp
+++ b/src/mbgl/renderer/render_fill_extrusion_layer.cpp
@@ -20,11 +20,11 @@ std::unique_ptr<Bucket> RenderFillExtrusionLayer::createBucket(const BucketParam
return std::make_unique<FillExtrusionBucket>(parameters, layers);
}
-void RenderFillExtrusionLayer::cascade(const style::CascadeParameters& parameters) {
+void RenderFillExtrusionLayer::cascade(const CascadeParameters& parameters) {
unevaluated = impl->cascading.cascade(parameters, std::move(unevaluated));
}
-bool RenderFillExtrusionLayer::evaluate(const style::PropertyEvaluationParameters& parameters) {
+bool RenderFillExtrusionLayer::evaluate(const PropertyEvaluationParameters& parameters) {
evaluated = unevaluated.evaluate(parameters);
passes = (evaluated.get<style::FillExtrusionOpacity>() > 0) ? RenderPass::Translucent
diff --git a/src/mbgl/renderer/render_fill_extrusion_layer.hpp b/src/mbgl/renderer/render_fill_extrusion_layer.hpp
index 87b6ad6071..b4fd1411f5 100644
--- a/src/mbgl/renderer/render_fill_extrusion_layer.hpp
+++ b/src/mbgl/renderer/render_fill_extrusion_layer.hpp
@@ -14,8 +14,8 @@ public:
std::unique_ptr<RenderLayer> clone() const override;
- void cascade(const style::CascadeParameters&) override;
- bool evaluate(const style::PropertyEvaluationParameters&) override;
+ void cascade(const CascadeParameters&) override;
+ bool evaluate(const PropertyEvaluationParameters&) override;
bool queryIntersectsFeature(
const GeometryCoordinates&,
diff --git a/src/mbgl/renderer/render_fill_layer.cpp b/src/mbgl/renderer/render_fill_layer.cpp
index 126189fc50..53c1ff3032 100644
--- a/src/mbgl/renderer/render_fill_layer.cpp
+++ b/src/mbgl/renderer/render_fill_layer.cpp
@@ -20,11 +20,11 @@ std::unique_ptr<Bucket> RenderFillLayer::createBucket(const BucketParameters& pa
return std::make_unique<FillBucket>(parameters, layers);
}
-void RenderFillLayer::cascade(const style::CascadeParameters& parameters) {
+void RenderFillLayer::cascade(const CascadeParameters& parameters) {
unevaluated = impl->cascading.cascade(parameters, std::move(unevaluated));
}
-bool RenderFillLayer::evaluate(const style::PropertyEvaluationParameters& parameters) {
+bool RenderFillLayer::evaluate(const PropertyEvaluationParameters& parameters) {
evaluated = unevaluated.evaluate(parameters);
if (unevaluated.get<style::FillOutlineColor>().isUndefined()) {
diff --git a/src/mbgl/renderer/render_fill_layer.hpp b/src/mbgl/renderer/render_fill_layer.hpp
index 25b969d4c3..3a8de3622a 100644
--- a/src/mbgl/renderer/render_fill_layer.hpp
+++ b/src/mbgl/renderer/render_fill_layer.hpp
@@ -14,8 +14,8 @@ public:
std::unique_ptr<RenderLayer> clone() const override;
- void cascade(const style::CascadeParameters&) override;
- bool evaluate(const style::PropertyEvaluationParameters&) override;
+ void cascade(const CascadeParameters&) override;
+ bool evaluate(const PropertyEvaluationParameters&) override;
bool queryIntersectsFeature(
const GeometryCoordinates&,
diff --git a/src/mbgl/renderer/render_layer.hpp b/src/mbgl/renderer/render_layer.hpp
index af5345d5e3..003059005e 100644
--- a/src/mbgl/renderer/render_layer.hpp
+++ b/src/mbgl/renderer/render_layer.hpp
@@ -12,11 +12,8 @@ namespace mbgl {
class Bucket;
class BucketParameters;
-
-namespace style {
class CascadeParameters;
class PropertyEvaluationParameters;
-} // namespace style
class RenderLayer {
@@ -33,11 +30,11 @@ public:
virtual std::unique_ptr<RenderLayer> clone() const = 0;
// Partially evaluate paint properties based on a set of classes.
- virtual void cascade(const style::CascadeParameters&) = 0;
+ virtual void cascade(const CascadeParameters&) = 0;
// Fully evaluate cascaded paint properties based on a zoom level.
// Returns true if any paint properties have active transitions.
- virtual bool evaluate(const style::PropertyEvaluationParameters&) = 0;
+ virtual bool evaluate(const PropertyEvaluationParameters&) = 0;
// Check whether this layer is of the given subtype.
template <class T>
diff --git a/src/mbgl/renderer/render_light.hpp b/src/mbgl/renderer/render_light.hpp
new file mode 100644
index 0000000000..8f59299552
--- /dev/null
+++ b/src/mbgl/renderer/render_light.hpp
@@ -0,0 +1,72 @@
+#pragma once
+
+#include <mbgl/style/light.hpp>
+#include <mbgl/renderer/transitioning_property.hpp>
+#include <mbgl/renderer/cascade_parameters.hpp>
+#include <mbgl/renderer/property_evaluator.hpp>
+#include <mbgl/renderer/property_evaluation_parameters.hpp>
+#include <mbgl/util/ignore.hpp>
+
+namespace mbgl {
+
+template <class TypeList>
+class Transitioning;
+
+template <class... Ps>
+class Transitioning<TypeList<Ps...>> : public IndexedTuple<
+ TypeList<Ps...>,
+ TypeList<TransitioningProperty<typename Ps::ValueType>...>>
+{
+private:
+ using Properties = TypeList<Ps...>;
+ using Raw = IndexedTuple<Properties, Properties>;
+ using Super = IndexedTuple<
+ TypeList<Ps...>,
+ TypeList<TransitioningProperty<typename Ps::ValueType>...>>;
+
+public:
+ Transitioning() = default;
+ Transitioning(const Raw& raw, Transitioning&& prior, const CascadeParameters& params)
+ : Super {
+ TransitioningProperty<typename Ps::ValueType>(
+ raw.template get<Ps>().value,
+ std::move(prior.template get<Ps>()),
+ raw.template get<Ps>().transition.reverseMerge(params.transition),
+ params.now)...
+ } {}
+
+ bool hasTransition() const {
+ bool result = false;
+ util::ignore({ result |= this->template get<Ps>().hasTransition()... });
+ return result;
+ }
+};
+
+template <class TypeList>
+class Evaluated;
+
+template <class... Ps>
+class Evaluated<TypeList<Ps...>> : public IndexedTuple<
+ TypeList<Ps...>,
+ TypeList<typename Ps::Type...>>
+{
+private:
+ using Properties = TypeList<Ps...>;
+ using TransitioningPs = Transitioning<Properties>;
+ using Super = IndexedTuple<
+ TypeList<Ps...>,
+ TypeList<typename Ps::Type...>>;
+
+public:
+ Evaluated() = default;
+ Evaluated(TransitioningPs& transitioning, const PropertyEvaluationParameters& params)
+ : Super {
+ transitioning.template get<Ps>()
+ .evaluate(PropertyEvaluator<typename Ps::Type>(params, Ps::defaultValue()), params.now)...
+ } {}
+};
+
+using TransitioningLight = Transitioning<style::LightProperties>;
+using EvaluatedLight = Evaluated<style::LightProperties>;
+
+} // namespace mbgl
diff --git a/src/mbgl/renderer/render_line_layer.cpp b/src/mbgl/renderer/render_line_layer.cpp
index 551d40bef5..e5060af79e 100644
--- a/src/mbgl/renderer/render_line_layer.cpp
+++ b/src/mbgl/renderer/render_line_layer.cpp
@@ -20,11 +20,11 @@ std::unique_ptr<Bucket> RenderLineLayer::createBucket(const BucketParameters& pa
return std::make_unique<LineBucket>(parameters, layers, impl->layout);
}
-void RenderLineLayer::cascade(const style::CascadeParameters& parameters) {
+void RenderLineLayer::cascade(const CascadeParameters& parameters) {
unevaluated = impl->cascading.cascade(parameters, std::move(unevaluated));
}
-bool RenderLineLayer::evaluate(const style::PropertyEvaluationParameters& parameters) {
+bool RenderLineLayer::evaluate(const PropertyEvaluationParameters& parameters) {
// for scaling dasharrays
auto dashArrayParams = parameters;
dashArrayParams.z = std::floor(dashArrayParams.z);
diff --git a/src/mbgl/renderer/render_line_layer.hpp b/src/mbgl/renderer/render_line_layer.hpp
index 0bde6f9a86..15052deb38 100644
--- a/src/mbgl/renderer/render_line_layer.hpp
+++ b/src/mbgl/renderer/render_line_layer.hpp
@@ -14,8 +14,8 @@ public:
std::unique_ptr<RenderLayer> clone() const override;
- void cascade(const style::CascadeParameters&) override;
- bool evaluate(const style::PropertyEvaluationParameters&) override;
+ void cascade(const CascadeParameters&) override;
+ bool evaluate(const PropertyEvaluationParameters&) override;
bool queryIntersectsFeature(
const GeometryCoordinates&,
diff --git a/src/mbgl/renderer/render_raster_layer.cpp b/src/mbgl/renderer/render_raster_layer.cpp
index f877a02398..0cfccc81b3 100644
--- a/src/mbgl/renderer/render_raster_layer.cpp
+++ b/src/mbgl/renderer/render_raster_layer.cpp
@@ -18,11 +18,11 @@ std::unique_ptr<Bucket> RenderRasterLayer::createBucket(const BucketParameters&,
return nullptr;
}
-void RenderRasterLayer::cascade(const style::CascadeParameters& parameters) {
+void RenderRasterLayer::cascade(const CascadeParameters& parameters) {
unevaluated = impl->cascading.cascade(parameters, std::move(unevaluated));
}
-bool RenderRasterLayer::evaluate(const style::PropertyEvaluationParameters& parameters) {
+bool RenderRasterLayer::evaluate(const PropertyEvaluationParameters& parameters) {
evaluated = unevaluated.evaluate(parameters);
passes = evaluated.get<style::RasterOpacity>() > 0 ? RenderPass::Translucent : RenderPass::None;
diff --git a/src/mbgl/renderer/render_raster_layer.hpp b/src/mbgl/renderer/render_raster_layer.hpp
index 1fd0fe7c47..c6e38fa147 100644
--- a/src/mbgl/renderer/render_raster_layer.hpp
+++ b/src/mbgl/renderer/render_raster_layer.hpp
@@ -14,8 +14,8 @@ public:
std::unique_ptr<RenderLayer> clone() const override;
- void cascade(const style::CascadeParameters&) override;
- bool evaluate(const style::PropertyEvaluationParameters&) override;
+ void cascade(const CascadeParameters&) override;
+ bool evaluate(const PropertyEvaluationParameters&) override;
std::unique_ptr<Bucket> createBucket(const BucketParameters&, const std::vector<const RenderLayer*>&) const override;
diff --git a/src/mbgl/renderer/render_source.hpp b/src/mbgl/renderer/render_source.hpp
index 5d93ae49d6..bec1d24d0f 100644
--- a/src/mbgl/renderer/render_source.hpp
+++ b/src/mbgl/renderer/render_source.hpp
@@ -21,15 +21,12 @@ class RenderedQueryOptions;
class SourceQueryOptions;
class Tile;
class RenderSourceObserver;
+class UpdateParameters;
namespace algorithm {
class ClipIDGenerator;
} // namespace algorithm
-namespace style {
-class UpdateParameters;
-} // namespace style
-
class RenderSource : protected TileObserver {
public:
RenderSource(const style::Source::Impl&);
@@ -39,7 +36,7 @@ public:
// Called when the camera has changed. May load new tiles, unload obsolete tiles, or
// trigger re-placement of existing complete tiles.
- virtual void updateTiles(const style::UpdateParameters&) = 0;
+ virtual void updateTiles(const UpdateParameters&) = 0;
// Removes all tiles (by putting them into the cache).
virtual void removeTiles() = 0;
diff --git a/src/mbgl/renderer/render_symbol_layer.cpp b/src/mbgl/renderer/render_symbol_layer.cpp
index d46dc614f0..0c3601aedf 100644
--- a/src/mbgl/renderer/render_symbol_layer.cpp
+++ b/src/mbgl/renderer/render_symbol_layer.cpp
@@ -2,8 +2,8 @@
#include <mbgl/layout/symbol_layout.hpp>
#include <mbgl/renderer/bucket.hpp>
#include <mbgl/renderer/bucket_parameters.hpp>
+#include <mbgl/renderer/property_evaluation_parameters.hpp>
#include <mbgl/style/layers/symbol_layer_impl.hpp>
-#include <mbgl/style/property_evaluation_parameters.hpp>
#include <mbgl/tile/geometry_tile_data.hpp>
namespace mbgl {
@@ -34,11 +34,11 @@ std::unique_ptr<SymbolLayout> RenderSymbolLayer::createLayout(const BucketParame
glyphDependencies);
}
-void RenderSymbolLayer::cascade(const style::CascadeParameters& parameters) {
+void RenderSymbolLayer::cascade(const CascadeParameters& parameters) {
unevaluated = impl->cascading.cascade(parameters, std::move(unevaluated));
}
-bool RenderSymbolLayer::evaluate(const style::PropertyEvaluationParameters& parameters) {
+bool RenderSymbolLayer::evaluate(const PropertyEvaluationParameters& parameters) {
evaluated = unevaluated.evaluate(parameters);
auto hasIconOpacity = evaluated.get<style::IconColor>().constantOr(Color::black()).a > 0 ||
diff --git a/src/mbgl/renderer/render_symbol_layer.hpp b/src/mbgl/renderer/render_symbol_layer.hpp
index b19b236e90..b9c2cc3247 100644
--- a/src/mbgl/renderer/render_symbol_layer.hpp
+++ b/src/mbgl/renderer/render_symbol_layer.hpp
@@ -66,8 +66,8 @@ public:
std::unique_ptr<RenderLayer> clone() const override;
- void cascade(const style::CascadeParameters&) override;
- bool evaluate(const style::PropertyEvaluationParameters&) override;
+ void cascade(const CascadeParameters&) override;
+ bool evaluate(const PropertyEvaluationParameters&) override;
style::IconPaintProperties::Evaluated iconPaintProperties() const;
style::TextPaintProperties::Evaluated textPaintProperties() const;
diff --git a/src/mbgl/renderer/sources/render_geojson_source.hpp b/src/mbgl/renderer/sources/render_geojson_source.hpp
index 3476b63afd..502df0f1c5 100644
--- a/src/mbgl/renderer/sources/render_geojson_source.hpp
+++ b/src/mbgl/renderer/sources/render_geojson_source.hpp
@@ -18,7 +18,7 @@ public:
// Called when the camera has changed. May load new tiles, unload obsolete tiles, or
// trigger re-placement of existing complete tiles.
- void updateTiles(const style::UpdateParameters&) final;
+ void updateTiles(const UpdateParameters&) final;
// Removes all tiles (by putting them into the cache).
void removeTiles() final;
diff --git a/src/mbgl/renderer/sources/render_raster_source.hpp b/src/mbgl/renderer/sources/render_raster_source.hpp
index 6b95be363f..ebb7b62150 100644
--- a/src/mbgl/renderer/sources/render_raster_source.hpp
+++ b/src/mbgl/renderer/sources/render_raster_source.hpp
@@ -14,7 +14,7 @@ public:
// Called when the camera has changed. May load new tiles, unload obsolete tiles, or
// trigger re-placement of existing complete tiles.
- void updateTiles(const style::UpdateParameters&) final;
+ void updateTiles(const UpdateParameters&) final;
// Removes all tiles (by putting them into the cache).
void removeTiles() final;
diff --git a/src/mbgl/renderer/sources/render_vector_source.hpp b/src/mbgl/renderer/sources/render_vector_source.hpp
index 0f40c14cf5..c435db6f0b 100644
--- a/src/mbgl/renderer/sources/render_vector_source.hpp
+++ b/src/mbgl/renderer/sources/render_vector_source.hpp
@@ -14,7 +14,7 @@ public:
// Called when the camera has changed. May load new tiles, unload obsolete tiles, or
// trigger re-placement of existing complete tiles.
- void updateTiles(const style::UpdateParameters&) final;
+ void updateTiles(const UpdateParameters&) final;
// Removes all tiles (by putting them into the cache).
void removeTiles() final;
diff --git a/src/mbgl/renderer/tile_pyramid.cpp b/src/mbgl/renderer/tile_pyramid.cpp
index 130b9dc5b6..97f9f31937 100644
--- a/src/mbgl/renderer/tile_pyramid.cpp
+++ b/src/mbgl/renderer/tile_pyramid.cpp
@@ -2,7 +2,7 @@
#include <mbgl/renderer/render_tile.hpp>
#include <mbgl/renderer/painter.hpp>
#include <mbgl/renderer/render_source.hpp>
-#include <mbgl/style/update_parameters.hpp>
+#include <mbgl/renderer/update_parameters.hpp>
#include <mbgl/map/transform.hpp>
#include <mbgl/map/query.hpp>
#include <mbgl/text/placement_config.hpp>
diff --git a/src/mbgl/renderer/tile_pyramid.hpp b/src/mbgl/renderer/tile_pyramid.hpp
index a38a21dd88..b8ffbfb2b0 100644
--- a/src/mbgl/renderer/tile_pyramid.hpp
+++ b/src/mbgl/renderer/tile_pyramid.hpp
@@ -22,10 +22,7 @@ class TransformState;
class RenderTile;
class RenderedQueryOptions;
class SourceQueryOptions;
-
-namespace style {
class UpdateParameters;
-} // namespace style
class TilePyramid {
public:
@@ -36,7 +33,7 @@ public:
// Called when the camera has changed. May load new tiles, unload obsolete tiles, or
// trigger re-placement of existing complete tiles.
- void updateTiles(const style::UpdateParameters&,
+ void updateTiles(const UpdateParameters&,
SourceType type,
uint16_t tileSize,
Range<uint8_t> zoomRange,
diff --git a/src/mbgl/renderer/transitioning_property.hpp b/src/mbgl/renderer/transitioning_property.hpp
new file mode 100644
index 0000000000..c211ccf116
--- /dev/null
+++ b/src/mbgl/renderer/transitioning_property.hpp
@@ -0,0 +1,75 @@
+#pragma once
+
+#include <mbgl/style/property_value.hpp>
+#include <mbgl/style/data_driven_property_value.hpp>
+#include <mbgl/style/transition_options.hpp>
+#include <mbgl/util/interpolate.hpp>
+
+#include <utility>
+
+namespace mbgl {
+
+template <class Value>
+class TransitioningProperty {
+public:
+ TransitioningProperty() = default;
+
+ TransitioningProperty(Value value_,
+ TransitioningProperty<Value> prior_,
+ style::TransitionOptions transition,
+ TimePoint now)
+ : begin(now + transition.delay.value_or(Duration::zero())),
+ end(begin + transition.duration.value_or(Duration::zero())),
+ value(std::move(value_)) {
+ if (transition.isDefined()) {
+ prior = { std::move(prior_) };
+ }
+ }
+
+ template <class Evaluator>
+ auto evaluate(const Evaluator& evaluator, TimePoint now) {
+ auto finalValue = value.evaluate(evaluator);
+ if (!prior) {
+ // No prior value.
+ return finalValue;
+ } else if (now >= end) {
+ // Transition from prior value is now complete.
+ prior = {};
+ return finalValue;
+ } else if (value.isDataDriven()) {
+ // Transitions to data-driven properties are not supported.
+ // We snap immediately to the data-driven value so that, when we perform layout,
+ // we see the data-driven function and can use it to populate vertex buffers.
+ prior = {};
+ return finalValue;
+ } else if (now < begin) {
+ // Transition hasn't started yet.
+ return prior->get().evaluate(evaluator, now);
+ } else {
+ // Interpolate between recursively-calculated prior value and final.
+ float t = std::chrono::duration<float>(now - begin) / (end - begin);
+ return util::interpolate(prior->get().evaluate(evaluator, now), finalValue,
+ util::DEFAULT_TRANSITION_EASE.solve(t, 0.001));
+ }
+ }
+
+ bool hasTransition() const {
+ return bool(prior);
+ }
+
+ bool isUndefined() const {
+ return value.isUndefined();
+ }
+
+ const Value& getValue() const {
+ return value;
+ }
+
+private:
+ optional<mapbox::util::recursive_wrapper<TransitioningProperty<Value>>> prior;
+ TimePoint begin;
+ TimePoint end;
+ Value value;
+};
+
+} // namespace mbgl
diff --git a/src/mbgl/renderer/update_parameters.hpp b/src/mbgl/renderer/update_parameters.hpp
new file mode 100644
index 0000000000..a00e01b973
--- /dev/null
+++ b/src/mbgl/renderer/update_parameters.hpp
@@ -0,0 +1,47 @@
+#pragma once
+
+#include <mbgl/map/mode.hpp>
+
+namespace mbgl {
+
+class TransformState;
+class Scheduler;
+class FileSource;
+class AnnotationManager;
+
+namespace style {
+class Style;
+} // namespace style
+
+class UpdateParameters {
+public:
+ UpdateParameters(float pixelRatio_,
+ MapDebugOptions debugOptions_,
+ const TransformState& transformState_,
+ Scheduler& workerScheduler_,
+ FileSource& fileSource_,
+ const MapMode mode_,
+ AnnotationManager& annotationManager_,
+ style::Style& style_)
+ : pixelRatio(pixelRatio_),
+ debugOptions(debugOptions_),
+ transformState(transformState_),
+ workerScheduler(workerScheduler_),
+ fileSource(fileSource_),
+ mode(mode_),
+ annotationManager(annotationManager_),
+ style(style_) {}
+
+ float pixelRatio;
+ MapDebugOptions debugOptions;
+ const TransformState& transformState;
+ Scheduler& workerScheduler;
+ FileSource& fileSource;
+ const MapMode mode;
+ AnnotationManager& annotationManager;
+
+ // TODO: remove
+ style::Style& style;
+};
+
+} // namespace mbgl