summaryrefslogtreecommitdiff
path: root/src/mbgl/renderer
diff options
context:
space:
mode:
Diffstat (limited to 'src/mbgl/renderer')
-rw-r--r--src/mbgl/renderer/bucket.hpp5
-rw-r--r--src/mbgl/renderer/bucket_parameters.cpp5
-rw-r--r--src/mbgl/renderer/bucket_parameters.hpp14
-rw-r--r--src/mbgl/renderer/circle_bucket.cpp24
-rw-r--r--src/mbgl/renderer/circle_bucket.hpp8
-rw-r--r--src/mbgl/renderer/fill_bucket.cpp18
-rw-r--r--src/mbgl/renderer/fill_bucket.hpp8
-rw-r--r--src/mbgl/renderer/group_by_layout.cpp48
-rw-r--r--src/mbgl/renderer/group_by_layout.hpp12
-rw-r--r--src/mbgl/renderer/line_bucket.cpp29
-rw-r--r--src/mbgl/renderer/line_bucket.hpp14
-rw-r--r--src/mbgl/renderer/painter.cpp20
-rw-r--r--src/mbgl/renderer/painter.hpp25
-rw-r--r--src/mbgl/renderer/painter_background.cpp6
-rw-r--r--src/mbgl/renderer/painter_circle.cpp6
-rw-r--r--src/mbgl/renderer/painter_fill.cpp12
-rw-r--r--src/mbgl/renderer/painter_line.cpp8
-rw-r--r--src/mbgl/renderer/painter_raster.cpp6
-rw-r--r--src/mbgl/renderer/painter_symbol.cpp12
-rw-r--r--src/mbgl/renderer/raster_bucket.cpp6
-rw-r--r--src/mbgl/renderer/raster_bucket.hpp2
-rw-r--r--src/mbgl/renderer/render_background_layer.cpp35
-rw-r--r--src/mbgl/renderer/render_background_layer.hpp34
-rw-r--r--src/mbgl/renderer/render_circle_layer.cpp65
-rw-r--r--src/mbgl/renderer/render_circle_layer.hpp41
-rw-r--r--src/mbgl/renderer/render_custom_layer.cpp26
-rw-r--r--src/mbgl/renderer/render_custom_layer.hpp29
-rw-r--r--src/mbgl/renderer/render_fill_extrusion_layer.cpp26
-rw-r--r--src/mbgl/renderer/render_fill_extrusion_layer.hpp32
-rw-r--r--src/mbgl/renderer/render_fill_layer.cpp70
-rw-r--r--src/mbgl/renderer/render_fill_layer.hpp41
-rw-r--r--src/mbgl/renderer/render_item.hpp6
-rw-r--r--src/mbgl/renderer/render_layer.cpp25
-rw-r--r--src/mbgl/renderer/render_layer.hpp87
-rw-r--r--src/mbgl/renderer/render_line_layer.cpp114
-rw-r--r--src/mbgl/renderer/render_line_layer.hpp48
-rw-r--r--src/mbgl/renderer/render_raster_layer.cpp33
-rw-r--r--src/mbgl/renderer/render_raster_layer.hpp34
-rw-r--r--src/mbgl/renderer/render_symbol_layer.cpp113
-rw-r--r--src/mbgl/renderer/render_symbol_layer.hpp97
-rw-r--r--src/mbgl/renderer/symbol_bucket.cpp8
-rw-r--r--src/mbgl/renderer/symbol_bucket.hpp2
42 files changed, 1139 insertions, 115 deletions
diff --git a/src/mbgl/renderer/bucket.hpp b/src/mbgl/renderer/bucket.hpp
index 84ecabe632..6c391cf014 100644
--- a/src/mbgl/renderer/bucket.hpp
+++ b/src/mbgl/renderer/bucket.hpp
@@ -3,6 +3,7 @@
#include <mbgl/renderer/render_pass.hpp>
#include <mbgl/util/noncopyable.hpp>
#include <mbgl/tile/geometry_tile_data.hpp>
+#include <mbgl/renderer/render_layer.hpp>
#include <atomic>
#include <string>
@@ -36,11 +37,11 @@ public:
// Every time this bucket is getting rendered, this function is called. This happens either
// once or twice (for Opaque and Transparent render passes).
- virtual void render(Painter&, PaintParameters&, const style::Layer&, const RenderTile&) = 0;
+ virtual void render(Painter&, PaintParameters&, const RenderLayer&, const RenderTile&) = 0;
virtual bool hasData() const = 0;
- virtual float getQueryRadius(const style::Layer&) const {
+ virtual float getQueryRadius(const RenderLayer&) const {
return 0;
};
diff --git a/src/mbgl/renderer/bucket_parameters.cpp b/src/mbgl/renderer/bucket_parameters.cpp
new file mode 100644
index 0000000000..35b87bffea
--- /dev/null
+++ b/src/mbgl/renderer/bucket_parameters.cpp
@@ -0,0 +1,5 @@
+#include <mbgl/renderer/bucket_parameters.hpp>
+
+namespace mbgl {
+
+} // namespace mbgl
diff --git a/src/mbgl/renderer/bucket_parameters.hpp b/src/mbgl/renderer/bucket_parameters.hpp
new file mode 100644
index 0000000000..1774ba2bbe
--- /dev/null
+++ b/src/mbgl/renderer/bucket_parameters.hpp
@@ -0,0 +1,14 @@
+#pragma once
+
+#include <mbgl/map/mode.hpp>
+#include <mbgl/tile/tile_id.hpp>
+
+namespace mbgl {
+
+class BucketParameters {
+public:
+ const OverscaledTileID tileID;
+ const MapMode mode;
+};
+
+} // namespace mbgl
diff --git a/src/mbgl/renderer/circle_bucket.cpp b/src/mbgl/renderer/circle_bucket.cpp
index 94529a66d8..1e08eca478 100644
--- a/src/mbgl/renderer/circle_bucket.cpp
+++ b/src/mbgl/renderer/circle_bucket.cpp
@@ -1,9 +1,9 @@
#include <mbgl/renderer/circle_bucket.hpp>
+#include <mbgl/renderer/bucket_parameters.hpp>
#include <mbgl/renderer/painter.hpp>
#include <mbgl/programs/circle_program.hpp>
-#include <mbgl/style/bucket_parameters.hpp>
-#include <mbgl/style/layers/circle_layer.hpp>
#include <mbgl/style/layers/circle_layer_impl.hpp>
+#include <mbgl/renderer/render_circle_layer.hpp>
#include <mbgl/util/constants.hpp>
#include <mbgl/util/math.hpp>
@@ -11,14 +11,14 @@ namespace mbgl {
using namespace style;
-CircleBucket::CircleBucket(const BucketParameters& parameters, const std::vector<const Layer*>& layers)
+CircleBucket::CircleBucket(const BucketParameters& parameters, const std::vector<const RenderLayer*>& layers)
: 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<CircleLayer>()->impl->paint.evaluated,
+ layer->as<RenderCircleLayer>()->evaluated,
parameters.tileID.overscaledZ));
}
}
@@ -36,9 +36,9 @@ void CircleBucket::upload(gl::Context& context) {
void CircleBucket::render(Painter& painter,
PaintParameters& parameters,
- const Layer& layer,
+ const RenderLayer& layer,
const RenderTile& tile) {
- painter.renderCircle(parameters, *this, *layer.as<CircleLayer>(), tile);
+ painter.renderCircle(parameters, *this, *layer.as<RenderCircleLayer>(), tile);
}
bool CircleBucket::hasData() const {
@@ -99,24 +99,24 @@ void CircleBucket::addFeature(const GeometryTileFeature& feature,
}
template <class Property>
-static float get(const CircleLayer& layer, const std::map<std::string, CircleProgram::PaintPropertyBinders>& paintPropertyBinders) {
+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.impl->paint.evaluated.get<Property>().constantOr(Property::defaultValue());
+ return layer.evaluated.get<Property>().constantOr(Property::defaultValue());
} else {
return *it->second.statistics<Property>().max();
}
}
-float CircleBucket::getQueryRadius(const style::Layer& layer) const {
- if (!layer.is<CircleLayer>()) {
+float CircleBucket::getQueryRadius(const RenderLayer& layer) const {
+ if (!layer.is<RenderCircleLayer>()) {
return 0;
}
- auto circleLayer = layer.as<CircleLayer>();
+ auto circleLayer = layer.as<RenderCircleLayer>();
float radius = get<CircleRadius>(*circleLayer, paintPropertyBinders);
- auto translate = circleLayer->impl->paint.evaluated.get<CircleTranslate>();
+ auto translate = circleLayer->evaluated.get<CircleTranslate>();
return radius + util::length(translate[0], translate[1]);
}
diff --git a/src/mbgl/renderer/circle_bucket.hpp b/src/mbgl/renderer/circle_bucket.hpp
index 02f60ad2ba..855565ebf4 100644
--- a/src/mbgl/renderer/circle_bucket.hpp
+++ b/src/mbgl/renderer/circle_bucket.hpp
@@ -11,22 +11,20 @@
namespace mbgl {
-namespace style {
class BucketParameters;
-} // namespace style
class CircleBucket : public Bucket {
public:
- CircleBucket(const style::BucketParameters&, const std::vector<const style::Layer*>&);
+ CircleBucket(const BucketParameters&, const std::vector<const RenderLayer*>&);
void addFeature(const GeometryTileFeature&,
const GeometryCollection&) override;
bool hasData() const override;
void upload(gl::Context&) override;
- void render(Painter&, PaintParameters&, const style::Layer&, const RenderTile&) override;
+ void render(Painter&, PaintParameters&, const RenderLayer&, const RenderTile&) override;
- float getQueryRadius(const style::Layer&) const override;
+ float getQueryRadius(const RenderLayer&) const override;
gl::VertexVector<CircleLayoutVertex> vertices;
gl::IndexVector<gl::Triangles> triangles;
diff --git a/src/mbgl/renderer/fill_bucket.cpp b/src/mbgl/renderer/fill_bucket.cpp
index 53bf825d48..2409fd365b 100644
--- a/src/mbgl/renderer/fill_bucket.cpp
+++ b/src/mbgl/renderer/fill_bucket.cpp
@@ -1,9 +1,9 @@
#include <mbgl/renderer/fill_bucket.hpp>
#include <mbgl/renderer/painter.hpp>
#include <mbgl/programs/fill_program.hpp>
-#include <mbgl/style/bucket_parameters.hpp>
-#include <mbgl/style/layers/fill_layer.hpp>
+#include <mbgl/renderer/bucket_parameters.hpp>
#include <mbgl/style/layers/fill_layer_impl.hpp>
+#include <mbgl/renderer/render_fill_layer.hpp>
#include <mbgl/util/math.hpp>
#include <mapbox/earcut.hpp>
@@ -28,13 +28,13 @@ using namespace style;
struct GeometryTooLongException : std::exception {};
-FillBucket::FillBucket(const BucketParameters& parameters, const std::vector<const Layer*>& layers) {
+FillBucket::FillBucket(const BucketParameters& parameters, const std::vector<const RenderLayer*>& layers) {
for (const auto& layer : layers) {
paintPropertyBinders.emplace(
std::piecewise_construct,
std::forward_as_tuple(layer->getID()),
std::forward_as_tuple(
- layer->as<FillLayer>()->impl->paint.evaluated,
+ layer->as<RenderFillLayer>()->evaluated,
parameters.tileID.overscaledZ));
}
}
@@ -123,21 +123,21 @@ void FillBucket::upload(gl::Context& context) {
void FillBucket::render(Painter& painter,
PaintParameters& parameters,
- const Layer& layer,
+ const RenderLayer& layer,
const RenderTile& tile) {
- painter.renderFill(parameters, *this, *layer.as<FillLayer>(), tile);
+ painter.renderFill(parameters, *this, *layer.as<RenderFillLayer>(), tile);
}
bool FillBucket::hasData() const {
return !triangleSegments.empty() || !lineSegments.empty();
}
-float FillBucket::getQueryRadius(const style::Layer& layer) const {
- if (!layer.is<FillLayer>()) {
+float FillBucket::getQueryRadius(const RenderLayer& layer) const {
+ if (!layer.is<RenderFillLayer>()) {
return 0;
}
- const std::array<float, 2>& translate = layer.as<FillLayer>()->impl->paint.evaluated.get<FillTranslate>();
+ const std::array<float, 2>& translate = layer.as<RenderFillLayer>()->evaluated.get<FillTranslate>();
return util::length(translate[0], translate[1]);
}
diff --git a/src/mbgl/renderer/fill_bucket.hpp b/src/mbgl/renderer/fill_bucket.hpp
index e96cd2ac5e..421d8b332b 100644
--- a/src/mbgl/renderer/fill_bucket.hpp
+++ b/src/mbgl/renderer/fill_bucket.hpp
@@ -12,22 +12,20 @@
namespace mbgl {
-namespace style {
class BucketParameters;
-} // namespace style
class FillBucket : public Bucket {
public:
- FillBucket(const style::BucketParameters&, const std::vector<const style::Layer*>&);
+ FillBucket(const BucketParameters&, const std::vector<const RenderLayer*>&);
void addFeature(const GeometryTileFeature&,
const GeometryCollection&) override;
bool hasData() const override;
void upload(gl::Context&) override;
- void render(Painter&, PaintParameters&, const style::Layer&, const RenderTile&) override;
+ void render(Painter&, PaintParameters&, const RenderLayer&, const RenderTile&) override;
- float getQueryRadius(const style::Layer&) const override;
+ float getQueryRadius(const RenderLayer&) const override;
gl::VertexVector<FillLayoutVertex> vertices;
gl::IndexVector<gl::Lines> lines;
diff --git a/src/mbgl/renderer/group_by_layout.cpp b/src/mbgl/renderer/group_by_layout.cpp
new file mode 100644
index 0000000000..df1eb7c7dd
--- /dev/null
+++ b/src/mbgl/renderer/group_by_layout.cpp
@@ -0,0 +1,48 @@
+#include <mbgl/renderer/group_by_layout.hpp>
+#include <mbgl/renderer/render_layer.hpp>
+#include <mbgl/style/layer_impl.hpp>
+#include <mbgl/style/conversion/stringify.hpp>
+#include <mbgl/util/rapidjson.hpp>
+
+#include <rapidjson/writer.h>
+#include <rapidjson/stringbuffer.h>
+
+#include <unordered_map>
+
+namespace mbgl {
+
+std::string layoutKey(const RenderLayer& layer) {
+ using namespace style::conversion;
+
+ rapidjson::StringBuffer s;
+ rapidjson::Writer<rapidjson::StringBuffer> writer(s);
+
+ writer.StartArray();
+ writer.Uint(static_cast<uint32_t>(layer.type));
+ writer.String(layer.baseImpl.source);
+ writer.String(layer.baseImpl.sourceLayer);
+ writer.Double(layer.baseImpl.minZoom);
+ writer.Double(layer.baseImpl.maxZoom);
+ writer.Uint(static_cast<uint32_t>(layer.baseImpl.visibility));
+ stringify(writer, layer.baseImpl.filter);
+ layer.baseImpl.stringifyLayout(writer);
+ writer.EndArray();
+
+ return s.GetString();
+}
+
+std::vector<std::vector<const RenderLayer*>> groupByLayout(const std::vector<std::unique_ptr<RenderLayer>>& layers) {
+ std::unordered_map<std::string, std::vector<const RenderLayer*>> map;
+ for (auto& layer : layers) {
+ map[layoutKey(*layer)].push_back(layer.get());
+ }
+
+ std::vector<std::vector<const RenderLayer*>> result;
+ for (auto& pair : map) {
+ result.push_back(pair.second);
+ }
+
+ return result;
+}
+
+} // namespace mbgl
diff --git a/src/mbgl/renderer/group_by_layout.hpp b/src/mbgl/renderer/group_by_layout.hpp
new file mode 100644
index 0000000000..bc3ecfae63
--- /dev/null
+++ b/src/mbgl/renderer/group_by_layout.hpp
@@ -0,0 +1,12 @@
+#pragma once
+
+#include <vector>
+#include <memory>
+
+namespace mbgl {
+
+class RenderLayer;
+
+std::vector<std::vector<const RenderLayer*>> groupByLayout(const std::vector<std::unique_ptr<RenderLayer>>&);
+
+} // namespace mbgl
diff --git a/src/mbgl/renderer/line_bucket.cpp b/src/mbgl/renderer/line_bucket.cpp
index 8c56524020..7bb4e2f202 100644
--- a/src/mbgl/renderer/line_bucket.cpp
+++ b/src/mbgl/renderer/line_bucket.cpp
@@ -1,7 +1,7 @@
#include <mbgl/renderer/line_bucket.hpp>
#include <mbgl/renderer/painter.hpp>
-#include <mbgl/style/layers/line_layer.hpp>
-#include <mbgl/style/bucket_parameters.hpp>
+#include <mbgl/renderer/render_line_layer.hpp>
+#include <mbgl/renderer/bucket_parameters.hpp>
#include <mbgl/style/layers/line_layer_impl.hpp>
#include <mbgl/util/math.hpp>
#include <mbgl/util/constants.hpp>
@@ -13,7 +13,7 @@ namespace mbgl {
using namespace style;
LineBucket::LineBucket(const BucketParameters& parameters,
- const std::vector<const Layer*>& layers,
+ const std::vector<const RenderLayer*>& layers,
const style::LineLayoutProperties& layout_)
: layout(layout_.evaluate(PropertyEvaluationParameters(parameters.tileID.overscaledZ))),
overscaling(parameters.tileID.overscaleFactor()) {
@@ -22,7 +22,7 @@ LineBucket::LineBucket(const BucketParameters& parameters,
std::piecewise_construct,
std::forward_as_tuple(layer->getID()),
std::forward_as_tuple(
- layer->as<LineLayer>()->impl->paint.evaluated,
+ layer->as<RenderLineLayer>()->evaluated,
parameters.tileID.overscaledZ));
}
}
@@ -460,9 +460,9 @@ void LineBucket::upload(gl::Context& context) {
void LineBucket::render(Painter& painter,
PaintParameters& parameters,
- const Layer& layer,
+ const RenderLayer& layer,
const RenderTile& tile) {
- painter.renderLine(parameters, *this, *layer.as<LineLayer>(), tile);
+ painter.renderLine(parameters, *this, *layer.as<RenderLineLayer>(), tile);
}
bool LineBucket::hasData() const {
@@ -470,17 +470,17 @@ bool LineBucket::hasData() const {
}
template <class Property>
-static float get(const LineLayer& layer, const std::map<std::string, LineProgram::PaintPropertyBinders>& paintPropertyBinders) {
+static float get(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.impl->paint.evaluated.get<Property>().constantOr(Property::defaultValue());
+ return layer.evaluated.get<Property>().constantOr(Property::defaultValue());
} else {
return *it->second.statistics<Property>().max();
}
}
-float LineBucket::getLineWidth(const style::LineLayer& layer) const {
- float lineWidth = layer.impl->paint.evaluated.get<LineWidth>();
+float LineBucket::getLineWidth(const RenderLineLayer& layer) const {
+ float lineWidth = layer.evaluated.get<LineWidth>();
float gapWidth = get<LineGapWidth>(layer, paintPropertyBinders);
if (gapWidth) {
@@ -490,15 +490,14 @@ float LineBucket::getLineWidth(const style::LineLayer& layer) const {
}
}
-float LineBucket::getQueryRadius(const style::Layer& layer) const {
- if (!layer.is<LineLayer>()) {
+float LineBucket::getQueryRadius(const RenderLayer& layer) const {
+ if (!layer.is<RenderLineLayer>()) {
return 0;
}
- auto lineLayer = layer.as<LineLayer>();
- auto paint = lineLayer->impl->paint;
+ auto lineLayer = layer.as<RenderLineLayer>();
- const std::array<float, 2>& translate = paint.evaluated.get<LineTranslate>();
+ const std::array<float, 2>& translate = lineLayer->evaluated.get<LineTranslate>();
float offset = get<LineOffset>(*lineLayer, paintPropertyBinders);
return getLineWidth(*lineLayer) / 2.0 + std::abs(offset) + util::length(translate[0], translate[1]);
}
diff --git a/src/mbgl/renderer/line_bucket.hpp b/src/mbgl/renderer/line_bucket.hpp
index 30198305ad..c319548714 100644
--- a/src/mbgl/renderer/line_bucket.hpp
+++ b/src/mbgl/renderer/line_bucket.hpp
@@ -12,15 +12,13 @@
namespace mbgl {
-namespace style {
class BucketParameters;
-class LineLayer;
-} // namespace style
+class RenderLineLayer;
class LineBucket : public Bucket {
public:
- LineBucket(const style::BucketParameters&,
- const std::vector<const style::Layer*>&,
+ LineBucket(const BucketParameters&,
+ const std::vector<const RenderLayer*>&,
const style::LineLayoutProperties&);
void addFeature(const GeometryTileFeature&,
@@ -28,9 +26,9 @@ public:
bool hasData() const override;
void upload(gl::Context&) override;
- void render(Painter&, PaintParameters&, const style::Layer&, const RenderTile&) override;
+ void render(Painter&, PaintParameters&, const RenderLayer&, const RenderTile&) override;
- float getQueryRadius(const style::Layer&) const override;
+ float getQueryRadius(const RenderLayer&) const override;
style::LineLayoutProperties::PossiblyEvaluated layout;
@@ -63,7 +61,7 @@ private:
const uint32_t overscaling;
- float getLineWidth(const style::LineLayer& layer) const;
+ float getLineWidth(const RenderLineLayer& layer) const;
};
} // namespace mbgl
diff --git a/src/mbgl/renderer/painter.cpp b/src/mbgl/renderer/painter.cpp
index f7a498ecae..0c4915d3e9 100644
--- a/src/mbgl/renderer/painter.cpp
+++ b/src/mbgl/renderer/painter.cpp
@@ -13,8 +13,8 @@
#include <mbgl/style/style.hpp>
#include <mbgl/style/layer_impl.hpp>
-#include <mbgl/style/layers/background_layer.hpp>
-#include <mbgl/style/layers/custom_layer.hpp>
+#include <mbgl/renderer/render_background_layer.hpp>
+#include <mbgl/renderer/render_custom_layer.hpp>
#include <mbgl/style/layers/custom_layer_impl.hpp>
#include <mbgl/sprite/sprite_atlas.hpp>
@@ -279,16 +279,16 @@ void Painter::renderPass(PaintParameters& parameters,
currentLayer = i;
const auto& item = *it;
- const Layer& layer = item.layer;
+ const RenderLayer& layer = item.layer;
- if (!layer.baseImpl->hasRenderPass(pass))
+ if (!layer.hasRenderPass(pass))
continue;
- if (layer.is<BackgroundLayer>()) {
+ if (layer.is<RenderBackgroundLayer>()) {
MBGL_DEBUG_GROUP(context, "background");
- renderBackground(parameters, *layer.as<BackgroundLayer>());
- } else if (layer.is<CustomLayer>()) {
- MBGL_DEBUG_GROUP(context, layer.baseImpl->id + " - custom");
+ renderBackground(parameters, *layer.as<RenderBackgroundLayer>());
+ } else if (layer.is<RenderCustomLayer>()) {
+ MBGL_DEBUG_GROUP(context, layer.baseImpl.id + " - custom");
// Reset GL state to a known state so the CustomLayer always has a clean slate.
context.vertexArrayObject = 0;
@@ -296,14 +296,14 @@ void Painter::renderPass(PaintParameters& parameters,
context.setStencilMode(gl::StencilMode::disabled());
context.setColorMode(colorModeForRenderPass());
- layer.as<CustomLayer>()->impl->render(state);
+ layer.as<RenderCustomLayer>()->impl->render(state);
// Reset the view back to our original one, just in case the CustomLayer changed
// the viewport or Framebuffer.
parameters.view.bind();
context.setDirtyState();
} else {
- MBGL_DEBUG_GROUP(context, layer.baseImpl->id + " - " + util::toString(item.tile->id));
+ MBGL_DEBUG_GROUP(context, layer.baseImpl.id + " - " + util::toString(item.tile->id));
item.bucket->render(*this, parameters, layer, *item.tile);
}
}
diff --git a/src/mbgl/renderer/painter.hpp b/src/mbgl/renderer/painter.hpp
index 3dcc1d5d46..9c6dd4505f 100644
--- a/src/mbgl/renderer/painter.hpp
+++ b/src/mbgl/renderer/painter.hpp
@@ -42,6 +42,13 @@ class CircleBucket;
class SymbolBucket;
class RasterBucket;
+class RenderFillLayer;
+class RenderLineLayer;
+class RenderCircleLayer;
+class RenderSymbolLayer;
+class RenderRasterLayer;
+class RenderBackgroundLayer;
+
class Programs;
class PaintParameters;
@@ -50,12 +57,6 @@ struct ClipID;
namespace style {
class Style;
class Source;
-class FillLayer;
-class LineLayer;
-class CircleLayer;
-class SymbolLayer;
-class RasterLayer;
-class BackgroundLayer;
} // namespace style
struct FrameData {
@@ -80,12 +81,12 @@ public:
void renderClippingMask(const UnwrappedTileID&, const ClipID&);
void renderTileDebug(const RenderTile&);
- void renderFill(PaintParameters&, FillBucket&, const style::FillLayer&, const RenderTile&);
- void renderLine(PaintParameters&, LineBucket&, const style::LineLayer&, const RenderTile&);
- void renderCircle(PaintParameters&, CircleBucket&, const style::CircleLayer&, const RenderTile&);
- void renderSymbol(PaintParameters&, SymbolBucket&, const style::SymbolLayer&, const RenderTile&);
- void renderRaster(PaintParameters&, RasterBucket&, const style::RasterLayer&, const RenderTile&);
- void renderBackground(PaintParameters&, const style::BackgroundLayer&);
+ void renderFill(PaintParameters&, FillBucket&, const RenderFillLayer&, const RenderTile&);
+ void renderLine(PaintParameters&, LineBucket&, const RenderLineLayer&, const RenderTile&);
+ void renderCircle(PaintParameters&, CircleBucket&, const RenderCircleLayer&, const RenderTile&);
+ void renderSymbol(PaintParameters&, SymbolBucket&, const RenderSymbolLayer&, const RenderTile&);
+ void renderRaster(PaintParameters&, RasterBucket&, const RenderRasterLayer&, const RenderTile&);
+ void renderBackground(PaintParameters&, const RenderBackgroundLayer&);
#ifndef NDEBUG
// Renders tile clip boundaries, using stencil buffer to calculate fill color.
diff --git a/src/mbgl/renderer/painter_background.cpp b/src/mbgl/renderer/painter_background.cpp
index 4ac414335b..ac16627246 100644
--- a/src/mbgl/renderer/painter_background.cpp
+++ b/src/mbgl/renderer/painter_background.cpp
@@ -1,6 +1,6 @@
#include <mbgl/renderer/painter.hpp>
#include <mbgl/renderer/paint_parameters.hpp>
-#include <mbgl/style/layers/background_layer.hpp>
+#include <mbgl/renderer/render_background_layer.hpp>
#include <mbgl/style/layers/background_layer_impl.hpp>
#include <mbgl/programs/programs.hpp>
#include <mbgl/programs/fill_program.hpp>
@@ -11,10 +11,10 @@ namespace mbgl {
using namespace style;
-void Painter::renderBackground(PaintParameters& parameters, const BackgroundLayer& layer) {
+void Painter::renderBackground(PaintParameters& parameters, const RenderBackgroundLayer& layer) {
// Note that for bottommost layers without a pattern, the background color is drawn with
// glClear rather than this method.
- const BackgroundPaintProperties::Evaluated& background = layer.impl->paint.evaluated;
+ const BackgroundPaintProperties::Evaluated& background = layer.evaluated;
style::FillPaintProperties::Evaluated properties;
properties.get<FillPattern>() = background.get<BackgroundPattern>();
diff --git a/src/mbgl/renderer/painter_circle.cpp b/src/mbgl/renderer/painter_circle.cpp
index 8d47e75f71..7c9194f6dd 100644
--- a/src/mbgl/renderer/painter_circle.cpp
+++ b/src/mbgl/renderer/painter_circle.cpp
@@ -2,7 +2,7 @@
#include <mbgl/renderer/paint_parameters.hpp>
#include <mbgl/renderer/circle_bucket.hpp>
#include <mbgl/renderer/render_tile.hpp>
-#include <mbgl/style/layers/circle_layer.hpp>
+#include <mbgl/renderer/render_circle_layer.hpp>
#include <mbgl/style/layers/circle_layer_impl.hpp>
#include <mbgl/programs/programs.hpp>
#include <mbgl/programs/circle_program.hpp>
@@ -14,13 +14,13 @@ using namespace style;
void Painter::renderCircle(PaintParameters& parameters,
CircleBucket& bucket,
- const CircleLayer& layer,
+ const RenderCircleLayer& layer,
const RenderTile& tile) {
if (pass == RenderPass::Opaque) {
return;
}
- const CirclePaintProperties::Evaluated& properties = layer.impl->paint.evaluated;
+ const CirclePaintProperties::Evaluated& properties = layer.evaluated;
const bool scaleWithMap = properties.get<CirclePitchScale>() == CirclePitchScaleType::Map;
parameters.programs.circle.draw(
diff --git a/src/mbgl/renderer/painter_fill.cpp b/src/mbgl/renderer/painter_fill.cpp
index 4276bd06ed..622f6386ef 100644
--- a/src/mbgl/renderer/painter_fill.cpp
+++ b/src/mbgl/renderer/painter_fill.cpp
@@ -2,7 +2,7 @@
#include <mbgl/renderer/paint_parameters.hpp>
#include <mbgl/renderer/fill_bucket.hpp>
#include <mbgl/renderer/render_tile.hpp>
-#include <mbgl/style/layers/fill_layer.hpp>
+#include <mbgl/renderer/render_fill_layer.hpp>
#include <mbgl/style/layers/fill_layer_impl.hpp>
#include <mbgl/sprite/sprite_atlas.hpp>
#include <mbgl/programs/programs.hpp>
@@ -15,9 +15,9 @@ using namespace style;
void Painter::renderFill(PaintParameters& parameters,
FillBucket& bucket,
- const FillLayer& layer,
+ const RenderFillLayer& layer,
const RenderTile& tile) {
- const FillPaintProperties::Evaluated& properties = layer.impl->paint.evaluated;
+ const FillPaintProperties::Evaluated& properties = layer.evaluated;
if (!properties.get<FillPattern>().from.empty()) {
if (pass != RenderPass::Translucent) {
@@ -70,7 +70,7 @@ void Painter::renderFill(PaintParameters& parameters,
*bucket.triangleIndexBuffer,
bucket.triangleSegments);
- if (!properties.get<FillAntialias>() || !layer.impl->paint.unevaluated.get<FillOutlineColor>().isUndefined()) {
+ if (!properties.get<FillAntialias>() || !layer.unevaluated.get<FillOutlineColor>().isUndefined()) {
return;
}
@@ -108,7 +108,7 @@ void Painter::renderFill(PaintParameters& parameters,
);
};
- if (properties.get<FillAntialias>() && !layer.impl->paint.unevaluated.get<FillOutlineColor>().isUndefined() && pass == RenderPass::Translucent) {
+ if (properties.get<FillAntialias>() && !layer.unevaluated.get<FillOutlineColor>().isUndefined() && pass == RenderPass::Translucent) {
draw(2,
parameters.programs.fillOutline,
gl::Lines { 2.0f },
@@ -127,7 +127,7 @@ void Painter::renderFill(PaintParameters& parameters,
bucket.triangleSegments);
}
- if (properties.get<FillAntialias>() && layer.impl->paint.unevaluated.get<FillOutlineColor>().isUndefined() && pass == RenderPass::Translucent) {
+ if (properties.get<FillAntialias>() && layer.unevaluated.get<FillOutlineColor>().isUndefined() && pass == RenderPass::Translucent) {
draw(2,
parameters.programs.fillOutline,
gl::Lines { 2.0f },
diff --git a/src/mbgl/renderer/painter_line.cpp b/src/mbgl/renderer/painter_line.cpp
index 4e19f841b1..4d7a27d0f6 100644
--- a/src/mbgl/renderer/painter_line.cpp
+++ b/src/mbgl/renderer/painter_line.cpp
@@ -2,7 +2,7 @@
#include <mbgl/renderer/paint_parameters.hpp>
#include <mbgl/renderer/line_bucket.hpp>
#include <mbgl/renderer/render_tile.hpp>
-#include <mbgl/style/layers/line_layer.hpp>
+#include <mbgl/renderer/render_line_layer.hpp>
#include <mbgl/style/layers/line_layer_impl.hpp>
#include <mbgl/programs/programs.hpp>
#include <mbgl/programs/line_program.hpp>
@@ -15,13 +15,13 @@ using namespace style;
void Painter::renderLine(PaintParameters& parameters,
LineBucket& bucket,
- const LineLayer& layer,
+ const RenderLineLayer& layer,
const RenderTile& tile) {
if (pass == RenderPass::Opaque) {
return;
}
- const LinePaintProperties::Evaluated& properties = layer.impl->paint.evaluated;
+ const LinePaintProperties::Evaluated& properties = layer.evaluated;
auto draw = [&] (auto& program, auto&& uniformValues) {
program.draw(
@@ -57,7 +57,7 @@ void Painter::renderLine(PaintParameters& parameters,
pixelsToGLUnits,
posA,
posB,
- layer.impl->dashLineWidth,
+ layer.dashLineWidth,
lineAtlas->getSize().width));
} else if (!properties.get<LinePattern>().from.empty()) {
diff --git a/src/mbgl/renderer/painter_raster.cpp b/src/mbgl/renderer/painter_raster.cpp
index c216955db8..31f10ed3ba 100644
--- a/src/mbgl/renderer/painter_raster.cpp
+++ b/src/mbgl/renderer/painter_raster.cpp
@@ -2,7 +2,7 @@
#include <mbgl/renderer/paint_parameters.hpp>
#include <mbgl/renderer/render_tile.hpp>
#include <mbgl/renderer/raster_bucket.hpp>
-#include <mbgl/style/layers/raster_layer.hpp>
+#include <mbgl/renderer/render_raster_layer.hpp>
#include <mbgl/style/layers/raster_layer_impl.hpp>
#include <mbgl/programs/programs.hpp>
#include <mbgl/programs/raster_program.hpp>
@@ -41,14 +41,14 @@ static std::array<float, 3> spinWeights(float spin) {
void Painter::renderRaster(PaintParameters& parameters,
RasterBucket& bucket,
- const RasterLayer& layer,
+ const RenderRasterLayer& layer,
const RenderTile& tile) {
if (pass != RenderPass::Translucent)
return;
if (!bucket.hasData())
return;
- const RasterPaintProperties::Evaluated& properties = layer.impl->paint.evaluated;
+ const RasterPaintProperties::Evaluated& properties = layer.evaluated;
const RasterProgram::PaintPropertyBinders paintAttributeData(properties, 0);
assert(bucket.texture);
diff --git a/src/mbgl/renderer/painter_symbol.cpp b/src/mbgl/renderer/painter_symbol.cpp
index d2f492d17a..9bafb5df80 100644
--- a/src/mbgl/renderer/painter_symbol.cpp
+++ b/src/mbgl/renderer/painter_symbol.cpp
@@ -2,7 +2,7 @@
#include <mbgl/renderer/paint_parameters.hpp>
#include <mbgl/renderer/symbol_bucket.hpp>
#include <mbgl/renderer/render_tile.hpp>
-#include <mbgl/style/layers/symbol_layer.hpp>
+#include <mbgl/renderer/render_symbol_layer.hpp>
#include <mbgl/style/layers/symbol_layer_impl.hpp>
#include <mbgl/text/glyph_atlas.hpp>
#include <mbgl/sprite/sprite_atlas.hpp>
@@ -20,7 +20,7 @@ using namespace style;
void Painter::renderSymbol(PaintParameters& parameters,
SymbolBucket& bucket,
- const SymbolLayer& layer,
+ const RenderSymbolLayer& layer,
const RenderTile& tile) {
if (pass == RenderPass::Opaque) {
return;
@@ -64,8 +64,8 @@ void Painter::renderSymbol(PaintParameters& parameters,
};
if (bucket.hasIconData()) {
- auto values = layer.impl->iconPropertyValues(layout);
- auto paintPropertyValues = layer.impl->iconPaintProperties();
+ auto values = layer.iconPropertyValues(layout);
+ auto paintPropertyValues = layer.iconPaintProperties();
SpriteAtlas& atlas = *layer.impl->spriteAtlas;
const bool iconScaled = layout.get<IconSize>().constantOr(1.0) != 1.0 ||
@@ -110,8 +110,8 @@ void Painter::renderSymbol(PaintParameters& parameters,
if (bucket.hasTextData()) {
glyphAtlas->bind(context, 0);
- auto values = layer.impl->textPropertyValues(layout);
- auto paintPropertyValues = layer.impl->textPaintProperties();
+ auto values = layer.textPropertyValues(layout);
+ auto paintPropertyValues = layer.textPaintProperties();
const Size texsize = glyphAtlas->getSize();
diff --git a/src/mbgl/renderer/raster_bucket.cpp b/src/mbgl/renderer/raster_bucket.cpp
index f328ad9313..ee8ef24071 100644
--- a/src/mbgl/renderer/raster_bucket.cpp
+++ b/src/mbgl/renderer/raster_bucket.cpp
@@ -1,5 +1,5 @@
#include <mbgl/renderer/raster_bucket.hpp>
-#include <mbgl/style/layers/raster_layer.hpp>
+#include <mbgl/renderer/render_raster_layer.hpp>
#include <mbgl/programs/raster_program.hpp>
#include <mbgl/renderer/painter.hpp>
#include <mbgl/gl/context.hpp>
@@ -18,9 +18,9 @@ void RasterBucket::upload(gl::Context& context) {
void RasterBucket::render(Painter& painter,
PaintParameters& parameters,
- const Layer& layer,
+ const RenderLayer& layer,
const RenderTile& tile) {
- painter.renderRaster(parameters, *this, *layer.as<RasterLayer>(), tile);
+ painter.renderRaster(parameters, *this, *layer.as<RenderRasterLayer>(), tile);
}
bool RasterBucket::hasData() const {
diff --git a/src/mbgl/renderer/raster_bucket.hpp b/src/mbgl/renderer/raster_bucket.hpp
index 20969cf6b8..334954e3f4 100644
--- a/src/mbgl/renderer/raster_bucket.hpp
+++ b/src/mbgl/renderer/raster_bucket.hpp
@@ -12,7 +12,7 @@ public:
RasterBucket(UnassociatedImage&&);
void upload(gl::Context&) override;
- void render(Painter&, PaintParameters&, const style::Layer&, const RenderTile&) override;
+ void render(Painter&, PaintParameters&, const RenderLayer&, const RenderTile&) override;
bool hasData() const override;
UnassociatedImage image;
diff --git a/src/mbgl/renderer/render_background_layer.cpp b/src/mbgl/renderer/render_background_layer.cpp
new file mode 100644
index 0000000000..5b98210975
--- /dev/null
+++ b/src/mbgl/renderer/render_background_layer.cpp
@@ -0,0 +1,35 @@
+#include <mbgl/renderer/render_background_layer.hpp>
+#include <mbgl/style/layers/background_layer_impl.hpp>
+#include <mbgl/renderer/bucket.hpp>
+
+namespace mbgl {
+
+RenderBackgroundLayer::RenderBackgroundLayer(const style::BackgroundLayer::Impl& _impl)
+ : RenderLayer(style::LayerType::Background, _impl),
+ impl(&_impl) {
+}
+
+std::unique_ptr<RenderLayer> RenderBackgroundLayer::clone() const {
+ return std::make_unique<RenderBackgroundLayer>(*this);
+}
+
+std::unique_ptr<Bucket> RenderBackgroundLayer::createBucket(const BucketParameters &,
+ const std::vector<const RenderLayer *> &) const {
+ assert(false);
+ return nullptr;
+}
+
+void RenderBackgroundLayer::cascade(const style::CascadeParameters &parameters) {
+ unevaluated = impl->cascading.cascade(parameters, std::move(unevaluated));
+}
+
+bool RenderBackgroundLayer::evaluate(const style::PropertyEvaluationParameters &parameters) {
+ evaluated = unevaluated.evaluate(parameters);
+
+ passes = evaluated.get<style::BackgroundOpacity>() > 0 ? RenderPass::Translucent
+ : RenderPass::None;
+
+ return unevaluated.hasTransition();
+}
+
+}
diff --git a/src/mbgl/renderer/render_background_layer.hpp b/src/mbgl/renderer/render_background_layer.hpp
new file mode 100644
index 0000000000..bd74f7b390
--- /dev/null
+++ b/src/mbgl/renderer/render_background_layer.hpp
@@ -0,0 +1,34 @@
+#pragma once
+
+#include <mbgl/renderer/render_layer.hpp>
+#include <mbgl/style/layers/background_layer.hpp>
+#include <mbgl/style/layers/background_layer_properties.hpp>
+
+namespace mbgl {
+
+class RenderBackgroundLayer: public RenderLayer {
+public:
+
+ RenderBackgroundLayer(const style::BackgroundLayer::Impl&);
+ ~RenderBackgroundLayer() final = default;
+
+ std::unique_ptr<RenderLayer> clone() const override;
+
+ void cascade(const style::CascadeParameters&) override;
+ bool evaluate(const style::PropertyEvaluationParameters&) override;
+
+ std::unique_ptr<Bucket> createBucket(const BucketParameters&, const std::vector<const RenderLayer*>&) const override;
+
+ // Paint properties
+ style::BackgroundPaintProperties::Unevaluated unevaluated;
+ style::BackgroundPaintProperties::Evaluated evaluated;
+
+ const style::BackgroundLayer::Impl* const impl;
+};
+
+template <>
+inline bool RenderLayer::is<RenderBackgroundLayer>() const {
+ return type == style::LayerType::Background;
+}
+
+}
diff --git a/src/mbgl/renderer/render_circle_layer.cpp b/src/mbgl/renderer/render_circle_layer.cpp
new file mode 100644
index 0000000000..aa127e9859
--- /dev/null
+++ b/src/mbgl/renderer/render_circle_layer.cpp
@@ -0,0 +1,65 @@
+#include <mbgl/renderer/render_circle_layer.hpp>
+#include <mbgl/renderer/circle_bucket.hpp>
+#include <mbgl/style/layers/circle_layer_impl.hpp>
+#include <mbgl/geometry/feature_index.hpp>
+#include <mbgl/util/math.hpp>
+#include <mbgl/util/intersection_tests.hpp>
+
+namespace mbgl {
+
+RenderCircleLayer::RenderCircleLayer(const style::CircleLayer::Impl& _impl)
+ : RenderLayer(style::LayerType::Circle, _impl),
+ impl(&_impl) {
+}
+
+std::unique_ptr<RenderLayer> RenderCircleLayer::clone() const {
+ return std::make_unique<RenderCircleLayer>(*this);
+}
+
+std::unique_ptr<Bucket> RenderCircleLayer::createBucket(const BucketParameters& parameters, const std::vector<const RenderLayer*>& layers) const {
+ return std::make_unique<CircleBucket>(parameters, layers);
+}
+
+void RenderCircleLayer::cascade(const style::CascadeParameters& parameters) {
+ unevaluated = impl->cascading.cascade(parameters, std::move(unevaluated));
+}
+
+bool RenderCircleLayer::evaluate(const style::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))
+ ? RenderPass::Translucent : RenderPass::None;
+
+ return unevaluated.hasTransition();
+}
+
+bool RenderCircleLayer::queryIntersectsFeature(
+ const GeometryCoordinates& queryGeometry,
+ const GeometryTileFeature& feature,
+ const float zoom,
+ const float bearing,
+ const float pixelsToTileUnits) const {
+
+ // Translate query geometry
+ auto translatedQueryGeometry = FeatureIndex::translateQueryGeometry(
+ queryGeometry,
+ evaluated.get<style::CircleTranslate>(),
+ evaluated.get<style::CircleTranslateAnchor>(),
+ bearing,
+ pixelsToTileUnits);
+
+ // Evaluate function
+ auto circleRadius = evaluated.get<style::CircleRadius>()
+ .evaluate(feature, zoom, style::CircleRadius::defaultValue())
+ * pixelsToTileUnits;
+
+ // Test intersection
+ return util::polygonIntersectsBufferedMultiPoint(translatedQueryGeometry.value_or(queryGeometry), feature.getGeometries(), circleRadius);
+}
+
+}
diff --git a/src/mbgl/renderer/render_circle_layer.hpp b/src/mbgl/renderer/render_circle_layer.hpp
new file mode 100644
index 0000000000..5117b12246
--- /dev/null
+++ b/src/mbgl/renderer/render_circle_layer.hpp
@@ -0,0 +1,41 @@
+#pragma once
+
+#include <mbgl/renderer/render_layer.hpp>
+#include <mbgl/style/layers/circle_layer.hpp>
+#include <mbgl/style/layers/circle_layer_properties.hpp>
+
+namespace mbgl {
+
+class RenderCircleLayer: public RenderLayer {
+public:
+
+ RenderCircleLayer(const style::CircleLayer::Impl&);
+ ~RenderCircleLayer() final = default;
+
+ std::unique_ptr<RenderLayer> clone() const override;
+
+ void cascade(const style::CascadeParameters&) override;
+ bool evaluate(const style::PropertyEvaluationParameters&) override;
+
+ bool queryIntersectsFeature(
+ const GeometryCoordinates&,
+ const GeometryTileFeature&,
+ const float,
+ const float,
+ const float) const override;
+
+ std::unique_ptr<Bucket> createBucket(const BucketParameters&, const std::vector<const RenderLayer*>&) const override;
+
+ // Paint properties
+ style::CirclePaintProperties::Unevaluated unevaluated;
+ style::CirclePaintProperties::Evaluated evaluated;
+
+ const style::CircleLayer::Impl* const impl;
+};
+
+template <>
+inline bool RenderLayer::is<RenderCircleLayer>() const {
+ return type == style::LayerType::Circle;
+}
+
+}
diff --git a/src/mbgl/renderer/render_custom_layer.cpp b/src/mbgl/renderer/render_custom_layer.cpp
new file mode 100644
index 0000000000..f9dda47d7a
--- /dev/null
+++ b/src/mbgl/renderer/render_custom_layer.cpp
@@ -0,0 +1,26 @@
+#include <mbgl/renderer/render_custom_layer.hpp>
+#include <mbgl/style/layers/custom_layer_impl.hpp>
+#include <mbgl/renderer/bucket.hpp>
+
+namespace mbgl {
+
+RenderCustomLayer::RenderCustomLayer(const style::CustomLayer::Impl& _impl)
+ : RenderLayer(style::LayerType::Custom, _impl),
+ impl(&_impl) {
+}
+
+std::unique_ptr<RenderLayer> RenderCustomLayer::clone() const {
+ return std::make_unique<RenderCustomLayer>(*this);
+}
+
+bool RenderCustomLayer::evaluate(const style::PropertyEvaluationParameters&) {
+ passes = RenderPass::Translucent;
+ return false;
+}
+
+std::unique_ptr<Bucket> RenderCustomLayer::createBucket(const BucketParameters&, const std::vector<const RenderLayer*>&) const {
+ assert(false);
+ return nullptr;
+}
+
+}
diff --git a/src/mbgl/renderer/render_custom_layer.hpp b/src/mbgl/renderer/render_custom_layer.hpp
new file mode 100644
index 0000000000..3c6c06ff7c
--- /dev/null
+++ b/src/mbgl/renderer/render_custom_layer.hpp
@@ -0,0 +1,29 @@
+#pragma once
+
+#include <mbgl/renderer/render_layer.hpp>
+#include <mbgl/style/layers/custom_layer.hpp>
+
+namespace mbgl {
+
+class RenderCustomLayer: public RenderLayer {
+public:
+
+ RenderCustomLayer(const style::CustomLayer::Impl&);
+ ~RenderCustomLayer() final = default;
+
+ std::unique_ptr<RenderLayer> clone() const override;
+
+ void cascade(const style::CascadeParameters&) final {}
+ bool evaluate(const style::PropertyEvaluationParameters&) final;
+
+ std::unique_ptr<Bucket> createBucket(const BucketParameters&, const std::vector<const RenderLayer*>&) const final;
+
+ const style::CustomLayer::Impl* const impl;
+};
+
+template <>
+inline bool RenderLayer::is<RenderCustomLayer>() const {
+ return type == style::LayerType::Custom;
+}
+
+}
diff --git a/src/mbgl/renderer/render_fill_extrusion_layer.cpp b/src/mbgl/renderer/render_fill_extrusion_layer.cpp
new file mode 100644
index 0000000000..a378f12cf0
--- /dev/null
+++ b/src/mbgl/renderer/render_fill_extrusion_layer.cpp
@@ -0,0 +1,26 @@
+#include <mbgl/renderer/render_fill_extrusion_layer.hpp>
+#include <mbgl/renderer/bucket.hpp>
+#include <mbgl/style/layers/fill_extrusion_layer_impl.hpp>
+
+namespace mbgl {
+
+RenderFillExtrusionLayer::RenderFillExtrusionLayer(const style::FillExtrusionLayer::Impl& _impl)
+ : RenderLayer(style::LayerType::FillExtrusion, _impl) {
+}
+
+std::unique_ptr<RenderLayer> RenderFillExtrusionLayer::clone() const {
+ return std::make_unique<RenderFillExtrusionLayer>(*this);
+}
+
+std::unique_ptr<Bucket> RenderFillExtrusionLayer::createBucket(const BucketParameters&, const std::vector<const RenderLayer*>&) const {
+ return nullptr;
+}
+
+void RenderFillExtrusionLayer::cascade(const style::CascadeParameters&) {
+}
+
+bool RenderFillExtrusionLayer::evaluate(const style::PropertyEvaluationParameters&) {
+ return false;
+}
+
+} // namespace mbgl
diff --git a/src/mbgl/renderer/render_fill_extrusion_layer.hpp b/src/mbgl/renderer/render_fill_extrusion_layer.hpp
new file mode 100644
index 0000000000..596ba02fee
--- /dev/null
+++ b/src/mbgl/renderer/render_fill_extrusion_layer.hpp
@@ -0,0 +1,32 @@
+#pragma once
+
+#include <mbgl/renderer/render_layer.hpp>
+#include <mbgl/style/layers/fill_extrusion_layer.hpp>
+#include <mbgl/style/layers/fill_extrusion_layer_properties.hpp>
+
+namespace mbgl {
+
+class RenderFillExtrusionLayer: public RenderLayer {
+public:
+
+ RenderFillExtrusionLayer(const style::FillExtrusionLayer::Impl&);
+ ~RenderFillExtrusionLayer() final = default;
+
+ std::unique_ptr<RenderLayer> clone() const override;
+
+ void cascade(const style::CascadeParameters&) override;
+ bool evaluate(const style::PropertyEvaluationParameters&) override;
+
+ std::unique_ptr<Bucket> createBucket(const BucketParameters&, const std::vector<const RenderLayer*>&) const override;
+
+ // Paint properties
+ style::FillExtrusionPaintProperties::Unevaluated unevaluated;
+ style::FillExtrusionPaintProperties::Evaluated evaluated;
+};
+
+template <>
+inline bool RenderLayer::is<RenderFillExtrusionLayer>() const {
+ return type == style::LayerType::FillExtrusion;
+}
+
+} // namespace mbgl
diff --git a/src/mbgl/renderer/render_fill_layer.cpp b/src/mbgl/renderer/render_fill_layer.cpp
new file mode 100644
index 0000000000..126189fc50
--- /dev/null
+++ b/src/mbgl/renderer/render_fill_layer.cpp
@@ -0,0 +1,70 @@
+#include <mbgl/renderer/render_fill_layer.hpp>
+#include <mbgl/renderer/fill_bucket.hpp>
+#include <mbgl/style/layers/fill_layer_impl.hpp>
+#include <mbgl/geometry/feature_index.hpp>
+#include <mbgl/util/math.hpp>
+#include <mbgl/util/intersection_tests.hpp>
+
+namespace mbgl {
+
+RenderFillLayer::RenderFillLayer(const style::FillLayer::Impl& _impl)
+ : RenderLayer(style::LayerType::Fill, _impl),
+ impl(&_impl) {
+}
+
+std::unique_ptr<RenderLayer> RenderFillLayer::clone() const {
+ return std::make_unique<RenderFillLayer>(*this);
+}
+
+std::unique_ptr<Bucket> RenderFillLayer::createBucket(const BucketParameters& parameters, const std::vector<const RenderLayer*>& layers) const {
+ return std::make_unique<FillBucket>(parameters, layers);
+}
+
+void RenderFillLayer::cascade(const style::CascadeParameters& parameters) {
+ unevaluated = impl->cascading.cascade(parameters, std::move(unevaluated));
+}
+
+bool RenderFillLayer::evaluate(const style::PropertyEvaluationParameters& parameters) {
+ evaluated = unevaluated.evaluate(parameters);
+
+ if (unevaluated.get<style::FillOutlineColor>().isUndefined()) {
+ evaluated.get<style::FillOutlineColor>() = evaluated.get<style::FillColor>();
+ }
+
+ passes = RenderPass::None;
+
+ if (evaluated.get<style::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) {
+ passes |= RenderPass::Translucent;
+ } else {
+ passes |= RenderPass::Opaque;
+ }
+
+ return unevaluated.hasTransition();
+}
+
+
+bool RenderFillLayer::queryIntersectsFeature(
+ const GeometryCoordinates& queryGeometry,
+ const GeometryTileFeature& feature,
+ const float,
+ const float bearing,
+ const float pixelsToTileUnits) const {
+
+ auto translatedQueryGeometry = FeatureIndex::translateQueryGeometry(
+ queryGeometry,
+ evaluated.get<style::FillTranslate>(),
+ evaluated.get<style::FillTranslateAnchor>(),
+ bearing,
+ pixelsToTileUnits);
+
+ return util::polygonIntersectsMultiPolygon(translatedQueryGeometry.value_or(queryGeometry), feature.getGeometries());
+}
+
+
+}
diff --git a/src/mbgl/renderer/render_fill_layer.hpp b/src/mbgl/renderer/render_fill_layer.hpp
new file mode 100644
index 0000000000..25b969d4c3
--- /dev/null
+++ b/src/mbgl/renderer/render_fill_layer.hpp
@@ -0,0 +1,41 @@
+#pragma once
+
+#include <mbgl/renderer/render_layer.hpp>
+#include <mbgl/style/layers/fill_layer.hpp>
+#include <mbgl/style/layers/fill_layer_properties.hpp>
+
+namespace mbgl {
+
+class RenderFillLayer: public RenderLayer {
+public:
+
+ RenderFillLayer(const style::FillLayer::Impl&);
+ ~RenderFillLayer() final = default;
+
+ std::unique_ptr<RenderLayer> clone() const override;
+
+ void cascade(const style::CascadeParameters&) override;
+ bool evaluate(const style::PropertyEvaluationParameters&) override;
+
+ bool queryIntersectsFeature(
+ const GeometryCoordinates&,
+ const GeometryTileFeature&,
+ const float,
+ const float,
+ const float) const override;
+
+ std::unique_ptr<Bucket> createBucket(const BucketParameters&, const std::vector<const RenderLayer*>&) const override;
+
+ // Paint properties
+ style::FillPaintProperties::Unevaluated unevaluated;
+ style::FillPaintProperties::Evaluated evaluated;
+
+ const style::FillLayer::Impl* const impl;
+};
+
+template <>
+inline bool RenderLayer::is<RenderFillLayer>() const {
+ return type == style::LayerType::Fill;
+}
+
+} // namespace mbgl
diff --git a/src/mbgl/renderer/render_item.hpp b/src/mbgl/renderer/render_item.hpp
index b4b1f4aec2..575287d9c6 100644
--- a/src/mbgl/renderer/render_item.hpp
+++ b/src/mbgl/renderer/render_item.hpp
@@ -7,17 +7,17 @@
namespace mbgl {
+class RenderLayer;
class RenderTile;
class Bucket;
namespace style {
-class Layer;
class Source;
} // namespace style
class RenderItem {
public:
- RenderItem(const style::Layer& layer_,
+ RenderItem(const RenderLayer& layer_,
const RenderTile* tile_ = nullptr,
Bucket* bucket_ = nullptr)
: tile(tile_), bucket(bucket_), layer(layer_) {
@@ -25,7 +25,7 @@ public:
const RenderTile* const tile;
Bucket* const bucket;
- const style::Layer& layer;
+ const RenderLayer& layer;
};
class RenderData {
diff --git a/src/mbgl/renderer/render_layer.cpp b/src/mbgl/renderer/render_layer.cpp
new file mode 100644
index 0000000000..6699f39144
--- /dev/null
+++ b/src/mbgl/renderer/render_layer.cpp
@@ -0,0 +1,25 @@
+#include <mbgl/renderer/render_layer.hpp>
+#include <mbgl/style/types.hpp>
+
+namespace mbgl {
+
+RenderLayer::RenderLayer(style::LayerType type_, const style::Layer::Impl& baseImpl_)
+ : type(type_), baseImpl(baseImpl_) {
+}
+
+const std::string& RenderLayer::getID() const {
+ return baseImpl.id;
+}
+
+bool RenderLayer::hasRenderPass(RenderPass pass) const {
+ return bool(passes & pass);
+}
+
+bool RenderLayer::needsRendering(float zoom) const {
+ return passes != RenderPass::None
+ && baseImpl.visibility != style::VisibilityType::None
+ && baseImpl.minZoom <= zoom
+ && baseImpl.maxZoom >= zoom;
+}
+
+} \ No newline at end of file
diff --git a/src/mbgl/renderer/render_layer.hpp b/src/mbgl/renderer/render_layer.hpp
new file mode 100644
index 0000000000..af5345d5e3
--- /dev/null
+++ b/src/mbgl/renderer/render_layer.hpp
@@ -0,0 +1,87 @@
+#pragma once
+
+#include <mbgl/renderer/render_pass.hpp>
+#include <mbgl/style/layer_impl.hpp>
+#include <mbgl/style/layer_type.hpp>
+#include <mbgl/tile/geometry_tile_data.hpp>
+
+#include <memory>
+#include <string>
+
+namespace mbgl {
+
+class Bucket;
+class BucketParameters;
+
+namespace style {
+class CascadeParameters;
+class PropertyEvaluationParameters;
+} // namespace style
+
+class RenderLayer {
+
+protected:
+ RenderLayer(style::LayerType, const style::Layer::Impl&);
+
+ const style::LayerType type;
+
+public:
+
+ virtual ~RenderLayer() = default;
+
+ // Create an identical copy of this layer.
+ virtual std::unique_ptr<RenderLayer> clone() const = 0;
+
+ // Partially evaluate paint properties based on a set of classes.
+ virtual void cascade(const style::CascadeParameters&) = 0;
+
+ // Fully evaluate cascaded paint properties based on a zoom level.
+ // Returns true if any paint properties have active transitions.
+ virtual bool evaluate(const style::PropertyEvaluationParameters&) = 0;
+
+ // Check whether this layer is of the given subtype.
+ template <class T>
+ bool is() const;
+
+ // Dynamically cast this layer to the given subtype.
+ template <class T>
+ T* as() {
+ return is<T>() ? reinterpret_cast<T*>(this) : nullptr;
+ }
+
+ template <class T>
+ const T* as() const {
+ return is<T>() ? reinterpret_cast<const T*>(this) : nullptr;
+ }
+
+ const std::string& getID() const;
+
+ // Checks whether this layer needs to be rendered in the given render pass.
+ bool hasRenderPass(RenderPass) const;
+
+ // Checks whether this layer can be rendered.
+ bool needsRendering(float zoom) const;
+
+ // Check wether the given geometry intersects
+ // with the feature
+ virtual bool queryIntersectsFeature(
+ const GeometryCoordinates&,
+ const GeometryTileFeature&,
+ const float,
+ const float,
+ const float) const { return false; };
+
+ virtual std::unique_ptr<Bucket> createBucket(const BucketParameters&, const std::vector<const RenderLayer*>&) const = 0;
+
+ // Private implementation
+ const style::Layer::Impl& baseImpl;
+
+ friend std::string layoutKey(const RenderLayer&);
+protected:
+
+ // Stores what render passes this layer is currently enabled for. This depends on the
+ // evaluated StyleProperties object and is updated accordingly.
+ RenderPass passes = RenderPass::None;
+};
+
+} // namespace mbgl
diff --git a/src/mbgl/renderer/render_line_layer.cpp b/src/mbgl/renderer/render_line_layer.cpp
new file mode 100644
index 0000000000..551d40bef5
--- /dev/null
+++ b/src/mbgl/renderer/render_line_layer.cpp
@@ -0,0 +1,114 @@
+#include <mbgl/renderer/render_line_layer.hpp>
+#include <mbgl/renderer/line_bucket.hpp>
+#include <mbgl/style/layers/line_layer_impl.hpp>
+#include <mbgl/geometry/feature_index.hpp>
+#include <mbgl/util/math.hpp>
+#include <mbgl/util/intersection_tests.hpp>
+
+namespace mbgl {
+
+RenderLineLayer::RenderLineLayer(const style::LineLayer::Impl& _impl)
+ : RenderLayer(style::LayerType::Line, _impl),
+ impl(&_impl) {
+}
+
+std::unique_ptr<RenderLayer> RenderLineLayer::clone() const {
+ return std::make_unique<RenderLineLayer>(*this);
+}
+
+std::unique_ptr<Bucket> RenderLineLayer::createBucket(const BucketParameters& parameters, const std::vector<const RenderLayer*>& layers) const {
+ return std::make_unique<LineBucket>(parameters, layers, impl->layout);
+}
+
+void RenderLineLayer::cascade(const style::CascadeParameters& parameters) {
+ unevaluated = impl->cascading.cascade(parameters, std::move(unevaluated));
+}
+
+bool RenderLineLayer::evaluate(const style::PropertyEvaluationParameters& parameters) {
+ // for scaling dasharrays
+ auto dashArrayParams = parameters;
+ dashArrayParams.z = std::floor(dashArrayParams.z);
+ dashLineWidth = unevaluated.evaluate<style::LineWidth>(dashArrayParams);
+
+ evaluated = unevaluated.evaluate(parameters);
+
+ passes = (evaluated.get<style::LineOpacity>().constantOr(1.0) > 0
+ && evaluated.get<style::LineColor>().constantOr(Color::black()).a > 0
+ && evaluated.get<style::LineWidth>() > 0)
+ ? RenderPass::Translucent : RenderPass::None;
+
+ return unevaluated.hasTransition();
+}
+optional<GeometryCollection> offsetLine(const GeometryCollection& rings, const double offset) {
+ if (offset == 0) return {};
+
+ GeometryCollection newRings;
+ Point<double> zero(0, 0);
+ for (const auto& ring : rings) {
+ newRings.emplace_back();
+ auto& newRing = newRings.back();
+
+ for (auto i = ring.begin(); i != ring.end(); i++) {
+ auto& p = *i;
+
+ Point<double> aToB = i == ring.begin() ?
+ zero :
+ util::perp(util::unit(convertPoint<double>(p - *(i - 1))));
+ Point<double> bToC = i + 1 == ring.end() ?
+ zero :
+ util::perp(util::unit(convertPoint<double>(*(i + 1) - p)));
+ Point<double> extrude = util::unit(aToB + bToC);
+
+ const double cosHalfAngle = extrude.x * bToC.x + extrude.y * bToC.y;
+ extrude *= (1.0 / cosHalfAngle);
+
+ newRing.push_back(convertPoint<int16_t>(extrude * offset) + p);
+ }
+ }
+
+ return newRings;
+}
+
+bool RenderLineLayer::queryIntersectsFeature(
+ const GeometryCoordinates& queryGeometry,
+ const GeometryTileFeature& feature,
+ const float zoom,
+ const float bearing,
+ const float pixelsToTileUnits) const {
+
+ // Translate query geometry
+ auto translatedQueryGeometry = FeatureIndex::translateQueryGeometry(
+ queryGeometry,
+ evaluated.get<style::LineTranslate>(),
+ evaluated.get<style::LineTranslateAnchor>(),
+ bearing,
+ pixelsToTileUnits);
+
+ // Evaluate function
+ auto offset = evaluated.get<style::LineOffset>()
+ .evaluate(feature, zoom, style::LineOffset::defaultValue()) * pixelsToTileUnits;
+
+ // Apply offset to geometry
+ auto offsetGeometry = offsetLine(feature.getGeometries(), offset);
+
+ // Test intersection
+ const float halfWidth = getLineWidth(feature, zoom) / 2.0 * pixelsToTileUnits;
+ return util::polygonIntersectsBufferedMultiLine(
+ translatedQueryGeometry.value_or(queryGeometry),
+ offsetGeometry.value_or(feature.getGeometries()),
+ halfWidth);
+}
+
+float RenderLineLayer::getLineWidth(const GeometryTileFeature& feature, const float zoom) const {
+ float lineWidth = evaluated.get<style::LineWidth>();
+ float gapWidth = evaluated.get<style::LineGapWidth>()
+ .evaluate(feature, zoom, style::LineGapWidth::defaultValue());
+ if (gapWidth) {
+ return gapWidth + 2 * lineWidth;
+ } else {
+ return lineWidth;
+ }
+}
+
+
+} // namespace mbgl
diff --git a/src/mbgl/renderer/render_line_layer.hpp b/src/mbgl/renderer/render_line_layer.hpp
new file mode 100644
index 0000000000..0bde6f9a86
--- /dev/null
+++ b/src/mbgl/renderer/render_line_layer.hpp
@@ -0,0 +1,48 @@
+#pragma once
+
+#include <mbgl/renderer/render_layer.hpp>
+#include <mbgl/style/layers/line_layer.hpp>
+#include <mbgl/style/layers/line_layer_properties.hpp>
+
+namespace mbgl {
+
+class RenderLineLayer: public RenderLayer {
+public:
+
+ RenderLineLayer(const style::LineLayer::Impl&);
+ ~RenderLineLayer() final = default;
+
+ std::unique_ptr<RenderLayer> clone() const override;
+
+ void cascade(const style::CascadeParameters&) override;
+ bool evaluate(const style::PropertyEvaluationParameters&) override;
+
+ bool queryIntersectsFeature(
+ const GeometryCoordinates&,
+ const GeometryTileFeature&,
+ const float,
+ const float,
+ const float) const override;
+
+ std::unique_ptr<Bucket> createBucket(const BucketParameters&, const std::vector<const RenderLayer*>&) const override;
+
+ // Paint properties
+ style::LinePaintProperties::Unevaluated unevaluated;
+ style::LinePaintProperties::Evaluated evaluated;
+
+ const style::LineLayer::Impl* const impl;
+
+ // Special case
+ float dashLineWidth = 1;
+
+private:
+ float getLineWidth(const GeometryTileFeature&, const float) const;
+
+};
+
+template <>
+inline bool RenderLayer::is<RenderLineLayer>() const {
+ return type == style::LayerType::Line;
+}
+
+} // namespace mbgl
diff --git a/src/mbgl/renderer/render_raster_layer.cpp b/src/mbgl/renderer/render_raster_layer.cpp
new file mode 100644
index 0000000000..f877a02398
--- /dev/null
+++ b/src/mbgl/renderer/render_raster_layer.cpp
@@ -0,0 +1,33 @@
+#include <mbgl/renderer/render_raster_layer.hpp>
+#include <mbgl/renderer/bucket.hpp>
+#include <mbgl/style/layers/raster_layer_impl.hpp>
+
+namespace mbgl {
+
+RenderRasterLayer::RenderRasterLayer(const style::RasterLayer::Impl& _impl)
+ : RenderLayer(style::LayerType::Raster, _impl),
+ impl(&_impl) {
+}
+
+std::unique_ptr<RenderLayer> RenderRasterLayer::clone() const {
+ return std::make_unique<RenderRasterLayer>(*this);
+}
+
+std::unique_ptr<Bucket> RenderRasterLayer::createBucket(const BucketParameters&, const std::vector<const RenderLayer*>&) const {
+ assert(false);
+ return nullptr;
+}
+
+void RenderRasterLayer::cascade(const style::CascadeParameters& parameters) {
+ unevaluated = impl->cascading.cascade(parameters, std::move(unevaluated));
+}
+
+bool RenderRasterLayer::evaluate(const style::PropertyEvaluationParameters& parameters) {
+ evaluated = unevaluated.evaluate(parameters);
+
+ passes = evaluated.get<style::RasterOpacity>() > 0 ? RenderPass::Translucent : RenderPass::None;
+
+ return unevaluated.hasTransition();
+}
+
+} // namespace mbgl
diff --git a/src/mbgl/renderer/render_raster_layer.hpp b/src/mbgl/renderer/render_raster_layer.hpp
new file mode 100644
index 0000000000..1fd0fe7c47
--- /dev/null
+++ b/src/mbgl/renderer/render_raster_layer.hpp
@@ -0,0 +1,34 @@
+#pragma once
+
+#include <mbgl/renderer/render_layer.hpp>
+#include <mbgl/style/layers/raster_layer.hpp>
+#include <mbgl/style/layers/raster_layer_properties.hpp>
+
+namespace mbgl {
+
+class RenderRasterLayer: public RenderLayer {
+public:
+
+ RenderRasterLayer(const style::RasterLayer::Impl&);
+ ~RenderRasterLayer() final = default;
+
+ std::unique_ptr<RenderLayer> clone() const override;
+
+ void cascade(const style::CascadeParameters&) override;
+ bool evaluate(const style::PropertyEvaluationParameters&) override;
+
+ std::unique_ptr<Bucket> createBucket(const BucketParameters&, const std::vector<const RenderLayer*>&) const override;
+
+ // Paint properties
+ style::RasterPaintProperties::Unevaluated unevaluated;
+ style::RasterPaintProperties::Evaluated evaluated;
+
+ const style::RasterLayer::Impl* const impl;
+};
+
+template <>
+inline bool RenderLayer::is<RenderRasterLayer>() const {
+ return type == style::LayerType::Raster;
+}
+
+} // namespace mbgl
diff --git a/src/mbgl/renderer/render_symbol_layer.cpp b/src/mbgl/renderer/render_symbol_layer.cpp
new file mode 100644
index 0000000000..90cc0a7615
--- /dev/null
+++ b/src/mbgl/renderer/render_symbol_layer.cpp
@@ -0,0 +1,113 @@
+#include <mbgl/renderer/render_symbol_layer.hpp>
+#include <mbgl/layout/symbol_layout.hpp>
+#include <mbgl/renderer/bucket.hpp>
+#include <mbgl/renderer/bucket_parameters.hpp>
+#include <mbgl/style/layers/symbol_layer_impl.hpp>
+#include <mbgl/style/property_evaluation_parameters.hpp>
+#include <mbgl/tile/geometry_tile_data.hpp>
+
+namespace mbgl {
+
+RenderSymbolLayer::RenderSymbolLayer(const style::SymbolLayer::Impl& _impl)
+ : RenderLayer(style::LayerType::Symbol, _impl),
+ impl(&_impl) {
+}
+
+std::unique_ptr<RenderLayer> RenderSymbolLayer::clone() const {
+ return std::make_unique<RenderSymbolLayer>(*this);
+}
+
+std::unique_ptr<Bucket> RenderSymbolLayer::createBucket(const BucketParameters&, const std::vector<const RenderLayer*>&) const {
+ assert(false); // Should be calling createLayout() instead.
+ return nullptr;
+}
+
+std::unique_ptr<SymbolLayout> RenderSymbolLayer::createLayout(const BucketParameters& parameters,
+ const std::vector<const RenderLayer*>& group,
+ const GeometryTileLayer& layer,
+ GlyphDependencies& glyphDependencies,
+ IconDependencyMap& iconDependencyMap) const {
+ return std::make_unique<SymbolLayout>(parameters,
+ group,
+ layer,
+ iconDependencyMap[impl->spriteAtlas],
+ (uintptr_t) impl->spriteAtlas,
+ glyphDependencies);
+}
+
+void RenderSymbolLayer::cascade(const style::CascadeParameters& parameters) {
+ unevaluated = impl->cascading.cascade(parameters, std::move(unevaluated));
+}
+
+bool RenderSymbolLayer::evaluate(const style::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;
+
+ passes = ((evaluated.get<style::IconOpacity>().constantOr(1) > 0 && hasIconOpacity && iconSize > 0)
+ || (evaluated.get<style::TextOpacity>().constantOr(1) > 0 && hasTextOpacity && textSize > 0))
+ ? RenderPass::Translucent : RenderPass::None;
+
+ return unevaluated.hasTransition();
+}
+
+
+style::IconPaintProperties::Evaluated RenderSymbolLayer::iconPaintProperties() const {
+ return style::IconPaintProperties::Evaluated {
+ 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>()
+ };
+}
+
+style::TextPaintProperties::Evaluated RenderSymbolLayer::textPaintProperties() const {
+ return style::TextPaintProperties::Evaluated {
+ 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>()
+ };
+}
+
+
+style::SymbolPropertyValues RenderSymbolLayer::iconPropertyValues(const style::SymbolLayoutProperties::PossiblyEvaluated& layout_) const {
+ return style::SymbolPropertyValues {
+ layout_.get<style::IconRotationAlignment>(), // icon-pitch-alignment is not yet implemented; inherit the rotation alignment
+ layout_.get<style::IconRotationAlignment>(),
+ layout_.get<style::IconSize>(),
+ evaluated.get<style::IconTranslate>(),
+ evaluated.get<style::IconTranslateAnchor>(),
+ iconSize,
+ 1.0f,
+ evaluated.get<style::IconHaloColor>().constantOr(Color::black()).a > 0 &&
+ evaluated.get<style::IconHaloWidth>().constantOr(1),
+ evaluated.get<style::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::TextSize>(),
+ evaluated.get<style::TextTranslate>(),
+ evaluated.get<style::TextTranslateAnchor>(),
+ textSize,
+ 24.0f,
+ evaluated.get<style::TextHaloColor>().constantOr(Color::black()).a > 0 &&
+ evaluated.get<style::TextHaloWidth>().constantOr(1),
+ evaluated.get<style::TextColor>().constantOr(Color::black()).a > 0
+ };
+}
+
+} // namespace mbgl
diff --git a/src/mbgl/renderer/render_symbol_layer.hpp b/src/mbgl/renderer/render_symbol_layer.hpp
new file mode 100644
index 0000000000..dbe7c4ea83
--- /dev/null
+++ b/src/mbgl/renderer/render_symbol_layer.hpp
@@ -0,0 +1,97 @@
+#pragma once
+
+#include <mbgl/text/glyph.hpp>
+#include <mbgl/renderer/render_layer.hpp>
+#include <mbgl/sprite/sprite_atlas.hpp>
+#include <mbgl/style/layers/symbol_layer.hpp>
+#include <mbgl/style/layers/symbol_layer_properties.hpp>
+
+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 PaintProperties<
+ IconOpacity,
+ IconColor,
+ IconHaloColor,
+ IconHaloWidth,
+ IconHaloBlur,
+ IconTranslate,
+ IconTranslateAnchor
+> {};
+
+class TextPaintProperties : public PaintProperties<
+ TextOpacity,
+ TextColor,
+ TextHaloColor,
+ TextHaloWidth,
+ TextHaloBlur,
+ TextTranslate,
+ TextTranslateAnchor
+> {};
+
+// Repackaging evaluated values from SymbolLayoutProperties + SymbolPaintProperties
+// for genericity over icons vs. text.
+class SymbolPropertyValues {
+public:
+ // Layout
+ AlignmentType pitchAlignment;
+ AlignmentType rotationAlignment;
+ PossiblyEvaluatedPropertyValue<float> layoutSize;
+
+ // Paint
+ std::array<float, 2> translate;
+ TranslateAnchorType translateAnchor;
+ float paintSize;
+
+ float sdfScale; // Constant (1.0 or 24.0)
+
+ bool hasHalo;
+ bool hasFill;
+};
+
+} // namespace style
+
+class BucketParameters;
+class SymbolLayout;
+class GeometryTileLayer;
+
+class RenderSymbolLayer: public RenderLayer {
+public:
+ RenderSymbolLayer(const style::SymbolLayer::Impl&);
+ ~RenderSymbolLayer() final = default;
+
+ std::unique_ptr<RenderLayer> clone() const override;
+
+ void cascade(const style::CascadeParameters&) override;
+ bool evaluate(const style::PropertyEvaluationParameters&) override;
+
+ style::IconPaintProperties::Evaluated iconPaintProperties() const;
+ style::TextPaintProperties::Evaluated textPaintProperties() const;
+
+ style::SymbolPropertyValues iconPropertyValues(const style::SymbolLayoutProperties::PossiblyEvaluated&) const;
+ style::SymbolPropertyValues textPropertyValues(const style::SymbolLayoutProperties::PossiblyEvaluated&) const;
+
+ std::unique_ptr<Bucket> createBucket(const BucketParameters&, const std::vector<const RenderLayer*>&) const override;
+ std::unique_ptr<SymbolLayout> createLayout(const BucketParameters&, const std::vector<const RenderLayer*>&,
+ const GeometryTileLayer&, GlyphDependencies&, IconDependencyMap&) const;
+
+ // Paint properties
+ style::SymbolPaintProperties::Unevaluated unevaluated;
+ style::SymbolPaintProperties::Evaluated evaluated;
+
+ float iconSize = 1.0f;
+ float textSize = 16.0f;
+
+ const style::SymbolLayer::Impl* const impl;
+};
+
+template <>
+inline bool RenderLayer::is<RenderSymbolLayer>() const {
+ return type == style::LayerType::Symbol;
+}
+
+} // namespace mbgl
diff --git a/src/mbgl/renderer/symbol_bucket.cpp b/src/mbgl/renderer/symbol_bucket.cpp
index 77a9a75ef1..9b016c16f9 100644
--- a/src/mbgl/renderer/symbol_bucket.cpp
+++ b/src/mbgl/renderer/symbol_bucket.cpp
@@ -1,7 +1,7 @@
#include <mbgl/renderer/symbol_bucket.hpp>
#include <mbgl/renderer/painter.hpp>
-#include <mbgl/style/bucket_parameters.hpp>
-#include <mbgl/style/layers/symbol_layer.hpp>
+#include <mbgl/renderer/render_symbol_layer.hpp>
+#include <mbgl/renderer/bucket_parameters.hpp>
#include <mbgl/style/layers/symbol_layer_impl.hpp>
namespace mbgl {
@@ -61,9 +61,9 @@ void SymbolBucket::upload(gl::Context& context) {
void SymbolBucket::render(Painter& painter,
PaintParameters& parameters,
- const Layer& layer,
+ const RenderLayer& layer,
const RenderTile& tile) {
- painter.renderSymbol(parameters, *this, *layer.as<SymbolLayer>(), tile);
+ painter.renderSymbol(parameters, *this, *layer.as<RenderSymbolLayer>(), tile);
}
bool SymbolBucket::hasData() const {
diff --git a/src/mbgl/renderer/symbol_bucket.hpp b/src/mbgl/renderer/symbol_bucket.hpp
index 659d7a3788..e00de03fd2 100644
--- a/src/mbgl/renderer/symbol_bucket.hpp
+++ b/src/mbgl/renderer/symbol_bucket.hpp
@@ -26,7 +26,7 @@ public:
bool iconsNeedLinear);
void upload(gl::Context&) override;
- void render(Painter&, PaintParameters&, const style::Layer&, const RenderTile&) override;
+ void render(Painter&, PaintParameters&, const RenderLayer&, const RenderTile&) override;
bool hasData() const override;
bool hasTextData() const;
bool hasIconData() const;