summaryrefslogtreecommitdiff
path: root/src/mbgl/renderer
diff options
context:
space:
mode:
authorJohn Firebaugh <john.firebaugh@gmail.com>2016-10-30 11:06:59 -0700
committerJohn Firebaugh <john.firebaugh@gmail.com>2016-11-17 15:13:38 -0800
commit38fcbe21d48186c4630a3b8a76d1b20e156faadd (patch)
tree098f73bfea98deb5202fe1c13b1277e43e322755 /src/mbgl/renderer
parentd4fc66af3924805d40576989c1e139ddafcc4670 (diff)
downloadqtlocation-mapboxgl-38fcbe21d48186c4630a3b8a76d1b20e156faadd.tar.gz
[core] Convert style properties to a tuple-based approach
This converts the style property classes (CirclePaintProperties and so on) to the same tuple-based approach as gl::Attribute and gl::Uniform. The approach is outlined in https://github.com/mapbox/cpp/blob/master/C%2B%2B%20Structural%20Metaprogramming.md. The main advantage of this approach is it allows writing algorithms that work on sets of style properties, without resorting to code generation or manually repetitive code. This lets us iterate on approaches to data-driven properties more easily. Another advantage is that the cascading, unevaluated, and evaluated states of a set of properties exist as independent structures, instead of individual properties holding their own state. This is a more functional approach that makes data flow clearer and reduces state.
Diffstat (limited to 'src/mbgl/renderer')
-rw-r--r--src/mbgl/renderer/line_bucket.cpp10
-rw-r--r--src/mbgl/renderer/line_bucket.hpp2
-rw-r--r--src/mbgl/renderer/painter_background.cpp18
-rw-r--r--src/mbgl/renderer/painter_circle.cpp20
-rw-r--r--src/mbgl/renderer/painter_fill.cpp38
-rw-r--r--src/mbgl/renderer/painter_line.cpp16
-rw-r--r--src/mbgl/renderer/painter_raster.cpp14
-rw-r--r--src/mbgl/renderer/painter_symbol.cpp4
-rw-r--r--src/mbgl/renderer/symbol_bucket.cpp2
-rw-r--r--src/mbgl/renderer/symbol_bucket.hpp4
10 files changed, 65 insertions, 63 deletions
diff --git a/src/mbgl/renderer/line_bucket.cpp b/src/mbgl/renderer/line_bucket.cpp
index 554fef5ca7..007060bd1b 100644
--- a/src/mbgl/renderer/line_bucket.cpp
+++ b/src/mbgl/renderer/line_bucket.cpp
@@ -64,7 +64,7 @@ void LineBucket::addGeometry(const GeometryCoordinates& coordinates) {
return;
}
- const float miterLimit = layout.lineJoin == LineJoinType::Bevel ? 1.05f : float(layout.lineMiterLimit);
+ const float miterLimit = layout.get<LineJoin>() == LineJoinType::Bevel ? 1.05f : float(layout.get<LineMiterLimit>());
const double sharpCornerOffset = SHARP_CORNER_OFFSET * (float(util::EXTENT) / (util::tileSize * overscaling));
@@ -77,8 +77,8 @@ void LineBucket::addGeometry(const GeometryCoordinates& coordinates) {
return;
}
- const LineCapType beginCap = layout.lineCap;
- const LineCapType endCap = closed ? LineCapType::Butt : LineCapType(layout.lineCap);
+ const LineCapType beginCap = layout.get<LineCap>();
+ const LineCapType endCap = closed ? LineCapType::Butt : LineCapType(layout.get<LineCap>());
double distance = 0;
bool startOfLine = true;
@@ -171,12 +171,12 @@ void LineBucket::addGeometry(const GeometryCoordinates& coordinates) {
// The join if a middle vertex, otherwise the cap
const bool middleVertex = prevCoordinate && nextCoordinate;
- LineJoinType currentJoin = layout.lineJoin;
+ LineJoinType currentJoin = layout.get<LineJoin>();
const LineCapType currentCap = nextCoordinate ? beginCap : endCap;
if (middleVertex) {
if (currentJoin == LineJoinType::Round) {
- if (miterLength < layout.lineRoundLimit) {
+ if (miterLength < layout.get<LineRoundLimit>()) {
currentJoin = LineJoinType::Miter;
} else if (miterLength <= 2) {
currentJoin = LineJoinType::FakeRound;
diff --git a/src/mbgl/renderer/line_bucket.hpp b/src/mbgl/renderer/line_bucket.hpp
index ae9d7d7f0e..d11d78ff69 100644
--- a/src/mbgl/renderer/line_bucket.hpp
+++ b/src/mbgl/renderer/line_bucket.hpp
@@ -24,7 +24,7 @@ public:
void addGeometry(const GeometryCollection&);
void addGeometry(const GeometryCoordinates& line);
- style::LineLayoutProperties layout;
+ style::LineLayoutProperties::Evaluated layout;
gl::VertexVector<LineVertex> vertices;
gl::IndexVector<gl::Triangles> triangles;
diff --git a/src/mbgl/renderer/painter_background.cpp b/src/mbgl/renderer/painter_background.cpp
index 4e87829914..acf327a5d4 100644
--- a/src/mbgl/renderer/painter_background.cpp
+++ b/src/mbgl/renderer/painter_background.cpp
@@ -14,13 +14,13 @@ using namespace style;
void Painter::renderBackground(PaintParameters& parameters, const BackgroundLayer& layer) {
// Note that for bottommost layers without a pattern, the background color is drawn with
// glClear rather than this method.
- const BackgroundPaintProperties& properties = layer.impl->paint;
+ const BackgroundPaintProperties::Evaluated& properties = layer.impl->paint.evaluated;
- if (!properties.backgroundPattern.value.to.empty()) {
+ if (!properties.get<BackgroundPattern>().to.empty()) {
optional<SpriteAtlasPosition> imagePosA = spriteAtlas->getPosition(
- properties.backgroundPattern.value.from, SpritePatternMode::Repeating);
+ properties.get<BackgroundPattern>().from, SpritePatternMode::Repeating);
optional<SpriteAtlasPosition> imagePosB = spriteAtlas->getPosition(
- properties.backgroundPattern.value.to, SpritePatternMode::Repeating);
+ properties.get<BackgroundPattern>().to, SpritePatternMode::Repeating);
if (!imagePosA || !imagePosB)
return;
@@ -36,11 +36,11 @@ void Painter::renderBackground(PaintParameters& parameters, const BackgroundLaye
colorModeForRenderPass(),
FillPatternUniforms::values(
matrixForTile(tileID),
- properties.backgroundOpacity.value,
+ properties.get<BackgroundOpacity>(),
context.viewport.getCurrentValue().size,
*imagePosA,
*imagePosB,
- properties.backgroundPattern.value,
+ properties.get<BackgroundPattern>(),
tileID,
state
),
@@ -58,9 +58,9 @@ void Painter::renderBackground(PaintParameters& parameters, const BackgroundLaye
colorModeForRenderPass(),
FillProgram::UniformValues {
uniforms::u_matrix::Value{ matrixForTile(tileID) },
- uniforms::u_opacity::Value{ properties.backgroundOpacity.value },
- uniforms::u_color::Value{ properties.backgroundColor.value },
- uniforms::u_outline_color::Value{ properties.backgroundColor.value },
+ uniforms::u_opacity::Value{ properties.get<BackgroundOpacity>() },
+ uniforms::u_color::Value{ properties.get<BackgroundColor>() },
+ uniforms::u_outline_color::Value{ properties.get<BackgroundColor>() },
uniforms::u_world::Value{ context.viewport.getCurrentValue().size },
},
tileTriangleVertexBuffer,
diff --git a/src/mbgl/renderer/painter_circle.cpp b/src/mbgl/renderer/painter_circle.cpp
index 763181605f..0767a50943 100644
--- a/src/mbgl/renderer/painter_circle.cpp
+++ b/src/mbgl/renderer/painter_circle.cpp
@@ -20,8 +20,8 @@ void Painter::renderCircle(PaintParameters& parameters,
return;
}
- const CirclePaintProperties& properties = layer.impl->paint;
- const bool scaleWithMap = properties.circlePitchScale.value == CirclePitchScaleType::Map;
+ const CirclePaintProperties::Evaluated& properties = layer.impl->paint.evaluated;
+ const bool scaleWithMap = properties.get<CirclePitchScale>() == CirclePitchScaleType::Map;
parameters.programs.circle.draw(
context,
@@ -32,13 +32,15 @@ void Painter::renderCircle(PaintParameters& parameters,
: gl::StencilMode::disabled(),
colorModeForRenderPass(),
CircleProgram::UniformValues {
- uniforms::u_matrix::Value{ tile.translatedMatrix(properties.circleTranslate.value,
- properties.circleTranslateAnchor.value,
- state) },
- uniforms::u_opacity::Value{ properties.circleOpacity.value },
- uniforms::u_color::Value{ properties.circleColor.value },
- uniforms::u_radius::Value{ properties.circleRadius.value },
- uniforms::u_blur::Value{ properties.circleBlur.value },
+ uniforms::u_matrix::Value{
+ tile.translatedMatrix(properties.get<CircleTranslate>(),
+ properties.get<CircleTranslateAnchor>(),
+ state)
+ },
+ uniforms::u_opacity::Value{ properties.get<CircleOpacity>() },
+ uniforms::u_color::Value{ properties.get<CircleColor>() },
+ uniforms::u_radius::Value{ properties.get<CircleRadius>() },
+ uniforms::u_blur::Value{ properties.get<CircleBlur>() },
uniforms::u_scale_with_map::Value{ scaleWithMap },
uniforms::u_extrude_scale::Value{ scaleWithMap
? std::array<float, 2> {{
diff --git a/src/mbgl/renderer/painter_fill.cpp b/src/mbgl/renderer/painter_fill.cpp
index e5a536fde3..356ccfc0b2 100644
--- a/src/mbgl/renderer/painter_fill.cpp
+++ b/src/mbgl/renderer/painter_fill.cpp
@@ -17,17 +17,17 @@ void Painter::renderFill(PaintParameters& parameters,
FillBucket& bucket,
const FillLayer& layer,
const RenderTile& tile) {
- const FillPaintProperties& properties = layer.impl->paint;
+ const FillPaintProperties::Evaluated& properties = layer.impl->paint.evaluated;
- if (!properties.fillPattern.value.from.empty()) {
+ if (!properties.get<FillPattern>().from.empty()) {
if (pass != RenderPass::Translucent) {
return;
}
optional<SpriteAtlasPosition> imagePosA = spriteAtlas->getPosition(
- properties.fillPattern.value.from, SpritePatternMode::Repeating);
+ properties.get<FillPattern>().from, SpritePatternMode::Repeating);
optional<SpriteAtlasPosition> imagePosB = spriteAtlas->getPosition(
- properties.fillPattern.value.to, SpritePatternMode::Repeating);
+ properties.get<FillPattern>().to, SpritePatternMode::Repeating);
if (!imagePosA || !imagePosB) {
return;
@@ -48,14 +48,14 @@ void Painter::renderFill(PaintParameters& parameters,
stencilModeForClipping(tile.clip),
colorModeForRenderPass(),
FillPatternUniforms::values(
- tile.translatedMatrix(properties.fillTranslate.value,
- properties.fillTranslateAnchor.value,
+ tile.translatedMatrix(properties.get<FillTranslate>(),
+ properties.get<FillTranslateAnchor>(),
state),
- properties.fillOpacity.value,
+ properties.get<FillOpacity>(),
context.viewport.getCurrentValue().size,
*imagePosA,
*imagePosB,
- properties.fillPattern.value,
+ properties.get<FillPattern>(),
tile.id,
state
),
@@ -72,7 +72,7 @@ void Painter::renderFill(PaintParameters& parameters,
*bucket.triangleIndexBuffer,
bucket.triangleSegments);
- if (!properties.fillAntialias.value || !properties.fillOutlineColor.isUndefined()) {
+ if (!properties.get<FillAntialias>() || !layer.impl->paint.unevaluated.get<FillOutlineColor>().isUndefined()) {
return;
}
@@ -97,11 +97,11 @@ void Painter::renderFill(PaintParameters& parameters,
stencilModeForClipping(tile.clip),
colorModeForRenderPass(),
FillProgram::UniformValues {
- uniforms::u_matrix::Value{ tile.translatedMatrix(properties.fillTranslate.value,
- properties.fillTranslateAnchor.value,
+ uniforms::u_matrix::Value{ tile.translatedMatrix(properties.get<FillTranslate>(),
+ properties.get<FillTranslateAnchor>(),
state) },
- uniforms::u_opacity::Value{ properties.fillOpacity.value },
- uniforms::u_color::Value{ properties.fillColor.value },
+ uniforms::u_opacity::Value{ properties.get<FillOpacity>() },
+ uniforms::u_color::Value{ properties.get<FillColor>() },
uniforms::u_outline_color::Value{ outlineColor },
uniforms::u_world::Value{ context.viewport.getCurrentValue().size },
},
@@ -111,10 +111,10 @@ void Painter::renderFill(PaintParameters& parameters,
);
};
- if (properties.fillAntialias.value && !properties.fillOutlineColor.isUndefined() && pass == RenderPass::Translucent) {
+ if (properties.get<FillAntialias>() && !layer.impl->paint.unevaluated.get<FillOutlineColor>().isUndefined() && pass == RenderPass::Translucent) {
draw(2,
parameters.programs.fillOutline,
- properties.fillOutlineColor.value,
+ properties.get<FillOutlineColor>(),
gl::Lines { 2.0f },
*bucket.vertexBuffer,
*bucket.lineIndexBuffer,
@@ -123,20 +123,20 @@ void Painter::renderFill(PaintParameters& parameters,
// 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 ((properties.fillColor.value.a >= 1.0f && properties.fillOpacity.value >= 1.0f) == (pass == RenderPass::Opaque)) {
+ if ((properties.get<FillColor>().a >= 1.0f && properties.get<FillOpacity>() >= 1.0f) == (pass == RenderPass::Opaque)) {
draw(1,
parameters.programs.fill,
- properties.fillOutlineColor.value,
+ properties.get<FillOutlineColor>(),
gl::Triangles(),
*bucket.vertexBuffer,
*bucket.triangleIndexBuffer,
bucket.triangleSegments);
}
- if (properties.fillAntialias.value && properties.fillOutlineColor.isUndefined() && pass == RenderPass::Translucent) {
+ if (properties.get<FillAntialias>() && layer.impl->paint.unevaluated.get<FillOutlineColor>().isUndefined() && pass == RenderPass::Translucent) {
draw(2,
parameters.programs.fillOutline,
- properties.fillColor.value,
+ properties.get<FillColor>(),
gl::Lines { 2.0f },
*bucket.vertexBuffer,
*bucket.lineIndexBuffer,
diff --git a/src/mbgl/renderer/painter_line.cpp b/src/mbgl/renderer/painter_line.cpp
index 151228ee95..a66f53a856 100644
--- a/src/mbgl/renderer/painter_line.cpp
+++ b/src/mbgl/renderer/painter_line.cpp
@@ -21,7 +21,7 @@ void Painter::renderLine(PaintParameters& parameters,
return;
}
- const auto& properties = layer.impl->paint;
+ const LinePaintProperties::Evaluated& properties = layer.impl->paint.evaluated;
auto draw = [&] (auto& program, auto&& uniformValues) {
program.draw(
@@ -37,11 +37,11 @@ void Painter::renderLine(PaintParameters& parameters,
);
};
- if (!properties.lineDasharray.value.from.empty()) {
- const LinePatternCap cap = bucket.layout.lineCap == LineCapType::Round
+ if (!properties.get<LineDasharray>().from.empty()) {
+ const LinePatternCap cap = bucket.layout.get<LineCap>() == LineCapType::Round
? LinePatternCap::Round : LinePatternCap::Square;
- LinePatternPos posA = lineAtlas->getDashPosition(properties.lineDasharray.value.from, cap);
- LinePatternPos posB = lineAtlas->getDashPosition(properties.lineDasharray.value.to, cap);
+ LinePatternPos posA = lineAtlas->getDashPosition(properties.get<LineDasharray>().from, cap);
+ LinePatternPos posB = lineAtlas->getDashPosition(properties.get<LineDasharray>().to, cap);
lineAtlas->bind(context, 0);
@@ -56,11 +56,11 @@ void Painter::renderLine(PaintParameters& parameters,
layer.impl->dashLineWidth,
lineAtlas->getSize().width));
- } else if (!properties.linePattern.value.from.empty()) {
+ } else if (!properties.get<LinePattern>().from.empty()) {
optional<SpriteAtlasPosition> posA = spriteAtlas->getPosition(
- properties.linePattern.value.from, SpritePatternMode::Repeating);
+ properties.get<LinePattern>().from, SpritePatternMode::Repeating);
optional<SpriteAtlasPosition> posB = spriteAtlas->getPosition(
- properties.linePattern.value.to, SpritePatternMode::Repeating);
+ properties.get<LinePattern>().to, SpritePatternMode::Repeating);
if (!posA || !posB)
return;
diff --git a/src/mbgl/renderer/painter_raster.cpp b/src/mbgl/renderer/painter_raster.cpp
index fe25878016..950d37abf2 100644
--- a/src/mbgl/renderer/painter_raster.cpp
+++ b/src/mbgl/renderer/painter_raster.cpp
@@ -48,7 +48,7 @@ void Painter::renderRaster(PaintParameters& parameters,
if (!bucket.hasData())
return;
- const RasterPaintProperties& properties = layer.impl->paint;
+ const RasterPaintProperties::Evaluated& properties = layer.impl->paint.evaluated;
assert(bucket.texture);
context.bindTexture(*bucket.texture, 0, gl::TextureFilter::Linear);
@@ -64,13 +64,13 @@ void Painter::renderRaster(PaintParameters& parameters,
uniforms::u_matrix::Value{ tile.matrix },
uniforms::u_image0::Value{ 0 },
uniforms::u_image1::Value{ 1 },
- uniforms::u_opacity0::Value{ properties.rasterOpacity.value },
+ uniforms::u_opacity0::Value{ properties.get<RasterOpacity>() },
uniforms::u_opacity1::Value{ 0 },
- uniforms::u_brightness_low::Value{ properties.rasterBrightnessMin.value },
- uniforms::u_brightness_high::Value{ properties.rasterBrightnessMax.value },
- uniforms::u_saturation_factor::Value{ saturationFactor(properties.rasterSaturation.value) },
- uniforms::u_contrast_factor::Value{ contrastFactor(properties.rasterContrast.value) },
- uniforms::u_spin_weights::Value{ spinWeights(properties.rasterHueRotate.value) },
+ uniforms::u_brightness_low::Value{ properties.get<RasterBrightnessMin>() },
+ uniforms::u_brightness_high::Value{ properties.get<RasterBrightnessMax>() },
+ uniforms::u_saturation_factor::Value{ saturationFactor(properties.get<RasterSaturation>()) },
+ uniforms::u_contrast_factor::Value{ contrastFactor(properties.get<RasterContrast>()) },
+ uniforms::u_spin_weights::Value{ spinWeights(properties.get<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 }} },
diff --git a/src/mbgl/renderer/painter_symbol.cpp b/src/mbgl/renderer/painter_symbol.cpp
index 8c1948e458..d4effe3f9d 100644
--- a/src/mbgl/renderer/painter_symbol.cpp
+++ b/src/mbgl/renderer/painter_symbol.cpp
@@ -43,8 +43,8 @@ void Painter::renderSymbol(PaintParameters& parameters,
// tile edges the icons are included in both tiles and clipped when drawing.
//
// TODO remove the `true ||` when #1673 is implemented
- const bool drawAcrossEdges = (frame.mapMode == MapMode::Continuous) && (true || !(layout.textAllowOverlap || layout.iconAllowOverlap ||
- layout.textIgnorePlacement || layout.iconIgnorePlacement));
+ const bool drawAcrossEdges = (frame.mapMode == MapMode::Continuous) && (true || !(layout.get<TextAllowOverlap>() || layout.get<IconAllowOverlap>() ||
+ layout.get<TextIgnorePlacement>() || layout.get<IconIgnorePlacement>()));
program.draw(
context,
diff --git a/src/mbgl/renderer/symbol_bucket.cpp b/src/mbgl/renderer/symbol_bucket.cpp
index 81170646bc..0f2c89339f 100644
--- a/src/mbgl/renderer/symbol_bucket.cpp
+++ b/src/mbgl/renderer/symbol_bucket.cpp
@@ -7,7 +7,7 @@ namespace mbgl {
using namespace style;
SymbolBucket::SymbolBucket(const MapMode mode_,
- style::SymbolLayoutProperties layout_,
+ style::SymbolLayoutProperties::Evaluated layout_,
bool sdfIcons_,
bool iconsNeedLinear_)
: mode(mode_),
diff --git a/src/mbgl/renderer/symbol_bucket.hpp b/src/mbgl/renderer/symbol_bucket.hpp
index e5c44d8a3c..d62a61aab7 100644
--- a/src/mbgl/renderer/symbol_bucket.hpp
+++ b/src/mbgl/renderer/symbol_bucket.hpp
@@ -17,7 +17,7 @@ namespace mbgl {
class SymbolBucket : public Bucket {
public:
SymbolBucket(const MapMode,
- style::SymbolLayoutProperties,
+ style::SymbolLayoutProperties::Evaluated,
bool sdfIcons,
bool iconsNeedLinear);
@@ -29,7 +29,7 @@ public:
bool hasCollisionBoxData() const;
const MapMode mode;
- const style::SymbolLayoutProperties layout;
+ const style::SymbolLayoutProperties::Evaluated layout;
const bool sdfIcons;
const bool iconsNeedLinear;