[core] Introduce a fully-evaluated tuple type for layout properties

This commit is contained in:
John Firebaugh
2017-03-30 15:56:35 -07:00
parent 939526bac4
commit d7a55a4be1
14 changed files with 84 additions and 42 deletions

View File

@@ -9,7 +9,7 @@ SymbolInstance::SymbolInstance(Anchor& anchor,
const GeometryCoordinates& line,
const std::pair<Shaping, Shaping>& shapedTextOrientations,
const PositionedIcon& shapedIcon,
const SymbolLayoutProperties::Evaluated& layout,
const SymbolLayoutProperties::PossiblyEvaluated& layout,
const bool addToBuffers,
const uint32_t index_,
const float textBoxScale,

View File

@@ -16,7 +16,7 @@ public:
const GeometryCoordinates& line,
const std::pair<Shaping, Shaping>& shapedTextOrientations,
const PositionedIcon& shapedIcon,
const style::SymbolLayoutProperties::Evaluated&,
const style::SymbolLayoutProperties::PossiblyEvaluated&,
const bool inside,
const uint32_t index,
const float textBoxScale,

View File

@@ -78,7 +78,7 @@ private:
const float zoom;
const MapMode mode;
style::SymbolLayoutProperties::Evaluated layout;
style::SymbolLayoutProperties::PossiblyEvaluated layout;
float textMaxSize;
SpriteAtlas& spriteAtlas;

View File

@@ -29,7 +29,7 @@ public:
void upload(gl::Context&) override;
void render(Painter&, PaintParameters&, const style::Layer&, const RenderTile&) override;
style::LineLayoutProperties::Evaluated layout;
style::LineLayoutProperties::PossiblyEvaluated layout;
gl::VertexVector<LineLayoutVertex> vertices;
gl::IndexVector<gl::Triangles> triangles;

View File

@@ -8,7 +8,7 @@ namespace mbgl {
using namespace style;
SymbolBucket::SymbolBucket(style::SymbolLayoutProperties::Evaluated layout_,
SymbolBucket::SymbolBucket(style::SymbolLayoutProperties::PossiblyEvaluated layout_,
const std::map<std::string, std::pair<
style::IconPaintProperties::Evaluated, style::TextPaintProperties::Evaluated>>& layerPaintProperties,
float zoom,

View File

@@ -16,7 +16,7 @@ namespace mbgl {
class SymbolBucket : public Bucket {
public:
SymbolBucket(style::SymbolLayoutProperties::Evaluated,
SymbolBucket(style::SymbolLayoutProperties::PossiblyEvaluated,
const std::map<std::string, std::pair<style::IconPaintProperties::Evaluated, style::TextPaintProperties::Evaluated>>&,
float zoom,
bool sdfIcons,
@@ -29,7 +29,7 @@ public:
bool hasIconData() const;
bool hasCollisionBoxData() const;
const style::SymbolLayoutProperties::Evaluated layout;
const style::SymbolLayoutProperties::PossiblyEvaluated layout;
const bool sdfIcons;
const bool iconsNeedLinear;

View File

@@ -68,7 +68,7 @@ TextPaintProperties::Evaluated SymbolLayer::Impl::textPaintProperties() const {
}
SymbolPropertyValues SymbolLayer::Impl::iconPropertyValues(const SymbolLayoutProperties::Evaluated& layout_) const {
SymbolPropertyValues SymbolLayer::Impl::iconPropertyValues(const SymbolLayoutProperties::PossiblyEvaluated& layout_) const {
return SymbolPropertyValues {
layout_.get<IconRotationAlignment>(), // icon-pitch-alignment is not yet implemented; inherit the rotation alignment
layout_.get<IconRotationAlignment>(),
@@ -83,7 +83,7 @@ SymbolPropertyValues SymbolLayer::Impl::iconPropertyValues(const SymbolLayoutPro
};
}
SymbolPropertyValues SymbolLayer::Impl::textPropertyValues(const SymbolLayoutProperties::Evaluated& layout_) const {
SymbolPropertyValues SymbolLayer::Impl::textPropertyValues(const SymbolLayoutProperties::PossiblyEvaluated& layout_) const {
return SymbolPropertyValues {
layout_.get<TextPitchAlignment>(),
layout_.get<TextRotationAlignment>(),

View File

@@ -72,8 +72,8 @@ public:
IconPaintProperties::Evaluated iconPaintProperties() const;
TextPaintProperties::Evaluated textPaintProperties() const;
SymbolPropertyValues iconPropertyValues(const SymbolLayoutProperties::Evaluated&) const;
SymbolPropertyValues textPropertyValues(const SymbolLayoutProperties::Evaluated&) const;
SymbolPropertyValues iconPropertyValues(const SymbolLayoutProperties::PossiblyEvaluated&) const;
SymbolPropertyValues textPropertyValues(const SymbolLayoutProperties::PossiblyEvaluated&) const;
SymbolLayoutProperties layout;
SymbolPaintProperties paint;

View File

@@ -16,7 +16,7 @@ class LayoutProperty {
public:
using UnevaluatedType = PropertyValue<T>;
using EvaluatorType = PropertyEvaluator<T>;
using EvaluatedType = T;
using PossiblyEvaluatedType = T;
using Type = T;
};
@@ -25,7 +25,7 @@ class DataDrivenLayoutProperty {
public:
using UnevaluatedType = DataDrivenPropertyValue<T>;
using EvaluatorType = DataDrivenPropertyEvaluator<T>;
using EvaluatedType = PossiblyEvaluatedPropertyValue<T>;
using PossiblyEvaluatedType = PossiblyEvaluatedPropertyValue<T>;
using Type = T;
};
@@ -33,23 +33,65 @@ template <class... Ps>
class LayoutProperties {
public:
using Properties = TypeList<Ps...>;
using EvaluatedTypes = TypeList<typename Ps::EvaluatedType...>;
using UnevaluatedTypes = TypeList<typename Ps::UnevaluatedType...>;
template <class TypeList>
using Tuple = IndexedTuple<Properties, TypeList>;
/*
For layout 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 non-data-driven property values have been fully evaluated, and data-driven 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 that a purposeful optimization.
*/
using UnevaluatedTypes = TypeList<typename Ps::UnevaluatedType...>;
using PossiblyEvaluatedTypes = TypeList<typename Ps::PossiblyEvaluatedType...>;
using EvaluatedTypes = TypeList<typename Ps::Type...>;
class Evaluated : public Tuple<EvaluatedTypes> {
public:
using Tuple<EvaluatedTypes>::Tuple;
};
class PossiblyEvaluated : public Tuple<PossiblyEvaluatedTypes> {
public:
using Tuple<PossiblyEvaluatedTypes>::Tuple;
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 SourceFunction<T>& t) {
return t.evaluate(feature, defaultValue);
},
[&] (const CompositeFunction<T>& t) {
return t.evaluate(z, feature, defaultValue);
});
}
template <class P>
typename P::Type evaluate(float z, const GeometryTileFeature& feature) const {
using T = typename P::Type;
return this->template get<P>().match(
[&] (const T& t) { return t; },
[&] (const SourceFunction<T>& t) { return t.evaluate(feature, P::defaultValue()); },
[&] (const CompositeFunction<T>& t) { return t.evaluate(z, feature, P::defaultValue()); });
auto evaluate(float z, const GeometryTileFeature& feature) const {
return evaluate(z, feature, this->template get<P>(), P::defaultValue());
}
Evaluated evaluate(float z, const GeometryTileFeature& feature) const {
return Evaluated {
evaluate<Ps>(z, feature)...
};
}
};
@@ -65,8 +107,8 @@ public:
.evaluate(Evaluator(parameters, P::defaultValue()));
}
Evaluated evaluate(const PropertyEvaluationParameters& parameters) const {
return Evaluated {
PossiblyEvaluated evaluate(const PropertyEvaluationParameters& parameters) const {
return PossiblyEvaluated {
evaluate<Ps>(parameters)...
};
}

View File

@@ -18,7 +18,7 @@ const float globalMinScale = 0.5f; // underscale by 1 zoom level
SymbolQuad getIconQuad(const Anchor& anchor,
const PositionedIcon& shapedIcon,
const GeometryCoordinates& line,
const SymbolLayoutProperties::Evaluated& layout,
const SymbolLayoutProperties::PossiblyEvaluated& layout,
const style::SymbolPlacementType placement,
const Shaping& shapedText) {
auto image = *(shapedIcon.image);
@@ -292,7 +292,7 @@ SymbolQuads getGlyphQuads(Anchor& anchor,
const Shaping& shapedText,
const float boxScale,
const GeometryCoordinates& line,
const SymbolLayoutProperties::Evaluated& layout,
const SymbolLayoutProperties::PossiblyEvaluated& layout,
const style::SymbolPlacementType placement,
const GlyphPositions& face) {
const float textRotate = layout.get<TextRotate>() * util::DEG2RAD;

View File

@@ -54,7 +54,7 @@ typedef std::vector<SymbolQuad> SymbolQuads;
SymbolQuad getIconQuad(const Anchor& anchor,
const PositionedIcon& shapedIcon,
const GeometryCoordinates& line,
const style::SymbolLayoutProperties::Evaluated&,
const style::SymbolLayoutProperties::PossiblyEvaluated&,
style::SymbolPlacementType placement,
const Shaping& shapedText);
@@ -62,7 +62,7 @@ SymbolQuads getGlyphQuads(Anchor& anchor,
const Shaping& shapedText,
const float boxScale,
const GeometryCoordinates& line,
const style::SymbolLayoutProperties::Evaluated&,
const style::SymbolLayoutProperties::PossiblyEvaluated&,
style::SymbolPlacementType placement,
const GlyphPositions& face);

View File

@@ -27,7 +27,7 @@ TEST(Buckets, LineBucket) {
}
TEST(Buckets, SymbolBucket) {
style::SymbolLayoutProperties::Evaluated layout;
style::SymbolLayoutProperties::PossiblyEvaluated layout;
bool sdfIcons = false;
bool iconsNeedLinear = false;

View File

@@ -10,7 +10,7 @@ using namespace mbgl;
using namespace mbgl::style;
TEST(getIconQuads, normal) {
SymbolLayoutProperties::Evaluated layout;
SymbolLayoutProperties::PossiblyEvaluated layout;
Anchor anchor(2.0, 3.0, 0.0, 0.5f, 0);
SpriteAtlasElement image = {
Rect<uint16_t>( 0, 0, 15, 11 ),
@@ -59,7 +59,7 @@ TEST(getIconQuads, style) {
// none
{
SymbolLayoutProperties::Evaluated layout;
SymbolLayoutProperties::PossiblyEvaluated layout;
SymbolQuad quad =
getIconQuad(anchor, shapedIcon, line, layout, SymbolPlacementType::Point, shapedText);
@@ -80,7 +80,7 @@ TEST(getIconQuads, style) {
// width
{
SymbolLayoutProperties::Evaluated layout;
SymbolLayoutProperties::PossiblyEvaluated layout;
layout.get<TextSize>() = 24.0f;
layout.get<IconTextFit>() = IconTextFitType::Width;
SymbolQuad quad =
@@ -98,7 +98,7 @@ TEST(getIconQuads, style) {
// width x textSize
{
SymbolLayoutProperties::Evaluated layout;
SymbolLayoutProperties::PossiblyEvaluated layout;
layout.get<TextSize>() = 12.0f;
layout.get<IconTextFit>() = IconTextFitType::Width;
SymbolQuad quad =
@@ -116,7 +116,7 @@ TEST(getIconQuads, style) {
// width x textSize + padding
{
SymbolLayoutProperties::Evaluated layout;
SymbolLayoutProperties::PossiblyEvaluated layout;
layout.get<TextSize>() = 12.0f;
layout.get<IconTextFit>() = IconTextFitType::Width;
layout.get<IconTextFitPadding>()[0] = 5.0f;
@@ -138,7 +138,7 @@ TEST(getIconQuads, style) {
// height
{
SymbolLayoutProperties::Evaluated layout;
SymbolLayoutProperties::PossiblyEvaluated layout;
layout.get<TextSize>() = 24.0f;
layout.get<IconTextFit>() = IconTextFitType::Height;
SymbolQuad quad =
@@ -156,7 +156,7 @@ TEST(getIconQuads, style) {
// height x textSize
{
SymbolLayoutProperties::Evaluated layout;
SymbolLayoutProperties::PossiblyEvaluated layout;
layout.get<TextSize>() = 12.0f;
layout.get<IconTextFit>() = IconTextFitType::Height;
SymbolQuad quad =
@@ -174,7 +174,7 @@ TEST(getIconQuads, style) {
// height x textSize + padding
{
SymbolLayoutProperties::Evaluated layout;
SymbolLayoutProperties::PossiblyEvaluated layout;
layout.get<TextSize>() = 12.0f;
layout.get<IconTextFit>() = IconTextFitType::Height;
layout.get<IconTextFitPadding>()[0] = 5.0f;
@@ -196,7 +196,7 @@ TEST(getIconQuads, style) {
// both
{
SymbolLayoutProperties::Evaluated layout;
SymbolLayoutProperties::PossiblyEvaluated layout;
layout.get<TextSize>() = 24.0f;
layout.get<IconTextFit>() = IconTextFitType::Both;
SymbolQuad quad =
@@ -214,7 +214,7 @@ TEST(getIconQuads, style) {
// both x textSize
{
SymbolLayoutProperties::Evaluated layout;
SymbolLayoutProperties::PossiblyEvaluated layout;
layout.get<TextSize>() = 12.0f;
layout.get<IconTextFit>() = IconTextFitType::Both;
SymbolQuad quad =
@@ -232,7 +232,7 @@ TEST(getIconQuads, style) {
// both x textSize + padding
{
SymbolLayoutProperties::Evaluated layout;
SymbolLayoutProperties::PossiblyEvaluated layout;
layout.get<TextSize>() = 12.0f;
layout.get<IconTextFit>() = IconTextFitType::Both;
layout.get<IconTextFitPadding>()[0] = 5.0f;
@@ -254,7 +254,7 @@ TEST(getIconQuads, style) {
// both x textSize + padding t/r/b/l
{
SymbolLayoutProperties::Evaluated layout;
SymbolLayoutProperties::PossiblyEvaluated layout;
layout.get<TextSize>() = 12.0f;
layout.get<IconTextFit>() = IconTextFitType::Both;
layout.get<IconTextFitPadding>()[0] = 0.0f;

View File

@@ -60,7 +60,7 @@ TEST(VectorTile, Issue7615) {
style::SymbolLayer symbolLayer("symbol", "source");
auto symbolBucket = std::make_shared<SymbolBucket>(
style::SymbolLayoutProperties::Evaluated(),
style::SymbolLayoutProperties::PossiblyEvaluated(),
std::map<
std::string,
std::pair<style::IconPaintProperties::Evaluated, style::TextPaintProperties::Evaluated>>(),
@@ -94,4 +94,4 @@ TEST(VectorTile, Issue8542) {
// Query before data is set
std::vector<Feature> result;
tile.querySourceFeatures(result, { { {"layer"} }, {} });
}
}