diff options
84 files changed, 3779 insertions, 1286 deletions
diff --git a/cmake/core-files.cmake b/cmake/core-files.cmake index 02335fef7..f486c6c38 100644 --- a/cmake/core-files.cmake +++ b/cmake/core-files.cmake @@ -392,6 +392,9 @@ set(MBGL_CORE_FILES src/mbgl/style/light_impl.cpp src/mbgl/style/light_impl.hpp src/mbgl/style/light_observer.hpp + src/mbgl/style/light_properties.cpp + src/mbgl/style/light_properties.hpp + src/mbgl/style/light_property.hpp src/mbgl/style/observer.hpp src/mbgl/style/paint_property.hpp src/mbgl/style/parser.cpp diff --git a/include/mbgl/style/position.hpp b/include/mbgl/style/position.hpp index 3be8d1c55..078e62bda 100644 --- a/include/mbgl/style/position.hpp +++ b/include/mbgl/style/position.hpp @@ -9,7 +9,7 @@ namespace style { class Position { public: Position() = default; - Position(std::array<float, 3>& position_) + Position(const std::array<float, 3>& position_) : radial(position_[0]), azimuthal(position_[1]), polar(position_[2]) { calculateCartesian(); }; diff --git a/include/mbgl/util/type_list.hpp b/include/mbgl/util/type_list.hpp index 4a5e95c8a..f3db277e4 100644 --- a/include/mbgl/util/type_list.hpp +++ b/include/mbgl/util/type_list.hpp @@ -8,33 +8,4 @@ namespace mbgl { template <class...> class TypeList {}; -namespace detail { - -template <class, class> -struct TypeCons; - -template <class T, class... Ts> -struct TypeCons<T, TypeList<Ts...>> { - using Type = TypeList<T, Ts...>; -}; - -template <class, template <class> class> -struct TypeFilter; - -template <template <class> class Predicate> -struct TypeFilter<TypeList<>, Predicate> { - using Type = TypeList<>; -}; - -template <template <class> class Predicate, class T, class... Ts> -struct TypeFilter<TypeList<T, Ts...>, Predicate> { - using Tail = typename TypeFilter<TypeList<Ts...>, Predicate>::Type; - using Type = std::conditional_t<Predicate<T>::value, typename TypeCons<T, Tail>::Type, Tail>; -}; - -} // namespace detail - -template <class TypeList, template <class> class Predicate> -using FilteredTypeList = typename detail::TypeFilter<TypeList, Predicate>::Type; - } // namespace mbgl diff --git a/scripts/generate-style-code.js b/scripts/generate-style-code.js index 9a7b2842f..445773b42 100755 --- a/scripts/generate-style-code.js +++ b/scripts/generate-style-code.js @@ -53,25 +53,44 @@ global.evaluatedType = function (property) { } }; -function attributeUniformType(property, type) { +function attributeUniformName(property, type) { const attributeNameExceptions = { - 'text-opacity': 'opacity', - 'icon-opacity': 'opacity', - 'text-color': 'fill_color', - 'icon-color': 'fill_color', - 'text-halo-color': 'halo_color', - 'icon-halo-color': 'halo_color', - 'text-halo-blur': 'halo_blur', - 'icon-halo-blur': 'halo_blur', - 'text-halo-width': 'halo_width', - 'icon-halo-width': 'halo_width', - 'line-gap-width': 'gapwidth' - } - const name = attributeNameExceptions[property.name] || + 'text-opacity': 'opacity', + 'icon-opacity': 'opacity', + 'text-color': 'fill_color', + 'icon-color': 'fill_color', + 'text-halo-color': 'halo_color', + 'icon-halo-color': 'halo_color', + 'text-halo-blur': 'halo_blur', + 'icon-halo-blur': 'halo_blur', + 'text-halo-width': 'halo_width', + 'icon-halo-width': 'halo_width', + 'line-gap-width': 'gapwidth' + }; + return attributeNameExceptions[property.name] || property.name.replace(type + '-', '').replace(/-/g, '_'); - return `attributes::a_${name}${name === 'offset' ? '<1>' : ''}, uniforms::u_${name}`; } +global.attributeType = function(property, type) { + const name = attributeUniformName(property, type); + return `attributes::a_${name}${name === 'offset' ? '<1>' : ''}`; +}; + +global.uniformType = function(property, type) { + const name = attributeUniformName(property, type); + return `uniforms::u_${name}`; +}; + +global.isDataDriven = function (property) { + switch (property['property-type']) { + case 'data-driven': + case 'cross-faded-data-driven': + return true; + default: + return false; + } +}; + global.layoutPropertyType = function (property) { switch (property['property-type']) { case 'data-driven': @@ -86,7 +105,7 @@ global.paintPropertyType = function (property, type) { switch (property['property-type']) { case 'data-driven': case 'cross-faded-data-driven': - return `DataDrivenPaintProperty<${evaluatedType(property)}, ${attributeUniformType(property, type)}>`; + return `DataDrivenPaintProperty<${evaluatedType(property)}, ${attributeType(property, type)}, ${uniformType(property, type)}>`; case 'cross-faded': return `CrossFadedPaintProperty<${evaluatedType(property)}>`; default: @@ -94,6 +113,18 @@ global.paintPropertyType = function (property, type) { } }; +global.possiblyEvaluatedType = function (property) { + switch (property['property-type']) { + case 'data-driven': + case 'cross-faded-data-driven': + return `PossiblyEvaluatedPropertyValue<${evaluatedType(property)}>`; + case 'cross-faded': + return `Faded<${evaluatedType(property)}>`; + default: + return evaluatedType(property); + } +}; + global.propertyValueType = function (property) { switch (property['property-type']) { case 'color-ramp': @@ -203,5 +234,10 @@ const lightProperties = Object.keys(spec[`light`]).reduce((memo, name) => { const lightHpp = ejs.compile(fs.readFileSync('include/mbgl/style/light.hpp.ejs', 'utf8'), {strict: true}); const lightCpp = ejs.compile(fs.readFileSync('src/mbgl/style/light.cpp.ejs', 'utf8'), {strict: true}); +const lightPropertiesHpp = ejs.compile(fs.readFileSync('src/mbgl/style/light_properties.hpp.ejs', 'utf8'), {strict: true}); +const lightPropertiesCpp = ejs.compile(fs.readFileSync('src/mbgl/style/light_properties.cpp.ejs', 'utf8'), {strict: true}); + writeIfModified(`include/mbgl/style/light.hpp`, lightHpp({properties: lightProperties})); writeIfModified(`src/mbgl/style/light.cpp`, lightCpp({properties: lightProperties})); +writeIfModified(`src/mbgl/style/light_properties.hpp`, lightPropertiesHpp({properties: lightProperties})); +writeIfModified(`src/mbgl/style/light_properties.cpp`, lightPropertiesCpp({properties: lightProperties})); diff --git a/src/mbgl/layout/symbol_layout.cpp b/src/mbgl/layout/symbol_layout.cpp index 41469f293..f3217d594 100644 --- a/src/mbgl/layout/symbol_layout.cpp +++ b/src/mbgl/layout/symbol_layout.cpp @@ -27,10 +27,10 @@ namespace mbgl { using namespace style; -template <class Property> -static bool has(const style::SymbolLayoutProperties::PossiblyEvaluated& layout) { - return layout.get<Property>().match( - [&] (const typename Property::Type& t) { return !t.empty(); }, +template <class T> +static bool has(const PossiblyEvaluatedPropertyValue<T>& value) { + return value.match( + [&] (const T& t) { return !t.empty(); }, [&] (const auto&) { return true; } ); } @@ -48,40 +48,40 @@ SymbolLayout::SymbolLayout(const BucketParameters& parameters, pixelRatio(parameters.pixelRatio), tileSize(util::tileSize * overscaling), tilePixelRatio(float(util::EXTENT) / tileSize), - textSize(layers.at(0)->as<RenderSymbolLayer>()->impl().layout.get<TextSize>()), - iconSize(layers.at(0)->as<RenderSymbolLayer>()->impl().layout.get<IconSize>()) + textSize(layers.at(0)->as<RenderSymbolLayer>()->impl().layout.textSize), + iconSize(layers.at(0)->as<RenderSymbolLayer>()->impl().layout.iconSize) { const SymbolLayer::Impl& leader = layers.at(0)->as<RenderSymbolLayer>()->impl(); layout = leader.layout.evaluate(PropertyEvaluationParameters(zoom)); - if (layout.get<IconRotationAlignment>() == AlignmentType::Auto) { - if (layout.get<SymbolPlacement>() != SymbolPlacementType::Point) { - layout.get<IconRotationAlignment>() = AlignmentType::Map; + if (layout.iconRotationAlignment == AlignmentType::Auto) { + if (layout.symbolPlacement != SymbolPlacementType::Point) { + layout.iconRotationAlignment = AlignmentType::Map; } else { - layout.get<IconRotationAlignment>() = AlignmentType::Viewport; + layout.iconRotationAlignment = AlignmentType::Viewport; } } - if (layout.get<TextRotationAlignment>() == AlignmentType::Auto) { - if (layout.get<SymbolPlacement>() != SymbolPlacementType::Point) { - layout.get<TextRotationAlignment>() = AlignmentType::Map; + if (layout.textRotationAlignment == AlignmentType::Auto) { + if (layout.symbolPlacement != SymbolPlacementType::Point) { + layout.textRotationAlignment = AlignmentType::Map; } else { - layout.get<TextRotationAlignment>() = AlignmentType::Viewport; + layout.textRotationAlignment = AlignmentType::Viewport; } } // If unspecified `*-pitch-alignment` inherits `*-rotation-alignment` - if (layout.get<TextPitchAlignment>() == AlignmentType::Auto) { - layout.get<TextPitchAlignment>() = layout.get<TextRotationAlignment>(); + if (layout.textPitchAlignment == AlignmentType::Auto) { + layout.textPitchAlignment = layout.textRotationAlignment; } - if (layout.get<IconPitchAlignment>() == AlignmentType::Auto) { - layout.get<IconPitchAlignment>() = layout.get<IconRotationAlignment>(); + if (layout.iconPitchAlignment == AlignmentType::Auto) { + layout.iconPitchAlignment = layout.iconRotationAlignment; } - const bool hasText = has<TextField>(layout) && has<TextFont>(layout); - const bool hasIcon = has<IconImage>(layout); + const bool hasText = has(layout.textField) && has(layout.textFont); + const bool hasIcon = has(layout.iconImage); if (!hasText && !hasIcon) { return; @@ -106,9 +106,9 @@ SymbolLayout::SymbolLayout(const BucketParameters& parameters, ft.index = i; if (hasText) { - std::string u8string = layout.evaluate<TextField>(zoom, ft); + std::string u8string = layout.textField.evaluate(ft, zoom, TextField::defaultValue()); - auto textTransform = layout.evaluate<TextTransform>(zoom, ft); + auto textTransform = layout.textTransform.evaluate(ft, zoom, TextTransform::defaultValue()); if (textTransform == TextTransformType::Uppercase) { u8string = platform::uppercase(u8string); } else if (textTransform == TextTransformType::Lowercase) { @@ -116,11 +116,11 @@ SymbolLayout::SymbolLayout(const BucketParameters& parameters, } ft.text = applyArabicShaping(util::utf8_to_utf16::convert(u8string)); - const bool canVerticalizeText = layout.get<TextRotationAlignment>() == AlignmentType::Map - && layout.get<SymbolPlacement>() != SymbolPlacementType::Point + const bool canVerticalizeText = layout.textRotationAlignment == AlignmentType::Map + && layout.symbolPlacement != SymbolPlacementType::Point && util::i18n::allowsVerticalWritingMode(*ft.text); - FontStack fontStack = layout.evaluate<TextFont>(zoom, ft); + FontStack fontStack = layout.textFont.evaluate(ft, zoom, TextFont::defaultValue()); GlyphIDs& dependencies = glyphDependencies[fontStack]; // Loop through all characters of this text and collect unique codepoints. @@ -135,7 +135,7 @@ SymbolLayout::SymbolLayout(const BucketParameters& parameters, } if (hasIcon) { - ft.icon = layout.evaluate<IconImage>(zoom, ft); + ft.icon = layout.iconImage.evaluate(ft, zoom, IconImage::defaultValue()); imageDependencies.insert(*ft.icon); } @@ -144,7 +144,7 @@ SymbolLayout::SymbolLayout(const BucketParameters& parameters, } } - if (layout.get<SymbolPlacement>() == SymbolPlacementType::Line) { + if (layout.symbolPlacement == SymbolPlacementType::Line) { util::mergeLines(features); } } @@ -155,14 +155,14 @@ bool SymbolLayout::hasSymbolInstances() const { void SymbolLayout::prepare(const GlyphMap& glyphMap, const GlyphPositions& glyphPositions, const ImageMap& imageMap, const ImagePositions& imagePositions) { - const bool textAlongLine = layout.get<TextRotationAlignment>() == AlignmentType::Map && - layout.get<SymbolPlacement>() != SymbolPlacementType::Point; + const bool textAlongLine = layout.textRotationAlignment == AlignmentType::Map && + layout.symbolPlacement != SymbolPlacementType::Point; for (auto it = features.begin(); it != features.end(); ++it) { auto& feature = *it; if (feature.geometry.empty()) continue; - FontStack fontStack = layout.evaluate<TextFont>(zoom, feature); + FontStack fontStack = layout.textFont.evaluate(feature, zoom, TextFont::defaultValue()); auto glyphMapIt = glyphMap.find(fontStack); const Glyphs& glyphs = glyphMapIt != glyphMap.end() @@ -179,15 +179,16 @@ void SymbolLayout::prepare(const GlyphMap& glyphMap, const GlyphPositions& glyph if (feature.text) { auto applyShaping = [&] (const std::u16string& text, WritingModeType writingMode) { const float oneEm = 24.0f; + const auto offset = layout.textOffset.evaluate(feature, zoom, TextOffset::defaultValue()); const Shaping result = getShaping( /* string */ text, - /* maxWidth: ems */ layout.get<SymbolPlacement>() == SymbolPlacementType::Point ? - layout.evaluate<TextMaxWidth>(zoom, feature) * oneEm : 0, - /* lineHeight: ems */ layout.get<TextLineHeight>() * oneEm, - /* anchor */ layout.evaluate<TextAnchor>(zoom, feature), - /* justify */ layout.evaluate<TextJustify>(zoom, feature), - /* spacing: ems */ util::i18n::allowsLetterSpacing(*feature.text) ? layout.evaluate<TextLetterSpacing>(zoom, feature) * oneEm : 0.0f, - /* translate */ Point<float>(layout.evaluate<TextOffset>(zoom, feature)[0] * oneEm, layout.evaluate<TextOffset>(zoom, feature)[1] * oneEm), + /* maxWidth: ems */ layout.symbolPlacement == SymbolPlacementType::Point ? + layout.textMaxWidth.evaluate(feature, zoom, TextMaxWidth::defaultValue()) * oneEm : 0, + /* lineHeight: ems */ layout.textLineHeight * oneEm, + /* anchor */ layout.textAnchor.evaluate(feature, zoom, TextAnchor::defaultValue()), + /* justify */ layout.textJustify.evaluate(feature, zoom, TextJustify::defaultValue()), + /* spacing: ems */ util::i18n::allowsLetterSpacing(*feature.text) ? layout.textLetterSpacing.evaluate(feature, zoom, TextLetterSpacing::defaultValue()) * oneEm : 0.0f, + /* translate */ Point<float>(offset[0] * oneEm, offset[1] * oneEm), /* verticalHeight */ oneEm, /* writingMode */ writingMode, /* bidirectional algorithm object */ bidi, @@ -209,15 +210,15 @@ void SymbolLayout::prepare(const GlyphMap& glyphMap, const GlyphPositions& glyph if (image != imageMap.end()) { shapedIcon = PositionedIcon::shapeIcon( imagePositions.at(*feature.icon), - layout.evaluate<IconOffset>(zoom, feature), - layout.evaluate<IconAnchor>(zoom, feature), - layout.evaluate<IconRotate>(zoom, feature) * util::DEG2RAD); + layout.iconOffset.evaluate(feature, zoom, IconOffset::defaultValue()), + layout.iconAnchor.evaluate(feature, zoom, IconAnchor::defaultValue()), + layout.iconRotate.evaluate(feature, zoom, IconRotate::defaultValue()) * util::DEG2RAD); if (image->second->sdf) { sdfIcons = true; } if (image->second->pixelRatio != pixelRatio) { iconsNeedLinear = true; - } else if (layout.get<IconRotate>().constantOr(1) != 0) { + } else if (layout.iconRotate.constantOr(1) != 0) { iconsNeedLinear = true; } } @@ -242,33 +243,33 @@ void SymbolLayout::addFeature(const std::size_t layoutFeatureIndex, const float minScale = 0.5f; const float glyphSize = 24.0f; - const float layoutTextSize = layout.evaluate<TextSize>(zoom + 1, feature); - const float layoutIconSize = layout.evaluate<IconSize>(zoom + 1, feature); - const std::array<float, 2> textOffset = layout.evaluate<TextOffset>(zoom, feature); - const std::array<float, 2> iconOffset = layout.evaluate<IconOffset>(zoom, feature); + const float layoutTextSize = layout.textSize.evaluate(feature, zoom + 1, TextSize::defaultValue()); + const float layoutIconSize = layout.iconSize.evaluate(feature, zoom + 1, IconSize::defaultValue()); + const std::array<float, 2> textOffset = layout.textOffset.evaluate(feature, zoom, TextOffset::defaultValue()); + const std::array<float, 2> iconOffset = layout.iconOffset.evaluate(feature, zoom, IconOffset::defaultValue()); // To reduce the number of labels that jump around when zooming we need // to use a text-size value that is the same for all zoom levels. // This calculates text-size at a high zoom level so that all tiles can // use the same value when calculating anchor positions. - const float textMaxSize = layout.evaluate<TextSize>(18, feature); + const float textMaxSize = layout.textSize.evaluate(feature, 18, TextSize::defaultValue()); const float fontScale = layoutTextSize / glyphSize; const float textBoxScale = tilePixelRatio * fontScale; const float textMaxBoxScale = tilePixelRatio * textMaxSize / glyphSize; const float iconBoxScale = tilePixelRatio * layoutIconSize; - const float symbolSpacing = tilePixelRatio * layout.get<SymbolSpacing>(); + const float symbolSpacing = tilePixelRatio * layout.symbolSpacing; // CJL: I'm not sure why SymbolPlacementType::Line -> avoidEdges = false. It seems redundant since // getAnchors will already avoid generating anchors outside the tile bounds. // However, SymbolPlacementType::LineCenter allows anchors outside tile boundaries, so its behavior // here should match SymbolPlacement::Point - const bool avoidEdges = layout.get<SymbolAvoidEdges>() && layout.get<SymbolPlacement>() != SymbolPlacementType::Line; - const float textPadding = layout.get<TextPadding>() * tilePixelRatio; - const float iconPadding = layout.get<IconPadding>() * tilePixelRatio; - const float textMaxAngle = layout.get<TextMaxAngle>() * util::DEG2RAD; - const SymbolPlacementType textPlacement = layout.get<TextRotationAlignment>() != AlignmentType::Map + const bool avoidEdges = layout.symbolAvoidEdges && layout.symbolPlacement != SymbolPlacementType::Line; + const float textPadding = layout.textPadding * tilePixelRatio; + const float iconPadding = layout.iconPadding * tilePixelRatio; + const float textMaxAngle = layout.textMaxAngle * util::DEG2RAD; + const SymbolPlacementType textPlacement = layout.textRotationAlignment != AlignmentType::Map ? SymbolPlacementType::Point - : layout.get<SymbolPlacement>(); + : layout.symbolPlacement; const float textRepeatDistance = symbolSpacing / 2; IndexedSubfeature indexedFeature(feature.index, sourceLayer->getName(), bucketLeaderID, symbolInstances.size()); @@ -303,7 +304,7 @@ void SymbolLayout::addFeature(const std::size_t layoutFeatureIndex, const auto& type = feature.getType(); - if (layout.get<SymbolPlacement>() == SymbolPlacementType::Line) { + if (layout.symbolPlacement == SymbolPlacementType::Line) { auto clippedLines = util::clipLines(feature.geometry, 0, 0, util::EXTENT, util::EXTENT); for (const auto& line : clippedLines) { Anchors anchors = getAnchors(line, @@ -323,7 +324,7 @@ void SymbolLayout::addFeature(const std::size_t layoutFeatureIndex, } } } - } else if (layout.get<SymbolPlacement>() == SymbolPlacementType::LineCenter) { + } else if (layout.symbolPlacement == SymbolPlacementType::LineCenter) { // No clipping, multiple lines per feature are allowed // "lines" with only one point are ignored as in clipLines for (const auto& line : feature.geometry) { @@ -411,8 +412,8 @@ std::vector<float> CalculateTileDistances(const GeometryCoordinates& line, const } std::unique_ptr<SymbolBucket> SymbolLayout::place(const bool showCollisionBoxes) { - const bool mayOverlap = layout.get<TextAllowOverlap>() || layout.get<IconAllowOverlap>() || - layout.get<TextIgnorePlacement>() || layout.get<IconIgnorePlacement>(); + const bool mayOverlap = layout.textAllowOverlap || layout.iconAllowOverlap || + layout.textIgnorePlacement || layout.iconIgnorePlacement; auto bucket = std::make_unique<SymbolBucket>(layout, layerPaintProperties, textSize, iconSize, zoom, sdfIcons, iconsNeedLinear, mayOverlap, bucketLeaderID, std::move(symbolInstances)); diff --git a/src/mbgl/layout/symbol_layout.hpp b/src/mbgl/layout/symbol_layout.hpp index 43b577859..27ab534c2 100644 --- a/src/mbgl/layout/symbol_layout.hpp +++ b/src/mbgl/layout/symbol_layout.hpp @@ -81,9 +81,9 @@ private: bool sdfIcons = false; bool iconsNeedLinear = false; - - style::TextSize::UnevaluatedType textSize; - style::IconSize::UnevaluatedType iconSize; + + style::PropertyValue<float> textSize; + style::PropertyValue<float> iconSize; std::vector<SymbolFeature> features; diff --git a/src/mbgl/programs/background_program.hpp b/src/mbgl/programs/background_program.hpp index b76318938..256bb2147 100644 --- a/src/mbgl/programs/background_program.hpp +++ b/src/mbgl/programs/background_program.hpp @@ -60,7 +60,7 @@ class BackgroundProgram : public Program< gl::Triangle, BackgroundLayoutAttributes, BackgroundUniforms, - style::Properties<>> + style::NoProperties> { public: using Program::Program; @@ -71,7 +71,7 @@ class BackgroundPatternProgram : public Program< gl::Triangle, BackgroundLayoutAttributes, BackgroundPatternUniforms, - style::Properties<>> + style::NoProperties> { public: using Program::Program; diff --git a/src/mbgl/programs/clipping_mask_program.hpp b/src/mbgl/programs/clipping_mask_program.hpp index 5dff4849f..0062cd152 100644 --- a/src/mbgl/programs/clipping_mask_program.hpp +++ b/src/mbgl/programs/clipping_mask_program.hpp @@ -14,7 +14,7 @@ class ClippingMaskProgram : public Program< PositionOnlyLayoutAttributes, gl::Uniforms< uniforms::u_matrix>, - style::Properties<>> + style::NoProperties> { public: using Program::Program; diff --git a/src/mbgl/programs/collision_box_program.hpp b/src/mbgl/programs/collision_box_program.hpp index 6e75adf36..40475461f 100644 --- a/src/mbgl/programs/collision_box_program.hpp +++ b/src/mbgl/programs/collision_box_program.hpp @@ -33,7 +33,7 @@ class CollisionBoxProgram : public Program< uniforms::u_matrix, uniforms::u_extrude_scale, uniforms::u_camera_to_center_distance>, - style::Properties<>> + style::NoProperties> { public: using Program::Program; @@ -66,16 +66,9 @@ public: const gl::VertexBuffer<CollisionBoxDynamicAttributes::Vertex>& dynamicVertexBuffer, const gl::IndexBuffer<DrawMode>& indexBuffer, const SegmentVector<Attributes>& segments, - const PaintPropertyBinders& paintPropertyBinders, - const typename PaintProperties::PossiblyEvaluated& currentProperties, - float currentZoom, const std::string& layerID) { - typename AllUniforms::Values allUniformValues = uniformValues - .concat(paintPropertyBinders.uniformValues(currentZoom, currentProperties)); - typename Attributes::Bindings allAttributeBindings = CollisionBoxLayoutAttributes::bindings(layoutVertexBuffer) - .concat(CollisionBoxDynamicAttributes::bindings(dynamicVertexBuffer)) - .concat(paintPropertyBinders.attributeBindings(currentProperties)); + .concat(CollisionBoxDynamicAttributes::bindings(dynamicVertexBuffer)); assert(layoutVertexBuffer.vertexCount == dynamicVertexBuffer.vertexCount); @@ -92,7 +85,7 @@ public: std::move(depthMode), std::move(stencilMode), std::move(colorMode), - allUniformValues, + uniformValues, vertexArrayIt->second, Attributes::offsetBindings(allAttributeBindings, segment.vertexOffset), indexBuffer, @@ -112,7 +105,7 @@ class CollisionCircleProgram : public Program< uniforms::u_extrude_scale, uniforms::u_overscale_factor, uniforms::u_camera_to_center_distance>, - style::Properties<>> + style::NoProperties> { public: using Program::Program; @@ -145,16 +138,9 @@ public: const gl::VertexBuffer<CollisionBoxDynamicAttributes::Vertex>& dynamicVertexBuffer, const gl::IndexBuffer<DrawMode>& indexBuffer, const SegmentVector<Attributes>& segments, - const PaintPropertyBinders& paintPropertyBinders, - const typename PaintProperties::PossiblyEvaluated& currentProperties, - float currentZoom, const std::string& layerID) { - typename AllUniforms::Values allUniformValues = uniformValues - .concat(paintPropertyBinders.uniformValues(currentZoom, currentProperties)); - typename Attributes::Bindings allAttributeBindings = CollisionBoxLayoutAttributes::bindings(layoutVertexBuffer) - .concat(CollisionBoxDynamicAttributes::bindings(dynamicVertexBuffer)) - .concat(paintPropertyBinders.attributeBindings(currentProperties)); + .concat(CollisionBoxDynamicAttributes::bindings(dynamicVertexBuffer)); for (auto& segment : segments) { auto vertexArrayIt = segment.vertexArrays.find(layerID); @@ -169,7 +155,7 @@ public: std::move(depthMode), std::move(stencilMode), std::move(colorMode), - allUniformValues, + uniformValues, vertexArrayIt->second, Attributes::offsetBindings(allAttributeBindings, segment.vertexOffset), indexBuffer, diff --git a/src/mbgl/programs/debug_program.hpp b/src/mbgl/programs/debug_program.hpp index 7a6d075cd..c40ebaf99 100644 --- a/src/mbgl/programs/debug_program.hpp +++ b/src/mbgl/programs/debug_program.hpp @@ -16,7 +16,7 @@ class DebugProgram : public Program< gl::Uniforms< uniforms::u_matrix, uniforms::u_color>, - style::Properties<>> + style::NoProperties> { public: using Program::Program; diff --git a/src/mbgl/programs/extrusion_texture_program.hpp b/src/mbgl/programs/extrusion_texture_program.hpp index bd8220888..a41efa5dd 100644 --- a/src/mbgl/programs/extrusion_texture_program.hpp +++ b/src/mbgl/programs/extrusion_texture_program.hpp @@ -18,7 +18,7 @@ class ExtrusionTextureProgram : public Program< uniforms::u_world, uniforms::u_image, uniforms::u_opacity>, - style::Properties<>> { + style::NoProperties> { public: using Program::Program; diff --git a/src/mbgl/programs/fill_extrusion_program.cpp b/src/mbgl/programs/fill_extrusion_program.cpp index aaf192a84..7bdc423cd 100644 --- a/src/mbgl/programs/fill_extrusion_program.cpp +++ b/src/mbgl/programs/fill_extrusion_program.cpp @@ -12,15 +12,15 @@ using namespace style; static_assert(sizeof(FillExtrusionLayoutVertex) == 12, "expected FillExtrusionLayoutVertex size"); std::array<float, 3> lightColor(const EvaluatedLight& light) { - const auto color = light.get<LightColor>(); + const auto color = light.color; return {{ color.r, color.g, color.b }}; } std::array<float, 3> lightPosition(const EvaluatedLight& light, const TransformState& state) { - auto lightPos = light.get<LightPosition>().getCartesian(); + auto lightPos = light.position.getCartesian(); mat3 lightMat; matrix::identity(lightMat); - if (light.get<LightAnchor>() == LightAnchorType::Viewport) { + if (light.anchor == LightAnchorType::Viewport) { matrix::rotate(lightMat, lightMat, -state.getAngle()); } matrix::transformMat3f(lightPos, lightPos, lightMat); @@ -28,7 +28,7 @@ std::array<float, 3> lightPosition(const EvaluatedLight& light, const TransformS } float lightIntensity(const EvaluatedLight& light) { - return light.get<LightIntensity>(); + return light.intensity; } FillExtrusionUniforms::Values diff --git a/src/mbgl/programs/heatmap_texture_program.hpp b/src/mbgl/programs/heatmap_texture_program.hpp index 7afe8060d..96bdbb517 100644 --- a/src/mbgl/programs/heatmap_texture_program.hpp +++ b/src/mbgl/programs/heatmap_texture_program.hpp @@ -23,7 +23,7 @@ class HeatmapTextureProgram : public Program< uniforms::u_image, uniforms::u_color_ramp, uniforms::u_opacity>, - style::Properties<>> { + style::NoProperties> { public: using Program::Program; diff --git a/src/mbgl/programs/hillshade_prepare_program.hpp b/src/mbgl/programs/hillshade_prepare_program.hpp index 76638afdd..6afb392cc 100644 --- a/src/mbgl/programs/hillshade_prepare_program.hpp +++ b/src/mbgl/programs/hillshade_prepare_program.hpp @@ -25,7 +25,7 @@ class HillshadePrepareProgram : public Program< uniforms::u_zoom, uniforms::u_maxzoom, uniforms::u_image>, - style::Properties<>> { + style::NoProperties> { public: using Program::Program; diff --git a/src/mbgl/programs/hillshade_program.hpp b/src/mbgl/programs/hillshade_program.hpp index 5f9b4d1c2..75f38990c 100644 --- a/src/mbgl/programs/hillshade_program.hpp +++ b/src/mbgl/programs/hillshade_program.hpp @@ -31,7 +31,7 @@ class HillshadeProgram : public Program< uniforms::u_accent, uniforms::u_light, uniforms::u_latrange>, - style::HillshadePaintProperties>{ + style::NoProperties>{ public: using Program::Program; diff --git a/src/mbgl/programs/line_program.cpp b/src/mbgl/programs/line_program.cpp index faf57ef19..368f05846 100644 --- a/src/mbgl/programs/line_program.cpp +++ b/src/mbgl/programs/line_program.cpp @@ -21,8 +21,8 @@ Values makeValues(const RenderLinePaintProperties::PossiblyEvaluated& properties return Values { uniforms::u_matrix::Value{ - tile.translatedMatrix(properties.get<LineTranslate>(), - properties.get<LineTranslateAnchor>(), + tile.translatedMatrix(properties.lineTranslate, + properties.lineTranslateAnchor, state) }, uniforms::u_ratio::Value{ 1.0f / tile.id.pixelsToTileUnits(1.0, state.getZoom()) }, @@ -53,8 +53,8 @@ LineSDFProgram::uniformValues(const RenderLinePaintProperties::PossiblyEvaluated const LinePatternPos& posA, const LinePatternPos& posB, float atlasWidth) { - const float widthA = posA.width * properties.get<LineDasharray>().fromScale; - const float widthB = posB.width * properties.get<LineDasharray>().toScale; + const float widthA = posA.width * properties.lineDasharray.fromScale; + const float widthB = posB.width * properties.lineDasharray.toScale; std::array<float, 2> scaleA {{ 1.0f / tile.id.pixelsToTileUnits(widthA, state.getIntegerZoom()), @@ -75,7 +75,7 @@ LineSDFProgram::uniformValues(const RenderLinePaintProperties::PossiblyEvaluated uniforms::u_patternscale_b::Value{ scaleB }, uniforms::u_tex_y_a::Value{ posA.y }, uniforms::u_tex_y_b::Value{ posB.y }, - uniforms::u_mix::Value{ properties.get<LineDasharray>().t }, + uniforms::u_mix::Value{ properties.lineDasharray.t }, uniforms::u_sdfgamma::Value{ atlasWidth / (std::min(widthA, widthB) * 256.0f * pixelRatio) / 2.0f }, uniforms::u_image::Value{ 0 } ); @@ -90,12 +90,12 @@ LinePatternProgram::uniformValues(const RenderLinePaintProperties::PossiblyEvalu const ImagePosition& posA, const ImagePosition& posB) { std::array<float, 2> sizeA {{ - tile.id.pixelsToTileUnits(posA.displaySize()[0] * properties.get<LinePattern>().fromScale, state.getIntegerZoom()), + tile.id.pixelsToTileUnits(posA.displaySize()[0] * properties.linePattern.fromScale, state.getIntegerZoom()), posA.displaySize()[1] }}; std::array<float, 2> sizeB {{ - tile.id.pixelsToTileUnits(posB.displaySize()[0] * properties.get<LinePattern>().toScale, state.getIntegerZoom()), + tile.id.pixelsToTileUnits(posB.displaySize()[0] * properties.linePattern.toScale, state.getIntegerZoom()), posB.displaySize()[1] }}; @@ -111,7 +111,7 @@ LinePatternProgram::uniformValues(const RenderLinePaintProperties::PossiblyEvalu uniforms::u_pattern_size_a::Value{ sizeA }, uniforms::u_pattern_size_b::Value{ sizeB }, uniforms::u_texsize::Value{ atlasSize }, - uniforms::u_fade::Value{ properties.get<LinePattern>().t }, + uniforms::u_fade::Value{ properties.linePattern.t }, uniforms::u_image::Value{ 0 } ); } diff --git a/src/mbgl/programs/program.hpp b/src/mbgl/programs/program.hpp index 4d5de0533..3727717c5 100644 --- a/src/mbgl/programs/program.hpp +++ b/src/mbgl/programs/program.hpp @@ -46,19 +46,21 @@ public: Shaders::fragmentSource)) { } + template <class PossiblyEvaluatedProperties> static typename AllUniforms::Values computeAllUniformValues( const UniformValues& uniformValues, const PaintPropertyBinders& paintPropertyBinders, - const typename PaintProperties::PossiblyEvaluated& currentProperties, + const PossiblyEvaluatedProperties& currentProperties, float currentZoom) { return uniformValues .concat(paintPropertyBinders.uniformValues(currentZoom, currentProperties)); } + template <class PossiblyEvaluatedProperties> static typename Attributes::Bindings computeAllAttributeBindings( const gl::VertexBuffer<LayoutVertex>& layoutVertexBuffer, const PaintPropertyBinders& paintPropertyBinders, - const typename PaintProperties::PossiblyEvaluated& currentProperties) { + const PossiblyEvaluatedProperties& currentProperties) { return LayoutAttributes::bindings(layoutVertexBuffer) .concat(paintPropertyBinders.attributeBindings(currentProperties)); } @@ -105,8 +107,7 @@ template <class Program> class ProgramMap { public: using PaintProperties = typename Program::PaintProperties; - using PaintPropertyBinders = typename Program::PaintPropertyBinders; - using Bitset = typename PaintPropertyBinders::Bitset; + using Bitset = std::bitset<8>; ProgramMap(gl::Context& context_, ProgramParameters parameters_) : context(context_), @@ -114,7 +115,7 @@ public: } Program& get(const typename PaintProperties::PossiblyEvaluated& currentProperties) { - Bitset bits = PaintPropertyBinders::constants(currentProperties); + Bitset bits = currentProperties.constants(); auto it = programs.find(bits); if (it != programs.end()) { return it->second; @@ -122,7 +123,7 @@ public: return programs.emplace(std::piecewise_construct, std::forward_as_tuple(bits), std::forward_as_tuple(context, - parameters.withAdditionalDefines(PaintPropertyBinders::defines(currentProperties)))).first->second; + parameters.withAdditionalDefines(currentProperties.defines()))).first->second; } private: diff --git a/src/mbgl/programs/raster_program.hpp b/src/mbgl/programs/raster_program.hpp index 09cb94ac1..2cf98d91c 100644 --- a/src/mbgl/programs/raster_program.hpp +++ b/src/mbgl/programs/raster_program.hpp @@ -43,7 +43,7 @@ class RasterProgram : public Program< uniforms::u_buffer_scale, uniforms::u_scale_parent, uniforms::u_tl_parent>, - style::RasterPaintProperties> + style::NoProperties> { public: using Program::Program; diff --git a/src/mbgl/renderer/buckets/circle_bucket.cpp b/src/mbgl/renderer/buckets/circle_bucket.cpp index d07c1f8db..49488ab97 100644 --- a/src/mbgl/renderer/buckets/circle_bucket.cpp +++ b/src/mbgl/renderer/buckets/circle_bucket.cpp @@ -15,11 +15,8 @@ CircleBucket::CircleBucket(const BucketParameters& parameters, const std::vector mode(parameters.mode) { for (const auto& layer : layers) { paintPropertyBinders.emplace( - std::piecewise_construct, - std::forward_as_tuple(layer->getID()), - std::forward_as_tuple( - layer->as<RenderCircleLayer>()->evaluated, - parameters.tileID.overscaledZ)); + layer->getID(), + layer->as<RenderCircleLayer>()->evaluated.createBinders(parameters.tileID.overscaledZ)); } } @@ -92,13 +89,14 @@ void CircleBucket::addFeature(const GeometryTileFeature& feature, } template <class Property> -static float get(const RenderCircleLayer& layer, const std::map<std::string, CircleProgram::PaintPropertyBinders>& paintPropertyBinders) { - auto it = paintPropertyBinders.find(layer.getID()); - if (it == paintPropertyBinders.end() || !it->second.statistics<Property>().max()) { - return layer.evaluated.get<Property>().constantOr(Property::defaultValue()); - } else { - return *it->second.statistics<Property>().max(); - } +static float get(const RenderCircleLayer&, const std::map<std::string, CircleProgram::PaintPropertyBinders>&) { +// auto it = paintPropertyBinders.find(layer.getID()); +// if (it == paintPropertyBinders.end() || !it->second.statistics<Property>().max()) { +// return layer.evaluated.get<Property>().constantOr(Property::defaultValue()); +// } else { +// return *it->second.statistics<Property>().max(); +// } + return 0; } float CircleBucket::getQueryRadius(const RenderLayer& layer) const { @@ -110,7 +108,7 @@ float CircleBucket::getQueryRadius(const RenderLayer& layer) const { float radius = get<CircleRadius>(*circleLayer, paintPropertyBinders); float stroke = get<CircleStrokeWidth>(*circleLayer, paintPropertyBinders); - auto translate = circleLayer->evaluated.get<CircleTranslate>(); + auto translate = circleLayer->evaluated.circleTranslate; return radius + stroke + util::length(translate[0], translate[1]); } diff --git a/src/mbgl/renderer/buckets/fill_bucket.cpp b/src/mbgl/renderer/buckets/fill_bucket.cpp index 14be98c3a..e9aa6dcb4 100644 --- a/src/mbgl/renderer/buckets/fill_bucket.cpp +++ b/src/mbgl/renderer/buckets/fill_bucket.cpp @@ -31,11 +31,8 @@ FillBucket::FillBucket(const BucketParameters& parameters, const std::vector<con : Bucket(LayerType::Fill) { for (const auto& layer : layers) { paintPropertyBinders.emplace( - std::piecewise_construct, - std::forward_as_tuple(layer->getID()), - std::forward_as_tuple( - layer->as<RenderFillLayer>()->evaluated, - parameters.tileID.overscaledZ)); + layer->getID(), + layer->as<RenderFillLayer>()->evaluated.createBinders(parameters.tileID.overscaledZ)); } } @@ -130,7 +127,7 @@ float FillBucket::getQueryRadius(const RenderLayer& layer) const { return 0; } - const std::array<float, 2>& translate = layer.as<RenderFillLayer>()->evaluated.get<FillTranslate>(); + const std::array<float, 2>& translate = layer.as<RenderFillLayer>()->evaluated.fillTranslate; return util::length(translate[0], translate[1]); } diff --git a/src/mbgl/renderer/buckets/fill_extrusion_bucket.cpp b/src/mbgl/renderer/buckets/fill_extrusion_bucket.cpp index c6dba38db..61ef692e4 100644 --- a/src/mbgl/renderer/buckets/fill_extrusion_bucket.cpp +++ b/src/mbgl/renderer/buckets/fill_extrusion_bucket.cpp @@ -37,11 +37,9 @@ struct GeometryTooLongException : std::exception {}; FillExtrusionBucket::FillExtrusionBucket(const BucketParameters& parameters, const std::vector<const RenderLayer*>& layers) : Bucket(LayerType::FillExtrusion) { for (const auto& layer : layers) { - paintPropertyBinders.emplace(std::piecewise_construct, - std::forward_as_tuple(layer->getID()), - std::forward_as_tuple( - layer->as<RenderFillExtrusionLayer>()->evaluated, - parameters.tileID.overscaledZ)); + paintPropertyBinders.emplace( + layer->getID(), + layer->as<RenderFillExtrusionLayer>()->evaluated.createBinders(parameters.tileID.overscaledZ)); } } @@ -167,7 +165,7 @@ float FillExtrusionBucket::getQueryRadius(const RenderLayer& layer) const { return 0; } - const std::array<float, 2>& translate = layer.as<RenderFillExtrusionLayer>()->evaluated.get<FillExtrusionTranslate>(); + const std::array<float, 2>& translate = layer.as<RenderFillExtrusionLayer>()->evaluated.fillExtrusionTranslate; return util::length(translate[0], translate[1]); } diff --git a/src/mbgl/renderer/buckets/heatmap_bucket.cpp b/src/mbgl/renderer/buckets/heatmap_bucket.cpp index eff0c6028..15c946674 100644 --- a/src/mbgl/renderer/buckets/heatmap_bucket.cpp +++ b/src/mbgl/renderer/buckets/heatmap_bucket.cpp @@ -15,11 +15,8 @@ HeatmapBucket::HeatmapBucket(const BucketParameters& parameters, const std::vect mode(parameters.mode) { for (const auto& layer : layers) { paintPropertyBinders.emplace( - std::piecewise_construct, - std::forward_as_tuple(layer->getID()), - std::forward_as_tuple( - layer->as<RenderHeatmapLayer>()->evaluated, - parameters.tileID.overscaledZ)); + layer->getID(), + layer->as<RenderHeatmapLayer>()->evaluated.createBinders(parameters.tileID.overscaledZ)); } } diff --git a/src/mbgl/renderer/buckets/line_bucket.cpp b/src/mbgl/renderer/buckets/line_bucket.cpp index a10551a7d..9ef04e694 100644 --- a/src/mbgl/renderer/buckets/line_bucket.cpp +++ b/src/mbgl/renderer/buckets/line_bucket.cpp @@ -20,11 +20,8 @@ LineBucket::LineBucket(const BucketParameters& parameters, zoom(parameters.tileID.overscaledZ) { for (const auto& layer : layers) { paintPropertyBinders.emplace( - std::piecewise_construct, - std::forward_as_tuple(layer->getID()), - std::forward_as_tuple( - layer->as<RenderLineLayer>()->evaluated, - parameters.tileID.overscaledZ)); + layer->getID(), + layer->as<RenderLineLayer>()->evaluated.createBinders(parameters.tileID.overscaledZ)); } } @@ -89,15 +86,15 @@ void LineBucket::addGeometry(const GeometryCoordinates& coordinates, const Geome return; } - const LineJoinType joinType = layout.evaluate<LineJoin>(zoom, feature); + const LineJoinType joinType = layout.lineJoin.evaluate(feature, zoom, LineJoin::defaultValue()); - const float miterLimit = joinType == LineJoinType::Bevel ? 1.05f : float(layout.get<LineMiterLimit>()); + const float miterLimit = joinType == LineJoinType::Bevel ? 1.05f : float(layout.lineMiterLimit); const double sharpCornerOffset = SHARP_CORNER_OFFSET * (float(util::EXTENT) / (util::tileSize * overscaling)); const GeometryCoordinate firstCoordinate = coordinates[first]; - const LineCapType beginCap = layout.get<LineCap>(); - const LineCapType endCap = type == FeatureType::Polygon ? LineCapType::Butt : LineCapType(layout.get<LineCap>()); + const LineCapType beginCap = layout.lineCap; + const LineCapType endCap = type == FeatureType::Polygon ? LineCapType::Butt : LineCapType(layout.lineCap); double distance = 0; bool startOfLine = true; @@ -203,7 +200,7 @@ void LineBucket::addGeometry(const GeometryCoordinates& coordinates, const Geome if (middleVertex) { if (currentJoin == LineJoinType::Round) { - if (miterLength < layout.get<LineRoundLimit>()) { + if (miterLength < layout.lineRoundLimit) { currentJoin = LineJoinType::Miter; } else if (miterLength <= 2) { currentJoin = LineJoinType::FakeRound; @@ -466,19 +463,36 @@ bool LineBucket::hasData() const { return !segments.empty(); } -template <class Property> -static float get(const RenderLineLayer& layer, const std::map<std::string, LineProgram::PaintPropertyBinders>& paintPropertyBinders) { +static float getLineWidth(const RenderLineLayer& layer, const std::map<std::string, LineProgram::PaintPropertyBinders>& paintPropertyBinders) { auto it = paintPropertyBinders.find(layer.getID()); - if (it == paintPropertyBinders.end() || !it->second.statistics<Property>().max()) { - return layer.evaluated.get<Property>().constantOr(Property::defaultValue()); + if (it == paintPropertyBinders.end() || !it->second.lineWidth->statistics.max()) { + return layer.evaluated.lineWidth.constantOr(LineWidth::defaultValue()); } else { - return *it->second.statistics<Property>().max(); + return *it->second.lineWidth->statistics.max(); + } +} + +static float getLineGapWidth(const RenderLineLayer& layer, const std::map<std::string, LineProgram::PaintPropertyBinders>& paintPropertyBinders) { + auto it = paintPropertyBinders.find(layer.getID()); + if (it == paintPropertyBinders.end() || !it->second.lineGapWidth->statistics.max()) { + return layer.evaluated.lineGapWidth.constantOr(LineGapWidth::defaultValue()); + } else { + return *it->second.lineGapWidth->statistics.max(); + } +} + +static float getLineOffset(const RenderLineLayer& layer, const std::map<std::string, LineProgram::PaintPropertyBinders>& paintPropertyBinders) { + auto it = paintPropertyBinders.find(layer.getID()); + if (it == paintPropertyBinders.end() || !it->second.lineOffset->statistics.max()) { + return layer.evaluated.lineOffset.constantOr(LineOffset::defaultValue()); + } else { + return *it->second.lineOffset->statistics.max(); } } float LineBucket::getLineWidth(const RenderLineLayer& layer) const { - float lineWidth = get<LineWidth>(layer, paintPropertyBinders); - float gapWidth = get<LineGapWidth>(layer, paintPropertyBinders); + float lineWidth = ::mbgl::getLineWidth(layer, paintPropertyBinders); + float gapWidth = ::mbgl::getLineGapWidth(layer, paintPropertyBinders); if (gapWidth) { return gapWidth + 2 * lineWidth; @@ -494,8 +508,8 @@ float LineBucket::getQueryRadius(const RenderLayer& layer) const { auto lineLayer = layer.as<RenderLineLayer>(); - const std::array<float, 2>& translate = lineLayer->evaluated.get<LineTranslate>(); - float offset = get<LineOffset>(*lineLayer, paintPropertyBinders); + const std::array<float, 2>& translate = lineLayer->evaluated.lineTranslate; + float offset = getLineOffset(*lineLayer, paintPropertyBinders); return getLineWidth(*lineLayer) / 2.0 + std::abs(offset) + util::length(translate[0], translate[1]); } diff --git a/src/mbgl/renderer/buckets/symbol_bucket.cpp b/src/mbgl/renderer/buckets/symbol_bucket.cpp index a3f652fc6..add38b005 100644 --- a/src/mbgl/renderer/buckets/symbol_bucket.cpp +++ b/src/mbgl/renderer/buckets/symbol_bucket.cpp @@ -32,12 +32,10 @@ SymbolBucket::SymbolBucket(style::SymbolLayoutProperties::PossiblyEvaluated layo for (const auto& pair : layerPaintProperties) { paintPropertyBinders.emplace( - std::piecewise_construct, - std::forward_as_tuple(pair.first), - std::forward_as_tuple( - std::piecewise_construct, - std::forward_as_tuple(pair.second.first, zoom), - std::forward_as_tuple(pair.second.second, zoom))); + pair.first, + std::make_pair( + pair.second.first.createBinders(zoom), + pair.second.second.createBinders(zoom))); } } diff --git a/src/mbgl/renderer/layers/render_background_layer.cpp b/src/mbgl/renderer/layers/render_background_layer.cpp index 2dc5fe733..8d022ce8c 100644 --- a/src/mbgl/renderer/layers/render_background_layer.cpp +++ b/src/mbgl/renderer/layers/render_background_layer.cpp @@ -35,7 +35,7 @@ void RenderBackgroundLayer::transition(const TransitionParameters ¶meters) { void RenderBackgroundLayer::evaluate(const PropertyEvaluationParameters ¶meters) { evaluated = unevaluated.evaluate(parameters); - passes = evaluated.get<style::BackgroundOpacity>() > 0 ? RenderPass::Translucent + passes = evaluated.backgroundOpacity > 0 ? RenderPass::Translucent : RenderPass::None; } @@ -47,19 +47,19 @@ void RenderBackgroundLayer::render(PaintParameters& parameters, RenderSource*) { // Note that for bottommost layers without a pattern, the background color is drawn with // glClear rather than this method. - const Properties<>::PossiblyEvaluated properties; - const BackgroundProgram::PaintPropertyBinders paintAttributeData(properties, 0); + static const NoProperties::PossiblyEvaluated properties; + static const NoProperties::Binders binders; auto draw = [&](auto& program, auto&& uniformValues) { const auto allUniformValues = program.computeAllUniformValues( std::move(uniformValues), - paintAttributeData, + binders, properties, parameters.state.getZoom() ); const auto allAttributeBindings = program.computeAllAttributeBindings( parameters.staticData.tileVertexBuffer, - paintAttributeData, + binders, properties ); @@ -79,9 +79,9 @@ void RenderBackgroundLayer::render(PaintParameters& parameters, RenderSource*) { ); }; - if (!evaluated.get<BackgroundPattern>().to.empty()) { - optional<ImagePosition> imagePosA = parameters.imageManager.getPattern(evaluated.get<BackgroundPattern>().from); - optional<ImagePosition> imagePosB = parameters.imageManager.getPattern(evaluated.get<BackgroundPattern>().to); + if (!evaluated.backgroundPattern.to.empty()) { + optional<ImagePosition> imagePosA = parameters.imageManager.getPattern(evaluated.backgroundPattern.from); + optional<ImagePosition> imagePosB = parameters.imageManager.getPattern(evaluated.backgroundPattern.to); if (!imagePosA || !imagePosB) return; @@ -93,11 +93,11 @@ void RenderBackgroundLayer::render(PaintParameters& parameters, RenderSource*) { parameters.programs.backgroundPattern, BackgroundPatternUniforms::values( parameters.matrixForTile(tileID), - evaluated.get<BackgroundOpacity>(), + evaluated.backgroundOpacity, parameters.imageManager.getPixelSize(), *imagePosA, *imagePosB, - evaluated.get<BackgroundPattern>(), + evaluated.backgroundPattern, tileID, parameters.state ) @@ -109,8 +109,8 @@ void RenderBackgroundLayer::render(PaintParameters& parameters, RenderSource*) { parameters.programs.background, BackgroundProgram::UniformValues { uniforms::u_matrix::Value{ parameters.matrixForTile(tileID) }, - uniforms::u_color::Value{ evaluated.get<BackgroundColor>() }, - uniforms::u_opacity::Value{ evaluated.get<BackgroundOpacity>() }, + uniforms::u_color::Value{ evaluated.backgroundColor }, + uniforms::u_opacity::Value{ evaluated.backgroundOpacity }, } ); } diff --git a/src/mbgl/renderer/layers/render_circle_layer.cpp b/src/mbgl/renderer/layers/render_circle_layer.cpp index ce63ada77..8f50c0a5b 100644 --- a/src/mbgl/renderer/layers/render_circle_layer.cpp +++ b/src/mbgl/renderer/layers/render_circle_layer.cpp @@ -34,12 +34,12 @@ void RenderCircleLayer::transition(const TransitionParameters& parameters) { void RenderCircleLayer::evaluate(const PropertyEvaluationParameters& parameters) { evaluated = unevaluated.evaluate(parameters); - passes = ((evaluated.get<style::CircleRadius>().constantOr(1) > 0 || - evaluated.get<style::CircleStrokeWidth>().constantOr(1) > 0) - && (evaluated.get<style::CircleColor>().constantOr(Color::black()).a > 0 || - evaluated.get<style::CircleStrokeColor>().constantOr(Color::black()).a > 0) - && (evaluated.get<style::CircleOpacity>().constantOr(1) > 0 || - evaluated.get<style::CircleStrokeOpacity>().constantOr(1) > 0)) + passes = ((evaluated.circleRadius.constantOr(1) > 0 || + evaluated.circleStrokeWidth.constantOr(1) > 0) + && (evaluated.circleColor.constantOr(Color::black()).a > 0 || + evaluated.circleStrokeColor.constantOr(Color::black()).a > 0) + && (evaluated.circleOpacity.constantOr(1) > 0 || + evaluated.circleStrokeOpacity.constantOr(1) > 0)) ? RenderPass::Translucent : RenderPass::None; } @@ -52,8 +52,8 @@ void RenderCircleLayer::render(PaintParameters& parameters, RenderSource*) { return; } - const bool scaleWithMap = evaluated.get<CirclePitchScale>() == CirclePitchScaleType::Map; - const bool pitchWithMap = evaluated.get<CirclePitchAlignment>() == AlignmentType::Map; + const bool scaleWithMap = evaluated.circlePitchScale == CirclePitchScaleType::Map; + const bool pitchWithMap = evaluated.circlePitchAlignment == AlignmentType::Map; for (const RenderTile& tile : renderTiles) { auto bucket_ = tile.tile.getBucket<CircleBucket>(*baseImpl); @@ -69,8 +69,8 @@ void RenderCircleLayer::render(PaintParameters& parameters, RenderSource*) { const auto allUniformValues = programInstance.computeAllUniformValues( CircleProgram::UniformValues { uniforms::u_matrix::Value{ - tile.translatedMatrix(evaluated.get<CircleTranslate>(), - evaluated.get<CircleTranslateAnchor>(), + tile.translatedMatrix(evaluated.circleTranslate, + evaluated.circleTranslateAnchor, parameters.state) }, uniforms::u_scale_with_map::Value{ scaleWithMap }, @@ -139,21 +139,21 @@ bool RenderCircleLayer::queryIntersectsFeature( // Translate query geometry const GeometryCoordinates& translatedQueryGeometry = FeatureIndex::translateQueryGeometry( queryGeometry, - evaluated.get<style::CircleTranslate>(), - evaluated.get<style::CircleTranslateAnchor>(), + evaluated.circleTranslate, + evaluated.circleTranslateAnchor, transformState.getAngle(), pixelsToTileUnits).value_or(queryGeometry); // Evaluate functions - auto radius = evaluated.evaluate<style::CircleRadius>(zoom, feature); - auto stroke = evaluated.evaluate<style::CircleStrokeWidth>(zoom, feature); + auto radius = evaluated.circleRadius.evaluate(feature, zoom, CircleRadius::defaultValue()); + auto stroke = evaluated.circleStrokeWidth.evaluate(feature, zoom, CircleStrokeWidth::defaultValue()); auto size = radius + stroke; // For pitch-alignment: map, compare feature geometry to query geometry in the plane of the tile // Otherwise, compare geometry in the plane of the viewport // A circle with fixed scaling relative to the viewport gets larger in tile space as it moves into the distance // A circle with fixed scaling relative to the map gets smaller in viewport space as it moves into the distance - bool alignWithMap = evaluated.evaluate<style::CirclePitchAlignment>(zoom, feature) == AlignmentType::Map; + bool alignWithMap = evaluated.circlePitchAlignment == AlignmentType::Map; const GeometryCoordinates& transformedQueryGeometry = alignWithMap ? translatedQueryGeometry : projectQueryGeometry(translatedQueryGeometry, posMatrix, transformState.getSize()); @@ -167,8 +167,8 @@ bool RenderCircleLayer::queryIntersectsFeature( float adjustedSize = transformedSize; vec4 center = {{ static_cast<double>(point.x), static_cast<double>(point.y), 0, 1 }}; matrix::transformMat4(center, center, posMatrix); - auto pitchScale = evaluated.evaluate<style::CirclePitchScale>(zoom, feature); - auto pitchAlignment = evaluated.evaluate<style::CirclePitchAlignment>(zoom, feature); + auto pitchScale = evaluated.circlePitchScale; + auto pitchAlignment = evaluated.circlePitchAlignment; if (pitchScale == CirclePitchScaleType::Viewport && pitchAlignment == AlignmentType::Map) { adjustedSize *= center[3] / transformState.getCameraToCenterDistance(); } else if (pitchScale == CirclePitchScaleType::Map && pitchAlignment == AlignmentType::Viewport) { diff --git a/src/mbgl/renderer/layers/render_fill_extrusion_layer.cpp b/src/mbgl/renderer/layers/render_fill_extrusion_layer.cpp index 2f720284f..8d9bae64a 100644 --- a/src/mbgl/renderer/layers/render_fill_extrusion_layer.cpp +++ b/src/mbgl/renderer/layers/render_fill_extrusion_layer.cpp @@ -37,7 +37,7 @@ void RenderFillExtrusionLayer::transition(const TransitionParameters& parameters void RenderFillExtrusionLayer::evaluate(const PropertyEvaluationParameters& parameters) { evaluated = unevaluated.evaluate(parameters); - passes = (evaluated.get<style::FillExtrusionOpacity>() > 0) + passes = (evaluated.fillExtrusionOpacity > 0) ? (RenderPass::Translucent | RenderPass::Pass3D) : RenderPass::None; } @@ -98,7 +98,7 @@ void RenderFillExtrusionLayer::render(PaintParameters& parameters, RenderSource* getID()); }; - if (evaluated.get<FillExtrusionPattern>().from.empty()) { + if (evaluated.fillExtrusionPattern.from.empty()) { for (const RenderTile& tile : renderTiles) { auto bucket_ = tile.tile.getBucket<FillExtrusionBucket>(*baseImpl); if (!bucket_) { @@ -110,8 +110,8 @@ void RenderFillExtrusionLayer::render(PaintParameters& parameters, RenderSource* parameters.programs.fillExtrusion.get(evaluated), bucket, FillExtrusionUniforms::values( - tile.translatedClipMatrix(evaluated.get<FillExtrusionTranslate>(), - evaluated.get<FillExtrusionTranslateAnchor>(), + tile.translatedClipMatrix(evaluated.fillExtrusionTranslate, + evaluated.fillExtrusionTranslateAnchor, parameters.state), parameters.state, parameters.evaluatedLight @@ -120,9 +120,9 @@ void RenderFillExtrusionLayer::render(PaintParameters& parameters, RenderSource* } } else { optional<ImagePosition> imagePosA = - parameters.imageManager.getPattern(evaluated.get<FillExtrusionPattern>().from); + parameters.imageManager.getPattern(evaluated.fillExtrusionPattern.from); optional<ImagePosition> imagePosB = - parameters.imageManager.getPattern(evaluated.get<FillExtrusionPattern>().to); + parameters.imageManager.getPattern(evaluated.fillExtrusionPattern.to); if (!imagePosA || !imagePosB) { return; @@ -141,11 +141,11 @@ void RenderFillExtrusionLayer::render(PaintParameters& parameters, RenderSource* parameters.programs.fillExtrusionPattern.get(evaluated), bucket, FillExtrusionPatternUniforms::values( - tile.translatedClipMatrix(evaluated.get<FillExtrusionTranslate>(), - evaluated.get<FillExtrusionTranslateAnchor>(), + tile.translatedClipMatrix(evaluated.fillExtrusionTranslate, + evaluated.fillExtrusionTranslateAnchor, parameters.state), parameters.imageManager.getPixelSize(), *imagePosA, *imagePosB, - evaluated.get<FillExtrusionPattern>(), tile.id, parameters.state, + evaluated.fillExtrusionPattern, tile.id, parameters.state, -std::pow(2, tile.id.canonical.z) / util::tileSize / 8.0f, parameters.evaluatedLight ) @@ -161,24 +161,24 @@ void RenderFillExtrusionLayer::render(PaintParameters& parameters, RenderSource* mat4 viewportMat; matrix::ortho(viewportMat, 0, size.width, size.height, 0, 0, 1); - const Properties<>::PossiblyEvaluated properties; - const ExtrusionTextureProgram::PaintPropertyBinders paintAttributeData{ properties, 0 }; - + static const NoProperties::PossiblyEvaluated properties; + static const NoProperties::Binders binders; + auto& programInstance = parameters.programs.extrusionTexture; const auto allUniformValues = programInstance.computeAllUniformValues( ExtrusionTextureProgram::UniformValues{ uniforms::u_matrix::Value{ viewportMat }, uniforms::u_world::Value{ size }, uniforms::u_image::Value{ 0 }, - uniforms::u_opacity::Value{ evaluated.get<FillExtrusionOpacity>() } + uniforms::u_opacity::Value{ evaluated.fillExtrusionOpacity } }, - paintAttributeData, + binders, properties, parameters.state.getZoom() ); const auto allAttributeBindings = programInstance.computeAllAttributeBindings( parameters.staticData.extrusionTextureVertexBuffer, - paintAttributeData, + binders, properties ); @@ -208,8 +208,8 @@ bool RenderFillExtrusionLayer::queryIntersectsFeature( auto translatedQueryGeometry = FeatureIndex::translateQueryGeometry( queryGeometry, - evaluated.get<style::FillExtrusionTranslate>(), - evaluated.get<style::FillExtrusionTranslateAnchor>(), + evaluated.fillExtrusionTranslate, + evaluated.fillExtrusionTranslateAnchor, transformState.getAngle(), pixelsToTileUnits); diff --git a/src/mbgl/renderer/layers/render_fill_layer.cpp b/src/mbgl/renderer/layers/render_fill_layer.cpp index f03eb66c8..928fdc44b 100644 --- a/src/mbgl/renderer/layers/render_fill_layer.cpp +++ b/src/mbgl/renderer/layers/render_fill_layer.cpp @@ -35,19 +35,19 @@ void RenderFillLayer::transition(const TransitionParameters& parameters) { void RenderFillLayer::evaluate(const PropertyEvaluationParameters& parameters) { evaluated = unevaluated.evaluate(parameters); - if (unevaluated.get<style::FillOutlineColor>().isUndefined()) { - evaluated.get<style::FillOutlineColor>() = evaluated.get<style::FillColor>(); + if (unevaluated.fillOutlineColor.isUndefined()) { + evaluated.fillOutlineColor = evaluated.fillColor; } passes = RenderPass::None; - if (evaluated.get<style::FillAntialias>()) { + if (evaluated.fillAntialias) { passes |= RenderPass::Translucent; } - if (!unevaluated.get<style::FillPattern>().isUndefined() - || evaluated.get<style::FillColor>().constantOr(Color()).a < 1.0f - || evaluated.get<style::FillOpacity>().constantOr(0) < 1.0f) { + if (!unevaluated.fillPattern.isUndefined() + || evaluated.fillColor.constantOr(Color()).a < 1.0f + || evaluated.fillOpacity.constantOr(0) < 1.0f) { passes |= RenderPass::Translucent; } else { passes |= RenderPass::Opaque; @@ -59,7 +59,7 @@ bool RenderFillLayer::hasTransition() const { } void RenderFillLayer::render(PaintParameters& parameters, RenderSource*) { - if (evaluated.get<FillPattern>().from.empty()) { + if (evaluated.fillPattern.from.empty()) { for (const RenderTile& tile : renderTiles) { auto bucket_ = tile.tile.getBucket<FillBucket>(*baseImpl); if (!bucket_) { @@ -79,8 +79,8 @@ void RenderFillLayer::render(PaintParameters& parameters, RenderSource*) { const auto allUniformValues = programInstance.computeAllUniformValues( FillProgram::UniformValues { uniforms::u_matrix::Value{ - tile.translatedMatrix(evaluated.get<FillTranslate>(), - evaluated.get<FillTranslateAnchor>(), + tile.translatedMatrix(evaluated.fillTranslate, + evaluated.fillTranslateAnchor, parameters.state) }, uniforms::u_world::Value{ parameters.context.viewport.getCurrentValue().size }, @@ -113,8 +113,8 @@ void RenderFillLayer::render(PaintParameters& parameters, RenderSource*) { // Only draw the fill when it's opaque and we're drawing opaque fragments, // or when it's translucent and we're drawing translucent fragments. - if ((evaluated.get<FillColor>().constantOr(Color()).a >= 1.0f - && evaluated.get<FillOpacity>().constantOr(0) >= 1.0f) == (parameters.pass == RenderPass::Opaque)) { + if ((evaluated.fillColor.constantOr(Color()).a >= 1.0f + && evaluated.fillOpacity.constantOr(0) >= 1.0f) == (parameters.pass == RenderPass::Opaque)) { draw(parameters.programs.fill, gl::Triangles(), parameters.depthModeForSublayer(1, parameters.pass == RenderPass::Opaque @@ -124,11 +124,11 @@ void RenderFillLayer::render(PaintParameters& parameters, RenderSource*) { bucket.triangleSegments); } - if (evaluated.get<FillAntialias>() && parameters.pass == RenderPass::Translucent) { + if (evaluated.fillAntialias && parameters.pass == RenderPass::Translucent) { draw(parameters.programs.fillOutline, gl::Lines{ 2.0f }, parameters.depthModeForSublayer( - unevaluated.get<FillOutlineColor>().isUndefined() ? 2 : 0, + unevaluated.fillOutlineColor.isUndefined() ? 2 : 0, gl::DepthMode::ReadOnly), *bucket.lineIndexBuffer, bucket.lineSegments); @@ -139,8 +139,8 @@ void RenderFillLayer::render(PaintParameters& parameters, RenderSource*) { return; } - optional<ImagePosition> imagePosA = parameters.imageManager.getPattern(evaluated.get<FillPattern>().from); - optional<ImagePosition> imagePosB = parameters.imageManager.getPattern(evaluated.get<FillPattern>().to); + optional<ImagePosition> imagePosA = parameters.imageManager.getPattern(evaluated.fillPattern.from); + optional<ImagePosition> imagePosB = parameters.imageManager.getPattern(evaluated.fillPattern.to); if (!imagePosA || !imagePosB) { return; @@ -166,14 +166,14 @@ void RenderFillLayer::render(PaintParameters& parameters, RenderSource*) { const auto allUniformValues = programInstance.computeAllUniformValues( FillPatternUniforms::values( - tile.translatedMatrix(evaluated.get<FillTranslate>(), - evaluated.get<FillTranslateAnchor>(), + tile.translatedMatrix(evaluated.fillTranslate, + evaluated.fillTranslateAnchor, parameters.state), parameters.context.viewport.getCurrentValue().size, parameters.imageManager.getPixelSize(), *imagePosA, *imagePosB, - evaluated.get<FillPattern>(), + evaluated.fillPattern, tile.id, parameters.state ), @@ -209,7 +209,7 @@ void RenderFillLayer::render(PaintParameters& parameters, RenderSource*) { *bucket.triangleIndexBuffer, bucket.triangleSegments); - if (evaluated.get<FillAntialias>() && unevaluated.get<FillOutlineColor>().isUndefined()) { + if (evaluated.fillAntialias && unevaluated.fillOutlineColor.isUndefined()) { draw(parameters.programs.fillOutlinePattern, gl::Lines { 2.0f }, parameters.depthModeForSublayer(2, gl::DepthMode::ReadOnly), @@ -230,8 +230,8 @@ bool RenderFillLayer::queryIntersectsFeature( auto translatedQueryGeometry = FeatureIndex::translateQueryGeometry( queryGeometry, - evaluated.get<style::FillTranslate>(), - evaluated.get<style::FillTranslateAnchor>(), + evaluated.fillTranslate, + evaluated.fillTranslateAnchor, transformState.getAngle(), pixelsToTileUnits); diff --git a/src/mbgl/renderer/layers/render_heatmap_layer.cpp b/src/mbgl/renderer/layers/render_heatmap_layer.cpp index c9ca477cb..f7ceee651 100644 --- a/src/mbgl/renderer/layers/render_heatmap_layer.cpp +++ b/src/mbgl/renderer/layers/render_heatmap_layer.cpp @@ -36,7 +36,7 @@ void RenderHeatmapLayer::transition(const TransitionParameters& parameters) { void RenderHeatmapLayer::evaluate(const PropertyEvaluationParameters& parameters) { evaluated = unevaluated.evaluate(parameters); - passes = (evaluated.get<style::HeatmapOpacity>() > 0) + passes = (evaluated.heatmapOpacity > 0) ? (RenderPass::Translucent | RenderPass::Pass3D) : RenderPass::None; } @@ -101,7 +101,7 @@ void RenderHeatmapLayer::render(PaintParameters& parameters, RenderSource*) { const auto allUniformValues = programInstance.computeAllUniformValues( HeatmapProgram::UniformValues { - uniforms::u_intensity::Value{ evaluated.get<style::HeatmapIntensity>() }, + uniforms::u_intensity::Value{ evaluated.heatmapIntensity }, uniforms::u_matrix::Value{ tile.matrix }, uniforms::heatmap::u_extrude_scale::Value{ extrudeScale } }, @@ -140,8 +140,8 @@ void RenderHeatmapLayer::render(PaintParameters& parameters, RenderSource*) { mat4 viewportMat; matrix::ortho(viewportMat, 0, size.width, size.height, 0, 0, 1); - const Properties<>::PossiblyEvaluated properties; - const HeatmapTextureProgram::PaintPropertyBinders paintAttributeData{ properties, 0 }; + static const NoProperties::PossiblyEvaluated properties; + static const NoProperties::Binders binders; auto& programInstance = parameters.programs.heatmapTexture; @@ -150,15 +150,15 @@ void RenderHeatmapLayer::render(PaintParameters& parameters, RenderSource*) { uniforms::u_matrix::Value{ viewportMat }, uniforms::u_world::Value{ size }, uniforms::u_image::Value{ 0 }, uniforms::u_color_ramp::Value{ 1 }, - uniforms::u_opacity::Value{ evaluated.get<HeatmapOpacity>() } + uniforms::u_opacity::Value{ evaluated.heatmapOpacity } }, - paintAttributeData, + binders, properties, parameters.state.getZoom() ); const auto allAttributeBindings = programInstance.computeAllAttributeBindings( parameters.staticData.extrusionTextureVertexBuffer, - paintAttributeData, + binders, properties ); @@ -180,7 +180,7 @@ void RenderHeatmapLayer::render(PaintParameters& parameters, RenderSource*) { } void RenderHeatmapLayer::updateColorRamp() { - auto colorValue = unevaluated.get<HeatmapColor>().getValue(); + auto colorValue = unevaluated.heatmapColor.getValue(); if (colorValue.isUndefined()) { colorValue = HeatmapLayer::getDefaultHeatmapColor(); } diff --git a/src/mbgl/renderer/layers/render_hillshade_layer.cpp b/src/mbgl/renderer/layers/render_hillshade_layer.cpp index 8bcd3f183..a4cbda473 100644 --- a/src/mbgl/renderer/layers/render_hillshade_layer.cpp +++ b/src/mbgl/renderer/layers/render_hillshade_layer.cpp @@ -36,9 +36,9 @@ const std::array<float, 2> RenderHillshadeLayer::getLatRange(const UnwrappedTile } const std::array<float, 2> RenderHillshadeLayer::getLight(const PaintParameters& parameters){ - float azimuthal = evaluated.get<HillshadeIlluminationDirection>() * util::DEG2RAD; - if (evaluated.get<HillshadeIlluminationAnchor>() == HillshadeIlluminationAnchorType::Viewport) azimuthal = azimuthal - parameters.state.getAngle(); - return {{evaluated.get<HillshadeExaggeration>(), azimuthal}}; + float azimuthal = evaluated.hillshadeIlluminationDirection * util::DEG2RAD; + if (evaluated.hillshadeIlluminationAnchor == HillshadeIlluminationAnchorType::Viewport) azimuthal = azimuthal - parameters.state.getAngle(); + return {{evaluated.hillshadeExaggeration, azimuthal}}; } void RenderHillshadeLayer::transition(const TransitionParameters& parameters) { @@ -47,7 +47,7 @@ void RenderHillshadeLayer::transition(const TransitionParameters& parameters) { void RenderHillshadeLayer::evaluate(const PropertyEvaluationParameters& parameters) { evaluated = unevaluated.evaluate(parameters); - passes = (evaluated.get<style::HillshadeExaggeration >() > 0) + passes = (evaluated.hillshadeExaggeration > 0) ? (RenderPass::Translucent | RenderPass::Pass3D) : RenderPass::None; } @@ -71,25 +71,25 @@ void RenderHillshadeLayer::render(PaintParameters& parameters, RenderSource* src const UnwrappedTileID& id) { auto& programInstance = parameters.programs.hillshade; - const HillshadeProgram::PaintPropertyBinders paintAttributeData{ evaluated, 0 }; + static const NoProperties::Binders binders; const auto allUniformValues = programInstance.computeAllUniformValues( HillshadeProgram::UniformValues { uniforms::u_matrix::Value{ matrix }, uniforms::u_image::Value{ 0 }, - uniforms::u_highlight::Value{ evaluated.get<HillshadeHighlightColor>() }, - uniforms::u_shadow::Value{ evaluated.get<HillshadeShadowColor>() }, - uniforms::u_accent::Value{ evaluated.get<HillshadeAccentColor>() }, + uniforms::u_highlight::Value{ evaluated.hillshadeHighlightColor }, + uniforms::u_shadow::Value{ evaluated.hillshadeShadowColor }, + uniforms::u_accent::Value{ evaluated.hillshadeAccentColor }, uniforms::u_light::Value{ getLight(parameters) }, uniforms::u_latrange::Value{ getLatRange(id) }, }, - paintAttributeData, + binders, evaluated, parameters.state.getZoom() ); const auto allAttributeBindings = programInstance.computeAllAttributeBindings( vertexBuffer, - paintAttributeData, + binders, evaluated ); @@ -130,9 +130,10 @@ void RenderHillshadeLayer::render(PaintParameters& parameters, RenderSource* src view.bind(); parameters.context.bindTexture(*bucket.dem, 0, gl::TextureFilter::Nearest, gl::TextureMipMap::No, gl::TextureWrap::Clamp, gl::TextureWrap::Clamp); - const Properties<>::PossiblyEvaluated properties; - const HillshadePrepareProgram::PaintPropertyBinders paintAttributeData{ properties, 0 }; - + + static const NoProperties::PossiblyEvaluated properties; + static const NoProperties::Binders binders; + auto& programInstance = parameters.programs.hillshadePrepare; const auto allUniformValues = programInstance.computeAllUniformValues( @@ -143,13 +144,13 @@ void RenderHillshadeLayer::render(PaintParameters& parameters, RenderSource* src uniforms::u_maxzoom::Value{ float(maxzoom) }, uniforms::u_image::Value{ 0 } }, - paintAttributeData, + binders, properties, parameters.state.getZoom() ); const auto allAttributeBindings = programInstance.computeAllAttributeBindings( parameters.staticData.rasterVertexBuffer, - paintAttributeData, + binders, properties ); @@ -189,8 +190,6 @@ void RenderHillshadeLayer::render(PaintParameters& parameters, RenderSource* src tile.id); } } - - } } diff --git a/src/mbgl/renderer/layers/render_line_layer.cpp b/src/mbgl/renderer/layers/render_line_layer.cpp index 4b6ea35e6..1c5e72609 100644 --- a/src/mbgl/renderer/layers/render_line_layer.cpp +++ b/src/mbgl/renderer/layers/render_line_layer.cpp @@ -34,17 +34,18 @@ void RenderLineLayer::transition(const TransitionParameters& parameters) { } void RenderLineLayer::evaluate(const PropertyEvaluationParameters& parameters) { - style::Properties<LineFloorwidth>::Unevaluated extra(unevaluated.get<style::LineWidth>()); - - auto dashArrayParams = parameters; - dashArrayParams.useIntegerZoom = true; - - evaluated = RenderLinePaintProperties::PossiblyEvaluated( - unevaluated.evaluate(parameters).concat(extra.evaluate(dashArrayParams))); - - passes = (evaluated.get<style::LineOpacity>().constantOr(1.0) > 0 - && evaluated.get<style::LineColor>().constantOr(Color::black()).a > 0 - && evaluated.get<style::LineWidth>().constantOr(1.0) > 0) +// style::Properties<LineFloorwidth>::Unevaluated extra(unevaluated.lineWidth); +// +// auto dashArrayParams = parameters; +// dashArrayParams.useIntegerZoom = true; +// +// evaluated = RenderLinePaintProperties::PossiblyEvaluated( +// unevaluated.evaluate(parameters).concat(extra.evaluate(dashArrayParams))); + evaluated = unevaluated.evaluate(parameters); + + passes = (evaluated.lineOpacity.constantOr(1.0) > 0 + && evaluated.lineColor.constantOr(Color::black()).a > 0 + && evaluated.lineWidth.constantOr(1.0) > 0) ? RenderPass::Translucent : RenderPass::None; } @@ -97,11 +98,11 @@ void RenderLineLayer::render(PaintParameters& parameters, RenderSource*) { ); }; - if (!evaluated.get<LineDasharray>().from.empty()) { - const LinePatternCap cap = bucket.layout.get<LineCap>() == LineCapType::Round + if (!evaluated.lineDasharray.from.empty()) { + const LinePatternCap cap = bucket.layout.lineCap == LineCapType::Round ? LinePatternCap::Round : LinePatternCap::Square; - LinePatternPos posA = parameters.lineAtlas.getDashPosition(evaluated.get<LineDasharray>().from, cap); - LinePatternPos posB = parameters.lineAtlas.getDashPosition(evaluated.get<LineDasharray>().to, cap); + LinePatternPos posA = parameters.lineAtlas.getDashPosition(evaluated.lineDasharray.from, cap); + LinePatternPos posB = parameters.lineAtlas.getDashPosition(evaluated.lineDasharray.to, cap); parameters.lineAtlas.bind(parameters.context, 0); @@ -116,9 +117,9 @@ void RenderLineLayer::render(PaintParameters& parameters, RenderSource*) { posB, parameters.lineAtlas.getSize().width)); - } else if (!evaluated.get<LinePattern>().from.empty()) { - optional<ImagePosition> posA = parameters.imageManager.getPattern(evaluated.get<LinePattern>().from); - optional<ImagePosition> posB = parameters.imageManager.getPattern(evaluated.get<LinePattern>().to); + } else if (!evaluated.linePattern.from.empty()) { + optional<ImagePosition> posA = parameters.imageManager.getPattern(evaluated.linePattern.from); + optional<ImagePosition> posB = parameters.imageManager.getPattern(evaluated.linePattern.to); if (!posA || !posB) return; @@ -187,13 +188,13 @@ bool RenderLineLayer::queryIntersectsFeature( // Translate query geometry auto translatedQueryGeometry = FeatureIndex::translateQueryGeometry( queryGeometry, - evaluated.get<style::LineTranslate>(), - evaluated.get<style::LineTranslateAnchor>(), + evaluated.lineTranslate, + evaluated.lineTranslateAnchor, transformState.getAngle(), pixelsToTileUnits); // Evaluate function - auto offset = evaluated.get<style::LineOffset>() + auto offset = evaluated.lineOffset .evaluate(feature, zoom, style::LineOffset::defaultValue()) * pixelsToTileUnits; // Apply offset to geometry @@ -208,9 +209,9 @@ bool RenderLineLayer::queryIntersectsFeature( } float RenderLineLayer::getLineWidth(const GeometryTileFeature& feature, const float zoom) const { - float lineWidth = evaluated.get<style::LineWidth>() + float lineWidth = evaluated.lineWidth .evaluate(feature, zoom, style::LineWidth::defaultValue()); - float gapWidth = evaluated.get<style::LineGapWidth>() + float gapWidth = evaluated.lineGapWidth .evaluate(feature, zoom, style::LineGapWidth::defaultValue()); if (gapWidth) { return gapWidth + 2 * lineWidth; diff --git a/src/mbgl/renderer/layers/render_line_layer.hpp b/src/mbgl/renderer/layers/render_line_layer.hpp index 5d5d79c04..1f47d3984 100644 --- a/src/mbgl/renderer/layers/render_line_layer.hpp +++ b/src/mbgl/renderer/layers/render_line_layer.hpp @@ -11,9 +11,10 @@ struct LineFloorwidth : style::DataDrivenPaintProperty<float, attributes::a_floo static float defaultValue() { return 1; } }; -class RenderLinePaintProperties : public style::ConcatenateProperties< - style::LinePaintProperties::PropertyTypes, - TypeList<LineFloorwidth>>::Type {}; +//class RenderLinePaintProperties : public style::ConcatenateProperties< +// style::LinePaintProperties::PropertyTypes, +// TypeList<LineFloorwidth>>::Type {}; +using RenderLinePaintProperties = style::LinePaintProperties; class RenderLineLayer: public RenderLayer { public: diff --git a/src/mbgl/renderer/layers/render_raster_layer.cpp b/src/mbgl/renderer/layers/render_raster_layer.cpp index e2524697b..62a1735b4 100644 --- a/src/mbgl/renderer/layers/render_raster_layer.cpp +++ b/src/mbgl/renderer/layers/render_raster_layer.cpp @@ -34,7 +34,7 @@ void RenderRasterLayer::transition(const TransitionParameters& parameters) { void RenderRasterLayer::evaluate(const PropertyEvaluationParameters& parameters) { evaluated = unevaluated.evaluate(parameters); - passes = evaluated.get<style::RasterOpacity>() > 0 ? RenderPass::Translucent : RenderPass::None; + passes = evaluated.rasterOpacity > 0 ? RenderPass::Translucent : RenderPass::None; } bool RenderRasterLayer::hasTransition() const { @@ -73,7 +73,7 @@ void RenderRasterLayer::render(PaintParameters& parameters, RenderSource* source if (parameters.pass != RenderPass::Translucent) return; - RasterProgram::PaintPropertyBinders paintAttributeData{ evaluated, 0 }; + static const NoProperties::Binders binders; auto draw = [&] (const mat4& matrix, const auto& vertexBuffer, @@ -86,24 +86,24 @@ void RenderRasterLayer::render(PaintParameters& parameters, RenderSource* source uniforms::u_matrix::Value{ matrix }, uniforms::u_image0::Value{ 0 }, uniforms::u_image1::Value{ 1 }, - uniforms::u_opacity::Value{ evaluated.get<RasterOpacity>() }, + uniforms::u_opacity::Value{ evaluated.rasterOpacity }, uniforms::u_fade_t::Value{ 1 }, - uniforms::u_brightness_low::Value{ evaluated.get<RasterBrightnessMin>() }, - uniforms::u_brightness_high::Value{ evaluated.get<RasterBrightnessMax>() }, - uniforms::u_saturation_factor::Value{ saturationFactor(evaluated.get<RasterSaturation>()) }, - uniforms::u_contrast_factor::Value{ contrastFactor(evaluated.get<RasterContrast>()) }, - uniforms::u_spin_weights::Value{ spinWeights(evaluated.get<RasterHueRotate>()) }, + uniforms::u_brightness_low::Value{ evaluated.rasterBrightnessMin }, + uniforms::u_brightness_high::Value{ evaluated.rasterBrightnessMax }, + uniforms::u_saturation_factor::Value{ saturationFactor(evaluated.rasterSaturation) }, + uniforms::u_contrast_factor::Value{ contrastFactor(evaluated.rasterContrast) }, + uniforms::u_spin_weights::Value{ spinWeights(evaluated.rasterHueRotate) }, uniforms::u_buffer_scale::Value{ 1.0f }, uniforms::u_scale_parent::Value{ 1.0f }, uniforms::u_tl_parent::Value{ std::array<float, 2> {{ 0.0f, 0.0f }} }, }, - paintAttributeData, + binders, evaluated, parameters.state.getZoom() ); const auto allAttributeBindings = programInstance.computeAllAttributeBindings( vertexBuffer, - paintAttributeData, + binders, evaluated ); @@ -123,7 +123,7 @@ void RenderRasterLayer::render(PaintParameters& parameters, RenderSource* source ); }; - const gl::TextureFilter filter = evaluated.get<RasterResampling>() == RasterResamplingType::Nearest ? gl::TextureFilter::Nearest : gl::TextureFilter::Linear; + const gl::TextureFilter filter = evaluated.rasterResampling == RasterResamplingType::Nearest ? gl::TextureFilter::Nearest : gl::TextureFilter::Linear; if (RenderImageSource* imageSource = source->as<RenderImageSource>()) { if (imageSource->isEnabled() && imageSource->isLoaded() && !imageSource->bucket->needsUpload()) { diff --git a/src/mbgl/renderer/layers/render_symbol_layer.cpp b/src/mbgl/renderer/layers/render_symbol_layer.cpp index f9e4e7c04..12c5ba43b 100644 --- a/src/mbgl/renderer/layers/render_symbol_layer.cpp +++ b/src/mbgl/renderer/layers/render_symbol_layer.cpp @@ -55,13 +55,13 @@ void RenderSymbolLayer::transition(const TransitionParameters& parameters) { void RenderSymbolLayer::evaluate(const PropertyEvaluationParameters& parameters) { evaluated = unevaluated.evaluate(parameters); - auto hasIconOpacity = evaluated.get<style::IconColor>().constantOr(Color::black()).a > 0 || - evaluated.get<style::IconHaloColor>().constantOr(Color::black()).a > 0; - auto hasTextOpacity = evaluated.get<style::TextColor>().constantOr(Color::black()).a > 0 || - evaluated.get<style::TextHaloColor>().constantOr(Color::black()).a > 0; + auto hasIconOpacity = evaluated.iconColor.constantOr(Color::black()).a > 0 || + evaluated.iconHaloColor.constantOr(Color::black()).a > 0; + auto hasTextOpacity = evaluated.textColor.constantOr(Color::black()).a > 0 || + evaluated.textHaloColor.constantOr(Color::black()).a > 0; - passes = ((evaluated.get<style::IconOpacity>().constantOr(1) > 0 && hasIconOpacity && iconSize > 0) - || (evaluated.get<style::TextOpacity>().constantOr(1) > 0 && hasTextOpacity && textSize > 0)) + passes = ((evaluated.iconOpacity.constantOr(1) > 0 && hasIconOpacity && iconSize > 0) + || (evaluated.textOpacity.constantOr(1) > 0 && hasTextOpacity && textSize > 0)) ? RenderPass::Translucent : RenderPass::None; } @@ -133,8 +133,8 @@ void RenderSymbolLayer::render(PaintParameters& parameters, RenderSource*) { auto values = iconPropertyValues(layout); auto paintPropertyValues = iconPaintProperties(); - const bool alongLine = layout.get<SymbolPlacement>() != SymbolPlacementType::Point && - layout.get<IconRotationAlignment>() == AlignmentType::Map; + const bool alongLine = layout.symbolPlacement != SymbolPlacementType::Point && + layout.iconRotationAlignment == AlignmentType::Map; if (alongLine) { reprojectLineLabels(bucket.icon.dynamicVertices, @@ -148,7 +148,7 @@ void RenderSymbolLayer::render(PaintParameters& parameters, RenderSource*) { parameters.context.updateVertexBuffer(*bucket.icon.dynamicVertexBuffer, std::move(bucket.icon.dynamicVertices)); } - const bool iconScaled = layout.get<IconSize>().constantOr(1.0) != 1.0 || bucket.iconsNeedLinear; + const bool iconScaled = layout.iconSize.constantOr(1.0) != 1.0 || bucket.iconsNeedLinear; const bool iconTransformed = values.rotationAlignment == AlignmentType::Map || parameters.state.getPitch() != 0; parameters.context.bindTexture(*geometryTile.iconAtlasTexture, 0, @@ -194,8 +194,8 @@ void RenderSymbolLayer::render(PaintParameters& parameters, RenderSource*) { auto values = textPropertyValues(layout); auto paintPropertyValues = textPaintProperties(); - const bool alongLine = layout.get<SymbolPlacement>() != SymbolPlacementType::Point && - layout.get<TextRotationAlignment>() == AlignmentType::Map; + const bool alongLine = layout.symbolPlacement != SymbolPlacementType::Point && + layout.textRotationAlignment == AlignmentType::Map; if (alongLine) { reprojectLineLabels(bucket.text.dynamicVertices, @@ -233,9 +233,6 @@ void RenderSymbolLayer::render(PaintParameters& parameters, RenderSource*) { } if (bucket.hasCollisionBoxData()) { - static const style::Properties<>::PossiblyEvaluated properties {}; - static const CollisionBoxProgram::PaintPropertyBinders paintAttributeData(properties, 0); - auto pixelRatio = tile.id.pixelsToTileUnits(1, parameters.state.getZoom()); const float scale = std::pow(2, parameters.state.getZoom() - tile.tile.id.overscaledZ); std::array<float,2> extrudeScale = @@ -259,16 +256,10 @@ void RenderSymbolLayer::render(PaintParameters& parameters, RenderSource*) { *bucket.collisionBox.dynamicVertexBuffer, *bucket.collisionBox.indexBuffer, bucket.collisionBox.segments, - paintAttributeData, - properties, - parameters.state.getZoom(), getID() ); } if (bucket.hasCollisionCircleData()) { - static const style::Properties<>::PossiblyEvaluated properties {}; - static const CollisionBoxProgram::PaintPropertyBinders paintAttributeData(properties, 0); - auto pixelRatio = tile.id.pixelsToTileUnits(1, parameters.state.getZoom()); const float scale = std::pow(2, parameters.state.getZoom() - tile.tile.id.overscaledZ); std::array<float,2> extrudeScale = @@ -294,9 +285,6 @@ void RenderSymbolLayer::render(PaintParameters& parameters, RenderSource*) { *bucket.collisionCircle.dynamicVertexBuffer, *bucket.collisionCircle.indexBuffer, bucket.collisionCircle.segments, - paintAttributeData, - properties, - parameters.state.getZoom(), getID() ); @@ -306,52 +294,52 @@ void RenderSymbolLayer::render(PaintParameters& parameters, RenderSource*) { style::IconPaintProperties::PossiblyEvaluated RenderSymbolLayer::iconPaintProperties() const { return style::IconPaintProperties::PossiblyEvaluated { - evaluated.get<style::IconOpacity>(), - evaluated.get<style::IconColor>(), - evaluated.get<style::IconHaloColor>(), - evaluated.get<style::IconHaloWidth>(), - evaluated.get<style::IconHaloBlur>(), - evaluated.get<style::IconTranslate>(), - evaluated.get<style::IconTranslateAnchor>() + evaluated.iconOpacity, + evaluated.iconColor, + evaluated.iconHaloColor, + evaluated.iconHaloWidth, + evaluated.iconHaloBlur, + evaluated.iconTranslate, + evaluated.iconTranslateAnchor }; } style::TextPaintProperties::PossiblyEvaluated RenderSymbolLayer::textPaintProperties() const { return style::TextPaintProperties::PossiblyEvaluated { - evaluated.get<style::TextOpacity>(), - evaluated.get<style::TextColor>(), - evaluated.get<style::TextHaloColor>(), - evaluated.get<style::TextHaloWidth>(), - evaluated.get<style::TextHaloBlur>(), - evaluated.get<style::TextTranslate>(), - evaluated.get<style::TextTranslateAnchor>() + evaluated.textOpacity, + evaluated.textColor, + evaluated.textHaloColor, + evaluated.textHaloWidth, + evaluated.textHaloBlur, + evaluated.textTranslate, + evaluated.textTranslateAnchor }; } style::SymbolPropertyValues RenderSymbolLayer::iconPropertyValues(const style::SymbolLayoutProperties::PossiblyEvaluated& layout_) const { return style::SymbolPropertyValues { - layout_.get<style::IconPitchAlignment>(), - layout_.get<style::IconRotationAlignment>(), - layout_.get<style::IconKeepUpright>(), - evaluated.get<style::IconTranslate>(), - evaluated.get<style::IconTranslateAnchor>(), - evaluated.get<style::IconHaloColor>().constantOr(Color::black()).a > 0 && - evaluated.get<style::IconHaloWidth>().constantOr(1), - evaluated.get<style::IconColor>().constantOr(Color::black()).a > 0 + layout_.iconPitchAlignment, + layout_.iconRotationAlignment, + layout_.iconKeepUpright, + evaluated.iconTranslate, + evaluated.iconTranslateAnchor, + evaluated.iconHaloColor.constantOr(Color::black()).a > 0 && + evaluated.iconHaloWidth.constantOr(1), + evaluated.iconColor.constantOr(Color::black()).a > 0 }; } style::SymbolPropertyValues RenderSymbolLayer::textPropertyValues(const style::SymbolLayoutProperties::PossiblyEvaluated& layout_) const { return style::SymbolPropertyValues { - layout_.get<style::TextPitchAlignment>(), - layout_.get<style::TextRotationAlignment>(), - layout_.get<style::TextKeepUpright>(), - evaluated.get<style::TextTranslate>(), - evaluated.get<style::TextTranslateAnchor>(), - evaluated.get<style::TextHaloColor>().constantOr(Color::black()).a > 0 && - evaluated.get<style::TextHaloWidth>().constantOr(1), - evaluated.get<style::TextColor>().constantOr(Color::black()).a > 0 + layout_.textPitchAlignment, + layout_.textRotationAlignment, + layout_.textKeepUpright, + evaluated.textTranslate, + evaluated.textTranslateAnchor, + evaluated.textHaloColor.constantOr(Color::black()).a > 0 && + evaluated.textHaloWidth.constantOr(1), + evaluated.textColor.constantOr(Color::black()).a > 0 }; } diff --git a/src/mbgl/renderer/layers/render_symbol_layer.hpp b/src/mbgl/renderer/layers/render_symbol_layer.hpp index 5b73b3029..f977e8130 100644 --- a/src/mbgl/renderer/layers/render_symbol_layer.hpp +++ b/src/mbgl/renderer/layers/render_symbol_layer.hpp @@ -10,29 +10,6 @@ namespace mbgl { namespace style { -// {icon,text}-specific paint-property packs for use in the symbol Programs. -// Since each program deals either with icons or text, using a smaller property set -// lets us avoid unnecessarily binding attributes for properties the program wouldn't use. -class IconPaintProperties : public Properties< - IconOpacity, - IconColor, - IconHaloColor, - IconHaloWidth, - IconHaloBlur, - IconTranslate, - IconTranslateAnchor -> {}; - -class TextPaintProperties : public Properties< - TextOpacity, - TextColor, - TextHaloColor, - TextHaloWidth, - TextHaloBlur, - TextTranslate, - TextTranslateAnchor -> {}; - // Repackaging evaluated values from SymbolLayoutProperties + SymbolPaintProperties // for genericity over icons vs. text. class SymbolPropertyValues { diff --git a/src/mbgl/renderer/paint_property_binder.hpp b/src/mbgl/renderer/paint_property_binder.hpp index aade672ae..7773e7931 100644 --- a/src/mbgl/renderer/paint_property_binder.hpp +++ b/src/mbgl/renderer/paint_property_binder.hpp @@ -273,100 +273,4 @@ struct InterpolationUniform : gl::UniformScalar<InterpolationUniform<Attr>, floa } }; -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>..., typename Ps::Uniform...>; - using UniformValues = typename Uniforms::Values; - - template <class EvaluatedProperties> - UniformValues uniformValues(float currentZoom, const EvaluatedProperties& currentProperties) 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) - }..., - typename Ps::Uniform::Value { - binders.template get<Ps>()->uniformValue(currentProperties.template get<Ps>()) - }... - }; - } - - template <class P> - const auto& statistics() const { - return binders.template get<P>()->statistics; - } - - - using Bitset = std::bitset<sizeof...(Ps)>; - - template <class EvaluatedProperties> - static Bitset constants(const EvaluatedProperties& currentProperties) { - Bitset result; - util::ignore({ - result.set(TypeIndex<Ps, Ps...>::value, - currentProperties.template get<Ps>().isConstant())... - }); - return result; - } - - template <class EvaluatedProperties> - static std::vector<std::string> defines(const EvaluatedProperties& currentProperties) { - std::vector<std::string> result; - util::ignore({ - (result.push_back(currentProperties.template get<Ps>().isConstant() - ? std::string("#define HAS_UNIFORM_") + Ps::Uniform::name() - : std::string()), 0)... - }); - return result; - } - -private: - Binders binders; -}; - } // namespace mbgl diff --git a/src/mbgl/renderer/render_light.hpp b/src/mbgl/renderer/render_light.hpp index f13f92531..03865d236 100644 --- a/src/mbgl/renderer/render_light.hpp +++ b/src/mbgl/renderer/render_light.hpp @@ -9,7 +9,7 @@ class TransitionParameters; class PropertyEvaluationParameters; using TransitioningLight = style::LightProperties::Unevaluated; -using EvaluatedLight = style::LightProperties::PossiblyEvaluated; +using EvaluatedLight = style::LightProperties::Evaluated; class RenderLight { public: diff --git a/src/mbgl/renderer/render_tile.cpp b/src/mbgl/renderer/render_tile.cpp index 64790938e..cf7156c7e 100644 --- a/src/mbgl/renderer/render_tile.cpp +++ b/src/mbgl/renderer/render_tile.cpp @@ -71,8 +71,8 @@ void RenderTile::finishRender(PaintParameters& parameters) { if (!used || parameters.debugOptions == MapDebugOptions::NoDebug) return; - static const style::Properties<>::PossiblyEvaluated properties {}; - static const DebugProgram::PaintPropertyBinders paintAttributeData(properties, 0); + static const NoProperties::PossiblyEvaluated properties; + static const NoProperties::Binders paintAttributeData; auto& program = parameters.programs.debug; diff --git a/src/mbgl/renderer/renderer_impl.cpp b/src/mbgl/renderer/renderer_impl.cpp index fea27403c..4af07551b 100644 --- a/src/mbgl/renderer/renderer_impl.cpp +++ b/src/mbgl/renderer/renderer_impl.cpp @@ -306,9 +306,9 @@ void Renderer::Impl::render(const UpdateParameters& updateParameters) { const BackgroundPaintProperties::PossiblyEvaluated& paint = background->evaluated; if (parameters.contextMode == GLContextMode::Unique && layerImpl.get() == layerImpls->at(0).get() - && paint.get<BackgroundPattern>().from.empty()) { + && paint.backgroundPattern.from.empty()) { // This is a solid background. We can use glClear(). - backgroundColor = paint.get<BackgroundColor>() * paint.get<BackgroundOpacity>(); + backgroundColor = paint.backgroundColor * paint.backgroundOpacity; } else { // This is a textured background, or not the bottommost layer. We need to render it with a quad. order.emplace_back(RenderItem { *layer, nullptr }); @@ -481,8 +481,8 @@ void Renderer::Impl::render(const UpdateParameters& updateParameters) { { MBGL_DEBUG_GROUP(parameters.context, "clipping masks"); - static const Properties<>::PossiblyEvaluated properties {}; - static const ClippingMaskProgram::PaintPropertyBinders paintAttributeData(properties, 0); + static const NoProperties::PossiblyEvaluated properties; + static const NoProperties::Binders binders; for (const auto& clipID : parameters.clipIDGenerator.getClipIDs()) { auto& program = parameters.staticData.programs.clippingMask; @@ -506,13 +506,13 @@ void Renderer::Impl::render(const UpdateParameters& updateParameters) { ClippingMaskProgram::UniformValues { uniforms::u_matrix::Value{ parameters.matrixForTile(clipID.first) }, }, - paintAttributeData, + binders, properties, parameters.state.getZoom() ), program.computeAllAttributeBindings( parameters.staticData.tileVertexBuffer, - paintAttributeData, + binders, properties ), "clipping" diff --git a/src/mbgl/renderer/sources/render_image_source.cpp b/src/mbgl/renderer/sources/render_image_source.cpp index 2ce046a7a..eaa02f539 100644 --- a/src/mbgl/renderer/sources/render_image_source.cpp +++ b/src/mbgl/renderer/sources/render_image_source.cpp @@ -55,8 +55,8 @@ void RenderImageSource::finishRender(PaintParameters& parameters) { return; } - static const style::Properties<>::PossiblyEvaluated properties {}; - static const DebugProgram::PaintPropertyBinders paintAttributeData(properties, 0); + static const NoProperties::PossiblyEvaluated properties; + static const NoProperties::Binders binders; auto& programInstance = parameters.programs.debug; @@ -74,13 +74,13 @@ void RenderImageSource::finishRender(PaintParameters& parameters) { uniforms::u_matrix::Value{ matrix }, uniforms::u_color::Value{ Color::red() } }, - paintAttributeData, + binders, properties, parameters.state.getZoom() ), programInstance.computeAllAttributeBindings( parameters.staticData.tileVertexBuffer, - paintAttributeData, + binders, properties ), "image" diff --git a/src/mbgl/style/layers/background_layer.cpp b/src/mbgl/style/layers/background_layer.cpp index e47b41daa..902f8f481 100644 --- a/src/mbgl/style/layers/background_layer.cpp +++ b/src/mbgl/style/layers/background_layer.cpp @@ -80,26 +80,26 @@ PropertyValue<Color> BackgroundLayer::getDefaultBackgroundColor() { } PropertyValue<Color> BackgroundLayer::getBackgroundColor() const { - return impl().paint.template get<BackgroundColor>().value; + return impl().paint.backgroundColor.value; } void BackgroundLayer::setBackgroundColor(PropertyValue<Color> value) { if (value == getBackgroundColor()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<BackgroundColor>().value = value; + impl_->paint.backgroundColor.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void BackgroundLayer::setBackgroundColorTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<BackgroundColor>().options = options; + impl_->paint.backgroundColor.options = options; baseImpl = std::move(impl_); } TransitionOptions BackgroundLayer::getBackgroundColorTransition() const { - return impl().paint.template get<BackgroundColor>().options; + return impl().paint.backgroundColor.options; } PropertyValue<std::string> BackgroundLayer::getDefaultBackgroundPattern() { @@ -107,26 +107,26 @@ PropertyValue<std::string> BackgroundLayer::getDefaultBackgroundPattern() { } PropertyValue<std::string> BackgroundLayer::getBackgroundPattern() const { - return impl().paint.template get<BackgroundPattern>().value; + return impl().paint.backgroundPattern.value; } void BackgroundLayer::setBackgroundPattern(PropertyValue<std::string> value) { if (value == getBackgroundPattern()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<BackgroundPattern>().value = value; + impl_->paint.backgroundPattern.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void BackgroundLayer::setBackgroundPatternTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<BackgroundPattern>().options = options; + impl_->paint.backgroundPattern.options = options; baseImpl = std::move(impl_); } TransitionOptions BackgroundLayer::getBackgroundPatternTransition() const { - return impl().paint.template get<BackgroundPattern>().options; + return impl().paint.backgroundPattern.options; } PropertyValue<float> BackgroundLayer::getDefaultBackgroundOpacity() { @@ -134,26 +134,26 @@ PropertyValue<float> BackgroundLayer::getDefaultBackgroundOpacity() { } PropertyValue<float> BackgroundLayer::getBackgroundOpacity() const { - return impl().paint.template get<BackgroundOpacity>().value; + return impl().paint.backgroundOpacity.value; } void BackgroundLayer::setBackgroundOpacity(PropertyValue<float> value) { if (value == getBackgroundOpacity()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<BackgroundOpacity>().value = value; + impl_->paint.backgroundOpacity.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void BackgroundLayer::setBackgroundOpacityTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<BackgroundOpacity>().options = options; + impl_->paint.backgroundOpacity.options = options; baseImpl = std::move(impl_); } TransitionOptions BackgroundLayer::getBackgroundOpacityTransition() const { - return impl().paint.template get<BackgroundOpacity>().options; + return impl().paint.backgroundOpacity.options; } using namespace conversion; diff --git a/src/mbgl/style/layers/background_layer_properties.cpp b/src/mbgl/style/layers/background_layer_properties.cpp index ba3e63897..b6835f15c 100644 --- a/src/mbgl/style/layers/background_layer_properties.cpp +++ b/src/mbgl/style/layers/background_layer_properties.cpp @@ -5,5 +5,47 @@ namespace mbgl { namespace style { +BackgroundPaintProperties::Unevaluated BackgroundPaintProperties::Transitionable::transitioned(const TransitionParameters& parameters, Unevaluated&& prior) const { + return Unevaluated { + backgroundColor.transition(parameters, std::move(prior.backgroundColor)), + backgroundPattern.transition(parameters, std::move(prior.backgroundPattern)), + backgroundOpacity.transition(parameters, std::move(prior.backgroundOpacity)), + }; +} + +BackgroundPaintProperties::Unevaluated BackgroundPaintProperties::Transitionable::untransitioned() const { + return Unevaluated { + Transitioning<PropertyValue<Color>>(backgroundColor.value), + Transitioning<PropertyValue<std::string>>(backgroundPattern.value), + Transitioning<PropertyValue<float>>(backgroundOpacity.value), + }; +} + +bool BackgroundPaintProperties::Transitionable::hasDataDrivenPropertyDifference(const Transitionable& other) const { + return false + || backgroundColor.value.hasDataDrivenPropertyDifference(other.backgroundColor.value) + || backgroundPattern.value.hasDataDrivenPropertyDifference(other.backgroundPattern.value) + || backgroundOpacity.value.hasDataDrivenPropertyDifference(other.backgroundOpacity.value) + ; +} + +bool BackgroundPaintProperties::Unevaluated::hasTransition() const { + return false + || backgroundColor.hasTransition() + || backgroundPattern.hasTransition() + || backgroundOpacity.hasTransition() + ; +} + +BackgroundPaintProperties::PossiblyEvaluated BackgroundPaintProperties::Unevaluated::evaluate(const PropertyEvaluationParameters& parameters) const { + return PossiblyEvaluated { + backgroundColor.evaluate(typename BackgroundColor::EvaluatorType(parameters, BackgroundColor::defaultValue()), parameters.now), + backgroundPattern.evaluate(typename BackgroundPattern::EvaluatorType(parameters, BackgroundPattern::defaultValue()), parameters.now), + backgroundOpacity.evaluate(typename BackgroundOpacity::EvaluatorType(parameters, BackgroundOpacity::defaultValue()), parameters.now), + }; +} + + + } // namespace style } // namespace mbgl diff --git a/src/mbgl/style/layers/background_layer_properties.hpp b/src/mbgl/style/layers/background_layer_properties.hpp index 3a61392fb..bd62ef0a5 100644 --- a/src/mbgl/style/layers/background_layer_properties.hpp +++ b/src/mbgl/style/layers/background_layer_properties.hpp @@ -24,11 +24,39 @@ struct BackgroundOpacity : PaintProperty<float> { static float defaultValue() { return 1; } }; -class BackgroundPaintProperties : public Properties< - BackgroundColor, - BackgroundPattern, - BackgroundOpacity -> {}; +class BackgroundPaintProperties { +public: + + class PossiblyEvaluated { + public: + Color backgroundColor; + Faded<std::string> backgroundPattern; + float backgroundOpacity; + }; + + class Unevaluated { + public: + style::Transitioning<PropertyValue<Color>> backgroundColor; + style::Transitioning<PropertyValue<std::string>> backgroundPattern; + style::Transitioning<PropertyValue<float>> backgroundOpacity; + + bool hasTransition() const; + PossiblyEvaluated evaluate(const PropertyEvaluationParameters&) const; + }; + + class Transitionable { + public: + style::Transitionable<PropertyValue<Color>> backgroundColor; + style::Transitionable<PropertyValue<std::string>> backgroundPattern; + style::Transitionable<PropertyValue<float>> backgroundOpacity; + + Unevaluated transitioned(const TransitionParameters&, Unevaluated&& prior) const; + Unevaluated untransitioned() const; + + bool hasDataDrivenPropertyDifference(const Transitionable& other) const; + }; +}; + } // namespace style } // namespace mbgl diff --git a/src/mbgl/style/layers/circle_layer.cpp b/src/mbgl/style/layers/circle_layer.cpp index 1dae77547..81a98cace 100644 --- a/src/mbgl/style/layers/circle_layer.cpp +++ b/src/mbgl/style/layers/circle_layer.cpp @@ -108,26 +108,26 @@ PropertyValue<float> CircleLayer::getDefaultCircleRadius() { } PropertyValue<float> CircleLayer::getCircleRadius() const { - return impl().paint.template get<CircleRadius>().value; + return impl().paint.circleRadius.value; } void CircleLayer::setCircleRadius(PropertyValue<float> value) { if (value == getCircleRadius()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<CircleRadius>().value = value; + impl_->paint.circleRadius.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void CircleLayer::setCircleRadiusTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<CircleRadius>().options = options; + impl_->paint.circleRadius.options = options; baseImpl = std::move(impl_); } TransitionOptions CircleLayer::getCircleRadiusTransition() const { - return impl().paint.template get<CircleRadius>().options; + return impl().paint.circleRadius.options; } PropertyValue<Color> CircleLayer::getDefaultCircleColor() { @@ -135,26 +135,26 @@ PropertyValue<Color> CircleLayer::getDefaultCircleColor() { } PropertyValue<Color> CircleLayer::getCircleColor() const { - return impl().paint.template get<CircleColor>().value; + return impl().paint.circleColor.value; } void CircleLayer::setCircleColor(PropertyValue<Color> value) { if (value == getCircleColor()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<CircleColor>().value = value; + impl_->paint.circleColor.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void CircleLayer::setCircleColorTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<CircleColor>().options = options; + impl_->paint.circleColor.options = options; baseImpl = std::move(impl_); } TransitionOptions CircleLayer::getCircleColorTransition() const { - return impl().paint.template get<CircleColor>().options; + return impl().paint.circleColor.options; } PropertyValue<float> CircleLayer::getDefaultCircleBlur() { @@ -162,26 +162,26 @@ PropertyValue<float> CircleLayer::getDefaultCircleBlur() { } PropertyValue<float> CircleLayer::getCircleBlur() const { - return impl().paint.template get<CircleBlur>().value; + return impl().paint.circleBlur.value; } void CircleLayer::setCircleBlur(PropertyValue<float> value) { if (value == getCircleBlur()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<CircleBlur>().value = value; + impl_->paint.circleBlur.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void CircleLayer::setCircleBlurTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<CircleBlur>().options = options; + impl_->paint.circleBlur.options = options; baseImpl = std::move(impl_); } TransitionOptions CircleLayer::getCircleBlurTransition() const { - return impl().paint.template get<CircleBlur>().options; + return impl().paint.circleBlur.options; } PropertyValue<float> CircleLayer::getDefaultCircleOpacity() { @@ -189,26 +189,26 @@ PropertyValue<float> CircleLayer::getDefaultCircleOpacity() { } PropertyValue<float> CircleLayer::getCircleOpacity() const { - return impl().paint.template get<CircleOpacity>().value; + return impl().paint.circleOpacity.value; } void CircleLayer::setCircleOpacity(PropertyValue<float> value) { if (value == getCircleOpacity()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<CircleOpacity>().value = value; + impl_->paint.circleOpacity.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void CircleLayer::setCircleOpacityTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<CircleOpacity>().options = options; + impl_->paint.circleOpacity.options = options; baseImpl = std::move(impl_); } TransitionOptions CircleLayer::getCircleOpacityTransition() const { - return impl().paint.template get<CircleOpacity>().options; + return impl().paint.circleOpacity.options; } PropertyValue<std::array<float, 2>> CircleLayer::getDefaultCircleTranslate() { @@ -216,26 +216,26 @@ PropertyValue<std::array<float, 2>> CircleLayer::getDefaultCircleTranslate() { } PropertyValue<std::array<float, 2>> CircleLayer::getCircleTranslate() const { - return impl().paint.template get<CircleTranslate>().value; + return impl().paint.circleTranslate.value; } void CircleLayer::setCircleTranslate(PropertyValue<std::array<float, 2>> value) { if (value == getCircleTranslate()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<CircleTranslate>().value = value; + impl_->paint.circleTranslate.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void CircleLayer::setCircleTranslateTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<CircleTranslate>().options = options; + impl_->paint.circleTranslate.options = options; baseImpl = std::move(impl_); } TransitionOptions CircleLayer::getCircleTranslateTransition() const { - return impl().paint.template get<CircleTranslate>().options; + return impl().paint.circleTranslate.options; } PropertyValue<TranslateAnchorType> CircleLayer::getDefaultCircleTranslateAnchor() { @@ -243,26 +243,26 @@ PropertyValue<TranslateAnchorType> CircleLayer::getDefaultCircleTranslateAnchor( } PropertyValue<TranslateAnchorType> CircleLayer::getCircleTranslateAnchor() const { - return impl().paint.template get<CircleTranslateAnchor>().value; + return impl().paint.circleTranslateAnchor.value; } void CircleLayer::setCircleTranslateAnchor(PropertyValue<TranslateAnchorType> value) { if (value == getCircleTranslateAnchor()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<CircleTranslateAnchor>().value = value; + impl_->paint.circleTranslateAnchor.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void CircleLayer::setCircleTranslateAnchorTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<CircleTranslateAnchor>().options = options; + impl_->paint.circleTranslateAnchor.options = options; baseImpl = std::move(impl_); } TransitionOptions CircleLayer::getCircleTranslateAnchorTransition() const { - return impl().paint.template get<CircleTranslateAnchor>().options; + return impl().paint.circleTranslateAnchor.options; } PropertyValue<CirclePitchScaleType> CircleLayer::getDefaultCirclePitchScale() { @@ -270,26 +270,26 @@ PropertyValue<CirclePitchScaleType> CircleLayer::getDefaultCirclePitchScale() { } PropertyValue<CirclePitchScaleType> CircleLayer::getCirclePitchScale() const { - return impl().paint.template get<CirclePitchScale>().value; + return impl().paint.circlePitchScale.value; } void CircleLayer::setCirclePitchScale(PropertyValue<CirclePitchScaleType> value) { if (value == getCirclePitchScale()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<CirclePitchScale>().value = value; + impl_->paint.circlePitchScale.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void CircleLayer::setCirclePitchScaleTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<CirclePitchScale>().options = options; + impl_->paint.circlePitchScale.options = options; baseImpl = std::move(impl_); } TransitionOptions CircleLayer::getCirclePitchScaleTransition() const { - return impl().paint.template get<CirclePitchScale>().options; + return impl().paint.circlePitchScale.options; } PropertyValue<AlignmentType> CircleLayer::getDefaultCirclePitchAlignment() { @@ -297,26 +297,26 @@ PropertyValue<AlignmentType> CircleLayer::getDefaultCirclePitchAlignment() { } PropertyValue<AlignmentType> CircleLayer::getCirclePitchAlignment() const { - return impl().paint.template get<CirclePitchAlignment>().value; + return impl().paint.circlePitchAlignment.value; } void CircleLayer::setCirclePitchAlignment(PropertyValue<AlignmentType> value) { if (value == getCirclePitchAlignment()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<CirclePitchAlignment>().value = value; + impl_->paint.circlePitchAlignment.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void CircleLayer::setCirclePitchAlignmentTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<CirclePitchAlignment>().options = options; + impl_->paint.circlePitchAlignment.options = options; baseImpl = std::move(impl_); } TransitionOptions CircleLayer::getCirclePitchAlignmentTransition() const { - return impl().paint.template get<CirclePitchAlignment>().options; + return impl().paint.circlePitchAlignment.options; } PropertyValue<float> CircleLayer::getDefaultCircleStrokeWidth() { @@ -324,26 +324,26 @@ PropertyValue<float> CircleLayer::getDefaultCircleStrokeWidth() { } PropertyValue<float> CircleLayer::getCircleStrokeWidth() const { - return impl().paint.template get<CircleStrokeWidth>().value; + return impl().paint.circleStrokeWidth.value; } void CircleLayer::setCircleStrokeWidth(PropertyValue<float> value) { if (value == getCircleStrokeWidth()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<CircleStrokeWidth>().value = value; + impl_->paint.circleStrokeWidth.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void CircleLayer::setCircleStrokeWidthTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<CircleStrokeWidth>().options = options; + impl_->paint.circleStrokeWidth.options = options; baseImpl = std::move(impl_); } TransitionOptions CircleLayer::getCircleStrokeWidthTransition() const { - return impl().paint.template get<CircleStrokeWidth>().options; + return impl().paint.circleStrokeWidth.options; } PropertyValue<Color> CircleLayer::getDefaultCircleStrokeColor() { @@ -351,26 +351,26 @@ PropertyValue<Color> CircleLayer::getDefaultCircleStrokeColor() { } PropertyValue<Color> CircleLayer::getCircleStrokeColor() const { - return impl().paint.template get<CircleStrokeColor>().value; + return impl().paint.circleStrokeColor.value; } void CircleLayer::setCircleStrokeColor(PropertyValue<Color> value) { if (value == getCircleStrokeColor()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<CircleStrokeColor>().value = value; + impl_->paint.circleStrokeColor.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void CircleLayer::setCircleStrokeColorTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<CircleStrokeColor>().options = options; + impl_->paint.circleStrokeColor.options = options; baseImpl = std::move(impl_); } TransitionOptions CircleLayer::getCircleStrokeColorTransition() const { - return impl().paint.template get<CircleStrokeColor>().options; + return impl().paint.circleStrokeColor.options; } PropertyValue<float> CircleLayer::getDefaultCircleStrokeOpacity() { @@ -378,26 +378,26 @@ PropertyValue<float> CircleLayer::getDefaultCircleStrokeOpacity() { } PropertyValue<float> CircleLayer::getCircleStrokeOpacity() const { - return impl().paint.template get<CircleStrokeOpacity>().value; + return impl().paint.circleStrokeOpacity.value; } void CircleLayer::setCircleStrokeOpacity(PropertyValue<float> value) { if (value == getCircleStrokeOpacity()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<CircleStrokeOpacity>().value = value; + impl_->paint.circleStrokeOpacity.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void CircleLayer::setCircleStrokeOpacityTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<CircleStrokeOpacity>().options = options; + impl_->paint.circleStrokeOpacity.options = options; baseImpl = std::move(impl_); } TransitionOptions CircleLayer::getCircleStrokeOpacityTransition() const { - return impl().paint.template get<CircleStrokeOpacity>().options; + return impl().paint.circleStrokeOpacity.options; } using namespace conversion; diff --git a/src/mbgl/style/layers/circle_layer_properties.cpp b/src/mbgl/style/layers/circle_layer_properties.cpp index af727fa36..c9e654e63 100644 --- a/src/mbgl/style/layers/circle_layer_properties.cpp +++ b/src/mbgl/style/layers/circle_layer_properties.cpp @@ -5,5 +5,215 @@ namespace mbgl { namespace style { +CirclePaintProperties::Unevaluated CirclePaintProperties::Transitionable::transitioned(const TransitionParameters& parameters, Unevaluated&& prior) const { + return Unevaluated { + circleRadius.transition(parameters, std::move(prior.circleRadius)), + circleColor.transition(parameters, std::move(prior.circleColor)), + circleBlur.transition(parameters, std::move(prior.circleBlur)), + circleOpacity.transition(parameters, std::move(prior.circleOpacity)), + circleTranslate.transition(parameters, std::move(prior.circleTranslate)), + circleTranslateAnchor.transition(parameters, std::move(prior.circleTranslateAnchor)), + circlePitchScale.transition(parameters, std::move(prior.circlePitchScale)), + circlePitchAlignment.transition(parameters, std::move(prior.circlePitchAlignment)), + circleStrokeWidth.transition(parameters, std::move(prior.circleStrokeWidth)), + circleStrokeColor.transition(parameters, std::move(prior.circleStrokeColor)), + circleStrokeOpacity.transition(parameters, std::move(prior.circleStrokeOpacity)), + }; +} + +CirclePaintProperties::Unevaluated CirclePaintProperties::Transitionable::untransitioned() const { + return Unevaluated { + Transitioning<PropertyValue<float>>(circleRadius.value), + Transitioning<PropertyValue<Color>>(circleColor.value), + Transitioning<PropertyValue<float>>(circleBlur.value), + Transitioning<PropertyValue<float>>(circleOpacity.value), + Transitioning<PropertyValue<std::array<float, 2>>>(circleTranslate.value), + Transitioning<PropertyValue<TranslateAnchorType>>(circleTranslateAnchor.value), + Transitioning<PropertyValue<CirclePitchScaleType>>(circlePitchScale.value), + Transitioning<PropertyValue<AlignmentType>>(circlePitchAlignment.value), + Transitioning<PropertyValue<float>>(circleStrokeWidth.value), + Transitioning<PropertyValue<Color>>(circleStrokeColor.value), + Transitioning<PropertyValue<float>>(circleStrokeOpacity.value), + }; +} + +bool CirclePaintProperties::Transitionable::hasDataDrivenPropertyDifference(const Transitionable& other) const { + return false + || circleRadius.value.hasDataDrivenPropertyDifference(other.circleRadius.value) + || circleColor.value.hasDataDrivenPropertyDifference(other.circleColor.value) + || circleBlur.value.hasDataDrivenPropertyDifference(other.circleBlur.value) + || circleOpacity.value.hasDataDrivenPropertyDifference(other.circleOpacity.value) + || circleTranslate.value.hasDataDrivenPropertyDifference(other.circleTranslate.value) + || circleTranslateAnchor.value.hasDataDrivenPropertyDifference(other.circleTranslateAnchor.value) + || circlePitchScale.value.hasDataDrivenPropertyDifference(other.circlePitchScale.value) + || circlePitchAlignment.value.hasDataDrivenPropertyDifference(other.circlePitchAlignment.value) + || circleStrokeWidth.value.hasDataDrivenPropertyDifference(other.circleStrokeWidth.value) + || circleStrokeColor.value.hasDataDrivenPropertyDifference(other.circleStrokeColor.value) + || circleStrokeOpacity.value.hasDataDrivenPropertyDifference(other.circleStrokeOpacity.value) + ; +} + +bool CirclePaintProperties::Unevaluated::hasTransition() const { + return false + || circleRadius.hasTransition() + || circleColor.hasTransition() + || circleBlur.hasTransition() + || circleOpacity.hasTransition() + || circleTranslate.hasTransition() + || circleTranslateAnchor.hasTransition() + || circlePitchScale.hasTransition() + || circlePitchAlignment.hasTransition() + || circleStrokeWidth.hasTransition() + || circleStrokeColor.hasTransition() + || circleStrokeOpacity.hasTransition() + ; +} + +CirclePaintProperties::PossiblyEvaluated CirclePaintProperties::Unevaluated::evaluate(const PropertyEvaluationParameters& parameters) const { + return PossiblyEvaluated { + circleRadius.evaluate(typename CircleRadius::EvaluatorType(parameters, CircleRadius::defaultValue()), parameters.now), + circleColor.evaluate(typename CircleColor::EvaluatorType(parameters, CircleColor::defaultValue()), parameters.now), + circleBlur.evaluate(typename CircleBlur::EvaluatorType(parameters, CircleBlur::defaultValue()), parameters.now), + circleOpacity.evaluate(typename CircleOpacity::EvaluatorType(parameters, CircleOpacity::defaultValue()), parameters.now), + circleTranslate.evaluate(typename CircleTranslate::EvaluatorType(parameters, CircleTranslate::defaultValue()), parameters.now), + circleTranslateAnchor.evaluate(typename CircleTranslateAnchor::EvaluatorType(parameters, CircleTranslateAnchor::defaultValue()), parameters.now), + circlePitchScale.evaluate(typename CirclePitchScale::EvaluatorType(parameters, CirclePitchScale::defaultValue()), parameters.now), + circlePitchAlignment.evaluate(typename CirclePitchAlignment::EvaluatorType(parameters, CirclePitchAlignment::defaultValue()), parameters.now), + circleStrokeWidth.evaluate(typename CircleStrokeWidth::EvaluatorType(parameters, CircleStrokeWidth::defaultValue()), parameters.now), + circleStrokeColor.evaluate(typename CircleStrokeColor::EvaluatorType(parameters, CircleStrokeColor::defaultValue()), parameters.now), + circleStrokeOpacity.evaluate(typename CircleStrokeOpacity::EvaluatorType(parameters, CircleStrokeOpacity::defaultValue()), parameters.now), + }; +} + +CirclePaintProperties::Binders CirclePaintProperties::PossiblyEvaluated::createBinders(float z) const { + return Binders { + PaintPropertyBinder<float, typename attributes::a_radius::Type>::create(circleRadius, z, CircleRadius::defaultValue()), + PaintPropertyBinder<Color, typename attributes::a_color::Type>::create(circleColor, z, CircleColor::defaultValue()), + PaintPropertyBinder<float, typename attributes::a_blur::Type>::create(circleBlur, z, CircleBlur::defaultValue()), + PaintPropertyBinder<float, typename attributes::a_opacity::Type>::create(circleOpacity, z, CircleOpacity::defaultValue()), + PaintPropertyBinder<float, typename attributes::a_stroke_width::Type>::create(circleStrokeWidth, z, CircleStrokeWidth::defaultValue()), + PaintPropertyBinder<Color, typename attributes::a_stroke_color::Type>::create(circleStrokeColor, z, CircleStrokeColor::defaultValue()), + PaintPropertyBinder<float, typename attributes::a_stroke_opacity::Type>::create(circleStrokeOpacity, z, CircleStrokeOpacity::defaultValue()), + }; +} + +std::bitset<8> CirclePaintProperties::PossiblyEvaluated::constants() const { + std::bitset<8> result; + result.set(0, circleRadius.isConstant()); + result.set(1, circleColor.isConstant()); + result.set(2, circleBlur.isConstant()); + result.set(3, circleOpacity.isConstant()); + result.set(4, circleStrokeWidth.isConstant()); + result.set(5, circleStrokeColor.isConstant()); + result.set(6, circleStrokeOpacity.isConstant()); + return result; +} + +std::vector<std::string> CirclePaintProperties::PossiblyEvaluated::defines() const { + std::vector<std::string> result; + result.push_back(circleRadius.isConstant() + ? std::string("#define HAS_UNIFORM_") + CircleRadius::Uniform::name() + : std::string()); + result.push_back(circleColor.isConstant() + ? std::string("#define HAS_UNIFORM_") + CircleColor::Uniform::name() + : std::string()); + result.push_back(circleBlur.isConstant() + ? std::string("#define HAS_UNIFORM_") + CircleBlur::Uniform::name() + : std::string()); + result.push_back(circleOpacity.isConstant() + ? std::string("#define HAS_UNIFORM_") + CircleOpacity::Uniform::name() + : std::string()); + result.push_back(circleStrokeWidth.isConstant() + ? std::string("#define HAS_UNIFORM_") + CircleStrokeWidth::Uniform::name() + : std::string()); + result.push_back(circleStrokeColor.isConstant() + ? std::string("#define HAS_UNIFORM_") + CircleStrokeColor::Uniform::name() + : std::string()); + result.push_back(circleStrokeOpacity.isConstant() + ? std::string("#define HAS_UNIFORM_") + CircleStrokeOpacity::Uniform::name() + : std::string()); + return result; +} + +void CirclePaintProperties::Binders::populateVertexVectors(const GeometryTileFeature& feature, std::size_t length) { + circleRadius->populateVertexVector(feature, length); + circleColor->populateVertexVector(feature, length); + circleBlur->populateVertexVector(feature, length); + circleOpacity->populateVertexVector(feature, length); + circleStrokeWidth->populateVertexVector(feature, length); + circleStrokeColor->populateVertexVector(feature, length); + circleStrokeOpacity->populateVertexVector(feature, length); +} + +void CirclePaintProperties::Binders::upload(gl::Context& context) { + circleRadius->upload(context); + circleColor->upload(context); + circleBlur->upload(context); + circleOpacity->upload(context); + circleStrokeWidth->upload(context); + circleStrokeColor->upload(context); + circleStrokeOpacity->upload(context); +} + +CirclePaintProperties::Binders::AttributeBindings CirclePaintProperties::Binders::attributeBindings(const PossiblyEvaluated& currentProperties) const { + return AttributeBindings { + circleRadius->attributeBinding(currentProperties.circleRadius), + circleColor->attributeBinding(currentProperties.circleColor), + circleBlur->attributeBinding(currentProperties.circleBlur), + circleOpacity->attributeBinding(currentProperties.circleOpacity), + circleStrokeWidth->attributeBinding(currentProperties.circleStrokeWidth), + circleStrokeColor->attributeBinding(currentProperties.circleStrokeColor), + circleStrokeOpacity->attributeBinding(currentProperties.circleStrokeOpacity), + }; +} + +CirclePaintProperties::Binders::UniformValues CirclePaintProperties::Binders::uniformValues(float currentZoom, const PossiblyEvaluated& currentProperties) const { + return UniformValues { + typename InterpolationUniform<attributes::a_radius>::Value { + circleRadius->interpolationFactor(currentZoom) + }, + typename InterpolationUniform<attributes::a_color>::Value { + circleColor->interpolationFactor(currentZoom) + }, + typename InterpolationUniform<attributes::a_blur>::Value { + circleBlur->interpolationFactor(currentZoom) + }, + typename InterpolationUniform<attributes::a_opacity>::Value { + circleOpacity->interpolationFactor(currentZoom) + }, + typename InterpolationUniform<attributes::a_stroke_width>::Value { + circleStrokeWidth->interpolationFactor(currentZoom) + }, + typename InterpolationUniform<attributes::a_stroke_color>::Value { + circleStrokeColor->interpolationFactor(currentZoom) + }, + typename InterpolationUniform<attributes::a_stroke_opacity>::Value { + circleStrokeOpacity->interpolationFactor(currentZoom) + }, + typename uniforms::u_radius::Value { + circleRadius->uniformValue(currentProperties.circleRadius) + }, + typename uniforms::u_color::Value { + circleColor->uniformValue(currentProperties.circleColor) + }, + typename uniforms::u_blur::Value { + circleBlur->uniformValue(currentProperties.circleBlur) + }, + typename uniforms::u_opacity::Value { + circleOpacity->uniformValue(currentProperties.circleOpacity) + }, + typename uniforms::u_stroke_width::Value { + circleStrokeWidth->uniformValue(currentProperties.circleStrokeWidth) + }, + typename uniforms::u_stroke_color::Value { + circleStrokeColor->uniformValue(currentProperties.circleStrokeColor) + }, + typename uniforms::u_stroke_opacity::Value { + circleStrokeOpacity->uniformValue(currentProperties.circleStrokeOpacity) + }, + }; +} + + } // namespace style } // namespace mbgl diff --git a/src/mbgl/style/layers/circle_layer_properties.hpp b/src/mbgl/style/layers/circle_layer_properties.hpp index bc0c961e7..e64cb2777 100644 --- a/src/mbgl/style/layers/circle_layer_properties.hpp +++ b/src/mbgl/style/layers/circle_layer_properties.hpp @@ -56,19 +56,116 @@ struct CircleStrokeOpacity : DataDrivenPaintProperty<float, attributes::a_stroke static float defaultValue() { return 1; } }; -class CirclePaintProperties : public Properties< - CircleRadius, - CircleColor, - CircleBlur, - CircleOpacity, - CircleTranslate, - CircleTranslateAnchor, - CirclePitchScale, - CirclePitchAlignment, - CircleStrokeWidth, - CircleStrokeColor, - CircleStrokeOpacity -> {}; +class CirclePaintProperties { +public: + class PossiblyEvaluated; + + class Binders { + public: + std::unique_ptr<PaintPropertyBinder<float, typename attributes::a_radius::Type>> circleRadius; + std::unique_ptr<PaintPropertyBinder<Color, typename attributes::a_color::Type>> circleColor; + std::unique_ptr<PaintPropertyBinder<float, typename attributes::a_blur::Type>> circleBlur; + std::unique_ptr<PaintPropertyBinder<float, typename attributes::a_opacity::Type>> circleOpacity; + std::unique_ptr<PaintPropertyBinder<float, typename attributes::a_stroke_width::Type>> circleStrokeWidth; + std::unique_ptr<PaintPropertyBinder<Color, typename attributes::a_stroke_color::Type>> circleStrokeColor; + std::unique_ptr<PaintPropertyBinder<float, typename attributes::a_stroke_opacity::Type>> circleStrokeOpacity; + + void populateVertexVectors(const GeometryTileFeature&, std::size_t length); + void upload(gl::Context&); + + using Attributes = gl::Attributes< + ZoomInterpolatedAttribute<attributes::a_radius>, + ZoomInterpolatedAttribute<attributes::a_color>, + ZoomInterpolatedAttribute<attributes::a_blur>, + ZoomInterpolatedAttribute<attributes::a_opacity>, + ZoomInterpolatedAttribute<attributes::a_stroke_width>, + ZoomInterpolatedAttribute<attributes::a_stroke_color>, + ZoomInterpolatedAttribute<attributes::a_stroke_opacity> + >; + + using Uniforms = gl::Uniforms< + InterpolationUniform<attributes::a_radius>, + InterpolationUniform<attributes::a_color>, + InterpolationUniform<attributes::a_blur>, + InterpolationUniform<attributes::a_opacity>, + InterpolationUniform<attributes::a_stroke_width>, + InterpolationUniform<attributes::a_stroke_color>, + InterpolationUniform<attributes::a_stroke_opacity>, + uniforms::u_radius, + uniforms::u_color, + uniforms::u_blur, + uniforms::u_opacity, + uniforms::u_stroke_width, + uniforms::u_stroke_color, + uniforms::u_stroke_opacity + >; + + using AttributeBindings = typename Attributes::Bindings; + using UniformValues = typename Uniforms::Values; + + AttributeBindings attributeBindings(const PossiblyEvaluated&) const; + UniformValues uniformValues(float z, const PossiblyEvaluated&) const; + }; + + class PossiblyEvaluated { + public: + PossiblyEvaluatedPropertyValue<float> circleRadius; + PossiblyEvaluatedPropertyValue<Color> circleColor; + PossiblyEvaluatedPropertyValue<float> circleBlur; + PossiblyEvaluatedPropertyValue<float> circleOpacity; + std::array<float, 2> circleTranslate; + TranslateAnchorType circleTranslateAnchor; + CirclePitchScaleType circlePitchScale; + AlignmentType circlePitchAlignment; + PossiblyEvaluatedPropertyValue<float> circleStrokeWidth; + PossiblyEvaluatedPropertyValue<Color> circleStrokeColor; + PossiblyEvaluatedPropertyValue<float> circleStrokeOpacity; + + Binders createBinders(float z) const; + + std::bitset<8> constants() const; + std::vector<std::string> defines() const; + }; + + class Unevaluated { + public: + style::Transitioning<PropertyValue<float>> circleRadius; + style::Transitioning<PropertyValue<Color>> circleColor; + style::Transitioning<PropertyValue<float>> circleBlur; + style::Transitioning<PropertyValue<float>> circleOpacity; + style::Transitioning<PropertyValue<std::array<float, 2>>> circleTranslate; + style::Transitioning<PropertyValue<TranslateAnchorType>> circleTranslateAnchor; + style::Transitioning<PropertyValue<CirclePitchScaleType>> circlePitchScale; + style::Transitioning<PropertyValue<AlignmentType>> circlePitchAlignment; + style::Transitioning<PropertyValue<float>> circleStrokeWidth; + style::Transitioning<PropertyValue<Color>> circleStrokeColor; + style::Transitioning<PropertyValue<float>> circleStrokeOpacity; + + bool hasTransition() const; + PossiblyEvaluated evaluate(const PropertyEvaluationParameters&) const; + }; + + class Transitionable { + public: + style::Transitionable<PropertyValue<float>> circleRadius; + style::Transitionable<PropertyValue<Color>> circleColor; + style::Transitionable<PropertyValue<float>> circleBlur; + style::Transitionable<PropertyValue<float>> circleOpacity; + style::Transitionable<PropertyValue<std::array<float, 2>>> circleTranslate; + style::Transitionable<PropertyValue<TranslateAnchorType>> circleTranslateAnchor; + style::Transitionable<PropertyValue<CirclePitchScaleType>> circlePitchScale; + style::Transitionable<PropertyValue<AlignmentType>> circlePitchAlignment; + style::Transitionable<PropertyValue<float>> circleStrokeWidth; + style::Transitionable<PropertyValue<Color>> circleStrokeColor; + style::Transitionable<PropertyValue<float>> circleStrokeOpacity; + + Unevaluated transitioned(const TransitionParameters&, Unevaluated&& prior) const; + Unevaluated untransitioned() const; + + bool hasDataDrivenPropertyDifference(const Transitionable& other) const; + }; +}; + } // namespace style } // namespace mbgl diff --git a/src/mbgl/style/layers/fill_extrusion_layer.cpp b/src/mbgl/style/layers/fill_extrusion_layer.cpp index db90415da..ddde6b6d0 100644 --- a/src/mbgl/style/layers/fill_extrusion_layer.cpp +++ b/src/mbgl/style/layers/fill_extrusion_layer.cpp @@ -108,26 +108,26 @@ PropertyValue<float> FillExtrusionLayer::getDefaultFillExtrusionOpacity() { } PropertyValue<float> FillExtrusionLayer::getFillExtrusionOpacity() const { - return impl().paint.template get<FillExtrusionOpacity>().value; + return impl().paint.fillExtrusionOpacity.value; } void FillExtrusionLayer::setFillExtrusionOpacity(PropertyValue<float> value) { if (value == getFillExtrusionOpacity()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<FillExtrusionOpacity>().value = value; + impl_->paint.fillExtrusionOpacity.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void FillExtrusionLayer::setFillExtrusionOpacityTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<FillExtrusionOpacity>().options = options; + impl_->paint.fillExtrusionOpacity.options = options; baseImpl = std::move(impl_); } TransitionOptions FillExtrusionLayer::getFillExtrusionOpacityTransition() const { - return impl().paint.template get<FillExtrusionOpacity>().options; + return impl().paint.fillExtrusionOpacity.options; } PropertyValue<Color> FillExtrusionLayer::getDefaultFillExtrusionColor() { @@ -135,26 +135,26 @@ PropertyValue<Color> FillExtrusionLayer::getDefaultFillExtrusionColor() { } PropertyValue<Color> FillExtrusionLayer::getFillExtrusionColor() const { - return impl().paint.template get<FillExtrusionColor>().value; + return impl().paint.fillExtrusionColor.value; } void FillExtrusionLayer::setFillExtrusionColor(PropertyValue<Color> value) { if (value == getFillExtrusionColor()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<FillExtrusionColor>().value = value; + impl_->paint.fillExtrusionColor.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void FillExtrusionLayer::setFillExtrusionColorTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<FillExtrusionColor>().options = options; + impl_->paint.fillExtrusionColor.options = options; baseImpl = std::move(impl_); } TransitionOptions FillExtrusionLayer::getFillExtrusionColorTransition() const { - return impl().paint.template get<FillExtrusionColor>().options; + return impl().paint.fillExtrusionColor.options; } PropertyValue<std::array<float, 2>> FillExtrusionLayer::getDefaultFillExtrusionTranslate() { @@ -162,26 +162,26 @@ PropertyValue<std::array<float, 2>> FillExtrusionLayer::getDefaultFillExtrusionT } PropertyValue<std::array<float, 2>> FillExtrusionLayer::getFillExtrusionTranslate() const { - return impl().paint.template get<FillExtrusionTranslate>().value; + return impl().paint.fillExtrusionTranslate.value; } void FillExtrusionLayer::setFillExtrusionTranslate(PropertyValue<std::array<float, 2>> value) { if (value == getFillExtrusionTranslate()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<FillExtrusionTranslate>().value = value; + impl_->paint.fillExtrusionTranslate.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void FillExtrusionLayer::setFillExtrusionTranslateTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<FillExtrusionTranslate>().options = options; + impl_->paint.fillExtrusionTranslate.options = options; baseImpl = std::move(impl_); } TransitionOptions FillExtrusionLayer::getFillExtrusionTranslateTransition() const { - return impl().paint.template get<FillExtrusionTranslate>().options; + return impl().paint.fillExtrusionTranslate.options; } PropertyValue<TranslateAnchorType> FillExtrusionLayer::getDefaultFillExtrusionTranslateAnchor() { @@ -189,26 +189,26 @@ PropertyValue<TranslateAnchorType> FillExtrusionLayer::getDefaultFillExtrusionTr } PropertyValue<TranslateAnchorType> FillExtrusionLayer::getFillExtrusionTranslateAnchor() const { - return impl().paint.template get<FillExtrusionTranslateAnchor>().value; + return impl().paint.fillExtrusionTranslateAnchor.value; } void FillExtrusionLayer::setFillExtrusionTranslateAnchor(PropertyValue<TranslateAnchorType> value) { if (value == getFillExtrusionTranslateAnchor()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<FillExtrusionTranslateAnchor>().value = value; + impl_->paint.fillExtrusionTranslateAnchor.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void FillExtrusionLayer::setFillExtrusionTranslateAnchorTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<FillExtrusionTranslateAnchor>().options = options; + impl_->paint.fillExtrusionTranslateAnchor.options = options; baseImpl = std::move(impl_); } TransitionOptions FillExtrusionLayer::getFillExtrusionTranslateAnchorTransition() const { - return impl().paint.template get<FillExtrusionTranslateAnchor>().options; + return impl().paint.fillExtrusionTranslateAnchor.options; } PropertyValue<std::string> FillExtrusionLayer::getDefaultFillExtrusionPattern() { @@ -216,26 +216,26 @@ PropertyValue<std::string> FillExtrusionLayer::getDefaultFillExtrusionPattern() } PropertyValue<std::string> FillExtrusionLayer::getFillExtrusionPattern() const { - return impl().paint.template get<FillExtrusionPattern>().value; + return impl().paint.fillExtrusionPattern.value; } void FillExtrusionLayer::setFillExtrusionPattern(PropertyValue<std::string> value) { if (value == getFillExtrusionPattern()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<FillExtrusionPattern>().value = value; + impl_->paint.fillExtrusionPattern.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void FillExtrusionLayer::setFillExtrusionPatternTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<FillExtrusionPattern>().options = options; + impl_->paint.fillExtrusionPattern.options = options; baseImpl = std::move(impl_); } TransitionOptions FillExtrusionLayer::getFillExtrusionPatternTransition() const { - return impl().paint.template get<FillExtrusionPattern>().options; + return impl().paint.fillExtrusionPattern.options; } PropertyValue<float> FillExtrusionLayer::getDefaultFillExtrusionHeight() { @@ -243,26 +243,26 @@ PropertyValue<float> FillExtrusionLayer::getDefaultFillExtrusionHeight() { } PropertyValue<float> FillExtrusionLayer::getFillExtrusionHeight() const { - return impl().paint.template get<FillExtrusionHeight>().value; + return impl().paint.fillExtrusionHeight.value; } void FillExtrusionLayer::setFillExtrusionHeight(PropertyValue<float> value) { if (value == getFillExtrusionHeight()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<FillExtrusionHeight>().value = value; + impl_->paint.fillExtrusionHeight.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void FillExtrusionLayer::setFillExtrusionHeightTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<FillExtrusionHeight>().options = options; + impl_->paint.fillExtrusionHeight.options = options; baseImpl = std::move(impl_); } TransitionOptions FillExtrusionLayer::getFillExtrusionHeightTransition() const { - return impl().paint.template get<FillExtrusionHeight>().options; + return impl().paint.fillExtrusionHeight.options; } PropertyValue<float> FillExtrusionLayer::getDefaultFillExtrusionBase() { @@ -270,26 +270,26 @@ PropertyValue<float> FillExtrusionLayer::getDefaultFillExtrusionBase() { } PropertyValue<float> FillExtrusionLayer::getFillExtrusionBase() const { - return impl().paint.template get<FillExtrusionBase>().value; + return impl().paint.fillExtrusionBase.value; } void FillExtrusionLayer::setFillExtrusionBase(PropertyValue<float> value) { if (value == getFillExtrusionBase()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<FillExtrusionBase>().value = value; + impl_->paint.fillExtrusionBase.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void FillExtrusionLayer::setFillExtrusionBaseTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<FillExtrusionBase>().options = options; + impl_->paint.fillExtrusionBase.options = options; baseImpl = std::move(impl_); } TransitionOptions FillExtrusionLayer::getFillExtrusionBaseTransition() const { - return impl().paint.template get<FillExtrusionBase>().options; + return impl().paint.fillExtrusionBase.options; } using namespace conversion; diff --git a/src/mbgl/style/layers/fill_extrusion_layer_properties.cpp b/src/mbgl/style/layers/fill_extrusion_layer_properties.cpp index 59572bd3a..23aea2ce0 100644 --- a/src/mbgl/style/layers/fill_extrusion_layer_properties.cpp +++ b/src/mbgl/style/layers/fill_extrusion_layer_properties.cpp @@ -5,5 +5,139 @@ namespace mbgl { namespace style { +FillExtrusionPaintProperties::Unevaluated FillExtrusionPaintProperties::Transitionable::transitioned(const TransitionParameters& parameters, Unevaluated&& prior) const { + return Unevaluated { + fillExtrusionOpacity.transition(parameters, std::move(prior.fillExtrusionOpacity)), + fillExtrusionColor.transition(parameters, std::move(prior.fillExtrusionColor)), + fillExtrusionTranslate.transition(parameters, std::move(prior.fillExtrusionTranslate)), + fillExtrusionTranslateAnchor.transition(parameters, std::move(prior.fillExtrusionTranslateAnchor)), + fillExtrusionPattern.transition(parameters, std::move(prior.fillExtrusionPattern)), + fillExtrusionHeight.transition(parameters, std::move(prior.fillExtrusionHeight)), + fillExtrusionBase.transition(parameters, std::move(prior.fillExtrusionBase)), + }; +} + +FillExtrusionPaintProperties::Unevaluated FillExtrusionPaintProperties::Transitionable::untransitioned() const { + return Unevaluated { + Transitioning<PropertyValue<float>>(fillExtrusionOpacity.value), + Transitioning<PropertyValue<Color>>(fillExtrusionColor.value), + Transitioning<PropertyValue<std::array<float, 2>>>(fillExtrusionTranslate.value), + Transitioning<PropertyValue<TranslateAnchorType>>(fillExtrusionTranslateAnchor.value), + Transitioning<PropertyValue<std::string>>(fillExtrusionPattern.value), + Transitioning<PropertyValue<float>>(fillExtrusionHeight.value), + Transitioning<PropertyValue<float>>(fillExtrusionBase.value), + }; +} + +bool FillExtrusionPaintProperties::Transitionable::hasDataDrivenPropertyDifference(const Transitionable& other) const { + return false + || fillExtrusionOpacity.value.hasDataDrivenPropertyDifference(other.fillExtrusionOpacity.value) + || fillExtrusionColor.value.hasDataDrivenPropertyDifference(other.fillExtrusionColor.value) + || fillExtrusionTranslate.value.hasDataDrivenPropertyDifference(other.fillExtrusionTranslate.value) + || fillExtrusionTranslateAnchor.value.hasDataDrivenPropertyDifference(other.fillExtrusionTranslateAnchor.value) + || fillExtrusionPattern.value.hasDataDrivenPropertyDifference(other.fillExtrusionPattern.value) + || fillExtrusionHeight.value.hasDataDrivenPropertyDifference(other.fillExtrusionHeight.value) + || fillExtrusionBase.value.hasDataDrivenPropertyDifference(other.fillExtrusionBase.value) + ; +} + +bool FillExtrusionPaintProperties::Unevaluated::hasTransition() const { + return false + || fillExtrusionOpacity.hasTransition() + || fillExtrusionColor.hasTransition() + || fillExtrusionTranslate.hasTransition() + || fillExtrusionTranslateAnchor.hasTransition() + || fillExtrusionPattern.hasTransition() + || fillExtrusionHeight.hasTransition() + || fillExtrusionBase.hasTransition() + ; +} + +FillExtrusionPaintProperties::PossiblyEvaluated FillExtrusionPaintProperties::Unevaluated::evaluate(const PropertyEvaluationParameters& parameters) const { + return PossiblyEvaluated { + fillExtrusionOpacity.evaluate(typename FillExtrusionOpacity::EvaluatorType(parameters, FillExtrusionOpacity::defaultValue()), parameters.now), + fillExtrusionColor.evaluate(typename FillExtrusionColor::EvaluatorType(parameters, FillExtrusionColor::defaultValue()), parameters.now), + fillExtrusionTranslate.evaluate(typename FillExtrusionTranslate::EvaluatorType(parameters, FillExtrusionTranslate::defaultValue()), parameters.now), + fillExtrusionTranslateAnchor.evaluate(typename FillExtrusionTranslateAnchor::EvaluatorType(parameters, FillExtrusionTranslateAnchor::defaultValue()), parameters.now), + fillExtrusionPattern.evaluate(typename FillExtrusionPattern::EvaluatorType(parameters, FillExtrusionPattern::defaultValue()), parameters.now), + fillExtrusionHeight.evaluate(typename FillExtrusionHeight::EvaluatorType(parameters, FillExtrusionHeight::defaultValue()), parameters.now), + fillExtrusionBase.evaluate(typename FillExtrusionBase::EvaluatorType(parameters, FillExtrusionBase::defaultValue()), parameters.now), + }; +} + +FillExtrusionPaintProperties::Binders FillExtrusionPaintProperties::PossiblyEvaluated::createBinders(float z) const { + return Binders { + PaintPropertyBinder<Color, typename attributes::a_color::Type>::create(fillExtrusionColor, z, FillExtrusionColor::defaultValue()), + PaintPropertyBinder<float, typename attributes::a_height::Type>::create(fillExtrusionHeight, z, FillExtrusionHeight::defaultValue()), + PaintPropertyBinder<float, typename attributes::a_base::Type>::create(fillExtrusionBase, z, FillExtrusionBase::defaultValue()), + }; +} + +std::bitset<8> FillExtrusionPaintProperties::PossiblyEvaluated::constants() const { + std::bitset<8> result; + result.set(0, fillExtrusionColor.isConstant()); + result.set(1, fillExtrusionHeight.isConstant()); + result.set(2, fillExtrusionBase.isConstant()); + return result; +} + +std::vector<std::string> FillExtrusionPaintProperties::PossiblyEvaluated::defines() const { + std::vector<std::string> result; + result.push_back(fillExtrusionColor.isConstant() + ? std::string("#define HAS_UNIFORM_") + FillExtrusionColor::Uniform::name() + : std::string()); + result.push_back(fillExtrusionHeight.isConstant() + ? std::string("#define HAS_UNIFORM_") + FillExtrusionHeight::Uniform::name() + : std::string()); + result.push_back(fillExtrusionBase.isConstant() + ? std::string("#define HAS_UNIFORM_") + FillExtrusionBase::Uniform::name() + : std::string()); + return result; +} + +void FillExtrusionPaintProperties::Binders::populateVertexVectors(const GeometryTileFeature& feature, std::size_t length) { + fillExtrusionColor->populateVertexVector(feature, length); + fillExtrusionHeight->populateVertexVector(feature, length); + fillExtrusionBase->populateVertexVector(feature, length); +} + +void FillExtrusionPaintProperties::Binders::upload(gl::Context& context) { + fillExtrusionColor->upload(context); + fillExtrusionHeight->upload(context); + fillExtrusionBase->upload(context); +} + +FillExtrusionPaintProperties::Binders::AttributeBindings FillExtrusionPaintProperties::Binders::attributeBindings(const PossiblyEvaluated& currentProperties) const { + return AttributeBindings { + fillExtrusionColor->attributeBinding(currentProperties.fillExtrusionColor), + fillExtrusionHeight->attributeBinding(currentProperties.fillExtrusionHeight), + fillExtrusionBase->attributeBinding(currentProperties.fillExtrusionBase), + }; +} + +FillExtrusionPaintProperties::Binders::UniformValues FillExtrusionPaintProperties::Binders::uniformValues(float currentZoom, const PossiblyEvaluated& currentProperties) const { + return UniformValues { + typename InterpolationUniform<attributes::a_color>::Value { + fillExtrusionColor->interpolationFactor(currentZoom) + }, + typename InterpolationUniform<attributes::a_height>::Value { + fillExtrusionHeight->interpolationFactor(currentZoom) + }, + typename InterpolationUniform<attributes::a_base>::Value { + fillExtrusionBase->interpolationFactor(currentZoom) + }, + typename uniforms::u_color::Value { + fillExtrusionColor->uniformValue(currentProperties.fillExtrusionColor) + }, + typename uniforms::u_height::Value { + fillExtrusionHeight->uniformValue(currentProperties.fillExtrusionHeight) + }, + typename uniforms::u_base::Value { + fillExtrusionBase->uniformValue(currentProperties.fillExtrusionBase) + }, + }; +} + + } // namespace style } // namespace mbgl diff --git a/src/mbgl/style/layers/fill_extrusion_layer_properties.hpp b/src/mbgl/style/layers/fill_extrusion_layer_properties.hpp index 19be59a2f..4e94a0813 100644 --- a/src/mbgl/style/layers/fill_extrusion_layer_properties.hpp +++ b/src/mbgl/style/layers/fill_extrusion_layer_properties.hpp @@ -40,15 +40,88 @@ struct FillExtrusionBase : DataDrivenPaintProperty<float, attributes::a_base, un static float defaultValue() { return 0; } }; -class FillExtrusionPaintProperties : public Properties< - FillExtrusionOpacity, - FillExtrusionColor, - FillExtrusionTranslate, - FillExtrusionTranslateAnchor, - FillExtrusionPattern, - FillExtrusionHeight, - FillExtrusionBase -> {}; +class FillExtrusionPaintProperties { +public: + class PossiblyEvaluated; + + class Binders { + public: + std::unique_ptr<PaintPropertyBinder<Color, typename attributes::a_color::Type>> fillExtrusionColor; + std::unique_ptr<PaintPropertyBinder<float, typename attributes::a_height::Type>> fillExtrusionHeight; + std::unique_ptr<PaintPropertyBinder<float, typename attributes::a_base::Type>> fillExtrusionBase; + + void populateVertexVectors(const GeometryTileFeature&, std::size_t length); + void upload(gl::Context&); + + using Attributes = gl::Attributes< + ZoomInterpolatedAttribute<attributes::a_color>, + ZoomInterpolatedAttribute<attributes::a_height>, + ZoomInterpolatedAttribute<attributes::a_base> + >; + + using Uniforms = gl::Uniforms< + InterpolationUniform<attributes::a_color>, + InterpolationUniform<attributes::a_height>, + InterpolationUniform<attributes::a_base>, + uniforms::u_color, + uniforms::u_height, + uniforms::u_base + >; + + using AttributeBindings = typename Attributes::Bindings; + using UniformValues = typename Uniforms::Values; + + AttributeBindings attributeBindings(const PossiblyEvaluated&) const; + UniformValues uniformValues(float z, const PossiblyEvaluated&) const; + }; + + class PossiblyEvaluated { + public: + float fillExtrusionOpacity; + PossiblyEvaluatedPropertyValue<Color> fillExtrusionColor; + std::array<float, 2> fillExtrusionTranslate; + TranslateAnchorType fillExtrusionTranslateAnchor; + Faded<std::string> fillExtrusionPattern; + PossiblyEvaluatedPropertyValue<float> fillExtrusionHeight; + PossiblyEvaluatedPropertyValue<float> fillExtrusionBase; + + Binders createBinders(float z) const; + + std::bitset<8> constants() const; + std::vector<std::string> defines() const; + }; + + class Unevaluated { + public: + style::Transitioning<PropertyValue<float>> fillExtrusionOpacity; + style::Transitioning<PropertyValue<Color>> fillExtrusionColor; + style::Transitioning<PropertyValue<std::array<float, 2>>> fillExtrusionTranslate; + style::Transitioning<PropertyValue<TranslateAnchorType>> fillExtrusionTranslateAnchor; + style::Transitioning<PropertyValue<std::string>> fillExtrusionPattern; + style::Transitioning<PropertyValue<float>> fillExtrusionHeight; + style::Transitioning<PropertyValue<float>> fillExtrusionBase; + + bool hasTransition() const; + PossiblyEvaluated evaluate(const PropertyEvaluationParameters&) const; + }; + + class Transitionable { + public: + style::Transitionable<PropertyValue<float>> fillExtrusionOpacity; + style::Transitionable<PropertyValue<Color>> fillExtrusionColor; + style::Transitionable<PropertyValue<std::array<float, 2>>> fillExtrusionTranslate; + style::Transitionable<PropertyValue<TranslateAnchorType>> fillExtrusionTranslateAnchor; + style::Transitionable<PropertyValue<std::string>> fillExtrusionPattern; + style::Transitionable<PropertyValue<float>> fillExtrusionHeight; + style::Transitionable<PropertyValue<float>> fillExtrusionBase; + + Unevaluated transitioned(const TransitionParameters&, Unevaluated&& prior) const; + Unevaluated untransitioned() const; + + bool hasDataDrivenPropertyDifference(const Transitionable& other) const; + }; +}; + } // namespace style } // namespace mbgl diff --git a/src/mbgl/style/layers/fill_layer.cpp b/src/mbgl/style/layers/fill_layer.cpp index 2da131b6b..7ab1799f8 100644 --- a/src/mbgl/style/layers/fill_layer.cpp +++ b/src/mbgl/style/layers/fill_layer.cpp @@ -108,26 +108,26 @@ PropertyValue<bool> FillLayer::getDefaultFillAntialias() { } PropertyValue<bool> FillLayer::getFillAntialias() const { - return impl().paint.template get<FillAntialias>().value; + return impl().paint.fillAntialias.value; } void FillLayer::setFillAntialias(PropertyValue<bool> value) { if (value == getFillAntialias()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<FillAntialias>().value = value; + impl_->paint.fillAntialias.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void FillLayer::setFillAntialiasTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<FillAntialias>().options = options; + impl_->paint.fillAntialias.options = options; baseImpl = std::move(impl_); } TransitionOptions FillLayer::getFillAntialiasTransition() const { - return impl().paint.template get<FillAntialias>().options; + return impl().paint.fillAntialias.options; } PropertyValue<float> FillLayer::getDefaultFillOpacity() { @@ -135,26 +135,26 @@ PropertyValue<float> FillLayer::getDefaultFillOpacity() { } PropertyValue<float> FillLayer::getFillOpacity() const { - return impl().paint.template get<FillOpacity>().value; + return impl().paint.fillOpacity.value; } void FillLayer::setFillOpacity(PropertyValue<float> value) { if (value == getFillOpacity()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<FillOpacity>().value = value; + impl_->paint.fillOpacity.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void FillLayer::setFillOpacityTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<FillOpacity>().options = options; + impl_->paint.fillOpacity.options = options; baseImpl = std::move(impl_); } TransitionOptions FillLayer::getFillOpacityTransition() const { - return impl().paint.template get<FillOpacity>().options; + return impl().paint.fillOpacity.options; } PropertyValue<Color> FillLayer::getDefaultFillColor() { @@ -162,26 +162,26 @@ PropertyValue<Color> FillLayer::getDefaultFillColor() { } PropertyValue<Color> FillLayer::getFillColor() const { - return impl().paint.template get<FillColor>().value; + return impl().paint.fillColor.value; } void FillLayer::setFillColor(PropertyValue<Color> value) { if (value == getFillColor()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<FillColor>().value = value; + impl_->paint.fillColor.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void FillLayer::setFillColorTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<FillColor>().options = options; + impl_->paint.fillColor.options = options; baseImpl = std::move(impl_); } TransitionOptions FillLayer::getFillColorTransition() const { - return impl().paint.template get<FillColor>().options; + return impl().paint.fillColor.options; } PropertyValue<Color> FillLayer::getDefaultFillOutlineColor() { @@ -189,26 +189,26 @@ PropertyValue<Color> FillLayer::getDefaultFillOutlineColor() { } PropertyValue<Color> FillLayer::getFillOutlineColor() const { - return impl().paint.template get<FillOutlineColor>().value; + return impl().paint.fillOutlineColor.value; } void FillLayer::setFillOutlineColor(PropertyValue<Color> value) { if (value == getFillOutlineColor()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<FillOutlineColor>().value = value; + impl_->paint.fillOutlineColor.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void FillLayer::setFillOutlineColorTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<FillOutlineColor>().options = options; + impl_->paint.fillOutlineColor.options = options; baseImpl = std::move(impl_); } TransitionOptions FillLayer::getFillOutlineColorTransition() const { - return impl().paint.template get<FillOutlineColor>().options; + return impl().paint.fillOutlineColor.options; } PropertyValue<std::array<float, 2>> FillLayer::getDefaultFillTranslate() { @@ -216,26 +216,26 @@ PropertyValue<std::array<float, 2>> FillLayer::getDefaultFillTranslate() { } PropertyValue<std::array<float, 2>> FillLayer::getFillTranslate() const { - return impl().paint.template get<FillTranslate>().value; + return impl().paint.fillTranslate.value; } void FillLayer::setFillTranslate(PropertyValue<std::array<float, 2>> value) { if (value == getFillTranslate()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<FillTranslate>().value = value; + impl_->paint.fillTranslate.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void FillLayer::setFillTranslateTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<FillTranslate>().options = options; + impl_->paint.fillTranslate.options = options; baseImpl = std::move(impl_); } TransitionOptions FillLayer::getFillTranslateTransition() const { - return impl().paint.template get<FillTranslate>().options; + return impl().paint.fillTranslate.options; } PropertyValue<TranslateAnchorType> FillLayer::getDefaultFillTranslateAnchor() { @@ -243,26 +243,26 @@ PropertyValue<TranslateAnchorType> FillLayer::getDefaultFillTranslateAnchor() { } PropertyValue<TranslateAnchorType> FillLayer::getFillTranslateAnchor() const { - return impl().paint.template get<FillTranslateAnchor>().value; + return impl().paint.fillTranslateAnchor.value; } void FillLayer::setFillTranslateAnchor(PropertyValue<TranslateAnchorType> value) { if (value == getFillTranslateAnchor()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<FillTranslateAnchor>().value = value; + impl_->paint.fillTranslateAnchor.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void FillLayer::setFillTranslateAnchorTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<FillTranslateAnchor>().options = options; + impl_->paint.fillTranslateAnchor.options = options; baseImpl = std::move(impl_); } TransitionOptions FillLayer::getFillTranslateAnchorTransition() const { - return impl().paint.template get<FillTranslateAnchor>().options; + return impl().paint.fillTranslateAnchor.options; } PropertyValue<std::string> FillLayer::getDefaultFillPattern() { @@ -270,26 +270,26 @@ PropertyValue<std::string> FillLayer::getDefaultFillPattern() { } PropertyValue<std::string> FillLayer::getFillPattern() const { - return impl().paint.template get<FillPattern>().value; + return impl().paint.fillPattern.value; } void FillLayer::setFillPattern(PropertyValue<std::string> value) { if (value == getFillPattern()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<FillPattern>().value = value; + impl_->paint.fillPattern.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void FillLayer::setFillPatternTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<FillPattern>().options = options; + impl_->paint.fillPattern.options = options; baseImpl = std::move(impl_); } TransitionOptions FillLayer::getFillPatternTransition() const { - return impl().paint.template get<FillPattern>().options; + return impl().paint.fillPattern.options; } using namespace conversion; diff --git a/src/mbgl/style/layers/fill_layer_properties.cpp b/src/mbgl/style/layers/fill_layer_properties.cpp index b07a08395..10ba8d43f 100644 --- a/src/mbgl/style/layers/fill_layer_properties.cpp +++ b/src/mbgl/style/layers/fill_layer_properties.cpp @@ -5,5 +5,139 @@ namespace mbgl { namespace style { +FillPaintProperties::Unevaluated FillPaintProperties::Transitionable::transitioned(const TransitionParameters& parameters, Unevaluated&& prior) const { + return Unevaluated { + fillAntialias.transition(parameters, std::move(prior.fillAntialias)), + fillOpacity.transition(parameters, std::move(prior.fillOpacity)), + fillColor.transition(parameters, std::move(prior.fillColor)), + fillOutlineColor.transition(parameters, std::move(prior.fillOutlineColor)), + fillTranslate.transition(parameters, std::move(prior.fillTranslate)), + fillTranslateAnchor.transition(parameters, std::move(prior.fillTranslateAnchor)), + fillPattern.transition(parameters, std::move(prior.fillPattern)), + }; +} + +FillPaintProperties::Unevaluated FillPaintProperties::Transitionable::untransitioned() const { + return Unevaluated { + Transitioning<PropertyValue<bool>>(fillAntialias.value), + Transitioning<PropertyValue<float>>(fillOpacity.value), + Transitioning<PropertyValue<Color>>(fillColor.value), + Transitioning<PropertyValue<Color>>(fillOutlineColor.value), + Transitioning<PropertyValue<std::array<float, 2>>>(fillTranslate.value), + Transitioning<PropertyValue<TranslateAnchorType>>(fillTranslateAnchor.value), + Transitioning<PropertyValue<std::string>>(fillPattern.value), + }; +} + +bool FillPaintProperties::Transitionable::hasDataDrivenPropertyDifference(const Transitionable& other) const { + return false + || fillAntialias.value.hasDataDrivenPropertyDifference(other.fillAntialias.value) + || fillOpacity.value.hasDataDrivenPropertyDifference(other.fillOpacity.value) + || fillColor.value.hasDataDrivenPropertyDifference(other.fillColor.value) + || fillOutlineColor.value.hasDataDrivenPropertyDifference(other.fillOutlineColor.value) + || fillTranslate.value.hasDataDrivenPropertyDifference(other.fillTranslate.value) + || fillTranslateAnchor.value.hasDataDrivenPropertyDifference(other.fillTranslateAnchor.value) + || fillPattern.value.hasDataDrivenPropertyDifference(other.fillPattern.value) + ; +} + +bool FillPaintProperties::Unevaluated::hasTransition() const { + return false + || fillAntialias.hasTransition() + || fillOpacity.hasTransition() + || fillColor.hasTransition() + || fillOutlineColor.hasTransition() + || fillTranslate.hasTransition() + || fillTranslateAnchor.hasTransition() + || fillPattern.hasTransition() + ; +} + +FillPaintProperties::PossiblyEvaluated FillPaintProperties::Unevaluated::evaluate(const PropertyEvaluationParameters& parameters) const { + return PossiblyEvaluated { + fillAntialias.evaluate(typename FillAntialias::EvaluatorType(parameters, FillAntialias::defaultValue()), parameters.now), + fillOpacity.evaluate(typename FillOpacity::EvaluatorType(parameters, FillOpacity::defaultValue()), parameters.now), + fillColor.evaluate(typename FillColor::EvaluatorType(parameters, FillColor::defaultValue()), parameters.now), + fillOutlineColor.evaluate(typename FillOutlineColor::EvaluatorType(parameters, FillOutlineColor::defaultValue()), parameters.now), + fillTranslate.evaluate(typename FillTranslate::EvaluatorType(parameters, FillTranslate::defaultValue()), parameters.now), + fillTranslateAnchor.evaluate(typename FillTranslateAnchor::EvaluatorType(parameters, FillTranslateAnchor::defaultValue()), parameters.now), + fillPattern.evaluate(typename FillPattern::EvaluatorType(parameters, FillPattern::defaultValue()), parameters.now), + }; +} + +FillPaintProperties::Binders FillPaintProperties::PossiblyEvaluated::createBinders(float z) const { + return Binders { + PaintPropertyBinder<float, typename attributes::a_opacity::Type>::create(fillOpacity, z, FillOpacity::defaultValue()), + PaintPropertyBinder<Color, typename attributes::a_color::Type>::create(fillColor, z, FillColor::defaultValue()), + PaintPropertyBinder<Color, typename attributes::a_outline_color::Type>::create(fillOutlineColor, z, FillOutlineColor::defaultValue()), + }; +} + +std::bitset<8> FillPaintProperties::PossiblyEvaluated::constants() const { + std::bitset<8> result; + result.set(0, fillOpacity.isConstant()); + result.set(1, fillColor.isConstant()); + result.set(2, fillOutlineColor.isConstant()); + return result; +} + +std::vector<std::string> FillPaintProperties::PossiblyEvaluated::defines() const { + std::vector<std::string> result; + result.push_back(fillOpacity.isConstant() + ? std::string("#define HAS_UNIFORM_") + FillOpacity::Uniform::name() + : std::string()); + result.push_back(fillColor.isConstant() + ? std::string("#define HAS_UNIFORM_") + FillColor::Uniform::name() + : std::string()); + result.push_back(fillOutlineColor.isConstant() + ? std::string("#define HAS_UNIFORM_") + FillOutlineColor::Uniform::name() + : std::string()); + return result; +} + +void FillPaintProperties::Binders::populateVertexVectors(const GeometryTileFeature& feature, std::size_t length) { + fillOpacity->populateVertexVector(feature, length); + fillColor->populateVertexVector(feature, length); + fillOutlineColor->populateVertexVector(feature, length); +} + +void FillPaintProperties::Binders::upload(gl::Context& context) { + fillOpacity->upload(context); + fillColor->upload(context); + fillOutlineColor->upload(context); +} + +FillPaintProperties::Binders::AttributeBindings FillPaintProperties::Binders::attributeBindings(const PossiblyEvaluated& currentProperties) const { + return AttributeBindings { + fillOpacity->attributeBinding(currentProperties.fillOpacity), + fillColor->attributeBinding(currentProperties.fillColor), + fillOutlineColor->attributeBinding(currentProperties.fillOutlineColor), + }; +} + +FillPaintProperties::Binders::UniformValues FillPaintProperties::Binders::uniformValues(float currentZoom, const PossiblyEvaluated& currentProperties) const { + return UniformValues { + typename InterpolationUniform<attributes::a_opacity>::Value { + fillOpacity->interpolationFactor(currentZoom) + }, + typename InterpolationUniform<attributes::a_color>::Value { + fillColor->interpolationFactor(currentZoom) + }, + typename InterpolationUniform<attributes::a_outline_color>::Value { + fillOutlineColor->interpolationFactor(currentZoom) + }, + typename uniforms::u_opacity::Value { + fillOpacity->uniformValue(currentProperties.fillOpacity) + }, + typename uniforms::u_color::Value { + fillColor->uniformValue(currentProperties.fillColor) + }, + typename uniforms::u_outline_color::Value { + fillOutlineColor->uniformValue(currentProperties.fillOutlineColor) + }, + }; +} + + } // namespace style } // namespace mbgl diff --git a/src/mbgl/style/layers/fill_layer_properties.hpp b/src/mbgl/style/layers/fill_layer_properties.hpp index cb0119451..23041d4a9 100644 --- a/src/mbgl/style/layers/fill_layer_properties.hpp +++ b/src/mbgl/style/layers/fill_layer_properties.hpp @@ -40,15 +40,88 @@ struct FillPattern : CrossFadedPaintProperty<std::string> { static std::string defaultValue() { return ""; } }; -class FillPaintProperties : public Properties< - FillAntialias, - FillOpacity, - FillColor, - FillOutlineColor, - FillTranslate, - FillTranslateAnchor, - FillPattern -> {}; +class FillPaintProperties { +public: + class PossiblyEvaluated; + + class Binders { + public: + std::unique_ptr<PaintPropertyBinder<float, typename attributes::a_opacity::Type>> fillOpacity; + std::unique_ptr<PaintPropertyBinder<Color, typename attributes::a_color::Type>> fillColor; + std::unique_ptr<PaintPropertyBinder<Color, typename attributes::a_outline_color::Type>> fillOutlineColor; + + void populateVertexVectors(const GeometryTileFeature&, std::size_t length); + void upload(gl::Context&); + + using Attributes = gl::Attributes< + ZoomInterpolatedAttribute<attributes::a_opacity>, + ZoomInterpolatedAttribute<attributes::a_color>, + ZoomInterpolatedAttribute<attributes::a_outline_color> + >; + + using Uniforms = gl::Uniforms< + InterpolationUniform<attributes::a_opacity>, + InterpolationUniform<attributes::a_color>, + InterpolationUniform<attributes::a_outline_color>, + uniforms::u_opacity, + uniforms::u_color, + uniforms::u_outline_color + >; + + using AttributeBindings = typename Attributes::Bindings; + using UniformValues = typename Uniforms::Values; + + AttributeBindings attributeBindings(const PossiblyEvaluated&) const; + UniformValues uniformValues(float z, const PossiblyEvaluated&) const; + }; + + class PossiblyEvaluated { + public: + bool fillAntialias; + PossiblyEvaluatedPropertyValue<float> fillOpacity; + PossiblyEvaluatedPropertyValue<Color> fillColor; + PossiblyEvaluatedPropertyValue<Color> fillOutlineColor; + std::array<float, 2> fillTranslate; + TranslateAnchorType fillTranslateAnchor; + Faded<std::string> fillPattern; + + Binders createBinders(float z) const; + + std::bitset<8> constants() const; + std::vector<std::string> defines() const; + }; + + class Unevaluated { + public: + style::Transitioning<PropertyValue<bool>> fillAntialias; + style::Transitioning<PropertyValue<float>> fillOpacity; + style::Transitioning<PropertyValue<Color>> fillColor; + style::Transitioning<PropertyValue<Color>> fillOutlineColor; + style::Transitioning<PropertyValue<std::array<float, 2>>> fillTranslate; + style::Transitioning<PropertyValue<TranslateAnchorType>> fillTranslateAnchor; + style::Transitioning<PropertyValue<std::string>> fillPattern; + + bool hasTransition() const; + PossiblyEvaluated evaluate(const PropertyEvaluationParameters&) const; + }; + + class Transitionable { + public: + style::Transitionable<PropertyValue<bool>> fillAntialias; + style::Transitionable<PropertyValue<float>> fillOpacity; + style::Transitionable<PropertyValue<Color>> fillColor; + style::Transitionable<PropertyValue<Color>> fillOutlineColor; + style::Transitionable<PropertyValue<std::array<float, 2>>> fillTranslate; + style::Transitionable<PropertyValue<TranslateAnchorType>> fillTranslateAnchor; + style::Transitionable<PropertyValue<std::string>> fillPattern; + + Unevaluated transitioned(const TransitionParameters&, Unevaluated&& prior) const; + Unevaluated untransitioned() const; + + bool hasDataDrivenPropertyDifference(const Transitionable& other) const; + }; +}; + } // namespace style } // namespace mbgl diff --git a/src/mbgl/style/layers/heatmap_layer.cpp b/src/mbgl/style/layers/heatmap_layer.cpp index df0055813..a82eceb02 100644 --- a/src/mbgl/style/layers/heatmap_layer.cpp +++ b/src/mbgl/style/layers/heatmap_layer.cpp @@ -108,26 +108,26 @@ PropertyValue<float> HeatmapLayer::getDefaultHeatmapRadius() { } PropertyValue<float> HeatmapLayer::getHeatmapRadius() const { - return impl().paint.template get<HeatmapRadius>().value; + return impl().paint.heatmapRadius.value; } void HeatmapLayer::setHeatmapRadius(PropertyValue<float> value) { if (value == getHeatmapRadius()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<HeatmapRadius>().value = value; + impl_->paint.heatmapRadius.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void HeatmapLayer::setHeatmapRadiusTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<HeatmapRadius>().options = options; + impl_->paint.heatmapRadius.options = options; baseImpl = std::move(impl_); } TransitionOptions HeatmapLayer::getHeatmapRadiusTransition() const { - return impl().paint.template get<HeatmapRadius>().options; + return impl().paint.heatmapRadius.options; } PropertyValue<float> HeatmapLayer::getDefaultHeatmapWeight() { @@ -135,26 +135,26 @@ PropertyValue<float> HeatmapLayer::getDefaultHeatmapWeight() { } PropertyValue<float> HeatmapLayer::getHeatmapWeight() const { - return impl().paint.template get<HeatmapWeight>().value; + return impl().paint.heatmapWeight.value; } void HeatmapLayer::setHeatmapWeight(PropertyValue<float> value) { if (value == getHeatmapWeight()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<HeatmapWeight>().value = value; + impl_->paint.heatmapWeight.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void HeatmapLayer::setHeatmapWeightTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<HeatmapWeight>().options = options; + impl_->paint.heatmapWeight.options = options; baseImpl = std::move(impl_); } TransitionOptions HeatmapLayer::getHeatmapWeightTransition() const { - return impl().paint.template get<HeatmapWeight>().options; + return impl().paint.heatmapWeight.options; } PropertyValue<float> HeatmapLayer::getDefaultHeatmapIntensity() { @@ -162,26 +162,26 @@ PropertyValue<float> HeatmapLayer::getDefaultHeatmapIntensity() { } PropertyValue<float> HeatmapLayer::getHeatmapIntensity() const { - return impl().paint.template get<HeatmapIntensity>().value; + return impl().paint.heatmapIntensity.value; } void HeatmapLayer::setHeatmapIntensity(PropertyValue<float> value) { if (value == getHeatmapIntensity()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<HeatmapIntensity>().value = value; + impl_->paint.heatmapIntensity.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void HeatmapLayer::setHeatmapIntensityTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<HeatmapIntensity>().options = options; + impl_->paint.heatmapIntensity.options = options; baseImpl = std::move(impl_); } TransitionOptions HeatmapLayer::getHeatmapIntensityTransition() const { - return impl().paint.template get<HeatmapIntensity>().options; + return impl().paint.heatmapIntensity.options; } ColorRampPropertyValue HeatmapLayer::getDefaultHeatmapColor() { @@ -191,26 +191,26 @@ ColorRampPropertyValue HeatmapLayer::getDefaultHeatmapColor() { } ColorRampPropertyValue HeatmapLayer::getHeatmapColor() const { - return impl().paint.template get<HeatmapColor>().value; + return impl().paint.heatmapColor.value; } void HeatmapLayer::setHeatmapColor(ColorRampPropertyValue value) { if (value == getHeatmapColor()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<HeatmapColor>().value = value; + impl_->paint.heatmapColor.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void HeatmapLayer::setHeatmapColorTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<HeatmapColor>().options = options; + impl_->paint.heatmapColor.options = options; baseImpl = std::move(impl_); } TransitionOptions HeatmapLayer::getHeatmapColorTransition() const { - return impl().paint.template get<HeatmapColor>().options; + return impl().paint.heatmapColor.options; } PropertyValue<float> HeatmapLayer::getDefaultHeatmapOpacity() { @@ -218,26 +218,26 @@ PropertyValue<float> HeatmapLayer::getDefaultHeatmapOpacity() { } PropertyValue<float> HeatmapLayer::getHeatmapOpacity() const { - return impl().paint.template get<HeatmapOpacity>().value; + return impl().paint.heatmapOpacity.value; } void HeatmapLayer::setHeatmapOpacity(PropertyValue<float> value) { if (value == getHeatmapOpacity()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<HeatmapOpacity>().value = value; + impl_->paint.heatmapOpacity.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void HeatmapLayer::setHeatmapOpacityTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<HeatmapOpacity>().options = options; + impl_->paint.heatmapOpacity.options = options; baseImpl = std::move(impl_); } TransitionOptions HeatmapLayer::getHeatmapOpacityTransition() const { - return impl().paint.template get<HeatmapOpacity>().options; + return impl().paint.heatmapOpacity.options; } using namespace conversion; diff --git a/src/mbgl/style/layers/heatmap_layer_properties.cpp b/src/mbgl/style/layers/heatmap_layer_properties.cpp index 2edb83958..947749a5a 100644 --- a/src/mbgl/style/layers/heatmap_layer_properties.cpp +++ b/src/mbgl/style/layers/heatmap_layer_properties.cpp @@ -5,5 +5,115 @@ namespace mbgl { namespace style { +HeatmapPaintProperties::Unevaluated HeatmapPaintProperties::Transitionable::transitioned(const TransitionParameters& parameters, Unevaluated&& prior) const { + return Unevaluated { + heatmapRadius.transition(parameters, std::move(prior.heatmapRadius)), + heatmapWeight.transition(parameters, std::move(prior.heatmapWeight)), + heatmapIntensity.transition(parameters, std::move(prior.heatmapIntensity)), + heatmapColor.transition(parameters, std::move(prior.heatmapColor)), + heatmapOpacity.transition(parameters, std::move(prior.heatmapOpacity)), + }; +} + +HeatmapPaintProperties::Unevaluated HeatmapPaintProperties::Transitionable::untransitioned() const { + return Unevaluated { + Transitioning<PropertyValue<float>>(heatmapRadius.value), + Transitioning<PropertyValue<float>>(heatmapWeight.value), + Transitioning<PropertyValue<float>>(heatmapIntensity.value), + Transitioning<ColorRampPropertyValue>(heatmapColor.value), + Transitioning<PropertyValue<float>>(heatmapOpacity.value), + }; +} + +bool HeatmapPaintProperties::Transitionable::hasDataDrivenPropertyDifference(const Transitionable& other) const { + return false + || heatmapRadius.value.hasDataDrivenPropertyDifference(other.heatmapRadius.value) + || heatmapWeight.value.hasDataDrivenPropertyDifference(other.heatmapWeight.value) + || heatmapIntensity.value.hasDataDrivenPropertyDifference(other.heatmapIntensity.value) + || heatmapColor.value.hasDataDrivenPropertyDifference(other.heatmapColor.value) + || heatmapOpacity.value.hasDataDrivenPropertyDifference(other.heatmapOpacity.value) + ; +} + +bool HeatmapPaintProperties::Unevaluated::hasTransition() const { + return false + || heatmapRadius.hasTransition() + || heatmapWeight.hasTransition() + || heatmapIntensity.hasTransition() + || heatmapColor.hasTransition() + || heatmapOpacity.hasTransition() + ; +} + +HeatmapPaintProperties::PossiblyEvaluated HeatmapPaintProperties::Unevaluated::evaluate(const PropertyEvaluationParameters& parameters) const { + return PossiblyEvaluated { + heatmapRadius.evaluate(typename HeatmapRadius::EvaluatorType(parameters, HeatmapRadius::defaultValue()), parameters.now), + heatmapWeight.evaluate(typename HeatmapWeight::EvaluatorType(parameters, HeatmapWeight::defaultValue()), parameters.now), + heatmapIntensity.evaluate(typename HeatmapIntensity::EvaluatorType(parameters, HeatmapIntensity::defaultValue()), parameters.now), + heatmapColor.evaluate(typename HeatmapColor::EvaluatorType(parameters, HeatmapColor::defaultValue()), parameters.now), + heatmapOpacity.evaluate(typename HeatmapOpacity::EvaluatorType(parameters, HeatmapOpacity::defaultValue()), parameters.now), + }; +} + +HeatmapPaintProperties::Binders HeatmapPaintProperties::PossiblyEvaluated::createBinders(float z) const { + return Binders { + PaintPropertyBinder<float, typename attributes::a_radius::Type>::create(heatmapRadius, z, HeatmapRadius::defaultValue()), + PaintPropertyBinder<float, typename attributes::a_weight::Type>::create(heatmapWeight, z, HeatmapWeight::defaultValue()), + }; +} + +std::bitset<8> HeatmapPaintProperties::PossiblyEvaluated::constants() const { + std::bitset<8> result; + result.set(0, heatmapRadius.isConstant()); + result.set(1, heatmapWeight.isConstant()); + return result; +} + +std::vector<std::string> HeatmapPaintProperties::PossiblyEvaluated::defines() const { + std::vector<std::string> result; + result.push_back(heatmapRadius.isConstant() + ? std::string("#define HAS_UNIFORM_") + HeatmapRadius::Uniform::name() + : std::string()); + result.push_back(heatmapWeight.isConstant() + ? std::string("#define HAS_UNIFORM_") + HeatmapWeight::Uniform::name() + : std::string()); + return result; +} + +void HeatmapPaintProperties::Binders::populateVertexVectors(const GeometryTileFeature& feature, std::size_t length) { + heatmapRadius->populateVertexVector(feature, length); + heatmapWeight->populateVertexVector(feature, length); +} + +void HeatmapPaintProperties::Binders::upload(gl::Context& context) { + heatmapRadius->upload(context); + heatmapWeight->upload(context); +} + +HeatmapPaintProperties::Binders::AttributeBindings HeatmapPaintProperties::Binders::attributeBindings(const PossiblyEvaluated& currentProperties) const { + return AttributeBindings { + heatmapRadius->attributeBinding(currentProperties.heatmapRadius), + heatmapWeight->attributeBinding(currentProperties.heatmapWeight), + }; +} + +HeatmapPaintProperties::Binders::UniformValues HeatmapPaintProperties::Binders::uniformValues(float currentZoom, const PossiblyEvaluated& currentProperties) const { + return UniformValues { + typename InterpolationUniform<attributes::a_radius>::Value { + heatmapRadius->interpolationFactor(currentZoom) + }, + typename InterpolationUniform<attributes::a_weight>::Value { + heatmapWeight->interpolationFactor(currentZoom) + }, + typename uniforms::u_radius::Value { + heatmapRadius->uniformValue(currentProperties.heatmapRadius) + }, + typename uniforms::u_weight::Value { + heatmapWeight->uniformValue(currentProperties.heatmapWeight) + }, + }; +} + + } // namespace style } // namespace mbgl diff --git a/src/mbgl/style/layers/heatmap_layer_properties.hpp b/src/mbgl/style/layers/heatmap_layer_properties.hpp index 4d49a52c7..02627e0b4 100644 --- a/src/mbgl/style/layers/heatmap_layer_properties.hpp +++ b/src/mbgl/style/layers/heatmap_layer_properties.hpp @@ -31,13 +31,78 @@ struct HeatmapOpacity : PaintProperty<float> { static float defaultValue() { return 1; } }; -class HeatmapPaintProperties : public Properties< - HeatmapRadius, - HeatmapWeight, - HeatmapIntensity, - HeatmapColor, - HeatmapOpacity -> {}; +class HeatmapPaintProperties { +public: + class PossiblyEvaluated; + + class Binders { + public: + std::unique_ptr<PaintPropertyBinder<float, typename attributes::a_radius::Type>> heatmapRadius; + std::unique_ptr<PaintPropertyBinder<float, typename attributes::a_weight::Type>> heatmapWeight; + + void populateVertexVectors(const GeometryTileFeature&, std::size_t length); + void upload(gl::Context&); + + using Attributes = gl::Attributes< + ZoomInterpolatedAttribute<attributes::a_radius>, + ZoomInterpolatedAttribute<attributes::a_weight> + >; + + using Uniforms = gl::Uniforms< + InterpolationUniform<attributes::a_radius>, + InterpolationUniform<attributes::a_weight>, + uniforms::u_radius, + uniforms::u_weight + >; + + using AttributeBindings = typename Attributes::Bindings; + using UniformValues = typename Uniforms::Values; + + AttributeBindings attributeBindings(const PossiblyEvaluated&) const; + UniformValues uniformValues(float z, const PossiblyEvaluated&) const; + }; + + class PossiblyEvaluated { + public: + PossiblyEvaluatedPropertyValue<float> heatmapRadius; + PossiblyEvaluatedPropertyValue<float> heatmapWeight; + float heatmapIntensity; + Color heatmapColor; + float heatmapOpacity; + + Binders createBinders(float z) const; + + std::bitset<8> constants() const; + std::vector<std::string> defines() const; + }; + + class Unevaluated { + public: + style::Transitioning<PropertyValue<float>> heatmapRadius; + style::Transitioning<PropertyValue<float>> heatmapWeight; + style::Transitioning<PropertyValue<float>> heatmapIntensity; + style::Transitioning<ColorRampPropertyValue> heatmapColor; + style::Transitioning<PropertyValue<float>> heatmapOpacity; + + bool hasTransition() const; + PossiblyEvaluated evaluate(const PropertyEvaluationParameters&) const; + }; + + class Transitionable { + public: + style::Transitionable<PropertyValue<float>> heatmapRadius; + style::Transitionable<PropertyValue<float>> heatmapWeight; + style::Transitionable<PropertyValue<float>> heatmapIntensity; + style::Transitionable<ColorRampPropertyValue> heatmapColor; + style::Transitionable<PropertyValue<float>> heatmapOpacity; + + Unevaluated transitioned(const TransitionParameters&, Unevaluated&& prior) const; + Unevaluated untransitioned() const; + + bool hasDataDrivenPropertyDifference(const Transitionable& other) const; + }; +}; + } // namespace style } // namespace mbgl diff --git a/src/mbgl/style/layers/hillshade_layer.cpp b/src/mbgl/style/layers/hillshade_layer.cpp index fb96c681c..fa61bba31 100644 --- a/src/mbgl/style/layers/hillshade_layer.cpp +++ b/src/mbgl/style/layers/hillshade_layer.cpp @@ -86,26 +86,26 @@ PropertyValue<float> HillshadeLayer::getDefaultHillshadeIlluminationDirection() } PropertyValue<float> HillshadeLayer::getHillshadeIlluminationDirection() const { - return impl().paint.template get<HillshadeIlluminationDirection>().value; + return impl().paint.hillshadeIlluminationDirection.value; } void HillshadeLayer::setHillshadeIlluminationDirection(PropertyValue<float> value) { if (value == getHillshadeIlluminationDirection()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<HillshadeIlluminationDirection>().value = value; + impl_->paint.hillshadeIlluminationDirection.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void HillshadeLayer::setHillshadeIlluminationDirectionTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<HillshadeIlluminationDirection>().options = options; + impl_->paint.hillshadeIlluminationDirection.options = options; baseImpl = std::move(impl_); } TransitionOptions HillshadeLayer::getHillshadeIlluminationDirectionTransition() const { - return impl().paint.template get<HillshadeIlluminationDirection>().options; + return impl().paint.hillshadeIlluminationDirection.options; } PropertyValue<HillshadeIlluminationAnchorType> HillshadeLayer::getDefaultHillshadeIlluminationAnchor() { @@ -113,26 +113,26 @@ PropertyValue<HillshadeIlluminationAnchorType> HillshadeLayer::getDefaultHillsha } PropertyValue<HillshadeIlluminationAnchorType> HillshadeLayer::getHillshadeIlluminationAnchor() const { - return impl().paint.template get<HillshadeIlluminationAnchor>().value; + return impl().paint.hillshadeIlluminationAnchor.value; } void HillshadeLayer::setHillshadeIlluminationAnchor(PropertyValue<HillshadeIlluminationAnchorType> value) { if (value == getHillshadeIlluminationAnchor()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<HillshadeIlluminationAnchor>().value = value; + impl_->paint.hillshadeIlluminationAnchor.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void HillshadeLayer::setHillshadeIlluminationAnchorTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<HillshadeIlluminationAnchor>().options = options; + impl_->paint.hillshadeIlluminationAnchor.options = options; baseImpl = std::move(impl_); } TransitionOptions HillshadeLayer::getHillshadeIlluminationAnchorTransition() const { - return impl().paint.template get<HillshadeIlluminationAnchor>().options; + return impl().paint.hillshadeIlluminationAnchor.options; } PropertyValue<float> HillshadeLayer::getDefaultHillshadeExaggeration() { @@ -140,26 +140,26 @@ PropertyValue<float> HillshadeLayer::getDefaultHillshadeExaggeration() { } PropertyValue<float> HillshadeLayer::getHillshadeExaggeration() const { - return impl().paint.template get<HillshadeExaggeration>().value; + return impl().paint.hillshadeExaggeration.value; } void HillshadeLayer::setHillshadeExaggeration(PropertyValue<float> value) { if (value == getHillshadeExaggeration()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<HillshadeExaggeration>().value = value; + impl_->paint.hillshadeExaggeration.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void HillshadeLayer::setHillshadeExaggerationTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<HillshadeExaggeration>().options = options; + impl_->paint.hillshadeExaggeration.options = options; baseImpl = std::move(impl_); } TransitionOptions HillshadeLayer::getHillshadeExaggerationTransition() const { - return impl().paint.template get<HillshadeExaggeration>().options; + return impl().paint.hillshadeExaggeration.options; } PropertyValue<Color> HillshadeLayer::getDefaultHillshadeShadowColor() { @@ -167,26 +167,26 @@ PropertyValue<Color> HillshadeLayer::getDefaultHillshadeShadowColor() { } PropertyValue<Color> HillshadeLayer::getHillshadeShadowColor() const { - return impl().paint.template get<HillshadeShadowColor>().value; + return impl().paint.hillshadeShadowColor.value; } void HillshadeLayer::setHillshadeShadowColor(PropertyValue<Color> value) { if (value == getHillshadeShadowColor()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<HillshadeShadowColor>().value = value; + impl_->paint.hillshadeShadowColor.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void HillshadeLayer::setHillshadeShadowColorTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<HillshadeShadowColor>().options = options; + impl_->paint.hillshadeShadowColor.options = options; baseImpl = std::move(impl_); } TransitionOptions HillshadeLayer::getHillshadeShadowColorTransition() const { - return impl().paint.template get<HillshadeShadowColor>().options; + return impl().paint.hillshadeShadowColor.options; } PropertyValue<Color> HillshadeLayer::getDefaultHillshadeHighlightColor() { @@ -194,26 +194,26 @@ PropertyValue<Color> HillshadeLayer::getDefaultHillshadeHighlightColor() { } PropertyValue<Color> HillshadeLayer::getHillshadeHighlightColor() const { - return impl().paint.template get<HillshadeHighlightColor>().value; + return impl().paint.hillshadeHighlightColor.value; } void HillshadeLayer::setHillshadeHighlightColor(PropertyValue<Color> value) { if (value == getHillshadeHighlightColor()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<HillshadeHighlightColor>().value = value; + impl_->paint.hillshadeHighlightColor.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void HillshadeLayer::setHillshadeHighlightColorTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<HillshadeHighlightColor>().options = options; + impl_->paint.hillshadeHighlightColor.options = options; baseImpl = std::move(impl_); } TransitionOptions HillshadeLayer::getHillshadeHighlightColorTransition() const { - return impl().paint.template get<HillshadeHighlightColor>().options; + return impl().paint.hillshadeHighlightColor.options; } PropertyValue<Color> HillshadeLayer::getDefaultHillshadeAccentColor() { @@ -221,26 +221,26 @@ PropertyValue<Color> HillshadeLayer::getDefaultHillshadeAccentColor() { } PropertyValue<Color> HillshadeLayer::getHillshadeAccentColor() const { - return impl().paint.template get<HillshadeAccentColor>().value; + return impl().paint.hillshadeAccentColor.value; } void HillshadeLayer::setHillshadeAccentColor(PropertyValue<Color> value) { if (value == getHillshadeAccentColor()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<HillshadeAccentColor>().value = value; + impl_->paint.hillshadeAccentColor.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void HillshadeLayer::setHillshadeAccentColorTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<HillshadeAccentColor>().options = options; + impl_->paint.hillshadeAccentColor.options = options; baseImpl = std::move(impl_); } TransitionOptions HillshadeLayer::getHillshadeAccentColorTransition() const { - return impl().paint.template get<HillshadeAccentColor>().options; + return impl().paint.hillshadeAccentColor.options; } using namespace conversion; diff --git a/src/mbgl/style/layers/hillshade_layer_properties.cpp b/src/mbgl/style/layers/hillshade_layer_properties.cpp index f296ab452..c51e557d6 100644 --- a/src/mbgl/style/layers/hillshade_layer_properties.cpp +++ b/src/mbgl/style/layers/hillshade_layer_properties.cpp @@ -5,5 +5,62 @@ namespace mbgl { namespace style { +HillshadePaintProperties::Unevaluated HillshadePaintProperties::Transitionable::transitioned(const TransitionParameters& parameters, Unevaluated&& prior) const { + return Unevaluated { + hillshadeIlluminationDirection.transition(parameters, std::move(prior.hillshadeIlluminationDirection)), + hillshadeIlluminationAnchor.transition(parameters, std::move(prior.hillshadeIlluminationAnchor)), + hillshadeExaggeration.transition(parameters, std::move(prior.hillshadeExaggeration)), + hillshadeShadowColor.transition(parameters, std::move(prior.hillshadeShadowColor)), + hillshadeHighlightColor.transition(parameters, std::move(prior.hillshadeHighlightColor)), + hillshadeAccentColor.transition(parameters, std::move(prior.hillshadeAccentColor)), + }; +} + +HillshadePaintProperties::Unevaluated HillshadePaintProperties::Transitionable::untransitioned() const { + return Unevaluated { + Transitioning<PropertyValue<float>>(hillshadeIlluminationDirection.value), + Transitioning<PropertyValue<HillshadeIlluminationAnchorType>>(hillshadeIlluminationAnchor.value), + Transitioning<PropertyValue<float>>(hillshadeExaggeration.value), + Transitioning<PropertyValue<Color>>(hillshadeShadowColor.value), + Transitioning<PropertyValue<Color>>(hillshadeHighlightColor.value), + Transitioning<PropertyValue<Color>>(hillshadeAccentColor.value), + }; +} + +bool HillshadePaintProperties::Transitionable::hasDataDrivenPropertyDifference(const Transitionable& other) const { + return false + || hillshadeIlluminationDirection.value.hasDataDrivenPropertyDifference(other.hillshadeIlluminationDirection.value) + || hillshadeIlluminationAnchor.value.hasDataDrivenPropertyDifference(other.hillshadeIlluminationAnchor.value) + || hillshadeExaggeration.value.hasDataDrivenPropertyDifference(other.hillshadeExaggeration.value) + || hillshadeShadowColor.value.hasDataDrivenPropertyDifference(other.hillshadeShadowColor.value) + || hillshadeHighlightColor.value.hasDataDrivenPropertyDifference(other.hillshadeHighlightColor.value) + || hillshadeAccentColor.value.hasDataDrivenPropertyDifference(other.hillshadeAccentColor.value) + ; +} + +bool HillshadePaintProperties::Unevaluated::hasTransition() const { + return false + || hillshadeIlluminationDirection.hasTransition() + || hillshadeIlluminationAnchor.hasTransition() + || hillshadeExaggeration.hasTransition() + || hillshadeShadowColor.hasTransition() + || hillshadeHighlightColor.hasTransition() + || hillshadeAccentColor.hasTransition() + ; +} + +HillshadePaintProperties::PossiblyEvaluated HillshadePaintProperties::Unevaluated::evaluate(const PropertyEvaluationParameters& parameters) const { + return PossiblyEvaluated { + hillshadeIlluminationDirection.evaluate(typename HillshadeIlluminationDirection::EvaluatorType(parameters, HillshadeIlluminationDirection::defaultValue()), parameters.now), + hillshadeIlluminationAnchor.evaluate(typename HillshadeIlluminationAnchor::EvaluatorType(parameters, HillshadeIlluminationAnchor::defaultValue()), parameters.now), + hillshadeExaggeration.evaluate(typename HillshadeExaggeration::EvaluatorType(parameters, HillshadeExaggeration::defaultValue()), parameters.now), + hillshadeShadowColor.evaluate(typename HillshadeShadowColor::EvaluatorType(parameters, HillshadeShadowColor::defaultValue()), parameters.now), + hillshadeHighlightColor.evaluate(typename HillshadeHighlightColor::EvaluatorType(parameters, HillshadeHighlightColor::defaultValue()), parameters.now), + hillshadeAccentColor.evaluate(typename HillshadeAccentColor::EvaluatorType(parameters, HillshadeAccentColor::defaultValue()), parameters.now), + }; +} + + + } // namespace style } // namespace mbgl diff --git a/src/mbgl/style/layers/hillshade_layer_properties.hpp b/src/mbgl/style/layers/hillshade_layer_properties.hpp index 260d7ea80..df54c5a38 100644 --- a/src/mbgl/style/layers/hillshade_layer_properties.hpp +++ b/src/mbgl/style/layers/hillshade_layer_properties.hpp @@ -36,14 +36,48 @@ struct HillshadeAccentColor : PaintProperty<Color> { static Color defaultValue() { return Color::black(); } }; -class HillshadePaintProperties : public Properties< - HillshadeIlluminationDirection, - HillshadeIlluminationAnchor, - HillshadeExaggeration, - HillshadeShadowColor, - HillshadeHighlightColor, - HillshadeAccentColor -> {}; +class HillshadePaintProperties { +public: + + class PossiblyEvaluated { + public: + float hillshadeIlluminationDirection; + HillshadeIlluminationAnchorType hillshadeIlluminationAnchor; + float hillshadeExaggeration; + Color hillshadeShadowColor; + Color hillshadeHighlightColor; + Color hillshadeAccentColor; + }; + + class Unevaluated { + public: + style::Transitioning<PropertyValue<float>> hillshadeIlluminationDirection; + style::Transitioning<PropertyValue<HillshadeIlluminationAnchorType>> hillshadeIlluminationAnchor; + style::Transitioning<PropertyValue<float>> hillshadeExaggeration; + style::Transitioning<PropertyValue<Color>> hillshadeShadowColor; + style::Transitioning<PropertyValue<Color>> hillshadeHighlightColor; + style::Transitioning<PropertyValue<Color>> hillshadeAccentColor; + + bool hasTransition() const; + PossiblyEvaluated evaluate(const PropertyEvaluationParameters&) const; + }; + + class Transitionable { + public: + style::Transitionable<PropertyValue<float>> hillshadeIlluminationDirection; + style::Transitionable<PropertyValue<HillshadeIlluminationAnchorType>> hillshadeIlluminationAnchor; + style::Transitionable<PropertyValue<float>> hillshadeExaggeration; + style::Transitionable<PropertyValue<Color>> hillshadeShadowColor; + style::Transitionable<PropertyValue<Color>> hillshadeHighlightColor; + style::Transitionable<PropertyValue<Color>> hillshadeAccentColor; + + Unevaluated transitioned(const TransitionParameters&, Unevaluated&& prior) const; + Unevaluated untransitioned() const; + + bool hasDataDrivenPropertyDifference(const Transitionable& other) const; + }; +}; + } // namespace style } // namespace mbgl diff --git a/src/mbgl/style/layers/layer.cpp.ejs b/src/mbgl/style/layers/layer.cpp.ejs index 4e80a7bf7..8094f7695 100644 --- a/src/mbgl/style/layers/layer.cpp.ejs +++ b/src/mbgl/style/layers/layer.cpp.ejs @@ -52,7 +52,11 @@ std::unique_ptr<Layer> <%- camelize(type) %>Layer::cloneRef(const std::string& i <% if (layoutProperties.length) { -%> void <%- camelize(type) %>Layer::Impl::stringifyLayout(rapidjson::Writer<rapidjson::StringBuffer>& writer) const { - layout.stringify(writer); + writer.StartObject(); +<% for (const property of layoutProperties) { -%> + conversion::stringify<<%- camelize(property.name) %>>(writer, layout.<%- camelizeWithLeadingLowercase(property.name) %>); +<% } -%> + writer.EndObject(); } <% } else { -%> void <%- camelize(type) %>Layer::Impl::stringifyLayout(rapidjson::Writer<rapidjson::StringBuffer>&) const { @@ -127,14 +131,14 @@ void <%- camelize(type) %>Layer::setMaxZoom(float maxZoom) { } <%- propertyValueType(property) %> <%- camelize(type) %>Layer::get<%- camelize(property.name) %>() const { - return impl().layout.get<<%- camelize(property.name) %>>(); + return impl().layout.<%- camelizeWithLeadingLowercase(property.name) %>; } void <%- camelize(type) %>Layer::set<%- camelize(property.name) %>(<%- propertyValueType(property) %> value) { if (value == get<%- camelize(property.name) %>()) return; auto impl_ = mutableImpl(); - impl_->layout.get<<%- camelize(property.name) %>>() = value; + impl_->layout.<%- camelizeWithLeadingLowercase(property.name) %> = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } @@ -153,26 +157,26 @@ void <%- camelize(type) %>Layer::set<%- camelize(property.name) %>(<%- propertyV } <%- propertyValueType(property) %> <%- camelize(type) %>Layer::get<%- camelize(property.name) %>() const { - return impl().paint.template get<<%- camelize(property.name) %>>().value; + return impl().paint.<%- camelizeWithLeadingLowercase(property.name) %>.value; } void <%- camelize(type) %>Layer::set<%- camelize(property.name) %>(<%- propertyValueType(property) %> value) { if (value == get<%- camelize(property.name) %>()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<<%- camelize(property.name) %>>().value = value; + impl_->paint.<%- camelizeWithLeadingLowercase(property.name) %>.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void <%- camelize(type) %>Layer::set<%- camelize(property.name) %>Transition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<<%- camelize(property.name) %>>().options = options; + impl_->paint.<%- camelizeWithLeadingLowercase(property.name) %>.options = options; baseImpl = std::move(impl_); } TransitionOptions <%- camelize(type) %>Layer::get<%- camelize(property.name) %>Transition() const { - return impl().paint.template get<<%- camelize(property.name) %>>().options; + return impl().paint.<%- camelizeWithLeadingLowercase(property.name) %>.options; } <% } -%> diff --git a/src/mbgl/style/layers/layer_properties.cpp.ejs b/src/mbgl/style/layers/layer_properties.cpp.ejs index e5523e543..5b3e3a9e6 100644 --- a/src/mbgl/style/layers/layer_properties.cpp.ejs +++ b/src/mbgl/style/layers/layer_properties.cpp.ejs @@ -10,5 +10,207 @@ namespace mbgl { namespace style { +<% if (layoutProperties.length) { -%> +bool operator==(const <%- camelize(type) %>LayoutProperties::Unevaluated& lhs, const <%- camelize(type) %>LayoutProperties::Unevaluated& rhs) { + return true +<% for (const property of layoutProperties) { -%> + && lhs.<%- camelizeWithLeadingLowercase(property.name) %> == rhs.<%- camelizeWithLeadingLowercase(property.name) %> +<% } -%> + ; +} + +<%- camelize(type) %>LayoutProperties::PossiblyEvaluated <%- camelize(type) %>LayoutProperties::Unevaluated::evaluate(const PropertyEvaluationParameters& parameters) const { + return PossiblyEvaluated { +<% for (const property of layoutProperties) { -%> + <%- camelizeWithLeadingLowercase(property.name) %>.evaluate(typename <%- camelize(property.name) %>::EvaluatorType(parameters, <%- camelize(property.name) %>::defaultValue()), parameters.now), +<% } -%> + }; +} + +<%- camelize(type) %>LayoutProperties::Evaluated <%- camelize(type) %>LayoutProperties::PossiblyEvaluated::evaluate(float z, const GeometryTileFeature& feature) const { + return Evaluated { +<% for (const property of layoutProperties) { -%> +<% if (isDataDriven(property)) { -%> + <%- camelizeWithLeadingLowercase(property.name) %>.evaluate(feature, z, <%- camelize(property.name) %>::defaultValue()), +<% } else { -%> + <%- camelizeWithLeadingLowercase(property.name) %>, +<% } -%> +<% } -%> + }; +} + +<% } -%> +<%- camelize(type) %>PaintProperties::Unevaluated <%- camelize(type) %>PaintProperties::Transitionable::transitioned(const TransitionParameters& parameters, Unevaluated&& prior) const { + return Unevaluated { +<% for (const property of paintProperties) { -%> + <%- camelizeWithLeadingLowercase(property.name) %>.transition(parameters, std::move(prior.<%- camelizeWithLeadingLowercase(property.name) %>)), +<% } -%> + }; +} + +<%- camelize(type) %>PaintProperties::Unevaluated <%- camelize(type) %>PaintProperties::Transitionable::untransitioned() const { + return Unevaluated { +<% for (const property of paintProperties) { -%> + Transitioning<<%- propertyValueType(property) %>>(<%- camelizeWithLeadingLowercase(property.name) %>.value), +<% } -%> + }; +} + +bool <%- camelize(type) %>PaintProperties::Transitionable::hasDataDrivenPropertyDifference(const Transitionable& other) const { + return false +<% for (const property of paintProperties) { -%> + || <%- camelizeWithLeadingLowercase(property.name) %>.value.hasDataDrivenPropertyDifference(other.<%- camelizeWithLeadingLowercase(property.name) %>.value) +<% } -%> + ; +} + +bool <%- camelize(type) %>PaintProperties::Unevaluated::hasTransition() const { + return false +<% for (const property of paintProperties) { -%> + || <%- camelizeWithLeadingLowercase(property.name) %>.hasTransition() +<% } -%> + ; +} + +<%- camelize(type) %>PaintProperties::PossiblyEvaluated <%- camelize(type) %>PaintProperties::Unevaluated::evaluate(const PropertyEvaluationParameters& parameters) const { + return PossiblyEvaluated { +<% for (const property of paintProperties) { -%> + <%- camelizeWithLeadingLowercase(property.name) %>.evaluate(typename <%- camelize(property.name) %>::EvaluatorType(parameters, <%- camelize(property.name) %>::defaultValue()), parameters.now), +<% } -%> + }; +} + +<% if (type !== "symbol" && type !== "background" && type !== "raster" && type !== "hillshade") { -%> +<%- camelize(type) %>PaintProperties::Binders <%- camelize(type) %>PaintProperties::PossiblyEvaluated::createBinders(float z) const { + return Binders { +<% for (const property of paintProperties.filter(isDataDriven)) { -%> + PaintPropertyBinder<<%- evaluatedType(property) %>, typename <%- attributeType(property, type) %>::Type>::create(<%- camelizeWithLeadingLowercase(property.name) %>, z, <%- camelize(property.name) %>::defaultValue()), +<% } -%> + }; +} + +std::bitset<8> <%- camelize(type) %>PaintProperties::PossiblyEvaluated::constants() const { + std::bitset<8> result; +<% for (let i = 0; i < paintProperties.filter(isDataDriven).length; i++) { -%> + result.set(<%- i %>, <%- camelizeWithLeadingLowercase(paintProperties.filter(isDataDriven)[i].name) %>.isConstant()); +<% } -%> + return result; +} + +std::vector<std::string> <%- camelize(type) %>PaintProperties::PossiblyEvaluated::defines() const { + std::vector<std::string> result; +<% for (const property of paintProperties.filter(isDataDriven)) { -%> + result.push_back(<%- camelizeWithLeadingLowercase(property.name) %>.isConstant() + ? std::string("#define HAS_UNIFORM_") + <%- camelize(property.name) %>::Uniform::name() + : std::string()); +<% } -%> + return result; +} + +void <%- camelize(type) %>PaintProperties::Binders::populateVertexVectors(const GeometryTileFeature& feature, std::size_t length) { +<% for (const property of paintProperties.filter(isDataDriven)) { -%> + <%- camelizeWithLeadingLowercase(property.name) %>->populateVertexVector(feature, length); +<% } -%> +} + +void <%- camelize(type) %>PaintProperties::Binders::upload(gl::Context& context) { +<% for (const property of paintProperties.filter(isDataDriven)) { -%> + <%- camelizeWithLeadingLowercase(property.name) %>->upload(context); +<% } -%> +} + +<%- camelize(type) %>PaintProperties::Binders::AttributeBindings <%- camelize(type) %>PaintProperties::Binders::attributeBindings(const PossiblyEvaluated& currentProperties) const { + return AttributeBindings { +<% for (const property of paintProperties.filter(isDataDriven)) { -%> + <%- camelizeWithLeadingLowercase(property.name) %>->attributeBinding(currentProperties.<%- camelizeWithLeadingLowercase(property.name) %>), +<% } -%> + }; +} + +<%- camelize(type) %>PaintProperties::Binders::UniformValues <%- camelize(type) %>PaintProperties::Binders::uniformValues(float currentZoom, const PossiblyEvaluated& currentProperties) const { + return UniformValues { +<% for (const property of paintProperties.filter(isDataDriven)) { -%> + typename InterpolationUniform<<%- attributeType(property, type) %>>::Value { + <%- camelizeWithLeadingLowercase(property.name) %>->interpolationFactor(currentZoom) + }, +<% } -%> +<% for (const property of paintProperties.filter(isDataDriven)) { -%> + typename <%- uniformType(property, type) %>::Value { + <%- camelizeWithLeadingLowercase(property.name) %>->uniformValue(currentProperties.<%- camelizeWithLeadingLowercase(property.name) %>) + }, +<% } -%> + }; +} +<% } -%> + +<% if (type === "symbol") { -%> +<% for (const subtype of ['icon', 'text']) { + const properties = paintProperties.filter(({name}) => name.startsWith(`${subtype}-`)); +%> + +<%- camelize(subtype) %>PaintProperties::Binders <%- camelize(subtype) %>PaintProperties::PossiblyEvaluated::createBinders(float z) const { + return Binders { +<% for (const property of properties.filter(isDataDriven)) { -%> + PaintPropertyBinder<<%- evaluatedType(property) %>, typename <%- attributeType(property, type) %>::Type>::create(<%- camelizeWithLeadingLowercase(property.name) %>, z, <%- camelize(property.name) %>::defaultValue()), +<% } -%> + }; +} + +std::bitset<8> <%- camelize(subtype) %>PaintProperties::PossiblyEvaluated::constants() const { + std::bitset<8> result; +<% for (let i = 0; i < properties.filter(isDataDriven).length; i++) { -%> + result.set(<%- i %>, <%- camelizeWithLeadingLowercase(properties.filter(isDataDriven)[i].name) %>.isConstant()); +<% } -%> + return result; +} + +std::vector<std::string> <%- camelize(subtype) %>PaintProperties::PossiblyEvaluated::defines() const { + std::vector<std::string> result; +<% for (const property of properties.filter(isDataDriven)) { -%> + result.push_back(<%- camelizeWithLeadingLowercase(property.name) %>.isConstant() + ? std::string("#define HAS_UNIFORM_") + <%- camelize(property.name) %>::Uniform::name() + : std::string()); +<% } -%> + return result; +} + +void <%- camelize(subtype) %>PaintProperties::Binders::populateVertexVectors(const GeometryTileFeature& feature, std::size_t length) { +<% for (const property of properties.filter(isDataDriven)) { -%> + <%- camelizeWithLeadingLowercase(property.name) %>->populateVertexVector(feature, length); +<% } -%> +} + +void <%- camelize(subtype) %>PaintProperties::Binders::upload(gl::Context& context) { +<% for (const property of properties.filter(isDataDriven)) { -%> + <%- camelizeWithLeadingLowercase(property.name) %>->upload(context); +<% } -%> +} + +<%- camelize(subtype) %>PaintProperties::Binders::AttributeBindings <%- camelize(subtype) %>PaintProperties::Binders::attributeBindings(const PossiblyEvaluated& currentProperties) const { + return AttributeBindings { +<% for (const property of properties.filter(isDataDriven)) { -%> + <%- camelizeWithLeadingLowercase(property.name) %>->attributeBinding(currentProperties.<%- camelizeWithLeadingLowercase(property.name) %>), +<% } -%> + }; +} + +<%- camelize(subtype) %>PaintProperties::Binders::UniformValues <%- camelize(subtype) %>PaintProperties::Binders::uniformValues(float currentZoom, const PossiblyEvaluated& currentProperties) const { + return UniformValues { +<% for (const property of properties.filter(isDataDriven)) { -%> + typename InterpolationUniform<<%- attributeType(property, type) %>>::Value { + <%- camelizeWithLeadingLowercase(property.name) %>->interpolationFactor(currentZoom) + }, +<% } -%> +<% for (const property of properties.filter(isDataDriven)) { -%> + typename <%- uniformType(property, type) %>::Value { + <%- camelizeWithLeadingLowercase(property.name) %>->uniformValue(currentProperties.<%- camelizeWithLeadingLowercase(property.name) %>) + }, +<% } -%> + }; +} + +<% } -%> +<% } -%> + } // namespace style } // namespace mbgl diff --git a/src/mbgl/style/layers/layer_properties.hpp.ejs b/src/mbgl/style/layers/layer_properties.hpp.ejs index 694d9a62b..c1b404bd6 100644 --- a/src/mbgl/style/layers/layer_properties.hpp.ejs +++ b/src/mbgl/style/layers/layer_properties.hpp.ejs @@ -36,20 +36,158 @@ struct <%- camelize(property.name) %> : <%- paintPropertyType(property, type) %> <% } -%> <% if (layoutProperties.length) { -%> -class <%- camelize(type) %>LayoutProperties : public Properties< -<% for (const property of layoutProperties.slice(0, -1)) { -%> - <%- camelize(property.name) %>, +class <%- camelize(type) %>LayoutProperties { +public: + class Evaluated { + public: +<% for (const property of layoutProperties) { -%> + <%- evaluatedType(property) %> <%- camelizeWithLeadingLowercase(property.name) %>; +<% } -%> + }; + + class PossiblyEvaluated { + public: +<% for (const property of layoutProperties) { -%> + <%- possiblyEvaluatedType(property) %> <%- camelizeWithLeadingLowercase(property.name) %>; +<% } -%> + + Evaluated evaluate(float z, const GeometryTileFeature& feature) const; + }; + + class Unevaluated { + public: +<% for (const property of layoutProperties) { -%> + <%- propertyValueType(property) %> <%- camelizeWithLeadingLowercase(property.name) %>; +<% } -%> + + PossiblyEvaluated evaluate(const PropertyEvaluationParameters&) const; + + friend bool operator==(const Unevaluated&, const Unevaluated&); + friend inline bool operator!=(const Unevaluated& lhs, const Unevaluated& rhs) { return !(lhs == rhs); } + }; +}; + <% } -%> - <%- camelize(layoutProperties.slice(-1)[0].name) %> -> {}; +class <%- camelize(type) %>PaintProperties { +public: +<% if (type !== "symbol" && type !== "background" && type !== "raster" && type !== "hillshade") { -%> + class PossiblyEvaluated; + + class Binders { + public: +<% for (const property of paintProperties.filter(isDataDriven)) { -%> + std::unique_ptr<PaintPropertyBinder<<%- evaluatedType(property) %>, typename <%- attributeType(property, type) %>::Type>> <%- camelizeWithLeadingLowercase(property.name) %>; +<% } -%> + + void populateVertexVectors(const GeometryTileFeature&, std::size_t length); + void upload(gl::Context&); + + using Attributes = gl::Attributes< + <%- paintProperties.filter(isDataDriven).map(property => `ZoomInterpolatedAttribute<${attributeType(property, type)}>`).join(',\n ') %> + >; + + using Uniforms = gl::Uniforms< + <%- paintProperties.filter(isDataDriven).map(property => `InterpolationUniform<${attributeType(property, type)}>`) + .concat(paintProperties.filter(isDataDriven).map(property => uniformType(property, type))).join(',\n ') %> + >; + + using AttributeBindings = typename Attributes::Bindings; + using UniformValues = typename Uniforms::Values; + + AttributeBindings attributeBindings(const PossiblyEvaluated&) const; + UniformValues uniformValues(float z, const PossiblyEvaluated&) const; + }; +<% } -%> + + class PossiblyEvaluated { + public: +<% for (const property of paintProperties) { -%> + <%- possiblyEvaluatedType(property) %> <%- camelizeWithLeadingLowercase(property.name) %>; +<% } -%> +<% if (type !== "symbol" && type !== "background" && type !== "raster" && type !== "hillshade") { -%> + + Binders createBinders(float z) const; + + std::bitset<8> constants() const; + std::vector<std::string> defines() const; +<% } -%> + }; + + class Unevaluated { + public: +<% for (const property of paintProperties) { -%> + style::Transitioning<<%- propertyValueType(property) %>> <%- camelizeWithLeadingLowercase(property.name) %>; +<% } -%> + + bool hasTransition() const; + PossiblyEvaluated evaluate(const PropertyEvaluationParameters&) const; + }; + + class Transitionable { + public: +<% for (const property of paintProperties) { -%> + style::Transitionable<<%- propertyValueType(property) %>> <%- camelizeWithLeadingLowercase(property.name) %>; +<% } -%> + + Unevaluated transitioned(const TransitionParameters&, Unevaluated&& prior) const; + Unevaluated untransitioned() const; + + bool hasDataDrivenPropertyDifference(const Transitionable& other) const; + }; +}; + +<% if (type === "symbol") { -%> +// {icon,text}-specific paint-property packs for use in the symbol Programs. +// Since each program deals either with icons or text, using a smaller property set +// lets us avoid unnecessarily binding attributes for properties the program wouldn't use. + +<% for (const subtype of ['icon', 'text']) { + const properties = paintProperties.filter(({name}) => name.startsWith(`${subtype}-`)); +%> +class <%- camelize(subtype) %>PaintProperties { +public: + class PossiblyEvaluated; + + class Binders { + public: +<% for (const property of properties.filter(isDataDriven)) { -%> + std::unique_ptr<PaintPropertyBinder<<%- evaluatedType(property) %>, typename <%- attributeType(property, type) %>::Type>> <%- camelizeWithLeadingLowercase(property.name) %>; +<% } -%> + + void populateVertexVectors(const GeometryTileFeature&, std::size_t length); + void upload(gl::Context&); + + using Attributes = gl::Attributes< + <%- properties.filter(isDataDriven).map(property => `ZoomInterpolatedAttribute<${attributeType(property, type)}>`).join(',\n ') %> + >; + + using Uniforms = gl::Uniforms< + <%- properties.filter(isDataDriven).map(property => `InterpolationUniform<${attributeType(property, type)}>`).join(',\n ') %>, + <%- properties.filter(isDataDriven).map(property => uniformType(property, type)).join(',\n ') %> + >; + + using AttributeBindings = typename Attributes::Bindings; + using UniformValues = typename Uniforms::Values; + + AttributeBindings attributeBindings(const PossiblyEvaluated&) const; + UniformValues uniformValues(float z, const PossiblyEvaluated&) const; + }; + + class PossiblyEvaluated { + public: +<% for (const property of properties) { -%> + <%- possiblyEvaluatedType(property) %> <%- camelizeWithLeadingLowercase(property.name) %>; +<% } -%> + + Binders createBinders(float z) const; + + std::bitset<8> constants() const; + std::vector<std::string> defines() const; + }; +}; <% } -%> -class <%- camelize(type) %>PaintProperties : public Properties< -<% for (const property of paintProperties.slice(0, -1)) { -%> - <%- camelize(property.name) %>, <% } -%> - <%- camelize(paintProperties.slice(-1)[0].name) %> -> {}; } // namespace style } // namespace mbgl diff --git a/src/mbgl/style/layers/line_layer.cpp b/src/mbgl/style/layers/line_layer.cpp index c744adad9..4354fe9f0 100644 --- a/src/mbgl/style/layers/line_layer.cpp +++ b/src/mbgl/style/layers/line_layer.cpp @@ -40,7 +40,12 @@ std::unique_ptr<Layer> LineLayer::cloneRef(const std::string& id_) const { } void LineLayer::Impl::stringifyLayout(rapidjson::Writer<rapidjson::StringBuffer>& writer) const { - layout.stringify(writer); + writer.StartObject(); + conversion::stringify<LineCap>(writer, layout.lineCap); + conversion::stringify<LineJoin>(writer, layout.lineJoin); + conversion::stringify<LineMiterLimit>(writer, layout.lineMiterLimit); + conversion::stringify<LineRoundLimit>(writer, layout.lineRoundLimit); + writer.EndObject(); } // Source @@ -106,14 +111,14 @@ PropertyValue<LineCapType> LineLayer::getDefaultLineCap() { } PropertyValue<LineCapType> LineLayer::getLineCap() const { - return impl().layout.get<LineCap>(); + return impl().layout.lineCap; } void LineLayer::setLineCap(PropertyValue<LineCapType> value) { if (value == getLineCap()) return; auto impl_ = mutableImpl(); - impl_->layout.get<LineCap>() = value; + impl_->layout.lineCap = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } @@ -122,14 +127,14 @@ PropertyValue<LineJoinType> LineLayer::getDefaultLineJoin() { } PropertyValue<LineJoinType> LineLayer::getLineJoin() const { - return impl().layout.get<LineJoin>(); + return impl().layout.lineJoin; } void LineLayer::setLineJoin(PropertyValue<LineJoinType> value) { if (value == getLineJoin()) return; auto impl_ = mutableImpl(); - impl_->layout.get<LineJoin>() = value; + impl_->layout.lineJoin = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } @@ -138,14 +143,14 @@ PropertyValue<float> LineLayer::getDefaultLineMiterLimit() { } PropertyValue<float> LineLayer::getLineMiterLimit() const { - return impl().layout.get<LineMiterLimit>(); + return impl().layout.lineMiterLimit; } void LineLayer::setLineMiterLimit(PropertyValue<float> value) { if (value == getLineMiterLimit()) return; auto impl_ = mutableImpl(); - impl_->layout.get<LineMiterLimit>() = value; + impl_->layout.lineMiterLimit = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } @@ -154,14 +159,14 @@ PropertyValue<float> LineLayer::getDefaultLineRoundLimit() { } PropertyValue<float> LineLayer::getLineRoundLimit() const { - return impl().layout.get<LineRoundLimit>(); + return impl().layout.lineRoundLimit; } void LineLayer::setLineRoundLimit(PropertyValue<float> value) { if (value == getLineRoundLimit()) return; auto impl_ = mutableImpl(); - impl_->layout.get<LineRoundLimit>() = value; + impl_->layout.lineRoundLimit = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } @@ -173,26 +178,26 @@ PropertyValue<float> LineLayer::getDefaultLineOpacity() { } PropertyValue<float> LineLayer::getLineOpacity() const { - return impl().paint.template get<LineOpacity>().value; + return impl().paint.lineOpacity.value; } void LineLayer::setLineOpacity(PropertyValue<float> value) { if (value == getLineOpacity()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<LineOpacity>().value = value; + impl_->paint.lineOpacity.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void LineLayer::setLineOpacityTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<LineOpacity>().options = options; + impl_->paint.lineOpacity.options = options; baseImpl = std::move(impl_); } TransitionOptions LineLayer::getLineOpacityTransition() const { - return impl().paint.template get<LineOpacity>().options; + return impl().paint.lineOpacity.options; } PropertyValue<Color> LineLayer::getDefaultLineColor() { @@ -200,26 +205,26 @@ PropertyValue<Color> LineLayer::getDefaultLineColor() { } PropertyValue<Color> LineLayer::getLineColor() const { - return impl().paint.template get<LineColor>().value; + return impl().paint.lineColor.value; } void LineLayer::setLineColor(PropertyValue<Color> value) { if (value == getLineColor()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<LineColor>().value = value; + impl_->paint.lineColor.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void LineLayer::setLineColorTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<LineColor>().options = options; + impl_->paint.lineColor.options = options; baseImpl = std::move(impl_); } TransitionOptions LineLayer::getLineColorTransition() const { - return impl().paint.template get<LineColor>().options; + return impl().paint.lineColor.options; } PropertyValue<std::array<float, 2>> LineLayer::getDefaultLineTranslate() { @@ -227,26 +232,26 @@ PropertyValue<std::array<float, 2>> LineLayer::getDefaultLineTranslate() { } PropertyValue<std::array<float, 2>> LineLayer::getLineTranslate() const { - return impl().paint.template get<LineTranslate>().value; + return impl().paint.lineTranslate.value; } void LineLayer::setLineTranslate(PropertyValue<std::array<float, 2>> value) { if (value == getLineTranslate()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<LineTranslate>().value = value; + impl_->paint.lineTranslate.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void LineLayer::setLineTranslateTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<LineTranslate>().options = options; + impl_->paint.lineTranslate.options = options; baseImpl = std::move(impl_); } TransitionOptions LineLayer::getLineTranslateTransition() const { - return impl().paint.template get<LineTranslate>().options; + return impl().paint.lineTranslate.options; } PropertyValue<TranslateAnchorType> LineLayer::getDefaultLineTranslateAnchor() { @@ -254,26 +259,26 @@ PropertyValue<TranslateAnchorType> LineLayer::getDefaultLineTranslateAnchor() { } PropertyValue<TranslateAnchorType> LineLayer::getLineTranslateAnchor() const { - return impl().paint.template get<LineTranslateAnchor>().value; + return impl().paint.lineTranslateAnchor.value; } void LineLayer::setLineTranslateAnchor(PropertyValue<TranslateAnchorType> value) { if (value == getLineTranslateAnchor()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<LineTranslateAnchor>().value = value; + impl_->paint.lineTranslateAnchor.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void LineLayer::setLineTranslateAnchorTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<LineTranslateAnchor>().options = options; + impl_->paint.lineTranslateAnchor.options = options; baseImpl = std::move(impl_); } TransitionOptions LineLayer::getLineTranslateAnchorTransition() const { - return impl().paint.template get<LineTranslateAnchor>().options; + return impl().paint.lineTranslateAnchor.options; } PropertyValue<float> LineLayer::getDefaultLineWidth() { @@ -281,26 +286,26 @@ PropertyValue<float> LineLayer::getDefaultLineWidth() { } PropertyValue<float> LineLayer::getLineWidth() const { - return impl().paint.template get<LineWidth>().value; + return impl().paint.lineWidth.value; } void LineLayer::setLineWidth(PropertyValue<float> value) { if (value == getLineWidth()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<LineWidth>().value = value; + impl_->paint.lineWidth.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void LineLayer::setLineWidthTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<LineWidth>().options = options; + impl_->paint.lineWidth.options = options; baseImpl = std::move(impl_); } TransitionOptions LineLayer::getLineWidthTransition() const { - return impl().paint.template get<LineWidth>().options; + return impl().paint.lineWidth.options; } PropertyValue<float> LineLayer::getDefaultLineGapWidth() { @@ -308,26 +313,26 @@ PropertyValue<float> LineLayer::getDefaultLineGapWidth() { } PropertyValue<float> LineLayer::getLineGapWidth() const { - return impl().paint.template get<LineGapWidth>().value; + return impl().paint.lineGapWidth.value; } void LineLayer::setLineGapWidth(PropertyValue<float> value) { if (value == getLineGapWidth()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<LineGapWidth>().value = value; + impl_->paint.lineGapWidth.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void LineLayer::setLineGapWidthTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<LineGapWidth>().options = options; + impl_->paint.lineGapWidth.options = options; baseImpl = std::move(impl_); } TransitionOptions LineLayer::getLineGapWidthTransition() const { - return impl().paint.template get<LineGapWidth>().options; + return impl().paint.lineGapWidth.options; } PropertyValue<float> LineLayer::getDefaultLineOffset() { @@ -335,26 +340,26 @@ PropertyValue<float> LineLayer::getDefaultLineOffset() { } PropertyValue<float> LineLayer::getLineOffset() const { - return impl().paint.template get<LineOffset>().value; + return impl().paint.lineOffset.value; } void LineLayer::setLineOffset(PropertyValue<float> value) { if (value == getLineOffset()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<LineOffset>().value = value; + impl_->paint.lineOffset.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void LineLayer::setLineOffsetTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<LineOffset>().options = options; + impl_->paint.lineOffset.options = options; baseImpl = std::move(impl_); } TransitionOptions LineLayer::getLineOffsetTransition() const { - return impl().paint.template get<LineOffset>().options; + return impl().paint.lineOffset.options; } PropertyValue<float> LineLayer::getDefaultLineBlur() { @@ -362,26 +367,26 @@ PropertyValue<float> LineLayer::getDefaultLineBlur() { } PropertyValue<float> LineLayer::getLineBlur() const { - return impl().paint.template get<LineBlur>().value; + return impl().paint.lineBlur.value; } void LineLayer::setLineBlur(PropertyValue<float> value) { if (value == getLineBlur()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<LineBlur>().value = value; + impl_->paint.lineBlur.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void LineLayer::setLineBlurTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<LineBlur>().options = options; + impl_->paint.lineBlur.options = options; baseImpl = std::move(impl_); } TransitionOptions LineLayer::getLineBlurTransition() const { - return impl().paint.template get<LineBlur>().options; + return impl().paint.lineBlur.options; } PropertyValue<std::vector<float>> LineLayer::getDefaultLineDasharray() { @@ -389,26 +394,26 @@ PropertyValue<std::vector<float>> LineLayer::getDefaultLineDasharray() { } PropertyValue<std::vector<float>> LineLayer::getLineDasharray() const { - return impl().paint.template get<LineDasharray>().value; + return impl().paint.lineDasharray.value; } void LineLayer::setLineDasharray(PropertyValue<std::vector<float>> value) { if (value == getLineDasharray()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<LineDasharray>().value = value; + impl_->paint.lineDasharray.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void LineLayer::setLineDasharrayTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<LineDasharray>().options = options; + impl_->paint.lineDasharray.options = options; baseImpl = std::move(impl_); } TransitionOptions LineLayer::getLineDasharrayTransition() const { - return impl().paint.template get<LineDasharray>().options; + return impl().paint.lineDasharray.options; } PropertyValue<std::string> LineLayer::getDefaultLinePattern() { @@ -416,26 +421,26 @@ PropertyValue<std::string> LineLayer::getDefaultLinePattern() { } PropertyValue<std::string> LineLayer::getLinePattern() const { - return impl().paint.template get<LinePattern>().value; + return impl().paint.linePattern.value; } void LineLayer::setLinePattern(PropertyValue<std::string> value) { if (value == getLinePattern()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<LinePattern>().value = value; + impl_->paint.linePattern.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void LineLayer::setLinePatternTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<LinePattern>().options = options; + impl_->paint.linePattern.options = options; baseImpl = std::move(impl_); } TransitionOptions LineLayer::getLinePatternTransition() const { - return impl().paint.template get<LinePattern>().options; + return impl().paint.linePattern.options; } using namespace conversion; diff --git a/src/mbgl/style/layers/line_layer_properties.cpp b/src/mbgl/style/layers/line_layer_properties.cpp index 174239bcc..169b571fb 100644 --- a/src/mbgl/style/layers/line_layer_properties.cpp +++ b/src/mbgl/style/layers/line_layer_properties.cpp @@ -5,5 +5,223 @@ namespace mbgl { namespace style { +bool operator==(const LineLayoutProperties::Unevaluated& lhs, const LineLayoutProperties::Unevaluated& rhs) { + return true + && lhs.lineCap == rhs.lineCap + && lhs.lineJoin == rhs.lineJoin + && lhs.lineMiterLimit == rhs.lineMiterLimit + && lhs.lineRoundLimit == rhs.lineRoundLimit + ; +} + +LineLayoutProperties::PossiblyEvaluated LineLayoutProperties::Unevaluated::evaluate(const PropertyEvaluationParameters& parameters) const { + return PossiblyEvaluated { + lineCap.evaluate(typename LineCap::EvaluatorType(parameters, LineCap::defaultValue()), parameters.now), + lineJoin.evaluate(typename LineJoin::EvaluatorType(parameters, LineJoin::defaultValue()), parameters.now), + lineMiterLimit.evaluate(typename LineMiterLimit::EvaluatorType(parameters, LineMiterLimit::defaultValue()), parameters.now), + lineRoundLimit.evaluate(typename LineRoundLimit::EvaluatorType(parameters, LineRoundLimit::defaultValue()), parameters.now), + }; +} + +LineLayoutProperties::Evaluated LineLayoutProperties::PossiblyEvaluated::evaluate(float z, const GeometryTileFeature& feature) const { + return Evaluated { + lineCap, + lineJoin.evaluate(feature, z, LineJoin::defaultValue()), + lineMiterLimit, + lineRoundLimit, + }; +} + +LinePaintProperties::Unevaluated LinePaintProperties::Transitionable::transitioned(const TransitionParameters& parameters, Unevaluated&& prior) const { + return Unevaluated { + lineOpacity.transition(parameters, std::move(prior.lineOpacity)), + lineColor.transition(parameters, std::move(prior.lineColor)), + lineTranslate.transition(parameters, std::move(prior.lineTranslate)), + lineTranslateAnchor.transition(parameters, std::move(prior.lineTranslateAnchor)), + lineWidth.transition(parameters, std::move(prior.lineWidth)), + lineGapWidth.transition(parameters, std::move(prior.lineGapWidth)), + lineOffset.transition(parameters, std::move(prior.lineOffset)), + lineBlur.transition(parameters, std::move(prior.lineBlur)), + lineDasharray.transition(parameters, std::move(prior.lineDasharray)), + linePattern.transition(parameters, std::move(prior.linePattern)), + }; +} + +LinePaintProperties::Unevaluated LinePaintProperties::Transitionable::untransitioned() const { + return Unevaluated { + Transitioning<PropertyValue<float>>(lineOpacity.value), + Transitioning<PropertyValue<Color>>(lineColor.value), + Transitioning<PropertyValue<std::array<float, 2>>>(lineTranslate.value), + Transitioning<PropertyValue<TranslateAnchorType>>(lineTranslateAnchor.value), + Transitioning<PropertyValue<float>>(lineWidth.value), + Transitioning<PropertyValue<float>>(lineGapWidth.value), + Transitioning<PropertyValue<float>>(lineOffset.value), + Transitioning<PropertyValue<float>>(lineBlur.value), + Transitioning<PropertyValue<std::vector<float>>>(lineDasharray.value), + Transitioning<PropertyValue<std::string>>(linePattern.value), + }; +} + +bool LinePaintProperties::Transitionable::hasDataDrivenPropertyDifference(const Transitionable& other) const { + return false + || lineOpacity.value.hasDataDrivenPropertyDifference(other.lineOpacity.value) + || lineColor.value.hasDataDrivenPropertyDifference(other.lineColor.value) + || lineTranslate.value.hasDataDrivenPropertyDifference(other.lineTranslate.value) + || lineTranslateAnchor.value.hasDataDrivenPropertyDifference(other.lineTranslateAnchor.value) + || lineWidth.value.hasDataDrivenPropertyDifference(other.lineWidth.value) + || lineGapWidth.value.hasDataDrivenPropertyDifference(other.lineGapWidth.value) + || lineOffset.value.hasDataDrivenPropertyDifference(other.lineOffset.value) + || lineBlur.value.hasDataDrivenPropertyDifference(other.lineBlur.value) + || lineDasharray.value.hasDataDrivenPropertyDifference(other.lineDasharray.value) + || linePattern.value.hasDataDrivenPropertyDifference(other.linePattern.value) + ; +} + +bool LinePaintProperties::Unevaluated::hasTransition() const { + return false + || lineOpacity.hasTransition() + || lineColor.hasTransition() + || lineTranslate.hasTransition() + || lineTranslateAnchor.hasTransition() + || lineWidth.hasTransition() + || lineGapWidth.hasTransition() + || lineOffset.hasTransition() + || lineBlur.hasTransition() + || lineDasharray.hasTransition() + || linePattern.hasTransition() + ; +} + +LinePaintProperties::PossiblyEvaluated LinePaintProperties::Unevaluated::evaluate(const PropertyEvaluationParameters& parameters) const { + return PossiblyEvaluated { + lineOpacity.evaluate(typename LineOpacity::EvaluatorType(parameters, LineOpacity::defaultValue()), parameters.now), + lineColor.evaluate(typename LineColor::EvaluatorType(parameters, LineColor::defaultValue()), parameters.now), + lineTranslate.evaluate(typename LineTranslate::EvaluatorType(parameters, LineTranslate::defaultValue()), parameters.now), + lineTranslateAnchor.evaluate(typename LineTranslateAnchor::EvaluatorType(parameters, LineTranslateAnchor::defaultValue()), parameters.now), + lineWidth.evaluate(typename LineWidth::EvaluatorType(parameters, LineWidth::defaultValue()), parameters.now), + lineGapWidth.evaluate(typename LineGapWidth::EvaluatorType(parameters, LineGapWidth::defaultValue()), parameters.now), + lineOffset.evaluate(typename LineOffset::EvaluatorType(parameters, LineOffset::defaultValue()), parameters.now), + lineBlur.evaluate(typename LineBlur::EvaluatorType(parameters, LineBlur::defaultValue()), parameters.now), + lineDasharray.evaluate(typename LineDasharray::EvaluatorType(parameters, LineDasharray::defaultValue()), parameters.now), + linePattern.evaluate(typename LinePattern::EvaluatorType(parameters, LinePattern::defaultValue()), parameters.now), + }; +} + +LinePaintProperties::Binders LinePaintProperties::PossiblyEvaluated::createBinders(float z) const { + return Binders { + PaintPropertyBinder<float, typename attributes::a_opacity::Type>::create(lineOpacity, z, LineOpacity::defaultValue()), + PaintPropertyBinder<Color, typename attributes::a_color::Type>::create(lineColor, z, LineColor::defaultValue()), + PaintPropertyBinder<float, typename attributes::a_width::Type>::create(lineWidth, z, LineWidth::defaultValue()), + PaintPropertyBinder<float, typename attributes::a_gapwidth::Type>::create(lineGapWidth, z, LineGapWidth::defaultValue()), + PaintPropertyBinder<float, typename attributes::a_offset<1>::Type>::create(lineOffset, z, LineOffset::defaultValue()), + PaintPropertyBinder<float, typename attributes::a_blur::Type>::create(lineBlur, z, LineBlur::defaultValue()), + }; +} + +std::bitset<8> LinePaintProperties::PossiblyEvaluated::constants() const { + std::bitset<8> result; + result.set(0, lineOpacity.isConstant()); + result.set(1, lineColor.isConstant()); + result.set(2, lineWidth.isConstant()); + result.set(3, lineGapWidth.isConstant()); + result.set(4, lineOffset.isConstant()); + result.set(5, lineBlur.isConstant()); + return result; +} + +std::vector<std::string> LinePaintProperties::PossiblyEvaluated::defines() const { + std::vector<std::string> result; + result.push_back(lineOpacity.isConstant() + ? std::string("#define HAS_UNIFORM_") + LineOpacity::Uniform::name() + : std::string()); + result.push_back(lineColor.isConstant() + ? std::string("#define HAS_UNIFORM_") + LineColor::Uniform::name() + : std::string()); + result.push_back(lineWidth.isConstant() + ? std::string("#define HAS_UNIFORM_") + LineWidth::Uniform::name() + : std::string()); + result.push_back(lineGapWidth.isConstant() + ? std::string("#define HAS_UNIFORM_") + LineGapWidth::Uniform::name() + : std::string()); + result.push_back(lineOffset.isConstant() + ? std::string("#define HAS_UNIFORM_") + LineOffset::Uniform::name() + : std::string()); + result.push_back(lineBlur.isConstant() + ? std::string("#define HAS_UNIFORM_") + LineBlur::Uniform::name() + : std::string()); + return result; +} + +void LinePaintProperties::Binders::populateVertexVectors(const GeometryTileFeature& feature, std::size_t length) { + lineOpacity->populateVertexVector(feature, length); + lineColor->populateVertexVector(feature, length); + lineWidth->populateVertexVector(feature, length); + lineGapWidth->populateVertexVector(feature, length); + lineOffset->populateVertexVector(feature, length); + lineBlur->populateVertexVector(feature, length); +} + +void LinePaintProperties::Binders::upload(gl::Context& context) { + lineOpacity->upload(context); + lineColor->upload(context); + lineWidth->upload(context); + lineGapWidth->upload(context); + lineOffset->upload(context); + lineBlur->upload(context); +} + +LinePaintProperties::Binders::AttributeBindings LinePaintProperties::Binders::attributeBindings(const PossiblyEvaluated& currentProperties) const { + return AttributeBindings { + lineOpacity->attributeBinding(currentProperties.lineOpacity), + lineColor->attributeBinding(currentProperties.lineColor), + lineWidth->attributeBinding(currentProperties.lineWidth), + lineGapWidth->attributeBinding(currentProperties.lineGapWidth), + lineOffset->attributeBinding(currentProperties.lineOffset), + lineBlur->attributeBinding(currentProperties.lineBlur), + }; +} + +LinePaintProperties::Binders::UniformValues LinePaintProperties::Binders::uniformValues(float currentZoom, const PossiblyEvaluated& currentProperties) const { + return UniformValues { + typename InterpolationUniform<attributes::a_opacity>::Value { + lineOpacity->interpolationFactor(currentZoom) + }, + typename InterpolationUniform<attributes::a_color>::Value { + lineColor->interpolationFactor(currentZoom) + }, + typename InterpolationUniform<attributes::a_width>::Value { + lineWidth->interpolationFactor(currentZoom) + }, + typename InterpolationUniform<attributes::a_gapwidth>::Value { + lineGapWidth->interpolationFactor(currentZoom) + }, + typename InterpolationUniform<attributes::a_offset<1>>::Value { + lineOffset->interpolationFactor(currentZoom) + }, + typename InterpolationUniform<attributes::a_blur>::Value { + lineBlur->interpolationFactor(currentZoom) + }, + typename uniforms::u_opacity::Value { + lineOpacity->uniformValue(currentProperties.lineOpacity) + }, + typename uniforms::u_color::Value { + lineColor->uniformValue(currentProperties.lineColor) + }, + typename uniforms::u_width::Value { + lineWidth->uniformValue(currentProperties.lineWidth) + }, + typename uniforms::u_gapwidth::Value { + lineGapWidth->uniformValue(currentProperties.lineGapWidth) + }, + typename uniforms::u_offset::Value { + lineOffset->uniformValue(currentProperties.lineOffset) + }, + typename uniforms::u_blur::Value { + lineBlur->uniformValue(currentProperties.lineBlur) + }, + }; +} + + } // namespace style } // namespace mbgl diff --git a/src/mbgl/style/layers/line_layer_properties.hpp b/src/mbgl/style/layers/line_layer_properties.hpp index aeaf51698..f65499d9d 100644 --- a/src/mbgl/style/layers/line_layer_properties.hpp +++ b/src/mbgl/style/layers/line_layer_properties.hpp @@ -72,25 +72,143 @@ struct LinePattern : CrossFadedPaintProperty<std::string> { static std::string defaultValue() { return ""; } }; -class LineLayoutProperties : public Properties< - LineCap, - LineJoin, - LineMiterLimit, - LineRoundLimit -> {}; - -class LinePaintProperties : public Properties< - LineOpacity, - LineColor, - LineTranslate, - LineTranslateAnchor, - LineWidth, - LineGapWidth, - LineOffset, - LineBlur, - LineDasharray, - LinePattern -> {}; +class LineLayoutProperties { +public: + class Evaluated { + public: + LineCapType lineCap; + LineJoinType lineJoin; + float lineMiterLimit; + float lineRoundLimit; + }; + + class PossiblyEvaluated { + public: + LineCapType lineCap; + PossiblyEvaluatedPropertyValue<LineJoinType> lineJoin; + float lineMiterLimit; + float lineRoundLimit; + + Evaluated evaluate(float z, const GeometryTileFeature& feature) const; + }; + + class Unevaluated { + public: + PropertyValue<LineCapType> lineCap; + PropertyValue<LineJoinType> lineJoin; + PropertyValue<float> lineMiterLimit; + PropertyValue<float> lineRoundLimit; + + PossiblyEvaluated evaluate(const PropertyEvaluationParameters&) const; + + friend bool operator==(const Unevaluated&, const Unevaluated&); + friend inline bool operator!=(const Unevaluated& lhs, const Unevaluated& rhs) { return !(lhs == rhs); } + }; +}; + +class LinePaintProperties { +public: + class PossiblyEvaluated; + + class Binders { + public: + std::unique_ptr<PaintPropertyBinder<float, typename attributes::a_opacity::Type>> lineOpacity; + std::unique_ptr<PaintPropertyBinder<Color, typename attributes::a_color::Type>> lineColor; + std::unique_ptr<PaintPropertyBinder<float, typename attributes::a_width::Type>> lineWidth; + std::unique_ptr<PaintPropertyBinder<float, typename attributes::a_gapwidth::Type>> lineGapWidth; + std::unique_ptr<PaintPropertyBinder<float, typename attributes::a_offset<1>::Type>> lineOffset; + std::unique_ptr<PaintPropertyBinder<float, typename attributes::a_blur::Type>> lineBlur; + + void populateVertexVectors(const GeometryTileFeature&, std::size_t length); + void upload(gl::Context&); + + using Attributes = gl::Attributes< + ZoomInterpolatedAttribute<attributes::a_opacity>, + ZoomInterpolatedAttribute<attributes::a_color>, + ZoomInterpolatedAttribute<attributes::a_width>, + ZoomInterpolatedAttribute<attributes::a_gapwidth>, + ZoomInterpolatedAttribute<attributes::a_offset<1>>, + ZoomInterpolatedAttribute<attributes::a_blur> + >; + + using Uniforms = gl::Uniforms< + InterpolationUniform<attributes::a_opacity>, + InterpolationUniform<attributes::a_color>, + InterpolationUniform<attributes::a_width>, + InterpolationUniform<attributes::a_gapwidth>, + InterpolationUniform<attributes::a_offset<1>>, + InterpolationUniform<attributes::a_blur>, + uniforms::u_opacity, + uniforms::u_color, + uniforms::u_width, + uniforms::u_gapwidth, + uniforms::u_offset, + uniforms::u_blur + >; + + using AttributeBindings = typename Attributes::Bindings; + using UniformValues = typename Uniforms::Values; + + AttributeBindings attributeBindings(const PossiblyEvaluated&) const; + UniformValues uniformValues(float z, const PossiblyEvaluated&) const; + }; + + class PossiblyEvaluated { + public: + PossiblyEvaluatedPropertyValue<float> lineOpacity; + PossiblyEvaluatedPropertyValue<Color> lineColor; + std::array<float, 2> lineTranslate; + TranslateAnchorType lineTranslateAnchor; + PossiblyEvaluatedPropertyValue<float> lineWidth; + PossiblyEvaluatedPropertyValue<float> lineGapWidth; + PossiblyEvaluatedPropertyValue<float> lineOffset; + PossiblyEvaluatedPropertyValue<float> lineBlur; + Faded<std::vector<float>> lineDasharray; + Faded<std::string> linePattern; + + Binders createBinders(float z) const; + + std::bitset<8> constants() const; + std::vector<std::string> defines() const; + }; + + class Unevaluated { + public: + style::Transitioning<PropertyValue<float>> lineOpacity; + style::Transitioning<PropertyValue<Color>> lineColor; + style::Transitioning<PropertyValue<std::array<float, 2>>> lineTranslate; + style::Transitioning<PropertyValue<TranslateAnchorType>> lineTranslateAnchor; + style::Transitioning<PropertyValue<float>> lineWidth; + style::Transitioning<PropertyValue<float>> lineGapWidth; + style::Transitioning<PropertyValue<float>> lineOffset; + style::Transitioning<PropertyValue<float>> lineBlur; + style::Transitioning<PropertyValue<std::vector<float>>> lineDasharray; + style::Transitioning<PropertyValue<std::string>> linePattern; + + bool hasTransition() const; + PossiblyEvaluated evaluate(const PropertyEvaluationParameters&) const; + }; + + class Transitionable { + public: + style::Transitionable<PropertyValue<float>> lineOpacity; + style::Transitionable<PropertyValue<Color>> lineColor; + style::Transitionable<PropertyValue<std::array<float, 2>>> lineTranslate; + style::Transitionable<PropertyValue<TranslateAnchorType>> lineTranslateAnchor; + style::Transitionable<PropertyValue<float>> lineWidth; + style::Transitionable<PropertyValue<float>> lineGapWidth; + style::Transitionable<PropertyValue<float>> lineOffset; + style::Transitionable<PropertyValue<float>> lineBlur; + style::Transitionable<PropertyValue<std::vector<float>>> lineDasharray; + style::Transitionable<PropertyValue<std::string>> linePattern; + + Unevaluated transitioned(const TransitionParameters&, Unevaluated&& prior) const; + Unevaluated untransitioned() const; + + bool hasDataDrivenPropertyDifference(const Transitionable& other) const; + }; +}; + } // namespace style } // namespace mbgl diff --git a/src/mbgl/style/layers/raster_layer.cpp b/src/mbgl/style/layers/raster_layer.cpp index 45d324083..63520b4e9 100644 --- a/src/mbgl/style/layers/raster_layer.cpp +++ b/src/mbgl/style/layers/raster_layer.cpp @@ -86,26 +86,26 @@ PropertyValue<float> RasterLayer::getDefaultRasterOpacity() { } PropertyValue<float> RasterLayer::getRasterOpacity() const { - return impl().paint.template get<RasterOpacity>().value; + return impl().paint.rasterOpacity.value; } void RasterLayer::setRasterOpacity(PropertyValue<float> value) { if (value == getRasterOpacity()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<RasterOpacity>().value = value; + impl_->paint.rasterOpacity.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void RasterLayer::setRasterOpacityTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<RasterOpacity>().options = options; + impl_->paint.rasterOpacity.options = options; baseImpl = std::move(impl_); } TransitionOptions RasterLayer::getRasterOpacityTransition() const { - return impl().paint.template get<RasterOpacity>().options; + return impl().paint.rasterOpacity.options; } PropertyValue<float> RasterLayer::getDefaultRasterHueRotate() { @@ -113,26 +113,26 @@ PropertyValue<float> RasterLayer::getDefaultRasterHueRotate() { } PropertyValue<float> RasterLayer::getRasterHueRotate() const { - return impl().paint.template get<RasterHueRotate>().value; + return impl().paint.rasterHueRotate.value; } void RasterLayer::setRasterHueRotate(PropertyValue<float> value) { if (value == getRasterHueRotate()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<RasterHueRotate>().value = value; + impl_->paint.rasterHueRotate.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void RasterLayer::setRasterHueRotateTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<RasterHueRotate>().options = options; + impl_->paint.rasterHueRotate.options = options; baseImpl = std::move(impl_); } TransitionOptions RasterLayer::getRasterHueRotateTransition() const { - return impl().paint.template get<RasterHueRotate>().options; + return impl().paint.rasterHueRotate.options; } PropertyValue<float> RasterLayer::getDefaultRasterBrightnessMin() { @@ -140,26 +140,26 @@ PropertyValue<float> RasterLayer::getDefaultRasterBrightnessMin() { } PropertyValue<float> RasterLayer::getRasterBrightnessMin() const { - return impl().paint.template get<RasterBrightnessMin>().value; + return impl().paint.rasterBrightnessMin.value; } void RasterLayer::setRasterBrightnessMin(PropertyValue<float> value) { if (value == getRasterBrightnessMin()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<RasterBrightnessMin>().value = value; + impl_->paint.rasterBrightnessMin.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void RasterLayer::setRasterBrightnessMinTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<RasterBrightnessMin>().options = options; + impl_->paint.rasterBrightnessMin.options = options; baseImpl = std::move(impl_); } TransitionOptions RasterLayer::getRasterBrightnessMinTransition() const { - return impl().paint.template get<RasterBrightnessMin>().options; + return impl().paint.rasterBrightnessMin.options; } PropertyValue<float> RasterLayer::getDefaultRasterBrightnessMax() { @@ -167,26 +167,26 @@ PropertyValue<float> RasterLayer::getDefaultRasterBrightnessMax() { } PropertyValue<float> RasterLayer::getRasterBrightnessMax() const { - return impl().paint.template get<RasterBrightnessMax>().value; + return impl().paint.rasterBrightnessMax.value; } void RasterLayer::setRasterBrightnessMax(PropertyValue<float> value) { if (value == getRasterBrightnessMax()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<RasterBrightnessMax>().value = value; + impl_->paint.rasterBrightnessMax.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void RasterLayer::setRasterBrightnessMaxTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<RasterBrightnessMax>().options = options; + impl_->paint.rasterBrightnessMax.options = options; baseImpl = std::move(impl_); } TransitionOptions RasterLayer::getRasterBrightnessMaxTransition() const { - return impl().paint.template get<RasterBrightnessMax>().options; + return impl().paint.rasterBrightnessMax.options; } PropertyValue<float> RasterLayer::getDefaultRasterSaturation() { @@ -194,26 +194,26 @@ PropertyValue<float> RasterLayer::getDefaultRasterSaturation() { } PropertyValue<float> RasterLayer::getRasterSaturation() const { - return impl().paint.template get<RasterSaturation>().value; + return impl().paint.rasterSaturation.value; } void RasterLayer::setRasterSaturation(PropertyValue<float> value) { if (value == getRasterSaturation()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<RasterSaturation>().value = value; + impl_->paint.rasterSaturation.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void RasterLayer::setRasterSaturationTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<RasterSaturation>().options = options; + impl_->paint.rasterSaturation.options = options; baseImpl = std::move(impl_); } TransitionOptions RasterLayer::getRasterSaturationTransition() const { - return impl().paint.template get<RasterSaturation>().options; + return impl().paint.rasterSaturation.options; } PropertyValue<float> RasterLayer::getDefaultRasterContrast() { @@ -221,26 +221,26 @@ PropertyValue<float> RasterLayer::getDefaultRasterContrast() { } PropertyValue<float> RasterLayer::getRasterContrast() const { - return impl().paint.template get<RasterContrast>().value; + return impl().paint.rasterContrast.value; } void RasterLayer::setRasterContrast(PropertyValue<float> value) { if (value == getRasterContrast()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<RasterContrast>().value = value; + impl_->paint.rasterContrast.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void RasterLayer::setRasterContrastTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<RasterContrast>().options = options; + impl_->paint.rasterContrast.options = options; baseImpl = std::move(impl_); } TransitionOptions RasterLayer::getRasterContrastTransition() const { - return impl().paint.template get<RasterContrast>().options; + return impl().paint.rasterContrast.options; } PropertyValue<RasterResamplingType> RasterLayer::getDefaultRasterResampling() { @@ -248,26 +248,26 @@ PropertyValue<RasterResamplingType> RasterLayer::getDefaultRasterResampling() { } PropertyValue<RasterResamplingType> RasterLayer::getRasterResampling() const { - return impl().paint.template get<RasterResampling>().value; + return impl().paint.rasterResampling.value; } void RasterLayer::setRasterResampling(PropertyValue<RasterResamplingType> value) { if (value == getRasterResampling()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<RasterResampling>().value = value; + impl_->paint.rasterResampling.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void RasterLayer::setRasterResamplingTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<RasterResampling>().options = options; + impl_->paint.rasterResampling.options = options; baseImpl = std::move(impl_); } TransitionOptions RasterLayer::getRasterResamplingTransition() const { - return impl().paint.template get<RasterResampling>().options; + return impl().paint.rasterResampling.options; } PropertyValue<float> RasterLayer::getDefaultRasterFadeDuration() { @@ -275,26 +275,26 @@ PropertyValue<float> RasterLayer::getDefaultRasterFadeDuration() { } PropertyValue<float> RasterLayer::getRasterFadeDuration() const { - return impl().paint.template get<RasterFadeDuration>().value; + return impl().paint.rasterFadeDuration.value; } void RasterLayer::setRasterFadeDuration(PropertyValue<float> value) { if (value == getRasterFadeDuration()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<RasterFadeDuration>().value = value; + impl_->paint.rasterFadeDuration.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void RasterLayer::setRasterFadeDurationTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<RasterFadeDuration>().options = options; + impl_->paint.rasterFadeDuration.options = options; baseImpl = std::move(impl_); } TransitionOptions RasterLayer::getRasterFadeDurationTransition() const { - return impl().paint.template get<RasterFadeDuration>().options; + return impl().paint.rasterFadeDuration.options; } using namespace conversion; diff --git a/src/mbgl/style/layers/raster_layer_properties.cpp b/src/mbgl/style/layers/raster_layer_properties.cpp index 303719af4..336cbe0c4 100644 --- a/src/mbgl/style/layers/raster_layer_properties.cpp +++ b/src/mbgl/style/layers/raster_layer_properties.cpp @@ -5,5 +5,72 @@ namespace mbgl { namespace style { +RasterPaintProperties::Unevaluated RasterPaintProperties::Transitionable::transitioned(const TransitionParameters& parameters, Unevaluated&& prior) const { + return Unevaluated { + rasterOpacity.transition(parameters, std::move(prior.rasterOpacity)), + rasterHueRotate.transition(parameters, std::move(prior.rasterHueRotate)), + rasterBrightnessMin.transition(parameters, std::move(prior.rasterBrightnessMin)), + rasterBrightnessMax.transition(parameters, std::move(prior.rasterBrightnessMax)), + rasterSaturation.transition(parameters, std::move(prior.rasterSaturation)), + rasterContrast.transition(parameters, std::move(prior.rasterContrast)), + rasterResampling.transition(parameters, std::move(prior.rasterResampling)), + rasterFadeDuration.transition(parameters, std::move(prior.rasterFadeDuration)), + }; +} + +RasterPaintProperties::Unevaluated RasterPaintProperties::Transitionable::untransitioned() const { + return Unevaluated { + Transitioning<PropertyValue<float>>(rasterOpacity.value), + Transitioning<PropertyValue<float>>(rasterHueRotate.value), + Transitioning<PropertyValue<float>>(rasterBrightnessMin.value), + Transitioning<PropertyValue<float>>(rasterBrightnessMax.value), + Transitioning<PropertyValue<float>>(rasterSaturation.value), + Transitioning<PropertyValue<float>>(rasterContrast.value), + Transitioning<PropertyValue<RasterResamplingType>>(rasterResampling.value), + Transitioning<PropertyValue<float>>(rasterFadeDuration.value), + }; +} + +bool RasterPaintProperties::Transitionable::hasDataDrivenPropertyDifference(const Transitionable& other) const { + return false + || rasterOpacity.value.hasDataDrivenPropertyDifference(other.rasterOpacity.value) + || rasterHueRotate.value.hasDataDrivenPropertyDifference(other.rasterHueRotate.value) + || rasterBrightnessMin.value.hasDataDrivenPropertyDifference(other.rasterBrightnessMin.value) + || rasterBrightnessMax.value.hasDataDrivenPropertyDifference(other.rasterBrightnessMax.value) + || rasterSaturation.value.hasDataDrivenPropertyDifference(other.rasterSaturation.value) + || rasterContrast.value.hasDataDrivenPropertyDifference(other.rasterContrast.value) + || rasterResampling.value.hasDataDrivenPropertyDifference(other.rasterResampling.value) + || rasterFadeDuration.value.hasDataDrivenPropertyDifference(other.rasterFadeDuration.value) + ; +} + +bool RasterPaintProperties::Unevaluated::hasTransition() const { + return false + || rasterOpacity.hasTransition() + || rasterHueRotate.hasTransition() + || rasterBrightnessMin.hasTransition() + || rasterBrightnessMax.hasTransition() + || rasterSaturation.hasTransition() + || rasterContrast.hasTransition() + || rasterResampling.hasTransition() + || rasterFadeDuration.hasTransition() + ; +} + +RasterPaintProperties::PossiblyEvaluated RasterPaintProperties::Unevaluated::evaluate(const PropertyEvaluationParameters& parameters) const { + return PossiblyEvaluated { + rasterOpacity.evaluate(typename RasterOpacity::EvaluatorType(parameters, RasterOpacity::defaultValue()), parameters.now), + rasterHueRotate.evaluate(typename RasterHueRotate::EvaluatorType(parameters, RasterHueRotate::defaultValue()), parameters.now), + rasterBrightnessMin.evaluate(typename RasterBrightnessMin::EvaluatorType(parameters, RasterBrightnessMin::defaultValue()), parameters.now), + rasterBrightnessMax.evaluate(typename RasterBrightnessMax::EvaluatorType(parameters, RasterBrightnessMax::defaultValue()), parameters.now), + rasterSaturation.evaluate(typename RasterSaturation::EvaluatorType(parameters, RasterSaturation::defaultValue()), parameters.now), + rasterContrast.evaluate(typename RasterContrast::EvaluatorType(parameters, RasterContrast::defaultValue()), parameters.now), + rasterResampling.evaluate(typename RasterResampling::EvaluatorType(parameters, RasterResampling::defaultValue()), parameters.now), + rasterFadeDuration.evaluate(typename RasterFadeDuration::EvaluatorType(parameters, RasterFadeDuration::defaultValue()), parameters.now), + }; +} + + + } // namespace style } // namespace mbgl diff --git a/src/mbgl/style/layers/raster_layer_properties.hpp b/src/mbgl/style/layers/raster_layer_properties.hpp index 08818c9fb..d43ab78a9 100644 --- a/src/mbgl/style/layers/raster_layer_properties.hpp +++ b/src/mbgl/style/layers/raster_layer_properties.hpp @@ -44,16 +44,54 @@ struct RasterFadeDuration : PaintProperty<float> { static float defaultValue() { return 300; } }; -class RasterPaintProperties : public Properties< - RasterOpacity, - RasterHueRotate, - RasterBrightnessMin, - RasterBrightnessMax, - RasterSaturation, - RasterContrast, - RasterResampling, - RasterFadeDuration -> {}; +class RasterPaintProperties { +public: + + class PossiblyEvaluated { + public: + float rasterOpacity; + float rasterHueRotate; + float rasterBrightnessMin; + float rasterBrightnessMax; + float rasterSaturation; + float rasterContrast; + RasterResamplingType rasterResampling; + float rasterFadeDuration; + }; + + class Unevaluated { + public: + style::Transitioning<PropertyValue<float>> rasterOpacity; + style::Transitioning<PropertyValue<float>> rasterHueRotate; + style::Transitioning<PropertyValue<float>> rasterBrightnessMin; + style::Transitioning<PropertyValue<float>> rasterBrightnessMax; + style::Transitioning<PropertyValue<float>> rasterSaturation; + style::Transitioning<PropertyValue<float>> rasterContrast; + style::Transitioning<PropertyValue<RasterResamplingType>> rasterResampling; + style::Transitioning<PropertyValue<float>> rasterFadeDuration; + + bool hasTransition() const; + PossiblyEvaluated evaluate(const PropertyEvaluationParameters&) const; + }; + + class Transitionable { + public: + style::Transitionable<PropertyValue<float>> rasterOpacity; + style::Transitionable<PropertyValue<float>> rasterHueRotate; + style::Transitionable<PropertyValue<float>> rasterBrightnessMin; + style::Transitionable<PropertyValue<float>> rasterBrightnessMax; + style::Transitionable<PropertyValue<float>> rasterSaturation; + style::Transitionable<PropertyValue<float>> rasterContrast; + style::Transitionable<PropertyValue<RasterResamplingType>> rasterResampling; + style::Transitionable<PropertyValue<float>> rasterFadeDuration; + + Unevaluated transitioned(const TransitionParameters&, Unevaluated&& prior) const; + Unevaluated untransitioned() const; + + bool hasDataDrivenPropertyDifference(const Transitionable& other) const; + }; +}; + } // namespace style } // namespace mbgl diff --git a/src/mbgl/style/layers/symbol_layer.cpp b/src/mbgl/style/layers/symbol_layer.cpp index 48af6b13a..9786e7a3f 100644 --- a/src/mbgl/style/layers/symbol_layer.cpp +++ b/src/mbgl/style/layers/symbol_layer.cpp @@ -40,7 +40,44 @@ std::unique_ptr<Layer> SymbolLayer::cloneRef(const std::string& id_) const { } void SymbolLayer::Impl::stringifyLayout(rapidjson::Writer<rapidjson::StringBuffer>& writer) const { - layout.stringify(writer); + writer.StartObject(); + conversion::stringify<SymbolPlacement>(writer, layout.symbolPlacement); + conversion::stringify<SymbolSpacing>(writer, layout.symbolSpacing); + conversion::stringify<SymbolAvoidEdges>(writer, layout.symbolAvoidEdges); + conversion::stringify<IconAllowOverlap>(writer, layout.iconAllowOverlap); + conversion::stringify<IconIgnorePlacement>(writer, layout.iconIgnorePlacement); + conversion::stringify<IconOptional>(writer, layout.iconOptional); + conversion::stringify<IconRotationAlignment>(writer, layout.iconRotationAlignment); + conversion::stringify<IconSize>(writer, layout.iconSize); + conversion::stringify<IconTextFit>(writer, layout.iconTextFit); + conversion::stringify<IconTextFitPadding>(writer, layout.iconTextFitPadding); + conversion::stringify<IconImage>(writer, layout.iconImage); + conversion::stringify<IconRotate>(writer, layout.iconRotate); + conversion::stringify<IconPadding>(writer, layout.iconPadding); + conversion::stringify<IconKeepUpright>(writer, layout.iconKeepUpright); + conversion::stringify<IconOffset>(writer, layout.iconOffset); + conversion::stringify<IconAnchor>(writer, layout.iconAnchor); + conversion::stringify<IconPitchAlignment>(writer, layout.iconPitchAlignment); + conversion::stringify<TextPitchAlignment>(writer, layout.textPitchAlignment); + conversion::stringify<TextRotationAlignment>(writer, layout.textRotationAlignment); + conversion::stringify<TextField>(writer, layout.textField); + conversion::stringify<TextFont>(writer, layout.textFont); + conversion::stringify<TextSize>(writer, layout.textSize); + conversion::stringify<TextMaxWidth>(writer, layout.textMaxWidth); + conversion::stringify<TextLineHeight>(writer, layout.textLineHeight); + conversion::stringify<TextLetterSpacing>(writer, layout.textLetterSpacing); + conversion::stringify<TextJustify>(writer, layout.textJustify); + conversion::stringify<TextAnchor>(writer, layout.textAnchor); + conversion::stringify<TextMaxAngle>(writer, layout.textMaxAngle); + conversion::stringify<TextRotate>(writer, layout.textRotate); + conversion::stringify<TextPadding>(writer, layout.textPadding); + conversion::stringify<TextKeepUpright>(writer, layout.textKeepUpright); + conversion::stringify<TextTransform>(writer, layout.textTransform); + conversion::stringify<TextOffset>(writer, layout.textOffset); + conversion::stringify<TextAllowOverlap>(writer, layout.textAllowOverlap); + conversion::stringify<TextIgnorePlacement>(writer, layout.textIgnorePlacement); + conversion::stringify<TextOptional>(writer, layout.textOptional); + writer.EndObject(); } // Source @@ -106,14 +143,14 @@ PropertyValue<SymbolPlacementType> SymbolLayer::getDefaultSymbolPlacement() { } PropertyValue<SymbolPlacementType> SymbolLayer::getSymbolPlacement() const { - return impl().layout.get<SymbolPlacement>(); + return impl().layout.symbolPlacement; } void SymbolLayer::setSymbolPlacement(PropertyValue<SymbolPlacementType> value) { if (value == getSymbolPlacement()) return; auto impl_ = mutableImpl(); - impl_->layout.get<SymbolPlacement>() = value; + impl_->layout.symbolPlacement = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } @@ -122,14 +159,14 @@ PropertyValue<float> SymbolLayer::getDefaultSymbolSpacing() { } PropertyValue<float> SymbolLayer::getSymbolSpacing() const { - return impl().layout.get<SymbolSpacing>(); + return impl().layout.symbolSpacing; } void SymbolLayer::setSymbolSpacing(PropertyValue<float> value) { if (value == getSymbolSpacing()) return; auto impl_ = mutableImpl(); - impl_->layout.get<SymbolSpacing>() = value; + impl_->layout.symbolSpacing = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } @@ -138,14 +175,14 @@ PropertyValue<bool> SymbolLayer::getDefaultSymbolAvoidEdges() { } PropertyValue<bool> SymbolLayer::getSymbolAvoidEdges() const { - return impl().layout.get<SymbolAvoidEdges>(); + return impl().layout.symbolAvoidEdges; } void SymbolLayer::setSymbolAvoidEdges(PropertyValue<bool> value) { if (value == getSymbolAvoidEdges()) return; auto impl_ = mutableImpl(); - impl_->layout.get<SymbolAvoidEdges>() = value; + impl_->layout.symbolAvoidEdges = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } @@ -154,14 +191,14 @@ PropertyValue<bool> SymbolLayer::getDefaultIconAllowOverlap() { } PropertyValue<bool> SymbolLayer::getIconAllowOverlap() const { - return impl().layout.get<IconAllowOverlap>(); + return impl().layout.iconAllowOverlap; } void SymbolLayer::setIconAllowOverlap(PropertyValue<bool> value) { if (value == getIconAllowOverlap()) return; auto impl_ = mutableImpl(); - impl_->layout.get<IconAllowOverlap>() = value; + impl_->layout.iconAllowOverlap = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } @@ -170,14 +207,14 @@ PropertyValue<bool> SymbolLayer::getDefaultIconIgnorePlacement() { } PropertyValue<bool> SymbolLayer::getIconIgnorePlacement() const { - return impl().layout.get<IconIgnorePlacement>(); + return impl().layout.iconIgnorePlacement; } void SymbolLayer::setIconIgnorePlacement(PropertyValue<bool> value) { if (value == getIconIgnorePlacement()) return; auto impl_ = mutableImpl(); - impl_->layout.get<IconIgnorePlacement>() = value; + impl_->layout.iconIgnorePlacement = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } @@ -186,14 +223,14 @@ PropertyValue<bool> SymbolLayer::getDefaultIconOptional() { } PropertyValue<bool> SymbolLayer::getIconOptional() const { - return impl().layout.get<IconOptional>(); + return impl().layout.iconOptional; } void SymbolLayer::setIconOptional(PropertyValue<bool> value) { if (value == getIconOptional()) return; auto impl_ = mutableImpl(); - impl_->layout.get<IconOptional>() = value; + impl_->layout.iconOptional = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } @@ -202,14 +239,14 @@ PropertyValue<AlignmentType> SymbolLayer::getDefaultIconRotationAlignment() { } PropertyValue<AlignmentType> SymbolLayer::getIconRotationAlignment() const { - return impl().layout.get<IconRotationAlignment>(); + return impl().layout.iconRotationAlignment; } void SymbolLayer::setIconRotationAlignment(PropertyValue<AlignmentType> value) { if (value == getIconRotationAlignment()) return; auto impl_ = mutableImpl(); - impl_->layout.get<IconRotationAlignment>() = value; + impl_->layout.iconRotationAlignment = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } @@ -218,14 +255,14 @@ PropertyValue<float> SymbolLayer::getDefaultIconSize() { } PropertyValue<float> SymbolLayer::getIconSize() const { - return impl().layout.get<IconSize>(); + return impl().layout.iconSize; } void SymbolLayer::setIconSize(PropertyValue<float> value) { if (value == getIconSize()) return; auto impl_ = mutableImpl(); - impl_->layout.get<IconSize>() = value; + impl_->layout.iconSize = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } @@ -234,14 +271,14 @@ PropertyValue<IconTextFitType> SymbolLayer::getDefaultIconTextFit() { } PropertyValue<IconTextFitType> SymbolLayer::getIconTextFit() const { - return impl().layout.get<IconTextFit>(); + return impl().layout.iconTextFit; } void SymbolLayer::setIconTextFit(PropertyValue<IconTextFitType> value) { if (value == getIconTextFit()) return; auto impl_ = mutableImpl(); - impl_->layout.get<IconTextFit>() = value; + impl_->layout.iconTextFit = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } @@ -250,14 +287,14 @@ PropertyValue<std::array<float, 4>> SymbolLayer::getDefaultIconTextFitPadding() } PropertyValue<std::array<float, 4>> SymbolLayer::getIconTextFitPadding() const { - return impl().layout.get<IconTextFitPadding>(); + return impl().layout.iconTextFitPadding; } void SymbolLayer::setIconTextFitPadding(PropertyValue<std::array<float, 4>> value) { if (value == getIconTextFitPadding()) return; auto impl_ = mutableImpl(); - impl_->layout.get<IconTextFitPadding>() = value; + impl_->layout.iconTextFitPadding = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } @@ -266,14 +303,14 @@ PropertyValue<std::string> SymbolLayer::getDefaultIconImage() { } PropertyValue<std::string> SymbolLayer::getIconImage() const { - return impl().layout.get<IconImage>(); + return impl().layout.iconImage; } void SymbolLayer::setIconImage(PropertyValue<std::string> value) { if (value == getIconImage()) return; auto impl_ = mutableImpl(); - impl_->layout.get<IconImage>() = value; + impl_->layout.iconImage = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } @@ -282,14 +319,14 @@ PropertyValue<float> SymbolLayer::getDefaultIconRotate() { } PropertyValue<float> SymbolLayer::getIconRotate() const { - return impl().layout.get<IconRotate>(); + return impl().layout.iconRotate; } void SymbolLayer::setIconRotate(PropertyValue<float> value) { if (value == getIconRotate()) return; auto impl_ = mutableImpl(); - impl_->layout.get<IconRotate>() = value; + impl_->layout.iconRotate = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } @@ -298,14 +335,14 @@ PropertyValue<float> SymbolLayer::getDefaultIconPadding() { } PropertyValue<float> SymbolLayer::getIconPadding() const { - return impl().layout.get<IconPadding>(); + return impl().layout.iconPadding; } void SymbolLayer::setIconPadding(PropertyValue<float> value) { if (value == getIconPadding()) return; auto impl_ = mutableImpl(); - impl_->layout.get<IconPadding>() = value; + impl_->layout.iconPadding = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } @@ -314,14 +351,14 @@ PropertyValue<bool> SymbolLayer::getDefaultIconKeepUpright() { } PropertyValue<bool> SymbolLayer::getIconKeepUpright() const { - return impl().layout.get<IconKeepUpright>(); + return impl().layout.iconKeepUpright; } void SymbolLayer::setIconKeepUpright(PropertyValue<bool> value) { if (value == getIconKeepUpright()) return; auto impl_ = mutableImpl(); - impl_->layout.get<IconKeepUpright>() = value; + impl_->layout.iconKeepUpright = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } @@ -330,14 +367,14 @@ PropertyValue<std::array<float, 2>> SymbolLayer::getDefaultIconOffset() { } PropertyValue<std::array<float, 2>> SymbolLayer::getIconOffset() const { - return impl().layout.get<IconOffset>(); + return impl().layout.iconOffset; } void SymbolLayer::setIconOffset(PropertyValue<std::array<float, 2>> value) { if (value == getIconOffset()) return; auto impl_ = mutableImpl(); - impl_->layout.get<IconOffset>() = value; + impl_->layout.iconOffset = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } @@ -346,14 +383,14 @@ PropertyValue<SymbolAnchorType> SymbolLayer::getDefaultIconAnchor() { } PropertyValue<SymbolAnchorType> SymbolLayer::getIconAnchor() const { - return impl().layout.get<IconAnchor>(); + return impl().layout.iconAnchor; } void SymbolLayer::setIconAnchor(PropertyValue<SymbolAnchorType> value) { if (value == getIconAnchor()) return; auto impl_ = mutableImpl(); - impl_->layout.get<IconAnchor>() = value; + impl_->layout.iconAnchor = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } @@ -362,14 +399,14 @@ PropertyValue<AlignmentType> SymbolLayer::getDefaultIconPitchAlignment() { } PropertyValue<AlignmentType> SymbolLayer::getIconPitchAlignment() const { - return impl().layout.get<IconPitchAlignment>(); + return impl().layout.iconPitchAlignment; } void SymbolLayer::setIconPitchAlignment(PropertyValue<AlignmentType> value) { if (value == getIconPitchAlignment()) return; auto impl_ = mutableImpl(); - impl_->layout.get<IconPitchAlignment>() = value; + impl_->layout.iconPitchAlignment = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } @@ -378,14 +415,14 @@ PropertyValue<AlignmentType> SymbolLayer::getDefaultTextPitchAlignment() { } PropertyValue<AlignmentType> SymbolLayer::getTextPitchAlignment() const { - return impl().layout.get<TextPitchAlignment>(); + return impl().layout.textPitchAlignment; } void SymbolLayer::setTextPitchAlignment(PropertyValue<AlignmentType> value) { if (value == getTextPitchAlignment()) return; auto impl_ = mutableImpl(); - impl_->layout.get<TextPitchAlignment>() = value; + impl_->layout.textPitchAlignment = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } @@ -394,14 +431,14 @@ PropertyValue<AlignmentType> SymbolLayer::getDefaultTextRotationAlignment() { } PropertyValue<AlignmentType> SymbolLayer::getTextRotationAlignment() const { - return impl().layout.get<TextRotationAlignment>(); + return impl().layout.textRotationAlignment; } void SymbolLayer::setTextRotationAlignment(PropertyValue<AlignmentType> value) { if (value == getTextRotationAlignment()) return; auto impl_ = mutableImpl(); - impl_->layout.get<TextRotationAlignment>() = value; + impl_->layout.textRotationAlignment = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } @@ -410,14 +447,14 @@ PropertyValue<std::string> SymbolLayer::getDefaultTextField() { } PropertyValue<std::string> SymbolLayer::getTextField() const { - return impl().layout.get<TextField>(); + return impl().layout.textField; } void SymbolLayer::setTextField(PropertyValue<std::string> value) { if (value == getTextField()) return; auto impl_ = mutableImpl(); - impl_->layout.get<TextField>() = value; + impl_->layout.textField = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } @@ -426,14 +463,14 @@ PropertyValue<std::vector<std::string>> SymbolLayer::getDefaultTextFont() { } PropertyValue<std::vector<std::string>> SymbolLayer::getTextFont() const { - return impl().layout.get<TextFont>(); + return impl().layout.textFont; } void SymbolLayer::setTextFont(PropertyValue<std::vector<std::string>> value) { if (value == getTextFont()) return; auto impl_ = mutableImpl(); - impl_->layout.get<TextFont>() = value; + impl_->layout.textFont = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } @@ -442,14 +479,14 @@ PropertyValue<float> SymbolLayer::getDefaultTextSize() { } PropertyValue<float> SymbolLayer::getTextSize() const { - return impl().layout.get<TextSize>(); + return impl().layout.textSize; } void SymbolLayer::setTextSize(PropertyValue<float> value) { if (value == getTextSize()) return; auto impl_ = mutableImpl(); - impl_->layout.get<TextSize>() = value; + impl_->layout.textSize = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } @@ -458,14 +495,14 @@ PropertyValue<float> SymbolLayer::getDefaultTextMaxWidth() { } PropertyValue<float> SymbolLayer::getTextMaxWidth() const { - return impl().layout.get<TextMaxWidth>(); + return impl().layout.textMaxWidth; } void SymbolLayer::setTextMaxWidth(PropertyValue<float> value) { if (value == getTextMaxWidth()) return; auto impl_ = mutableImpl(); - impl_->layout.get<TextMaxWidth>() = value; + impl_->layout.textMaxWidth = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } @@ -474,14 +511,14 @@ PropertyValue<float> SymbolLayer::getDefaultTextLineHeight() { } PropertyValue<float> SymbolLayer::getTextLineHeight() const { - return impl().layout.get<TextLineHeight>(); + return impl().layout.textLineHeight; } void SymbolLayer::setTextLineHeight(PropertyValue<float> value) { if (value == getTextLineHeight()) return; auto impl_ = mutableImpl(); - impl_->layout.get<TextLineHeight>() = value; + impl_->layout.textLineHeight = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } @@ -490,14 +527,14 @@ PropertyValue<float> SymbolLayer::getDefaultTextLetterSpacing() { } PropertyValue<float> SymbolLayer::getTextLetterSpacing() const { - return impl().layout.get<TextLetterSpacing>(); + return impl().layout.textLetterSpacing; } void SymbolLayer::setTextLetterSpacing(PropertyValue<float> value) { if (value == getTextLetterSpacing()) return; auto impl_ = mutableImpl(); - impl_->layout.get<TextLetterSpacing>() = value; + impl_->layout.textLetterSpacing = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } @@ -506,14 +543,14 @@ PropertyValue<TextJustifyType> SymbolLayer::getDefaultTextJustify() { } PropertyValue<TextJustifyType> SymbolLayer::getTextJustify() const { - return impl().layout.get<TextJustify>(); + return impl().layout.textJustify; } void SymbolLayer::setTextJustify(PropertyValue<TextJustifyType> value) { if (value == getTextJustify()) return; auto impl_ = mutableImpl(); - impl_->layout.get<TextJustify>() = value; + impl_->layout.textJustify = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } @@ -522,14 +559,14 @@ PropertyValue<SymbolAnchorType> SymbolLayer::getDefaultTextAnchor() { } PropertyValue<SymbolAnchorType> SymbolLayer::getTextAnchor() const { - return impl().layout.get<TextAnchor>(); + return impl().layout.textAnchor; } void SymbolLayer::setTextAnchor(PropertyValue<SymbolAnchorType> value) { if (value == getTextAnchor()) return; auto impl_ = mutableImpl(); - impl_->layout.get<TextAnchor>() = value; + impl_->layout.textAnchor = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } @@ -538,14 +575,14 @@ PropertyValue<float> SymbolLayer::getDefaultTextMaxAngle() { } PropertyValue<float> SymbolLayer::getTextMaxAngle() const { - return impl().layout.get<TextMaxAngle>(); + return impl().layout.textMaxAngle; } void SymbolLayer::setTextMaxAngle(PropertyValue<float> value) { if (value == getTextMaxAngle()) return; auto impl_ = mutableImpl(); - impl_->layout.get<TextMaxAngle>() = value; + impl_->layout.textMaxAngle = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } @@ -554,14 +591,14 @@ PropertyValue<float> SymbolLayer::getDefaultTextRotate() { } PropertyValue<float> SymbolLayer::getTextRotate() const { - return impl().layout.get<TextRotate>(); + return impl().layout.textRotate; } void SymbolLayer::setTextRotate(PropertyValue<float> value) { if (value == getTextRotate()) return; auto impl_ = mutableImpl(); - impl_->layout.get<TextRotate>() = value; + impl_->layout.textRotate = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } @@ -570,14 +607,14 @@ PropertyValue<float> SymbolLayer::getDefaultTextPadding() { } PropertyValue<float> SymbolLayer::getTextPadding() const { - return impl().layout.get<TextPadding>(); + return impl().layout.textPadding; } void SymbolLayer::setTextPadding(PropertyValue<float> value) { if (value == getTextPadding()) return; auto impl_ = mutableImpl(); - impl_->layout.get<TextPadding>() = value; + impl_->layout.textPadding = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } @@ -586,14 +623,14 @@ PropertyValue<bool> SymbolLayer::getDefaultTextKeepUpright() { } PropertyValue<bool> SymbolLayer::getTextKeepUpright() const { - return impl().layout.get<TextKeepUpright>(); + return impl().layout.textKeepUpright; } void SymbolLayer::setTextKeepUpright(PropertyValue<bool> value) { if (value == getTextKeepUpright()) return; auto impl_ = mutableImpl(); - impl_->layout.get<TextKeepUpright>() = value; + impl_->layout.textKeepUpright = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } @@ -602,14 +639,14 @@ PropertyValue<TextTransformType> SymbolLayer::getDefaultTextTransform() { } PropertyValue<TextTransformType> SymbolLayer::getTextTransform() const { - return impl().layout.get<TextTransform>(); + return impl().layout.textTransform; } void SymbolLayer::setTextTransform(PropertyValue<TextTransformType> value) { if (value == getTextTransform()) return; auto impl_ = mutableImpl(); - impl_->layout.get<TextTransform>() = value; + impl_->layout.textTransform = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } @@ -618,14 +655,14 @@ PropertyValue<std::array<float, 2>> SymbolLayer::getDefaultTextOffset() { } PropertyValue<std::array<float, 2>> SymbolLayer::getTextOffset() const { - return impl().layout.get<TextOffset>(); + return impl().layout.textOffset; } void SymbolLayer::setTextOffset(PropertyValue<std::array<float, 2>> value) { if (value == getTextOffset()) return; auto impl_ = mutableImpl(); - impl_->layout.get<TextOffset>() = value; + impl_->layout.textOffset = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } @@ -634,14 +671,14 @@ PropertyValue<bool> SymbolLayer::getDefaultTextAllowOverlap() { } PropertyValue<bool> SymbolLayer::getTextAllowOverlap() const { - return impl().layout.get<TextAllowOverlap>(); + return impl().layout.textAllowOverlap; } void SymbolLayer::setTextAllowOverlap(PropertyValue<bool> value) { if (value == getTextAllowOverlap()) return; auto impl_ = mutableImpl(); - impl_->layout.get<TextAllowOverlap>() = value; + impl_->layout.textAllowOverlap = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } @@ -650,14 +687,14 @@ PropertyValue<bool> SymbolLayer::getDefaultTextIgnorePlacement() { } PropertyValue<bool> SymbolLayer::getTextIgnorePlacement() const { - return impl().layout.get<TextIgnorePlacement>(); + return impl().layout.textIgnorePlacement; } void SymbolLayer::setTextIgnorePlacement(PropertyValue<bool> value) { if (value == getTextIgnorePlacement()) return; auto impl_ = mutableImpl(); - impl_->layout.get<TextIgnorePlacement>() = value; + impl_->layout.textIgnorePlacement = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } @@ -666,14 +703,14 @@ PropertyValue<bool> SymbolLayer::getDefaultTextOptional() { } PropertyValue<bool> SymbolLayer::getTextOptional() const { - return impl().layout.get<TextOptional>(); + return impl().layout.textOptional; } void SymbolLayer::setTextOptional(PropertyValue<bool> value) { if (value == getTextOptional()) return; auto impl_ = mutableImpl(); - impl_->layout.get<TextOptional>() = value; + impl_->layout.textOptional = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } @@ -685,26 +722,26 @@ PropertyValue<float> SymbolLayer::getDefaultIconOpacity() { } PropertyValue<float> SymbolLayer::getIconOpacity() const { - return impl().paint.template get<IconOpacity>().value; + return impl().paint.iconOpacity.value; } void SymbolLayer::setIconOpacity(PropertyValue<float> value) { if (value == getIconOpacity()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<IconOpacity>().value = value; + impl_->paint.iconOpacity.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void SymbolLayer::setIconOpacityTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<IconOpacity>().options = options; + impl_->paint.iconOpacity.options = options; baseImpl = std::move(impl_); } TransitionOptions SymbolLayer::getIconOpacityTransition() const { - return impl().paint.template get<IconOpacity>().options; + return impl().paint.iconOpacity.options; } PropertyValue<Color> SymbolLayer::getDefaultIconColor() { @@ -712,26 +749,26 @@ PropertyValue<Color> SymbolLayer::getDefaultIconColor() { } PropertyValue<Color> SymbolLayer::getIconColor() const { - return impl().paint.template get<IconColor>().value; + return impl().paint.iconColor.value; } void SymbolLayer::setIconColor(PropertyValue<Color> value) { if (value == getIconColor()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<IconColor>().value = value; + impl_->paint.iconColor.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void SymbolLayer::setIconColorTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<IconColor>().options = options; + impl_->paint.iconColor.options = options; baseImpl = std::move(impl_); } TransitionOptions SymbolLayer::getIconColorTransition() const { - return impl().paint.template get<IconColor>().options; + return impl().paint.iconColor.options; } PropertyValue<Color> SymbolLayer::getDefaultIconHaloColor() { @@ -739,26 +776,26 @@ PropertyValue<Color> SymbolLayer::getDefaultIconHaloColor() { } PropertyValue<Color> SymbolLayer::getIconHaloColor() const { - return impl().paint.template get<IconHaloColor>().value; + return impl().paint.iconHaloColor.value; } void SymbolLayer::setIconHaloColor(PropertyValue<Color> value) { if (value == getIconHaloColor()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<IconHaloColor>().value = value; + impl_->paint.iconHaloColor.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void SymbolLayer::setIconHaloColorTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<IconHaloColor>().options = options; + impl_->paint.iconHaloColor.options = options; baseImpl = std::move(impl_); } TransitionOptions SymbolLayer::getIconHaloColorTransition() const { - return impl().paint.template get<IconHaloColor>().options; + return impl().paint.iconHaloColor.options; } PropertyValue<float> SymbolLayer::getDefaultIconHaloWidth() { @@ -766,26 +803,26 @@ PropertyValue<float> SymbolLayer::getDefaultIconHaloWidth() { } PropertyValue<float> SymbolLayer::getIconHaloWidth() const { - return impl().paint.template get<IconHaloWidth>().value; + return impl().paint.iconHaloWidth.value; } void SymbolLayer::setIconHaloWidth(PropertyValue<float> value) { if (value == getIconHaloWidth()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<IconHaloWidth>().value = value; + impl_->paint.iconHaloWidth.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void SymbolLayer::setIconHaloWidthTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<IconHaloWidth>().options = options; + impl_->paint.iconHaloWidth.options = options; baseImpl = std::move(impl_); } TransitionOptions SymbolLayer::getIconHaloWidthTransition() const { - return impl().paint.template get<IconHaloWidth>().options; + return impl().paint.iconHaloWidth.options; } PropertyValue<float> SymbolLayer::getDefaultIconHaloBlur() { @@ -793,26 +830,26 @@ PropertyValue<float> SymbolLayer::getDefaultIconHaloBlur() { } PropertyValue<float> SymbolLayer::getIconHaloBlur() const { - return impl().paint.template get<IconHaloBlur>().value; + return impl().paint.iconHaloBlur.value; } void SymbolLayer::setIconHaloBlur(PropertyValue<float> value) { if (value == getIconHaloBlur()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<IconHaloBlur>().value = value; + impl_->paint.iconHaloBlur.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void SymbolLayer::setIconHaloBlurTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<IconHaloBlur>().options = options; + impl_->paint.iconHaloBlur.options = options; baseImpl = std::move(impl_); } TransitionOptions SymbolLayer::getIconHaloBlurTransition() const { - return impl().paint.template get<IconHaloBlur>().options; + return impl().paint.iconHaloBlur.options; } PropertyValue<std::array<float, 2>> SymbolLayer::getDefaultIconTranslate() { @@ -820,26 +857,26 @@ PropertyValue<std::array<float, 2>> SymbolLayer::getDefaultIconTranslate() { } PropertyValue<std::array<float, 2>> SymbolLayer::getIconTranslate() const { - return impl().paint.template get<IconTranslate>().value; + return impl().paint.iconTranslate.value; } void SymbolLayer::setIconTranslate(PropertyValue<std::array<float, 2>> value) { if (value == getIconTranslate()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<IconTranslate>().value = value; + impl_->paint.iconTranslate.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void SymbolLayer::setIconTranslateTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<IconTranslate>().options = options; + impl_->paint.iconTranslate.options = options; baseImpl = std::move(impl_); } TransitionOptions SymbolLayer::getIconTranslateTransition() const { - return impl().paint.template get<IconTranslate>().options; + return impl().paint.iconTranslate.options; } PropertyValue<TranslateAnchorType> SymbolLayer::getDefaultIconTranslateAnchor() { @@ -847,26 +884,26 @@ PropertyValue<TranslateAnchorType> SymbolLayer::getDefaultIconTranslateAnchor() } PropertyValue<TranslateAnchorType> SymbolLayer::getIconTranslateAnchor() const { - return impl().paint.template get<IconTranslateAnchor>().value; + return impl().paint.iconTranslateAnchor.value; } void SymbolLayer::setIconTranslateAnchor(PropertyValue<TranslateAnchorType> value) { if (value == getIconTranslateAnchor()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<IconTranslateAnchor>().value = value; + impl_->paint.iconTranslateAnchor.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void SymbolLayer::setIconTranslateAnchorTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<IconTranslateAnchor>().options = options; + impl_->paint.iconTranslateAnchor.options = options; baseImpl = std::move(impl_); } TransitionOptions SymbolLayer::getIconTranslateAnchorTransition() const { - return impl().paint.template get<IconTranslateAnchor>().options; + return impl().paint.iconTranslateAnchor.options; } PropertyValue<float> SymbolLayer::getDefaultTextOpacity() { @@ -874,26 +911,26 @@ PropertyValue<float> SymbolLayer::getDefaultTextOpacity() { } PropertyValue<float> SymbolLayer::getTextOpacity() const { - return impl().paint.template get<TextOpacity>().value; + return impl().paint.textOpacity.value; } void SymbolLayer::setTextOpacity(PropertyValue<float> value) { if (value == getTextOpacity()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<TextOpacity>().value = value; + impl_->paint.textOpacity.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void SymbolLayer::setTextOpacityTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<TextOpacity>().options = options; + impl_->paint.textOpacity.options = options; baseImpl = std::move(impl_); } TransitionOptions SymbolLayer::getTextOpacityTransition() const { - return impl().paint.template get<TextOpacity>().options; + return impl().paint.textOpacity.options; } PropertyValue<Color> SymbolLayer::getDefaultTextColor() { @@ -901,26 +938,26 @@ PropertyValue<Color> SymbolLayer::getDefaultTextColor() { } PropertyValue<Color> SymbolLayer::getTextColor() const { - return impl().paint.template get<TextColor>().value; + return impl().paint.textColor.value; } void SymbolLayer::setTextColor(PropertyValue<Color> value) { if (value == getTextColor()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<TextColor>().value = value; + impl_->paint.textColor.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void SymbolLayer::setTextColorTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<TextColor>().options = options; + impl_->paint.textColor.options = options; baseImpl = std::move(impl_); } TransitionOptions SymbolLayer::getTextColorTransition() const { - return impl().paint.template get<TextColor>().options; + return impl().paint.textColor.options; } PropertyValue<Color> SymbolLayer::getDefaultTextHaloColor() { @@ -928,26 +965,26 @@ PropertyValue<Color> SymbolLayer::getDefaultTextHaloColor() { } PropertyValue<Color> SymbolLayer::getTextHaloColor() const { - return impl().paint.template get<TextHaloColor>().value; + return impl().paint.textHaloColor.value; } void SymbolLayer::setTextHaloColor(PropertyValue<Color> value) { if (value == getTextHaloColor()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<TextHaloColor>().value = value; + impl_->paint.textHaloColor.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void SymbolLayer::setTextHaloColorTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<TextHaloColor>().options = options; + impl_->paint.textHaloColor.options = options; baseImpl = std::move(impl_); } TransitionOptions SymbolLayer::getTextHaloColorTransition() const { - return impl().paint.template get<TextHaloColor>().options; + return impl().paint.textHaloColor.options; } PropertyValue<float> SymbolLayer::getDefaultTextHaloWidth() { @@ -955,26 +992,26 @@ PropertyValue<float> SymbolLayer::getDefaultTextHaloWidth() { } PropertyValue<float> SymbolLayer::getTextHaloWidth() const { - return impl().paint.template get<TextHaloWidth>().value; + return impl().paint.textHaloWidth.value; } void SymbolLayer::setTextHaloWidth(PropertyValue<float> value) { if (value == getTextHaloWidth()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<TextHaloWidth>().value = value; + impl_->paint.textHaloWidth.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void SymbolLayer::setTextHaloWidthTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<TextHaloWidth>().options = options; + impl_->paint.textHaloWidth.options = options; baseImpl = std::move(impl_); } TransitionOptions SymbolLayer::getTextHaloWidthTransition() const { - return impl().paint.template get<TextHaloWidth>().options; + return impl().paint.textHaloWidth.options; } PropertyValue<float> SymbolLayer::getDefaultTextHaloBlur() { @@ -982,26 +1019,26 @@ PropertyValue<float> SymbolLayer::getDefaultTextHaloBlur() { } PropertyValue<float> SymbolLayer::getTextHaloBlur() const { - return impl().paint.template get<TextHaloBlur>().value; + return impl().paint.textHaloBlur.value; } void SymbolLayer::setTextHaloBlur(PropertyValue<float> value) { if (value == getTextHaloBlur()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<TextHaloBlur>().value = value; + impl_->paint.textHaloBlur.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void SymbolLayer::setTextHaloBlurTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<TextHaloBlur>().options = options; + impl_->paint.textHaloBlur.options = options; baseImpl = std::move(impl_); } TransitionOptions SymbolLayer::getTextHaloBlurTransition() const { - return impl().paint.template get<TextHaloBlur>().options; + return impl().paint.textHaloBlur.options; } PropertyValue<std::array<float, 2>> SymbolLayer::getDefaultTextTranslate() { @@ -1009,26 +1046,26 @@ PropertyValue<std::array<float, 2>> SymbolLayer::getDefaultTextTranslate() { } PropertyValue<std::array<float, 2>> SymbolLayer::getTextTranslate() const { - return impl().paint.template get<TextTranslate>().value; + return impl().paint.textTranslate.value; } void SymbolLayer::setTextTranslate(PropertyValue<std::array<float, 2>> value) { if (value == getTextTranslate()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<TextTranslate>().value = value; + impl_->paint.textTranslate.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void SymbolLayer::setTextTranslateTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<TextTranslate>().options = options; + impl_->paint.textTranslate.options = options; baseImpl = std::move(impl_); } TransitionOptions SymbolLayer::getTextTranslateTransition() const { - return impl().paint.template get<TextTranslate>().options; + return impl().paint.textTranslate.options; } PropertyValue<TranslateAnchorType> SymbolLayer::getDefaultTextTranslateAnchor() { @@ -1036,26 +1073,26 @@ PropertyValue<TranslateAnchorType> SymbolLayer::getDefaultTextTranslateAnchor() } PropertyValue<TranslateAnchorType> SymbolLayer::getTextTranslateAnchor() const { - return impl().paint.template get<TextTranslateAnchor>().value; + return impl().paint.textTranslateAnchor.value; } void SymbolLayer::setTextTranslateAnchor(PropertyValue<TranslateAnchorType> value) { if (value == getTextTranslateAnchor()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<TextTranslateAnchor>().value = value; + impl_->paint.textTranslateAnchor.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void SymbolLayer::setTextTranslateAnchorTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<TextTranslateAnchor>().options = options; + impl_->paint.textTranslateAnchor.options = options; baseImpl = std::move(impl_); } TransitionOptions SymbolLayer::getTextTranslateAnchorTransition() const { - return impl().paint.template get<TextTranslateAnchor>().options; + return impl().paint.textTranslateAnchor.options; } using namespace conversion; diff --git a/src/mbgl/style/layers/symbol_layer_properties.cpp b/src/mbgl/style/layers/symbol_layer_properties.cpp index 5a1ce713b..8d2cc597e 100644 --- a/src/mbgl/style/layers/symbol_layer_properties.cpp +++ b/src/mbgl/style/layers/symbol_layer_properties.cpp @@ -5,5 +5,431 @@ namespace mbgl { namespace style { +bool operator==(const SymbolLayoutProperties::Unevaluated& lhs, const SymbolLayoutProperties::Unevaluated& rhs) { + return true + && lhs.symbolPlacement == rhs.symbolPlacement + && lhs.symbolSpacing == rhs.symbolSpacing + && lhs.symbolAvoidEdges == rhs.symbolAvoidEdges + && lhs.iconAllowOverlap == rhs.iconAllowOverlap + && lhs.iconIgnorePlacement == rhs.iconIgnorePlacement + && lhs.iconOptional == rhs.iconOptional + && lhs.iconRotationAlignment == rhs.iconRotationAlignment + && lhs.iconSize == rhs.iconSize + && lhs.iconTextFit == rhs.iconTextFit + && lhs.iconTextFitPadding == rhs.iconTextFitPadding + && lhs.iconImage == rhs.iconImage + && lhs.iconRotate == rhs.iconRotate + && lhs.iconPadding == rhs.iconPadding + && lhs.iconKeepUpright == rhs.iconKeepUpright + && lhs.iconOffset == rhs.iconOffset + && lhs.iconAnchor == rhs.iconAnchor + && lhs.iconPitchAlignment == rhs.iconPitchAlignment + && lhs.textPitchAlignment == rhs.textPitchAlignment + && lhs.textRotationAlignment == rhs.textRotationAlignment + && lhs.textField == rhs.textField + && lhs.textFont == rhs.textFont + && lhs.textSize == rhs.textSize + && lhs.textMaxWidth == rhs.textMaxWidth + && lhs.textLineHeight == rhs.textLineHeight + && lhs.textLetterSpacing == rhs.textLetterSpacing + && lhs.textJustify == rhs.textJustify + && lhs.textAnchor == rhs.textAnchor + && lhs.textMaxAngle == rhs.textMaxAngle + && lhs.textRotate == rhs.textRotate + && lhs.textPadding == rhs.textPadding + && lhs.textKeepUpright == rhs.textKeepUpright + && lhs.textTransform == rhs.textTransform + && lhs.textOffset == rhs.textOffset + && lhs.textAllowOverlap == rhs.textAllowOverlap + && lhs.textIgnorePlacement == rhs.textIgnorePlacement + && lhs.textOptional == rhs.textOptional + ; +} + +SymbolLayoutProperties::PossiblyEvaluated SymbolLayoutProperties::Unevaluated::evaluate(const PropertyEvaluationParameters& parameters) const { + return PossiblyEvaluated { + symbolPlacement.evaluate(typename SymbolPlacement::EvaluatorType(parameters, SymbolPlacement::defaultValue()), parameters.now), + symbolSpacing.evaluate(typename SymbolSpacing::EvaluatorType(parameters, SymbolSpacing::defaultValue()), parameters.now), + symbolAvoidEdges.evaluate(typename SymbolAvoidEdges::EvaluatorType(parameters, SymbolAvoidEdges::defaultValue()), parameters.now), + iconAllowOverlap.evaluate(typename IconAllowOverlap::EvaluatorType(parameters, IconAllowOverlap::defaultValue()), parameters.now), + iconIgnorePlacement.evaluate(typename IconIgnorePlacement::EvaluatorType(parameters, IconIgnorePlacement::defaultValue()), parameters.now), + iconOptional.evaluate(typename IconOptional::EvaluatorType(parameters, IconOptional::defaultValue()), parameters.now), + iconRotationAlignment.evaluate(typename IconRotationAlignment::EvaluatorType(parameters, IconRotationAlignment::defaultValue()), parameters.now), + iconSize.evaluate(typename IconSize::EvaluatorType(parameters, IconSize::defaultValue()), parameters.now), + iconTextFit.evaluate(typename IconTextFit::EvaluatorType(parameters, IconTextFit::defaultValue()), parameters.now), + iconTextFitPadding.evaluate(typename IconTextFitPadding::EvaluatorType(parameters, IconTextFitPadding::defaultValue()), parameters.now), + iconImage.evaluate(typename IconImage::EvaluatorType(parameters, IconImage::defaultValue()), parameters.now), + iconRotate.evaluate(typename IconRotate::EvaluatorType(parameters, IconRotate::defaultValue()), parameters.now), + iconPadding.evaluate(typename IconPadding::EvaluatorType(parameters, IconPadding::defaultValue()), parameters.now), + iconKeepUpright.evaluate(typename IconKeepUpright::EvaluatorType(parameters, IconKeepUpright::defaultValue()), parameters.now), + iconOffset.evaluate(typename IconOffset::EvaluatorType(parameters, IconOffset::defaultValue()), parameters.now), + iconAnchor.evaluate(typename IconAnchor::EvaluatorType(parameters, IconAnchor::defaultValue()), parameters.now), + iconPitchAlignment.evaluate(typename IconPitchAlignment::EvaluatorType(parameters, IconPitchAlignment::defaultValue()), parameters.now), + textPitchAlignment.evaluate(typename TextPitchAlignment::EvaluatorType(parameters, TextPitchAlignment::defaultValue()), parameters.now), + textRotationAlignment.evaluate(typename TextRotationAlignment::EvaluatorType(parameters, TextRotationAlignment::defaultValue()), parameters.now), + textField.evaluate(typename TextField::EvaluatorType(parameters, TextField::defaultValue()), parameters.now), + textFont.evaluate(typename TextFont::EvaluatorType(parameters, TextFont::defaultValue()), parameters.now), + textSize.evaluate(typename TextSize::EvaluatorType(parameters, TextSize::defaultValue()), parameters.now), + textMaxWidth.evaluate(typename TextMaxWidth::EvaluatorType(parameters, TextMaxWidth::defaultValue()), parameters.now), + textLineHeight.evaluate(typename TextLineHeight::EvaluatorType(parameters, TextLineHeight::defaultValue()), parameters.now), + textLetterSpacing.evaluate(typename TextLetterSpacing::EvaluatorType(parameters, TextLetterSpacing::defaultValue()), parameters.now), + textJustify.evaluate(typename TextJustify::EvaluatorType(parameters, TextJustify::defaultValue()), parameters.now), + textAnchor.evaluate(typename TextAnchor::EvaluatorType(parameters, TextAnchor::defaultValue()), parameters.now), + textMaxAngle.evaluate(typename TextMaxAngle::EvaluatorType(parameters, TextMaxAngle::defaultValue()), parameters.now), + textRotate.evaluate(typename TextRotate::EvaluatorType(parameters, TextRotate::defaultValue()), parameters.now), + textPadding.evaluate(typename TextPadding::EvaluatorType(parameters, TextPadding::defaultValue()), parameters.now), + textKeepUpright.evaluate(typename TextKeepUpright::EvaluatorType(parameters, TextKeepUpright::defaultValue()), parameters.now), + textTransform.evaluate(typename TextTransform::EvaluatorType(parameters, TextTransform::defaultValue()), parameters.now), + textOffset.evaluate(typename TextOffset::EvaluatorType(parameters, TextOffset::defaultValue()), parameters.now), + textAllowOverlap.evaluate(typename TextAllowOverlap::EvaluatorType(parameters, TextAllowOverlap::defaultValue()), parameters.now), + textIgnorePlacement.evaluate(typename TextIgnorePlacement::EvaluatorType(parameters, TextIgnorePlacement::defaultValue()), parameters.now), + textOptional.evaluate(typename TextOptional::EvaluatorType(parameters, TextOptional::defaultValue()), parameters.now), + }; +} + +SymbolLayoutProperties::Evaluated SymbolLayoutProperties::PossiblyEvaluated::evaluate(float z, const GeometryTileFeature& feature) const { + return Evaluated { + symbolPlacement, + symbolSpacing, + symbolAvoidEdges, + iconAllowOverlap, + iconIgnorePlacement, + iconOptional, + iconRotationAlignment, + iconSize.evaluate(feature, z, IconSize::defaultValue()), + iconTextFit, + iconTextFitPadding, + iconImage.evaluate(feature, z, IconImage::defaultValue()), + iconRotate.evaluate(feature, z, IconRotate::defaultValue()), + iconPadding, + iconKeepUpright, + iconOffset.evaluate(feature, z, IconOffset::defaultValue()), + iconAnchor.evaluate(feature, z, IconAnchor::defaultValue()), + iconPitchAlignment, + textPitchAlignment, + textRotationAlignment, + textField.evaluate(feature, z, TextField::defaultValue()), + textFont.evaluate(feature, z, TextFont::defaultValue()), + textSize.evaluate(feature, z, TextSize::defaultValue()), + textMaxWidth.evaluate(feature, z, TextMaxWidth::defaultValue()), + textLineHeight, + textLetterSpacing.evaluate(feature, z, TextLetterSpacing::defaultValue()), + textJustify.evaluate(feature, z, TextJustify::defaultValue()), + textAnchor.evaluate(feature, z, TextAnchor::defaultValue()), + textMaxAngle, + textRotate.evaluate(feature, z, TextRotate::defaultValue()), + textPadding, + textKeepUpright, + textTransform.evaluate(feature, z, TextTransform::defaultValue()), + textOffset.evaluate(feature, z, TextOffset::defaultValue()), + textAllowOverlap, + textIgnorePlacement, + textOptional, + }; +} + +SymbolPaintProperties::Unevaluated SymbolPaintProperties::Transitionable::transitioned(const TransitionParameters& parameters, Unevaluated&& prior) const { + return Unevaluated { + iconOpacity.transition(parameters, std::move(prior.iconOpacity)), + iconColor.transition(parameters, std::move(prior.iconColor)), + iconHaloColor.transition(parameters, std::move(prior.iconHaloColor)), + iconHaloWidth.transition(parameters, std::move(prior.iconHaloWidth)), + iconHaloBlur.transition(parameters, std::move(prior.iconHaloBlur)), + iconTranslate.transition(parameters, std::move(prior.iconTranslate)), + iconTranslateAnchor.transition(parameters, std::move(prior.iconTranslateAnchor)), + textOpacity.transition(parameters, std::move(prior.textOpacity)), + textColor.transition(parameters, std::move(prior.textColor)), + textHaloColor.transition(parameters, std::move(prior.textHaloColor)), + textHaloWidth.transition(parameters, std::move(prior.textHaloWidth)), + textHaloBlur.transition(parameters, std::move(prior.textHaloBlur)), + textTranslate.transition(parameters, std::move(prior.textTranslate)), + textTranslateAnchor.transition(parameters, std::move(prior.textTranslateAnchor)), + }; +} + +SymbolPaintProperties::Unevaluated SymbolPaintProperties::Transitionable::untransitioned() const { + return Unevaluated { + Transitioning<PropertyValue<float>>(iconOpacity.value), + Transitioning<PropertyValue<Color>>(iconColor.value), + Transitioning<PropertyValue<Color>>(iconHaloColor.value), + Transitioning<PropertyValue<float>>(iconHaloWidth.value), + Transitioning<PropertyValue<float>>(iconHaloBlur.value), + Transitioning<PropertyValue<std::array<float, 2>>>(iconTranslate.value), + Transitioning<PropertyValue<TranslateAnchorType>>(iconTranslateAnchor.value), + Transitioning<PropertyValue<float>>(textOpacity.value), + Transitioning<PropertyValue<Color>>(textColor.value), + Transitioning<PropertyValue<Color>>(textHaloColor.value), + Transitioning<PropertyValue<float>>(textHaloWidth.value), + Transitioning<PropertyValue<float>>(textHaloBlur.value), + Transitioning<PropertyValue<std::array<float, 2>>>(textTranslate.value), + Transitioning<PropertyValue<TranslateAnchorType>>(textTranslateAnchor.value), + }; +} + +bool SymbolPaintProperties::Transitionable::hasDataDrivenPropertyDifference(const Transitionable& other) const { + return false + || iconOpacity.value.hasDataDrivenPropertyDifference(other.iconOpacity.value) + || iconColor.value.hasDataDrivenPropertyDifference(other.iconColor.value) + || iconHaloColor.value.hasDataDrivenPropertyDifference(other.iconHaloColor.value) + || iconHaloWidth.value.hasDataDrivenPropertyDifference(other.iconHaloWidth.value) + || iconHaloBlur.value.hasDataDrivenPropertyDifference(other.iconHaloBlur.value) + || iconTranslate.value.hasDataDrivenPropertyDifference(other.iconTranslate.value) + || iconTranslateAnchor.value.hasDataDrivenPropertyDifference(other.iconTranslateAnchor.value) + || textOpacity.value.hasDataDrivenPropertyDifference(other.textOpacity.value) + || textColor.value.hasDataDrivenPropertyDifference(other.textColor.value) + || textHaloColor.value.hasDataDrivenPropertyDifference(other.textHaloColor.value) + || textHaloWidth.value.hasDataDrivenPropertyDifference(other.textHaloWidth.value) + || textHaloBlur.value.hasDataDrivenPropertyDifference(other.textHaloBlur.value) + || textTranslate.value.hasDataDrivenPropertyDifference(other.textTranslate.value) + || textTranslateAnchor.value.hasDataDrivenPropertyDifference(other.textTranslateAnchor.value) + ; +} + +bool SymbolPaintProperties::Unevaluated::hasTransition() const { + return false + || iconOpacity.hasTransition() + || iconColor.hasTransition() + || iconHaloColor.hasTransition() + || iconHaloWidth.hasTransition() + || iconHaloBlur.hasTransition() + || iconTranslate.hasTransition() + || iconTranslateAnchor.hasTransition() + || textOpacity.hasTransition() + || textColor.hasTransition() + || textHaloColor.hasTransition() + || textHaloWidth.hasTransition() + || textHaloBlur.hasTransition() + || textTranslate.hasTransition() + || textTranslateAnchor.hasTransition() + ; +} + +SymbolPaintProperties::PossiblyEvaluated SymbolPaintProperties::Unevaluated::evaluate(const PropertyEvaluationParameters& parameters) const { + return PossiblyEvaluated { + iconOpacity.evaluate(typename IconOpacity::EvaluatorType(parameters, IconOpacity::defaultValue()), parameters.now), + iconColor.evaluate(typename IconColor::EvaluatorType(parameters, IconColor::defaultValue()), parameters.now), + iconHaloColor.evaluate(typename IconHaloColor::EvaluatorType(parameters, IconHaloColor::defaultValue()), parameters.now), + iconHaloWidth.evaluate(typename IconHaloWidth::EvaluatorType(parameters, IconHaloWidth::defaultValue()), parameters.now), + iconHaloBlur.evaluate(typename IconHaloBlur::EvaluatorType(parameters, IconHaloBlur::defaultValue()), parameters.now), + iconTranslate.evaluate(typename IconTranslate::EvaluatorType(parameters, IconTranslate::defaultValue()), parameters.now), + iconTranslateAnchor.evaluate(typename IconTranslateAnchor::EvaluatorType(parameters, IconTranslateAnchor::defaultValue()), parameters.now), + textOpacity.evaluate(typename TextOpacity::EvaluatorType(parameters, TextOpacity::defaultValue()), parameters.now), + textColor.evaluate(typename TextColor::EvaluatorType(parameters, TextColor::defaultValue()), parameters.now), + textHaloColor.evaluate(typename TextHaloColor::EvaluatorType(parameters, TextHaloColor::defaultValue()), parameters.now), + textHaloWidth.evaluate(typename TextHaloWidth::EvaluatorType(parameters, TextHaloWidth::defaultValue()), parameters.now), + textHaloBlur.evaluate(typename TextHaloBlur::EvaluatorType(parameters, TextHaloBlur::defaultValue()), parameters.now), + textTranslate.evaluate(typename TextTranslate::EvaluatorType(parameters, TextTranslate::defaultValue()), parameters.now), + textTranslateAnchor.evaluate(typename TextTranslateAnchor::EvaluatorType(parameters, TextTranslateAnchor::defaultValue()), parameters.now), + }; +} + + + + +IconPaintProperties::Binders IconPaintProperties::PossiblyEvaluated::createBinders(float z) const { + return Binders { + PaintPropertyBinder<float, typename attributes::a_opacity::Type>::create(iconOpacity, z, IconOpacity::defaultValue()), + PaintPropertyBinder<Color, typename attributes::a_fill_color::Type>::create(iconColor, z, IconColor::defaultValue()), + PaintPropertyBinder<Color, typename attributes::a_halo_color::Type>::create(iconHaloColor, z, IconHaloColor::defaultValue()), + PaintPropertyBinder<float, typename attributes::a_halo_width::Type>::create(iconHaloWidth, z, IconHaloWidth::defaultValue()), + PaintPropertyBinder<float, typename attributes::a_halo_blur::Type>::create(iconHaloBlur, z, IconHaloBlur::defaultValue()), + }; +} + +std::bitset<8> IconPaintProperties::PossiblyEvaluated::constants() const { + std::bitset<8> result; + result.set(0, iconOpacity.isConstant()); + result.set(1, iconColor.isConstant()); + result.set(2, iconHaloColor.isConstant()); + result.set(3, iconHaloWidth.isConstant()); + result.set(4, iconHaloBlur.isConstant()); + return result; +} + +std::vector<std::string> IconPaintProperties::PossiblyEvaluated::defines() const { + std::vector<std::string> result; + result.push_back(iconOpacity.isConstant() + ? std::string("#define HAS_UNIFORM_") + IconOpacity::Uniform::name() + : std::string()); + result.push_back(iconColor.isConstant() + ? std::string("#define HAS_UNIFORM_") + IconColor::Uniform::name() + : std::string()); + result.push_back(iconHaloColor.isConstant() + ? std::string("#define HAS_UNIFORM_") + IconHaloColor::Uniform::name() + : std::string()); + result.push_back(iconHaloWidth.isConstant() + ? std::string("#define HAS_UNIFORM_") + IconHaloWidth::Uniform::name() + : std::string()); + result.push_back(iconHaloBlur.isConstant() + ? std::string("#define HAS_UNIFORM_") + IconHaloBlur::Uniform::name() + : std::string()); + return result; +} + +void IconPaintProperties::Binders::populateVertexVectors(const GeometryTileFeature& feature, std::size_t length) { + iconOpacity->populateVertexVector(feature, length); + iconColor->populateVertexVector(feature, length); + iconHaloColor->populateVertexVector(feature, length); + iconHaloWidth->populateVertexVector(feature, length); + iconHaloBlur->populateVertexVector(feature, length); +} + +void IconPaintProperties::Binders::upload(gl::Context& context) { + iconOpacity->upload(context); + iconColor->upload(context); + iconHaloColor->upload(context); + iconHaloWidth->upload(context); + iconHaloBlur->upload(context); +} + +IconPaintProperties::Binders::AttributeBindings IconPaintProperties::Binders::attributeBindings(const PossiblyEvaluated& currentProperties) const { + return AttributeBindings { + iconOpacity->attributeBinding(currentProperties.iconOpacity), + iconColor->attributeBinding(currentProperties.iconColor), + iconHaloColor->attributeBinding(currentProperties.iconHaloColor), + iconHaloWidth->attributeBinding(currentProperties.iconHaloWidth), + iconHaloBlur->attributeBinding(currentProperties.iconHaloBlur), + }; +} + +IconPaintProperties::Binders::UniformValues IconPaintProperties::Binders::uniformValues(float currentZoom, const PossiblyEvaluated& currentProperties) const { + return UniformValues { + typename InterpolationUniform<attributes::a_opacity>::Value { + iconOpacity->interpolationFactor(currentZoom) + }, + typename InterpolationUniform<attributes::a_fill_color>::Value { + iconColor->interpolationFactor(currentZoom) + }, + typename InterpolationUniform<attributes::a_halo_color>::Value { + iconHaloColor->interpolationFactor(currentZoom) + }, + typename InterpolationUniform<attributes::a_halo_width>::Value { + iconHaloWidth->interpolationFactor(currentZoom) + }, + typename InterpolationUniform<attributes::a_halo_blur>::Value { + iconHaloBlur->interpolationFactor(currentZoom) + }, + typename uniforms::u_opacity::Value { + iconOpacity->uniformValue(currentProperties.iconOpacity) + }, + typename uniforms::u_fill_color::Value { + iconColor->uniformValue(currentProperties.iconColor) + }, + typename uniforms::u_halo_color::Value { + iconHaloColor->uniformValue(currentProperties.iconHaloColor) + }, + typename uniforms::u_halo_width::Value { + iconHaloWidth->uniformValue(currentProperties.iconHaloWidth) + }, + typename uniforms::u_halo_blur::Value { + iconHaloBlur->uniformValue(currentProperties.iconHaloBlur) + }, + }; +} + + + +TextPaintProperties::Binders TextPaintProperties::PossiblyEvaluated::createBinders(float z) const { + return Binders { + PaintPropertyBinder<float, typename attributes::a_opacity::Type>::create(textOpacity, z, TextOpacity::defaultValue()), + PaintPropertyBinder<Color, typename attributes::a_fill_color::Type>::create(textColor, z, TextColor::defaultValue()), + PaintPropertyBinder<Color, typename attributes::a_halo_color::Type>::create(textHaloColor, z, TextHaloColor::defaultValue()), + PaintPropertyBinder<float, typename attributes::a_halo_width::Type>::create(textHaloWidth, z, TextHaloWidth::defaultValue()), + PaintPropertyBinder<float, typename attributes::a_halo_blur::Type>::create(textHaloBlur, z, TextHaloBlur::defaultValue()), + }; +} + +std::bitset<8> TextPaintProperties::PossiblyEvaluated::constants() const { + std::bitset<8> result; + result.set(0, textOpacity.isConstant()); + result.set(1, textColor.isConstant()); + result.set(2, textHaloColor.isConstant()); + result.set(3, textHaloWidth.isConstant()); + result.set(4, textHaloBlur.isConstant()); + return result; +} + +std::vector<std::string> TextPaintProperties::PossiblyEvaluated::defines() const { + std::vector<std::string> result; + result.push_back(textOpacity.isConstant() + ? std::string("#define HAS_UNIFORM_") + TextOpacity::Uniform::name() + : std::string()); + result.push_back(textColor.isConstant() + ? std::string("#define HAS_UNIFORM_") + TextColor::Uniform::name() + : std::string()); + result.push_back(textHaloColor.isConstant() + ? std::string("#define HAS_UNIFORM_") + TextHaloColor::Uniform::name() + : std::string()); + result.push_back(textHaloWidth.isConstant() + ? std::string("#define HAS_UNIFORM_") + TextHaloWidth::Uniform::name() + : std::string()); + result.push_back(textHaloBlur.isConstant() + ? std::string("#define HAS_UNIFORM_") + TextHaloBlur::Uniform::name() + : std::string()); + return result; +} + +void TextPaintProperties::Binders::populateVertexVectors(const GeometryTileFeature& feature, std::size_t length) { + textOpacity->populateVertexVector(feature, length); + textColor->populateVertexVector(feature, length); + textHaloColor->populateVertexVector(feature, length); + textHaloWidth->populateVertexVector(feature, length); + textHaloBlur->populateVertexVector(feature, length); +} + +void TextPaintProperties::Binders::upload(gl::Context& context) { + textOpacity->upload(context); + textColor->upload(context); + textHaloColor->upload(context); + textHaloWidth->upload(context); + textHaloBlur->upload(context); +} + +TextPaintProperties::Binders::AttributeBindings TextPaintProperties::Binders::attributeBindings(const PossiblyEvaluated& currentProperties) const { + return AttributeBindings { + textOpacity->attributeBinding(currentProperties.textOpacity), + textColor->attributeBinding(currentProperties.textColor), + textHaloColor->attributeBinding(currentProperties.textHaloColor), + textHaloWidth->attributeBinding(currentProperties.textHaloWidth), + textHaloBlur->attributeBinding(currentProperties.textHaloBlur), + }; +} + +TextPaintProperties::Binders::UniformValues TextPaintProperties::Binders::uniformValues(float currentZoom, const PossiblyEvaluated& currentProperties) const { + return UniformValues { + typename InterpolationUniform<attributes::a_opacity>::Value { + textOpacity->interpolationFactor(currentZoom) + }, + typename InterpolationUniform<attributes::a_fill_color>::Value { + textColor->interpolationFactor(currentZoom) + }, + typename InterpolationUniform<attributes::a_halo_color>::Value { + textHaloColor->interpolationFactor(currentZoom) + }, + typename InterpolationUniform<attributes::a_halo_width>::Value { + textHaloWidth->interpolationFactor(currentZoom) + }, + typename InterpolationUniform<attributes::a_halo_blur>::Value { + textHaloBlur->interpolationFactor(currentZoom) + }, + typename uniforms::u_opacity::Value { + textOpacity->uniformValue(currentProperties.textOpacity) + }, + typename uniforms::u_fill_color::Value { + textColor->uniformValue(currentProperties.textColor) + }, + typename uniforms::u_halo_color::Value { + textHaloColor->uniformValue(currentProperties.textHaloColor) + }, + typename uniforms::u_halo_width::Value { + textHaloWidth->uniformValue(currentProperties.textHaloWidth) + }, + typename uniforms::u_halo_blur::Value { + textHaloBlur->uniformValue(currentProperties.textHaloBlur) + }, + }; +} + + } // namespace style } // namespace mbgl diff --git a/src/mbgl/style/layers/symbol_layer_properties.hpp b/src/mbgl/style/layers/symbol_layer_properties.hpp index e70ac28d5..d8f4d42d4 100644 --- a/src/mbgl/style/layers/symbol_layer_properties.hpp +++ b/src/mbgl/style/layers/symbol_layer_properties.hpp @@ -248,61 +248,328 @@ struct TextTranslateAnchor : PaintProperty<TranslateAnchorType> { static TranslateAnchorType defaultValue() { return TranslateAnchorType::Map; } }; -class SymbolLayoutProperties : public Properties< - SymbolPlacement, - SymbolSpacing, - SymbolAvoidEdges, - IconAllowOverlap, - IconIgnorePlacement, - IconOptional, - IconRotationAlignment, - IconSize, - IconTextFit, - IconTextFitPadding, - IconImage, - IconRotate, - IconPadding, - IconKeepUpright, - IconOffset, - IconAnchor, - IconPitchAlignment, - TextPitchAlignment, - TextRotationAlignment, - TextField, - TextFont, - TextSize, - TextMaxWidth, - TextLineHeight, - TextLetterSpacing, - TextJustify, - TextAnchor, - TextMaxAngle, - TextRotate, - TextPadding, - TextKeepUpright, - TextTransform, - TextOffset, - TextAllowOverlap, - TextIgnorePlacement, - TextOptional -> {}; - -class SymbolPaintProperties : public Properties< - IconOpacity, - IconColor, - IconHaloColor, - IconHaloWidth, - IconHaloBlur, - IconTranslate, - IconTranslateAnchor, - TextOpacity, - TextColor, - TextHaloColor, - TextHaloWidth, - TextHaloBlur, - TextTranslate, - TextTranslateAnchor -> {}; +class SymbolLayoutProperties { +public: + class Evaluated { + public: + SymbolPlacementType symbolPlacement; + float symbolSpacing; + bool symbolAvoidEdges; + bool iconAllowOverlap; + bool iconIgnorePlacement; + bool iconOptional; + AlignmentType iconRotationAlignment; + float iconSize; + IconTextFitType iconTextFit; + std::array<float, 4> iconTextFitPadding; + std::string iconImage; + float iconRotate; + float iconPadding; + bool iconKeepUpright; + std::array<float, 2> iconOffset; + SymbolAnchorType iconAnchor; + AlignmentType iconPitchAlignment; + AlignmentType textPitchAlignment; + AlignmentType textRotationAlignment; + std::string textField; + std::vector<std::string> textFont; + float textSize; + float textMaxWidth; + float textLineHeight; + float textLetterSpacing; + TextJustifyType textJustify; + SymbolAnchorType textAnchor; + float textMaxAngle; + float textRotate; + float textPadding; + bool textKeepUpright; + TextTransformType textTransform; + std::array<float, 2> textOffset; + bool textAllowOverlap; + bool textIgnorePlacement; + bool textOptional; + }; + + class PossiblyEvaluated { + public: + SymbolPlacementType symbolPlacement; + float symbolSpacing; + bool symbolAvoidEdges; + bool iconAllowOverlap; + bool iconIgnorePlacement; + bool iconOptional; + AlignmentType iconRotationAlignment; + PossiblyEvaluatedPropertyValue<float> iconSize; + IconTextFitType iconTextFit; + std::array<float, 4> iconTextFitPadding; + PossiblyEvaluatedPropertyValue<std::string> iconImage; + PossiblyEvaluatedPropertyValue<float> iconRotate; + float iconPadding; + bool iconKeepUpright; + PossiblyEvaluatedPropertyValue<std::array<float, 2>> iconOffset; + PossiblyEvaluatedPropertyValue<SymbolAnchorType> iconAnchor; + AlignmentType iconPitchAlignment; + AlignmentType textPitchAlignment; + AlignmentType textRotationAlignment; + PossiblyEvaluatedPropertyValue<std::string> textField; + PossiblyEvaluatedPropertyValue<std::vector<std::string>> textFont; + PossiblyEvaluatedPropertyValue<float> textSize; + PossiblyEvaluatedPropertyValue<float> textMaxWidth; + float textLineHeight; + PossiblyEvaluatedPropertyValue<float> textLetterSpacing; + PossiblyEvaluatedPropertyValue<TextJustifyType> textJustify; + PossiblyEvaluatedPropertyValue<SymbolAnchorType> textAnchor; + float textMaxAngle; + PossiblyEvaluatedPropertyValue<float> textRotate; + float textPadding; + bool textKeepUpright; + PossiblyEvaluatedPropertyValue<TextTransformType> textTransform; + PossiblyEvaluatedPropertyValue<std::array<float, 2>> textOffset; + bool textAllowOverlap; + bool textIgnorePlacement; + bool textOptional; + + Evaluated evaluate(float z, const GeometryTileFeature& feature) const; + }; + + class Unevaluated { + public: + PropertyValue<SymbolPlacementType> symbolPlacement; + PropertyValue<float> symbolSpacing; + PropertyValue<bool> symbolAvoidEdges; + PropertyValue<bool> iconAllowOverlap; + PropertyValue<bool> iconIgnorePlacement; + PropertyValue<bool> iconOptional; + PropertyValue<AlignmentType> iconRotationAlignment; + PropertyValue<float> iconSize; + PropertyValue<IconTextFitType> iconTextFit; + PropertyValue<std::array<float, 4>> iconTextFitPadding; + PropertyValue<std::string> iconImage; + PropertyValue<float> iconRotate; + PropertyValue<float> iconPadding; + PropertyValue<bool> iconKeepUpright; + PropertyValue<std::array<float, 2>> iconOffset; + PropertyValue<SymbolAnchorType> iconAnchor; + PropertyValue<AlignmentType> iconPitchAlignment; + PropertyValue<AlignmentType> textPitchAlignment; + PropertyValue<AlignmentType> textRotationAlignment; + PropertyValue<std::string> textField; + PropertyValue<std::vector<std::string>> textFont; + PropertyValue<float> textSize; + PropertyValue<float> textMaxWidth; + PropertyValue<float> textLineHeight; + PropertyValue<float> textLetterSpacing; + PropertyValue<TextJustifyType> textJustify; + PropertyValue<SymbolAnchorType> textAnchor; + PropertyValue<float> textMaxAngle; + PropertyValue<float> textRotate; + PropertyValue<float> textPadding; + PropertyValue<bool> textKeepUpright; + PropertyValue<TextTransformType> textTransform; + PropertyValue<std::array<float, 2>> textOffset; + PropertyValue<bool> textAllowOverlap; + PropertyValue<bool> textIgnorePlacement; + PropertyValue<bool> textOptional; + + PossiblyEvaluated evaluate(const PropertyEvaluationParameters&) const; + + friend bool operator==(const Unevaluated&, const Unevaluated&); + friend inline bool operator!=(const Unevaluated& lhs, const Unevaluated& rhs) { return !(lhs == rhs); } + }; +}; + +class SymbolPaintProperties { +public: + + class PossiblyEvaluated { + public: + PossiblyEvaluatedPropertyValue<float> iconOpacity; + PossiblyEvaluatedPropertyValue<Color> iconColor; + PossiblyEvaluatedPropertyValue<Color> iconHaloColor; + PossiblyEvaluatedPropertyValue<float> iconHaloWidth; + PossiblyEvaluatedPropertyValue<float> iconHaloBlur; + std::array<float, 2> iconTranslate; + TranslateAnchorType iconTranslateAnchor; + PossiblyEvaluatedPropertyValue<float> textOpacity; + PossiblyEvaluatedPropertyValue<Color> textColor; + PossiblyEvaluatedPropertyValue<Color> textHaloColor; + PossiblyEvaluatedPropertyValue<float> textHaloWidth; + PossiblyEvaluatedPropertyValue<float> textHaloBlur; + std::array<float, 2> textTranslate; + TranslateAnchorType textTranslateAnchor; + }; + + class Unevaluated { + public: + style::Transitioning<PropertyValue<float>> iconOpacity; + style::Transitioning<PropertyValue<Color>> iconColor; + style::Transitioning<PropertyValue<Color>> iconHaloColor; + style::Transitioning<PropertyValue<float>> iconHaloWidth; + style::Transitioning<PropertyValue<float>> iconHaloBlur; + style::Transitioning<PropertyValue<std::array<float, 2>>> iconTranslate; + style::Transitioning<PropertyValue<TranslateAnchorType>> iconTranslateAnchor; + style::Transitioning<PropertyValue<float>> textOpacity; + style::Transitioning<PropertyValue<Color>> textColor; + style::Transitioning<PropertyValue<Color>> textHaloColor; + style::Transitioning<PropertyValue<float>> textHaloWidth; + style::Transitioning<PropertyValue<float>> textHaloBlur; + style::Transitioning<PropertyValue<std::array<float, 2>>> textTranslate; + style::Transitioning<PropertyValue<TranslateAnchorType>> textTranslateAnchor; + + bool hasTransition() const; + PossiblyEvaluated evaluate(const PropertyEvaluationParameters&) const; + }; + + class Transitionable { + public: + style::Transitionable<PropertyValue<float>> iconOpacity; + style::Transitionable<PropertyValue<Color>> iconColor; + style::Transitionable<PropertyValue<Color>> iconHaloColor; + style::Transitionable<PropertyValue<float>> iconHaloWidth; + style::Transitionable<PropertyValue<float>> iconHaloBlur; + style::Transitionable<PropertyValue<std::array<float, 2>>> iconTranslate; + style::Transitionable<PropertyValue<TranslateAnchorType>> iconTranslateAnchor; + style::Transitionable<PropertyValue<float>> textOpacity; + style::Transitionable<PropertyValue<Color>> textColor; + style::Transitionable<PropertyValue<Color>> textHaloColor; + style::Transitionable<PropertyValue<float>> textHaloWidth; + style::Transitionable<PropertyValue<float>> textHaloBlur; + style::Transitionable<PropertyValue<std::array<float, 2>>> textTranslate; + style::Transitionable<PropertyValue<TranslateAnchorType>> textTranslateAnchor; + + Unevaluated transitioned(const TransitionParameters&, Unevaluated&& prior) const; + Unevaluated untransitioned() const; + + bool hasDataDrivenPropertyDifference(const Transitionable& other) const; + }; +}; + +// {icon,text}-specific paint-property packs for use in the symbol Programs. +// Since each program deals either with icons or text, using a smaller property set +// lets us avoid unnecessarily binding attributes for properties the program wouldn't use. + + +class IconPaintProperties { +public: + class PossiblyEvaluated; + + class Binders { + public: + std::unique_ptr<PaintPropertyBinder<float, typename attributes::a_opacity::Type>> iconOpacity; + std::unique_ptr<PaintPropertyBinder<Color, typename attributes::a_fill_color::Type>> iconColor; + std::unique_ptr<PaintPropertyBinder<Color, typename attributes::a_halo_color::Type>> iconHaloColor; + std::unique_ptr<PaintPropertyBinder<float, typename attributes::a_halo_width::Type>> iconHaloWidth; + std::unique_ptr<PaintPropertyBinder<float, typename attributes::a_halo_blur::Type>> iconHaloBlur; + + void populateVertexVectors(const GeometryTileFeature&, std::size_t length); + void upload(gl::Context&); + + using Attributes = gl::Attributes< + ZoomInterpolatedAttribute<attributes::a_opacity>, + ZoomInterpolatedAttribute<attributes::a_fill_color>, + ZoomInterpolatedAttribute<attributes::a_halo_color>, + ZoomInterpolatedAttribute<attributes::a_halo_width>, + ZoomInterpolatedAttribute<attributes::a_halo_blur> + >; + + using Uniforms = gl::Uniforms< + InterpolationUniform<attributes::a_opacity>, + InterpolationUniform<attributes::a_fill_color>, + InterpolationUniform<attributes::a_halo_color>, + InterpolationUniform<attributes::a_halo_width>, + InterpolationUniform<attributes::a_halo_blur>, + uniforms::u_opacity, + uniforms::u_fill_color, + uniforms::u_halo_color, + uniforms::u_halo_width, + uniforms::u_halo_blur + >; + + using AttributeBindings = typename Attributes::Bindings; + using UniformValues = typename Uniforms::Values; + + AttributeBindings attributeBindings(const PossiblyEvaluated&) const; + UniformValues uniformValues(float z, const PossiblyEvaluated&) const; + }; + + class PossiblyEvaluated { + public: + PossiblyEvaluatedPropertyValue<float> iconOpacity; + PossiblyEvaluatedPropertyValue<Color> iconColor; + PossiblyEvaluatedPropertyValue<Color> iconHaloColor; + PossiblyEvaluatedPropertyValue<float> iconHaloWidth; + PossiblyEvaluatedPropertyValue<float> iconHaloBlur; + std::array<float, 2> iconTranslate; + TranslateAnchorType iconTranslateAnchor; + + Binders createBinders(float z) const; + + std::bitset<8> constants() const; + std::vector<std::string> defines() const; + }; +}; + + +class TextPaintProperties { +public: + class PossiblyEvaluated; + + class Binders { + public: + std::unique_ptr<PaintPropertyBinder<float, typename attributes::a_opacity::Type>> textOpacity; + std::unique_ptr<PaintPropertyBinder<Color, typename attributes::a_fill_color::Type>> textColor; + std::unique_ptr<PaintPropertyBinder<Color, typename attributes::a_halo_color::Type>> textHaloColor; + std::unique_ptr<PaintPropertyBinder<float, typename attributes::a_halo_width::Type>> textHaloWidth; + std::unique_ptr<PaintPropertyBinder<float, typename attributes::a_halo_blur::Type>> textHaloBlur; + + void populateVertexVectors(const GeometryTileFeature&, std::size_t length); + void upload(gl::Context&); + + using Attributes = gl::Attributes< + ZoomInterpolatedAttribute<attributes::a_opacity>, + ZoomInterpolatedAttribute<attributes::a_fill_color>, + ZoomInterpolatedAttribute<attributes::a_halo_color>, + ZoomInterpolatedAttribute<attributes::a_halo_width>, + ZoomInterpolatedAttribute<attributes::a_halo_blur> + >; + + using Uniforms = gl::Uniforms< + InterpolationUniform<attributes::a_opacity>, + InterpolationUniform<attributes::a_fill_color>, + InterpolationUniform<attributes::a_halo_color>, + InterpolationUniform<attributes::a_halo_width>, + InterpolationUniform<attributes::a_halo_blur>, + uniforms::u_opacity, + uniforms::u_fill_color, + uniforms::u_halo_color, + uniforms::u_halo_width, + uniforms::u_halo_blur + >; + + using AttributeBindings = typename Attributes::Bindings; + using UniformValues = typename Uniforms::Values; + + AttributeBindings attributeBindings(const PossiblyEvaluated&) const; + UniformValues uniformValues(float z, const PossiblyEvaluated&) const; + }; + + class PossiblyEvaluated { + public: + PossiblyEvaluatedPropertyValue<float> textOpacity; + PossiblyEvaluatedPropertyValue<Color> textColor; + PossiblyEvaluatedPropertyValue<Color> textHaloColor; + PossiblyEvaluatedPropertyValue<float> textHaloWidth; + PossiblyEvaluatedPropertyValue<float> textHaloBlur; + std::array<float, 2> textTranslate; + TranslateAnchorType textTranslateAnchor; + + Binders createBinders(float z) const; + + std::bitset<8> constants() const; + std::vector<std::string> defines() const; + }; +}; + } // namespace style } // namespace mbgl diff --git a/src/mbgl/style/layout_property.hpp b/src/mbgl/style/layout_property.hpp index 0fcad30cc..7b745e151 100644 --- a/src/mbgl/style/layout_property.hpp +++ b/src/mbgl/style/layout_property.hpp @@ -10,10 +10,7 @@ namespace style { template <class T> class LayoutProperty { public: - using TransitionableType = std::nullptr_t; - using UnevaluatedType = PropertyValue<T>; using EvaluatorType = PropertyEvaluator<T>; - using PossiblyEvaluatedType = T; using Type = T; static constexpr bool IsDataDriven = false; }; @@ -21,10 +18,7 @@ public: template <class T> class DataDrivenLayoutProperty { public: - using TransitionableType = std::nullptr_t; - using UnevaluatedType = PropertyValue<T>; using EvaluatorType = DataDrivenPropertyEvaluator<T>; - using PossiblyEvaluatedType = PossiblyEvaluatedPropertyValue<T>; using Type = T; static constexpr bool IsDataDriven = true; }; diff --git a/src/mbgl/style/light.cpp b/src/mbgl/style/light.cpp index 352dc4d94..4571698b8 100644 --- a/src/mbgl/style/light.cpp +++ b/src/mbgl/style/light.cpp @@ -29,25 +29,25 @@ LightAnchorType Light::getDefaultAnchor() { } PropertyValue<LightAnchorType> Light::getAnchor() const { - return impl->properties.template get<LightAnchor>().value; + return impl->properties.anchor.value; } void Light::setAnchor(PropertyValue<LightAnchorType> property) { auto impl_ = mutableImpl(); - impl_->properties.template get<LightAnchor>().value = property; + impl_->properties.anchor.value = property; impl = std::move(impl_); observer->onLightChanged(*this); } void Light::setAnchorTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->properties.template get<LightAnchor>().options = options; + impl_->properties.anchor.options = options; impl = std::move(impl_); observer->onLightChanged(*this); } TransitionOptions Light::getAnchorTransition() const { - return impl->properties.template get<LightAnchor>().options; + return impl->properties.anchor.options; } Position Light::getDefaultPosition() { @@ -55,25 +55,25 @@ Position Light::getDefaultPosition() { } PropertyValue<Position> Light::getPosition() const { - return impl->properties.template get<LightPosition>().value; + return impl->properties.position.value; } void Light::setPosition(PropertyValue<Position> property) { auto impl_ = mutableImpl(); - impl_->properties.template get<LightPosition>().value = property; + impl_->properties.position.value = property; impl = std::move(impl_); observer->onLightChanged(*this); } void Light::setPositionTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->properties.template get<LightPosition>().options = options; + impl_->properties.position.options = options; impl = std::move(impl_); observer->onLightChanged(*this); } TransitionOptions Light::getPositionTransition() const { - return impl->properties.template get<LightPosition>().options; + return impl->properties.position.options; } Color Light::getDefaultColor() { @@ -81,25 +81,25 @@ Color Light::getDefaultColor() { } PropertyValue<Color> Light::getColor() const { - return impl->properties.template get<LightColor>().value; + return impl->properties.color.value; } void Light::setColor(PropertyValue<Color> property) { auto impl_ = mutableImpl(); - impl_->properties.template get<LightColor>().value = property; + impl_->properties.color.value = property; impl = std::move(impl_); observer->onLightChanged(*this); } void Light::setColorTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->properties.template get<LightColor>().options = options; + impl_->properties.color.options = options; impl = std::move(impl_); observer->onLightChanged(*this); } TransitionOptions Light::getColorTransition() const { - return impl->properties.template get<LightColor>().options; + return impl->properties.color.options; } float Light::getDefaultIntensity() { @@ -107,25 +107,25 @@ float Light::getDefaultIntensity() { } PropertyValue<float> Light::getIntensity() const { - return impl->properties.template get<LightIntensity>().value; + return impl->properties.intensity.value; } void Light::setIntensity(PropertyValue<float> property) { auto impl_ = mutableImpl(); - impl_->properties.template get<LightIntensity>().value = property; + impl_->properties.intensity.value = property; impl = std::move(impl_); observer->onLightChanged(*this); } void Light::setIntensityTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->properties.template get<LightIntensity>().options = options; + impl_->properties.intensity.options = options; impl = std::move(impl_); observer->onLightChanged(*this); } TransitionOptions Light::getIntensityTransition() const { - return impl->properties.template get<LightIntensity>().options; + return impl->properties.intensity.options; } diff --git a/src/mbgl/style/light.cpp.ejs b/src/mbgl/style/light.cpp.ejs index 45241c60f..5def9e3da 100644 --- a/src/mbgl/style/light.cpp.ejs +++ b/src/mbgl/style/light.cpp.ejs @@ -33,25 +33,25 @@ Mutable<Light::Impl> Light::mutableImpl() const { } <%- propertyValueType(property) %> Light::get<%- camelize(property.name) %>() const { - return impl->properties.template get<Light<%- camelize(property.name) %>>().value; + return impl->properties.<%- camelizeWithLeadingLowercase(property.name) %>.value; } void Light::set<%- camelize(property.name) %>(<%- propertyValueType(property) %> property) { auto impl_ = mutableImpl(); - impl_->properties.template get<Light<%- camelize(property.name) %>>().value = property; + impl_->properties.<%- camelizeWithLeadingLowercase(property.name) %>.value = property; impl = std::move(impl_); observer->onLightChanged(*this); } void Light::set<%- camelize(property.name) %>Transition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->properties.template get<Light<%- camelize(property.name) %>>().options = options; + impl_->properties.<%- camelizeWithLeadingLowercase(property.name) %>.options = options; impl = std::move(impl_); observer->onLightChanged(*this); } TransitionOptions Light::get<%- camelize(property.name) %>Transition() const { - return impl->properties.template get<Light<%- camelize(property.name) %>>().options; + return impl->properties.<%- camelizeWithLeadingLowercase(property.name) %>.options; } <% } -%> diff --git a/src/mbgl/style/light_impl.hpp b/src/mbgl/style/light_impl.hpp index f094c9d46..06c5307c4 100644 --- a/src/mbgl/style/light_impl.hpp +++ b/src/mbgl/style/light_impl.hpp @@ -1,55 +1,11 @@ #pragma once #include <mbgl/style/light.hpp> -#include <mbgl/style/property_value.hpp> -#include <mbgl/style/types.hpp> -#include <mbgl/style/position.hpp> -#include <mbgl/style/properties.hpp> -#include <mbgl/renderer/property_evaluator.hpp> -#include <mbgl/util/color.hpp> -#include <mbgl/util/indexed_tuple.hpp> +#include <mbgl/style/light_properties.hpp> namespace mbgl { namespace style { -template <class T> -class LightProperty { -public: - using TransitionableType = Transitionable<PropertyValue<T>>; - using UnevaluatedType = Transitioning<PropertyValue<T>>; - using EvaluatorType = PropertyEvaluator<T>; - using PossiblyEvaluatedType = T; - using Type = T; - static constexpr bool IsDataDriven = false; -}; - -struct LightAnchor : LightProperty<LightAnchorType> { - static LightAnchorType defaultValue() { - return LightAnchorType::Viewport; - } -}; - -struct LightPosition : LightProperty<Position> { - static Position defaultValue() { - std::array<float, 3> default_ = { { 1.15, 210, 30 } }; - return Position{ { default_ } }; - } -}; - -struct LightColor : LightProperty<Color> { - static Color defaultValue() { - return Color::white(); - } -}; - -struct LightIntensity : LightProperty<float> { - static float defaultValue() { - return 0.5; - } -}; - -using LightProperties = Properties<LightAnchor, LightPosition, LightColor, LightIntensity>; - class Light::Impl { public: LightProperties::Transitionable properties; diff --git a/src/mbgl/style/light_properties.cpp b/src/mbgl/style/light_properties.cpp new file mode 100644 index 000000000..3cfedf45f --- /dev/null +++ b/src/mbgl/style/light_properties.cpp @@ -0,0 +1,45 @@ +// This file is generated. Edit scripts/generate-style-code.js, then run `make style-code`. + +#include <mbgl/style/light_properties.hpp> + +namespace mbgl { +namespace style { + +LightProperties::Unevaluated LightProperties::Transitionable::transitioned(const TransitionParameters& parameters, Unevaluated&& prior) const { + return Unevaluated { + anchor.transition(parameters, std::move(prior.anchor)), + position.transition(parameters, std::move(prior.position)), + color.transition(parameters, std::move(prior.color)), + intensity.transition(parameters, std::move(prior.intensity)), + }; +} + +LightProperties::Unevaluated LightProperties::Transitionable::untransitioned() const { + return Unevaluated { + Transitioning<PropertyValue<LightAnchorType>>(anchor.value), + Transitioning<PropertyValue<Position>>(position.value), + Transitioning<PropertyValue<Color>>(color.value), + Transitioning<PropertyValue<float>>(intensity.value), + }; +} + +bool LightProperties::Unevaluated::hasTransition() const { + return false + || anchor.hasTransition() + || position.hasTransition() + || color.hasTransition() + || intensity.hasTransition() + ; +} + +LightProperties::Evaluated LightProperties::Unevaluated::evaluate(const PropertyEvaluationParameters& parameters) const { + return Evaluated { + anchor.evaluate(typename LightAnchor::EvaluatorType(parameters, LightAnchor::defaultValue()), parameters.now), + position.evaluate(typename LightPosition::EvaluatorType(parameters, LightPosition::defaultValue()), parameters.now), + color.evaluate(typename LightColor::EvaluatorType(parameters, LightColor::defaultValue()), parameters.now), + intensity.evaluate(typename LightIntensity::EvaluatorType(parameters, LightIntensity::defaultValue()), parameters.now), + }; +} + +} // namespace style +} // namespace mbgl diff --git a/src/mbgl/style/light_properties.cpp.ejs b/src/mbgl/style/light_properties.cpp.ejs new file mode 100644 index 000000000..ea79ca8cc --- /dev/null +++ b/src/mbgl/style/light_properties.cpp.ejs @@ -0,0 +1,44 @@ +<% + const properties = locals.properties; +-%> +// This file is generated. Edit scripts/generate-style-code.js, then run `make style-code`. + +#include <mbgl/style/light_properties.hpp> + +namespace mbgl { +namespace style { + +LightProperties::Unevaluated LightProperties::Transitionable::transitioned(const TransitionParameters& parameters, Unevaluated&& prior) const { + return Unevaluated { +<% for (const property of properties) { -%> + <%- camelizeWithLeadingLowercase(property.name) %>.transition(parameters, std::move(prior.<%- camelizeWithLeadingLowercase(property.name) %>)), +<% } -%> + }; +} + +LightProperties::Unevaluated LightProperties::Transitionable::untransitioned() const { + return Unevaluated { +<% for (const property of properties) { -%> + Transitioning<<%- propertyValueType(property) %>>(<%- camelizeWithLeadingLowercase(property.name) %>.value), +<% } -%> + }; +} + +bool LightProperties::Unevaluated::hasTransition() const { + return false +<% for (const property of properties) { -%> + || <%- camelizeWithLeadingLowercase(property.name) %>.hasTransition() +<% } -%> + ; +} + +LightProperties::Evaluated LightProperties::Unevaluated::evaluate(const PropertyEvaluationParameters& parameters) const { + return Evaluated { +<% for (const property of properties) { -%> + <%- camelizeWithLeadingLowercase(property.name) %>.evaluate(typename Light<%- camelize(property.name) %>::EvaluatorType(parameters, Light<%- camelize(property.name) %>::defaultValue()), parameters.now), +<% } -%> + }; +} + +} // namespace style +} // namespace mbgl diff --git a/src/mbgl/style/light_properties.hpp b/src/mbgl/style/light_properties.hpp new file mode 100644 index 000000000..7eb00b998 --- /dev/null +++ b/src/mbgl/style/light_properties.hpp @@ -0,0 +1,64 @@ +// This file is generated. Edit scripts/generate-style-code.js, then run `make style-code`. + +#pragma once + +#include <mbgl/style/light_property.hpp> +#include <mbgl/style/types.hpp> +#include <mbgl/style/position.hpp> +#include <mbgl/style/properties.hpp> +#include <mbgl/util/color.hpp> + +namespace mbgl { +namespace style { + +struct LightAnchor : LightProperty<LightAnchorType> { + static LightAnchorType defaultValue() { return LightAnchorType::Viewport; } +}; + +struct LightPosition : LightProperty<Position> { + static Position defaultValue() { return {{ 1.15, 210, 30 }}; } +}; + +struct LightColor : LightProperty<Color> { + static Color defaultValue() { return Color::white(); } +}; + +struct LightIntensity : LightProperty<float> { + static float defaultValue() { return 0.5; } +}; + +class LightProperties { +public: + class Evaluated { + public: + LightAnchorType anchor; + Position position; + Color color; + float intensity; + }; + + class Unevaluated { + public: + style::Transitioning<PropertyValue<LightAnchorType>> anchor; + style::Transitioning<PropertyValue<Position>> position; + style::Transitioning<PropertyValue<Color>> color; + style::Transitioning<PropertyValue<float>> intensity; + + bool hasTransition() const; + Evaluated evaluate(const PropertyEvaluationParameters&) const; + }; + + class Transitionable { + public: + style::Transitionable<PropertyValue<LightAnchorType>> anchor; + style::Transitionable<PropertyValue<Position>> position; + style::Transitionable<PropertyValue<Color>> color; + style::Transitionable<PropertyValue<float>> intensity; + + Unevaluated transitioned(const TransitionParameters&, Unevaluated&& prior) const; + Unevaluated untransitioned() const; + }; +}; + +} // namespace style +} // namespace mbgl diff --git a/src/mbgl/style/light_properties.hpp.ejs b/src/mbgl/style/light_properties.hpp.ejs new file mode 100644 index 000000000..2e5ea37a0 --- /dev/null +++ b/src/mbgl/style/light_properties.hpp.ejs @@ -0,0 +1,54 @@ +<% + const properties = locals.properties; +-%> +// This file is generated. Edit scripts/generate-style-code.js, then run `make style-code`. + +#pragma once + +#include <mbgl/style/light_property.hpp> +#include <mbgl/style/types.hpp> +#include <mbgl/style/position.hpp> +#include <mbgl/style/properties.hpp> +#include <mbgl/util/color.hpp> + +namespace mbgl { +namespace style { + +<% for (const property of properties) { -%> +struct Light<%- camelize(property.name) %> : LightProperty<<%- evaluatedType(property) %>> { + static <%- evaluatedType(property) %> defaultValue() { return <%- defaultValue(property) %>; } +}; + +<% } -%> +class LightProperties { +public: + class Evaluated { + public: +<% for (const property of properties) { -%> + <%- evaluatedType(property) %> <%- camelizeWithLeadingLowercase(property.name) %>; +<% } -%> + }; + + class Unevaluated { + public: +<% for (const property of properties) { -%> + style::Transitioning<<%- propertyValueType(property) %>> <%- camelizeWithLeadingLowercase(property.name) %>; +<% } -%> + + bool hasTransition() const; + Evaluated evaluate(const PropertyEvaluationParameters&) const; + }; + + class Transitionable { + public: +<% for (const property of properties) { -%> + style::Transitionable<<%- propertyValueType(property) %>> <%- camelizeWithLeadingLowercase(property.name) %>; +<% } -%> + + Unevaluated transitioned(const TransitionParameters&, Unevaluated&& prior) const; + Unevaluated untransitioned() const; + }; +}; + +} // namespace style +} // namespace mbgl diff --git a/src/mbgl/style/light_property.hpp b/src/mbgl/style/light_property.hpp new file mode 100644 index 000000000..11a2bdf4c --- /dev/null +++ b/src/mbgl/style/light_property.hpp @@ -0,0 +1,19 @@ +#pragma once + +#include <mbgl/style/properties.hpp> +#include <mbgl/style/property_value.hpp> +#include <mbgl/renderer/property_evaluator.hpp> + +namespace mbgl { +namespace style { + +template <class T> +class LightProperty { +public: + using EvaluatorType = PropertyEvaluator<T>; + using Type = T; + static constexpr bool IsDataDriven = false; +}; + +} // namespace style +} // namespace mbgl diff --git a/src/mbgl/style/paint_property.hpp b/src/mbgl/style/paint_property.hpp index 3d9d7710d..231e9b481 100644 --- a/src/mbgl/style/paint_property.hpp +++ b/src/mbgl/style/paint_property.hpp @@ -15,10 +15,7 @@ namespace style { template <class T> class PaintProperty { public: - using TransitionableType = Transitionable<PropertyValue<T>>; - using UnevaluatedType = Transitioning<PropertyValue<T>>; using EvaluatorType = PropertyEvaluator<T>; - using PossiblyEvaluatedType = T; using Type = T; static constexpr bool IsDataDriven = false; }; @@ -26,10 +23,7 @@ public: template <class T, class A, class U> class DataDrivenPaintProperty { public: - using TransitionableType = Transitionable<PropertyValue<T>>; - using UnevaluatedType = Transitioning<PropertyValue<T>>; using EvaluatorType = DataDrivenPropertyEvaluator<T>; - using PossiblyEvaluatedType = PossiblyEvaluatedPropertyValue<T>; using Type = T; static constexpr bool IsDataDriven = true; @@ -40,10 +34,7 @@ public: template <class T> class CrossFadedPaintProperty { public: - using TransitionableType = Transitionable<PropertyValue<T>>; - using UnevaluatedType = Transitioning<PropertyValue<T>>; using EvaluatorType = CrossFadedPropertyEvaluator<T>; - using PossiblyEvaluatedType = Faded<T>; using Type = T; static constexpr bool IsDataDriven = false; }; @@ -60,10 +51,7 @@ public: */ class ColorRampProperty { public: - using TransitionableType = Transitionable<ColorRampPropertyValue>; - using UnevaluatedType = Transitioning<ColorRampPropertyValue>; using EvaluatorType = PropertyEvaluator<Color>; - using PossiblyEvaluatedType = Color; using Type = Color; static constexpr bool IsDataDriven = false; diff --git a/src/mbgl/style/properties.hpp b/src/mbgl/style/properties.hpp index 9206e9698..2ac0c6e0f 100644 --- a/src/mbgl/style/properties.hpp +++ b/src/mbgl/style/properties.hpp @@ -96,149 +96,31 @@ public: } }; -template <class P> -struct IsDataDriven : std::integral_constant<bool, P::IsDataDriven> {}; - -template <class... Ps> -class Properties { +class NoProperties { public: - /* - For style properties we implement a two step evaluation process: if you have a zoom level, - you can evaluate a set of unevaluated property values, producing a set of possibly evaluated - values, where undefined, constant, or camera function values have been fully evaluated, and - source or composite function values have not. - - Once you also have a particular feature, you can evaluate that set of possibly evaluated values - fully, producing a set of fully evaluated values. - - This is in theory maximally efficient in terms of avoiding repeated evaluation of camera - functions, though it's more of a historical accident than a purposeful optimization. - */ - - using PropertyTypes = TypeList<Ps...>; - using TransitionableTypes = TypeList<typename Ps::TransitionableType...>; - using UnevaluatedTypes = TypeList<typename Ps::UnevaluatedType...>; - using PossiblyEvaluatedTypes = TypeList<typename Ps::PossiblyEvaluatedType...>; - using EvaluatedTypes = TypeList<typename Ps::Type...>; - - using DataDrivenProperties = FilteredTypeList<PropertyTypes, IsDataDriven>; - using Binders = PaintPropertyBinders<DataDrivenProperties>; - - template <class TypeList> - using Tuple = IndexedTuple<PropertyTypes, TypeList>; - - class Evaluated : public Tuple<EvaluatedTypes> { - public: - template <class... Us> - Evaluated(Us&&... us) - : Tuple<EvaluatedTypes>(std::forward<Us>(us)...) { - } - }; - - class PossiblyEvaluated : public Tuple<PossiblyEvaluatedTypes> { - public: - template <class... Us> - PossiblyEvaluated(Us&&... us) - : Tuple<PossiblyEvaluatedTypes>(std::forward<Us>(us)...) { - } - - template <class T> - static T evaluate(float, const GeometryTileFeature&, const T& t, const T&) { - return t; - } - - template <class T> - static T evaluate(float z, const GeometryTileFeature& feature, - const PossiblyEvaluatedPropertyValue<T>& v, const T& defaultValue) { - return v.match( - [&] (const T& t) { - return t; - }, - [&] (const PropertyExpression<T>& t) { - return t.evaluate(z, feature, defaultValue); - }); - } - - template <class P> - auto evaluate(float z, const GeometryTileFeature& feature) const { - return evaluate(z, feature, this->template get<P>(), P::defaultValue()); - } + class PossiblyEvaluated {}; - Evaluated evaluate(float z, const GeometryTileFeature& feature) const { - return Evaluated { - evaluate<Ps>(z, feature)... - }; - } - }; - - class Unevaluated : public Tuple<UnevaluatedTypes> { + class Binders { public: - template <class... Us> - Unevaluated(Us&&... us) - : Tuple<UnevaluatedTypes>(std::forward<Us>(us)...) { - } + void populateVertexVectors(const GeometryTileFeature&, std::size_t length); + void upload(gl::Context&); - bool hasTransition() const { - bool result = false; - util::ignore({ result |= this->template get<Ps>().hasTransition()... }); - return result; - } + using Attributes = gl::Attributes<>; + using Uniforms = gl::Uniforms<>; - template <class P> - auto evaluate(const PropertyEvaluationParameters& parameters) const { - using Evaluator = typename P::EvaluatorType; - return this->template get<P>() - .evaluate(Evaluator(parameters, P::defaultValue()), parameters.now); - } + using AttributeBindings = typename Attributes::Bindings; + using UniformValues = typename Uniforms::Values; - PossiblyEvaluated evaluate(const PropertyEvaluationParameters& parameters) const { - return PossiblyEvaluated { - evaluate<Ps>(parameters)... - }; + template <class PossiblyEvaluated> + AttributeBindings attributeBindings(const PossiblyEvaluated&) const { + return {}; } - template <class Writer> - void stringify(Writer& writer) const { - writer.StartObject(); - util::ignore({ (conversion::stringify<Ps>(writer, this->template get<Ps>()), 0)... }); - writer.EndObject(); + template <class PossiblyEvaluated> + UniformValues uniformValues(float, const PossiblyEvaluated&) const { + return {}; } }; - - class Transitionable : public Tuple<TransitionableTypes> { - public: - template <class... Us> - Transitionable(Us&&... us) - : Tuple<TransitionableTypes>(std::forward<Us>(us)...) { - } - - Unevaluated transitioned(const TransitionParameters& parameters, Unevaluated&& prior) const { - return Unevaluated { - this->template get<Ps>() - .transition(parameters, std::move(prior.template get<Ps>()))... - }; - } - - Unevaluated untransitioned() const { - return Unevaluated { - typename Ps::UnevaluatedType(this->template get<Ps>().value)... - }; - } - - bool hasDataDrivenPropertyDifference(const Transitionable& other) const { - bool result = false; - util::ignore({ (result |= this->template get<Ps>().value.hasDataDrivenPropertyDifference(other.template get<Ps>().value))... }); - return result; - } - }; -}; - -template <class...> -struct ConcatenateProperties; - -template <class... As, class... Bs> -struct ConcatenateProperties<TypeList<As...>, TypeList<Bs...>> { - using Type = Properties<As..., Bs...>; }; } // namespace style diff --git a/src/mbgl/text/placement.cpp b/src/mbgl/text/placement.cpp index a050be464..a7c3f1881 100644 --- a/src/mbgl/text/placement.cpp +++ b/src/mbgl/text/placement.cpp @@ -74,14 +74,14 @@ void Placement::placeLayer(RenderSymbolLayer& symbolLayer, const mat4& projMatri matrix::multiply(posMatrix, projMatrix, posMatrix); mat4 textLabelPlaneMatrix = getLabelPlaneMatrix(posMatrix, - layout.get<style::TextPitchAlignment>() == style::AlignmentType::Map, - layout.get<style::TextRotationAlignment>() == style::AlignmentType::Map, + layout.textPitchAlignment == style::AlignmentType::Map, + layout.textRotationAlignment == style::AlignmentType::Map, state, pixelsToTileUnits); mat4 iconLabelPlaneMatrix = getLabelPlaneMatrix(posMatrix, - layout.get<style::IconPitchAlignment>() == style::AlignmentType::Map, - layout.get<style::IconRotationAlignment>() == style::AlignmentType::Map, + layout.iconPitchAlignment == style::AlignmentType::Map, + layout.iconRotationAlignment == style::AlignmentType::Map, state, pixelsToTileUnits); @@ -131,8 +131,8 @@ void Placement::placeLayerBucket( auto placed = collisionIndex.placeFeature(symbolInstance.textCollisionFeature, posMatrix, textLabelPlaneMatrix, textPixelRatio, placedSymbol, scale, fontSize, - bucket.layout.get<style::TextAllowOverlap>(), - bucket.layout.get<style::TextPitchAlignment>() == style::AlignmentType::Map, + bucket.layout.textAllowOverlap, + bucket.layout.textPitchAlignment == style::AlignmentType::Map, showCollisionBoxes); placeText = placed.first; offscreen &= placed.second; @@ -145,15 +145,15 @@ void Placement::placeLayerBucket( auto placed = collisionIndex.placeFeature(symbolInstance.iconCollisionFeature, posMatrix, iconLabelPlaneMatrix, textPixelRatio, placedSymbol, scale, fontSize, - bucket.layout.get<style::IconAllowOverlap>(), - bucket.layout.get<style::IconPitchAlignment>() == style::AlignmentType::Map, + bucket.layout.iconAllowOverlap, + bucket.layout.iconPitchAlignment == style::AlignmentType::Map, showCollisionBoxes); placeIcon = placed.first; offscreen &= placed.second; } - const bool iconWithoutText = !symbolInstance.hasText || bucket.layout.get<style::TextOptional>(); - const bool textWithoutIcon = !symbolInstance.hasIcon || bucket.layout.get<style::IconOptional>(); + const bool iconWithoutText = !symbolInstance.hasText || bucket.layout.textOptional; + const bool textWithoutIcon = !symbolInstance.hasIcon || bucket.layout.iconOptional; // combine placements for icon and text if (!iconWithoutText && !textWithoutIcon) { @@ -165,11 +165,11 @@ void Placement::placeLayerBucket( } if (placeText) { - collisionIndex.insertFeature(symbolInstance.textCollisionFeature, bucket.layout.get<style::TextIgnorePlacement>(), bucket.bucketInstanceId); + collisionIndex.insertFeature(symbolInstance.textCollisionFeature, bucket.layout.textIgnorePlacement, bucket.bucketInstanceId); } if (placeIcon) { - collisionIndex.insertFeature(symbolInstance.iconCollisionFeature, bucket.layout.get<style::IconIgnorePlacement>(), bucket.bucketInstanceId); + collisionIndex.insertFeature(symbolInstance.iconCollisionFeature, bucket.layout.iconIgnorePlacement, bucket.bucketInstanceId); } assert(symbolInstance.crossTileID != 0); @@ -254,16 +254,16 @@ void Placement::updateBucketOpacities(SymbolBucket& bucket, std::set<uint32_t>& JointOpacityState duplicateOpacityState(false, false, true); - const bool textAllowOverlap = bucket.layout.get<style::TextAllowOverlap>(); - const bool iconAllowOverlap = bucket.layout.get<style::IconAllowOverlap>(); + const bool textAllowOverlap = bucket.layout.textAllowOverlap; + const bool iconAllowOverlap = bucket.layout.iconAllowOverlap; // If allow-overlap is true, we can show symbols before placement runs on them // But we have to wait for placement if we potentially depend on a paired icon/text // with allow-overlap: false. // See https://github.com/mapbox/mapbox-gl-native/issues/12483 JointOpacityState defaultOpacityState( - textAllowOverlap && (iconAllowOverlap || !bucket.hasIconData() || bucket.layout.get<style::IconOptional>()), - iconAllowOverlap && (textAllowOverlap || !bucket.hasTextData() || bucket.layout.get<style::TextOptional>()), + textAllowOverlap && (iconAllowOverlap || !bucket.hasIconData() || bucket.layout.iconOptional), + iconAllowOverlap && (textAllowOverlap || !bucket.hasTextData() || bucket.layout.textOptional), true); for (SymbolInstance& symbolInstance : bucket.symbolInstances) { diff --git a/src/mbgl/text/quads.cpp b/src/mbgl/text/quads.cpp index ec4461ac6..8d8edc0e9 100644 --- a/src/mbgl/text/quads.cpp +++ b/src/mbgl/text/quads.cpp @@ -33,7 +33,7 @@ SymbolQuad getIconQuad(const PositionedIcon& shapedIcon, Point<float> br; Point<float> bl; - if (layout.get<IconTextFit>() != IconTextFitType::None && shapedText) { + if (layout.iconTextFit != IconTextFitType::None && shapedText) { auto iconWidth = right - left; auto iconHeight = bottom - top; auto size = layoutTextSize / 24.0f; @@ -43,14 +43,14 @@ SymbolQuad getIconQuad(const PositionedIcon& shapedIcon, auto textBottom = shapedText.bottom * size; auto textWidth = textRight - textLeft; auto textHeight = textBottom - textTop; - auto padT = layout.get<IconTextFitPadding>()[0]; - auto padR = layout.get<IconTextFitPadding>()[1]; - auto padB = layout.get<IconTextFitPadding>()[2]; - auto padL = layout.get<IconTextFitPadding>()[3]; - auto offsetY = layout.get<IconTextFit>() == IconTextFitType::Width ? (textHeight - iconHeight) * 0.5 : 0; - auto offsetX = layout.get<IconTextFit>() == IconTextFitType::Height ? (textWidth - iconWidth) * 0.5 : 0; - auto width = layout.get<IconTextFit>() == IconTextFitType::Width || layout.get<IconTextFit>() == IconTextFitType::Both ? textWidth : iconWidth; - auto height = layout.get<IconTextFit>() == IconTextFitType::Height || layout.get<IconTextFit>() == IconTextFitType::Both ? textHeight : iconHeight; + auto padT = layout.iconTextFitPadding[0]; + auto padR = layout.iconTextFitPadding[1]; + auto padB = layout.iconTextFitPadding[2]; + auto padL = layout.iconTextFitPadding[3]; + auto offsetY = layout.iconTextFit == IconTextFitType::Width ? (textHeight - iconHeight) * 0.5 : 0; + auto offsetX = layout.iconTextFit == IconTextFitType::Height ? (textWidth - iconWidth) * 0.5 : 0; + auto width = layout.iconTextFit == IconTextFitType::Width || layout.iconTextFit == IconTextFitType::Both ? textWidth : iconWidth; + auto height = layout.iconTextFit == IconTextFitType::Height || layout.iconTextFit == IconTextFitType::Both ? textHeight : iconHeight; left = textLeft + offsetX - padL; top = textTop + offsetY - padT; right = textLeft + offsetX + padR + width; @@ -95,10 +95,10 @@ SymbolQuads getGlyphQuads(const Shaping& shapedText, const SymbolLayoutProperties::Evaluated& layout, const style::SymbolPlacementType placement, const GlyphPositionMap& positions) { - const float textRotate = layout.get<TextRotate>() * util::DEG2RAD; + const float textRotate = layout.textRotate * util::DEG2RAD; const float oneEm = 24.0; - std::array<float, 2> textOffset = layout.get<TextOffset>(); + std::array<float, 2> textOffset = layout.textOffset; textOffset[0] *= oneEm; textOffset[1] *= oneEm; @@ -117,7 +117,7 @@ SymbolQuads getGlyphQuads(const Shaping& shapedText, const float rectBuffer = 3.0f + glyphPadding; const float halfAdvance = glyph.metrics.advance / 2.0; - const bool alongLine = layout.get<TextRotationAlignment>() == AlignmentType::Map && placement != SymbolPlacementType::Point; + const bool alongLine = layout.textRotationAlignment == AlignmentType::Map && placement != SymbolPlacementType::Point; const Point<float> glyphOffset = alongLine ? Point<float>{ positionedGlyph.x + halfAdvance, positionedGlyph.y } : diff --git a/test/style/conversion/layer.test.cpp b/test/style/conversion/layer.test.cpp index 33cd32999..500302354 100644 --- a/test/style/conversion/layer.test.cpp +++ b/test/style/conversion/layer.test.cpp @@ -27,7 +27,7 @@ TEST(StyleConversion, LayerTransition) { })JSON"); ASSERT_EQ(400ms, *layer->as<BackgroundLayer>()->impl().paint - .get<BackgroundColor>().options.duration); + .backgroundColor.options.duration); ASSERT_EQ(500ms, *layer->as<BackgroundLayer>()->impl().paint - .get<BackgroundColor>().options.delay); + .backgroundColor.options.delay); } |