summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohn Firebaugh <john.firebaugh@gmail.com>2015-10-19 18:30:25 -0700
committerJohn Firebaugh <john.firebaugh@gmail.com>2015-10-26 12:00:11 -0700
commitbb6241844a092cf632fe740e6ac79c920117dd4e (patch)
tree6d2540fde2c2a3fbe3d1f8bfce32c57e192894d9 /src
parente257ad284bf02f658949f3f2ddb7becbbcf1f820 (diff)
downloadqtlocation-mapboxgl-bb6241844a092cf632fe740e6ac79c920117dd4e.tar.gz
[core] Extract PaintPropertiesMap
Diffstat (limited to 'src')
-rw-r--r--src/mbgl/annotation/annotation_manager.cpp1
-rw-r--r--src/mbgl/annotation/shape_annotation_impl.cpp6
-rw-r--r--src/mbgl/layer/background_layer.cpp13
-rw-r--r--src/mbgl/layer/background_layer.hpp2
-rw-r--r--src/mbgl/layer/circle_layer.cpp19
-rw-r--r--src/mbgl/layer/circle_layer.hpp2
-rw-r--r--src/mbgl/layer/fill_layer.cpp28
-rw-r--r--src/mbgl/layer/fill_layer.hpp2
-rw-r--r--src/mbgl/layer/line_layer.cpp26
-rw-r--r--src/mbgl/layer/line_layer.hpp2
-rw-r--r--src/mbgl/layer/raster_layer.cpp21
-rw-r--r--src/mbgl/layer/raster_layer.hpp2
-rw-r--r--src/mbgl/layer/symbol_layer.cpp34
-rw-r--r--src/mbgl/layer/symbol_layer.hpp2
-rw-r--r--src/mbgl/style/paint_properties_map.cpp114
-rw-r--r--src/mbgl/style/paint_properties_map.hpp89
-rw-r--r--src/mbgl/style/style.cpp9
-rw-r--r--src/mbgl/style/style_layer.cpp120
-rw-r--r--src/mbgl/style/style_layer.hpp97
-rw-r--r--src/mbgl/style/style_parser.cpp2
20 files changed, 318 insertions, 273 deletions
diff --git a/src/mbgl/annotation/annotation_manager.cpp b/src/mbgl/annotation/annotation_manager.cpp
index b8e9f973f2..374d770a29 100644
--- a/src/mbgl/annotation/annotation_manager.cpp
+++ b/src/mbgl/annotation/annotation_manager.cpp
@@ -115,7 +115,6 @@ void AnnotationManager::updateStyle(Style& style) {
std::unique_ptr<SymbolLayer> layer = std::make_unique<SymbolLayer>();
layer->id = PointLayerID;
layer->type = StyleLayerType::Symbol;
- layer->styles.emplace(ClassID::Default, ClassProperties());
layer->bucket = std::make_shared<StyleBucket>(layer->type);
layer->bucket->name = layer->id;
diff --git a/src/mbgl/annotation/shape_annotation_impl.cpp b/src/mbgl/annotation/shape_annotation_impl.cpp
index 45b25f45e5..b70b3423ba 100644
--- a/src/mbgl/annotation/shape_annotation_impl.cpp
+++ b/src/mbgl/annotation/shape_annotation_impl.cpp
@@ -37,7 +37,7 @@ void ShapeAnnotationImpl::updateStyle(Style& style) {
paintProperties.set(PropertyKey::LineOpacity, ConstantFunction<float>(properties.opacity));
paintProperties.set(PropertyKey::LineWidth, ConstantFunction<float>(properties.width));
paintProperties.set(PropertyKey::LineColor, ConstantFunction<Color>(properties.color));
- layer->styles.emplace(ClassID::Default, std::move(paintProperties));
+ layer->paints.paints.emplace(ClassID::Default, std::move(paintProperties));
} else if (shape.properties.is<FillPaintProperties>()) {
layer = createFillLayer();
@@ -47,7 +47,7 @@ void ShapeAnnotationImpl::updateStyle(Style& style) {
paintProperties.set(PropertyKey::FillOpacity, ConstantFunction<float>(properties.opacity));
paintProperties.set(PropertyKey::FillColor, ConstantFunction<Color>(properties.fill_color));
paintProperties.set(PropertyKey::FillOutlineColor, ConstantFunction<Color>(properties.stroke_color));
- layer->styles.emplace(ClassID::Default, std::move(paintProperties));
+ layer->paints.paints.emplace(ClassID::Default, std::move(paintProperties));
} else {
beforeLayerID = shape.properties.get<std::string>();
@@ -68,7 +68,7 @@ void ShapeAnnotationImpl::updateStyle(Style& style) {
return;
}
- layer->styles = sourceLayer->styles;
+ layer->paints.paints = sourceLayer->paints.paints;
layer->bucket->layout = sourceLayer->bucket->layout;
}
diff --git a/src/mbgl/layer/background_layer.cpp b/src/mbgl/layer/background_layer.cpp
index 271c5479e9..31e524bc81 100644
--- a/src/mbgl/layer/background_layer.cpp
+++ b/src/mbgl/layer/background_layer.cpp
@@ -2,11 +2,14 @@
namespace mbgl {
-RenderPass BackgroundLayer::applyStyleProperties(const StyleCalculationParameters& parameters) {
- applyTransitionedStyleProperty(PropertyKey::BackgroundOpacity, properties.opacity, parameters);
- applyTransitionedStyleProperty(PropertyKey::BackgroundColor, properties.color, parameters);
- applyStyleProperty(PropertyKey::BackgroundImage, properties.image, parameters);
- return properties.isVisible() ? RenderPass::Translucent : RenderPass::None;
+void BackgroundLayer::recalculate(const StyleCalculationParameters& parameters) {
+ paints.removeExpiredTransitions(parameters.now);
+
+ paints.calculateTransitioned(PropertyKey::BackgroundOpacity, properties.opacity, parameters);
+ paints.calculateTransitioned(PropertyKey::BackgroundColor, properties.color, parameters);
+ paints.calculate(PropertyKey::BackgroundImage, properties.image, parameters);
+
+ passes = properties.isVisible() ? RenderPass::Translucent : RenderPass::None;
}
}
diff --git a/src/mbgl/layer/background_layer.hpp b/src/mbgl/layer/background_layer.hpp
index c5d211c9c6..8fe689ee66 100644
--- a/src/mbgl/layer/background_layer.hpp
+++ b/src/mbgl/layer/background_layer.hpp
@@ -8,7 +8,7 @@ namespace mbgl {
class BackgroundLayer : public StyleLayer {
public:
- RenderPass applyStyleProperties(const StyleCalculationParameters&) override;
+ void recalculate(const StyleCalculationParameters&) override;
BackgroundPaintProperties properties;
};
diff --git a/src/mbgl/layer/circle_layer.cpp b/src/mbgl/layer/circle_layer.cpp
index 75044b6a41..0f16b02d3c 100644
--- a/src/mbgl/layer/circle_layer.cpp
+++ b/src/mbgl/layer/circle_layer.cpp
@@ -2,14 +2,17 @@
namespace mbgl {
-RenderPass CircleLayer::applyStyleProperties(const StyleCalculationParameters& parameters) {
- applyTransitionedStyleProperty(PropertyKey::CircleRadius, properties.radius, parameters);
- applyTransitionedStyleProperty(PropertyKey::CircleColor, properties.color, parameters);
- applyTransitionedStyleProperty(PropertyKey::CircleOpacity, properties.opacity, parameters);
- applyTransitionedStyleProperty(PropertyKey::CircleTranslate, properties.translate, parameters);
- applyStyleProperty(PropertyKey::CircleTranslateAnchor, properties.translateAnchor, parameters);
- applyTransitionedStyleProperty(PropertyKey::CircleBlur, properties.blur, parameters);
- return properties.isVisible() ? RenderPass::Translucent : RenderPass::None;
+void CircleLayer::recalculate(const StyleCalculationParameters& parameters) {
+ paints.removeExpiredTransitions(parameters.now);
+
+ paints.calculateTransitioned(PropertyKey::CircleRadius, properties.radius, parameters);
+ paints.calculateTransitioned(PropertyKey::CircleColor, properties.color, parameters);
+ paints.calculateTransitioned(PropertyKey::CircleOpacity, properties.opacity, parameters);
+ paints.calculateTransitioned(PropertyKey::CircleTranslate, properties.translate, parameters);
+ paints.calculate(PropertyKey::CircleTranslateAnchor, properties.translateAnchor, parameters);
+ paints.calculateTransitioned(PropertyKey::CircleBlur, properties.blur, parameters);
+
+ passes = properties.isVisible() ? RenderPass::Translucent : RenderPass::None;
}
}
diff --git a/src/mbgl/layer/circle_layer.hpp b/src/mbgl/layer/circle_layer.hpp
index 78a4ee7b77..ae1f68198d 100644
--- a/src/mbgl/layer/circle_layer.hpp
+++ b/src/mbgl/layer/circle_layer.hpp
@@ -8,7 +8,7 @@ namespace mbgl {
class CircleLayer : public StyleLayer {
public:
- RenderPass applyStyleProperties(const StyleCalculationParameters&) override;
+ void recalculate(const StyleCalculationParameters&) override;
CirclePaintProperties properties;
};
diff --git a/src/mbgl/layer/fill_layer.cpp b/src/mbgl/layer/fill_layer.cpp
index 792fd947b6..ba3001efa6 100644
--- a/src/mbgl/layer/fill_layer.cpp
+++ b/src/mbgl/layer/fill_layer.cpp
@@ -2,28 +2,28 @@
namespace mbgl {
-RenderPass FillLayer::applyStyleProperties(const StyleCalculationParameters& parameters) {
- applyStyleProperty(PropertyKey::FillAntialias, properties.antialias, parameters);
- applyTransitionedStyleProperty(PropertyKey::FillOpacity, properties.opacity, parameters);
- applyTransitionedStyleProperty(PropertyKey::FillColor, properties.fill_color, parameters);
- applyTransitionedStyleProperty(PropertyKey::FillOutlineColor, properties.stroke_color, parameters);
- applyTransitionedStyleProperty(PropertyKey::FillTranslate, properties.translate, parameters);
- applyStyleProperty(PropertyKey::FillTranslateAnchor, properties.translateAnchor, parameters);
- applyStyleProperty(PropertyKey::FillImage, properties.image, parameters);
+void FillLayer::recalculate(const StyleCalculationParameters& parameters) {
+ paints.removeExpiredTransitions(parameters.now);
- RenderPass result = RenderPass::None;
+ paints.calculate(PropertyKey::FillAntialias, properties.antialias, parameters);
+ paints.calculateTransitioned(PropertyKey::FillOpacity, properties.opacity, parameters);
+ paints.calculateTransitioned(PropertyKey::FillColor, properties.fill_color, parameters);
+ paints.calculateTransitioned(PropertyKey::FillOutlineColor, properties.stroke_color, parameters);
+ paints.calculateTransitioned(PropertyKey::FillTranslate, properties.translate, parameters);
+ paints.calculate(PropertyKey::FillTranslateAnchor, properties.translateAnchor, parameters);
+ paints.calculate(PropertyKey::FillImage, properties.image, parameters);
+
+ passes = RenderPass::None;
if (properties.antialias) {
- result |= RenderPass::Translucent;
+ passes |= RenderPass::Translucent;
}
if (!properties.image.from.empty() || (properties.fill_color[3] * properties.opacity) < 1.0f) {
- result |= RenderPass::Translucent;
+ passes |= RenderPass::Translucent;
} else {
- result |= RenderPass::Opaque;
+ passes |= RenderPass::Opaque;
}
-
- return result;
}
}
diff --git a/src/mbgl/layer/fill_layer.hpp b/src/mbgl/layer/fill_layer.hpp
index 6538d369dd..59ccaf36c6 100644
--- a/src/mbgl/layer/fill_layer.hpp
+++ b/src/mbgl/layer/fill_layer.hpp
@@ -8,7 +8,7 @@ namespace mbgl {
class FillLayer : public StyleLayer {
public:
- RenderPass applyStyleProperties(const StyleCalculationParameters&) override;
+ void recalculate(const StyleCalculationParameters&) override;
FillPaintProperties properties;
};
diff --git a/src/mbgl/layer/line_layer.cpp b/src/mbgl/layer/line_layer.cpp
index 9e520da6db..4556741029 100644
--- a/src/mbgl/layer/line_layer.cpp
+++ b/src/mbgl/layer/line_layer.cpp
@@ -2,23 +2,25 @@
namespace mbgl {
-RenderPass LineLayer::applyStyleProperties(const StyleCalculationParameters& parameters) {
- applyTransitionedStyleProperty(PropertyKey::LineOpacity, properties.opacity, parameters);
- applyTransitionedStyleProperty(PropertyKey::LineColor, properties.color, parameters);
- applyTransitionedStyleProperty(PropertyKey::LineTranslate, properties.translate, parameters);
- applyStyleProperty(PropertyKey::LineTranslateAnchor, properties.translateAnchor, parameters);
- applyTransitionedStyleProperty(PropertyKey::LineWidth, properties.width, parameters);
- applyTransitionedStyleProperty(PropertyKey::LineGapWidth, properties.gap_width, parameters);
- applyTransitionedStyleProperty(PropertyKey::LineBlur, properties.blur, parameters);
- applyStyleProperty(PropertyKey::LineDashArray, properties.dash_array, parameters);
- applyStyleProperty(PropertyKey::LineImage, properties.image, parameters);
+void LineLayer::recalculate(const StyleCalculationParameters& parameters) {
+ paints.removeExpiredTransitions(parameters.now);
+
+ paints.calculateTransitioned(PropertyKey::LineOpacity, properties.opacity, parameters);
+ paints.calculateTransitioned(PropertyKey::LineColor, properties.color, parameters);
+ paints.calculateTransitioned(PropertyKey::LineTranslate, properties.translate, parameters);
+ paints.calculate(PropertyKey::LineTranslateAnchor, properties.translateAnchor, parameters);
+ paints.calculateTransitioned(PropertyKey::LineWidth, properties.width, parameters);
+ paints.calculateTransitioned(PropertyKey::LineGapWidth, properties.gap_width, parameters);
+ paints.calculateTransitioned(PropertyKey::LineBlur, properties.blur, parameters);
+ paints.calculate(PropertyKey::LineDashArray, properties.dash_array, parameters);
+ paints.calculate(PropertyKey::LineImage, properties.image, parameters);
// for scaling dasharrays
StyleCalculationParameters dashArrayParams = parameters;
dashArrayParams.z = std::floor(dashArrayParams.z);
- applyStyleProperty(PropertyKey::LineWidth, properties.dash_line_width, dashArrayParams);
+ paints.calculate(PropertyKey::LineWidth, properties.dash_line_width, dashArrayParams);
- return properties.isVisible() ? RenderPass::Translucent : RenderPass::None;
+ passes = properties.isVisible() ? RenderPass::Translucent : RenderPass::None;
}
}
diff --git a/src/mbgl/layer/line_layer.hpp b/src/mbgl/layer/line_layer.hpp
index f5125bcd8d..d9cf73521b 100644
--- a/src/mbgl/layer/line_layer.hpp
+++ b/src/mbgl/layer/line_layer.hpp
@@ -8,7 +8,7 @@ namespace mbgl {
class LineLayer : public StyleLayer {
public:
- RenderPass applyStyleProperties(const StyleCalculationParameters&) override;
+ void recalculate(const StyleCalculationParameters&) override;
LinePaintProperties properties;
};
diff --git a/src/mbgl/layer/raster_layer.cpp b/src/mbgl/layer/raster_layer.cpp
index 2087f4db79..b217f9d356 100644
--- a/src/mbgl/layer/raster_layer.cpp
+++ b/src/mbgl/layer/raster_layer.cpp
@@ -2,15 +2,18 @@
namespace mbgl {
-RenderPass RasterLayer::applyStyleProperties(const StyleCalculationParameters& parameters) {
- applyTransitionedStyleProperty(PropertyKey::RasterOpacity, properties.opacity, parameters);
- applyTransitionedStyleProperty(PropertyKey::RasterHueRotate, properties.hue_rotate, parameters);
- applyTransitionedStyleProperty(PropertyKey::RasterBrightnessLow, properties.brightness[0], parameters);
- applyTransitionedStyleProperty(PropertyKey::RasterBrightnessHigh, properties.brightness[1], parameters);
- applyTransitionedStyleProperty(PropertyKey::RasterSaturation, properties.saturation, parameters);
- applyTransitionedStyleProperty(PropertyKey::RasterContrast, properties.contrast, parameters);
- applyTransitionedStyleProperty(PropertyKey::RasterFade, properties.fade, parameters);
- return properties.isVisible() ? RenderPass::Translucent : RenderPass::None;
+void RasterLayer::recalculate(const StyleCalculationParameters& parameters) {
+ paints.removeExpiredTransitions(parameters.now);
+
+ paints.calculateTransitioned(PropertyKey::RasterOpacity, properties.opacity, parameters);
+ paints.calculateTransitioned(PropertyKey::RasterHueRotate, properties.hue_rotate, parameters);
+ paints.calculateTransitioned(PropertyKey::RasterBrightnessLow, properties.brightness[0], parameters);
+ paints.calculateTransitioned(PropertyKey::RasterBrightnessHigh, properties.brightness[1], parameters);
+ paints.calculateTransitioned(PropertyKey::RasterSaturation, properties.saturation, parameters);
+ paints.calculateTransitioned(PropertyKey::RasterContrast, properties.contrast, parameters);
+ paints.calculateTransitioned(PropertyKey::RasterFade, properties.fade, parameters);
+
+ passes = properties.isVisible() ? RenderPass::Translucent : RenderPass::None;
}
}
diff --git a/src/mbgl/layer/raster_layer.hpp b/src/mbgl/layer/raster_layer.hpp
index b11c829452..ba34dc60c0 100644
--- a/src/mbgl/layer/raster_layer.hpp
+++ b/src/mbgl/layer/raster_layer.hpp
@@ -8,7 +8,7 @@ namespace mbgl {
class RasterLayer : public StyleLayer {
public:
- RenderPass applyStyleProperties(const StyleCalculationParameters&) override;
+ void recalculate(const StyleCalculationParameters&) override;
RasterPaintProperties properties;
};
diff --git a/src/mbgl/layer/symbol_layer.cpp b/src/mbgl/layer/symbol_layer.cpp
index 08a994d176..940c518430 100644
--- a/src/mbgl/layer/symbol_layer.cpp
+++ b/src/mbgl/layer/symbol_layer.cpp
@@ -4,22 +4,24 @@
namespace mbgl {
-RenderPass SymbolLayer::applyStyleProperties(const StyleCalculationParameters& parameters) {
- applyTransitionedStyleProperty(PropertyKey::IconOpacity, properties.icon.opacity, parameters);
- applyTransitionedStyleProperty(PropertyKey::IconColor, properties.icon.color, parameters);
- applyTransitionedStyleProperty(PropertyKey::IconHaloColor, properties.icon.halo_color, parameters);
- applyTransitionedStyleProperty(PropertyKey::IconHaloWidth, properties.icon.halo_width, parameters);
- applyTransitionedStyleProperty(PropertyKey::IconHaloBlur, properties.icon.halo_blur, parameters);
- applyTransitionedStyleProperty(PropertyKey::IconTranslate, properties.icon.translate, parameters);
- applyStyleProperty(PropertyKey::IconTranslateAnchor, properties.icon.translate_anchor, parameters);
+void SymbolLayer::recalculate(const StyleCalculationParameters& parameters) {
+ paints.removeExpiredTransitions(parameters.now);
- applyTransitionedStyleProperty(PropertyKey::TextOpacity, properties.text.opacity, parameters);
- applyTransitionedStyleProperty(PropertyKey::TextColor, properties.text.color, parameters);
- applyTransitionedStyleProperty(PropertyKey::TextHaloColor, properties.text.halo_color, parameters);
- applyTransitionedStyleProperty(PropertyKey::TextHaloWidth, properties.text.halo_width, parameters);
- applyTransitionedStyleProperty(PropertyKey::TextHaloBlur, properties.text.halo_blur, parameters);
- applyTransitionedStyleProperty(PropertyKey::TextTranslate, properties.text.translate, parameters);
- applyStyleProperty(PropertyKey::TextTranslateAnchor, properties.text.translate_anchor, parameters);
+ paints.calculateTransitioned(PropertyKey::IconOpacity, properties.icon.opacity, parameters);
+ paints.calculateTransitioned(PropertyKey::IconColor, properties.icon.color, parameters);
+ paints.calculateTransitioned(PropertyKey::IconHaloColor, properties.icon.halo_color, parameters);
+ paints.calculateTransitioned(PropertyKey::IconHaloWidth, properties.icon.halo_width, parameters);
+ paints.calculateTransitioned(PropertyKey::IconHaloBlur, properties.icon.halo_blur, parameters);
+ paints.calculateTransitioned(PropertyKey::IconTranslate, properties.icon.translate, parameters);
+ paints.calculate(PropertyKey::IconTranslateAnchor, properties.icon.translate_anchor, parameters);
+
+ paints.calculateTransitioned(PropertyKey::TextOpacity, properties.text.opacity, parameters);
+ paints.calculateTransitioned(PropertyKey::TextColor, properties.text.color, parameters);
+ paints.calculateTransitioned(PropertyKey::TextHaloColor, properties.text.halo_color, parameters);
+ paints.calculateTransitioned(PropertyKey::TextHaloWidth, properties.text.halo_width, parameters);
+ paints.calculateTransitioned(PropertyKey::TextHaloBlur, properties.text.halo_blur, parameters);
+ paints.calculateTransitioned(PropertyKey::TextTranslate, properties.text.translate, parameters);
+ paints.calculate(PropertyKey::TextTranslateAnchor, properties.text.translate_anchor, parameters);
// text-size and icon-size are layout properties but they also need to be evaluated as paint properties:
auto it = bucket->layout.properties.find(PropertyKey::IconSize);
@@ -33,7 +35,7 @@ RenderPass SymbolLayer::applyStyleProperties(const StyleCalculationParameters& p
properties.text.size = mapbox::util::apply_visitor(evaluator, it->second);
}
- return properties.isVisible() ? RenderPass::Translucent : RenderPass::None;
+ passes = properties.isVisible() ? RenderPass::Translucent : RenderPass::None;
}
}
diff --git a/src/mbgl/layer/symbol_layer.hpp b/src/mbgl/layer/symbol_layer.hpp
index abc0f2109a..52aed14a14 100644
--- a/src/mbgl/layer/symbol_layer.hpp
+++ b/src/mbgl/layer/symbol_layer.hpp
@@ -8,7 +8,7 @@ namespace mbgl {
class SymbolLayer : public StyleLayer {
public:
- RenderPass applyStyleProperties(const StyleCalculationParameters&) override;
+ void recalculate(const StyleCalculationParameters&) override;
SymbolPaintProperties properties;
};
diff --git a/src/mbgl/style/paint_properties_map.cpp b/src/mbgl/style/paint_properties_map.cpp
new file mode 100644
index 0000000000..18f6867457
--- /dev/null
+++ b/src/mbgl/style/paint_properties_map.cpp
@@ -0,0 +1,114 @@
+#include <mbgl/style/paint_properties_map.hpp>
+#include <mbgl/style/property_transition.hpp>
+#include <mbgl/style/property_fallback.hpp>
+#include <mbgl/style/class_properties.hpp>
+
+namespace mbgl {
+
+void PaintPropertiesMap::cascade(const std::vector<std::string>& classes,
+ const TimePoint& now,
+ const PropertyTransition& defaultTransition) {
+ // Stores all keys that we have already added transitions for.
+ std::set<PropertyKey> alreadyApplied;
+
+ // We only apply the default style values if there are no classes set.
+ if (classes.empty()) {
+ cascadeClass(ClassID::Default, alreadyApplied, now, defaultTransition);
+ return;
+ }
+
+ // Reverse iterate through all class names and apply them last to first.
+ for (auto it = classes.rbegin(); it != classes.rend(); ++it) {
+ // From here on, we're only dealing with IDs to avoid comparing strings all the time.
+ cascadeClass(ClassDictionary::Get().lookup(*it), alreadyApplied, now, defaultTransition);
+ }
+
+ // As the last class, apply the default class.
+ cascadeClass(ClassID::Default, alreadyApplied, now, defaultTransition);
+
+ // Make sure that we also transition to the fallback value for keys that aren't changed by
+ // any applied classes.
+ for (auto& propertyPair : appliedStyle) {
+ const PropertyKey key = propertyPair.first;
+ if (alreadyApplied.find(key) != alreadyApplied.end()) {
+ // This property has already been set by a previous class, so we don't need to
+ // transition to the fallback.
+ continue;
+ }
+
+ AppliedClassPropertyValues &appliedProperties = propertyPair.second;
+ // Make sure that we don't do double transitions to the fallback value.
+ if (appliedProperties.mostRecent() == ClassID::Fallback) {
+ continue;
+ }
+
+ // This property key hasn't been set by a previous class, so we need to add a transition
+ // to the fallback value for that key.
+ const TimePoint begin = now + *defaultTransition.delay;
+ const TimePoint end = begin + *defaultTransition.duration;
+ const PropertyValue &value = PropertyFallbackValue::Get(key);
+ appliedProperties.add(ClassID::Fallback, begin, end, value);
+ }
+}
+
+void PaintPropertiesMap::cascadeClass(const ClassID classID,
+ std::set<PropertyKey>& alreadyApplied,
+ const TimePoint& now,
+ const PropertyTransition& defaultTransition) {
+ auto styleIt = paints.find(classID);
+ if (styleIt == paints.end()) {
+ // There is no class in this layer with this class_name.
+ return;
+ }
+
+ // Loop through all the properties in this style, and add transitions to them, if they're
+ // not already the most recent transition.
+ const ClassProperties& classProperties = styleIt->second;
+ for (const auto& propertyPair : classProperties) {
+ PropertyKey key = propertyPair.first;
+ if (alreadyApplied.find(key) != alreadyApplied.end()) {
+ // This property has already been set by a previous class.
+ continue;
+ }
+
+ // Mark this property as written by a previous class, so that subsequent
+ // classes won't override this.
+ alreadyApplied.insert(key);
+
+ // If the most recent transition is not the one with the highest priority, create
+ // a transition.
+ AppliedClassPropertyValues &appliedProperties = appliedStyle[key];
+ if (appliedProperties.mostRecent() != classID) {
+ PropertyTransition transition = classProperties.getTransition(key);
+ Duration delay = transition.delay ? *transition.delay : *defaultTransition.delay;
+ Duration duration = transition.duration ? *transition.duration : *defaultTransition.duration;
+ const TimePoint begin = now + delay;
+ const TimePoint end = begin + duration;
+ const PropertyValue &value = propertyPair.second;
+ appliedProperties.add(classID, begin, end, value);
+ }
+ }
+}
+
+bool PaintPropertiesMap::hasTransitions() const {
+ for (const auto& pair : appliedStyle) {
+ if (pair.second.hasTransitions()) {
+ return true;
+ }
+ }
+ return hasPendingTransitions;
+}
+
+void PaintPropertiesMap::removeExpiredTransitions(const TimePoint& now) {
+ for (auto it = appliedStyle.begin(); it != appliedStyle.end();) {
+ AppliedClassPropertyValues& values = it->second;
+ values.cleanup(now);
+ // If the current properties object is empty, remove it from the map entirely.
+ values.empty() ? appliedStyle.erase(it++) : ++it;
+ }
+
+ // Clear the pending transitions flag upon each update.
+ hasPendingTransitions = false;
+}
+
+}
diff --git a/src/mbgl/style/paint_properties_map.hpp b/src/mbgl/style/paint_properties_map.hpp
new file mode 100644
index 0000000000..14ed33fe4d
--- /dev/null
+++ b/src/mbgl/style/paint_properties_map.hpp
@@ -0,0 +1,89 @@
+#ifndef MBGL_PAINT_PROPERTIES_MAP
+#define MBGL_PAINT_PROPERTIES_MAP
+
+#include <mbgl/style/applied_class_properties.hpp>
+#include <mbgl/style/property_evaluator.hpp>
+#include <mbgl/style/class_dictionary.hpp>
+#include <mbgl/style/property_key.hpp>
+
+#include <mbgl/util/interpolate.hpp>
+
+#include <map>
+#include <set>
+
+namespace mbgl {
+
+class ClassProperties;
+class PropertyTransition;
+
+class PaintPropertiesMap {
+public:
+ void cascade(const std::vector<std::string>& classNames,
+ const TimePoint& now,
+ const PropertyTransition& defaultTransition);
+
+ bool hasTransitions() const;
+ void removeExpiredTransitions(const TimePoint& now);
+
+ template <typename T>
+ void calculate(PropertyKey key, T& target, const StyleCalculationParameters& parameters) {
+ auto it = appliedStyle.find(key);
+ if (it != appliedStyle.end()) {
+ AppliedClassPropertyValues &applied = it->second;
+ // Iterate through all properties that we need to apply in order.
+ const PropertyEvaluator<T> evaluator(parameters);
+ for (auto& property : applied.propertyValues) {
+ if (parameters.now >= property.begin) {
+ // We overwrite the current property with the new value.
+ target = mapbox::util::apply_visitor(evaluator, property.value);
+ } else {
+ // Do not apply this property because its transition hasn't begun yet.
+ }
+ }
+ }
+ }
+
+ template <typename T>
+ void calculateTransitioned(PropertyKey key, T& target, const StyleCalculationParameters& parameters) {
+ auto it = appliedStyle.find(key);
+ if (it != appliedStyle.end()) {
+ AppliedClassPropertyValues &applied = it->second;
+ // Iterate through all properties that we need to apply in order.
+ const PropertyEvaluator<T> evaluator(parameters);
+ for (auto& property : applied.propertyValues) {
+ if (parameters.now >= property.end) {
+ // We overwrite the current property with the new value.
+ target = mapbox::util::apply_visitor(evaluator, property.value);
+ } else if (parameters.now >= property.begin) {
+ // We overwrite the current property partially with the new value.
+ float progress = std::chrono::duration<float>(parameters.now - property.begin) / (property.end - property.begin);
+ target = util::interpolate(target, mapbox::util::apply_visitor(evaluator, property.value), progress);
+ hasPendingTransitions = true;
+ } else {
+ // Do not apply this property because its transition hasn't begun yet.
+ }
+ }
+ }
+ }
+
+ // Raw parsed paint class to property value map.
+ std::map<ClassID, ClassProperties> paints;
+
+private:
+ // Applies all properties from a class, if they haven't been applied already.
+ void cascadeClass(const ClassID,
+ std::set<PropertyKey>&,
+ const TimePoint&,
+ const PropertyTransition&);
+
+ // For every property, stores a list of applied property values, with
+ // optional transition times.
+ std::map<PropertyKey, AppliedClassPropertyValues> appliedStyle;
+
+ // Stores whether there are pending transitions to be done on each update.
+ bool hasPendingTransitions = false;
+};
+
+};
+
+#endif
diff --git a/src/mbgl/style/style.cpp b/src/mbgl/style/style.cpp
index 84640be259..b68ce496b8 100644
--- a/src/mbgl/style/style.cpp
+++ b/src/mbgl/style/style.cpp
@@ -121,9 +121,9 @@ void Style::update(const TransformState& transform,
void Style::cascade() {
for (const auto& layer : layers) {
- layer->setClasses(data.getClasses(),
- data.getAnimationTime(),
- PropertyTransition { data.getDefaultTransitionDuration(), data.getDefaultTransitionDelay() });
+ layer->cascade(data.getClasses(),
+ data.getAnimationTime(),
+ PropertyTransition { data.getDefaultTransitionDuration(), data.getDefaultTransitionDelay() });
}
}
@@ -142,7 +142,8 @@ void Style::recalculate(float z) {
data.getDefaultFadeDuration());
for (const auto& layer : layers) {
- layer->updateProperties(parameters);
+ layer->recalculate(parameters);
+
if (!layer->bucket) {
continue;
}
diff --git a/src/mbgl/style/style_layer.cpp b/src/mbgl/style/style_layer.cpp
index 5b87377608..eab8777d83 100644
--- a/src/mbgl/style/style_layer.cpp
+++ b/src/mbgl/style/style_layer.cpp
@@ -1,6 +1,4 @@
#include <mbgl/style/style_layer.hpp>
-#include <mbgl/style/property_fallback.hpp>
-
#include <mbgl/layer/fill_layer.hpp>
#include <mbgl/layer/line_layer.hpp>
#include <mbgl/layer/circle_layer.hpp>
@@ -29,122 +27,18 @@ std::unique_ptr<StyleLayer> StyleLayer::create(StyleLayerType type) {
}
}
-bool StyleLayer::hasRenderPass(RenderPass pass) const {
- return bool(passes & pass);
-}
-
-void StyleLayer::setClasses(const std::vector<std::string> &class_names, const TimePoint& now,
- const PropertyTransition &defaultTransition) {
- // Stores all keys that we have already added transitions for.
- std::set<PropertyKey> already_applied;
-
- // We only apply the default style values if there are no classes set.
- if (class_names.empty()) {
- applyClassProperties(ClassID::Default, already_applied, now, defaultTransition);
- return;
- }
-
- // Reverse iterate through all class names and apply them last to first.
- for (auto it = class_names.rbegin(); it != class_names.rend(); ++it) {
- const std::string &class_name = *it;
- // From here on, we're only dealing with IDs to avoid comparing strings all the time.
- const ClassID class_id = ClassDictionary::Get().lookup(class_name);
- applyClassProperties(class_id, already_applied, now, defaultTransition);
- }
-
- // As the last class, apply the default class.
- applyClassProperties(ClassID::Default, already_applied, now, defaultTransition);
-
- // Make sure that we also transition to the fallback value for keys that aren't changed by
- // any applied classes.
- for (auto& property_pair : appliedStyle) {
- const PropertyKey key = property_pair.first;
- if (already_applied.find(key) != already_applied.end()) {
- // This property has already been set by a previous class, so we don't need to
- // transition to the fallback.
- continue;
- }
-
- AppliedClassPropertyValues &appliedProperties = property_pair.second;
- // Make sure that we don't do double transitions to the fallback value.
- if (appliedProperties.mostRecent() == ClassID::Fallback) {
- continue;
- }
-
- // This property key hasn't been set by a previous class, so we need to add a transition
- // to the fallback value for that key.
- const TimePoint begin = now + *defaultTransition.delay;
- const TimePoint end = begin + *defaultTransition.duration;
- const PropertyValue &value = PropertyFallbackValue::Get(key);
- appliedProperties.add(ClassID::Fallback, begin, end, value);
- }
-}
-
-// Helper function for applying all properties of a a single class that haven't been applied yet.
-void StyleLayer::applyClassProperties(const ClassID class_id,
- std::set<PropertyKey> &already_applied, const TimePoint& now,
- const PropertyTransition &defaultTransition) {
- auto style_it = styles.find(class_id);
- if (style_it == styles.end()) {
- // There is no class in this layer with this class_name.
- return;
- }
-
- // Loop through all the properties in this style, and add transitions to them, if they're
- // not already the most recent transition.
- const ClassProperties &class_properties = style_it->second;
- for (const auto& property_pair : class_properties) {
- PropertyKey key = property_pair.first;
- if (already_applied.find(key) != already_applied.end()) {
- // This property has already been set by a previous class.
- continue;
- }
-
- // Mark this property as written by a previous class, so that subsequent
- // classes won't override this.
- already_applied.insert(key);
-
- // If the most recent transition is not the one with the highest priority, create
- // a transition.
- AppliedClassPropertyValues &appliedProperties = appliedStyle[key];
- if (appliedProperties.mostRecent() != class_id) {
- PropertyTransition transition = class_properties.getTransition(key);
- Duration delay = transition.delay ? *transition.delay : *defaultTransition.delay;
- Duration duration = transition.duration ? *transition.duration : *defaultTransition.duration;
- const TimePoint begin = now + delay;
- const TimePoint end = begin + duration;
- const PropertyValue &value = property_pair.second;
- appliedProperties.add(class_id, begin, end, value);
- }
- }
-}
-
-void StyleLayer::updateProperties(const StyleCalculationParameters& parameters) {
- cleanupAppliedStyleProperties(parameters.now);
-
- // Clear the pending transitions flag upon each update.
- hasPendingTransitions = false;
-
- // Update the render passes when this layer is visible.
- passes = applyStyleProperties(parameters);
+void StyleLayer::cascade(const std::vector<std::string>& classes,
+ const TimePoint& now,
+ const PropertyTransition& defaultTransition) {
+ paints.cascade(classes, now, defaultTransition);
}
bool StyleLayer::hasTransitions() const {
- for (const auto& pair : appliedStyle) {
- if (pair.second.hasTransitions()) {
- return true;
- }
- }
- return hasPendingTransitions;
+ return paints.hasTransitions();
}
-void StyleLayer::cleanupAppliedStyleProperties(const TimePoint& now) {
- for (auto it = appliedStyle.begin(); it != appliedStyle.end();) {
- AppliedClassPropertyValues& values = it->second;
- values.cleanup(now);
- // If the current properties object is empty, remove it from the map entirely.
- values.empty() ? appliedStyle.erase(it++) : ++it;
- }
+bool StyleLayer::hasRenderPass(RenderPass pass) const {
+ return bool(passes & pass);
}
}
diff --git a/src/mbgl/style/style_layer.hpp b/src/mbgl/style/style_layer.hpp
index b6ff6ae8f7..43d595bb38 100644
--- a/src/mbgl/style/style_layer.hpp
+++ b/src/mbgl/style/style_layer.hpp
@@ -3,26 +3,23 @@
#include <mbgl/style/class_dictionary.hpp>
#include <mbgl/style/class_properties.hpp>
-#include <mbgl/style/applied_class_properties.hpp>
-#include <mbgl/style/zoom_history.hpp>
-#include <mbgl/style/property_evaluator.hpp>
-#include <mbgl/style/style_calculation_parameters.hpp>
+#include <mbgl/style/paint_properties_map.hpp>
#include <mbgl/renderer/render_pass.hpp>
-#include <mbgl/util/ptr.hpp>
#include <mbgl/util/noncopyable.hpp>
#include <mbgl/util/chrono.hpp>
-#include <mbgl/util/interpolate.hpp>
+#include <mbgl/util/ptr.hpp>
#include <vector>
#include <string>
#include <map>
-#include <set>
namespace mbgl {
class StyleBucket;
+class StyleCalculationParameters;
+class PropertyTransition;
class StyleLayer : public util::noncopyable {
public:
@@ -30,97 +27,35 @@ public:
virtual ~StyleLayer() = default;
- // Checks whether this layer needs to be rendered in the given render pass.
- bool hasRenderPass(RenderPass) const;
-
- // Updates the StyleProperties information in this layer by evaluating all
- // pending transitions and applied classes in order.
- void updateProperties(const StyleCalculationParameters&);
+ // Partially evaluate paint properties based on a set of classes.
+ void cascade(const std::vector<std::string>& classNames,
+ const TimePoint& now,
+ const PropertyTransition& defaultTransition);
- // Sets the list of classes and creates transitions to the currently applied values.
- void setClasses(const std::vector<std::string> &class_names, const TimePoint& now,
- const PropertyTransition &defaultTransition);
+ // Fully evaluate cascaded paint properties based on a zoom level.
+ virtual void recalculate(const StyleCalculationParameters&) = 0;
+ // Checks whether this layer has any active paint properties with transitions.
bool hasTransitions() const;
+ // Checks whether this layer needs to be rendered in the given render pass.
+ bool hasRenderPass(RenderPass) const;
+
public:
- // The name of this layer.
std::string id;
-
StyleLayerType type = StyleLayerType::Unknown;
// Bucket information, telling the renderer how to generate the geometries
// for this layer (feature property filters, tessellation instructions, ...).
util::ptr<StyleBucket> bucket;
- // Contains all style classes that can be applied to this layer.
- std::map<ClassID, ClassProperties> styles;
+ // Contains all paint classes that can be applied to this layer.
+ PaintPropertiesMap paints;
protected:
- // TODO: extract
- template <typename T>
- void applyStyleProperty(PropertyKey key, T& target, const StyleCalculationParameters& parameters) {
- auto it = appliedStyle.find(key);
- if (it != appliedStyle.end()) {
- AppliedClassPropertyValues &applied = it->second;
- // Iterate through all properties that we need to apply in order.
- const PropertyEvaluator<T> evaluator(parameters);
- for (auto& property : applied.propertyValues) {
- if (parameters.now >= property.begin) {
- // We overwrite the current property with the new value.
- target = mapbox::util::apply_visitor(evaluator, property.value);
- } else {
- // Do not apply this property because its transition hasn't begun yet.
- }
- }
- }
- }
-
- template <typename T>
- void applyTransitionedStyleProperty(PropertyKey key, T& target, const StyleCalculationParameters& parameters) {
- auto it = appliedStyle.find(key);
- if (it != appliedStyle.end()) {
- AppliedClassPropertyValues &applied = it->second;
- // Iterate through all properties that we need to apply in order.
- const PropertyEvaluator<T> evaluator(parameters);
- for (auto& property : applied.propertyValues) {
- if (parameters.now >= property.end) {
- // We overwrite the current property with the new value.
- target = mapbox::util::apply_visitor(evaluator, property.value);
- } else if (parameters.now >= property.begin) {
- // We overwrite the current property partially with the new value.
- float progress = std::chrono::duration<float>(parameters.now - property.begin) / (property.end - property.begin);
- target = util::interpolate(target, mapbox::util::apply_visitor(evaluator, property.value), progress);
- hasPendingTransitions = true;
- } else {
- // Do not apply this property because its transition hasn't begun yet.
- }
- }
- }
- }
-
-private:
- // Applies all properties from a class, if they haven't been applied already.
- void applyClassProperties(ClassID class_id, std::set<PropertyKey> &already_applied,
- const TimePoint& now, const PropertyTransition &defaultTransition);
-
- // Sets the properties of this object by evaluating all pending transitions and
- // aplied classes in order.
- virtual RenderPass applyStyleProperties(const StyleCalculationParameters&) = 0;
-
- // Removes all expired style transitions.
- void cleanupAppliedStyleProperties(const TimePoint& now);
-
- // For every property, stores a list of applied property values, with
- // optional transition times.
- std::map<PropertyKey, AppliedClassPropertyValues> appliedStyle;
-
// Stores what render passes this layer is currently enabled for. This depends on the
// evaluated StyleProperties object and is updated accordingly.
RenderPass passes = RenderPass::None;
-
- // Stores whether there are pending transitions to be done on each update.
- bool hasPendingTransitions = false;
};
}
diff --git a/src/mbgl/style/style_parser.cpp b/src/mbgl/style/style_parser.cpp
index 391f6b0e21..3aecfa51eb 100644
--- a/src/mbgl/style/style_parser.cpp
+++ b/src/mbgl/style/style_parser.cpp
@@ -798,7 +798,7 @@ void StyleParser::parseLayer(const std::string& id, JSVal value, util::ptr<Style
std::map<ClassID, ClassProperties> paints;
parsePaints(value, paints);
- layer->styles = std::move(paints);
+ layer->paints.paints = std::move(paints);
}
#pragma mark - Parse Styles