diff options
author | John Firebaugh <john.firebaugh@gmail.com> | 2015-10-19 18:30:25 -0700 |
---|---|---|
committer | John Firebaugh <john.firebaugh@gmail.com> | 2015-10-26 12:00:11 -0700 |
commit | bb6241844a092cf632fe740e6ac79c920117dd4e (patch) | |
tree | 6d2540fde2c2a3fbe3d1f8bfce32c57e192894d9 /src | |
parent | e257ad284bf02f658949f3f2ddb7becbbcf1f820 (diff) | |
download | qtlocation-mapboxgl-bb6241844a092cf632fe740e6ac79c920117dd4e.tar.gz |
[core] Extract PaintPropertiesMap
Diffstat (limited to 'src')
-rw-r--r-- | src/mbgl/annotation/annotation_manager.cpp | 1 | ||||
-rw-r--r-- | src/mbgl/annotation/shape_annotation_impl.cpp | 6 | ||||
-rw-r--r-- | src/mbgl/layer/background_layer.cpp | 13 | ||||
-rw-r--r-- | src/mbgl/layer/background_layer.hpp | 2 | ||||
-rw-r--r-- | src/mbgl/layer/circle_layer.cpp | 19 | ||||
-rw-r--r-- | src/mbgl/layer/circle_layer.hpp | 2 | ||||
-rw-r--r-- | src/mbgl/layer/fill_layer.cpp | 28 | ||||
-rw-r--r-- | src/mbgl/layer/fill_layer.hpp | 2 | ||||
-rw-r--r-- | src/mbgl/layer/line_layer.cpp | 26 | ||||
-rw-r--r-- | src/mbgl/layer/line_layer.hpp | 2 | ||||
-rw-r--r-- | src/mbgl/layer/raster_layer.cpp | 21 | ||||
-rw-r--r-- | src/mbgl/layer/raster_layer.hpp | 2 | ||||
-rw-r--r-- | src/mbgl/layer/symbol_layer.cpp | 34 | ||||
-rw-r--r-- | src/mbgl/layer/symbol_layer.hpp | 2 | ||||
-rw-r--r-- | src/mbgl/style/paint_properties_map.cpp | 114 | ||||
-rw-r--r-- | src/mbgl/style/paint_properties_map.hpp | 89 | ||||
-rw-r--r-- | src/mbgl/style/style.cpp | 9 | ||||
-rw-r--r-- | src/mbgl/style/style_layer.cpp | 120 | ||||
-rw-r--r-- | src/mbgl/style/style_layer.hpp | 97 | ||||
-rw-r--r-- | src/mbgl/style/style_parser.cpp | 2 |
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 |