[core] Polymorphic bucket creation
This commit is contained in:
@@ -21,4 +21,8 @@ void BackgroundLayer::recalculate(const StyleCalculationParameters& parameters)
|
||||
passes = properties.isVisible() ? RenderPass::Translucent : RenderPass::None;
|
||||
}
|
||||
|
||||
std::unique_ptr<Bucket> BackgroundLayer::createBucket(StyleBucketParameters&) const {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -15,6 +15,8 @@ public:
|
||||
|
||||
void recalculate(const StyleCalculationParameters&) override;
|
||||
|
||||
std::unique_ptr<Bucket> createBucket(StyleBucketParameters&) const override;
|
||||
|
||||
BackgroundPaintProperties properties;
|
||||
};
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#include <mbgl/layer/circle_layer.hpp>
|
||||
#include <mbgl/style/property_parsing.hpp>
|
||||
#include <mbgl/style/style_bucket_parameters.hpp>
|
||||
#include <mbgl/renderer/circle_bucket.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
@@ -27,4 +29,14 @@ void CircleLayer::recalculate(const StyleCalculationParameters& parameters) {
|
||||
passes = properties.isVisible() ? RenderPass::Translucent : RenderPass::None;
|
||||
}
|
||||
|
||||
std::unique_ptr<Bucket> CircleLayer::createBucket(StyleBucketParameters& parameters) const {
|
||||
auto bucket = std::make_unique<CircleBucket>();
|
||||
|
||||
parameters.eachFilteredFeature(filter, [&] (const auto& feature) {
|
||||
bucket->addGeometry(feature.getGeometries());
|
||||
});
|
||||
|
||||
return std::move(bucket);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -15,6 +15,8 @@ public:
|
||||
|
||||
void recalculate(const StyleCalculationParameters&) override;
|
||||
|
||||
std::unique_ptr<Bucket> createBucket(StyleBucketParameters&) const override;
|
||||
|
||||
CirclePaintProperties properties;
|
||||
};
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#include <mbgl/layer/fill_layer.hpp>
|
||||
#include <mbgl/style/property_parsing.hpp>
|
||||
#include <mbgl/style/style_bucket_parameters.hpp>
|
||||
#include <mbgl/renderer/fill_bucket.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
@@ -43,4 +45,14 @@ void FillLayer::recalculate(const StyleCalculationParameters& parameters) {
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<Bucket> FillLayer::createBucket(StyleBucketParameters& parameters) const {
|
||||
auto bucket = std::make_unique<FillBucket>();
|
||||
|
||||
parameters.eachFilteredFeature(filter, [&] (const auto& feature) {
|
||||
bucket->addGeometry(feature.getGeometries());
|
||||
});
|
||||
|
||||
return std::move(bucket);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -15,6 +15,8 @@ public:
|
||||
|
||||
void recalculate(const StyleCalculationParameters&) override;
|
||||
|
||||
std::unique_ptr<Bucket> createBucket(StyleBucketParameters&) const override;
|
||||
|
||||
FillPaintProperties properties;
|
||||
};
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#include <mbgl/layer/line_layer.hpp>
|
||||
#include <mbgl/style/property_parsing.hpp>
|
||||
#include <mbgl/style/style_bucket_parameters.hpp>
|
||||
#include <mbgl/renderer/line_bucket.hpp>
|
||||
#include <mbgl/map/tile_id.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
@@ -52,4 +54,21 @@ void LineLayer::recalculate(const StyleCalculationParameters& parameters) {
|
||||
passes = properties.isVisible() ? RenderPass::Translucent : RenderPass::None;
|
||||
}
|
||||
|
||||
std::unique_ptr<Bucket> LineLayer::createBucket(StyleBucketParameters& parameters) const {
|
||||
auto bucket = std::make_unique<LineBucket>();
|
||||
|
||||
const float z = parameters.tileID.z;
|
||||
|
||||
layout.calculate(PropertyKey::LineCap, bucket->layout.cap, z);
|
||||
layout.calculate(PropertyKey::LineJoin, bucket->layout.join, z);
|
||||
layout.calculate(PropertyKey::LineMiterLimit, bucket->layout.miter_limit, z);
|
||||
layout.calculate(PropertyKey::LineRoundLimit, bucket->layout.round_limit, z);
|
||||
|
||||
parameters.eachFilteredFeature(filter, [&] (const auto& feature) {
|
||||
bucket->addGeometry(feature.getGeometries());
|
||||
});
|
||||
|
||||
return std::move(bucket);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -15,6 +15,8 @@ public:
|
||||
|
||||
void recalculate(const StyleCalculationParameters&) override;
|
||||
|
||||
std::unique_ptr<Bucket> createBucket(StyleBucketParameters&) const override;
|
||||
|
||||
LinePaintProperties properties;
|
||||
};
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include <mbgl/layer/raster_layer.hpp>
|
||||
#include <mbgl/style/property_parsing.hpp>
|
||||
#include <mbgl/renderer/bucket.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
@@ -35,4 +36,8 @@ void RasterLayer::recalculate(const StyleCalculationParameters& parameters) {
|
||||
passes = properties.isVisible() ? RenderPass::Translucent : RenderPass::None;
|
||||
}
|
||||
|
||||
std::unique_ptr<Bucket> RasterLayer::createBucket(StyleBucketParameters&) const {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -15,6 +15,8 @@ public:
|
||||
|
||||
void recalculate(const StyleCalculationParameters&) override;
|
||||
|
||||
std::unique_ptr<Bucket> createBucket(StyleBucketParameters&) const override;
|
||||
|
||||
RasterPaintProperties properties;
|
||||
};
|
||||
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
#include <mbgl/layer/symbol_layer.hpp>
|
||||
#include <mbgl/renderer/symbol_bucket.hpp>
|
||||
#include <mbgl/map/tile_id.hpp>
|
||||
#include <mbgl/style/property_evaluator.hpp>
|
||||
#include <mbgl/style/property_parsing.hpp>
|
||||
#include <mbgl/style/style_bucket_parameters.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
@@ -108,4 +111,70 @@ void SymbolLayer::recalculate(const StyleCalculationParameters& parameters) {
|
||||
passes = properties.isVisible() ? RenderPass::Translucent : RenderPass::None;
|
||||
}
|
||||
|
||||
std::unique_ptr<Bucket> SymbolLayer::createBucket(StyleBucketParameters& parameters) const {
|
||||
const float z = parameters.tileID.z;
|
||||
auto bucket = std::make_unique<SymbolBucket>(parameters.tileID.overscaling, z);
|
||||
|
||||
layout.calculate(PropertyKey::SymbolPlacement, bucket->layout.placement, z);
|
||||
if (bucket->layout.placement == PlacementType::Line) {
|
||||
bucket->layout.icon.rotation_alignment = RotationAlignmentType::Map;
|
||||
bucket->layout.text.rotation_alignment = RotationAlignmentType::Map;
|
||||
};
|
||||
layout.calculate(PropertyKey::SymbolSpacing, bucket->layout.spacing, z);
|
||||
layout.calculate(PropertyKey::SymbolAvoidEdges, bucket->layout.avoid_edges, z);
|
||||
|
||||
layout.calculate(PropertyKey::IconAllowOverlap, bucket->layout.icon.allow_overlap, z);
|
||||
layout.calculate(PropertyKey::IconIgnorePlacement, bucket->layout.icon.ignore_placement, z);
|
||||
layout.calculate(PropertyKey::IconOptional, bucket->layout.icon.optional, z);
|
||||
layout.calculate(PropertyKey::IconRotationAlignment, bucket->layout.icon.rotation_alignment, z);
|
||||
layout.calculate(PropertyKey::IconImage, bucket->layout.icon.image, z);
|
||||
layout.calculate(PropertyKey::IconPadding, bucket->layout.icon.padding, z);
|
||||
layout.calculate(PropertyKey::IconRotate, bucket->layout.icon.rotate, z);
|
||||
layout.calculate(PropertyKey::IconKeepUpright, bucket->layout.icon.keep_upright, z);
|
||||
layout.calculate(PropertyKey::IconOffset, bucket->layout.icon.offset, z);
|
||||
|
||||
layout.calculate(PropertyKey::TextRotationAlignment, bucket->layout.text.rotation_alignment, z);
|
||||
layout.calculate(PropertyKey::TextField, bucket->layout.text.field, z);
|
||||
layout.calculate(PropertyKey::TextFont, bucket->layout.text.font, z);
|
||||
layout.calculate(PropertyKey::TextMaxWidth, bucket->layout.text.max_width, z);
|
||||
layout.calculate(PropertyKey::TextLineHeight, bucket->layout.text.line_height, z);
|
||||
layout.calculate(PropertyKey::TextLetterSpacing, bucket->layout.text.letter_spacing, z);
|
||||
layout.calculate(PropertyKey::TextMaxAngle, bucket->layout.text.max_angle, z);
|
||||
layout.calculate(PropertyKey::TextRotate, bucket->layout.text.rotate, z);
|
||||
layout.calculate(PropertyKey::TextPadding, bucket->layout.text.padding, z);
|
||||
layout.calculate(PropertyKey::TextIgnorePlacement, bucket->layout.text.ignore_placement, z);
|
||||
layout.calculate(PropertyKey::TextOptional, bucket->layout.text.optional, z);
|
||||
layout.calculate(PropertyKey::TextJustify, bucket->layout.text.justify, z);
|
||||
layout.calculate(PropertyKey::TextAnchor, bucket->layout.text.anchor, z);
|
||||
layout.calculate(PropertyKey::TextKeepUpright, bucket->layout.text.keep_upright, z);
|
||||
layout.calculate(PropertyKey::TextTransform, bucket->layout.text.transform, z);
|
||||
layout.calculate(PropertyKey::TextOffset, bucket->layout.text.offset, z);
|
||||
layout.calculate(PropertyKey::TextAllowOverlap, bucket->layout.text.allow_overlap, z);
|
||||
|
||||
layout.calculate(PropertyKey::IconSize, bucket->layout.icon.size, z + 1);
|
||||
layout.calculate(PropertyKey::IconSize, bucket->layout.icon.max_size, 18);
|
||||
layout.calculate(PropertyKey::TextSize, bucket->layout.text.size, z + 1);
|
||||
layout.calculate(PropertyKey::TextSize, bucket->layout.text.max_size, 18);
|
||||
|
||||
bucket->parseFeatures(parameters.layer, filter);
|
||||
|
||||
if (bucket->needsDependencies(parameters.glyphStore, parameters.sprite)) {
|
||||
parameters.partialParse = true;
|
||||
}
|
||||
|
||||
// We do not add features if the parser is in a "partial" state because
|
||||
// the layer ordering needs to be respected when calculating text
|
||||
// collisions. Although, at this point, we requested all the resources
|
||||
// needed by this tile.
|
||||
if (!parameters.partialParse) {
|
||||
bucket->addFeatures(parameters.tileUID,
|
||||
parameters.spriteAtlas,
|
||||
parameters.glyphAtlas,
|
||||
parameters.glyphStore,
|
||||
parameters.collisionTile);
|
||||
}
|
||||
|
||||
return std::move(bucket);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -15,6 +15,8 @@ public:
|
||||
|
||||
void recalculate(const StyleCalculationParameters&) override;
|
||||
|
||||
std::unique_ptr<Bucket> createBucket(StyleBucketParameters&) const override;
|
||||
|
||||
SymbolPaintProperties properties;
|
||||
};
|
||||
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
#include <mbgl/text/collision_tile.hpp>
|
||||
#include <mbgl/map/tile_worker.hpp>
|
||||
#include <mbgl/map/geometry_tile.hpp>
|
||||
#include <mbgl/style/style.hpp>
|
||||
#include <mbgl/style/style_layer.hpp>
|
||||
#include <mbgl/style/property_evaluator.hpp>
|
||||
#include <mbgl/style/style_bucket_parameters.hpp>
|
||||
#include <mbgl/geometry/sprite_atlas.hpp>
|
||||
#include <mbgl/geometry/glyph_atlas.hpp>
|
||||
#include <mbgl/renderer/fill_bucket.hpp>
|
||||
#include <mbgl/renderer/line_bucket.hpp>
|
||||
#include <mbgl/renderer/circle_bucket.hpp>
|
||||
#include <mbgl/renderer/symbol_bucket.hpp>
|
||||
#include <mbgl/platform/log.hpp>
|
||||
#include <mbgl/util/constants.hpp>
|
||||
@@ -21,7 +19,6 @@ TileWorker::TileWorker(TileID id_,
|
||||
const std::atomic<TileData::State>& state_)
|
||||
: id(id_),
|
||||
sourceID(sourceID_),
|
||||
parameters(id.z),
|
||||
style(style_),
|
||||
state(state_) {
|
||||
assert(style.sprite);
|
||||
@@ -36,6 +33,7 @@ TileParseResult TileWorker::parseAllLayers(std::vector<util::ptr<StyleLayer>> la
|
||||
PlacementConfig config) {
|
||||
// We're doing a fresh parse of the tile, because the underlying data has changed.
|
||||
pending.clear();
|
||||
partialParse = false;
|
||||
|
||||
// Reset the collision tile so we have a clean slate; we're placing all features anyway.
|
||||
collisionTile = std::make_unique<CollisionTile>(config);
|
||||
@@ -99,15 +97,6 @@ void TileWorker::redoPlacement(
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void applyLayoutProperty(PropertyKey key, const ClassProperties &classProperties, T &target, const StyleCalculationParameters& parameters) {
|
||||
auto it = classProperties.properties.find(key);
|
||||
if (it != classProperties.properties.end()) {
|
||||
const PropertyEvaluator<T> evaluator(parameters);
|
||||
target = mapbox::util::apply_visitor(evaluator, it->second);
|
||||
}
|
||||
}
|
||||
|
||||
void TileWorker::parseLayer(const StyleLayer& layer, const GeometryTile& geometryTile) {
|
||||
// Cancel early when parsing.
|
||||
if (state == TileData::State::obsolete)
|
||||
@@ -135,145 +124,23 @@ void TileWorker::parseLayer(const StyleLayer& layer, const GeometryTile& geometr
|
||||
return;
|
||||
}
|
||||
|
||||
switch (layer.type) {
|
||||
case StyleLayerType::Fill:
|
||||
createFillBucket(*geometryLayer, layer);
|
||||
break;
|
||||
case StyleLayerType::Line:
|
||||
createLineBucket(*geometryLayer, layer);
|
||||
break;
|
||||
case StyleLayerType::Circle:
|
||||
createCircleBucket(*geometryLayer, layer);
|
||||
break;
|
||||
case StyleLayerType::Symbol:
|
||||
createSymbolBucket(*geometryLayer, layer);
|
||||
break;
|
||||
case StyleLayerType::Raster:
|
||||
break;
|
||||
default:
|
||||
Log::Warning(Event::ParseTile, "unknown bucket render type for layer '%s' (source layer '%s')",
|
||||
layer.id.c_str(), layer.sourceLayer.c_str());
|
||||
}
|
||||
}
|
||||
StyleBucketParameters parameters(id,
|
||||
*geometryLayer,
|
||||
state,
|
||||
reinterpret_cast<uintptr_t>(this),
|
||||
partialParse,
|
||||
*style.spriteAtlas,
|
||||
*style.sprite,
|
||||
*style.glyphAtlas,
|
||||
*style.glyphStore,
|
||||
*collisionTile);
|
||||
|
||||
template <class Bucket>
|
||||
void TileWorker::addBucketGeometries(Bucket& bucket, const GeometryTileLayer& layer, const FilterExpression &filter) {
|
||||
for (std::size_t i = 0; i < layer.featureCount(); i++) {
|
||||
auto feature = layer.getFeature(i);
|
||||
std::unique_ptr<Bucket> bucket = layer.createBucket(parameters);
|
||||
|
||||
if (state == TileData::State::obsolete)
|
||||
return;
|
||||
|
||||
GeometryTileFeatureExtractor extractor(*feature);
|
||||
if (!evaluate(filter, extractor))
|
||||
continue;
|
||||
|
||||
bucket->addGeometry(feature->getGeometries());
|
||||
}
|
||||
}
|
||||
|
||||
void TileWorker::createFillBucket(const GeometryTileLayer& tileLayer,
|
||||
const StyleLayer& layer) {
|
||||
auto bucket = std::make_unique<FillBucket>();
|
||||
|
||||
// Fill does not have layout properties to apply.
|
||||
|
||||
addBucketGeometries(bucket, tileLayer, layer.filter);
|
||||
|
||||
insertBucket(layer.bucketName(), std::move(bucket));
|
||||
}
|
||||
|
||||
void TileWorker::createLineBucket(const GeometryTileLayer& tileLayer,
|
||||
const StyleLayer& layer) {
|
||||
auto bucket = std::make_unique<LineBucket>();
|
||||
|
||||
const float z = id.z;
|
||||
auto& layout = bucket->layout;
|
||||
|
||||
applyLayoutProperty(PropertyKey::LineCap, layer.layout, layout.cap, z);
|
||||
applyLayoutProperty(PropertyKey::LineJoin, layer.layout, layout.join, z);
|
||||
applyLayoutProperty(PropertyKey::LineMiterLimit, layer.layout, layout.miter_limit, z);
|
||||
applyLayoutProperty(PropertyKey::LineRoundLimit, layer.layout, layout.round_limit, z);
|
||||
|
||||
addBucketGeometries(bucket, tileLayer, layer.filter);
|
||||
|
||||
insertBucket(layer.bucketName(), std::move(bucket));
|
||||
}
|
||||
|
||||
void TileWorker::createCircleBucket(const GeometryTileLayer& tileLayer,
|
||||
const StyleLayer& layer) {
|
||||
auto bucket = std::make_unique<CircleBucket>();
|
||||
|
||||
// Circle does not have layout properties to apply.
|
||||
|
||||
addBucketGeometries(bucket, tileLayer, layer.filter);
|
||||
|
||||
insertBucket(layer.bucketName(), std::move(bucket));
|
||||
}
|
||||
|
||||
void TileWorker::createSymbolBucket(const GeometryTileLayer& tileLayer,
|
||||
const StyleLayer& layer) {
|
||||
auto bucket = std::make_unique<SymbolBucket>(id.overscaling, id.z);
|
||||
|
||||
const float z = id.z;
|
||||
auto& layout = bucket->layout;
|
||||
|
||||
applyLayoutProperty(PropertyKey::SymbolPlacement, layer.layout, layout.placement, z);
|
||||
if (layout.placement == PlacementType::Line) {
|
||||
layout.icon.rotation_alignment = RotationAlignmentType::Map;
|
||||
layout.text.rotation_alignment = RotationAlignmentType::Map;
|
||||
};
|
||||
applyLayoutProperty(PropertyKey::SymbolSpacing, layer.layout, layout.spacing, z);
|
||||
applyLayoutProperty(PropertyKey::SymbolAvoidEdges, layer.layout, layout.avoid_edges, z);
|
||||
|
||||
applyLayoutProperty(PropertyKey::IconAllowOverlap, layer.layout, layout.icon.allow_overlap, z);
|
||||
applyLayoutProperty(PropertyKey::IconIgnorePlacement, layer.layout, layout.icon.ignore_placement, z);
|
||||
applyLayoutProperty(PropertyKey::IconOptional, layer.layout, layout.icon.optional, z);
|
||||
applyLayoutProperty(PropertyKey::IconRotationAlignment, layer.layout, layout.icon.rotation_alignment, z);
|
||||
applyLayoutProperty(PropertyKey::IconImage, layer.layout, layout.icon.image, z);
|
||||
applyLayoutProperty(PropertyKey::IconPadding, layer.layout, layout.icon.padding, z);
|
||||
applyLayoutProperty(PropertyKey::IconRotate, layer.layout, layout.icon.rotate, z);
|
||||
applyLayoutProperty(PropertyKey::IconKeepUpright, layer.layout, layout.icon.keep_upright, z);
|
||||
applyLayoutProperty(PropertyKey::IconOffset, layer.layout, layout.icon.offset, z);
|
||||
|
||||
applyLayoutProperty(PropertyKey::TextRotationAlignment, layer.layout, layout.text.rotation_alignment, z);
|
||||
applyLayoutProperty(PropertyKey::TextField, layer.layout, layout.text.field, z);
|
||||
applyLayoutProperty(PropertyKey::TextFont, layer.layout, layout.text.font, z);
|
||||
applyLayoutProperty(PropertyKey::TextMaxWidth, layer.layout, layout.text.max_width, z);
|
||||
applyLayoutProperty(PropertyKey::TextLineHeight, layer.layout, layout.text.line_height, z);
|
||||
applyLayoutProperty(PropertyKey::TextLetterSpacing, layer.layout, layout.text.letter_spacing, z);
|
||||
applyLayoutProperty(PropertyKey::TextMaxAngle, layer.layout, layout.text.max_angle, z);
|
||||
applyLayoutProperty(PropertyKey::TextRotate, layer.layout, layout.text.rotate, z);
|
||||
applyLayoutProperty(PropertyKey::TextPadding, layer.layout, layout.text.padding, z);
|
||||
applyLayoutProperty(PropertyKey::TextIgnorePlacement, layer.layout, layout.text.ignore_placement, z);
|
||||
applyLayoutProperty(PropertyKey::TextOptional, layer.layout, layout.text.optional, z);
|
||||
applyLayoutProperty(PropertyKey::TextJustify, layer.layout, layout.text.justify, z);
|
||||
applyLayoutProperty(PropertyKey::TextAnchor, layer.layout, layout.text.anchor, z);
|
||||
applyLayoutProperty(PropertyKey::TextKeepUpright, layer.layout, layout.text.keep_upright, z);
|
||||
applyLayoutProperty(PropertyKey::TextTransform, layer.layout, layout.text.transform, z);
|
||||
applyLayoutProperty(PropertyKey::TextOffset, layer.layout, layout.text.offset, z);
|
||||
applyLayoutProperty(PropertyKey::TextAllowOverlap, layer.layout, layout.text.allow_overlap, z);
|
||||
|
||||
applyLayoutProperty(PropertyKey::IconSize, layer.layout, layout.icon.size, z + 1);
|
||||
applyLayoutProperty(PropertyKey::IconSize, layer.layout, layout.icon.max_size, 18);
|
||||
applyLayoutProperty(PropertyKey::TextSize, layer.layout, layout.text.size, z + 1);
|
||||
applyLayoutProperty(PropertyKey::TextSize, layer.layout, layout.text.max_size, 18);
|
||||
|
||||
bucket->parseFeatures(tileLayer, layer.filter);
|
||||
|
||||
assert(style.glyphStore);
|
||||
assert(style.sprite);
|
||||
const bool needsDependencies = bucket->needsDependencies(*style.glyphStore, *style.sprite);
|
||||
if (needsDependencies) {
|
||||
if (layer.type == StyleLayerType::Symbol && partialParse) {
|
||||
// We cannot parse this bucket yet. Instead, we're saving it for later.
|
||||
pending.emplace_back(layer, std::move(bucket));
|
||||
} else {
|
||||
assert(style.spriteAtlas);
|
||||
assert(style.glyphAtlas);
|
||||
assert(style.glyphStore);
|
||||
assert(collisionTile);
|
||||
bucket->addFeatures(reinterpret_cast<uintptr_t>(this), *style.spriteAtlas,
|
||||
*style.glyphAtlas, *style.glyphStore, *collisionTile);
|
||||
insertBucket(layer.bucketName(), std::move(bucket));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,8 +6,6 @@
|
||||
#include <mbgl/map/tile_data.hpp>
|
||||
#include <mbgl/util/noncopyable.hpp>
|
||||
#include <mbgl/util/ptr.hpp>
|
||||
#include <mbgl/style/filter_expression.hpp>
|
||||
#include <mbgl/style/style_calculation_parameters.hpp>
|
||||
#include <mbgl/text/placement_config.hpp>
|
||||
|
||||
#include <string>
|
||||
@@ -23,7 +21,6 @@ class GeometryTile;
|
||||
class Style;
|
||||
class Bucket;
|
||||
class StyleLayer;
|
||||
class GeometryTileLayer;
|
||||
|
||||
// We're using this class to shuttle the resulting buckets from the worker thread to the MapContext
|
||||
// thread. This class is movable-only because the vector contains movable-only value elements.
|
||||
@@ -56,24 +53,16 @@ public:
|
||||
|
||||
private:
|
||||
void parseLayer(const StyleLayer&, const GeometryTile&);
|
||||
|
||||
void createFillBucket(const GeometryTileLayer&, const StyleLayer&);
|
||||
void createLineBucket(const GeometryTileLayer&, const StyleLayer&);
|
||||
void createCircleBucket(const GeometryTileLayer&, const StyleLayer&);
|
||||
void createSymbolBucket(const GeometryTileLayer&, const StyleLayer&);
|
||||
|
||||
void insertBucket(const std::string& name, std::unique_ptr<Bucket>);
|
||||
|
||||
template <class Bucket>
|
||||
void addBucketGeometries(Bucket&, const GeometryTileLayer&, const FilterExpression&);
|
||||
|
||||
const TileID id;
|
||||
const std::string sourceID;
|
||||
const StyleCalculationParameters parameters;
|
||||
|
||||
Style& style;
|
||||
const std::atomic<TileData::State>& state;
|
||||
|
||||
bool partialParse = false;
|
||||
|
||||
std::unique_ptr<CollisionTile> collisionTile;
|
||||
|
||||
// Contains buckets that we couldn't parse so far due to missing resources.
|
||||
|
||||
@@ -21,7 +21,7 @@ class CollisionTile;
|
||||
class Bucket : private util::noncopyable {
|
||||
public:
|
||||
Bucket() : uploaded(false) {}
|
||||
|
||||
|
||||
// As long as this bucket has a Prepare render pass, this function is getting called. Typically,
|
||||
// this only happens once when the bucket is being rendered for the first time.
|
||||
virtual void upload() = 0;
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include <mbgl/style/property_key.hpp>
|
||||
#include <mbgl/style/property_value.hpp>
|
||||
#include <mbgl/style/property_evaluator.hpp>
|
||||
#include <mbgl/style/property_transition.hpp>
|
||||
|
||||
#include <map>
|
||||
@@ -29,6 +30,15 @@ public:
|
||||
return properties.end();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void calculate(PropertyKey key, T& target, const float z) const {
|
||||
auto it = properties.find(key);
|
||||
if (it != properties.end()) {
|
||||
const PropertyEvaluator<T> evaluator(z);
|
||||
target = mapbox::util::apply_visitor(evaluator, it->second);
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
std::map<PropertyKey, PropertyValue> properties;
|
||||
std::map<PropertyKey, PropertyTransition> transitions;
|
||||
|
||||
19
src/mbgl/style/style_bucket_parameters.cpp
Normal file
19
src/mbgl/style/style_bucket_parameters.cpp
Normal file
@@ -0,0 +1,19 @@
|
||||
#include <mbgl/style/style_bucket_parameters.hpp>
|
||||
#include <mbgl/map/geometry_tile.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
void StyleBucketParameters::eachFilteredFeature(const FilterExpression& filter,
|
||||
std::function<void (const GeometryTileFeature&)> function) {
|
||||
for (std::size_t i = 0; !cancelled() && i < layer.featureCount(); i++) {
|
||||
auto feature = layer.getFeature(i);
|
||||
|
||||
GeometryTileFeatureExtractor extractor(*feature);
|
||||
if (!evaluate(filter, extractor))
|
||||
continue;
|
||||
|
||||
function(*feature);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
63
src/mbgl/style/style_bucket_parameters.hpp
Normal file
63
src/mbgl/style/style_bucket_parameters.hpp
Normal file
@@ -0,0 +1,63 @@
|
||||
#ifndef STYLE_BUCKET_PARAMETERS
|
||||
#define STYLE_BUCKET_PARAMETERS
|
||||
|
||||
#include <mbgl/style/filter_expression.hpp>
|
||||
#include <mbgl/map/tile_data.hpp>
|
||||
|
||||
#include <functional>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class TileID;
|
||||
class GeometryTileLayer;
|
||||
class GeometryTileFeature;
|
||||
class SpriteAtlas;
|
||||
class Sprite;
|
||||
class GlyphAtlas;
|
||||
class GlyphStore;
|
||||
class CollisionTile;
|
||||
|
||||
class StyleBucketParameters {
|
||||
public:
|
||||
StyleBucketParameters(const TileID& tileID_,
|
||||
const GeometryTileLayer& layer_,
|
||||
const std::atomic<TileData::State>& state_,
|
||||
uintptr_t tileUID_,
|
||||
bool& partialParse_,
|
||||
SpriteAtlas& spriteAtlas_,
|
||||
Sprite& sprite_,
|
||||
GlyphAtlas& glyphAtlas_,
|
||||
GlyphStore& glyphStore_,
|
||||
CollisionTile& collisionTile_)
|
||||
: tileID(tileID_),
|
||||
layer(layer_),
|
||||
state(state_),
|
||||
tileUID(tileUID_),
|
||||
partialParse(partialParse_),
|
||||
spriteAtlas(spriteAtlas_),
|
||||
sprite(sprite_),
|
||||
glyphAtlas(glyphAtlas_),
|
||||
glyphStore(glyphStore_),
|
||||
collisionTile(collisionTile_) {}
|
||||
|
||||
bool cancelled() const {
|
||||
return state == TileData::State::obsolete;
|
||||
}
|
||||
|
||||
void eachFilteredFeature(const FilterExpression&, std::function<void (const GeometryTileFeature&)>);
|
||||
|
||||
const TileID& tileID;
|
||||
const GeometryTileLayer& layer;
|
||||
const std::atomic<TileData::State>& state;
|
||||
uintptr_t tileUID;
|
||||
bool& partialParse;
|
||||
SpriteAtlas& spriteAtlas;
|
||||
Sprite& sprite;
|
||||
GlyphAtlas& glyphAtlas;
|
||||
GlyphStore& glyphStore;
|
||||
CollisionTile& collisionTile;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <mbgl/style/paint_properties_map.hpp>
|
||||
|
||||
#include <mbgl/renderer/render_pass.hpp>
|
||||
#include <mbgl/map/tile_data.hpp>
|
||||
|
||||
#include <mbgl/util/noncopyable.hpp>
|
||||
#include <mbgl/util/chrono.hpp>
|
||||
@@ -20,6 +21,7 @@
|
||||
namespace mbgl {
|
||||
|
||||
class StyleCalculationParameters;
|
||||
class StyleBucketParameters;
|
||||
class PropertyTransition;
|
||||
|
||||
using JSVal = rapidjson::Value;
|
||||
@@ -44,6 +46,8 @@ public:
|
||||
// Fully evaluate cascaded paint properties based on a zoom level.
|
||||
virtual void recalculate(const StyleCalculationParameters&) = 0;
|
||||
|
||||
virtual std::unique_ptr<Bucket> createBucket(StyleBucketParameters&) const = 0;
|
||||
|
||||
// Checks whether this layer has any active paint properties with transitions.
|
||||
bool hasTransitions() const;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user